404

[ Avaa Bypassed ]




Upload:

Command:

elspacio@18.224.32.70: ~ $
#!/usr/bin/env php
<?php

/*
 * Generated by Humbug Box 3.16.0@adb282a.
 *
 * @link https://github.com/humbug/box
 */

Phar::mapPhar('box-auto-generated-alias-7fa96f4d99a1.phar');

require 'phar://box-auto-generated-alias-7fa96f4d99a1.phar/.box/bin/check-requirements.php';

require 'phar://box-auto-generated-alias-7fa96f4d99a1.phar/psalm';

__HALT_COMPILER(); ?>
�;	stubs/SPL.phpstubdi���cdi/G��"stubs/CoreGenericIterators.phpstub�j���c�j�b�d�"stubs/CoreGenericFunctions.phpstub����c���̤ stubs/CoreGenericClasses.phpstub�7���c�7����stubs/phpparser.phpstub����c���B�stubs/extensions/ffi.phpstub ���c �Oh��stubs/extensions/dom.phpstub�]���c�]Ln%r�stubs/extensions/gmp.phpstub����c���rU� stubs/extensions/decimal.phpstub�@���c�@�f.��stubs/extensions/apcu.phpstub���c�ͤstubs/extensions/soap.phpstub{+���c{+�l�N�stubs/extensions/mysqli.phpstub'���c'�":8�stubs/extensions/geos.phpstub����c�S���stubs/extensions/ds.phpstub4c���c4c�NQ٤stubs/extensions/pdo.phpstub����c�+��/� stubs/extensions/mongodb.phpstub����c�G�@�stubs/extensions/random.phpstubG
���cG
Yf'��stubs/extensions/redis.phpstub	P���c	P�d�ܤstubs/extensions/xdebug.phpstub����c���Ȥ"stubs/extensions/simplexml.phpstub=���c=z�ѩ�stubs/Php81.phpstub����c���stubs/Php82.phpstubq���cqT��stubs/Reflection.phpstubx8���cx8���"stubs/CoreImmutableClasses.phpstub���cl�Ȥstubs/Php80.phpstub����c��:vendor/netresearch/jsonmapper/src/JsonMapper/Exception.php0���c0���0vendor/netresearch/jsonmapper/src/JsonMapper.php�l���c�lރ	��%vendor/netresearch/jsonmapper/LICENSER(���cR((}���vendor/autoload.php���c!ۻΤ-vendor/spatie/array-to-xml/src/ArrayToXml.php����c�� ʙ�+vendor/dnoegel/php-xdg-base-dir/src/Xdg.php����c�yE,E�'vendor/dnoegel/php-xdg-base-dir/LICENSE!���c!�W&�Mvendor/composer/package-versions-deprecated/src/PackageVersions/Installer.php9$���c9$�Әm�Lvendor/composer/package-versions-deprecated/src/PackageVersions/Versions.phpM"���cM")❝�Tvendor/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php����c�m���3vendor/composer/package-versions-deprecated/LICENSE!���c!����vendor/composer/ClassLoader.php/@���c/@!mj�%vendor/composer/autoload_classmap.php"����c"�!��vendor/composer/installed.php[S���c[S
�Ti�*vendor/composer/pcre/src/ReplaceResult.php����c�-��T�*vendor/composer/pcre/src/PcreException.php���cX3	�9vendor/composer/pcre/src/UnexpectedNullMatchException.php���c�zC�4vendor/composer/pcre/src/MatchStrictGroupsResult.php���c&�!�6vendor/composer/pcre/src/MatchAllWithOffsetsResult.php����c��_k�(vendor/composer/pcre/src/MatchResult.php���c��_��7vendor/composer/pcre/src/MatchAllStrictGroupsResult.php����c�+T-��"vendor/composer/pcre/src/Regex.php���cm�a��!vendor/composer/pcre/src/Preg.php�D���c�D�d���+vendor/composer/pcre/src/MatchAllResult.php����c����3vendor/composer/pcre/src/MatchWithOffsetsResult.php����c�����vendor/composer/pcre/LICENSE���chg�^�#vendor/composer/autoload_static.php�@���c�@w�7�"vendor/composer/autoload_files.php����c�k�P��!vendor/composer/autoload_real.php����c��(�+�-vendor/composer/xdebug-handler/src/Status.php����c�?���.vendor/composer/xdebug-handler/src/Process.phpR���cR�~45�0vendor/composer/xdebug-handler/src/PhpConfig.php����c���I�4vendor/composer/xdebug-handler/src/XdebugHandler.phpVN���cVN�$Ť&vendor/composer/xdebug-handler/LICENSE)���c)#�;^�vendor/composer/LICENSE.���c. ��!vendor/composer/autoload_psr4.phpM���cM�J�(vendor/composer/semver/src/Intervals.php�N���c�N]��<�%vendor/composer/semver/src/Semver.php\
���c\
o�,�,vendor/composer/semver/src/VersionParser.phpeT���ceT���+�=vendor/composer/semver/src/Constraint/MatchNoneConstraint.php����c��g�!�<vendor/composer/semver/src/Constraint/MatchAllConstraint.php����c���y�4vendor/composer/semver/src/Constraint/Constraint.php�0���c�0,[Z��9vendor/composer/semver/src/Constraint/MultiConstraint.phpD#���cD#ȿ�ͤ/vendor/composer/semver/src/Constraint/Bound.phpI
���cI
��~�=vendor/composer/semver/src/Constraint/ConstraintInterface.php����c�ܒu�)vendor/composer/semver/src/Comparator.phpj
���cj
�b#6�/vendor/composer/semver/src/CompilingMatcher.php5���c5%��.�'vendor/composer/semver/src/Interval.php����c�#�q�vendor/composer/semver/LICENSE���cBh�%vendor/composer/InstalledVersions.php;���c;�7��"vendor/composer/platform_check.php����c�qK�\�'vendor/composer/autoload_namespaces.php����c��/t�5vendor/nikic/php-parser/lib/PhpParser/NodeVisitor.php����c�b.���.vendor/nikic/php-parser/lib/PhpParser/Node.php����c��/��@vendor/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php+����c+��e���6vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php>���c>�`)��5vendor/nikic/php-parser/lib/PhpParser/NameContext.php+&���c+&��{�Lvendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.phpQ���cQW���>vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php$���c$"��;vendor/nikic/php-parser/lib/PhpParser/Internal/DiffElem.phpF���cF�]�ʤ9vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php<���c<\5�k�4vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php�	���c�	��.h�=vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php����c�����6vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.phpi���ci��ɤFvendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluationException.phpn���cn�,��7vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php����c�?4�7�/vendor/nikic/php-parser/lib/PhpParser/Lexer.php�Z���c�Z�}�9vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.phpN$���cN$���[vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php���cf�|K�Wvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FlexibleDocStringEmulator.php�	���c�	�V��Mvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php����c�K2qe�Pvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php����c��[ ��Svendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.phpj���cj��S�Svendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php����c����x�]vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.phpt���ct�*O�Mvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php����c�'�#ʤMvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php����c�3�ڤSvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php����c���ޕ�Ovendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php����c����Ovendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php���c?
��Wvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/CoaleseEqualTokenEmulator.php)���c)�"�Kvendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php����c��C�4vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php����c��L��8vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php�+���c�+�̐r�8vendor/nikic/php-parser/lib/PhpParser/Builder/Class_.php���c��\�8vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php!���c!ε)��6vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php*���c*$�L�:vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php����c��t�<vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php"
���c"
;[�7�:vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php����c�]�M�7vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php����c��K��;vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php����c�3�"��8vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php����c����Ȥ:vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php����c�

�y�7vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php����c�	��>vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php���c7f��<vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php����c���>t�Dvendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php����c��M�a�=vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php
���c
����<vendor/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php�
���c�
{<���8vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php�%���c�%��~�8vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.phpΚ���cΚ"�?�?vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php�����c���^��1vendor/nikic/php-parser/lib/PhpParser/Comment.php����c��N�v�5vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php����c���0�Avendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php����c���|A�?vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php����c��]�<vendor/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php�%���c�%3r�0vendor/nikic/php-parser/lib/PhpParser/Parser.php����c�S���5vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php/
���c/
0E7vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.phpl'���cl'��r�@vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php����c�iM�3vendor/nikic/php-parser/lib/PhpParser/Node/Name.php>���c>*��5vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.phpz���cz&D�>�?vendor/nikic/php-parser/lib/PhpParser/Node/IntersectionType.php����c���.��8vendor/nikic/php-parser/lib/PhpParser/Node/Attribute.phpu���cu		�~�:vendor/nikic/php-parser/lib/PhpParser/Node/ComplexType.phpq���cq�
�Bvendor/nikic/php-parser/lib/PhpParser/Node/VariadicPlaceholder.php����c�D���>vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php���c�E�|�=vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php����c���Hvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php���c��*&�=vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.php���c�g��=vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php�	���c�	fR��@vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php����c���o�Evendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.phpn���cnNeS�Dvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.phpk���ck�7���Gvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.phpr���cr�7��Gvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.phpr���cr�����Jvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.php{���c{���Gvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.phpt���ct剝��Evendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.phpn���cn Ye��Kvendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.php~���c~���t�2vendor/nikic/php-parser/lib/PhpParser/Node/Arg.php]���c]x�{�4vendor/nikic/php-parser/lib/PhpParser/Node/Param.php����c�(،Ĥ7vendor/nikic/php-parser/lib/PhpParser/Node/MatchArm.php����c�4�k�=vendor/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php����c�p)
�;vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php���c�@�e�5vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php���cv�i�@vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php���cYW�J�;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php���c�pIP�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.phpz���cz\�Q��>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php����c���N�;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php�
���c�
�E,P�=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php����c��P�&�Ivendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.php���c���>�9vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php����c�W�V�?vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php����c���i��>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php����c�2Pڌ�9vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php#���c#$�m��Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php����c�͠���Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php���cc�S��:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.phpV���cV���Z�Evendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.phpk���ckE豽�Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.phpn���cnhL�Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.phpn���cn|���Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.phpn���cn4�DN�Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.phpb���cbu"2\�Dvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.phph���chkq��@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php`���c`;�~�Bvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.phpd���cdN�s�Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.phpo���co"���Ivendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.phpt���ctV�b�Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.phpm���cmG���Cvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.phpf���cfY��N�Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.phpp���cp�!��Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.phpn���cn�ڦ�Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.phpm���cm-d^x�Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.phpp���cp��t�@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php`���c`ƙ�%�@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.phpa���ca����Bvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.phpe���ce{�ӤGvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.phpo���co_W�Q�Kvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.phpw���cw��|�Kvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.phpw���cwB�F;�Evendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.phpk���ck���>�@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php`���c`�b��Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.phpl���clj�~`�Dvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.phph���ch���Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.phpm���cm�Щ�Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.phpb���cb�6s�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php����c�a/��<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php����c�*�"�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php����c��yʎ�<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php����c�?�(-�<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php`���c`|ǭ}�=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.phpf���cf>E��<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php���c����8vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php_���c_RPLB�>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php����c� �2�Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php�	���c�	��<{�>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php����c�����;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php����c��l���8vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php����c���w<�>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php����c�9�*�Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.phpk���ck�i�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.php����c�K��T�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php����c�e���Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.php����c�'K�y�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php����c�(y�ۤ:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php����c��<�&�9vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php���cxޠ+�Cvendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.php0���c0�
&r�>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php����c�!2�Τ:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php5���c5���D�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.php����c�8��=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php����c�OYaV�:vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php����c��s:�=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php����c�r|��=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php����c�U; O�Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php���cb���Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.php���c�Ť�Avendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.php���c�
k��@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.php���c��
�Bvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.php���cٹ��Cvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.php���c~:b�Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.php���c�e4K�@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.php���c<�~Y�@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.php���c[���Gvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.php���c�A
�Evendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Coalesce.php���c
��@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.php���c
D�|�Fvendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.php���c�fN�9vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php ���c ,팤?vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php���c
l.?�>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.php���cV���?vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.php����c�/|�@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.php���cg Sؤ?vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.php���cr��z�=vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.php���c�ww�@vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.php���cj='�<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.phpb���cb
,ؤ;vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php����c���猤>vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php����c�S�x[�<vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php����c�B�� �<vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php����c�_s
�Bvendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php����c�Y�Ml�9vendor/nikic/php-parser/lib/PhpParser/Node/Identifier.php���cB��d�8vendor/nikic/php-parser/lib/PhpParser/Node/UnionType.php����c����B�3vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php����c��t�S�3vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php����c�h�,��;vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php����c�)�ۤ7vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php`���c`i'�=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php����c��DՕ�<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php����c�@E���9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php����c��5��:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php����c�Ј�4�:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php����c���8�9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php����c�5n"�Qvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.phpx���cx\��2�Lvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php_���c__rJl�:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php!���c!H'���8vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php����c��_�<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php����c��b���>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php���c�5�k�<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php����c� ���=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.phpY
���cY
�1��;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php����c�2��N�9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php���c����=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php����c�]���<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php�
���c�
#���9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.php[���c[�D)�:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php����c��^���;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.phpS���cS�=�ͤBvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php����c�k0�%�9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php=���c=

x��>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php���c*n��:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php����c��Z�:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.phpc���cc31��>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php����c�(Oq�:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php����c�ޏ���7vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.phpX���cXX<��@vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php%���c%r�Ѽ�8vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php\���c\1��B�=vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php����c���H��;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php����c�����Fvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php8���c8���B�;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.phpg���cg�!4��;vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php����c��.B�7vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php^���c^��<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php����c�$G5�<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.phpB���cBX�ki�9vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php����c�,�7��:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php����c��򯾤:vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php����c��/�2�<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php����c������>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php����c�~Ap��<vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php7���c79eD
�?vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php*���c*�7�Dvendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php����c��3���>vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php����c�t1�-�5vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.phpO���cO��_/�7vendor/nikic/php-parser/lib/PhpParser/Parser/Tokens.php5���c5�ﯤ�5vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.phpL,���cL,Ѕ�	�9vendor/nikic/php-parser/lib/PhpParser/Parser/Multiple.php����c�O�ä/vendor/nikic/php-parser/lib/PhpParser/Error.php����c�|h���1vendor/nikic/php-parser/lib/PhpParser/Builder.php����c��r�Mvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php����c�<��ƤDvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php?���c?�ݤKvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.php����c�,�.�Ivendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php8���c8��v�Dvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php����c�ٗ�D�Bvendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php�&���c�&�H��&vendor/nikic/php-parser/grammar/php7.y�����c��
����/vendor/nikic/php-parser/grammar/parser.template	���c	-ɚQ�&vendor/nikic/php-parser/grammar/php5.y�����c��P%PG�/vendor/nikic/php-parser/grammar/tokens.template*���c*��_֤,vendor/nikic/php-parser/grammar/phpyLang.php����c���ݤ2vendor/nikic/php-parser/grammar/rebuildParsers.php����c��ƾ�(vendor/nikic/php-parser/grammar/tokens.y�
���c�
�C~j�vendor/nikic/php-parser/LICENSE����c���*�%vendor/nikic/php-parser/bin/php-parsez���cz�ԩd�5vendor/phpdocumentor/type-resolver/src/PseudoType.php����c����8vendor/phpdocumentor/type-resolver/src/FqsenResolver.php	���c	O���:vendor/phpdocumentor/type-resolver/src/Types/Callable_.php����c�r-,��7vendor/phpdocumentor/type-resolver/src/Types/Scalar.php����c���,��?vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php
7���c
7$F�@vendor/phpdocumentor/type-resolver/src/Types/InterfaceString.php����c�-�4�7vendor/phpdocumentor/type-resolver/src/Types/Array_.php����c���Q�;vendor/phpdocumentor/type-resolver/src/Types/Collection.php����c� �^��=vendor/phpdocumentor/type-resolver/src/Types/AbstractList.php����c��n��8vendor/phpdocumentor/type-resolver/src/Types/Static_.php#���c#�%3Ѥ6vendor/phpdocumentor/type-resolver/src/Types/Void_.php%���c%DqCl�:vendor/phpdocumentor/type-resolver/src/Types/Resource_.php����c�~��8vendor/phpdocumentor/type-resolver/src/Types/Parent_.php���cF��2�6vendor/phpdocumentor/type-resolver/src/Types/Self_.php����c�N�pY�?vendor/phpdocumentor/type-resolver/src/Types/AggregatedType.php�
���c�
m��x�9vendor/phpdocumentor/type-resolver/src/Types/Compound.php%���c%��<��=vendor/phpdocumentor/type-resolver/src/Types/Intersection.php4���c4)��9vendor/phpdocumentor/type-resolver/src/Types/ArrayKey.php����c�}�‡�;vendor/phpdocumentor/type-resolver/src/Types/Expression.phpF���cFؔ���8vendor/phpdocumentor/type-resolver/src/Types/String_.php����c���Ȥ8vendor/phpdocumentor/type-resolver/src/Types/Context.php����c���
��<vendor/phpdocumentor/type-resolver/src/Types/ClassString.phpk���ck����6vendor/phpdocumentor/type-resolver/src/Types/Null_.php����c�T�_��9vendor/phpdocumentor/type-resolver/src/Types/Nullable.phpu���cu���8vendor/phpdocumentor/type-resolver/src/Types/Boolean.php����c�b�eФ7vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php����c��8S�5vendor/phpdocumentor/type-resolver/src/Types/This.phpw���cww���7vendor/phpdocumentor/type-resolver/src/Types/Never_.php���ct��:�7vendor/phpdocumentor/type-resolver/src/Types/Float_.php����c�5O�ۤ8vendor/phpdocumentor/type-resolver/src/Types/Integer.php����c�ԿQY�8vendor/phpdocumentor/type-resolver/src/Types/Object_.php���c��Z.�:vendor/phpdocumentor/type-resolver/src/Types/Iterable_.phpN���cN
;f�7vendor/phpdocumentor/type-resolver/src/TypeResolver.php�[���c�[•Ť?vendor/phpdocumentor/type-resolver/src/PseudoTypes/Numeric_.php`���c`~�E�<vendor/phpdocumentor/type-resolver/src/PseudoTypes/True_.php����c��mW$�Dvendor/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php����c��o]��Fvendor/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php����c������=vendor/phpdocumentor/type-resolver/src/PseudoTypes/False_.php����c�^�y�Nvendor/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php����c����Hvendor/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php����c��g�T�Dvendor/phpdocumentor/type-resolver/src/PseudoTypes/NumericString.php����c�1�+ڤCvendor/phpdocumentor/type-resolver/src/PseudoTypes/IntegerRange.phpA���cA�+<��<vendor/phpdocumentor/type-resolver/src/PseudoTypes/List_.php����c�C��ܤFvendor/phpdocumentor/type-resolver/src/PseudoTypes/PositiveInteger.php����c��y�äFvendor/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php����c�st�Bvendor/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php����c����&�Evendor/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php����c���Evendor/phpdocumentor/type-resolver/src/PseudoTypes/CallableString.php����c��R���/vendor/phpdocumentor/type-resolver/src/Type.php����c��DZ̤@vendor/phpdocumentor/type-resolver/composer-require-checker.jsono���co,:�G�*vendor/phpdocumentor/type-resolver/LICENSE8���c8��ʤ-vendor/phpdocumentor/type-resolver/rector.php����c��n���@vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php0%���c0%��4m�6vendor/phpdocumentor/reflection-docblock/src/Utils.php�	���c�	g/OS�Ivendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php����c�UC�Hvendor/phpdocumentor/reflection-docblock/src/Exception/PcreException.php����c�TIs�Lvendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php���c#Q�F�Dvendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.phpI���cI�{���Lvendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.phpE2���cE2s�S��Dvendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php����c���*�Evendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php���cy�L�=vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php����c�ϭϾ�Gvendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.phpJ���cJ��Cvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php:���c:��g�Fvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php����c�����Ivendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php6���c6��s�Lvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php����c��(&�Rvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php����c��ڤNvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.phpJ���cJ�L�q�Cvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php����c����Dvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.phpx���cxݳ2�Kvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.phpQ���cQ��E��Evendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php" ���c" Tj��Lvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.phpO���cOꑋ�Bvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php����c�S�f�Fvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php�
���c�
��Wvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php����c���2u�]vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php����c����.�Gvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.phpC���cC6��Evendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php�
���c�
��-�Hvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php<���c<�5� �Dvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php�
���c�
��B��Evendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.phpy���cy7���Cvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php�
���c�
�����Jvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php����c�I^�+�Fvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php���cG�k�Ivendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.phpJ���cJ7�Svendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php-���c- 	�äEvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php�	���c�	��,#�Fvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.phpx���cx)�?�Fvendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php�	���c�	]��Evendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php����c�e.3ܤ9vendor/phpdocumentor/reflection-docblock/src/DocBlock.php����c��ǀ
�0vendor/phpdocumentor/reflection-docblock/LICENSE8���c8��ʤ6vendor/phpdocumentor/reflection-common/src/Project.php���c��Ť7vendor/phpdocumentor/reflection-common/src/Location.php����c���4�=vendor/phpdocumentor/reflection-common/src/ProjectFactory.phpn���cn٦�j�3vendor/phpdocumentor/reflection-common/src/File.php����c���Ko�4vendor/phpdocumentor/reflection-common/src/Fqsen.php����c�gA4=�6vendor/phpdocumentor/reflection-common/src/Element.php���c�ݳ�.vendor/phpdocumentor/reflection-common/LICENSE9���c9*2Ȑ�)vendor/amphp/amp/lib/TimeoutException.php����c�Xݝ��-vendor/amphp/amp/lib/MultiReasonException.php����c�����1vendor/amphp/amp/lib/Internal/ResolutionQueue.php����c�@��0vendor/amphp/amp/lib/Internal/PrivatePromise.php1���c1�����1vendor/amphp/amp/lib/Internal/PrivateIterator.php����c�p5��+vendor/amphp/amp/lib/Internal/functions.php�
���c�
��}�*vendor/amphp/amp/lib/Internal/Producer.php,���c,+QS\�-vendor/amphp/amp/lib/Internal/Placeholder.php+���c+#fk@�1vendor/amphp/amp/lib/TimeoutCancellationToken.php3���c3j_$�$vendor/amphp/amp/lib/LazyPromise.php����c���X-� vendor/amphp/amp/lib/Emitter.php���c�[���!vendor/amphp/amp/lib/Iterator.php\���c\���vendor/amphp/amp/lib/Loop.phpF���cF��<��.vendor/amphp/amp/lib/NullCancellationToken.php����c�ӟ�D�vendor/amphp/amp/lib/Struct.php����c��Q#�+vendor/amphp/amp/lib/CancelledException.phpk���ck���"vendor/amphp/amp/lib/functions.php]���c]��¤"vendor/amphp/amp/lib/Coroutine.php)���c)
�7��2vendor/amphp/amp/lib/CombinedCancellationToken.php���c3��o�0vendor/amphp/amp/lib/CancellationTokenSource.php=���c=��h� vendor/amphp/amp/lib/Failure.php����c�9���!vendor/amphp/amp/lib/Producer.php����c�q�V|� vendor/amphp/amp/lib/Success.php���c��5M�&vendor/amphp/amp/lib/CallableMaker.php�
���c�
*�@S�!vendor/amphp/amp/lib/Deferred.php)���c):�=��+vendor/amphp/amp/lib/Loop/TracingDriver.phpi���ci���*vendor/amphp/amp/lib/Loop/NativeDriver.php�8���c�87���1vendor/amphp/amp/lib/Loop/Internal/TimerQueue.phpJ���cJ��&�$vendor/amphp/amp/lib/Loop/Driver.phpCg���cCg��P̤&vendor/amphp/amp/lib/Loop/EvDriver.php!���c!��.��1vendor/amphp/amp/lib/Loop/InvalidWatcherError.php*���c*�t/j�)vendor/amphp/amp/lib/Loop/EventDriver.phpL%���cL%d-F��+vendor/amphp/amp/lib/Loop/DriverFactory.php���c�Ɠ'�%vendor/amphp/amp/lib/Loop/Watcher.php����c�Y�9a�&vendor/amphp/amp/lib/Loop/UvDriver.php�(���c�(T�g�9vendor/amphp/amp/lib/Loop/UnsupportedFeatureException.php(���c(�e.��*vendor/amphp/amp/lib/CancellationToken.php���cs��*vendor/amphp/amp/lib/InvalidYieldError.php���cx_�Ǥ vendor/amphp/amp/lib/Delayed.php����c��a� vendor/amphp/amp/lib/Promise.php����c���vendor/amphp/amp/LICENSEq���cqrg��4vendor/amphp/byte-stream/lib/ResourceInputStream.php<���c<o�ȸ�1vendor/amphp/byte-stream/lib/PendingReadError.php����c���,��Bvendor/amphp/byte-stream/lib/Base64/Base64DecodingOutputStream.php����c����Avendor/amphp/byte-stream/lib/Base64/Base64DecodingInputStream.phpP���cPa�tѤAvendor/amphp/byte-stream/lib/Base64/Base64EncodingInputStream.php����c��\�Bvendor/amphp/byte-stream/lib/Base64/Base64EncodingOutputStream.php����c��!p��0vendor/amphp/byte-stream/lib/StreamException.phpf���cf)���(vendor/amphp/byte-stream/lib/Payload.php�	���c�	�!u)�1vendor/amphp/byte-stream/lib/ZlibOutputStream.phpg���cg��j�,vendor/amphp/byte-stream/lib/InputStream.phpO���cO��qc�+vendor/amphp/byte-stream/lib/LineReader.php���c��~�*vendor/amphp/byte-stream/lib/functions.php����c�
D���1vendor/amphp/byte-stream/lib/InputStreamChain.php����c���[�-vendor/amphp/byte-stream/lib/OutputStream.phpJ���cJ��P��5vendor/amphp/byte-stream/lib/ResourceOutputStream.php0*���c0*�ز�0vendor/amphp/byte-stream/lib/ClosedException.phpq���cqkH�b�/vendor/amphp/byte-stream/lib/InMemoryStream.php����c�DQp��/vendor/amphp/byte-stream/lib/IteratorStream.php���c=��h�(vendor/amphp/byte-stream/lib/Message.phpp���cp���#�0vendor/amphp/byte-stream/lib/ZlibInputStream.php����c���-vendor/amphp/byte-stream/lib/OutputBuffer.php����c�-W�� vendor/amphp/byte-stream/LICENSE6���c6\>W�-vendor/symfony/polyfill-mbstring/Mbstring.php�p���c�pFN]�.vendor/symfony/polyfill-mbstring/bootstrap.php ���c ����(vendor/symfony/polyfill-mbstring/LICENSE)���c)�\��@vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.phpU���cU���@vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.phpW[���cW[�:{)�Fvendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php���c�3�0vendor/symfony/polyfill-mbstring/bootstrap80.phpP%���cP%lՄ`�1vendor/symfony/deprecation-contracts/function.php4���c4a
d��,vendor/symfony/deprecation-contracts/LICENSE)���c)�2�+vendor/symfony/polyfill-php80/bootstrap.php����c�1T��%vendor/symfony/polyfill-php80/LICENSE$���c$LO!
�;vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php����c�MK�<�<vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php����c�t]\ڤEvendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.phpj���cj�0���<vendor/symfony/polyfill-php80/Resources/stubs/ValueError.phpa���ca���L�:vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.phpw���cw=7T8�'vendor/symfony/polyfill-php80/Php80.php�
���c�
cH���*vendor/symfony/polyfill-php80/PhpToken.php����c�]f�(vendor/symfony/console/ConsoleEvents.php����c���]	�*vendor/symfony/console/Input/ArgvInput.php�0���c�0&G.�/vendor/symfony/console/Input/InputInterface.php����c��� �.vendor/symfony/console/Input/InputArgument.php�
���c�
��MD�4vendor/symfony/console/Input/InputAwareInterface.phpP���cPM=��0vendor/symfony/console/Input/InputDefinition.php`.���c`.TOa��&vendor/symfony/console/Input/Input.phpH���cH7��+vendor/symfony/console/Input/ArrayInput.php����c�>�km�,vendor/symfony/console/Input/InputOption.php5���c5̪w�9vendor/symfony/console/Input/StreamableInputInterface.php~���c~��ʾ�,vendor/symfony/console/Input/StringInput.php�
���c�
^��0vendor/symfony/console/Command/LockableTrait.php;���c;��b�8vendor/symfony/console/Command/DumpCompletionCommand.phpz���cz�OX�2vendor/symfony/console/Command/CompleteCommand.php/!���c/!��C�.vendor/symfony/console/Command/HelpCommand.phpB���cBQl>Τ=vendor/symfony/console/Command/SignalableCommandInterface.php����c���S�*vendor/symfony/console/Command/Command.php�P���c�P��ͤ.vendor/symfony/console/Command/LazyCommand.phpc���cc:i�K�.vendor/symfony/console/Command/ListCommand.php9���c9�E�Ƥ#vendor/symfony/console/Terminal.php~���c~,OO<�3vendor/symfony/console/Event/ConsoleSignalEvent.php����c�Z!��2vendor/symfony/console/Event/ConsoleErrorEvent.php1���c1s�(��6vendor/symfony/console/Event/ConsoleTerminateEvent.phpz���czNSm��-vendor/symfony/console/Event/ConsoleEvent.php����c��ߤ4vendor/symfony/console/Event/ConsoleCommandEvent.php����c���ۤ,vendor/symfony/console/Style/OutputStyle.php`���c`�n�b�-vendor/symfony/console/Style/SymfonyStyle.php&:���c&:��J�/vendor/symfony/console/Style/StyleInterface.phpS
���cS
�m���&vendor/symfony/console/Application.php�����c��θ�Z�.vendor/symfony/console/Attribute/AsCommand.phpR���cRe�\�8vendor/symfony/console/SignalRegistry/SignalRegistry.phpH���cH,���3vendor/symfony/console/Exception/LogicException.php����c��{�P�?vendor/symfony/console/Exception/NamespaceNotFoundException.php����c���H�7vendor/symfony/console/Exception/ExceptionInterface.php����c�NL*4�5vendor/symfony/console/Exception/RuntimeException.php����c�F��b�=vendor/symfony/console/Exception/CommandNotFoundException.php����c�k_hi�;vendor/symfony/console/Exception/InvalidOptionException.php���c�'mR�:vendor/symfony/console/Exception/MissingInputException.php���cvw&Ť=vendor/symfony/console/Exception/InvalidArgumentException.php����c�w�&I�?vendor/symfony/console/CommandLoader/CommandLoaderInterface.php����c���}�=vendor/symfony/console/CommandLoader/FactoryCommandLoader.phpm���cm$Dl-�?vendor/symfony/console/CommandLoader/ContainerCommandLoader.php"���c"�M��>vendor/symfony/console/Formatter/OutputFormatterStyleStack.php5
���c5
�x��9vendor/symfony/console/Formatter/OutputFormatterStyle.phpk���ck����=vendor/symfony/console/Formatter/OutputFormatterInterface.phpH���cH�3��8vendor/symfony/console/Formatter/NullOutputFormatter.phps���cswںD�4vendor/symfony/console/Formatter/OutputFormatter.php����c��GB�Fvendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php����c��W�)�=vendor/symfony/console/Formatter/NullOutputFormatterStyle.php����c���t5�Bvendor/symfony/console/Formatter/OutputFormatterStyleInterface.phpk���ck����0vendor/symfony/console/Completion/Suggestion.php����c�bx��;vendor/symfony/console/Completion/CompletionSuggestions.phpv���cvR�W�5vendor/symfony/console/Completion/CompletionInput.phpo ���co �n֤Fvendor/symfony/console/Completion/Output/CompletionOutputInterface.php���c}$=u�Avendor/symfony/console/Completion/Output/BashCompletionOutput.php!���c!�Z�"� vendor/symfony/console/Color.phpb���cb����Dvendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php����c��D�Ҥ2vendor/symfony/console/CI/GithubActionReporter.php���c'�6vendor/symfony/console/EventListener/ErrorListener.phpy���cy�6�/vendor/symfony/console/Logger/ConsoleLogger.php����c����~�vendor/symfony/console/LICENSE)���c)a�x�2vendor/symfony/console/Question/ChoiceQuestion.php����c�8��%�8vendor/symfony/console/Question/ConfirmationQuestion.php-���c-Qy�,vendor/symfony/console/Question/Question.php����c���RƤ4vendor/symfony/console/Resources/bin/hiddeninput.exe$���c$���v�0vendor/symfony/console/Resources/completion.bash�
���c�
�z(�(vendor/symfony/console/Helper/Helper.php����c�tŻ��0vendor/symfony/console/Helper/QuestionHelper.php�M���c�MD���+vendor/symfony/console/Helper/TableCell.php���c���=�3vendor/symfony/console/Helper/ProgressIndicator.php����c�>�!�1vendor/symfony/console/Helper/FormatterHelper.php�	���c�	��/�,vendor/symfony/console/Helper/TableStyle.php�0���c�0���7�2vendor/symfony/console/Helper/DescriptorHelper.php
���c
"�mΤ7vendor/symfony/console/Helper/SymfonyQuestionHelper.phpc
���cc
ı��0vendor/symfony/console/Helper/TableCellStyle.phpl���clb�h(�+vendor/symfony/console/Helper/HelperSet.phpO
���cO
�A%�0vendor/symfony/console/Helper/TableSeparator.php)���c)>"���6vendor/symfony/console/Helper/DebugFormatterHelper.php`
���c`
U�vͤ1vendor/symfony/console/Helper/HelperInterface.phpa���ca��u�/vendor/symfony/console/Helper/ProcessHelper.php����c�S�)դ'vendor/symfony/console/Helper/Table.php�r���c�r���-vendor/symfony/console/Helper/ProgressBar.php6H���c6H�y���2vendor/symfony/console/Helper/InputAwareHelper.php-���c-��f�(vendor/symfony/console/Helper/Dumper.phpj���cjX����+vendor/symfony/console/Helper/TableRows.phpZ���cZ�a�Ф5vendor/symfony/console/Output/TrimmedBufferOutput.phpz���cz���/vendor/symfony/console/Output/ConsoleOutput.php/���c/G�k�1vendor/symfony/console/Output/OutputInterface.php|���c|��lݤ0vendor/symfony/console/Output/BufferedOutput.phpg���cg;OT��.vendor/symfony/console/Output/StreamOutput.php�
���c�
�y�r�(vendor/symfony/console/Output/Output.phpr���crv&lM�6vendor/symfony/console/Output/ConsoleSectionOutput.php����c�krդ8vendor/symfony/console/Output/ConsoleOutputInterface.php5���c5c��_�,vendor/symfony/console/Output/NullOutput.phpD	���cD	�FN�3vendor/symfony/console/SingleCommandApplication.phpG���cG�����3vendor/symfony/console/Tester/ApplicationTester.php�
���c�
h3��-vendor/symfony/console/Tester/TesterTrait.php����c���e�9vendor/symfony/console/Tester/CommandCompletionTester.php\���c\�2��@vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php����c�5�y%�/vendor/symfony/console/Tester/CommandTester.phpV	���cV	%F�ˤ!vendor/symfony/console/Cursor.phpG���cG����4vendor/symfony/console/Descriptor/JsonDescriptor.php����c�U��1�<vendor/symfony/console/Descriptor/ApplicationDescription.php4���c4ώ�*�3vendor/symfony/console/Descriptor/XmlDescriptor.phpE'���cE'�;[n�8vendor/symfony/console/Descriptor/MarkdownDescriptor.php����c��(箤4vendor/symfony/console/Descriptor/TextDescriptor.php.2���c.2�sXD�0vendor/symfony/console/Descriptor/Descriptor.php:���c:��o�9vendor/symfony/console/Descriptor/DescriptorInterface.phpY���cYsP�U�.vendor/symfony/string/Slugger/AsciiSlugger.phpA���cA�e��2vendor/symfony/string/Slugger/SluggerInterface.php����c�@aդ$vendor/symfony/string/LazyString.php|���c|1
�^�3vendor/symfony/string/Inflector/FrenchInflector.php@���c@0%���6vendor/symfony/string/Inflector/InflectorInterface.phpZ���cZR*��4vendor/symfony/string/Inflector/EnglishInflector.php&=���c&=1��]�6vendor/symfony/string/Exception/ExceptionInterface.phpg���cg��P�4vendor/symfony/string/Exception/RuntimeException.php����c�.m
�<vendor/symfony/string/Exception/InvalidArgumentException.php����c�8"�I�)vendor/symfony/string/CodePointString.php����c��ŵ �'vendor/symfony/string/UnicodeString.php�2���c�2��?��$vendor/symfony/string/ByteString.php�<���c�<��k�/vendor/symfony/string/AbstractUnicodeString.php�i���c�iI�nP�vendor/symfony/string/LICENSE)���c)=��<vendor/symfony/string/Resources/data/wcswidth_table_wide.php����c��W�<vendor/symfony/string/Resources/data/wcswidth_table_zero.php����c���ɤ-vendor/symfony/string/Resources/functions.phpt���ct��u�(vendor/symfony/string/AbstractString.php2O���c2O�4ep�+vendor/symfony/polyfill-ctype/bootstrap.php4���c4�Y6�%vendor/symfony/polyfill-ctype/LICENSE)���c)�`e0�'vendor/symfony/polyfill-ctype/Ctype.php����c����"�-vendor/symfony/polyfill-ctype/bootstrap80.phpp���cp���֤8vendor/symfony/service-contracts/ServiceLocatorTrait.php���c��ħ�;vendor/symfony/service-contracts/ServiceSubscriberTrait.php����c�4����@vendor/symfony/service-contracts/Attribute/SubscribedService.phpB���cBC��f�7vendor/symfony/service-contracts/Attribute/Required.php����c��$�3vendor/symfony/service-contracts/ResetInterface.php����c�M�E��?vendor/symfony/service-contracts/ServiceSubscriberInterface.php����c�0?Br�=vendor/symfony/service-contracts/ServiceProviderInterface.php����c��ENF�(vendor/symfony/service-contracts/LICENSE)���c)5古"vendor/symfony/filesystem/Path.phpf���cfJ�¨�:vendor/symfony/filesystem/Exception/ExceptionInterface.php����c�{H9�=vendor/symfony/filesystem/Exception/FileNotFoundException.php����c��va��8vendor/symfony/filesystem/Exception/RuntimeException.php����c��_
�3vendor/symfony/filesystem/Exception/IOException.php����c�G1�)�<vendor/symfony/filesystem/Exception/IOExceptionInterface.php����c��QQH�@vendor/symfony/filesystem/Exception/InvalidArgumentException.php����c���ɿ�!vendor/symfony/filesystem/LICENSE)���c)a�x�(vendor/symfony/filesystem/Filesystem.phprt���crtt���2vendor/symfony/polyfill-intl-grapheme/Grapheme.php&���c&�t|K�3vendor/symfony/polyfill-intl-grapheme/bootstrap.php�	���c�	M�ޤ-vendor/symfony/polyfill-intl-grapheme/LICENSE)���c)�\��5vendor/symfony/polyfill-intl-grapheme/bootstrap80.phpI���cI�x�5vendor/symfony/polyfill-intl-normalizer/bootstrap.php0���c03PyŤ/vendor/symfony/polyfill-intl-normalizer/LICENSE)���c)�\��6vendor/symfony/polyfill-intl-normalizer/Normalizer.phpO$���cO$ra��Fvendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php����c��8�j�Xvendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php�����c����b�Rvendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php�=���c�=���Tvendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php�����c��X3��Lvendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php�.���c�.Y��v�7vendor/symfony/polyfill-intl-normalizer/bootstrap80.php+���c+�!Τ+vendor/symfony/polyfill-php73/bootstrap.php����c�$�͓�%vendor/symfony/polyfill-php73/LICENSE)���c)�`e0�?vendor/symfony/polyfill-php73/Resources/stubs/JsonException.phph���ch�Ф'vendor/symfony/polyfill-php73/Php73.php����c�b��C�&vendor/webmozart/assert/src/Assert.php�����c����Ga�%vendor/webmozart/assert/src/Mixin.php=����c=�(Ɩ�8vendor/webmozart/assert/src/InvalidArgumentException.phpq���cq�x��vendor/webmozart/assert/LICENSE<���c<t�}��7vendor/psr/container/src/NotFoundExceptionInterface.php����c��7�
�8vendor/psr/container/src/ContainerExceptionInterface.php����c�8��t�/vendor/psr/container/src/ContainerInterface.php&���c&�Ć�vendor/psr/container/LICENSEy���cy�O�p�vendor/psr/log/LICENSE=���c=p��O�*vendor/psr/log/Psr/Log/LoggerInterface.php9���c9�ZҤ/vendor/psr/log/Psr/Log/LoggerAwareInterface.php@���c@���	�)vendor/psr/log/Psr/Log/AbstractLogger.php0���c0G�¤#vendor/psr/log/Psr/Log/LogLevel.phpP���cP�W\{�&vendor/psr/log/Psr/Log/LoggerTrait.phpf
���cf
-�mg�%vendor/psr/log/Psr/Log/NullLogger.php����c��M;�+vendor/psr/log/Psr/Log/LoggerAwareTrait.php����c����D�3vendor/psr/log/Psr/Log/InvalidArgumentException.phpw���cw#��"vendor/sebastian/diff/src/Line.php[���c[�H�@vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php���c=�l	�>vendor/sebastian/diff/src/Exception/ConfigurationException.phpL���cL��M�1vendor/sebastian/diff/src/Exception/Exception.phpy���cySHΣ�@vendor/sebastian/diff/src/Exception/InvalidArgumentException.php����c�]���#vendor/sebastian/diff/src/Chunk.phpn���cn���u�Ovendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php����c�.���"vendor/sebastian/diff/src/Diff.phpy���cy�gq<�$vendor/sebastian/diff/src/Differ.php:$���c:$Mn�H�$vendor/sebastian/diff/src/Parser.php����c��	���?vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php���c���x�:vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php����c���ޤ=vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php\���c\L���Cvendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php�(���c�(��٬�?vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php#���c#oM2ĤMvendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php���c���vendor/sebastian/diff/LICENSE
���c
a��1�;vendor/felixfbecker/advanced-json-rpc/lib/ErrorResponse.phpr���cr���6vendor/felixfbecker/advanced-json-rpc/lib/Response.php����c��㉑�7vendor/felixfbecker/advanced-json-rpc/lib/ErrorCode.php
���c
�Q�ɤ=vendor/felixfbecker/advanced-json-rpc/lib/SuccessResponse.phph���chO�zZ�:vendor/felixfbecker/advanced-json-rpc/lib/Notification.php����c�Jd	��8vendor/felixfbecker/advanced-json-rpc/lib/Dispatcher.php����c�p��5vendor/felixfbecker/advanced-json-rpc/lib/Message.php���c��cS�3vendor/felixfbecker/advanced-json-rpc/lib/Error.php����c�S�o�5vendor/felixfbecker/advanced-json-rpc/lib/Request.php����c���^�-vendor/felixfbecker/advanced-json-rpc/LICENSE����c�>��9�>vendor/felixfbecker/language-server-protocol/package-lock.jsonN���cNj�\�Ivendor/felixfbecker/language-server-protocol/src/SignatureHelpOptions.php����c�$t�]vendor/felixfbecker/language-server-protocol/src/SemanticTokensClientCapabilitiesRequests.php����c�m�S��:vendor/felixfbecker/language-server-protocol/src/Hover.php����c����,�^vendor/felixfbecker/language-server-protocol/src/DocumentRangeFormattingClientCapabilities.php����c����Uvendor/felixfbecker/language-server-protocol/src/TypeDefinitionClientCapabilities.php���c!.T�Ovendor/felixfbecker/language-server-protocol/src/InitializeResultServerInfo.php����c���M=�_vendor/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItem.php����c�H�y�Dvendor/felixfbecker/language-server-protocol/src/CodeDescription.php����c��ڨ^�Gvendor/felixfbecker/language-server-protocol/src/DiagnosticSeverity.phpk���ck�Ϥ��Fvendor/felixfbecker/language-server-protocol/src/FormattingOptions.php����c��u���Ovendor/felixfbecker/language-server-protocol/src/CompletionItemLabelDetails.php~���c~�v,�=vendor/felixfbecker/language-server-protocol/src/Location.php)���c)�iM�Cvendor/felixfbecker/language-server-protocol/src/CompletionItem.php����c��m�Lvendor/felixfbecker/language-server-protocol/src/TextDocumentSyncOptions.php����c��l��Mvendor/felixfbecker/language-server-protocol/src/RenameClientCapabilities.php���c�`�ϤEvendor/felixfbecker/language-server-protocol/src/InsertTextFormat.php����c�<YIG�Fvendor/felixfbecker/language-server-protocol/src/DocumentHighlight.php����c���X�Yvendor/felixfbecker/language-server-protocol/src/ShowMessageRequestClientCapabilities.php����c��hV��Evendor/felixfbecker/language-server-protocol/src/ReferenceContext.php����c��N�]�Bvendor/felixfbecker/language-server-protocol/src/DiagnosticTag.php@���c@:��L�Wvendor/felixfbecker/language-server-protocol/src/TextDocumentSyncClientCapabilities.phpJ���cJ4B�դFvendor/felixfbecker/language-server-protocol/src/SymbolInformation.php����c�e��T�Svendor/felixfbecker/language-server-protocol/src/TextDocumentContentChangeEvent.phpr���cr=���Hvendor/felixfbecker/language-server-protocol/src/FailureHandlingKind.php=���c=(�Ҕ�?vendor/felixfbecker/language-server-protocol/src/SymbolKind.php���c	��^�Xvendor/felixfbecker/language-server-protocol/src/DocumentHighlightClientCapabilities.php���c^��U�kvendor/felixfbecker/language-server-protocol/src/WorkspaceEditClientCapabilitiesChangeAnnotationSupport.php����c���0�@vendor/felixfbecker/language-server-protocol/src/SaveOptions.php'���c'7��t�Gvendor/felixfbecker/language-server-protocol/src/CompletionItemKind.php����c�1-K�_vendor/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionList.php����c���պ�Ovendor/felixfbecker/language-server-protocol/src/MarkdownClientCapabilities.php����c���붤:vendor/felixfbecker/language-server-protocol/src/Range.php����c�-�d��Nvendor/felixfbecker/language-server-protocol/src/ClientCapabilitiesGeneral.php����c�_��@�=vendor/felixfbecker/language-server-protocol/src/Position.php����c��ja�Evendor/felixfbecker/language-server-protocol/src/SymbolDescriptor.php����c�<��Tvendor/felixfbecker/language-server-protocol/src/DocumentColorClientCapabilities.php����c�M��8�Qvendor/felixfbecker/language-server-protocol/src/DefinitionClientCapabilities.phpo���co��}ʤBvendor/felixfbecker/language-server-protocol/src/SignatureHelp.php$���c$��-�Hvendor/felixfbecker/language-server-protocol/src/DependencyReference.php����c�@i��Kvendor/felixfbecker/language-server-protocol/src/TextDocumentIdentifier.php����c�"&���Lvendor/felixfbecker/language-server-protocol/src/HoverClientCapabilities.phpE���cE	��Tvendor/felixfbecker/language-server-protocol/src/CallHierarchyClientCapabilities.phpH���cH�M
I�Yvendor/felixfbecker/language-server-protocol/src/PublishDiagnosticsClientCapabilities.php����c���&��tvendor/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemInsertTextModeSupport.php����c�)J��^vendor/felixfbecker/language-server-protocol/src/ClientCapabilitiesWorkspaceFileOperations.phpn���cn��k�Fvendor/felixfbecker/language-server-protocol/src/MessageActionItem.phpq���cq!_�>vendor/felixfbecker/language-server-protocol/src/ErrorCode.phpi���ci���?vendor/felixfbecker/language-server-protocol/src/MarkupKind.php$���c$�pY�@vendor/felixfbecker/language-server-protocol/src/TokenFormat.php����c����dvendor/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesResolveSupport.php����c���~�_vendor/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilitiesTagSupport.phpK���cK�4�Avendor/felixfbecker/language-server-protocol/src/MarkedString.php����c�8@xȤ?vendor/felixfbecker/language-server-protocol/src/LogMessage.php6���c6�1�Evendor/felixfbecker/language-server-protocol/src/InitializeResult.php����c��5ّ�Bvendor/felixfbecker/language-server-protocol/src/WorkspaceEdit.php>	���c>	��nS�Fvendor/felixfbecker/language-server-protocol/src/PackageDescriptor.php����c��(��Uvendor/felixfbecker/language-server-protocol/src/ExecuteCommandClientCapabilities.phpy���cy��?vendor/felixfbecker/language-server-protocol/src/Diagnostic.php����c�U��ۤ`vendor/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesTagSupport.php���c�;8��Yvendor/felixfbecker/language-server-protocol/src/LinkedEditingRangeClientCapabilities.phpL���cL����Tvendor/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilities.php����c�k�}0�Pvendor/felixfbecker/language-server-protocol/src/ReferenceClientCapabilities.phpw���cw?H�H�Nvendor/felixfbecker/language-server-protocol/src/SymbolLocationInformation.phpz���cz[���Svendor/felixfbecker/language-server-protocol/src/ShowDocumentClientCapabilities.phpV���cV�x(�Cvendor/felixfbecker/language-server-protocol/src/CodeActionKind.php����c���O�Gvendor/felixfbecker/language-server-protocol/src/ClientCapabilities.php����c���uۤTvendor/felixfbecker/language-server-protocol/src/VersionedTextDocumentIdentifier.php����c�e[��Ivendor/felixfbecker/language-server-protocol/src/TextDocumentSyncKind.php>���c>��x�Yvendor/felixfbecker/language-server-protocol/src/RegularExpressionsClientCapabilities.php[���c[��
^�jvendor/felixfbecker/language-server-protocol/src/ShowMessageRequestClientCapabilitiesMessageActionItem.php
���c
�դGvendor/felixfbecker/language-server-protocol/src/CodeActionDisabled.php����c��ƀ�Vvendor/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilities.php����c� e��Fvendor/felixfbecker/language-server-protocol/src/CompletionContext.php$���c$��)�Pvendor/felixfbecker/language-server-protocol/src/ClientCapabilitiesWorkspace.phpi���ci�	�Uvendor/felixfbecker/language-server-protocol/src/SelectionRangeClientCapabilities.phpJ���cJ0�Q��Svendor/felixfbecker/language-server-protocol/src/TextDocumentClientCapabilities.php+���c+!r��Uvendor/felixfbecker/language-server-protocol/src/SemanticTokensClientCapabilities.php����c��Տ�_vendor/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilitiesSymbolKind.php����c���}ФEvendor/felixfbecker/language-server-protocol/src/TextDocumentItem.php����c�&�ts�Evendor/felixfbecker/language-server-protocol/src/ChangeAnnotation.php����c���`��?vendor/felixfbecker/language-server-protocol/src/ClientInfo.php ���c �1��Xvendor/felixfbecker/language-server-protocol/src/CodeLensWorkspaceClientCapabilities.php����c�=�YͤRvendor/felixfbecker/language-server-protocol/src/PrepareSupportDefaultBehavior.php
���c
|e�c�>vendor/felixfbecker/language-server-protocol/src/SymbolTag.php-���c-Cj�դ_vendor/felixfbecker/language-server-protocol/src/DocumentOnTypeFormattingClientCapabilities.php����c�ܱZ0�ivendor/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesCodeActionLiteralSupport.php���ctkO�mvendor/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemResolveSupport.php����c���_�Cvendor/felixfbecker/language-server-protocol/src/InsertTextMode.php����c���&�Dvendor/felixfbecker/language-server-protocol/src/WorkspaceFolder.php����c���r�_vendor/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesResolveSupport.php����c���\��hvendor/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilitiesSignatureInformation.php����c�
�t�Fvendor/felixfbecker/language-server-protocol/src/CodeActionContext.php,���c,��շ�Svendor/felixfbecker/language-server-protocol/src/DocumentLinkClientCapabilities.php����c��p�Q�Qvendor/felixfbecker/language-server-protocol/src/DiagnosticRelatedInformation.php����c����֤Jvendor/felixfbecker/language-server-protocol/src/ResourceOperationKind.php����c��8+�<vendor/felixfbecker/language-server-protocol/src/Command.php����c�6;o��Tvendor/felixfbecker/language-server-protocol/src/DocumentOnTypeFormattingOptions.php���c�(פJvendor/felixfbecker/language-server-protocol/src/ExecuteCommandOptions.phpg���cg�<��Mvendor/felixfbecker/language-server-protocol/src/ClientCapabilitiesWindow.phpE���cE�װn�Qvendor/felixfbecker/language-server-protocol/src/CodeActionClientCapabilities.php�	���c�	Tm¤ivendor/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemTagSupport.php����c�k��n�Tvendor/felixfbecker/language-server-protocol/src/WorkspaceEditClientCapabilities.php����c��X���Uvendor/felixfbecker/language-server-protocol/src/ImplementationClientCapabilities.php���c��m:�Uvendor/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilities.php����c�8}4��Jvendor/felixfbecker/language-server-protocol/src/DocumentHighlightKind.php����c����Ivendor/felixfbecker/language-server-protocol/src/ParameterInformation.php����c�"/��cvendor/felixfbecker/language-server-protocol/src/PublishDiagnosticsClientCapabilitiesTagSupport.php����c��_���Fvendor/felixfbecker/language-server-protocol/src/CompletionOptions.php����c���)%�Bvendor/felixfbecker/language-server-protocol/src/MarkupContent.php����c�ϳP��?vendor/felixfbecker/language-server-protocol/src/CodeAction.php���cm1f�wvendor/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind.php����c�S�s+�Rvendor/felixfbecker/language-server-protocol/src/DeclarationClientCapabilities.php����c�(���^vendor/felixfbecker/language-server-protocol/src/SemanticTokensWorkspaceClientCapabilities.php����c�.�e�]vendor/felixfbecker/language-server-protocol/src/DidChangeConfigurationClientCapabilities.php����c�F��/�Yvendor/felixfbecker/language-server-protocol/src/DocumentFormattingClientCapabilities.php����c�l4�a�|vendor/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilitiesSignatureInformationParameterInformation.php!���c!��WؤOvendor/felixfbecker/language-server-protocol/src/CodeLensClientCapabilities.php����c�P�^�\vendor/felixfbecker/language-server-protocol/src/DidChangeWatchedFilesClientCapabilities.php���cԽ�:�Nvendor/felixfbecker/language-server-protocol/src/MonikerClientCapabilities.phpA���cAؔ��Gvendor/felixfbecker/language-server-protocol/src/ContentChangeEvent.phpf���cf4��G�Ivendor/felixfbecker/language-server-protocol/src/SignatureInformation.php����c��n�=�=vendor/felixfbecker/language-server-protocol/src/TextEdit.phpz���czyV��>vendor/felixfbecker/language-server-protocol/src/FileEvent.php����c������Svendor/felixfbecker/language-server-protocol/src/FoldingRangeClientCapabilities.php���cY�դ=vendor/felixfbecker/language-server-protocol/src/LogTrace.php����c�*g �Jvendor/felixfbecker/language-server-protocol/src/CompletionTriggerKind.php6���c6aU��Dvendor/felixfbecker/language-server-protocol/src/CodeLensOptions.phpq���cqSu��Qvendor/felixfbecker/language-server-protocol/src/CompletionClientCapabilities.phpl���cl|�8.�Ivendor/felixfbecker/language-server-protocol/src/ReferenceInformation.php`���c`;H���`vendor/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesSymbolKind.php���c�T�ƤFvendor/felixfbecker/language-server-protocol/src/CompletionItemTag.php����c�ۂ��Gvendor/felixfbecker/language-server-protocol/src/ServerCapabilities.php����c��e���@vendor/felixfbecker/language-server-protocol/src/MessageType.phpk���ck(I���=vendor/felixfbecker/language-server-protocol/src/CodeLens.php����c�lJ�>�Cvendor/felixfbecker/language-server-protocol/src/CompletionList.php����c��ꊪ�Cvendor/felixfbecker/language-server-protocol/src/FileChangeType.phpT���cTL,W��Jvendor/felixfbecker/language-server-protocol/src/CodeActionTriggerKind.php����c��}Ф9vendor/felixfbecker/language-server-protocol/package.jsonN���cN2W>��4vendor/felixfbecker/language-server-protocol/LICENSE����c�>��9�4vendor/fidry/cpu-core-counter/src/CpuCoreCounter.phpw���cw��/vendor/fidry/cpu-core-counter/src/Diagnoser.php����c����3vendor/fidry/cpu-core-counter/src/Exec/ProcOpen.php����c�TY.��=vendor/fidry/cpu-core-counter/src/NumberOfCpuCoreNotFound.php(���c(��:vendor/fidry/cpu-core-counter/src/Finder/CpuInfoFinder.php����c�_\��;vendor/fidry/cpu-core-counter/src/Finder/FinderRegistry.php����c��6n��=vendor/fidry/cpu-core-counter/src/Finder/HwPhysicalFinder.php~���c~�w�ä@vendor/fidry/cpu-core-counter/src/Finder/SkipOnWindowsFinder.php"���c"�E���=vendor/fidry/cpu-core-counter/src/Finder/NProcessorFinder.php���cb��@vendor/fidry/cpu-core-counter/src/Finder/ProcOpenBasedFinder.phpJ���cJ`���:vendor/fidry/cpu-core-counter/src/Finder/CpuCoreFinder.php���c��פ>vendor/fidry/cpu-core-counter/src/Finder/NullCpuCoreFinder.php����c����>vendor/fidry/cpu-core-counter/src/Finder/_NProcessorFinder.php����c� 2���>vendor/fidry/cpu-core-counter/src/Finder/WmicLogicalFinder.php����c��EΤ?vendor/fidry/cpu-core-counter/src/Finder/WmicPhysicalFinder.php����c�O��ڤ?vendor/fidry/cpu-core-counter/src/Finder/DummyCpuCoreFinder.phpE���cE<��#�8vendor/fidry/cpu-core-counter/src/Finder/NProcFinder.php����c��h��@vendor/fidry/cpu-core-counter/src/Finder/OnlyOnWindowsFinder.php/���c/�#1��<vendor/fidry/cpu-core-counter/src/Finder/HwLogicalFinder.phpz���cz"�٤.vendor/fidry/cpu-core-counter/bin/diagnose.phpx���cx8t�@�-vendor/fidry/cpu-core-counter/bin/execute.phpw���cw�
���
config.xsd.����c.����src/Psalm/StatementsSource.php����c��lĤ$src/Psalm/Report/SonarqubeReport.php���c�Vˤ&src/Psalm/Report/JsonSummaryReport.php����c��T�ۤ&src/Psalm/Report/CodeClimateReport.phpZ	���cZ	��+ � src/Psalm/Report/CountReport.php���c�E�Ť"src/Psalm/Report/ConsoleReport.php'���c' ρ&�(src/Psalm/Report/GithubActionsReport.phpm���cm���$�"src/Psalm/Report/ReportOptions.php\���c\bx��src/Psalm/Report/JsonReport.php���cmࢶ�"src/Psalm/Report/CompactReport.php�	���c�	���j� src/Psalm/Report/SarifReport.php%���c%��	_� src/Psalm/Report/EmacsReport.php���cσɼ�src/Psalm/Report/TextReport.php���c�L]
�.src/Psalm/Report/ByIssueLevelAndTypeReport.php����c��;��%src/Psalm/Report/CheckstyleReport.php����c��y���src/Psalm/Report/XmlReport.php����c�tt�B�!src/Psalm/Report/PylintReport.php+���c+%�/a�#src/Psalm/Report/PhpStormReport.phpv���cvDK{� src/Psalm/Report/JunitReport.php����c�ҁ1�!src/Psalm/Config/IssueHandler.php���c���&src/Psalm/Config/ProjectFileFilter.php�	���c�	�&���src/Psalm/Config/Creator.php� ���c� ���=�src/Psalm/Config/FileFilter.php�H���c�H/�z�,src/Psalm/Config/TaintAnalysisFileFilter.phpz���cz"��)src/Psalm/Config/ErrorLevelFileFilter.php����c��YǤsrc/Psalm/Progress/Progress.phpU���cU���V�&src/Psalm/Progress/DefaultProgress.php����c�
m�m�#src/Psalm/Progress/LongProgress.php"
���c"
���q�#src/Psalm/Progress/VoidProgress.php����c���_�$src/Psalm/Progress/DebugProgress.php���crF
E�"src/Psalm/Issue/InvalidOperand.php����c��gū�&src/Psalm/Issue/TaintedUnserialize.php����c�>��ͤ,src/Psalm/Issue/UndefinedInterfaceMethod.php����c��hL��(src/Psalm/Issue/MixedReturnStatement.php����c�����*src/Psalm/Issue/MixedArrayTypeCoercion.php����c�љ�&�(src/Psalm/Issue/PossiblyNullArgument.php����c�4>�c�&src/Psalm/Issue/InvalidArrayOffset.php����c��PZ�*src/Psalm/Issue/UndefinedDocblockClass.php����c����(�%src/Psalm/Issue/MissingReturnType.php����c���׊�3src/Psalm/Issue/MismatchingDocblockPropertyType.php����c�g4��&src/Psalm/Issue/DeprecatedProperty.php����c��h
z�(src/Psalm/Issue/PossiblyNullIterator.php����c���(src/Psalm/Issue/PossiblyUnusedMethod.php����c����:src/Psalm/Issue/RedundantFunctionCallGivenDocblockType.php����c��R���%src/Psalm/Issue/DuplicateConstant.php����c���$\�0src/Psalm/Issue/MismatchingDocblockParamType.php����c����(src/Psalm/Issue/InvalidEnumCaseValue.php����c���ܤ0src/Psalm/Issue/TraitMethodSignatureMismatch.php����c��7¤/src/Psalm/Issue/UnimplementedAbstractMethod.php����c���
��-src/Psalm/Issue/PossiblyNullPropertyFetch.php:���c:o��!src/Psalm/Issue/FunctionIssue.php����c�C�N�-src/Psalm/Issue/PossiblyInvalidMethodCall.php����c�-u��1src/Psalm/Issue/MismatchingDocblockReturnType.php����c��Oy��"src/Psalm/Issue/ImpureVariable.php����c�k�
�!src/Psalm/Issue/InternalClass.php����c���W�-src/Psalm/Issue/MixedArgumentTypeCoercion.php����c�����4src/Psalm/Issue/NonInvariantDocblockPropertyType.php����c��2
¤!src/Psalm/Issue/ForbiddenCode.php����c�y�6��!src/Psalm/Issue/TaintedCustom.php����c�i��T�"src/Psalm/Issue/TaintedInclude.php����c�`��!src/Psalm/Issue/TaintedCookie.php����c�5R�*src/Psalm/Issue/InvalidReturnStatement.php����c�qaT�src/Psalm/Issue/ParseError.php����c�����$src/Psalm/Issue/NoEnumProperties.php����c����/src/Psalm/Issue/MixedStringOffsetAssignment.php����c��>�(src/Psalm/Issue/InvalidPropertyFetch.php����c�RFO�3src/Psalm/Issue/PossiblyUndefinedIntArrayOffset.php����c�I�MΤ7src/Psalm/Issue/PossiblyNullPropertyAssignmentValue.php����c���0�%src/Psalm/Issue/DuplicateEnumCase.php����c��%*Ť(src/Psalm/Issue/InvalidTemplateParam.php����c�!a�� src/Psalm/Issue/UnusedMethod.php����c�cѳ��-src/Psalm/Issue/PossiblyUndefinedVariable.php����c�$��&src/Psalm/Issue/DeprecatedConstant.php����c�p'+դ6src/Psalm/Issue/PossiblyUndefinedStringArrayOffset.php����c��u��(src/Psalm/Issue/MissingTemplateParam.php����c�9=௤'src/Psalm/Issue/ContinueOutsideLoop.php����c� �KA�/src/Psalm/Issue/ImpureByReferenceAssignment.php����c�|�ҍ�&src/Psalm/Issue/InvalidExtendClass.php����c�a Ȥsrc/Psalm/Issue/MethodIssue.php����c�Lup�!src/Psalm/Issue/VariableIssue.php����c�"�vG�!src/Psalm/Issue/InvalidParent.php����c����7� src/Psalm/Issue/InvalidScope.php����c��ߏǤ4src/Psalm/Issue/InvalidTraversableImplementation.php����c�����!src/Psalm/Issue/ComplexMethod.php����c�0Z�B�&src/Psalm/Issue/PsalmInternalError.php����c���a3�,src/Psalm/Issue/InvalidDocblockParamName.php����c����Z�*src/Psalm/Issue/UnrecognizedExpression.php����c��0��!src/Psalm/Issue/TaintedHeader.php����c���[ݤ*src/Psalm/Issue/DuplicateEnumCaseValue.php����c���e�%src/Psalm/Issue/ParamNameMismatch.php����c���T�&src/Psalm/Issue/DeprecatedFunction.php����c��_�Ĥ*src/Psalm/Issue/NullPropertyAssignment.php0���c06���#src/Psalm/Issue/NullArrayOffset.php����c���6��*src/Psalm/Issue/UndefinedPropertyFetch.php����c�Mn��.src/Psalm/Issue/PossiblyInvalidArrayOffset.php����c��u�ۤ#src/Psalm/Issue/DeprecatedTrait.php����c�Iݰ��src/Psalm/Issue/NullOperand.php����c�EwV�+src/Psalm/Issue/OverriddenFinalConstant.php����c�w�7�$src/Psalm/Issue/InternalProperty.php����c���`w�'src/Psalm/Issue/PossiblyInvalidCast.php����c��l:�%src/Psalm/Issue/MixedFunctionCall.php����c�ӭ���2src/Psalm/Issue/RedundantCastGivenDocblockType.php����c�Y�ߤ"src/Psalm/Issue/UndefinedTrace.php����c����$�src/Psalm/Issue/TaintedFile.php���c��¤+src/Psalm/Issue/PossiblyNullArrayAccess.php8���c8*�'M�"src/Psalm/Issue/UndefinedTrait.php����c����Ϥsrc/Psalm/Issue/InvalidCast.php����c�y��e�5src/Psalm/Issue/LessSpecificImplementedReturnType.php����c��!�3�#src/Psalm/Issue/UndefinedMethod.php����c�%��Ӥ*src/Psalm/Issue/PossiblyInvalidOperand.php����c���Ȥ#src/Psalm/Issue/InvalidToString.php����c�����0src/Psalm/Issue/PossiblyInvalidPropertyFetch.php����c�Y9�k�,src/Psalm/Issue/MissingClosureReturnType.php����c��KI� src/Psalm/Issue/InvalidClone.php����c��?���-src/Psalm/Issue/MixedPropertyTypeCoercion.php���cp/=̤0src/Psalm/Issue/ReferenceConstraintViolation.php����c�����(src/Psalm/Issue/ImpureStaticVariable.php����c���2B�(src/Psalm/Issue/ImplicitToStringCast.php����c��nUv�%src/Psalm/Issue/UndefinedFunction.php����c�N���'src/Psalm/Issue/PossiblyNullOperand.php����c��
R[�8src/Psalm/Issue/RedundantPropertyInitializationCheck.php����c�֕�.src/Psalm/Issue/ConstantDeclarationInTrait.php����c�7�l�src/Psalm/Issue/Trace.php����c��)�)src/Psalm/Issue/TaintedTextWithQuotes.php����c�pLX9�0src/Psalm/Issue/ConstructorSignatureMismatch.php����c�yg֤)src/Psalm/Issue/UninitializedProperty.php����c�[J41�-src/Psalm/Issue/InaccessibleClassConstant.php����c����"src/Psalm/Issue/UnusedVariable.php����c��&�3src/Psalm/Issue/UndefinedThisPropertyAssignment.php����c���֤*src/Psalm/Issue/InvalidPassByReference.php����c�����#src/Psalm/Issue/InvalidDocblock.php����c�Q}J�2src/Psalm/Issue/InvalidConstantAssignmentValue.php����c���Z�%src/Psalm/Issue/UnusedReturnValue.php����c���Y��,src/Psalm/Issue/OverriddenPropertyAccess.php����c�l*�*src/Psalm/Issue/InvalidLiteralArgument.php����c��T�+src/Psalm/Issue/MixedInferredReturnType.php����c��)b�'src/Psalm/Issue/UnresolvableInclude.php����c� $�k�*src/Psalm/Issue/MoreSpecificReturnType.php����c�����&src/Psalm/Issue/UnusedFunctionCall.php����c�O�ԅ�'src/Psalm/Issue/UnsafeInstantiation.php����c��w�&�*src/Psalm/Issue/TypeDoesNotContainNull.php����c�淽Ф&src/Psalm/Issue/ImpureFunctionCall.php����c�e�?e�%src/Psalm/Issue/NonStaticSelfCall.php����c�R���*src/Psalm/Issue/InvalidArrayAssignment.php����c�j!��/src/Psalm/Issue/OverriddenInterfaceConstant.php����c���Q�(src/Psalm/Issue/MixedArrayAssignment.php����c���4�0src/Psalm/Issue/UnimplementedInterfaceMethod.php����c��2�� src/Psalm/Issue/TaintedShell.php����c�Q���*src/Psalm/Issue/OverriddenMethodAccess.php����c�ˡ�&src/Psalm/Issue/MixedPropertyFetch.php����c�ĤΤ4src/Psalm/Issue/MoreSpecificImplementedParamType.php����c���¤/src/Psalm/Issue/PropertyNotSetInConstructor.php����c��
�0�src/Psalm/Issue/RiskyCast.php����c�W�˖�4src/Psalm/Issue/UndefinedMagicPropertyAssignment.php����c�޾פ)src/Psalm/Issue/PossiblyFalseArgument.php����c���]��(src/Psalm/Issue/PossiblyFalseOperand.php����c���Τ$src/Psalm/Issue/IfThisIsMismatch.php����c�aŔ�$src/Psalm/Issue/DeprecatedMethod.php����c����:src/Psalm/Issue/PossiblyInvalidPropertyAssignmentValue.php����c��T��(src/Psalm/Issue/UnresolvableConstant.php����c�Яt�&src/Psalm/Issue/InaccessibleMethod.php����c��-�_�#src/Psalm/Issue/InvalidArgument.php����c�dYԪ�1src/Psalm/Issue/LessSpecificClassConstantType.php����c�f���-src/Psalm/Issue/PossiblyUnusedReturnValue.php����c����#src/Psalm/Issue/DeprecatedClass.php����c�H�n� src/Psalm/Issue/NullIterator.php����c��Qyh�(src/Psalm/Issue/PropertyTypeCoercion.php����c�N�i�!src/Psalm/Issue/InvalidGlobal.php����c��Y@.�$src/Psalm/Issue/MixedArrayOffset.php����c��I��src/Psalm/Issue/ClassIssue.php����c��nۤ)src/Psalm/Issue/RedundantFunctionCall.php����c����
�$src/Psalm/Issue/MixedArrayAccess.php����c�\O�Ѥ&src/Psalm/Issue/UnusedClosureParam.php����c�R 0/�*src/Psalm/Issue/InvalidEnumBackingType.php����c��o�r�%src/Psalm/Issue/InvalidReturnType.php����c�(����"src/Psalm/Issue/UndefinedClass.php����c�����.src/Psalm/Issue/MissingImmutableAnnotation.php����c�/�m�&src/Psalm/Issue/AbstractMethodCall.php����c���d�%src/Psalm/Issue/InvalidMethodCall.php����c�HE���&src/Psalm/Issue/UndefinedInterface.php����c��o�%src/Psalm/Issue/MissingDependency.php����c�Ӭ�1src/Psalm/Issue/ExtensionRequirementViolation.php����c���I��src/Psalm/Issue/ConfigIssue.php����c��µ �2src/Psalm/Issue/InvalidPropertyAssignmentValue.php����c���m�!src/Psalm/Issue/NullReference.php����c���Ф/src/Psalm/Issue/PossiblyInvalidFunctionCall.php����c�ң�`�'src/Psalm/Issue/InvalidFunctionCall.php����c���N�$src/Psalm/Issue/EmptyArrayAccess.php����c�RX�R�"src/Psalm/Issue/InternalMethod.php����c��!�1�*src/Psalm/Issue/InterfaceInstantiation.php����c�^�ᔤ src/Psalm/Issue/InvalidClass.php����c��e��+src/Psalm/Issue/PossiblyInvalidArgument.php����c�o#��#src/Psalm/Issue/TooFewArguments.php����c�iH�8�%src/Psalm/Issue/TaintedUserSecret.php����c��n�+src/Psalm/Issue/PossiblyNullArrayOffset.php����c�xm�.src/Psalm/Issue/UncaughtThrowInGlobalScope.php����c�����,src/Psalm/Issue/NonInvariantPropertyType.php����c�c���-src/Psalm/Issue/InvalidNullableReturnType.php����c��DH�'src/Psalm/Issue/MissingPropertyType.php����c�����#src/Psalm/Issue/MixedMethodCall.php����c�?E�ͤ src/Psalm/Issue/ReservedWord.php����c�=��F� src/Psalm/Issue/NullArgument.php����c�M��l�'src/Psalm/Issue/UnusedBaselineEntry.php����c��
)�5src/Psalm/Issue/ReferenceReusedFromConfusingScope.php����c��ݪD�+src/Psalm/Issue/MixedReturnTypeCoercion.php����c��c�+�(src/Psalm/Issue/ImpureStaticProperty.php����c��0�i�$src/Psalm/Issue/ImpureMethodCall.php����c�����'src/Psalm/Issue/UnusedPsalmSuppress.php����c��ġ)�)src/Psalm/Issue/AbstractInstantiation.php����c��%�ɤ&src/Psalm/Issue/RawObjectIteration.php����c�4�@b�(src/Psalm/Issue/InaccessibleProperty.php����c���@�'src/Psalm/Issue/DeprecatedInterface.php����c��D�#src/Psalm/Issue/InvalidIterator.php����c�.�Q�$src/Psalm/Issue/InvalidAttribute.php����c��Ż��src/Psalm/Issue/TaintedSql.php~���c~�=���%src/Psalm/Issue/UndefinedConstant.php����c�Ȋ�Фsrc/Psalm/Issue/TaintedSSRF.php���cj_���+src/Psalm/Issue/NamedArgumentNotAllowed.php����c�2�G{�$src/Psalm/Issue/LoopInvalidation.php����c�2����#src/Psalm/Issue/MixedIssueTrait.php����c��q��'src/Psalm/Issue/TaintedSystemSecret.php����c�����+src/Psalm/Issue/NullableReturnStatement.php����c�
)��,src/Psalm/Issue/UnnecessaryVarAnnotation.php����c�6zb]�/src/Psalm/Issue/UndefinedPropertyAssignment.php����c�+M7�%src/Psalm/Issue/UndefinedVariable.php����c�G6���%src/Psalm/Issue/UnusedConstructor.php����c��ي��*src/Psalm/Issue/TypeDoesNotContainType.php����c�z`�I�src/Psalm/Issue/NoValue.php����c�`�w�#src/Psalm/Issue/DuplicateMethod.php����c��ʤU�(src/Psalm/Issue/InvalidNamedArgument.php����c�)��פ+src/Psalm/Issue/UnhandledMatchCondition.php����c�Ca�h�.src/Psalm/Issue/PossiblyInvalidDocblockTag.php����c�T�-�%src/Psalm/Issue/InvalidTypeImport.php����c���R��%src/Psalm/Issue/DuplicateFunction.php����c�Ҵ8K�#src/Psalm/Issue/MixedAssignment.php����c��¿�)src/Psalm/Issue/TooManyTemplateParams.php����c��^��!src/Psalm/Issue/MixedArgument.php����c�x
�+src/Psalm/Issue/MissingClosureParamType.php����c���R�'src/Psalm/Issue/InvalidParamDefault.php����c� q:� src/Psalm/Issue/FalseOperand.php����c����,src/Psalm/Issue/PossiblyNullFunctionCall.php����c���+src/Psalm/Issue/MixedPropertyAssignment.php����c�X���8src/Psalm/Issue/MethodSignatureMustProvideReturnType.php����c�11썤+src/Psalm/Issue/InvalidStaticInvocation.php����c�����src/Psalm/Issue/MixedClone.php����c����֤src/Psalm/Issue/MixedIssue.php����c���!Ϥ.src/Psalm/Issue/PossibleRawObjectIteration.php����c���M!�&src/Psalm/Issue/InvalidStringClass.php����c�5�J�.src/Psalm/Issue/UndefinedThisPropertyFetch.php����c����D�5src/Psalm/Issue/MethodSignatureMustOmitReturnType.php����c��i��2src/Psalm/Issue/ConflictingReferenceConstraint.php����c�tN���'src/Psalm/Issue/MissingDocblockType.php����c���L.�"src/Psalm/Issue/ParentNotFound.php����c���ޤ6src/Psalm/Issue/ImplementationRequirementViolation.php����c�-�Ϥ+src/Psalm/Issue/FalsableReturnStatement.php����c�����src/Psalm/Issue/TaintedHtml.php���c��$�!src/Psalm/Issue/PropertyIssue.php����c���̨�#src/Psalm/Issue/StringIncrement.php����c�kq���%src/Psalm/Issue/MutableDependency.php����c��5mݤ&src/Psalm/Issue/InvalidArrayAccess.php����c���ͤ&src/Psalm/Issue/ClassConstantIssue.php}���c}`0�ڤsrc/Psalm/Issue/PluginIssue.php]���c]䕿H�.src/Psalm/Issue/UnsafeGenericInstantiation.php����c���&�/src/Psalm/Issue/UndefinedMagicPropertyFetch.php����c�6K��)src/Psalm/Issue/PossiblyFalseIterator.php����c�f��G�"src/Psalm/Issue/DuplicateParam.php����c�M���#src/Psalm/Issue/UnevaluatedCode.php����c�"��0src/Psalm/Issue/ImplementedParamTypeMismatch.php����c����e� src/Psalm/Issue/InvalidCatch.php����c�UYje�0src/Psalm/Issue/PossiblyUndefinedArrayOffset.php����c��1��2src/Psalm/Issue/PossiblyInvalidArrayAssignment.php����c�����5src/Psalm/Issue/PossiblyInvalidPropertyAssignment.php����c�Zϙ�$src/Psalm/Issue/AssignmentToVoid.php����c�v�x(�%src/Psalm/Issue/DuplicateArrayKey.php����c���6�/src/Psalm/Issue/PossiblyNullArrayAssignment.php����c�c"=��)src/Psalm/Issue/MissingThrowsDocblock.php����c��Le��,src/Psalm/Issue/InvalidClassConstantType.php����c��4N��src/Psalm/Issue/CheckType.php����c�>�#C�'src/Psalm/Issue/ImpurePropertyFetch.php����c����Ȥ#src/Psalm/Issue/NullArrayAccess.php)���c)b�Nw�-src/Psalm/Issue/DocblockTypeContradiction.php����c�21�,src/Psalm/Issue/ImpurePropertyAssignment.php����c��h)�$src/Psalm/Issue/NullFunctionCall.php����c��јu�.src/Psalm/Issue/PossiblyInvalidArrayAccess.php����c��Qr<�-src/Psalm/Issue/RedundantIdentityWithTrue.php����c��y��$src/Psalm/Issue/UnusedMethodCall.php����c���r�0src/Psalm/Issue/AmbiguousConstantInheritance.php����c��K�(src/Psalm/Issue/PossiblyInvalidClone.php����c�j�Ő�"src/Psalm/Issue/UnusedProperty.php����c�U���src/Psalm/Issue/MissingFile.php|���c|��,�src/Psalm/Issue/UnusedClass.php����c����)src/Psalm/Issue/UnrecognizedStatement.php����c�5��w�-src/Psalm/Issue/UnsupportedReferenceUsage.php����c���y6�1src/Psalm/Issue/ImplementedReturnTypeMismatch.php����c���5��*src/Psalm/Issue/LessSpecificReturnType.php����c��yp�+src/Psalm/Issue/PossiblyInvalidIterator.php����c�|;B�&src/Psalm/Issue/UnusedForeachValue.php����c�p����'src/Psalm/Issue/PossiblyUnusedParam.php����c��H��)src/Psalm/Issue/NoInterfaceProperties.php����c�X7f�+src/Psalm/Issue/UndefinedAttributeClass.php����c������(src/Psalm/Issue/ParadoxicalCondition.php����c�
���2src/Psalm/Issue/PossiblyNullPropertyAssignment.php?���c?��*�&src/Psalm/Issue/RedundantCondition.php����c��X|Ϥsrc/Psalm/Issue/CodeIssue.php�	���c�	K�?�+src/Psalm/Issue/UndefinedGlobalVariable.php����c�GW턤%src/Psalm/Issue/NullPropertyFetch.php+���c+��3src/Psalm/Issue/PossiblyUndefinedGlobalVariable.php����c���ߤ src/Psalm/Issue/InvalidThrow.php����c�23���)src/Psalm/Issue/InvalidScalarArgument.php����c�@�A9�*src/Psalm/Issue/PossiblyUnusedProperty.php����c����/src/Psalm/Issue/LessSpecificReturnStatement.php����c��^�s�"src/Psalm/Issue/DuplicateClass.php����c�77*��-src/Psalm/Issue/InvalidPropertyAssignment.php����c�&f.�#src/Psalm/Issue/ComplexFunction.php����c��E��(src/Psalm/Issue/UndefinedMagicMethod.php����c��ڥ�src/Psalm/Issue/TaintedEval.php���c&sxP�!src/Psalm/Issue/ArgumentIssue.php����c���,�!src/Psalm/Issue/RedundantCast.php����c��b��)src/Psalm/Issue/PossiblyNullReference.php����c�2���7src/Psalm/Issue/RedundantConditionGivenDocblockType.php����c��D�<� src/Psalm/Issue/MixedOperand.php����c��|\�&src/Psalm/Issue/MissingConstructor.php����c���Q�8src/Psalm/Issue/PossiblyFalsePropertyAssignmentValue.php����c�J8��$src/Psalm/Issue/TooManyArguments.php����c�U��0�%src/Psalm/Issue/CircularReference.php����c��Y�j�+src/Psalm/Issue/PossiblyUndefinedMethod.php����c�����*src/Psalm/Issue/PossiblyFalseReference.php����c��W�Ϥ src/Psalm/Issue/TaintedInput.php���c���+src/Psalm/Issue/MethodSignatureMismatch.php����c�ūM��$src/Psalm/Issue/MissingParamType.php����c��j���-src/Psalm/Issue/InvalidFalsableReturnType.php����c�1D��src/Psalm/Issue/TaintedLdap.php���c��:�(src/Psalm/Issue/ArgumentTypeCoercion.php����c�Ӗ��#src/Psalm/Issue/TaintedCallable.php����c�\�ˤ%src/Psalm/Issue/InvalidEnumMethod.php����c�sx�P�src/Psalm/Issue/UnusedParam.php����c��/�i�=src/Psalm/Internal/Stubs/Generator/ClassLikeStubGenerator.phpP"���cP"b�g�5src/Psalm/Internal/Stubs/Generator/StubsGenerator.php3.���c3.���8src/Psalm/Internal/Provider/ClassLikeStorageProvider.php����c�!~��8src/Psalm/Internal/Provider/FileStorageCacheProvider.phpD���cD�r+�:src/Psalm/Internal/Provider/PropertyVisibilityProvider.php����c�@��w�)src/Psalm/Internal/Provider/Providers.phpt���ct{��O�4src/Psalm/Internal/Provider/MethodParamsProvider.php�	���c�	�ȝɤ4src/Psalm/Internal/Provider/PropertyTypeProvider.php����c�x��2src/Psalm/Internal/Provider/StatementsProvider.phpU:���cU:?Gxä:src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php����c����ޤCsrc/Psalm/Internal/Provider/AddRemoveTaints/HtmlFunctionTainter.php����c�r��Msrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPadReturnTypeProvider.php����c�~9hV�Tsrc/Psalm/Internal/Provider/ReturnTypeProvider/GetClassMethodsReturnTypeProvider.phpz���cz�9��[src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPointerAdjustmentReturnTypeProvider.php����c�XJ�Ksrc/Psalm/Internal/Provider/ReturnTypeProvider/PdoStatementSetFetchMode.php3
���c3
Kְ��Rsrc/Psalm/Internal/Provider/ReturnTypeProvider/GetObjectVarsReturnTypeProvider.php����c�#R�(�Hsrc/Psalm/Internal/Provider/ReturnTypeProvider/SimpleXmlElementAsXml.php<���c<-^���Rsrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillKeysReturnTypeProvider.php8���c8��+]�Psrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReduceReturnTypeProvider.php�$���c�$q��Lsrc/Psalm/Internal/Provider/ReturnTypeProvider/DirnameReturnTypeProvider.phpx���cxO[��Msrc/Psalm/Internal/Provider/ReturnTypeProvider/BasenameReturnTypeProvider.php����c�xZc�Tsrc/Psalm/Internal/Provider/ReturnTypeProvider/IteratorToArrayReturnTypeProvider.php����c������Esrc/Psalm/Internal/Provider/ReturnTypeProvider/DomNodeAppendChild.phpa���ca4�x�Nsrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayRandReturnTypeProvider.phpz���czhU
\�Osrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMergeReturnTypeProvider.php'���c'��{��Xsrc/Psalm/Internal/Provider/ReturnTypeProvider/ClosureFromCallableReturnTypeProvider.php����c�'B�Psrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php%���c%�\~�Ssrc/Psalm/Internal/Provider/ReturnTypeProvider/DateTimeModifyReturnTypeProvider.php����c���!��Ksrc/Psalm/Internal/Provider/ReturnTypeProvider/HexdecReturnTypeProvider.phpR���cR�ȤLsrc/Psalm/Internal/Provider/ReturnTypeProvider/InArrayReturnTypeProvider.php_	���c_	�v���Vsrc/Psalm/Internal/Provider/ReturnTypeProvider/ImagickPixelColorReturnTypeProvider.php�	���c�	��t��Nsrc/Psalm/Internal/Provider/ReturnTypeProvider/FilterVarReturnTypeProvider.phpi���ci�BI�Jsrc/Psalm/Internal/Provider/ReturnTypeProvider/RoundReturnTypeProvider.php7
���c7
p���Qsrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReverseReturnTypeProvider.php2	���c2	�D	��Ksrc/Psalm/Internal/Provider/ReturnTypeProvider/MktimeReturnTypeProvider.phpB���cBZO��Msrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPopReturnTypeProvider.php����c��cw>�Wsrc/Psalm/Internal/Provider/ReturnTypeProvider/MbInternalEncodingReturnTypeProvider.php4
���c4
? _�Qsrc/Psalm/Internal/Provider/ReturnTypeProvider/PdoStatementReturnTypeProvider.php����c����Msrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.phpB���cB��ᒤMsrc/Psalm/Internal/Provider/ReturnTypeProvider/ParseUrlReturnTypeProvider.php"���c"syhu�Ksrc/Psalm/Internal/Provider/ReturnTypeProvider/MinMaxReturnTypeProvider.phpx���cxms.�Psrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFilterReturnTypeProvider.php%���c%��r�Isrc/Psalm/Internal/Provider/ReturnTypeProvider/RandReturnTypeProvider.phpE���cE�u
Z�Ssrc/Psalm/Internal/Provider/ReturnTypeProvider/VersionCompareReturnTypeProvider.phpo���co�G�2�Psrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayUniqueReturnTypeProvider.php����c���)�Osrc/Psalm/Internal/Provider/ReturnTypeProvider/StrReplaceReturnTypeProvider.php\
���c\
)��"�Jsrc/Psalm/Internal/Provider/ReturnTypeProvider/StrTrReturnTypeProvider.php����c���TҤOsrc/Psalm/Internal/Provider/ReturnTypeProvider/ArraySliceReturnTypeProvider.php�
���c�
��'�Ssrc/Psalm/Internal/Provider/ReturnTypeProvider/FirstArgStringReturnTypeProvider.php����c�B����Qsrc/Psalm/Internal/Provider/ReturnTypeProvider/TriggerErrorReturnTypeProvider.php�	���c�	P��$�Nsrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillReturnTypeProvider.php����c�����Psrc/Psalm/Internal/Provider/ReturnTypeProvider/ArraySpliceReturnTypeProvider.php����c�H���Qsrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayCombineReturnTypeProvider.php_���c_kz#ؤOsrc/Psalm/Internal/Provider/ReturnTypeProvider/ArrayChunkReturnTypeProvider.php���c�t�2�9src/Psalm/Internal/Provider/PropertyExistenceProvider.php����c��
��6src/Psalm/Internal/Provider/FunctionParamsProvider.phpK���cKʐ
�3src/Psalm/Internal/Provider/FileStorageProvider.php����c���&�>src/Psalm/Internal/Provider/DynamicFunctionStorageProvider.php����c�耫�0src/Psalm/Internal/Provider/FakeFileProvider.phpt���ct��jV�9src/Psalm/Internal/Provider/FunctionExistenceProvider.phpb���cbE�,src/Psalm/Internal/Provider/FileProvider.php����c���.�=src/Psalm/Internal/Provider/ClassLikeStorageCacheProvider.php����c�}�հ�7src/Psalm/Internal/Provider/StatementsVolatileCache.php	���c	�C��8src/Psalm/Internal/Provider/MethodReturnTypeProvider.php2
���c2
 ����:src/Psalm/Internal/Provider/FileReferenceCacheProvider.phpy����cy�&C!U�8src/Psalm/Internal/Provider/MethodVisibilityProvider.phpW���cW����5src/Psalm/Internal/Provider/FileReferenceProvider.php����c�,&$�Tsrc/Psalm/Internal/Provider/PropertyTypeProvider/DomDocumentPropertyTypeProvider.php����c�Axפ3src/Psalm/Internal/Provider/ParserCacheProvider.phpx.���cx.�qKa�4src/Psalm/Internal/Provider/ProjectCacheProvider.php���c�.[��7src/Psalm/Internal/Provider/MethodExistenceProvider.phpj���cj,���0src/Psalm/Internal/Provider/NodeDataProvider.php����c��w�s�&src/Psalm/Internal/EventDispatcher.php7���c7J��v�#src/Psalm/Internal/ErrorHandler.phpA
���cA
ßNu�#src/Psalm/Internal/Cli/Refactor.php''���c'')���!src/Psalm/Internal/Cli/Plugin.php"���c"ዜ��)src/Psalm/Internal/Cli/LanguageServer.php�#���c�#d;���"src/Psalm/Internal/Cli/Psalter.php�I���c�I�X	� src/Psalm/Internal/Cli/Psalm.phpY����cY��o���$src/Psalm/Internal/Scope/IfScope.php����c�ɣ���/src/Psalm/Internal/Scope/IfConditionalScope.php]���c]��9g�&src/Psalm/Internal/Scope/CaseScope.php����c����s�(src/Psalm/Internal/Scope/SwitchScope.php����c����&src/Psalm/Internal/Scope/LoopScope.php����c�؉�+�)src/Psalm/Internal/Scope/FinallyScope.phpt���ct�,�[�src/Psalm/Internal/CliUtils.phpB?���cB?
M��@src/Psalm/Internal/FileManipulation/ClassDocblockManipulator.php�
���c�
�}2T�Csrc/Psalm/Internal/FileManipulation/FunctionDocblockManipulator.php�F���c�F�Zä>src/Psalm/Internal/FileManipulation/FileManipulationBuffer.php����c���P֤5src/Psalm/Internal/FileManipulation/CodeMigration.php���c��e��Csrc/Psalm/Internal/FileManipulation/PropertyDocblockManipulator.php����c���e^�2src/Psalm/Internal/Fork/ForkProcessDoneMessage.php����c���=� src/Psalm/Internal/Fork/Pool.phprB���crB�v�>�*src/Psalm/Internal/Fork/PsalmRestarter.php����c���]�/src/Psalm/Internal/Fork/ForkTaskDoneMessage.php����c�8�%�3src/Psalm/Internal/Fork/ForkProcessErrorMessage.phpl���clS�*�'src/Psalm/Internal/Fork/ForkMessage.phpA���cA�����>src/Psalm/Internal/ExecutionEnvironment/BuildInfoCollector.phpz)���cz)-�`+�Asrc/Psalm/Internal/ExecutionEnvironment/SystemCommandExecutor.php����c�Ƥ�ۤ<src/Psalm/Internal/ExecutionEnvironment/GitInfoCollector.php����c��f��8src/Psalm/Internal/Analyzer/Statements/UnsetAnalyzer.php����c�'�S��8src/Psalm/Internal/Analyzer/Statements/ThrowAnalyzer.php����c���*�9src/Psalm/Internal/Analyzer/Statements/StaticAnalyzer.php����c���<�9src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.phpVT���cVT!W�Ф7src/Psalm/Internal/Analyzer/Statements/EchoAnalyzer.php
���c
b��f�Csrc/Psalm/Internal/Analyzer/Statements/Expression/CloneAnalyzer.phpg���cgWz��Csrc/Psalm/Internal/Analyzer/Statements/Expression/EmptyAnalyzer.php����c��sݤBsrc/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.phpst���cstZ�K�Csrc/Psalm/Internal/Analyzer/Statements/Expression/IssetAnalyzer.php����c�h���Hsrc/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php�����c����a�Hsrc/Psalm/Internal/Analyzer/Statements/Expression/BooleanNotAnalyzer.php����c�ꕄ��Isrc/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/OrAnalyzer.phpZ1���cZ1.��L�Osrc/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/CoalesceAnalyzer.phpX���cXIY�\�Jsrc/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/AndAnalyzer.phps���csI�k_�Msrc/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.phpZ9���cZ9���Vsrc/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/NonComparisonOpAnalyzer.php[
���c[
��|��Ssrc/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php����c����Fsrc/Psalm/Internal/Analyzer/Statements/Expression/NullsafeAnalyzer.phpK���cK��8p�Esrc/Psalm/Internal/Analyzer/Statements/Expression/TernaryAnalyzer.php()���c()O��Hsrc/Psalm/Internal/Analyzer/Statements/Expression/ClassConstAnalyzer.php�u���c�u�Z���Esrc/Psalm/Internal/Analyzer/Statements/Expression/IncludeAnalyzer.php^9���c^9��û�Esrc/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php����c��%�P�Nsrc/Psalm/Internal/Analyzer/Statements/Expression/IncDecExpressionAnalyzer.php����c�����csrc/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php^����c^��;�Xsrc/Psalm/Internal/Analyzer/Statements/Expression/Assignment/ArrayAssignmentAnalyzer.php����c����Y�Qsrc/Psalm/Internal/Analyzer/Statements/Expression/Assignment/AssignedProperty.php����c����Ťasrc/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.phpe(���ce(�no��Bsrc/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php����c�V�I��Gsrc/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php~`���c~`�ê�Gsrc/Psalm/Internal/Analyzer/Statements/Expression/ArrayCreationInfo.php���cp�B�Hsrc/Psalm/Internal/Analyzer/Statements/Expression/BitwiseNotAnalyzer.php/���c/!��?�Bsrc/Psalm/Internal/Analyzer/Statements/Expression/EvalAnalyzer.php�	���c�	k��Lsrc/Psalm/Internal/Analyzer/Statements/Expression/UnaryPlusMinusAnalyzer.php����c�xئ|�Fsrc/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.phpTF���cTF�I~�Gsrc/Psalm/Internal/Analyzer/Statements/Expression/YieldFromAnalyzer.php�	���c�	���Hsrc/Psalm/Internal/Analyzer/Statements/Expression/MagicConstAnalyzer.phpo���co�E�Csrc/Psalm/Internal/Analyzer/Statements/Expression/PrintAnalyzer.php���cn>��Jsrc/Psalm/Internal/Analyzer/Statements/Expression/ExpressionIdentifier.php���c�[1�Hsrc/Psalm/Internal/Analyzer/Statements/Expression/InstanceofAnalyzer.php���c���=�Msrc/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.phpM4���cM4o��#�Ssrc/Psalm/Internal/Analyzer/Statements/Expression/Call/NamedFunctionCallHandler.phpfN���cfN�IդMsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php--���c-- m��Ksrc/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php�����c��2�P��Osrc/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.phpƑ���cƑp���Fsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.phpl���cl;���Osrc/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentMapPopulator.php{���c{[}��Ksrc/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallInfo.php����c��e�N�Vsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php%���c%��MO�_src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallProhibitionAnalyzer.php����c�T�ӤZsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodVisibilityAnalyzer.php����c�R��h�Zsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MissingMethodCallHandler.php73���c73�I���bsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.phpXP���cXP�l��Zsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallPurityAnalyzer.php���c
�ޤ`src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalysisResult.php����c�a���Ssrc/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicCallContext.php����c�R�FE�Zsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.phpi���cip��]src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.phpmH���cmHj�f�Ysrc/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php�s���c�s���Xsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php�b���c�b>H�Lsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php����c�w�0�hsrc/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.phpiN���ciN�1���`src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php�����c��,��ݤCsrc/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php%���c%�=��Csrc/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.phpIV���cIVQ����Bsrc/Psalm/Internal/Analyzer/Statements/Expression/ExitAnalyzer.php\���c\���
�Csrc/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php1���c1�F;��Psrc/Psalm/Internal/Analyzer/Statements/Expression/EncapsulatedStringAnalyzer.php����c�5E.�Wsrc/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php�����c���K�$�Qsrc/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.phph���ch��/�Ysrc/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.phpQ:���cQ:�λ'�Nsrc/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php�����c����dx�Nsrc/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.phpu&���cu&K���Wsrc/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php8���c8�6�?src/Psalm/Internal/Analyzer/Statements/Block/SwitchAnalyzer.php����c��^	y�>src/Psalm/Internal/Analyzer/Statements/Block/WhileAnalyzer.php@���c@<i�ȤFsrc/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php�-���c�-�Q��;src/Psalm/Internal/Analyzer/Statements/Block/DoAnalyzer.php
���c
���Csrc/Psalm/Internal/Analyzer/Statements/Block/SwitchCaseAnalyzer.php0X���c0Xlr���@src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php�����c�� |UR�=src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php�Y���c�Y�e��<src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php�A���c�A�7��?src/Psalm/Internal/Analyzer/Statements/Block/IfElseAnalyzer.php�3���c�3QhIݤDsrc/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseAnalyzer.php
���c
!^��Fsrc/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseIfAnalyzer.php�5���c�5k�_b�Bsrc/Psalm/Internal/Analyzer/Statements/Block/IfElse/IfAnalyzer.php�?���c�?~7Ԥ<src/Psalm/Internal/Analyzer/Statements/Block/ForAnalyzer.php����c���ȥ�Bsrc/Psalm/Internal/Analyzer/Statements/UnusedAssignmentRemover.phpz1���cz1���|�8src/Psalm/Internal/Analyzer/Statements/BreakAnalyzer.php9���c9?�ri�=src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php�F���c�F�mq�;src/Psalm/Internal/Analyzer/Statements/ContinueAnalyzer.php���c���Ϥ9src/Psalm/Internal/Analyzer/Statements/GlobalAnalyzer.php�
���c�
�8��0src/Psalm/Internal/Analyzer/FunctionAnalyzer.php����c�M�@�0src/Psalm/Internal/Analyzer/MethodComparator.php@����c@����.�1src/Psalm/Internal/Analyzer/NamespaceAnalyzer.php�"���c�"�Uٸ�4src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php����c�
D�*�1src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php�\���c�\���/�/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php#����c#���{�)src/Psalm/Internal/Analyzer/IssueData.php�
���c�
���(src/Psalm/Internal/Analyzer/CanAlias.php����c�‰��.src/Psalm/Internal/Analyzer/MethodAnalyzer.php�#���c�#ؗ��-src/Psalm/Internal/Analyzer/TraitAnalyzer.php@���c@��h�1src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php����c��um��-src/Psalm/Internal/Analyzer/ScopeAnalyzer.phpt6���ct6�IuϤ.src/Psalm/Internal/Analyzer/SourceAnalyzer.php|���c|�ĉ\�-src/Psalm/Internal/Analyzer/ClassAnalyzer.php�$���c�$*,l�,src/Psalm/Internal/Analyzer/FileAnalyzer.phpKQ���cKQù�e�2src/Psalm/Internal/Analyzer/AttributesAnalyzer.phpe0���ce0[|�c�4src/Psalm/Internal/Analyzer/ClassLikeNameOptions.php����c�zh��0src/Psalm/Internal/Analyzer/DataFlowNodeData.phpO���cOW�ܤ2src/Psalm/Internal/Analyzer/StatementsAnalyzer.php����c���-��/src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php����c�H�|�@src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeCollector.phpw!���cw!��6x�?src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php�{���c�{T,�/src/Psalm/Internal/Analyzer/ClosureAnalyzer.php�+���c�+�zJC�/src/Psalm/Internal/Analyzer/CommentAnalyzer.phpz.���cz.N�ᄂ,src/Psalm/Internal/Analyzer/TypeAnalyzer.php����c���5�src/Psalm/Internal/Composer.phpj���cj��p��;src/Psalm/Internal/PluginManager/Command/DisableCommand.php	
���c	
v1˚�:src/Psalm/Internal/PluginManager/Command/EnableCommand.php
���c
B��q�8src/Psalm/Internal/PluginManager/Command/ShowCommand.php�	���c�	���6src/Psalm/Internal/PluginManager/PluginListFactory.php
���c
����1src/Psalm/Internal/PluginManager/ComposerLock.php ���c r����/src/Psalm/Internal/PluginManager/ConfigFile.phpr���cr�B��/src/Psalm/Internal/PluginManager/PluginList.php����c����I�/src/Psalm/Internal/Algebra/FormulaGenerator.phps0���cs0�qnT�-src/Psalm/Internal/Scanner/DocblockParser.php&���c&[����-src/Psalm/Internal/Scanner/ParsedDocblock.php�	���c�	~26��6src/Psalm/Internal/Scanner/FunctionDocblockComment.php����c����Q�:src/Psalm/Internal/Scanner/UnresolvedConstantComponent.php����c���C��1src/Psalm/Internal/Scanner/VarDocblockComment.php=���c=�i��>src/Psalm/Internal/Scanner/UnresolvedConstant/KeyValuePair.php����c��&0�Fsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseAnd.php����c��B��Csrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedTernary.php����c��5�Fsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedAdditionOp.php����c���܃�Bsrc/Psalm/Internal/Scanner/UnresolvedConstant/ArrayOffsetFetch.php����c��_��=src/Psalm/Internal/Scanner/UnresolvedConstant/ScalarValue.php����c�\=�Isrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedSubtractionOp.php ���c ��p?�Dsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBinaryOp.phpF���cF�ՖäEsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseOr.php����c��U츤Dsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedConcatOp.php���c����?src/Psalm/Internal/Scanner/UnresolvedConstant/ClassConstant.php����c��nja�Fsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseXor.php����c�ra2�Lsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedMultiplicationOp.php#���c#����:src/Psalm/Internal/Scanner/UnresolvedConstant/Constant.php����c�qM�
�=src/Psalm/Internal/Scanner/UnresolvedConstant/ArraySpread.phpv���cv��Y��<src/Psalm/Internal/Scanner/UnresolvedConstant/ArrayValue.php����c��i���Fsrc/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedDivisionOp.php���cRB"�2src/Psalm/Internal/Scanner/PhpStormMetaScanner.php�2���c�28�H@�7src/Psalm/Internal/Scanner/ClassLikeDocblockComment.php����c�ʩ�v�*src/Psalm/Internal/Scanner/FileScanner.php�
���c�
�D��4src/Psalm/Internal/LanguageServer/ProtocolReader.php<���c<o1�f�4src/Psalm/Internal/LanguageServer/ProtocolWriter.php���cA��Ť:src/Psalm/Internal/LanguageServer/ProtocolStreamReader.php���c�K�פ6src/Psalm/Internal/LanguageServer/EmitterInterface.php����c��x0�9src/Psalm/Internal/LanguageServer/Server/TextDocument.php�<���c�<�y8�6src/Psalm/Internal/LanguageServer/Server/Workspace.php����c�4�l��1src/Psalm/Internal/LanguageServer/IdGenerator.phpO���cO�5�F�9src/Psalm/Internal/LanguageServer/Client/TextDocument.php����c��E�1�4src/Psalm/Internal/LanguageServer/LanguageServer.phppK���cpK�	꟤4src/Psalm/Internal/LanguageServer/LanguageClient.php����c��nߙ�3src/Psalm/Internal/LanguageServer/ClientHandler.php����c�ޘ�ɤ:src/Psalm/Internal/LanguageServer/ProtocolStreamWriter.php����c��FФ-src/Psalm/Internal/LanguageServer/Message.php2���c2۽�ݤ2src/Psalm/Internal/LanguageServer/EmitterTrait.php���c��m�'src/Psalm/Internal/IncludeCollector.php���c���+src/Psalm/Internal/Type/TypeCombination.php�
���c�
�N$2�5src/Psalm/Internal/Type/SimpleAssertionReconciler.phpM���cM�97�6src/Psalm/Internal/Type/NegatedAssertionReconciler.php=���c=�s~#�<src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.phpO����cO��H;ʤ/src/Psalm/Internal/Type/AssertionReconciler.php����c��r=�7src/Psalm/Internal/Type/TemplateStandinTypeReplacer.php�����c��z�
�&src/Psalm/Internal/Type/TypeParser.php����c��p?��;src/Psalm/Internal/Type/Comparator/TypeComparisonResult.phpV���cV�7R1�=src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php����c����;src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php6F���c6Fx��:src/Psalm/Internal/Type/Comparator/UnionTypeComparator.php�C���c�C�-��:src/Psalm/Internal/Type/Comparator/ArrayTypeComparator.php����c�0��=src/Psalm/Internal/Type/Comparator/CallableTypeComparator.php|A���c|AS��;src/Psalm/Internal/Type/Comparator/KeyedArrayComparator.php����c�����7src/Psalm/Internal/Type/Comparator/ObjectComparator.php�1���c�12K��@src/Psalm/Internal/Type/Comparator/ClassLikeStringComparator.php�	���c�	*�<src/Psalm/Internal/Type/Comparator/GenericTypeComparator.phpe���ce����;src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php{`���c{`���8src/Psalm/Internal/Type/TemplateInferredTypeReplacer.php�A���c�AM3���)src/Psalm/Internal/Type/TypeTokenizer.php�5���c�5���(src/Psalm/Internal/Type/TypeCombiner.php:����c:�9�K��%src/Psalm/Internal/Type/ArrayType.php����c��F�N�0src/Psalm/Internal/Type/ParseTree/MethodTree.php@���c@(0��4src/Psalm/Internal/Type/ParseTree/TemplateIsTree.phpX���cX�D�+src/Psalm/Internal/Type/ParseTree/Value.phpU���cU��r�/src/Psalm/Internal/Type/ParseTree/UnionTree.php����c���Z�5src/Psalm/Internal/Type/ParseTree/ConditionalTree.php����c�'am.�7src/Psalm/Internal/Type/ParseTree/EncapsulationTree.php����c�/�B�7src/Psalm/Internal/Type/ParseTree/CallableParamTree.php����c��[�<�6src/Psalm/Internal/Type/ParseTree/IntersectionTree.php����c��J�J�3src/Psalm/Internal/Type/ParseTree/FieldEllipsis.php����c��s�)�*src/Psalm/Internal/Type/ParseTree/Root.php����c����1src/Psalm/Internal/Type/ParseTree/GenericTree.phpg���cgS�8�4src/Psalm/Internal/Type/ParseTree/KeyedArrayTree.phpj���cj�u��@src/Psalm/Internal/Type/ParseTree/CallableWithReturnTypeTree.php����c�Γ��2src/Psalm/Internal/Type/ParseTree/NullableTree.php����c�l�v�>src/Psalm/Internal/Type/ParseTree/MethodWithReturnTypeTree.php����c��2�ˤ5src/Psalm/Internal/Type/ParseTree/MethodParamTree.php����c�Hv�o�4src/Psalm/Internal/Type/ParseTree/TemplateAsTree.php����c��_�A�<src/Psalm/Internal/Type/ParseTree/KeyedArrayPropertyTree.phpL���cL ��ޤ2src/Psalm/Internal/Type/ParseTree/CallableTree.phph���ch����7src/Psalm/Internal/Type/ParseTree/IndexedAccessTree.phpG���cG=q
S�4src/Psalm/Internal/Type/TypeAlias/ClassTypeAlias.php����c�3��r�5src/Psalm/Internal/Type/TypeAlias/InlineTypeAlias.phpH���cHd�~?�7src/Psalm/Internal/Type/TypeAlias/LinkableTypeAlias.php6���c6��
��*src/Psalm/Internal/Type/TemplateResult.php����c������%src/Psalm/Internal/Type/ParseTree.php~���c~U-n��%src/Psalm/Internal/Type/TypeAlias.php?���c?�4���,src/Psalm/Internal/Type/ParseTreeCreator.php�g���c�gb���)src/Psalm/Internal/Type/TemplateBound.php{���c{��i�(src/Psalm/Internal/Type/TypeExpander.php2����c2�d�X� src/Psalm/Internal/Json/Json.php����c�x�=�src/Psalm/Internal/Algebra.php�W���c�Wg6�e�'src/Psalm/Internal/MethodIdentifier.phpH���cH�q�H�$src/Psalm/Internal/RuntimeCaches.php����c�v���*src/Psalm/Internal/ReferenceConstraint.php����c�z6�ɤGsrc/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php�����c��x�O�=src/Psalm/Internal/PhpVisitor/Reflector/AttributeResolver.php����c�C�
�<src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.phpc���cc�LԤ@src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.phpv����cv��I�Csrc/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php�O���c�O�TL��>src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.phpr<���cr<\⧤Csrc/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php[����c[�Y�6֤Fsrc/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php�a���c�a4�_�=src/Psalm/Internal/PhpVisitor/Reflector/ExpressionScanner.php,���c,v�H��0src/Psalm/Internal/PhpVisitor/CloningVisitor.php���c����6src/Psalm/Internal/PhpVisitor/PartialParserVisitor.phpX3���cX3��l�4src/Psalm/Internal/PhpVisitor/TypeMappingVisitor.php`���c``c�9src/Psalm/Internal/PhpVisitor/ConditionCloningVisitor.php����c�l_�9src/Psalm/Internal/PhpVisitor/CheckTrivialExprVisitor.php�	���c�	�ö�4src/Psalm/Internal/PhpVisitor/SimpleNameResolver.phpY���cY!���4src/Psalm/Internal/PhpVisitor/NodeCleanerVisitor.phpc���cc�
��2src/Psalm/Internal/PhpVisitor/ReflectorVisitor.phpU���cUX�ᐤ6src/Psalm/Internal/PhpVisitor/AssignmentMapVisitor.php����c�$i�M�4src/Psalm/Internal/PhpVisitor/NodeCounterVisitor.php:���c:Z��O�4src/Psalm/Internal/PhpVisitor/YieldTypeCollector.php����c��	Oɤ9src/Psalm/Internal/PhpVisitor/ParamReplacementVisitor.php����c��(�|�-src/Psalm/Internal/PhpVisitor/TraitFinder.phph	���ch	���|�6src/Psalm/Internal/PhpVisitor/OffsetShifterVisitor.php����c�����5src/Psalm/Internal/PhpVisitor/ShortClosureVisitor.php����c���h�?src/Psalm/Internal/Codebase/ClassConstantByWildcardResolver.php����c�H
M��0src/Psalm/Internal/Codebase/VariableUseGraph.php����c���& �*src/Psalm/Internal/Codebase/Reflection.php�G���c�G_&�֤+src/Psalm/Internal/Codebase/PropertyMap.php����c�.��-src/Psalm/Internal/Codebase/DataFlowGraph.phpR���cR���5src/Psalm/Internal/Codebase/ReferenceMapGenerator.php����c� >�*src/Psalm/Internal/Codebase/ClassLikes.php<5���c<5hV|�'src/Psalm/Internal/Codebase/Methods.phpr����cr��x)�(src/Psalm/Internal/Codebase/Analyzer.php����c�-����)src/Psalm/Internal/Codebase/Populator.php����c�و��.src/Psalm/Internal/Codebase/TaintFlowGraph.php�<���c�<
���)src/Psalm/Internal/Codebase/Functions.phpA[���cA[�X���'src/Psalm/Internal/Codebase/Scanner.php2f���c2f�e2�*src/Psalm/Internal/Codebase/Properties.php0)���c0)�̤6src/Psalm/Internal/Codebase/InternalCallMapHandler.php�2���c�2�Oiä4src/Psalm/Internal/Codebase/ConstantTypeResolver.php�,���c�,�cB�.src/Psalm/Internal/TypeVisitor/TypeScanner.php
	���c
	j	�X�.src/Psalm/Internal/TypeVisitor/TypeChecker.php+���c+��j�;src/Psalm/Internal/TypeVisitor/ContainsClassLikeVisitor.php����c�A�W�9src/Psalm/Internal/TypeVisitor/ContainsLiteralVisitor.php����c�_���8src/Psalm/Internal/TypeVisitor/TemplateTypeCollector.php����c��x,�>src/Psalm/Internal/TypeVisitor/CanContainObjectTypeVisitor.php����c�i,���8src/Psalm/Internal/TypeVisitor/ContainsStaticVisitor.phpl���clj\(�4src/Psalm/Internal/TypeVisitor/ClasslikeReplacer.phpj���cj��m�5src/Psalm/Internal/TypeVisitor/FromDocblockSetter.php���c�貀�0src/Psalm/Internal/TypeVisitor/TypeLocalizer.php#
���c#
�ݐ�$src/Psalm/Internal/DataFlow/Path.php���c��Ȥ,src/Psalm/Internal/DataFlow/DataFlowNode.phpX���cX]��H�+src/Psalm/Internal/DataFlow/TaintSource.php����c�Wǽ�)src/Psalm/Internal/DataFlow/TaintSink.php����c�˜��src/Psalm/Internal/Clause.php����c��A��&src/Psalm/Internal/Diff/FileDiffer.php�!���c�!H��$src/Psalm/Internal/Diff/DiffElem.php$���c$�
[;�0src/Psalm/Internal/Diff/FileStatementsDiffer.php����c��ی�5src/Psalm/Internal/Diff/NamespaceStatementsDiffer.php����c��5I�1src/Psalm/Internal/Diff/ClassStatementsDiffer.phpk%���ck%��.�%src/Psalm/Internal/Diff/AstDiffer.php]
���c]
�UVͤ#src/Psalm/Internal/VersionUtils.php'
���c'
�D+i�3src/Psalm/Internal/PhpTraverser/CustomTraverser.php���cUQ@��src/Psalm/NodeTypeProvider.php����c�K �0src/Psalm/Storage/ImmutableNonCloneableTrait.php����c�خ��src/Psalm/Storage/Assertion.php����c��U�G�*src/Psalm/Storage/Assertion/IsNotIsset.php/���c/#F�+src/Psalm/Storage/Assertion/IsIdentical.php���c�DȚ�-src/Psalm/Storage/Assertion/HasExactCount.phpE���cE2��3src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.phpB���cBO����1src/Psalm/Storage/Assertion/DoesNotHaveMethod.php����c���e�9src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php���cZE\��#src/Psalm/Storage/Assertion/Any.php����c���q��'src/Psalm/Storage/Assertion/IsIsset.php����c�M�w�+src/Psalm/Storage/Assertion/IsNotAClass.php����c����)src/Psalm/Storage/Assertion/IsNotType.php����c�Fb�&src/Psalm/Storage/Assertion/Truthy.php����c�ev�3�&src/Psalm/Storage/Assertion/IsType.php����c�0�-^�,src/Psalm/Storage/Assertion/IsClassEqual.php����c��F!�4src/Psalm/Storage/Assertion/NotNonEmptyCountable.phpy���cy�E��.src/Psalm/Storage/Assertion/IsLooselyEqual.php
���c
MGw�.src/Psalm/Storage/Assertion/IsNotCountable.php����c�S�Rl�*src/Psalm/Storage/Assertion/IsLessThan.php���chs��(src/Psalm/Storage/Assertion/NonEmpty.php����c�:Efx�*src/Psalm/Storage/Assertion/NotInArray.php$���c$�R/��/src/Psalm/Storage/Assertion/IsClassNotEqual.php����c�O=p/�&src/Psalm/Storage/Assertion/Empty_.php.���c.u��ؤ.src/Psalm/Storage/Assertion/ArrayKeyExists.php
���c
n���7src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php?���c?��)src/Psalm/Storage/Assertion/HasMethod.php����c�F�/7�+src/Psalm/Storage/Assertion/HasArrayKey.php_���c_"fg�-src/Psalm/Storage/Assertion/IsGreaterThan.php����c��@Ŏ�1src/Psalm/Storage/Assertion/IsNotLooselyEqual.phpU���cU�l_�1src/Psalm/Storage/Assertion/NonEmptyCountable.phpf���cf6$?�.src/Psalm/Storage/Assertion/IsNotIdentical.phpL���cLi�c�4src/Psalm/Storage/Assertion/HasStringArrayAccess.php����c��!�0�0src/Psalm/Storage/Assertion/NestedAssertions.php=���c=�@��,src/Psalm/Storage/Assertion/IsEqualIsset.php����c�=m&�6src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.phpK���cK�r�'src/Psalm/Storage/Assertion/InArray.php����c���#�3src/Psalm/Storage/Assertion/NotNestedAssertions.php����c�J7h�4src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.phpO���cOaD�W�%src/Psalm/Storage/Assertion/Falsy.php$���c$Ã�Q�/src/Psalm/Storage/Assertion/HasAtLeastCount.php����c���쎤5src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php<���c<�Z�Ϥ+src/Psalm/Storage/Assertion/IsCountable.php���cPV�)�(src/Psalm/Storage/Assertion/IsAClass.phpW���cWnar�+src/Psalm/Storage/FunctionLikeParameter.php����c���e¤)src/Psalm/Storage/CustomMetadataTrait.php����c�}ѕ��!src/Psalm/Storage/FileStorage.phpj���cjޫ<D�%src/Psalm/Storage/PropertyStorage.php.	���c.	�_�Ҥ)src/Psalm/Storage/FunctionLikeStorage.php����c��
7�&src/Psalm/Storage/AttributeStorage.php����c�J��&src/Psalm/Storage/ClassLikeStorage.php'���c'TT �%src/Psalm/Storage/FunctionStorage.php0���c0|�#Ĥ,src/Psalm/Storage/HasAttributesInterface.php����c�� ��#src/Psalm/Storage/MethodStorage.php���c�a1�%src/Psalm/Storage/EnumCaseStorage.php����c��1�B�#src/Psalm/Storage/Possibilities.phpo���cos����*src/Psalm/Storage/ClassConstantStorage.php	���c	;��"src/Psalm/Storage/AttributeArg.php[���c[3h��(src/Psalm/PluginFileExtensionsSocket.php�
���c�
_�src/Psalm/Codebase.phpw����cw�7oy��.src/Psalm/Exception/TypeParseTreeException.phpk���ck��Ȥ6src/Psalm/Exception/UnsupportedIssueToFixException.phps���cs��<��3src/Psalm/Exception/UnpreparedAnalysisException.phpp���cp�2*\�'src/Psalm/Exception/ConfigException.php^���c^���G�/src/Psalm/Exception/UnanalyzedFileException.phpl���cl�P�>�,src/Psalm/Exception/FileIncludeException.phpi���ciJ��ݤ2src/Psalm/Exception/CircularReferenceException.phpo���co9ػ�9src/Psalm/Exception/InvalidClasslikeOverrideException.phpv���cv�d�>�5src/Psalm/Exception/UnpopulatedClasslikeException.phpq���cq�����%src/Psalm/Exception/CodeException.phpb���cb��'$�5src/Psalm/Exception/UnresolvableConstantException.php����c�%�Ф/src/Psalm/Exception/ConfigCreationException.phpl���cl�2#��)src/Psalm/Exception/RefactorException.phpf���cf�>Rh�.src/Psalm/Exception/DocblockParseException.phpe���ce�^٤6src/Psalm/Exception/ComplicatedExpressionException.phps���cs�{?u�/src/Psalm/Exception/ConfigNotFoundException.phpt���ct�=g��2src/Psalm/Exception/IncorrectDocblockException.php~���c~�ޤ6src/Psalm/Exception/InvalidMethodOverrideException.phps���cs���.src/Psalm/Exception/ScopeAnalysisException.phpk���ck��Ug�&src/Psalm/PluginRegistrationSocket.php���c`��N�src/Psalm/Report.php~
���c~
�_G��src/Psalm/IssueBuffer.php~���c~�~�*src/Psalm/SourceControl/Git/RemoteInfo.php����c��[EФ*src/Psalm/SourceControl/Git/CommitInfo.php����c��`�/�'src/Psalm/SourceControl/Git/GitInfo.php���c�uYl�-src/Psalm/SourceControl/SourceControlInfo.php|���c|��T�.src/Psalm/Plugin/PluginEntryPointInterface.php����c�����,src/Psalm/Plugin/DynamicTemplateProvider.php����c�J���2src/Psalm/Plugin/PluginFileExtensionsInterface.php���c���+src/Psalm/Plugin/DynamicFunctionStorage.php����c��2��,src/Psalm/Plugin/FileExtensionsInterface.php6���c6��j�>src/Psalm/Plugin/EventHandler/AfterClassLikeVisitInterface.phpQ���cQݷ��<src/Psalm/Plugin/EventHandler/AfterFileAnalysisInterface.php!���c!���o�9src/Psalm/Plugin/EventHandler/BeforeAddIssueInterface.php����c��١E�?src/Psalm/Plugin/EventHandler/PropertyTypeProviderInterface.phpj���cjYި��Asrc/Psalm/Plugin/EventHandler/AfterClassLikeAnalysisInterface.php����c���M7�8src/Psalm/Plugin/EventHandler/AfterAnalysisInterface.php���cA�X��:src/Psalm/Plugin/EventHandler/Event/AfterAnalysisEvent.php����c����Dsrc/Psalm/Plugin/EventHandler/Event/MethodExistenceProviderEvent.php����c�&���Csrc/Psalm/Plugin/EventHandler/Event/AfterClassLikeAnalysisEvent.php5���c5H���Fsrc/Psalm/Plugin/EventHandler/Event/FunctionExistenceProviderEvent.php����c�C��Ksrc/Psalm/Plugin/EventHandler/Event/DynamicFunctionStorageProviderEvent.phpg���cg,e���>src/Psalm/Plugin/EventHandler/Event/AfterFileAnalysisEvent.php����c��og٤Isrc/Psalm/Plugin/EventHandler/Event/AfterClassLikeExistenceCheckEvent.php����c�>�ۤKsrc/Psalm/Plugin/EventHandler/Event/AfterEveryFunctionCallAnalysisEvent.php����c���v�Dsrc/Psalm/Plugin/EventHandler/Event/AfterExpressionAnalysisEvent.php����c��䑤Gsrc/Psalm/Plugin/EventHandler/Event/FunctionReturnTypeProviderEvent.php���cֳ�P�Csrc/Psalm/Plugin/EventHandler/Event/FunctionParamsProviderEvent.php����c�8�Sl�Csrc/Psalm/Plugin/EventHandler/Event/AfterCodebasePopulatedEvent.php����c��@�$�;src/Psalm/Plugin/EventHandler/Event/BeforeAddIssueEvent.php����c��
A��Asrc/Psalm/Plugin/EventHandler/Event/PropertyTypeProviderEvent.php����c��Kb�@src/Psalm/Plugin/EventHandler/Event/AfterClassLikeVisitEvent.php����c�;
�W�Dsrc/Psalm/Plugin/EventHandler/Event/BeforeStatementAnalysisEvent.php&���c&3��>src/Psalm/Plugin/EventHandler/Event/StringInterpreterEvent.phpd���cd�la�Gsrc/Psalm/Plugin/EventHandler/Event/PropertyVisibilityProviderEvent.php����c�3��Fsrc/Psalm/Plugin/EventHandler/Event/AfterFunctionLikeAnalysisEvent.php'	���c'	���W�Esrc/Psalm/Plugin/EventHandler/Event/MethodVisibilityProviderEvent.php
���c
��֓�Csrc/Psalm/Plugin/EventHandler/Event/AfterStatementAnalysisEvent.php����c��'�-�Fsrc/Psalm/Plugin/EventHandler/Event/PropertyExistenceProviderEvent.php����c�bA�]�Fsrc/Psalm/Plugin/EventHandler/Event/AfterFunctionCallAnalysisEvent.php����c�fD�¤Asrc/Psalm/Plugin/EventHandler/Event/MethodParamsProviderEvent.php����c�bq�Dsrc/Psalm/Plugin/EventHandler/Event/AfterMethodCallAnalysisEvent.php����c�1�%�?src/Psalm/Plugin/EventHandler/Event/BeforeFileAnalysisEvent.php����c��焤Esrc/Psalm/Plugin/EventHandler/Event/MethodReturnTypeProviderEvent.php�
���c�
�!��<src/Psalm/Plugin/EventHandler/Event/AddRemoveTaintsEvent.php:���c:�C�Isrc/Psalm/Plugin/EventHandler/DynamicFunctionStorageProviderInterface.php����c�7�ߍ�Bsrc/Psalm/Plugin/EventHandler/AfterExpressionAnalysisInterface.phpc���cc�(�u�Bsrc/Psalm/Plugin/EventHandler/MethodExistenceProviderInterface.php����c���'��Dsrc/Psalm/Plugin/EventHandler/AfterFunctionLikeAnalysisInterface.phpf���cf�4`��Gsrc/Psalm/Plugin/EventHandler/AfterClassLikeExistenceCheckInterface.php���c<�=��Bsrc/Psalm/Plugin/EventHandler/AfterMethodCallAnalysisInterface.php����c����<�=src/Psalm/Plugin/EventHandler/BeforeFileAnalysisInterface.php&���c&��5�4src/Psalm/Plugin/EventHandler/AddTaintsInterface.php7���c7���h�Esrc/Psalm/Plugin/EventHandler/FunctionReturnTypeProviderInterface.php����c��s�?src/Psalm/Plugin/EventHandler/MethodParamsProviderInterface.php����c���ʫ�Isrc/Psalm/Plugin/EventHandler/AfterEveryFunctionCallAnalysisInterface.php���c7�t�Csrc/Psalm/Plugin/EventHandler/MethodVisibilityProviderInterface.php_���c_����Esrc/Psalm/Plugin/EventHandler/PropertyVisibilityProviderInterface.phpg���cg�/�Dsrc/Psalm/Plugin/EventHandler/PropertyExistenceProviderInterface.php����c���+Ǥ<src/Psalm/Plugin/EventHandler/StringInterpreterInterface.phpW���cWn2���Dsrc/Psalm/Plugin/EventHandler/FunctionExistenceProviderInterface.php����c�^I�*�Csrc/Psalm/Plugin/EventHandler/MethodReturnTypeProviderInterface.php����c�ف�
�Asrc/Psalm/Plugin/EventHandler/FunctionParamsProviderInterface.php����c���U��Dsrc/Psalm/Plugin/EventHandler/AfterFunctionCallAnalysisInterface.php���c,���7src/Psalm/Plugin/EventHandler/RemoveTaintsInterface.php?���c?�暤Asrc/Psalm/Plugin/EventHandler/AfterCodebasePopulatedInterface.php����c�+m7��Bsrc/Psalm/Plugin/EventHandler/BeforeStatementAnalysisInterface.php
���c
V��&�Asrc/Psalm/Plugin/EventHandler/AfterStatementAnalysisInterface.php]���c]��&��#src/Psalm/Plugin/ArgTypeInferer.phps���csn�u�$src/Psalm/Plugin/PluginInterface.php>���c>Ѓ��*src/Psalm/Plugin/RegistrationInterface.php����c���%դsrc/Psalm/Plugin/Shepherd.php����c��{_��src/Psalm/ErrorBaseline.phpe#���ce#�Q��src/Psalm/CodeLocation/Raw.php����c�4u�/src/Psalm/CodeLocation/DocblockTypeLocation.php���c���K�-src/Psalm/CodeLocation/ParseErrorLocation.php���c��V��src/Psalm/FileSource.php����c��=;�src/Psalm/Context.php�f���c�f�r}7�src/Psalm/CodeLocation.php�-���c�-�#;��src/Psalm/Aliases.php����c����src/Psalm/Type/TypeVisitor.php����c��ʡb�src/Psalm/Type/TypeNode.php����c��YR�src/Psalm/Type/Reconciler.php����c�a�#��)src/Psalm/Type/Atomic/TNonEmptyString.php����c���6�� src/Psalm/Type/Atomic/TFalse.php����c�m
� src/Psalm/Type/Atomic/Scalar.php����c��Jч�,src/Psalm/Type/Atomic/TDependentGetClass.php����c��x�]�*src/Psalm/Type/Atomic/TLowercaseString.phpx���cx��٤'src/Psalm/Type/Atomic/TLiteralFloat.php����c�\~<�&src/Psalm/Type/Atomic/TTraitString.php����c�T��"src/Psalm/Type/Atomic/TClosure.php����c�����'src/Psalm/Type/Atomic/TSingleLetter.php����c�k�,�'src/Psalm/Type/Atomic/DependentType.php.���c.�RI�%src/Psalm/Type/Atomic/TEmptyMixed.php����c�F��v�'src/Psalm/Type/Atomic/TEmptyNumeric.phpq���cqO̙6�&src/Psalm/Type/Atomic/TEmptyScalar.php-���c-a�-̤-src/Psalm/Type/Atomic/TTemplateParamClass.php����c�h���(src/Psalm/Type/Atomic/TTemplateParam.php����c��a�>� src/Psalm/Type/Atomic/TFloat.phpC���cC�j6�&src/Psalm/Type/Atomic/TClassString.php����c��T�/src/Psalm/Type/Atomic/TObjectWithProperties.php����c���*�'src/Psalm/Type/Atomic/TPropertiesOf.php���c�v2�/src/Psalm/Type/Atomic/TTemplatePropertiesOf.php�	���c�	
��F�#src/Psalm/Type/Atomic/TIterable.php����c� �Q��"src/Psalm/Type/Atomic/TNumeric.php����c�����-src/Psalm/Type/Atomic/TLiteralClassString.php�	���c�	�:���*src/Psalm/Type/Atomic/TTemplateValueOf.php����c��4!�+src/Psalm/Type/Atomic/TDependentListKey.php}���c}�@+N� src/Psalm/Type/Atomic/TArray.php@���c@-Bb�&src/Psalm/Type/Atomic/TNamedObject.php����c�e|�;�#src/Psalm/Type/Atomic/TIntRange.php����c�����0src/Psalm/Type/Atomic/TTemplateIndexedAccess.php����c����)src/Psalm/Type/Atomic/TCallableObject.php:���c:P�c��1src/Psalm/Type/Atomic/TAnonymousClassInstance.php����c�1��Z�%src/Psalm/Type/Atomic/TLiteralInt.phpW���cW<��Ӥ'src/Psalm/Type/Atomic/TCallableList.php���c���)src/Psalm/Type/Atomic/TCallableString.php����c�����&src/Psalm/Type/Atomic/TConditional.php����c��,?$�)src/Psalm/Type/Atomic/TNonEmptyScalar.php8���c8ge��$src/Psalm/Type/Atomic/TTypeAlias.php����c���>�'src/Psalm/Type/Atomic/CallableTrait.php7#���c7#�?���"src/Psalm/Type/Atomic/TValueOf.phpP���cP�'ݤ;src/Psalm/Type/Atomic/TNonEmptyNonspecificLiteralString.php����c�78�� src/Psalm/Type/Atomic/TMixed.phpH���cH�TQ�src/Psalm/Type/Atomic/TBool.php>���c>�$��src/Psalm/Type/Atomic/TInt.php;���c;[[%�!src/Psalm/Type/Atomic/TString.phpG���cG-�7�src/Psalm/Type/Atomic/TVoid.php����c�Xx��� src/Psalm/Type/Atomic/TKeyOf.php;���c;�����src/Psalm/Type/Atomic/TNull.phpn���cn\!|�0src/Psalm/Type/Atomic/TDependentGetDebugType.php����c���Q�)src/Psalm/Type/Atomic/TNonFalsyString.php����c����;�-src/Psalm/Type/Atomic/TCallableKeyedArray.php.���c.rQ�B�)src/Psalm/Type/Atomic/TClassStringMap.php���c��(src/Psalm/Type/Atomic/TClassConstant.php{���c{�y]m�(src/Psalm/Type/Atomic/TLiteralString.php����c�ENż�%src/Psalm/Type/Atomic/TKeyedArray.php�J���c�JTCڤ#src/Psalm/Type/Atomic/TEnumCase.php���cm,���(src/Psalm/Type/Atomic/TCallableArray.php���c�cmפ(src/Psalm/Type/Atomic/TNonEmptyMixed.php����c����� src/Psalm/Type/Atomic/TNever.php����c���Ĥ&src/Psalm/Type/Atomic/GenericTrait.php���c��V��2src/Psalm/Type/Atomic/TNonEmptyLowercaseString.phpm���cm(VMa�#src/Psalm/Type/Atomic/TResource.php����c�a�f�!src/Psalm/Type/Atomic/TScalar.php8���c8�MԤ'src/Psalm/Type/Atomic/TNonEmptyList.php\���c\�l��src/Psalm/Type/Atomic/TList.php4���c4���ɤ(src/Psalm/Type/Atomic/TGenericObject.php����c�U�a�+src/Psalm/Type/Atomic/TDependentGetType.php\���c\ �w�$src/Psalm/Type/Atomic/TIntMaskOf.php����c����0src/Psalm/Type/Atomic/TNonspecificLiteralInt.phpC���cCi�l�(src/Psalm/Type/Atomic/TNumericString.php����c�;m�(src/Psalm/Type/Atomic/TNonEmptyArray.php���c��g�)src/Psalm/Type/Atomic/TClosedResource.php����c�yo�J�#src/Psalm/Type/Atomic/TCallable.phpM���cM����3src/Psalm/Type/Atomic/TNonspecificLiteralString.php����c�e�s,�!src/Psalm/Type/Atomic/TObject.php����c�i�Y̤#src/Psalm/Type/Atomic/TArrayKey.php����c�"��.src/Psalm/Type/Atomic/HasIntersectionTrait.php����c��}9��(src/Psalm/Type/Atomic/TTemplateKeyOf.php����c��&ɤsrc/Psalm/Type/Atomic/TTrue.php����c�݆�"src/Psalm/Type/Atomic/TIntMask.php����c��̫n�src/Psalm/Type/MutableUnion.php�8���c�8�4��!src/Psalm/Type/TaintKindGroup.php����c����src/Psalm/Type/UnionTrait.phpב���cבB���src/Psalm/Type/TaintKind.php���c\�wk�src/Psalm/Type/Atomic.php�d���c�dJ/5G�%src/Psalm/Type/MutableTypeVisitor.php����c���O�src/Psalm/Type/Union.phpj$���cj$p�J�src/Psalm/Config.phpf@���cf@�s�g�src/Psalm/FileManipulation.php����c�uN|�&src/Psalm/Node/VirtualNullableType.php����c��#.B�src/Psalm/Node/VirtualName.php����c��i
ʤ"src/Psalm/Node/VirtualMatchArm.php����c�?<�h�(src/Psalm/Node/Scalar/VirtualLNumber.php����c��y_ߤ)src/Psalm/Node/Scalar/VirtualEncapsed.php����c�֠�f�3src/Psalm/Node/Scalar/VirtualEncapsedStringPart.php����c�ൈ��'src/Psalm/Node/Scalar/VirtualString.php����c��s�n�(src/Psalm/Node/Scalar/VirtualDNumber.php����c�D��0src/Psalm/Node/Scalar/MagicConst/VirtualFile.php����c�\+M��1src/Psalm/Node/Scalar/MagicConst/VirtualClass.php����c���`�0src/Psalm/Node/Scalar/MagicConst/VirtualLine.php����c�ԯ�r�2src/Psalm/Node/Scalar/MagicConst/VirtualMethod.php����c�m �Ǥ5src/Psalm/Node/Scalar/MagicConst/VirtualNamespace.php����c�%�u��4src/Psalm/Node/Scalar/MagicConst/VirtualFunction.php����c��b�n�/src/Psalm/Node/Scalar/MagicConst/VirtualDir.php����c�R!Τ1src/Psalm/Node/Scalar/MagicConst/VirtualTrait.php����c�����src/Psalm/Node/VirtualArg.php����c�iH�N�src/Psalm/Node/VirtualNode.php����c�dښD�+src/Psalm/Node/VirtualVarLikeIdentifier.php���c�y�(src/Psalm/Node/VirtualAttributeGroup.php����c�"!0�'src/Psalm/Node/Expr/VirtualFuncCall.php����c���D�2src/Psalm/Node/Expr/VirtualStaticPropertyFetch.php����c�����$src/Psalm/Node/Expr/VirtualArray.php����c��wS�)src/Psalm/Node/Expr/VirtualUnaryMinus.php����c�d�c�&src/Psalm/Node/Expr/VirtualPostDec.php����c�*��#src/Psalm/Node/Expr/VirtualEval.php����c�?T%w�)src/Psalm/Node/Expr/VirtualBitwiseNot.php����c�G促�2src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseXor.php����c������+src/Psalm/Node/Expr/BinaryOp/VirtualMul.php����c�:�|c�1src/Psalm/Node/Expr/BinaryOp/VirtualSpaceship.php����c�b��+src/Psalm/Node/Expr/BinaryOp/VirtualMod.php����c��z��0src/Psalm/Node/Expr/BinaryOp/VirtualCoalesce.php����c�͘�c�-src/Psalm/Node/Expr/BinaryOp/VirtualMinus.php����c�W�|�2src/Psalm/Node/Expr/BinaryOp/VirtualBooleanAnd.php����c���`�1src/Psalm/Node/Expr/BinaryOp/VirtualLogicalOr.php����c����6src/Psalm/Node/Expr/BinaryOp/VirtualGreaterOrEqual.php����c���w��1src/Psalm/Node/Expr/BinaryOp/VirtualIdentical.php����c��*��2src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseAnd.php����c��pR��1src/Psalm/Node/Expr/BinaryOp/VirtualShiftLeft.php����c��8�/src/Psalm/Node/Expr/BinaryOp/VirtualSmaller.php����c�tS�>�1src/Psalm/Node/Expr/BinaryOp/VirtualBooleanOr.php����c�)VP�-src/Psalm/Node/Expr/BinaryOp/VirtualEqual.php����c��D��,src/Psalm/Node/Expr/BinaryOp/VirtualPlus.php����c�NQ
Z�0src/Psalm/Node/Expr/BinaryOp/VirtualNotEqual.php����c�1j
�6src/Psalm/Node/Expr/BinaryOp/VirtualSmallerOrEqual.php����c�h}�1src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseOr.php����c�:�٤+src/Psalm/Node/Expr/BinaryOp/VirtualPow.php����c�(�̤.src/Psalm/Node/Expr/BinaryOp/VirtualConcat.php����c�����+src/Psalm/Node/Expr/BinaryOp/VirtualDiv.php����c�D5UF�4src/Psalm/Node/Expr/BinaryOp/VirtualNotIdentical.php����c�B�J�2src/Psalm/Node/Expr/BinaryOp/VirtualLogicalAnd.php����c�:���/src/Psalm/Node/Expr/BinaryOp/VirtualGreater.php����c����2src/Psalm/Node/Expr/BinaryOp/VirtualShiftRight.php����c��)�2src/Psalm/Node/Expr/BinaryOp/VirtualLogicalXor.php����c�x1�1src/Psalm/Node/Expr/VirtualNullsafeMethodCall.php����c�m���$src/Psalm/Node/Expr/VirtualError.php����c��^�n�)src/Psalm/Node/Expr/VirtualClosureUse.php����c������$src/Psalm/Node/Expr/VirtualEmpty.php����c��X�c�,src/Psalm/Node/Expr/VirtualArrayDimFetch.php����c�-9���(src/Psalm/Node/Expr/VirtualAssignRef.php����c���ޤ,src/Psalm/Node/Expr/VirtualErrorSuppress.php����c��<d�%src/Psalm/Node/Expr/VirtualPreInc.php����c�3�5�(src/Psalm/Node/Expr/VirtualYieldFrom.php����c�E�郤$src/Psalm/Node/Expr/VirtualMatch.php����c�ɩ�T�%src/Psalm/Node/Expr/VirtualPreDec.php����c�2�?ʤ)src/Psalm/Node/Expr/VirtualInstanceof.php����c��&U�(src/Psalm/Node/Expr/VirtualUnaryPlus.php����c�Tp��"src/Psalm/Node/Expr/VirtualNew.php����c���<�$src/Psalm/Node/Expr/VirtualThrow.php����c�2��?�#src/Psalm/Node/Expr/VirtualList.php����c����$src/Psalm/Node/Expr/VirtualYield.php����c�F���%src/Psalm/Node/Expr/VirtualAssign.php����c�(ᄏ�$src/Psalm/Node/Expr/VirtualIsset.php����c�=�M�)src/Psalm/Node/Expr/VirtualConstFetch.php����c��@ʤ(src/Psalm/Node/Expr/VirtualArrayItem.php����c�����)src/Psalm/Node/Expr/VirtualStaticCall.php����c���Nj�)src/Psalm/Node/Expr/VirtualMethodCall.php����c�N�f��'src/Psalm/Node/Expr/VirtualVariable.php����c��]���4src/Psalm/Node/Expr/VirtualNullsafePropertyFetch.php���c��?¤)src/Psalm/Node/Expr/VirtualBooleanNot.php����c�
�h�&src/Psalm/Node/Expr/VirtualTernary.php����c�LE�i�&src/Psalm/Node/Expr/VirtualPostInc.php����c���ä(src/Psalm/Node/Expr/VirtualShellExec.php����c�>��4�2src/Psalm/Node/Expr/AssignOp/VirtualBitwiseXor.php����c�*[+.�+src/Psalm/Node/Expr/AssignOp/VirtualMul.php����c���Զ�+src/Psalm/Node/Expr/AssignOp/VirtualMod.php����c�_W1Ϥ0src/Psalm/Node/Expr/AssignOp/VirtualCoalesce.php����c��e��-src/Psalm/Node/Expr/AssignOp/VirtualMinus.php����c��.��2src/Psalm/Node/Expr/AssignOp/VirtualBitwiseAnd.php����c�o��'�1src/Psalm/Node/Expr/AssignOp/VirtualShiftLeft.php����c���
��,src/Psalm/Node/Expr/AssignOp/VirtualPlus.php����c��07X�1src/Psalm/Node/Expr/AssignOp/VirtualBitwiseOr.php����c��[���+src/Psalm/Node/Expr/AssignOp/VirtualPow.php����c���P�.src/Psalm/Node/Expr/AssignOp/VirtualConcat.php����c���w�+src/Psalm/Node/Expr/AssignOp/VirtualDiv.php����c�����2src/Psalm/Node/Expr/AssignOp/VirtualShiftRight.php����c���c��&src/Psalm/Node/Expr/VirtualInclude.php����c�J�;"�)src/Psalm/Node/Expr/Cast/VirtualArray.php����c�
��I�)src/Psalm/Node/Expr/Cast/VirtualUnset.php����c���ˤ'src/Psalm/Node/Expr/Cast/VirtualInt.php����c�S2]!�(src/Psalm/Node/Expr/Cast/VirtualBool.php����c���*src/Psalm/Node/Expr/Cast/VirtualObject.php����c���t�*src/Psalm/Node/Expr/Cast/VirtualDouble.php����c��k�*src/Psalm/Node/Expr/Cast/VirtualString.php����c��;�j�$src/Psalm/Node/Expr/VirtualPrint.php����c��F6�$src/Psalm/Node/Expr/VirtualClone.php����c�����.src/Psalm/Node/Expr/VirtualClassConstFetch.php����c��ʚ�#src/Psalm/Node/Expr/VirtualExit.php����c�Qn���,src/Psalm/Node/Expr/VirtualArrowFunction.php����c�,��&src/Psalm/Node/Expr/VirtualClosure.php����c�UU���,src/Psalm/Node/Expr/VirtualPropertyFetch.php����c�k��'src/Psalm/Node/Name/VirtualRelative.php����c��d���-src/Psalm/Node/Name/VirtualFullyQualified.php����c�hĊ�src/Psalm/Node/VirtualConst.php����c��i��/src/Psalm/Node/Stmt/VirtualPropertyProperty.php����c�r�xZ�"src/Psalm/Node/Stmt/VirtualFor.php����c�T��2�$src/Psalm/Node/Stmt/VirtualClass.php����c��2<X�&src/Psalm/Node/Stmt/VirtualForeach.php����c�9��Ȥ$src/Psalm/Node/Stmt/VirtualUnset.php����c�CHd�#src/Psalm/Node/Stmt/VirtualEcho.php����c�C2ͤ<src/Psalm/Node/Stmt/TraitUseAdaptation/VirtualPrecedence.php���c��M��7src/Psalm/Node/Stmt/TraitUseAdaptation/VirtualAlias.php����c�Q���(src/Psalm/Node/Stmt/VirtualInterface.php����c��.��'src/Psalm/Node/Stmt/VirtualContinue.php����c�]=^�#src/Psalm/Node/Stmt/VirtualCase.php����c���.L�$src/Psalm/Node/Stmt/VirtualCatch.php����c����
�%src/Psalm/Node/Stmt/VirtualUseUse.php����c�01)��&src/Psalm/Node/Stmt/VirtualFinally.php����c�9���'src/Psalm/Node/Stmt/VirtualGroupUse.php����c���ho�%src/Psalm/Node/Stmt/VirtualSwitch.php����c�.���)src/Psalm/Node/Stmt/VirtualExpression.php���c��W�$src/Psalm/Node/Stmt/VirtualBreak.php����c���/�(src/Psalm/Node/Stmt/VirtualNamespace.php����c���Ú�$src/Psalm/Node/Stmt/VirtualWhile.php����c�!���$src/Psalm/Node/Stmt/VirtualThrow.php����c������$src/Psalm/Node/Stmt/VirtualLabel.php����c����+src/Psalm/Node/Stmt/VirtualHaltCompiler.php����c�43��'src/Psalm/Node/Stmt/VirtualFunction.php����c���k�'src/Psalm/Node/Stmt/VirtualTraitUse.php����c�ێ��-src/Psalm/Node/Stmt/VirtualDeclareDeclare.php����c�����&src/Psalm/Node/Stmt/VirtualDeclare.php����c��c�ʤ'src/Psalm/Node/Stmt/VirtualProperty.php����c���vq�%src/Psalm/Node/Stmt/VirtualElseIf.php����c�51Ф%src/Psalm/Node/Stmt/VirtualStatic.php����c�i:Q �#src/Psalm/Node/Stmt/VirtualGoto.php����c��#I��!src/Psalm/Node/Stmt/VirtualDo.php����c�s�
#�(src/Psalm/Node/Stmt/VirtualStaticVar.php����c�w����%src/Psalm/Node/Stmt/VirtualReturn.php����c�,aq��!src/Psalm/Node/Stmt/VirtualIf.php����c�[�Z�"src/Psalm/Node/Stmt/VirtualNop.php����c��؁.�)src/Psalm/Node/Stmt/VirtualClassConst.php����c��? �)src/Psalm/Node/Stmt/VirtualInlineHTML.php����c�3Ս��'src/Psalm/Node/Stmt/VirtualTryCatch.php����c���{��#src/Psalm/Node/Stmt/VirtualElse.php����c���$src/Psalm/Node/Stmt/VirtualConst.php����c�Gwx�%src/Psalm/Node/Stmt/VirtualGlobal.php����c����Ҥ*src/Psalm/Node/Stmt/VirtualClassMethod.php����c��-�P�$src/Psalm/Node/Stmt/VirtualTrait.php����c�C�Z��"src/Psalm/Node/Stmt/VirtualUse.php����c��8C�src/Psalm/Node/VirtualParam.php����c�"���$src/Psalm/Node/VirtualIdentifier.php&���c&�����#src/Psalm/Node/VirtualAttribute.php����c�L���#src/Psalm/Node/VirtualUnionType.php����c��~�src/Psalm/DocComment.php���c6���$src/Psalm/FileBasedPluginAdapter.php����c��x[�src/Psalm/Type.phprl���crl�H'}�psalm����c��(��dictionaries/PropertyMap.php5E���c5E1}��#dictionaries/CallMap_historical.php(����c(���Pf�"dictionaries/ManualPropertyMap.php����c��[ۤ!dictionaries/CallMap_80_delta.phps���csg��Ӥ!dictionaries/CallMap_71_delta.php���c�
���!dictionaries/CallMap_82_delta.php����c�-Ll��dictionaries/CallMap.php}���c}�_��!dictionaries/CallMap_74_delta.php
���c
44�l�!dictionaries/CallMap_81_delta.php�����c�����ɤ!dictionaries/CallMap_72_delta.phpwL���cwL��d��%dictionaries/InternalTaintSinkMap.phpE���cE"�z=�!dictionaries/CallMap_73_delta.php���c0;�f�<dictionaries/scripts/update_signaturemap_from_other_tool.php{���c{��.��3docs/running_psalm/issues/PossiblyUnusedProperty.md����c��y���.docs/running_psalm/issues/DuplicateFunction.md����c��.docs/running_psalm/issues/DuplicateEnumCase.md����c�ÿq�)docs/running_psalm/issues/TaintedInput.mdB���cB���;docs/running_psalm/issues/PossiblyNullPropertyAssignment.md����c���A��+docs/running_psalm/issues/ImpureVariable.md����c��ȉ�,docs/running_psalm/issues/TooFewArguments.md����c�&V�ڤ/docs/running_psalm/issues/UnusedFunctionCall.md����c�=�q�,docs/running_psalm/issues/InvalidIterator.md����c�G%�5docs/running_psalm/issues/MissingClosureReturnType.md����c�m�j�:docs/running_psalm/issues/ExtensionRequirementViolation.mdi���ci��KZ�0docs/running_psalm/issues/DeprecatedInterface.mdA���cA�7U��.docs/running_psalm/issues/InvalidReturnType.md����c��ȸ6�>docs/running_psalm/issues/LessSpecificImplementedReturnType.md����c�8(R�;docs/running_psalm/issues/InvalidPropertyAssignmentValue.md����c��X3�.docs/running_psalm/issues/NullPropertyFetch.md{���c{�=]X�.docs/running_psalm/issues/MutableDependency.mdP���cPv��0docs/running_psalm/issues/InvalidParamDefault.md����c����}�-docs/running_psalm/issues/IfThisIsMismatch.md7���c7�a��*docs/running_psalm/issues/InvalidParent.md����c����Ӥ,docs/running_psalm/issues/StringIncrement.md����c��$�<docs/running_psalm/issues/UndefinedThisPropertyAssignment.md����c�G�_}�1docs/running_psalm/issues/PossiblyNullArgument.md����c�;Y4�1docs/running_psalm/issues/PossiblyFalseOperand.md����c��״�1docs/running_psalm/issues/ImpureStaticProperty.md7���c7�U7�4docs/running_psalm/issues/NullableReturnStatement.md���c�
��4docs/running_psalm/issues/MixedInferredReturnType.md����c��>�4docs/running_psalm/issues/OverriddenFinalConstant.md���c�Όv�-docs/running_psalm/issues/InvalidAttribute.md+���c+)֫ɤ8docs/running_psalm/issues/UndefinedPropertyAssignment.md����c�uȐ��.docs/running_psalm/issues/UnusedConstructor.md���c3n:
�6docs/running_psalm/issues/DocblockTypeContradiction.mdy���cy�\�0docs/running_psalm/issues/UnresolvableInclude.md����c�����=docs/running_psalm/issues/InvalidTraversableImplementation.md>���c>�iM��0docs/running_psalm/issues/PossiblyNullOperand.md����c���
פ+docs/running_psalm/issues/UnusedProperty.md����c�629��/docs/running_psalm/issues/ImpureFunctionCall.md@���c@�U��/docs/running_psalm/issues/AbstractMethodCall.md����c�W�8Τ4docs/running_psalm/issues/UnhandledMatchCondition.mdW���cW���9�4docs/running_psalm/issues/PossiblyNullArrayOffset.md����c�1��@docs/running_psalm/issues/RedundantConditionGivenDocblockType.md{���c{��tޤ+docs/running_psalm/issues/UndefinedClass.mdh���ch	��/docs/running_psalm/issues/MissingConstructor.md����c�K�X��4docs/running_psalm/issues/PossiblyNullArrayAccess.md����c���=�.docs/running_psalm/issues/MissingReturnType.md����c�L��Ƥ)docs/running_psalm/issues/MixedOperand.mdW���cW�T��,docs/running_psalm/issues/DeprecatedTrait.md0���c0X�z�3docs/running_psalm/issues/LessSpecificReturnType.md����c�L6e�3docs/running_psalm/issues/OverriddenMethodAccess.md����c���n�8docs/running_psalm/issues/PossiblyInvalidFunctionCall.md����c�J�j��/docs/running_psalm/issues/RedundantCondition.md����c��aI�Cdocs/running_psalm/issues/PossiblyInvalidPropertyAssignmentValue.md5���c5��Z�,docs/running_psalm/issues/ComplexFunction.mdi���ci{Τ,docs/running_psalm/issues/NullArrayAccess.mdx���cx6Mx1�4docs/running_psalm/issues/MixedReturnTypeCoercion.md����c�L�j��Adocs/running_psalm/issues/RedundantPropertyInitializationCheck.md3���c3�rA�7docs/running_psalm/issues/PossiblyInvalidArrayAccess.md����c�ci�,�7docs/running_psalm/issues/PossiblyInvalidArrayOffset.md����c�(;%�+docs/running_psalm/issues/UndefinedTrace.md����c��%N��,docs/running_psalm/issues/TaintedCallable.md4���c4�9Qפ0docs/running_psalm/issues/MissingDocblockType.md����c�Of��3docs/running_psalm/issues/UndefinedDocblockClass.md����c���^�1docs/running_psalm/issues/InvalidPropertyFetch.md����c��`&�(docs/running_psalm/issues/TaintedLdap.md����c��ֵ��)docs/running_psalm/issues/InvalidClass.mdb���cbn;���+docs/running_psalm/issues/DuplicateParam.md����c��
��,docs/running_psalm/issues/UnevaluatedCode.md����c���ߒ�6docs/running_psalm/issues/InvalidFalsableReturnType.md����c�����-docs/running_psalm/issues/MixedArrayOffset.md����c���T��Cdocs/running_psalm/issues/RedundantFunctionCallGivenDocblockType.mde���ce(9��0docs/running_psalm/issues/InvalidFunctionCall.mdx���cxѶ�s�/docs/running_psalm/issues/MixedPropertyFetch.md����c��F�F�.docs/running_psalm/issues/UndefinedFunction.mdf���cf��T�*docs/running_psalm/issues/MixedArgument.md����c��fD�,docs/running_psalm/issues/UndefinedMethod.mdm���cm���^�/docs/running_psalm/issues/DeprecatedConstant.md����c�dnj�5docs/running_psalm/issues/InvalidDocblockParamName.md
���c
$�\��/docs/running_psalm/issues/DeprecatedProperty.md���c�G`�7docs/running_psalm/issues/PossiblyInvalidDocblockTag.md����c�E)�6docs/running_psalm/issues/PossiblyNullPropertyFetch.md����c��u�Ť<docs/running_psalm/issues/MismatchingDocblockPropertyType.md����c�N���/docs/running_psalm/issues/UnusedForeachValue.md����c��W�'docs/running_psalm/issues/MixedClone.mdx���cx;ɮ�,docs/running_psalm/issues/InvalidArgument.mdz���cz���ɤ/docs/running_psalm/issues/InvalidStringClass.md����c�*��q�1docs/running_psalm/issues/ArgumentTypeCoercion.md]���c]?&�^�6docs/running_psalm/issues/PossiblyInvalidMethodCall.md���c~
���6docs/running_psalm/issues/UnsupportedReferenceUsage.md����c�Xd\>�1docs/running_psalm/issues/UndefinedMagicMethod.md����c�����.docs/running_psalm/issues/NonStaticSelfCall.md����c�̄���)docs/running_psalm/issues/NullIterator.md^���c^Vj�-docs/running_psalm/issues/NullFunctionCall.mds���cs���Y�4docs/running_psalm/issues/InvalidStaticInvocation.md����c�A��Ĥ<docs/running_psalm/issues/PossiblyUndefinedIntArrayOffset.md���cy��7�-docs/running_psalm/issues/NoEnumProperties.md����c�0l�Ѥ+docs/running_psalm/issues/InternalMethod.md����c�����3docs/running_psalm/issues/UndefinedPropertyFetch.md����c��~h�1docs/running_psalm/issues/PossiblyUnusedMethod.mdb���cb��`�4docs/running_psalm/issues/PossiblyInvalidIterator.md����c��D1�3docs/running_psalm/issues/PossiblyInvalidOperand.md����c��L/�-docs/running_psalm/issues/EmptyArrayAccess.mdx���cx�-B�4docs/running_psalm/issues/PossiblyInvalidArgument.md����c����/docs/running_psalm/issues/InaccessibleMethod.md����c���wb�.docs/running_psalm/issues/DuplicateConstant.md���c��B�8docs/running_psalm/issues/LessSpecificReturnStatement.md����c��1�6docs/running_psalm/issues/InaccessibleClassConstant.md����c��	��8docs/running_psalm/issues/UndefinedMagicPropertyFetch.md���c����(docs/running_psalm/issues/PluginIssue.md*���c*��xͤ1docs/running_psalm/issues/InvalidNamedArgument.md����c�M�*docs/running_psalm/issues/ForbiddenCode.md����c��(g�1docs/running_psalm/issues/ParadoxicalCondition.md���c.�

�8docs/running_psalm/issues/OverriddenInterfaceConstant.md���c��N��.docs/running_psalm/issues/DuplicateArrayKey.md����c����_�2docs/running_psalm/issues/AbstractInstantiation.md����c��!�Ȥ0docs/running_psalm/issues/UnsafeInstantiation.md=���c=�����*docs/running_psalm/issues/RedundantCast.md����c�/1�2docs/running_psalm/issues/TaintedTextWithQuotes.md����c���;�-docs/running_psalm/issues/UnusedMethodCall.md����c��0�T�3docs/running_psalm/issues/InvalidPassByReference.md����c�p�0docs/running_psalm/issues/UnusedPsalmSuppress.md����c��W�0�/docs/running_psalm/issues/DeprecatedFunction.md2���c2/%B��2docs/running_psalm/issues/RedundantFunctionCall.md����c����+docs/running_psalm/issues/TaintedInclude.md����c�#����0docs/running_psalm/issues/ImpurePropertyFetch.md����c�R�V�3docs/running_psalm/issues/TypeDoesNotContainNull.md����c��:�^�6docs/running_psalm/issues/InvalidPropertyAssignment.md����c��D��6docs/running_psalm/issues/PossiblyUnusedReturnValue.md	���c	0��	�$docs/running_psalm/issues/NoValue.mdB���cB���I�)docs/running_psalm/issues/InvalidScope.mda���cal��#�1docs/running_psalm/issues/PossiblyNullIterator.md����c�ia)��2docs/running_psalm/issues/MissingThrowsDocblock.md����c�
*�"�>docs/running_psalm/issues/PossiblyInvalidPropertyAssignment.md`���c`b��ݤ9docs/running_psalm/issues/TraitMethodSignatureMismatch.md���c��,�,docs/running_psalm/issues/MixedAssignment.md����c��=��&docs/running_psalm/issues/CheckType.md{���c{�WRo�8docs/running_psalm/issues/UnimplementedAbstractMethod.md����c���+a�)docs/running_psalm/issues/TaintedShell.md����c���Q�3docs/running_psalm/issues/InvalidReturnStatement.md����c����6docs/running_psalm/issues/InvalidNullableReturnType.md����c��D�Ť,docs/running_psalm/issues/InvalidToString.md����c�۱���3docs/running_psalm/issues/NullPropertyAssignment.mdy���cy	�p��9docs/running_psalm/issues/MismatchingDocblockParamType.md����c��X��(docs/running_psalm/issues/MissingFile.md����c�H3�G�(docs/running_psalm/issues/UnusedClass.md����c�H�Yڤ(docs/running_psalm/issues/UnusedParam.mdp���cp����0docs/running_psalm/issues/PossiblyUnusedParam.md����c��6�ˤ1docs/running_psalm/issues/InaccessibleProperty.md����c�&�ؤ9docs/running_psalm/issues/PossiblyInvalidPropertyFetch.mdY���cY�ϾӤ1docs/running_psalm/issues/MissingTemplateParam.md����c�:���4docs/running_psalm/issues/FalsableReturnStatement.md����c�Y��/�8docs/running_psalm/issues/MixedStringOffsetAssignment.md����c������4docs/running_psalm/issues/NamedArgumentNotAllowed.md����c���8Ѥ6docs/running_psalm/issues/PossiblyUndefinedVariable.md����c��	��1docs/running_psalm/issues/UnresolvableConstant.md����c�0�ۤ.docs/running_psalm/issues/CircularReference.md����c��p��(docs/running_psalm/issues/ConfigIssue.md����c�����=docs/running_psalm/issues/UndefinedMagicPropertyAssignment.md3���c373�4docs/running_psalm/issues/MethodSignatureMismatch.md'���c'��d:�5docs/running_psalm/issues/PossiblyNullFunctionCall.md����c�R>�'�<docs/running_psalm/issues/PossiblyUndefinedGlobalVariable.md����c��tf@�/docs/running_psalm/issues/InvalidArrayAccess.md����c�[�H�9docs/running_psalm/issues/ImplementedParamTypeMismatch.md	���c	6�J�5docs/running_psalm/issues/NonInvariantPropertyType.mdN���cN��4�-docs/running_psalm/issues/InternalProperty.md����c�y6�Q�,docs/running_psalm/issues/DeprecatedClass.md"���c"�2�C�3docs/running_psalm/issues/DuplicateEnumCaseValue.mdR���cR�hqA�/docs/running_psalm/issues/InvalidArrayOffset.md����c�y�yڤ*docs/running_psalm/issues/NullReference.mdm���cm�ߍ&�;docs/running_psalm/issues/RedundantCastGivenDocblockType.md����c�$�6v�9docs/running_psalm/issues/UnimplementedInterfaceMethod.md����c�_�פ5docs/running_psalm/issues/OverriddenPropertyAccess.md
���c
��7�7docs/running_psalm/issues/PossibleRawObjectIteration.md����c��e��3docs/running_psalm/issues/PossiblyFalseReference.md���cW\]4�2docs/running_psalm/issues/PossiblyFalseIterator.md����c��I��/docs/running_psalm/issues/RawObjectIteration.mdm���cm�𒮤7docs/running_psalm/issues/MissingImmutableAnnotation.md����c�>մz�@docs/running_psalm/issues/PossiblyNullPropertyAssignmentValue.md$���c$-��}�7docs/running_psalm/issues/ConstantDeclarationInTrait.md����c���9[�0docs/running_psalm/issues/MissingPropertyType.md����c�`���1docs/running_psalm/issues/MixedReturnStatement.md����c�D�m��*docs/running_psalm/issues/TaintedCustom.mdh���ch%���*docs/running_psalm/issues/ComplexMethod.mdc���cc�X��5docs/running_psalm/issues/InvalidClassConstantType.mdI���cI/�L��)docs/running_psalm/issues/InvalidCatch.md����c���,�.docs/running_psalm/issues/ParamNameMismatch.md	���c	3���)docs/running_psalm/issues/NullArgument.md����c�ϥ�Ť,docs/running_psalm/issues/MixedMethodCall.mdf���cfx!��/docs/running_psalm/issues/UndefinedInterface.md����c�g@vV�&docs/running_psalm/issues/RiskyCast.md3���c3;���*docs/running_psalm/issues/TaintedCookie.md����c�����8docs/running_psalm/issues/PossiblyNullArrayAssignment.md����c���Ǥ1docs/running_psalm/issues/ImpureStaticVariable.md���c�� �.docs/running_psalm/issues/InvalidEnumMethod.md���c�ŇѤ*docs/running_psalm/issues/InternalClass.md����c��ዂ�7docs/running_psalm/issues/UndefinedThisPropertyFetch.md����c�Gv�k�Adocs/running_psalm/issues/PossiblyFalsePropertyAssignmentValue.md3���c3�f큤?docs/running_psalm/issues/PossiblyUndefinedStringArrayOffset.md)���c)V0�-docs/running_psalm/issues/ImpureMethodCall.mdz���czw1�w�2docs/running_psalm/issues/PossiblyFalseArgument.mdT���cTM��2docs/running_psalm/issues/NoInterfaceProperties.md-���c-��/�4docs/running_psalm/issues/UndefinedGlobalVariable.mdn���cns���7docs/running_psalm/issues/UnsafeGenericInstantiation.md5	���c5	ZNj>�4docs/running_psalm/issues/UndefinedAttributeClass.md����c�]2��/docs/running_psalm/issues/TaintedUnserialize.md���cc��-docs/running_psalm/issues/AssignmentToVoid.md���c��Pɤ.docs/running_psalm/issues/InvalidMethodCall.mdt���ct�lq	�(docs/running_psalm/issues/TaintedHtml.mdg���cg��c�:docs/running_psalm/issues/ImplementedReturnTypeMismatch.md����c���O�3docs/running_psalm/issues/InterfaceInstantiation.md����c�Z���.docs/running_psalm/issues/UndefinedVariable.md����c��_��5docs/running_psalm/issues/UndefinedInterfaceMethod.md����c�6�ܬ�>docs/running_psalm/issues/ReferenceReusedFromConfusingScope.md����c��+�h�/docs/running_psalm/issues/InvalidExtendClass.md����c�0'R��5docs/running_psalm/issues/UnnecessaryVarAnnotation.md���c�u�f�+docs/running_psalm/issues/UndefinedTrait.mdq���cqݹͤ'docs/running_psalm/issues/ParseError.md����c�uAf��=docs/running_psalm/issues/NonInvariantDocblockPropertyType.md����c�� ���4docs/running_psalm/issues/PossiblyUndefinedMethod.md����c����,docs/running_psalm/issues/NullArrayOffset.md����c��%�S�3docs/running_psalm/issues/InvalidArrayAssignment.md}���c}���Q�1docs/running_psalm/issues/PossiblyInvalidClone.md����c��d���2docs/running_psalm/issues/TooManyTemplateParams.mdE���cELQ�ڤ:docs/running_psalm/issues/MismatchingDocblockReturnType.md����c�B
�s�,docs/running_psalm/issues/DuplicateMethod.md����c�)���5docs/running_psalm/issues/ImpurePropertyAssignment.md����c�a�3"�)docs/running_psalm/issues/ReservedWord.md|���c|�>���)docs/running_psalm/issues/UnusedMethod.md����c��:V�9docs/running_psalm/issues/ReferenceConstraintViolation.md����c� sϤ*docs/running_psalm/issues/InvalidGlobal.mdZ���cZ��.docs/running_psalm/issues/InvalidTypeImport.md����c���K�Adocs/running_psalm/issues/MethodSignatureMustProvideReturnType.md����c��&���)docs/running_psalm/issues/FalseOperand.md����c�y�4docs/running_psalm/issues/MixedPropertyAssignment.md����c�K�`�2docs/running_psalm/issues/UnrecognizedStatement.md����c���C��4docs/running_psalm/issues/MissingClosureParamType.md����c��"&f�-docs/running_psalm/issues/DeprecatedMethod.mdc���cc^�ӂ�;docs/running_psalm/issues/InvalidConstantAssignmentValue.md����c������3docs/running_psalm/issues/UnrecognizedExpression.md����c�cB�+docs/running_psalm/issues/DuplicateClass.md���c���+docs/running_psalm/issues/UnusedVariable.md:���c:�b�?docs/running_psalm/issues/ImplementationRequirementViolation.md����c���դ:docs/running_psalm/issues/LessSpecificClassConstantType.mdK���cKi7a^�"docs/running_psalm/issues/Trace.md����c���x�1docs/running_psalm/issues/PropertyTypeCoercion.md���c���.docs/running_psalm/issues/TaintedUserSecret.md����c�Z����0docs/running_psalm/issues/PossiblyInvalidCast.md����c��S��)docs/running_psalm/issues/InvalidClone.mdz���czx&%��3docs/running_psalm/issues/TypeDoesNotContainType.md����c�m���(docs/running_psalm/issues/NullOperand.md����c��p$�/docs/running_psalm/issues/UnusedClosureParam.md����c�z<�6docs/running_psalm/issues/MixedPropertyTypeCoercion.md2���c2��9A�3docs/running_psalm/issues/InvalidLiteralArgument.md���cbgK�2docs/running_psalm/issues/InvalidScalarArgument.md����c��a	�1docs/running_psalm/issues/InvalidTemplateParam.mdt���ct�|K)�)docs/running_psalm/issues/InvalidThrow.md����c�)��Ԥ8docs/running_psalm/issues/ImpureByReferenceAssignment.md����c�ӬF��*docs/running_psalm/issues/TaintedHeader.md���c ��&�9docs/running_psalm/issues/ConstructorSignatureMismatch.md����c����=docs/running_psalm/issues/MoreSpecificImplementedParamType.md����c�Y��t�9docs/running_psalm/issues/PossiblyUndefinedArrayOffset.mdM���cM֚]l�1docs/running_psalm/issues/ImplicitToStringCast.mdt���ct��!��;docs/running_psalm/issues/PossiblyInvalidArrayAssignment.md����c���,�-docs/running_psalm/issues/MixedArrayAccess.md����c��Rࣤ,docs/running_psalm/issues/InvalidDocblock.mdt���ct%F�z�-docs/running_psalm/issues/TooManyArguments.md����c�4����>docs/running_psalm/issues/MethodSignatureMustOmitReturnType.md����c��#�0docs/running_psalm/issues/ContinueOutsideLoop.md����c�O9Y֤(docs/running_psalm/issues/TaintedFile.md����c���Ȥ.docs/running_psalm/issues/UndefinedConstant.mdn���cn��y}�-docs/running_psalm/issues/LoopInvalidation.md����c��|���.docs/running_psalm/issues/MixedFunctionCall.md����c�$���0docs/running_psalm/issues/TaintedSystemSecret.md���cG�@��1docs/running_psalm/issues/InvalidEnumCaseValue.mdY���cYxw��6docs/running_psalm/issues/RedundantIdentityWithTrue.md9���c9q�`�3docs/running_psalm/issues/MixedArrayTypeCoercion.md2���c2{��2docs/running_psalm/issues/PossiblyNullReference.md����c�9n(6�7docs/running_psalm/issues/UncaughtThrowInGlobalScope.md����c��^�0docs/running_psalm/issues/UnusedBaselineEntry.md����c�l_��2docs/running_psalm/issues/UninitializedProperty.md���c }�9docs/running_psalm/issues/AmbiguousConstantInheritance.md(���c(
;f	�(docs/running_psalm/issues/TaintedSSRF.mdO���cO8���.docs/running_psalm/issues/MissingDependency.md����c��C��+docs/running_psalm/issues/ParentNotFound.md����c������'docs/running_psalm/issues/TaintedSql.mdy���cy���(docs/running_psalm/issues/TaintedEval.mdA���cA�<��6docs/running_psalm/issues/MixedArgumentTypeCoercion.md&���c&>@�#�.docs/running_psalm/issues/UnusedReturnValue.md4���c43Yۤ+docs/running_psalm/issues/InvalidOperand.md����c�jVz��1docs/running_psalm/issues/MixedArrayAssignment.md����c�;��l�(docs/running_psalm/issues/InvalidCast.md����c���M�8docs/running_psalm/issues/PropertyNotSetInConstructor.md����c�w��ä-docs/running_psalm/issues/MissingParamType.md����c�_�@d�3docs/running_psalm/issues/MoreSpecificReturnType.mdM���cM��+&�3docs/running_psalm/issues/InvalidEnumBackingType.md����c��8K�;docs/running_psalm/issues/ConflictingReferenceConstraint.md����c��
�-�phar-versions.php����c�$~���assets/psalm-phar/dot-gitignore���cP
sT�assets/psalm-phar/README.mdn���cn+�E�assets/psalm-phar/composer.json����c���+�.box/vendor/autoload.php����c�s����$.box/vendor/composer/ClassLoader.php�>���c�>�5Ky�*.box/vendor/composer/autoload_classmap.php,
���c,
�ӽǤ(.box/vendor/composer/autoload_static.phpK���cK���?�&.box/vendor/composer/autoload_real.php���c�yi\�.box/vendor/composer/LICENSE.���c. ��&.box/vendor/composer/autoload_psr4.php6���c60Ӥ*.box/vendor/composer/semver/src/Semver.php����c��ׯ��1.box/vendor/composer/semver/src/VersionParser.php�9���c�9�Wz�9.box/vendor/composer/semver/src/Constraint/Constraint.php'&���c'&��`�>.box/vendor/composer/semver/src/Constraint/MultiConstraint.php~���c~5[�e�B.box/vendor/composer/semver/src/Constraint/ConstraintInterface.php����c���wQ�..box/vendor/composer/semver/src/Comparator.phpu���cu	74�,.box/vendor/composer/autoload_namespaces.php����c�t�!פ.box/src/Terminal.php�
���c�
%V��.box/src/Printer.php����c�)8AV�".box/src/IsPhpVersionFulfilled.php����c��!83�".box/src/RequirementCollection.php����c�Wb�?�.box/src/Requirement.phpm���cm��B��.box/src/IsFulfilled.phpv���cv�%*H�.box/src/Checker.php����c��)W>�.box/src/IO.php ���c �[l%�!.box/src/IsExtensionFulfilled.phpv���cv'0�Ҥ.box/.requirements.phpd���cd���.box/bin/check-requirements.php����c�^ʨ�<?php

/**
 * The SplDoublyLinkedList class provides the main functionalities of a doubly linked list.
 * @link https://php.net/manual/en/class.spldoublylinkedlist.php
 *
 * @template TValue
 * @template-implements Iterator<int, TValue>
 * @template-implements ArrayAccess<int, TValue>
 */
class SplDoublyLinkedList implements Iterator, Countable, ArrayAccess, Serializable
{
    public function __construct() {}

    /**
     * Add/insert a new value at the specified index
     *
     * @param int $index The index where the new value is to be inserted.
     * @param TValue $newval The new value for the index.
     * @return void
     *
     * @link https://php.net/spldoublylinkedlist.add
     * @since 5.5.0
     */
    public function add($index, $newval) {}

    /**
     * Pops a node from the end of the doubly linked list
     * @link https://php.net/manual/en/spldoublylinkedlist.pop.php
     *
     * @return TValue The value of the popped node.
     *
     * @since 5.3.0
     */
    public function pop() {}

    /**
     * Shifts a node from the beginning of the doubly linked list
     * @link https://php.net/manual/en/spldoublylinkedlist.shift.php
     *
     * @return TValue The value of the shifted node.
     *
     * @since 5.3.0
     */
    public function shift() {}

    /**
     * Pushes an element at the end of the doubly linked list
     * @link https://php.net/manual/en/spldoublylinkedlist.push.php
     *
     * @param TValue $value The value to push.
     * @return void
     *
     * @since 5.3.0
     */
    public function push($value) {}

    /**
     * Prepends the doubly linked list with an element
     * @link https://php.net/manual/en/spldoublylinkedlist.unshift.php
     *
     * @param TValue $value The value to unshift.
     * @return void
     *
     * @since 5.3.0
     */
    public function unshift($value) {}

    /**
     * Peeks at the node from the end of the doubly linked list
     * @link https://php.net/manual/en/spldoublylinkedlist.top.php
     *
     * @return TValue The value of the last node.
     *
     * @since 5.3.0
     */
    public function top() {}

    /**
     * Peeks at the node from the beginning of the doubly linked list
     * @link https://php.net/manual/en/spldoublylinkedlist.bottom.php
     *
     * @return TValue The value of the first node.
     *
     * @since 5.3.0
     */
    public function bottom() {}

    /**
     * Counts the number of elements in the doubly linked list.
     * @link https://php.net/manual/en/spldoublylinkedlist.count.php
     *
     * @return int the number of elements in the doubly linked list.
     *
     * @since 5.3.0
     */
    public function count() {}

    /**
     * Checks whether the doubly linked list is empty.
     * @link https://php.net/manual/en/spldoublylinkedlist.isempty.php
     *
     * @return bool whether the doubly linked list is empty.
     *
     * @since 5.3.0
     */
    public function isEmpty() {}

    /**
     * Returns whether the requested $index exists
     * @link https://php.net/manual/en/spldoublylinkedlist.offsetexists.php
     *
     * @param int $index The index being checked.
     * @return bool true if the requested index exists, otherwise false
     *
     * @since 5.3.0
     */
    public function offsetExists($index) {}

    /**
     * Returns the value at the specified $index
     * @link https://php.net/manual/en/spldoublylinkedlist.offsetget.php
     *
     * @param int $index The index with the value.
     * @return TValue The value at the specified index.
     *
     * @since 5.3.0
     */
    public function offsetGet($index) {}

    /**
     * Sets the value at the specified $index to $newval
     * @link https://php.net/manual/en/spldoublylinkedlist.offsetset.php
     *
     * @param int $index The index being set.
     * @param TValue $newval The new value for the index.
     * @return void
     *
     * @since 5.3.0
     */
    public function offsetSet($index, $newval) {}

    /**
     * Unsets the value at the specified $index
     * @link https://php.net/manual/en/spldoublylinkedlist.offsetunset.php
     *
     * @param int $index The index being unset.
     * @return void
     *
     * @since 5.3.0
     */
    public function offsetUnset($index) {}

    /**
     * Return current array entry
     * @link https://php.net/manual/en/spldoublylinkedlist.current.php
     *
     * @return TValue The current node value.
     *
     * @since 5.3.0
     */
    public function current() {}

    /**
     * Return current node index
     * @link https://php.net/manual/en/spldoublylinkedlist.key.php
     *
     * @return int The current node index.
     *
     * @since 5.3.0
     */
    public function key() {}
}

/**
 * The SplFixedArray class provides the main functionalities of array.
 * The main differences between a SplFixedArray and a normal PHP array is that
 * the SplFixedArray is of fixed length and allows only integers within the range as indexes.
 * The advantage is that it uses less memory than a standard array.
 *
 * @link https://php.net/manual/en/class.splfixedarray.php
 *
 * @template TValue
 * @template-implements ArrayAccess<int, TValue>
 * @template-implements Iterator<int, TValue>
 */
class SplFixedArray implements Iterator, ArrayAccess, Countable {
    /**
     * Constructs a new fixed array
     *
     * Initializes a fixed array with a number of NULL values equal to size.
     * @link https://php.net/manual/en/splfixedarray.construct.php
     *
     * @param int $size The size of the fixed array. This expects a number between 0 and PHP_INT_MAX.

     * @since 5.3.0
     */
    public function __construct(int $size = 0) {}

    /**
     * Import a PHP array in a new SplFixedArray instance
     * @link https://php.net/manual/en/splfixedarray.fromarray.php
     *
     * @template TInValue
     * @param array<int, TInValue> $array The array to import
     * @param bool $save_indexes [optional] Try to save the numeric indexes used in the original array.
     *
     * @return SplFixedArray<TInValue> Instance of SplFixedArray containing the array content

     * @since 5.3.0
     */
    public static function fromArray(array $array, bool $save_indexes = true): SplFixedArray {}

    /**
     * Returns a PHP array from the fixed array
     * @link https://php.net/manual/en/splfixedarray.toarray.php
     *
     * @return array<int, TValue>

     * @since 5.3.0
     */
    public function toArray(): array {}

    /**
     * Returns the size of the array.
     * @link https://php.net/manual/en/splfixedarray.getsize.php
     *
     * @return int The size of the array

     * @see SplFixedArray::count()
     *
     * @since 5.3.0
     */
    public function getSize(): int {}

    /**
     * Returns the size of the array.
     * @link https://php.net/manual/en/splfixedarray.count.php
     *
     * @return int The size of the array
     *
     * @since 5.3.0
     */
    public function count(): int {}

    /**
     * Rewind the iterator back to the start
     * @link https://php.net/manual/en/splfixedarray.rewind.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function rewind(): void {}

    /**
     * Check whether the array contains more elements
     * @link https://php.net/manual/en/splfixedarray.valid.php
     *
     * @return bool true if the array contains any more elements, false otherwise.
     *
     * @since 5.3.0
     */
    public function valid(): bool {}

    /**
     * Returns current array index
     * @link https://php.net/manual/en/splfixedarray.key.php
     *
     * @return int The current array index
     *
     * @since 5.3.0
     */
    public function key(): int {}

    /**
     * Returns the current array entry
     * @link https://php.net/manual/en/splfixedarray.current.php
     *
     * @return TValue The current element value
     *
     * @since 5.3.0
     */
    public function current() {}

    /**
     * Move to the next entry
     * @link https://php.net/manual/en/splfixedarray.next.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function next(): void {}

    /**
     * Returns whether the specified index exists
     * @link https://php.net/manual/en/splfixedarray.offsetexists.php
     *
     * @param int $index The index being checked.
     * @return bool true if the requested index exists, and false otherwise.
     *
     * @since 5.3.0
     */
    public function offsetExists(int $index): bool {}

    /**
     * Sets a new value at a specified index
     * @link https://php.net/manual/en/splfixedarray.offsetset.php
     *
     * @param int $index The index being sent.
     * @param TValue $newval The new value for the index
     * @return void
     *
     * @since 5.3.0
     */
    public function offsetSet(int $index, $newval): void {}

    /**
     * Unsets the value at the specified $index
     * @link https://php.net/manual/en/splfixedarray.offsetunset.php
     *
     * @param int $index The index being unset
     * @return void
     *
     * @since 5.3.0
     */
    public function offsetUnset(int $index): void {}

    /**
     * Returns the value at the specified index
     * @link https://php.net/manual/en/splfixedarray.offsetget.php
     *
     * @param int $index The index with the value
     * @return TValue The value at the specified index
     *
     * @since 5.3.0
     */
    public function offsetGet(int $index) {}
}


/**
 * The SplStack class provides the main functionalities of a stack implemented using a doubly linked list.
 * @link https://php.net/manual/en/class.splstack.php
 *
 * @template TValue
 * @template-extends SplDoublyLinkedList<TValue>
 */
class SplStack extends SplDoublyLinkedList {
}

/**
 * The SplQueue class provides the main functionalities of a queue implemented using a doubly linked list.
 * @link https://php.net/manual/en/class.splqueue.php
 *
 * @template TValue
 * @template-extends SplDoublyLinkedList<TValue>
 */
class SplQueue extends SplDoublyLinkedList {
    /**
     * Adds an element to the queue.
     * @link https://php.net/manual/en/splqueue.enqueue.php
     *
     * @param TValue $value The value to enqueue.
     * @return void
     *
     * @since 5.3.0
     */
    public function enqueue($value) {}

    /**
     * Dequeues a node from the queue
     * @link https://php.net/manual/en/splqueue.dequeue.php
     *
     * @return TValue The value of the dequeued node.
     *
     * @since 5.3.0
     */
    public function dequeue() {}
}

/**
 * The SplHeap class provides the main functionalities of a Heap.
 * @link https://php.net/manual/en/class.splheap.php
 *
 * @template TValue
 * @template-implements Iterator<int, TValue>
 */
abstract class SplHeap implements Iterator, Countable {
    public function __construct() {}

    /**
     * Compare elements in order to place them correctly in the heap while sifting up
     * @link https://php.net/manual/en/splheap.compare.php
     *
     * @param TValue $value1 The value of the first node being compared.
     * @param TValue $value2 The value of the second node being compared.
     * @return int Positive integer if value1 is greater than value2, 0 if they are equal, negative integer otherwise.
     *
     * @since 5.3.0
     */
    protected abstract function compare($value1, $value2): int;

    /**
     * Counts the number of elements in the heap
     * @link https://php.net/manual/en/splheap.count.php
     *
     * @return int The number of elements in the heap.
     *
     * @since 5.3.0
     */
    public function count(): int {}

    /**
     * Get the current datastructure node.
     * @link https://php.net/manual/en/splheap.current.php
     *
     * @return TValue The current node value
     *
     * @since 5.3.0
     */
    public function current() {}

    /**
     * Extracts a node from top of the heap and sift up
     * @link https://php.net/manual/en/splheap.extract.php
     *
     * @return TValue The current node value
     *
     * @since 5.3.0
     */
    public function extract() {}

    /**
     * Inserts an element in the heap by sifting it up
     * @link https://php.net/manual/en/splheap.insert.php
     *
     * @param TValue $value The value to insert.
     * @return void
     *
     * @since 5.3.0
     */
    public function insert($value): void {}

    /**
     * Tells if the heap is in a corrupted state
     * @link https://php.net/manual/en/splheap.isCorrupted.php
     *
     * @return bool true if the heap is corrupted, false otherwise.
     *
     * @since 7.0.0
     */
    public function isCorrupted(): bool {}

    /**
     * Checks whether the heap is empty
     * @link https://php.net/manual/en/splheap.isEmpty.php
     *
     * @return bool Whether the heap is empty
     *
     * @since 5.3.0
     */
    public function isEmpty(): bool {}

    /**
     * Return current node index
     * @link https://php.net/manual/en/splheap.key.php
     *
     * @return int The current node index
     *
     * @since 5.3.0
     */
    public function key() {}

    /**
     * Move to the next node. This will delete the top node of the heap.
     * @link https://php.net/manual/en/splheap.next.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function next(): void {}

    /**
     * Recover from the corrupted state and allow further actions on the heap
     * @link https://php.net/manual/en/splheap.recoverFromCorruption.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function recoverFromCorruption(): void {}

    /**
     * Rewind iterator back to the start (no-op)
     * @link https://php.net/manual/en/splheap.rewind.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function rewind(): void {}

    /**
     * Peeks at the node from the top of the heap
     * @link https://php.net/manual/en/splheap.top.php
     *
     * @return TValue The value of the node on the top.
     *
     * @since 5.3.0
     */
    public function top() {}

    /**
     * Check whether the heap contains any more nodes
     * @link https://php.net/manual/en/splheap.valid.php
     *
     * @return bool Returns true if the heap contains any more nodes, false otherwise.
     *
     * @since 5.3.0
     */
    public function valid(): bool {}
}


/**
 * The SplMaxHeap class provides the main functionalities of a heap, keeping the maximum on the top.
 * @link https://php.net/manual/en/class.splmaxheap.php
 *
 * @template TValue
 * @template-extends SplHeap<TValue>
 */
class SplMaxHeap extends SplHeap {
}

/**
 * The SplMinHeap class provides the main functionalities of a heap, keeping the maximum on the top.
 * @link https://php.net/manual/en/class.splminheap.php
 *
 * @template TValue
 * @template-extends SplHeap<TValue>
 */
class SplMinHeap extends SplHeap {
}

/**
 * The SplPriorityQueue class provides the main functionalities of a prioritized queue, implemented using a max heap.
 * @link https://php.net/manual/en/class.splpriorityqueue.php
 *
 * @template TPriority
 * @template TValue
 * @template-implements Iterator<int, TValue>
 */
class SplPriorityQueue implements Iterator, Countable {
    /**
     * Extract the data
     */
    const EXTR_DATA = 0x00000001;
    /**
     * Extract the priority
     */
    const EXTR_PRIORITY = 0x00000002;
    /**
     * Extract an array containing both
     */
    const EXTR_BOTH = 0x00000003;

    public function __construct() {}

    /**
     * Compare priorities in order to place them correctly in the queue while sifting up
     * @link https://php.net/manual/en/splpriorityqueue.compare.php
     *
     * @param TValue $priority1 The priority of the first node being compared.
     * @param TValue $priority2 The priority of the second node being compared.
     * @return int Positive integer if priority1 is greater than priority2, 0 if they are equal, negative integer otherwise.
     *
     * @since 5.3.0
     */
    public function compare($priority1, $priority2): int {}

    /**
     * Counts the number of elements in the queue
     * @link https://php.net/manual/en/splpriorityqueue.count.php
     *
     * @return int The number of elements in the queue.
     *
     * @since 5.3.0
     */
    public function count(): int {}

    /**
     * Get the current datastructure node.
     * @link https://php.net/manual/en/splpriorityqueue.current.php
     *
     * @return TValue The current node value
     *
     * @since 5.3.0
     */
    public function current() {}

    /**
     * Extracts a node from top of the queue and sift up
     * @link https://php.net/manual/en/splpriorityqueue.extract.php
     *
     * @return TValue The current node value
     *
     * @since 5.3.0
     */
    public function extract() {}

    /**
     * Get the flags of extraction
     * @link https://php.net/manual/en/splpriorityqueue.getextractflags.php
     *
     * @return SplPriorityQueue::EXTR_* Returns the current extraction mode
     *
     * @see SplPriorityQueue::setExtractFlags
     *
     * @since 5.3.0
     */
    public function getExtractFlags(): int {}

    /**
     * Inserts an element in the queue by sifting it up
     * @link https://php.net/manual/en/splpriorityqueue.insert.php
     *
     * @param TValue $value The value to insert.
     * @param TPriority $priority The associated priority.
     * @return true
     *
     * @since 5.3.0
     */
    public function insert($value, $priority): bool {}

    /**
     * Tells if the queue is in a corrupted state
     * @link https://php.net/manual/en/splpriorityqueue.isCorrupted.php
     *
     * @return bool true if the queue is corrupted, false otherwise.
     *
     * @since 7.0.0
     */
    public function isCorrupted(): bool {}

    /**
     * Checks whether the queue is empty
     * @link https://php.net/manual/en/splpriorityqueue.isEmpty.php
     *
     * @return bool Whether the queue is empty
     *
     * @since 5.3.0
     */
    public function isEmpty(): bool {}

    /**
     * Return current node index
     * @link https://php.net/manual/en/splpriorityqueue.key.php
     *
     * @return int The current node index
     *
     * @since 5.3.0
     */
    public function key() {}

    /**
     * Move to the next node.
     * @link https://php.net/manual/en/splpriorityqueue.next.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function next(): void {}

    /**
     * Recover from the corrupted state and allow further actions on the queue
     * @link https://php.net/manual/en/splpriorityqueue.recoverFromCorruption.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function recoverFromCorruption(): void {}

    /**
     * Rewind iterator back to the start (no-op)
     * @link https://php.net/manual/en/splpriorityqueue.rewind.php
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function rewind(): void {}

    /**
     * Sets the mode of extraction
     * @link https://php.net/manual/en/splpriorityqueue.setextractflags.php
     *
     * @param SplPriorityQueue::EXTR_* $flags Defines what is extracted by SplPriorityQueue::current(), SplPriorityQueue::top() and SplPriorityQueue::extract().
     *
     * @return void
     *
     * @since 5.3.0
     */
    public function setExtractFlags(int $flags): void {}

    /**
     * Peeks at the node from the top of the queue
     * @link https://php.net/manual/en/splpriorityqueue.top.php
     *
     * @return TValue The value of the node on the top.
     *
     * @since 5.3.0
     */
    public function top() {}

    /**
     * Check whether the queue contains any more nodes
     * @link https://php.net/manual/en/splpriorityqueue.valid.php
     *
     * @return bool Returns true if the queue contains any more nodes, false otherwise.
     *
     * @since 5.3.0
     */
    public function valid(): bool {}
}


/**
 * The SplObjectStorage class provides a map from objects to data or, by
 * ignoring data, an object set. This dual purpose can be useful in many
 * cases involving the need to uniquely identify objects.
 * @link https://php.net/manual/en/class.splobjectstorage.php
 *
 * @template TObject as object
 * @template TArrayValue
 * @template-implements ArrayAccess<TObject, TArrayValue>
 * @template-implements Iterator<int, TObject>
 */
class SplObjectStorage implements Countable, Iterator, Serializable, ArrayAccess {
    public function __construct() {}

    /**
     * Adds an object in the storage
     * @link https://php.net/manual/en/splobjectstorage.attach.php
     *
     * @param TObject $object The object to add.
     * @param TArrayValue|null $data [optional] The data to associate with the object.
     * @return void
     *
     * @since 5.1.0
     */
    public function attach($object, $data = null) {}

    /**
     * Removes an object from the storage
     * @link https://php.net/manual/en/splobjectstorage.detach.php
     *
     * @param TObject $object The object to remove.
     * @return void
     *
     * @since 5.1.0
     */
    public function detach($object) {}

    /**
     * Checks if the storage contains a specific object
     * @link https://php.net/manual/en/splobjectstorage.contains.php
     *
     * @param TObject $object The object to look for.
     * @return bool true if the object is in the storage, false otherwise.
     *
     * @since 5.1.0
     */
    public function contains($object) {}

    /**
     * Adds all objects from another storage
     * @link https://php.net/manual/en/splobjectstorage.addall.php
     *
     * @param SplObjectStorage<TObject, TArrayValue> $storage The storage you want to import.
     * @return void
     *
     * @since 5.3.0
     */
    public function addAll($storage) {}

    /**
     * Removes objects contained in another storage from the current storage
     * @link https://php.net/manual/en/splobjectstorage.removeall.php
     *
     * @param SplObjectStorage<TObject, TArrayValue> $storage The storage containing the elements to remove.
     * @return void
     *
     * @since 5.3.0
     */
    public function removeAll($storage) {}

    /**
     * Removes all objects except for those contained in another storage from the current storage
     * @link https://php.net/manual/en/splobjectstorage.removeallexcept.php
     *
     * @param SplObjectStorage<TObject, TArrayValue> $storage The storage containing the elements to retain in the current storage.
     * @return void
     *
     * @since 5.3.6
     */
    public function removeAllExcept($storage) {}

    /**
     * Returns the data associated with the current iterator entry
     * @link https://php.net/manual/en/splobjectstorage.getinfo.php
     *
     * @return TArrayValue The data associated with the current iterator position.
     *
     * @since 5.3.0
     */
    public function getInfo() {}

    /**
     * Sets the data associated with the current iterator entry
     * @link https://php.net/manual/en/splobjectstorage.setinfo.php
     *
     * @param TArrayValue $data The data to associate with the current iterator entry.
     * @return void
     *
     * @since 5.3.0
     */
    public function setInfo($data) {}

    /**
     * Returns the number of objects in the storage
     * @link https://php.net/manual/en/splobjectstorage.count.php
     *
     * @return int The number of objects in the storage.
     *
     * @since 5.1.0
     */
    public function count() {}

    /**
     * Rewind the iterator to the first storage element
     * @link https://php.net/manual/en/splobjectstorage.rewind.php
     *
     * @return void
     *
     * @since 5.1.0
     */
    public function rewind() {}

    /**
     * Returns if the current iterator entry is valid
     * @link https://php.net/manual/en/splobjectstorage.valid.php
     *
     * @return bool true if the iterator entry is valid, false otherwise.
     *
     * @since 5.1.0
     */
    public function valid() {}

    /**
     * Returns the index at which the iterator currently is
     * @link https://php.net/manual/en/splobjectstorage.key.php
     *
     * @return int The index corresponding to the position of the iterator.
     *
     * @since 5.1.0
     */
    public function key() {}

    /**
     * Returns the current storage entry
     * @link https://php.net/manual/en/splobjectstorage.current.php
     *
     * @return TObject The object at the current iterator position.
     *
     * @since 5.1.0
     */
    public function current() {}

    /**
     * Move to the next entry
     * @link https://php.net/manual/en/splobjectstorage.next.php
     *
     * @return void
     *
     * @since 5.1.0
     */
    public function next() {}

    /**
     * Unserializes a storage from its string representation
     * @link https://php.net/manual/en/splobjectstorage.unserialize.php
     *
     * @param string $serialized The serialized representation of a storage.
     * @return void
     *
     * @since 5.2.2
     */
    public function unserialize($serialized) {}

    /**
     * Serializes the storage
     * @link https://php.net/manual/en/splobjectstorage.serialize.php
     *
     * @return string A string representing the storage.
     *
     * @since 5.2.2
     */
    public function serialize() {}

    /**
     * Checks whether an object exists in the storage
     * @link https://php.net/manual/en/splobjectstorage.offsetexists.php
     *
     * @param TObject $object The object to look for.
     * @return bool true if the object exists in the storage, and false otherwise.
     *
     * @since 5.3.0
     */
    public function offsetExists($object) {}

    /**
     * Associates data to an object in the storage
     * @link https://php.net/manual/en/splobjectstorage.offsetset.php
     *
     * @param TObject $object The object to associate data with.
     * @param TArrayValue|null $data [optional] The data to associate with the object.
     * @return void
     *
     * @since 5.3.0
     */
    public function offsetSet($object, $data = null) {}

    /**
     * Removes an object from the storage
     * @link https://php.net/manual/en/splobjectstorage.offsetunset.php
     *
     * @param TObject $object The object to remove.
     * @return void
     *
     * @since 5.3.0
     */
    public function offsetUnset($object) {}

    /**
     * Returns the data associated with an <type>object</type>
     * @link https://php.net/manual/en/splobjectstorage.offsetget.php
     *
     * @param TObject $object The object to look for.
     * @return TArrayValue The data previously associated with the object in the storage.
     *
     * @since 5.3.0
     */
    public function offsetGet($object) {}

    /**
     * Calculate a unique identifier for the contained objects
     * @link https://php.net/manual/en/splobjectstorage.gethash.php
     *
     * @param object $object object whose identifier is to be calculated.
     * @return string A string with the calculated identifier.
     *
     * @since 5.4.0
     */
    public function getHash($object) {}

}
<?php

/**
 * @template-covariant TKey
 * @template-covariant TValue
 *
 * @template-extends Traversable<TKey, TValue>
 */
interface IteratorAggregate extends Traversable {

    /**
     * @return Traversable<TKey, TValue> An instance of an object implementing Iterator or Traversable
     */
    public function getIterator();
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 *
 * @template-extends Traversable<TKey, TValue>
 */
interface Iterator extends Traversable {

    /**
     * @return TValue|null returns current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current();

    /**
     * @return void Any returned value is ignored.
     */
    public function next();

    /**
     * @return TKey|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key();

    /**
     * @return bool The return value will be casted to boolean and then evaluated.
     *              Returns true on success or false on failure.
     */
    public function valid();

    /**
     * @return void Any returned value is ignored.
     */
    public function rewind();
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 *
 * @template-extends Iterator<TKey, TValue>
 */
interface OuterIterator extends Iterator {
    /**
     * @return Iterator<TKey, TValue>
     */
    public function getInnerIterator();
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 *
 * @template-extends Iterator<TKey, TValue>
 */
interface RecursiveIterator extends Iterator {

    /**
     * @return bool true if the current entry can be iterated over, otherwise returns false.
     */
    public function hasChildren();

    /**
     * @return RecursiveIterator<TKey, TValue> An iterator for the current entry.
     */
    public function getChildren();
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-extends Iterator<TKey, TValue>
 */
interface SeekableIterator extends Iterator {
    /**
     * Seeks to a position
     * @link https://php.net/manual/en/seekableiterator.seek.php
     *
     * @param int $position The position to seek to.
     * @return void
     *
     * @since 5.1.0
     */
    public function seek($position);
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-covariant TIterator as Traversable<TKey, TValue>
 *
 * @template-implements OuterIterator<TKey, TValue>
 *
 * @mixin TIterator
 */
class IteratorIterator implements OuterIterator {
    /**
     * @param TIterator $iterator
     */
    public function __construct(Traversable $iterator) {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current key value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 * @template TKey
 * @template TValue
 * @template TIterator as Iterator<TKey, TValue>
 *
 * @template-extends IteratorIterator<TKey, TValue, TIterator>
 */
class AppendIterator extends IteratorIterator {
    public function __construct(){}

    /**
     * @param TIterator $iterator
     * @return void
     */
    public function append(Iterator $iterator) {}

    /**
     * @return ArrayIterator<TKey, TValue>
     */
    public function getArrayIterator() {}

    /**
     * @return int
     */
    public function getIteratorIndex() {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 * @template TKey as array-key
 * @template TValue
 * @template-implements SeekableIterator<TKey, TValue>
 * @template-implements ArrayAccess<TKey, TValue>
 */
class ArrayIterator implements SeekableIterator, ArrayAccess, Serializable, Countable {
    const STD_PROP_LIST = 1;
    const ARRAY_AS_PROPS = 2;

    /**
     * @param array<TKey, TValue> $array The array or object to be iterated on.
     * @param int-mask-of<static::*> $flags Flags to control the behaviour of the ArrayObject object.
     */
    public function __construct($array = array(), $flags = 0) { }

    /**
     * @param TKey $index The offset being checked.
     * @return bool true if the offset exists, otherwise false
     */
    public function offsetExists($index) { }

    /**
     * @param TKey $index The offset to get the value from.
     * @return TValue|null The value at offset index, null when accessing invalid indexes
     * @psalm-ignore-nullable-return
     */
    public function offsetGet($index) { }

    /**
     * @param TKey $index The index to set for.
     * @param TValue $newval The new value to store at the index.
     * @return void
     */
    public function offsetSet($index, $newval) { }

    /**
     * @param TKey $index The offset to unset.
     * @return void
     */
    public function offsetUnset($index) { }

    /**
     * @param TValue $value The value to append.
     * @return void
     */
    public function append($value) { }

    /**
     * @return array<TKey, TValue> A copy of the array, or array of public properties
     *                             if ArrayIterator refers to an object.
     */
    public function getArrayCopy() { }

    /**
     * @return int The number of elements or public properties in the associated
     *             array or object, respectively.
     */
    public function count() { }

    /**
     * @return int-mask-of<self::*> The current flags.
     */
    public function getFlags() { }

    /**
     * @param int-mask-of<self::*> $flags bitmask
     * @return void
     */
    public function setFlags($flags) { }

    /**
     * @return void
     */
    public function asort() { }

    /**
     * @return void
     */
    public function ksort() { }

    /**
     * @param callable(TValue,TValue):int $cmp_function The compare function used for the sort.
     * @return void
     */
    public function uasort($cmp_function) { }

    /**
     * @param callable(TKey,TKey):int $cmp_function The compare function used for the sort.
     * @return void
     */
    public function uksort($cmp_function) { }

    /**
     * @return void
     */
    public function natsort() { }

    /**
     * @return void
     */
    public function natcasesort() { }

    /**
     * @param string $serialized The serialized ArrayIterator object to be unserialized.
     * @return void
     */
    public function unserialize($serialized) { }

    /**
     * @return string The serialized ArrayIterator
     */
    public function serialize() { }

    /**
     * @return void
     */
    public function rewind() { }

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() { }

    /**
     * @return TKey|null The current array key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() { }

    /**
     * @return void
     */
    public function next() { }

    /**
     * @return bool
     */
    public function valid() { }

    /**
     * @param int $position The position to seek to.
     * @return void
     */
    public function seek($position) { }
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-covariant TIterator as Traversable<TKey, TValue>
 *
 * @template-extends IteratorIterator<TKey, TValue, TIterator>
 */
abstract class FilterIterator extends IteratorIterator {
    /** @return bool */
    abstract public function accept();

    /**
     * @return TValue Can return any type.
     */
    public function current() {}

    /**
     * @return TKey scalar on success, or null on failure.
     */
    public function key() {}
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-covariant TIterator as Iterator<TKey, TValue>
 *
 * @template-implements OuterIterator<TKey, TValue>
 * @template-implements ArrayAccess<TKey, TValue>
 *
 * @template-extends IteratorIterator<TKey, TValue, TIterator>
 */
class CachingIterator extends IteratorIterator implements OuterIterator , ArrayAccess , Countable  {
    const CALL_TOSTRING = 1 ;
    const CATCH_GET_CHILD = 16 ;
    const TOSTRING_USE_KEY = 2 ;
    const TOSTRING_USE_CURRENT = 4 ;
    const TOSTRING_USE_INNER = 8 ;
    const FULL_CACHE = 256 ;

    /**
     * @param TIterator $iterator
     * @param int-mask-of<self::*> $flags
     */
    public function __construct(Iterator $iterator, int $flags = self::CALL_TOSTRING) {}

    /** @return bool */
    public function hasNext () {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}

    /**
     * @return array<array-key, TValue>
     */
    public function getCache() {}
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-covariant TIterator as Iterator<TKey, TValue>
 *
 * @template-implements OuterIterator<TKey, TValue>
 *
 * @template-extends FilterIterator<TKey, TValue, TIterator>
 */
class CallbackFilterIterator extends FilterIterator implements OuterIterator  {
    /**
     * @param TIterator $iterator
     * @param callable(TValue, TKey, TIterator): bool $callback
     */
    public function __construct(Iterator $iterator, callable $callback) {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 * @template-implements SeekableIterator<int, DirectoryIterator>
 */
class DirectoryIterator extends SplFileInfo implements SeekableIterator {

    public function __construct(string $path){}

    /**
     * @return self
     */
    public function current() {}
    /**
     * @return int|false
     * @psalm-ignore-falsable-return
     */
    public function key() {}

    /**
     * @return void
     */
    public function next(){}
    /**
     * @return void
     */
    public function rewind(){}

    /**
     * @param int $position
     */
    public function seek($position) {}

    /**
     * @return bool
     */
    public function valid(){}
}

/**
 * @template-implements Iterator<never, never>
 */
class EmptyIterator implements Iterator {
    /**
     * @return never
     */
    public function current() {}
    /**
     * @return never
     */
    public function key() {}
    /**
     * @return void
     */
    public function next() {}
    /**
     * @return void
     */
    public function rewind() {}

    /**
     * @return false
     */
    public function valid() {}
}

/**
 * @template-extends SeekableIterator<string, FilesystemIterator|SplFileInfo|string>
 */
class FilesystemIterator extends DirectoryIterator
{
    const CURRENT_AS_PATHNAME = 32;
    const CURRENT_AS_FILEINFO = 0;
    const CURRENT_AS_SELF = 16;
    const CURRENT_MODE_MASK = 240;
    const KEY_AS_PATHNAME = 0;
    const KEY_AS_FILENAME = 256;
    const FOLLOW_SYMLINKS = 512;
    const KEY_MODE_MASK = 3840;
    const NEW_CURRENT_AND_KEY = 256;
    const SKIP_DOTS = 4096;
    const UNIX_PATHS = 8192;

    /**
     * @param int-mask<self::CURRENT_AS_PATHNAME,self::CURRENT_AS_FILEINFO,self::CURRENT_AS_SELF,self::KEY_AS_PATHNAME,self::KEY_AS_FILENAME,self::FOLLOW_SYMLINKS,self::NEW_CURRENT_AND_KEY,self::SKIP_DOTS,self::UNIX_PATHS> $flags
     */
    public function __construct(string $path, int $flags = self::KEY_AS_PATHNAME|self::CURRENT_AS_FILEINFO|self::SKIP_DOTS) {}

    /**
     * @return FilesystemIterator|SplFileInfo|string|null
     * @psalm-ignore-nullable-return
     */
    public function current() {}
    /**
     * @return int-mask<self::CURRENT_AS_PATHNAME,self::CURRENT_AS_FILEINFO,self::CURRENT_AS_SELF,self::KEY_AS_PATHNAME,self::KEY_AS_FILENAME,self::FOLLOW_SYMLINKS,self::NEW_CURRENT_AND_KEY,self::SKIP_DOTS,self::UNIX_PATH>
     */
    public function getFlags() {}

    /**
     * @param int-mask<self::CURRENT_AS_PATHNAME,self::CURRENT_AS_FILEINFO,self::CURRENT_AS_SELF,self::KEY_AS_PATHNAME,self::KEY_AS_FILENAME,self::FOLLOW_SYMLINKS,self::NEW_CURRENT_AND_KEY,self::SKIP_DOTS,self::UNIX_PATH> $flags
     * @return void
     */
    public function setFlags($flags) {}
    /**
     * @return string|null
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}



/**
 * @template-extends SeekableIterator<string, GlobIterator|SplFileInfo|string>
 */
class GlobIterator extends FilesystemIterator implements Countable {
    /**
     * @return int
     */
    public function count() {}
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-covariant TIterator as Iterator<TKey, TValue>
 *
 * @template-extends IteratorIterator<TKey, TValue, TIterator>
 */
class InfiniteIterator extends IteratorIterator {
    /**
     * @param TIterator $iterator
     */
    public function __construct(Iterator $iterator) {}

    /**
     * @return TValue|null current value or null if iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-covariant TIterator as Iterator<TKey, TValue>
 *
 * @template-implements OuterIterator<TKey, TValue>
 *
 * @template-extends IteratorIterator<TKey, TValue, TIterator>
 */
class LimitIterator extends IteratorIterator implements OuterIterator {
    /**
     * @param TIterator $iterator
     */
    public function __construct(Iterator $iterator, int $offset = 0, int $limit = -1) {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}



/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template-covariant TIterator as Iterator<TKey, TValue>
 *
 * @template-extends IteratorIterator<TKey, TValue, TIterator>
 */
class NoRewindIterator extends IteratorIterator {
    /**
     * @param TIterator $iterator
     */
    public function __construct(Iterator $iterator) {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 *
 * @template-covariant TKey
 * @template-covariant TValue
 *
 * @template-implements Iterator<TKey, TValue>
 */
class MultipleIterator implements Iterator {
    const MIT_NEED_ANY = 0 ;
    const MIT_NEED_ALL = 1 ;
    const MIT_KEYS_NUMERIC = 0 ;
    const MIT_KEYS_ASSOC = 2 ;

    /**
     * @param int-mask-of<self::MIT_*> $flags
     */
    public function __construct (int $flags = 0) {}
    /**
     * @param Iterator<TKey,TValue> $iterator
     * @param string|int $infos
     * @return void
     */
    public function attachIterator(Iterator $iterator, $infos = '') {}
    /**
     * @param Iterator<TKey, TValue> $iterator
     * @return bool
     */
    public function containsIterator(Iterator $iterator) {}

    /**
     * @return int
     */
    public function countIterators() {}
    /**
     * nullable values are returned when MIT_NEED_ANY is set
     * and one of the iterators is already drained.
     * When MIT_NEED_ALL is set and one of the iterators
     * is already drained, `current()` throws
     *
     * @return array<array-key, TValue|null>
     */
    public function current() {}
    /**
     * @param Iterator<TKey,TValue> $iterator
     * @return void
     */
    public function detachIterator(Iterator $iterator) {}
    /**
     * @return int-mask-of<self::MIT_*>
     */
    public function getFlags() {}
    /**
     * @return array<array-key, TValue|null>
     */
    public function key() {}
    /**
     * @param int-mask-of<self::MIT_*> $flags
     * @return void
     */
    public function setFlags( int $flags ) {}
}

/**
 * @template TKey
 * @template TValue
 * @template TIterator as RecursiveIterator<TKey, TValue>
 *
 * @template-extends FilterIterator<TKey, TValue, TIterator>
 * @template-implements RecursiveIterator<TKey, TValue>
 */
abstract class RecursiveFilterIterator extends FilterIterator implements RecursiveIterator {

    /**
     * @param TIterator $iterator
     */
    public function __construct(RecursiveIterator $iterator) {}
    /**
     * @return TIterator
     */
    public function getChildren() {}

    /**
     * @return bool
     */
    public function hasChildren() {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 * @template TKey
 * @template TValue
 * @template TIterator as RecursiveIterator<TKey, TValue>
 *
 * @template-extends RecursiveFilterIterator<TKey, TValue, TIterator>
 */
class ParentIterator extends RecursiveFilterIterator implements RecursiveIterator, OuterIterator {

    /**
     * @return bool
     */
    public function accept() {}
    /**
     * @param TIterator $iterator
     */
    public function __construct(RecursiveIterator $iterator) {}
    /**
     * @return ParentIterator<TKey,TValue>
     */
    public function getChildren() {}

    /**
     * @return bool
     */
    public function hasChildren() {}
    /**
     * @return void
     */
    public function next() {}
    /**
     * @return void
     */
    public function rewind() {}

    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 * @template TKey
 * @template TValue
 *
 * @template-implements RecursiveIterator<TKey, TValue>
 * @template-extends ArrayIterator<TKey, TValue>
 */
class RecursiveArrayIterator extends ArrayIterator implements RecursiveIterator {
    const STD_PROP_LIST = 1 ;
    const ARRAY_AS_PROPS = 2 ;
    const CHILD_ARRAYS_ONLY = 4 ;

    /**
     * @return RecursiveArrayIterator<TKey, TValue>
     */
    public function getChildren() {}

    /**
     * @return bool
     */
    public function hasChildren() {}
    /**
     * @return TValue|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return TKey|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}

/**
 * @template TKey
 * @template TValue
 * @template TIterator as Iterator<TKey, TValue>
 *
 * @template-implements RecursiveIterator<TKey, TValue>
 * @template-extends CachingIterator<TKey, TValue, TIterator>
 */
class RecursiveCachingIterator extends CachingIterator implements RecursiveIterator {
    /**
     * @return RecursiveCachingIterator<TKey,TValue, TIterator>
     */
    public function getChildren() {}

    /**
     * @return bool
     */
    public function hasChildren() {}
}

/**
 * @template TKey
 * @template TValue
 * @template TIterator as RecursiveIterator<TKey, TValue>
 *
 * @template-implements RecursiveIterator<TKey, TValue>
 * @template-extends CallbackFilterIterator<TKey, TValue, TIterator>
 */
class RecursiveCallbackFilterIterator extends CallbackFilterIterator implements RecursiveIterator {

    /**
     * @param TIterator $iterator
     * @param callable(TValue, TKey, TIterator): bool $callback
     */
    public function __construct(RecursiveIterator $iterator, callable $callback) {}
    /**
     * @return RecursiveCallbackFilterIterator<TKey, TValue, TIterator>
     */
    public function getChildren() {}

    /**
     * @return bool
     */
    public function hasChildren() {}

    /**
     * @return TValue|null current value or null when iterator is drained
     */
    public function current() {}

    /**
     * @return TKey|null current value or null when iterator is drained
     */
    public function key() {}
}

/**
 * @template-implements RecursiveIterator<string, RecursiveDirectoryIterator|string|SplFileInfo>
 * @template-implements SeekableIterator<string, RecursiveDirectoryIterator|string|SplFileInfo>
 */
class RecursiveDirectoryIterator extends FilesystemIterator implements RecursiveIterator, SeekableIterator {

    const CURRENT_AS_PATHNAME = 32 ;
    const CURRENT_AS_FILEINFO = 0 ;
    const CURRENT_AS_SELF = 16 ;
    const CURRENT_MODE_MASK = 240 ;
    const KEY_AS_PATHNAME = 0 ;
    const KEY_AS_FILENAME = 256 ;
    const FOLLOW_SYMLINKS = 512 ;
    const KEY_MODE_MASK = 3840 ;
    const NEW_CURRENT_AND_KEY = 256 ;
    const SKIP_DOTS = 4096 ;
    const UNIX_PATHS = 8192 ;

    /**
     * @param string $path
     * @param int-mask<self::CURRENT_AS_PATHNAME,self::CURRENT_AS_FILEINFO,self::CURRENT_AS_SELF,self::KEY_AS_PATHNAME,self::KEY_AS_FILENAME,self::FOLLOW_SYMLINKS,self::NEW_CURRENT_AND_KEY,self::SKIP_DOTS,self::UNIX_PATHS> $flags
     */
    public function __construct(string $path, int $flags = self::KEY_AS_PATHNAME|self::CURRENT_AS_FILEINFO) {}

    /**
     * @return string
     */
    public function getSubPath() {}
    /**
     * @return string
     */
    public function getSubPathname() {}

    /**
     * @return RecursiveDirectoryIterator|string|SplFileInfo|null current value or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function current() {}

    /**
     * @return string|null current key or null when iterator is drained
     * @psalm-ignore-nullable-return
     */
    public function key() {}
}


/**
 * @template TIterator as RecursiveIterator|IteratorAggregate
 * @mixin TIterator
 */
class RecursiveIteratorIterator implements OuterIterator {
    /**
     * @param TIterator $iterator
     * @param int $mode
     * @param int $flags
     *
     * @return void
     */
    public function __construct($iterator, $mode = 0, $flags = 0) {}
}

/**
 * @template TKey
 * @template TValue
 * @template TIterator as RecursiveIterator<TKey, TValue>
 *
 * @template-implements RecursiveIterator<TKey, TValue>
 * @template-extends RegexIterator<TKey, TValue, TIterator>
 */
class RecursiveRegexIterator extends RegexIterator implements RecursiveIterator {

    const MATCH = 0 ;
    const GET_MATCH = 1 ;
    const ALL_MATCHES = 2 ;
    const SPLIT = 3 ;
    const REPLACE = 4 ;
    const USE_KEY = 1 ;

    /**
     * @param TIterator $iterator
     * @param string $regex
     * @param self::MATH|self::GET_MATCH|self::ALL_MATCHES|self::SPLIT|self::REPLACE $mode
     * @param self::USE_KEY|0 $flags
     * @param int $preg_flags
     */
    public function __construct(RecursiveIterator $iterator, string $regex, int $mode = self::MATCH, int $flags = 0, int $preg_flags = 0) {}

    /**
     * @return RecursiveRegexIterator<TKey, TValue>
     */
    public function getChildren() {}
}

/**
 * @template TKey
 * @template TValue
 *
 * @template-extends RecursiveIteratorIterator<TKey, TValue>
 * @template-implements OuterIterator<TKey, TValue>
 */
class RecursiveTreeIterator extends RecursiveIteratorIterator implements OuterIterator {

    const LEAVES_ONLY = 0 ;
    const SELF_FIRST = 1 ;
    const CHILD_FIRST = 2 ;
    const CATCH_GET_CHILD = 16 ;

    const BYPASS_CURRENT = 4 ;
    const BYPASS_KEY = 8 ;
    const PREFIX_LEFT = 0 ;
    const PREFIX_MID_HAS_NEXT = 1 ;
    const PREFIX_MID_LAST = 2 ;
    const PREFIX_END_HAS_NEXT = 3 ;
    const PREFIX_END_LAST = 4 ;
    const PREFIX_RIGHT = 5 ;

    /**
     * @return void
     */
    public function beginChildren() {}

    /**
     * @return RecursiveIterator
     */
    public function beginIteration() {}
    /**
     * @return RecursiveIterator
     */
    public function callGetChildren() {}
    /**
     * @return bool
     */
    public function callHasChildren() {}

    /**
     * @param RecursiveIterator<TKey, TValue>|IteratorAggregate<TKey, TValue> $it
     * @param int-mask<self::BYPASS_CURRENT, self::BYPASS_KEY> $flags
     * @param int-mask<self::CATCH_GET_CHILD> $cit_flags
     * @param self::LEAVES_ONLY|self::SELF_FIRST|self::CHILD_FIRST $mode
     */
    public function __construct($it, int $flags = self::BYPASS_KEY, int $cit_flags = self::CATCH_GET_CHILD, int $mode = self::SELF_FIRST) {}

    /**
     * @return string
     */
    public function current() {}
    /**
     * @return void
     */
    public function endChildren() {}
    /**
     * @return void
     */
    public function endIteration() {}

    /**
     * @return string
     */
    public function getEntry() {}
    /**
     * @return string
     */
    public function getPostfix() {}
    /**
     * @return string
     */
    public function getPrefix() {}
    /**
     * @return string
     */
    public function key() {}
    /**
     * @return void
     */
    public function next() {}
    /**
     * @return void
     */
    public function nextElement() {}
    /**
     * @return void
     */
    public function rewind() {}
    /**
     * @return void
     */
    public function setPostfix(string $postfix ) {}
    /**
     * @param self::PREFIX_* $part
     * @param string $value
     * @return void
     */
    public function setPrefixPart(int $part , string $value ) {}
    /**
     * @return bool
     */
    public function valid() {}
}

/**
 * @template TKey
 * @template TValue
 * @template TIterator as Iterator<TKey, TValue>
 *
 * @template-extends FilterIterator<TKey, TValue, TIterator>
 */
class RegexIterator extends FilterIterator {
    const MATCH = 0 ;
    const GET_MATCH = 1 ;
    const ALL_MATCHES = 2 ;
    const SPLIT = 3 ;
    const REPLACE = 4 ;
    const USE_KEY = 1 ;

    /**
     * @param TIterator $iterator
     * @param string $regex
     * @param self::MATCH|self::GET_MATCH|self::ALL_MATCHES|self::SPLIT|self::REPLACE $mode
     * @param int-mask<self::USE_KEY> $flags
     * @param int $preg_flags
     */
    public function __construct(Iterator $iterator, string $regex, int $mode = self::MATCH, int $flags = 0, int $preg_flags = 0) {}
    /**
     * @return TValue Can return any type.
     */
    public function current() {}

    /**
     * @return TKey scalar on success, or null on failure.
     */
    public function key() {}
}
<?php
/**
 * @psalm-template TArray as array
 *
 * @param TArray $array
 * @param mixed $search_value
 * @param bool  $strict
 *
 * @return (TArray is non-empty-array ? non-empty-list<key-of<TArray>> : list<key-of<TArray>>)
 * @psalm-pure
 */
function array_keys(array $array, $search_value = null, bool $strict = false)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> $array
 * @param array ...$arrays
 *
 * @return array<TKey, TValue>
 * @psalm-pure
 */
function array_intersect(array $array, array ...$arrays)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> $array
 * @param array ...$arrays
 *
 * @return array<TKey, TValue>
 * @psalm-pure
 */
function array_intersect_key(array $array, array ...$arrays)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> $array
 * @param array ...$arrays
 *
 * @return array<TKey, TValue>
 * @psalm-pure
 */
function array_intersect_assoc(array $array, array ...$arrays)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<mixed, TKey> $keys
 * @param array<mixed, TValue> $values
 *
 * @return (
 *     PHP_MAJOR_VERSION is 8 ?
 *         ($keys is non-empty-array ? non-empty-array<TKey, TValue> : array<TKey, TValue>) :
 *         ($keys is non-empty-array ? non-empty-array<TKey, TValue>|false : array<TKey, TValue>|false)
 * )
 * @psalm-ignore-falsable-return
 * @psalm-pure
 */
function array_combine(array $keys, array $values)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> $array
 * @param array ...$arrays
 *
 * @return array<TKey, TValue>
 * @psalm-pure
 */
function array_diff(array $array, array ...$arrays)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> $array
 * @param array ...$arrays
 *
 * @return array<TKey, TValue>
 * @psalm-pure
 */
function array_diff_key(array $array, array ...$arrays)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> $array
 * @param array ...$arrays
 *
 * @return array<TKey, TValue>
 * @psalm-pure
 */
function array_diff_assoc(array $array, array ...$arrays)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> $array
 *
 * @return array<TValue, TKey>
 * @psalm-pure
 */
function array_flip(array $array)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TArray as array<TKey, mixed>
 *
 * @param TArray $array
 *
 * @return (TArray is array<never, never> ? null : (TArray is non-empty-list ? int<0,max> : (TArray is non-empty-array ? TKey : TKey|null)))
 * @psalm-pure
 * @psalm-ignore-nullable-return
 */
function key($array)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 * @psalm-template TArray as array<TKey, TValue>
 *
 * @param TArray $array
 *
 * @return (TArray is array<never, never> ? false : (TArray is non-empty-array ? TValue : TValue|false))
 * @psalm-pure
 */
function current($array)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 * @psalm-template TArray as array<TKey, TValue>
 *
 * @param TArray $array
 *
 * @return (TArray is array<never, never> ? false : (TArray is non-empty-array ? TValue : TValue|false))
 */
function reset(&$array)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 * @psalm-template TArray as array<TKey, TValue>
 *
 * @param TArray $array
 *
 * @return (TArray is array<never, never> ? false : (TArray is non-empty-array ? TValue : TValue|false))
 */
function end(&$array)
{
}

/**
 * @psalm-template TKey as array-key
 * @psalm-template TArray as array<TKey, mixed>
 *
 * @param TArray $array
 *
 * @return (TArray is array<never, never> ? null : (TArray is non-empty-array ? key-of<TArray> : key-of<TArray>|null))
 * @psalm-pure
 */
function array_key_first($array)
{
}

/**
 * @psalm-template TArray as array
 *
 * @param TArray $array
 *
 * @return (TArray is array<never, never> ? null : (TArray is non-empty-array ? key-of<TArray> : key-of<TArray>|null))
 * @psalm-pure
 */
function array_key_last($array)
{
}

/**
 * @psalm-template TArray as array
 *
 * @param TArray $array
 *
 * @return (TArray is non-empty-array ? non-empty-list<value-of<TArray>> : list<value-of<TArray>>)
 * @psalm-pure
 */
function array_values($array)
{
}

/**
 * @psalm-template T
 *
 * @param mixed           $needle
 * @param array<T, mixed> $haystack
 * @param bool            $strict
 *
 * @return T|false
 * @psalm-pure
 */
function array_search($needle, array $haystack, bool $strict = false)
{
}

/**
 * @psalm-template T
 * @psalm-template TArray as array<T>
 *
 * @param TArray $array
 * @param-out (TArray is non-empty-array ? non-empty-list<T> : list<T>) $array
 */
function shuffle(array &$array): bool
{
}

/**
 * @psalm-template T
 * @psalm-template TArray as array<T>
 *
 * @param TArray $array
 * @param-out (TArray is non-empty-array ? non-empty-list<T> : list<T>) $array
 */
function sort(array &$array, int $flags = SORT_REGULAR): bool
{
}

/**
 * @psalm-template T
 * @psalm-template TArray as array<T>
 *
 * @param TArray $array
 * @param-out (TArray is non-empty-array ? non-empty-list<T> : list<T>) $array
 */
function rsort(array &$array, int $flags = SORT_REGULAR): bool
{
}

/**
 * @psalm-template T
 * @psalm-template TArray as array<T>
 *
 * @param TArray $array
 * @param callable(T,T):int $callback
 * @param-out (TArray is non-empty-array ? non-empty-list<T> : list<T>) $array
 */
function usort(array &$array, callable $callback): bool
{
}

/**
 * @psalm-template TKey
 * @psalm-template T
 * @psalm-template TArray as array<TKey,T>
 *
 * @param TArray $array
 * @param callable(T,T):int $callback
 * @param-out (TArray is non-empty-array ? non-empty-array<TKey,T> : array<TKey,T>) $array
 */
function uasort(array &$array, callable $callback): bool
{
}

/**
 * @psalm-template TKey
 * @psalm-template T
 * @psalm-template TArray as array<TKey,T>
 *
 * @param TArray $array
 * @param callable(TKey,TKey):int $callback
 * @param-out (TArray is non-empty-array ? non-empty-array<TKey,T> : array<TKey,T>) $array
 */
function uksort(array &$array, callable $callback): bool
{
}

/**
 * @psalm-pure
 *
 * @psalm-template K of array-key
 * @psalm-template T
 *
 * @param array<K,T> $array
 *
 * @return array<K,T>
 */
function array_change_key_case(array $array, int $case = CASE_LOWER)
{
}

/**
 * @psalm-pure
 *
 * @psalm-template TKey as array-key
 *
 * @param TKey $key
 * @param array<TKey, mixed> $array
 *
 * @return bool
 */
function array_key_exists($key, array $array) : bool
{
}

/**
 * @psalm-pure
 *
 * @no-named-arguments
 *
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> ...$arrays
 *
 * @return array<TKey, TValue>
 */
function array_merge_recursive(array ...$arrays)
{
}

/**
 * @psalm-pure
 * 
 * @no-named-arguments
 *
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey, TValue> ...$arrays
 *
 * @return array<TKey, TValue>
 */
function array_merge(array ...$arrays)
{
}

/**
 * @psalm-pure
 *
 * @psalm-template TKey as array-key
 * @psalm-template TValue
 *
 * @param array<TKey> $keys
 * @param TValue $value
 *
 * @return array<TKey, TValue>
 */
function array_fill_keys(array $keys, $value): array
{
}

/**
 * @psalm-pure
 *
 * @psalm-template TKey
 *
 * @param string $pattern
 * @param array<TKey,string> $array
 * @param 0|1 $flags 1=PREG_GREP_INVERT
 * @return array<TKey,string>
 */
function preg_grep($pattern, array $array, $flags = 0)
{
}

/**
 * @param resource $stream
 * @param-out closed-resource $stream
 */
function fclose(&$stream) : bool
{
}

/**
 * @psalm-pure
 * @template T as string
 * @param T $string
 * @return (T is non-empty-string ? non-empty-string : string)
 */
function sodium_bin2base64(string $string, int $id): string

/**
 * @psalm-pure
 * @template T as string
 * @param T $string
 * @return (T is non-empty-string ? non-empty-string : string)
 */
function sodium_bin2hex(string $string): string {}

/**
 * @param string $string
 * @param-out null $string
 */
function sodium_memzero(string &$string): void
{
}

/**
 * @param mixed $value
 * @param bool $return
 * @return ($return is true ? string : void)
 *
 * @psalm-taint-specialize
 * @psalm-flow ($value) -> return
 * @psalm-taint-sink html $value
 */
function var_export($value, bool $return = false) {}

/**
 * @param mixed $value
 * @param list<mixed> $values
 * @return string
 *
 * @psalm-taint-specialize
 * @psalm-flow ($value, $values) -> return
 * @psalm-taint-sink html $value
 * @psalm-taint-sink html $values
 */
function var_dump($value, ...$values) {}

/**
 * @param mixed $value
 * @param bool $return
 * @return ($return is true ? string : true)
 *
 * @psalm-taint-specialize
 * @psalm-flow ($value) -> return
 * @psalm-taint-sink html $value
 */
function print_r($value, bool $return = false) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-sink file $filename
 * @param mixed $filename
 * @return ($return is true ? string : bool)
 */
function highlight_file($filename, bool $return = false) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-sink file $filename
 * @param mixed $filename
 * @return ($return is true ? string : bool)
 */
function show_source($filename, bool $return = false) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-sink file $filename
 */
function php_strip_whitespace(string $filename) : string {}

/**
 * @psalm-pure
 *
 * @param mixed $string
 * @return ($return is true ? string : bool)
 *
 * @psalm-flow ($string) -> return
 */
function highlight_string($string, bool $return = false) {}

/**
 * @psalm-pure
 *
 * @return ($as_float is true ? float : string)
 */
function microtime(bool $as_float = false) {}

/**
 * @psalm-pure
 *
 * @return ($as_float is true ? float : array<string, int>)
 */
function gettimeofday(bool $as_float = false) {}

/**
 * @psalm-pure
 *
 * @param numeric $num
 * @return ($num is int ? positive-int|0 : ($num is float ? float : positive-int|0|float))
 */
function abs($num) {}

/**
 * @psalm-pure
 *
 * @template T as string|int|float
 * @template TStep as int|float
 * @param T $start
 * @param T $end
 * @param TStep $step
 * @return (
 *     T is int
 *     ? (TStep is int ? non-empty-list<int> : non-empty-list<float>)
 *     : (
 *         T is float
 *         ? non-empty-list<float>
 *         : (
 *              T is string
 *              ? non-empty-list<string>
 *              : (
 *                   T is int|float
 *                   ? non-empty-list<int|float>
 *                   : non-empty-list<int|float|string>
 *              )
 *         )
 *     )
 * )
 */
function range($start, $end, $step = 1) {}

/**
 * @psalm-pure
 *
 * @return (
 *     $format is 'd'|'j'|'N'|'w'|'z'|'W'|'m'|'n'|'t'|'L'|'o'|'Y'|'y'|'B'|'g'|'G'|'h'|'H'|'i'|'s'|'u'|'v'|'Z'|'U'|'I'
 *     ? numeric-string
 *     : ($timestamp is numeric ? string : string|false)
 * )
 */
function date(string $format, int $timestamp = 0) {}

/**
 * @psalm-pure
 *
 * @param mixed $vars
 * @param-out string|int|float|null $vars
 * @psalm-flow ($string, $format) -> return
 * @return (func_num_args() is 2 ? (null|list<float|int|string|null>) : int)
 */
function sscanf(string $string, string $format, &...$vars) {}

/**
 * @psalm-pure
 *
 * @return (
 *     func_num_args() is 1
 *     ? array{dirname: string, basename: string, extension?: string, filename: string}
 *     : string
 * )
 */
function pathinfo(string $path, int $flags = \PATHINFO_DIRNAME) {}

/**
 * @psalm-pure
 *
 * @return (func_num_args() is 0 ? array<string, string> : string|false)
 */
function getenv(string $varname = '', bool $local_only = false) {}

/**
 * @psalm-pure
 *
 * @return (
 *     $string is non-empty-string ? non-empty-lowercase-string : lowercase-string
 * )
 *
 * @psalm-flow ($string) -> return
 */
function strtolower(string $string) : string {}

/**
 * @psalm-pure
 *
 * @return (
 *     $string is non-falsy-string
 *     ? non-falsy-string
 *     : ($string is non-empty-string ? non-empty-string : string)
 * )
 *
 * @psalm-flow ($string) -> return
 */
function strtoupper(string $string) : string {}

/**
 * @psalm-pure
 *
 * @param string|array<string> $string
 * @param string|array<string> $replace
 * @param int|array<int> $offset
 * @param null|int|array<int> $length
 *
 * @return ($string is array<string> ? array<string> : string)
 *
 * @psalm-flow ($string, $replace) -> return
 */
function substr_replace($string, $replace, $offset, $length = null) {}

/**
 * @psalm-pure
 *
 * @param string $haystack
 *
 * @psalm-return positive-int|0|false
 */
function strpos($haystack, $needle, int $offset = 0) : int {}

/**
 * @psalm-pure
 *
 * @return (
 *      $string is class-string
 *          ? ($characters is '\\' ? class-string : string)
 *          : ($string is lowercase-string ? lowercase-string : string)
 * )
 *
 * @psalm-flow ($string) -> return
 */
function trim(string $string, string $characters = " \t\n\r\0\x0B") : string {}

/**
 * @psalm-pure
 *
 * @return (
 *      $string is class-string
 *          ? ($characters is '\\' ? class-string : string)
 *          : ($string is lowercase-string ? lowercase-string : string)
 * )
 *
 * @psalm-flow ($string) -> return
 */
function ltrim(string $string, string $characters = " \t\n\r\0\x0B") : string {}

/**
 * @psalm-pure
 *
 * @return ($string is lowercase-string ? lowercase-string : string)
 *
 * @psalm-flow ($string) -> return
 */
function rtrim(string $string, string $characters = " \t\n\r\0\x0B") : string {}

/**
 * @psalm-pure
 *
 * @param string|array $separator
 * @param array<string|float|int|stringable-object|null|bool> $array
 *
 * @return (
 *     $separator is non-empty-string
 *     ? ($array is non-empty-array
 *         ? ($array is array<literal-string|literal-int>
 *             ? ($separator is literal-string ? non-empty-literal-string : non-empty-string)
 *             : non-empty-string
 *         )
 *         : string)
 *     : ($array is non-empty-array
 *         ? ($array is array<non-empty-literal-string|non-empty-string>
 *             ? ($array is array<non-empty-literal-string> ? non-empty-literal-string : non-empty-string)
 *             : string
 *         )
 *         : string)
 * )
 *
 * @psalm-flow ($separator) -> return
 * @psalm-flow ($array) -(array-fetch)-> return
 */
function implode($separator, array $array = []) : string {}

/**
 * @psalm-pure
 *
 * @param string|array $separator
 * @param array<string|float|int|stringable-object|null|bool> $array
 *
 * @return (
 *     $separator is non-empty-string
 *     ? ($array is non-empty-array
 *         ? ($array is array<literal-string|literal-int>
 *             ? ($separator is literal-string ? non-empty-literal-string : non-empty-string)
 *             : non-empty-string
 *         )
 *         : string)
 *     : ($array is non-empty-array
 *         ? ($array is array<non-empty-literal-string|non-empty-string>
 *             ? ($array is array<non-empty-literal-string> ? non-empty-literal-string : non-empty-string)
 *             : string
 *         )
 *         : string)
 * )
 *
 * @psalm-flow ($separator) -> return
 * @psalm-flow ($array) -(array-fetch)-> return
 */
function join($separator, array $array = []): string
{
}

/**
 * @psalm-pure
 *
 * @param non-empty-string $separator
 *
 * @return (
 *     $string is lowercase-string
 *         ? (
 *             $limit is int<min, -2>
 *                 ? list<empty>
 *                 : (
 *                     $limit is int<0, 1>
 *                         ? list{lowercase-string}
 *                         : (
 *                             $limit is 2
 *                                 ? list{0: lowercase-string, 1?: lowercase-string}
 *                                 : (
 *                                     $limit is 3
 *                                         ? list{0: lowercase-string, 1?: lowercase-string, 2?: lowercase-string}
 *                                         : non-empty-list<lowercase-string>
 *                                 )
 *                         )
 *                 )
 *         )
 *         : (
 *             $limit is int<min, -2>
 *                 ? list<empty>
 *                 : (
 *                     $limit is int<0, 1>
 *                         ? list{string}
 *                         : (
 *                             $limit is 2
 *                                 ? list{0: string, 1?: string}
 *                                 : (
 *                                     $limit is 3
 *                                         ? list{0: string, 1?: string, 2?: string}
 *                                         : non-empty-list<string>
 *                                 )
 *                         )
 *                 )
 *         )
 * )
 *
 * @psalm-flow ($string) -(array-assignment)-> return
 */
function explode(string $separator, string $string, int $limit = -1) : array {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($subject) -(array-assignment)-> return
 *
 * @template TFlags as int-mask<0, 1, 2, 4>
 *
 * @param TFlags $flags
 *
 * @return (TFlags is 0|2 ? non-empty-list<string>|false : (TFlags is 1|3 ? list<string>|false : list<array{string,int}>|false))
 *
 * @psalm-ignore-falsable-return
 */
function preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0) {}

/**
 * @param array $array
 *
 * @return (
 *     $array is array<int>
 *     ? int
 *     : ($array is array<float>
 *         ? float
 *         : float|int
 *     )
 * )
 */
function array_sum(array $array) {}

/**
 * @param array $array
 *
 * @return (
 *     $array is array<int>
 *     ? int
 *     : ($array is array<float>
 *         ? float
 *         : float|int
 *     )
 * )
 */
function array_product(array $array) {}

/**
 * 257 is FILTER_VALIDATE_INT
 * @psalm-taint-escape ($filter is 257 ? 'html' : null)
 *
 * 258 is FILTER_VALIDATE_BOOLEAN
 * @psalm-taint-escape ($filter is 258 ? 'html' : null)
 *
 * 259 is FILTER_VALIDATE_FLOAT
 * @psalm-taint-escape ($filter is 259 ? 'html' : null)
 *
 * 519 is FILTER_SANITIZE_NUMBER_INT
 * @psalm-taint-escape ($filter is 519 ? 'html' : null)
 *
 * 520 is FILTER_SANITIZE_NUMBER_FLOAT
 * @psalm-taint-escape ($filter is 520 ? 'html' : null)
 *
 * @psalm-flow ($value, $filter, $options) -> return
 */
function filter_var(mixed $value, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape html
 * @psalm-flow ($string) -> return
 */
function strip_tags(string $string, ?string $allowed_tags = null) : string {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function stripcslashes(string $string) : string {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function stripslashes(string $string) : string {}

/**
 * @psalm-pure
 *
 * Tainting is handled in a plugin
 *
 * @psalm-flow ($string) -> return
 */
function htmlentities(string $string, ?int $flags = null, ?string $encoding = null, bool $double_encode = true) : string {}

/**
 * @psalm-pure
 *
 * Tainting is handled in a plugin
 *
 * @psalm-flow ($string) -> return
 */
function html_entity_decode(string $string, ?int $flags = null, ?string $encoding = null) : string {}

/**
 * @psalm-pure
 *
 * Tainting is handled in a plugin
 *
 * @psalm-flow ($string) -> return
 * @psalm-return (
 *     $string is non-empty-string
 *     ? non-empty-string
 *     : string
 * )
 */
function htmlspecialchars(string $string, int $flags = ENT_COMPAT | ENT_HTML401, ?string $encoding = 'UTF-8', bool $double_encode = true) : string {}

/**
 * @psalm-pure
 *
 * Tainting is handled in a plugin
 *
 * @psalm-flow ($string) -> return
 */
function htmlspecialchars_decode(string $string, ?int $flags = null) : string {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape html
 * @psalm-taint-escape has_quotes
 * @psalm-flow ($string) -> return
 */
function urlencode(string $string) : string {}

/**
 * @psalm-pure
 *
 * @psalm-return (
 *     $string is ''
 *     ? 0
 *     : (
 *          $string is non-empty-string
 *              ? positive-int
 *              : (0|positive-int)
 *     )
 * )
 */
function strlen(string $string) : int {}

/**
 * @psalm-pure
 *
 * @param string|array<string|int|float> $search
 * @param string|array<string|int|float> $replace
 * @param string|array<string|int|float> $subject
 * @param int $count
 * @return ($subject is array ? array<string> : string)
 *
 * @psalm-flow ($replace, $subject) -> return
 */
function str_replace($search, $replace, $subject, &$count = null) {}

/**
 * @psalm-pure
 *
 * @param string|array<string|int|float> $search
 * @param string|array<string|int|float> $replace
 * @param string|array<string|int|float> $subject
 * @param int $count
 * @return ($subject is array ? array<string> : string)
 *
 * @psalm-flow ($replace, $subject) -> return
 */
function str_ireplace($search, $replace, $subject, &$count = null) {}

/**
 * @psalm-pure
 *
 * @return ($string is non-empty-string ? non-empty-string : ($length is positive-int ? non-empty-string: string))
 *
 * @psalm-flow ($string, $pad_string) -> return
 */
function str_pad(string $string, int $length, $pad_string = '', int $pad_type = STR_PAD_RIGHT): string {}

/**
 * @psalm-pure
 *
 * @todo update $times to be `0|positive-int`
 * @return (
 *      $string is non-empty-string
 *      ? (
 *          $times is positive-int
 *          ? non-empty-string
 *          : ($times is 0 ? '' : string)
 *      )
 *      : ($times is 0 ? '' : string)
 * )
 *
 * @psalm-flow ($string) -> return
 */
function str_repeat(string $string, int $times): string {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function str_rot13(string $string): string {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function str_shuffle(string $string): string {}

/**
 * @psalm-pure
 * @return ($length is positive-int ? list<string> : false)
 *
 * @psalm-flow ($string) -> return
 */
function str_split(string $string, int $length = 1) {}

/**
 * @psalm-pure
 * @return string|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($haystack) -> return
 */
function strstr(string $haystack, string $needle, bool $before_needle = false) {}

/**
 * @psalm-pure
 * @return string|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($haystack) -> return
 */
function stristr(string $haystack, string $needle, bool $before_needle = false) {}

/**
 * @psalm-pure
 * @return string|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($haystack) -> return
 */
function strchr(string $haystack, string $needle, bool $before_needle = false) {}

/**
 * @psalm-pure
 * @return string|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($string) -> return
 */
function strpbrk(string $string, string $characters) {}

/**
 * @psalm-pure
 * @return string|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($haystack) -> return
 */
function strrchr(string $haystack, string $needle) {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function strrev(string $string): string {}

/**
 * @psalm-pure
 *
 * @param 0|1|2 $format
 * @return (
 *     $format is 0 ?
 *     int :
 *     (
 *         $format is 1 ?
 *         list<string> :
 *         array<int, string>
 *     )
 * )
 */
function str_word_count(string $string, int $format = 0, string|null $characters = null) {}

/**
 * @psalm-pure
 *
 * @param string|string[] $pattern
 * @param string|array<string|int|float> $replacement
 * @param string|array<string|int|float> $subject
 * @param int $count
 * @return ($subject is array ? array<string> : string|null)
 *
 * @psalm-flow ($replacement, $subject) -> return
 */
function preg_filter($pattern, $replacement, $subject, int $limit = -1, &$count = null) {}

/**
 * @psalm-pure
 *
 * @param string|string[] $pattern
 * @param string|array<string|int|float> $replacement
 * @param string|array<string|int|float> $subject
 * @param int $count
 * @return ($subject is array ? array<string>|null : string|null)
 *
 * @psalm-flow ($replacement, $subject) -> return
 */
function preg_replace($pattern, $replacement, $subject, int $limit = -1, &$count = null) {}

/**
 * @param string|string[] $pattern
 * @param callable(string[]):string $callback
 * @param string|array<string|int|float> $subject
 * @param int $count
 * @return ($subject is array ? array<string>|null : string|null)
 *
 * @psalm-taint-specialize
 * @psalm-flow ($subject) -> return
 */
function preg_replace_callback($pattern, $callback, $subject, int $limit = -1, &$count = null, int $flags = 0) {}

/**
 * @psalm-pure
 * @template TFlags as int
 *
 * @param string $pattern
 * @param string $subject
 * @param mixed $matches
 * @param TFlags $flags
 * @param-out (
 *          TFlags is 1
 *          ? array<list<string>>
 *          : (TFlags is 2
 *              ? list<array<string>>
 *              : (TFlags is 256|257
 *                  ? array<list<array{string, int}>>
 *                  : (TFlags is 258
 *                      ? list<array<array{string, int}>>
 *                      : (TFlags is 512|513
 *                          ? array<list<?string>>
 *                          : (TFlags is 514
 *                              ? list<array<?string>>
 *                              : (TFlags is 770
 *                                  ? list<array<array{?string, int}>>
 *                                  : array
 *                              )
 *                          )
 *                      )
 *                  )
 *              )
 *          )
 *        ) $matches
 * @return int|false
 * @psalm-ignore-falsable-return
 */
function preg_match_all($pattern, $subject, &$matches = [], int $flags = 1, int $offset = 0) {}

/**
 * @psalm-pure
 * @template TFlags as int-mask<0, 256, 512>
 *
 * @param string $pattern
 * @param string $subject
 * @param mixed $matches
 * @param TFlags $flags
 * @param-out (TFlags is 256 ? array<array-key, array{string, 0|positive-int}|array{'', -1}> :
 *             TFlags is 512 ? array<array-key, string|null> :
 *             TFlags is 768 ? array<array-key, array{string, 0|positive-int}|array{null, -1}> :
 *                             array<array-key, string>
 *            ) $matches
 * @return 1|0|false
 * @psalm-ignore-falsable-return
 */
function preg_match($pattern, $subject, &$matches = [], int $flags = 0, int $offset = 0) {}

/**
 * @psalm-pure
 *
 * @return (PHP_MAJOR_VERSION is 5|7 ? string|false : string)
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($string) -> return
 */
function substr(string $string, int $offset, ?int $length = null) {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($str) -> return
 */
function preg_quote(string $str, ?string $delimiter = null) : string {}

/**
 * @psalm-pure
 *
 * @param string|int|float $values
 * @return ($format is non-empty-string
 *      ? ($values is non-empty-string|int|float ? non-empty-string : string)
 *      : string)
 *
 * @psalm-flow ($format, $values) -> return
 */
function sprintf(string $format, ...$values) : string {}

/**
 * @psalm-pure
 * @return string|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($format, $values) -> return
 */
function vsprintf(string $format, array $values) {}

/**
 * @psalm-pure
 * @return string
 *
 * @psalm-flow ($string) -> return
 */
function wordwrap(string $string, int $width = 75, string $break = "\n", bool $cut_long_words = false) : string {}

/**
 * @psalm-pure
 *
 * @param string|int|float $values
 *
 * @psalm-taint-specialize
 * @psalm-flow ($format, $values) -> return
 * @psalm-taint-sink html $format
 * @psalm-taint-sink html $values
 */
function printf(string $format, ...$values) : string {}

/**
 * @psalm-taint-specialize
 * @psalm-taint-sink html $format
 * @psalm-taint-sink html $values
 */
function vprintf(string $format, array $values) : int {}

/**
 * @psalm-pure
 *
 * @return string|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($path) -> return
 */
function realpath(string $path) {}

/**
 * @psalm-pure
 *
 * @param numeric-string $num1
 * @param numeric-string $num2
 * @return (PHP_MAJOR_VERSION is 8 ? numeric-string : ($num2 is "0" ? null : numeric-string))
 */
function bcdiv(string $num1, string $num2, int $scale = 0): ?string {}

/**
 * @psalm-pure
 *
 * @param scalar|null|object $value
 * @return string The string value of var.
 *
 * @psalm-flow ($value) -> return
 */
function strval ($value): string {}

/**
 * @return ($string is non-empty-string ? non-empty-list<string> : non-empty-list<string>|array{null})
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function str_getcsv(string $string, string $separator = ',', string $enclosure = '"', string $escape = '\\\\')
{
}

/**
 * @template TKey as array-key
 * @template TArray as array<mixed, TKey>
 *
 * @param TArray $array
 *
 * @return (TArray is non-empty-array ? non-empty-array<TKey, positive-int> : array<TKey, positive-int>)
 *
 * @psalm-pure
 */
function array_count_values(array $array): array {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function addcslashes(string $string, string $characters) : string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function addslashes(string $string): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function ucfirst(string $string): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string, $separators) -> return
 */
function ucwords (string $string, string $separators = " \t\r\n\f\v"): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function lcfirst(string $string): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function nl2br(string $string, bool $use_xhtml = false): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function quoted_printable_decode(string $string): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function quoted_printable_encode(string $string): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function quotemeta(string $string): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function chop(string $string, string $characters = " \t\n\r\0\x0B"): string
{
}

/**
 * @psalm-pure
 * @psalm-flow ($string, $separator) -> return
 */
function chunk_split(string $string, int $length = 76, string $separator= ''): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function convert_uudecode(string $string): string
{
}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 */
function convert_uuencode(string $string) : string
{
}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape ldap
 * @psalm-flow ($value) -> return
 */
function ldap_escape(string $value, string $ignore = "", int $flags = 0) : string {}

/**
 * @psalm-pure
 *
 * @return mixed
 * @psalm-flow ($json) -> return
 */
function json_decode(string $json, ?bool $associative = null, int $depth = 512, int $flags = 0) {}

/**
 * @psalm-pure
 *
 * @return ($flags is 4194304 ? non-empty-string : non-empty-string|false)
 *
 * @psalm-flow ($value) -> return
 * @psalm-ignore-falsable-return
 */
function json_encode(mixed $value, int $flags = 0, int $depth = 512) {}

/**
 * @psalm-pure
 *
 * @return string|false
 *
 * @psalm-flow ($values) -> return
 * @psalm-ignore-falsable-return
 */
function pack(string $format, mixed ...$values) {}

/**
 * @psalm-pure
 *
 * @param string|int $in_codepage
 * @param string|int $out_codepage
 * @psalm-flow ($subject) -> return
 */
function sapi_windows_cp_conv($in_codepage, $out_codepage, string $subject) : ?string {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($prefix) -> return
 */
function uniqid(string $prefix = "", bool $more_entropy = false) : string {}

/**
 * @psalm-pure
 *
 * @return array|false
 * @psalm-ignore-falsable-return
 *
 * @psalm-flow ($string) -> return
 */
function unpack(string $format, string $string, int $offset = 0) {}

/**
 * @psalm-pure
 *
 * @return string|false
 *
 * @psalm-flow ($string) -> return
 * @psalm-ignore-falsable-return
 */
function base64_decode(string $string, bool $strict = false) {}

/**
 * @psalm-pure
 *
 * @psalm-flow ($string) -> return
 * @template T as string
 * @param T $string
 * @return (T is non-empty-string ? non-empty-string : string)
 */
function base64_encode(string $string) : string {}

/**
 * @psalm-pure
 *
 * @template T as string
 * @param T $string
 * @return (T is non-empty-string ? non-empty-string : string)
 */
function bin2hex(string $string): string {}

/**
 * @psalm-pure
 *
 * @param resource|null $context
 *
 * @return ($associative is false|0 ? list<string> : array<string, string|list<string>>)|false
 *
 * @psalm-taint-sink ssrf $url
 */
function get_headers(string $url, int $associative = 0, $context = null) : array|false {}

/**
 * @psalm-pure
 *
 * @return array<lowercase-string, string>|false
 *
 * @psalm-taint-sink ssrf $filename
 */
function get_meta_tags(string $filename, bool $use_include_path = false) : array|false {}

/**
 * @return ($categorize is false ? array<string,int|string|float|bool|null|array|resource> : array<string, array<string,int|string|float|bool|null|array|resource>>)
 */
function get_defined_constants(bool $categorize = false): array {}

/**
 * @param mixed $object_or_class
 * @param class-string $class
 * @param bool $allow_string
 * @return ($allow_string is false ? ($object_or_class is object ? bool : false) : bool)
 */
function is_a($object_or_class, string $class, $allow_string = false): bool{}

/**
 * @template T of array|string
 * @param T $string
 * @return (T is array<int, string> ? array<int, string> : T is array ? array : string|false)
 * @psalm-ignore-falsable-return
 */
function mb_convert_encoding(array|string $string, string $to_encoding, array|string|null $from_encoding = null): array|string|false{}

/**
 * @template TRead of null|array<array-key, resource>
 * @template TWrite of null|array<array-key, resource>
 * @template TExcept of null|array<array-key, resource>
 * @param TRead $read
 * @param TWrite $write
 * @param TExcept $except
 * @return false|int<0, max>
 * @param-out (TRead is null ? null : array<array-key, resource>) $read
 * @param-out (TWrite is null ? null : array<array-key, resource>) $write
 * @param-out (TExcept is null ? null : array<array-key, resource>) $except
 * @psalm-suppress ReferenceConstraintViolation
 */
function stream_select(null|array &$read, null|array &$write, null|array &$except, null|int $seconds, null|int $microseconds = null) : bool|int {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string) -> return
 */
function mysqli_escape_string($string) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string) -> return
 */
function mysqli_real_escape_string($string) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string) -> return
 */
function db2_escape_string($string) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string) -> return
 */
function cubrid_real_escape_string($string) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string1, $string2) -> return
 */
function pg_escape_bytea($string1, $string2 = null) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string1, $string2) -> return
 */
function pg_escape_identifier($string1, $string2 = null) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string1, $string2) -> return
 */
function pg_escape_literal($string1, $string2 = null) {}

/**
 * @psalm-pure
 *
 * @psalm-taint-escape sql
 * @psalm-flow ($string1, $string2) -> return
 */
function pg_escape_string($string1, $string2 = null) {}
<?php

/**
 * Interface to detect if a class is traversable using &foreach;.
 * @link http://php.net/manual/en/class.traversable.php
 *
 * @template-covariant TKey
 * @template-covariant TValue
 */
interface Traversable {
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @template TSend
 * @template-covariant TReturn
 *
 * @template-implements Traversable<TKey, TValue>
 */
class Generator implements Traversable {
    /**
     * @psalm-ignore-nullable-return
     * @return ?TValue Can return any type.
     */
    public function current() {}

    /**
     * @return void Any returned value is ignored.
     */
    public function next() {}

    /**
     * @return TKey scalar on success, or null on failure.
     */
    public function key() {}

    /**
     * @return bool The return value will be casted to boolean and then evaluated.
     */
    public function valid() {}

    /**
     * @return void Any returned value is ignored.
     */
    public function rewind() {}

    /**
     * @return TReturn Can return any type.
     */
    public function getReturn() {}

    /**
     * @param TSend $value
     * @psalm-ignore-nullable-return
     * @return ?TValue Can return any type.
     */
    public function send($value) {}

    /**
     * @psalm-ignore-nullable-return
     * @return ?TValue Can return any type.
     */
    public function throw(Throwable $exception) {}
}

/**
 * Interface to provide accessing objects as arrays.
 * @link http://php.net/manual/en/class.arrayaccess.php
 *
 * @template TKey
 * @template TValue
 */
interface ArrayAccess {

    /**
     * Whether a offset exists
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
     *
     * @param TKey $offset An offset to check for.
     * @return bool true on success or false on failure.
     *              The return value will be casted to boolean if non-boolean was returned.
     *
     * @since 5.0.0
     */
    public function offsetExists($offset);

    /**
     * Offset to retrieve
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
     *
     * @param TKey $offset The offset to retrieve.
     * @return TValue|null Can return all value types.
     * @psalm-ignore-nullable-return
     *
     * @since 5.0.0
     */
    public function offsetGet($offset);

    /**
     * Offset to set
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
     *
     * @param TKey|null $offset The offset to assign the value to.
     * @param TValue $value The value to set.
     * @return void
     *
     * @since 5.0.0
     */
    public function offsetSet($offset, $value);

    /**
     * Offset to unset
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
     *
     * @param TKey $offset The offset to unset.
     * @return void
     *
     * @since 5.0.0
     */
    public function offsetUnset($offset);
}

/**
 * This class allows objects to work as arrays.
 * @link http://php.net/manual/en/class.arrayobject.php
 *
 * @template TKey
 * @template TValue
 * @template-implements IteratorAggregate<TKey, TValue>
 * @template-implements ArrayAccess<TKey, TValue>
 */
class ArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable {
    /**
     * Properties of the object have their normal functionality when accessed as list (var_dump, foreach, etc.).
     */
    const STD_PROP_LIST = 1;

    /**
     * Entries can be accessed as properties (read and write).
     */
    const ARRAY_AS_PROPS = 2;

    /**
     * Construct a new array object
     * @link http://php.net/manual/en/arrayobject.construct.php
     *
     * @param array<TKey, TValue>|object $input The input parameter accepts an array or an Object.
     * @param int $flags Flags to control the behaviour of the ArrayObject object.
     * @param string $iterator_class Specify the class that will be used for iteration of the ArrayObject object. ArrayIterator is the default class used.
     * @psalm-param class-string<ArrayIterator<TKey,TValue>>|class-string<ArrayObject<TKey,TValue>> $iterator_class
     *
     * @since 5.0.0
     */
    public function __construct($input = null, $flags = 0, $iterator_class = "ArrayIterator") { }

    /**
     * Returns whether the requested index exists
     * @link http://php.net/manual/en/arrayobject.offsetexists.php
     *
     * @param TKey $index The index being checked.
     * @return bool true if the requested index exists, otherwise false
     *
     * @since 5.0.0
     */
    public function offsetExists($index) { }

    /**
     * Returns the value at the specified index
     * @link http://php.net/manual/en/arrayobject.offsetget.php
     *
     * @param TKey $index The index with the value.
     * @return TValue The value at the specified index or false.
     *
     * @since 5.0.0
     */
    public function offsetGet($index) { }

    /**
     * Sets the value at the specified index to newval
     * @link http://php.net/manual/en/arrayobject.offsetset.php
     *
     * @param TKey $index  The index being set.
     * @param TValue $newval The new value for the index.
     * @return void
     *
     * @since 5.0.0
     */
    public function offsetSet($index, $newval) { }

    /**
     * Unsets the value at the specified index
     * @link http://php.net/manual/en/arrayobject.offsetunset.php
     *
     * @param TKey $index The index being unset.
     * @return void
     *
     * @since 5.0.0
     */
    public function offsetUnset($index) { }

    /**
     * Appends the value
     * @link http://php.net/manual/en/arrayobject.append.php
     *
     * @param TValue $value The value being appended.
     * @return void
     *
     * @since 5.0.0
     */
    public function append($value) { }

    /**
     * Creates a copy of the ArrayObject.
     * @link http://php.net/manual/en/arrayobject.getarraycopy.php
     *
     * @return array<TKey, TValue>  a copy of the array. When the ArrayObject refers to an object
     *                              an array of the public properties of that object will be returned.
     *
     * @since 5.0.0
     */
    public function getArrayCopy() { }

    /**
     * Get the number of public properties in the ArrayObject
     * When the ArrayObject is constructed from an array all properties are public.
     * @link http://php.net/manual/en/arrayobject.count.php
     *
     * @return int The number of public properties in the ArrayObject.
     *
     * @since 5.0.0
     */
    public function count() { }

    /**
     * Gets the behavior flags.
     * @link http://php.net/manual/en/arrayobject.getflags.php
     *
     * @return int the behavior flags of the ArrayObject.
     *
     * @since 5.1.0
     */
    public function getFlags() { }

    /**
     * Sets the behavior flags.
     *
     * It takes on either a bitmask, or named constants. Using named
     * constants is strongly encouraged to ensure compatibility for future
     * versions.
     *
     * The available behavior flags are listed below. The actual
     * meanings of these flags are described in the
     * predefined constants.
     *
     * <table>
     * ArrayObject behavior flags
     * <tr valign="top">
     * <td>value</td>
     * <td>constant</td>
     * </tr>
     * <tr valign="top">
     * <td>1</td>
     * <td>
     * ArrayObject::STD_PROP_LIST
     * </td>
     * </tr>
     * <tr valign="top">
     * <td>2</td>
     * <td>
     * ArrayObject::ARRAY_AS_PROPS
     * </td>
     * </tr>
     * </table>
     *
     * @link http://php.net/manual/en/arrayobject.setflags.php
     *
     * @param int $flags The new ArrayObject behavior.
     * @return void
     *
     * @since 5.1.0
     */
    public function setFlags($flags) { }

    /**
     * Sort the entries by value
     * @link http://php.net/manual/en/arrayobject.asort.php
     *
     * @return void
     *
     * @since 5.2.0
     */
    public function asort() { }

    /**
     * Sort the entries by key
     * @link http://php.net/manual/en/arrayobject.ksort.php
     *
     * @return void
     *
     * @since 5.2.0
     */
    public function ksort() { }

    /**
     * Sort the entries with a user-defined comparison function and maintain key association
     * @link http://php.net/manual/en/arrayobject.uasort.php
     *
     * Function <i>cmp_function</i> should accept two
     * parameters which will be filled by pairs of entries.
     * The comparison function must return an integer less than, equal
     * to, or greater than zero if the first argument is considered to
     * be respectively less than, equal to, or greater than the
     * second.
     *
     * @param callable(TValue, TValue):int $cmp_function
     * @return void
     *
     * @since 5.2.0
     */
    public function uasort($cmp_function) { }

    /**
     * Sort the entries by keys using a user-defined comparison function
     * @link http://php.net/manual/en/arrayobject.uksort.php
     *
     * Function <i>cmp_function</i> should accept two
     * parameters which will be filled by pairs of entry keys.
     * The comparison function must return an integer less than, equal
     * to, or greater than zero if the first argument is considered to
     * be respectively less than, equal to, or greater than the
     * second.
     *
     * @param callable(TKey, TKey):int $cmp_function The callable comparison function.
     * @return void
     *
     * @since 5.2.0
     */
    public function uksort($cmp_function) { }

    /**
     * Sort entries using a "natural order" algorithm
     * @link http://php.net/manual/en/arrayobject.natsort.php
     *
     * @return void
     *
     * @since 5.2.0
     */
    public function natsort() { }

    /**
     * Sort an array using a case insensitive "natural order" algorithm
     * @link http://php.net/manual/en/arrayobject.natcasesort.php
     *
     * @return void
     *
     * @since 5.2.0
     */
    public function natcasesort() { }

    /**
     * Unserialize an ArrayObject
     * @link http://php.net/manual/en/arrayobject.unserialize.php
     *
     * @param string $serialized  The serialized ArrayObject
     * @return void The unserialized ArrayObject
     *
     * @since 5.3.0
     */
    public function unserialize($serialized) { }

    /**
     * Serialize an ArrayObject
     * @link http://php.net/manual/en/arrayobject.serialize.php
     *
     * @return string The serialized representation of the ArrayObject.
     *
     * @since 5.3.0
     */
    public function serialize() { }

    /**
     * Create a new iterator from an ArrayObject instance
     * @link http://php.net/manual/en/arrayobject.getiterator.php
     *
     * @return ArrayIterator<TKey, TValue> An iterator from an ArrayObject.
     *
     * @since 5.0.0
     */
    public function getIterator() { }

    /**
     * Exchange the array for another one.
     * @link http://php.net/manual/en/arrayobject.exchangearray.php
     *
     * @param mixed $input The new array or object to exchange with the current array.
     * @return array the old array.
     *
     * @since 5.1.0
     */
    public function exchangeArray($input) { }

    /**
     * Sets the iterator classname for the ArrayObject.
     * @link http://php.net/manual/en/arrayobject.setiteratorclass.php
     *
     * @param string $iterator_class The classname of the array iterator to use when iterating over this object.
     * @psalm-param class-string<ArrayIterator<TKey,TValue>>|class-string<ArrayObject<TKey,TValue>> $iterator_class
     * @return void
     *
     * @since 5.1.0
     */
    public function setIteratorClass($iterator_class) { }

    /**
     * Gets the iterator classname for the ArrayObject.
     * @link http://php.net/manual/en/arrayobject.getiteratorclass.php
     *
     * @return string the iterator class name that is used to iterate over this object.
     * @psalm-return class-string<ArrayIterator<TKey,TValue>>|class-string<ArrayObject<TKey,TValue>>
     *
     * @since 5.1.0
     */
    public function getIteratorClass() { }
}

interface Serializable {
    /**
     * @return null|string
     */
    public function serialize();

    /**
     * @param string $data
     * @return void
     */
    public function unserialize($data);
}

/**
 * @template-covariant T as object
 * @psalm-immutable
 */
final class WeakReference
{
    // always fail
    public function __construct() {}

    /**
     * @template TIn as object
     * @param TIn $referent
     * @return WeakReference<TIn>
     */
    public static function create(object $referent): WeakReference {}

    /** @return ?T */
    public function get(): ?object {}
}

/**
 * @template TKey of object
 * @template TVal of mixed
 * @implements ArrayAccess<TKey, TVal>
 * @implements IteratorAggregate<TKey,TVal>
 * @implements Traversable<TKey,TVal>
 *
 * @since 8.0.0
 */
final class WeakMap implements ArrayAccess, Countable, IteratorAggregate, Traversable
{
    /**
     * @param TKey $offset
     * @return bool
     */
    public function offsetExists($offset) {}

    /**
     * @param TKey $offset
     * @return TVal|null
     * @psalm-ignore-nullable-return
     */
    public function offsetGet($offset) {}

    /**
     * @param TKey $offset
     * @param TVal $value
     * @return void
     */
    public function offsetSet($offset, $value) {}

    /**
     * @param TKey $offset
     * @return void
     */
    public function offsetUnset($offset) {}
}

class mysqli
{
    /**
     * @psalm-pure
     *
     * @psalm-taint-escape sql
     * @psalm-flow ($string) -> return
     */
    function escape_string($string) {}

    /**
     * @psalm-pure
     *
     * @psalm-taint-escape sql
     * @psalm-flow ($string) -> return
     */
    function real_escape_string($string) {}
}

class SQLite3
{
    /**
     * @psalm-pure
     *
     * @psalm-taint-escape sql
     * @psalm-flow ($string) -> return
     */
    static function escapeString($string) {}
}


#[Attribute(Attribute::TARGET_METHOD)]
final class ReturnTypeWillChange
{
    public function __construct() {}
}

#[Attribute(Attribute::TARGET_PARAMETER)]
final class SensitiveParameter
{
    public function __construct() {}
}

#[Attribute(Attribute::TARGET_CLASS)]
final class AllowDynamicProperties
{
    public function __construct() {}
}
<?php declare(strict_types=1);

namespace PhpParser\Node\Expr;

use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\VariadicPlaceholder;

abstract class CallLike extends Expr {
    /**
     * @return list<Arg|VariadicPlaceholder>
     */
    abstract public function getRawArgs(): array;

    public function isFirstClassCallable(): bool {}

    /**
     * @psalm-pure
     * @return list<Arg>
     */
    public function getArgs(): array {}
}
<?php

namespace {
    /**
     * @since 7.4.0
     */
    final class FFI
    {
        public static function cdef(string $code = "", ?string $lib = null): FFI
        {
        }

        public static function load(string $filename): ?FFI
        {
        }

        public static function scope(string $name): FFI
        {
        }

        /**
         * @param \FFI\CType|string $type
         */
        public static function new($type, bool $owned = true, bool $persistent = false): ?\FFI\CData
        {
        }

        public static function free(\FFI\CData $ptr): void
        {
        }

        /**
         * @param \FFI\CType $type
         * @param \FFI\CData|int|float|bool|null $ptr
         */
        public static function cast($type, &$ptr): ?\FFI\CData
        {
        }

        public static function type(string $type): ?\FFI\CType
        {
        }

        public static function typeof(\FFI\CData $ptr): \FFI\CType
        {
        }

        /**
         * @param array<int<0,max>> $dimensions
         */
        public static function arrayType(\FFI\CType $type, array $dimensions): \FFI\CType
        {
        }

        public static function addr(\FFI\CData $ptr): \FFI\CData
        {
        }

        /**
         * @param \FFI\CData|\FFI\CType $ptr
         * @return int<0,max>
         */
        public static function sizeof($ptr): int
        {
        }

        /**
         * @param \FFI\CData|\FFI\CType $ptr
         * @return positive-int
         */
        public static function alignof($ptr): int
        {
        }

        /**
         * @param \FFI\CData|string $from
         * @param int<0,max> $size
         */
        public static function memcpy(\FFI\CData $to, $from, int $size): void
        {
        }

        /**
         * @param string|\FFI\CData $ptr1
         * @param string|\FFI\CData $ptr2
         * @param int<0,max> $size
         */
        public static function memcmp(&$ptr1, &$ptr2, int $size): int
        {
        }

        /**
         * @param int<0,max> $size
         */
        public static function memset(\FFI\CData $ptr, int $value, int $size): void
        {
        }

        /**
         * @param int<0,max>|null $size
         */
        public static function string(\FFI\CData $ptr, ?int $size = null): string
        {
        }

        public static function isNull(\FFI\CData $ptr): bool
        {
        }
    }

}

namespace FFI {

    /**
     * @since 7.4.0
     */
    final class CData
    {

    }

    /**
     * @since 7.4.0
     */
    final class CType
    {
        /**
         * @since 8.1
         */
        public const TYPE_VOID = 0;

        /**
         * @since 8.1
         */
        public const TYPE_FLOAT = 1;

        /**
         * @since 8.1
         */
        public const TYPE_DOUBLE = 2;

        /**
         * @since 8.1
         */
        public const TYPE_LONGDOUBLE = 3;

        /**
         * @since 8.1
         */
        public const TYPE_UINT8 = 4;

        /**
         * @since 8.1
         */
        public const TYPE_SINT8 = 5;

        /**
         * @since 8.1
         */
        public const TYPE_UINT16 = 6;

        /**
         * @since 8.1
         */
        public const TYPE_SINT16 = 7;

        /**
         * @since 8.1
         */
        public const TYPE_UINT32 = 8;

        /**
         * @since 8.1
         */
        public const TYPE_SINT32 = 9;

        /**
         * @since 8.1
         */
        public const TYPE_UINT64 = 10;

        /**
         * @since 8.1
         */
        public const TYPE_SINT64 = 11;

        /**
         * @since 8.1
         */
        public const TYPE_ENUM = 12;

        /**
         * @since 8.1
         */
        public const TYPE_BOOL = 13;

        /**
         * @since 8.1
         */
        public const TYPE_CHAR = 14;

        /**
         * @since 8.1
         */
        public const TYPE_POINTER = 15;

        /**
         * @since 8.1
         */
        public const TYPE_FUNC = 16;

        /**
         * @since 8.1
         */
        public const TYPE_ARRAY = 17;

        /**
         * @since 8.1
         */
        public const TYPE_STRUCT = 18;

        /**
         * @since 8.1
         */
        public const ATTR_CONST = 1;

        /**
         * @since 8.1
         */
        public const ATTR_INCOMPLETE_TAG = 2;

        /**
         * @since 8.1
         */
        public const ATTR_VARIADIC = 4;

        /**
         * @since 8.1
         */
        public const ATTR_INCOMPLETE_ARRAY = 8;

        /**
         * @since 8.1
         */
        public const ATTR_VLA = 16;

        /**
         * @since 8.1
         */
        public const ATTR_UNION = 32;

        /**
         * @since 8.1
         */
        public const ATTR_PACKED = 64;

        /**
         * @since 8.1
         */
        public const ATTR_MS_STRUCT = 128;

        /**
         * @since 8.1
         */
        public const ATTR_GCC_STRUCT = 256;

        /**
         * @since 8.1
         */
        public const ABI_DEFAULT = 0;

        /**
         * @since 8.1
         */
        public const ABI_CDECL = 1;

        /**
         * @since 8.1
         */
        public const ABI_FASTCALL = 2;

        /**
         * @since 8.1
         */
        public const ABI_THISCALL = 3;

        /**
         * @since 8.1
         */
        public const ABI_STDCALL = 4;

        /**
         * @since 8.1
         */
        public const ABI_PASCAL = 5;

        /**
         * @since 8.1
         */
        public const ABI_REGISTER = 6;

        /**
         * @since 8.1
         */
        public const ABI_MS = 7;

        /**
         * @since 8.1
         */
        public const ABI_SYSV = 8;

        /**
         * @since 8.1
         */
        public const ABI_VECTORCALL = 9;

        public function getName(): string
        {
        }

        /**
         * @since 8.1.0
         * @return self::TYPE_*
         */
        public function getKind(): int
        {
        }

        /**
         * @since 8.1.0
         * @return int<0,max>
         */
        public function getSize(): int
        {
        }

        /**
         * @since 8.1.0
         * @return int<0,max>
         */
        public function getAlignment(): int
        {
        }

        /**
         * @since 8.1.0
         */
        public function getAttributes(): int
        {
        }

        /**
         * @since 8.1.0
         * @return self::TYPE_UINT32|self::TYPE_UINT64
         */
        public function getEnumKind(): int
        {
        }

        /**
         * @since 8.1.0
         */
        public function getArrayElementType(): CType
        {
        }

        /**
         * @since 8.1.0
         * @return int<0,max>
         */
        public function getArrayLength(): int
        {
        }

        /**
         * @since 8.1.0
         */
        public function getPointerType(): CType
        {
        }

        /**
         * @since 8.1.0
         * @return string[]
         */
        public function getStructFieldNames(): array
        {
        }

        /**
         * @since 8.1.0
         * @return int<0,max>
         */
        public function getStructFieldOffset(string $name): int
        {
        }

        /**
         * @since 8.1.0
         */
        public function getStructFieldType(string $name): CType
        {
        }

        /**
         * @since 8.1.0
         * @return self::ABI_*
         */
        public function getFuncABI(): int
        {
        }

        /**
         * @since 8.1.0
         */
        public function getFuncReturnType(): CType
        {
        }

        /**
         * @since 8.1.0
         * @return int<0,max>
         */
        public function getFuncParameterCount(): int
        {
        }

        /**
         * @param int<0,max> $index
         * @since 8.1.0
         */
        public function getFuncParameterType(int $index): CType
        {
        }
    }

    /**
     * @since 7.4.0
     */
    class Exception extends \Error
    {
    }

    /**
     * @since 7.4.0
     */
    final class ParserException extends Exception
    {
    }
}
<?php
// This file is the result of combining the stubs from the
// [documentation](https://www.php.net/manual/en/class.domattr.php), the stubs from
// [php-src](https://github.com/php/php-src/blob/master/ext/dom/php_dom.stub.php), the reflection-generated stubs, and
// further updates for Psalm.

const XML_ELEMENT_NODE = 1;
const XML_ATTRIBUTE_NODE = 2;
const XML_TEXT_NODE = 3;
const XML_CDATA_SECTION_NODE = 4;
const XML_ENTITY_REF_NODE = 5;
const XML_ENTITY_NODE = 6;
const XML_PI_NODE = 7;
const XML_COMMENT_NODE = 8;
const XML_DOCUMENT_NODE = 9;
const XML_DOCUMENT_TYPE_NODE = 10;
const XML_DOCUMENT_FRAG_NODE = 11;
const XML_NOTATION_NODE = 12;
const XML_HTML_DOCUMENT_NODE = 13;
const XML_DTD_NODE = 14;
const XML_ELEMENT_DECL_NODE = 15;
const XML_ATTRIBUTE_DECL_NODE = 16;
const XML_ENTITY_DECL_NODE = 17;
const XML_NAMESPACE_DECL_NODE = 18;
const XML_LOCAL_NAMESPACE = 18;
const XML_ATTRIBUTE_CDATA = 1;
const XML_ATTRIBUTE_ID = 2;
const XML_ATTRIBUTE_IDREF = 3;
const XML_ATTRIBUTE_IDREFS = 4;
const XML_ATTRIBUTE_ENTITY = 6;
const XML_ATTRIBUTE_NMTOKEN = 7;
const XML_ATTRIBUTE_NMTOKENS = 8;
const XML_ATTRIBUTE_ENUMERATION = 9;
const XML_ATTRIBUTE_NOTATION = 10;
const DOM_PHP_ERR = 0;
const DOM_INDEX_SIZE_ERR = 1;
const DOMSTRING_SIZE_ERR = 2;
const DOM_HIERARCHY_REQUEST_ERR = 3;
const DOM_WRONG_DOCUMENT_ERR = 4;
const DOM_INVALID_CHARACTER_ERR = 5;
const DOM_NO_DATA_ALLOWED_ERR = 6;
const DOM_NO_MODIFICATION_ALLOWED_ERR = 7;
const DOM_NOT_FOUND_ERR = 8;
const DOM_NOT_SUPPORTED_ERR = 9;
const DOM_INUSE_ATTRIBUTE_ERR = 10;
const DOM_INVALID_STATE_ERR = 11;
const DOM_SYNTAX_ERR = 12;
const DOM_INVALID_MODIFICATION_ERR = 13;
const DOM_NAMESPACE_ERR = 14;
const DOM_INVALID_ACCESS_ERR = 15;
const DOM_VALIDATION_ERR = 16;

final class DOMException extends Exception
{
    public int $code;
}

/** @php-from 8.0 */
interface DOMParentNode
{
    /**
     * @param DOMNode|string ...$nodes
     */
    public function append(...$nodes) : void;

    /**
     * @param DOMNode|string ...$nodes
     */
    public function prepend(...$nodes) : void;
}

/** @php-from 8.0 */
interface DOMChildNode
{
    public function remove() : void;

    /**
     * @param DOMNode|string ...$nodes
     */
    public function before(...$nodes) : void;

    /**
     * @param DOMNode|string ...$nodes
     */
    public function after(...$nodes) : void;

    /**
     * @param DOMNode|string ...$nodes
     */
    public function replaceWith(...$nodes) : void;
}

class DOMImplementation
{
    // Not implemented: https://github.com/php/php-src/blob/c53455ffd78179feb6f5cef180fa638890699266/ext/dom/domimplementation.c#L230
    // public function getFeature(string $feature, string $version)
    // {
    // }

    public function hasFeature(string $feature, string $version): bool {}

    /**
     * @return DOMDocumentType|false
     * @psalm-ignore-falsable-return
     */
    public function createDocumentType(string $qualifiedName, string $publicId = '', string $systemId = '') {}

    /**
     * @return DOMDocument|false
     * @psalm-ignore-falsable-return
     */
    public function createDocument(string $namespace = '', string $qualifiedName = '', DOMDocumentType $doctype = null) {}

    /**
     * @return DOMDocument|false
     * @psalm-ignore-falsable-return
     * @php-from 8.0
     */
    public function createDocument(string $namespace = '', string $qualifiedName = '', ?DOMDocumentType $doctype = null) {}

    /**
     * @return DOMDocument|false
     * @psalm-ignore-falsable-return
     * @php-from 8.0.3
     */
    public function createDocument(?string $namespace = null, string $qualifiedName = '', ?DOMDocumentType $doctype = null) {}
}

class DOMNode
{
    /** @readonly */
    public string $nodeName;
    public ?string $nodeValue;
    /** @readonly */
    public int $nodeType;
    /** @readonly */
    public ?DOMNode $parentNode;
    /**
     * @readonly
     * @var DOMNodeList<DOMNode>
     */
    public DOMNodeList $childNodes;
    /** @readonly */
    public ?DOMNode $firstChild;
    /** @readonly */
    public ?DOMNode $lastChild;
    /** @readonly */
    public ?DOMNode $previousSibling;
    /** @readonly */
    public ?DOMNode $nextSibling;
    /**
     * @readonly
     * @var DOMNamedNodeMap<DOMAttr>|null
     */
    public ?DOMNamedNodeMap $attributes;
    /** @readonly */
    public ?DOMDocument $ownerDocument;
    /** @readonly */
    public ?string $namespaceURI;
    public string $prefix;
    /** @readonly */
    public ?string $localName;
    /** @readonly */
    public ?string $baseURI;
    public string $textContent;

    /**
     * @return DOMNode|false
     * @psalm-ignore-falsable-return
     */
    public function appendChild(DOMNode $node) {}

    /**
     * @return string|false
     * @psalm-ignore-falsable-return
     */
    public function C14N(bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null) {}

    /**
     * @return int|false
     * @psalm-ignore-falsable-return
     */
    public function C14NFile(string $uri, bool $exclusive = false, bool $withComments = false, ?array $xpath = null, ?array $nsPrefixes = null) {}

    /**
     * @return DOMNode|false
     * @psalm-ignore-falsable-return
     */
    public function cloneNode(bool $deep = false) {}

    public function getLineNo(): int {}

    public function getNodePath(): ?string {}

    public function hasAttributes(): bool {}

    public function hasChildNodes(): bool {}

    /**
     * @return DOMNode|false
     * @psalm-ignore-falsable-return
     */
    public function insertBefore(DOMNode $node, ?DOMNode $child = null) {}

    public function isDefaultNamespace(string $namespace): bool {}

    public function isSameNode(DOMNode $otherNode): bool {}

    public function isSupported(string $feature, string $version): bool {}

    public function lookupNamespaceURI(?string $prefix): ?string {}

    public function lookupPrefix(string $namespace): ?string {}

    public function normalize(): void {}

    /**
     * @return DOMNode|false
     * @psalm-ignore-falsable-return
     */
    public function removeChild(DOMNode $child) {}

    /**
     * @return DOMNode|false
     * @psalm-ignore-falsable-return
     */
    public function replaceChild(DOMNode $node, DOMNode $child) {}
}

class DOMNameSpaceNode
{
    /** @readonly */
    public string $nodeName;
    /** @readonly */
    public ?string $nodeValue;
    /** @readonly */
    public int $nodeType;
    /** @readonly */
    public string $prefix;
    /** @readonly */
    public ?string $localName;
    /** @readonly */
    public ?string $namespaceURI;
    /** @readonly */
    public ?DOMDocument $ownerDocument;
    /** @readonly */
    public ?DOMNode $parentNode;
}

class DOMDocumentFragment extends DOMNode implements DOMParentNode
{
    /** @readonly */
    public ?DOMElement $firstElementChild;
    /** @readonly */
    public ?DOMElement $lastElementChild;
    /** @readonly */
    public int $childElementCount;

    public function __construct() {}

    public function appendXML(string $data): bool {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function append(...$nodes): void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function prepend(...$nodes): void {}
}

class DOMDocument extends DOMNode implements DOMParentNode
{
    /** @readonly */
    public ?DOMDocumentType $doctype;
    /** @readonly */
    public DOMImplementation $implementation;
    /** @readonly */
    public ?DOMElement $documentElement;

    /**
     * @deprecated
     * @readonly
     */
    public ?string $actualEncoding;

    /**
     * @var ?string
     */
    public $encoding;

    /** @readonly */
    public ?string $xmlEncoding;

    /**
     * @var bool
     */
    public $standalone;

    /**
     * @var bool
     */
    public $xmlStandalone;

    /**
     * @var ?string
     */
    public $version;

    /**
     * @var ?string
     */
    public $xmlVersion;

    /**
     * @var bool
     */
    public $strictErrorChecking;

    /**
     * @var ?string
     */
    public $documentURI;

    /**
     * @var mixed
     * @readonly
     * @deprecated
     */
    public $config;

    /**
     * @var bool
     */
    public $formatOutput;

    /**
     * @var bool
     */
    public $validateOnParse;

    /**
     * @var bool
     */
    public $resolveExternals;

    /**
     * @var bool
     */
    public $preserveWhiteSpace;

    /**
     * @var bool
     */
    public $recover;

    /**
     * @var bool
     */
    public $substituteEntities;

    /** @readonly */
    public ?DOMElement $firstElementChild;
    /** @readonly */
    public ?DOMElement $lastElementChild;
    /** @readonly */
    public int $childElementCount;

    public function __construct(string $version = '1.0', string $encoding = '') {}

    /**
     * @return DOMAttr|false
     * @psalm-ignore-falsable-return
     */
    public function createAttribute(string $localName) {}

    /**
     * @return DOMAttr|false
     * @psalm-ignore-falsable-return
     */
    public function createAttributeNS(?string $namespace, string $qualifiedName) {}

    /**
     * @return DOMCdataSection|false
     * @psalm-ignore-falsable-return
     */
    public function createCDATASection(string $data) {}

    /**
     * @return DOMComment|false
     * @psalm-ignore-falsable-return
     */
    public function createComment(string $data) {}

    /**
     * @throws DOMException
     * @php-from 8.1
     */
    public function createComment(string $data): DOMComment {}

    /**
     * @return DOMDocumentFragment|false
     * @psalm-ignore-falsable-return
     */
    public function createDocumentFragment() {}

    /**
     * @throws DOMException
     * @php-from 8.1
     */
    public function createDocumentFragment(): DOMDocumentFragment {}

    /**
     * @return DOMElement|false
     * @psalm-ignore-falsable-return
     */
    public function createElement(string $localName, string $value = '') {}

    /**
     * @return DOMElement|false
     * @psalm-ignore-falsable-return
     */
    public function createElementNS(?string $namespace, string $qualifiedName, string $value = '') {}

    /**
     * @return DOMEntityReference|false
     * @psalm-ignore-falsable-return
     */
    public function createEntityReference(string $name) {}

    /**
     * @return DOMProcessingInstruction|false
     * @psalm-ignore-falsable-return
     */
    public function createProcessingInstruction(string $target, string $data = '') {}

    /**
     * @return DOMText|false
     * @psalm-ignore-falsable-return
     */
    public function createTextNode(string $data) {}

    /**
     * @throws DOMException
     * @php-from 8.1
     */
    public function createTextNode(string $data): DOMText {}

    public function getElementById(string $elementId): ?DOMElement {}

    /** @return DOMNodeList<DOMElement> */
    public function getElementsByTagName(string $qualifiedName): DOMNodeList {}

    /** @return DOMNodeList<DOMElement> */
    public function getElementsByTagNameNS(string $namespace, string $localName): DOMNodeList {}

    /**
     * @return DOMNodeList<DOMElement>
     * @php-from 8.0.3
     */
    public function getElementsByTagNameNS(?string $namespace, string $localName): DOMNodeList {}

    /**
     * @return DOMNode|false
     * @psalm-ignore-falsable-return
     */
    public function importNode(DOMNode $node, bool $deep = false) {}

    /**
     * @return DOMDocument|false
     * @psalm-ignore-falsable-return
     **/
    public function load(string $filename, int $options = 0) {}

    /**
     * @return DOMDocument|false
     * @psalm-ignore-falsable-return
     */
    public function loadXML(string $source, int $options = 0) {}

    public function normalizeDocument(): void {}

    public function registerNodeClass(string $baseClass, ?string $extendedClass): bool {}

    /**
     * @return int|false
     * @psalm-ignore-falsable-return
     */
    public function save(string $filename, int $options = 0) {}

    /** @return DOMDocument|bool */
    public function loadHTML(string $source, int $options = 0) {}

    /** @return DOMDocument|bool */
    public function loadHTMLFile(string $filename, int $options = 0) {}

    /**
     * @return string|false
     * @psalm-ignore-falsable-return
     */
    public function saveHTML(?DOMNode $node = null) {}

    /**
     * @return int|false
     * @psalm-ignore-falsable-return
     */
    public function saveHTMLFile(string $filename) {}

    /**
     * @return string|false
     * @psalm-ignore-falsable-return
     */
    public function saveXML(?DOMNode $node = null, int $options = 0) {}

    public function schemaValidate(string $filename, int $flags = 0): bool {}

    public function schemaValidateSource(string $source, int $flags = 0): bool {}

    public function relaxNGValidate(string $filename): bool {}

    public function relaxNGValidateSource(string $source): bool {}

    public function validate(): bool {}

    /**
     * @return int|false
     * @psalm-ignore-falsable-return
     */
    public function xinclude(int $options = 0) {}

    /**
     * @return DOMNode|false
     * @psalm-ignore-falsable-return
     */
    public function adoptNode(DOMNode $node) {}

    /**
     * @return DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function append(...$nodes) : void {}

    /**
     * @return DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function prepend(...$nodes) : void {}
}

/**
 * @template-covariant TNode as DOMNode
 * @template-implements Traversable<int, TNode>
 */
class DOMNodeList implements Traversable
{
    /** @readonly */
    public int $length;

    /**
     * @return TNode|null
     * @psalm-ignore-nullable-return
     */
    public function item(int $index) {}
}

/**
 * @template-covariant TNode as DOMNode
 * @template-implements Traversable<int, TNode>
 *
 * @php-from 7.2
 */
class DOMNodeList implements Traversable, Countable
{
    /** @readonly */
    public int $length;

    public function count(): int {}

    /**
     * @return TNode|null
     * @psalm-ignore-nullable-return
     */
    public function item(int $index) {}
}

/**
 * @template-covariant TNode as DOMNode
 * @template-implements IteratorAggregate<int, TNode>
 *
 * @php-from 8.0
 */
class DOMNodeList implements IteratorAggregate, Countable
{
    /** @readonly */
    public int $length;

    public function count(): int {}

    /** @return Iterator<int, TNode> */
    public function getIterator() : Iterator {}

    /**
     * @return TNode|null
     * @psalm-ignore-nullable-return
     */
    public function item(int $index) {}
}

/**
 * @template-covariant TNode as DOMNode
 * @template-implements Traversable<string, TNode>
 */
class DOMNamedNodeMap implements Traversable, Countable
{
    /** @readonly */
    public int $length;

    /** @return TNode|null */
    public function getNamedItem(string $qualifiedName): ?DOMNode {}

    /** @return TNode|null */
    public function getNamedItemNS(?string $namespace, string $localName): ?DOMNode {}

    /**
     * @return TNode|null
     * @psalm-ignore-nullable-return
     */
    public function item(int $index): ?DOMNode {}

    public function count(): int {}
}

/**
 * @template-covariant TNode as DOMNode
 * @template-implements IteratorAggregate<string, TNode>
 *
 * @php-from 8.0
 */
class DOMNamedNodeMap implements IteratorAggregate, Countable
{
    /** @readonly */
    public int $length;

    /** @return TNode|null */
    public function getNamedItem(string $qualifiedName): ?DOMNode {}

    /** @return TNode|null */
    public function getNamedItemNS(?string $namespace, string $localName): ?DOMNode {}

    /**
     * @return TNode|null
     * @psalm-ignore-nullable-return
     */
    public function item(int $index): ?DOMNode {}

    public function count(): int {}

    /** @return Iterator<string, TNode> */
    public function getIterator() : Iterator {}
}

class DOMCharacterData extends DOMNode implements DOMChildNode
{
    public string $data;
    /** @readonly */
    public int $length;
    /** @readonly */
    public ?DOMElement $previousElementSibling;
    /** @readonly */
    public ?DOMElement $nextElementSibling;

    public function appendData(string $data): bool {}

    /**
     * @return string|false
     * @psalm-ignore-falsable-return
     */
    public function substringData(int $offset, int $count) {}

    public function insertData(int $offset, string $data): bool {}

    public function deleteData(int $offset, int $count): bool {}

    public function replaceData(int $offset, int $count, string $data): bool {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function replaceWith(...$nodes) : void {}

    /** @php-from 8.0 */
    public function remove() : void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function before(...$nodes) : void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function after(...$nodes) : void {}
}

class DOMAttr extends DOMNode
{
    /** @readonly */
    public string $name;
    /** @readonly */
    public bool $specified;
    public string $value;
    /** @readonly */
    public ?DOMElement $ownerElement;
    /** @readonly */
    public mixed $schemaTypeInfo;

    /**
     * Inherited from DOMNode, but always non-null
     * @readonly
     */
    public string $localName;

    public function __construct(string $name, string $value = '') {}

    public function isId(): bool {}
}

class DOMElement extends DOMNode implements DOMParentNode, DOMChildNode
{
    /** @readonly */
    public string $tagName;
    /** @readonly */
    public mixed $schemaTypeInfo;
    /** @readonly */
    public ?DOMElement $firstElementChild;
    /** @readonly */
    public ?DOMElement $lastElementChild;
    /** @readonly */
    public int $childElementCount;
    /** @readonly */
    public ?DOMElement $previousElementSibling;
    /** @readonly */
    public ?DOMElement $nextElementSibling;

    /**
     * Inherited from DOMNode, but always non-null.
     *
     * @readonly
     * @var DOMNamedNodeMap<DOMAttr>
     */
    public DOMNamedNodeMap $attributes;

    /**
     * Inherited from DOMNode, but always non-null
     * @readonly
     */
    public string $localName;

    public function __construct(string $qualifiedName, ?string $value = null, string $namespace = '') {}

    public function getAttribute(string $qualifiedName): string {}

    public function getAttributeNS(?string $namespace, string $localName): string {}

    /**
     * @return DOMAttr|DOMNameSpaceNode|false
     * @psalm-ignore-falsable-return
     */
    public function getAttributeNode(string $qualifiedName) {}

    /**
     * @return DOMAttr|DOMNameSpaceNode|false
     * @psalm-ignore-falsable-return
     */
    public function getAttributeNodeNS(?string $namespace, string $localName) {}

    /** @return DOMNodeList<DOMElement> */
    public function getElementsByTagName(string $qualifiedName): DOMNodeList {}

    /** @return DOMNodeList<DOMElement> */
    public function getElementsByTagNameNS(string $namespace, string $localName): DOMNodeList {}

    /**
     * @return DOMNodeList<DOMElement>
     * @php-from 8.0.3
     */
    public function getElementsByTagNameNS(?string $namespace, string $localName): DOMNodeList {}

    public function hasAttribute(string $qualifiedName): bool {}

    public function hasAttributeNS(?string $namespace, string $localName): bool {}

    public function removeAttribute(string $qualifiedName): bool {}

    public function removeAttributeNS(?string $namespace, string $localName): void {}

    /**
     * @return DOMAttr|false
     * @psalm-ignore-falsable-return
     */
    public function removeAttributeNode(DOMAttr $attr) {}

    /**
     * @return DOMAttr|false
     * @psalm-ignore-falsable-return
     */
    public function setAttribute(string $qualifiedName, string $value) {}

    public function setAttributeNS(?string $namespace, string $qualifiedName, string $value): void {}

    /**
     * @return DOMAttr|null|false
     * @psalm-ignore-falsable-return
     */
    public function setAttributeNode(DOMAttr $attr) {}

    /**
     * @return DOMAttr|null|false
     * @psalm-ignore-falsable-return
     */
    public function setAttributeNodeNS(DOMAttr $attr) {}

    public function setIdAttribute(string $qualifiedName, bool $isId): void {}

    public function setIdAttributeNS(string $namespace, string $qualifiedName, bool $isId): void {}

    public function setIdAttributeNode(DOMAttr $attr, bool $isId): void {}

    /** @php-from 8.0 */
    public function remove() : void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function before(...$nodes) : void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function after(...$nodes) : void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function replaceWith(...$nodes) : void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function append(...$nodes) : void {}

    /**
     * @param DOMNode|string ...$nodes
     * @php-from 8.0
     */
    public function prepend(...$nodes) : void {}
}

class DOMText extends DOMCharacterData
{
    /** @readonly */
    public string $wholeText;

    public function __construct(string $data = '') {}

    public function isWhitespaceInElementContent(): bool {}

    /**
     * @alias DOMText::isWhitespaceInElementContent
     */
    public function isElementContentWhitespace(): bool {}

    /**
     * @return DOMText|false
     * @psalm-ignore-falsable-return
     */
    public function splitText(int $offset) {}
}

class DOMComment extends DOMCharacterData
{
    public function __construct(string $data = '') {}
}

class DOMCdataSection extends DOMText
{
    public function __construct(string $data) {}
}

class DOMDocumentType extends DOMNode
{
    /** @readonly */
    public string $name;
    /** @readonly */
    public DOMNamedNodeMap $entities;
    /** @readonly */
    public DOMNamedNodeMap $notations;
    /** @readonly */
    public string $publicId;
    /** @readonly */
    public string $systemId;
    /** @readonly */
    public ?string $internalSubset;
}

class DOMNotation extends DOMNode
{
    /** @readonly */
    public string $publicId;
    /** @readonly */
    public string $systemId;
}

class DOMEntity extends DOMNode
{
    /** @readonly */
    public ?string $publicId;
    /** @readonly */
    public ?string $systemId;
    /** @readonly */
    public ?string $notationName;

    /**
     * @readonly
     * @deprecated
     */
    public ?string $actualEncoding;

    /**
     * @readonly
     * @deprecated
     */
    public ?string $encoding;

    /**
     * @readonly
     * @deprecated
     */
    public ?string $version;
}

class DOMEntityReference extends DOMNode
{
    public function __construct(string $name) {}
}

class DOMProcessingInstruction extends DOMNode
{
    /** @readonly */
    public string $target;
    public string $data;

    public function __construct(string $name, string $value = '') {}
}

class DOMXPath
{
    /** @readonly */
    public DOMDocument $document;
    public bool $registerNodeNamespaces;

    public function __construct(DOMDocument $document, bool $registerNodeNS = true) {}

    public function evaluate(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed {}

    /**
     * @return DOMNodeList<DOMNode>|false
     */
    public function query(string $expression, ?DOMNode $contextNode = null, bool $registerNodeNS = true): mixed {}

    public function registerNamespace(string $prefix, string $namespace): bool {}

    public function registerPhpFunctions(string|array|null $restrict = null): void {}
}
<?php

class GMP implements Serializable {
    private function __construct() {}

    public function __toString(): string {}

    public function serialize(): string {}

    public function unserialize(string $data): void {}
}
<?php
namespace Decimal;

/**
 * Copied from https://github.com/php-decimal/stubs/blob/master/Decimal.php
 *
 * The MIT License (MIT)
 * Copyright (c) 2018 Rudi Theunissen
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including  without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
 * THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

final class Decimal implements \JsonSerializable
{
    /**
     * These constants are for auto-complete only.
     */
    const ROUND_UP          = 101; /* Round away from zero. */
    const ROUND_DOWN        = 102; /* Round towards zero. */
    const ROUND_CEILING     = 103; /* Round towards positive infinity */
    const ROUND_FLOOR       = 104; /* Round towards negative infinity */
    const ROUND_HALF_UP     = 105; /* Round to nearest, ties away from zero. */
    const ROUND_HALF_DOWN   = 106; /* Round to nearest, ties towards zero. */
    const ROUND_HALF_EVEN   = 107; /* Round to nearest, ties towards even. */
    const ROUND_HALF_ODD    = 108; /* Round to nearest, ties towards odd. */
    const ROUND_TRUNCATE    = 109; /* Truncate, keeping infinity. */

    const DEFAULT_ROUNDING  = Decimal::ROUND_HALF_EVEN;
    const DEFAULT_PRECISION = 28;

    const MIN_PRECISION     = 1;
    const MAX_PRECISION     = 0; /* This value may change across platforms */

    /**
     * Constructor
     *
     * Initializes a new instance using a given value and minimum precision.
     *
     * @param Decimal|string|int $value
     * @param int                $precision
     *
     * @throws \BadMethodCallException if already constructed.
     * @throws \TypeError if the value is not a decimal, string, or integer.
     * @throws \DomainException is the type is supported but the value could not
     *                          be converted to decimal.
     */
    public function __construct($value, int $precision = Decimal::DEFAULT_PRECISION) {}

    /**
     * Sum
     *
     * The precision of the result will be the max of all precisions that were
     * encountered during the calculation. The given precision should therefore
     * be considered the minimum precision of the result.
     *
     * This method is equivalent to adding each value individually.
     *
     * @param array|\Traversable $values
     * @param int                $precision Minimum precision of the sum.
     *
     * @return Decimal the sum of all given values.
     *
     * @throws \TypeError if an unsupported type is encountered.
     * @throws \ArithmeticError if addition is undefined, eg. INF + -INF
     */
    public static function sum($values, int $precision = Decimal::DEFAULT_PRECISION): Decimal {}

    /**
     * Average
     *
     * The precision of the result will be the max of all precisions that were
     * encountered during the calculation. The given precision should therefore
     * be considered the minimum precision of the result.
     *
     * This method is equivalent to adding each value individually,
     * then dividing by the number of values.
     *
     * @param array|\Traversable $values
     * @param int                $precision Minimum precision of the average.
     *
     * @return Decimal the average of all given values.
     *
     * @throws \TypeError if an unsupported type is encountered.
     * @throws \ArithmeticError if addition is undefined, eg. INF + -INF
     */
    public static function avg($values, int $precision = Decimal::DEFAULT_PRECISION): Decimal {}

    /**
     * Copy
     *
     * @param int $precision The precision of the return value, which defaults
     *                       to the precision of this decimal.
     *
     * @return Decimal a copy of this decimal.
     */
    public function copy(int $precision = null): Decimal {}

    /**
     * Add
     *
     * This method is equivalent to the `+` operator.
     *
     * The precision of the result will be the max of this decimal's precision
     * and the given value's precision, where scalar values assume the default.
     *
     * @param Decimal|string|int $value
     *
     * @return Decimal the result of adding this decimal to the given value.
     *
     * @throws \TypeError if the value is not a decimal, string or integer.
     */
    public function add($value): Decimal {}

    /**
     * Subtract
     *
     * This method is equivalent to the `-` operator.
     *
     * The precision of the result will be the max of this decimal's precision
     * and the given value's precision, where scalar values assume the default.
     *
     * @param Decimal|string|int $value
     *
     * @return Decimal the result of subtracting a given value from this decimal.
     *
     * @throws \TypeError if the value is not a decimal, string or integer.
     */
    public function sub($value): Decimal {}

    /**
     * Multiply
     *
     * This method is equivalent to the `*` operator.
     *
     * The precision of the result will be the max of this decimal's precision
     * and the given value's precision, where scalar values assume the default.
     *
     * @param Decimal|string|int $value
     *
     * @return Decimal the result of multiplying this decimal by the given value.
     *
     * @throws \TypeError if the given value is not a decimal, string or integer.
     */
    public function mul($value): Decimal {}

    /**
     * Divide
     *
     * This method is equivalent to the `/` operator.
     *
     * The precision of the result will be the max of this decimal's precision
     * and the given value's precision, where scalar values assume the default.
     *
     * @param Decimal|string|int $value
     *
     * @return Decimal the result of dividing this decimal by the given value.
     *
     * @throws \TypeError if the value is not a decimal, string or integer.
     * @throws \DivisionByZeroError if dividing by zero.
     * @throws \ArithmeticError if division is undefined, eg. INF / -INF
     */
    public function div($value): Decimal {}

    /**
     * Modulo (integer)
     *
     * This method is equivalent to the `%` operator.
     *
     * The precision of the result will be the max of this decimal's precision
     * and the given value's precision, where scalar values assume the default.
     *
     * @see Decimal::rem for the decimal remainder.
     *
     * @param Decimal|string|int $value
     *
     * @return Decimal the remainder after dividing the integer value of this
     *                 decimal by the integer value of the given value
     *
     * @throws \TypeError if the value is not a decimal, string or integer.
     * @throws \DivisionByZeroError if the integer value of $value is zero.
     * @throws \ArithmeticError if the operation is undefined, eg. INF % -INF
     */
    public function mod($value): Decimal {}

    /**
     * Remainder
     *
     * The precision of the result will be the max of this decimal's precision
     * and the given value's precision, where scalar values assume the default.
     *
     * @param Decimal|string|int $value
     *
     * @return Decimal the remainder after dividing this decimal by a given value.
     *
     * @throws \TypeError if the value is not a decimal, string or integer.
     * @throws \DivisionByZeroError if the integer value of $value is zero.
     * @throws \ArithmeticError if the operation is undefined, eg. INF, -INF
     */
    public function rem($value): Decimal {}

    /**
     * Power
     *
     * This method is equivalent to the `**` operator.
     *
     * The precision of the result will be the max of this decimal's precision
     * and the given value's precision, where scalar values assume the default.
     *
     * @param Decimal|string|int $exponent The power to raise this decimal to.
     *
     * @return Decimal the result of raising this decimal to a given power.
     *
     * @throws \TypeError if the exponent is not a decimal, string or integer.
     */
    public function pow($exponent): Decimal {}

    /**
     * Natural logarithm
     *
     * This method is equivalent in function to PHP's `log`.
     *
     * @return Decimal the natural logarithm of this decimal (log base e),
     *                 with the same precision as this decimal.
     */
    public function ln(): Decimal {}

    /**
     * Exponent
     *
     * @return Decimal the exponent of this decimal, ie. e to the power of this,
     *                 with the same precision as this decimal.
     */
    public function exp(): Decimal {}

    /**
     * Base-10 logarithm
     *
     * @return Decimal the base-10 logarithm of this decimal, with the same
     *                 precision as this decimal.
     */
    public function log10(): Decimal {}

    /**
     * Square root
     *
     * @return Decimal the square root of this decimal, with the same precision
     *                 as this decimal.
     */
    public function sqrt(): Decimal {}

    /**
     * Floor
     *
     * @return Decimal the closest integer towards negative infinity.
     */
    public function floor(): Decimal {}

    /**
     * Ceiling
     *
     * @return Decimal the closest integer towards positive infinity.
     */
    public function ceil(): Decimal {}

    /**
     * Truncate
     *
     * @return Decimal the integer value of this decimal.
     */
    public function truncate(): Decimal {}

    /**
     * Round
     *
     * @param int $places The number of places behind the decimal to round to.
     * @param int $mode   The rounding mode, which are constants of Decimal.
     *
     * @return Decimal the value of this decimal with the same precision,
     *                 rounded according to the specified number of decimal
     *                 places and rounding mode
     *
     * @throws \InvalidArgumentException if the rounding mode is not supported.
     */
    public function round(int $places = 0, int $mode = Decimal::DEFAULT_ROUNDING): Decimal {}

    /**
     * Decimal point shift.
     *
     * @param int $places The number of places to shift the decimal point by.
     *                    A positive shift moves the decimal point to the right,
     *                    a negative shift moves the decimal point to the left.
     *
     * @return Decimal A copy of this decimal with its decimal place shifted.
     */
    public function shift(int $places): Decimal {}

    /**
     * Trims trailing zeroes.
     *
     * @return Decimal A copy of this decimal without trailing zeroes.
     */
    public function trim(): Decimal {}

    /**
     * Precision
     *
     * @return int the precision of this decimal.
     */
    public function precision(): int {}

    /**
     * Signum
     *
     * @return int 0 if zero, -1 if negative, or 1 if positive.
     */
    public function signum(): int {}

    /**
     * Parity (integer)
     *
     * @return int 0 if the integer value of this decimal is even, 1 if odd.
     *             Special numbers like NAN and INF will return 1.
     */
    public function parity(): int {}

    /**
     * Absolute
     *
     * @return Decimal the absolute (positive) value of this decimal.
     */
    public function abs(): Decimal {}

    /**
     * Negate
     *
     * @return Decimal the same value as this decimal, but the sign inverted.
     */
    public function negate(): Decimal {}

    /**
     * @return bool TRUE if this decimal is an integer and even, FALSE otherwise.
     */
    public function isEven(): bool {}

    /**
     * @return bool TRUE if this decimal is an integer and odd, FALSE otherwise.
     */
    public function isOdd(): bool {}

    /**
     * @return bool TRUE if this decimal is positive, FALSE otherwise.
     */
    public function isPositive(): bool {}

    /**
     * @return bool TRUE if this decimal is negative, FALSE otherwise.
     */
    public function isNegative(): bool {}

    /**
     * @return bool TRUE if this decimal is not a defined number.
     */
    public function isNaN(): bool {}

    /**
     * @return bool TRUE if this decimal represents infinity, FALSE otherwise.
     */
    public function isInf(): bool {}

    /**
     * @return bool TRUE if this decimal is an integer, ie. does not have
     *              significant figures behind the decimal point, otherwise FALSE.
     */
    public function isInteger(): bool {}

    /**
     * @return bool TRUE if this decimal is either positive or negative zero.
     */
    public function isZero(): bool {}

    /**
     * @param int  $places   The number of places behind the decimal point.
     * @param bool $commas   TRUE if thousands should be separated by a comma.
     * @param int  $rounding
     *
     * @return string the value of this decimal formatted to a fixed number of
     *                decimal places, optionally with thousands comma-separated,
     *                using a given rounding mode.
     */
    public function toFixed(int $places = 0, bool $commas = false, int $rounding = Decimal::DEFAULT_ROUNDING): string {}

    /**
     * String representation.
     *
     * This method is equivalent to a cast to string.
     *
     * This method should not be used as a canonical representation of this
     * decimal, because values can be represented in more than one way. However,
     * this method does guarantee that a decimal instantiated by its output with
     * the same precision will be exactly equal to this decimal.
     *
     * @return string the value of this decimal represented exactly, in either
     *                fixed or scientific form, depending on the value.
     */
    public function toString(): string {}

    /**
     * Integer representation.
     *
     * This method is equivalent to a cast to int.
     *
     * @return int the integer value of this decimal.
     *
     * @throws \OverflowException if the value is greater than PHP_INT_MAX.
     */
    public function toInt(): int {}

    /**
     * Binary floating point representation.
     *
     * This method is equivalent to a cast to float, and is not affected by the
     * 'precision' INI setting.
     *
     * @return float the native PHP floating point value of this decimal.
     *
     * @throws \OverflowException  if the value is greater than PHP_FLOAT_MAX.
     * @throws \UnderflowException if the value is smaller than PHP_FLOAT_MIN.
     */
    public function toFloat(): float {}

    /**
     * Equality
     *
     * This method is equivalent to the `==` operator.
     *
     * @param mixed $other
     *
     * @return bool TRUE if this decimal is considered equal to the given value.
     *              Equal decimal values tie-break on precision.
     */
    public function equals($other): bool {}

    /**
     * Ordering
     *
     * This method is equivalent to the `<=>` operator.
     *
     * @param mixed $other
     *
     * @return int  0 if this decimal is considered is equal to $other,
     *             -1 if this decimal should be placed before $other,
     *              1 if this decimal should be placed after $other.
     */
    public function compareTo($other): int {}

    /**
     * String representation.
     *
     * This method is equivalent to a cast to string, as well as `toString`.
     *
     * @return string the value of this decimal represented exactly, in either
     *                fixed or scientific form, depending on the value.
     */
    public function __toString(): string {}

    /**
     * JSON
     *
     * This method is only here to honour the interface, and is equivalent to
     * `toString`. JSON does not have a decimal type so all decimals are encoded
     * as strings in the same format as `toString`.
     *
     * @return string
     */
    public function jsonSerialize() {}
}
<?php

define('APC_LIST_ACTIVE', 1);
define('APC_LIST_DELETED', 2);
define('APC_ITER_TYPE', 1);
define('APC_ITER_KEY', 2);
define('APC_ITER_FILENAME', 4);
define('APC_ITER_DEVICE', 8);
define('APC_ITER_INODE', 16);
define('APC_ITER_VALUE', 32);
define('APC_ITER_MD5', 64);
define('APC_ITER_NUM_HITS', 128);
define('APC_ITER_MTIME', 256);
define('APC_ITER_CTIME', 512);
define('APC_ITER_DTIME', 1024);
define('APC_ITER_ATIME', 2048);
define('APC_ITER_REFCOUNT', 4096);
define('APC_ITER_MEM_SIZE', 8192);
define('APC_ITER_TTL', 16384);
define('APC_ITER_NONE', 0);
define('APC_ITER_ALL', -1);

class APCUIterator implements Iterator
{
    /**
     * @param array<string>|null|string $search
     * @param int $format
     * @param int $chunk_size
     * @param int $list
     *
     * @return void
     */
    public function __construct($search, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE)
    {
    }

    /**
     * @return void
     */
    public function rewind()
    {
    }

    /**
     * @return void
     */
    public function next()
    {
    }

    /**
     * @return bool
     */
    public function valid()
    {
    }

    /**
     * @return string
     */
    public function key()
    {
    }

    /**
     * @return mixed
     */
    public function current()
    {
    }

    /**
     * @return int
     */
    public function getTotalHits()
    {
    }

    /**
     * @return int
     */
    public function getTotalSize()
    {
    }

    /**
     * @return int
     */
    public function getTotalCount()
    {
    }
}
<?php

/**
 * The SoapClient class provides a client for SOAP 1.1, SOAP 1.2 servers. It can be used in WSDL
 * or non-WSDL mode.
 * @link https://php.net/manual/en/class.soapclient.php
 */
class SoapClient  {

    /**
     * SoapClient constructor
     * @link https://php.net/manual/en/soapclient.soapclient.php
     * @param mixed $wsdl <p>
     * URI of the WSDL file or <b>NULL</b> if working in
     * non-WSDL mode.
     * </p>
     * <p>
     * During development, WSDL caching may be disabled by the
     * use of the soap.wsdl_cache_ttl <i>php.ini</i> setting
     * otherwise changes made to the WSDL file will have no effect until
     * soap.wsdl_cache_ttl is expired.
     * </p>
     * @param array $options [optional] <p>
     * An array of options. If working in WSDL mode, this parameter is optional.
     * If working in non-WSDL mode, the location and
     * uri options must be set, where location
     * is the URL of the SOAP server to send the request to, and uri
     * is the target namespace of the SOAP service.
     * </p>
     * <p>
     * The style and use options only work in
     * non-WSDL mode. In WSDL mode, they come from the WSDL file.
     * </p>
     * <p>
     * The soap_version option should be one of either
     * <b>SOAP_1_1</b> or <b>SOAP_1_2</b> to
     * select SOAP 1.1 or 1.2, respectively. If omitted, 1.1 is used.
     * </p>
     * <p>
     * For HTTP authentication, the login and
     * password options can be used to supply credentials.
     * For making an HTTP connection through
     * a proxy server, the options proxy_host,
     * proxy_port, proxy_login
     * and proxy_password are also available.
     * For HTTPS client certificate authentication use
     * local_cert and passphrase options. An
     * authentication may be supplied in the authentication
     * option. The authentication method may be either
     * <b>SOAP_AUTHENTICATION_BASIC</b> (default) or
     * <b>SOAP_AUTHENTICATION_DIGEST</b>.
     * </p>
     * <p>
     * The compression option allows to use compression
     * of HTTP SOAP requests and responses.
     * </p>
     * <p>
     * The encoding option defines internal character
     * encoding. This option does not change the encoding of SOAP requests (it is
     * always utf-8), but converts strings into it.
     * </p>
     * <p>
     * The trace option enables tracing of request so faults
     * can be backtraced. This defaults to <b>FALSE</b>
     * </p>
     * <p>
     * The classmap option can be used to map some WSDL
     * types to PHP classes. This option must be an array with WSDL types
     * as keys and names of PHP classes as values.
     * </p>
     * <p>
     * Setting the boolean trace option enables use of the
     * methods
     * SoapClient->__getLastRequest,
     * SoapClient->__getLastRequestHeaders,
     * SoapClient->__getLastResponse and
     * SoapClient->__getLastResponseHeaders.
     * </p>
     * <p>
     * The exceptions option is a boolean value defining whether
     * soap errors throw exceptions of type
     * SoapFault.
     * </p>
     * <p>
     * The connection_timeout option defines a timeout in seconds
     * for the connection to the SOAP service. This option does not define a timeout
     * for services with slow responses. To limit the time to wait for calls to finish the
     * default_socket_timeout setting
     * is available.
     * </p>
     * <p>
     * The typemap option is an array of type mappings.
     * Type mapping is an array with keys type_name,
     * type_ns (namespace URI), from_xml
     * (callback accepting one string parameter) and to_xml
     * (callback accepting one object parameter).
     * </p>
     * <p>
     * The cache_wsdl option is one of
     * <b>WSDL_CACHE_NONE</b>,
     * <b>WSDL_CACHE_DISK</b>,
     * <b>WSDL_CACHE_MEMORY</b> or
     * <b>WSDL_CACHE_BOTH</b>.
     * </p>
     * <p>
     * The user_agent option specifies string to use in
     * User-Agent header.
     * </p>
     * <p>
     * The stream_context option is a resource
     * for context.
     * </p>
     * <p>
     * The features option is a bitmask of
     * <b>SOAP_SINGLE_ELEMENT_ARRAYS</b>,
     * <b>SOAP_USE_XSI_ARRAY_TYPE</b>,
     * <b>SOAP_WAIT_ONE_WAY_CALLS</b>.
     * </p>
     * <p>
     * The keep_alive option is a boolean value defining whether
     * to send the Connection: Keep-Alive header or
     * Connection: close.
     * </p>
     * <p>
     * The ssl_method option is one of
     * <b>SOAP_SSL_METHOD_TLS</b>,
     * <b>SOAP_SSL_METHOD_SSLv2</b>,
     * <b>SOAP_SSL_METHOD_SSLv3</b> or
     * <b>SOAP_SSL_METHOD_SSLv23</b>.
     * </p>
     * @throws SoapFault A SoapFault exception will be thrown if the wsdl URI cannot be loaded.
     * @since 5.0.1
     */
    public function __construct ($wsdl, array $options = null) {}

     /**
      * Calls a SOAP function (deprecated)
      * @link https://php.net/manual/en/soapclient.call.php
      * @param string $function_name
      * @param array $arguments
      * @return mixed
      * @since 5.0.1
      */
     public function __call ($function_name, $arguments) {}

     /**
      * Calls a SOAP function
      * @link https://php.net/manual/en/soapclient.soapcall.php
      * @param string $function_name <p>
      * The name of the SOAP function to call.
      * </p>
      * @param array $arguments <p>
      * An array of the arguments to pass to the function. This can be either
      * an ordered or an associative array. Note that most SOAP servers require
      * parameter names to be provided, in which case this must be an
      * associative array.
      * </p>
      * @param array $options [optional] <p>
      * An associative array of options to pass to the client.
      * </p>
      * <p>
      * The location option is the URL of the remote Web service.
      * </p>
      * <p>
      * The uri option is the target namespace of the SOAP service.
      * </p>
      * <p>
      * The soapaction option is the action to call.
      * </p>
      * @param mixed $input_headers [optional] <p>
      * An array of headers to be sent along with the SOAP request.
      * </p>
      * @param array $output_headers [optional] <p>
      * If supplied, this array will be filled with the headers from the SOAP response.
      * </p>
      * @return mixed SOAP functions may return one, or multiple values. If only one value is returned
      * by the SOAP function, the return value of __soapCall will be
      * a simple value (e.g. an integer, a string, etc). If multiple values are
      * returned, __soapCall will return
      * an associative array of named output parameters.
      * </p>
      * <p>
      * On error, if the SoapClient object was constructed with the exceptions
      * option set to <b>FALSE</b>, a SoapFault object will be returned.
      * @since 5.0.1
      */
     public function __soapCall (string $function_name, array $arguments, array $options = null, $input_headers = null, &$output_headers = null) {}

     /**
      * Returns last SOAP request
      * @link https://php.net/manual/en/soapclient.getlastrequest.php
      * @return string|null The last SOAP request, as an XML string.
      * @since 5.0.1
      */
     public function __getLastRequest () {}

     /**
      * Returns last SOAP response
      * @link https://php.net/manual/en/soapclient.getlastresponse.php
      * @return string|null The last SOAP response, as an XML string.
      * @since 5.0.1
      */
     public function __getLastResponse () {}

     /**
      * Returns the SOAP headers from the last request
      * @link https://php.net/manual/en/soapclient.getlastrequestheaders.php
      * @return string|null The last SOAP request headers.
      * @since 5.0.1
      */
     public function __getLastRequestHeaders () {}

     /**
      * Returns the SOAP headers from the last response
      * @link https://php.net/manual/en/soapclient.getlastresponseheaders.php
      * @return string|null The last SOAP response headers.
      * @since 5.0.1
      */
     public function __getLastResponseHeaders () {}

     /**
      * Returns list of available SOAP functions
      * @link https://php.net/manual/en/soapclient.getfunctions.php
      * @return array|null The array of SOAP function prototypes, detailing the return type,
      * the function name and type-hinted parameters.
      * @since 5.0.1
      */
     public function __getFunctions () {}

     /**
      * Returns a list of SOAP types
      * @link https://php.net/manual/en/soapclient.gettypes.php
      * @return array|null The array of SOAP types, detailing all structures and types.
      * @since 5.0.1
      */
     public function __getTypes () {}

     /**
      * Returns a list of all cookies
      * @link https://php.net/manual/en/soapclient.getcookies.php
      * @return array The array of all cookies
      * @since 5.4.3
      */
     public function __getCookies () {}

     /**
      * The __setCookie purpose
      * @link https://php.net/manual/en/soapclient.setcookie.php
      * @param string $name <p>
      * The name of the cookie.
      * </p>
      * @param string $value [optional] <p>
      * The value of the cookie. If not specified, the cookie will be deleted.
      * </p>
      * @return void No value is returned.
      * @since 5.0.4
      */
     public function __setCookie ($name, $value = null) {}

     /**
      * Sets the location of the Web service to use
      * @link https://php.net/manual/en/soapclient.setlocation.php
      * @param string $new_location [optional] <p>
      * The new endpoint URL.
      * </p>
      * @return string The old endpoint URL.
      * @since 5.0.1
      */
     public function __setLocation ($new_location = null) {}

     /**
      * Sets SOAP headers for subsequent calls
      * @link https://php.net/manual/en/soapclient.setsoapheaders.php
      * @param mixed $soapheaders [optional] <p>
      * The headers to be set. It could be <b>SoapHeader</b>
      * object or array of <b>SoapHeader</b> objects.
      * If not specified or set to <b>NULL</b>, the headers will be deleted.
      * </p>
      * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
      * @since 5.0.5
      */
     public function __setSoapHeaders ($soapheaders = null) {}

}

class SoapFault extends Exception {
    /**
     * @param array|string|null $code
     */
    public function __construct(
        $code,
        string $string,
        ?string $actor = null,
        mixed $details = null,
        ?string $name = null,
        mixed $headerFault = null
    ) {}
}

class SoapHeader {
    public function __construct(
        string $namespace,
        string $name,
        // Actually doesn't have a default, not specifying results in no SoapHeader::$data property. Specifying null
        // results in a SoapHeader::$data property with null as the value. This probably makes no difference.
        mixed $data = null,
        bool $mustUnderstand = false,
        // Same as $data, no default. The documentation specifies this as a `string` but it accepts null.
        ?string $actor = null
    ) {}
}
<?php

/**
 * @template TValue
 *
 * @template-implements Traversable<int, TValue>
 */
class mysqli_result implements Traversable
{
    /**
     * @psalm-taint-sink callable $class
     *
     * @template T of object
     * @param class-string<T> $class
     * @param array $constructor_args
     * @return T|null|false
     */
    function fetch_object(string $class = stdClass::class, array $constructor_args = []): object|false|null {}
}


/**
 * @psalm-taint-sink callable $class
 *
 * @template T of object
 * @template TValue
 *
 * @param mysqli_result<TValue> $result
 * @param class-string<T> $class
 * @param array $constructor_args
 * @return T|null|false
 */
function mysqli_fetch_object(mysqli_result $result, string $class = stdClass::class, array $constructor_args = []): object|false|null {}
<?php

define('GEOSBUF_CAP_ROUND', 1);
define('GEOSBUF_CAP_FLAT', 2);
define('GEOSBUF_CAP_SQUARE', 3);
define('GEOSBUF_JOIN_ROUND', 1);
define('GEOSBUF_JOIN_MITRE', 2);
define('GEOSBUF_JOIN_BEVEL', 3);

define('GEOS_POINT', 0);
define('GEOS_LINESTRING', 1);
define('GEOS_LINEARRING', 2);
define('GEOS_POLYGON', 3);
define('GEOS_MULTIPOINT', 4);
define('GEOS_MULTILINESTRING', 5);
define('GEOS_MULTIPOLYGON', 6);
define('GEOS_GEOMETRYCOLLECTION', 7);

define('GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE', 1);

define('GEOSRELATE_BNR_MOD2', 1);
define('GEOSRELATE_BNR_OGC', 1);
define('GEOSRELATE_BNR_ENDPOINT', 2);
define('GEOSRELATE_BNR_MULTIVALENT_ENDPOINT', 3);
define('GEOSRELATE_BNR_MONOVALENT_ENDPOINT', 4);
<?php

namespace Ds;

use ArrayAccess;
use Countable;
use JsonSerializable;
use OutOfBoundsException;
use OutOfRangeException;
use Traversable;
use UnderflowException;

/**
 * @template-covariant TKey
 * @template-covariant TValue
 * @extends Traversable<TKey, TValue>
 */
interface Collection extends Traversable, Countable, JsonSerializable
{
    /**
     * @return Collection<TKey, TValue>
     * @psalm-mutation-free
     */
    public function copy(): Collection;

    /**
     * @return array<TKey, TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array;

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool;

    /**
     * @psalm-mutation-free
     */
    public function count(): int;
}

/**
 * @template TValue
 * @implements Sequence<TValue>
 */
final class Deque implements Sequence
{
    /**
     * @param iterable<TValue> $values
     */
    public function __construct(iterable $values = [])
    {
    }

    /**
     * @return Deque<TValue>
     * @psalm-mutation-free
     */
    public function copy(): Deque
    {
    }

    /**
     * @return list<TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function count(): int
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int
    {
    }

    /**
     * @return float|int
     * @psalm-mutation-free
     */
    public function sum()
    {
    }

    /**
     * @param TValue ...$values
     * @psalm-mutation-free
     */
    public function contains(...$values): bool
    {
    }

    /**
     * @param (callable(TValue): bool)|null $callback
     * @return Deque<TValue>
     * @psalm-mutation-free
     */
    public function filter(callable $callback = null): Deque
    {
    }

    /**
     * @param TValue $value
     * @return int|false
     * @psalm-mutation-free
     */
    public function find($value)
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function first()
    {
    }

    /**
     * @return TValue
     * @throws \OutOfRangeException
     * @psalm-mutation-free
     */
    public function get(int $index)
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function join(?string $glue = null): string
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function last()
    {
    }

    /**
     * @template TNewValue
     * @param callable(TValue): TNewValue $callback
     * @return Deque<TNewValue>
     * @psalm-mutation-free
     */
    public function map(callable $callback): Deque
    {
    }

    /**
     * @template TValue2
     * @param iterable<TValue2> $values
     * @return Deque<TValue|TValue2>
     * @psalm-mutation-free
     */
    public function merge(iterable $values): Deque
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     */
    public function pop()
    {
    }

    /**
     * @template TCarry
     * @param callable(TCarry, TValue): TCarry $callback
     * @param TCarry $initial
     * @return TCarry
     * @psalm-mutation-free
     */
    public function reduce(callable $callback, $initial = null)
    {
    }

    /**
     * @return TValue
     * @throws \OutOfRangeException
     */
    public function remove(int $index)
    {
    }

    /**
     * @return Deque<TValue>
     * @psalm-mutation-free
     */
    public function reversed(): Deque
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     */
    public function shift()
    {
    }

    /**
     * @return Deque<TValue>
     * @psalm-mutation-free
     */
    public function slice(int $offset, ?int $length = null): Deque
    {
    }

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     * @return Deque<TValue>
     * @psalm-mutation-free
     */
    public function sorted(callable $comparator = null): Deque
    {
    }
}

/**
 * @template TKey
 * @template TValue
 * @implements Collection<TKey, TValue>
 * @implements ArrayAccess<TKey, TValue>
 */
final class Map implements Collection, ArrayAccess
{
    /**
     * @param iterable<TKey, TValue> $values
     */
    public function __construct(iterable $values = [])
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int
    {
    }

    /**
     * @return Map<TKey, TValue>
     * @psalm-mutation-free
     */
    public function copy(): Map
    {
    }

    /**
     * @return array<TKey, TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function count(): int
    {
    }

    /**
     * @param callable(TKey, TValue): TValue $callback
     */
    public function apply(callable $callback): void
    {
    }

    /**
     * @return Pair<TKey, TValue>
     * @throws UnderflowException
     * @psalm-mutation-free
     */
    public function first(): Pair
    {
    }

    /**
     * @return Pair<TKey, TValue>
     * @throws UnderflowException
     * @psalm-mutation-free
     */
    public function last(): Pair
    {
    }

    /**
     * @return Pair<TKey, TValue>
     * @throws OutOfRangeException
     * @psalm-mutation-free
     */
    public function skip(int $position): Pair
    {
    }

    /**
     * @template TKey2
     * @template TValue2
     * @param iterable<TKey2, TValue2> $values
     * @return Map<TKey|TKey2, TValue|TValue2>
     * @psalm-mutation-free
     */
    public function merge(iterable $values): Map
    {
    }

    /**
     * @template TKey2
     * @template TValue2
     * @param Map<TKey2, TValue2> $map
     * @return Map<TKey&TKey2, TValue>
     * @psalm-mutation-free
     */
    public function intersect(Map $map): Map
    {
    }

    /**
     * @template TValue2
     * @param Map<TKey, TValue2> $map
     * @return Map<TKey, TValue>
     * @psalm-mutation-free
     */
    public function diff(Map $map): Map
    {
    }

    /**
     * @param TKey $key
     * @psalm-mutation-free
     */
    public function hasKey($key): bool
    {
    }

    /**
     * @param TValue $value
     * @psalm-mutation-free
     */
    public function hasValue($value): bool
    {
    }

    /**
     * @param (callable(TKey, TValue): bool)|null $callback
     * @return Map<TKey, TValue>
     * @psalm-mutation-free
     */
    public function filter(callable $callback = null): Map
    {
    }

    /**
     * @template TDefault
     * @param TKey $key
     * @param TDefault $default
     * @return (
     *     func_num_args() is 1
     *     ? TValue
     *     : TValue|TDefault
     * )
     * @throws OutOfBoundsException
     * @psalm-mutation-free
     */
    public function get($key, $default = null)
    {
    }

    /**
     * @return Set<TKey>
     * @psalm-mutation-free
     */
    public function keys(): Set
    {
    }

    /**
     * @template TNewValue
     * @param callable(TKey, TValue): TNewValue $callback
     * @return Map<TKey, TNewValue>
     * @psalm-mutation-free
     */
    public function map(callable $callback): Map
    {
    }

    /**
     * @return Sequence<Pair<TKey, TValue>>
     * @psalm-mutation-free
     */
    public function pairs(): Sequence
    {
    }

    /**
     * @param TKey $key
     * @param TValue $value
     */
    public function put($key, $value)
    {
    }

    /**
     * @param iterable<TKey, TValue> $values
     */
    public function putAll(iterable $values)
    {
    }

    /**
     * @template TCarry
     * @param callable(TCarry, TKey, TValue): TCarry $callback
     * @param TCarry $initial
     * @return TCarry
     * @psalm-mutation-free
     */
    public function reduce(callable $callback, $initial = null)
    {
    }

    /**
     * @template TDefault
     * @param TKey $key
     * @param TDefault $default
     * @return (
     *     func_num_args() is 1
     *     ? TValue
     *     : TValue|TDefault
     * )
     * @throws \OutOfBoundsException
     */
    public function remove($key, $default = null)
    {
    }

    /**
     * @return Map<TKey, TValue>
     * @psalm-mutation-free
     */
    public function reversed(): Map
    {
    }

    /**
     * @return Map<TKey, TValue>
     * @psalm-mutation-free
     */
    public function slice(int $offset, ?int $length = null): Map
    {
    }

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     */
    public function sort(callable $comparator = null)
    {
    }

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     * @return Map<TKey, TValue>
     * @psalm-mutation-free
     */
    public function sorted(callable $comparator = null): Map
    {
    }

    /**
     * @param (callable(TKey, TKey): int)|null $comparator
     */
    public function ksort(callable $comparator = null)
    {
    }

    /**
     * @param (callable(TKey, TKey): int)|null $comparator
     * @return Map<TKey, TValue>
     * @psalm-mutation-free
     */
    public function ksorted(callable $comparator = null): Map
    {
    }

    /**
     * @return Sequence<TValue>
     * @psalm-mutation-free
     */
    public function values(): Sequence
    {
    }

    /**
     * @template TKey2
     * @template TValue2
     * @param Map<TKey2, TValue2> $map
     * @return Map<TKey|TKey2, TValue|TValue2>
     * @psalm-mutation-free
     */
    public function union(Map $map): Map
    {
    }

    /**
     * @template TKey2
     * @template TValue2
     * @param Map<TKey2, TValue2> $map
     * @return Map<TKey|TKey2, TValue|TValue2>
     * @psalm-mutation-free
     */
    public function xor(Map $map): Map
    {
    }
}

/**
 * @template-covariant TKey
 * @template-covariant TValue
 */
final class Pair implements JsonSerializable
{
    /**
     * @var TKey
     */
    public $key;

    /**
     * @var TValue
     */
    public $value;

    /**
     * @param TKey $key
     * @param TValue $value
     */
    public function __construct($key = null, $value = null)
    {
    }

    /**
     * @return Pair<TKey, TValue>
     * @psalm-mutation-free
     */
    public function copy(): Pair
    {
    }
}

/**
 * @template TValue
 * @extends Collection<int, TValue>
 * @extends ArrayAccess<int, TValue>
 */
interface Sequence extends Collection, ArrayAccess
{
    /**
     * @return Sequence<TValue>
     * @psalm-mutation-free
     */
    public function copy(): Sequence;

    /**
     * @return list<TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array;

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool;

    /**
     * @psalm-mutation-free
     */
    public function count(): int;

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void;

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int;

    /**
     * @return float|int
     * @psalm-mutation-free
     */
    public function sum();

    /**
     * @param callable(TValue): TValue $callback
     */
    public function apply(callable $callback): void;

    /**
     * @param TValue ...$values
     * @psalm-mutation-free
     */
    public function contains(...$values): bool;

    /**
     * @param (callable(TValue): bool)|null $callback
     * @return Sequence<TValue>
     * @psalm-mutation-free
     */
    public function filter(callable $callback = null): Sequence;

    /**
     * @param TValue $value
     * @return int|false
     * @psalm-mutation-free
     */
    public function find($value);

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function first();

    /**
     * @return TValue
     * @throws \OutOfRangeException
     * @psalm-mutation-free
     */
    public function get(int $index);

    /**
     * @param TValue ...$values
     * @throws \OutOfRangeException
     */
    public function insert(int $index, ...$values);

    /**
     * @psalm-mutation-free
     */
    public function join(?string $glue = null): string;

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function last();

    /**
     * @template TNewValue
     * @param callable(TValue): TNewValue $callback
     * @return Sequence<TNewValue>
     * @psalm-mutation-free
     */
    public function map(callable $callback): Sequence;

    /**
     * @template TValue2
     * @param iterable<TValue2> $values
     * @return Sequence<TValue|TValue2>
     * @psalm-mutation-free
     */
    public function merge(iterable $values): Sequence;

    /**
     * @return TValue
     * @throws \UnderflowException
     */
    public function pop();

    /**
     * @param TValue ...$values
     */
    public function push(...$values);

    /**
     * @template TCarry
     * @param callable(TCarry, TValue): TCarry $callback
     * @param TCarry $initial
     * @return TCarry
     * @psalm-mutation-free
     */
    public function reduce(callable $callback, $initial = null);

    /**
     * @return TValue
     * @throws \OutOfRangeException
     */
    public function remove(int $index);

    /**
     * @return Sequence<TValue>
     * @psalm-mutation-free
     */
    public function reversed(): Sequence;

    /**
     * @param TValue $value
     * @throws \OutOfRangeException
     */
    public function set(int $index, $value);

    /**
     * @return TValue
     * @throws \UnderflowException
     */
    public function shift();

    /**
     * @return Sequence<TValue>
     * @psalm-mutation-free
     */
    public function slice(int $index, ?int $length = null): Sequence;

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     */
    public function sort(callable $comparator = null);

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     * @return Sequence<TValue>
     * @psalm-mutation-free
     */
    public function sorted(callable $comparator = null): Sequence;

    /**
     * @param TValue ...$values
     */
    public function unshift(...$values);
}


/**
 * @template TValue
 * @implements Sequence<TValue>
 */
final class Vector implements Sequence
{
    /**
     * @param iterable<TValue> $values
     */
    public function __construct(iterable $values = [])
    {
    }

    /**
     * @return Vector<TValue>
     * @psalm-mutation-free
     */
    public function copy(): Vector
    {
    }

    /**
     * @return list<TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function count(): int
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int
    {
    }

    /**
     * @return float|int
     * @psalm-mutation-free
     */
    public function sum()
    {
    }

    /**
     * @param TValue ...$values
     * @psalm-mutation-free
     */
    public function contains(...$values): bool
    {
    }

    /**
     * @param (callable(TValue): bool)|null $callback
     * @return Vector<TValue>
     * @psalm-mutation-free
     */
    public function filter(callable $callback = null): Vector
    {
    }

    /**
     * @param TValue $value
     * @return int|false
     * @psalm-mutation-free
     */
    public function find($value)
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function first()
    {
    }

    /**
     * @return TValue
     * @throws \OutOfRangeException
     * @psalm-mutation-free
     */
    public function get(int $index)
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function join(?string $glue = null): string
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function last()
    {
    }

    /**
     * @template TNewValue
     * @param callable(TValue): TNewValue $callback
     * @return Vector<TNewValue>
     * @psalm-mutation-free
     */
    public function map(callable $callback): Vector
    {
    }

    /**
     * @template TValue2
     * @param iterable<TValue2> $values
     * @return Vector<TValue|TValue2>
     * @psalm-mutation-free
     */
    public function merge(iterable $values): Sequence
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     */
    public function pop()
    {
    }

    /**
     * @template TCarry
     * @param callable(TCarry, TValue): TCarry $callback
     * @param TCarry $initial
     * @return TCarry
     * @psalm-mutation-free
     */
    public function reduce(callable $callback, $initial = null)
    {
    }

    /**
     * @return TValue
     * @throws \OutOfRangeException
     */
    public function remove(int $index)
    {
    }

    /**
     * @return Vector<TValue>
     * @psalm-mutation-free
     */
    public function reversed(): Vector
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     */
    public function shift()
    {
    }

    /**
     * @return Vector<TValue>
     * @psalm-mutation-free
     */
    public function slice(int $offset, ?int $length = null): Vector
    {
    }

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     * @return Vector<TValue>
     * @psalm-mutation-free
     */
    public function sorted(callable $comparator = null): Vector
    {
    }
}

/**
 * @template TValue
 * @implements Collection<int, TValue>
 * @implements ArrayAccess<int, TValue>
 */
final class Set implements Collection, ArrayAccess
{
    /**
     * @param iterable<TValue> $values
     */
    public function __construct(iterable $values = [])
    {
    }

    /**
     * @return Set<TValue>
     * @psalm-mutation-free
     */
    public function copy(): Set
    {
    }

    /**
     * @return list<TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function count(): int
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int
    {
    }

    /**
     * @param TValue ...$values
     */
    public function add(...$values): void
    {
    }

    /**
     * @param TValue ...$values
     * @psalm-mutation-free
     */
    public function contains(...$values): bool
    {
    }

    /**
     * @template TValue2
     * @param Set<TValue2> $set
     * @return Set<TValue>
     * @psalm-mutation-free
     */
    public function diff(Set $set): Set
    {
    }

    /**
     * @param (callable(TValue): bool)|null $callback
     * @return Set<TValue>
     * @psalm-mutation-free
     */
    public function filter(callable $callback = null): Set
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function first()
    {
    }

    /**
     * @return TValue
     * @throws \OutOfRangeException
     * @psalm-mutation-free
     */
    public function get(int $index)
    {
    }

    /**
     * @template TValue2
     * @param Set<TValue2> $set
     * @return Set<TValue&TValue2>
     * @psalm-mutation-free
     */
    public function intersect(Set $set): Set
    {
    }

    /**
     * @return TValue
     * @throws \UnderflowException
     * @psalm-mutation-free
     */
    public function last()
    {
    }

    /**
     * @template TNewValue
     * @param callable(TValue): TNewValue $callback
     * @return Set<TNewValue>
     */
    public function map(callable $callback): Set
    {
    }

    /**
     * @template TValue2
     * @param iterable<TValue2> $values
     * @return Set<TValue|TValue2>
     * @psalm-mutation-free
     */
    public function merge(iterable $values): Set
    {
    }

    /**
     * @param TValue ...$values
     */
    public function remove(...$values): void
    {
    }

    /**
     * @return Set<TValue>
     * @psalm-mutation-free
     */
    public function reversed(): Set
    {
    }

    /**
     * @return Set<TValue>
     * @psalm-mutation-free
     */
    public function slice(int $index, ?int $length = null): Set
    {
    }

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     */
    public function sort(callable $comparator = null): void
    {
    }

    /**
     * @param (callable(TValue, TValue): int)|null $comparator
     * @return Set<TValue>
     * @psalm-mutation-free
     */
    public function sorted(callable $comparator = null): Set
    {
    }

    /**
     * @template TValue2
     * @param Set<TValue2> $set
     * @return Set<TValue|TValue2>
     * @psalm-mutation-free
     */
    public function union(Set $set): Set
    {
    }

    /**
     * @template TValue2
     * @param Set<TValue2> $set
     * @return Set<TValue|TValue2>
     * @psalm-mutation-free
     */
    public function xor(Set $set): Set
    {
    }
}

/**
 * @template TValue
 * @implements Collection<int, TValue>
 * @implements ArrayAccess<int, TValue>
 */
final class Stack implements Collection, ArrayAccess
{
    /**
     * @param iterable<TValue> $values
     */
    public function __construct(iterable $values = [])
    {
    }

    /**
     * @return Stack<TValue>
     * @psalm-mutation-free
     */
    public function copy(): Stack
    {
    }

    /**
     * @return list<TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function count(): int
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int
    {
    }

    /**
     * @return TValue
     * @throws UnderflowException
     * @psalm-mutation-free
     */
    public function peek()
    {
    }

    /**
     * @return TValue
     * @throws UnderflowException
     */
    public function pop()
    {
    }

    /**
     * @param TValue ...$values
     */
    public function push(...$values): void
    {
    }
}

/**
 * @template TValue
 * @implements Collection<int, TValue>
 * @implements ArrayAccess<int, TValue>
 */
final class Queue implements Collection, ArrayAccess
{
    /**
     * @param iterable<TValue> $values
     */
    public function __construct(iterable $values = [])
    {
    }

    /**
     * @return Queue<TValue>
     * @psalm-mutation-free
     */
    public function copy(): Queue
    {
    }

    /**
     * @return list<TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function count(): int
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int
    {
    }

    /**
     * @return TValue
     * @throws UnderflowException
     * @psalm-mutation-free
     */
    public function peek()
    {
    }

    /**
     * @return TValue
     * @throws UnderflowException
     */
    public function pop()
    {
    }

    /**
     * @param TValue ...$values
     */
    public function push(...$values): void
    {
    }
}

/**
 * @template TValue
 * @implements Collection<int, TValue>
 */
final class PriorityQueue implements Collection
{
    /**
     * @return PriorityQueue<TValue>
     * @psalm-mutation-free
     */
    public function copy(): PriorityQueue
    {
    }

    /**
     * @return list<TValue>
     * @psalm-mutation-free
     */
    public function toArray(): array
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function isEmpty(): bool
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function count(): int
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function allocate(int $capacity): void
    {
    }

    /**
     * @psalm-mutation-free
     */
    public function capacity(): int
    {
    }

    /**
     * @return TValue
     * @throws UnderflowException
     * @psalm-mutation-free
     */
    public function peek()
    {
    }

    /**
     * @return TValue
     * @throws UnderflowException
     */
    public function pop()
    {
    }

    /**
     * @param TValue $value
     */
    public function push($value, int $priority): void
    {
    }
}
<?php

class PDO
{
    public const PARAM_NULL = 0;
    public const PARAM_INT = 1;
    public const PARAM_STR = 2;
    public const PARAM_LOB = 3;
    public const PARAM_STMT = 4;
    public const PARAM_BOOL = 5;
    // public const PARAM_STR_NATL = 1073741824; since 7.2
    // public const PARAM_STR_CHAR = 536870912; since 7.2
    public const PARAM_INPUT_OUTPUT = 2147483648;
    // public const FETCH_DEFAULT = 0; since 8.0.7
    public const FETCH_LAZY = 1;
    public const FETCH_ASSOC = 2;
    public const FETCH_NAMED = 11;
    public const FETCH_NUM = 3;
    public const FETCH_BOTH = 4;
    public const FETCH_OBJ = 5;
    public const FETCH_BOUND = 6;
    public const FETCH_COLUMN = 7;
    public const FETCH_CLASS = 8;
    public const FETCH_INTO = 9;
    public const FETCH_FUNC = 10;
    public const FETCH_GROUP = 65536;
    public const FETCH_UNIQUE = 196608;
    public const FETCH_KEY_PAIR = 12;
    public const FETCH_CLASSTYPE = 262144;
    public const FETCH_SERIALIZE = 524288; // Deprecated 8.1
    public const FETCH_PROPS_LATE = 1048576;
    public const ATTR_AUTOCOMMIT = 0;
    public const ATTR_PREFETCH = 1;
    public const ATTR_TIMEOUT = 2;
    public const ATTR_ERRMODE = 3;
    public const ATTR_SERVER_VERSION = 4;
    public const ATTR_CLIENT_VERSION = 5;
    public const ATTR_SERVER_INFO = 6;
    public const ATTR_CONNECTION_STATUS = 7;
    public const ATTR_CASE = 8;
    public const ATTR_CURSOR_NAME = 9;
    public const ATTR_CURSOR = 10;
    public const ATTR_DRIVER_NAME = 16;
    public const ATTR_ORACLE_NULLS = 11;
    public const ATTR_PERSISTENT = 12;
    public const ATTR_STATEMENT_CLASS = 13;
    public const ATTR_FETCH_CATALOG_NAMES = 15;
    public const ATTR_FETCH_TABLE_NAMES = 14;
    public const ATTR_STRINGIFY_FETCHES = 17;
    public const ATTR_MAX_COLUMN_LEN = 18;
    public const ATTR_DEFAULT_FETCH_MODE = 19;
    public const ATTR_EMULATE_PREPARES = 20;
    // public const ATTR_DEFAULT_STR_PARAM = 21; since 7.2
    public const ERRMODE_SILENT = 0;
    public const ERRMODE_WARNING = 1;
    public const ERRMODE_EXCEPTION = 2;
    public const CASE_NATURAL = 0;
    public const CASE_LOWER = 2;
    public const CASE_UPPER = 1;
    public const NULL_NATURAL = 0;
    public const NULL_EMPTY_STRING = 1;
    public const NULL_TO_STRING = 2;
    public const FETCH_ORI_NEXT = 0;
    public const FETCH_ORI_PRIOR = 1;
    public const FETCH_ORI_FIRST = 2;
    public const FETCH_ORI_LAST = 3;
    public const FETCH_ORI_ABS = 4;
    public const FETCH_ORI_REL = 5;
    public const CURSOR_FWDONLY = 0;
    public const CURSOR_SCROLL = 1;
    public const ERR_NONE = 00000;
    public const PARAM_EVT_ALLOC = 0;
    public const PARAM_EVT_FREE = 1;
    public const PARAM_EVT_EXEC_PRE = 2;
    public const PARAM_EVT_EXEC_POST = 3;
    public const PARAM_EVT_FETCH_PRE = 4;
    public const PARAM_EVT_FETCH_POST = 5;
    public const PARAM_EVT_NORMALIZE = 6;
    // public const SQLITE_DETERMINISTIC = ???; since 7.1.4 with pdo_sqlite

    public function __construct(
        string $dsn,
        ?string $username = null,
        ?string $password = null,
        ?array $options = null
    ) {}

    public function beginTransaction(): bool {}

    public function commit(): bool {}

    public function errorCode(): ?string {}

    public function errorInfo(): array {}

    /**
     * @psalm-taint-sink sql $statement
     *
     * @return int|false
     */
    public function exec(string $statement) {}

    /** @return bool|int|string|array|null */
    public function getAttribute(int $attribute) {}

    public static function getAvailableDrivers(): array {}

    public function inTransaction(): bool {}

    /** @return string|false */
    public function lastInsertId(?string $name = null) {}

    /**
     * @psalm-taint-sink sql $query
     *
     * @return PDOStatement|false
     */
    public function prepare(string $query, array $options = []) {}

    /**
     * @psalm-taint-sink sql $query
     *
     * @return PDOStatement|false
     */
    public function query(string $query, ?int $fetchMode = null) {}

    /**
     * @return string|false
     */
    public function quote(string $string, int $type = PDO::PARAM_STR) {}

    public function rollBack(): bool {}

    public function setAttribute(int $attribute, mixed $value): bool {}
}

/**
 * @template TValue
 *
 * @template-implements Traversable<int, TValue>
 */
class PDOStatement implements Traversable
{
    /**
     * @psalm-taint-sink callable $class
     *
     * @template T of object
     * @param class-string<T> $class
     * @param array $ctorArgs
     * @return false|T
     */
    public function fetchObject($class = \stdclass::class, array $ctorArgs = array()) {}
}

 class PDOException extends RuntimeException {
    protected string $code;
    public ?array $errorInfo = null;
}
<?php

namespace MongoDB\Driver;

use Iterator;
use Traversable;

/**
 * @template-covariant TKey
 * @template-covariant TValue
 *
 * @template-extends Traversable<TKey, TValue>
 */
interface CursorInterface extends Traversable
{
    /**
     * @return array<TValue>
     */
    public function toArray();
}

/**
 * @template-covariant TValue of array|object
 *
 * @template-implements Iterator<int, TValue>
 * @template-implements CursorInterface<int, TValue>
 */
final class Cursor implements CursorInterface, Iterator
{
    /**
     * @return TValue
     */
    public function current() {}

    /**
     * @return void
     */
    public function next() {}

    /**
     * @return int
     */
    public function key() {}

    /**
     * @return bool
     */
    public function valid() {}

    /**
     * @return void
     */
    public function rewind() {}

    /**
     * @return array<TValue>
     */
    public function toArray() {}
}
<?php

/**
 * PHP 8.2 introduces a new PHP extension named "random".
 * @see https://github.com/php/php-src/blob/master/ext/random/random.stub.php
 * @see https://php.watch/versions/8.2/ext-random
 */

namespace Random\Engine
{
    final class Mt19937 implements \Random\Engine
    {
        public function __construct(int|null $seed = null, int $mode = MT_RAND_MT19937) {}

        /** @return non-empty-string */
        public function generate(): string {}

        public function __serialize(): array {}

        public function __unserialize(array $data): void {}

        public function __debugInfo(): array {}
    }

    final class PcgOneseq128XslRr64 implements \Random\Engine
    {
        public function __construct(string|int|null $seed = null) {}

        public function generate(): string {}

        public function jump(int $advance): void {}

        public function __serialize(): array {}

        public function __unserialize(array $data): void {}

        public function __debugInfo(): array {}
    }

    final class Xoshiro256StarStar implements \Random\Engine
    {
        public function __construct(string|int|null $seed = null) {}

        public function generate(): string {}

        public function jump(): void {}

        public function jumpLong(): void {}

        public function __serialize(): array {}

        public function __unserialize(array $data): void {}

        public function __debugInfo(): array {}
    }

    final class Secure implements \Random\CryptoSafeEngine
    {
        public function generate(): string {}
    }
}

namespace Random
{
    interface Engine
    {
        public function generate(): string;
    }

    interface CryptoSafeEngine extends Engine
    {
    }

    final class Randomizer
    {
        public readonly Engine $engine;

        public function __construct(?Engine $engine = null) {}

        public function nextInt(): int {}

        public function getInt(int $min, int $max): int {}

        /**
         * @param positive-int $length
         * @return non-empty-string
         */
        public function getBytes(int $length): string {}

        public function shuffleArray(array $array): array {}

        public function shuffleBytes(string $bytes): string {}

        public function pickArrayKeys(array $array, int $num): array {}

        public function __serialize(): array {}

        public function __unserialize(array $data): void {}
    }

    class RandomError extends \Error
    {
    }

    class BrokenRandomEngineError extends RandomError
    {
    }

    class RandomException extends \Exception
    {
    }
}
<?php

/**
 * @see https://github.com/phpredis/phpredis/blob/develop/redis.stub.php
 * @see https://github.com/phpredis/phpredis/blob/develop/redis_array.stub.php
 * @see https://github.com/phpredis/phpredis/blob/develop/redis_cluster.stub.php
 * @see https://github.com/phpredis/phpredis/blob/develop/redis_sentinel.stub.php
 */

class Redis {

    public function __construct(array $options = null) {}

    public function _compress(string $value): string {}

    public function __destruct() {}

    public function _pack(mixed $value): string {}

    public function _prefix(string $key): string {}

    public function _serialize(mixed $value): string {}

    public function _uncompress(string $value): string {}

    public function _unpack(string $value): mixed {}

    public function _unserialize(string $value): mixed {}

    /**
     * @param string $args
     * @return mixed|Redis
     */
    public function acl(string $subcmd, ...$args) {}

	/** @return false|int|Redis */
    public function append(string $key, string $value) {}

    public function auth(mixed $credentials): bool {}

    public function bgSave(): bool {}

    public function bgrewriteaof(): bool {}

    /** @return false|int|Redis */
    public function bitcount(string $key, int $start = 0, int $end = -1) {}

    /**
     * @return false|int|Redis
     */
    public function bitop(string $operation, string $deskey, string $srckey, string ...$other_keys): int {}

    /** @return false|int|Redis */
    public function bitpos(string $key, int $bit, int $start = 0, int $end = -1) {}

    public function blPop(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array|null|false {}

    public function brPop(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array|null|false {}

    public function brpoplpush(string $src, string $dst, int $timeout): Redis|string|false {}

    public function bzPopMax(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array|false {}

    public function bzPopMin(string|array $key, string|int $timeout_or_key, mixed ...$extra_args): array|false {}

    public function clearLastError(): bool {}

    public function client(string $opt, string $arg = null): mixed {}

    public function close(): bool {}

    public function command(string $opt = null, string|array $arg): mixed {}

    public function config(string $operation, string $key, mixed $value = null): mixed {}

    public function connect(string $host, int $port = 6379, float $timeout = 0, string $persistent_id = null, int $retry_interval = 0, float $read_timeout = 0, array $context = null): bool {}

    public function copy(string $src, string $dst, array $options = null): bool {}

    public function dbSize(): int {}

    public function debug(string $key): string {}

	/** @return false|int|Redis */
    public function decr(string $key, int $by = 1) {}

	/** @return false|int|Redis */
    public function decrBy(string $key, int $value) {}

    /**
     * @return false|int|Redis
     */
    public function del(array|string $key, string ...$other_keys) {}

    /**
     * @deprecated
     * @alias Redis::del
     * @return false|int|Redis
     */
    public function delete(array|string $key, string ...$other_keys) {}

    public function discard(): bool {}

    public function dump(string $key): string {}

	/** @return false|string|Redis */
    public function echo(string $str) {}

    public function eval(string $script, array $keys = null, int $num_keys = 0): mixed {}

    public function evalsha(string $sha1, array $keys = null, int $num_keys = 0): mixed {}

    public function exec(): Redis|array|false {}

	/** @return int|Redis|bool */
    public function exists(mixed $key, mixed ...$other_keys) {}

    public function expire(string $key, int $timeout): Redis|bool {}

    public function expireAt(string $key, int $timestamp): Redis|bool {}

    public function flushAll(bool $async = false): bool {}

    public function flushDB(bool $async = false): bool {}

    public function geoadd(string $key, float $lng, float $lat, string $member, mixed ...$other_triples): int {}

    public function geodist(string $key, string $src, string $dst, ?string $unit = null): Redis|float|false {}

    public function geohash(string $key, string $member, string ...$other_members): array|false {}

    public function geopos(string $key, string $member, string ...$other_members): Redis|array|false {}

    public function georadius(string $key, float $lng, float $lat, float $radius, string $unit, array $options = []): Redis|mixed|false {}

    public function georadius_ro(string $key, float $lng, float $lat, float $radius, string $unit, array $options = []): Redis|mixed|false {}

    public function georadiusbymember(string $key, string $member, float $radius, string $unit, array $options = []): Redis|mixed|false {}

    public function georadiusbymember_ro(string $key, string $member, float $radius, string $unit, array $options = []): Redis|mixed|false {}

    public function geosearch(string $key, array|string $position, array|int|float $shape, string $unit, array $options = []): array|false {}

    public function geosearchstore(string $dst, string $src, array|string $position, array|int|float $shape, string $unit, array $options = []): array|false {}

	/** @return false|string|Redis */
    public function get(string $key) {}

    public function getAuth(): mixed {}

	/** @return false|int|Redis */
    public function getBit(string $key, int $idx) {}

    public function getDBNum(): int {}

    public function getHost(): string {}

    public function getLastError(): ?string {}

    public function getMode(): int {}

    public function getOption(int $option): mixed {}

    public function getPersistentID(): ?string {}

    public function getPort(): int {}

	/** @return false|string|Redis */
    public function getRange(string $key, int $start, int $end) {}

    public function getReadTimeout(): int {}

	/** @return false|string|Redis */
    public function getset(string $key, string $value) {}

    public function getTimeout(): int {}

    public function hDel(string $key, string $member, string ...$other_members): Redis|int|false {}

    public function hExists(string $key, string $member): Redis|bool {}

    public function hGet(string $key, string $member): Redis|mixed|false {}

    public function hGetAll(string $key): Redis|array|false {}

    public function hIncrBy(string $key, string $member, int $value): Redis|int|false {}

    public function hIncrByFloat(string $key, string $member, float $value): Redis|float|false {}

    public function hKeys(string $key): Redis|array|false {}

    public function hLen(string $key): Redis|int|false {}

    public function hMget(string $key, array $keys): Redis|array|false {}

    public function hMset(string $key, array $keyvals): Redis|bool|false {}

    public function hSet(string $key, string $member, string $value): Redis|int|false {}

    public function hSetNx(string $key, string $member, string $value): Redis|bool {}

    public function hStrLen(string $key, string $member): int {}

    public function hVals(string $key): Redis|array|false {}

    public function hscan(string $key, ?int &$iterator, ?string $pattern = null, int $count = 0): bool|array {}

	/** @return false|int|Redis */
    public function incr(string $key, int $by = 1) {}

	/** @return false|int|Redis */
    public function incrBy(string $key, int $value) {}

	/** @return false|int|Redis */
    public function incrByFloat(string $key, float $value) {}

    public function info(string $opt = null): Redis|array|false {}

    public function isConnected(): bool {}

	/** @return false|array|Redis */
    public function keys(string $pattern) {}

    /**
     * @param mixed $elements
     * @return false|int|Redis
     */
    public function lInsert(string $key, string $pos, mixed $pivot, mixed $value) {}


    public function lLen(string $key): Redis|int|false {}

    public function lMove(string $src, string $dst, string $wherefrom, string $whereto): string {}

	/** @return false|string|Redis */
    public function lPop(string $key) {}

    /**
     * @param mixed $elements
     * @return false|int|Redis
     */
    public function lPush(string $key, ...$elements) {}

    /**
     * @param mixed $elements
     * @return false|int|Redis
     */
    public function rPush(string $key, ...$elements) {}

	/** @return false|int|Redis */
    public function lPushx(string $key, string $value) {}

	/** @return false|int|Redis */
    public function rPushx(string $key, string $value) {}

    public function lSet(string $key, int $index, string $value): Redis|bool {}

    public function lastSave(): int {}

    public function lindex(string $key, int $index): Redis|mixed|false {}

    public function lrange(string $key, int $start , int $end): Redis|array|false {}

    /**
     * @return int|Redis|false
     */
    public function lrem(string $key, string $value, int $count = 0) {}

    public function ltrim(string $key, int $start , int $end): Redis|bool {}

	/** @return false|list<false|string>|Redis */
    public function mget(array $keys) {}

    public function migrate(string $host, int $port, string $key, string $dst, int $timeout, bool $copy = false, bool $replace = false): bool {}

    public function move(string $key, int $index): bool {}

    /**
     * @param array<string, string>
     */
    public function mset($key_values): Redis|bool {}

    /**
     * @param array<string, string>
     */
    public function msetnx($key_values): Redis|bool {}

    public function multi(int $value = Redis::MULTI): bool|Redis {}

    public function object(string $subcommand, string $key): Redis|int|string|false {}

    /**
     * @deprecated
     * @alias Redis::connect
     */
    public function open(string $host, int $port = 6379, float $timeout = 0, string $persistent_id = NULL, int $retry_interval = 0, float $read_timeout = 0, array $context = NULL): bool {}

    public function pconnect(string $host, int $port = 6379, float $timeout = 0, string $persistent_id = NULL, int $retry_interval = 0, float $read_timeout = 0, array $context = NULL): bool {}

    public function persist(string $key): bool {}

    public function pexpire(string $key, int $timeout): bool {}

    public function pexpireAt(string $key, int $timestamp): bool {}

    public function pfadd(string $key, array $elements): int {}

    public function pfcount(string $key): int {}

    public function pfmerge(string $dst, array $keys): bool {}

	/** @return false|string|Redis */
    public function ping(string $key = NULL) {}

    public function pipeline(): bool|Redis {}

    /**
     * @deprecated
     * @alias Redis::pconnect
     */
    public function popen(string $host, int $port = 6379, float $timeout = 0, string $persistent_id = NULL, int $retry_interval = 0, float $read_timeout = 0, array $context = NULL): bool {}

    /** @return bool|Redis */
    public function psetex(string $key, int $expire, string $value) {}

    public function psubscribe(array $patterns): void {}

    public function pttl(string $key): Redis|int|false {}

    public function publish(string $channel, string $message): mixed {}

    public function pubsub(string $command, mixed $arg = null): mixed {}

    public function punsubscribe(array $patterns): array|false {}

	/** @return false|string|Redis */
    public function rPop(string $key) {}

	/** @return false|string|Redis */
    public function randomKey() {}

    public function rawcommand(string $command, mixed ...$args): mixed {}

	/** @return bool|Redis */
    public function rename(string $key_src, string $key_dst) {}

	/** @return bool|Redis */
    public function renameNx(string $key_src, string $key_dst) {}

    public function restore(string $key, int $timeout, string $value): bool {}

    public function role(): mixed {}

    public function rpoplpush(string $src, string $dst): Redis|string|false {}

    public function sAdd(string $key, string $value, mixed ...$other_values): Redis|int|false {}

    public function sAddArray(string $key, array $values): int {}

    public function sDiff(string $key, string ...$other_keys): Redis|array|false {}

    public function sDiffStore(string $dst, string $key, string ...$other_keys): Redis|int|false {}

    public function sInter(array|string $key, string ...$other_keys): Redis|array|false {}

    public function sInterStore(array|string $key, string ...$other_keys): Redis|int|false {}

    public function sMembers(string $key): Redis|array|false {}

    public function sMisMember(string $key, string $member, string ...$other_members): array|false {}

    public function sMove(string $src, string $dst, string $value): Redis|bool {}

    public function sPop(string $key, int $count = 0): Redis|string|array|false {}

    public function sRandMember(string $key, int $count = 0): Redis|string|array|false {}

    public function sUnion(string $key, string ...$other_keys): Redis|array|false {}

    public function sUnionStore(string $dst, string $key, string ...$other_keys): Redis|int|false {}

    public function save(): bool {}

    public function scan(?int &$iterator, ?string $pattern = null, int $count = 0, string $type = NULL): array|false {}

    public function scard(string $key): Redis|int|false {}

    public function script(string $command, mixed ...$args): mixed {}

    public function select(int $db): bool {}

    /** @return bool|Redis */
    public function set(string $key, string $value, mixed $opt = NULL) {}

	/** @return false|int|Redis */
    public function setBit(string $key, int $idx, bool $value) {}

	/** @return false|int|Redis */
    public function setRange(string $key, int $start, string $value) {}


    public function setOption(int $option, mixed $value): bool {}

    /** @return bool|Redis */
    public function setex(string $key, int $expire, string $value) {}

	/** @return bool|array|Redis */
    public function setnx(string $key, string $value) {}

    public function sismember(string $key, string $value): Redis|bool {}

    public function slaveof(string $host = null, int $port = 6379): bool {}

    public function slowlog(string $mode, int $option = 0): mixed {}

    public function sort(string $key, array $options = null): mixed {}

    /**
     * @deprecated
     */
    public function sortAsc(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {}

    /**
     * @deprecated
     */
    public function sortAscAlpha(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {}

    /**
     * @deprecated
     */
    public function sortDesc(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {}

    /**
     * @deprecated
     */
    public function sortDescAlpha(string $key, ?string $pattern = null, mixed $get = null, int $offset = -1, int $count = -1, ?string $store = null): array {}

    public function srem(string $key, string $value, mixed ...$other_values): Redis|int|false {}

    public function sscan(string $key, int &$iterator, ?string $pattern = null, int $count = 0): array|false {}

	/** @return false|int|Redis */
    public function strlen(string $key) {}

    public function subscribe(string $channel, string ...$other_channels): array|false {}

    public function swapdb(string $src, string $dst): bool {}

    public function time(): array|false {}

    public function ttl(string $key): Redis|int|false {}

	/** @return false|int|Redis */
    public function type(string $key) {}

       /**
     * @return false|int|Redis
     */
    public function unlink(array|string $key, string ...$other_keys) {}

    public function unsubscribe(string $channel, string ...$other_channels): array|false {}

	/** @return bool|Redis */
    public function unwatch() {}

    /**
     * @return bool|Redis
     */
    public function watch(array|string $key, string ...$other_keys) {}

    public function wait(int $count, int $timeout): int|false {}

    public function xack(string $key, string $group, array $ids): int|false {}

    public function xadd(string $key, string $id, array $values, int $maxlen = 0, bool $approx = false): string|false {}

    public function xclaim(string $key, string $group, string $consumer, int $min_iddle, array $ids, array $options): string|array|false {}

    public function xdel(string $key, array $ids): Redis|int|false {}

    public function xgroup(string $operation, string $key = null, string $arg1 = null, string $arg2 = null, bool $arg3 = false): mixed {}

    public function xinfo(string $operation, ?string $arg1 = null, ?string $arg2 = null, int $count = -1): mixed {}

    public function xlen(string $key): int {}

    public function xpending(string $key, string $group, string $start = null, string $end = null, int $count = -1, string $consumer = null): Redis|array|false {}

    public function xrange(string $key, string $start, string $end, int $count = -1): bool|array {}

    public function xread(array $streams, int $count = -1, int $block = -1): bool|array {}

    public function xreadgroup(string $group, string $consumer, array $streams, int $count = 1, int $block = 1): bool|array {}

    public function xrevrange(string $key, string $start, string $end, int $count = -1): bool|array {}

    public function xtrim(string $key, int $maxlen, bool $approx = false): int {}

    public function zAdd(string $key, array|float $score_or_options, mixed ...$more_scores_and_mems): Redis|int|false {}

    public function zCard(string $key): Redis|int|false {}

    public function zCount(string $key, string $start , string $end): Redis|int|false {}

    public function zIncrBy(string $key, float $value, mixed $member): Redis|float|false {}

    public function zLexCount(string $key, string $min, string $max): Redis|int|false {}

    public function zMscore(string $key, string $member, string ...$other_members): array|false {}

    public function zPopMax(string $key, int $value = null): array|false {}

    public function zPopMin(string $key, int $value = null): array|false {}

    public function zRange(string $key, int $start, int $end, mixed $scores = null): Redis|array|false {}

    public function zRangeByLex(string $key, string $min, string $max, int $offset = -1, int $count = -1): array|false {}

    public function zRangeByScore(string $key, string $start, string $end, array $options = []): Redis|array|false {}

    public function zRandMember(string $key, array $options = null): string|array|false {}

    public function zRank(string $key, mixed $member): Redis|int|false {}

    public function zRem(mixed $key, mixed $member, mixed ...$other_members): Redis|int|false {}

    public function zRemRangeByLex(string $key, string $min, string $max): int|false {}

    public function zRemRangeByRank(string $key, int $start, int $end): Redis|int|false {}

    public function zRemRangeByScore(string $key, string $start, string $end): Redis|int|false {}

    public function zRevRange(string $key, int $start, int $end, mixed $scores = null): Redis|array|false {}

    public function zRevRangeByLex(string $key, string $min, string $max, int $offset = -1, int $count = -1): array|false {}

    public function zRevRangeByScore(string $key, string $start, string $end, array $options = []): array|false {}

    public function zRevRank(string $key, mixed $member): Redis|int|false {}

    public function zScore(string $key, mixed $member): Redis|float|false {}

    public function zdiff(array $keys, array $options = null): array|false {}

    public function zdiffstore(string $dst, array $keys, array $options = null): int {}

    public function zinter(array $keys, ?array $weights = null, ?array $options = null): Redis|array|false {}

    public function zinterstore(string $dst, array $keys, ?array $weights = null, ?string $aggregate = null): Redis|int|false {}

    public function zscan(string $key, ?int &$iterator, ?string $pattern = null, int $count = 0): bool|array {}

    public function zunion(array $keys, ?array $weights = null, ?array $options = null): Redis|array|false {}

    public function zunionstore(string $dst, array $keys, ?array $weights = NULL, ?string $aggregate = NULL): Redis|int|false {}
}
<?php

const XDEBUG_TRACE_APPEND = 1;
const XDEBUG_TRACE_COMPUTERIZED = 2;
const XDEBUG_TRACE_HTML = 4;
const XDEBUG_TRACE_NAKED_FILENAME = 8;
const XDEBUG_CC_UNUSED = 1;
const XDEBUG_CC_DEAD_CODE = 2;
const XDEBUG_CC_BRANCH_CHECK = 4;
const XDEBUG_STACK_NO_DESC = 1;
const XDEBUG_FILTER_TRACING = 256;
const XDEBUG_FILTER_CODE_COVERAGE = 512;
const XDEBUG_FILTER_NONE = 0;
const XDEBUG_PATH_WHITELIST = 1;
const XDEBUG_PATH_BLACKLIST = 2;
const XDEBUG_NAMESPACE_WHITELIST = 17;
const XDEBUG_NAMESPACE_BLACKLIST = 18;

function xdebug_code_coverage_started() : bool
{
}

/**
* @return array<string, array<int, int>>
*/
function xdebug_get_code_coverage() : array
{
}

/**
* @param array<int, string> $configuration
*/
function xdebug_set_filter(int $group, int $list_type, array $configuration) : array
{
}

function xdebug_start_code_coverage(int $options) : void
{
}

function xdebug_stop_code_coverage(int $cleanup = 1) : void
{
}
<?php

/**
 * @param class-string<SimpleXMLElement> $class_name
 * @return SimpleXMLElement|false
 */
function simplexml_load_file(string $filename, ?string $class_name = SimpleXMLElement::class, int $options = 0, string $namespace_or_prefix = '', bool $is_prefix = false) {}

/**
 * @param class-string<SimpleXMLElement> $class_name
 * @return SimpleXMLElement|false
 */
function simplexml_load_string(string $data, ?string $class_name = 'SimpleXMLElement', int $options = 0, string $namespace_or_prefix = '', bool $is_prefix = false) {}

/**
 * @param class-string<SimpleXMLElement> $class_name
 */
function simplexml_import_dom(DOMNode $node, ?string $class_name = 'SimpleXMLElement'): ?SimpleXMLElement {}

/**
 * @param class-string<SimpleXMLElement> $class_name
 * @php-from 8.1
 */
function simplexml_import_dom(SimpleXMLElement|DOMNode $node, ?string $class_name = 'SimpleXMLElement'): ?SimpleXMLElement {}

/**
 * @implements Traversable<string, SimpleXMLElement>
 */
class SimpleXMLElement implements Traversable, Countable
{
    /** @return array<array-key, SimpleXMLElement>|null|false */
    public function xpath(string $expression) {}

    public function registerXPathNamespace(string $prefix, string $namespace): bool {}

    /** @return ($filename is null ? string|false : bool) */
    public function asXML(?string $filename = null) {}

    /**
     * @return ($filename is null ? string|false : bool)
     * @alias SimpleXMLElement::asXML
     */
    public function saveXML(?string $filename = null) {}

    public function getNamespaces(bool $recursive = false): array {}

    /** @return array|false */
    public function getDocNamespaces(bool $recursive = false, bool $fromRoot = true) {}

    public function children(?string $namespaceOrPrefix = null, bool $isPrefix = false): ?SimpleXMLElement {}

    public function attributes(?string $namespaceOrPrefix = null, bool $isPrefix = false): ?SimpleXMLElement {}

    final public function __construct(string $data, int $options = 0, bool $dataIsURL = false, string $namespaceOrPrefix = '', bool $isPrefix = false) {}

    public function addChild(string $qualifiedName, ?string $value = null, ?string $namespace = null): ?SimpleXMLElement {}

    public function addAttribute(string $qualifiedName, string $value, ?string $namespace = null): void {}

    public function getName(): string {}

    public function __toString(): string {}

    public function count(): int {}
}

/**
 * @implements RecursiveIterator<string, SimpleXMLElement>
 */
class SimpleXMLIterator extends SimpleXMLElement implements RecursiveIterator, Countable
{
    public function count(): int {}

    public function rewind(): void {}

    public function valid(): bool {}

    public function current(): SimpleXMLIterator {}

    public function key(): ?string {}

    public function next(): void {}

    public function hasChildren(): bool {}

    public function getChildren(): SimpleXMLIterator {}
}

/**
 * @implements RecursiveIterator<string, SimpleXMLElement>
 * @php-from 8.0
 */
class SimpleXMLElement implements Stringable, Countable, RecursiveIterator
{
    public function count(): int {}

    public function rewind(): void {}

    public function valid(): bool {}

    public function current(): SimpleXMLElement {}

    public function key(): ?string {}

    public function next(): void {}

    public function hasChildren(): bool {}

    public function getChildren(): ?SimpleXMLElement {}
}

/** @php-from 8.0 */
class SimpleXMLIterator extends SimpleXMLElement
{
    public function current(): SimpleXMLElement {}

    public function getChildren(): ?SimpleXMLElement {}
}
<?php
namespace {
    interface UnitEnum {
        /** @var non-empty-string $name */
        public readonly string $name;

        /**
         * @psalm-pure
         * @return list<static>
         */
        public static function cases(): array;
    }

    interface BackedEnum extends UnitEnum
    {
        /** @var non-empty-string $name */
        public readonly string $name;
        public readonly int|string $value;

        /**
         * @psalm-pure
         */
        public static function from(string|int $value): static;

        /**
         * @psalm-pure
         */
        public static function tryFrom(string|int $value): ?static;

        /**
         * @psalm-pure
         * @return list<static>
         */
        public static function cases(): array;
    }

    class ReflectionClass implements Reflector {
        /** @psalm-pure */
        public function isEnum(): bool {}
    }

    class ReflectionProperty implements Reflector
    {
        /**
         * Starting from PHP 8.1, this method is pure, and has no effect.
         *
         * @psalm-pure
         */
        public function setAccessible(bool $accessible): void {}
    }

    class ReflectionMethod extends ReflectionFunctionAbstract
    {
        /**
         * Starting from PHP 8.1, this method is pure, and has no effect.
         *
         * @psalm-pure
         */
        public function setAccessible(bool $accessible): void {}
    }

    /** @psalm-immutable */
    class ReflectionEnum extends ReflectionClass implements Reflector
    {
        public function getBackingType(): ?ReflectionType;
        public function getCase(string $name): ReflectionEnumUnitCase;
        /** @return list<ReflectionEnumUnitCase> */
        public function getCases(): array;
        public function hasCase(string $name): bool;
        public function isBacked(): bool;
    }

    /** @psalm-immutable */
    class ReflectionEnumUnitCase extends ReflectionClassConstant implements Reflector
    {
        public function getEnum(): ReflectionEnum;
        public function getValue(): UnitEnum;
    }

    /** @psalm-immutable */
    class ReflectionEnumBackedCase extends ReflectionEnumUnitCase implements Reflector
    {
        public function getBackingValue(): int|string;
    }

    /** @psalm-immutable */
    class ReflectionIntersectionType extends ReflectionType {
        /** @return non-empty-list<ReflectionNamedType> */
        public function getTypes(): array {}

        /** @return false */
        public function allowsNull(): bool {}
    }
}

namespace FTP {
    final class Connection {}
}

namespace IMAP {
    final class Connection {}
}

namespace LDAP {
   final class Connection {}
   final class Result {}
   final class ResultEntry {}
}

namespace PgSql {
   final class Connection {}
   final class Result {}
   final class Lob {}
}

namespace PSpell {
     final class Config {}
     final class Dictionary {}
}
<?php
namespace {
    class ReflectionClass implements Reflector {
        /** @psalm-pure */
        public function isReadOnly(): bool {}
    }

    /** @psalm-immutable */
    class ReflectionUnionType extends ReflectionType {
        /** @return non-empty-list<ReflectionNamedType|ReflectionIntersectionType> */
        public function getTypes(): array {}
    }
}
<?php

/**
 * @template-covariant T as object
 *
 * @property-read class-string<T> $name
 */
class ReflectionClass implements Reflector {

    /**
     * @var class-string<T>
     */
    public $name;

    /**
     * @param T|class-string<T>|interface-string<T>|trait-string|enum-string<T> $argument
     * @psalm-pure
     */
    public function __construct($argument) {}

    /**
     * @return class-string<T>
     * @psalm-pure
     */
    public function getName(): string {}

    /** @psalm-pure */
    public function isInternal(): bool {}

    /** @psalm-pure */
    public function isUserDefined(): bool {}

    /** @psalm-pure */
    public function isInstantiable(): bool {}

    /** @psalm-pure */
    public function isCloneable(): bool {}

    /**
     * @return non-empty-string|false
     * @psalm-pure
     */
    public function getFileName() {}

    /**
     * @return positive-int|false
     * @psalm-pure
     */
    public function getStartLine() {}

    /**
     * @return positive-int|false
     * @psalm-pure
     */
    public function getEndLine() {}

    /**
     * @return non-empty-string|false
     * @psalm-pure
     */
    public function getDocComment() {}

    /** @psalm-pure */
    public function getConstructor(): ?ReflectionMethod {}

    /** @psalm-pure */
    public function hasMethod(string $name): bool {}

    /**
     * @psalm-pure
     * @throws ReflectionException
     */
    public function getMethod(string $name): ReflectionMethod {}

    /**
     * @param int-mask-of<ReflectionMethod::IS_*>|null $filter
     * @return list<ReflectionMethod>
     * @psalm-pure
     */
    public function getMethods(?int $filter = null): array {}

    /**
     * @psalm-pure
     * @throws ReflectionException
     */
    public function hasProperty(string $name): bool {}

    /**
     * @psalm-pure
     * @throws ReflectionException
     */
    public function getProperty(string $name): ReflectionProperty {}

    /**
     * @param int-mask-of<ReflectionProperty::IS_*>|null $filter
     * @return list<ReflectionProperty>
     *
     * @psalm-pure
     */
    public function getProperties(?int $filter = null): array {}

    /**
     * @psalm-pure
     */
    public function hasConstant(string $name): bool {}

    /**
     * @return mixed
     *
     * @psalm-pure
     * @throws ReflectionException
     */
    public function getConstant(string $name) {}

    /**
     * @return ReflectionClassConstant|false
     *
     * @psalm-pure
     * @throws ReflectionException
     */
    public function getReflectionConstant(string $name) {}

    /**
     * @param int-mask-of<ReflectionClassConstant::IS_*>|null $filter
     * @return array<non-empty-string, mixed>
     *
     * @psalm-pure
     */
    public function getConstants(?int $filter = null): array {}

    /**
     * @param int-mask-of<ReflectionClassConstant::IS_*>|null $filter
     * @return list<ReflectionClassConstant>
     *
     * @psalm-pure
     */
    public function getReflectionConstants(?int $filter = null): array {}

    /**
     * @return array<interface-string, self>
     * @psalm-pure
     */
    public function getInterfaces(): array {}

    /**
     * @return list<interface-string>
     * @psalm-pure
     */
    public function getInterfaceNames(): array {}

    /** @psalm-pure */
    public function isInterface(): bool {}

    /**
     * @return array<trait-string, self>
     *
     * @psalm-pure
     */
    public function getTraits(): array {}

    /**
     * @return array<non-empty-string, non-empty-string>
     *
     * @psalm-pure
     */
    public function getTraitAliases(): array {}

    /** @psalm-pure */
    public function isTrait(): bool {}

    /** @psalm-pure */
    public function isAbstract(): bool {}

    /** @psalm-pure */
    public function isFinal(): bool {}

    /**
     * @return int-mask-of<ReflectionClass::IS_*>
     * @psalm-pure
     */
    public function getModifiers(): int {}

    /**
     * @template J as object
     * @param J $object
     * @psalm-assert-if-true T&J $object
     * @psalm-pure
     */
    public function isInstance(object $object): bool {}

    /**
     * @param mixed ...$args
     *
     * @return T
     */
    public function newInstance(...$args): object {}

    /**
     * @param list<mixed> $args
     *
     * @return T
     */
    public function newInstanceArgs(array $args): object {}

    /**
     * @return T
     */
    public function newInstanceWithoutConstructor(): object {}

    /**
     * @psalm-pure
     *
     * @return ReflectionClass|false
     */
    public function getParentClass() {}

    /**
     * @template J as object
     * @param self<J>|class-string<J> $class
     * @psalm-assert-if-true self<T&J> $this
     * @psalm-pure
     */
    public function isSubclassOf($class): bool {}

    /** @return array<non-empty-string, mixed> */
    public function getStaticProperties(): array {}

    /**
     * @return array<non-empty-string, mixed>
     *
     * @psalm-pure
     */
    public function getDefaultProperties(): array {}

    /** @psalm-pure */
    public function isIterateable(): bool {}

    /** @psalm-pure */
    public function isIterable(): bool {}

    /**
     * @template J as object
     * @param self<J>|interface-string<J> $interface
     * @psalm-assert-if-true self<T&J> $this
     * @psalm-pure
     */
    public function implementsInterface($interface): bool {}

    /** @psalm-pure */
    public function getExtension(): ?ReflectionExtension {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getExtensionName() {}

    /** @psalm-pure */
    public function inNamespace(): bool {}

    /** @psalm-pure */
    public function getNamespaceName(): string {}

    /**
     * @return non-empty-string
     *
     * @psalm-pure
     */
    public function getShortName(): string {}

    /**
     * @return list<trait-string>
     * @psalm-pure
     */
    public function getTraitNames(): array {}

    /**
     * @since 8.0
     * @template TClass as object
     * @param class-string<TClass>|null $name
     * @return ($name is null ? list<ReflectionAttribute<object>> : list<ReflectionAttribute<TClass>>)
     * @psalm-pure
     */
    public function getAttributes(?string $name = null, int $flags = 0): array {}
}

abstract class ReflectionFunctionAbstract implements Reflector
{
    /** @psalm-pure */
    public function inNamespace(): bool {}

    /** @psalm-pure */
    public function isClosure(): bool {}

    /** @psalm-pure */
    public function isDeprecated(): bool {}

    /** @psalm-pure */
    public function isInternal(): bool {}

    /** @psalm-pure */
    public function isUserDefined(): bool {}

    public function getClosureThis(): ?object {}

    /** @psalm-pure */
    public function getClosureScopeClass(): ?ReflectionClass {}

    /** @psalm-pure */
    public function getClosureCalledClass(): ?ReflectionClass {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getDocComment() {}

    /**
     * @return positive-int|false
     *
     * @psalm-pure
     */
    public function getStartLine() {}

    /**
     * @return positive-int|false
     *
     * @psalm-pure
     */
    public function getEndLine() {}

    /** @psalm-pure */
    public function getExtension(): ?ReflectionExtension {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getExtensionName() {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getFileName() {}

    /**
     * @return non-empty-string
     *
     * @psalm-pure
     */
    public function getName(): string {}

    /** @psalm-pure */
    public function getNamespaceName(): string {}

    /**
     * @return positive-int|0
     *
     * @psalm-pure
     */
    public function getNumberOfParameters(): int {}

    /**
     * @return positive-int|0
     *
     * @psalm-pure
     */
    public function getNumberOfRequiredParameters(): int {}

    /**
     * @return list<ReflectionParameter>
     *
     * @psalm-pure
     */
    public function getParameters(): array {}

    /**
     * @psalm-assert-if-true ReflectionType $this->getReturnType()
     *
     * @psalm-pure
     */
    public function hasReturnType(): bool {}

    /** @psalm-pure */
    public function getReturnType(): ?ReflectionType {}

    /**
     * @return non-empty-string
     *
     * @psalm-pure
     */
    public function getShortName(): string {}

    /** @psalm-pure */
    public function returnsReference(): bool {}

    /** @psalm-pure */
    public function isGenerator(): bool {}

    /** @psalm-pure */
    public function isVariadic(): bool {}

    /** @psalm-pure */
    public function isDisabled(): bool {}

    /** @psalm-pure */
    public function getClosure(): Closure {}

    /**
     * @since 8.0
     * @template TClass as object
     * @param class-string<TClass>|null $name
     * @return ($name is null ? array<ReflectionAttribute<object>> : array<ReflectionAttribute<TClass>>)
     */
    public function getAttributes(?string $name = null, int $flags = 0): array {}
}

class ReflectionFunction extends ReflectionFunctionAbstract
{
    /**
     * @param callable-string|Closure $function
     *
     * @psalm-pure
     */
    public function __construct(callable $function) {}

    /**
     * @return non-empty-string
     *
     * @psalm-pure
     */
    public function __toString(): string {}
}

class ReflectionProperty implements Reflector
{
    /**
     * @var string
     * @readonly
     */
    public $name;

    /**
     * @var class-string
     * @readonly
     */
    public $class;

    /**
     * @return non-empty-string
     *
     * @psalm-pure
     */
    public function getName(): string {}

    /**
     * @since 8.0
     * @template TClass as object
     * @param class-string<TClass>|null $name
     * @return ($name is null ? array<ReflectionAttribute<object>> : array<ReflectionAttribute<TClass>>)
     */
    public function getAttributes(?string $name = null, int $flags = 0): array {}

    /**
     * @since 7.4
     * @psalm-assert-if-true ReflectionType $this->getType()
     * @psalm-pure
     */
    public function hasType() : bool {}

    /**
     * @since 7.4
     * @psalm-pure
     */
    public function getType() : ?ReflectionType {}

    /** @psalm-pure */
    public function isPublic(): bool {}

    /** @psalm-pure */
    public function isPrivate(): bool {}

    /** @psalm-pure */
    public function isProtected(): bool {}

    /** @psalm-pure */
    public function isStatic(): bool {}

    /** @psalm-pure */
    public function isDefault(): bool {}

    /**
     * @return int-mask-of<self::IS_>
     * @psalm-pure
     */
    public function getModifiers(): int {}

    /** @psalm-pure */
    public function getDeclaringClass(): ReflectionClass {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getDocComment() {}

    /**
     * @since 8.0
     * @psalm-pure
     */
    public function hasDefaultValue(): bool {}

    /**
     * @return mixed
     *
     * @psalm-pure
     */
    public function getDefaultValue() {}

    /**
     * @since 8.0
     * @psalm-pure
     */
    public function isPromoted(): bool {}

    /**
     * @since 8.1
     * @psalm-pure
     */
    public function isReadOnly(): bool {}
}

class ReflectionMethod extends ReflectionFunctionAbstract
{
    /**
     * @var string
     * @readonly
     */
    public $name;

    /**
     * @var class-string
     * @readonly
     */
    public $class;

    /** @psalm-pure */
    public function isStatic(): bool {}

    /** @psalm-pure */
    public function isConstructor(): bool {}

    /** @psalm-pure */
    public function isDestructor(): bool {}

    /**
     * @return int-mask-of<ReflectionMethod::IS_*>
     * @psalm-pure
     */
    public function getModifiers(): int {}

    /** @psalm-pure */
    public function getDeclaringClass(): ReflectionClass {}

    /** @psalm-pure */
    public function getPrototype(): ReflectionMethod {}
}

/** @psalm-immutable */
class ReflectionClassConstant implements Reflector
{
    /**
     * @var non-empty-string
     * @readonly
     */
    public $name;

    /**
     * @var class-string
     * @readonly
     */
    public $class;

    /**
     * @var bool
     * @since 8.1
     * @readonly
     */
    public $isFinal;

    /**
     * @since 8.0
     * @template TClass as object
     * @param class-string<TClass>|null $name
     * @return ($name is null ? array<ReflectionAttribute<object>> : array<ReflectionAttribute<TClass>>)
     */
    public function getAttributes(?string $name = null, int $flags = 0): array {}

    /** @return non-empty-string */
    public function getName(): string {}

    /** @return int-mask-of<self::IS_*> */
    public function getModifiers(): int {}

    /** @return non-empty-string|false */
    public function getDocComment() {}
}

/** @psalm-immutable */
class ReflectionParameter implements Reflector {
    /**
     * @var non-empty-string
     * @readonly
     */
    public $name;

    /** @return non-empty-string */
    public function getName(): string {}

    /**
     * @psalm-assert-if-true ReflectionType $this->getType()
     */
    public function hasType() : bool {}

    public function getType() : ?ReflectionType {}

    /**
     * @since 8.0
     * @template TClass as object
     * @param class-string<TClass>|null $name
     * @return ($name is null ? array<ReflectionAttribute<object>> : array<ReflectionAttribute<TClass>>)
     */
    public function getAttributes(?string $name = null, int $flags = 0): array {}

    /**
    * @since 8.0
    */
    public function isPromoted(): bool {}

    /**
     * @psalm-assert-if-true string $this->getDefaultValueConstantName()
     */
    public function isDefaultValueConstant(): bool {}

    public function getDefaultValueConstantName(): ?string {}
}

/** @psalm-immutable */
abstract class ReflectionType
{
}

/** @psalm-immutable */
class ReflectionNamedType extends ReflectionType
{
    /** @return non-empty-string */
    public function getName(): string {}

    /**
     * @psalm-assert-if-false class-string|'self'|'static' $this->getName()
     */
    public function isBuiltin(): bool {}

    /** @return non-empty-string */
    public function __toString(): string {}
}
<?php

class DateTimeImmutable implements DateTimeInterface
{
    public function __construct(string $datetime = "now", DateTimeZone $timezone = null) {}

    /**
     * @psalm-mutation-free
     * @return static|false
     */
    public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null) {}

    /**
     * @psalm-mutation-free
     *
     * @param string $format
     *
     * @return ($format is non-empty-string ? non-empty-string : string)
     */
    public function format($format) {}

    /**
     * @psalm-mutation-free
     * @return DateTimeZone
     */
    public function getTimezone() {}

    /**
     * @psalm-mutation-free
     * @return int
     */
    public function getOffset() {}

    /**
     * @psalm-mutation-free
     * @return int
     */
    public function getTimestamp() {}

    /**
     * @psalm-mutation-free
     * @param bool $absolute
     * @return DateInterval
     */
    public function diff(DateTimeInterface $targetObject, $absolute = false) {}

    /**
     * @psalm-mutation-free
     * @return static|false
     */
    public function modify(string $modifier) {}

    /**
     * @psalm-mutation-free
     * @return static
     */
    public function add(DateInterval $interval) {}

    /**
     * @psalm-mutation-free
     * @return static

     */
    public function sub(DateInterval $interval) {}

    /**
     * @psalm-mutation-free
     * @return static
     */
    public function setTimezone(DateTimeZone $timezone) {}

    /**
     * @psalm-mutation-free
     * @return static
     */
    public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0) {}

    /**
     * @psalm-mutation-free
     * @return static
     */
    public function setDate(int $year, int $month, int $day) {}

    /**
     * @psalm-mutation-free
     * @return static
     */
    public function setISODate(int $year, int $week, int $dayOfWeek = 1) {}

    /**
     * @psalm-mutation-free
     * @return static
     */
    public function setTimestamp(int $unixtimestamp) {}

    /**
     * @psalm-mutation-free
     * @return static
     */
    public static function createFromMutable(DateTime $object) {}
}

/**
 * @psalm-immutable
 */
class DateTimeZone
{
    public function __construct(string $timezone) {}
}

/**
 * @psalm-immutable
 *
 * @template-covariant Start of string|DateTimeInterface
 * @implements Traversable<int, DateTimeInterface>
 */
class DatePeriod implements Traversable
{
    const EXCLUDE_START_DATE = 1;
    /**
     * @param Start $start
     * @param (Start is string ? 0|self::EXCLUDE_START_DATE : DateInterval) $interval
     * @param (Start is string ? never : DateTimeInterface|positive-int) $end
     * @param (Start is string ? never : 0|self::EXCLUDE_START_DATE) $options
     */
    public function __construct($start, $interval = 0, $end = 1, $options = 0) {}
}

/**
 * @psalm-taint-specialize
 */
interface Throwable
{
    /**
     * @psalm-mutation-free
     */
    public function getMessage() : string;

    /**
     * @psalm-mutation-free
     *
     * @return int|string https://www.php.net/manual/en/throwable.getcode.php
     */
    public function getCode();

    /**
     * @psalm-mutation-free
     */
    public function getFile() : string;

    /**
     * @psalm-mutation-free
     */
    public function getLine() : int;

    /**
     * @psalm-mutation-free
     * @return list<array{file?:string,line?:int,function?:string,class?:class-string,type?:'::'|'->',args?:array<mixed>}>
     */
    public function getTrace() : array;

    /**
     * @psalm-mutation-free
     */
    public function getPrevious() : ?Throwable;

    /**
     * @psalm-mutation-free
     * @psalm-taint-source input
     */
    public function getTraceAsString() : string;

    /**
     * @return string
     * @psalm-taint-source input
     */
    public function __toString();
}

/**
 * @psalm-taint-specialize
 */
class Exception implements Throwable
{
    /**
     * @var string
     */
    protected $message = '';

    /**
     * @var int
     */
    protected $code = 0;

    /**
     * @var string
     */
    protected $file = '';

    /**
     * @var int
     */
    protected $line = 0;

    /**
     * @psalm-external-mutation-free
     * @param string $message
     * @param int $code
     * @param Throwable $previous
     */
    public function __construct($message = "", $code = 0, Throwable $previous = null) {}

    /**
     * @psalm-mutation-free
     */
    public final function getMessage() : string {}

    /**
     * @psalm-mutation-free
     *
     * @return int|string https://www.php.net/manual/en/throwable.getcode.php
     */
    public final function getCode() {}

    /**
     * @psalm-mutation-free
     */
    public final function getFile(): string {}

    /**
     * @psalm-mutation-free
     */
    public final function getLine(): int {}

    /**
     * @psalm-mutation-free
     * @return list<array{file?:string,line?:int,function?:string,class?:class-string,type?:'::'|'->',args?:array<mixed>}>
     */
    public final function getTrace() : array {}

    /**
     * @psalm-mutation-free
     */
    public final function getPrevious() : ?Throwable {}

    /**
     * @psalm-mutation-free
     * @psalm-taint-source input
     */
    public final function getTraceAsString() : string {}

    /**
     * @return string
     * @psalm-taint-source input
     */
    public function __toString() {}
}

/**
 * @psalm-taint-specialize
 */
class Error implements Throwable
{
    /**
     * @var string
     */
    protected $message = '';

    /**
     * @var int
     */
    protected $code = 0;

    /**
     * @var string
     */
    protected $file = '';

    /**
     * @var int
     */
    protected $line = 0;

    /**
     * @psalm-external-mutation-free
     * @param string $message
     * @param int $code
     * @param Throwable $previous
     */
    public function __construct($message = "", $code = 0, Throwable $previous = null) {}

    /**
     * @psalm-mutation-free
     */
    public final function getMessage() : string {}

    /**
     * @psalm-mutation-free
     */
    public final function getCode(): int {}

    /**
     * @psalm-mutation-free
     */
    public final function getFile(): string {}

    /**
     * @psalm-mutation-free
     */
    public final function getLine(): int{}

    /**
     * @psalm-mutation-free
     * @return list<array{file?:string,line?:int,function?:string,class?:class-string,type?:'::'|'->',args?:array<mixed>}>
     */
    public final function getTrace() : array {}

    /**
     * @psalm-mutation-free
     */
    public final function getPrevious() : ?Throwable {}

    /**
     * @psalm-mutation-free
     * @psalm-taint-source input
     */
    public final function getTraceAsString() : string {}

    /**
     * @return string
     * @psalm-taint-source input
     */
    public function __toString() {}
}
<?php

interface Stringable
{
    /** @return string */
    function __toString();
}

/**
 * @template TClass as object
 */
class ReflectionAttribute
{
    const IS_INSTANCEOF = 2;

    private function __construct()
    {
    }

    /**
     * @return non-empty-string
     *
     * @psalm-pure
     */
    public function getName() : string
    {
    }

    /**
     * @psalm-pure
     * @return int-mask-of<Attribute::TARGET_*>
     */
    public function getTarget() : int
    {
    }

    /** @psalm-pure */
    public function isRepeated() : bool
    {
    }

    public function getArguments() : array
    {
    }

    /**
     * @return TClass
     */
    public function newInstance() : object
    {
    }

    /**
     * @return never-return
     */
    private function __clone()
    {
    }
}

/**
 * @template-covariant T as object
 *
 * @property-read class-string<T> $name
 */
class ReflectionClass implements Reflector {
    /**
     * @return non-empty-string|false
     * @psalm-pure
     */
    public function getFileName(): string|false {}

    /**
     * @return positive-int|false
     * @psalm-pure
     */
    public function getStartLine(): int|false {}

    /**
     * @return positive-int|false
     * @psalm-pure
     */
    public function getEndLine(): int|false {}

    /**
     * @return non-empty-string|false
     * @psalm-pure
     */
    public function getDocComment(): string|false {}

    /**
     * @template J as object
     * @param self<J>|class-string<J> $class
     * @psalm-assert-if-true self<T&J> $this
     * @psalm-pure
     */
    public function isSubclassOf(self|string $class): bool {}

    /**
     * @template J as object
     * @param self<J>|interface-string<J> $interface
     * @psalm-assert-if-true self<T&J> $this
     * @psalm-pure
     */
    public function implementsInterface(self|string $interface): bool {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getExtensionName(): string|false {}

    /**
     * @param list<mixed>|array<string, mixed> $args
     *
     * @return T
     */
    public function newInstanceArgs(array $args): object {}
}

/** @psalm-immutable */
class ReflectionClassConstant
{
    public const IS_PUBLIC = 1;
    public const IS_PROTECTED = 2;
    public const IS_PRIVATE = 4;

    /** @return non-empty-string|false */
    public function getDocComment(): string|false {}
}

abstract class ReflectionFunctionAbstract implements Reflector
{
    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getDocComment(): string|false {}

    /**
     * @return positive-int|false
     *
     * @psalm-pure
     */
    public function getStartLine(): int|false {}

    /**
     * @return positive-int|false
     *
     * @psalm-pure
     */
    public function getEndLine(): int|false {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getFileName(): string|false {}

    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getExtensionName(): string|false {}
}

/** @psalm-immutable */
class Attribute
{
    public int $flags;

    public const TARGET_CLASS = 1;
    public const TARGET_FUNCTION = 2;
    public const TARGET_METHOD = 4;
    public const TARGET_PROPERTY = 8;
    public const TARGET_CLASS_CONSTANT = 16;
    public const TARGET_PARAMETER = 32;
    public const TARGET_ALL = 63;
    public const IS_REPEATABLE = 64;

    /**
     * @param int-mask-of<self::*> $flags
     */
    public function __construct(int $flags = self::TARGET_ALL)
    {
    }
}

class ReflectionProperty implements Reflector
{
    /**
     * @return non-empty-string|false
     *
     * @psalm-pure
     */
    public function getDocComment(): string|false {}
}

/** @psalm-immutable */
class ReflectionUnionType extends ReflectionType {
    /** @return non-empty-list<ReflectionNamedType> */
    public function getTypes(): array {}
}

class UnhandledMatchError extends Error {}

/**
 * @psalm-immutable
 *
 * @template-covariant Start of string|DateTimeInterface
 * @implements IteratorAggregate<int, DateTimeInterface>
 */
class DatePeriod implements IteratorAggregate
{
    const EXCLUDE_START_DATE = 1;
    /**
     * @param Start $start
     * @param (Start is string ? 0|self::EXCLUDE_START_DATE : DateInterval) $interval
     * @param (Start is string ? never : DateTimeInterface|positive-int) $end
     * @param (Start is string ? never : 0|self::EXCLUDE_START_DATE) $options
     */
    public function __construct($start, $interval = 0, $end = 1, $options = 0) {}

    /** @psalm-return (Start is string ? (Traversable<int, DateTime>&Iterator) : (Traversable<int, Start>&Iterator)) */
    public function getIterator(): Iterator {}
}

/**
 * @psalm-pure
 *
 * @param resource|null $context
 *
 * @return ($associative is false|0 ? list<string> : array<string, string|list<string>>)|false
 *
 * @psalm-taint-sink ssrf $url
 */
function get_headers(string $url, bool $associative = false, $context = null) : array|false {}
<?php

namespace _HumbugBox1cb33d1f20f1;

/**
 * Part of JsonMapper
 *
 * PHP version 5
 *
 * @category Netresearch
 * @package  JsonMapper
 * @author   Christian Weiske <cweiske@cweiske.de>
 * @license  OSL-3.0 http://opensource.org/licenses/osl-3.0
 * @link     http://cweiske.de/
 */
/**
 * Simple exception
 *
 * @category Netresearch
 * @package  JsonMapper
 * @author   Christian Weiske <cweiske@cweiske.de>
 * @license  OSL-3.0 http://opensource.org/licenses/osl-3.0
 * @link     http://cweiske.de/
 */
class JsonMapper_Exception extends \Exception
{
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/**
 * Part of JsonMapper
 *
 * PHP version 5
 *
 * @category Netresearch
 * @package  JsonMapper
 * @author   Christian Weiske <cweiske@cweiske.de>
 * @license  OSL-3.0 http://opensource.org/licenses/osl-3.0
 * @link     http://cweiske.de/
 */
/**
 * Automatically map JSON structures into objects.
 *
 * @category Netresearch
 * @package  JsonMapper
 * @author   Christian Weiske <cweiske@cweiske.de>
 * @license  OSL-3.0 http://opensource.org/licenses/osl-3.0
 * @link     http://cweiske.de/
 */
class JsonMapper
{
    /**
     * PSR-3 compatible logger object
     *
     * @link http://www.php-fig.org/psr/psr-3/
     * @var  object
     * @see  setLogger()
     */
    protected $logger;
    /**
     * Throw an exception when JSON data contain a property
     * that is not defined in the PHP class
     *
     * @var boolean
     */
    public $bExceptionOnUndefinedProperty = \false;
    /**
     * Throw an exception if the JSON data miss a property
     * that is marked with @required in the PHP class
     *
     * @var boolean
     */
    public $bExceptionOnMissingData = \false;
    /**
     * If the types of map() parameters shall be checked.
     *
     * You have to disable it if you're using the json_decode "assoc" parameter.
     *
     *     json_decode($str, false)
     *
     * @var boolean
     */
    public $bEnforceMapType = \true;
    /**
     * Throw an exception when an object is expected but the JSON contains
     * a non-object type.
     *
     * @var boolean
     */
    public $bStrictObjectTypeChecking = \false;
    /**
     * Throw an exception, if null value is found
     * but the type of attribute does not allow nulls.
     *
     * @var bool
     */
    public $bStrictNullTypes = \true;
    /**
     * Allow mapping of private and proteted properties.
     *
     * @var boolean
     */
    public $bIgnoreVisibility = \false;
    /**
     * Remove attributes that were not passed in JSON,
     * to avoid confusion between them and NULL values.
     *
     * @var boolean
     */
    public $bRemoveUndefinedAttributes = \false;
    /**
     * Override class names that JsonMapper uses to create objects.
     * Useful when your setter methods accept abstract classes or interfaces.
     *
     * @var array
     */
    public $classMap = array();
    /**
     * Callback used when an undefined property is found.
     *
     * Works only when $bExceptionOnUndefinedProperty is disabled.
     *
     * Parameters to this function are:
     * 1. Object that is being filled
     * 2. Name of the unknown JSON property
     * 3. JSON value of the property
     *
     * @var callable
     */
    public $undefinedPropertyHandler = null;
    /**
     * Runtime cache for inspected classes. This is particularly effective if
     * mapArray() is called with a large number of objects
     *
     * @var array property inspection result cache
     */
    protected $arInspectedClasses = array();
    /**
     * Method to call on each object after deserialization is done.
     *
     * Is only called if it exists on the object.
     *
     * @var string|null
     */
    public $postMappingMethod = null;
    /**
     * Map data all data in $json into the given $object instance.
     *
     * @param object|array $json   JSON object structure from json_decode()
     * @param object       $object Object to map $json data into
     *
     * @return mixed Mapped object is returned.
     * @see    mapArray()
     */
    public function map($json, $object)
    {
        if ($this->bEnforceMapType && !\is_object($json)) {
            throw new \InvalidArgumentException('JsonMapper::map() requires first argument to be an object' . ', ' . \gettype($json) . ' given.');
        }
        if (!\is_object($object)) {
            throw new \InvalidArgumentException('JsonMapper::map() requires second argument to be an object' . ', ' . \gettype($object) . ' given.');
        }
        $strClassName = \get_class($object);
        $rc = new \ReflectionClass($object);
        $strNs = $rc->getNamespaceName();
        $providedProperties = array();
        foreach ($json as $key => $jvalue) {
            $key = $this->getSafeName($key);
            $providedProperties[$key] = \true;
            // Store the property inspection results so we don't have to do it
            // again for subsequent objects of the same type
            if (!isset($this->arInspectedClasses[$strClassName][$key])) {
                $this->arInspectedClasses[$strClassName][$key] = $this->inspectProperty($rc, $key);
            }
            list($hasProperty, $accessor, $type, $isNullable) = $this->arInspectedClasses[$strClassName][$key];
            if (!$hasProperty) {
                if ($this->bExceptionOnUndefinedProperty) {
                    throw new JsonMapper_Exception('JSON property "' . $key . '" does not exist' . ' in object of type ' . $strClassName);
                } else {
                    if ($this->undefinedPropertyHandler !== null) {
                        \call_user_func($this->undefinedPropertyHandler, $object, $key, $jvalue);
                    } else {
                        $this->log('info', 'Property {property} does not exist in {class}', array('property' => $key, 'class' => $strClassName));
                    }
                }
                continue;
            }
            if ($accessor === null) {
                if ($this->bExceptionOnUndefinedProperty) {
                    throw new JsonMapper_Exception('JSON property "' . $key . '" has no public setter method' . ' in object of type ' . $strClassName);
                }
                $this->log('info', 'Property {property} has no public setter method in {class}', array('property' => $key, 'class' => $strClassName));
                continue;
            }
            if ($isNullable || !$this->bStrictNullTypes) {
                if ($jvalue === null) {
                    $this->setProperty($object, $accessor, null);
                    continue;
                }
                $type = $this->removeNullable($type);
            } else {
                if ($jvalue === null) {
                    throw new JsonMapper_Exception('JSON property "' . $key . '" in class "' . $strClassName . '" must not be NULL');
                }
            }
            $type = $this->getFullNamespace($type, $strNs);
            $type = $this->getMappedType($type, $jvalue);
            if ($type === null || $type === 'mixed') {
                //no given type - simply set the json data
                $this->setProperty($object, $accessor, $jvalue);
                continue;
            } else {
                if ($this->isObjectOfSameType($type, $jvalue)) {
                    $this->setProperty($object, $accessor, $jvalue);
                    continue;
                } else {
                    if ($this->isSimpleType($type)) {
                        if ($type === 'string' && \is_object($jvalue)) {
                            throw new JsonMapper_Exception('JSON property "' . $key . '" in class "' . $strClassName . '" is an object and' . ' cannot be converted to a string');
                        }
                        \settype($jvalue, $type);
                        $this->setProperty($object, $accessor, $jvalue);
                        continue;
                    }
                }
            }
            //FIXME: check if type exists, give detailed error message if not
            if ($type === '') {
                throw new JsonMapper_Exception('Empty type at property "' . $strClassName . '::$' . $key . '"');
            } else {
                if (\strpos($type, '|')) {
                    throw new JsonMapper_Exception('Cannot decide which of the union types shall be used: ' . $type);
                }
            }
            $array = null;
            $subtype = null;
            if ($this->isArrayOfType($type)) {
                //array
                $array = array();
                $subtype = \substr($type, 0, -2);
            } else {
                if (\substr($type, -1) == ']') {
                    list($proptype, $subtype) = \explode('[', \substr($type, 0, -1));
                    if ($proptype == 'array') {
                        $array = array();
                    } else {
                        $array = $this->createInstance($proptype, \false, $jvalue);
                    }
                } else {
                    if (\is_a($type, 'ArrayObject', \true)) {
                        $array = $this->createInstance($type, \false, $jvalue);
                    }
                }
            }
            if ($array !== null) {
                if (!\is_array($jvalue) && $this->isFlatType(\gettype($jvalue))) {
                    throw new JsonMapper_Exception('JSON property "' . $key . '" must be an array, ' . \gettype($jvalue) . ' given');
                }
                $cleanSubtype = $this->removeNullable($subtype);
                $subtype = $this->getFullNamespace($cleanSubtype, $strNs);
                $child = $this->mapArray($jvalue, $array, $subtype, $key);
            } else {
                if ($this->isFlatType(\gettype($jvalue))) {
                    //use constructor parameter if we have a class
                    // but only a flat type (i.e. string, int)
                    if ($this->bStrictObjectTypeChecking) {
                        throw new JsonMapper_Exception('JSON property "' . $key . '" must be an object, ' . \gettype($jvalue) . ' given');
                    }
                    $child = $this->createInstance($type, \true, $jvalue);
                } else {
                    $child = $this->createInstance($type, \false, $jvalue);
                    $this->map($jvalue, $child);
                }
            }
            $this->setProperty($object, $accessor, $child);
        }
        if ($this->bExceptionOnMissingData) {
            $this->checkMissingData($providedProperties, $rc);
        }
        if ($this->bRemoveUndefinedAttributes) {
            $this->removeUndefinedAttributes($object, $providedProperties);
        }
        if ($this->postMappingMethod !== null && $rc->hasMethod($this->postMappingMethod)) {
            $refDeserializePostMethod = $rc->getMethod($this->postMappingMethod);
            $refDeserializePostMethod->setAccessible(\true);
            $refDeserializePostMethod->invoke($object);
        }
        return $object;
    }
    /**
     * Convert a type name to a fully namespaced type name.
     *
     * @param string $type  Type name (simple type or class name)
     * @param string $strNs Base namespace that gets prepended to the type name
     *
     * @return string Fully-qualified type name with namespace
     */
    protected function getFullNamespace($type, $strNs)
    {
        if ($type === null || $type === '' || $type[0] === '\\' || $strNs === '') {
            return $type;
        }
        list($first) = \explode('[', $type, 2);
        if ($first === 'mixed' || $this->isSimpleType($first)) {
            return $type;
        }
        //create a full qualified namespace
        return '\\' . $strNs . '\\' . $type;
    }
    /**
     * Check required properties exist in json
     *
     * @param array  $providedProperties array with json properties
     * @param object $rc                 Reflection class to check
     *
     * @throws JsonMapper_Exception
     *
     * @return void
     */
    protected function checkMissingData($providedProperties, \ReflectionClass $rc)
    {
        foreach ($rc->getProperties() as $property) {
            $rprop = $rc->getProperty($property->name);
            $docblock = $rprop->getDocComment();
            $annotations = static::parseAnnotations($docblock);
            if (isset($annotations['required']) && !isset($providedProperties[$property->name])) {
                throw new JsonMapper_Exception('Required property "' . $property->name . '" of class ' . $rc->getName() . ' is missing in JSON data');
            }
        }
    }
    /**
     * Remove attributes from object that were not passed in JSON data.
     *
     * This is to avoid confusion between those that were actually passed
     * as NULL, and those that weren't provided at all.
     *
     * @param object $object             Object to remove properties from
     * @param array  $providedProperties Array with JSON properties
     *
     * @return void
     */
    protected function removeUndefinedAttributes($object, $providedProperties)
    {
        foreach (\get_object_vars($object) as $propertyName => $dummy) {
            if (!isset($providedProperties[$propertyName])) {
                unset($object->{$propertyName});
            }
        }
    }
    /**
     * Map an array
     *
     * @param array  $json       JSON array structure from json_decode()
     * @param mixed  $array      Array or ArrayObject that gets filled with
     *                           data from $json
     * @param string $class      Class name for children objects.
     *                           All children will get mapped onto this type.
     *                           Supports class names and simple types
     *                           like "string" and nullability "string|null".
     *                           Pass "null" to not convert any values
     * @param string $parent_key Defines the key this array belongs to
     *                           in order to aid debugging.
     *
     * @return mixed Mapped $array is returned
     */
    public function mapArray($json, $array, $class = null, $parent_key = '')
    {
        $originalClass = $class;
        foreach ($json as $key => $jvalue) {
            $class = $this->getMappedType($originalClass, $jvalue);
            if ($class === null) {
                $array[$key] = $jvalue;
            } else {
                if ($this->isArrayOfType($class)) {
                    $array[$key] = $this->mapArray($jvalue, array(), \substr($class, 0, -2));
                } else {
                    if ($this->isFlatType(\gettype($jvalue))) {
                        //use constructor parameter if we have a class
                        // but only a flat type (i.e. string, int)
                        if ($jvalue === null) {
                            $array[$key] = null;
                        } else {
                            if ($this->isSimpleType($class)) {
                                \settype($jvalue, $class);
                                $array[$key] = $jvalue;
                            } else {
                                $array[$key] = $this->createInstance($class, \true, $jvalue);
                            }
                        }
                    } else {
                        if ($this->isFlatType($class)) {
                            throw new JsonMapper_Exception('JSON property "' . ($parent_key ? $parent_key : '?') . '"' . ' is an array of type "' . $class . '"' . ' but contained a value of type' . ' "' . \gettype($jvalue) . '"');
                        } else {
                            if (\is_a($class, 'ArrayObject', \true)) {
                                $array[$key] = $this->mapArray($jvalue, $this->createInstance($class));
                            } else {
                                $array[$key] = $this->map($jvalue, $this->createInstance($class, \false, $jvalue));
                            }
                        }
                    }
                }
            }
        }
        return $array;
    }
    /**
     * Try to find out if a property exists in a given class.
     * Checks property first, falls back to setter method.
     *
     * @param ReflectionClass $rc   Reflection class to check
     * @param string          $name Property name
     *
     * @return array First value: if the property exists
     *               Second value: the accessor to use (
     *                 ReflectionMethod or ReflectionProperty, or null)
     *               Third value: type of the property
     *               Fourth value: if the property is nullable
     */
    protected function inspectProperty(\ReflectionClass $rc, $name)
    {
        //try setter method first
        $setter = 'set' . $this->getCamelCaseName($name);
        if ($rc->hasMethod($setter)) {
            $rmeth = $rc->getMethod($setter);
            if ($rmeth->isPublic() || $this->bIgnoreVisibility) {
                $isNullable = \false;
                $rparams = $rmeth->getParameters();
                if (\count($rparams) > 0) {
                    $isNullable = $rparams[0]->allowsNull();
                    $ptype = $rparams[0]->getType();
                    if ($ptype !== null) {
                        $typeName = $this->stringifyReflectionType($ptype);
                        //allow overriding an "array" type hint
                        // with a more specific class in the docblock
                        if ($typeName !== 'array') {
                            return array(\true, $rmeth, $typeName, $isNullable);
                        }
                    }
                }
                $docblock = $rmeth->getDocComment();
                $annotations = static::parseAnnotations($docblock);
                if (!isset($annotations['param'][0])) {
                    return array(\true, $rmeth, null, $isNullable);
                }
                list($type) = \explode(' ', \trim($annotations['param'][0]));
                return array(\true, $rmeth, $type, $this->isNullable($type));
            }
        }
        //now try to set the property directly
        //we have to look it up in the class hierarchy
        $class = $rc;
        $rprop = null;
        do {
            if ($class->hasProperty($name)) {
                $rprop = $class->getProperty($name);
            }
        } while ($rprop === null && ($class = $class->getParentClass()));
        if ($rprop === null) {
            //case-insensitive property matching
            foreach ($rc->getProperties() as $p) {
                if (\strcasecmp($p->name, $name) === 0) {
                    $rprop = $p;
                    break;
                }
            }
        }
        if ($rprop !== null) {
            if ($rprop->isPublic() || $this->bIgnoreVisibility) {
                $docblock = $rprop->getDocComment();
                $annotations = static::parseAnnotations($docblock);
                if (!isset($annotations['var'][0])) {
                    // If there is no annotations (higher priority) inspect
                    // if there's a scalar type being defined
                    if (\PHP_VERSION_ID >= 70400 && $rprop->hasType()) {
                        $rPropType = $rprop->getType();
                        $propTypeName = $this->stringifyReflectionType($rPropType);
                        if ($this->isSimpleType($propTypeName)) {
                            return array(\true, $rprop, $propTypeName, $rPropType->allowsNull());
                        }
                        return array(\true, $rprop, '\\' . \ltrim($propTypeName, '\\'), $rPropType->allowsNull());
                    }
                    return array(\true, $rprop, null, \false);
                }
                //support "@var type description"
                list($type) = \explode(' ', $annotations['var'][0]);
                return array(\true, $rprop, $type, $this->isNullable($type));
            } else {
                //no setter, private property
                return array(\true, null, null, \false);
            }
        }
        //no setter, no property
        return array(\false, null, null, \false);
    }
    /**
     * Removes - and _ and makes the next letter uppercase
     *
     * @param string $name Property name
     *
     * @return string CamelCasedVariableName
     */
    protected function getCamelCaseName($name)
    {
        return \str_replace(' ', '', \ucwords(\str_replace(array('_', '-'), ' ', $name)));
    }
    /**
     * Since hyphens cannot be used in variables we have to uppercase them.
     *
     * Technically you may use them, but they are awkward to access.
     *
     * @param string $name Property name
     *
     * @return string Name without hyphen
     */
    protected function getSafeName($name)
    {
        if (\strpos($name, '-') !== \false) {
            $name = $this->getCamelCaseName($name);
        }
        return $name;
    }
    /**
     * Set a property on a given object to a given value.
     *
     * Checks if the setter or the property are public are made before
     * calling this method.
     *
     * @param object $object   Object to set property on
     * @param object $accessor ReflectionMethod or ReflectionProperty
     * @param mixed  $value    Value of property
     *
     * @return void
     */
    protected function setProperty($object, $accessor, $value)
    {
        if (!$accessor->isPublic() && $this->bIgnoreVisibility) {
            $accessor->setAccessible(\true);
        }
        if ($accessor instanceof \ReflectionProperty) {
            $accessor->setValue($object, $value);
        } else {
            //setter method
            $accessor->invoke($object, $value);
        }
    }
    /**
     * Create a new object of the given type.
     *
     * This method exists to be overwritten in child classes,
     * so you can do dependency injection or so.
     *
     * @param string  $class        Class name to instantiate
     * @param boolean $useParameter Pass $parameter to the constructor or not
     * @param mixed   $jvalue       Constructor parameter (the json value)
     *
     * @return object Freshly created object
     */
    protected function createInstance($class, $useParameter = \false, $jvalue = null)
    {
        if ($useParameter) {
            return new $class($jvalue);
        } else {
            $reflectClass = new \ReflectionClass($class);
            $constructor = $reflectClass->getConstructor();
            if (null === $constructor || $constructor->getNumberOfRequiredParameters() > 0) {
                return $reflectClass->newInstanceWithoutConstructor();
            }
            return $reflectClass->newInstance();
        }
    }
    /**
     * Get the mapped class/type name for this class.
     * Returns the incoming classname if not mapped.
     *
     * @param string $type   Type name to map
     * @param mixed  $jvalue Constructor parameter (the json value)
     *
     * @return string The mapped type/class name
     */
    protected function getMappedType($type, $jvalue = null)
    {
        if (isset($this->classMap[$type])) {
            $target = $this->classMap[$type];
        } else {
            if (\is_string($type) && $type !== '' && $type[0] == '\\' && isset($this->classMap[\substr($type, 1)])) {
                $target = $this->classMap[\substr($type, 1)];
            } else {
                $target = null;
            }
        }
        if ($target) {
            if (\is_callable($target)) {
                $type = $target($type, $jvalue);
            } else {
                $type = $target;
            }
        }
        return $type;
    }
    /**
     * Checks if the given type is a "simple type"
     *
     * @param string $type type name from gettype()
     *
     * @return boolean True if it is a simple PHP type
     *
     * @see isFlatType()
     */
    protected function isSimpleType($type)
    {
        return $type == 'string' || $type == 'boolean' || $type == 'bool' || $type == 'integer' || $type == 'int' || $type == 'double' || $type == 'float' || $type == 'array' || $type == 'object';
    }
    /**
     * Checks if the object is of this type or has this type as one of its parents
     *
     * @param string $type  class name of type being required
     * @param mixed  $value Some PHP value to be tested
     *
     * @return boolean True if $object has type of $type
     */
    protected function isObjectOfSameType($type, $value)
    {
        if (\false === \is_object($value)) {
            return \false;
        }
        return \is_a($value, $type);
    }
    /**
     * Checks if the given type is a type that is not nested
     * (simple type except array and object)
     *
     * @param string $type type name from gettype()
     *
     * @return boolean True if it is a non-nested PHP type
     *
     * @see isSimpleType()
     */
    protected function isFlatType($type)
    {
        return $type == 'NULL' || $type == 'string' || $type == 'boolean' || $type == 'bool' || $type == 'integer' || $type == 'int' || $type == 'double' || $type == 'float';
    }
    /**
     * Returns true if type is an array of elements
     * (bracket notation)
     *
     * @param string $strType type to be matched
     *
     * @return bool
     */
    protected function isArrayOfType($strType)
    {
        return \substr($strType, -2) === '[]';
    }
    /**
     * Checks if the given type is nullable
     *
     * @param string $type type name from the phpdoc param
     *
     * @return boolean True if it is nullable
     */
    protected function isNullable($type)
    {
        return \stripos('|' . $type . '|', '|null|') !== \false;
    }
    /**
     * Remove the 'null' section of a type
     *
     * @param string $type type name from the phpdoc param
     *
     * @return string The new type value
     */
    protected function removeNullable($type)
    {
        if ($type === null) {
            return null;
        }
        return \substr(\str_ireplace('|null|', '|', '|' . $type . '|'), 1, -1);
    }
    /**
     * Get a string representation of the reflection type.
     * Required because named, union and intersection types need to be handled.
     *
     * @param ReflectionType $type Native PHP type
     *
     * @return string "foo|bar"
     */
    protected function stringifyReflectionType(\ReflectionType $type)
    {
        if ($type instanceof \ReflectionNamedType) {
            return ($type->isBuiltin() ? '' : '\\') . $type->getName();
        }
        return \implode('|', \array_map(function (\ReflectionNamedType $type) {
            return ($type->isBuiltin() ? '' : '\\') . $type->getName();
        }, $type->getTypes()));
    }
    /**
     * Copied from PHPUnit 3.7.29, Util/Test.php
     *
     * @param string $docblock Full method docblock
     *
     * @return array Array of arrays.
     *               Key is the "@"-name like "param",
     *               each value is an array of the rest of the @-lines
     */
    protected static function parseAnnotations($docblock)
    {
        $annotations = array();
        // Strip away the docblock header and footer
        // to ease parsing of one line annotations
        $docblock = \substr($docblock, 3, -2);
        $re = '/@(?P<name>[A-Za-z_-]+)(?:[ \\t]+(?P<value>.*?))?[ \\t]*\\r?$/m';
        if (\preg_match_all($re, $docblock, $matches)) {
            $numMatches = \count($matches[0]);
            for ($i = 0; $i < $numMatches; ++$i) {
                $annotations[$matches['name'][$i]][] = $matches['value'][$i];
            }
        }
        return $annotations;
    }
    /**
     * Log a message to the $logger object
     *
     * @param string $level   Logging level
     * @param string $message Text to log
     * @param array  $context Additional information
     *
     * @return null
     */
    protected function log($level, $message, array $context = array())
    {
        if ($this->logger) {
            $this->logger->log($level, $message, $context);
        }
    }
    /**
     * Sets a logger instance on the object
     *
     * @param LoggerInterface $logger PSR-3 compatible logger object
     *
     * @return null
     */
    public function setLogger($logger)
    {
        $this->logger = $logger;
    }
}
Open Software License v. 3.0 (OSL-3.0)

This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:

     Licensed under the Open Software License version 3.0

1) Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:

     a) to reproduce the Original Work in copies, either alone or as part of a collective work;
    
     b) to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;

     c) to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License;

     d) to perform the Original Work publicly; and

     e) to display the Original Work publicly.

2) Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.

3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.

4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor’s trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.

5) External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).

6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.

7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.

8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.

9) Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including “fair use” or “fair dealing”). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).

10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.

11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.

12) Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.

13) Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.

14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.

16) Modification of This License. This License is Copyright (c) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.<?php

// autoload.php @generated by Composer

if (PHP_VERSION_ID < 50600) {
    if (!headers_sent()) {
        header('HTTP/1.1 500 Internal Server Error');
    }
    $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
    if (!ini_get('display_errors')) {
        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
            fwrite(STDERR, $err);
        } elseif (!headers_sent()) {
            echo $err;
        }
    }
    trigger_error(
        $err,
        E_USER_ERROR
    );
}

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit7e022409458d7c6e0a17a3098ef276ac::getLoader();
<?php

namespace _HumbugBox1cb33d1f20f1\Spatie\ArrayToXml;

use DOMDocument;
use DOMElement;
use DOMException;
use Exception;
class ArrayToXml
{
    protected $document;
    protected $replaceSpacesByUnderScoresInKeyNames = \true;
    protected $addXmlDeclaration = \true;
    protected $numericTagNamePrefix = 'numeric_';
    public function __construct(array $array, $rootElement = '', $replaceSpacesByUnderScoresInKeyNames = \true, $xmlEncoding = null, $xmlVersion = '1.0', $domProperties = [], $xmlStandalone = null)
    {
        $this->document = new DOMDocument($xmlVersion, $xmlEncoding ?? '');
        if (!\is_null($xmlStandalone)) {
            $this->document->xmlStandalone = $xmlStandalone;
        }
        if (!empty($domProperties)) {
            $this->setDomProperties($domProperties);
        }
        $this->replaceSpacesByUnderScoresInKeyNames = $replaceSpacesByUnderScoresInKeyNames;
        if (!empty($array) && $this->isArrayAllKeySequential($array)) {
            throw new DOMException('Invalid Character Error');
        }
        $root = $this->createRootElement($rootElement);
        $this->document->appendChild($root);
        $this->convertElement($root, $array);
    }
    public function setNumericTagNamePrefix(string $prefix)
    {
        $this->numericTagNamePrefix = $prefix;
    }
    public static function convert(array $array, $rootElement = '', bool $replaceSpacesByUnderScoresInKeyNames = \true, string $xmlEncoding = null, string $xmlVersion = '1.0', array $domProperties = [], bool $xmlStandalone = null)
    {
        $converter = new static($array, $rootElement, $replaceSpacesByUnderScoresInKeyNames, $xmlEncoding, $xmlVersion, $domProperties, $xmlStandalone);
        return $converter->toXml();
    }
    public function toXml() : string
    {
        return $this->addXmlDeclaration ? $this->document->saveXML() : $this->document->saveXml($this->document->documentElement);
    }
    public function toDom() : DOMDocument
    {
        return $this->document;
    }
    protected function ensureValidDomProperties(array $domProperties)
    {
        foreach ($domProperties as $key => $value) {
            if (!\property_exists($this->document, $key)) {
                throw new Exception("{$key} is not a valid property of DOMDocument");
            }
        }
    }
    public function setDomProperties(array $domProperties)
    {
        $this->ensureValidDomProperties($domProperties);
        foreach ($domProperties as $key => $value) {
            $this->document->{$key} = $value;
        }
        return $this;
    }
    public function prettify()
    {
        $this->document->preserveWhiteSpace = \false;
        $this->document->formatOutput = \true;
        return $this;
    }
    public function dropXmlDeclaration()
    {
        $this->addXmlDeclaration = \false;
        return $this;
    }
    public function addProcessingInstruction($target, $data)
    {
        $elements = $this->document->getElementsByTagName('*');
        $rootElement = $elements->count() > 0 ? $elements->item(0) : null;
        $processingInstruction = $this->document->createProcessingInstruction($target, $data);
        $this->document->insertBefore($processingInstruction, $rootElement);
        return $this;
    }
    private function convertElement(DOMElement $element, $value)
    {
        $sequential = $this->isArrayAllKeySequential($value);
        if (!\is_array($value)) {
            $value = \htmlspecialchars($value ?? '');
            $value = $this->removeControlCharacters($value);
            $element->nodeValue = $value;
            return;
        }
        foreach ($value as $key => $data) {
            if (!$sequential) {
                if ($key === '_attributes' || $key === '@attributes') {
                    $this->addAttributes($element, $data);
                } elseif (($key === '_value' || $key === '@value') && \is_string($data)) {
                    $element->nodeValue = \htmlspecialchars($data);
                } elseif (($key === '_cdata' || $key === '@cdata') && \is_string($data)) {
                    $element->appendChild($this->document->createCDATASection($data));
                } elseif (($key === '_mixed' || $key === '@mixed') && \is_string($data)) {
                    $fragment = $this->document->createDocumentFragment();
                    $fragment->appendXML($data);
                    $element->appendChild($fragment);
                } elseif ($key === '__numeric') {
                    $this->addNumericNode($element, $data);
                } elseif (\substr($key, 0, 9) === '__custom:') {
                    $this->addNode($element, \str_replace('\\:', ':', \preg_split('/(?<!\\\\):/', $key)[1]), $data);
                } else {
                    $this->addNode($element, $key, $data);
                }
            } elseif (\is_array($data)) {
                $this->addCollectionNode($element, $data);
            } else {
                $this->addSequentialNode($element, $data);
            }
        }
    }
    protected function addNumericNode(DOMElement $element, $value)
    {
        foreach ($value as $key => $item) {
            $this->convertElement($element, [$this->numericTagNamePrefix . $key => $item]);
        }
    }
    protected function addNode(DOMElement $element, $key, $value)
    {
        if ($this->replaceSpacesByUnderScoresInKeyNames) {
            $key = \str_replace(' ', '_', $key);
        }
        $child = $this->document->createElement($key);
        $element->appendChild($child);
        $this->convertElement($child, $value);
    }
    protected function addCollectionNode(DOMElement $element, $value)
    {
        if ($element->childNodes->length === 0 && $element->attributes->length === 0) {
            $this->convertElement($element, $value);
            return;
        }
        $child = $this->document->createElement($element->tagName);
        $element->parentNode->appendChild($child);
        $this->convertElement($child, $value);
    }
    protected function addSequentialNode(DOMElement $element, $value)
    {
        if (empty($element->nodeValue) && !\is_numeric($element->nodeValue)) {
            $element->nodeValue = \htmlspecialchars($value);
            return;
        }
        $child = $this->document->createElement($element->tagName);
        $child->nodeValue = \htmlspecialchars($value);
        $element->parentNode->appendChild($child);
    }
    protected function isArrayAllKeySequential($value)
    {
        if (!\is_array($value)) {
            return \false;
        }
        if (\count($value) <= 0) {
            return \true;
        }
        if (\key($value) === '__numeric') {
            return \false;
        }
        return \array_unique(\array_map('is_int', \array_keys($value))) === [\true];
    }
    protected function addAttributes(DOMElement $element, array $data)
    {
        foreach ($data as $attrKey => $attrVal) {
            $element->setAttribute($attrKey, $attrVal ?? '');
        }
    }
    protected function createRootElement($rootElement) : DOMElement
    {
        if (\is_string($rootElement)) {
            $rootElementName = $rootElement ?: 'root';
            return $this->document->createElement($rootElementName);
        }
        $rootElementName = $rootElement['rootElementName'] ?? 'root';
        $element = $this->document->createElement($rootElementName);
        foreach ($rootElement as $key => $value) {
            if ($key !== '_attributes' && $key !== '@attributes') {
                continue;
            }
            $this->addAttributes($element, $rootElement[$key]);
        }
        return $element;
    }
    protected function removeControlCharacters(string $value) : string
    {
        return \preg_replace('/[\\x00-\\x09\\x0B\\x0C\\x0E-\\x1F\\x7F]/', '', $value);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\XdgBaseDir;

/**
 * Simple implementation of the XDG standard http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
 *
 * Based on the python implementation https://github.com/takluyver/pyxdg/blob/master/xdg/BaseDirectory.py
 */
class Xdg
{
    const S_IFDIR = 040000;
    // directory
    const S_IRWXO = 07;
    // rwx other
    const S_IRWXG = 056;
    // rwx group
    const RUNTIME_DIR_FALLBACK = 'php-xdg-runtime-dir-fallback-';
    /**
     * @return string
     */
    public function getHomeDir()
    {
        return \getenv('HOME') ?: \getenv('HOMEDRIVE') . \DIRECTORY_SEPARATOR . \getenv('HOMEPATH');
    }
    /**
     * @return string
     */
    public function getHomeConfigDir()
    {
        if ($path = \getenv('XDG_CONFIG_HOME')) {
            return $path;
        }
        $homeDir = $this->getHomeDir();
        $path = \DIRECTORY_SEPARATOR === $homeDir ? $homeDir . '.config' : $homeDir . \DIRECTORY_SEPARATOR . '.config';
        return $path;
    }
    /**
     * @return string
     */
    public function getHomeDataDir()
    {
        $path = \getenv('XDG_DATA_HOME') ?: $this->getHomeDir() . \DIRECTORY_SEPARATOR . '.local' . \DIRECTORY_SEPARATOR . 'share';
        return $path;
    }
    /**
     * @return array
     */
    public function getConfigDirs()
    {
        $configDirs = \getenv('XDG_CONFIG_DIRS') ? \explode(':', \getenv('XDG_CONFIG_DIRS')) : array('/etc/xdg');
        $paths = \array_merge(array($this->getHomeConfigDir()), $configDirs);
        return $paths;
    }
    /**
     * @return array
     */
    public function getDataDirs()
    {
        $dataDirs = \getenv('XDG_DATA_DIRS') ? \explode(':', \getenv('XDG_DATA_DIRS')) : array('/usr/local/share', '/usr/share');
        $paths = \array_merge(array($this->getHomeDataDir()), $dataDirs);
        return $paths;
    }
    /**
     * @return string
     */
    public function getHomeCacheDir()
    {
        $path = \getenv('XDG_CACHE_HOME') ?: $this->getHomeDir() . \DIRECTORY_SEPARATOR . '.cache';
        return $path;
    }
    public function getRuntimeDir($strict = \true)
    {
        if ($runtimeDir = \getenv('XDG_RUNTIME_DIR')) {
            return $runtimeDir;
        }
        if ($strict) {
            throw new \RuntimeException('XDG_RUNTIME_DIR was not set');
        }
        $fallback = \sys_get_temp_dir() . \DIRECTORY_SEPARATOR . self::RUNTIME_DIR_FALLBACK . \getenv('USER');
        $create = \false;
        if (!\is_dir($fallback)) {
            \mkdir($fallback, 0700, \true);
        }
        $st = \lstat($fallback);
        # The fallback must be a directory
        if (!$st['mode'] & self::S_IFDIR) {
            \rmdir($fallback);
            $create = \true;
        } elseif ($st['uid'] != $this->getUid() || $st['mode'] & (self::S_IRWXG | self::S_IRWXO)) {
            \rmdir($fallback);
            $create = \true;
        }
        if ($create) {
            \mkdir($fallback, 0700, \true);
        }
        return $fallback;
    }
    private function getUid()
    {
        if (\function_exists('posix_getuid')) {
            return \posix_getuid();
        }
        return \getmyuid();
    }
}
Copyright (c) 2014 Daniel Nögel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PackageVersions;

use _HumbugBox1cb33d1f20f1\Composer\Composer;
use _HumbugBox1cb33d1f20f1\Composer\Config;
use _HumbugBox1cb33d1f20f1\Composer\EventDispatcher\EventSubscriberInterface;
use _HumbugBox1cb33d1f20f1\Composer\IO\IOInterface;
use _HumbugBox1cb33d1f20f1\Composer\Package\AliasPackage;
use _HumbugBox1cb33d1f20f1\Composer\Package\Locker;
use _HumbugBox1cb33d1f20f1\Composer\Package\PackageInterface;
use _HumbugBox1cb33d1f20f1\Composer\Package\RootPackageInterface;
use _HumbugBox1cb33d1f20f1\Composer\Plugin\PluginInterface;
use _HumbugBox1cb33d1f20f1\Composer\Script\Event;
use _HumbugBox1cb33d1f20f1\Composer\Script\ScriptEvents;
use Generator;
use RuntimeException;
use function array_key_exists;
use function array_merge;
use function chmod;
use function dirname;
use function file_exists;
use function file_put_contents;
use function is_writable;
use function iterator_to_array;
use function rename;
use function sprintf;
use function uniqid;
use function var_export;
final class Installer implements PluginInterface, EventSubscriberInterface
{
    private static $generatedClassTemplate = <<<'PHP'
<?php

declare(strict_types=1);

namespace PackageVersions;

use Composer\InstalledVersions;
use OutOfBoundsException;

class_exists(InstalledVersions::class);

/**
 * This class is generated by composer/package-versions-deprecated, specifically by
 * @see \PackageVersions\Installer
 *
 * This file is overwritten at every run of `composer install` or `composer update`.
 *
 * @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
 */
%s
{
    /**
     * @deprecated please use {@see self::rootPackageName()} instead.
     *             This constant will be removed in version 2.0.0.
     */
    const ROOT_PACKAGE_NAME = '%s';

    /**
     * Array of all available composer packages.
     * Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead.
     *
     * @var array<string, string>
     * @internal
     */
    const VERSIONS          = %s;

    private function __construct()
    {
    }

    /**
     * @psalm-pure
     *
     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
     *                                  cause any side effects here.
     */
    public static function rootPackageName() : string
    {
        if (!self::composer2ApiUsable()) {
            return self::ROOT_PACKAGE_NAME;
        }

        return InstalledVersions::getRootPackage()['name'];
    }

    /**
     * @throws OutOfBoundsException If a version cannot be located.
     *
     * @psalm-param key-of<self::VERSIONS> $packageName
     * @psalm-pure
     *
     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
     *                                  cause any side effects here.
     */
    public static function getVersion(string $packageName): string
    {
        if (self::composer2ApiUsable()) {
            return InstalledVersions::getPrettyVersion($packageName)
                . '@' . InstalledVersions::getReference($packageName);
        }

        if (isset(self::VERSIONS[$packageName])) {
            return self::VERSIONS[$packageName];
        }

        throw new OutOfBoundsException(
            'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
        );
    }

    private static function composer2ApiUsable(): bool
    {
        if (!class_exists(InstalledVersions::class, false)) {
            return false;
        }

        if (method_exists(InstalledVersions::class, 'getAllRawData')) {
            $rawData = InstalledVersions::getAllRawData();
            if (count($rawData) === 1 && count($rawData[0]) === 0) {
                return false;
            }
        } else {
            $rawData = InstalledVersions::getRawData();
            if ($rawData === null || $rawData === []) {
                return false;
            }
        }

        return true;
    }
}

PHP;
    public function activate(Composer $composer, IOInterface $io)
    {
        // Nothing to do here, as all features are provided through event listeners
    }
    public function deactivate(Composer $composer, IOInterface $io)
    {
        // Nothing to do here, as all features are provided through event listeners
    }
    public function uninstall(Composer $composer, IOInterface $io)
    {
        // Nothing to do here, as all features are provided through event listeners
    }
    /**
     * {@inheritDoc}
     */
    public static function getSubscribedEvents() : array
    {
        return [ScriptEvents::POST_AUTOLOAD_DUMP => 'dumpVersionsClass'];
    }
    /**
     * @throws RuntimeException
     */
    public static function dumpVersionsClass(Event $composerEvent)
    {
        $composer = $composerEvent->getComposer();
        $rootPackage = $composer->getPackage();
        $versions = iterator_to_array(self::getVersions($composer->getLocker(), $rootPackage));
        if (!array_key_exists('composer/package-versions-deprecated', $versions)) {
            //plugin must be globally installed - we only want to generate versions for projects which specifically
            //require composer/package-versions-deprecated
            return;
        }
        $versionClass = self::generateVersionsClass($rootPackage->getName(), $versions);
        self::writeVersionClassToFile($versionClass, $composer, $composerEvent->getIO());
    }
    /**
     * @param string[] $versions
     */
    private static function generateVersionsClass(string $rootPackageName, array $versions) : string
    {
        return sprintf(
            self::$generatedClassTemplate,
            'fin' . 'al ' . 'cla' . 'ss ' . 'Versions',
            // note: workaround for regex-based code parsers :-(
            $rootPackageName,
            var_export($versions, \true)
        );
    }
    /**
     * @throws RuntimeException
     */
    private static function writeVersionClassToFile(string $versionClassSource, Composer $composer, IOInterface $io)
    {
        $installPath = self::locateRootPackageInstallPath($composer->getConfig(), $composer->getPackage()) . '/src/PackageVersions/Versions.php';
        $installDir = dirname($installPath);
        if (!file_exists($installDir)) {
            $io->write('<info>composer/package-versions-deprecated:</info> Package not found (probably scheduled for removal); generation of version class skipped.');
            return;
        }
        if (!is_writable($installDir)) {
            $io->write(sprintf('<info>composer/package-versions-deprecated:</info> %s is not writable; generation of version class skipped.', $installDir));
            return;
        }
        $io->write('<info>composer/package-versions-deprecated:</info> Generating version class...');
        $installPathTmp = $installPath . '_' . uniqid('tmp', \true);
        file_put_contents($installPathTmp, $versionClassSource);
        chmod($installPathTmp, 0664);
        rename($installPathTmp, $installPath);
        $io->write('<info>composer/package-versions-deprecated:</info> ...done generating version class');
    }
    /**
     * @throws RuntimeException
     */
    private static function locateRootPackageInstallPath(Config $composerConfig, RootPackageInterface $rootPackage) : string
    {
        if (self::getRootPackageAlias($rootPackage)->getName() === 'composer/package-versions-deprecated') {
            return dirname($composerConfig->get('vendor-dir'));
        }
        return $composerConfig->get('vendor-dir') . '/composer/package-versions-deprecated';
    }
    private static function getRootPackageAlias(RootPackageInterface $rootPackage) : PackageInterface
    {
        $package = $rootPackage;
        while ($package instanceof AliasPackage) {
            $package = $package->getAliasOf();
        }
        return $package;
    }
    /**
     * @return Generator&string[]
     *
     * @psalm-return Generator<string, string>
     */
    private static function getVersions(Locker $locker, RootPackageInterface $rootPackage) : Generator
    {
        $lockData = $locker->getLockData();
        $lockData['packages-dev'] = $lockData['packages-dev'] ?? [];
        $packages = $lockData['packages'];
        if (\getenv('COMPOSER_DEV_MODE') !== '0') {
            $packages = array_merge($packages, $lockData['packages-dev']);
        }
        foreach ($packages as $package) {
            (yield $package['name'] => $package['version'] . '@' . ($package['source']['reference'] ?? $package['dist']['reference'] ?? ''));
        }
        foreach ($rootPackage->getReplaces() as $replace) {
            $version = $replace->getPrettyConstraint();
            if ($version === 'self.version') {
                $version = $rootPackage->getPrettyVersion();
            }
            (yield $replace->getTarget() => $version . '@' . $rootPackage->getSourceReference());
        }
        (yield $rootPackage->getName() => $rootPackage->getPrettyVersion() . '@' . $rootPackage->getSourceReference());
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PackageVersions;

use _HumbugBox1cb33d1f20f1\Composer\InstalledVersions;
use OutOfBoundsException;
\class_exists(InstalledVersions::class);
/**
 * This class is generated by composer/package-versions-deprecated, specifically by
 * @see \PackageVersions\Installer
 *
 * This file is overwritten at every run of `composer install` or `composer update`.
 *
 * @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
 */
final class Versions
{
    /**
     * @deprecated please use {@see self::rootPackageName()} instead.
     *             This constant will be removed in version 2.0.0.
     */
    const ROOT_PACKAGE_NAME = 'vimeo/psalm';
    /**
     * Array of all available composer packages.
     * Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead.
     *
     * @var array<string, string>
     * @internal
     */
    const VERSIONS = array('amphp/amp' => 'v2.6.2@9d5100cebffa729aaffecd3ad25dc5aeea4f13bb', 'amphp/byte-stream' => 'v1.8.1@acbd8002b3536485c997c4e019206b3f10ca15bd', 'composer/package-versions-deprecated' => '1.11.99.5@b4f54f74ef3453349c24a845d22392cd31e65f1d', 'composer/pcre' => '3.1.0@4bff79ddd77851fe3cdd11616ed3f92841ba5bd2', 'composer/semver' => '3.3.2@3953f23262f2bff1919fc82183ad9acb13ff62c9', 'composer/xdebug-handler' => '3.0.3@ced299686f41dce890debac69273b47ffe98a40c', 'dnoegel/php-xdg-base-dir' => 'v0.1.1@8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd', 'felixfbecker/advanced-json-rpc' => 'v3.2.1@b5f37dbff9a8ad360ca341f3240dc1c168b45447', 'felixfbecker/language-server-protocol' => 'v1.5.2@6e82196ffd7c62f7794d778ca52b69feec9f2842', 'fidry/cpu-core-counter' => '0.4.1@79261cc280aded96d098e1b0e0ba0c4881b432c2', 'netresearch/jsonmapper' => 'v4.1.0@cfa81ea1d35294d64adb9c68aa4cb9e92400e53f', 'nikic/php-parser' => 'v4.15.3@570e980a201d8ed0236b0a62ddf2c9cbb2034039', 'phpdocumentor/reflection-common' => '2.2.0@1d01c49d4ed62f25aa84a747ad35d5a16924662b', 'phpdocumentor/reflection-docblock' => '5.3.0@622548b623e81ca6d78b721c5e029f4ce664f170', 'phpdocumentor/type-resolver' => '1.6.2@48f445a408c131e38cab1c235aa6d2bb7a0bb20d', 'psr/container' => '1.1.2@513e0666f7216c7459170d56df27dfcefe1689ea', 'psr/log' => '1.1.4@d49695b909c3b7628b6289db5479a1c204601f11', 'sebastian/diff' => '4.0.4@3461e3fccc7cfdfc2720be910d3bd73c69be590d', 'spatie/array-to-xml' => '2.17.1@5cbec9c6ab17e320c58a259f0cebe88bde4a7c46', 'symfony/console' => 'v5.4.17@58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f', 'symfony/deprecation-contracts' => 'v2.5.2@e8b495ea28c1d97b5e0c121748d6f9b53d075c66', 'symfony/filesystem' => 'v5.4.13@ac09569844a9109a5966b9438fc29113ce77cf51', 'symfony/polyfill-ctype' => 'v1.27.0@5bbc823adecdae860bb64756d639ecfec17b050a', 'symfony/polyfill-intl-grapheme' => 'v1.27.0@511a08c03c1960e08a883f4cffcacd219b758354', 'symfony/polyfill-intl-normalizer' => 'v1.27.0@19bd1e4fcd5b91116f14d8533c57831ed00571b6', 'symfony/polyfill-mbstring' => 'v1.27.0@8ad114f6b39e2c98a8b0e3bd907732c207c2b534', 'symfony/polyfill-php73' => 'v1.27.0@9e8ecb5f92152187c4799efd3c96b78ccab18ff9', 'symfony/polyfill-php80' => 'v1.27.0@7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936', 'symfony/service-contracts' => 'v2.5.2@4b426aac47d6427cc1a1d0f7e2ac724627f5966c', 'symfony/string' => 'v5.4.17@55733a8664b8853b003e70251c58bc8cb2d82a6b', 'webmozart/assert' => '1.11.0@11cb2199493b2f8a3b53e7f19068fc6aac760991', 'bamarni/composer-bin-plugin' => '1.8.2@92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880', 'brianium/paratest' => 'v6.8.1@168c1cfdf79e5b19b57cb03060fc9a6a79c5f582', 'dealerdirect/phpcodesniffer-composer-installer' => 'v1.0.0@4be43904336affa5c2f70744a348312336afd0da', 'dg/bypass-finals' => 'v1.4.1@4c424c3ed359220fce044f35cdf9f48b0089b2ca', 'doctrine/instantiator' => '1.5.0@0a0fa9780f5d4e507415a065172d26a98d02047b', 'hamcrest/hamcrest-php' => 'v2.0.1@8c3d0a3f6af734494ad8f6fbbee0ba92422859f3', 'jean85/pretty-package-versions' => '2.0.5@ae547e455a3d8babd07b96966b17d7fd21d9c6af', 'mockery/mockery' => '1.5.1@e92dcc83d5a51851baf5f5591d32cb2b16e3684e', 'myclabs/deep-copy' => '1.11.0@14daed4296fae74d9e3201d2c4925d1acb7aa614', 'nunomaduro/mock-final-classes' => 'v1.1.0@5d113210c085ac13a8e1225f8b6f390c797a98f0', 'phar-io/manifest' => '2.0.3@97803eca37d319dfa7826cc2437fc020857acb53', 'phar-io/version' => '3.2.1@4f7fd7836c6f332bb2933569e566a0d6c4cbed74', 'php-parallel-lint/php-parallel-lint' => 'v1.3.2@6483c9832e71973ed29cf71bd6b3f4fde438a9de', 'phpstan/phpdoc-parser' => '1.15.3@61800f71a5526081d1b5633766aa88341f1ade76', 'phpunit/php-code-coverage' => '9.2.23@9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c', 'phpunit/php-file-iterator' => '3.0.6@cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf', 'phpunit/php-invoker' => '3.1.1@5a10147d0aaf65b58940a0b72f71c9ac0423cc67', 'phpunit/php-text-template' => '2.0.4@5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28', 'phpunit/php-timer' => '5.0.3@5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2', 'phpunit/phpunit' => '9.5.28@954ca3113a03bf780d22f07bf055d883ee04b65e', 'psalm/plugin-mockery' => '1.1.0@876247d15f91df08240d00dac69c5135b6689283', 'psalm/plugin-phpunit' => '0.18.4@e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc', 'sebastian/cli-parser' => '1.0.1@442e7c7e687e42adc03470c7b668bc4b2402c0b2', 'sebastian/code-unit' => '1.0.8@1fc9f64c0927627ef78ba436c9b17d967e68e120', 'sebastian/code-unit-reverse-lookup' => '2.0.3@ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5', 'sebastian/comparator' => '4.0.8@fa0f136dd2334583309d32b62544682ee972b51a', 'sebastian/complexity' => '2.0.2@739b35e53379900cc9ac327b2147867b8b6efd88', 'sebastian/environment' => '5.1.4@1b5dff7bb151a4db11d49d90e5408e4e938270f7', 'sebastian/exporter' => '4.0.5@ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d', 'sebastian/global-state' => '5.0.5@0ca8db5a5fc9c8646244e629625ac486fa286bf2', 'sebastian/lines-of-code' => '1.0.3@c1c2e997aa3146983ed888ad08b15470a2e22ecc', 'sebastian/object-enumerator' => '4.0.4@5c9eeac41b290a3712d88851518825ad78f45c71', 'sebastian/object-reflector' => '2.0.4@b4f479ebdbf63ac605d183ece17d8d7fe49c15c7', 'sebastian/recursion-context' => '4.0.4@cd9d8cf3c5804de4341c283ed787f099f5506172', 'sebastian/resource-operations' => '3.0.3@0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8', 'sebastian/type' => '3.2.0@fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e', 'sebastian/version' => '3.0.2@c6c1022351a901512170118436c764e473f6de8c', 'slevomat/coding-standard' => '8.8.0@59e25146a4ef0a7b194c5bc55b32dd414345db89', 'squizlabs/php_codesniffer' => '3.7.1@1359e176e9307e906dc3d890bcc9603ff6d90619', 'symfony/process' => 'v5.4.11@6e75fe6874cbc7e4773d049616ab450eff537bf1', 'theseer/tokenizer' => '1.2.1@34a41e998c2183e22995f158c581e7b5e755ab9e', 'vimeo/psalm' => '5.6.0@e784128902dfe01d489c4123d69918a9f3c1eac5');
    private function __construct()
    {
    }
    /**
     * @psalm-pure
     *
     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
     *                                  cause any side effects here.
     */
    public static function rootPackageName() : string
    {
        if (!self::composer2ApiUsable()) {
            return self::ROOT_PACKAGE_NAME;
        }
        return InstalledVersions::getRootPackage()['name'];
    }
    /**
     * @throws OutOfBoundsException If a version cannot be located.
     *
     * @psalm-param key-of<self::VERSIONS> $packageName
     * @psalm-pure
     *
     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
     *                                  cause any side effects here.
     */
    public static function getVersion(string $packageName) : string
    {
        if (self::composer2ApiUsable()) {
            return InstalledVersions::getPrettyVersion($packageName) . '@' . InstalledVersions::getReference($packageName);
        }
        if (isset(self::VERSIONS[$packageName])) {
            return self::VERSIONS[$packageName];
        }
        throw new OutOfBoundsException('Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files');
    }
    private static function composer2ApiUsable() : bool
    {
        if (!\class_exists(InstalledVersions::class, \false)) {
            return \false;
        }
        if (\method_exists(InstalledVersions::class, 'getAllRawData')) {
            $rawData = InstalledVersions::getAllRawData();
            if (\count($rawData) === 1 && \count($rawData[0]) === 0) {
                return \false;
            }
        } else {
            $rawData = InstalledVersions::getRawData();
            if ($rawData === null || $rawData === []) {
                return \false;
            }
        }
        return \true;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PackageVersions;

use Generator;
use OutOfBoundsException;
use UnexpectedValueException;
use function array_key_exists;
use function array_merge;
use function basename;
use function file_exists;
use function file_get_contents;
use function getcwd;
use function iterator_to_array;
use function json_decode;
use function json_encode;
use function sprintf;
/**
 * @internal
 *
 * This is a fallback for {@see \PackageVersions\Versions::getVersion()}
 * Do not use this class directly: it is intended to be only used when
 * {@see \PackageVersions\Versions} fails to be generated, which typically
 * happens when running composer with `--no-scripts` flag)
 */
final class FallbackVersions
{
    const ROOT_PACKAGE_NAME = 'unknown/root-package@UNKNOWN';
    private function __construct()
    {
    }
    /**
     * @throws OutOfBoundsException If a version cannot be located.
     * @throws UnexpectedValueException If the composer.lock file could not be located.
     */
    public static function getVersion(string $packageName) : string
    {
        $versions = iterator_to_array(self::getVersions(self::getPackageData()));
        if (!array_key_exists($packageName, $versions)) {
            throw new OutOfBoundsException('Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files');
        }
        return $versions[$packageName];
    }
    /**
     * @return mixed[]
     *
     * @throws UnexpectedValueException
     */
    private static function getPackageData() : array
    {
        $checkedPaths = [
            // The top-level project's ./vendor/composer/installed.json
            getcwd() . '/vendor/composer/installed.json',
            __DIR__ . '/../../../../composer/installed.json',
            // The top-level project's ./composer.lock
            getcwd() . '/composer.lock',
            __DIR__ . '/../../../../../composer.lock',
            // This package's composer.lock
            __DIR__ . '/../../composer.lock',
        ];
        $packageData = [];
        foreach ($checkedPaths as $path) {
            if (!file_exists($path)) {
                continue;
            }
            $data = json_decode(file_get_contents($path), \true);
            switch (basename($path)) {
                case 'installed.json':
                    // composer 2.x installed.json format
                    if (isset($data['packages'])) {
                        $packageData[] = $data['packages'];
                    } else {
                        // composer 1.x installed.json format
                        $packageData[] = $data;
                    }
                    break;
                case 'composer.lock':
                    $packageData[] = $data['packages'] + ($data['packages-dev'] ?? []);
                    break;
                default:
            }
        }
        if ($packageData !== []) {
            return array_merge(...$packageData);
        }
        throw new UnexpectedValueException(sprintf('PackageVersions could not locate the `vendor/composer/installed.json` or your `composer.lock` ' . 'location. This is assumed to be in %s. If you customized your composer vendor directory and ran composer ' . 'installation with --no-scripts, or if you deployed without the required composer files, PackageVersions ' . 'can\'t detect installed versions.', json_encode($checkedPaths)));
    }
    /**
     * @param mixed[] $packageData
     *
     * @return Generator&string[]
     *
     * @psalm-return Generator<string, string>
     */
    private static function getVersions(array $packageData) : Generator
    {
        foreach ($packageData as $package) {
            (yield $package['name'] => $package['version'] . '@' . ($package['source']['reference'] ?? $package['dist']['reference'] ?? ''));
        }
        (yield self::ROOT_PACKAGE_NAME => self::ROOT_PACKAGE_NAME);
    }
}
Copyright (c) 2016 Marco Pivetta

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Autoload;

/**
 * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 *
 *     $loader = new \Composer\Autoload\ClassLoader();
 *
 *     // register classes with namespaces
 *     $loader->add('Symfony\Component', __DIR__.'/component');
 *     $loader->add('Symfony',           __DIR__.'/framework');
 *
 *     // activate the autoloader
 *     $loader->register();
 *
 *     // to enable searching the include path (eg. for PEAR packages)
 *     $loader->setUseIncludePath(true);
 *
 * In this example, if you try to use a class in the Symfony\Component
 * namespace or one of its children (Symfony\Component\Console for instance),
 * the autoloader will first look for the class under the component/
 * directory, and it will then fallback to the framework/ directory if not
 * found before giving up.
 *
 * This class is loosely based on the Symfony UniversalClassLoader.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @see    https://www.php-fig.org/psr/psr-0/
 * @see    https://www.php-fig.org/psr/psr-4/
 */
class ClassLoader
{
    /** @var \Closure(string):void */
    private static $includeFile;

    /** @var ?string */
    private $vendorDir;

    // PSR-4
    /**
     * @var array[]
     * @psalm-var array<string, array<string, int>>
     */
    private $prefixLengthsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, array<int, string>>
     */
    private $prefixDirsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr4 = array();

    // PSR-0
    /**
     * @var array[]
     * @psalm-var array<string, array<string, string[]>>
     */
    private $prefixesPsr0 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr0 = array();

    /** @var bool */
    private $useIncludePath = false;

    /**
     * @var string[]
     * @psalm-var array<string, string>
     */
    private $classMap = array();

    /** @var bool */
    private $classMapAuthoritative = false;

    /**
     * @var bool[]
     * @psalm-var array<string, bool>
     */
    private $missingClasses = array();

    /** @var ?string */
    private $apcuPrefix;

    /**
     * @var self[]
     */
    private static $registeredLoaders = array();

    /**
     * @param ?string $vendorDir
     */
    public function __construct($vendorDir = null)
    {
        $this->vendorDir = $vendorDir;
        self::initializeIncludeClosure();
    }

    /**
     * @return string[]
     */
    public function getPrefixes()
    {
        if (!empty($this->prefixesPsr0)) {
            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
        }

        return array();
    }

    /**
     * @return array[]
     * @psalm-return array<string, array<int, string>>
     */
    public function getPrefixesPsr4()
    {
        return $this->prefixDirsPsr4;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirs()
    {
        return $this->fallbackDirsPsr0;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirsPsr4()
    {
        return $this->fallbackDirsPsr4;
    }

    /**
     * @return string[] Array of classname => path
     * @psalm-return array<string, string>
     */
    public function getClassMap()
    {
        return $this->classMap;
    }

    /**
     * @param string[] $classMap Class to filename map
     * @psalm-param array<string, string> $classMap
     *
     * @return void
     */
    public function addClassMap(array $classMap)
    {
        if ($this->classMap) {
            $this->classMap = array_merge($this->classMap, $classMap);
        } else {
            $this->classMap = $classMap;
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix, either
     * appending or prepending to the ones previously set for this prefix.
     *
     * @param string          $prefix  The prefix
     * @param string[]|string $paths   The PSR-0 root directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @return void
     */
    public function add($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            if ($prepend) {
                $this->fallbackDirsPsr0 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr0
                );
            } else {
                $this->fallbackDirsPsr0 = array_merge(
                    $this->fallbackDirsPsr0,
                    (array) $paths
                );
            }

            return;
        }

        $first = $prefix[0];
        if (!isset($this->prefixesPsr0[$first][$prefix])) {
            $this->prefixesPsr0[$first][$prefix] = (array) $paths;

            return;
        }
        if ($prepend) {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                (array) $paths,
                $this->prefixesPsr0[$first][$prefix]
            );
        } else {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                $this->prefixesPsr0[$first][$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace, either
     * appending or prepending to the ones previously set for this namespace.
     *
     * @param string          $prefix  The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths   The PSR-4 base directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function addPsr4($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            // Register directories for the root namespace.
            if ($prepend) {
                $this->fallbackDirsPsr4 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr4
                );
            } else {
                $this->fallbackDirsPsr4 = array_merge(
                    $this->fallbackDirsPsr4,
                    (array) $paths
                );
            }
        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
            // Register directories for a new namespace.
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        } elseif ($prepend) {
            // Prepend directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                (array) $paths,
                $this->prefixDirsPsr4[$prefix]
            );
        } else {
            // Append directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                $this->prefixDirsPsr4[$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix,
     * replacing any others previously set for this prefix.
     *
     * @param string          $prefix The prefix
     * @param string[]|string $paths  The PSR-0 base directories
     *
     * @return void
     */
    public function set($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr0 = (array) $paths;
        } else {
            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace,
     * replacing any others previously set for this namespace.
     *
     * @param string          $prefix The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths  The PSR-4 base directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function setPsr4($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr4 = (array) $paths;
        } else {
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        }
    }

    /**
     * Turns on searching the include path for class files.
     *
     * @param bool $useIncludePath
     *
     * @return void
     */
    public function setUseIncludePath($useIncludePath)
    {
        $this->useIncludePath = $useIncludePath;
    }

    /**
     * Can be used to check if the autoloader uses the include path to check
     * for classes.
     *
     * @return bool
     */
    public function getUseIncludePath()
    {
        return $this->useIncludePath;
    }

    /**
     * Turns off searching the prefix and fallback directories for classes
     * that have not been registered with the class map.
     *
     * @param bool $classMapAuthoritative
     *
     * @return void
     */
    public function setClassMapAuthoritative($classMapAuthoritative)
    {
        $this->classMapAuthoritative = $classMapAuthoritative;
    }

    /**
     * Should class lookup fail if not found in the current class map?
     *
     * @return bool
     */
    public function isClassMapAuthoritative()
    {
        return $this->classMapAuthoritative;
    }

    /**
     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
     *
     * @param string|null $apcuPrefix
     *
     * @return void
     */
    public function setApcuPrefix($apcuPrefix)
    {
        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
    }

    /**
     * The APCu prefix in use, or null if APCu caching is not enabled.
     *
     * @return string|null
     */
    public function getApcuPrefix()
    {
        return $this->apcuPrefix;
    }

    /**
     * Registers this instance as an autoloader.
     *
     * @param bool $prepend Whether to prepend the autoloader or not
     *
     * @return void
     */
    public function register($prepend = false)
    {
        spl_autoload_register(array($this, 'loadClass'), true, $prepend);

        if (null === $this->vendorDir) {
            return;
        }

        if ($prepend) {
            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
        } else {
            unset(self::$registeredLoaders[$this->vendorDir]);
            self::$registeredLoaders[$this->vendorDir] = $this;
        }
    }

    /**
     * Unregisters this instance as an autoloader.
     *
     * @return void
     */
    public function unregister()
    {
        spl_autoload_unregister(array($this, 'loadClass'));

        if (null !== $this->vendorDir) {
            unset(self::$registeredLoaders[$this->vendorDir]);
        }
    }

    /**
     * Loads the given class or interface.
     *
     * @param  string    $class The name of the class
     * @return true|null True if loaded, null otherwise
     */
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            (self::$includeFile)($file);

            return true;
        }

        return null;
    }

    /**
     * Finds the path to the file where the class is defined.
     *
     * @param string $class The name of the class
     *
     * @return string|false The path if found, false otherwise
     */
    public function findFile($class)
    {
        // class map lookup
        if (isset($this->classMap[$class])) {
            return $this->classMap[$class];
        }
        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
            return false;
        }
        if (null !== $this->apcuPrefix) {
            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
            if ($hit) {
                return $file;
            }
        }

        $file = $this->findFileWithExtension($class, '.php');

        // Search for Hack files if we are running on HHVM
        if (false === $file && defined('HHVM_VERSION')) {
            $file = $this->findFileWithExtension($class, '.hh');
        }

        if (null !== $this->apcuPrefix) {
            apcu_add($this->apcuPrefix.$class, $file);
        }

        if (false === $file) {
            // Remember that this class does not exist.
            $this->missingClasses[$class] = true;
        }

        return $file;
    }

    /**
     * Returns the currently registered loaders indexed by their corresponding vendor directories.
     *
     * @return self[]
     */
    public static function getRegisteredLoaders()
    {
        return self::$registeredLoaders;
    }

    /**
     * @param  string       $class
     * @param  string       $ext
     * @return string|false
     */
    private function findFileWithExtension($class, $ext)
    {
        // PSR-4 lookup
        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

        $first = $class[0];
        if (isset($this->prefixLengthsPsr4[$first])) {
            $subPath = $class;
            while (false !== $lastPos = strrpos($subPath, '\\')) {
                $subPath = substr($subPath, 0, $lastPos);
                $search = $subPath . '\\';
                if (isset($this->prefixDirsPsr4[$search])) {
                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
                        if (file_exists($file = $dir . $pathEnd)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-4 fallback dirs
        foreach ($this->fallbackDirsPsr4 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
                return $file;
            }
        }

        // PSR-0 lookup
        if (false !== $pos = strrpos($class, '\\')) {
            // namespaced class name
            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
        } else {
            // PEAR-like class name
            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
        }

        if (isset($this->prefixesPsr0[$first])) {
            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
                if (0 === strpos($class, $prefix)) {
                    foreach ($dirs as $dir) {
                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-0 fallback dirs
        foreach ($this->fallbackDirsPsr0 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                return $file;
            }
        }

        // PSR-0 include paths.
        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
            return $file;
        }

        return false;
    }

    private static function initializeIncludeClosure(): void
    {
        if (self::$includeFile !== null) {
            return;
        }

        /**
         * Scope isolated include.
         *
         * Prevents access to $this/self from included files.
         *
         * @param  string $file
         * @return void
         */
        self::$includeFile = static function($file) {
            include $file;
        };
    }
}
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
    'Psalm\\Aliases' => $baseDir . '/src/Psalm/Aliases.php',
    'Psalm\\CodeLocation' => $baseDir . '/src/Psalm/CodeLocation.php',
    'Psalm\\CodeLocation\\DocblockTypeLocation' => $baseDir . '/src/Psalm/CodeLocation/DocblockTypeLocation.php',
    'Psalm\\CodeLocation\\ParseErrorLocation' => $baseDir . '/src/Psalm/CodeLocation/ParseErrorLocation.php',
    'Psalm\\CodeLocation\\Raw' => $baseDir . '/src/Psalm/CodeLocation/Raw.php',
    'Psalm\\Codebase' => $baseDir . '/src/Psalm/Codebase.php',
    'Psalm\\Config' => $baseDir . '/src/Psalm/Config.php',
    'Psalm\\Config\\Creator' => $baseDir . '/src/Psalm/Config/Creator.php',
    'Psalm\\Config\\ErrorLevelFileFilter' => $baseDir . '/src/Psalm/Config/ErrorLevelFileFilter.php',
    'Psalm\\Config\\FileFilter' => $baseDir . '/src/Psalm/Config/FileFilter.php',
    'Psalm\\Config\\IssueHandler' => $baseDir . '/src/Psalm/Config/IssueHandler.php',
    'Psalm\\Config\\ProjectFileFilter' => $baseDir . '/src/Psalm/Config/ProjectFileFilter.php',
    'Psalm\\Config\\TaintAnalysisFileFilter' => $baseDir . '/src/Psalm/Config/TaintAnalysisFileFilter.php',
    'Psalm\\Context' => $baseDir . '/src/Psalm/Context.php',
    'Psalm\\DocComment' => $baseDir . '/src/Psalm/DocComment.php',
    'Psalm\\ErrorBaseline' => $baseDir . '/src/Psalm/ErrorBaseline.php',
    'Psalm\\Exception\\CircularReferenceException' => $baseDir . '/src/Psalm/Exception/CircularReferenceException.php',
    'Psalm\\Exception\\CodeException' => $baseDir . '/src/Psalm/Exception/CodeException.php',
    'Psalm\\Exception\\ComplicatedExpressionException' => $baseDir . '/src/Psalm/Exception/ComplicatedExpressionException.php',
    'Psalm\\Exception\\ConfigCreationException' => $baseDir . '/src/Psalm/Exception/ConfigCreationException.php',
    'Psalm\\Exception\\ConfigException' => $baseDir . '/src/Psalm/Exception/ConfigException.php',
    'Psalm\\Exception\\ConfigNotFoundException' => $baseDir . '/src/Psalm/Exception/ConfigNotFoundException.php',
    'Psalm\\Exception\\DocblockParseException' => $baseDir . '/src/Psalm/Exception/DocblockParseException.php',
    'Psalm\\Exception\\FileIncludeException' => $baseDir . '/src/Psalm/Exception/FileIncludeException.php',
    'Psalm\\Exception\\IncorrectDocblockException' => $baseDir . '/src/Psalm/Exception/IncorrectDocblockException.php',
    'Psalm\\Exception\\InvalidClasslikeOverrideException' => $baseDir . '/src/Psalm/Exception/InvalidClasslikeOverrideException.php',
    'Psalm\\Exception\\InvalidMethodOverrideException' => $baseDir . '/src/Psalm/Exception/InvalidMethodOverrideException.php',
    'Psalm\\Exception\\RefactorException' => $baseDir . '/src/Psalm/Exception/RefactorException.php',
    'Psalm\\Exception\\ScopeAnalysisException' => $baseDir . '/src/Psalm/Exception/ScopeAnalysisException.php',
    'Psalm\\Exception\\TypeParseTreeException' => $baseDir . '/src/Psalm/Exception/TypeParseTreeException.php',
    'Psalm\\Exception\\UnanalyzedFileException' => $baseDir . '/src/Psalm/Exception/UnanalyzedFileException.php',
    'Psalm\\Exception\\UnpopulatedClasslikeException' => $baseDir . '/src/Psalm/Exception/UnpopulatedClasslikeException.php',
    'Psalm\\Exception\\UnpreparedAnalysisException' => $baseDir . '/src/Psalm/Exception/UnpreparedAnalysisException.php',
    'Psalm\\Exception\\UnresolvableConstantException' => $baseDir . '/src/Psalm/Exception/UnresolvableConstantException.php',
    'Psalm\\Exception\\UnsupportedIssueToFixException' => $baseDir . '/src/Psalm/Exception/UnsupportedIssueToFixException.php',
    'Psalm\\FileBasedPluginAdapter' => $baseDir . '/src/Psalm/FileBasedPluginAdapter.php',
    'Psalm\\FileManipulation' => $baseDir . '/src/Psalm/FileManipulation.php',
    'Psalm\\FileSource' => $baseDir . '/src/Psalm/FileSource.php',
    'Psalm\\Internal\\Algebra' => $baseDir . '/src/Psalm/Internal/Algebra.php',
    'Psalm\\Internal\\Algebra\\FormulaGenerator' => $baseDir . '/src/Psalm/Internal/Algebra/FormulaGenerator.php',
    'Psalm\\Internal\\Analyzer\\AlgebraAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\AttributesAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/AttributesAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\CanAlias' => $baseDir . '/src/Psalm/Internal/Analyzer/CanAlias.php',
    'Psalm\\Internal\\Analyzer\\ClassAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/ClassAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\ClassLikeAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\ClassLikeNameOptions' => $baseDir . '/src/Psalm/Internal/Analyzer/ClassLikeNameOptions.php',
    'Psalm\\Internal\\Analyzer\\ClosureAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/ClosureAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\CommentAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/CommentAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\DataFlowNodeData' => $baseDir . '/src/Psalm/Internal/Analyzer/DataFlowNodeData.php',
    'Psalm\\Internal\\Analyzer\\FileAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/FileAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\FunctionAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/FunctionAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\FunctionLikeAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\FunctionLike\\ReturnTypeAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\FunctionLike\\ReturnTypeCollector' => $baseDir . '/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeCollector.php',
    'Psalm\\Internal\\Analyzer\\InterfaceAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\IssueData' => $baseDir . '/src/Psalm/Internal/Analyzer/IssueData.php',
    'Psalm\\Internal\\Analyzer\\MethodAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/MethodAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\MethodComparator' => $baseDir . '/src/Psalm/Internal/Analyzer/MethodComparator.php',
    'Psalm\\Internal\\Analyzer\\NamespaceAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/NamespaceAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\ProjectAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\ScopeAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/ScopeAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\SourceAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/SourceAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\StatementsAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\DoAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/DoAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\ForAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/ForAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\ForeachAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfConditionalAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElseAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElseAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElse\\ElseAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElse\\ElseIfAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseIfAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElse\\IfAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/IfAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\LoopAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\SwitchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/SwitchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\SwitchCaseAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/SwitchCaseAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\TryAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Block\\WhileAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Block/WhileAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\BreakAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/BreakAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\ContinueAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/ContinueAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\EchoAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/EchoAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\ExpressionAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ArrayAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ArrayCreationInfo' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayCreationInfo.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\AssertionFinder' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\AssignmentAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\ArrayAssignmentAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/ArrayAssignmentAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\AssignedProperty' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/AssignedProperty.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\InstancePropertyAssignmentAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\StaticPropertyAssignmentAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOpAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\AndAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/AndAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\ArithmeticOpAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\CoalesceAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/CoalesceAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\ConcatAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\NonComparisonOpAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/NonComparisonOpAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\OrAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/OrAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BitwiseNotAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BitwiseNotAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BooleanNotAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/BooleanNotAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\CallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArgumentAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArgumentMapPopulator' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentMapPopulator.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArgumentsAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArrayFunctionArgumentsAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ClassTemplateParamCollector' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\FunctionCallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\FunctionCallInfo' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallInfo.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\FunctionCallReturnTypeFetcher' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\MethodCallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\AtomicCallContext' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicCallContext.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\AtomicMethodCallAnalysisResult' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalysisResult.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\AtomicMethodCallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\ExistingAtomicMethodCallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodCallProhibitionAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallProhibitionAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodCallPurityAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallPurityAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodCallReturnTypeFetcher' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodVisibilityAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodVisibilityAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MissingMethodCallHandler' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MissingMethodCallHandler.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\NamedFunctionCallHandler' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NamedFunctionCallHandler.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\NewAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\StaticCallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\StaticMethod\\AtomicStaticCallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\StaticMethod\\ExistingAtomicStaticCallAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\CastAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ClassConstAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/ClassConstAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\CloneAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/CloneAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\EmptyAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/EmptyAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\EncapsulatedStringAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/EncapsulatedStringAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\EvalAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/EvalAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ExitAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/ExitAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ExpressionIdentifier' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/ExpressionIdentifier.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\ArrayFetchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\AtomicPropertyFetchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\ConstFetchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\InstancePropertyFetchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\StaticPropertyFetchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\VariableFetchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\IncDecExpressionAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/IncDecExpressionAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\IncludeAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/IncludeAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\InstanceofAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/InstanceofAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\IssetAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/IssetAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\MagicConstAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/MagicConstAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\MatchAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\NullsafeAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/NullsafeAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\PrintAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/PrintAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\SimpleTypeInferer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\TernaryAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/TernaryAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\UnaryPlusMinusAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/UnaryPlusMinusAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\YieldAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\Expression\\YieldFromAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/Expression/YieldFromAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\GlobalAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/GlobalAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\ReturnAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\StaticAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/StaticAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\ThrowAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/ThrowAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\UnsetAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/UnsetAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\Statements\\UnusedAssignmentRemover' => $baseDir . '/src/Psalm/Internal/Analyzer/Statements/UnusedAssignmentRemover.php',
    'Psalm\\Internal\\Analyzer\\TraitAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/TraitAnalyzer.php',
    'Psalm\\Internal\\Analyzer\\TypeAnalyzer' => $baseDir . '/src/Psalm/Internal/Analyzer/TypeAnalyzer.php',
    'Psalm\\Internal\\Clause' => $baseDir . '/src/Psalm/Internal/Clause.php',
    'Psalm\\Internal\\CliUtils' => $baseDir . '/src/Psalm/Internal/CliUtils.php',
    'Psalm\\Internal\\Cli\\LanguageServer' => $baseDir . '/src/Psalm/Internal/Cli/LanguageServer.php',
    'Psalm\\Internal\\Cli\\Plugin' => $baseDir . '/src/Psalm/Internal/Cli/Plugin.php',
    'Psalm\\Internal\\Cli\\Psalm' => $baseDir . '/src/Psalm/Internal/Cli/Psalm.php',
    'Psalm\\Internal\\Cli\\Psalter' => $baseDir . '/src/Psalm/Internal/Cli/Psalter.php',
    'Psalm\\Internal\\Cli\\Refactor' => $baseDir . '/src/Psalm/Internal/Cli/Refactor.php',
    'Psalm\\Internal\\Codebase\\Analyzer' => $baseDir . '/src/Psalm/Internal/Codebase/Analyzer.php',
    'Psalm\\Internal\\Codebase\\ClassConstantByWildcardResolver' => $baseDir . '/src/Psalm/Internal/Codebase/ClassConstantByWildcardResolver.php',
    'Psalm\\Internal\\Codebase\\ClassLikes' => $baseDir . '/src/Psalm/Internal/Codebase/ClassLikes.php',
    'Psalm\\Internal\\Codebase\\ConstantTypeResolver' => $baseDir . '/src/Psalm/Internal/Codebase/ConstantTypeResolver.php',
    'Psalm\\Internal\\Codebase\\DataFlowGraph' => $baseDir . '/src/Psalm/Internal/Codebase/DataFlowGraph.php',
    'Psalm\\Internal\\Codebase\\Functions' => $baseDir . '/src/Psalm/Internal/Codebase/Functions.php',
    'Psalm\\Internal\\Codebase\\InternalCallMapHandler' => $baseDir . '/src/Psalm/Internal/Codebase/InternalCallMapHandler.php',
    'Psalm\\Internal\\Codebase\\Methods' => $baseDir . '/src/Psalm/Internal/Codebase/Methods.php',
    'Psalm\\Internal\\Codebase\\Populator' => $baseDir . '/src/Psalm/Internal/Codebase/Populator.php',
    'Psalm\\Internal\\Codebase\\Properties' => $baseDir . '/src/Psalm/Internal/Codebase/Properties.php',
    'Psalm\\Internal\\Codebase\\PropertyMap' => $baseDir . '/src/Psalm/Internal/Codebase/PropertyMap.php',
    'Psalm\\Internal\\Codebase\\ReferenceMapGenerator' => $baseDir . '/src/Psalm/Internal/Codebase/ReferenceMapGenerator.php',
    'Psalm\\Internal\\Codebase\\Reflection' => $baseDir . '/src/Psalm/Internal/Codebase/Reflection.php',
    'Psalm\\Internal\\Codebase\\Scanner' => $baseDir . '/src/Psalm/Internal/Codebase/Scanner.php',
    'Psalm\\Internal\\Codebase\\TaintFlowGraph' => $baseDir . '/src/Psalm/Internal/Codebase/TaintFlowGraph.php',
    'Psalm\\Internal\\Codebase\\VariableUseGraph' => $baseDir . '/src/Psalm/Internal/Codebase/VariableUseGraph.php',
    'Psalm\\Internal\\Composer' => $baseDir . '/src/Psalm/Internal/Composer.php',
    'Psalm\\Internal\\DataFlow\\DataFlowNode' => $baseDir . '/src/Psalm/Internal/DataFlow/DataFlowNode.php',
    'Psalm\\Internal\\DataFlow\\Path' => $baseDir . '/src/Psalm/Internal/DataFlow/Path.php',
    'Psalm\\Internal\\DataFlow\\TaintSink' => $baseDir . '/src/Psalm/Internal/DataFlow/TaintSink.php',
    'Psalm\\Internal\\DataFlow\\TaintSource' => $baseDir . '/src/Psalm/Internal/DataFlow/TaintSource.php',
    'Psalm\\Internal\\Diff\\AstDiffer' => $baseDir . '/src/Psalm/Internal/Diff/AstDiffer.php',
    'Psalm\\Internal\\Diff\\ClassStatementsDiffer' => $baseDir . '/src/Psalm/Internal/Diff/ClassStatementsDiffer.php',
    'Psalm\\Internal\\Diff\\DiffElem' => $baseDir . '/src/Psalm/Internal/Diff/DiffElem.php',
    'Psalm\\Internal\\Diff\\FileDiffer' => $baseDir . '/src/Psalm/Internal/Diff/FileDiffer.php',
    'Psalm\\Internal\\Diff\\FileStatementsDiffer' => $baseDir . '/src/Psalm/Internal/Diff/FileStatementsDiffer.php',
    'Psalm\\Internal\\Diff\\NamespaceStatementsDiffer' => $baseDir . '/src/Psalm/Internal/Diff/NamespaceStatementsDiffer.php',
    'Psalm\\Internal\\ErrorHandler' => $baseDir . '/src/Psalm/Internal/ErrorHandler.php',
    'Psalm\\Internal\\EventDispatcher' => $baseDir . '/src/Psalm/Internal/EventDispatcher.php',
    'Psalm\\Internal\\ExecutionEnvironment\\BuildInfoCollector' => $baseDir . '/src/Psalm/Internal/ExecutionEnvironment/BuildInfoCollector.php',
    'Psalm\\Internal\\ExecutionEnvironment\\GitInfoCollector' => $baseDir . '/src/Psalm/Internal/ExecutionEnvironment/GitInfoCollector.php',
    'Psalm\\Internal\\ExecutionEnvironment\\SystemCommandExecutor' => $baseDir . '/src/Psalm/Internal/ExecutionEnvironment/SystemCommandExecutor.php',
    'Psalm\\Internal\\FileManipulation\\ClassDocblockManipulator' => $baseDir . '/src/Psalm/Internal/FileManipulation/ClassDocblockManipulator.php',
    'Psalm\\Internal\\FileManipulation\\CodeMigration' => $baseDir . '/src/Psalm/Internal/FileManipulation/CodeMigration.php',
    'Psalm\\Internal\\FileManipulation\\FileManipulationBuffer' => $baseDir . '/src/Psalm/Internal/FileManipulation/FileManipulationBuffer.php',
    'Psalm\\Internal\\FileManipulation\\FunctionDocblockManipulator' => $baseDir . '/src/Psalm/Internal/FileManipulation/FunctionDocblockManipulator.php',
    'Psalm\\Internal\\FileManipulation\\PropertyDocblockManipulator' => $baseDir . '/src/Psalm/Internal/FileManipulation/PropertyDocblockManipulator.php',
    'Psalm\\Internal\\Fork\\ForkMessage' => $baseDir . '/src/Psalm/Internal/Fork/ForkMessage.php',
    'Psalm\\Internal\\Fork\\ForkProcessDoneMessage' => $baseDir . '/src/Psalm/Internal/Fork/ForkProcessDoneMessage.php',
    'Psalm\\Internal\\Fork\\ForkProcessErrorMessage' => $baseDir . '/src/Psalm/Internal/Fork/ForkProcessErrorMessage.php',
    'Psalm\\Internal\\Fork\\ForkTaskDoneMessage' => $baseDir . '/src/Psalm/Internal/Fork/ForkTaskDoneMessage.php',
    'Psalm\\Internal\\Fork\\Pool' => $baseDir . '/src/Psalm/Internal/Fork/Pool.php',
    'Psalm\\Internal\\Fork\\PsalmRestarter' => $baseDir . '/src/Psalm/Internal/Fork/PsalmRestarter.php',
    'Psalm\\Internal\\IncludeCollector' => $baseDir . '/src/Psalm/Internal/IncludeCollector.php',
    'Psalm\\Internal\\Json\\Json' => $baseDir . '/src/Psalm/Internal/Json/Json.php',
    'Psalm\\Internal\\LanguageServer\\ClientHandler' => $baseDir . '/src/Psalm/Internal/LanguageServer/ClientHandler.php',
    'Psalm\\Internal\\LanguageServer\\Client\\TextDocument' => $baseDir . '/src/Psalm/Internal/LanguageServer/Client/TextDocument.php',
    'Psalm\\Internal\\LanguageServer\\EmitterInterface' => $baseDir . '/src/Psalm/Internal/LanguageServer/EmitterInterface.php',
    'Psalm\\Internal\\LanguageServer\\EmitterTrait' => $baseDir . '/src/Psalm/Internal/LanguageServer/EmitterTrait.php',
    'Psalm\\Internal\\LanguageServer\\IdGenerator' => $baseDir . '/src/Psalm/Internal/LanguageServer/IdGenerator.php',
    'Psalm\\Internal\\LanguageServer\\LanguageClient' => $baseDir . '/src/Psalm/Internal/LanguageServer/LanguageClient.php',
    'Psalm\\Internal\\LanguageServer\\LanguageServer' => $baseDir . '/src/Psalm/Internal/LanguageServer/LanguageServer.php',
    'Psalm\\Internal\\LanguageServer\\Message' => $baseDir . '/src/Psalm/Internal/LanguageServer/Message.php',
    'Psalm\\Internal\\LanguageServer\\ProtocolReader' => $baseDir . '/src/Psalm/Internal/LanguageServer/ProtocolReader.php',
    'Psalm\\Internal\\LanguageServer\\ProtocolStreamReader' => $baseDir . '/src/Psalm/Internal/LanguageServer/ProtocolStreamReader.php',
    'Psalm\\Internal\\LanguageServer\\ProtocolStreamWriter' => $baseDir . '/src/Psalm/Internal/LanguageServer/ProtocolStreamWriter.php',
    'Psalm\\Internal\\LanguageServer\\ProtocolWriter' => $baseDir . '/src/Psalm/Internal/LanguageServer/ProtocolWriter.php',
    'Psalm\\Internal\\LanguageServer\\Server\\TextDocument' => $baseDir . '/src/Psalm/Internal/LanguageServer/Server/TextDocument.php',
    'Psalm\\Internal\\LanguageServer\\Server\\Workspace' => $baseDir . '/src/Psalm/Internal/LanguageServer/Server/Workspace.php',
    'Psalm\\Internal\\MethodIdentifier' => $baseDir . '/src/Psalm/Internal/MethodIdentifier.php',
    'Psalm\\Internal\\PhpTraverser\\CustomTraverser' => $baseDir . '/src/Psalm/Internal/PhpTraverser/CustomTraverser.php',
    'Psalm\\Internal\\PhpVisitor\\AssignmentMapVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/AssignmentMapVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\CheckTrivialExprVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/CheckTrivialExprVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\CloningVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/CloningVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\ConditionCloningVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/ConditionCloningVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\NodeCleanerVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/NodeCleanerVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\NodeCounterVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/NodeCounterVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\OffsetShifterVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/OffsetShifterVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\ParamReplacementVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/ParamReplacementVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\PartialParserVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/PartialParserVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\ReflectorVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\AttributeResolver' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/AttributeResolver.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\ClassLikeDocblockParser' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\ClassLikeNodeScanner' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\ExpressionResolver' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\ExpressionScanner' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionScanner.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\FunctionLikeDocblockParser' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\FunctionLikeDocblockScanner' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\FunctionLikeNodeScanner' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php',
    'Psalm\\Internal\\PhpVisitor\\Reflector\\TypeHintResolver' => $baseDir . '/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php',
    'Psalm\\Internal\\PhpVisitor\\ShortClosureVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/ShortClosureVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\SimpleNameResolver' => $baseDir . '/src/Psalm/Internal/PhpVisitor/SimpleNameResolver.php',
    'Psalm\\Internal\\PhpVisitor\\TraitFinder' => $baseDir . '/src/Psalm/Internal/PhpVisitor/TraitFinder.php',
    'Psalm\\Internal\\PhpVisitor\\TypeMappingVisitor' => $baseDir . '/src/Psalm/Internal/PhpVisitor/TypeMappingVisitor.php',
    'Psalm\\Internal\\PhpVisitor\\YieldTypeCollector' => $baseDir . '/src/Psalm/Internal/PhpVisitor/YieldTypeCollector.php',
    'Psalm\\Internal\\PluginManager\\Command\\DisableCommand' => $baseDir . '/src/Psalm/Internal/PluginManager/Command/DisableCommand.php',
    'Psalm\\Internal\\PluginManager\\Command\\EnableCommand' => $baseDir . '/src/Psalm/Internal/PluginManager/Command/EnableCommand.php',
    'Psalm\\Internal\\PluginManager\\Command\\ShowCommand' => $baseDir . '/src/Psalm/Internal/PluginManager/Command/ShowCommand.php',
    'Psalm\\Internal\\PluginManager\\ComposerLock' => $baseDir . '/src/Psalm/Internal/PluginManager/ComposerLock.php',
    'Psalm\\Internal\\PluginManager\\ConfigFile' => $baseDir . '/src/Psalm/Internal/PluginManager/ConfigFile.php',
    'Psalm\\Internal\\PluginManager\\PluginList' => $baseDir . '/src/Psalm/Internal/PluginManager/PluginList.php',
    'Psalm\\Internal\\PluginManager\\PluginListFactory' => $baseDir . '/src/Psalm/Internal/PluginManager/PluginListFactory.php',
    'Psalm\\Internal\\Provider\\AddRemoveTaints\\HtmlFunctionTainter' => $baseDir . '/src/Psalm/Internal/Provider/AddRemoveTaints/HtmlFunctionTainter.php',
    'Psalm\\Internal\\Provider\\ClassLikeStorageCacheProvider' => $baseDir . '/src/Psalm/Internal/Provider/ClassLikeStorageCacheProvider.php',
    'Psalm\\Internal\\Provider\\ClassLikeStorageProvider' => $baseDir . '/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php',
    'Psalm\\Internal\\Provider\\DynamicFunctionStorageProvider' => $baseDir . '/src/Psalm/Internal/Provider/DynamicFunctionStorageProvider.php',
    'Psalm\\Internal\\Provider\\FakeFileProvider' => $baseDir . '/src/Psalm/Internal/Provider/FakeFileProvider.php',
    'Psalm\\Internal\\Provider\\FileProvider' => $baseDir . '/src/Psalm/Internal/Provider/FileProvider.php',
    'Psalm\\Internal\\Provider\\FileReferenceCacheProvider' => $baseDir . '/src/Psalm/Internal/Provider/FileReferenceCacheProvider.php',
    'Psalm\\Internal\\Provider\\FileReferenceProvider' => $baseDir . '/src/Psalm/Internal/Provider/FileReferenceProvider.php',
    'Psalm\\Internal\\Provider\\FileStorageCacheProvider' => $baseDir . '/src/Psalm/Internal/Provider/FileStorageCacheProvider.php',
    'Psalm\\Internal\\Provider\\FileStorageProvider' => $baseDir . '/src/Psalm/Internal/Provider/FileStorageProvider.php',
    'Psalm\\Internal\\Provider\\FunctionExistenceProvider' => $baseDir . '/src/Psalm/Internal/Provider/FunctionExistenceProvider.php',
    'Psalm\\Internal\\Provider\\FunctionParamsProvider' => $baseDir . '/src/Psalm/Internal/Provider/FunctionParamsProvider.php',
    'Psalm\\Internal\\Provider\\FunctionReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\MethodExistenceProvider' => $baseDir . '/src/Psalm/Internal/Provider/MethodExistenceProvider.php',
    'Psalm\\Internal\\Provider\\MethodParamsProvider' => $baseDir . '/src/Psalm/Internal/Provider/MethodParamsProvider.php',
    'Psalm\\Internal\\Provider\\MethodReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/MethodReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\MethodVisibilityProvider' => $baseDir . '/src/Psalm/Internal/Provider/MethodVisibilityProvider.php',
    'Psalm\\Internal\\Provider\\NodeDataProvider' => $baseDir . '/src/Psalm/Internal/Provider/NodeDataProvider.php',
    'Psalm\\Internal\\Provider\\ParserCacheProvider' => $baseDir . '/src/Psalm/Internal/Provider/ParserCacheProvider.php',
    'Psalm\\Internal\\Provider\\ProjectCacheProvider' => $baseDir . '/src/Psalm/Internal/Provider/ProjectCacheProvider.php',
    'Psalm\\Internal\\Provider\\PropertyExistenceProvider' => $baseDir . '/src/Psalm/Internal/Provider/PropertyExistenceProvider.php',
    'Psalm\\Internal\\Provider\\PropertyTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/PropertyTypeProvider.php',
    'Psalm\\Internal\\Provider\\PropertyTypeProvider\\DomDocumentPropertyTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/PropertyTypeProvider/DomDocumentPropertyTypeProvider.php',
    'Psalm\\Internal\\Provider\\PropertyVisibilityProvider' => $baseDir . '/src/Psalm/Internal/Provider/PropertyVisibilityProvider.php',
    'Psalm\\Internal\\Provider\\Providers' => $baseDir . '/src/Psalm/Internal/Provider/Providers.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayChunkReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayChunkReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayColumnReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayCombineReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayCombineReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayFillKeysReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillKeysReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayFillReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayFilterReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFilterReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayMapReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayMergeReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMergeReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayPadReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPadReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayPointerAdjustmentReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPointerAdjustmentReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayPopReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPopReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayRandReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayRandReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayReduceReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReduceReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayReverseReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReverseReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArraySliceReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArraySliceReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArraySpliceReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArraySpliceReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayUniqueReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayUniqueReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\BasenameReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/BasenameReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ClosureFromCallableReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ClosureFromCallableReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\DateTimeModifyReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/DateTimeModifyReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\DirnameReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/DirnameReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\DomNodeAppendChild' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/DomNodeAppendChild.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\FilterVarReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/FilterVarReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\FirstArgStringReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/FirstArgStringReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\GetClassMethodsReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/GetClassMethodsReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\GetObjectVarsReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/GetObjectVarsReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\HexdecReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/HexdecReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ImagickPixelColorReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ImagickPixelColorReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\InArrayReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/InArrayReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\IteratorToArrayReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/IteratorToArrayReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\MbInternalEncodingReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/MbInternalEncodingReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\MinMaxReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/MinMaxReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\MktimeReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/MktimeReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ParseUrlReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ParseUrlReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\PdoStatementReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/PdoStatementReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\PdoStatementSetFetchMode' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/PdoStatementSetFetchMode.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\RandReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/RandReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\RoundReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/RoundReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\SimpleXmlElementAsXml' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/SimpleXmlElementAsXml.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\StrReplaceReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/StrReplaceReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\StrTrReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/StrTrReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\TriggerErrorReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/TriggerErrorReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\ReturnTypeProvider\\VersionCompareReturnTypeProvider' => $baseDir . '/src/Psalm/Internal/Provider/ReturnTypeProvider/VersionCompareReturnTypeProvider.php',
    'Psalm\\Internal\\Provider\\StatementsProvider' => $baseDir . '/src/Psalm/Internal/Provider/StatementsProvider.php',
    'Psalm\\Internal\\Provider\\StatementsVolatileCache' => $baseDir . '/src/Psalm/Internal/Provider/StatementsVolatileCache.php',
    'Psalm\\Internal\\ReferenceConstraint' => $baseDir . '/src/Psalm/Internal/ReferenceConstraint.php',
    'Psalm\\Internal\\RuntimeCaches' => $baseDir . '/src/Psalm/Internal/RuntimeCaches.php',
    'Psalm\\Internal\\Scanner\\ClassLikeDocblockComment' => $baseDir . '/src/Psalm/Internal/Scanner/ClassLikeDocblockComment.php',
    'Psalm\\Internal\\Scanner\\DocblockParser' => $baseDir . '/src/Psalm/Internal/Scanner/DocblockParser.php',
    'Psalm\\Internal\\Scanner\\FileScanner' => $baseDir . '/src/Psalm/Internal/Scanner/FileScanner.php',
    'Psalm\\Internal\\Scanner\\FunctionDocblockComment' => $baseDir . '/src/Psalm/Internal/Scanner/FunctionDocblockComment.php',
    'Psalm\\Internal\\Scanner\\ParsedDocblock' => $baseDir . '/src/Psalm/Internal/Scanner/ParsedDocblock.php',
    'Psalm\\Internal\\Scanner\\PhpStormMetaScanner' => $baseDir . '/src/Psalm/Internal/Scanner/PhpStormMetaScanner.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstantComponent' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstantComponent.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ArrayOffsetFetch' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ArrayOffsetFetch.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ArraySpread' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ArraySpread.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ArrayValue' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ArrayValue.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ClassConstant' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ClassConstant.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\Constant' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/Constant.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\KeyValuePair' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/KeyValuePair.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ScalarValue' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ScalarValue.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedAdditionOp' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedAdditionOp.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBinaryOp' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBinaryOp.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBitwiseAnd' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseAnd.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBitwiseOr' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseOr.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBitwiseXor' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseXor.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedConcatOp' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedConcatOp.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedDivisionOp' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedDivisionOp.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedMultiplicationOp' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedMultiplicationOp.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedSubtractionOp' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedSubtractionOp.php',
    'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedTernary' => $baseDir . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedTernary.php',
    'Psalm\\Internal\\Scanner\\VarDocblockComment' => $baseDir . '/src/Psalm/Internal/Scanner/VarDocblockComment.php',
    'Psalm\\Internal\\Scope\\CaseScope' => $baseDir . '/src/Psalm/Internal/Scope/CaseScope.php',
    'Psalm\\Internal\\Scope\\FinallyScope' => $baseDir . '/src/Psalm/Internal/Scope/FinallyScope.php',
    'Psalm\\Internal\\Scope\\IfConditionalScope' => $baseDir . '/src/Psalm/Internal/Scope/IfConditionalScope.php',
    'Psalm\\Internal\\Scope\\IfScope' => $baseDir . '/src/Psalm/Internal/Scope/IfScope.php',
    'Psalm\\Internal\\Scope\\LoopScope' => $baseDir . '/src/Psalm/Internal/Scope/LoopScope.php',
    'Psalm\\Internal\\Scope\\SwitchScope' => $baseDir . '/src/Psalm/Internal/Scope/SwitchScope.php',
    'Psalm\\Internal\\Stubs\\Generator\\ClassLikeStubGenerator' => $baseDir . '/src/Psalm/Internal/Stubs/Generator/ClassLikeStubGenerator.php',
    'Psalm\\Internal\\Stubs\\Generator\\StubsGenerator' => $baseDir . '/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php',
    'Psalm\\Internal\\TypeVisitor\\CanContainObjectTypeVisitor' => $baseDir . '/src/Psalm/Internal/TypeVisitor/CanContainObjectTypeVisitor.php',
    'Psalm\\Internal\\TypeVisitor\\ClasslikeReplacer' => $baseDir . '/src/Psalm/Internal/TypeVisitor/ClasslikeReplacer.php',
    'Psalm\\Internal\\TypeVisitor\\ContainsClassLikeVisitor' => $baseDir . '/src/Psalm/Internal/TypeVisitor/ContainsClassLikeVisitor.php',
    'Psalm\\Internal\\TypeVisitor\\ContainsLiteralVisitor' => $baseDir . '/src/Psalm/Internal/TypeVisitor/ContainsLiteralVisitor.php',
    'Psalm\\Internal\\TypeVisitor\\ContainsStaticVisitor' => $baseDir . '/src/Psalm/Internal/TypeVisitor/ContainsStaticVisitor.php',
    'Psalm\\Internal\\TypeVisitor\\FromDocblockSetter' => $baseDir . '/src/Psalm/Internal/TypeVisitor/FromDocblockSetter.php',
    'Psalm\\Internal\\TypeVisitor\\TemplateTypeCollector' => $baseDir . '/src/Psalm/Internal/TypeVisitor/TemplateTypeCollector.php',
    'Psalm\\Internal\\TypeVisitor\\TypeChecker' => $baseDir . '/src/Psalm/Internal/TypeVisitor/TypeChecker.php',
    'Psalm\\Internal\\TypeVisitor\\TypeLocalizer' => $baseDir . '/src/Psalm/Internal/TypeVisitor/TypeLocalizer.php',
    'Psalm\\Internal\\TypeVisitor\\TypeScanner' => $baseDir . '/src/Psalm/Internal/TypeVisitor/TypeScanner.php',
    'Psalm\\Internal\\Type\\ArrayType' => $baseDir . '/src/Psalm/Internal/Type/ArrayType.php',
    'Psalm\\Internal\\Type\\AssertionReconciler' => $baseDir . '/src/Psalm/Internal/Type/AssertionReconciler.php',
    'Psalm\\Internal\\Type\\Comparator\\ArrayTypeComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/ArrayTypeComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\AtomicTypeComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\CallableTypeComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/CallableTypeComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\ClassLikeStringComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/ClassLikeStringComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\GenericTypeComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/GenericTypeComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\IntegerRangeComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\KeyedArrayComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/KeyedArrayComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\ObjectComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/ObjectComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\ScalarTypeComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php',
    'Psalm\\Internal\\Type\\Comparator\\TypeComparisonResult' => $baseDir . '/src/Psalm/Internal/Type/Comparator/TypeComparisonResult.php',
    'Psalm\\Internal\\Type\\Comparator\\UnionTypeComparator' => $baseDir . '/src/Psalm/Internal/Type/Comparator/UnionTypeComparator.php',
    'Psalm\\Internal\\Type\\NegatedAssertionReconciler' => $baseDir . '/src/Psalm/Internal/Type/NegatedAssertionReconciler.php',
    'Psalm\\Internal\\Type\\ParseTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree.php',
    'Psalm\\Internal\\Type\\ParseTreeCreator' => $baseDir . '/src/Psalm/Internal/Type/ParseTreeCreator.php',
    'Psalm\\Internal\\Type\\ParseTree\\CallableParamTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/CallableParamTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\CallableTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/CallableTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\CallableWithReturnTypeTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/CallableWithReturnTypeTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\ConditionalTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/ConditionalTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\EncapsulationTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/EncapsulationTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\FieldEllipsis' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/FieldEllipsis.php',
    'Psalm\\Internal\\Type\\ParseTree\\GenericTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/GenericTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\IndexedAccessTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/IndexedAccessTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\IntersectionTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/IntersectionTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\KeyedArrayPropertyTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/KeyedArrayPropertyTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\KeyedArrayTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/KeyedArrayTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\MethodParamTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/MethodParamTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\MethodTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/MethodTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\MethodWithReturnTypeTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/MethodWithReturnTypeTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\NullableTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/NullableTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\Root' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/Root.php',
    'Psalm\\Internal\\Type\\ParseTree\\TemplateAsTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/TemplateAsTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\TemplateIsTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/TemplateIsTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\UnionTree' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/UnionTree.php',
    'Psalm\\Internal\\Type\\ParseTree\\Value' => $baseDir . '/src/Psalm/Internal/Type/ParseTree/Value.php',
    'Psalm\\Internal\\Type\\SimpleAssertionReconciler' => $baseDir . '/src/Psalm/Internal/Type/SimpleAssertionReconciler.php',
    'Psalm\\Internal\\Type\\SimpleNegatedAssertionReconciler' => $baseDir . '/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php',
    'Psalm\\Internal\\Type\\TemplateBound' => $baseDir . '/src/Psalm/Internal/Type/TemplateBound.php',
    'Psalm\\Internal\\Type\\TemplateInferredTypeReplacer' => $baseDir . '/src/Psalm/Internal/Type/TemplateInferredTypeReplacer.php',
    'Psalm\\Internal\\Type\\TemplateResult' => $baseDir . '/src/Psalm/Internal/Type/TemplateResult.php',
    'Psalm\\Internal\\Type\\TemplateStandinTypeReplacer' => $baseDir . '/src/Psalm/Internal/Type/TemplateStandinTypeReplacer.php',
    'Psalm\\Internal\\Type\\TypeAlias' => $baseDir . '/src/Psalm/Internal/Type/TypeAlias.php',
    'Psalm\\Internal\\Type\\TypeAlias\\ClassTypeAlias' => $baseDir . '/src/Psalm/Internal/Type/TypeAlias/ClassTypeAlias.php',
    'Psalm\\Internal\\Type\\TypeAlias\\InlineTypeAlias' => $baseDir . '/src/Psalm/Internal/Type/TypeAlias/InlineTypeAlias.php',
    'Psalm\\Internal\\Type\\TypeAlias\\LinkableTypeAlias' => $baseDir . '/src/Psalm/Internal/Type/TypeAlias/LinkableTypeAlias.php',
    'Psalm\\Internal\\Type\\TypeCombination' => $baseDir . '/src/Psalm/Internal/Type/TypeCombination.php',
    'Psalm\\Internal\\Type\\TypeCombiner' => $baseDir . '/src/Psalm/Internal/Type/TypeCombiner.php',
    'Psalm\\Internal\\Type\\TypeExpander' => $baseDir . '/src/Psalm/Internal/Type/TypeExpander.php',
    'Psalm\\Internal\\Type\\TypeParser' => $baseDir . '/src/Psalm/Internal/Type/TypeParser.php',
    'Psalm\\Internal\\Type\\TypeTokenizer' => $baseDir . '/src/Psalm/Internal/Type/TypeTokenizer.php',
    'Psalm\\Internal\\VersionUtils' => $baseDir . '/src/Psalm/Internal/VersionUtils.php',
    'Psalm\\IssueBuffer' => $baseDir . '/src/Psalm/IssueBuffer.php',
    'Psalm\\Issue\\AbstractInstantiation' => $baseDir . '/src/Psalm/Issue/AbstractInstantiation.php',
    'Psalm\\Issue\\AbstractMethodCall' => $baseDir . '/src/Psalm/Issue/AbstractMethodCall.php',
    'Psalm\\Issue\\AmbiguousConstantInheritance' => $baseDir . '/src/Psalm/Issue/AmbiguousConstantInheritance.php',
    'Psalm\\Issue\\ArgumentIssue' => $baseDir . '/src/Psalm/Issue/ArgumentIssue.php',
    'Psalm\\Issue\\ArgumentTypeCoercion' => $baseDir . '/src/Psalm/Issue/ArgumentTypeCoercion.php',
    'Psalm\\Issue\\AssignmentToVoid' => $baseDir . '/src/Psalm/Issue/AssignmentToVoid.php',
    'Psalm\\Issue\\CheckType' => $baseDir . '/src/Psalm/Issue/CheckType.php',
    'Psalm\\Issue\\CircularReference' => $baseDir . '/src/Psalm/Issue/CircularReference.php',
    'Psalm\\Issue\\ClassConstantIssue' => $baseDir . '/src/Psalm/Issue/ClassConstantIssue.php',
    'Psalm\\Issue\\ClassIssue' => $baseDir . '/src/Psalm/Issue/ClassIssue.php',
    'Psalm\\Issue\\CodeIssue' => $baseDir . '/src/Psalm/Issue/CodeIssue.php',
    'Psalm\\Issue\\ComplexFunction' => $baseDir . '/src/Psalm/Issue/ComplexFunction.php',
    'Psalm\\Issue\\ComplexMethod' => $baseDir . '/src/Psalm/Issue/ComplexMethod.php',
    'Psalm\\Issue\\ConfigIssue' => $baseDir . '/src/Psalm/Issue/ConfigIssue.php',
    'Psalm\\Issue\\ConflictingReferenceConstraint' => $baseDir . '/src/Psalm/Issue/ConflictingReferenceConstraint.php',
    'Psalm\\Issue\\ConstantDeclarationInTrait' => $baseDir . '/src/Psalm/Issue/ConstantDeclarationInTrait.php',
    'Psalm\\Issue\\ConstructorSignatureMismatch' => $baseDir . '/src/Psalm/Issue/ConstructorSignatureMismatch.php',
    'Psalm\\Issue\\ContinueOutsideLoop' => $baseDir . '/src/Psalm/Issue/ContinueOutsideLoop.php',
    'Psalm\\Issue\\DeprecatedClass' => $baseDir . '/src/Psalm/Issue/DeprecatedClass.php',
    'Psalm\\Issue\\DeprecatedConstant' => $baseDir . '/src/Psalm/Issue/DeprecatedConstant.php',
    'Psalm\\Issue\\DeprecatedFunction' => $baseDir . '/src/Psalm/Issue/DeprecatedFunction.php',
    'Psalm\\Issue\\DeprecatedInterface' => $baseDir . '/src/Psalm/Issue/DeprecatedInterface.php',
    'Psalm\\Issue\\DeprecatedMethod' => $baseDir . '/src/Psalm/Issue/DeprecatedMethod.php',
    'Psalm\\Issue\\DeprecatedProperty' => $baseDir . '/src/Psalm/Issue/DeprecatedProperty.php',
    'Psalm\\Issue\\DeprecatedTrait' => $baseDir . '/src/Psalm/Issue/DeprecatedTrait.php',
    'Psalm\\Issue\\DocblockTypeContradiction' => $baseDir . '/src/Psalm/Issue/DocblockTypeContradiction.php',
    'Psalm\\Issue\\DuplicateArrayKey' => $baseDir . '/src/Psalm/Issue/DuplicateArrayKey.php',
    'Psalm\\Issue\\DuplicateClass' => $baseDir . '/src/Psalm/Issue/DuplicateClass.php',
    'Psalm\\Issue\\DuplicateConstant' => $baseDir . '/src/Psalm/Issue/DuplicateConstant.php',
    'Psalm\\Issue\\DuplicateEnumCase' => $baseDir . '/src/Psalm/Issue/DuplicateEnumCase.php',
    'Psalm\\Issue\\DuplicateEnumCaseValue' => $baseDir . '/src/Psalm/Issue/DuplicateEnumCaseValue.php',
    'Psalm\\Issue\\DuplicateFunction' => $baseDir . '/src/Psalm/Issue/DuplicateFunction.php',
    'Psalm\\Issue\\DuplicateMethod' => $baseDir . '/src/Psalm/Issue/DuplicateMethod.php',
    'Psalm\\Issue\\DuplicateParam' => $baseDir . '/src/Psalm/Issue/DuplicateParam.php',
    'Psalm\\Issue\\EmptyArrayAccess' => $baseDir . '/src/Psalm/Issue/EmptyArrayAccess.php',
    'Psalm\\Issue\\ExtensionRequirementViolation' => $baseDir . '/src/Psalm/Issue/ExtensionRequirementViolation.php',
    'Psalm\\Issue\\FalsableReturnStatement' => $baseDir . '/src/Psalm/Issue/FalsableReturnStatement.php',
    'Psalm\\Issue\\FalseOperand' => $baseDir . '/src/Psalm/Issue/FalseOperand.php',
    'Psalm\\Issue\\ForbiddenCode' => $baseDir . '/src/Psalm/Issue/ForbiddenCode.php',
    'Psalm\\Issue\\FunctionIssue' => $baseDir . '/src/Psalm/Issue/FunctionIssue.php',
    'Psalm\\Issue\\IfThisIsMismatch' => $baseDir . '/src/Psalm/Issue/IfThisIsMismatch.php',
    'Psalm\\Issue\\ImplementationRequirementViolation' => $baseDir . '/src/Psalm/Issue/ImplementationRequirementViolation.php',
    'Psalm\\Issue\\ImplementedParamTypeMismatch' => $baseDir . '/src/Psalm/Issue/ImplementedParamTypeMismatch.php',
    'Psalm\\Issue\\ImplementedReturnTypeMismatch' => $baseDir . '/src/Psalm/Issue/ImplementedReturnTypeMismatch.php',
    'Psalm\\Issue\\ImplicitToStringCast' => $baseDir . '/src/Psalm/Issue/ImplicitToStringCast.php',
    'Psalm\\Issue\\ImpureByReferenceAssignment' => $baseDir . '/src/Psalm/Issue/ImpureByReferenceAssignment.php',
    'Psalm\\Issue\\ImpureFunctionCall' => $baseDir . '/src/Psalm/Issue/ImpureFunctionCall.php',
    'Psalm\\Issue\\ImpureMethodCall' => $baseDir . '/src/Psalm/Issue/ImpureMethodCall.php',
    'Psalm\\Issue\\ImpurePropertyAssignment' => $baseDir . '/src/Psalm/Issue/ImpurePropertyAssignment.php',
    'Psalm\\Issue\\ImpurePropertyFetch' => $baseDir . '/src/Psalm/Issue/ImpurePropertyFetch.php',
    'Psalm\\Issue\\ImpureStaticProperty' => $baseDir . '/src/Psalm/Issue/ImpureStaticProperty.php',
    'Psalm\\Issue\\ImpureStaticVariable' => $baseDir . '/src/Psalm/Issue/ImpureStaticVariable.php',
    'Psalm\\Issue\\ImpureVariable' => $baseDir . '/src/Psalm/Issue/ImpureVariable.php',
    'Psalm\\Issue\\InaccessibleClassConstant' => $baseDir . '/src/Psalm/Issue/InaccessibleClassConstant.php',
    'Psalm\\Issue\\InaccessibleMethod' => $baseDir . '/src/Psalm/Issue/InaccessibleMethod.php',
    'Psalm\\Issue\\InaccessibleProperty' => $baseDir . '/src/Psalm/Issue/InaccessibleProperty.php',
    'Psalm\\Issue\\InterfaceInstantiation' => $baseDir . '/src/Psalm/Issue/InterfaceInstantiation.php',
    'Psalm\\Issue\\InternalClass' => $baseDir . '/src/Psalm/Issue/InternalClass.php',
    'Psalm\\Issue\\InternalMethod' => $baseDir . '/src/Psalm/Issue/InternalMethod.php',
    'Psalm\\Issue\\InternalProperty' => $baseDir . '/src/Psalm/Issue/InternalProperty.php',
    'Psalm\\Issue\\InvalidArgument' => $baseDir . '/src/Psalm/Issue/InvalidArgument.php',
    'Psalm\\Issue\\InvalidArrayAccess' => $baseDir . '/src/Psalm/Issue/InvalidArrayAccess.php',
    'Psalm\\Issue\\InvalidArrayAssignment' => $baseDir . '/src/Psalm/Issue/InvalidArrayAssignment.php',
    'Psalm\\Issue\\InvalidArrayOffset' => $baseDir . '/src/Psalm/Issue/InvalidArrayOffset.php',
    'Psalm\\Issue\\InvalidAttribute' => $baseDir . '/src/Psalm/Issue/InvalidAttribute.php',
    'Psalm\\Issue\\InvalidCast' => $baseDir . '/src/Psalm/Issue/InvalidCast.php',
    'Psalm\\Issue\\InvalidCatch' => $baseDir . '/src/Psalm/Issue/InvalidCatch.php',
    'Psalm\\Issue\\InvalidClass' => $baseDir . '/src/Psalm/Issue/InvalidClass.php',
    'Psalm\\Issue\\InvalidClassConstantType' => $baseDir . '/src/Psalm/Issue/InvalidClassConstantType.php',
    'Psalm\\Issue\\InvalidClone' => $baseDir . '/src/Psalm/Issue/InvalidClone.php',
    'Psalm\\Issue\\InvalidConstantAssignmentValue' => $baseDir . '/src/Psalm/Issue/InvalidConstantAssignmentValue.php',
    'Psalm\\Issue\\InvalidDocblock' => $baseDir . '/src/Psalm/Issue/InvalidDocblock.php',
    'Psalm\\Issue\\InvalidDocblockParamName' => $baseDir . '/src/Psalm/Issue/InvalidDocblockParamName.php',
    'Psalm\\Issue\\InvalidEnumBackingType' => $baseDir . '/src/Psalm/Issue/InvalidEnumBackingType.php',
    'Psalm\\Issue\\InvalidEnumCaseValue' => $baseDir . '/src/Psalm/Issue/InvalidEnumCaseValue.php',
    'Psalm\\Issue\\InvalidEnumMethod' => $baseDir . '/src/Psalm/Issue/InvalidEnumMethod.php',
    'Psalm\\Issue\\InvalidExtendClass' => $baseDir . '/src/Psalm/Issue/InvalidExtendClass.php',
    'Psalm\\Issue\\InvalidFalsableReturnType' => $baseDir . '/src/Psalm/Issue/InvalidFalsableReturnType.php',
    'Psalm\\Issue\\InvalidFunctionCall' => $baseDir . '/src/Psalm/Issue/InvalidFunctionCall.php',
    'Psalm\\Issue\\InvalidGlobal' => $baseDir . '/src/Psalm/Issue/InvalidGlobal.php',
    'Psalm\\Issue\\InvalidIterator' => $baseDir . '/src/Psalm/Issue/InvalidIterator.php',
    'Psalm\\Issue\\InvalidLiteralArgument' => $baseDir . '/src/Psalm/Issue/InvalidLiteralArgument.php',
    'Psalm\\Issue\\InvalidMethodCall' => $baseDir . '/src/Psalm/Issue/InvalidMethodCall.php',
    'Psalm\\Issue\\InvalidNamedArgument' => $baseDir . '/src/Psalm/Issue/InvalidNamedArgument.php',
    'Psalm\\Issue\\InvalidNullableReturnType' => $baseDir . '/src/Psalm/Issue/InvalidNullableReturnType.php',
    'Psalm\\Issue\\InvalidOperand' => $baseDir . '/src/Psalm/Issue/InvalidOperand.php',
    'Psalm\\Issue\\InvalidParamDefault' => $baseDir . '/src/Psalm/Issue/InvalidParamDefault.php',
    'Psalm\\Issue\\InvalidParent' => $baseDir . '/src/Psalm/Issue/InvalidParent.php',
    'Psalm\\Issue\\InvalidPassByReference' => $baseDir . '/src/Psalm/Issue/InvalidPassByReference.php',
    'Psalm\\Issue\\InvalidPropertyAssignment' => $baseDir . '/src/Psalm/Issue/InvalidPropertyAssignment.php',
    'Psalm\\Issue\\InvalidPropertyAssignmentValue' => $baseDir . '/src/Psalm/Issue/InvalidPropertyAssignmentValue.php',
    'Psalm\\Issue\\InvalidPropertyFetch' => $baseDir . '/src/Psalm/Issue/InvalidPropertyFetch.php',
    'Psalm\\Issue\\InvalidReturnStatement' => $baseDir . '/src/Psalm/Issue/InvalidReturnStatement.php',
    'Psalm\\Issue\\InvalidReturnType' => $baseDir . '/src/Psalm/Issue/InvalidReturnType.php',
    'Psalm\\Issue\\InvalidScalarArgument' => $baseDir . '/src/Psalm/Issue/InvalidScalarArgument.php',
    'Psalm\\Issue\\InvalidScope' => $baseDir . '/src/Psalm/Issue/InvalidScope.php',
    'Psalm\\Issue\\InvalidStaticInvocation' => $baseDir . '/src/Psalm/Issue/InvalidStaticInvocation.php',
    'Psalm\\Issue\\InvalidStringClass' => $baseDir . '/src/Psalm/Issue/InvalidStringClass.php',
    'Psalm\\Issue\\InvalidTemplateParam' => $baseDir . '/src/Psalm/Issue/InvalidTemplateParam.php',
    'Psalm\\Issue\\InvalidThrow' => $baseDir . '/src/Psalm/Issue/InvalidThrow.php',
    'Psalm\\Issue\\InvalidToString' => $baseDir . '/src/Psalm/Issue/InvalidToString.php',
    'Psalm\\Issue\\InvalidTraversableImplementation' => $baseDir . '/src/Psalm/Issue/InvalidTraversableImplementation.php',
    'Psalm\\Issue\\InvalidTypeImport' => $baseDir . '/src/Psalm/Issue/InvalidTypeImport.php',
    'Psalm\\Issue\\LessSpecificClassConstantType' => $baseDir . '/src/Psalm/Issue/LessSpecificClassConstantType.php',
    'Psalm\\Issue\\LessSpecificImplementedReturnType' => $baseDir . '/src/Psalm/Issue/LessSpecificImplementedReturnType.php',
    'Psalm\\Issue\\LessSpecificReturnStatement' => $baseDir . '/src/Psalm/Issue/LessSpecificReturnStatement.php',
    'Psalm\\Issue\\LessSpecificReturnType' => $baseDir . '/src/Psalm/Issue/LessSpecificReturnType.php',
    'Psalm\\Issue\\LoopInvalidation' => $baseDir . '/src/Psalm/Issue/LoopInvalidation.php',
    'Psalm\\Issue\\MethodIssue' => $baseDir . '/src/Psalm/Issue/MethodIssue.php',
    'Psalm\\Issue\\MethodSignatureMismatch' => $baseDir . '/src/Psalm/Issue/MethodSignatureMismatch.php',
    'Psalm\\Issue\\MethodSignatureMustOmitReturnType' => $baseDir . '/src/Psalm/Issue/MethodSignatureMustOmitReturnType.php',
    'Psalm\\Issue\\MethodSignatureMustProvideReturnType' => $baseDir . '/src/Psalm/Issue/MethodSignatureMustProvideReturnType.php',
    'Psalm\\Issue\\MismatchingDocblockParamType' => $baseDir . '/src/Psalm/Issue/MismatchingDocblockParamType.php',
    'Psalm\\Issue\\MismatchingDocblockPropertyType' => $baseDir . '/src/Psalm/Issue/MismatchingDocblockPropertyType.php',
    'Psalm\\Issue\\MismatchingDocblockReturnType' => $baseDir . '/src/Psalm/Issue/MismatchingDocblockReturnType.php',
    'Psalm\\Issue\\MissingClosureParamType' => $baseDir . '/src/Psalm/Issue/MissingClosureParamType.php',
    'Psalm\\Issue\\MissingClosureReturnType' => $baseDir . '/src/Psalm/Issue/MissingClosureReturnType.php',
    'Psalm\\Issue\\MissingConstructor' => $baseDir . '/src/Psalm/Issue/MissingConstructor.php',
    'Psalm\\Issue\\MissingDependency' => $baseDir . '/src/Psalm/Issue/MissingDependency.php',
    'Psalm\\Issue\\MissingDocblockType' => $baseDir . '/src/Psalm/Issue/MissingDocblockType.php',
    'Psalm\\Issue\\MissingFile' => $baseDir . '/src/Psalm/Issue/MissingFile.php',
    'Psalm\\Issue\\MissingImmutableAnnotation' => $baseDir . '/src/Psalm/Issue/MissingImmutableAnnotation.php',
    'Psalm\\Issue\\MissingParamType' => $baseDir . '/src/Psalm/Issue/MissingParamType.php',
    'Psalm\\Issue\\MissingPropertyType' => $baseDir . '/src/Psalm/Issue/MissingPropertyType.php',
    'Psalm\\Issue\\MissingReturnType' => $baseDir . '/src/Psalm/Issue/MissingReturnType.php',
    'Psalm\\Issue\\MissingTemplateParam' => $baseDir . '/src/Psalm/Issue/MissingTemplateParam.php',
    'Psalm\\Issue\\MissingThrowsDocblock' => $baseDir . '/src/Psalm/Issue/MissingThrowsDocblock.php',
    'Psalm\\Issue\\MixedArgument' => $baseDir . '/src/Psalm/Issue/MixedArgument.php',
    'Psalm\\Issue\\MixedArgumentTypeCoercion' => $baseDir . '/src/Psalm/Issue/MixedArgumentTypeCoercion.php',
    'Psalm\\Issue\\MixedArrayAccess' => $baseDir . '/src/Psalm/Issue/MixedArrayAccess.php',
    'Psalm\\Issue\\MixedArrayAssignment' => $baseDir . '/src/Psalm/Issue/MixedArrayAssignment.php',
    'Psalm\\Issue\\MixedArrayOffset' => $baseDir . '/src/Psalm/Issue/MixedArrayOffset.php',
    'Psalm\\Issue\\MixedArrayTypeCoercion' => $baseDir . '/src/Psalm/Issue/MixedArrayTypeCoercion.php',
    'Psalm\\Issue\\MixedAssignment' => $baseDir . '/src/Psalm/Issue/MixedAssignment.php',
    'Psalm\\Issue\\MixedClone' => $baseDir . '/src/Psalm/Issue/MixedClone.php',
    'Psalm\\Issue\\MixedFunctionCall' => $baseDir . '/src/Psalm/Issue/MixedFunctionCall.php',
    'Psalm\\Issue\\MixedInferredReturnType' => $baseDir . '/src/Psalm/Issue/MixedInferredReturnType.php',
    'Psalm\\Issue\\MixedIssue' => $baseDir . '/src/Psalm/Issue/MixedIssue.php',
    'Psalm\\Issue\\MixedIssueTrait' => $baseDir . '/src/Psalm/Issue/MixedIssueTrait.php',
    'Psalm\\Issue\\MixedMethodCall' => $baseDir . '/src/Psalm/Issue/MixedMethodCall.php',
    'Psalm\\Issue\\MixedOperand' => $baseDir . '/src/Psalm/Issue/MixedOperand.php',
    'Psalm\\Issue\\MixedPropertyAssignment' => $baseDir . '/src/Psalm/Issue/MixedPropertyAssignment.php',
    'Psalm\\Issue\\MixedPropertyFetch' => $baseDir . '/src/Psalm/Issue/MixedPropertyFetch.php',
    'Psalm\\Issue\\MixedPropertyTypeCoercion' => $baseDir . '/src/Psalm/Issue/MixedPropertyTypeCoercion.php',
    'Psalm\\Issue\\MixedReturnStatement' => $baseDir . '/src/Psalm/Issue/MixedReturnStatement.php',
    'Psalm\\Issue\\MixedReturnTypeCoercion' => $baseDir . '/src/Psalm/Issue/MixedReturnTypeCoercion.php',
    'Psalm\\Issue\\MixedStringOffsetAssignment' => $baseDir . '/src/Psalm/Issue/MixedStringOffsetAssignment.php',
    'Psalm\\Issue\\MoreSpecificImplementedParamType' => $baseDir . '/src/Psalm/Issue/MoreSpecificImplementedParamType.php',
    'Psalm\\Issue\\MoreSpecificReturnType' => $baseDir . '/src/Psalm/Issue/MoreSpecificReturnType.php',
    'Psalm\\Issue\\MutableDependency' => $baseDir . '/src/Psalm/Issue/MutableDependency.php',
    'Psalm\\Issue\\NamedArgumentNotAllowed' => $baseDir . '/src/Psalm/Issue/NamedArgumentNotAllowed.php',
    'Psalm\\Issue\\NoEnumProperties' => $baseDir . '/src/Psalm/Issue/NoEnumProperties.php',
    'Psalm\\Issue\\NoInterfaceProperties' => $baseDir . '/src/Psalm/Issue/NoInterfaceProperties.php',
    'Psalm\\Issue\\NoValue' => $baseDir . '/src/Psalm/Issue/NoValue.php',
    'Psalm\\Issue\\NonInvariantDocblockPropertyType' => $baseDir . '/src/Psalm/Issue/NonInvariantDocblockPropertyType.php',
    'Psalm\\Issue\\NonInvariantPropertyType' => $baseDir . '/src/Psalm/Issue/NonInvariantPropertyType.php',
    'Psalm\\Issue\\NonStaticSelfCall' => $baseDir . '/src/Psalm/Issue/NonStaticSelfCall.php',
    'Psalm\\Issue\\NullArgument' => $baseDir . '/src/Psalm/Issue/NullArgument.php',
    'Psalm\\Issue\\NullArrayAccess' => $baseDir . '/src/Psalm/Issue/NullArrayAccess.php',
    'Psalm\\Issue\\NullArrayOffset' => $baseDir . '/src/Psalm/Issue/NullArrayOffset.php',
    'Psalm\\Issue\\NullFunctionCall' => $baseDir . '/src/Psalm/Issue/NullFunctionCall.php',
    'Psalm\\Issue\\NullIterator' => $baseDir . '/src/Psalm/Issue/NullIterator.php',
    'Psalm\\Issue\\NullOperand' => $baseDir . '/src/Psalm/Issue/NullOperand.php',
    'Psalm\\Issue\\NullPropertyAssignment' => $baseDir . '/src/Psalm/Issue/NullPropertyAssignment.php',
    'Psalm\\Issue\\NullPropertyFetch' => $baseDir . '/src/Psalm/Issue/NullPropertyFetch.php',
    'Psalm\\Issue\\NullReference' => $baseDir . '/src/Psalm/Issue/NullReference.php',
    'Psalm\\Issue\\NullableReturnStatement' => $baseDir . '/src/Psalm/Issue/NullableReturnStatement.php',
    'Psalm\\Issue\\OverriddenFinalConstant' => $baseDir . '/src/Psalm/Issue/OverriddenFinalConstant.php',
    'Psalm\\Issue\\OverriddenInterfaceConstant' => $baseDir . '/src/Psalm/Issue/OverriddenInterfaceConstant.php',
    'Psalm\\Issue\\OverriddenMethodAccess' => $baseDir . '/src/Psalm/Issue/OverriddenMethodAccess.php',
    'Psalm\\Issue\\OverriddenPropertyAccess' => $baseDir . '/src/Psalm/Issue/OverriddenPropertyAccess.php',
    'Psalm\\Issue\\ParadoxicalCondition' => $baseDir . '/src/Psalm/Issue/ParadoxicalCondition.php',
    'Psalm\\Issue\\ParamNameMismatch' => $baseDir . '/src/Psalm/Issue/ParamNameMismatch.php',
    'Psalm\\Issue\\ParentNotFound' => $baseDir . '/src/Psalm/Issue/ParentNotFound.php',
    'Psalm\\Issue\\ParseError' => $baseDir . '/src/Psalm/Issue/ParseError.php',
    'Psalm\\Issue\\PluginIssue' => $baseDir . '/src/Psalm/Issue/PluginIssue.php',
    'Psalm\\Issue\\PossibleRawObjectIteration' => $baseDir . '/src/Psalm/Issue/PossibleRawObjectIteration.php',
    'Psalm\\Issue\\PossiblyFalseArgument' => $baseDir . '/src/Psalm/Issue/PossiblyFalseArgument.php',
    'Psalm\\Issue\\PossiblyFalseIterator' => $baseDir . '/src/Psalm/Issue/PossiblyFalseIterator.php',
    'Psalm\\Issue\\PossiblyFalseOperand' => $baseDir . '/src/Psalm/Issue/PossiblyFalseOperand.php',
    'Psalm\\Issue\\PossiblyFalsePropertyAssignmentValue' => $baseDir . '/src/Psalm/Issue/PossiblyFalsePropertyAssignmentValue.php',
    'Psalm\\Issue\\PossiblyFalseReference' => $baseDir . '/src/Psalm/Issue/PossiblyFalseReference.php',
    'Psalm\\Issue\\PossiblyInvalidArgument' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidArgument.php',
    'Psalm\\Issue\\PossiblyInvalidArrayAccess' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidArrayAccess.php',
    'Psalm\\Issue\\PossiblyInvalidArrayAssignment' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidArrayAssignment.php',
    'Psalm\\Issue\\PossiblyInvalidArrayOffset' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidArrayOffset.php',
    'Psalm\\Issue\\PossiblyInvalidCast' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidCast.php',
    'Psalm\\Issue\\PossiblyInvalidClone' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidClone.php',
    'Psalm\\Issue\\PossiblyInvalidDocblockTag' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidDocblockTag.php',
    'Psalm\\Issue\\PossiblyInvalidFunctionCall' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidFunctionCall.php',
    'Psalm\\Issue\\PossiblyInvalidIterator' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidIterator.php',
    'Psalm\\Issue\\PossiblyInvalidMethodCall' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidMethodCall.php',
    'Psalm\\Issue\\PossiblyInvalidOperand' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidOperand.php',
    'Psalm\\Issue\\PossiblyInvalidPropertyAssignment' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidPropertyAssignment.php',
    'Psalm\\Issue\\PossiblyInvalidPropertyAssignmentValue' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidPropertyAssignmentValue.php',
    'Psalm\\Issue\\PossiblyInvalidPropertyFetch' => $baseDir . '/src/Psalm/Issue/PossiblyInvalidPropertyFetch.php',
    'Psalm\\Issue\\PossiblyNullArgument' => $baseDir . '/src/Psalm/Issue/PossiblyNullArgument.php',
    'Psalm\\Issue\\PossiblyNullArrayAccess' => $baseDir . '/src/Psalm/Issue/PossiblyNullArrayAccess.php',
    'Psalm\\Issue\\PossiblyNullArrayAssignment' => $baseDir . '/src/Psalm/Issue/PossiblyNullArrayAssignment.php',
    'Psalm\\Issue\\PossiblyNullArrayOffset' => $baseDir . '/src/Psalm/Issue/PossiblyNullArrayOffset.php',
    'Psalm\\Issue\\PossiblyNullFunctionCall' => $baseDir . '/src/Psalm/Issue/PossiblyNullFunctionCall.php',
    'Psalm\\Issue\\PossiblyNullIterator' => $baseDir . '/src/Psalm/Issue/PossiblyNullIterator.php',
    'Psalm\\Issue\\PossiblyNullOperand' => $baseDir . '/src/Psalm/Issue/PossiblyNullOperand.php',
    'Psalm\\Issue\\PossiblyNullPropertyAssignment' => $baseDir . '/src/Psalm/Issue/PossiblyNullPropertyAssignment.php',
    'Psalm\\Issue\\PossiblyNullPropertyAssignmentValue' => $baseDir . '/src/Psalm/Issue/PossiblyNullPropertyAssignmentValue.php',
    'Psalm\\Issue\\PossiblyNullPropertyFetch' => $baseDir . '/src/Psalm/Issue/PossiblyNullPropertyFetch.php',
    'Psalm\\Issue\\PossiblyNullReference' => $baseDir . '/src/Psalm/Issue/PossiblyNullReference.php',
    'Psalm\\Issue\\PossiblyUndefinedArrayOffset' => $baseDir . '/src/Psalm/Issue/PossiblyUndefinedArrayOffset.php',
    'Psalm\\Issue\\PossiblyUndefinedGlobalVariable' => $baseDir . '/src/Psalm/Issue/PossiblyUndefinedGlobalVariable.php',
    'Psalm\\Issue\\PossiblyUndefinedIntArrayOffset' => $baseDir . '/src/Psalm/Issue/PossiblyUndefinedIntArrayOffset.php',
    'Psalm\\Issue\\PossiblyUndefinedMethod' => $baseDir . '/src/Psalm/Issue/PossiblyUndefinedMethod.php',
    'Psalm\\Issue\\PossiblyUndefinedStringArrayOffset' => $baseDir . '/src/Psalm/Issue/PossiblyUndefinedStringArrayOffset.php',
    'Psalm\\Issue\\PossiblyUndefinedVariable' => $baseDir . '/src/Psalm/Issue/PossiblyUndefinedVariable.php',
    'Psalm\\Issue\\PossiblyUnusedMethod' => $baseDir . '/src/Psalm/Issue/PossiblyUnusedMethod.php',
    'Psalm\\Issue\\PossiblyUnusedParam' => $baseDir . '/src/Psalm/Issue/PossiblyUnusedParam.php',
    'Psalm\\Issue\\PossiblyUnusedProperty' => $baseDir . '/src/Psalm/Issue/PossiblyUnusedProperty.php',
    'Psalm\\Issue\\PossiblyUnusedReturnValue' => $baseDir . '/src/Psalm/Issue/PossiblyUnusedReturnValue.php',
    'Psalm\\Issue\\PropertyIssue' => $baseDir . '/src/Psalm/Issue/PropertyIssue.php',
    'Psalm\\Issue\\PropertyNotSetInConstructor' => $baseDir . '/src/Psalm/Issue/PropertyNotSetInConstructor.php',
    'Psalm\\Issue\\PropertyTypeCoercion' => $baseDir . '/src/Psalm/Issue/PropertyTypeCoercion.php',
    'Psalm\\Issue\\PsalmInternalError' => $baseDir . '/src/Psalm/Issue/PsalmInternalError.php',
    'Psalm\\Issue\\RawObjectIteration' => $baseDir . '/src/Psalm/Issue/RawObjectIteration.php',
    'Psalm\\Issue\\RedundantCast' => $baseDir . '/src/Psalm/Issue/RedundantCast.php',
    'Psalm\\Issue\\RedundantCastGivenDocblockType' => $baseDir . '/src/Psalm/Issue/RedundantCastGivenDocblockType.php',
    'Psalm\\Issue\\RedundantCondition' => $baseDir . '/src/Psalm/Issue/RedundantCondition.php',
    'Psalm\\Issue\\RedundantConditionGivenDocblockType' => $baseDir . '/src/Psalm/Issue/RedundantConditionGivenDocblockType.php',
    'Psalm\\Issue\\RedundantFunctionCall' => $baseDir . '/src/Psalm/Issue/RedundantFunctionCall.php',
    'Psalm\\Issue\\RedundantFunctionCallGivenDocblockType' => $baseDir . '/src/Psalm/Issue/RedundantFunctionCallGivenDocblockType.php',
    'Psalm\\Issue\\RedundantIdentityWithTrue' => $baseDir . '/src/Psalm/Issue/RedundantIdentityWithTrue.php',
    'Psalm\\Issue\\RedundantPropertyInitializationCheck' => $baseDir . '/src/Psalm/Issue/RedundantPropertyInitializationCheck.php',
    'Psalm\\Issue\\ReferenceConstraintViolation' => $baseDir . '/src/Psalm/Issue/ReferenceConstraintViolation.php',
    'Psalm\\Issue\\ReferenceReusedFromConfusingScope' => $baseDir . '/src/Psalm/Issue/ReferenceReusedFromConfusingScope.php',
    'Psalm\\Issue\\ReservedWord' => $baseDir . '/src/Psalm/Issue/ReservedWord.php',
    'Psalm\\Issue\\RiskyCast' => $baseDir . '/src/Psalm/Issue/RiskyCast.php',
    'Psalm\\Issue\\StringIncrement' => $baseDir . '/src/Psalm/Issue/StringIncrement.php',
    'Psalm\\Issue\\TaintedCallable' => $baseDir . '/src/Psalm/Issue/TaintedCallable.php',
    'Psalm\\Issue\\TaintedCookie' => $baseDir . '/src/Psalm/Issue/TaintedCookie.php',
    'Psalm\\Issue\\TaintedCustom' => $baseDir . '/src/Psalm/Issue/TaintedCustom.php',
    'Psalm\\Issue\\TaintedEval' => $baseDir . '/src/Psalm/Issue/TaintedEval.php',
    'Psalm\\Issue\\TaintedFile' => $baseDir . '/src/Psalm/Issue/TaintedFile.php',
    'Psalm\\Issue\\TaintedHeader' => $baseDir . '/src/Psalm/Issue/TaintedHeader.php',
    'Psalm\\Issue\\TaintedHtml' => $baseDir . '/src/Psalm/Issue/TaintedHtml.php',
    'Psalm\\Issue\\TaintedInclude' => $baseDir . '/src/Psalm/Issue/TaintedInclude.php',
    'Psalm\\Issue\\TaintedInput' => $baseDir . '/src/Psalm/Issue/TaintedInput.php',
    'Psalm\\Issue\\TaintedLdap' => $baseDir . '/src/Psalm/Issue/TaintedLdap.php',
    'Psalm\\Issue\\TaintedSSRF' => $baseDir . '/src/Psalm/Issue/TaintedSSRF.php',
    'Psalm\\Issue\\TaintedShell' => $baseDir . '/src/Psalm/Issue/TaintedShell.php',
    'Psalm\\Issue\\TaintedSql' => $baseDir . '/src/Psalm/Issue/TaintedSql.php',
    'Psalm\\Issue\\TaintedSystemSecret' => $baseDir . '/src/Psalm/Issue/TaintedSystemSecret.php',
    'Psalm\\Issue\\TaintedTextWithQuotes' => $baseDir . '/src/Psalm/Issue/TaintedTextWithQuotes.php',
    'Psalm\\Issue\\TaintedUnserialize' => $baseDir . '/src/Psalm/Issue/TaintedUnserialize.php',
    'Psalm\\Issue\\TaintedUserSecret' => $baseDir . '/src/Psalm/Issue/TaintedUserSecret.php',
    'Psalm\\Issue\\TooFewArguments' => $baseDir . '/src/Psalm/Issue/TooFewArguments.php',
    'Psalm\\Issue\\TooManyArguments' => $baseDir . '/src/Psalm/Issue/TooManyArguments.php',
    'Psalm\\Issue\\TooManyTemplateParams' => $baseDir . '/src/Psalm/Issue/TooManyTemplateParams.php',
    'Psalm\\Issue\\Trace' => $baseDir . '/src/Psalm/Issue/Trace.php',
    'Psalm\\Issue\\TraitMethodSignatureMismatch' => $baseDir . '/src/Psalm/Issue/TraitMethodSignatureMismatch.php',
    'Psalm\\Issue\\TypeDoesNotContainNull' => $baseDir . '/src/Psalm/Issue/TypeDoesNotContainNull.php',
    'Psalm\\Issue\\TypeDoesNotContainType' => $baseDir . '/src/Psalm/Issue/TypeDoesNotContainType.php',
    'Psalm\\Issue\\UncaughtThrowInGlobalScope' => $baseDir . '/src/Psalm/Issue/UncaughtThrowInGlobalScope.php',
    'Psalm\\Issue\\UndefinedAttributeClass' => $baseDir . '/src/Psalm/Issue/UndefinedAttributeClass.php',
    'Psalm\\Issue\\UndefinedClass' => $baseDir . '/src/Psalm/Issue/UndefinedClass.php',
    'Psalm\\Issue\\UndefinedConstant' => $baseDir . '/src/Psalm/Issue/UndefinedConstant.php',
    'Psalm\\Issue\\UndefinedDocblockClass' => $baseDir . '/src/Psalm/Issue/UndefinedDocblockClass.php',
    'Psalm\\Issue\\UndefinedFunction' => $baseDir . '/src/Psalm/Issue/UndefinedFunction.php',
    'Psalm\\Issue\\UndefinedGlobalVariable' => $baseDir . '/src/Psalm/Issue/UndefinedGlobalVariable.php',
    'Psalm\\Issue\\UndefinedInterface' => $baseDir . '/src/Psalm/Issue/UndefinedInterface.php',
    'Psalm\\Issue\\UndefinedInterfaceMethod' => $baseDir . '/src/Psalm/Issue/UndefinedInterfaceMethod.php',
    'Psalm\\Issue\\UndefinedMagicMethod' => $baseDir . '/src/Psalm/Issue/UndefinedMagicMethod.php',
    'Psalm\\Issue\\UndefinedMagicPropertyAssignment' => $baseDir . '/src/Psalm/Issue/UndefinedMagicPropertyAssignment.php',
    'Psalm\\Issue\\UndefinedMagicPropertyFetch' => $baseDir . '/src/Psalm/Issue/UndefinedMagicPropertyFetch.php',
    'Psalm\\Issue\\UndefinedMethod' => $baseDir . '/src/Psalm/Issue/UndefinedMethod.php',
    'Psalm\\Issue\\UndefinedPropertyAssignment' => $baseDir . '/src/Psalm/Issue/UndefinedPropertyAssignment.php',
    'Psalm\\Issue\\UndefinedPropertyFetch' => $baseDir . '/src/Psalm/Issue/UndefinedPropertyFetch.php',
    'Psalm\\Issue\\UndefinedThisPropertyAssignment' => $baseDir . '/src/Psalm/Issue/UndefinedThisPropertyAssignment.php',
    'Psalm\\Issue\\UndefinedThisPropertyFetch' => $baseDir . '/src/Psalm/Issue/UndefinedThisPropertyFetch.php',
    'Psalm\\Issue\\UndefinedTrace' => $baseDir . '/src/Psalm/Issue/UndefinedTrace.php',
    'Psalm\\Issue\\UndefinedTrait' => $baseDir . '/src/Psalm/Issue/UndefinedTrait.php',
    'Psalm\\Issue\\UndefinedVariable' => $baseDir . '/src/Psalm/Issue/UndefinedVariable.php',
    'Psalm\\Issue\\UnevaluatedCode' => $baseDir . '/src/Psalm/Issue/UnevaluatedCode.php',
    'Psalm\\Issue\\UnhandledMatchCondition' => $baseDir . '/src/Psalm/Issue/UnhandledMatchCondition.php',
    'Psalm\\Issue\\UnimplementedAbstractMethod' => $baseDir . '/src/Psalm/Issue/UnimplementedAbstractMethod.php',
    'Psalm\\Issue\\UnimplementedInterfaceMethod' => $baseDir . '/src/Psalm/Issue/UnimplementedInterfaceMethod.php',
    'Psalm\\Issue\\UninitializedProperty' => $baseDir . '/src/Psalm/Issue/UninitializedProperty.php',
    'Psalm\\Issue\\UnnecessaryVarAnnotation' => $baseDir . '/src/Psalm/Issue/UnnecessaryVarAnnotation.php',
    'Psalm\\Issue\\UnrecognizedExpression' => $baseDir . '/src/Psalm/Issue/UnrecognizedExpression.php',
    'Psalm\\Issue\\UnrecognizedStatement' => $baseDir . '/src/Psalm/Issue/UnrecognizedStatement.php',
    'Psalm\\Issue\\UnresolvableConstant' => $baseDir . '/src/Psalm/Issue/UnresolvableConstant.php',
    'Psalm\\Issue\\UnresolvableInclude' => $baseDir . '/src/Psalm/Issue/UnresolvableInclude.php',
    'Psalm\\Issue\\UnsafeGenericInstantiation' => $baseDir . '/src/Psalm/Issue/UnsafeGenericInstantiation.php',
    'Psalm\\Issue\\UnsafeInstantiation' => $baseDir . '/src/Psalm/Issue/UnsafeInstantiation.php',
    'Psalm\\Issue\\UnsupportedReferenceUsage' => $baseDir . '/src/Psalm/Issue/UnsupportedReferenceUsage.php',
    'Psalm\\Issue\\UnusedBaselineEntry' => $baseDir . '/src/Psalm/Issue/UnusedBaselineEntry.php',
    'Psalm\\Issue\\UnusedClass' => $baseDir . '/src/Psalm/Issue/UnusedClass.php',
    'Psalm\\Issue\\UnusedClosureParam' => $baseDir . '/src/Psalm/Issue/UnusedClosureParam.php',
    'Psalm\\Issue\\UnusedConstructor' => $baseDir . '/src/Psalm/Issue/UnusedConstructor.php',
    'Psalm\\Issue\\UnusedForeachValue' => $baseDir . '/src/Psalm/Issue/UnusedForeachValue.php',
    'Psalm\\Issue\\UnusedFunctionCall' => $baseDir . '/src/Psalm/Issue/UnusedFunctionCall.php',
    'Psalm\\Issue\\UnusedMethod' => $baseDir . '/src/Psalm/Issue/UnusedMethod.php',
    'Psalm\\Issue\\UnusedMethodCall' => $baseDir . '/src/Psalm/Issue/UnusedMethodCall.php',
    'Psalm\\Issue\\UnusedParam' => $baseDir . '/src/Psalm/Issue/UnusedParam.php',
    'Psalm\\Issue\\UnusedProperty' => $baseDir . '/src/Psalm/Issue/UnusedProperty.php',
    'Psalm\\Issue\\UnusedPsalmSuppress' => $baseDir . '/src/Psalm/Issue/UnusedPsalmSuppress.php',
    'Psalm\\Issue\\UnusedReturnValue' => $baseDir . '/src/Psalm/Issue/UnusedReturnValue.php',
    'Psalm\\Issue\\UnusedVariable' => $baseDir . '/src/Psalm/Issue/UnusedVariable.php',
    'Psalm\\Issue\\VariableIssue' => $baseDir . '/src/Psalm/Issue/VariableIssue.php',
    'Psalm\\NodeTypeProvider' => $baseDir . '/src/Psalm/NodeTypeProvider.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualBitwiseAnd' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualBitwiseAnd.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualBitwiseOr' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualBitwiseOr.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualBitwiseXor' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualBitwiseXor.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualCoalesce' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualCoalesce.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualConcat' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualConcat.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualDiv' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualDiv.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualMinus' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualMinus.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualMod' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualMod.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualMul' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualMul.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualPlus' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualPlus.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualPow' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualPow.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualShiftLeft' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualShiftLeft.php',
    'Psalm\\Node\\Expr\\AssignOp\\VirtualShiftRight' => $baseDir . '/src/Psalm/Node/Expr/AssignOp/VirtualShiftRight.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualBitwiseAnd' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseAnd.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualBitwiseOr' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseOr.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualBitwiseXor' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseXor.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualBooleanAnd' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualBooleanAnd.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualBooleanOr' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualBooleanOr.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualCoalesce' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualCoalesce.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualConcat' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualConcat.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualDiv' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualDiv.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualEqual' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualEqual.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualGreater' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualGreater.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualGreaterOrEqual' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualGreaterOrEqual.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualIdentical' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualIdentical.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualLogicalAnd' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualLogicalAnd.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualLogicalOr' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualLogicalOr.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualLogicalXor' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualLogicalXor.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualMinus' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualMinus.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualMod' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualMod.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualMul' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualMul.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualNotEqual' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualNotEqual.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualNotIdentical' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualNotIdentical.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualPlus' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualPlus.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualPow' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualPow.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualShiftLeft' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualShiftLeft.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualShiftRight' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualShiftRight.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualSmaller' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualSmaller.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualSmallerOrEqual' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualSmallerOrEqual.php',
    'Psalm\\Node\\Expr\\BinaryOp\\VirtualSpaceship' => $baseDir . '/src/Psalm/Node/Expr/BinaryOp/VirtualSpaceship.php',
    'Psalm\\Node\\Expr\\Cast\\VirtualArray' => $baseDir . '/src/Psalm/Node/Expr/Cast/VirtualArray.php',
    'Psalm\\Node\\Expr\\Cast\\VirtualBool' => $baseDir . '/src/Psalm/Node/Expr/Cast/VirtualBool.php',
    'Psalm\\Node\\Expr\\Cast\\VirtualDouble' => $baseDir . '/src/Psalm/Node/Expr/Cast/VirtualDouble.php',
    'Psalm\\Node\\Expr\\Cast\\VirtualInt' => $baseDir . '/src/Psalm/Node/Expr/Cast/VirtualInt.php',
    'Psalm\\Node\\Expr\\Cast\\VirtualObject' => $baseDir . '/src/Psalm/Node/Expr/Cast/VirtualObject.php',
    'Psalm\\Node\\Expr\\Cast\\VirtualString' => $baseDir . '/src/Psalm/Node/Expr/Cast/VirtualString.php',
    'Psalm\\Node\\Expr\\Cast\\VirtualUnset' => $baseDir . '/src/Psalm/Node/Expr/Cast/VirtualUnset.php',
    'Psalm\\Node\\Expr\\VirtualArray' => $baseDir . '/src/Psalm/Node/Expr/VirtualArray.php',
    'Psalm\\Node\\Expr\\VirtualArrayDimFetch' => $baseDir . '/src/Psalm/Node/Expr/VirtualArrayDimFetch.php',
    'Psalm\\Node\\Expr\\VirtualArrayItem' => $baseDir . '/src/Psalm/Node/Expr/VirtualArrayItem.php',
    'Psalm\\Node\\Expr\\VirtualArrowFunction' => $baseDir . '/src/Psalm/Node/Expr/VirtualArrowFunction.php',
    'Psalm\\Node\\Expr\\VirtualAssign' => $baseDir . '/src/Psalm/Node/Expr/VirtualAssign.php',
    'Psalm\\Node\\Expr\\VirtualAssignRef' => $baseDir . '/src/Psalm/Node/Expr/VirtualAssignRef.php',
    'Psalm\\Node\\Expr\\VirtualBitwiseNot' => $baseDir . '/src/Psalm/Node/Expr/VirtualBitwiseNot.php',
    'Psalm\\Node\\Expr\\VirtualBooleanNot' => $baseDir . '/src/Psalm/Node/Expr/VirtualBooleanNot.php',
    'Psalm\\Node\\Expr\\VirtualClassConstFetch' => $baseDir . '/src/Psalm/Node/Expr/VirtualClassConstFetch.php',
    'Psalm\\Node\\Expr\\VirtualClone' => $baseDir . '/src/Psalm/Node/Expr/VirtualClone.php',
    'Psalm\\Node\\Expr\\VirtualClosure' => $baseDir . '/src/Psalm/Node/Expr/VirtualClosure.php',
    'Psalm\\Node\\Expr\\VirtualClosureUse' => $baseDir . '/src/Psalm/Node/Expr/VirtualClosureUse.php',
    'Psalm\\Node\\Expr\\VirtualConstFetch' => $baseDir . '/src/Psalm/Node/Expr/VirtualConstFetch.php',
    'Psalm\\Node\\Expr\\VirtualEmpty' => $baseDir . '/src/Psalm/Node/Expr/VirtualEmpty.php',
    'Psalm\\Node\\Expr\\VirtualError' => $baseDir . '/src/Psalm/Node/Expr/VirtualError.php',
    'Psalm\\Node\\Expr\\VirtualErrorSuppress' => $baseDir . '/src/Psalm/Node/Expr/VirtualErrorSuppress.php',
    'Psalm\\Node\\Expr\\VirtualEval' => $baseDir . '/src/Psalm/Node/Expr/VirtualEval.php',
    'Psalm\\Node\\Expr\\VirtualExit' => $baseDir . '/src/Psalm/Node/Expr/VirtualExit.php',
    'Psalm\\Node\\Expr\\VirtualFuncCall' => $baseDir . '/src/Psalm/Node/Expr/VirtualFuncCall.php',
    'Psalm\\Node\\Expr\\VirtualInclude' => $baseDir . '/src/Psalm/Node/Expr/VirtualInclude.php',
    'Psalm\\Node\\Expr\\VirtualInstanceof' => $baseDir . '/src/Psalm/Node/Expr/VirtualInstanceof.php',
    'Psalm\\Node\\Expr\\VirtualIsset' => $baseDir . '/src/Psalm/Node/Expr/VirtualIsset.php',
    'Psalm\\Node\\Expr\\VirtualList' => $baseDir . '/src/Psalm/Node/Expr/VirtualList.php',
    'Psalm\\Node\\Expr\\VirtualMatch' => $baseDir . '/src/Psalm/Node/Expr/VirtualMatch.php',
    'Psalm\\Node\\Expr\\VirtualMethodCall' => $baseDir . '/src/Psalm/Node/Expr/VirtualMethodCall.php',
    'Psalm\\Node\\Expr\\VirtualNew' => $baseDir . '/src/Psalm/Node/Expr/VirtualNew.php',
    'Psalm\\Node\\Expr\\VirtualNullsafeMethodCall' => $baseDir . '/src/Psalm/Node/Expr/VirtualNullsafeMethodCall.php',
    'Psalm\\Node\\Expr\\VirtualNullsafePropertyFetch' => $baseDir . '/src/Psalm/Node/Expr/VirtualNullsafePropertyFetch.php',
    'Psalm\\Node\\Expr\\VirtualPostDec' => $baseDir . '/src/Psalm/Node/Expr/VirtualPostDec.php',
    'Psalm\\Node\\Expr\\VirtualPostInc' => $baseDir . '/src/Psalm/Node/Expr/VirtualPostInc.php',
    'Psalm\\Node\\Expr\\VirtualPreDec' => $baseDir . '/src/Psalm/Node/Expr/VirtualPreDec.php',
    'Psalm\\Node\\Expr\\VirtualPreInc' => $baseDir . '/src/Psalm/Node/Expr/VirtualPreInc.php',
    'Psalm\\Node\\Expr\\VirtualPrint' => $baseDir . '/src/Psalm/Node/Expr/VirtualPrint.php',
    'Psalm\\Node\\Expr\\VirtualPropertyFetch' => $baseDir . '/src/Psalm/Node/Expr/VirtualPropertyFetch.php',
    'Psalm\\Node\\Expr\\VirtualShellExec' => $baseDir . '/src/Psalm/Node/Expr/VirtualShellExec.php',
    'Psalm\\Node\\Expr\\VirtualStaticCall' => $baseDir . '/src/Psalm/Node/Expr/VirtualStaticCall.php',
    'Psalm\\Node\\Expr\\VirtualStaticPropertyFetch' => $baseDir . '/src/Psalm/Node/Expr/VirtualStaticPropertyFetch.php',
    'Psalm\\Node\\Expr\\VirtualTernary' => $baseDir . '/src/Psalm/Node/Expr/VirtualTernary.php',
    'Psalm\\Node\\Expr\\VirtualThrow' => $baseDir . '/src/Psalm/Node/Expr/VirtualThrow.php',
    'Psalm\\Node\\Expr\\VirtualUnaryMinus' => $baseDir . '/src/Psalm/Node/Expr/VirtualUnaryMinus.php',
    'Psalm\\Node\\Expr\\VirtualUnaryPlus' => $baseDir . '/src/Psalm/Node/Expr/VirtualUnaryPlus.php',
    'Psalm\\Node\\Expr\\VirtualVariable' => $baseDir . '/src/Psalm/Node/Expr/VirtualVariable.php',
    'Psalm\\Node\\Expr\\VirtualYield' => $baseDir . '/src/Psalm/Node/Expr/VirtualYield.php',
    'Psalm\\Node\\Expr\\VirtualYieldFrom' => $baseDir . '/src/Psalm/Node/Expr/VirtualYieldFrom.php',
    'Psalm\\Node\\Name\\VirtualFullyQualified' => $baseDir . '/src/Psalm/Node/Name/VirtualFullyQualified.php',
    'Psalm\\Node\\Name\\VirtualRelative' => $baseDir . '/src/Psalm/Node/Name/VirtualRelative.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualClass' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualClass.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualDir' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualDir.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualFile' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualFile.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualFunction' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualFunction.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualLine' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualLine.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualMethod' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualMethod.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualNamespace' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualNamespace.php',
    'Psalm\\Node\\Scalar\\MagicConst\\VirtualTrait' => $baseDir . '/src/Psalm/Node/Scalar/MagicConst/VirtualTrait.php',
    'Psalm\\Node\\Scalar\\VirtualDNumber' => $baseDir . '/src/Psalm/Node/Scalar/VirtualDNumber.php',
    'Psalm\\Node\\Scalar\\VirtualEncapsed' => $baseDir . '/src/Psalm/Node/Scalar/VirtualEncapsed.php',
    'Psalm\\Node\\Scalar\\VirtualEncapsedStringPart' => $baseDir . '/src/Psalm/Node/Scalar/VirtualEncapsedStringPart.php',
    'Psalm\\Node\\Scalar\\VirtualLNumber' => $baseDir . '/src/Psalm/Node/Scalar/VirtualLNumber.php',
    'Psalm\\Node\\Scalar\\VirtualString' => $baseDir . '/src/Psalm/Node/Scalar/VirtualString.php',
    'Psalm\\Node\\Stmt\\TraitUseAdaptation\\VirtualAlias' => $baseDir . '/src/Psalm/Node/Stmt/TraitUseAdaptation/VirtualAlias.php',
    'Psalm\\Node\\Stmt\\TraitUseAdaptation\\VirtualPrecedence' => $baseDir . '/src/Psalm/Node/Stmt/TraitUseAdaptation/VirtualPrecedence.php',
    'Psalm\\Node\\Stmt\\VirtualBreak' => $baseDir . '/src/Psalm/Node/Stmt/VirtualBreak.php',
    'Psalm\\Node\\Stmt\\VirtualCase' => $baseDir . '/src/Psalm/Node/Stmt/VirtualCase.php',
    'Psalm\\Node\\Stmt\\VirtualCatch' => $baseDir . '/src/Psalm/Node/Stmt/VirtualCatch.php',
    'Psalm\\Node\\Stmt\\VirtualClass' => $baseDir . '/src/Psalm/Node/Stmt/VirtualClass.php',
    'Psalm\\Node\\Stmt\\VirtualClassConst' => $baseDir . '/src/Psalm/Node/Stmt/VirtualClassConst.php',
    'Psalm\\Node\\Stmt\\VirtualClassMethod' => $baseDir . '/src/Psalm/Node/Stmt/VirtualClassMethod.php',
    'Psalm\\Node\\Stmt\\VirtualConst' => $baseDir . '/src/Psalm/Node/Stmt/VirtualConst.php',
    'Psalm\\Node\\Stmt\\VirtualContinue' => $baseDir . '/src/Psalm/Node/Stmt/VirtualContinue.php',
    'Psalm\\Node\\Stmt\\VirtualDeclare' => $baseDir . '/src/Psalm/Node/Stmt/VirtualDeclare.php',
    'Psalm\\Node\\Stmt\\VirtualDeclareDeclare' => $baseDir . '/src/Psalm/Node/Stmt/VirtualDeclareDeclare.php',
    'Psalm\\Node\\Stmt\\VirtualDo' => $baseDir . '/src/Psalm/Node/Stmt/VirtualDo.php',
    'Psalm\\Node\\Stmt\\VirtualEcho' => $baseDir . '/src/Psalm/Node/Stmt/VirtualEcho.php',
    'Psalm\\Node\\Stmt\\VirtualElse' => $baseDir . '/src/Psalm/Node/Stmt/VirtualElse.php',
    'Psalm\\Node\\Stmt\\VirtualElseIf' => $baseDir . '/src/Psalm/Node/Stmt/VirtualElseIf.php',
    'Psalm\\Node\\Stmt\\VirtualExpression' => $baseDir . '/src/Psalm/Node/Stmt/VirtualExpression.php',
    'Psalm\\Node\\Stmt\\VirtualFinally' => $baseDir . '/src/Psalm/Node/Stmt/VirtualFinally.php',
    'Psalm\\Node\\Stmt\\VirtualFor' => $baseDir . '/src/Psalm/Node/Stmt/VirtualFor.php',
    'Psalm\\Node\\Stmt\\VirtualForeach' => $baseDir . '/src/Psalm/Node/Stmt/VirtualForeach.php',
    'Psalm\\Node\\Stmt\\VirtualFunction' => $baseDir . '/src/Psalm/Node/Stmt/VirtualFunction.php',
    'Psalm\\Node\\Stmt\\VirtualGlobal' => $baseDir . '/src/Psalm/Node/Stmt/VirtualGlobal.php',
    'Psalm\\Node\\Stmt\\VirtualGoto' => $baseDir . '/src/Psalm/Node/Stmt/VirtualGoto.php',
    'Psalm\\Node\\Stmt\\VirtualGroupUse' => $baseDir . '/src/Psalm/Node/Stmt/VirtualGroupUse.php',
    'Psalm\\Node\\Stmt\\VirtualHaltCompiler' => $baseDir . '/src/Psalm/Node/Stmt/VirtualHaltCompiler.php',
    'Psalm\\Node\\Stmt\\VirtualIf' => $baseDir . '/src/Psalm/Node/Stmt/VirtualIf.php',
    'Psalm\\Node\\Stmt\\VirtualInlineHTML' => $baseDir . '/src/Psalm/Node/Stmt/VirtualInlineHTML.php',
    'Psalm\\Node\\Stmt\\VirtualInterface' => $baseDir . '/src/Psalm/Node/Stmt/VirtualInterface.php',
    'Psalm\\Node\\Stmt\\VirtualLabel' => $baseDir . '/src/Psalm/Node/Stmt/VirtualLabel.php',
    'Psalm\\Node\\Stmt\\VirtualNamespace' => $baseDir . '/src/Psalm/Node/Stmt/VirtualNamespace.php',
    'Psalm\\Node\\Stmt\\VirtualNop' => $baseDir . '/src/Psalm/Node/Stmt/VirtualNop.php',
    'Psalm\\Node\\Stmt\\VirtualProperty' => $baseDir . '/src/Psalm/Node/Stmt/VirtualProperty.php',
    'Psalm\\Node\\Stmt\\VirtualPropertyProperty' => $baseDir . '/src/Psalm/Node/Stmt/VirtualPropertyProperty.php',
    'Psalm\\Node\\Stmt\\VirtualReturn' => $baseDir . '/src/Psalm/Node/Stmt/VirtualReturn.php',
    'Psalm\\Node\\Stmt\\VirtualStatic' => $baseDir . '/src/Psalm/Node/Stmt/VirtualStatic.php',
    'Psalm\\Node\\Stmt\\VirtualStaticVar' => $baseDir . '/src/Psalm/Node/Stmt/VirtualStaticVar.php',
    'Psalm\\Node\\Stmt\\VirtualSwitch' => $baseDir . '/src/Psalm/Node/Stmt/VirtualSwitch.php',
    'Psalm\\Node\\Stmt\\VirtualThrow' => $baseDir . '/src/Psalm/Node/Stmt/VirtualThrow.php',
    'Psalm\\Node\\Stmt\\VirtualTrait' => $baseDir . '/src/Psalm/Node/Stmt/VirtualTrait.php',
    'Psalm\\Node\\Stmt\\VirtualTraitUse' => $baseDir . '/src/Psalm/Node/Stmt/VirtualTraitUse.php',
    'Psalm\\Node\\Stmt\\VirtualTryCatch' => $baseDir . '/src/Psalm/Node/Stmt/VirtualTryCatch.php',
    'Psalm\\Node\\Stmt\\VirtualUnset' => $baseDir . '/src/Psalm/Node/Stmt/VirtualUnset.php',
    'Psalm\\Node\\Stmt\\VirtualUse' => $baseDir . '/src/Psalm/Node/Stmt/VirtualUse.php',
    'Psalm\\Node\\Stmt\\VirtualUseUse' => $baseDir . '/src/Psalm/Node/Stmt/VirtualUseUse.php',
    'Psalm\\Node\\Stmt\\VirtualWhile' => $baseDir . '/src/Psalm/Node/Stmt/VirtualWhile.php',
    'Psalm\\Node\\VirtualArg' => $baseDir . '/src/Psalm/Node/VirtualArg.php',
    'Psalm\\Node\\VirtualAttribute' => $baseDir . '/src/Psalm/Node/VirtualAttribute.php',
    'Psalm\\Node\\VirtualAttributeGroup' => $baseDir . '/src/Psalm/Node/VirtualAttributeGroup.php',
    'Psalm\\Node\\VirtualConst' => $baseDir . '/src/Psalm/Node/VirtualConst.php',
    'Psalm\\Node\\VirtualIdentifier' => $baseDir . '/src/Psalm/Node/VirtualIdentifier.php',
    'Psalm\\Node\\VirtualMatchArm' => $baseDir . '/src/Psalm/Node/VirtualMatchArm.php',
    'Psalm\\Node\\VirtualName' => $baseDir . '/src/Psalm/Node/VirtualName.php',
    'Psalm\\Node\\VirtualNode' => $baseDir . '/src/Psalm/Node/VirtualNode.php',
    'Psalm\\Node\\VirtualNullableType' => $baseDir . '/src/Psalm/Node/VirtualNullableType.php',
    'Psalm\\Node\\VirtualParam' => $baseDir . '/src/Psalm/Node/VirtualParam.php',
    'Psalm\\Node\\VirtualUnionType' => $baseDir . '/src/Psalm/Node/VirtualUnionType.php',
    'Psalm\\Node\\VirtualVarLikeIdentifier' => $baseDir . '/src/Psalm/Node/VirtualVarLikeIdentifier.php',
    'Psalm\\PluginFileExtensionsSocket' => $baseDir . '/src/Psalm/PluginFileExtensionsSocket.php',
    'Psalm\\PluginRegistrationSocket' => $baseDir . '/src/Psalm/PluginRegistrationSocket.php',
    'Psalm\\Plugin\\ArgTypeInferer' => $baseDir . '/src/Psalm/Plugin/ArgTypeInferer.php',
    'Psalm\\Plugin\\DynamicFunctionStorage' => $baseDir . '/src/Psalm/Plugin/DynamicFunctionStorage.php',
    'Psalm\\Plugin\\DynamicTemplateProvider' => $baseDir . '/src/Psalm/Plugin/DynamicTemplateProvider.php',
    'Psalm\\Plugin\\EventHandler\\AddTaintsInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AddTaintsInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterClassLikeAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterClassLikeAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterClassLikeExistenceCheckInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterClassLikeExistenceCheckInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterClassLikeVisitInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterClassLikeVisitInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterCodebasePopulatedInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterCodebasePopulatedInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterEveryFunctionCallAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterEveryFunctionCallAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterExpressionAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterExpressionAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterFileAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterFileAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterFunctionCallAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterFunctionCallAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterFunctionLikeAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterFunctionLikeAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterMethodCallAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterMethodCallAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\AfterStatementAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/AfterStatementAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\BeforeAddIssueInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/BeforeAddIssueInterface.php',
    'Psalm\\Plugin\\EventHandler\\BeforeFileAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/BeforeFileAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\BeforeStatementAnalysisInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/BeforeStatementAnalysisInterface.php',
    'Psalm\\Plugin\\EventHandler\\DynamicFunctionStorageProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/DynamicFunctionStorageProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AddRemoveTaintsEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AddRemoveTaintsEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterClassLikeAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterClassLikeAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterClassLikeExistenceCheckEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterClassLikeExistenceCheckEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterClassLikeVisitEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterClassLikeVisitEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterCodebasePopulatedEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterCodebasePopulatedEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterEveryFunctionCallAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterEveryFunctionCallAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterExpressionAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterExpressionAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterFileAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterFileAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterFunctionCallAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterFunctionCallAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterFunctionLikeAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterFunctionLikeAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterMethodCallAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterMethodCallAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\AfterStatementAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/AfterStatementAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\BeforeAddIssueEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/BeforeAddIssueEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\BeforeFileAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/BeforeFileAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\BeforeStatementAnalysisEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/BeforeStatementAnalysisEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\DynamicFunctionStorageProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/DynamicFunctionStorageProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\FunctionExistenceProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/FunctionExistenceProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\FunctionParamsProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/FunctionParamsProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\FunctionReturnTypeProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/FunctionReturnTypeProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\MethodExistenceProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/MethodExistenceProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\MethodParamsProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/MethodParamsProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\MethodReturnTypeProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/MethodReturnTypeProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\MethodVisibilityProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/MethodVisibilityProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\PropertyExistenceProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/PropertyExistenceProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\PropertyTypeProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/PropertyTypeProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\PropertyVisibilityProviderEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/PropertyVisibilityProviderEvent.php',
    'Psalm\\Plugin\\EventHandler\\Event\\StringInterpreterEvent' => $baseDir . '/src/Psalm/Plugin/EventHandler/Event/StringInterpreterEvent.php',
    'Psalm\\Plugin\\EventHandler\\FunctionExistenceProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/FunctionExistenceProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\FunctionParamsProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/FunctionParamsProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\FunctionReturnTypeProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/FunctionReturnTypeProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\MethodExistenceProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/MethodExistenceProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\MethodParamsProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/MethodParamsProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\MethodReturnTypeProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/MethodReturnTypeProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\MethodVisibilityProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/MethodVisibilityProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\PropertyExistenceProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/PropertyExistenceProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\PropertyTypeProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/PropertyTypeProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\PropertyVisibilityProviderInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/PropertyVisibilityProviderInterface.php',
    'Psalm\\Plugin\\EventHandler\\RemoveTaintsInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/RemoveTaintsInterface.php',
    'Psalm\\Plugin\\EventHandler\\StringInterpreterInterface' => $baseDir . '/src/Psalm/Plugin/EventHandler/StringInterpreterInterface.php',
    'Psalm\\Plugin\\FileExtensionsInterface' => $baseDir . '/src/Psalm/Plugin/FileExtensionsInterface.php',
    'Psalm\\Plugin\\PluginEntryPointInterface' => $baseDir . '/src/Psalm/Plugin/PluginEntryPointInterface.php',
    'Psalm\\Plugin\\PluginFileExtensionsInterface' => $baseDir . '/src/Psalm/Plugin/PluginFileExtensionsInterface.php',
    'Psalm\\Plugin\\PluginInterface' => $baseDir . '/src/Psalm/Plugin/PluginInterface.php',
    'Psalm\\Plugin\\RegistrationInterface' => $baseDir . '/src/Psalm/Plugin/RegistrationInterface.php',
    'Psalm\\Plugin\\Shepherd' => $baseDir . '/src/Psalm/Plugin/Shepherd.php',
    'Psalm\\Progress\\DebugProgress' => $baseDir . '/src/Psalm/Progress/DebugProgress.php',
    'Psalm\\Progress\\DefaultProgress' => $baseDir . '/src/Psalm/Progress/DefaultProgress.php',
    'Psalm\\Progress\\LongProgress' => $baseDir . '/src/Psalm/Progress/LongProgress.php',
    'Psalm\\Progress\\Progress' => $baseDir . '/src/Psalm/Progress/Progress.php',
    'Psalm\\Progress\\VoidProgress' => $baseDir . '/src/Psalm/Progress/VoidProgress.php',
    'Psalm\\Report' => $baseDir . '/src/Psalm/Report.php',
    'Psalm\\Report\\ByIssueLevelAndTypeReport' => $baseDir . '/src/Psalm/Report/ByIssueLevelAndTypeReport.php',
    'Psalm\\Report\\CheckstyleReport' => $baseDir . '/src/Psalm/Report/CheckstyleReport.php',
    'Psalm\\Report\\CodeClimateReport' => $baseDir . '/src/Psalm/Report/CodeClimateReport.php',
    'Psalm\\Report\\CompactReport' => $baseDir . '/src/Psalm/Report/CompactReport.php',
    'Psalm\\Report\\ConsoleReport' => $baseDir . '/src/Psalm/Report/ConsoleReport.php',
    'Psalm\\Report\\CountReport' => $baseDir . '/src/Psalm/Report/CountReport.php',
    'Psalm\\Report\\EmacsReport' => $baseDir . '/src/Psalm/Report/EmacsReport.php',
    'Psalm\\Report\\GithubActionsReport' => $baseDir . '/src/Psalm/Report/GithubActionsReport.php',
    'Psalm\\Report\\JsonReport' => $baseDir . '/src/Psalm/Report/JsonReport.php',
    'Psalm\\Report\\JsonSummaryReport' => $baseDir . '/src/Psalm/Report/JsonSummaryReport.php',
    'Psalm\\Report\\JunitReport' => $baseDir . '/src/Psalm/Report/JunitReport.php',
    'Psalm\\Report\\PhpStormReport' => $baseDir . '/src/Psalm/Report/PhpStormReport.php',
    'Psalm\\Report\\PylintReport' => $baseDir . '/src/Psalm/Report/PylintReport.php',
    'Psalm\\Report\\ReportOptions' => $baseDir . '/src/Psalm/Report/ReportOptions.php',
    'Psalm\\Report\\SarifReport' => $baseDir . '/src/Psalm/Report/SarifReport.php',
    'Psalm\\Report\\SonarqubeReport' => $baseDir . '/src/Psalm/Report/SonarqubeReport.php',
    'Psalm\\Report\\TextReport' => $baseDir . '/src/Psalm/Report/TextReport.php',
    'Psalm\\Report\\XmlReport' => $baseDir . '/src/Psalm/Report/XmlReport.php',
    'Psalm\\SourceControl\\Git\\CommitInfo' => $baseDir . '/src/Psalm/SourceControl/Git/CommitInfo.php',
    'Psalm\\SourceControl\\Git\\GitInfo' => $baseDir . '/src/Psalm/SourceControl/Git/GitInfo.php',
    'Psalm\\SourceControl\\Git\\RemoteInfo' => $baseDir . '/src/Psalm/SourceControl/Git/RemoteInfo.php',
    'Psalm\\SourceControl\\SourceControlInfo' => $baseDir . '/src/Psalm/SourceControl/SourceControlInfo.php',
    'Psalm\\StatementsSource' => $baseDir . '/src/Psalm/StatementsSource.php',
    'Psalm\\Storage\\Assertion' => $baseDir . '/src/Psalm/Storage/Assertion.php',
    'Psalm\\Storage\\Assertion\\Any' => $baseDir . '/src/Psalm/Storage/Assertion/Any.php',
    'Psalm\\Storage\\Assertion\\ArrayKeyDoesNotExist' => $baseDir . '/src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.php',
    'Psalm\\Storage\\Assertion\\ArrayKeyExists' => $baseDir . '/src/Psalm/Storage/Assertion/ArrayKeyExists.php',
    'Psalm\\Storage\\Assertion\\DoesNotHaveAtLeastCount' => $baseDir . '/src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php',
    'Psalm\\Storage\\Assertion\\DoesNotHaveExactCount' => $baseDir . '/src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php',
    'Psalm\\Storage\\Assertion\\DoesNotHaveMethod' => $baseDir . '/src/Psalm/Storage/Assertion/DoesNotHaveMethod.php',
    'Psalm\\Storage\\Assertion\\Empty_' => $baseDir . '/src/Psalm/Storage/Assertion/Empty_.php',
    'Psalm\\Storage\\Assertion\\Falsy' => $baseDir . '/src/Psalm/Storage/Assertion/Falsy.php',
    'Psalm\\Storage\\Assertion\\HasArrayKey' => $baseDir . '/src/Psalm/Storage/Assertion/HasArrayKey.php',
    'Psalm\\Storage\\Assertion\\HasAtLeastCount' => $baseDir . '/src/Psalm/Storage/Assertion/HasAtLeastCount.php',
    'Psalm\\Storage\\Assertion\\HasExactCount' => $baseDir . '/src/Psalm/Storage/Assertion/HasExactCount.php',
    'Psalm\\Storage\\Assertion\\HasIntOrStringArrayAccess' => $baseDir . '/src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php',
    'Psalm\\Storage\\Assertion\\HasMethod' => $baseDir . '/src/Psalm/Storage/Assertion/HasMethod.php',
    'Psalm\\Storage\\Assertion\\HasStringArrayAccess' => $baseDir . '/src/Psalm/Storage/Assertion/HasStringArrayAccess.php',
    'Psalm\\Storage\\Assertion\\InArray' => $baseDir . '/src/Psalm/Storage/Assertion/InArray.php',
    'Psalm\\Storage\\Assertion\\IsAClass' => $baseDir . '/src/Psalm/Storage/Assertion/IsAClass.php',
    'Psalm\\Storage\\Assertion\\IsClassEqual' => $baseDir . '/src/Psalm/Storage/Assertion/IsClassEqual.php',
    'Psalm\\Storage\\Assertion\\IsClassNotEqual' => $baseDir . '/src/Psalm/Storage/Assertion/IsClassNotEqual.php',
    'Psalm\\Storage\\Assertion\\IsCountable' => $baseDir . '/src/Psalm/Storage/Assertion/IsCountable.php',
    'Psalm\\Storage\\Assertion\\IsEqualIsset' => $baseDir . '/src/Psalm/Storage/Assertion/IsEqualIsset.php',
    'Psalm\\Storage\\Assertion\\IsGreaterThan' => $baseDir . '/src/Psalm/Storage/Assertion/IsGreaterThan.php',
    'Psalm\\Storage\\Assertion\\IsGreaterThanOrEqualTo' => $baseDir . '/src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.php',
    'Psalm\\Storage\\Assertion\\IsIdentical' => $baseDir . '/src/Psalm/Storage/Assertion/IsIdentical.php',
    'Psalm\\Storage\\Assertion\\IsIsset' => $baseDir . '/src/Psalm/Storage/Assertion/IsIsset.php',
    'Psalm\\Storage\\Assertion\\IsLessThan' => $baseDir . '/src/Psalm/Storage/Assertion/IsLessThan.php',
    'Psalm\\Storage\\Assertion\\IsLessThanOrEqualTo' => $baseDir . '/src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.php',
    'Psalm\\Storage\\Assertion\\IsLooselyEqual' => $baseDir . '/src/Psalm/Storage/Assertion/IsLooselyEqual.php',
    'Psalm\\Storage\\Assertion\\IsNotAClass' => $baseDir . '/src/Psalm/Storage/Assertion/IsNotAClass.php',
    'Psalm\\Storage\\Assertion\\IsNotCountable' => $baseDir . '/src/Psalm/Storage/Assertion/IsNotCountable.php',
    'Psalm\\Storage\\Assertion\\IsNotIdentical' => $baseDir . '/src/Psalm/Storage/Assertion/IsNotIdentical.php',
    'Psalm\\Storage\\Assertion\\IsNotIsset' => $baseDir . '/src/Psalm/Storage/Assertion/IsNotIsset.php',
    'Psalm\\Storage\\Assertion\\IsNotLooselyEqual' => $baseDir . '/src/Psalm/Storage/Assertion/IsNotLooselyEqual.php',
    'Psalm\\Storage\\Assertion\\IsNotType' => $baseDir . '/src/Psalm/Storage/Assertion/IsNotType.php',
    'Psalm\\Storage\\Assertion\\IsType' => $baseDir . '/src/Psalm/Storage/Assertion/IsType.php',
    'Psalm\\Storage\\Assertion\\NestedAssertions' => $baseDir . '/src/Psalm/Storage/Assertion/NestedAssertions.php',
    'Psalm\\Storage\\Assertion\\NonEmpty' => $baseDir . '/src/Psalm/Storage/Assertion/NonEmpty.php',
    'Psalm\\Storage\\Assertion\\NonEmptyCountable' => $baseDir . '/src/Psalm/Storage/Assertion/NonEmptyCountable.php',
    'Psalm\\Storage\\Assertion\\NotInArray' => $baseDir . '/src/Psalm/Storage/Assertion/NotInArray.php',
    'Psalm\\Storage\\Assertion\\NotNestedAssertions' => $baseDir . '/src/Psalm/Storage/Assertion/NotNestedAssertions.php',
    'Psalm\\Storage\\Assertion\\NotNonEmptyCountable' => $baseDir . '/src/Psalm/Storage/Assertion/NotNonEmptyCountable.php',
    'Psalm\\Storage\\Assertion\\Truthy' => $baseDir . '/src/Psalm/Storage/Assertion/Truthy.php',
    'Psalm\\Storage\\AttributeArg' => $baseDir . '/src/Psalm/Storage/AttributeArg.php',
    'Psalm\\Storage\\AttributeStorage' => $baseDir . '/src/Psalm/Storage/AttributeStorage.php',
    'Psalm\\Storage\\ClassConstantStorage' => $baseDir . '/src/Psalm/Storage/ClassConstantStorage.php',
    'Psalm\\Storage\\ClassLikeStorage' => $baseDir . '/src/Psalm/Storage/ClassLikeStorage.php',
    'Psalm\\Storage\\CustomMetadataTrait' => $baseDir . '/src/Psalm/Storage/CustomMetadataTrait.php',
    'Psalm\\Storage\\EnumCaseStorage' => $baseDir . '/src/Psalm/Storage/EnumCaseStorage.php',
    'Psalm\\Storage\\FileStorage' => $baseDir . '/src/Psalm/Storage/FileStorage.php',
    'Psalm\\Storage\\FunctionLikeParameter' => $baseDir . '/src/Psalm/Storage/FunctionLikeParameter.php',
    'Psalm\\Storage\\FunctionLikeStorage' => $baseDir . '/src/Psalm/Storage/FunctionLikeStorage.php',
    'Psalm\\Storage\\FunctionStorage' => $baseDir . '/src/Psalm/Storage/FunctionStorage.php',
    'Psalm\\Storage\\HasAttributesInterface' => $baseDir . '/src/Psalm/Storage/HasAttributesInterface.php',
    'Psalm\\Storage\\ImmutableNonCloneableTrait' => $baseDir . '/src/Psalm/Storage/ImmutableNonCloneableTrait.php',
    'Psalm\\Storage\\MethodStorage' => $baseDir . '/src/Psalm/Storage/MethodStorage.php',
    'Psalm\\Storage\\Possibilities' => $baseDir . '/src/Psalm/Storage/Possibilities.php',
    'Psalm\\Storage\\PropertyStorage' => $baseDir . '/src/Psalm/Storage/PropertyStorage.php',
    'Psalm\\Type' => $baseDir . '/src/Psalm/Type.php',
    'Psalm\\Type\\Atomic' => $baseDir . '/src/Psalm/Type/Atomic.php',
    'Psalm\\Type\\Atomic\\CallableTrait' => $baseDir . '/src/Psalm/Type/Atomic/CallableTrait.php',
    'Psalm\\Type\\Atomic\\DependentType' => $baseDir . '/src/Psalm/Type/Atomic/DependentType.php',
    'Psalm\\Type\\Atomic\\GenericTrait' => $baseDir . '/src/Psalm/Type/Atomic/GenericTrait.php',
    'Psalm\\Type\\Atomic\\HasIntersectionTrait' => $baseDir . '/src/Psalm/Type/Atomic/HasIntersectionTrait.php',
    'Psalm\\Type\\Atomic\\Scalar' => $baseDir . '/src/Psalm/Type/Atomic/Scalar.php',
    'Psalm\\Type\\Atomic\\TAnonymousClassInstance' => $baseDir . '/src/Psalm/Type/Atomic/TAnonymousClassInstance.php',
    'Psalm\\Type\\Atomic\\TArray' => $baseDir . '/src/Psalm/Type/Atomic/TArray.php',
    'Psalm\\Type\\Atomic\\TArrayKey' => $baseDir . '/src/Psalm/Type/Atomic/TArrayKey.php',
    'Psalm\\Type\\Atomic\\TBool' => $baseDir . '/src/Psalm/Type/Atomic/TBool.php',
    'Psalm\\Type\\Atomic\\TCallable' => $baseDir . '/src/Psalm/Type/Atomic/TCallable.php',
    'Psalm\\Type\\Atomic\\TCallableArray' => $baseDir . '/src/Psalm/Type/Atomic/TCallableArray.php',
    'Psalm\\Type\\Atomic\\TCallableKeyedArray' => $baseDir . '/src/Psalm/Type/Atomic/TCallableKeyedArray.php',
    'Psalm\\Type\\Atomic\\TCallableList' => $baseDir . '/src/Psalm/Type/Atomic/TCallableList.php',
    'Psalm\\Type\\Atomic\\TCallableObject' => $baseDir . '/src/Psalm/Type/Atomic/TCallableObject.php',
    'Psalm\\Type\\Atomic\\TCallableString' => $baseDir . '/src/Psalm/Type/Atomic/TCallableString.php',
    'Psalm\\Type\\Atomic\\TClassConstant' => $baseDir . '/src/Psalm/Type/Atomic/TClassConstant.php',
    'Psalm\\Type\\Atomic\\TClassString' => $baseDir . '/src/Psalm/Type/Atomic/TClassString.php',
    'Psalm\\Type\\Atomic\\TClassStringMap' => $baseDir . '/src/Psalm/Type/Atomic/TClassStringMap.php',
    'Psalm\\Type\\Atomic\\TClosedResource' => $baseDir . '/src/Psalm/Type/Atomic/TClosedResource.php',
    'Psalm\\Type\\Atomic\\TClosure' => $baseDir . '/src/Psalm/Type/Atomic/TClosure.php',
    'Psalm\\Type\\Atomic\\TConditional' => $baseDir . '/src/Psalm/Type/Atomic/TConditional.php',
    'Psalm\\Type\\Atomic\\TDependentGetClass' => $baseDir . '/src/Psalm/Type/Atomic/TDependentGetClass.php',
    'Psalm\\Type\\Atomic\\TDependentGetDebugType' => $baseDir . '/src/Psalm/Type/Atomic/TDependentGetDebugType.php',
    'Psalm\\Type\\Atomic\\TDependentGetType' => $baseDir . '/src/Psalm/Type/Atomic/TDependentGetType.php',
    'Psalm\\Type\\Atomic\\TDependentListKey' => $baseDir . '/src/Psalm/Type/Atomic/TDependentListKey.php',
    'Psalm\\Type\\Atomic\\TEmptyMixed' => $baseDir . '/src/Psalm/Type/Atomic/TEmptyMixed.php',
    'Psalm\\Type\\Atomic\\TEmptyNumeric' => $baseDir . '/src/Psalm/Type/Atomic/TEmptyNumeric.php',
    'Psalm\\Type\\Atomic\\TEmptyScalar' => $baseDir . '/src/Psalm/Type/Atomic/TEmptyScalar.php',
    'Psalm\\Type\\Atomic\\TEnumCase' => $baseDir . '/src/Psalm/Type/Atomic/TEnumCase.php',
    'Psalm\\Type\\Atomic\\TFalse' => $baseDir . '/src/Psalm/Type/Atomic/TFalse.php',
    'Psalm\\Type\\Atomic\\TFloat' => $baseDir . '/src/Psalm/Type/Atomic/TFloat.php',
    'Psalm\\Type\\Atomic\\TGenericObject' => $baseDir . '/src/Psalm/Type/Atomic/TGenericObject.php',
    'Psalm\\Type\\Atomic\\TInt' => $baseDir . '/src/Psalm/Type/Atomic/TInt.php',
    'Psalm\\Type\\Atomic\\TIntMask' => $baseDir . '/src/Psalm/Type/Atomic/TIntMask.php',
    'Psalm\\Type\\Atomic\\TIntMaskOf' => $baseDir . '/src/Psalm/Type/Atomic/TIntMaskOf.php',
    'Psalm\\Type\\Atomic\\TIntRange' => $baseDir . '/src/Psalm/Type/Atomic/TIntRange.php',
    'Psalm\\Type\\Atomic\\TIterable' => $baseDir . '/src/Psalm/Type/Atomic/TIterable.php',
    'Psalm\\Type\\Atomic\\TKeyOf' => $baseDir . '/src/Psalm/Type/Atomic/TKeyOf.php',
    'Psalm\\Type\\Atomic\\TKeyedArray' => $baseDir . '/src/Psalm/Type/Atomic/TKeyedArray.php',
    'Psalm\\Type\\Atomic\\TList' => $baseDir . '/src/Psalm/Type/Atomic/TList.php',
    'Psalm\\Type\\Atomic\\TLiteralClassString' => $baseDir . '/src/Psalm/Type/Atomic/TLiteralClassString.php',
    'Psalm\\Type\\Atomic\\TLiteralFloat' => $baseDir . '/src/Psalm/Type/Atomic/TLiteralFloat.php',
    'Psalm\\Type\\Atomic\\TLiteralInt' => $baseDir . '/src/Psalm/Type/Atomic/TLiteralInt.php',
    'Psalm\\Type\\Atomic\\TLiteralString' => $baseDir . '/src/Psalm/Type/Atomic/TLiteralString.php',
    'Psalm\\Type\\Atomic\\TLowercaseString' => $baseDir . '/src/Psalm/Type/Atomic/TLowercaseString.php',
    'Psalm\\Type\\Atomic\\TMixed' => $baseDir . '/src/Psalm/Type/Atomic/TMixed.php',
    'Psalm\\Type\\Atomic\\TNamedObject' => $baseDir . '/src/Psalm/Type/Atomic/TNamedObject.php',
    'Psalm\\Type\\Atomic\\TNever' => $baseDir . '/src/Psalm/Type/Atomic/TNever.php',
    'Psalm\\Type\\Atomic\\TNonEmptyArray' => $baseDir . '/src/Psalm/Type/Atomic/TNonEmptyArray.php',
    'Psalm\\Type\\Atomic\\TNonEmptyList' => $baseDir . '/src/Psalm/Type/Atomic/TNonEmptyList.php',
    'Psalm\\Type\\Atomic\\TNonEmptyLowercaseString' => $baseDir . '/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php',
    'Psalm\\Type\\Atomic\\TNonEmptyMixed' => $baseDir . '/src/Psalm/Type/Atomic/TNonEmptyMixed.php',
    'Psalm\\Type\\Atomic\\TNonEmptyNonspecificLiteralString' => $baseDir . '/src/Psalm/Type/Atomic/TNonEmptyNonspecificLiteralString.php',
    'Psalm\\Type\\Atomic\\TNonEmptyScalar' => $baseDir . '/src/Psalm/Type/Atomic/TNonEmptyScalar.php',
    'Psalm\\Type\\Atomic\\TNonEmptyString' => $baseDir . '/src/Psalm/Type/Atomic/TNonEmptyString.php',
    'Psalm\\Type\\Atomic\\TNonFalsyString' => $baseDir . '/src/Psalm/Type/Atomic/TNonFalsyString.php',
    'Psalm\\Type\\Atomic\\TNonspecificLiteralInt' => $baseDir . '/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php',
    'Psalm\\Type\\Atomic\\TNonspecificLiteralString' => $baseDir . '/src/Psalm/Type/Atomic/TNonspecificLiteralString.php',
    'Psalm\\Type\\Atomic\\TNull' => $baseDir . '/src/Psalm/Type/Atomic/TNull.php',
    'Psalm\\Type\\Atomic\\TNumeric' => $baseDir . '/src/Psalm/Type/Atomic/TNumeric.php',
    'Psalm\\Type\\Atomic\\TNumericString' => $baseDir . '/src/Psalm/Type/Atomic/TNumericString.php',
    'Psalm\\Type\\Atomic\\TObject' => $baseDir . '/src/Psalm/Type/Atomic/TObject.php',
    'Psalm\\Type\\Atomic\\TObjectWithProperties' => $baseDir . '/src/Psalm/Type/Atomic/TObjectWithProperties.php',
    'Psalm\\Type\\Atomic\\TPropertiesOf' => $baseDir . '/src/Psalm/Type/Atomic/TPropertiesOf.php',
    'Psalm\\Type\\Atomic\\TResource' => $baseDir . '/src/Psalm/Type/Atomic/TResource.php',
    'Psalm\\Type\\Atomic\\TScalar' => $baseDir . '/src/Psalm/Type/Atomic/TScalar.php',
    'Psalm\\Type\\Atomic\\TSingleLetter' => $baseDir . '/src/Psalm/Type/Atomic/TSingleLetter.php',
    'Psalm\\Type\\Atomic\\TString' => $baseDir . '/src/Psalm/Type/Atomic/TString.php',
    'Psalm\\Type\\Atomic\\TTemplateIndexedAccess' => $baseDir . '/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php',
    'Psalm\\Type\\Atomic\\TTemplateKeyOf' => $baseDir . '/src/Psalm/Type/Atomic/TTemplateKeyOf.php',
    'Psalm\\Type\\Atomic\\TTemplateParam' => $baseDir . '/src/Psalm/Type/Atomic/TTemplateParam.php',
    'Psalm\\Type\\Atomic\\TTemplateParamClass' => $baseDir . '/src/Psalm/Type/Atomic/TTemplateParamClass.php',
    'Psalm\\Type\\Atomic\\TTemplatePropertiesOf' => $baseDir . '/src/Psalm/Type/Atomic/TTemplatePropertiesOf.php',
    'Psalm\\Type\\Atomic\\TTemplateValueOf' => $baseDir . '/src/Psalm/Type/Atomic/TTemplateValueOf.php',
    'Psalm\\Type\\Atomic\\TTraitString' => $baseDir . '/src/Psalm/Type/Atomic/TTraitString.php',
    'Psalm\\Type\\Atomic\\TTrue' => $baseDir . '/src/Psalm/Type/Atomic/TTrue.php',
    'Psalm\\Type\\Atomic\\TTypeAlias' => $baseDir . '/src/Psalm/Type/Atomic/TTypeAlias.php',
    'Psalm\\Type\\Atomic\\TValueOf' => $baseDir . '/src/Psalm/Type/Atomic/TValueOf.php',
    'Psalm\\Type\\Atomic\\TVoid' => $baseDir . '/src/Psalm/Type/Atomic/TVoid.php',
    'Psalm\\Type\\MutableTypeVisitor' => $baseDir . '/src/Psalm/Type/MutableTypeVisitor.php',
    'Psalm\\Type\\MutableUnion' => $baseDir . '/src/Psalm/Type/MutableUnion.php',
    'Psalm\\Type\\Reconciler' => $baseDir . '/src/Psalm/Type/Reconciler.php',
    'Psalm\\Type\\TaintKind' => $baseDir . '/src/Psalm/Type/TaintKind.php',
    'Psalm\\Type\\TaintKindGroup' => $baseDir . '/src/Psalm/Type/TaintKindGroup.php',
    'Psalm\\Type\\TypeNode' => $baseDir . '/src/Psalm/Type/TypeNode.php',
    'Psalm\\Type\\TypeVisitor' => $baseDir . '/src/Psalm/Type/TypeVisitor.php',
    'Psalm\\Type\\Union' => $baseDir . '/src/Psalm/Type/Union.php',
    'Psalm\\Type\\UnionTrait' => $baseDir . '/src/Psalm/Type/UnionTrait.php',
    'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Dispatcher' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/Dispatcher.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Error' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/Error.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\ErrorCode' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/ErrorCode.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\ErrorResponse' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/ErrorResponse.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Message' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/Message.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Notification' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/Notification.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Request' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/Request.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Response' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/Response.php',
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\SuccessResponse' => $vendorDir . '/felixfbecker/advanced-json-rpc/lib/SuccessResponse.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64DecodingInputStream' => $vendorDir . '/amphp/byte-stream/lib/Base64/Base64DecodingInputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64DecodingOutputStream' => $vendorDir . '/amphp/byte-stream/lib/Base64/Base64DecodingOutputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64EncodingInputStream' => $vendorDir . '/amphp/byte-stream/lib/Base64/Base64EncodingInputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64EncodingOutputStream' => $vendorDir . '/amphp/byte-stream/lib/Base64/Base64EncodingOutputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ClosedException' => $vendorDir . '/amphp/byte-stream/lib/ClosedException.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\InMemoryStream' => $vendorDir . '/amphp/byte-stream/lib/InMemoryStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\InputStream' => $vendorDir . '/amphp/byte-stream/lib/InputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\InputStreamChain' => $vendorDir . '/amphp/byte-stream/lib/InputStreamChain.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\IteratorStream' => $vendorDir . '/amphp/byte-stream/lib/IteratorStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\LineReader' => $vendorDir . '/amphp/byte-stream/lib/LineReader.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Message' => $vendorDir . '/amphp/byte-stream/lib/Message.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\OutputBuffer' => $vendorDir . '/amphp/byte-stream/lib/OutputBuffer.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\OutputStream' => $vendorDir . '/amphp/byte-stream/lib/OutputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Payload' => $vendorDir . '/amphp/byte-stream/lib/Payload.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\PendingReadError' => $vendorDir . '/amphp/byte-stream/lib/PendingReadError.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ResourceInputStream' => $vendorDir . '/amphp/byte-stream/lib/ResourceInputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ResourceOutputStream' => $vendorDir . '/amphp/byte-stream/lib/ResourceOutputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\StreamException' => $vendorDir . '/amphp/byte-stream/lib/StreamException.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ZlibInputStream' => $vendorDir . '/amphp/byte-stream/lib/ZlibInputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ZlibOutputStream' => $vendorDir . '/amphp/byte-stream/lib/ZlibOutputStream.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\CallableMaker' => $vendorDir . '/amphp/amp/lib/CallableMaker.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\CancellationToken' => $vendorDir . '/amphp/amp/lib/CancellationToken.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\CancellationTokenSource' => $vendorDir . '/amphp/amp/lib/CancellationTokenSource.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\CancelledException' => $vendorDir . '/amphp/amp/lib/CancelledException.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\CombinedCancellationToken' => $vendorDir . '/amphp/amp/lib/CombinedCancellationToken.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Coroutine' => $vendorDir . '/amphp/amp/lib/Coroutine.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Deferred' => $vendorDir . '/amphp/amp/lib/Deferred.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Delayed' => $vendorDir . '/amphp/amp/lib/Delayed.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Emitter' => $vendorDir . '/amphp/amp/lib/Emitter.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Failure' => $vendorDir . '/amphp/amp/lib/Failure.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\Placeholder' => $vendorDir . '/amphp/amp/lib/Internal/Placeholder.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\PrivateIterator' => $vendorDir . '/amphp/amp/lib/Internal/PrivateIterator.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\PrivatePromise' => $vendorDir . '/amphp/amp/lib/Internal/PrivatePromise.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\Producer' => $vendorDir . '/amphp/amp/lib/Internal/Producer.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\ResolutionQueue' => $vendorDir . '/amphp/amp/lib/Internal/ResolutionQueue.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\InvalidYieldError' => $vendorDir . '/amphp/amp/lib/InvalidYieldError.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Iterator' => $vendorDir . '/amphp/amp/lib/Iterator.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\LazyPromise' => $vendorDir . '/amphp/amp/lib/LazyPromise.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop' => $vendorDir . '/amphp/amp/lib/Loop.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\Driver' => $vendorDir . '/amphp/amp/lib/Loop/Driver.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\DriverFactory' => $vendorDir . '/amphp/amp/lib/Loop/DriverFactory.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\EvDriver' => $vendorDir . '/amphp/amp/lib/Loop/EvDriver.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\EventDriver' => $vendorDir . '/amphp/amp/lib/Loop/EventDriver.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\Internal\\TimerQueue' => $vendorDir . '/amphp/amp/lib/Loop/Internal/TimerQueue.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\InvalidWatcherError' => $vendorDir . '/amphp/amp/lib/Loop/InvalidWatcherError.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\NativeDriver' => $vendorDir . '/amphp/amp/lib/Loop/NativeDriver.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\TracingDriver' => $vendorDir . '/amphp/amp/lib/Loop/TracingDriver.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\UnsupportedFeatureException' => $vendorDir . '/amphp/amp/lib/Loop/UnsupportedFeatureException.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\UvDriver' => $vendorDir . '/amphp/amp/lib/Loop/UvDriver.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\Watcher' => $vendorDir . '/amphp/amp/lib/Loop/Watcher.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\MultiReasonException' => $vendorDir . '/amphp/amp/lib/MultiReasonException.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\NullCancellationToken' => $vendorDir . '/amphp/amp/lib/NullCancellationToken.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Producer' => $vendorDir . '/amphp/amp/lib/Producer.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Promise' => $vendorDir . '/amphp/amp/lib/Promise.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Struct' => $vendorDir . '/amphp/amp/lib/Struct.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\Success' => $vendorDir . '/amphp/amp/lib/Success.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\TimeoutCancellationToken' => $vendorDir . '/amphp/amp/lib/TimeoutCancellationToken.php',
    '_HumbugBox1cb33d1f20f1\\Amp\\TimeoutException' => $vendorDir . '/amphp/amp/lib/TimeoutException.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchAllResult' => $vendorDir . '/composer/pcre/src/MatchAllResult.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchAllStrictGroupsResult' => $vendorDir . '/composer/pcre/src/MatchAllStrictGroupsResult.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchAllWithOffsetsResult' => $vendorDir . '/composer/pcre/src/MatchAllWithOffsetsResult.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchResult' => $vendorDir . '/composer/pcre/src/MatchResult.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchStrictGroupsResult' => $vendorDir . '/composer/pcre/src/MatchStrictGroupsResult.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchWithOffsetsResult' => $vendorDir . '/composer/pcre/src/MatchWithOffsetsResult.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\PcreException' => $vendorDir . '/composer/pcre/src/PcreException.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\Preg' => $vendorDir . '/composer/pcre/src/Preg.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\Regex' => $vendorDir . '/composer/pcre/src/Regex.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\ReplaceResult' => $vendorDir . '/composer/pcre/src/ReplaceResult.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\UnexpectedNullMatchException' => $vendorDir . '/composer/pcre/src/UnexpectedNullMatchException.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Comparator' => $vendorDir . '/composer/semver/src/Comparator.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\CompilingMatcher' => $vendorDir . '/composer/semver/src/CompilingMatcher.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\Bound' => $vendorDir . '/composer/semver/src/Constraint/Bound.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\Constraint' => $vendorDir . '/composer/semver/src/Constraint/Constraint.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\ConstraintInterface' => $vendorDir . '/composer/semver/src/Constraint/ConstraintInterface.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\MatchAllConstraint' => $vendorDir . '/composer/semver/src/Constraint/MatchAllConstraint.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\MatchNoneConstraint' => $vendorDir . '/composer/semver/src/Constraint/MatchNoneConstraint.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\MultiConstraint' => $vendorDir . '/composer/semver/src/Constraint/MultiConstraint.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Interval' => $vendorDir . '/composer/semver/src/Interval.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Intervals' => $vendorDir . '/composer/semver/src/Intervals.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Semver' => $vendorDir . '/composer/semver/src/Semver.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\VersionParser' => $vendorDir . '/composer/semver/src/VersionParser.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\PhpConfig' => $vendorDir . '/composer/xdebug-handler/src/PhpConfig.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\Process' => $vendorDir . '/composer/xdebug-handler/src/Process.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\Status' => $vendorDir . '/composer/xdebug-handler/src/Status.php',
    '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\XdebugHandler' => $vendorDir . '/composer/xdebug-handler/src/XdebugHandler.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\CpuCoreCounter' => $vendorDir . '/fidry/cpu-core-counter/src/CpuCoreCounter.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Diagnoser' => $vendorDir . '/fidry/cpu-core-counter/src/Diagnoser.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Exec\\ProcOpen' => $vendorDir . '/fidry/cpu-core-counter/src/Exec/ProcOpen.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\CpuCoreFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/CpuCoreFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\CpuInfoFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/CpuInfoFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\DummyCpuCoreFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/DummyCpuCoreFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\FinderRegistry' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/FinderRegistry.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\HwLogicalFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/HwLogicalFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\HwPhysicalFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/HwPhysicalFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\NProcFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/NProcFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\NProcessorFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/NProcessorFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\NullCpuCoreFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/NullCpuCoreFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\OnlyOnWindowsFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/OnlyOnWindowsFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\ProcOpenBasedFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/ProcOpenBasedFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\SkipOnWindowsFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/SkipOnWindowsFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\WmicLogicalFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/WmicLogicalFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\WmicPhysicalFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/WmicPhysicalFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\_NProcessorFinder' => $vendorDir . '/fidry/cpu-core-counter/src/Finder/_NProcessorFinder.php',
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\NumberOfCpuCoreNotFound' => $vendorDir . '/fidry/cpu-core-counter/src/NumberOfCpuCoreNotFound.php',
    '_HumbugBox1cb33d1f20f1\\JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CallHierarchyClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/CallHierarchyClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ChangeAnnotation' => $vendorDir . '/felixfbecker/language-server-protocol/src/ChangeAnnotation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/ClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesGeneral' => $vendorDir . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesGeneral.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesWindow' => $vendorDir . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesWindow.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesWorkspace' => $vendorDir . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesWorkspace.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesWorkspaceFileOperations' => $vendorDir . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesWorkspaceFileOperations.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientInfo' => $vendorDir . '/felixfbecker/language-server-protocol/src/ClientInfo.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeAction' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeAction.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilitiesCodeActionLiteralSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesCodeActionLiteralSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilitiesResolveSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesResolveSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionContext' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionContext.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionDisabled' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionDisabled.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionTriggerKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeActionTriggerKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeDescription' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeDescription.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLens' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeLens.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLensClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeLensClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLensOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeLensOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLensWorkspaceClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/CodeLensWorkspaceClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Command' => $vendorDir . '/felixfbecker/language-server-protocol/src/Command.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItem' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItem.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItemInsertTextModeSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemInsertTextModeSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItemResolveSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemResolveSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItemTagSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemTagSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionList' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionList.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionContext' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionContext.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItem' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionItem.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItemKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionItemKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItemLabelDetails' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionItemLabelDetails.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItemTag' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionItemTag.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionList' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionList.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionTriggerKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/CompletionTriggerKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ContentChangeEvent' => $vendorDir . '/felixfbecker/language-server-protocol/src/ContentChangeEvent.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DeclarationClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DeclarationClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DefinitionClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DefinitionClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DependencyReference' => $vendorDir . '/felixfbecker/language-server-protocol/src/DependencyReference.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Diagnostic' => $vendorDir . '/felixfbecker/language-server-protocol/src/Diagnostic.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DiagnosticRelatedInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/DiagnosticRelatedInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DiagnosticSeverity' => $vendorDir . '/felixfbecker/language-server-protocol/src/DiagnosticSeverity.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DiagnosticTag' => $vendorDir . '/felixfbecker/language-server-protocol/src/DiagnosticTag.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DidChangeConfigurationClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DidChangeConfigurationClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DidChangeWatchedFilesClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DidChangeWatchedFilesClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentColorClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentColorClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentFormattingClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentFormattingClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentHighlight' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentHighlight.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentHighlightClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentHighlightClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentHighlightKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentHighlightKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentLinkClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentLinkClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentOnTypeFormattingClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentOnTypeFormattingClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentOnTypeFormattingOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentOnTypeFormattingOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentRangeFormattingClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentRangeFormattingClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentSymbolClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentSymbolClientCapabilitiesSymbolKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilitiesSymbolKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentSymbolClientCapabilitiesTagSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilitiesTagSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ErrorCode' => $vendorDir . '/felixfbecker/language-server-protocol/src/ErrorCode.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ExecuteCommandClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/ExecuteCommandClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ExecuteCommandOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/ExecuteCommandOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FailureHandlingKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/FailureHandlingKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FileChangeType' => $vendorDir . '/felixfbecker/language-server-protocol/src/FileChangeType.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FileEvent' => $vendorDir . '/felixfbecker/language-server-protocol/src/FileEvent.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FoldingRangeClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/FoldingRangeClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FormattingOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/FormattingOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Hover' => $vendorDir . '/felixfbecker/language-server-protocol/src/Hover.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\HoverClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/HoverClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ImplementationClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/ImplementationClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InitializeResult' => $vendorDir . '/felixfbecker/language-server-protocol/src/InitializeResult.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InitializeResultServerInfo' => $vendorDir . '/felixfbecker/language-server-protocol/src/InitializeResultServerInfo.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InsertTextFormat' => $vendorDir . '/felixfbecker/language-server-protocol/src/InsertTextFormat.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InsertTextMode' => $vendorDir . '/felixfbecker/language-server-protocol/src/InsertTextMode.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\LinkedEditingRangeClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/LinkedEditingRangeClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Location' => $vendorDir . '/felixfbecker/language-server-protocol/src/Location.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\LogMessage' => $vendorDir . '/felixfbecker/language-server-protocol/src/LogMessage.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\LogTrace' => $vendorDir . '/felixfbecker/language-server-protocol/src/LogTrace.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkdownClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/MarkdownClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkedString' => $vendorDir . '/felixfbecker/language-server-protocol/src/MarkedString.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkupContent' => $vendorDir . '/felixfbecker/language-server-protocol/src/MarkupContent.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkupKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/MarkupKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MessageActionItem' => $vendorDir . '/felixfbecker/language-server-protocol/src/MessageActionItem.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MessageType' => $vendorDir . '/felixfbecker/language-server-protocol/src/MessageType.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MonikerClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/MonikerClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PackageDescriptor' => $vendorDir . '/felixfbecker/language-server-protocol/src/PackageDescriptor.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ParameterInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/ParameterInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Position' => $vendorDir . '/felixfbecker/language-server-protocol/src/Position.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PrepareSupportDefaultBehavior' => $vendorDir . '/felixfbecker/language-server-protocol/src/PrepareSupportDefaultBehavior.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PublishDiagnosticsClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/PublishDiagnosticsClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PublishDiagnosticsClientCapabilitiesTagSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/PublishDiagnosticsClientCapabilitiesTagSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Range' => $vendorDir . '/felixfbecker/language-server-protocol/src/Range.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ReferenceClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/ReferenceClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ReferenceContext' => $vendorDir . '/felixfbecker/language-server-protocol/src/ReferenceContext.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ReferenceInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/ReferenceInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\RegularExpressionsClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/RegularExpressionsClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\RenameClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/RenameClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ResourceOperationKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/ResourceOperationKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SaveOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/SaveOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SelectionRangeClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/SelectionRangeClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SemanticTokensClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/SemanticTokensClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SemanticTokensClientCapabilitiesRequests' => $vendorDir . '/felixfbecker/language-server-protocol/src/SemanticTokensClientCapabilitiesRequests.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SemanticTokensWorkspaceClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/SemanticTokensWorkspaceClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ServerCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/ServerCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ShowDocumentClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/ShowDocumentClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ShowMessageRequestClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/ShowMessageRequestClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ShowMessageRequestClientCapabilitiesMessageActionItem' => $vendorDir . '/felixfbecker/language-server-protocol/src/ShowMessageRequestClientCapabilitiesMessageActionItem.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelp' => $vendorDir . '/felixfbecker/language-server-protocol/src/SignatureHelp.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpClientCapabilitiesSignatureInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilitiesSignatureInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpClientCapabilitiesSignatureInformationParameterInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilitiesSignatureInformationParameterInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/SignatureHelpOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/SignatureInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolDescriptor' => $vendorDir . '/felixfbecker/language-server-protocol/src/SymbolDescriptor.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/SymbolInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/SymbolKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolLocationInformation' => $vendorDir . '/felixfbecker/language-server-protocol/src/SymbolLocationInformation.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolTag' => $vendorDir . '/felixfbecker/language-server-protocol/src/SymbolTag.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextDocumentClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentContentChangeEvent' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextDocumentContentChangeEvent.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentIdentifier' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextDocumentIdentifier.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentItem' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextDocumentItem.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentSyncClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextDocumentSyncClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentSyncKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextDocumentSyncKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentSyncOptions' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextDocumentSyncOptions.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextEdit' => $vendorDir . '/felixfbecker/language-server-protocol/src/TextEdit.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TokenFormat' => $vendorDir . '/felixfbecker/language-server-protocol/src/TokenFormat.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TypeDefinitionClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/TypeDefinitionClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\VersionedTextDocumentIdentifier' => $vendorDir . '/felixfbecker/language-server-protocol/src/VersionedTextDocumentIdentifier.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceEdit' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceEdit.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceEditClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceEditClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceEditClientCapabilitiesChangeAnnotationSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceEditClientCapabilitiesChangeAnnotationSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceFolder' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceFolder.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilities' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilities.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilitiesResolveSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesResolveSupport.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilitiesSymbolKind' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesSymbolKind.php',
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilitiesTagSupport' => $vendorDir . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesTagSupport.php',
    '_HumbugBox1cb33d1f20f1\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
    '_HumbugBox1cb33d1f20f1\\PackageVersions\\FallbackVersions' => $vendorDir . '/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php',
    '_HumbugBox1cb33d1f20f1\\PackageVersions\\Installer' => $vendorDir . '/composer/package-versions-deprecated/src/PackageVersions/Installer.php',
    '_HumbugBox1cb33d1f20f1\\PackageVersions\\Versions' => $vendorDir . '/composer/package-versions-deprecated/src/PackageVersions/Versions.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\BuilderFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\BuilderHelpers' => $vendorDir . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\ClassConst' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Class_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Class_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Declaration' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Declaration.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\EnumCase' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Enum_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Enum_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\FunctionLike' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Function_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Function_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Interface_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Interface_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Method' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Method.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Namespace_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Param' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Param.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Property' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Property.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\TraitUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\TraitUseAdaptation' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Trait_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Trait_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Use_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Builder/Use_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Comment' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Comment.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Comment\\Doc' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Comment/Doc.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\ConstExprEvaluationException' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ConstExprEvaluationException.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\ConstExprEvaluator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Error' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Error.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\ErrorHandler' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ErrorHandler.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\ErrorHandler\\Collecting' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\ErrorHandler\\Throwing' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\DiffElem' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Internal/DiffElem.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\Differ' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Internal/Differ.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\PrintableNewAnonClassNode' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\TokenStream' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\JsonDecoder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/JsonDecoder.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\Emulative' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\CoaleseEqualTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/CoaleseEqualTokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\FlexibleDocStringEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FlexibleDocStringEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\FnTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NameContext' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NameContext.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeAbstract.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeDumper' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeDumper.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeFinder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeFinder.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeTraverser' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeTraverser.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeTraverserInterface' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitorAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\CloningVisitor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\FindingVisitor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\NameResolver' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Arg' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Arg.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Attribute' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Attribute.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\AttributeGroup' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\ComplexType' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/ComplexType.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Const_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Const_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ArrayDimFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ArrayItem' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Array_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ArrowFunction' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Assign' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Coalesce' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Coalesce.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Concat' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Div' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Minus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Mod' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Mul' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Plus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Pow' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignRef' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Concat' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Div' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Equal' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Greater' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Identical' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Minus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Mod' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Mul' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Plus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Pow' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BitwiseNot' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BooleanNot' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\CallLike' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Array_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Bool_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Double' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Int_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Object_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\String_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Unset_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ClassConstFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Clone_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Closure' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ClosureUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ConstFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Empty_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Error' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ErrorSuppress' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Eval_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Exit_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\FuncCall' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Include_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Instanceof_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Isset_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\List_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Match_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\MethodCall' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\New_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\NullsafeMethodCall' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\NullsafePropertyFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PostDec' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PostInc' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PreDec' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PreInc' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Print_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PropertyFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ShellExec' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\StaticCall' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\StaticPropertyFetch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Ternary' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Throw_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\UnaryMinus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\UnaryPlus' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Variable' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\YieldFrom' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Yield_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\FunctionLike' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Identifier' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Identifier.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\IntersectionType' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/IntersectionType.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\MatchArm' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/MatchArm.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Name' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Name.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Name\\FullyQualified' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Name\\Relative' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\NullableType' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/NullableType.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Param' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Param.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\DNumber' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\Encapsed' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\EncapsedStringPart' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\LNumber' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\File' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Function_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Line' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Method' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\String_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Break_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Case_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Catch_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ClassConst' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ClassLike' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ClassMethod' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Class_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Const_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Continue_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\DeclareDeclare' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Declare_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Do_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Echo_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ElseIf_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Else_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\EnumCase' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Enum_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Expression' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Finally_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\For_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Foreach_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Function_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Global_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Goto_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\GroupUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\HaltCompiler' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\If_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\InlineHTML' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Interface_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Label' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Namespace_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Nop' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Property' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\PropertyProperty' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Return_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\StaticVar' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Static_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Switch_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Throw_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Trait_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TryCatch' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Unset_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\UseUse' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Use_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\While_' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\UnionType' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/UnionType.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\VarLikeIdentifier' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\VariadicPlaceholder' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Node/VariadicPlaceholder.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\ParserAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ParserAbstract.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\ParserFactory' => $vendorDir . '/nikic/php-parser/lib/PhpParser/ParserFactory.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Multiple' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Multiple.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Php5' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Php5.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Php7' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Php7.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Tokens' => $vendorDir . '/nikic/php-parser/lib/PhpParser/Parser/Tokens.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\PrettyPrinterAbstract' => $vendorDir . '/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php',
    '_HumbugBox1cb33d1f20f1\\PhpParser\\PrettyPrinter\\Standard' => $vendorDir . '/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerAwareInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareInterface.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerAwareTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerAwareTrait.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php',
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\ConfigurationException' => $vendorDir . '/sebastian/diff/src/Exception/ConfigurationException.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php',
    '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php',
    '_HumbugBox1cb33d1f20f1\\Spatie\\ArrayToXml\\ArrayToXml' => $vendorDir . '/spatie/array-to-xml/src/ArrayToXml.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Application' => $vendorDir . '/symfony/console/Application.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Attribute\\AsCommand' => $vendorDir . '/symfony/console/Attribute/AsCommand.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CI\\GithubActionReporter' => $vendorDir . '/symfony/console/CI/GithubActionReporter.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Color' => $vendorDir . '/symfony/console/Color.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => $vendorDir . '/symfony/console/CommandLoader/CommandLoaderInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/ContainerCommandLoader.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => $vendorDir . '/symfony/console/CommandLoader/FactoryCommandLoader.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\Command' => $vendorDir . '/symfony/console/Command/Command.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\CompleteCommand' => $vendorDir . '/symfony/console/Command/CompleteCommand.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\DumpCompletionCommand' => $vendorDir . '/symfony/console/Command/DumpCompletionCommand.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\HelpCommand' => $vendorDir . '/symfony/console/Command/HelpCommand.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\LazyCommand' => $vendorDir . '/symfony/console/Command/LazyCommand.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\ListCommand' => $vendorDir . '/symfony/console/Command/ListCommand.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\LockableTrait' => $vendorDir . '/symfony/console/Command/LockableTrait.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\SignalableCommandInterface' => $vendorDir . '/symfony/console/Command/SignalableCommandInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\CompletionInput' => $vendorDir . '/symfony/console/Completion/CompletionInput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\CompletionSuggestions' => $vendorDir . '/symfony/console/Completion/CompletionSuggestions.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\Output\\BashCompletionOutput' => $vendorDir . '/symfony/console/Completion/Output/BashCompletionOutput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\Output\\CompletionOutputInterface' => $vendorDir . '/symfony/console/Completion/Output/CompletionOutputInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\Suggestion' => $vendorDir . '/symfony/console/Completion/Suggestion.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\ConsoleEvents' => $vendorDir . '/symfony/console/ConsoleEvents.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Cursor' => $vendorDir . '/symfony/console/Cursor.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => $vendorDir . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => $vendorDir . '/symfony/console/Descriptor/ApplicationDescription.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\Descriptor' => $vendorDir . '/symfony/console/Descriptor/Descriptor.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => $vendorDir . '/symfony/console/Descriptor/DescriptorInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => $vendorDir . '/symfony/console/Descriptor/JsonDescriptor.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => $vendorDir . '/symfony/console/Descriptor/MarkdownDescriptor.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => $vendorDir . '/symfony/console/Descriptor/TextDescriptor.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => $vendorDir . '/symfony/console/Descriptor/XmlDescriptor.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\EventListener\\ErrorListener' => $vendorDir . '/symfony/console/EventListener/ErrorListener.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => $vendorDir . '/symfony/console/Event/ConsoleCommandEvent.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => $vendorDir . '/symfony/console/Event/ConsoleErrorEvent.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleEvent' => $vendorDir . '/symfony/console/Event/ConsoleEvent.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleSignalEvent' => $vendorDir . '/symfony/console/Event/ConsoleSignalEvent.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => $vendorDir . '/symfony/console/Event/ConsoleTerminateEvent.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => $vendorDir . '/symfony/console/Exception/CommandNotFoundException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/console/Exception/ExceptionInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/console/Exception/InvalidArgumentException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\InvalidOptionException' => $vendorDir . '/symfony/console/Exception/InvalidOptionException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\LogicException' => $vendorDir . '/symfony/console/Exception/LogicException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\MissingInputException' => $vendorDir . '/symfony/console/Exception/MissingInputException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => $vendorDir . '/symfony/console/Exception/NamespaceNotFoundException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\RuntimeException' => $vendorDir . '/symfony/console/Exception/RuntimeException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatter' => $vendorDir . '/symfony/console/Formatter/NullOutputFormatter.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/NullOutputFormatterStyle.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatter' => $vendorDir . '/symfony/console/Formatter/OutputFormatter.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyle.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => $vendorDir . '/symfony/console/Formatter/OutputFormatterStyleStack.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => $vendorDir . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => $vendorDir . '/symfony/console/Helper/DebugFormatterHelper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\DescriptorHelper' => $vendorDir . '/symfony/console/Helper/DescriptorHelper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\Dumper' => $vendorDir . '/symfony/console/Helper/Dumper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\FormatterHelper' => $vendorDir . '/symfony/console/Helper/FormatterHelper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\Helper' => $vendorDir . '/symfony/console/Helper/Helper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\HelperInterface' => $vendorDir . '/symfony/console/Helper/HelperInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\HelperSet' => $vendorDir . '/symfony/console/Helper/HelperSet.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\InputAwareHelper' => $vendorDir . '/symfony/console/Helper/InputAwareHelper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\ProcessHelper' => $vendorDir . '/symfony/console/Helper/ProcessHelper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\ProgressBar' => $vendorDir . '/symfony/console/Helper/ProgressBar.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\ProgressIndicator' => $vendorDir . '/symfony/console/Helper/ProgressIndicator.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\QuestionHelper' => $vendorDir . '/symfony/console/Helper/QuestionHelper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => $vendorDir . '/symfony/console/Helper/SymfonyQuestionHelper.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\Table' => $vendorDir . '/symfony/console/Helper/Table.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableCell' => $vendorDir . '/symfony/console/Helper/TableCell.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableCellStyle' => $vendorDir . '/symfony/console/Helper/TableCellStyle.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableRows' => $vendorDir . '/symfony/console/Helper/TableRows.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputArgument' => $vendorDir . '/symfony/console/Input/InputArgument.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputAwareInterface' => $vendorDir . '/symfony/console/Input/InputAwareInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputDefinition' => $vendorDir . '/symfony/console/Input/InputDefinition.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputInterface' => $vendorDir . '/symfony/console/Input/InputInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputOption' => $vendorDir . '/symfony/console/Input/InputOption.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\StreamableInputInterface' => $vendorDir . '/symfony/console/Input/StreamableInputInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\StringInput' => $vendorDir . '/symfony/console/Input/StringInput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Logger\\ConsoleLogger' => $vendorDir . '/symfony/console/Logger/ConsoleLogger.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\BufferedOutput' => $vendorDir . '/symfony/console/Output/BufferedOutput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\ConsoleOutput' => $vendorDir . '/symfony/console/Output/ConsoleOutput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => $vendorDir . '/symfony/console/Output/ConsoleOutputInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => $vendorDir . '/symfony/console/Output/ConsoleSectionOutput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\NullOutput' => $vendorDir . '/symfony/console/Output/NullOutput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\Output' => $vendorDir . '/symfony/console/Output/Output.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\OutputInterface' => $vendorDir . '/symfony/console/Output/OutputInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\StreamOutput' => $vendorDir . '/symfony/console/Output/StreamOutput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\TrimmedBufferOutput' => $vendorDir . '/symfony/console/Output/TrimmedBufferOutput.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Question\\ChoiceQuestion' => $vendorDir . '/symfony/console/Question/ChoiceQuestion.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => $vendorDir . '/symfony/console/Question/ConfirmationQuestion.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Question\\Question' => $vendorDir . '/symfony/console/Question/Question.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry' => $vendorDir . '/symfony/console/SignalRegistry/SignalRegistry.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\SingleCommandApplication' => $vendorDir . '/symfony/console/SingleCommandApplication.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Style\\OutputStyle' => $vendorDir . '/symfony/console/Style/OutputStyle.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Style\\StyleInterface' => $vendorDir . '/symfony/console/Style/StyleInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Style\\SymfonyStyle' => $vendorDir . '/symfony/console/Style/SymfonyStyle.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Terminal' => $vendorDir . '/symfony/console/Terminal.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\ApplicationTester' => $vendorDir . '/symfony/console/Tester/ApplicationTester.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\CommandCompletionTester' => $vendorDir . '/symfony/console/Tester/CommandCompletionTester.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\CommandTester' => $vendorDir . '/symfony/console/Tester/CommandTester.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\Constraint\\CommandIsSuccessful' => $vendorDir . '/symfony/console/Tester/Constraint/CommandIsSuccessful.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\TesterTrait' => $vendorDir . '/symfony/console/Tester/TesterTrait.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/ExceptionInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => $vendorDir . '/symfony/filesystem/Exception/FileNotFoundException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\IOException' => $vendorDir . '/symfony/filesystem/Exception/IOException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\IOExceptionInterface' => $vendorDir . '/symfony/filesystem/Exception/IOExceptionInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/filesystem/Exception/InvalidArgumentException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\RuntimeException' => $vendorDir . '/symfony/filesystem/Exception/RuntimeException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Filesystem' => $vendorDir . '/symfony/filesystem/Filesystem.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Path' => $vendorDir . '/symfony/filesystem/Path.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\AbstractString' => $vendorDir . '/symfony/string/AbstractString.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\AbstractUnicodeString' => $vendorDir . '/symfony/string/AbstractUnicodeString.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\ByteString' => $vendorDir . '/symfony/string/ByteString.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\CodePointString' => $vendorDir . '/symfony/string/CodePointString.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/string/Exception/ExceptionInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Exception\\InvalidArgumentException' => $vendorDir . '/symfony/string/Exception/InvalidArgumentException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Exception\\RuntimeException' => $vendorDir . '/symfony/string/Exception/RuntimeException.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Inflector\\EnglishInflector' => $vendorDir . '/symfony/string/Inflector/EnglishInflector.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Inflector\\FrenchInflector' => $vendorDir . '/symfony/string/Inflector/FrenchInflector.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Inflector\\InflectorInterface' => $vendorDir . '/symfony/string/Inflector/InflectorInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\LazyString' => $vendorDir . '/symfony/string/LazyString.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Slugger\\AsciiSlugger' => $vendorDir . '/symfony/string/Slugger/AsciiSlugger.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Slugger\\SluggerInterface' => $vendorDir . '/symfony/string/Slugger/SluggerInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\UnicodeString' => $vendorDir . '/symfony/string/UnicodeString.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\Attribute\\Required' => $vendorDir . '/symfony/service-contracts/Attribute/Required.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => $vendorDir . '/symfony/service-contracts/Attribute/SubscribedService.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ResetInterface' => $vendorDir . '/symfony/service-contracts/ResetInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceLocatorTrait' => $vendorDir . '/symfony/service-contracts/ServiceLocatorTrait.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceProviderInterface' => $vendorDir . '/symfony/service-contracts/ServiceProviderInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberInterface.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => $vendorDir . '/symfony/service-contracts/ServiceSubscriberTrait.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Ctype\\Ctype' => $vendorDir . '/symfony/polyfill-ctype/Ctype.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Grapheme\\Grapheme' => $vendorDir . '/symfony/polyfill-intl-grapheme/Grapheme.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Normalizer.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Mbstring\\Mbstring' => $vendorDir . '/symfony/polyfill-mbstring/Mbstring.php',
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php73\\Php73' => $vendorDir . '/symfony/polyfill-php73/Php73.php',
    '_HumbugBox1cb33d1f20f1\\UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
    '_HumbugBox1cb33d1f20f1\\ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
    '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\Assert' => $vendorDir . '/webmozart/assert/src/Assert.php',
    '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\InvalidArgumentException' => $vendorDir . '/webmozart/assert/src/InvalidArgumentException.php',
    '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\Mixin' => $vendorDir . '/webmozart/assert/src/Mixin.php',
    '_HumbugBox1cb33d1f20f1\\XdgBaseDir\\Xdg' => $vendorDir . '/dnoegel/php-xdg-base-dir/src/Xdg.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlockFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlockFactory.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlockFactoryInterface' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Description' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Description.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\ExampleFinder' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Serializer' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tag' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\TagFactory' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Example' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Property' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Reference' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\See' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\TagWithType' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version' => $vendorDir . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Element' => $vendorDir . '/phpdocumentor/reflection-common/src/Element.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Exception\\PcreException' => $vendorDir . '/phpdocumentor/reflection-docblock/src/Exception/PcreException.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\File' => $vendorDir . '/phpdocumentor/reflection-common/src/File.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Fqsen' => $vendorDir . '/phpdocumentor/reflection-common/src/Fqsen.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\FqsenResolver' => $vendorDir . '/phpdocumentor/type-resolver/src/FqsenResolver.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Location' => $vendorDir . '/phpdocumentor/reflection-common/src/Location.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Project' => $vendorDir . '/phpdocumentor/reflection-common/src/Project.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\ProjectFactory' => $vendorDir . '/phpdocumentor/reflection-common/src/ProjectFactory.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoType' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoType.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\CallableString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/CallableString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\False_' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/False_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\HtmlEscapedString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\IntegerRange' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/IntegerRange.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\List_' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/List_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\LiteralString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\LowercaseString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NegativeInteger' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyLowercaseString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NumericString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/NumericString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\Numeric_' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/Numeric_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\PositiveInteger' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/PositiveInteger.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\TraitString' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\True_' => $vendorDir . '/phpdocumentor/type-resolver/src/PseudoTypes/True_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Type' => $vendorDir . '/phpdocumentor/type-resolver/src/Type.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\TypeResolver' => $vendorDir . '/phpdocumentor/type-resolver/src/TypeResolver.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\AbstractList' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/AbstractList.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\AggregatedType' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/AggregatedType.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\ArrayKey' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/ArrayKey.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Array_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Array_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Boolean' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Boolean.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Callable_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Callable_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\ClassString' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/ClassString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Collection' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Collection.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Compound' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Compound.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Context' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Context.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\ContextFactory' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/ContextFactory.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Expression' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Expression.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Float_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Float_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Integer' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Integer.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\InterfaceString' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/InterfaceString.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Intersection' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Intersection.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Iterable_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Iterable_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Mixed_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Mixed_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Never_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Never_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Null_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Null_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Nullable' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Nullable.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Object_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Object_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Parent_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Parent_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Resource_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Resource_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Scalar' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Scalar.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Self_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Self_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Static_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Static_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\String_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/String_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\This' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/This.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Void_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Void_.php',
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Utils' => $vendorDir . '/phpdocumentor/reflection-docblock/src/Utils.php',
);
<?php

namespace _HumbugBox1cb33d1f20f1;

return array('root' => array('name' => 'vimeo/psalm', 'pretty_version' => '5.6.0', 'version' => '5.6.0.0', 'reference' => 'e784128902dfe01d489c4123d69918a9f3c1eac5', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \true), 'versions' => array('amphp/amp' => array('pretty_version' => 'v2.6.2', 'version' => '2.6.2.0', 'reference' => '9d5100cebffa729aaffecd3ad25dc5aeea4f13bb', 'type' => 'library', 'install_path' => __DIR__ . '/../amphp/amp', 'aliases' => array(), 'dev_requirement' => \false), 'amphp/byte-stream' => array('pretty_version' => 'v1.8.1', 'version' => '1.8.1.0', 'reference' => 'acbd8002b3536485c997c4e019206b3f10ca15bd', 'type' => 'library', 'install_path' => __DIR__ . '/../amphp/byte-stream', 'aliases' => array(), 'dev_requirement' => \false), 'bamarni/composer-bin-plugin' => array('pretty_version' => '1.8.2', 'version' => '1.8.2.0', 'reference' => '92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../bamarni/composer-bin-plugin', 'aliases' => array(), 'dev_requirement' => \true), 'brianium/paratest' => array('pretty_version' => 'v6.8.1', 'version' => '6.8.1.0', 'reference' => '168c1cfdf79e5b19b57cb03060fc9a6a79c5f582', 'type' => 'library', 'install_path' => __DIR__ . '/../brianium/paratest', 'aliases' => array(), 'dev_requirement' => \true), 'composer/package-versions-deprecated' => array('pretty_version' => '1.11.99.5', 'version' => '1.11.99.5', 'reference' => 'b4f54f74ef3453349c24a845d22392cd31e65f1d', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/./package-versions-deprecated', 'aliases' => array(), 'dev_requirement' => \false), 'composer/pcre' => array('pretty_version' => '3.1.0', 'version' => '3.1.0.0', 'reference' => '4bff79ddd77851fe3cdd11616ed3f92841ba5bd2', 'type' => 'library', 'install_path' => __DIR__ . '/./pcre', 'aliases' => array(), 'dev_requirement' => \false), 'composer/semver' => array('pretty_version' => '3.3.2', 'version' => '3.3.2.0', 'reference' => '3953f23262f2bff1919fc82183ad9acb13ff62c9', 'type' => 'library', 'install_path' => __DIR__ . '/./semver', 'aliases' => array(), 'dev_requirement' => \false), 'composer/xdebug-handler' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'reference' => 'ced299686f41dce890debac69273b47ffe98a40c', 'type' => 'library', 'install_path' => __DIR__ . '/./xdebug-handler', 'aliases' => array(), 'dev_requirement' => \false), 'cordoval/hamcrest-php' => array('dev_requirement' => \true, 'replaced' => array(0 => '*')), 'davedevelopment/hamcrest-php' => array('dev_requirement' => \true, 'replaced' => array(0 => '*')), 'dealerdirect/phpcodesniffer-composer-installer' => array('pretty_version' => 'v1.0.0', 'version' => '1.0.0.0', 'reference' => '4be43904336affa5c2f70744a348312336afd0da', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../dealerdirect/phpcodesniffer-composer-installer', 'aliases' => array(), 'dev_requirement' => \true), 'dg/bypass-finals' => array('pretty_version' => 'v1.4.1', 'version' => '1.4.1.0', 'reference' => '4c424c3ed359220fce044f35cdf9f48b0089b2ca', 'type' => 'library', 'install_path' => __DIR__ . '/../dg/bypass-finals', 'aliases' => array(), 'dev_requirement' => \true), 'dnoegel/php-xdg-base-dir' => array('pretty_version' => 'v0.1.1', 'version' => '0.1.1.0', 'reference' => '8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd', 'type' => 'library', 'install_path' => __DIR__ . '/../dnoegel/php-xdg-base-dir', 'aliases' => array(), 'dev_requirement' => \false), 'doctrine/instantiator' => array('pretty_version' => '1.5.0', 'version' => '1.5.0.0', 'reference' => '0a0fa9780f5d4e507415a065172d26a98d02047b', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/instantiator', 'aliases' => array(), 'dev_requirement' => \true), 'felixfbecker/advanced-json-rpc' => array('pretty_version' => 'v3.2.1', 'version' => '3.2.1.0', 'reference' => 'b5f37dbff9a8ad360ca341f3240dc1c168b45447', 'type' => 'library', 'install_path' => __DIR__ . '/../felixfbecker/advanced-json-rpc', 'aliases' => array(), 'dev_requirement' => \false), 'felixfbecker/language-server-protocol' => array('pretty_version' => 'v1.5.2', 'version' => '1.5.2.0', 'reference' => '6e82196ffd7c62f7794d778ca52b69feec9f2842', 'type' => 'library', 'install_path' => __DIR__ . '/../felixfbecker/language-server-protocol', 'aliases' => array(), 'dev_requirement' => \false), 'fidry/cpu-core-counter' => array('pretty_version' => '0.4.1', 'version' => '0.4.1.0', 'reference' => '79261cc280aded96d098e1b0e0ba0c4881b432c2', 'type' => 'library', 'install_path' => __DIR__ . '/../fidry/cpu-core-counter', 'aliases' => array(), 'dev_requirement' => \false), 'grogy/php-parallel-lint' => array('dev_requirement' => \true, 'replaced' => array(0 => '*')), 'hamcrest/hamcrest-php' => array('pretty_version' => 'v2.0.1', 'version' => '2.0.1.0', 'reference' => '8c3d0a3f6af734494ad8f6fbbee0ba92422859f3', 'type' => 'library', 'install_path' => __DIR__ . '/../hamcrest/hamcrest-php', 'aliases' => array(), 'dev_requirement' => \true), 'jakub-onderka/php-parallel-lint' => array('dev_requirement' => \true, 'replaced' => array(0 => '*')), 'jean85/pretty-package-versions' => array('pretty_version' => '2.0.5', 'version' => '2.0.5.0', 'reference' => 'ae547e455a3d8babd07b96966b17d7fd21d9c6af', 'type' => 'library', 'install_path' => __DIR__ . '/../jean85/pretty-package-versions', 'aliases' => array(), 'dev_requirement' => \true), 'kodova/hamcrest-php' => array('dev_requirement' => \true, 'replaced' => array(0 => '*')), 'mockery/mockery' => array('pretty_version' => '1.5.1', 'version' => '1.5.1.0', 'reference' => 'e92dcc83d5a51851baf5f5591d32cb2b16e3684e', 'type' => 'library', 'install_path' => __DIR__ . '/../mockery/mockery', 'aliases' => array(), 'dev_requirement' => \true), 'myclabs/deep-copy' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => '14daed4296fae74d9e3201d2c4925d1acb7aa614', 'type' => 'library', 'install_path' => __DIR__ . '/../myclabs/deep-copy', 'aliases' => array(), 'dev_requirement' => \true), 'netresearch/jsonmapper' => array('pretty_version' => 'v4.1.0', 'version' => '4.1.0.0', 'reference' => 'cfa81ea1d35294d64adb9c68aa4cb9e92400e53f', 'type' => 'library', 'install_path' => __DIR__ . '/../netresearch/jsonmapper', 'aliases' => array(), 'dev_requirement' => \false), 'nikic/php-parser' => array('pretty_version' => 'v4.15.3', 'version' => '4.15.3.0', 'reference' => '570e980a201d8ed0236b0a62ddf2c9cbb2034039', 'type' => 'library', 'install_path' => __DIR__ . '/../nikic/php-parser', 'aliases' => array(), 'dev_requirement' => \false), 'nunomaduro/mock-final-classes' => array('pretty_version' => 'v1.1.0', 'version' => '1.1.0.0', 'reference' => '5d113210c085ac13a8e1225f8b6f390c797a98f0', 'type' => 'library', 'install_path' => __DIR__ . '/../nunomaduro/mock-final-classes', 'aliases' => array(), 'dev_requirement' => \true), 'ocramius/package-versions' => array('dev_requirement' => \false, 'replaced' => array(0 => '1.11.99')), 'phar-io/manifest' => array('pretty_version' => '2.0.3', 'version' => '2.0.3.0', 'reference' => '97803eca37d319dfa7826cc2437fc020857acb53', 'type' => 'library', 'install_path' => __DIR__ . '/../phar-io/manifest', 'aliases' => array(), 'dev_requirement' => \true), 'phar-io/version' => array('pretty_version' => '3.2.1', 'version' => '3.2.1.0', 'reference' => '4f7fd7836c6f332bb2933569e566a0d6c4cbed74', 'type' => 'library', 'install_path' => __DIR__ . '/../phar-io/version', 'aliases' => array(), 'dev_requirement' => \true), 'php-parallel-lint/php-parallel-lint' => array('pretty_version' => 'v1.3.2', 'version' => '1.3.2.0', 'reference' => '6483c9832e71973ed29cf71bd6b3f4fde438a9de', 'type' => 'library', 'install_path' => __DIR__ . '/../php-parallel-lint/php-parallel-lint', 'aliases' => array(), 'dev_requirement' => \true), 'phpdocumentor/reflection-common' => array('pretty_version' => '2.2.0', 'version' => '2.2.0.0', 'reference' => '1d01c49d4ed62f25aa84a747ad35d5a16924662b', 'type' => 'library', 'install_path' => __DIR__ . '/../phpdocumentor/reflection-common', 'aliases' => array(), 'dev_requirement' => \false), 'phpdocumentor/reflection-docblock' => array('pretty_version' => '5.3.0', 'version' => '5.3.0.0', 'reference' => '622548b623e81ca6d78b721c5e029f4ce664f170', 'type' => 'library', 'install_path' => __DIR__ . '/../phpdocumentor/reflection-docblock', 'aliases' => array(), 'dev_requirement' => \false), 'phpdocumentor/type-resolver' => array('pretty_version' => '1.6.2', 'version' => '1.6.2.0', 'reference' => '48f445a408c131e38cab1c235aa6d2bb7a0bb20d', 'type' => 'library', 'install_path' => __DIR__ . '/../phpdocumentor/type-resolver', 'aliases' => array(), 'dev_requirement' => \false), 'phpstan/phpdoc-parser' => array('pretty_version' => '1.15.3', 'version' => '1.15.3.0', 'reference' => '61800f71a5526081d1b5633766aa88341f1ade76', 'type' => 'library', 'install_path' => __DIR__ . '/../phpstan/phpdoc-parser', 'aliases' => array(), 'dev_requirement' => \true), 'phpunit/php-code-coverage' => array('pretty_version' => '9.2.23', 'version' => '9.2.23.0', 'reference' => '9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/php-code-coverage', 'aliases' => array(), 'dev_requirement' => \true), 'phpunit/php-file-iterator' => array('pretty_version' => '3.0.6', 'version' => '3.0.6.0', 'reference' => 'cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/php-file-iterator', 'aliases' => array(), 'dev_requirement' => \true), 'phpunit/php-invoker' => array('pretty_version' => '3.1.1', 'version' => '3.1.1.0', 'reference' => '5a10147d0aaf65b58940a0b72f71c9ac0423cc67', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/php-invoker', 'aliases' => array(), 'dev_requirement' => \true), 'phpunit/php-text-template' => array('pretty_version' => '2.0.4', 'version' => '2.0.4.0', 'reference' => '5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/php-text-template', 'aliases' => array(), 'dev_requirement' => \true), 'phpunit/php-timer' => array('pretty_version' => '5.0.3', 'version' => '5.0.3.0', 'reference' => '5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/php-timer', 'aliases' => array(), 'dev_requirement' => \true), 'phpunit/phpunit' => array('pretty_version' => '9.5.28', 'version' => '9.5.28.0', 'reference' => '954ca3113a03bf780d22f07bf055d883ee04b65e', 'type' => 'library', 'install_path' => __DIR__ . '/../phpunit/phpunit', 'aliases' => array(), 'dev_requirement' => \true), 'psalm/plugin-mockery' => array('pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '876247d15f91df08240d00dac69c5135b6689283', 'type' => 'psalm-plugin', 'install_path' => __DIR__ . '/../psalm/plugin-mockery', 'aliases' => array(), 'dev_requirement' => \true), 'psalm/plugin-phpunit' => array('pretty_version' => '0.18.4', 'version' => '0.18.4.0', 'reference' => 'e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc', 'type' => 'psalm-plugin', 'install_path' => __DIR__ . '/../psalm/plugin-phpunit', 'aliases' => array(), 'dev_requirement' => \true), 'psalm/psalm' => array('dev_requirement' => \false, 'provided' => array(0 => '5.6.0')), 'psr/container' => array('pretty_version' => '1.1.2', 'version' => '1.1.2.0', 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log' => array('pretty_version' => '1.1.4', 'version' => '1.1.4.0', 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0|2.0')), 'sebastian/cli-parser' => array('pretty_version' => '1.0.1', 'version' => '1.0.1.0', 'reference' => '442e7c7e687e42adc03470c7b668bc4b2402c0b2', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/cli-parser', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/code-unit' => array('pretty_version' => '1.0.8', 'version' => '1.0.8.0', 'reference' => '1fc9f64c0927627ef78ba436c9b17d967e68e120', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/code-unit', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/code-unit-reverse-lookup' => array('pretty_version' => '2.0.3', 'version' => '2.0.3.0', 'reference' => 'ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/code-unit-reverse-lookup', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/comparator' => array('pretty_version' => '4.0.8', 'version' => '4.0.8.0', 'reference' => 'fa0f136dd2334583309d32b62544682ee972b51a', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/comparator', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/complexity' => array('pretty_version' => '2.0.2', 'version' => '2.0.2.0', 'reference' => '739b35e53379900cc9ac327b2147867b8b6efd88', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/complexity', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/diff' => array('pretty_version' => '4.0.4', 'version' => '4.0.4.0', 'reference' => '3461e3fccc7cfdfc2720be910d3bd73c69be590d', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/diff', 'aliases' => array(), 'dev_requirement' => \false), 'sebastian/environment' => array('pretty_version' => '5.1.4', 'version' => '5.1.4.0', 'reference' => '1b5dff7bb151a4db11d49d90e5408e4e938270f7', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/environment', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/exporter' => array('pretty_version' => '4.0.5', 'version' => '4.0.5.0', 'reference' => 'ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/exporter', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/global-state' => array('pretty_version' => '5.0.5', 'version' => '5.0.5.0', 'reference' => '0ca8db5a5fc9c8646244e629625ac486fa286bf2', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/global-state', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/lines-of-code' => array('pretty_version' => '1.0.3', 'version' => '1.0.3.0', 'reference' => 'c1c2e997aa3146983ed888ad08b15470a2e22ecc', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/lines-of-code', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/object-enumerator' => array('pretty_version' => '4.0.4', 'version' => '4.0.4.0', 'reference' => '5c9eeac41b290a3712d88851518825ad78f45c71', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/object-enumerator', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/object-reflector' => array('pretty_version' => '2.0.4', 'version' => '2.0.4.0', 'reference' => 'b4f479ebdbf63ac605d183ece17d8d7fe49c15c7', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/object-reflector', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/recursion-context' => array('pretty_version' => '4.0.4', 'version' => '4.0.4.0', 'reference' => 'cd9d8cf3c5804de4341c283ed787f099f5506172', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/recursion-context', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/resource-operations' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'reference' => '0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/resource-operations', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/type' => array('pretty_version' => '3.2.0', 'version' => '3.2.0.0', 'reference' => 'fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/type', 'aliases' => array(), 'dev_requirement' => \true), 'sebastian/version' => array('pretty_version' => '3.0.2', 'version' => '3.0.2.0', 'reference' => 'c6c1022351a901512170118436c764e473f6de8c', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/version', 'aliases' => array(), 'dev_requirement' => \true), 'slevomat/coding-standard' => array('pretty_version' => '8.8.0', 'version' => '8.8.0.0', 'reference' => '59e25146a4ef0a7b194c5bc55b32dd414345db89', 'type' => 'phpcodesniffer-standard', 'install_path' => __DIR__ . '/../slevomat/coding-standard', 'aliases' => array(), 'dev_requirement' => \true), 'spatie/array-to-xml' => array('pretty_version' => '2.17.1', 'version' => '2.17.1.0', 'reference' => '5cbec9c6ab17e320c58a259f0cebe88bde4a7c46', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/array-to-xml', 'aliases' => array(), 'dev_requirement' => \false), 'squizlabs/php_codesniffer' => array('pretty_version' => '3.7.1', 'version' => '3.7.1.0', 'reference' => '1359e176e9307e906dc3d890bcc9603ff6d90619', 'type' => 'library', 'install_path' => __DIR__ . '/../squizlabs/php_codesniffer', 'aliases' => array(), 'dev_requirement' => \true), 'symfony/console' => array('pretty_version' => 'v5.4.17', 'version' => '5.4.17.0', 'reference' => '58422fdcb0e715ed05b385f70d3e8b5ed4bbd45f', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/deprecation-contracts' => array('pretty_version' => 'v2.5.2', 'version' => '2.5.2.0', 'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/filesystem' => array('pretty_version' => 'v5.4.13', 'version' => '5.4.13.0', 'reference' => 'ac09569844a9109a5966b9438fc29113ce77cf51', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-ctype' => array('pretty_version' => 'v1.27.0', 'version' => '1.27.0.0', 'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-intl-grapheme' => array('pretty_version' => 'v1.27.0', 'version' => '1.27.0.0', 'reference' => '511a08c03c1960e08a883f4cffcacd219b758354', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-intl-normalizer' => array('pretty_version' => 'v1.27.0', 'version' => '1.27.0.0', 'reference' => '19bd1e4fcd5b91116f14d8533c57831ed00571b6', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-mbstring' => array('pretty_version' => 'v1.27.0', 'version' => '1.27.0.0', 'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-php73' => array('pretty_version' => 'v1.27.0', 'version' => '1.27.0.0', 'reference' => '9e8ecb5f92152187c4799efd3c96b78ccab18ff9', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php73', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-php80' => array('pretty_version' => 'v1.27.0', 'version' => '1.27.0.0', 'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-php80', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/process' => array('pretty_version' => 'v5.4.11', 'version' => '5.4.11.0', 'reference' => '6e75fe6874cbc7e4773d049616ab450eff537bf1', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'dev_requirement' => \true), 'symfony/service-contracts' => array('pretty_version' => 'v2.5.2', 'version' => '2.5.2.0', 'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/string' => array('pretty_version' => 'v5.4.17', 'version' => '5.4.17.0', 'reference' => '55733a8664b8853b003e70251c58bc8cb2d82a6b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/string', 'aliases' => array(), 'dev_requirement' => \false), 'theseer/tokenizer' => array('pretty_version' => '1.2.1', 'version' => '1.2.1.0', 'reference' => '34a41e998c2183e22995f158c581e7b5e755ab9e', 'type' => 'library', 'install_path' => __DIR__ . '/../theseer/tokenizer', 'aliases' => array(), 'dev_requirement' => \true), 'vimeo/psalm' => array('pretty_version' => '5.6.0', 'version' => '5.6.0.0', 'reference' => 'e784128902dfe01d489c4123d69918a9f3c1eac5', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'webmozart/assert' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', 'type' => 'library', 'install_path' => __DIR__ . '/../webmozart/assert', 'aliases' => array(), 'dev_requirement' => \false)));
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

final class ReplaceResult
{
    /**
     * @readonly
     * @var string
     */
    public $result;
    /**
     * @readonly
     * @var 0|positive-int
     */
    public $count;
    /**
     * @readonly
     * @var bool
     */
    public $matched;
    /**
     * @param 0|positive-int $count
     */
    public function __construct(int $count, string $result)
    {
        $this->count = $count;
        $this->matched = (bool) $count;
        $this->result = $result;
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

class PcreException extends \RuntimeException
{
    /**
     * @param  string $function
     * @param  string|string[] $pattern
     * @return self
     */
    public static function fromFunction($function, $pattern)
    {
        $code = \preg_last_error();
        if (\is_array($pattern)) {
            $pattern = \implode(', ', $pattern);
        }
        return new PcreException($function . '(): failed executing "' . $pattern . '": ' . self::pcreLastErrorMessage($code), $code);
    }
    /**
     * @param  int $code
     * @return string
     */
    private static function pcreLastErrorMessage($code)
    {
        if (\function_exists('preg_last_error_msg')) {
            return \preg_last_error_msg();
        }
        // older php versions did not set the code properly in all cases
        if (\PHP_VERSION_ID < 70201 && $code === 0) {
            return 'UNDEFINED_ERROR';
        }
        $constants = \get_defined_constants(\true);
        if (!isset($constants['pcre'])) {
            return 'UNDEFINED_ERROR';
        }
        foreach ($constants['pcre'] as $const => $val) {
            if ($val === $code && \substr($const, -6) === '_ERROR') {
                return $const;
            }
        }
        return 'UNDEFINED_ERROR';
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

class UnexpectedNullMatchException extends PcreException
{
    public static function fromFunction($function, $pattern)
    {
        throw new \LogicException('fromFunction should not be called on ' . self::class . ', use ' . PcreException::class);
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

final class MatchStrictGroupsResult
{
    /**
     * An array of match group => string matched
     *
     * @readonly
     * @var array<int|string, string>
     */
    public $matches;
    /**
     * @readonly
     * @var bool
     */
    public $matched;
    /**
     * @param 0|positive-int $count
     * @param array<string> $matches
     */
    public function __construct(int $count, array $matches)
    {
        $this->matches = $matches;
        $this->matched = (bool) $count;
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

final class MatchAllWithOffsetsResult
{
    /**
     * An array of match group => list of matches, every match being a pair of string matched + offset in bytes (or -1 if no match)
     *
     * @readonly
     * @var array<int|string, list<array{string|null, int}>>
     * @phpstan-var array<int|string, list<array{string|null, int<-1, max>}>>
     */
    public $matches;
    /**
     * @readonly
     * @var 0|positive-int
     */
    public $count;
    /**
     * @readonly
     * @var bool
     */
    public $matched;
    /**
     * @param 0|positive-int $count
     * @param array<int|string, list<array{string|null, int}>> $matches
     * @phpstan-param array<int|string, list<array{string|null, int<-1, max>}>> $matches
     */
    public function __construct(int $count, array $matches)
    {
        $this->matches = $matches;
        $this->matched = (bool) $count;
        $this->count = $count;
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

final class MatchResult
{
    /**
     * An array of match group => string matched
     *
     * @readonly
     * @var array<int|string, string|null>
     */
    public $matches;
    /**
     * @readonly
     * @var bool
     */
    public $matched;
    /**
     * @param 0|positive-int $count
     * @param array<string|null> $matches
     */
    public function __construct(int $count, array $matches)
    {
        $this->matches = $matches;
        $this->matched = (bool) $count;
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

final class MatchAllStrictGroupsResult
{
    /**
     * An array of match group => list of matched strings
     *
     * @readonly
     * @var array<int|string, list<string>>
     */
    public $matches;
    /**
     * @readonly
     * @var 0|positive-int
     */
    public $count;
    /**
     * @readonly
     * @var bool
     */
    public $matched;
    /**
     * @param 0|positive-int $count
     * @param array<array<string>> $matches
     */
    public function __construct(int $count, array $matches)
    {
        $this->matches = $matches;
        $this->matched = (bool) $count;
        $this->count = $count;
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

class Regex
{
    /**
     * @param non-empty-string $pattern
     */
    public static function isMatch(string $pattern, string $subject, int $offset = 0) : bool
    {
        return (bool) Preg::match($pattern, $subject, $matches, 0, $offset);
    }
    /**
     * @param non-empty-string $pattern
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     */
    public static function match(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchResult
    {
        self::checkOffsetCapture($flags, 'matchWithOffsets');
        $count = Preg::match($pattern, $subject, $matches, $flags, $offset);
        return new MatchResult($count, $matches);
    }
    /**
     * Variant of `match()` which returns non-null matches (or throws)
     *
     * @param non-empty-string $pattern
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     * @throws UnexpectedNullMatchException
     */
    public static function matchStrictGroups(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchStrictGroupsResult
    {
        $count = Preg::matchStrictGroups($pattern, $subject, $matches, $flags, $offset);
        return new MatchStrictGroupsResult($count, $matches);
    }
    /**
     * Runs preg_match with PREG_OFFSET_CAPTURE
     *
     * @param non-empty-string $pattern
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_MATCH_OFFSET are always set, no other flags are supported
     */
    public static function matchWithOffsets(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchWithOffsetsResult
    {
        $count = Preg::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
        return new MatchWithOffsetsResult($count, $matches);
    }
    /**
     * @param non-empty-string $pattern
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     */
    public static function matchAll(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchAllResult
    {
        self::checkOffsetCapture($flags, 'matchAllWithOffsets');
        self::checkSetOrder($flags);
        $count = Preg::matchAll($pattern, $subject, $matches, $flags, $offset);
        return new MatchAllResult($count, $matches);
    }
    /**
     * Variant of `matchAll()` which returns non-null matches (or throws)
     *
     * @param non-empty-string $pattern
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     * @throws UnexpectedNullMatchException
     */
    public static function matchAllStrictGroups(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchAllStrictGroupsResult
    {
        self::checkOffsetCapture($flags, 'matchAllWithOffsets');
        self::checkSetOrder($flags);
        $count = Preg::matchAllStrictGroups($pattern, $subject, $matches, $flags, $offset);
        return new MatchAllStrictGroupsResult($count, $matches);
    }
    /**
     * Runs preg_match_all with PREG_OFFSET_CAPTURE
     *
     * @param non-empty-string $pattern
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_MATCH_OFFSET are always set, no other flags are supported
     */
    public static function matchAllWithOffsets(string $pattern, string $subject, int $flags = 0, int $offset = 0) : MatchAllWithOffsetsResult
    {
        self::checkSetOrder($flags);
        $count = Preg::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
        return new MatchAllWithOffsetsResult($count, $matches);
    }
    /**
     * @param string|string[] $pattern
     * @param string|string[] $replacement
     * @param string          $subject
     */
    public static function replace($pattern, $replacement, $subject, int $limit = -1) : ReplaceResult
    {
        $result = Preg::replace($pattern, $replacement, $subject, $limit, $count);
        return new ReplaceResult($count, $result);
    }
    /**
     * @param string|string[] $pattern
     * @param callable(array<int|string, string|null>): string $replacement
     * @param string          $subject
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
     */
    public static function replaceCallback($pattern, callable $replacement, $subject, int $limit = -1, int $flags = 0) : ReplaceResult
    {
        $result = Preg::replaceCallback($pattern, $replacement, $subject, $limit, $count, $flags);
        return new ReplaceResult($count, $result);
    }
    /**
     * Variant of `replaceCallback()` which outputs non-null matches (or throws)
     *
     * @param string $pattern
     * @param callable(array<int|string, string>): string $replacement
     * @param string          $subject
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
     */
    public static function replaceCallbackStrictGroups($pattern, callable $replacement, $subject, int $limit = -1, int $flags = 0) : ReplaceResult
    {
        $result = Preg::replaceCallbackStrictGroups($pattern, $replacement, $subject, $limit, $count, $flags);
        return new ReplaceResult($count, $result);
    }
    /**
     * @param array<string, callable(array<int|string, string|null>): string> $pattern
     * @param string $subject
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
     */
    public static function replaceCallbackArray(array $pattern, $subject, int $limit = -1, int $flags = 0) : ReplaceResult
    {
        $result = Preg::replaceCallbackArray($pattern, $subject, $limit, $count, $flags);
        return new ReplaceResult($count, $result);
    }
    private static function checkOffsetCapture(int $flags, string $useFunctionName) : void
    {
        if (($flags & \PREG_OFFSET_CAPTURE) !== 0) {
            throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use ' . $useFunctionName . '() instead');
        }
    }
    private static function checkSetOrder(int $flags) : void
    {
        if (($flags & \PREG_SET_ORDER) !== 0) {
            throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the return type');
        }
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

class Preg
{
    /** @internal */
    public const ARRAY_MSG = '$subject as an array is not supported. You can use \'foreach\' instead.';
    /** @internal */
    public const INVALID_TYPE_MSG = '$subject must be a string, %s given.';
    /**
     * @param non-empty-string   $pattern
     * @param array<string|null> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     * @return 0|1
     *
     * @param-out array<int|string, string|null> $matches
     */
    public static function match(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : int
    {
        self::checkOffsetCapture($flags, 'matchWithOffsets');
        $result = \preg_match($pattern, $subject, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset);
        if ($result === \false) {
            throw PcreException::fromFunction('preg_match', $pattern);
        }
        return $result;
    }
    /**
     * Variant of `match()` which outputs non-null matches (or throws)
     *
     * @param non-empty-string $pattern
     * @param array<string> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     * @return 0|1
     * @throws UnexpectedNullMatchException
     *
     * @param-out array<int|string, string> $matches
     */
    public static function matchStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : int
    {
        $result = self::match($pattern, $subject, $matchesInternal, $flags, $offset);
        $matches = self::enforceNonNullMatches($pattern, $matchesInternal, 'match');
        return $result;
    }
    /**
     * Runs preg_match with PREG_OFFSET_CAPTURE
     *
     * @param non-empty-string   $pattern
     * @param array<int|string, array{string|null, int}> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_OFFSET_CAPTURE are always set, no other flags are supported
     * @return 0|1
     *
     * @param-out array<int|string, array{string|null, int<-1, max>}> $matches
     */
    public static function matchWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0) : int
    {
        $result = \preg_match($pattern, $subject, $matches, $flags | \PREG_UNMATCHED_AS_NULL | \PREG_OFFSET_CAPTURE, $offset);
        if ($result === \false) {
            throw PcreException::fromFunction('preg_match', $pattern);
        }
        return $result;
    }
    /**
     * @param non-empty-string   $pattern
     * @param array<int|string, list<string|null>> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     * @return 0|positive-int
     *
     * @param-out array<int|string, list<string|null>> $matches
     */
    public static function matchAll(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : int
    {
        self::checkOffsetCapture($flags, 'matchAllWithOffsets');
        self::checkSetOrder($flags);
        $result = \preg_match_all($pattern, $subject, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset);
        if (!\is_int($result)) {
            // PHP < 8 may return null, 8+ returns int|false
            throw PcreException::fromFunction('preg_match_all', $pattern);
        }
        return $result;
    }
    /**
     * Variant of `match()` which outputs non-null matches (or throws)
     *
     * @param non-empty-string   $pattern
     * @param array<int|string, list<string|null>> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     * @return 0|positive-int
     * @throws UnexpectedNullMatchException
     *
     * @param-out array<int|string, list<string>> $matches
     */
    public static function matchAllStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : int
    {
        $result = self::matchAll($pattern, $subject, $matchesInternal, $flags, $offset);
        $matches = self::enforceNonNullMatchAll($pattern, $matchesInternal, 'matchAll');
        return $result;
    }
    /**
     * Runs preg_match_all with PREG_OFFSET_CAPTURE
     *
     * @param non-empty-string   $pattern
     * @param array<int|string, list<array{string|null, int}>> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_UNMATCHED_AS_NULL and PREG_MATCH_OFFSET are always set, no other flags are supported
     * @return 0|positive-int
     *
     * @phpstan-param array<int|string, list<array{string|null, int<-1, max>}>> $matches
     */
    public static function matchAllWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0) : int
    {
        self::checkSetOrder($flags);
        $result = \preg_match_all($pattern, $subject, $matches, $flags | \PREG_UNMATCHED_AS_NULL | \PREG_OFFSET_CAPTURE, $offset);
        if (!\is_int($result)) {
            // PHP < 8 may return null, 8+ returns int|false
            throw PcreException::fromFunction('preg_match_all', $pattern);
        }
        return $result;
    }
    /**
     * @param string|string[] $pattern
     * @param string|string[] $replacement
     * @param string $subject
     * @param int             $count Set by method
     *
     * @param-out int<0, max> $count
     */
    public static function replace($pattern, $replacement, $subject, int $limit = -1, int &$count = null) : string
    {
        if (!\is_scalar($subject)) {
            if (\is_array($subject)) {
                throw new \InvalidArgumentException(static::ARRAY_MSG);
            }
            throw new \TypeError(\sprintf(static::INVALID_TYPE_MSG, \gettype($subject)));
        }
        $result = \preg_replace($pattern, $replacement, $subject, $limit, $count);
        if ($result === null) {
            throw PcreException::fromFunction('preg_replace', $pattern);
        }
        return $result;
    }
    /**
     * @param string|string[] $pattern
     * @param callable(array<int|string, string|null>): string $replacement
     * @param string $subject
     * @param int             $count Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
     *
     * @param-out int<0, max> $count
     */
    public static function replaceCallback($pattern, callable $replacement, $subject, int $limit = -1, int &$count = null, int $flags = 0) : string
    {
        if (!\is_scalar($subject)) {
            if (\is_array($subject)) {
                throw new \InvalidArgumentException(static::ARRAY_MSG);
            }
            throw new \TypeError(\sprintf(static::INVALID_TYPE_MSG, \gettype($subject)));
        }
        $result = \preg_replace_callback($pattern, $replacement, $subject, $limit, $count, $flags | \PREG_UNMATCHED_AS_NULL);
        if ($result === null) {
            throw PcreException::fromFunction('preg_replace_callback', $pattern);
        }
        return $result;
    }
    /**
     * Variant of `replaceCallback()` which outputs non-null matches (or throws)
     *
     * @param string $pattern
     * @param callable(array<int|string, string>): string $replacement
     * @param string $subject
     * @param int $count Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
     *
     * @param-out int<0, max> $count
     */
    public static function replaceCallbackStrictGroups(string $pattern, callable $replacement, $subject, int $limit = -1, int &$count = null, int $flags = 0) : string
    {
        return self::replaceCallback($pattern, function (array $matches) use($pattern, $replacement) {
            return $replacement(self::enforceNonNullMatches($pattern, $matches, 'replaceCallback'));
        }, $subject, $limit, $count, $flags);
    }
    /**
     * @param array<string, callable(array<int|string, string|null>): string> $pattern
     * @param string $subject
     * @param int    $count Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL|PREG_OFFSET_CAPTURE> $flags PREG_OFFSET_CAPTURE is supported, PREG_UNMATCHED_AS_NULL is always set
     *
     * @param-out int<0, max> $count
     */
    public static function replaceCallbackArray(array $pattern, $subject, int $limit = -1, int &$count = null, int $flags = 0) : string
    {
        if (!\is_scalar($subject)) {
            if (\is_array($subject)) {
                throw new \InvalidArgumentException(static::ARRAY_MSG);
            }
            throw new \TypeError(\sprintf(static::INVALID_TYPE_MSG, \gettype($subject)));
        }
        $result = \preg_replace_callback_array($pattern, $subject, $limit, $count, $flags | \PREG_UNMATCHED_AS_NULL);
        if ($result === null) {
            $pattern = \array_keys($pattern);
            throw PcreException::fromFunction('preg_replace_callback_array', $pattern);
        }
        return $result;
    }
    /**
     * @param int-mask<PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_OFFSET_CAPTURE> $flags PREG_SPLIT_NO_EMPTY or PREG_SPLIT_DELIM_CAPTURE
     * @return list<string>
     */
    public static function split(string $pattern, string $subject, int $limit = -1, int $flags = 0) : array
    {
        if (($flags & \PREG_SPLIT_OFFSET_CAPTURE) !== 0) {
            throw new \InvalidArgumentException('PREG_SPLIT_OFFSET_CAPTURE is not supported as it changes the type of $matches, use splitWithOffsets() instead');
        }
        $result = \preg_split($pattern, $subject, $limit, $flags);
        if ($result === \false) {
            throw PcreException::fromFunction('preg_split', $pattern);
        }
        return $result;
    }
    /**
     * @param int-mask<PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_OFFSET_CAPTURE> $flags PREG_SPLIT_NO_EMPTY or PREG_SPLIT_DELIM_CAPTURE, PREG_SPLIT_OFFSET_CAPTURE is always set
     * @return list<array{string, int}>
     * @phpstan-return list<array{string, int<0, max>}>
     */
    public static function splitWithOffsets(string $pattern, string $subject, int $limit = -1, int $flags = 0) : array
    {
        $result = \preg_split($pattern, $subject, $limit, $flags | \PREG_SPLIT_OFFSET_CAPTURE);
        if ($result === \false) {
            throw PcreException::fromFunction('preg_split', $pattern);
        }
        return $result;
    }
    /**
     * @template T of string|\Stringable
     * @param string   $pattern
     * @param array<T> $array
     * @param int-mask<PREG_GREP_INVERT> $flags PREG_GREP_INVERT
     * @return array<T>
     */
    public static function grep(string $pattern, array $array, int $flags = 0) : array
    {
        $result = \preg_grep($pattern, $array, $flags);
        if ($result === \false) {
            throw PcreException::fromFunction('preg_grep', $pattern);
        }
        return $result;
    }
    /**
     * Variant of match() which returns a bool instead of int
     *
     * @param non-empty-string   $pattern
     * @param array<string|null> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     *
     * @param-out array<int|string, string|null> $matches
     */
    public static function isMatch(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : bool
    {
        return (bool) static::match($pattern, $subject, $matches, $flags, $offset);
    }
    /**
     * Variant of `isMatch()` which outputs non-null matches (or throws)
     *
     * @param non-empty-string $pattern
     * @param array<string> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     * @throws UnexpectedNullMatchException
     *
     * @param-out array<int|string, string> $matches
     */
    public static function isMatchStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : bool
    {
        return (bool) self::matchStrictGroups($pattern, $subject, $matches, $flags, $offset);
    }
    /**
     * Variant of matchAll() which returns a bool instead of int
     *
     * @param non-empty-string   $pattern
     * @param array<int|string, list<string|null>> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     *
     * @param-out array<int|string, list<string|null>> $matches
     */
    public static function isMatchAll(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : bool
    {
        return (bool) static::matchAll($pattern, $subject, $matches, $flags, $offset);
    }
    /**
     * Variant of `isMatchAll()` which outputs non-null matches (or throws)
     *
     * @param non-empty-string $pattern
     * @param array<int|string, list<string>> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     *
     * @param-out array<int|string, list<string>> $matches
     */
    public static function isMatchAllStrictGroups(string $pattern, string $subject, ?array &$matches = null, int $flags = 0, int $offset = 0) : bool
    {
        return (bool) self::matchAllStrictGroups($pattern, $subject, $matches, $flags, $offset);
    }
    /**
     * Variant of matchWithOffsets() which returns a bool instead of int
     *
     * Runs preg_match with PREG_OFFSET_CAPTURE
     *
     * @param non-empty-string   $pattern
     * @param array<int|string, array{string|null, int}> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     *
     * @param-out array<int|string, array{string|null, int<-1, max>}> $matches
     */
    public static function isMatchWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0) : bool
    {
        return (bool) static::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
    }
    /**
     * Variant of matchAllWithOffsets() which returns a bool instead of int
     *
     * Runs preg_match_all with PREG_OFFSET_CAPTURE
     *
     * @param non-empty-string   $pattern
     * @param array<int|string, list<array{string|null, int}>> $matches Set by method
     * @param int-mask<PREG_UNMATCHED_AS_NULL> $flags PREG_UNMATCHED_AS_NULL is always set, no other flags are supported
     *
     * @param-out array<int|string, list<array{string|null, int<-1, max>}>> $matches
     */
    public static function isMatchAllWithOffsets(string $pattern, string $subject, ?array &$matches, int $flags = 0, int $offset = 0) : bool
    {
        return (bool) static::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
    }
    private static function checkOffsetCapture(int $flags, string $useFunctionName) : void
    {
        if (($flags & \PREG_OFFSET_CAPTURE) !== 0) {
            throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the type of $matches, use ' . $useFunctionName . '() instead');
        }
    }
    private static function checkSetOrder(int $flags) : void
    {
        if (($flags & \PREG_SET_ORDER) !== 0) {
            throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the type of $matches');
        }
    }
    /**
     * @param array<int|string, string|null> $matches
     * @return array<int|string, string>
     * @throws UnexpectedNullMatchException
     */
    private static function enforceNonNullMatches(string $pattern, array $matches, string $variantMethod)
    {
        foreach ($matches as $group => $match) {
            if (null === $match) {
                throw new UnexpectedNullMatchException('Pattern "' . $pattern . '" had an unexpected unmatched group "' . $group . '", make sure the pattern always matches or use ' . $variantMethod . '() instead.');
            }
        }
        /** @var array<string> */
        return $matches;
    }
    /**
     * @param array<int|string, list<string|null>> $matches
     * @return array<int|string, list<string>>
     * @throws UnexpectedNullMatchException
     */
    private static function enforceNonNullMatchAll(string $pattern, array $matches, string $variantMethod)
    {
        foreach ($matches as $group => $groupMatches) {
            foreach ($groupMatches as $match) {
                if (null === $match) {
                    throw new UnexpectedNullMatchException('Pattern "' . $pattern . '" had an unexpected unmatched group "' . $group . '", make sure the pattern always matches or use ' . $variantMethod . '() instead.');
                }
            }
        }
        /** @var array<int|string, list<string>> */
        return $matches;
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

final class MatchAllResult
{
    /**
     * An array of match group => list of matched strings
     *
     * @readonly
     * @var array<int|string, list<string|null>>
     */
    public $matches;
    /**
     * @readonly
     * @var 0|positive-int
     */
    public $count;
    /**
     * @readonly
     * @var bool
     */
    public $matched;
    /**
     * @param 0|positive-int $count
     * @param array<int|string, array<string|null>> $matches
     */
    public function __construct(int $count, array $matches)
    {
        $this->matches = $matches;
        $this->matched = (bool) $count;
        $this->count = $count;
    }
}
<?php

/*
 * This file is part of composer/pcre.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Pcre;

final class MatchWithOffsetsResult
{
    /**
     * An array of match group => pair of string matched + offset in bytes (or -1 if no match)
     *
     * @readonly
     * @var array<int|string, array{string|null, int}>
     * @phpstan-var array<int|string, array{string|null, int<-1, max>}>
     */
    public $matches;
    /**
     * @readonly
     * @var bool
     */
    public $matched;
    /**
     * @param 0|positive-int $count
     * @param array<array{string|null, int}> $matches
     * @phpstan-param array<int|string, array{string|null, int<-1, max>}> $matches
     */
    public function __construct(int $count, array $matches)
    {
        $this->matches = $matches;
        $this->matched = (bool) $count;
    }
}
Copyright (C) 2021 Composer

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php

// autoload_static.php @generated by Composer

namespace Composer\Autoload;

class ComposerStaticInit7e022409458d7c6e0a17a3098ef276ac
{
    public static $files = array (
        '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
        'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
        '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
        '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
        '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
        'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
        'e8aa6e4b5a1db2f56ae794f1505391a8' => __DIR__ . '/..' . '/amphp/amp/lib/functions.php',
        '76cd0796156622033397994f25b0d8fc' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/functions.php',
        '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
        'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
        '6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => __DIR__ . '/..' . '/amphp/byte-stream/lib/functions.php',
    );

    public static $prefixLengthsPsr4 = array (
        '_' => 
        array (
            '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\' => 48,
            '_HumbugBox1cb33d1f20f1\\XdgBaseDir\\' => 34,
            '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\' => 40,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php80\\' => 46,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php73\\' => 46,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Mbstring\\' => 49,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Normalizer\\' => 56,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Grapheme\\' => 54,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Ctype\\' => 46,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\' => 49,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\' => 48,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\' => 52,
            '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\' => 49,
            '_HumbugBox1cb33d1f20f1\\Spatie\\ArrayToXml\\' => 41,
            '_HumbugBox1cb33d1f20f1\\Psr\\Log\\' => 31,
            '_HumbugBox1cb33d1f20f1\\Psr\\Container\\' => 37,
            '_HumbugBox1cb33d1f20f1\\PhpParser\\' => 33,
            '_HumbugBox1cb33d1f20f1\\PackageVersions\\' => 39,
            '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\' => 46,
            '_HumbugBox1cb33d1f20f1\\JsonMapper\\' => 34,
            '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\' => 44,
            '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\' => 46,
            '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\' => 39,
            '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\' => 37,
            '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\' => 38,
            '_HumbugBox1cb33d1f20f1\\Amp\\' => 27,
            '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\' => 39,
        ),
        'P' => 
        array (
            'Psalm\\' => 6,
        ),
    );

    public static $prefixDirsPsr4 = array (
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\' => 
        array (
            0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',
            1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',
            2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',
        ),
        '_HumbugBox1cb33d1f20f1\\XdgBaseDir\\' => 
        array (
            0 => __DIR__ . '/..' . '/dnoegel/php-xdg-base-dir/src',
        ),
        '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\' => 
        array (
            0 => __DIR__ . '/..' . '/webmozart/assert/src',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php80\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php73\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-php73',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Mbstring\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Normalizer\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Grapheme\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Ctype\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/service-contracts',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/string',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/filesystem',
        ),
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\' => 
        array (
            0 => __DIR__ . '/..' . '/symfony/console',
        ),
        '_HumbugBox1cb33d1f20f1\\Spatie\\ArrayToXml\\' => 
        array (
            0 => __DIR__ . '/..' . '/spatie/array-to-xml/src',
        ),
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\' => 
        array (
            0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
        ),
        '_HumbugBox1cb33d1f20f1\\Psr\\Container\\' => 
        array (
            0 => __DIR__ . '/..' . '/psr/container/src',
        ),
        '_HumbugBox1cb33d1f20f1\\PhpParser\\' => 
        array (
            0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
        ),
        '_HumbugBox1cb33d1f20f1\\PackageVersions\\' => 
        array (
            0 => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions',
        ),
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\' => 
        array (
            0 => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src',
        ),
        '_HumbugBox1cb33d1f20f1\\JsonMapper\\' => 
        array (
            0 => __DIR__ . '/..' . '/netresearch/jsonmapper/src/JsonMapper',
        ),
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\' => 
        array (
            0 => __DIR__ . '/..' . '/fidry/cpu-core-counter/src',
        ),
        '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\' => 
        array (
            0 => __DIR__ . '/..' . '/composer/xdebug-handler/src',
        ),
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\' => 
        array (
            0 => __DIR__ . '/..' . '/composer/semver/src',
        ),
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\' => 
        array (
            0 => __DIR__ . '/..' . '/composer/pcre/src',
        ),
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\' => 
        array (
            0 => __DIR__ . '/..' . '/amphp/byte-stream/lib',
        ),
        '_HumbugBox1cb33d1f20f1\\Amp\\' => 
        array (
            0 => __DIR__ . '/..' . '/amphp/amp/lib',
        ),
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\' => 
        array (
            0 => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib',
        ),
        'Psalm\\' => 
        array (
            0 => __DIR__ . '/../..' . '/src/Psalm',
        ),
    );

    public static $classMap = array (
        'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
        'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php',
        'Psalm\\Aliases' => __DIR__ . '/../..' . '/src/Psalm/Aliases.php',
        'Psalm\\CodeLocation' => __DIR__ . '/../..' . '/src/Psalm/CodeLocation.php',
        'Psalm\\CodeLocation\\DocblockTypeLocation' => __DIR__ . '/../..' . '/src/Psalm/CodeLocation/DocblockTypeLocation.php',
        'Psalm\\CodeLocation\\ParseErrorLocation' => __DIR__ . '/../..' . '/src/Psalm/CodeLocation/ParseErrorLocation.php',
        'Psalm\\CodeLocation\\Raw' => __DIR__ . '/../..' . '/src/Psalm/CodeLocation/Raw.php',
        'Psalm\\Codebase' => __DIR__ . '/../..' . '/src/Psalm/Codebase.php',
        'Psalm\\Config' => __DIR__ . '/../..' . '/src/Psalm/Config.php',
        'Psalm\\Config\\Creator' => __DIR__ . '/../..' . '/src/Psalm/Config/Creator.php',
        'Psalm\\Config\\ErrorLevelFileFilter' => __DIR__ . '/../..' . '/src/Psalm/Config/ErrorLevelFileFilter.php',
        'Psalm\\Config\\FileFilter' => __DIR__ . '/../..' . '/src/Psalm/Config/FileFilter.php',
        'Psalm\\Config\\IssueHandler' => __DIR__ . '/../..' . '/src/Psalm/Config/IssueHandler.php',
        'Psalm\\Config\\ProjectFileFilter' => __DIR__ . '/../..' . '/src/Psalm/Config/ProjectFileFilter.php',
        'Psalm\\Config\\TaintAnalysisFileFilter' => __DIR__ . '/../..' . '/src/Psalm/Config/TaintAnalysisFileFilter.php',
        'Psalm\\Context' => __DIR__ . '/../..' . '/src/Psalm/Context.php',
        'Psalm\\DocComment' => __DIR__ . '/../..' . '/src/Psalm/DocComment.php',
        'Psalm\\ErrorBaseline' => __DIR__ . '/../..' . '/src/Psalm/ErrorBaseline.php',
        'Psalm\\Exception\\CircularReferenceException' => __DIR__ . '/../..' . '/src/Psalm/Exception/CircularReferenceException.php',
        'Psalm\\Exception\\CodeException' => __DIR__ . '/../..' . '/src/Psalm/Exception/CodeException.php',
        'Psalm\\Exception\\ComplicatedExpressionException' => __DIR__ . '/../..' . '/src/Psalm/Exception/ComplicatedExpressionException.php',
        'Psalm\\Exception\\ConfigCreationException' => __DIR__ . '/../..' . '/src/Psalm/Exception/ConfigCreationException.php',
        'Psalm\\Exception\\ConfigException' => __DIR__ . '/../..' . '/src/Psalm/Exception/ConfigException.php',
        'Psalm\\Exception\\ConfigNotFoundException' => __DIR__ . '/../..' . '/src/Psalm/Exception/ConfigNotFoundException.php',
        'Psalm\\Exception\\DocblockParseException' => __DIR__ . '/../..' . '/src/Psalm/Exception/DocblockParseException.php',
        'Psalm\\Exception\\FileIncludeException' => __DIR__ . '/../..' . '/src/Psalm/Exception/FileIncludeException.php',
        'Psalm\\Exception\\IncorrectDocblockException' => __DIR__ . '/../..' . '/src/Psalm/Exception/IncorrectDocblockException.php',
        'Psalm\\Exception\\InvalidClasslikeOverrideException' => __DIR__ . '/../..' . '/src/Psalm/Exception/InvalidClasslikeOverrideException.php',
        'Psalm\\Exception\\InvalidMethodOverrideException' => __DIR__ . '/../..' . '/src/Psalm/Exception/InvalidMethodOverrideException.php',
        'Psalm\\Exception\\RefactorException' => __DIR__ . '/../..' . '/src/Psalm/Exception/RefactorException.php',
        'Psalm\\Exception\\ScopeAnalysisException' => __DIR__ . '/../..' . '/src/Psalm/Exception/ScopeAnalysisException.php',
        'Psalm\\Exception\\TypeParseTreeException' => __DIR__ . '/../..' . '/src/Psalm/Exception/TypeParseTreeException.php',
        'Psalm\\Exception\\UnanalyzedFileException' => __DIR__ . '/../..' . '/src/Psalm/Exception/UnanalyzedFileException.php',
        'Psalm\\Exception\\UnpopulatedClasslikeException' => __DIR__ . '/../..' . '/src/Psalm/Exception/UnpopulatedClasslikeException.php',
        'Psalm\\Exception\\UnpreparedAnalysisException' => __DIR__ . '/../..' . '/src/Psalm/Exception/UnpreparedAnalysisException.php',
        'Psalm\\Exception\\UnresolvableConstantException' => __DIR__ . '/../..' . '/src/Psalm/Exception/UnresolvableConstantException.php',
        'Psalm\\Exception\\UnsupportedIssueToFixException' => __DIR__ . '/../..' . '/src/Psalm/Exception/UnsupportedIssueToFixException.php',
        'Psalm\\FileBasedPluginAdapter' => __DIR__ . '/../..' . '/src/Psalm/FileBasedPluginAdapter.php',
        'Psalm\\FileManipulation' => __DIR__ . '/../..' . '/src/Psalm/FileManipulation.php',
        'Psalm\\FileSource' => __DIR__ . '/../..' . '/src/Psalm/FileSource.php',
        'Psalm\\Internal\\Algebra' => __DIR__ . '/../..' . '/src/Psalm/Internal/Algebra.php',
        'Psalm\\Internal\\Algebra\\FormulaGenerator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Algebra/FormulaGenerator.php',
        'Psalm\\Internal\\Analyzer\\AlgebraAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/AlgebraAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\AttributesAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/AttributesAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\CanAlias' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/CanAlias.php',
        'Psalm\\Internal\\Analyzer\\ClassAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/ClassAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\ClassLikeAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\ClassLikeNameOptions' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/ClassLikeNameOptions.php',
        'Psalm\\Internal\\Analyzer\\ClosureAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/ClosureAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\CommentAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/CommentAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\DataFlowNodeData' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/DataFlowNodeData.php',
        'Psalm\\Internal\\Analyzer\\FileAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/FileAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\FunctionAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/FunctionAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\FunctionLikeAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\FunctionLike\\ReturnTypeAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\FunctionLike\\ReturnTypeCollector' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeCollector.php',
        'Psalm\\Internal\\Analyzer\\InterfaceAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/InterfaceAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\IssueData' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/IssueData.php',
        'Psalm\\Internal\\Analyzer\\MethodAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/MethodAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\MethodComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/MethodComparator.php',
        'Psalm\\Internal\\Analyzer\\NamespaceAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/NamespaceAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\ProjectAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\ScopeAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/ScopeAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\SourceAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/SourceAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\StatementsAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\DoAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/DoAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\ForAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/ForAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\ForeachAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfConditionalAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/IfConditionalAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElseAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElseAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElse\\ElseAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElse\\ElseIfAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/ElseIfAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\IfElse\\IfAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/IfElse/IfAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\LoopAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/LoopAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\SwitchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/SwitchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\SwitchCaseAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/SwitchCaseAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\TryAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/TryAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Block\\WhileAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Block/WhileAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\BreakAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/BreakAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\ContinueAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/ContinueAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\EchoAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/EchoAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\ExpressionAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ArrayAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ArrayCreationInfo' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayCreationInfo.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\AssertionFinder' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\AssignmentAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\ArrayAssignmentAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/ArrayAssignmentAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\AssignedProperty' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/AssignedProperty.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\InstancePropertyAssignmentAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/InstancePropertyAssignmentAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Assignment\\StaticPropertyAssignmentAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Assignment/StaticPropertyAssignmentAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOpAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\AndAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/AndAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\ArithmeticOpAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ArithmeticOpAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\CoalesceAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/CoalesceAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\ConcatAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\NonComparisonOpAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/NonComparisonOpAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BinaryOp\\OrAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/OrAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BitwiseNotAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BitwiseNotAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\BooleanNotAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/BooleanNotAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\CallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/CallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArgumentAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArgumentMapPopulator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentMapPopulator.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArgumentsAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ArrayFunctionArgumentsAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\ClassTemplateParamCollector' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ClassTemplateParamCollector.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\FunctionCallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\FunctionCallInfo' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallInfo.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\FunctionCallReturnTypeFetcher' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\MethodCallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\AtomicCallContext' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicCallContext.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\AtomicMethodCallAnalysisResult' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalysisResult.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\AtomicMethodCallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\ExistingAtomicMethodCallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodCallProhibitionAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallProhibitionAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodCallPurityAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallPurityAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodCallReturnTypeFetcher' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodCallReturnTypeFetcher.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MethodVisibilityAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MethodVisibilityAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\Method\\MissingMethodCallHandler' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/MissingMethodCallHandler.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\NamedFunctionCallHandler' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NamedFunctionCallHandler.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\NewAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/NewAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\StaticCallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\StaticMethod\\AtomicStaticCallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Call\\StaticMethod\\ExistingAtomicStaticCallAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\CastAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/CastAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ClassConstAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/ClassConstAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\CloneAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/CloneAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\EmptyAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/EmptyAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\EncapsulatedStringAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/EncapsulatedStringAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\EvalAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/EvalAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ExitAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/ExitAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\ExpressionIdentifier' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/ExpressionIdentifier.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\ArrayFetchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\AtomicPropertyFetchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/AtomicPropertyFetchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\ConstFetchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ConstFetchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\InstancePropertyFetchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/InstancePropertyFetchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\StaticPropertyFetchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/StaticPropertyFetchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\Fetch\\VariableFetchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/VariableFetchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\IncDecExpressionAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/IncDecExpressionAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\IncludeAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/IncludeAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\InstanceofAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/InstanceofAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\IssetAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/IssetAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\MagicConstAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/MagicConstAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\MatchAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/MatchAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\NullsafeAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/NullsafeAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\PrintAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/PrintAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\SimpleTypeInferer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\TernaryAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/TernaryAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\UnaryPlusMinusAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/UnaryPlusMinusAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\YieldAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/YieldAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\Expression\\YieldFromAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/Expression/YieldFromAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\GlobalAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/GlobalAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\ReturnAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/ReturnAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\StaticAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/StaticAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\ThrowAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/ThrowAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\UnsetAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/UnsetAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\Statements\\UnusedAssignmentRemover' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/Statements/UnusedAssignmentRemover.php',
        'Psalm\\Internal\\Analyzer\\TraitAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/TraitAnalyzer.php',
        'Psalm\\Internal\\Analyzer\\TypeAnalyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Analyzer/TypeAnalyzer.php',
        'Psalm\\Internal\\Clause' => __DIR__ . '/../..' . '/src/Psalm/Internal/Clause.php',
        'Psalm\\Internal\\CliUtils' => __DIR__ . '/../..' . '/src/Psalm/Internal/CliUtils.php',
        'Psalm\\Internal\\Cli\\LanguageServer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Cli/LanguageServer.php',
        'Psalm\\Internal\\Cli\\Plugin' => __DIR__ . '/../..' . '/src/Psalm/Internal/Cli/Plugin.php',
        'Psalm\\Internal\\Cli\\Psalm' => __DIR__ . '/../..' . '/src/Psalm/Internal/Cli/Psalm.php',
        'Psalm\\Internal\\Cli\\Psalter' => __DIR__ . '/../..' . '/src/Psalm/Internal/Cli/Psalter.php',
        'Psalm\\Internal\\Cli\\Refactor' => __DIR__ . '/../..' . '/src/Psalm/Internal/Cli/Refactor.php',
        'Psalm\\Internal\\Codebase\\Analyzer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/Analyzer.php',
        'Psalm\\Internal\\Codebase\\ClassConstantByWildcardResolver' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/ClassConstantByWildcardResolver.php',
        'Psalm\\Internal\\Codebase\\ClassLikes' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/ClassLikes.php',
        'Psalm\\Internal\\Codebase\\ConstantTypeResolver' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/ConstantTypeResolver.php',
        'Psalm\\Internal\\Codebase\\DataFlowGraph' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/DataFlowGraph.php',
        'Psalm\\Internal\\Codebase\\Functions' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/Functions.php',
        'Psalm\\Internal\\Codebase\\InternalCallMapHandler' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/InternalCallMapHandler.php',
        'Psalm\\Internal\\Codebase\\Methods' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/Methods.php',
        'Psalm\\Internal\\Codebase\\Populator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/Populator.php',
        'Psalm\\Internal\\Codebase\\Properties' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/Properties.php',
        'Psalm\\Internal\\Codebase\\PropertyMap' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/PropertyMap.php',
        'Psalm\\Internal\\Codebase\\ReferenceMapGenerator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/ReferenceMapGenerator.php',
        'Psalm\\Internal\\Codebase\\Reflection' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/Reflection.php',
        'Psalm\\Internal\\Codebase\\Scanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/Scanner.php',
        'Psalm\\Internal\\Codebase\\TaintFlowGraph' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/TaintFlowGraph.php',
        'Psalm\\Internal\\Codebase\\VariableUseGraph' => __DIR__ . '/../..' . '/src/Psalm/Internal/Codebase/VariableUseGraph.php',
        'Psalm\\Internal\\Composer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Composer.php',
        'Psalm\\Internal\\DataFlow\\DataFlowNode' => __DIR__ . '/../..' . '/src/Psalm/Internal/DataFlow/DataFlowNode.php',
        'Psalm\\Internal\\DataFlow\\Path' => __DIR__ . '/../..' . '/src/Psalm/Internal/DataFlow/Path.php',
        'Psalm\\Internal\\DataFlow\\TaintSink' => __DIR__ . '/../..' . '/src/Psalm/Internal/DataFlow/TaintSink.php',
        'Psalm\\Internal\\DataFlow\\TaintSource' => __DIR__ . '/../..' . '/src/Psalm/Internal/DataFlow/TaintSource.php',
        'Psalm\\Internal\\Diff\\AstDiffer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Diff/AstDiffer.php',
        'Psalm\\Internal\\Diff\\ClassStatementsDiffer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Diff/ClassStatementsDiffer.php',
        'Psalm\\Internal\\Diff\\DiffElem' => __DIR__ . '/../..' . '/src/Psalm/Internal/Diff/DiffElem.php',
        'Psalm\\Internal\\Diff\\FileDiffer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Diff/FileDiffer.php',
        'Psalm\\Internal\\Diff\\FileStatementsDiffer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Diff/FileStatementsDiffer.php',
        'Psalm\\Internal\\Diff\\NamespaceStatementsDiffer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Diff/NamespaceStatementsDiffer.php',
        'Psalm\\Internal\\ErrorHandler' => __DIR__ . '/../..' . '/src/Psalm/Internal/ErrorHandler.php',
        'Psalm\\Internal\\EventDispatcher' => __DIR__ . '/../..' . '/src/Psalm/Internal/EventDispatcher.php',
        'Psalm\\Internal\\ExecutionEnvironment\\BuildInfoCollector' => __DIR__ . '/../..' . '/src/Psalm/Internal/ExecutionEnvironment/BuildInfoCollector.php',
        'Psalm\\Internal\\ExecutionEnvironment\\GitInfoCollector' => __DIR__ . '/../..' . '/src/Psalm/Internal/ExecutionEnvironment/GitInfoCollector.php',
        'Psalm\\Internal\\ExecutionEnvironment\\SystemCommandExecutor' => __DIR__ . '/../..' . '/src/Psalm/Internal/ExecutionEnvironment/SystemCommandExecutor.php',
        'Psalm\\Internal\\FileManipulation\\ClassDocblockManipulator' => __DIR__ . '/../..' . '/src/Psalm/Internal/FileManipulation/ClassDocblockManipulator.php',
        'Psalm\\Internal\\FileManipulation\\CodeMigration' => __DIR__ . '/../..' . '/src/Psalm/Internal/FileManipulation/CodeMigration.php',
        'Psalm\\Internal\\FileManipulation\\FileManipulationBuffer' => __DIR__ . '/../..' . '/src/Psalm/Internal/FileManipulation/FileManipulationBuffer.php',
        'Psalm\\Internal\\FileManipulation\\FunctionDocblockManipulator' => __DIR__ . '/../..' . '/src/Psalm/Internal/FileManipulation/FunctionDocblockManipulator.php',
        'Psalm\\Internal\\FileManipulation\\PropertyDocblockManipulator' => __DIR__ . '/../..' . '/src/Psalm/Internal/FileManipulation/PropertyDocblockManipulator.php',
        'Psalm\\Internal\\Fork\\ForkMessage' => __DIR__ . '/../..' . '/src/Psalm/Internal/Fork/ForkMessage.php',
        'Psalm\\Internal\\Fork\\ForkProcessDoneMessage' => __DIR__ . '/../..' . '/src/Psalm/Internal/Fork/ForkProcessDoneMessage.php',
        'Psalm\\Internal\\Fork\\ForkProcessErrorMessage' => __DIR__ . '/../..' . '/src/Psalm/Internal/Fork/ForkProcessErrorMessage.php',
        'Psalm\\Internal\\Fork\\ForkTaskDoneMessage' => __DIR__ . '/../..' . '/src/Psalm/Internal/Fork/ForkTaskDoneMessage.php',
        'Psalm\\Internal\\Fork\\Pool' => __DIR__ . '/../..' . '/src/Psalm/Internal/Fork/Pool.php',
        'Psalm\\Internal\\Fork\\PsalmRestarter' => __DIR__ . '/../..' . '/src/Psalm/Internal/Fork/PsalmRestarter.php',
        'Psalm\\Internal\\IncludeCollector' => __DIR__ . '/../..' . '/src/Psalm/Internal/IncludeCollector.php',
        'Psalm\\Internal\\Json\\Json' => __DIR__ . '/../..' . '/src/Psalm/Internal/Json/Json.php',
        'Psalm\\Internal\\LanguageServer\\ClientHandler' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/ClientHandler.php',
        'Psalm\\Internal\\LanguageServer\\Client\\TextDocument' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/Client/TextDocument.php',
        'Psalm\\Internal\\LanguageServer\\EmitterInterface' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/EmitterInterface.php',
        'Psalm\\Internal\\LanguageServer\\EmitterTrait' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/EmitterTrait.php',
        'Psalm\\Internal\\LanguageServer\\IdGenerator' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/IdGenerator.php',
        'Psalm\\Internal\\LanguageServer\\LanguageClient' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/LanguageClient.php',
        'Psalm\\Internal\\LanguageServer\\LanguageServer' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/LanguageServer.php',
        'Psalm\\Internal\\LanguageServer\\Message' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/Message.php',
        'Psalm\\Internal\\LanguageServer\\ProtocolReader' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/ProtocolReader.php',
        'Psalm\\Internal\\LanguageServer\\ProtocolStreamReader' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/ProtocolStreamReader.php',
        'Psalm\\Internal\\LanguageServer\\ProtocolStreamWriter' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/ProtocolStreamWriter.php',
        'Psalm\\Internal\\LanguageServer\\ProtocolWriter' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/ProtocolWriter.php',
        'Psalm\\Internal\\LanguageServer\\Server\\TextDocument' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/Server/TextDocument.php',
        'Psalm\\Internal\\LanguageServer\\Server\\Workspace' => __DIR__ . '/../..' . '/src/Psalm/Internal/LanguageServer/Server/Workspace.php',
        'Psalm\\Internal\\MethodIdentifier' => __DIR__ . '/../..' . '/src/Psalm/Internal/MethodIdentifier.php',
        'Psalm\\Internal\\PhpTraverser\\CustomTraverser' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpTraverser/CustomTraverser.php',
        'Psalm\\Internal\\PhpVisitor\\AssignmentMapVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/AssignmentMapVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\CheckTrivialExprVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/CheckTrivialExprVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\CloningVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/CloningVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\ConditionCloningVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/ConditionCloningVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\NodeCleanerVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/NodeCleanerVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\NodeCounterVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/NodeCounterVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\OffsetShifterVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/OffsetShifterVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\ParamReplacementVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/ParamReplacementVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\PartialParserVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/PartialParserVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\ReflectorVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\AttributeResolver' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/AttributeResolver.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\ClassLikeDocblockParser' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeDocblockParser.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\ClassLikeNodeScanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\ExpressionResolver' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionResolver.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\ExpressionScanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/ExpressionScanner.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\FunctionLikeDocblockParser' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockParser.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\FunctionLikeDocblockScanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeDocblockScanner.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\FunctionLikeNodeScanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/FunctionLikeNodeScanner.php',
        'Psalm\\Internal\\PhpVisitor\\Reflector\\TypeHintResolver' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/Reflector/TypeHintResolver.php',
        'Psalm\\Internal\\PhpVisitor\\ShortClosureVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/ShortClosureVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\SimpleNameResolver' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/SimpleNameResolver.php',
        'Psalm\\Internal\\PhpVisitor\\TraitFinder' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/TraitFinder.php',
        'Psalm\\Internal\\PhpVisitor\\TypeMappingVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/TypeMappingVisitor.php',
        'Psalm\\Internal\\PhpVisitor\\YieldTypeCollector' => __DIR__ . '/../..' . '/src/Psalm/Internal/PhpVisitor/YieldTypeCollector.php',
        'Psalm\\Internal\\PluginManager\\Command\\DisableCommand' => __DIR__ . '/../..' . '/src/Psalm/Internal/PluginManager/Command/DisableCommand.php',
        'Psalm\\Internal\\PluginManager\\Command\\EnableCommand' => __DIR__ . '/../..' . '/src/Psalm/Internal/PluginManager/Command/EnableCommand.php',
        'Psalm\\Internal\\PluginManager\\Command\\ShowCommand' => __DIR__ . '/../..' . '/src/Psalm/Internal/PluginManager/Command/ShowCommand.php',
        'Psalm\\Internal\\PluginManager\\ComposerLock' => __DIR__ . '/../..' . '/src/Psalm/Internal/PluginManager/ComposerLock.php',
        'Psalm\\Internal\\PluginManager\\ConfigFile' => __DIR__ . '/../..' . '/src/Psalm/Internal/PluginManager/ConfigFile.php',
        'Psalm\\Internal\\PluginManager\\PluginList' => __DIR__ . '/../..' . '/src/Psalm/Internal/PluginManager/PluginList.php',
        'Psalm\\Internal\\PluginManager\\PluginListFactory' => __DIR__ . '/../..' . '/src/Psalm/Internal/PluginManager/PluginListFactory.php',
        'Psalm\\Internal\\Provider\\AddRemoveTaints\\HtmlFunctionTainter' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/AddRemoveTaints/HtmlFunctionTainter.php',
        'Psalm\\Internal\\Provider\\ClassLikeStorageCacheProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ClassLikeStorageCacheProvider.php',
        'Psalm\\Internal\\Provider\\ClassLikeStorageProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php',
        'Psalm\\Internal\\Provider\\DynamicFunctionStorageProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/DynamicFunctionStorageProvider.php',
        'Psalm\\Internal\\Provider\\FakeFileProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FakeFileProvider.php',
        'Psalm\\Internal\\Provider\\FileProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FileProvider.php',
        'Psalm\\Internal\\Provider\\FileReferenceCacheProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FileReferenceCacheProvider.php',
        'Psalm\\Internal\\Provider\\FileReferenceProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FileReferenceProvider.php',
        'Psalm\\Internal\\Provider\\FileStorageCacheProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FileStorageCacheProvider.php',
        'Psalm\\Internal\\Provider\\FileStorageProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FileStorageProvider.php',
        'Psalm\\Internal\\Provider\\FunctionExistenceProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FunctionExistenceProvider.php',
        'Psalm\\Internal\\Provider\\FunctionParamsProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FunctionParamsProvider.php',
        'Psalm\\Internal\\Provider\\FunctionReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\MethodExistenceProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/MethodExistenceProvider.php',
        'Psalm\\Internal\\Provider\\MethodParamsProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/MethodParamsProvider.php',
        'Psalm\\Internal\\Provider\\MethodReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/MethodReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\MethodVisibilityProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/MethodVisibilityProvider.php',
        'Psalm\\Internal\\Provider\\NodeDataProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/NodeDataProvider.php',
        'Psalm\\Internal\\Provider\\ParserCacheProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ParserCacheProvider.php',
        'Psalm\\Internal\\Provider\\ProjectCacheProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ProjectCacheProvider.php',
        'Psalm\\Internal\\Provider\\PropertyExistenceProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/PropertyExistenceProvider.php',
        'Psalm\\Internal\\Provider\\PropertyTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/PropertyTypeProvider.php',
        'Psalm\\Internal\\Provider\\PropertyTypeProvider\\DomDocumentPropertyTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/PropertyTypeProvider/DomDocumentPropertyTypeProvider.php',
        'Psalm\\Internal\\Provider\\PropertyVisibilityProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/PropertyVisibilityProvider.php',
        'Psalm\\Internal\\Provider\\Providers' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/Providers.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayChunkReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayChunkReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayColumnReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayCombineReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayCombineReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayFillKeysReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillKeysReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayFillReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayFilterReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFilterReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayMapReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayMergeReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMergeReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayPadReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPadReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayPointerAdjustmentReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPointerAdjustmentReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayPopReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayPopReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayRandReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayRandReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayReduceReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReduceReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayReverseReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayReverseReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArraySliceReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArraySliceReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArraySpliceReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArraySpliceReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ArrayUniqueReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayUniqueReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\BasenameReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/BasenameReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ClosureFromCallableReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ClosureFromCallableReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\DateTimeModifyReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/DateTimeModifyReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\DirnameReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/DirnameReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\DomNodeAppendChild' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/DomNodeAppendChild.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\FilterVarReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/FilterVarReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\FirstArgStringReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/FirstArgStringReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\GetClassMethodsReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/GetClassMethodsReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\GetObjectVarsReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/GetObjectVarsReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\HexdecReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/HexdecReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ImagickPixelColorReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ImagickPixelColorReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\InArrayReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/InArrayReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\IteratorToArrayReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/IteratorToArrayReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\MbInternalEncodingReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/MbInternalEncodingReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\MinMaxReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/MinMaxReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\MktimeReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/MktimeReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\ParseUrlReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/ParseUrlReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\PdoStatementReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/PdoStatementReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\PdoStatementSetFetchMode' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/PdoStatementSetFetchMode.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\RandReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/RandReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\RoundReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/RoundReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\SimpleXmlElementAsXml' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/SimpleXmlElementAsXml.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\StrReplaceReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/StrReplaceReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\StrTrReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/StrTrReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\TriggerErrorReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/TriggerErrorReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\ReturnTypeProvider\\VersionCompareReturnTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/ReturnTypeProvider/VersionCompareReturnTypeProvider.php',
        'Psalm\\Internal\\Provider\\StatementsProvider' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/StatementsProvider.php',
        'Psalm\\Internal\\Provider\\StatementsVolatileCache' => __DIR__ . '/../..' . '/src/Psalm/Internal/Provider/StatementsVolatileCache.php',
        'Psalm\\Internal\\ReferenceConstraint' => __DIR__ . '/../..' . '/src/Psalm/Internal/ReferenceConstraint.php',
        'Psalm\\Internal\\RuntimeCaches' => __DIR__ . '/../..' . '/src/Psalm/Internal/RuntimeCaches.php',
        'Psalm\\Internal\\Scanner\\ClassLikeDocblockComment' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/ClassLikeDocblockComment.php',
        'Psalm\\Internal\\Scanner\\DocblockParser' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/DocblockParser.php',
        'Psalm\\Internal\\Scanner\\FileScanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/FileScanner.php',
        'Psalm\\Internal\\Scanner\\FunctionDocblockComment' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/FunctionDocblockComment.php',
        'Psalm\\Internal\\Scanner\\ParsedDocblock' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/ParsedDocblock.php',
        'Psalm\\Internal\\Scanner\\PhpStormMetaScanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/PhpStormMetaScanner.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstantComponent' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstantComponent.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ArrayOffsetFetch' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ArrayOffsetFetch.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ArraySpread' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ArraySpread.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ArrayValue' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ArrayValue.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ClassConstant' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ClassConstant.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\Constant' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/Constant.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\KeyValuePair' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/KeyValuePair.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\ScalarValue' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/ScalarValue.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedAdditionOp' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedAdditionOp.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBinaryOp' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBinaryOp.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBitwiseAnd' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseAnd.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBitwiseOr' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseOr.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedBitwiseXor' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedBitwiseXor.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedConcatOp' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedConcatOp.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedDivisionOp' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedDivisionOp.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedMultiplicationOp' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedMultiplicationOp.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedSubtractionOp' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedSubtractionOp.php',
        'Psalm\\Internal\\Scanner\\UnresolvedConstant\\UnresolvedTernary' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/UnresolvedConstant/UnresolvedTernary.php',
        'Psalm\\Internal\\Scanner\\VarDocblockComment' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scanner/VarDocblockComment.php',
        'Psalm\\Internal\\Scope\\CaseScope' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scope/CaseScope.php',
        'Psalm\\Internal\\Scope\\FinallyScope' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scope/FinallyScope.php',
        'Psalm\\Internal\\Scope\\IfConditionalScope' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scope/IfConditionalScope.php',
        'Psalm\\Internal\\Scope\\IfScope' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scope/IfScope.php',
        'Psalm\\Internal\\Scope\\LoopScope' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scope/LoopScope.php',
        'Psalm\\Internal\\Scope\\SwitchScope' => __DIR__ . '/../..' . '/src/Psalm/Internal/Scope/SwitchScope.php',
        'Psalm\\Internal\\Stubs\\Generator\\ClassLikeStubGenerator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Stubs/Generator/ClassLikeStubGenerator.php',
        'Psalm\\Internal\\Stubs\\Generator\\StubsGenerator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Stubs/Generator/StubsGenerator.php',
        'Psalm\\Internal\\TypeVisitor\\CanContainObjectTypeVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/CanContainObjectTypeVisitor.php',
        'Psalm\\Internal\\TypeVisitor\\ClasslikeReplacer' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/ClasslikeReplacer.php',
        'Psalm\\Internal\\TypeVisitor\\ContainsClassLikeVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/ContainsClassLikeVisitor.php',
        'Psalm\\Internal\\TypeVisitor\\ContainsLiteralVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/ContainsLiteralVisitor.php',
        'Psalm\\Internal\\TypeVisitor\\ContainsStaticVisitor' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/ContainsStaticVisitor.php',
        'Psalm\\Internal\\TypeVisitor\\FromDocblockSetter' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/FromDocblockSetter.php',
        'Psalm\\Internal\\TypeVisitor\\TemplateTypeCollector' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/TemplateTypeCollector.php',
        'Psalm\\Internal\\TypeVisitor\\TypeChecker' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/TypeChecker.php',
        'Psalm\\Internal\\TypeVisitor\\TypeLocalizer' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/TypeLocalizer.php',
        'Psalm\\Internal\\TypeVisitor\\TypeScanner' => __DIR__ . '/../..' . '/src/Psalm/Internal/TypeVisitor/TypeScanner.php',
        'Psalm\\Internal\\Type\\ArrayType' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ArrayType.php',
        'Psalm\\Internal\\Type\\AssertionReconciler' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/AssertionReconciler.php',
        'Psalm\\Internal\\Type\\Comparator\\ArrayTypeComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/ArrayTypeComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\AtomicTypeComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/AtomicTypeComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\CallableTypeComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/CallableTypeComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\ClassLikeStringComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/ClassLikeStringComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\GenericTypeComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/GenericTypeComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\IntegerRangeComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/IntegerRangeComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\KeyedArrayComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/KeyedArrayComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\ObjectComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/ObjectComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\ScalarTypeComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/ScalarTypeComparator.php',
        'Psalm\\Internal\\Type\\Comparator\\TypeComparisonResult' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/TypeComparisonResult.php',
        'Psalm\\Internal\\Type\\Comparator\\UnionTypeComparator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/Comparator/UnionTypeComparator.php',
        'Psalm\\Internal\\Type\\NegatedAssertionReconciler' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/NegatedAssertionReconciler.php',
        'Psalm\\Internal\\Type\\ParseTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree.php',
        'Psalm\\Internal\\Type\\ParseTreeCreator' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTreeCreator.php',
        'Psalm\\Internal\\Type\\ParseTree\\CallableParamTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/CallableParamTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\CallableTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/CallableTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\CallableWithReturnTypeTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/CallableWithReturnTypeTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\ConditionalTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/ConditionalTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\EncapsulationTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/EncapsulationTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\FieldEllipsis' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/FieldEllipsis.php',
        'Psalm\\Internal\\Type\\ParseTree\\GenericTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/GenericTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\IndexedAccessTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/IndexedAccessTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\IntersectionTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/IntersectionTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\KeyedArrayPropertyTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/KeyedArrayPropertyTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\KeyedArrayTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/KeyedArrayTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\MethodParamTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/MethodParamTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\MethodTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/MethodTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\MethodWithReturnTypeTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/MethodWithReturnTypeTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\NullableTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/NullableTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\Root' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/Root.php',
        'Psalm\\Internal\\Type\\ParseTree\\TemplateAsTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/TemplateAsTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\TemplateIsTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/TemplateIsTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\UnionTree' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/UnionTree.php',
        'Psalm\\Internal\\Type\\ParseTree\\Value' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/ParseTree/Value.php',
        'Psalm\\Internal\\Type\\SimpleAssertionReconciler' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/SimpleAssertionReconciler.php',
        'Psalm\\Internal\\Type\\SimpleNegatedAssertionReconciler' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php',
        'Psalm\\Internal\\Type\\TemplateBound' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TemplateBound.php',
        'Psalm\\Internal\\Type\\TemplateInferredTypeReplacer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TemplateInferredTypeReplacer.php',
        'Psalm\\Internal\\Type\\TemplateResult' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TemplateResult.php',
        'Psalm\\Internal\\Type\\TemplateStandinTypeReplacer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TemplateStandinTypeReplacer.php',
        'Psalm\\Internal\\Type\\TypeAlias' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeAlias.php',
        'Psalm\\Internal\\Type\\TypeAlias\\ClassTypeAlias' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeAlias/ClassTypeAlias.php',
        'Psalm\\Internal\\Type\\TypeAlias\\InlineTypeAlias' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeAlias/InlineTypeAlias.php',
        'Psalm\\Internal\\Type\\TypeAlias\\LinkableTypeAlias' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeAlias/LinkableTypeAlias.php',
        'Psalm\\Internal\\Type\\TypeCombination' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeCombination.php',
        'Psalm\\Internal\\Type\\TypeCombiner' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeCombiner.php',
        'Psalm\\Internal\\Type\\TypeExpander' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeExpander.php',
        'Psalm\\Internal\\Type\\TypeParser' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeParser.php',
        'Psalm\\Internal\\Type\\TypeTokenizer' => __DIR__ . '/../..' . '/src/Psalm/Internal/Type/TypeTokenizer.php',
        'Psalm\\Internal\\VersionUtils' => __DIR__ . '/../..' . '/src/Psalm/Internal/VersionUtils.php',
        'Psalm\\IssueBuffer' => __DIR__ . '/../..' . '/src/Psalm/IssueBuffer.php',
        'Psalm\\Issue\\AbstractInstantiation' => __DIR__ . '/../..' . '/src/Psalm/Issue/AbstractInstantiation.php',
        'Psalm\\Issue\\AbstractMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/AbstractMethodCall.php',
        'Psalm\\Issue\\AmbiguousConstantInheritance' => __DIR__ . '/../..' . '/src/Psalm/Issue/AmbiguousConstantInheritance.php',
        'Psalm\\Issue\\ArgumentIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/ArgumentIssue.php',
        'Psalm\\Issue\\ArgumentTypeCoercion' => __DIR__ . '/../..' . '/src/Psalm/Issue/ArgumentTypeCoercion.php',
        'Psalm\\Issue\\AssignmentToVoid' => __DIR__ . '/../..' . '/src/Psalm/Issue/AssignmentToVoid.php',
        'Psalm\\Issue\\CheckType' => __DIR__ . '/../..' . '/src/Psalm/Issue/CheckType.php',
        'Psalm\\Issue\\CircularReference' => __DIR__ . '/../..' . '/src/Psalm/Issue/CircularReference.php',
        'Psalm\\Issue\\ClassConstantIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/ClassConstantIssue.php',
        'Psalm\\Issue\\ClassIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/ClassIssue.php',
        'Psalm\\Issue\\CodeIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/CodeIssue.php',
        'Psalm\\Issue\\ComplexFunction' => __DIR__ . '/../..' . '/src/Psalm/Issue/ComplexFunction.php',
        'Psalm\\Issue\\ComplexMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/ComplexMethod.php',
        'Psalm\\Issue\\ConfigIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/ConfigIssue.php',
        'Psalm\\Issue\\ConflictingReferenceConstraint' => __DIR__ . '/../..' . '/src/Psalm/Issue/ConflictingReferenceConstraint.php',
        'Psalm\\Issue\\ConstantDeclarationInTrait' => __DIR__ . '/../..' . '/src/Psalm/Issue/ConstantDeclarationInTrait.php',
        'Psalm\\Issue\\ConstructorSignatureMismatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/ConstructorSignatureMismatch.php',
        'Psalm\\Issue\\ContinueOutsideLoop' => __DIR__ . '/../..' . '/src/Psalm/Issue/ContinueOutsideLoop.php',
        'Psalm\\Issue\\DeprecatedClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/DeprecatedClass.php',
        'Psalm\\Issue\\DeprecatedConstant' => __DIR__ . '/../..' . '/src/Psalm/Issue/DeprecatedConstant.php',
        'Psalm\\Issue\\DeprecatedFunction' => __DIR__ . '/../..' . '/src/Psalm/Issue/DeprecatedFunction.php',
        'Psalm\\Issue\\DeprecatedInterface' => __DIR__ . '/../..' . '/src/Psalm/Issue/DeprecatedInterface.php',
        'Psalm\\Issue\\DeprecatedMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/DeprecatedMethod.php',
        'Psalm\\Issue\\DeprecatedProperty' => __DIR__ . '/../..' . '/src/Psalm/Issue/DeprecatedProperty.php',
        'Psalm\\Issue\\DeprecatedTrait' => __DIR__ . '/../..' . '/src/Psalm/Issue/DeprecatedTrait.php',
        'Psalm\\Issue\\DocblockTypeContradiction' => __DIR__ . '/../..' . '/src/Psalm/Issue/DocblockTypeContradiction.php',
        'Psalm\\Issue\\DuplicateArrayKey' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateArrayKey.php',
        'Psalm\\Issue\\DuplicateClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateClass.php',
        'Psalm\\Issue\\DuplicateConstant' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateConstant.php',
        'Psalm\\Issue\\DuplicateEnumCase' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateEnumCase.php',
        'Psalm\\Issue\\DuplicateEnumCaseValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateEnumCaseValue.php',
        'Psalm\\Issue\\DuplicateFunction' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateFunction.php',
        'Psalm\\Issue\\DuplicateMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateMethod.php',
        'Psalm\\Issue\\DuplicateParam' => __DIR__ . '/../..' . '/src/Psalm/Issue/DuplicateParam.php',
        'Psalm\\Issue\\EmptyArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/EmptyArrayAccess.php',
        'Psalm\\Issue\\ExtensionRequirementViolation' => __DIR__ . '/../..' . '/src/Psalm/Issue/ExtensionRequirementViolation.php',
        'Psalm\\Issue\\FalsableReturnStatement' => __DIR__ . '/../..' . '/src/Psalm/Issue/FalsableReturnStatement.php',
        'Psalm\\Issue\\FalseOperand' => __DIR__ . '/../..' . '/src/Psalm/Issue/FalseOperand.php',
        'Psalm\\Issue\\ForbiddenCode' => __DIR__ . '/../..' . '/src/Psalm/Issue/ForbiddenCode.php',
        'Psalm\\Issue\\FunctionIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/FunctionIssue.php',
        'Psalm\\Issue\\IfThisIsMismatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/IfThisIsMismatch.php',
        'Psalm\\Issue\\ImplementationRequirementViolation' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImplementationRequirementViolation.php',
        'Psalm\\Issue\\ImplementedParamTypeMismatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImplementedParamTypeMismatch.php',
        'Psalm\\Issue\\ImplementedReturnTypeMismatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImplementedReturnTypeMismatch.php',
        'Psalm\\Issue\\ImplicitToStringCast' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImplicitToStringCast.php',
        'Psalm\\Issue\\ImpureByReferenceAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpureByReferenceAssignment.php',
        'Psalm\\Issue\\ImpureFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpureFunctionCall.php',
        'Psalm\\Issue\\ImpureMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpureMethodCall.php',
        'Psalm\\Issue\\ImpurePropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpurePropertyAssignment.php',
        'Psalm\\Issue\\ImpurePropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpurePropertyFetch.php',
        'Psalm\\Issue\\ImpureStaticProperty' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpureStaticProperty.php',
        'Psalm\\Issue\\ImpureStaticVariable' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpureStaticVariable.php',
        'Psalm\\Issue\\ImpureVariable' => __DIR__ . '/../..' . '/src/Psalm/Issue/ImpureVariable.php',
        'Psalm\\Issue\\InaccessibleClassConstant' => __DIR__ . '/../..' . '/src/Psalm/Issue/InaccessibleClassConstant.php',
        'Psalm\\Issue\\InaccessibleMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/InaccessibleMethod.php',
        'Psalm\\Issue\\InaccessibleProperty' => __DIR__ . '/../..' . '/src/Psalm/Issue/InaccessibleProperty.php',
        'Psalm\\Issue\\InterfaceInstantiation' => __DIR__ . '/../..' . '/src/Psalm/Issue/InterfaceInstantiation.php',
        'Psalm\\Issue\\InternalClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/InternalClass.php',
        'Psalm\\Issue\\InternalMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/InternalMethod.php',
        'Psalm\\Issue\\InternalProperty' => __DIR__ . '/../..' . '/src/Psalm/Issue/InternalProperty.php',
        'Psalm\\Issue\\InvalidArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidArgument.php',
        'Psalm\\Issue\\InvalidArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidArrayAccess.php',
        'Psalm\\Issue\\InvalidArrayAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidArrayAssignment.php',
        'Psalm\\Issue\\InvalidArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidArrayOffset.php',
        'Psalm\\Issue\\InvalidAttribute' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidAttribute.php',
        'Psalm\\Issue\\InvalidCast' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidCast.php',
        'Psalm\\Issue\\InvalidCatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidCatch.php',
        'Psalm\\Issue\\InvalidClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidClass.php',
        'Psalm\\Issue\\InvalidClassConstantType' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidClassConstantType.php',
        'Psalm\\Issue\\InvalidClone' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidClone.php',
        'Psalm\\Issue\\InvalidConstantAssignmentValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidConstantAssignmentValue.php',
        'Psalm\\Issue\\InvalidDocblock' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidDocblock.php',
        'Psalm\\Issue\\InvalidDocblockParamName' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidDocblockParamName.php',
        'Psalm\\Issue\\InvalidEnumBackingType' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidEnumBackingType.php',
        'Psalm\\Issue\\InvalidEnumCaseValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidEnumCaseValue.php',
        'Psalm\\Issue\\InvalidEnumMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidEnumMethod.php',
        'Psalm\\Issue\\InvalidExtendClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidExtendClass.php',
        'Psalm\\Issue\\InvalidFalsableReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidFalsableReturnType.php',
        'Psalm\\Issue\\InvalidFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidFunctionCall.php',
        'Psalm\\Issue\\InvalidGlobal' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidGlobal.php',
        'Psalm\\Issue\\InvalidIterator' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidIterator.php',
        'Psalm\\Issue\\InvalidLiteralArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidLiteralArgument.php',
        'Psalm\\Issue\\InvalidMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidMethodCall.php',
        'Psalm\\Issue\\InvalidNamedArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidNamedArgument.php',
        'Psalm\\Issue\\InvalidNullableReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidNullableReturnType.php',
        'Psalm\\Issue\\InvalidOperand' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidOperand.php',
        'Psalm\\Issue\\InvalidParamDefault' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidParamDefault.php',
        'Psalm\\Issue\\InvalidParent' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidParent.php',
        'Psalm\\Issue\\InvalidPassByReference' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidPassByReference.php',
        'Psalm\\Issue\\InvalidPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidPropertyAssignment.php',
        'Psalm\\Issue\\InvalidPropertyAssignmentValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidPropertyAssignmentValue.php',
        'Psalm\\Issue\\InvalidPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidPropertyFetch.php',
        'Psalm\\Issue\\InvalidReturnStatement' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidReturnStatement.php',
        'Psalm\\Issue\\InvalidReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidReturnType.php',
        'Psalm\\Issue\\InvalidScalarArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidScalarArgument.php',
        'Psalm\\Issue\\InvalidScope' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidScope.php',
        'Psalm\\Issue\\InvalidStaticInvocation' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidStaticInvocation.php',
        'Psalm\\Issue\\InvalidStringClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidStringClass.php',
        'Psalm\\Issue\\InvalidTemplateParam' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidTemplateParam.php',
        'Psalm\\Issue\\InvalidThrow' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidThrow.php',
        'Psalm\\Issue\\InvalidToString' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidToString.php',
        'Psalm\\Issue\\InvalidTraversableImplementation' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidTraversableImplementation.php',
        'Psalm\\Issue\\InvalidTypeImport' => __DIR__ . '/../..' . '/src/Psalm/Issue/InvalidTypeImport.php',
        'Psalm\\Issue\\LessSpecificClassConstantType' => __DIR__ . '/../..' . '/src/Psalm/Issue/LessSpecificClassConstantType.php',
        'Psalm\\Issue\\LessSpecificImplementedReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/LessSpecificImplementedReturnType.php',
        'Psalm\\Issue\\LessSpecificReturnStatement' => __DIR__ . '/../..' . '/src/Psalm/Issue/LessSpecificReturnStatement.php',
        'Psalm\\Issue\\LessSpecificReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/LessSpecificReturnType.php',
        'Psalm\\Issue\\LoopInvalidation' => __DIR__ . '/../..' . '/src/Psalm/Issue/LoopInvalidation.php',
        'Psalm\\Issue\\MethodIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/MethodIssue.php',
        'Psalm\\Issue\\MethodSignatureMismatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/MethodSignatureMismatch.php',
        'Psalm\\Issue\\MethodSignatureMustOmitReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MethodSignatureMustOmitReturnType.php',
        'Psalm\\Issue\\MethodSignatureMustProvideReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MethodSignatureMustProvideReturnType.php',
        'Psalm\\Issue\\MismatchingDocblockParamType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MismatchingDocblockParamType.php',
        'Psalm\\Issue\\MismatchingDocblockPropertyType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MismatchingDocblockPropertyType.php',
        'Psalm\\Issue\\MismatchingDocblockReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MismatchingDocblockReturnType.php',
        'Psalm\\Issue\\MissingClosureParamType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingClosureParamType.php',
        'Psalm\\Issue\\MissingClosureReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingClosureReturnType.php',
        'Psalm\\Issue\\MissingConstructor' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingConstructor.php',
        'Psalm\\Issue\\MissingDependency' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingDependency.php',
        'Psalm\\Issue\\MissingDocblockType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingDocblockType.php',
        'Psalm\\Issue\\MissingFile' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingFile.php',
        'Psalm\\Issue\\MissingImmutableAnnotation' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingImmutableAnnotation.php',
        'Psalm\\Issue\\MissingParamType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingParamType.php',
        'Psalm\\Issue\\MissingPropertyType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingPropertyType.php',
        'Psalm\\Issue\\MissingReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingReturnType.php',
        'Psalm\\Issue\\MissingTemplateParam' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingTemplateParam.php',
        'Psalm\\Issue\\MissingThrowsDocblock' => __DIR__ . '/../..' . '/src/Psalm/Issue/MissingThrowsDocblock.php',
        'Psalm\\Issue\\MixedArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedArgument.php',
        'Psalm\\Issue\\MixedArgumentTypeCoercion' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedArgumentTypeCoercion.php',
        'Psalm\\Issue\\MixedArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedArrayAccess.php',
        'Psalm\\Issue\\MixedArrayAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedArrayAssignment.php',
        'Psalm\\Issue\\MixedArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedArrayOffset.php',
        'Psalm\\Issue\\MixedArrayTypeCoercion' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedArrayTypeCoercion.php',
        'Psalm\\Issue\\MixedAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedAssignment.php',
        'Psalm\\Issue\\MixedClone' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedClone.php',
        'Psalm\\Issue\\MixedFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedFunctionCall.php',
        'Psalm\\Issue\\MixedInferredReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedInferredReturnType.php',
        'Psalm\\Issue\\MixedIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedIssue.php',
        'Psalm\\Issue\\MixedIssueTrait' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedIssueTrait.php',
        'Psalm\\Issue\\MixedMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedMethodCall.php',
        'Psalm\\Issue\\MixedOperand' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedOperand.php',
        'Psalm\\Issue\\MixedPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedPropertyAssignment.php',
        'Psalm\\Issue\\MixedPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedPropertyFetch.php',
        'Psalm\\Issue\\MixedPropertyTypeCoercion' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedPropertyTypeCoercion.php',
        'Psalm\\Issue\\MixedReturnStatement' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedReturnStatement.php',
        'Psalm\\Issue\\MixedReturnTypeCoercion' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedReturnTypeCoercion.php',
        'Psalm\\Issue\\MixedStringOffsetAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/MixedStringOffsetAssignment.php',
        'Psalm\\Issue\\MoreSpecificImplementedParamType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MoreSpecificImplementedParamType.php',
        'Psalm\\Issue\\MoreSpecificReturnType' => __DIR__ . '/../..' . '/src/Psalm/Issue/MoreSpecificReturnType.php',
        'Psalm\\Issue\\MutableDependency' => __DIR__ . '/../..' . '/src/Psalm/Issue/MutableDependency.php',
        'Psalm\\Issue\\NamedArgumentNotAllowed' => __DIR__ . '/../..' . '/src/Psalm/Issue/NamedArgumentNotAllowed.php',
        'Psalm\\Issue\\NoEnumProperties' => __DIR__ . '/../..' . '/src/Psalm/Issue/NoEnumProperties.php',
        'Psalm\\Issue\\NoInterfaceProperties' => __DIR__ . '/../..' . '/src/Psalm/Issue/NoInterfaceProperties.php',
        'Psalm\\Issue\\NoValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/NoValue.php',
        'Psalm\\Issue\\NonInvariantDocblockPropertyType' => __DIR__ . '/../..' . '/src/Psalm/Issue/NonInvariantDocblockPropertyType.php',
        'Psalm\\Issue\\NonInvariantPropertyType' => __DIR__ . '/../..' . '/src/Psalm/Issue/NonInvariantPropertyType.php',
        'Psalm\\Issue\\NonStaticSelfCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/NonStaticSelfCall.php',
        'Psalm\\Issue\\NullArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullArgument.php',
        'Psalm\\Issue\\NullArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullArrayAccess.php',
        'Psalm\\Issue\\NullArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullArrayOffset.php',
        'Psalm\\Issue\\NullFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullFunctionCall.php',
        'Psalm\\Issue\\NullIterator' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullIterator.php',
        'Psalm\\Issue\\NullOperand' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullOperand.php',
        'Psalm\\Issue\\NullPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullPropertyAssignment.php',
        'Psalm\\Issue\\NullPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullPropertyFetch.php',
        'Psalm\\Issue\\NullReference' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullReference.php',
        'Psalm\\Issue\\NullableReturnStatement' => __DIR__ . '/../..' . '/src/Psalm/Issue/NullableReturnStatement.php',
        'Psalm\\Issue\\OverriddenFinalConstant' => __DIR__ . '/../..' . '/src/Psalm/Issue/OverriddenFinalConstant.php',
        'Psalm\\Issue\\OverriddenInterfaceConstant' => __DIR__ . '/../..' . '/src/Psalm/Issue/OverriddenInterfaceConstant.php',
        'Psalm\\Issue\\OverriddenMethodAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/OverriddenMethodAccess.php',
        'Psalm\\Issue\\OverriddenPropertyAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/OverriddenPropertyAccess.php',
        'Psalm\\Issue\\ParadoxicalCondition' => __DIR__ . '/../..' . '/src/Psalm/Issue/ParadoxicalCondition.php',
        'Psalm\\Issue\\ParamNameMismatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/ParamNameMismatch.php',
        'Psalm\\Issue\\ParentNotFound' => __DIR__ . '/../..' . '/src/Psalm/Issue/ParentNotFound.php',
        'Psalm\\Issue\\ParseError' => __DIR__ . '/../..' . '/src/Psalm/Issue/ParseError.php',
        'Psalm\\Issue\\PluginIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/PluginIssue.php',
        'Psalm\\Issue\\PossibleRawObjectIteration' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossibleRawObjectIteration.php',
        'Psalm\\Issue\\PossiblyFalseArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyFalseArgument.php',
        'Psalm\\Issue\\PossiblyFalseIterator' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyFalseIterator.php',
        'Psalm\\Issue\\PossiblyFalseOperand' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyFalseOperand.php',
        'Psalm\\Issue\\PossiblyFalsePropertyAssignmentValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyFalsePropertyAssignmentValue.php',
        'Psalm\\Issue\\PossiblyFalseReference' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyFalseReference.php',
        'Psalm\\Issue\\PossiblyInvalidArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidArgument.php',
        'Psalm\\Issue\\PossiblyInvalidArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidArrayAccess.php',
        'Psalm\\Issue\\PossiblyInvalidArrayAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidArrayAssignment.php',
        'Psalm\\Issue\\PossiblyInvalidArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidArrayOffset.php',
        'Psalm\\Issue\\PossiblyInvalidCast' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidCast.php',
        'Psalm\\Issue\\PossiblyInvalidClone' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidClone.php',
        'Psalm\\Issue\\PossiblyInvalidDocblockTag' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidDocblockTag.php',
        'Psalm\\Issue\\PossiblyInvalidFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidFunctionCall.php',
        'Psalm\\Issue\\PossiblyInvalidIterator' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidIterator.php',
        'Psalm\\Issue\\PossiblyInvalidMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidMethodCall.php',
        'Psalm\\Issue\\PossiblyInvalidOperand' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidOperand.php',
        'Psalm\\Issue\\PossiblyInvalidPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidPropertyAssignment.php',
        'Psalm\\Issue\\PossiblyInvalidPropertyAssignmentValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidPropertyAssignmentValue.php',
        'Psalm\\Issue\\PossiblyInvalidPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyInvalidPropertyFetch.php',
        'Psalm\\Issue\\PossiblyNullArgument' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullArgument.php',
        'Psalm\\Issue\\PossiblyNullArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullArrayAccess.php',
        'Psalm\\Issue\\PossiblyNullArrayAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullArrayAssignment.php',
        'Psalm\\Issue\\PossiblyNullArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullArrayOffset.php',
        'Psalm\\Issue\\PossiblyNullFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullFunctionCall.php',
        'Psalm\\Issue\\PossiblyNullIterator' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullIterator.php',
        'Psalm\\Issue\\PossiblyNullOperand' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullOperand.php',
        'Psalm\\Issue\\PossiblyNullPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullPropertyAssignment.php',
        'Psalm\\Issue\\PossiblyNullPropertyAssignmentValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullPropertyAssignmentValue.php',
        'Psalm\\Issue\\PossiblyNullPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullPropertyFetch.php',
        'Psalm\\Issue\\PossiblyNullReference' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyNullReference.php',
        'Psalm\\Issue\\PossiblyUndefinedArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUndefinedArrayOffset.php',
        'Psalm\\Issue\\PossiblyUndefinedGlobalVariable' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUndefinedGlobalVariable.php',
        'Psalm\\Issue\\PossiblyUndefinedIntArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUndefinedIntArrayOffset.php',
        'Psalm\\Issue\\PossiblyUndefinedMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUndefinedMethod.php',
        'Psalm\\Issue\\PossiblyUndefinedStringArrayOffset' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUndefinedStringArrayOffset.php',
        'Psalm\\Issue\\PossiblyUndefinedVariable' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUndefinedVariable.php',
        'Psalm\\Issue\\PossiblyUnusedMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUnusedMethod.php',
        'Psalm\\Issue\\PossiblyUnusedParam' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUnusedParam.php',
        'Psalm\\Issue\\PossiblyUnusedProperty' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUnusedProperty.php',
        'Psalm\\Issue\\PossiblyUnusedReturnValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/PossiblyUnusedReturnValue.php',
        'Psalm\\Issue\\PropertyIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/PropertyIssue.php',
        'Psalm\\Issue\\PropertyNotSetInConstructor' => __DIR__ . '/../..' . '/src/Psalm/Issue/PropertyNotSetInConstructor.php',
        'Psalm\\Issue\\PropertyTypeCoercion' => __DIR__ . '/../..' . '/src/Psalm/Issue/PropertyTypeCoercion.php',
        'Psalm\\Issue\\PsalmInternalError' => __DIR__ . '/../..' . '/src/Psalm/Issue/PsalmInternalError.php',
        'Psalm\\Issue\\RawObjectIteration' => __DIR__ . '/../..' . '/src/Psalm/Issue/RawObjectIteration.php',
        'Psalm\\Issue\\RedundantCast' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantCast.php',
        'Psalm\\Issue\\RedundantCastGivenDocblockType' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantCastGivenDocblockType.php',
        'Psalm\\Issue\\RedundantCondition' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantCondition.php',
        'Psalm\\Issue\\RedundantConditionGivenDocblockType' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantConditionGivenDocblockType.php',
        'Psalm\\Issue\\RedundantFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantFunctionCall.php',
        'Psalm\\Issue\\RedundantFunctionCallGivenDocblockType' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantFunctionCallGivenDocblockType.php',
        'Psalm\\Issue\\RedundantIdentityWithTrue' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantIdentityWithTrue.php',
        'Psalm\\Issue\\RedundantPropertyInitializationCheck' => __DIR__ . '/../..' . '/src/Psalm/Issue/RedundantPropertyInitializationCheck.php',
        'Psalm\\Issue\\ReferenceConstraintViolation' => __DIR__ . '/../..' . '/src/Psalm/Issue/ReferenceConstraintViolation.php',
        'Psalm\\Issue\\ReferenceReusedFromConfusingScope' => __DIR__ . '/../..' . '/src/Psalm/Issue/ReferenceReusedFromConfusingScope.php',
        'Psalm\\Issue\\ReservedWord' => __DIR__ . '/../..' . '/src/Psalm/Issue/ReservedWord.php',
        'Psalm\\Issue\\RiskyCast' => __DIR__ . '/../..' . '/src/Psalm/Issue/RiskyCast.php',
        'Psalm\\Issue\\StringIncrement' => __DIR__ . '/../..' . '/src/Psalm/Issue/StringIncrement.php',
        'Psalm\\Issue\\TaintedCallable' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedCallable.php',
        'Psalm\\Issue\\TaintedCookie' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedCookie.php',
        'Psalm\\Issue\\TaintedCustom' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedCustom.php',
        'Psalm\\Issue\\TaintedEval' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedEval.php',
        'Psalm\\Issue\\TaintedFile' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedFile.php',
        'Psalm\\Issue\\TaintedHeader' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedHeader.php',
        'Psalm\\Issue\\TaintedHtml' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedHtml.php',
        'Psalm\\Issue\\TaintedInclude' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedInclude.php',
        'Psalm\\Issue\\TaintedInput' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedInput.php',
        'Psalm\\Issue\\TaintedLdap' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedLdap.php',
        'Psalm\\Issue\\TaintedSSRF' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedSSRF.php',
        'Psalm\\Issue\\TaintedShell' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedShell.php',
        'Psalm\\Issue\\TaintedSql' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedSql.php',
        'Psalm\\Issue\\TaintedSystemSecret' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedSystemSecret.php',
        'Psalm\\Issue\\TaintedTextWithQuotes' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedTextWithQuotes.php',
        'Psalm\\Issue\\TaintedUnserialize' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedUnserialize.php',
        'Psalm\\Issue\\TaintedUserSecret' => __DIR__ . '/../..' . '/src/Psalm/Issue/TaintedUserSecret.php',
        'Psalm\\Issue\\TooFewArguments' => __DIR__ . '/../..' . '/src/Psalm/Issue/TooFewArguments.php',
        'Psalm\\Issue\\TooManyArguments' => __DIR__ . '/../..' . '/src/Psalm/Issue/TooManyArguments.php',
        'Psalm\\Issue\\TooManyTemplateParams' => __DIR__ . '/../..' . '/src/Psalm/Issue/TooManyTemplateParams.php',
        'Psalm\\Issue\\Trace' => __DIR__ . '/../..' . '/src/Psalm/Issue/Trace.php',
        'Psalm\\Issue\\TraitMethodSignatureMismatch' => __DIR__ . '/../..' . '/src/Psalm/Issue/TraitMethodSignatureMismatch.php',
        'Psalm\\Issue\\TypeDoesNotContainNull' => __DIR__ . '/../..' . '/src/Psalm/Issue/TypeDoesNotContainNull.php',
        'Psalm\\Issue\\TypeDoesNotContainType' => __DIR__ . '/../..' . '/src/Psalm/Issue/TypeDoesNotContainType.php',
        'Psalm\\Issue\\UncaughtThrowInGlobalScope' => __DIR__ . '/../..' . '/src/Psalm/Issue/UncaughtThrowInGlobalScope.php',
        'Psalm\\Issue\\UndefinedAttributeClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedAttributeClass.php',
        'Psalm\\Issue\\UndefinedClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedClass.php',
        'Psalm\\Issue\\UndefinedConstant' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedConstant.php',
        'Psalm\\Issue\\UndefinedDocblockClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedDocblockClass.php',
        'Psalm\\Issue\\UndefinedFunction' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedFunction.php',
        'Psalm\\Issue\\UndefinedGlobalVariable' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedGlobalVariable.php',
        'Psalm\\Issue\\UndefinedInterface' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedInterface.php',
        'Psalm\\Issue\\UndefinedInterfaceMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedInterfaceMethod.php',
        'Psalm\\Issue\\UndefinedMagicMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedMagicMethod.php',
        'Psalm\\Issue\\UndefinedMagicPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedMagicPropertyAssignment.php',
        'Psalm\\Issue\\UndefinedMagicPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedMagicPropertyFetch.php',
        'Psalm\\Issue\\UndefinedMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedMethod.php',
        'Psalm\\Issue\\UndefinedPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedPropertyAssignment.php',
        'Psalm\\Issue\\UndefinedPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedPropertyFetch.php',
        'Psalm\\Issue\\UndefinedThisPropertyAssignment' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedThisPropertyAssignment.php',
        'Psalm\\Issue\\UndefinedThisPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedThisPropertyFetch.php',
        'Psalm\\Issue\\UndefinedTrace' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedTrace.php',
        'Psalm\\Issue\\UndefinedTrait' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedTrait.php',
        'Psalm\\Issue\\UndefinedVariable' => __DIR__ . '/../..' . '/src/Psalm/Issue/UndefinedVariable.php',
        'Psalm\\Issue\\UnevaluatedCode' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnevaluatedCode.php',
        'Psalm\\Issue\\UnhandledMatchCondition' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnhandledMatchCondition.php',
        'Psalm\\Issue\\UnimplementedAbstractMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnimplementedAbstractMethod.php',
        'Psalm\\Issue\\UnimplementedInterfaceMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnimplementedInterfaceMethod.php',
        'Psalm\\Issue\\UninitializedProperty' => __DIR__ . '/../..' . '/src/Psalm/Issue/UninitializedProperty.php',
        'Psalm\\Issue\\UnnecessaryVarAnnotation' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnnecessaryVarAnnotation.php',
        'Psalm\\Issue\\UnrecognizedExpression' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnrecognizedExpression.php',
        'Psalm\\Issue\\UnrecognizedStatement' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnrecognizedStatement.php',
        'Psalm\\Issue\\UnresolvableConstant' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnresolvableConstant.php',
        'Psalm\\Issue\\UnresolvableInclude' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnresolvableInclude.php',
        'Psalm\\Issue\\UnsafeGenericInstantiation' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnsafeGenericInstantiation.php',
        'Psalm\\Issue\\UnsafeInstantiation' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnsafeInstantiation.php',
        'Psalm\\Issue\\UnsupportedReferenceUsage' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnsupportedReferenceUsage.php',
        'Psalm\\Issue\\UnusedBaselineEntry' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedBaselineEntry.php',
        'Psalm\\Issue\\UnusedClass' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedClass.php',
        'Psalm\\Issue\\UnusedClosureParam' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedClosureParam.php',
        'Psalm\\Issue\\UnusedConstructor' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedConstructor.php',
        'Psalm\\Issue\\UnusedForeachValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedForeachValue.php',
        'Psalm\\Issue\\UnusedFunctionCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedFunctionCall.php',
        'Psalm\\Issue\\UnusedMethod' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedMethod.php',
        'Psalm\\Issue\\UnusedMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedMethodCall.php',
        'Psalm\\Issue\\UnusedParam' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedParam.php',
        'Psalm\\Issue\\UnusedProperty' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedProperty.php',
        'Psalm\\Issue\\UnusedPsalmSuppress' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedPsalmSuppress.php',
        'Psalm\\Issue\\UnusedReturnValue' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedReturnValue.php',
        'Psalm\\Issue\\UnusedVariable' => __DIR__ . '/../..' . '/src/Psalm/Issue/UnusedVariable.php',
        'Psalm\\Issue\\VariableIssue' => __DIR__ . '/../..' . '/src/Psalm/Issue/VariableIssue.php',
        'Psalm\\NodeTypeProvider' => __DIR__ . '/../..' . '/src/Psalm/NodeTypeProvider.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualBitwiseAnd' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualBitwiseAnd.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualBitwiseOr' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualBitwiseOr.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualBitwiseXor' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualBitwiseXor.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualCoalesce' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualCoalesce.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualConcat' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualConcat.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualDiv' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualDiv.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualMinus' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualMinus.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualMod' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualMod.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualMul' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualMul.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualPlus' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualPlus.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualPow' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualPow.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualShiftLeft' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualShiftLeft.php',
        'Psalm\\Node\\Expr\\AssignOp\\VirtualShiftRight' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/AssignOp/VirtualShiftRight.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualBitwiseAnd' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseAnd.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualBitwiseOr' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseOr.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualBitwiseXor' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualBitwiseXor.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualBooleanAnd' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualBooleanAnd.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualBooleanOr' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualBooleanOr.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualCoalesce' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualCoalesce.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualConcat' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualConcat.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualDiv' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualDiv.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualEqual' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualEqual.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualGreater' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualGreater.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualGreaterOrEqual' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualGreaterOrEqual.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualIdentical' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualIdentical.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualLogicalAnd' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualLogicalAnd.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualLogicalOr' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualLogicalOr.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualLogicalXor' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualLogicalXor.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualMinus' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualMinus.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualMod' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualMod.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualMul' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualMul.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualNotEqual' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualNotEqual.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualNotIdentical' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualNotIdentical.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualPlus' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualPlus.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualPow' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualPow.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualShiftLeft' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualShiftLeft.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualShiftRight' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualShiftRight.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualSmaller' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualSmaller.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualSmallerOrEqual' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualSmallerOrEqual.php',
        'Psalm\\Node\\Expr\\BinaryOp\\VirtualSpaceship' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/BinaryOp/VirtualSpaceship.php',
        'Psalm\\Node\\Expr\\Cast\\VirtualArray' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/Cast/VirtualArray.php',
        'Psalm\\Node\\Expr\\Cast\\VirtualBool' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/Cast/VirtualBool.php',
        'Psalm\\Node\\Expr\\Cast\\VirtualDouble' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/Cast/VirtualDouble.php',
        'Psalm\\Node\\Expr\\Cast\\VirtualInt' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/Cast/VirtualInt.php',
        'Psalm\\Node\\Expr\\Cast\\VirtualObject' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/Cast/VirtualObject.php',
        'Psalm\\Node\\Expr\\Cast\\VirtualString' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/Cast/VirtualString.php',
        'Psalm\\Node\\Expr\\Cast\\VirtualUnset' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/Cast/VirtualUnset.php',
        'Psalm\\Node\\Expr\\VirtualArray' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualArray.php',
        'Psalm\\Node\\Expr\\VirtualArrayDimFetch' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualArrayDimFetch.php',
        'Psalm\\Node\\Expr\\VirtualArrayItem' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualArrayItem.php',
        'Psalm\\Node\\Expr\\VirtualArrowFunction' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualArrowFunction.php',
        'Psalm\\Node\\Expr\\VirtualAssign' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualAssign.php',
        'Psalm\\Node\\Expr\\VirtualAssignRef' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualAssignRef.php',
        'Psalm\\Node\\Expr\\VirtualBitwiseNot' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualBitwiseNot.php',
        'Psalm\\Node\\Expr\\VirtualBooleanNot' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualBooleanNot.php',
        'Psalm\\Node\\Expr\\VirtualClassConstFetch' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualClassConstFetch.php',
        'Psalm\\Node\\Expr\\VirtualClone' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualClone.php',
        'Psalm\\Node\\Expr\\VirtualClosure' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualClosure.php',
        'Psalm\\Node\\Expr\\VirtualClosureUse' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualClosureUse.php',
        'Psalm\\Node\\Expr\\VirtualConstFetch' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualConstFetch.php',
        'Psalm\\Node\\Expr\\VirtualEmpty' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualEmpty.php',
        'Psalm\\Node\\Expr\\VirtualError' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualError.php',
        'Psalm\\Node\\Expr\\VirtualErrorSuppress' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualErrorSuppress.php',
        'Psalm\\Node\\Expr\\VirtualEval' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualEval.php',
        'Psalm\\Node\\Expr\\VirtualExit' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualExit.php',
        'Psalm\\Node\\Expr\\VirtualFuncCall' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualFuncCall.php',
        'Psalm\\Node\\Expr\\VirtualInclude' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualInclude.php',
        'Psalm\\Node\\Expr\\VirtualInstanceof' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualInstanceof.php',
        'Psalm\\Node\\Expr\\VirtualIsset' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualIsset.php',
        'Psalm\\Node\\Expr\\VirtualList' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualList.php',
        'Psalm\\Node\\Expr\\VirtualMatch' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualMatch.php',
        'Psalm\\Node\\Expr\\VirtualMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualMethodCall.php',
        'Psalm\\Node\\Expr\\VirtualNew' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualNew.php',
        'Psalm\\Node\\Expr\\VirtualNullsafeMethodCall' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualNullsafeMethodCall.php',
        'Psalm\\Node\\Expr\\VirtualNullsafePropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualNullsafePropertyFetch.php',
        'Psalm\\Node\\Expr\\VirtualPostDec' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualPostDec.php',
        'Psalm\\Node\\Expr\\VirtualPostInc' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualPostInc.php',
        'Psalm\\Node\\Expr\\VirtualPreDec' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualPreDec.php',
        'Psalm\\Node\\Expr\\VirtualPreInc' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualPreInc.php',
        'Psalm\\Node\\Expr\\VirtualPrint' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualPrint.php',
        'Psalm\\Node\\Expr\\VirtualPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualPropertyFetch.php',
        'Psalm\\Node\\Expr\\VirtualShellExec' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualShellExec.php',
        'Psalm\\Node\\Expr\\VirtualStaticCall' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualStaticCall.php',
        'Psalm\\Node\\Expr\\VirtualStaticPropertyFetch' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualStaticPropertyFetch.php',
        'Psalm\\Node\\Expr\\VirtualTernary' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualTernary.php',
        'Psalm\\Node\\Expr\\VirtualThrow' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualThrow.php',
        'Psalm\\Node\\Expr\\VirtualUnaryMinus' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualUnaryMinus.php',
        'Psalm\\Node\\Expr\\VirtualUnaryPlus' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualUnaryPlus.php',
        'Psalm\\Node\\Expr\\VirtualVariable' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualVariable.php',
        'Psalm\\Node\\Expr\\VirtualYield' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualYield.php',
        'Psalm\\Node\\Expr\\VirtualYieldFrom' => __DIR__ . '/../..' . '/src/Psalm/Node/Expr/VirtualYieldFrom.php',
        'Psalm\\Node\\Name\\VirtualFullyQualified' => __DIR__ . '/../..' . '/src/Psalm/Node/Name/VirtualFullyQualified.php',
        'Psalm\\Node\\Name\\VirtualRelative' => __DIR__ . '/../..' . '/src/Psalm/Node/Name/VirtualRelative.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualClass' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualClass.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualDir' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualDir.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualFile' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualFile.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualFunction' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualFunction.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualLine' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualLine.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualMethod' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualMethod.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualNamespace' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualNamespace.php',
        'Psalm\\Node\\Scalar\\MagicConst\\VirtualTrait' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/MagicConst/VirtualTrait.php',
        'Psalm\\Node\\Scalar\\VirtualDNumber' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/VirtualDNumber.php',
        'Psalm\\Node\\Scalar\\VirtualEncapsed' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/VirtualEncapsed.php',
        'Psalm\\Node\\Scalar\\VirtualEncapsedStringPart' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/VirtualEncapsedStringPart.php',
        'Psalm\\Node\\Scalar\\VirtualLNumber' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/VirtualLNumber.php',
        'Psalm\\Node\\Scalar\\VirtualString' => __DIR__ . '/../..' . '/src/Psalm/Node/Scalar/VirtualString.php',
        'Psalm\\Node\\Stmt\\TraitUseAdaptation\\VirtualAlias' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/TraitUseAdaptation/VirtualAlias.php',
        'Psalm\\Node\\Stmt\\TraitUseAdaptation\\VirtualPrecedence' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/TraitUseAdaptation/VirtualPrecedence.php',
        'Psalm\\Node\\Stmt\\VirtualBreak' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualBreak.php',
        'Psalm\\Node\\Stmt\\VirtualCase' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualCase.php',
        'Psalm\\Node\\Stmt\\VirtualCatch' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualCatch.php',
        'Psalm\\Node\\Stmt\\VirtualClass' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualClass.php',
        'Psalm\\Node\\Stmt\\VirtualClassConst' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualClassConst.php',
        'Psalm\\Node\\Stmt\\VirtualClassMethod' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualClassMethod.php',
        'Psalm\\Node\\Stmt\\VirtualConst' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualConst.php',
        'Psalm\\Node\\Stmt\\VirtualContinue' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualContinue.php',
        'Psalm\\Node\\Stmt\\VirtualDeclare' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualDeclare.php',
        'Psalm\\Node\\Stmt\\VirtualDeclareDeclare' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualDeclareDeclare.php',
        'Psalm\\Node\\Stmt\\VirtualDo' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualDo.php',
        'Psalm\\Node\\Stmt\\VirtualEcho' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualEcho.php',
        'Psalm\\Node\\Stmt\\VirtualElse' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualElse.php',
        'Psalm\\Node\\Stmt\\VirtualElseIf' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualElseIf.php',
        'Psalm\\Node\\Stmt\\VirtualExpression' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualExpression.php',
        'Psalm\\Node\\Stmt\\VirtualFinally' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualFinally.php',
        'Psalm\\Node\\Stmt\\VirtualFor' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualFor.php',
        'Psalm\\Node\\Stmt\\VirtualForeach' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualForeach.php',
        'Psalm\\Node\\Stmt\\VirtualFunction' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualFunction.php',
        'Psalm\\Node\\Stmt\\VirtualGlobal' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualGlobal.php',
        'Psalm\\Node\\Stmt\\VirtualGoto' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualGoto.php',
        'Psalm\\Node\\Stmt\\VirtualGroupUse' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualGroupUse.php',
        'Psalm\\Node\\Stmt\\VirtualHaltCompiler' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualHaltCompiler.php',
        'Psalm\\Node\\Stmt\\VirtualIf' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualIf.php',
        'Psalm\\Node\\Stmt\\VirtualInlineHTML' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualInlineHTML.php',
        'Psalm\\Node\\Stmt\\VirtualInterface' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualInterface.php',
        'Psalm\\Node\\Stmt\\VirtualLabel' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualLabel.php',
        'Psalm\\Node\\Stmt\\VirtualNamespace' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualNamespace.php',
        'Psalm\\Node\\Stmt\\VirtualNop' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualNop.php',
        'Psalm\\Node\\Stmt\\VirtualProperty' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualProperty.php',
        'Psalm\\Node\\Stmt\\VirtualPropertyProperty' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualPropertyProperty.php',
        'Psalm\\Node\\Stmt\\VirtualReturn' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualReturn.php',
        'Psalm\\Node\\Stmt\\VirtualStatic' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualStatic.php',
        'Psalm\\Node\\Stmt\\VirtualStaticVar' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualStaticVar.php',
        'Psalm\\Node\\Stmt\\VirtualSwitch' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualSwitch.php',
        'Psalm\\Node\\Stmt\\VirtualThrow' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualThrow.php',
        'Psalm\\Node\\Stmt\\VirtualTrait' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualTrait.php',
        'Psalm\\Node\\Stmt\\VirtualTraitUse' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualTraitUse.php',
        'Psalm\\Node\\Stmt\\VirtualTryCatch' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualTryCatch.php',
        'Psalm\\Node\\Stmt\\VirtualUnset' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualUnset.php',
        'Psalm\\Node\\Stmt\\VirtualUse' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualUse.php',
        'Psalm\\Node\\Stmt\\VirtualUseUse' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualUseUse.php',
        'Psalm\\Node\\Stmt\\VirtualWhile' => __DIR__ . '/../..' . '/src/Psalm/Node/Stmt/VirtualWhile.php',
        'Psalm\\Node\\VirtualArg' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualArg.php',
        'Psalm\\Node\\VirtualAttribute' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualAttribute.php',
        'Psalm\\Node\\VirtualAttributeGroup' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualAttributeGroup.php',
        'Psalm\\Node\\VirtualConst' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualConst.php',
        'Psalm\\Node\\VirtualIdentifier' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualIdentifier.php',
        'Psalm\\Node\\VirtualMatchArm' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualMatchArm.php',
        'Psalm\\Node\\VirtualName' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualName.php',
        'Psalm\\Node\\VirtualNode' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualNode.php',
        'Psalm\\Node\\VirtualNullableType' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualNullableType.php',
        'Psalm\\Node\\VirtualParam' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualParam.php',
        'Psalm\\Node\\VirtualUnionType' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualUnionType.php',
        'Psalm\\Node\\VirtualVarLikeIdentifier' => __DIR__ . '/../..' . '/src/Psalm/Node/VirtualVarLikeIdentifier.php',
        'Psalm\\PluginFileExtensionsSocket' => __DIR__ . '/../..' . '/src/Psalm/PluginFileExtensionsSocket.php',
        'Psalm\\PluginRegistrationSocket' => __DIR__ . '/../..' . '/src/Psalm/PluginRegistrationSocket.php',
        'Psalm\\Plugin\\ArgTypeInferer' => __DIR__ . '/../..' . '/src/Psalm/Plugin/ArgTypeInferer.php',
        'Psalm\\Plugin\\DynamicFunctionStorage' => __DIR__ . '/../..' . '/src/Psalm/Plugin/DynamicFunctionStorage.php',
        'Psalm\\Plugin\\DynamicTemplateProvider' => __DIR__ . '/../..' . '/src/Psalm/Plugin/DynamicTemplateProvider.php',
        'Psalm\\Plugin\\EventHandler\\AddTaintsInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AddTaintsInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterClassLikeAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterClassLikeAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterClassLikeExistenceCheckInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterClassLikeExistenceCheckInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterClassLikeVisitInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterClassLikeVisitInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterCodebasePopulatedInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterCodebasePopulatedInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterEveryFunctionCallAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterEveryFunctionCallAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterExpressionAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterExpressionAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterFileAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterFileAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterFunctionCallAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterFunctionCallAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterFunctionLikeAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterFunctionLikeAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterMethodCallAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterMethodCallAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\AfterStatementAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/AfterStatementAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\BeforeAddIssueInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/BeforeAddIssueInterface.php',
        'Psalm\\Plugin\\EventHandler\\BeforeFileAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/BeforeFileAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\BeforeStatementAnalysisInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/BeforeStatementAnalysisInterface.php',
        'Psalm\\Plugin\\EventHandler\\DynamicFunctionStorageProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/DynamicFunctionStorageProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AddRemoveTaintsEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AddRemoveTaintsEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterClassLikeAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterClassLikeAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterClassLikeExistenceCheckEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterClassLikeExistenceCheckEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterClassLikeVisitEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterClassLikeVisitEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterCodebasePopulatedEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterCodebasePopulatedEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterEveryFunctionCallAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterEveryFunctionCallAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterExpressionAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterExpressionAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterFileAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterFileAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterFunctionCallAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterFunctionCallAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterFunctionLikeAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterFunctionLikeAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterMethodCallAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterMethodCallAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\AfterStatementAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/AfterStatementAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\BeforeAddIssueEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/BeforeAddIssueEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\BeforeFileAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/BeforeFileAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\BeforeStatementAnalysisEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/BeforeStatementAnalysisEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\DynamicFunctionStorageProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/DynamicFunctionStorageProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\FunctionExistenceProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/FunctionExistenceProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\FunctionParamsProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/FunctionParamsProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\FunctionReturnTypeProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/FunctionReturnTypeProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\MethodExistenceProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/MethodExistenceProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\MethodParamsProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/MethodParamsProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\MethodReturnTypeProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/MethodReturnTypeProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\MethodVisibilityProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/MethodVisibilityProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\PropertyExistenceProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/PropertyExistenceProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\PropertyTypeProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/PropertyTypeProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\PropertyVisibilityProviderEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/PropertyVisibilityProviderEvent.php',
        'Psalm\\Plugin\\EventHandler\\Event\\StringInterpreterEvent' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/Event/StringInterpreterEvent.php',
        'Psalm\\Plugin\\EventHandler\\FunctionExistenceProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/FunctionExistenceProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\FunctionParamsProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/FunctionParamsProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\FunctionReturnTypeProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/FunctionReturnTypeProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\MethodExistenceProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/MethodExistenceProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\MethodParamsProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/MethodParamsProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\MethodReturnTypeProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/MethodReturnTypeProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\MethodVisibilityProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/MethodVisibilityProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\PropertyExistenceProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/PropertyExistenceProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\PropertyTypeProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/PropertyTypeProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\PropertyVisibilityProviderInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/PropertyVisibilityProviderInterface.php',
        'Psalm\\Plugin\\EventHandler\\RemoveTaintsInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/RemoveTaintsInterface.php',
        'Psalm\\Plugin\\EventHandler\\StringInterpreterInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/EventHandler/StringInterpreterInterface.php',
        'Psalm\\Plugin\\FileExtensionsInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/FileExtensionsInterface.php',
        'Psalm\\Plugin\\PluginEntryPointInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/PluginEntryPointInterface.php',
        'Psalm\\Plugin\\PluginFileExtensionsInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/PluginFileExtensionsInterface.php',
        'Psalm\\Plugin\\PluginInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/PluginInterface.php',
        'Psalm\\Plugin\\RegistrationInterface' => __DIR__ . '/../..' . '/src/Psalm/Plugin/RegistrationInterface.php',
        'Psalm\\Plugin\\Shepherd' => __DIR__ . '/../..' . '/src/Psalm/Plugin/Shepherd.php',
        'Psalm\\Progress\\DebugProgress' => __DIR__ . '/../..' . '/src/Psalm/Progress/DebugProgress.php',
        'Psalm\\Progress\\DefaultProgress' => __DIR__ . '/../..' . '/src/Psalm/Progress/DefaultProgress.php',
        'Psalm\\Progress\\LongProgress' => __DIR__ . '/../..' . '/src/Psalm/Progress/LongProgress.php',
        'Psalm\\Progress\\Progress' => __DIR__ . '/../..' . '/src/Psalm/Progress/Progress.php',
        'Psalm\\Progress\\VoidProgress' => __DIR__ . '/../..' . '/src/Psalm/Progress/VoidProgress.php',
        'Psalm\\Report' => __DIR__ . '/../..' . '/src/Psalm/Report.php',
        'Psalm\\Report\\ByIssueLevelAndTypeReport' => __DIR__ . '/../..' . '/src/Psalm/Report/ByIssueLevelAndTypeReport.php',
        'Psalm\\Report\\CheckstyleReport' => __DIR__ . '/../..' . '/src/Psalm/Report/CheckstyleReport.php',
        'Psalm\\Report\\CodeClimateReport' => __DIR__ . '/../..' . '/src/Psalm/Report/CodeClimateReport.php',
        'Psalm\\Report\\CompactReport' => __DIR__ . '/../..' . '/src/Psalm/Report/CompactReport.php',
        'Psalm\\Report\\ConsoleReport' => __DIR__ . '/../..' . '/src/Psalm/Report/ConsoleReport.php',
        'Psalm\\Report\\CountReport' => __DIR__ . '/../..' . '/src/Psalm/Report/CountReport.php',
        'Psalm\\Report\\EmacsReport' => __DIR__ . '/../..' . '/src/Psalm/Report/EmacsReport.php',
        'Psalm\\Report\\GithubActionsReport' => __DIR__ . '/../..' . '/src/Psalm/Report/GithubActionsReport.php',
        'Psalm\\Report\\JsonReport' => __DIR__ . '/../..' . '/src/Psalm/Report/JsonReport.php',
        'Psalm\\Report\\JsonSummaryReport' => __DIR__ . '/../..' . '/src/Psalm/Report/JsonSummaryReport.php',
        'Psalm\\Report\\JunitReport' => __DIR__ . '/../..' . '/src/Psalm/Report/JunitReport.php',
        'Psalm\\Report\\PhpStormReport' => __DIR__ . '/../..' . '/src/Psalm/Report/PhpStormReport.php',
        'Psalm\\Report\\PylintReport' => __DIR__ . '/../..' . '/src/Psalm/Report/PylintReport.php',
        'Psalm\\Report\\ReportOptions' => __DIR__ . '/../..' . '/src/Psalm/Report/ReportOptions.php',
        'Psalm\\Report\\SarifReport' => __DIR__ . '/../..' . '/src/Psalm/Report/SarifReport.php',
        'Psalm\\Report\\SonarqubeReport' => __DIR__ . '/../..' . '/src/Psalm/Report/SonarqubeReport.php',
        'Psalm\\Report\\TextReport' => __DIR__ . '/../..' . '/src/Psalm/Report/TextReport.php',
        'Psalm\\Report\\XmlReport' => __DIR__ . '/../..' . '/src/Psalm/Report/XmlReport.php',
        'Psalm\\SourceControl\\Git\\CommitInfo' => __DIR__ . '/../..' . '/src/Psalm/SourceControl/Git/CommitInfo.php',
        'Psalm\\SourceControl\\Git\\GitInfo' => __DIR__ . '/../..' . '/src/Psalm/SourceControl/Git/GitInfo.php',
        'Psalm\\SourceControl\\Git\\RemoteInfo' => __DIR__ . '/../..' . '/src/Psalm/SourceControl/Git/RemoteInfo.php',
        'Psalm\\SourceControl\\SourceControlInfo' => __DIR__ . '/../..' . '/src/Psalm/SourceControl/SourceControlInfo.php',
        'Psalm\\StatementsSource' => __DIR__ . '/../..' . '/src/Psalm/StatementsSource.php',
        'Psalm\\Storage\\Assertion' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion.php',
        'Psalm\\Storage\\Assertion\\Any' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/Any.php',
        'Psalm\\Storage\\Assertion\\ArrayKeyDoesNotExist' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/ArrayKeyDoesNotExist.php',
        'Psalm\\Storage\\Assertion\\ArrayKeyExists' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/ArrayKeyExists.php',
        'Psalm\\Storage\\Assertion\\DoesNotHaveAtLeastCount' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/DoesNotHaveAtLeastCount.php',
        'Psalm\\Storage\\Assertion\\DoesNotHaveExactCount' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/DoesNotHaveExactCount.php',
        'Psalm\\Storage\\Assertion\\DoesNotHaveMethod' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/DoesNotHaveMethod.php',
        'Psalm\\Storage\\Assertion\\Empty_' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/Empty_.php',
        'Psalm\\Storage\\Assertion\\Falsy' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/Falsy.php',
        'Psalm\\Storage\\Assertion\\HasArrayKey' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/HasArrayKey.php',
        'Psalm\\Storage\\Assertion\\HasAtLeastCount' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/HasAtLeastCount.php',
        'Psalm\\Storage\\Assertion\\HasExactCount' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/HasExactCount.php',
        'Psalm\\Storage\\Assertion\\HasIntOrStringArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/HasIntOrStringArrayAccess.php',
        'Psalm\\Storage\\Assertion\\HasMethod' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/HasMethod.php',
        'Psalm\\Storage\\Assertion\\HasStringArrayAccess' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/HasStringArrayAccess.php',
        'Psalm\\Storage\\Assertion\\InArray' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/InArray.php',
        'Psalm\\Storage\\Assertion\\IsAClass' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsAClass.php',
        'Psalm\\Storage\\Assertion\\IsClassEqual' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsClassEqual.php',
        'Psalm\\Storage\\Assertion\\IsClassNotEqual' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsClassNotEqual.php',
        'Psalm\\Storage\\Assertion\\IsCountable' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsCountable.php',
        'Psalm\\Storage\\Assertion\\IsEqualIsset' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsEqualIsset.php',
        'Psalm\\Storage\\Assertion\\IsGreaterThan' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsGreaterThan.php',
        'Psalm\\Storage\\Assertion\\IsGreaterThanOrEqualTo' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsGreaterThanOrEqualTo.php',
        'Psalm\\Storage\\Assertion\\IsIdentical' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsIdentical.php',
        'Psalm\\Storage\\Assertion\\IsIsset' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsIsset.php',
        'Psalm\\Storage\\Assertion\\IsLessThan' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsLessThan.php',
        'Psalm\\Storage\\Assertion\\IsLessThanOrEqualTo' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsLessThanOrEqualTo.php',
        'Psalm\\Storage\\Assertion\\IsLooselyEqual' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsLooselyEqual.php',
        'Psalm\\Storage\\Assertion\\IsNotAClass' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsNotAClass.php',
        'Psalm\\Storage\\Assertion\\IsNotCountable' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsNotCountable.php',
        'Psalm\\Storage\\Assertion\\IsNotIdentical' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsNotIdentical.php',
        'Psalm\\Storage\\Assertion\\IsNotIsset' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsNotIsset.php',
        'Psalm\\Storage\\Assertion\\IsNotLooselyEqual' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsNotLooselyEqual.php',
        'Psalm\\Storage\\Assertion\\IsNotType' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsNotType.php',
        'Psalm\\Storage\\Assertion\\IsType' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/IsType.php',
        'Psalm\\Storage\\Assertion\\NestedAssertions' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/NestedAssertions.php',
        'Psalm\\Storage\\Assertion\\NonEmpty' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/NonEmpty.php',
        'Psalm\\Storage\\Assertion\\NonEmptyCountable' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/NonEmptyCountable.php',
        'Psalm\\Storage\\Assertion\\NotInArray' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/NotInArray.php',
        'Psalm\\Storage\\Assertion\\NotNestedAssertions' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/NotNestedAssertions.php',
        'Psalm\\Storage\\Assertion\\NotNonEmptyCountable' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/NotNonEmptyCountable.php',
        'Psalm\\Storage\\Assertion\\Truthy' => __DIR__ . '/../..' . '/src/Psalm/Storage/Assertion/Truthy.php',
        'Psalm\\Storage\\AttributeArg' => __DIR__ . '/../..' . '/src/Psalm/Storage/AttributeArg.php',
        'Psalm\\Storage\\AttributeStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/AttributeStorage.php',
        'Psalm\\Storage\\ClassConstantStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/ClassConstantStorage.php',
        'Psalm\\Storage\\ClassLikeStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/ClassLikeStorage.php',
        'Psalm\\Storage\\CustomMetadataTrait' => __DIR__ . '/../..' . '/src/Psalm/Storage/CustomMetadataTrait.php',
        'Psalm\\Storage\\EnumCaseStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/EnumCaseStorage.php',
        'Psalm\\Storage\\FileStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/FileStorage.php',
        'Psalm\\Storage\\FunctionLikeParameter' => __DIR__ . '/../..' . '/src/Psalm/Storage/FunctionLikeParameter.php',
        'Psalm\\Storage\\FunctionLikeStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/FunctionLikeStorage.php',
        'Psalm\\Storage\\FunctionStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/FunctionStorage.php',
        'Psalm\\Storage\\HasAttributesInterface' => __DIR__ . '/../..' . '/src/Psalm/Storage/HasAttributesInterface.php',
        'Psalm\\Storage\\ImmutableNonCloneableTrait' => __DIR__ . '/../..' . '/src/Psalm/Storage/ImmutableNonCloneableTrait.php',
        'Psalm\\Storage\\MethodStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/MethodStorage.php',
        'Psalm\\Storage\\Possibilities' => __DIR__ . '/../..' . '/src/Psalm/Storage/Possibilities.php',
        'Psalm\\Storage\\PropertyStorage' => __DIR__ . '/../..' . '/src/Psalm/Storage/PropertyStorage.php',
        'Psalm\\Type' => __DIR__ . '/../..' . '/src/Psalm/Type.php',
        'Psalm\\Type\\Atomic' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic.php',
        'Psalm\\Type\\Atomic\\CallableTrait' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/CallableTrait.php',
        'Psalm\\Type\\Atomic\\DependentType' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/DependentType.php',
        'Psalm\\Type\\Atomic\\GenericTrait' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/GenericTrait.php',
        'Psalm\\Type\\Atomic\\HasIntersectionTrait' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/HasIntersectionTrait.php',
        'Psalm\\Type\\Atomic\\Scalar' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/Scalar.php',
        'Psalm\\Type\\Atomic\\TAnonymousClassInstance' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TAnonymousClassInstance.php',
        'Psalm\\Type\\Atomic\\TArray' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TArray.php',
        'Psalm\\Type\\Atomic\\TArrayKey' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TArrayKey.php',
        'Psalm\\Type\\Atomic\\TBool' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TBool.php',
        'Psalm\\Type\\Atomic\\TCallable' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TCallable.php',
        'Psalm\\Type\\Atomic\\TCallableArray' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TCallableArray.php',
        'Psalm\\Type\\Atomic\\TCallableKeyedArray' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TCallableKeyedArray.php',
        'Psalm\\Type\\Atomic\\TCallableList' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TCallableList.php',
        'Psalm\\Type\\Atomic\\TCallableObject' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TCallableObject.php',
        'Psalm\\Type\\Atomic\\TCallableString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TCallableString.php',
        'Psalm\\Type\\Atomic\\TClassConstant' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TClassConstant.php',
        'Psalm\\Type\\Atomic\\TClassString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TClassString.php',
        'Psalm\\Type\\Atomic\\TClassStringMap' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TClassStringMap.php',
        'Psalm\\Type\\Atomic\\TClosedResource' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TClosedResource.php',
        'Psalm\\Type\\Atomic\\TClosure' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TClosure.php',
        'Psalm\\Type\\Atomic\\TConditional' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TConditional.php',
        'Psalm\\Type\\Atomic\\TDependentGetClass' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TDependentGetClass.php',
        'Psalm\\Type\\Atomic\\TDependentGetDebugType' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TDependentGetDebugType.php',
        'Psalm\\Type\\Atomic\\TDependentGetType' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TDependentGetType.php',
        'Psalm\\Type\\Atomic\\TDependentListKey' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TDependentListKey.php',
        'Psalm\\Type\\Atomic\\TEmptyMixed' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TEmptyMixed.php',
        'Psalm\\Type\\Atomic\\TEmptyNumeric' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TEmptyNumeric.php',
        'Psalm\\Type\\Atomic\\TEmptyScalar' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TEmptyScalar.php',
        'Psalm\\Type\\Atomic\\TEnumCase' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TEnumCase.php',
        'Psalm\\Type\\Atomic\\TFalse' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TFalse.php',
        'Psalm\\Type\\Atomic\\TFloat' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TFloat.php',
        'Psalm\\Type\\Atomic\\TGenericObject' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TGenericObject.php',
        'Psalm\\Type\\Atomic\\TInt' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TInt.php',
        'Psalm\\Type\\Atomic\\TIntMask' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TIntMask.php',
        'Psalm\\Type\\Atomic\\TIntMaskOf' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TIntMaskOf.php',
        'Psalm\\Type\\Atomic\\TIntRange' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TIntRange.php',
        'Psalm\\Type\\Atomic\\TIterable' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TIterable.php',
        'Psalm\\Type\\Atomic\\TKeyOf' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TKeyOf.php',
        'Psalm\\Type\\Atomic\\TKeyedArray' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TKeyedArray.php',
        'Psalm\\Type\\Atomic\\TList' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TList.php',
        'Psalm\\Type\\Atomic\\TLiteralClassString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TLiteralClassString.php',
        'Psalm\\Type\\Atomic\\TLiteralFloat' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TLiteralFloat.php',
        'Psalm\\Type\\Atomic\\TLiteralInt' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TLiteralInt.php',
        'Psalm\\Type\\Atomic\\TLiteralString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TLiteralString.php',
        'Psalm\\Type\\Atomic\\TLowercaseString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TLowercaseString.php',
        'Psalm\\Type\\Atomic\\TMixed' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TMixed.php',
        'Psalm\\Type\\Atomic\\TNamedObject' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNamedObject.php',
        'Psalm\\Type\\Atomic\\TNever' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNever.php',
        'Psalm\\Type\\Atomic\\TNonEmptyArray' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonEmptyArray.php',
        'Psalm\\Type\\Atomic\\TNonEmptyList' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonEmptyList.php',
        'Psalm\\Type\\Atomic\\TNonEmptyLowercaseString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonEmptyLowercaseString.php',
        'Psalm\\Type\\Atomic\\TNonEmptyMixed' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonEmptyMixed.php',
        'Psalm\\Type\\Atomic\\TNonEmptyNonspecificLiteralString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonEmptyNonspecificLiteralString.php',
        'Psalm\\Type\\Atomic\\TNonEmptyScalar' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonEmptyScalar.php',
        'Psalm\\Type\\Atomic\\TNonEmptyString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonEmptyString.php',
        'Psalm\\Type\\Atomic\\TNonFalsyString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonFalsyString.php',
        'Psalm\\Type\\Atomic\\TNonspecificLiteralInt' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonspecificLiteralInt.php',
        'Psalm\\Type\\Atomic\\TNonspecificLiteralString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNonspecificLiteralString.php',
        'Psalm\\Type\\Atomic\\TNull' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNull.php',
        'Psalm\\Type\\Atomic\\TNumeric' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNumeric.php',
        'Psalm\\Type\\Atomic\\TNumericString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TNumericString.php',
        'Psalm\\Type\\Atomic\\TObject' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TObject.php',
        'Psalm\\Type\\Atomic\\TObjectWithProperties' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TObjectWithProperties.php',
        'Psalm\\Type\\Atomic\\TPropertiesOf' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TPropertiesOf.php',
        'Psalm\\Type\\Atomic\\TResource' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TResource.php',
        'Psalm\\Type\\Atomic\\TScalar' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TScalar.php',
        'Psalm\\Type\\Atomic\\TSingleLetter' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TSingleLetter.php',
        'Psalm\\Type\\Atomic\\TString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TString.php',
        'Psalm\\Type\\Atomic\\TTemplateIndexedAccess' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTemplateIndexedAccess.php',
        'Psalm\\Type\\Atomic\\TTemplateKeyOf' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTemplateKeyOf.php',
        'Psalm\\Type\\Atomic\\TTemplateParam' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTemplateParam.php',
        'Psalm\\Type\\Atomic\\TTemplateParamClass' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTemplateParamClass.php',
        'Psalm\\Type\\Atomic\\TTemplatePropertiesOf' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTemplatePropertiesOf.php',
        'Psalm\\Type\\Atomic\\TTemplateValueOf' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTemplateValueOf.php',
        'Psalm\\Type\\Atomic\\TTraitString' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTraitString.php',
        'Psalm\\Type\\Atomic\\TTrue' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTrue.php',
        'Psalm\\Type\\Atomic\\TTypeAlias' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TTypeAlias.php',
        'Psalm\\Type\\Atomic\\TValueOf' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TValueOf.php',
        'Psalm\\Type\\Atomic\\TVoid' => __DIR__ . '/../..' . '/src/Psalm/Type/Atomic/TVoid.php',
        'Psalm\\Type\\MutableTypeVisitor' => __DIR__ . '/../..' . '/src/Psalm/Type/MutableTypeVisitor.php',
        'Psalm\\Type\\MutableUnion' => __DIR__ . '/../..' . '/src/Psalm/Type/MutableUnion.php',
        'Psalm\\Type\\Reconciler' => __DIR__ . '/../..' . '/src/Psalm/Type/Reconciler.php',
        'Psalm\\Type\\TaintKind' => __DIR__ . '/../..' . '/src/Psalm/Type/TaintKind.php',
        'Psalm\\Type\\TaintKindGroup' => __DIR__ . '/../..' . '/src/Psalm/Type/TaintKindGroup.php',
        'Psalm\\Type\\TypeNode' => __DIR__ . '/../..' . '/src/Psalm/Type/TypeNode.php',
        'Psalm\\Type\\TypeVisitor' => __DIR__ . '/../..' . '/src/Psalm/Type/TypeVisitor.php',
        'Psalm\\Type\\Union' => __DIR__ . '/../..' . '/src/Psalm/Type/Union.php',
        'Psalm\\Type\\UnionTrait' => __DIR__ . '/../..' . '/src/Psalm/Type/UnionTrait.php',
        'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Dispatcher' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/Dispatcher.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Error' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/Error.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\ErrorCode' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/ErrorCode.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\ErrorResponse' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/ErrorResponse.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Message' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/Message.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Notification' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/Notification.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Request' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/Request.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\Response' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/Response.php',
        '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\SuccessResponse' => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib/SuccessResponse.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64DecodingInputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/Base64/Base64DecodingInputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64DecodingOutputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/Base64/Base64DecodingOutputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64EncodingInputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/Base64/Base64EncodingInputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Base64\\Base64EncodingOutputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/Base64/Base64EncodingOutputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ClosedException' => __DIR__ . '/..' . '/amphp/byte-stream/lib/ClosedException.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\InMemoryStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/InMemoryStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\InputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/InputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\InputStreamChain' => __DIR__ . '/..' . '/amphp/byte-stream/lib/InputStreamChain.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\IteratorStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/IteratorStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\LineReader' => __DIR__ . '/..' . '/amphp/byte-stream/lib/LineReader.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Message' => __DIR__ . '/..' . '/amphp/byte-stream/lib/Message.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\OutputBuffer' => __DIR__ . '/..' . '/amphp/byte-stream/lib/OutputBuffer.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\OutputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/OutputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\Payload' => __DIR__ . '/..' . '/amphp/byte-stream/lib/Payload.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\PendingReadError' => __DIR__ . '/..' . '/amphp/byte-stream/lib/PendingReadError.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ResourceInputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/ResourceInputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ResourceOutputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/ResourceOutputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\StreamException' => __DIR__ . '/..' . '/amphp/byte-stream/lib/StreamException.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ZlibInputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/ZlibInputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\ZlibOutputStream' => __DIR__ . '/..' . '/amphp/byte-stream/lib/ZlibOutputStream.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\CallableMaker' => __DIR__ . '/..' . '/amphp/amp/lib/CallableMaker.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\CancellationToken' => __DIR__ . '/..' . '/amphp/amp/lib/CancellationToken.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\CancellationTokenSource' => __DIR__ . '/..' . '/amphp/amp/lib/CancellationTokenSource.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\CancelledException' => __DIR__ . '/..' . '/amphp/amp/lib/CancelledException.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\CombinedCancellationToken' => __DIR__ . '/..' . '/amphp/amp/lib/CombinedCancellationToken.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Coroutine' => __DIR__ . '/..' . '/amphp/amp/lib/Coroutine.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Deferred' => __DIR__ . '/..' . '/amphp/amp/lib/Deferred.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Delayed' => __DIR__ . '/..' . '/amphp/amp/lib/Delayed.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Emitter' => __DIR__ . '/..' . '/amphp/amp/lib/Emitter.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Failure' => __DIR__ . '/..' . '/amphp/amp/lib/Failure.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\Placeholder' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/Placeholder.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\PrivateIterator' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/PrivateIterator.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\PrivatePromise' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/PrivatePromise.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\Producer' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/Producer.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Internal\\ResolutionQueue' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/ResolutionQueue.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\InvalidYieldError' => __DIR__ . '/..' . '/amphp/amp/lib/InvalidYieldError.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Iterator' => __DIR__ . '/..' . '/amphp/amp/lib/Iterator.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\LazyPromise' => __DIR__ . '/..' . '/amphp/amp/lib/LazyPromise.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop' => __DIR__ . '/..' . '/amphp/amp/lib/Loop.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\Driver' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/Driver.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\DriverFactory' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/DriverFactory.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\EvDriver' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/EvDriver.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\EventDriver' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/EventDriver.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\Internal\\TimerQueue' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/Internal/TimerQueue.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\InvalidWatcherError' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/InvalidWatcherError.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\NativeDriver' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/NativeDriver.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\TracingDriver' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/TracingDriver.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\UnsupportedFeatureException' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/UnsupportedFeatureException.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\UvDriver' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/UvDriver.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Loop\\Watcher' => __DIR__ . '/..' . '/amphp/amp/lib/Loop/Watcher.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\MultiReasonException' => __DIR__ . '/..' . '/amphp/amp/lib/MultiReasonException.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\NullCancellationToken' => __DIR__ . '/..' . '/amphp/amp/lib/NullCancellationToken.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Producer' => __DIR__ . '/..' . '/amphp/amp/lib/Producer.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Promise' => __DIR__ . '/..' . '/amphp/amp/lib/Promise.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Struct' => __DIR__ . '/..' . '/amphp/amp/lib/Struct.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\Success' => __DIR__ . '/..' . '/amphp/amp/lib/Success.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\TimeoutCancellationToken' => __DIR__ . '/..' . '/amphp/amp/lib/TimeoutCancellationToken.php',
        '_HumbugBox1cb33d1f20f1\\Amp\\TimeoutException' => __DIR__ . '/..' . '/amphp/amp/lib/TimeoutException.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchAllResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchAllResult.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchAllStrictGroupsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchAllStrictGroupsResult.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchAllWithOffsetsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchAllWithOffsetsResult.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchResult.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchStrictGroupsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchStrictGroupsResult.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\MatchWithOffsetsResult' => __DIR__ . '/..' . '/composer/pcre/src/MatchWithOffsetsResult.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\PcreException' => __DIR__ . '/..' . '/composer/pcre/src/PcreException.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\Preg' => __DIR__ . '/..' . '/composer/pcre/src/Preg.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\Regex' => __DIR__ . '/..' . '/composer/pcre/src/Regex.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\ReplaceResult' => __DIR__ . '/..' . '/composer/pcre/src/ReplaceResult.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\UnexpectedNullMatchException' => __DIR__ . '/..' . '/composer/pcre/src/UnexpectedNullMatchException.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Comparator' => __DIR__ . '/..' . '/composer/semver/src/Comparator.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\CompilingMatcher' => __DIR__ . '/..' . '/composer/semver/src/CompilingMatcher.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\Bound' => __DIR__ . '/..' . '/composer/semver/src/Constraint/Bound.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\Constraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/Constraint.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\ConstraintInterface' => __DIR__ . '/..' . '/composer/semver/src/Constraint/ConstraintInterface.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\MatchAllConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MatchAllConstraint.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\MatchNoneConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MatchNoneConstraint.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Constraint\\MultiConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MultiConstraint.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Interval' => __DIR__ . '/..' . '/composer/semver/src/Interval.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Intervals' => __DIR__ . '/..' . '/composer/semver/src/Intervals.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\Semver' => __DIR__ . '/..' . '/composer/semver/src/Semver.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\VersionParser' => __DIR__ . '/..' . '/composer/semver/src/VersionParser.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\PhpConfig' => __DIR__ . '/..' . '/composer/xdebug-handler/src/PhpConfig.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\Process' => __DIR__ . '/..' . '/composer/xdebug-handler/src/Process.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\Status' => __DIR__ . '/..' . '/composer/xdebug-handler/src/Status.php',
        '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\XdebugHandler' => __DIR__ . '/..' . '/composer/xdebug-handler/src/XdebugHandler.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\CpuCoreCounter' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/CpuCoreCounter.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Diagnoser' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Diagnoser.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Exec\\ProcOpen' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Exec/ProcOpen.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\CpuCoreFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/CpuCoreFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\CpuInfoFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/CpuInfoFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\DummyCpuCoreFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/DummyCpuCoreFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\FinderRegistry' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/FinderRegistry.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\HwLogicalFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/HwLogicalFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\HwPhysicalFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/HwPhysicalFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\NProcFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/NProcFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\NProcessorFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/NProcessorFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\NullCpuCoreFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/NullCpuCoreFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\OnlyOnWindowsFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/OnlyOnWindowsFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\ProcOpenBasedFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/ProcOpenBasedFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\SkipOnWindowsFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/SkipOnWindowsFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\WmicLogicalFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/WmicLogicalFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\WmicPhysicalFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/WmicPhysicalFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\Finder\\_NProcessorFinder' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/Finder/_NProcessorFinder.php',
        '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\NumberOfCpuCoreNotFound' => __DIR__ . '/..' . '/fidry/cpu-core-counter/src/NumberOfCpuCoreNotFound.php',
        '_HumbugBox1cb33d1f20f1\\JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CallHierarchyClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CallHierarchyClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ChangeAnnotation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ChangeAnnotation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesGeneral' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesGeneral.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesWindow' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesWindow.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesWorkspace' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesWorkspace.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientCapabilitiesWorkspaceFileOperations' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ClientCapabilitiesWorkspaceFileOperations.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ClientInfo' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ClientInfo.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeAction' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeAction.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilitiesCodeActionLiteralSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesCodeActionLiteralSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionClientCapabilitiesResolveSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionClientCapabilitiesResolveSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionContext' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionContext.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionDisabled' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionDisabled.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeActionTriggerKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeActionTriggerKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeDescription' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeDescription.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLens' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeLens.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLensClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeLensClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLensOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeLensOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CodeLensWorkspaceClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CodeLensWorkspaceClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Command' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/Command.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItem' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItem.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItemInsertTextModeSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemInsertTextModeSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItemResolveSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemResolveSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionItemTagSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionItemTagSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionClientCapabilitiesCompletionList' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionClientCapabilitiesCompletionList.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionContext' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionContext.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItem' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionItem.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItemKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionItemKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItemLabelDetails' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionItemLabelDetails.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionItemTag' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionItemTag.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionList' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionList.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\CompletionTriggerKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/CompletionTriggerKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ContentChangeEvent' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ContentChangeEvent.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DeclarationClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DeclarationClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DefinitionClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DefinitionClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DependencyReference' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DependencyReference.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Diagnostic' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/Diagnostic.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DiagnosticRelatedInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DiagnosticRelatedInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DiagnosticSeverity' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DiagnosticSeverity.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DiagnosticTag' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DiagnosticTag.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DidChangeConfigurationClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DidChangeConfigurationClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DidChangeWatchedFilesClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DidChangeWatchedFilesClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentColorClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentColorClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentFormattingClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentFormattingClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentHighlight' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentHighlight.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentHighlightClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentHighlightClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentHighlightKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentHighlightKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentLinkClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentLinkClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentOnTypeFormattingClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentOnTypeFormattingClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentOnTypeFormattingOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentOnTypeFormattingOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentRangeFormattingClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentRangeFormattingClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentSymbolClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentSymbolClientCapabilitiesSymbolKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilitiesSymbolKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\DocumentSymbolClientCapabilitiesTagSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/DocumentSymbolClientCapabilitiesTagSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ErrorCode' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ErrorCode.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ExecuteCommandClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ExecuteCommandClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ExecuteCommandOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ExecuteCommandOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FailureHandlingKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/FailureHandlingKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FileChangeType' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/FileChangeType.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FileEvent' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/FileEvent.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FoldingRangeClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/FoldingRangeClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\FormattingOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/FormattingOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Hover' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/Hover.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\HoverClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/HoverClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ImplementationClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ImplementationClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InitializeResult' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/InitializeResult.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InitializeResultServerInfo' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/InitializeResultServerInfo.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InsertTextFormat' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/InsertTextFormat.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\InsertTextMode' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/InsertTextMode.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\LinkedEditingRangeClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/LinkedEditingRangeClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Location' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/Location.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\LogMessage' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/LogMessage.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\LogTrace' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/LogTrace.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkdownClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/MarkdownClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkedString' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/MarkedString.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkupContent' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/MarkupContent.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MarkupKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/MarkupKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MessageActionItem' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/MessageActionItem.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MessageType' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/MessageType.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\MonikerClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/MonikerClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PackageDescriptor' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/PackageDescriptor.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ParameterInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ParameterInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Position' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/Position.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PrepareSupportDefaultBehavior' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/PrepareSupportDefaultBehavior.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PublishDiagnosticsClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/PublishDiagnosticsClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\PublishDiagnosticsClientCapabilitiesTagSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/PublishDiagnosticsClientCapabilitiesTagSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\Range' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/Range.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ReferenceClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ReferenceClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ReferenceContext' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ReferenceContext.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ReferenceInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ReferenceInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\RegularExpressionsClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/RegularExpressionsClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\RenameClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/RenameClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ResourceOperationKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ResourceOperationKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SaveOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SaveOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SelectionRangeClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SelectionRangeClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SemanticTokensClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SemanticTokensClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SemanticTokensClientCapabilitiesRequests' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SemanticTokensClientCapabilitiesRequests.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SemanticTokensWorkspaceClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SemanticTokensWorkspaceClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ServerCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ServerCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ShowDocumentClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ShowDocumentClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ShowMessageRequestClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ShowMessageRequestClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\ShowMessageRequestClientCapabilitiesMessageActionItem' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/ShowMessageRequestClientCapabilitiesMessageActionItem.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelp' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SignatureHelp.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpClientCapabilitiesSignatureInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilitiesSignatureInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpClientCapabilitiesSignatureInformationParameterInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SignatureHelpClientCapabilitiesSignatureInformationParameterInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureHelpOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SignatureHelpOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SignatureInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SignatureInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolDescriptor' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SymbolDescriptor.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SymbolInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SymbolKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolLocationInformation' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SymbolLocationInformation.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\SymbolTag' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/SymbolTag.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextDocumentClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentContentChangeEvent' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextDocumentContentChangeEvent.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentIdentifier' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextDocumentIdentifier.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentItem' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextDocumentItem.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentSyncClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextDocumentSyncClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentSyncKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextDocumentSyncKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextDocumentSyncOptions' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextDocumentSyncOptions.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TextEdit' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TextEdit.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TokenFormat' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TokenFormat.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\TypeDefinitionClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/TypeDefinitionClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\VersionedTextDocumentIdentifier' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/VersionedTextDocumentIdentifier.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceEdit' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceEdit.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceEditClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceEditClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceEditClientCapabilitiesChangeAnnotationSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceEditClientCapabilitiesChangeAnnotationSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceFolder' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceFolder.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilities' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilities.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilitiesResolveSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesResolveSupport.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilitiesSymbolKind' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesSymbolKind.php',
        '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\WorkspaceSymbolClientCapabilitiesTagSupport' => __DIR__ . '/..' . '/felixfbecker/language-server-protocol/src/WorkspaceSymbolClientCapabilitiesTagSupport.php',
        '_HumbugBox1cb33d1f20f1\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
        '_HumbugBox1cb33d1f20f1\\PackageVersions\\FallbackVersions' => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php',
        '_HumbugBox1cb33d1f20f1\\PackageVersions\\Installer' => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions/Installer.php',
        '_HumbugBox1cb33d1f20f1\\PackageVersions\\Versions' => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions/Versions.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\BuilderFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderFactory.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\BuilderHelpers' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/BuilderHelpers.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\ClassConst' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Class_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Class_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Declaration' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Declaration.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\EnumCase' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Enum_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Enum_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\FunctionLike' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Function_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Function_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Interface_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Interface_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Method' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Method.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Namespace_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Param' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Param.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Property' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Property.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\TraitUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\TraitUseAdaptation' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Trait_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Trait_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Builder\\Use_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Builder/Use_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Comment' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Comment.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Comment\\Doc' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Comment/Doc.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\ConstExprEvaluationException' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ConstExprEvaluationException.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\ConstExprEvaluator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Error' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Error.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\ErrorHandler' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ErrorHandler.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\ErrorHandler\\Collecting' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Collecting.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\ErrorHandler\\Throwing' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\DiffElem' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Internal/DiffElem.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\Differ' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Internal/Differ.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\PrintableNewAnonClassNode' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Internal\\TokenStream' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\JsonDecoder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/JsonDecoder.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\Emulative' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\AttributeEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\CoaleseEqualTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/CoaleseEqualTokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\EnumTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/EnumTokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ExplicitOctalEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ExplicitOctalEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\FlexibleDocStringEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FlexibleDocStringEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\FnTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\KeywordEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\MatchTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\NullsafeTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NullsafeTokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\NumericLiteralSeparatorEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/NumericLiteralSeparatorEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyFunctionTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ReadonlyTokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyTokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\ReverseEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Lexer\\TokenEmulator\\TokenEmulator' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NameContext' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NameContext.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeAbstract.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeDumper' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeDumper.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeFinder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeFinder.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeTraverser' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeTraverser.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeTraverserInterface' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitorAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\CloningVisitor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\FindingVisitor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\FirstFindingVisitor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\NameResolver' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\NodeConnectingVisitor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor/NodeConnectingVisitor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\NodeVisitor\\ParentConnectingVisitor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/NodeVisitor/ParentConnectingVisitor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Arg' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Arg.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Attribute' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Attribute.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\AttributeGroup' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/AttributeGroup.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\ComplexType' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/ComplexType.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Const_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Const_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ArrayDimFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ArrayItem' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Array_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ArrowFunction' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Assign' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseOr.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\BitwiseXor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseXor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Coalesce' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Coalesce.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Concat' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Concat.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Div' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Div.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Minus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Minus.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Mod' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mod.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Mul' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Mul.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Plus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Plus.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\Pow' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/Pow.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\ShiftLeft' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftLeft.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignOp\\ShiftRight' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/ShiftRight.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\AssignRef' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/AssignRef.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseOr.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BitwiseXor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseXor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanAnd.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\BooleanOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BooleanOr.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Coalesce' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Coalesce.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Concat' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Concat.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Div' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Div.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Equal' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Equal.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Greater' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Greater.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\GreaterOrEqual' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Identical' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalAnd' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalAnd.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalOr' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalOr.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\LogicalXor' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/LogicalXor.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Minus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Minus.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Mod' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mod.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Mul' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Mul.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\NotEqual' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotEqual.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\NotIdentical' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/NotIdentical.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Plus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Plus.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Pow' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Pow.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftLeft' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftLeft.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\ShiftRight' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/ShiftRight.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Smaller' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\SmallerOrEqual' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/SmallerOrEqual.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BinaryOp\\Spaceship' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Spaceship.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BitwiseNot' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\BooleanNot' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\CallLike' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/CallLike.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Array_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Bool_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Bool_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Double' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Double.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Int_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Int_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Object_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Object_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\String_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/String_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Cast\\Unset_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Unset_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ClassConstFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClassConstFetch.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Clone_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Closure' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ClosureUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ConstFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Empty_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Error' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ErrorSuppress' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ErrorSuppress.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Eval_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Exit_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\FuncCall' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Include_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Instanceof_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Isset_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\List_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Match_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Match_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\MethodCall' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\New_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\NullsafeMethodCall' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafeMethodCall.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\NullsafePropertyFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/NullsafePropertyFetch.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PostDec' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PostInc' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PreDec' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PreInc' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Print_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\PropertyFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\ShellExec' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\StaticCall' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\StaticPropertyFetch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Ternary' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Throw_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Throw_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\UnaryMinus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\UnaryPlus' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Variable' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\YieldFrom' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Expr\\Yield_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\FunctionLike' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Identifier' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Identifier.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\IntersectionType' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/IntersectionType.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\MatchArm' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/MatchArm.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Name' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Name.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Name\\FullyQualified' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Name\\Relative' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\NullableType' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/NullableType.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Param' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Param.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\DNumber' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/DNumber.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\Encapsed' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\EncapsedStringPart' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\LNumber' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Class_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Class_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Dir' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Dir.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\File' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/File.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Function_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Function_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Line' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Line.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Method' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Method.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Namespace_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Namespace_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\MagicConst\\Trait_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst/Trait_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Scalar\\String_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Break_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Case_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Catch_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ClassConst' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ClassLike' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ClassMethod' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Class_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Const_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Continue_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\DeclareDeclare' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Declare_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Do_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Echo_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\ElseIf_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Else_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\EnumCase' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Enum_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Enum_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Expression' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Finally_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\For_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Foreach_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Function_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Global_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Goto_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\GroupUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\HaltCompiler' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\If_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\InlineHTML' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Interface_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Label' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Namespace_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Nop' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Property' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Property.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\PropertyProperty' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Return_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\StaticVar' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Static_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Switch_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Throw_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUseAdaptation' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Alias' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Alias.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TraitUseAdaptation\\Precedence' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Trait_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\TryCatch' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Unset_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\UseUse' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\Use_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\Stmt\\While_' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\UnionType' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/UnionType.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\VarLikeIdentifier' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Node\\VariadicPlaceholder' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Node/VariadicPlaceholder.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\ParserAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ParserAbstract.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\ParserFactory' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/ParserFactory.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Multiple' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Multiple.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Php5' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Php5.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Php7' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Php7.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\Parser\\Tokens' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/Parser/Tokens.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\PrettyPrinterAbstract' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php',
        '_HumbugBox1cb33d1f20f1\\PhpParser\\PrettyPrinter\\Standard' => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerAwareInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerAwareInterface.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerAwareTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerAwareTrait.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php',
        '_HumbugBox1cb33d1f20f1\\Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\ConfigurationException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/ConfigurationException.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php',
        '_HumbugBox1cb33d1f20f1\\SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php',
        '_HumbugBox1cb33d1f20f1\\Spatie\\ArrayToXml\\ArrayToXml' => __DIR__ . '/..' . '/spatie/array-to-xml/src/ArrayToXml.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Application' => __DIR__ . '/..' . '/symfony/console/Application.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Attribute\\AsCommand' => __DIR__ . '/..' . '/symfony/console/Attribute/AsCommand.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CI\\GithubActionReporter' => __DIR__ . '/..' . '/symfony/console/CI/GithubActionReporter.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Color' => __DIR__ . '/..' . '/symfony/console/Color.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CommandLoader\\CommandLoaderInterface' => __DIR__ . '/..' . '/symfony/console/CommandLoader/CommandLoaderInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CommandLoader\\ContainerCommandLoader' => __DIR__ . '/..' . '/symfony/console/CommandLoader/ContainerCommandLoader.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\CommandLoader\\FactoryCommandLoader' => __DIR__ . '/..' . '/symfony/console/CommandLoader/FactoryCommandLoader.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\Command' => __DIR__ . '/..' . '/symfony/console/Command/Command.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\CompleteCommand' => __DIR__ . '/..' . '/symfony/console/Command/CompleteCommand.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\DumpCompletionCommand' => __DIR__ . '/..' . '/symfony/console/Command/DumpCompletionCommand.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\HelpCommand' => __DIR__ . '/..' . '/symfony/console/Command/HelpCommand.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\LazyCommand' => __DIR__ . '/..' . '/symfony/console/Command/LazyCommand.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\ListCommand' => __DIR__ . '/..' . '/symfony/console/Command/ListCommand.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\LockableTrait' => __DIR__ . '/..' . '/symfony/console/Command/LockableTrait.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Command\\SignalableCommandInterface' => __DIR__ . '/..' . '/symfony/console/Command/SignalableCommandInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\CompletionInput' => __DIR__ . '/..' . '/symfony/console/Completion/CompletionInput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\CompletionSuggestions' => __DIR__ . '/..' . '/symfony/console/Completion/CompletionSuggestions.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\Output\\BashCompletionOutput' => __DIR__ . '/..' . '/symfony/console/Completion/Output/BashCompletionOutput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\Output\\CompletionOutputInterface' => __DIR__ . '/..' . '/symfony/console/Completion/Output/CompletionOutputInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Completion\\Suggestion' => __DIR__ . '/..' . '/symfony/console/Completion/Suggestion.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\ConsoleEvents' => __DIR__ . '/..' . '/symfony/console/ConsoleEvents.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Cursor' => __DIR__ . '/..' . '/symfony/console/Cursor.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\DependencyInjection\\AddConsoleCommandPass' => __DIR__ . '/..' . '/symfony/console/DependencyInjection/AddConsoleCommandPass.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\ApplicationDescription' => __DIR__ . '/..' . '/symfony/console/Descriptor/ApplicationDescription.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\Descriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/Descriptor.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\DescriptorInterface' => __DIR__ . '/..' . '/symfony/console/Descriptor/DescriptorInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\JsonDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/JsonDescriptor.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\MarkdownDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/MarkdownDescriptor.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\TextDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/TextDescriptor.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Descriptor\\XmlDescriptor' => __DIR__ . '/..' . '/symfony/console/Descriptor/XmlDescriptor.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\EventListener\\ErrorListener' => __DIR__ . '/..' . '/symfony/console/EventListener/ErrorListener.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleCommandEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleCommandEvent.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleErrorEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleErrorEvent.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleEvent.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleSignalEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleSignalEvent.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Event\\ConsoleTerminateEvent' => __DIR__ . '/..' . '/symfony/console/Event/ConsoleTerminateEvent.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\CommandNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/CommandNotFoundException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/console/Exception/ExceptionInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidArgumentException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\InvalidOptionException' => __DIR__ . '/..' . '/symfony/console/Exception/InvalidOptionException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\LogicException' => __DIR__ . '/..' . '/symfony/console/Exception/LogicException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\MissingInputException' => __DIR__ . '/..' . '/symfony/console/Exception/MissingInputException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\NamespaceNotFoundException' => __DIR__ . '/..' . '/symfony/console/Exception/NamespaceNotFoundException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/console/Exception/RuntimeException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatter' => __DIR__ . '/..' . '/symfony/console/Formatter/NullOutputFormatter.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\NullOutputFormatterStyle' => __DIR__ . '/..' . '/symfony/console/Formatter/NullOutputFormatterStyle.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatter' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatter.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyle' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyle.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\OutputFormatterStyleStack' => __DIR__ . '/..' . '/symfony/console/Formatter/OutputFormatterStyleStack.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Formatter\\WrappableOutputFormatterInterface' => __DIR__ . '/..' . '/symfony/console/Formatter/WrappableOutputFormatterInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\DebugFormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DebugFormatterHelper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\DescriptorHelper' => __DIR__ . '/..' . '/symfony/console/Helper/DescriptorHelper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\Dumper' => __DIR__ . '/..' . '/symfony/console/Helper/Dumper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\FormatterHelper' => __DIR__ . '/..' . '/symfony/console/Helper/FormatterHelper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\Helper' => __DIR__ . '/..' . '/symfony/console/Helper/Helper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\HelperInterface' => __DIR__ . '/..' . '/symfony/console/Helper/HelperInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\HelperSet' => __DIR__ . '/..' . '/symfony/console/Helper/HelperSet.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\InputAwareHelper' => __DIR__ . '/..' . '/symfony/console/Helper/InputAwareHelper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\ProcessHelper' => __DIR__ . '/..' . '/symfony/console/Helper/ProcessHelper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\ProgressBar' => __DIR__ . '/..' . '/symfony/console/Helper/ProgressBar.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\ProgressIndicator' => __DIR__ . '/..' . '/symfony/console/Helper/ProgressIndicator.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\QuestionHelper' => __DIR__ . '/..' . '/symfony/console/Helper/QuestionHelper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\SymfonyQuestionHelper' => __DIR__ . '/..' . '/symfony/console/Helper/SymfonyQuestionHelper.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\Table' => __DIR__ . '/..' . '/symfony/console/Helper/Table.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableCell' => __DIR__ . '/..' . '/symfony/console/Helper/TableCell.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableCellStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableCellStyle.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableRows' => __DIR__ . '/..' . '/symfony/console/Helper/TableRows.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableSeparator' => __DIR__ . '/..' . '/symfony/console/Helper/TableSeparator.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Helper\\TableStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableStyle.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\ArgvInput' => __DIR__ . '/..' . '/symfony/console/Input/ArgvInput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\ArrayInput' => __DIR__ . '/..' . '/symfony/console/Input/ArrayInput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\Input' => __DIR__ . '/..' . '/symfony/console/Input/Input.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputArgument' => __DIR__ . '/..' . '/symfony/console/Input/InputArgument.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputAwareInterface' => __DIR__ . '/..' . '/symfony/console/Input/InputAwareInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputDefinition' => __DIR__ . '/..' . '/symfony/console/Input/InputDefinition.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputInterface' => __DIR__ . '/..' . '/symfony/console/Input/InputInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\InputOption' => __DIR__ . '/..' . '/symfony/console/Input/InputOption.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\StreamableInputInterface' => __DIR__ . '/..' . '/symfony/console/Input/StreamableInputInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Input\\StringInput' => __DIR__ . '/..' . '/symfony/console/Input/StringInput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Logger\\ConsoleLogger' => __DIR__ . '/..' . '/symfony/console/Logger/ConsoleLogger.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\BufferedOutput' => __DIR__ . '/..' . '/symfony/console/Output/BufferedOutput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\ConsoleOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\ConsoleOutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleOutputInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\ConsoleSectionOutput' => __DIR__ . '/..' . '/symfony/console/Output/ConsoleSectionOutput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\NullOutput' => __DIR__ . '/..' . '/symfony/console/Output/NullOutput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\Output' => __DIR__ . '/..' . '/symfony/console/Output/Output.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\OutputInterface' => __DIR__ . '/..' . '/symfony/console/Output/OutputInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\StreamOutput' => __DIR__ . '/..' . '/symfony/console/Output/StreamOutput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Output\\TrimmedBufferOutput' => __DIR__ . '/..' . '/symfony/console/Output/TrimmedBufferOutput.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Question\\ChoiceQuestion' => __DIR__ . '/..' . '/symfony/console/Question/ChoiceQuestion.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Question\\ConfirmationQuestion' => __DIR__ . '/..' . '/symfony/console/Question/ConfirmationQuestion.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Question\\Question' => __DIR__ . '/..' . '/symfony/console/Question/Question.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\SignalRegistry\\SignalRegistry' => __DIR__ . '/..' . '/symfony/console/SignalRegistry/SignalRegistry.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\SingleCommandApplication' => __DIR__ . '/..' . '/symfony/console/SingleCommandApplication.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Style\\OutputStyle' => __DIR__ . '/..' . '/symfony/console/Style/OutputStyle.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Style\\StyleInterface' => __DIR__ . '/..' . '/symfony/console/Style/StyleInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Style\\SymfonyStyle' => __DIR__ . '/..' . '/symfony/console/Style/SymfonyStyle.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Terminal' => __DIR__ . '/..' . '/symfony/console/Terminal.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\ApplicationTester' => __DIR__ . '/..' . '/symfony/console/Tester/ApplicationTester.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\CommandCompletionTester' => __DIR__ . '/..' . '/symfony/console/Tester/CommandCompletionTester.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\CommandTester' => __DIR__ . '/..' . '/symfony/console/Tester/CommandTester.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\Constraint\\CommandIsSuccessful' => __DIR__ . '/..' . '/symfony/console/Tester/Constraint/CommandIsSuccessful.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\Tester\\TesterTrait' => __DIR__ . '/..' . '/symfony/console/Tester/TesterTrait.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/filesystem/Exception/ExceptionInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\FileNotFoundException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/FileNotFoundException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\IOException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/IOException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\IOExceptionInterface' => __DIR__ . '/..' . '/symfony/filesystem/Exception/IOExceptionInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/InvalidArgumentException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/filesystem/Exception/RuntimeException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Filesystem' => __DIR__ . '/..' . '/symfony/filesystem/Filesystem.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\Path' => __DIR__ . '/..' . '/symfony/filesystem/Path.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\AbstractString' => __DIR__ . '/..' . '/symfony/string/AbstractString.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\AbstractUnicodeString' => __DIR__ . '/..' . '/symfony/string/AbstractUnicodeString.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\ByteString' => __DIR__ . '/..' . '/symfony/string/ByteString.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\CodePointString' => __DIR__ . '/..' . '/symfony/string/CodePointString.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/string/Exception/ExceptionInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Exception\\InvalidArgumentException' => __DIR__ . '/..' . '/symfony/string/Exception/InvalidArgumentException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Exception\\RuntimeException' => __DIR__ . '/..' . '/symfony/string/Exception/RuntimeException.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Inflector\\EnglishInflector' => __DIR__ . '/..' . '/symfony/string/Inflector/EnglishInflector.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Inflector\\FrenchInflector' => __DIR__ . '/..' . '/symfony/string/Inflector/FrenchInflector.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Inflector\\InflectorInterface' => __DIR__ . '/..' . '/symfony/string/Inflector/InflectorInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\LazyString' => __DIR__ . '/..' . '/symfony/string/LazyString.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Slugger\\AsciiSlugger' => __DIR__ . '/..' . '/symfony/string/Slugger/AsciiSlugger.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\Slugger\\SluggerInterface' => __DIR__ . '/..' . '/symfony/string/Slugger/SluggerInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\UnicodeString' => __DIR__ . '/..' . '/symfony/string/UnicodeString.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\Attribute\\Required' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/Required.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\Attribute\\SubscribedService' => __DIR__ . '/..' . '/symfony/service-contracts/Attribute/SubscribedService.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ResetInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ResetInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceLocatorTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceLocatorTrait.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceProviderInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceProviderInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceSubscriberInterface' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberInterface.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\ServiceSubscriberTrait' => __DIR__ . '/..' . '/symfony/service-contracts/ServiceSubscriberTrait.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Ctype\\Ctype' => __DIR__ . '/..' . '/symfony/polyfill-ctype/Ctype.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Grapheme\\Grapheme' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/Grapheme.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Normalizer\\Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Normalizer.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Mbstring\\Mbstring' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/Mbstring.php',
        '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php73\\Php73' => __DIR__ . '/..' . '/symfony/polyfill-php73/Php73.php',
        '_HumbugBox1cb33d1f20f1\\UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
        '_HumbugBox1cb33d1f20f1\\ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
        '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\Assert' => __DIR__ . '/..' . '/webmozart/assert/src/Assert.php',
        '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\InvalidArgumentException' => __DIR__ . '/..' . '/webmozart/assert/src/InvalidArgumentException.php',
        '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\Mixin' => __DIR__ . '/..' . '/webmozart/assert/src/Mixin.php',
        '_HumbugBox1cb33d1f20f1\\XdgBaseDir\\Xdg' => __DIR__ . '/..' . '/dnoegel/php-xdg-base-dir/src/Xdg.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlockFactory' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlockFactory.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlockFactoryInterface' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Description' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Description.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\DescriptionFactory' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\ExampleFinder' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Serializer' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tag' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\TagFactory' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Author' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\BaseTag' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Covers' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Deprecated' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Example' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Factory\\StaticMethod' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\AlignFormatter' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Formatter\\PassthroughFormatter' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Generic' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\InvalidTag' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Link' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Method' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Param' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Property' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyRead' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\PropertyWrite' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Fqsen' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Reference' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Reference\\Url' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Return_' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\See' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Since' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Source' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\TagWithType' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Throws' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Uses' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Var_' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\DocBlock\\Tags\\Version' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Element' => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src/Element.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Exception\\PcreException' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/Exception/PcreException.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\File' => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src/File.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Fqsen' => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src/Fqsen.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\FqsenResolver' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/FqsenResolver.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Location' => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src/Location.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Project' => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src/Project.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\ProjectFactory' => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src/ProjectFactory.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoType' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoType.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\CallableString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/CallableString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\False_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/False_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\HtmlEscapedString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\IntegerRange' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/IntegerRange.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\List_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/List_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\LiteralString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\LowercaseString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NegativeInteger' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NegativeInteger.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyLowercaseString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NonEmptyString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\NumericString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/NumericString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\Numeric_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/Numeric_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\PositiveInteger' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/PositiveInteger.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\TraitString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\PseudoTypes\\True_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/PseudoTypes/True_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Type' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Type.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\TypeResolver' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/TypeResolver.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\AbstractList' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/AbstractList.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\AggregatedType' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/AggregatedType.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\ArrayKey' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/ArrayKey.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Array_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Array_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Boolean' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Boolean.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Callable_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Callable_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\ClassString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/ClassString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Collection' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Collection.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Compound' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Compound.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Context' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Context.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\ContextFactory' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/ContextFactory.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Expression' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Expression.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Float_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Float_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Integer' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Integer.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\InterfaceString' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/InterfaceString.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Intersection' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Intersection.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Iterable_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Iterable_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Mixed_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Mixed_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Never_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Never_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Null_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Null_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Nullable' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Nullable.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Object_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Object_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Parent_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Parent_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Resource_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Resource_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Scalar' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Scalar.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Self_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Self_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Static_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Static_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\String_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/String_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\This' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/This.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\Void_' => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src/Types/Void_.php',
        '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Utils' => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src/Utils.php',
    );

    public static function getInitializer(ClassLoader $loader)
    {
        return \Closure::bind(function () use ($loader) {
            $loader->prefixLengthsPsr4 = ComposerStaticInit7e022409458d7c6e0a17a3098ef276ac::$prefixLengthsPsr4;
            $loader->prefixDirsPsr4 = ComposerStaticInit7e022409458d7c6e0a17a3098ef276ac::$prefixDirsPsr4;
            $loader->classMap = ComposerStaticInit7e022409458d7c6e0a17a3098ef276ac::$classMap;

        }, null, ClassLoader::class);
    }
}
<?php

// autoload_files.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
    'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
    '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
    '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
    '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
    'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
    'e8aa6e4b5a1db2f56ae794f1505391a8' => $vendorDir . '/amphp/amp/lib/functions.php',
    '76cd0796156622033397994f25b0d8fc' => $vendorDir . '/amphp/amp/lib/Internal/functions.php',
    '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
    'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
    '6cd5651c4fef5ed6b63e8d8b8ffbf3cc' => $vendorDir . '/amphp/byte-stream/lib/functions.php',
);
<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit7e022409458d7c6e0a17a3098ef276ac
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    /**
     * @return \Composer\Autoload\ClassLoader
     */
    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        require __DIR__ . '/platform_check.php';

        spl_autoload_register(array('ComposerAutoloaderInit7e022409458d7c6e0a17a3098ef276ac', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
        spl_autoload_unregister(array('ComposerAutoloaderInit7e022409458d7c6e0a17a3098ef276ac', 'loadClassLoader'));

        require __DIR__ . '/autoload_static.php';
        call_user_func(\Composer\Autoload\ComposerStaticInit7e022409458d7c6e0a17a3098ef276ac::getInitializer($loader));

        $loader->setClassMapAuthoritative(true);
        $loader->register(true);

        $filesToLoad = \Composer\Autoload\ComposerStaticInit7e022409458d7c6e0a17a3098ef276ac::$files;
        $requireFile = static function ($fileIdentifier, $file) {
            if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
                $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;

                require $file;
            }
        };
        foreach ($filesToLoad as $fileIdentifier => $file) {
            ($requireFile)($fileIdentifier, $file);
        }

        return $loader;
    }
}
<?php

/*
 * This file is part of composer/xdebug-handler.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Composer\XdebugHandler;

use _HumbugBox1cb33d1f20f1\Psr\Log\LoggerInterface;
use _HumbugBox1cb33d1f20f1\Psr\Log\LogLevel;
/**
 * @author John Stevenson <john-stevenson@blueyonder.co.uk>
 * @internal
 */
class Status
{
    const ENV_RESTART = 'XDEBUG_HANDLER_RESTART';
    const CHECK = 'Check';
    const ERROR = 'Error';
    const INFO = 'Info';
    const NORESTART = 'NoRestart';
    const RESTART = 'Restart';
    const RESTARTING = 'Restarting';
    const RESTARTED = 'Restarted';
    /** @var bool */
    private $debug;
    /** @var string */
    private $envAllowXdebug;
    /** @var string|null */
    private $loaded;
    /** @var LoggerInterface|null */
    private $logger;
    /** @var bool */
    private $modeOff;
    /** @var float */
    private $time;
    /**
     * @param string $envAllowXdebug Prefixed _ALLOW_XDEBUG name
     * @param bool $debug Whether debug output is required
     */
    public function __construct(string $envAllowXdebug, bool $debug)
    {
        $start = \getenv(self::ENV_RESTART);
        Process::setEnv(self::ENV_RESTART);
        $this->time = \is_numeric($start) ? \round((\microtime(\true) - $start) * 1000) : 0;
        $this->envAllowXdebug = $envAllowXdebug;
        $this->debug = $debug && \defined('STDERR');
        $this->modeOff = \false;
    }
    /**
     * Activates status message output to a PSR3 logger
     *
     * @return void
     */
    public function setLogger(LoggerInterface $logger) : void
    {
        $this->logger = $logger;
    }
    /**
     * Calls a handler method to report a message
     *
     * @throws \InvalidArgumentException If $op is not known
     */
    public function report(string $op, ?string $data) : void
    {
        if ($this->logger !== null || $this->debug) {
            $callable = [$this, 'report' . $op];
            if (!\is_callable($callable)) {
                throw new \InvalidArgumentException('Unknown op handler: ' . $op);
            }
            $params = $data !== null ? [$data] : [];
            \call_user_func_array($callable, $params);
        }
    }
    /**
     * Outputs a status message
     */
    private function output(string $text, ?string $level = null) : void
    {
        if ($this->logger !== null) {
            $this->logger->log($level !== null ? $level : LogLevel::DEBUG, $text);
        }
        if ($this->debug) {
            \fwrite(\STDERR, \sprintf('xdebug-handler[%d] %s', \getmypid(), $text . \PHP_EOL));
        }
    }
    /**
     * Checking status message
     */
    private function reportCheck(string $loaded) : void
    {
        list($version, $mode) = \explode('|', $loaded);
        if ($version !== '') {
            $this->loaded = '(' . $version . ')' . ($mode !== '' ? ' xdebug.mode=' . $mode : '');
        }
        $this->modeOff = $mode === 'off';
        $this->output('Checking ' . $this->envAllowXdebug);
    }
    /**
     * Error status message
     */
    private function reportError(string $error) : void
    {
        $this->output(\sprintf('No restart (%s)', $error), LogLevel::WARNING);
    }
    /**
     * Info status message
     */
    private function reportInfo(string $info) : void
    {
        $this->output($info);
    }
    /**
     * No restart status message
     */
    private function reportNoRestart() : void
    {
        $this->output($this->getLoadedMessage());
        if ($this->loaded !== null) {
            $text = \sprintf('No restart (%s)', $this->getEnvAllow());
            if (!(bool) \getenv($this->envAllowXdebug)) {
                $text .= ' Allowed by ' . ($this->modeOff ? 'xdebug.mode' : 'application');
            }
            $this->output($text);
        }
    }
    /**
     * Restart status message
     */
    private function reportRestart() : void
    {
        $this->output($this->getLoadedMessage());
        Process::setEnv(self::ENV_RESTART, (string) \microtime(\true));
    }
    /**
     * Restarted status message
     */
    private function reportRestarted() : void
    {
        $loaded = $this->getLoadedMessage();
        $text = \sprintf('Restarted (%d ms). %s', $this->time, $loaded);
        $level = $this->loaded !== null ? LogLevel::WARNING : null;
        $this->output($text, $level);
    }
    /**
     * Restarting status message
     */
    private function reportRestarting(string $command) : void
    {
        $text = \sprintf('Process restarting (%s)', $this->getEnvAllow());
        $this->output($text);
        $text = 'Running ' . $command;
        $this->output($text);
    }
    /**
     * Returns the _ALLOW_XDEBUG environment variable as name=value
     */
    private function getEnvAllow() : string
    {
        return $this->envAllowXdebug . '=' . \getenv($this->envAllowXdebug);
    }
    /**
     * Returns the Xdebug status and version
     */
    private function getLoadedMessage() : string
    {
        $loaded = $this->loaded !== null ? \sprintf('loaded %s', $this->loaded) : 'not loaded';
        return 'The Xdebug extension is ' . $loaded;
    }
}
<?php

/*
 * This file is part of composer/xdebug-handler.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Composer\XdebugHandler;

use _HumbugBox1cb33d1f20f1\Composer\Pcre\Preg;
/**
 * Process utility functions
 *
 * @author John Stevenson <john-stevenson@blueyonder.co.uk>
 */
class Process
{
    /**
     * Escapes a string to be used as a shell argument.
     *
     * From https://github.com/johnstevenson/winbox-args
     * MIT Licensed (c) John Stevenson <john-stevenson@blueyonder.co.uk>
     *
     * @param string $arg  The argument to be escaped
     * @param bool $meta Additionally escape cmd.exe meta characters
     * @param bool $module The argument is the module to invoke
     */
    public static function escape(string $arg, bool $meta = \true, bool $module = \false) : string
    {
        if (!\defined('PHP_WINDOWS_VERSION_BUILD')) {
            return "'" . \str_replace("'", "'\\''", $arg) . "'";
        }
        $quote = \strpbrk($arg, " \t") !== \false || $arg === '';
        $arg = Preg::replace('/(\\\\*)"/', '$1$1\\"', $arg, -1, $dquotes);
        if ($meta) {
            $meta = $dquotes || Preg::isMatch('/%[^%]+%/', $arg);
            if (!$meta) {
                $quote = $quote || \strpbrk($arg, '^&|<>()') !== \false;
            } elseif ($module && !$dquotes && $quote) {
                $meta = \false;
            }
        }
        if ($quote) {
            $arg = '"' . Preg::replace('/(\\\\*)$/', '$1$1', $arg) . '"';
        }
        if ($meta) {
            $arg = Preg::replace('/(["^&|<>()%])/', '^$1', $arg);
        }
        return $arg;
    }
    /**
     * Escapes an array of arguments that make up a shell command
     *
     * @param string[] $args Argument list, with the module name first
     */
    public static function escapeShellCommand(array $args) : string
    {
        $command = '';
        $module = \array_shift($args);
        if ($module !== null) {
            $command = self::escape($module, \true, \true);
            foreach ($args as $arg) {
                $command .= ' ' . self::escape($arg);
            }
        }
        return $command;
    }
    /**
     * Makes putenv environment changes available in $_SERVER and $_ENV
     *
     * @param string $name
     * @param ?string $value A null value unsets the variable
     */
    public static function setEnv(string $name, ?string $value = null) : bool
    {
        $unset = null === $value;
        if (!\putenv($unset ? $name : $name . '=' . $value)) {
            return \false;
        }
        if ($unset) {
            unset($_SERVER[$name]);
        } else {
            $_SERVER[$name] = $value;
        }
        // Update $_ENV if it is being used
        if (\false !== \stripos((string) \ini_get('variables_order'), 'E')) {
            if ($unset) {
                unset($_ENV[$name]);
            } else {
                $_ENV[$name] = $value;
            }
        }
        return \true;
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of composer/xdebug-handler.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\XdebugHandler;

/**
 * @author John Stevenson <john-stevenson@blueyonder.co.uk>
 *
 * @phpstan-type restartData array{tmpIni: string, scannedInis: bool, scanDir: false|string, phprc: false|string, inis: string[], skipped: string}
 */
class PhpConfig
{
    /**
     * Use the original PHP configuration
     *
     * @return string[] Empty array of PHP cli options
     */
    public function useOriginal() : array
    {
        $this->getDataAndReset();
        return [];
    }
    /**
     * Use standard restart settings
     *
     * @return string[] PHP cli options
     */
    public function useStandard() : array
    {
        $data = $this->getDataAndReset();
        if ($data !== null) {
            return ['-n', '-c', $data['tmpIni']];
        }
        return [];
    }
    /**
     * Use environment variables to persist settings
     *
     * @return string[] Empty array of PHP cli options
     */
    public function usePersistent() : array
    {
        $data = $this->getDataAndReset();
        if ($data !== null) {
            $this->updateEnv('PHPRC', $data['tmpIni']);
            $this->updateEnv('PHP_INI_SCAN_DIR', '');
        }
        return [];
    }
    /**
     * Returns restart data if available and resets the environment
     *
     * @phpstan-return restartData|null
     */
    private function getDataAndReset() : ?array
    {
        $data = XdebugHandler::getRestartSettings();
        if ($data !== null) {
            $this->updateEnv('PHPRC', $data['phprc']);
            $this->updateEnv('PHP_INI_SCAN_DIR', $data['scanDir']);
        }
        return $data;
    }
    /**
     * Updates a restart settings value in the environment
     *
     * @param string $name
     * @param string|false $value
     */
    private function updateEnv(string $name, $value) : void
    {
        Process::setEnv($name, \false !== $value ? $value : null);
    }
}
<?php

/*
 * This file is part of composer/xdebug-handler.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Composer\XdebugHandler;

use _HumbugBox1cb33d1f20f1\Composer\Pcre\Preg;
use _HumbugBox1cb33d1f20f1\Psr\Log\LoggerInterface;
/**
 * @author John Stevenson <john-stevenson@blueyonder.co.uk>
 *
 * @phpstan-import-type restartData from PhpConfig
 */
class XdebugHandler
{
    const SUFFIX_ALLOW = '_ALLOW_XDEBUG';
    const SUFFIX_INIS = '_ORIGINAL_INIS';
    const RESTART_ID = 'internal';
    const RESTART_SETTINGS = 'XDEBUG_HANDLER_SETTINGS';
    const DEBUG = 'XDEBUG_HANDLER_DEBUG';
    /** @var string|null */
    protected $tmpIni;
    /** @var bool */
    private static $inRestart;
    /** @var string */
    private static $name;
    /** @var string|null */
    private static $skipped;
    /** @var bool */
    private static $xdebugActive;
    /** @var string|null */
    private static $xdebugMode;
    /** @var string|null */
    private static $xdebugVersion;
    /** @var bool */
    private $cli;
    /** @var string|null */
    private $debug;
    /** @var string */
    private $envAllowXdebug;
    /** @var string */
    private $envOriginalInis;
    /** @var bool */
    private $persistent;
    /** @var string|null */
    private $script;
    /** @var Status */
    private $statusWriter;
    /**
     * Constructor
     *
     * The $envPrefix is used to create distinct environment variables. It is
     * uppercased and prepended to the default base values. For example 'myapp'
     * would result in MYAPP_ALLOW_XDEBUG and MYAPP_ORIGINAL_INIS.
     *
     * @param string $envPrefix Value used in environment variables
     * @throws \RuntimeException If the parameter is invalid
     */
    public function __construct(string $envPrefix)
    {
        if ($envPrefix === '') {
            throw new \RuntimeException('Invalid constructor parameter');
        }
        self::$name = \strtoupper($envPrefix);
        $this->envAllowXdebug = self::$name . self::SUFFIX_ALLOW;
        $this->envOriginalInis = self::$name . self::SUFFIX_INIS;
        self::setXdebugDetails();
        self::$inRestart = \false;
        if ($this->cli = \PHP_SAPI === 'cli') {
            $this->debug = (string) \getenv(self::DEBUG);
        }
        $this->statusWriter = new Status($this->envAllowXdebug, (bool) $this->debug);
    }
    /**
     * Activates status message output to a PSR3 logger
     */
    public function setLogger(LoggerInterface $logger) : self
    {
        $this->statusWriter->setLogger($logger);
        return $this;
    }
    /**
     * Sets the main script location if it cannot be called from argv
     */
    public function setMainScript(string $script) : self
    {
        $this->script = $script;
        return $this;
    }
    /**
     * Persist the settings to keep Xdebug out of sub-processes
     */
    public function setPersistent() : self
    {
        $this->persistent = \true;
        return $this;
    }
    /**
     * Checks if Xdebug is loaded and the process needs to be restarted
     *
     * This behaviour can be disabled by setting the MYAPP_ALLOW_XDEBUG
     * environment variable to 1. This variable is used internally so that
     * the restarted process is created only once.
     */
    public function check() : void
    {
        $this->notify(Status::CHECK, self::$xdebugVersion . '|' . self::$xdebugMode);
        $envArgs = \explode('|', (string) \getenv($this->envAllowXdebug));
        if (!(bool) $envArgs[0] && $this->requiresRestart(self::$xdebugActive)) {
            // Restart required
            $this->notify(Status::RESTART);
            if ($this->prepareRestart()) {
                $command = $this->getCommand();
                $this->restart($command);
            }
            return;
        }
        if (self::RESTART_ID === $envArgs[0] && \count($envArgs) === 5) {
            // Restarted, so unset environment variable and use saved values
            $this->notify(Status::RESTARTED);
            Process::setEnv($this->envAllowXdebug);
            self::$inRestart = \true;
            if (self::$xdebugVersion === null) {
                // Skipped version is only set if Xdebug is not loaded
                self::$skipped = $envArgs[1];
            }
            $this->tryEnableSignals();
            // Put restart settings in the environment
            $this->setEnvRestartSettings($envArgs);
            return;
        }
        $this->notify(Status::NORESTART);
        $settings = self::getRestartSettings();
        if ($settings !== null) {
            // Called with existing settings, so sync our settings
            $this->syncSettings($settings);
        }
    }
    /**
     * Returns an array of php.ini locations with at least one entry
     *
     * The equivalent of calling php_ini_loaded_file then php_ini_scanned_files.
     * The loaded ini location is the first entry and may be empty.
     *
     * @return string[]
     */
    public static function getAllIniFiles() : array
    {
        if (self::$name !== null) {
            $env = \getenv(self::$name . self::SUFFIX_INIS);
            if (\false !== $env) {
                return \explode(\PATH_SEPARATOR, $env);
            }
        }
        $paths = [(string) \php_ini_loaded_file()];
        $scanned = \php_ini_scanned_files();
        if ($scanned !== \false) {
            $paths = \array_merge($paths, \array_map('trim', \explode(',', $scanned)));
        }
        return $paths;
    }
    /**
     * Returns an array of restart settings or null
     *
     * Settings will be available if the current process was restarted, or
     * called with the settings from an existing restart.
     *
     * @phpstan-return restartData|null
     */
    public static function getRestartSettings() : ?array
    {
        $envArgs = \explode('|', (string) \getenv(self::RESTART_SETTINGS));
        if (\count($envArgs) !== 6 || !self::$inRestart && \php_ini_loaded_file() !== $envArgs[0]) {
            return null;
        }
        return ['tmpIni' => $envArgs[0], 'scannedInis' => (bool) $envArgs[1], 'scanDir' => '*' === $envArgs[2] ? \false : $envArgs[2], 'phprc' => '*' === $envArgs[3] ? \false : $envArgs[3], 'inis' => \explode(\PATH_SEPARATOR, $envArgs[4]), 'skipped' => $envArgs[5]];
    }
    /**
     * Returns the Xdebug version that triggered a successful restart
     */
    public static function getSkippedVersion() : string
    {
        return (string) self::$skipped;
    }
    /**
     * Returns whether Xdebug is loaded and active
     *
     * true: if Xdebug is loaded and is running in an active mode.
     * false: if Xdebug is not loaded, or it is running with xdebug.mode=off.
     */
    public static function isXdebugActive() : bool
    {
        self::setXdebugDetails();
        return self::$xdebugActive;
    }
    /**
     * Allows an extending class to decide if there should be a restart
     *
     * The default is to restart if Xdebug is loaded and its mode is not "off".
     */
    protected function requiresRestart(bool $default) : bool
    {
        return $default;
    }
    /**
     * Allows an extending class to access the tmpIni
     *
     * @param string[] $command     *
     */
    protected function restart(array $command) : void
    {
        $this->doRestart($command);
    }
    /**
     * Executes the restarted command then deletes the tmp ini
     *
     * @param string[] $command
     * @phpstan-return never
     */
    private function doRestart(array $command) : void
    {
        $this->tryEnableSignals();
        $this->notify(Status::RESTARTING, \implode(' ', $command));
        if (\PHP_VERSION_ID >= 70400) {
            $cmd = $command;
        } else {
            $cmd = Process::escapeShellCommand($command);
            if (\defined('PHP_WINDOWS_VERSION_BUILD')) {
                // Outer quotes required on cmd string below PHP 8
                $cmd = '"' . $cmd . '"';
            }
        }
        $process = \proc_open($cmd, [], $pipes);
        if (\is_resource($process)) {
            $exitCode = \proc_close($process);
        }
        if (!isset($exitCode)) {
            // Unlikely that php or the default shell cannot be invoked
            $this->notify(Status::ERROR, 'Unable to restart process');
            $exitCode = -1;
        } else {
            $this->notify(Status::INFO, 'Restarted process exited ' . $exitCode);
        }
        if ($this->debug === '2') {
            $this->notify(Status::INFO, 'Temp ini saved: ' . $this->tmpIni);
        } else {
            @\unlink((string) $this->tmpIni);
        }
        exit($exitCode);
    }
    /**
     * Returns true if everything was written for the restart
     *
     * If any of the following fails (however unlikely) we must return false to
     * stop potential recursion:
     *   - tmp ini file creation
     *   - environment variable creation
     */
    private function prepareRestart() : bool
    {
        $error = null;
        $iniFiles = self::getAllIniFiles();
        $scannedInis = \count($iniFiles) > 1;
        $tmpDir = \sys_get_temp_dir();
        if (!$this->cli) {
            $error = 'Unsupported SAPI: ' . \PHP_SAPI;
        } elseif (!$this->checkConfiguration($info)) {
            $error = $info;
        } elseif (!$this->checkMainScript()) {
            $error = 'Unable to access main script: ' . $this->script;
        } elseif (!$this->writeTmpIni($iniFiles, $tmpDir, $error)) {
            $error = $error !== null ? $error : 'Unable to create temp ini file at: ' . $tmpDir;
        } elseif (!$this->setEnvironment($scannedInis, $iniFiles)) {
            $error = 'Unable to set environment variables';
        }
        if ($error !== null) {
            $this->notify(Status::ERROR, $error);
        }
        return $error === null;
    }
    /**
     * Returns true if the tmp ini file was written
     *
     * @param string[] $iniFiles All ini files used in the current process
     */
    private function writeTmpIni(array $iniFiles, string $tmpDir, ?string &$error) : bool
    {
        if (($tmpfile = @\tempnam($tmpDir, '')) === \false) {
            return \false;
        }
        $this->tmpIni = $tmpfile;
        // $iniFiles has at least one item and it may be empty
        if ($iniFiles[0] === '') {
            \array_shift($iniFiles);
        }
        $content = '';
        $sectionRegex = '/^\\s*\\[(?:PATH|HOST)\\s*=/mi';
        $xdebugRegex = '/^\\s*(zend_extension\\s*=.*xdebug.*)$/mi';
        foreach ($iniFiles as $file) {
            // Check for inaccessible ini files
            if (($data = @\file_get_contents($file)) === \false) {
                $error = 'Unable to read ini: ' . $file;
                return \false;
            }
            // Check and remove directives after HOST and PATH sections
            if (Preg::isMatchWithOffsets($sectionRegex, $data, $matches, \PREG_OFFSET_CAPTURE)) {
                $data = \substr($data, 0, $matches[0][1]);
            }
            $content .= Preg::replace($xdebugRegex, ';$1', $data) . \PHP_EOL;
        }
        // Merge loaded settings into our ini content, if it is valid
        $config = \parse_ini_string($content);
        $loaded = \ini_get_all(null, \false);
        if (\false === $config || \false === $loaded) {
            $error = 'Unable to parse ini data';
            return \false;
        }
        $content .= $this->mergeLoadedConfig($loaded, $config);
        // Work-around for https://bugs.php.net/bug.php?id=75932
        $content .= 'opcache.enable_cli=0' . \PHP_EOL;
        return (bool) @\file_put_contents($this->tmpIni, $content);
    }
    /**
     * Returns the command line arguments for the restart
     *
     * @return string[]
     */
    private function getCommand() : array
    {
        $php = [\PHP_BINARY];
        $args = \array_slice($_SERVER['argv'], 1);
        if (!$this->persistent) {
            // Use command-line options
            \array_push($php, '-n', '-c', $this->tmpIni);
        }
        return \array_merge($php, [$this->script], $args);
    }
    /**
     * Returns true if the restart environment variables were set
     *
     * No need to update $_SERVER since this is set in the restarted process.
     *
     * @param string[] $iniFiles All ini files used in the current process
     */
    private function setEnvironment(bool $scannedInis, array $iniFiles) : bool
    {
        $scanDir = \getenv('PHP_INI_SCAN_DIR');
        $phprc = \getenv('PHPRC');
        // Make original inis available to restarted process
        if (!\putenv($this->envOriginalInis . '=' . \implode(\PATH_SEPARATOR, $iniFiles))) {
            return \false;
        }
        if ($this->persistent) {
            // Use the environment to persist the settings
            if (!\putenv('PHP_INI_SCAN_DIR=') || !\putenv('PHPRC=' . $this->tmpIni)) {
                return \false;
            }
        }
        // Flag restarted process and save values for it to use
        $envArgs = [self::RESTART_ID, self::$xdebugVersion, (int) $scannedInis, \false === $scanDir ? '*' : $scanDir, \false === $phprc ? '*' : $phprc];
        return \putenv($this->envAllowXdebug . '=' . \implode('|', $envArgs));
    }
    /**
     * Logs status messages
     */
    private function notify(string $op, ?string $data = null) : void
    {
        $this->statusWriter->report($op, $data);
    }
    /**
     * Returns default, changed and command-line ini settings
     *
     * @param mixed[] $loadedConfig All current ini settings
     * @param mixed[] $iniConfig Settings from user ini files
     *
     */
    private function mergeLoadedConfig(array $loadedConfig, array $iniConfig) : string
    {
        $content = '';
        foreach ($loadedConfig as $name => $value) {
            // Value will either be null, string or array (HHVM only)
            if (!\is_string($value) || \strpos($name, 'xdebug') === 0 || $name === 'apc.mmap_file_mask') {
                continue;
            }
            if (!isset($iniConfig[$name]) || $iniConfig[$name] !== $value) {
                // Double-quote escape each value
                $content .= $name . '="' . \addcslashes($value, '\\"') . '"' . \PHP_EOL;
            }
        }
        return $content;
    }
    /**
     * Returns true if the script name can be used
     */
    private function checkMainScript() : bool
    {
        if ($this->script !== null) {
            // Allow an application to set -- for standard input
            return \file_exists($this->script) || '--' === $this->script;
        }
        if (\file_exists($this->script = $_SERVER['argv'][0])) {
            return \true;
        }
        // Use a backtrace to resolve Phar and chdir issues.
        $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
        $main = \end($trace);
        if ($main !== \false && isset($main['file'])) {
            return \file_exists($this->script = $main['file']);
        }
        return \false;
    }
    /**
     * Adds restart settings to the environment
     *
     * @param string[] $envArgs
     */
    private function setEnvRestartSettings(array $envArgs) : void
    {
        $settings = [\php_ini_loaded_file(), $envArgs[2], $envArgs[3], $envArgs[4], \getenv($this->envOriginalInis), self::$skipped];
        Process::setEnv(self::RESTART_SETTINGS, \implode('|', $settings));
    }
    /**
     * Syncs settings and the environment if called with existing settings
     *
     * @phpstan-param restartData $settings
     */
    private function syncSettings(array $settings) : void
    {
        if (\false === \getenv($this->envOriginalInis)) {
            // Called by another app, so make original inis available
            Process::setEnv($this->envOriginalInis, \implode(\PATH_SEPARATOR, $settings['inis']));
        }
        self::$skipped = $settings['skipped'];
        $this->notify(Status::INFO, 'Process called with existing restart settings');
    }
    /**
     * Returns true if there are no known configuration issues
     */
    private function checkConfiguration(?string &$info) : bool
    {
        if (!\function_exists('proc_open')) {
            $info = 'proc_open function is disabled';
            return \false;
        }
        if (\extension_loaded('uopz') && !(bool) \ini_get('uopz.disable')) {
            // uopz works at opcode level and disables exit calls
            if (\function_exists('uopz_allow_exit')) {
                @\uopz_allow_exit(\true);
            } else {
                $info = 'uopz extension is not compatible';
                return \false;
            }
        }
        // Check UNC paths when using cmd.exe
        if (\defined('PHP_WINDOWS_VERSION_BUILD') && \PHP_VERSION_ID < 70400) {
            $workingDir = \getcwd();
            if ($workingDir === \false) {
                $info = 'unable to determine working directory';
                return \false;
            }
            if (0 === \strpos($workingDir, '\\\\')) {
                $info = 'cmd.exe does not support UNC paths: ' . $workingDir;
                return \false;
            }
        }
        return \true;
    }
    /**
     * Enables async signals and control interrupts in the restarted process
     *
     * Available on Unix PHP 7.1+ with the pcntl extension and Windows PHP 7.4+.
     */
    private function tryEnableSignals() : void
    {
        if (\function_exists('pcntl_async_signals') && \function_exists('pcntl_signal')) {
            \pcntl_async_signals(\true);
            $message = 'Async signals enabled';
            if (!self::$inRestart) {
                // Restarting, so ignore SIGINT in parent
                \pcntl_signal(\SIGINT, \SIG_IGN);
            } elseif (\is_int(\pcntl_signal_get_handler(\SIGINT))) {
                // Restarted, no handler set so force default action
                \pcntl_signal(\SIGINT, \SIG_DFL);
            }
        }
        if (!self::$inRestart && \function_exists('sapi_windows_set_ctrl_handler')) {
            // Restarting, so set a handler to ignore CTRL events in the parent.
            // This ensures that CTRL+C events will be available in the child
            // process without having to enable them there, which is unreliable.
            \sapi_windows_set_ctrl_handler(function ($evt) {
            });
        }
    }
    /**
     * Sets static properties $xdebugActive, $xdebugVersion and $xdebugMode
     */
    private static function setXdebugDetails() : void
    {
        if (self::$xdebugActive !== null) {
            return;
        }
        self::$xdebugActive = \false;
        if (!\extension_loaded('xdebug')) {
            return;
        }
        $version = \phpversion('xdebug');
        self::$xdebugVersion = $version !== \false ? $version : 'unknown';
        if (\version_compare(self::$xdebugVersion, '3.1', '>=')) {
            $modes = \xdebug_info('mode');
            self::$xdebugMode = \count($modes) === 0 ? 'off' : \implode(',', $modes);
            self::$xdebugActive = self::$xdebugMode !== 'off';
            return;
        }
        // See if xdebug.mode is supported in this version
        $iniMode = \ini_get('xdebug.mode');
        if ($iniMode === \false) {
            self::$xdebugActive = \true;
            return;
        }
        // Environment value wins but cannot be empty
        $envMode = (string) \getenv('XDEBUG_MODE');
        if ($envMode !== '') {
            self::$xdebugMode = $envMode;
        } else {
            self::$xdebugMode = $iniMode !== '' ? $iniMode : 'off';
        }
        // An empty comma-separated list is treated as mode 'off'
        if (Preg::isMatch('/^,+$/', \str_replace(' ', '', self::$xdebugMode))) {
            self::$xdebugMode = 'off';
        }
        self::$xdebugActive = self::$xdebugMode !== 'off';
    }
}
MIT License

Copyright (c) 2017 Composer

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Copyright (c) Nils Adermann, Jordi Boggiano

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
    '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
    '_HumbugBox1cb33d1f20f1\\XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'),
    '_HumbugBox1cb33d1f20f1\\Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Intl\\Grapheme\\' => array($vendorDir . '/symfony/polyfill-intl-grapheme'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
    '_HumbugBox1cb33d1f20f1\\Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
    '_HumbugBox1cb33d1f20f1\\Spatie\\ArrayToXml\\' => array($vendorDir . '/spatie/array-to-xml/src'),
    '_HumbugBox1cb33d1f20f1\\Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
    '_HumbugBox1cb33d1f20f1\\Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
    '_HumbugBox1cb33d1f20f1\\PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
    '_HumbugBox1cb33d1f20f1\\PackageVersions\\' => array($vendorDir . '/composer/package-versions-deprecated/src/PackageVersions'),
    '_HumbugBox1cb33d1f20f1\\LanguageServerProtocol\\' => array($vendorDir . '/felixfbecker/language-server-protocol/src'),
    '_HumbugBox1cb33d1f20f1\\JsonMapper\\' => array($vendorDir . '/netresearch/jsonmapper/src/JsonMapper'),
    '_HumbugBox1cb33d1f20f1\\Fidry\\CpuCoreCounter\\' => array($vendorDir . '/fidry/cpu-core-counter/src'),
    '_HumbugBox1cb33d1f20f1\\Composer\\XdebugHandler\\' => array($vendorDir . '/composer/xdebug-handler/src'),
    '_HumbugBox1cb33d1f20f1\\Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
    '_HumbugBox1cb33d1f20f1\\Composer\\Pcre\\' => array($vendorDir . '/composer/pcre/src'),
    '_HumbugBox1cb33d1f20f1\\Amp\\ByteStream\\' => array($vendorDir . '/amphp/byte-stream/lib'),
    '_HumbugBox1cb33d1f20f1\\Amp\\' => array($vendorDir . '/amphp/amp/lib'),
    '_HumbugBox1cb33d1f20f1\\AdvancedJsonRpc\\' => array($vendorDir . '/felixfbecker/advanced-json-rpc/lib'),
    'Psalm\\' => array($baseDir . '/src/Psalm'),
);
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver;

use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\Constraint;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\ConstraintInterface;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\MatchAllConstraint;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\MatchNoneConstraint;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\MultiConstraint;
/**
 * Helper class generating intervals from constraints
 *
 * This contains utilities for:
 *
 *  - compacting an existing constraint which can be used to combine several into one
 * by creating a MultiConstraint out of the many constraints you have.
 *
 *  - checking whether one subset is a subset of another.
 *
 * Note: You should call clear to free memoization memory  usage when you are done using this class
 */
class Intervals
{
    /**
     * @phpstan-var array<string, array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}>
     */
    private static $intervalsCache = array();
    /**
     * @phpstan-var array<string, int>
     */
    private static $opSortOrder = array('>=' => -3, '<' => -2, '>' => 2, '<=' => 3);
    /**
     * Clears the memoization cache once you are done
     *
     * @return void
     */
    public static function clear()
    {
        self::$intervalsCache = array();
    }
    /**
     * Checks whether $candidate is a subset of $constraint
     *
     * @return bool
     */
    public static function isSubsetOf(ConstraintInterface $candidate, ConstraintInterface $constraint)
    {
        if ($constraint instanceof MatchAllConstraint) {
            return \true;
        }
        if ($candidate instanceof MatchNoneConstraint || $constraint instanceof MatchNoneConstraint) {
            return \false;
        }
        $intersectionIntervals = self::get(new MultiConstraint(array($candidate, $constraint), \true));
        $candidateIntervals = self::get($candidate);
        if (\count($intersectionIntervals['numeric']) !== \count($candidateIntervals['numeric'])) {
            return \false;
        }
        foreach ($intersectionIntervals['numeric'] as $index => $interval) {
            if (!isset($candidateIntervals['numeric'][$index])) {
                return \false;
            }
            if ((string) $candidateIntervals['numeric'][$index]->getStart() !== (string) $interval->getStart()) {
                return \false;
            }
            if ((string) $candidateIntervals['numeric'][$index]->getEnd() !== (string) $interval->getEnd()) {
                return \false;
            }
        }
        if ($intersectionIntervals['branches']['exclude'] !== $candidateIntervals['branches']['exclude']) {
            return \false;
        }
        if (\count($intersectionIntervals['branches']['names']) !== \count($candidateIntervals['branches']['names'])) {
            return \false;
        }
        foreach ($intersectionIntervals['branches']['names'] as $index => $name) {
            if ($name !== $candidateIntervals['branches']['names'][$index]) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * Checks whether $a and $b have any intersection, equivalent to $a->matches($b)
     *
     * @return bool
     */
    public static function haveIntersections(ConstraintInterface $a, ConstraintInterface $b)
    {
        if ($a instanceof MatchAllConstraint || $b instanceof MatchAllConstraint) {
            return \true;
        }
        if ($a instanceof MatchNoneConstraint || $b instanceof MatchNoneConstraint) {
            return \false;
        }
        $intersectionIntervals = self::generateIntervals(new MultiConstraint(array($a, $b), \true), \true);
        return \count($intersectionIntervals['numeric']) > 0 || $intersectionIntervals['branches']['exclude'] || \count($intersectionIntervals['branches']['names']) > 0;
    }
    /**
     * Attempts to optimize a MultiConstraint
     *
     * When merging MultiConstraints together they can get very large, this will
     * compact it by looking at the real intervals covered by all the constraints
     * and then creates a new constraint containing only the smallest amount of rules
     * to match the same intervals.
     *
     * @return ConstraintInterface
     */
    public static function compactConstraint(ConstraintInterface $constraint)
    {
        if (!$constraint instanceof MultiConstraint) {
            return $constraint;
        }
        $intervals = self::generateIntervals($constraint);
        $constraints = array();
        $hasNumericMatchAll = \false;
        if (\count($intervals['numeric']) === 1 && (string) $intervals['numeric'][0]->getStart() === (string) Interval::fromZero() && (string) $intervals['numeric'][0]->getEnd() === (string) Interval::untilPositiveInfinity()) {
            $constraints[] = $intervals['numeric'][0]->getStart();
            $hasNumericMatchAll = \true;
        } else {
            $unEqualConstraints = array();
            for ($i = 0, $count = \count($intervals['numeric']); $i < $count; $i++) {
                $interval = $intervals['numeric'][$i];
                // if current interval ends with < N and next interval begins with > N we can swap this out for != N
                // but this needs to happen as a conjunctive expression together with the start of the current interval
                // and end of next interval, so [>=M, <N] || [>N, <P] => [>=M, !=N, <P] but M/P can be skipped if
                // they are zero/+inf
                if ($interval->getEnd()->getOperator() === '<' && $i + 1 < $count) {
                    $nextInterval = $intervals['numeric'][$i + 1];
                    if ($interval->getEnd()->getVersion() === $nextInterval->getStart()->getVersion() && $nextInterval->getStart()->getOperator() === '>') {
                        // only add a start if we didn't already do so, can be skipped if we're looking at second
                        // interval in [>=M, <N] || [>N, <P] || [>P, <Q] where unEqualConstraints currently contains
                        // [>=M, !=N] already and we only want to add !=P right now
                        if (\count($unEqualConstraints) === 0 && (string) $interval->getStart() !== (string) Interval::fromZero()) {
                            $unEqualConstraints[] = $interval->getStart();
                        }
                        $unEqualConstraints[] = new Constraint('!=', $interval->getEnd()->getVersion());
                        continue;
                    }
                }
                if (\count($unEqualConstraints) > 0) {
                    // this is where the end of the following interval of a != constraint is added as explained above
                    if ((string) $interval->getEnd() !== (string) Interval::untilPositiveInfinity()) {
                        $unEqualConstraints[] = $interval->getEnd();
                    }
                    // count is 1 if entire constraint is just one != expression
                    if (\count($unEqualConstraints) > 1) {
                        $constraints[] = new MultiConstraint($unEqualConstraints, \true);
                    } else {
                        $constraints[] = $unEqualConstraints[0];
                    }
                    $unEqualConstraints = array();
                    continue;
                }
                // convert back >= x - <= x intervals to == x
                if ($interval->getStart()->getVersion() === $interval->getEnd()->getVersion() && $interval->getStart()->getOperator() === '>=' && $interval->getEnd()->getOperator() === '<=') {
                    $constraints[] = new Constraint('==', $interval->getStart()->getVersion());
                    continue;
                }
                if ((string) $interval->getStart() === (string) Interval::fromZero()) {
                    $constraints[] = $interval->getEnd();
                } elseif ((string) $interval->getEnd() === (string) Interval::untilPositiveInfinity()) {
                    $constraints[] = $interval->getStart();
                } else {
                    $constraints[] = new MultiConstraint(array($interval->getStart(), $interval->getEnd()), \true);
                }
            }
        }
        $devConstraints = array();
        if (0 === \count($intervals['branches']['names'])) {
            if ($intervals['branches']['exclude']) {
                if ($hasNumericMatchAll) {
                    return new MatchAllConstraint();
                }
                // otherwise constraint should contain a != operator and already cover this
            }
        } else {
            foreach ($intervals['branches']['names'] as $branchName) {
                if ($intervals['branches']['exclude']) {
                    $devConstraints[] = new Constraint('!=', $branchName);
                } else {
                    $devConstraints[] = new Constraint('==', $branchName);
                }
            }
            // excluded branches, e.g. != dev-foo are conjunctive with the interval, so
            // > 2.0 != dev-foo must return a conjunctive constraint
            if ($intervals['branches']['exclude']) {
                if (\count($constraints) > 1) {
                    return new MultiConstraint(\array_merge(array(new MultiConstraint($constraints, \false)), $devConstraints), \true);
                }
                if (\count($constraints) === 1 && (string) $constraints[0] === (string) Interval::fromZero()) {
                    if (\count($devConstraints) > 1) {
                        return new MultiConstraint($devConstraints, \true);
                    }
                    return $devConstraints[0];
                }
                return new MultiConstraint(\array_merge($constraints, $devConstraints), \true);
            }
            // otherwise devConstraints contains a list of == operators for branches which are disjunctive with the
            // rest of the constraint
            $constraints = \array_merge($constraints, $devConstraints);
        }
        if (\count($constraints) > 1) {
            return new MultiConstraint($constraints, \false);
        }
        if (\count($constraints) === 1) {
            return $constraints[0];
        }
        return new MatchNoneConstraint();
    }
    /**
     * Creates an array of numeric intervals and branch constraints representing a given constraint
     *
     * if the returned numeric array is empty it means the constraint matches nothing in the numeric range (0 - +inf)
     * if the returned branches array is empty it means no dev-* versions are matched
     * if a constraint matches all possible dev-* versions, branches will contain Interval::anyDev()
     *
     * @return array
     * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
     */
    public static function get(ConstraintInterface $constraint)
    {
        $key = (string) $constraint;
        if (!isset(self::$intervalsCache[$key])) {
            self::$intervalsCache[$key] = self::generateIntervals($constraint);
        }
        return self::$intervalsCache[$key];
    }
    /**
     * @param bool $stopOnFirstValidInterval
     *
     * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
     */
    private static function generateIntervals(ConstraintInterface $constraint, $stopOnFirstValidInterval = \false)
    {
        if ($constraint instanceof MatchAllConstraint) {
            return array('numeric' => array(new Interval(Interval::fromZero(), Interval::untilPositiveInfinity())), 'branches' => Interval::anyDev());
        }
        if ($constraint instanceof MatchNoneConstraint) {
            return array('numeric' => array(), 'branches' => array('names' => array(), 'exclude' => \false));
        }
        if ($constraint instanceof Constraint) {
            return self::generateSingleConstraintIntervals($constraint);
        }
        if (!$constraint instanceof MultiConstraint) {
            throw new \UnexpectedValueException('The constraint passed in should be an MatchAllConstraint, Constraint or MultiConstraint instance, got ' . \get_class($constraint) . '.');
        }
        $constraints = $constraint->getConstraints();
        $numericGroups = array();
        $constraintBranches = array();
        foreach ($constraints as $c) {
            $res = self::get($c);
            $numericGroups[] = $res['numeric'];
            $constraintBranches[] = $res['branches'];
        }
        if ($constraint->isDisjunctive()) {
            $branches = Interval::noDev();
            foreach ($constraintBranches as $b) {
                if ($b['exclude']) {
                    if ($branches['exclude']) {
                        // disjunctive constraint, so only exclude what's excluded in all constraints
                        // !=a,!=b || !=b,!=c => !=b
                        $branches['names'] = \array_intersect($branches['names'], $b['names']);
                    } else {
                        // disjunctive constraint so exclude all names which are not explicitly included in the alternative
                        // (==b || ==c) || !=a,!=b => !=a
                        $branches['exclude'] = \true;
                        $branches['names'] = \array_diff($b['names'], $branches['names']);
                    }
                } else {
                    if ($branches['exclude']) {
                        // disjunctive constraint so exclude all names which are not explicitly included in the alternative
                        // !=a,!=b || (==b || ==c) => !=a
                        $branches['names'] = \array_diff($branches['names'], $b['names']);
                    } else {
                        // disjunctive constraint, so just add all the other branches
                        // (==a || ==b) || ==c => ==a || ==b || ==c
                        $branches['names'] = \array_merge($branches['names'], $b['names']);
                    }
                }
            }
        } else {
            $branches = Interval::anyDev();
            foreach ($constraintBranches as $b) {
                if ($b['exclude']) {
                    if ($branches['exclude']) {
                        // conjunctive, so just add all branch names to be excluded
                        // !=a && !=b => !=a,!=b
                        $branches['names'] = \array_merge($branches['names'], $b['names']);
                    } else {
                        // conjunctive, so only keep included names which are not excluded
                        // (==a||==c) && !=a,!=b => ==c
                        $branches['names'] = \array_diff($branches['names'], $b['names']);
                    }
                } else {
                    if ($branches['exclude']) {
                        // conjunctive, so only keep included names which are not excluded
                        // !=a,!=b && (==a||==c) => ==c
                        $branches['names'] = \array_diff($b['names'], $branches['names']);
                        $branches['exclude'] = \false;
                    } else {
                        // conjunctive, so only keep names that are included in both
                        // (==a||==b) && (==a||==c) => ==a
                        $branches['names'] = \array_intersect($branches['names'], $b['names']);
                    }
                }
            }
        }
        $branches['names'] = \array_unique($branches['names']);
        if (\count($numericGroups) === 1) {
            return array('numeric' => $numericGroups[0], 'branches' => $branches);
        }
        $borders = array();
        foreach ($numericGroups as $group) {
            foreach ($group as $interval) {
                $borders[] = array('version' => $interval->getStart()->getVersion(), 'operator' => $interval->getStart()->getOperator(), 'side' => 'start');
                $borders[] = array('version' => $interval->getEnd()->getVersion(), 'operator' => $interval->getEnd()->getOperator(), 'side' => 'end');
            }
        }
        $opSortOrder = self::$opSortOrder;
        \usort($borders, function ($a, $b) use($opSortOrder) {
            $order = \version_compare($a['version'], $b['version']);
            if ($order === 0) {
                return $opSortOrder[$a['operator']] - $opSortOrder[$b['operator']];
            }
            return $order;
        });
        $activeIntervals = 0;
        $intervals = array();
        $index = 0;
        $activationThreshold = $constraint->isConjunctive() ? \count($numericGroups) : 1;
        $start = null;
        foreach ($borders as $border) {
            if ($border['side'] === 'start') {
                $activeIntervals++;
            } else {
                $activeIntervals--;
            }
            if (!$start && $activeIntervals >= $activationThreshold) {
                $start = new Constraint($border['operator'], $border['version']);
            } elseif ($start && $activeIntervals < $activationThreshold) {
                // filter out invalid intervals like > x - <= x, or >= x - < x
                if (\version_compare($start->getVersion(), $border['version'], '=') && ($start->getOperator() === '>' && $border['operator'] === '<=' || $start->getOperator() === '>=' && $border['operator'] === '<')) {
                    unset($intervals[$index]);
                } else {
                    $intervals[$index] = new Interval($start, new Constraint($border['operator'], $border['version']));
                    $index++;
                    if ($stopOnFirstValidInterval) {
                        break;
                    }
                }
                $start = null;
            }
        }
        return array('numeric' => $intervals, 'branches' => $branches);
    }
    /**
     * @phpstan-return array{'numeric': Interval[], 'branches': array{'names': string[], 'exclude': bool}}
     */
    private static function generateSingleConstraintIntervals(Constraint $constraint)
    {
        $op = $constraint->getOperator();
        // handle branch constraints first
        if (\strpos($constraint->getVersion(), 'dev-') === 0) {
            $intervals = array();
            $branches = array('names' => array(), 'exclude' => \false);
            // != dev-foo means any numeric version may match, we treat >/< like != they are not really defined for branches
            if ($op === '!=') {
                $intervals[] = new Interval(Interval::fromZero(), Interval::untilPositiveInfinity());
                $branches = array('names' => array($constraint->getVersion()), 'exclude' => \true);
            } elseif ($op === '==') {
                $branches['names'][] = $constraint->getVersion();
            }
            return array('numeric' => $intervals, 'branches' => $branches);
        }
        if ($op[0] === '>') {
            // > & >=
            return array('numeric' => array(new Interval($constraint, Interval::untilPositiveInfinity())), 'branches' => Interval::noDev());
        }
        if ($op[0] === '<') {
            // < & <=
            return array('numeric' => array(new Interval(Interval::fromZero(), $constraint)), 'branches' => Interval::noDev());
        }
        if ($op === '!=') {
            // convert !=x to intervals of 0 - <x && >x - +inf + dev*
            return array('numeric' => array(new Interval(Interval::fromZero(), new Constraint('<', $constraint->getVersion())), new Interval(new Constraint('>', $constraint->getVersion()), Interval::untilPositiveInfinity())), 'branches' => Interval::anyDev());
        }
        // convert ==x to an interval of >=x - <=x
        return array('numeric' => array(new Interval(new Constraint('>=', $constraint->getVersion()), new Constraint('<=', $constraint->getVersion()))), 'branches' => Interval::noDev());
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver;

use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\Constraint;
class Semver
{
    const SORT_ASC = 1;
    const SORT_DESC = -1;
    /** @var VersionParser */
    private static $versionParser;
    /**
     * Determine if given version satisfies given constraints.
     *
     * @param string $version
     * @param string $constraints
     *
     * @return bool
     */
    public static function satisfies($version, $constraints)
    {
        if (null === self::$versionParser) {
            self::$versionParser = new VersionParser();
        }
        $versionParser = self::$versionParser;
        $provider = new Constraint('==', $versionParser->normalize($version));
        $parsedConstraints = $versionParser->parseConstraints($constraints);
        return $parsedConstraints->matches($provider);
    }
    /**
     * Return all versions that satisfy given constraints.
     *
     * @param string[] $versions
     * @param string   $constraints
     *
     * @return string[]
     */
    public static function satisfiedBy(array $versions, $constraints)
    {
        $versions = \array_filter($versions, function ($version) use($constraints) {
            return Semver::satisfies($version, $constraints);
        });
        return \array_values($versions);
    }
    /**
     * Sort given array of versions.
     *
     * @param string[] $versions
     *
     * @return string[]
     */
    public static function sort(array $versions)
    {
        return self::usort($versions, self::SORT_ASC);
    }
    /**
     * Sort given array of versions in reverse.
     *
     * @param string[] $versions
     *
     * @return string[]
     */
    public static function rsort(array $versions)
    {
        return self::usort($versions, self::SORT_DESC);
    }
    /**
     * @param string[] $versions
     * @param int      $direction
     *
     * @return string[]
     */
    private static function usort(array $versions, $direction)
    {
        if (null === self::$versionParser) {
            self::$versionParser = new VersionParser();
        }
        $versionParser = self::$versionParser;
        $normalized = array();
        // Normalize outside of usort() scope for minor performance increase.
        // Creates an array of arrays: [[normalized, key], ...]
        foreach ($versions as $key => $version) {
            $normalizedVersion = $versionParser->normalize($version);
            $normalizedVersion = $versionParser->normalizeDefaultBranch($normalizedVersion);
            $normalized[] = array($normalizedVersion, $key);
        }
        \usort($normalized, function (array $left, array $right) use($direction) {
            if ($left[0] === $right[0]) {
                return 0;
            }
            if (Comparator::lessThan($left[0], $right[0])) {
                return -$direction;
            }
            return $direction;
        });
        // Recreate input array, using the original indexes which are now in sorted order.
        $sorted = array();
        foreach ($normalized as $item) {
            $sorted[] = $versions[$item[1]];
        }
        return $sorted;
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver;

use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\ConstraintInterface;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\MatchAllConstraint;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\MultiConstraint;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\Constraint;
/**
 * Version parser.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 */
class VersionParser
{
    /**
     * Regex to match pre-release data (sort of).
     *
     * Due to backwards compatibility:
     *   - Instead of enforcing hyphen, an underscore, dot or nothing at all are also accepted.
     *   - Only stabilities as recognized by Composer are allowed to precede a numerical identifier.
     *   - Numerical-only pre-release identifiers are not supported, see tests.
     *
     *                        |--------------|
     * [major].[minor].[patch] -[pre-release] +[build-metadata]
     *
     * @var string
     */
    private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\\d+)*+)?)?([.-]?dev)?';
    /** @var string */
    private static $stabilitiesRegex = 'stable|RC|beta|alpha|dev';
    /**
     * Returns the stability of a version.
     *
     * @param string $version
     *
     * @return string
     * @phpstan-return 'stable'|'RC'|'beta'|'alpha'|'dev'
     */
    public static function parseStability($version)
    {
        $version = (string) \preg_replace('{#.+$}', '', (string) $version);
        if (\strpos($version, 'dev-') === 0 || '-dev' === \substr($version, -4)) {
            return 'dev';
        }
        \preg_match('{' . self::$modifierRegex . '(?:\\+.*)?$}i', \strtolower($version), $match);
        if (!empty($match[3])) {
            return 'dev';
        }
        if (!empty($match[1])) {
            if ('beta' === $match[1] || 'b' === $match[1]) {
                return 'beta';
            }
            if ('alpha' === $match[1] || 'a' === $match[1]) {
                return 'alpha';
            }
            if ('rc' === $match[1]) {
                return 'RC';
            }
        }
        return 'stable';
    }
    /**
     * @param string $stability
     *
     * @return string
     */
    public static function normalizeStability($stability)
    {
        $stability = \strtolower((string) $stability);
        return $stability === 'rc' ? 'RC' : $stability;
    }
    /**
     * Normalizes a version string to be able to perform comparisons on it.
     *
     * @param string $version
     * @param ?string $fullVersion optional complete version string to give more context
     *
     * @throws \UnexpectedValueException
     *
     * @return string
     */
    public function normalize($version, $fullVersion = null)
    {
        $version = \trim((string) $version);
        $origVersion = $version;
        if (null === $fullVersion) {
            $fullVersion = $version;
        }
        // strip off aliasing
        if (\preg_match('{^([^,\\s]++) ++as ++([^,\\s]++)$}', $version, $match)) {
            $version = $match[1];
        }
        // strip off stability flag
        if (\preg_match('{@(?:' . self::$stabilitiesRegex . ')$}i', $version, $match)) {
            $version = \substr($version, 0, \strlen($version) - \strlen($match[0]));
        }
        // normalize master/trunk/default branches to dev-name for BC with 1.x as these used to be valid constraints
        if (\in_array($version, array('master', 'trunk', 'default'), \true)) {
            $version = 'dev-' . $version;
        }
        // if requirement is branch-like, use full name
        if (\stripos($version, 'dev-') === 0) {
            return 'dev-' . \substr($version, 4);
        }
        // strip off build metadata
        if (\preg_match('{^([^,\\s+]++)\\+[^\\s]++$}', $version, $match)) {
            $version = $match[1];
        }
        // match classical versioning
        if (\preg_match('{^v?(\\d{1,5})(\\.\\d++)?(\\.\\d++)?(\\.\\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
            $version = $matches[1] . (!empty($matches[2]) ? $matches[2] : '.0') . (!empty($matches[3]) ? $matches[3] : '.0') . (!empty($matches[4]) ? $matches[4] : '.0');
            $index = 5;
            // match date(time) based versioning
        } elseif (\preg_match('{^v?(\\d{4}(?:[.:-]?\\d{2}){1,6}(?:[.:-]?\\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) {
            $version = \preg_replace('{\\D}', '.', $matches[1]);
            $index = 2;
        }
        // add version modifiers if a version was matched
        if (isset($index)) {
            if (!empty($matches[$index])) {
                if ('stable' === $matches[$index]) {
                    return $version;
                }
                $version .= '-' . $this->expandStability($matches[$index]) . (isset($matches[$index + 1]) && '' !== $matches[$index + 1] ? \ltrim($matches[$index + 1], '.-') : '');
            }
            if (!empty($matches[$index + 2])) {
                $version .= '-dev';
            }
            return $version;
        }
        // match dev branches
        if (\preg_match('{(.*?)[.-]?dev$}i', $version, $match)) {
            try {
                $normalized = $this->normalizeBranch($match[1]);
                // a branch ending with -dev is only valid if it is numeric
                // if it gets prefixed with dev- it means the branch name should
                // have had a dev- prefix already when passed to normalize
                if (\strpos($normalized, 'dev-') === \false) {
                    return $normalized;
                }
            } catch (\Exception $e) {
            }
        }
        $extraMessage = '';
        if (\preg_match('{ +as +' . \preg_quote($version) . '(?:@(?:' . self::$stabilitiesRegex . '))?$}', $fullVersion)) {
            $extraMessage = ' in "' . $fullVersion . '", the alias must be an exact version';
        } elseif (\preg_match('{^' . \preg_quote($version) . '(?:@(?:' . self::$stabilitiesRegex . '))? +as +}', $fullVersion)) {
            $extraMessage = ' in "' . $fullVersion . '", the alias source must be an exact version, if it is a branch name you should prefix it with dev-';
        }
        throw new \UnexpectedValueException('Invalid version string "' . $origVersion . '"' . $extraMessage);
    }
    /**
     * Extract numeric prefix from alias, if it is in numeric format, suitable for version comparison.
     *
     * @param string $branch Branch name (e.g. 2.1.x-dev)
     *
     * @return string|false Numeric prefix if present (e.g. 2.1.) or false
     */
    public function parseNumericAliasPrefix($branch)
    {
        if (\preg_match('{^(?P<version>(\\d++\\.)*\\d++)(?:\\.x)?-dev$}i', (string) $branch, $matches)) {
            return $matches['version'] . '.';
        }
        return \false;
    }
    /**
     * Normalizes a branch name to be able to perform comparisons on it.
     *
     * @param string $name
     *
     * @return string
     */
    public function normalizeBranch($name)
    {
        $name = \trim((string) $name);
        if (\preg_match('{^v?(\\d++)(\\.(?:\\d++|[xX*]))?(\\.(?:\\d++|[xX*]))?(\\.(?:\\d++|[xX*]))?$}i', $name, $matches)) {
            $version = '';
            for ($i = 1; $i < 5; ++$i) {
                $version .= isset($matches[$i]) ? \str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x';
            }
            return \str_replace('x', '9999999', $version) . '-dev';
        }
        return 'dev-' . $name;
    }
    /**
     * Normalizes a default branch name (i.e. master on git) to 9999999-dev.
     *
     * @param string $name
     *
     * @return string
     *
     * @deprecated No need to use this anymore in theory, Composer 2 does not normalize any branch names to 9999999-dev anymore
     */
    public function normalizeDefaultBranch($name)
    {
        if ($name === 'dev-master' || $name === 'dev-default' || $name === 'dev-trunk') {
            return '9999999-dev';
        }
        return (string) $name;
    }
    /**
     * Parses a constraint string into MultiConstraint and/or Constraint objects.
     *
     * @param string $constraints
     *
     * @return ConstraintInterface
     */
    public function parseConstraints($constraints)
    {
        $prettyConstraint = (string) $constraints;
        $orConstraints = \preg_split('{\\s*\\|\\|?\\s*}', \trim((string) $constraints));
        if (\false === $orConstraints) {
            throw new \RuntimeException('Failed to preg_split string: ' . $constraints);
        }
        $orGroups = array();
        foreach ($orConstraints as $constraints) {
            $andConstraints = \preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
            if (\false === $andConstraints) {
                throw new \RuntimeException('Failed to preg_split string: ' . $constraints);
            }
            if (\count($andConstraints) > 1) {
                $constraintObjects = array();
                foreach ($andConstraints as $constraint) {
                    foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
                        $constraintObjects[] = $parsedConstraint;
                    }
                }
            } else {
                $constraintObjects = $this->parseConstraint($andConstraints[0]);
            }
            if (1 === \count($constraintObjects)) {
                $constraint = $constraintObjects[0];
            } else {
                $constraint = new MultiConstraint($constraintObjects);
            }
            $orGroups[] = $constraint;
        }
        $constraint = MultiConstraint::create($orGroups, \false);
        $constraint->setPrettyString($prettyConstraint);
        return $constraint;
    }
    /**
     * @param string $constraint
     *
     * @throws \UnexpectedValueException
     *
     * @return array
     *
     * @phpstan-return non-empty-array<ConstraintInterface>
     */
    private function parseConstraint($constraint)
    {
        // strip off aliasing
        if (\preg_match('{^([^,\\s]++) ++as ++([^,\\s]++)$}', $constraint, $match)) {
            $constraint = $match[1];
        }
        // strip @stability flags, and keep it for later use
        if (\preg_match('{^([^,\\s]*?)@(' . self::$stabilitiesRegex . ')$}i', $constraint, $match)) {
            $constraint = '' !== $match[1] ? $match[1] : '*';
            if ($match[2] !== 'stable') {
                $stabilityModifier = $match[2];
            }
        }
        // get rid of #refs as those are used by composer only
        if (\preg_match('{^(dev-[^,\\s@]+?|[^,\\s@]+?\\.x-dev)#.+$}i', $constraint, $match)) {
            $constraint = $match[1];
        }
        if (\preg_match('{^(v)?[xX*](\\.[xX*])*$}i', $constraint, $match)) {
            if (!empty($match[1]) || !empty($match[2])) {
                return array(new Constraint('>=', '0.0.0.0-dev'));
            }
            return array(new MatchAllConstraint());
        }
        $versionRegex = 'v?(\\d++)(?:\\.(\\d++))?(?:\\.(\\d++))?(?:\\.(\\d++))?(?:' . self::$modifierRegex . '|\\.([xX*][.-]?dev))(?:\\+[^\\s]+)?';
        // Tilde Range
        //
        // Like wildcard constraints, unsuffixed tilde constraints say that they must be greater than the previous
        // version, to ensure that unstable instances of the current version are allowed. However, if a stability
        // suffix is added to the constraint, then a >= match on the current version is used instead.
        if (\preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
            if (\strpos($constraint, '~>') === 0) {
                throw new \UnexpectedValueException('Could not parse version constraint ' . $constraint . ': ' . 'Invalid operator "~>", you probably meant to use the "~" operator');
            }
            // Work out which position in the version we are operating at
            if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
                $position = 4;
            } elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }
            // when matching 2.x-dev or 3.0.x-dev we have to shift the second or third number, despite no second/third number matching above
            if (!empty($matches[8])) {
                $position++;
            }
            // Calculate the stability suffix
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7]) && empty($matches[8])) {
                $stabilitySuffix .= '-dev';
            }
            $lowVersion = $this->normalize(\substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);
            // For upper bound, we increment the position of one more significance,
            // but highPosition = 0 would be illegal
            $highPosition = \max(1, $position - 1);
            $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);
            return array($lowerBound, $upperBound);
        }
        // Caret Range
        //
        // Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple.
        // In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for
        // versions 0.X >=0.1.0, and no updates for versions 0.0.X
        if (\preg_match('{^\\^' . $versionRegex . '($)}i', $constraint, $matches)) {
            // Work out which position in the version we are operating at
            if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
                $position = 1;
            } elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
                $position = 2;
            } else {
                $position = 3;
            }
            // Calculate the stability suffix
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7]) && empty($matches[8])) {
                $stabilitySuffix .= '-dev';
            }
            $lowVersion = $this->normalize(\substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);
            // For upper bound, we increment the position of one more significance,
            // but highPosition = 0 would be illegal
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);
            return array($lowerBound, $upperBound);
        }
        // X Range
        //
        // Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple.
        // A partial version range is treated as an X-Range, so the special character is in fact optional.
        if (\preg_match('{^v?(\\d++)(?:\\.(\\d++))?(?:\\.(\\d++))?(?:\\.[xX*])++$}', $constraint, $matches)) {
            if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }
            $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev';
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
            if ($lowVersion === '0.0.0.0-dev') {
                return array(new Constraint('<', $highVersion));
            }
            return array(new Constraint('>=', $lowVersion), new Constraint('<', $highVersion));
        }
        // Hyphen Range
        //
        // Specifies an inclusive set. If a partial version is provided as the first version in the inclusive range,
        // then the missing pieces are replaced with zeroes. If a partial version is provided as the second version in
        // the inclusive range, then all versions that start with the supplied parts of the tuple are accepted, but
        // nothing that would be greater than the provided tuple parts.
        if (\preg_match('{^(?P<from>' . $versionRegex . ') +- +(?P<to>' . $versionRegex . ')($)}i', $constraint, $matches)) {
            // Calculate the stability suffix
            $lowStabilitySuffix = '';
            if (empty($matches[6]) && empty($matches[8]) && empty($matches[9])) {
                $lowStabilitySuffix = '-dev';
            }
            $lowVersion = $this->normalize($matches['from']);
            $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix);
            $empty = function ($x) {
                return $x === 0 || $x === '0' ? \false : empty($x);
            };
            if (!$empty($matches[12]) && !$empty($matches[13]) || !empty($matches[15]) || !empty($matches[17]) || !empty($matches[18])) {
                $highVersion = $this->normalize($matches['to']);
                $upperBound = new Constraint('<=', $highVersion);
            } else {
                $highMatch = array('', $matches[11], $matches[12], $matches[13], $matches[14]);
                // validate to version
                $this->normalize($matches['to']);
                $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[12]) ? 1 : 2, 1) . '-dev';
                $upperBound = new Constraint('<', $highVersion);
            }
            return array($lowerBound, $upperBound);
        }
        // Basic Comparators
        if (\preg_match('{^(<>|!=|>=?|<=?|==?)?\\s*(.*)}', $constraint, $matches)) {
            try {
                try {
                    $version = $this->normalize($matches[2]);
                } catch (\UnexpectedValueException $e) {
                    // recover from an invalid constraint like foobar-dev which should be dev-foobar
                    // except if the constraint uses a known operator, in which case it must be a parse error
                    if (\substr($matches[2], -4) === '-dev' && \preg_match('{^[0-9a-zA-Z-./]+$}', $matches[2])) {
                        $version = $this->normalize('dev-' . \substr($matches[2], 0, -4));
                    } else {
                        throw $e;
                    }
                }
                $op = $matches[1] ?: '=';
                if ($op !== '==' && $op !== '=' && !empty($stabilityModifier) && self::parseStability($version) === 'stable') {
                    $version .= '-' . $stabilityModifier;
                } elseif ('<' === $op || '>=' === $op) {
                    if (!\preg_match('/-' . self::$modifierRegex . '$/', \strtolower($matches[2]))) {
                        if (\strpos($matches[2], 'dev-') !== 0) {
                            $version .= '-dev';
                        }
                    }
                }
                return array(new Constraint($matches[1] ?: '=', $version));
            } catch (\Exception $e) {
            }
        }
        $message = 'Could not parse version constraint ' . $constraint;
        if (isset($e)) {
            $message .= ': ' . $e->getMessage();
        }
        throw new \UnexpectedValueException($message);
    }
    /**
     * Increment, decrement, or simply pad a version number.
     *
     * Support function for {@link parseConstraint()}
     *
     * @param array  $matches   Array with version parts in array indexes 1,2,3,4
     * @param int    $position  1,2,3,4 - which segment of the version to increment/decrement
     * @param int    $increment
     * @param string $pad       The string to pad version parts after $position
     *
     * @return string|null The new version
     *
     * @phpstan-param string[] $matches
     */
    private function manipulateVersionString(array $matches, $position, $increment = 0, $pad = '0')
    {
        for ($i = 4; $i > 0; --$i) {
            if ($i > $position) {
                $matches[$i] = $pad;
            } elseif ($i === $position && $increment) {
                $matches[$i] += $increment;
                // If $matches[$i] was 0, carry the decrement
                if ($matches[$i] < 0) {
                    $matches[$i] = $pad;
                    --$position;
                    // Return null on a carry overflow
                    if ($i === 1) {
                        return null;
                    }
                }
            }
        }
        return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4];
    }
    /**
     * Expand shorthand stability string to long version.
     *
     * @param string $stability
     *
     * @return string
     */
    private function expandStability($stability)
    {
        $stability = \strtolower($stability);
        switch ($stability) {
            case 'a':
                return 'alpha';
            case 'b':
                return 'beta';
            case 'p':
            case 'pl':
                return 'patch';
            case 'rc':
                return 'RC';
            default:
                return $stability;
        }
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint;

/**
 * Blackhole of constraints, nothing escapes it
 */
class MatchNoneConstraint implements ConstraintInterface
{
    /** @var string|null */
    protected $prettyString;
    /**
     * @param ConstraintInterface $provider
     *
     * @return bool
     */
    public function matches(ConstraintInterface $provider)
    {
        return \false;
    }
    /**
     * {@inheritDoc}
     */
    public function compile($otherOperator)
    {
        return 'false';
    }
    /**
     * {@inheritDoc}
     */
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    /**
     * {@inheritDoc}
     */
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return (string) $this;
    }
    /**
     * {@inheritDoc}
     */
    public function __toString()
    {
        return '[]';
    }
    /**
     * {@inheritDoc}
     */
    public function getUpperBound()
    {
        return new Bound('0.0.0.0-dev', \false);
    }
    /**
     * {@inheritDoc}
     */
    public function getLowerBound()
    {
        return new Bound('0.0.0.0-dev', \false);
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint;

/**
 * Defines the absence of a constraint.
 *
 * This constraint matches everything.
 */
class MatchAllConstraint implements ConstraintInterface
{
    /** @var string|null */
    protected $prettyString;
    /**
     * @param ConstraintInterface $provider
     *
     * @return bool
     */
    public function matches(ConstraintInterface $provider)
    {
        return \true;
    }
    /**
     * {@inheritDoc}
     */
    public function compile($otherOperator)
    {
        return 'true';
    }
    /**
     * {@inheritDoc}
     */
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    /**
     * {@inheritDoc}
     */
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return (string) $this;
    }
    /**
     * {@inheritDoc}
     */
    public function __toString()
    {
        return '*';
    }
    /**
     * {@inheritDoc}
     */
    public function getUpperBound()
    {
        return Bound::positiveInfinity();
    }
    /**
     * {@inheritDoc}
     */
    public function getLowerBound()
    {
        return Bound::zero();
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint;

/**
 * Defines a constraint.
 */
class Constraint implements ConstraintInterface
{
    /* operator integer values */
    const OP_EQ = 0;
    const OP_LT = 1;
    const OP_LE = 2;
    const OP_GT = 3;
    const OP_GE = 4;
    const OP_NE = 5;
    /* operator string values */
    const STR_OP_EQ = '==';
    const STR_OP_EQ_ALT = '=';
    const STR_OP_LT = '<';
    const STR_OP_LE = '<=';
    const STR_OP_GT = '>';
    const STR_OP_GE = '>=';
    const STR_OP_NE = '!=';
    const STR_OP_NE_ALT = '<>';
    /**
     * Operator to integer translation table.
     *
     * @var array
     * @phpstan-var array<self::STR_OP_*, self::OP_*>
     */
    private static $transOpStr = array('=' => self::OP_EQ, '==' => self::OP_EQ, '<' => self::OP_LT, '<=' => self::OP_LE, '>' => self::OP_GT, '>=' => self::OP_GE, '<>' => self::OP_NE, '!=' => self::OP_NE);
    /**
     * Integer to operator translation table.
     *
     * @var array
     * @phpstan-var array<self::OP_*, self::STR_OP_*>
     */
    private static $transOpInt = array(self::OP_EQ => '==', self::OP_LT => '<', self::OP_LE => '<=', self::OP_GT => '>', self::OP_GE => '>=', self::OP_NE => '!=');
    /**
     * @var int
     * @phpstan-var self::OP_*
     */
    protected $operator;
    /** @var string */
    protected $version;
    /** @var string|null */
    protected $prettyString;
    /** @var Bound */
    protected $lowerBound;
    /** @var Bound */
    protected $upperBound;
    /**
     * Sets operator and version to compare with.
     *
     * @param string $operator
     * @param string $version
     *
     * @throws \InvalidArgumentException if invalid operator is given.
     *
     * @phpstan-param self::STR_OP_* $operator
     */
    public function __construct($operator, $version)
    {
        if (!isset(self::$transOpStr[$operator])) {
            throw new \InvalidArgumentException(\sprintf('Invalid operator "%s" given, expected one of: %s', $operator, \implode(', ', self::getSupportedOperators())));
        }
        $this->operator = self::$transOpStr[$operator];
        $this->version = $version;
    }
    /**
     * @return string
     */
    public function getVersion()
    {
        return $this->version;
    }
    /**
     * @return string
     *
     * @phpstan-return self::STR_OP_*
     */
    public function getOperator()
    {
        return self::$transOpInt[$this->operator];
    }
    /**
     * @param ConstraintInterface $provider
     *
     * @return bool
     */
    public function matches(ConstraintInterface $provider)
    {
        if ($provider instanceof self) {
            return $this->matchSpecific($provider);
        }
        // turn matching around to find a match
        return $provider->matches($this);
    }
    /**
     * {@inheritDoc}
     */
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    /**
     * {@inheritDoc}
     */
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return $this->__toString();
    }
    /**
     * Get all supported comparison operators.
     *
     * @return array
     *
     * @phpstan-return list<self::STR_OP_*>
     */
    public static function getSupportedOperators()
    {
        return \array_keys(self::$transOpStr);
    }
    /**
     * @param  string $operator
     * @return int
     *
     * @phpstan-param  self::STR_OP_* $operator
     * @phpstan-return self::OP_*
     */
    public static function getOperatorConstant($operator)
    {
        return self::$transOpStr[$operator];
    }
    /**
     * @param string $a
     * @param string $b
     * @param string $operator
     * @param bool   $compareBranches
     *
     * @throws \InvalidArgumentException if invalid operator is given.
     *
     * @return bool
     *
     * @phpstan-param self::STR_OP_* $operator
     */
    public function versionCompare($a, $b, $operator, $compareBranches = \false)
    {
        if (!isset(self::$transOpStr[$operator])) {
            throw new \InvalidArgumentException(\sprintf('Invalid operator "%s" given, expected one of: %s', $operator, \implode(', ', self::getSupportedOperators())));
        }
        $aIsBranch = \strpos($a, 'dev-') === 0;
        $bIsBranch = \strpos($b, 'dev-') === 0;
        if ($operator === '!=' && ($aIsBranch || $bIsBranch)) {
            return $a !== $b;
        }
        if ($aIsBranch && $bIsBranch) {
            return $operator === '==' && $a === $b;
        }
        // when branches are not comparable, we make sure dev branches never match anything
        if (!$compareBranches && ($aIsBranch || $bIsBranch)) {
            return \false;
        }
        return \version_compare($a, $b, $operator);
    }
    /**
     * {@inheritDoc}
     */
    public function compile($otherOperator)
    {
        if (\strpos($this->version, 'dev-') === 0) {
            if (self::OP_EQ === $this->operator) {
                if (self::OP_EQ === $otherOperator) {
                    return \sprintf('$b && $v === %s', \var_export($this->version, \true));
                }
                if (self::OP_NE === $otherOperator) {
                    return \sprintf('!$b || $v !== %s', \var_export($this->version, \true));
                }
                return 'false';
            }
            if (self::OP_NE === $this->operator) {
                if (self::OP_EQ === $otherOperator) {
                    return \sprintf('!$b || $v !== %s', \var_export($this->version, \true));
                }
                if (self::OP_NE === $otherOperator) {
                    return 'true';
                }
                return '!$b';
            }
            return 'false';
        }
        if (self::OP_EQ === $this->operator) {
            if (self::OP_EQ === $otherOperator) {
                return \sprintf('\\version_compare($v, %s, \'==\')', \var_export($this->version, \true));
            }
            if (self::OP_NE === $otherOperator) {
                return \sprintf('$b || \\version_compare($v, %s, \'!=\')', \var_export($this->version, \true));
            }
            return \sprintf('!$b && \\version_compare(%s, $v, \'%s\')', \var_export($this->version, \true), self::$transOpInt[$otherOperator]);
        }
        if (self::OP_NE === $this->operator) {
            if (self::OP_EQ === $otherOperator) {
                return \sprintf('$b || (!$b && \\version_compare($v, %s, \'!=\'))', \var_export($this->version, \true));
            }
            if (self::OP_NE === $otherOperator) {
                return 'true';
            }
            return '!$b';
        }
        if (self::OP_LT === $this->operator || self::OP_LE === $this->operator) {
            if (self::OP_LT === $otherOperator || self::OP_LE === $otherOperator) {
                return '!$b';
            }
        } else {
            // $this->operator must be self::OP_GT || self::OP_GE here
            if (self::OP_GT === $otherOperator || self::OP_GE === $otherOperator) {
                return '!$b';
            }
        }
        if (self::OP_NE === $otherOperator) {
            return 'true';
        }
        $codeComparison = \sprintf('\\version_compare($v, %s, \'%s\')', \var_export($this->version, \true), self::$transOpInt[$this->operator]);
        if ($this->operator === self::OP_LE) {
            if ($otherOperator === self::OP_GT) {
                return \sprintf('!$b && \\version_compare($v, %s, \'!=\') && ', \var_export($this->version, \true)) . $codeComparison;
            }
        } elseif ($this->operator === self::OP_GE) {
            if ($otherOperator === self::OP_LT) {
                return \sprintf('!$b && \\version_compare($v, %s, \'!=\') && ', \var_export($this->version, \true)) . $codeComparison;
            }
        }
        return \sprintf('!$b && %s', $codeComparison);
    }
    /**
     * @param Constraint $provider
     * @param bool       $compareBranches
     *
     * @return bool
     */
    public function matchSpecific(Constraint $provider, $compareBranches = \false)
    {
        $noEqualOp = \str_replace('=', '', self::$transOpInt[$this->operator]);
        $providerNoEqualOp = \str_replace('=', '', self::$transOpInt[$provider->operator]);
        $isEqualOp = self::OP_EQ === $this->operator;
        $isNonEqualOp = self::OP_NE === $this->operator;
        $isProviderEqualOp = self::OP_EQ === $provider->operator;
        $isProviderNonEqualOp = self::OP_NE === $provider->operator;
        // '!=' operator is match when other operator is not '==' operator or version is not match
        // these kinds of comparisons always have a solution
        if ($isNonEqualOp || $isProviderNonEqualOp) {
            if ($isNonEqualOp && !$isProviderNonEqualOp && !$isProviderEqualOp && \strpos($provider->version, 'dev-') === 0) {
                return \false;
            }
            if ($isProviderNonEqualOp && !$isNonEqualOp && !$isEqualOp && \strpos($this->version, 'dev-') === 0) {
                return \false;
            }
            if (!$isEqualOp && !$isProviderEqualOp) {
                return \true;
            }
            return $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
        }
        // an example for the condition is <= 2.0 & < 1.0
        // these kinds of comparisons always have a solution
        if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) {
            return !(\strpos($this->version, 'dev-') === 0 || \strpos($provider->version, 'dev-') === 0);
        }
        $version1 = $isEqualOp ? $this->version : $provider->version;
        $version2 = $isEqualOp ? $provider->version : $this->version;
        $operator = $isEqualOp ? $provider->operator : $this->operator;
        if ($this->versionCompare($version1, $version2, self::$transOpInt[$operator], $compareBranches)) {
            // special case, e.g. require >= 1.0 and provide < 1.0
            // 1.0 >= 1.0 but 1.0 is outside of the provided interval
            return !(self::$transOpInt[$provider->operator] === $providerNoEqualOp && self::$transOpInt[$this->operator] !== $noEqualOp && \version_compare($provider->version, $this->version, '=='));
        }
        return \false;
    }
    /**
     * @return string
     */
    public function __toString()
    {
        return self::$transOpInt[$this->operator] . ' ' . $this->version;
    }
    /**
     * {@inheritDoc}
     */
    public function getLowerBound()
    {
        $this->extractBounds();
        return $this->lowerBound;
    }
    /**
     * {@inheritDoc}
     */
    public function getUpperBound()
    {
        $this->extractBounds();
        return $this->upperBound;
    }
    /**
     * @return void
     */
    private function extractBounds()
    {
        if (null !== $this->lowerBound) {
            return;
        }
        // Branches
        if (\strpos($this->version, 'dev-') === 0) {
            $this->lowerBound = Bound::zero();
            $this->upperBound = Bound::positiveInfinity();
            return;
        }
        switch ($this->operator) {
            case self::OP_EQ:
                $this->lowerBound = new Bound($this->version, \true);
                $this->upperBound = new Bound($this->version, \true);
                break;
            case self::OP_LT:
                $this->lowerBound = Bound::zero();
                $this->upperBound = new Bound($this->version, \false);
                break;
            case self::OP_LE:
                $this->lowerBound = Bound::zero();
                $this->upperBound = new Bound($this->version, \true);
                break;
            case self::OP_GT:
                $this->lowerBound = new Bound($this->version, \false);
                $this->upperBound = Bound::positiveInfinity();
                break;
            case self::OP_GE:
                $this->lowerBound = new Bound($this->version, \true);
                $this->upperBound = Bound::positiveInfinity();
                break;
            case self::OP_NE:
                $this->lowerBound = Bound::zero();
                $this->upperBound = Bound::positiveInfinity();
                break;
        }
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint;

/**
 * Defines a conjunctive or disjunctive set of constraints.
 */
class MultiConstraint implements ConstraintInterface
{
    /**
     * @var ConstraintInterface[]
     * @phpstan-var non-empty-array<ConstraintInterface>
     */
    protected $constraints;
    /** @var string|null */
    protected $prettyString;
    /** @var string|null */
    protected $string;
    /** @var bool */
    protected $conjunctive;
    /** @var Bound|null */
    protected $lowerBound;
    /** @var Bound|null */
    protected $upperBound;
    /**
     * @param ConstraintInterface[] $constraints A set of constraints
     * @param bool                  $conjunctive Whether the constraints should be treated as conjunctive or disjunctive
     *
     * @throws \InvalidArgumentException If less than 2 constraints are passed
     */
    public function __construct(array $constraints, $conjunctive = \true)
    {
        if (\count($constraints) < 2) {
            throw new \InvalidArgumentException('Must provide at least two constraints for a MultiConstraint. Use ' . 'the regular Constraint class for one constraint only or MatchAllConstraint for none. You may use ' . 'MultiConstraint::create() which optimizes and handles those cases automatically.');
        }
        $this->constraints = $constraints;
        $this->conjunctive = $conjunctive;
    }
    /**
     * @return ConstraintInterface[]
     */
    public function getConstraints()
    {
        return $this->constraints;
    }
    /**
     * @return bool
     */
    public function isConjunctive()
    {
        return $this->conjunctive;
    }
    /**
     * @return bool
     */
    public function isDisjunctive()
    {
        return !$this->conjunctive;
    }
    /**
     * {@inheritDoc}
     */
    public function compile($otherOperator)
    {
        $parts = array();
        foreach ($this->constraints as $constraint) {
            $code = $constraint->compile($otherOperator);
            if ($code === 'true') {
                if (!$this->conjunctive) {
                    return 'true';
                }
            } elseif ($code === 'false') {
                if ($this->conjunctive) {
                    return 'false';
                }
            } else {
                $parts[] = '(' . $code . ')';
            }
        }
        if (!$parts) {
            return $this->conjunctive ? 'true' : 'false';
        }
        return $this->conjunctive ? \implode('&&', $parts) : \implode('||', $parts);
    }
    /**
     * @param ConstraintInterface $provider
     *
     * @return bool
     */
    public function matches(ConstraintInterface $provider)
    {
        if (\false === $this->conjunctive) {
            foreach ($this->constraints as $constraint) {
                if ($provider->matches($constraint)) {
                    return \true;
                }
            }
            return \false;
        }
        // when matching a conjunctive and a disjunctive multi constraint we have to iterate over the disjunctive one
        // otherwise we'd return true if different parts of the disjunctive constraint match the conjunctive one
        // which would lead to incorrect results, e.g. [>1 and <2] would match [<1 or >2] although they do not intersect
        if ($provider instanceof MultiConstraint && $provider->isDisjunctive()) {
            return $provider->matches($this);
        }
        foreach ($this->constraints as $constraint) {
            if (!$provider->matches($constraint)) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * {@inheritDoc}
     */
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    /**
     * {@inheritDoc}
     */
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return (string) $this;
    }
    /**
     * {@inheritDoc}
     */
    public function __toString()
    {
        if ($this->string !== null) {
            return $this->string;
        }
        $constraints = array();
        foreach ($this->constraints as $constraint) {
            $constraints[] = (string) $constraint;
        }
        return $this->string = '[' . \implode($this->conjunctive ? ' ' : ' || ', $constraints) . ']';
    }
    /**
     * {@inheritDoc}
     */
    public function getLowerBound()
    {
        $this->extractBounds();
        if (null === $this->lowerBound) {
            throw new \LogicException('extractBounds should have populated the lowerBound property');
        }
        return $this->lowerBound;
    }
    /**
     * {@inheritDoc}
     */
    public function getUpperBound()
    {
        $this->extractBounds();
        if (null === $this->upperBound) {
            throw new \LogicException('extractBounds should have populated the upperBound property');
        }
        return $this->upperBound;
    }
    /**
     * Tries to optimize the constraints as much as possible, meaning
     * reducing/collapsing congruent constraints etc.
     * Does not necessarily return a MultiConstraint instance if
     * things can be reduced to a simple constraint
     *
     * @param ConstraintInterface[] $constraints A set of constraints
     * @param bool                  $conjunctive Whether the constraints should be treated as conjunctive or disjunctive
     *
     * @return ConstraintInterface
     */
    public static function create(array $constraints, $conjunctive = \true)
    {
        if (0 === \count($constraints)) {
            return new MatchAllConstraint();
        }
        if (1 === \count($constraints)) {
            return $constraints[0];
        }
        $optimized = self::optimizeConstraints($constraints, $conjunctive);
        if ($optimized !== null) {
            list($constraints, $conjunctive) = $optimized;
            if (\count($constraints) === 1) {
                return $constraints[0];
            }
        }
        return new self($constraints, $conjunctive);
    }
    /**
     * @param  ConstraintInterface[] $constraints
     * @param  bool                  $conjunctive
     * @return ?array
     *
     * @phpstan-return array{0: list<ConstraintInterface>, 1: bool}|null
     */
    private static function optimizeConstraints(array $constraints, $conjunctive)
    {
        // parse the two OR groups and if they are contiguous we collapse
        // them into one constraint
        // [>= 1 < 2] || [>= 2 < 3] || [>= 3 < 4] => [>= 1 < 4]
        if (!$conjunctive) {
            $left = $constraints[0];
            $mergedConstraints = array();
            $optimized = \false;
            for ($i = 1, $l = \count($constraints); $i < $l; $i++) {
                $right = $constraints[$i];
                if ($left instanceof self && $left->conjunctive && $right instanceof self && $right->conjunctive && \count($left->constraints) === 2 && \count($right->constraints) === 2 && ($left0 = (string) $left->constraints[0]) && $left0[0] === '>' && $left0[1] === '=' && ($left1 = (string) $left->constraints[1]) && $left1[0] === '<' && ($right0 = (string) $right->constraints[0]) && $right0[0] === '>' && $right0[1] === '=' && ($right1 = (string) $right->constraints[1]) && $right1[0] === '<' && \substr($left1, 2) === \substr($right0, 3)) {
                    $optimized = \true;
                    $left = new MultiConstraint(array($left->constraints[0], $right->constraints[1]), \true);
                } else {
                    $mergedConstraints[] = $left;
                    $left = $right;
                }
            }
            if ($optimized) {
                $mergedConstraints[] = $left;
                return array($mergedConstraints, \false);
            }
        }
        // TODO: Here's the place to put more optimizations
        return null;
    }
    /**
     * @return void
     */
    private function extractBounds()
    {
        if (null !== $this->lowerBound) {
            return;
        }
        foreach ($this->constraints as $constraint) {
            if (null === $this->lowerBound || null === $this->upperBound) {
                $this->lowerBound = $constraint->getLowerBound();
                $this->upperBound = $constraint->getUpperBound();
                continue;
            }
            if ($constraint->getLowerBound()->compareTo($this->lowerBound, $this->isConjunctive() ? '>' : '<')) {
                $this->lowerBound = $constraint->getLowerBound();
            }
            if ($constraint->getUpperBound()->compareTo($this->upperBound, $this->isConjunctive() ? '<' : '>')) {
                $this->upperBound = $constraint->getUpperBound();
            }
        }
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint;

class Bound
{
    /**
     * @var string
     */
    private $version;
    /**
     * @var bool
     */
    private $isInclusive;
    /**
     * @param string $version
     * @param bool   $isInclusive
     */
    public function __construct($version, $isInclusive)
    {
        $this->version = $version;
        $this->isInclusive = $isInclusive;
    }
    /**
     * @return string
     */
    public function getVersion()
    {
        return $this->version;
    }
    /**
     * @return bool
     */
    public function isInclusive()
    {
        return $this->isInclusive;
    }
    /**
     * @return bool
     */
    public function isZero()
    {
        return $this->getVersion() === '0.0.0.0-dev' && $this->isInclusive();
    }
    /**
     * @return bool
     */
    public function isPositiveInfinity()
    {
        return $this->getVersion() === \PHP_INT_MAX . '.0.0.0' && !$this->isInclusive();
    }
    /**
     * Compares a bound to another with a given operator.
     *
     * @param Bound  $other
     * @param string $operator
     *
     * @return bool
     */
    public function compareTo(Bound $other, $operator)
    {
        if (!\in_array($operator, array('<', '>'), \true)) {
            throw new \InvalidArgumentException('Does not support any other operator other than > or <.');
        }
        // If they are the same it doesn't matter
        if ($this == $other) {
            return \false;
        }
        $compareResult = \version_compare($this->getVersion(), $other->getVersion());
        // Not the same version means we don't need to check if the bounds are inclusive or not
        if (0 !== $compareResult) {
            return ('>' === $operator ? 1 : -1) === $compareResult;
        }
        // Question we're answering here is "am I higher than $other?"
        return '>' === $operator ? $other->isInclusive() : !$other->isInclusive();
    }
    public function __toString()
    {
        return \sprintf('%s [%s]', $this->getVersion(), $this->isInclusive() ? 'inclusive' : 'exclusive');
    }
    /**
     * @return self
     */
    public static function zero()
    {
        return new Bound('0.0.0.0-dev', \true);
    }
    /**
     * @return self
     */
    public static function positiveInfinity()
    {
        return new Bound(\PHP_INT_MAX . '.0.0.0', \false);
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint;

/**
 * DO NOT IMPLEMENT this interface. It is only meant for usage as a type hint
 * in libraries relying on composer/semver but creating your own constraint class
 * that implements this interface is not a supported use case and will cause the
 * composer/semver components to return unexpected results.
 */
interface ConstraintInterface
{
    /**
     * Checks whether the given constraint intersects in any way with this constraint
     *
     * @param ConstraintInterface $provider
     *
     * @return bool
     */
    public function matches(ConstraintInterface $provider);
    /**
     * Provides a compiled version of the constraint for the given operator
     * The compiled version must be a PHP expression.
     * Executor of compile version must provide 2 variables:
     * - $v = the string version to compare with
     * - $b = whether or not the version is a non-comparable branch (starts with "dev-")
     *
     * @see Constraint::OP_* for the list of available operators.
     * @example return '!$b && version_compare($v, '1.0', '>')';
     *
     * @param int $otherOperator one Constraint::OP_*
     *
     * @return string
     *
     * @phpstan-param Constraint::OP_* $otherOperator
     */
    public function compile($otherOperator);
    /**
     * @return Bound
     */
    public function getUpperBound();
    /**
     * @return Bound
     */
    public function getLowerBound();
    /**
     * @return string
     */
    public function getPrettyString();
    /**
     * @param string|null $prettyString
     *
     * @return void
     */
    public function setPrettyString($prettyString);
    /**
     * @return string
     */
    public function __toString();
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver;

use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\Constraint;
class Comparator
{
    /**
     * Evaluates the expression: $version1 > $version2.
     *
     * @param string $version1
     * @param string $version2
     *
     * @return bool
     */
    public static function greaterThan($version1, $version2)
    {
        return self::compare($version1, '>', $version2);
    }
    /**
     * Evaluates the expression: $version1 >= $version2.
     *
     * @param string $version1
     * @param string $version2
     *
     * @return bool
     */
    public static function greaterThanOrEqualTo($version1, $version2)
    {
        return self::compare($version1, '>=', $version2);
    }
    /**
     * Evaluates the expression: $version1 < $version2.
     *
     * @param string $version1
     * @param string $version2
     *
     * @return bool
     */
    public static function lessThan($version1, $version2)
    {
        return self::compare($version1, '<', $version2);
    }
    /**
     * Evaluates the expression: $version1 <= $version2.
     *
     * @param string $version1
     * @param string $version2
     *
     * @return bool
     */
    public static function lessThanOrEqualTo($version1, $version2)
    {
        return self::compare($version1, '<=', $version2);
    }
    /**
     * Evaluates the expression: $version1 == $version2.
     *
     * @param string $version1
     * @param string $version2
     *
     * @return bool
     */
    public static function equalTo($version1, $version2)
    {
        return self::compare($version1, '==', $version2);
    }
    /**
     * Evaluates the expression: $version1 != $version2.
     *
     * @param string $version1
     * @param string $version2
     *
     * @return bool
     */
    public static function notEqualTo($version1, $version2)
    {
        return self::compare($version1, '!=', $version2);
    }
    /**
     * Evaluates the expression: $version1 $operator $version2.
     *
     * @param string $version1
     * @param string $operator
     * @param string $version2
     *
     * @return bool
     *
     * @phpstan-param Constraint::STR_OP_*  $operator
     */
    public static function compare($version1, $operator, $version2)
    {
        $constraint = new Constraint($operator, $version2);
        return $constraint->matchSpecific(new Constraint('==', $version1), \true);
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver;

use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\Constraint;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\ConstraintInterface;
/**
 * Helper class to evaluate constraint by compiling and reusing the code to evaluate
 */
class CompilingMatcher
{
    /**
     * @var array
     * @phpstan-var array<string, callable>
     */
    private static $compiledCheckerCache = array();
    /**
     * @var array
     * @phpstan-var array<string, bool>
     */
    private static $resultCache = array();
    /** @var bool */
    private static $enabled;
    /**
     * @phpstan-var array<Constraint::OP_*, Constraint::STR_OP_*>
     */
    private static $transOpInt = array(Constraint::OP_EQ => Constraint::STR_OP_EQ, Constraint::OP_LT => Constraint::STR_OP_LT, Constraint::OP_LE => Constraint::STR_OP_LE, Constraint::OP_GT => Constraint::STR_OP_GT, Constraint::OP_GE => Constraint::STR_OP_GE, Constraint::OP_NE => Constraint::STR_OP_NE);
    /**
     * Clears the memoization cache once you are done
     *
     * @return void
     */
    public static function clear()
    {
        self::$resultCache = array();
        self::$compiledCheckerCache = array();
    }
    /**
     * Evaluates the expression: $constraint match $operator $version
     *
     * @param ConstraintInterface $constraint
     * @param int                 $operator
     * @phpstan-param Constraint::OP_*  $operator
     * @param string              $version
     *
     * @return mixed
     */
    public static function match(ConstraintInterface $constraint, $operator, $version)
    {
        $resultCacheKey = $operator . $constraint . ';' . $version;
        if (isset(self::$resultCache[$resultCacheKey])) {
            return self::$resultCache[$resultCacheKey];
        }
        if (self::$enabled === null) {
            self::$enabled = !\in_array('eval', \explode(',', (string) \ini_get('disable_functions')), \true);
        }
        if (!self::$enabled) {
            return self::$resultCache[$resultCacheKey] = $constraint->matches(new Constraint(self::$transOpInt[$operator], $version));
        }
        $cacheKey = $operator . $constraint;
        if (!isset(self::$compiledCheckerCache[$cacheKey])) {
            $code = $constraint->compile($operator);
            self::$compiledCheckerCache[$cacheKey] = $function = eval('return function($v, $b){return ' . $code . ';};');
        } else {
            $function = self::$compiledCheckerCache[$cacheKey];
        }
        return self::$resultCache[$resultCacheKey] = $function($version, \strpos($version, 'dev-') === 0);
    }
}
<?php

/*
 * This file is part of composer/semver.
 *
 * (c) Composer <https://github.com/composer>
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer\Semver;

use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\Constraint;
class Interval
{
    /** @var Constraint */
    private $start;
    /** @var Constraint */
    private $end;
    public function __construct(Constraint $start, Constraint $end)
    {
        $this->start = $start;
        $this->end = $end;
    }
    /**
     * @return Constraint
     */
    public function getStart()
    {
        return $this->start;
    }
    /**
     * @return Constraint
     */
    public function getEnd()
    {
        return $this->end;
    }
    /**
     * @return Constraint
     */
    public static function fromZero()
    {
        static $zero;
        if (null === $zero) {
            $zero = new Constraint('>=', '0.0.0.0-dev');
        }
        return $zero;
    }
    /**
     * @return Constraint
     */
    public static function untilPositiveInfinity()
    {
        static $positiveInfinity;
        if (null === $positiveInfinity) {
            $positiveInfinity = new Constraint('<', \PHP_INT_MAX . '.0.0.0');
        }
        return $positiveInfinity;
    }
    /**
     * @return self
     */
    public static function any()
    {
        return new self(self::fromZero(), self::untilPositiveInfinity());
    }
    /**
     * @return array{'names': string[], 'exclude': bool}
     */
    public static function anyDev()
    {
        // any == exclude nothing
        return array('names' => array(), 'exclude' => \true);
    }
    /**
     * @return array{'names': string[], 'exclude': bool}
     */
    public static function noDev()
    {
        // nothing == no names included
        return array('names' => array(), 'exclude' => \false);
    }
}
Copyright (C) 2015 Composer

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Composer;

use Composer\Autoload\ClassLoader;
use _HumbugBox1cb33d1f20f1\Composer\Semver\VersionParser;
/**
 * This class is copied in every Composer installed project and available to all
 *
 * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
 *
 * To require its presence, you can require `composer-runtime-api ^2.0`
 *
 * @final
 */
class InstalledVersions
{
    /**
     * @var mixed[]|null
     * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
     */
    private static $installed;
    /**
     * @var bool|null
     */
    private static $canGetVendors;
    /**
     * @var array[]
     * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
     */
    private static $installedByVendor = array();
    /**
     * Returns a list of all package names which are present, either by being installed, replaced or provided
     *
     * @return string[]
     * @psalm-return list<string>
     */
    public static function getInstalledPackages()
    {
        $packages = array();
        foreach (self::getInstalled() as $installed) {
            $packages[] = \array_keys($installed['versions']);
        }
        if (1 === \count($packages)) {
            return $packages[0];
        }
        return \array_keys(\array_flip(\call_user_func_array('array_merge', $packages)));
    }
    /**
     * Returns a list of all package names with a specific type e.g. 'library'
     *
     * @param  string   $type
     * @return string[]
     * @psalm-return list<string>
     */
    public static function getInstalledPackagesByType($type)
    {
        $packagesByType = array();
        foreach (self::getInstalled() as $installed) {
            foreach ($installed['versions'] as $name => $package) {
                if (isset($package['type']) && $package['type'] === $type) {
                    $packagesByType[] = $name;
                }
            }
        }
        return $packagesByType;
    }
    /**
     * Checks whether the given package is installed
     *
     * This also returns true if the package name is provided or replaced by another package
     *
     * @param  string $packageName
     * @param  bool   $includeDevRequirements
     * @return bool
     */
    public static function isInstalled($packageName, $includeDevRequirements = \true)
    {
        foreach (self::getInstalled() as $installed) {
            if (isset($installed['versions'][$packageName])) {
                return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
            }
        }
        return \false;
    }
    /**
     * Checks whether the given package satisfies a version constraint
     *
     * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
     *
     *   Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
     *
     * @param  VersionParser $parser      Install composer/semver to have access to this class and functionality
     * @param  string        $packageName
     * @param  string|null   $constraint  A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
     * @return bool
     */
    public static function satisfies(VersionParser $parser, $packageName, $constraint)
    {
        $constraint = $parser->parseConstraints($constraint);
        $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
        return $provided->matches($constraint);
    }
    /**
     * Returns a version constraint representing all the range(s) which are installed for a given package
     *
     * It is easier to use this via isInstalled() with the $constraint argument if you need to check
     * whether a given version of a package is installed, and not just whether it exists
     *
     * @param  string $packageName
     * @return string Version constraint usable with composer/semver
     */
    public static function getVersionRanges($packageName)
    {
        foreach (self::getInstalled() as $installed) {
            if (!isset($installed['versions'][$packageName])) {
                continue;
            }
            $ranges = array();
            if (isset($installed['versions'][$packageName]['pretty_version'])) {
                $ranges[] = $installed['versions'][$packageName]['pretty_version'];
            }
            if (\array_key_exists('aliases', $installed['versions'][$packageName])) {
                $ranges = \array_merge($ranges, $installed['versions'][$packageName]['aliases']);
            }
            if (\array_key_exists('replaced', $installed['versions'][$packageName])) {
                $ranges = \array_merge($ranges, $installed['versions'][$packageName]['replaced']);
            }
            if (\array_key_exists('provided', $installed['versions'][$packageName])) {
                $ranges = \array_merge($ranges, $installed['versions'][$packageName]['provided']);
            }
            return \implode(' || ', $ranges);
        }
        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
    }
    /**
     * @param  string      $packageName
     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
     */
    public static function getVersion($packageName)
    {
        foreach (self::getInstalled() as $installed) {
            if (!isset($installed['versions'][$packageName])) {
                continue;
            }
            if (!isset($installed['versions'][$packageName]['version'])) {
                return null;
            }
            return $installed['versions'][$packageName]['version'];
        }
        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
    }
    /**
     * @param  string      $packageName
     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
     */
    public static function getPrettyVersion($packageName)
    {
        foreach (self::getInstalled() as $installed) {
            if (!isset($installed['versions'][$packageName])) {
                continue;
            }
            if (!isset($installed['versions'][$packageName]['pretty_version'])) {
                return null;
            }
            return $installed['versions'][$packageName]['pretty_version'];
        }
        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
    }
    /**
     * @param  string      $packageName
     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
     */
    public static function getReference($packageName)
    {
        foreach (self::getInstalled() as $installed) {
            if (!isset($installed['versions'][$packageName])) {
                continue;
            }
            if (!isset($installed['versions'][$packageName]['reference'])) {
                return null;
            }
            return $installed['versions'][$packageName]['reference'];
        }
        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
    }
    /**
     * @param  string      $packageName
     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
     */
    public static function getInstallPath($packageName)
    {
        foreach (self::getInstalled() as $installed) {
            if (!isset($installed['versions'][$packageName])) {
                continue;
            }
            return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
        }
        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
    }
    /**
     * @return array
     * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
     */
    public static function getRootPackage()
    {
        $installed = self::getInstalled();
        return $installed[0]['root'];
    }
    /**
     * Returns the raw installed.php data for custom implementations
     *
     * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
     * @return array[]
     * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
     */
    public static function getRawData()
    {
        @\trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', \E_USER_DEPRECATED);
        if (null === self::$installed) {
            // only require the installed.php file if this file is loaded from its dumped location,
            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
            if (\substr(__DIR__, -8, 1) !== 'C') {
                self::$installed = (include __DIR__ . '/installed.php');
            } else {
                self::$installed = array();
            }
        }
        return self::$installed;
    }
    /**
     * Returns the raw data of all installed.php which are currently loaded for custom implementations
     *
     * @return array[]
     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
     */
    public static function getAllRawData()
    {
        return self::getInstalled();
    }
    /**
     * Lets you reload the static array from another file
     *
     * This is only useful for complex integrations in which a project needs to use
     * this class but then also needs to execute another project's autoloader in process,
     * and wants to ensure both projects have access to their version of installed.php.
     *
     * A typical case would be PHPUnit, where it would need to make sure it reads all
     * the data it needs from this class, then call reload() with
     * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
     * the project in which it runs can then also use this class safely, without
     * interference between PHPUnit's dependencies and the project's dependencies.
     *
     * @param  array[] $data A vendor/composer/installed.php data set
     * @return void
     *
     * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
     */
    public static function reload($data)
    {
        self::$installed = $data;
        self::$installedByVendor = array();
    }
    /**
     * @return array[]
     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
     */
    private static function getInstalled()
    {
        if (null === self::$canGetVendors) {
            self::$canGetVendors = \method_exists('_HumbugBox1cb33d1f20f1\\Composer\\Autoload\\ClassLoader', 'getRegisteredLoaders');
        }
        $installed = array();
        if (self::$canGetVendors) {
            foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
                if (isset(self::$installedByVendor[$vendorDir])) {
                    $installed[] = self::$installedByVendor[$vendorDir];
                } elseif (\is_file($vendorDir . '/composer/installed.php')) {
                    $installed[] = self::$installedByVendor[$vendorDir] = (require $vendorDir . '/composer/installed.php');
                    if (null === self::$installed && \strtr($vendorDir . '/composer', '\\', '/') === \strtr(__DIR__, '\\', '/')) {
                        self::$installed = $installed[\count($installed) - 1];
                    }
                }
            }
        }
        if (null === self::$installed) {
            // only require the installed.php file if this file is loaded from its dumped location,
            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
            if (\substr(__DIR__, -8, 1) !== 'C') {
                self::$installed = (require __DIR__ . '/installed.php');
            } else {
                self::$installed = array();
            }
        }
        $installed[] = self::$installed;
        return $installed;
    }
}
<?php

// platform_check.php @generated by Composer

$issues = array();

if (!(PHP_VERSION_ID >= 70400)) {
    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.';
}

$missingExtensions = array();
extension_loaded('dom') || $missingExtensions[] = 'dom';
extension_loaded('filter') || $missingExtensions[] = 'filter';
extension_loaded('json') || $missingExtensions[] = 'json';
extension_loaded('libxml') || $missingExtensions[] = 'libxml';
extension_loaded('pcre') || $missingExtensions[] = 'pcre';
extension_loaded('reflection') || $missingExtensions[] = 'reflection';
extension_loaded('simplexml') || $missingExtensions[] = 'simplexml';
extension_loaded('spl') || $missingExtensions[] = 'spl';
extension_loaded('tokenizer') || $missingExtensions[] = 'tokenizer';

if ($missingExtensions) {
    $issues[] = 'Your Composer dependencies require the following PHP extensions to be installed: ' . implode(', ', $missingExtensions) . '.';
}

if ($issues) {
    if (!headers_sent()) {
        header('HTTP/1.1 500 Internal Server Error');
    }
    if (!ini_get('display_errors')) {
        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
        } elseif (!headers_sent()) {
            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
        }
    }
    trigger_error(
        'Composer detected issues in your platform: ' . implode(' ', $issues),
        E_USER_ERROR
    );
}
<?php

// autoload_namespaces.php @generated by Composer

$vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);

return array(
);
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

interface NodeVisitor
{
    /**
     * Called once before traversal.
     *
     * Return value semantics:
     *  * null:      $nodes stays as-is
     *  * otherwise: $nodes is set to the return value
     *
     * @param Node[] $nodes Array of nodes
     *
     * @return null|Node[] Array of nodes
     */
    public function beforeTraverse(array $nodes);
    /**
     * Called when entering a node.
     *
     * Return value semantics:
     *  * null
     *        => $node stays as-is
     *  * NodeTraverser::DONT_TRAVERSE_CHILDREN
     *        => Children of $node are not traversed. $node stays as-is
     *  * NodeTraverser::STOP_TRAVERSAL
     *        => Traversal is aborted. $node stays as-is
     *  * otherwise
     *        => $node is set to the return value
     *
     * @param Node $node Node
     *
     * @return null|int|Node Replacement node (or special return value)
     */
    public function enterNode(Node $node);
    /**
     * Called when leaving a node.
     *
     * Return value semantics:
     *  * null
     *        => $node stays as-is
     *  * NodeTraverser::REMOVE_NODE
     *        => $node is removed from the parent array
     *  * NodeTraverser::STOP_TRAVERSAL
     *        => Traversal is aborted. $node stays as-is
     *  * array (of Nodes)
     *        => The return value is merged into the parent array (at the position of the $node)
     *  * otherwise
     *        => $node is set to the return value
     *
     * @param Node $node Node
     *
     * @return null|int|Node|Node[] Replacement node (or special return value)
     */
    public function leaveNode(Node $node);
    /**
     * Called once after traversal.
     *
     * Return value semantics:
     *  * null:      $nodes stays as-is
     *  * otherwise: $nodes is set to the return value
     *
     * @param Node[] $nodes Array of nodes
     *
     * @return null|Node[] Array of nodes
     */
    public function afterTraverse(array $nodes);
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

interface Node
{
    /**
     * Gets the type of the node.
     *
     * @return string Type of the node
     */
    public function getType() : string;
    /**
     * Gets the names of the sub nodes.
     *
     * @return array Names of sub nodes
     */
    public function getSubNodeNames() : array;
    /**
     * Gets line the node started in (alias of getStartLine).
     *
     * @return int Start line (or -1 if not available)
     */
    public function getLine() : int;
    /**
     * Gets line the node started in.
     *
     * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
     *
     * @return int Start line (or -1 if not available)
     */
    public function getStartLine() : int;
    /**
     * Gets the line the node ended in.
     *
     * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
     *
     * @return int End line (or -1 if not available)
     */
    public function getEndLine() : int;
    /**
     * Gets the token offset of the first token that is part of this node.
     *
     * The offset is an index into the array returned by Lexer::getTokens().
     *
     * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int Token start position (or -1 if not available)
     */
    public function getStartTokenPos() : int;
    /**
     * Gets the token offset of the last token that is part of this node.
     *
     * The offset is an index into the array returned by Lexer::getTokens().
     *
     * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int Token end position (or -1 if not available)
     */
    public function getEndTokenPos() : int;
    /**
     * Gets the file offset of the first character that is part of this node.
     *
     * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int File start position (or -1 if not available)
     */
    public function getStartFilePos() : int;
    /**
     * Gets the file offset of the last character that is part of this node.
     *
     * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int File end position (or -1 if not available)
     */
    public function getEndFilePos() : int;
    /**
     * Gets all comments directly preceding this node.
     *
     * The comments are also available through the "comments" attribute.
     *
     * @return Comment[]
     */
    public function getComments() : array;
    /**
     * Gets the doc comment of the node.
     *
     * @return null|Comment\Doc Doc comment object or null
     */
    public function getDocComment();
    /**
     * Sets the doc comment of the node.
     *
     * This will either replace an existing doc comment or add it to the comments array.
     *
     * @param Comment\Doc $docComment Doc comment to set
     */
    public function setDocComment(Comment\Doc $docComment);
    /**
     * Sets an attribute on a node.
     *
     * @param string $key
     * @param mixed  $value
     */
    public function setAttribute(string $key, $value);
    /**
     * Returns whether an attribute exists.
     *
     * @param string $key
     *
     * @return bool
     */
    public function hasAttribute(string $key) : bool;
    /**
     * Returns the value of an attribute.
     *
     * @param string $key
     * @param mixed  $default
     *
     * @return mixed
     */
    public function getAttribute(string $key, $default = null);
    /**
     * Returns all the attributes of this node.
     *
     * @return array
     */
    public function getAttributes() : array;
    /**
     * Replaces all the attributes of this node.
     *
     * @param array $attributes
     */
    public function setAttributes(array $attributes);
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\PrettyPrinter;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use _HumbugBox1cb33d1f20f1\PhpParser\PrettyPrinterAbstract;
class Standard extends PrettyPrinterAbstract
{
    // Special nodes
    protected function pParam(Node\Param $node)
    {
        return $this->pAttrGroups($node->attrGroups, \true) . $this->pModifiers($node->flags) . ($node->type ? $this->p($node->type) . ' ' : '') . ($node->byRef ? '&' : '') . ($node->variadic ? '...' : '') . $this->p($node->var) . ($node->default ? ' = ' . $this->p($node->default) : '');
    }
    protected function pArg(Node\Arg $node)
    {
        return ($node->name ? $node->name->toString() . ': ' : '') . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value);
    }
    protected function pVariadicPlaceholder(Node\VariadicPlaceholder $node)
    {
        return '...';
    }
    protected function pConst(Node\Const_ $node)
    {
        return $node->name . ' = ' . $this->p($node->value);
    }
    protected function pNullableType(Node\NullableType $node)
    {
        return '?' . $this->p($node->type);
    }
    protected function pUnionType(Node\UnionType $node)
    {
        $types = [];
        foreach ($node->types as $typeNode) {
            if ($typeNode instanceof Node\IntersectionType) {
                $types[] = '(' . $this->p($typeNode) . ')';
                continue;
            }
            $types[] = $this->p($typeNode);
        }
        return \implode('|', $types);
    }
    protected function pIntersectionType(Node\IntersectionType $node)
    {
        return $this->pImplode($node->types, '&');
    }
    protected function pIdentifier(Node\Identifier $node)
    {
        return $node->name;
    }
    protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node)
    {
        return '$' . $node->name;
    }
    protected function pAttribute(Node\Attribute $node)
    {
        return $this->p($node->name) . ($node->args ? '(' . $this->pCommaSeparated($node->args) . ')' : '');
    }
    protected function pAttributeGroup(Node\AttributeGroup $node)
    {
        return '#[' . $this->pCommaSeparated($node->attrs) . ']';
    }
    // Names
    protected function pName(Name $node)
    {
        return \implode('\\', $node->parts);
    }
    protected function pName_FullyQualified(Name\FullyQualified $node)
    {
        return '\\' . \implode('\\', $node->parts);
    }
    protected function pName_Relative(Name\Relative $node)
    {
        return 'namespace\\' . \implode('\\', $node->parts);
    }
    // Magic Constants
    protected function pScalar_MagicConst_Class(MagicConst\Class_ $node)
    {
        return '__CLASS__';
    }
    protected function pScalar_MagicConst_Dir(MagicConst\Dir $node)
    {
        return '__DIR__';
    }
    protected function pScalar_MagicConst_File(MagicConst\File $node)
    {
        return '__FILE__';
    }
    protected function pScalar_MagicConst_Function(MagicConst\Function_ $node)
    {
        return '__FUNCTION__';
    }
    protected function pScalar_MagicConst_Line(MagicConst\Line $node)
    {
        return '__LINE__';
    }
    protected function pScalar_MagicConst_Method(MagicConst\Method $node)
    {
        return '__METHOD__';
    }
    protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node)
    {
        return '__NAMESPACE__';
    }
    protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node)
    {
        return '__TRAIT__';
    }
    // Scalars
    protected function pScalar_String(Scalar\String_ $node)
    {
        $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED);
        switch ($kind) {
            case Scalar\String_::KIND_NOWDOC:
                $label = $node->getAttribute('docLabel');
                if ($label && !$this->containsEndLabel($node->value, $label)) {
                    if ($node->value === '') {
                        return "<<<'{$label}'\n{$label}" . $this->docStringEndToken;
                    }
                    return "<<<'{$label}'\n{$node->value}\n{$label}" . $this->docStringEndToken;
                }
            /* break missing intentionally */
            case Scalar\String_::KIND_SINGLE_QUOTED:
                return $this->pSingleQuotedString($node->value);
            case Scalar\String_::KIND_HEREDOC:
                $label = $node->getAttribute('docLabel');
                if ($label && !$this->containsEndLabel($node->value, $label)) {
                    if ($node->value === '') {
                        return "<<<{$label}\n{$label}" . $this->docStringEndToken;
                    }
                    $escaped = $this->escapeString($node->value, null);
                    return "<<<{$label}\n" . $escaped . "\n{$label}" . $this->docStringEndToken;
                }
            /* break missing intentionally */
            case Scalar\String_::KIND_DOUBLE_QUOTED:
                return '"' . $this->escapeString($node->value, '"') . '"';
        }
        throw new \Exception('Invalid string kind');
    }
    protected function pScalar_Encapsed(Scalar\Encapsed $node)
    {
        if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) {
            $label = $node->getAttribute('docLabel');
            if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) {
                if (\count($node->parts) === 1 && $node->parts[0] instanceof Scalar\EncapsedStringPart && $node->parts[0]->value === '') {
                    return "<<<{$label}\n{$label}" . $this->docStringEndToken;
                }
                return "<<<{$label}\n" . $this->pEncapsList($node->parts, null) . "\n{$label}" . $this->docStringEndToken;
            }
        }
        return '"' . $this->pEncapsList($node->parts, '"') . '"';
    }
    protected function pScalar_LNumber(Scalar\LNumber $node)
    {
        if ($node->value === -\PHP_INT_MAX - 1) {
            // PHP_INT_MIN cannot be represented as a literal,
            // because the sign is not part of the literal
            return '(-' . \PHP_INT_MAX . '-1)';
        }
        $kind = $node->getAttribute('kind', Scalar\LNumber::KIND_DEC);
        if (Scalar\LNumber::KIND_DEC === $kind) {
            return (string) $node->value;
        }
        if ($node->value < 0) {
            $sign = '-';
            $str = (string) -$node->value;
        } else {
            $sign = '';
            $str = (string) $node->value;
        }
        switch ($kind) {
            case Scalar\LNumber::KIND_BIN:
                return $sign . '0b' . \base_convert($str, 10, 2);
            case Scalar\LNumber::KIND_OCT:
                return $sign . '0' . \base_convert($str, 10, 8);
            case Scalar\LNumber::KIND_HEX:
                return $sign . '0x' . \base_convert($str, 10, 16);
        }
        throw new \Exception('Invalid number kind');
    }
    protected function pScalar_DNumber(Scalar\DNumber $node)
    {
        if (!\is_finite($node->value)) {
            if ($node->value === \INF) {
                return '\\INF';
            } elseif ($node->value === -\INF) {
                return '-\\INF';
            } else {
                return '\\NAN';
            }
        }
        // Try to find a short full-precision representation
        $stringValue = \sprintf('%.16G', $node->value);
        if ($node->value !== (double) $stringValue) {
            $stringValue = \sprintf('%.17G', $node->value);
        }
        // %G is locale dependent and there exists no locale-independent alternative. We don't want
        // mess with switching locales here, so let's assume that a comma is the only non-standard
        // decimal separator we may encounter...
        $stringValue = \str_replace(',', '.', $stringValue);
        // ensure that number is really printed as float
        return \preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue;
    }
    protected function pScalar_EncapsedStringPart(Scalar\EncapsedStringPart $node)
    {
        throw new \LogicException('Cannot directly print EncapsedStringPart');
    }
    // Assignments
    protected function pExpr_Assign(Expr\Assign $node)
    {
        return $this->pInfixOp(Expr\Assign::class, $node->var, ' = ', $node->expr);
    }
    protected function pExpr_AssignRef(Expr\AssignRef $node)
    {
        return $this->pInfixOp(Expr\AssignRef::class, $node->var, ' =& ', $node->expr);
    }
    protected function pExpr_AssignOp_Plus(AssignOp\Plus $node)
    {
        return $this->pInfixOp(AssignOp\Plus::class, $node->var, ' += ', $node->expr);
    }
    protected function pExpr_AssignOp_Minus(AssignOp\Minus $node)
    {
        return $this->pInfixOp(AssignOp\Minus::class, $node->var, ' -= ', $node->expr);
    }
    protected function pExpr_AssignOp_Mul(AssignOp\Mul $node)
    {
        return $this->pInfixOp(AssignOp\Mul::class, $node->var, ' *= ', $node->expr);
    }
    protected function pExpr_AssignOp_Div(AssignOp\Div $node)
    {
        return $this->pInfixOp(AssignOp\Div::class, $node->var, ' /= ', $node->expr);
    }
    protected function pExpr_AssignOp_Concat(AssignOp\Concat $node)
    {
        return $this->pInfixOp(AssignOp\Concat::class, $node->var, ' .= ', $node->expr);
    }
    protected function pExpr_AssignOp_Mod(AssignOp\Mod $node)
    {
        return $this->pInfixOp(AssignOp\Mod::class, $node->var, ' %= ', $node->expr);
    }
    protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node)
    {
        return $this->pInfixOp(AssignOp\BitwiseAnd::class, $node->var, ' &= ', $node->expr);
    }
    protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node)
    {
        return $this->pInfixOp(AssignOp\BitwiseOr::class, $node->var, ' |= ', $node->expr);
    }
    protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node)
    {
        return $this->pInfixOp(AssignOp\BitwiseXor::class, $node->var, ' ^= ', $node->expr);
    }
    protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node)
    {
        return $this->pInfixOp(AssignOp\ShiftLeft::class, $node->var, ' <<= ', $node->expr);
    }
    protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node)
    {
        return $this->pInfixOp(AssignOp\ShiftRight::class, $node->var, ' >>= ', $node->expr);
    }
    protected function pExpr_AssignOp_Pow(AssignOp\Pow $node)
    {
        return $this->pInfixOp(AssignOp\Pow::class, $node->var, ' **= ', $node->expr);
    }
    protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node)
    {
        return $this->pInfixOp(AssignOp\Coalesce::class, $node->var, ' ??= ', $node->expr);
    }
    // Binary expressions
    protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node)
    {
        return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right);
    }
    protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node)
    {
        return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right);
    }
    protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node)
    {
        return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right);
    }
    protected function pExpr_BinaryOp_Div(BinaryOp\Div $node)
    {
        return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right);
    }
    protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node)
    {
        return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right);
    }
    protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node)
    {
        return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right);
    }
    protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node)
    {
        return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right);
    }
    protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node)
    {
        return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right);
    }
    protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node)
    {
        return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right);
    }
    protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node)
    {
        return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right);
    }
    protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node)
    {
        return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right);
    }
    protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node)
    {
        return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right);
    }
    protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node)
    {
        return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right);
    }
    protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node)
    {
        return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right);
    }
    protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node)
    {
        return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right);
    }
    protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node)
    {
        return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right);
    }
    protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node)
    {
        return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right);
    }
    protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node)
    {
        return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right);
    }
    protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node)
    {
        return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right);
    }
    protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node)
    {
        return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right);
    }
    protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node)
    {
        return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right);
    }
    protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node)
    {
        return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right);
    }
    protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node)
    {
        return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right);
    }
    protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node)
    {
        return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right);
    }
    protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node)
    {
        return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right);
    }
    protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node)
    {
        return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right);
    }
    protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node)
    {
        return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right);
    }
    protected function pExpr_Instanceof(Expr\Instanceof_ $node)
    {
        list($precedence, $associativity) = $this->precedenceMap[Expr\Instanceof_::class];
        return $this->pPrec($node->expr, $precedence, $associativity, -1) . ' instanceof ' . $this->pNewVariable($node->class);
    }
    // Unary expressions
    protected function pExpr_BooleanNot(Expr\BooleanNot $node)
    {
        return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr);
    }
    protected function pExpr_BitwiseNot(Expr\BitwiseNot $node)
    {
        return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr);
    }
    protected function pExpr_UnaryMinus(Expr\UnaryMinus $node)
    {
        if ($node->expr instanceof Expr\UnaryMinus || $node->expr instanceof Expr\PreDec) {
            // Enforce -(-$expr) instead of --$expr
            return '-(' . $this->p($node->expr) . ')';
        }
        return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr);
    }
    protected function pExpr_UnaryPlus(Expr\UnaryPlus $node)
    {
        if ($node->expr instanceof Expr\UnaryPlus || $node->expr instanceof Expr\PreInc) {
            // Enforce +(+$expr) instead of ++$expr
            return '+(' . $this->p($node->expr) . ')';
        }
        return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr);
    }
    protected function pExpr_PreInc(Expr\PreInc $node)
    {
        return $this->pPrefixOp(Expr\PreInc::class, '++', $node->var);
    }
    protected function pExpr_PreDec(Expr\PreDec $node)
    {
        return $this->pPrefixOp(Expr\PreDec::class, '--', $node->var);
    }
    protected function pExpr_PostInc(Expr\PostInc $node)
    {
        return $this->pPostfixOp(Expr\PostInc::class, $node->var, '++');
    }
    protected function pExpr_PostDec(Expr\PostDec $node)
    {
        return $this->pPostfixOp(Expr\PostDec::class, $node->var, '--');
    }
    protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node)
    {
        return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr);
    }
    protected function pExpr_YieldFrom(Expr\YieldFrom $node)
    {
        return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr);
    }
    protected function pExpr_Print(Expr\Print_ $node)
    {
        return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr);
    }
    // Casts
    protected function pExpr_Cast_Int(Cast\Int_ $node)
    {
        return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr);
    }
    protected function pExpr_Cast_Double(Cast\Double $node)
    {
        $kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE);
        if ($kind === Cast\Double::KIND_DOUBLE) {
            $cast = '(double)';
        } elseif ($kind === Cast\Double::KIND_FLOAT) {
            $cast = '(float)';
        } elseif ($kind === Cast\Double::KIND_REAL) {
            $cast = '(real)';
        }
        return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr);
    }
    protected function pExpr_Cast_String(Cast\String_ $node)
    {
        return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr);
    }
    protected function pExpr_Cast_Array(Cast\Array_ $node)
    {
        return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr);
    }
    protected function pExpr_Cast_Object(Cast\Object_ $node)
    {
        return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr);
    }
    protected function pExpr_Cast_Bool(Cast\Bool_ $node)
    {
        return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr);
    }
    protected function pExpr_Cast_Unset(Cast\Unset_ $node)
    {
        return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr);
    }
    // Function calls and similar constructs
    protected function pExpr_FuncCall(Expr\FuncCall $node)
    {
        return $this->pCallLhs($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
    }
    protected function pExpr_MethodCall(Expr\MethodCall $node)
    {
        return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
    }
    protected function pExpr_NullsafeMethodCall(Expr\NullsafeMethodCall $node)
    {
        return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
    }
    protected function pExpr_StaticCall(Expr\StaticCall $node)
    {
        return $this->pDereferenceLhs($node->class) . '::' . ($node->name instanceof Expr ? $node->name instanceof Expr\Variable ? $this->p($node->name) : '{' . $this->p($node->name) . '}' : $node->name) . '(' . $this->pMaybeMultiline($node->args) . ')';
    }
    protected function pExpr_Empty(Expr\Empty_ $node)
    {
        return 'empty(' . $this->p($node->expr) . ')';
    }
    protected function pExpr_Isset(Expr\Isset_ $node)
    {
        return 'isset(' . $this->pCommaSeparated($node->vars) . ')';
    }
    protected function pExpr_Eval(Expr\Eval_ $node)
    {
        return 'eval(' . $this->p($node->expr) . ')';
    }
    protected function pExpr_Include(Expr\Include_ $node)
    {
        static $map = [Expr\Include_::TYPE_INCLUDE => 'include', Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', Expr\Include_::TYPE_REQUIRE => 'require', Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once'];
        return $map[$node->type] . ' ' . $this->p($node->expr);
    }
    protected function pExpr_List(Expr\List_ $node)
    {
        return 'list(' . $this->pCommaSeparated($node->items) . ')';
    }
    // Other
    protected function pExpr_Error(Expr\Error $node)
    {
        throw new \LogicException('Cannot pretty-print AST with Error nodes');
    }
    protected function pExpr_Variable(Expr\Variable $node)
    {
        if ($node->name instanceof Expr) {
            return '${' . $this->p($node->name) . '}';
        } else {
            return '$' . $node->name;
        }
    }
    protected function pExpr_Array(Expr\Array_ $node)
    {
        $syntax = $node->getAttribute('kind', $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG);
        if ($syntax === Expr\Array_::KIND_SHORT) {
            return '[' . $this->pMaybeMultiline($node->items, \true) . ']';
        } else {
            return 'array(' . $this->pMaybeMultiline($node->items, \true) . ')';
        }
    }
    protected function pExpr_ArrayItem(Expr\ArrayItem $node)
    {
        return (null !== $node->key ? $this->p($node->key) . ' => ' : '') . ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value);
    }
    protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node)
    {
        return $this->pDereferenceLhs($node->var) . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
    }
    protected function pExpr_ConstFetch(Expr\ConstFetch $node)
    {
        return $this->p($node->name);
    }
    protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node)
    {
        return $this->pDereferenceLhs($node->class) . '::' . $this->p($node->name);
    }
    protected function pExpr_PropertyFetch(Expr\PropertyFetch $node)
    {
        return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name);
    }
    protected function pExpr_NullsafePropertyFetch(Expr\NullsafePropertyFetch $node)
    {
        return $this->pDereferenceLhs($node->var) . '?->' . $this->pObjectProperty($node->name);
    }
    protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node)
    {
        return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name);
    }
    protected function pExpr_ShellExec(Expr\ShellExec $node)
    {
        return '`' . $this->pEncapsList($node->parts, '`') . '`';
    }
    protected function pExpr_Closure(Expr\Closure $node)
    {
        return $this->pAttrGroups($node->attrGroups, \true) . ($node->static ? 'static ' : '') . 'function ' . ($node->byRef ? '&' : '') . '(' . $this->pCommaSeparated($node->params) . ')' . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')' : '') . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pExpr_Match(Expr\Match_ $node)
    {
        return 'match (' . $this->p($node->cond) . ') {' . $this->pCommaSeparatedMultiline($node->arms, \true) . $this->nl . '}';
    }
    protected function pMatchArm(Node\MatchArm $node)
    {
        return ($node->conds ? $this->pCommaSeparated($node->conds) : 'default') . ' => ' . $this->p($node->body);
    }
    protected function pExpr_ArrowFunction(Expr\ArrowFunction $node)
    {
        return $this->pAttrGroups($node->attrGroups, \true) . ($node->static ? 'static ' : '') . 'fn' . ($node->byRef ? '&' : '') . '(' . $this->pCommaSeparated($node->params) . ')' . (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '') . ' => ' . $this->p($node->expr);
    }
    protected function pExpr_ClosureUse(Expr\ClosureUse $node)
    {
        return ($node->byRef ? '&' : '') . $this->p($node->var);
    }
    protected function pExpr_New(Expr\New_ $node)
    {
        if ($node->class instanceof Stmt\Class_) {
            $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : '';
            return 'new ' . $this->pClassCommon($node->class, $args);
        }
        return 'new ' . $this->pNewVariable($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')';
    }
    protected function pExpr_Clone(Expr\Clone_ $node)
    {
        return 'clone ' . $this->p($node->expr);
    }
    protected function pExpr_Ternary(Expr\Ternary $node)
    {
        // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator.
        // this is okay because the part between ? and : never needs parentheses.
        return $this->pInfixOp(Expr\Ternary::class, $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else);
    }
    protected function pExpr_Exit(Expr\Exit_ $node)
    {
        $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE);
        return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
    }
    protected function pExpr_Throw(Expr\Throw_ $node)
    {
        return 'throw ' . $this->p($node->expr);
    }
    protected function pExpr_Yield(Expr\Yield_ $node)
    {
        if ($node->value === null) {
            return 'yield';
        } else {
            // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary
            return '(yield ' . ($node->key !== null ? $this->p($node->key) . ' => ' : '') . $this->p($node->value) . ')';
        }
    }
    // Declarations
    protected function pStmt_Namespace(Stmt\Namespace_ $node)
    {
        if ($this->canUseSemicolonNamespaces) {
            return 'namespace ' . $this->p($node->name) . ';' . $this->nl . $this->pStmts($node->stmts, \false);
        } else {
            return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') . ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
        }
    }
    protected function pStmt_Use(Stmt\Use_ $node)
    {
        return 'use ' . $this->pUseType($node->type) . $this->pCommaSeparated($node->uses) . ';';
    }
    protected function pStmt_GroupUse(Stmt\GroupUse $node)
    {
        return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) . '\\{' . $this->pCommaSeparated($node->uses) . '};';
    }
    protected function pStmt_UseUse(Stmt\UseUse $node)
    {
        return $this->pUseType($node->type) . $this->p($node->name) . (null !== $node->alias ? ' as ' . $node->alias : '');
    }
    protected function pUseType($type)
    {
        return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : '');
    }
    protected function pStmt_Interface(Stmt\Interface_ $node)
    {
        return $this->pAttrGroups($node->attrGroups) . 'interface ' . $node->name . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Enum(Stmt\Enum_ $node)
    {
        return $this->pAttrGroups($node->attrGroups) . 'enum ' . $node->name . ($node->scalarType ? " : {$node->scalarType}" : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Class(Stmt\Class_ $node)
    {
        return $this->pClassCommon($node, ' ' . $node->name);
    }
    protected function pStmt_Trait(Stmt\Trait_ $node)
    {
        return $this->pAttrGroups($node->attrGroups) . 'trait ' . $node->name . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_EnumCase(Stmt\EnumCase $node)
    {
        return $this->pAttrGroups($node->attrGroups) . 'case ' . $node->name . ($node->expr ? ' = ' . $this->p($node->expr) : '') . ';';
    }
    protected function pStmt_TraitUse(Stmt\TraitUse $node)
    {
        return 'use ' . $this->pCommaSeparated($node->traits) . (empty($node->adaptations) ? ';' : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}');
    }
    protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node)
    {
        return $this->p($node->trait) . '::' . $node->method . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';';
    }
    protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node)
    {
        return (null !== $node->trait ? $this->p($node->trait) . '::' : '') . $node->method . ' as' . (null !== $node->newModifier ? ' ' . \rtrim($this->pModifiers($node->newModifier), ' ') : '') . (null !== $node->newName ? ' ' . $node->newName : '') . ';';
    }
    protected function pStmt_Property(Stmt\Property $node)
    {
        return $this->pAttrGroups($node->attrGroups) . (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) . ($node->type ? $this->p($node->type) . ' ' : '') . $this->pCommaSeparated($node->props) . ';';
    }
    protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node)
    {
        return '$' . $node->name . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
    }
    protected function pStmt_ClassMethod(Stmt\ClassMethod $node)
    {
        return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pMaybeMultiline($node->params) . ')' . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') . (null !== $node->stmts ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' : ';');
    }
    protected function pStmt_ClassConst(Stmt\ClassConst $node)
    {
        return $this->pAttrGroups($node->attrGroups) . $this->pModifiers($node->flags) . 'const ' . $this->pCommaSeparated($node->consts) . ';';
    }
    protected function pStmt_Function(Stmt\Function_ $node)
    {
        return $this->pAttrGroups($node->attrGroups) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pCommaSeparated($node->params) . ')' . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Const(Stmt\Const_ $node)
    {
        return 'const ' . $this->pCommaSeparated($node->consts) . ';';
    }
    protected function pStmt_Declare(Stmt\Declare_ $node)
    {
        return 'declare (' . $this->pCommaSeparated($node->declares) . ')' . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';');
    }
    protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node)
    {
        return $node->key . '=' . $this->p($node->value);
    }
    // Control flow
    protected function pStmt_If(Stmt\If_ $node)
    {
        return 'if (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}' . ($node->elseifs ? ' ' . $this->pImplode($node->elseifs, ' ') : '') . (null !== $node->else ? ' ' . $this->p($node->else) : '');
    }
    protected function pStmt_ElseIf(Stmt\ElseIf_ $node)
    {
        return 'elseif (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Else(Stmt\Else_ $node)
    {
        return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_For(Stmt\For_ $node)
    {
        return 'for (' . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') . $this->pCommaSeparated($node->loop) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Foreach(Stmt\Foreach_ $node)
    {
        return 'foreach (' . $this->p($node->expr) . ' as ' . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_While(Stmt\While_ $node)
    {
        return 'while (' . $this->p($node->cond) . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Do(Stmt\Do_ $node)
    {
        return 'do {' . $this->pStmts($node->stmts) . $this->nl . '} while (' . $this->p($node->cond) . ');';
    }
    protected function pStmt_Switch(Stmt\Switch_ $node)
    {
        return 'switch (' . $this->p($node->cond) . ') {' . $this->pStmts($node->cases) . $this->nl . '}';
    }
    protected function pStmt_Case(Stmt\Case_ $node)
    {
        return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' . $this->pStmts($node->stmts);
    }
    protected function pStmt_TryCatch(Stmt\TryCatch $node)
    {
        return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}' . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '') . ($node->finally !== null ? ' ' . $this->p($node->finally) : '');
    }
    protected function pStmt_Catch(Stmt\Catch_ $node)
    {
        return 'catch (' . $this->pImplode($node->types, '|') . ($node->var !== null ? ' ' . $this->p($node->var) : '') . ') {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Finally(Stmt\Finally_ $node)
    {
        return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pStmt_Break(Stmt\Break_ $node)
    {
        return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
    }
    protected function pStmt_Continue(Stmt\Continue_ $node)
    {
        return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';';
    }
    protected function pStmt_Return(Stmt\Return_ $node)
    {
        return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';';
    }
    protected function pStmt_Throw(Stmt\Throw_ $node)
    {
        return 'throw ' . $this->p($node->expr) . ';';
    }
    protected function pStmt_Label(Stmt\Label $node)
    {
        return $node->name . ':';
    }
    protected function pStmt_Goto(Stmt\Goto_ $node)
    {
        return 'goto ' . $node->name . ';';
    }
    // Other
    protected function pStmt_Expression(Stmt\Expression $node)
    {
        return $this->p($node->expr) . ';';
    }
    protected function pStmt_Echo(Stmt\Echo_ $node)
    {
        return 'echo ' . $this->pCommaSeparated($node->exprs) . ';';
    }
    protected function pStmt_Static(Stmt\Static_ $node)
    {
        return 'static ' . $this->pCommaSeparated($node->vars) . ';';
    }
    protected function pStmt_Global(Stmt\Global_ $node)
    {
        return 'global ' . $this->pCommaSeparated($node->vars) . ';';
    }
    protected function pStmt_StaticVar(Stmt\StaticVar $node)
    {
        return $this->p($node->var) . (null !== $node->default ? ' = ' . $this->p($node->default) : '');
    }
    protected function pStmt_Unset(Stmt\Unset_ $node)
    {
        return 'unset(' . $this->pCommaSeparated($node->vars) . ');';
    }
    protected function pStmt_InlineHTML(Stmt\InlineHTML $node)
    {
        $newline = $node->getAttribute('hasLeadingNewline', \true) ? "\n" : '';
        return '?>' . $newline . $node->value . '<?php ';
    }
    protected function pStmt_HaltCompiler(Stmt\HaltCompiler $node)
    {
        return '__halt_compiler();' . $node->remaining;
    }
    protected function pStmt_Nop(Stmt\Nop $node)
    {
        return '';
    }
    // Helpers
    protected function pClassCommon(Stmt\Class_ $node, $afterClassToken)
    {
        return $this->pAttrGroups($node->attrGroups, $node->name === null) . $this->pModifiers($node->flags) . 'class' . $afterClassToken . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
    }
    protected function pObjectProperty($node)
    {
        if ($node instanceof Expr) {
            return '{' . $this->p($node) . '}';
        } else {
            return $node;
        }
    }
    protected function pEncapsList(array $encapsList, $quote)
    {
        $return = '';
        foreach ($encapsList as $element) {
            if ($element instanceof Scalar\EncapsedStringPart) {
                $return .= $this->escapeString($element->value, $quote);
            } else {
                $return .= '{' . $this->p($element) . '}';
            }
        }
        return $return;
    }
    protected function pSingleQuotedString(string $string)
    {
        return '\'' . \addcslashes($string, '\'\\') . '\'';
    }
    protected function escapeString($string, $quote)
    {
        if (null === $quote) {
            // For doc strings, don't escape newlines
            $escaped = \addcslashes($string, "\t\f\v\$\\");
        } else {
            $escaped = \addcslashes($string, "\n\r\t\f\v\$" . $quote . "\\");
        }
        // Escape control characters and non-UTF-8 characters.
        // Regex based on https://stackoverflow.com/a/11709412/385378.
        $regex = '/(
              [\\x00-\\x08\\x0E-\\x1F] # Control characters
            | [\\xC0-\\xC1] # Invalid UTF-8 Bytes
            | [\\xF5-\\xFF] # Invalid UTF-8 Bytes
            | \\xE0(?=[\\x80-\\x9F]) # Overlong encoding of prior code point
            | \\xF0(?=[\\x80-\\x8F]) # Overlong encoding of prior code point
            | [\\xC2-\\xDF](?![\\x80-\\xBF]) # Invalid UTF-8 Sequence Start
            | [\\xE0-\\xEF](?![\\x80-\\xBF]{2}) # Invalid UTF-8 Sequence Start
            | [\\xF0-\\xF4](?![\\x80-\\xBF]{3}) # Invalid UTF-8 Sequence Start
            | (?<=[\\x00-\\x7F\\xF5-\\xFF])[\\x80-\\xBF] # Invalid UTF-8 Sequence Middle
            | (?<![\\xC2-\\xDF]|[\\xE0-\\xEF]|[\\xE0-\\xEF][\\x80-\\xBF]|[\\xF0-\\xF4]|[\\xF0-\\xF4][\\x80-\\xBF]|[\\xF0-\\xF4][\\x80-\\xBF]{2})[\\x80-\\xBF] # Overlong Sequence
            | (?<=[\\xE0-\\xEF])[\\x80-\\xBF](?![\\x80-\\xBF]) # Short 3 byte sequence
            | (?<=[\\xF0-\\xF4])[\\x80-\\xBF](?![\\x80-\\xBF]{2}) # Short 4 byte sequence
            | (?<=[\\xF0-\\xF4][\\x80-\\xBF])[\\x80-\\xBF](?![\\x80-\\xBF]) # Short 4 byte sequence (2)
        )/x';
        return \preg_replace_callback($regex, function ($matches) {
            \assert(\strlen($matches[0]) === 1);
            $hex = \dechex(\ord($matches[0]));
            return '\\x' . \str_pad($hex, 2, '0', \STR_PAD_LEFT);
        }, $escaped);
    }
    protected function containsEndLabel($string, $label, $atStart = \true, $atEnd = \true)
    {
        $start = $atStart ? '(?:^|[\\r\\n])' : '[\\r\\n]';
        $end = $atEnd ? '(?:$|[;\\r\\n])' : '[;\\r\\n]';
        return \false !== \strpos($string, $label) && \preg_match('/' . $start . $label . $end . '/', $string);
    }
    protected function encapsedContainsEndLabel(array $parts, $label)
    {
        foreach ($parts as $i => $part) {
            $atStart = $i === 0;
            $atEnd = $i === \count($parts) - 1;
            if ($part instanceof Scalar\EncapsedStringPart && $this->containsEndLabel($part->value, $label, $atStart, $atEnd)) {
                return \true;
            }
        }
        return \false;
    }
    protected function pDereferenceLhs(Node $node)
    {
        if (!$this->dereferenceLhsRequiresParens($node)) {
            return $this->p($node);
        } else {
            return '(' . $this->p($node) . ')';
        }
    }
    protected function pCallLhs(Node $node)
    {
        if (!$this->callLhsRequiresParens($node)) {
            return $this->p($node);
        } else {
            return '(' . $this->p($node) . ')';
        }
    }
    protected function pNewVariable(Node $node)
    {
        // TODO: This is not fully accurate.
        return $this->pDereferenceLhs($node);
    }
    /**
     * @param Node[] $nodes
     * @return bool
     */
    protected function hasNodeWithComments(array $nodes)
    {
        foreach ($nodes as $node) {
            if ($node && $node->getComments()) {
                return \true;
            }
        }
        return \false;
    }
    protected function pMaybeMultiline(array $nodes, bool $trailingComma = \false)
    {
        if (!$this->hasNodeWithComments($nodes)) {
            return $this->pCommaSeparated($nodes);
        } else {
            return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl;
        }
    }
    protected function pAttrGroups(array $nodes, bool $inline = \false) : string
    {
        $result = '';
        $sep = $inline ? ' ' : $this->nl;
        foreach ($nodes as $node) {
            $result .= $this->p($node) . $sep;
        }
        return $result;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

interface ErrorHandler
{
    /**
     * Handle an error generated during lexing, parsing or some other operation.
     *
     * @param Error $error The error that needs to be handled
     */
    public function handleError(Error $error);
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name\FullyQualified;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class NameContext
{
    /** @var null|Name Current namespace */
    protected $namespace;
    /** @var Name[][] Map of format [aliasType => [aliasName => originalName]] */
    protected $aliases = [];
    /** @var Name[][] Same as $aliases but preserving original case */
    protected $origAliases = [];
    /** @var ErrorHandler Error handler */
    protected $errorHandler;
    /**
     * Create a name context.
     *
     * @param ErrorHandler $errorHandler Error handling used to report errors
     */
    public function __construct(ErrorHandler $errorHandler)
    {
        $this->errorHandler = $errorHandler;
    }
    /**
     * Start a new namespace.
     *
     * This also resets the alias table.
     *
     * @param Name|null $namespace Null is the global namespace
     */
    public function startNamespace(Name $namespace = null)
    {
        $this->namespace = $namespace;
        $this->origAliases = $this->aliases = [Stmt\Use_::TYPE_NORMAL => [], Stmt\Use_::TYPE_FUNCTION => [], Stmt\Use_::TYPE_CONSTANT => []];
    }
    /**
     * Add an alias / import.
     *
     * @param Name   $name        Original name
     * @param string $aliasName   Aliased name
     * @param int    $type        One of Stmt\Use_::TYPE_*
     * @param array  $errorAttrs Attributes to use to report an error
     */
    public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = [])
    {
        // Constant names are case sensitive, everything else case insensitive
        if ($type === Stmt\Use_::TYPE_CONSTANT) {
            $aliasLookupName = $aliasName;
        } else {
            $aliasLookupName = \strtolower($aliasName);
        }
        if (isset($this->aliases[$type][$aliasLookupName])) {
            $typeStringMap = [Stmt\Use_::TYPE_NORMAL => '', Stmt\Use_::TYPE_FUNCTION => 'function ', Stmt\Use_::TYPE_CONSTANT => 'const '];
            $this->errorHandler->handleError(new Error(\sprintf('Cannot use %s%s as %s because the name is already in use', $typeStringMap[$type], $name, $aliasName), $errorAttrs));
            return;
        }
        $this->aliases[$type][$aliasLookupName] = $name;
        $this->origAliases[$type][$aliasName] = $name;
    }
    /**
     * Get current namespace.
     *
     * @return null|Name Namespace (or null if global namespace)
     */
    public function getNamespace()
    {
        return $this->namespace;
    }
    /**
     * Get resolved name.
     *
     * @param Name $name Name to resolve
     * @param int  $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT}
     *
     * @return null|Name Resolved name, or null if static resolution is not possible
     */
    public function getResolvedName(Name $name, int $type)
    {
        // don't resolve special class names
        if ($type === Stmt\Use_::TYPE_NORMAL && $name->isSpecialClassName()) {
            if (!$name->isUnqualified()) {
                $this->errorHandler->handleError(new Error(\sprintf("'\\%s' is an invalid class name", $name->toString()), $name->getAttributes()));
            }
            return $name;
        }
        // fully qualified names are already resolved
        if ($name->isFullyQualified()) {
            return $name;
        }
        // Try to resolve aliases
        if (null !== ($resolvedName = $this->resolveAlias($name, $type))) {
            return $resolvedName;
        }
        if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) {
            if (null === $this->namespace) {
                // outside of a namespace unaliased unqualified is same as fully qualified
                return new FullyQualified($name, $name->getAttributes());
            }
            // Cannot resolve statically
            return null;
        }
        // if no alias exists prepend current namespace
        return FullyQualified::concat($this->namespace, $name, $name->getAttributes());
    }
    /**
     * Get resolved class name.
     *
     * @param Name $name Class ame to resolve
     *
     * @return Name Resolved name
     */
    public function getResolvedClassName(Name $name) : Name
    {
        return $this->getResolvedName($name, Stmt\Use_::TYPE_NORMAL);
    }
    /**
     * Get possible ways of writing a fully qualified name (e.g., by making use of aliases).
     *
     * @param string $name Fully-qualified name (without leading namespace separator)
     * @param int    $type One of Stmt\Use_::TYPE_*
     *
     * @return Name[] Possible representations of the name
     */
    public function getPossibleNames(string $name, int $type) : array
    {
        $lcName = \strtolower($name);
        if ($type === Stmt\Use_::TYPE_NORMAL) {
            // self, parent and static must always be unqualified
            if ($lcName === "self" || $lcName === "parent" || $lcName === "static") {
                return [new Name($name)];
            }
        }
        // Collect possible ways to write this name, starting with the fully-qualified name
        $possibleNames = [new FullyQualified($name)];
        if (null !== ($nsRelativeName = $this->getNamespaceRelativeName($name, $lcName, $type))) {
            // Make sure there is no alias that makes the normally namespace-relative name
            // into something else
            if (null === $this->resolveAlias($nsRelativeName, $type)) {
                $possibleNames[] = $nsRelativeName;
            }
        }
        // Check for relevant namespace use statements
        foreach ($this->origAliases[Stmt\Use_::TYPE_NORMAL] as $alias => $orig) {
            $lcOrig = $orig->toLowerString();
            if (0 === \strpos($lcName, $lcOrig . '\\')) {
                $possibleNames[] = new Name($alias . \substr($name, \strlen($lcOrig)));
            }
        }
        // Check for relevant type-specific use statements
        foreach ($this->origAliases[$type] as $alias => $orig) {
            if ($type === Stmt\Use_::TYPE_CONSTANT) {
                // Constants are are complicated-sensitive
                $normalizedOrig = $this->normalizeConstName($orig->toString());
                if ($normalizedOrig === $this->normalizeConstName($name)) {
                    $possibleNames[] = new Name($alias);
                }
            } else {
                // Everything else is case-insensitive
                if ($orig->toLowerString() === $lcName) {
                    $possibleNames[] = new Name($alias);
                }
            }
        }
        return $possibleNames;
    }
    /**
     * Get shortest representation of this fully-qualified name.
     *
     * @param string $name Fully-qualified name (without leading namespace separator)
     * @param int    $type One of Stmt\Use_::TYPE_*
     *
     * @return Name Shortest representation
     */
    public function getShortName(string $name, int $type) : Name
    {
        $possibleNames = $this->getPossibleNames($name, $type);
        // Find shortest name
        $shortestName = null;
        $shortestLength = \INF;
        foreach ($possibleNames as $possibleName) {
            $length = \strlen($possibleName->toCodeString());
            if ($length < $shortestLength) {
                $shortestName = $possibleName;
                $shortestLength = $length;
            }
        }
        return $shortestName;
    }
    private function resolveAlias(Name $name, $type)
    {
        $firstPart = $name->getFirst();
        if ($name->isQualified()) {
            // resolve aliases for qualified names, always against class alias table
            $checkName = \strtolower($firstPart);
            if (isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName])) {
                $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName];
                return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes());
            }
        } elseif ($name->isUnqualified()) {
            // constant aliases are case-sensitive, function aliases case-insensitive
            $checkName = $type === Stmt\Use_::TYPE_CONSTANT ? $firstPart : \strtolower($firstPart);
            if (isset($this->aliases[$type][$checkName])) {
                // resolve unqualified aliases
                return new FullyQualified($this->aliases[$type][$checkName], $name->getAttributes());
            }
        }
        // No applicable aliases
        return null;
    }
    private function getNamespaceRelativeName(string $name, string $lcName, int $type)
    {
        if (null === $this->namespace) {
            return new Name($name);
        }
        if ($type === Stmt\Use_::TYPE_CONSTANT) {
            // The constants true/false/null always resolve to the global symbols, even inside a
            // namespace, so they may be used without qualification
            if ($lcName === "true" || $lcName === "false" || $lcName === "null") {
                return new Name($name);
            }
        }
        $namespacePrefix = \strtolower($this->namespace . '\\');
        if (0 === \strpos($lcName, $namespacePrefix)) {
            return new Name(\substr($name, \strlen($namespacePrefix)));
        }
        return null;
    }
    private function normalizeConstName(string $name)
    {
        $nsSep = \strrpos($name, '\\');
        if (\false === $nsSep) {
            return $name;
        }
        // Constants have case-insensitive namespace and case-sensitive short-name
        $ns = \substr($name, 0, $nsSep);
        $shortName = \substr($name, $nsSep + 1);
        return \strtolower($ns) . '\\' . $shortName;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Internal;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
/**
 * This node is used internally by the format-preserving pretty printer to print anonymous classes.
 *
 * The normal anonymous class structure violates assumptions about the order of token offsets.
 * Namely, the constructor arguments are part of the Expr\New_ node and follow the class node, even
 * though they are actually interleaved with them. This special node type is used temporarily to
 * restore a sane token offset order.
 *
 * @internal
 */
class PrintableNewAnonClassNode extends Expr
{
    /** @var Node\AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    /** @var Node\Arg[] Arguments */
    public $args;
    /** @var null|Node\Name Name of extended class */
    public $extends;
    /** @var Node\Name[] Names of implemented interfaces */
    public $implements;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    public function __construct(array $attrGroups, array $args, Node\Name $extends = null, array $implements, array $stmts, array $attributes)
    {
        parent::__construct($attributes);
        $this->attrGroups = $attrGroups;
        $this->args = $args;
        $this->extends = $extends;
        $this->implements = $implements;
        $this->stmts = $stmts;
    }
    public static function fromNewNode(Expr\New_ $newNode)
    {
        $class = $newNode->class;
        \assert($class instanceof Node\Stmt\Class_);
        // We don't assert that $class->name is null here, to allow consumers to assign unique names
        // to anonymous classes for their own purposes. We simplify ignore the name here.
        return new self($class->attrGroups, $newNode->args, $class->extends, $class->implements, $class->stmts, $newNode->getAttributes());
    }
    public function getType() : string
    {
        return 'Expr_PrintableNewAnonClass';
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'args', 'extends', 'implements', 'stmts'];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Internal;

/**
 * Provides operations on token streams, for use by pretty printer.
 *
 * @internal
 */
class TokenStream
{
    /** @var array Tokens (in token_get_all format) */
    private $tokens;
    /** @var int[] Map from position to indentation */
    private $indentMap;
    /**
     * Create token stream instance.
     *
     * @param array $tokens Tokens in token_get_all() format
     */
    public function __construct(array $tokens)
    {
        $this->tokens = $tokens;
        $this->indentMap = $this->calcIndentMap();
    }
    /**
     * Whether the given position is immediately surrounded by parenthesis.
     *
     * @param int $startPos Start position
     * @param int $endPos   End position
     *
     * @return bool
     */
    public function haveParens(int $startPos, int $endPos) : bool
    {
        return $this->haveTokenImmediatelyBefore($startPos, '(') && $this->haveTokenImmediatelyAfter($endPos, ')');
    }
    /**
     * Whether the given position is immediately surrounded by braces.
     *
     * @param int $startPos Start position
     * @param int $endPos   End position
     *
     * @return bool
     */
    public function haveBraces(int $startPos, int $endPos) : bool
    {
        return ($this->haveTokenImmediatelyBefore($startPos, '{') || $this->haveTokenImmediatelyBefore($startPos, \T_CURLY_OPEN)) && $this->haveTokenImmediatelyAfter($endPos, '}');
    }
    /**
     * Check whether the position is directly preceded by a certain token type.
     *
     * During this check whitespace and comments are skipped.
     *
     * @param int        $pos               Position before which the token should occur
     * @param int|string $expectedTokenType Token to check for
     *
     * @return bool Whether the expected token was found
     */
    public function haveTokenImmediatelyBefore(int $pos, $expectedTokenType) : bool
    {
        $tokens = $this->tokens;
        $pos--;
        for (; $pos >= 0; $pos--) {
            $tokenType = $tokens[$pos][0];
            if ($tokenType === $expectedTokenType) {
                return \true;
            }
            if ($tokenType !== \T_WHITESPACE && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) {
                break;
            }
        }
        return \false;
    }
    /**
     * Check whether the position is directly followed by a certain token type.
     *
     * During this check whitespace and comments are skipped.
     *
     * @param int        $pos               Position after which the token should occur
     * @param int|string $expectedTokenType Token to check for
     *
     * @return bool Whether the expected token was found
     */
    public function haveTokenImmediatelyAfter(int $pos, $expectedTokenType) : bool
    {
        $tokens = $this->tokens;
        $pos++;
        for (; $pos < \count($tokens); $pos++) {
            $tokenType = $tokens[$pos][0];
            if ($tokenType === $expectedTokenType) {
                return \true;
            }
            if ($tokenType !== \T_WHITESPACE && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) {
                break;
            }
        }
        return \false;
    }
    public function skipLeft(int $pos, $skipTokenType)
    {
        $tokens = $this->tokens;
        $pos = $this->skipLeftWhitespace($pos);
        if ($skipTokenType === \T_WHITESPACE) {
            return $pos;
        }
        if ($tokens[$pos][0] !== $skipTokenType) {
            // Shouldn't happen. The skip token MUST be there
            throw new \Exception('Encountered unexpected token');
        }
        $pos--;
        return $this->skipLeftWhitespace($pos);
    }
    public function skipRight(int $pos, $skipTokenType)
    {
        $tokens = $this->tokens;
        $pos = $this->skipRightWhitespace($pos);
        if ($skipTokenType === \T_WHITESPACE) {
            return $pos;
        }
        if ($tokens[$pos][0] !== $skipTokenType) {
            // Shouldn't happen. The skip token MUST be there
            throw new \Exception('Encountered unexpected token');
        }
        $pos++;
        return $this->skipRightWhitespace($pos);
    }
    /**
     * Return first non-whitespace token position smaller or equal to passed position.
     *
     * @param int $pos Token position
     * @return int Non-whitespace token position
     */
    public function skipLeftWhitespace(int $pos)
    {
        $tokens = $this->tokens;
        for (; $pos >= 0; $pos--) {
            $type = $tokens[$pos][0];
            if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) {
                break;
            }
        }
        return $pos;
    }
    /**
     * Return first non-whitespace position greater or equal to passed position.
     *
     * @param int $pos Token position
     * @return int Non-whitespace token position
     */
    public function skipRightWhitespace(int $pos)
    {
        $tokens = $this->tokens;
        for ($count = \count($tokens); $pos < $count; $pos++) {
            $type = $tokens[$pos][0];
            if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) {
                break;
            }
        }
        return $pos;
    }
    public function findRight(int $pos, $findTokenType)
    {
        $tokens = $this->tokens;
        for ($count = \count($tokens); $pos < $count; $pos++) {
            $type = $tokens[$pos][0];
            if ($type === $findTokenType) {
                return $pos;
            }
        }
        return -1;
    }
    /**
     * Whether the given position range contains a certain token type.
     *
     * @param int $startPos Starting position (inclusive)
     * @param int $endPos Ending position (exclusive)
     * @param int|string $tokenType Token type to look for
     * @return bool Whether the token occurs in the given range
     */
    public function haveTokenInRange(int $startPos, int $endPos, $tokenType)
    {
        $tokens = $this->tokens;
        for ($pos = $startPos; $pos < $endPos; $pos++) {
            if ($tokens[$pos][0] === $tokenType) {
                return \true;
            }
        }
        return \false;
    }
    public function haveBracesInRange(int $startPos, int $endPos)
    {
        return $this->haveTokenInRange($startPos, $endPos, '{') || $this->haveTokenInRange($startPos, $endPos, \T_CURLY_OPEN) || $this->haveTokenInRange($startPos, $endPos, '}');
    }
    public function haveTagInRange(int $startPos, int $endPos) : bool
    {
        return $this->haveTokenInRange($startPos, $endPos, \T_OPEN_TAG) || $this->haveTokenInRange($startPos, $endPos, \T_CLOSE_TAG);
    }
    /**
     * Get indentation before token position.
     *
     * @param int $pos Token position
     *
     * @return int Indentation depth (in spaces)
     */
    public function getIndentationBefore(int $pos) : int
    {
        return $this->indentMap[$pos];
    }
    /**
     * Get the code corresponding to a token offset range, optionally adjusted for indentation.
     *
     * @param int $from   Token start position (inclusive)
     * @param int $to     Token end position (exclusive)
     * @param int $indent By how much the code should be indented (can be negative as well)
     *
     * @return string Code corresponding to token range, adjusted for indentation
     */
    public function getTokenCode(int $from, int $to, int $indent) : string
    {
        $tokens = $this->tokens;
        $result = '';
        for ($pos = $from; $pos < $to; $pos++) {
            $token = $tokens[$pos];
            if (\is_array($token)) {
                $type = $token[0];
                $content = $token[1];
                if ($type === \T_CONSTANT_ENCAPSED_STRING || $type === \T_ENCAPSED_AND_WHITESPACE) {
                    $result .= $content;
                } else {
                    // TODO Handle non-space indentation
                    if ($indent < 0) {
                        $result .= \str_replace("\n" . \str_repeat(" ", -$indent), "\n", $content);
                    } elseif ($indent > 0) {
                        $result .= \str_replace("\n", "\n" . \str_repeat(" ", $indent), $content);
                    } else {
                        $result .= $content;
                    }
                }
            } else {
                $result .= $token;
            }
        }
        return $result;
    }
    /**
     * Precalculate the indentation at every token position.
     *
     * @return int[] Token position to indentation map
     */
    private function calcIndentMap()
    {
        $indentMap = [];
        $indent = 0;
        foreach ($this->tokens as $token) {
            $indentMap[] = $indent;
            if ($token[0] === \T_WHITESPACE) {
                $content = $token[1];
                $newlinePos = \strrpos($content, "\n");
                if (\false !== $newlinePos) {
                    $indent = \strlen($content) - $newlinePos - 1;
                }
            }
        }
        // Add a sentinel for one past end of the file
        $indentMap[] = $indent;
        return $indentMap;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Internal;

/**
 * @internal
 */
class DiffElem
{
    const TYPE_KEEP = 0;
    const TYPE_REMOVE = 1;
    const TYPE_ADD = 2;
    const TYPE_REPLACE = 3;
    /** @var int One of the TYPE_* constants */
    public $type;
    /** @var mixed Is null for add operations */
    public $old;
    /** @var mixed Is null for remove operations */
    public $new;
    public function __construct(int $type, $old, $new)
    {
        $this->type = $type;
        $this->old = $old;
        $this->new = $new;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Internal;

/**
 * Implements the Myers diff algorithm.
 *
 * Myers, Eugene W. "An O (ND) difference algorithm and its variations."
 * Algorithmica 1.1 (1986): 251-266.
 *
 * @internal
 */
class Differ
{
    private $isEqual;
    /**
     * Create differ over the given equality relation.
     *
     * @param callable $isEqual Equality relation with signature function($a, $b) : bool
     */
    public function __construct(callable $isEqual)
    {
        $this->isEqual = $isEqual;
    }
    /**
     * Calculate diff (edit script) from $old to $new.
     *
     * @param array $old Original array
     * @param array $new New array
     *
     * @return DiffElem[] Diff (edit script)
     */
    public function diff(array $old, array $new)
    {
        list($trace, $x, $y) = $this->calculateTrace($old, $new);
        return $this->extractDiff($trace, $x, $y, $old, $new);
    }
    /**
     * Calculate diff, including "replace" operations.
     *
     * If a sequence of remove operations is followed by the same number of add operations, these
     * will be coalesced into replace operations.
     *
     * @param array $old Original array
     * @param array $new New array
     *
     * @return DiffElem[] Diff (edit script), including replace operations
     */
    public function diffWithReplacements(array $old, array $new)
    {
        return $this->coalesceReplacements($this->diff($old, $new));
    }
    private function calculateTrace(array $a, array $b)
    {
        $n = \count($a);
        $m = \count($b);
        $max = $n + $m;
        $v = [1 => 0];
        $trace = [];
        for ($d = 0; $d <= $max; $d++) {
            $trace[] = $v;
            for ($k = -$d; $k <= $d; $k += 2) {
                if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
                    $x = $v[$k + 1];
                } else {
                    $x = $v[$k - 1] + 1;
                }
                $y = $x - $k;
                while ($x < $n && $y < $m && ($this->isEqual)($a[$x], $b[$y])) {
                    $x++;
                    $y++;
                }
                $v[$k] = $x;
                if ($x >= $n && $y >= $m) {
                    return [$trace, $x, $y];
                }
            }
        }
        throw new \Exception('Should not happen');
    }
    private function extractDiff(array $trace, int $x, int $y, array $a, array $b)
    {
        $result = [];
        for ($d = \count($trace) - 1; $d >= 0; $d--) {
            $v = $trace[$d];
            $k = $x - $y;
            if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
                $prevK = $k + 1;
            } else {
                $prevK = $k - 1;
            }
            $prevX = $v[$prevK];
            $prevY = $prevX - $prevK;
            while ($x > $prevX && $y > $prevY) {
                $result[] = new DiffElem(DiffElem::TYPE_KEEP, $a[$x - 1], $b[$y - 1]);
                $x--;
                $y--;
            }
            if ($d === 0) {
                break;
            }
            while ($x > $prevX) {
                $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $a[$x - 1], null);
                $x--;
            }
            while ($y > $prevY) {
                $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $b[$y - 1]);
                $y--;
            }
        }
        return \array_reverse($result);
    }
    /**
     * Coalesce equal-length sequences of remove+add into a replace operation.
     *
     * @param DiffElem[] $diff
     * @return DiffElem[]
     */
    private function coalesceReplacements(array $diff)
    {
        $newDiff = [];
        $c = \count($diff);
        for ($i = 0; $i < $c; $i++) {
            $diffType = $diff[$i]->type;
            if ($diffType !== DiffElem::TYPE_REMOVE) {
                $newDiff[] = $diff[$i];
                continue;
            }
            $j = $i;
            while ($j < $c && $diff[$j]->type === DiffElem::TYPE_REMOVE) {
                $j++;
            }
            $k = $j;
            while ($k < $c && $diff[$k]->type === DiffElem::TYPE_ADD) {
                $k++;
            }
            if ($j - $i === $k - $j) {
                $len = $j - $i;
                for ($n = 0; $n < $len; $n++) {
                    $newDiff[] = new DiffElem(DiffElem::TYPE_REPLACE, $diff[$i + $n]->old, $diff[$j + $n]->new);
                }
            } else {
                for (; $i < $k; $i++) {
                    $newDiff[] = $diff[$i];
                }
            }
            $i = $k - 1;
        }
        return $newDiff;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor\FindingVisitor;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor\FirstFindingVisitor;
class NodeFinder
{
    /**
     * Find all nodes satisfying a filter callback.
     *
     * @param Node|Node[] $nodes  Single node or array of nodes to search in
     * @param callable    $filter Filter callback: function(Node $node) : bool
     *
     * @return Node[] Found nodes satisfying the filter callback
     */
    public function find($nodes, callable $filter) : array
    {
        if (!\is_array($nodes)) {
            $nodes = [$nodes];
        }
        $visitor = new FindingVisitor($filter);
        $traverser = new NodeTraverser();
        $traverser->addVisitor($visitor);
        $traverser->traverse($nodes);
        return $visitor->getFoundNodes();
    }
    /**
     * Find all nodes that are instances of a certain class.
     *
     * @param Node|Node[] $nodes Single node or array of nodes to search in
     * @param string      $class Class name
     *
     * @return Node[] Found nodes (all instances of $class)
     */
    public function findInstanceOf($nodes, string $class) : array
    {
        return $this->find($nodes, function ($node) use($class) {
            return $node instanceof $class;
        });
    }
    /**
     * Find first node satisfying a filter callback.
     *
     * @param Node|Node[] $nodes  Single node or array of nodes to search in
     * @param callable    $filter Filter callback: function(Node $node) : bool
     *
     * @return null|Node Found node (or null if none found)
     */
    public function findFirst($nodes, callable $filter)
    {
        if (!\is_array($nodes)) {
            $nodes = [$nodes];
        }
        $visitor = new FirstFindingVisitor($filter);
        $traverser = new NodeTraverser();
        $traverser->addVisitor($visitor);
        $traverser->traverse($nodes);
        return $visitor->getFoundNode();
    }
    /**
     * Find first node that is an instance of a certain class.
     *
     * @param Node|Node[] $nodes  Single node or array of nodes to search in
     * @param string      $class Class name
     *
     * @return null|Node Found node, which is an instance of $class (or null if none found)
     */
    public function findFirstInstanceOf($nodes, string $class)
    {
        return $this->findFirst($nodes, function ($node) use($class) {
            return $node instanceof $class;
        });
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

/**
 * @codeCoverageIgnore
 */
class NodeVisitorAbstract implements NodeVisitor
{
    public function beforeTraverse(array $nodes)
    {
        return null;
    }
    public function enterNode(Node $node)
    {
        return null;
    }
    public function leaveNode(Node $node)
    {
        return null;
    }
    public function afterTraverse(array $nodes)
    {
        return null;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

abstract class NodeAbstract implements Node, \JsonSerializable
{
    protected $attributes;
    /**
     * Creates a Node.
     *
     * @param array $attributes Array of attributes
     */
    public function __construct(array $attributes = [])
    {
        $this->attributes = $attributes;
    }
    /**
     * Gets line the node started in (alias of getStartLine).
     *
     * @return int Start line (or -1 if not available)
     */
    public function getLine() : int
    {
        return $this->attributes['startLine'] ?? -1;
    }
    /**
     * Gets line the node started in.
     *
     * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default).
     *
     * @return int Start line (or -1 if not available)
     */
    public function getStartLine() : int
    {
        return $this->attributes['startLine'] ?? -1;
    }
    /**
     * Gets the line the node ended in.
     *
     * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default).
     *
     * @return int End line (or -1 if not available)
     */
    public function getEndLine() : int
    {
        return $this->attributes['endLine'] ?? -1;
    }
    /**
     * Gets the token offset of the first token that is part of this node.
     *
     * The offset is an index into the array returned by Lexer::getTokens().
     *
     * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int Token start position (or -1 if not available)
     */
    public function getStartTokenPos() : int
    {
        return $this->attributes['startTokenPos'] ?? -1;
    }
    /**
     * Gets the token offset of the last token that is part of this node.
     *
     * The offset is an index into the array returned by Lexer::getTokens().
     *
     * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int Token end position (or -1 if not available)
     */
    public function getEndTokenPos() : int
    {
        return $this->attributes['endTokenPos'] ?? -1;
    }
    /**
     * Gets the file offset of the first character that is part of this node.
     *
     * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int File start position (or -1 if not available)
     */
    public function getStartFilePos() : int
    {
        return $this->attributes['startFilePos'] ?? -1;
    }
    /**
     * Gets the file offset of the last character that is part of this node.
     *
     * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default).
     *
     * @return int File end position (or -1 if not available)
     */
    public function getEndFilePos() : int
    {
        return $this->attributes['endFilePos'] ?? -1;
    }
    /**
     * Gets all comments directly preceding this node.
     *
     * The comments are also available through the "comments" attribute.
     *
     * @return Comment[]
     */
    public function getComments() : array
    {
        return $this->attributes['comments'] ?? [];
    }
    /**
     * Gets the doc comment of the node.
     *
     * @return null|Comment\Doc Doc comment object or null
     */
    public function getDocComment()
    {
        $comments = $this->getComments();
        for ($i = \count($comments) - 1; $i >= 0; $i--) {
            $comment = $comments[$i];
            if ($comment instanceof Comment\Doc) {
                return $comment;
            }
        }
        return null;
    }
    /**
     * Sets the doc comment of the node.
     *
     * This will either replace an existing doc comment or add it to the comments array.
     *
     * @param Comment\Doc $docComment Doc comment to set
     */
    public function setDocComment(Comment\Doc $docComment)
    {
        $comments = $this->getComments();
        for ($i = \count($comments) - 1; $i >= 0; $i--) {
            if ($comments[$i] instanceof Comment\Doc) {
                // Replace existing doc comment.
                $comments[$i] = $docComment;
                $this->setAttribute('comments', $comments);
                return;
            }
        }
        // Append new doc comment.
        $comments[] = $docComment;
        $this->setAttribute('comments', $comments);
    }
    public function setAttribute(string $key, $value)
    {
        $this->attributes[$key] = $value;
    }
    public function hasAttribute(string $key) : bool
    {
        return \array_key_exists($key, $this->attributes);
    }
    public function getAttribute(string $key, $default = null)
    {
        if (\array_key_exists($key, $this->attributes)) {
            return $this->attributes[$key];
        }
        return $default;
    }
    public function getAttributes() : array
    {
        return $this->attributes;
    }
    public function setAttributes(array $attributes)
    {
        $this->attributes = $attributes;
    }
    /**
     * @return array
     */
    public function jsonSerialize() : array
    {
        return ['nodeType' => $this->getType()] + \get_object_vars($this);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\PhpParser;

class ConstExprEvaluationException extends \Exception
{
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

class ParserFactory
{
    const PREFER_PHP7 = 1;
    const PREFER_PHP5 = 2;
    const ONLY_PHP7 = 3;
    const ONLY_PHP5 = 4;
    /**
     * Creates a Parser instance, according to the provided kind.
     *
     * @param int        $kind  One of ::PREFER_PHP7, ::PREFER_PHP5, ::ONLY_PHP7 or ::ONLY_PHP5
     * @param Lexer|null $lexer Lexer to use. Defaults to emulative lexer when not specified
     * @param array      $parserOptions Parser options. See ParserAbstract::__construct() argument
     *
     * @return Parser The parser instance
     */
    public function create(int $kind, Lexer $lexer = null, array $parserOptions = []) : Parser
    {
        if (null === $lexer) {
            $lexer = new Lexer\Emulative();
        }
        switch ($kind) {
            case self::PREFER_PHP7:
                return new Parser\Multiple([new Parser\Php7($lexer, $parserOptions), new Parser\Php5($lexer, $parserOptions)]);
            case self::PREFER_PHP5:
                return new Parser\Multiple([new Parser\Php5($lexer, $parserOptions), new Parser\Php7($lexer, $parserOptions)]);
            case self::ONLY_PHP7:
                return new Parser\Php7($lexer, $parserOptions);
            case self::ONLY_PHP5:
                return new Parser\Php5($lexer, $parserOptions);
            default:
                throw new \LogicException('Kind must be one of ::PREFER_PHP7, ::PREFER_PHP5, ::ONLY_PHP7 or ::ONLY_PHP5');
        }
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

use _HumbugBox1cb33d1f20f1\PhpParser\Parser\Tokens;
class Lexer
{
    protected $code;
    protected $tokens;
    protected $pos;
    protected $line;
    protected $filePos;
    protected $prevCloseTagHasNewline;
    protected $tokenMap;
    protected $dropTokens;
    protected $identifierTokens;
    private $attributeStartLineUsed;
    private $attributeEndLineUsed;
    private $attributeStartTokenPosUsed;
    private $attributeEndTokenPosUsed;
    private $attributeStartFilePosUsed;
    private $attributeEndFilePosUsed;
    private $attributeCommentsUsed;
    /**
     * Creates a Lexer.
     *
     * @param array $options Options array. Currently only the 'usedAttributes' option is supported,
     *                       which is an array of attributes to add to the AST nodes. Possible
     *                       attributes are: 'comments', 'startLine', 'endLine', 'startTokenPos',
     *                       'endTokenPos', 'startFilePos', 'endFilePos'. The option defaults to the
     *                       first three. For more info see getNextToken() docs.
     */
    public function __construct(array $options = [])
    {
        // Create Map from internal tokens to PhpParser tokens.
        $this->defineCompatibilityTokens();
        $this->tokenMap = $this->createTokenMap();
        $this->identifierTokens = $this->createIdentifierTokenMap();
        // map of tokens to drop while lexing (the map is only used for isset lookup,
        // that's why the value is simply set to 1; the value is never actually used.)
        $this->dropTokens = \array_fill_keys([\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT, \T_BAD_CHARACTER], 1);
        $defaultAttributes = ['comments', 'startLine', 'endLine'];
        $usedAttributes = \array_fill_keys($options['usedAttributes'] ?? $defaultAttributes, \true);
        // Create individual boolean properties to make these checks faster.
        $this->attributeStartLineUsed = isset($usedAttributes['startLine']);
        $this->attributeEndLineUsed = isset($usedAttributes['endLine']);
        $this->attributeStartTokenPosUsed = isset($usedAttributes['startTokenPos']);
        $this->attributeEndTokenPosUsed = isset($usedAttributes['endTokenPos']);
        $this->attributeStartFilePosUsed = isset($usedAttributes['startFilePos']);
        $this->attributeEndFilePosUsed = isset($usedAttributes['endFilePos']);
        $this->attributeCommentsUsed = isset($usedAttributes['comments']);
    }
    /**
     * Initializes the lexer for lexing the provided source code.
     *
     * This function does not throw if lexing errors occur. Instead, errors may be retrieved using
     * the getErrors() method.
     *
     * @param string $code The source code to lex
     * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to
     *                                        ErrorHandler\Throwing
     */
    public function startLexing(string $code, ErrorHandler $errorHandler = null)
    {
        if (null === $errorHandler) {
            $errorHandler = new ErrorHandler\Throwing();
        }
        $this->code = $code;
        // keep the code around for __halt_compiler() handling
        $this->pos = -1;
        $this->line = 1;
        $this->filePos = 0;
        // If inline HTML occurs without preceding code, treat it as if it had a leading newline.
        // This ensures proper composability, because having a newline is the "safe" assumption.
        $this->prevCloseTagHasNewline = \true;
        $scream = \ini_set('xdebug.scream', '0');
        $this->tokens = @\token_get_all($code);
        $this->postprocessTokens($errorHandler);
        if (\false !== $scream) {
            \ini_set('xdebug.scream', $scream);
        }
    }
    private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $errorHandler)
    {
        $tokens = [];
        for ($i = $start; $i < $end; $i++) {
            $chr = $this->code[$i];
            if ($chr === "\x00") {
                // PHP cuts error message after null byte, so need special case
                $errorMsg = 'Unexpected null byte';
            } else {
                $errorMsg = \sprintf('Unexpected character "%s" (ASCII %d)', $chr, \ord($chr));
            }
            $tokens[] = [\T_BAD_CHARACTER, $chr, $line];
            $errorHandler->handleError(new Error($errorMsg, ['startLine' => $line, 'endLine' => $line, 'startFilePos' => $i, 'endFilePos' => $i]));
        }
        return $tokens;
    }
    /**
     * Check whether comment token is unterminated.
     *
     * @return bool
     */
    private function isUnterminatedComment($token) : bool
    {
        return ($token[0] === \T_COMMENT || $token[0] === \T_DOC_COMMENT) && \substr($token[1], 0, 2) === '/*' && \substr($token[1], -2) !== '*/';
    }
    protected function postprocessTokens(ErrorHandler $errorHandler)
    {
        // PHP's error handling for token_get_all() is rather bad, so if we want detailed
        // error information we need to compute it ourselves. Invalid character errors are
        // detected by finding "gaps" in the token array. Unterminated comments are detected
        // by checking if a trailing comment has a "*/" at the end.
        //
        // Additionally, we perform a number of canonicalizations here:
        //  * Use the PHP 8.0 comment format, which does not include trailing whitespace anymore.
        //  * Use PHP 8.0 T_NAME_* tokens.
        //  * Use PHP 8.1 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG and
        //    T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG tokens used to disambiguate intersection types.
        $filePos = 0;
        $line = 1;
        $numTokens = \count($this->tokens);
        for ($i = 0; $i < $numTokens; $i++) {
            $token = $this->tokens[$i];
            // Since PHP 7.4 invalid characters are represented by a T_BAD_CHARACTER token.
            // In this case we only need to emit an error.
            if ($token[0] === \T_BAD_CHARACTER) {
                $this->handleInvalidCharacterRange($filePos, $filePos + 1, $line, $errorHandler);
            }
            if ($token[0] === \T_COMMENT && \substr($token[1], 0, 2) !== '/*' && \preg_match('/(\\r\\n|\\n|\\r)$/D', $token[1], $matches)) {
                $trailingNewline = $matches[0];
                $token[1] = \substr($token[1], 0, -\strlen($trailingNewline));
                $this->tokens[$i] = $token;
                if (isset($this->tokens[$i + 1]) && $this->tokens[$i + 1][0] === \T_WHITESPACE) {
                    // Move trailing newline into following T_WHITESPACE token, if it already exists.
                    $this->tokens[$i + 1][1] = $trailingNewline . $this->tokens[$i + 1][1];
                    $this->tokens[$i + 1][2]--;
                } else {
                    // Otherwise, we need to create a new T_WHITESPACE token.
                    \array_splice($this->tokens, $i + 1, 0, [[\T_WHITESPACE, $trailingNewline, $line]]);
                    $numTokens++;
                }
            }
            // Emulate PHP 8 T_NAME_* tokens, by combining sequences of T_NS_SEPARATOR and T_STRING
            // into a single token.
            if (\is_array($token) && ($token[0] === \T_NS_SEPARATOR || isset($this->identifierTokens[$token[0]]))) {
                $lastWasSeparator = $token[0] === \T_NS_SEPARATOR;
                $text = $token[1];
                for ($j = $i + 1; isset($this->tokens[$j]); $j++) {
                    if ($lastWasSeparator) {
                        if (!isset($this->identifierTokens[$this->tokens[$j][0]])) {
                            break;
                        }
                        $lastWasSeparator = \false;
                    } else {
                        if ($this->tokens[$j][0] !== \T_NS_SEPARATOR) {
                            break;
                        }
                        $lastWasSeparator = \true;
                    }
                    $text .= $this->tokens[$j][1];
                }
                if ($lastWasSeparator) {
                    // Trailing separator is not part of the name.
                    $j--;
                    $text = \substr($text, 0, -1);
                }
                if ($j > $i + 1) {
                    if ($token[0] === \T_NS_SEPARATOR) {
                        $type = \T_NAME_FULLY_QUALIFIED;
                    } else {
                        if ($token[0] === \T_NAMESPACE) {
                            $type = \T_NAME_RELATIVE;
                        } else {
                            $type = \T_NAME_QUALIFIED;
                        }
                    }
                    $token = [$type, $text, $line];
                    \array_splice($this->tokens, $i, $j - $i, [$token]);
                    $numTokens -= $j - $i - 1;
                }
            }
            if ($token === '&') {
                $next = $i + 1;
                while (isset($this->tokens[$next]) && $this->tokens[$next][0] === \T_WHITESPACE) {
                    $next++;
                }
                $followedByVarOrVarArg = isset($this->tokens[$next]) && ($this->tokens[$next][0] === \T_VARIABLE || $this->tokens[$next][0] === \T_ELLIPSIS);
                $this->tokens[$i] = $token = [$followedByVarOrVarArg ? \T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG : \T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG, '&', $line];
            }
            $tokenValue = \is_string($token) ? $token : $token[1];
            $tokenLen = \strlen($tokenValue);
            if (\substr($this->code, $filePos, $tokenLen) !== $tokenValue) {
                // Something is missing, must be an invalid character
                $nextFilePos = \strpos($this->code, $tokenValue, $filePos);
                $badCharTokens = $this->handleInvalidCharacterRange($filePos, $nextFilePos, $line, $errorHandler);
                $filePos = (int) $nextFilePos;
                \array_splice($this->tokens, $i, 0, $badCharTokens);
                $numTokens += \count($badCharTokens);
                $i += \count($badCharTokens);
            }
            $filePos += $tokenLen;
            $line += \substr_count($tokenValue, "\n");
        }
        if ($filePos !== \strlen($this->code)) {
            if (\substr($this->code, $filePos, 2) === '/*') {
                // Unlike PHP, HHVM will drop unterminated comments entirely
                $comment = \substr($this->code, $filePos);
                $errorHandler->handleError(new Error('Unterminated comment', ['startLine' => $line, 'endLine' => $line + \substr_count($comment, "\n"), 'startFilePos' => $filePos, 'endFilePos' => $filePos + \strlen($comment)]));
                // Emulate the PHP behavior
                $isDocComment = isset($comment[3]) && $comment[3] === '*';
                $this->tokens[] = [$isDocComment ? \T_DOC_COMMENT : \T_COMMENT, $comment, $line];
            } else {
                // Invalid characters at the end of the input
                $badCharTokens = $this->handleInvalidCharacterRange($filePos, \strlen($this->code), $line, $errorHandler);
                $this->tokens = \array_merge($this->tokens, $badCharTokens);
            }
            return;
        }
        if (\count($this->tokens) > 0) {
            // Check for unterminated comment
            $lastToken = $this->tokens[\count($this->tokens) - 1];
            if ($this->isUnterminatedComment($lastToken)) {
                $errorHandler->handleError(new Error('Unterminated comment', ['startLine' => $line - \substr_count($lastToken[1], "\n"), 'endLine' => $line, 'startFilePos' => $filePos - \strlen($lastToken[1]), 'endFilePos' => $filePos]));
            }
        }
    }
    /**
     * Fetches the next token.
     *
     * The available attributes are determined by the 'usedAttributes' option, which can
     * be specified in the constructor. The following attributes are supported:
     *
     *  * 'comments'      => Array of PhpParser\Comment or PhpParser\Comment\Doc instances,
     *                       representing all comments that occurred between the previous
     *                       non-discarded token and the current one.
     *  * 'startLine'     => Line in which the node starts.
     *  * 'endLine'       => Line in which the node ends.
     *  * 'startTokenPos' => Offset into the token array of the first token in the node.
     *  * 'endTokenPos'   => Offset into the token array of the last token in the node.
     *  * 'startFilePos'  => Offset into the code string of the first character that is part of the node.
     *  * 'endFilePos'    => Offset into the code string of the last character that is part of the node.
     *
     * @param mixed $value           Variable to store token content in
     * @param mixed $startAttributes Variable to store start attributes in
     * @param mixed $endAttributes   Variable to store end attributes in
     *
     * @return int Token id
     */
    public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int
    {
        $startAttributes = [];
        $endAttributes = [];
        while (1) {
            if (isset($this->tokens[++$this->pos])) {
                $token = $this->tokens[$this->pos];
            } else {
                // EOF token with ID 0
                $token = "\x00";
            }
            if ($this->attributeStartLineUsed) {
                $startAttributes['startLine'] = $this->line;
            }
            if ($this->attributeStartTokenPosUsed) {
                $startAttributes['startTokenPos'] = $this->pos;
            }
            if ($this->attributeStartFilePosUsed) {
                $startAttributes['startFilePos'] = $this->filePos;
            }
            if (\is_string($token)) {
                $value = $token;
                if (isset($token[1])) {
                    // bug in token_get_all
                    $this->filePos += 2;
                    $id = \ord('"');
                } else {
                    $this->filePos += 1;
                    $id = \ord($token);
                }
            } elseif (!isset($this->dropTokens[$token[0]])) {
                $value = $token[1];
                $id = $this->tokenMap[$token[0]];
                if (\T_CLOSE_TAG === $token[0]) {
                    $this->prevCloseTagHasNewline = \false !== \strpos($token[1], "\n") || \false !== \strpos($token[1], "\r");
                } elseif (\T_INLINE_HTML === $token[0]) {
                    $startAttributes['hasLeadingNewline'] = $this->prevCloseTagHasNewline;
                }
                $this->line += \substr_count($value, "\n");
                $this->filePos += \strlen($value);
            } else {
                $origLine = $this->line;
                $origFilePos = $this->filePos;
                $this->line += \substr_count($token[1], "\n");
                $this->filePos += \strlen($token[1]);
                if (\T_COMMENT === $token[0] || \T_DOC_COMMENT === $token[0]) {
                    if ($this->attributeCommentsUsed) {
                        $comment = \T_DOC_COMMENT === $token[0] ? new Comment\Doc($token[1], $origLine, $origFilePos, $this->pos, $this->line, $this->filePos - 1, $this->pos) : new Comment($token[1], $origLine, $origFilePos, $this->pos, $this->line, $this->filePos - 1, $this->pos);
                        $startAttributes['comments'][] = $comment;
                    }
                }
                continue;
            }
            if ($this->attributeEndLineUsed) {
                $endAttributes['endLine'] = $this->line;
            }
            if ($this->attributeEndTokenPosUsed) {
                $endAttributes['endTokenPos'] = $this->pos;
            }
            if ($this->attributeEndFilePosUsed) {
                $endAttributes['endFilePos'] = $this->filePos - 1;
            }
            return $id;
        }
        throw new \RuntimeException('Reached end of lexer loop');
    }
    /**
     * Returns the token array for current code.
     *
     * The token array is in the same format as provided by the
     * token_get_all() function and does not discard tokens (i.e.
     * whitespace and comments are included). The token position
     * attributes are against this token array.
     *
     * @return array Array of tokens in token_get_all() format
     */
    public function getTokens() : array
    {
        return $this->tokens;
    }
    /**
     * Handles __halt_compiler() by returning the text after it.
     *
     * @return string Remaining text
     */
    public function handleHaltCompiler() : string
    {
        // text after T_HALT_COMPILER, still including ();
        $textAfter = \substr($this->code, $this->filePos);
        // ensure that it is followed by ();
        // this simplifies the situation, by not allowing any comments
        // in between of the tokens.
        if (!\preg_match('~^\\s*\\(\\s*\\)\\s*(?:;|\\?>\\r?\\n?)~', $textAfter, $matches)) {
            throw new Error('__HALT_COMPILER must be followed by "();"');
        }
        // prevent the lexer from returning any further tokens
        $this->pos = \count($this->tokens);
        // return with (); removed
        return \substr($textAfter, \strlen($matches[0]));
    }
    private function defineCompatibilityTokens()
    {
        static $compatTokensDefined = \false;
        if ($compatTokensDefined) {
            return;
        }
        $compatTokens = [
            // PHP 7.4
            'T_BAD_CHARACTER',
            'T_FN',
            'T_COALESCE_EQUAL',
            // PHP 8.0
            'T_NAME_QUALIFIED',
            'T_NAME_FULLY_QUALIFIED',
            'T_NAME_RELATIVE',
            'T_MATCH',
            'T_NULLSAFE_OBJECT_OPERATOR',
            'T_ATTRIBUTE',
            // PHP 8.1
            'T_ENUM',
            'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG',
            'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG',
            'T_READONLY',
        ];
        // PHP-Parser might be used together with another library that also emulates some or all
        // of these tokens. Perform a sanity-check that all already defined tokens have been
        // assigned a unique ID.
        $usedTokenIds = [];
        foreach ($compatTokens as $token) {
            if (\defined($token)) {
                $tokenId = \constant($token);
                $clashingToken = $usedTokenIds[$tokenId] ?? null;
                if ($clashingToken !== null) {
                    throw new \Error(\sprintf('Token %s has same ID as token %s, ' . 'you may be using a library with broken token emulation', $token, $clashingToken));
                }
                $usedTokenIds[$tokenId] = $token;
            }
        }
        // Now define any tokens that have not yet been emulated. Try to assign IDs from -1
        // downwards, but skip any IDs that may already be in use.
        $newTokenId = -1;
        foreach ($compatTokens as $token) {
            if (!\defined($token)) {
                while (isset($usedTokenIds[$newTokenId])) {
                    $newTokenId--;
                }
                \define($token, $newTokenId);
                $newTokenId--;
            }
        }
        $compatTokensDefined = \true;
    }
    /**
     * Creates the token map.
     *
     * The token map maps the PHP internal token identifiers
     * to the identifiers used by the Parser. Additionally it
     * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'.
     *
     * @return array The token map
     */
    protected function createTokenMap() : array
    {
        $tokenMap = [];
        // 256 is the minimum possible token number, as everything below
        // it is an ASCII value
        for ($i = 256; $i < 1000; ++$i) {
            if (\T_DOUBLE_COLON === $i) {
                // T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM
                $tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM;
            } elseif (\T_OPEN_TAG_WITH_ECHO === $i) {
                // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
                $tokenMap[$i] = Tokens::T_ECHO;
            } elseif (\T_CLOSE_TAG === $i) {
                // T_CLOSE_TAG is equivalent to ';'
                $tokenMap[$i] = \ord(';');
            } elseif ('UNKNOWN' !== ($name = \token_name($i))) {
                if ('T_HASHBANG' === $name) {
                    // HHVM uses a special token for #! hashbang lines
                    $tokenMap[$i] = Tokens::T_INLINE_HTML;
                } elseif (\defined($name = Tokens::class . '::' . $name)) {
                    // Other tokens can be mapped directly
                    $tokenMap[$i] = \constant($name);
                }
            }
        }
        // HHVM uses a special token for numbers that overflow to double
        if (\defined('_HumbugBox1cb33d1f20f1\\T_ONUMBER')) {
            $tokenMap[\_HumbugBox1cb33d1f20f1\T_ONUMBER] = Tokens::T_DNUMBER;
        }
        // HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant
        if (\defined('_HumbugBox1cb33d1f20f1\\T_COMPILER_HALT_OFFSET')) {
            $tokenMap[\_HumbugBox1cb33d1f20f1\T_COMPILER_HALT_OFFSET] = Tokens::T_STRING;
        }
        // Assign tokens for which we define compatibility constants, as token_name() does not know them.
        $tokenMap[\T_FN] = Tokens::T_FN;
        $tokenMap[\T_COALESCE_EQUAL] = Tokens::T_COALESCE_EQUAL;
        $tokenMap[\T_NAME_QUALIFIED] = Tokens::T_NAME_QUALIFIED;
        $tokenMap[\T_NAME_FULLY_QUALIFIED] = Tokens::T_NAME_FULLY_QUALIFIED;
        $tokenMap[\T_NAME_RELATIVE] = Tokens::T_NAME_RELATIVE;
        $tokenMap[\T_MATCH] = Tokens::T_MATCH;
        $tokenMap[\T_NULLSAFE_OBJECT_OPERATOR] = Tokens::T_NULLSAFE_OBJECT_OPERATOR;
        $tokenMap[\T_ATTRIBUTE] = Tokens::T_ATTRIBUTE;
        $tokenMap[\T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG] = Tokens::T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG;
        $tokenMap[\T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG] = Tokens::T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG;
        $tokenMap[\T_ENUM] = Tokens::T_ENUM;
        $tokenMap[\T_READONLY] = Tokens::T_READONLY;
        return $tokenMap;
    }
    private function createIdentifierTokenMap() : array
    {
        // Based on semi_reserved production.
        return \array_fill_keys([\T_STRING, \T_STATIC, \T_ABSTRACT, \T_FINAL, \T_PRIVATE, \T_PROTECTED, \T_PUBLIC, \T_READONLY, \T_INCLUDE, \T_INCLUDE_ONCE, \T_EVAL, \T_REQUIRE, \T_REQUIRE_ONCE, \T_LOGICAL_OR, \T_LOGICAL_XOR, \T_LOGICAL_AND, \T_INSTANCEOF, \T_NEW, \T_CLONE, \T_EXIT, \T_IF, \T_ELSEIF, \T_ELSE, \T_ENDIF, \T_ECHO, \T_DO, \T_WHILE, \T_ENDWHILE, \T_FOR, \T_ENDFOR, \T_FOREACH, \T_ENDFOREACH, \T_DECLARE, \T_ENDDECLARE, \T_AS, \T_TRY, \T_CATCH, \T_FINALLY, \T_THROW, \T_USE, \T_INSTEADOF, \T_GLOBAL, \T_VAR, \T_UNSET, \T_ISSET, \T_EMPTY, \T_CONTINUE, \T_GOTO, \T_FUNCTION, \T_CONST, \T_RETURN, \T_PRINT, \T_YIELD, \T_LIST, \T_SWITCH, \T_ENDSWITCH, \T_CASE, \T_DEFAULT, \T_BREAK, \T_ARRAY, \T_CALLABLE, \T_EXTENDS, \T_IMPLEMENTS, \T_NAMESPACE, \T_TRAIT, \T_INTERFACE, \T_CLASS, \T_CLASS_C, \T_TRAIT_C, \T_FUNC_C, \T_METHOD_C, \T_LINE, \T_FILE, \T_DIR, \T_NS_C, \T_HALT_COMPILER, \T_FN, \T_MATCH], \true);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\AttributeEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\EnumTokenEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\CoaleseEqualTokenEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\ExplicitOctalEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\FlexibleDocStringEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\FnTokenEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\NumericLiteralSeparatorEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\ReadonlyFunctionTokenEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\ReadonlyTokenEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\ReverseEmulator;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator\TokenEmulator;
class Emulative extends Lexer
{
    const PHP_7_3 = '7.3dev';
    const PHP_7_4 = '7.4dev';
    const PHP_8_0 = '8.0dev';
    const PHP_8_1 = '8.1dev';
    const PHP_8_2 = '8.2dev';
    /** @var mixed[] Patches used to reverse changes introduced in the code */
    private $patches = [];
    /** @var TokenEmulator[] */
    private $emulators = [];
    /** @var string */
    private $targetPhpVersion;
    /**
     * @param mixed[] $options Lexer options. In addition to the usual options,
     *                         accepts a 'phpVersion' string that specifies the
     *                         version to emulate. Defaults to newest supported.
     */
    public function __construct(array $options = [])
    {
        $this->targetPhpVersion = $options['phpVersion'] ?? Emulative::PHP_8_2;
        unset($options['phpVersion']);
        parent::__construct($options);
        $emulators = [new FlexibleDocStringEmulator(), new FnTokenEmulator(), new MatchTokenEmulator(), new CoaleseEqualTokenEmulator(), new NumericLiteralSeparatorEmulator(), new NullsafeTokenEmulator(), new AttributeEmulator(), new EnumTokenEmulator(), new ReadonlyTokenEmulator(), new ExplicitOctalEmulator(), new ReadonlyFunctionTokenEmulator()];
        // Collect emulators that are relevant for the PHP version we're running
        // and the PHP version we're targeting for emulation.
        foreach ($emulators as $emulator) {
            $emulatorPhpVersion = $emulator->getPhpVersion();
            if ($this->isForwardEmulationNeeded($emulatorPhpVersion)) {
                $this->emulators[] = $emulator;
            } else {
                if ($this->isReverseEmulationNeeded($emulatorPhpVersion)) {
                    $this->emulators[] = new ReverseEmulator($emulator);
                }
            }
        }
    }
    public function startLexing(string $code, ErrorHandler $errorHandler = null)
    {
        $emulators = \array_filter($this->emulators, function ($emulator) use($code) {
            return $emulator->isEmulationNeeded($code);
        });
        if (empty($emulators)) {
            // Nothing to emulate, yay
            parent::startLexing($code, $errorHandler);
            return;
        }
        $this->patches = [];
        foreach ($emulators as $emulator) {
            $code = $emulator->preprocessCode($code, $this->patches);
        }
        $collector = new ErrorHandler\Collecting();
        parent::startLexing($code, $collector);
        $this->sortPatches();
        $this->fixupTokens();
        $errors = $collector->getErrors();
        if (!empty($errors)) {
            $this->fixupErrors($errors);
            foreach ($errors as $error) {
                $errorHandler->handleError($error);
            }
        }
        foreach ($emulators as $emulator) {
            $this->tokens = $emulator->emulate($code, $this->tokens);
        }
    }
    private function isForwardEmulationNeeded(string $emulatorPhpVersion) : bool
    {
        return \version_compare(\PHP_VERSION, $emulatorPhpVersion, '<') && \version_compare($this->targetPhpVersion, $emulatorPhpVersion, '>=');
    }
    private function isReverseEmulationNeeded(string $emulatorPhpVersion) : bool
    {
        return \version_compare(\PHP_VERSION, $emulatorPhpVersion, '>=') && \version_compare($this->targetPhpVersion, $emulatorPhpVersion, '<');
    }
    private function sortPatches()
    {
        // Patches may be contributed by different emulators.
        // Make sure they are sorted by increasing patch position.
        \usort($this->patches, function ($p1, $p2) {
            return $p1[0] <=> $p2[0];
        });
    }
    private function fixupTokens()
    {
        if (\count($this->patches) === 0) {
            return;
        }
        // Load first patch
        $patchIdx = 0;
        list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
        // We use a manual loop over the tokens, because we modify the array on the fly
        $pos = 0;
        for ($i = 0, $c = \count($this->tokens); $i < $c; $i++) {
            $token = $this->tokens[$i];
            if (\is_string($token)) {
                if ($patchPos === $pos) {
                    // Only support replacement for string tokens.
                    \assert($patchType === 'replace');
                    $this->tokens[$i] = $patchText;
                    // Fetch the next patch
                    $patchIdx++;
                    if ($patchIdx >= \count($this->patches)) {
                        // No more patches, we're done
                        return;
                    }
                    list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
                }
                $pos += \strlen($token);
                continue;
            }
            $len = \strlen($token[1]);
            $posDelta = 0;
            while ($patchPos >= $pos && $patchPos < $pos + $len) {
                $patchTextLen = \strlen($patchText);
                if ($patchType === 'remove') {
                    if ($patchPos === $pos && $patchTextLen === $len) {
                        // Remove token entirely
                        \array_splice($this->tokens, $i, 1, []);
                        $i--;
                        $c--;
                    } else {
                        // Remove from token string
                        $this->tokens[$i][1] = \substr_replace($token[1], '', $patchPos - $pos + $posDelta, $patchTextLen);
                        $posDelta -= $patchTextLen;
                    }
                } elseif ($patchType === 'add') {
                    // Insert into the token string
                    $this->tokens[$i][1] = \substr_replace($token[1], $patchText, $patchPos - $pos + $posDelta, 0);
                    $posDelta += $patchTextLen;
                } else {
                    if ($patchType === 'replace') {
                        // Replace inside the token string
                        $this->tokens[$i][1] = \substr_replace($token[1], $patchText, $patchPos - $pos + $posDelta, $patchTextLen);
                    } else {
                        \assert(\false);
                    }
                }
                // Fetch the next patch
                $patchIdx++;
                if ($patchIdx >= \count($this->patches)) {
                    // No more patches, we're done
                    return;
                }
                list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
                // Multiple patches may apply to the same token. Reload the current one to check
                // If the new patch applies
                $token = $this->tokens[$i];
            }
            $pos += $len;
        }
        // A patch did not apply
        \assert(\false);
    }
    /**
     * Fixup line and position information in errors.
     *
     * @param Error[] $errors
     */
    private function fixupErrors(array $errors)
    {
        foreach ($errors as $error) {
            $attrs = $error->getAttributes();
            $posDelta = 0;
            $lineDelta = 0;
            foreach ($this->patches as $patch) {
                list($patchPos, $patchType, $patchText) = $patch;
                if ($patchPos >= $attrs['startFilePos']) {
                    // No longer relevant
                    break;
                }
                if ($patchType === 'add') {
                    $posDelta += \strlen($patchText);
                    $lineDelta += \substr_count($patchText, "\n");
                } else {
                    if ($patchType === 'remove') {
                        $posDelta -= \strlen($patchText);
                        $lineDelta -= \substr_count($patchText, "\n");
                    }
                }
            }
            $attrs['startFilePos'] += $posDelta;
            $attrs['endFilePos'] += $posDelta;
            $attrs['startLine'] += $lineDelta;
            $attrs['endLine'] += $lineDelta;
            $error->setAttributes($attrs);
        }
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
/*
 * In PHP 8.1, "readonly(" was special cased in the lexer in order to support functions with
 * name readonly. In PHP 8.2, this may conflict with readonly properties having a DNF type. For
 * this reason, PHP 8.2 instead treats this as T_READONLY and then handles it specially in the
 * parser. This emulator only exists to handle this special case, which is skipped by the
 * PHP 8.1 ReadonlyTokenEmulator.
 */
class ReadonlyFunctionTokenEmulator extends KeywordEmulator
{
    public function getKeywordString() : string
    {
        return 'readonly';
    }
    public function getKeywordToken() : int
    {
        return \T_READONLY;
    }
    public function getPhpVersion() : string
    {
        return Emulative::PHP_8_2;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        // Don't bother
        return $tokens;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class FlexibleDocStringEmulator extends TokenEmulator
{
    const FLEXIBLE_DOC_STRING_REGEX = <<<'REGEX'
/<<<[ \t]*(['"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\1\r?\n
(?:.*\r?\n)*?
(?<indentation>\h*)\2(?![a-zA-Z0-9_\x80-\xff])(?<separator>(?:;?[\r\n])?)/x
REGEX;
    public function getPhpVersion() : string
    {
        return Emulative::PHP_7_3;
    }
    public function isEmulationNeeded(string $code) : bool
    {
        return \strpos($code, '<<<') !== \false;
    }
    public function emulate(string $code, array $tokens) : array
    {
        // Handled by preprocessing + fixup.
        return $tokens;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        // Not supported.
        return $tokens;
    }
    public function preprocessCode(string $code, array &$patches) : string
    {
        if (!\preg_match_all(self::FLEXIBLE_DOC_STRING_REGEX, $code, $matches, \PREG_SET_ORDER | \PREG_OFFSET_CAPTURE)) {
            // No heredoc/nowdoc found
            return $code;
        }
        // Keep track of how much we need to adjust string offsets due to the modifications we
        // already made
        $posDelta = 0;
        foreach ($matches as $match) {
            $indentation = $match['indentation'][0];
            $indentationStart = $match['indentation'][1];
            $separator = $match['separator'][0];
            $separatorStart = $match['separator'][1];
            if ($indentation === '' && $separator !== '') {
                // Ordinary heredoc/nowdoc
                continue;
            }
            if ($indentation !== '') {
                // Remove indentation
                $indentationLen = \strlen($indentation);
                $code = \substr_replace($code, '', $indentationStart + $posDelta, $indentationLen);
                $patches[] = [$indentationStart + $posDelta, 'add', $indentation];
                $posDelta -= $indentationLen;
            }
            if ($separator === '') {
                // Insert newline as separator
                $code = \substr_replace($code, "\n", $separatorStart + $posDelta, 0);
                $patches[] = [$separatorStart + $posDelta, 'remove', "\n"];
                $posDelta += 1;
            }
        }
        return $code;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

/**
 * Reverses emulation direction of the inner emulator.
 */
final class ReverseEmulator extends TokenEmulator
{
    /** @var TokenEmulator Inner emulator */
    private $emulator;
    public function __construct(TokenEmulator $emulator)
    {
        $this->emulator = $emulator;
    }
    public function getPhpVersion() : string
    {
        return $this->emulator->getPhpVersion();
    }
    public function isEmulationNeeded(string $code) : bool
    {
        return $this->emulator->isEmulationNeeded($code);
    }
    public function emulate(string $code, array $tokens) : array
    {
        return $this->emulator->reverseEmulate($code, $tokens);
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        return $this->emulator->emulate($code, $tokens);
    }
    public function preprocessCode(string $code, array &$patches) : string
    {
        return $code;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class MatchTokenEmulator extends KeywordEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_8_0;
    }
    public function getKeywordString() : string
    {
        return 'match';
    }
    public function getKeywordToken() : int
    {
        return \T_MATCH;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class ReadonlyTokenEmulator extends KeywordEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_8_1;
    }
    public function getKeywordString() : string
    {
        return 'readonly';
    }
    public function getKeywordToken() : int
    {
        return \T_READONLY;
    }
    protected function isKeywordContext(array $tokens, int $pos) : bool
    {
        if (!parent::isKeywordContext($tokens, $pos)) {
            return \false;
        }
        // Support "function readonly("
        return !(isset($tokens[$pos + 1]) && ($tokens[$pos + 1][0] === '(' || $tokens[$pos + 1][0] === \T_WHITESPACE && isset($tokens[$pos + 2]) && $tokens[$pos + 2][0] === '('));
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
class ExplicitOctalEmulator extends TokenEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_8_1;
    }
    public function isEmulationNeeded(string $code) : bool
    {
        return \strpos($code, '0o') !== \false || \strpos($code, '0O') !== \false;
    }
    public function emulate(string $code, array $tokens) : array
    {
        for ($i = 0, $c = \count($tokens); $i < $c; ++$i) {
            if ($tokens[$i][0] == \T_LNUMBER && $tokens[$i][1] === '0' && isset($tokens[$i + 1]) && $tokens[$i + 1][0] == \T_STRING && \preg_match('/[oO][0-7]+(?:_[0-7]+)*/', $tokens[$i + 1][1])) {
                $tokenKind = $this->resolveIntegerOrFloatToken($tokens[$i + 1][1]);
                \array_splice($tokens, $i, 2, [[$tokenKind, '0' . $tokens[$i + 1][1], $tokens[$i][2]]]);
                $c--;
            }
        }
        return $tokens;
    }
    private function resolveIntegerOrFloatToken(string $str) : int
    {
        $str = \substr($str, 1);
        $str = \str_replace('_', '', $str);
        $num = \octdec($str);
        return \is_float($num) ? \T_DNUMBER : \T_LNUMBER;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        // Explicit octals were not legal code previously, don't bother.
        return $tokens;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class NumericLiteralSeparatorEmulator extends TokenEmulator
{
    const BIN = '(?:0b[01]+(?:_[01]+)*)';
    const HEX = '(?:0x[0-9a-f]+(?:_[0-9a-f]+)*)';
    const DEC = '(?:[0-9]+(?:_[0-9]+)*)';
    const SIMPLE_FLOAT = '(?:' . self::DEC . '\\.' . self::DEC . '?|\\.' . self::DEC . ')';
    const EXP = '(?:e[+-]?' . self::DEC . ')';
    const FLOAT = '(?:' . self::SIMPLE_FLOAT . self::EXP . '?|' . self::DEC . self::EXP . ')';
    const NUMBER = '~' . self::FLOAT . '|' . self::BIN . '|' . self::HEX . '|' . self::DEC . '~iA';
    public function getPhpVersion() : string
    {
        return Emulative::PHP_7_4;
    }
    public function isEmulationNeeded(string $code) : bool
    {
        return \preg_match('~[0-9]_[0-9]~', $code) || \preg_match('~0x[0-9a-f]+_[0-9a-f]~i', $code);
    }
    public function emulate(string $code, array $tokens) : array
    {
        // We need to manually iterate and manage a count because we'll change
        // the tokens array on the way
        $codeOffset = 0;
        for ($i = 0, $c = \count($tokens); $i < $c; ++$i) {
            $token = $tokens[$i];
            $tokenLen = \strlen(\is_array($token) ? $token[1] : $token);
            if ($token[0] !== \T_LNUMBER && $token[0] !== \T_DNUMBER) {
                $codeOffset += $tokenLen;
                continue;
            }
            $res = \preg_match(self::NUMBER, $code, $matches, 0, $codeOffset);
            \assert($res, "No number at number token position");
            $match = $matches[0];
            $matchLen = \strlen($match);
            if ($matchLen === $tokenLen) {
                // Original token already holds the full number.
                $codeOffset += $tokenLen;
                continue;
            }
            $tokenKind = $this->resolveIntegerOrFloatToken($match);
            $newTokens = [[$tokenKind, $match, $token[2]]];
            $numTokens = 1;
            $len = $tokenLen;
            while ($matchLen > $len) {
                $nextToken = $tokens[$i + $numTokens];
                $nextTokenText = \is_array($nextToken) ? $nextToken[1] : $nextToken;
                $nextTokenLen = \strlen($nextTokenText);
                $numTokens++;
                if ($matchLen < $len + $nextTokenLen) {
                    // Split trailing characters into a partial token.
                    \assert(\is_array($nextToken), "Partial token should be an array token");
                    $partialText = \substr($nextTokenText, $matchLen - $len);
                    $newTokens[] = [$nextToken[0], $partialText, $nextToken[2]];
                    break;
                }
                $len += $nextTokenLen;
            }
            \array_splice($tokens, $i, $numTokens, $newTokens);
            $c -= $numTokens - \count($newTokens);
            $codeOffset += $matchLen;
        }
        return $tokens;
    }
    private function resolveIntegerOrFloatToken(string $str) : int
    {
        $str = \str_replace('_', '', $str);
        if (\stripos($str, '0b') === 0) {
            $num = \bindec($str);
        } elseif (\stripos($str, '0x') === 0) {
            $num = \hexdec($str);
        } elseif (\stripos($str, '0') === 0 && \ctype_digit($str)) {
            $num = \octdec($str);
        } else {
            $num = +$str;
        }
        return \is_float($num) ? \T_DNUMBER : \T_LNUMBER;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        // Numeric separators were not legal code previously, don't bother.
        return $tokens;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

abstract class KeywordEmulator extends TokenEmulator
{
    abstract function getKeywordString() : string;
    abstract function getKeywordToken() : int;
    public function isEmulationNeeded(string $code) : bool
    {
        return \strpos(\strtolower($code), $this->getKeywordString()) !== \false;
    }
    protected function isKeywordContext(array $tokens, int $pos) : bool
    {
        $previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $pos);
        return $previousNonSpaceToken === null || $previousNonSpaceToken[0] !== \T_OBJECT_OPERATOR;
    }
    public function emulate(string $code, array $tokens) : array
    {
        $keywordString = $this->getKeywordString();
        foreach ($tokens as $i => $token) {
            if ($token[0] === \T_STRING && \strtolower($token[1]) === $keywordString && $this->isKeywordContext($tokens, $i)) {
                $tokens[$i][0] = $this->getKeywordToken();
            }
        }
        return $tokens;
    }
    /**
     * @param mixed[] $tokens
     * @return array|string|null
     */
    private function getPreviousNonSpaceToken(array $tokens, int $start)
    {
        for ($i = $start - 1; $i >= 0; --$i) {
            if ($tokens[$i][0] === \T_WHITESPACE) {
                continue;
            }
            return $tokens[$i];
        }
        return null;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        $keywordToken = $this->getKeywordToken();
        foreach ($tokens as $i => $token) {
            if ($token[0] === $keywordToken) {
                $tokens[$i][0] = \T_STRING;
            }
        }
        return $tokens;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class FnTokenEmulator extends KeywordEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_7_4;
    }
    public function getKeywordString() : string
    {
        return 'fn';
    }
    public function getKeywordToken() : int
    {
        return \T_FN;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class NullsafeTokenEmulator extends TokenEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_8_0;
    }
    public function isEmulationNeeded(string $code) : bool
    {
        return \strpos($code, '?->') !== \false;
    }
    public function emulate(string $code, array $tokens) : array
    {
        // We need to manually iterate and manage a count because we'll change
        // the tokens array on the way
        $line = 1;
        for ($i = 0, $c = \count($tokens); $i < $c; ++$i) {
            if ($tokens[$i] === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1][0] === \T_OBJECT_OPERATOR) {
                \array_splice($tokens, $i, 2, [[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line]]);
                $c--;
                continue;
            }
            // Handle ?-> inside encapsed string.
            if ($tokens[$i][0] === \T_ENCAPSED_AND_WHITESPACE && isset($tokens[$i - 1]) && $tokens[$i - 1][0] === \T_VARIABLE && \preg_match('/^\\?->([a-zA-Z_\\x80-\\xff][a-zA-Z0-9_\\x80-\\xff]*)/', $tokens[$i][1], $matches)) {
                $replacement = [[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line], [\T_STRING, $matches[1], $line]];
                if (\strlen($matches[0]) !== \strlen($tokens[$i][1])) {
                    $replacement[] = [\T_ENCAPSED_AND_WHITESPACE, \substr($tokens[$i][1], \strlen($matches[0])), $line];
                }
                \array_splice($tokens, $i, 1, $replacement);
                $c += \count($replacement) - 1;
                continue;
            }
            if (\is_array($tokens[$i])) {
                $line += \substr_count($tokens[$i][1], "\n");
            }
        }
        return $tokens;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        // ?-> was not valid code previously, don't bother.
        return $tokens;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class EnumTokenEmulator extends KeywordEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_8_1;
    }
    public function getKeywordString() : string
    {
        return 'enum';
    }
    public function getKeywordToken() : int
    {
        return \T_ENUM;
    }
    protected function isKeywordContext(array $tokens, int $pos) : bool
    {
        return parent::isKeywordContext($tokens, $pos) && isset($tokens[$pos + 2]) && $tokens[$pos + 1][0] === \T_WHITESPACE && $tokens[$pos + 2][0] === \T_STRING;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class AttributeEmulator extends TokenEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_8_0;
    }
    public function isEmulationNeeded(string $code) : bool
    {
        return \strpos($code, '#[') !== \false;
    }
    public function emulate(string $code, array $tokens) : array
    {
        // We need to manually iterate and manage a count because we'll change
        // the tokens array on the way.
        $line = 1;
        for ($i = 0, $c = \count($tokens); $i < $c; ++$i) {
            if ($tokens[$i] === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1] === '[') {
                \array_splice($tokens, $i, 2, [[\T_ATTRIBUTE, '#[', $line]]);
                $c--;
                continue;
            }
            if (\is_array($tokens[$i])) {
                $line += \substr_count($tokens[$i][1], "\n");
            }
        }
        return $tokens;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        // TODO
        return $tokens;
    }
    public function preprocessCode(string $code, array &$patches) : string
    {
        $pos = 0;
        while (\false !== ($pos = \strpos($code, '#[', $pos))) {
            // Replace #[ with %[
            $code[$pos] = '%';
            $patches[] = [$pos, 'replace', '#'];
            $pos += 2;
        }
        return $code;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
final class CoaleseEqualTokenEmulator extends TokenEmulator
{
    public function getPhpVersion() : string
    {
        return Emulative::PHP_7_4;
    }
    public function isEmulationNeeded(string $code) : bool
    {
        return \strpos($code, '??=') !== \false;
    }
    public function emulate(string $code, array $tokens) : array
    {
        // We need to manually iterate and manage a count because we'll change
        // the tokens array on the way
        $line = 1;
        for ($i = 0, $c = \count($tokens); $i < $c; ++$i) {
            if (isset($tokens[$i + 1])) {
                if ($tokens[$i][0] === \T_COALESCE && $tokens[$i + 1] === '=') {
                    \array_splice($tokens, $i, 2, [[\T_COALESCE_EQUAL, '??=', $line]]);
                    $c--;
                    continue;
                }
            }
            if (\is_array($tokens[$i])) {
                $line += \substr_count($tokens[$i][1], "\n");
            }
        }
        return $tokens;
    }
    public function reverseEmulate(string $code, array $tokens) : array
    {
        // ??= was not valid code previously, don't bother.
        return $tokens;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Lexer\TokenEmulator;

/** @internal */
abstract class TokenEmulator
{
    public abstract function getPhpVersion() : string;
    public abstract function isEmulationNeeded(string $code) : bool;
    /**
     * @return array Modified Tokens
     */
    public abstract function emulate(string $code, array $tokens) : array;
    /**
     * @return array Modified Tokens
     */
    public abstract function reverseEmulate(string $code, array $tokens) : array;
    public function preprocessCode(string $code, array &$patches) : string
    {
        return $code;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Include_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Class_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\GroupUse;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Use_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\UseUse;
class NodeDumper
{
    private $dumpComments;
    private $dumpPositions;
    private $code;
    /**
     * Constructs a NodeDumper.
     *
     * Supported options:
     *  * bool dumpComments: Whether comments should be dumped.
     *  * bool dumpPositions: Whether line/offset information should be dumped. To dump offset
     *                        information, the code needs to be passed to dump().
     *
     * @param array $options Options (see description)
     */
    public function __construct(array $options = [])
    {
        $this->dumpComments = !empty($options['dumpComments']);
        $this->dumpPositions = !empty($options['dumpPositions']);
    }
    /**
     * Dumps a node or array.
     *
     * @param array|Node  $node Node or array to dump
     * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if
     *                          the dumpPositions option is enabled and the dumping of node offsets
     *                          is desired.
     *
     * @return string Dumped value
     */
    public function dump($node, string $code = null) : string
    {
        $this->code = $code;
        return $this->dumpRecursive($node);
    }
    protected function dumpRecursive($node)
    {
        if ($node instanceof Node) {
            $r = $node->getType();
            if ($this->dumpPositions && null !== ($p = $this->dumpPosition($node))) {
                $r .= $p;
            }
            $r .= '(';
            foreach ($node->getSubNodeNames() as $key) {
                $r .= "\n    " . $key . ': ';
                $value = $node->{$key};
                if (null === $value) {
                    $r .= 'null';
                } elseif (\false === $value) {
                    $r .= 'false';
                } elseif (\true === $value) {
                    $r .= 'true';
                } elseif (\is_scalar($value)) {
                    if ('flags' === $key || 'newModifier' === $key) {
                        $r .= $this->dumpFlags($value);
                    } elseif ('type' === $key && $node instanceof Include_) {
                        $r .= $this->dumpIncludeType($value);
                    } elseif ('type' === $key && ($node instanceof Use_ || $node instanceof UseUse || $node instanceof GroupUse)) {
                        $r .= $this->dumpUseType($value);
                    } else {
                        $r .= $value;
                    }
                } else {
                    $r .= \str_replace("\n", "\n    ", $this->dumpRecursive($value));
                }
            }
            if ($this->dumpComments && ($comments = $node->getComments())) {
                $r .= "\n    comments: " . \str_replace("\n", "\n    ", $this->dumpRecursive($comments));
            }
        } elseif (\is_array($node)) {
            $r = 'array(';
            foreach ($node as $key => $value) {
                $r .= "\n    " . $key . ': ';
                if (null === $value) {
                    $r .= 'null';
                } elseif (\false === $value) {
                    $r .= 'false';
                } elseif (\true === $value) {
                    $r .= 'true';
                } elseif (\is_scalar($value)) {
                    $r .= $value;
                } else {
                    $r .= \str_replace("\n", "\n    ", $this->dumpRecursive($value));
                }
            }
        } elseif ($node instanceof Comment) {
            return $node->getReformattedText();
        } else {
            throw new \InvalidArgumentException('Can only dump nodes and arrays.');
        }
        return $r . "\n)";
    }
    protected function dumpFlags($flags)
    {
        $strs = [];
        if ($flags & Class_::MODIFIER_PUBLIC) {
            $strs[] = 'MODIFIER_PUBLIC';
        }
        if ($flags & Class_::MODIFIER_PROTECTED) {
            $strs[] = 'MODIFIER_PROTECTED';
        }
        if ($flags & Class_::MODIFIER_PRIVATE) {
            $strs[] = 'MODIFIER_PRIVATE';
        }
        if ($flags & Class_::MODIFIER_ABSTRACT) {
            $strs[] = 'MODIFIER_ABSTRACT';
        }
        if ($flags & Class_::MODIFIER_STATIC) {
            $strs[] = 'MODIFIER_STATIC';
        }
        if ($flags & Class_::MODIFIER_FINAL) {
            $strs[] = 'MODIFIER_FINAL';
        }
        if ($flags & Class_::MODIFIER_READONLY) {
            $strs[] = 'MODIFIER_READONLY';
        }
        if ($strs) {
            return \implode(' | ', $strs) . ' (' . $flags . ')';
        } else {
            return $flags;
        }
    }
    protected function dumpIncludeType($type)
    {
        $map = [Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQUIRE_ONCE'];
        if (!isset($map[$type])) {
            return $type;
        }
        return $map[$type] . ' (' . $type . ')';
    }
    protected function dumpUseType($type)
    {
        $map = [Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', Use_::TYPE_NORMAL => 'TYPE_NORMAL', Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', Use_::TYPE_CONSTANT => 'TYPE_CONSTANT'];
        if (!isset($map[$type])) {
            return $type;
        }
        return $map[$type] . ' (' . $type . ')';
    }
    /**
     * Dump node position, if possible.
     *
     * @param Node $node Node for which to dump position
     *
     * @return string|null Dump of position, or null if position information not available
     */
    protected function dumpPosition(Node $node)
    {
        if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) {
            return null;
        }
        $start = $node->getStartLine();
        $end = $node->getEndLine();
        if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') && null !== $this->code) {
            $start .= ':' . $this->toColumn($this->code, $node->getStartFilePos());
            $end .= ':' . $this->toColumn($this->code, $node->getEndFilePos());
        }
        return "[{$start} - {$end}]";
    }
    // Copied from Error class
    private function toColumn($code, $pos)
    {
        if ($pos > \strlen($code)) {
            throw new \RuntimeException('Invalid position information');
        }
        $lineStartPos = \strrpos($code, "\n", $pos - \strlen($code));
        if (\false === $lineStartPos) {
            $lineStartPos = -1;
        }
        return $pos - $lineStartPos;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Concat;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\String_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Use_;
class BuilderFactory
{
    /**
     * Creates an attribute node.
     *
     * @param string|Name $name Name of the attribute
     * @param array       $args Attribute named arguments
     *
     * @return Node\Attribute
     */
    public function attribute($name, array $args = []) : Node\Attribute
    {
        return new Node\Attribute(BuilderHelpers::normalizeName($name), $this->args($args));
    }
    /**
     * Creates a namespace builder.
     *
     * @param null|string|Node\Name $name Name of the namespace
     *
     * @return Builder\Namespace_ The created namespace builder
     */
    public function namespace($name) : Builder\Namespace_
    {
        return new Builder\Namespace_($name);
    }
    /**
     * Creates a class builder.
     *
     * @param string $name Name of the class
     *
     * @return Builder\Class_ The created class builder
     */
    public function class(string $name) : Builder\Class_
    {
        return new Builder\Class_($name);
    }
    /**
     * Creates an interface builder.
     *
     * @param string $name Name of the interface
     *
     * @return Builder\Interface_ The created interface builder
     */
    public function interface(string $name) : Builder\Interface_
    {
        return new Builder\Interface_($name);
    }
    /**
     * Creates a trait builder.
     *
     * @param string $name Name of the trait
     *
     * @return Builder\Trait_ The created trait builder
     */
    public function trait(string $name) : Builder\Trait_
    {
        return new Builder\Trait_($name);
    }
    /**
     * Creates an enum builder.
     *
     * @param string $name Name of the enum
     *
     * @return Builder\Enum_ The created enum builder
     */
    public function enum(string $name) : Builder\Enum_
    {
        return new Builder\Enum_($name);
    }
    /**
     * Creates a trait use builder.
     *
     * @param Node\Name|string ...$traits Trait names
     *
     * @return Builder\TraitUse The create trait use builder
     */
    public function useTrait(...$traits) : Builder\TraitUse
    {
        return new Builder\TraitUse(...$traits);
    }
    /**
     * Creates a trait use adaptation builder.
     *
     * @param Node\Name|string|null  $trait  Trait name
     * @param Node\Identifier|string $method Method name
     *
     * @return Builder\TraitUseAdaptation The create trait use adaptation builder
     */
    public function traitUseAdaptation($trait, $method = null) : Builder\TraitUseAdaptation
    {
        if ($method === null) {
            $method = $trait;
            $trait = null;
        }
        return new Builder\TraitUseAdaptation($trait, $method);
    }
    /**
     * Creates a method builder.
     *
     * @param string $name Name of the method
     *
     * @return Builder\Method The created method builder
     */
    public function method(string $name) : Builder\Method
    {
        return new Builder\Method($name);
    }
    /**
     * Creates a parameter builder.
     *
     * @param string $name Name of the parameter
     *
     * @return Builder\Param The created parameter builder
     */
    public function param(string $name) : Builder\Param
    {
        return new Builder\Param($name);
    }
    /**
     * Creates a property builder.
     *
     * @param string $name Name of the property
     *
     * @return Builder\Property The created property builder
     */
    public function property(string $name) : Builder\Property
    {
        return new Builder\Property($name);
    }
    /**
     * Creates a function builder.
     *
     * @param string $name Name of the function
     *
     * @return Builder\Function_ The created function builder
     */
    public function function(string $name) : Builder\Function_
    {
        return new Builder\Function_($name);
    }
    /**
     * Creates a namespace/class use builder.
     *
     * @param Node\Name|string $name Name of the entity (namespace or class) to alias
     *
     * @return Builder\Use_ The created use builder
     */
    public function use($name) : Builder\Use_
    {
        return new Builder\Use_($name, Use_::TYPE_NORMAL);
    }
    /**
     * Creates a function use builder.
     *
     * @param Node\Name|string $name Name of the function to alias
     *
     * @return Builder\Use_ The created use function builder
     */
    public function useFunction($name) : Builder\Use_
    {
        return new Builder\Use_($name, Use_::TYPE_FUNCTION);
    }
    /**
     * Creates a constant use builder.
     *
     * @param Node\Name|string $name Name of the const to alias
     *
     * @return Builder\Use_ The created use const builder
     */
    public function useConst($name) : Builder\Use_
    {
        return new Builder\Use_($name, Use_::TYPE_CONSTANT);
    }
    /**
     * Creates a class constant builder.
     *
     * @param string|Identifier                          $name  Name
     * @param Node\Expr|bool|null|int|float|string|array $value Value
     *
     * @return Builder\ClassConst The created use const builder
     */
    public function classConst($name, $value) : Builder\ClassConst
    {
        return new Builder\ClassConst($name, $value);
    }
    /**
     * Creates an enum case builder.
     *
     * @param string|Identifier $name  Name
     *
     * @return Builder\EnumCase The created use const builder
     */
    public function enumCase($name) : Builder\EnumCase
    {
        return new Builder\EnumCase($name);
    }
    /**
     * Creates node a for a literal value.
     *
     * @param Expr|bool|null|int|float|string|array $value $value
     *
     * @return Expr
     */
    public function val($value) : Expr
    {
        return BuilderHelpers::normalizeValue($value);
    }
    /**
     * Creates variable node.
     *
     * @param string|Expr $name Name
     *
     * @return Expr\Variable
     */
    public function var($name) : Expr\Variable
    {
        if (!\is_string($name) && !$name instanceof Expr) {
            throw new \LogicException('Variable name must be string or Expr');
        }
        return new Expr\Variable($name);
    }
    /**
     * Normalizes an argument list.
     *
     * Creates Arg nodes for all arguments and converts literal values to expressions.
     *
     * @param array $args List of arguments to normalize
     *
     * @return Arg[]
     */
    public function args(array $args) : array
    {
        $normalizedArgs = [];
        foreach ($args as $key => $arg) {
            if (!$arg instanceof Arg) {
                $arg = new Arg(BuilderHelpers::normalizeValue($arg));
            }
            if (\is_string($key)) {
                $arg->name = BuilderHelpers::normalizeIdentifier($key);
            }
            $normalizedArgs[] = $arg;
        }
        return $normalizedArgs;
    }
    /**
     * Creates a function call node.
     *
     * @param string|Name|Expr $name Function name
     * @param array            $args Function arguments
     *
     * @return Expr\FuncCall
     */
    public function funcCall($name, array $args = []) : Expr\FuncCall
    {
        return new Expr\FuncCall(BuilderHelpers::normalizeNameOrExpr($name), $this->args($args));
    }
    /**
     * Creates a method call node.
     *
     * @param Expr                   $var  Variable the method is called on
     * @param string|Identifier|Expr $name Method name
     * @param array                  $args Method arguments
     *
     * @return Expr\MethodCall
     */
    public function methodCall(Expr $var, $name, array $args = []) : Expr\MethodCall
    {
        return new Expr\MethodCall($var, BuilderHelpers::normalizeIdentifierOrExpr($name), $this->args($args));
    }
    /**
     * Creates a static method call node.
     *
     * @param string|Name|Expr       $class Class name
     * @param string|Identifier|Expr $name  Method name
     * @param array                  $args  Method arguments
     *
     * @return Expr\StaticCall
     */
    public function staticCall($class, $name, array $args = []) : Expr\StaticCall
    {
        return new Expr\StaticCall(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifierOrExpr($name), $this->args($args));
    }
    /**
     * Creates an object creation node.
     *
     * @param string|Name|Expr $class Class name
     * @param array            $args  Constructor arguments
     *
     * @return Expr\New_
     */
    public function new($class, array $args = []) : Expr\New_
    {
        return new Expr\New_(BuilderHelpers::normalizeNameOrExpr($class), $this->args($args));
    }
    /**
     * Creates a constant fetch node.
     *
     * @param string|Name $name Constant name
     *
     * @return Expr\ConstFetch
     */
    public function constFetch($name) : Expr\ConstFetch
    {
        return new Expr\ConstFetch(BuilderHelpers::normalizeName($name));
    }
    /**
     * Creates a property fetch node.
     *
     * @param Expr                   $var  Variable holding object
     * @param string|Identifier|Expr $name Property name
     *
     * @return Expr\PropertyFetch
     */
    public function propertyFetch(Expr $var, $name) : Expr\PropertyFetch
    {
        return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name));
    }
    /**
     * Creates a class constant fetch node.
     *
     * @param string|Name|Expr  $class Class name
     * @param string|Identifier $name  Constant name
     *
     * @return Expr\ClassConstFetch
     */
    public function classConstFetch($class, $name) : Expr\ClassConstFetch
    {
        return new Expr\ClassConstFetch(BuilderHelpers::normalizeNameOrExpr($class), BuilderHelpers::normalizeIdentifier($name));
    }
    /**
     * Creates nested Concat nodes from a list of expressions.
     *
     * @param Expr|string ...$exprs Expressions or literal strings
     *
     * @return Concat
     */
    public function concat(...$exprs) : Concat
    {
        $numExprs = \count($exprs);
        if ($numExprs < 2) {
            throw new \LogicException('Expected at least two expressions');
        }
        $lastConcat = $this->normalizeStringExpr($exprs[0]);
        for ($i = 1; $i < $numExprs; $i++) {
            $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i]));
        }
        return $lastConcat;
    }
    /**
     * @param string|Expr $expr
     * @return Expr
     */
    private function normalizeStringExpr($expr) : Expr
    {
        if ($expr instanceof Expr) {
            return $expr;
        }
        if (\is_string($expr)) {
            return new String_($expr);
        }
        throw new \LogicException('Expected string or Expr');
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Class_ extends Declaration
{
    protected $name;
    protected $extends = null;
    protected $implements = [];
    protected $flags = 0;
    protected $uses = [];
    protected $constants = [];
    protected $properties = [];
    protected $methods = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates a class builder.
     *
     * @param string $name Name of the class
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Extends a class.
     *
     * @param Name|string $class Name of class to extend
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function extend($class)
    {
        $this->extends = BuilderHelpers::normalizeName($class);
        return $this;
    }
    /**
     * Implements one or more interfaces.
     *
     * @param Name|string ...$interfaces Names of interfaces to implement
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function implement(...$interfaces)
    {
        foreach ($interfaces as $interface) {
            $this->implements[] = BuilderHelpers::normalizeName($interface);
        }
        return $this;
    }
    /**
     * Makes the class abstract.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeAbstract()
    {
        $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT);
        return $this;
    }
    /**
     * Makes the class final.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeFinal()
    {
        $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_FINAL);
        return $this;
    }
    public function makeReadonly()
    {
        $this->flags = BuilderHelpers::addClassModifier($this->flags, Stmt\Class_::MODIFIER_READONLY);
        return $this;
    }
    /**
     * Adds a statement.
     *
     * @param Stmt|PhpParser\Builder $stmt The statement to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmt($stmt)
    {
        $stmt = BuilderHelpers::normalizeNode($stmt);
        $targets = [Stmt\TraitUse::class => &$this->uses, Stmt\ClassConst::class => &$this->constants, Stmt\Property::class => &$this->properties, Stmt\ClassMethod::class => &$this->methods];
        $class = \get_class($stmt);
        if (!isset($targets[$class])) {
            throw new \LogicException(\sprintf('Unexpected node of type "%s"', $stmt->getType()));
        }
        $targets[$class][] = $stmt;
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built class node.
     *
     * @return Stmt\Class_ The built class node
     */
    public function getNode() : PhpParser\Node
    {
        return new Stmt\Class_($this->name, ['flags' => $this->flags, 'extends' => $this->extends, 'implements' => $this->implements, 'stmts' => \array_merge($this->uses, $this->constants, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Trait_ extends Declaration
{
    protected $name;
    protected $uses = [];
    protected $properties = [];
    protected $methods = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates an interface builder.
     *
     * @param string $name Name of the interface
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Adds a statement.
     *
     * @param Stmt|PhpParser\Builder $stmt The statement to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmt($stmt)
    {
        $stmt = BuilderHelpers::normalizeNode($stmt);
        if ($stmt instanceof Stmt\Property) {
            $this->properties[] = $stmt;
        } elseif ($stmt instanceof Stmt\ClassMethod) {
            $this->methods[] = $stmt;
        } elseif ($stmt instanceof Stmt\TraitUse) {
            $this->uses[] = $stmt;
        } else {
            throw new \LogicException(\sprintf('Unexpected node of type "%s"', $stmt->getType()));
        }
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built trait node.
     *
     * @return Stmt\Trait_ The built interface node
     */
    public function getNode() : PhpParser\Node
    {
        return new Stmt\Trait_($this->name, ['stmts' => \array_merge($this->uses, $this->properties, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser\Builder;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Use_ implements Builder
{
    protected $name;
    protected $type;
    protected $alias = null;
    /**
     * Creates a name use (alias) builder.
     *
     * @param Node\Name|string $name Name of the entity (namespace, class, function, constant) to alias
     * @param int              $type One of the Stmt\Use_::TYPE_* constants
     */
    public function __construct($name, int $type)
    {
        $this->name = BuilderHelpers::normalizeName($name);
        $this->type = $type;
    }
    /**
     * Sets alias for used name.
     *
     * @param string $alias Alias to use (last component of full name by default)
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function as(string $alias)
    {
        $this->alias = $alias;
        return $this;
    }
    /**
     * Returns the built node.
     *
     * @return Stmt\Use_ The built node
     */
    public function getNode() : Node
    {
        return new Stmt\Use_([new Stmt\UseUse($this->name, $this->alias)], $this->type);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class EnumCase implements PhpParser\Builder
{
    protected $name;
    protected $value = null;
    protected $attributes = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates an enum case builder.
     *
     * @param string|Identifier $name  Name
     */
    public function __construct($name)
    {
        $this->name = $name;
    }
    /**
     * Sets the value.
     *
     * @param Node\Expr|string|int $value
     *
     * @return $this
     */
    public function setValue($value)
    {
        $this->value = BuilderHelpers::normalizeValue($value);
        return $this;
    }
    /**
     * Sets doc comment for the constant.
     *
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setDocComment($docComment)
    {
        $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built enum case node.
     *
     * @return Stmt\EnumCase The built constant node
     */
    public function getNode() : PhpParser\Node
    {
        return new Stmt\EnumCase($this->name, $this->value, $this->attributeGroups, $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Interface_ extends Declaration
{
    protected $name;
    protected $extends = [];
    protected $constants = [];
    protected $methods = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates an interface builder.
     *
     * @param string $name Name of the interface
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Extends one or more interfaces.
     *
     * @param Name|string ...$interfaces Names of interfaces to extend
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function extend(...$interfaces)
    {
        foreach ($interfaces as $interface) {
            $this->extends[] = BuilderHelpers::normalizeName($interface);
        }
        return $this;
    }
    /**
     * Adds a statement.
     *
     * @param Stmt|PhpParser\Builder $stmt The statement to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmt($stmt)
    {
        $stmt = BuilderHelpers::normalizeNode($stmt);
        if ($stmt instanceof Stmt\ClassConst) {
            $this->constants[] = $stmt;
        } elseif ($stmt instanceof Stmt\ClassMethod) {
            // we erase all statements in the body of an interface method
            $stmt->stmts = null;
            $this->methods[] = $stmt;
        } else {
            throw new \LogicException(\sprintf('Unexpected node of type "%s"', $stmt->getType()));
        }
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built interface node.
     *
     * @return Stmt\Interface_ The built interface node
     */
    public function getNode() : PhpParser\Node
    {
        return new Stmt\Interface_($this->name, ['extends' => $this->extends, 'stmts' => \array_merge($this->constants, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser\Builder;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class TraitUse implements Builder
{
    protected $traits = [];
    protected $adaptations = [];
    /**
     * Creates a trait use builder.
     *
     * @param Node\Name|string ...$traits Names of used traits
     */
    public function __construct(...$traits)
    {
        foreach ($traits as $trait) {
            $this->and($trait);
        }
    }
    /**
     * Adds used trait.
     *
     * @param Node\Name|string $trait Trait name
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function and($trait)
    {
        $this->traits[] = BuilderHelpers::normalizeName($trait);
        return $this;
    }
    /**
     * Adds trait adaptation.
     *
     * @param Stmt\TraitUseAdaptation|Builder\TraitUseAdaptation $adaptation Trait adaptation
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function with($adaptation)
    {
        $adaptation = BuilderHelpers::normalizeNode($adaptation);
        if (!$adaptation instanceof Stmt\TraitUseAdaptation) {
            throw new \LogicException('Adaptation must have type TraitUseAdaptation');
        }
        $this->adaptations[] = $adaptation;
        return $this;
    }
    /**
     * Returns the built node.
     *
     * @return Node The built node
     */
    public function getNode() : Node
    {
        return new Stmt\TraitUse($this->traits, $this->adaptations);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Param implements PhpParser\Builder
{
    protected $name;
    protected $default = null;
    /** @var Node\Identifier|Node\Name|Node\NullableType|null */
    protected $type = null;
    protected $byRef = \false;
    protected $variadic = \false;
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates a parameter builder.
     *
     * @param string $name Name of the parameter
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Sets default value for the parameter.
     *
     * @param mixed $value Default value to use
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setDefault($value)
    {
        $this->default = BuilderHelpers::normalizeValue($value);
        return $this;
    }
    /**
     * Sets type for the parameter.
     *
     * @param string|Node\Name|Node\Identifier|Node\ComplexType $type Parameter type
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setType($type)
    {
        $this->type = BuilderHelpers::normalizeType($type);
        if ($this->type == 'void') {
            throw new \LogicException('Parameter type cannot be void');
        }
        return $this;
    }
    /**
     * Sets type for the parameter.
     *
     * @param string|Node\Name|Node\Identifier|Node\ComplexType $type Parameter type
     *
     * @return $this The builder instance (for fluid interface)
     *
     * @deprecated Use setType() instead
     */
    public function setTypeHint($type)
    {
        return $this->setType($type);
    }
    /**
     * Make the parameter accept the value by reference.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeByRef()
    {
        $this->byRef = \true;
        return $this;
    }
    /**
     * Make the parameter variadic
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeVariadic()
    {
        $this->variadic = \true;
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built parameter node.
     *
     * @return Node\Param The built parameter node
     */
    public function getNode() : Node
    {
        return new Node\Param(new Node\Expr\Variable($this->name), $this->default, $this->type, $this->byRef, $this->variadic, [], 0, $this->attributeGroups);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Function_ extends FunctionLike
{
    protected $name;
    protected $stmts = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates a function builder.
     *
     * @param string $name Name of the function
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Adds a statement.
     *
     * @param Node|PhpParser\Builder $stmt The statement to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmt($stmt)
    {
        $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built function node.
     *
     * @return Stmt\Function_ The built function node
     */
    public function getNode() : Node
    {
        return new Stmt\Function_($this->name, ['byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, 'attrGroups' => $this->attributeGroups], $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Method extends FunctionLike
{
    protected $name;
    protected $flags = 0;
    /** @var array|null */
    protected $stmts = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates a method builder.
     *
     * @param string $name Name of the method
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Makes the method public.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePublic()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC);
        return $this;
    }
    /**
     * Makes the method protected.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeProtected()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED);
        return $this;
    }
    /**
     * Makes the method private.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePrivate()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE);
        return $this;
    }
    /**
     * Makes the method static.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeStatic()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC);
        return $this;
    }
    /**
     * Makes the method abstract.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeAbstract()
    {
        if (!empty($this->stmts)) {
            throw new \LogicException('Cannot make method with statements abstract');
        }
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT);
        $this->stmts = null;
        // abstract methods don't have statements
        return $this;
    }
    /**
     * Makes the method final.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeFinal()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL);
        return $this;
    }
    /**
     * Adds a statement.
     *
     * @param Node|PhpParser\Builder $stmt The statement to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmt($stmt)
    {
        if (null === $this->stmts) {
            throw new \LogicException('Cannot add statements to an abstract method');
        }
        $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built method node.
     *
     * @return Stmt\ClassMethod The built method node
     */
    public function getNode() : Node
    {
        return new Stmt\ClassMethod($this->name, ['flags' => $this->flags, 'byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, 'attrGroups' => $this->attributeGroups], $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\ComplexType;
class Property implements PhpParser\Builder
{
    protected $name;
    protected $flags = 0;
    protected $default = null;
    protected $attributes = [];
    /** @var null|Identifier|Name|NullableType */
    protected $type;
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates a property builder.
     *
     * @param string $name Name of the property
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Makes the property public.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePublic()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC);
        return $this;
    }
    /**
     * Makes the property protected.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeProtected()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED);
        return $this;
    }
    /**
     * Makes the property private.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePrivate()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE);
        return $this;
    }
    /**
     * Makes the property static.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeStatic()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC);
        return $this;
    }
    /**
     * Makes the property readonly.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeReadonly()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_READONLY);
        return $this;
    }
    /**
     * Sets default value for the property.
     *
     * @param mixed $value Default value to use
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setDefault($value)
    {
        $this->default = BuilderHelpers::normalizeValue($value);
        return $this;
    }
    /**
     * Sets doc comment for the property.
     *
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setDocComment($docComment)
    {
        $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
        return $this;
    }
    /**
     * Sets the property type for PHP 7.4+.
     *
     * @param string|Name|Identifier|ComplexType $type
     *
     * @return $this
     */
    public function setType($type)
    {
        $this->type = BuilderHelpers::normalizeType($type);
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built class node.
     *
     * @return Stmt\Property The built property node
     */
    public function getNode() : PhpParser\Node
    {
        return new Stmt\Property($this->flags !== 0 ? $this->flags : Stmt\Class_::MODIFIER_PUBLIC, [new Stmt\PropertyProperty($this->name, $this->default)], $this->attributes, $this->type, $this->attributeGroups);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Enum_ extends Declaration
{
    protected $name;
    protected $scalarType = null;
    protected $implements = [];
    protected $uses = [];
    protected $enumCases = [];
    protected $constants = [];
    protected $methods = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates an enum builder.
     *
     * @param string $name Name of the enum
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * Sets the scalar type.
     *
     * @param string|Identifier $type
     *
     * @return $this
     */
    public function setScalarType($scalarType)
    {
        $this->scalarType = BuilderHelpers::normalizeType($scalarType);
        return $this;
    }
    /**
     * Implements one or more interfaces.
     *
     * @param Name|string ...$interfaces Names of interfaces to implement
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function implement(...$interfaces)
    {
        foreach ($interfaces as $interface) {
            $this->implements[] = BuilderHelpers::normalizeName($interface);
        }
        return $this;
    }
    /**
     * Adds a statement.
     *
     * @param Stmt|PhpParser\Builder $stmt The statement to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmt($stmt)
    {
        $stmt = BuilderHelpers::normalizeNode($stmt);
        $targets = [Stmt\TraitUse::class => &$this->uses, Stmt\EnumCase::class => &$this->enumCases, Stmt\ClassConst::class => &$this->constants, Stmt\ClassMethod::class => &$this->methods];
        $class = \get_class($stmt);
        if (!isset($targets[$class])) {
            throw new \LogicException(\sprintf('Unexpected node of type "%s"', $stmt->getType()));
        }
        $targets[$class][] = $stmt;
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built class node.
     *
     * @return Stmt\Enum_ The built enum node
     */
    public function getNode() : PhpParser\Node
    {
        return new Stmt\Enum_($this->name, ['scalarType' => $this->scalarType, 'implements' => $this->implements, 'stmts' => \array_merge($this->uses, $this->enumCases, $this->constants, $this->methods), 'attrGroups' => $this->attributeGroups], $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
abstract class FunctionLike extends Declaration
{
    protected $returnByRef = \false;
    protected $params = [];
    /** @var string|Node\Name|Node\NullableType|null */
    protected $returnType = null;
    /**
     * Make the function return by reference.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeReturnByRef()
    {
        $this->returnByRef = \true;
        return $this;
    }
    /**
     * Adds a parameter.
     *
     * @param Node\Param|Param $param The parameter to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addParam($param)
    {
        $param = BuilderHelpers::normalizeNode($param);
        if (!$param instanceof Node\Param) {
            throw new \LogicException(\sprintf('Expected parameter node, got "%s"', $param->getType()));
        }
        $this->params[] = $param;
        return $this;
    }
    /**
     * Adds multiple parameters.
     *
     * @param array $params The parameters to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addParams(array $params)
    {
        foreach ($params as $param) {
            $this->addParam($param);
        }
        return $this;
    }
    /**
     * Sets the return type for PHP 7.
     *
     * @param string|Node\Name|Node\Identifier|Node\ComplexType $type
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setReturnType($type)
    {
        $this->returnType = BuilderHelpers::normalizeType($type);
        return $this;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Namespace_ extends Declaration
{
    private $name;
    private $stmts = [];
    /**
     * Creates a namespace builder.
     *
     * @param Node\Name|string|null $name Name of the namespace
     */
    public function __construct($name)
    {
        $this->name = null !== $name ? BuilderHelpers::normalizeName($name) : null;
    }
    /**
     * Adds a statement.
     *
     * @param Node|PhpParser\Builder $stmt The statement to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmt($stmt)
    {
        $this->stmts[] = BuilderHelpers::normalizeStmt($stmt);
        return $this;
    }
    /**
     * Returns the built node.
     *
     * @return Stmt\Namespace_ The built node
     */
    public function getNode() : Node
    {
        return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser\Builder;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class TraitUseAdaptation implements Builder
{
    const TYPE_UNDEFINED = 0;
    const TYPE_ALIAS = 1;
    const TYPE_PRECEDENCE = 2;
    /** @var int Type of building adaptation */
    protected $type;
    protected $trait;
    protected $method;
    protected $modifier = null;
    protected $alias = null;
    protected $insteadof = [];
    /**
     * Creates a trait use adaptation builder.
     *
     * @param Node\Name|string|null  $trait  Name of adaptated trait
     * @param Node\Identifier|string $method Name of adaptated method
     */
    public function __construct($trait, $method)
    {
        $this->type = self::TYPE_UNDEFINED;
        $this->trait = \is_null($trait) ? null : BuilderHelpers::normalizeName($trait);
        $this->method = BuilderHelpers::normalizeIdentifier($method);
    }
    /**
     * Sets alias of method.
     *
     * @param Node\Identifier|string $alias Alias for adaptated method
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function as($alias)
    {
        if ($this->type === self::TYPE_UNDEFINED) {
            $this->type = self::TYPE_ALIAS;
        }
        if ($this->type !== self::TYPE_ALIAS) {
            throw new \LogicException('Cannot set alias for not alias adaptation buider');
        }
        $this->alias = $alias;
        return $this;
    }
    /**
     * Sets adaptated method public.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePublic()
    {
        $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC);
        return $this;
    }
    /**
     * Sets adaptated method protected.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeProtected()
    {
        $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED);
        return $this;
    }
    /**
     * Sets adaptated method private.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePrivate()
    {
        $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE);
        return $this;
    }
    /**
     * Adds overwritten traits.
     *
     * @param Node\Name|string ...$traits Traits for overwrite
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function insteadof(...$traits)
    {
        if ($this->type === self::TYPE_UNDEFINED) {
            if (\is_null($this->trait)) {
                throw new \LogicException('Precedence adaptation must have trait');
            }
            $this->type = self::TYPE_PRECEDENCE;
        }
        if ($this->type !== self::TYPE_PRECEDENCE) {
            throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider');
        }
        foreach ($traits as $trait) {
            $this->insteadof[] = BuilderHelpers::normalizeName($trait);
        }
        return $this;
    }
    protected function setModifier(int $modifier)
    {
        if ($this->type === self::TYPE_UNDEFINED) {
            $this->type = self::TYPE_ALIAS;
        }
        if ($this->type !== self::TYPE_ALIAS) {
            throw new \LogicException('Cannot set access modifier for not alias adaptation buider');
        }
        if (\is_null($this->modifier)) {
            $this->modifier = $modifier;
        } else {
            throw new \LogicException('Multiple access type modifiers are not allowed');
        }
    }
    /**
     * Returns the built node.
     *
     * @return Node The built node
     */
    public function getNode() : Node
    {
        switch ($this->type) {
            case self::TYPE_ALIAS:
                return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias);
            case self::TYPE_PRECEDENCE:
                return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof);
            default:
                throw new \LogicException('Type of adaptation is not defined');
        }
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
abstract class Declaration implements PhpParser\Builder
{
    protected $attributes = [];
    public abstract function addStmt($stmt);
    /**
     * Adds multiple statements.
     *
     * @param array $stmts The statements to add
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addStmts(array $stmts)
    {
        foreach ($stmts as $stmt) {
            $this->addStmt($stmt);
        }
        return $this;
    }
    /**
     * Sets doc comment for the declaration.
     *
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setDocComment($docComment)
    {
        $this->attributes['comments'] = [BuilderHelpers::normalizeDocComment($docComment)];
        return $this;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Builder;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderHelpers;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Const_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class ClassConst implements PhpParser\Builder
{
    protected $flags = 0;
    protected $attributes = [];
    protected $constants = [];
    /** @var Node\AttributeGroup[] */
    protected $attributeGroups = [];
    /**
     * Creates a class constant builder
     *
     * @param string|Identifier                          $name  Name
     * @param Node\Expr|bool|null|int|float|string|array $value Value
     */
    public function __construct($name, $value)
    {
        $this->constants = [new Const_($name, BuilderHelpers::normalizeValue($value))];
    }
    /**
     * Add another constant to const group
     *
     * @param string|Identifier                          $name  Name
     * @param Node\Expr|bool|null|int|float|string|array $value Value
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addConst($name, $value)
    {
        $this->constants[] = new Const_($name, BuilderHelpers::normalizeValue($value));
        return $this;
    }
    /**
     * Makes the constant public.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePublic()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC);
        return $this;
    }
    /**
     * Makes the constant protected.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeProtected()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED);
        return $this;
    }
    /**
     * Makes the constant private.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makePrivate()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE);
        return $this;
    }
    /**
     * Makes the constant final.
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function makeFinal()
    {
        $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL);
        return $this;
    }
    /**
     * Sets doc comment for the constant.
     *
     * @param PhpParser\Comment\Doc|string $docComment Doc comment to set
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function setDocComment($docComment)
    {
        $this->attributes = ['comments' => [BuilderHelpers::normalizeDocComment($docComment)]];
        return $this;
    }
    /**
     * Adds an attribute group.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return $this The builder instance (for fluid interface)
     */
    public function addAttribute($attribute)
    {
        $this->attributeGroups[] = BuilderHelpers::normalizeAttribute($attribute);
        return $this;
    }
    /**
     * Returns the built class node.
     *
     * @return Stmt\ClassConst The built constant node
     */
    public function getNode() : PhpParser\Node
    {
        return new Stmt\ClassConst($this->constants, $this->flags, $this->attributes, $this->attributeGroups);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\ComplexType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\NullableType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
/**
 * This class defines helpers used in the implementation of builders. Don't use it directly.
 *
 * @internal
 */
final class BuilderHelpers
{
    /**
     * Normalizes a node: Converts builder objects to nodes.
     *
     * @param Node|Builder $node The node to normalize
     *
     * @return Node The normalized node
     */
    public static function normalizeNode($node) : Node
    {
        if ($node instanceof Builder) {
            return $node->getNode();
        }
        if ($node instanceof Node) {
            return $node;
        }
        throw new \LogicException('Expected node or builder object');
    }
    /**
     * Normalizes a node to a statement.
     *
     * Expressions are wrapped in a Stmt\Expression node.
     *
     * @param Node|Builder $node The node to normalize
     *
     * @return Stmt The normalized statement node
     */
    public static function normalizeStmt($node) : Stmt
    {
        $node = self::normalizeNode($node);
        if ($node instanceof Stmt) {
            return $node;
        }
        if ($node instanceof Expr) {
            return new Stmt\Expression($node);
        }
        throw new \LogicException('Expected statement or expression node');
    }
    /**
     * Normalizes strings to Identifier.
     *
     * @param string|Identifier $name The identifier to normalize
     *
     * @return Identifier The normalized identifier
     */
    public static function normalizeIdentifier($name) : Identifier
    {
        if ($name instanceof Identifier) {
            return $name;
        }
        if (\is_string($name)) {
            return new Identifier($name);
        }
        throw new \LogicException('_HumbugBox1cb33d1f20f1\\Expected string or instance of Node\\Identifier');
    }
    /**
     * Normalizes strings to Identifier, also allowing expressions.
     *
     * @param string|Identifier|Expr $name The identifier to normalize
     *
     * @return Identifier|Expr The normalized identifier or expression
     */
    public static function normalizeIdentifierOrExpr($name)
    {
        if ($name instanceof Identifier || $name instanceof Expr) {
            return $name;
        }
        if (\is_string($name)) {
            return new Identifier($name);
        }
        throw new \LogicException('_HumbugBox1cb33d1f20f1\\Expected string or instance of Node\\Identifier or Node\\Expr');
    }
    /**
     * Normalizes a name: Converts string names to Name nodes.
     *
     * @param Name|string $name The name to normalize
     *
     * @return Name The normalized name
     */
    public static function normalizeName($name) : Name
    {
        if ($name instanceof Name) {
            return $name;
        }
        if (\is_string($name)) {
            if (!$name) {
                throw new \LogicException('Name cannot be empty');
            }
            if ($name[0] === '\\') {
                return new Name\FullyQualified(\substr($name, 1));
            }
            if (0 === \strpos($name, 'namespace\\')) {
                return new Name\Relative(\substr($name, \strlen('namespace\\')));
            }
            return new Name($name);
        }
        throw new \LogicException('_HumbugBox1cb33d1f20f1\\Name must be a string or an instance of Node\\Name');
    }
    /**
     * Normalizes a name: Converts string names to Name nodes, while also allowing expressions.
     *
     * @param Expr|Name|string $name The name to normalize
     *
     * @return Name|Expr The normalized name or expression
     */
    public static function normalizeNameOrExpr($name)
    {
        if ($name instanceof Expr) {
            return $name;
        }
        if (!\is_string($name) && !$name instanceof Name) {
            throw new \LogicException('_HumbugBox1cb33d1f20f1\\Name must be a string or an instance of Node\\Name or Node\\Expr');
        }
        return self::normalizeName($name);
    }
    /**
     * Normalizes a type: Converts plain-text type names into proper AST representation.
     *
     * In particular, builtin types become Identifiers, custom types become Names and nullables
     * are wrapped in NullableType nodes.
     *
     * @param string|Name|Identifier|ComplexType $type The type to normalize
     *
     * @return Name|Identifier|ComplexType The normalized type
     */
    public static function normalizeType($type)
    {
        if (!\is_string($type)) {
            if (!$type instanceof Name && !$type instanceof Identifier && !$type instanceof ComplexType) {
                throw new \LogicException('Type must be a string, or an instance of Name, Identifier or ComplexType');
            }
            return $type;
        }
        $nullable = \false;
        if (\strlen($type) > 0 && $type[0] === '?') {
            $nullable = \true;
            $type = \substr($type, 1);
        }
        $builtinTypes = ['array', 'callable', 'bool', 'int', 'float', 'string', 'iterable', 'void', 'object', 'null', 'false', 'mixed', 'never', 'true'];
        $lowerType = \strtolower($type);
        if (\in_array($lowerType, $builtinTypes)) {
            $type = new Identifier($lowerType);
        } else {
            $type = self::normalizeName($type);
        }
        $notNullableTypes = ['void', 'mixed', 'never'];
        if ($nullable && \in_array((string) $type, $notNullableTypes)) {
            throw new \LogicException(\sprintf('%s type cannot be nullable', $type));
        }
        return $nullable ? new NullableType($type) : $type;
    }
    /**
     * Normalizes a value: Converts nulls, booleans, integers,
     * floats, strings and arrays into their respective nodes
     *
     * @param Node\Expr|bool|null|int|float|string|array $value The value to normalize
     *
     * @return Expr The normalized value
     */
    public static function normalizeValue($value) : Expr
    {
        if ($value instanceof Node\Expr) {
            return $value;
        }
        if (\is_null($value)) {
            return new Expr\ConstFetch(new Name('null'));
        }
        if (\is_bool($value)) {
            return new Expr\ConstFetch(new Name($value ? 'true' : 'false'));
        }
        if (\is_int($value)) {
            return new Scalar\LNumber($value);
        }
        if (\is_float($value)) {
            return new Scalar\DNumber($value);
        }
        if (\is_string($value)) {
            return new Scalar\String_($value);
        }
        if (\is_array($value)) {
            $items = [];
            $lastKey = -1;
            foreach ($value as $itemKey => $itemValue) {
                // for consecutive, numeric keys don't generate keys
                if (null !== $lastKey && ++$lastKey === $itemKey) {
                    $items[] = new Expr\ArrayItem(self::normalizeValue($itemValue));
                } else {
                    $lastKey = null;
                    $items[] = new Expr\ArrayItem(self::normalizeValue($itemValue), self::normalizeValue($itemKey));
                }
            }
            return new Expr\Array_($items);
        }
        throw new \LogicException('Invalid value');
    }
    /**
     * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc.
     *
     * @param Comment\Doc|string $docComment The doc comment to normalize
     *
     * @return Comment\Doc The normalized doc comment
     */
    public static function normalizeDocComment($docComment) : Comment\Doc
    {
        if ($docComment instanceof Comment\Doc) {
            return $docComment;
        }
        if (\is_string($docComment)) {
            return new Comment\Doc($docComment);
        }
        throw new \LogicException('_HumbugBox1cb33d1f20f1\\Doc comment must be a string or an instance of PhpParser\\Comment\\Doc');
    }
    /**
     * Normalizes a attribute: Converts attribute to the Attribute Group if needed.
     *
     * @param Node\Attribute|Node\AttributeGroup $attribute
     *
     * @return Node\AttributeGroup The Attribute Group
     */
    public static function normalizeAttribute($attribute) : Node\AttributeGroup
    {
        if ($attribute instanceof Node\AttributeGroup) {
            return $attribute;
        }
        if (!$attribute instanceof Node\Attribute) {
            throw new \LogicException('_HumbugBox1cb33d1f20f1\\Attribute must be an instance of PhpParser\\Node\\Attribute or PhpParser\\Node\\AttributeGroup');
        }
        return new Node\AttributeGroup([$attribute]);
    }
    /**
     * Adds a modifier and returns new modifier bitmask.
     *
     * @param int $modifiers Existing modifiers
     * @param int $modifier  Modifier to set
     *
     * @return int New modifiers
     */
    public static function addModifier(int $modifiers, int $modifier) : int
    {
        Stmt\Class_::verifyModifier($modifiers, $modifier);
        return $modifiers | $modifier;
    }
    /**
     * Adds a modifier and returns new modifier bitmask.
     * @return int New modifiers
     */
    public static function addClassModifier(int $existingModifiers, int $modifierToSet) : int
    {
        Stmt\Class_::verifyClassModifier($existingModifiers, $modifierToSet);
        return $existingModifiers | $modifierToSet;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

/*
 * This parser is based on a skeleton written by Moriyoshi Koizumi, which in
 * turn is based on work by Masato Bito.
 */
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\Double;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Param;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\Encapsed;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\LNumber;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\String_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Class_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassConst;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Enum_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Interface_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Namespace_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Property;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\TryCatch;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\UseUse;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\VarLikeIdentifier;
abstract class ParserAbstract implements Parser
{
    const SYMBOL_NONE = -1;
    /*
     * The following members will be filled with generated parsing data:
     */
    /** @var int Size of $tokenToSymbol map */
    protected $tokenToSymbolMapSize;
    /** @var int Size of $action table */
    protected $actionTableSize;
    /** @var int Size of $goto table */
    protected $gotoTableSize;
    /** @var int Symbol number signifying an invalid token */
    protected $invalidSymbol;
    /** @var int Symbol number of error recovery token */
    protected $errorSymbol;
    /** @var int Action number signifying default action */
    protected $defaultAction;
    /** @var int Rule number signifying that an unexpected token was encountered */
    protected $unexpectedTokenRule;
    protected $YY2TBLSTATE;
    /** @var int Number of non-leaf states */
    protected $numNonLeafStates;
    /** @var int[] Map of lexer tokens to internal symbols */
    protected $tokenToSymbol;
    /** @var string[] Map of symbols to their names */
    protected $symbolToName;
    /** @var array Names of the production rules (only necessary for debugging) */
    protected $productions;
    /** @var int[] Map of states to a displacement into the $action table. The corresponding action for this
     *             state/symbol pair is $action[$actionBase[$state] + $symbol]. If $actionBase[$state] is 0, the
     *             action is defaulted, i.e. $actionDefault[$state] should be used instead. */
    protected $actionBase;
    /** @var int[] Table of actions. Indexed according to $actionBase comment. */
    protected $action;
    /** @var int[] Table indexed analogously to $action. If $actionCheck[$actionBase[$state] + $symbol] != $symbol
     *             then the action is defaulted, i.e. $actionDefault[$state] should be used instead. */
    protected $actionCheck;
    /** @var int[] Map of states to their default action */
    protected $actionDefault;
    /** @var callable[] Semantic action callbacks */
    protected $reduceCallbacks;
    /** @var int[] Map of non-terminals to a displacement into the $goto table. The corresponding goto state for this
     *             non-terminal/state pair is $goto[$gotoBase[$nonTerminal] + $state] (unless defaulted) */
    protected $gotoBase;
    /** @var int[] Table of states to goto after reduction. Indexed according to $gotoBase comment. */
    protected $goto;
    /** @var int[] Table indexed analogously to $goto. If $gotoCheck[$gotoBase[$nonTerminal] + $state] != $nonTerminal
     *             then the goto state is defaulted, i.e. $gotoDefault[$nonTerminal] should be used. */
    protected $gotoCheck;
    /** @var int[] Map of non-terminals to the default state to goto after their reduction */
    protected $gotoDefault;
    /** @var int[] Map of rules to the non-terminal on their left-hand side, i.e. the non-terminal to use for
     *             determining the state to goto after reduction. */
    protected $ruleToNonTerminal;
    /** @var int[] Map of rules to the length of their right-hand side, which is the number of elements that have to
     *             be popped from the stack(s) on reduction. */
    protected $ruleToLength;
    /*
     * The following members are part of the parser state:
     */
    /** @var Lexer Lexer that is used when parsing */
    protected $lexer;
    /** @var mixed Temporary value containing the result of last semantic action (reduction) */
    protected $semValue;
    /** @var array Semantic value stack (contains values of tokens and semantic action results) */
    protected $semStack;
    /** @var array[] Start attribute stack */
    protected $startAttributeStack;
    /** @var array[] End attribute stack */
    protected $endAttributeStack;
    /** @var array End attributes of last *shifted* token */
    protected $endAttributes;
    /** @var array Start attributes of last *read* token */
    protected $lookaheadStartAttributes;
    /** @var ErrorHandler Error handler */
    protected $errorHandler;
    /** @var int Error state, used to avoid error floods */
    protected $errorState;
    /**
     * Initialize $reduceCallbacks map.
     */
    protected abstract function initReduceCallbacks();
    /**
     * Creates a parser instance.
     *
     * Options: Currently none.
     *
     * @param Lexer $lexer A lexer
     * @param array $options Options array.
     */
    public function __construct(Lexer $lexer, array $options = [])
    {
        $this->lexer = $lexer;
        if (isset($options['throwOnError'])) {
            throw new \LogicException('"throwOnError" is no longer supported, use "errorHandler" instead');
        }
        $this->initReduceCallbacks();
    }
    /**
     * Parses PHP code into a node tree.
     *
     * If a non-throwing error handler is used, the parser will continue parsing after an error
     * occurred and attempt to build a partial AST.
     *
     * @param string $code The source code to parse
     * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults
     *                                        to ErrorHandler\Throwing.
     *
     * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and
     *                          the parser was unable to recover from an error).
     */
    public function parse(string $code, ErrorHandler $errorHandler = null)
    {
        $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing();
        $this->lexer->startLexing($code, $this->errorHandler);
        $result = $this->doParse();
        // Clear out some of the interior state, so we don't hold onto unnecessary
        // memory between uses of the parser
        $this->startAttributeStack = [];
        $this->endAttributeStack = [];
        $this->semStack = [];
        $this->semValue = null;
        return $result;
    }
    protected function doParse()
    {
        // We start off with no lookahead-token
        $symbol = self::SYMBOL_NONE;
        // The attributes for a node are taken from the first and last token of the node.
        // From the first token only the startAttributes are taken and from the last only
        // the endAttributes. Both are merged using the array union operator (+).
        $startAttributes = [];
        $endAttributes = [];
        $this->endAttributes = $endAttributes;
        // Keep stack of start and end attributes
        $this->startAttributeStack = [];
        $this->endAttributeStack = [$endAttributes];
        // Start off in the initial state and keep a stack of previous states
        $state = 0;
        $stateStack = [$state];
        // Semantic value stack (contains values of tokens and semantic action results)
        $this->semStack = [];
        // Current position in the stack(s)
        $stackPos = 0;
        $this->errorState = 0;
        for (;;) {
            //$this->traceNewState($state, $symbol);
            if ($this->actionBase[$state] === 0) {
                $rule = $this->actionDefault[$state];
            } else {
                if ($symbol === self::SYMBOL_NONE) {
                    // Fetch the next token id from the lexer and fetch additional info by-ref.
                    // The end attributes are fetched into a temporary variable and only set once the token is really
                    // shifted (not during read). Otherwise you would sometimes get off-by-one errors, when a rule is
                    // reduced after a token was read but not yet shifted.
                    $tokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $endAttributes);
                    // map the lexer token id to the internally used symbols
                    $symbol = $tokenId >= 0 && $tokenId < $this->tokenToSymbolMapSize ? $this->tokenToSymbol[$tokenId] : $this->invalidSymbol;
                    if ($symbol === $this->invalidSymbol) {
                        throw new \RangeException(\sprintf('The lexer returned an invalid token (id=%d, value=%s)', $tokenId, $tokenValue));
                    }
                    // Allow productions to access the start attributes of the lookahead token.
                    $this->lookaheadStartAttributes = $startAttributes;
                    //$this->traceRead($symbol);
                }
                $idx = $this->actionBase[$state] + $symbol;
                if (($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) && ($action = $this->action[$idx]) !== $this->defaultAction) {
                    /*
                     * >= numNonLeafStates: shift and reduce
                     * > 0: shift
                     * = 0: accept
                     * < 0: reduce
                     * = -YYUNEXPECTED: error
                     */
                    if ($action > 0) {
                        /* shift */
                        //$this->traceShift($symbol);
                        ++$stackPos;
                        $stateStack[$stackPos] = $state = $action;
                        $this->semStack[$stackPos] = $tokenValue;
                        $this->startAttributeStack[$stackPos] = $startAttributes;
                        $this->endAttributeStack[$stackPos] = $endAttributes;
                        $this->endAttributes = $endAttributes;
                        $symbol = self::SYMBOL_NONE;
                        if ($this->errorState) {
                            --$this->errorState;
                        }
                        if ($action < $this->numNonLeafStates) {
                            continue;
                        }
                        /* $yyn >= numNonLeafStates means shift-and-reduce */
                        $rule = $action - $this->numNonLeafStates;
                    } else {
                        $rule = -$action;
                    }
                } else {
                    $rule = $this->actionDefault[$state];
                }
            }
            for (;;) {
                if ($rule === 0) {
                    /* accept */
                    //$this->traceAccept();
                    return $this->semValue;
                } elseif ($rule !== $this->unexpectedTokenRule) {
                    /* reduce */
                    //$this->traceReduce($rule);
                    try {
                        $this->reduceCallbacks[$rule]($stackPos);
                    } catch (Error $e) {
                        if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) {
                            $e->setStartLine($startAttributes['startLine']);
                        }
                        $this->emitError($e);
                        // Can't recover from this type of error
                        return null;
                    }
                    /* Goto - shift nonterminal */
                    $lastEndAttributes = $this->endAttributeStack[$stackPos];
                    $ruleLength = $this->ruleToLength[$rule];
                    $stackPos -= $ruleLength;
                    $nonTerminal = $this->ruleToNonTerminal[$rule];
                    $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos];
                    if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) {
                        $state = $this->goto[$idx];
                    } else {
                        $state = $this->gotoDefault[$nonTerminal];
                    }
                    ++$stackPos;
                    $stateStack[$stackPos] = $state;
                    $this->semStack[$stackPos] = $this->semValue;
                    $this->endAttributeStack[$stackPos] = $lastEndAttributes;
                    if ($ruleLength === 0) {
                        // Empty productions use the start attributes of the lookahead token.
                        $this->startAttributeStack[$stackPos] = $this->lookaheadStartAttributes;
                    }
                } else {
                    /* error */
                    switch ($this->errorState) {
                        case 0:
                            $msg = $this->getErrorMessage($symbol, $state);
                            $this->emitError(new Error($msg, $startAttributes + $endAttributes));
                        // Break missing intentionally
                        case 1:
                        case 2:
                            $this->errorState = 3;
                            // Pop until error-expecting state uncovered
                            while (!(($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $this->errorSymbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) || ($action = $this->action[$idx]) === $this->defaultAction) {
                                // Not totally sure about this
                                if ($stackPos <= 0) {
                                    // Could not recover from error
                                    return null;
                                }
                                $state = $stateStack[--$stackPos];
                                //$this->tracePop($state);
                            }
                            //$this->traceShift($this->errorSymbol);
                            ++$stackPos;
                            $stateStack[$stackPos] = $state = $action;
                            // We treat the error symbol as being empty, so we reset the end attributes
                            // to the end attributes of the last non-error symbol
                            $this->startAttributeStack[$stackPos] = $this->lookaheadStartAttributes;
                            $this->endAttributeStack[$stackPos] = $this->endAttributeStack[$stackPos - 1];
                            $this->endAttributes = $this->endAttributeStack[$stackPos - 1];
                            break;
                        case 3:
                            if ($symbol === 0) {
                                // Reached EOF without recovering from error
                                return null;
                            }
                            //$this->traceDiscard($symbol);
                            $symbol = self::SYMBOL_NONE;
                            break 2;
                    }
                }
                if ($state < $this->numNonLeafStates) {
                    break;
                }
                /* >= numNonLeafStates means shift-and-reduce */
                $rule = $state - $this->numNonLeafStates;
            }
        }
        throw new \RuntimeException('Reached end of parser loop');
    }
    protected function emitError(Error $error)
    {
        $this->errorHandler->handleError($error);
    }
    /**
     * Format error message including expected tokens.
     *
     * @param int $symbol Unexpected symbol
     * @param int $state  State at time of error
     *
     * @return string Formatted error message
     */
    protected function getErrorMessage(int $symbol, int $state) : string
    {
        $expectedString = '';
        if ($expected = $this->getExpectedTokens($state)) {
            $expectedString = ', expecting ' . \implode(' or ', $expected);
        }
        return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString;
    }
    /**
     * Get limited number of expected tokens in given state.
     *
     * @param int $state State
     *
     * @return string[] Expected tokens. If too many, an empty array is returned.
     */
    protected function getExpectedTokens(int $state) : array
    {
        $expected = [];
        $base = $this->actionBase[$state];
        foreach ($this->symbolToName as $symbol => $name) {
            $idx = $base + $symbol;
            if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) {
                if ($this->action[$idx] !== $this->unexpectedTokenRule && $this->action[$idx] !== $this->defaultAction && $symbol !== $this->errorSymbol) {
                    if (\count($expected) === 4) {
                        /* Too many expected tokens */
                        return [];
                    }
                    $expected[] = $name;
                }
            }
        }
        return $expected;
    }
    /*
     * Tracing functions used for debugging the parser.
     */
    /*
    protected function traceNewState($state, $symbol) {
        echo '% State ' . $state
            . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n";
    }
    
    protected function traceRead($symbol) {
        echo '% Reading ' . $this->symbolToName[$symbol] . "\n";
    }
    
    protected function traceShift($symbol) {
        echo '% Shift ' . $this->symbolToName[$symbol] . "\n";
    }
    
    protected function traceAccept() {
        echo "% Accepted.\n";
    }
    
    protected function traceReduce($n) {
        echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n";
    }
    
    protected function tracePop($state) {
        echo '% Recovering, uncovered state ' . $state . "\n";
    }
    
    protected function traceDiscard($symbol) {
        echo '% Discard ' . $this->symbolToName[$symbol] . "\n";
    }
    */
    /*
     * Helper functions invoked by semantic actions
     */
    /**
     * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions.
     *
     * @param Node\Stmt[] $stmts
     * @return Node\Stmt[]
     */
    protected function handleNamespaces(array $stmts) : array
    {
        $hasErrored = \false;
        $style = $this->getNamespacingStyle($stmts);
        if (null === $style) {
            // not namespaced, nothing to do
            return $stmts;
        } elseif ('brace' === $style) {
            // For braced namespaces we only have to check that there are no invalid statements between the namespaces
            $afterFirstNamespace = \false;
            foreach ($stmts as $stmt) {
                if ($stmt instanceof Node\Stmt\Namespace_) {
                    $afterFirstNamespace = \true;
                } elseif (!$stmt instanceof Node\Stmt\HaltCompiler && !$stmt instanceof Node\Stmt\Nop && $afterFirstNamespace && !$hasErrored) {
                    $this->emitError(new Error('No code may exist outside of namespace {}', $stmt->getAttributes()));
                    $hasErrored = \true;
                    // Avoid one error for every statement
                }
            }
            return $stmts;
        } else {
            // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts
            $resultStmts = [];
            $targetStmts =& $resultStmts;
            $lastNs = null;
            foreach ($stmts as $stmt) {
                if ($stmt instanceof Node\Stmt\Namespace_) {
                    if ($lastNs !== null) {
                        $this->fixupNamespaceAttributes($lastNs);
                    }
                    if ($stmt->stmts === null) {
                        $stmt->stmts = [];
                        $targetStmts =& $stmt->stmts;
                        $resultStmts[] = $stmt;
                    } else {
                        // This handles the invalid case of mixed style namespaces
                        $resultStmts[] = $stmt;
                        $targetStmts =& $resultStmts;
                    }
                    $lastNs = $stmt;
                } elseif ($stmt instanceof Node\Stmt\HaltCompiler) {
                    // __halt_compiler() is not moved into the namespace
                    $resultStmts[] = $stmt;
                } else {
                    $targetStmts[] = $stmt;
                }
            }
            if ($lastNs !== null) {
                $this->fixupNamespaceAttributes($lastNs);
            }
            return $resultStmts;
        }
    }
    private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt)
    {
        // We moved the statements into the namespace node, as such the end of the namespace node
        // needs to be extended to the end of the statements.
        if (empty($stmt->stmts)) {
            return;
        }
        // We only move the builtin end attributes here. This is the best we can do with the
        // knowledge we have.
        $endAttributes = ['endLine', 'endFilePos', 'endTokenPos'];
        $lastStmt = $stmt->stmts[\count($stmt->stmts) - 1];
        foreach ($endAttributes as $endAttribute) {
            if ($lastStmt->hasAttribute($endAttribute)) {
                $stmt->setAttribute($endAttribute, $lastStmt->getAttribute($endAttribute));
            }
        }
    }
    /**
     * Determine namespacing style (semicolon or brace)
     *
     * @param Node[] $stmts Top-level statements.
     *
     * @return null|string One of "semicolon", "brace" or null (no namespaces)
     */
    private function getNamespacingStyle(array $stmts)
    {
        $style = null;
        $hasNotAllowedStmts = \false;
        foreach ($stmts as $i => $stmt) {
            if ($stmt instanceof Node\Stmt\Namespace_) {
                $currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace';
                if (null === $style) {
                    $style = $currentStyle;
                    if ($hasNotAllowedStmts) {
                        $this->emitError(new Error('Namespace declaration statement has to be the very first statement in the script', $stmt->getLine()));
                    }
                } elseif ($style !== $currentStyle) {
                    $this->emitError(new Error('Cannot mix bracketed namespace declarations with unbracketed namespace declarations', $stmt->getLine()));
                    // Treat like semicolon style for namespace normalization
                    return 'semicolon';
                }
                continue;
            }
            /* declare(), __halt_compiler() and nops can be used before a namespace declaration */
            if ($stmt instanceof Node\Stmt\Declare_ || $stmt instanceof Node\Stmt\HaltCompiler || $stmt instanceof Node\Stmt\Nop) {
                continue;
            }
            /* There may be a hashbang line at the very start of the file */
            if ($i === 0 && $stmt instanceof Node\Stmt\InlineHTML && \preg_match('/\\A#!.*\\r?\\n\\z/', $stmt->value)) {
                continue;
            }
            /* Everything else if forbidden before namespace declarations */
            $hasNotAllowedStmts = \true;
        }
        return $style;
    }
    /**
     * Fix up parsing of static property calls in PHP 5.
     *
     * In PHP 5 A::$b[c][d] and A::$b[c][d]() have very different interpretation. The former is
     * interpreted as (A::$b)[c][d], while the latter is the same as A::{$b[c][d]}(). We parse the
     * latter as the former initially and this method fixes the AST into the correct form when we
     * encounter the "()".
     *
     * @param  Node\Expr\StaticPropertyFetch|Node\Expr\ArrayDimFetch $prop
     * @param  Node\Arg[] $args
     * @param  array      $attributes
     *
     * @return Expr\StaticCall
     */
    protected function fixupPhp5StaticPropCall($prop, array $args, array $attributes) : Expr\StaticCall
    {
        if ($prop instanceof Node\Expr\StaticPropertyFetch) {
            $name = $prop->name instanceof VarLikeIdentifier ? $prop->name->toString() : $prop->name;
            $var = new Expr\Variable($name, $prop->name->getAttributes());
            return new Expr\StaticCall($prop->class, $var, $args, $attributes);
        } elseif ($prop instanceof Node\Expr\ArrayDimFetch) {
            $tmp = $prop;
            while ($tmp->var instanceof Node\Expr\ArrayDimFetch) {
                $tmp = $tmp->var;
            }
            /** @var Expr\StaticPropertyFetch $staticProp */
            $staticProp = $tmp->var;
            // Set start attributes to attributes of innermost node
            $tmp = $prop;
            $this->fixupStartAttributes($tmp, $staticProp->name);
            while ($tmp->var instanceof Node\Expr\ArrayDimFetch) {
                $tmp = $tmp->var;
                $this->fixupStartAttributes($tmp, $staticProp->name);
            }
            $name = $staticProp->name instanceof VarLikeIdentifier ? $staticProp->name->toString() : $staticProp->name;
            $tmp->var = new Expr\Variable($name, $staticProp->name->getAttributes());
            return new Expr\StaticCall($staticProp->class, $prop, $args, $attributes);
        } else {
            throw new \Exception();
        }
    }
    protected function fixupStartAttributes(Node $to, Node $from)
    {
        $startAttributes = ['startLine', 'startFilePos', 'startTokenPos'];
        foreach ($startAttributes as $startAttribute) {
            if ($from->hasAttribute($startAttribute)) {
                $to->setAttribute($startAttribute, $from->getAttribute($startAttribute));
            }
        }
    }
    protected function handleBuiltinTypes(Name $name)
    {
        $builtinTypes = ['bool' => \true, 'int' => \true, 'float' => \true, 'string' => \true, 'iterable' => \true, 'void' => \true, 'object' => \true, 'null' => \true, 'false' => \true, 'mixed' => \true, 'never' => \true, 'true' => \true];
        if (!$name->isUnqualified()) {
            return $name;
        }
        $lowerName = $name->toLowerString();
        if (!isset($builtinTypes[$lowerName])) {
            return $name;
        }
        return new Node\Identifier($lowerName, $name->getAttributes());
    }
    /**
     * Get combined start and end attributes at a stack location
     *
     * @param int $pos Stack location
     *
     * @return array Combined start and end attributes
     */
    protected function getAttributesAt(int $pos) : array
    {
        return $this->startAttributeStack[$pos] + $this->endAttributeStack[$pos];
    }
    protected function getFloatCastKind(string $cast) : int
    {
        $cast = \strtolower($cast);
        if (\strpos($cast, 'float') !== \false) {
            return Double::KIND_FLOAT;
        }
        if (\strpos($cast, 'real') !== \false) {
            return Double::KIND_REAL;
        }
        return Double::KIND_DOUBLE;
    }
    protected function parseLNumber($str, $attributes, $allowInvalidOctal = \false)
    {
        try {
            return LNumber::fromString($str, $attributes, $allowInvalidOctal);
        } catch (Error $error) {
            $this->emitError($error);
            // Use dummy value
            return new LNumber(0, $attributes);
        }
    }
    /**
     * Parse a T_NUM_STRING token into either an integer or string node.
     *
     * @param string $str        Number string
     * @param array  $attributes Attributes
     *
     * @return LNumber|String_ Integer or string node.
     */
    protected function parseNumString(string $str, array $attributes)
    {
        if (!\preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) {
            return new String_($str, $attributes);
        }
        $num = +$str;
        if (!\is_int($num)) {
            return new String_($str, $attributes);
        }
        return new LNumber($num, $attributes);
    }
    protected function stripIndentation(string $string, int $indentLen, string $indentChar, bool $newlineAtStart, bool $newlineAtEnd, array $attributes)
    {
        if ($indentLen === 0) {
            return $string;
        }
        $start = $newlineAtStart ? '(?:(?<=\\n)|\\A)' : '(?<=\\n)';
        $end = $newlineAtEnd ? '(?:(?=[\\r\\n])|\\z)' : '(?=[\\r\\n])';
        $regex = '/' . $start . '([ \\t]*)(' . $end . ')?/';
        return \preg_replace_callback($regex, function ($matches) use($indentLen, $indentChar, $attributes) {
            $prefix = \substr($matches[1], 0, $indentLen);
            if (\false !== \strpos($prefix, $indentChar === " " ? "\t" : " ")) {
                $this->emitError(new Error('Invalid indentation - tabs and spaces cannot be mixed', $attributes));
            } elseif (\strlen($prefix) < $indentLen && !isset($matches[2])) {
                $this->emitError(new Error('Invalid body indentation level ' . '(expecting an indentation level of at least ' . $indentLen . ')', $attributes));
            }
            return \substr($matches[0], \strlen($prefix));
        }, $string);
    }
    protected function parseDocString(string $startToken, $contents, string $endToken, array $attributes, array $endTokenAttributes, bool $parseUnicodeEscape)
    {
        $kind = \strpos($startToken, "'") === \false ? String_::KIND_HEREDOC : String_::KIND_NOWDOC;
        $regex = '/\\A[bB]?<<<[ \\t]*[\'"]?([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)[\'"]?(?:\\r\\n|\\n|\\r)\\z/';
        $result = \preg_match($regex, $startToken, $matches);
        \assert($result === 1);
        $label = $matches[1];
        $result = \preg_match('/\\A[ \\t]*/', $endToken, $matches);
        \assert($result === 1);
        $indentation = $matches[0];
        $attributes['kind'] = $kind;
        $attributes['docLabel'] = $label;
        $attributes['docIndentation'] = $indentation;
        $indentHasSpaces = \false !== \strpos($indentation, " ");
        $indentHasTabs = \false !== \strpos($indentation, "\t");
        if ($indentHasSpaces && $indentHasTabs) {
            $this->emitError(new Error('Invalid indentation - tabs and spaces cannot be mixed', $endTokenAttributes));
            // Proceed processing as if this doc string is not indented
            $indentation = '';
        }
        $indentLen = \strlen($indentation);
        $indentChar = $indentHasSpaces ? " " : "\t";
        if (\is_string($contents)) {
            if ($contents === '') {
                return new String_('', $attributes);
            }
            $contents = $this->stripIndentation($contents, $indentLen, $indentChar, \true, \true, $attributes);
            $contents = \preg_replace('~(\\r\\n|\\n|\\r)\\z~', '', $contents);
            if ($kind === String_::KIND_HEREDOC) {
                $contents = String_::parseEscapeSequences($contents, null, $parseUnicodeEscape);
            }
            return new String_($contents, $attributes);
        } else {
            \assert(\count($contents) > 0);
            if (!$contents[0] instanceof Node\Scalar\EncapsedStringPart) {
                // If there is no leading encapsed string part, pretend there is an empty one
                $this->stripIndentation('', $indentLen, $indentChar, \true, \false, $contents[0]->getAttributes());
            }
            $newContents = [];
            foreach ($contents as $i => $part) {
                if ($part instanceof Node\Scalar\EncapsedStringPart) {
                    $isLast = $i === \count($contents) - 1;
                    $part->value = $this->stripIndentation($part->value, $indentLen, $indentChar, $i === 0, $isLast, $part->getAttributes());
                    $part->value = String_::parseEscapeSequences($part->value, null, $parseUnicodeEscape);
                    if ($isLast) {
                        $part->value = \preg_replace('~(\\r\\n|\\n|\\r)\\z~', '', $part->value);
                    }
                    if ('' === $part->value) {
                        continue;
                    }
                }
                $newContents[] = $part;
            }
            return new Encapsed($newContents, $attributes);
        }
    }
    /**
     * Create attributes for a zero-length common-capturing nop.
     *
     * @param Comment[] $comments
     * @return array
     */
    protected function createCommentNopAttributes(array $comments)
    {
        $comment = $comments[\count($comments) - 1];
        $commentEndLine = $comment->getEndLine();
        $commentEndFilePos = $comment->getEndFilePos();
        $commentEndTokenPos = $comment->getEndTokenPos();
        $attributes = ['comments' => $comments];
        if (-1 !== $commentEndLine) {
            $attributes['startLine'] = $commentEndLine;
            $attributes['endLine'] = $commentEndLine;
        }
        if (-1 !== $commentEndFilePos) {
            $attributes['startFilePos'] = $commentEndFilePos + 1;
            $attributes['endFilePos'] = $commentEndFilePos;
        }
        if (-1 !== $commentEndTokenPos) {
            $attributes['startTokenPos'] = $commentEndTokenPos + 1;
            $attributes['endTokenPos'] = $commentEndTokenPos;
        }
        return $attributes;
    }
    protected function checkClassModifier($a, $b, $modifierPos)
    {
        try {
            Class_::verifyClassModifier($a, $b);
        } catch (Error $error) {
            $error->setAttributes($this->getAttributesAt($modifierPos));
            $this->emitError($error);
        }
    }
    protected function checkModifier($a, $b, $modifierPos)
    {
        // Jumping through some hoops here because verifyModifier() is also used elsewhere
        try {
            Class_::verifyModifier($a, $b);
        } catch (Error $error) {
            $error->setAttributes($this->getAttributesAt($modifierPos));
            $this->emitError($error);
        }
    }
    protected function checkParam(Param $node)
    {
        if ($node->variadic && null !== $node->default) {
            $this->emitError(new Error('Variadic parameter cannot have a default value', $node->default->getAttributes()));
        }
    }
    protected function checkTryCatch(TryCatch $node)
    {
        if (empty($node->catches) && null === $node->finally) {
            $this->emitError(new Error('Cannot use try without catch or finally', $node->getAttributes()));
        }
    }
    protected function checkNamespace(Namespace_ $node)
    {
        if (null !== $node->stmts) {
            foreach ($node->stmts as $stmt) {
                if ($stmt instanceof Namespace_) {
                    $this->emitError(new Error('Namespace declarations cannot be nested', $stmt->getAttributes()));
                }
            }
        }
    }
    private function checkClassName($name, $namePos)
    {
        if (null !== $name && $name->isSpecialClassName()) {
            $this->emitError(new Error(\sprintf('Cannot use \'%s\' as class name as it is reserved', $name), $this->getAttributesAt($namePos)));
        }
    }
    private function checkImplementedInterfaces(array $interfaces)
    {
        foreach ($interfaces as $interface) {
            if ($interface->isSpecialClassName()) {
                $this->emitError(new Error(\sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), $interface->getAttributes()));
            }
        }
    }
    protected function checkClass(Class_ $node, $namePos)
    {
        $this->checkClassName($node->name, $namePos);
        if ($node->extends && $node->extends->isSpecialClassName()) {
            $this->emitError(new Error(\sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), $node->extends->getAttributes()));
        }
        $this->checkImplementedInterfaces($node->implements);
    }
    protected function checkInterface(Interface_ $node, $namePos)
    {
        $this->checkClassName($node->name, $namePos);
        $this->checkImplementedInterfaces($node->extends);
    }
    protected function checkEnum(Enum_ $node, $namePos)
    {
        $this->checkClassName($node->name, $namePos);
        $this->checkImplementedInterfaces($node->implements);
    }
    protected function checkClassMethod(ClassMethod $node, $modifierPos)
    {
        if ($node->flags & Class_::MODIFIER_STATIC) {
            switch ($node->name->toLowerString()) {
                case '__construct':
                    $this->emitError(new Error(\sprintf('Constructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
                    break;
                case '__destruct':
                    $this->emitError(new Error(\sprintf('Destructor %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
                    break;
                case '__clone':
                    $this->emitError(new Error(\sprintf('Clone method %s() cannot be static', $node->name), $this->getAttributesAt($modifierPos)));
                    break;
            }
        }
        if ($node->flags & Class_::MODIFIER_READONLY) {
            $this->emitError(new Error(\sprintf('Method %s() cannot be readonly', $node->name), $this->getAttributesAt($modifierPos)));
        }
    }
    protected function checkClassConst(ClassConst $node, $modifierPos)
    {
        if ($node->flags & Class_::MODIFIER_STATIC) {
            $this->emitError(new Error("Cannot use 'static' as constant modifier", $this->getAttributesAt($modifierPos)));
        }
        if ($node->flags & Class_::MODIFIER_ABSTRACT) {
            $this->emitError(new Error("Cannot use 'abstract' as constant modifier", $this->getAttributesAt($modifierPos)));
        }
        if ($node->flags & Class_::MODIFIER_READONLY) {
            $this->emitError(new Error("Cannot use 'readonly' as constant modifier", $this->getAttributesAt($modifierPos)));
        }
    }
    protected function checkProperty(Property $node, $modifierPos)
    {
        if ($node->flags & Class_::MODIFIER_ABSTRACT) {
            $this->emitError(new Error('Properties cannot be declared abstract', $this->getAttributesAt($modifierPos)));
        }
        if ($node->flags & Class_::MODIFIER_FINAL) {
            $this->emitError(new Error('Properties cannot be declared final', $this->getAttributesAt($modifierPos)));
        }
    }
    protected function checkUseUse(UseUse $node, $namePos)
    {
        if ($node->alias && $node->alias->isSpecialClassName()) {
            $this->emitError(new Error(\sprintf('Cannot use %s as %s because \'%2$s\' is a special class name', $node->name, $node->alias), $this->getAttributesAt($namePos)));
        }
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

use _HumbugBox1cb33d1f20f1\PhpParser\Internal\DiffElem;
use _HumbugBox1cb33d1f20f1\PhpParser\Internal\PrintableNewAnonClassNode;
use _HumbugBox1cb33d1f20f1\PhpParser\Internal\TokenStream;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
abstract class PrettyPrinterAbstract
{
    const FIXUP_PREC_LEFT = 0;
    // LHS operand affected by precedence
    const FIXUP_PREC_RIGHT = 1;
    // RHS operand affected by precedence
    const FIXUP_CALL_LHS = 2;
    // LHS of call
    const FIXUP_DEREF_LHS = 3;
    // LHS of dereferencing operation
    const FIXUP_BRACED_NAME = 4;
    // Name operand that may require bracing
    const FIXUP_VAR_BRACED_NAME = 5;
    // Name operand that may require ${} bracing
    const FIXUP_ENCAPSED = 6;
    // Encapsed string part
    protected $precedenceMap = [
        // [precedence, associativity]
        // where for precedence -1 is %left, 0 is %nonassoc and 1 is %right
        BinaryOp\Pow::class => [0, 1],
        Expr\BitwiseNot::class => [10, 1],
        Expr\PreInc::class => [10, 1],
        Expr\PreDec::class => [10, 1],
        Expr\PostInc::class => [10, -1],
        Expr\PostDec::class => [10, -1],
        Expr\UnaryPlus::class => [10, 1],
        Expr\UnaryMinus::class => [10, 1],
        Cast\Int_::class => [10, 1],
        Cast\Double::class => [10, 1],
        Cast\String_::class => [10, 1],
        Cast\Array_::class => [10, 1],
        Cast\Object_::class => [10, 1],
        Cast\Bool_::class => [10, 1],
        Cast\Unset_::class => [10, 1],
        Expr\ErrorSuppress::class => [10, 1],
        Expr\Instanceof_::class => [20, 0],
        Expr\BooleanNot::class => [30, 1],
        BinaryOp\Mul::class => [40, -1],
        BinaryOp\Div::class => [40, -1],
        BinaryOp\Mod::class => [40, -1],
        BinaryOp\Plus::class => [50, -1],
        BinaryOp\Minus::class => [50, -1],
        BinaryOp\Concat::class => [50, -1],
        BinaryOp\ShiftLeft::class => [60, -1],
        BinaryOp\ShiftRight::class => [60, -1],
        BinaryOp\Smaller::class => [70, 0],
        BinaryOp\SmallerOrEqual::class => [70, 0],
        BinaryOp\Greater::class => [70, 0],
        BinaryOp\GreaterOrEqual::class => [70, 0],
        BinaryOp\Equal::class => [80, 0],
        BinaryOp\NotEqual::class => [80, 0],
        BinaryOp\Identical::class => [80, 0],
        BinaryOp\NotIdentical::class => [80, 0],
        BinaryOp\Spaceship::class => [80, 0],
        BinaryOp\BitwiseAnd::class => [90, -1],
        BinaryOp\BitwiseXor::class => [100, -1],
        BinaryOp\BitwiseOr::class => [110, -1],
        BinaryOp\BooleanAnd::class => [120, -1],
        BinaryOp\BooleanOr::class => [130, -1],
        BinaryOp\Coalesce::class => [140, 1],
        Expr\Ternary::class => [150, 0],
        // parser uses %left for assignments, but they really behave as %right
        Expr\Assign::class => [160, 1],
        Expr\AssignRef::class => [160, 1],
        AssignOp\Plus::class => [160, 1],
        AssignOp\Minus::class => [160, 1],
        AssignOp\Mul::class => [160, 1],
        AssignOp\Div::class => [160, 1],
        AssignOp\Concat::class => [160, 1],
        AssignOp\Mod::class => [160, 1],
        AssignOp\BitwiseAnd::class => [160, 1],
        AssignOp\BitwiseOr::class => [160, 1],
        AssignOp\BitwiseXor::class => [160, 1],
        AssignOp\ShiftLeft::class => [160, 1],
        AssignOp\ShiftRight::class => [160, 1],
        AssignOp\Pow::class => [160, 1],
        AssignOp\Coalesce::class => [160, 1],
        Expr\YieldFrom::class => [165, 1],
        Expr\Print_::class => [168, 1],
        BinaryOp\LogicalAnd::class => [170, -1],
        BinaryOp\LogicalXor::class => [180, -1],
        BinaryOp\LogicalOr::class => [190, -1],
        Expr\Include_::class => [200, -1],
    ];
    /** @var int Current indentation level. */
    protected $indentLevel;
    /** @var string Newline including current indentation. */
    protected $nl;
    /** @var string Token placed at end of doc string to ensure it is followed by a newline. */
    protected $docStringEndToken;
    /** @var bool Whether semicolon namespaces can be used (i.e. no global namespace is used) */
    protected $canUseSemicolonNamespaces;
    /** @var array Pretty printer options */
    protected $options;
    /** @var TokenStream Original tokens for use in format-preserving pretty print */
    protected $origTokens;
    /** @var Internal\Differ Differ for node lists */
    protected $nodeListDiffer;
    /** @var bool[] Map determining whether a certain character is a label character */
    protected $labelCharMap;
    /**
     * @var int[][] Map from token classes and subnode names to FIXUP_* constants. This is used
     *              during format-preserving prints to place additional parens/braces if necessary.
     */
    protected $fixupMap;
    /**
     * @var int[][] Map from "{$node->getType()}->{$subNode}" to ['left' => $l, 'right' => $r],
     *              where $l and $r specify the token type that needs to be stripped when removing
     *              this node.
     */
    protected $removalMap;
    /**
     * @var mixed[] Map from "{$node->getType()}->{$subNode}" to [$find, $beforeToken, $extraLeft, $extraRight].
     *              $find is an optional token after which the insertion occurs. $extraLeft/Right
     *              are optionally added before/after the main insertions.
     */
    protected $insertionMap;
    /**
     * @var string[] Map From "{$node->getType()}->{$subNode}" to string that should be inserted
     *               between elements of this list subnode.
     */
    protected $listInsertionMap;
    protected $emptyListInsertionMap;
    /** @var int[] Map from "{$node->getType()}->{$subNode}" to token before which the modifiers
     *             should be reprinted. */
    protected $modifierChangeMap;
    /**
     * Creates a pretty printer instance using the given options.
     *
     * Supported options:
     *  * bool $shortArraySyntax = false: Whether to use [] instead of array() as the default array
     *                                    syntax, if the node does not specify a format.
     *
     * @param array $options Dictionary of formatting options
     */
    public function __construct(array $options = [])
    {
        $this->docStringEndToken = '_DOC_STRING_END_' . \mt_rand();
        $defaultOptions = ['shortArraySyntax' => \false];
        $this->options = $options + $defaultOptions;
    }
    /**
     * Reset pretty printing state.
     */
    protected function resetState()
    {
        $this->indentLevel = 0;
        $this->nl = "\n";
        $this->origTokens = null;
    }
    /**
     * Set indentation level
     *
     * @param int $level Level in number of spaces
     */
    protected function setIndentLevel(int $level)
    {
        $this->indentLevel = $level;
        $this->nl = "\n" . \str_repeat(' ', $level);
    }
    /**
     * Increase indentation level.
     */
    protected function indent()
    {
        $this->indentLevel += 4;
        $this->nl .= '    ';
    }
    /**
     * Decrease indentation level.
     */
    protected function outdent()
    {
        \assert($this->indentLevel >= 4);
        $this->indentLevel -= 4;
        $this->nl = "\n" . \str_repeat(' ', $this->indentLevel);
    }
    /**
     * Pretty prints an array of statements.
     *
     * @param Node[] $stmts Array of statements
     *
     * @return string Pretty printed statements
     */
    public function prettyPrint(array $stmts) : string
    {
        $this->resetState();
        $this->preprocessNodes($stmts);
        return \ltrim($this->handleMagicTokens($this->pStmts($stmts, \false)));
    }
    /**
     * Pretty prints an expression.
     *
     * @param Expr $node Expression node
     *
     * @return string Pretty printed node
     */
    public function prettyPrintExpr(Expr $node) : string
    {
        $this->resetState();
        return $this->handleMagicTokens($this->p($node));
    }
    /**
     * Pretty prints a file of statements (includes the opening <?php tag if it is required).
     *
     * @param Node[] $stmts Array of statements
     *
     * @return string Pretty printed statements
     */
    public function prettyPrintFile(array $stmts) : string
    {
        if (!$stmts) {
            return "<?php\n\n";
        }
        $p = "<?php\n\n" . $this->prettyPrint($stmts);
        if ($stmts[0] instanceof Stmt\InlineHTML) {
            $p = \preg_replace('/^<\\?php\\s+\\?>\\n?/', '', $p);
        }
        if ($stmts[\count($stmts) - 1] instanceof Stmt\InlineHTML) {
            $p = \preg_replace('/<\\?php$/', '', \rtrim($p));
        }
        return $p;
    }
    /**
     * Preprocesses the top-level nodes to initialize pretty printer state.
     *
     * @param Node[] $nodes Array of nodes
     */
    protected function preprocessNodes(array $nodes)
    {
        /* We can use semicolon-namespaces unless there is a global namespace declaration */
        $this->canUseSemicolonNamespaces = \true;
        foreach ($nodes as $node) {
            if ($node instanceof Stmt\Namespace_ && null === $node->name) {
                $this->canUseSemicolonNamespaces = \false;
                break;
            }
        }
    }
    /**
     * Handles (and removes) no-indent and doc-string-end tokens.
     *
     * @param string $str
     * @return string
     */
    protected function handleMagicTokens(string $str) : string
    {
        // Replace doc-string-end tokens with nothing or a newline
        $str = \str_replace($this->docStringEndToken . ";\n", ";\n", $str);
        $str = \str_replace($this->docStringEndToken, "\n", $str);
        return $str;
    }
    /**
     * Pretty prints an array of nodes (statements) and indents them optionally.
     *
     * @param Node[] $nodes  Array of nodes
     * @param bool   $indent Whether to indent the printed nodes
     *
     * @return string Pretty printed statements
     */
    protected function pStmts(array $nodes, bool $indent = \true) : string
    {
        if ($indent) {
            $this->indent();
        }
        $result = '';
        foreach ($nodes as $node) {
            $comments = $node->getComments();
            if ($comments) {
                $result .= $this->nl . $this->pComments($comments);
                if ($node instanceof Stmt\Nop) {
                    continue;
                }
            }
            $result .= $this->nl . $this->p($node);
        }
        if ($indent) {
            $this->outdent();
        }
        return $result;
    }
    /**
     * Pretty-print an infix operation while taking precedence into account.
     *
     * @param string $class          Node class of operator
     * @param Node   $leftNode       Left-hand side node
     * @param string $operatorString String representation of the operator
     * @param Node   $rightNode      Right-hand side node
     *
     * @return string Pretty printed infix operation
     */
    protected function pInfixOp(string $class, Node $leftNode, string $operatorString, Node $rightNode) : string
    {
        list($precedence, $associativity) = $this->precedenceMap[$class];
        return $this->pPrec($leftNode, $precedence, $associativity, -1) . $operatorString . $this->pPrec($rightNode, $precedence, $associativity, 1);
    }
    /**
     * Pretty-print a prefix operation while taking precedence into account.
     *
     * @param string $class          Node class of operator
     * @param string $operatorString String representation of the operator
     * @param Node   $node           Node
     *
     * @return string Pretty printed prefix operation
     */
    protected function pPrefixOp(string $class, string $operatorString, Node $node) : string
    {
        list($precedence, $associativity) = $this->precedenceMap[$class];
        return $operatorString . $this->pPrec($node, $precedence, $associativity, 1);
    }
    /**
     * Pretty-print a postfix operation while taking precedence into account.
     *
     * @param string $class          Node class of operator
     * @param string $operatorString String representation of the operator
     * @param Node   $node           Node
     *
     * @return string Pretty printed postfix operation
     */
    protected function pPostfixOp(string $class, Node $node, string $operatorString) : string
    {
        list($precedence, $associativity) = $this->precedenceMap[$class];
        return $this->pPrec($node, $precedence, $associativity, -1) . $operatorString;
    }
    /**
     * Prints an expression node with the least amount of parentheses necessary to preserve the meaning.
     *
     * @param Node $node                Node to pretty print
     * @param int  $parentPrecedence    Precedence of the parent operator
     * @param int  $parentAssociativity Associativity of parent operator
     *                                  (-1 is left, 0 is nonassoc, 1 is right)
     * @param int  $childPosition       Position of the node relative to the operator
     *                                  (-1 is left, 1 is right)
     *
     * @return string The pretty printed node
     */
    protected function pPrec(Node $node, int $parentPrecedence, int $parentAssociativity, int $childPosition) : string
    {
        $class = \get_class($node);
        if (isset($this->precedenceMap[$class])) {
            $childPrecedence = $this->precedenceMap[$class][0];
            if ($childPrecedence > $parentPrecedence || $parentPrecedence === $childPrecedence && $parentAssociativity !== $childPosition) {
                return '(' . $this->p($node) . ')';
            }
        }
        return $this->p($node);
    }
    /**
     * Pretty prints an array of nodes and implodes the printed values.
     *
     * @param Node[] $nodes Array of Nodes to be printed
     * @param string $glue  Character to implode with
     *
     * @return string Imploded pretty printed nodes
     */
    protected function pImplode(array $nodes, string $glue = '') : string
    {
        $pNodes = [];
        foreach ($nodes as $node) {
            if (null === $node) {
                $pNodes[] = '';
            } else {
                $pNodes[] = $this->p($node);
            }
        }
        return \implode($glue, $pNodes);
    }
    /**
     * Pretty prints an array of nodes and implodes the printed values with commas.
     *
     * @param Node[] $nodes Array of Nodes to be printed
     *
     * @return string Comma separated pretty printed nodes
     */
    protected function pCommaSeparated(array $nodes) : string
    {
        return $this->pImplode($nodes, ', ');
    }
    /**
     * Pretty prints a comma-separated list of nodes in multiline style, including comments.
     *
     * The result includes a leading newline and one level of indentation (same as pStmts).
     *
     * @param Node[] $nodes         Array of Nodes to be printed
     * @param bool   $trailingComma Whether to use a trailing comma
     *
     * @return string Comma separated pretty printed nodes in multiline style
     */
    protected function pCommaSeparatedMultiline(array $nodes, bool $trailingComma) : string
    {
        $this->indent();
        $result = '';
        $lastIdx = \count($nodes) - 1;
        foreach ($nodes as $idx => $node) {
            if ($node !== null) {
                $comments = $node->getComments();
                if ($comments) {
                    $result .= $this->nl . $this->pComments($comments);
                }
                $result .= $this->nl . $this->p($node);
            } else {
                $result .= $this->nl;
            }
            if ($trailingComma || $idx !== $lastIdx) {
                $result .= ',';
            }
        }
        $this->outdent();
        return $result;
    }
    /**
     * Prints reformatted text of the passed comments.
     *
     * @param Comment[] $comments List of comments
     *
     * @return string Reformatted text of comments
     */
    protected function pComments(array $comments) : string
    {
        $formattedComments = [];
        foreach ($comments as $comment) {
            $formattedComments[] = \str_replace("\n", $this->nl, $comment->getReformattedText());
        }
        return \implode($this->nl, $formattedComments);
    }
    /**
     * Perform a format-preserving pretty print of an AST.
     *
     * The format preservation is best effort. For some changes to the AST the formatting will not
     * be preserved (at least not locally).
     *
     * In order to use this method a number of prerequisites must be satisfied:
     *  * The startTokenPos and endTokenPos attributes in the lexer must be enabled.
     *  * The CloningVisitor must be run on the AST prior to modification.
     *  * The original tokens must be provided, using the getTokens() method on the lexer.
     *
     * @param Node[] $stmts      Modified AST with links to original AST
     * @param Node[] $origStmts  Original AST with token offset information
     * @param array  $origTokens Tokens of the original code
     *
     * @return string
     */
    public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens) : string
    {
        $this->initializeNodeListDiffer();
        $this->initializeLabelCharMap();
        $this->initializeFixupMap();
        $this->initializeRemovalMap();
        $this->initializeInsertionMap();
        $this->initializeListInsertionMap();
        $this->initializeEmptyListInsertionMap();
        $this->initializeModifierChangeMap();
        $this->resetState();
        $this->origTokens = new TokenStream($origTokens);
        $this->preprocessNodes($stmts);
        $pos = 0;
        $result = $this->pArray($stmts, $origStmts, $pos, 0, 'File', 'stmts', null);
        if (null !== $result) {
            $result .= $this->origTokens->getTokenCode($pos, \count($origTokens), 0);
        } else {
            // Fallback
            // TODO Add <?php properly
            $result = "<?php\n" . $this->pStmts($stmts, \false);
        }
        return \ltrim($this->handleMagicTokens($result));
    }
    protected function pFallback(Node $node)
    {
        return $this->{'p' . $node->getType()}($node);
    }
    /**
     * Pretty prints a node.
     *
     * This method also handles formatting preservation for nodes.
     *
     * @param Node $node Node to be pretty printed
     * @param bool $parentFormatPreserved Whether parent node has preserved formatting
     *
     * @return string Pretty printed node
     */
    protected function p(Node $node, $parentFormatPreserved = \false) : string
    {
        // No orig tokens means this is a normal pretty print without preservation of formatting
        if (!$this->origTokens) {
            return $this->{'p' . $node->getType()}($node);
        }
        /** @var Node $origNode */
        $origNode = $node->getAttribute('origNode');
        if (null === $origNode) {
            return $this->pFallback($node);
        }
        $class = \get_class($node);
        \assert($class === \get_class($origNode));
        $startPos = $origNode->getStartTokenPos();
        $endPos = $origNode->getEndTokenPos();
        \assert($startPos >= 0 && $endPos >= 0);
        $fallbackNode = $node;
        if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) {
            // Normalize node structure of anonymous classes
            $node = PrintableNewAnonClassNode::fromNewNode($node);
            $origNode = PrintableNewAnonClassNode::fromNewNode($origNode);
        }
        // InlineHTML node does not contain closing and opening PHP tags. If the parent formatting
        // is not preserved, then we need to use the fallback code to make sure the tags are
        // printed.
        if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) {
            return $this->pFallback($fallbackNode);
        }
        $indentAdjustment = $this->indentLevel - $this->origTokens->getIndentationBefore($startPos);
        $type = $node->getType();
        $fixupInfo = $this->fixupMap[$class] ?? null;
        $result = '';
        $pos = $startPos;
        foreach ($node->getSubNodeNames() as $subNodeName) {
            $subNode = $node->{$subNodeName};
            $origSubNode = $origNode->{$subNodeName};
            if (!$subNode instanceof Node && $subNode !== null || !$origSubNode instanceof Node && $origSubNode !== null) {
                if ($subNode === $origSubNode) {
                    // Unchanged, can reuse old code
                    continue;
                }
                if (\is_array($subNode) && \is_array($origSubNode)) {
                    // Array subnode changed, we might be able to reconstruct it
                    $listResult = $this->pArray($subNode, $origSubNode, $pos, $indentAdjustment, $type, $subNodeName, $fixupInfo[$subNodeName] ?? null);
                    if (null === $listResult) {
                        return $this->pFallback($fallbackNode);
                    }
                    $result .= $listResult;
                    continue;
                }
                if (\is_int($subNode) && \is_int($origSubNode)) {
                    // Check if this is a modifier change
                    $key = $type . '->' . $subNodeName;
                    if (!isset($this->modifierChangeMap[$key])) {
                        return $this->pFallback($fallbackNode);
                    }
                    $findToken = $this->modifierChangeMap[$key];
                    $result .= $this->pModifiers($subNode);
                    $pos = $this->origTokens->findRight($pos, $findToken);
                    continue;
                }
                // If a non-node, non-array subnode changed, we don't be able to do a partial
                // reconstructions, as we don't have enough offset information. Pretty print the
                // whole node instead.
                return $this->pFallback($fallbackNode);
            }
            $extraLeft = '';
            $extraRight = '';
            if ($origSubNode !== null) {
                $subStartPos = $origSubNode->getStartTokenPos();
                $subEndPos = $origSubNode->getEndTokenPos();
                \assert($subStartPos >= 0 && $subEndPos >= 0);
            } else {
                if ($subNode === null) {
                    // Both null, nothing to do
                    continue;
                }
                // A node has been inserted, check if we have insertion information for it
                $key = $type . '->' . $subNodeName;
                if (!isset($this->insertionMap[$key])) {
                    return $this->pFallback($fallbackNode);
                }
                list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key];
                if (null !== $findToken) {
                    $subStartPos = $this->origTokens->findRight($pos, $findToken) + (int) (!$beforeToken);
                } else {
                    $subStartPos = $pos;
                }
                if (null === $extraLeft && null !== $extraRight) {
                    // If inserting on the right only, skipping whitespace looks better
                    $subStartPos = $this->origTokens->skipRightWhitespace($subStartPos);
                }
                $subEndPos = $subStartPos - 1;
            }
            if (null === $subNode) {
                // A node has been removed, check if we have removal information for it
                $key = $type . '->' . $subNodeName;
                if (!isset($this->removalMap[$key])) {
                    return $this->pFallback($fallbackNode);
                }
                // Adjust positions to account for additional tokens that must be skipped
                $removalInfo = $this->removalMap[$key];
                if (isset($removalInfo['left'])) {
                    $subStartPos = $this->origTokens->skipLeft($subStartPos - 1, $removalInfo['left']) + 1;
                }
                if (isset($removalInfo['right'])) {
                    $subEndPos = $this->origTokens->skipRight($subEndPos + 1, $removalInfo['right']) - 1;
                }
            }
            $result .= $this->origTokens->getTokenCode($pos, $subStartPos, $indentAdjustment);
            if (null !== $subNode) {
                $result .= $extraLeft;
                $origIndentLevel = $this->indentLevel;
                $this->setIndentLevel($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment);
                // If it's the same node that was previously in this position, it certainly doesn't
                // need fixup. It's important to check this here, because our fixup checks are more
                // conservative than strictly necessary.
                if (isset($fixupInfo[$subNodeName]) && $subNode->getAttribute('origNode') !== $origSubNode) {
                    $fixup = $fixupInfo[$subNodeName];
                    $res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos);
                } else {
                    $res = $this->p($subNode, \true);
                }
                $this->safeAppend($result, $res);
                $this->setIndentLevel($origIndentLevel);
                $result .= $extraRight;
            }
            $pos = $subEndPos + 1;
        }
        $result .= $this->origTokens->getTokenCode($pos, $endPos + 1, $indentAdjustment);
        return $result;
    }
    /**
     * Perform a format-preserving pretty print of an array.
     *
     * @param array       $nodes            New nodes
     * @param array       $origNodes        Original nodes
     * @param int         $pos              Current token position (updated by reference)
     * @param int         $indentAdjustment Adjustment for indentation
     * @param string      $parentNodeType   Type of the containing node.
     * @param string      $subNodeName      Name of array subnode.
     * @param null|int    $fixup            Fixup information for array item nodes
     *
     * @return null|string Result of pretty print or null if cannot preserve formatting
     */
    protected function pArray(array $nodes, array $origNodes, int &$pos, int $indentAdjustment, string $parentNodeType, string $subNodeName, $fixup)
    {
        $diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes);
        $mapKey = $parentNodeType . '->' . $subNodeName;
        $insertStr = $this->listInsertionMap[$mapKey] ?? null;
        $isStmtList = $subNodeName === 'stmts';
        $beforeFirstKeepOrReplace = \true;
        $skipRemovedNode = \false;
        $delayedAdd = [];
        $lastElemIndentLevel = $this->indentLevel;
        $insertNewline = \false;
        if ($insertStr === "\n") {
            $insertStr = '';
            $insertNewline = \true;
        }
        if ($isStmtList && \count($origNodes) === 1 && \count($nodes) !== 1) {
            $startPos = $origNodes[0]->getStartTokenPos();
            $endPos = $origNodes[0]->getEndTokenPos();
            \assert($startPos >= 0 && $endPos >= 0);
            if (!$this->origTokens->haveBraces($startPos, $endPos)) {
                // This was a single statement without braces, but either additional statements
                // have been added, or the single statement has been removed. This requires the
                // addition of braces. For now fall back.
                // TODO: Try to preserve formatting
                return null;
            }
        }
        $result = '';
        foreach ($diff as $i => $diffElem) {
            $diffType = $diffElem->type;
            /** @var Node|null $arrItem */
            $arrItem = $diffElem->new;
            /** @var Node|null $origArrItem */
            $origArrItem = $diffElem->old;
            if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) {
                $beforeFirstKeepOrReplace = \false;
                if ($origArrItem === null || $arrItem === null) {
                    // We can only handle the case where both are null
                    if ($origArrItem === $arrItem) {
                        continue;
                    }
                    return null;
                }
                if (!$arrItem instanceof Node || !$origArrItem instanceof Node) {
                    // We can only deal with nodes. This can occur for Names, which use string arrays.
                    return null;
                }
                $itemStartPos = $origArrItem->getStartTokenPos();
                $itemEndPos = $origArrItem->getEndTokenPos();
                \assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos);
                $origIndentLevel = $this->indentLevel;
                $lastElemIndentLevel = $this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment;
                $this->setIndentLevel($lastElemIndentLevel);
                $comments = $arrItem->getComments();
                $origComments = $origArrItem->getComments();
                $commentStartPos = $origComments ? $origComments[0]->getStartTokenPos() : $itemStartPos;
                \assert($commentStartPos >= 0);
                if ($commentStartPos < $pos) {
                    // Comments may be assigned to multiple nodes if they start at the same position.
                    // Make sure we don't try to print them multiple times.
                    $commentStartPos = $itemStartPos;
                }
                if ($skipRemovedNode) {
                    if ($isStmtList && ($this->origTokens->haveBracesInRange($pos, $itemStartPos) || $this->origTokens->haveTagInRange($pos, $itemStartPos))) {
                        // We'd remove the brace of a code block.
                        // TODO: Preserve formatting.
                        $this->setIndentLevel($origIndentLevel);
                        return null;
                    }
                } else {
                    $result .= $this->origTokens->getTokenCode($pos, $commentStartPos, $indentAdjustment);
                }
                if (!empty($delayedAdd)) {
                    /** @var Node $delayedAddNode */
                    foreach ($delayedAdd as $delayedAddNode) {
                        if ($insertNewline) {
                            $delayedAddComments = $delayedAddNode->getComments();
                            if ($delayedAddComments) {
                                $result .= $this->pComments($delayedAddComments) . $this->nl;
                            }
                        }
                        $this->safeAppend($result, $this->p($delayedAddNode, \true));
                        if ($insertNewline) {
                            $result .= $insertStr . $this->nl;
                        } else {
                            $result .= $insertStr;
                        }
                    }
                    $delayedAdd = [];
                }
                if ($comments !== $origComments) {
                    if ($comments) {
                        $result .= $this->pComments($comments) . $this->nl;
                    }
                } else {
                    $result .= $this->origTokens->getTokenCode($commentStartPos, $itemStartPos, $indentAdjustment);
                }
                // If we had to remove anything, we have done so now.
                $skipRemovedNode = \false;
            } elseif ($diffType === DiffElem::TYPE_ADD) {
                if (null === $insertStr) {
                    // We don't have insertion information for this list type
                    return null;
                }
                // We go multiline if the original code was multiline,
                // or if it's an array item with a comment above it.
                if ($insertStr === ', ' && ($this->isMultiline($origNodes) || $arrItem->getComments())) {
                    $insertStr = ',';
                    $insertNewline = \true;
                }
                if ($beforeFirstKeepOrReplace) {
                    // Will be inserted at the next "replace" or "keep" element
                    $delayedAdd[] = $arrItem;
                    continue;
                }
                $itemStartPos = $pos;
                $itemEndPos = $pos - 1;
                $origIndentLevel = $this->indentLevel;
                $this->setIndentLevel($lastElemIndentLevel);
                if ($insertNewline) {
                    $result .= $insertStr . $this->nl;
                    $comments = $arrItem->getComments();
                    if ($comments) {
                        $result .= $this->pComments($comments) . $this->nl;
                    }
                } else {
                    $result .= $insertStr;
                }
            } elseif ($diffType === DiffElem::TYPE_REMOVE) {
                if (!$origArrItem instanceof Node) {
                    // We only support removal for nodes
                    return null;
                }
                $itemStartPos = $origArrItem->getStartTokenPos();
                $itemEndPos = $origArrItem->getEndTokenPos();
                \assert($itemStartPos >= 0 && $itemEndPos >= 0);
                // Consider comments part of the node.
                $origComments = $origArrItem->getComments();
                if ($origComments) {
                    $itemStartPos = $origComments[0]->getStartTokenPos();
                }
                if ($i === 0) {
                    // If we're removing from the start, keep the tokens before the node and drop those after it,
                    // instead of the other way around.
                    $result .= $this->origTokens->getTokenCode($pos, $itemStartPos, $indentAdjustment);
                    $skipRemovedNode = \true;
                } else {
                    if ($isStmtList && ($this->origTokens->haveBracesInRange($pos, $itemStartPos) || $this->origTokens->haveTagInRange($pos, $itemStartPos))) {
                        // We'd remove the brace of a code block.
                        // TODO: Preserve formatting.
                        return null;
                    }
                }
                $pos = $itemEndPos + 1;
                continue;
            } else {
                throw new \Exception("Shouldn't happen");
            }
            if (null !== $fixup && $arrItem->getAttribute('origNode') !== $origArrItem) {
                $res = $this->pFixup($fixup, $arrItem, null, $itemStartPos, $itemEndPos);
            } else {
                $res = $this->p($arrItem, \true);
            }
            $this->safeAppend($result, $res);
            $this->setIndentLevel($origIndentLevel);
            $pos = $itemEndPos + 1;
        }
        if ($skipRemovedNode) {
            // TODO: Support removing single node.
            return null;
        }
        if (!empty($delayedAdd)) {
            if (!isset($this->emptyListInsertionMap[$mapKey])) {
                return null;
            }
            list($findToken, $extraLeft, $extraRight) = $this->emptyListInsertionMap[$mapKey];
            if (null !== $findToken) {
                $insertPos = $this->origTokens->findRight($pos, $findToken) + 1;
                $result .= $this->origTokens->getTokenCode($pos, $insertPos, $indentAdjustment);
                $pos = $insertPos;
            }
            $first = \true;
            $result .= $extraLeft;
            foreach ($delayedAdd as $delayedAddNode) {
                if (!$first) {
                    $result .= $insertStr;
                    if ($insertNewline) {
                        $result .= $this->nl;
                    }
                }
                $result .= $this->p($delayedAddNode, \true);
                $first = \false;
            }
            $result .= $extraRight === "\n" ? $this->nl : $extraRight;
        }
        return $result;
    }
    /**
     * Print node with fixups.
     *
     * Fixups here refer to the addition of extra parentheses, braces or other characters, that
     * are required to preserve program semantics in a certain context (e.g. to maintain precedence
     * or because only certain expressions are allowed in certain places).
     *
     * @param int         $fixup       Fixup type
     * @param Node        $subNode     Subnode to print
     * @param string|null $parentClass Class of parent node
     * @param int         $subStartPos Original start pos of subnode
     * @param int         $subEndPos   Original end pos of subnode
     *
     * @return string Result of fixed-up print of subnode
     */
    protected function pFixup(int $fixup, Node $subNode, $parentClass, int $subStartPos, int $subEndPos) : string
    {
        switch ($fixup) {
            case self::FIXUP_PREC_LEFT:
            case self::FIXUP_PREC_RIGHT:
                if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) {
                    list($precedence, $associativity) = $this->precedenceMap[$parentClass];
                    return $this->pPrec($subNode, $precedence, $associativity, $fixup === self::FIXUP_PREC_LEFT ? -1 : 1);
                }
                break;
            case self::FIXUP_CALL_LHS:
                if ($this->callLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
                    return '(' . $this->p($subNode) . ')';
                }
                break;
            case self::FIXUP_DEREF_LHS:
                if ($this->dereferenceLhsRequiresParens($subNode) && !$this->origTokens->haveParens($subStartPos, $subEndPos)) {
                    return '(' . $this->p($subNode) . ')';
                }
                break;
            case self::FIXUP_BRACED_NAME:
            case self::FIXUP_VAR_BRACED_NAME:
                if ($subNode instanceof Expr && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) {
                    return ($fixup === self::FIXUP_VAR_BRACED_NAME ? '$' : '') . '{' . $this->p($subNode) . '}';
                }
                break;
            case self::FIXUP_ENCAPSED:
                if (!$subNode instanceof Scalar\EncapsedStringPart && !$this->origTokens->haveBraces($subStartPos, $subEndPos)) {
                    return '{' . $this->p($subNode) . '}';
                }
                break;
            default:
                throw new \Exception('Cannot happen');
        }
        // Nothing special to do
        return $this->p($subNode);
    }
    /**
     * Appends to a string, ensuring whitespace between label characters.
     *
     * Example: "echo" and "$x" result in "echo$x", but "echo" and "x" result in "echo x".
     * Without safeAppend the result would be "echox", which does not preserve semantics.
     *
     * @param string $str
     * @param string $append
     */
    protected function safeAppend(string &$str, string $append)
    {
        if ($str === "") {
            $str = $append;
            return;
        }
        if ($append === "") {
            return;
        }
        if (!$this->labelCharMap[$append[0]] || !$this->labelCharMap[$str[\strlen($str) - 1]]) {
            $str .= $append;
        } else {
            $str .= " " . $append;
        }
    }
    /**
     * Determines whether the LHS of a call must be wrapped in parenthesis.
     *
     * @param Node $node LHS of a call
     *
     * @return bool Whether parentheses are required
     */
    protected function callLhsRequiresParens(Node $node) : bool
    {
        return !($node instanceof Node\Name || $node instanceof Expr\Variable || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\NullsafeMethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_);
    }
    /**
     * Determines whether the LHS of a dereferencing operation must be wrapped in parenthesis.
     *
     * @param Node $node LHS of dereferencing operation
     *
     * @return bool Whether parentheses are required
     */
    protected function dereferenceLhsRequiresParens(Node $node) : bool
    {
        return !($node instanceof Expr\Variable || $node instanceof Node\Name || $node instanceof Expr\ArrayDimFetch || $node instanceof Expr\PropertyFetch || $node instanceof Expr\NullsafePropertyFetch || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\FuncCall || $node instanceof Expr\MethodCall || $node instanceof Expr\NullsafeMethodCall || $node instanceof Expr\StaticCall || $node instanceof Expr\Array_ || $node instanceof Scalar\String_ || $node instanceof Expr\ConstFetch || $node instanceof Expr\ClassConstFetch);
    }
    /**
     * Print modifiers, including trailing whitespace.
     *
     * @param int $modifiers Modifier mask to print
     *
     * @return string Printed modifiers
     */
    protected function pModifiers(int $modifiers)
    {
        return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '') . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '') . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '') . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '') . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '') . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : '') . ($modifiers & Stmt\Class_::MODIFIER_READONLY ? 'readonly ' : '');
    }
    /**
     * Determine whether a list of nodes uses multiline formatting.
     *
     * @param (Node|null)[] $nodes Node list
     *
     * @return bool Whether multiline formatting is used
     */
    protected function isMultiline(array $nodes) : bool
    {
        if (\count($nodes) < 2) {
            return \false;
        }
        $pos = -1;
        foreach ($nodes as $node) {
            if (null === $node) {
                continue;
            }
            $endPos = $node->getEndTokenPos() + 1;
            if ($pos >= 0) {
                $text = $this->origTokens->getTokenCode($pos, $endPos, 0);
                if (\false === \strpos($text, "\n")) {
                    // We require that a newline is present between *every* item. If the formatting
                    // is inconsistent, with only some items having newlines, we don't consider it
                    // as multiline
                    return \false;
                }
            }
            $pos = $endPos;
        }
        return \true;
    }
    /**
     * Lazily initializes label char map.
     *
     * The label char map determines whether a certain character may occur in a label.
     */
    protected function initializeLabelCharMap()
    {
        if ($this->labelCharMap) {
            return;
        }
        $this->labelCharMap = [];
        for ($i = 0; $i < 256; $i++) {
            // Since PHP 7.1 The lower range is 0x80. However, we also want to support code for
            // older versions.
            $chr = \chr($i);
            $this->labelCharMap[$chr] = $i >= 0x7f || \ctype_alnum($chr);
        }
    }
    /**
     * Lazily initializes node list differ.
     *
     * The node list differ is used to determine differences between two array subnodes.
     */
    protected function initializeNodeListDiffer()
    {
        if ($this->nodeListDiffer) {
            return;
        }
        $this->nodeListDiffer = new Internal\Differ(function ($a, $b) {
            if ($a instanceof Node && $b instanceof Node) {
                return $a === $b->getAttribute('origNode');
            }
            // Can happen for array destructuring
            return $a === null && $b === null;
        });
    }
    /**
     * Lazily initializes fixup map.
     *
     * The fixup map is used to determine whether a certain subnode of a certain node may require
     * some kind of "fixup" operation, e.g. the addition of parenthesis or braces.
     */
    protected function initializeFixupMap()
    {
        if ($this->fixupMap) {
            return;
        }
        $this->fixupMap = [
            Expr\PreInc::class => ['var' => self::FIXUP_PREC_RIGHT],
            Expr\PreDec::class => ['var' => self::FIXUP_PREC_RIGHT],
            Expr\PostInc::class => ['var' => self::FIXUP_PREC_LEFT],
            Expr\PostDec::class => ['var' => self::FIXUP_PREC_LEFT],
            Expr\Instanceof_::class => ['expr' => self::FIXUP_PREC_LEFT, 'class' => self::FIXUP_PREC_RIGHT],
            Expr\Ternary::class => ['cond' => self::FIXUP_PREC_LEFT, 'else' => self::FIXUP_PREC_RIGHT],
            Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS],
            Expr\StaticCall::class => ['class' => self::FIXUP_DEREF_LHS],
            Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS],
            Expr\ClassConstFetch::class => ['var' => self::FIXUP_DEREF_LHS],
            Expr\New_::class => ['class' => self::FIXUP_DEREF_LHS],
            // TODO: FIXUP_NEW_VARIABLE
            Expr\MethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME],
            Expr\NullsafeMethodCall::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME],
            Expr\StaticPropertyFetch::class => ['class' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_VAR_BRACED_NAME],
            Expr\PropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME],
            Expr\NullsafePropertyFetch::class => ['var' => self::FIXUP_DEREF_LHS, 'name' => self::FIXUP_BRACED_NAME],
            Scalar\Encapsed::class => ['parts' => self::FIXUP_ENCAPSED],
        ];
        $binaryOps = [BinaryOp\Pow::class, BinaryOp\Mul::class, BinaryOp\Div::class, BinaryOp\Mod::class, BinaryOp\Plus::class, BinaryOp\Minus::class, BinaryOp\Concat::class, BinaryOp\ShiftLeft::class, BinaryOp\ShiftRight::class, BinaryOp\Smaller::class, BinaryOp\SmallerOrEqual::class, BinaryOp\Greater::class, BinaryOp\GreaterOrEqual::class, BinaryOp\Equal::class, BinaryOp\NotEqual::class, BinaryOp\Identical::class, BinaryOp\NotIdentical::class, BinaryOp\Spaceship::class, BinaryOp\BitwiseAnd::class, BinaryOp\BitwiseXor::class, BinaryOp\BitwiseOr::class, BinaryOp\BooleanAnd::class, BinaryOp\BooleanOr::class, BinaryOp\Coalesce::class, BinaryOp\LogicalAnd::class, BinaryOp\LogicalXor::class, BinaryOp\LogicalOr::class];
        foreach ($binaryOps as $binaryOp) {
            $this->fixupMap[$binaryOp] = ['left' => self::FIXUP_PREC_LEFT, 'right' => self::FIXUP_PREC_RIGHT];
        }
        $assignOps = [Expr\Assign::class, Expr\AssignRef::class, AssignOp\Plus::class, AssignOp\Minus::class, AssignOp\Mul::class, AssignOp\Div::class, AssignOp\Concat::class, AssignOp\Mod::class, AssignOp\BitwiseAnd::class, AssignOp\BitwiseOr::class, AssignOp\BitwiseXor::class, AssignOp\ShiftLeft::class, AssignOp\ShiftRight::class, AssignOp\Pow::class, AssignOp\Coalesce::class];
        foreach ($assignOps as $assignOp) {
            $this->fixupMap[$assignOp] = ['var' => self::FIXUP_PREC_LEFT, 'expr' => self::FIXUP_PREC_RIGHT];
        }
        $prefixOps = [Expr\BitwiseNot::class, Expr\BooleanNot::class, Expr\UnaryPlus::class, Expr\UnaryMinus::class, Cast\Int_::class, Cast\Double::class, Cast\String_::class, Cast\Array_::class, Cast\Object_::class, Cast\Bool_::class, Cast\Unset_::class, Expr\ErrorSuppress::class, Expr\YieldFrom::class, Expr\Print_::class, Expr\Include_::class];
        foreach ($prefixOps as $prefixOp) {
            $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_RIGHT];
        }
    }
    /**
     * Lazily initializes the removal map.
     *
     * The removal map is used to determine which additional tokens should be removed when a
     * certain node is replaced by null.
     */
    protected function initializeRemovalMap()
    {
        if ($this->removalMap) {
            return;
        }
        $stripBoth = ['left' => \T_WHITESPACE, 'right' => \T_WHITESPACE];
        $stripLeft = ['left' => \T_WHITESPACE];
        $stripRight = ['right' => \T_WHITESPACE];
        $stripDoubleArrow = ['right' => \T_DOUBLE_ARROW];
        $stripColon = ['left' => ':'];
        $stripEquals = ['left' => '='];
        $this->removalMap = ['Expr_ArrayDimFetch->dim' => $stripBoth, 'Expr_ArrayItem->key' => $stripDoubleArrow, 'Expr_ArrowFunction->returnType' => $stripColon, 'Expr_Closure->returnType' => $stripColon, 'Expr_Exit->expr' => $stripBoth, 'Expr_Ternary->if' => $stripBoth, 'Expr_Yield->key' => $stripDoubleArrow, 'Expr_Yield->value' => $stripBoth, 'Param->type' => $stripRight, 'Param->default' => $stripEquals, 'Stmt_Break->num' => $stripBoth, 'Stmt_Catch->var' => $stripLeft, 'Stmt_ClassMethod->returnType' => $stripColon, 'Stmt_Class->extends' => ['left' => \T_EXTENDS], 'Stmt_Enum->scalarType' => $stripColon, 'Stmt_EnumCase->expr' => $stripEquals, 'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS], 'Stmt_Continue->num' => $stripBoth, 'Stmt_Foreach->keyVar' => $stripDoubleArrow, 'Stmt_Function->returnType' => $stripColon, 'Stmt_If->else' => $stripLeft, 'Stmt_Namespace->name' => $stripLeft, 'Stmt_Property->type' => $stripRight, 'Stmt_PropertyProperty->default' => $stripEquals, 'Stmt_Return->expr' => $stripBoth, 'Stmt_StaticVar->default' => $stripEquals, 'Stmt_TraitUseAdaptation_Alias->newName' => $stripLeft, 'Stmt_TryCatch->finally' => $stripLeft];
    }
    protected function initializeInsertionMap()
    {
        if ($this->insertionMap) {
            return;
        }
        // TODO: "yield" where both key and value are inserted doesn't work
        // [$find, $beforeToken, $extraLeft, $extraRight]
        $this->insertionMap = [
            'Expr_ArrayDimFetch->dim' => ['[', \false, null, null],
            'Expr_ArrayItem->key' => [null, \false, null, ' => '],
            'Expr_ArrowFunction->returnType' => [')', \false, ' : ', null],
            'Expr_Closure->returnType' => [')', \false, ' : ', null],
            'Expr_Ternary->if' => ['?', \false, ' ', ' '],
            'Expr_Yield->key' => [\T_YIELD, \false, null, ' => '],
            'Expr_Yield->value' => [\T_YIELD, \false, ' ', null],
            'Param->type' => [null, \false, null, ' '],
            'Param->default' => [null, \false, ' = ', null],
            'Stmt_Break->num' => [\T_BREAK, \false, ' ', null],
            'Stmt_Catch->var' => [null, \false, ' ', null],
            'Stmt_ClassMethod->returnType' => [')', \false, ' : ', null],
            'Stmt_Class->extends' => [null, \false, ' extends ', null],
            'Stmt_Enum->scalarType' => [null, \false, ' : ', null],
            'Stmt_EnumCase->expr' => [null, \false, ' = ', null],
            'Expr_PrintableNewAnonClass->extends' => [null, ' extends ', null],
            'Stmt_Continue->num' => [\T_CONTINUE, \false, ' ', null],
            'Stmt_Foreach->keyVar' => [\T_AS, \false, null, ' => '],
            'Stmt_Function->returnType' => [')', \false, ' : ', null],
            'Stmt_If->else' => [null, \false, ' ', null],
            'Stmt_Namespace->name' => [\T_NAMESPACE, \false, ' ', null],
            'Stmt_Property->type' => [\T_VARIABLE, \true, null, ' '],
            'Stmt_PropertyProperty->default' => [null, \false, ' = ', null],
            'Stmt_Return->expr' => [\T_RETURN, \false, ' ', null],
            'Stmt_StaticVar->default' => [null, \false, ' = ', null],
            //'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, false, ' ', null], // TODO
            'Stmt_TryCatch->finally' => [null, \false, ' ', null],
        ];
    }
    protected function initializeListInsertionMap()
    {
        if ($this->listInsertionMap) {
            return;
        }
        $this->listInsertionMap = [
            // special
            //'Expr_ShellExec->parts' => '', // TODO These need to be treated more carefully
            //'Scalar_Encapsed->parts' => '',
            'Stmt_Catch->types' => '|',
            'UnionType->types' => '|',
            'IntersectionType->types' => '&',
            'Stmt_If->elseifs' => ' ',
            'Stmt_TryCatch->catches' => ' ',
            // comma-separated lists
            'Expr_Array->items' => ', ',
            'Expr_ArrowFunction->params' => ', ',
            'Expr_Closure->params' => ', ',
            'Expr_Closure->uses' => ', ',
            'Expr_FuncCall->args' => ', ',
            'Expr_Isset->vars' => ', ',
            'Expr_List->items' => ', ',
            'Expr_MethodCall->args' => ', ',
            'Expr_NullsafeMethodCall->args' => ', ',
            'Expr_New->args' => ', ',
            'Expr_PrintableNewAnonClass->args' => ', ',
            'Expr_StaticCall->args' => ', ',
            'Stmt_ClassConst->consts' => ', ',
            'Stmt_ClassMethod->params' => ', ',
            'Stmt_Class->implements' => ', ',
            'Stmt_Enum->implements' => ', ',
            'Expr_PrintableNewAnonClass->implements' => ', ',
            'Stmt_Const->consts' => ', ',
            'Stmt_Declare->declares' => ', ',
            'Stmt_Echo->exprs' => ', ',
            'Stmt_For->init' => ', ',
            'Stmt_For->cond' => ', ',
            'Stmt_For->loop' => ', ',
            'Stmt_Function->params' => ', ',
            'Stmt_Global->vars' => ', ',
            'Stmt_GroupUse->uses' => ', ',
            'Stmt_Interface->extends' => ', ',
            'Stmt_Match->arms' => ', ',
            'Stmt_Property->props' => ', ',
            'Stmt_StaticVar->vars' => ', ',
            'Stmt_TraitUse->traits' => ', ',
            'Stmt_TraitUseAdaptation_Precedence->insteadof' => ', ',
            'Stmt_Unset->vars' => ', ',
            'Stmt_Use->uses' => ', ',
            'MatchArm->conds' => ', ',
            'AttributeGroup->attrs' => ', ',
            // statement lists
            'Expr_Closure->stmts' => "\n",
            'Stmt_Case->stmts' => "\n",
            'Stmt_Catch->stmts' => "\n",
            'Stmt_Class->stmts' => "\n",
            'Stmt_Enum->stmts' => "\n",
            'Expr_PrintableNewAnonClass->stmts' => "\n",
            'Stmt_Interface->stmts' => "\n",
            'Stmt_Trait->stmts' => "\n",
            'Stmt_ClassMethod->stmts' => "\n",
            'Stmt_Declare->stmts' => "\n",
            'Stmt_Do->stmts' => "\n",
            'Stmt_ElseIf->stmts' => "\n",
            'Stmt_Else->stmts' => "\n",
            'Stmt_Finally->stmts' => "\n",
            'Stmt_Foreach->stmts' => "\n",
            'Stmt_For->stmts' => "\n",
            'Stmt_Function->stmts' => "\n",
            'Stmt_If->stmts' => "\n",
            'Stmt_Namespace->stmts' => "\n",
            'Stmt_Class->attrGroups' => "\n",
            'Stmt_Enum->attrGroups' => "\n",
            'Stmt_EnumCase->attrGroups' => "\n",
            'Stmt_Interface->attrGroups' => "\n",
            'Stmt_Trait->attrGroups' => "\n",
            'Stmt_Function->attrGroups' => "\n",
            'Stmt_ClassMethod->attrGroups' => "\n",
            'Stmt_ClassConst->attrGroups' => "\n",
            'Stmt_Property->attrGroups' => "\n",
            'Expr_PrintableNewAnonClass->attrGroups' => ' ',
            'Expr_Closure->attrGroups' => ' ',
            'Expr_ArrowFunction->attrGroups' => ' ',
            'Param->attrGroups' => ' ',
            'Stmt_Switch->cases' => "\n",
            'Stmt_TraitUse->adaptations' => "\n",
            'Stmt_TryCatch->stmts' => "\n",
            'Stmt_While->stmts' => "\n",
            // dummy for top-level context
            'File->stmts' => "\n",
        ];
    }
    protected function initializeEmptyListInsertionMap()
    {
        if ($this->emptyListInsertionMap) {
            return;
        }
        // TODO Insertion into empty statement lists.
        // [$find, $extraLeft, $extraRight]
        $this->emptyListInsertionMap = ['Expr_ArrowFunction->params' => ['(', '', ''], 'Expr_Closure->uses' => [')', ' use(', ')'], 'Expr_Closure->params' => ['(', '', ''], 'Expr_FuncCall->args' => ['(', '', ''], 'Expr_MethodCall->args' => ['(', '', ''], 'Expr_NullsafeMethodCall->args' => ['(', '', ''], 'Expr_New->args' => ['(', '', ''], 'Expr_PrintableNewAnonClass->args' => ['(', '', ''], 'Expr_PrintableNewAnonClass->implements' => [null, ' implements ', ''], 'Expr_StaticCall->args' => ['(', '', ''], 'Stmt_Class->implements' => [null, ' implements ', ''], 'Stmt_Enum->implements' => [null, ' implements ', ''], 'Stmt_ClassMethod->params' => ['(', '', ''], 'Stmt_Interface->extends' => [null, ' extends ', ''], 'Stmt_Function->params' => ['(', '', ''], 'Stmt_Interface->attrGroups' => [null, '', "\n"], 'Stmt_Class->attrGroups' => [null, '', "\n"], 'Stmt_ClassConst->attrGroups' => [null, '', "\n"], 'Stmt_ClassMethod->attrGroups' => [null, '', "\n"], 'Stmt_Function->attrGroups' => [null, '', "\n"], 'Stmt_Property->attrGroups' => [null, '', "\n"], 'Stmt_Trait->attrGroups' => [null, '', "\n"], 'Expr_ArrowFunction->attrGroups' => [null, '', ' '], 'Expr_Closure->attrGroups' => [null, '', ' '], 'Expr_PrintableNewAnonClass->attrGroups' => [\T_NEW, ' ', '']];
    }
    protected function initializeModifierChangeMap()
    {
        if ($this->modifierChangeMap) {
            return;
        }
        $this->modifierChangeMap = ['Stmt_ClassConst->flags' => \T_CONST, 'Stmt_ClassMethod->flags' => \T_FUNCTION, 'Stmt_Class->flags' => \T_CLASS, 'Stmt_Property->flags' => \T_VARIABLE, 'Param->flags' => \T_VARIABLE];
        // List of integer subnodes that are not modifiers:
        // Expr_Include->type
        // Stmt_GroupUse->type
        // Stmt_Use->type
        // Stmt_UseUse->type
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

class Comment implements \JsonSerializable
{
    protected $text;
    protected $startLine;
    protected $startFilePos;
    protected $startTokenPos;
    protected $endLine;
    protected $endFilePos;
    protected $endTokenPos;
    /**
     * Constructs a comment node.
     *
     * @param string $text          Comment text (including comment delimiters like /*)
     * @param int    $startLine     Line number the comment started on
     * @param int    $startFilePos  File offset the comment started on
     * @param int    $startTokenPos Token offset the comment started on
     */
    public function __construct(string $text, int $startLine = -1, int $startFilePos = -1, int $startTokenPos = -1, int $endLine = -1, int $endFilePos = -1, int $endTokenPos = -1)
    {
        $this->text = $text;
        $this->startLine = $startLine;
        $this->startFilePos = $startFilePos;
        $this->startTokenPos = $startTokenPos;
        $this->endLine = $endLine;
        $this->endFilePos = $endFilePos;
        $this->endTokenPos = $endTokenPos;
    }
    /**
     * Gets the comment text.
     *
     * @return string The comment text (including comment delimiters like /*)
     */
    public function getText() : string
    {
        return $this->text;
    }
    /**
     * Gets the line number the comment started on.
     *
     * @return int Line number (or -1 if not available)
     */
    public function getStartLine() : int
    {
        return $this->startLine;
    }
    /**
     * Gets the file offset the comment started on.
     *
     * @return int File offset (or -1 if not available)
     */
    public function getStartFilePos() : int
    {
        return $this->startFilePos;
    }
    /**
     * Gets the token offset the comment started on.
     *
     * @return int Token offset (or -1 if not available)
     */
    public function getStartTokenPos() : int
    {
        return $this->startTokenPos;
    }
    /**
     * Gets the line number the comment ends on.
     *
     * @return int Line number (or -1 if not available)
     */
    public function getEndLine() : int
    {
        return $this->endLine;
    }
    /**
     * Gets the file offset the comment ends on.
     *
     * @return int File offset (or -1 if not available)
     */
    public function getEndFilePos() : int
    {
        return $this->endFilePos;
    }
    /**
     * Gets the token offset the comment ends on.
     *
     * @return int Token offset (or -1 if not available)
     */
    public function getEndTokenPos() : int
    {
        return $this->endTokenPos;
    }
    /**
     * Gets the line number the comment started on.
     *
     * @deprecated Use getStartLine() instead
     *
     * @return int Line number
     */
    public function getLine() : int
    {
        return $this->startLine;
    }
    /**
     * Gets the file offset the comment started on.
     *
     * @deprecated Use getStartFilePos() instead
     *
     * @return int File offset
     */
    public function getFilePos() : int
    {
        return $this->startFilePos;
    }
    /**
     * Gets the token offset the comment started on.
     *
     * @deprecated Use getStartTokenPos() instead
     *
     * @return int Token offset
     */
    public function getTokenPos() : int
    {
        return $this->startTokenPos;
    }
    /**
     * Gets the comment text.
     *
     * @return string The comment text (including comment delimiters like /*)
     */
    public function __toString() : string
    {
        return $this->text;
    }
    /**
     * Gets the reformatted comment text.
     *
     * "Reformatted" here means that we try to clean up the whitespace at the
     * starts of the lines. This is necessary because we receive the comments
     * without trailing whitespace on the first line, but with trailing whitespace
     * on all subsequent lines.
     *
     * @return mixed|string
     */
    public function getReformattedText()
    {
        $text = \trim($this->text);
        $newlinePos = \strpos($text, "\n");
        if (\false === $newlinePos) {
            // Single line comments don't need further processing
            return $text;
        } elseif (\preg_match('((*BSR_ANYCRLF)(*ANYCRLF)^.*(?:\\R\\s+\\*.*)+$)', $text)) {
            // Multi line comment of the type
            //
            //     /*
            //      * Some text.
            //      * Some more text.
            //      */
            //
            // is handled by replacing the whitespace sequences before the * by a single space
            return \preg_replace('(^\\s+\\*)m', ' *', $this->text);
        } elseif (\preg_match('(^/\\*\\*?\\s*[\\r\\n])', $text) && \preg_match('(\\n(\\s*)\\*/$)', $text, $matches)) {
            // Multi line comment of the type
            //
            //    /*
            //        Some text.
            //        Some more text.
            //    */
            //
            // is handled by removing the whitespace sequence on the line before the closing
            // */ on all lines. So if the last line is "    */", then "    " is removed at the
            // start of all lines.
            return \preg_replace('(^' . \preg_quote($matches[1]) . ')m', '', $text);
        } elseif (\preg_match('(^/\\*\\*?\\s*(?!\\s))', $text, $matches)) {
            // Multi line comment of the type
            //
            //     /* Some text.
            //        Some more text.
            //          Indented text.
            //        Even more text. */
            //
            // is handled by removing the difference between the shortest whitespace prefix on all
            // lines and the length of the "/* " opening sequence.
            $prefixLen = $this->getShortestWhitespacePrefixLen(\substr($text, $newlinePos + 1));
            $removeLen = $prefixLen - \strlen($matches[0]);
            return \preg_replace('(^\\s{' . $removeLen . '})m', '', $text);
        }
        // No idea how to format this comment, so simply return as is
        return $text;
    }
    /**
     * Get length of shortest whitespace prefix (at the start of a line).
     *
     * If there is a line with no prefix whitespace, 0 is a valid return value.
     *
     * @param string $str String to check
     * @return int Length in characters. Tabs count as single characters.
     */
    private function getShortestWhitespacePrefixLen(string $str) : int
    {
        $lines = \explode("\n", $str);
        $shortestPrefixLen = \INF;
        foreach ($lines as $line) {
            \preg_match('(^\\s*)', $line, $matches);
            $prefixLen = \strlen($matches[0]);
            if ($prefixLen < $shortestPrefixLen) {
                $shortestPrefixLen = $prefixLen;
            }
        }
        return $shortestPrefixLen;
    }
    /**
     * @return       array
     * @psalm-return array{nodeType:string, text:mixed, line:mixed, filePos:mixed}
     */
    public function jsonSerialize() : array
    {
        // Technically not a node, but we make it look like one anyway
        $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment';
        return [
            'nodeType' => $type,
            'text' => $this->text,
            // TODO: Rename these to include "start".
            'line' => $this->startLine,
            'filePos' => $this->startFilePos,
            'tokenPos' => $this->startTokenPos,
            'endLine' => $this->endLine,
            'endFilePos' => $this->endFilePos,
            'endTokenPos' => $this->endTokenPos,
        ];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Comment;

class Doc extends \_HumbugBox1cb33d1f20f1\PhpParser\Comment
{
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;
/**
 * Error handler that collects all errors into an array.
 *
 * This allows graceful handling of errors.
 */
class Collecting implements ErrorHandler
{
    /** @var Error[] Collected errors */
    private $errors = [];
    public function handleError(Error $error)
    {
        $this->errors[] = $error;
    }
    /**
     * Get collected errors.
     *
     * @return Error[]
     */
    public function getErrors() : array
    {
        return $this->errors;
    }
    /**
     * Check whether there are any errors.
     *
     * @return bool
     */
    public function hasErrors() : bool
    {
        return !empty($this->errors);
    }
    /**
     * Reset/clear collected errors.
     */
    public function clearErrors()
    {
        $this->errors = [];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;
/**
 * Error handler that handles all errors by throwing them.
 *
 * This is the default strategy used by all components.
 */
class Throwing implements ErrorHandler
{
    public function handleError(Error $error)
    {
        throw $error;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\PhpParser;

use function array_merge;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
/**
 * Evaluates constant expressions.
 *
 * This evaluator is able to evaluate all constant expressions (as defined by PHP), which can be
 * evaluated without further context. If a subexpression is not of this type, a user-provided
 * fallback evaluator is invoked. To support all constant expressions that are also supported by
 * PHP (and not already handled by this class), the fallback evaluator must be able to handle the
 * following node types:
 *
 *  * All Scalar\MagicConst\* nodes.
 *  * Expr\ConstFetch nodes. Only null/false/true are already handled by this class.
 *  * Expr\ClassConstFetch nodes.
 *
 * The fallback evaluator should throw ConstExprEvaluationException for nodes it cannot evaluate.
 *
 * The evaluation is dependent on runtime configuration in two respects: Firstly, floating
 * point to string conversions are affected by the precision ini setting. Secondly, they are also
 * affected by the LC_NUMERIC locale.
 */
class ConstExprEvaluator
{
    private $fallbackEvaluator;
    /**
     * Create a constant expression evaluator.
     *
     * The provided fallback evaluator is invoked whenever a subexpression cannot be evaluated. See
     * class doc comment for more information.
     *
     * @param callable|null $fallbackEvaluator To call if subexpression cannot be evaluated
     */
    public function __construct(callable $fallbackEvaluator = null)
    {
        $this->fallbackEvaluator = $fallbackEvaluator ?? function (Expr $expr) {
            throw new ConstExprEvaluationException("Expression of type {$expr->getType()} cannot be evaluated");
        };
    }
    /**
     * Silently evaluates a constant expression into a PHP value.
     *
     * Thrown Errors, warnings or notices will be converted into a ConstExprEvaluationException.
     * The original source of the exception is available through getPrevious().
     *
     * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
     * constructor will be invoked. By default, if no fallback is provided, an exception of type
     * ConstExprEvaluationException is thrown.
     *
     * See class doc comment for caveats and limitations.
     *
     * @param Expr $expr Constant expression to evaluate
     * @return mixed Result of evaluation
     *
     * @throws ConstExprEvaluationException if the expression cannot be evaluated or an error occurred
     */
    public function evaluateSilently(Expr $expr)
    {
        \set_error_handler(function ($num, $str, $file, $line) {
            throw new \ErrorException($str, 0, $num, $file, $line);
        });
        try {
            return $this->evaluate($expr);
        } catch (\Throwable $e) {
            if (!$e instanceof ConstExprEvaluationException) {
                $e = new ConstExprEvaluationException("An error occurred during constant expression evaluation", 0, $e);
            }
            throw $e;
        } finally {
            \restore_error_handler();
        }
    }
    /**
     * Directly evaluates a constant expression into a PHP value.
     *
     * May generate Error exceptions, warnings or notices. Use evaluateSilently() to convert these
     * into a ConstExprEvaluationException.
     *
     * If some part of the expression cannot be evaluated, the fallback evaluator passed to the
     * constructor will be invoked. By default, if no fallback is provided, an exception of type
     * ConstExprEvaluationException is thrown.
     *
     * See class doc comment for caveats and limitations.
     *
     * @param Expr $expr Constant expression to evaluate
     * @return mixed Result of evaluation
     *
     * @throws ConstExprEvaluationException if the expression cannot be evaluated
     */
    public function evaluateDirectly(Expr $expr)
    {
        return $this->evaluate($expr);
    }
    private function evaluate(Expr $expr)
    {
        if ($expr instanceof Scalar\LNumber || $expr instanceof Scalar\DNumber || $expr instanceof Scalar\String_) {
            return $expr->value;
        }
        if ($expr instanceof Expr\Array_) {
            return $this->evaluateArray($expr);
        }
        // Unary operators
        if ($expr instanceof Expr\UnaryPlus) {
            return +$this->evaluate($expr->expr);
        }
        if ($expr instanceof Expr\UnaryMinus) {
            return -$this->evaluate($expr->expr);
        }
        if ($expr instanceof Expr\BooleanNot) {
            return !$this->evaluate($expr->expr);
        }
        if ($expr instanceof Expr\BitwiseNot) {
            return ~$this->evaluate($expr->expr);
        }
        if ($expr instanceof Expr\BinaryOp) {
            return $this->evaluateBinaryOp($expr);
        }
        if ($expr instanceof Expr\Ternary) {
            return $this->evaluateTernary($expr);
        }
        if ($expr instanceof Expr\ArrayDimFetch && null !== $expr->dim) {
            return $this->evaluate($expr->var)[$this->evaluate($expr->dim)];
        }
        if ($expr instanceof Expr\ConstFetch) {
            return $this->evaluateConstFetch($expr);
        }
        return ($this->fallbackEvaluator)($expr);
    }
    private function evaluateArray(Expr\Array_ $expr)
    {
        $array = [];
        foreach ($expr->items as $item) {
            if (null !== $item->key) {
                $array[$this->evaluate($item->key)] = $this->evaluate($item->value);
            } elseif ($item->unpack) {
                $array = array_merge($array, $this->evaluate($item->value));
            } else {
                $array[] = $this->evaluate($item->value);
            }
        }
        return $array;
    }
    private function evaluateTernary(Expr\Ternary $expr)
    {
        if (null === $expr->if) {
            return $this->evaluate($expr->cond) ?: $this->evaluate($expr->else);
        }
        return $this->evaluate($expr->cond) ? $this->evaluate($expr->if) : $this->evaluate($expr->else);
    }
    private function evaluateBinaryOp(Expr\BinaryOp $expr)
    {
        if ($expr instanceof Expr\BinaryOp\Coalesce && $expr->left instanceof Expr\ArrayDimFetch) {
            // This needs to be special cased to respect BP_VAR_IS fetch semantics
            return $this->evaluate($expr->left->var)[$this->evaluate($expr->left->dim)] ?? $this->evaluate($expr->right);
        }
        // The evaluate() calls are repeated in each branch, because some of the operators are
        // short-circuiting and evaluating the RHS in advance may be illegal in that case
        $l = $expr->left;
        $r = $expr->right;
        switch ($expr->getOperatorSigil()) {
            case '&':
                return $this->evaluate($l) & $this->evaluate($r);
            case '|':
                return $this->evaluate($l) | $this->evaluate($r);
            case '^':
                return $this->evaluate($l) ^ $this->evaluate($r);
            case '&&':
                return $this->evaluate($l) && $this->evaluate($r);
            case '||':
                return $this->evaluate($l) || $this->evaluate($r);
            case '??':
                return $this->evaluate($l) ?? $this->evaluate($r);
            case '.':
                return $this->evaluate($l) . $this->evaluate($r);
            case '/':
                return $this->evaluate($l) / $this->evaluate($r);
            case '==':
                return $this->evaluate($l) == $this->evaluate($r);
            case '>':
                return $this->evaluate($l) > $this->evaluate($r);
            case '>=':
                return $this->evaluate($l) >= $this->evaluate($r);
            case '===':
                return $this->evaluate($l) === $this->evaluate($r);
            case 'and':
                return $this->evaluate($l) and $this->evaluate($r);
            case 'or':
                return $this->evaluate($l) or $this->evaluate($r);
            case 'xor':
                return $this->evaluate($l) xor $this->evaluate($r);
            case '-':
                return $this->evaluate($l) - $this->evaluate($r);
            case '%':
                return $this->evaluate($l) % $this->evaluate($r);
            case '*':
                return $this->evaluate($l) * $this->evaluate($r);
            case '!=':
                return $this->evaluate($l) != $this->evaluate($r);
            case '!==':
                return $this->evaluate($l) !== $this->evaluate($r);
            case '+':
                return $this->evaluate($l) + $this->evaluate($r);
            case '**':
                return $this->evaluate($l) ** $this->evaluate($r);
            case '<<':
                return $this->evaluate($l) << $this->evaluate($r);
            case '>>':
                return $this->evaluate($l) >> $this->evaluate($r);
            case '<':
                return $this->evaluate($l) < $this->evaluate($r);
            case '<=':
                return $this->evaluate($l) <= $this->evaluate($r);
            case '<=>':
                return $this->evaluate($l) <=> $this->evaluate($r);
        }
        throw new \Exception('Should not happen');
    }
    private function evaluateConstFetch(Expr\ConstFetch $expr)
    {
        $name = $expr->name->toLowerString();
        switch ($name) {
            case 'null':
                return null;
            case 'false':
                return \false;
            case 'true':
                return \true;
        }
        return ($this->fallbackEvaluator)($expr);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

interface Parser
{
    /**
     * Parses PHP code into a node tree.
     *
     * @param string $code The source code to parse
     * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults
     *                                        to ErrorHandler\Throwing.
     *
     * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and
     *                          the parser was unable to recover from an error).
     */
    public function parse(string $code, ErrorHandler $errorHandler = null);
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

class JsonDecoder
{
    /** @var \ReflectionClass[] Node type to reflection class map */
    private $reflectionClassCache;
    public function decode(string $json)
    {
        $value = \json_decode($json, \true);
        if (\json_last_error()) {
            throw new \RuntimeException('JSON decoding error: ' . \json_last_error_msg());
        }
        return $this->decodeRecursive($value);
    }
    private function decodeRecursive($value)
    {
        if (\is_array($value)) {
            if (isset($value['nodeType'])) {
                if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') {
                    return $this->decodeComment($value);
                }
                return $this->decodeNode($value);
            }
            return $this->decodeArray($value);
        }
        return $value;
    }
    private function decodeArray(array $array) : array
    {
        $decodedArray = [];
        foreach ($array as $key => $value) {
            $decodedArray[$key] = $this->decodeRecursive($value);
        }
        return $decodedArray;
    }
    private function decodeNode(array $value) : Node
    {
        $nodeType = $value['nodeType'];
        if (!\is_string($nodeType)) {
            throw new \RuntimeException('Node type must be a string');
        }
        $reflectionClass = $this->reflectionClassFromNodeType($nodeType);
        /** @var Node $node */
        $node = $reflectionClass->newInstanceWithoutConstructor();
        if (isset($value['attributes'])) {
            if (!\is_array($value['attributes'])) {
                throw new \RuntimeException('Attributes must be an array');
            }
            $node->setAttributes($this->decodeArray($value['attributes']));
        }
        foreach ($value as $name => $subNode) {
            if ($name === 'nodeType' || $name === 'attributes') {
                continue;
            }
            $node->{$name} = $this->decodeRecursive($subNode);
        }
        return $node;
    }
    private function decodeComment(array $value) : Comment
    {
        $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
        if (!isset($value['text'])) {
            throw new \RuntimeException('Comment must have text');
        }
        return new $className($value['text'], $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1, $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1);
    }
    private function reflectionClassFromNodeType(string $nodeType) : \ReflectionClass
    {
        if (!isset($this->reflectionClassCache[$nodeType])) {
            $className = $this->classNameFromNodeType($nodeType);
            $this->reflectionClassCache[$nodeType] = new \ReflectionClass($className);
        }
        return $this->reflectionClassCache[$nodeType];
    }
    private function classNameFromNodeType(string $nodeType) : string
    {
        $className = 'PhpParser\\Node\\' . \strtr($nodeType, '_', '\\');
        if (\class_exists($className)) {
            return $className;
        }
        $className .= '_';
        if (\class_exists($className)) {
            return $className;
        }
        throw new \RuntimeException("Unknown node type \"{$nodeType}\"");
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

class NodeTraverser implements NodeTraverserInterface
{
    /**
     * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CHILDREN, child nodes
     * of the current node will not be traversed for any visitors.
     *
     * For subsequent visitors enterNode() will still be called on the current
     * node and leaveNode() will also be invoked for the current node.
     */
    const DONT_TRAVERSE_CHILDREN = 1;
    /**
     * If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns
     * STOP_TRAVERSAL, traversal is aborted.
     *
     * The afterTraverse() method will still be invoked.
     */
    const STOP_TRAVERSAL = 2;
    /**
     * If NodeVisitor::leaveNode() returns REMOVE_NODE for a node that occurs
     * in an array, it will be removed from the array.
     *
     * For subsequent visitors leaveNode() will still be invoked for the
     * removed node.
     */
    const REMOVE_NODE = 3;
    /**
     * If NodeVisitor::enterNode() returns DONT_TRAVERSE_CURRENT_AND_CHILDREN, child nodes
     * of the current node will not be traversed for any visitors.
     *
     * For subsequent visitors enterNode() will not be called as well.
     * leaveNode() will be invoked for visitors that has enterNode() method invoked.
     */
    const DONT_TRAVERSE_CURRENT_AND_CHILDREN = 4;
    /** @var NodeVisitor[] Visitors */
    protected $visitors = [];
    /** @var bool Whether traversal should be stopped */
    protected $stopTraversal;
    public function __construct()
    {
        // for BC
    }
    /**
     * Adds a visitor.
     *
     * @param NodeVisitor $visitor Visitor to add
     */
    public function addVisitor(NodeVisitor $visitor)
    {
        $this->visitors[] = $visitor;
    }
    /**
     * Removes an added visitor.
     *
     * @param NodeVisitor $visitor
     */
    public function removeVisitor(NodeVisitor $visitor)
    {
        foreach ($this->visitors as $index => $storedVisitor) {
            if ($storedVisitor === $visitor) {
                unset($this->visitors[$index]);
                break;
            }
        }
    }
    /**
     * Traverses an array of nodes using the registered visitors.
     *
     * @param Node[] $nodes Array of nodes
     *
     * @return Node[] Traversed array of nodes
     */
    public function traverse(array $nodes) : array
    {
        $this->stopTraversal = \false;
        foreach ($this->visitors as $visitor) {
            if (null !== ($return = $visitor->beforeTraverse($nodes))) {
                $nodes = $return;
            }
        }
        $nodes = $this->traverseArray($nodes);
        foreach ($this->visitors as $visitor) {
            if (null !== ($return = $visitor->afterTraverse($nodes))) {
                $nodes = $return;
            }
        }
        return $nodes;
    }
    /**
     * Recursively traverse a node.
     *
     * @param Node $node Node to traverse.
     *
     * @return Node Result of traversal (may be original node or new one)
     */
    protected function traverseNode(Node $node) : Node
    {
        foreach ($node->getSubNodeNames() as $name) {
            $subNode =& $node->{$name};
            if (\is_array($subNode)) {
                $subNode = $this->traverseArray($subNode);
                if ($this->stopTraversal) {
                    break;
                }
            } elseif ($subNode instanceof Node) {
                $traverseChildren = \true;
                $breakVisitorIndex = null;
                foreach ($this->visitors as $visitorIndex => $visitor) {
                    $return = $visitor->enterNode($subNode);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $this->ensureReplacementReasonable($subNode, $return);
                            $subNode = $return;
                        } elseif (self::DONT_TRAVERSE_CHILDREN === $return) {
                            $traverseChildren = \false;
                        } elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
                            $traverseChildren = \false;
                            $breakVisitorIndex = $visitorIndex;
                            break;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } else {
                            throw new \LogicException('enterNode() returned invalid value of type ' . \gettype($return));
                        }
                    }
                }
                if ($traverseChildren) {
                    $subNode = $this->traverseNode($subNode);
                    if ($this->stopTraversal) {
                        break;
                    }
                }
                foreach ($this->visitors as $visitorIndex => $visitor) {
                    $return = $visitor->leaveNode($subNode);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $this->ensureReplacementReasonable($subNode, $return);
                            $subNode = $return;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } elseif (\is_array($return)) {
                            throw new \LogicException('leaveNode() may only return an array ' . 'if the parent structure is an array');
                        } else {
                            throw new \LogicException('leaveNode() returned invalid value of type ' . \gettype($return));
                        }
                    }
                    if ($breakVisitorIndex === $visitorIndex) {
                        break;
                    }
                }
            }
        }
        return $node;
    }
    /**
     * Recursively traverse array (usually of nodes).
     *
     * @param array $nodes Array to traverse
     *
     * @return array Result of traversal (may be original array or changed one)
     */
    protected function traverseArray(array $nodes) : array
    {
        $doNodes = [];
        foreach ($nodes as $i => &$node) {
            if ($node instanceof Node) {
                $traverseChildren = \true;
                $breakVisitorIndex = null;
                foreach ($this->visitors as $visitorIndex => $visitor) {
                    $return = $visitor->enterNode($node);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $this->ensureReplacementReasonable($node, $return);
                            $node = $return;
                        } elseif (self::DONT_TRAVERSE_CHILDREN === $return) {
                            $traverseChildren = \false;
                        } elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
                            $traverseChildren = \false;
                            $breakVisitorIndex = $visitorIndex;
                            break;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } else {
                            throw new \LogicException('enterNode() returned invalid value of type ' . \gettype($return));
                        }
                    }
                }
                if ($traverseChildren) {
                    $node = $this->traverseNode($node);
                    if ($this->stopTraversal) {
                        break;
                    }
                }
                foreach ($this->visitors as $visitorIndex => $visitor) {
                    $return = $visitor->leaveNode($node);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $this->ensureReplacementReasonable($node, $return);
                            $node = $return;
                        } elseif (\is_array($return)) {
                            $doNodes[] = [$i, $return];
                            break;
                        } elseif (self::REMOVE_NODE === $return) {
                            $doNodes[] = [$i, []];
                            break;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } elseif (\false === $return) {
                            throw new \LogicException('bool(false) return from leaveNode() no longer supported. ' . 'Return NodeTraverser::REMOVE_NODE instead');
                        } else {
                            throw new \LogicException('leaveNode() returned invalid value of type ' . \gettype($return));
                        }
                    }
                    if ($breakVisitorIndex === $visitorIndex) {
                        break;
                    }
                }
            } elseif (\is_array($node)) {
                throw new \LogicException('Invalid node structure: Contains nested arrays');
            }
        }
        if (!empty($doNodes)) {
            while (list($i, $replace) = \array_pop($doNodes)) {
                \array_splice($nodes, $i, 1, $replace);
            }
        }
        return $nodes;
    }
    private function ensureReplacementReasonable($old, $new)
    {
        if ($old instanceof Node\Stmt && $new instanceof Node\Expr) {
            throw new \LogicException("Trying to replace statement ({$old->getType()}) " . "with expression ({$new->getType()}). Are you missing a " . "Stmt_Expression wrapper?");
        }
        if ($old instanceof Node\Expr && $new instanceof Node\Stmt) {
            throw new \LogicException("Trying to replace expression ({$old->getType()}) " . "with statement ({$new->getType()})");
        }
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

interface NodeTraverserInterface
{
    /**
     * Adds a visitor.
     *
     * @param NodeVisitor $visitor Visitor to add
     */
    public function addVisitor(NodeVisitor $visitor);
    /**
     * Removes an added visitor.
     *
     * @param NodeVisitor $visitor
     */
    public function removeVisitor(NodeVisitor $visitor);
    /**
     * Traverses an array of nodes using the registered visitors.
     *
     * @param Node[] $nodes Array of nodes
     *
     * @return Node[] Traversed array of nodes
     */
    public function traverse(array $nodes) : array;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class Name extends NodeAbstract
{
    /** @var string[] Parts of the name */
    public $parts;
    private static $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true];
    /**
     * Constructs a name node.
     *
     * @param string|string[]|self $name       Name as string, part array or Name instance (copy ctor)
     * @param array                $attributes Additional attributes
     */
    public function __construct($name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->parts = self::prepareName($name);
    }
    public function getSubNodeNames() : array
    {
        return ['parts'];
    }
    /**
     * Gets the first part of the name, i.e. everything before the first namespace separator.
     *
     * @return string First part of the name
     */
    public function getFirst() : string
    {
        return $this->parts[0];
    }
    /**
     * Gets the last part of the name, i.e. everything after the last namespace separator.
     *
     * @return string Last part of the name
     */
    public function getLast() : string
    {
        return $this->parts[\count($this->parts) - 1];
    }
    /**
     * Checks whether the name is unqualified. (E.g. Name)
     *
     * @return bool Whether the name is unqualified
     */
    public function isUnqualified() : bool
    {
        return 1 === \count($this->parts);
    }
    /**
     * Checks whether the name is qualified. (E.g. Name\Name)
     *
     * @return bool Whether the name is qualified
     */
    public function isQualified() : bool
    {
        return 1 < \count($this->parts);
    }
    /**
     * Checks whether the name is fully qualified. (E.g. \Name)
     *
     * @return bool Whether the name is fully qualified
     */
    public function isFullyQualified() : bool
    {
        return \false;
    }
    /**
     * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
     *
     * @return bool Whether the name is relative
     */
    public function isRelative() : bool
    {
        return \false;
    }
    /**
     * Returns a string representation of the name itself, without taking the name type into
     * account (e.g., not including a leading backslash for fully qualified names).
     *
     * @return string String representation
     */
    public function toString() : string
    {
        return \implode('\\', $this->parts);
    }
    /**
     * Returns a string representation of the name as it would occur in code (e.g., including
     * leading backslash for fully qualified names.
     *
     * @return string String representation
     */
    public function toCodeString() : string
    {
        return $this->toString();
    }
    /**
     * Returns lowercased string representation of the name, without taking the name type into
     * account (e.g., no leading backslash for fully qualified names).
     *
     * @return string Lowercased string representation
     */
    public function toLowerString() : string
    {
        return \strtolower(\implode('\\', $this->parts));
    }
    /**
     * Checks whether the identifier is a special class name (self, parent or static).
     *
     * @return bool Whether identifier is a special class name
     */
    public function isSpecialClassName() : bool
    {
        return \count($this->parts) === 1 && isset(self::$specialClassNames[\strtolower($this->parts[0])]);
    }
    /**
     * Returns a string representation of the name by imploding the namespace parts with the
     * namespace separator.
     *
     * @return string String representation
     */
    public function __toString() : string
    {
        return \implode('\\', $this->parts);
    }
    /**
     * Gets a slice of a name (similar to array_slice).
     *
     * This method returns a new instance of the same type as the original and with the same
     * attributes.
     *
     * If the slice is empty, null is returned. The null value will be correctly handled in
     * concatenations using concat().
     *
     * Offset and length have the same meaning as in array_slice().
     *
     * @param int      $offset Offset to start the slice at (may be negative)
     * @param int|null $length Length of the slice (may be negative)
     *
     * @return static|null Sliced name
     */
    public function slice(int $offset, int $length = null)
    {
        $numParts = \count($this->parts);
        $realOffset = $offset < 0 ? $offset + $numParts : $offset;
        if ($realOffset < 0 || $realOffset > $numParts) {
            throw new \OutOfBoundsException(\sprintf('Offset %d is out of bounds', $offset));
        }
        if (null === $length) {
            $realLength = $numParts - $realOffset;
        } else {
            $realLength = $length < 0 ? $length + $numParts - $realOffset : $length;
            if ($realLength < 0 || $realLength > $numParts - $realOffset) {
                throw new \OutOfBoundsException(\sprintf('Length %d is out of bounds', $length));
            }
        }
        if ($realLength === 0) {
            // Empty slice is represented as null
            return null;
        }
        return new static(\array_slice($this->parts, $realOffset, $realLength), $this->attributes);
    }
    /**
     * Concatenate two names, yielding a new Name instance.
     *
     * The type of the generated instance depends on which class this method is called on, for
     * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance.
     *
     * If one of the arguments is null, a new instance of the other name will be returned. If both
     * arguments are null, null will be returned. As such, writing
     *     Name::concat($namespace, $shortName)
     * where $namespace is a Name node or null will work as expected.
     *
     * @param string|string[]|self|null $name1      The first name
     * @param string|string[]|self|null $name2      The second name
     * @param array                     $attributes Attributes to assign to concatenated name
     *
     * @return static|null Concatenated name
     */
    public static function concat($name1, $name2, array $attributes = [])
    {
        if (null === $name1 && null === $name2) {
            return null;
        } elseif (null === $name1) {
            return new static(self::prepareName($name2), $attributes);
        } elseif (null === $name2) {
            return new static(self::prepareName($name1), $attributes);
        } else {
            return new static(\array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes);
        }
    }
    /**
     * Prepares a (string, array or Name node) name for use in name changing methods by converting
     * it to an array.
     *
     * @param string|string[]|self $name Name to prepare
     *
     * @return string[] Prepared name
     */
    private static function prepareName($name) : array
    {
        if (\is_string($name)) {
            if ('' === $name) {
                throw new \InvalidArgumentException('Name cannot be empty');
            }
            return \explode('\\', $name);
        } elseif (\is_array($name)) {
            if (empty($name)) {
                throw new \InvalidArgumentException('Name cannot be empty');
            }
            return $name;
        } elseif ($name instanceof self) {
            return $name->parts;
        }
        throw new \InvalidArgumentException('Expected string, array of parts or Name instance');
    }
    public function getType() : string
    {
        return 'Name';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

abstract class Scalar extends Expr
{
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class IntersectionType extends ComplexType
{
    /** @var (Identifier|Name)[] Types */
    public $types;
    /**
     * Constructs an intersection type.
     *
     * @param (Identifier|Name)[] $types      Types
     * @param array               $attributes Additional attributes
     */
    public function __construct(array $types, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->types = $types;
    }
    public function getSubNodeNames() : array
    {
        return ['types'];
    }
    public function getType() : string
    {
        return 'IntersectionType';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class Attribute extends NodeAbstract
{
    /** @var Name Attribute name */
    public $name;
    /** @var Arg[] Attribute arguments */
    public $args;
    /**
     * @param Node\Name $name       Attribute name
     * @param Arg[]     $args       Attribute arguments
     * @param array     $attributes Additional node attributes
     */
    public function __construct(Name $name, array $args = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = $name;
        $this->args = $args;
    }
    public function getSubNodeNames() : array
    {
        return ['name', 'args'];
    }
    public function getType() : string
    {
        return 'Attribute';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
/**
 * This is a base class for complex types, including nullable types and union types.
 *
 * It does not provide any shared behavior and exists only for type-checking purposes.
 */
abstract class ComplexType extends NodeAbstract
{
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
/**
 * Represents the "..." in "foo(...)" of the first-class callable syntax.
 */
class VariadicPlaceholder extends NodeAbstract
{
    /**
     * Create a variadic argument placeholder (first-class callable syntax).
     *
     * @param array $attributes Additional attributes
     */
    public function __construct(array $attributes = [])
    {
        $this->attributes = $attributes;
    }
    public function getType() : string
    {
        return 'VariadicPlaceholder';
    }
    public function getSubNodeNames() : array
    {
        return [];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
class Encapsed extends Scalar
{
    /** @var Expr[] list of string parts */
    public $parts;
    /**
     * Constructs an encapsed string node.
     *
     * @param Expr[] $parts      Encaps list
     * @param array  $attributes Additional attributes
     */
    public function __construct(array $parts, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->parts = $parts;
    }
    public function getSubNodeNames() : array
    {
        return ['parts'];
    }
    public function getType() : string
    {
        return 'Scalar_Encapsed';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
class String_ extends Scalar
{
    /* For use in "kind" attribute */
    const KIND_SINGLE_QUOTED = 1;
    const KIND_DOUBLE_QUOTED = 2;
    const KIND_HEREDOC = 3;
    const KIND_NOWDOC = 4;
    /** @var string String value */
    public $value;
    protected static $replacements = ['\\' => '\\', '$' => '$', 'n' => "\n", 'r' => "\r", 't' => "\t", 'f' => "\f", 'v' => "\v", 'e' => "\x1b"];
    /**
     * Constructs a string scalar node.
     *
     * @param string $value      Value of the string
     * @param array  $attributes Additional attributes
     */
    public function __construct(string $value, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['value'];
    }
    /**
     * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
     */
    public static function fromString(string $str, array $attributes = [], bool $parseUnicodeEscape = \true) : self
    {
        $attributes['kind'] = $str[0] === "'" || $str[1] === "'" && ($str[0] === 'b' || $str[0] === 'B') ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED;
        $attributes['rawValue'] = $str;
        $string = self::parse($str, $parseUnicodeEscape);
        return new self($string, $attributes);
    }
    /**
     * @internal
     *
     * Parses a string token.
     *
     * @param string $str String token content
     * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
     *
     * @return string The parsed string
     */
    public static function parse(string $str, bool $parseUnicodeEscape = \true) : string
    {
        $bLength = 0;
        if ('b' === $str[0] || 'B' === $str[0]) {
            $bLength = 1;
        }
        if ('\'' === $str[$bLength]) {
            return \str_replace(['\\\\', '\\\''], ['\\', '\''], \substr($str, $bLength + 1, -1));
        } else {
            return self::parseEscapeSequences(\substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape);
        }
    }
    /**
     * @internal
     *
     * Parses escape sequences in strings (all string types apart from single quoted).
     *
     * @param string      $str   String without quotes
     * @param null|string $quote Quote type
     * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
     *
     * @return string String with escape sequences parsed
     */
    public static function parseEscapeSequences(string $str, $quote, bool $parseUnicodeEscape = \true) : string
    {
        if (null !== $quote) {
            $str = \str_replace('\\' . $quote, $quote, $str);
        }
        $extra = '';
        if ($parseUnicodeEscape) {
            $extra = '|u\\{([0-9a-fA-F]+)\\}';
        }
        return \preg_replace_callback('~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~', function ($matches) {
            $str = $matches[1];
            if (isset(self::$replacements[$str])) {
                return self::$replacements[$str];
            } elseif ('x' === $str[0] || 'X' === $str[0]) {
                return \chr(\hexdec(\substr($str, 1)));
            } elseif ('u' === $str[0]) {
                return self::codePointToUtf8(\hexdec($matches[2]));
            } else {
                return \chr(\octdec($str));
            }
        }, $str);
    }
    /**
     * Converts a Unicode code point to its UTF-8 encoded representation.
     *
     * @param int $num Code point
     *
     * @return string UTF-8 representation of code point
     */
    private static function codePointToUtf8(int $num) : string
    {
        if ($num <= 0x7f) {
            return \chr($num);
        }
        if ($num <= 0x7ff) {
            return \chr(($num >> 6) + 0xc0) . \chr(($num & 0x3f) + 0x80);
        }
        if ($num <= 0xffff) {
            return \chr(($num >> 12) + 0xe0) . \chr(($num >> 6 & 0x3f) + 0x80) . \chr(($num & 0x3f) + 0x80);
        }
        if ($num <= 0x1fffff) {
            return \chr(($num >> 18) + 0xf0) . \chr(($num >> 12 & 0x3f) + 0x80) . \chr(($num >> 6 & 0x3f) + 0x80) . \chr(($num & 0x3f) + 0x80);
        }
        throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large');
    }
    public function getType() : string
    {
        return 'Scalar_String';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
class EncapsedStringPart extends Scalar
{
    /** @var string String value */
    public $value;
    /**
     * Constructs a node representing a string part of an encapsed string.
     *
     * @param string $value      String value
     * @param array  $attributes Additional attributes
     */
    public function __construct(string $value, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['value'];
    }
    public function getType() : string
    {
        return 'Scalar_EncapsedStringPart';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
class DNumber extends Scalar
{
    /** @var float Number value */
    public $value;
    /**
     * Constructs a float number scalar node.
     *
     * @param float $value      Value of the number
     * @param array $attributes Additional attributes
     */
    public function __construct(float $value, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['value'];
    }
    /**
     * @param mixed[] $attributes
     */
    public static function fromString(string $str, array $attributes = []) : DNumber
    {
        $attributes['rawValue'] = $str;
        $float = self::parse($str);
        return new DNumber($float, $attributes);
    }
    /**
     * @internal
     *
     * Parses a DNUMBER token like PHP would.
     *
     * @param string $str A string number
     *
     * @return float The parsed number
     */
    public static function parse(string $str) : float
    {
        $str = \str_replace('_', '', $str);
        // Check whether this is one of the special integer notations.
        if ('0' === $str[0]) {
            // hex
            if ('x' === $str[1] || 'X' === $str[1]) {
                return \hexdec($str);
            }
            // bin
            if ('b' === $str[1] || 'B' === $str[1]) {
                return \bindec($str);
            }
            // oct, but only if the string does not contain any of '.eE'.
            if (\false === \strpbrk($str, '.eE')) {
                // substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit
                // (8 or 9) so that only the digits before that are used.
                return \octdec(\substr($str, 0, \strcspn($str, '89')));
            }
        }
        // dec
        return (float) $str;
    }
    public function getType() : string
    {
        return 'Scalar_DNumber';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
class LNumber extends Scalar
{
    /* For use in "kind" attribute */
    const KIND_BIN = 2;
    const KIND_OCT = 8;
    const KIND_DEC = 10;
    const KIND_HEX = 16;
    /** @var int Number value */
    public $value;
    /**
     * Constructs an integer number scalar node.
     *
     * @param int   $value      Value of the number
     * @param array $attributes Additional attributes
     */
    public function __construct(int $value, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['value'];
    }
    /**
     * Constructs an LNumber node from a string number literal.
     *
     * @param string $str               String number literal (decimal, octal, hex or binary)
     * @param array  $attributes        Additional attributes
     * @param bool   $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5)
     *
     * @return LNumber The constructed LNumber, including kind attribute
     */
    public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = \false) : LNumber
    {
        $attributes['rawValue'] = $str;
        $str = \str_replace('_', '', $str);
        if ('0' !== $str[0] || '0' === $str) {
            $attributes['kind'] = LNumber::KIND_DEC;
            return new LNumber((int) $str, $attributes);
        }
        if ('x' === $str[1] || 'X' === $str[1]) {
            $attributes['kind'] = LNumber::KIND_HEX;
            return new LNumber(\hexdec($str), $attributes);
        }
        if ('b' === $str[1] || 'B' === $str[1]) {
            $attributes['kind'] = LNumber::KIND_BIN;
            return new LNumber(\bindec($str), $attributes);
        }
        if (!$allowInvalidOctal && \strpbrk($str, '89')) {
            throw new Error('Invalid numeric literal', $attributes);
        }
        // Strip optional explicit octal prefix.
        if ('o' === $str[1] || 'O' === $str[1]) {
            $str = \substr($str, 2);
        }
        // use intval instead of octdec to get proper cutting behavior with malformed numbers
        $attributes['kind'] = LNumber::KIND_OCT;
        return new LNumber(\intval($str, 8), $attributes);
    }
    public function getType() : string
    {
        return 'Scalar_LNumber';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
abstract class MagicConst extends Scalar
{
    /**
     * Constructs a magic constant node.
     *
     * @param array $attributes Additional attributes
     */
    public function __construct(array $attributes = [])
    {
        $this->attributes = $attributes;
    }
    public function getSubNodeNames() : array
    {
        return [];
    }
    /**
     * Get name of magic constant.
     *
     * @return string Name of magic constant
     */
    public abstract function getName() : string;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class Line extends MagicConst
{
    public function getName() : string
    {
        return '__LINE__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_Line';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class Dir extends MagicConst
{
    public function getName() : string
    {
        return '__DIR__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_Dir';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class Class_ extends MagicConst
{
    public function getName() : string
    {
        return '__CLASS__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_Class';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class Trait_ extends MagicConst
{
    public function getName() : string
    {
        return '__TRAIT__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_Trait';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class Function_ extends MagicConst
{
    public function getName() : string
    {
        return '__FUNCTION__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_Function';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class Method extends MagicConst
{
    public function getName() : string
    {
        return '__METHOD__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_Method';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class File extends MagicConst
{
    public function getName() : string
    {
        return '__FILE__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_File';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst;
class Namespace_ extends MagicConst
{
    public function getName() : string
    {
        return '__NAMESPACE__';
    }
    public function getType() : string
    {
        return 'Scalar_MagicConst_Namespace';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\VariadicPlaceholder;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class Arg extends NodeAbstract
{
    /** @var Identifier|null Parameter name (for named parameters) */
    public $name;
    /** @var Expr Value to pass */
    public $value;
    /** @var bool Whether to pass by ref */
    public $byRef;
    /** @var bool Whether to unpack the argument */
    public $unpack;
    /**
     * Constructs a function call argument node.
     *
     * @param Expr  $value      Value to pass
     * @param bool  $byRef      Whether to pass by ref
     * @param bool  $unpack     Whether to unpack the argument
     * @param array $attributes Additional attributes
     * @param Identifier|null $name Parameter name (for named parameters)
     */
    public function __construct(Expr $value, bool $byRef = \false, bool $unpack = \false, array $attributes = [], Identifier $name = null)
    {
        $this->attributes = $attributes;
        $this->name = $name;
        $this->value = $value;
        $this->byRef = $byRef;
        $this->unpack = $unpack;
    }
    public function getSubNodeNames() : array
    {
        return ['name', 'value', 'byRef', 'unpack'];
    }
    public function getType() : string
    {
        return 'Arg';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class Param extends NodeAbstract
{
    /** @var null|Identifier|Name|ComplexType Type declaration */
    public $type;
    /** @var bool Whether parameter is passed by reference */
    public $byRef;
    /** @var bool Whether this is a variadic argument */
    public $variadic;
    /** @var Expr\Variable|Expr\Error Parameter variable */
    public $var;
    /** @var null|Expr Default value */
    public $default;
    /** @var int */
    public $flags;
    /** @var AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    /**
     * Constructs a parameter node.
     *
     * @param Expr\Variable|Expr\Error                $var        Parameter variable
     * @param null|Expr                               $default    Default value
     * @param null|string|Identifier|Name|ComplexType $type       Type declaration
     * @param bool                                    $byRef      Whether is passed by reference
     * @param bool                                    $variadic   Whether this is a variadic argument
     * @param array                                   $attributes Additional attributes
     * @param int                                     $flags      Optional visibility flags
     * @param AttributeGroup[]                        $attrGroups PHP attribute groups
     */
    public function __construct($var, Expr $default = null, $type = null, bool $byRef = \false, bool $variadic = \false, array $attributes = [], int $flags = 0, array $attrGroups = [])
    {
        $this->attributes = $attributes;
        $this->type = \is_string($type) ? new Identifier($type) : $type;
        $this->byRef = $byRef;
        $this->variadic = $variadic;
        $this->var = $var;
        $this->default = $default;
        $this->flags = $flags;
        $this->attrGroups = $attrGroups;
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'flags', 'type', 'byRef', 'variadic', 'var', 'default'];
    }
    public function getType() : string
    {
        return 'Param';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class MatchArm extends NodeAbstract
{
    /** @var null|Node\Expr[] */
    public $conds;
    /** @var Node\Expr */
    public $body;
    /**
     * @param null|Node\Expr[] $conds
     */
    public function __construct($conds, Node\Expr $body, array $attributes = [])
    {
        $this->conds = $conds;
        $this->body = $body;
        $this->attributes = $attributes;
    }
    public function getSubNodeNames() : array
    {
        return ['conds', 'body'];
    }
    public function getType() : string
    {
        return 'MatchArm';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class AttributeGroup extends NodeAbstract
{
    /** @var Attribute[] Attributes */
    public $attrs;
    /**
     * @param Attribute[] $attrs PHP attributes
     * @param array $attributes Additional node attributes
     */
    public function __construct(array $attrs, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->attrs = $attrs;
    }
    public function getSubNodeNames() : array
    {
        return ['attrs'];
    }
    public function getType() : string
    {
        return 'AttributeGroup';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
interface FunctionLike extends Node
{
    /**
     * Whether to return by reference
     *
     * @return bool
     */
    public function returnsByRef() : bool;
    /**
     * List of parameters
     *
     * @return Param[]
     */
    public function getParams() : array;
    /**
     * Get the declared return type or null
     *
     * @return null|Identifier|Name|ComplexType
     */
    public function getReturnType();
    /**
     * The function body
     *
     * @return Stmt[]|null
     */
    public function getStmts();
    /**
     * Get PHP attribute groups.
     *
     * @return AttributeGroup[]
     */
    public function getAttrGroups() : array;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
class Const_ extends NodeAbstract
{
    /** @var Identifier Name */
    public $name;
    /** @var Expr Value */
    public $value;
    /** @var Name|null Namespaced name (if using NameResolver) */
    public $namespacedName;
    /**
     * Constructs a const node for use in class const and const statements.
     *
     * @param string|Identifier $name       Name
     * @param Expr              $value      Value
     * @param array             $attributes Additional attributes
     */
    public function __construct($name, Expr $value, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['name', 'value'];
    }
    public function getType() : string
    {
        return 'Const';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

/**
 * Represents a name that is written in source code with a leading dollar,
 * but is not a proper variable. The leading dollar is not stored as part of the name.
 *
 * Examples: Names in property declarations are formatted as variables. Names in static property
 * lookups are also formatted as variables.
 */
class VarLikeIdentifier extends Identifier
{
    public function getType() : string
    {
        return 'VarLikeIdentifier';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Ternary extends Expr
{
    /** @var Expr Condition */
    public $cond;
    /** @var null|Expr Expression for true */
    public $if;
    /** @var Expr Expression for false */
    public $else;
    /**
     * Constructs a ternary operator node.
     *
     * @param Expr      $cond       Condition
     * @param null|Expr $if         Expression for true
     * @param Expr      $else       Expression for false
     * @param array                    $attributes Additional attributes
     */
    public function __construct(Expr $cond, $if, Expr $else, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->if = $if;
        $this->else = $else;
    }
    public function getSubNodeNames() : array
    {
        return ['cond', 'if', 'else'];
    }
    public function getType() : string
    {
        return 'Expr_Ternary';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Yield_ extends Expr
{
    /** @var null|Expr Key expression */
    public $key;
    /** @var null|Expr Value expression */
    public $value;
    /**
     * Constructs a yield expression node.
     *
     * @param null|Expr $value      Value expression
     * @param null|Expr $key        Key expression
     * @param array     $attributes Additional attributes
     */
    public function __construct(Expr $value = null, Expr $key = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->key = $key;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['key', 'value'];
    }
    public function getType() : string
    {
        return 'Expr_Yield';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class BooleanNot extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs a boolean not node.
     *
     * @param Expr $expr       Expression
     * @param array               $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_BooleanNot';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\FunctionLike;
class Closure extends Expr implements FunctionLike
{
    /** @var bool Whether the closure is static */
    public $static;
    /** @var bool Whether to return by reference */
    public $byRef;
    /** @var Node\Param[] Parameters */
    public $params;
    /** @var ClosureUse[] use()s */
    public $uses;
    /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
    public $returnType;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /** @var Node\AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    /**
     * Constructs a lambda function node.
     *
     * @param array $subNodes   Array of the following optional subnodes:
     *                          'static'     => false  : Whether the closure is static
     *                          'byRef'      => false  : Whether to return by reference
     *                          'params'     => array(): Parameters
     *                          'uses'       => array(): use()s
     *                          'returnType' => null   : Return type
     *                          'stmts'      => array(): Statements
     *                          'attrGroups' => array(): PHP attributes groups
     * @param array $attributes Additional attributes
     */
    public function __construct(array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->static = $subNodes['static'] ?? \false;
        $this->byRef = $subNodes['byRef'] ?? \false;
        $this->params = $subNodes['params'] ?? [];
        $this->uses = $subNodes['uses'] ?? [];
        $returnType = $subNodes['returnType'] ?? null;
        $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
        $this->stmts = $subNodes['stmts'] ?? [];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'static', 'byRef', 'params', 'uses', 'returnType', 'stmts'];
    }
    public function returnsByRef() : bool
    {
        return $this->byRef;
    }
    public function getParams() : array
    {
        return $this->params;
    }
    public function getReturnType()
    {
        return $this->returnType;
    }
    /** @return Node\Stmt[] */
    public function getStmts() : array
    {
        return $this->stmts;
    }
    public function getAttrGroups() : array
    {
        return $this->attrGroups;
    }
    public function getType() : string
    {
        return 'Expr_Closure';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class YieldFrom extends Expr
{
    /** @var Expr Expression to yield from */
    public $expr;
    /**
     * Constructs an "yield from" node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_YieldFrom';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
class NullsafePropertyFetch extends Expr
{
    /** @var Expr Variable holding object */
    public $var;
    /** @var Identifier|Expr Property name */
    public $name;
    /**
     * Constructs a nullsafe property fetch node.
     *
     * @param Expr                   $var        Variable holding object
     * @param string|Identifier|Expr $name       Property name
     * @param array                  $attributes Additional attributes
     */
    public function __construct(Expr $var, $name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'name'];
    }
    public function getType() : string
    {
        return 'Expr_NullsafePropertyFetch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Eval_ extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs an eval() node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_Eval';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
class Instanceof_ extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /** @var Name|Expr Class name */
    public $class;
    /**
     * Constructs an instanceof check node.
     *
     * @param Expr      $expr       Expression
     * @param Name|Expr $class      Class name
     * @param array     $attributes Additional attributes
     */
    public function __construct(Expr $expr, $class, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
        $this->class = $class;
    }
    public function getSubNodeNames() : array
    {
        return ['expr', 'class'];
    }
    public function getType() : string
    {
        return 'Expr_Instanceof';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class UnaryMinus extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs a unary minus node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_UnaryMinus';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Exit_ extends Expr
{
    /* For use in "kind" attribute */
    const KIND_EXIT = 1;
    const KIND_DIE = 2;
    /** @var null|Expr Expression */
    public $expr;
    /**
     * Constructs an exit() node.
     *
     * @param null|Expr $expr       Expression
     * @param array                    $attributes Additional attributes
     */
    public function __construct(Expr $expr = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_Exit';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class ErrorSuppress extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs an error suppress node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_ErrorSuppress';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
class PropertyFetch extends Expr
{
    /** @var Expr Variable holding object */
    public $var;
    /** @var Identifier|Expr Property name */
    public $name;
    /**
     * Constructs a function call node.
     *
     * @param Expr                   $var        Variable holding object
     * @param string|Identifier|Expr $name       Property name
     * @param array                  $attributes Additional attributes
     */
    public function __construct(Expr $var, $name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'name'];
    }
    public function getType() : string
    {
        return 'Expr_PropertyFetch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Array_ extends Expr
{
    // For use in "kind" attribute
    const KIND_LONG = 1;
    // array() syntax
    const KIND_SHORT = 2;
    // [] syntax
    /** @var (ArrayItem|null)[] Items */
    public $items;
    /**
     * Constructs an array node.
     *
     * @param (ArrayItem|null)[] $items      Items of the array
     * @param array       $attributes Additional attributes
     */
    public function __construct(array $items = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->items = $items;
    }
    public function getSubNodeNames() : array
    {
        return ['items'];
    }
    public function getType() : string
    {
        return 'Expr_Array';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class NotEqual extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '!=';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_NotEqual';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Identical extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '===';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Identical';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class BitwiseAnd extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '&';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_BitwiseAnd';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class BitwiseXor extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '^';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_BitwiseXor';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Plus extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '+';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Plus';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Greater extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '>';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Greater';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Mod extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '%';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Mod';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Minus extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '-';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Minus';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class BooleanAnd extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '&&';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_BooleanAnd';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class NotIdentical extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '!==';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_NotIdentical';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class BooleanOr extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '||';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_BooleanOr';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Concat extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '.';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Concat';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class LogicalAnd extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return 'and';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_LogicalAnd';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Spaceship extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '<=>';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Spaceship';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class ShiftLeft extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '<<';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_ShiftLeft';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class LogicalXor extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return 'xor';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_LogicalXor';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Div extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '/';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Div';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Pow extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '**';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Pow';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Equal extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '==';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Equal';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class ShiftRight extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '>>';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_ShiftRight';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class GreaterOrEqual extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '>=';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_GreaterOrEqual';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class SmallerOrEqual extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '<=';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_SmallerOrEqual';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Coalesce extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '??';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Coalesce';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Mul extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '*';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Mul';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class BitwiseOr extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '|';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_BitwiseOr';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class Smaller extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return '<';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_Smaller';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
class LogicalOr extends BinaryOp
{
    public function getOperatorSigil() : string
    {
        return 'or';
    }
    public function getType() : string
    {
        return 'Expr_BinaryOp_LogicalOr';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\VarLikeIdentifier;
class StaticPropertyFetch extends Expr
{
    /** @var Name|Expr Class name */
    public $class;
    /** @var VarLikeIdentifier|Expr Property name */
    public $name;
    /**
     * Constructs a static property fetch node.
     *
     * @param Name|Expr                     $class      Class name
     * @param string|VarLikeIdentifier|Expr $name       Property name
     * @param array                         $attributes Additional attributes
     */
    public function __construct($class, $name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->class = $class;
        $this->name = \is_string($name) ? new VarLikeIdentifier($name) : $name;
    }
    public function getSubNodeNames() : array
    {
        return ['class', 'name'];
    }
    public function getType() : string
    {
        return 'Expr_StaticPropertyFetch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Print_ extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs an print() node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_Print';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Include_ extends Expr
{
    const TYPE_INCLUDE = 1;
    const TYPE_INCLUDE_ONCE = 2;
    const TYPE_REQUIRE = 3;
    const TYPE_REQUIRE_ONCE = 4;
    /** @var Expr Expression */
    public $expr;
    /** @var int Type of include */
    public $type;
    /**
     * Constructs an include node.
     *
     * @param Expr  $expr       Expression
     * @param int   $type       Type of include
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, int $type, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
        $this->type = $type;
    }
    public function getSubNodeNames() : array
    {
        return ['expr', 'type'];
    }
    public function getType() : string
    {
        return 'Expr_Include';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Clone_ extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs a clone node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_Clone';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Variable extends Expr
{
    /** @var string|Expr Name */
    public $name;
    /**
     * Constructs a variable node.
     *
     * @param string|Expr $name       Name
     * @param array       $attributes Additional attributes
     */
    public function __construct($name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = $name;
    }
    public function getSubNodeNames() : array
    {
        return ['name'];
    }
    public function getType() : string
    {
        return 'Expr_Variable';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class FuncCall extends CallLike
{
    /** @var Node\Name|Expr Function name */
    public $name;
    /** @var array<Node\Arg|Node\VariadicPlaceholder> Arguments */
    public $args;
    /**
     * Constructs a function call node.
     *
     * @param Node\Name|Expr                           $name       Function name
     * @param array<Node\Arg|Node\VariadicPlaceholder> $args       Arguments
     * @param array                                    $attributes Additional attributes
     */
    public function __construct($name, array $args = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = $name;
        $this->args = $args;
    }
    public function getSubNodeNames() : array
    {
        return ['name', 'args'];
    }
    public function getType() : string
    {
        return 'Expr_FuncCall';
    }
    public function getRawArgs() : array
    {
        return $this->args;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class AssignRef extends Expr
{
    /** @var Expr Variable reference is assigned to */
    public $var;
    /** @var Expr Variable which is referenced */
    public $expr;
    /**
     * Constructs an assignment node.
     *
     * @param Expr  $var        Variable
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $var, Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'expr'];
    }
    public function getType() : string
    {
        return 'Expr_AssignRef';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
abstract class AssignOp extends Expr
{
    /** @var Expr Variable */
    public $var;
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs a compound assignment operation node.
     *
     * @param Expr  $var        Variable
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $var, Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'expr'];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
abstract class Cast extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs a cast node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class BitwiseNot extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs a bitwise not node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_BitwiseNot';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\FunctionLike;
class ArrowFunction extends Expr implements FunctionLike
{
    /** @var bool */
    public $static;
    /** @var bool */
    public $byRef;
    /** @var Node\Param[] */
    public $params = [];
    /** @var null|Node\Identifier|Node\Name|Node\ComplexType */
    public $returnType;
    /** @var Expr */
    public $expr;
    /** @var Node\AttributeGroup[] */
    public $attrGroups;
    /**
     * @param array $subNodes   Array of the following optional subnodes:
     *                          'static'     => false   : Whether the closure is static
     *                          'byRef'      => false   : Whether to return by reference
     *                          'params'     => array() : Parameters
     *                          'returnType' => null    : Return type
     *                          'expr'       => Expr    : Expression body
     *                          'attrGroups' => array() : PHP attribute groups
     * @param array $attributes Additional attributes
     */
    public function __construct(array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->static = $subNodes['static'] ?? \false;
        $this->byRef = $subNodes['byRef'] ?? \false;
        $this->params = $subNodes['params'] ?? [];
        $returnType = $subNodes['returnType'] ?? null;
        $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
        $this->expr = $subNodes['expr'];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'static', 'byRef', 'params', 'returnType', 'expr'];
    }
    public function returnsByRef() : bool
    {
        return $this->byRef;
    }
    public function getParams() : array
    {
        return $this->params;
    }
    public function getReturnType()
    {
        return $this->returnType;
    }
    public function getAttrGroups() : array
    {
        return $this->attrGroups;
    }
    /**
     * @return Node\Stmt\Return_[]
     */
    public function getStmts() : array
    {
        return [new Node\Stmt\Return_($this->expr)];
    }
    public function getType() : string
    {
        return 'Expr_ArrowFunction';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
class ConstFetch extends Expr
{
    /** @var Name Constant name */
    public $name;
    /**
     * Constructs a const fetch node.
     *
     * @param Name  $name       Constant name
     * @param array $attributes Additional attributes
     */
    public function __construct(Name $name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = $name;
    }
    public function getSubNodeNames() : array
    {
        return ['name'];
    }
    public function getType() : string
    {
        return 'Expr_ConstFetch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class PostDec extends Expr
{
    /** @var Expr Variable */
    public $var;
    /**
     * Constructs a post decrement node.
     *
     * @param Expr  $var        Variable
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $var, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
    }
    public function getSubNodeNames() : array
    {
        return ['var'];
    }
    public function getType() : string
    {
        return 'Expr_PostDec';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\VariadicPlaceholder;
class New_ extends CallLike
{
    /** @var Node\Name|Expr|Node\Stmt\Class_ Class name */
    public $class;
    /** @var array<Arg|VariadicPlaceholder> Arguments */
    public $args;
    /**
     * Constructs a function call node.
     *
     * @param Node\Name|Expr|Node\Stmt\Class_ $class      Class name (or class node for anonymous classes)
     * @param array<Arg|VariadicPlaceholder>  $args       Arguments
     * @param array                           $attributes Additional attributes
     */
    public function __construct($class, array $args = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->class = $class;
        $this->args = $args;
    }
    public function getSubNodeNames() : array
    {
        return ['class', 'args'];
    }
    public function getType() : string
    {
        return 'Expr_New';
    }
    public function getRawArgs() : array
    {
        return $this->args;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class ClosureUse extends Expr
{
    /** @var Expr\Variable Variable to use */
    public $var;
    /** @var bool Whether to use by reference */
    public $byRef;
    /**
     * Constructs a closure use node.
     *
     * @param Expr\Variable $var        Variable to use
     * @param bool          $byRef      Whether to use by reference
     * @param array         $attributes Additional attributes
     */
    public function __construct(Expr\Variable $var, bool $byRef = \false, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->byRef = $byRef;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'byRef'];
    }
    public function getType() : string
    {
        return 'Expr_ClosureUse';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class ArrayDimFetch extends Expr
{
    /** @var Expr Variable */
    public $var;
    /** @var null|Expr Array index / dim */
    public $dim;
    /**
     * Constructs an array index fetch node.
     *
     * @param Expr      $var        Variable
     * @param null|Expr $dim        Array index / dim
     * @param array     $attributes Additional attributes
     */
    public function __construct(Expr $var, Expr $dim = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->dim = $dim;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'dim'];
    }
    public function getType() : string
    {
        return 'Expr_ArrayDimFetch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Throw_ extends Node\Expr
{
    /** @var Node\Expr Expression */
    public $expr;
    /**
     * Constructs a throw expression node.
     *
     * @param Node\Expr $expr       Expression
     * @param array     $attributes Additional attributes
     */
    public function __construct(Node\Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_Throw';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class PreDec extends Expr
{
    /** @var Expr Variable */
    public $var;
    /**
     * Constructs a pre decrement node.
     *
     * @param Expr  $var        Variable
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $var, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
    }
    public function getSubNodeNames() : array
    {
        return ['var'];
    }
    public function getType() : string
    {
        return 'Expr_PreDec';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\VariadicPlaceholder;
class NullsafeMethodCall extends CallLike
{
    /** @var Expr Variable holding object */
    public $var;
    /** @var Identifier|Expr Method name */
    public $name;
    /** @var array<Arg|VariadicPlaceholder> Arguments */
    public $args;
    /**
     * Constructs a nullsafe method call node.
     *
     * @param Expr                           $var        Variable holding object
     * @param string|Identifier|Expr         $name       Method name
     * @param array<Arg|VariadicPlaceholder> $args       Arguments
     * @param array                          $attributes Additional attributes
     */
    public function __construct(Expr $var, $name, array $args = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
        $this->args = $args;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'name', 'args'];
    }
    public function getType() : string
    {
        return 'Expr_NullsafeMethodCall';
    }
    public function getRawArgs() : array
    {
        return $this->args;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Isset_ extends Expr
{
    /** @var Expr[] Variables */
    public $vars;
    /**
     * Constructs an array node.
     *
     * @param Expr[] $vars       Variables
     * @param array  $attributes Additional attributes
     */
    public function __construct(array $vars, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->vars = $vars;
    }
    public function getSubNodeNames() : array
    {
        return ['vars'];
    }
    public function getType() : string
    {
        return 'Expr_Isset';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Empty_ extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs an empty() node.
     *
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_Empty';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class List_ extends Expr
{
    /** @var (ArrayItem|null)[] List of items to assign to */
    public $items;
    /**
     * Constructs a list() destructuring node.
     *
     * @param (ArrayItem|null)[] $items      List of items to assign to
     * @param array              $attributes Additional attributes
     */
    public function __construct(array $items, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->items = $items;
    }
    public function getSubNodeNames() : array
    {
        return ['items'];
    }
    public function getType() : string
    {
        return 'Expr_List';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
class ClassConstFetch extends Expr
{
    /** @var Name|Expr Class name */
    public $class;
    /** @var Identifier|Error Constant name */
    public $name;
    /**
     * Constructs a class const fetch node.
     *
     * @param Name|Expr               $class      Class name
     * @param string|Identifier|Error $name       Constant name
     * @param array                   $attributes Additional attributes
     */
    public function __construct($class, $name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->class = $class;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
    }
    public function getSubNodeNames() : array
    {
        return ['class', 'name'];
    }
    public function getType() : string
    {
        return 'Expr_ClassConstFetch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\VariadicPlaceholder;
class MethodCall extends CallLike
{
    /** @var Expr Variable holding object */
    public $var;
    /** @var Identifier|Expr Method name */
    public $name;
    /** @var array<Arg|VariadicPlaceholder> Arguments */
    public $args;
    /**
     * Constructs a function call node.
     *
     * @param Expr                           $var        Variable holding object
     * @param string|Identifier|Expr         $name       Method name
     * @param array<Arg|VariadicPlaceholder> $args       Arguments
     * @param array                          $attributes Additional attributes
     */
    public function __construct(Expr $var, $name, array $args = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
        $this->args = $args;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'name', 'args'];
    }
    public function getType() : string
    {
        return 'Expr_MethodCall';
    }
    public function getRawArgs() : array
    {
        return $this->args;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Assign extends Expr
{
    /** @var Expr Variable */
    public $var;
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs an assignment node.
     *
     * @param Expr  $var        Variable
     * @param Expr  $expr       Expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $var, Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'expr'];
    }
    public function getType() : string
    {
        return 'Expr_Assign';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\MatchArm;
class Match_ extends Node\Expr
{
    /** @var Node\Expr */
    public $cond;
    /** @var MatchArm[] */
    public $arms;
    /**
     * @param MatchArm[] $arms
     */
    public function __construct(Node\Expr $cond, array $arms = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->arms = $arms;
    }
    public function getSubNodeNames() : array
    {
        return ['cond', 'arms'];
    }
    public function getType() : string
    {
        return 'Expr_Match';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class ArrayItem extends Expr
{
    /** @var null|Expr Key */
    public $key;
    /** @var Expr Value */
    public $value;
    /** @var bool Whether to assign by reference */
    public $byRef;
    /** @var bool Whether to unpack the argument */
    public $unpack;
    /**
     * Constructs an array item node.
     *
     * @param Expr      $value      Value
     * @param null|Expr $key        Key
     * @param bool      $byRef      Whether to assign by reference
     * @param array     $attributes Additional attributes
     */
    public function __construct(Expr $value, Expr $key = null, bool $byRef = \false, array $attributes = [], bool $unpack = \false)
    {
        $this->attributes = $attributes;
        $this->key = $key;
        $this->value = $value;
        $this->byRef = $byRef;
        $this->unpack = $unpack;
    }
    public function getSubNodeNames() : array
    {
        return ['key', 'value', 'byRef', 'unpack'];
    }
    public function getType() : string
    {
        return 'Expr_ArrayItem';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class PreInc extends Expr
{
    /** @var Expr Variable */
    public $var;
    /**
     * Constructs a pre increment node.
     *
     * @param Expr  $var        Variable
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $var, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
    }
    public function getSubNodeNames() : array
    {
        return ['var'];
    }
    public function getType() : string
    {
        return 'Expr_PreInc';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class UnaryPlus extends Expr
{
    /** @var Expr Expression */
    public $expr;
    /**
     * Constructs a unary plus node.
     *
     * @param Expr $expr       Expression
     * @param array               $attributes Additional attributes
     */
    public function __construct(Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Expr_UnaryPlus';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class ShellExec extends Expr
{
    /** @var array Encapsed string array */
    public $parts;
    /**
     * Constructs a shell exec (backtick) node.
     *
     * @param array $parts      Encapsed string array
     * @param array $attributes Additional attributes
     */
    public function __construct(array $parts, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->parts = $parts;
    }
    public function getSubNodeNames() : array
    {
        return ['parts'];
    }
    public function getType() : string
    {
        return 'Expr_ShellExec';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class BitwiseAnd extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_BitwiseAnd';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class BitwiseXor extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_BitwiseXor';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Plus extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Plus';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Mod extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Mod';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Minus extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Minus';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Concat extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Concat';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class ShiftLeft extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_ShiftLeft';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Div extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Div';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Pow extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Pow';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class ShiftRight extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_ShiftRight';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Coalesce extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Coalesce';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class Mul extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_Mul';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp;
class BitwiseOr extends AssignOp
{
    public function getType() : string
    {
        return 'Expr_AssignOp_BitwiseOr';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
/**
 * Error node used during parsing with error recovery.
 *
 * An error node may be placed at a position where an expression is required, but an error occurred.
 * Error nodes will not be present if the parser is run in throwOnError mode (the default).
 */
class Error extends Expr
{
    /**
     * Constructs an error node.
     *
     * @param array $attributes Additional attributes
     */
    public function __construct(array $attributes = [])
    {
        $this->attributes = $attributes;
    }
    public function getSubNodeNames() : array
    {
        return [];
    }
    public function getType() : string
    {
        return 'Expr_Error';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
class Array_ extends Cast
{
    public function getType() : string
    {
        return 'Expr_Cast_Array';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
class Bool_ extends Cast
{
    public function getType() : string
    {
        return 'Expr_Cast_Bool';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
class Double extends Cast
{
    // For use in "kind" attribute
    const KIND_DOUBLE = 1;
    // "double" syntax
    const KIND_FLOAT = 2;
    // "float" syntax
    const KIND_REAL = 3;
    // "real" syntax
    public function getType() : string
    {
        return 'Expr_Cast_Double';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
class String_ extends Cast
{
    public function getType() : string
    {
        return 'Expr_Cast_String';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
class Unset_ extends Cast
{
    public function getType() : string
    {
        return 'Expr_Cast_Unset';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
class Int_ extends Cast
{
    public function getType() : string
    {
        return 'Expr_Cast_Int';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast;
class Object_ extends Cast
{
    public function getType() : string
    {
        return 'Expr_Cast_Object';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\VariadicPlaceholder;
abstract class CallLike extends Expr
{
    /**
     * Return raw arguments, which may be actual Args, or VariadicPlaceholders for first-class
     * callables.
     *
     * @return array<Arg|VariadicPlaceholder>
     */
    public abstract function getRawArgs() : array;
    /**
     * Returns whether this call expression is actually a first class callable.
     */
    public function isFirstClassCallable() : bool
    {
        foreach ($this->getRawArgs() as $arg) {
            if ($arg instanceof VariadicPlaceholder) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * Assert that this is not a first-class callable and return only ordinary Args.
     *
     * @return Arg[]
     */
    public function getArgs() : array
    {
        \assert(!$this->isFirstClassCallable());
        return $this->getRawArgs();
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class PostInc extends Expr
{
    /** @var Expr Variable */
    public $var;
    /**
     * Constructs a post increment node.
     *
     * @param Expr  $var        Variable
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $var, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
    }
    public function getSubNodeNames() : array
    {
        return ['var'];
    }
    public function getType() : string
    {
        return 'Expr_PostInc';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\VariadicPlaceholder;
class StaticCall extends CallLike
{
    /** @var Node\Name|Expr Class name */
    public $class;
    /** @var Identifier|Expr Method name */
    public $name;
    /** @var array<Arg|VariadicPlaceholder> Arguments */
    public $args;
    /**
     * Constructs a static method call node.
     *
     * @param Node\Name|Expr                 $class      Class name
     * @param string|Identifier|Expr         $name       Method name
     * @param array<Arg|VariadicPlaceholder> $args       Arguments
     * @param array                          $attributes Additional attributes
     */
    public function __construct($class, $name, array $args = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->class = $class;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
        $this->args = $args;
    }
    public function getSubNodeNames() : array
    {
        return ['class', 'name', 'args'];
    }
    public function getType() : string
    {
        return 'Expr_StaticCall';
    }
    public function getRawArgs() : array
    {
        return $this->args;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
abstract class BinaryOp extends Expr
{
    /** @var Expr The left hand side expression */
    public $left;
    /** @var Expr The right hand side expression */
    public $right;
    /**
     * Constructs a binary operator node.
     *
     * @param Expr  $left       The left hand side expression
     * @param Expr  $right      The right hand side expression
     * @param array $attributes Additional attributes
     */
    public function __construct(Expr $left, Expr $right, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->left = $left;
        $this->right = $right;
    }
    public function getSubNodeNames() : array
    {
        return ['left', 'right'];
    }
    /**
     * Get the operator sigil for this binary operation.
     *
     * In the case there are multiple possible sigils for an operator, this method does not
     * necessarily return the one used in the parsed code.
     *
     * @return string
     */
    public abstract function getOperatorSigil() : string;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;

class Relative extends \_HumbugBox1cb33d1f20f1\PhpParser\Node\Name
{
    /**
     * Checks whether the name is unqualified. (E.g. Name)
     *
     * @return bool Whether the name is unqualified
     */
    public function isUnqualified() : bool
    {
        return \false;
    }
    /**
     * Checks whether the name is qualified. (E.g. Name\Name)
     *
     * @return bool Whether the name is qualified
     */
    public function isQualified() : bool
    {
        return \false;
    }
    /**
     * Checks whether the name is fully qualified. (E.g. \Name)
     *
     * @return bool Whether the name is fully qualified
     */
    public function isFullyQualified() : bool
    {
        return \false;
    }
    /**
     * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
     *
     * @return bool Whether the name is relative
     */
    public function isRelative() : bool
    {
        return \true;
    }
    public function toCodeString() : string
    {
        return 'namespace\\' . $this->toString();
    }
    public function getType() : string
    {
        return 'Name_Relative';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;

class FullyQualified extends \_HumbugBox1cb33d1f20f1\PhpParser\Node\Name
{
    /**
     * Checks whether the name is unqualified. (E.g. Name)
     *
     * @return bool Whether the name is unqualified
     */
    public function isUnqualified() : bool
    {
        return \false;
    }
    /**
     * Checks whether the name is qualified. (E.g. Name\Name)
     *
     * @return bool Whether the name is qualified
     */
    public function isQualified() : bool
    {
        return \false;
    }
    /**
     * Checks whether the name is fully qualified. (E.g. \Name)
     *
     * @return bool Whether the name is fully qualified
     */
    public function isFullyQualified() : bool
    {
        return \true;
    }
    /**
     * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name)
     *
     * @return bool Whether the name is relative
     */
    public function isRelative() : bool
    {
        return \false;
    }
    public function toCodeString() : string
    {
        return '\\' . $this->toString();
    }
    public function getType() : string
    {
        return 'Name_FullyQualified';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
/**
 * Represents a non-namespaced name. Namespaced names are represented using Name nodes.
 */
class Identifier extends NodeAbstract
{
    /** @var string Identifier as string */
    public $name;
    private static $specialClassNames = ['self' => \true, 'parent' => \true, 'static' => \true];
    /**
     * Constructs an identifier node.
     *
     * @param string $name       Identifier as string
     * @param array  $attributes Additional attributes
     */
    public function __construct(string $name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = $name;
    }
    public function getSubNodeNames() : array
    {
        return ['name'];
    }
    /**
     * Get identifier as string.
     *
     * @return string Identifier as string.
     */
    public function toString() : string
    {
        return $this->name;
    }
    /**
     * Get lowercased identifier as string.
     *
     * @return string Lowercased identifier as string
     */
    public function toLowerString() : string
    {
        return \strtolower($this->name);
    }
    /**
     * Checks whether the identifier is a special class name (self, parent or static).
     *
     * @return bool Whether identifier is a special class name
     */
    public function isSpecialClassName() : bool
    {
        return isset(self::$specialClassNames[\strtolower($this->name)]);
    }
    /**
     * Get identifier as string.
     *
     * @return string Identifier as string
     */
    public function __toString() : string
    {
        return $this->name;
    }
    public function getType() : string
    {
        return 'Identifier';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

class UnionType extends ComplexType
{
    /** @var (Identifier|Name|IntersectionType)[] Types */
    public $types;
    /**
     * Constructs a union type.
     *
     * @param (Identifier|Name|IntersectionType)[] $types      Types
     * @param array               $attributes Additional attributes
     */
    public function __construct(array $types, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->types = $types;
    }
    public function getSubNodeNames() : array
    {
        return ['types'];
    }
    public function getType() : string
    {
        return 'UnionType';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
abstract class Stmt extends NodeAbstract
{
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
abstract class Expr extends NodeAbstract
{
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node;

class NullableType extends ComplexType
{
    /** @var Identifier|Name Type */
    public $type;
    /**
     * Constructs a nullable type (wrapping another type).
     *
     * @param string|Identifier|Name $type       Type
     * @param array                  $attributes Additional attributes
     */
    public function __construct($type, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->type = \is_string($type) ? new Identifier($type) : $type;
    }
    public function getSubNodeNames() : array
    {
        return ['type'];
    }
    public function getType() : string
    {
        return 'NullableType';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Do_ extends Node\Stmt
{
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /** @var Node\Expr Condition */
    public $cond;
    /**
     * Constructs a do while node.
     *
     * @param Node\Expr   $cond       Condition
     * @param Node\Stmt[] $stmts      Statements
     * @param array       $attributes Additional attributes
     */
    public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['stmts', 'cond'];
    }
    public function getType() : string
    {
        return 'Stmt_Do';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Continue_ extends Node\Stmt
{
    /** @var null|Node\Expr Number of loops to continue */
    public $num;
    /**
     * Constructs a continue node.
     *
     * @param null|Node\Expr $num        Number of loops to continue
     * @param array          $attributes Additional attributes
     */
    public function __construct(Node\Expr $num = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->num = $num;
    }
    public function getSubNodeNames() : array
    {
        return ['num'];
    }
    public function getType() : string
    {
        return 'Stmt_Continue';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Declare_ extends Node\Stmt
{
    /** @var DeclareDeclare[] List of declares */
    public $declares;
    /** @var Node\Stmt[]|null Statements */
    public $stmts;
    /**
     * Constructs a declare node.
     *
     * @param DeclareDeclare[] $declares   List of declares
     * @param Node\Stmt[]|null $stmts      Statements
     * @param array            $attributes Additional attributes
     */
    public function __construct(array $declares, array $stmts = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->declares = $declares;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['declares', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Declare';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Else_ extends Node\Stmt
{
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs an else node.
     *
     * @param Node\Stmt[] $stmts      Statements
     * @param array       $attributes Additional attributes
     */
    public function __construct(array $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Else';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class Catch_ extends Node\Stmt
{
    /** @var Node\Name[] Types of exceptions to catch */
    public $types;
    /** @var Expr\Variable|null Variable for exception */
    public $var;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs a catch node.
     *
     * @param Node\Name[]           $types      Types of exceptions to catch
     * @param Expr\Variable|null    $var        Variable for exception
     * @param Node\Stmt[]           $stmts      Statements
     * @param array                 $attributes Additional attributes
     */
    public function __construct(array $types, Expr\Variable $var = null, array $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->types = $types;
        $this->var = $var;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['types', 'var', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Catch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Class_ extends ClassLike
{
    const MODIFIER_PUBLIC = 1;
    const MODIFIER_PROTECTED = 2;
    const MODIFIER_PRIVATE = 4;
    const MODIFIER_STATIC = 8;
    const MODIFIER_ABSTRACT = 16;
    const MODIFIER_FINAL = 32;
    const MODIFIER_READONLY = 64;
    const VISIBILITY_MODIFIER_MASK = 7;
    // 1 | 2 | 4
    /** @var int Type */
    public $flags;
    /** @var null|Node\Name Name of extended class */
    public $extends;
    /** @var Node\Name[] Names of implemented interfaces */
    public $implements;
    /**
     * Constructs a class node.
     *
     * @param string|Node\Identifier|null $name Name
     * @param array       $subNodes   Array of the following optional subnodes:
     *                                'flags'       => 0      : Flags
     *                                'extends'     => null   : Name of extended class
     *                                'implements'  => array(): Names of implemented interfaces
     *                                'stmts'       => array(): Statements
     *                                'attrGroups'  => array(): PHP attribute groups
     * @param array       $attributes Additional attributes
     */
    public function __construct($name, array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0;
        $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
        $this->extends = $subNodes['extends'] ?? null;
        $this->implements = $subNodes['implements'] ?? [];
        $this->stmts = $subNodes['stmts'] ?? [];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'flags', 'name', 'extends', 'implements', 'stmts'];
    }
    /**
     * Whether the class is explicitly abstract.
     *
     * @return bool
     */
    public function isAbstract() : bool
    {
        return (bool) ($this->flags & self::MODIFIER_ABSTRACT);
    }
    /**
     * Whether the class is final.
     *
     * @return bool
     */
    public function isFinal() : bool
    {
        return (bool) ($this->flags & self::MODIFIER_FINAL);
    }
    public function isReadonly() : bool
    {
        return (bool) ($this->flags & self::MODIFIER_READONLY);
    }
    /**
     * Whether the class is anonymous.
     *
     * @return bool
     */
    public function isAnonymous() : bool
    {
        return null === $this->name;
    }
    /**
     * @internal
     */
    public static function verifyClassModifier($a, $b)
    {
        if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) {
            throw new Error('Multiple abstract modifiers are not allowed');
        }
        if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) {
            throw new Error('Multiple final modifiers are not allowed');
        }
        if ($a & self::MODIFIER_READONLY && $b & self::MODIFIER_READONLY) {
            throw new Error('Multiple readonly modifiers are not allowed');
        }
        if ($a & 48 && $b & 48) {
            throw new Error('Cannot use the final modifier on an abstract class');
        }
    }
    /**
     * @internal
     */
    public static function verifyModifier($a, $b)
    {
        if ($a & self::VISIBILITY_MODIFIER_MASK && $b & self::VISIBILITY_MODIFIER_MASK) {
            throw new Error('Multiple access type modifiers are not allowed');
        }
        if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) {
            throw new Error('Multiple abstract modifiers are not allowed');
        }
        if ($a & self::MODIFIER_STATIC && $b & self::MODIFIER_STATIC) {
            throw new Error('Multiple static modifiers are not allowed');
        }
        if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) {
            throw new Error('Multiple final modifiers are not allowed');
        }
        if ($a & self::MODIFIER_READONLY && $b & self::MODIFIER_READONLY) {
            throw new Error('Multiple readonly modifiers are not allowed');
        }
        if ($a & 48 && $b & 48) {
            throw new Error('Cannot use the final modifier on an abstract class member');
        }
    }
    public function getType() : string
    {
        return 'Stmt_Class';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Echo_ extends Node\Stmt
{
    /** @var Node\Expr[] Expressions */
    public $exprs;
    /**
     * Constructs an echo node.
     *
     * @param Node\Expr[] $exprs      Expressions
     * @param array       $attributes Additional attributes
     */
    public function __construct(array $exprs, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->exprs = $exprs;
    }
    public function getSubNodeNames() : array
    {
        return ['exprs'];
    }
    public function getType() : string
    {
        return 'Stmt_Echo';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\TraitUseAdaptation;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Precedence extends Node\Stmt\TraitUseAdaptation
{
    /** @var Node\Name[] Overwritten traits */
    public $insteadof;
    /**
     * Constructs a trait use precedence adaptation node.
     *
     * @param Node\Name              $trait       Trait name
     * @param string|Node\Identifier $method      Method name
     * @param Node\Name[]            $insteadof   Overwritten traits
     * @param array                  $attributes  Additional attributes
     */
    public function __construct(Node\Name $trait, $method, array $insteadof, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->trait = $trait;
        $this->method = \is_string($method) ? new Node\Identifier($method) : $method;
        $this->insteadof = $insteadof;
    }
    public function getSubNodeNames() : array
    {
        return ['trait', 'method', 'insteadof'];
    }
    public function getType() : string
    {
        return 'Stmt_TraitUseAdaptation_Precedence';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\TraitUseAdaptation;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Alias extends Node\Stmt\TraitUseAdaptation
{
    /** @var null|int New modifier */
    public $newModifier;
    /** @var null|Node\Identifier New name */
    public $newName;
    /**
     * Constructs a trait use precedence adaptation node.
     *
     * @param null|Node\Name              $trait       Trait name
     * @param string|Node\Identifier      $method      Method name
     * @param null|int                    $newModifier New modifier
     * @param null|string|Node\Identifier $newName     New name
     * @param array                       $attributes  Additional attributes
     */
    public function __construct($trait, $method, $newModifier, $newName, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->trait = $trait;
        $this->method = \is_string($method) ? new Node\Identifier($method) : $method;
        $this->newModifier = $newModifier;
        $this->newName = \is_string($newName) ? new Node\Identifier($newName) : $newName;
    }
    public function getSubNodeNames() : array
    {
        return ['trait', 'method', 'newModifier', 'newName'];
    }
    public function getType() : string
    {
        return 'Stmt_TraitUseAdaptation_Alias';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Trait_ extends ClassLike
{
    /**
     * Constructs a trait node.
     *
     * @param string|Node\Identifier $name Name
     * @param array  $subNodes   Array of the following optional subnodes:
     *                           'stmts'      => array(): Statements
     *                           'attrGroups' => array(): PHP attribute groups
     * @param array  $attributes Additional attributes
     */
    public function __construct($name, array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
        $this->stmts = $subNodes['stmts'] ?? [];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'name', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Trait';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Use_ extends Stmt
{
    /**
     * Unknown type. Both Stmt\Use_ / Stmt\GroupUse and Stmt\UseUse have a $type property, one of them will always be
     * TYPE_UNKNOWN while the other has one of the three other possible types. For normal use statements the type on the
     * Stmt\UseUse is unknown. It's only the other way around for mixed group use declarations.
     */
    const TYPE_UNKNOWN = 0;
    /** Class or namespace import */
    const TYPE_NORMAL = 1;
    /** Function import */
    const TYPE_FUNCTION = 2;
    /** Constant import */
    const TYPE_CONSTANT = 3;
    /** @var int Type of alias */
    public $type;
    /** @var UseUse[] Aliases */
    public $uses;
    /**
     * Constructs an alias (use) list node.
     *
     * @param UseUse[] $uses       Aliases
     * @param int      $type       Type of alias
     * @param array    $attributes Additional attributes
     */
    public function __construct(array $uses, int $type = self::TYPE_NORMAL, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->type = $type;
        $this->uses = $uses;
    }
    public function getSubNodeNames() : array
    {
        return ['type', 'uses'];
    }
    public function getType() : string
    {
        return 'Stmt_Use';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\AttributeGroup;
class EnumCase extends Node\Stmt
{
    /** @var Node\Identifier Enum case name */
    public $name;
    /** @var Node\Expr|null Enum case expression */
    public $expr;
    /** @var Node\AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    /**
     * @param string|Node\Identifier    $name       Enum case name
     * @param Node\Expr|null            $expr       Enum case expression
     * @param AttributeGroup[]          $attrGroups PHP attribute groups
     * @param array                     $attributes Additional attributes
     */
    public function __construct($name, Node\Expr $expr = null, array $attrGroups = [], array $attributes = [])
    {
        parent::__construct($attributes);
        $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
        $this->expr = $expr;
        $this->attrGroups = $attrGroups;
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'name', 'expr'];
    }
    public function getType() : string
    {
        return 'Stmt_EnumCase';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Interface_ extends ClassLike
{
    /** @var Node\Name[] Extended interfaces */
    public $extends;
    /**
     * Constructs a class node.
     *
     * @param string|Node\Identifier $name Name
     * @param array  $subNodes   Array of the following optional subnodes:
     *                           'extends'    => array(): Name of extended interfaces
     *                           'stmts'      => array(): Statements
     *                           'attrGroups' => array(): PHP attribute groups
     * @param array  $attributes Additional attributes
     */
    public function __construct($name, array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
        $this->extends = $subNodes['extends'] ?? [];
        $this->stmts = $subNodes['stmts'] ?? [];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'name', 'extends', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Interface';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class TraitUse extends Node\Stmt
{
    /** @var Node\Name[] Traits */
    public $traits;
    /** @var TraitUseAdaptation[] Adaptations */
    public $adaptations;
    /**
     * Constructs a trait use node.
     *
     * @param Node\Name[]          $traits      Traits
     * @param TraitUseAdaptation[] $adaptations Adaptations
     * @param array                $attributes  Additional attributes
     */
    public function __construct(array $traits, array $adaptations = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->traits = $traits;
        $this->adaptations = $adaptations;
    }
    public function getSubNodeNames() : array
    {
        return ['traits', 'adaptations'];
    }
    public function getType() : string
    {
        return 'Stmt_TraitUse';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\FunctionLike;
class Function_ extends Node\Stmt implements FunctionLike
{
    /** @var bool Whether function returns by reference */
    public $byRef;
    /** @var Node\Identifier Name */
    public $name;
    /** @var Node\Param[] Parameters */
    public $params;
    /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
    public $returnType;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /** @var Node\AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    /** @var Node\Name|null Namespaced name (if using NameResolver) */
    public $namespacedName;
    /**
     * Constructs a function node.
     *
     * @param string|Node\Identifier $name Name
     * @param array  $subNodes   Array of the following optional subnodes:
     *                           'byRef'      => false  : Whether to return by reference
     *                           'params'     => array(): Parameters
     *                           'returnType' => null   : Return type
     *                           'stmts'      => array(): Statements
     *                           'attrGroups' => array(): PHP attribute groups
     * @param array  $attributes Additional attributes
     */
    public function __construct($name, array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->byRef = $subNodes['byRef'] ?? \false;
        $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
        $this->params = $subNodes['params'] ?? [];
        $returnType = $subNodes['returnType'] ?? null;
        $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
        $this->stmts = $subNodes['stmts'] ?? [];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'byRef', 'name', 'params', 'returnType', 'stmts'];
    }
    public function returnsByRef() : bool
    {
        return $this->byRef;
    }
    public function getParams() : array
    {
        return $this->params;
    }
    public function getReturnType()
    {
        return $this->returnType;
    }
    public function getAttrGroups() : array
    {
        return $this->attrGroups;
    }
    /** @return Node\Stmt[] */
    public function getStmts() : array
    {
        return $this->stmts;
    }
    public function getType() : string
    {
        return 'Stmt_Function';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Static_ extends Stmt
{
    /** @var StaticVar[] Variable definitions */
    public $vars;
    /**
     * Constructs a static variables list node.
     *
     * @param StaticVar[] $vars       Variable definitions
     * @param array       $attributes Additional attributes
     */
    public function __construct(array $vars, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->vars = $vars;
    }
    public function getSubNodeNames() : array
    {
        return ['vars'];
    }
    public function getType() : string
    {
        return 'Stmt_Static';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Label extends Stmt
{
    /** @var Identifier Name */
    public $name;
    /**
     * Constructs a label node.
     *
     * @param string|Identifier $name       Name
     * @param array             $attributes Additional attributes
     */
    public function __construct($name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
    }
    public function getSubNodeNames() : array
    {
        return ['name'];
    }
    public function getType() : string
    {
        return 'Stmt_Label';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
abstract class ClassLike extends Node\Stmt
{
    /** @var Node\Identifier|null Name */
    public $name;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /** @var Node\AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    /** @var Node\Name|null Namespaced name (if using NameResolver) */
    public $namespacedName;
    /**
     * @return TraitUse[]
     */
    public function getTraitUses() : array
    {
        $traitUses = [];
        foreach ($this->stmts as $stmt) {
            if ($stmt instanceof TraitUse) {
                $traitUses[] = $stmt;
            }
        }
        return $traitUses;
    }
    /**
     * @return ClassConst[]
     */
    public function getConstants() : array
    {
        $constants = [];
        foreach ($this->stmts as $stmt) {
            if ($stmt instanceof ClassConst) {
                $constants[] = $stmt;
            }
        }
        return $constants;
    }
    /**
     * @return Property[]
     */
    public function getProperties() : array
    {
        $properties = [];
        foreach ($this->stmts as $stmt) {
            if ($stmt instanceof Property) {
                $properties[] = $stmt;
            }
        }
        return $properties;
    }
    /**
     * Gets property with the given name defined directly in this class/interface/trait.
     *
     * @param string $name Name of the property
     *
     * @return Property|null Property node or null if the property does not exist
     */
    public function getProperty(string $name)
    {
        foreach ($this->stmts as $stmt) {
            if ($stmt instanceof Property) {
                foreach ($stmt->props as $prop) {
                    if ($prop instanceof PropertyProperty && $name === $prop->name->toString()) {
                        return $stmt;
                    }
                }
            }
        }
        return null;
    }
    /**
     * Gets all methods defined directly in this class/interface/trait
     *
     * @return ClassMethod[]
     */
    public function getMethods() : array
    {
        $methods = [];
        foreach ($this->stmts as $stmt) {
            if ($stmt instanceof ClassMethod) {
                $methods[] = $stmt;
            }
        }
        return $methods;
    }
    /**
     * Gets method with the given name defined directly in this class/interface/trait.
     *
     * @param string $name Name of the method (compared case-insensitively)
     *
     * @return ClassMethod|null Method node or null if the method does not exist
     */
    public function getMethod(string $name)
    {
        $lowerName = \strtolower($name);
        foreach ($this->stmts as $stmt) {
            if ($stmt instanceof ClassMethod && $lowerName === $stmt->name->toLowerString()) {
                return $stmt;
            }
        }
        return null;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\ComplexType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
class Property extends Node\Stmt
{
    /** @var int Modifiers */
    public $flags;
    /** @var PropertyProperty[] Properties */
    public $props;
    /** @var null|Identifier|Name|ComplexType Type declaration */
    public $type;
    /** @var Node\AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    /**
     * Constructs a class property list node.
     *
     * @param int                                     $flags      Modifiers
     * @param PropertyProperty[]                      $props      Properties
     * @param array                                   $attributes Additional attributes
     * @param null|string|Identifier|Name|ComplexType $type       Type declaration
     * @param Node\AttributeGroup[]                   $attrGroups PHP attribute groups
     */
    public function __construct(int $flags, array $props, array $attributes = [], $type = null, array $attrGroups = [])
    {
        $this->attributes = $attributes;
        $this->flags = $flags;
        $this->props = $props;
        $this->type = \is_string($type) ? new Identifier($type) : $type;
        $this->attrGroups = $attrGroups;
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'flags', 'type', 'props'];
    }
    /**
     * Whether the property is explicitly or implicitly public.
     *
     * @return bool
     */
    public function isPublic() : bool
    {
        return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0;
    }
    /**
     * Whether the property is protected.
     *
     * @return bool
     */
    public function isProtected() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_PROTECTED);
    }
    /**
     * Whether the property is private.
     *
     * @return bool
     */
    public function isPrivate() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_PRIVATE);
    }
    /**
     * Whether the property is static.
     *
     * @return bool
     */
    public function isStatic() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_STATIC);
    }
    /**
     * Whether the property is readonly.
     *
     * @return bool
     */
    public function isReadonly() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_READONLY);
    }
    public function getType() : string
    {
        return 'Stmt_Property';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Enum_ extends ClassLike
{
    /** @var null|Node\Identifier Scalar Type */
    public $scalarType;
    /** @var Node\Name[] Names of implemented interfaces */
    public $implements;
    /**
     * @param string|Node\Identifier|null $name       Name
     * @param array                       $subNodes   Array of the following optional subnodes:
     *                                                'scalarType'  => null    : Scalar type
     *                                                'implements'  => array() : Names of implemented interfaces
     *                                                'stmts'       => array() : Statements
     *                                                'attrGroups'  => array() : PHP attribute groups
     * @param array                       $attributes Additional attributes
     */
    public function __construct($name, array $subNodes = [], array $attributes = [])
    {
        $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
        $this->scalarType = $subNodes['scalarType'] ?? null;
        $this->implements = $subNodes['implements'] ?? [];
        $this->stmts = $subNodes['stmts'] ?? [];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
        parent::__construct($attributes);
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'name', 'scalarType', 'implements', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Enum';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Const_ extends Node\Stmt
{
    /** @var Node\Const_[] Constant declarations */
    public $consts;
    /**
     * Constructs a const list node.
     *
     * @param Node\Const_[] $consts     Constant declarations
     * @param array         $attributes Additional attributes
     */
    public function __construct(array $consts, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->consts = $consts;
    }
    public function getSubNodeNames() : array
    {
        return ['consts'];
    }
    public function getType() : string
    {
        return 'Stmt_Const';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Switch_ extends Node\Stmt
{
    /** @var Node\Expr Condition */
    public $cond;
    /** @var Case_[] Case list */
    public $cases;
    /**
     * Constructs a case node.
     *
     * @param Node\Expr $cond       Condition
     * @param Case_[]   $cases      Case list
     * @param array     $attributes Additional attributes
     */
    public function __construct(Node\Expr $cond, array $cases, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->cases = $cases;
    }
    public function getSubNodeNames() : array
    {
        return ['cond', 'cases'];
    }
    public function getType() : string
    {
        return 'Stmt_Switch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class DeclareDeclare extends Node\Stmt
{
    /** @var Node\Identifier Key */
    public $key;
    /** @var Node\Expr Value */
    public $value;
    /**
     * Constructs a declare key=>value pair node.
     *
     * @param string|Node\Identifier $key        Key
     * @param Node\Expr              $value      Value
     * @param array                  $attributes Additional attributes
     */
    public function __construct($key, Node\Expr $value, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->key = \is_string($key) ? new Node\Identifier($key) : $key;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['key', 'value'];
    }
    public function getType() : string
    {
        return 'Stmt_DeclareDeclare';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class Goto_ extends Stmt
{
    /** @var Identifier Name of label to jump to */
    public $name;
    /**
     * Constructs a goto node.
     *
     * @param string|Identifier $name       Name of label to jump to
     * @param array             $attributes Additional attributes
     */
    public function __construct($name, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = \is_string($name) ? new Identifier($name) : $name;
    }
    public function getSubNodeNames() : array
    {
        return ['name'];
    }
    public function getType() : string
    {
        return 'Stmt_Goto';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
/**
 * Represents statements of type "expr;"
 */
class Expression extends Node\Stmt
{
    /** @var Node\Expr Expression */
    public $expr;
    /**
     * Constructs an expression statement.
     *
     * @param Node\Expr $expr       Expression
     * @param array     $attributes Additional attributes
     */
    public function __construct(Node\Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Stmt_Expression';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Throw_ extends Node\Stmt
{
    /** @var Node\Expr Expression */
    public $expr;
    /**
     * Constructs a legacy throw statement node.
     *
     * @param Node\Expr $expr       Expression
     * @param array     $attributes Additional attributes
     */
    public function __construct(Node\Expr $expr, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Stmt_Throw';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class While_ extends Node\Stmt
{
    /** @var Node\Expr Condition */
    public $cond;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs a while node.
     *
     * @param Node\Expr   $cond       Condition
     * @param Node\Stmt[] $stmts      Statements
     * @param array       $attributes Additional attributes
     */
    public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['cond', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_While';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Namespace_ extends Node\Stmt
{
    /* For use in the "kind" attribute */
    const KIND_SEMICOLON = 1;
    const KIND_BRACED = 2;
    /** @var null|Node\Name Name */
    public $name;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs a namespace node.
     *
     * @param null|Node\Name   $name       Name
     * @param null|Node\Stmt[] $stmts      Statements
     * @param array            $attributes Additional attributes
     */
    public function __construct(Node\Name $name = null, $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = $name;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['name', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Namespace';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Break_ extends Node\Stmt
{
    /** @var null|Node\Expr Number of loops to break */
    public $num;
    /**
     * Constructs a break node.
     *
     * @param null|Node\Expr $num        Number of loops to break
     * @param array          $attributes Additional attributes
     */
    public function __construct(Node\Expr $num = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->num = $num;
    }
    public function getSubNodeNames() : array
    {
        return ['num'];
    }
    public function getType() : string
    {
        return 'Stmt_Break';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class If_ extends Node\Stmt
{
    /** @var Node\Expr Condition expression */
    public $cond;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /** @var ElseIf_[] Elseif clauses */
    public $elseifs;
    /** @var null|Else_ Else clause */
    public $else;
    /**
     * Constructs an if node.
     *
     * @param Node\Expr $cond       Condition
     * @param array     $subNodes   Array of the following optional subnodes:
     *                              'stmts'   => array(): Statements
     *                              'elseifs' => array(): Elseif clauses
     *                              'else'    => null   : Else clause
     * @param array     $attributes Additional attributes
     */
    public function __construct(Node\Expr $cond, array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->stmts = $subNodes['stmts'] ?? [];
        $this->elseifs = $subNodes['elseifs'] ?? [];
        $this->else = $subNodes['else'] ?? null;
    }
    public function getSubNodeNames() : array
    {
        return ['cond', 'stmts', 'elseifs', 'else'];
    }
    public function getType() : string
    {
        return 'Stmt_If';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class HaltCompiler extends Stmt
{
    /** @var string Remaining text after halt compiler statement. */
    public $remaining;
    /**
     * Constructs a __halt_compiler node.
     *
     * @param string $remaining  Remaining text after halt compiler statement.
     * @param array  $attributes Additional attributes
     */
    public function __construct(string $remaining, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->remaining = $remaining;
    }
    public function getSubNodeNames() : array
    {
        return ['remaining'];
    }
    public function getType() : string
    {
        return 'Stmt_HaltCompiler';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class For_ extends Node\Stmt
{
    /** @var Node\Expr[] Init expressions */
    public $init;
    /** @var Node\Expr[] Loop conditions */
    public $cond;
    /** @var Node\Expr[] Loop expressions */
    public $loop;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs a for loop node.
     *
     * @param array $subNodes   Array of the following optional subnodes:
     *                          'init'  => array(): Init expressions
     *                          'cond'  => array(): Loop conditions
     *                          'loop'  => array(): Loop expressions
     *                          'stmts' => array(): Statements
     * @param array $attributes Additional attributes
     */
    public function __construct(array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->init = $subNodes['init'] ?? [];
        $this->cond = $subNodes['cond'] ?? [];
        $this->loop = $subNodes['loop'] ?? [];
        $this->stmts = $subNodes['stmts'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['init', 'cond', 'loop', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_For';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
class StaticVar extends Node\Stmt
{
    /** @var Expr\Variable Variable */
    public $var;
    /** @var null|Node\Expr Default value */
    public $default;
    /**
     * Constructs a static variable node.
     *
     * @param Expr\Variable  $var         Name
     * @param null|Node\Expr $default    Default value
     * @param array          $attributes Additional attributes
     */
    public function __construct(Expr\Variable $var, Node\Expr $default = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->var = $var;
        $this->default = $default;
    }
    public function getSubNodeNames() : array
    {
        return ['var', 'default'];
    }
    public function getType() : string
    {
        return 'Stmt_StaticVar';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Global_ extends Node\Stmt
{
    /** @var Node\Expr[] Variables */
    public $vars;
    /**
     * Constructs a global variables list node.
     *
     * @param Node\Expr[] $vars       Variables to unset
     * @param array       $attributes Additional attributes
     */
    public function __construct(array $vars, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->vars = $vars;
    }
    public function getSubNodeNames() : array
    {
        return ['vars'];
    }
    public function getType() : string
    {
        return 'Stmt_Global';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
abstract class TraitUseAdaptation extends Node\Stmt
{
    /** @var Node\Name|null Trait name */
    public $trait;
    /** @var Node\Identifier Method name */
    public $method;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class ElseIf_ extends Node\Stmt
{
    /** @var Node\Expr Condition */
    public $cond;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs an elseif node.
     *
     * @param Node\Expr   $cond       Condition
     * @param Node\Stmt[] $stmts      Statements
     * @param array       $attributes Additional attributes
     */
    public function __construct(Node\Expr $cond, array $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['cond', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_ElseIf';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Return_ extends Node\Stmt
{
    /** @var null|Node\Expr Expression */
    public $expr;
    /**
     * Constructs a return node.
     *
     * @param null|Node\Expr $expr       Expression
     * @param array          $attributes Additional attributes
     */
    public function __construct(Node\Expr $expr = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
    }
    public function getSubNodeNames() : array
    {
        return ['expr'];
    }
    public function getType() : string
    {
        return 'Stmt_Return';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
/** Nop/empty statement (;). */
class Nop extends Node\Stmt
{
    public function getSubNodeNames() : array
    {
        return [];
    }
    public function getType() : string
    {
        return 'Stmt_Nop';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Foreach_ extends Node\Stmt
{
    /** @var Node\Expr Expression to iterate */
    public $expr;
    /** @var null|Node\Expr Variable to assign key to */
    public $keyVar;
    /** @var bool Whether to assign value by reference */
    public $byRef;
    /** @var Node\Expr Variable to assign value to */
    public $valueVar;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs a foreach node.
     *
     * @param Node\Expr $expr       Expression to iterate
     * @param Node\Expr $valueVar   Variable to assign value to
     * @param array     $subNodes   Array of the following optional subnodes:
     *                              'keyVar' => null   : Variable to assign key to
     *                              'byRef'  => false  : Whether to assign value by reference
     *                              'stmts'  => array(): Statements
     * @param array     $attributes Additional attributes
     */
    public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->expr = $expr;
        $this->keyVar = $subNodes['keyVar'] ?? null;
        $this->byRef = $subNodes['byRef'] ?? \false;
        $this->valueVar = $valueVar;
        $this->stmts = $subNodes['stmts'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['expr', 'keyVar', 'byRef', 'valueVar', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Foreach';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class TryCatch extends Node\Stmt
{
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /** @var Catch_[] Catches */
    public $catches;
    /** @var null|Finally_ Optional finally node */
    public $finally;
    /**
     * Constructs a try catch node.
     *
     * @param Node\Stmt[]   $stmts      Statements
     * @param Catch_[]      $catches    Catches
     * @param null|Finally_ $finally    Optional finally node
     * @param array         $attributes Additional attributes
     */
    public function __construct(array $stmts, array $catches, Finally_ $finally = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->stmts = $stmts;
        $this->catches = $catches;
        $this->finally = $finally;
    }
    public function getSubNodeNames() : array
    {
        return ['stmts', 'catches', 'finally'];
    }
    public function getType() : string
    {
        return 'Stmt_TryCatch';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Case_ extends Node\Stmt
{
    /** @var null|Node\Expr Condition (null for default) */
    public $cond;
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs a case node.
     *
     * @param null|Node\Expr $cond       Condition (null for default)
     * @param Node\Stmt[]    $stmts      Statements
     * @param array          $attributes Additional attributes
     */
    public function __construct($cond, array $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->cond = $cond;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['cond', 'stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Case';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Unset_ extends Node\Stmt
{
    /** @var Node\Expr[] Variables to unset */
    public $vars;
    /**
     * Constructs an unset node.
     *
     * @param Node\Expr[] $vars       Variables to unset
     * @param array       $attributes Additional attributes
     */
    public function __construct(array $vars, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->vars = $vars;
    }
    public function getSubNodeNames() : array
    {
        return ['vars'];
    }
    public function getType() : string
    {
        return 'Stmt_Unset';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
class UseUse extends Node\Stmt
{
    /** @var int One of the Stmt\Use_::TYPE_* constants. Will only differ from TYPE_UNKNOWN for mixed group uses */
    public $type;
    /** @var Node\Name Namespace, class, function or constant to alias */
    public $name;
    /** @var Identifier|null Alias */
    public $alias;
    /**
     * Constructs an alias (use) node.
     *
     * @param Node\Name              $name       Namespace/Class to alias
     * @param null|string|Identifier $alias      Alias
     * @param int                    $type       Type of the use element (for mixed group use only)
     * @param array                  $attributes Additional attributes
     */
    public function __construct(Node\Name $name, $alias = null, int $type = Use_::TYPE_UNKNOWN, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->type = $type;
        $this->name = $name;
        $this->alias = \is_string($alias) ? new Identifier($alias) : $alias;
    }
    public function getSubNodeNames() : array
    {
        return ['type', 'name', 'alias'];
    }
    /**
     * Get alias. If not explicitly given this is the last component of the used name.
     *
     * @return Identifier
     */
    public function getAlias() : Identifier
    {
        if (null !== $this->alias) {
            return $this->alias;
        }
        return new Identifier($this->name->getLast());
    }
    public function getType() : string
    {
        return 'Stmt_UseUse';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class Finally_ extends Node\Stmt
{
    /** @var Node\Stmt[] Statements */
    public $stmts;
    /**
     * Constructs a finally node.
     *
     * @param Node\Stmt[] $stmts      Statements
     * @param array       $attributes Additional attributes
     */
    public function __construct(array $stmts = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->stmts = $stmts;
    }
    public function getSubNodeNames() : array
    {
        return ['stmts'];
    }
    public function getType() : string
    {
        return 'Stmt_Finally';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class InlineHTML extends Stmt
{
    /** @var string String */
    public $value;
    /**
     * Constructs an inline HTML node.
     *
     * @param string $value      String
     * @param array  $attributes Additional attributes
     */
    public function __construct(string $value, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->value = $value;
    }
    public function getSubNodeNames() : array
    {
        return ['value'];
    }
    public function getType() : string
    {
        return 'Stmt_InlineHTML';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
class GroupUse extends Stmt
{
    /** @var int Type of group use */
    public $type;
    /** @var Name Prefix for uses */
    public $prefix;
    /** @var UseUse[] Uses */
    public $uses;
    /**
     * Constructs a group use node.
     *
     * @param Name     $prefix     Prefix for uses
     * @param UseUse[] $uses       Uses
     * @param int      $type       Type of group use
     * @param array    $attributes Additional attributes
     */
    public function __construct(Name $prefix, array $uses, int $type = Use_::TYPE_NORMAL, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->type = $type;
        $this->prefix = $prefix;
        $this->uses = $uses;
    }
    public function getSubNodeNames() : array
    {
        return ['type', 'prefix', 'uses'];
    }
    public function getType() : string
    {
        return 'Stmt_GroupUse';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\FunctionLike;
class ClassMethod extends Node\Stmt implements FunctionLike
{
    /** @var int Flags */
    public $flags;
    /** @var bool Whether to return by reference */
    public $byRef;
    /** @var Node\Identifier Name */
    public $name;
    /** @var Node\Param[] Parameters */
    public $params;
    /** @var null|Node\Identifier|Node\Name|Node\ComplexType Return type */
    public $returnType;
    /** @var Node\Stmt[]|null Statements */
    public $stmts;
    /** @var Node\AttributeGroup[] PHP attribute groups */
    public $attrGroups;
    private static $magicNames = ['__construct' => \true, '__destruct' => \true, '__call' => \true, '__callstatic' => \true, '__get' => \true, '__set' => \true, '__isset' => \true, '__unset' => \true, '__sleep' => \true, '__wakeup' => \true, '__tostring' => \true, '__set_state' => \true, '__clone' => \true, '__invoke' => \true, '__debuginfo' => \true, '__serialize' => \true, '__unserialize' => \true];
    /**
     * Constructs a class method node.
     *
     * @param string|Node\Identifier $name Name
     * @param array $subNodes   Array of the following optional subnodes:
     *                          'flags       => MODIFIER_PUBLIC: Flags
     *                          'byRef'      => false          : Whether to return by reference
     *                          'params'     => array()        : Parameters
     *                          'returnType' => null           : Return type
     *                          'stmts'      => array()        : Statements
     *                          'attrGroups' => array()        : PHP attribute groups
     * @param array $attributes Additional attributes
     */
    public function __construct($name, array $subNodes = [], array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0;
        $this->byRef = $subNodes['byRef'] ?? \false;
        $this->name = \is_string($name) ? new Node\Identifier($name) : $name;
        $this->params = $subNodes['params'] ?? [];
        $returnType = $subNodes['returnType'] ?? null;
        $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
        $this->stmts = \array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : [];
        $this->attrGroups = $subNodes['attrGroups'] ?? [];
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'returnType', 'stmts'];
    }
    public function returnsByRef() : bool
    {
        return $this->byRef;
    }
    public function getParams() : array
    {
        return $this->params;
    }
    public function getReturnType()
    {
        return $this->returnType;
    }
    public function getStmts()
    {
        return $this->stmts;
    }
    public function getAttrGroups() : array
    {
        return $this->attrGroups;
    }
    /**
     * Whether the method is explicitly or implicitly public.
     *
     * @return bool
     */
    public function isPublic() : bool
    {
        return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0;
    }
    /**
     * Whether the method is protected.
     *
     * @return bool
     */
    public function isProtected() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_PROTECTED);
    }
    /**
     * Whether the method is private.
     *
     * @return bool
     */
    public function isPrivate() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_PRIVATE);
    }
    /**
     * Whether the method is abstract.
     *
     * @return bool
     */
    public function isAbstract() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_ABSTRACT);
    }
    /**
     * Whether the method is final.
     *
     * @return bool
     */
    public function isFinal() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_FINAL);
    }
    /**
     * Whether the method is static.
     *
     * @return bool
     */
    public function isStatic() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_STATIC);
    }
    /**
     * Whether the method is magic.
     *
     * @return bool
     */
    public function isMagic() : bool
    {
        return isset(self::$magicNames[$this->name->toLowerString()]);
    }
    public function getType() : string
    {
        return 'Stmt_ClassMethod';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class PropertyProperty extends Node\Stmt
{
    /** @var Node\VarLikeIdentifier Name */
    public $name;
    /** @var null|Node\Expr Default */
    public $default;
    /**
     * Constructs a class property node.
     *
     * @param string|Node\VarLikeIdentifier $name       Name
     * @param null|Node\Expr                $default    Default value
     * @param array                         $attributes Additional attributes
     */
    public function __construct($name, Node\Expr $default = null, array $attributes = [])
    {
        $this->attributes = $attributes;
        $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name;
        $this->default = $default;
    }
    public function getSubNodeNames() : array
    {
        return ['name', 'default'];
    }
    public function getType() : string
    {
        return 'Stmt_PropertyProperty';
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
class ClassConst extends Node\Stmt
{
    /** @var int Modifiers */
    public $flags;
    /** @var Node\Const_[] Constant declarations */
    public $consts;
    /** @var Node\AttributeGroup[] */
    public $attrGroups;
    /**
     * Constructs a class const list node.
     *
     * @param Node\Const_[]         $consts     Constant declarations
     * @param int                   $flags      Modifiers
     * @param array                 $attributes Additional attributes
     * @param Node\AttributeGroup[] $attrGroups PHP attribute groups
     */
    public function __construct(array $consts, int $flags = 0, array $attributes = [], array $attrGroups = [])
    {
        $this->attributes = $attributes;
        $this->flags = $flags;
        $this->consts = $consts;
        $this->attrGroups = $attrGroups;
    }
    public function getSubNodeNames() : array
    {
        return ['attrGroups', 'flags', 'consts'];
    }
    /**
     * Whether constant is explicitly or implicitly public.
     *
     * @return bool
     */
    public function isPublic() : bool
    {
        return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0;
    }
    /**
     * Whether constant is protected.
     *
     * @return bool
     */
    public function isProtected() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_PROTECTED);
    }
    /**
     * Whether constant is private.
     *
     * @return bool
     */
    public function isPrivate() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_PRIVATE);
    }
    /**
     * Whether constant is final.
     *
     * @return bool
     */
    public function isFinal() : bool
    {
        return (bool) ($this->flags & Class_::MODIFIER_FINAL);
    }
    public function getType() : string
    {
        return 'Stmt_ClassConst';
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\PhpParser\Parser;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
/* This is an automatically GENERATED file, which should not be manually edited.
 * Instead edit one of the following:
 *  * the grammar files grammar/php5.y or grammar/php7.y
 *  * the skeleton file grammar/parser.template
 *  * the preprocessing script grammar/rebuildParsers.php
 */
class Php7 extends \_HumbugBox1cb33d1f20f1\PhpParser\ParserAbstract
{
    protected $tokenToSymbolMapSize = 396;
    protected $actionTableSize = 1223;
    protected $gotoTableSize = 626;
    protected $invalidSymbol = 168;
    protected $errorSymbol = 1;
    protected $defaultAction = -32766;
    protected $unexpectedTokenRule = 32767;
    protected $YY2TBLSTATE = 429;
    protected $numNonLeafStates = 726;
    protected $symbolToName = array("EOF", "error", "T_THROW", "T_INCLUDE", "T_INCLUDE_ONCE", "T_EVAL", "T_REQUIRE", "T_REQUIRE_ONCE", "','", "T_LOGICAL_OR", "T_LOGICAL_XOR", "T_LOGICAL_AND", "T_PRINT", "T_YIELD", "T_DOUBLE_ARROW", "T_YIELD_FROM", "'='", "T_PLUS_EQUAL", "T_MINUS_EQUAL", "T_MUL_EQUAL", "T_DIV_EQUAL", "T_CONCAT_EQUAL", "T_MOD_EQUAL", "T_AND_EQUAL", "T_OR_EQUAL", "T_XOR_EQUAL", "T_SL_EQUAL", "T_SR_EQUAL", "T_POW_EQUAL", "T_COALESCE_EQUAL", "'?'", "':'", "T_COALESCE", "T_BOOLEAN_OR", "T_BOOLEAN_AND", "'|'", "'^'", "T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG", "T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG", "T_IS_EQUAL", "T_IS_NOT_EQUAL", "T_IS_IDENTICAL", "T_IS_NOT_IDENTICAL", "T_SPACESHIP", "'<'", "T_IS_SMALLER_OR_EQUAL", "'>'", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_ENUM", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_NULLSAFE_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "T_ATTRIBUTE", "';'", "']'", "'{'", "'}'", "'('", "')'", "'`'", "'\"'", "'\$'");
    protected $tokenToSymbol = array(0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 56, 166, 168, 167, 55, 168, 168, 163, 164, 53, 50, 8, 51, 52, 54, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 31, 159, 44, 16, 46, 30, 68, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 70, 168, 160, 36, 168, 165, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 161, 35, 162, 58, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 48, 49, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158);
    protected $action = array(132, 133, 134, 575, 135, 136, 0, 738, 739, 740, 137, 37, 850, 825, 851, 476, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 101, 102, 103, 104, 105, 1097, 1098, 1099, 1096, 1095, 1094, 1100, 732, 731, -32766, 1289, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 1022, 377, 376, 2, 741, -32766, -32766, -32766, -32766, -32766, 822, 417, -32766, -32766, -32766, -32766, -32766, -32766, 267, 138, 399, 745, 746, 747, 748, 287, -32766, 423, -32766, -32766, -32766, -32766, -32766, -32766, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 779, 576, 780, 781, 782, 783, 771, 772, 340, 341, 774, 775, 760, 761, 762, 764, 765, 766, 351, 806, 807, 808, 809, 810, 577, 767, 768, 578, 579, 800, 791, 789, 790, 803, 786, 787, -327, 423, 580, 581, 785, 582, 583, 584, 585, 586, 587, 605, -590, 477, -86, 814, 788, 588, 589, -590, 139, -32766, -32766, -32766, 132, 133, 134, 575, 135, 136, 1046, 738, 739, 740, 137, 37, 323, 1013, 823, 824, 1334, 1324, -32766, 1335, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 1097, 1098, 1099, 1096, 1095, 1094, 1100, -587, 732, 731, -32766, -32766, -32766, 12, -587, 81, -32766, -32766, -32766, 945, 946, 322, 927, 34, 947, 1224, 1223, 1225, 741, -86, 942, -32766, 1075, -32766, -32766, -32766, -32766, -32766, 239, -32766, -32766, -32766, 267, 138, 399, 745, 746, 747, 748, 461, 462, 423, 35, 247, 103, 104, 105, 128, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 779, 576, 780, 781, 782, 783, 771, 772, 340, 341, 774, 775, 760, 761, 762, 764, 765, 766, 351, 806, 807, 808, 809, 810, 577, 767, 768, 578, 579, 800, 791, 789, 790, 803, 786, 787, -327, 144, 580, 581, 785, 582, 583, 584, 585, 586, 587, 1222, 82, 83, 84, -590, 788, 588, 589, -590, 148, 763, 733, 734, 735, 736, 737, 1309, 738, 739, 740, 776, 777, 36, 1308, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 288, 271, -587, -193, 375, 376, -587, 976, -32766, 1021, 453, 454, 455, 109, 417, 945, 946, 741, 712, 819, 947, -32766, -32766, -32766, -271, 1073, 941, 1224, 1223, 1225, 288, 742, 743, 744, 745, 746, 747, 748, -192, -365, 812, -365, -32766, 599, -32766, -32766, 549, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 779, 802, 780, 781, 782, 783, 771, 772, 773, 801, 774, 775, 760, 761, 762, 764, 765, 766, 805, 806, 807, 808, 809, 810, 811, 767, 768, 769, 770, 800, 791, 789, 790, 803, 786, 787, 251, 820, 778, 784, 785, 792, 793, 795, 794, 796, 797, 732, 731, 1261, 1022, 1019, 788, 799, 798, 49, 50, 51, 507, 52, 53, 1009, 1008, 1007, 1010, 54, 55, -111, 56, 816, 1045, 14, -111, 1022, -111, 287, 1305, 977, 306, 302, 1022, 238, -111, -111, -111, -111, -111, -111, -111, -111, 106, 107, 108, 1089, 271, -32766, -32766, -32766, 280, 284, 126, -193, 929, 57, 58, 287, 109, 1019, -541, 59, 308, 60, 244, 245, 61, 62, 63, 64, 65, 66, 67, 68, 1229, 27, 269, 69, 439, 508, -341, 1022, 929, 1255, 1256, 509, 907, 823, -192, 150, 907, 1253, 41, 24, 510, 352, 511, 818, 512, 386, 513, 11, 699, 514, 515, 648, 25, 814, 43, 44, 440, 372, 371, 907, 45, 516, 702, 1220, 667, 668, 363, 334, -540, 357, -541, -541, 320, 1215, 1249, 518, 519, 520, -581, 1074, 335, 724, -581, 1019, -32766, -541, 336, 521, 522, 703, 1243, 1244, 1245, 1246, 1240, 1241, 294, -541, 850, -547, 851, 823, 1247, 1242, 365, 1022, 1224, 1223, 1225, 295, -153, -153, -153, 369, 70, 897, 318, 319, 322, 897, 384, 149, 402, 373, 374, -153, 435, -153, 436, -153, 280, -153, -540, -540, 141, 1220, 378, 379, 639, 640, 322, 370, 897, 907, 437, 438, 829, -540, -88, 151, 732, 731, 945, 946, 153, 823, -32766, 517, -51, -540, 154, -546, 883, 941, -111, -111, -111, 31, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 155, 74, 27, 157, 32, 322, -85, 123, 124, 909, 129, 697, 130, 909, 823, 697, -153, 143, 1253, 158, -32766, -544, 1229, -542, 159, 160, 1222, 161, -79, 1134, 1136, -75, 285, -32766, -32766, -32766, 909, -32766, 697, -32766, -539, -32766, -301, -73, -32766, 897, -72, -71, 1220, -32766, -32766, -32766, -16, 140, 1215, -32766, -32766, 732, 731, 322, -70, -32766, 414, -69, -4, 907, -68, -67, 521, 522, -32766, 1243, 1244, 1245, 1246, 1240, 1241, -66, -47, -18, 147, 270, 281, 1247, 1242, -544, -544, -542, -542, 732, 731, 713, 716, 906, -32766, 72, 146, 907, 319, 322, 1222, -297, -542, 823, -539, -539, 276, -32766, -32766, -32766, 277, -32766, -544, -32766, -542, -32766, 282, 283, -32766, -539, 909, 328, 697, -32766, -32766, -32766, -32766, 704, 286, -32766, -32766, -539, 1222, 923, 289, -32766, 414, 1220, 290, -32766, -32766, -32766, 271, -32766, -32766, -32766, 47, -32766, 897, -111, -32766, 677, 109, 814, 145, -32766, -32766, -32766, -32766, 823, 131, -32766, -32766, 1336, -32766, 654, 670, -32766, 414, 1104, 370, 637, 430, 551, 73, 13, -32766, 293, 555, 295, 897, 945, 946, 649, 74, 434, 517, 458, 322, 487, 690, 842, 941, -111, -111, -111, 301, 1022, 561, 655, 671, 1260, 300, -32766, -539, -32766, 907, 603, 303, 1222, 296, 297, 39, 1262, 9, 40, -32766, -32766, -32766, 0, -32766, 907, -32766, 909, -32766, 697, -4, -32766, 0, 1229, 907, 0, -32766, -32766, -32766, -32766, 307, 125, -32766, -32766, 0, 1222, 907, 0, -32766, 414, 0, 0, -32766, -32766, -32766, 707, -32766, -32766, -32766, 962, -32766, 697, -505, -32766, 714, -495, 7, 482, -32766, -32766, -32766, -32766, -539, -539, -32766, -32766, 16, 1222, 567, 367, -32766, 414, 925, 295, -32766, -32766, -32766, -539, -32766, -32766, -32766, 822, -32766, 897, 721, -32766, 722, -575, 888, -539, -32766, -32766, -32766, 986, 963, 970, -32766, -32766, 897, -249, -249, -249, -32766, 414, 823, 370, 960, 897, 971, 886, 958, -32766, 1078, 1081, 718, 1082, 945, 946, 1079, 897, 1080, 517, 1086, 33, 1250, 834, 883, 941, -111, -111, -111, 27, 1275, 1293, 1327, -248, -248, -248, 1220, 642, 884, 370, 317, 823, 366, 698, 701, 1253, 1331, 705, -111, 706, 945, 946, 708, 709, 710, 517, 909, -32766, 697, -249, 883, 941, -111, -111, -111, 711, 715, 700, -509, 1333, 845, 909, 48, 697, -573, 1220, 844, 853, 295, 935, 909, 1215, 697, 74, 978, 852, 1332, 322, 934, 932, 933, 936, 909, 1206, 697, -248, 522, 916, 1243, 1244, 1245, 1246, 1240, 1241, 926, 914, 968, 969, 1330, 1287, 1247, 1242, 1276, 1294, -32766, 1300, 1303, 1191, -547, -546, 1222, -545, 72, -489, 1, 319, 322, -32766, -32766, -32766, 28, -32766, 29, -32766, 38, -32766, 298, 299, -32766, 42, 46, 71, 75, -32766, -32766, -32766, 76, 77, 78, -32766, -32766, 368, 79, 80, 142, -32766, 414, 152, 156, 243, 324, 352, 353, 127, -32766, -274, 354, 355, 356, 357, 358, 359, 360, 361, 362, 364, 431, 0, -272, -271, 18, 19, 20, 21, 23, 401, 478, 479, 486, 489, 490, 491, 492, 496, 497, 498, 505, 684, 1233, 1174, 1251, 1048, 1047, 1028, 0, 1210, 1024, -276, -103, 17, 22, 26, 292, 400, 596, 600, 628, 689, 1178, 1228, 1175, 1306, 0, 0, 1254, 0, 322);
    protected $actionCheck = array(2, 3, 4, 5, 6, 7, 0, 9, 10, 11, 12, 13, 106, 1, 108, 31, 9, 10, 11, 44, 45, 46, 47, 48, 49, 50, 51, 52, 116, 117, 118, 119, 120, 121, 122, 37, 38, 30, 1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 138, 106, 107, 8, 57, 9, 10, 11, 9, 10, 155, 116, 9, 10, 11, 9, 10, 11, 71, 72, 73, 74, 75, 76, 77, 163, 30, 80, 32, 33, 34, 35, 36, 30, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 8, 80, 136, 137, 138, 139, 140, 141, 142, 143, 144, 51, 1, 161, 31, 80, 150, 151, 152, 8, 154, 9, 10, 11, 2, 3, 4, 5, 6, 7, 164, 9, 10, 11, 12, 13, 70, 1, 82, 159, 80, 85, 30, 83, 32, 33, 34, 35, 36, 37, 38, 116, 117, 118, 119, 120, 121, 122, 1, 37, 38, 9, 10, 11, 8, 8, 161, 9, 10, 11, 117, 118, 167, 1, 8, 122, 155, 156, 157, 57, 97, 128, 30, 162, 32, 33, 34, 35, 30, 14, 32, 33, 34, 71, 72, 73, 74, 75, 76, 77, 134, 135, 80, 147, 148, 50, 51, 52, 8, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 164, 8, 136, 137, 138, 139, 140, 141, 142, 143, 144, 80, 9, 10, 11, 160, 150, 151, 152, 164, 154, 2, 3, 4, 5, 6, 7, 1, 9, 10, 11, 12, 13, 30, 8, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 30, 57, 160, 8, 106, 107, 164, 31, 9, 137, 129, 130, 131, 69, 116, 117, 118, 57, 161, 80, 122, 9, 10, 11, 164, 1, 128, 155, 156, 157, 30, 71, 72, 73, 74, 75, 76, 77, 8, 106, 80, 108, 30, 1, 32, 33, 85, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 8, 156, 136, 137, 138, 139, 140, 141, 142, 143, 144, 37, 38, 146, 138, 116, 150, 151, 152, 2, 3, 4, 5, 6, 7, 119, 120, 121, 122, 12, 13, 101, 15, 80, 1, 101, 106, 138, 108, 163, 1, 159, 8, 113, 138, 97, 116, 117, 118, 119, 120, 121, 122, 123, 53, 54, 55, 123, 57, 9, 10, 11, 163, 30, 14, 164, 122, 50, 51, 163, 69, 116, 70, 56, 8, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 1, 70, 71, 72, 73, 74, 162, 138, 122, 78, 79, 80, 1, 82, 164, 14, 1, 86, 87, 88, 89, 163, 91, 156, 93, 106, 95, 108, 161, 98, 99, 75, 76, 80, 103, 104, 105, 106, 107, 1, 109, 110, 31, 116, 75, 76, 115, 116, 70, 163, 134, 135, 8, 122, 1, 124, 125, 126, 160, 159, 8, 161, 164, 116, 137, 149, 8, 136, 137, 31, 139, 140, 141, 142, 143, 144, 145, 161, 106, 163, 108, 82, 151, 152, 8, 138, 155, 156, 157, 158, 75, 76, 77, 8, 163, 84, 165, 166, 167, 84, 8, 101, 102, 106, 107, 90, 8, 92, 8, 94, 163, 96, 134, 135, 161, 116, 106, 107, 111, 112, 167, 106, 84, 1, 8, 8, 8, 149, 31, 14, 37, 38, 117, 118, 14, 82, 137, 122, 31, 161, 14, 163, 127, 128, 129, 130, 131, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 14, 163, 70, 14, 14, 167, 31, 16, 16, 159, 16, 161, 16, 159, 82, 161, 162, 16, 86, 16, 74, 70, 1, 70, 16, 16, 80, 16, 31, 59, 60, 31, 37, 87, 88, 89, 159, 91, 161, 93, 70, 95, 35, 31, 98, 84, 31, 31, 116, 103, 104, 105, 31, 161, 122, 109, 110, 37, 38, 167, 31, 115, 116, 31, 0, 1, 31, 31, 136, 137, 124, 139, 140, 141, 142, 143, 144, 31, 31, 31, 31, 31, 31, 151, 152, 134, 135, 134, 135, 37, 38, 31, 31, 31, 74, 163, 31, 1, 166, 167, 80, 35, 149, 82, 134, 135, 35, 87, 88, 89, 35, 91, 161, 93, 161, 95, 35, 35, 98, 149, 159, 35, 161, 103, 104, 105, 74, 31, 37, 109, 110, 161, 80, 38, 37, 115, 116, 116, 37, 87, 88, 89, 57, 91, 124, 93, 70, 95, 84, 128, 98, 77, 69, 80, 70, 103, 104, 105, 137, 82, 31, 109, 110, 83, 85, 96, 94, 115, 116, 82, 106, 113, 108, 85, 154, 97, 124, 113, 89, 158, 84, 117, 118, 90, 163, 128, 122, 97, 167, 97, 92, 127, 128, 129, 130, 131, 133, 138, 153, 100, 100, 146, 132, 74, 70, 137, 1, 153, 114, 80, 134, 135, 159, 146, 150, 159, 87, 88, 89, -1, 91, 1, 93, 159, 95, 161, 162, 98, -1, 1, 1, -1, 103, 104, 105, 74, 132, 161, 109, 110, -1, 80, 1, -1, 115, 116, -1, -1, 87, 88, 89, 31, 91, 124, 93, 159, 95, 161, 149, 98, 31, 149, 149, 102, 103, 104, 105, 74, 134, 135, 109, 110, 149, 80, 81, 149, 115, 116, 154, 158, 87, 88, 89, 149, 91, 124, 93, 155, 95, 84, 159, 98, 159, 163, 159, 161, 103, 104, 105, 159, 159, 159, 109, 110, 84, 100, 101, 102, 115, 116, 82, 106, 159, 84, 159, 159, 159, 124, 159, 159, 162, 159, 117, 118, 159, 84, 159, 122, 159, 161, 160, 160, 127, 128, 129, 130, 131, 70, 160, 160, 160, 100, 101, 102, 116, 160, 162, 106, 161, 82, 161, 161, 161, 86, 162, 161, 128, 161, 117, 118, 161, 161, 161, 122, 159, 137, 161, 162, 127, 128, 129, 130, 131, 161, 161, 161, 165, 162, 162, 159, 70, 161, 163, 116, 162, 162, 158, 162, 159, 122, 161, 163, 162, 162, 162, 167, 162, 162, 162, 162, 159, 162, 161, 162, 137, 162, 139, 140, 141, 142, 143, 144, 162, 162, 162, 162, 162, 162, 151, 152, 162, 162, 74, 162, 162, 165, 163, 163, 80, 163, 163, 163, 163, 166, 167, 87, 88, 89, 163, 91, 163, 93, 163, 95, 134, 135, 98, 163, 163, 163, 163, 103, 104, 105, 163, 163, 163, 109, 110, 149, 163, 163, 163, 115, 116, 163, 163, 163, 163, 163, 163, 161, 124, 164, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, 163, -1, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -1, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, -1, -1, 166, -1, 167);
    protected $actionBase = array(0, -2, 154, 542, 752, 893, 929, 580, 53, 394, 855, 307, 307, 67, 307, 307, 307, 565, 908, 908, 917, 908, 538, 784, 649, 649, 649, 708, 708, 708, 708, 740, 740, 849, 849, 881, 817, 634, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 1036, 12, 323, 389, 678, 1044, 1050, 1046, 1051, 1042, 1041, 1045, 1047, 1052, 942, 943, 753, 946, 947, 949, 950, 1048, 873, 1043, 1049, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 346, 491, 50, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 54, 54, 54, 620, 620, 359, 190, 184, 955, 955, 955, 955, 955, 955, 955, 955, 955, 955, 658, 47, 144, 144, 7, 7, 7, 7, 7, 371, -25, -25, -25, -25, 709, 347, 916, 474, 526, 375, 280, 317, 245, 340, 340, 187, 187, 396, 396, -87, -87, 396, 396, 396, 747, 747, 747, 747, 443, 505, -94, 308, 454, 480, 480, 480, 480, 454, 454, 454, 454, 755, 1054, 454, 454, 454, 641, 822, 822, 998, 442, 442, 442, 822, 499, 776, 88, 499, 88, 37, 92, 756, 85, -54, 425, 756, 639, 764, 189, 143, 820, 524, 820, 1040, 385, 767, 413, 735, 688, 857, 902, 1053, 787, 940, 788, 941, 228, 98, 685, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1055, 415, 1040, 286, 1055, 1055, 1055, 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, 534, 286, 483, 496, 286, 774, 415, 12, 800, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 736, -16, 12, 323, 204, 204, 427, 168, 204, 204, 204, 204, 12, 12, 12, 524, 773, 733, 537, 742, 377, 773, 773, 773, 115, 124, 207, 342, 695, 754, 446, 761, 761, 775, 957, 957, 761, 765, 761, 775, 973, 761, 761, 957, 957, 809, 232, 625, 579, 612, 627, 957, 475, 761, 761, 761, 761, 792, 643, 761, 433, 281, 761, 761, 792, 758, 739, 46, 751, 957, 957, 957, 792, 603, 751, 751, 751, 819, 821, 746, 738, 571, 507, 645, 198, 783, 738, 738, 761, 619, 746, 738, 746, 738, 812, 738, 738, 738, 746, 738, 765, 585, 738, 691, 644, 188, 738, 6, 974, 975, 624, 979, 967, 980, 1009, 981, 985, 878, 956, 992, 972, 986, 965, 963, 750, 679, 680, 801, 797, 954, 771, 771, 771, 951, 771, 771, 771, 771, 771, 771, 771, 771, 679, 858, 814, 745, 777, 995, 682, 684, 743, 872, 899, 948, 994, 1030, 987, 741, 689, 1016, 999, 846, 875, 1000, 1001, 1017, 1031, 1032, 880, 772, 903, 904, 859, 1003, 879, 771, 974, 985, 663, 972, 986, 965, 963, 734, 724, 720, 723, 717, 704, 700, 703, 737, 1033, 907, 818, 866, 1002, 952, 679, 867, 1012, 856, 1018, 1019, 877, 778, 768, 868, 910, 1004, 1005, 1006, 882, 1034, 884, 744, 1013, 997, 1020, 780, 911, 1021, 1022, 1023, 1024, 887, 913, 888, 889, 823, 781, 1010, 757, 918, 528, 769, 770, 789, 1008, 642, 993, 900, 919, 920, 1025, 1026, 1027, 922, 923, 990, 828, 1014, 760, 1015, 1011, 829, 830, 647, 785, 1035, 759, 763, 779, 653, 674, 924, 925, 927, 991, 748, 762, 841, 843, 1037, 683, 1038, 931, 677, 844, 696, 938, 1029, 697, 699, 786, 901, 811, 782, 766, 1007, 749, 845, 939, 847, 848, 850, 1028, 853, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 458, 458, 458, 458, 458, 458, 307, 307, 307, 307, 0, 0, 307, 0, 0, 0, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 219, 219, 291, 291, 291, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 291, 291, 291, 291, 291, 291, 291, 291, 809, 442, 442, 442, 442, 219, 219, 219, 219, 219, -88, -88, 219, 809, 219, 219, 442, 442, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 0, 0, 286, 88, 219, 765, 765, 765, 765, 219, 219, 219, 219, 88, 88, 219, 219, 219, 0, 0, 0, 0, 0, 0, 0, 0, 286, 88, 0, 286, 0, 765, 765, 219, 0, 809, 314, 219, 0, 0, 0, 0, 286, 765, 286, 415, 761, 88, 761, 415, 415, 204, 12, 314, 527, 527, 527, 527, 0, 0, 524, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 809, 765, 0, 809, 0, 765, 765, 765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 765, 0, 0, 957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 973, 0, 0, 0, 0, 0, 0, 765, 0, 0, 0, 0, 0, 0, 0, 0, 771, 778, 0, 778, 0, 771, 771, 771, 0, 0, 0, 0, 785, 683);
    protected $actionDefault = array(3, 32767, 103, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 101, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 593, 593, 593, 593, 32767, 32767, 253, 103, 32767, 32767, 467, 385, 385, 385, 32767, 32767, 537, 537, 537, 537, 537, 537, 32767, 32767, 32767, 32767, 32767, 32767, 467, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 101, 32767, 32767, 32767, 37, 7, 8, 10, 11, 50, 17, 323, 32767, 32767, 32767, 32767, 103, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 586, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 471, 450, 451, 453, 454, 384, 538, 592, 326, 589, 383, 146, 338, 328, 241, 329, 257, 472, 258, 473, 476, 477, 214, 286, 380, 150, 414, 468, 416, 466, 470, 415, 390, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 388, 389, 469, 447, 446, 445, 32767, 32767, 412, 413, 417, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 103, 32767, 387, 420, 418, 419, 436, 437, 434, 435, 438, 32767, 439, 440, 441, 442, 32767, 315, 32767, 32767, 32767, 364, 362, 315, 112, 32767, 32767, 427, 428, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 531, 444, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 103, 32767, 101, 533, 409, 411, 501, 422, 423, 421, 391, 32767, 508, 32767, 103, 510, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 532, 32767, 539, 539, 32767, 494, 101, 194, 32767, 32767, 32767, 194, 194, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 600, 494, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 32767, 194, 111, 32767, 32767, 32767, 101, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 189, 32767, 267, 269, 103, 554, 194, 32767, 513, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 506, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 494, 432, 139, 32767, 139, 539, 424, 425, 426, 496, 539, 539, 539, 311, 288, 32767, 32767, 32767, 32767, 511, 511, 101, 101, 101, 101, 506, 32767, 32767, 32767, 32767, 112, 100, 100, 100, 100, 100, 104, 102, 32767, 32767, 32767, 32767, 222, 100, 32767, 102, 102, 32767, 32767, 222, 224, 211, 102, 226, 32767, 558, 559, 222, 102, 226, 226, 226, 246, 246, 483, 317, 102, 100, 102, 102, 196, 317, 317, 32767, 102, 483, 317, 483, 317, 198, 317, 317, 317, 483, 317, 32767, 102, 317, 213, 100, 100, 317, 32767, 32767, 32767, 496, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 221, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 526, 32767, 543, 556, 430, 431, 433, 541, 455, 456, 457, 458, 459, 460, 461, 463, 588, 32767, 500, 32767, 32767, 32767, 32767, 337, 598, 32767, 598, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 599, 32767, 539, 32767, 32767, 32767, 32767, 429, 9, 76, 489, 43, 44, 52, 58, 517, 518, 519, 520, 514, 515, 521, 516, 32767, 32767, 522, 564, 32767, 32767, 540, 591, 32767, 32767, 32767, 32767, 32767, 32767, 139, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 526, 32767, 137, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 539, 32767, 32767, 32767, 32767, 313, 310, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 539, 32767, 32767, 32767, 32767, 32767, 290, 32767, 307, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 285, 32767, 32767, 379, 32767, 32767, 32767, 32767, 358, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 152, 152, 3, 3, 340, 152, 152, 152, 340, 340, 152, 340, 340, 340, 152, 152, 152, 152, 152, 152, 279, 184, 261, 264, 246, 246, 152, 350, 152);
    protected $goto = array(194, 194, 685, 425, 653, 346, 614, 650, 419, 310, 311, 331, 569, 316, 424, 332, 426, 630, 1200, 930, 693, 1051, 1201, 1204, 931, 1205, 165, 165, 165, 165, 218, 195, 191, 191, 175, 177, 213, 191, 191, 191, 191, 191, 192, 192, 192, 192, 192, 192, 186, 187, 188, 189, 190, 215, 213, 216, 529, 530, 415, 531, 533, 534, 535, 536, 537, 538, 539, 540, 1120, 166, 167, 168, 193, 169, 170, 171, 164, 172, 173, 174, 176, 212, 214, 217, 235, 240, 241, 242, 254, 255, 256, 257, 258, 259, 260, 261, 263, 264, 265, 266, 278, 279, 313, 314, 315, 420, 421, 422, 574, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 178, 234, 179, 196, 197, 198, 236, 186, 187, 188, 189, 190, 215, 1120, 199, 180, 181, 182, 200, 196, 183, 237, 201, 199, 163, 202, 203, 184, 204, 205, 206, 185, 207, 208, 209, 210, 211, 275, 275, 275, 275, 843, 593, 646, 647, 560, 664, 665, 666, 720, 629, 631, 840, 418, 651, 604, 841, 350, 675, 679, 996, 683, 691, 992, 616, 616, 817, 350, 350, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1252, 1092, 1093, 350, 350, 874, 350, 848, 1337, 896, 891, 892, 905, 849, 893, 846, 894, 895, 847, 548, 900, 899, 901, 350, 391, 394, 554, 594, 598, 1270, 1270, 1072, 1068, 1069, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1270, 1268, 1268, 815, 347, 348, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1268, 1221, 1020, 1221, 1020, 1221, 836, 5, 1020, 6, 1020, 1020, 1281, 961, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 349, 349, 349, 349, 1221, 460, 460, 566, 678, 1221, 1221, 1221, 1221, 344, 460, 1221, 1221, 1221, 1302, 1302, 1302, 1302, 602, 617, 620, 621, 622, 623, 643, 644, 645, 695, 836, 912, 553, 546, 1310, 913, 548, 532, 532, 821, 856, 982, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 543, 473, 543, 868, 543, 928, 855, 928, 389, 475, 337, 546, 553, 562, 563, 339, 572, 595, 609, 610, 1320, 1320, 249, 249, 1026, 1025, 15, 821, 450, 821, 494, 565, 495, 955, 955, 955, 955, 1320, 501, 450, 949, 956, 839, 652, 1321, 1321, 1169, 1214, 246, 246, 246, 246, 248, 250, 1323, 985, 959, 959, 957, 959, 719, 1321, 545, 994, 989, 470, 1295, 1296, 953, 405, 692, 917, 1108, 432, 541, 541, 541, 541, 612, 597, 452, 444, 1029, 1030, 1001, 658, 444, 1292, 444, 1292, 674, 1292, 860, 833, 656, 980, 836, 861, 547, 557, 854, 321, 305, 547, 333, 557, 1297, 1298, 392, 456, 570, 607, 1211, 944, 398, 858, 1304, 1304, 1304, 1304, 463, 573, 464, 465, 608, 1004, 866, 403, 404, 1328, 1329, 1057, 662, 1212, 663, 471, 407, 408, 409, 723, 676, 870, 1288, 410, 624, 626, 627, 342, 427, 1216, 869, 857, 1056, 1060, 427, 864, 1061, 1103, 966, 0, 0, 964, 1027, 1027, 0, 0, 0, 657, 1038, 1034, 1035, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 444, 0, 1059, 444, 954, 0, 1290, 1290, 1059, 592, 1085, 0, 696, 682, 682, 0, 502, 688, 1083, 0, 0, 0, 1217, 1218, 272, 428, 1101, 873, 0, 544, 831, 544, 0, 0, 0, 673, 938, 0, 0, 1015, 1031, 1032, 0, 0, 0, 0, 0, 0, 1219, 1278, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 252, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 999, 999);
    protected $gotoCheck = array(42, 42, 72, 65, 65, 96, 55, 55, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 78, 78, 9, 126, 78, 78, 78, 78, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 23, 23, 23, 23, 15, 129, 85, 85, 48, 85, 85, 85, 48, 48, 48, 26, 13, 48, 13, 27, 14, 48, 48, 48, 48, 48, 48, 107, 107, 7, 14, 14, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 143, 143, 14, 14, 45, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 64, 15, 64, 14, 58, 58, 58, 58, 58, 168, 168, 15, 15, 15, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 169, 169, 6, 96, 96, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 72, 72, 72, 72, 72, 22, 46, 72, 46, 72, 72, 14, 49, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 24, 24, 24, 24, 72, 148, 148, 170, 14, 72, 72, 72, 72, 177, 148, 72, 72, 72, 9, 9, 9, 9, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 22, 72, 75, 75, 179, 72, 14, 171, 171, 12, 35, 102, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 19, 83, 19, 35, 19, 9, 35, 9, 61, 83, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 180, 180, 5, 5, 117, 117, 75, 12, 19, 12, 154, 103, 154, 19, 19, 19, 19, 180, 154, 19, 19, 19, 25, 63, 181, 181, 150, 14, 5, 5, 5, 5, 5, 5, 180, 25, 25, 25, 25, 25, 25, 181, 25, 25, 25, 174, 174, 174, 92, 92, 92, 17, 17, 112, 106, 106, 106, 106, 17, 106, 82, 23, 118, 118, 17, 119, 23, 129, 23, 129, 115, 129, 17, 18, 17, 17, 22, 39, 9, 9, 17, 167, 167, 9, 29, 9, 176, 176, 9, 9, 2, 2, 17, 91, 28, 37, 129, 129, 129, 129, 9, 9, 9, 9, 79, 109, 9, 81, 81, 9, 9, 128, 81, 159, 81, 156, 81, 81, 81, 98, 81, 41, 129, 81, 84, 84, 84, 81, 116, 20, 16, 16, 16, 16, 116, 9, 131, 146, 95, -1, -1, 16, 116, 116, -1, -1, -1, 116, 116, 116, 116, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, -1, 129, 23, 16, -1, 129, 129, 129, 8, 8, -1, 8, 8, 8, -1, 8, 8, 8, -1, -1, -1, 20, 20, 24, 88, 16, 16, -1, 24, 20, 24, -1, -1, -1, 88, 88, -1, -1, 88, 88, 88, -1, -1, -1, -1, -1, -1, 20, 20, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 106, 106);
    protected $gotoBase = array(0, 0, -250, 0, 0, 360, 235, 181, 522, 7, 0, 0, 33, -156, -113, -178, 43, -49, 126, 72, 100, 0, -9, 158, 282, 377, 172, 176, 120, 150, 0, 0, 0, 0, 0, -39, 0, 119, 0, 116, 0, 45, -1, 0, 0, 195, -456, 0, -529, 250, 0, 0, 0, 0, 0, -33, 0, 0, 182, 0, 0, 306, 0, 143, 203, -235, 0, 0, 0, 0, 0, 0, -6, 0, 0, -21, 0, 0, -385, 124, -46, -19, 144, -123, 10, -538, 0, 0, 275, 0, 0, 127, 106, 0, 0, 60, -472, 0, 76, 0, 0, 0, 294, 328, 0, 0, 386, -50, 0, 99, 0, 0, 138, 0, 0, 149, 219, 87, 139, 137, 0, 0, 0, 0, 0, 0, 19, 0, 101, 159, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -69, 0, 0, 58, 0, 257, 0, 114, 0, 0, 0, -120, 0, 40, 0, 0, 108, 0, 0, 0, 0, 0, 0, 0, 122, -7, 8, 264, 86, 0, 0, 107, 0, 78, 269, 0, 291, 55, 79, 0, 0);
    protected $gotoDefault = array(-32768, 506, 727, 4, 728, 921, 804, 813, 590, 523, 694, 343, 618, 416, 1286, 898, 1107, 571, 832, 1230, 1238, 451, 835, 326, 717, 880, 881, 882, 395, 381, 387, 393, 641, 619, 488, 867, 447, 859, 480, 862, 446, 871, 162, 413, 504, 875, 3, 877, 550, 908, 382, 885, 383, 669, 887, 556, 889, 890, 390, 396, 397, 1112, 564, 615, 902, 253, 558, 903, 380, 904, 911, 385, 388, 680, 459, 499, 493, 406, 1087, 559, 601, 638, 441, 467, 613, 625, 611, 474, 1023, 411, 325, 943, 951, 481, 457, 965, 345, 973, 725, 1119, 632, 483, 981, 633, 988, 991, 524, 525, 472, 1003, 268, 1006, 484, 1044, 659, 1017, 1018, 660, 634, 1040, 635, 661, 636, 1042, 466, 591, 1050, 448, 1058, 1274, 449, 1062, 262, 1065, 274, 412, 429, 1070, 1071, 8, 1077, 686, 687, 10, 273, 503, 1102, 681, 445, 1118, 433, 1188, 1190, 552, 485, 1208, 1207, 672, 500, 1213, 442, 1277, 443, 526, 468, 312, 527, 304, 329, 309, 542, 291, 330, 528, 469, 1283, 1291, 327, 30, 1311, 1322, 338, 568, 606);
    protected $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 21, 21, 22, 23, 23, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 29, 30, 30, 32, 34, 34, 28, 36, 36, 33, 38, 38, 35, 35, 37, 37, 39, 39, 31, 40, 40, 41, 43, 44, 44, 45, 46, 46, 48, 47, 47, 47, 47, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 25, 25, 68, 68, 71, 71, 70, 69, 69, 62, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 26, 26, 27, 27, 27, 27, 27, 87, 87, 89, 89, 82, 82, 90, 90, 91, 91, 91, 83, 83, 86, 86, 84, 84, 92, 93, 93, 56, 56, 64, 64, 67, 67, 67, 66, 94, 94, 95, 57, 57, 57, 57, 96, 96, 97, 97, 98, 98, 99, 100, 100, 101, 101, 102, 102, 54, 54, 50, 50, 104, 52, 52, 105, 51, 51, 53, 53, 63, 63, 63, 63, 80, 80, 108, 108, 110, 110, 111, 111, 111, 111, 109, 109, 109, 113, 113, 113, 113, 88, 88, 116, 116, 116, 117, 117, 114, 114, 118, 118, 120, 120, 121, 121, 115, 122, 122, 119, 123, 123, 123, 123, 112, 112, 81, 81, 81, 20, 20, 20, 125, 124, 124, 126, 126, 126, 126, 59, 127, 127, 128, 60, 130, 130, 131, 131, 132, 132, 85, 133, 133, 133, 133, 133, 133, 138, 138, 139, 139, 140, 140, 140, 140, 140, 141, 142, 142, 137, 137, 134, 134, 136, 136, 144, 144, 143, 143, 143, 143, 143, 143, 143, 135, 145, 145, 147, 146, 146, 61, 103, 148, 148, 55, 55, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 155, 149, 149, 154, 154, 157, 158, 158, 159, 160, 161, 161, 161, 161, 19, 19, 72, 72, 72, 72, 150, 150, 150, 150, 163, 163, 151, 151, 153, 153, 153, 156, 156, 168, 168, 168, 168, 168, 168, 168, 168, 168, 169, 169, 107, 171, 171, 171, 171, 152, 152, 152, 152, 152, 152, 152, 152, 58, 58, 166, 166, 166, 166, 172, 172, 162, 162, 162, 173, 173, 173, 173, 173, 173, 73, 73, 65, 65, 65, 65, 129, 129, 129, 129, 176, 175, 165, 165, 165, 165, 165, 165, 165, 164, 164, 164, 174, 174, 174, 174, 106, 170, 178, 178, 177, 177, 179, 179, 179, 179, 179, 179, 179, 179, 167, 167, 167, 167, 181, 182, 180, 180, 180, 180, 180, 180, 180, 180, 183, 183, 183, 183);
    protected $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, 0, 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 6, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, 5, 6, 3, 2, 1, 1, 1, 0, 2, 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, 0, 1, 0, 1, 3, 1, 1, 1, 8, 9, 7, 8, 7, 6, 8, 0, 2, 0, 2, 1, 2, 1, 2, 1, 1, 1, 0, 2, 0, 2, 0, 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 7, 0, 2, 1, 3, 3, 4, 1, 4, 0, 2, 5, 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, 3, 0, 2, 1, 1, 1, 1, 6, 8, 6, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 1, 1, 2, 1, 1, 0, 1, 0, 2, 2, 2, 4, 3, 1, 1, 3, 1, 2, 2, 3, 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, 0, 1, 5, 5, 10, 3, 5, 1, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 1, 3, 2, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 4, 2, 2, 8, 9, 8, 9, 9, 10, 9, 10, 8, 3, 2, 0, 4, 2, 1, 3, 2, 1, 2, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 0, 3, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 4, 4, 1, 4, 4, 0, 1, 1, 1, 3, 3, 1, 4, 2, 2, 1, 3, 1, 4, 4, 3, 3, 3, 3, 1, 3, 1, 1, 3, 1, 1, 4, 1, 1, 1, 3, 1, 1, 2, 1, 3, 4, 3, 2, 0, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 6, 3, 1, 1, 2, 1);
    protected function initReduceCallbacks()
    {
        $this->reduceCallbacks = [0 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 1 => function ($stackPos) {
            $this->semValue = $this->handleNamespaces($this->semStack[$stackPos - (1 - 1)]);
        }, 2 => function ($stackPos) {
            if (\is_array($this->semStack[$stackPos - (2 - 2)])) {
                $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]);
            } else {
                $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
                $this->semValue = $this->semStack[$stackPos - (2 - 1)];
            }
        }, 3 => function ($stackPos) {
            $this->semValue = array();
        }, 4 => function ($stackPos) {
            $startAttributes = $this->lookaheadStartAttributes;
            if (isset($startAttributes['comments'])) {
                $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments']));
            } else {
                $nop = null;
            }
            if ($nop !== null) {
                $this->semStack[$stackPos - (1 - 1)][] = $nop;
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 5 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 6 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 7 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 8 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 9 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 10 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 11 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 12 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 13 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 14 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 15 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 16 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 17 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 18 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 19 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 20 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 21 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 22 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 23 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 24 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 25 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 26 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 27 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 28 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 29 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 30 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 31 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 32 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 33 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 34 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 35 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 36 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 37 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 38 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 39 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 40 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 41 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 42 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 43 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 44 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 45 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 46 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 47 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 48 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 49 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 50 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 51 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 52 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 53 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 54 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 55 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 56 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 57 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 58 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 59 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 60 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 61 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 62 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 63 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 64 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 65 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 66 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 67 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 68 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 69 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 70 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 71 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 72 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 73 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 74 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 75 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 76 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 77 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 78 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 79 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 80 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 81 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 82 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 83 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 84 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 85 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 86 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 87 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 88 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 89 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 90 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 91 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 92 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 93 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 94 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 95 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 96 => function ($stackPos) {
            $this->semValue = new Name(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 97 => function ($stackPos) {
            $this->semValue = new Expr\Variable(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 98 => function ($stackPos) {
            /* nothing */
        }, 99 => function ($stackPos) {
            /* nothing */
        }, 100 => function ($stackPos) {
            /* nothing */
        }, 101 => function ($stackPos) {
            $this->emitError(new Error('A trailing comma is not allowed here', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes));
        }, 102 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 103 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 104 => function ($stackPos) {
            $this->semValue = new Node\Attribute($this->semStack[$stackPos - (1 - 1)], [], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 105 => function ($stackPos) {
            $this->semValue = new Node\Attribute($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 106 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 107 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 108 => function ($stackPos) {
            $this->semValue = new Node\AttributeGroup($this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 109 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 110 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 111 => function ($stackPos) {
            $this->semValue = [];
        }, 112 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 113 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 114 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 115 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 116 => function ($stackPos) {
            $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 117 => function ($stackPos) {
            $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (3 - 2)], null, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
            $this->checkNamespace($this->semValue);
        }, 118 => function ($stackPos) {
            $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
            $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($this->semValue);
        }, 119 => function ($stackPos) {
            $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
            $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($this->semValue);
        }, 120 => function ($stackPos) {
            $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 121 => function ($stackPos) {
            $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 122 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 123 => function ($stackPos) {
            $this->semValue = new Stmt\Const_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 124 => function ($stackPos) {
            $this->semValue = Stmt\Use_::TYPE_FUNCTION;
        }, 125 => function ($stackPos) {
            $this->semValue = Stmt\Use_::TYPE_CONSTANT;
        }, 126 => function ($stackPos) {
            $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->semStack[$stackPos - (7 - 2)], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
        }, 127 => function ($stackPos) {
            $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 128 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 129 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 130 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 131 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 132 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 133 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 134 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 135 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 136 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 137 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (1 - 1));
        }, 138 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (3 - 3));
        }, 139 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (1 - 1));
        }, 140 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (3 - 3));
        }, 141 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
            $this->semValue->type = Stmt\Use_::TYPE_NORMAL;
        }, 142 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue->type = $this->semStack[$stackPos - (2 - 1)];
        }, 143 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 144 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 145 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 146 => function ($stackPos) {
            $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 147 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 148 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 149 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 150 => function ($stackPos) {
            $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 151 => function ($stackPos) {
            if (\is_array($this->semStack[$stackPos - (2 - 2)])) {
                $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]);
            } else {
                $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
                $this->semValue = $this->semStack[$stackPos - (2 - 1)];
            }
        }, 152 => function ($stackPos) {
            $this->semValue = array();
        }, 153 => function ($stackPos) {
            $startAttributes = $this->lookaheadStartAttributes;
            if (isset($startAttributes['comments'])) {
                $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments']));
            } else {
                $nop = null;
            }
            if ($nop !== null) {
                $this->semStack[$stackPos - (1 - 1)][] = $nop;
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 154 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 155 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 156 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 157 => function ($stackPos) {
            throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 158 => function ($stackPos) {
            if ($this->semStack[$stackPos - (3 - 2)]) {
                $this->semValue = $this->semStack[$stackPos - (3 - 2)];
                $attrs = $this->startAttributeStack[$stackPos - (3 - 1)];
                $stmts = $this->semValue;
                if (!empty($attrs['comments'])) {
                    $stmts[0]->setAttribute('comments', \array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', [])));
                }
            } else {
                $startAttributes = $this->startAttributeStack[$stackPos - (3 - 1)];
                if (isset($startAttributes['comments'])) {
                    $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes);
                } else {
                    $this->semValue = null;
                }
                if (null === $this->semValue) {
                    $this->semValue = array();
                }
            }
        }, 159 => function ($stackPos) {
            $this->semValue = new Stmt\If_($this->semStack[$stackPos - (7 - 3)], ['stmts' => \is_array($this->semStack[$stackPos - (7 - 5)]) ? $this->semStack[$stackPos - (7 - 5)] : array($this->semStack[$stackPos - (7 - 5)]), 'elseifs' => $this->semStack[$stackPos - (7 - 6)], 'else' => $this->semStack[$stackPos - (7 - 7)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
        }, 160 => function ($stackPos) {
            $this->semValue = new Stmt\If_($this->semStack[$stackPos - (10 - 3)], ['stmts' => $this->semStack[$stackPos - (10 - 6)], 'elseifs' => $this->semStack[$stackPos - (10 - 7)], 'else' => $this->semStack[$stackPos - (10 - 8)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes);
        }, 161 => function ($stackPos) {
            $this->semValue = new Stmt\While_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 162 => function ($stackPos) {
            $this->semValue = new Stmt\Do_($this->semStack[$stackPos - (7 - 5)], \is_array($this->semStack[$stackPos - (7 - 2)]) ? $this->semStack[$stackPos - (7 - 2)] : array($this->semStack[$stackPos - (7 - 2)]), $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
        }, 163 => function ($stackPos) {
            $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos - (9 - 3)], 'cond' => $this->semStack[$stackPos - (9 - 5)], 'loop' => $this->semStack[$stackPos - (9 - 7)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 164 => function ($stackPos) {
            $this->semValue = new Stmt\Switch_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 165 => function ($stackPos) {
            $this->semValue = new Stmt\Break_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 166 => function ($stackPos) {
            $this->semValue = new Stmt\Continue_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 167 => function ($stackPos) {
            $this->semValue = new Stmt\Return_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 168 => function ($stackPos) {
            $this->semValue = new Stmt\Global_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 169 => function ($stackPos) {
            $this->semValue = new Stmt\Static_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 170 => function ($stackPos) {
            $this->semValue = new Stmt\Echo_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 171 => function ($stackPos) {
            $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 172 => function ($stackPos) {
            $e = $this->semStack[$stackPos - (2 - 1)];
            if ($e instanceof Expr\Throw_) {
                // For backwards-compatibility reasons, convert throw in statement position into
                // Stmt\Throw_ rather than Stmt\Expression(Expr\Throw_).
                $this->semValue = new Stmt\Throw_($e->expr, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
            } else {
                $this->semValue = new Stmt\Expression($e, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
            }
        }, 173 => function ($stackPos) {
            $this->semValue = new Stmt\Unset_($this->semStack[$stackPos - (5 - 3)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 174 => function ($stackPos) {
            $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos - (7 - 5)][1], 'stmts' => $this->semStack[$stackPos - (7 - 7)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
        }, 175 => function ($stackPos) {
            $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (9 - 3)], $this->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $this->semStack[$stackPos - (9 - 5)], 'byRef' => $this->semStack[$stackPos - (9 - 7)][1], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 176 => function ($stackPos) {
            $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (6 - 3)], new Expr\Error($this->startAttributeStack[$stackPos - (6 - 4)] + $this->endAttributeStack[$stackPos - (6 - 4)]), ['stmts' => $this->semStack[$stackPos - (6 - 6)]], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 177 => function ($stackPos) {
            $this->semValue = new Stmt\Declare_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 178 => function ($stackPos) {
            $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
            $this->checkTryCatch($this->semValue);
        }, 179 => function ($stackPos) {
            $this->semValue = new Stmt\Goto_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 180 => function ($stackPos) {
            $this->semValue = new Stmt\Label($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 181 => function ($stackPos) {
            $this->semValue = array();
            /* means: no statement */
        }, 182 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 183 => function ($stackPos) {
            $startAttributes = $this->startAttributeStack[$stackPos - (1 - 1)];
            if (isset($startAttributes['comments'])) {
                $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes);
            } else {
                $this->semValue = null;
            }
            if ($this->semValue === null) {
                $this->semValue = array();
            }
            /* means: no statement */
        }, 184 => function ($stackPos) {
            $this->semValue = array();
        }, 185 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 186 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 187 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 188 => function ($stackPos) {
            $this->semValue = new Stmt\Catch_($this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 7)], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
        }, 189 => function ($stackPos) {
            $this->semValue = null;
        }, 190 => function ($stackPos) {
            $this->semValue = new Stmt\Finally_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 191 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 192 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 193 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 194 => function ($stackPos) {
            $this->semValue = \false;
        }, 195 => function ($stackPos) {
            $this->semValue = \true;
        }, 196 => function ($stackPos) {
            $this->semValue = \false;
        }, 197 => function ($stackPos) {
            $this->semValue = \true;
        }, 198 => function ($stackPos) {
            $this->semValue = \false;
        }, 199 => function ($stackPos) {
            $this->semValue = \true;
        }, 200 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 201 => function ($stackPos) {
            $this->semValue = [];
        }, 202 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 203 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 204 => function ($stackPos) {
            $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (8 - 3)], ['byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 5)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
        }, 205 => function ($stackPos) {
            $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (9 - 4)], ['byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 6)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 206 => function ($stackPos) {
            $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (7 - 2)], ['type' => $this->semStack[$stackPos - (7 - 1)], 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
            $this->checkClass($this->semValue, $stackPos - (7 - 2));
        }, 207 => function ($stackPos) {
            $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (8 - 3)], ['type' => $this->semStack[$stackPos - (8 - 2)], 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
            $this->checkClass($this->semValue, $stackPos - (8 - 3));
        }, 208 => function ($stackPos) {
            $this->semValue = new Stmt\Interface_($this->semStack[$stackPos - (7 - 3)], ['extends' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)], 'attrGroups' => $this->semStack[$stackPos - (7 - 1)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
            $this->checkInterface($this->semValue, $stackPos - (7 - 3));
        }, 209 => function ($stackPos) {
            $this->semValue = new Stmt\Trait_($this->semStack[$stackPos - (6 - 3)], ['stmts' => $this->semStack[$stackPos - (6 - 5)], 'attrGroups' => $this->semStack[$stackPos - (6 - 1)]], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 210 => function ($stackPos) {
            $this->semValue = new Stmt\Enum_($this->semStack[$stackPos - (8 - 3)], ['scalarType' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
            $this->checkEnum($this->semValue, $stackPos - (8 - 3));
        }, 211 => function ($stackPos) {
            $this->semValue = null;
        }, 212 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 213 => function ($stackPos) {
            $this->semValue = null;
        }, 214 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 215 => function ($stackPos) {
            $this->semValue = 0;
        }, 216 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 217 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 218 => function ($stackPos) {
            $this->checkClassModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
            $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)];
        }, 219 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT;
        }, 220 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_FINAL;
        }, 221 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_READONLY;
        }, 222 => function ($stackPos) {
            $this->semValue = null;
        }, 223 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 224 => function ($stackPos) {
            $this->semValue = array();
        }, 225 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 226 => function ($stackPos) {
            $this->semValue = array();
        }, 227 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 228 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 229 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 230 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 231 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 232 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 233 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 234 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 235 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 236 => function ($stackPos) {
            $this->semValue = null;
        }, 237 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 238 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 239 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 240 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 241 => function ($stackPos) {
            $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 242 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 243 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 3)];
        }, 244 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 245 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (5 - 3)];
        }, 246 => function ($stackPos) {
            $this->semValue = array();
        }, 247 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 248 => function ($stackPos) {
            $this->semValue = new Stmt\Case_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 249 => function ($stackPos) {
            $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 250 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 251 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 252 => function ($stackPos) {
            $this->semValue = new Expr\Match_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
        }, 253 => function ($stackPos) {
            $this->semValue = [];
        }, 254 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 255 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 256 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 257 => function ($stackPos) {
            $this->semValue = new Node\MatchArm($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 258 => function ($stackPos) {
            $this->semValue = new Node\MatchArm(null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 259 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 260 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 261 => function ($stackPos) {
            $this->semValue = array();
        }, 262 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 263 => function ($stackPos) {
            $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (5 - 3)], \is_array($this->semStack[$stackPos - (5 - 5)]) ? $this->semStack[$stackPos - (5 - 5)] : array($this->semStack[$stackPos - (5 - 5)]), $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 264 => function ($stackPos) {
            $this->semValue = array();
        }, 265 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 266 => function ($stackPos) {
            $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 267 => function ($stackPos) {
            $this->semValue = null;
        }, 268 => function ($stackPos) {
            $this->semValue = new Stmt\Else_(\is_array($this->semStack[$stackPos - (2 - 2)]) ? $this->semStack[$stackPos - (2 - 2)] : array($this->semStack[$stackPos - (2 - 2)]), $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 269 => function ($stackPos) {
            $this->semValue = null;
        }, 270 => function ($stackPos) {
            $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 271 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false);
        }, 272 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (2 - 2)], \true);
        }, 273 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false);
        }, 274 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false);
        }, 275 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 276 => function ($stackPos) {
            $this->semValue = array();
        }, 277 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 278 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 279 => function ($stackPos) {
            $this->semValue = 0;
        }, 280 => function ($stackPos) {
            $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
            $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)];
        }, 281 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PUBLIC;
        }, 282 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PROTECTED;
        }, 283 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PRIVATE;
        }, 284 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_READONLY;
        }, 285 => function ($stackPos) {
            $this->semValue = new Node\Param($this->semStack[$stackPos - (6 - 6)], null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]);
            $this->checkParam($this->semValue);
        }, 286 => function ($stackPos) {
            $this->semValue = new Node\Param($this->semStack[$stackPos - (8 - 6)], $this->semStack[$stackPos - (8 - 8)], $this->semStack[$stackPos - (8 - 3)], $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 5)], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (8 - 2)], $this->semStack[$stackPos - (8 - 1)]);
            $this->checkParam($this->semValue);
        }, 287 => function ($stackPos) {
            $this->semValue = new Node\Param(new Expr\Error($this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes), null, $this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 1)]);
        }, 288 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 289 => function ($stackPos) {
            $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 290 => function ($stackPos) {
            $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 291 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 292 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 293 => function ($stackPos) {
            $this->semValue = new Node\Name('static', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 294 => function ($stackPos) {
            $this->semValue = $this->handleBuiltinTypes($this->semStack[$stackPos - (1 - 1)]);
        }, 295 => function ($stackPos) {
            $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 296 => function ($stackPos) {
            $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 297 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 298 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 299 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]);
        }, 300 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 301 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 302 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 303 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]);
        }, 304 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 305 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]);
        }, 306 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 307 => function ($stackPos) {
            $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 308 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]);
        }, 309 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 310 => function ($stackPos) {
            $this->semValue = new Node\IntersectionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 311 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 312 => function ($stackPos) {
            $this->semValue = new Node\NullableType($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 313 => function ($stackPos) {
            $this->semValue = new Node\UnionType($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 314 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 315 => function ($stackPos) {
            $this->semValue = null;
        }, 316 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 317 => function ($stackPos) {
            $this->semValue = null;
        }, 318 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 319 => function ($stackPos) {
            $this->semValue = null;
        }, 320 => function ($stackPos) {
            $this->semValue = array();
        }, 321 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 322 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (3 - 2)]);
        }, 323 => function ($stackPos) {
            $this->semValue = new Node\VariadicPlaceholder($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 324 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 325 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 326 => function ($stackPos) {
            $this->semValue = new Node\Arg($this->semStack[$stackPos - (1 - 1)], \false, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 327 => function ($stackPos) {
            $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \true, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 328 => function ($stackPos) {
            $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \false, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 329 => function ($stackPos) {
            $this->semValue = new Node\Arg($this->semStack[$stackPos - (3 - 3)], \false, \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (3 - 1)]);
        }, 330 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 331 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 332 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 333 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 334 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 335 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 336 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 337 => function ($stackPos) {
            $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 338 => function ($stackPos) {
            $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 339 => function ($stackPos) {
            if ($this->semStack[$stackPos - (2 - 2)] !== null) {
                $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
                $this->semValue = $this->semStack[$stackPos - (2 - 1)];
            }
        }, 340 => function ($stackPos) {
            $this->semValue = array();
        }, 341 => function ($stackPos) {
            $startAttributes = $this->lookaheadStartAttributes;
            if (isset($startAttributes['comments'])) {
                $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments']));
            } else {
                $nop = null;
            }
            if ($nop !== null) {
                $this->semStack[$stackPos - (1 - 1)][] = $nop;
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 342 => function ($stackPos) {
            $this->semValue = new Stmt\Property($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 1)]);
            $this->checkProperty($this->semValue, $stackPos - (5 - 2));
        }, 343 => function ($stackPos) {
            $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 2)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes, $this->semStack[$stackPos - (5 - 1)]);
            $this->checkClassConst($this->semValue, $stackPos - (5 - 2));
        }, 344 => function ($stackPos) {
            $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos - (10 - 5)], ['type' => $this->semStack[$stackPos - (10 - 2)], 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 7)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes);
            $this->checkClassMethod($this->semValue, $stackPos - (10 - 2));
        }, 345 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 346 => function ($stackPos) {
            $this->semValue = new Stmt\EnumCase($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->semStack[$stackPos - (5 - 1)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 347 => function ($stackPos) {
            $this->semValue = null;
            /* will be skipped */
        }, 348 => function ($stackPos) {
            $this->semValue = array();
        }, 349 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 350 => function ($stackPos) {
            $this->semValue = array();
        }, 351 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 352 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 353 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (5 - 1)][0], $this->semStack[$stackPos - (5 - 1)][1], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 354 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], null, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 355 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 356 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 357 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]);
        }, 358 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 359 => function ($stackPos) {
            $this->semValue = array(null, $this->semStack[$stackPos - (1 - 1)]);
        }, 360 => function ($stackPos) {
            $this->semValue = null;
        }, 361 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 362 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 363 => function ($stackPos) {
            $this->semValue = 0;
        }, 364 => function ($stackPos) {
            $this->semValue = 0;
        }, 365 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 366 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 367 => function ($stackPos) {
            $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
            $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)];
        }, 368 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PUBLIC;
        }, 369 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PROTECTED;
        }, 370 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PRIVATE;
        }, 371 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_STATIC;
        }, 372 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT;
        }, 373 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_FINAL;
        }, 374 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_READONLY;
        }, 375 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 376 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 377 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 378 => function ($stackPos) {
            $this->semValue = new Node\VarLikeIdentifier(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 379 => function ($stackPos) {
            $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 380 => function ($stackPos) {
            $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 381 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 382 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 383 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 384 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 385 => function ($stackPos) {
            $this->semValue = array();
        }, 386 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 387 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 388 => function ($stackPos) {
            $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 389 => function ($stackPos) {
            $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 390 => function ($stackPos) {
            $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 391 => function ($stackPos) {
            $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 392 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 393 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 394 => function ($stackPos) {
            $this->semValue = new Expr\Clone_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 395 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 396 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 397 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 398 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 399 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 400 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 401 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 402 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 403 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 404 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 405 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 406 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 407 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 408 => function ($stackPos) {
            $this->semValue = new Expr\PostInc($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 409 => function ($stackPos) {
            $this->semValue = new Expr\PreInc($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 410 => function ($stackPos) {
            $this->semValue = new Expr\PostDec($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 411 => function ($stackPos) {
            $this->semValue = new Expr\PreDec($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 412 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 413 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 414 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 415 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 416 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 417 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 418 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 419 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 420 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 421 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 422 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 423 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 424 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 425 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 426 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 427 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 428 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 429 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 430 => function ($stackPos) {
            $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 431 => function ($stackPos) {
            $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 432 => function ($stackPos) {
            $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 433 => function ($stackPos) {
            $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 434 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 435 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 436 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 437 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 438 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 439 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 440 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 441 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 442 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 443 => function ($stackPos) {
            $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 444 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 445 => function ($stackPos) {
            $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 446 => function ($stackPos) {
            $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 447 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 448 => function ($stackPos) {
            $this->semValue = new Expr\Isset_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 449 => function ($stackPos) {
            $this->semValue = new Expr\Empty_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 450 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 451 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 452 => function ($stackPos) {
            $this->semValue = new Expr\Eval_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 453 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 454 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 455 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 456 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes;
            $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos - (2 - 1)]);
            $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos - (2 - 2)], $attrs);
        }, 457 => function ($stackPos) {
            $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 458 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 459 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 460 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 461 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 462 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes;
            $attrs['kind'] = \strtolower($this->semStack[$stackPos - (2 - 1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
            $this->semValue = new Expr\Exit_($this->semStack[$stackPos - (2 - 2)], $attrs);
        }, 463 => function ($stackPos) {
            $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 464 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 465 => function ($stackPos) {
            $this->semValue = new Expr\ShellExec($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 466 => function ($stackPos) {
            $this->semValue = new Expr\Print_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 467 => function ($stackPos) {
            $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 468 => function ($stackPos) {
            $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (2 - 2)], null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 469 => function ($stackPos) {
            $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 470 => function ($stackPos) {
            $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 471 => function ($stackPos) {
            $this->semValue = new Expr\Throw_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 472 => function ($stackPos) {
            $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'returnType' => $this->semStack[$stackPos - (8 - 6)], 'expr' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
        }, 473 => function ($stackPos) {
            $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 474 => function ($stackPos) {
            $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (8 - 2)], 'params' => $this->semStack[$stackPos - (8 - 4)], 'uses' => $this->semStack[$stackPos - (8 - 6)], 'returnType' => $this->semStack[$stackPos - (8 - 7)], 'stmts' => $this->semStack[$stackPos - (8 - 8)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
        }, 475 => function ($stackPos) {
            $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => []], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 476 => function ($stackPos) {
            $this->semValue = new Expr\ArrowFunction(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'returnType' => $this->semStack[$stackPos - (9 - 7)], 'expr' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 477 => function ($stackPos) {
            $this->semValue = new Expr\ArrowFunction(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'returnType' => $this->semStack[$stackPos - (10 - 8)], 'expr' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes);
        }, 478 => function ($stackPos) {
            $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 5)], 'uses' => $this->semStack[$stackPos - (9 - 7)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)], 'attrGroups' => $this->semStack[$stackPos - (9 - 1)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 479 => function ($stackPos) {
            $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (10 - 4)], 'params' => $this->semStack[$stackPos - (10 - 6)], 'uses' => $this->semStack[$stackPos - (10 - 8)], 'returnType' => $this->semStack[$stackPos - (10 - 9)], 'stmts' => $this->semStack[$stackPos - (10 - 10)], 'attrGroups' => $this->semStack[$stackPos - (10 - 1)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes);
        }, 480 => function ($stackPos) {
            $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos - (8 - 4)], 'implements' => $this->semStack[$stackPos - (8 - 5)], 'stmts' => $this->semStack[$stackPos - (8 - 7)], 'attrGroups' => $this->semStack[$stackPos - (8 - 1)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes), $this->semStack[$stackPos - (8 - 3)]);
            $this->checkClass($this->semValue[0], -1);
        }, 481 => function ($stackPos) {
            $this->semValue = new Expr\New_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 482 => function ($stackPos) {
            list($class, $ctorArgs) = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 483 => function ($stackPos) {
            $this->semValue = array();
        }, 484 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 3)];
        }, 485 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 486 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 487 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 488 => function ($stackPos) {
            $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos - (2 - 2)], $this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 489 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 490 => function ($stackPos) {
            $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 491 => function ($stackPos) {
            $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 492 => function ($stackPos) {
            $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 493 => function ($stackPos) {
            $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 494 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 495 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 496 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 497 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 498 => function ($stackPos) {
            $this->semValue = new Name\FullyQualified(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 499 => function ($stackPos) {
            $this->semValue = new Name\Relative(\substr($this->semStack[$stackPos - (1 - 1)], 10), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 500 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 501 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 502 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 503 => function ($stackPos) {
            $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
            $this->errorState = 2;
        }, 504 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 505 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 506 => function ($stackPos) {
            $this->semValue = null;
        }, 507 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 508 => function ($stackPos) {
            $this->semValue = array();
        }, 509 => function ($stackPos) {
            $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos - (1 - 1)], '`'), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes));
        }, 510 => function ($stackPos) {
            foreach ($this->semStack[$stackPos - (1 - 1)] as $s) {
                if ($s instanceof Node\Scalar\EncapsedStringPart) {
                    $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', \true);
                }
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 511 => function ($stackPos) {
            $this->semValue = array();
        }, 512 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 513 => function ($stackPos) {
            $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 514 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 515 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 516 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 517 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 518 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 519 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 520 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 521 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 522 => function ($stackPos) {
            $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 523 => function ($stackPos) {
            $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], new Expr\Error($this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)]), $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->errorState = 2;
        }, 524 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes;
            $attrs['kind'] = Expr\Array_::KIND_SHORT;
            $this->semValue = new Expr\Array_($this->semStack[$stackPos - (3 - 2)], $attrs);
        }, 525 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes;
            $attrs['kind'] = Expr\Array_::KIND_LONG;
            $this->semValue = new Expr\Array_($this->semStack[$stackPos - (4 - 3)], $attrs);
        }, 526 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 527 => function ($stackPos) {
            $this->semValue = Scalar\String_::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 528 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes;
            $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
            foreach ($this->semStack[$stackPos - (3 - 2)] as $s) {
                if ($s instanceof Node\Scalar\EncapsedStringPart) {
                    $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', \true);
                }
            }
            $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos - (3 - 2)], $attrs);
        }, 529 => function ($stackPos) {
            $this->semValue = $this->parseLNumber($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 530 => function ($stackPos) {
            $this->semValue = Scalar\DNumber::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 531 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 532 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 533 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 534 => function ($stackPos) {
            $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \true);
        }, 535 => function ($stackPos) {
            $this->semValue = $this->parseDocString($this->semStack[$stackPos - (2 - 1)], '', $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (2 - 2)] + $this->endAttributeStack[$stackPos - (2 - 2)], \true);
        }, 536 => function ($stackPos) {
            $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \true);
        }, 537 => function ($stackPos) {
            $this->semValue = null;
        }, 538 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 539 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 540 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 541 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 542 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 543 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 544 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 545 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 546 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 547 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 548 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 549 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 550 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 551 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 552 => function ($stackPos) {
            $this->semValue = new Expr\MethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 553 => function ($stackPos) {
            $this->semValue = new Expr\NullsafeMethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 554 => function ($stackPos) {
            $this->semValue = null;
        }, 555 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 556 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 557 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 558 => function ($stackPos) {
            $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 559 => function ($stackPos) {
            $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 560 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 561 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 562 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 563 => function ($stackPos) {
            $this->semValue = new Expr\Variable(new Expr\Error($this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes), $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
            $this->errorState = 2;
        }, 564 => function ($stackPos) {
            $var = $this->semStack[$stackPos - (1 - 1)]->name;
            $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes) : $var;
        }, 565 => function ($stackPos) {
            $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 566 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 567 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 568 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 569 => function ($stackPos) {
            $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 570 => function ($stackPos) {
            $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 571 => function ($stackPos) {
            $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 572 => function ($stackPos) {
            $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 573 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 574 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 575 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 576 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 577 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 578 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 579 => function ($stackPos) {
            $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
            $this->errorState = 2;
        }, 580 => function ($stackPos) {
            $this->semValue = new Expr\List_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 581 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
            $end = \count($this->semValue) - 1;
            if ($this->semValue[$end] === null) {
                \array_pop($this->semValue);
            }
        }, 582 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 583 => function ($stackPos) {
            /* do nothing -- prevent default action of $$=$this->semStack[$1]. See $551. */
        }, 584 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 585 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 586 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 587 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 588 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 589 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 590 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 1)], \true, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 591 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 592 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 593 => function ($stackPos) {
            $this->semValue = null;
        }, 594 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 595 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 596 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 597 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]);
        }, 598 => function ($stackPos) {
            $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 599 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 600 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 601 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 602 => function ($stackPos) {
            $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 603 => function ($stackPos) {
            $this->semValue = new Expr\NullsafePropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 604 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 605 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 606 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 4)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 607 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 608 => function ($stackPos) {
            $this->semValue = new Scalar\String_($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 609 => function ($stackPos) {
            $this->semValue = $this->parseNumString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 610 => function ($stackPos) {
            $this->semValue = $this->parseNumString('-' . $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 611 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }];
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\PhpParser\Parser;

/* GENERATED file based on grammar/tokens.y */
final class Tokens
{
    const YYERRTOK = 256;
    const T_THROW = 257;
    const T_INCLUDE = 258;
    const T_INCLUDE_ONCE = 259;
    const T_EVAL = 260;
    const T_REQUIRE = 261;
    const T_REQUIRE_ONCE = 262;
    const T_LOGICAL_OR = 263;
    const T_LOGICAL_XOR = 264;
    const T_LOGICAL_AND = 265;
    const T_PRINT = 266;
    const T_YIELD = 267;
    const T_DOUBLE_ARROW = 268;
    const T_YIELD_FROM = 269;
    const T_PLUS_EQUAL = 270;
    const T_MINUS_EQUAL = 271;
    const T_MUL_EQUAL = 272;
    const T_DIV_EQUAL = 273;
    const T_CONCAT_EQUAL = 274;
    const T_MOD_EQUAL = 275;
    const T_AND_EQUAL = 276;
    const T_OR_EQUAL = 277;
    const T_XOR_EQUAL = 278;
    const T_SL_EQUAL = 279;
    const T_SR_EQUAL = 280;
    const T_POW_EQUAL = 281;
    const T_COALESCE_EQUAL = 282;
    const T_COALESCE = 283;
    const T_BOOLEAN_OR = 284;
    const T_BOOLEAN_AND = 285;
    const T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG = 286;
    const T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG = 287;
    const T_IS_EQUAL = 288;
    const T_IS_NOT_EQUAL = 289;
    const T_IS_IDENTICAL = 290;
    const T_IS_NOT_IDENTICAL = 291;
    const T_SPACESHIP = 292;
    const T_IS_SMALLER_OR_EQUAL = 293;
    const T_IS_GREATER_OR_EQUAL = 294;
    const T_SL = 295;
    const T_SR = 296;
    const T_INSTANCEOF = 297;
    const T_INC = 298;
    const T_DEC = 299;
    const T_INT_CAST = 300;
    const T_DOUBLE_CAST = 301;
    const T_STRING_CAST = 302;
    const T_ARRAY_CAST = 303;
    const T_OBJECT_CAST = 304;
    const T_BOOL_CAST = 305;
    const T_UNSET_CAST = 306;
    const T_POW = 307;
    const T_NEW = 308;
    const T_CLONE = 309;
    const T_EXIT = 310;
    const T_IF = 311;
    const T_ELSEIF = 312;
    const T_ELSE = 313;
    const T_ENDIF = 314;
    const T_LNUMBER = 315;
    const T_DNUMBER = 316;
    const T_STRING = 317;
    const T_STRING_VARNAME = 318;
    const T_VARIABLE = 319;
    const T_NUM_STRING = 320;
    const T_INLINE_HTML = 321;
    const T_ENCAPSED_AND_WHITESPACE = 322;
    const T_CONSTANT_ENCAPSED_STRING = 323;
    const T_ECHO = 324;
    const T_DO = 325;
    const T_WHILE = 326;
    const T_ENDWHILE = 327;
    const T_FOR = 328;
    const T_ENDFOR = 329;
    const T_FOREACH = 330;
    const T_ENDFOREACH = 331;
    const T_DECLARE = 332;
    const T_ENDDECLARE = 333;
    const T_AS = 334;
    const T_SWITCH = 335;
    const T_MATCH = 336;
    const T_ENDSWITCH = 337;
    const T_CASE = 338;
    const T_DEFAULT = 339;
    const T_BREAK = 340;
    const T_CONTINUE = 341;
    const T_GOTO = 342;
    const T_FUNCTION = 343;
    const T_FN = 344;
    const T_CONST = 345;
    const T_RETURN = 346;
    const T_TRY = 347;
    const T_CATCH = 348;
    const T_FINALLY = 349;
    const T_USE = 350;
    const T_INSTEADOF = 351;
    const T_GLOBAL = 352;
    const T_STATIC = 353;
    const T_ABSTRACT = 354;
    const T_FINAL = 355;
    const T_PRIVATE = 356;
    const T_PROTECTED = 357;
    const T_PUBLIC = 358;
    const T_READONLY = 359;
    const T_VAR = 360;
    const T_UNSET = 361;
    const T_ISSET = 362;
    const T_EMPTY = 363;
    const T_HALT_COMPILER = 364;
    const T_CLASS = 365;
    const T_TRAIT = 366;
    const T_INTERFACE = 367;
    const T_ENUM = 368;
    const T_EXTENDS = 369;
    const T_IMPLEMENTS = 370;
    const T_OBJECT_OPERATOR = 371;
    const T_NULLSAFE_OBJECT_OPERATOR = 372;
    const T_LIST = 373;
    const T_ARRAY = 374;
    const T_CALLABLE = 375;
    const T_CLASS_C = 376;
    const T_TRAIT_C = 377;
    const T_METHOD_C = 378;
    const T_FUNC_C = 379;
    const T_LINE = 380;
    const T_FILE = 381;
    const T_START_HEREDOC = 382;
    const T_END_HEREDOC = 383;
    const T_DOLLAR_OPEN_CURLY_BRACES = 384;
    const T_CURLY_OPEN = 385;
    const T_PAAMAYIM_NEKUDOTAYIM = 386;
    const T_NAMESPACE = 387;
    const T_NS_C = 388;
    const T_DIR = 389;
    const T_NS_SEPARATOR = 390;
    const T_ELLIPSIS = 391;
    const T_NAME_FULLY_QUALIFIED = 392;
    const T_NAME_QUALIFIED = 393;
    const T_NAME_RELATIVE = 394;
    const T_ATTRIBUTE = 395;
}
<?php

namespace _HumbugBox1cb33d1f20f1\PhpParser\Parser;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
/* This is an automatically GENERATED file, which should not be manually edited.
 * Instead edit one of the following:
 *  * the grammar files grammar/php5.y or grammar/php7.y
 *  * the skeleton file grammar/parser.template
 *  * the preprocessing script grammar/rebuildParsers.php
 */
class Php5 extends \_HumbugBox1cb33d1f20f1\PhpParser\ParserAbstract
{
    protected $tokenToSymbolMapSize = 396;
    protected $actionTableSize = 1099;
    protected $gotoTableSize = 640;
    protected $invalidSymbol = 168;
    protected $errorSymbol = 1;
    protected $defaultAction = -32766;
    protected $unexpectedTokenRule = 32767;
    protected $YY2TBLSTATE = 415;
    protected $numNonLeafStates = 663;
    protected $symbolToName = array("EOF", "error", "T_THROW", "T_INCLUDE", "T_INCLUDE_ONCE", "T_EVAL", "T_REQUIRE", "T_REQUIRE_ONCE", "','", "T_LOGICAL_OR", "T_LOGICAL_XOR", "T_LOGICAL_AND", "T_PRINT", "T_YIELD", "T_DOUBLE_ARROW", "T_YIELD_FROM", "'='", "T_PLUS_EQUAL", "T_MINUS_EQUAL", "T_MUL_EQUAL", "T_DIV_EQUAL", "T_CONCAT_EQUAL", "T_MOD_EQUAL", "T_AND_EQUAL", "T_OR_EQUAL", "T_XOR_EQUAL", "T_SL_EQUAL", "T_SR_EQUAL", "T_POW_EQUAL", "T_COALESCE_EQUAL", "'?'", "':'", "T_COALESCE", "T_BOOLEAN_OR", "T_BOOLEAN_AND", "'|'", "'^'", "T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG", "T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG", "T_IS_EQUAL", "T_IS_NOT_EQUAL", "T_IS_IDENTICAL", "T_IS_NOT_IDENTICAL", "T_SPACESHIP", "'<'", "T_IS_SMALLER_OR_EQUAL", "'>'", "T_IS_GREATER_OR_EQUAL", "T_SL", "T_SR", "'+'", "'-'", "'.'", "'*'", "'/'", "'%'", "'!'", "T_INSTANCEOF", "'~'", "T_INC", "T_DEC", "T_INT_CAST", "T_DOUBLE_CAST", "T_STRING_CAST", "T_ARRAY_CAST", "T_OBJECT_CAST", "T_BOOL_CAST", "T_UNSET_CAST", "'@'", "T_POW", "'['", "T_NEW", "T_CLONE", "T_EXIT", "T_IF", "T_ELSEIF", "T_ELSE", "T_ENDIF", "T_LNUMBER", "T_DNUMBER", "T_STRING", "T_STRING_VARNAME", "T_VARIABLE", "T_NUM_STRING", "T_INLINE_HTML", "T_ENCAPSED_AND_WHITESPACE", "T_CONSTANT_ENCAPSED_STRING", "T_ECHO", "T_DO", "T_WHILE", "T_ENDWHILE", "T_FOR", "T_ENDFOR", "T_FOREACH", "T_ENDFOREACH", "T_DECLARE", "T_ENDDECLARE", "T_AS", "T_SWITCH", "T_MATCH", "T_ENDSWITCH", "T_CASE", "T_DEFAULT", "T_BREAK", "T_CONTINUE", "T_GOTO", "T_FUNCTION", "T_FN", "T_CONST", "T_RETURN", "T_TRY", "T_CATCH", "T_FINALLY", "T_USE", "T_INSTEADOF", "T_GLOBAL", "T_STATIC", "T_ABSTRACT", "T_FINAL", "T_PRIVATE", "T_PROTECTED", "T_PUBLIC", "T_READONLY", "T_VAR", "T_UNSET", "T_ISSET", "T_EMPTY", "T_HALT_COMPILER", "T_CLASS", "T_TRAIT", "T_INTERFACE", "T_EXTENDS", "T_IMPLEMENTS", "T_OBJECT_OPERATOR", "T_LIST", "T_ARRAY", "T_CALLABLE", "T_CLASS_C", "T_TRAIT_C", "T_METHOD_C", "T_FUNC_C", "T_LINE", "T_FILE", "T_START_HEREDOC", "T_END_HEREDOC", "T_DOLLAR_OPEN_CURLY_BRACES", "T_CURLY_OPEN", "T_PAAMAYIM_NEKUDOTAYIM", "T_NAMESPACE", "T_NS_C", "T_DIR", "T_NS_SEPARATOR", "T_ELLIPSIS", "T_NAME_FULLY_QUALIFIED", "T_NAME_QUALIFIED", "T_NAME_RELATIVE", "';'", "'{'", "'}'", "'('", "')'", "'\$'", "'`'", "']'", "'\"'", "T_ENUM", "T_NULLSAFE_OBJECT_OPERATOR", "T_ATTRIBUTE");
    protected $tokenToSymbol = array(0, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 56, 164, 168, 161, 55, 168, 168, 159, 160, 53, 50, 8, 51, 52, 54, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 31, 156, 44, 16, 46, 30, 68, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 70, 168, 163, 36, 168, 162, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 157, 35, 158, 58, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43, 45, 47, 48, 49, 57, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 165, 131, 132, 133, 166, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 167);
    protected $action = array(700, 670, 671, 672, 673, 674, 286, 675, 676, 677, 713, 714, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, 245, 246, 242, 243, 244, -32766, -32766, 678, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 1229, 245, 246, 1230, 679, 680, 681, 682, 683, 684, 685, 899, 900, 747, -32766, -32766, -32766, -32766, -32766, -32766, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 716, 739, 717, 718, 719, 720, 708, 709, 710, 738, 711, 712, 697, 698, 699, 701, 702, 703, 741, 742, 743, 744, 745, 746, 875, 704, 705, 706, 707, 737, 728, 726, 727, 723, 724, 1046, 715, 721, 722, 729, 730, 732, 731, 733, 734, 55, 56, 425, 57, 58, 725, 736, 735, 755, 59, 60, -226, 61, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32766, 337, -32767, -32767, -32767, -32767, 29, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 620, -32766, -32766, -32766, -32766, 62, 63, 1046, -32766, -32766, -32766, 64, 419, 65, 294, 295, 66, 67, 68, 69, 70, 71, 72, 73, 823, 25, 302, 74, 418, 984, 986, 669, 668, 1100, 1101, 1078, 755, 755, 767, 1220, 768, 470, -32766, -32766, -32766, 341, 749, 824, 54, -32767, -32767, -32767, -32767, 98, 99, 100, 101, 102, 220, 221, 222, 362, 876, -32766, 27, -32766, -32766, -32766, -32766, -32766, 1046, 493, 126, 1080, 1079, 1081, 370, 1068, 930, 207, 478, 479, 952, 953, 954, 951, 950, 949, 128, 480, 481, 803, 1106, 1107, 1108, 1109, 1103, 1104, 319, 32, 297, 10, 211, -515, 1110, 1105, 669, 668, 1080, 1079, 1081, 220, 221, 222, 41, 364, 341, 334, 421, 336, 426, -128, -128, -128, 313, 1046, 469, -4, 824, 54, 812, 770, 207, 40, 21, 427, -128, 471, -128, 472, -128, 473, -128, 1046, 428, 220, 221, 222, -32766, 33, 34, 429, 361, 327, 52, 35, 474, -32766, -32766, -32766, 342, 357, 358, 475, 476, 48, 207, 249, 669, 668, 477, 443, 300, 795, 846, 430, 431, 28, -32766, 814, -32766, -32766, -32766, -32766, -32766, -32766, -32766, -32767, -32767, -32767, -32767, -32767, 952, 953, 954, 951, 950, 949, 422, 755, 424, 426, 826, 634, -128, -32766, -32766, 469, 824, 54, 288, 812, 1151, 755, 40, 21, 427, 317, 471, 345, 472, 129, 473, 9, 1186, 428, 769, 360, 324, 905, 33, 34, 429, 361, 1046, 415, 35, 474, 944, 1068, 315, 125, 357, 358, 475, 476, -32766, -32766, -32766, 926, 302, 477, 121, 1068, 759, 846, 430, 431, 669, 668, 423, 755, 1152, 809, 1046, 480, 766, -32766, 805, -32766, -32766, -32766, -32766, -261, 127, 347, 436, 841, 341, 1078, 1200, 426, 446, 826, 634, -4, 807, 469, 824, 54, 436, 812, 341, 755, 40, 21, 427, 444, 471, 130, 472, 1068, 473, 346, 767, 428, 768, -211, -211, -211, 33, 34, 429, 361, 308, 1076, 35, 474, -32766, -32766, -32766, 1046, 357, 358, 475, 476, -32766, -32766, -32766, 906, 120, 477, 539, 1068, 795, 846, 430, 431, 436, -32766, 341, -32766, -32766, -32766, 1046, 480, 810, -32766, 925, -32766, -32766, 754, 1080, 1079, 1081, 49, -32766, -32766, -32766, 749, 751, 426, 1201, 826, 634, -211, 30, 469, 669, 668, 436, 812, 341, 75, 40, 21, 427, -32766, 471, 1064, 472, 124, 473, 669, 668, 428, 212, -210, -210, -210, 33, 34, 429, 361, 51, 1186, 35, 474, 755, -32766, -32766, -32766, 357, 358, 475, 476, 213, 824, 54, 221, 222, 477, 20, 581, 795, 846, 430, 431, 220, 221, 222, 755, 222, 247, 78, 79, 80, 81, 341, 207, 517, 103, 104, 105, 752, 307, 131, 637, 1068, 207, 341, 207, 122, 826, 634, -210, 36, 106, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 1112, 307, 346, 436, 214, 341, 824, 54, 426, 123, 250, 129, 134, 106, 469, -32766, 572, 1112, 812, 245, 246, 40, 21, 427, 251, 471, 252, 472, 341, 473, 453, 22, 428, 207, 899, 900, 638, 33, 34, 429, 824, 54, -86, 35, 474, 220, 221, 222, 314, 357, 358, 100, 101, 102, 239, 240, 241, 645, 477, -230, 458, 589, 135, 374, 596, 597, 207, 760, 640, 648, 642, 941, 654, 929, 662, 822, 133, 307, 837, 426, -32766, 106, 749, 43, 44, 469, 45, 442, 46, 812, 826, 634, 40, 21, 427, 47, 471, 50, 472, 53, 473, 132, 608, 428, 302, 604, -280, -32766, 33, 34, 429, 824, 54, 426, 35, 474, 755, 957, -84, 469, 357, 358, 521, 812, 628, 363, 40, 21, 427, 477, 471, 575, 472, -515, 473, 847, 616, 428, -423, -32766, 11, 646, 33, 34, 429, 824, 54, 445, 35, 474, 462, 285, 578, 1111, 357, 358, 593, 369, 848, 594, 290, 826, 634, 477, 0, 0, 532, 0, 0, 325, 0, 0, 0, 0, 0, 651, 0, 0, 0, 322, 326, 0, 0, 0, 426, 0, 0, 0, 0, 323, 469, 316, 318, -516, 812, 862, 634, 40, 21, 427, 0, 471, 0, 472, 0, 473, 1158, 0, 428, 0, -414, 6, 7, 33, 34, 429, 824, 54, 426, 35, 474, 12, 14, 373, 469, 357, 358, -424, 812, 563, 754, 40, 21, 427, 477, 471, 248, 472, 839, 473, 38, 39, 428, 657, 658, 765, 813, 33, 34, 429, 821, 800, 815, 35, 474, 215, 216, 878, 869, 357, 358, 217, 870, 218, 798, 863, 826, 634, 477, 860, 858, 936, 937, 934, 820, 209, 804, 806, 808, 811, 933, 763, 764, 1100, 1101, 935, 659, 78, 335, 426, 359, 1102, 635, 639, 641, 469, 643, 644, 647, 812, 826, 634, 40, 21, 427, 649, 471, 650, 472, 652, 473, 653, 636, 428, 796, 1226, 1228, 762, 33, 34, 429, 215, 216, 845, 35, 474, 761, 217, 844, 218, 357, 358, 1227, 843, 1060, 831, 1048, 842, 1049, 477, 559, 209, 1106, 1107, 1108, 1109, 1103, 1104, 398, 1100, 1101, 829, 942, 867, 1110, 1105, 868, 1102, 457, 1225, 1194, 1192, 1177, 1157, 219, 1190, 1091, 917, 1198, 1188, 0, 826, 634, 24, -433, 26, 31, 37, 42, 76, 77, 210, 287, 292, 293, 308, 309, 310, 311, 339, 356, 416, 0, -227, -226, 16, 17, 18, 393, 454, 461, 463, 467, 553, 625, 1051, 559, 1054, 1106, 1107, 1108, 1109, 1103, 1104, 398, 907, 1116, 1050, 1026, 564, 1110, 1105, 1025, 1093, 1055, 0, 1044, 0, 1057, 1056, 219, 1059, 1058, 1075, 0, 1191, 1176, 1172, 1189, 1090, 1223, 1117, 1171, 600);
    protected $actionCheck = array(2, 3, 4, 5, 6, 7, 14, 9, 10, 11, 12, 13, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 0, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 9, 10, 11, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 69, 70, 53, 54, 55, 9, 10, 57, 30, 116, 32, 33, 34, 35, 36, 37, 38, 80, 69, 70, 83, 71, 72, 73, 74, 75, 76, 77, 135, 136, 80, 33, 34, 35, 36, 37, 38, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 31, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 13, 134, 135, 136, 137, 138, 139, 140, 141, 142, 3, 4, 5, 6, 7, 148, 149, 150, 82, 12, 13, 160, 15, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 8, 44, 45, 46, 47, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 80, 33, 34, 35, 36, 50, 51, 13, 9, 10, 11, 56, 128, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 1, 70, 71, 72, 73, 59, 60, 37, 38, 78, 79, 80, 82, 82, 106, 85, 108, 86, 9, 10, 11, 161, 80, 1, 2, 44, 45, 46, 47, 48, 49, 50, 51, 52, 9, 10, 11, 106, 156, 30, 8, 32, 33, 34, 35, 36, 13, 116, 8, 153, 154, 155, 8, 122, 158, 30, 125, 126, 116, 117, 118, 119, 120, 121, 31, 134, 135, 156, 137, 138, 139, 140, 141, 142, 143, 145, 146, 8, 8, 133, 149, 150, 37, 38, 153, 154, 155, 9, 10, 11, 159, 8, 161, 162, 8, 164, 74, 75, 76, 77, 8, 13, 80, 0, 1, 2, 84, 158, 30, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 13, 98, 9, 10, 11, 9, 103, 104, 105, 106, 8, 70, 109, 110, 9, 10, 11, 8, 115, 116, 117, 118, 70, 30, 31, 37, 38, 124, 31, 8, 127, 128, 129, 130, 8, 30, 156, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 116, 117, 118, 119, 120, 121, 8, 82, 8, 74, 156, 157, 158, 33, 34, 80, 1, 2, 8, 84, 163, 82, 87, 88, 89, 133, 91, 70, 93, 152, 95, 108, 82, 98, 158, 8, 113, 160, 103, 104, 105, 106, 13, 108, 109, 110, 123, 122, 113, 157, 115, 116, 117, 118, 9, 10, 11, 156, 71, 124, 157, 122, 127, 128, 129, 130, 37, 38, 8, 82, 160, 156, 13, 134, 156, 30, 156, 32, 33, 34, 35, 158, 157, 148, 159, 122, 161, 80, 1, 74, 133, 156, 157, 158, 156, 80, 1, 2, 159, 84, 161, 82, 87, 88, 89, 157, 91, 157, 93, 122, 95, 161, 106, 98, 108, 100, 101, 102, 103, 104, 105, 106, 159, 116, 109, 110, 9, 10, 11, 13, 115, 116, 117, 118, 9, 10, 11, 160, 16, 124, 81, 122, 127, 128, 129, 130, 159, 30, 161, 32, 33, 34, 13, 134, 156, 30, 156, 32, 33, 153, 153, 154, 155, 70, 9, 10, 11, 80, 80, 74, 160, 156, 157, 158, 14, 80, 37, 38, 159, 84, 161, 152, 87, 88, 89, 30, 91, 160, 93, 14, 95, 37, 38, 98, 16, 100, 101, 102, 103, 104, 105, 106, 70, 82, 109, 110, 82, 33, 34, 35, 115, 116, 117, 118, 16, 1, 2, 10, 11, 124, 160, 85, 127, 128, 129, 130, 9, 10, 11, 82, 11, 14, 157, 9, 10, 11, 161, 30, 85, 53, 54, 55, 154, 57, 157, 31, 122, 30, 161, 30, 157, 156, 157, 158, 30, 69, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 144, 57, 161, 159, 16, 161, 1, 2, 74, 157, 16, 152, 157, 69, 80, 116, 161, 144, 84, 69, 70, 87, 88, 89, 16, 91, 16, 93, 161, 95, 75, 76, 98, 30, 135, 136, 31, 103, 104, 105, 1, 2, 31, 109, 110, 9, 10, 11, 31, 115, 116, 50, 51, 52, 50, 51, 52, 31, 124, 160, 75, 76, 101, 102, 111, 112, 30, 156, 157, 31, 31, 156, 157, 156, 157, 31, 31, 57, 38, 74, 33, 69, 80, 70, 70, 80, 70, 89, 70, 84, 156, 157, 87, 88, 89, 70, 91, 70, 93, 70, 95, 70, 96, 98, 71, 77, 82, 85, 103, 104, 105, 1, 2, 74, 109, 110, 82, 82, 97, 80, 115, 116, 85, 84, 92, 106, 87, 88, 89, 124, 91, 90, 93, 133, 95, 128, 94, 98, 147, 116, 97, 31, 103, 104, 105, 1, 2, 97, 109, 110, 97, 97, 100, 144, 115, 116, 100, 106, 128, 113, 161, 156, 157, 124, -1, -1, 151, -1, -1, 114, -1, -1, -1, -1, -1, 31, -1, -1, -1, 131, 131, -1, -1, -1, 74, -1, -1, -1, -1, 132, 80, 133, 133, 133, 84, 156, 157, 87, 88, 89, -1, 91, -1, 93, -1, 95, 144, -1, 98, -1, 147, 147, 147, 103, 104, 105, 1, 2, 74, 109, 110, 147, 147, 147, 80, 115, 116, 147, 84, 151, 153, 87, 88, 89, 124, 91, 31, 93, 152, 95, 156, 156, 98, 156, 156, 156, 156, 103, 104, 105, 156, 156, 156, 109, 110, 50, 51, 156, 156, 115, 116, 56, 156, 58, 156, 156, 156, 157, 124, 156, 156, 156, 156, 156, 156, 70, 156, 156, 156, 156, 156, 156, 156, 78, 79, 156, 158, 157, 157, 74, 157, 86, 157, 157, 157, 80, 157, 157, 157, 84, 156, 157, 87, 88, 89, 157, 91, 157, 93, 157, 95, 157, 157, 98, 158, 158, 158, 158, 103, 104, 105, 50, 51, 158, 109, 110, 158, 56, 158, 58, 115, 116, 158, 158, 158, 158, 158, 158, 158, 124, 135, 70, 137, 138, 139, 140, 141, 142, 143, 78, 79, 158, 158, 158, 149, 150, 158, 86, 158, 158, 158, 158, 158, 164, 159, 158, 158, 158, 158, 158, -1, 156, 157, 159, 162, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, -1, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 135, 160, 137, 138, 139, 140, 141, 142, 143, 160, 160, 160, 160, 160, 149, 150, 160, 160, 163, -1, 162, -1, 163, 163, 159, 163, 163, 163, -1, 163, 163, 163, 163, 163, 163, 163, 163, 163);
    protected $actionBase = array(0, 229, 310, 390, 470, 103, 325, 325, 784, -2, -2, 149, -2, -2, -2, 660, 765, 799, 765, 589, 694, 870, 870, 870, 252, 404, 404, 404, 514, 177, 177, 918, 434, 118, 295, 313, 240, 491, 491, 491, 491, 138, 138, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 89, 206, 773, 550, 535, 775, 776, 777, 912, 709, 913, 856, 857, 700, 858, 859, 862, 863, 864, 855, 865, 935, 866, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 322, 592, 285, 319, 232, 44, 691, 691, 691, 691, 691, 691, 691, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, 582, 530, 530, 530, 594, 860, 658, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 926, 500, -21, -21, 492, 702, 420, 355, 216, 549, 151, 26, 26, 331, 331, 331, 331, 331, 46, 46, 5, 5, 5, 5, 153, 188, 188, 188, 188, 121, 121, 121, 121, 314, 314, 394, 394, 362, 300, 298, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 67, 656, 656, 659, 659, 522, 554, 554, 554, 554, 679, -59, -59, 381, 462, 462, 462, 528, 717, 854, 382, 382, 382, 382, 382, 382, 561, 561, 561, -3, -3, -3, 692, 115, 137, 115, 137, 678, 732, 450, 732, 338, 677, -15, 510, 810, 468, 707, 850, 711, 853, 572, 735, 267, 529, 654, 674, 463, 529, 529, 529, 529, 654, 610, 640, 608, 463, 529, 463, 718, 323, 496, 89, 570, 507, 675, 778, 293, 670, 780, 290, 373, 332, 566, 278, 435, 733, 781, 914, 917, 385, 715, 675, 675, 675, 352, 511, 278, -8, 605, 605, 605, 605, 156, 605, 605, 605, 605, 251, 276, 375, 402, 779, 657, 657, 690, 872, 869, 869, 657, 689, 657, 690, 874, 874, 874, 874, 657, 657, 657, 657, 869, 869, 869, 688, 869, 239, 703, 704, 704, 874, 742, 743, 657, 657, 712, 869, 869, 869, 712, 695, 874, 701, 741, 277, 869, 874, 672, 689, 672, 657, 701, 672, 689, 689, 672, 22, 666, 668, 873, 875, 887, 790, 662, 685, 879, 880, 876, 878, 871, 699, 744, 745, 497, 669, 671, 673, 680, 719, 682, 713, 674, 667, 667, 667, 655, 720, 655, 667, 667, 667, 667, 667, 667, 667, 667, 916, 646, 731, 714, 653, 749, 553, 573, 791, 664, 811, 900, 893, 867, 919, 881, 898, 655, 920, 739, 247, 643, 882, 783, 786, 655, 883, 655, 792, 655, 902, 812, 686, 813, 814, 667, 910, 921, 923, 924, 925, 927, 928, 929, 930, 684, 931, 750, 696, 894, 299, 877, 718, 729, 705, 788, 751, 820, 328, 932, 823, 655, 655, 794, 785, 655, 795, 756, 740, 890, 757, 895, 933, 664, 708, 896, 655, 706, 825, 934, 328, 681, 683, 888, 661, 761, 886, 911, 885, 796, 649, 663, 829, 830, 831, 693, 763, 891, 892, 889, 764, 803, 665, 805, 697, 832, 807, 884, 768, 833, 834, 899, 676, 730, 710, 698, 687, 809, 835, 897, 769, 770, 771, 848, 772, 849, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, -2, -2, -2, -2, 0, 0, -2, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 599, -21, -21, -21, -21, 599, -21, -21, -21, -21, -21, -21, -21, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, -21, 599, 599, 599, -21, 382, -21, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 599, 0, 0, 599, -21, 599, -21, 599, -21, -21, 599, 599, 599, 599, 599, 599, 599, -21, -21, -21, -21, -21, -21, 0, 561, 561, 561, 561, -21, -21, -21, -21, 382, 382, 382, 382, 382, 382, 259, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 561, 561, -3, -3, 382, 382, 382, 382, 382, 259, 382, 382, 463, 689, 689, 689, 137, 137, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, 463, 0, 463, 0, 382, 463, 689, 463, 657, 137, 689, 689, 463, 869, 616, 616, 616, 616, 328, 278, 0, 0, 689, 689, 0, 0, 0, 0, 0, 689, 0, 0, 0, 0, 0, 0, 869, 0, 0, 0, 0, 0, 667, 247, 0, 705, 335, 0, 0, 0, 0, 0, 0, 705, 335, 347, 347, 0, 684, 667, 667, 667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 328);
    protected $actionDefault = array(3, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 544, 544, 499, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 299, 299, 299, 32767, 32767, 32767, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, 32767, 32767, 32767, 32767, 32767, 32767, 383, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 389, 549, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 364, 365, 367, 368, 298, 552, 533, 247, 390, 548, 297, 249, 327, 503, 32767, 32767, 32767, 329, 122, 258, 203, 502, 125, 296, 234, 382, 384, 328, 303, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 302, 458, 361, 360, 359, 460, 32767, 459, 496, 496, 499, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 325, 487, 486, 326, 456, 330, 457, 333, 461, 464, 331, 332, 349, 350, 347, 348, 351, 462, 463, 480, 481, 478, 479, 301, 352, 353, 354, 355, 482, 483, 484, 485, 32767, 32767, 543, 543, 32767, 32767, 282, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 340, 341, 471, 472, 32767, 238, 238, 238, 238, 283, 238, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 335, 336, 334, 466, 467, 465, 432, 32767, 32767, 32767, 434, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 504, 32767, 32767, 32767, 32767, 32767, 517, 421, 171, 32767, 413, 32767, 171, 171, 171, 171, 32767, 222, 224, 167, 32767, 171, 32767, 490, 32767, 32767, 32767, 32767, 522, 345, 32767, 32767, 116, 32767, 32767, 32767, 559, 32767, 517, 32767, 116, 32767, 32767, 32767, 32767, 358, 337, 338, 339, 32767, 32767, 521, 515, 474, 475, 476, 477, 32767, 468, 469, 470, 473, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 429, 435, 435, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 520, 519, 32767, 414, 498, 188, 186, 186, 32767, 208, 208, 32767, 32767, 190, 491, 510, 32767, 190, 173, 32767, 400, 175, 498, 32767, 32767, 240, 32767, 240, 32767, 400, 240, 32767, 32767, 240, 32767, 415, 439, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 379, 380, 493, 506, 32767, 507, 32767, 413, 343, 344, 346, 322, 32767, 324, 369, 370, 371, 372, 373, 374, 375, 377, 32767, 419, 32767, 422, 32767, 32767, 32767, 257, 32767, 557, 32767, 32767, 306, 557, 32767, 32767, 32767, 551, 32767, 32767, 300, 32767, 32767, 32767, 32767, 253, 32767, 169, 32767, 541, 32767, 558, 32767, 515, 32767, 342, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 516, 32767, 32767, 32767, 32767, 229, 32767, 452, 32767, 116, 32767, 32767, 32767, 189, 32767, 32767, 304, 248, 32767, 32767, 550, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 114, 32767, 170, 32767, 32767, 32767, 191, 32767, 32767, 515, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 295, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 515, 32767, 32767, 233, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 415, 32767, 276, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 127, 127, 3, 127, 127, 260, 3, 260, 127, 260, 260, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 216, 219, 208, 208, 164, 127, 127, 268);
    protected $goto = array(166, 140, 140, 140, 166, 187, 168, 144, 147, 141, 142, 143, 149, 163, 163, 163, 163, 144, 144, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 138, 159, 160, 161, 162, 184, 139, 185, 494, 495, 377, 496, 500, 501, 502, 503, 504, 505, 506, 507, 970, 164, 145, 146, 148, 171, 176, 186, 203, 253, 256, 258, 260, 263, 264, 265, 266, 267, 268, 269, 277, 278, 279, 280, 303, 304, 328, 329, 330, 394, 395, 396, 543, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 150, 151, 152, 167, 153, 169, 154, 204, 170, 155, 156, 157, 205, 158, 136, 621, 561, 757, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 1113, 629, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 758, 520, 531, 509, 656, 556, 1183, 750, 509, 592, 786, 1183, 888, 612, 613, 884, 617, 618, 624, 626, 631, 633, 817, 855, 855, 855, 855, 850, 856, 174, 891, 891, 1205, 1205, 177, 178, 179, 401, 402, 403, 404, 173, 202, 206, 208, 257, 259, 261, 262, 270, 271, 272, 273, 274, 275, 281, 282, 283, 284, 305, 306, 331, 332, 333, 406, 407, 408, 409, 175, 180, 254, 255, 181, 182, 183, 498, 498, 498, 498, 498, 498, 861, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 510, 586, 538, 601, 602, 510, 545, 546, 547, 548, 549, 550, 551, 552, 554, 587, 1209, 560, 350, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 400, 607, 537, 537, 569, 533, 909, 535, 535, 497, 499, 525, 541, 570, 573, 584, 591, 298, 296, 296, 296, 298, 289, 299, 611, 378, 511, 614, 595, 947, 375, 511, 437, 437, 437, 437, 437, 437, 1163, 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, 1077, 948, 338, 1175, 321, 1077, 898, 898, 898, 898, 606, 898, 898, 1217, 1217, 1202, 753, 576, 605, 756, 1077, 1077, 1077, 1077, 1077, 1077, 1069, 384, 384, 384, 391, 1217, 877, 859, 857, 859, 655, 466, 512, 886, 881, 753, 384, 753, 384, 968, 384, 895, 385, 588, 353, 414, 384, 1231, 1019, 542, 1197, 1197, 1197, 568, 1094, 386, 386, 386, 904, 915, 515, 1029, 19, 15, 372, 389, 915, 940, 448, 450, 632, 340, 1216, 1216, 1114, 615, 938, 840, 555, 775, 386, 913, 1070, 1073, 1074, 399, 1069, 1182, 660, 23, 1216, 773, 1182, 544, 603, 1066, 1219, 1071, 1174, 1071, 519, 1199, 1199, 1199, 1089, 1088, 1072, 343, 523, 534, 519, 519, 772, 351, 352, 13, 579, 583, 627, 1061, 388, 782, 562, 771, 515, 783, 1181, 3, 4, 918, 956, 865, 451, 574, 1160, 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 514, 529, 0, 0, 0, 0, 514, 0, 529, 0, 0, 0, 0, 610, 513, 516, 439, 440, 1067, 619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 780, 1224, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, 0, 0, 0, 0, 0, 778, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 301);
    protected $gotoCheck = array(43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 57, 69, 15, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 128, 9, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 16, 102, 32, 69, 32, 32, 120, 6, 69, 32, 29, 120, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 50, 69, 69, 69, 69, 69, 69, 27, 77, 77, 77, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 119, 119, 119, 119, 119, 119, 33, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, 67, 110, 67, 67, 119, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, 142, 57, 72, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 51, 51, 51, 51, 51, 51, 84, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 5, 5, 5, 5, 5, 5, 5, 63, 46, 124, 63, 129, 98, 63, 124, 57, 57, 57, 57, 57, 57, 133, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 98, 127, 82, 127, 57, 57, 57, 57, 57, 49, 57, 57, 144, 144, 140, 11, 40, 40, 14, 57, 57, 57, 57, 57, 57, 82, 13, 13, 13, 48, 144, 14, 14, 14, 14, 14, 57, 14, 14, 14, 11, 13, 11, 13, 102, 13, 79, 11, 70, 70, 70, 13, 13, 103, 2, 9, 9, 9, 2, 34, 125, 125, 125, 81, 13, 13, 34, 34, 34, 34, 17, 13, 8, 8, 8, 8, 18, 143, 143, 8, 8, 8, 9, 34, 25, 125, 85, 82, 82, 82, 125, 82, 121, 74, 34, 143, 24, 121, 47, 34, 116, 143, 82, 82, 82, 47, 121, 121, 121, 126, 126, 82, 58, 58, 58, 47, 47, 23, 72, 72, 58, 62, 62, 62, 114, 12, 23, 12, 23, 13, 26, 121, 30, 30, 86, 100, 71, 65, 66, 132, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 9, -1, -1, -1, -1, 9, -1, 9, -1, -1, -1, -1, 13, 9, 9, 9, 9, 13, 13, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 9, -1, -1, -1, -1, -1, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 5);
    protected $gotoBase = array(0, 0, -172, 0, 0, 353, 201, 0, 477, 149, 0, 110, 195, 117, 426, 112, 203, 140, 171, 0, 0, 0, 0, 168, 164, 157, 119, 27, 0, 205, -118, 0, -428, 266, 51, 0, 0, 0, 0, 0, 388, 0, 0, -24, 0, 0, 345, 484, 146, 133, 209, 75, 0, 0, 0, 0, 0, 107, 161, 0, 0, 0, 222, -77, 0, 106, 97, -343, 0, -94, 135, 123, -129, 0, 129, 0, 0, -50, 0, 143, 0, 159, 64, 0, 338, 132, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, 121, 0, 165, 156, 0, 0, 0, 0, 0, 87, 273, 259, 0, 0, 114, 0, 150, 0, 0, -5, -91, 200, 0, 0, 84, 154, 202, 77, -48, 178, 0, 0, 93, 187, 0, 0, 0, 0, 0, 0, 136, 0, 286, 167, 102, 0, 0);
    protected $gotoDefault = array(-32768, 468, 664, 2, 665, 835, 740, 748, 598, 482, 630, 582, 380, 1193, 792, 793, 794, 381, 368, 483, 379, 410, 405, 781, 774, 776, 784, 172, 411, 787, 1, 789, 518, 825, 1020, 365, 797, 366, 590, 799, 527, 801, 802, 137, 382, 383, 528, 484, 390, 577, 816, 276, 387, 818, 367, 819, 828, 371, 465, 455, 460, 530, 557, 609, 432, 447, 571, 565, 536, 1086, 566, 864, 349, 872, 661, 880, 883, 485, 558, 894, 452, 902, 1099, 397, 908, 914, 919, 291, 922, 417, 412, 585, 927, 928, 5, 932, 622, 623, 8, 312, 955, 599, 969, 420, 1039, 1041, 486, 487, 522, 459, 508, 526, 488, 1062, 441, 413, 1065, 433, 489, 490, 434, 435, 1083, 355, 1168, 354, 449, 320, 1155, 580, 1118, 456, 1208, 1164, 348, 491, 492, 376, 1187, 392, 1203, 438, 1210, 1218, 344, 540, 567);
    protected $ruleToNonTerminal = array(0, 1, 3, 3, 2, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 11, 12, 12, 13, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 18, 18, 19, 19, 21, 21, 17, 17, 22, 22, 23, 23, 24, 24, 25, 25, 20, 20, 26, 28, 28, 29, 30, 30, 32, 31, 31, 31, 31, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 14, 14, 54, 54, 56, 55, 55, 48, 48, 58, 58, 59, 59, 60, 60, 61, 61, 15, 16, 16, 16, 64, 64, 64, 65, 65, 68, 68, 66, 66, 70, 70, 41, 41, 50, 50, 53, 53, 53, 52, 52, 71, 42, 42, 42, 42, 72, 72, 73, 73, 74, 74, 39, 39, 35, 35, 75, 37, 37, 76, 36, 36, 38, 38, 49, 49, 49, 62, 62, 78, 78, 79, 79, 81, 81, 81, 80, 80, 63, 63, 82, 82, 82, 83, 83, 84, 84, 84, 44, 44, 85, 85, 85, 45, 45, 86, 86, 87, 87, 67, 88, 88, 88, 88, 93, 93, 94, 94, 95, 95, 95, 95, 95, 96, 97, 97, 92, 92, 89, 89, 91, 91, 99, 99, 98, 98, 98, 98, 98, 98, 90, 90, 101, 100, 100, 46, 46, 40, 40, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 34, 34, 47, 47, 106, 106, 107, 107, 107, 107, 113, 102, 102, 109, 109, 115, 115, 116, 117, 118, 118, 118, 118, 118, 118, 118, 69, 69, 57, 57, 57, 57, 103, 103, 122, 122, 119, 119, 123, 123, 123, 123, 104, 104, 104, 108, 108, 108, 114, 114, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 27, 27, 27, 27, 27, 27, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 112, 112, 105, 105, 105, 105, 129, 129, 132, 132, 131, 131, 133, 133, 51, 51, 51, 51, 135, 135, 134, 134, 134, 134, 134, 136, 136, 121, 121, 124, 124, 120, 120, 138, 137, 137, 137, 137, 125, 125, 125, 125, 111, 111, 126, 126, 126, 126, 77, 139, 139, 140, 140, 140, 110, 110, 141, 141, 142, 142, 142, 142, 142, 127, 127, 127, 127, 144, 145, 143, 143, 143, 143, 143, 143, 143, 146, 146, 146);
    protected $ruleToLength = array(1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, 1, 7, 6, 3, 1, 3, 1, 3, 1, 1, 3, 1, 3, 1, 2, 3, 1, 3, 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, 3, 5, 8, 3, 5, 9, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 1, 2, 2, 5, 7, 9, 5, 6, 3, 3, 2, 2, 1, 1, 1, 0, 2, 8, 0, 4, 1, 3, 0, 1, 0, 1, 0, 1, 1, 1, 10, 7, 6, 5, 1, 2, 2, 0, 2, 0, 2, 0, 2, 1, 3, 1, 4, 1, 4, 1, 1, 4, 1, 3, 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, 1, 1, 4, 0, 2, 3, 0, 2, 4, 0, 2, 0, 3, 1, 2, 1, 1, 0, 1, 3, 4, 6, 1, 1, 1, 0, 1, 0, 2, 2, 3, 3, 1, 3, 1, 2, 2, 3, 1, 1, 2, 4, 3, 1, 1, 3, 2, 0, 1, 3, 3, 9, 3, 1, 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, 3, 1, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, 0, 1, 1, 3, 3, 4, 4, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 5, 4, 3, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 2, 1, 2, 10, 11, 3, 3, 2, 4, 4, 3, 4, 4, 4, 4, 7, 3, 2, 0, 4, 1, 3, 2, 1, 2, 2, 4, 6, 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, 0, 2, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 3, 1, 4, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 4, 3, 1, 3, 1, 1, 3, 3, 0, 2, 0, 1, 3, 1, 3, 1, 1, 1, 1, 1, 6, 4, 3, 4, 2, 4, 4, 1, 3, 1, 2, 1, 1, 4, 1, 1, 3, 6, 4, 4, 4, 4, 1, 4, 0, 1, 1, 3, 1, 1, 4, 3, 1, 1, 1, 0, 0, 2, 3, 1, 3, 1, 4, 2, 2, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 6, 3, 1, 1, 1);
    protected function initReduceCallbacks()
    {
        $this->reduceCallbacks = [0 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 1 => function ($stackPos) {
            $this->semValue = $this->handleNamespaces($this->semStack[$stackPos - (1 - 1)]);
        }, 2 => function ($stackPos) {
            if (\is_array($this->semStack[$stackPos - (2 - 2)])) {
                $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]);
            } else {
                $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
                $this->semValue = $this->semStack[$stackPos - (2 - 1)];
            }
        }, 3 => function ($stackPos) {
            $this->semValue = array();
        }, 4 => function ($stackPos) {
            $startAttributes = $this->lookaheadStartAttributes;
            if (isset($startAttributes['comments'])) {
                $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments']));
            } else {
                $nop = null;
            }
            if ($nop !== null) {
                $this->semStack[$stackPos - (1 - 1)][] = $nop;
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 5 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 6 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 7 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 8 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 9 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 10 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 11 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 12 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 13 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 14 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 15 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 16 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 17 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 18 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 19 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 20 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 21 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 22 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 23 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 24 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 25 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 26 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 27 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 28 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 29 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 30 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 31 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 32 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 33 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 34 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 35 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 36 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 37 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 38 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 39 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 40 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 41 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 42 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 43 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 44 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 45 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 46 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 47 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 48 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 49 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 50 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 51 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 52 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 53 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 54 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 55 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 56 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 57 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 58 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 59 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 60 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 61 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 62 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 63 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 64 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 65 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 66 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 67 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 68 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 69 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 70 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 71 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 72 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 73 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 74 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 75 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 76 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 77 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 78 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 79 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 80 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 81 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 82 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 83 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 84 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 85 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 86 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 87 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 88 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 89 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 90 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 91 => function ($stackPos) {
            $this->semValue = new Name(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 92 => function ($stackPos) {
            $this->semValue = new Expr\Variable(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 93 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 94 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 95 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 96 => function ($stackPos) {
            $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 97 => function ($stackPos) {
            $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (3 - 2)], null, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
            $this->checkNamespace($this->semValue);
        }, 98 => function ($stackPos) {
            $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos - (5 - 2)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
            $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($this->semValue);
        }, 99 => function ($stackPos) {
            $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
            $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($this->semValue);
        }, 100 => function ($stackPos) {
            $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (3 - 2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 101 => function ($stackPos) {
            $this->semValue = new Stmt\Use_($this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 102 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 103 => function ($stackPos) {
            $this->semValue = new Stmt\Const_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 104 => function ($stackPos) {
            $this->semValue = Stmt\Use_::TYPE_FUNCTION;
        }, 105 => function ($stackPos) {
            $this->semValue = Stmt\Use_::TYPE_CONSTANT;
        }, 106 => function ($stackPos) {
            $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 6)], $this->semStack[$stackPos - (7 - 2)], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
        }, 107 => function ($stackPos) {
            $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 108 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 109 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 110 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 111 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 112 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 113 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 114 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (1 - 1));
        }, 115 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (3 - 3));
        }, 116 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (1 - 1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (1 - 1));
        }, 117 => function ($stackPos) {
            $this->semValue = new Stmt\UseUse($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->checkUseUse($this->semValue, $stackPos - (3 - 3));
        }, 118 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
            $this->semValue->type = Stmt\Use_::TYPE_NORMAL;
        }, 119 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue->type = $this->semStack[$stackPos - (2 - 1)];
        }, 120 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 121 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 122 => function ($stackPos) {
            $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 123 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 124 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 125 => function ($stackPos) {
            $this->semValue = new Node\Const_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 126 => function ($stackPos) {
            if (\is_array($this->semStack[$stackPos - (2 - 2)])) {
                $this->semValue = \array_merge($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]);
            } else {
                $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
                $this->semValue = $this->semStack[$stackPos - (2 - 1)];
            }
        }, 127 => function ($stackPos) {
            $this->semValue = array();
        }, 128 => function ($stackPos) {
            $startAttributes = $this->lookaheadStartAttributes;
            if (isset($startAttributes['comments'])) {
                $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments']));
            } else {
                $nop = null;
            }
            if ($nop !== null) {
                $this->semStack[$stackPos - (1 - 1)][] = $nop;
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 129 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 130 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 131 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 132 => function ($stackPos) {
            throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 133 => function ($stackPos) {
            if ($this->semStack[$stackPos - (3 - 2)]) {
                $this->semValue = $this->semStack[$stackPos - (3 - 2)];
                $attrs = $this->startAttributeStack[$stackPos - (3 - 1)];
                $stmts = $this->semValue;
                if (!empty($attrs['comments'])) {
                    $stmts[0]->setAttribute('comments', \array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', [])));
                }
            } else {
                $startAttributes = $this->startAttributeStack[$stackPos - (3 - 1)];
                if (isset($startAttributes['comments'])) {
                    $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes);
                } else {
                    $this->semValue = null;
                }
                if (null === $this->semValue) {
                    $this->semValue = array();
                }
            }
        }, 134 => function ($stackPos) {
            $this->semValue = new Stmt\If_($this->semStack[$stackPos - (5 - 2)], ['stmts' => \is_array($this->semStack[$stackPos - (5 - 3)]) ? $this->semStack[$stackPos - (5 - 3)] : array($this->semStack[$stackPos - (5 - 3)]), 'elseifs' => $this->semStack[$stackPos - (5 - 4)], 'else' => $this->semStack[$stackPos - (5 - 5)]], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 135 => function ($stackPos) {
            $this->semValue = new Stmt\If_($this->semStack[$stackPos - (8 - 2)], ['stmts' => $this->semStack[$stackPos - (8 - 4)], 'elseifs' => $this->semStack[$stackPos - (8 - 5)], 'else' => $this->semStack[$stackPos - (8 - 6)]], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
        }, 136 => function ($stackPos) {
            $this->semValue = new Stmt\While_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 137 => function ($stackPos) {
            $this->semValue = new Stmt\Do_($this->semStack[$stackPos - (5 - 4)], \is_array($this->semStack[$stackPos - (5 - 2)]) ? $this->semStack[$stackPos - (5 - 2)] : array($this->semStack[$stackPos - (5 - 2)]), $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 138 => function ($stackPos) {
            $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos - (9 - 3)], 'cond' => $this->semStack[$stackPos - (9 - 5)], 'loop' => $this->semStack[$stackPos - (9 - 7)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 139 => function ($stackPos) {
            $this->semValue = new Stmt\Switch_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 140 => function ($stackPos) {
            $this->semValue = new Stmt\Break_(null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 141 => function ($stackPos) {
            $this->semValue = new Stmt\Break_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 142 => function ($stackPos) {
            $this->semValue = new Stmt\Continue_(null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 143 => function ($stackPos) {
            $this->semValue = new Stmt\Continue_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 144 => function ($stackPos) {
            $this->semValue = new Stmt\Return_(null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 145 => function ($stackPos) {
            $this->semValue = new Stmt\Return_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 146 => function ($stackPos) {
            $this->semValue = new Stmt\Global_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 147 => function ($stackPos) {
            $this->semValue = new Stmt\Static_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 148 => function ($stackPos) {
            $this->semValue = new Stmt\Echo_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 149 => function ($stackPos) {
            $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 150 => function ($stackPos) {
            $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 151 => function ($stackPos) {
            $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 152 => function ($stackPos) {
            $this->semValue = new Stmt\Unset_($this->semStack[$stackPos - (5 - 3)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 153 => function ($stackPos) {
            $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (7 - 3)], $this->semStack[$stackPos - (7 - 5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos - (7 - 5)][1], 'stmts' => $this->semStack[$stackPos - (7 - 7)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
        }, 154 => function ($stackPos) {
            $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos - (9 - 3)], $this->semStack[$stackPos - (9 - 7)][0], ['keyVar' => $this->semStack[$stackPos - (9 - 5)], 'byRef' => $this->semStack[$stackPos - (9 - 7)][1], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
        }, 155 => function ($stackPos) {
            $this->semValue = new Stmt\Declare_($this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 156 => function ($stackPos) {
            $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos - (6 - 3)], $this->semStack[$stackPos - (6 - 5)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
            $this->checkTryCatch($this->semValue);
        }, 157 => function ($stackPos) {
            $this->semValue = new Stmt\Throw_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 158 => function ($stackPos) {
            $this->semValue = new Stmt\Goto_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 159 => function ($stackPos) {
            $this->semValue = new Stmt\Label($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 160 => function ($stackPos) {
            $this->semValue = new Stmt\Expression($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 161 => function ($stackPos) {
            $this->semValue = array();
            /* means: no statement */
        }, 162 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 163 => function ($stackPos) {
            $startAttributes = $this->startAttributeStack[$stackPos - (1 - 1)];
            if (isset($startAttributes['comments'])) {
                $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes);
            } else {
                $this->semValue = null;
            }
            if ($this->semValue === null) {
                $this->semValue = array();
            }
            /* means: no statement */
        }, 164 => function ($stackPos) {
            $this->semValue = array();
        }, 165 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 166 => function ($stackPos) {
            $this->semValue = new Stmt\Catch_(array($this->semStack[$stackPos - (8 - 3)]), $this->semStack[$stackPos - (8 - 4)], $this->semStack[$stackPos - (8 - 7)], $this->startAttributeStack[$stackPos - (8 - 1)] + $this->endAttributes);
        }, 167 => function ($stackPos) {
            $this->semValue = null;
        }, 168 => function ($stackPos) {
            $this->semValue = new Stmt\Finally_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 169 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 170 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 171 => function ($stackPos) {
            $this->semValue = \false;
        }, 172 => function ($stackPos) {
            $this->semValue = \true;
        }, 173 => function ($stackPos) {
            $this->semValue = \false;
        }, 174 => function ($stackPos) {
            $this->semValue = \true;
        }, 175 => function ($stackPos) {
            $this->semValue = \false;
        }, 176 => function ($stackPos) {
            $this->semValue = \true;
        }, 177 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 178 => function ($stackPos) {
            $this->semValue = new Node\Identifier($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 179 => function ($stackPos) {
            $this->semValue = new Stmt\Function_($this->semStack[$stackPos - (10 - 3)], ['byRef' => $this->semStack[$stackPos - (10 - 2)], 'params' => $this->semStack[$stackPos - (10 - 5)], 'returnType' => $this->semStack[$stackPos - (10 - 7)], 'stmts' => $this->semStack[$stackPos - (10 - 9)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes);
        }, 180 => function ($stackPos) {
            $this->semValue = new Stmt\Class_($this->semStack[$stackPos - (7 - 2)], ['type' => $this->semStack[$stackPos - (7 - 1)], 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes);
            $this->checkClass($this->semValue, $stackPos - (7 - 2));
        }, 181 => function ($stackPos) {
            $this->semValue = new Stmt\Interface_($this->semStack[$stackPos - (6 - 2)], ['extends' => $this->semStack[$stackPos - (6 - 3)], 'stmts' => $this->semStack[$stackPos - (6 - 5)]], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
            $this->checkInterface($this->semValue, $stackPos - (6 - 2));
        }, 182 => function ($stackPos) {
            $this->semValue = new Stmt\Trait_($this->semStack[$stackPos - (5 - 2)], ['stmts' => $this->semStack[$stackPos - (5 - 4)]], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 183 => function ($stackPos) {
            $this->semValue = 0;
        }, 184 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT;
        }, 185 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_FINAL;
        }, 186 => function ($stackPos) {
            $this->semValue = null;
        }, 187 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 188 => function ($stackPos) {
            $this->semValue = array();
        }, 189 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 190 => function ($stackPos) {
            $this->semValue = array();
        }, 191 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 192 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 193 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 194 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 195 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 196 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 197 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 198 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 199 => function ($stackPos) {
            $this->semValue = null;
        }, 200 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 201 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 202 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 203 => function ($stackPos) {
            $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 204 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 205 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 3)];
        }, 206 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 207 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (5 - 3)];
        }, 208 => function ($stackPos) {
            $this->semValue = array();
        }, 209 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 210 => function ($stackPos) {
            $this->semValue = new Stmt\Case_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 211 => function ($stackPos) {
            $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 212 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 213 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 214 => function ($stackPos) {
            $this->semValue = \is_array($this->semStack[$stackPos - (1 - 1)]) ? $this->semStack[$stackPos - (1 - 1)] : array($this->semStack[$stackPos - (1 - 1)]);
        }, 215 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 2)];
        }, 216 => function ($stackPos) {
            $this->semValue = array();
        }, 217 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 218 => function ($stackPos) {
            $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (3 - 2)], \is_array($this->semStack[$stackPos - (3 - 3)]) ? $this->semStack[$stackPos - (3 - 3)] : array($this->semStack[$stackPos - (3 - 3)]), $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 219 => function ($stackPos) {
            $this->semValue = array();
        }, 220 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 221 => function ($stackPos) {
            $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 222 => function ($stackPos) {
            $this->semValue = null;
        }, 223 => function ($stackPos) {
            $this->semValue = new Stmt\Else_(\is_array($this->semStack[$stackPos - (2 - 2)]) ? $this->semStack[$stackPos - (2 - 2)] : array($this->semStack[$stackPos - (2 - 2)]), $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 224 => function ($stackPos) {
            $this->semValue = null;
        }, 225 => function ($stackPos) {
            $this->semValue = new Stmt\Else_($this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 226 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false);
        }, 227 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (2 - 2)], \true);
        }, 228 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)], \false);
        }, 229 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 230 => function ($stackPos) {
            $this->semValue = array();
        }, 231 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 232 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 233 => function ($stackPos) {
            $this->semValue = new Node\Param($this->semStack[$stackPos - (4 - 4)], null, $this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 2)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
            $this->checkParam($this->semValue);
        }, 234 => function ($stackPos) {
            $this->semValue = new Node\Param($this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 6)], $this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 3)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
            $this->checkParam($this->semValue);
        }, 235 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 236 => function ($stackPos) {
            $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 237 => function ($stackPos) {
            $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 238 => function ($stackPos) {
            $this->semValue = null;
        }, 239 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 240 => function ($stackPos) {
            $this->semValue = null;
        }, 241 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 2)];
        }, 242 => function ($stackPos) {
            $this->semValue = array();
        }, 243 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 244 => function ($stackPos) {
            $this->semValue = array(new Node\Arg($this->semStack[$stackPos - (3 - 2)], \false, \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes));
        }, 245 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 246 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 247 => function ($stackPos) {
            $this->semValue = new Node\Arg($this->semStack[$stackPos - (1 - 1)], \false, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 248 => function ($stackPos) {
            $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \true, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 249 => function ($stackPos) {
            $this->semValue = new Node\Arg($this->semStack[$stackPos - (2 - 2)], \false, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 250 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 251 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 252 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 253 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 254 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 255 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 256 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 257 => function ($stackPos) {
            $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 258 => function ($stackPos) {
            $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 259 => function ($stackPos) {
            if ($this->semStack[$stackPos - (2 - 2)] !== null) {
                $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
                $this->semValue = $this->semStack[$stackPos - (2 - 1)];
            }
        }, 260 => function ($stackPos) {
            $this->semValue = array();
        }, 261 => function ($stackPos) {
            $startAttributes = $this->lookaheadStartAttributes;
            if (isset($startAttributes['comments'])) {
                $nop = new Stmt\Nop($this->createCommentNopAttributes($startAttributes['comments']));
            } else {
                $nop = null;
            }
            if ($nop !== null) {
                $this->semStack[$stackPos - (1 - 1)][] = $nop;
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 262 => function ($stackPos) {
            $this->semValue = new Stmt\Property($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
            $this->checkProperty($this->semValue, $stackPos - (3 - 1));
        }, 263 => function ($stackPos) {
            $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos - (3 - 2)], 0, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 264 => function ($stackPos) {
            $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos - (9 - 4)], ['type' => $this->semStack[$stackPos - (9 - 1)], 'byRef' => $this->semStack[$stackPos - (9 - 3)], 'params' => $this->semStack[$stackPos - (9 - 6)], 'returnType' => $this->semStack[$stackPos - (9 - 8)], 'stmts' => $this->semStack[$stackPos - (9 - 9)]], $this->startAttributeStack[$stackPos - (9 - 1)] + $this->endAttributes);
            $this->checkClassMethod($this->semValue, $stackPos - (9 - 1));
        }, 265 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 266 => function ($stackPos) {
            $this->semValue = array();
        }, 267 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 268 => function ($stackPos) {
            $this->semValue = array();
        }, 269 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 270 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 271 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (5 - 1)][0], $this->semStack[$stackPos - (5 - 1)][1], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 4)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 272 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], $this->semStack[$stackPos - (4 - 3)], null, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 273 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 274 => function ($stackPos) {
            $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos - (4 - 1)][0], $this->semStack[$stackPos - (4 - 1)][1], null, $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 275 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)]);
        }, 276 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 277 => function ($stackPos) {
            $this->semValue = array(null, $this->semStack[$stackPos - (1 - 1)]);
        }, 278 => function ($stackPos) {
            $this->semValue = null;
        }, 279 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 280 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 281 => function ($stackPos) {
            $this->semValue = 0;
        }, 282 => function ($stackPos) {
            $this->semValue = 0;
        }, 283 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 284 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 285 => function ($stackPos) {
            $this->checkModifier($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $stackPos - (2 - 2));
            $this->semValue = $this->semStack[$stackPos - (2 - 1)] | $this->semStack[$stackPos - (2 - 2)];
        }, 286 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PUBLIC;
        }, 287 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PROTECTED;
        }, 288 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_PRIVATE;
        }, 289 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_STATIC;
        }, 290 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT;
        }, 291 => function ($stackPos) {
            $this->semValue = Stmt\Class_::MODIFIER_FINAL;
        }, 292 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 293 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 294 => function ($stackPos) {
            $this->semValue = new Node\VarLikeIdentifier(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 295 => function ($stackPos) {
            $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (1 - 1)], null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 296 => function ($stackPos) {
            $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 297 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 298 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 299 => function ($stackPos) {
            $this->semValue = array();
        }, 300 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 301 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 302 => function ($stackPos) {
            $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 303 => function ($stackPos) {
            $this->semValue = new Expr\Assign($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 304 => function ($stackPos) {
            $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 305 => function ($stackPos) {
            $this->semValue = new Expr\AssignRef($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 306 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 307 => function ($stackPos) {
            $this->semValue = new Expr\Clone_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 308 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 309 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 310 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 311 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 312 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 313 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 314 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 315 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 316 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 317 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 318 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 319 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 320 => function ($stackPos) {
            $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 321 => function ($stackPos) {
            $this->semValue = new Expr\PostInc($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 322 => function ($stackPos) {
            $this->semValue = new Expr\PreInc($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 323 => function ($stackPos) {
            $this->semValue = new Expr\PostDec($this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 324 => function ($stackPos) {
            $this->semValue = new Expr\PreDec($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 325 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 326 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 327 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 328 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 329 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 330 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 331 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 332 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 333 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 334 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 335 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 336 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 337 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 338 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 339 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 340 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 341 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 342 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 343 => function ($stackPos) {
            $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 344 => function ($stackPos) {
            $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 345 => function ($stackPos) {
            $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 346 => function ($stackPos) {
            $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 347 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 348 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 349 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 350 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 351 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 352 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 353 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 354 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 355 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 356 => function ($stackPos) {
            $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 357 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 358 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 359 => function ($stackPos) {
            $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 360 => function ($stackPos) {
            $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 361 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 362 => function ($stackPos) {
            $this->semValue = new Expr\Isset_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 363 => function ($stackPos) {
            $this->semValue = new Expr\Empty_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 364 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 365 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 366 => function ($stackPos) {
            $this->semValue = new Expr\Eval_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 367 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 368 => function ($stackPos) {
            $this->semValue = new Expr\Include_($this->semStack[$stackPos - (2 - 2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 369 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 370 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes;
            $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos - (2 - 1)]);
            $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos - (2 - 2)], $attrs);
        }, 371 => function ($stackPos) {
            $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 372 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 373 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 374 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 375 => function ($stackPos) {
            $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 376 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes;
            $attrs['kind'] = \strtolower($this->semStack[$stackPos - (2 - 1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
            $this->semValue = new Expr\Exit_($this->semStack[$stackPos - (2 - 2)], $attrs);
        }, 377 => function ($stackPos) {
            $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 378 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 379 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 380 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 381 => function ($stackPos) {
            $this->semValue = new Expr\ShellExec($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 382 => function ($stackPos) {
            $this->semValue = new Expr\Print_($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 383 => function ($stackPos) {
            $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 384 => function ($stackPos) {
            $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 385 => function ($stackPos) {
            $this->semValue = new Expr\Closure(['static' => \false, 'byRef' => $this->semStack[$stackPos - (10 - 2)], 'params' => $this->semStack[$stackPos - (10 - 4)], 'uses' => $this->semStack[$stackPos - (10 - 6)], 'returnType' => $this->semStack[$stackPos - (10 - 7)], 'stmts' => $this->semStack[$stackPos - (10 - 9)]], $this->startAttributeStack[$stackPos - (10 - 1)] + $this->endAttributes);
        }, 386 => function ($stackPos) {
            $this->semValue = new Expr\Closure(['static' => \true, 'byRef' => $this->semStack[$stackPos - (11 - 3)], 'params' => $this->semStack[$stackPos - (11 - 5)], 'uses' => $this->semStack[$stackPos - (11 - 7)], 'returnType' => $this->semStack[$stackPos - (11 - 8)], 'stmts' => $this->semStack[$stackPos - (11 - 10)]], $this->startAttributeStack[$stackPos - (11 - 1)] + $this->endAttributes);
        }, 387 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 388 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 389 => function ($stackPos) {
            $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (2 - 2)], null, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 390 => function ($stackPos) {
            $this->semValue = new Expr\Yield_($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 2)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 391 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes;
            $attrs['kind'] = Expr\Array_::KIND_LONG;
            $this->semValue = new Expr\Array_($this->semStack[$stackPos - (4 - 3)], $attrs);
        }, 392 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes;
            $attrs['kind'] = Expr\Array_::KIND_SHORT;
            $this->semValue = new Expr\Array_($this->semStack[$stackPos - (3 - 2)], $attrs);
        }, 393 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 394 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch(Scalar\String_::fromString($this->semStack[$stackPos - (4 - 1)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes), $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 395 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 396 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 397 => function ($stackPos) {
            $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos - (7 - 3)], 'implements' => $this->semStack[$stackPos - (7 - 4)], 'stmts' => $this->semStack[$stackPos - (7 - 6)]], $this->startAttributeStack[$stackPos - (7 - 1)] + $this->endAttributes), $this->semStack[$stackPos - (7 - 2)]);
            $this->checkClass($this->semValue[0], -1);
        }, 398 => function ($stackPos) {
            $this->semValue = new Expr\New_($this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 399 => function ($stackPos) {
            list($class, $ctorArgs) = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 400 => function ($stackPos) {
            $this->semValue = array();
        }, 401 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (4 - 3)];
        }, 402 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 403 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 404 => function ($stackPos) {
            $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos - (2 - 2)], $this->semStack[$stackPos - (2 - 1)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 405 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 406 => function ($stackPos) {
            $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 407 => function ($stackPos) {
            $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 408 => function ($stackPos) {
            $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 409 => function ($stackPos) {
            $this->semValue = new Expr\StaticCall($this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 4)], $this->semStack[$stackPos - (6 - 6)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 410 => function ($stackPos) {
            $this->semValue = $this->fixupPhp5StaticPropCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 411 => function ($stackPos) {
            $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 412 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 413 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 414 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 415 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 416 => function ($stackPos) {
            $this->semValue = new Name($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 417 => function ($stackPos) {
            $this->semValue = new Name\FullyQualified(\substr($this->semStack[$stackPos - (1 - 1)], 1), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 418 => function ($stackPos) {
            $this->semValue = new Name\Relative(\substr($this->semStack[$stackPos - (1 - 1)], 10), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 419 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 420 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 421 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 422 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 423 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 424 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 425 => function ($stackPos) {
            $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 426 => function ($stackPos) {
            $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 427 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 428 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 429 => function ($stackPos) {
            $this->semValue = null;
        }, 430 => function ($stackPos) {
            $this->semValue = null;
        }, 431 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 432 => function ($stackPos) {
            $this->semValue = array();
        }, 433 => function ($stackPos) {
            $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos - (1 - 1)], '`', \false), $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes));
        }, 434 => function ($stackPos) {
            foreach ($this->semStack[$stackPos - (1 - 1)] as $s) {
                if ($s instanceof Node\Scalar\EncapsedStringPart) {
                    $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', \false);
                }
            }
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 435 => function ($stackPos) {
            $this->semValue = array();
        }, 436 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 437 => function ($stackPos) {
            $this->semValue = $this->parseLNumber($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes, \true);
        }, 438 => function ($stackPos) {
            $this->semValue = Scalar\DNumber::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 439 => function ($stackPos) {
            $this->semValue = Scalar\String_::fromString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes, \false);
        }, 440 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 441 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 442 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 443 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 444 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 445 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 446 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 447 => function ($stackPos) {
            $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 448 => function ($stackPos) {
            $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \false);
        }, 449 => function ($stackPos) {
            $this->semValue = $this->parseDocString($this->semStack[$stackPos - (2 - 1)], '', $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (2 - 2)] + $this->endAttributeStack[$stackPos - (2 - 2)], \false);
        }, 450 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 451 => function ($stackPos) {
            $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 452 => function ($stackPos) {
            $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 453 => function ($stackPos) {
            $this->semValue = new Expr\Array_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 454 => function ($stackPos) {
            $this->semValue = new Expr\Array_($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 455 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 456 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 457 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 458 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 459 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 460 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 461 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 462 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 463 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 464 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 465 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 466 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 467 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 468 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 469 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 470 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 471 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 472 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 473 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 474 => function ($stackPos) {
            $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 475 => function ($stackPos) {
            $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 476 => function ($stackPos) {
            $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 477 => function ($stackPos) {
            $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 478 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 479 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 480 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 481 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 482 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 483 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 484 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 485 => function ($stackPos) {
            $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 486 => function ($stackPos) {
            $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (5 - 1)], $this->semStack[$stackPos - (5 - 3)], $this->semStack[$stackPos - (5 - 5)], $this->startAttributeStack[$stackPos - (5 - 1)] + $this->endAttributes);
        }, 487 => function ($stackPos) {
            $this->semValue = new Expr\Ternary($this->semStack[$stackPos - (4 - 1)], null, $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 488 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 489 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 490 => function ($stackPos) {
            $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 491 => function ($stackPos) {
            $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 492 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 493 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 494 => function ($stackPos) {
            $attrs = $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes;
            $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
            foreach ($this->semStack[$stackPos - (3 - 2)] as $s) {
                if ($s instanceof Node\Scalar\EncapsedStringPart) {
                    $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', \true);
                }
            }
            $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos - (3 - 2)], $attrs);
        }, 495 => function ($stackPos) {
            $this->semValue = $this->parseDocString($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 2)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes, $this->startAttributeStack[$stackPos - (3 - 3)] + $this->endAttributeStack[$stackPos - (3 - 3)], \true);
        }, 496 => function ($stackPos) {
            $this->semValue = array();
        }, 497 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 498 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 499 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos];
        }, 500 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 501 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 502 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 503 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 504 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 505 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 506 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 507 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 508 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 509 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 510 => function ($stackPos) {
            $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 511 => function ($stackPos) {
            $this->semValue = new Expr\MethodCall($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 512 => function ($stackPos) {
            $this->semValue = new Expr\FuncCall($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 513 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 514 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 515 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 516 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 517 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 518 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (2 - 2)], $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 519 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 520 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 521 => function ($stackPos) {
            $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 4)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 522 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 523 => function ($stackPos) {
            $var = \substr($this->semStack[$stackPos - (1 - 1)], 1);
            $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes) : $var;
        }, 524 => function ($stackPos) {
            $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 525 => function ($stackPos) {
            $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos - (6 - 1)], $this->semStack[$stackPos - (6 - 5)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 526 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 527 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 528 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 529 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 530 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 531 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 532 => function ($stackPos) {
            $this->semValue = null;
        }, 533 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 534 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 535 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 536 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 537 => function ($stackPos) {
            $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
            $this->errorState = 2;
        }, 538 => function ($stackPos) {
            $this->semValue = new Expr\List_($this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 539 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 540 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 541 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 542 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 543 => function ($stackPos) {
            $this->semValue = null;
        }, 544 => function ($stackPos) {
            $this->semValue = array();
        }, 545 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 546 => function ($stackPos) {
            $this->semStack[$stackPos - (3 - 1)][] = $this->semStack[$stackPos - (3 - 3)];
            $this->semValue = $this->semStack[$stackPos - (3 - 1)];
        }, 547 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 548 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (3 - 3)], $this->semStack[$stackPos - (3 - 1)], \false, $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 549 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (1 - 1)], null, \false, $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 550 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (4 - 4)], $this->semStack[$stackPos - (4 - 1)], \true, $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 551 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 552 => function ($stackPos) {
            $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos - (2 - 2)], null, \false, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes, \true, $this->startAttributeStack[$stackPos - (2 - 1)] + $this->endAttributes);
        }, 553 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 554 => function ($stackPos) {
            $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)];
            $this->semValue = $this->semStack[$stackPos - (2 - 1)];
        }, 555 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (1 - 1)]);
        }, 556 => function ($stackPos) {
            $this->semValue = array($this->semStack[$stackPos - (2 - 1)], $this->semStack[$stackPos - (2 - 2)]);
        }, 557 => function ($stackPos) {
            $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 558 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 559 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }, 560 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (4 - 1)], $this->semStack[$stackPos - (4 - 3)], $this->startAttributeStack[$stackPos - (4 - 1)] + $this->endAttributes);
        }, 561 => function ($stackPos) {
            $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos - (3 - 1)], $this->semStack[$stackPos - (3 - 3)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 562 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 563 => function ($stackPos) {
            $this->semValue = new Expr\Variable($this->semStack[$stackPos - (3 - 2)], $this->startAttributeStack[$stackPos - (3 - 1)] + $this->endAttributes);
        }, 564 => function ($stackPos) {
            $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos - (6 - 2)], $this->semStack[$stackPos - (6 - 4)], $this->startAttributeStack[$stackPos - (6 - 1)] + $this->endAttributes);
        }, 565 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (3 - 2)];
        }, 566 => function ($stackPos) {
            $this->semValue = new Scalar\String_($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 567 => function ($stackPos) {
            $this->semValue = $this->parseNumString($this->semStack[$stackPos - (1 - 1)], $this->startAttributeStack[$stackPos - (1 - 1)] + $this->endAttributes);
        }, 568 => function ($stackPos) {
            $this->semValue = $this->semStack[$stackPos - (1 - 1)];
        }];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\Parser;

use _HumbugBox1cb33d1f20f1\PhpParser\Error;
use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;
use _HumbugBox1cb33d1f20f1\PhpParser\Parser;
class Multiple implements Parser
{
    /** @var Parser[] List of parsers to try, in order of preference */
    private $parsers;
    /**
     * Create a parser which will try multiple parsers in an order of preference.
     *
     * Parsers will be invoked in the order they're provided to the constructor. If one of the
     * parsers runs without throwing, it's output is returned. Otherwise the exception that the
     * first parser generated is thrown.
     *
     * @param Parser[] $parsers
     */
    public function __construct(array $parsers)
    {
        $this->parsers = $parsers;
    }
    public function parse(string $code, ErrorHandler $errorHandler = null)
    {
        if (null === $errorHandler) {
            $errorHandler = new ErrorHandler\Throwing();
        }
        list($firstStmts, $firstError) = $this->tryParse($this->parsers[0], $errorHandler, $code);
        if ($firstError === null) {
            return $firstStmts;
        }
        for ($i = 1, $c = \count($this->parsers); $i < $c; ++$i) {
            list($stmts, $error) = $this->tryParse($this->parsers[$i], $errorHandler, $code);
            if ($error === null) {
                return $stmts;
            }
        }
        throw $firstError;
    }
    private function tryParse(Parser $parser, ErrorHandler $errorHandler, $code)
    {
        $stmts = null;
        $error = null;
        try {
            $stmts = $parser->parse($code, $errorHandler);
        } catch (Error $error) {
        }
        return [$stmts, $error];
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

class Error extends \RuntimeException
{
    protected $rawMessage;
    protected $attributes;
    /**
     * Creates an Exception signifying a parse error.
     *
     * @param string    $message    Error message
     * @param array|int $attributes Attributes of node/token where error occurred
     *                              (or start line of error -- deprecated)
     */
    public function __construct(string $message, $attributes = [])
    {
        $this->rawMessage = $message;
        if (\is_array($attributes)) {
            $this->attributes = $attributes;
        } else {
            $this->attributes = ['startLine' => $attributes];
        }
        $this->updateMessage();
    }
    /**
     * Gets the error message
     *
     * @return string Error message
     */
    public function getRawMessage() : string
    {
        return $this->rawMessage;
    }
    /**
     * Gets the line the error starts in.
     *
     * @return int Error start line
     */
    public function getStartLine() : int
    {
        return $this->attributes['startLine'] ?? -1;
    }
    /**
     * Gets the line the error ends in.
     *
     * @return int Error end line
     */
    public function getEndLine() : int
    {
        return $this->attributes['endLine'] ?? -1;
    }
    /**
     * Gets the attributes of the node/token the error occurred at.
     *
     * @return array
     */
    public function getAttributes() : array
    {
        return $this->attributes;
    }
    /**
     * Sets the attributes of the node/token the error occurred at.
     *
     * @param array $attributes
     */
    public function setAttributes(array $attributes)
    {
        $this->attributes = $attributes;
        $this->updateMessage();
    }
    /**
     * Sets the line of the PHP file the error occurred in.
     *
     * @param string $message Error message
     */
    public function setRawMessage(string $message)
    {
        $this->rawMessage = $message;
        $this->updateMessage();
    }
    /**
     * Sets the line the error starts in.
     *
     * @param int $line Error start line
     */
    public function setStartLine(int $line)
    {
        $this->attributes['startLine'] = $line;
        $this->updateMessage();
    }
    /**
     * Returns whether the error has start and end column information.
     *
     * For column information enable the startFilePos and endFilePos in the lexer options.
     *
     * @return bool
     */
    public function hasColumnInfo() : bool
    {
        return isset($this->attributes['startFilePos'], $this->attributes['endFilePos']);
    }
    /**
     * Gets the start column (1-based) into the line where the error started.
     *
     * @param string $code Source code of the file
     * @return int
     */
    public function getStartColumn(string $code) : int
    {
        if (!$this->hasColumnInfo()) {
            throw new \RuntimeException('Error does not have column information');
        }
        return $this->toColumn($code, $this->attributes['startFilePos']);
    }
    /**
     * Gets the end column (1-based) into the line where the error ended.
     *
     * @param string $code Source code of the file
     * @return int
     */
    public function getEndColumn(string $code) : int
    {
        if (!$this->hasColumnInfo()) {
            throw new \RuntimeException('Error does not have column information');
        }
        return $this->toColumn($code, $this->attributes['endFilePos']);
    }
    /**
     * Formats message including line and column information.
     *
     * @param string $code Source code associated with the error, for calculation of the columns
     *
     * @return string Formatted message
     */
    public function getMessageWithColumnInfo(string $code) : string
    {
        return \sprintf('%s from %d:%d to %d:%d', $this->getRawMessage(), $this->getStartLine(), $this->getStartColumn($code), $this->getEndLine(), $this->getEndColumn($code));
    }
    /**
     * Converts a file offset into a column.
     *
     * @param string $code Source code that $pos indexes into
     * @param int    $pos  0-based position in $code
     *
     * @return int 1-based column (relative to start of line)
     */
    private function toColumn(string $code, int $pos) : int
    {
        if ($pos > \strlen($code)) {
            throw new \RuntimeException('Invalid position information');
        }
        $lineStartPos = \strrpos($code, "\n", $pos - \strlen($code));
        if (\false === $lineStartPos) {
            $lineStartPos = -1;
        }
        return $pos - $lineStartPos;
    }
    /**
     * Updates the exception message after a change to rawMessage or rawLine.
     */
    protected function updateMessage()
    {
        $this->message = $this->rawMessage;
        if (-1 === $this->getStartLine()) {
            $this->message .= ' on unknown line';
        } else {
            $this->message .= ' on line ' . $this->getStartLine();
        }
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser;

interface Builder
{
    /**
     * Returns the built node.
     *
     * @return Node The built node
     */
    public function getNode() : Node;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor;

use function array_pop;
use function count;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
/**
 * Visitor that connects a child node to its parent node.
 *
 * On the child node, the parent node can be accessed through
 * <code>$node->getAttribute('parent')</code>.
 */
final class ParentConnectingVisitor extends NodeVisitorAbstract
{
    /**
     * @var Node[]
     */
    private $stack = [];
    public function beforeTraverse(array $nodes)
    {
        $this->stack = [];
    }
    public function enterNode(Node $node)
    {
        if (!empty($this->stack)) {
            $node->setAttribute('parent', $this->stack[count($this->stack) - 1]);
        }
        $this->stack[] = $node;
    }
    public function leaveNode(Node $node)
    {
        array_pop($this->stack);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
/**
 * Visitor cloning all nodes and linking to the original nodes using an attribute.
 *
 * This visitor is required to perform format-preserving pretty prints.
 */
class CloningVisitor extends NodeVisitorAbstract
{
    public function enterNode(Node $origNode)
    {
        $node = clone $origNode;
        $node->setAttribute('origNode', $origNode);
        return $node;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
/**
 * Visitor that connects a child node to its parent node
 * as well as its sibling nodes.
 *
 * On the child node, the parent node can be accessed through
 * <code>$node->getAttribute('parent')</code>, the previous
 * node can be accessed through <code>$node->getAttribute('previous')</code>,
 * and the next node can be accessed through <code>$node->getAttribute('next')</code>.
 */
final class NodeConnectingVisitor extends NodeVisitorAbstract
{
    /**
     * @var Node[]
     */
    private $stack = [];
    /**
     * @var ?Node
     */
    private $previous;
    public function beforeTraverse(array $nodes)
    {
        $this->stack = [];
        $this->previous = null;
    }
    public function enterNode(Node $node)
    {
        if (!empty($this->stack)) {
            $node->setAttribute('parent', $this->stack[\count($this->stack) - 1]);
        }
        if ($this->previous !== null && $this->previous->getAttribute('parent') === $node->getAttribute('parent')) {
            $node->setAttribute('previous', $this->previous);
            $this->previous->setAttribute('next', $node);
        }
        $this->stack[] = $node;
    }
    public function leaveNode(Node $node)
    {
        $this->previous = $node;
        \array_pop($this->stack);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeTraverser;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
/**
 * This visitor can be used to find the first node satisfying some criterion determined by
 * a filter callback.
 */
class FirstFindingVisitor extends NodeVisitorAbstract
{
    /** @var callable Filter callback */
    protected $filterCallback;
    /** @var null|Node Found node */
    protected $foundNode;
    public function __construct(callable $filterCallback)
    {
        $this->filterCallback = $filterCallback;
    }
    /**
     * Get found node satisfying the filter callback.
     *
     * Returns null if no node satisfies the filter callback.
     *
     * @return null|Node Found node (or null if not found)
     */
    public function getFoundNode()
    {
        return $this->foundNode;
    }
    public function beforeTraverse(array $nodes)
    {
        $this->foundNode = null;
        return null;
    }
    public function enterNode(Node $node)
    {
        $filterCallback = $this->filterCallback;
        if ($filterCallback($node)) {
            $this->foundNode = $node;
            return NodeTraverser::STOP_TRAVERSAL;
        }
        return null;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
/**
 * This visitor can be used to find and collect all nodes satisfying some criterion determined by
 * a filter callback.
 */
class FindingVisitor extends NodeVisitorAbstract
{
    /** @var callable Filter callback */
    protected $filterCallback;
    /** @var Node[] Found nodes */
    protected $foundNodes;
    public function __construct(callable $filterCallback)
    {
        $this->filterCallback = $filterCallback;
    }
    /**
     * Get found nodes satisfying the filter callback.
     *
     * Nodes are returned in pre-order.
     *
     * @return Node[] Found nodes
     */
    public function getFoundNodes() : array
    {
        return $this->foundNodes;
    }
    public function beforeTraverse(array $nodes)
    {
        $this->foundNodes = [];
        return null;
    }
    public function enterNode(Node $node)
    {
        $filterCallback = $this->filterCallback;
        if ($filterCallback($node)) {
            $this->foundNodes[] = $node;
        }
        return null;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;
use _HumbugBox1cb33d1f20f1\PhpParser\NameContext;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name\FullyQualified;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
class NameResolver extends NodeVisitorAbstract
{
    /** @var NameContext Naming context */
    protected $nameContext;
    /** @var bool Whether to preserve original names */
    protected $preserveOriginalNames;
    /** @var bool Whether to replace resolved nodes in place, or to add resolvedNode attributes */
    protected $replaceNodes;
    /**
     * Constructs a name resolution visitor.
     *
     * Options:
     *  * preserveOriginalNames (default false): An "originalName" attribute will be added to
     *    all name nodes that underwent resolution.
     *  * replaceNodes (default true): Resolved names are replaced in-place. Otherwise, a
     *    resolvedName attribute is added. (Names that cannot be statically resolved receive a
     *    namespacedName attribute, as usual.)
     *
     * @param ErrorHandler|null $errorHandler Error handler
     * @param array $options Options
     */
    public function __construct(ErrorHandler $errorHandler = null, array $options = [])
    {
        $this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing());
        $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? \false;
        $this->replaceNodes = $options['replaceNodes'] ?? \true;
    }
    /**
     * Get name resolution context.
     *
     * @return NameContext
     */
    public function getNameContext() : NameContext
    {
        return $this->nameContext;
    }
    public function beforeTraverse(array $nodes)
    {
        $this->nameContext->startNamespace();
        return null;
    }
    public function enterNode(Node $node)
    {
        if ($node instanceof Stmt\Namespace_) {
            $this->nameContext->startNamespace($node->name);
        } elseif ($node instanceof Stmt\Use_) {
            foreach ($node->uses as $use) {
                $this->addAlias($use, $node->type, null);
            }
        } elseif ($node instanceof Stmt\GroupUse) {
            foreach ($node->uses as $use) {
                $this->addAlias($use, $node->type, $node->prefix);
            }
        } elseif ($node instanceof Stmt\Class_) {
            if (null !== $node->extends) {
                $node->extends = $this->resolveClassName($node->extends);
            }
            foreach ($node->implements as &$interface) {
                $interface = $this->resolveClassName($interface);
            }
            $this->resolveAttrGroups($node);
            if (null !== $node->name) {
                $this->addNamespacedName($node);
            }
        } elseif ($node instanceof Stmt\Interface_) {
            foreach ($node->extends as &$interface) {
                $interface = $this->resolveClassName($interface);
            }
            $this->resolveAttrGroups($node);
            $this->addNamespacedName($node);
        } elseif ($node instanceof Stmt\Enum_) {
            foreach ($node->implements as &$interface) {
                $interface = $this->resolveClassName($interface);
            }
            $this->resolveAttrGroups($node);
            if (null !== $node->name) {
                $this->addNamespacedName($node);
            }
        } elseif ($node instanceof Stmt\Trait_) {
            $this->resolveAttrGroups($node);
            $this->addNamespacedName($node);
        } elseif ($node instanceof Stmt\Function_) {
            $this->resolveSignature($node);
            $this->resolveAttrGroups($node);
            $this->addNamespacedName($node);
        } elseif ($node instanceof Stmt\ClassMethod || $node instanceof Expr\Closure || $node instanceof Expr\ArrowFunction) {
            $this->resolveSignature($node);
            $this->resolveAttrGroups($node);
        } elseif ($node instanceof Stmt\Property) {
            if (null !== $node->type) {
                $node->type = $this->resolveType($node->type);
            }
            $this->resolveAttrGroups($node);
        } elseif ($node instanceof Stmt\Const_) {
            foreach ($node->consts as $const) {
                $this->addNamespacedName($const);
            }
        } else {
            if ($node instanceof Stmt\ClassConst) {
                $this->resolveAttrGroups($node);
            } else {
                if ($node instanceof Stmt\EnumCase) {
                    $this->resolveAttrGroups($node);
                } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch || $node instanceof Expr\New_ || $node instanceof Expr\Instanceof_) {
                    if ($node->class instanceof Name) {
                        $node->class = $this->resolveClassName($node->class);
                    }
                } elseif ($node instanceof Stmt\Catch_) {
                    foreach ($node->types as &$type) {
                        $type = $this->resolveClassName($type);
                    }
                } elseif ($node instanceof Expr\FuncCall) {
                    if ($node->name instanceof Name) {
                        $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION);
                    }
                } elseif ($node instanceof Expr\ConstFetch) {
                    $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT);
                } elseif ($node instanceof Stmt\TraitUse) {
                    foreach ($node->traits as &$trait) {
                        $trait = $this->resolveClassName($trait);
                    }
                    foreach ($node->adaptations as $adaptation) {
                        if (null !== $adaptation->trait) {
                            $adaptation->trait = $this->resolveClassName($adaptation->trait);
                        }
                        if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) {
                            foreach ($adaptation->insteadof as &$insteadof) {
                                $insteadof = $this->resolveClassName($insteadof);
                            }
                        }
                    }
                }
            }
        }
        return null;
    }
    private function addAlias(Stmt\UseUse $use, int $type, Name $prefix = null)
    {
        // Add prefix for group uses
        $name = $prefix ? Name::concat($prefix, $use->name) : $use->name;
        // Type is determined either by individual element or whole use declaration
        $type |= $use->type;
        $this->nameContext->addAlias($name, (string) $use->getAlias(), $type, $use->getAttributes());
    }
    /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure $node */
    private function resolveSignature($node)
    {
        foreach ($node->params as $param) {
            $param->type = $this->resolveType($param->type);
            $this->resolveAttrGroups($param);
        }
        $node->returnType = $this->resolveType($node->returnType);
    }
    private function resolveType($node)
    {
        if ($node instanceof Name) {
            return $this->resolveClassName($node);
        }
        if ($node instanceof Node\NullableType) {
            $node->type = $this->resolveType($node->type);
            return $node;
        }
        if ($node instanceof Node\UnionType || $node instanceof Node\IntersectionType) {
            foreach ($node->types as &$type) {
                $type = $this->resolveType($type);
            }
            return $node;
        }
        return $node;
    }
    /**
     * Resolve name, according to name resolver options.
     *
     * @param Name $name Function or constant name to resolve
     * @param int  $type One of Stmt\Use_::TYPE_*
     *
     * @return Name Resolved name, or original name with attribute
     */
    protected function resolveName(Name $name, int $type) : Name
    {
        if (!$this->replaceNodes) {
            $resolvedName = $this->nameContext->getResolvedName($name, $type);
            if (null !== $resolvedName) {
                $name->setAttribute('resolvedName', $resolvedName);
            } else {
                $name->setAttribute('namespacedName', FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes()));
            }
            return $name;
        }
        if ($this->preserveOriginalNames) {
            // Save the original name
            $originalName = $name;
            $name = clone $originalName;
            $name->setAttribute('originalName', $originalName);
        }
        $resolvedName = $this->nameContext->getResolvedName($name, $type);
        if (null !== $resolvedName) {
            return $resolvedName;
        }
        // unqualified names inside a namespace cannot be resolved at compile-time
        // add the namespaced version of the name as an attribute
        $name->setAttribute('namespacedName', FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes()));
        return $name;
    }
    protected function resolveClassName(Name $name)
    {
        return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL);
    }
    protected function addNamespacedName(Node $node)
    {
        $node->namespacedName = Name::concat($this->nameContext->getNamespace(), (string) $node->name);
    }
    protected function resolveAttrGroups(Node $node)
    {
        foreach ($node->attrGroups as $attrGroup) {
            foreach ($attrGroup->attrs as $attr) {
                $attr->name = $this->resolveClassName($attr->name);
            }
        }
    }
}
%pure_parser
%expect 2

%tokens

%%

start:
    top_statement_list                                      { $$ = $this->handleNamespaces($1); }
;

top_statement_list_ex:
      top_statement_list_ex top_statement                   { pushNormalizing($1, $2); }
    | /* empty */                                           { init(); }
;

top_statement_list:
      top_statement_list_ex
          { makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
            if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;

ampersand:
      T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
    | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG
;

reserved_non_modifiers:
      T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND
    | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE
    | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH
    | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
    | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT
    | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
    | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER | T_FN
    | T_MATCH | T_ENUM
;

semi_reserved:
      reserved_non_modifiers
    | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC | T_READONLY
;

identifier_maybe_reserved:
      T_STRING                                              { $$ = Node\Identifier[$1]; }
    | semi_reserved                                         { $$ = Node\Identifier[$1]; }
;

identifier_not_reserved:
      T_STRING                                              { $$ = Node\Identifier[$1]; }
;

reserved_non_modifiers_identifier:
      reserved_non_modifiers                                { $$ = Node\Identifier[$1]; }
;

namespace_declaration_name:
      T_STRING                                              { $$ = Name[$1]; }
    | semi_reserved                                         { $$ = Name[$1]; }
    | T_NAME_QUALIFIED                                      { $$ = Name[$1]; }
;

namespace_name:
      T_STRING                                              { $$ = Name[$1]; }
    | T_NAME_QUALIFIED                                      { $$ = Name[$1]; }
;

legacy_namespace_name:
      namespace_name                                        { $$ = $1; }
    | T_NAME_FULLY_QUALIFIED                                { $$ = Name[substr($1, 1)]; }
;

plain_variable:
      T_VARIABLE                                            { $$ = Expr\Variable[parseVar($1)]; }
;

semi:
      ';'                                                   { /* nothing */ }
    | error                                                 { /* nothing */ }
;

no_comma:
      /* empty */ { /* nothing */ }
    | ',' { $this->emitError(new Error('A trailing comma is not allowed here', attributes())); }
;

optional_comma:
      /* empty */
    | ','
;

attribute_decl:
      class_name                                            { $$ = Node\Attribute[$1, []]; }
    | class_name argument_list                              { $$ = Node\Attribute[$1, $2]; }
;

attribute_group:
      attribute_decl                                        { init($1); }
    | attribute_group ',' attribute_decl                    { push($1, $3); }
;

attribute:
      T_ATTRIBUTE attribute_group optional_comma ']'        { $$ = Node\AttributeGroup[$2]; }
;

attributes:
      attribute                                             { init($1); }
    | attributes attribute                                  { push($1, $2); }
;

optional_attributes:
      /* empty */                                           { $$ = []; }
    | attributes                                            { $$ = $1; }
;

top_statement:
      statement                                             { $$ = $1; }
    | function_declaration_statement                        { $$ = $1; }
    | class_declaration_statement                           { $$ = $1; }
    | T_HALT_COMPILER
          { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; }
    | T_NAMESPACE namespace_declaration_name semi
          { $$ = Stmt\Namespace_[$2, null];
            $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
            $this->checkNamespace($$); }
    | T_NAMESPACE namespace_declaration_name '{' top_statement_list '}'
          { $$ = Stmt\Namespace_[$2, $4];
            $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($$); }
    | T_NAMESPACE '{' top_statement_list '}'
          { $$ = Stmt\Namespace_[null, $3];
            $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($$); }
    | T_USE use_declarations semi                           { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; }
    | T_USE use_type use_declarations semi                  { $$ = Stmt\Use_[$3, $2]; }
    | group_use_declaration semi                            { $$ = $1; }
    | T_CONST constant_declaration_list semi                { $$ = Stmt\Const_[$2]; }
;

use_type:
      T_FUNCTION                                            { $$ = Stmt\Use_::TYPE_FUNCTION; }
    | T_CONST                                               { $$ = Stmt\Use_::TYPE_CONSTANT; }
;

group_use_declaration:
      T_USE use_type legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations '}'
          { $$ = Stmt\GroupUse[$3, $6, $2]; }
    | T_USE legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations '}'
          { $$ = Stmt\GroupUse[$2, $5, Stmt\Use_::TYPE_UNKNOWN]; }
;

unprefixed_use_declarations:
      non_empty_unprefixed_use_declarations optional_comma  { $$ = $1; }
;

non_empty_unprefixed_use_declarations:
      non_empty_unprefixed_use_declarations ',' unprefixed_use_declaration
          { push($1, $3); }
    | unprefixed_use_declaration                            { init($1); }
;

use_declarations:
      non_empty_use_declarations no_comma                   { $$ = $1; }
;

non_empty_use_declarations:
      non_empty_use_declarations ',' use_declaration        { push($1, $3); }
    | use_declaration                                       { init($1); }
;

inline_use_declarations:
      non_empty_inline_use_declarations optional_comma      { $$ = $1; }
;

non_empty_inline_use_declarations:
      non_empty_inline_use_declarations ',' inline_use_declaration
          { push($1, $3); }
    | inline_use_declaration                                { init($1); }
;

unprefixed_use_declaration:
      namespace_name
          { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); }
    | namespace_name T_AS identifier_not_reserved
          { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); }
;

use_declaration:
      legacy_namespace_name
          { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); }
    | legacy_namespace_name T_AS identifier_not_reserved
          { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); }
;

inline_use_declaration:
      unprefixed_use_declaration                            { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; }
    | use_type unprefixed_use_declaration                   { $$ = $2; $$->type = $1; }
;

constant_declaration_list:
      non_empty_constant_declaration_list no_comma          { $$ = $1; }
;

non_empty_constant_declaration_list:
      non_empty_constant_declaration_list ',' constant_declaration
          { push($1, $3); }
    | constant_declaration                                  { init($1); }
;

constant_declaration:
    identifier_not_reserved '=' expr                        { $$ = Node\Const_[$1, $3]; }
;

class_const_list:
      non_empty_class_const_list no_comma                   { $$ = $1; }
;

non_empty_class_const_list:
      non_empty_class_const_list ',' class_const            { push($1, $3); }
    | class_const                                           { init($1); }
;

class_const:
    identifier_maybe_reserved '=' expr                      { $$ = Node\Const_[$1, $3]; }
;

inner_statement_list_ex:
      inner_statement_list_ex inner_statement               { pushNormalizing($1, $2); }
    | /* empty */                                           { init(); }
;

inner_statement_list:
      inner_statement_list_ex
          { makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
            if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;

inner_statement:
      statement                                             { $$ = $1; }
    | function_declaration_statement                        { $$ = $1; }
    | class_declaration_statement                           { $$ = $1; }
    | T_HALT_COMPILER
          { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); }
;

non_empty_statement:
      '{' inner_statement_list '}'
    {
        if ($2) {
            $$ = $2; prependLeadingComments($$);
        } else {
            makeNop($$, $this->startAttributeStack[#1], $this->endAttributes);
            if (null === $$) { $$ = array(); }
        }
    }
    | T_IF '(' expr ')' statement elseif_list else_single
          { $$ = Stmt\If_[$3, ['stmts' => toArray($5), 'elseifs' => $6, 'else' => $7]]; }
    | T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
          { $$ = Stmt\If_[$3, ['stmts' => $6, 'elseifs' => $7, 'else' => $8]]; }
    | T_WHILE '(' expr ')' while_statement                  { $$ = Stmt\While_[$3, $5]; }
    | T_DO statement T_WHILE '(' expr ')' ';'               { $$ = Stmt\Do_   [$5, toArray($2)]; }
    | T_FOR '(' for_expr ';'  for_expr ';' for_expr ')' for_statement
          { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; }
    | T_SWITCH '(' expr ')' switch_case_list                { $$ = Stmt\Switch_[$3, $5]; }
    | T_BREAK optional_expr semi                            { $$ = Stmt\Break_[$2]; }
    | T_CONTINUE optional_expr semi                         { $$ = Stmt\Continue_[$2]; }
    | T_RETURN optional_expr semi                           { $$ = Stmt\Return_[$2]; }
    | T_GLOBAL global_var_list semi                         { $$ = Stmt\Global_[$2]; }
    | T_STATIC static_var_list semi                         { $$ = Stmt\Static_[$2]; }
    | T_ECHO expr_list_forbid_comma semi                    { $$ = Stmt\Echo_[$2]; }
    | T_INLINE_HTML                                         { $$ = Stmt\InlineHTML[$1]; }
    | expr semi {
        $e = $1;
        if ($e instanceof Expr\Throw_) {
            // For backwards-compatibility reasons, convert throw in statement position into
            // Stmt\Throw_ rather than Stmt\Expression(Expr\Throw_).
            $$ = Stmt\Throw_[$e->expr];
        } else {
            $$ = Stmt\Expression[$e];
        }
    }
    | T_UNSET '(' variables_list ')' semi                   { $$ = Stmt\Unset_[$3]; }
    | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
          { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; }
    | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement
          { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; }
    | T_FOREACH '(' expr error ')' foreach_statement
          { $$ = Stmt\Foreach_[$3, new Expr\Error(stackAttributes(#4)), ['stmts' => $6]]; }
    | T_DECLARE '(' declare_list ')' declare_statement      { $$ = Stmt\Declare_[$3, $5]; }
    | T_TRY '{' inner_statement_list '}' catches optional_finally
          { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); }
    | T_GOTO identifier_not_reserved semi                   { $$ = Stmt\Goto_[$2]; }
    | identifier_not_reserved ':'                           { $$ = Stmt\Label[$1]; }
    | error                                                 { $$ = array(); /* means: no statement */ }
;

statement:
      non_empty_statement                                   { $$ = $1; }
    | ';'
          { makeNop($$, $this->startAttributeStack[#1], $this->endAttributes);
            if ($$ === null) $$ = array(); /* means: no statement */ }
;

catches:
      /* empty */                                           { init(); }
    | catches catch                                         { push($1, $2); }
;

name_union:
      name                                                  { init($1); }
    | name_union '|' name                                   { push($1, $3); }
;

catch:
    T_CATCH '(' name_union optional_plain_variable ')' '{' inner_statement_list '}'
        { $$ = Stmt\Catch_[$3, $4, $7]; }
;

optional_finally:
      /* empty */                                           { $$ = null; }
    | T_FINALLY '{' inner_statement_list '}'                { $$ = Stmt\Finally_[$3]; }
;

variables_list:
      non_empty_variables_list optional_comma               { $$ = $1; }
;

non_empty_variables_list:
      variable                                              { init($1); }
    | non_empty_variables_list ',' variable                 { push($1, $3); }
;

optional_ref:
      /* empty */                                           { $$ = false; }
    | ampersand                                             { $$ = true; }
;

optional_arg_ref:
      /* empty */                                           { $$ = false; }
    | T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG                 { $$ = true; }
;

optional_ellipsis:
      /* empty */                                           { $$ = false; }
    | T_ELLIPSIS                                            { $$ = true; }
;

block_or_error:
      '{' inner_statement_list '}'                          { $$ = $2; }
    | error                                                 { $$ = []; }
;

identifier_maybe_readonly:
      identifier_not_reserved                               { $$ = $1; }
    | T_READONLY                                            { $$ = Node\Identifier[$1]; }
;

function_declaration_statement:
      T_FUNCTION optional_ref identifier_maybe_readonly '(' parameter_list ')' optional_return_type block_or_error
          { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $8, 'attrGroups' => []]]; }
    | attributes T_FUNCTION optional_ref identifier_maybe_readonly '(' parameter_list ')' optional_return_type block_or_error
          { $$ = Stmt\Function_[$4, ['byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; }
;

class_declaration_statement:
      class_entry_type identifier_not_reserved extends_from implements_list '{' class_statement_list '}'
          { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6, 'attrGroups' => []]];
            $this->checkClass($$, #2); }
    | attributes class_entry_type identifier_not_reserved extends_from implements_list '{' class_statement_list '}'
          { $$ = Stmt\Class_[$3, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]];
            $this->checkClass($$, #3); }
    | optional_attributes T_INTERFACE identifier_not_reserved interface_extends_list '{' class_statement_list '}'
          { $$ = Stmt\Interface_[$3, ['extends' => $4, 'stmts' => $6, 'attrGroups' => $1]];
            $this->checkInterface($$, #3); }
    | optional_attributes T_TRAIT identifier_not_reserved '{' class_statement_list '}'
          { $$ = Stmt\Trait_[$3, ['stmts' => $5, 'attrGroups' => $1]]; }
    | optional_attributes T_ENUM identifier_not_reserved enum_scalar_type implements_list '{' class_statement_list '}'
          { $$ = Stmt\Enum_[$3, ['scalarType' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]];
            $this->checkEnum($$, #3); }
;

enum_scalar_type:
      /* empty */                                           { $$ = null; }
    | ':' type                                              { $$ = $2; }

enum_case_expr:
      /* empty */                                           { $$ = null; }
    | '=' expr                                              { $$ = $2; }
;

class_entry_type:
      T_CLASS                                               { $$ = 0; }
    | class_modifiers T_CLASS                               { $$ = $1; }
;

class_modifiers:
      class_modifier                                        { $$ = $1; }
    | class_modifiers class_modifier                        { $this->checkClassModifier($1, $2, #2); $$ = $1 | $2; }
;

class_modifier:
      T_ABSTRACT                                            { $$ = Stmt\Class_::MODIFIER_ABSTRACT; }
    | T_FINAL                                               { $$ = Stmt\Class_::MODIFIER_FINAL; }
    | T_READONLY                                            { $$ = Stmt\Class_::MODIFIER_READONLY; }
;

extends_from:
      /* empty */                                           { $$ = null; }
    | T_EXTENDS class_name                                  { $$ = $2; }
;

interface_extends_list:
      /* empty */                                           { $$ = array(); }
    | T_EXTENDS class_name_list                             { $$ = $2; }
;

implements_list:
      /* empty */                                           { $$ = array(); }
    | T_IMPLEMENTS class_name_list                          { $$ = $2; }
;

class_name_list:
      non_empty_class_name_list no_comma                    { $$ = $1; }
;

non_empty_class_name_list:
      class_name                                            { init($1); }
    | non_empty_class_name_list ',' class_name              { push($1, $3); }
;

for_statement:
      statement                                             { $$ = toArray($1); }
    | ':' inner_statement_list T_ENDFOR ';'                 { $$ = $2; }
;

foreach_statement:
      statement                                             { $$ = toArray($1); }
    | ':' inner_statement_list T_ENDFOREACH ';'             { $$ = $2; }
;

declare_statement:
      non_empty_statement                                   { $$ = toArray($1); }
    | ';'                                                   { $$ = null; }
    | ':' inner_statement_list T_ENDDECLARE ';'             { $$ = $2; }
;

declare_list:
      non_empty_declare_list no_comma                       { $$ = $1; }
;

non_empty_declare_list:
      declare_list_element                                  { init($1); }
    | non_empty_declare_list ',' declare_list_element       { push($1, $3); }
;

declare_list_element:
      identifier_not_reserved '=' expr                      { $$ = Stmt\DeclareDeclare[$1, $3]; }
;

switch_case_list:
      '{' case_list '}'                                     { $$ = $2; }
    | '{' ';' case_list '}'                                 { $$ = $3; }
    | ':' case_list T_ENDSWITCH ';'                         { $$ = $2; }
    | ':' ';' case_list T_ENDSWITCH ';'                     { $$ = $3; }
;

case_list:
      /* empty */                                           { init(); }
    | case_list case                                        { push($1, $2); }
;

case:
      T_CASE expr case_separator inner_statement_list_ex    { $$ = Stmt\Case_[$2, $4]; }
    | T_DEFAULT case_separator inner_statement_list_ex      { $$ = Stmt\Case_[null, $3]; }
;

case_separator:
      ':'
    | ';'
;

match:
      T_MATCH '(' expr ')' '{' match_arm_list '}'           { $$ = Expr\Match_[$3, $6]; }
;

match_arm_list:
      /* empty */                                           { $$ = []; }
    | non_empty_match_arm_list optional_comma               { $$ = $1; }
;

non_empty_match_arm_list:
      match_arm                                             { init($1); }
    | non_empty_match_arm_list ',' match_arm                { push($1, $3); }
;

match_arm:
      expr_list_allow_comma T_DOUBLE_ARROW expr             { $$ = Node\MatchArm[$1, $3]; }
    | T_DEFAULT optional_comma T_DOUBLE_ARROW expr          { $$ = Node\MatchArm[null, $4]; }
;

while_statement:
      statement                                             { $$ = toArray($1); }
    | ':' inner_statement_list T_ENDWHILE ';'               { $$ = $2; }
;

elseif_list:
      /* empty */                                           { init(); }
    | elseif_list elseif                                    { push($1, $2); }
;

elseif:
      T_ELSEIF '(' expr ')' statement                       { $$ = Stmt\ElseIf_[$3, toArray($5)]; }
;

new_elseif_list:
      /* empty */                                           { init(); }
    | new_elseif_list new_elseif                            { push($1, $2); }
;

new_elseif:
     T_ELSEIF '(' expr ')' ':' inner_statement_list         { $$ = Stmt\ElseIf_[$3, $6]; }
;

else_single:
      /* empty */                                           { $$ = null; }
    | T_ELSE statement                                      { $$ = Stmt\Else_[toArray($2)]; }
;

new_else_single:
      /* empty */                                           { $$ = null; }
    | T_ELSE ':' inner_statement_list                       { $$ = Stmt\Else_[$3]; }
;

foreach_variable:
      variable                                              { $$ = array($1, false); }
    | ampersand variable                                    { $$ = array($2, true); }
    | list_expr                                             { $$ = array($1, false); }
    | array_short_syntax                                    { $$ = array($1, false); }
;

parameter_list:
      non_empty_parameter_list optional_comma               { $$ = $1; }
    | /* empty */                                           { $$ = array(); }
;

non_empty_parameter_list:
      parameter                                             { init($1); }
    | non_empty_parameter_list ',' parameter                { push($1, $3); }
;

optional_property_modifiers:
      /* empty */               { $$ = 0; }
    | optional_property_modifiers property_modifier
          { $this->checkModifier($1, $2, #2); $$ = $1 | $2; }
;

property_modifier:
      T_PUBLIC                  { $$ = Stmt\Class_::MODIFIER_PUBLIC; }
    | T_PROTECTED               { $$ = Stmt\Class_::MODIFIER_PROTECTED; }
    | T_PRIVATE                 { $$ = Stmt\Class_::MODIFIER_PRIVATE; }
    | T_READONLY                { $$ = Stmt\Class_::MODIFIER_READONLY; }
;

parameter:
      optional_attributes optional_property_modifiers optional_type_without_static
      optional_arg_ref optional_ellipsis plain_variable
          { $$ = new Node\Param($6, null, $3, $4, $5, attributes(), $2, $1);
            $this->checkParam($$); }
    | optional_attributes optional_property_modifiers optional_type_without_static
      optional_arg_ref optional_ellipsis plain_variable '=' expr
          { $$ = new Node\Param($6, $8, $3, $4, $5, attributes(), $2, $1);
            $this->checkParam($$); }
    | optional_attributes optional_property_modifiers optional_type_without_static
      optional_arg_ref optional_ellipsis error
          { $$ = new Node\Param(Expr\Error[], null, $3, $4, $5, attributes(), $2, $1); }
;

type_expr:
      type                                                  { $$ = $1; }
    | '?' type                                              { $$ = Node\NullableType[$2]; }
    | union_type                                            { $$ = Node\UnionType[$1]; }
    | intersection_type                                     { $$ = $1; }
;

type:
      type_without_static                                   { $$ = $1; }
    | T_STATIC                                              { $$ = Node\Name['static']; }
;

type_without_static:
      name                                                  { $$ = $this->handleBuiltinTypes($1); }
    | T_ARRAY                                               { $$ = Node\Identifier['array']; }
    | T_CALLABLE                                            { $$ = Node\Identifier['callable']; }
;

union_type_element:
                type { $$ = $1; }
        |        '(' intersection_type ')' { $$ = $2; }
;

union_type:
      union_type_element '|' union_type_element             { init($1, $3); }
    | union_type '|' union_type_element                     { push($1, $3); }
;

union_type_without_static_element:
                type_without_static { $$ = $1; }
        |        '(' intersection_type_without_static ')' { $$ = $2; }
;

union_type_without_static:
      union_type_without_static_element '|' union_type_without_static_element   { init($1, $3); }
    | union_type_without_static '|' union_type_without_static_element           { push($1, $3); }
;

intersection_type_list:
      type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type   { init($1, $3); }
    | intersection_type_list T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type
          { push($1, $3); }
;

intersection_type:
      intersection_type_list { $$ = Node\IntersectionType[$1]; }
;

intersection_type_without_static_list:
      type_without_static T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static
          { init($1, $3); }
    | intersection_type_without_static_list T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static
          { push($1, $3); }
;

intersection_type_without_static:
      intersection_type_without_static_list { $$ = Node\IntersectionType[$1]; }
;

type_expr_without_static:
      type_without_static                                   { $$ = $1; }
    | '?' type_without_static                               { $$ = Node\NullableType[$2]; }
    | union_type_without_static                             { $$ = Node\UnionType[$1]; }
    | intersection_type_without_static                      { $$ = $1; }
;

optional_type_without_static:
      /* empty */                                           { $$ = null; }
    | type_expr_without_static                              { $$ = $1; }
;

optional_return_type:
      /* empty */                                           { $$ = null; }
    | ':' type_expr                                         { $$ = $2; }
    | ':' error                                             { $$ = null; }
;

argument_list:
      '(' ')'                                               { $$ = array(); }
    | '(' non_empty_argument_list optional_comma ')'        { $$ = $2; }
    | '(' variadic_placeholder ')'                          { init($2); }
;

variadic_placeholder:
      T_ELLIPSIS                                            { $$ = Node\VariadicPlaceholder[]; }
;

non_empty_argument_list:
      argument                                              { init($1); }
    | non_empty_argument_list ',' argument                  { push($1, $3); }
;

argument:
      expr                                                  { $$ = Node\Arg[$1, false, false]; }
    | ampersand variable                                    { $$ = Node\Arg[$2, true, false]; }
    | T_ELLIPSIS expr                                       { $$ = Node\Arg[$2, false, true]; }
    | identifier_maybe_reserved ':' expr
          { $$ = new Node\Arg($3, false, false, attributes(), $1); }
;

global_var_list:
      non_empty_global_var_list no_comma                    { $$ = $1; }
;

non_empty_global_var_list:
      non_empty_global_var_list ',' global_var              { push($1, $3); }
    | global_var                                            { init($1); }
;

global_var:
      simple_variable                                       { $$ = $1; }
;

static_var_list:
      non_empty_static_var_list no_comma                    { $$ = $1; }
;

non_empty_static_var_list:
      non_empty_static_var_list ',' static_var              { push($1, $3); }
    | static_var                                            { init($1); }
;

static_var:
      plain_variable                                        { $$ = Stmt\StaticVar[$1, null]; }
    | plain_variable '=' expr                               { $$ = Stmt\StaticVar[$1, $3]; }
;

class_statement_list_ex:
      class_statement_list_ex class_statement               { if ($2 !== null) { push($1, $2); } }
    | /* empty */                                           { init(); }
;

class_statement_list:
      class_statement_list_ex
          { makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
            if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;

class_statement:
      optional_attributes variable_modifiers optional_type_without_static property_declaration_list semi
          { $$ = new Stmt\Property($2, $4, attributes(), $3, $1);
            $this->checkProperty($$, #2); }
    | optional_attributes method_modifiers T_CONST class_const_list semi
          { $$ = new Stmt\ClassConst($4, $2, attributes(), $1);
            $this->checkClassConst($$, #2); }
    | optional_attributes method_modifiers T_FUNCTION optional_ref identifier_maybe_reserved '(' parameter_list ')'
      optional_return_type method_body
          { $$ = Stmt\ClassMethod[$5, ['type' => $2, 'byRef' => $4, 'params' => $7, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]];
            $this->checkClassMethod($$, #2); }
    | T_USE class_name_list trait_adaptations               { $$ = Stmt\TraitUse[$2, $3]; }
    | optional_attributes T_CASE identifier_maybe_reserved enum_case_expr semi
         { $$ = Stmt\EnumCase[$3, $4, $1]; }
    | error                                                 { $$ = null; /* will be skipped */ }
;

trait_adaptations:
      ';'                                                   { $$ = array(); }
    | '{' trait_adaptation_list '}'                         { $$ = $2; }
;

trait_adaptation_list:
      /* empty */                                           { init(); }
    | trait_adaptation_list trait_adaptation                { push($1, $2); }
;

trait_adaptation:
      trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';'
          { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; }
    | trait_method_reference T_AS member_modifier identifier_maybe_reserved ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; }
    | trait_method_reference T_AS member_modifier ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; }
    | trait_method_reference T_AS identifier_not_reserved ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
    | trait_method_reference T_AS reserved_non_modifiers_identifier ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
;

trait_method_reference_fully_qualified:
      name T_PAAMAYIM_NEKUDOTAYIM identifier_maybe_reserved { $$ = array($1, $3); }
;
trait_method_reference:
      trait_method_reference_fully_qualified                { $$ = $1; }
    | identifier_maybe_reserved                             { $$ = array(null, $1); }
;

method_body:
      ';' /* abstract method */                             { $$ = null; }
    | block_or_error                                        { $$ = $1; }
;

variable_modifiers:
      non_empty_member_modifiers                            { $$ = $1; }
    | T_VAR                                                 { $$ = 0; }
;

method_modifiers:
      /* empty */                                           { $$ = 0; }
    | non_empty_member_modifiers                            { $$ = $1; }
;

non_empty_member_modifiers:
      member_modifier                                       { $$ = $1; }
    | non_empty_member_modifiers member_modifier            { $this->checkModifier($1, $2, #2); $$ = $1 | $2; }
;

member_modifier:
      T_PUBLIC                                              { $$ = Stmt\Class_::MODIFIER_PUBLIC; }
    | T_PROTECTED                                           { $$ = Stmt\Class_::MODIFIER_PROTECTED; }
    | T_PRIVATE                                             { $$ = Stmt\Class_::MODIFIER_PRIVATE; }
    | T_STATIC                                              { $$ = Stmt\Class_::MODIFIER_STATIC; }
    | T_ABSTRACT                                            { $$ = Stmt\Class_::MODIFIER_ABSTRACT; }
    | T_FINAL                                               { $$ = Stmt\Class_::MODIFIER_FINAL; }
    | T_READONLY                                            { $$ = Stmt\Class_::MODIFIER_READONLY; }
;

property_declaration_list:
      non_empty_property_declaration_list no_comma          { $$ = $1; }
;

non_empty_property_declaration_list:
      property_declaration                                  { init($1); }
    | non_empty_property_declaration_list ',' property_declaration
          { push($1, $3); }
;

property_decl_name:
      T_VARIABLE                                            { $$ = Node\VarLikeIdentifier[parseVar($1)]; }
;

property_declaration:
      property_decl_name                                    { $$ = Stmt\PropertyProperty[$1, null]; }
    | property_decl_name '=' expr                           { $$ = Stmt\PropertyProperty[$1, $3]; }
;

expr_list_forbid_comma:
      non_empty_expr_list no_comma                          { $$ = $1; }
;

expr_list_allow_comma:
      non_empty_expr_list optional_comma                    { $$ = $1; }
;

non_empty_expr_list:
      non_empty_expr_list ',' expr                          { push($1, $3); }
    | expr                                                  { init($1); }
;

for_expr:
      /* empty */                                           { $$ = array(); }
    | expr_list_forbid_comma                                { $$ = $1; }
;

expr:
      variable                                              { $$ = $1; }
    | list_expr '=' expr                                    { $$ = Expr\Assign[$1, $3]; }
    | array_short_syntax '=' expr                           { $$ = Expr\Assign[$1, $3]; }
    | variable '=' expr                                     { $$ = Expr\Assign[$1, $3]; }
    | variable '=' ampersand variable                       { $$ = Expr\AssignRef[$1, $4]; }
    | new_expr                                              { $$ = $1; }
    | match                                                 { $$ = $1; }
    | T_CLONE expr                                          { $$ = Expr\Clone_[$2]; }
    | variable T_PLUS_EQUAL expr                            { $$ = Expr\AssignOp\Plus      [$1, $3]; }
    | variable T_MINUS_EQUAL expr                           { $$ = Expr\AssignOp\Minus     [$1, $3]; }
    | variable T_MUL_EQUAL expr                             { $$ = Expr\AssignOp\Mul       [$1, $3]; }
    | variable T_DIV_EQUAL expr                             { $$ = Expr\AssignOp\Div       [$1, $3]; }
    | variable T_CONCAT_EQUAL expr                          { $$ = Expr\AssignOp\Concat    [$1, $3]; }
    | variable T_MOD_EQUAL expr                             { $$ = Expr\AssignOp\Mod       [$1, $3]; }
    | variable T_AND_EQUAL expr                             { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; }
    | variable T_OR_EQUAL expr                              { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; }
    | variable T_XOR_EQUAL expr                             { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; }
    | variable T_SL_EQUAL expr                              { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; }
    | variable T_SR_EQUAL expr                              { $$ = Expr\AssignOp\ShiftRight[$1, $3]; }
    | variable T_POW_EQUAL expr                             { $$ = Expr\AssignOp\Pow       [$1, $3]; }
    | variable T_COALESCE_EQUAL expr                        { $$ = Expr\AssignOp\Coalesce  [$1, $3]; }
    | variable T_INC                                        { $$ = Expr\PostInc[$1]; }
    | T_INC variable                                        { $$ = Expr\PreInc [$2]; }
    | variable T_DEC                                        { $$ = Expr\PostDec[$1]; }
    | T_DEC variable                                        { $$ = Expr\PreDec [$2]; }
    | expr T_BOOLEAN_OR expr                                { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; }
    | expr T_BOOLEAN_AND expr                               { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; }
    | expr T_LOGICAL_OR expr                                { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; }
    | expr T_LOGICAL_AND expr                               { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; }
    | expr T_LOGICAL_XOR expr                               { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; }
    | expr '|' expr                                         { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; }
    | expr T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr   { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; }
    | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG expr       { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; }
    | expr '^' expr                                         { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; }
    | expr '.' expr                                         { $$ = Expr\BinaryOp\Concat    [$1, $3]; }
    | expr '+' expr                                         { $$ = Expr\BinaryOp\Plus      [$1, $3]; }
    | expr '-' expr                                         { $$ = Expr\BinaryOp\Minus     [$1, $3]; }
    | expr '*' expr                                         { $$ = Expr\BinaryOp\Mul       [$1, $3]; }
    | expr '/' expr                                         { $$ = Expr\BinaryOp\Div       [$1, $3]; }
    | expr '%' expr                                         { $$ = Expr\BinaryOp\Mod       [$1, $3]; }
    | expr T_SL expr                                        { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; }
    | expr T_SR expr                                        { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; }
    | expr T_POW expr                                       { $$ = Expr\BinaryOp\Pow       [$1, $3]; }
    | '+' expr %prec T_INC                                  { $$ = Expr\UnaryPlus [$2]; }
    | '-' expr %prec T_INC                                  { $$ = Expr\UnaryMinus[$2]; }
    | '!' expr                                              { $$ = Expr\BooleanNot[$2]; }
    | '~' expr                                              { $$ = Expr\BitwiseNot[$2]; }
    | expr T_IS_IDENTICAL expr                              { $$ = Expr\BinaryOp\Identical     [$1, $3]; }
    | expr T_IS_NOT_IDENTICAL expr                          { $$ = Expr\BinaryOp\NotIdentical  [$1, $3]; }
    | expr T_IS_EQUAL expr                                  { $$ = Expr\BinaryOp\Equal         [$1, $3]; }
    | expr T_IS_NOT_EQUAL expr                              { $$ = Expr\BinaryOp\NotEqual      [$1, $3]; }
    | expr T_SPACESHIP expr                                 { $$ = Expr\BinaryOp\Spaceship     [$1, $3]; }
    | expr '<' expr                                         { $$ = Expr\BinaryOp\Smaller       [$1, $3]; }
    | expr T_IS_SMALLER_OR_EQUAL expr                       { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; }
    | expr '>' expr                                         { $$ = Expr\BinaryOp\Greater       [$1, $3]; }
    | expr T_IS_GREATER_OR_EQUAL expr                       { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; }
    | expr T_INSTANCEOF class_name_reference                { $$ = Expr\Instanceof_[$1, $3]; }
    | '(' expr ')'                                          { $$ = $2; }
    | expr '?' expr ':' expr                                { $$ = Expr\Ternary[$1, $3,   $5]; }
    | expr '?' ':' expr                                     { $$ = Expr\Ternary[$1, null, $4]; }
    | expr T_COALESCE expr                                  { $$ = Expr\BinaryOp\Coalesce[$1, $3]; }
    | T_ISSET '(' expr_list_allow_comma ')'                 { $$ = Expr\Isset_[$3]; }
    | T_EMPTY '(' expr ')'                                  { $$ = Expr\Empty_[$3]; }
    | T_INCLUDE expr                                        { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; }
    | T_INCLUDE_ONCE expr                                   { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; }
    | T_EVAL '(' expr ')'                                   { $$ = Expr\Eval_[$3]; }
    | T_REQUIRE expr                                        { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; }
    | T_REQUIRE_ONCE expr                                   { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; }
    | T_INT_CAST expr                                       { $$ = Expr\Cast\Int_    [$2]; }
    | T_DOUBLE_CAST expr
          { $attrs = attributes();
            $attrs['kind'] = $this->getFloatCastKind($1);
            $$ = new Expr\Cast\Double($2, $attrs); }
    | T_STRING_CAST expr                                    { $$ = Expr\Cast\String_ [$2]; }
    | T_ARRAY_CAST expr                                     { $$ = Expr\Cast\Array_  [$2]; }
    | T_OBJECT_CAST expr                                    { $$ = Expr\Cast\Object_ [$2]; }
    | T_BOOL_CAST expr                                      { $$ = Expr\Cast\Bool_   [$2]; }
    | T_UNSET_CAST expr                                     { $$ = Expr\Cast\Unset_  [$2]; }
    | T_EXIT exit_expr
          { $attrs = attributes();
            $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
            $$ = new Expr\Exit_($2, $attrs); }
    | '@' expr                                              { $$ = Expr\ErrorSuppress[$2]; }
    | scalar                                                { $$ = $1; }
    | '`' backticks_expr '`'                                { $$ = Expr\ShellExec[$2]; }
    | T_PRINT expr                                          { $$ = Expr\Print_[$2]; }
    | T_YIELD                                               { $$ = Expr\Yield_[null, null]; }
    | T_YIELD expr                                          { $$ = Expr\Yield_[$2, null]; }
    | T_YIELD expr T_DOUBLE_ARROW expr                      { $$ = Expr\Yield_[$4, $2]; }
    | T_YIELD_FROM expr                                     { $$ = Expr\YieldFrom[$2]; }
    | T_THROW expr                                          { $$ = Expr\Throw_[$2]; }

    | T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW
          { $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $2, 'params' => $4, 'returnType' => $6, 'expr' => $8, 'attrGroups' => []]]; }
    | T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW
          { $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => []]]; }
    | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
          { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $8, 'attrGroups' => []]]; }
    | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type       block_or_error
          { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => []]]; }

    | attributes T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW
          { $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => $1]]; }
    | attributes T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW
          { $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $4, 'params' => $6, 'returnType' => $8, 'expr' => $10, 'attrGroups' => $1]]; }
    | attributes T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
          { $$ = Expr\Closure[['static' => false, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; }
    | attributes T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type       block_or_error
          { $$ = Expr\Closure[['static' => true, 'byRef' => $4, 'params' => $6, 'uses' => $8, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]]; }
;

anonymous_class:
      optional_attributes T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
          { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3);
            $this->checkClass($$[0], -1); }
;

new_expr:
      T_NEW class_name_reference ctor_arguments             { $$ = Expr\New_[$2, $3]; }
    | T_NEW anonymous_class
          { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; }
;

lexical_vars:
      /* empty */                                           { $$ = array(); }
    | T_USE '(' lexical_var_list ')'                        { $$ = $3; }
;

lexical_var_list:
      non_empty_lexical_var_list optional_comma             { $$ = $1; }
;

non_empty_lexical_var_list:
      lexical_var                                           { init($1); }
    | non_empty_lexical_var_list ',' lexical_var            { push($1, $3); }
;

lexical_var:
      optional_ref plain_variable                           { $$ = Expr\ClosureUse[$2, $1]; }
;

name_readonly:
      T_READONLY                                            { $$ = Name[$1]; }
;

function_call:
      name argument_list                                    { $$ = Expr\FuncCall[$1, $2]; }
    | name_readonly argument_list                           { $$ = Expr\FuncCall[$1, $2]; }
    | callable_expr argument_list                           { $$ = Expr\FuncCall[$1, $2]; }
    | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
          { $$ = Expr\StaticCall[$1, $3, $4]; }
;

class_name:
      T_STATIC                                              { $$ = Name[$1]; }
    | name                                                  { $$ = $1; }
;

name:
      T_STRING                                              { $$ = Name[$1]; }
    | T_NAME_QUALIFIED                                      { $$ = Name[$1]; }
    | T_NAME_FULLY_QUALIFIED                                { $$ = Name\FullyQualified[substr($1, 1)]; }
    | T_NAME_RELATIVE                                       { $$ = Name\Relative[substr($1, 10)]; }
;

class_name_reference:
      class_name                                            { $$ = $1; }
    | new_variable                                          { $$ = $1; }
    | '(' expr ')'                                          { $$ = $2; }
    | error                                                 { $$ = Expr\Error[]; $this->errorState = 2; }
;

class_name_or_var:
      class_name                                            { $$ = $1; }
    | fully_dereferencable                                  { $$ = $1; }
;

exit_expr:
      /* empty */                                           { $$ = null; }
    | '(' optional_expr ')'                                 { $$ = $2; }
;

backticks_expr:
      /* empty */                                           { $$ = array(); }
    | T_ENCAPSED_AND_WHITESPACE
          { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`')]); }
    | encaps_list                                           { parseEncapsed($1, '`', true); $$ = $1; }
;

ctor_arguments:
      /* empty */                                           { $$ = array(); }
    | argument_list                                         { $$ = $1; }
;

constant:
      name                                                  { $$ = Expr\ConstFetch[$1]; }
    | T_LINE                                                { $$ = Scalar\MagicConst\Line[]; }
    | T_FILE                                                { $$ = Scalar\MagicConst\File[]; }
    | T_DIR                                                 { $$ = Scalar\MagicConst\Dir[]; }
    | T_CLASS_C                                             { $$ = Scalar\MagicConst\Class_[]; }
    | T_TRAIT_C                                             { $$ = Scalar\MagicConst\Trait_[]; }
    | T_METHOD_C                                            { $$ = Scalar\MagicConst\Method[]; }
    | T_FUNC_C                                              { $$ = Scalar\MagicConst\Function_[]; }
    | T_NS_C                                                { $$ = Scalar\MagicConst\Namespace_[]; }
;

class_constant:
      class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_maybe_reserved
          { $$ = Expr\ClassConstFetch[$1, $3]; }
    /* We interpret an isolated FOO:: as an unfinished class constant fetch. It could also be
       an unfinished static property fetch or unfinished scoped call. */
    | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error
          { $$ = Expr\ClassConstFetch[$1, new Expr\Error(stackAttributes(#3))]; $this->errorState = 2; }
;

array_short_syntax:
      '[' array_pair_list ']'
          { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT;
            $$ = new Expr\Array_($2, $attrs); }
;

dereferencable_scalar:
      T_ARRAY '(' array_pair_list ')'
          { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG;
            $$ = new Expr\Array_($3, $attrs); }
    | array_short_syntax                                    { $$ = $1; }
    | T_CONSTANT_ENCAPSED_STRING                            { $$ = Scalar\String_::fromString($1, attributes()); }
    | '"' encaps_list '"'
          { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
            parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); }
;

scalar:
      T_LNUMBER                                             { $$ = $this->parseLNumber($1, attributes()); }
    | T_DNUMBER                                             { $$ = Scalar\DNumber::fromString($1, attributes()); }
    | dereferencable_scalar                                 { $$ = $1; }
    | constant                                              { $$ = $1; }
    | class_constant                                        { $$ = $1; }
    | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
          { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); }
    | T_START_HEREDOC T_END_HEREDOC
          { $$ = $this->parseDocString($1, '', $2, attributes(), stackAttributes(#2), true); }
    | T_START_HEREDOC encaps_list T_END_HEREDOC
          { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); }
;

optional_expr:
      /* empty */                                           { $$ = null; }
    | expr                                                  { $$ = $1; }
;

fully_dereferencable:
      variable                                              { $$ = $1; }
    | '(' expr ')'                                          { $$ = $2; }
    | dereferencable_scalar                                 { $$ = $1; }
    | class_constant                                        { $$ = $1; }
;

array_object_dereferencable:
      fully_dereferencable                                  { $$ = $1; }
    | constant                                              { $$ = $1; }
;

callable_expr:
      callable_variable                                     { $$ = $1; }
    | '(' expr ')'                                          { $$ = $2; }
    | dereferencable_scalar                                 { $$ = $1; }
;

callable_variable:
      simple_variable                                       { $$ = $1; }
    | array_object_dereferencable '[' optional_expr ']'     { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | array_object_dereferencable '{' expr '}'              { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | function_call                                         { $$ = $1; }
    | array_object_dereferencable T_OBJECT_OPERATOR property_name argument_list
          { $$ = Expr\MethodCall[$1, $3, $4]; }
    | array_object_dereferencable T_NULLSAFE_OBJECT_OPERATOR property_name argument_list
          { $$ = Expr\NullsafeMethodCall[$1, $3, $4]; }
;

optional_plain_variable:
      /* empty */                                           { $$ = null; }
    | plain_variable                                        { $$ = $1; }
;

variable:
      callable_variable                                     { $$ = $1; }
    | static_member                                         { $$ = $1; }
    | array_object_dereferencable T_OBJECT_OPERATOR property_name
          { $$ = Expr\PropertyFetch[$1, $3]; }
    | array_object_dereferencable T_NULLSAFE_OBJECT_OPERATOR property_name
          { $$ = Expr\NullsafePropertyFetch[$1, $3]; }
;

simple_variable:
      plain_variable                                        { $$ = $1; }
    | '$' '{' expr '}'                                      { $$ = Expr\Variable[$3]; }
    | '$' simple_variable                                   { $$ = Expr\Variable[$2]; }
    | '$' error                                             { $$ = Expr\Variable[Expr\Error[]]; $this->errorState = 2; }
;

static_member_prop_name:
      simple_variable
          { $var = $1->name; $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; }
;

static_member:
      class_name_or_var T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name
          { $$ = Expr\StaticPropertyFetch[$1, $3]; }
;

new_variable:
      simple_variable                                       { $$ = $1; }
    | new_variable '[' optional_expr ']'                    { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | new_variable '{' expr '}'                             { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | new_variable T_OBJECT_OPERATOR property_name          { $$ = Expr\PropertyFetch[$1, $3]; }
    | new_variable T_NULLSAFE_OBJECT_OPERATOR property_name { $$ = Expr\NullsafePropertyFetch[$1, $3]; }
    | class_name T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name
          { $$ = Expr\StaticPropertyFetch[$1, $3]; }
    | new_variable T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name
          { $$ = Expr\StaticPropertyFetch[$1, $3]; }
;

member_name:
      identifier_maybe_reserved                             { $$ = $1; }
    | '{' expr '}'                                          { $$ = $2; }
    | simple_variable                                       { $$ = $1; }
;

property_name:
      identifier_not_reserved                               { $$ = $1; }
    | '{' expr '}'                                          { $$ = $2; }
    | simple_variable                                       { $$ = $1; }
    | error                                                 { $$ = Expr\Error[]; $this->errorState = 2; }
;

list_expr:
      T_LIST '(' inner_array_pair_list ')'                  { $$ = Expr\List_[$3]; }
;

array_pair_list:
      inner_array_pair_list
          { $$ = $1; $end = count($$)-1; if ($$[$end] === null) array_pop($$); }
;

comma_or_error:
      ','
    | error
          { /* do nothing -- prevent default action of $$=$1. See #551. */ }
;

inner_array_pair_list:
      inner_array_pair_list comma_or_error array_pair       { push($1, $3); }
    | array_pair                                            { init($1); }
;

array_pair:
      expr                                                  { $$ = Expr\ArrayItem[$1, null, false]; }
    | ampersand variable                                    { $$ = Expr\ArrayItem[$2, null, true]; }
    | list_expr                                             { $$ = Expr\ArrayItem[$1, null, false]; }
    | expr T_DOUBLE_ARROW expr                              { $$ = Expr\ArrayItem[$3, $1,   false]; }
    | expr T_DOUBLE_ARROW ampersand variable                { $$ = Expr\ArrayItem[$4, $1,   true]; }
    | expr T_DOUBLE_ARROW list_expr                         { $$ = Expr\ArrayItem[$3, $1,   false]; }
    | T_ELLIPSIS expr                                       { $$ = Expr\ArrayItem[$2, null, false, attributes(), true]; }
    | /* empty */                                           { $$ = null; }
;

encaps_list:
      encaps_list encaps_var                                { push($1, $2); }
    | encaps_list encaps_string_part                        { push($1, $2); }
    | encaps_var                                            { init($1); }
    | encaps_string_part encaps_var                         { init($1, $2); }
;

encaps_string_part:
      T_ENCAPSED_AND_WHITESPACE                             { $$ = Scalar\EncapsedStringPart[$1]; }
;

encaps_str_varname:
      T_STRING_VARNAME                                      { $$ = Expr\Variable[$1]; }
;

encaps_var:
      plain_variable                                        { $$ = $1; }
    | plain_variable '[' encaps_var_offset ']'              { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | plain_variable T_OBJECT_OPERATOR identifier_not_reserved
          { $$ = Expr\PropertyFetch[$1, $3]; }
    | plain_variable T_NULLSAFE_OBJECT_OPERATOR identifier_not_reserved
          { $$ = Expr\NullsafePropertyFetch[$1, $3]; }
    | T_DOLLAR_OPEN_CURLY_BRACES expr '}'                   { $$ = Expr\Variable[$2]; }
    | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}'       { $$ = Expr\Variable[$2]; }
    | T_DOLLAR_OPEN_CURLY_BRACES encaps_str_varname '[' expr ']' '}'
          { $$ = Expr\ArrayDimFetch[$2, $4]; }
    | T_CURLY_OPEN variable '}'                             { $$ = $2; }
;

encaps_var_offset:
      T_STRING                                              { $$ = Scalar\String_[$1]; }
    | T_NUM_STRING                                          { $$ = $this->parseNumString($1, attributes()); }
    | '-' T_NUM_STRING                                      { $$ = $this->parseNumString('-' . $2, attributes()); }
    | plain_variable                                        { $$ = $1; }
;

%%
<?php
$meta #
#semval($) $this->semValue
#semval($,%t) $this->semValue
#semval(%n) $stackPos-(%l-%n)
#semval(%n,%t) $stackPos-(%l-%n)

namespace PhpParser\Parser;

use PhpParser\Error;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt;
#include;

/* This is an automatically GENERATED file, which should not be manually edited.
 * Instead edit one of the following:
 *  * the grammar files grammar/php5.y or grammar/php7.y
 *  * the skeleton file grammar/parser.template
 *  * the preprocessing script grammar/rebuildParsers.php
 */
class #(-p) extends \PhpParser\ParserAbstract
{
    protected $tokenToSymbolMapSize = #(YYMAXLEX);
    protected $actionTableSize = #(YYLAST);
    protected $gotoTableSize = #(YYGLAST);

    protected $invalidSymbol = #(YYBADCH);
    protected $errorSymbol = #(YYINTERRTOK);
    protected $defaultAction = #(YYDEFAULT);
    protected $unexpectedTokenRule = #(YYUNEXPECTED);

    protected $YY2TBLSTATE = #(YY2TBLSTATE);
    protected $numNonLeafStates = #(YYNLSTATES);

    protected $symbolToName = array(
        #listvar terminals
    );

    protected $tokenToSymbol = array(
        #listvar yytranslate
    );

    protected $action = array(
        #listvar yyaction
    );

    protected $actionCheck = array(
        #listvar yycheck
    );

    protected $actionBase = array(
        #listvar yybase
    );

    protected $actionDefault = array(
        #listvar yydefault
    );

    protected $goto = array(
        #listvar yygoto
    );

    protected $gotoCheck = array(
        #listvar yygcheck
    );

    protected $gotoBase = array(
        #listvar yygbase
    );

    protected $gotoDefault = array(
        #listvar yygdefault
    );

    protected $ruleToNonTerminal = array(
        #listvar yylhs
    );

    protected $ruleToLength = array(
        #listvar yylen
    );
#if -t

    protected $productions = array(
        #production-strings;
    );
#endif

    protected function initReduceCallbacks() {
        $this->reduceCallbacks = [
#reduce
            %n => function ($stackPos) {
                %b
            },
#noact
            %n => function ($stackPos) {
                $this->semValue = $this->semStack[$stackPos];
            },
#endreduce
        ];
    }
}
#tailcode;
%pure_parser
%expect 6

%tokens

%%

start:
    top_statement_list                                      { $$ = $this->handleNamespaces($1); }
;

top_statement_list_ex:
      top_statement_list_ex top_statement                   { pushNormalizing($1, $2); }
    | /* empty */                                           { init(); }
;

top_statement_list:
      top_statement_list_ex
          { makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
            if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;

ampersand:
      T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
    | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG
;

reserved_non_modifiers:
      T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND
    | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE
    | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH
    | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO
    | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT
    | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
    | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER | T_FN
    | T_MATCH
;

semi_reserved:
      reserved_non_modifiers
    | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC
;

identifier_ex:
      T_STRING                                              { $$ = Node\Identifier[$1]; }
    | semi_reserved                                         { $$ = Node\Identifier[$1]; }
;

identifier:
      T_STRING                                              { $$ = Node\Identifier[$1]; }
;

reserved_non_modifiers_identifier:
      reserved_non_modifiers                                { $$ = Node\Identifier[$1]; }
;

namespace_name:
      T_STRING                                              { $$ = Name[$1]; }
    | T_NAME_QUALIFIED                                      { $$ = Name[$1]; }
;

legacy_namespace_name:
      namespace_name                                        { $$ = $1; }
    | T_NAME_FULLY_QUALIFIED                                { $$ = Name[substr($1, 1)]; }
;

plain_variable:
      T_VARIABLE                                            { $$ = Expr\Variable[parseVar($1)]; }
;

top_statement:
      statement                                             { $$ = $1; }
    | function_declaration_statement                        { $$ = $1; }
    | class_declaration_statement                           { $$ = $1; }
    | T_HALT_COMPILER
          { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; }
    | T_NAMESPACE namespace_name ';'
          { $$ = Stmt\Namespace_[$2, null];
            $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON);
            $this->checkNamespace($$); }
    | T_NAMESPACE namespace_name '{' top_statement_list '}'
          { $$ = Stmt\Namespace_[$2, $4];
            $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($$); }
    | T_NAMESPACE '{' top_statement_list '}'
          { $$ = Stmt\Namespace_[null, $3];
            $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED);
            $this->checkNamespace($$); }
    | T_USE use_declarations ';'                            { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; }
    | T_USE use_type use_declarations ';'                   { $$ = Stmt\Use_[$3, $2]; }
    | group_use_declaration ';'                             { $$ = $1; }
    | T_CONST constant_declaration_list ';'                 { $$ = Stmt\Const_[$2]; }
;

use_type:
      T_FUNCTION                                            { $$ = Stmt\Use_::TYPE_FUNCTION; }
    | T_CONST                                               { $$ = Stmt\Use_::TYPE_CONSTANT; }
;

group_use_declaration:
      T_USE use_type legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations '}'
          { $$ = Stmt\GroupUse[$3, $6, $2]; }
    | T_USE legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations '}'
          { $$ = Stmt\GroupUse[$2, $5, Stmt\Use_::TYPE_UNKNOWN]; }
;

unprefixed_use_declarations:
      unprefixed_use_declarations ',' unprefixed_use_declaration
          { push($1, $3); }
    | unprefixed_use_declaration                            { init($1); }
;

use_declarations:
      use_declarations ',' use_declaration                  { push($1, $3); }
    | use_declaration                                       { init($1); }
;

inline_use_declarations:
      inline_use_declarations ',' inline_use_declaration    { push($1, $3); }
    | inline_use_declaration                                { init($1); }
;

unprefixed_use_declaration:
      namespace_name
          { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); }
    | namespace_name T_AS identifier
          { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); }
;

use_declaration:
      legacy_namespace_name
          { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); }
    | legacy_namespace_name T_AS identifier
          { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); }
;

inline_use_declaration:
      unprefixed_use_declaration                            { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; }
    | use_type unprefixed_use_declaration                   { $$ = $2; $$->type = $1; }
;

constant_declaration_list:
      constant_declaration_list ',' constant_declaration    { push($1, $3); }
    | constant_declaration                                  { init($1); }
;

constant_declaration:
    identifier '=' static_scalar                            { $$ = Node\Const_[$1, $3]; }
;

class_const_list:
      class_const_list ',' class_const                      { push($1, $3); }
    | class_const                                           { init($1); }
;

class_const:
    identifier_ex '=' static_scalar                         { $$ = Node\Const_[$1, $3]; }
;

inner_statement_list_ex:
      inner_statement_list_ex inner_statement               { pushNormalizing($1, $2); }
    | /* empty */                                           { init(); }
;

inner_statement_list:
      inner_statement_list_ex
          { makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
            if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;

inner_statement:
      statement                                             { $$ = $1; }
    | function_declaration_statement                        { $$ = $1; }
    | class_declaration_statement                           { $$ = $1; }
    | T_HALT_COMPILER
          { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); }
;

non_empty_statement:
      '{' inner_statement_list '}'
    {
        if ($2) {
            $$ = $2; prependLeadingComments($$);
        } else {
            makeNop($$, $this->startAttributeStack[#1], $this->endAttributes);
            if (null === $$) { $$ = array(); }
        }
    }
    | T_IF parentheses_expr statement elseif_list else_single
          { $$ = Stmt\If_[$2, ['stmts' => toArray($3), 'elseifs' => $4, 'else' => $5]]; }
    | T_IF parentheses_expr ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';'
          { $$ = Stmt\If_[$2, ['stmts' => $4, 'elseifs' => $5, 'else' => $6]]; }
    | T_WHILE parentheses_expr while_statement              { $$ = Stmt\While_[$2, $3]; }
    | T_DO statement T_WHILE parentheses_expr ';'           { $$ = Stmt\Do_   [$4, toArray($2)]; }
    | T_FOR '(' for_expr ';'  for_expr ';' for_expr ')' for_statement
          { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; }
    | T_SWITCH parentheses_expr switch_case_list            { $$ = Stmt\Switch_[$2, $3]; }
    | T_BREAK ';'                                           { $$ = Stmt\Break_[null]; }
    | T_BREAK expr ';'                                      { $$ = Stmt\Break_[$2]; }
    | T_CONTINUE ';'                                        { $$ = Stmt\Continue_[null]; }
    | T_CONTINUE expr ';'                                   { $$ = Stmt\Continue_[$2]; }
    | T_RETURN ';'                                          { $$ = Stmt\Return_[null]; }
    | T_RETURN expr ';'                                     { $$ = Stmt\Return_[$2]; }
    | T_GLOBAL global_var_list ';'                          { $$ = Stmt\Global_[$2]; }
    | T_STATIC static_var_list ';'                          { $$ = Stmt\Static_[$2]; }
    | T_ECHO expr_list ';'                                  { $$ = Stmt\Echo_[$2]; }
    | T_INLINE_HTML                                         { $$ = Stmt\InlineHTML[$1]; }
    | yield_expr ';'                                        { $$ = Stmt\Expression[$1]; }
    | expr ';'                                              { $$ = Stmt\Expression[$1]; }
    | T_UNSET '(' variables_list ')' ';'                    { $$ = Stmt\Unset_[$3]; }
    | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement
          { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; }
    | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement
          { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; }
    | T_DECLARE '(' declare_list ')' declare_statement      { $$ = Stmt\Declare_[$3, $5]; }
    | T_TRY '{' inner_statement_list '}' catches optional_finally
          { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); }
    | T_THROW expr ';'                                      { $$ = Stmt\Throw_[$2]; }
    | T_GOTO identifier ';'                                 { $$ = Stmt\Goto_[$2]; }
    | identifier ':'                                        { $$ = Stmt\Label[$1]; }
    | expr error                                            { $$ = Stmt\Expression[$1]; }
    | error                                                 { $$ = array(); /* means: no statement */ }
;

statement:
      non_empty_statement                                   { $$ = $1; }
    | ';'
          { makeNop($$, $this->startAttributeStack[#1], $this->endAttributes);
            if ($$ === null) $$ = array(); /* means: no statement */ }
;

catches:
      /* empty */                                           { init(); }
    | catches catch                                         { push($1, $2); }
;

catch:
    T_CATCH '(' name plain_variable ')' '{' inner_statement_list '}'
        { $$ = Stmt\Catch_[array($3), $4, $7]; }
;

optional_finally:
      /* empty */                                           { $$ = null; }
    | T_FINALLY '{' inner_statement_list '}'                { $$ = Stmt\Finally_[$3]; }
;

variables_list:
      variable                                              { init($1); }
    | variables_list ',' variable                           { push($1, $3); }
;

optional_ref:
      /* empty */                                           { $$ = false; }
    | ampersand                                             { $$ = true; }
;

optional_arg_ref:
      /* empty */                                           { $$ = false; }
    | T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG                 { $$ = true; }
;

optional_ellipsis:
      /* empty */                                           { $$ = false; }
    | T_ELLIPSIS                                            { $$ = true; }
;

identifier_maybe_readonly:
      identifier                                            { $$ = $1; }
    | T_READONLY                                            { $$ = Node\Identifier[$1]; }
;

function_declaration_statement:
    T_FUNCTION optional_ref identifier_maybe_readonly '(' parameter_list ')' optional_return_type '{' inner_statement_list '}'
        { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; }
;

class_declaration_statement:
      class_entry_type identifier extends_from implements_list '{' class_statement_list '}'
          { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]];
            $this->checkClass($$, #2); }
    | T_INTERFACE identifier interface_extends_list '{' class_statement_list '}'
          { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]];
            $this->checkInterface($$, #2); }
    | T_TRAIT identifier '{' class_statement_list '}'
          { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; }
;

class_entry_type:
      T_CLASS                                               { $$ = 0; }
    | T_ABSTRACT T_CLASS                                    { $$ = Stmt\Class_::MODIFIER_ABSTRACT; }
    | T_FINAL T_CLASS                                       { $$ = Stmt\Class_::MODIFIER_FINAL; }
;

extends_from:
      /* empty */                                           { $$ = null; }
    | T_EXTENDS class_name                                  { $$ = $2; }
;

interface_extends_list:
      /* empty */                                           { $$ = array(); }
    | T_EXTENDS class_name_list                             { $$ = $2; }
;

implements_list:
      /* empty */                                           { $$ = array(); }
    | T_IMPLEMENTS class_name_list                          { $$ = $2; }
;

class_name_list:
      class_name                                            { init($1); }
    | class_name_list ',' class_name                        { push($1, $3); }
;

for_statement:
      statement                                             { $$ = toArray($1); }
    | ':' inner_statement_list T_ENDFOR ';'                 { $$ = $2; }
;

foreach_statement:
      statement                                             { $$ = toArray($1); }
    | ':' inner_statement_list T_ENDFOREACH ';'             { $$ = $2; }
;

declare_statement:
      non_empty_statement                                   { $$ = toArray($1); }
    | ';'                                                   { $$ = null; }
    | ':' inner_statement_list T_ENDDECLARE ';'             { $$ = $2; }
;

declare_list:
      declare_list_element                                  { init($1); }
    | declare_list ',' declare_list_element                 { push($1, $3); }
;

declare_list_element:
      identifier '=' static_scalar                          { $$ = Stmt\DeclareDeclare[$1, $3]; }
;

switch_case_list:
      '{' case_list '}'                                     { $$ = $2; }
    | '{' ';' case_list '}'                                 { $$ = $3; }
    | ':' case_list T_ENDSWITCH ';'                         { $$ = $2; }
    | ':' ';' case_list T_ENDSWITCH ';'                     { $$ = $3; }
;

case_list:
      /* empty */                                           { init(); }
    | case_list case                                        { push($1, $2); }
;

case:
      T_CASE expr case_separator inner_statement_list_ex    { $$ = Stmt\Case_[$2, $4]; }
    | T_DEFAULT case_separator inner_statement_list_ex      { $$ = Stmt\Case_[null, $3]; }
;

case_separator:
      ':'
    | ';'
;

while_statement:
      statement                                             { $$ = toArray($1); }
    | ':' inner_statement_list T_ENDWHILE ';'               { $$ = $2; }
;

elseif_list:
      /* empty */                                           { init(); }
    | elseif_list elseif                                    { push($1, $2); }
;

elseif:
      T_ELSEIF parentheses_expr statement                   { $$ = Stmt\ElseIf_[$2, toArray($3)]; }
;

new_elseif_list:
      /* empty */                                           { init(); }
    | new_elseif_list new_elseif                            { push($1, $2); }
;

new_elseif:
     T_ELSEIF parentheses_expr ':' inner_statement_list     { $$ = Stmt\ElseIf_[$2, $4]; }
;

else_single:
      /* empty */                                           { $$ = null; }
    | T_ELSE statement                                      { $$ = Stmt\Else_[toArray($2)]; }
;

new_else_single:
      /* empty */                                           { $$ = null; }
    | T_ELSE ':' inner_statement_list                       { $$ = Stmt\Else_[$3]; }
;

foreach_variable:
      variable                                              { $$ = array($1, false); }
    | ampersand variable                                    { $$ = array($2, true); }
    | list_expr                                             { $$ = array($1, false); }
;

parameter_list:
      non_empty_parameter_list                              { $$ = $1; }
    | /* empty */                                           { $$ = array(); }
;

non_empty_parameter_list:
      parameter                                             { init($1); }
    | non_empty_parameter_list ',' parameter                { push($1, $3); }
;

parameter:
      optional_param_type optional_arg_ref optional_ellipsis plain_variable
          { $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); }
    | optional_param_type optional_arg_ref optional_ellipsis plain_variable '=' static_scalar
          { $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); }
;

type:
      name                                                  { $$ = $1; }
    | T_ARRAY                                               { $$ = Node\Identifier['array']; }
    | T_CALLABLE                                            { $$ = Node\Identifier['callable']; }
;

optional_param_type:
      /* empty */                                           { $$ = null; }
    | type                                                  { $$ = $1; }
;

optional_return_type:
      /* empty */                                           { $$ = null; }
    | ':' type                                              { $$ = $2; }
;

argument_list:
      '(' ')'                                               { $$ = array(); }
    | '(' non_empty_argument_list ')'                       { $$ = $2; }
    | '(' yield_expr ')'                                    { $$ = array(Node\Arg[$2, false, false]); }
;

non_empty_argument_list:
      argument                                              { init($1); }
    | non_empty_argument_list ',' argument                  { push($1, $3); }
;

argument:
      expr                                                  { $$ = Node\Arg[$1, false, false]; }
    | ampersand variable                                    { $$ = Node\Arg[$2, true, false]; }
    | T_ELLIPSIS expr                                       { $$ = Node\Arg[$2, false, true]; }
;

global_var_list:
      global_var_list ',' global_var                        { push($1, $3); }
    | global_var                                            { init($1); }
;

global_var:
      plain_variable                                        { $$ = $1; }
    | '$' variable                                          { $$ = Expr\Variable[$2]; }
    | '$' '{' expr '}'                                      { $$ = Expr\Variable[$3]; }
;

static_var_list:
      static_var_list ',' static_var                        { push($1, $3); }
    | static_var                                            { init($1); }
;

static_var:
      plain_variable                                        { $$ = Stmt\StaticVar[$1, null]; }
    | plain_variable '=' static_scalar                      { $$ = Stmt\StaticVar[$1, $3]; }
;

class_statement_list_ex:
      class_statement_list_ex class_statement               { if ($2 !== null) { push($1, $2); } }
    | /* empty */                                           { init(); }
;

class_statement_list:
      class_statement_list_ex
          { makeZeroLengthNop($nop, $this->lookaheadStartAttributes);
            if ($nop !== null) { $1[] = $nop; } $$ = $1; }
;

class_statement:
      variable_modifiers property_declaration_list ';'
          { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); }
    | T_CONST class_const_list ';'                          { $$ = Stmt\ClassConst[$2, 0]; }
    | method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body
          { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]];
            $this->checkClassMethod($$, #1); }
    | T_USE class_name_list trait_adaptations               { $$ = Stmt\TraitUse[$2, $3]; }
;

trait_adaptations:
      ';'                                                   { $$ = array(); }
    | '{' trait_adaptation_list '}'                         { $$ = $2; }
;

trait_adaptation_list:
      /* empty */                                           { init(); }
    | trait_adaptation_list trait_adaptation                { push($1, $2); }
;

trait_adaptation:
      trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';'
          { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; }
    | trait_method_reference T_AS member_modifier identifier_ex ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; }
    | trait_method_reference T_AS member_modifier ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; }
    | trait_method_reference T_AS identifier ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
    | trait_method_reference T_AS reserved_non_modifiers_identifier ';'
          { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; }
;

trait_method_reference_fully_qualified:
      name T_PAAMAYIM_NEKUDOTAYIM identifier_ex             { $$ = array($1, $3); }
;
trait_method_reference:
      trait_method_reference_fully_qualified                { $$ = $1; }
    | identifier_ex                                         { $$ = array(null, $1); }
;

method_body:
      ';' /* abstract method */                             { $$ = null; }
    | '{' inner_statement_list '}'                          { $$ = $2; }
;

variable_modifiers:
      non_empty_member_modifiers                            { $$ = $1; }
    | T_VAR                                                 { $$ = 0; }
;

method_modifiers:
      /* empty */                                           { $$ = 0; }
    | non_empty_member_modifiers                            { $$ = $1; }
;

non_empty_member_modifiers:
      member_modifier                                       { $$ = $1; }
    | non_empty_member_modifiers member_modifier            { $this->checkModifier($1, $2, #2); $$ = $1 | $2; }
;

member_modifier:
      T_PUBLIC                                              { $$ = Stmt\Class_::MODIFIER_PUBLIC; }
    | T_PROTECTED                                           { $$ = Stmt\Class_::MODIFIER_PROTECTED; }
    | T_PRIVATE                                             { $$ = Stmt\Class_::MODIFIER_PRIVATE; }
    | T_STATIC                                              { $$ = Stmt\Class_::MODIFIER_STATIC; }
    | T_ABSTRACT                                            { $$ = Stmt\Class_::MODIFIER_ABSTRACT; }
    | T_FINAL                                               { $$ = Stmt\Class_::MODIFIER_FINAL; }
;

property_declaration_list:
      property_declaration                                  { init($1); }
    | property_declaration_list ',' property_declaration    { push($1, $3); }
;

property_decl_name:
      T_VARIABLE                                            { $$ = Node\VarLikeIdentifier[parseVar($1)]; }
;

property_declaration:
      property_decl_name                                    { $$ = Stmt\PropertyProperty[$1, null]; }
    | property_decl_name '=' static_scalar                  { $$ = Stmt\PropertyProperty[$1, $3]; }
;

expr_list:
      expr_list ',' expr                                    { push($1, $3); }
    | expr                                                  { init($1); }
;

for_expr:
      /* empty */                                           { $$ = array(); }
    | expr_list                                             { $$ = $1; }
;

expr:
      variable                                              { $$ = $1; }
    | list_expr '=' expr                                    { $$ = Expr\Assign[$1, $3]; }
    | variable '=' expr                                     { $$ = Expr\Assign[$1, $3]; }
    | variable '=' ampersand variable                       { $$ = Expr\AssignRef[$1, $4]; }
    | variable '=' ampersand new_expr                       { $$ = Expr\AssignRef[$1, $4]; }
    | new_expr                                              { $$ = $1; }
    | T_CLONE expr                                          { $$ = Expr\Clone_[$2]; }
    | variable T_PLUS_EQUAL expr                            { $$ = Expr\AssignOp\Plus      [$1, $3]; }
    | variable T_MINUS_EQUAL expr                           { $$ = Expr\AssignOp\Minus     [$1, $3]; }
    | variable T_MUL_EQUAL expr                             { $$ = Expr\AssignOp\Mul       [$1, $3]; }
    | variable T_DIV_EQUAL expr                             { $$ = Expr\AssignOp\Div       [$1, $3]; }
    | variable T_CONCAT_EQUAL expr                          { $$ = Expr\AssignOp\Concat    [$1, $3]; }
    | variable T_MOD_EQUAL expr                             { $$ = Expr\AssignOp\Mod       [$1, $3]; }
    | variable T_AND_EQUAL expr                             { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; }
    | variable T_OR_EQUAL expr                              { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; }
    | variable T_XOR_EQUAL expr                             { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; }
    | variable T_SL_EQUAL expr                              { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; }
    | variable T_SR_EQUAL expr                              { $$ = Expr\AssignOp\ShiftRight[$1, $3]; }
    | variable T_POW_EQUAL expr                             { $$ = Expr\AssignOp\Pow       [$1, $3]; }
    | variable T_COALESCE_EQUAL expr                        { $$ = Expr\AssignOp\Coalesce  [$1, $3]; }
    | variable T_INC                                        { $$ = Expr\PostInc[$1]; }
    | T_INC variable                                        { $$ = Expr\PreInc [$2]; }
    | variable T_DEC                                        { $$ = Expr\PostDec[$1]; }
    | T_DEC variable                                        { $$ = Expr\PreDec [$2]; }
    | expr T_BOOLEAN_OR expr                                { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; }
    | expr T_BOOLEAN_AND expr                               { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; }
    | expr T_LOGICAL_OR expr                                { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; }
    | expr T_LOGICAL_AND expr                               { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; }
    | expr T_LOGICAL_XOR expr                               { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; }
    | expr '|' expr                                         { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; }
    | expr T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr   { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; }
    | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG expr       { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; }
    | expr '^' expr                                         { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; }
    | expr '.' expr                                         { $$ = Expr\BinaryOp\Concat    [$1, $3]; }
    | expr '+' expr                                         { $$ = Expr\BinaryOp\Plus      [$1, $3]; }
    | expr '-' expr                                         { $$ = Expr\BinaryOp\Minus     [$1, $3]; }
    | expr '*' expr                                         { $$ = Expr\BinaryOp\Mul       [$1, $3]; }
    | expr '/' expr                                         { $$ = Expr\BinaryOp\Div       [$1, $3]; }
    | expr '%' expr                                         { $$ = Expr\BinaryOp\Mod       [$1, $3]; }
    | expr T_SL expr                                        { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; }
    | expr T_SR expr                                        { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; }
    | expr T_POW expr                                       { $$ = Expr\BinaryOp\Pow       [$1, $3]; }
    | '+' expr %prec T_INC                                  { $$ = Expr\UnaryPlus [$2]; }
    | '-' expr %prec T_INC                                  { $$ = Expr\UnaryMinus[$2]; }
    | '!' expr                                              { $$ = Expr\BooleanNot[$2]; }
    | '~' expr                                              { $$ = Expr\BitwiseNot[$2]; }
    | expr T_IS_IDENTICAL expr                              { $$ = Expr\BinaryOp\Identical     [$1, $3]; }
    | expr T_IS_NOT_IDENTICAL expr                          { $$ = Expr\BinaryOp\NotIdentical  [$1, $3]; }
    | expr T_IS_EQUAL expr                                  { $$ = Expr\BinaryOp\Equal         [$1, $3]; }
    | expr T_IS_NOT_EQUAL expr                              { $$ = Expr\BinaryOp\NotEqual      [$1, $3]; }
    | expr T_SPACESHIP expr                                 { $$ = Expr\BinaryOp\Spaceship     [$1, $3]; }
    | expr '<' expr                                         { $$ = Expr\BinaryOp\Smaller       [$1, $3]; }
    | expr T_IS_SMALLER_OR_EQUAL expr                       { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; }
    | expr '>' expr                                         { $$ = Expr\BinaryOp\Greater       [$1, $3]; }
    | expr T_IS_GREATER_OR_EQUAL expr                       { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; }
    | expr T_INSTANCEOF class_name_reference                { $$ = Expr\Instanceof_[$1, $3]; }
    | parentheses_expr                                      { $$ = $1; }
    /* we need a separate '(' new_expr ')' rule to avoid problems caused by a s/r conflict */
    | '(' new_expr ')'                                      { $$ = $2; }
    | expr '?' expr ':' expr                                { $$ = Expr\Ternary[$1, $3,   $5]; }
    | expr '?' ':' expr                                     { $$ = Expr\Ternary[$1, null, $4]; }
    | expr T_COALESCE expr                                  { $$ = Expr\BinaryOp\Coalesce[$1, $3]; }
    | T_ISSET '(' variables_list ')'                        { $$ = Expr\Isset_[$3]; }
    | T_EMPTY '(' expr ')'                                  { $$ = Expr\Empty_[$3]; }
    | T_INCLUDE expr                                        { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; }
    | T_INCLUDE_ONCE expr                                   { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; }
    | T_EVAL parentheses_expr                               { $$ = Expr\Eval_[$2]; }
    | T_REQUIRE expr                                        { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; }
    | T_REQUIRE_ONCE expr                                   { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; }
    | T_INT_CAST expr                                       { $$ = Expr\Cast\Int_    [$2]; }
    | T_DOUBLE_CAST expr
          { $attrs = attributes();
            $attrs['kind'] = $this->getFloatCastKind($1);
            $$ = new Expr\Cast\Double($2, $attrs); }
    | T_STRING_CAST expr                                    { $$ = Expr\Cast\String_ [$2]; }
    | T_ARRAY_CAST expr                                     { $$ = Expr\Cast\Array_  [$2]; }
    | T_OBJECT_CAST expr                                    { $$ = Expr\Cast\Object_ [$2]; }
    | T_BOOL_CAST expr                                      { $$ = Expr\Cast\Bool_   [$2]; }
    | T_UNSET_CAST expr                                     { $$ = Expr\Cast\Unset_  [$2]; }
    | T_EXIT exit_expr
          { $attrs = attributes();
            $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
            $$ = new Expr\Exit_($2, $attrs); }
    | '@' expr                                              { $$ = Expr\ErrorSuppress[$2]; }
    | scalar                                                { $$ = $1; }
    | array_expr                                            { $$ = $1; }
    | scalar_dereference                                    { $$ = $1; }
    | '`' backticks_expr '`'                                { $$ = Expr\ShellExec[$2]; }
    | T_PRINT expr                                          { $$ = Expr\Print_[$2]; }
    | T_YIELD                                               { $$ = Expr\Yield_[null, null]; }
    | T_YIELD_FROM expr                                     { $$ = Expr\YieldFrom[$2]; }
    | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
      '{' inner_statement_list '}'
          { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; }
    | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
      '{' inner_statement_list '}'
          { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; }
;

parentheses_expr:
      '(' expr ')'                                          { $$ = $2; }
    | '(' yield_expr ')'                                    { $$ = $2; }
;

yield_expr:
      T_YIELD expr                                          { $$ = Expr\Yield_[$2, null]; }
    | T_YIELD expr T_DOUBLE_ARROW expr                      { $$ = Expr\Yield_[$4, $2]; }
;

array_expr:
      T_ARRAY '(' array_pair_list ')'
          { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG;
            $$ = new Expr\Array_($3, $attrs); }
    | '[' array_pair_list ']'
          { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT;
            $$ = new Expr\Array_($2, $attrs); }
;

scalar_dereference:
      array_expr '[' dim_offset ']'                         { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']'         { $$ = Expr\ArrayDimFetch[Scalar\String_::fromString($1, attributes()), $3]; }
    | constant '[' dim_offset ']'                           { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | scalar_dereference '[' dim_offset ']'                 { $$ = Expr\ArrayDimFetch[$1, $3]; }
    /* alternative array syntax missing intentionally */
;

anonymous_class:
      T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
          { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2);
            $this->checkClass($$[0], -1); }
;

new_expr:
      T_NEW class_name_reference ctor_arguments             { $$ = Expr\New_[$2, $3]; }
    | T_NEW anonymous_class
          { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; }
;

lexical_vars:
      /* empty */                                           { $$ = array(); }
    | T_USE '(' lexical_var_list ')'                        { $$ = $3; }
;

lexical_var_list:
      lexical_var                                           { init($1); }
    | lexical_var_list ',' lexical_var                      { push($1, $3); }
;

lexical_var:
      optional_ref plain_variable                           { $$ = Expr\ClosureUse[$2, $1]; }
;

name_readonly:
      T_READONLY                                            { $$ = Name[$1]; }
;

function_call:
      name argument_list                                    { $$ = Expr\FuncCall[$1, $2]; }
    | name_readonly argument_list                           { $$ = Expr\FuncCall[$1, $2]; }
    | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex argument_list
          { $$ = Expr\StaticCall[$1, $3, $4]; }
    | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list
          { $$ = Expr\StaticCall[$1, $4, $6]; }
    | static_property argument_list
          { $$ = $this->fixupPhp5StaticPropCall($1, $2, attributes()); }
    | variable_without_objects argument_list
          { $$ = Expr\FuncCall[$1, $2]; }
    | function_call '[' dim_offset ']'                      { $$ = Expr\ArrayDimFetch[$1, $3]; }
      /* alternative array syntax missing intentionally */
;

class_name:
      T_STATIC                                              { $$ = Name[$1]; }
    | name                                                  { $$ = $1; }
;

name:
      T_STRING                                              { $$ = Name[$1]; }
    | T_NAME_QUALIFIED                                      { $$ = Name[$1]; }
    | T_NAME_FULLY_QUALIFIED                                { $$ = Name\FullyQualified[substr($1, 1)]; }
    | T_NAME_RELATIVE                                       { $$ = Name\Relative[substr($1, 10)]; }
;

class_name_reference:
      class_name                                            { $$ = $1; }
    | dynamic_class_name_reference                          { $$ = $1; }
;

dynamic_class_name_reference:
      object_access_for_dcnr                                { $$ = $1; }
    | base_variable                                         { $$ = $1; }
;

class_name_or_var:
      class_name                                            { $$ = $1; }
    | reference_variable                                    { $$ = $1; }
;

object_access_for_dcnr:
      base_variable T_OBJECT_OPERATOR object_property
          { $$ = Expr\PropertyFetch[$1, $3]; }
    | object_access_for_dcnr T_OBJECT_OPERATOR object_property
          { $$ = Expr\PropertyFetch[$1, $3]; }
    | object_access_for_dcnr '[' dim_offset ']'             { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | object_access_for_dcnr '{' expr '}'                   { $$ = Expr\ArrayDimFetch[$1, $3]; }
;

exit_expr:
      /* empty */                                           { $$ = null; }
    | '(' ')'                                               { $$ = null; }
    | parentheses_expr                                      { $$ = $1; }
;

backticks_expr:
      /* empty */                                           { $$ = array(); }
    | T_ENCAPSED_AND_WHITESPACE
          { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`', false)]); }
    | encaps_list                                           { parseEncapsed($1, '`', false); $$ = $1; }
;

ctor_arguments:
      /* empty */                                           { $$ = array(); }
    | argument_list                                         { $$ = $1; }
;

common_scalar:
      T_LNUMBER                                             { $$ = $this->parseLNumber($1, attributes(), true); }
    | T_DNUMBER                                             { $$ = Scalar\DNumber::fromString($1, attributes()); }
    | T_CONSTANT_ENCAPSED_STRING                            { $$ = Scalar\String_::fromString($1, attributes(), false); }
    | T_LINE                                                { $$ = Scalar\MagicConst\Line[]; }
    | T_FILE                                                { $$ = Scalar\MagicConst\File[]; }
    | T_DIR                                                 { $$ = Scalar\MagicConst\Dir[]; }
    | T_CLASS_C                                             { $$ = Scalar\MagicConst\Class_[]; }
    | T_TRAIT_C                                             { $$ = Scalar\MagicConst\Trait_[]; }
    | T_METHOD_C                                            { $$ = Scalar\MagicConst\Method[]; }
    | T_FUNC_C                                              { $$ = Scalar\MagicConst\Function_[]; }
    | T_NS_C                                                { $$ = Scalar\MagicConst\Namespace_[]; }
    | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
          { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), false); }
    | T_START_HEREDOC T_END_HEREDOC
          { $$ = $this->parseDocString($1, '', $2, attributes(), stackAttributes(#2), false); }
;

static_scalar:
      common_scalar                                         { $$ = $1; }
    | class_name T_PAAMAYIM_NEKUDOTAYIM identifier_ex       { $$ = Expr\ClassConstFetch[$1, $3]; }
    | name                                                  { $$ = Expr\ConstFetch[$1]; }
    | T_ARRAY '(' static_array_pair_list ')'                { $$ = Expr\Array_[$3]; }
    | '[' static_array_pair_list ']'                        { $$ = Expr\Array_[$2]; }
    | static_operation                                      { $$ = $1; }
;

static_operation:
      static_scalar T_BOOLEAN_OR static_scalar              { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; }
    | static_scalar T_BOOLEAN_AND static_scalar             { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; }
    | static_scalar T_LOGICAL_OR static_scalar              { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; }
    | static_scalar T_LOGICAL_AND static_scalar             { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; }
    | static_scalar T_LOGICAL_XOR static_scalar             { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; }
    | static_scalar '|' static_scalar                       { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; }
    | static_scalar T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG static_scalar
          { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; }
    | static_scalar T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG static_scalar
          { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; }
    | static_scalar '^' static_scalar                       { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; }
    | static_scalar '.' static_scalar                       { $$ = Expr\BinaryOp\Concat    [$1, $3]; }
    | static_scalar '+' static_scalar                       { $$ = Expr\BinaryOp\Plus      [$1, $3]; }
    | static_scalar '-' static_scalar                       { $$ = Expr\BinaryOp\Minus     [$1, $3]; }
    | static_scalar '*' static_scalar                       { $$ = Expr\BinaryOp\Mul       [$1, $3]; }
    | static_scalar '/' static_scalar                       { $$ = Expr\BinaryOp\Div       [$1, $3]; }
    | static_scalar '%' static_scalar                       { $$ = Expr\BinaryOp\Mod       [$1, $3]; }
    | static_scalar T_SL static_scalar                      { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; }
    | static_scalar T_SR static_scalar                      { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; }
    | static_scalar T_POW static_scalar                     { $$ = Expr\BinaryOp\Pow       [$1, $3]; }
    | '+' static_scalar %prec T_INC                         { $$ = Expr\UnaryPlus [$2]; }
    | '-' static_scalar %prec T_INC                         { $$ = Expr\UnaryMinus[$2]; }
    | '!' static_scalar                                     { $$ = Expr\BooleanNot[$2]; }
    | '~' static_scalar                                     { $$ = Expr\BitwiseNot[$2]; }
    | static_scalar T_IS_IDENTICAL static_scalar            { $$ = Expr\BinaryOp\Identical     [$1, $3]; }
    | static_scalar T_IS_NOT_IDENTICAL static_scalar        { $$ = Expr\BinaryOp\NotIdentical  [$1, $3]; }
    | static_scalar T_IS_EQUAL static_scalar                { $$ = Expr\BinaryOp\Equal         [$1, $3]; }
    | static_scalar T_IS_NOT_EQUAL static_scalar            { $$ = Expr\BinaryOp\NotEqual      [$1, $3]; }
    | static_scalar '<' static_scalar                       { $$ = Expr\BinaryOp\Smaller       [$1, $3]; }
    | static_scalar T_IS_SMALLER_OR_EQUAL static_scalar     { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; }
    | static_scalar '>' static_scalar                       { $$ = Expr\BinaryOp\Greater       [$1, $3]; }
    | static_scalar T_IS_GREATER_OR_EQUAL static_scalar     { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; }
    | static_scalar '?' static_scalar ':' static_scalar     { $$ = Expr\Ternary[$1, $3,   $5]; }
    | static_scalar '?' ':' static_scalar                   { $$ = Expr\Ternary[$1, null, $4]; }
    | static_scalar '[' static_scalar ']'                   { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | '(' static_scalar ')'                                 { $$ = $2; }
;

constant:
      name                                                  { $$ = Expr\ConstFetch[$1]; }
    | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex
          { $$ = Expr\ClassConstFetch[$1, $3]; }
;

scalar:
      common_scalar                                         { $$ = $1; }
    | constant                                              { $$ = $1; }
    | '"' encaps_list '"'
          { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
            parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); }
    | T_START_HEREDOC encaps_list T_END_HEREDOC
          { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); }
;

static_array_pair_list:
      /* empty */                                           { $$ = array(); }
    | non_empty_static_array_pair_list optional_comma       { $$ = $1; }
;

optional_comma:
      /* empty */
    | ','
;

non_empty_static_array_pair_list:
      non_empty_static_array_pair_list ',' static_array_pair { push($1, $3); }
    | static_array_pair                                      { init($1); }
;

static_array_pair:
      static_scalar T_DOUBLE_ARROW static_scalar            { $$ = Expr\ArrayItem[$3, $1,   false]; }
    | static_scalar                                         { $$ = Expr\ArrayItem[$1, null, false]; }
;

variable:
      object_access                                         { $$ = $1; }
    | base_variable                                         { $$ = $1; }
    | function_call                                         { $$ = $1; }
    | new_expr_array_deref                                  { $$ = $1; }
;

new_expr_array_deref:
      '(' new_expr ')' '[' dim_offset ']'                   { $$ = Expr\ArrayDimFetch[$2, $5]; }
    | new_expr_array_deref '[' dim_offset ']'               { $$ = Expr\ArrayDimFetch[$1, $3]; }
      /* alternative array syntax missing intentionally */
;

object_access:
      variable_or_new_expr T_OBJECT_OPERATOR object_property
          { $$ = Expr\PropertyFetch[$1, $3]; }
    | variable_or_new_expr T_OBJECT_OPERATOR object_property argument_list
          { $$ = Expr\MethodCall[$1, $3, $4]; }
    | object_access argument_list                           { $$ = Expr\FuncCall[$1, $2]; }
    | object_access '[' dim_offset ']'                      { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | object_access '{' expr '}'                            { $$ = Expr\ArrayDimFetch[$1, $3]; }
;

variable_or_new_expr:
      variable                                              { $$ = $1; }
    | '(' new_expr ')'                                      { $$ = $2; }
;

variable_without_objects:
      reference_variable                                    { $$ = $1; }
    | '$' variable_without_objects                          { $$ = Expr\Variable[$2]; }
;

base_variable:
      variable_without_objects                              { $$ = $1; }
    | static_property                                       { $$ = $1; }
;

static_property:
      class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' reference_variable
          { $$ = Expr\StaticPropertyFetch[$1, $4]; }
    | static_property_with_arrays                           { $$ = $1; }
;

static_property_simple_name:
      T_VARIABLE
          { $var = parseVar($1); $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; }
;

static_property_with_arrays:
      class_name_or_var T_PAAMAYIM_NEKUDOTAYIM static_property_simple_name
          { $$ = Expr\StaticPropertyFetch[$1, $3]; }
    | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' '{' expr '}'
          { $$ = Expr\StaticPropertyFetch[$1, $5]; }
    | static_property_with_arrays '[' dim_offset ']'        { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | static_property_with_arrays '{' expr '}'              { $$ = Expr\ArrayDimFetch[$1, $3]; }
;

reference_variable:
      reference_variable '[' dim_offset ']'                 { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | reference_variable '{' expr '}'                       { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | plain_variable                                        { $$ = $1; }
    | '$' '{' expr '}'                                      { $$ = Expr\Variable[$3]; }
;

dim_offset:
      /* empty */                                           { $$ = null; }
    | expr                                                  { $$ = $1; }
;

object_property:
      identifier                                            { $$ = $1; }
    | '{' expr '}'                                          { $$ = $2; }
    | variable_without_objects                              { $$ = $1; }
    | error                                                 { $$ = Expr\Error[]; $this->errorState = 2; }
;

list_expr:
      T_LIST '(' list_expr_elements ')'                     { $$ = Expr\List_[$3]; }
;

list_expr_elements:
      list_expr_elements ',' list_expr_element              { push($1, $3); }
    | list_expr_element                                     { init($1); }
;

list_expr_element:
      variable                                              { $$ = Expr\ArrayItem[$1, null, false]; }
    | list_expr                                             { $$ = Expr\ArrayItem[$1, null, false]; }
    | /* empty */                                           { $$ = null; }
;

array_pair_list:
      /* empty */                                           { $$ = array(); }
    | non_empty_array_pair_list optional_comma              { $$ = $1; }
;

non_empty_array_pair_list:
      non_empty_array_pair_list ',' array_pair              { push($1, $3); }
    | array_pair                                            { init($1); }
;

array_pair:
      expr T_DOUBLE_ARROW expr                              { $$ = Expr\ArrayItem[$3, $1,   false]; }
    | expr                                                  { $$ = Expr\ArrayItem[$1, null, false]; }
    | expr T_DOUBLE_ARROW ampersand variable                { $$ = Expr\ArrayItem[$4, $1,   true]; }
    | ampersand variable                                    { $$ = Expr\ArrayItem[$2, null, true]; }
    | T_ELLIPSIS expr                                       { $$ = Expr\ArrayItem[$2, null, false, attributes(), true]; }
;

encaps_list:
      encaps_list encaps_var                                { push($1, $2); }
    | encaps_list encaps_string_part                        { push($1, $2); }
    | encaps_var                                            { init($1); }
    | encaps_string_part encaps_var                         { init($1, $2); }
;

encaps_string_part:
      T_ENCAPSED_AND_WHITESPACE                             { $$ = Scalar\EncapsedStringPart[$1]; }
;

encaps_str_varname:
      T_STRING_VARNAME                                      { $$ = Expr\Variable[$1]; }
;

encaps_var:
      plain_variable                                        { $$ = $1; }
    | plain_variable '[' encaps_var_offset ']'              { $$ = Expr\ArrayDimFetch[$1, $3]; }
    | plain_variable T_OBJECT_OPERATOR identifier           { $$ = Expr\PropertyFetch[$1, $3]; }
    | T_DOLLAR_OPEN_CURLY_BRACES expr '}'                   { $$ = Expr\Variable[$2]; }
    | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}'       { $$ = Expr\Variable[$2]; }
    | T_DOLLAR_OPEN_CURLY_BRACES encaps_str_varname '[' expr ']' '}'
          { $$ = Expr\ArrayDimFetch[$2, $4]; }
    | T_CURLY_OPEN variable '}'                             { $$ = $2; }
;

encaps_var_offset:
      T_STRING                                              { $$ = Scalar\String_[$1]; }
    | T_NUM_STRING                                          { $$ = $this->parseNumString($1, attributes()); }
    | plain_variable                                        { $$ = $1; }
;

%%
<?php
$meta #
#semval($) $this->semValue
#semval($,%t) $this->semValue
#semval(%n) $this->stackPos-(%l-%n)
#semval(%n,%t) $this->stackPos-(%l-%n)

namespace PhpParser\Parser;
#include;

/* GENERATED file based on grammar/tokens.y */
final class Tokens
{
#tokenval
    const %s = %n;
#endtokenval
}
<?php

namespace _HumbugBox1cb33d1f20f1;

///////////////////////////////
/// Utility regex constants ///
///////////////////////////////
const LIB = '(?(DEFINE)
    (?<singleQuotedString>\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\')
    (?<doubleQuotedString>"[^\\\\"]*+(?:\\\\.[^\\\\"]*+)*+")
    (?<string>(?&singleQuotedString)|(?&doubleQuotedString))
    (?<comment>/\\*[^*]*+(?:\\*(?!/)[^*]*+)*+\\*/)
    (?<code>\\{[^\'"/{}]*+(?:(?:(?&string)|(?&comment)|(?&code)|/)[^\'"/{}]*+)*+})
)';
const PARAMS = '\\[(?<params>[^[\\]]*+(?:\\[(?&params)\\][^[\\]]*+)*+)\\]';
const ARGS = '\\((?<args>[^()]*+(?:\\((?&args)\\)[^()]*+)*+)\\)';
///////////////////////////////
/// Preprocessing functions ///
///////////////////////////////
function preprocessGrammar($code)
{
    $code = resolveNodes($code);
    $code = resolveMacros($code);
    $code = resolveStackAccess($code);
    return $code;
}
function resolveNodes($code)
{
    return \preg_replace_callback('~\\b(?<name>[A-Z][a-zA-Z_\\\\]++)\\s*' . \_HumbugBox1cb33d1f20f1\PARAMS . '~', function ($matches) {
        // recurse
        $matches['params'] = resolveNodes($matches['params']);
        $params = magicSplit('(?:' . \_HumbugBox1cb33d1f20f1\PARAMS . '|' . \_HumbugBox1cb33d1f20f1\ARGS . ')(*SKIP)(*FAIL)|,', $matches['params']);
        $paramCode = '';
        foreach ($params as $param) {
            $paramCode .= $param . ', ';
        }
        return 'new ' . $matches['name'] . '(' . $paramCode . 'attributes())';
    }, $code);
}
function resolveMacros($code)
{
    return \preg_replace_callback('~\\b(?<!::|->)(?!array\\()(?<name>[a-z][A-Za-z]++)' . \_HumbugBox1cb33d1f20f1\ARGS . '~', function ($matches) {
        // recurse
        $matches['args'] = resolveMacros($matches['args']);
        $name = $matches['name'];
        $args = magicSplit('(?:' . \_HumbugBox1cb33d1f20f1\PARAMS . '|' . \_HumbugBox1cb33d1f20f1\ARGS . ')(*SKIP)(*FAIL)|,', $matches['args']);
        if ('attributes' === $name) {
            assertArgs(0, $args, $name);
            return '$this->startAttributeStack[#1] + $this->endAttributes';
        }
        if ('stackAttributes' === $name) {
            assertArgs(1, $args, $name);
            return '$this->startAttributeStack[' . $args[0] . ']' . ' + $this->endAttributeStack[' . $args[0] . ']';
        }
        if ('init' === $name) {
            return '$$ = array(' . \implode(', ', $args) . ')';
        }
        if ('push' === $name) {
            assertArgs(2, $args, $name);
            return $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0];
        }
        if ('pushNormalizing' === $name) {
            assertArgs(2, $args, $name);
            return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }' . ' else { ' . $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0] . '; }';
        }
        if ('toArray' == $name) {
            assertArgs(1, $args, $name);
            return 'is_array(' . $args[0] . ') ? ' . $args[0] . ' : array(' . $args[0] . ')';
        }
        if ('parseVar' === $name) {
            assertArgs(1, $args, $name);
            return 'substr(' . $args[0] . ', 1)';
        }
        if ('parseEncapsed' === $name) {
            assertArgs(3, $args, $name);
            return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\\Scalar\\EncapsedStringPart) {' . ' $s->value = Node\\Scalar\\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }';
        }
        if ('makeNop' === $name) {
            assertArgs(3, $args, $name);
            return '$startAttributes = ' . $args[1] . ';' . ' if (isset($startAttributes[\'comments\']))' . ' { ' . $args[0] . ' = new Stmt\\Nop($startAttributes + ' . $args[2] . '); }' . ' else { ' . $args[0] . ' = null; }';
        }
        if ('makeZeroLengthNop' == $name) {
            assertArgs(2, $args, $name);
            return '$startAttributes = ' . $args[1] . ';' . ' if (isset($startAttributes[\'comments\']))' . ' { ' . $args[0] . ' = new Stmt\\Nop($this->createCommentNopAttributes($startAttributes[\'comments\'])); }' . ' else { ' . $args[0] . ' = null; }';
        }
        if ('prependLeadingComments' === $name) {
            assertArgs(1, $args, $name);
            return '$attrs = $this->startAttributeStack[#1]; $stmts = ' . $args[0] . '; ' . 'if (!empty($attrs[\'comments\'])) {' . '$stmts[0]->setAttribute(\'comments\', ' . 'array_merge($attrs[\'comments\'], $stmts[0]->getAttribute(\'comments\', []))); }';
        }
        return $matches[0];
    }, $code);
}
function assertArgs($num, $args, $name)
{
    if ($num != \count($args)) {
        die('Wrong argument count for ' . $name . '().');
    }
}
function resolveStackAccess($code)
{
    $code = \preg_replace('/\\$\\d+/', '$this->semStack[$0]', $code);
    $code = \preg_replace('/#(\\d+)/', '$$1', $code);
    return $code;
}
function removeTrailingWhitespace($code)
{
    $lines = \explode("\n", $code);
    $lines = \array_map('rtrim', $lines);
    return \implode("\n", $lines);
}
//////////////////////////////
/// Regex helper functions ///
//////////////////////////////
function regex($regex)
{
    return '~' . \_HumbugBox1cb33d1f20f1\LIB . '(?:' . \str_replace('~', '\\~', $regex) . ')~';
}
function magicSplit($regex, $string)
{
    $pieces = \preg_split(regex('(?:(?&string)|(?&comment)|(?&code))(*SKIP)(*FAIL)|' . $regex), $string);
    foreach ($pieces as &$piece) {
        $piece = \trim($piece);
    }
    if ($pieces === ['']) {
        return [];
    }
    return $pieces;
}
<?php

namespace _HumbugBox1cb33d1f20f1;

require __DIR__ . '/phpyLang.php';
$grammarFileToName = [__DIR__ . '/php5.y' => 'Php5', __DIR__ . '/php7.y' => 'Php7'];
$tokensFile = __DIR__ . '/tokens.y';
$tokensTemplate = __DIR__ . '/tokens.template';
$skeletonFile = __DIR__ . '/parser.template';
$tmpGrammarFile = __DIR__ . '/tmp_parser.phpy';
$tmpResultFile = __DIR__ . '/tmp_parser.php';
$resultDir = __DIR__ . '/../lib/PhpParser/Parser';
$tokensResultsFile = $resultDir . '/Tokens.php';
$kmyacc = \getenv('KMYACC');
if (!$kmyacc) {
    // Use phpyacc from dev dependencies by default.
    $kmyacc = __DIR__ . '/../vendor/bin/phpyacc';
}
$options = \array_flip($argv);
$optionDebug = isset($options['--debug']);
$optionKeepTmpGrammar = isset($options['--keep-tmp-grammar']);
///////////////////
/// Main script ///
///////////////////
$tokens = \file_get_contents($tokensFile);
foreach ($grammarFileToName as $grammarFile => $name) {
    echo "Building temporary {$name} grammar file.\n";
    $grammarCode = \file_get_contents($grammarFile);
    $grammarCode = \str_replace('%tokens', $tokens, $grammarCode);
    $grammarCode = preprocessGrammar($grammarCode);
    \file_put_contents($tmpGrammarFile, $grammarCode);
    $additionalArgs = $optionDebug ? '-t -v' : '';
    echo "Building {$name} parser.\n";
    $output = execCmd("{$kmyacc} {$additionalArgs} -m {$skeletonFile} -p {$name} {$tmpGrammarFile}");
    $resultCode = \file_get_contents($tmpResultFile);
    $resultCode = removeTrailingWhitespace($resultCode);
    ensureDirExists($resultDir);
    \file_put_contents("{$resultDir}/{$name}.php", $resultCode);
    \unlink($tmpResultFile);
    echo "Building token definition.\n";
    $output = execCmd("{$kmyacc} -m {$tokensTemplate} {$tmpGrammarFile}");
    \rename($tmpResultFile, $tokensResultsFile);
    if (!$optionKeepTmpGrammar) {
        \unlink($tmpGrammarFile);
    }
}
////////////////////////////////
/// Utility helper functions ///
////////////////////////////////
function ensureDirExists($dir)
{
    if (!\is_dir($dir)) {
        \mkdir($dir, 0777, \true);
    }
}
function execCmd($cmd)
{
    $output = \trim(\shell_exec("{$cmd} 2>&1"));
    if ($output !== "") {
        echo "> " . $cmd . "\n";
        echo $output;
    }
    return $output;
}
/* We currently rely on the token ID mapping to be the same between PHP 5 and PHP 7 - so the same lexer can be used for
 * both. This is enforced by sharing this token file. */

%right T_THROW
%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE
%left ','
%left T_LOGICAL_OR
%left T_LOGICAL_XOR
%left T_LOGICAL_AND
%right T_PRINT
%right T_YIELD
%right T_DOUBLE_ARROW
%right T_YIELD_FROM
%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL T_COALESCE_EQUAL
%left '?' ':'
%right T_COALESCE
%left T_BOOLEAN_OR
%left T_BOOLEAN_AND
%left '|'
%left '^'
%left T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP
%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
%left T_SL T_SR
%left '+' '-' '.'
%left '*' '/' '%'
%right '!'
%nonassoc T_INSTANCEOF
%right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
%right T_POW
%right '['
%nonassoc T_NEW T_CLONE
%token T_EXIT
%token T_IF
%left T_ELSEIF
%left T_ELSE
%left T_ENDIF
%token T_LNUMBER
%token T_DNUMBER
%token T_STRING
%token T_STRING_VARNAME
%token T_VARIABLE
%token T_NUM_STRING
%token T_INLINE_HTML
%token T_ENCAPSED_AND_WHITESPACE
%token T_CONSTANT_ENCAPSED_STRING
%token T_ECHO
%token T_DO
%token T_WHILE
%token T_ENDWHILE
%token T_FOR
%token T_ENDFOR
%token T_FOREACH
%token T_ENDFOREACH
%token T_DECLARE
%token T_ENDDECLARE
%token T_AS
%token T_SWITCH
%token T_MATCH
%token T_ENDSWITCH
%token T_CASE
%token T_DEFAULT
%token T_BREAK
%token T_CONTINUE
%token T_GOTO
%token T_FUNCTION
%token T_FN
%token T_CONST
%token T_RETURN
%token T_TRY
%token T_CATCH
%token T_FINALLY
%token T_THROW
%token T_USE
%token T_INSTEADOF
%token T_GLOBAL
%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC T_READONLY
%token T_VAR
%token T_UNSET
%token T_ISSET
%token T_EMPTY
%token T_HALT_COMPILER
%token T_CLASS
%token T_TRAIT
%token T_INTERFACE
%token T_ENUM
%token T_EXTENDS
%token T_IMPLEMENTS
%token T_OBJECT_OPERATOR
%token T_NULLSAFE_OBJECT_OPERATOR
%token T_DOUBLE_ARROW
%token T_LIST
%token T_ARRAY
%token T_CALLABLE
%token T_CLASS_C
%token T_TRAIT_C
%token T_METHOD_C
%token T_FUNC_C
%token T_LINE
%token T_FILE
%token T_START_HEREDOC
%token T_END_HEREDOC
%token T_DOLLAR_OPEN_CURLY_BRACES
%token T_CURLY_OPEN
%token T_PAAMAYIM_NEKUDOTAYIM
%token T_NAMESPACE
%token T_NS_C
%token T_DIR
%token T_NS_SEPARATOR
%token T_ELLIPSIS
%token T_NAME_FULLY_QUALIFIED
%token T_NAME_QUALIFIED
%token T_NAME_RELATIVE
%token T_ATTRIBUTE
%token T_ENUM
BSD 3-Clause License

Copyright (c) 2011, Nikita Popov
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#!/usr/bin/env php
<?php 
namespace _HumbugBox1cb33d1f20f1;

foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
    if (\file_exists($file)) {
        require $file;
        break;
    }
}
\ini_set('xdebug.max_nesting_level', 3000);
// Disable Xdebug var_dump() output truncation
\ini_set('xdebug.var_display_max_children', -1);
\ini_set('xdebug.var_display_max_data', -1);
\ini_set('xdebug.var_display_max_depth', -1);
list($operations, $files, $attributes) = parseArgs($argv);
/* Dump nodes by default */
if (empty($operations)) {
    $operations[] = 'dump';
}
if (empty($files)) {
    showHelp("Must specify at least one file.");
}
$lexer = new PhpParser\Lexer\Emulative(['usedAttributes' => ['startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments']]);
$parser = (new PhpParser\ParserFactory())->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer);
$dumper = new PhpParser\NodeDumper(['dumpComments' => \true, 'dumpPositions' => $attributes['with-positions']]);
$prettyPrinter = new PhpParser\PrettyPrinter\Standard();
$traverser = new PhpParser\NodeTraverser();
$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver());
foreach ($files as $file) {
    if (\strpos($file, '<?php') === 0) {
        $code = $file;
        \fwrite(\STDERR, "====> Code {$code}\n");
    } else {
        if (!\file_exists($file)) {
            \fwrite(\STDERR, "File {$file} does not exist.\n");
            exit(1);
        }
        $code = \file_get_contents($file);
        \fwrite(\STDERR, "====> File {$file}:\n");
    }
    if ($attributes['with-recovery']) {
        $errorHandler = new PhpParser\ErrorHandler\Collecting();
        $stmts = $parser->parse($code, $errorHandler);
        foreach ($errorHandler->getErrors() as $error) {
            $message = formatErrorMessage($error, $code, $attributes['with-column-info']);
            \fwrite(\STDERR, $message . "\n");
        }
        if (null === $stmts) {
            continue;
        }
    } else {
        try {
            $stmts = $parser->parse($code);
        } catch (PhpParser\Error $error) {
            $message = formatErrorMessage($error, $code, $attributes['with-column-info']);
            \fwrite(\STDERR, $message . "\n");
            exit(1);
        }
    }
    foreach ($operations as $operation) {
        if ('dump' === $operation) {
            \fwrite(\STDERR, "==> Node dump:\n");
            echo $dumper->dump($stmts, $code), "\n";
        } elseif ('pretty-print' === $operation) {
            \fwrite(\STDERR, "==> Pretty print:\n");
            echo $prettyPrinter->prettyPrintFile($stmts), "\n";
        } elseif ('json-dump' === $operation) {
            \fwrite(\STDERR, "==> JSON dump:\n");
            echo \json_encode($stmts, \JSON_PRETTY_PRINT), "\n";
        } elseif ('var-dump' === $operation) {
            \fwrite(\STDERR, "==> var_dump():\n");
            \var_dump($stmts);
        } elseif ('resolve-names' === $operation) {
            \fwrite(\STDERR, "==> Resolved names.\n");
            $stmts = $traverser->traverse($stmts);
        }
    }
}
function formatErrorMessage(PhpParser\Error $e, $code, $withColumnInfo)
{
    if ($withColumnInfo && $e->hasColumnInfo()) {
        return $e->getMessageWithColumnInfo($code);
    } else {
        return $e->getMessage();
    }
}
function showHelp($error = '')
{
    if ($error) {
        \fwrite(\STDERR, $error . "\n\n");
    }
    \fwrite($error ? \STDERR : \STDOUT, <<<OUTPUT
Usage: php-parse [operations] file1.php [file2.php ...]
   or: php-parse [operations] "<?php code"
Turn PHP source code into an abstract syntax tree.

Operations is a list of the following options (--dump by default):

    -d, --dump              Dump nodes using NodeDumper
    -p, --pretty-print      Pretty print file using PrettyPrinter\\Standard
    -j, --json-dump         Print json_encode() result
        --var-dump          var_dump() nodes (for exact structure)
    -N, --resolve-names     Resolve names using NodeVisitor\\NameResolver
    -c, --with-column-info  Show column-numbers for errors (if available)
    -P, --with-positions    Show positions in node dumps
    -r, --with-recovery     Use parsing with error recovery
    -h, --help              Display this page

Example:
    php-parse -d -p -N -d file.php

    Dumps nodes, pretty prints them, then resolves names and dumps them again.


OUTPUT
);
    exit($error ? 1 : 0);
}
function parseArgs($args)
{
    $operations = [];
    $files = [];
    $attributes = ['with-column-info' => \false, 'with-positions' => \false, 'with-recovery' => \false];
    \array_shift($args);
    $parseOptions = \true;
    foreach ($args as $arg) {
        if (!$parseOptions) {
            $files[] = $arg;
            continue;
        }
        switch ($arg) {
            case '--dump':
            case '-d':
                $operations[] = 'dump';
                break;
            case '--pretty-print':
            case '-p':
                $operations[] = 'pretty-print';
                break;
            case '--json-dump':
            case '-j':
                $operations[] = 'json-dump';
                break;
            case '--var-dump':
                $operations[] = 'var-dump';
                break;
            case '--resolve-names':
            case '-N':
                $operations[] = 'resolve-names';
                break;
            case '--with-column-info':
            case '-c':
                $attributes['with-column-info'] = \true;
                break;
            case '--with-positions':
            case '-P':
                $attributes['with-positions'] = \true;
                break;
            case '--with-recovery':
            case '-r':
                $attributes['with-recovery'] = \true;
                break;
            case '--help':
            case '-h':
                showHelp();
                break;
            case '--':
                $parseOptions = \false;
                break;
            default:
                if ($arg[0] === '-') {
                    showHelp("Invalid operation {$arg}.");
                } else {
                    $files[] = $arg;
                }
        }
    }
    return [$operations, $files, $attributes];
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

interface PseudoType extends Type
{
    public function underlyingType() : Type;
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context;
use function explode;
use function implode;
use function strpos;
/**
 * Resolver for Fqsen using Context information
 *
 * @psalm-immutable
 */
class FqsenResolver
{
    /** @var string Definition of the NAMESPACE operator in PHP */
    private const OPERATOR_NAMESPACE = '\\';
    public function resolve(string $fqsen, ?Context $context = null) : Fqsen
    {
        if ($context === null) {
            $context = new Context('');
        }
        if ($this->isFqsen($fqsen)) {
            return new Fqsen($fqsen);
        }
        return $this->resolvePartialStructuralElementName($fqsen, $context);
    }
    /**
     * Tests whether the given type is a Fully Qualified Structural Element Name.
     */
    private function isFqsen(string $type) : bool
    {
        return strpos($type, self::OPERATOR_NAMESPACE) === 0;
    }
    /**
     * Resolves a partial Structural Element Name (i.e. `Reflection\DocBlock`) to its FQSEN representation
     * (i.e. `\phpDocumentor\Reflection\DocBlock`) based on the Namespace and aliases mentioned in the Context.
     *
     * @throws InvalidArgumentException When type is not a valid FQSEN.
     */
    private function resolvePartialStructuralElementName(string $type, Context $context) : Fqsen
    {
        $typeParts = explode(self::OPERATOR_NAMESPACE, $type, 2);
        $namespaceAliases = $context->getNamespaceAliases();
        // if the first segment is not an alias; prepend namespace name and return
        if (!isset($namespaceAliases[$typeParts[0]])) {
            $namespace = $context->getNamespace();
            if ($namespace !== '') {
                $namespace .= self::OPERATOR_NAMESPACE;
            }
            return new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type);
        }
        $typeParts[0] = $namespaceAliases[$typeParts[0]];
        return new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts));
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a Callable type.
 *
 * @psalm-immutable
 */
final class Callable_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'callable';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the 'scalar' pseudo-type, which is either a string, integer, float or boolean.
 *
 * @psalm-immutable
 */
final class Scalar implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'scalar';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use ArrayIterator;
use InvalidArgumentException;
use ReflectionClass;
use ReflectionClassConstant;
use ReflectionMethod;
use ReflectionParameter;
use ReflectionProperty;
use Reflector;
use RuntimeException;
use UnexpectedValueException;
use function define;
use function defined;
use function file_exists;
use function file_get_contents;
use function get_class;
use function in_array;
use function is_string;
use function strrpos;
use function substr;
use function token_get_all;
use function trim;
use const T_AS;
use const T_CLASS;
use const T_CURLY_OPEN;
use const T_DOLLAR_OPEN_CURLY_BRACES;
use const T_NAME_FULLY_QUALIFIED;
use const T_NAME_QUALIFIED;
use const T_NAMESPACE;
use const T_NS_SEPARATOR;
use const T_STRING;
use const T_USE;
if (!defined('T_NAME_QUALIFIED')) {
    define('T_NAME_QUALIFIED', 'T_NAME_QUALIFIED');
}
if (!defined('T_NAME_FULLY_QUALIFIED')) {
    define('T_NAME_FULLY_QUALIFIED', 'T_NAME_FULLY_QUALIFIED');
}
/**
 * Convenience class to create a Context for DocBlocks when not using the Reflection Component of phpDocumentor.
 *
 * For a DocBlock to be able to resolve types that use partial namespace names or rely on namespace imports we need to
 * provide a bit of context so that the DocBlock can read that and based on it decide how to resolve the types to
 * Fully Qualified names.
 *
 * @see Context for more information.
 */
final class ContextFactory
{
    /** The literal used at the end of a use statement. */
    private const T_LITERAL_END_OF_USE = ';';
    /** The literal used between sets of use statements */
    private const T_LITERAL_USE_SEPARATOR = ',';
    /**
     * Build a Context given a Class Reflection.
     *
     * @see Context for more information on Contexts.
     */
    public function createFromReflector(Reflector $reflector) : Context
    {
        if ($reflector instanceof ReflectionClass) {
            //phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable
            /** @var ReflectionClass<object> $reflector */
            return $this->createFromReflectionClass($reflector);
        }
        if ($reflector instanceof ReflectionParameter) {
            return $this->createFromReflectionParameter($reflector);
        }
        if ($reflector instanceof ReflectionMethod) {
            return $this->createFromReflectionMethod($reflector);
        }
        if ($reflector instanceof ReflectionProperty) {
            return $this->createFromReflectionProperty($reflector);
        }
        if ($reflector instanceof ReflectionClassConstant) {
            return $this->createFromReflectionClassConstant($reflector);
        }
        throw new UnexpectedValueException('Unhandled \\Reflector instance given:  ' . get_class($reflector));
    }
    private function createFromReflectionParameter(ReflectionParameter $parameter) : Context
    {
        $class = $parameter->getDeclaringClass();
        if (!$class) {
            throw new InvalidArgumentException('Unable to get class of ' . $parameter->getName());
        }
        return $this->createFromReflectionClass($class);
    }
    private function createFromReflectionMethod(ReflectionMethod $method) : Context
    {
        $class = $method->getDeclaringClass();
        return $this->createFromReflectionClass($class);
    }
    private function createFromReflectionProperty(ReflectionProperty $property) : Context
    {
        $class = $property->getDeclaringClass();
        return $this->createFromReflectionClass($class);
    }
    private function createFromReflectionClassConstant(ReflectionClassConstant $constant) : Context
    {
        //phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable
        /** @phpstan-var ReflectionClass<object> $class */
        $class = $constant->getDeclaringClass();
        return $this->createFromReflectionClass($class);
    }
    /**
     * @phpstan-param ReflectionClass<object> $class
     */
    private function createFromReflectionClass(ReflectionClass $class) : Context
    {
        $fileName = $class->getFileName();
        $namespace = $class->getNamespaceName();
        if (is_string($fileName) && file_exists($fileName)) {
            $contents = file_get_contents($fileName);
            if ($contents === \false) {
                throw new RuntimeException('Unable to read file "' . $fileName . '"');
            }
            return $this->createForNamespace($namespace, $contents);
        }
        return new Context($namespace, []);
    }
    /**
     * Build a Context for a namespace in the provided file contents.
     *
     * @see Context for more information on Contexts.
     *
     * @param string $namespace    It does not matter if a `\` precedes the namespace name,
     * this method first normalizes.
     * @param string $fileContents The file's contents to retrieve the aliases from with the given namespace.
     */
    public function createForNamespace(string $namespace, string $fileContents) : Context
    {
        $namespace = trim($namespace, '\\');
        $useStatements = [];
        $currentNamespace = '';
        $tokens = new ArrayIterator(token_get_all($fileContents));
        while ($tokens->valid()) {
            $currentToken = $tokens->current();
            switch ($currentToken[0]) {
                case T_NAMESPACE:
                    $currentNamespace = $this->parseNamespace($tokens);
                    break;
                case T_CLASS:
                    // Fast-forward the iterator through the class so that any
                    // T_USE tokens found within are skipped - these are not
                    // valid namespace use statements so should be ignored.
                    $braceLevel = 0;
                    $firstBraceFound = \false;
                    while ($tokens->valid() && ($braceLevel > 0 || !$firstBraceFound)) {
                        $currentToken = $tokens->current();
                        if ($currentToken === '{' || in_array($currentToken[0], [T_CURLY_OPEN, T_DOLLAR_OPEN_CURLY_BRACES], \true)) {
                            if (!$firstBraceFound) {
                                $firstBraceFound = \true;
                            }
                            ++$braceLevel;
                        }
                        if ($currentToken === '}') {
                            --$braceLevel;
                        }
                        $tokens->next();
                    }
                    break;
                case T_USE:
                    if ($currentNamespace === $namespace) {
                        $useStatements += $this->parseUseStatement($tokens);
                    }
                    break;
            }
            $tokens->next();
        }
        return new Context($namespace, $useStatements);
    }
    /**
     * Deduce the name from tokens when we are at the T_NAMESPACE token.
     *
     * @param ArrayIterator<int, string|array{0:int,1:string,2:int}> $tokens
     */
    private function parseNamespace(ArrayIterator $tokens) : string
    {
        // skip to the first string or namespace separator
        $this->skipToNextStringOrNamespaceSeparator($tokens);
        $name = '';
        $acceptedTokens = [T_STRING, T_NS_SEPARATOR, T_NAME_QUALIFIED];
        while ($tokens->valid() && in_array($tokens->current()[0], $acceptedTokens, \true)) {
            $name .= $tokens->current()[1];
            $tokens->next();
        }
        return $name;
    }
    /**
     * Deduce the names of all imports when we are at the T_USE token.
     *
     * @param ArrayIterator<int, string|array{0:int,1:string,2:int}> $tokens
     *
     * @return string[]
     * @psalm-return array<string, string>
     */
    private function parseUseStatement(ArrayIterator $tokens) : array
    {
        $uses = [];
        while ($tokens->valid()) {
            $this->skipToNextStringOrNamespaceSeparator($tokens);
            $uses += $this->extractUseStatements($tokens);
            $currentToken = $tokens->current();
            if ($currentToken[0] === self::T_LITERAL_END_OF_USE) {
                return $uses;
            }
        }
        return $uses;
    }
    /**
     * Fast-forwards the iterator as longs as we don't encounter a T_STRING or T_NS_SEPARATOR token.
     *
     * @param ArrayIterator<int, string|array{0:int,1:string,2:int}> $tokens
     */
    private function skipToNextStringOrNamespaceSeparator(ArrayIterator $tokens) : void
    {
        while ($tokens->valid()) {
            $currentToken = $tokens->current();
            if (in_array($currentToken[0], [T_STRING, T_NS_SEPARATOR], \true)) {
                break;
            }
            if ($currentToken[0] === T_NAME_QUALIFIED) {
                break;
            }
            if (defined('T_NAME_FULLY_QUALIFIED') && $currentToken[0] === T_NAME_FULLY_QUALIFIED) {
                break;
            }
            $tokens->next();
        }
    }
    /**
     * Deduce the namespace name and alias of an import when we are at the T_USE token or have not reached the end of
     * a USE statement yet. This will return a key/value array of the alias => namespace.
     *
     * @param ArrayIterator<int, string|array{0:int,1:string,2:int}> $tokens
     *
     * @return string[]
     * @psalm-return array<string, string>
     *
     * @psalm-suppress TypeDoesNotContainType
     */
    private function extractUseStatements(ArrayIterator $tokens) : array
    {
        $extractedUseStatements = [];
        $groupedNs = '';
        $currentNs = '';
        $currentAlias = '';
        $state = 'start';
        while ($tokens->valid()) {
            $currentToken = $tokens->current();
            $tokenId = is_string($currentToken) ? $currentToken : $currentToken[0];
            $tokenValue = is_string($currentToken) ? null : $currentToken[1];
            switch ($state) {
                case 'start':
                    switch ($tokenId) {
                        case T_STRING:
                        case T_NS_SEPARATOR:
                            $currentNs .= (string) $tokenValue;
                            $currentAlias = $tokenValue;
                            break;
                        case T_NAME_QUALIFIED:
                        case T_NAME_FULLY_QUALIFIED:
                            $currentNs .= (string) $tokenValue;
                            $currentAlias = substr((string) $tokenValue, (int) strrpos((string) $tokenValue, '\\') + 1);
                            break;
                        case T_CURLY_OPEN:
                        case '{':
                            $state = 'grouped';
                            $groupedNs = $currentNs;
                            break;
                        case T_AS:
                            $state = 'start-alias';
                            break;
                        case self::T_LITERAL_USE_SEPARATOR:
                        case self::T_LITERAL_END_OF_USE:
                            $state = 'end';
                            break;
                        default:
                            break;
                    }
                    break;
                case 'start-alias':
                    switch ($tokenId) {
                        case T_STRING:
                            $currentAlias = $tokenValue;
                            break;
                        case self::T_LITERAL_USE_SEPARATOR:
                        case self::T_LITERAL_END_OF_USE:
                            $state = 'end';
                            break;
                        default:
                            break;
                    }
                    break;
                case 'grouped':
                    switch ($tokenId) {
                        case T_STRING:
                        case T_NS_SEPARATOR:
                            $currentNs .= (string) $tokenValue;
                            $currentAlias = $tokenValue;
                            break;
                        case T_AS:
                            $state = 'grouped-alias';
                            break;
                        case self::T_LITERAL_USE_SEPARATOR:
                            $state = 'grouped';
                            $extractedUseStatements[(string) $currentAlias] = $currentNs;
                            $currentNs = $groupedNs;
                            $currentAlias = '';
                            break;
                        case self::T_LITERAL_END_OF_USE:
                            $state = 'end';
                            break;
                        default:
                            break;
                    }
                    break;
                case 'grouped-alias':
                    switch ($tokenId) {
                        case T_STRING:
                            $currentAlias = $tokenValue;
                            break;
                        case self::T_LITERAL_USE_SEPARATOR:
                            $state = 'grouped';
                            $extractedUseStatements[(string) $currentAlias] = $currentNs;
                            $currentNs = $groupedNs;
                            $currentAlias = '';
                            break;
                        case self::T_LITERAL_END_OF_USE:
                            $state = 'end';
                            break;
                        default:
                            break;
                    }
            }
            if ($state === 'end') {
                break;
            }
            $tokens->next();
        }
        if ($groupedNs !== $currentNs) {
            $extractedUseStatements[(string) $currentAlias] = $currentNs;
        }
        return $extractedUseStatements;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class InterfaceString implements Type
{
    private ?Fqsen $fqsen;
    /**
     * Initializes this representation of a class string with the given Fqsen.
     */
    public function __construct(?Fqsen $fqsen = null)
    {
        $this->fqsen = $fqsen;
    }
    /**
     * Returns the FQSEN associated with this object.
     */
    public function getFqsen() : ?Fqsen
    {
        return $this->fqsen;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        if ($this->fqsen === null) {
            return 'interface-string';
        }
        return 'interface-string<' . (string) $this->fqsen . '>';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

/**
 * Represents an array type as described in the PSR-5, the PHPDoc Standard.
 *
 * An array can be represented in two forms:
 *
 * 1. Untyped (`array`), where the key and value type is unknown and hence classified as 'Mixed_'.
 * 2. Types (`string[]`), where the value type is provided by preceding an opening and closing square bracket with a
 *    type name.
 *
 * @psalm-immutable
 */
class Array_ extends AbstractList
{
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Represents a collection type as described in the PSR-5, the PHPDoc Standard.
 *
 * A collection can be represented in two forms:
 *
 * 1. `ACollectionObject<aValueType>`
 * 2. `ACollectionObject<aValueType,aKeyType>`
 *
 * - ACollectionObject can be 'array' or an object that can act as an array
 * - aValueType and aKeyType can be any type expression
 *
 * @psalm-immutable
 */
final class Collection extends AbstractList
{
    private ?Fqsen $fqsen;
    /**
     * Initializes this representation of an array with the given Type or Fqsen.
     */
    public function __construct(?Fqsen $fqsen, Type $valueType, ?Type $keyType = null)
    {
        parent::__construct($valueType, $keyType);
        $this->fqsen = $fqsen;
    }
    /**
     * Returns the FQSEN associated with this object.
     */
    public function getFqsen() : ?Fqsen
    {
        return $this->fqsen;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        $objectType = (string) ($this->fqsen ?? 'object');
        if ($this->keyType === null) {
            return $objectType . '<' . $this->valueType . '>';
        }
        return $objectType . '<' . $this->keyType . ',' . $this->valueType . '>';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Represents a list of values. This is an abstract class for Array_ and Collection.
 *
 * @psalm-immutable
 */
abstract class AbstractList implements Type
{
    /** @var Type */
    protected $valueType;
    /** @var Type|null */
    protected $keyType;
    /** @var Type */
    protected $defaultKeyType;
    /**
     * Initializes this representation of an array with the given Type.
     */
    public function __construct(?Type $valueType = null, ?Type $keyType = null)
    {
        if ($valueType === null) {
            $valueType = new Mixed_();
        }
        $this->valueType = $valueType;
        $this->defaultKeyType = new Compound([new String_(), new Integer()]);
        $this->keyType = $keyType;
    }
    /**
     * Returns the type for the keys of this array.
     */
    public function getKeyType() : Type
    {
        return $this->keyType ?? $this->defaultKeyType;
    }
    /**
     * Returns the type for the values of this array.
     */
    public function getValueType() : Type
    {
        return $this->valueType;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        if ($this->keyType) {
            return 'array<' . $this->keyType . ',' . $this->valueType . '>';
        }
        if ($this->valueType instanceof Mixed_) {
            return 'array';
        }
        if ($this->valueType instanceof Compound) {
            return '(' . $this->valueType . ')[]';
        }
        return $this->valueType . '[]';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the 'static' type.
 *
 * Self, as a Type, represents the class in which the associated element was called. This differs from self as self does
 * not take inheritance into account but static means that the return type is always that of the class of the called
 * element.
 *
 * See the documentation on late static binding in the PHP Documentation for more information on the difference between
 * static and self.
 *
 * @psalm-immutable
 */
final class Static_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'static';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the return-type 'void'.
 *
 * Void is generally only used when working with return types as it signifies that the method intentionally does not
 * return any value.
 *
 * @psalm-immutable
 */
final class Void_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'void';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the 'resource' Type.
 *
 * @psalm-immutable
 */
final class Resource_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'resource';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the 'parent' type.
 *
 * Parent, as a Type, represents the parent class of class in which the associated element was defined.
 *
 * @psalm-immutable
 */
final class Parent_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'parent';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the 'self' type.
 *
 * Self, as a Type, represents the class in which the associated element was defined.
 *
 * @psalm-immutable
 */
final class Self_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'self';
    }
}
<?php

/**
 * This file is part of phpDocumentor.
 *
 *  For the full copyright and license information, please view the LICENSE
 *  file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use ArrayIterator;
use IteratorAggregate;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use function array_key_exists;
use function implode;
/**
 * Base class for aggregated types like Compound and Intersection
 *
 * A Aggregated Type is not so much a special keyword or object reference but is a series of Types that are separated
 * using separator.
 *
 * @psalm-immutable
 * @template-implements IteratorAggregate<int, Type>
 */
abstract class AggregatedType implements Type, IteratorAggregate
{
    /**
     * @psalm-allow-private-mutation
     * @var array<int, Type>
     */
    private array $types = [];
    private string $token;
    /**
     * @param array<Type> $types
     */
    public function __construct(array $types, string $token)
    {
        foreach ($types as $type) {
            $this->add($type);
        }
        $this->token = $token;
    }
    /**
     * Returns the type at the given index.
     */
    public function get(int $index) : ?Type
    {
        if (!$this->has($index)) {
            return null;
        }
        return $this->types[$index];
    }
    /**
     * Tests if this compound type has a type with the given index.
     */
    public function has(int $index) : bool
    {
        return array_key_exists($index, $this->types);
    }
    /**
     * Tests if this compound type contains the given type.
     */
    public function contains(Type $type) : bool
    {
        foreach ($this->types as $typePart) {
            // if the type is duplicate; do not add it
            if ((string) $typePart === (string) $type) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return implode($this->token, $this->types);
    }
    /**
     * @return ArrayIterator<int, Type>
     */
    public function getIterator() : ArrayIterator
    {
        return new ArrayIterator($this->types);
    }
    /**
     * @psalm-suppress ImpureMethodCall
     */
    private function add(Type $type) : void
    {
        if ($type instanceof self) {
            foreach ($type->getIterator() as $subType) {
                $this->add($subType);
            }
            return;
        }
        // if the type is duplicate; do not add it
        if ($this->contains($type)) {
            return;
        }
        $this->types[] = $type;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a Compound Type.
 *
 * A Compound Type is not so much a special keyword or object reference but is a series of Types that are separated
 * using an OR operator (`|`). This combination of types signifies that whatever is associated with this compound type
 * may contain a value with any of the given types.
 *
 * @psalm-immutable
 */
final class Compound extends AggregatedType
{
    /**
     * Initializes a compound type (i.e. `string|int`) and tests if the provided types all implement the Type interface.
     *
     * @param array<Type> $types
     */
    public function __construct(array $types)
    {
        parent::__construct($types, '|');
    }
}
<?php

/**
 * This file is part of phpDocumentor.
 *
 *  For the full copyright and license information, please view the LICENSE
 *  file that was distributed with this source code.
 *
 *  @link      http://phpdoc.org
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a Compound Type.
 *
 * A Intersection Type is not so much a special keyword or object reference but is a series of Types that are separated
 * using an AND operator (`&`). This combination of types signifies that whatever is associated with this Intersection
 * type may contain a value with any of the given types.
 *
 * @psalm-immutable
 */
final class Intersection extends AggregatedType
{
    /**
     * Initializes a intersection type (i.e. `\A&\B`) and tests if the provided types all implement the Type interface.
     *
     * @param array<Type> $types
     */
    public function __construct(array $types)
    {
        parent::__construct($types, '&');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a array-key Type.
 *
 * A array-key Type is the supertype (but not a union) of int and string.
 *
 * @psalm-immutable
 */
final class ArrayKey extends AggregatedType implements PseudoType
{
    public function __construct()
    {
        parent::__construct([new String_(), new Integer()], '|');
    }
    public function underlyingType() : Type
    {
        return new Compound([new String_(), new Integer()]);
    }
    public function __toString() : string
    {
        return 'array-key';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Represents an expression type as described in the PSR-5, the PHPDoc Standard.
 *
 * @psalm-immutable
 */
final class Expression implements Type
{
    protected Type $valueType;
    /**
     * Initializes this representation of an array with the given Type.
     */
    public function __construct(Type $valueType)
    {
        $this->valueType = $valueType;
    }
    /**
     * Returns the value for the keys of this array.
     */
    public function getValueType() : Type
    {
        return $this->valueType;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return '(' . $this->valueType . ')';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
class String_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use function strlen;
use function substr;
use function trim;
/**
 * Provides information about the Context in which the DocBlock occurs that receives this context.
 *
 * A DocBlock does not know of its own accord in which namespace it occurs and which namespace aliases are applicable
 * for the block of code in which it is in. This information is however necessary to resolve Class names in tags since
 * you can provide a short form or make use of namespace aliases.
 *
 * The phpDocumentor Reflection component knows how to create this class but if you use the DocBlock parser from your
 * own application it is possible to generate a Context class using the ContextFactory; this will analyze the file in
 * which an associated class resides for its namespace and imports.
 *
 * @see ContextFactory::createFromClassReflector()
 * @see ContextFactory::createForNamespace()
 *
 * @psalm-immutable
 */
final class Context
{
    /** @var string The current namespace. */
    private string $namespace;
    /**
     * @var string[] List of namespace aliases => Fully Qualified Namespace.
     * @psalm-var array<string, string>
     */
    private array $namespaceAliases;
    /**
     * Initializes the new context and normalizes all passed namespaces to be in Qualified Namespace Name (QNN)
     * format (without a preceding `\`).
     *
     * @param string   $namespace        The namespace where this DocBlock resides in.
     * @param string[] $namespaceAliases List of namespace aliases => Fully Qualified Namespace.
     * @psalm-param array<string, string> $namespaceAliases
     */
    public function __construct(string $namespace, array $namespaceAliases = [])
    {
        $this->namespace = $namespace !== 'global' && $namespace !== 'default' ? trim($namespace, '\\') : '';
        foreach ($namespaceAliases as $alias => $fqnn) {
            if ($fqnn[0] === '\\') {
                $fqnn = substr($fqnn, 1);
            }
            if ($fqnn[strlen($fqnn) - 1] === '\\') {
                $fqnn = substr($fqnn, 0, -1);
            }
            $namespaceAliases[$alias] = $fqnn;
        }
        $this->namespaceAliases = $namespaceAliases;
    }
    /**
     * Returns the Qualified Namespace Name (thus without `\` in front) where the associated element is in.
     */
    public function getNamespace() : string
    {
        return $this->namespace;
    }
    /**
     * Returns a list of Qualified Namespace Names (thus without `\` in front) that are imported, the keys represent
     * the alias for the imported Namespace.
     *
     * @return string[]
     * @psalm-return array<string, string>
     */
    public function getNamespaceAliases() : array
    {
        return $this->namespaceAliases;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class ClassString extends String_ implements PseudoType
{
    private ?Fqsen $fqsen;
    /**
     * Initializes this representation of a class string with the given Fqsen.
     */
    public function __construct(?Fqsen $fqsen = null)
    {
        $this->fqsen = $fqsen;
    }
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns the FQSEN associated with this object.
     */
    public function getFqsen() : ?Fqsen
    {
        return $this->fqsen;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        if ($this->fqsen === null) {
            return 'class-string';
        }
        return 'class-string<' . (string) $this->fqsen . '>';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a null value or type.
 *
 * @psalm-immutable
 */
final class Null_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'null';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a nullable type. The real type is wrapped.
 *
 * @psalm-immutable
 */
final class Nullable implements Type
{
    /** @var Type The actual type that is wrapped */
    private Type $realType;
    /**
     * Initialises this nullable type using the real type embedded
     */
    public function __construct(Type $realType)
    {
        $this->realType = $realType;
    }
    /**
     * Provide access to the actual type directly, if needed.
     */
    public function getActualType() : Type
    {
        return $this->realType;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return '?' . $this->realType->__toString();
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a Boolean type.
 *
 * @psalm-immutable
 */
class Boolean implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'bool';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing an unknown, or mixed, type.
 *
 * @psalm-immutable
 */
final class Mixed_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'mixed';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the '$this' pseudo-type.
 *
 * $this, as a Type, represents the instance of the class associated with the element as it was called. $this is
 * commonly used when documenting fluent interfaces since it represents that the same object is returned.
 *
 * @psalm-immutable
 */
final class This implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return '$this';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing the return-type 'never'.
 *
 * Never is generally only used when working with return types as it signifies that the method that only
 * ever throw or exit.
 *
 * @psalm-immutable
 */
final class Never_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'never';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value Object representing a Float.
 *
 * @psalm-immutable
 */
final class Float_ implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'float';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
/**
 * Value object representing Integer type
 *
 * @psalm-immutable
 */
class Integer implements Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'int';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use function strpos;
/**
 * Value Object representing an object.
 *
 * An object can be either typed or untyped. When an object is typed it means that it has an identifier, the FQSEN,
 * pointing to an element in PHP. Object types that are untyped do not refer to a specific class but represent objects
 * in general.
 *
 * @psalm-immutable
 */
final class Object_ implements Type
{
    private ?Fqsen $fqsen;
    /**
     * Initializes this object with an optional FQSEN, if not provided this object is considered 'untyped'.
     *
     * @throws InvalidArgumentException When provided $fqsen is not a valid type.
     */
    public function __construct(?Fqsen $fqsen = null)
    {
        if (strpos((string) $fqsen, '::') !== \false || strpos((string) $fqsen, '()') !== \false) {
            throw new InvalidArgumentException('Object types can only refer to a class, interface or trait but a method, function, constant or ' . 'property was received: ' . (string) $fqsen);
        }
        $this->fqsen = $fqsen;
    }
    /**
     * Returns the FQSEN associated with this object.
     */
    public function getFqsen() : ?Fqsen
    {
        return $this->fqsen;
    }
    public function __toString() : string
    {
        if ($this->fqsen) {
            return (string) $this->fqsen;
        }
        return 'object';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;

/**
 * Value Object representing iterable type
 *
 * @psalm-immutable
 */
final class Iterable_ extends AbstractList
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        if ($this->keyType) {
            return 'iterable<' . $this->keyType . ',' . $this->valueType . '>';
        }
        if ($this->valueType instanceof Mixed_) {
            return 'iterable';
        }
        return 'iterable<' . $this->valueType . '>';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

use ArrayIterator;
use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\CallableString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\False_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\HtmlEscapedString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\IntegerRange;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\List_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\LiteralString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\LowercaseString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\NegativeInteger;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\NonEmptyLowercaseString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\NonEmptyString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\Numeric_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\NumericString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\PositiveInteger;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\TraitString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes\True_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Array_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\ArrayKey;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Boolean;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Callable_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\ClassString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Collection;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Compound;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Expression;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Float_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Integer;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\InterfaceString;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Intersection;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Iterable_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Mixed_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Never_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Null_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Nullable;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Object_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Parent_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Resource_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Scalar;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Self_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Static_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\This;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Void_;
use RuntimeException;
use function array_key_exists;
use function array_key_last;
use function array_pop;
use function array_values;
use function class_exists;
use function class_implements;
use function count;
use function current;
use function in_array;
use function is_numeric;
use function preg_split;
use function strpos;
use function strtolower;
use function trim;
use const PREG_SPLIT_DELIM_CAPTURE;
use const PREG_SPLIT_NO_EMPTY;
final class TypeResolver
{
    /** @var string Definition of the ARRAY operator for types */
    private const OPERATOR_ARRAY = '[]';
    /** @var string Definition of the NAMESPACE operator in PHP */
    private const OPERATOR_NAMESPACE = '\\';
    /** @var int the iterator parser is inside a compound context */
    private const PARSER_IN_COMPOUND = 0;
    /** @var int the iterator parser is inside a nullable expression context */
    private const PARSER_IN_NULLABLE = 1;
    /** @var int the iterator parser is inside an array expression context */
    private const PARSER_IN_ARRAY_EXPRESSION = 2;
    /** @var int the iterator parser is inside a collection expression context */
    private const PARSER_IN_COLLECTION_EXPRESSION = 3;
    /**
     * @var array<string, string> List of recognized keywords and unto which Value Object they map
     * @psalm-var array<string, class-string<Type>>
     */
    private array $keywords = ['string' => String_::class, 'class-string' => ClassString::class, 'interface-string' => InterfaceString::class, 'html-escaped-string' => HtmlEscapedString::class, 'lowercase-string' => LowercaseString::class, 'non-empty-lowercase-string' => NonEmptyLowercaseString::class, 'non-empty-string' => NonEmptyString::class, 'numeric-string' => NumericString::class, 'numeric' => Numeric_::class, 'trait-string' => TraitString::class, 'int' => Integer::class, 'integer' => Integer::class, 'positive-int' => PositiveInteger::class, 'negative-int' => NegativeInteger::class, 'bool' => Boolean::class, 'boolean' => Boolean::class, 'real' => Float_::class, 'float' => Float_::class, 'double' => Float_::class, 'object' => Object_::class, 'mixed' => Mixed_::class, 'array' => Array_::class, 'array-key' => ArrayKey::class, 'resource' => Resource_::class, 'void' => Void_::class, 'null' => Null_::class, 'scalar' => Scalar::class, 'callback' => Callable_::class, 'callable' => Callable_::class, 'callable-string' => CallableString::class, 'false' => False_::class, 'true' => True_::class, 'literal-string' => LiteralString::class, 'self' => Self_::class, '$this' => This::class, 'static' => Static_::class, 'parent' => Parent_::class, 'iterable' => Iterable_::class, 'never' => Never_::class, 'list' => List_::class];
    /** @psalm-readonly */
    private FqsenResolver $fqsenResolver;
    /**
     * Initializes this TypeResolver with the means to create and resolve Fqsen objects.
     */
    public function __construct(?FqsenResolver $fqsenResolver = null)
    {
        $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver();
    }
    /**
     * Analyzes the given type and returns the FQCN variant.
     *
     * When a type is provided this method checks whether it is not a keyword or
     * Fully Qualified Class Name. If so it will use the given namespace and
     * aliases to expand the type to a FQCN representation.
     *
     * This method only works as expected if the namespace and aliases are set;
     * no dynamic reflection is being performed here.
     *
     * @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be
     * replaced with another namespace.
     * @uses Context::getNamespace()        to determine with what to prefix the type name.
     *
     * @param string $type The relative or absolute type.
     */
    public function resolve(string $type, ?Context $context = null) : Type
    {
        $type = trim($type);
        if (!$type) {
            throw new InvalidArgumentException('Attempted to resolve "' . $type . '" but it appears to be empty');
        }
        if ($context === null) {
            $context = new Context('');
        }
        // split the type string into tokens `|`, `?`, `<`, `>`, `,`, `(`, `)`, `[]`, '<', '>' and type names
        $tokens = preg_split('/(\\||\\?|<|>|&|, ?|\\(|\\)|\\[\\]+)/', $type, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
        if ($tokens === \false) {
            throw new InvalidArgumentException('Unable to split the type string "' . $type . '" into tokens');
        }
        /** @var ArrayIterator<int, string|null> $tokenIterator */
        $tokenIterator = new ArrayIterator($tokens);
        return $this->parseTypes($tokenIterator, $context, self::PARSER_IN_COMPOUND);
    }
    /**
     * Analyse each tokens and creates types
     *
     * @param ArrayIterator<int, string|null> $tokens        the iterator on tokens
     * @param int                        $parserContext on of self::PARSER_* constants, indicating
     * the context where we are in the parsing
     */
    private function parseTypes(ArrayIterator $tokens, Context $context, int $parserContext) : Type
    {
        $types = [];
        $token = '';
        $compoundToken = '|';
        while ($tokens->valid()) {
            $token = $tokens->current();
            if ($token === null) {
                throw new RuntimeException('Unexpected nullable character');
            }
            if ($token === '|' || $token === '&') {
                if (count($types) === 0) {
                    throw new RuntimeException('A type is missing before a type separator');
                }
                if (!in_array($parserContext, [self::PARSER_IN_COMPOUND, self::PARSER_IN_ARRAY_EXPRESSION, self::PARSER_IN_COLLECTION_EXPRESSION, self::PARSER_IN_NULLABLE], \true)) {
                    throw new RuntimeException('Unexpected type separator');
                }
                $compoundToken = $token;
                $tokens->next();
            } elseif ($token === '?') {
                if (!in_array($parserContext, [self::PARSER_IN_COMPOUND, self::PARSER_IN_ARRAY_EXPRESSION, self::PARSER_IN_COLLECTION_EXPRESSION, self::PARSER_IN_NULLABLE], \true)) {
                    throw new RuntimeException('Unexpected nullable character');
                }
                $tokens->next();
                $type = $this->parseTypes($tokens, $context, self::PARSER_IN_NULLABLE);
                $types[] = new Nullable($type);
            } elseif ($token === '(') {
                $tokens->next();
                $type = $this->parseTypes($tokens, $context, self::PARSER_IN_ARRAY_EXPRESSION);
                $token = $tokens->current();
                if ($token === null) {
                    // Someone did not properly close their array expression ..
                    break;
                }
                $tokens->next();
                $resolvedType = new Expression($type);
                $types[] = $resolvedType;
            } elseif ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION && isset($token[0]) && $token[0] === ')') {
                break;
            } elseif ($token === '<') {
                if (count($types) === 0) {
                    throw new RuntimeException('Unexpected collection operator "<", class name is missing');
                }
                $classType = array_pop($types);
                if ($classType !== null) {
                    if ((string) $classType === 'class-string') {
                        $types[] = $this->resolveClassString($tokens, $context);
                    } elseif ((string) $classType === 'int') {
                        $types[] = $this->resolveIntRange($tokens);
                    } elseif ((string) $classType === 'interface-string') {
                        $types[] = $this->resolveInterfaceString($tokens, $context);
                    } else {
                        $types[] = $this->resolveCollection($tokens, $classType, $context);
                    }
                }
                $tokens->next();
            } elseif ($parserContext === self::PARSER_IN_COLLECTION_EXPRESSION && ($token === '>' || trim($token) === ',')) {
                break;
            } elseif ($token === self::OPERATOR_ARRAY) {
                $last = array_key_last($types);
                if ($last === null) {
                    throw new InvalidArgumentException('Unexpected array operator');
                }
                $lastItem = $types[$last];
                if ($lastItem instanceof Expression) {
                    $lastItem = $lastItem->getValueType();
                }
                $types[$last] = new Array_($lastItem);
                $tokens->next();
            } else {
                $types[] = $this->resolveSingleType($token, $context);
                $tokens->next();
            }
        }
        if ($token === '|' || $token === '&') {
            throw new RuntimeException('A type is missing after a type separator');
        }
        if (count($types) === 0) {
            if ($parserContext === self::PARSER_IN_NULLABLE) {
                throw new RuntimeException('A type is missing after a nullable character');
            }
            if ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION) {
                throw new RuntimeException('A type is missing in an array expression');
            }
            if ($parserContext === self::PARSER_IN_COLLECTION_EXPRESSION) {
                throw new RuntimeException('A type is missing in a collection expression');
            }
        } elseif (count($types) === 1) {
            return current($types);
        }
        if ($compoundToken === '|') {
            return new Compound(array_values($types));
        }
        return new Intersection(array_values($types));
    }
    /**
     * resolve the given type into a type object
     *
     * @param string $type the type string, representing a single type
     *
     * @return Type|Array_|Object_
     *
     * @psalm-mutation-free
     */
    private function resolveSingleType(string $type, Context $context) : object
    {
        switch (\true) {
            case $this->isKeyword($type):
                return $this->resolveKeyword($type);
            case $this->isFqsen($type):
                return $this->resolveTypedObject($type);
            case $this->isPartialStructuralElementName($type):
                return $this->resolveTypedObject($type, $context);
            // @codeCoverageIgnoreStart
            default:
                // I haven't got the foggiest how the logic would come here but added this as a defense.
                throw new RuntimeException('Unable to resolve type "' . $type . '", there is no known method to resolve it');
        }
        // @codeCoverageIgnoreEnd
    }
    /**
     * Adds a keyword to the list of Keywords and associates it with a specific Value Object.
     *
     * @psalm-param class-string<Type> $typeClassName
     */
    public function addKeyword(string $keyword, string $typeClassName) : void
    {
        if (!class_exists($typeClassName)) {
            throw new InvalidArgumentException('The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class' . ' but we could not find the class ' . $typeClassName);
        }
        $interfaces = class_implements($typeClassName);
        if ($interfaces === \false) {
            throw new InvalidArgumentException('The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class' . ' but we could not find the class ' . $typeClassName);
        }
        if (!in_array(Type::class, $interfaces, \true)) {
            throw new InvalidArgumentException('The class "' . $typeClassName . '" must implement the interface "phpDocumentor\\Reflection\\Type"');
        }
        $this->keywords[$keyword] = $typeClassName;
    }
    /**
     * Detects whether the given type represents a PHPDoc keyword.
     *
     * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
     *
     * @psalm-mutation-free
     */
    private function isKeyword(string $type) : bool
    {
        return array_key_exists(strtolower($type), $this->keywords);
    }
    /**
     * Detects whether the given type represents a relative structural element name.
     *
     * @param string $type A relative or absolute type as defined in the phpDocumentor documentation.
     *
     * @psalm-mutation-free
     */
    private function isPartialStructuralElementName(string $type) : bool
    {
        return isset($type[0]) && $type[0] !== self::OPERATOR_NAMESPACE && !$this->isKeyword($type);
    }
    /**
     * Tests whether the given type is a Fully Qualified Structural Element Name.
     *
     * @psalm-mutation-free
     */
    private function isFqsen(string $type) : bool
    {
        return strpos($type, self::OPERATOR_NAMESPACE) === 0;
    }
    /**
     * Resolves the given keyword (such as `string`) into a Type object representing that keyword.
     *
     * @psalm-mutation-free
     */
    private function resolveKeyword(string $type) : Type
    {
        $className = $this->keywords[strtolower($type)];
        return new $className();
    }
    /**
     * Resolves the given FQSEN string into an FQSEN object.
     *
     * @psalm-mutation-free
     */
    private function resolveTypedObject(string $type, ?Context $context = null) : Object_
    {
        return new Object_($this->fqsenResolver->resolve($type, $context));
    }
    /**
     * Resolves class string
     *
     * @param ArrayIterator<int, (string|null)> $tokens
     */
    private function resolveClassString(ArrayIterator $tokens, Context $context) : Type
    {
        $tokens->next();
        $classType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
        if (!$classType instanceof Object_ || $classType->getFqsen() === null) {
            throw new RuntimeException($classType . ' is not a class string');
        }
        $token = $tokens->current();
        if ($token !== '>') {
            if (empty($token)) {
                throw new RuntimeException('class-string: ">" is missing');
            }
            throw new RuntimeException('Unexpected character "' . $token . '", ">" is missing');
        }
        return new ClassString($classType->getFqsen());
    }
    /**
     * Resolves integer ranges
     *
     * @param ArrayIterator<int, (string|null)> $tokens
     */
    private function resolveIntRange(ArrayIterator $tokens) : Type
    {
        $tokens->next();
        $token = '';
        $minValue = null;
        $maxValue = null;
        $commaFound = \false;
        $tokenCounter = 0;
        while ($tokens->valid()) {
            $tokenCounter++;
            $token = $tokens->current();
            if ($token === null) {
                throw new RuntimeException('Unexpected nullable character');
            }
            $token = trim($token);
            if ($token === '>') {
                break;
            }
            if ($token === ',') {
                $commaFound = \true;
            }
            if ($commaFound === \false && $minValue === null) {
                if (is_numeric($token) || $token === 'max' || $token === 'min') {
                    $minValue = $token;
                }
            }
            if ($commaFound === \true && $maxValue === null) {
                if (is_numeric($token) || $token === 'max' || $token === 'min') {
                    $maxValue = $token;
                }
            }
            $tokens->next();
        }
        if ($token !== '>') {
            if (empty($token)) {
                throw new RuntimeException('interface-string: ">" is missing');
            }
            throw new RuntimeException('Unexpected character "' . $token . '", ">" is missing');
        }
        if ($minValue === null || $maxValue === null || $tokenCounter > 4) {
            throw new RuntimeException('int<min,max> has not the correct format');
        }
        return new IntegerRange($minValue, $maxValue);
    }
    /**
     * Resolves class string
     *
     * @param ArrayIterator<int, (string|null)> $tokens
     */
    private function resolveInterfaceString(ArrayIterator $tokens, Context $context) : Type
    {
        $tokens->next();
        $classType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
        if (!$classType instanceof Object_ || $classType->getFqsen() === null) {
            throw new RuntimeException($classType . ' is not a interface string');
        }
        $token = $tokens->current();
        if ($token !== '>') {
            if (empty($token)) {
                throw new RuntimeException('interface-string: ">" is missing');
            }
            throw new RuntimeException('Unexpected character "' . $token . '", ">" is missing');
        }
        return new InterfaceString($classType->getFqsen());
    }
    /**
     * Resolves the collection values and keys
     *
     * @param ArrayIterator<int, (string|null)> $tokens
     *
     * @return Array_|Iterable_|Collection
     */
    private function resolveCollection(ArrayIterator $tokens, Type $classType, Context $context) : Type
    {
        $isArray = (string) $classType === 'array';
        $isIterable = (string) $classType === 'iterable';
        $isList = (string) $classType === 'list';
        // allow only "array", "iterable" or class name before "<"
        if (!$isArray && !$isIterable && !$isList && (!$classType instanceof Object_ || $classType->getFqsen() === null)) {
            throw new RuntimeException($classType . ' is not a collection');
        }
        $tokens->next();
        $valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
        $keyType = null;
        $token = $tokens->current();
        if ($token !== null && trim($token) === ',' && !$isList) {
            // if we have a comma, then we just parsed the key type, not the value type
            $keyType = $valueType;
            if ($isArray) {
                // check the key type for an "array" collection. We allow only
                // strings or integers.
                if (!$keyType instanceof ArrayKey && !$keyType instanceof String_ && !$keyType instanceof Integer && !$keyType instanceof Compound) {
                    throw new RuntimeException('An array can have only integers or strings as keys');
                }
                if ($keyType instanceof Compound) {
                    foreach ($keyType->getIterator() as $item) {
                        if (!$item instanceof ArrayKey && !$item instanceof String_ && !$item instanceof Integer) {
                            throw new RuntimeException('An array can have only integers or strings as keys');
                        }
                    }
                }
            }
            $tokens->next();
            // now let's parse the value type
            $valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION);
        }
        $token = $tokens->current();
        if ($token !== '>') {
            if (empty($token)) {
                throw new RuntimeException('Collection: ">" is missing');
            }
            throw new RuntimeException('Unexpected character "' . $token . '", ">" is missing');
        }
        if ($isArray) {
            return new Array_($valueType, $keyType);
        }
        if ($isIterable) {
            return new Iterable_($valueType, $keyType);
        }
        if ($isList) {
            return new List_($valueType);
        }
        if ($classType instanceof Object_) {
            return $this->makeCollectionFromObject($classType, $valueType, $keyType);
        }
        throw new RuntimeException('Invalid $classType provided');
    }
    /**
     * @psalm-pure
     */
    private function makeCollectionFromObject(Object_ $object, Type $valueType, ?Type $keyType = null) : Collection
    {
        return new Collection($object->getFqsen(), $valueType, $keyType);
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\AggregatedType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Compound;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Float_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Integer;
/**
 * Value Object representing the 'numeric' pseudo-type, which is either a numeric-string, integer or float.
 *
 * @psalm-immutable
 */
final class Numeric_ extends AggregatedType implements PseudoType
{
    public function __construct()
    {
        AggregatedType::__construct([new NumericString(), new Integer(), new Float_()], '|');
    }
    public function underlyingType() : Type
    {
        return new Compound([new NumericString(), new Integer(), new Float_()]);
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'numeric';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link https://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Boolean;
use function class_alias;
/**
 * Value Object representing the PseudoType 'False', which is a Boolean type.
 *
 * @psalm-immutable
 */
final class True_ extends Boolean implements PseudoType
{
    public function underlyingType() : Type
    {
        return new Boolean();
    }
    public function __toString() : string
    {
        return 'true';
    }
}
class_alias(True_::class, '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\True_', \false);
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class LiteralString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'literal-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class LowercaseString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'lowercase-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link https://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Boolean;
use function class_alias;
/**
 * Value Object representing the PseudoType 'False', which is a Boolean type.
 *
 * @psalm-immutable
 */
final class False_ extends Boolean implements PseudoType
{
    public function underlyingType() : Type
    {
        return new Boolean();
    }
    public function __toString() : string
    {
        return 'false';
    }
}
class_alias(False_::class, '_HumbugBox1cb33d1f20f1\\phpDocumentor\\Reflection\\Types\\False_', \false);
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class NonEmptyLowercaseString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'non-empty-lowercase-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class HtmlEscapedString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'html-escaped-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class NumericString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'numeric-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Integer;
/**
 * Value Object representing the type 'int'.
 *
 * @psalm-immutable
 */
final class IntegerRange extends Integer implements PseudoType
{
    private string $minValue;
    private string $maxValue;
    public function __construct(string $minValue, string $maxValue)
    {
        $this->minValue = $minValue;
        $this->maxValue = $maxValue;
    }
    public function underlyingType() : Type
    {
        return new Integer();
    }
    public function getMinValue() : string
    {
        return $this->minValue;
    }
    public function getMaxValue() : string
    {
        return $this->maxValue;
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'int<' . $this->minValue . ', ' . $this->maxValue . '>';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Array_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Integer;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Mixed_;
/**
 * Value Object representing the type 'list'.
 *
 * @psalm-immutable
 */
final class List_ extends Array_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new Array_();
    }
    public function __construct(?Type $valueType = null)
    {
        parent::__construct($valueType, new Integer());
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        if ($this->valueType instanceof Mixed_) {
            return 'list';
        }
        return 'list<' . $this->valueType . '>';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Integer;
/**
 * Value Object representing the type 'int'.
 *
 * @psalm-immutable
 */
final class PositiveInteger extends Integer implements PseudoType
{
    public function underlyingType() : Type
    {
        return new Integer();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'positive-int';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Integer;
/**
 * Value Object representing the type 'int'.
 *
 * @psalm-immutable
 */
final class NegativeInteger extends Integer implements PseudoType
{
    public function underlyingType() : Type
    {
        return new Integer();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'negative-int';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class TraitString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'trait-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class NonEmptyString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'non-empty-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoTypes;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\PseudoType;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\String_;
/**
 * Value Object representing the type 'string'.
 *
 * @psalm-immutable
 */
final class CallableString extends String_ implements PseudoType
{
    public function underlyingType() : Type
    {
        return new String_();
    }
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string
    {
        return 'callable-string';
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

/**
 * @psalm-immutable
 */
interface Type
{
    /**
     * Returns a rendered output of the Type as it would be used in a DocBlock.
     */
    public function __toString() : string;
}
{
  "symbol-whitelist" : [
    "null", "true", "false",
    "static", "self", "parent",
    "array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", "XSLTProcessor",
    "T_NAME_QUALIFIED", "T_NAME_FULLY_QUALIFIED"
  ],
  "php-core-extensions" : [
    "Core",
    "pcre",
    "Reflection",
    "tokenizer",
    "SPL",
    "standard"
  ]
}
The MIT License (MIT)

Copyright (c) 2010 Mike van Riel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1;

use _HumbugBox1cb33d1f20f1\Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use _HumbugBox1cb33d1f20f1\Rector\Config\RectorConfig;
use _HumbugBox1cb33d1f20f1\Rector\Set\ValueObject\LevelSetList;
return static function (RectorConfig $rectorConfig) : void {
    $rectorConfig->paths([__DIR__ . '/src', __DIR__ . '/tests/unit']);
    // register a single rule
    $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
    $rectorConfig->rule(Rector\CodeQuality\Rector\Class_\CompleteDynamicPropertiesRector::class);
    $rectorConfig->rule(Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector::class);
    $rectorConfig->rule(Rector\PHPUnit\Rector\Class_\AddProphecyTraitRector::class);
    $rectorConfig->importNames();
    // define sets of rules
    $rectorConfig->sets([LevelSetList::UP_TO_PHP_74]);
};
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

use InvalidArgumentException;
use LogicException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\TagFactory;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_shift;
use function count;
use function explode;
use function is_object;
use function method_exists;
use function preg_match;
use function preg_replace;
use function str_replace;
use function strpos;
use function substr;
use function trim;
final class DocBlockFactory implements DocBlockFactoryInterface
{
    /** @var DocBlock\DescriptionFactory */
    private $descriptionFactory;
    /** @var DocBlock\TagFactory */
    private $tagFactory;
    /**
     * Initializes this factory with the required subcontractors.
     */
    public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory)
    {
        $this->descriptionFactory = $descriptionFactory;
        $this->tagFactory = $tagFactory;
    }
    /**
     * Factory method for easy instantiation.
     *
     * @param array<string, class-string<Tag>> $additionalTags
     */
    public static function createInstance(array $additionalTags = []) : self
    {
        $fqsenResolver = new FqsenResolver();
        $tagFactory = new StandardTagFactory($fqsenResolver);
        $descriptionFactory = new DescriptionFactory($tagFactory);
        $tagFactory->addService($descriptionFactory);
        $tagFactory->addService(new TypeResolver($fqsenResolver));
        $docBlockFactory = new self($descriptionFactory, $tagFactory);
        foreach ($additionalTags as $tagName => $tagHandler) {
            $docBlockFactory->registerTagHandler($tagName, $tagHandler);
        }
        return $docBlockFactory;
    }
    /**
     * @param object|string $docblock A string containing the DocBlock to parse or an object supporting the
     *                                getDocComment method (such as a ReflectionClass object).
     */
    public function create($docblock, ?Types\Context $context = null, ?Location $location = null) : DocBlock
    {
        if (is_object($docblock)) {
            if (!method_exists($docblock, 'getDocComment')) {
                $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method';
                throw new InvalidArgumentException($exceptionMessage);
            }
            $docblock = $docblock->getDocComment();
            Assert::string($docblock);
        }
        Assert::stringNotEmpty($docblock);
        if ($context === null) {
            $context = new Types\Context('');
        }
        $parts = $this->splitDocBlock($this->stripDocComment($docblock));
        [$templateMarker, $summary, $description, $tags] = $parts;
        return new DocBlock($summary, $description ? $this->descriptionFactory->create($description, $context) : null, $this->parseTagBlock($tags, $context), $context, $location, $templateMarker === '#@+', $templateMarker === '#@-');
    }
    /**
     * @param class-string<Tag> $handler
     */
    public function registerTagHandler(string $tagName, string $handler) : void
    {
        $this->tagFactory->registerTagHandler($tagName, $handler);
    }
    /**
     * Strips the asterisks from the DocBlock comment.
     *
     * @param string $comment String containing the comment text.
     */
    private function stripDocComment(string $comment) : string
    {
        $comment = preg_replace('#[ \\t]*(?:\\/\\*\\*|\\*\\/|\\*)?[ \\t]?(.*)?#u', '$1', $comment);
        Assert::string($comment);
        $comment = trim($comment);
        // reg ex above is not able to remove */ from a single line docblock
        if (substr($comment, -2) === '*/') {
            $comment = trim(substr($comment, 0, -2));
        }
        return str_replace(["\r\n", "\r"], "\n", $comment);
    }
    // phpcs:disable
    /**
     * Splits the DocBlock into a template marker, summary, description and block of tags.
     *
     * @param string $comment Comment to split into the sub-parts.
     *
     * @return string[] containing the template marker (if any), summary, description and a string containing the tags.
     *
     * @author Mike van Riel <me@mikevanriel.com> for extending the regex with template marker support.
     *
     * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
     */
    private function splitDocBlock(string $comment) : array
    {
        // phpcs:enable
        // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
        // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the
        // performance impact of running a regular expression
        if (strpos($comment, '@') === 0) {
            return ['', '', '', $comment];
        }
        // clears all extra horizontal whitespace from the line endings to prevent parsing issues
        $comment = preg_replace('/\\h*$/Sum', '', $comment);
        Assert::string($comment);
        /*
         * Splits the docblock into a template marker, summary, description and tags section.
         *
         * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may
         *   occur after it and will be stripped).
         * - The short description is started from the first character until a dot is encountered followed by a
         *   newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing
         *   errors). This is optional.
         * - The long description, any character until a new line is encountered followed by an @ and word
         *   characters (a tag). This is optional.
         * - Tags; the remaining characters
         *
         * Big thanks to RichardJ for contributing this Regular Expression
         */
        preg_match('/
            \\A
            # 1. Extract the template marker
            (?:(\\#\\@\\+|\\#\\@\\-)\\n?)?

            # 2. Extract the summary
            (?:
              (?! @\\pL ) # The summary may not start with an @
              (
                [^\\n.]+
                (?:
                  (?! \\. \\n | \\n{2} )     # End summary upon a dot followed by newline or two newlines
                  [\\n.]* (?! [ \\t]* @\\pL ) # End summary when an @ is found as first character on a new line
                  [^\\n.]+                 # Include anything else
                )*
                \\.?
              )?
            )

            # 3. Extract the description
            (?:
              \\s*        # Some form of whitespace _must_ precede a description because a summary must be there
              (?! @\\pL ) # The description may not start with an @
              (
                [^\\n]+
                (?: \\n+
                  (?! [ \\t]* @\\pL ) # End description when an @ is found as first character on a new line
                  [^\\n]+            # Include anything else
                )*
              )
            )?

            # 4. Extract the tags (anything that follows)
            (\\s+ [\\s\\S]*)? # everything that follows
            /ux', $comment, $matches);
        array_shift($matches);
        while (count($matches) < 4) {
            $matches[] = '';
        }
        return $matches;
    }
    /**
     * Creates the tag objects.
     *
     * @param string        $tags    Tag block to parse.
     * @param Types\Context $context Context of the parsed Tag
     *
     * @return DocBlock\Tag[]
     */
    private function parseTagBlock(string $tags, Types\Context $context) : array
    {
        $tags = $this->filterTagBlock($tags);
        if ($tags === null) {
            return [];
        }
        $result = [];
        $lines = $this->splitTagBlockIntoTagLines($tags);
        foreach ($lines as $key => $tagLine) {
            $result[$key] = $this->tagFactory->create(trim($tagLine), $context);
        }
        return $result;
    }
    /**
     * @return string[]
     */
    private function splitTagBlockIntoTagLines(string $tags) : array
    {
        $result = [];
        foreach (explode("\n", $tags) as $tagLine) {
            if ($tagLine !== '' && strpos($tagLine, '@') === 0) {
                $result[] = $tagLine;
            } else {
                $result[count($result) - 1] .= "\n" . $tagLine;
            }
        }
        return $result;
    }
    private function filterTagBlock(string $tags) : ?string
    {
        $tags = trim($tags);
        if (!$tags) {
            return null;
        }
        if ($tags[0] !== '@') {
            // @codeCoverageIgnoreStart
            // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that
            // we didn't foresee.
            throw new LogicException('A tag block started with text instead of an at-sign(@): ' . $tags);
            // @codeCoverageIgnoreEnd
        }
        return $tags;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Exception\PcreException;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function preg_last_error;
use function preg_split as php_preg_split;
abstract class Utils
{
    /**
     * Wrapper function for phps preg_split
     *
     * This function is inspired by {@link https://github.com/thecodingmachine/safe/blob/master/generated/pcre.php}. But
     * since this library is all about performance we decided to strip everything we don't need. Reducing the amount
     * of files that have to be loaded, ect.
     *
     * @param string $pattern The pattern to search for, as a string.
     * @param string $subject The input string.
     * @param int $limit If specified, then only substrings up to limit are returned with the
     *      rest of the string being placed in the last substring. A limit of -1 or 0 means "no limit".
     * @param int $flags flags can be any combination of the following flags (combined with the | bitwise operator):
     * *PREG_SPLIT_NO_EMPTY*
     *      If this flag is set, only non-empty pieces will be returned by preg_split().
     * *PREG_SPLIT_DELIM_CAPTURE*
     *      If this flag is set, parenthesized expression in the delimiter pattern will be captured
     *      and returned as well.
     * *PREG_SPLIT_OFFSET_CAPTURE*
     *      If this flag is set, for every occurring match the appendant string offset will also be returned.
     *      Note that this changes the return value in an array where every element is an array consisting of the
     *      matched string at offset 0 and its string offset into subject at offset 1.
     *
     * @return string[] Returns an array containing substrings of subject
     *                                                      split along boundaries matched by pattern
     *
     * @throws PcreException
     */
    public static function pregSplit(string $pattern, string $subject, int $limit = -1, int $flags = 0) : array
    {
        $parts = php_preg_split($pattern, $subject, $limit, $flags);
        if ($parts === \false) {
            throw PcreException::createFromPhpError(preg_last_error());
        }
        Assert::allString($parts);
        return $parts;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
// phpcs:ignore SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming.SuperfluousSuffix
interface DocBlockFactoryInterface
{
    /**
     * Factory method for easy instantiation.
     *
     * @param array<string, class-string<Tag>> $additionalTags
     */
    public static function createInstance(array $additionalTags = []) : DocBlockFactory;
    /**
     * @param string|object $docblock
     */
    public function create($docblock, ?Types\Context $context = null, ?Location $location = null) : DocBlock;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Exception;

use InvalidArgumentException;
use const PREG_BACKTRACK_LIMIT_ERROR;
use const PREG_BAD_UTF8_ERROR;
use const PREG_BAD_UTF8_OFFSET_ERROR;
use const PREG_INTERNAL_ERROR;
use const PREG_JIT_STACKLIMIT_ERROR;
use const PREG_NO_ERROR;
use const PREG_RECURSION_LIMIT_ERROR;
final class PcreException extends InvalidArgumentException
{
    public static function createFromPhpError(int $errorCode) : self
    {
        switch ($errorCode) {
            case PREG_BACKTRACK_LIMIT_ERROR:
                return new self('Backtrack limit error');
            case PREG_RECURSION_LIMIT_ERROR:
                return new self('Recursion limit error');
            case PREG_BAD_UTF8_ERROR:
                return new self('Bad UTF8 error');
            case PREG_BAD_UTF8_OFFSET_ERROR:
                return new self('Bad UTF8 offset error');
            case PREG_JIT_STACKLIMIT_ERROR:
                return new self('Jit stacklimit error');
            case PREG_NO_ERROR:
            case PREG_INTERNAL_ERROR:
            default:
        }
        return new self('Unknown Pcre error');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use function count;
use function implode;
use function ltrim;
use function min;
use function str_replace;
use function strlen;
use function strpos;
use function substr;
use function trim;
use const PREG_SPLIT_DELIM_CAPTURE;
/**
 * Creates a new Description object given a body of text.
 *
 * Descriptions in phpDocumentor are somewhat complex entities as they can contain one or more tags inside their
 * body that can be replaced with a readable output. The replacing is done by passing a Formatter object to the
 * Description object's `render` method.
 *
 * In addition to the above does a Description support two types of escape sequences:
 *
 * 1. `{@}` to escape the `@` character to prevent it from being interpreted as part of a tag, i.e. `{{@}link}`
 * 2. `{}` to escape the `}` character, this can be used if you want to use the `}` character in the description
 *    of an inline tag.
 *
 * If a body consists of multiple lines then this factory will also remove any superfluous whitespace at the beginning
 * of each line while maintaining any indentation that is used. This will prevent formatting parsers from tripping
 * over unexpected spaces as can be observed with tag descriptions.
 */
class DescriptionFactory
{
    /** @var TagFactory */
    private $tagFactory;
    /**
     * Initializes this factory with the means to construct (inline) tags.
     */
    public function __construct(TagFactory $tagFactory)
    {
        $this->tagFactory = $tagFactory;
    }
    /**
     * Returns the parsed text of this description.
     */
    public function create(string $contents, ?TypeContext $context = null) : Description
    {
        $tokens = $this->lex($contents);
        $count = count($tokens);
        $tagCount = 0;
        $tags = [];
        for ($i = 1; $i < $count; $i += 2) {
            $tags[] = $this->tagFactory->create($tokens[$i], $context);
            $tokens[$i] = '%' . ++$tagCount . '$s';
        }
        //In order to allow "literal" inline tags, the otherwise invalid
        //sequence "{@}" is changed to "@", and "{}" is changed to "}".
        //"%" is escaped to "%%" because of vsprintf.
        //See unit tests for examples.
        for ($i = 0; $i < $count; $i += 2) {
            $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]);
        }
        return new Description(implode('', $tokens), $tags);
    }
    /**
     * Strips the contents from superfluous whitespace and splits the description into a series of tokens.
     *
     * @return string[] A series of tokens of which the description text is composed.
     */
    private function lex(string $contents) : array
    {
        $contents = $this->removeSuperfluousStartingWhitespace($contents);
        // performance optimalization; if there is no inline tag, don't bother splitting it up.
        if (strpos($contents, '{@') === \false) {
            return [$contents];
        }
        return Utils::pregSplit('/\\{
                # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally.
                (?!@\\})
                # We want to capture the whole tag line, but without the inline tag delimiters.
                (\\@
                    # Match everything up to the next delimiter.
                    [^{}]*
                    # Nested inline tag content should not be captured, or it will appear in the result separately.
                    (?:
                        # Match nested inline tags.
                        (?:
                            # Because we did not catch the tag delimiters earlier, we must be explicit with them here.
                            # Notice that this also matches "{}", as a way to later introduce it as an escape sequence.
                            \\{(?1)?\\}
                            |
                            # Make sure we match hanging "{".
                            \\{
                        )
                        # Match content after the nested inline tag.
                        [^{}]*
                    )* # If there are more inline tags, match them as well. We use "*" since there may not be any
                       # nested inline tags.
                )
            \\}/Sux', $contents, 0, PREG_SPLIT_DELIM_CAPTURE);
    }
    /**
     * Removes the superfluous from a multi-line description.
     *
     * When a description has more than one line then it can happen that the second and subsequent lines have an
     * additional indentation. This is commonly in use with tags like this:
     *
     *     {@}since 1.1.0 This is an example
     *         description where we have an
     *         indentation in the second and
     *         subsequent lines.
     *
     * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent
     * lines and this may cause rendering issues when, for example, using a Markdown converter.
     */
    private function removeSuperfluousStartingWhitespace(string $contents) : string
    {
        $lines = Utils::pregSplit("/\r\n?|\n/", $contents);
        // if there is only one line then we don't have lines with superfluous whitespace and
        // can use the contents as-is
        if (count($lines) <= 1) {
            return $contents;
        }
        // determine how many whitespace characters need to be stripped
        $startingSpaceCount = 9999999;
        for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) {
            // lines with a no length do not count as they are not indented at all
            if (trim($lines[$i]) === '') {
                continue;
            }
            // determine the number of prefixing spaces by checking the difference in line length before and after
            // an ltrim
            $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i])));
        }
        // strip the number of spaces from each line
        if ($startingSpaceCount > 0) {
            for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) {
                $lines[$i] = substr($lines[$i], $startingSpaceCount);
            }
        }
        return implode("\n", $lines);
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
use function sprintf;
use function str_repeat;
use function str_replace;
use function strlen;
use function wordwrap;
/**
 * Converts a DocBlock back from an object to a complete DocComment including Asterisks.
 */
class Serializer
{
    /** @var string The string to indent the comment with. */
    protected $indentString = ' ';
    /** @var int The number of times the indent string is repeated. */
    protected $indent = 0;
    /** @var bool Whether to indent the first line with the given indent amount and string. */
    protected $isFirstLineIndented = \true;
    /** @var int|null The max length of a line. */
    protected $lineLength;
    /** @var Formatter A custom tag formatter. */
    protected $tagFormatter;
    /** @var string */
    private $lineEnding;
    /**
     * Create a Serializer instance.
     *
     * @param int       $indent          The number of times the indent string is repeated.
     * @param string    $indentString    The string to indent the comment with.
     * @param bool      $indentFirstLine Whether to indent the first line.
     * @param int|null  $lineLength      The max length of a line or NULL to disable line wrapping.
     * @param Formatter $tagFormatter    A custom tag formatter, defaults to PassthroughFormatter.
     * @param string    $lineEnding      Line ending used in the output, by default \n is used.
     */
    public function __construct(int $indent = 0, string $indentString = ' ', bool $indentFirstLine = \true, ?int $lineLength = null, ?Formatter $tagFormatter = null, string $lineEnding = "\n")
    {
        $this->indent = $indent;
        $this->indentString = $indentString;
        $this->isFirstLineIndented = $indentFirstLine;
        $this->lineLength = $lineLength;
        $this->tagFormatter = $tagFormatter ?: new PassthroughFormatter();
        $this->lineEnding = $lineEnding;
    }
    /**
     * Generate a DocBlock comment.
     *
     * @param DocBlock $docblock The DocBlock to serialize.
     *
     * @return string The serialized doc block.
     */
    public function getDocComment(DocBlock $docblock) : string
    {
        $indent = str_repeat($this->indentString, $this->indent);
        $firstIndent = $this->isFirstLineIndented ? $indent : '';
        // 3 === strlen(' * ')
        $wrapLength = $this->lineLength ? $this->lineLength - strlen($indent) - 3 : null;
        $text = $this->removeTrailingSpaces($indent, $this->addAsterisksForEachLine($indent, $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength)));
        $comment = $firstIndent . "/**\n";
        if ($text) {
            $comment .= $indent . ' * ' . $text . "\n";
            $comment .= $indent . " *\n";
        }
        $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment);
        return str_replace("\n", $this->lineEnding, $comment . $indent . ' */');
    }
    private function removeTrailingSpaces(string $indent, string $text) : string
    {
        return str_replace(sprintf("\n%s * \n", $indent), sprintf("\n%s *\n", $indent), $text);
    }
    private function addAsterisksForEachLine(string $indent, string $text) : string
    {
        return str_replace("\n", sprintf("\n%s * ", $indent), $text);
    }
    private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, ?int $wrapLength) : string
    {
        $text = $docblock->getSummary() . ((string) $docblock->getDescription() ? "\n\n" . $docblock->getDescription() : '');
        if ($wrapLength !== null) {
            $text = wordwrap($text, $wrapLength);
            return $text;
        }
        return $text;
    }
    private function addTagBlock(DocBlock $docblock, ?int $wrapLength, string $indent, string $comment) : string
    {
        foreach ($docblock->getTags() as $tag) {
            $tagText = $this->tagFormatter->format($tag);
            if ($wrapLength !== null) {
                $tagText = wordwrap($tagText, $wrapLength);
            }
            $tagText = str_replace("\n", sprintf("\n%s * ", $indent), $tagText);
            $comment .= sprintf("%s * %s\n", $indent, $tagText);
        }
        return $comment;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Author;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Covers;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Generic;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Method;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Param;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Property;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\PropertyRead;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Return_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\See as SeeTag;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Since;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Source;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Throws;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Uses;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Var_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Version;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\FqsenResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use ReflectionMethod;
use ReflectionNamedType;
use ReflectionParameter;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_merge;
use function array_slice;
use function call_user_func_array;
use function count;
use function get_class;
use function preg_match;
use function strpos;
use function trim;
/**
 * Creates a Tag object given the contents of a tag.
 *
 * This Factory is capable of determining the appropriate class for a tag and instantiate it using its `create`
 * factory method. The `create` factory method of a Tag can have a variable number of arguments; this way you can
 * pass the dependencies that you need to construct a tag object.
 *
 * > Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise
 * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to
 * > verify that a dependency is actually passed.
 *
 * This Factory also features a Service Locator component that is used to pass the right dependencies to the
 * `create` method of a tag; each dependency should be registered as a service or as a parameter.
 *
 * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass
 * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface.
 */
final class StandardTagFactory implements TagFactory
{
    /** PCRE regular expression matching a tag name. */
    public const REGEX_TAGNAME = '[\\w\\-\\_\\\\:]+';
    /**
     * @var array<class-string<Tag>> An array with a tag as a key, and an
     *                               FQCN to a class that handles it as an array value.
     */
    private $tagHandlerMappings = [
        'author' => Author::class,
        'covers' => Covers::class,
        'deprecated' => Deprecated::class,
        // 'example'        => '\phpDocumentor\Reflection\DocBlock\Tags\Example',
        'link' => LinkTag::class,
        'method' => Method::class,
        'param' => Param::class,
        'property-read' => PropertyRead::class,
        'property' => Property::class,
        'property-write' => PropertyWrite::class,
        'return' => Return_::class,
        'see' => SeeTag::class,
        'since' => Since::class,
        'source' => Source::class,
        'throw' => Throws::class,
        'throws' => Throws::class,
        'uses' => Uses::class,
        'var' => Var_::class,
        'version' => Version::class,
    ];
    /**
     * @var array<class-string<Tag>> An array with a anotation s a key, and an
     *      FQCN to a class that handles it as an array value.
     */
    private $annotationMappings = [];
    /**
     * @var ReflectionParameter[][] a lazy-loading cache containing parameters
     *      for each tagHandler that has been used.
     */
    private $tagHandlerParameterCache = [];
    /** @var FqsenResolver */
    private $fqsenResolver;
    /**
     * @var mixed[] an array representing a simple Service Locator where we can store parameters and
     *     services that can be inserted into the Factory Methods of Tag Handlers.
     */
    private $serviceLocator = [];
    /**
     * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers.
     *
     * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property
     * is used.
     *
     * @see self::registerTagHandler() to add a new tag handler to the existing default list.
     *
     * @param array<class-string<Tag>> $tagHandlers
     */
    public function __construct(FqsenResolver $fqsenResolver, ?array $tagHandlers = null)
    {
        $this->fqsenResolver = $fqsenResolver;
        if ($tagHandlers !== null) {
            $this->tagHandlerMappings = $tagHandlers;
        }
        $this->addService($fqsenResolver, FqsenResolver::class);
    }
    public function create(string $tagLine, ?TypeContext $context = null) : Tag
    {
        if (!$context) {
            $context = new TypeContext('');
        }
        [$tagName, $tagBody] = $this->extractTagParts($tagLine);
        return $this->createTag(trim($tagBody), $tagName, $context);
    }
    /**
     * @param mixed $value
     */
    public function addParameter(string $name, $value) : void
    {
        $this->serviceLocator[$name] = $value;
    }
    public function addService(object $service, ?string $alias = null) : void
    {
        $this->serviceLocator[$alias ?: get_class($service)] = $service;
    }
    public function registerTagHandler(string $tagName, string $handler) : void
    {
        Assert::stringNotEmpty($tagName);
        Assert::classExists($handler);
        Assert::implementsInterface($handler, Tag::class);
        if (strpos($tagName, '\\') && $tagName[0] !== '\\') {
            throw new InvalidArgumentException('A namespaced tag must have a leading backslash as it must be fully qualified');
        }
        $this->tagHandlerMappings[$tagName] = $handler;
    }
    /**
     * Extracts all components for a tag.
     *
     * @return string[]
     */
    private function extractTagParts(string $tagLine) : array
    {
        $matches = [];
        if (!preg_match('/^@(' . self::REGEX_TAGNAME . ')((?:[\\s\\(\\{])\\s*([^\\s].*)|$)/us', $tagLine, $matches)) {
            throw new InvalidArgumentException('The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors');
        }
        if (count($matches) < 3) {
            $matches[] = '';
        }
        return array_slice($matches, 1);
    }
    /**
     * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the
     * body was invalid.
     */
    private function createTag(string $body, string $name, TypeContext $context) : Tag
    {
        $handlerClassName = $this->findHandlerClassName($name, $context);
        $arguments = $this->getArgumentsForParametersFromWiring($this->fetchParametersForHandlerFactoryMethod($handlerClassName), $this->getServiceLocatorWithDynamicParameters($context, $name, $body));
        try {
            $callable = [$handlerClassName, 'create'];
            Assert::isCallable($callable);
            /** @phpstan-var callable(string): ?Tag $callable */
            $tag = call_user_func_array($callable, $arguments);
            return $tag ?? InvalidTag::create($body, $name);
        } catch (InvalidArgumentException $e) {
            return InvalidTag::create($body, $name)->withError($e);
        }
    }
    /**
     * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).
     *
     * @return class-string<Tag>
     */
    private function findHandlerClassName(string $tagName, TypeContext $context) : string
    {
        $handlerClassName = Generic::class;
        if (isset($this->tagHandlerMappings[$tagName])) {
            $handlerClassName = $this->tagHandlerMappings[$tagName];
        } elseif ($this->isAnnotation($tagName)) {
            // TODO: Annotation support is planned for a later stage and as such is disabled for now
            $tagName = (string) $this->fqsenResolver->resolve($tagName, $context);
            if (isset($this->annotationMappings[$tagName])) {
                $handlerClassName = $this->annotationMappings[$tagName];
            }
        }
        return $handlerClassName;
    }
    /**
     * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters.
     *
     * @param ReflectionParameter[] $parameters
     * @param mixed[]               $locator
     *
     * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters
     *     is provided with this method.
     */
    private function getArgumentsForParametersFromWiring(array $parameters, array $locator) : array
    {
        $arguments = [];
        foreach ($parameters as $parameter) {
            $type = $parameter->getType();
            $typeHint = null;
            if ($type instanceof ReflectionNamedType) {
                $typeHint = $type->getName();
                if ($typeHint === 'self') {
                    $declaringClass = $parameter->getDeclaringClass();
                    if ($declaringClass !== null) {
                        $typeHint = $declaringClass->getName();
                    }
                }
            }
            if (isset($locator[$typeHint])) {
                $arguments[] = $locator[$typeHint];
                continue;
            }
            $parameterName = $parameter->getName();
            if (isset($locator[$parameterName])) {
                $arguments[] = $locator[$parameterName];
                continue;
            }
            $arguments[] = null;
        }
        return $arguments;
    }
    /**
     * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given
     * tag handler class name.
     *
     * @param class-string $handlerClassName
     *
     * @return ReflectionParameter[]
     */
    private function fetchParametersForHandlerFactoryMethod(string $handlerClassName) : array
    {
        if (!isset($this->tagHandlerParameterCache[$handlerClassName])) {
            $methodReflection = new ReflectionMethod($handlerClassName, 'create');
            $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters();
        }
        return $this->tagHandlerParameterCache[$handlerClassName];
    }
    /**
     * Returns a copy of this class' Service Locator with added dynamic parameters,
     * such as the tag's name, body and Context.
     *
     * @param TypeContext $context The Context (namespace and aliasses) that may be
     *  passed and is used to resolve FQSENs.
     * @param string      $tagName The name of the tag that may be
     *  passed onto the factory method of the Tag class.
     * @param string      $tagBody The body of the tag that may be
     *  passed onto the factory method of the Tag class.
     *
     * @return mixed[]
     */
    private function getServiceLocatorWithDynamicParameters(TypeContext $context, string $tagName, string $tagBody) : array
    {
        return array_merge($this->serviceLocator, ['name' => $tagName, 'body' => $tagBody, TypeContext::class => $context]);
    }
    /**
     * Returns whether the given tag belongs to an annotation.
     *
     * @todo this method should be populated once we implement Annotation notation support.
     */
    private function isAnnotation(string $tagContent) : bool
    {
        // 1. Contains a namespace separator
        // 2. Contains parenthesis
        // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part
        //    of the annotation class name matches the found tag name
        return \false;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
interface TagFactory
{
    /**
     * Adds a parameter to the service locator that can be injected in a tag's factory method.
     *
     * When calling a tag's "create" method we always check the signature for dependencies to inject. One way is to
     * typehint a parameter in the signature so that we can use that interface or class name to inject a dependency
     * (see {@see addService()} for more information on that).
     *
     * Another way is to check the name of the argument against the names in the Service Locator. With this method
     * you can add a variable that will be inserted when a tag's create method is not typehinted and has a matching
     * name.
     *
     * Be aware that there are two reserved names:
     *
     * - name, representing the name of the tag.
     * - body, representing the complete body of the tag.
     *
     * These parameters are injected at the last moment and will override any existing parameter with those names.
     *
     * @param mixed $value
     */
    public function addParameter(string $name, $value) : void;
    /**
     * Factory method responsible for instantiating the correct sub type.
     *
     * @param string $tagLine The text for this tag, including description.
     *
     * @return Tag A new tag object.
     *
     * @throws InvalidArgumentException If an invalid tag line was presented.
     */
    public function create(string $tagLine, ?TypeContext $context = null) : Tag;
    /**
     * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided.
     *
     * When calling a tag's "create" method we always check the signature for dependencies to inject. If a parameter
     * has a typehint then the ServiceLocator is queried to see if a Service is registered for that typehint.
     *
     * Because interfaces are regularly used as type-hints this method provides an alias parameter; if the FQCN of the
     * interface is passed as alias then every time that interface is requested the provided service will be returned.
     */
    public function addService(object $service) : void;
    /**
     * Registers a handler for tags.
     *
     * If you want to use your own tags then you can use this method to instruct the TagFactory
     * to register the name of a tag with the FQCN of a 'Tag Handler'. The Tag handler should implement
     * the {@see Tag} interface (and thus the create method).
     *
     * @param string                    $tagName Name of tag to register a handler for. When registering a namespaced
     *                                   tag, the full name, along with a prefixing slash MUST be provided.
     * @param class-string<Tag>         $handler FQCN of handler.
     *
     * @throws InvalidArgumentException If the tag name is not a string.
     * @throws InvalidArgumentException If the tag name is namespaced (contains backslashes) but
     *                                   does not start with a backslash.
     * @throws InvalidArgumentException If the handler is not a string.
     * @throws InvalidArgumentException If the handler is not an existing class.
     * @throws InvalidArgumentException If the handler does not implement the {@see Tag} interface.
     */
    public function registerTagHandler(string $tagName, string $handler) : void;
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
use function vsprintf;
/**
 * Object representing to description for a DocBlock.
 *
 * A Description object can consist of plain text but can also include tags. A Description Formatter can then combine
 * a body template with sprintf-style placeholders together with formatted tags in order to reconstitute a complete
 * description text using the format that you would prefer.
 *
 * Because parsing a Description text can be a verbose process this is handled by the {@see DescriptionFactory}. It is
 * thus recommended to use that to create a Description object, like this:
 *
 *     $description = $descriptionFactory->create('This is a {@see Description}', $context);
 *
 * The description factory will interpret the given body and create a body template and list of tags from them, and pass
 * that onto the constructor if this class.
 *
 * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace
 * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial
 * > type names and FQSENs.
 *
 * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this:
 *
 *     $description = new Description(
 *         'This is a %1$s',
 *         [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ]
 *     );
 *
 * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object
 * is mainly responsible for rendering.
 *
 * @see DescriptionFactory to create a new Description.
 * @see Description\Formatter for the formatting of the body and tags.
 */
class Description
{
    /** @var string */
    private $bodyTemplate;
    /** @var Tag[] */
    private $tags;
    /**
     * Initializes a Description with its body (template) and a listing of the tags used in the body template.
     *
     * @param Tag[] $tags
     */
    public function __construct(string $bodyTemplate, array $tags = [])
    {
        $this->bodyTemplate = $bodyTemplate;
        $this->tags = $tags;
    }
    /**
     * Returns the body template.
     */
    public function getBodyTemplate() : string
    {
        return $this->bodyTemplate;
    }
    /**
     * Returns the tags for this DocBlock.
     *
     * @return Tag[]
     */
    public function getTags() : array
    {
        return $this->tags;
    }
    /**
     * Renders this description as a string where the provided formatter will format the tags in the expected string
     * format.
     */
    public function render(?Formatter $formatter = null) : string
    {
        if ($formatter === null) {
            $formatter = new PassthroughFormatter();
        }
        $tags = [];
        foreach ($this->tags as $tag) {
            $tags[] = '{' . $formatter->format($tag) . '}';
        }
        return vsprintf($this->bodyTemplate, $tags);
    }
    /**
     * Returns a plain string representation of this description.
     */
    public function __toString() : string
    {
        return $this->render();
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter;
interface Tag
{
    public function getName() : string;
    /**
     * @return Tag|mixed Class that implements Tag
     * @phpstan-return ?Tag
     */
    public static function create(string $body);
    public function render(?Formatter $formatter = null) : string;
    public function __toString() : string;
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Example;
use function array_slice;
use function file;
use function getcwd;
use function implode;
use function is_readable;
use function rtrim;
use function sprintf;
use function trim;
use const DIRECTORY_SEPARATOR;
/**
 * Class used to find an example file's location based on a given ExampleDescriptor.
 */
class ExampleFinder
{
    /** @var string */
    private $sourceDirectory = '';
    /** @var string[] */
    private $exampleDirectories = [];
    /**
     * Attempts to find the example contents for the given descriptor.
     */
    public function find(Example $example) : string
    {
        $filename = $example->getFilePath();
        $file = $this->getExampleFileContents($filename);
        if (!$file) {
            return sprintf('** File not found : %s **', $filename);
        }
        return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount()));
    }
    /**
     * Registers the project's root directory where an 'examples' folder can be expected.
     */
    public function setSourceDirectory(string $directory = '') : void
    {
        $this->sourceDirectory = $directory;
    }
    /**
     * Returns the project's root directory where an 'examples' folder can be expected.
     */
    public function getSourceDirectory() : string
    {
        return $this->sourceDirectory;
    }
    /**
     * Registers a series of directories that may contain examples.
     *
     * @param string[] $directories
     */
    public function setExampleDirectories(array $directories) : void
    {
        $this->exampleDirectories = $directories;
    }
    /**
     * Returns a series of directories that may contain examples.
     *
     * @return string[]
     */
    public function getExampleDirectories() : array
    {
        return $this->exampleDirectories;
    }
    /**
     * Attempts to find the requested example file and returns its contents or null if no file was found.
     *
     * This method will try several methods in search of the given example file, the first one it encounters is
     * returned:
     *
     * 1. Iterates through all examples folders for the given filename
     * 2. Checks the source folder for the given filename
     * 3. Checks the 'examples' folder in the current working directory for examples
     * 4. Checks the path relative to the current working directory for the given filename
     *
     * @return string[] all lines of the example file
     */
    private function getExampleFileContents(string $filename) : ?array
    {
        $normalizedPath = null;
        foreach ($this->exampleDirectories as $directory) {
            $exampleFileFromConfig = $this->constructExamplePath($directory, $filename);
            if (is_readable($exampleFileFromConfig)) {
                $normalizedPath = $exampleFileFromConfig;
                break;
            }
        }
        if (!$normalizedPath) {
            if (is_readable($this->getExamplePathFromSource($filename))) {
                $normalizedPath = $this->getExamplePathFromSource($filename);
            } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) {
                $normalizedPath = $this->getExamplePathFromExampleDirectory($filename);
            } elseif (is_readable($filename)) {
                $normalizedPath = $filename;
            }
        }
        $lines = $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : \false;
        return $lines !== \false ? $lines : null;
    }
    /**
     * Get example filepath based on the example directory inside your project.
     */
    private function getExamplePathFromExampleDirectory(string $file) : string
    {
        return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file;
    }
    /**
     * Returns a path to the example file in the given directory..
     */
    private function constructExamplePath(string $directory, string $file) : string
    {
        return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file;
    }
    /**
     * Get example filepath based on sourcecode.
     */
    private function getExamplePathFromSource(string $file) : string
    {
        return sprintf('%s%s%s', trim($this->getSourceDirectory(), '\\/'), DIRECTORY_SEPARATOR, trim($file, '"'));
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_shift;
use function array_unshift;
use function implode;
use function strpos;
use function substr;
use const PREG_SPLIT_DELIM_CAPTURE;
/**
 * Reflection class for a {@}var tag in a Docblock.
 */
final class Var_ extends TagWithType implements Factory\StaticMethod
{
    /** @var string|null */
    protected $variableName = '';
    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
    {
        Assert::string($variableName);
        $this->name = 'var';
        $this->variableName = $variableName;
        $this->type = $type;
        $this->description = $description;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        [$firstPart, $body] = self::extractTypeFromBody($body);
        $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
        $type = null;
        $variableName = '';
        // if the first item that is encountered is not a variable; it is a type
        if ($firstPart && $firstPart[0] !== '$') {
            $type = $typeResolver->resolve($firstPart, $context);
        } else {
            // first part is not a type; we should prepend it to the parts array for further processing
            array_unshift($parts, $firstPart);
        }
        // if the next item starts with a $ it must be the variable name
        if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
            $variableName = array_shift($parts);
            if ($type) {
                array_shift($parts);
            }
            Assert::notNull($variableName);
            $variableName = substr($variableName, 1);
        }
        $description = $descriptionFactory->create(implode('', $parts), $context);
        return new static($variableName, $type, $description);
    }
    /**
     * Returns the variable's name.
     */
    public function getVariableName() : ?string
    {
        return $this->variableName;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        if ($this->variableName) {
            $variableName = '$' . $this->variableName;
        } else {
            $variableName = '';
        }
        $type = (string) $this->type;
        return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
/**
 * Parses a tag definition for a DocBlock.
 */
abstract class BaseTag implements DocBlock\Tag
{
    /** @var string Name of the tag */
    protected $name = '';
    /** @var Description|null Description of the tag. */
    protected $description;
    /**
     * Gets the name of this tag.
     *
     * @return string The name of this tag.
     */
    public function getName() : string
    {
        return $this->name;
    }
    public function getDescription() : ?Description
    {
        return $this->description;
    }
    public function render(?Formatter $formatter = null) : string
    {
        if ($formatter === null) {
            $formatter = new Formatter\PassthroughFormatter();
        }
        return $formatter->format($this);
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function preg_match;
/**
 * Reflection class for a {@}deprecated tag in a Docblock.
 */
final class Deprecated extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'deprecated';
    /**
     * PCRE regular expression matching a version vector.
     * Assumes the "x" modifier.
     */
    public const REGEX_VECTOR = '(?:
        # Normal release vectors.
        \\d\\S*
        |
        # VCS version vectors. Per PHPCS, they are expected to
        # follow the form of the VCS name, followed by ":", followed
        # by the version vector itself.
        # By convention, popular VCSes like CVS, SVN and GIT use "$"
        # around the actual version vector.
        [^\\s\\:]+\\:\\s*\\$[^\\$]+\\$
    )';
    /** @var string|null The version vector. */
    private $version;
    public function __construct(?string $version = null, ?Description $description = null)
    {
        Assert::nullOrNotEmpty($version);
        $this->version = $version;
        $this->description = $description;
    }
    /**
     * @return static
     */
    public static function create(?string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        if (empty($body)) {
            return new static();
        }
        $matches = [];
        if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {
            return new static(null, $descriptionFactory !== null ? $descriptionFactory->create($body, $context) : null);
        }
        Assert::notNull($descriptionFactory);
        return new static($matches[1], $descriptionFactory->create($matches[2] ?? '', $context));
    }
    /**
     * Gets the version section of the tag.
     */
    public function getVersion() : ?string
    {
        return $this->version;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $version = (string) $this->version;
        return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 *  For the full copyright and license information, please view the LICENSE
 *  file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Reference;

use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
/**
 * Url reference used by {@see \phpDocumentor\Reflection\DocBlock\Tags\See}
 */
final class Url implements Reference
{
    /** @var string */
    private $uri;
    public function __construct(string $uri)
    {
        Assert::stringNotEmpty($uri);
        $this->uri = $uri;
    }
    public function __toString() : string
    {
        return $this->uri;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 *  For the full copyright and license information, please view the LICENSE
 *  file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Reference;

/**
 * Interface for references in {@see \phpDocumentor\Reflection\DocBlock\Tags\See}
 */
interface Reference
{
    public function __toString() : string;
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 *  For the full copyright and license information, please view the LICENSE
 *  file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Reference;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen as RealFqsen;
/**
 * Fqsen reference used by {@see \phpDocumentor\Reflection\DocBlock\Tags\See}
 */
final class Fqsen implements Reference
{
    /** @var RealFqsen */
    private $fqsen;
    public function __construct(RealFqsen $fqsen)
    {
        $this->fqsen = $fqsen;
    }
    /**
     * @return string string representation of the referenced fqsen
     */
    public function __toString() : string
    {
        return (string) $this->fqsen;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
/**
 * Reflection class for a {@}link tag in a Docblock.
 */
final class Link extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'link';
    /** @var string */
    private $link;
    /**
     * Initializes a link to a URL.
     */
    public function __construct(string $link, ?Description $description = null)
    {
        $this->link = $link;
        $this->description = $description;
    }
    public static function create(string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::notNull($descriptionFactory);
        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
        $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
        return new static($parts[0], $description);
    }
    /**
     * Gets the link
     */
    public function getLink() : string
    {
        return $this->link;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $link = $this->link;
        return $link . ($description !== '' ? ($link !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_shift;
use function array_unshift;
use function implode;
use function strpos;
use function substr;
use const PREG_SPLIT_DELIM_CAPTURE;
/**
 * Reflection class for the {@}param tag in a Docblock.
 */
final class Param extends TagWithType implements Factory\StaticMethod
{
    /** @var string|null */
    private $variableName;
    /** @var bool determines whether this is a variadic argument */
    private $isVariadic;
    /** @var bool determines whether this is passed by reference */
    private $isReference;
    public function __construct(?string $variableName, ?Type $type = null, bool $isVariadic = \false, ?Description $description = null, bool $isReference = \false)
    {
        $this->name = 'param';
        $this->variableName = $variableName;
        $this->type = $type;
        $this->isVariadic = $isVariadic;
        $this->description = $description;
        $this->isReference = $isReference;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        [$firstPart, $body] = self::extractTypeFromBody($body);
        $type = null;
        $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
        $variableName = '';
        $isVariadic = \false;
        $isReference = \false;
        // if the first item that is encountered is not a variable; it is a type
        if ($firstPart && !self::strStartsWithVariable($firstPart)) {
            $type = $typeResolver->resolve($firstPart, $context);
        } else {
            // first part is not a type; we should prepend it to the parts array for further processing
            array_unshift($parts, $firstPart);
        }
        // if the next item starts with a $ or ...$ or &$ or &...$ it must be the variable name
        if (isset($parts[0]) && self::strStartsWithVariable($parts[0])) {
            $variableName = array_shift($parts);
            if ($type) {
                array_shift($parts);
            }
            Assert::notNull($variableName);
            if (strpos($variableName, '$') === 0) {
                $variableName = substr($variableName, 1);
            } elseif (strpos($variableName, '&$') === 0) {
                $isReference = \true;
                $variableName = substr($variableName, 2);
            } elseif (strpos($variableName, '...$') === 0) {
                $isVariadic = \true;
                $variableName = substr($variableName, 4);
            } elseif (strpos($variableName, '&...$') === 0) {
                $isVariadic = \true;
                $isReference = \true;
                $variableName = substr($variableName, 5);
            }
        }
        $description = $descriptionFactory->create(implode('', $parts), $context);
        return new static($variableName, $type, $isVariadic, $description, $isReference);
    }
    /**
     * Returns the variable's name.
     */
    public function getVariableName() : ?string
    {
        return $this->variableName;
    }
    /**
     * Returns whether this tag is variadic.
     */
    public function isVariadic() : bool
    {
        return $this->isVariadic;
    }
    /**
     * Returns whether this tag is passed by reference.
     */
    public function isReference() : bool
    {
        return $this->isReference;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $variableName = '';
        if ($this->variableName) {
            $variableName .= ($this->isReference ? '&' : '') . ($this->isVariadic ? '...' : '');
            $variableName .= '$' . $this->variableName;
        }
        $type = (string) $this->type;
        return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
    }
    private static function strStartsWithVariable(string $str) : bool
    {
        return strpos($str, '$') === 0 || strpos($str, '...$') === 0 || strpos($str, '&$') === 0 || strpos($str, '&...$') === 0;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_shift;
use function array_unshift;
use function implode;
use function strpos;
use function substr;
use const PREG_SPLIT_DELIM_CAPTURE;
/**
 * Reflection class for a {@}property-read tag in a Docblock.
 */
final class PropertyRead extends TagWithType implements Factory\StaticMethod
{
    /** @var string|null */
    protected $variableName;
    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
    {
        Assert::string($variableName);
        $this->name = 'property-read';
        $this->variableName = $variableName;
        $this->type = $type;
        $this->description = $description;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        [$firstPart, $body] = self::extractTypeFromBody($body);
        $type = null;
        $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
        $variableName = '';
        // if the first item that is encountered is not a variable; it is a type
        if ($firstPart && $firstPart[0] !== '$') {
            $type = $typeResolver->resolve($firstPart, $context);
        } else {
            // first part is not a type; we should prepend it to the parts array for further processing
            array_unshift($parts, $firstPart);
        }
        // if the next item starts with a $ it must be the variable name
        if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
            $variableName = array_shift($parts);
            if ($type) {
                array_shift($parts);
            }
            Assert::notNull($variableName);
            $variableName = substr($variableName, 1);
        }
        $description = $descriptionFactory->create(implode('', $parts), $context);
        return new static($variableName, $type, $description);
    }
    /**
     * Returns the variable's name.
     */
    public function getVariableName() : ?string
    {
        return $this->variableName;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        if ($this->variableName) {
            $variableName = '$' . $this->variableName;
        } else {
            $variableName = '';
        }
        $type = (string) $this->type;
        return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Mixed_;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Void_;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_keys;
use function explode;
use function implode;
use function is_string;
use function preg_match;
use function sort;
use function strpos;
use function substr;
use function trim;
use function var_export;
/**
 * Reflection class for an {@}method in a Docblock.
 */
final class Method extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'method';
    /** @var string */
    private $methodName;
    /**
     * @phpstan-var array<int, array{name: string, type: Type}>
     * @var array<int, array<string, Type|string>>
     */
    private $arguments;
    /** @var bool */
    private $isStatic;
    /** @var Type */
    private $returnType;
    /**
     * @param array<int, array<string, Type|string>> $arguments
     * @phpstan-param array<int, array{name: string, type: Type}|string> $arguments
     */
    public function __construct(string $methodName, array $arguments = [], ?Type $returnType = null, bool $static = \false, ?Description $description = null)
    {
        Assert::stringNotEmpty($methodName);
        if ($returnType === null) {
            $returnType = new Void_();
        }
        $this->methodName = $methodName;
        $this->arguments = $this->filterArguments($arguments);
        $this->returnType = $returnType;
        $this->isStatic = $static;
        $this->description = $description;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : ?self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        // 1. none or more whitespace
        // 2. optionally the keyword "static" followed by whitespace
        // 3. optionally a word with underscores followed by whitespace : as
        //    type for the return value
        // 4. then optionally a word with underscores followed by () and
        //    whitespace : as method name as used by phpDocumentor
        // 5. then a word with underscores, followed by ( and any character
        //    until a ) and whitespace : as method name with signature
        // 6. any remaining text : as description
        if (!preg_match('/^
                # Static keyword
                # Declares a static method ONLY if type is also present
                (?:
                    (static)
                    \\s+
                )?
                # Return type
                (?:
                    (
                        (?:[\\w\\|_\\\\]*\\$this[\\w\\|_\\\\]*)
                        |
                        (?:
                            (?:[\\w\\|_\\\\]+)
                            # array notation
                            (?:\\[\\])*
                        )*+
                    )
                    \\s+
                )?
                # Method name
                ([\\w_]+)
                # Arguments
                (?:
                    \\(([^\\)]*)\\)
                )?
                \\s*
                # Description
                (.*)
            $/sux', $body, $matches)) {
            return null;
        }
        [, $static, $returnType, $methodName, $argumentLines, $description] = $matches;
        $static = $static === 'static';
        if ($returnType === '') {
            $returnType = 'void';
        }
        $returnType = $typeResolver->resolve($returnType, $context);
        $description = $descriptionFactory->create($description, $context);
        /** @phpstan-var array<int, array{name: string, type: Type}> $arguments */
        $arguments = [];
        if ($argumentLines !== '') {
            $argumentsExploded = explode(',', $argumentLines);
            foreach ($argumentsExploded as $argument) {
                $argument = explode(' ', self::stripRestArg(trim($argument)), 2);
                if (strpos($argument[0], '$') === 0) {
                    $argumentName = substr($argument[0], 1);
                    $argumentType = new Mixed_();
                } else {
                    $argumentType = $typeResolver->resolve($argument[0], $context);
                    $argumentName = '';
                    if (isset($argument[1])) {
                        $argument[1] = self::stripRestArg($argument[1]);
                        $argumentName = substr($argument[1], 1);
                    }
                }
                $arguments[] = ['name' => $argumentName, 'type' => $argumentType];
            }
        }
        return new static($methodName, $arguments, $returnType, $static, $description);
    }
    /**
     * Retrieves the method name.
     */
    public function getMethodName() : string
    {
        return $this->methodName;
    }
    /**
     * @return array<int, array<string, Type|string>>
     * @phpstan-return array<int, array{name: string, type: Type}>
     */
    public function getArguments() : array
    {
        return $this->arguments;
    }
    /**
     * Checks whether the method tag describes a static method or not.
     *
     * @return bool TRUE if the method declaration is for a static method, FALSE otherwise.
     */
    public function isStatic() : bool
    {
        return $this->isStatic;
    }
    public function getReturnType() : Type
    {
        return $this->returnType;
    }
    public function __toString() : string
    {
        $arguments = [];
        foreach ($this->arguments as $argument) {
            $arguments[] = $argument['type'] . ' $' . $argument['name'];
        }
        $argumentStr = '(' . implode(', ', $arguments) . ')';
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $static = $this->isStatic ? 'static' : '';
        $returnType = (string) $this->returnType;
        $methodName = $this->methodName;
        return $static . ($returnType !== '' ? ($static !== '' ? ' ' : '') . $returnType : '') . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $methodName : '') . $argumentStr . ($description !== '' ? ' ' . $description : '');
    }
    /**
     * @param mixed[][]|string[] $arguments
     * @phpstan-param array<int, array{name: string, type: Type}|string> $arguments
     *
     * @return mixed[][]
     * @phpstan-return array<int, array{name: string, type: Type}>
     */
    private function filterArguments(array $arguments = []) : array
    {
        $result = [];
        foreach ($arguments as $argument) {
            if (is_string($argument)) {
                $argument = ['name' => $argument];
            }
            if (!isset($argument['type'])) {
                $argument['type'] = new Mixed_();
            }
            $keys = array_keys($argument);
            sort($keys);
            if ($keys !== ['name', 'type']) {
                throw new InvalidArgumentException('Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, \true));
            }
            $result[] = $argument;
        }
        return $result;
    }
    private static function stripRestArg(string $argument) : string
    {
        if (strpos($argument, '...') === 0) {
            $argument = trim(substr($argument, 3));
        }
        return $argument;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_shift;
use function array_unshift;
use function implode;
use function strpos;
use function substr;
use const PREG_SPLIT_DELIM_CAPTURE;
/**
 * Reflection class for a {@}property-write tag in a Docblock.
 */
final class PropertyWrite extends TagWithType implements Factory\StaticMethod
{
    /** @var string */
    protected $variableName;
    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
    {
        Assert::string($variableName);
        $this->name = 'property-write';
        $this->variableName = $variableName;
        $this->type = $type;
        $this->description = $description;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        [$firstPart, $body] = self::extractTypeFromBody($body);
        $type = null;
        $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
        $variableName = '';
        // if the first item that is encountered is not a variable; it is a type
        if ($firstPart && $firstPart[0] !== '$') {
            $type = $typeResolver->resolve($firstPart, $context);
        } else {
            // first part is not a type; we should prepend it to the parts array for further processing
            array_unshift($parts, $firstPart);
        }
        // if the next item starts with a $ it must be the variable name
        if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
            $variableName = array_shift($parts);
            if ($type) {
                array_shift($parts);
            }
            Assert::notNull($variableName);
            $variableName = substr($variableName, 1);
        }
        $description = $descriptionFactory->create(implode('', $parts), $context);
        return new static($variableName, $type, $description);
    }
    /**
     * Returns the variable's name.
     */
    public function getVariableName() : ?string
    {
        return $this->variableName;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        if ($this->variableName) {
            $variableName = '$' . $this->variableName;
        } else {
            $variableName = '';
        }
        $type = (string) $this->type;
        return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Reference\Fqsen as FqsenRef;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Reference\Reference;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Reference\Url;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\FqsenResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_key_exists;
use function explode;
use function preg_match;
/**
 * Reflection class for an {@}see tag in a Docblock.
 */
final class See extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'see';
    /** @var Reference */
    protected $refers;
    /**
     * Initializes this tag.
     */
    public function __construct(Reference $refers, ?Description $description = null)
    {
        $this->refers = $refers;
        $this->description = $description;
    }
    public static function create(string $body, ?FqsenResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::notNull($descriptionFactory);
        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
        $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null;
        // https://tools.ietf.org/html/rfc2396#section-3
        if (preg_match('#\\w://\\w#', $parts[0])) {
            return new static(new Url($parts[0]), $description);
        }
        return new static(new FqsenRef(self::resolveFqsen($parts[0], $typeResolver, $context)), $description);
    }
    private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
    {
        Assert::notNull($fqsenResolver);
        $fqsenParts = explode('::', $parts);
        $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
        if (!array_key_exists(1, $fqsenParts)) {
            return $resolved;
        }
        return new Fqsen($resolved . '::' . $fqsenParts[1]);
    }
    /**
     * Returns the ref of this tag.
     */
    public function getReference() : Reference
    {
        return $this->refers;
    }
    /**
     * Returns a string representation of this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $refers = (string) $this->refers;
        return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function preg_match;
/**
 * Reflection class for a {@}version tag in a Docblock.
 */
final class Version extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'version';
    /**
     * PCRE regular expression matching a version vector.
     * Assumes the "x" modifier.
     */
    public const REGEX_VECTOR = '(?:
        # Normal release vectors.
        \\d\\S*
        |
        # VCS version vectors. Per PHPCS, they are expected to
        # follow the form of the VCS name, followed by ":", followed
        # by the version vector itself.
        # By convention, popular VCSes like CVS, SVN and GIT use "$"
        # around the actual version vector.
        [^\\s\\:]+\\:\\s*\\$[^\\$]+\\$
    )';
    /** @var string|null The version vector. */
    private $version;
    public function __construct(?string $version = null, ?Description $description = null)
    {
        Assert::nullOrStringNotEmpty($version);
        $this->version = $version;
        $this->description = $description;
    }
    public static function create(?string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : ?self
    {
        if (empty($body)) {
            return new static();
        }
        $matches = [];
        if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {
            return null;
        }
        $description = null;
        if ($descriptionFactory !== null) {
            $description = $descriptionFactory->create($matches[2] ?? '', $context);
        }
        return new static($matches[1], $description);
    }
    /**
     * Gets the version section of the tag.
     */
    public function getVersion() : ?string
    {
        return $this->version;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $version = (string) $this->version;
        return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use function max;
use function str_repeat;
use function strlen;
class AlignFormatter implements Formatter
{
    /** @var int The maximum tag name length. */
    protected $maxLen = 0;
    /**
     * @param Tag[] $tags All tags that should later be aligned with the formatter.
     */
    public function __construct(array $tags)
    {
        foreach ($tags as $tag) {
            $this->maxLen = max($this->maxLen, strlen($tag->getName()));
        }
    }
    /**
     * Formats the given tag to return a simple plain text version.
     */
    public function format(Tag $tag) : string
    {
        return '@' . $tag->getName() . str_repeat(' ', $this->maxLen - strlen($tag->getName()) + 1) . $tag;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use function trim;
class PassthroughFormatter implements Formatter
{
    /**
     * Formats the given tag to return a simple plain text version.
     */
    public function format(Tag $tag) : string
    {
        return trim('@' . $tag->getName() . ' ' . $tag);
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_shift;
use function array_unshift;
use function implode;
use function strpos;
use function substr;
use const PREG_SPLIT_DELIM_CAPTURE;
/**
 * Reflection class for a {@}property tag in a Docblock.
 */
final class Property extends TagWithType implements Factory\StaticMethod
{
    /** @var string|null */
    protected $variableName;
    public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
    {
        Assert::string($variableName);
        $this->name = 'property';
        $this->variableName = $variableName;
        $this->type = $type;
        $this->description = $description;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        [$firstPart, $body] = self::extractTypeFromBody($body);
        $type = null;
        $parts = Utils::pregSplit('/(\\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE);
        $variableName = '';
        // if the first item that is encountered is not a variable; it is a type
        if ($firstPart && $firstPart[0] !== '$') {
            $type = $typeResolver->resolve($firstPart, $context);
        } else {
            // first part is not a type; we should prepend it to the parts array for further processing
            array_unshift($parts, $firstPart);
        }
        // if the next item starts with a $ it must be the variable name
        if (isset($parts[0]) && strpos($parts[0], '$') === 0) {
            $variableName = array_shift($parts);
            if ($type) {
                array_shift($parts);
            }
            Assert::notNull($variableName);
            $variableName = substr($variableName, 1);
        }
        $description = $descriptionFactory->create(implode('', $parts), $context);
        return new static($variableName, $type, $description);
    }
    /**
     * Returns the variable's name.
     */
    public function getVariableName() : ?string
    {
        return $this->variableName;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        if ($this->variableName) {
            $variableName = '$' . $this->variableName;
        } else {
            $variableName = '';
        }
        $type = (string) $this->type;
        return $type . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\FqsenResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_key_exists;
use function explode;
/**
 * Reflection class for a @covers tag in a Docblock.
 */
final class Covers extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'covers';
    /** @var Fqsen */
    private $refers;
    /**
     * Initializes this tag.
     */
    public function __construct(Fqsen $refers, ?Description $description = null)
    {
        $this->refers = $refers;
        $this->description = $description;
    }
    public static function create(string $body, ?DescriptionFactory $descriptionFactory = null, ?FqsenResolver $resolver = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($descriptionFactory);
        Assert::notNull($resolver);
        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
        return new static(self::resolveFqsen($parts[0], $resolver, $context), $descriptionFactory->create($parts[1] ?? '', $context));
    }
    private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
    {
        Assert::notNull($fqsenResolver);
        $fqsenParts = explode('::', $parts);
        $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
        if (!array_key_exists(1, $fqsenParts)) {
            return $resolved;
        }
        return new Fqsen($resolved . '::' . $fqsenParts[1]);
    }
    /**
     * Returns the structural element this tag refers to.
     */
    public function getReference() : Fqsen
    {
        return $this->refers;
    }
    /**
     * Returns a string representation of this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $refers = (string) $this->refers;
        return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
interface Formatter
{
    /**
     * Formats a tag into a string representation according to a specific format, such as Markdown.
     */
    public function format(Tag $tag) : string;
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function preg_match;
/**
 * Reflection class for a {@}since tag in a Docblock.
 */
final class Since extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'since';
    /**
     * PCRE regular expression matching a version vector.
     * Assumes the "x" modifier.
     */
    public const REGEX_VECTOR = '(?:
        # Normal release vectors.
        \\d\\S*
        |
        # VCS version vectors. Per PHPCS, they are expected to
        # follow the form of the VCS name, followed by ":", followed
        # by the version vector itself.
        # By convention, popular VCSes like CVS, SVN and GIT use "$"
        # around the actual version vector.
        [^\\s\\:]+\\:\\s*\\$[^\\$]+\\$
    )';
    /** @var string|null The version vector. */
    private $version;
    public function __construct(?string $version = null, ?Description $description = null)
    {
        Assert::nullOrNotEmpty($version);
        $this->version = $version;
        $this->description = $description;
    }
    public static function create(?string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : ?self
    {
        if (empty($body)) {
            return new static();
        }
        $matches = [];
        if (!preg_match('/^(' . self::REGEX_VECTOR . ')\\s*(.+)?$/sux', $body, $matches)) {
            return null;
        }
        Assert::notNull($descriptionFactory);
        return new static($matches[1], $descriptionFactory->create($matches[2] ?? '', $context));
    }
    /**
     * Gets the version section of the tag.
     */
    public function getVersion() : ?string
    {
        return $this->version;
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $version = (string) $this->version;
        return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
/**
 * Reflection class for a {@}throws tag in a Docblock.
 */
final class Throws extends TagWithType implements Factory\StaticMethod
{
    public function __construct(Type $type, ?Description $description = null)
    {
        $this->name = 'throws';
        $this->type = $type;
        $this->description = $description;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        [$type, $description] = self::extractTypeFromBody($body);
        $type = $typeResolver->resolve($type, $context);
        $description = $descriptionFactory->create($description, $context);
        return new static($type, $description);
    }
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $type = (string) $this->type;
        return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Fqsen;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\FqsenResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Utils;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_key_exists;
use function explode;
/**
 * Reflection class for a {@}uses tag in a Docblock.
 */
final class Uses extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'uses';
    /** @var Fqsen */
    protected $refers;
    /**
     * Initializes this tag.
     */
    public function __construct(Fqsen $refers, ?Description $description = null)
    {
        $this->refers = $refers;
        $this->description = $description;
    }
    public static function create(string $body, ?FqsenResolver $resolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::notNull($resolver);
        Assert::notNull($descriptionFactory);
        $parts = Utils::pregSplit('/\\s+/Su', $body, 2);
        return new static(self::resolveFqsen($parts[0], $resolver, $context), $descriptionFactory->create($parts[1] ?? '', $context));
    }
    private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen
    {
        Assert::notNull($fqsenResolver);
        $fqsenParts = explode('::', $parts);
        $resolved = $fqsenResolver->resolve($fqsenParts[0], $context);
        if (!array_key_exists(1, $fqsenParts)) {
            return $resolved;
        }
        return new Fqsen($resolved . '::' . $fqsenParts[1]);
    }
    /**
     * Returns the structural element this tag refers to.
     */
    public function getReference() : Fqsen
    {
        return $this->refers;
    }
    /**
     * Returns a string representation of this tag.
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $refers = (string) $this->refers;
        return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use function in_array;
use function strlen;
use function substr;
use function trim;
abstract class TagWithType extends BaseTag
{
    /** @var ?Type */
    protected $type;
    /**
     * Returns the type section of the variable.
     */
    public function getType() : ?Type
    {
        return $this->type;
    }
    /**
     * @return string[]
     */
    protected static function extractTypeFromBody(string $body) : array
    {
        $type = '';
        $nestingLevel = 0;
        for ($i = 0, $iMax = strlen($body); $i < $iMax; $i++) {
            $character = $body[$i];
            if ($nestingLevel === 0 && trim($character) === '') {
                break;
            }
            $type .= $character;
            if (in_array($character, ['<', '(', '[', '{'])) {
                $nestingLevel++;
                continue;
            }
            if (in_array($character, ['>', ')', ']', '}'])) {
                $nestingLevel--;
                continue;
            }
        }
        $description = trim(substr($body, strlen($type)));
        return [$type, $description];
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function array_key_exists;
use function preg_match;
use function rawurlencode;
use function str_replace;
use function strpos;
use function trim;
/**
 * Reflection class for a {@}example tag in a Docblock.
 */
final class Example implements Tag, Factory\StaticMethod
{
    /** @var string Path to a file to use as an example. May also be an absolute URI. */
    private $filePath;
    /**
     * @var bool Whether the file path component represents an URI. This determines how the file portion
     *     appears at {@link getContent()}.
     */
    private $isURI;
    /** @var int */
    private $startingLine;
    /** @var int */
    private $lineCount;
    /** @var string|null */
    private $content;
    public function __construct(string $filePath, bool $isURI, int $startingLine, int $lineCount, ?string $content)
    {
        Assert::stringNotEmpty($filePath);
        Assert::greaterThanEq($startingLine, 1);
        Assert::greaterThanEq($lineCount, 0);
        $this->filePath = $filePath;
        $this->startingLine = $startingLine;
        $this->lineCount = $lineCount;
        if ($content !== null) {
            $this->content = trim($content);
        }
        $this->isURI = $isURI;
    }
    public function getContent() : string
    {
        if ($this->content === null || $this->content === '') {
            $filePath = $this->filePath;
            if ($this->isURI) {
                $filePath = $this->isUriRelative($this->filePath) ? str_replace('%2F', '/', rawurlencode($this->filePath)) : $this->filePath;
            }
            return trim($filePath);
        }
        return $this->content;
    }
    public function getDescription() : ?string
    {
        return $this->content;
    }
    public static function create(string $body) : ?Tag
    {
        // File component: File path in quotes or File URI / Source information
        if (!preg_match('/^\\s*(?:(\\"[^\\"]+\\")|(\\S+))(?:\\s+(.*))?$/sux', $body, $matches)) {
            return null;
        }
        $filePath = null;
        $fileUri = null;
        if ($matches[1] !== '') {
            $filePath = $matches[1];
        } else {
            $fileUri = $matches[2];
        }
        $startingLine = 1;
        $lineCount = 0;
        $description = null;
        if (array_key_exists(3, $matches)) {
            $description = $matches[3];
            // Starting line / Number of lines / Description
            if (preg_match('/^([1-9]\\d*)(?:\\s+((?1))\\s*)?(.*)$/sux', $matches[3], $contentMatches)) {
                $startingLine = (int) $contentMatches[1];
                if (isset($contentMatches[2])) {
                    $lineCount = (int) $contentMatches[2];
                }
                if (array_key_exists(3, $contentMatches)) {
                    $description = $contentMatches[3];
                }
            }
        }
        return new static($filePath ?? $fileUri ?? '', $fileUri !== null, $startingLine, $lineCount, $description);
    }
    /**
     * Returns the file path.
     *
     * @return string Path to a file to use as an example.
     *     May also be an absolute URI.
     */
    public function getFilePath() : string
    {
        return trim($this->filePath, '"');
    }
    /**
     * Returns a string representation for this tag.
     */
    public function __toString() : string
    {
        $filePath = $this->filePath;
        $isDefaultLine = $this->startingLine === 1 && $this->lineCount === 0;
        $startingLine = !$isDefaultLine ? (string) $this->startingLine : '';
        $lineCount = !$isDefaultLine ? (string) $this->lineCount : '';
        $content = (string) $this->content;
        return $filePath . ($startingLine !== '' ? ($filePath !== '' ? ' ' : '') . $startingLine : '') . ($lineCount !== '' ? ($filePath !== '' || $startingLine !== '' ? ' ' : '') . $lineCount : '') . ($content !== '' ? ($filePath !== '' || $startingLine !== '' || $lineCount !== '' ? ' ' : '') . $content : '');
    }
    /**
     * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute).
     */
    private function isUriRelative(string $uri) : bool
    {
        return strpos($uri, ':') === \false;
    }
    public function getStartingLine() : int
    {
        return $this->startingLine;
    }
    public function getLineCount() : int
    {
        return $this->lineCount;
    }
    public function getName() : string
    {
        return 'example';
    }
    public function render(?Formatter $formatter = null) : string
    {
        if ($formatter === null) {
            $formatter = new Formatter\PassthroughFormatter();
        }
        return $formatter->format($this);
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use Closure;
use Exception;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
use ReflectionClass;
use ReflectionException;
use ReflectionFunction;
use Throwable;
use function array_map;
use function get_class;
use function get_resource_type;
use function is_array;
use function is_object;
use function is_resource;
use function sprintf;
/**
 * This class represents an exception during the tag creation
 *
 * Since the internals of the library are relaying on the correct syntax of a docblock
 * we cannot simply throw exceptions at all time because the exceptions will break the creation of a
 * docklock. Just silently ignore the exceptions is not an option because the user as an issue to fix.
 *
 * This tag holds that error information until a using application is able to display it. The object wil just behave
 * like any normal tag. So the normal application flow will not break.
 */
final class InvalidTag implements Tag
{
    /** @var string */
    private $name;
    /** @var string */
    private $body;
    /** @var Throwable|null */
    private $throwable;
    private function __construct(string $name, string $body)
    {
        $this->name = $name;
        $this->body = $body;
    }
    public function getException() : ?Throwable
    {
        return $this->throwable;
    }
    public function getName() : string
    {
        return $this->name;
    }
    public static function create(string $body, string $name = '') : self
    {
        return new self($name, $body);
    }
    public function withError(Throwable $exception) : self
    {
        $this->flattenExceptionBacktrace($exception);
        $tag = new self($this->name, $this->body);
        $tag->throwable = $exception;
        return $tag;
    }
    /**
     * Removes all complex types from backtrace
     *
     * Not all objects are serializable. So we need to remove them from the
     * stored exception to be sure that we do not break existing library usage.
     */
    private function flattenExceptionBacktrace(Throwable $exception) : void
    {
        $traceProperty = (new ReflectionClass(Exception::class))->getProperty('trace');
        $traceProperty->setAccessible(\true);
        do {
            $trace = $exception->getTrace();
            if (isset($trace[0]['args'])) {
                $trace = array_map(function (array $call) : array {
                    $call['args'] = array_map([$this, 'flattenArguments'], $call['args'] ?? []);
                    return $call;
                }, $trace);
            }
            $traceProperty->setValue($exception, $trace);
            $exception = $exception->getPrevious();
        } while ($exception !== null);
        $traceProperty->setAccessible(\false);
    }
    /**
     * @param mixed $value
     *
     * @return mixed
     *
     * @throws ReflectionException
     */
    private function flattenArguments($value)
    {
        if ($value instanceof Closure) {
            $closureReflection = new ReflectionFunction($value);
            $value = sprintf('(Closure at %s:%s)', $closureReflection->getFileName(), $closureReflection->getStartLine());
        } elseif (is_object($value)) {
            $value = sprintf('object(%s)', get_class($value));
        } elseif (is_resource($value)) {
            $value = sprintf('resource(%s)', get_resource_type($value));
        } elseif (is_array($value)) {
            $value = array_map([$this, 'flattenArguments'], $value);
        }
        return $value;
    }
    public function render(?Formatter $formatter = null) : string
    {
        if ($formatter === null) {
            $formatter = new Formatter\PassthroughFormatter();
        }
        return $formatter->format($this);
    }
    public function __toString() : string
    {
        return $this->body;
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\Factory;

/**
 * @deprecated This contract is totally covered by Tag contract. Every class using StaticMethod also use Tag
 */
interface StaticMethod
{
    /**
     * @return mixed
     */
    public static function create(string $body);
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use InvalidArgumentException;
use function filter_var;
use function preg_match;
use function trim;
use const FILTER_VALIDATE_EMAIL;
/**
 * Reflection class for an {@}author tag in a Docblock.
 */
final class Author extends BaseTag implements Factory\StaticMethod
{
    /** @var string register that this is the author tag. */
    protected $name = 'author';
    /** @var string The name of the author */
    private $authorName;
    /** @var string The email of the author */
    private $authorEmail;
    /**
     * Initializes this tag with the author name and e-mail.
     */
    public function __construct(string $authorName, string $authorEmail)
    {
        if ($authorEmail && !filter_var($authorEmail, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException('The author tag does not have a valid e-mail address');
        }
        $this->authorName = $authorName;
        $this->authorEmail = $authorEmail;
    }
    /**
     * Gets the author's name.
     *
     * @return string The author's name.
     */
    public function getAuthorName() : string
    {
        return $this->authorName;
    }
    /**
     * Returns the author's email.
     *
     * @return string The author's email.
     */
    public function getEmail() : string
    {
        return $this->authorEmail;
    }
    /**
     * Returns this tag in string form.
     */
    public function __toString() : string
    {
        if ($this->authorEmail) {
            $authorEmail = '<' . $this->authorEmail . '>';
        } else {
            $authorEmail = '';
        }
        $authorName = $this->authorName;
        return $authorName . ($authorEmail !== '' ? ($authorName !== '' ? ' ' : '') . $authorEmail : '');
    }
    /**
     * Attempts to create a new Author object based on the tag body.
     */
    public static function create(string $body) : ?self
    {
        $splitTagContent = preg_match('/^([^\\<]*)(?:\\<([^\\>]*)\\>)?$/u', $body, $matches);
        if (!$splitTagContent) {
            return null;
        }
        $authorName = trim($matches[1]);
        $email = isset($matches[2]) ? trim($matches[2]) : '';
        return new static($authorName, $email);
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Type;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\TypeResolver;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
/**
 * Reflection class for a {@}return tag in a Docblock.
 */
final class Return_ extends TagWithType implements Factory\StaticMethod
{
    public function __construct(Type $type, ?Description $description = null)
    {
        $this->name = 'return';
        $this->type = $type;
        $this->description = $description;
    }
    public static function create(string $body, ?TypeResolver $typeResolver = null, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::notNull($typeResolver);
        Assert::notNull($descriptionFactory);
        [$type, $description] = self::extractTypeFromBody($body);
        $type = $typeResolver->resolve($type, $context);
        $description = $descriptionFactory->create($description, $context);
        return new static($type, $description);
    }
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $type = $this->type ? '' . $this->type : 'mixed';
        return $type . ($description !== '' ? ' ' . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function preg_match;
/**
 * Parses a tag definition for a DocBlock.
 */
final class Generic extends BaseTag implements Factory\StaticMethod
{
    /**
     * Parses a tag and populates the member variables.
     *
     * @param string      $name        Name of the tag.
     * @param Description $description The contents of the given tag.
     */
    public function __construct(string $name, ?Description $description = null)
    {
        $this->validateTagName($name);
        $this->name = $name;
        $this->description = $description;
    }
    /**
     * Creates a new tag that represents any unknown tag type.
     *
     * @return static
     */
    public static function create(string $body, string $name = '', ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($name);
        Assert::notNull($descriptionFactory);
        $description = $body !== '' ? $descriptionFactory->create($body, $context) : null;
        return new static($name, $description);
    }
    /**
     * Returns the tag as a serialized string
     */
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        return $description;
    }
    /**
     * Validates if the tag name matches the expected format, otherwise throws an exception.
     */
    private function validateTagName(string $name) : void
    {
        if (!preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) {
            throw new InvalidArgumentException('The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, ' . 'hyphens and backslashes.');
        }
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Description;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types\Context as TypeContext;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
use function preg_match;
/**
 * Reflection class for a {@}source tag in a Docblock.
 */
final class Source extends BaseTag implements Factory\StaticMethod
{
    /** @var string */
    protected $name = 'source';
    /** @var int The starting line, relative to the structural element's location. */
    private $startingLine;
    /** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */
    private $lineCount;
    /**
     * @param int|string      $startingLine should be a to int convertible value
     * @param int|string|null $lineCount    should be a to int convertible value
     */
    public function __construct($startingLine, $lineCount = null, ?Description $description = null)
    {
        Assert::integerish($startingLine);
        Assert::nullOrIntegerish($lineCount);
        $this->startingLine = (int) $startingLine;
        $this->lineCount = $lineCount !== null ? (int) $lineCount : null;
        $this->description = $description;
    }
    public static function create(string $body, ?DescriptionFactory $descriptionFactory = null, ?TypeContext $context = null) : self
    {
        Assert::stringNotEmpty($body);
        Assert::notNull($descriptionFactory);
        $startingLine = 1;
        $lineCount = null;
        $description = null;
        // Starting line / Number of lines / Description
        if (preg_match('/^([1-9]\\d*)\\s*(?:((?1))\\s+)?(.*)$/sux', $body, $matches)) {
            $startingLine = (int) $matches[1];
            if (isset($matches[2]) && $matches[2] !== '') {
                $lineCount = (int) $matches[2];
            }
            $description = $matches[3];
        }
        return new static($startingLine, $lineCount, $descriptionFactory->create($description ?? '', $context));
    }
    /**
     * Gets the starting line.
     *
     * @return int The starting line, relative to the structural element's
     *     location.
     */
    public function getStartingLine() : int
    {
        return $this->startingLine;
    }
    /**
     * Returns the number of lines.
     *
     * @return int|null The number of lines, relative to the starting line. NULL
     *     means "to the end".
     */
    public function getLineCount() : ?int
    {
        return $this->lineCount;
    }
    public function __toString() : string
    {
        if ($this->description) {
            $description = $this->description->render();
        } else {
            $description = '';
        }
        $startingLine = (string) $this->startingLine;
        $lineCount = $this->lineCount !== null ? ' ' . $this->lineCount : '';
        return $startingLine . $lineCount . ($description !== '' ? ' ' . $description : '');
    }
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tag;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlock\Tags\TagWithType;
use _HumbugBox1cb33d1f20f1\Webmozart\Assert\Assert;
final class DocBlock
{
    /** @var string The opening line for this docblock. */
    private $summary;
    /** @var DocBlock\Description The actual description for this docblock. */
    private $description;
    /** @var Tag[] An array containing all the tags in this docblock; except inline. */
    private $tags = [];
    /** @var Types\Context|null Information about the context of this DocBlock. */
    private $context;
    /** @var Location|null Information about the location of this DocBlock. */
    private $location;
    /** @var bool Is this DocBlock (the start of) a template? */
    private $isTemplateStart;
    /** @var bool Does this DocBlock signify the end of a DocBlock template? */
    private $isTemplateEnd;
    /**
     * @param DocBlock\Tag[] $tags
     * @param Types\Context  $context  The context in which the DocBlock occurs.
     * @param Location       $location The location within the file that this DocBlock occurs in.
     */
    public function __construct(string $summary = '', ?DocBlock\Description $description = null, array $tags = [], ?Types\Context $context = null, ?Location $location = null, bool $isTemplateStart = \false, bool $isTemplateEnd = \false)
    {
        Assert::allIsInstanceOf($tags, Tag::class);
        $this->summary = $summary;
        $this->description = $description ?: new DocBlock\Description('');
        foreach ($tags as $tag) {
            $this->addTag($tag);
        }
        $this->context = $context;
        $this->location = $location;
        $this->isTemplateEnd = $isTemplateEnd;
        $this->isTemplateStart = $isTemplateStart;
    }
    public function getSummary() : string
    {
        return $this->summary;
    }
    public function getDescription() : DocBlock\Description
    {
        return $this->description;
    }
    /**
     * Returns the current context.
     */
    public function getContext() : ?Types\Context
    {
        return $this->context;
    }
    /**
     * Returns the current location.
     */
    public function getLocation() : ?Location
    {
        return $this->location;
    }
    /**
     * Returns whether this DocBlock is the start of a Template section.
     *
     * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker
     * (`#@+`) that is appended directly after the opening `/**` of a DocBlock.
     *
     * An example of such an opening is:
     *
     * ```
     * /**#@+
     *  * My DocBlock
     *  * /
     * ```
     *
     * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all
     * elements that follow until another DocBlock is found that contains the closing marker (`#@-`).
     *
     * @see self::isTemplateEnd() for the check whether a closing marker was provided.
     */
    public function isTemplateStart() : bool
    {
        return $this->isTemplateStart;
    }
    /**
     * Returns whether this DocBlock is the end of a Template section.
     *
     * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality.
     */
    public function isTemplateEnd() : bool
    {
        return $this->isTemplateEnd;
    }
    /**
     * Returns the tags for this DocBlock.
     *
     * @return Tag[]
     */
    public function getTags() : array
    {
        return $this->tags;
    }
    /**
     * Returns an array of tags matching the given name. If no tags are found
     * an empty array is returned.
     *
     * @param string $name String to search by.
     *
     * @return Tag[]
     */
    public function getTagsByName(string $name) : array
    {
        $result = [];
        foreach ($this->getTags() as $tag) {
            if ($tag->getName() !== $name) {
                continue;
            }
            $result[] = $tag;
        }
        return $result;
    }
    /**
     * Returns an array of tags with type matching the given name. If no tags are found
     * an empty array is returned.
     *
     * @param string $name String to search by.
     *
     * @return TagWithType[]
     */
    public function getTagsWithTypeByName(string $name) : array
    {
        $result = [];
        foreach ($this->getTagsByName($name) as $tag) {
            if (!$tag instanceof TagWithType) {
                continue;
            }
            $result[] = $tag;
        }
        return $result;
    }
    /**
     * Checks if a tag of a certain type is present in this DocBlock.
     *
     * @param string $name Tag name to check for.
     */
    public function hasTag(string $name) : bool
    {
        foreach ($this->getTags() as $tag) {
            if ($tag->getName() === $name) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * Remove a tag from this DocBlock.
     *
     * @param Tag $tagToRemove The tag to remove.
     */
    public function removeTag(Tag $tagToRemove) : void
    {
        foreach ($this->tags as $key => $tag) {
            if ($tag === $tagToRemove) {
                unset($this->tags[$key]);
                break;
            }
        }
    }
    /**
     * Adds a tag to this DocBlock.
     *
     * @param Tag $tag The tag to add.
     */
    private function addTag(Tag $tag) : void
    {
        $this->tags[] = $tag;
    }
}
The MIT License (MIT)

Copyright (c) 2010 Mike van Riel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

declare (strict_types=1);
/**
 * phpDocumentor
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

/**
 * Interface for project. Since the definition of a project can be different per factory this interface will be small.
 */
interface Project
{
    /**
     * Returns the name of the project.
     */
    public function getName() : string;
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

/**
 * The location where an element occurs within a file.
 *
 * @psalm-immutable
 */
final class Location
{
    /** @var int */
    private $lineNumber = 0;
    /** @var int */
    private $columnNumber = 0;
    /**
     * Initializes the location for an element using its line number in the file and optionally the column number.
     */
    public function __construct(int $lineNumber, int $columnNumber = 0)
    {
        $this->lineNumber = $lineNumber;
        $this->columnNumber = $columnNumber;
    }
    /**
     * Returns the line number that is covered by this location.
     */
    public function getLineNumber() : int
    {
        return $this->lineNumber;
    }
    /**
     * Returns the column number (character position on a line) for this location object.
     */
    public function getColumnNumber() : int
    {
        return $this->columnNumber;
    }
}
<?php

declare (strict_types=1);
/**
 * phpDocumentor
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

/**
 * Interface for project factories. A project factory shall convert a set of files
 * into an object implementing the Project interface.
 */
interface ProjectFactory
{
    /**
     * Creates a project from the set of files.
     *
     * @param File[] $files
     */
    public function create(string $name, array $files) : Project;
}
<?php

declare (strict_types=1);
/**
 * This file is part of phpDocumentor.
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

/**
 * Interface for files processed by the ProjectFactory
 */
interface File
{
    /**
     * Returns the content of the file as a string.
     */
    public function getContents() : string;
    /**
     * Returns md5 hash of the file.
     */
    public function md5() : string;
    /**
     * Returns an relative path to the file.
     */
    public function path() : string;
}
<?php

declare (strict_types=1);
/**
 * phpDocumentor
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

use InvalidArgumentException;
use function assert;
use function end;
use function explode;
use function is_string;
use function preg_match;
use function sprintf;
use function trim;
/**
 * Value Object for Fqsen.
 *
 * @link https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc-meta.md
 *
 * @psalm-immutable
 */
final class Fqsen
{
    /** @var string full quallified class name */
    private $fqsen;
    /** @var string name of the element without path. */
    private $name;
    /**
     * Initializes the object.
     *
     * @throws InvalidArgumentException when $fqsen is not matching the format.
     */
    public function __construct(string $fqsen)
    {
        $matches = [];
        $result = preg_match(
            //phpcs:ignore Generic.Files.LineLength.TooLong
            '/^\\\\([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff\\\\]*)?(?:[:]{2}\\$?([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*))?(?:\\(\\))?$/',
            $fqsen,
            $matches
        );
        if ($result === 0) {
            throw new InvalidArgumentException(sprintf('"%s" is not a valid Fqsen.', $fqsen));
        }
        $this->fqsen = $fqsen;
        if (isset($matches[2])) {
            $this->name = $matches[2];
        } else {
            $matches = explode('\\', $fqsen);
            $name = end($matches);
            assert(is_string($name));
            $this->name = trim($name, '()');
        }
    }
    /**
     * converts this class to string.
     */
    public function __toString() : string
    {
        return $this->fqsen;
    }
    /**
     * Returns the name of the element without path.
     */
    public function getName() : string
    {
        return $this->name;
    }
}
<?php

declare (strict_types=1);
/**
 * phpDocumentor
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * @link      http://phpdoc.org
 */
namespace _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection;

/**
 * Interface for Api Elements
 */
interface Element
{
    /**
     * Returns the Fqsen of the element.
     */
    public function getFqsen() : Fqsen;
    /**
     * Returns the name of the element.
     */
    public function getName() : string;
}
The MIT License (MIT)

Copyright (c) 2015 phpDocumentor

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Thrown if a promise doesn't resolve within a specified timeout.
 *
 * @see \Amp\Promise\timeout()
 */
class TimeoutException extends \Exception
{
    /**
     * @param string $message Exception message.
     */
    public function __construct(string $message = "Operation timed out")
    {
        parent::__construct($message);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

class MultiReasonException extends \Exception
{
    /** @var \Throwable[] */
    private $reasons;
    /**
     * @param \Throwable[] $reasons Array of exceptions rejecting the promise.
     * @param string|null  $message
     */
    public function __construct(array $reasons, string $message = null)
    {
        parent::__construct($message ?: "Multiple errors encountered; use " . self::class . "::getReasons() to retrieve the array of exceptions thrown");
        $this->reasons = $reasons;
    }
    /**
     * @return \Throwable[]
     */
    public function getReasons() : array
    {
        return $this->reasons;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Internal;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Loop;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
/**
 * Stores a set of functions to be invoked when a promise is resolved.
 *
 * @internal
 * @psalm-internal Amp\Internal
 */
class ResolutionQueue
{
    /** @var array<array-key, callable(\Throwable|null, mixed): (Promise|\React\Promise\PromiseInterface|\Generator<mixed,
     *     Promise|\React\Promise\PromiseInterface|array<array-key, Promise|\React\Promise\PromiseInterface>, mixed,
     *     mixed>|null) | callable(\Throwable|null, mixed): void> */
    private $queue = [];
    /**
     * @param callable|null $callback Initial callback to add to queue.
     *
     * @psalm-param null|callable(\Throwable|null, mixed): (Promise|\React\Promise\PromiseInterface|\Generator<mixed,
     *     Promise|\React\Promise\PromiseInterface|array<array-key, Promise|\React\Promise\PromiseInterface>, mixed,
     *     mixed>|null) | callable(\Throwable|null, mixed): void $callback
     */
    public function __construct(callable $callback = null)
    {
        if ($callback !== null) {
            $this->push($callback);
        }
    }
    /**
     * Unrolls instances of self to avoid blowing up the call stack on resolution.
     *
     * @param callable $callback
     *
     * @psalm-param callable(\Throwable|null, mixed): (Promise|\React\Promise\PromiseInterface|\Generator<mixed,
     *     Promise|\React\Promise\PromiseInterface|array<array-key, Promise|\React\Promise\PromiseInterface>, mixed,
     *     mixed>|null) | callable(\Throwable|null, mixed): void $callback
     *
     * @return void
     */
    public function push(callable $callback)
    {
        if ($callback instanceof self) {
            $this->queue = \array_merge($this->queue, $callback->queue);
            return;
        }
        $this->queue[] = $callback;
    }
    /**
     * Calls each callback in the queue, passing the provided values to the function.
     *
     * @param \Throwable|null $exception
     * @param mixed           $value
     *
     * @return void
     */
    public function __invoke($exception, $value)
    {
        foreach ($this->queue as $callback) {
            try {
                $result = $callback($exception, $value);
                if ($result === null) {
                    continue;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    Promise\rethrow($result);
                }
            } catch (\Throwable $exception) {
                Loop::defer(static function () use($exception) {
                    throw $exception;
                });
            }
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Internal;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
/**
 * Wraps a Promise instance that has public methods to resolve and fail the promise into an object that only allows
 * access to the public API methods.
 */
final class PrivatePromise implements Promise
{
    /** @var Promise */
    private $promise;
    public function __construct(Promise $promise)
    {
        $this->promise = $promise;
    }
    public function onResolve(callable $onResolved)
    {
        $this->promise->onResolve($onResolved);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Internal;

use _HumbugBox1cb33d1f20f1\Amp\Iterator;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
/**
 * Wraps an Iterator instance that has public methods to emit, complete, and fail into an object that only allows
 * access to the public API methods.
 *
 * @template-covariant TValue
 * @template-implements Iterator<TValue>
 */
final class PrivateIterator implements Iterator
{
    /** @var Iterator<TValue> */
    private $iterator;
    /**
     * @param Iterator $iterator
     *
     * @psalm-param Iterator<TValue> $iterator
     */
    public function __construct(Iterator $iterator)
    {
        $this->iterator = $iterator;
    }
    /**
     * @return Promise<bool>
     */
    public function advance() : Promise
    {
        return $this->iterator->advance();
    }
    /**
     * @psalm-return TValue
     */
    public function getCurrent()
    {
        return $this->iterator->getCurrent();
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Internal;

/**
 * Formats a stacktrace obtained via `debug_backtrace()`.
 *
 * @param array<array{file?: string, line: int, type?: string, class: string, function: string}> $trace Output of
 *     `debug_backtrace()`.
 *
 * @return string Formatted stacktrace.
 *
 * @codeCoverageIgnore
 * @internal
 */
function formatStacktrace(array $trace) : string
{
    return \implode("\n", \array_map(static function ($e, $i) {
        $line = "#{$i} ";
        if (isset($e["file"])) {
            $line .= "{$e['file']}:{$e['line']} ";
        }
        if (isset($e["type"])) {
            $line .= $e["class"] . $e["type"];
        }
        return $line . $e["function"] . "()";
    }, $trace, \array_keys($trace)));
}
/**
 * Creates a `TypeError` with a standardized error message.
 *
 * @param string[] $expected Expected types.
 * @param mixed    $given Given value.
 *
 * @return \TypeError
 *
 * @internal
 */
function createTypeError(array $expected, $given) : \TypeError
{
    $givenType = \is_object($given) ? \sprintf("instance of %s", \get_class($given)) : \gettype($given);
    if (\count($expected) === 1) {
        $expectedType = "Expected the following type: " . \array_pop($expected);
    } else {
        $expectedType = "Expected one of the following types: " . \implode(", ", $expected);
    }
    return new \TypeError("{$expectedType}; {$givenType} given");
}
/**
 * Returns the current time relative to an arbitrary point in time.
 *
 * @return int Time in milliseconds.
 */
function getCurrentTime() : int
{
    /** @var int|null $startTime */
    static $startTime;
    /** @var int|null $nextWarning */
    static $nextWarning;
    if (\PHP_INT_SIZE === 4) {
        // @codeCoverageIgnoreStart
        if ($startTime === null) {
            $startTime = \PHP_VERSION_ID >= 70300 ? \hrtime(\false)[0] : \time();
            $nextWarning = \PHP_INT_MAX - 86400 * 7;
        }
        if (\PHP_VERSION_ID >= 70300) {
            list($seconds, $nanoseconds) = \hrtime(\false);
            $seconds -= $startTime;
            if ($seconds >= $nextWarning) {
                $timeToOverflow = (\PHP_INT_MAX - $seconds * 1000) / 1000;
                \trigger_error("getCurrentTime() will overflow in {$timeToOverflow} seconds, please restart the process before that. " . "You're using a 32 bit version of PHP, so time will overflow about every 24 days. Regular restarts are required.", \E_USER_WARNING);
                /** @psalm-suppress PossiblyNullOperand */
                $nextWarning += 600;
                // every 10 minutes
            }
            return (int) ($seconds * 1000 + $nanoseconds / 1000000);
        }
        $seconds = \microtime(\true) - $startTime;
        if ($seconds >= $nextWarning) {
            $timeToOverflow = (\PHP_INT_MAX - $seconds * 1000) / 1000;
            \trigger_error("getCurrentTime() will overflow in {$timeToOverflow} seconds, please restart the process before that. " . "You're using a 32 bit version of PHP, so time will overflow about every 24 days. Regular restarts are required.", \E_USER_WARNING);
            /** @psalm-suppress PossiblyNullOperand */
            $nextWarning += 600;
            // every 10 minutes
        }
        return (int) ($seconds * 1000);
        // @codeCoverageIgnoreEnd
    }
    if (\PHP_VERSION_ID >= 70300) {
        list($seconds, $nanoseconds) = \hrtime(\false);
        return (int) ($seconds * 1000 + $nanoseconds / 1000000);
    }
    return (int) (\microtime(\true) * 1000);
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Internal;

use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Failure;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
/**
 * Trait used by Iterator implementations. Do not use this trait in your code, instead compose your class from one of
 * the available classes implementing \Amp\Iterator.
 * Note that it is the responsibility of the user of this trait to ensure that listeners have a chance to listen first
 * before emitting values.
 *
 * @internal
 * @template-covariant TValue
 */
trait Producer
{
    /** @var Promise|null */
    private $complete;
    /** @var mixed[] */
    private $values = [];
    /** @var Deferred[] */
    private $backPressure = [];
    /** @var int */
    private $consumePosition = -1;
    /** @var int */
    private $emitPosition = -1;
    /** @var Deferred|null */
    private $waiting;
    /** @var null|array */
    private $resolutionTrace;
    /**
     * {@inheritdoc}
     *
     * @return Promise<bool>
     */
    public function advance() : Promise
    {
        if ($this->waiting !== null) {
            throw new \Error("The prior promise returned must resolve before invoking this method again");
        }
        unset($this->values[$this->consumePosition]);
        $position = ++$this->consumePosition;
        if (\array_key_exists($position, $this->values)) {
            \assert(isset($this->backPressure[$position]));
            $deferred = $this->backPressure[$position];
            unset($this->backPressure[$position]);
            $deferred->resolve();
            return new Success(\true);
        }
        if ($this->complete) {
            return $this->complete;
        }
        $this->waiting = new Deferred();
        return $this->waiting->promise();
    }
    /**
     * {@inheritdoc}
     *
     * @return TValue
     */
    public function getCurrent()
    {
        if (empty($this->values) && $this->complete) {
            throw new \Error("The iterator has completed");
        }
        if (!\array_key_exists($this->consumePosition, $this->values)) {
            throw new \Error("Promise returned from advance() must resolve before calling this method");
        }
        return $this->values[$this->consumePosition];
    }
    /**
     * Emits a value from the iterator. The returned promise is resolved once the emitted value has been consumed.
     *
     * @param mixed $value
     *
     * @return Promise
     * @psalm-return Promise<null>
     *
     * @throws \Error If the iterator has completed.
     */
    private function emit($value) : Promise
    {
        if ($this->complete) {
            throw new \Error("Iterators cannot emit values after calling complete");
        }
        if ($value instanceof ReactPromise) {
            $value = Promise\adapt($value);
        }
        if ($value instanceof Promise) {
            $deferred = new Deferred();
            $value->onResolve(function ($e, $v) use($deferred) {
                if ($this->complete) {
                    $deferred->fail(new \Error("The iterator was completed before the promise result could be emitted"));
                    return;
                }
                if ($e) {
                    $this->fail($e);
                    $deferred->fail($e);
                    return;
                }
                $deferred->resolve($this->emit($v));
            });
            return $deferred->promise();
        }
        $position = ++$this->emitPosition;
        $this->values[$position] = $value;
        if ($this->waiting !== null) {
            $waiting = $this->waiting;
            $this->waiting = null;
            $waiting->resolve(\true);
            return new Success();
            // Consumer was already waiting for a new value, so back-pressure is unnecessary.
        }
        $this->backPressure[$position] = $pressure = new Deferred();
        return $pressure->promise();
    }
    /**
     * Completes the iterator.
     *
     * @return void
     *
     * @throws \Error If the iterator has already been completed.
     */
    private function complete()
    {
        if ($this->complete) {
            $message = "Iterator has already been completed";
            if (isset($this->resolutionTrace)) {
                $trace = formatStacktrace($this->resolutionTrace);
                $message .= ". Previous completion trace:\n\n{$trace}\n\n";
            } else {
                // @codeCoverageIgnoreStart
                $message .= ", define environment variable AMP_DEBUG or const AMP_DEBUG = true and enable assertions " . "for a stacktrace of the previous resolution.";
                // @codeCoverageIgnoreEnd
            }
            throw new \Error($message);
        }
        \assert((function () {
            $env = \getenv("AMP_DEBUG") ?: "0";
            if ($env !== "0" && $env !== "false" || \defined("_HumbugBox1cb33d1f20f1\\AMP_DEBUG") && \_HumbugBox1cb33d1f20f1\AMP_DEBUG) {
                $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
                \array_shift($trace);
                // remove current closure
                $this->resolutionTrace = $trace;
            }
            return \true;
        })());
        $this->complete = new Success(\false);
        if ($this->waiting !== null) {
            $waiting = $this->waiting;
            $this->waiting = null;
            $waiting->resolve($this->complete);
        }
    }
    /**
     * @param \Throwable $exception
     *
     * @return void
     */
    private function fail(\Throwable $exception)
    {
        $this->complete = new Failure($exception);
        if ($this->waiting !== null) {
            $waiting = $this->waiting;
            $this->waiting = null;
            $waiting->resolve($this->complete);
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Internal;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Failure;
use _HumbugBox1cb33d1f20f1\Amp\Loop;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
/**
 * Trait used by Promise implementations. Do not use this trait in your code, instead compose your class from one of
 * the available classes implementing \Amp\Promise.
 *
 * @internal
 */
trait Placeholder
{
    /** @var bool */
    private $resolved = \false;
    /** @var mixed */
    private $result;
    /** @var ResolutionQueue|null|callable(\Throwable|null, mixed): (Promise|\React\Promise\PromiseInterface|\Generator<mixed,
     *     Promise|\React\Promise\PromiseInterface|array<array-key, Promise|\React\Promise\PromiseInterface>, mixed,
     *     mixed>|null)|callable(\Throwable|null, mixed): void */
    private $onResolved;
    /** @var null|array */
    private $resolutionTrace;
    /**
     * @inheritdoc
     */
    public function onResolve(callable $onResolved)
    {
        if ($this->resolved) {
            if ($this->result instanceof Promise) {
                $this->result->onResolve($onResolved);
                return;
            }
            try {
                /** @var mixed $result */
                $result = $onResolved(null, $this->result);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    Promise\rethrow($result);
                }
            } catch (\Throwable $exception) {
                Loop::defer(static function () use($exception) {
                    throw $exception;
                });
            }
            return;
        }
        if (null === $this->onResolved) {
            $this->onResolved = $onResolved;
            return;
        }
        if (!$this->onResolved instanceof ResolutionQueue) {
            /** @psalm-suppress InternalClass */
            $this->onResolved = new ResolutionQueue($this->onResolved);
        }
        /** @psalm-suppress InternalMethod */
        $this->onResolved->push($onResolved);
    }
    public function __destruct()
    {
        try {
            $this->result = null;
        } catch (\Throwable $e) {
            Loop::defer(static function () use($e) {
                throw $e;
            });
        }
    }
    /**
     * @param mixed $value
     *
     * @return void
     *
     * @throws \Error Thrown if the promise has already been resolved.
     */
    private function resolve($value = null)
    {
        if ($this->resolved) {
            $message = "Promise has already been resolved";
            if (isset($this->resolutionTrace)) {
                $trace = formatStacktrace($this->resolutionTrace);
                $message .= ". Previous resolution trace:\n\n{$trace}\n\n";
            } else {
                // @codeCoverageIgnoreStart
                $message .= ", define environment variable AMP_DEBUG or const AMP_DEBUG = true and enable assertions " . "for a stacktrace of the previous resolution.";
                // @codeCoverageIgnoreEnd
            }
            throw new \Error($message);
        }
        \assert((function () {
            $env = \getenv("AMP_DEBUG") ?: "0";
            if ($env !== "0" && $env !== "false" || \defined("_HumbugBox1cb33d1f20f1\\AMP_DEBUG") && \_HumbugBox1cb33d1f20f1\AMP_DEBUG) {
                $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
                \array_shift($trace);
                // remove current closure
                $this->resolutionTrace = $trace;
            }
            return \true;
        })());
        if ($value instanceof ReactPromise) {
            $value = Promise\adapt($value);
        }
        $this->resolved = \true;
        $this->result = $value;
        if ($this->onResolved === null) {
            return;
        }
        $onResolved = $this->onResolved;
        $this->onResolved = null;
        if ($this->result instanceof Promise) {
            $this->result->onResolve($onResolved);
            return;
        }
        try {
            /** @var mixed $result */
            $result = $onResolved(null, $this->result);
            $onResolved = null;
            // allow garbage collection of $onResolved, to catch any exceptions from destructors
            if ($result === null) {
                return;
            }
            if ($result instanceof \Generator) {
                $result = new Coroutine($result);
            }
            if ($result instanceof Promise || $result instanceof ReactPromise) {
                Promise\rethrow($result);
            }
        } catch (\Throwable $exception) {
            Loop::defer(static function () use($exception) {
                throw $exception;
            });
        }
    }
    /**
     * @param \Throwable $reason Failure reason.
     *
     * @return void
     */
    private function fail(\Throwable $reason)
    {
        $this->resolve(new Failure($reason));
    }
    /**
     * @return bool True if the placeholder has been resolved.
     */
    private function isResolved() : bool
    {
        return $this->resolved;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

use function _HumbugBox1cb33d1f20f1\Amp\Internal\formatStacktrace;
/**
 * A TimeoutCancellationToken automatically requests cancellation after the timeout has elapsed.
 */
final class TimeoutCancellationToken implements CancellationToken
{
    /** @var string */
    private $watcher;
    /** @var CancellationToken */
    private $token;
    /**
     * @param int    $timeout Milliseconds until cancellation is requested.
     * @param string $message Message for TimeoutException. Default is "Operation timed out".
     */
    public function __construct(int $timeout, string $message = "Operation timed out")
    {
        $source = new CancellationTokenSource();
        $this->token = $source->getToken();
        $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
        $this->watcher = Loop::delay($timeout, static function () use($source, $message, $trace) {
            $trace = formatStacktrace($trace);
            $source->cancel(new TimeoutException("{$message}\r\nTimeoutCancellationToken was created here:\r\n{$trace}"));
        });
        Loop::unreference($this->watcher);
    }
    /**
     * Cancels the delay watcher.
     */
    public function __destruct()
    {
        Loop::cancel($this->watcher);
    }
    /**
     * {@inheritdoc}
     */
    public function subscribe(callable $callback) : string
    {
        return $this->token->subscribe($callback);
    }
    /**
     * {@inheritdoc}
     */
    public function unsubscribe(string $id)
    {
        $this->token->unsubscribe($id);
    }
    /**
     * {@inheritdoc}
     */
    public function isRequested() : bool
    {
        return $this->token->isRequested();
    }
    /**
     * {@inheritdoc}
     */
    public function throwIfRequested()
    {
        $this->token->throwIfRequested();
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Creates a promise that calls $promisor only when the result of the promise is requested (i.e. onResolve() is called
 * on the promise). $promisor can return a promise or any value. If $promisor throws an exception, the promise fails
 * with that exception. If $promisor returns a Generator, it will be run as a coroutine.
 */
final class LazyPromise implements Promise
{
    /** @var callable|null */
    private $promisor;
    /** @var Promise|null */
    private $promise;
    /**
     * @param callable $promisor Function which starts an async operation, returning a Promise (or any value).
     *     Generators will be run as a coroutine.
     */
    public function __construct(callable $promisor)
    {
        $this->promisor = $promisor;
    }
    /**
     * {@inheritdoc}
     */
    public function onResolve(callable $onResolved)
    {
        if ($this->promise === null) {
            \assert($this->promisor !== null);
            $provider = $this->promisor;
            $this->promisor = null;
            $this->promise = call($provider);
        }
        \assert($this->promise !== null);
        $this->promise->onResolve($onResolved);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Emitter is a container for an iterator that can emit values using the emit() method and completed using the
 * complete() and fail() methods of this object. The contained iterator may be accessed using the iterate()
 * method. This object should not be part of a public API, but used internally to create and emit values to an
 * iterator.
 *
 * @template TValue
 */
final class Emitter
{
    /** @var Iterator<TValue> Has public emit, complete, and fail methods. */
    private $emitter;
    /** @var Iterator<TValue> Hides producer methods. */
    private $iterator;
    public function __construct()
    {
        $this->emitter = new class implements Iterator
        {
            use Internal\Producer {
                emit as public;
                complete as public;
                fail as public;
            }
        };
        $this->iterator = new Internal\PrivateIterator($this->emitter);
    }
    /**
     * @return Iterator
     * @psalm-return Iterator<TValue>
     */
    public function iterate() : Iterator
    {
        return $this->iterator;
    }
    /**
     * Emits a value to the iterator.
     *
     * @param mixed $value
     *
     * @psalm-param TValue $value
     *
     * @return Promise
     * @psalm-return Promise<null>
     * @psalm-suppress MixedInferredReturnType
     * @psalm-suppress MixedReturnStatement
     */
    public function emit($value) : Promise
    {
        /** @psalm-suppress UndefinedInterfaceMethod */
        return $this->emitter->emit($value);
    }
    /**
     * Completes the iterator.
     *
     * @return void
     */
    public function complete()
    {
        /** @psalm-suppress UndefinedInterfaceMethod */
        $this->emitter->complete();
    }
    /**
     * Fails the iterator with the given reason.
     *
     * @param \Throwable $reason
     *
     * @return void
     */
    public function fail(\Throwable $reason)
    {
        /** @psalm-suppress UndefinedInterfaceMethod */
        $this->emitter->fail($reason);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Defines an asynchronous iterator over a set of values that is designed to be used within a coroutine.
 *
 * @template-covariant TValue
 */
interface Iterator
{
    /**
     * Succeeds with true if an emitted value is available by calling getCurrent() or false if the iterator has
     * resolved. If the iterator fails, the returned promise will fail with the same exception.
     *
     * @return Promise
     * @psalm-return Promise<bool>
     *
     * @throws \Error If the prior promise returned from this method has not resolved.
     * @throws \Throwable The exception used to fail the iterator.
     */
    public function advance() : Promise;
    /**
     * Gets the last emitted value or throws an exception if the iterator has completed.
     *
     * @return mixed  Value emitted from the iterator.
     * @psalm-return TValue
     *
     * @throws \Error If the iterator has resolved or advance() was not called before calling this method.
     * @throws \Throwable The exception used to fail the iterator.
     */
    public function getCurrent();
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

use _HumbugBox1cb33d1f20f1\Amp\Loop\Driver;
use _HumbugBox1cb33d1f20f1\Amp\Loop\DriverFactory;
use _HumbugBox1cb33d1f20f1\Amp\Loop\InvalidWatcherError;
use _HumbugBox1cb33d1f20f1\Amp\Loop\UnsupportedFeatureException;
use _HumbugBox1cb33d1f20f1\Amp\Loop\Watcher;
/**
 * Accessor to allow global access to the event loop.
 *
 * @see \Amp\Loop\Driver
 */
final class Loop
{
    /**
     * @var Driver
     */
    private static $driver;
    /**
     * Disable construction as this is a static class.
     */
    private function __construct()
    {
        // intentionally left blank
    }
    /**
     * Sets the driver to be used for `Loop::run()`.
     *
     * @param Driver $driver
     *
     * @return void
     */
    public static function set(Driver $driver)
    {
        try {
            self::$driver = new class extends Driver
            {
                /**
                 * @return void
                 */
                protected function activate(array $watchers)
                {
                    throw new \Error("Can't activate watcher during garbage collection.");
                }
                /**
                 * @return void
                 */
                protected function dispatch(bool $blocking)
                {
                    throw new \Error("Can't dispatch during garbage collection.");
                }
                /**
                 * @return void
                 */
                protected function deactivate(Watcher $watcher)
                {
                    // do nothing
                }
                public function getHandle()
                {
                    return null;
                }
            };
            \gc_collect_cycles();
        } finally {
            self::$driver = $driver;
        }
    }
    /**
     * Run the event loop and optionally execute a callback within the scope of it.
     *
     * The loop MUST continue to run until it is either stopped explicitly, no referenced watchers exist anymore, or an
     * exception is thrown that cannot be handled. Exceptions that cannot be handled are exceptions thrown from an
     * error handler or exceptions that would be passed to an error handler but none exists to handle them.
     *
     * @param callable|null $callback The callback to execute.
     *
     * @return void
     */
    public static function run(callable $callback = null)
    {
        if ($callback) {
            self::$driver->defer($callback);
        }
        self::$driver->run();
    }
    /**
     * Stop the event loop.
     *
     * When an event loop is stopped, it continues with its current tick and exits the loop afterwards. Multiple calls
     * to stop MUST be ignored and MUST NOT raise an exception.
     *
     * @return void
     */
    public static function stop()
    {
        self::$driver->stop();
    }
    /**
     * Defer the execution of a callback.
     *
     * The deferred callable MUST be executed before any other type of watcher in a tick. Order of enabling MUST be
     * preserved when executing the callbacks.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param callable(string $watcherId, mixed $data) $callback The callback to defer. The `$watcherId` will be
     *     invalidated before the callback call.
     * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public static function defer(callable $callback, $data = null) : string
    {
        return self::$driver->defer($callback, $data);
    }
    /**
     * Delay the execution of a callback.
     *
     * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which
     * timers expire first, but timers with the same expiration time MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param int   $delay The amount of time, in milliseconds, to delay the execution for.
     * @param callable(string $watcherId, mixed $data) $callback The callback to delay. The `$watcherId` will be
     *     invalidated before the callback call.
     * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public static function delay(int $delay, callable $callback, $data = null) : string
    {
        return self::$driver->delay($delay, $callback, $data);
    }
    /**
     * Repeatedly execute a callback.
     *
     * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be
     * determined by which timers expire first, but timers with the same expiration time MAY be executed in any order.
     * The first execution is scheduled after the first interval period.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param int   $interval The time interval, in milliseconds, to wait between executions.
     * @param callable(string $watcherId, mixed $data) $callback The callback to repeat.
     * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public static function repeat(int $interval, callable $callback, $data = null) : string
    {
        return self::$driver->repeat($interval, $callback, $data);
    }
    /**
     * Execute a callback when a stream resource becomes readable or is closed for reading.
     *
     * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the
     * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid
     * resources, but are not required to, due to the high performance impact. Watchers on closed resources are
     * therefore undefined behavior.
     *
     * Multiple watchers on the same stream MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param resource $stream The stream to monitor.
     * @param callable(string $watcherId, resource $stream, mixed $data) $callback The callback to execute.
     * @param mixed    $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public static function onReadable($stream, callable $callback, $data = null) : string
    {
        return self::$driver->onReadable($stream, $callback, $data);
    }
    /**
     * Execute a callback when a stream resource becomes writable or is closed for writing.
     *
     * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the
     * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid
     * resources, but are not required to, due to the high performance impact. Watchers on closed resources are
     * therefore undefined behavior.
     *
     * Multiple watchers on the same stream MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param resource $stream The stream to monitor.
     * @param callable(string $watcherId, resource $stream, mixed $data) $callback The callback to execute.
     * @param mixed    $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public static function onWritable($stream, callable $callback, $data = null) : string
    {
        return self::$driver->onWritable($stream, $callback, $data);
    }
    /**
     * Execute a callback when a signal is received.
     *
     * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior.
     * Implementations MAY try to detect this, if possible, but are not required to. This is due to technical
     * limitations of the signals being registered globally per process.
     *
     * Multiple watchers on the same signal MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param int   $signo The signal number to monitor.
     * @param callable(string $watcherId, int $signo, mixed $data) $callback The callback to execute.
     * @param mixed $data Arbitrary data given to the callback function as the $data parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     *
     * @throws UnsupportedFeatureException If signal handling is not supported.
     */
    public static function onSignal(int $signo, callable $callback, $data = null) : string
    {
        return self::$driver->onSignal($signo, $callback, $data);
    }
    /**
     * Enable a watcher to be active starting in the next tick.
     *
     * Watchers MUST immediately be marked as enabled, but only be activated (i.e. callbacks can be called) right before
     * the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     *
     * @throws InvalidWatcherError If the watcher identifier is invalid.
     */
    public static function enable(string $watcherId)
    {
        self::$driver->enable($watcherId);
    }
    /**
     * Disable a watcher immediately.
     *
     * A watcher MUST be disabled immediately, e.g. if a defer watcher disables a later defer watcher, the second defer
     * watcher isn't executed in this tick.
     *
     * Disabling a watcher MUST NOT invalidate the watcher. Calling this function MUST NOT fail, even if passed an
     * invalid watcher.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     */
    public static function disable(string $watcherId)
    {
        if (\PHP_VERSION_ID < 70200 && !isset(self::$driver)) {
            // Prior to PHP 7.2, self::$driver may be unset during destruct.
            // See https://github.com/amphp/amp/issues/212.
            return;
        }
        self::$driver->disable($watcherId);
    }
    /**
     * Cancel a watcher.
     *
     * This will detatch the event loop from all resources that are associated to the watcher. After this operation the
     * watcher is permanently invalid. Calling this function MUST NOT fail, even if passed an invalid watcher.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     */
    public static function cancel(string $watcherId)
    {
        if (\PHP_VERSION_ID < 70200 && !isset(self::$driver)) {
            // Prior to PHP 7.2, self::$driver may be unset during destruct.
            // See https://github.com/amphp/amp/issues/212.
            return;
        }
        self::$driver->cancel($watcherId);
    }
    /**
     * Reference a watcher.
     *
     * This will keep the event loop alive whilst the watcher is still being monitored. Watchers have this state by
     * default.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     *
     * @throws InvalidWatcherError If the watcher identifier is invalid.
     */
    public static function reference(string $watcherId)
    {
        self::$driver->reference($watcherId);
    }
    /**
     * Unreference a watcher.
     *
     * The event loop should exit the run method when only unreferenced watchers are still being monitored. Watchers
     * are all referenced by default.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     */
    public static function unreference(string $watcherId)
    {
        if (\PHP_VERSION_ID < 70200 && !isset(self::$driver)) {
            // Prior to PHP 7.2, self::$driver may be unset during destruct.
            // See https://github.com/amphp/amp/issues/212.
            return;
        }
        self::$driver->unreference($watcherId);
    }
    /**
     * Returns the current loop time in millisecond increments. Note this value does not necessarily correlate to
     * wall-clock time, rather the value returned is meant to be used in relative comparisons to prior values returned
     * by this method (intervals, expiration calculations, etc.) and is only updated once per loop tick.
     *
     * @return int
     */
    public static function now() : int
    {
        return self::$driver->now();
    }
    /**
     * Stores information in the loop bound registry.
     *
     * Stored information is package private. Packages MUST NOT retrieve the stored state of other packages. Packages
     * MUST use their namespace as prefix for keys. They may do so by using `SomeClass::class` as key.
     *
     * If packages want to expose loop bound state to consumers other than the package, they SHOULD provide a dedicated
     * interface for that purpose instead of sharing the storage key.
     *
     * @param string $key The namespaced storage key.
     * @param mixed  $value The value to be stored.
     *
     * @return void
     */
    public static function setState(string $key, $value)
    {
        self::$driver->setState($key, $value);
    }
    /**
     * Gets information stored bound to the loop.
     *
     * Stored information is package private. Packages MUST NOT retrieve the stored state of other packages. Packages
     * MUST use their namespace as prefix for keys. They may do so by using `SomeClass::class` as key.
     *
     * If packages want to expose loop bound state to consumers other than the package, they SHOULD provide a dedicated
     * interface for that purpose instead of sharing the storage key.
     *
     * @param string $key The namespaced storage key.
     *
     * @return mixed The previously stored value or `null` if it doesn't exist.
     */
    public static function getState(string $key)
    {
        return self::$driver->getState($key);
    }
    /**
     * Set a callback to be executed when an error occurs.
     *
     * The callback receives the error as the first and only parameter. The return value of the callback gets ignored.
     * If it can't handle the error, it MUST throw the error. Errors thrown by the callback or during its invocation
     * MUST be thrown into the `run` loop and stop the driver.
     *
     * Subsequent calls to this method will overwrite the previous handler.
     *
     * @param callable(\Throwable $error)|null $callback The callback to execute. `null` will clear the
     *     current handler.
     *
     * @return callable(\Throwable $error)|null The previous handler, `null` if there was none.
     */
    public static function setErrorHandler(callable $callback = null)
    {
        return self::$driver->setErrorHandler($callback);
    }
    /**
     * Retrieve an associative array of information about the event loop driver.
     *
     * The returned array MUST contain the following data describing the driver's currently registered watchers:
     *
     *     [
     *         "defer"            => ["enabled" => int, "disabled" => int],
     *         "delay"            => ["enabled" => int, "disabled" => int],
     *         "repeat"           => ["enabled" => int, "disabled" => int],
     *         "on_readable"      => ["enabled" => int, "disabled" => int],
     *         "on_writable"      => ["enabled" => int, "disabled" => int],
     *         "on_signal"        => ["enabled" => int, "disabled" => int],
     *         "enabled_watchers" => ["referenced" => int, "unreferenced" => int],
     *         "running"          => bool
     *     ];
     *
     * Implementations MAY optionally add more information in the array but at minimum the above `key => value` format
     * MUST always be provided.
     *
     * @return array Statistics about the loop in the described format.
     */
    public static function getInfo() : array
    {
        return self::$driver->getInfo();
    }
    /**
     * Retrieve the event loop driver that is in scope.
     *
     * @return Driver
     */
    public static function get() : Driver
    {
        return self::$driver;
    }
}
// Default factory, don't move this to a file loaded by the composer "files" autoload mechanism, otherwise custom
// implementations might have issues setting a default loop, because it's overridden by us then.
// @codeCoverageIgnoreStart
Loop::set((new DriverFactory())->create());
// @codeCoverageIgnoreEnd
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * A NullCancellationToken can be used to avoid conditionals to check whether a token has been provided.
 *
 * Instead of writing
 *
 * ```php
 * if ($token) {
 *     $token->throwIfRequested();
 * }
 * ```
 *
 * potentially multiple times, it allows writing
 *
 * ```php
 * $token = $token ?? new NullCancellationToken;
 *
 * // ...
 *
 * $token->throwIfRequested();
 * ```
 *
 * instead.
 */
final class NullCancellationToken implements CancellationToken
{
    /** @inheritdoc */
    public function subscribe(callable $callback) : string
    {
        return "null-token";
    }
    /** @inheritdoc */
    public function unsubscribe(string $id)
    {
        // nothing to do
    }
    /** @inheritdoc */
    public function isRequested() : bool
    {
        return \false;
    }
    /** @inheritdoc */
    public function throwIfRequested()
    {
        // nothing to do
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * A "safe" struct trait for public property aggregators.
 *
 * This trait is intended to make using public properties a little safer by throwing when
 * nonexistent property names are read or written.
 */
trait Struct
{
    /**
     * The minimum percentage [0-100] at which to recommend a similar property
     * name when generating error messages.
     */
    private $__propertySuggestThreshold = 70;
    /**
     * @param string $property
     *
     * @psalm-return no-return
     */
    public function __get(string $property)
    {
        throw new \Error($this->generateStructPropertyError($property));
    }
    /**
     * @param string $property
     * @param mixed  $value
     *
     * @psalm-return no-return
     */
    public function __set(string $property, $value)
    {
        throw new \Error($this->generateStructPropertyError($property));
    }
    private function generateStructPropertyError(string $property) : string
    {
        $suggestion = $this->suggestPropertyName($property);
        $suggestStr = $suggestion == "" ? "" : " ... did you mean \"{$suggestion}?\"";
        return \sprintf(
            "%s property \"%s\" does not exist%s",
            \str_replace("\x00", "@", \get_class($this)),
            // Handle anonymous class names.
            $property,
            $suggestStr
        );
    }
    private function suggestPropertyName(string $badProperty) : string
    {
        $badProperty = \strtolower($badProperty);
        $bestMatch = "";
        $bestMatchPercentage = 0;
        /** @psalm-suppress RawObjectIteration */
        foreach ($this as $property => $value) {
            // Never suggest properties that begin with an underscore
            if ($property[0] === "_") {
                continue;
            }
            \similar_text($badProperty, \strtolower($property), $byRefPercentage);
            if ($byRefPercentage > $bestMatchPercentage) {
                $bestMatchPercentage = $byRefPercentage;
                $bestMatch = $property;
            }
        }
        return $bestMatchPercentage >= $this->__propertySuggestThreshold ? $bestMatch : "";
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Will be thrown in case an operation is cancelled.
 *
 * @see CancellationToken
 * @see CancellationTokenSource
 */
class CancelledException extends \Exception
{
    public function __construct(\Throwable $previous = null)
    {
        parent::__construct("The operation was cancelled", 0, $previous);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
/**
 * Returns a new function that wraps $callback in a promise/coroutine-aware function that automatically runs
 * Generators as coroutines. The returned function always returns a promise when invoked. Errors have to be handled
 * by the callback caller or they will go unnoticed.
 *
 * Use this function to create a coroutine-aware callable for a promise-aware callback caller.
 *
 * @template TReturn
 * @template TPromise
 * @template TGeneratorReturn
 * @template TGeneratorPromise
 *
 * @template TGenerator as TGeneratorReturn|Promise<TGeneratorPromise>
 * @template T as TReturn|Promise<TPromise>|\Generator<mixed, mixed, mixed, TGenerator>
 *
 * @formatter:off
 *
 * @param callable(...mixed): T $callback
 *
 * @return callable
 * @psalm-return (T is Promise ? (callable(mixed...): Promise<TPromise>) : (T is \Generator ? (TGenerator is Promise ? (callable(mixed...): Promise<TGeneratorPromise>) : (callable(mixed...): Promise<TGeneratorReturn>)) : (callable(mixed...): Promise<TReturn>)))
 *
 * @formatter:on
 *
 * @see asyncCoroutine()
 *
 * @psalm-suppress InvalidReturnType
 */
function coroutine(callable $callback) : callable
{
    /** @psalm-suppress InvalidReturnStatement */
    return static function (...$args) use($callback) : Promise {
        return call($callback, ...$args);
    };
}
/**
 * Returns a new function that wraps $callback in a promise/coroutine-aware function that automatically runs
 * Generators as coroutines. The returned function always returns void when invoked. Errors are forwarded to the
 * loop's error handler using `Amp\Promise\rethrow()`.
 *
 * Use this function to create a coroutine-aware callable for a non-promise-aware callback caller.
 *
 * @param callable(...mixed): mixed $callback
 *
 * @return callable
 * @psalm-return callable(mixed...): void
 *
 * @see coroutine()
 */
function asyncCoroutine(callable $callback) : callable
{
    return static function (...$args) use($callback) {
        Promise\rethrow(call($callback, ...$args));
    };
}
/**
 * Calls the given function, always returning a promise. If the function returns a Generator, it will be run as a
 * coroutine. If the function throws, a failed promise will be returned.
 *
 * @template TReturn
 * @template TPromise
 * @template TGeneratorReturn
 * @template TGeneratorPromise
 *
 * @template TGenerator as TGeneratorReturn|Promise<TGeneratorPromise>
 * @template T as TReturn|Promise<TPromise>|\Generator<mixed, mixed, mixed, TGenerator>
 *
 * @formatter:off
 *
 * @param callable(...mixed): T $callback
 * @param mixed ...$args Arguments to pass to the function.
 *
 * @return Promise
 * @psalm-return (T is Promise ? Promise<TPromise> : (T is \Generator ? (TGenerator is Promise ? Promise<TGeneratorPromise> : Promise<TGeneratorReturn>) : Promise<TReturn>))
 *
 * @formatter:on
 */
function call(callable $callback, ...$args) : Promise
{
    try {
        $result = $callback(...$args);
    } catch (\Throwable $exception) {
        return new Failure($exception);
    }
    if ($result instanceof \Generator) {
        return new Coroutine($result);
    }
    if ($result instanceof Promise) {
        return $result;
    }
    if ($result instanceof ReactPromise) {
        return Promise\adapt($result);
    }
    return new Success($result);
}
/**
 * Calls the given function. If the function returns a Generator, it will be run as a coroutine. If the function
 * throws or returns a failing promise, the failure is forwarded to the loop error handler.
 *
 * @param callable(...mixed): mixed $callback
 * @param mixed ...$args Arguments to pass to the function.
 *
 * @return void
 */
function asyncCall(callable $callback, ...$args)
{
    Promise\rethrow(call($callback, ...$args));
}
/**
 * Sleeps for the specified number of milliseconds.
 *
 * @param int $milliseconds
 *
 * @return Delayed
 */
function delay(int $milliseconds) : Delayed
{
    return new Delayed($milliseconds);
}
/**
 * Returns the current time relative to an arbitrary point in time.
 *
 * @return int Time in milliseconds.
 */
function getCurrentTime() : int
{
    return Internal\getCurrentTime();
}
namespace _HumbugBox1cb33d1f20f1\Amp\Promise;

use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Loop;
use _HumbugBox1cb33d1f20f1\Amp\MultiReasonException;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
use _HumbugBox1cb33d1f20f1\Amp\TimeoutException;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
use function _HumbugBox1cb33d1f20f1\Amp\Internal\createTypeError;
/**
 * Registers a callback that will forward the failure reason to the event loop's error handler if the promise fails.
 *
 * Use this function if you neither return the promise nor handle a possible error yourself to prevent errors from
 * going entirely unnoticed.
 *
 * @param Promise|ReactPromise $promise Promise to register the handler on.
 *
 * @return void
 * @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface.
 *
 */
function rethrow($promise)
{
    if (!$promise instanceof Promise) {
        if ($promise instanceof ReactPromise) {
            $promise = adapt($promise);
        } else {
            throw createTypeError([Promise::class, ReactPromise::class], $promise);
        }
    }
    $promise->onResolve(static function ($exception) {
        if ($exception) {
            throw $exception;
        }
    });
}
/**
 * Runs the event loop until the promise is resolved. Should not be called within a running event loop.
 *
 * Use this function only in synchronous contexts to wait for an asynchronous operation. Use coroutines and yield to
 * await promise resolution in a fully asynchronous application instead.
 *
 * @template TPromise
 * @template T as Promise<TPromise>|ReactPromise
 *
 * @param Promise|ReactPromise $promise Promise to wait for.
 *
 * @return mixed Promise success value.
 *
 * @psalm-param T              $promise
 * @psalm-return (T is Promise ? TPromise : mixed)
 *
 * @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface.
 * @throws \Error If the event loop stopped without the $promise being resolved.
 * @throws \Throwable Promise failure reason.
 */
function wait($promise)
{
    if (!$promise instanceof Promise) {
        if ($promise instanceof ReactPromise) {
            $promise = adapt($promise);
        } else {
            throw createTypeError([Promise::class, ReactPromise::class], $promise);
        }
    }
    $resolved = \false;
    try {
        Loop::run(function () use(&$resolved, &$value, &$exception, $promise) {
            $promise->onResolve(function ($e, $v) use(&$resolved, &$value, &$exception) {
                Loop::stop();
                $resolved = \true;
                $exception = $e;
                $value = $v;
            });
        });
    } catch (\Throwable $throwable) {
        throw new \Error("Loop exceptionally stopped without resolving the promise", 0, $throwable);
    }
    if (!$resolved) {
        throw new \Error("Loop stopped without resolving the promise");
    }
    if ($exception) {
        throw $exception;
    }
    return $value;
}
/**
 * Creates an artificial timeout for any `Promise`.
 *
 * If the timeout expires before the promise is resolved, the returned promise fails with an instance of
 * `Amp\TimeoutException`.
 *
 * @template TReturn
 *
 * @param Promise<TReturn>|ReactPromise $promise Promise to which the timeout is applied.
 * @param int                           $timeout Timeout in milliseconds.
 *
 * @return Promise<TReturn>
 *
 * @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface.
 */
function timeout($promise, int $timeout) : Promise
{
    if (!$promise instanceof Promise) {
        if ($promise instanceof ReactPromise) {
            $promise = adapt($promise);
        } else {
            throw createTypeError([Promise::class, ReactPromise::class], $promise);
        }
    }
    $deferred = new Deferred();
    $watcher = Loop::delay($timeout, static function () use(&$deferred) {
        $temp = $deferred;
        // prevent double resolve
        $deferred = null;
        $temp->fail(new TimeoutException());
    });
    Loop::unreference($watcher);
    $promise->onResolve(function () use(&$deferred, $promise, $watcher) {
        if ($deferred !== null) {
            Loop::cancel($watcher);
            $deferred->resolve($promise);
        }
    });
    return $deferred->promise();
}
/**
 * Creates an artificial timeout for any `Promise`.
 *
 * If the promise is resolved before the timeout expires, the result is returned
 *
 * If the timeout expires before the promise is resolved, a default value is returned
 *
 * @template TReturn
 *
 * @param Promise<TReturn>|ReactPromise $promise Promise to which the timeout is applied.
 * @param int                           $timeout Timeout in milliseconds.
 * @param TReturn                       $default
 *
 * @return Promise<TReturn>
 *
 * @throws \TypeError If $promise is not an instance of \Amp\Promise or \React\Promise\PromiseInterface.
 */
function timeoutWithDefault($promise, int $timeout, $default = null) : Promise
{
    $promise = timeout($promise, $timeout);
    return call(static function () use($promise, $default) {
        try {
            return (yield $promise);
        } catch (TimeoutException $exception) {
            return $default;
        }
    });
}
/**
 * Adapts any object with a done(callable $onFulfilled, callable $onRejected) or then(callable $onFulfilled,
 * callable $onRejected) method to a promise usable by components depending on placeholders implementing
 * \AsyncInterop\Promise.
 *
 * @param object $promise Object with a done() or then() method.
 *
 * @return Promise Promise resolved by the $thenable object.
 *
 * @throws \Error If the provided object does not have a then() method.
 */
function adapt($promise) : Promise
{
    if (!\is_object($promise)) {
        throw new \Error("Object must be provided");
    }
    $deferred = new Deferred();
    if (\method_exists($promise, 'done')) {
        $promise->done([$deferred, 'resolve'], [$deferred, 'fail']);
    } elseif (\method_exists($promise, 'then')) {
        $promise->then([$deferred, 'resolve'], [$deferred, 'fail']);
    } else {
        throw new \Error("Object must have a 'then' or 'done' method");
    }
    return $deferred->promise();
}
/**
 * Returns a promise that is resolved when all promises are resolved. The returned promise will not fail.
 * Returned promise succeeds with a two-item array delineating successful and failed promise results,
 * with keys identical and corresponding to the original given array.
 *
 * This function is the same as some() with the notable exception that it will never fail even
 * if all promises in the array resolve unsuccessfully.
 *
 * @template TValue
 *
 * @param Promise<TValue>[]|ReactPromise[] $promises
 *
 * @return Promise<array{0: \Throwable[], 1: TValue[]}>
 *
 * @throws \Error If a non-Promise is in the array.
 */
function any(array $promises) : Promise
{
    return some($promises, 0);
}
/**
 * Returns a promise that succeeds when all promises succeed, and fails if any promise fails. Returned
 * promise succeeds with an array of values used to succeed each contained promise, with keys corresponding to
 * the array of promises.
 *
 * @param Promise[]|ReactPromise[]                             $promises Array of only promises.
 *
 * @return Promise
 *
 * @throws \Error If a non-Promise is in the array.
 *
 * @template TValue
 *
 * @psalm-param array<array-key, Promise<TValue>|ReactPromise> $promises
 * @psalm-assert array<array-key, Promise<TValue>|ReactPromise> $promises $promises
 * @psalm-return Promise<array<array-key, TValue>>
 */
function all(array $promises) : Promise
{
    if (empty($promises)) {
        return new Success([]);
    }
    $deferred = new Deferred();
    $result = $deferred->promise();
    $pending = \count($promises);
    $values = [];
    foreach ($promises as $key => $promise) {
        if ($promise instanceof ReactPromise) {
            $promise = adapt($promise);
        } elseif (!$promise instanceof Promise) {
            throw createTypeError([Promise::class, ReactPromise::class], $promise);
        }
        $values[$key] = null;
        // add entry to array to preserve order
        $promise->onResolve(function ($exception, $value) use(&$deferred, &$values, &$pending, $key) {
            if ($pending === 0) {
                return;
            }
            if ($exception) {
                $pending = 0;
                $deferred->fail($exception);
                $deferred = null;
                return;
            }
            $values[$key] = $value;
            if (0 === --$pending) {
                $deferred->resolve($values);
            }
        });
    }
    return $result;
}
/**
 * Returns a promise that succeeds when the first promise succeeds, and fails only if all promises fail.
 *
 * @template TValue
 *
 * @param Promise<TValue>[]|ReactPromise[] $promises Array of only promises.
 *
 * @return Promise<TValue>
 *
 * @throws \Error If the array is empty or a non-Promise is in the array.
 */
function first(array $promises) : Promise
{
    if (empty($promises)) {
        throw new \Error("No promises provided");
    }
    $deferred = new Deferred();
    $result = $deferred->promise();
    $pending = \count($promises);
    $exceptions = [];
    foreach ($promises as $key => $promise) {
        if ($promise instanceof ReactPromise) {
            $promise = adapt($promise);
        } elseif (!$promise instanceof Promise) {
            throw createTypeError([Promise::class, ReactPromise::class], $promise);
        }
        $exceptions[$key] = null;
        // add entry to array to preserve order
        $promise->onResolve(function ($error, $value) use(&$deferred, &$exceptions, &$pending, $key) {
            if ($pending === 0) {
                return;
            }
            if (!$error) {
                $pending = 0;
                $deferred->resolve($value);
                $deferred = null;
                return;
            }
            $exceptions[$key] = $error;
            if (0 === --$pending) {
                $deferred->fail(new MultiReasonException($exceptions));
            }
        });
    }
    return $result;
}
/**
 * Resolves with a two-item array delineating successful and failed Promise results.
 *
 * The returned promise will only fail if the given number of required promises fail.
 *
 * @template TValue
 *
 * @param Promise<TValue>[]|ReactPromise[] $promises Array of only promises.
 * @param int                              $required Number of promises that must succeed for the
 *     returned promise to succeed.
 *
 * @return Promise<array{0: \Throwable[], 1: TValue[]}>
 *
 * @throws \Error If a non-Promise is in the array.
 */
function some(array $promises, int $required = 1) : Promise
{
    if ($required < 0) {
        throw new \Error("Number of promises required must be non-negative");
    }
    $pending = \count($promises);
    if ($required > $pending) {
        throw new \Error("Too few promises provided");
    }
    if (empty($promises)) {
        return new Success([[], []]);
    }
    $deferred = new Deferred();
    $result = $deferred->promise();
    $values = [];
    $exceptions = [];
    foreach ($promises as $key => $promise) {
        if ($promise instanceof ReactPromise) {
            $promise = adapt($promise);
        } elseif (!$promise instanceof Promise) {
            throw createTypeError([Promise::class, ReactPromise::class], $promise);
        }
        $values[$key] = $exceptions[$key] = null;
        // add entry to arrays to preserve order
        $promise->onResolve(static function ($exception, $value) use(&$values, &$exceptions, &$pending, $key, $required, $deferred) {
            if ($exception) {
                $exceptions[$key] = $exception;
                unset($values[$key]);
            } else {
                $values[$key] = $value;
                unset($exceptions[$key]);
            }
            if (0 === --$pending) {
                if (\count($values) < $required) {
                    $deferred->fail(new MultiReasonException($exceptions));
                } else {
                    $deferred->resolve([$exceptions, $values]);
                }
            }
        });
    }
    return $result;
}
/**
 * Wraps a promise into another promise, altering the exception or result.
 *
 * @param Promise|ReactPromise $promise
 * @param callable             $callback
 *
 * @return Promise
 */
function wrap($promise, callable $callback) : Promise
{
    if ($promise instanceof ReactPromise) {
        $promise = adapt($promise);
    } elseif (!$promise instanceof Promise) {
        throw createTypeError([Promise::class, ReactPromise::class], $promise);
    }
    $deferred = new Deferred();
    $promise->onResolve(static function (\Throwable $exception = null, $result) use($deferred, $callback) {
        try {
            $result = $callback($exception, $result);
        } catch (\Throwable $exception) {
            $deferred->fail($exception);
            return;
        }
        $deferred->resolve($result);
    });
    return $deferred->promise();
}
namespace _HumbugBox1cb33d1f20f1\Amp\Iterator;

use _HumbugBox1cb33d1f20f1\Amp\Delayed;
use _HumbugBox1cb33d1f20f1\Amp\Emitter;
use _HumbugBox1cb33d1f20f1\Amp\Iterator;
use _HumbugBox1cb33d1f20f1\Amp\Producer;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
use function _HumbugBox1cb33d1f20f1\Amp\coroutine;
use function _HumbugBox1cb33d1f20f1\Amp\Internal\createTypeError;
/**
 * Creates an iterator from the given iterable, emitting the each value. The iterable may contain promises. If any
 * promise fails, the iterator will fail with the same reason.
 *
 * @param array|\Traversable $iterable Elements to emit.
 * @param int                $delay Delay between element emissions in milliseconds.
 *
 * @return Iterator
 *
 * @throws \TypeError If the argument is not an array or instance of \Traversable.
 */
function fromIterable($iterable, int $delay = 0) : Iterator
{
    if (!$iterable instanceof \Traversable && !\is_array($iterable)) {
        throw createTypeError(["array", "Traversable"], $iterable);
    }
    if ($delay) {
        return new Producer(static function (callable $emit) use($iterable, $delay) {
            foreach ($iterable as $value) {
                (yield new Delayed($delay));
                (yield $emit($value));
            }
        });
    }
    return new Producer(static function (callable $emit) use($iterable) {
        foreach ($iterable as $value) {
            (yield $emit($value));
        }
    });
}
/**
 * @template TValue
 * @template TReturn
 *
 * @param Iterator<TValue> $iterator
 * @param callable (TValue $value): TReturn $onEmit
 *
 * @return Iterator<TReturn>
 */
function map(Iterator $iterator, callable $onEmit) : Iterator
{
    return new Producer(static function (callable $emit) use($iterator, $onEmit) {
        while ((yield $iterator->advance())) {
            (yield $emit($onEmit($iterator->getCurrent())));
        }
    });
}
/**
 * @template TValue
 *
 * @param Iterator<TValue> $iterator
 * @param callable(TValue $value):bool $filter
 *
 * @return Iterator<TValue>
 */
function filter(Iterator $iterator, callable $filter) : Iterator
{
    return new Producer(static function (callable $emit) use($iterator, $filter) {
        while ((yield $iterator->advance())) {
            if ($filter($iterator->getCurrent())) {
                (yield $emit($iterator->getCurrent()));
            }
        }
    });
}
/**
 * Creates an iterator that emits values emitted from any iterator in the array of iterators.
 *
 * @param Iterator[] $iterators
 *
 * @return Iterator
 */
function merge(array $iterators) : Iterator
{
    $emitter = new Emitter();
    $result = $emitter->iterate();
    $coroutine = coroutine(static function (Iterator $iterator) use(&$emitter) {
        while ((yield $iterator->advance()) && $emitter !== null) {
            (yield $emitter->emit($iterator->getCurrent()));
        }
    });
    $coroutines = [];
    foreach ($iterators as $iterator) {
        if (!$iterator instanceof Iterator) {
            throw createTypeError([Iterator::class], $iterator);
        }
        $coroutines[] = $coroutine($iterator);
    }
    Promise\all($coroutines)->onResolve(static function ($exception) use(&$emitter) {
        if ($exception) {
            $emitter->fail($exception);
            $emitter = null;
        } else {
            $emitter->complete();
        }
    });
    return $result;
}
/**
 * Concatenates the given iterators into a single iterator, emitting values from a single iterator at a time. The
 * prior iterator must complete before values are emitted from any subsequent iterators. Iterators are concatenated
 * in the order given (iteration order of the array).
 *
 * @param Iterator[] $iterators
 *
 * @return Iterator
 */
function concat(array $iterators) : Iterator
{
    foreach ($iterators as $iterator) {
        if (!$iterator instanceof Iterator) {
            throw createTypeError([Iterator::class], $iterator);
        }
    }
    $emitter = new Emitter();
    $previous = [];
    $promise = Promise\all($previous);
    $coroutine = coroutine(static function (Iterator $iterator, callable $emit) {
        while ((yield $iterator->advance())) {
            (yield $emit($iterator->getCurrent()));
        }
    });
    foreach ($iterators as $iterator) {
        $emit = coroutine(static function ($value) use($emitter, $promise) {
            static $pending = \true, $failed = \false;
            if ($failed) {
                return;
            }
            if ($pending) {
                try {
                    (yield $promise);
                    $pending = \false;
                } catch (\Throwable $exception) {
                    $failed = \true;
                    return;
                    // Prior iterator failed.
                }
            }
            (yield $emitter->emit($value));
        });
        $previous[] = $coroutine($iterator, $emit);
        $promise = Promise\all($previous);
    }
    $promise->onResolve(static function ($exception) use($emitter) {
        if ($exception) {
            $emitter->fail($exception);
            return;
        }
        $emitter->complete();
    });
    return $emitter->iterate();
}
/**
 * Discards all remaining items and returns the number of discarded items.
 *
 * @template TValue
 *
 * @param Iterator               $iterator
 *
 * @return Promise
 *
 * @psalm-param Iterator<TValue> $iterator
 * @psalm-return Promise<int>
 */
function discard(Iterator $iterator) : Promise
{
    return call(static function () use($iterator) : \Generator {
        $count = 0;
        while ((yield $iterator->advance())) {
            $count++;
        }
        return $count;
    });
}
/**
 * Collects all items from an iterator into an array.
 *
 * @template TValue
 *
 * @param Iterator               $iterator
 *
 * @psalm-param Iterator<TValue> $iterator
 *
 * @return Promise
 * @psalm-return Promise<array<array-key, TValue>>
 */
function toArray(Iterator $iterator) : Promise
{
    return call(static function () use($iterator) {
        /** @psalm-var list $array */
        $array = [];
        while ((yield $iterator->advance())) {
            $array[] = $iterator->getCurrent();
        }
        return $array;
    });
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
/**
 * Creates a promise from a generator function yielding promises.
 *
 * When a promise is yielded, execution of the generator is interrupted until the promise is resolved. A success
 * value is sent into the generator, while a failure reason is thrown into the generator. Using a coroutine,
 * asynchronous code can be written without callbacks and be structured like synchronous code.
 *
 * @template-covariant TReturn
 * @template-implements Promise<TReturn>
 */
final class Coroutine implements Promise
{
    use Internal\Placeholder;
    /**
     * Attempts to transform the non-promise yielded from the generator into a promise, otherwise returns an instance
     * `Amp\Failure` failed with an instance of `Amp\InvalidYieldError`.
     *
     * @param mixed      $yielded Non-promise yielded from generator.
     * @param \Generator $generator No type for performance, we already know the type.
     *
     * @return Promise
     */
    private static function transform($yielded, $generator) : Promise
    {
        $exception = null;
        // initialize here, see https://github.com/vimeo/psalm/issues/2951
        try {
            if (\is_array($yielded)) {
                return Promise\all($yielded);
            }
            if ($yielded instanceof ReactPromise) {
                return Promise\adapt($yielded);
            }
            // No match, continue to returning Failure below.
        } catch (\Throwable $exception) {
            // Conversion to promise failed, fall-through to returning Failure below.
        }
        return new Failure(new InvalidYieldError($generator, \sprintf("Unexpected yield; Expected an instance of %s or %s or an array of such instances", Promise::class, ReactPromise::class), $exception));
    }
    /**
     * @param \Generator $generator
     * @psalm-param \Generator<mixed,Promise|ReactPromise|array<array-key,
     *     Promise|ReactPromise>,mixed,Promise<TReturn>|ReactPromise|TReturn> $generator
     */
    public function __construct(\Generator $generator)
    {
        try {
            $yielded = $generator->current();
            if (!$yielded instanceof Promise) {
                if (!$generator->valid()) {
                    $this->resolve($generator->getReturn());
                    return;
                }
                $yielded = self::transform($yielded, $generator);
            }
        } catch (\Throwable $exception) {
            $this->fail($exception);
            return;
        }
        /**
         * @param \Throwable|null $e Exception to be thrown into the generator.
         * @param mixed           $v Value to be sent into the generator.
         *
         * @return void
         *
         * @psalm-suppress MissingClosureParamType
         * @psalm-suppress MissingClosureReturnType
         */
        $onResolve = function (\Throwable $e = null, $v) use($generator, &$onResolve) {
            /** @var bool $immediate Used to control iterative coroutine continuation. */
            static $immediate = \true;
            /** @var \Throwable|null $exception Promise failure reason when executing next coroutine step, null at all other times. */
            static $exception;
            /** @var mixed $value Promise success value when executing next coroutine step, null at all other times. */
            static $value;
            $exception = $e;
            /** @psalm-suppress MixedAssignment */
            $value = $v;
            if (!$immediate) {
                $immediate = \true;
                return;
            }
            try {
                try {
                    do {
                        if ($exception) {
                            // Throw exception at current execution point.
                            $yielded = $generator->throw($exception);
                        } else {
                            // Send the new value and execute to next yield statement.
                            $yielded = $generator->send($value);
                        }
                        if (!$yielded instanceof Promise) {
                            if (!$generator->valid()) {
                                $this->resolve($generator->getReturn());
                                $onResolve = null;
                                return;
                            }
                            $yielded = self::transform($yielded, $generator);
                        }
                        $immediate = \false;
                        $yielded->onResolve($onResolve);
                    } while ($immediate);
                    $immediate = \true;
                } catch (\Throwable $exception) {
                    $this->fail($exception);
                    $onResolve = null;
                } finally {
                    $exception = null;
                    $value = null;
                }
            } catch (\Throwable $e) {
                Loop::defer(static function () use($e) {
                    throw $e;
                });
            }
        };
        try {
            $yielded->onResolve($onResolve);
            unset($generator, $yielded, $onResolve);
        } catch (\Throwable $e) {
            Loop::defer(static function () use($e) {
                throw $e;
            });
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

final class CombinedCancellationToken implements CancellationToken
{
    /** @var array{0: CancellationToken, 1: string}[] */
    private $tokens = [];
    /** @var string */
    private $nextId = "a";
    /** @var callable[] */
    private $callbacks = [];
    /** @var CancelledException|null */
    private $exception;
    public function __construct(CancellationToken ...$tokens)
    {
        $thatException =& $this->exception;
        $thatCallbacks =& $this->callbacks;
        foreach ($tokens as $token) {
            $id = $token->subscribe(static function (CancelledException $exception) use(&$thatException, &$thatCallbacks) {
                $thatException = $exception;
                $callbacks = $thatCallbacks;
                $thatCallbacks = [];
                foreach ($callbacks as $callback) {
                    asyncCall($callback, $thatException);
                }
            });
            $this->tokens[] = [$token, $id];
        }
    }
    public function __destruct()
    {
        foreach ($this->tokens as list($token, $id)) {
            /** @var CancellationToken $token */
            $token->unsubscribe($id);
        }
    }
    /** @inheritdoc */
    public function subscribe(callable $callback) : string
    {
        $id = $this->nextId++;
        if ($this->exception) {
            asyncCall($callback, $this->exception);
        } else {
            $this->callbacks[$id] = $callback;
        }
        return $id;
    }
    /** @inheritdoc */
    public function unsubscribe(string $id)
    {
        unset($this->callbacks[$id]);
    }
    /** @inheritdoc */
    public function isRequested() : bool
    {
        foreach ($this->tokens as list($token)) {
            if ($token->isRequested()) {
                return \true;
            }
        }
        return \false;
    }
    /** @inheritdoc */
    public function throwIfRequested()
    {
        foreach ($this->tokens as list($token)) {
            $token->throwIfRequested();
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
use function _HumbugBox1cb33d1f20f1\Amp\Promise\rethrow;
/**
 * A cancellation token source provides a mechanism to cancel operations.
 *
 * Cancellation of operation works by creating a cancellation token source and passing the corresponding token when
 * starting the operation. To cancel the operation, invoke `CancellationTokenSource::cancel()`.
 *
 * Any operation can decide what to do on a cancellation request, it has "don't care" semantics. An operation SHOULD be
 * aborted, but MAY continue. Example: A DNS client might continue to receive and cache the response, as the query has
 * been sent anyway. An HTTP client would usually close a connection, but might not do so in case a response is close to
 * be fully received to reuse the connection.
 *
 * **Example**
 *
 * ```php
 * $tokenSource = new CancellationTokenSource;
 * $token = $tokenSource->getToken();
 *
 * $response = yield $httpClient->request("https://example.com/stream", $token);
 * $responseBody = $response->getBody();
 *
 * while (($chunk = yield $response->read()) !== null) {
 *     // consume $chunk
 *
 *     if ($noLongerInterested) {
 *         $cancellationTokenSource->cancel();
 *         break;
 *     }
 * }
 * ```
 *
 * @see CancellationToken
 * @see CancelledException
 */
final class CancellationTokenSource
{
    /** @var CancellationToken */
    private $token;
    /** @var callable|null */
    private $onCancel;
    public function __construct()
    {
        $onCancel = null;
        $this->token = new class($onCancel) implements CancellationToken
        {
            /** @var string */
            private $nextId = "a";
            /** @var callable[] */
            private $callbacks = [];
            /** @var \Throwable|null */
            private $exception;
            /**
             * @param mixed $onCancel
             * @param-out callable $onCancel
             */
            public function __construct(&$onCancel)
            {
                /** @psalm-suppress MissingClosureReturnType We still support PHP 7.0 */
                $onCancel = function (\Throwable $exception) {
                    $this->exception = $exception;
                    $callbacks = $this->callbacks;
                    $this->callbacks = [];
                    foreach ($callbacks as $callback) {
                        $this->invokeCallback($callback);
                    }
                };
            }
            /**
             * @param callable $callback
             *
             * @return void
             */
            private function invokeCallback(callable $callback)
            {
                // No type declaration to prevent exception outside the try!
                try {
                    /** @var mixed $result */
                    $result = $callback($this->exception);
                    if ($result instanceof \Generator) {
                        /** @psalm-var \Generator<mixed, Promise|ReactPromise|(Promise|ReactPromise)[], mixed, mixed> $result */
                        $result = new Coroutine($result);
                    }
                    if ($result instanceof Promise || $result instanceof ReactPromise) {
                        rethrow($result);
                    }
                } catch (\Throwable $exception) {
                    Loop::defer(static function () use($exception) {
                        throw $exception;
                    });
                }
            }
            public function subscribe(callable $callback) : string
            {
                $id = $this->nextId++;
                if ($this->exception) {
                    $this->invokeCallback($callback);
                } else {
                    $this->callbacks[$id] = $callback;
                }
                return $id;
            }
            public function unsubscribe(string $id)
            {
                unset($this->callbacks[$id]);
            }
            public function isRequested() : bool
            {
                return isset($this->exception);
            }
            public function throwIfRequested()
            {
                if (isset($this->exception)) {
                    throw $this->exception;
                }
            }
        };
        $this->onCancel = $onCancel;
    }
    public function getToken() : CancellationToken
    {
        return $this->token;
    }
    /**
     * @param \Throwable|null $previous Exception to be used as the previous exception to CancelledException.
     *
     * @return void
     */
    public function cancel(\Throwable $previous = null)
    {
        if ($this->onCancel === null) {
            return;
        }
        $onCancel = $this->onCancel;
        $this->onCancel = null;
        $onCancel(new CancelledException($previous));
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
/**
 * Creates a failed promise using the given exception.
 *
 * @template-covariant TValue
 * @template-implements Promise<TValue>
 */
final class Failure implements Promise
{
    /** @var \Throwable $exception */
    private $exception;
    /**
     * @param \Throwable $exception Rejection reason.
     */
    public function __construct(\Throwable $exception)
    {
        $this->exception = $exception;
    }
    /**
     * {@inheritdoc}
     */
    public function onResolve(callable $onResolved)
    {
        try {
            /** @var mixed $result */
            $result = $onResolved($this->exception, null);
            if ($result === null) {
                return;
            }
            if ($result instanceof \Generator) {
                $result = new Coroutine($result);
            }
            if ($result instanceof Promise || $result instanceof ReactPromise) {
                Promise\rethrow($result);
            }
        } catch (\Throwable $exception) {
            Loop::defer(static function () use($exception) {
                throw $exception;
            });
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * @template-covariant TValue
 * @template-implements Iterator<TValue>
 */
final class Producer implements Iterator
{
    /**
     * @use Internal\Producer<TValue>
     */
    use CallableMaker, Internal\Producer;
    /**
     * @param callable(callable(TValue):Promise):\Generator $producer
     *
     * @throws \Error Thrown if the callable does not return a Generator.
     */
    public function __construct(callable $producer)
    {
        $result = $producer($this->callableFromInstanceMethod("emit"));
        if (!$result instanceof \Generator) {
            throw new \Error("The callable did not return a Generator");
        }
        $coroutine = new Coroutine($result);
        $coroutine->onResolve(function ($exception) {
            if ($this->complete) {
                return;
            }
            if ($exception) {
                $this->fail($exception);
                return;
            }
            $this->complete();
        });
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
/**
 * Creates a successful promise using the given value (which can be any value except an object implementing
 * `Amp\Promise` or `React\Promise\PromiseInterface`).
 *
 * @template-covariant TValue
 * @template-implements Promise<TValue>
 */
final class Success implements Promise
{
    /** @var mixed */
    private $value;
    /**
     * @param mixed $value Anything other than a Promise object.
     *
     * @psalm-param TValue $value
     *
     * @throws \Error If a promise is given as the value.
     */
    public function __construct($value = null)
    {
        if ($value instanceof Promise || $value instanceof ReactPromise) {
            throw new \Error("Cannot use a promise as success value");
        }
        $this->value = $value;
    }
    /**
     * {@inheritdoc}
     */
    public function onResolve(callable $onResolved)
    {
        try {
            $result = $onResolved(null, $this->value);
            if ($result === null) {
                return;
            }
            if ($result instanceof \Generator) {
                $result = new Coroutine($result);
            }
            if ($result instanceof Promise || $result instanceof ReactPromise) {
                Promise\rethrow($result);
            }
        } catch (\Throwable $exception) {
            Loop::defer(static function () use($exception) {
                throw $exception;
            });
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

// @codeCoverageIgnoreStart
if (\PHP_VERSION_ID < 70100) {
    /** @psalm-suppress DuplicateClass */
    trait CallableMaker
    {
        /** @var \ReflectionClass */
        private static $__reflectionClass;
        /** @var \ReflectionMethod[] */
        private static $__reflectionMethods = [];
        /**
         * Creates a callable from a protected or private instance method that may be invoked by callers requiring a
         * publicly invokable callback.
         *
         * @param string $method Instance method name.
         *
         * @return callable
         *
         * @psalm-suppress MixedInferredReturnType
         */
        private function callableFromInstanceMethod(string $method) : callable
        {
            if (!isset(self::$__reflectionMethods[$method])) {
                if (self::$__reflectionClass === null) {
                    self::$__reflectionClass = new \ReflectionClass(self::class);
                }
                self::$__reflectionMethods[$method] = self::$__reflectionClass->getMethod($method);
            }
            return self::$__reflectionMethods[$method]->getClosure($this);
        }
        /**
         * Creates a callable from a protected or private static method that may be invoked by methods requiring a
         * publicly invokable callback.
         *
         * @param string $method Static method name.
         *
         * @return callable
         *
         * @psalm-suppress MixedInferredReturnType
         */
        private static function callableFromStaticMethod(string $method) : callable
        {
            if (!isset(self::$__reflectionMethods[$method])) {
                if (self::$__reflectionClass === null) {
                    self::$__reflectionClass = new \ReflectionClass(self::class);
                }
                self::$__reflectionMethods[$method] = self::$__reflectionClass->getMethod($method);
            }
            return self::$__reflectionMethods[$method]->getClosure();
        }
    }
} else {
    /** @psalm-suppress DuplicateClass */
    trait CallableMaker
    {
        /**
         * @deprecated Use \Closure::fromCallable() instead of this method in PHP 7.1.
         */
        private function callableFromInstanceMethod(string $method) : callable
        {
            return \Closure::fromCallable([$this, $method]);
        }
        /**
         * @deprecated Use \Closure::fromCallable() instead of this method in PHP 7.1.
         */
        private static function callableFromStaticMethod(string $method) : callable
        {
            return \Closure::fromCallable([self::class, $method]);
        }
    }
}
// @codeCoverageIgnoreEnd
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Deferred is a container for a promise that is resolved using the resolve() and fail() methods of this object.
 * The contained promise may be accessed using the promise() method. This object should not be part of a public
 * API, but used internally to create and resolve a promise.
 *
 * @template TValue
 */
final class Deferred
{
    /** @var Promise<TValue> Has public resolve and fail methods. */
    private $resolver;
    /** @var Promise<TValue> Hides placeholder methods */
    private $promise;
    public function __construct()
    {
        $this->resolver = new class implements Promise
        {
            use Internal\Placeholder {
                resolve as public;
                fail as public;
                isResolved as public;
            }
        };
        $this->promise = new Internal\PrivatePromise($this->resolver);
    }
    /**
     * @return Promise<TValue>
     */
    public function promise() : Promise
    {
        return $this->promise;
    }
    /**
     * Fulfill the promise with the given value.
     *
     * @param mixed $value
     *
     * @psalm-param TValue|Promise<TValue> $value
     *
     * @return void
     */
    public function resolve($value = null)
    {
        /** @psalm-suppress UndefinedInterfaceMethod */
        $this->resolver->resolve($value);
    }
    /**
     * Fails the promise the the given reason.
     *
     * @param \Throwable $reason
     *
     * @return void
     */
    public function fail(\Throwable $reason)
    {
        /** @psalm-suppress UndefinedInterfaceMethod */
        $this->resolver->fail($reason);
    }
    /**
     * @return bool True if the promise has been resolved.
     */
    public function isResolved() : bool
    {
        return $this->resolver->isResolved();
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

use function _HumbugBox1cb33d1f20f1\Amp\Internal\formatStacktrace;
final class TracingDriver extends Driver
{
    /** @var Driver */
    private $driver;
    /** @var true[] */
    private $enabledWatchers = [];
    /** @var true[] */
    private $unreferencedWatchers = [];
    /** @var string[] */
    private $creationTraces = [];
    /** @var string[] */
    private $cancelTraces = [];
    public function __construct(Driver $driver)
    {
        $this->driver = $driver;
    }
    public function run()
    {
        $this->driver->run();
    }
    public function stop()
    {
        $this->driver->stop();
    }
    public function defer(callable $callback, $data = null) : string
    {
        $id = $this->driver->defer(function (...$args) use($callback) {
            $this->cancel($args[0]);
            return $callback(...$args);
        }, $data);
        $this->creationTraces[$id] = formatStacktrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS));
        $this->enabledWatchers[$id] = \true;
        return $id;
    }
    public function delay(int $delay, callable $callback, $data = null) : string
    {
        $id = $this->driver->delay($delay, function (...$args) use($callback) {
            $this->cancel($args[0]);
            return $callback(...$args);
        }, $data);
        $this->creationTraces[$id] = formatStacktrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS));
        $this->enabledWatchers[$id] = \true;
        return $id;
    }
    public function repeat(int $interval, callable $callback, $data = null) : string
    {
        $id = $this->driver->repeat($interval, $callback, $data);
        $this->creationTraces[$id] = formatStacktrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS));
        $this->enabledWatchers[$id] = \true;
        return $id;
    }
    public function onReadable($stream, callable $callback, $data = null) : string
    {
        $id = $this->driver->onReadable($stream, $callback, $data);
        $this->creationTraces[$id] = formatStacktrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS));
        $this->enabledWatchers[$id] = \true;
        return $id;
    }
    public function onWritable($stream, callable $callback, $data = null) : string
    {
        $id = $this->driver->onWritable($stream, $callback, $data);
        $this->creationTraces[$id] = formatStacktrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS));
        $this->enabledWatchers[$id] = \true;
        return $id;
    }
    public function onSignal(int $signo, callable $callback, $data = null) : string
    {
        $id = $this->driver->onSignal($signo, $callback, $data);
        $this->creationTraces[$id] = formatStacktrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS));
        $this->enabledWatchers[$id] = \true;
        return $id;
    }
    public function enable(string $watcherId)
    {
        try {
            $this->driver->enable($watcherId);
            $this->enabledWatchers[$watcherId] = \true;
        } catch (InvalidWatcherError $e) {
            throw new InvalidWatcherError($watcherId, $e->getMessage() . "\r\n\r\n" . $this->getTraces($watcherId));
        }
    }
    public function cancel(string $watcherId)
    {
        $this->driver->cancel($watcherId);
        if (!isset($this->cancelTraces[$watcherId])) {
            $this->cancelTraces[$watcherId] = formatStacktrace(\debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS));
        }
        unset($this->enabledWatchers[$watcherId], $this->unreferencedWatchers[$watcherId]);
    }
    public function disable(string $watcherId)
    {
        $this->driver->disable($watcherId);
        unset($this->enabledWatchers[$watcherId]);
    }
    public function reference(string $watcherId)
    {
        try {
            $this->driver->reference($watcherId);
            unset($this->unreferencedWatchers[$watcherId]);
        } catch (InvalidWatcherError $e) {
            throw new InvalidWatcherError($watcherId, $e->getMessage() . "\r\n\r\n" . $this->getTraces($watcherId));
        }
    }
    public function unreference(string $watcherId)
    {
        $this->driver->unreference($watcherId);
        $this->unreferencedWatchers[$watcherId] = \true;
    }
    public function setErrorHandler(callable $callback = null)
    {
        return $this->driver->setErrorHandler($callback);
    }
    /** @inheritdoc */
    public function getHandle()
    {
        $this->driver->getHandle();
    }
    public function dump() : string
    {
        $dump = "Enabled, referenced watchers keeping the loop running: ";
        foreach ($this->enabledWatchers as $watcher => $_) {
            if (isset($this->unreferencedWatchers[$watcher])) {
                continue;
            }
            $dump .= "Watcher ID: " . $watcher . "\r\n";
            $dump .= $this->getCreationTrace($watcher);
            $dump .= "\r\n\r\n";
        }
        return \rtrim($dump);
    }
    public function getInfo() : array
    {
        return $this->driver->getInfo();
    }
    public function __debugInfo()
    {
        return $this->driver->__debugInfo();
    }
    public function now() : int
    {
        return $this->driver->now();
    }
    protected function error(\Throwable $exception)
    {
        $this->driver->error($exception);
    }
    /**
     * @inheritdoc
     *
     * @return void
     */
    protected function activate(array $watchers)
    {
        // nothing to do in a decorator
    }
    /**
     * @inheritdoc
     *
     * @return void
     */
    protected function dispatch(bool $blocking)
    {
        // nothing to do in a decorator
    }
    /**
     * @inheritdoc
     *
     * @return void
     */
    protected function deactivate(Watcher $watcher)
    {
        // nothing to do in a decorator
    }
    private function getTraces(string $watcherId) : string
    {
        return "Creation Trace:\r\n" . $this->getCreationTrace($watcherId) . "\r\n\r\n" . "Cancellation Trace:\r\n" . $this->getCancelTrace($watcherId);
    }
    private function getCreationTrace(string $watcher) : string
    {
        if (!isset($this->creationTraces[$watcher])) {
            return 'No creation trace, yet.';
        }
        return $this->creationTraces[$watcher];
    }
    private function getCancelTrace(string $watcher) : string
    {
        if (!isset($this->cancelTraces[$watcher])) {
            return 'No cancellation trace, yet.';
        }
        return $this->cancelTraces[$watcher];
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

use _HumbugBox1cb33d1f20f1\Amp\CallableMaker;
use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
use function _HumbugBox1cb33d1f20f1\Amp\Internal\getCurrentTime;
use function _HumbugBox1cb33d1f20f1\Amp\Promise\rethrow;
class NativeDriver extends Driver
{
    use CallableMaker;
    /** @var resource[] */
    private $readStreams = [];
    /** @var Watcher[][] */
    private $readWatchers = [];
    /** @var resource[] */
    private $writeStreams = [];
    /** @var Watcher[][] */
    private $writeWatchers = [];
    /** @var Internal\TimerQueue */
    private $timerQueue;
    /** @var Watcher[][] */
    private $signalWatchers = [];
    /** @var int Internal timestamp for now. */
    private $now;
    /** @var int Loop time offset */
    private $nowOffset;
    /** @var bool */
    private $signalHandling;
    /** @var callable */
    private $streamSelectErrorHandler;
    /** @var bool */
    private $streamSelectIgnoreResult = \false;
    public function __construct()
    {
        $this->timerQueue = new Internal\TimerQueue();
        $this->signalHandling = \extension_loaded("pcntl");
        $this->nowOffset = getCurrentTime();
        $this->now = \random_int(0, $this->nowOffset);
        $this->nowOffset -= $this->now;
        $this->streamSelectErrorHandler = function ($errno, $message) {
            // Casing changed in PHP 8 from 'unable' to 'Unable'
            if (\stripos($message, "stream_select(): unable to select [4]: ") === 0) {
                // EINTR
                $this->streamSelectIgnoreResult = \true;
                return;
            }
            if (\strpos($message, 'FD_SETSIZE') !== \false) {
                $message = \str_replace(["\r\n", "\n", "\r"], " ", $message);
                $pattern = '(stream_select\\(\\): You MUST recompile PHP with a larger value of FD_SETSIZE. It is set to (\\d+), but you have descriptors numbered at least as high as (\\d+)\\.)';
                if (\preg_match($pattern, $message, $match)) {
                    $helpLink = 'https://amphp.org/amp/event-loop/#implementations';
                    $message = 'You have reached the limits of stream_select(). It has a FD_SETSIZE of ' . $match[1] . ', but you have file descriptors numbered at least as high as ' . $match[2] . '. ' . "You can install one of the extensions listed on {$helpLink} to support a higher number of " . "concurrent file descriptors. If a large number of open file descriptors is unexpected, you " . "might be leaking file descriptors that aren't closed correctly.";
                }
            }
            throw new \Exception($message, $errno);
        };
    }
    /**
     * {@inheritdoc}
     *
     * @throws \Amp\Loop\UnsupportedFeatureException If the pcntl extension is not available.
     */
    public function onSignal(int $signo, callable $callback, $data = null) : string
    {
        if (!$this->signalHandling) {
            throw new UnsupportedFeatureException("Signal handling requires the pcntl extension");
        }
        return parent::onSignal($signo, $callback, $data);
    }
    /**
     * {@inheritdoc}
     */
    public function now() : int
    {
        $this->now = getCurrentTime() - $this->nowOffset;
        return $this->now;
    }
    /**
     * {@inheritdoc}
     */
    public function getHandle()
    {
        return null;
    }
    /**
     * @param bool $blocking
     *
     * @return void
     *
     * @throws \Throwable
     */
    protected function dispatch(bool $blocking)
    {
        $this->selectStreams($this->readStreams, $this->writeStreams, $blocking ? $this->getTimeout() : 0);
        $now = $this->now();
        while ($watcher = $this->timerQueue->extract($now)) {
            if ($watcher->type & Watcher::REPEAT) {
                $watcher->enabled = \false;
                // Trick base class into adding to enable queue when calling enable()
                $this->enable($watcher->id);
            } else {
                $this->cancel($watcher->id);
            }
            try {
                // Execute the timer.
                $result = ($watcher->callback)($watcher->id, $watcher->data);
                if ($result === null) {
                    continue;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        }
        if ($this->signalHandling) {
            \pcntl_signal_dispatch();
        }
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function activate(array $watchers)
    {
        foreach ($watchers as $watcher) {
            switch ($watcher->type) {
                case Watcher::READABLE:
                    \assert(\is_resource($watcher->value));
                    $streamId = (int) $watcher->value;
                    $this->readWatchers[$streamId][$watcher->id] = $watcher;
                    $this->readStreams[$streamId] = $watcher->value;
                    break;
                case Watcher::WRITABLE:
                    \assert(\is_resource($watcher->value));
                    $streamId = (int) $watcher->value;
                    $this->writeWatchers[$streamId][$watcher->id] = $watcher;
                    $this->writeStreams[$streamId] = $watcher->value;
                    break;
                case Watcher::DELAY:
                case Watcher::REPEAT:
                    \assert(\is_int($watcher->value));
                    $this->timerQueue->insert($watcher);
                    break;
                case Watcher::SIGNAL:
                    \assert(\is_int($watcher->value));
                    if (!isset($this->signalWatchers[$watcher->value])) {
                        if (!@\pcntl_signal($watcher->value, $this->callableFromInstanceMethod('handleSignal'))) {
                            $message = "Failed to register signal handler";
                            if ($error = \error_get_last()) {
                                $message .= \sprintf("; Errno: %d; %s", $error["type"], $error["message"]);
                            }
                            throw new \Error($message);
                        }
                    }
                    $this->signalWatchers[$watcher->value][$watcher->id] = $watcher;
                    break;
                default:
                    // @codeCoverageIgnoreStart
                    throw new \Error("Unknown watcher type");
            }
        }
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function deactivate(Watcher $watcher)
    {
        switch ($watcher->type) {
            case Watcher::READABLE:
                $streamId = (int) $watcher->value;
                unset($this->readWatchers[$streamId][$watcher->id]);
                if (empty($this->readWatchers[$streamId])) {
                    unset($this->readWatchers[$streamId], $this->readStreams[$streamId]);
                }
                break;
            case Watcher::WRITABLE:
                $streamId = (int) $watcher->value;
                unset($this->writeWatchers[$streamId][$watcher->id]);
                if (empty($this->writeWatchers[$streamId])) {
                    unset($this->writeWatchers[$streamId], $this->writeStreams[$streamId]);
                }
                break;
            case Watcher::DELAY:
            case Watcher::REPEAT:
                $this->timerQueue->remove($watcher);
                break;
            case Watcher::SIGNAL:
                \assert(\is_int($watcher->value));
                if (isset($this->signalWatchers[$watcher->value])) {
                    unset($this->signalWatchers[$watcher->value][$watcher->id]);
                    if (empty($this->signalWatchers[$watcher->value])) {
                        unset($this->signalWatchers[$watcher->value]);
                        @\pcntl_signal($watcher->value, \SIG_DFL);
                    }
                }
                break;
            default:
                // @codeCoverageIgnoreStart
                throw new \Error("Unknown watcher type");
        }
    }
    /**
     * @param resource[] $read
     * @param resource[] $write
     * @param int        $timeout
     *
     * @return void
     */
    private function selectStreams(array $read, array $write, int $timeout)
    {
        $timeout /= self::MILLISEC_PER_SEC;
        if (!empty($read) || !empty($write)) {
            // Use stream_select() if there are any streams in the loop.
            if ($timeout >= 0) {
                $seconds = (int) $timeout;
                $microseconds = (int) (($timeout - $seconds) * self::MICROSEC_PER_SEC);
            } else {
                $seconds = null;
                $microseconds = null;
            }
            // Failed connection attempts are indicated via except on Windows
            // @link https://github.com/reactphp/event-loop/blob/8bd064ce23c26c4decf186c2a5a818c9a8209eb0/src/StreamSelectLoop.php#L279-L287
            // @link https://docs.microsoft.com/de-de/windows/win32/api/winsock2/nf-winsock2-select
            $except = null;
            if (\DIRECTORY_SEPARATOR === '\\') {
                $except = $write;
            }
            \set_error_handler($this->streamSelectErrorHandler);
            try {
                $result = \stream_select($read, $write, $except, $seconds, $microseconds);
            } finally {
                \restore_error_handler();
            }
            if ($this->streamSelectIgnoreResult || $result === 0) {
                $this->streamSelectIgnoreResult = \false;
                return;
            }
            if (!$result) {
                $this->error(new \Exception('Unknown error during stream_select'));
                return;
            }
            foreach ($read as $stream) {
                $streamId = (int) $stream;
                if (!isset($this->readWatchers[$streamId])) {
                    continue;
                    // All read watchers disabled.
                }
                foreach ($this->readWatchers[$streamId] as $watcher) {
                    if (!isset($this->readWatchers[$streamId][$watcher->id])) {
                        continue;
                        // Watcher disabled by another IO watcher.
                    }
                    try {
                        $result = ($watcher->callback)($watcher->id, $stream, $watcher->data);
                        if ($result === null) {
                            continue;
                        }
                        if ($result instanceof \Generator) {
                            $result = new Coroutine($result);
                        }
                        if ($result instanceof Promise || $result instanceof ReactPromise) {
                            rethrow($result);
                        }
                    } catch (\Throwable $exception) {
                        $this->error($exception);
                    }
                }
            }
            \assert(\is_array($write));
            // See https://github.com/vimeo/psalm/issues/3036
            if ($except) {
                foreach ($except as $key => $socket) {
                    $write[$key] = $socket;
                }
            }
            foreach ($write as $stream) {
                $streamId = (int) $stream;
                if (!isset($this->writeWatchers[$streamId])) {
                    continue;
                    // All write watchers disabled.
                }
                foreach ($this->writeWatchers[$streamId] as $watcher) {
                    if (!isset($this->writeWatchers[$streamId][$watcher->id])) {
                        continue;
                        // Watcher disabled by another IO watcher.
                    }
                    try {
                        $result = ($watcher->callback)($watcher->id, $stream, $watcher->data);
                        if ($result === null) {
                            continue;
                        }
                        if ($result instanceof \Generator) {
                            $result = new Coroutine($result);
                        }
                        if ($result instanceof Promise || $result instanceof ReactPromise) {
                            rethrow($result);
                        }
                    } catch (\Throwable $exception) {
                        $this->error($exception);
                    }
                }
            }
            return;
        }
        if ($timeout < 0) {
            // Only signal watchers are enabled, so sleep indefinitely.
            \usleep(\PHP_INT_MAX);
            return;
        }
        if ($timeout > 0) {
            // Sleep until next timer expires.
            \usleep((int) ($timeout * self::MICROSEC_PER_SEC));
        }
    }
    /**
     * @return int Milliseconds until next timer expires or -1 if there are no pending times.
     */
    private function getTimeout() : int
    {
        $expiration = $this->timerQueue->peek();
        if ($expiration === null) {
            return -1;
        }
        $expiration -= getCurrentTime() - $this->nowOffset;
        return $expiration > 0 ? $expiration : 0;
    }
    /**
     * @param int $signo
     *
     * @return void
     */
    private function handleSignal(int $signo)
    {
        foreach ($this->signalWatchers[$signo] as $watcher) {
            if (!isset($this->signalWatchers[$signo][$watcher->id])) {
                continue;
            }
            try {
                $result = ($watcher->callback)($watcher->id, $signo, $watcher->data);
                if ($result === null) {
                    continue;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop\Internal;

use _HumbugBox1cb33d1f20f1\Amp\Loop\Watcher;
/**
 * Uses a binary tree stored in an array to implement a heap.
 */
final class TimerQueue
{
    /** @var Watcher[] */
    private $data = [];
    /** @var int[] */
    private $pointers = [];
    /**
     * @param int $node Rebuild the data array from the given node upward.
     *
     * @return void
     */
    private function heapifyUp(int $node)
    {
        $entry = $this->data[$node];
        while ($node !== 0 && $entry->expiration < $this->data[$parent = $node - 1 >> 1]->expiration) {
            $this->swap($node, $parent);
            $node = $parent;
        }
    }
    /**
     * @param int $node Rebuild the data array from the given node downward.
     *
     * @return void
     */
    private function heapifyDown(int $node)
    {
        $length = \count($this->data);
        while (($child = ($node << 1) + 1) < $length) {
            if ($this->data[$child]->expiration < $this->data[$node]->expiration && ($child + 1 >= $length || $this->data[$child]->expiration < $this->data[$child + 1]->expiration)) {
                // Left child is less than parent and right child.
                $swap = $child;
            } elseif ($child + 1 < $length && $this->data[$child + 1]->expiration < $this->data[$node]->expiration) {
                // Right child is less than parent and left child.
                $swap = $child + 1;
            } else {
                // Left and right child are greater than parent.
                break;
            }
            $this->swap($node, $swap);
            $node = $swap;
        }
    }
    private function swap(int $left, int $right)
    {
        $temp = $this->data[$left];
        $this->data[$left] = $this->data[$right];
        $this->pointers[$this->data[$right]->id] = $left;
        $this->data[$right] = $temp;
        $this->pointers[$temp->id] = $right;
    }
    /**
     * Inserts the watcher into the queue. Time complexity: O(log(n)).
     *
     * @param Watcher $watcher
     *
     * @psalm-param Watcher<int> $watcher
     *
     * @return void
     */
    public function insert(Watcher $watcher)
    {
        \assert($watcher->expiration !== null);
        \assert(!isset($this->pointers[$watcher->id]));
        $node = \count($this->data);
        $this->data[$node] = $watcher;
        $this->pointers[$watcher->id] = $node;
        $this->heapifyUp($node);
    }
    /**
     * Removes the given watcher from the queue. Time complexity: O(log(n)).
     *
     * @param Watcher $watcher
     *
     * @psalm-param Watcher<int> $watcher
     *
     * @return void
     */
    public function remove(Watcher $watcher)
    {
        $id = $watcher->id;
        if (!isset($this->pointers[$id])) {
            return;
        }
        $this->removeAndRebuild($this->pointers[$id]);
    }
    /**
     * Deletes and returns the Watcher on top of the heap if it has expired, otherwise null is returned.
     * Time complexity: O(log(n)).
     *
     * @param int $now Current loop time.
     *
     * @return Watcher|null Expired watcher at the top of the heap or null if the watcher has not expired.
     *
     * @psalm-return Watcher<int>|null
     */
    public function extract(int $now)
    {
        if (empty($this->data)) {
            return null;
        }
        $watcher = $this->data[0];
        if ($watcher->expiration > $now) {
            return null;
        }
        $this->removeAndRebuild(0);
        return $watcher;
    }
    /**
     * Returns the expiration time value at the top of the heap. Time complexity: O(1).
     *
     * @return int|null Expiration time of the watcher at the top of the heap or null if the heap is empty.
     */
    public function peek()
    {
        return isset($this->data[0]) ? $this->data[0]->expiration : null;
    }
    /**
     * @param int $node Remove the given node and then rebuild the data array.
     *
     * @return void
     */
    private function removeAndRebuild(int $node)
    {
        $length = \count($this->data) - 1;
        $id = $this->data[$node]->id;
        $left = $this->data[$node] = $this->data[$length];
        $this->pointers[$left->id] = $node;
        unset($this->data[$length], $this->pointers[$id]);
        if ($node < $length) {
            // don't need to do anything if we removed the last element
            $parent = $node - 1 >> 1;
            if ($parent >= 0 && $this->data[$node]->expiration < $this->data[$parent]->expiration) {
                $this->heapifyUp($node);
            } else {
                $this->heapifyDown($node);
            }
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
use function _HumbugBox1cb33d1f20f1\Amp\Promise\rethrow;
/**
 * Event loop driver which implements all basic operations to allow interoperability.
 *
 * Watchers (enabled or new watchers) MUST immediately be marked as enabled, but only be activated (i.e. callbacks can
 * be called) right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
 *
 * All registered callbacks MUST NOT be called from a file with strict types enabled (`declare(strict_types=1)`).
 */
abstract class Driver
{
    // Don't use 1e3 / 1e6, they result in a float instead of int
    const MILLISEC_PER_SEC = 1000;
    const MICROSEC_PER_SEC = 1000000;
    /** @var string */
    private $nextId = "a";
    /** @var Watcher[] */
    private $watchers = [];
    /** @var Watcher[] */
    private $enableQueue = [];
    /** @var Watcher[] */
    private $deferQueue = [];
    /** @var Watcher[] */
    private $nextTickQueue = [];
    /** @var callable(\Throwable):void|null */
    private $errorHandler;
    /** @var bool */
    private $running = \false;
    /** @var array */
    private $registry = [];
    /**
     * Run the event loop.
     *
     * One iteration of the loop is called one "tick". A tick covers the following steps:
     *
     *  1. Activate watchers created / enabled in the last tick / before `run()`.
     *  2. Execute all enabled defer watchers.
     *  3. Execute all due timer, pending signal and actionable stream callbacks, each only once per tick.
     *
     * The loop MUST continue to run until it is either stopped explicitly, no referenced watchers exist anymore, or an
     * exception is thrown that cannot be handled. Exceptions that cannot be handled are exceptions thrown from an
     * error handler or exceptions that would be passed to an error handler but none exists to handle them.
     *
     * @return void
     */
    public function run()
    {
        $this->running = \true;
        try {
            while ($this->running) {
                if ($this->isEmpty()) {
                    return;
                }
                $this->tick();
            }
        } finally {
            $this->stop();
        }
    }
    /**
     * @return bool True if no enabled and referenced watchers remain in the loop.
     */
    private function isEmpty() : bool
    {
        foreach ($this->watchers as $watcher) {
            if ($watcher->enabled && $watcher->referenced) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * Executes a single tick of the event loop.
     *
     * @return void
     */
    private function tick()
    {
        if (empty($this->deferQueue)) {
            $this->deferQueue = $this->nextTickQueue;
        } else {
            $this->deferQueue = \array_merge($this->deferQueue, $this->nextTickQueue);
        }
        $this->nextTickQueue = [];
        $this->activate($this->enableQueue);
        $this->enableQueue = [];
        foreach ($this->deferQueue as $watcher) {
            if (!isset($this->deferQueue[$watcher->id])) {
                continue;
                // Watcher disabled by another defer watcher.
            }
            unset($this->watchers[$watcher->id], $this->deferQueue[$watcher->id]);
            try {
                /** @var mixed $result */
                $result = ($watcher->callback)($watcher->id, $watcher->data);
                if ($result === null) {
                    continue;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        }
        /** @psalm-suppress RedundantCondition */
        $this->dispatch(empty($this->nextTickQueue) && empty($this->enableQueue) && $this->running && !$this->isEmpty());
    }
    /**
     * Activates (enables) all the given watchers.
     *
     * @param Watcher[] $watchers
     *
     * @return void
     */
    protected abstract function activate(array $watchers);
    /**
     * Dispatches any pending read/write, timer, and signal events.
     *
     * @param bool $blocking
     *
     * @return void
     */
    protected abstract function dispatch(bool $blocking);
    /**
     * Stop the event loop.
     *
     * When an event loop is stopped, it continues with its current tick and exits the loop afterwards. Multiple calls
     * to stop MUST be ignored and MUST NOT raise an exception.
     *
     * @return void
     */
    public function stop()
    {
        $this->running = \false;
    }
    /**
     * Defer the execution of a callback.
     *
     * The deferred callable MUST be executed before any other type of watcher in a tick. Order of enabling MUST be
     * preserved when executing the callbacks.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param callable (string $watcherId, mixed $data) $callback The callback to defer. The `$watcherId` will be
     *     invalidated before the callback call.
     * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public function defer(callable $callback, $data = null) : string
    {
        /** @psalm-var Watcher<null> $watcher */
        $watcher = new Watcher();
        $watcher->type = Watcher::DEFER;
        $watcher->id = $this->nextId++;
        $watcher->callback = $callback;
        $watcher->data = $data;
        $this->watchers[$watcher->id] = $watcher;
        $this->nextTickQueue[$watcher->id] = $watcher;
        return $watcher->id;
    }
    /**
     * Delay the execution of a callback.
     *
     * The delay is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be determined by which
     * timers expire first, but timers with the same expiration time MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param int   $delay The amount of time, in milliseconds, to delay the execution for.
     * @param callable (string $watcherId, mixed $data) $callback The callback to delay. The `$watcherId` will be
     *     invalidated before the callback call.
     * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public function delay(int $delay, callable $callback, $data = null) : string
    {
        if ($delay < 0) {
            throw new \Error("Delay must be greater than or equal to zero");
        }
        /** @psalm-var Watcher<int> $watcher */
        $watcher = new Watcher();
        $watcher->type = Watcher::DELAY;
        $watcher->id = $this->nextId++;
        $watcher->callback = $callback;
        $watcher->value = $delay;
        $watcher->expiration = $this->now() + $delay;
        $watcher->data = $data;
        $this->watchers[$watcher->id] = $watcher;
        $this->enableQueue[$watcher->id] = $watcher;
        return $watcher->id;
    }
    /**
     * Repeatedly execute a callback.
     *
     * The interval between executions is a minimum and approximate, accuracy is not guaranteed. Order of calls MUST be
     * determined by which timers expire first, but timers with the same expiration time MAY be executed in any order.
     * The first execution is scheduled after the first interval period.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param int   $interval The time interval, in milliseconds, to wait between executions.
     * @param callable (string $watcherId, mixed $data) $callback The callback to repeat.
     * @param mixed $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public function repeat(int $interval, callable $callback, $data = null) : string
    {
        if ($interval < 0) {
            throw new \Error("Interval must be greater than or equal to zero");
        }
        /** @psalm-var Watcher<int> $watcher */
        $watcher = new Watcher();
        $watcher->type = Watcher::REPEAT;
        $watcher->id = $this->nextId++;
        $watcher->callback = $callback;
        $watcher->value = $interval;
        $watcher->expiration = $this->now() + $interval;
        $watcher->data = $data;
        $this->watchers[$watcher->id] = $watcher;
        $this->enableQueue[$watcher->id] = $watcher;
        return $watcher->id;
    }
    /**
     * Execute a callback when a stream resource becomes readable or is closed for reading.
     *
     * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the
     * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid
     * resources, but are not required to, due to the high performance impact. Watchers on closed resources are
     * therefore undefined behavior.
     *
     * Multiple watchers on the same stream MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param resource $stream The stream to monitor.
     * @param callable (string $watcherId, resource $stream, mixed $data) $callback The callback to execute.
     * @param mixed    $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public function onReadable($stream, callable $callback, $data = null) : string
    {
        /** @psalm-var Watcher<resource> $watcher */
        $watcher = new Watcher();
        $watcher->type = Watcher::READABLE;
        $watcher->id = $this->nextId++;
        $watcher->callback = $callback;
        $watcher->value = $stream;
        $watcher->data = $data;
        $this->watchers[$watcher->id] = $watcher;
        $this->enableQueue[$watcher->id] = $watcher;
        return $watcher->id;
    }
    /**
     * Execute a callback when a stream resource becomes writable or is closed for writing.
     *
     * Warning: Closing resources locally, e.g. with `fclose`, might not invoke the callback. Be sure to `cancel` the
     * watcher when closing the resource locally. Drivers MAY choose to notify the user if there are watchers on invalid
     * resources, but are not required to, due to the high performance impact. Watchers on closed resources are
     * therefore undefined behavior.
     *
     * Multiple watchers on the same stream MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param resource $stream The stream to monitor.
     * @param callable (string $watcherId, resource $stream, mixed $data) $callback The callback to execute.
     * @param mixed    $data Arbitrary data given to the callback function as the `$data` parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     */
    public function onWritable($stream, callable $callback, $data = null) : string
    {
        /** @psalm-var Watcher<resource> $watcher */
        $watcher = new Watcher();
        $watcher->type = Watcher::WRITABLE;
        $watcher->id = $this->nextId++;
        $watcher->callback = $callback;
        $watcher->value = $stream;
        $watcher->data = $data;
        $this->watchers[$watcher->id] = $watcher;
        $this->enableQueue[$watcher->id] = $watcher;
        return $watcher->id;
    }
    /**
     * Execute a callback when a signal is received.
     *
     * Warning: Installing the same signal on different instances of this interface is deemed undefined behavior.
     * Implementations MAY try to detect this, if possible, but are not required to. This is due to technical
     * limitations of the signals being registered globally per process.
     *
     * Multiple watchers on the same signal MAY be executed in any order.
     *
     * The created watcher MUST immediately be marked as enabled, but only be activated (i.e. callback can be called)
     * right before the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param int   $signo The signal number to monitor.
     * @param callable (string $watcherId, int $signo, mixed $data) $callback The callback to execute.
     * @param mixed $data Arbitrary data given to the callback function as the $data parameter.
     *
     * @return string An unique identifier that can be used to cancel, enable or disable the watcher.
     *
     * @throws UnsupportedFeatureException If signal handling is not supported.
     */
    public function onSignal(int $signo, callable $callback, $data = null) : string
    {
        /** @psalm-var Watcher<int> $watcher */
        $watcher = new Watcher();
        $watcher->type = Watcher::SIGNAL;
        $watcher->id = $this->nextId++;
        $watcher->callback = $callback;
        $watcher->value = $signo;
        $watcher->data = $data;
        $this->watchers[$watcher->id] = $watcher;
        $this->enableQueue[$watcher->id] = $watcher;
        return $watcher->id;
    }
    /**
     * Enable a watcher to be active starting in the next tick.
     *
     * Watchers MUST immediately be marked as enabled, but only be activated (i.e. callbacks can be called) right before
     * the next tick. Callbacks of watchers MUST NOT be called in the tick they were enabled.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     *
     * @throws InvalidWatcherError If the watcher identifier is invalid.
     */
    public function enable(string $watcherId)
    {
        if (!isset($this->watchers[$watcherId])) {
            throw new InvalidWatcherError($watcherId, "Cannot enable an invalid watcher identifier: '{$watcherId}'");
        }
        $watcher = $this->watchers[$watcherId];
        if ($watcher->enabled) {
            return;
            // Watcher already enabled.
        }
        $watcher->enabled = \true;
        switch ($watcher->type) {
            case Watcher::DEFER:
                $this->nextTickQueue[$watcher->id] = $watcher;
                break;
            case Watcher::REPEAT:
            case Watcher::DELAY:
                \assert(\is_int($watcher->value));
                $watcher->expiration = $this->now() + $watcher->value;
                $this->enableQueue[$watcher->id] = $watcher;
                break;
            default:
                $this->enableQueue[$watcher->id] = $watcher;
                break;
        }
    }
    /**
     * Cancel a watcher.
     *
     * This will detach the event loop from all resources that are associated to the watcher. After this operation the
     * watcher is permanently invalid. Calling this function MUST NOT fail, even if passed an invalid watcher.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     */
    public function cancel(string $watcherId)
    {
        $this->disable($watcherId);
        unset($this->watchers[$watcherId]);
    }
    /**
     * Disable a watcher immediately.
     *
     * A watcher MUST be disabled immediately, e.g. if a defer watcher disables a later defer watcher, the second defer
     * watcher isn't executed in this tick.
     *
     * Disabling a watcher MUST NOT invalidate the watcher. Calling this function MUST NOT fail, even if passed an
     * invalid watcher.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     */
    public function disable(string $watcherId)
    {
        if (!isset($this->watchers[$watcherId])) {
            return;
        }
        $watcher = $this->watchers[$watcherId];
        if (!$watcher->enabled) {
            return;
            // Watcher already disabled.
        }
        $watcher->enabled = \false;
        $id = $watcher->id;
        switch ($watcher->type) {
            case Watcher::DEFER:
                if (isset($this->nextTickQueue[$id])) {
                    // Watcher was only queued to be enabled.
                    unset($this->nextTickQueue[$id]);
                } else {
                    unset($this->deferQueue[$id]);
                }
                break;
            default:
                if (isset($this->enableQueue[$id])) {
                    // Watcher was only queued to be enabled.
                    unset($this->enableQueue[$id]);
                } else {
                    $this->deactivate($watcher);
                }
                break;
        }
    }
    /**
     * Deactivates (disables) the given watcher.
     *
     * @param Watcher $watcher
     *
     * @return void
     */
    protected abstract function deactivate(Watcher $watcher);
    /**
     * Reference a watcher.
     *
     * This will keep the event loop alive whilst the watcher is still being monitored. Watchers have this state by
     * default.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     *
     * @throws InvalidWatcherError If the watcher identifier is invalid.
     */
    public function reference(string $watcherId)
    {
        if (!isset($this->watchers[$watcherId])) {
            throw new InvalidWatcherError($watcherId, "Cannot reference an invalid watcher identifier: '{$watcherId}'");
        }
        $this->watchers[$watcherId]->referenced = \true;
    }
    /**
     * Unreference a watcher.
     *
     * The event loop should exit the run method when only unreferenced watchers are still being monitored. Watchers
     * are all referenced by default.
     *
     * @param string $watcherId The watcher identifier.
     *
     * @return void
     */
    public function unreference(string $watcherId)
    {
        if (!isset($this->watchers[$watcherId])) {
            return;
        }
        $this->watchers[$watcherId]->referenced = \false;
    }
    /**
     * Stores information in the loop bound registry.
     *
     * Stored information is package private. Packages MUST NOT retrieve the stored state of other packages. Packages
     * MUST use their namespace as prefix for keys. They may do so by using `SomeClass::class` as key.
     *
     * If packages want to expose loop bound state to consumers other than the package, they SHOULD provide a dedicated
     * interface for that purpose instead of sharing the storage key.
     *
     * @param string $key The namespaced storage key.
     * @param mixed  $value The value to be stored.
     *
     * @return void
     */
    public final function setState(string $key, $value)
    {
        if ($value === null) {
            unset($this->registry[$key]);
        } else {
            $this->registry[$key] = $value;
        }
    }
    /**
     * Gets information stored bound to the loop.
     *
     * Stored information is package private. Packages MUST NOT retrieve the stored state of other packages. Packages
     * MUST use their namespace as prefix for keys. They may do so by using `SomeClass::class` as key.
     *
     * If packages want to expose loop bound state to consumers other than the package, they SHOULD provide a dedicated
     * interface for that purpose instead of sharing the storage key.
     *
     * @param string $key The namespaced storage key.
     *
     * @return mixed The previously stored value or `null` if it doesn't exist.
     */
    public final function getState(string $key)
    {
        return isset($this->registry[$key]) ? $this->registry[$key] : null;
    }
    /**
     * Set a callback to be executed when an error occurs.
     *
     * The callback receives the error as the first and only parameter. The return value of the callback gets ignored.
     * If it can't handle the error, it MUST throw the error. Errors thrown by the callback or during its invocation
     * MUST be thrown into the `run` loop and stop the driver.
     *
     * Subsequent calls to this method will overwrite the previous handler.
     *
     * @param callable(\Throwable $error):void|null $callback The callback to execute. `null` will clear the
     *     current handler.
     *
     * @return callable(\Throwable $error):void|null The previous handler, `null` if there was none.
     */
    public function setErrorHandler(callable $callback = null)
    {
        $previous = $this->errorHandler;
        $this->errorHandler = $callback;
        return $previous;
    }
    /**
     * Invokes the error handler with the given exception.
     *
     * @param \Throwable $exception The exception thrown from a watcher callback.
     *
     * @return void
     * @throws \Throwable If no error handler has been set.
     */
    protected function error(\Throwable $exception)
    {
        if ($this->errorHandler === null) {
            throw $exception;
        }
        ($this->errorHandler)($exception);
    }
    /**
     * Returns the current loop time in millisecond increments. Note this value does not necessarily correlate to
     * wall-clock time, rather the value returned is meant to be used in relative comparisons to prior values returned
     * by this method (intervals, expiration calculations, etc.) and is only updated once per loop tick.
     *
     * Extending classes should override this function to return a value cached once per loop tick.
     *
     * @return int
     */
    public function now() : int
    {
        return (int) (\microtime(\true) * self::MILLISEC_PER_SEC);
    }
    /**
     * Get the underlying loop handle.
     *
     * Example: the `uv_loop` resource for `libuv` or the `EvLoop` object for `libev` or `null` for a native driver.
     *
     * Note: This function is *not* exposed in the `Loop` class. Users shall access it directly on the respective loop
     * instance.
     *
     * @return null|object|resource The loop handle the event loop operates on. `null` if there is none.
     */
    public abstract function getHandle();
    /**
     * Returns the same array of data as getInfo().
     *
     * @return array
     */
    public function __debugInfo()
    {
        // @codeCoverageIgnoreStart
        return $this->getInfo();
        // @codeCoverageIgnoreEnd
    }
    /**
     * Retrieve an associative array of information about the event loop driver.
     *
     * The returned array MUST contain the following data describing the driver's currently registered watchers:
     *
     *     [
     *         "defer"            => ["enabled" => int, "disabled" => int],
     *         "delay"            => ["enabled" => int, "disabled" => int],
     *         "repeat"           => ["enabled" => int, "disabled" => int],
     *         "on_readable"      => ["enabled" => int, "disabled" => int],
     *         "on_writable"      => ["enabled" => int, "disabled" => int],
     *         "on_signal"        => ["enabled" => int, "disabled" => int],
     *         "enabled_watchers" => ["referenced" => int, "unreferenced" => int],
     *         "running"          => bool
     *     ];
     *
     * Implementations MAY optionally add more information in the array but at minimum the above `key => value` format
     * MUST always be provided.
     *
     * @return array Statistics about the loop in the described format.
     */
    public function getInfo() : array
    {
        $watchers = ["referenced" => 0, "unreferenced" => 0];
        $defer = $delay = $repeat = $onReadable = $onWritable = $onSignal = ["enabled" => 0, "disabled" => 0];
        foreach ($this->watchers as $watcher) {
            switch ($watcher->type) {
                case Watcher::READABLE:
                    $array =& $onReadable;
                    break;
                case Watcher::WRITABLE:
                    $array =& $onWritable;
                    break;
                case Watcher::SIGNAL:
                    $array =& $onSignal;
                    break;
                case Watcher::DEFER:
                    $array =& $defer;
                    break;
                case Watcher::DELAY:
                    $array =& $delay;
                    break;
                case Watcher::REPEAT:
                    $array =& $repeat;
                    break;
                default:
                    // @codeCoverageIgnoreStart
                    throw new \Error("Unknown watcher type");
            }
            if ($watcher->enabled) {
                ++$array["enabled"];
                if ($watcher->referenced) {
                    ++$watchers["referenced"];
                } else {
                    ++$watchers["unreferenced"];
                }
            } else {
                ++$array["disabled"];
            }
        }
        return ["enabled_watchers" => $watchers, "defer" => $defer, "delay" => $delay, "repeat" => $repeat, "on_readable" => $onReadable, "on_writable" => $onWritable, "on_signal" => $onSignal, "running" => (bool) $this->running];
    }
}
<?php

/** @noinspection PhpComposerExtensionStubsInspection */
namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
use function _HumbugBox1cb33d1f20f1\Amp\Internal\getCurrentTime;
use function _HumbugBox1cb33d1f20f1\Amp\Promise\rethrow;
class EvDriver extends Driver
{
    /** @var \EvSignal[]|null */
    private static $activeSignals;
    public static function isSupported() : bool
    {
        return \extension_loaded("ev");
    }
    /** @var \EvLoop */
    private $handle;
    /** @var \EvWatcher[] */
    private $events = [];
    /** @var callable */
    private $ioCallback;
    /** @var callable */
    private $timerCallback;
    /** @var callable */
    private $signalCallback;
    /** @var \EvSignal[] */
    private $signals = [];
    /** @var int Internal timestamp for now. */
    private $now;
    /** @var int Loop time offset */
    private $nowOffset;
    public function __construct()
    {
        $this->handle = new \EvLoop();
        $this->nowOffset = getCurrentTime();
        $this->now = \random_int(0, $this->nowOffset);
        $this->nowOffset -= $this->now;
        if (self::$activeSignals === null) {
            self::$activeSignals =& $this->signals;
        }
        /**
         * @param \EvIO $event
         *
         * @return void
         */
        $this->ioCallback = function (\EvIO $event) {
            /** @var Watcher $watcher */
            $watcher = $event->data;
            try {
                $result = ($watcher->callback)($watcher->id, $watcher->value, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
        /**
         * @param \EvTimer $event
         *
         * @return void
         */
        $this->timerCallback = function (\EvTimer $event) {
            /** @var Watcher $watcher */
            $watcher = $event->data;
            if ($watcher->type & Watcher::DELAY) {
                $this->cancel($watcher->id);
            } elseif ($watcher->value === 0) {
                // Disable and re-enable so it's not executed repeatedly in the same tick
                // See https://github.com/amphp/amp/issues/131
                $this->disable($watcher->id);
                $this->enable($watcher->id);
            }
            try {
                $result = ($watcher->callback)($watcher->id, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
        /**
         * @param \EvSignal $event
         *
         * @return void
         */
        $this->signalCallback = function (\EvSignal $event) {
            /** @var Watcher $watcher */
            $watcher = $event->data;
            try {
                $result = ($watcher->callback)($watcher->id, $watcher->value, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
    }
    /**
     * {@inheritdoc}
     */
    public function cancel(string $watcherId)
    {
        parent::cancel($watcherId);
        unset($this->events[$watcherId]);
    }
    public function __destruct()
    {
        foreach ($this->events as $event) {
            /** @psalm-suppress all */
            if ($event !== null) {
                // Events may have been nulled in extension depending on destruct order.
                $event->stop();
            }
        }
        // We need to clear all references to events manually, see
        // https://bitbucket.org/osmanov/pecl-ev/issues/31/segfault-in-ev_timer_stop
        $this->events = [];
    }
    /**
     * {@inheritdoc}
     */
    public function run()
    {
        $active = self::$activeSignals;
        \assert($active !== null);
        foreach ($active as $event) {
            $event->stop();
        }
        self::$activeSignals =& $this->signals;
        foreach ($this->signals as $event) {
            $event->start();
        }
        try {
            parent::run();
        } finally {
            foreach ($this->signals as $event) {
                $event->stop();
            }
            self::$activeSignals =& $active;
            foreach ($active as $event) {
                $event->start();
            }
        }
    }
    /**
     * {@inheritdoc}
     */
    public function stop()
    {
        $this->handle->stop();
        parent::stop();
    }
    /**
     * {@inheritdoc}
     */
    public function now() : int
    {
        $this->now = getCurrentTime() - $this->nowOffset;
        return $this->now;
    }
    /**
     * {@inheritdoc}
     */
    public function getHandle() : \EvLoop
    {
        return $this->handle;
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function dispatch(bool $blocking)
    {
        $this->handle->run($blocking ? \Ev::RUN_ONCE : \Ev::RUN_ONCE | \Ev::RUN_NOWAIT);
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function activate(array $watchers)
    {
        $this->handle->nowUpdate();
        $now = $this->now();
        foreach ($watchers as $watcher) {
            if (!isset($this->events[$id = $watcher->id])) {
                switch ($watcher->type) {
                    case Watcher::READABLE:
                        \assert(\is_resource($watcher->value));
                        $this->events[$id] = $this->handle->io($watcher->value, \Ev::READ, $this->ioCallback, $watcher);
                        break;
                    case Watcher::WRITABLE:
                        \assert(\is_resource($watcher->value));
                        $this->events[$id] = $this->handle->io($watcher->value, \Ev::WRITE, $this->ioCallback, $watcher);
                        break;
                    case Watcher::DELAY:
                    case Watcher::REPEAT:
                        \assert(\is_int($watcher->value));
                        $interval = $watcher->value / self::MILLISEC_PER_SEC;
                        $this->events[$id] = $this->handle->timer(\max(0, ($watcher->expiration - $now) / self::MILLISEC_PER_SEC), $watcher->type & Watcher::REPEAT ? $interval : 0, $this->timerCallback, $watcher);
                        break;
                    case Watcher::SIGNAL:
                        \assert(\is_int($watcher->value));
                        $this->events[$id] = $this->handle->signal($watcher->value, $this->signalCallback, $watcher);
                        break;
                    default:
                        // @codeCoverageIgnoreStart
                        throw new \Error("Unknown watcher type");
                }
            } else {
                $this->events[$id]->start();
            }
            if ($watcher->type === Watcher::SIGNAL) {
                /** @psalm-suppress PropertyTypeCoercion */
                $this->signals[$id] = $this->events[$id];
            }
        }
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function deactivate(Watcher $watcher)
    {
        if (isset($this->events[$id = $watcher->id])) {
            $this->events[$id]->stop();
            if ($watcher->type === Watcher::SIGNAL) {
                unset($this->signals[$id]);
            }
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

/**
 * MUST be thrown if any operation (except disable() and cancel()) is attempted with an invalid watcher identifier.
 *
 * An invalid watcher identifier is any identifier that is not yet emitted by the driver or cancelled by the user.
 */
class InvalidWatcherError extends \Error
{
    /** @var string */
    private $watcherId;
    /**
     * @param string $watcherId The watcher identifier.
     * @param string $message The exception message.
     */
    public function __construct(string $watcherId, string $message)
    {
        $this->watcherId = $watcherId;
        parent::__construct($message);
    }
    /**
     * @return string The watcher identifier.
     */
    public function getWatcherId()
    {
        return $this->watcherId;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
use function _HumbugBox1cb33d1f20f1\Amp\Internal\getCurrentTime;
use function _HumbugBox1cb33d1f20f1\Amp\Promise\rethrow;
class EventDriver extends Driver
{
    /** @var \Event[]|null */
    private static $activeSignals;
    /** @var \EventBase */
    private $handle;
    /** @var \Event[] */
    private $events = [];
    /** @var callable */
    private $ioCallback;
    /** @var callable */
    private $timerCallback;
    /** @var callable */
    private $signalCallback;
    /** @var \Event[] */
    private $signals = [];
    /** @var int Internal timestamp for now. */
    private $now;
    /** @var int Loop time offset */
    private $nowOffset;
    public function __construct()
    {
        $config = new \EventConfig();
        if (\DIRECTORY_SEPARATOR !== '\\') {
            $config->requireFeatures(\EventConfig::FEATURE_FDS);
        }
        $this->handle = new \EventBase($config);
        $this->nowOffset = getCurrentTime();
        $this->now = \random_int(0, $this->nowOffset);
        $this->nowOffset -= $this->now;
        if (self::$activeSignals === null) {
            self::$activeSignals =& $this->signals;
        }
        /**
         * @param         $resource
         * @param         $what
         * @param Watcher $watcher
         *
         * @return void
         */
        $this->ioCallback = function ($resource, $what, Watcher $watcher) {
            \assert(\is_resource($watcher->value));
            try {
                $result = ($watcher->callback)($watcher->id, $watcher->value, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
        /**
         * @param         $resource
         * @param         $what
         * @param Watcher $watcher
         *
         * @return void
         */
        $this->timerCallback = function ($resource, $what, Watcher $watcher) {
            \assert(\is_int($watcher->value));
            if ($watcher->type & Watcher::DELAY) {
                $this->cancel($watcher->id);
            } else {
                $this->events[$watcher->id]->add($watcher->value / self::MILLISEC_PER_SEC);
            }
            try {
                $result = ($watcher->callback)($watcher->id, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
        /**
         * @param         $signum
         * @param         $what
         * @param Watcher $watcher
         *
         * @return void
         */
        $this->signalCallback = function ($signum, $what, Watcher $watcher) {
            try {
                $result = ($watcher->callback)($watcher->id, $watcher->value, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
    }
    /**
     * {@inheritdoc}
     */
    public function cancel(string $watcherId)
    {
        parent::cancel($watcherId);
        if (isset($this->events[$watcherId])) {
            $this->events[$watcherId]->free();
            unset($this->events[$watcherId]);
        }
    }
    public static function isSupported() : bool
    {
        return \extension_loaded("event");
    }
    /**
     * @codeCoverageIgnore
     */
    public function __destruct()
    {
        // Unset here, otherwise $event->del() in the loop may fail with a warning, because __destruct order isn't defined.
        // Related https://github.com/amphp/amp/issues/159.
        $events = $this->events;
        $this->events = [];
        foreach ($events as $event) {
            if ($event !== null) {
                // Events may have been nulled in extension depending on destruct order.
                $event->free();
            }
        }
        // Manually free the loop handle to fully release loop resources.
        // See https://github.com/amphp/amp/issues/177.
        if ($this->handle !== null) {
            $this->handle->free();
            $this->handle = null;
        }
    }
    /**
     * {@inheritdoc}
     */
    public function run()
    {
        $active = self::$activeSignals;
        \assert($active !== null);
        foreach ($active as $event) {
            $event->del();
        }
        self::$activeSignals =& $this->signals;
        foreach ($this->signals as $event) {
            /** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
            $event->add();
        }
        try {
            parent::run();
        } finally {
            foreach ($this->signals as $event) {
                $event->del();
            }
            self::$activeSignals =& $active;
            foreach ($active as $event) {
                /** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
                $event->add();
            }
        }
    }
    /**
     * {@inheritdoc}
     */
    public function stop()
    {
        $this->handle->stop();
        parent::stop();
    }
    /**
     * {@inheritdoc}
     */
    public function now() : int
    {
        $this->now = getCurrentTime() - $this->nowOffset;
        return $this->now;
    }
    /**
     * {@inheritdoc}
     */
    public function getHandle() : \EventBase
    {
        return $this->handle;
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function dispatch(bool $blocking)
    {
        $this->handle->loop($blocking ? \EventBase::LOOP_ONCE : \EventBase::LOOP_ONCE | \EventBase::LOOP_NONBLOCK);
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function activate(array $watchers)
    {
        $now = $this->now();
        foreach ($watchers as $watcher) {
            if (!isset($this->events[$id = $watcher->id])) {
                switch ($watcher->type) {
                    case Watcher::READABLE:
                        \assert(\is_resource($watcher->value));
                        $this->events[$id] = new \Event($this->handle, $watcher->value, \Event::READ | \Event::PERSIST, $this->ioCallback, $watcher);
                        break;
                    case Watcher::WRITABLE:
                        \assert(\is_resource($watcher->value));
                        $this->events[$id] = new \Event($this->handle, $watcher->value, \Event::WRITE | \Event::PERSIST, $this->ioCallback, $watcher);
                        break;
                    case Watcher::DELAY:
                    case Watcher::REPEAT:
                        \assert(\is_int($watcher->value));
                        $this->events[$id] = new \Event($this->handle, -1, \Event::TIMEOUT, $this->timerCallback, $watcher);
                        break;
                    case Watcher::SIGNAL:
                        \assert(\is_int($watcher->value));
                        $this->events[$id] = new \Event($this->handle, $watcher->value, \Event::SIGNAL | \Event::PERSIST, $this->signalCallback, $watcher);
                        break;
                    default:
                        // @codeCoverageIgnoreStart
                        throw new \Error("Unknown watcher type");
                }
            }
            switch ($watcher->type) {
                case Watcher::DELAY:
                case Watcher::REPEAT:
                    \assert(\is_int($watcher->value));
                    $interval = \max(0, $watcher->expiration - $now);
                    $this->events[$id]->add($interval > 0 ? $interval / self::MILLISEC_PER_SEC : 0);
                    break;
                case Watcher::SIGNAL:
                    $this->signals[$id] = $this->events[$id];
                // no break
                default:
                    /** @psalm-suppress TooFewArguments https://github.com/JetBrains/phpstorm-stubs/pull/763 */
                    $this->events[$id]->add();
                    break;
            }
        }
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function deactivate(Watcher $watcher)
    {
        if (isset($this->events[$id = $watcher->id])) {
            $this->events[$id]->del();
            if ($watcher->type === Watcher::SIGNAL) {
                unset($this->signals[$id]);
            }
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

// @codeCoverageIgnoreStart
class DriverFactory
{
    /**
     * Creates a new loop instance and chooses the best available driver.
     *
     * @return Driver
     *
     * @throws \Error If an invalid class has been specified via AMP_LOOP_DRIVER
     */
    public function create() : Driver
    {
        $driver = (function () {
            if ($driver = $this->createDriverFromEnv()) {
                return $driver;
            }
            if (UvDriver::isSupported()) {
                return new UvDriver();
            }
            if (EvDriver::isSupported()) {
                return new EvDriver();
            }
            if (EventDriver::isSupported()) {
                return new EventDriver();
            }
            return new NativeDriver();
        })();
        if (\getenv("AMP_DEBUG_TRACE_WATCHERS")) {
            return new TracingDriver($driver);
        }
        return $driver;
    }
    /**
     * @return Driver|null
     */
    private function createDriverFromEnv()
    {
        $driver = \getenv("AMP_LOOP_DRIVER");
        if (!$driver) {
            return null;
        }
        if (!\class_exists($driver)) {
            throw new \Error(\sprintf("Driver '%s' does not exist.", $driver));
        }
        if (!\is_subclass_of($driver, Driver::class)) {
            throw new \Error(\sprintf("Driver '%s' is not a subclass of '%s'.", $driver, Driver::class));
        }
        return new $driver();
    }
}
// @codeCoverageIgnoreEnd
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

use _HumbugBox1cb33d1f20f1\Amp\Struct;
/**
 * @template TValue as (int|resource|null)
 *
 * @psalm-suppress MissingConstructor
 */
class Watcher
{
    use Struct;
    const IO = 0b11;
    const READABLE = 0b1;
    const WRITABLE = 0b10;
    const DEFER = 0b100;
    const TIMER = 0b11000;
    const DELAY = 0b1000;
    const REPEAT = 0b10000;
    const SIGNAL = 0b100000;
    /** @var int */
    public $type;
    /** @var bool */
    public $enabled = \true;
    /** @var bool */
    public $referenced = \true;
    /** @var string */
    public $id;
    /** @var callable */
    public $callback;
    /**
     * Data provided to the watcher callback.
     *
     * @var mixed
     */
    public $data;
    /**
     * Watcher-dependent value storage. Stream for IO watchers, signal number for signal watchers, interval for timers.
     *
     * @var resource|int|null
     * @psalm-var TValue
     */
    public $value;
    /** @var int|null */
    public $expiration;
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\React\Promise\PromiseInterface as ReactPromise;
use function _HumbugBox1cb33d1f20f1\Amp\Promise\rethrow;
class UvDriver extends Driver
{
    /** @var resource A uv_loop resource created with uv_loop_new() */
    private $handle;
    /** @var resource[] */
    private $events = [];
    /** @var Watcher[][] */
    private $watchers = [];
    /** @var resource[] */
    private $streams = [];
    /** @var callable */
    private $ioCallback;
    /** @var callable */
    private $timerCallback;
    /** @var callable */
    private $signalCallback;
    public function __construct()
    {
        $this->handle = \uv_loop_new();
        /**
         * @param $event
         * @param $status
         * @param $events
         * @param $resource
         *
         * @return void
         */
        $this->ioCallback = function ($event, $status, $events, $resource) {
            $watchers = $this->watchers[(int) $event];
            switch ($status) {
                case 0:
                    // OK
                    break;
                default:
                    // Invoke the callback on errors, as this matches behavior with other loop back-ends.
                    // Re-enable watcher as libuv disables the watcher on non-zero status.
                    $flags = 0;
                    foreach ($watchers as $watcher) {
                        $flags |= $watcher->enabled ? $watcher->type : 0;
                    }
                    \uv_poll_start($event, $flags, $this->ioCallback);
                    break;
            }
            foreach ($watchers as $watcher) {
                // $events is OR'ed with 4 to trigger watcher if no events are indicated (0) or on UV_DISCONNECT (4).
                // http://docs.libuv.org/en/v1.x/poll.html
                if (!($watcher->enabled && ($watcher->type & $events || ($events | 4) === 4))) {
                    continue;
                }
                try {
                    $result = ($watcher->callback)($watcher->id, $resource, $watcher->data);
                    if ($result === null) {
                        continue;
                    }
                    if ($result instanceof \Generator) {
                        $result = new Coroutine($result);
                    }
                    if ($result instanceof Promise || $result instanceof ReactPromise) {
                        rethrow($result);
                    }
                } catch (\Throwable $exception) {
                    $this->error($exception);
                }
            }
        };
        /**
         * @param $event
         *
         * @return void
         */
        $this->timerCallback = function ($event) {
            $watcher = $this->watchers[(int) $event][0];
            if ($watcher->type & Watcher::DELAY) {
                unset($this->events[$watcher->id], $this->watchers[(int) $event]);
                // Avoid call to uv_is_active().
                $this->cancel($watcher->id);
                // Remove reference to watcher in parent.
            } elseif ($watcher->value === 0) {
                // Disable and re-enable so it's not executed repeatedly in the same tick
                // See https://github.com/amphp/amp/issues/131
                $this->disable($watcher->id);
                $this->enable($watcher->id);
            }
            try {
                $result = ($watcher->callback)($watcher->id, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
        /**
         * @param $event
         * @param $signo
         *
         * @return void
         */
        $this->signalCallback = function ($event, $signo) {
            $watcher = $this->watchers[(int) $event][0];
            try {
                $result = ($watcher->callback)($watcher->id, $signo, $watcher->data);
                if ($result === null) {
                    return;
                }
                if ($result instanceof \Generator) {
                    $result = new Coroutine($result);
                }
                if ($result instanceof Promise || $result instanceof ReactPromise) {
                    rethrow($result);
                }
            } catch (\Throwable $exception) {
                $this->error($exception);
            }
        };
    }
    /**
     * {@inheritdoc}
     */
    public function cancel(string $watcherId)
    {
        parent::cancel($watcherId);
        if (!isset($this->events[$watcherId])) {
            return;
        }
        $event = $this->events[$watcherId];
        $eventId = (int) $event;
        if (isset($this->watchers[$eventId][0])) {
            // All except IO watchers.
            unset($this->watchers[$eventId]);
        } elseif (isset($this->watchers[$eventId][$watcherId])) {
            $watcher = $this->watchers[$eventId][$watcherId];
            unset($this->watchers[$eventId][$watcherId]);
            if (empty($this->watchers[$eventId])) {
                unset($this->watchers[$eventId], $this->streams[(int) $watcher->value]);
            }
        }
        unset($this->events[$watcherId]);
    }
    public static function isSupported() : bool
    {
        return \extension_loaded("uv");
    }
    /**
     * {@inheritdoc}
     */
    public function now() : int
    {
        \uv_update_time($this->handle);
        /** @psalm-suppress TooManyArguments */
        return \uv_now($this->handle);
    }
    /**
     * {@inheritdoc}
     */
    public function getHandle()
    {
        return $this->handle;
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function dispatch(bool $blocking)
    {
        /** @psalm-suppress TooManyArguments */
        \uv_run($this->handle, $blocking ? \UV::RUN_ONCE : \UV::RUN_NOWAIT);
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function activate(array $watchers)
    {
        $now = $this->now();
        foreach ($watchers as $watcher) {
            $id = $watcher->id;
            switch ($watcher->type) {
                case Watcher::READABLE:
                case Watcher::WRITABLE:
                    \assert(\is_resource($watcher->value));
                    $streamId = (int) $watcher->value;
                    if (isset($this->streams[$streamId])) {
                        $event = $this->streams[$streamId];
                    } elseif (isset($this->events[$id])) {
                        $event = $this->streams[$streamId] = $this->events[$id];
                    } else {
                        /** @psalm-suppress UndefinedFunction */
                        $event = $this->streams[$streamId] = \_HumbugBox1cb33d1f20f1\uv_poll_init_socket($this->handle, $watcher->value);
                    }
                    $eventId = (int) $event;
                    $this->events[$id] = $event;
                    $this->watchers[$eventId][$id] = $watcher;
                    $flags = 0;
                    foreach ($this->watchers[$eventId] as $w) {
                        $flags |= $w->enabled ? $w->type : 0;
                    }
                    \uv_poll_start($event, $flags, $this->ioCallback);
                    break;
                case Watcher::DELAY:
                case Watcher::REPEAT:
                    \assert(\is_int($watcher->value));
                    if (isset($this->events[$id])) {
                        $event = $this->events[$id];
                    } else {
                        $event = $this->events[$id] = \uv_timer_init($this->handle);
                    }
                    $this->watchers[(int) $event] = [$watcher];
                    \uv_timer_start($event, \max(0, $watcher->expiration - $now), $watcher->type & Watcher::REPEAT ? $watcher->value : 0, $this->timerCallback);
                    break;
                case Watcher::SIGNAL:
                    \assert(\is_int($watcher->value));
                    if (isset($this->events[$id])) {
                        $event = $this->events[$id];
                    } else {
                        /** @psalm-suppress UndefinedFunction */
                        $event = $this->events[$id] = \_HumbugBox1cb33d1f20f1\uv_signal_init($this->handle);
                    }
                    $this->watchers[(int) $event] = [$watcher];
                    /** @psalm-suppress UndefinedFunction */
                    \_HumbugBox1cb33d1f20f1\uv_signal_start($event, $this->signalCallback, $watcher->value);
                    break;
                default:
                    // @codeCoverageIgnoreStart
                    throw new \Error("Unknown watcher type");
            }
        }
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    protected function deactivate(Watcher $watcher)
    {
        $id = $watcher->id;
        if (!isset($this->events[$id])) {
            return;
        }
        $event = $this->events[$id];
        if (!\uv_is_active($event)) {
            return;
        }
        switch ($watcher->type) {
            case Watcher::READABLE:
            case Watcher::WRITABLE:
                $flags = 0;
                foreach ($this->watchers[(int) $event] as $w) {
                    $flags |= $w->enabled ? $w->type : 0;
                }
                if ($flags) {
                    \uv_poll_start($event, $flags, $this->ioCallback);
                } else {
                    \uv_poll_stop($event);
                }
                break;
            case Watcher::DELAY:
            case Watcher::REPEAT:
                \uv_timer_stop($event);
                break;
            case Watcher::SIGNAL:
                \uv_signal_stop($event);
                break;
            default:
                // @codeCoverageIgnoreStart
                throw new \Error("Unknown watcher type");
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\Loop;

/**
 * MUST be thrown if a feature is not supported by the system.
 *
 * This might happen if ext-pcntl is missing and the loop driver doesn't support another way to dispatch signals.
 */
class UnsupportedFeatureException extends \Exception
{
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Cancellation tokens are simple objects that allow registering handlers to subscribe to cancellation requests.
 */
interface CancellationToken
{
    /**
     * Subscribes a new handler to be invoked on a cancellation request.
     *
     * This handler might be invoked immediately in case the token has already been cancelled. Returned generators will
     * automatically be run as coroutines. Any unhandled exceptions will be throw into the event loop.
     *
     * @param callable(CancelledException) $callback Callback to be invoked on a cancellation request. Will receive a
     * `CancelledException` as first argument that may be used to fail the operation's promise.
     *
     * @return string Identifier that can be used to cancel the subscription.
     */
    public function subscribe(callable $callback) : string;
    /**
     * Unsubscribes a previously registered handler.
     *
     * The handler will no longer be called as long as this method isn't invoked from a subscribed callback.
     *
     * @param string $id
     *
     * @return void
     */
    public function unsubscribe(string $id);
    /**
     * Returns whether cancellation has been requested yet.
     *
     * @return bool
     */
    public function isRequested() : bool;
    /**
     * Throws the `CancelledException` if cancellation has been requested, otherwise does nothing.
     *
     * @return void
     *
     * @throws CancelledException
     */
    public function throwIfRequested();
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

class InvalidYieldError extends \Error
{
    /**
     * @param \Generator      $generator
     * @param string          $prefix
     * @param \Throwable|null $previous
     */
    public function __construct(\Generator $generator, string $prefix, \Throwable $previous = null)
    {
        $yielded = $generator->current();
        $prefix .= \sprintf("; %s yielded at key %s", \is_object($yielded) ? \get_class($yielded) : \gettype($yielded), \var_export($generator->key(), \true));
        if (!$generator->valid()) {
            parent::__construct($prefix, 0, $previous);
            return;
        }
        $reflGen = new \ReflectionGenerator($generator);
        $exeGen = $reflGen->getExecutingGenerator();
        if ($isSubgenerator = $exeGen !== $generator) {
            $reflGen = new \ReflectionGenerator($exeGen);
        }
        parent::__construct(\sprintf("%s on line %s in %s", $prefix, $reflGen->getExecutingLine(), $reflGen->getExecutingFile()), 0, $previous);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Creates a promise that resolves itself with a given value after a number of milliseconds.
 *
 * @template-covariant TReturn
 * @template-implements Promise<TReturn>
 */
final class Delayed implements Promise
{
    use Internal\Placeholder;
    /** @var string|null Event loop watcher identifier. */
    private $watcher;
    /**
     * @param int     $time Milliseconds before succeeding the promise.
     * @param TReturn $value Succeed the promise with this value.
     */
    public function __construct(int $time, $value = null)
    {
        $this->watcher = Loop::delay($time, function () use($value) {
            $this->watcher = null;
            $this->resolve($value);
        });
    }
    /**
     * References the internal watcher in the event loop, keeping the loop running while this promise is pending.
     *
     * @return self
     */
    public function reference() : self
    {
        if ($this->watcher !== null) {
            Loop::reference($this->watcher);
        }
        return $this;
    }
    /**
     * Unreferences the internal watcher in the event loop, allowing the loop to stop while this promise is pending if
     * no other events are pending in the loop.
     *
     * @return self
     */
    public function unreference() : self
    {
        if ($this->watcher !== null) {
            Loop::unreference($this->watcher);
        }
        return $this;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp;

/**
 * Representation of the future value of an asynchronous operation.
 *
 * @template-covariant TValue
 * @psalm-yield TValue
 */
interface Promise
{
    /**
     * Registers a callback to be invoked when the promise is resolved.
     *
     * If this method is called multiple times, additional handlers will be registered instead of replacing any already
     * existing handlers.
     *
     * If the promise is already resolved, the callback MUST be executed immediately.
     *
     * Exceptions MUST NOT be thrown from this method. Any exceptions thrown from invoked callbacks MUST be
     * forwarded to the event-loop error handler.
     *
     * Note: You shouldn't implement this interface yourself. Instead, provide a method that returns a promise for the
     * operation you're implementing. Objects other than pure placeholders implementing it are a very bad idea.
     *
     * @param callable $onResolved The first argument shall be `null` on success, while the second shall be `null` on
     *     failure.
     *
     * @psalm-param callable(\Throwable|null, mixed): (Promise|\React\Promise\PromiseInterface|\Generator<mixed,
     *     Promise|\React\Promise\PromiseInterface|array<array-key, Promise|\React\Promise\PromiseInterface>, mixed,
     *     mixed>|null) | callable(\Throwable|null, mixed): void $onResolved
     *
     * @return void
     */
    public function onResolve(callable $onResolved);
}

The MIT License (MIT)

Copyright (c) 2015-2019 amphp
Copyright (c) 2016 PHP Asynchronous Interoperability Group

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Loop;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
/**
 * Input stream abstraction for PHP's stream resources.
 */
final class ResourceInputStream implements InputStream
{
    const DEFAULT_CHUNK_SIZE = 8192;
    /** @var resource|null */
    private $resource;
    /** @var string */
    private $watcher;
    /** @var Deferred|null */
    private $deferred;
    /** @var bool */
    private $readable = \true;
    /** @var int */
    private $chunkSize;
    /** @var bool */
    private $useSingleRead;
    /** @var callable */
    private $immediateCallable;
    /** @var string|null */
    private $immediateWatcher;
    /**
     * @param resource $stream Stream resource.
     * @param int      $chunkSize Chunk size per read operation.
     *
     * @throws \Error If an invalid stream or parameter has been passed.
     */
    public function __construct($stream, int $chunkSize = self::DEFAULT_CHUNK_SIZE)
    {
        if (!\is_resource($stream) || \get_resource_type($stream) !== 'stream') {
            throw new \Error("Expected a valid stream");
        }
        $meta = \stream_get_meta_data($stream);
        $useSingleRead = $meta["stream_type"] === "udp_socket" || $meta["stream_type"] === "STDIO";
        $this->useSingleRead = $useSingleRead;
        if (\strpos($meta["mode"], "r") === \false && \strpos($meta["mode"], "+") === \false) {
            throw new \Error("Expected a readable stream");
        }
        \stream_set_blocking($stream, \false);
        \stream_set_read_buffer($stream, 0);
        $this->resource =& $stream;
        $this->chunkSize =& $chunkSize;
        $deferred =& $this->deferred;
        $readable =& $this->readable;
        $this->watcher = Loop::onReadable($this->resource, static function ($watcher) use(&$deferred, &$readable, &$stream, &$chunkSize, $useSingleRead) {
            if ($useSingleRead) {
                $data = @\fread($stream, $chunkSize);
            } else {
                $data = @\stream_get_contents($stream, $chunkSize);
            }
            \assert($data !== \false, "Trying to read from a previously fclose()'d resource. Do NOT manually fclose() resources the loop still has a reference to.");
            // Error suppression, because pthreads does crazy things with resources,
            // which might be closed during two operations.
            // See https://github.com/amphp/byte-stream/issues/32
            if ($data === '' && @\feof($stream)) {
                $readable = \false;
                $stream = null;
                $data = null;
                // Stream closed, resolve read with null.
                Loop::cancel($watcher);
            } else {
                Loop::disable($watcher);
            }
            $temp = $deferred;
            $deferred = null;
            \assert($temp instanceof Deferred);
            $temp->resolve($data);
        });
        $this->immediateCallable = static function ($watcherId, $data) use(&$deferred) {
            $temp = $deferred;
            $deferred = null;
            \assert($temp instanceof Deferred);
            $temp->resolve($data);
        };
        Loop::disable($this->watcher);
    }
    /** @inheritdoc */
    public function read() : Promise
    {
        if ($this->deferred !== null) {
            throw new PendingReadError();
        }
        if (!$this->readable) {
            return new Success();
            // Resolve with null on closed stream.
        }
        \assert($this->resource !== null);
        // Attempt a direct read, because Windows suffers from slow I/O on STDIN otherwise.
        if ($this->useSingleRead) {
            $data = @\fread($this->resource, $this->chunkSize);
        } else {
            $data = @\stream_get_contents($this->resource, $this->chunkSize);
        }
        \assert($data !== \false, "Trying to read from a previously fclose()'d resource. Do NOT manually fclose() resources the loop still has a reference to.");
        if ($data === '') {
            // Error suppression, because pthreads does crazy things with resources,
            // which might be closed during two operations.
            // See https://github.com/amphp/byte-stream/issues/32
            if (@\feof($this->resource)) {
                $this->readable = \false;
                $this->resource = null;
                Loop::cancel($this->watcher);
                return new Success();
                // Stream closed, resolve read with null.
            }
            $this->deferred = new Deferred();
            Loop::enable($this->watcher);
            return $this->deferred->promise();
        }
        // Prevent an immediate read → write loop from blocking everything
        // See e.g. examples/benchmark-throughput.php
        $this->deferred = new Deferred();
        $this->immediateWatcher = Loop::defer($this->immediateCallable, $data);
        return $this->deferred->promise();
    }
    /**
     * Closes the stream forcefully. Multiple `close()` calls are ignored.
     *
     * @return void
     */
    public function close()
    {
        if (\is_resource($this->resource)) {
            // Error suppression, as resource might already be closed
            $meta = @\stream_get_meta_data($this->resource);
            if ($meta && \strpos($meta["mode"], "+") !== \false) {
                @\stream_socket_shutdown($this->resource, \STREAM_SHUT_RD);
            } else {
                /** @psalm-suppress InvalidPropertyAssignmentValue */
                @\fclose($this->resource);
            }
        }
        $this->free();
    }
    /**
     * Nulls reference to resource, marks stream unreadable, and succeeds any pending read with null.
     *
     * @return void
     */
    private function free()
    {
        $this->readable = \false;
        $this->resource = null;
        if ($this->deferred !== null) {
            $deferred = $this->deferred;
            $this->deferred = null;
            $deferred->resolve();
        }
        Loop::cancel($this->watcher);
        if ($this->immediateWatcher !== null) {
            Loop::cancel($this->immediateWatcher);
        }
    }
    /**
     * @return resource|null The stream resource or null if the stream has closed.
     */
    public function getResource()
    {
        return $this->resource;
    }
    /**
     * @return void
     */
    public function setChunkSize(int $chunkSize)
    {
        $this->chunkSize = $chunkSize;
    }
    /**
     * References the read watcher, so the loop keeps running in case there's an active read.
     *
     * @return void
     *
     * @see Loop::reference()
     */
    public function reference()
    {
        if (!$this->resource) {
            throw new \Error("Resource has already been freed");
        }
        Loop::reference($this->watcher);
    }
    /**
     * Unreferences the read watcher, so the loop doesn't keep running even if there are active reads.
     *
     * @return void
     *
     * @see Loop::unreference()
     */
    public function unreference()
    {
        if (!$this->resource) {
            throw new \Error("Resource has already been freed");
        }
        Loop::unreference($this->watcher);
    }
    public function __destruct()
    {
        if ($this->resource !== null) {
            $this->free();
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

/**
 * Thrown in case a second read operation is attempted while another read operation is still pending.
 */
final class PendingReadError extends \Error
{
    public function __construct(string $message = "The previous read operation must complete before read can be called again", int $code = 0, \Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream\Base64;

use _HumbugBox1cb33d1f20f1\Amp\ByteStream\OutputStream;
use _HumbugBox1cb33d1f20f1\Amp\ByteStream\StreamException;
use _HumbugBox1cb33d1f20f1\Amp\Failure;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
final class Base64DecodingOutputStream implements OutputStream
{
    /** @var OutputStream */
    private $destination;
    /** @var string */
    private $buffer = '';
    /** @var int */
    private $offset = 0;
    public function __construct(OutputStream $destination)
    {
        $this->destination = $destination;
    }
    public function write(string $data) : Promise
    {
        $this->buffer .= $data;
        $length = \strlen($this->buffer);
        $chunk = \base64_decode(\substr($this->buffer, 0, $length - $length % 4), \true);
        if ($chunk === \false) {
            return new Failure(new StreamException('Invalid base64 near offset ' . $this->offset));
        }
        $this->offset += $length - $length % 4;
        $this->buffer = \substr($this->buffer, $length - $length % 4);
        return $this->destination->write($chunk);
    }
    public function end(string $finalData = "") : Promise
    {
        $this->offset += \strlen($this->buffer);
        $chunk = \base64_decode($this->buffer . $finalData, \true);
        if ($chunk === \false) {
            return new Failure(new StreamException('Invalid base64 near offset ' . $this->offset));
        }
        $this->buffer = '';
        return $this->destination->end($chunk);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream\Base64;

use _HumbugBox1cb33d1f20f1\Amp\ByteStream\InputStream;
use _HumbugBox1cb33d1f20f1\Amp\ByteStream\StreamException;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
final class Base64DecodingInputStream implements InputStream
{
    /** @var InputStream|null */
    private $source;
    /** @var string|null */
    private $buffer = '';
    public function __construct(InputStream $source)
    {
        $this->source = $source;
    }
    public function read() : Promise
    {
        return call(function () {
            if ($this->source === null) {
                throw new StreamException('Failed to read stream chunk due to invalid base64 data');
            }
            $chunk = (yield $this->source->read());
            if ($chunk === null) {
                if ($this->buffer === null) {
                    return null;
                }
                $chunk = \base64_decode($this->buffer, \true);
                if ($chunk === \false) {
                    $this->source = null;
                    $this->buffer = null;
                    throw new StreamException('Failed to read stream chunk due to invalid base64 data');
                }
                $this->buffer = null;
                return $chunk;
            }
            $this->buffer .= $chunk;
            $length = \strlen($this->buffer);
            $chunk = \base64_decode(\substr($this->buffer, 0, $length - $length % 4), \true);
            if ($chunk === \false) {
                $this->source = null;
                $this->buffer = null;
                throw new StreamException('Failed to read stream chunk due to invalid base64 data');
            }
            $this->buffer = \substr($this->buffer, $length - $length % 4);
            return $chunk;
        });
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream\Base64;

use _HumbugBox1cb33d1f20f1\Amp\ByteStream\InputStream;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
final class Base64EncodingInputStream implements InputStream
{
    /** @var InputStream */
    private $source;
    /** @var string|null */
    private $buffer = '';
    public function __construct(InputStream $source)
    {
        $this->source = $source;
    }
    public function read() : Promise
    {
        return call(function () {
            $chunk = (yield $this->source->read());
            if ($chunk === null) {
                if ($this->buffer === null) {
                    return null;
                }
                $chunk = \base64_encode($this->buffer);
                $this->buffer = null;
                return $chunk;
            }
            $this->buffer .= $chunk;
            $length = \strlen($this->buffer);
            $chunk = \base64_encode(\substr($this->buffer, 0, $length - $length % 3));
            $this->buffer = \substr($this->buffer, $length - $length % 3);
            return $chunk;
        });
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream\Base64;

use _HumbugBox1cb33d1f20f1\Amp\ByteStream\OutputStream;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
final class Base64EncodingOutputStream implements OutputStream
{
    /** @var OutputStream */
    private $destination;
    /** @var string */
    private $buffer = '';
    public function __construct(OutputStream $destination)
    {
        $this->destination = $destination;
    }
    public function write(string $data) : Promise
    {
        $this->buffer .= $data;
        $length = \strlen($this->buffer);
        $chunk = \base64_encode(\substr($this->buffer, 0, $length - $length % 3));
        $this->buffer = \substr($this->buffer, $length - $length % 3);
        return $this->destination->write($chunk);
    }
    public function end(string $finalData = "") : Promise
    {
        $chunk = \base64_encode($this->buffer . $finalData);
        $this->buffer = '';
        return $this->destination->end($chunk);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

class StreamException extends \Exception
{
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
/**
 * Creates a buffered message from an InputStream. The message can be consumed in chunks using the read() API or it may
 * be buffered and accessed in its entirety by calling buffer(). Once buffering is requested through buffer(), the
 * stream cannot be read in chunks. On destruct any remaining data is read from the InputStream given to this class.
 */
class Payload implements InputStream
{
    /** @var InputStream */
    private $stream;
    /** @var \Amp\Promise|null */
    private $promise;
    /** @var \Amp\Promise|null */
    private $lastRead;
    /**
     * @param \Amp\ByteStream\InputStream $stream
     */
    public function __construct(InputStream $stream)
    {
        $this->stream = $stream;
    }
    public function __destruct()
    {
        if (!$this->promise) {
            Promise\rethrow(new Coroutine($this->consume()));
        }
    }
    private function consume() : \Generator
    {
        try {
            if ($this->lastRead && null === (yield $this->lastRead)) {
                return;
            }
            while (null !== (yield $this->stream->read())) {
                // Discard unread bytes from message.
            }
        } catch (\Throwable $exception) {
            // If exception is thrown here the connection closed anyway.
        }
    }
    /**
     * @inheritdoc
     *
     * @throws \Error If a buffered message was requested by calling buffer().
     */
    public final function read() : Promise
    {
        if ($this->promise) {
            throw new \Error("Cannot stream message data once a buffered message has been requested");
        }
        return $this->lastRead = $this->stream->read();
    }
    /**
     * Buffers the entire message and resolves the returned promise then.
     *
     * @return Promise<string> Resolves with the entire message contents.
     */
    public final function buffer() : Promise
    {
        if ($this->promise) {
            return $this->promise;
        }
        return $this->promise = call(function () {
            $buffer = '';
            if ($this->lastRead && null === (yield $this->lastRead)) {
                return $buffer;
            }
            while (null !== ($chunk = (yield $this->stream->read()))) {
                $buffer .= $chunk;
            }
            return $buffer;
        });
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
/**
 * Allows compression of output streams using Zlib.
 */
final class ZlibOutputStream implements OutputStream
{
    /** @var OutputStream|null */
    private $destination;
    /** @var int */
    private $encoding;
    /** @var array */
    private $options;
    /** @var resource|null */
    private $resource;
    /**
     * @param OutputStream $destination Output stream to write the compressed data to.
     * @param int          $encoding Compression encoding to use, see `deflate_init()`.
     * @param array        $options Compression options to use, see `deflate_init()`.
     *
     * @throws StreamException If an invalid encoding or invalid options have been passed.
     *
     * @see http://php.net/manual/en/function.deflate-init.php
     */
    public function __construct(OutputStream $destination, int $encoding, array $options = [])
    {
        $this->destination = $destination;
        $this->encoding = $encoding;
        $this->options = $options;
        $this->resource = @\deflate_init($encoding, $options);
        if ($this->resource === \false) {
            throw new StreamException("Failed initializing deflate context");
        }
    }
    /** @inheritdoc */
    public function write(string $data) : Promise
    {
        if ($this->resource === null) {
            throw new ClosedException("The stream has already been closed");
        }
        \assert($this->destination !== null);
        $compressed = \deflate_add($this->resource, $data, \ZLIB_SYNC_FLUSH);
        if ($compressed === \false) {
            throw new StreamException("Failed adding data to deflate context");
        }
        $promise = $this->destination->write($compressed);
        $promise->onResolve(function ($error) {
            if ($error) {
                $this->close();
            }
        });
        return $promise;
    }
    /** @inheritdoc */
    public function end(string $finalData = "") : Promise
    {
        if ($this->resource === null) {
            throw new ClosedException("The stream has already been closed");
        }
        \assert($this->destination !== null);
        $compressed = \deflate_add($this->resource, $finalData, \ZLIB_FINISH);
        if ($compressed === \false) {
            throw new StreamException("Failed adding data to deflate context");
        }
        $promise = $this->destination->end($compressed);
        $promise->onResolve(function () {
            $this->close();
        });
        return $promise;
    }
    /**
     * @internal
     * @return void
     */
    private function close()
    {
        $this->resource = null;
        $this->destination = null;
    }
    /**
     * Gets the used compression encoding.
     *
     * @return int Encoding specified on construction time.
     */
    public function getEncoding() : int
    {
        return $this->encoding;
    }
    /**
     * Gets the used compression options.
     *
     * @return array Options array passed on construction time.
     */
    public function getOptions() : array
    {
        return $this->options;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
/**
 * An `InputStream` allows reading byte streams in chunks.
 *
 * **Example**
 *
 * ```php
 * function readAll(InputStream $in): Promise {
 *     return Amp\call(function () use ($in) {
 *         $buffer = "";
 *
 *         while (($chunk = yield $in->read()) !== null) {
 *             $buffer .= $chunk;
 *         }
 *
 *         return $buffer;
 *     });
 * }
 * ```
 */
interface InputStream
{
    /**
     * Reads data from the stream.
     *
     * @return Promise Resolves with a string when new data is available or `null` if the stream has closed.
     *
     * @psalm-return Promise<string|null>
     *
     * @throws PendingReadError Thrown if another read operation is still pending.
     */
    public function read() : Promise;
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
final class LineReader
{
    /** @var string */
    private $delimiter;
    /** @var bool */
    private $lineMode;
    /** @var string */
    private $buffer = "";
    /** @var InputStream */
    private $source;
    public function __construct(InputStream $inputStream, string $delimiter = null)
    {
        $this->source = $inputStream;
        $this->delimiter = $delimiter === null ? "\n" : $delimiter;
        $this->lineMode = $delimiter === null;
    }
    /**
     * @return Promise<string|null>
     */
    public function readLine() : Promise
    {
        return call(function () {
            if (\false !== \strpos($this->buffer, $this->delimiter)) {
                list($line, $this->buffer) = \explode($this->delimiter, $this->buffer, 2);
                return $this->lineMode ? \rtrim($line, "\r") : $line;
            }
            while (null !== ($chunk = (yield $this->source->read()))) {
                $this->buffer .= $chunk;
                if (\false !== \strpos($this->buffer, $this->delimiter)) {
                    list($line, $this->buffer) = \explode($this->delimiter, $this->buffer, 2);
                    return $this->lineMode ? \rtrim($line, "\r") : $line;
                }
            }
            if ($this->buffer === "") {
                return null;
            }
            $line = $this->buffer;
            $this->buffer = "";
            return $this->lineMode ? \rtrim($line, "\r") : $line;
        });
    }
    public function getBuffer() : string
    {
        return $this->buffer;
    }
    /**
     * @return void
     */
    public function clearBuffer()
    {
        $this->buffer = "";
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Iterator;
use _HumbugBox1cb33d1f20f1\Amp\Loop;
use _HumbugBox1cb33d1f20f1\Amp\Producer;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
// @codeCoverageIgnoreStart
if (\strlen('…') !== 3) {
    throw new \Error('The mbstring.func_overload ini setting is enabled. It must be disabled to use the stream package.');
}
// @codeCoverageIgnoreEnd
if (!\defined('STDOUT')) {
    \define('STDOUT', \fopen('php://stdout', 'w'));
}
if (!\defined('STDERR')) {
    \define('STDERR', \fopen('php://stderr', 'w'));
}
/**
 * @param \Amp\ByteStream\InputStream  $source
 * @param \Amp\ByteStream\OutputStream $destination
 *
 * @return \Amp\Promise
 */
function pipe(InputStream $source, OutputStream $destination) : Promise
{
    return call(function () use($source, $destination) : \Generator {
        $written = 0;
        while (($chunk = (yield $source->read())) !== null) {
            $written += \strlen($chunk);
            $writePromise = $destination->write($chunk);
            $chunk = null;
            // free memory
            (yield $writePromise);
        }
        return $written;
    });
}
/**
 * @param \Amp\ByteStream\InputStream $source
 *
 * @return \Amp\Promise
 */
function buffer(InputStream $source) : Promise
{
    return call(function () use($source) : \Generator {
        $buffer = "";
        while (($chunk = (yield $source->read())) !== null) {
            $buffer .= $chunk;
            $chunk = null;
            // free memory
        }
        return $buffer;
    });
}
/**
 * The php://input input buffer stream for the process associated with the currently active event loop.
 *
 * @return ResourceInputStream
 */
function getInputBufferStream() : ResourceInputStream
{
    static $key = InputStream::class . '\\input';
    $stream = Loop::getState($key);
    if (!$stream) {
        $stream = new ResourceInputStream(\fopen('php://input', 'rb'));
        Loop::setState($key, $stream);
    }
    return $stream;
}
/**
 * The php://output output buffer stream for the process associated with the currently active event loop.
 *
 * @return ResourceOutputStream
 */
function getOutputBufferStream() : ResourceOutputStream
{
    static $key = OutputStream::class . '\\output';
    $stream = Loop::getState($key);
    if (!$stream) {
        $stream = new ResourceOutputStream(\fopen('php://output', 'wb'));
        Loop::setState($key, $stream);
    }
    return $stream;
}
/**
 * The STDIN stream for the process associated with the currently active event loop.
 *
 * @return ResourceInputStream
 */
function getStdin() : ResourceInputStream
{
    static $key = InputStream::class . '\\stdin';
    $stream = Loop::getState($key);
    if (!$stream) {
        $stream = new ResourceInputStream(\STDIN);
        Loop::setState($key, $stream);
    }
    return $stream;
}
/**
 * The STDOUT stream for the process associated with the currently active event loop.
 *
 * @return ResourceOutputStream
 */
function getStdout() : ResourceOutputStream
{
    static $key = OutputStream::class . '\\stdout';
    $stream = Loop::getState($key);
    if (!$stream) {
        $stream = new ResourceOutputStream(\STDOUT);
        Loop::setState($key, $stream);
    }
    return $stream;
}
/**
 * The STDERR stream for the process associated with the currently active event loop.
 *
 * @return ResourceOutputStream
 */
function getStderr() : ResourceOutputStream
{
    static $key = OutputStream::class . '\\stderr';
    $stream = Loop::getState($key);
    if (!$stream) {
        $stream = new ResourceOutputStream(\STDERR);
        Loop::setState($key, $stream);
    }
    return $stream;
}
function parseLineDelimitedJson(InputStream $stream, bool $assoc = \false, int $depth = 512, int $options = 0) : Iterator
{
    return new Producer(static function (callable $emit) use($stream, $assoc, $depth, $options) {
        $reader = new LineReader($stream);
        while (null !== ($line = (yield $reader->readLine()))) {
            $line = \trim($line);
            if ($line === '') {
                continue;
            }
            /** @noinspection PhpComposerExtensionStubsInspection */
            $data = \json_decode($line, $assoc, $depth, $options);
            /** @noinspection PhpComposerExtensionStubsInspection */
            $error = \json_last_error();
            /** @noinspection PhpComposerExtensionStubsInspection */
            if ($error !== \JSON_ERROR_NONE) {
                /** @noinspection PhpComposerExtensionStubsInspection */
                throw new StreamException('Failed to parse JSON: ' . \json_last_error_msg(), $error);
            }
            (yield $emit($data));
        }
    });
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
use function _HumbugBox1cb33d1f20f1\Amp\call;
final class InputStreamChain implements InputStream
{
    /** @var InputStream[] */
    private $streams;
    /** @var bool */
    private $reading = \false;
    public function __construct(InputStream ...$streams)
    {
        $this->streams = $streams;
    }
    /** @inheritDoc */
    public function read() : Promise
    {
        if ($this->reading) {
            throw new PendingReadError();
        }
        if (!$this->streams) {
            return new Success(null);
        }
        return call(function () {
            $this->reading = \true;
            try {
                while ($this->streams) {
                    $chunk = (yield $this->streams[0]->read());
                    if ($chunk === null) {
                        \array_shift($this->streams);
                        continue;
                    }
                    return $chunk;
                }
                return null;
            } finally {
                $this->reading = \false;
            }
        });
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
/**
 * An `OutputStream` allows writing data in chunks. Writers can wait on the returned promises to feel the backpressure.
 */
interface OutputStream
{
    /**
     * Writes data to the stream.
     *
     * @param string $data Bytes to write.
     *
     * @return Promise Succeeds once the data has been successfully written to the stream.
     *
     * @throws ClosedException If the stream has already been closed.
     * @throws StreamException If writing to the stream fails.
     */
    public function write(string $data) : Promise;
    /**
     * Marks the stream as no longer writable. Optionally writes a final data chunk before. Note that this is not the
     * same as forcefully closing the stream. This method waits for all pending writes to complete before closing the
     * stream. Socket streams implementing this interface should only close the writable side of the stream.
     *
     * @param string $finalData Bytes to write.
     *
     * @return Promise Succeeds once the data has been successfully written to the stream.
     *
     * @throws ClosedException If the stream has already been closed.
     * @throws StreamException If writing to the stream fails.
     */
    public function end(string $finalData = "") : Promise;
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Failure;
use _HumbugBox1cb33d1f20f1\Amp\Loop;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
/**
 * Output stream abstraction for PHP's stream resources.
 */
final class ResourceOutputStream implements OutputStream
{
    const MAX_CONSECUTIVE_EMPTY_WRITES = 3;
    const LARGE_CHUNK_SIZE = 128 * 1024;
    /** @var resource|null */
    private $resource;
    /** @var string */
    private $watcher;
    /** @var \SplQueue<array> */
    private $writes;
    /** @var bool */
    private $writable = \true;
    /** @var int|null */
    private $chunkSize;
    /**
     * @param resource $stream Stream resource.
     * @param int|null $chunkSize Chunk size per `fwrite()` operation.
     */
    public function __construct($stream, int $chunkSize = null)
    {
        if (!\is_resource($stream) || \get_resource_type($stream) !== 'stream') {
            throw new \Error("Expected a valid stream");
        }
        $meta = \stream_get_meta_data($stream);
        if (\strpos($meta["mode"], "r") !== \false && \strpos($meta["mode"], "+") === \false) {
            throw new \Error("Expected a writable stream");
        }
        \stream_set_blocking($stream, \false);
        \stream_set_write_buffer($stream, 0);
        $this->resource = $stream;
        $this->chunkSize =& $chunkSize;
        $writes = $this->writes = new \SplQueue();
        $writable =& $this->writable;
        $resource =& $this->resource;
        $this->watcher = Loop::onWritable($stream, static function ($watcher, $stream) use($writes, &$chunkSize, &$writable, &$resource) {
            static $emptyWrites = 0;
            try {
                while (!$writes->isEmpty()) {
                    /** @var Deferred $deferred */
                    list($data, $previous, $deferred) = $writes->shift();
                    $length = \strlen($data);
                    if ($length === 0) {
                        $deferred->resolve(0);
                        continue;
                    }
                    if (!\is_resource($stream) || ($metaData = @\stream_get_meta_data($stream)) && $metaData['eof']) {
                        throw new ClosedException("The stream was closed by the peer");
                    }
                    // Error reporting suppressed since fwrite() emits E_WARNING if the pipe is broken or the buffer is full.
                    // Use conditional, because PHP doesn't like getting null passed
                    if ($chunkSize) {
                        $written = @\fwrite($stream, $data, $chunkSize);
                    } else {
                        $written = @\fwrite($stream, $data);
                    }
                    \assert(
                        $written !== \false || \PHP_VERSION_ID >= 70400,
                        // PHP 7.4+ returns false on EPIPE.
                        "Trying to write on a previously fclose()'d resource. Do NOT manually fclose() resources the still referenced in the loop."
                    );
                    // PHP 7.4.0 and 7.4.1 may return false on EAGAIN.
                    if ($written === \false && \PHP_VERSION_ID >= 70402) {
                        $message = "Failed to write to stream";
                        if ($error = \error_get_last()) {
                            $message .= \sprintf("; %s", $error["message"]);
                        }
                        throw new StreamException($message);
                    }
                    // Broken pipes between processes on macOS/FreeBSD do not detect EOF properly.
                    if ($written === 0 || $written === \false) {
                        if ($emptyWrites++ > self::MAX_CONSECUTIVE_EMPTY_WRITES) {
                            $message = "Failed to write to stream after multiple attempts";
                            if ($error = \error_get_last()) {
                                $message .= \sprintf("; %s", $error["message"]);
                            }
                            throw new StreamException($message);
                        }
                        $writes->unshift([$data, $previous, $deferred]);
                        return;
                    }
                    $emptyWrites = 0;
                    if ($length > $written) {
                        $data = \substr($data, $written);
                        $writes->unshift([$data, $written + $previous, $deferred]);
                        return;
                    }
                    $deferred->resolve($written + $previous);
                }
            } catch (\Throwable $exception) {
                $resource = null;
                $writable = \false;
                /** @psalm-suppress PossiblyUndefinedVariable */
                $deferred->fail($exception);
                while (!$writes->isEmpty()) {
                    list(, , $deferred) = $writes->shift();
                    $deferred->fail($exception);
                }
                Loop::cancel($watcher);
            } finally {
                if ($writes->isEmpty()) {
                    Loop::disable($watcher);
                }
            }
        });
        Loop::disable($this->watcher);
    }
    /**
     * Writes data to the stream.
     *
     * @param string $data Bytes to write.
     *
     * @return Promise Succeeds once the data has been successfully written to the stream.
     *
     * @throws ClosedException If the stream has already been closed.
     */
    public function write(string $data) : Promise
    {
        return $this->send($data, \false);
    }
    /**
     * Closes the stream after all pending writes have been completed. Optionally writes a final data chunk before.
     *
     * @param string $finalData Bytes to write.
     *
     * @return Promise Succeeds once the data has been successfully written to the stream.
     *
     * @throws ClosedException If the stream has already been closed.
     */
    public function end(string $finalData = "") : Promise
    {
        return $this->send($finalData, \true);
    }
    private function send(string $data, bool $end = \false) : Promise
    {
        if (!$this->writable) {
            return new Failure(new ClosedException("The stream is not writable"));
        }
        $length = \strlen($data);
        $written = 0;
        if ($end) {
            $this->writable = \false;
        }
        if ($this->writes->isEmpty()) {
            if ($length === 0) {
                if ($end) {
                    $this->close();
                }
                return new Success(0);
            }
            if (!\is_resource($this->resource) || ($metaData = @\stream_get_meta_data($this->resource)) && $metaData['eof']) {
                return new Failure(new ClosedException("The stream was closed by the peer"));
            }
            // Error reporting suppressed since fwrite() emits E_WARNING if the pipe is broken or the buffer is full.
            // Use conditional, because PHP doesn't like getting null passed.
            if ($this->chunkSize) {
                $written = @\fwrite($this->resource, $data, $this->chunkSize);
            } else {
                $written = @\fwrite($this->resource, $data);
            }
            \assert(
                $written !== \false || \PHP_VERSION_ID >= 70400,
                // PHP 7.4+ returns false on EPIPE.
                "Trying to write on a previously fclose()'d resource. Do NOT manually fclose() resources the still referenced in the loop."
            );
            // PHP 7.4.0 and 7.4.1 may return false on EAGAIN.
            if ($written === \false && \PHP_VERSION_ID >= 70402) {
                $message = "Failed to write to stream";
                if ($error = \error_get_last()) {
                    $message .= \sprintf("; %s", $error["message"]);
                }
                return new Failure(new StreamException($message));
            }
            $written = (int) $written;
            // Cast potential false to 0.
            if ($length === $written) {
                if ($end) {
                    $this->close();
                }
                return new Success($written);
            }
            $data = \substr($data, $written);
        }
        $deferred = new Deferred();
        if ($length - $written > self::LARGE_CHUNK_SIZE) {
            $chunks = \str_split($data, self::LARGE_CHUNK_SIZE);
            $data = \array_pop($chunks);
            foreach ($chunks as $chunk) {
                $this->writes->push([$chunk, $written, new Deferred()]);
                $written += self::LARGE_CHUNK_SIZE;
            }
        }
        $this->writes->push([$data, $written, $deferred]);
        Loop::enable($this->watcher);
        $promise = $deferred->promise();
        if ($end) {
            $promise->onResolve([$this, "close"]);
        }
        return $promise;
    }
    /**
     * Closes the stream forcefully. Multiple `close()` calls are ignored.
     *
     * @return void
     */
    public function close()
    {
        if (\is_resource($this->resource)) {
            // Error suppression, as resource might already be closed
            $meta = @\stream_get_meta_data($this->resource);
            if ($meta && \strpos($meta["mode"], "+") !== \false) {
                @\stream_socket_shutdown($this->resource, \STREAM_SHUT_WR);
            } else {
                /** @psalm-suppress InvalidPropertyAssignmentValue psalm reports this as closed-resource */
                @\fclose($this->resource);
            }
        }
        $this->free();
    }
    /**
     * Nulls reference to resource, marks stream unwritable, and fails any pending write.
     *
     * @return void
     */
    private function free()
    {
        $this->resource = null;
        $this->writable = \false;
        if (!$this->writes->isEmpty()) {
            $exception = new ClosedException("The socket was closed before writing completed");
            do {
                /** @var Deferred $deferred */
                list(, , $deferred) = $this->writes->shift();
                $deferred->fail($exception);
            } while (!$this->writes->isEmpty());
        }
        Loop::cancel($this->watcher);
    }
    /**
     * @return resource|null Stream resource or null if end() has been called or the stream closed.
     */
    public function getResource()
    {
        return $this->resource;
    }
    /**
     * @return void
     */
    public function setChunkSize(int $chunkSize)
    {
        $this->chunkSize = $chunkSize;
    }
    public function __destruct()
    {
        if ($this->resource !== null) {
            $this->free();
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

final class ClosedException extends StreamException
{
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
/**
 * Input stream with a single already known data chunk.
 */
final class InMemoryStream implements InputStream
{
    private $contents;
    /**
     * @param string|null $contents Data chunk or `null` for no data chunk.
     */
    public function __construct(string $contents = null)
    {
        $this->contents = $contents;
    }
    /**
     * Reads data from the stream.
     *
     * @return Promise<string|null> Resolves with the full contents or `null` if the stream has closed / already been consumed.
     */
    public function read() : Promise
    {
        if ($this->contents === null) {
            return new Success();
        }
        $promise = new Success($this->contents);
        $this->contents = null;
        return $promise;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Failure;
use _HumbugBox1cb33d1f20f1\Amp\Iterator;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
final class IteratorStream implements InputStream
{
    /** @var Iterator<string> */
    private $iterator;
    /** @var \Throwable|null */
    private $exception;
    /** @var bool */
    private $pending = \false;
    /**
     * @psam-param Iterator<string> $iterator
     */
    public function __construct(Iterator $iterator)
    {
        $this->iterator = $iterator;
    }
    /** @inheritdoc */
    public function read() : Promise
    {
        if ($this->exception) {
            return new Failure($this->exception);
        }
        if ($this->pending) {
            throw new PendingReadError();
        }
        $this->pending = \true;
        /** @var Deferred<string|null> $deferred */
        $deferred = new Deferred();
        $this->iterator->advance()->onResolve(function ($error, $hasNextElement) use($deferred) {
            $this->pending = \false;
            if ($error) {
                $this->exception = $error;
                $deferred->fail($error);
            } elseif ($hasNextElement) {
                $chunk = $this->iterator->getCurrent();
                if (!\is_string($chunk)) {
                    $this->exception = new StreamException(\sprintf("Unexpected iterator value of type '%s', expected string", \is_object($chunk) ? \get_class($chunk) : \gettype($chunk)));
                    $deferred->fail($this->exception);
                    return;
                }
                $deferred->resolve($chunk);
            } else {
                $deferred->resolve();
            }
        });
        return $deferred->promise();
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Coroutine;
use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Failure;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
/**
 * Creates a buffered message from an InputStream. The message can be consumed in chunks using the read() API or it may
 * be buffered and accessed in its entirety by waiting for the promise to resolve.
 *
 * Other implementations may extend this class to add custom properties such as a `isBinary()` flag for WebSocket
 * messages.
 *
 * Buffering Example:
 *
 * $stream = new Message($inputStream);
 * $content = yield $stream;
 *
 * Streaming Example:
 *
 * $stream = new Message($inputStream);
 *
 * while (($chunk = yield $stream->read()) !== null) {
 *     // Immediately use $chunk, reducing memory consumption since the entire message is never buffered.
 * }
 *
 * @deprecated Use Amp\ByteStream\Payload instead.
 */
class Message implements InputStream, Promise
{
    /** @var InputStream */
    private $source;
    /** @var string */
    private $buffer = "";
    /** @var Deferred|null */
    private $pendingRead;
    /** @var Coroutine|null */
    private $coroutine;
    /** @var bool True if onResolve() has been called. */
    private $buffering = \false;
    /** @var Deferred|null */
    private $backpressure;
    /** @var bool True if the iterator has completed. */
    private $complete = \false;
    /** @var \Throwable|null Used to fail future reads on failure. */
    private $error;
    /**
     * @param InputStream $source An iterator that only emits strings.
     */
    public function __construct(InputStream $source)
    {
        $this->source = $source;
    }
    private function consume() : \Generator
    {
        while (($chunk = (yield $this->source->read())) !== null) {
            $buffer = $this->buffer .= $chunk;
            if ($buffer === "") {
                continue;
                // Do not succeed reads with empty string.
            } elseif ($this->pendingRead) {
                $deferred = $this->pendingRead;
                $this->pendingRead = null;
                $this->buffer = "";
                $deferred->resolve($buffer);
                $buffer = "";
                // Destroy last emitted chunk to free memory.
            } elseif (!$this->buffering) {
                $buffer = "";
                // Destroy last emitted chunk to free memory.
                $this->backpressure = new Deferred();
                (yield $this->backpressure->promise());
            }
        }
        $this->complete = \true;
        if ($this->pendingRead) {
            $deferred = $this->pendingRead;
            $this->pendingRead = null;
            $deferred->resolve($this->buffer !== "" ? $this->buffer : null);
            $this->buffer = "";
        }
        return $this->buffer;
    }
    /** @inheritdoc */
    public final function read() : Promise
    {
        if ($this->pendingRead) {
            throw new PendingReadError();
        }
        if ($this->coroutine === null) {
            $this->coroutine = new Coroutine($this->consume());
            $this->coroutine->onResolve(function ($error) {
                if ($error) {
                    $this->error = $error;
                }
                if ($this->pendingRead) {
                    $deferred = $this->pendingRead;
                    $this->pendingRead = null;
                    $deferred->fail($error);
                }
            });
        }
        if ($this->error) {
            return new Failure($this->error);
        }
        if ($this->buffer !== "") {
            $buffer = $this->buffer;
            $this->buffer = "";
            if ($this->backpressure) {
                $backpressure = $this->backpressure;
                $this->backpressure = null;
                $backpressure->resolve();
            }
            return new Success($buffer);
        }
        if ($this->complete) {
            return new Success();
        }
        $this->pendingRead = new Deferred();
        return $this->pendingRead->promise();
    }
    /** @inheritdoc */
    public final function onResolve(callable $onResolved)
    {
        $this->buffering = \true;
        if ($this->coroutine === null) {
            $this->coroutine = new Coroutine($this->consume());
        }
        if ($this->backpressure) {
            $backpressure = $this->backpressure;
            $this->backpressure = null;
            $backpressure->resolve();
        }
        $this->coroutine->onResolve($onResolved);
    }
    /**
     * Exposes the source input stream.
     *
     * This might be required to resolve a promise with an InputStream, because promises in Amp can't be resolved with
     * other promises.
     *
     * @return InputStream
     */
    public final function getInputStream() : InputStream
    {
        return $this->source;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
use function _HumbugBox1cb33d1f20f1\Amp\call;
/**
 * Allows decompression of input streams using Zlib.
 */
final class ZlibInputStream implements InputStream
{
    /** @var InputStream|null */
    private $source;
    /** @var int */
    private $encoding;
    /** @var array */
    private $options;
    /** @var resource|null */
    private $resource;
    /**
     * @param InputStream $source Input stream to read compressed data from.
     * @param int         $encoding Compression algorithm used, see `inflate_init()`.
     * @param array       $options Algorithm options, see `inflate_init()`.
     *
     * @throws StreamException
     * @throws \Error
     *
     * @see http://php.net/manual/en/function.inflate-init.php
     */
    public function __construct(InputStream $source, int $encoding, array $options = [])
    {
        $this->source = $source;
        $this->encoding = $encoding;
        $this->options = $options;
        $this->resource = @\inflate_init($encoding, $options);
        if ($this->resource === \false) {
            throw new StreamException("Failed initializing deflate context");
        }
    }
    /** @inheritdoc */
    public function read() : Promise
    {
        return call(function () {
            if ($this->resource === null) {
                return null;
            }
            \assert($this->source !== null);
            $data = (yield $this->source->read());
            // Needs a double guard, as stream might have been closed while reading
            /** @psalm-suppress ParadoxicalCondition */
            if ($this->resource === null) {
                return null;
            }
            if ($data === null) {
                $decompressed = @\inflate_add($this->resource, "", \ZLIB_FINISH);
                if ($decompressed === \false) {
                    throw new StreamException("Failed adding data to deflate context");
                }
                $this->close();
                return $decompressed;
            }
            $decompressed = @\inflate_add($this->resource, $data, \ZLIB_SYNC_FLUSH);
            if ($decompressed === \false) {
                throw new StreamException("Failed adding data to deflate context");
            }
            return $decompressed;
        });
    }
    /**
     * @internal
     * @return void
     */
    private function close()
    {
        $this->resource = null;
        $this->source = null;
    }
    /**
     * Gets the used compression encoding.
     *
     * @return int Encoding specified on construction time.
     */
    public function getEncoding() : int
    {
        return $this->encoding;
    }
    /**
     * Gets the used compression options.
     *
     * @return array Options array passed on construction time.
     */
    public function getOptions() : array
    {
        return $this->options;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Amp\ByteStream;

use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
class OutputBuffer implements OutputStream, Promise
{
    /** @var Deferred */
    private $deferred;
    /** @var string */
    private $contents = '';
    /** @var bool */
    private $closed = \false;
    public function __construct()
    {
        $this->deferred = new Deferred();
    }
    public function write(string $data) : Promise
    {
        if ($this->closed) {
            throw new ClosedException("The stream has already been closed.");
        }
        $this->contents .= $data;
        return new Success(\strlen($data));
    }
    public function end(string $finalData = "") : Promise
    {
        if ($this->closed) {
            throw new ClosedException("The stream has already been closed.");
        }
        $this->contents .= $finalData;
        $this->closed = \true;
        $this->deferred->resolve($this->contents);
        $this->contents = "";
        return new Success(\strlen($finalData));
    }
    public function onResolve(callable $onResolved)
    {
        $this->deferred->promise()->onResolve($onResolved);
    }
}

The MIT License (MIT)

Copyright (c) 2016-2021 amphp

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Mbstring;

/**
 * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
 *
 * Implemented:
 * - mb_chr                  - Returns a specific character from its Unicode code point
 * - mb_convert_encoding     - Convert character encoding
 * - mb_convert_variables    - Convert character code in variable(s)
 * - mb_decode_mimeheader    - Decode string in MIME header field
 * - mb_encode_mimeheader    - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
 * - mb_decode_numericentity - Decode HTML numeric string reference to character
 * - mb_encode_numericentity - Encode character to HTML numeric string reference
 * - mb_convert_case         - Perform case folding on a string
 * - mb_detect_encoding      - Detect character encoding
 * - mb_get_info             - Get internal settings of mbstring
 * - mb_http_input           - Detect HTTP input character encoding
 * - mb_http_output          - Set/Get HTTP output character encoding
 * - mb_internal_encoding    - Set/Get internal character encoding
 * - mb_list_encodings       - Returns an array of all supported encodings
 * - mb_ord                  - Returns the Unicode code point of a character
 * - mb_output_handler       - Callback function converts character encoding in output buffer
 * - mb_scrub                - Replaces ill-formed byte sequences with substitute characters
 * - mb_strlen               - Get string length
 * - mb_strpos               - Find position of first occurrence of string in a string
 * - mb_strrpos              - Find position of last occurrence of a string in a string
 * - mb_str_split            - Convert a string to an array
 * - mb_strtolower           - Make a string lowercase
 * - mb_strtoupper           - Make a string uppercase
 * - mb_substitute_character - Set/Get substitution character
 * - mb_substr               - Get part of string
 * - mb_stripos              - Finds position of first occurrence of a string within another, case insensitive
 * - mb_stristr              - Finds first occurrence of a string within another, case insensitive
 * - mb_strrchr              - Finds the last occurrence of a character in a string within another
 * - mb_strrichr             - Finds the last occurrence of a character in a string within another, case insensitive
 * - mb_strripos             - Finds position of last occurrence of a string within another, case insensitive
 * - mb_strstr               - Finds first occurrence of a string within another
 * - mb_strwidth             - Return width of string
 * - mb_substr_count         - Count the number of substring occurrences
 *
 * Not implemented:
 * - mb_convert_kana         - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
 * - mb_ereg_*               - Regular expression with multibyte support
 * - mb_parse_str            - Parse GET/POST/COOKIE data and set global variable
 * - mb_preferred_mime_name  - Get MIME charset string
 * - mb_regex_encoding       - Returns current encoding for multibyte regex as string
 * - mb_regex_set_options    - Set/Get the default options for mbregex functions
 * - mb_send_mail            - Send encoded mail
 * - mb_split                - Split multibyte string using regular expression
 * - mb_strcut               - Get part of string
 * - mb_strimwidth           - Get truncated string with specified width
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Mbstring
{
    public const MB_CASE_FOLD = \PHP_INT_MAX;
    private const CASE_FOLD = [['µ', 'ſ', "ͅ", 'ς', "ϐ", "ϑ", "ϕ", "ϖ", "ϰ", "ϱ", "ϵ", "ẛ", "ι"], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "ṡ", 'ι']];
    private static $encodingList = ['ASCII', 'UTF-8'];
    private static $language = 'neutral';
    private static $internalEncoding = 'UTF-8';
    public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
    {
        if (\is_array($fromEncoding) || null !== $fromEncoding && \false !== \strpos($fromEncoding, ',')) {
            $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
        } else {
            $fromEncoding = self::getEncoding($fromEncoding);
        }
        $toEncoding = self::getEncoding($toEncoding);
        if ('BASE64' === $fromEncoding) {
            $s = \base64_decode($s);
            $fromEncoding = $toEncoding;
        }
        if ('BASE64' === $toEncoding) {
            return \base64_encode($s);
        }
        if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
            if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
                $fromEncoding = 'Windows-1252';
            }
            if ('UTF-8' !== $fromEncoding) {
                $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s);
            }
            return \preg_replace_callback('/[\\x80-\\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
        }
        if ('HTML-ENTITIES' === $fromEncoding) {
            $s = \html_entity_decode($s, \ENT_COMPAT, 'UTF-8');
            $fromEncoding = 'UTF-8';
        }
        return \iconv($fromEncoding, $toEncoding . '//IGNORE', $s);
    }
    public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
    {
        $ok = \true;
        \array_walk_recursive($vars, function (&$v) use(&$ok, $toEncoding, $fromEncoding) {
            if (\false === ($v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding))) {
                $ok = \false;
            }
        });
        return $ok ? $fromEncoding : \false;
    }
    public static function mb_decode_mimeheader($s)
    {
        return \iconv_mime_decode($s, 2, self::$internalEncoding);
    }
    public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
    {
        \trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING);
    }
    public static function mb_decode_numericentity($s, $convmap, $encoding = null)
    {
        if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
            \trigger_error('mb_decode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
            return null;
        }
        if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) {
            return \false;
        }
        if (null !== $encoding && !\is_scalar($encoding)) {
            \trigger_error('mb_decode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
            return '';
            // Instead of null (cf. mb_encode_numericentity).
        }
        $s = (string) $s;
        if ('' === $s) {
            return '';
        }
        $encoding = self::getEncoding($encoding);
        if ('UTF-8' === $encoding) {
            $encoding = null;
            if (!\preg_match('//u', $s)) {
                $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
            }
        } else {
            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
        }
        $cnt = \floor(\count($convmap) / 4) * 4;
        for ($i = 0; $i < $cnt; $i += 4) {
            // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
            $convmap[$i] += $convmap[$i + 2];
            $convmap[$i + 1] += $convmap[$i + 2];
        }
        $s = \preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use($cnt, $convmap) {
            $c = isset($m[2]) ? (int) \hexdec($m[2]) : $m[1];
            for ($i = 0; $i < $cnt; $i += 4) {
                if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
                    return self::mb_chr($c - $convmap[$i + 2]);
                }
            }
            return $m[0];
        }, $s);
        if (null === $encoding) {
            return $s;
        }
        return \iconv('UTF-8', $encoding . '//IGNORE', $s);
    }
    public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = \false)
    {
        if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
            \trigger_error('mb_encode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
            return null;
        }
        if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) {
            return \false;
        }
        if (null !== $encoding && !\is_scalar($encoding)) {
            \trigger_error('mb_encode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
            return null;
            // Instead of '' (cf. mb_decode_numericentity).
        }
        if (null !== $is_hex && !\is_scalar($is_hex)) {
            \trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, ' . \gettype($s) . ' given', \E_USER_WARNING);
            return null;
        }
        $s = (string) $s;
        if ('' === $s) {
            return '';
        }
        $encoding = self::getEncoding($encoding);
        if ('UTF-8' === $encoding) {
            $encoding = null;
            if (!\preg_match('//u', $s)) {
                $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
            }
        } else {
            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
        }
        static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
        $cnt = \floor(\count($convmap) / 4) * 4;
        $i = 0;
        $len = \strlen($s);
        $result = '';
        while ($i < $len) {
            $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"];
            $uchr = \substr($s, $i, $ulen);
            $i += $ulen;
            $c = self::mb_ord($uchr);
            for ($j = 0; $j < $cnt; $j += 4) {
                if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
                    $cOffset = $c + $convmap[$j + 2] & $convmap[$j + 3];
                    $result .= $is_hex ? \sprintf('&#x%X;', $cOffset) : '&#' . $cOffset . ';';
                    continue 2;
                }
            }
            $result .= $uchr;
        }
        if (null === $encoding) {
            return $result;
        }
        return \iconv('UTF-8', $encoding . '//IGNORE', $result);
    }
    public static function mb_convert_case($s, $mode, $encoding = null)
    {
        $s = (string) $s;
        if ('' === $s) {
            return '';
        }
        $encoding = self::getEncoding($encoding);
        if ('UTF-8' === $encoding) {
            $encoding = null;
            if (!\preg_match('//u', $s)) {
                $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
            }
        } else {
            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
        }
        if (\MB_CASE_TITLE == $mode) {
            static $titleRegexp = null;
            if (null === $titleRegexp) {
                $titleRegexp = self::getData('titleCaseRegexp');
            }
            $s = \preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s);
        } else {
            if (\MB_CASE_UPPER == $mode) {
                static $upper = null;
                if (null === $upper) {
                    $upper = self::getData('upperCase');
                }
                $map = $upper;
            } else {
                if (self::MB_CASE_FOLD === $mode) {
                    $s = \str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s);
                }
                static $lower = null;
                if (null === $lower) {
                    $lower = self::getData('lowerCase');
                }
                $map = $lower;
            }
            static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
            $i = 0;
            $len = \strlen($s);
            while ($i < $len) {
                $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"];
                $uchr = \substr($s, $i, $ulen);
                $i += $ulen;
                if (isset($map[$uchr])) {
                    $uchr = $map[$uchr];
                    $nlen = \strlen($uchr);
                    if ($nlen == $ulen) {
                        $nlen = $i;
                        do {
                            $s[--$nlen] = $uchr[--$ulen];
                        } while ($ulen);
                    } else {
                        $s = \substr_replace($s, $uchr, $i - $ulen, $ulen);
                        $len += $nlen - $ulen;
                        $i += $nlen - $ulen;
                    }
                }
            }
        }
        if (null === $encoding) {
            return $s;
        }
        return \iconv('UTF-8', $encoding . '//IGNORE', $s);
    }
    public static function mb_internal_encoding($encoding = null)
    {
        if (null === $encoding) {
            return self::$internalEncoding;
        }
        $normalizedEncoding = self::getEncoding($encoding);
        if ('UTF-8' === $normalizedEncoding || \false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
            self::$internalEncoding = $normalizedEncoding;
            return \true;
        }
        if (80000 > \PHP_VERSION_ID) {
            return \false;
        }
        throw new \ValueError(\sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding));
    }
    public static function mb_language($lang = null)
    {
        if (null === $lang) {
            return self::$language;
        }
        switch ($normalizedLang = \strtolower($lang)) {
            case 'uni':
            case 'neutral':
                self::$language = $normalizedLang;
                return \true;
        }
        if (80000 > \PHP_VERSION_ID) {
            return \false;
        }
        throw new \ValueError(\sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang));
    }
    public static function mb_list_encodings()
    {
        return ['UTF-8'];
    }
    public static function mb_encoding_aliases($encoding)
    {
        switch (\strtoupper($encoding)) {
            case 'UTF8':
            case 'UTF-8':
                return ['utf8'];
        }
        return \false;
    }
    public static function mb_check_encoding($var = null, $encoding = null)
    {
        if (null === $encoding) {
            if (null === $var) {
                return \false;
            }
            $encoding = self::$internalEncoding;
        }
        return self::mb_detect_encoding($var, [$encoding]) || \false !== @\iconv($encoding, $encoding, $var);
    }
    public static function mb_detect_encoding($str, $encodingList = null, $strict = \false)
    {
        if (null === $encodingList) {
            $encodingList = self::$encodingList;
        } else {
            if (!\is_array($encodingList)) {
                $encodingList = \array_map('trim', \explode(',', $encodingList));
            }
            $encodingList = \array_map('strtoupper', $encodingList);
        }
        foreach ($encodingList as $enc) {
            switch ($enc) {
                case 'ASCII':
                    if (!\preg_match('/[\\x80-\\xFF]/', $str)) {
                        return $enc;
                    }
                    break;
                case 'UTF8':
                case 'UTF-8':
                    if (\preg_match('//u', $str)) {
                        return 'UTF-8';
                    }
                    break;
                default:
                    if (0 === \strncmp($enc, 'ISO-8859-', 9)) {
                        return $enc;
                    }
            }
        }
        return \false;
    }
    public static function mb_detect_order($encodingList = null)
    {
        if (null === $encodingList) {
            return self::$encodingList;
        }
        if (!\is_array($encodingList)) {
            $encodingList = \array_map('trim', \explode(',', $encodingList));
        }
        $encodingList = \array_map('strtoupper', $encodingList);
        foreach ($encodingList as $enc) {
            switch ($enc) {
                default:
                    if (\strncmp($enc, 'ISO-8859-', 9)) {
                        return \false;
                    }
                // no break
                case 'ASCII':
                case 'UTF8':
                case 'UTF-8':
            }
        }
        self::$encodingList = $encodingList;
        return \true;
    }
    public static function mb_strlen($s, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return \strlen($s);
        }
        return @\iconv_strlen($s, $encoding);
    }
    public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return \strpos($haystack, $needle, $offset);
        }
        $needle = (string) $needle;
        if ('' === $needle) {
            if (80000 > \PHP_VERSION_ID) {
                \trigger_error(__METHOD__ . ': Empty delimiter', \E_USER_WARNING);
                return \false;
            }
            return 0;
        }
        return \iconv_strpos($haystack, $needle, $offset, $encoding);
    }
    public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return \strrpos($haystack, $needle, $offset);
        }
        if ($offset != (int) $offset) {
            $offset = 0;
        } elseif ($offset = (int) $offset) {
            if ($offset < 0) {
                if (0 > ($offset += self::mb_strlen($needle))) {
                    $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
                }
                $offset = 0;
            } else {
                $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
            }
        }
        $pos = '' !== $needle || 80000 > \PHP_VERSION_ID ? \iconv_strrpos($haystack, $needle, $encoding) : self::mb_strlen($haystack, $encoding);
        return \false !== $pos ? $offset + $pos : \false;
    }
    public static function mb_str_split($string, $split_length = 1, $encoding = null)
    {
        if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
            \trigger_error('mb_str_split() expects parameter 1 to be string, ' . \gettype($string) . ' given', \E_USER_WARNING);
            return null;
        }
        if (1 > ($split_length = (int) $split_length)) {
            if (80000 > \PHP_VERSION_ID) {
                \trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
                return \false;
            }
            throw new \ValueError('Argument #2 ($length) must be greater than 0');
        }
        if (null === $encoding) {
            $encoding = \mb_internal_encoding();
        }
        if ('UTF-8' === ($encoding = self::getEncoding($encoding))) {
            $rx = '/(';
            while (65535 < $split_length) {
                $rx .= '.{65535}';
                $split_length -= 65535;
            }
            $rx .= '.{' . $split_length . '})/us';
            return \preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
        }
        $result = [];
        $length = \mb_strlen($string, $encoding);
        for ($i = 0; $i < $length; $i += $split_length) {
            $result[] = \mb_substr($string, $i, $split_length, $encoding);
        }
        return $result;
    }
    public static function mb_strtolower($s, $encoding = null)
    {
        return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding);
    }
    public static function mb_strtoupper($s, $encoding = null)
    {
        return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding);
    }
    public static function mb_substitute_character($c = null)
    {
        if (null === $c) {
            return 'none';
        }
        if (0 === \strcasecmp($c, 'none')) {
            return \true;
        }
        if (80000 > \PHP_VERSION_ID) {
            return \false;
        }
        if (\is_int($c) || 'long' === $c || 'entity' === $c) {
            return \false;
        }
        throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint');
    }
    public static function mb_substr($s, $start, $length = null, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            return (string) \substr($s, $start, null === $length ? 2147483647 : $length);
        }
        if ($start < 0) {
            $start = \iconv_strlen($s, $encoding) + $start;
            if ($start < 0) {
                $start = 0;
            }
        }
        if (null === $length) {
            $length = 2147483647;
        } elseif ($length < 0) {
            $length = \iconv_strlen($s, $encoding) + $length - $start;
            if ($length < 0) {
                return '';
            }
        }
        return (string) \iconv_substr($s, $start, $length, $encoding);
    }
    public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
        return self::mb_strpos($haystack, $needle, $offset, $encoding);
    }
    public static function mb_stristr($haystack, $needle, $part = \false, $encoding = null)
    {
        $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
        return self::getSubpart($pos, $part, $haystack, $encoding);
    }
    public static function mb_strrchr($haystack, $needle, $part = \false, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('CP850' === $encoding || 'ASCII' === $encoding) {
            $pos = \strrpos($haystack, $needle);
        } else {
            $needle = self::mb_substr($needle, 0, 1, $encoding);
            $pos = \iconv_strrpos($haystack, $needle, $encoding);
        }
        return self::getSubpart($pos, $part, $haystack, $encoding);
    }
    public static function mb_strrichr($haystack, $needle, $part = \false, $encoding = null)
    {
        $needle = self::mb_substr($needle, 0, 1, $encoding);
        $pos = self::mb_strripos($haystack, $needle, $encoding);
        return self::getSubpart($pos, $part, $haystack, $encoding);
    }
    public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
    {
        $haystack = self::mb_convert_case($haystack, self::MB_CASE_FOLD, $encoding);
        $needle = self::mb_convert_case($needle, self::MB_CASE_FOLD, $encoding);
        return self::mb_strrpos($haystack, $needle, $offset, $encoding);
    }
    public static function mb_strstr($haystack, $needle, $part = \false, $encoding = null)
    {
        $pos = \strpos($haystack, $needle);
        if (\false === $pos) {
            return \false;
        }
        if ($part) {
            return \substr($haystack, 0, $pos);
        }
        return \substr($haystack, $pos);
    }
    public static function mb_get_info($type = 'all')
    {
        $info = ['internal_encoding' => self::$internalEncoding, 'http_output' => 'pass', 'http_output_conv_mimetypes' => '^(text/|application/xhtml\\+xml)', 'func_overload' => 0, 'func_overload_list' => 'no overload', 'mail_charset' => 'UTF-8', 'mail_header_encoding' => 'BASE64', 'mail_body_encoding' => 'BASE64', 'illegal_chars' => 0, 'encoding_translation' => 'Off', 'language' => self::$language, 'detect_order' => self::$encodingList, 'substitute_character' => 'none', 'strict_detection' => 'Off'];
        if ('all' === $type) {
            return $info;
        }
        if (isset($info[$type])) {
            return $info[$type];
        }
        return \false;
    }
    public static function mb_http_input($type = '')
    {
        return \false;
    }
    public static function mb_http_output($encoding = null)
    {
        return null !== $encoding ? 'pass' === $encoding : 'pass';
    }
    public static function mb_strwidth($s, $encoding = null)
    {
        $encoding = self::getEncoding($encoding);
        if ('UTF-8' !== $encoding) {
            $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
        }
        $s = \preg_replace('/[\\x{1100}-\\x{115F}\\x{2329}\\x{232A}\\x{2E80}-\\x{303E}\\x{3040}-\\x{A4CF}\\x{AC00}-\\x{D7A3}\\x{F900}-\\x{FAFF}\\x{FE10}-\\x{FE19}\\x{FE30}-\\x{FE6F}\\x{FF00}-\\x{FF60}\\x{FFE0}-\\x{FFE6}\\x{20000}-\\x{2FFFD}\\x{30000}-\\x{3FFFD}]/u', '', $s, -1, $wide);
        return ($wide << 1) + \iconv_strlen($s, 'UTF-8');
    }
    public static function mb_substr_count($haystack, $needle, $encoding = null)
    {
        return \substr_count($haystack, $needle);
    }
    public static function mb_output_handler($contents, $status)
    {
        return $contents;
    }
    public static function mb_chr($code, $encoding = null)
    {
        if (0x80 > ($code %= 0x200000)) {
            $s = \chr($code);
        } elseif (0x800 > $code) {
            $s = \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f);
        } elseif (0x10000 > $code) {
            $s = \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
        } else {
            $s = \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
        }
        if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) {
            $s = \mb_convert_encoding($s, $encoding, 'UTF-8');
        }
        return $s;
    }
    public static function mb_ord($s, $encoding = null)
    {
        if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) {
            $s = \mb_convert_encoding($s, 'UTF-8', $encoding);
        }
        if (1 === \strlen($s)) {
            return \ord($s);
        }
        $code = ($s = \unpack('C*', \substr($s, 0, 4))) ? $s[1] : 0;
        if (0xf0 <= $code) {
            return ($code - 0xf0 << 18) + ($s[2] - 0x80 << 12) + ($s[3] - 0x80 << 6) + $s[4] - 0x80;
        }
        if (0xe0 <= $code) {
            return ($code - 0xe0 << 12) + ($s[2] - 0x80 << 6) + $s[3] - 0x80;
        }
        if (0xc0 <= $code) {
            return ($code - 0xc0 << 6) + $s[2] - 0x80;
        }
        return $code;
    }
    private static function getSubpart($pos, $part, $haystack, $encoding)
    {
        if (\false === $pos) {
            return \false;
        }
        if ($part) {
            return self::mb_substr($haystack, 0, $pos, $encoding);
        }
        return self::mb_substr($haystack, $pos, null, $encoding);
    }
    private static function html_encoding_callback(array $m)
    {
        $i = 1;
        $entities = '';
        $m = \unpack('C*', \htmlentities($m[0], \ENT_COMPAT, 'UTF-8'));
        while (isset($m[$i])) {
            if (0x80 > $m[$i]) {
                $entities .= \chr($m[$i++]);
                continue;
            }
            if (0xf0 <= $m[$i]) {
                $c = ($m[$i++] - 0xf0 << 18) + ($m[$i++] - 0x80 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80;
            } elseif (0xe0 <= $m[$i]) {
                $c = ($m[$i++] - 0xe0 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80;
            } else {
                $c = ($m[$i++] - 0xc0 << 6) + $m[$i++] - 0x80;
            }
            $entities .= '&#' . $c . ';';
        }
        return $entities;
    }
    private static function title_case(array $s)
    {
        return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8') . self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8');
    }
    private static function getData($file)
    {
        if (\file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) {
            return require $file;
        }
        return \false;
    }
    private static function getEncoding($encoding)
    {
        if (null === $encoding) {
            return self::$internalEncoding;
        }
        if ('UTF-8' === $encoding) {
            return 'UTF-8';
        }
        $encoding = \strtoupper($encoding);
        if ('8BIT' === $encoding || 'BINARY' === $encoding) {
            return 'CP850';
        }
        if ('UTF8' === $encoding) {
            return 'UTF-8';
        }
        return $encoding;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Mbstring as p;
if (\PHP_VERSION_ID >= 80000) {
    return require __DIR__ . '/bootstrap80.php';
}
if (!\function_exists('mb_convert_encoding')) {
    function mb_convert_encoding($string, $to_encoding, $from_encoding = null)
    {
        return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding);
    }
}
if (!\function_exists('mb_decode_mimeheader')) {
    function mb_decode_mimeheader($string)
    {
        return p\Mbstring::mb_decode_mimeheader($string);
    }
}
if (!\function_exists('mb_encode_mimeheader')) {
    function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0)
    {
        return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent);
    }
}
if (!\function_exists('mb_decode_numericentity')) {
    function mb_decode_numericentity($string, $map, $encoding = null)
    {
        return p\Mbstring::mb_decode_numericentity($string, $map, $encoding);
    }
}
if (!\function_exists('mb_encode_numericentity')) {
    function mb_encode_numericentity($string, $map, $encoding = null, $hex = \false)
    {
        return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex);
    }
}
if (!\function_exists('mb_convert_case')) {
    function mb_convert_case($string, $mode, $encoding = null)
    {
        return p\Mbstring::mb_convert_case($string, $mode, $encoding);
    }
}
if (!\function_exists('mb_internal_encoding')) {
    function mb_internal_encoding($encoding = null)
    {
        return p\Mbstring::mb_internal_encoding($encoding);
    }
}
if (!\function_exists('mb_language')) {
    function mb_language($language = null)
    {
        return p\Mbstring::mb_language($language);
    }
}
if (!\function_exists('mb_list_encodings')) {
    function mb_list_encodings()
    {
        return p\Mbstring::mb_list_encodings();
    }
}
if (!\function_exists('mb_encoding_aliases')) {
    function mb_encoding_aliases($encoding)
    {
        return p\Mbstring::mb_encoding_aliases($encoding);
    }
}
if (!\function_exists('mb_check_encoding')) {
    function mb_check_encoding($value = null, $encoding = null)
    {
        return p\Mbstring::mb_check_encoding($value, $encoding);
    }
}
if (!\function_exists('mb_detect_encoding')) {
    function mb_detect_encoding($string, $encodings = null, $strict = \false)
    {
        return p\Mbstring::mb_detect_encoding($string, $encodings, $strict);
    }
}
if (!\function_exists('mb_detect_order')) {
    function mb_detect_order($encoding = null)
    {
        return p\Mbstring::mb_detect_order($encoding);
    }
}
if (!\function_exists('mb_parse_str')) {
    function mb_parse_str($string, &$result = [])
    {
        \parse_str($string, $result);
        return (bool) $result;
    }
}
if (!\function_exists('mb_strlen')) {
    function mb_strlen($string, $encoding = null)
    {
        return p\Mbstring::mb_strlen($string, $encoding);
    }
}
if (!\function_exists('mb_strpos')) {
    function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
    {
        return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding);
    }
}
if (!\function_exists('mb_strtolower')) {
    function mb_strtolower($string, $encoding = null)
    {
        return p\Mbstring::mb_strtolower($string, $encoding);
    }
}
if (!\function_exists('mb_strtoupper')) {
    function mb_strtoupper($string, $encoding = null)
    {
        return p\Mbstring::mb_strtoupper($string, $encoding);
    }
}
if (!\function_exists('mb_substitute_character')) {
    function mb_substitute_character($substitute_character = null)
    {
        return p\Mbstring::mb_substitute_character($substitute_character);
    }
}
if (!\function_exists('mb_substr')) {
    function mb_substr($string, $start, $length = 2147483647, $encoding = null)
    {
        return p\Mbstring::mb_substr($string, $start, $length, $encoding);
    }
}
if (!\function_exists('mb_stripos')) {
    function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
    {
        return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding);
    }
}
if (!\function_exists('mb_stristr')) {
    function mb_stristr($haystack, $needle, $before_needle = \false, $encoding = null)
    {
        return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding);
    }
}
if (!\function_exists('mb_strrchr')) {
    function mb_strrchr($haystack, $needle, $before_needle = \false, $encoding = null)
    {
        return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding);
    }
}
if (!\function_exists('mb_strrichr')) {
    function mb_strrichr($haystack, $needle, $before_needle = \false, $encoding = null)
    {
        return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding);
    }
}
if (!\function_exists('mb_strripos')) {
    function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
    {
        return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding);
    }
}
if (!\function_exists('mb_strrpos')) {
    function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
    {
        return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding);
    }
}
if (!\function_exists('mb_strstr')) {
    function mb_strstr($haystack, $needle, $before_needle = \false, $encoding = null)
    {
        return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding);
    }
}
if (!\function_exists('mb_get_info')) {
    function mb_get_info($type = 'all')
    {
        return p\Mbstring::mb_get_info($type);
    }
}
if (!\function_exists('mb_http_output')) {
    function mb_http_output($encoding = null)
    {
        return p\Mbstring::mb_http_output($encoding);
    }
}
if (!\function_exists('mb_strwidth')) {
    function mb_strwidth($string, $encoding = null)
    {
        return p\Mbstring::mb_strwidth($string, $encoding);
    }
}
if (!\function_exists('mb_substr_count')) {
    function mb_substr_count($haystack, $needle, $encoding = null)
    {
        return p\Mbstring::mb_substr_count($haystack, $needle, $encoding);
    }
}
if (!\function_exists('mb_output_handler')) {
    function mb_output_handler($string, $status)
    {
        return p\Mbstring::mb_output_handler($string, $status);
    }
}
if (!\function_exists('mb_http_input')) {
    function mb_http_input($type = null)
    {
        return p\Mbstring::mb_http_input($type);
    }
}
if (!\function_exists('mb_convert_variables')) {
    function mb_convert_variables($to_encoding, $from_encoding, &...$vars)
    {
        return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars);
    }
}
if (!\function_exists('mb_ord')) {
    function mb_ord($string, $encoding = null)
    {
        return p\Mbstring::mb_ord($string, $encoding);
    }
}
if (!\function_exists('mb_chr')) {
    function mb_chr($codepoint, $encoding = null)
    {
        return p\Mbstring::mb_chr($codepoint, $encoding);
    }
}
if (!\function_exists('mb_scrub')) {
    function mb_scrub($string, $encoding = null)
    {
        $encoding = null === $encoding ? \mb_internal_encoding() : $encoding;
        return \mb_convert_encoding($string, $encoding, $encoding);
    }
}
if (!\function_exists('mb_str_split')) {
    function mb_str_split($string, $length = 1, $encoding = null)
    {
        return p\Mbstring::mb_str_split($string, $length, $encoding);
    }
}
if (\extension_loaded('mbstring')) {
    return;
}
if (!\defined('MB_CASE_UPPER')) {
    \define('MB_CASE_UPPER', 0);
}
if (!\defined('MB_CASE_LOWER')) {
    \define('MB_CASE_LOWER', 1);
}
if (!\defined('MB_CASE_TITLE')) {
    \define('MB_CASE_TITLE', 2);
}
Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1;

return array('A' => 'a', 'B' => 'b', 'C' => 'c', 'D' => 'd', 'E' => 'e', 'F' => 'f', 'G' => 'g', 'H' => 'h', 'I' => 'i', 'J' => 'j', 'K' => 'k', 'L' => 'l', 'M' => 'm', 'N' => 'n', 'O' => 'o', 'P' => 'p', 'Q' => 'q', 'R' => 'r', 'S' => 's', 'T' => 't', 'U' => 'u', 'V' => 'v', 'W' => 'w', 'X' => 'x', 'Y' => 'y', 'Z' => 'z', 'À' => 'à', 'Á' => 'á', 'Â' => 'â', 'Ã' => 'ã', 'Ä' => 'ä', 'Å' => 'å', 'Æ' => 'æ', 'Ç' => 'ç', 'È' => 'è', 'É' => 'é', 'Ê' => 'ê', 'Ë' => 'ë', 'Ì' => 'ì', 'Í' => 'í', 'Î' => 'î', 'Ï' => 'ï', 'Ð' => 'ð', 'Ñ' => 'ñ', 'Ò' => 'ò', 'Ó' => 'ó', 'Ô' => 'ô', 'Õ' => 'õ', 'Ö' => 'ö', 'Ø' => 'ø', 'Ù' => 'ù', 'Ú' => 'ú', 'Û' => 'û', 'Ü' => 'ü', 'Ý' => 'ý', 'Þ' => 'þ', 'Ā' => 'ā', 'Ă' => 'ă', 'Ą' => 'ą', 'Ć' => 'ć', 'Ĉ' => 'ĉ', 'Ċ' => 'ċ', 'Č' => 'č', 'Ď' => 'ď', 'Đ' => 'đ', 'Ē' => 'ē', 'Ĕ' => 'ĕ', 'Ė' => 'ė', 'Ę' => 'ę', 'Ě' => 'ě', 'Ĝ' => 'ĝ', 'Ğ' => 'ğ', 'Ġ' => 'ġ', 'Ģ' => 'ģ', 'Ĥ' => 'ĥ', 'Ħ' => 'ħ', 'Ĩ' => 'ĩ', 'Ī' => 'ī', 'Ĭ' => 'ĭ', 'Į' => 'į', 'İ' => 'i̇', 'IJ' => 'ij', 'Ĵ' => 'ĵ', 'Ķ' => 'ķ', 'Ĺ' => 'ĺ', 'Ļ' => 'ļ', 'Ľ' => 'ľ', 'Ŀ' => 'ŀ', 'Ł' => 'ł', 'Ń' => 'ń', 'Ņ' => 'ņ', 'Ň' => 'ň', 'Ŋ' => 'ŋ', 'Ō' => 'ō', 'Ŏ' => 'ŏ', 'Ő' => 'ő', 'Œ' => 'œ', 'Ŕ' => 'ŕ', 'Ŗ' => 'ŗ', 'Ř' => 'ř', 'Ś' => 'ś', 'Ŝ' => 'ŝ', 'Ş' => 'ş', 'Š' => 'š', 'Ţ' => 'ţ', 'Ť' => 'ť', 'Ŧ' => 'ŧ', 'Ũ' => 'ũ', 'Ū' => 'ū', 'Ŭ' => 'ŭ', 'Ů' => 'ů', 'Ű' => 'ű', 'Ų' => 'ų', 'Ŵ' => 'ŵ', 'Ŷ' => 'ŷ', 'Ÿ' => 'ÿ', 'Ź' => 'ź', 'Ż' => 'ż', 'Ž' => 'ž', 'Ɓ' => 'ɓ', 'Ƃ' => 'ƃ', 'Ƅ' => 'ƅ', 'Ɔ' => 'ɔ', 'Ƈ' => 'ƈ', 'Ɖ' => 'ɖ', 'Ɗ' => 'ɗ', 'Ƌ' => 'ƌ', 'Ǝ' => 'ǝ', 'Ə' => 'ə', 'Ɛ' => 'ɛ', 'Ƒ' => 'ƒ', 'Ɠ' => 'ɠ', 'Ɣ' => 'ɣ', 'Ɩ' => 'ɩ', 'Ɨ' => 'ɨ', 'Ƙ' => 'ƙ', 'Ɯ' => 'ɯ', 'Ɲ' => 'ɲ', 'Ɵ' => 'ɵ', 'Ơ' => 'ơ', 'Ƣ' => 'ƣ', 'Ƥ' => 'ƥ', 'Ʀ' => 'ʀ', 'Ƨ' => 'ƨ', 'Ʃ' => 'ʃ', 'Ƭ' => 'ƭ', 'Ʈ' => 'ʈ', 'Ư' => 'ư', 'Ʊ' => 'ʊ', 'Ʋ' => 'ʋ', 'Ƴ' => 'ƴ', 'Ƶ' => 'ƶ', 'Ʒ' => 'ʒ', 'Ƹ' => 'ƹ', 'Ƽ' => 'ƽ', 'DŽ' => 'dž', 'Dž' => 'dž', 'LJ' => 'lj', 'Lj' => 'lj', 'NJ' => 'nj', 'Nj' => 'nj', 'Ǎ' => 'ǎ', 'Ǐ' => 'ǐ', 'Ǒ' => 'ǒ', 'Ǔ' => 'ǔ', 'Ǖ' => 'ǖ', 'Ǘ' => 'ǘ', 'Ǚ' => 'ǚ', 'Ǜ' => 'ǜ', 'Ǟ' => 'ǟ', 'Ǡ' => 'ǡ', 'Ǣ' => 'ǣ', 'Ǥ' => 'ǥ', 'Ǧ' => 'ǧ', 'Ǩ' => 'ǩ', 'Ǫ' => 'ǫ', 'Ǭ' => 'ǭ', 'Ǯ' => 'ǯ', 'DZ' => 'dz', 'Dz' => 'dz', 'Ǵ' => 'ǵ', 'Ƕ' => 'ƕ', 'Ƿ' => 'ƿ', 'Ǹ' => 'ǹ', 'Ǻ' => 'ǻ', 'Ǽ' => 'ǽ', 'Ǿ' => 'ǿ', 'Ȁ' => 'ȁ', 'Ȃ' => 'ȃ', 'Ȅ' => 'ȅ', 'Ȇ' => 'ȇ', 'Ȉ' => 'ȉ', 'Ȋ' => 'ȋ', 'Ȍ' => 'ȍ', 'Ȏ' => 'ȏ', 'Ȑ' => 'ȑ', 'Ȓ' => 'ȓ', 'Ȕ' => 'ȕ', 'Ȗ' => 'ȗ', 'Ș' => 'ș', 'Ț' => 'ț', 'Ȝ' => 'ȝ', 'Ȟ' => 'ȟ', 'Ƞ' => 'ƞ', 'Ȣ' => 'ȣ', 'Ȥ' => 'ȥ', 'Ȧ' => 'ȧ', 'Ȩ' => 'ȩ', 'Ȫ' => 'ȫ', 'Ȭ' => 'ȭ', 'Ȯ' => 'ȯ', 'Ȱ' => 'ȱ', 'Ȳ' => 'ȳ', 'Ⱥ' => 'ⱥ', 'Ȼ' => 'ȼ', 'Ƚ' => 'ƚ', 'Ⱦ' => 'ⱦ', 'Ɂ' => 'ɂ', 'Ƀ' => 'ƀ', 'Ʉ' => 'ʉ', 'Ʌ' => 'ʌ', 'Ɇ' => 'ɇ', 'Ɉ' => 'ɉ', 'Ɋ' => 'ɋ', 'Ɍ' => 'ɍ', 'Ɏ' => 'ɏ', 'Ͱ' => 'ͱ', 'Ͳ' => 'ͳ', 'Ͷ' => 'ͷ', 'Ϳ' => 'ϳ', 'Ά' => 'ά', 'Έ' => 'έ', 'Ή' => 'ή', 'Ί' => 'ί', 'Ό' => 'ό', 'Ύ' => 'ύ', 'Ώ' => 'ώ', 'Α' => 'α', 'Β' => 'β', 'Γ' => 'γ', 'Δ' => 'δ', 'Ε' => 'ε', 'Ζ' => 'ζ', 'Η' => 'η', 'Θ' => 'θ', 'Ι' => 'ι', 'Κ' => 'κ', 'Λ' => 'λ', 'Μ' => 'μ', 'Ν' => 'ν', 'Ξ' => 'ξ', 'Ο' => 'ο', 'Π' => 'π', 'Ρ' => 'ρ', 'Σ' => 'σ', 'Τ' => 'τ', 'Υ' => 'υ', 'Φ' => 'φ', 'Χ' => 'χ', 'Ψ' => 'ψ', 'Ω' => 'ω', 'Ϊ' => 'ϊ', 'Ϋ' => 'ϋ', 'Ϗ' => 'ϗ', 'Ϙ' => 'ϙ', 'Ϛ' => 'ϛ', 'Ϝ' => 'ϝ', 'Ϟ' => 'ϟ', 'Ϡ' => 'ϡ', 'Ϣ' => 'ϣ', 'Ϥ' => 'ϥ', 'Ϧ' => 'ϧ', 'Ϩ' => 'ϩ', 'Ϫ' => 'ϫ', 'Ϭ' => 'ϭ', 'Ϯ' => 'ϯ', 'ϴ' => 'θ', 'Ϸ' => 'ϸ', 'Ϲ' => 'ϲ', 'Ϻ' => 'ϻ', 'Ͻ' => 'ͻ', 'Ͼ' => 'ͼ', 'Ͽ' => 'ͽ', 'Ѐ' => 'ѐ', 'Ё' => 'ё', 'Ђ' => 'ђ', 'Ѓ' => 'ѓ', 'Є' => 'є', 'Ѕ' => 'ѕ', 'І' => 'і', 'Ї' => 'ї', 'Ј' => 'ј', 'Љ' => 'љ', 'Њ' => 'њ', 'Ћ' => 'ћ', 'Ќ' => 'ќ', 'Ѝ' => 'ѝ', 'Ў' => 'ў', 'Џ' => 'џ', 'А' => 'а', 'Б' => 'б', 'В' => 'в', 'Г' => 'г', 'Д' => 'д', 'Е' => 'е', 'Ж' => 'ж', 'З' => 'з', 'И' => 'и', 'Й' => 'й', 'К' => 'к', 'Л' => 'л', 'М' => 'м', 'Н' => 'н', 'О' => 'о', 'П' => 'п', 'Р' => 'р', 'С' => 'с', 'Т' => 'т', 'У' => 'у', 'Ф' => 'ф', 'Х' => 'х', 'Ц' => 'ц', 'Ч' => 'ч', 'Ш' => 'ш', 'Щ' => 'щ', 'Ъ' => 'ъ', 'Ы' => 'ы', 'Ь' => 'ь', 'Э' => 'э', 'Ю' => 'ю', 'Я' => 'я', 'Ѡ' => 'ѡ', 'Ѣ' => 'ѣ', 'Ѥ' => 'ѥ', 'Ѧ' => 'ѧ', 'Ѩ' => 'ѩ', 'Ѫ' => 'ѫ', 'Ѭ' => 'ѭ', 'Ѯ' => 'ѯ', 'Ѱ' => 'ѱ', 'Ѳ' => 'ѳ', 'Ѵ' => 'ѵ', 'Ѷ' => 'ѷ', 'Ѹ' => 'ѹ', 'Ѻ' => 'ѻ', 'Ѽ' => 'ѽ', 'Ѿ' => 'ѿ', 'Ҁ' => 'ҁ', 'Ҋ' => 'ҋ', 'Ҍ' => 'ҍ', 'Ҏ' => 'ҏ', 'Ґ' => 'ґ', 'Ғ' => 'ғ', 'Ҕ' => 'ҕ', 'Җ' => 'җ', 'Ҙ' => 'ҙ', 'Қ' => 'қ', 'Ҝ' => 'ҝ', 'Ҟ' => 'ҟ', 'Ҡ' => 'ҡ', 'Ң' => 'ң', 'Ҥ' => 'ҥ', 'Ҧ' => 'ҧ', 'Ҩ' => 'ҩ', 'Ҫ' => 'ҫ', 'Ҭ' => 'ҭ', 'Ү' => 'ү', 'Ұ' => 'ұ', 'Ҳ' => 'ҳ', 'Ҵ' => 'ҵ', 'Ҷ' => 'ҷ', 'Ҹ' => 'ҹ', 'Һ' => 'һ', 'Ҽ' => 'ҽ', 'Ҿ' => 'ҿ', 'Ӏ' => 'ӏ', 'Ӂ' => 'ӂ', 'Ӄ' => 'ӄ', 'Ӆ' => 'ӆ', 'Ӈ' => 'ӈ', 'Ӊ' => 'ӊ', 'Ӌ' => 'ӌ', 'Ӎ' => 'ӎ', 'Ӑ' => 'ӑ', 'Ӓ' => 'ӓ', 'Ӕ' => 'ӕ', 'Ӗ' => 'ӗ', 'Ә' => 'ә', 'Ӛ' => 'ӛ', 'Ӝ' => 'ӝ', 'Ӟ' => 'ӟ', 'Ӡ' => 'ӡ', 'Ӣ' => 'ӣ', 'Ӥ' => 'ӥ', 'Ӧ' => 'ӧ', 'Ө' => 'ө', 'Ӫ' => 'ӫ', 'Ӭ' => 'ӭ', 'Ӯ' => 'ӯ', 'Ӱ' => 'ӱ', 'Ӳ' => 'ӳ', 'Ӵ' => 'ӵ', 'Ӷ' => 'ӷ', 'Ӹ' => 'ӹ', 'Ӻ' => 'ӻ', 'Ӽ' => 'ӽ', 'Ӿ' => 'ӿ', 'Ԁ' => 'ԁ', 'Ԃ' => 'ԃ', 'Ԅ' => 'ԅ', 'Ԇ' => 'ԇ', 'Ԉ' => 'ԉ', 'Ԋ' => 'ԋ', 'Ԍ' => 'ԍ', 'Ԏ' => 'ԏ', 'Ԑ' => 'ԑ', 'Ԓ' => 'ԓ', 'Ԕ' => 'ԕ', 'Ԗ' => 'ԗ', 'Ԙ' => 'ԙ', 'Ԛ' => 'ԛ', 'Ԝ' => 'ԝ', 'Ԟ' => 'ԟ', 'Ԡ' => 'ԡ', 'Ԣ' => 'ԣ', 'Ԥ' => 'ԥ', 'Ԧ' => 'ԧ', 'Ԩ' => 'ԩ', 'Ԫ' => 'ԫ', 'Ԭ' => 'ԭ', 'Ԯ' => 'ԯ', 'Ա' => 'ա', 'Բ' => 'բ', 'Գ' => 'գ', 'Դ' => 'դ', 'Ե' => 'ե', 'Զ' => 'զ', 'Է' => 'է', 'Ը' => 'ը', 'Թ' => 'թ', 'Ժ' => 'ժ', 'Ի' => 'ի', 'Լ' => 'լ', 'Խ' => 'խ', 'Ծ' => 'ծ', 'Կ' => 'կ', 'Հ' => 'հ', 'Ձ' => 'ձ', 'Ղ' => 'ղ', 'Ճ' => 'ճ', 'Մ' => 'մ', 'Յ' => 'յ', 'Ն' => 'ն', 'Շ' => 'շ', 'Ո' => 'ո', 'Չ' => 'չ', 'Պ' => 'պ', 'Ջ' => 'ջ', 'Ռ' => 'ռ', 'Ս' => 'ս', 'Վ' => 'վ', 'Տ' => 'տ', 'Ր' => 'ր', 'Ց' => 'ց', 'Ւ' => 'ւ', 'Փ' => 'փ', 'Ք' => 'ք', 'Օ' => 'օ', 'Ֆ' => 'ֆ', 'Ⴀ' => 'ⴀ', 'Ⴁ' => 'ⴁ', 'Ⴂ' => 'ⴂ', 'Ⴃ' => 'ⴃ', 'Ⴄ' => 'ⴄ', 'Ⴅ' => 'ⴅ', 'Ⴆ' => 'ⴆ', 'Ⴇ' => 'ⴇ', 'Ⴈ' => 'ⴈ', 'Ⴉ' => 'ⴉ', 'Ⴊ' => 'ⴊ', 'Ⴋ' => 'ⴋ', 'Ⴌ' => 'ⴌ', 'Ⴍ' => 'ⴍ', 'Ⴎ' => 'ⴎ', 'Ⴏ' => 'ⴏ', 'Ⴐ' => 'ⴐ', 'Ⴑ' => 'ⴑ', 'Ⴒ' => 'ⴒ', 'Ⴓ' => 'ⴓ', 'Ⴔ' => 'ⴔ', 'Ⴕ' => 'ⴕ', 'Ⴖ' => 'ⴖ', 'Ⴗ' => 'ⴗ', 'Ⴘ' => 'ⴘ', 'Ⴙ' => 'ⴙ', 'Ⴚ' => 'ⴚ', 'Ⴛ' => 'ⴛ', 'Ⴜ' => 'ⴜ', 'Ⴝ' => 'ⴝ', 'Ⴞ' => 'ⴞ', 'Ⴟ' => 'ⴟ', 'Ⴠ' => 'ⴠ', 'Ⴡ' => 'ⴡ', 'Ⴢ' => 'ⴢ', 'Ⴣ' => 'ⴣ', 'Ⴤ' => 'ⴤ', 'Ⴥ' => 'ⴥ', 'Ⴧ' => 'ⴧ', 'Ⴭ' => 'ⴭ', 'Ꭰ' => 'ꭰ', 'Ꭱ' => 'ꭱ', 'Ꭲ' => 'ꭲ', 'Ꭳ' => 'ꭳ', 'Ꭴ' => 'ꭴ', 'Ꭵ' => 'ꭵ', 'Ꭶ' => 'ꭶ', 'Ꭷ' => 'ꭷ', 'Ꭸ' => 'ꭸ', 'Ꭹ' => 'ꭹ', 'Ꭺ' => 'ꭺ', 'Ꭻ' => 'ꭻ', 'Ꭼ' => 'ꭼ', 'Ꭽ' => 'ꭽ', 'Ꭾ' => 'ꭾ', 'Ꭿ' => 'ꭿ', 'Ꮀ' => 'ꮀ', 'Ꮁ' => 'ꮁ', 'Ꮂ' => 'ꮂ', 'Ꮃ' => 'ꮃ', 'Ꮄ' => 'ꮄ', 'Ꮅ' => 'ꮅ', 'Ꮆ' => 'ꮆ', 'Ꮇ' => 'ꮇ', 'Ꮈ' => 'ꮈ', 'Ꮉ' => 'ꮉ', 'Ꮊ' => 'ꮊ', 'Ꮋ' => 'ꮋ', 'Ꮌ' => 'ꮌ', 'Ꮍ' => 'ꮍ', 'Ꮎ' => 'ꮎ', 'Ꮏ' => 'ꮏ', 'Ꮐ' => 'ꮐ', 'Ꮑ' => 'ꮑ', 'Ꮒ' => 'ꮒ', 'Ꮓ' => 'ꮓ', 'Ꮔ' => 'ꮔ', 'Ꮕ' => 'ꮕ', 'Ꮖ' => 'ꮖ', 'Ꮗ' => 'ꮗ', 'Ꮘ' => 'ꮘ', 'Ꮙ' => 'ꮙ', 'Ꮚ' => 'ꮚ', 'Ꮛ' => 'ꮛ', 'Ꮜ' => 'ꮜ', 'Ꮝ' => 'ꮝ', 'Ꮞ' => 'ꮞ', 'Ꮟ' => 'ꮟ', 'Ꮠ' => 'ꮠ', 'Ꮡ' => 'ꮡ', 'Ꮢ' => 'ꮢ', 'Ꮣ' => 'ꮣ', 'Ꮤ' => 'ꮤ', 'Ꮥ' => 'ꮥ', 'Ꮦ' => 'ꮦ', 'Ꮧ' => 'ꮧ', 'Ꮨ' => 'ꮨ', 'Ꮩ' => 'ꮩ', 'Ꮪ' => 'ꮪ', 'Ꮫ' => 'ꮫ', 'Ꮬ' => 'ꮬ', 'Ꮭ' => 'ꮭ', 'Ꮮ' => 'ꮮ', 'Ꮯ' => 'ꮯ', 'Ꮰ' => 'ꮰ', 'Ꮱ' => 'ꮱ', 'Ꮲ' => 'ꮲ', 'Ꮳ' => 'ꮳ', 'Ꮴ' => 'ꮴ', 'Ꮵ' => 'ꮵ', 'Ꮶ' => 'ꮶ', 'Ꮷ' => 'ꮷ', 'Ꮸ' => 'ꮸ', 'Ꮹ' => 'ꮹ', 'Ꮺ' => 'ꮺ', 'Ꮻ' => 'ꮻ', 'Ꮼ' => 'ꮼ', 'Ꮽ' => 'ꮽ', 'Ꮾ' => 'ꮾ', 'Ꮿ' => 'ꮿ', 'Ᏸ' => 'ᏸ', 'Ᏹ' => 'ᏹ', 'Ᏺ' => 'ᏺ', 'Ᏻ' => 'ᏻ', 'Ᏼ' => 'ᏼ', 'Ᏽ' => 'ᏽ', 'Ა' => 'ა', 'Ბ' => 'ბ', 'Გ' => 'გ', 'Დ' => 'დ', 'Ე' => 'ე', 'Ვ' => 'ვ', 'Ზ' => 'ზ', 'Თ' => 'თ', 'Ი' => 'ი', 'Კ' => 'კ', 'Ლ' => 'ლ', 'Მ' => 'მ', 'Ნ' => 'ნ', 'Ო' => 'ო', 'Პ' => 'პ', 'Ჟ' => 'ჟ', 'Რ' => 'რ', 'Ს' => 'ს', 'Ტ' => 'ტ', 'Უ' => 'უ', 'Ფ' => 'ფ', 'Ქ' => 'ქ', 'Ღ' => 'ღ', 'Ყ' => 'ყ', 'Შ' => 'შ', 'Ჩ' => 'ჩ', 'Ც' => 'ც', 'Ძ' => 'ძ', 'Წ' => 'წ', 'Ჭ' => 'ჭ', 'Ხ' => 'ხ', 'Ჯ' => 'ჯ', 'Ჰ' => 'ჰ', 'Ჱ' => 'ჱ', 'Ჲ' => 'ჲ', 'Ჳ' => 'ჳ', 'Ჴ' => 'ჴ', 'Ჵ' => 'ჵ', 'Ჶ' => 'ჶ', 'Ჷ' => 'ჷ', 'Ჸ' => 'ჸ', 'Ჹ' => 'ჹ', 'Ჺ' => 'ჺ', 'Ჽ' => 'ჽ', 'Ჾ' => 'ჾ', 'Ჿ' => 'ჿ', 'Ḁ' => 'ḁ', 'Ḃ' => 'ḃ', 'Ḅ' => 'ḅ', 'Ḇ' => 'ḇ', 'Ḉ' => 'ḉ', 'Ḋ' => 'ḋ', 'Ḍ' => 'ḍ', 'Ḏ' => 'ḏ', 'Ḑ' => 'ḑ', 'Ḓ' => 'ḓ', 'Ḕ' => 'ḕ', 'Ḗ' => 'ḗ', 'Ḙ' => 'ḙ', 'Ḛ' => 'ḛ', 'Ḝ' => 'ḝ', 'Ḟ' => 'ḟ', 'Ḡ' => 'ḡ', 'Ḣ' => 'ḣ', 'Ḥ' => 'ḥ', 'Ḧ' => 'ḧ', 'Ḩ' => 'ḩ', 'Ḫ' => 'ḫ', 'Ḭ' => 'ḭ', 'Ḯ' => 'ḯ', 'Ḱ' => 'ḱ', 'Ḳ' => 'ḳ', 'Ḵ' => 'ḵ', 'Ḷ' => 'ḷ', 'Ḹ' => 'ḹ', 'Ḻ' => 'ḻ', 'Ḽ' => 'ḽ', 'Ḿ' => 'ḿ', 'Ṁ' => 'ṁ', 'Ṃ' => 'ṃ', 'Ṅ' => 'ṅ', 'Ṇ' => 'ṇ', 'Ṉ' => 'ṉ', 'Ṋ' => 'ṋ', 'Ṍ' => 'ṍ', 'Ṏ' => 'ṏ', 'Ṑ' => 'ṑ', 'Ṓ' => 'ṓ', 'Ṕ' => 'ṕ', 'Ṗ' => 'ṗ', 'Ṙ' => 'ṙ', 'Ṛ' => 'ṛ', 'Ṝ' => 'ṝ', 'Ṟ' => 'ṟ', 'Ṡ' => 'ṡ', 'Ṣ' => 'ṣ', 'Ṥ' => 'ṥ', 'Ṧ' => 'ṧ', 'Ṩ' => 'ṩ', 'Ṫ' => 'ṫ', 'Ṭ' => 'ṭ', 'Ṯ' => 'ṯ', 'Ṱ' => 'ṱ', 'Ṳ' => 'ṳ', 'Ṵ' => 'ṵ', 'Ṷ' => 'ṷ', 'Ṹ' => 'ṹ', 'Ṻ' => 'ṻ', 'Ṽ' => 'ṽ', 'Ṿ' => 'ṿ', 'Ẁ' => 'ẁ', 'Ẃ' => 'ẃ', 'Ẅ' => 'ẅ', 'Ẇ' => 'ẇ', 'Ẉ' => 'ẉ', 'Ẋ' => 'ẋ', 'Ẍ' => 'ẍ', 'Ẏ' => 'ẏ', 'Ẑ' => 'ẑ', 'Ẓ' => 'ẓ', 'Ẕ' => 'ẕ', 'ẞ' => 'ß', 'Ạ' => 'ạ', 'Ả' => 'ả', 'Ấ' => 'ấ', 'Ầ' => 'ầ', 'Ẩ' => 'ẩ', 'Ẫ' => 'ẫ', 'Ậ' => 'ậ', 'Ắ' => 'ắ', 'Ằ' => 'ằ', 'Ẳ' => 'ẳ', 'Ẵ' => 'ẵ', 'Ặ' => 'ặ', 'Ẹ' => 'ẹ', 'Ẻ' => 'ẻ', 'Ẽ' => 'ẽ', 'Ế' => 'ế', 'Ề' => 'ề', 'Ể' => 'ể', 'Ễ' => 'ễ', 'Ệ' => 'ệ', 'Ỉ' => 'ỉ', 'Ị' => 'ị', 'Ọ' => 'ọ', 'Ỏ' => 'ỏ', 'Ố' => 'ố', 'Ồ' => 'ồ', 'Ổ' => 'ổ', 'Ỗ' => 'ỗ', 'Ộ' => 'ộ', 'Ớ' => 'ớ', 'Ờ' => 'ờ', 'Ở' => 'ở', 'Ỡ' => 'ỡ', 'Ợ' => 'ợ', 'Ụ' => 'ụ', 'Ủ' => 'ủ', 'Ứ' => 'ứ', 'Ừ' => 'ừ', 'Ử' => 'ử', 'Ữ' => 'ữ', 'Ự' => 'ự', 'Ỳ' => 'ỳ', 'Ỵ' => 'ỵ', 'Ỷ' => 'ỷ', 'Ỹ' => 'ỹ', 'Ỻ' => 'ỻ', 'Ỽ' => 'ỽ', 'Ỿ' => 'ỿ', 'Ἀ' => 'ἀ', 'Ἁ' => 'ἁ', 'Ἂ' => 'ἂ', 'Ἃ' => 'ἃ', 'Ἄ' => 'ἄ', 'Ἅ' => 'ἅ', 'Ἆ' => 'ἆ', 'Ἇ' => 'ἇ', 'Ἐ' => 'ἐ', 'Ἑ' => 'ἑ', 'Ἒ' => 'ἒ', 'Ἓ' => 'ἓ', 'Ἔ' => 'ἔ', 'Ἕ' => 'ἕ', 'Ἠ' => 'ἠ', 'Ἡ' => 'ἡ', 'Ἢ' => 'ἢ', 'Ἣ' => 'ἣ', 'Ἤ' => 'ἤ', 'Ἥ' => 'ἥ', 'Ἦ' => 'ἦ', 'Ἧ' => 'ἧ', 'Ἰ' => 'ἰ', 'Ἱ' => 'ἱ', 'Ἲ' => 'ἲ', 'Ἳ' => 'ἳ', 'Ἴ' => 'ἴ', 'Ἵ' => 'ἵ', 'Ἶ' => 'ἶ', 'Ἷ' => 'ἷ', 'Ὀ' => 'ὀ', 'Ὁ' => 'ὁ', 'Ὂ' => 'ὂ', 'Ὃ' => 'ὃ', 'Ὄ' => 'ὄ', 'Ὅ' => 'ὅ', 'Ὑ' => 'ὑ', 'Ὓ' => 'ὓ', 'Ὕ' => 'ὕ', 'Ὗ' => 'ὗ', 'Ὠ' => 'ὠ', 'Ὡ' => 'ὡ', 'Ὢ' => 'ὢ', 'Ὣ' => 'ὣ', 'Ὤ' => 'ὤ', 'Ὥ' => 'ὥ', 'Ὦ' => 'ὦ', 'Ὧ' => 'ὧ', 'ᾈ' => 'ᾀ', 'ᾉ' => 'ᾁ', 'ᾊ' => 'ᾂ', 'ᾋ' => 'ᾃ', 'ᾌ' => 'ᾄ', 'ᾍ' => 'ᾅ', 'ᾎ' => 'ᾆ', 'ᾏ' => 'ᾇ', 'ᾘ' => 'ᾐ', 'ᾙ' => 'ᾑ', 'ᾚ' => 'ᾒ', 'ᾛ' => 'ᾓ', 'ᾜ' => 'ᾔ', 'ᾝ' => 'ᾕ', 'ᾞ' => 'ᾖ', 'ᾟ' => 'ᾗ', 'ᾨ' => 'ᾠ', 'ᾩ' => 'ᾡ', 'ᾪ' => 'ᾢ', 'ᾫ' => 'ᾣ', 'ᾬ' => 'ᾤ', 'ᾭ' => 'ᾥ', 'ᾮ' => 'ᾦ', 'ᾯ' => 'ᾧ', 'Ᾰ' => 'ᾰ', 'Ᾱ' => 'ᾱ', 'Ὰ' => 'ὰ', 'Ά' => 'ά', 'ᾼ' => 'ᾳ', 'Ὲ' => 'ὲ', 'Έ' => 'έ', 'Ὴ' => 'ὴ', 'Ή' => 'ή', 'ῌ' => 'ῃ', 'Ῐ' => 'ῐ', 'Ῑ' => 'ῑ', 'Ὶ' => 'ὶ', 'Ί' => 'ί', 'Ῠ' => 'ῠ', 'Ῡ' => 'ῡ', 'Ὺ' => 'ὺ', 'Ύ' => 'ύ', 'Ῥ' => 'ῥ', 'Ὸ' => 'ὸ', 'Ό' => 'ό', 'Ὼ' => 'ὼ', 'Ώ' => 'ώ', 'ῼ' => 'ῳ', 'Ω' => 'ω', 'K' => 'k', 'Å' => 'å', 'Ⅎ' => 'ⅎ', 'Ⅰ' => 'ⅰ', 'Ⅱ' => 'ⅱ', 'Ⅲ' => 'ⅲ', 'Ⅳ' => 'ⅳ', 'Ⅴ' => 'ⅴ', 'Ⅵ' => 'ⅵ', 'Ⅶ' => 'ⅶ', 'Ⅷ' => 'ⅷ', 'Ⅸ' => 'ⅸ', 'Ⅹ' => 'ⅹ', 'Ⅺ' => 'ⅺ', 'Ⅻ' => 'ⅻ', 'Ⅼ' => 'ⅼ', 'Ⅽ' => 'ⅽ', 'Ⅾ' => 'ⅾ', 'Ⅿ' => 'ⅿ', 'Ↄ' => 'ↄ', 'Ⓐ' => 'ⓐ', 'Ⓑ' => 'ⓑ', 'Ⓒ' => 'ⓒ', 'Ⓓ' => 'ⓓ', 'Ⓔ' => 'ⓔ', 'Ⓕ' => 'ⓕ', 'Ⓖ' => 'ⓖ', 'Ⓗ' => 'ⓗ', 'Ⓘ' => 'ⓘ', 'Ⓙ' => 'ⓙ', 'Ⓚ' => 'ⓚ', 'Ⓛ' => 'ⓛ', 'Ⓜ' => 'ⓜ', 'Ⓝ' => 'ⓝ', 'Ⓞ' => 'ⓞ', 'Ⓟ' => 'ⓟ', 'Ⓠ' => 'ⓠ', 'Ⓡ' => 'ⓡ', 'Ⓢ' => 'ⓢ', 'Ⓣ' => 'ⓣ', 'Ⓤ' => 'ⓤ', 'Ⓥ' => 'ⓥ', 'Ⓦ' => 'ⓦ', 'Ⓧ' => 'ⓧ', 'Ⓨ' => 'ⓨ', 'Ⓩ' => 'ⓩ', 'Ⰰ' => 'ⰰ', 'Ⰱ' => 'ⰱ', 'Ⰲ' => 'ⰲ', 'Ⰳ' => 'ⰳ', 'Ⰴ' => 'ⰴ', 'Ⰵ' => 'ⰵ', 'Ⰶ' => 'ⰶ', 'Ⰷ' => 'ⰷ', 'Ⰸ' => 'ⰸ', 'Ⰹ' => 'ⰹ', 'Ⰺ' => 'ⰺ', 'Ⰻ' => 'ⰻ', 'Ⰼ' => 'ⰼ', 'Ⰽ' => 'ⰽ', 'Ⰾ' => 'ⰾ', 'Ⰿ' => 'ⰿ', 'Ⱀ' => 'ⱀ', 'Ⱁ' => 'ⱁ', 'Ⱂ' => 'ⱂ', 'Ⱃ' => 'ⱃ', 'Ⱄ' => 'ⱄ', 'Ⱅ' => 'ⱅ', 'Ⱆ' => 'ⱆ', 'Ⱇ' => 'ⱇ', 'Ⱈ' => 'ⱈ', 'Ⱉ' => 'ⱉ', 'Ⱊ' => 'ⱊ', 'Ⱋ' => 'ⱋ', 'Ⱌ' => 'ⱌ', 'Ⱍ' => 'ⱍ', 'Ⱎ' => 'ⱎ', 'Ⱏ' => 'ⱏ', 'Ⱐ' => 'ⱐ', 'Ⱑ' => 'ⱑ', 'Ⱒ' => 'ⱒ', 'Ⱓ' => 'ⱓ', 'Ⱔ' => 'ⱔ', 'Ⱕ' => 'ⱕ', 'Ⱖ' => 'ⱖ', 'Ⱗ' => 'ⱗ', 'Ⱘ' => 'ⱘ', 'Ⱙ' => 'ⱙ', 'Ⱚ' => 'ⱚ', 'Ⱛ' => 'ⱛ', 'Ⱜ' => 'ⱜ', 'Ⱝ' => 'ⱝ', 'Ⱞ' => 'ⱞ', 'Ⱡ' => 'ⱡ', 'Ɫ' => 'ɫ', 'Ᵽ' => 'ᵽ', 'Ɽ' => 'ɽ', 'Ⱨ' => 'ⱨ', 'Ⱪ' => 'ⱪ', 'Ⱬ' => 'ⱬ', 'Ɑ' => 'ɑ', 'Ɱ' => 'ɱ', 'Ɐ' => 'ɐ', 'Ɒ' => 'ɒ', 'Ⱳ' => 'ⱳ', 'Ⱶ' => 'ⱶ', 'Ȿ' => 'ȿ', 'Ɀ' => 'ɀ', 'Ⲁ' => 'ⲁ', 'Ⲃ' => 'ⲃ', 'Ⲅ' => 'ⲅ', 'Ⲇ' => 'ⲇ', 'Ⲉ' => 'ⲉ', 'Ⲋ' => 'ⲋ', 'Ⲍ' => 'ⲍ', 'Ⲏ' => 'ⲏ', 'Ⲑ' => 'ⲑ', 'Ⲓ' => 'ⲓ', 'Ⲕ' => 'ⲕ', 'Ⲗ' => 'ⲗ', 'Ⲙ' => 'ⲙ', 'Ⲛ' => 'ⲛ', 'Ⲝ' => 'ⲝ', 'Ⲟ' => 'ⲟ', 'Ⲡ' => 'ⲡ', 'Ⲣ' => 'ⲣ', 'Ⲥ' => 'ⲥ', 'Ⲧ' => 'ⲧ', 'Ⲩ' => 'ⲩ', 'Ⲫ' => 'ⲫ', 'Ⲭ' => 'ⲭ', 'Ⲯ' => 'ⲯ', 'Ⲱ' => 'ⲱ', 'Ⲳ' => 'ⲳ', 'Ⲵ' => 'ⲵ', 'Ⲷ' => 'ⲷ', 'Ⲹ' => 'ⲹ', 'Ⲻ' => 'ⲻ', 'Ⲽ' => 'ⲽ', 'Ⲿ' => 'ⲿ', 'Ⳁ' => 'ⳁ', 'Ⳃ' => 'ⳃ', 'Ⳅ' => 'ⳅ', 'Ⳇ' => 'ⳇ', 'Ⳉ' => 'ⳉ', 'Ⳋ' => 'ⳋ', 'Ⳍ' => 'ⳍ', 'Ⳏ' => 'ⳏ', 'Ⳑ' => 'ⳑ', 'Ⳓ' => 'ⳓ', 'Ⳕ' => 'ⳕ', 'Ⳗ' => 'ⳗ', 'Ⳙ' => 'ⳙ', 'Ⳛ' => 'ⳛ', 'Ⳝ' => 'ⳝ', 'Ⳟ' => 'ⳟ', 'Ⳡ' => 'ⳡ', 'Ⳣ' => 'ⳣ', 'Ⳬ' => 'ⳬ', 'Ⳮ' => 'ⳮ', 'Ⳳ' => 'ⳳ', 'Ꙁ' => 'ꙁ', 'Ꙃ' => 'ꙃ', 'Ꙅ' => 'ꙅ', 'Ꙇ' => 'ꙇ', 'Ꙉ' => 'ꙉ', 'Ꙋ' => 'ꙋ', 'Ꙍ' => 'ꙍ', 'Ꙏ' => 'ꙏ', 'Ꙑ' => 'ꙑ', 'Ꙓ' => 'ꙓ', 'Ꙕ' => 'ꙕ', 'Ꙗ' => 'ꙗ', 'Ꙙ' => 'ꙙ', 'Ꙛ' => 'ꙛ', 'Ꙝ' => 'ꙝ', 'Ꙟ' => 'ꙟ', 'Ꙡ' => 'ꙡ', 'Ꙣ' => 'ꙣ', 'Ꙥ' => 'ꙥ', 'Ꙧ' => 'ꙧ', 'Ꙩ' => 'ꙩ', 'Ꙫ' => 'ꙫ', 'Ꙭ' => 'ꙭ', 'Ꚁ' => 'ꚁ', 'Ꚃ' => 'ꚃ', 'Ꚅ' => 'ꚅ', 'Ꚇ' => 'ꚇ', 'Ꚉ' => 'ꚉ', 'Ꚋ' => 'ꚋ', 'Ꚍ' => 'ꚍ', 'Ꚏ' => 'ꚏ', 'Ꚑ' => 'ꚑ', 'Ꚓ' => 'ꚓ', 'Ꚕ' => 'ꚕ', 'Ꚗ' => 'ꚗ', 'Ꚙ' => 'ꚙ', 'Ꚛ' => 'ꚛ', 'Ꜣ' => 'ꜣ', 'Ꜥ' => 'ꜥ', 'Ꜧ' => 'ꜧ', 'Ꜩ' => 'ꜩ', 'Ꜫ' => 'ꜫ', 'Ꜭ' => 'ꜭ', 'Ꜯ' => 'ꜯ', 'Ꜳ' => 'ꜳ', 'Ꜵ' => 'ꜵ', 'Ꜷ' => 'ꜷ', 'Ꜹ' => 'ꜹ', 'Ꜻ' => 'ꜻ', 'Ꜽ' => 'ꜽ', 'Ꜿ' => 'ꜿ', 'Ꝁ' => 'ꝁ', 'Ꝃ' => 'ꝃ', 'Ꝅ' => 'ꝅ', 'Ꝇ' => 'ꝇ', 'Ꝉ' => 'ꝉ', 'Ꝋ' => 'ꝋ', 'Ꝍ' => 'ꝍ', 'Ꝏ' => 'ꝏ', 'Ꝑ' => 'ꝑ', 'Ꝓ' => 'ꝓ', 'Ꝕ' => 'ꝕ', 'Ꝗ' => 'ꝗ', 'Ꝙ' => 'ꝙ', 'Ꝛ' => 'ꝛ', 'Ꝝ' => 'ꝝ', 'Ꝟ' => 'ꝟ', 'Ꝡ' => 'ꝡ', 'Ꝣ' => 'ꝣ', 'Ꝥ' => 'ꝥ', 'Ꝧ' => 'ꝧ', 'Ꝩ' => 'ꝩ', 'Ꝫ' => 'ꝫ', 'Ꝭ' => 'ꝭ', 'Ꝯ' => 'ꝯ', 'Ꝺ' => 'ꝺ', 'Ꝼ' => 'ꝼ', 'Ᵹ' => 'ᵹ', 'Ꝿ' => 'ꝿ', 'Ꞁ' => 'ꞁ', 'Ꞃ' => 'ꞃ', 'Ꞅ' => 'ꞅ', 'Ꞇ' => 'ꞇ', 'Ꞌ' => 'ꞌ', 'Ɥ' => 'ɥ', 'Ꞑ' => 'ꞑ', 'Ꞓ' => 'ꞓ', 'Ꞗ' => 'ꞗ', 'Ꞙ' => 'ꞙ', 'Ꞛ' => 'ꞛ', 'Ꞝ' => 'ꞝ', 'Ꞟ' => 'ꞟ', 'Ꞡ' => 'ꞡ', 'Ꞣ' => 'ꞣ', 'Ꞥ' => 'ꞥ', 'Ꞧ' => 'ꞧ', 'Ꞩ' => 'ꞩ', 'Ɦ' => 'ɦ', 'Ɜ' => 'ɜ', 'Ɡ' => 'ɡ', 'Ɬ' => 'ɬ', 'Ɪ' => 'ɪ', 'Ʞ' => 'ʞ', 'Ʇ' => 'ʇ', 'Ʝ' => 'ʝ', 'Ꭓ' => 'ꭓ', 'Ꞵ' => 'ꞵ', 'Ꞷ' => 'ꞷ', 'Ꞹ' => 'ꞹ', 'Ꞻ' => 'ꞻ', 'Ꞽ' => 'ꞽ', 'Ꞿ' => 'ꞿ', 'Ꟃ' => 'ꟃ', 'Ꞔ' => 'ꞔ', 'Ʂ' => 'ʂ', 'Ᶎ' => 'ᶎ', 'Ꟈ' => 'ꟈ', 'Ꟊ' => 'ꟊ', 'Ꟶ' => 'ꟶ', 'A' => 'a', 'B' => 'b', 'C' => 'c', 'D' => 'd', 'E' => 'e', 'F' => 'f', 'G' => 'g', 'H' => 'h', 'I' => 'i', 'J' => 'j', 'K' => 'k', 'L' => 'l', 'M' => 'm', 'N' => 'n', 'O' => 'o', 'P' => 'p', 'Q' => 'q', 'R' => 'r', 'S' => 's', 'T' => 't', 'U' => 'u', 'V' => 'v', 'W' => 'w', 'X' => 'x', 'Y' => 'y', 'Z' => 'z', '𐐀' => '𐐨', '𐐁' => '𐐩', '𐐂' => '𐐪', '𐐃' => '𐐫', '𐐄' => '𐐬', '𐐅' => '𐐭', '𐐆' => '𐐮', '𐐇' => '𐐯', '𐐈' => '𐐰', '𐐉' => '𐐱', '𐐊' => '𐐲', '𐐋' => '𐐳', '𐐌' => '𐐴', '𐐍' => '𐐵', '𐐎' => '𐐶', '𐐏' => '𐐷', '𐐐' => '𐐸', '𐐑' => '𐐹', '𐐒' => '𐐺', '𐐓' => '𐐻', '𐐔' => '𐐼', '𐐕' => '𐐽', '𐐖' => '𐐾', '𐐗' => '𐐿', '𐐘' => '𐑀', '𐐙' => '𐑁', '𐐚' => '𐑂', '𐐛' => '𐑃', '𐐜' => '𐑄', '𐐝' => '𐑅', '𐐞' => '𐑆', '𐐟' => '𐑇', '𐐠' => '𐑈', '𐐡' => '𐑉', '𐐢' => '𐑊', '𐐣' => '𐑋', '𐐤' => '𐑌', '𐐥' => '𐑍', '𐐦' => '𐑎', '𐐧' => '𐑏', '𐒰' => '𐓘', '𐒱' => '𐓙', '𐒲' => '𐓚', '𐒳' => '𐓛', '𐒴' => '𐓜', '𐒵' => '𐓝', '𐒶' => '𐓞', '𐒷' => '𐓟', '𐒸' => '𐓠', '𐒹' => '𐓡', '𐒺' => '𐓢', '𐒻' => '𐓣', '𐒼' => '𐓤', '𐒽' => '𐓥', '𐒾' => '𐓦', '𐒿' => '𐓧', '𐓀' => '𐓨', '𐓁' => '𐓩', '𐓂' => '𐓪', '𐓃' => '𐓫', '𐓄' => '𐓬', '𐓅' => '𐓭', '𐓆' => '𐓮', '𐓇' => '𐓯', '𐓈' => '𐓰', '𐓉' => '𐓱', '𐓊' => '𐓲', '𐓋' => '𐓳', '𐓌' => '𐓴', '𐓍' => '𐓵', '𐓎' => '𐓶', '𐓏' => '𐓷', '𐓐' => '𐓸', '𐓑' => '𐓹', '𐓒' => '𐓺', '𐓓' => '𐓻', '𐲀' => '𐳀', '𐲁' => '𐳁', '𐲂' => '𐳂', '𐲃' => '𐳃', '𐲄' => '𐳄', '𐲅' => '𐳅', '𐲆' => '𐳆', '𐲇' => '𐳇', '𐲈' => '𐳈', '𐲉' => '𐳉', '𐲊' => '𐳊', '𐲋' => '𐳋', '𐲌' => '𐳌', '𐲍' => '𐳍', '𐲎' => '𐳎', '𐲏' => '𐳏', '𐲐' => '𐳐', '𐲑' => '𐳑', '𐲒' => '𐳒', '𐲓' => '𐳓', '𐲔' => '𐳔', '𐲕' => '𐳕', '𐲖' => '𐳖', '𐲗' => '𐳗', '𐲘' => '𐳘', '𐲙' => '𐳙', '𐲚' => '𐳚', '𐲛' => '𐳛', '𐲜' => '𐳜', '𐲝' => '𐳝', '𐲞' => '𐳞', '𐲟' => '𐳟', '𐲠' => '𐳠', '𐲡' => '𐳡', '𐲢' => '𐳢', '𐲣' => '𐳣', '𐲤' => '𐳤', '𐲥' => '𐳥', '𐲦' => '𐳦', '𐲧' => '𐳧', '𐲨' => '𐳨', '𐲩' => '𐳩', '𐲪' => '𐳪', '𐲫' => '𐳫', '𐲬' => '𐳬', '𐲭' => '𐳭', '𐲮' => '𐳮', '𐲯' => '𐳯', '𐲰' => '𐳰', '𐲱' => '𐳱', '𐲲' => '𐳲', '𑢠' => '𑣀', '𑢡' => '𑣁', '𑢢' => '𑣂', '𑢣' => '𑣃', '𑢤' => '𑣄', '𑢥' => '𑣅', '𑢦' => '𑣆', '𑢧' => '𑣇', '𑢨' => '𑣈', '𑢩' => '𑣉', '𑢪' => '𑣊', '𑢫' => '𑣋', '𑢬' => '𑣌', '𑢭' => '𑣍', '𑢮' => '𑣎', '𑢯' => '𑣏', '𑢰' => '𑣐', '𑢱' => '𑣑', '𑢲' => '𑣒', '𑢳' => '𑣓', '𑢴' => '𑣔', '𑢵' => '𑣕', '𑢶' => '𑣖', '𑢷' => '𑣗', '𑢸' => '𑣘', '𑢹' => '𑣙', '𑢺' => '𑣚', '𑢻' => '𑣛', '𑢼' => '𑣜', '𑢽' => '𑣝', '𑢾' => '𑣞', '𑢿' => '𑣟', '𖹀' => '𖹠', '𖹁' => '𖹡', '𖹂' => '𖹢', '𖹃' => '𖹣', '𖹄' => '𖹤', '𖹅' => '𖹥', '𖹆' => '𖹦', '𖹇' => '𖹧', '𖹈' => '𖹨', '𖹉' => '𖹩', '𖹊' => '𖹪', '𖹋' => '𖹫', '𖹌' => '𖹬', '𖹍' => '𖹭', '𖹎' => '𖹮', '𖹏' => '𖹯', '𖹐' => '𖹰', '𖹑' => '𖹱', '𖹒' => '𖹲', '𖹓' => '𖹳', '𖹔' => '𖹴', '𖹕' => '𖹵', '𖹖' => '𖹶', '𖹗' => '𖹷', '𖹘' => '𖹸', '𖹙' => '𖹹', '𖹚' => '𖹺', '𖹛' => '𖹻', '𖹜' => '𖹼', '𖹝' => '𖹽', '𖹞' => '𖹾', '𖹟' => '𖹿', '𞤀' => '𞤢', '𞤁' => '𞤣', '𞤂' => '𞤤', '𞤃' => '𞤥', '𞤄' => '𞤦', '𞤅' => '𞤧', '𞤆' => '𞤨', '𞤇' => '𞤩', '𞤈' => '𞤪', '𞤉' => '𞤫', '𞤊' => '𞤬', '𞤋' => '𞤭', '𞤌' => '𞤮', '𞤍' => '𞤯', '𞤎' => '𞤰', '𞤏' => '𞤱', '𞤐' => '𞤲', '𞤑' => '𞤳', '𞤒' => '𞤴', '𞤓' => '𞤵', '𞤔' => '𞤶', '𞤕' => '𞤷', '𞤖' => '𞤸', '𞤗' => '𞤹', '𞤘' => '𞤺', '𞤙' => '𞤻', '𞤚' => '𞤼', '𞤛' => '𞤽', '𞤜' => '𞤾', '𞤝' => '𞤿', '𞤞' => '𞥀', '𞤟' => '𞥁', '𞤠' => '𞥂', '𞤡' => '𞥃');
<?php

namespace _HumbugBox1cb33d1f20f1;

return array('a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D', 'e' => 'E', 'f' => 'F', 'g' => 'G', 'h' => 'H', 'i' => 'I', 'j' => 'J', 'k' => 'K', 'l' => 'L', 'm' => 'M', 'n' => 'N', 'o' => 'O', 'p' => 'P', 'q' => 'Q', 'r' => 'R', 's' => 'S', 't' => 'T', 'u' => 'U', 'v' => 'V', 'w' => 'W', 'x' => 'X', 'y' => 'Y', 'z' => 'Z', 'µ' => 'Μ', 'à' => 'À', 'á' => 'Á', 'â' => 'Â', 'ã' => 'Ã', 'ä' => 'Ä', 'å' => 'Å', 'æ' => 'Æ', 'ç' => 'Ç', 'è' => 'È', 'é' => 'É', 'ê' => 'Ê', 'ë' => 'Ë', 'ì' => 'Ì', 'í' => 'Í', 'î' => 'Î', 'ï' => 'Ï', 'ð' => 'Ð', 'ñ' => 'Ñ', 'ò' => 'Ò', 'ó' => 'Ó', 'ô' => 'Ô', 'õ' => 'Õ', 'ö' => 'Ö', 'ø' => 'Ø', 'ù' => 'Ù', 'ú' => 'Ú', 'û' => 'Û', 'ü' => 'Ü', 'ý' => 'Ý', 'þ' => 'Þ', 'ÿ' => 'Ÿ', 'ā' => 'Ā', 'ă' => 'Ă', 'ą' => 'Ą', 'ć' => 'Ć', 'ĉ' => 'Ĉ', 'ċ' => 'Ċ', 'č' => 'Č', 'ď' => 'Ď', 'đ' => 'Đ', 'ē' => 'Ē', 'ĕ' => 'Ĕ', 'ė' => 'Ė', 'ę' => 'Ę', 'ě' => 'Ě', 'ĝ' => 'Ĝ', 'ğ' => 'Ğ', 'ġ' => 'Ġ', 'ģ' => 'Ģ', 'ĥ' => 'Ĥ', 'ħ' => 'Ħ', 'ĩ' => 'Ĩ', 'ī' => 'Ī', 'ĭ' => 'Ĭ', 'į' => 'Į', 'ı' => 'I', 'ij' => 'IJ', 'ĵ' => 'Ĵ', 'ķ' => 'Ķ', 'ĺ' => 'Ĺ', 'ļ' => 'Ļ', 'ľ' => 'Ľ', 'ŀ' => 'Ŀ', 'ł' => 'Ł', 'ń' => 'Ń', 'ņ' => 'Ņ', 'ň' => 'Ň', 'ŋ' => 'Ŋ', 'ō' => 'Ō', 'ŏ' => 'Ŏ', 'ő' => 'Ő', 'œ' => 'Œ', 'ŕ' => 'Ŕ', 'ŗ' => 'Ŗ', 'ř' => 'Ř', 'ś' => 'Ś', 'ŝ' => 'Ŝ', 'ş' => 'Ş', 'š' => 'Š', 'ţ' => 'Ţ', 'ť' => 'Ť', 'ŧ' => 'Ŧ', 'ũ' => 'Ũ', 'ū' => 'Ū', 'ŭ' => 'Ŭ', 'ů' => 'Ů', 'ű' => 'Ű', 'ų' => 'Ų', 'ŵ' => 'Ŵ', 'ŷ' => 'Ŷ', 'ź' => 'Ź', 'ż' => 'Ż', 'ž' => 'Ž', 'ſ' => 'S', 'ƀ' => 'Ƀ', 'ƃ' => 'Ƃ', 'ƅ' => 'Ƅ', 'ƈ' => 'Ƈ', 'ƌ' => 'Ƌ', 'ƒ' => 'Ƒ', 'ƕ' => 'Ƕ', 'ƙ' => 'Ƙ', 'ƚ' => 'Ƚ', 'ƞ' => 'Ƞ', 'ơ' => 'Ơ', 'ƣ' => 'Ƣ', 'ƥ' => 'Ƥ', 'ƨ' => 'Ƨ', 'ƭ' => 'Ƭ', 'ư' => 'Ư', 'ƴ' => 'Ƴ', 'ƶ' => 'Ƶ', 'ƹ' => 'Ƹ', 'ƽ' => 'Ƽ', 'ƿ' => 'Ƿ', 'Dž' => 'DŽ', 'dž' => 'DŽ', 'Lj' => 'LJ', 'lj' => 'LJ', 'Nj' => 'NJ', 'nj' => 'NJ', 'ǎ' => 'Ǎ', 'ǐ' => 'Ǐ', 'ǒ' => 'Ǒ', 'ǔ' => 'Ǔ', 'ǖ' => 'Ǖ', 'ǘ' => 'Ǘ', 'ǚ' => 'Ǚ', 'ǜ' => 'Ǜ', 'ǝ' => 'Ǝ', 'ǟ' => 'Ǟ', 'ǡ' => 'Ǡ', 'ǣ' => 'Ǣ', 'ǥ' => 'Ǥ', 'ǧ' => 'Ǧ', 'ǩ' => 'Ǩ', 'ǫ' => 'Ǫ', 'ǭ' => 'Ǭ', 'ǯ' => 'Ǯ', 'Dz' => 'DZ', 'dz' => 'DZ', 'ǵ' => 'Ǵ', 'ǹ' => 'Ǹ', 'ǻ' => 'Ǻ', 'ǽ' => 'Ǽ', 'ǿ' => 'Ǿ', 'ȁ' => 'Ȁ', 'ȃ' => 'Ȃ', 'ȅ' => 'Ȅ', 'ȇ' => 'Ȇ', 'ȉ' => 'Ȉ', 'ȋ' => 'Ȋ', 'ȍ' => 'Ȍ', 'ȏ' => 'Ȏ', 'ȑ' => 'Ȑ', 'ȓ' => 'Ȓ', 'ȕ' => 'Ȕ', 'ȗ' => 'Ȗ', 'ș' => 'Ș', 'ț' => 'Ț', 'ȝ' => 'Ȝ', 'ȟ' => 'Ȟ', 'ȣ' => 'Ȣ', 'ȥ' => 'Ȥ', 'ȧ' => 'Ȧ', 'ȩ' => 'Ȩ', 'ȫ' => 'Ȫ', 'ȭ' => 'Ȭ', 'ȯ' => 'Ȯ', 'ȱ' => 'Ȱ', 'ȳ' => 'Ȳ', 'ȼ' => 'Ȼ', 'ȿ' => 'Ȿ', 'ɀ' => 'Ɀ', 'ɂ' => 'Ɂ', 'ɇ' => 'Ɇ', 'ɉ' => 'Ɉ', 'ɋ' => 'Ɋ', 'ɍ' => 'Ɍ', 'ɏ' => 'Ɏ', 'ɐ' => 'Ɐ', 'ɑ' => 'Ɑ', 'ɒ' => 'Ɒ', 'ɓ' => 'Ɓ', 'ɔ' => 'Ɔ', 'ɖ' => 'Ɖ', 'ɗ' => 'Ɗ', 'ə' => 'Ə', 'ɛ' => 'Ɛ', 'ɜ' => 'Ɜ', 'ɠ' => 'Ɠ', 'ɡ' => 'Ɡ', 'ɣ' => 'Ɣ', 'ɥ' => 'Ɥ', 'ɦ' => 'Ɦ', 'ɨ' => 'Ɨ', 'ɩ' => 'Ɩ', 'ɪ' => 'Ɪ', 'ɫ' => 'Ɫ', 'ɬ' => 'Ɬ', 'ɯ' => 'Ɯ', 'ɱ' => 'Ɱ', 'ɲ' => 'Ɲ', 'ɵ' => 'Ɵ', 'ɽ' => 'Ɽ', 'ʀ' => 'Ʀ', 'ʂ' => 'Ʂ', 'ʃ' => 'Ʃ', 'ʇ' => 'Ʇ', 'ʈ' => 'Ʈ', 'ʉ' => 'Ʉ', 'ʊ' => 'Ʊ', 'ʋ' => 'Ʋ', 'ʌ' => 'Ʌ', 'ʒ' => 'Ʒ', 'ʝ' => 'Ʝ', 'ʞ' => 'Ʞ', 'ͅ' => 'Ι', 'ͱ' => 'Ͱ', 'ͳ' => 'Ͳ', 'ͷ' => 'Ͷ', 'ͻ' => 'Ͻ', 'ͼ' => 'Ͼ', 'ͽ' => 'Ͽ', 'ά' => 'Ά', 'έ' => 'Έ', 'ή' => 'Ή', 'ί' => 'Ί', 'α' => 'Α', 'β' => 'Β', 'γ' => 'Γ', 'δ' => 'Δ', 'ε' => 'Ε', 'ζ' => 'Ζ', 'η' => 'Η', 'θ' => 'Θ', 'ι' => 'Ι', 'κ' => 'Κ', 'λ' => 'Λ', 'μ' => 'Μ', 'ν' => 'Ν', 'ξ' => 'Ξ', 'ο' => 'Ο', 'π' => 'Π', 'ρ' => 'Ρ', 'ς' => 'Σ', 'σ' => 'Σ', 'τ' => 'Τ', 'υ' => 'Υ', 'φ' => 'Φ', 'χ' => 'Χ', 'ψ' => 'Ψ', 'ω' => 'Ω', 'ϊ' => 'Ϊ', 'ϋ' => 'Ϋ', 'ό' => 'Ό', 'ύ' => 'Ύ', 'ώ' => 'Ώ', 'ϐ' => 'Β', 'ϑ' => 'Θ', 'ϕ' => 'Φ', 'ϖ' => 'Π', 'ϗ' => 'Ϗ', 'ϙ' => 'Ϙ', 'ϛ' => 'Ϛ', 'ϝ' => 'Ϝ', 'ϟ' => 'Ϟ', 'ϡ' => 'Ϡ', 'ϣ' => 'Ϣ', 'ϥ' => 'Ϥ', 'ϧ' => 'Ϧ', 'ϩ' => 'Ϩ', 'ϫ' => 'Ϫ', 'ϭ' => 'Ϭ', 'ϯ' => 'Ϯ', 'ϰ' => 'Κ', 'ϱ' => 'Ρ', 'ϲ' => 'Ϲ', 'ϳ' => 'Ϳ', 'ϵ' => 'Ε', 'ϸ' => 'Ϸ', 'ϻ' => 'Ϻ', 'а' => 'А', 'б' => 'Б', 'в' => 'В', 'г' => 'Г', 'д' => 'Д', 'е' => 'Е', 'ж' => 'Ж', 'з' => 'З', 'и' => 'И', 'й' => 'Й', 'к' => 'К', 'л' => 'Л', 'м' => 'М', 'н' => 'Н', 'о' => 'О', 'п' => 'П', 'р' => 'Р', 'с' => 'С', 'т' => 'Т', 'у' => 'У', 'ф' => 'Ф', 'х' => 'Х', 'ц' => 'Ц', 'ч' => 'Ч', 'ш' => 'Ш', 'щ' => 'Щ', 'ъ' => 'Ъ', 'ы' => 'Ы', 'ь' => 'Ь', 'э' => 'Э', 'ю' => 'Ю', 'я' => 'Я', 'ѐ' => 'Ѐ', 'ё' => 'Ё', 'ђ' => 'Ђ', 'ѓ' => 'Ѓ', 'є' => 'Є', 'ѕ' => 'Ѕ', 'і' => 'І', 'ї' => 'Ї', 'ј' => 'Ј', 'љ' => 'Љ', 'њ' => 'Њ', 'ћ' => 'Ћ', 'ќ' => 'Ќ', 'ѝ' => 'Ѝ', 'ў' => 'Ў', 'џ' => 'Џ', 'ѡ' => 'Ѡ', 'ѣ' => 'Ѣ', 'ѥ' => 'Ѥ', 'ѧ' => 'Ѧ', 'ѩ' => 'Ѩ', 'ѫ' => 'Ѫ', 'ѭ' => 'Ѭ', 'ѯ' => 'Ѯ', 'ѱ' => 'Ѱ', 'ѳ' => 'Ѳ', 'ѵ' => 'Ѵ', 'ѷ' => 'Ѷ', 'ѹ' => 'Ѹ', 'ѻ' => 'Ѻ', 'ѽ' => 'Ѽ', 'ѿ' => 'Ѿ', 'ҁ' => 'Ҁ', 'ҋ' => 'Ҋ', 'ҍ' => 'Ҍ', 'ҏ' => 'Ҏ', 'ґ' => 'Ґ', 'ғ' => 'Ғ', 'ҕ' => 'Ҕ', 'җ' => 'Җ', 'ҙ' => 'Ҙ', 'қ' => 'Қ', 'ҝ' => 'Ҝ', 'ҟ' => 'Ҟ', 'ҡ' => 'Ҡ', 'ң' => 'Ң', 'ҥ' => 'Ҥ', 'ҧ' => 'Ҧ', 'ҩ' => 'Ҩ', 'ҫ' => 'Ҫ', 'ҭ' => 'Ҭ', 'ү' => 'Ү', 'ұ' => 'Ұ', 'ҳ' => 'Ҳ', 'ҵ' => 'Ҵ', 'ҷ' => 'Ҷ', 'ҹ' => 'Ҹ', 'һ' => 'Һ', 'ҽ' => 'Ҽ', 'ҿ' => 'Ҿ', 'ӂ' => 'Ӂ', 'ӄ' => 'Ӄ', 'ӆ' => 'Ӆ', 'ӈ' => 'Ӈ', 'ӊ' => 'Ӊ', 'ӌ' => 'Ӌ', 'ӎ' => 'Ӎ', 'ӏ' => 'Ӏ', 'ӑ' => 'Ӑ', 'ӓ' => 'Ӓ', 'ӕ' => 'Ӕ', 'ӗ' => 'Ӗ', 'ә' => 'Ә', 'ӛ' => 'Ӛ', 'ӝ' => 'Ӝ', 'ӟ' => 'Ӟ', 'ӡ' => 'Ӡ', 'ӣ' => 'Ӣ', 'ӥ' => 'Ӥ', 'ӧ' => 'Ӧ', 'ө' => 'Ө', 'ӫ' => 'Ӫ', 'ӭ' => 'Ӭ', 'ӯ' => 'Ӯ', 'ӱ' => 'Ӱ', 'ӳ' => 'Ӳ', 'ӵ' => 'Ӵ', 'ӷ' => 'Ӷ', 'ӹ' => 'Ӹ', 'ӻ' => 'Ӻ', 'ӽ' => 'Ӽ', 'ӿ' => 'Ӿ', 'ԁ' => 'Ԁ', 'ԃ' => 'Ԃ', 'ԅ' => 'Ԅ', 'ԇ' => 'Ԇ', 'ԉ' => 'Ԉ', 'ԋ' => 'Ԋ', 'ԍ' => 'Ԍ', 'ԏ' => 'Ԏ', 'ԑ' => 'Ԑ', 'ԓ' => 'Ԓ', 'ԕ' => 'Ԕ', 'ԗ' => 'Ԗ', 'ԙ' => 'Ԙ', 'ԛ' => 'Ԛ', 'ԝ' => 'Ԝ', 'ԟ' => 'Ԟ', 'ԡ' => 'Ԡ', 'ԣ' => 'Ԣ', 'ԥ' => 'Ԥ', 'ԧ' => 'Ԧ', 'ԩ' => 'Ԩ', 'ԫ' => 'Ԫ', 'ԭ' => 'Ԭ', 'ԯ' => 'Ԯ', 'ա' => 'Ա', 'բ' => 'Բ', 'գ' => 'Գ', 'դ' => 'Դ', 'ե' => 'Ե', 'զ' => 'Զ', 'է' => 'Է', 'ը' => 'Ը', 'թ' => 'Թ', 'ժ' => 'Ժ', 'ի' => 'Ի', 'լ' => 'Լ', 'խ' => 'Խ', 'ծ' => 'Ծ', 'կ' => 'Կ', 'հ' => 'Հ', 'ձ' => 'Ձ', 'ղ' => 'Ղ', 'ճ' => 'Ճ', 'մ' => 'Մ', 'յ' => 'Յ', 'ն' => 'Ն', 'շ' => 'Շ', 'ո' => 'Ո', 'չ' => 'Չ', 'պ' => 'Պ', 'ջ' => 'Ջ', 'ռ' => 'Ռ', 'ս' => 'Ս', 'վ' => 'Վ', 'տ' => 'Տ', 'ր' => 'Ր', 'ց' => 'Ց', 'ւ' => 'Ւ', 'փ' => 'Փ', 'ք' => 'Ք', 'օ' => 'Օ', 'ֆ' => 'Ֆ', 'ა' => 'Ა', 'ბ' => 'Ბ', 'გ' => 'Გ', 'დ' => 'Დ', 'ე' => 'Ე', 'ვ' => 'Ვ', 'ზ' => 'Ზ', 'თ' => 'Თ', 'ი' => 'Ი', 'კ' => 'Კ', 'ლ' => 'Ლ', 'მ' => 'Მ', 'ნ' => 'Ნ', 'ო' => 'Ო', 'პ' => 'Პ', 'ჟ' => 'Ჟ', 'რ' => 'Რ', 'ს' => 'Ს', 'ტ' => 'Ტ', 'უ' => 'Უ', 'ფ' => 'Ფ', 'ქ' => 'Ქ', 'ღ' => 'Ღ', 'ყ' => 'Ყ', 'შ' => 'Შ', 'ჩ' => 'Ჩ', 'ც' => 'Ც', 'ძ' => 'Ძ', 'წ' => 'Წ', 'ჭ' => 'Ჭ', 'ხ' => 'Ხ', 'ჯ' => 'Ჯ', 'ჰ' => 'Ჰ', 'ჱ' => 'Ჱ', 'ჲ' => 'Ჲ', 'ჳ' => 'Ჳ', 'ჴ' => 'Ჴ', 'ჵ' => 'Ჵ', 'ჶ' => 'Ჶ', 'ჷ' => 'Ჷ', 'ჸ' => 'Ჸ', 'ჹ' => 'Ჹ', 'ჺ' => 'Ჺ', 'ჽ' => 'Ჽ', 'ჾ' => 'Ჾ', 'ჿ' => 'Ჿ', 'ᏸ' => 'Ᏸ', 'ᏹ' => 'Ᏹ', 'ᏺ' => 'Ᏺ', 'ᏻ' => 'Ᏻ', 'ᏼ' => 'Ᏼ', 'ᏽ' => 'Ᏽ', 'ᲀ' => 'В', 'ᲁ' => 'Д', 'ᲂ' => 'О', 'ᲃ' => 'С', 'ᲄ' => 'Т', 'ᲅ' => 'Т', 'ᲆ' => 'Ъ', 'ᲇ' => 'Ѣ', 'ᲈ' => 'Ꙋ', 'ᵹ' => 'Ᵹ', 'ᵽ' => 'Ᵽ', 'ᶎ' => 'Ᶎ', 'ḁ' => 'Ḁ', 'ḃ' => 'Ḃ', 'ḅ' => 'Ḅ', 'ḇ' => 'Ḇ', 'ḉ' => 'Ḉ', 'ḋ' => 'Ḋ', 'ḍ' => 'Ḍ', 'ḏ' => 'Ḏ', 'ḑ' => 'Ḑ', 'ḓ' => 'Ḓ', 'ḕ' => 'Ḕ', 'ḗ' => 'Ḗ', 'ḙ' => 'Ḙ', 'ḛ' => 'Ḛ', 'ḝ' => 'Ḝ', 'ḟ' => 'Ḟ', 'ḡ' => 'Ḡ', 'ḣ' => 'Ḣ', 'ḥ' => 'Ḥ', 'ḧ' => 'Ḧ', 'ḩ' => 'Ḩ', 'ḫ' => 'Ḫ', 'ḭ' => 'Ḭ', 'ḯ' => 'Ḯ', 'ḱ' => 'Ḱ', 'ḳ' => 'Ḳ', 'ḵ' => 'Ḵ', 'ḷ' => 'Ḷ', 'ḹ' => 'Ḹ', 'ḻ' => 'Ḻ', 'ḽ' => 'Ḽ', 'ḿ' => 'Ḿ', 'ṁ' => 'Ṁ', 'ṃ' => 'Ṃ', 'ṅ' => 'Ṅ', 'ṇ' => 'Ṇ', 'ṉ' => 'Ṉ', 'ṋ' => 'Ṋ', 'ṍ' => 'Ṍ', 'ṏ' => 'Ṏ', 'ṑ' => 'Ṑ', 'ṓ' => 'Ṓ', 'ṕ' => 'Ṕ', 'ṗ' => 'Ṗ', 'ṙ' => 'Ṙ', 'ṛ' => 'Ṛ', 'ṝ' => 'Ṝ', 'ṟ' => 'Ṟ', 'ṡ' => 'Ṡ', 'ṣ' => 'Ṣ', 'ṥ' => 'Ṥ', 'ṧ' => 'Ṧ', 'ṩ' => 'Ṩ', 'ṫ' => 'Ṫ', 'ṭ' => 'Ṭ', 'ṯ' => 'Ṯ', 'ṱ' => 'Ṱ', 'ṳ' => 'Ṳ', 'ṵ' => 'Ṵ', 'ṷ' => 'Ṷ', 'ṹ' => 'Ṹ', 'ṻ' => 'Ṻ', 'ṽ' => 'Ṽ', 'ṿ' => 'Ṿ', 'ẁ' => 'Ẁ', 'ẃ' => 'Ẃ', 'ẅ' => 'Ẅ', 'ẇ' => 'Ẇ', 'ẉ' => 'Ẉ', 'ẋ' => 'Ẋ', 'ẍ' => 'Ẍ', 'ẏ' => 'Ẏ', 'ẑ' => 'Ẑ', 'ẓ' => 'Ẓ', 'ẕ' => 'Ẕ', 'ẛ' => 'Ṡ', 'ạ' => 'Ạ', 'ả' => 'Ả', 'ấ' => 'Ấ', 'ầ' => 'Ầ', 'ẩ' => 'Ẩ', 'ẫ' => 'Ẫ', 'ậ' => 'Ậ', 'ắ' => 'Ắ', 'ằ' => 'Ằ', 'ẳ' => 'Ẳ', 'ẵ' => 'Ẵ', 'ặ' => 'Ặ', 'ẹ' => 'Ẹ', 'ẻ' => 'Ẻ', 'ẽ' => 'Ẽ', 'ế' => 'Ế', 'ề' => 'Ề', 'ể' => 'Ể', 'ễ' => 'Ễ', 'ệ' => 'Ệ', 'ỉ' => 'Ỉ', 'ị' => 'Ị', 'ọ' => 'Ọ', 'ỏ' => 'Ỏ', 'ố' => 'Ố', 'ồ' => 'Ồ', 'ổ' => 'Ổ', 'ỗ' => 'Ỗ', 'ộ' => 'Ộ', 'ớ' => 'Ớ', 'ờ' => 'Ờ', 'ở' => 'Ở', 'ỡ' => 'Ỡ', 'ợ' => 'Ợ', 'ụ' => 'Ụ', 'ủ' => 'Ủ', 'ứ' => 'Ứ', 'ừ' => 'Ừ', 'ử' => 'Ử', 'ữ' => 'Ữ', 'ự' => 'Ự', 'ỳ' => 'Ỳ', 'ỵ' => 'Ỵ', 'ỷ' => 'Ỷ', 'ỹ' => 'Ỹ', 'ỻ' => 'Ỻ', 'ỽ' => 'Ỽ', 'ỿ' => 'Ỿ', 'ἀ' => 'Ἀ', 'ἁ' => 'Ἁ', 'ἂ' => 'Ἂ', 'ἃ' => 'Ἃ', 'ἄ' => 'Ἄ', 'ἅ' => 'Ἅ', 'ἆ' => 'Ἆ', 'ἇ' => 'Ἇ', 'ἐ' => 'Ἐ', 'ἑ' => 'Ἑ', 'ἒ' => 'Ἒ', 'ἓ' => 'Ἓ', 'ἔ' => 'Ἔ', 'ἕ' => 'Ἕ', 'ἠ' => 'Ἠ', 'ἡ' => 'Ἡ', 'ἢ' => 'Ἢ', 'ἣ' => 'Ἣ', 'ἤ' => 'Ἤ', 'ἥ' => 'Ἥ', 'ἦ' => 'Ἦ', 'ἧ' => 'Ἧ', 'ἰ' => 'Ἰ', 'ἱ' => 'Ἱ', 'ἲ' => 'Ἲ', 'ἳ' => 'Ἳ', 'ἴ' => 'Ἴ', 'ἵ' => 'Ἵ', 'ἶ' => 'Ἶ', 'ἷ' => 'Ἷ', 'ὀ' => 'Ὀ', 'ὁ' => 'Ὁ', 'ὂ' => 'Ὂ', 'ὃ' => 'Ὃ', 'ὄ' => 'Ὄ', 'ὅ' => 'Ὅ', 'ὑ' => 'Ὑ', 'ὓ' => 'Ὓ', 'ὕ' => 'Ὕ', 'ὗ' => 'Ὗ', 'ὠ' => 'Ὠ', 'ὡ' => 'Ὡ', 'ὢ' => 'Ὢ', 'ὣ' => 'Ὣ', 'ὤ' => 'Ὤ', 'ὥ' => 'Ὥ', 'ὦ' => 'Ὦ', 'ὧ' => 'Ὧ', 'ὰ' => 'Ὰ', 'ά' => 'Ά', 'ὲ' => 'Ὲ', 'έ' => 'Έ', 'ὴ' => 'Ὴ', 'ή' => 'Ή', 'ὶ' => 'Ὶ', 'ί' => 'Ί', 'ὸ' => 'Ὸ', 'ό' => 'Ό', 'ὺ' => 'Ὺ', 'ύ' => 'Ύ', 'ὼ' => 'Ὼ', 'ώ' => 'Ώ', 'ᾀ' => 'ἈΙ', 'ᾁ' => 'ἉΙ', 'ᾂ' => 'ἊΙ', 'ᾃ' => 'ἋΙ', 'ᾄ' => 'ἌΙ', 'ᾅ' => 'ἍΙ', 'ᾆ' => 'ἎΙ', 'ᾇ' => 'ἏΙ', 'ᾐ' => 'ἨΙ', 'ᾑ' => 'ἩΙ', 'ᾒ' => 'ἪΙ', 'ᾓ' => 'ἫΙ', 'ᾔ' => 'ἬΙ', 'ᾕ' => 'ἭΙ', 'ᾖ' => 'ἮΙ', 'ᾗ' => 'ἯΙ', 'ᾠ' => 'ὨΙ', 'ᾡ' => 'ὩΙ', 'ᾢ' => 'ὪΙ', 'ᾣ' => 'ὫΙ', 'ᾤ' => 'ὬΙ', 'ᾥ' => 'ὭΙ', 'ᾦ' => 'ὮΙ', 'ᾧ' => 'ὯΙ', 'ᾰ' => 'Ᾰ', 'ᾱ' => 'Ᾱ', 'ᾳ' => 'ΑΙ', 'ι' => 'Ι', 'ῃ' => 'ΗΙ', 'ῐ' => 'Ῐ', 'ῑ' => 'Ῑ', 'ῠ' => 'Ῠ', 'ῡ' => 'Ῡ', 'ῥ' => 'Ῥ', 'ῳ' => 'ΩΙ', 'ⅎ' => 'Ⅎ', 'ⅰ' => 'Ⅰ', 'ⅱ' => 'Ⅱ', 'ⅲ' => 'Ⅲ', 'ⅳ' => 'Ⅳ', 'ⅴ' => 'Ⅴ', 'ⅵ' => 'Ⅵ', 'ⅶ' => 'Ⅶ', 'ⅷ' => 'Ⅷ', 'ⅸ' => 'Ⅸ', 'ⅹ' => 'Ⅹ', 'ⅺ' => 'Ⅺ', 'ⅻ' => 'Ⅻ', 'ⅼ' => 'Ⅼ', 'ⅽ' => 'Ⅽ', 'ⅾ' => 'Ⅾ', 'ⅿ' => 'Ⅿ', 'ↄ' => 'Ↄ', 'ⓐ' => 'Ⓐ', 'ⓑ' => 'Ⓑ', 'ⓒ' => 'Ⓒ', 'ⓓ' => 'Ⓓ', 'ⓔ' => 'Ⓔ', 'ⓕ' => 'Ⓕ', 'ⓖ' => 'Ⓖ', 'ⓗ' => 'Ⓗ', 'ⓘ' => 'Ⓘ', 'ⓙ' => 'Ⓙ', 'ⓚ' => 'Ⓚ', 'ⓛ' => 'Ⓛ', 'ⓜ' => 'Ⓜ', 'ⓝ' => 'Ⓝ', 'ⓞ' => 'Ⓞ', 'ⓟ' => 'Ⓟ', 'ⓠ' => 'Ⓠ', 'ⓡ' => 'Ⓡ', 'ⓢ' => 'Ⓢ', 'ⓣ' => 'Ⓣ', 'ⓤ' => 'Ⓤ', 'ⓥ' => 'Ⓥ', 'ⓦ' => 'Ⓦ', 'ⓧ' => 'Ⓧ', 'ⓨ' => 'Ⓨ', 'ⓩ' => 'Ⓩ', 'ⰰ' => 'Ⰰ', 'ⰱ' => 'Ⰱ', 'ⰲ' => 'Ⰲ', 'ⰳ' => 'Ⰳ', 'ⰴ' => 'Ⰴ', 'ⰵ' => 'Ⰵ', 'ⰶ' => 'Ⰶ', 'ⰷ' => 'Ⰷ', 'ⰸ' => 'Ⰸ', 'ⰹ' => 'Ⰹ', 'ⰺ' => 'Ⰺ', 'ⰻ' => 'Ⰻ', 'ⰼ' => 'Ⰼ', 'ⰽ' => 'Ⰽ', 'ⰾ' => 'Ⰾ', 'ⰿ' => 'Ⰿ', 'ⱀ' => 'Ⱀ', 'ⱁ' => 'Ⱁ', 'ⱂ' => 'Ⱂ', 'ⱃ' => 'Ⱃ', 'ⱄ' => 'Ⱄ', 'ⱅ' => 'Ⱅ', 'ⱆ' => 'Ⱆ', 'ⱇ' => 'Ⱇ', 'ⱈ' => 'Ⱈ', 'ⱉ' => 'Ⱉ', 'ⱊ' => 'Ⱊ', 'ⱋ' => 'Ⱋ', 'ⱌ' => 'Ⱌ', 'ⱍ' => 'Ⱍ', 'ⱎ' => 'Ⱎ', 'ⱏ' => 'Ⱏ', 'ⱐ' => 'Ⱐ', 'ⱑ' => 'Ⱑ', 'ⱒ' => 'Ⱒ', 'ⱓ' => 'Ⱓ', 'ⱔ' => 'Ⱔ', 'ⱕ' => 'Ⱕ', 'ⱖ' => 'Ⱖ', 'ⱗ' => 'Ⱗ', 'ⱘ' => 'Ⱘ', 'ⱙ' => 'Ⱙ', 'ⱚ' => 'Ⱚ', 'ⱛ' => 'Ⱛ', 'ⱜ' => 'Ⱜ', 'ⱝ' => 'Ⱝ', 'ⱞ' => 'Ⱞ', 'ⱡ' => 'Ⱡ', 'ⱥ' => 'Ⱥ', 'ⱦ' => 'Ⱦ', 'ⱨ' => 'Ⱨ', 'ⱪ' => 'Ⱪ', 'ⱬ' => 'Ⱬ', 'ⱳ' => 'Ⱳ', 'ⱶ' => 'Ⱶ', 'ⲁ' => 'Ⲁ', 'ⲃ' => 'Ⲃ', 'ⲅ' => 'Ⲅ', 'ⲇ' => 'Ⲇ', 'ⲉ' => 'Ⲉ', 'ⲋ' => 'Ⲋ', 'ⲍ' => 'Ⲍ', 'ⲏ' => 'Ⲏ', 'ⲑ' => 'Ⲑ', 'ⲓ' => 'Ⲓ', 'ⲕ' => 'Ⲕ', 'ⲗ' => 'Ⲗ', 'ⲙ' => 'Ⲙ', 'ⲛ' => 'Ⲛ', 'ⲝ' => 'Ⲝ', 'ⲟ' => 'Ⲟ', 'ⲡ' => 'Ⲡ', 'ⲣ' => 'Ⲣ', 'ⲥ' => 'Ⲥ', 'ⲧ' => 'Ⲧ', 'ⲩ' => 'Ⲩ', 'ⲫ' => 'Ⲫ', 'ⲭ' => 'Ⲭ', 'ⲯ' => 'Ⲯ', 'ⲱ' => 'Ⲱ', 'ⲳ' => 'Ⲳ', 'ⲵ' => 'Ⲵ', 'ⲷ' => 'Ⲷ', 'ⲹ' => 'Ⲹ', 'ⲻ' => 'Ⲻ', 'ⲽ' => 'Ⲽ', 'ⲿ' => 'Ⲿ', 'ⳁ' => 'Ⳁ', 'ⳃ' => 'Ⳃ', 'ⳅ' => 'Ⳅ', 'ⳇ' => 'Ⳇ', 'ⳉ' => 'Ⳉ', 'ⳋ' => 'Ⳋ', 'ⳍ' => 'Ⳍ', 'ⳏ' => 'Ⳏ', 'ⳑ' => 'Ⳑ', 'ⳓ' => 'Ⳓ', 'ⳕ' => 'Ⳕ', 'ⳗ' => 'Ⳗ', 'ⳙ' => 'Ⳙ', 'ⳛ' => 'Ⳛ', 'ⳝ' => 'Ⳝ', 'ⳟ' => 'Ⳟ', 'ⳡ' => 'Ⳡ', 'ⳣ' => 'Ⳣ', 'ⳬ' => 'Ⳬ', 'ⳮ' => 'Ⳮ', 'ⳳ' => 'Ⳳ', 'ⴀ' => 'Ⴀ', 'ⴁ' => 'Ⴁ', 'ⴂ' => 'Ⴂ', 'ⴃ' => 'Ⴃ', 'ⴄ' => 'Ⴄ', 'ⴅ' => 'Ⴅ', 'ⴆ' => 'Ⴆ', 'ⴇ' => 'Ⴇ', 'ⴈ' => 'Ⴈ', 'ⴉ' => 'Ⴉ', 'ⴊ' => 'Ⴊ', 'ⴋ' => 'Ⴋ', 'ⴌ' => 'Ⴌ', 'ⴍ' => 'Ⴍ', 'ⴎ' => 'Ⴎ', 'ⴏ' => 'Ⴏ', 'ⴐ' => 'Ⴐ', 'ⴑ' => 'Ⴑ', 'ⴒ' => 'Ⴒ', 'ⴓ' => 'Ⴓ', 'ⴔ' => 'Ⴔ', 'ⴕ' => 'Ⴕ', 'ⴖ' => 'Ⴖ', 'ⴗ' => 'Ⴗ', 'ⴘ' => 'Ⴘ', 'ⴙ' => 'Ⴙ', 'ⴚ' => 'Ⴚ', 'ⴛ' => 'Ⴛ', 'ⴜ' => 'Ⴜ', 'ⴝ' => 'Ⴝ', 'ⴞ' => 'Ⴞ', 'ⴟ' => 'Ⴟ', 'ⴠ' => 'Ⴠ', 'ⴡ' => 'Ⴡ', 'ⴢ' => 'Ⴢ', 'ⴣ' => 'Ⴣ', 'ⴤ' => 'Ⴤ', 'ⴥ' => 'Ⴥ', 'ⴧ' => 'Ⴧ', 'ⴭ' => 'Ⴭ', 'ꙁ' => 'Ꙁ', 'ꙃ' => 'Ꙃ', 'ꙅ' => 'Ꙅ', 'ꙇ' => 'Ꙇ', 'ꙉ' => 'Ꙉ', 'ꙋ' => 'Ꙋ', 'ꙍ' => 'Ꙍ', 'ꙏ' => 'Ꙏ', 'ꙑ' => 'Ꙑ', 'ꙓ' => 'Ꙓ', 'ꙕ' => 'Ꙕ', 'ꙗ' => 'Ꙗ', 'ꙙ' => 'Ꙙ', 'ꙛ' => 'Ꙛ', 'ꙝ' => 'Ꙝ', 'ꙟ' => 'Ꙟ', 'ꙡ' => 'Ꙡ', 'ꙣ' => 'Ꙣ', 'ꙥ' => 'Ꙥ', 'ꙧ' => 'Ꙧ', 'ꙩ' => 'Ꙩ', 'ꙫ' => 'Ꙫ', 'ꙭ' => 'Ꙭ', 'ꚁ' => 'Ꚁ', 'ꚃ' => 'Ꚃ', 'ꚅ' => 'Ꚅ', 'ꚇ' => 'Ꚇ', 'ꚉ' => 'Ꚉ', 'ꚋ' => 'Ꚋ', 'ꚍ' => 'Ꚍ', 'ꚏ' => 'Ꚏ', 'ꚑ' => 'Ꚑ', 'ꚓ' => 'Ꚓ', 'ꚕ' => 'Ꚕ', 'ꚗ' => 'Ꚗ', 'ꚙ' => 'Ꚙ', 'ꚛ' => 'Ꚛ', 'ꜣ' => 'Ꜣ', 'ꜥ' => 'Ꜥ', 'ꜧ' => 'Ꜧ', 'ꜩ' => 'Ꜩ', 'ꜫ' => 'Ꜫ', 'ꜭ' => 'Ꜭ', 'ꜯ' => 'Ꜯ', 'ꜳ' => 'Ꜳ', 'ꜵ' => 'Ꜵ', 'ꜷ' => 'Ꜷ', 'ꜹ' => 'Ꜹ', 'ꜻ' => 'Ꜻ', 'ꜽ' => 'Ꜽ', 'ꜿ' => 'Ꜿ', 'ꝁ' => 'Ꝁ', 'ꝃ' => 'Ꝃ', 'ꝅ' => 'Ꝅ', 'ꝇ' => 'Ꝇ', 'ꝉ' => 'Ꝉ', 'ꝋ' => 'Ꝋ', 'ꝍ' => 'Ꝍ', 'ꝏ' => 'Ꝏ', 'ꝑ' => 'Ꝑ', 'ꝓ' => 'Ꝓ', 'ꝕ' => 'Ꝕ', 'ꝗ' => 'Ꝗ', 'ꝙ' => 'Ꝙ', 'ꝛ' => 'Ꝛ', 'ꝝ' => 'Ꝝ', 'ꝟ' => 'Ꝟ', 'ꝡ' => 'Ꝡ', 'ꝣ' => 'Ꝣ', 'ꝥ' => 'Ꝥ', 'ꝧ' => 'Ꝧ', 'ꝩ' => 'Ꝩ', 'ꝫ' => 'Ꝫ', 'ꝭ' => 'Ꝭ', 'ꝯ' => 'Ꝯ', 'ꝺ' => 'Ꝺ', 'ꝼ' => 'Ꝼ', 'ꝿ' => 'Ꝿ', 'ꞁ' => 'Ꞁ', 'ꞃ' => 'Ꞃ', 'ꞅ' => 'Ꞅ', 'ꞇ' => 'Ꞇ', 'ꞌ' => 'Ꞌ', 'ꞑ' => 'Ꞑ', 'ꞓ' => 'Ꞓ', 'ꞔ' => 'Ꞔ', 'ꞗ' => 'Ꞗ', 'ꞙ' => 'Ꞙ', 'ꞛ' => 'Ꞛ', 'ꞝ' => 'Ꞝ', 'ꞟ' => 'Ꞟ', 'ꞡ' => 'Ꞡ', 'ꞣ' => 'Ꞣ', 'ꞥ' => 'Ꞥ', 'ꞧ' => 'Ꞧ', 'ꞩ' => 'Ꞩ', 'ꞵ' => 'Ꞵ', 'ꞷ' => 'Ꞷ', 'ꞹ' => 'Ꞹ', 'ꞻ' => 'Ꞻ', 'ꞽ' => 'Ꞽ', 'ꞿ' => 'Ꞿ', 'ꟃ' => 'Ꟃ', 'ꟈ' => 'Ꟈ', 'ꟊ' => 'Ꟊ', 'ꟶ' => 'Ꟶ', 'ꭓ' => 'Ꭓ', 'ꭰ' => 'Ꭰ', 'ꭱ' => 'Ꭱ', 'ꭲ' => 'Ꭲ', 'ꭳ' => 'Ꭳ', 'ꭴ' => 'Ꭴ', 'ꭵ' => 'Ꭵ', 'ꭶ' => 'Ꭶ', 'ꭷ' => 'Ꭷ', 'ꭸ' => 'Ꭸ', 'ꭹ' => 'Ꭹ', 'ꭺ' => 'Ꭺ', 'ꭻ' => 'Ꭻ', 'ꭼ' => 'Ꭼ', 'ꭽ' => 'Ꭽ', 'ꭾ' => 'Ꭾ', 'ꭿ' => 'Ꭿ', 'ꮀ' => 'Ꮀ', 'ꮁ' => 'Ꮁ', 'ꮂ' => 'Ꮂ', 'ꮃ' => 'Ꮃ', 'ꮄ' => 'Ꮄ', 'ꮅ' => 'Ꮅ', 'ꮆ' => 'Ꮆ', 'ꮇ' => 'Ꮇ', 'ꮈ' => 'Ꮈ', 'ꮉ' => 'Ꮉ', 'ꮊ' => 'Ꮊ', 'ꮋ' => 'Ꮋ', 'ꮌ' => 'Ꮌ', 'ꮍ' => 'Ꮍ', 'ꮎ' => 'Ꮎ', 'ꮏ' => 'Ꮏ', 'ꮐ' => 'Ꮐ', 'ꮑ' => 'Ꮑ', 'ꮒ' => 'Ꮒ', 'ꮓ' => 'Ꮓ', 'ꮔ' => 'Ꮔ', 'ꮕ' => 'Ꮕ', 'ꮖ' => 'Ꮖ', 'ꮗ' => 'Ꮗ', 'ꮘ' => 'Ꮘ', 'ꮙ' => 'Ꮙ', 'ꮚ' => 'Ꮚ', 'ꮛ' => 'Ꮛ', 'ꮜ' => 'Ꮜ', 'ꮝ' => 'Ꮝ', 'ꮞ' => 'Ꮞ', 'ꮟ' => 'Ꮟ', 'ꮠ' => 'Ꮠ', 'ꮡ' => 'Ꮡ', 'ꮢ' => 'Ꮢ', 'ꮣ' => 'Ꮣ', 'ꮤ' => 'Ꮤ', 'ꮥ' => 'Ꮥ', 'ꮦ' => 'Ꮦ', 'ꮧ' => 'Ꮧ', 'ꮨ' => 'Ꮨ', 'ꮩ' => 'Ꮩ', 'ꮪ' => 'Ꮪ', 'ꮫ' => 'Ꮫ', 'ꮬ' => 'Ꮬ', 'ꮭ' => 'Ꮭ', 'ꮮ' => 'Ꮮ', 'ꮯ' => 'Ꮯ', 'ꮰ' => 'Ꮰ', 'ꮱ' => 'Ꮱ', 'ꮲ' => 'Ꮲ', 'ꮳ' => 'Ꮳ', 'ꮴ' => 'Ꮴ', 'ꮵ' => 'Ꮵ', 'ꮶ' => 'Ꮶ', 'ꮷ' => 'Ꮷ', 'ꮸ' => 'Ꮸ', 'ꮹ' => 'Ꮹ', 'ꮺ' => 'Ꮺ', 'ꮻ' => 'Ꮻ', 'ꮼ' => 'Ꮼ', 'ꮽ' => 'Ꮽ', 'ꮾ' => 'Ꮾ', 'ꮿ' => 'Ꮿ', 'a' => 'A', 'b' => 'B', 'c' => 'C', 'd' => 'D', 'e' => 'E', 'f' => 'F', 'g' => 'G', 'h' => 'H', 'i' => 'I', 'j' => 'J', 'k' => 'K', 'l' => 'L', 'm' => 'M', 'n' => 'N', 'o' => 'O', 'p' => 'P', 'q' => 'Q', 'r' => 'R', 's' => 'S', 't' => 'T', 'u' => 'U', 'v' => 'V', 'w' => 'W', 'x' => 'X', 'y' => 'Y', 'z' => 'Z', '𐐨' => '𐐀', '𐐩' => '𐐁', '𐐪' => '𐐂', '𐐫' => '𐐃', '𐐬' => '𐐄', '𐐭' => '𐐅', '𐐮' => '𐐆', '𐐯' => '𐐇', '𐐰' => '𐐈', '𐐱' => '𐐉', '𐐲' => '𐐊', '𐐳' => '𐐋', '𐐴' => '𐐌', '𐐵' => '𐐍', '𐐶' => '𐐎', '𐐷' => '𐐏', '𐐸' => '𐐐', '𐐹' => '𐐑', '𐐺' => '𐐒', '𐐻' => '𐐓', '𐐼' => '𐐔', '𐐽' => '𐐕', '𐐾' => '𐐖', '𐐿' => '𐐗', '𐑀' => '𐐘', '𐑁' => '𐐙', '𐑂' => '𐐚', '𐑃' => '𐐛', '𐑄' => '𐐜', '𐑅' => '𐐝', '𐑆' => '𐐞', '𐑇' => '𐐟', '𐑈' => '𐐠', '𐑉' => '𐐡', '𐑊' => '𐐢', '𐑋' => '𐐣', '𐑌' => '𐐤', '𐑍' => '𐐥', '𐑎' => '𐐦', '𐑏' => '𐐧', '𐓘' => '𐒰', '𐓙' => '𐒱', '𐓚' => '𐒲', '𐓛' => '𐒳', '𐓜' => '𐒴', '𐓝' => '𐒵', '𐓞' => '𐒶', '𐓟' => '𐒷', '𐓠' => '𐒸', '𐓡' => '𐒹', '𐓢' => '𐒺', '𐓣' => '𐒻', '𐓤' => '𐒼', '𐓥' => '𐒽', '𐓦' => '𐒾', '𐓧' => '𐒿', '𐓨' => '𐓀', '𐓩' => '𐓁', '𐓪' => '𐓂', '𐓫' => '𐓃', '𐓬' => '𐓄', '𐓭' => '𐓅', '𐓮' => '𐓆', '𐓯' => '𐓇', '𐓰' => '𐓈', '𐓱' => '𐓉', '𐓲' => '𐓊', '𐓳' => '𐓋', '𐓴' => '𐓌', '𐓵' => '𐓍', '𐓶' => '𐓎', '𐓷' => '𐓏', '𐓸' => '𐓐', '𐓹' => '𐓑', '𐓺' => '𐓒', '𐓻' => '𐓓', '𐳀' => '𐲀', '𐳁' => '𐲁', '𐳂' => '𐲂', '𐳃' => '𐲃', '𐳄' => '𐲄', '𐳅' => '𐲅', '𐳆' => '𐲆', '𐳇' => '𐲇', '𐳈' => '𐲈', '𐳉' => '𐲉', '𐳊' => '𐲊', '𐳋' => '𐲋', '𐳌' => '𐲌', '𐳍' => '𐲍', '𐳎' => '𐲎', '𐳏' => '𐲏', '𐳐' => '𐲐', '𐳑' => '𐲑', '𐳒' => '𐲒', '𐳓' => '𐲓', '𐳔' => '𐲔', '𐳕' => '𐲕', '𐳖' => '𐲖', '𐳗' => '𐲗', '𐳘' => '𐲘', '𐳙' => '𐲙', '𐳚' => '𐲚', '𐳛' => '𐲛', '𐳜' => '𐲜', '𐳝' => '𐲝', '𐳞' => '𐲞', '𐳟' => '𐲟', '𐳠' => '𐲠', '𐳡' => '𐲡', '𐳢' => '𐲢', '𐳣' => '𐲣', '𐳤' => '𐲤', '𐳥' => '𐲥', '𐳦' => '𐲦', '𐳧' => '𐲧', '𐳨' => '𐲨', '𐳩' => '𐲩', '𐳪' => '𐲪', '𐳫' => '𐲫', '𐳬' => '𐲬', '𐳭' => '𐲭', '𐳮' => '𐲮', '𐳯' => '𐲯', '𐳰' => '𐲰', '𐳱' => '𐲱', '𐳲' => '𐲲', '𑣀' => '𑢠', '𑣁' => '𑢡', '𑣂' => '𑢢', '𑣃' => '𑢣', '𑣄' => '𑢤', '𑣅' => '𑢥', '𑣆' => '𑢦', '𑣇' => '𑢧', '𑣈' => '𑢨', '𑣉' => '𑢩', '𑣊' => '𑢪', '𑣋' => '𑢫', '𑣌' => '𑢬', '𑣍' => '𑢭', '𑣎' => '𑢮', '𑣏' => '𑢯', '𑣐' => '𑢰', '𑣑' => '𑢱', '𑣒' => '𑢲', '𑣓' => '𑢳', '𑣔' => '𑢴', '𑣕' => '𑢵', '𑣖' => '𑢶', '𑣗' => '𑢷', '𑣘' => '𑢸', '𑣙' => '𑢹', '𑣚' => '𑢺', '𑣛' => '𑢻', '𑣜' => '𑢼', '𑣝' => '𑢽', '𑣞' => '𑢾', '𑣟' => '𑢿', '𖹠' => '𖹀', '𖹡' => '𖹁', '𖹢' => '𖹂', '𖹣' => '𖹃', '𖹤' => '𖹄', '𖹥' => '𖹅', '𖹦' => '𖹆', '𖹧' => '𖹇', '𖹨' => '𖹈', '𖹩' => '𖹉', '𖹪' => '𖹊', '𖹫' => '𖹋', '𖹬' => '𖹌', '𖹭' => '𖹍', '𖹮' => '𖹎', '𖹯' => '𖹏', '𖹰' => '𖹐', '𖹱' => '𖹑', '𖹲' => '𖹒', '𖹳' => '𖹓', '𖹴' => '𖹔', '𖹵' => '𖹕', '𖹶' => '𖹖', '𖹷' => '𖹗', '𖹸' => '𖹘', '𖹹' => '𖹙', '𖹺' => '𖹚', '𖹻' => '𖹛', '𖹼' => '𖹜', '𖹽' => '𖹝', '𖹾' => '𖹞', '𖹿' => '𖹟', '𞤢' => '𞤀', '𞤣' => '𞤁', '𞤤' => '𞤂', '𞤥' => '𞤃', '𞤦' => '𞤄', '𞤧' => '𞤅', '𞤨' => '𞤆', '𞤩' => '𞤇', '𞤪' => '𞤈', '𞤫' => '𞤉', '𞤬' => '𞤊', '𞤭' => '𞤋', '𞤮' => '𞤌', '𞤯' => '𞤍', '𞤰' => '𞤎', '𞤱' => '𞤏', '𞤲' => '𞤐', '𞤳' => '𞤑', '𞤴' => '𞤒', '𞤵' => '𞤓', '𞤶' => '𞤔', '𞤷' => '𞤕', '𞤸' => '𞤖', '𞤹' => '𞤗', '𞤺' => '𞤘', '𞤻' => '𞤙', '𞤼' => '𞤚', '𞤽' => '𞤛', '𞤾' => '𞤜', '𞤿' => '𞤝', '𞥀' => '𞤞', '𞥁' => '𞤟', '𞥂' => '𞤠', '𞥃' => '𞤡', 'ß' => 'SS', 'ff' => 'FF', 'fi' => 'FI', 'fl' => 'FL', 'ffi' => 'FFI', 'ffl' => 'FFL', 'ſt' => 'ST', 'st' => 'ST', 'և' => 'ԵՒ', 'ﬓ' => 'ՄՆ', 'ﬔ' => 'ՄԵ', 'ﬕ' => 'ՄԻ', 'ﬖ' => 'ՎՆ', 'ﬗ' => 'ՄԽ', 'ʼn' => 'ʼN', 'ΐ' => 'Ϊ́', 'ΰ' => 'Ϋ́', 'ǰ' => 'J̌', 'ẖ' => 'H̱', 'ẗ' => 'T̈', 'ẘ' => 'W̊', 'ẙ' => 'Y̊', 'ẚ' => 'Aʾ', 'ὐ' => 'Υ̓', 'ὒ' => 'Υ̓̀', 'ὔ' => 'Υ̓́', 'ὖ' => 'Υ̓͂', 'ᾶ' => 'Α͂', 'ῆ' => 'Η͂', 'ῒ' => 'Ϊ̀', 'ΐ' => 'Ϊ́', 'ῖ' => 'Ι͂', 'ῗ' => 'Ϊ͂', 'ῢ' => 'Ϋ̀', 'ΰ' => 'Ϋ́', 'ῤ' => 'Ρ̓', 'ῦ' => 'Υ͂', 'ῧ' => 'Ϋ͂', 'ῶ' => 'Ω͂', 'ᾈ' => 'ἈΙ', 'ᾉ' => 'ἉΙ', 'ᾊ' => 'ἊΙ', 'ᾋ' => 'ἋΙ', 'ᾌ' => 'ἌΙ', 'ᾍ' => 'ἍΙ', 'ᾎ' => 'ἎΙ', 'ᾏ' => 'ἏΙ', 'ᾘ' => 'ἨΙ', 'ᾙ' => 'ἩΙ', 'ᾚ' => 'ἪΙ', 'ᾛ' => 'ἫΙ', 'ᾜ' => 'ἬΙ', 'ᾝ' => 'ἭΙ', 'ᾞ' => 'ἮΙ', 'ᾟ' => 'ἯΙ', 'ᾨ' => 'ὨΙ', 'ᾩ' => 'ὩΙ', 'ᾪ' => 'ὪΙ', 'ᾫ' => 'ὫΙ', 'ᾬ' => 'ὬΙ', 'ᾭ' => 'ὭΙ', 'ᾮ' => 'ὮΙ', 'ᾯ' => 'ὯΙ', 'ᾼ' => 'ΑΙ', 'ῌ' => 'ΗΙ', 'ῼ' => 'ΩΙ', 'ᾲ' => 'ᾺΙ', 'ᾴ' => 'ΆΙ', 'ῂ' => 'ῊΙ', 'ῄ' => 'ΉΙ', 'ῲ' => 'ῺΙ', 'ῴ' => 'ΏΙ', 'ᾷ' => 'Α͂Ι', 'ῇ' => 'Η͂Ι', 'ῷ' => 'Ω͂Ι');
<?php

namespace _HumbugBox1cb33d1f20f1;

// from Case_Ignorable in https://unicode.org/Public/UNIDATA/DerivedCoreProperties.txt
return '/(?<![\\x{0027}\\x{002E}\\x{003A}\\x{005E}\\x{0060}\\x{00A8}\\x{00AD}\\x{00AF}\\x{00B4}\\x{00B7}\\x{00B8}\\x{02B0}-\\x{02C1}\\x{02C2}-\\x{02C5}\\x{02C6}-\\x{02D1}\\x{02D2}-\\x{02DF}\\x{02E0}-\\x{02E4}\\x{02E5}-\\x{02EB}\\x{02EC}\\x{02ED}\\x{02EE}\\x{02EF}-\\x{02FF}\\x{0300}-\\x{036F}\\x{0374}\\x{0375}\\x{037A}\\x{0384}-\\x{0385}\\x{0387}\\x{0483}-\\x{0487}\\x{0488}-\\x{0489}\\x{0559}\\x{0591}-\\x{05BD}\\x{05BF}\\x{05C1}-\\x{05C2}\\x{05C4}-\\x{05C5}\\x{05C7}\\x{05F4}\\x{0600}-\\x{0605}\\x{0610}-\\x{061A}\\x{061C}\\x{0640}\\x{064B}-\\x{065F}\\x{0670}\\x{06D6}-\\x{06DC}\\x{06DD}\\x{06DF}-\\x{06E4}\\x{06E5}-\\x{06E6}\\x{06E7}-\\x{06E8}\\x{06EA}-\\x{06ED}\\x{070F}\\x{0711}\\x{0730}-\\x{074A}\\x{07A6}-\\x{07B0}\\x{07EB}-\\x{07F3}\\x{07F4}-\\x{07F5}\\x{07FA}\\x{07FD}\\x{0816}-\\x{0819}\\x{081A}\\x{081B}-\\x{0823}\\x{0824}\\x{0825}-\\x{0827}\\x{0828}\\x{0829}-\\x{082D}\\x{0859}-\\x{085B}\\x{08D3}-\\x{08E1}\\x{08E2}\\x{08E3}-\\x{0902}\\x{093A}\\x{093C}\\x{0941}-\\x{0948}\\x{094D}\\x{0951}-\\x{0957}\\x{0962}-\\x{0963}\\x{0971}\\x{0981}\\x{09BC}\\x{09C1}-\\x{09C4}\\x{09CD}\\x{09E2}-\\x{09E3}\\x{09FE}\\x{0A01}-\\x{0A02}\\x{0A3C}\\x{0A41}-\\x{0A42}\\x{0A47}-\\x{0A48}\\x{0A4B}-\\x{0A4D}\\x{0A51}\\x{0A70}-\\x{0A71}\\x{0A75}\\x{0A81}-\\x{0A82}\\x{0ABC}\\x{0AC1}-\\x{0AC5}\\x{0AC7}-\\x{0AC8}\\x{0ACD}\\x{0AE2}-\\x{0AE3}\\x{0AFA}-\\x{0AFF}\\x{0B01}\\x{0B3C}\\x{0B3F}\\x{0B41}-\\x{0B44}\\x{0B4D}\\x{0B56}\\x{0B62}-\\x{0B63}\\x{0B82}\\x{0BC0}\\x{0BCD}\\x{0C00}\\x{0C04}\\x{0C3E}-\\x{0C40}\\x{0C46}-\\x{0C48}\\x{0C4A}-\\x{0C4D}\\x{0C55}-\\x{0C56}\\x{0C62}-\\x{0C63}\\x{0C81}\\x{0CBC}\\x{0CBF}\\x{0CC6}\\x{0CCC}-\\x{0CCD}\\x{0CE2}-\\x{0CE3}\\x{0D00}-\\x{0D01}\\x{0D3B}-\\x{0D3C}\\x{0D41}-\\x{0D44}\\x{0D4D}\\x{0D62}-\\x{0D63}\\x{0DCA}\\x{0DD2}-\\x{0DD4}\\x{0DD6}\\x{0E31}\\x{0E34}-\\x{0E3A}\\x{0E46}\\x{0E47}-\\x{0E4E}\\x{0EB1}\\x{0EB4}-\\x{0EB9}\\x{0EBB}-\\x{0EBC}\\x{0EC6}\\x{0EC8}-\\x{0ECD}\\x{0F18}-\\x{0F19}\\x{0F35}\\x{0F37}\\x{0F39}\\x{0F71}-\\x{0F7E}\\x{0F80}-\\x{0F84}\\x{0F86}-\\x{0F87}\\x{0F8D}-\\x{0F97}\\x{0F99}-\\x{0FBC}\\x{0FC6}\\x{102D}-\\x{1030}\\x{1032}-\\x{1037}\\x{1039}-\\x{103A}\\x{103D}-\\x{103E}\\x{1058}-\\x{1059}\\x{105E}-\\x{1060}\\x{1071}-\\x{1074}\\x{1082}\\x{1085}-\\x{1086}\\x{108D}\\x{109D}\\x{10FC}\\x{135D}-\\x{135F}\\x{1712}-\\x{1714}\\x{1732}-\\x{1734}\\x{1752}-\\x{1753}\\x{1772}-\\x{1773}\\x{17B4}-\\x{17B5}\\x{17B7}-\\x{17BD}\\x{17C6}\\x{17C9}-\\x{17D3}\\x{17D7}\\x{17DD}\\x{180B}-\\x{180D}\\x{180E}\\x{1843}\\x{1885}-\\x{1886}\\x{18A9}\\x{1920}-\\x{1922}\\x{1927}-\\x{1928}\\x{1932}\\x{1939}-\\x{193B}\\x{1A17}-\\x{1A18}\\x{1A1B}\\x{1A56}\\x{1A58}-\\x{1A5E}\\x{1A60}\\x{1A62}\\x{1A65}-\\x{1A6C}\\x{1A73}-\\x{1A7C}\\x{1A7F}\\x{1AA7}\\x{1AB0}-\\x{1ABD}\\x{1ABE}\\x{1B00}-\\x{1B03}\\x{1B34}\\x{1B36}-\\x{1B3A}\\x{1B3C}\\x{1B42}\\x{1B6B}-\\x{1B73}\\x{1B80}-\\x{1B81}\\x{1BA2}-\\x{1BA5}\\x{1BA8}-\\x{1BA9}\\x{1BAB}-\\x{1BAD}\\x{1BE6}\\x{1BE8}-\\x{1BE9}\\x{1BED}\\x{1BEF}-\\x{1BF1}\\x{1C2C}-\\x{1C33}\\x{1C36}-\\x{1C37}\\x{1C78}-\\x{1C7D}\\x{1CD0}-\\x{1CD2}\\x{1CD4}-\\x{1CE0}\\x{1CE2}-\\x{1CE8}\\x{1CED}\\x{1CF4}\\x{1CF8}-\\x{1CF9}\\x{1D2C}-\\x{1D6A}\\x{1D78}\\x{1D9B}-\\x{1DBF}\\x{1DC0}-\\x{1DF9}\\x{1DFB}-\\x{1DFF}\\x{1FBD}\\x{1FBF}-\\x{1FC1}\\x{1FCD}-\\x{1FCF}\\x{1FDD}-\\x{1FDF}\\x{1FED}-\\x{1FEF}\\x{1FFD}-\\x{1FFE}\\x{200B}-\\x{200F}\\x{2018}\\x{2019}\\x{2024}\\x{2027}\\x{202A}-\\x{202E}\\x{2060}-\\x{2064}\\x{2066}-\\x{206F}\\x{2071}\\x{207F}\\x{2090}-\\x{209C}\\x{20D0}-\\x{20DC}\\x{20DD}-\\x{20E0}\\x{20E1}\\x{20E2}-\\x{20E4}\\x{20E5}-\\x{20F0}\\x{2C7C}-\\x{2C7D}\\x{2CEF}-\\x{2CF1}\\x{2D6F}\\x{2D7F}\\x{2DE0}-\\x{2DFF}\\x{2E2F}\\x{3005}\\x{302A}-\\x{302D}\\x{3031}-\\x{3035}\\x{303B}\\x{3099}-\\x{309A}\\x{309B}-\\x{309C}\\x{309D}-\\x{309E}\\x{30FC}-\\x{30FE}\\x{A015}\\x{A4F8}-\\x{A4FD}\\x{A60C}\\x{A66F}\\x{A670}-\\x{A672}\\x{A674}-\\x{A67D}\\x{A67F}\\x{A69C}-\\x{A69D}\\x{A69E}-\\x{A69F}\\x{A6F0}-\\x{A6F1}\\x{A700}-\\x{A716}\\x{A717}-\\x{A71F}\\x{A720}-\\x{A721}\\x{A770}\\x{A788}\\x{A789}-\\x{A78A}\\x{A7F8}-\\x{A7F9}\\x{A802}\\x{A806}\\x{A80B}\\x{A825}-\\x{A826}\\x{A8C4}-\\x{A8C5}\\x{A8E0}-\\x{A8F1}\\x{A8FF}\\x{A926}-\\x{A92D}\\x{A947}-\\x{A951}\\x{A980}-\\x{A982}\\x{A9B3}\\x{A9B6}-\\x{A9B9}\\x{A9BC}\\x{A9CF}\\x{A9E5}\\x{A9E6}\\x{AA29}-\\x{AA2E}\\x{AA31}-\\x{AA32}\\x{AA35}-\\x{AA36}\\x{AA43}\\x{AA4C}\\x{AA70}\\x{AA7C}\\x{AAB0}\\x{AAB2}-\\x{AAB4}\\x{AAB7}-\\x{AAB8}\\x{AABE}-\\x{AABF}\\x{AAC1}\\x{AADD}\\x{AAEC}-\\x{AAED}\\x{AAF3}-\\x{AAF4}\\x{AAF6}\\x{AB5B}\\x{AB5C}-\\x{AB5F}\\x{ABE5}\\x{ABE8}\\x{ABED}\\x{FB1E}\\x{FBB2}-\\x{FBC1}\\x{FE00}-\\x{FE0F}\\x{FE13}\\x{FE20}-\\x{FE2F}\\x{FE52}\\x{FE55}\\x{FEFF}\\x{FF07}\\x{FF0E}\\x{FF1A}\\x{FF3E}\\x{FF40}\\x{FF70}\\x{FF9E}-\\x{FF9F}\\x{FFE3}\\x{FFF9}-\\x{FFFB}\\x{101FD}\\x{102E0}\\x{10376}-\\x{1037A}\\x{10A01}-\\x{10A03}\\x{10A05}-\\x{10A06}\\x{10A0C}-\\x{10A0F}\\x{10A38}-\\x{10A3A}\\x{10A3F}\\x{10AE5}-\\x{10AE6}\\x{10D24}-\\x{10D27}\\x{10F46}-\\x{10F50}\\x{11001}\\x{11038}-\\x{11046}\\x{1107F}-\\x{11081}\\x{110B3}-\\x{110B6}\\x{110B9}-\\x{110BA}\\x{110BD}\\x{110CD}\\x{11100}-\\x{11102}\\x{11127}-\\x{1112B}\\x{1112D}-\\x{11134}\\x{11173}\\x{11180}-\\x{11181}\\x{111B6}-\\x{111BE}\\x{111C9}-\\x{111CC}\\x{1122F}-\\x{11231}\\x{11234}\\x{11236}-\\x{11237}\\x{1123E}\\x{112DF}\\x{112E3}-\\x{112EA}\\x{11300}-\\x{11301}\\x{1133B}-\\x{1133C}\\x{11340}\\x{11366}-\\x{1136C}\\x{11370}-\\x{11374}\\x{11438}-\\x{1143F}\\x{11442}-\\x{11444}\\x{11446}\\x{1145E}\\x{114B3}-\\x{114B8}\\x{114BA}\\x{114BF}-\\x{114C0}\\x{114C2}-\\x{114C3}\\x{115B2}-\\x{115B5}\\x{115BC}-\\x{115BD}\\x{115BF}-\\x{115C0}\\x{115DC}-\\x{115DD}\\x{11633}-\\x{1163A}\\x{1163D}\\x{1163F}-\\x{11640}\\x{116AB}\\x{116AD}\\x{116B0}-\\x{116B5}\\x{116B7}\\x{1171D}-\\x{1171F}\\x{11722}-\\x{11725}\\x{11727}-\\x{1172B}\\x{1182F}-\\x{11837}\\x{11839}-\\x{1183A}\\x{11A01}-\\x{11A0A}\\x{11A33}-\\x{11A38}\\x{11A3B}-\\x{11A3E}\\x{11A47}\\x{11A51}-\\x{11A56}\\x{11A59}-\\x{11A5B}\\x{11A8A}-\\x{11A96}\\x{11A98}-\\x{11A99}\\x{11C30}-\\x{11C36}\\x{11C38}-\\x{11C3D}\\x{11C3F}\\x{11C92}-\\x{11CA7}\\x{11CAA}-\\x{11CB0}\\x{11CB2}-\\x{11CB3}\\x{11CB5}-\\x{11CB6}\\x{11D31}-\\x{11D36}\\x{11D3A}\\x{11D3C}-\\x{11D3D}\\x{11D3F}-\\x{11D45}\\x{11D47}\\x{11D90}-\\x{11D91}\\x{11D95}\\x{11D97}\\x{11EF3}-\\x{11EF4}\\x{16AF0}-\\x{16AF4}\\x{16B30}-\\x{16B36}\\x{16B40}-\\x{16B43}\\x{16F8F}-\\x{16F92}\\x{16F93}-\\x{16F9F}\\x{16FE0}-\\x{16FE1}\\x{1BC9D}-\\x{1BC9E}\\x{1BCA0}-\\x{1BCA3}\\x{1D167}-\\x{1D169}\\x{1D173}-\\x{1D17A}\\x{1D17B}-\\x{1D182}\\x{1D185}-\\x{1D18B}\\x{1D1AA}-\\x{1D1AD}\\x{1D242}-\\x{1D244}\\x{1DA00}-\\x{1DA36}\\x{1DA3B}-\\x{1DA6C}\\x{1DA75}\\x{1DA84}\\x{1DA9B}-\\x{1DA9F}\\x{1DAA1}-\\x{1DAAF}\\x{1E000}-\\x{1E006}\\x{1E008}-\\x{1E018}\\x{1E01B}-\\x{1E021}\\x{1E023}-\\x{1E024}\\x{1E026}-\\x{1E02A}\\x{1E8D0}-\\x{1E8D6}\\x{1E944}-\\x{1E94A}\\x{1F3FB}-\\x{1F3FF}\\x{E0001}\\x{E0020}-\\x{E007F}\\x{E0100}-\\x{E01EF}])(\\pL)(\\pL*+)/u';
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Mbstring as p;
if (!\function_exists('mb_convert_encoding')) {
    function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null) : array|string|false
    {
        return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding);
    }
}
if (!\function_exists('mb_decode_mimeheader')) {
    function mb_decode_mimeheader(?string $string) : string
    {
        return p\Mbstring::mb_decode_mimeheader((string) $string);
    }
}
if (!\function_exists('mb_encode_mimeheader')) {
    function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0) : string
    {
        return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent);
    }
}
if (!\function_exists('mb_decode_numericentity')) {
    function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null) : string
    {
        return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding);
    }
}
if (!\function_exists('mb_encode_numericentity')) {
    function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = \false) : string
    {
        return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex);
    }
}
if (!\function_exists('mb_convert_case')) {
    function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null) : string
    {
        return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding);
    }
}
if (!\function_exists('mb_internal_encoding')) {
    function mb_internal_encoding(?string $encoding = null) : string|bool
    {
        return p\Mbstring::mb_internal_encoding($encoding);
    }
}
if (!\function_exists('mb_language')) {
    function mb_language(?string $language = null) : string|bool
    {
        return p\Mbstring::mb_language($language);
    }
}
if (!\function_exists('mb_list_encodings')) {
    function mb_list_encodings() : array
    {
        return p\Mbstring::mb_list_encodings();
    }
}
if (!\function_exists('mb_encoding_aliases')) {
    function mb_encoding_aliases(?string $encoding) : array
    {
        return p\Mbstring::mb_encoding_aliases((string) $encoding);
    }
}
if (!\function_exists('mb_check_encoding')) {
    function mb_check_encoding(array|string|null $value = null, ?string $encoding = null) : bool
    {
        return p\Mbstring::mb_check_encoding($value, $encoding);
    }
}
if (!\function_exists('mb_detect_encoding')) {
    function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = \false) : string|false
    {
        return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict);
    }
}
if (!\function_exists('mb_detect_order')) {
    function mb_detect_order(array|string|null $encoding = null) : array|bool
    {
        return p\Mbstring::mb_detect_order($encoding);
    }
}
if (!\function_exists('mb_parse_str')) {
    function mb_parse_str(?string $string, &$result = []) : bool
    {
        \parse_str((string) $string, $result);
        return (bool) $result;
    }
}
if (!\function_exists('mb_strlen')) {
    function mb_strlen(?string $string, ?string $encoding = null) : int
    {
        return p\Mbstring::mb_strlen((string) $string, $encoding);
    }
}
if (!\function_exists('mb_strpos')) {
    function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false
    {
        return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding);
    }
}
if (!\function_exists('mb_strtolower')) {
    function mb_strtolower(?string $string, ?string $encoding = null) : string
    {
        return p\Mbstring::mb_strtolower((string) $string, $encoding);
    }
}
if (!\function_exists('mb_strtoupper')) {
    function mb_strtoupper(?string $string, ?string $encoding = null) : string
    {
        return p\Mbstring::mb_strtoupper((string) $string, $encoding);
    }
}
if (!\function_exists('mb_substitute_character')) {
    function mb_substitute_character(string|int|null $substitute_character = null) : string|int|bool
    {
        return p\Mbstring::mb_substitute_character($substitute_character);
    }
}
if (!\function_exists('mb_substr')) {
    function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null) : string
    {
        return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding);
    }
}
if (!\function_exists('mb_stripos')) {
    function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false
    {
        return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding);
    }
}
if (!\function_exists('mb_stristr')) {
    function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false
    {
        return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding);
    }
}
if (!\function_exists('mb_strrchr')) {
    function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false
    {
        return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding);
    }
}
if (!\function_exists('mb_strrichr')) {
    function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false
    {
        return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding);
    }
}
if (!\function_exists('mb_strripos')) {
    function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false
    {
        return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding);
    }
}
if (!\function_exists('mb_strrpos')) {
    function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null) : int|false
    {
        return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding);
    }
}
if (!\function_exists('mb_strstr')) {
    function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = \false, ?string $encoding = null) : string|false
    {
        return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding);
    }
}
if (!\function_exists('mb_get_info')) {
    function mb_get_info(?string $type = 'all') : array|string|int|false
    {
        return p\Mbstring::mb_get_info((string) $type);
    }
}
if (!\function_exists('mb_http_output')) {
    function mb_http_output(?string $encoding = null) : string|bool
    {
        return p\Mbstring::mb_http_output($encoding);
    }
}
if (!\function_exists('mb_strwidth')) {
    function mb_strwidth(?string $string, ?string $encoding = null) : int
    {
        return p\Mbstring::mb_strwidth((string) $string, $encoding);
    }
}
if (!\function_exists('mb_substr_count')) {
    function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null) : int
    {
        return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding);
    }
}
if (!\function_exists('mb_output_handler')) {
    function mb_output_handler(?string $string, ?int $status) : string
    {
        return p\Mbstring::mb_output_handler((string) $string, (int) $status);
    }
}
if (!\function_exists('mb_http_input')) {
    function mb_http_input(?string $type = null) : array|string|false
    {
        return p\Mbstring::mb_http_input($type);
    }
}
if (!\function_exists('mb_convert_variables')) {
    function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars) : string|false
    {
        return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars);
    }
}
if (!\function_exists('mb_ord')) {
    function mb_ord(?string $string, ?string $encoding = null) : int|false
    {
        return p\Mbstring::mb_ord((string) $string, $encoding);
    }
}
if (!\function_exists('mb_chr')) {
    function mb_chr(?int $codepoint, ?string $encoding = null) : string|false
    {
        return p\Mbstring::mb_chr((int) $codepoint, $encoding);
    }
}
if (!\function_exists('mb_scrub')) {
    function mb_scrub(?string $string, ?string $encoding = null) : string
    {
        $encoding ??= \mb_internal_encoding();
        return \mb_convert_encoding((string) $string, $encoding, $encoding);
    }
}
if (!\function_exists('mb_str_split')) {
    function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null) : array
    {
        return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding);
    }
}
if (\extension_loaded('mbstring')) {
    return;
}
if (!\defined('MB_CASE_UPPER')) {
    \define('MB_CASE_UPPER', 0);
}
if (!\defined('MB_CASE_LOWER')) {
    \define('MB_CASE_LOWER', 1);
}
if (!\defined('MB_CASE_TITLE')) {
    \define('MB_CASE_TITLE', 2);
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
if (!\function_exists('_HumbugBox1cb33d1f20f1\\trigger_deprecation')) {
    /**
     * Triggers a silenced deprecation notice.
     *
     * @param string $package The name of the Composer package that is triggering the deprecation
     * @param string $version The version of the package that introduced the deprecation
     * @param string $message The message of the deprecation
     * @param mixed  ...$args Values to insert in the message using printf() formatting
     *
     * @author Nicolas Grekas <p@tchwork.com>
     */
    function trigger_deprecation(string $package, string $version, string $message, ...$args) : void
    {
        @\trigger_error(($package || $version ? "Since {$package} {$version}: " : '') . ($args ? \vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
    }
}
Copyright (c) 2020-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Php80 as p;
if (\PHP_VERSION_ID >= 80000) {
    return;
}
if (!\defined('FILTER_VALIDATE_BOOL') && \defined('FILTER_VALIDATE_BOOLEAN')) {
    \define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN);
}
if (!\function_exists('fdiv')) {
    function fdiv(float $num1, float $num2) : float
    {
        return p\Php80::fdiv($num1, $num2);
    }
}
if (!\function_exists('preg_last_error_msg')) {
    function preg_last_error_msg() : string
    {
        return p\Php80::preg_last_error_msg();
    }
}
if (!\function_exists('str_contains')) {
    function str_contains(?string $haystack, ?string $needle) : bool
    {
        return p\Php80::str_contains($haystack ?? '', $needle ?? '');
    }
}
if (!\function_exists('str_starts_with')) {
    function str_starts_with(?string $haystack, ?string $needle) : bool
    {
        return p\Php80::str_starts_with($haystack ?? '', $needle ?? '');
    }
}
if (!\function_exists('str_ends_with')) {
    function str_ends_with(?string $haystack, ?string $needle) : bool
    {
        return p\Php80::str_ends_with($haystack ?? '', $needle ?? '');
    }
}
if (!\function_exists('get_debug_type')) {
    function get_debug_type($value) : string
    {
        return p\Php80::get_debug_type($value);
    }
}
if (!\function_exists('get_resource_id')) {
    function get_resource_id($resource) : int
    {
        return p\Php80::get_resource_id($resource);
    }
}
Copyright (c) 2020 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#[Attribute(Attribute::TARGET_CLASS)]
final class Attribute
{
    public const TARGET_CLASS = 1;
    public const TARGET_FUNCTION = 2;
    public const TARGET_METHOD = 4;
    public const TARGET_PROPERTY = 8;
    public const TARGET_CLASS_CONSTANT = 16;
    public const TARGET_PARAMETER = 32;
    public const TARGET_ALL = 63;
    public const IS_REPEATABLE = 64;

    /** @var int */
    public $flags;

    public function __construct(int $flags = self::TARGET_ALL)
    {
        $this->flags = $flags;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

if (\PHP_VERSION_ID < 80000) {
    interface Stringable
    {
        /**
         * @return string
         */
        public function __toString();
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
if (\PHP_VERSION_ID < 80000) {
    class UnhandledMatchError extends \Error
    {
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
if (\PHP_VERSION_ID < 80000) {
    class ValueError extends \Error
    {
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) {
    class PhpToken extends Symfony\Polyfill\Php80\PhpToken
    {
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php80;

/**
 * @author Ion Bazan <ion.bazan@gmail.com>
 * @author Nico Oelgart <nicoswd@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Php80
{
    public static function fdiv(float $dividend, float $divisor): float
    {
        return @($dividend / $divisor);
    }

    public static function get_debug_type($value): string
    {
        switch (true) {
            case null === $value: return 'null';
            case \is_bool($value): return 'bool';
            case \is_string($value): return 'string';
            case \is_array($value): return 'array';
            case \is_int($value): return 'int';
            case \is_float($value): return 'float';
            case \is_object($value): break;
            case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
            default:
                if (null === $type = @get_resource_type($value)) {
                    return 'unknown';
                }

                if ('Unknown' === $type) {
                    $type = 'closed';
                }

                return "resource ($type)";
        }

        $class = \get_class($value);

        if (false === strpos($class, '@')) {
            return $class;
        }

        return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
    }

    public static function get_resource_id($res): int
    {
        if (!\is_resource($res) && null === @get_resource_type($res)) {
            throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
        }

        return (int) $res;
    }

    public static function preg_last_error_msg(): string
    {
        switch (preg_last_error()) {
            case \PREG_INTERNAL_ERROR:
                return 'Internal error';
            case \PREG_BAD_UTF8_ERROR:
                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
            case \PREG_BAD_UTF8_OFFSET_ERROR:
                return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
            case \PREG_BACKTRACK_LIMIT_ERROR:
                return 'Backtrack limit exhausted';
            case \PREG_RECURSION_LIMIT_ERROR:
                return 'Recursion limit exhausted';
            case \PREG_JIT_STACKLIMIT_ERROR:
                return 'JIT stack limit exhausted';
            case \PREG_NO_ERROR:
                return 'No error';
            default:
                return 'Unknown error';
        }
    }

    public static function str_contains(string $haystack, string $needle): bool
    {
        return '' === $needle || false !== strpos($haystack, $needle);
    }

    public static function str_starts_with(string $haystack, string $needle): bool
    {
        return 0 === strncmp($haystack, $needle, \strlen($needle));
    }

    public static function str_ends_with(string $haystack, string $needle): bool
    {
        if ('' === $needle || $needle === $haystack) {
            return true;
        }

        if ('' === $haystack) {
            return false;
        }

        $needleLength = \strlen($needle);

        return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Polyfill\Php80;

/**
 * @author Fedonyuk Anton <info@ensostudio.ru>
 *
 * @internal
 */
class PhpToken implements \Stringable
{
    /**
     * @var int
     */
    public $id;

    /**
     * @var string
     */
    public $text;

    /**
     * @var int
     */
    public $line;

    /**
     * @var int
     */
    public $pos;

    public function __construct(int $id, string $text, int $line = -1, int $position = -1)
    {
        $this->id = $id;
        $this->text = $text;
        $this->line = $line;
        $this->pos = $position;
    }

    public function getTokenName(): ?string
    {
        if ('UNKNOWN' === $name = token_name($this->id)) {
            $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text;
        }

        return $name;
    }

    /**
     * @param int|string|array $kind
     */
    public function is($kind): bool
    {
        foreach ((array) $kind as $value) {
            if (\in_array($value, [$this->id, $this->text], true)) {
                return true;
            }
        }

        return false;
    }

    public function isIgnorable(): bool
    {
        return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true);
    }

    public function __toString(): string
    {
        return (string) $this->text;
    }

    /**
     * @return static[]
     */
    public static function tokenize(string $code, int $flags = 0): array
    {
        $line = 1;
        $position = 0;
        $tokens = token_get_all($code, $flags);
        foreach ($tokens as $index => $token) {
            if (\is_string($token)) {
                $id = \ord($token);
                $text = $token;
            } else {
                [$id, $text, $line] = $token;
            }
            $tokens[$index] = new static($id, $text, $line, $position);
            $position += \strlen($text);
        }

        return $tokens;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleCommandEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleErrorEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleSignalEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleTerminateEvent;
/**
 * Contains all events dispatched by an Application.
 *
 * @author Francesco Levorato <git@flevour.net>
 */
final class ConsoleEvents
{
    /**
     * The COMMAND event allows you to attach listeners before any command is
     * executed by the console. It also allows you to modify the command, input and output
     * before they are handed to the command.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent")
     */
    public const COMMAND = 'console.command';
    /**
     * The SIGNAL event allows you to perform some actions
     * after the command execution was interrupted.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleSignalEvent")
     */
    public const SIGNAL = 'console.signal';
    /**
     * The TERMINATE event allows you to attach listeners after a command is
     * executed by the console.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent")
     */
    public const TERMINATE = 'console.terminate';
    /**
     * The ERROR event occurs when an uncaught exception or error appears.
     *
     * This event allows you to deal with the exception/error or
     * to modify the thrown exception.
     *
     * @Event("Symfony\Component\Console\Event\ConsoleErrorEvent")
     */
    public const ERROR = 'console.error';
    /**
     * Event aliases.
     *
     * These aliases can be consumed by RegisterListenersPass.
     */
    public const ALIASES = [ConsoleCommandEvent::class => self::COMMAND, ConsoleErrorEvent::class => self::ERROR, ConsoleSignalEvent::class => self::SIGNAL, ConsoleTerminateEvent::class => self::TERMINATE];
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
/**
 * ArgvInput represents an input coming from the CLI arguments.
 *
 * Usage:
 *
 *     $input = new ArgvInput();
 *
 * By default, the `$_SERVER['argv']` array is used for the input values.
 *
 * This can be overridden by explicitly passing the input values in the constructor:
 *
 *     $input = new ArgvInput($_SERVER['argv']);
 *
 * If you pass it yourself, don't forget that the first element of the array
 * is the name of the running application.
 *
 * When passing an argument to the constructor, be sure that it respects
 * the same rules as the argv one. It's almost always better to use the
 * `StringInput` when you want to provide your own input.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
 * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
 */
class ArgvInput extends Input
{
    private $tokens;
    private $parsed;
    public function __construct(array $argv = null, InputDefinition $definition = null)
    {
        $argv = $argv ?? $_SERVER['argv'] ?? [];
        // strip the application name
        \array_shift($argv);
        $this->tokens = $argv;
        parent::__construct($definition);
    }
    protected function setTokens(array $tokens)
    {
        $this->tokens = $tokens;
    }
    /**
     * {@inheritdoc}
     */
    protected function parse()
    {
        $parseOptions = \true;
        $this->parsed = $this->tokens;
        while (null !== ($token = \array_shift($this->parsed))) {
            $parseOptions = $this->parseToken($token, $parseOptions);
        }
    }
    protected function parseToken(string $token, bool $parseOptions) : bool
    {
        if ($parseOptions && '' == $token) {
            $this->parseArgument($token);
        } elseif ($parseOptions && '--' == $token) {
            return \false;
        } elseif ($parseOptions && \str_starts_with($token, '--')) {
            $this->parseLongOption($token);
        } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
            $this->parseShortOption($token);
        } else {
            $this->parseArgument($token);
        }
        return $parseOptions;
    }
    /**
     * Parses a short option.
     */
    private function parseShortOption(string $token)
    {
        $name = \substr($token, 1);
        if (\strlen($name) > 1) {
            if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
                // an option with a value (with no space)
                $this->addShortOption($name[0], \substr($name, 1));
            } else {
                $this->parseShortOptionSet($name);
            }
        } else {
            $this->addShortOption($name, null);
        }
    }
    /**
     * Parses a short option set.
     *
     * @throws RuntimeException When option given doesn't exist
     */
    private function parseShortOptionSet(string $name)
    {
        $len = \strlen($name);
        for ($i = 0; $i < $len; ++$i) {
            if (!$this->definition->hasShortcut($name[$i])) {
                $encoding = \mb_detect_encoding($name, null, \true);
                throw new RuntimeException(\sprintf('The "-%s" option does not exist.', \false === $encoding ? $name[$i] : \mb_substr($name, $i, 1, $encoding)));
            }
            $option = $this->definition->getOptionForShortcut($name[$i]);
            if ($option->acceptValue()) {
                $this->addLongOption($option->getName(), $i === $len - 1 ? null : \substr($name, $i + 1));
                break;
            } else {
                $this->addLongOption($option->getName(), null);
            }
        }
    }
    /**
     * Parses a long option.
     */
    private function parseLongOption(string $token)
    {
        $name = \substr($token, 2);
        if (\false !== ($pos = \strpos($name, '='))) {
            if ('' === ($value = \substr($name, $pos + 1))) {
                \array_unshift($this->parsed, $value);
            }
            $this->addLongOption(\substr($name, 0, $pos), $value);
        } else {
            $this->addLongOption($name, null);
        }
    }
    /**
     * Parses an argument.
     *
     * @throws RuntimeException When too many arguments are given
     */
    private function parseArgument(string $token)
    {
        $c = \count($this->arguments);
        // if input is expecting another argument, add it
        if ($this->definition->hasArgument($c)) {
            $arg = $this->definition->getArgument($c);
            $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;
            // if last argument isArray(), append token to last argument
        } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
            $arg = $this->definition->getArgument($c - 1);
            $this->arguments[$arg->getName()][] = $token;
            // unexpected argument
        } else {
            $all = $this->definition->getArguments();
            $symfonyCommandName = null;
            if (($inputArgument = $all[$key = \array_key_first($all)] ?? null) && 'command' === $inputArgument->getName()) {
                $symfonyCommandName = $this->arguments['command'] ?? null;
                unset($all[$key]);
            }
            if (\count($all)) {
                if ($symfonyCommandName) {
                    $message = \sprintf('Too many arguments to "%s" command, expected arguments "%s".', $symfonyCommandName, \implode('" "', \array_keys($all)));
                } else {
                    $message = \sprintf('Too many arguments, expected arguments "%s".', \implode('" "', \array_keys($all)));
                }
            } elseif ($symfonyCommandName) {
                $message = \sprintf('No arguments expected for "%s" command, got "%s".', $symfonyCommandName, $token);
            } else {
                $message = \sprintf('No arguments expected, got "%s".', $token);
            }
            throw new RuntimeException($message);
        }
    }
    /**
     * Adds a short option value.
     *
     * @throws RuntimeException When option given doesn't exist
     */
    private function addShortOption(string $shortcut, $value)
    {
        if (!$this->definition->hasShortcut($shortcut)) {
            throw new RuntimeException(\sprintf('The "-%s" option does not exist.', $shortcut));
        }
        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
    }
    /**
     * Adds a long option value.
     *
     * @throws RuntimeException When option given doesn't exist
     */
    private function addLongOption(string $name, $value)
    {
        if (!$this->definition->hasOption($name)) {
            if (!$this->definition->hasNegation($name)) {
                throw new RuntimeException(\sprintf('The "--%s" option does not exist.', $name));
            }
            $optionName = $this->definition->negationToName($name);
            if (null !== $value) {
                throw new RuntimeException(\sprintf('The "--%s" option does not accept a value.', $name));
            }
            $this->options[$optionName] = \false;
            return;
        }
        $option = $this->definition->getOption($name);
        if (null !== $value && !$option->acceptValue()) {
            throw new RuntimeException(\sprintf('The "--%s" option does not accept a value.', $name));
        }
        if (\in_array($value, ['', null], \true) && $option->acceptValue() && \count($this->parsed)) {
            // if option accepts an optional or mandatory argument
            // let's see if there is one provided
            $next = \array_shift($this->parsed);
            if (isset($next[0]) && '-' !== $next[0] || \in_array($next, ['', null], \true)) {
                $value = $next;
            } else {
                \array_unshift($this->parsed, $next);
            }
        }
        if (null === $value) {
            if ($option->isValueRequired()) {
                throw new RuntimeException(\sprintf('The "--%s" option requires a value.', $name));
            }
            if (!$option->isArray() && !$option->isValueOptional()) {
                $value = \true;
            }
        }
        if ($option->isArray()) {
            $this->options[$name][] = $value;
        } else {
            $this->options[$name] = $value;
        }
    }
    /**
     * {@inheritdoc}
     */
    public function getFirstArgument()
    {
        $isOption = \false;
        foreach ($this->tokens as $i => $token) {
            if ($token && '-' === $token[0]) {
                if (\str_contains($token, '=') || !isset($this->tokens[$i + 1])) {
                    continue;
                }
                // If it's a long option, consider that everything after "--" is the option name.
                // Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator)
                $name = '-' === $token[1] ? \substr($token, 2) : \substr($token, -1);
                if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) {
                    // noop
                } elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) {
                    $isOption = \true;
                }
                continue;
            }
            if ($isOption) {
                $isOption = \false;
                continue;
            }
            return $token;
        }
        return null;
    }
    /**
     * {@inheritdoc}
     */
    public function hasParameterOption($values, bool $onlyParams = \false)
    {
        $values = (array) $values;
        foreach ($this->tokens as $token) {
            if ($onlyParams && '--' === $token) {
                return \false;
            }
            foreach ($values as $value) {
                // Options with values:
                //   For long options, test for '--option=' at beginning
                //   For short options, test for '-o' at beginning
                $leading = \str_starts_with($value, '--') ? $value . '=' : $value;
                if ($token === $value || '' !== $leading && \str_starts_with($token, $leading)) {
                    return \true;
                }
            }
        }
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function getParameterOption($values, $default = \false, bool $onlyParams = \false)
    {
        $values = (array) $values;
        $tokens = $this->tokens;
        while (0 < \count($tokens)) {
            $token = \array_shift($tokens);
            if ($onlyParams && '--' === $token) {
                return $default;
            }
            foreach ($values as $value) {
                if ($token === $value) {
                    return \array_shift($tokens);
                }
                // Options with values:
                //   For long options, test for '--option=' at beginning
                //   For short options, test for '-o' at beginning
                $leading = \str_starts_with($value, '--') ? $value . '=' : $value;
                if ('' !== $leading && \str_starts_with($token, $leading)) {
                    return \substr($token, \strlen($leading));
                }
            }
        }
        return $default;
    }
    /**
     * Returns a stringified representation of the args passed to the command.
     *
     * @return string
     */
    public function __toString()
    {
        $tokens = \array_map(function ($token) {
            if (\preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
                return $match[1] . $this->escapeToken($match[2]);
            }
            if ($token && '-' !== $token[0]) {
                return $this->escapeToken($token);
            }
            return $token;
        }, $this->tokens);
        return \implode(' ', $tokens);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
/**
 * InputInterface is the interface implemented by all input classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface InputInterface
{
    /**
     * Returns the first argument from the raw parameters (not parsed).
     *
     * @return string|null
     */
    public function getFirstArgument();
    /**
     * Returns true if the raw parameters (not parsed) contain a value.
     *
     * This method is to be used to introspect the input parameters
     * before they have been validated. It must be used carefully.
     * Does not necessarily return the correct result for short options
     * when multiple flags are combined in the same option.
     *
     * @param string|array $values     The values to look for in the raw parameters (can be an array)
     * @param bool         $onlyParams Only check real parameters, skip those following an end of options (--) signal
     *
     * @return bool
     */
    public function hasParameterOption($values, bool $onlyParams = \false);
    /**
     * Returns the value of a raw option (not parsed).
     *
     * This method is to be used to introspect the input parameters
     * before they have been validated. It must be used carefully.
     * Does not necessarily return the correct result for short options
     * when multiple flags are combined in the same option.
     *
     * @param string|array                     $values     The value(s) to look for in the raw parameters (can be an array)
     * @param string|bool|int|float|array|null $default    The default value to return if no result is found
     * @param bool                             $onlyParams Only check real parameters, skip those following an end of options (--) signal
     *
     * @return mixed
     */
    public function getParameterOption($values, $default = \false, bool $onlyParams = \false);
    /**
     * Binds the current Input instance with the given arguments and options.
     *
     * @throws RuntimeException
     */
    public function bind(InputDefinition $definition);
    /**
     * Validates the input.
     *
     * @throws RuntimeException When not enough arguments are given
     */
    public function validate();
    /**
     * Returns all the given arguments merged with the default values.
     *
     * @return array<string|bool|int|float|array|null>
     */
    public function getArguments();
    /**
     * Returns the argument value for a given argument name.
     *
     * @return mixed
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    public function getArgument(string $name);
    /**
     * Sets an argument value by name.
     *
     * @param mixed $value The argument value
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    public function setArgument(string $name, $value);
    /**
     * Returns true if an InputArgument object exists by name or position.
     *
     * @return bool
     */
    public function hasArgument(string $name);
    /**
     * Returns all the given options merged with the default values.
     *
     * @return array<string|bool|int|float|array|null>
     */
    public function getOptions();
    /**
     * Returns the option value for a given option name.
     *
     * @return mixed
     *
     * @throws InvalidArgumentException When option given doesn't exist
     */
    public function getOption(string $name);
    /**
     * Sets an option value by name.
     *
     * @param mixed $value The option value
     *
     * @throws InvalidArgumentException When option given doesn't exist
     */
    public function setOption(string $name, $value);
    /**
     * Returns true if an InputOption object exists by name.
     *
     * @return bool
     */
    public function hasOption(string $name);
    /**
     * Is this input means interactive?
     *
     * @return bool
     */
    public function isInteractive();
    /**
     * Sets the input interactivity.
     */
    public function setInteractive(bool $interactive);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
/**
 * Represents a command line argument.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InputArgument
{
    public const REQUIRED = 1;
    public const OPTIONAL = 2;
    public const IS_ARRAY = 4;
    private $name;
    private $mode;
    private $default;
    private $description;
    /**
     * @param string                           $name        The argument name
     * @param int|null                         $mode        The argument mode: self::REQUIRED or self::OPTIONAL
     * @param string                           $description A description text
     * @param string|bool|int|float|array|null $default     The default value (for self::OPTIONAL mode only)
     *
     * @throws InvalidArgumentException When argument mode is not valid
     */
    public function __construct(string $name, int $mode = null, string $description = '', $default = null)
    {
        if (null === $mode) {
            $mode = self::OPTIONAL;
        } elseif ($mode > 7 || $mode < 1) {
            throw new InvalidArgumentException(\sprintf('Argument mode "%s" is not valid.', $mode));
        }
        $this->name = $name;
        $this->mode = $mode;
        $this->description = $description;
        $this->setDefault($default);
    }
    /**
     * Returns the argument name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Returns true if the argument is required.
     *
     * @return bool true if parameter mode is self::REQUIRED, false otherwise
     */
    public function isRequired()
    {
        return self::REQUIRED === (self::REQUIRED & $this->mode);
    }
    /**
     * Returns true if the argument can take multiple values.
     *
     * @return bool true if mode is self::IS_ARRAY, false otherwise
     */
    public function isArray()
    {
        return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);
    }
    /**
     * Sets the default value.
     *
     * @param string|bool|int|float|array|null $default
     *
     * @throws LogicException When incorrect default value is given
     */
    public function setDefault($default = null)
    {
        if ($this->isRequired() && null !== $default) {
            throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');
        }
        if ($this->isArray()) {
            if (null === $default) {
                $default = [];
            } elseif (!\is_array($default)) {
                throw new LogicException('A default value for an array argument must be an array.');
            }
        }
        $this->default = $default;
    }
    /**
     * Returns the default value.
     *
     * @return string|bool|int|float|array|null
     */
    public function getDefault()
    {
        return $this->default;
    }
    /**
     * Returns the description text.
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

/**
 * InputAwareInterface should be implemented by classes that depends on the
 * Console Input.
 *
 * @author Wouter J <waldio.webdesign@gmail.com>
 */
interface InputAwareInterface
{
    /**
     * Sets the Console Input.
     */
    public function setInput(InputInterface $input);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
/**
 * A InputDefinition represents a set of valid command line arguments and options.
 *
 * Usage:
 *
 *     $definition = new InputDefinition([
 *         new InputArgument('name', InputArgument::REQUIRED),
 *         new InputOption('foo', 'f', InputOption::VALUE_REQUIRED),
 *     ]);
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InputDefinition
{
    private $arguments;
    private $requiredCount;
    private $lastArrayArgument;
    private $lastOptionalArgument;
    private $options;
    private $negations;
    private $shortcuts;
    /**
     * @param array $definition An array of InputArgument and InputOption instance
     */
    public function __construct(array $definition = [])
    {
        $this->setDefinition($definition);
    }
    /**
     * Sets the definition of the input.
     */
    public function setDefinition(array $definition)
    {
        $arguments = [];
        $options = [];
        foreach ($definition as $item) {
            if ($item instanceof InputOption) {
                $options[] = $item;
            } else {
                $arguments[] = $item;
            }
        }
        $this->setArguments($arguments);
        $this->setOptions($options);
    }
    /**
     * Sets the InputArgument objects.
     *
     * @param InputArgument[] $arguments An array of InputArgument objects
     */
    public function setArguments(array $arguments = [])
    {
        $this->arguments = [];
        $this->requiredCount = 0;
        $this->lastOptionalArgument = null;
        $this->lastArrayArgument = null;
        $this->addArguments($arguments);
    }
    /**
     * Adds an array of InputArgument objects.
     *
     * @param InputArgument[] $arguments An array of InputArgument objects
     */
    public function addArguments(?array $arguments = [])
    {
        if (null !== $arguments) {
            foreach ($arguments as $argument) {
                $this->addArgument($argument);
            }
        }
    }
    /**
     * @throws LogicException When incorrect argument is given
     */
    public function addArgument(InputArgument $argument)
    {
        if (isset($this->arguments[$argument->getName()])) {
            throw new LogicException(\sprintf('An argument with name "%s" already exists.', $argument->getName()));
        }
        if (null !== $this->lastArrayArgument) {
            throw new LogicException(\sprintf('Cannot add a required argument "%s" after an array argument "%s".', $argument->getName(), $this->lastArrayArgument->getName()));
        }
        if ($argument->isRequired() && null !== $this->lastOptionalArgument) {
            throw new LogicException(\sprintf('Cannot add a required argument "%s" after an optional one "%s".', $argument->getName(), $this->lastOptionalArgument->getName()));
        }
        if ($argument->isArray()) {
            $this->lastArrayArgument = $argument;
        }
        if ($argument->isRequired()) {
            ++$this->requiredCount;
        } else {
            $this->lastOptionalArgument = $argument;
        }
        $this->arguments[$argument->getName()] = $argument;
    }
    /**
     * Returns an InputArgument by name or by position.
     *
     * @param string|int $name The InputArgument name or position
     *
     * @return InputArgument
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    public function getArgument($name)
    {
        if (!$this->hasArgument($name)) {
            throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
        }
        $arguments = \is_int($name) ? \array_values($this->arguments) : $this->arguments;
        return $arguments[$name];
    }
    /**
     * Returns true if an InputArgument object exists by name or position.
     *
     * @param string|int $name The InputArgument name or position
     *
     * @return bool
     */
    public function hasArgument($name)
    {
        $arguments = \is_int($name) ? \array_values($this->arguments) : $this->arguments;
        return isset($arguments[$name]);
    }
    /**
     * Gets the array of InputArgument objects.
     *
     * @return InputArgument[]
     */
    public function getArguments()
    {
        return $this->arguments;
    }
    /**
     * Returns the number of InputArguments.
     *
     * @return int
     */
    public function getArgumentCount()
    {
        return null !== $this->lastArrayArgument ? \PHP_INT_MAX : \count($this->arguments);
    }
    /**
     * Returns the number of required InputArguments.
     *
     * @return int
     */
    public function getArgumentRequiredCount()
    {
        return $this->requiredCount;
    }
    /**
     * @return array<string|bool|int|float|array|null>
     */
    public function getArgumentDefaults()
    {
        $values = [];
        foreach ($this->arguments as $argument) {
            $values[$argument->getName()] = $argument->getDefault();
        }
        return $values;
    }
    /**
     * Sets the InputOption objects.
     *
     * @param InputOption[] $options An array of InputOption objects
     */
    public function setOptions(array $options = [])
    {
        $this->options = [];
        $this->shortcuts = [];
        $this->negations = [];
        $this->addOptions($options);
    }
    /**
     * Adds an array of InputOption objects.
     *
     * @param InputOption[] $options An array of InputOption objects
     */
    public function addOptions(array $options = [])
    {
        foreach ($options as $option) {
            $this->addOption($option);
        }
    }
    /**
     * @throws LogicException When option given already exist
     */
    public function addOption(InputOption $option)
    {
        if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {
            throw new LogicException(\sprintf('An option named "%s" already exists.', $option->getName()));
        }
        if (isset($this->negations[$option->getName()])) {
            throw new LogicException(\sprintf('An option named "%s" already exists.', $option->getName()));
        }
        if ($option->getShortcut()) {
            foreach (\explode('|', $option->getShortcut()) as $shortcut) {
                if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) {
                    throw new LogicException(\sprintf('An option with shortcut "%s" already exists.', $shortcut));
                }
            }
        }
        $this->options[$option->getName()] = $option;
        if ($option->getShortcut()) {
            foreach (\explode('|', $option->getShortcut()) as $shortcut) {
                $this->shortcuts[$shortcut] = $option->getName();
            }
        }
        if ($option->isNegatable()) {
            $negatedName = 'no-' . $option->getName();
            if (isset($this->options[$negatedName])) {
                throw new LogicException(\sprintf('An option named "%s" already exists.', $negatedName));
            }
            $this->negations[$negatedName] = $option->getName();
        }
    }
    /**
     * Returns an InputOption by name.
     *
     * @return InputOption
     *
     * @throws InvalidArgumentException When option given doesn't exist
     */
    public function getOption(string $name)
    {
        if (!$this->hasOption($name)) {
            throw new InvalidArgumentException(\sprintf('The "--%s" option does not exist.', $name));
        }
        return $this->options[$name];
    }
    /**
     * Returns true if an InputOption object exists by name.
     *
     * This method can't be used to check if the user included the option when
     * executing the command (use getOption() instead).
     *
     * @return bool
     */
    public function hasOption(string $name)
    {
        return isset($this->options[$name]);
    }
    /**
     * Gets the array of InputOption objects.
     *
     * @return InputOption[]
     */
    public function getOptions()
    {
        return $this->options;
    }
    /**
     * Returns true if an InputOption object exists by shortcut.
     *
     * @return bool
     */
    public function hasShortcut(string $name)
    {
        return isset($this->shortcuts[$name]);
    }
    /**
     * Returns true if an InputOption object exists by negated name.
     */
    public function hasNegation(string $name) : bool
    {
        return isset($this->negations[$name]);
    }
    /**
     * Gets an InputOption by shortcut.
     *
     * @return InputOption
     */
    public function getOptionForShortcut(string $shortcut)
    {
        return $this->getOption($this->shortcutToName($shortcut));
    }
    /**
     * @return array<string|bool|int|float|array|null>
     */
    public function getOptionDefaults()
    {
        $values = [];
        foreach ($this->options as $option) {
            $values[$option->getName()] = $option->getDefault();
        }
        return $values;
    }
    /**
     * Returns the InputOption name given a shortcut.
     *
     * @throws InvalidArgumentException When option given does not exist
     *
     * @internal
     */
    public function shortcutToName(string $shortcut) : string
    {
        if (!isset($this->shortcuts[$shortcut])) {
            throw new InvalidArgumentException(\sprintf('The "-%s" option does not exist.', $shortcut));
        }
        return $this->shortcuts[$shortcut];
    }
    /**
     * Returns the InputOption name given a negation.
     *
     * @throws InvalidArgumentException When option given does not exist
     *
     * @internal
     */
    public function negationToName(string $negation) : string
    {
        if (!isset($this->negations[$negation])) {
            throw new InvalidArgumentException(\sprintf('The "--%s" option does not exist.', $negation));
        }
        return $this->negations[$negation];
    }
    /**
     * Gets the synopsis.
     *
     * @return string
     */
    public function getSynopsis(bool $short = \false)
    {
        $elements = [];
        if ($short && $this->getOptions()) {
            $elements[] = '[options]';
        } elseif (!$short) {
            foreach ($this->getOptions() as $option) {
                $value = '';
                if ($option->acceptValue()) {
                    $value = \sprintf(' %s%s%s', $option->isValueOptional() ? '[' : '', \strtoupper($option->getName()), $option->isValueOptional() ? ']' : '');
                }
                $shortcut = $option->getShortcut() ? \sprintf('-%s|', $option->getShortcut()) : '';
                $negation = $option->isNegatable() ? \sprintf('|--no-%s', $option->getName()) : '';
                $elements[] = \sprintf('[%s--%s%s%s]', $shortcut, $option->getName(), $value, $negation);
            }
        }
        if (\count($elements) && $this->getArguments()) {
            $elements[] = '[--]';
        }
        $tail = '';
        foreach ($this->getArguments() as $argument) {
            $element = '<' . $argument->getName() . '>';
            if ($argument->isArray()) {
                $element .= '...';
            }
            if (!$argument->isRequired()) {
                $element = '[' . $element;
                $tail .= ']';
            }
            $elements[] = $element;
        }
        return \implode(' ', $elements) . $tail;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
/**
 * Input is the base class for all concrete Input classes.
 *
 * Three concrete classes are provided by default:
 *
 *  * `ArgvInput`: The input comes from the CLI arguments (argv)
 *  * `StringInput`: The input is provided as a string
 *  * `ArrayInput`: The input is provided as an array
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Input implements InputInterface, StreamableInputInterface
{
    protected $definition;
    protected $stream;
    protected $options = [];
    protected $arguments = [];
    protected $interactive = \true;
    public function __construct(InputDefinition $definition = null)
    {
        if (null === $definition) {
            $this->definition = new InputDefinition();
        } else {
            $this->bind($definition);
            $this->validate();
        }
    }
    /**
     * {@inheritdoc}
     */
    public function bind(InputDefinition $definition)
    {
        $this->arguments = [];
        $this->options = [];
        $this->definition = $definition;
        $this->parse();
    }
    /**
     * Processes command line arguments.
     */
    protected abstract function parse();
    /**
     * {@inheritdoc}
     */
    public function validate()
    {
        $definition = $this->definition;
        $givenArguments = $this->arguments;
        $missingArguments = \array_filter(\array_keys($definition->getArguments()), function ($argument) use($definition, $givenArguments) {
            return !\array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired();
        });
        if (\count($missingArguments) > 0) {
            throw new RuntimeException(\sprintf('Not enough arguments (missing: "%s").', \implode(', ', $missingArguments)));
        }
    }
    /**
     * {@inheritdoc}
     */
    public function isInteractive()
    {
        return $this->interactive;
    }
    /**
     * {@inheritdoc}
     */
    public function setInteractive(bool $interactive)
    {
        $this->interactive = $interactive;
    }
    /**
     * {@inheritdoc}
     */
    public function getArguments()
    {
        return \array_merge($this->definition->getArgumentDefaults(), $this->arguments);
    }
    /**
     * {@inheritdoc}
     */
    public function getArgument(string $name)
    {
        if (!$this->definition->hasArgument($name)) {
            throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
        }
        return $this->arguments[$name] ?? $this->definition->getArgument($name)->getDefault();
    }
    /**
     * {@inheritdoc}
     */
    public function setArgument(string $name, $value)
    {
        if (!$this->definition->hasArgument($name)) {
            throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
        }
        $this->arguments[$name] = $value;
    }
    /**
     * {@inheritdoc}
     */
    public function hasArgument(string $name)
    {
        return $this->definition->hasArgument($name);
    }
    /**
     * {@inheritdoc}
     */
    public function getOptions()
    {
        return \array_merge($this->definition->getOptionDefaults(), $this->options);
    }
    /**
     * {@inheritdoc}
     */
    public function getOption(string $name)
    {
        if ($this->definition->hasNegation($name)) {
            if (null === ($value = $this->getOption($this->definition->negationToName($name)))) {
                return $value;
            }
            return !$value;
        }
        if (!$this->definition->hasOption($name)) {
            throw new InvalidArgumentException(\sprintf('The "%s" option does not exist.', $name));
        }
        return \array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();
    }
    /**
     * {@inheritdoc}
     */
    public function setOption(string $name, $value)
    {
        if ($this->definition->hasNegation($name)) {
            $this->options[$this->definition->negationToName($name)] = !$value;
            return;
        } elseif (!$this->definition->hasOption($name)) {
            throw new InvalidArgumentException(\sprintf('The "%s" option does not exist.', $name));
        }
        $this->options[$name] = $value;
    }
    /**
     * {@inheritdoc}
     */
    public function hasOption(string $name)
    {
        return $this->definition->hasOption($name) || $this->definition->hasNegation($name);
    }
    /**
     * Escapes a token through escapeshellarg if it contains unsafe chars.
     *
     * @return string
     */
    public function escapeToken(string $token)
    {
        return \preg_match('{^[\\w-]+$}', $token) ? $token : \escapeshellarg($token);
    }
    /**
     * {@inheritdoc}
     */
    public function setStream($stream)
    {
        $this->stream = $stream;
    }
    /**
     * {@inheritdoc}
     */
    public function getStream()
    {
        return $this->stream;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidOptionException;
/**
 * ArrayInput represents an input provided as an array.
 *
 * Usage:
 *
 *     $input = new ArrayInput(['command' => 'foo:bar', 'foo' => 'bar', '--bar' => 'foobar']);
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ArrayInput extends Input
{
    private $parameters;
    public function __construct(array $parameters, InputDefinition $definition = null)
    {
        $this->parameters = $parameters;
        parent::__construct($definition);
    }
    /**
     * {@inheritdoc}
     */
    public function getFirstArgument()
    {
        foreach ($this->parameters as $param => $value) {
            if ($param && \is_string($param) && '-' === $param[0]) {
                continue;
            }
            return $value;
        }
        return null;
    }
    /**
     * {@inheritdoc}
     */
    public function hasParameterOption($values, bool $onlyParams = \false)
    {
        $values = (array) $values;
        foreach ($this->parameters as $k => $v) {
            if (!\is_int($k)) {
                $v = $k;
            }
            if ($onlyParams && '--' === $v) {
                return \false;
            }
            if (\in_array($v, $values)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function getParameterOption($values, $default = \false, bool $onlyParams = \false)
    {
        $values = (array) $values;
        foreach ($this->parameters as $k => $v) {
            if ($onlyParams && ('--' === $k || \is_int($k) && '--' === $v)) {
                return $default;
            }
            if (\is_int($k)) {
                if (\in_array($v, $values)) {
                    return \true;
                }
            } elseif (\in_array($k, $values)) {
                return $v;
            }
        }
        return $default;
    }
    /**
     * Returns a stringified representation of the args passed to the command.
     *
     * @return string
     */
    public function __toString()
    {
        $params = [];
        foreach ($this->parameters as $param => $val) {
            if ($param && \is_string($param) && '-' === $param[0]) {
                $glue = '-' === $param[1] ? '=' : ' ';
                if (\is_array($val)) {
                    foreach ($val as $v) {
                        $params[] = $param . ('' != $v ? $glue . $this->escapeToken($v) : '');
                    }
                } else {
                    $params[] = $param . ('' != $val ? $glue . $this->escapeToken($val) : '');
                }
            } else {
                $params[] = \is_array($val) ? \implode(' ', \array_map([$this, 'escapeToken'], $val)) : $this->escapeToken($val);
            }
        }
        return \implode(' ', $params);
    }
    /**
     * {@inheritdoc}
     */
    protected function parse()
    {
        foreach ($this->parameters as $key => $value) {
            if ('--' === $key) {
                return;
            }
            if (\str_starts_with($key, '--')) {
                $this->addLongOption(\substr($key, 2), $value);
            } elseif (\str_starts_with($key, '-')) {
                $this->addShortOption(\substr($key, 1), $value);
            } else {
                $this->addArgument($key, $value);
            }
        }
    }
    /**
     * Adds a short option value.
     *
     * @throws InvalidOptionException When option given doesn't exist
     */
    private function addShortOption(string $shortcut, $value)
    {
        if (!$this->definition->hasShortcut($shortcut)) {
            throw new InvalidOptionException(\sprintf('The "-%s" option does not exist.', $shortcut));
        }
        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
    }
    /**
     * Adds a long option value.
     *
     * @throws InvalidOptionException When option given doesn't exist
     * @throws InvalidOptionException When a required value is missing
     */
    private function addLongOption(string $name, $value)
    {
        if (!$this->definition->hasOption($name)) {
            if (!$this->definition->hasNegation($name)) {
                throw new InvalidOptionException(\sprintf('The "--%s" option does not exist.', $name));
            }
            $optionName = $this->definition->negationToName($name);
            $this->options[$optionName] = \false;
            return;
        }
        $option = $this->definition->getOption($name);
        if (null === $value) {
            if ($option->isValueRequired()) {
                throw new InvalidOptionException(\sprintf('The "--%s" option requires a value.', $name));
            }
            if (!$option->isValueOptional()) {
                $value = \true;
            }
        }
        $this->options[$name] = $value;
    }
    /**
     * Adds an argument value.
     *
     * @param string|int $name  The argument name
     * @param mixed      $value The value for the argument
     *
     * @throws InvalidArgumentException When argument given doesn't exist
     */
    private function addArgument($name, $value)
    {
        if (!$this->definition->hasArgument($name)) {
            throw new InvalidArgumentException(\sprintf('The "%s" argument does not exist.', $name));
        }
        $this->arguments[$name] = $value;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
/**
 * Represents a command line option.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class InputOption
{
    /**
     * Do not accept input for the option (e.g. --yell). This is the default behavior of options.
     */
    public const VALUE_NONE = 1;
    /**
     * A value must be passed when the option is used (e.g. --iterations=5 or -i5).
     */
    public const VALUE_REQUIRED = 2;
    /**
     * The option may or may not have a value (e.g. --yell or --yell=loud).
     */
    public const VALUE_OPTIONAL = 4;
    /**
     * The option accepts multiple values (e.g. --dir=/foo --dir=/bar).
     */
    public const VALUE_IS_ARRAY = 8;
    /**
     * The option may have either positive or negative value (e.g. --ansi or --no-ansi).
     */
    public const VALUE_NEGATABLE = 16;
    private $name;
    private $shortcut;
    private $mode;
    private $default;
    private $description;
    /**
     * @param string|array|null                $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
     * @param int|null                         $mode     The option mode: One of the VALUE_* constants
     * @param string|bool|int|float|array|null $default  The default value (must be null for self::VALUE_NONE)
     *
     * @throws InvalidArgumentException If option mode is invalid or incompatible
     */
    public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
    {
        if (\str_starts_with($name, '--')) {
            $name = \substr($name, 2);
        }
        if (empty($name)) {
            throw new InvalidArgumentException('An option name cannot be empty.');
        }
        if (empty($shortcut)) {
            $shortcut = null;
        }
        if (null !== $shortcut) {
            if (\is_array($shortcut)) {
                $shortcut = \implode('|', $shortcut);
            }
            $shortcuts = \preg_split('{(\\|)-?}', \ltrim($shortcut, '-'));
            $shortcuts = \array_filter($shortcuts);
            $shortcut = \implode('|', $shortcuts);
            if (empty($shortcut)) {
                throw new InvalidArgumentException('An option shortcut cannot be empty.');
            }
        }
        if (null === $mode) {
            $mode = self::VALUE_NONE;
        } elseif ($mode >= self::VALUE_NEGATABLE << 1 || $mode < 1) {
            throw new InvalidArgumentException(\sprintf('Option mode "%s" is not valid.', $mode));
        }
        $this->name = $name;
        $this->shortcut = $shortcut;
        $this->mode = $mode;
        $this->description = $description;
        if ($this->isArray() && !$this->acceptValue()) {
            throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');
        }
        if ($this->isNegatable() && $this->acceptValue()) {
            throw new InvalidArgumentException('Impossible to have an option mode VALUE_NEGATABLE if the option also accepts a value.');
        }
        $this->setDefault($default);
    }
    /**
     * Returns the option shortcut.
     *
     * @return string|null
     */
    public function getShortcut()
    {
        return $this->shortcut;
    }
    /**
     * Returns the option name.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Returns true if the option accepts a value.
     *
     * @return bool true if value mode is not self::VALUE_NONE, false otherwise
     */
    public function acceptValue()
    {
        return $this->isValueRequired() || $this->isValueOptional();
    }
    /**
     * Returns true if the option requires a value.
     *
     * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise
     */
    public function isValueRequired()
    {
        return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);
    }
    /**
     * Returns true if the option takes an optional value.
     *
     * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise
     */
    public function isValueOptional()
    {
        return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);
    }
    /**
     * Returns true if the option can take multiple values.
     *
     * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise
     */
    public function isArray()
    {
        return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);
    }
    public function isNegatable() : bool
    {
        return self::VALUE_NEGATABLE === (self::VALUE_NEGATABLE & $this->mode);
    }
    /**
     * @param string|bool|int|float|array|null $default
     */
    public function setDefault($default = null)
    {
        if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {
            throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');
        }
        if ($this->isArray()) {
            if (null === $default) {
                $default = [];
            } elseif (!\is_array($default)) {
                throw new LogicException('A default value for an array option must be an array.');
            }
        }
        $this->default = $this->acceptValue() || $this->isNegatable() ? $default : \false;
    }
    /**
     * Returns the default value.
     *
     * @return string|bool|int|float|array|null
     */
    public function getDefault()
    {
        return $this->default;
    }
    /**
     * Returns the description text.
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }
    /**
     * Checks whether the given option equals this one.
     *
     * @return bool
     */
    public function equals(self $option)
    {
        return $option->getName() === $this->getName() && $option->getShortcut() === $this->getShortcut() && $option->getDefault() === $this->getDefault() && $option->isNegatable() === $this->isNegatable() && $option->isArray() === $this->isArray() && $option->isValueRequired() === $this->isValueRequired() && $option->isValueOptional() === $this->isValueOptional();
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

/**
 * StreamableInputInterface is the interface implemented by all input classes
 * that have an input stream.
 *
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
interface StreamableInputInterface extends InputInterface
{
    /**
     * Sets the input stream to read from when interacting with the user.
     *
     * This is mainly useful for testing purpose.
     *
     * @param resource $stream The input stream
     */
    public function setStream($stream);
    /**
     * Returns the input stream.
     *
     * @return resource|null
     */
    public function getStream();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
/**
 * StringInput represents an input provided as a string.
 *
 * Usage:
 *
 *     $input = new StringInput('foo --bar="foobar"');
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class StringInput extends ArgvInput
{
    public const REGEX_STRING = '([^\\s]+?)(?:\\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
    public const REGEX_UNQUOTED_STRING = '([^\\s\\\\]+?)';
    public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
    /**
     * @param string $input A string representing the parameters from the CLI
     */
    public function __construct(string $input)
    {
        parent::__construct([]);
        $this->setTokens($this->tokenize($input));
    }
    /**
     * Tokenizes a string.
     *
     * @throws InvalidArgumentException When unable to parse input (should never happen)
     */
    private function tokenize(string $input) : array
    {
        $tokens = [];
        $length = \strlen($input);
        $cursor = 0;
        $token = null;
        while ($cursor < $length) {
            if ('\\' === $input[$cursor]) {
                $token .= $input[++$cursor] ?? '';
                ++$cursor;
                continue;
            }
            if (\preg_match('/\\s+/A', $input, $match, 0, $cursor)) {
                if (null !== $token) {
                    $tokens[] = $token;
                    $token = null;
                }
            } elseif (\preg_match('/([^="\'\\s]+?)(=?)(' . self::REGEX_QUOTED_STRING . '+)/A', $input, $match, 0, $cursor)) {
                $token .= $match[1] . $match[2] . \stripcslashes(\str_replace(['"\'', '\'"', '\'\'', '""'], '', \substr($match[3], 1, -1)));
            } elseif (\preg_match('/' . self::REGEX_QUOTED_STRING . '/A', $input, $match, 0, $cursor)) {
                $token .= \stripcslashes(\substr($match[0], 1, -1));
            } elseif (\preg_match('/' . self::REGEX_UNQUOTED_STRING . '/A', $input, $match, 0, $cursor)) {
                $token .= $match[1];
            } else {
                // should never happen
                throw new InvalidArgumentException(\sprintf('Unable to parse input near "... %s ...".', \substr($input, $cursor, 10)));
            }
            $cursor += \strlen($match[0]);
        }
        if (null !== $token) {
            $tokens[] = $token;
        }
        return $tokens;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Lock\LockFactory;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Lock\LockInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Lock\Store\FlockStore;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Lock\Store\SemaphoreStore;
/**
 * Basic lock feature for commands.
 *
 * @author Geoffrey Brier <geoffrey.brier@gmail.com>
 */
trait LockableTrait
{
    /** @var LockInterface|null */
    private $lock;
    /**
     * Locks a command.
     */
    private function lock(string $name = null, bool $blocking = \false) : bool
    {
        if (!\class_exists(SemaphoreStore::class)) {
            throw new LogicException('To enable the locking feature you must install the symfony/lock component.');
        }
        if (null !== $this->lock) {
            throw new LogicException('A lock is already in place.');
        }
        if (SemaphoreStore::isSupported()) {
            $store = new SemaphoreStore();
        } else {
            $store = new FlockStore();
        }
        $this->lock = (new LockFactory($store))->createLock($name ?: $this->getName());
        if (!$this->lock->acquire($blocking)) {
            $this->lock = null;
            return \false;
        }
        return \true;
    }
    /**
     * Releases the command lock if there is one.
     */
    private function release()
    {
        if ($this->lock) {
            $this->lock->release();
            $this->lock = null;
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Process\Process;
/**
 * Dumps the completion script for the current shell.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class DumpCompletionCommand extends Command
{
    protected static $defaultName = 'completion';
    protected static $defaultDescription = 'Dump the shell completion script';
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
    {
        if ($input->mustSuggestArgumentValuesFor('shell')) {
            $suggestions->suggestValues($this->getSupportedShells());
        }
    }
    protected function configure()
    {
        $fullCommand = $_SERVER['PHP_SELF'];
        $commandName = \basename($fullCommand);
        $fullCommand = @\realpath($fullCommand) ?: $fullCommand;
        $this->setHelp(<<<EOH
The <info>%command.name%</> command dumps the shell completion script required
to use shell autocompletion (currently only bash completion is supported).

<comment>Static installation
-------------------</>

Dump the script to a global completion file and restart your shell:

    <info>%command.full_name% bash | sudo tee /etc/bash_completion.d/{$commandName}</>

Or dump the script to a local file and source it:

    <info>%command.full_name% bash > completion.sh</>

    <comment># source the file whenever you use the project</>
    <info>source completion.sh</>

    <comment># or add this line at the end of your "~/.bashrc" file:</>
    <info>source /path/to/completion.sh</>

<comment>Dynamic installation
--------------------</>

Add this to the end of your shell configuration file (e.g. <info>"~/.bashrc"</>):

    <info>eval "\$({$fullCommand} completion bash)"</>
EOH
)->addArgument('shell', InputArgument::OPTIONAL, 'The shell type (e.g. "bash"), the value of the "$SHELL" env var will be used if this is not given')->addOption('debug', null, InputOption::VALUE_NONE, 'Tail the completion debug log');
    }
    protected function execute(InputInterface $input, OutputInterface $output) : int
    {
        $commandName = \basename($_SERVER['argv'][0]);
        if ($input->getOption('debug')) {
            $this->tailDebugLog($commandName, $output);
            return self::SUCCESS;
        }
        $shell = $input->getArgument('shell') ?? self::guessShell();
        $completionFile = __DIR__ . '/../Resources/completion.' . $shell;
        if (!\file_exists($completionFile)) {
            $supportedShells = $this->getSupportedShells();
            if ($output instanceof ConsoleOutputInterface) {
                $output = $output->getErrorOutput();
            }
            if ($shell) {
                $output->writeln(\sprintf('<error>Detected shell "%s", which is not supported by Symfony shell completion (supported shells: "%s").</>', $shell, \implode('", "', $supportedShells)));
            } else {
                $output->writeln(\sprintf('<error>Shell not detected, Symfony shell completion only supports "%s").</>', \implode('", "', $supportedShells)));
            }
            return self::INVALID;
        }
        $output->write(\str_replace(['{{ COMMAND_NAME }}', '{{ VERSION }}'], [$commandName, $this->getApplication()->getVersion()], \file_get_contents($completionFile)));
        return self::SUCCESS;
    }
    private static function guessShell() : string
    {
        return \basename($_SERVER['SHELL'] ?? '');
    }
    private function tailDebugLog(string $commandName, OutputInterface $output) : void
    {
        $debugFile = \sys_get_temp_dir() . '/sf_' . $commandName . '.log';
        if (!\file_exists($debugFile)) {
            \touch($debugFile);
        }
        $process = new Process(['tail', '-f', $debugFile], null, null, null, 0);
        $process->run(function (string $type, string $line) use($output) : void {
            $output->write($line);
        });
    }
    /**
     * @return string[]
     */
    private function getSupportedShells() : array
    {
        return \array_map(function ($f) {
            return \pathinfo($f, \PATHINFO_EXTENSION);
        }, \glob(__DIR__ . '/../Resources/completion.*'));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\Output\BashCompletionOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\Output\CompletionOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\CommandNotFoundException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Responsible for providing the values to the shell completion.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class CompleteCommand extends Command
{
    protected static $defaultName = '|_complete';
    protected static $defaultDescription = 'Internal command to provide shell completion suggestions';
    private $completionOutputs;
    private $isDebug = \false;
    /**
     * @param array<string, class-string<CompletionOutputInterface>> $completionOutputs A list of additional completion outputs, with shell name as key and FQCN as value
     */
    public function __construct(array $completionOutputs = [])
    {
        // must be set before the parent constructor, as the property value is used in configure()
        $this->completionOutputs = $completionOutputs + ['bash' => BashCompletionOutput::class];
        parent::__construct();
    }
    protected function configure() : void
    {
        $this->addOption('shell', 's', InputOption::VALUE_REQUIRED, 'The shell type ("' . \implode('", "', \array_keys($this->completionOutputs)) . '")')->addOption('input', 'i', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'An array of input tokens (e.g. COMP_WORDS or argv)')->addOption('current', 'c', InputOption::VALUE_REQUIRED, 'The index of the "input" array that the cursor is in (e.g. COMP_CWORD)')->addOption('symfony', 'S', InputOption::VALUE_REQUIRED, 'The version of the completion script');
    }
    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->isDebug = \filter_var(\getenv('SYMFONY_COMPLETION_DEBUG'), \FILTER_VALIDATE_BOOLEAN);
    }
    protected function execute(InputInterface $input, OutputInterface $output) : int
    {
        try {
            // uncomment when a bugfix or BC break has been introduced in the shell completion scripts
            // $version = $input->getOption('symfony');
            // if ($version && version_compare($version, 'x.y', '>=')) {
            //    $message = sprintf('Completion script version is not supported ("%s" given, ">=x.y" required).', $version);
            //    $this->log($message);
            //    $output->writeln($message.' Install the Symfony completion script again by using the "completion" command.');
            //    return 126;
            // }
            $shell = $input->getOption('shell');
            if (!$shell) {
                throw new \RuntimeException('The "--shell" option must be set.');
            }
            if (!($completionOutput = $this->completionOutputs[$shell] ?? \false)) {
                throw new \RuntimeException(\sprintf('Shell completion is not supported for your shell: "%s" (supported: "%s").', $shell, \implode('", "', \array_keys($this->completionOutputs))));
            }
            $completionInput = $this->createCompletionInput($input);
            $suggestions = new CompletionSuggestions();
            $this->log(['', '<comment>' . \date('Y-m-d H:i:s') . '</>', '<info>Input:</> <comment>("|" indicates the cursor position)</>', '  ' . (string) $completionInput, '<info>Command:</>', '  ' . (string) \implode(' ', $_SERVER['argv']), '<info>Messages:</>']);
            $command = $this->findCommand($completionInput, $output);
            if (null === $command) {
                $this->log('  No command found, completing using the Application class.');
                $this->getApplication()->complete($completionInput, $suggestions);
            } elseif ($completionInput->mustSuggestArgumentValuesFor('command') && $command->getName() !== $completionInput->getCompletionValue() && !\in_array($completionInput->getCompletionValue(), $command->getAliases(), \true)) {
                $this->log('  No command found, completing using the Application class.');
                // expand shortcut names ("cache:cl<TAB>") into their full name ("cache:clear")
                $suggestions->suggestValues(\array_filter(\array_merge([$command->getName()], $command->getAliases())));
            } else {
                $command->mergeApplicationDefinition();
                $completionInput->bind($command->getDefinition());
                if (CompletionInput::TYPE_OPTION_NAME === $completionInput->getCompletionType()) {
                    $this->log('  Completing option names for the <comment>' . \get_class($command instanceof LazyCommand ? $command->getCommand() : $command) . '</> command.');
                    $suggestions->suggestOptions($command->getDefinition()->getOptions());
                } else {
                    $this->log(['  Completing using the <comment>' . \get_class($command instanceof LazyCommand ? $command->getCommand() : $command) . '</> class.', '  Completing <comment>' . $completionInput->getCompletionType() . '</> for <comment>' . $completionInput->getCompletionName() . '</>']);
                    if (null !== ($compval = $completionInput->getCompletionValue())) {
                        $this->log('  Current value: <comment>' . $compval . '</>');
                    }
                    $command->complete($completionInput, $suggestions);
                }
            }
            /** @var CompletionOutputInterface $completionOutput */
            $completionOutput = new $completionOutput();
            $this->log('<info>Suggestions:</>');
            if ($options = $suggestions->getOptionSuggestions()) {
                $this->log('  --' . \implode(' --', \array_map(function ($o) {
                    return $o->getName();
                }, $options)));
            } elseif ($values = $suggestions->getValueSuggestions()) {
                $this->log('  ' . \implode(' ', $values));
            } else {
                $this->log('  <comment>No suggestions were provided</>');
            }
            $completionOutput->write($suggestions, $output);
        } catch (\Throwable $e) {
            $this->log(['<error>Error!</error>', (string) $e]);
            if ($output->isDebug()) {
                throw $e;
            }
            return self::FAILURE;
        }
        return self::SUCCESS;
    }
    private function createCompletionInput(InputInterface $input) : CompletionInput
    {
        $currentIndex = $input->getOption('current');
        if (!$currentIndex || !\ctype_digit($currentIndex)) {
            throw new \RuntimeException('The "--current" option must be set and it must be an integer.');
        }
        $completionInput = CompletionInput::fromTokens($input->getOption('input'), (int) $currentIndex);
        try {
            $completionInput->bind($this->getApplication()->getDefinition());
        } catch (ExceptionInterface $e) {
        }
        return $completionInput;
    }
    private function findCommand(CompletionInput $completionInput, OutputInterface $output) : ?Command
    {
        try {
            $inputName = $completionInput->getFirstArgument();
            if (null === $inputName) {
                return null;
            }
            return $this->getApplication()->find($inputName);
        } catch (CommandNotFoundException $e) {
        }
        return null;
    }
    private function log($messages) : void
    {
        if (!$this->isDebug) {
            return;
        }
        $commandName = \basename($_SERVER['argv'][0]);
        \file_put_contents(\sys_get_temp_dir() . '/sf_' . $commandName . '.log', \implode(\PHP_EOL, (array) $messages) . \PHP_EOL, \FILE_APPEND);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor\ApplicationDescription;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\DescriptorHelper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * HelpCommand displays the help for a given command.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class HelpCommand extends Command
{
    private $command;
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this->ignoreValidationErrors();
        $this->setName('help')->setDefinition([new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help')])->setDescription('Display help for a command')->setHelp(<<<'EOF'
The <info>%command.name%</info> command displays help for a given command:

  <info>%command.full_name% list</info>

You can also output the help in other formats by using the <comment>--format</comment> option:

  <info>%command.full_name% --format=xml list</info>

To display the list of available commands, please use the <info>list</info> command.
EOF
);
    }
    public function setCommand(Command $command)
    {
        $this->command = $command;
    }
    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        if (null === $this->command) {
            $this->command = $this->getApplication()->find($input->getArgument('command_name'));
        }
        $helper = new DescriptorHelper();
        $helper->describe($output, $this->command, ['format' => $input->getOption('format'), 'raw_text' => $input->getOption('raw')]);
        $this->command = null;
        return 0;
    }
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
    {
        if ($input->mustSuggestArgumentValuesFor('command_name')) {
            $descriptor = new ApplicationDescription($this->getApplication());
            $suggestions->suggestValues(\array_keys($descriptor->getCommands()));
            return;
        }
        if ($input->mustSuggestOptionValuesFor('format')) {
            $helper = new DescriptorHelper();
            $suggestions->suggestValues($helper->getFormats());
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

/**
 * Interface for command reacting to signal.
 *
 * @author Grégoire Pineau <lyrixx@lyrix.info>
 */
interface SignalableCommandInterface
{
    /**
     * Returns the list of signals to subscribe.
     */
    public function getSubscribedSignals() : array;
    /**
     * The method will be called when the application is signaled.
     */
    public function handleSignal(int $signal) : void;
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Attribute\AsCommand;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\HelperSet;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Base class for all commands.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Command
{
    // see https://tldp.org/LDP/abs/html/exitcodes.html
    public const SUCCESS = 0;
    public const FAILURE = 1;
    public const INVALID = 2;
    /**
     * @var string|null The default command name
     */
    protected static $defaultName;
    /**
     * @var string|null The default command description
     */
    protected static $defaultDescription;
    private $application;
    private $name;
    private $processTitle;
    private $aliases = [];
    private $definition;
    private $hidden = \false;
    private $help = '';
    private $description = '';
    private $fullDefinition;
    private $ignoreValidationErrors = \false;
    private $code;
    private $synopsis = [];
    private $usages = [];
    private $helperSet;
    /**
     * @return string|null
     */
    public static function getDefaultName()
    {
        $class = static::class;
        if (\PHP_VERSION_ID >= 80000 && ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class))) {
            return $attribute[0]->newInstance()->name;
        }
        $r = new \ReflectionProperty($class, 'defaultName');
        return $class === $r->class ? static::$defaultName : null;
    }
    public static function getDefaultDescription() : ?string
    {
        $class = static::class;
        if (\PHP_VERSION_ID >= 80000 && ($attribute = (new \ReflectionClass($class))->getAttributes(AsCommand::class))) {
            return $attribute[0]->newInstance()->description;
        }
        $r = new \ReflectionProperty($class, 'defaultDescription');
        return $class === $r->class ? static::$defaultDescription : null;
    }
    /**
     * @param string|null $name The name of the command; passing null means it must be set in configure()
     *
     * @throws LogicException When the command name is empty
     */
    public function __construct(string $name = null)
    {
        $this->definition = new InputDefinition();
        if (null === $name && null !== ($name = static::getDefaultName())) {
            $aliases = \explode('|', $name);
            if ('' === ($name = \array_shift($aliases))) {
                $this->setHidden(\true);
                $name = \array_shift($aliases);
            }
            $this->setAliases($aliases);
        }
        if (null !== $name) {
            $this->setName($name);
        }
        if ('' === $this->description) {
            $this->setDescription(static::getDefaultDescription() ?? '');
        }
        $this->configure();
    }
    /**
     * Ignores validation errors.
     *
     * This is mainly useful for the help command.
     */
    public function ignoreValidationErrors()
    {
        $this->ignoreValidationErrors = \true;
    }
    public function setApplication(Application $application = null)
    {
        $this->application = $application;
        if ($application) {
            $this->setHelperSet($application->getHelperSet());
        } else {
            $this->helperSet = null;
        }
        $this->fullDefinition = null;
    }
    public function setHelperSet(HelperSet $helperSet)
    {
        $this->helperSet = $helperSet;
    }
    /**
     * Gets the helper set.
     *
     * @return HelperSet|null
     */
    public function getHelperSet()
    {
        return $this->helperSet;
    }
    /**
     * Gets the application instance for this command.
     *
     * @return Application|null
     */
    public function getApplication()
    {
        return $this->application;
    }
    /**
     * Checks whether the command is enabled or not in the current environment.
     *
     * Override this to check for x or y and return false if the command cannot
     * run properly under the current conditions.
     *
     * @return bool
     */
    public function isEnabled()
    {
        return \true;
    }
    /**
     * Configures the current command.
     */
    protected function configure()
    {
    }
    /**
     * Executes the current command.
     *
     * This method is not abstract because you can use this class
     * as a concrete class. In this case, instead of defining the
     * execute() method, you set the code to execute by passing
     * a Closure to the setCode() method.
     *
     * @return int 0 if everything went fine, or an exit code
     *
     * @throws LogicException When this abstract method is not implemented
     *
     * @see setCode()
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        throw new LogicException('You must override the execute() method in the concrete command class.');
    }
    /**
     * Interacts with the user.
     *
     * This method is executed before the InputDefinition is validated.
     * This means that this is the only place where the command can
     * interactively ask for values of missing required arguments.
     */
    protected function interact(InputInterface $input, OutputInterface $output)
    {
    }
    /**
     * Initializes the command after the input has been bound and before the input
     * is validated.
     *
     * This is mainly useful when a lot of commands extends one main command
     * where some things need to be initialized based on the input arguments and options.
     *
     * @see InputInterface::bind()
     * @see InputInterface::validate()
     */
    protected function initialize(InputInterface $input, OutputInterface $output)
    {
    }
    /**
     * Runs the command.
     *
     * The code to execute is either defined directly with the
     * setCode() method or by overriding the execute() method
     * in a sub-class.
     *
     * @return int The command exit code
     *
     * @throws ExceptionInterface When input binding fails. Bypass this by calling {@link ignoreValidationErrors()}.
     *
     * @see setCode()
     * @see execute()
     */
    public function run(InputInterface $input, OutputInterface $output)
    {
        // add the application arguments and options
        $this->mergeApplicationDefinition();
        // bind the input against the command specific arguments/options
        try {
            $input->bind($this->getDefinition());
        } catch (ExceptionInterface $e) {
            if (!$this->ignoreValidationErrors) {
                throw $e;
            }
        }
        $this->initialize($input, $output);
        if (null !== $this->processTitle) {
            if (\function_exists('cli_set_process_title')) {
                if (!@\cli_set_process_title($this->processTitle)) {
                    if ('Darwin' === \PHP_OS) {
                        $output->writeln('<comment>Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.</comment>', OutputInterface::VERBOSITY_VERY_VERBOSE);
                    } else {
                        \cli_set_process_title($this->processTitle);
                    }
                }
            } elseif (\function_exists('_HumbugBox1cb33d1f20f1\\setproctitle')) {
                setproctitle($this->processTitle);
            } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
                $output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
            }
        }
        if ($input->isInteractive()) {
            $this->interact($input, $output);
        }
        // The command name argument is often omitted when a command is executed directly with its run() method.
        // It would fail the validation if we didn't make sure the command argument is present,
        // since it's required by the application.
        if ($input->hasArgument('command') && null === $input->getArgument('command')) {
            $input->setArgument('command', $this->getName());
        }
        $input->validate();
        if ($this->code) {
            $statusCode = ($this->code)($input, $output);
        } else {
            $statusCode = $this->execute($input, $output);
            if (!\is_int($statusCode)) {
                throw new \TypeError(\sprintf('Return value of "%s::execute()" must be of the type int, "%s" returned.', static::class, \get_debug_type($statusCode)));
            }
        }
        return \is_numeric($statusCode) ? (int) $statusCode : 0;
    }
    /**
     * Adds suggestions to $suggestions for the current completion input (e.g. option or argument).
     */
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
    {
    }
    /**
     * Sets the code to execute when running this command.
     *
     * If this method is used, it overrides the code defined
     * in the execute() method.
     *
     * @param callable $code A callable(InputInterface $input, OutputInterface $output)
     *
     * @return $this
     *
     * @throws InvalidArgumentException
     *
     * @see execute()
     */
    public function setCode(callable $code)
    {
        if ($code instanceof \Closure) {
            $r = new \ReflectionFunction($code);
            if (null === $r->getClosureThis()) {
                \set_error_handler(static function () {
                });
                try {
                    if ($c = \Closure::bind($code, $this)) {
                        $code = $c;
                    }
                } finally {
                    \restore_error_handler();
                }
            }
        }
        $this->code = $code;
        return $this;
    }
    /**
     * Merges the application definition with the command definition.
     *
     * This method is not part of public API and should not be used directly.
     *
     * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
     *
     * @internal
     */
    public function mergeApplicationDefinition(bool $mergeArgs = \true)
    {
        if (null === $this->application) {
            return;
        }
        $this->fullDefinition = new InputDefinition();
        $this->fullDefinition->setOptions($this->definition->getOptions());
        $this->fullDefinition->addOptions($this->application->getDefinition()->getOptions());
        if ($mergeArgs) {
            $this->fullDefinition->setArguments($this->application->getDefinition()->getArguments());
            $this->fullDefinition->addArguments($this->definition->getArguments());
        } else {
            $this->fullDefinition->setArguments($this->definition->getArguments());
        }
    }
    /**
     * Sets an array of argument and option instances.
     *
     * @param array|InputDefinition $definition An array of argument and option instances or a definition instance
     *
     * @return $this
     */
    public function setDefinition($definition)
    {
        if ($definition instanceof InputDefinition) {
            $this->definition = $definition;
        } else {
            $this->definition->setDefinition($definition);
        }
        $this->fullDefinition = null;
        return $this;
    }
    /**
     * Gets the InputDefinition attached to this Command.
     *
     * @return InputDefinition
     */
    public function getDefinition()
    {
        return $this->fullDefinition ?? $this->getNativeDefinition();
    }
    /**
     * Gets the InputDefinition to be used to create representations of this Command.
     *
     * Can be overridden to provide the original command representation when it would otherwise
     * be changed by merging with the application InputDefinition.
     *
     * This method is not part of public API and should not be used directly.
     *
     * @return InputDefinition
     */
    public function getNativeDefinition()
    {
        if (null === $this->definition) {
            throw new LogicException(\sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', static::class));
        }
        return $this->definition;
    }
    /**
     * Adds an argument.
     *
     * @param int|null $mode    The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
     * @param mixed    $default The default value (for InputArgument::OPTIONAL mode only)
     *
     * @throws InvalidArgumentException When argument mode is not valid
     *
     * @return $this
     */
    public function addArgument(string $name, int $mode = null, string $description = '', $default = null)
    {
        $this->definition->addArgument(new InputArgument($name, $mode, $description, $default));
        if (null !== $this->fullDefinition) {
            $this->fullDefinition->addArgument(new InputArgument($name, $mode, $description, $default));
        }
        return $this;
    }
    /**
     * Adds an option.
     *
     * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts
     * @param int|null          $mode     The option mode: One of the InputOption::VALUE_* constants
     * @param mixed             $default  The default value (must be null for InputOption::VALUE_NONE)
     *
     * @throws InvalidArgumentException If option mode is invalid or incompatible
     *
     * @return $this
     */
    public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null)
    {
        $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
        if (null !== $this->fullDefinition) {
            $this->fullDefinition->addOption(new InputOption($name, $shortcut, $mode, $description, $default));
        }
        return $this;
    }
    /**
     * Sets the name of the command.
     *
     * This method can set both the namespace and the name if
     * you separate them by a colon (:)
     *
     *     $command->setName('foo:bar');
     *
     * @return $this
     *
     * @throws InvalidArgumentException When the name is invalid
     */
    public function setName(string $name)
    {
        $this->validateName($name);
        $this->name = $name;
        return $this;
    }
    /**
     * Sets the process title of the command.
     *
     * This feature should be used only when creating a long process command,
     * like a daemon.
     *
     * @return $this
     */
    public function setProcessTitle(string $title)
    {
        $this->processTitle = $title;
        return $this;
    }
    /**
     * Returns the command name.
     *
     * @return string|null
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * @param bool $hidden Whether or not the command should be hidden from the list of commands
     *                     The default value will be true in Symfony 6.0
     *
     * @return $this
     *
     * @final since Symfony 5.1
     */
    public function setHidden(bool $hidden)
    {
        $this->hidden = $hidden;
        return $this;
    }
    /**
     * @return bool whether the command should be publicly shown or not
     */
    public function isHidden()
    {
        return $this->hidden;
    }
    /**
     * Sets the description for the command.
     *
     * @return $this
     */
    public function setDescription(string $description)
    {
        $this->description = $description;
        return $this;
    }
    /**
     * Returns the description for the command.
     *
     * @return string
     */
    public function getDescription()
    {
        return $this->description;
    }
    /**
     * Sets the help for the command.
     *
     * @return $this
     */
    public function setHelp(string $help)
    {
        $this->help = $help;
        return $this;
    }
    /**
     * Returns the help for the command.
     *
     * @return string
     */
    public function getHelp()
    {
        return $this->help;
    }
    /**
     * Returns the processed help for the command replacing the %command.name% and
     * %command.full_name% patterns with the real values dynamically.
     *
     * @return string
     */
    public function getProcessedHelp()
    {
        $name = $this->name;
        $isSingleCommand = $this->application && $this->application->isSingleCommand();
        $placeholders = ['%command.name%', '%command.full_name%'];
        $replacements = [$name, $isSingleCommand ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'] . ' ' . $name];
        return \str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription());
    }
    /**
     * Sets the aliases for the command.
     *
     * @param string[] $aliases An array of aliases for the command
     *
     * @return $this
     *
     * @throws InvalidArgumentException When an alias is invalid
     */
    public function setAliases(iterable $aliases)
    {
        $list = [];
        foreach ($aliases as $alias) {
            $this->validateName($alias);
            $list[] = $alias;
        }
        $this->aliases = \is_array($aliases) ? $aliases : $list;
        return $this;
    }
    /**
     * Returns the aliases for the command.
     *
     * @return array
     */
    public function getAliases()
    {
        return $this->aliases;
    }
    /**
     * Returns the synopsis for the command.
     *
     * @param bool $short Whether to show the short version of the synopsis (with options folded) or not
     *
     * @return string
     */
    public function getSynopsis(bool $short = \false)
    {
        $key = $short ? 'short' : 'long';
        if (!isset($this->synopsis[$key])) {
            $this->synopsis[$key] = \trim(\sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));
        }
        return $this->synopsis[$key];
    }
    /**
     * Add a command usage example, it'll be prefixed with the command name.
     *
     * @return $this
     */
    public function addUsage(string $usage)
    {
        if (!\str_starts_with($usage, $this->name)) {
            $usage = \sprintf('%s %s', $this->name, $usage);
        }
        $this->usages[] = $usage;
        return $this;
    }
    /**
     * Returns alternative usages of the command.
     *
     * @return array
     */
    public function getUsages()
    {
        return $this->usages;
    }
    /**
     * Gets a helper instance by name.
     *
     * @return mixed
     *
     * @throws LogicException           if no HelperSet is defined
     * @throws InvalidArgumentException if the helper is not defined
     */
    public function getHelper(string $name)
    {
        if (null === $this->helperSet) {
            throw new LogicException(\sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name));
        }
        return $this->helperSet->get($name);
    }
    /**
     * Validates a command name.
     *
     * It must be non-empty and parts can optionally be separated by ":".
     *
     * @throws InvalidArgumentException When the name is invalid
     */
    private function validateName(string $name)
    {
        if (!\preg_match('/^[^\\:]++(\\:[^\\:]++)*$/', $name)) {
            throw new InvalidArgumentException(\sprintf('Command name "%s" is invalid.', $name));
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\HelperSet;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * @author Nicolas Grekas <p@tchwork.com>
 */
final class LazyCommand extends Command
{
    private $command;
    private $isEnabled;
    public function __construct(string $name, array $aliases, string $description, bool $isHidden, \Closure $commandFactory, ?bool $isEnabled = \true)
    {
        $this->setName($name)->setAliases($aliases)->setHidden($isHidden)->setDescription($description);
        $this->command = $commandFactory;
        $this->isEnabled = $isEnabled;
    }
    public function ignoreValidationErrors() : void
    {
        $this->getCommand()->ignoreValidationErrors();
    }
    public function setApplication(Application $application = null) : void
    {
        if ($this->command instanceof parent) {
            $this->command->setApplication($application);
        }
        parent::setApplication($application);
    }
    public function setHelperSet(HelperSet $helperSet) : void
    {
        if ($this->command instanceof parent) {
            $this->command->setHelperSet($helperSet);
        }
        parent::setHelperSet($helperSet);
    }
    public function isEnabled() : bool
    {
        return $this->isEnabled ?? $this->getCommand()->isEnabled();
    }
    public function run(InputInterface $input, OutputInterface $output) : int
    {
        return $this->getCommand()->run($input, $output);
    }
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
    {
        $this->getCommand()->complete($input, $suggestions);
    }
    /**
     * @return $this
     */
    public function setCode(callable $code) : self
    {
        $this->getCommand()->setCode($code);
        return $this;
    }
    /**
     * @internal
     */
    public function mergeApplicationDefinition(bool $mergeArgs = \true) : void
    {
        $this->getCommand()->mergeApplicationDefinition($mergeArgs);
    }
    /**
     * @return $this
     */
    public function setDefinition($definition) : self
    {
        $this->getCommand()->setDefinition($definition);
        return $this;
    }
    public function getDefinition() : InputDefinition
    {
        return $this->getCommand()->getDefinition();
    }
    public function getNativeDefinition() : InputDefinition
    {
        return $this->getCommand()->getNativeDefinition();
    }
    /**
     * @return $this
     */
    public function addArgument(string $name, int $mode = null, string $description = '', $default = null) : self
    {
        $this->getCommand()->addArgument($name, $mode, $description, $default);
        return $this;
    }
    /**
     * @return $this
     */
    public function addOption(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) : self
    {
        $this->getCommand()->addOption($name, $shortcut, $mode, $description, $default);
        return $this;
    }
    /**
     * @return $this
     */
    public function setProcessTitle(string $title) : self
    {
        $this->getCommand()->setProcessTitle($title);
        return $this;
    }
    /**
     * @return $this
     */
    public function setHelp(string $help) : self
    {
        $this->getCommand()->setHelp($help);
        return $this;
    }
    public function getHelp() : string
    {
        return $this->getCommand()->getHelp();
    }
    public function getProcessedHelp() : string
    {
        return $this->getCommand()->getProcessedHelp();
    }
    public function getSynopsis(bool $short = \false) : string
    {
        return $this->getCommand()->getSynopsis($short);
    }
    /**
     * @return $this
     */
    public function addUsage(string $usage) : self
    {
        $this->getCommand()->addUsage($usage);
        return $this;
    }
    public function getUsages() : array
    {
        return $this->getCommand()->getUsages();
    }
    /**
     * @return mixed
     */
    public function getHelper(string $name)
    {
        return $this->getCommand()->getHelper($name);
    }
    public function getCommand() : parent
    {
        if (!$this->command instanceof \Closure) {
            return $this->command;
        }
        $command = $this->command = ($this->command)();
        $command->setApplication($this->getApplication());
        if (null !== $this->getHelperSet()) {
            $command->setHelperSet($this->getHelperSet());
        }
        $command->setName($this->getName())->setAliases($this->getAliases())->setHidden($this->isHidden())->setDescription($this->getDescription());
        // Will throw if the command is not correctly initialized.
        $command->getDefinition();
        return $command;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor\ApplicationDescription;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\DescriptorHelper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * ListCommand displays the list of all available commands for the application.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ListCommand extends Command
{
    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this->setName('list')->setDefinition([new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), new InputOption('short', null, InputOption::VALUE_NONE, 'To skip describing commands\' arguments')])->setDescription('List commands')->setHelp(<<<'EOF'
The <info>%command.name%</info> command lists all commands:

  <info>%command.full_name%</info>

You can also display the commands for a specific namespace:

  <info>%command.full_name% test</info>

You can also output the information in other formats by using the <comment>--format</comment> option:

  <info>%command.full_name% --format=xml</info>

It's also possible to get raw list of commands (useful for embedding command runner):

  <info>%command.full_name% --raw</info>
EOF
);
    }
    /**
     * {@inheritdoc}
     */
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $helper = new DescriptorHelper();
        $helper->describe($output, $this->getApplication(), ['format' => $input->getOption('format'), 'raw_text' => $input->getOption('raw'), 'namespace' => $input->getArgument('namespace'), 'short' => $input->getOption('short')]);
        return 0;
    }
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
    {
        if ($input->mustSuggestArgumentValuesFor('namespace')) {
            $descriptor = new ApplicationDescription($this->getApplication());
            $suggestions->suggestValues(\array_keys($descriptor->getNamespaces()));
            return;
        }
        if ($input->mustSuggestOptionValuesFor('format')) {
            $helper = new DescriptorHelper();
            $suggestions->suggestValues($helper->getFormats());
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console;

class Terminal
{
    private static $width;
    private static $height;
    private static $stty;
    /**
     * Gets the terminal width.
     *
     * @return int
     */
    public function getWidth()
    {
        $width = \getenv('COLUMNS');
        if (\false !== $width) {
            return (int) \trim($width);
        }
        if (null === self::$width) {
            self::initDimensions();
        }
        return self::$width ?: 80;
    }
    /**
     * Gets the terminal height.
     *
     * @return int
     */
    public function getHeight()
    {
        $height = \getenv('LINES');
        if (\false !== $height) {
            return (int) \trim($height);
        }
        if (null === self::$height) {
            self::initDimensions();
        }
        return self::$height ?: 50;
    }
    /**
     * @internal
     */
    public static function hasSttyAvailable() : bool
    {
        if (null !== self::$stty) {
            return self::$stty;
        }
        // skip check if exec function is disabled
        if (!\function_exists('exec')) {
            return \false;
        }
        \exec('stty 2>&1', $output, $exitcode);
        return self::$stty = 0 === $exitcode;
    }
    private static function initDimensions()
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            if (\preg_match('/^(\\d+)x(\\d+)(?: \\((\\d+)x(\\d+)\\))?$/', \trim(\getenv('ANSICON')), $matches)) {
                // extract [w, H] from "wxh (WxH)"
                // or [w, h] from "wxh"
                self::$width = (int) $matches[1];
                self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
            } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) {
                // only use stty on Windows if the terminal does not support vt100 (e.g. Windows 7 + git-bash)
                // testing for stty in a Windows 10 vt100-enabled console will implicitly disable vt100 support on STDOUT
                self::initDimensionsUsingStty();
            } elseif (null !== ($dimensions = self::getConsoleMode())) {
                // extract [w, h] from "wxh"
                self::$width = (int) $dimensions[0];
                self::$height = (int) $dimensions[1];
            }
        } else {
            self::initDimensionsUsingStty();
        }
    }
    /**
     * Returns whether STDOUT has vt100 support (some Windows 10+ configurations).
     */
    private static function hasVt100Support() : bool
    {
        return \function_exists('sapi_windows_vt100_support') && \sapi_windows_vt100_support(\fopen('php://stdout', 'w'));
    }
    /**
     * Initializes dimensions using the output of an stty columns line.
     */
    private static function initDimensionsUsingStty()
    {
        if ($sttyString = self::getSttyColumns()) {
            if (\preg_match('/rows.(\\d+);.columns.(\\d+);/i', $sttyString, $matches)) {
                // extract [w, h] from "rows h; columns w;"
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            } elseif (\preg_match('/;.(\\d+).rows;.(\\d+).columns/i', $sttyString, $matches)) {
                // extract [w, h] from "; h rows; w columns"
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            }
        }
    }
    /**
     * Runs and parses mode CON if it's available, suppressing any error output.
     *
     * @return int[]|null An array composed of the width and the height or null if it could not be parsed
     */
    private static function getConsoleMode() : ?array
    {
        $info = self::readFromProcess('mode CON');
        if (null === $info || !\preg_match('/--------+\\r?\\n.+?(\\d+)\\r?\\n.+?(\\d+)\\r?\\n/', $info, $matches)) {
            return null;
        }
        return [(int) $matches[2], (int) $matches[1]];
    }
    /**
     * Runs and parses stty -a if it's available, suppressing any error output.
     */
    private static function getSttyColumns() : ?string
    {
        return self::readFromProcess('stty -a | grep columns');
    }
    private static function readFromProcess(string $command) : ?string
    {
        if (!\function_exists('proc_open')) {
            return null;
        }
        $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];
        $process = \proc_open($command, $descriptorspec, $pipes, null, null, ['suppress_errors' => \true]);
        if (!\is_resource($process)) {
            return null;
        }
        $info = \stream_get_contents($pipes[1]);
        \fclose($pipes[1]);
        \fclose($pipes[2]);
        \proc_close($process);
        return $info;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * @author marie <marie@users.noreply.github.com>
 */
final class ConsoleSignalEvent extends ConsoleEvent
{
    private $handlingSignal;
    public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $handlingSignal)
    {
        parent::__construct($command, $input, $output);
        $this->handlingSignal = $handlingSignal;
    }
    public function getHandlingSignal() : int
    {
        return $this->handlingSignal;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Allows to handle throwables thrown while running a command.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class ConsoleErrorEvent extends ConsoleEvent
{
    private $error;
    private $exitCode;
    public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null)
    {
        parent::__construct($command, $input, $output);
        $this->error = $error;
    }
    public function getError() : \Throwable
    {
        return $this->error;
    }
    public function setError(\Throwable $error) : void
    {
        $this->error = $error;
    }
    public function setExitCode(int $exitCode) : void
    {
        $this->exitCode = $exitCode;
        $r = new \ReflectionProperty($this->error, 'code');
        $r->setAccessible(\true);
        $r->setValue($this->error, $this->exitCode);
    }
    public function getExitCode() : int
    {
        return $this->exitCode ?? (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Allows to manipulate the exit code of a command after its execution.
 *
 * @author Francesco Levorato <git@flevour.net>
 */
final class ConsoleTerminateEvent extends ConsoleEvent
{
    private $exitCode;
    public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode)
    {
        parent::__construct($command, $input, $output);
        $this->setExitCode($exitCode);
    }
    public function setExitCode(int $exitCode) : void
    {
        $this->exitCode = $exitCode;
    }
    public function getExitCode() : int
    {
        return $this->exitCode;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Contracts\EventDispatcher\Event;
/**
 * Allows to inspect input and output of a command.
 *
 * @author Francesco Levorato <git@flevour.net>
 */
class ConsoleEvent extends Event
{
    protected $command;
    private $input;
    private $output;
    public function __construct(?Command $command, InputInterface $input, OutputInterface $output)
    {
        $this->command = $command;
        $this->input = $input;
        $this->output = $output;
    }
    /**
     * Gets the command that is executed.
     *
     * @return Command|null
     */
    public function getCommand()
    {
        return $this->command;
    }
    /**
     * Gets the input instance.
     *
     * @return InputInterface
     */
    public function getInput()
    {
        return $this->input;
    }
    /**
     * Gets the output instance.
     *
     * @return OutputInterface
     */
    public function getOutput()
    {
        return $this->output;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event;

/**
 * Allows to do things before the command is executed, like skipping the command or changing the input.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class ConsoleCommandEvent extends ConsoleEvent
{
    /**
     * The return code for skipped commands, this will also be passed into the terminate event.
     */
    public const RETURN_CODE_DISABLED = 113;
    /**
     * Indicates if the command should be run or skipped.
     */
    private $commandShouldRun = \true;
    /**
     * Disables the command, so it won't be run.
     */
    public function disableCommand() : bool
    {
        return $this->commandShouldRun = \false;
    }
    public function enableCommand() : bool
    {
        return $this->commandShouldRun = \true;
    }
    /**
     * Returns true if the command is runnable, false otherwise.
     */
    public function commandShouldRun() : bool
    {
        return $this->commandShouldRun;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\ProgressBar;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Decorates output to add console style guide helpers.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
abstract class OutputStyle implements OutputInterface, StyleInterface
{
    private $output;
    public function __construct(OutputInterface $output)
    {
        $this->output = $output;
    }
    /**
     * {@inheritdoc}
     */
    public function newLine(int $count = 1)
    {
        $this->output->write(\str_repeat(\PHP_EOL, $count));
    }
    /**
     * @return ProgressBar
     */
    public function createProgressBar(int $max = 0)
    {
        return new ProgressBar($this->output, $max);
    }
    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = \false, int $type = self::OUTPUT_NORMAL)
    {
        $this->output->write($messages, $newline, $type);
    }
    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $type = self::OUTPUT_NORMAL)
    {
        $this->output->writeln($messages, $type);
    }
    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        $this->output->setVerbosity($level);
    }
    /**
     * {@inheritdoc}
     */
    public function getVerbosity()
    {
        return $this->output->getVerbosity();
    }
    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        $this->output->setDecorated($decorated);
    }
    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return $this->output->isDecorated();
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        $this->output->setFormatter($formatter);
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->output->getFormatter();
    }
    /**
     * {@inheritdoc}
     */
    public function isQuiet()
    {
        return $this->output->isQuiet();
    }
    /**
     * {@inheritdoc}
     */
    public function isVerbose()
    {
        return $this->output->isVerbose();
    }
    /**
     * {@inheritdoc}
     */
    public function isVeryVerbose()
    {
        return $this->output->isVeryVerbose();
    }
    /**
     * {@inheritdoc}
     */
    public function isDebug()
    {
        return $this->output->isDebug();
    }
    protected function getErrorOutput()
    {
        if (!$this->output instanceof ConsoleOutputInterface) {
            return $this->output;
        }
        return $this->output->getErrorOutput();
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\Helper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\ProgressBar;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\SymfonyQuestionHelper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\Table;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\TableCell;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\TableSeparator;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\TrimmedBufferOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\ChoiceQuestion;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\ConfirmationQuestion;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\Question;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Terminal;
/**
 * Output decorator helpers for the Symfony Style Guide.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class SymfonyStyle extends OutputStyle
{
    public const MAX_LINE_LENGTH = 120;
    private $input;
    private $output;
    private $questionHelper;
    private $progressBar;
    private $lineLength;
    private $bufferedOutput;
    public function __construct(InputInterface $input, OutputInterface $output)
    {
        $this->input = $input;
        $this->bufferedOutput = new TrimmedBufferOutput(\DIRECTORY_SEPARATOR === '\\' ? 4 : 2, $output->getVerbosity(), \false, clone $output->getFormatter());
        // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not.
        $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
        $this->lineLength = \min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH);
        parent::__construct($this->output = $output);
    }
    /**
     * Formats a message as a block of text.
     *
     * @param string|array $messages The message to write in the block
     */
    public function block($messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = \false, bool $escape = \true)
    {
        $messages = \is_array($messages) ? \array_values($messages) : [$messages];
        $this->autoPrependBlock();
        $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape));
        $this->newLine();
    }
    /**
     * {@inheritdoc}
     */
    public function title(string $message)
    {
        $this->autoPrependBlock();
        $this->writeln([\sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)), \sprintf('<comment>%s</>', \str_repeat('=', Helper::width(Helper::removeDecoration($this->getFormatter(), $message))))]);
        $this->newLine();
    }
    /**
     * {@inheritdoc}
     */
    public function section(string $message)
    {
        $this->autoPrependBlock();
        $this->writeln([\sprintf('<comment>%s</>', OutputFormatter::escapeTrailingBackslash($message)), \sprintf('<comment>%s</>', \str_repeat('-', Helper::width(Helper::removeDecoration($this->getFormatter(), $message))))]);
        $this->newLine();
    }
    /**
     * {@inheritdoc}
     */
    public function listing(array $elements)
    {
        $this->autoPrependText();
        $elements = \array_map(function ($element) {
            return \sprintf(' * %s', $element);
        }, $elements);
        $this->writeln($elements);
        $this->newLine();
    }
    /**
     * {@inheritdoc}
     */
    public function text($message)
    {
        $this->autoPrependText();
        $messages = \is_array($message) ? \array_values($message) : [$message];
        foreach ($messages as $message) {
            $this->writeln(\sprintf(' %s', $message));
        }
    }
    /**
     * Formats a command comment.
     *
     * @param string|array $message
     */
    public function comment($message)
    {
        $this->block($message, null, null, '<fg=default;bg=default> // </>', \false, \false);
    }
    /**
     * {@inheritdoc}
     */
    public function success($message)
    {
        $this->block($message, 'OK', 'fg=black;bg=green', ' ', \true);
    }
    /**
     * {@inheritdoc}
     */
    public function error($message)
    {
        $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', \true);
    }
    /**
     * {@inheritdoc}
     */
    public function warning($message)
    {
        $this->block($message, 'WARNING', 'fg=black;bg=yellow', ' ', \true);
    }
    /**
     * {@inheritdoc}
     */
    public function note($message)
    {
        $this->block($message, 'NOTE', 'fg=yellow', ' ! ');
    }
    /**
     * Formats an info message.
     *
     * @param string|array $message
     */
    public function info($message)
    {
        $this->block($message, 'INFO', 'fg=green', ' ', \true);
    }
    /**
     * {@inheritdoc}
     */
    public function caution($message)
    {
        $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', \true);
    }
    /**
     * {@inheritdoc}
     */
    public function table(array $headers, array $rows)
    {
        $this->createTable()->setHeaders($headers)->setRows($rows)->render();
        $this->newLine();
    }
    /**
     * Formats a horizontal table.
     */
    public function horizontalTable(array $headers, array $rows)
    {
        $this->createTable()->setHorizontal(\true)->setHeaders($headers)->setRows($rows)->render();
        $this->newLine();
    }
    /**
     * Formats a list of key/value horizontally.
     *
     * Each row can be one of:
     * * 'A title'
     * * ['key' => 'value']
     * * new TableSeparator()
     *
     * @param string|array|TableSeparator ...$list
     */
    public function definitionList(...$list)
    {
        $headers = [];
        $row = [];
        foreach ($list as $value) {
            if ($value instanceof TableSeparator) {
                $headers[] = $value;
                $row[] = $value;
                continue;
            }
            if (\is_string($value)) {
                $headers[] = new TableCell($value, ['colspan' => 2]);
                $row[] = null;
                continue;
            }
            if (!\is_array($value)) {
                throw new InvalidArgumentException('Value should be an array, string, or an instance of TableSeparator.');
            }
            $headers[] = \key($value);
            $row[] = \current($value);
        }
        $this->horizontalTable($headers, [$row]);
    }
    /**
     * {@inheritdoc}
     */
    public function ask(string $question, string $default = null, callable $validator = null)
    {
        $question = new Question($question, $default);
        $question->setValidator($validator);
        return $this->askQuestion($question);
    }
    /**
     * {@inheritdoc}
     */
    public function askHidden(string $question, callable $validator = null)
    {
        $question = new Question($question);
        $question->setHidden(\true);
        $question->setValidator($validator);
        return $this->askQuestion($question);
    }
    /**
     * {@inheritdoc}
     */
    public function confirm(string $question, bool $default = \true)
    {
        return $this->askQuestion(new ConfirmationQuestion($question, $default));
    }
    /**
     * {@inheritdoc}
     */
    public function choice(string $question, array $choices, $default = null)
    {
        if (null !== $default) {
            $values = \array_flip($choices);
            $default = $values[$default] ?? $default;
        }
        return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));
    }
    /**
     * {@inheritdoc}
     */
    public function progressStart(int $max = 0)
    {
        $this->progressBar = $this->createProgressBar($max);
        $this->progressBar->start();
    }
    /**
     * {@inheritdoc}
     */
    public function progressAdvance(int $step = 1)
    {
        $this->getProgressBar()->advance($step);
    }
    /**
     * {@inheritdoc}
     */
    public function progressFinish()
    {
        $this->getProgressBar()->finish();
        $this->newLine(2);
        $this->progressBar = null;
    }
    /**
     * {@inheritdoc}
     */
    public function createProgressBar(int $max = 0)
    {
        $progressBar = parent::createProgressBar($max);
        if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === \getenv('TERM_PROGRAM')) {
            $progressBar->setEmptyBarCharacter('░');
            // light shade character \u2591
            $progressBar->setProgressCharacter('');
            $progressBar->setBarCharacter('▓');
            // dark shade character \u2593
        }
        return $progressBar;
    }
    /**
     * @see ProgressBar::iterate()
     */
    public function progressIterate(iterable $iterable, int $max = null) : iterable
    {
        yield from $this->createProgressBar()->iterate($iterable, $max);
        $this->newLine(2);
    }
    /**
     * @return mixed
     */
    public function askQuestion(Question $question)
    {
        if ($this->input->isInteractive()) {
            $this->autoPrependBlock();
        }
        if (!$this->questionHelper) {
            $this->questionHelper = new SymfonyQuestionHelper();
        }
        $answer = $this->questionHelper->ask($this->input, $this, $question);
        if ($this->input->isInteractive()) {
            $this->newLine();
            $this->bufferedOutput->write("\n");
        }
        return $answer;
    }
    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $type = self::OUTPUT_NORMAL)
    {
        if (!\is_iterable($messages)) {
            $messages = [$messages];
        }
        foreach ($messages as $message) {
            parent::writeln($message, $type);
            $this->writeBuffer($message, \true, $type);
        }
    }
    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = \false, int $type = self::OUTPUT_NORMAL)
    {
        if (!\is_iterable($messages)) {
            $messages = [$messages];
        }
        foreach ($messages as $message) {
            parent::write($message, $newline, $type);
            $this->writeBuffer($message, $newline, $type);
        }
    }
    /**
     * {@inheritdoc}
     */
    public function newLine(int $count = 1)
    {
        parent::newLine($count);
        $this->bufferedOutput->write(\str_repeat("\n", $count));
    }
    /**
     * Returns a new instance which makes use of stderr if available.
     *
     * @return self
     */
    public function getErrorStyle()
    {
        return new self($this->input, $this->getErrorOutput());
    }
    public function createTable() : Table
    {
        $output = $this->output instanceof ConsoleOutputInterface ? $this->output->section() : $this->output;
        $style = clone Table::getStyleDefinition('symfony-style-guide');
        $style->setCellHeaderFormat('<info>%s</info>');
        return (new Table($output))->setStyle($style);
    }
    private function getProgressBar() : ProgressBar
    {
        if (!$this->progressBar) {
            throw new RuntimeException('The ProgressBar is not started.');
        }
        return $this->progressBar;
    }
    private function autoPrependBlock() : void
    {
        $chars = \substr(\str_replace(\PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2);
        if (!isset($chars[0])) {
            $this->newLine();
            // empty history, so we should start with a new line.
            return;
        }
        // Prepend new line for each non LF chars (This means no blank line was output before)
        $this->newLine(2 - \substr_count($chars, "\n"));
    }
    private function autoPrependText() : void
    {
        $fetched = $this->bufferedOutput->fetch();
        // Prepend new line if last char isn't EOL:
        if (!\str_ends_with($fetched, "\n")) {
            $this->newLine();
        }
    }
    private function writeBuffer(string $message, bool $newLine, int $type) : void
    {
        // We need to know if the last chars are PHP_EOL
        $this->bufferedOutput->write($message, $newLine, $type);
    }
    private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = \false, bool $escape = \false) : array
    {
        $indentLength = 0;
        $prefixLength = Helper::width(Helper::removeDecoration($this->getFormatter(), $prefix));
        $lines = [];
        if (null !== $type) {
            $type = \sprintf('[%s] ', $type);
            $indentLength = \strlen($type);
            $lineIndentation = \str_repeat(' ', $indentLength);
        }
        // wrap and add newlines for each element
        foreach ($messages as $key => $message) {
            if ($escape) {
                $message = OutputFormatter::escape($message);
            }
            $decorationLength = Helper::width($message) - Helper::width(Helper::removeDecoration($this->getFormatter(), $message));
            $messageLineLength = \min($this->lineLength - $prefixLength - $indentLength + $decorationLength, $this->lineLength);
            $messageLines = \explode(\PHP_EOL, \wordwrap($message, $messageLineLength, \PHP_EOL, \true));
            foreach ($messageLines as $messageLine) {
                $lines[] = $messageLine;
            }
            if (\count($messages) > 1 && $key < \count($messages) - 1) {
                $lines[] = '';
            }
        }
        $firstLineIndex = 0;
        if ($padding && $this->isDecorated()) {
            $firstLineIndex = 1;
            \array_unshift($lines, '');
            $lines[] = '';
        }
        foreach ($lines as $i => &$line) {
            if (null !== $type) {
                $line = $firstLineIndex === $i ? $type . $line : $lineIndentation . $line;
            }
            $line = $prefix . $line;
            $line .= \str_repeat(' ', \max($this->lineLength - Helper::width(Helper::removeDecoration($this->getFormatter(), $line)), 0));
            if ($style) {
                $line = \sprintf('<%s>%s</>', $style, $line);
            }
        }
        return $lines;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style;

/**
 * Output style helpers.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
interface StyleInterface
{
    /**
     * Formats a command title.
     */
    public function title(string $message);
    /**
     * Formats a section title.
     */
    public function section(string $message);
    /**
     * Formats a list.
     */
    public function listing(array $elements);
    /**
     * Formats informational text.
     *
     * @param string|array $message
     */
    public function text($message);
    /**
     * Formats a success result bar.
     *
     * @param string|array $message
     */
    public function success($message);
    /**
     * Formats an error result bar.
     *
     * @param string|array $message
     */
    public function error($message);
    /**
     * Formats an warning result bar.
     *
     * @param string|array $message
     */
    public function warning($message);
    /**
     * Formats a note admonition.
     *
     * @param string|array $message
     */
    public function note($message);
    /**
     * Formats a caution admonition.
     *
     * @param string|array $message
     */
    public function caution($message);
    /**
     * Formats a table.
     */
    public function table(array $headers, array $rows);
    /**
     * Asks a question.
     *
     * @return mixed
     */
    public function ask(string $question, string $default = null, callable $validator = null);
    /**
     * Asks a question with the user input hidden.
     *
     * @return mixed
     */
    public function askHidden(string $question, callable $validator = null);
    /**
     * Asks for confirmation.
     *
     * @return bool
     */
    public function confirm(string $question, bool $default = \true);
    /**
     * Asks a choice question.
     *
     * @param string|int|null $default
     *
     * @return mixed
     */
    public function choice(string $question, array $choices, $default = null);
    /**
     * Add newline(s).
     */
    public function newLine(int $count = 1);
    /**
     * Starts the progress output.
     */
    public function progressStart(int $max = 0);
    /**
     * Advances the progress output X steps.
     */
    public function progressAdvance(int $step = 1);
    /**
     * Finishes the progress output.
     */
    public function progressFinish();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\CompleteCommand;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\DumpCompletionCommand;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\HelpCommand;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\LazyCommand;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\ListCommand;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\SignalableCommandInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\CommandLoader\CommandLoaderInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleCommandEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleErrorEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleSignalEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleTerminateEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\CommandNotFoundException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\NamespaceNotFoundException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\DebugFormatterHelper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\FormatterHelper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\Helper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\HelperSet;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\ProcessHelper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\QuestionHelper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\ArgvInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\ArrayInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputAwareInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\SignalRegistry\SignalRegistry;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style\SymfonyStyle;
use _HumbugBox1cb33d1f20f1\Symfony\Component\ErrorHandler\ErrorHandler;
use _HumbugBox1cb33d1f20f1\Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service\ResetInterface;
/**
 * An Application is the container for a collection of commands.
 *
 * It is the main entry point of a Console application.
 *
 * This class is optimized for a standard CLI environment.
 *
 * Usage:
 *
 *     $app = new Application('myapp', '1.0 (stable)');
 *     $app->add(new SimpleCommand());
 *     $app->run();
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Application implements ResetInterface
{
    private $commands = [];
    private $wantHelps = \false;
    private $runningCommand;
    private $name;
    private $version;
    private $commandLoader;
    private $catchExceptions = \true;
    private $autoExit = \true;
    private $definition;
    private $helperSet;
    private $dispatcher;
    private $terminal;
    private $defaultCommand;
    private $singleCommand = \false;
    private $initialized;
    private $signalRegistry;
    private $signalsToDispatchEvent = [];
    public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN')
    {
        $this->name = $name;
        $this->version = $version;
        $this->terminal = new Terminal();
        $this->defaultCommand = 'list';
        if (\defined('SIGINT') && SignalRegistry::isSupported()) {
            $this->signalRegistry = new SignalRegistry();
            $this->signalsToDispatchEvent = [\SIGINT, \SIGTERM, \SIGUSR1, \SIGUSR2];
        }
    }
    /**
     * @final
     */
    public function setDispatcher(EventDispatcherInterface $dispatcher)
    {
        $this->dispatcher = $dispatcher;
    }
    public function setCommandLoader(CommandLoaderInterface $commandLoader)
    {
        $this->commandLoader = $commandLoader;
    }
    public function getSignalRegistry() : SignalRegistry
    {
        if (!$this->signalRegistry) {
            throw new RuntimeException('Signals are not supported. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
        }
        return $this->signalRegistry;
    }
    public function setSignalsToDispatchEvent(int ...$signalsToDispatchEvent)
    {
        $this->signalsToDispatchEvent = $signalsToDispatchEvent;
    }
    /**
     * Runs the current application.
     *
     * @return int 0 if everything went fine, or an error code
     *
     * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}.
     */
    public function run(InputInterface $input = null, OutputInterface $output = null)
    {
        if (\function_exists('putenv')) {
            @\putenv('LINES=' . $this->terminal->getHeight());
            @\putenv('COLUMNS=' . $this->terminal->getWidth());
        }
        if (null === $input) {
            $input = new ArgvInput();
        }
        if (null === $output) {
            $output = new ConsoleOutput();
        }
        $renderException = function (\Throwable $e) use($output) {
            if ($output instanceof ConsoleOutputInterface) {
                $this->renderThrowable($e, $output->getErrorOutput());
            } else {
                $this->renderThrowable($e, $output);
            }
        };
        if ($phpHandler = \set_exception_handler($renderException)) {
            \restore_exception_handler();
            if (!\is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) {
                $errorHandler = \true;
            } elseif ($errorHandler = $phpHandler[0]->setExceptionHandler($renderException)) {
                $phpHandler[0]->setExceptionHandler($errorHandler);
            }
        }
        $this->configureIO($input, $output);
        try {
            $exitCode = $this->doRun($input, $output);
        } catch (\Exception $e) {
            if (!$this->catchExceptions) {
                throw $e;
            }
            $renderException($e);
            $exitCode = $e->getCode();
            if (\is_numeric($exitCode)) {
                $exitCode = (int) $exitCode;
                if ($exitCode <= 0) {
                    $exitCode = 1;
                }
            } else {
                $exitCode = 1;
            }
        } finally {
            // if the exception handler changed, keep it
            // otherwise, unregister $renderException
            if (!$phpHandler) {
                if (\set_exception_handler($renderException) === $renderException) {
                    \restore_exception_handler();
                }
                \restore_exception_handler();
            } elseif (!$errorHandler) {
                $finalHandler = $phpHandler[0]->setExceptionHandler(null);
                if ($finalHandler !== $renderException) {
                    $phpHandler[0]->setExceptionHandler($finalHandler);
                }
            }
        }
        if ($this->autoExit) {
            if ($exitCode > 255) {
                $exitCode = 255;
            }
            exit($exitCode);
        }
        return $exitCode;
    }
    /**
     * Runs the current application.
     *
     * @return int 0 if everything went fine, or an error code
     */
    public function doRun(InputInterface $input, OutputInterface $output)
    {
        if (\true === $input->hasParameterOption(['--version', '-V'], \true)) {
            $output->writeln($this->getLongVersion());
            return 0;
        }
        try {
            // Makes ArgvInput::getFirstArgument() able to distinguish an option from an argument.
            $input->bind($this->getDefinition());
        } catch (ExceptionInterface $e) {
            // Errors must be ignored, full binding/validation happens later when the command is known.
        }
        $name = $this->getCommandName($input);
        if (\true === $input->hasParameterOption(['--help', '-h'], \true)) {
            if (!$name) {
                $name = 'help';
                $input = new ArrayInput(['command_name' => $this->defaultCommand]);
            } else {
                $this->wantHelps = \true;
            }
        }
        if (!$name) {
            $name = $this->defaultCommand;
            $definition = $this->getDefinition();
            $definition->setArguments(\array_merge($definition->getArguments(), ['command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name)]));
        }
        try {
            $this->runningCommand = null;
            // the command name MUST be the first element of the input
            $command = $this->find($name);
        } catch (\Throwable $e) {
            if (!($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException) || 1 !== \count($alternatives = $e->getAlternatives()) || !$input->isInteractive()) {
                if (null !== $this->dispatcher) {
                    $event = new ConsoleErrorEvent($input, $output, $e);
                    $this->dispatcher->dispatch($event, ConsoleEvents::ERROR);
                    if (0 === $event->getExitCode()) {
                        return 0;
                    }
                    $e = $event->getError();
                }
                throw $e;
            }
            $alternative = $alternatives[0];
            $style = new SymfonyStyle($input, $output);
            $output->writeln('');
            $formattedBlock = (new FormatterHelper())->formatBlock(\sprintf('Command "%s" is not defined.', $name), 'error', \true);
            $output->writeln($formattedBlock);
            if (!$style->confirm(\sprintf('Do you want to run "%s" instead? ', $alternative), \false)) {
                if (null !== $this->dispatcher) {
                    $event = new ConsoleErrorEvent($input, $output, $e);
                    $this->dispatcher->dispatch($event, ConsoleEvents::ERROR);
                    return $event->getExitCode();
                }
                return 1;
            }
            $command = $this->find($alternative);
        }
        if ($command instanceof LazyCommand) {
            $command = $command->getCommand();
        }
        $this->runningCommand = $command;
        $exitCode = $this->doRunCommand($command, $input, $output);
        $this->runningCommand = null;
        return $exitCode;
    }
    /**
     * {@inheritdoc}
     */
    public function reset()
    {
    }
    public function setHelperSet(HelperSet $helperSet)
    {
        $this->helperSet = $helperSet;
    }
    /**
     * Get the helper set associated with the command.
     *
     * @return HelperSet
     */
    public function getHelperSet()
    {
        if (!$this->helperSet) {
            $this->helperSet = $this->getDefaultHelperSet();
        }
        return $this->helperSet;
    }
    public function setDefinition(InputDefinition $definition)
    {
        $this->definition = $definition;
    }
    /**
     * Gets the InputDefinition related to this Application.
     *
     * @return InputDefinition
     */
    public function getDefinition()
    {
        if (!$this->definition) {
            $this->definition = $this->getDefaultInputDefinition();
        }
        if ($this->singleCommand) {
            $inputDefinition = $this->definition;
            $inputDefinition->setArguments();
            return $inputDefinition;
        }
        return $this->definition;
    }
    /**
     * Adds suggestions to $suggestions for the current completion input (e.g. option or argument).
     */
    public function complete(CompletionInput $input, CompletionSuggestions $suggestions) : void
    {
        if (CompletionInput::TYPE_ARGUMENT_VALUE === $input->getCompletionType() && 'command' === $input->getCompletionName()) {
            $commandNames = [];
            foreach ($this->all() as $name => $command) {
                // skip hidden commands and aliased commands as they already get added below
                if ($command->isHidden() || $command->getName() !== $name) {
                    continue;
                }
                $commandNames[] = $command->getName();
                foreach ($command->getAliases() as $name) {
                    $commandNames[] = $name;
                }
            }
            $suggestions->suggestValues(\array_filter($commandNames));
            return;
        }
        if (CompletionInput::TYPE_OPTION_NAME === $input->getCompletionType()) {
            $suggestions->suggestOptions($this->getDefinition()->getOptions());
            return;
        }
    }
    /**
     * Gets the help message.
     *
     * @return string
     */
    public function getHelp()
    {
        return $this->getLongVersion();
    }
    /**
     * Gets whether to catch exceptions or not during commands execution.
     *
     * @return bool
     */
    public function areExceptionsCaught()
    {
        return $this->catchExceptions;
    }
    /**
     * Sets whether to catch exceptions or not during commands execution.
     */
    public function setCatchExceptions(bool $boolean)
    {
        $this->catchExceptions = $boolean;
    }
    /**
     * Gets whether to automatically exit after a command execution or not.
     *
     * @return bool
     */
    public function isAutoExitEnabled()
    {
        return $this->autoExit;
    }
    /**
     * Sets whether to automatically exit after a command execution or not.
     */
    public function setAutoExit(bool $boolean)
    {
        $this->autoExit = $boolean;
    }
    /**
     * Gets the name of the application.
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Sets the application name.
     **/
    public function setName(string $name)
    {
        $this->name = $name;
    }
    /**
     * Gets the application version.
     *
     * @return string
     */
    public function getVersion()
    {
        return $this->version;
    }
    /**
     * Sets the application version.
     */
    public function setVersion(string $version)
    {
        $this->version = $version;
    }
    /**
     * Returns the long version of the application.
     *
     * @return string
     */
    public function getLongVersion()
    {
        if ('UNKNOWN' !== $this->getName()) {
            if ('UNKNOWN' !== $this->getVersion()) {
                return \sprintf('%s <info>%s</info>', $this->getName(), $this->getVersion());
            }
            return $this->getName();
        }
        return 'Console Tool';
    }
    /**
     * Registers a new command.
     *
     * @return Command
     */
    public function register(string $name)
    {
        return $this->add(new Command($name));
    }
    /**
     * Adds an array of command objects.
     *
     * If a Command is not enabled it will not be added.
     *
     * @param Command[] $commands An array of commands
     */
    public function addCommands(array $commands)
    {
        foreach ($commands as $command) {
            $this->add($command);
        }
    }
    /**
     * Adds a command object.
     *
     * If a command with the same name already exists, it will be overridden.
     * If the command is not enabled it will not be added.
     *
     * @return Command|null
     */
    public function add(Command $command)
    {
        $this->init();
        $command->setApplication($this);
        if (!$command->isEnabled()) {
            $command->setApplication(null);
            return null;
        }
        if (!$command instanceof LazyCommand) {
            // Will throw if the command is not correctly initialized.
            $command->getDefinition();
        }
        if (!$command->getName()) {
            throw new LogicException(\sprintf('The command defined in "%s" cannot have an empty name.', \get_debug_type($command)));
        }
        $this->commands[$command->getName()] = $command;
        foreach ($command->getAliases() as $alias) {
            $this->commands[$alias] = $command;
        }
        return $command;
    }
    /**
     * Returns a registered command by name or alias.
     *
     * @return Command
     *
     * @throws CommandNotFoundException When given command name does not exist
     */
    public function get(string $name)
    {
        $this->init();
        if (!$this->has($name)) {
            throw new CommandNotFoundException(\sprintf('The command "%s" does not exist.', $name));
        }
        // When the command has a different name than the one used at the command loader level
        if (!isset($this->commands[$name])) {
            throw new CommandNotFoundException(\sprintf('The "%s" command cannot be found because it is registered under multiple names. Make sure you don\'t set a different name via constructor or "setName()".', $name));
        }
        $command = $this->commands[$name];
        if ($this->wantHelps) {
            $this->wantHelps = \false;
            $helpCommand = $this->get('help');
            $helpCommand->setCommand($command);
            return $helpCommand;
        }
        return $command;
    }
    /**
     * Returns true if the command exists, false otherwise.
     *
     * @return bool
     */
    public function has(string $name)
    {
        $this->init();
        return isset($this->commands[$name]) || $this->commandLoader && $this->commandLoader->has($name) && $this->add($this->commandLoader->get($name));
    }
    /**
     * Returns an array of all unique namespaces used by currently registered commands.
     *
     * It does not return the global namespace which always exists.
     *
     * @return string[]
     */
    public function getNamespaces()
    {
        $namespaces = [];
        foreach ($this->all() as $command) {
            if ($command->isHidden()) {
                continue;
            }
            $namespaces[] = $this->extractAllNamespaces($command->getName());
            foreach ($command->getAliases() as $alias) {
                $namespaces[] = $this->extractAllNamespaces($alias);
            }
        }
        return \array_values(\array_unique(\array_filter(\array_merge([], ...$namespaces))));
    }
    /**
     * Finds a registered namespace by a name or an abbreviation.
     *
     * @return string
     *
     * @throws NamespaceNotFoundException When namespace is incorrect or ambiguous
     */
    public function findNamespace(string $namespace)
    {
        $allNamespaces = $this->getNamespaces();
        $expr = \implode('[^:]*:', \array_map('preg_quote', \explode(':', $namespace))) . '[^:]*';
        $namespaces = \preg_grep('{^' . $expr . '}', $allNamespaces);
        if (empty($namespaces)) {
            $message = \sprintf('There are no commands defined in the "%s" namespace.', $namespace);
            if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
                if (1 == \count($alternatives)) {
                    $message .= "\n\nDid you mean this?\n    ";
                } else {
                    $message .= "\n\nDid you mean one of these?\n    ";
                }
                $message .= \implode("\n    ", $alternatives);
            }
            throw new NamespaceNotFoundException($message, $alternatives);
        }
        $exact = \in_array($namespace, $namespaces, \true);
        if (\count($namespaces) > 1 && !$exact) {
            throw new NamespaceNotFoundException(\sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $namespace, $this->getAbbreviationSuggestions(\array_values($namespaces))), \array_values($namespaces));
        }
        return $exact ? $namespace : \reset($namespaces);
    }
    /**
     * Finds a command by name or alias.
     *
     * Contrary to get, this command tries to find the best
     * match if you give it an abbreviation of a name or alias.
     *
     * @return Command
     *
     * @throws CommandNotFoundException When command name is incorrect or ambiguous
     */
    public function find(string $name)
    {
        $this->init();
        $aliases = [];
        foreach ($this->commands as $command) {
            foreach ($command->getAliases() as $alias) {
                if (!$this->has($alias)) {
                    $this->commands[$alias] = $command;
                }
            }
        }
        if ($this->has($name)) {
            return $this->get($name);
        }
        $allCommands = $this->commandLoader ? \array_merge($this->commandLoader->getNames(), \array_keys($this->commands)) : \array_keys($this->commands);
        $expr = \implode('[^:]*:', \array_map('preg_quote', \explode(':', $name))) . '[^:]*';
        $commands = \preg_grep('{^' . $expr . '}', $allCommands);
        if (empty($commands)) {
            $commands = \preg_grep('{^' . $expr . '}i', $allCommands);
        }
        // if no commands matched or we just matched namespaces
        if (empty($commands) || \count(\preg_grep('{^' . $expr . '$}i', $commands)) < 1) {
            if (\false !== ($pos = \strrpos($name, ':'))) {
                // check if a namespace exists and contains commands
                $this->findNamespace(\substr($name, 0, $pos));
            }
            $message = \sprintf('Command "%s" is not defined.', $name);
            if ($alternatives = $this->findAlternatives($name, $allCommands)) {
                // remove hidden commands
                $alternatives = \array_filter($alternatives, function ($name) {
                    return !$this->get($name)->isHidden();
                });
                if (1 == \count($alternatives)) {
                    $message .= "\n\nDid you mean this?\n    ";
                } else {
                    $message .= "\n\nDid you mean one of these?\n    ";
                }
                $message .= \implode("\n    ", $alternatives);
            }
            throw new CommandNotFoundException($message, \array_values($alternatives));
        }
        // filter out aliases for commands which are already on the list
        if (\count($commands) > 1) {
            $commandList = $this->commandLoader ? \array_merge(\array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
            $commands = \array_unique(\array_filter($commands, function ($nameOrAlias) use(&$commandList, $commands, &$aliases) {
                if (!$commandList[$nameOrAlias] instanceof Command) {
                    $commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias);
                }
                $commandName = $commandList[$nameOrAlias]->getName();
                $aliases[$nameOrAlias] = $commandName;
                return $commandName === $nameOrAlias || !\in_array($commandName, $commands);
            }));
        }
        if (\count($commands) > 1) {
            $usableWidth = $this->terminal->getWidth() - 10;
            $abbrevs = \array_values($commands);
            $maxLen = 0;
            foreach ($abbrevs as $abbrev) {
                $maxLen = \max(Helper::width($abbrev), $maxLen);
            }
            $abbrevs = \array_map(function ($cmd) use($commandList, $usableWidth, $maxLen, &$commands) {
                if ($commandList[$cmd]->isHidden()) {
                    unset($commands[\array_search($cmd, $commands)]);
                    return \false;
                }
                $abbrev = \str_pad($cmd, $maxLen, ' ') . ' ' . $commandList[$cmd]->getDescription();
                return Helper::width($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3) . '...' : $abbrev;
            }, \array_values($commands));
            if (\count($commands) > 1) {
                $suggestions = $this->getAbbreviationSuggestions(\array_filter($abbrevs));
                throw new CommandNotFoundException(\sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $name, $suggestions), \array_values($commands));
            }
        }
        $command = $this->get(\reset($commands));
        if ($command->isHidden()) {
            throw new CommandNotFoundException(\sprintf('The command "%s" does not exist.', $name));
        }
        return $command;
    }
    /**
     * Gets the commands (registered in the given namespace if provided).
     *
     * The array keys are the full names and the values the command instances.
     *
     * @return Command[]
     */
    public function all(string $namespace = null)
    {
        $this->init();
        if (null === $namespace) {
            if (!$this->commandLoader) {
                return $this->commands;
            }
            $commands = $this->commands;
            foreach ($this->commandLoader->getNames() as $name) {
                if (!isset($commands[$name]) && $this->has($name)) {
                    $commands[$name] = $this->get($name);
                }
            }
            return $commands;
        }
        $commands = [];
        foreach ($this->commands as $name => $command) {
            if ($namespace === $this->extractNamespace($name, \substr_count($namespace, ':') + 1)) {
                $commands[$name] = $command;
            }
        }
        if ($this->commandLoader) {
            foreach ($this->commandLoader->getNames() as $name) {
                if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, \substr_count($namespace, ':') + 1) && $this->has($name)) {
                    $commands[$name] = $this->get($name);
                }
            }
        }
        return $commands;
    }
    /**
     * Returns an array of possible abbreviations given a set of names.
     *
     * @return string[][]
     */
    public static function getAbbreviations(array $names)
    {
        $abbrevs = [];
        foreach ($names as $name) {
            for ($len = \strlen($name); $len > 0; --$len) {
                $abbrev = \substr($name, 0, $len);
                $abbrevs[$abbrev][] = $name;
            }
        }
        return $abbrevs;
    }
    public function renderThrowable(\Throwable $e, OutputInterface $output) : void
    {
        $output->writeln('', OutputInterface::VERBOSITY_QUIET);
        $this->doRenderThrowable($e, $output);
        if (null !== $this->runningCommand) {
            $output->writeln(\sprintf('<info>%s</info>', OutputFormatter::escape(\sprintf($this->runningCommand->getSynopsis(), $this->getName()))), OutputInterface::VERBOSITY_QUIET);
            $output->writeln('', OutputInterface::VERBOSITY_QUIET);
        }
    }
    protected function doRenderThrowable(\Throwable $e, OutputInterface $output) : void
    {
        do {
            $message = \trim($e->getMessage());
            if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $class = \get_debug_type($e);
                $title = \sprintf('  [%s%s]  ', $class, 0 !== ($code = $e->getCode()) ? ' (' . $code . ')' : '');
                $len = Helper::width($title);
            } else {
                $len = 0;
            }
            if (\str_contains($message, "@anonymous\x00")) {
                $message = \preg_replace_callback('/[a-zA-Z_\\x7f-\\xff][\\\\a-zA-Z0-9_\\x7f-\\xff]*+@anonymous\\x00.*?\\.php(?:0x?|:[0-9]++\\$)[0-9a-fA-F]++/', function ($m) {
                    return \class_exists($m[0], \false) ? ((\get_parent_class($m[0]) ?: \key(\class_implements($m[0]))) ?: 'class') . '@anonymous' : $m[0];
                }, $message);
            }
            $width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : \PHP_INT_MAX;
            $lines = [];
            foreach ('' !== $message ? \preg_split('/\\r?\\n/', $message) : [] as $line) {
                foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
                    // pre-format lines to get the right string length
                    $lineLength = Helper::width($line) + 4;
                    $lines[] = [$line, $lineLength];
                    $len = \max($lineLength, $len);
                }
            }
            $messages = [];
            if (!$e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $messages[] = \sprintf('<comment>%s</comment>', OutputFormatter::escape(\sprintf('In %s line %s:', \basename($e->getFile()) ?: 'n/a', $e->getLine() ?: 'n/a')));
            }
            $messages[] = $emptyLine = \sprintf('<error>%s</error>', \str_repeat(' ', $len));
            if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $messages[] = \sprintf('<error>%s%s</error>', $title, \str_repeat(' ', \max(0, $len - Helper::width($title))));
            }
            foreach ($lines as $line) {
                $messages[] = \sprintf('<error>  %s  %s</error>', OutputFormatter::escape($line[0]), \str_repeat(' ', $len - $line[1]));
            }
            $messages[] = $emptyLine;
            $messages[] = '';
            $output->writeln($messages, OutputInterface::VERBOSITY_QUIET);
            if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) {
                $output->writeln('<comment>Exception trace:</comment>', OutputInterface::VERBOSITY_QUIET);
                // exception related properties
                $trace = $e->getTrace();
                \array_unshift($trace, ['function' => '', 'file' => $e->getFile() ?: 'n/a', 'line' => $e->getLine() ?: 'n/a', 'args' => []]);
                for ($i = 0, $count = \count($trace); $i < $count; ++$i) {
                    $class = $trace[$i]['class'] ?? '';
                    $type = $trace[$i]['type'] ?? '';
                    $function = $trace[$i]['function'] ?? '';
                    $file = $trace[$i]['file'] ?? 'n/a';
                    $line = $trace[$i]['line'] ?? 'n/a';
                    $output->writeln(\sprintf(' %s%s at <info>%s:%s</info>', $class, $function ? $type . $function . '()' : '', $file, $line), OutputInterface::VERBOSITY_QUIET);
                }
                $output->writeln('', OutputInterface::VERBOSITY_QUIET);
            }
        } while ($e = $e->getPrevious());
    }
    /**
     * Configures the input and output instances based on the user arguments and options.
     */
    protected function configureIO(InputInterface $input, OutputInterface $output)
    {
        if (\true === $input->hasParameterOption(['--ansi'], \true)) {
            $output->setDecorated(\true);
        } elseif (\true === $input->hasParameterOption(['--no-ansi'], \true)) {
            $output->setDecorated(\false);
        }
        if (\true === $input->hasParameterOption(['--no-interaction', '-n'], \true)) {
            $input->setInteractive(\false);
        }
        switch ($shellVerbosity = (int) \getenv('SHELL_VERBOSITY')) {
            case -1:
                $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
                break;
            case 1:
                $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
                break;
            case 2:
                $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
                break;
            case 3:
                $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
                break;
            default:
                $shellVerbosity = 0;
                break;
        }
        if (\true === $input->hasParameterOption(['--quiet', '-q'], \true)) {
            $output->setVerbosity(OutputInterface::VERBOSITY_QUIET);
            $shellVerbosity = -1;
        } else {
            if ($input->hasParameterOption('-vvv', \true) || $input->hasParameterOption('--verbose=3', \true) || 3 === $input->getParameterOption('--verbose', \false, \true)) {
                $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG);
                $shellVerbosity = 3;
            } elseif ($input->hasParameterOption('-vv', \true) || $input->hasParameterOption('--verbose=2', \true) || 2 === $input->getParameterOption('--verbose', \false, \true)) {
                $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE);
                $shellVerbosity = 2;
            } elseif ($input->hasParameterOption('-v', \true) || $input->hasParameterOption('--verbose=1', \true) || $input->hasParameterOption('--verbose', \true) || $input->getParameterOption('--verbose', \false, \true)) {
                $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
                $shellVerbosity = 1;
            }
        }
        if (-1 === $shellVerbosity) {
            $input->setInteractive(\false);
        }
        if (\function_exists('putenv')) {
            @\putenv('SHELL_VERBOSITY=' . $shellVerbosity);
        }
        $_ENV['SHELL_VERBOSITY'] = $shellVerbosity;
        $_SERVER['SHELL_VERBOSITY'] = $shellVerbosity;
    }
    /**
     * Runs the current command.
     *
     * If an event dispatcher has been attached to the application,
     * events are also dispatched during the life-cycle of the command.
     *
     * @return int 0 if everything went fine, or an error code
     */
    protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
    {
        foreach ($command->getHelperSet() as $helper) {
            if ($helper instanceof InputAwareInterface) {
                $helper->setInput($input);
            }
        }
        if ($this->signalsToDispatchEvent) {
            $commandSignals = $command instanceof SignalableCommandInterface ? $command->getSubscribedSignals() : [];
            if ($commandSignals || null !== $this->dispatcher) {
                if (!$this->signalRegistry) {
                    throw new RuntimeException('Unable to subscribe to signal events. Make sure that the `pcntl` extension is installed and that "pcntl_*" functions are not disabled by your php.ini\'s "disable_functions" directive.');
                }
                if (Terminal::hasSttyAvailable()) {
                    $sttyMode = \shell_exec('stty -g');
                    foreach ([\SIGINT, \SIGTERM] as $signal) {
                        $this->signalRegistry->register($signal, static function () use($sttyMode) {
                            \shell_exec('stty ' . $sttyMode);
                        });
                    }
                }
            }
            if (null !== $this->dispatcher) {
                foreach ($this->signalsToDispatchEvent as $signal) {
                    $event = new ConsoleSignalEvent($command, $input, $output, $signal);
                    $this->signalRegistry->register($signal, function ($signal, $hasNext) use($event) {
                        $this->dispatcher->dispatch($event, ConsoleEvents::SIGNAL);
                        // No more handlers, we try to simulate PHP default behavior
                        if (!$hasNext) {
                            if (!\in_array($signal, [\SIGUSR1, \SIGUSR2], \true)) {
                                exit(0);
                            }
                        }
                    });
                }
            }
            foreach ($commandSignals as $signal) {
                $this->signalRegistry->register($signal, [$command, 'handleSignal']);
            }
        }
        if (null === $this->dispatcher) {
            return $command->run($input, $output);
        }
        // bind before the console.command event, so the listeners have access to input options/arguments
        try {
            $command->mergeApplicationDefinition();
            $input->bind($command->getDefinition());
        } catch (ExceptionInterface $e) {
            // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition
        }
        $event = new ConsoleCommandEvent($command, $input, $output);
        $e = null;
        try {
            $this->dispatcher->dispatch($event, ConsoleEvents::COMMAND);
            if ($event->commandShouldRun()) {
                $exitCode = $command->run($input, $output);
            } else {
                $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
            }
        } catch (\Throwable $e) {
            $event = new ConsoleErrorEvent($input, $output, $e, $command);
            $this->dispatcher->dispatch($event, ConsoleEvents::ERROR);
            $e = $event->getError();
            if (0 === ($exitCode = $event->getExitCode())) {
                $e = null;
            }
        }
        $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
        $this->dispatcher->dispatch($event, ConsoleEvents::TERMINATE);
        if (null !== $e) {
            throw $e;
        }
        return $event->getExitCode();
    }
    /**
     * Gets the name of the command based on input.
     *
     * @return string|null
     */
    protected function getCommandName(InputInterface $input)
    {
        return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument();
    }
    /**
     * Gets the default input definition.
     *
     * @return InputDefinition
     */
    protected function getDefaultInputDefinition()
    {
        return new InputDefinition([new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display help for the given command. When no command is given display help for the <info>' . $this->defaultCommand . '</info> command'), new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'), new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'), new InputOption('--ansi', '', InputOption::VALUE_NEGATABLE, 'Force (or disable --no-ansi) ANSI output', null), new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question')]);
    }
    /**
     * Gets the default commands that should always be available.
     *
     * @return Command[]
     */
    protected function getDefaultCommands()
    {
        return [new HelpCommand(), new ListCommand(), new CompleteCommand(), new DumpCompletionCommand()];
    }
    /**
     * Gets the default helper set with the helpers that should always be available.
     *
     * @return HelperSet
     */
    protected function getDefaultHelperSet()
    {
        return new HelperSet([new FormatterHelper(), new DebugFormatterHelper(), new ProcessHelper(), new QuestionHelper()]);
    }
    /**
     * Returns abbreviated suggestions in string format.
     */
    private function getAbbreviationSuggestions(array $abbrevs) : string
    {
        return '    ' . \implode("\n    ", $abbrevs);
    }
    /**
     * Returns the namespace part of the command name.
     *
     * This method is not part of public API and should not be used directly.
     *
     * @return string
     */
    public function extractNamespace(string $name, int $limit = null)
    {
        $parts = \explode(':', $name, -1);
        return \implode(':', null === $limit ? $parts : \array_slice($parts, 0, $limit));
    }
    /**
     * Finds alternative of $name among $collection,
     * if nothing is found in $collection, try in $abbrevs.
     *
     * @return string[]
     */
    private function findAlternatives(string $name, iterable $collection) : array
    {
        $threshold = 1000.0;
        $alternatives = [];
        $collectionParts = [];
        foreach ($collection as $item) {
            $collectionParts[$item] = \explode(':', $item);
        }
        foreach (\explode(':', $name) as $i => $subname) {
            foreach ($collectionParts as $collectionName => $parts) {
                $exists = isset($alternatives[$collectionName]);
                if (!isset($parts[$i]) && $exists) {
                    $alternatives[$collectionName] += $threshold;
                    continue;
                } elseif (!isset($parts[$i])) {
                    continue;
                }
                $lev = \levenshtein($subname, $parts[$i]);
                if ($lev <= \strlen($subname) / 3 || '' !== $subname && \str_contains($parts[$i], $subname)) {
                    $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
                } elseif ($exists) {
                    $alternatives[$collectionName] += $threshold;
                }
            }
        }
        foreach ($collection as $item) {
            $lev = \levenshtein($name, $item);
            if ($lev <= \strlen($name) / 3 || \str_contains($item, $name)) {
                $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;
            }
        }
        $alternatives = \array_filter($alternatives, function ($lev) use($threshold) {
            return $lev < 2 * $threshold;
        });
        \ksort($alternatives, \SORT_NATURAL | \SORT_FLAG_CASE);
        return \array_keys($alternatives);
    }
    /**
     * Sets the default Command name.
     *
     * @return $this
     */
    public function setDefaultCommand(string $commandName, bool $isSingleCommand = \false)
    {
        $this->defaultCommand = \explode('|', \ltrim($commandName, '|'))[0];
        if ($isSingleCommand) {
            // Ensure the command exist
            $this->find($commandName);
            $this->singleCommand = \true;
        }
        return $this;
    }
    /**
     * @internal
     */
    public function isSingleCommand() : bool
    {
        return $this->singleCommand;
    }
    private function splitStringByWidth(string $string, int $width) : array
    {
        // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly.
        // additionally, array_slice() is not enough as some character has doubled width.
        // we need a function to split string not by character count but by string width
        if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) {
            return \str_split($string, $width);
        }
        $utf8String = \mb_convert_encoding($string, 'utf8', $encoding);
        $lines = [];
        $line = '';
        $offset = 0;
        while (\preg_match('/.{1,10000}/u', $utf8String, $m, 0, $offset)) {
            $offset += \strlen($m[0]);
            foreach (\preg_split('//u', $m[0]) as $char) {
                // test if $char could be appended to current line
                if (\mb_strwidth($line . $char, 'utf8') <= $width) {
                    $line .= $char;
                    continue;
                }
                // if not, push current line to array and make new line
                $lines[] = \str_pad($line, $width);
                $line = $char;
            }
        }
        $lines[] = \count($lines) ? \str_pad($line, $width) : $line;
        \mb_convert_variables($encoding, 'utf8', $lines);
        return $lines;
    }
    /**
     * Returns all namespaces of the command name.
     *
     * @return string[]
     */
    private function extractAllNamespaces(string $name) : array
    {
        // -1 as third argument is needed to skip the command short name when exploding
        $parts = \explode(':', $name, -1);
        $namespaces = [];
        foreach ($parts as $part) {
            if (\count($namespaces)) {
                $namespaces[] = \end($namespaces) . ':' . $part;
            } else {
                $namespaces[] = $part;
            }
        }
        return $namespaces;
    }
    private function init()
    {
        if ($this->initialized) {
            return;
        }
        $this->initialized = \true;
        foreach ($this->getDefaultCommands() as $command) {
            $this->add($command);
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Attribute;

/**
 * Service tag to autoconfigure commands.
 */
#[\Attribute(\Attribute::TARGET_CLASS)]
class AsCommand
{
    public function __construct(public string $name, public ?string $description = null, array $aliases = [], bool $hidden = \false)
    {
        if (!$hidden && !$aliases) {
            return;
        }
        $name = \explode('|', $name);
        $name = \array_merge($name, $aliases);
        if ($hidden && '' !== $name[0]) {
            \array_unshift($name, '');
        }
        $this->name = \implode('|', $name);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\SignalRegistry;

final class SignalRegistry
{
    private $signalHandlers = [];
    public function __construct()
    {
        if (\function_exists('pcntl_async_signals')) {
            \pcntl_async_signals(\true);
        }
    }
    public function register(int $signal, callable $signalHandler) : void
    {
        if (!isset($this->signalHandlers[$signal])) {
            $previousCallback = \pcntl_signal_get_handler($signal);
            if (\is_callable($previousCallback)) {
                $this->signalHandlers[$signal][] = $previousCallback;
            }
        }
        $this->signalHandlers[$signal][] = $signalHandler;
        \pcntl_signal($signal, [$this, 'handle']);
    }
    public static function isSupported() : bool
    {
        if (!\function_exists('pcntl_signal')) {
            return \false;
        }
        if (\in_array('pcntl_signal', \explode(',', \ini_get('disable_functions')))) {
            return \false;
        }
        return \true;
    }
    /**
     * @internal
     */
    public function handle(int $signal) : void
    {
        $count = \count($this->signalHandlers[$signal]);
        foreach ($this->signalHandlers[$signal] as $i => $signalHandler) {
            $hasNext = $i !== $count - 1;
            $signalHandler($signal, $hasNext);
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class LogicException extends \LogicException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * Represents an incorrect namespace typed in the console.
 *
 * @author Pierre du Plessis <pdples@gmail.com>
 */
class NamespaceNotFoundException extends CommandNotFoundException
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * ExceptionInterface.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
interface ExceptionInterface extends \Throwable
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * Represents an incorrect command name typed in the console.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface
{
    private $alternatives;
    /**
     * @param string          $message      Exception message to throw
     * @param string[]        $alternatives List of similar defined names
     * @param int             $code         Exception code
     * @param \Throwable|null $previous     Previous exception used for the exception chaining
     */
    public function __construct(string $message, array $alternatives = [], int $code = 0, \Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
        $this->alternatives = $alternatives;
    }
    /**
     * @return string[]
     */
    public function getAlternatives()
    {
        return $this->alternatives;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * Represents an incorrect option name or value typed in the console.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * Represents failure to read input from stdin.
 *
 * @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
 */
class MissingInputException extends RuntimeException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception;

/**
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\CommandLoader;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\CommandNotFoundException;
/**
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
interface CommandLoaderInterface
{
    /**
     * Loads a command.
     *
     * @return Command
     *
     * @throws CommandNotFoundException
     */
    public function get(string $name);
    /**
     * Checks if a command exists.
     *
     * @return bool
     */
    public function has(string $name);
    /**
     * @return string[]
     */
    public function getNames();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\CommandLoader;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\CommandNotFoundException;
/**
 * A simple command loader using factories to instantiate commands lazily.
 *
 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
 */
class FactoryCommandLoader implements CommandLoaderInterface
{
    private $factories;
    /**
     * @param callable[] $factories Indexed by command names
     */
    public function __construct(array $factories)
    {
        $this->factories = $factories;
    }
    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        return isset($this->factories[$name]);
    }
    /**
     * {@inheritdoc}
     */
    public function get(string $name)
    {
        if (!isset($this->factories[$name])) {
            throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name));
        }
        $factory = $this->factories[$name];
        return $factory();
    }
    /**
     * {@inheritdoc}
     */
    public function getNames()
    {
        return \array_keys($this->factories);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\CommandLoader;

use _HumbugBox1cb33d1f20f1\Psr\Container\ContainerInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\CommandNotFoundException;
/**
 * Loads commands from a PSR-11 container.
 *
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class ContainerCommandLoader implements CommandLoaderInterface
{
    private $container;
    private $commandMap;
    /**
     * @param array $commandMap An array with command names as keys and service ids as values
     */
    public function __construct(ContainerInterface $container, array $commandMap)
    {
        $this->container = $container;
        $this->commandMap = $commandMap;
    }
    /**
     * {@inheritdoc}
     */
    public function get(string $name)
    {
        if (!$this->has($name)) {
            throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name));
        }
        return $this->container->get($this->commandMap[$name]);
    }
    /**
     * {@inheritdoc}
     */
    public function has(string $name)
    {
        return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]);
    }
    /**
     * {@inheritdoc}
     */
    public function getNames()
    {
        return \array_keys($this->commandMap);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service\ResetInterface;
/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class OutputFormatterStyleStack implements ResetInterface
{
    /**
     * @var OutputFormatterStyleInterface[]
     */
    private $styles;
    private $emptyStyle;
    public function __construct(OutputFormatterStyleInterface $emptyStyle = null)
    {
        $this->emptyStyle = $emptyStyle ?? new OutputFormatterStyle();
        $this->reset();
    }
    /**
     * Resets stack (ie. empty internal arrays).
     */
    public function reset()
    {
        $this->styles = [];
    }
    /**
     * Pushes a style in the stack.
     */
    public function push(OutputFormatterStyleInterface $style)
    {
        $this->styles[] = $style;
    }
    /**
     * Pops a style from the stack.
     *
     * @return OutputFormatterStyleInterface
     *
     * @throws InvalidArgumentException When style tags incorrectly nested
     */
    public function pop(OutputFormatterStyleInterface $style = null)
    {
        if (empty($this->styles)) {
            return $this->emptyStyle;
        }
        if (null === $style) {
            return \array_pop($this->styles);
        }
        foreach (\array_reverse($this->styles, \true) as $index => $stackedStyle) {
            if ($style->apply('') === $stackedStyle->apply('')) {
                $this->styles = \array_slice($this->styles, 0, $index);
                return $stackedStyle;
            }
        }
        throw new InvalidArgumentException('Incorrectly nested style tag found.');
    }
    /**
     * Computes current style with stacks top codes.
     *
     * @return OutputFormatterStyle
     */
    public function getCurrent()
    {
        if (empty($this->styles)) {
            return $this->emptyStyle;
        }
        return $this->styles[\count($this->styles) - 1];
    }
    /**
     * @return $this
     */
    public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle)
    {
        $this->emptyStyle = $emptyStyle;
        return $this;
    }
    /**
     * @return OutputFormatterStyleInterface
     */
    public function getEmptyStyle()
    {
        return $this->emptyStyle;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Color;
/**
 * Formatter style class for defining styles.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 */
class OutputFormatterStyle implements OutputFormatterStyleInterface
{
    private $color;
    private $foreground;
    private $background;
    private $options;
    private $href;
    private $handlesHrefGracefully;
    /**
     * Initializes output formatter style.
     *
     * @param string|null $foreground The style foreground color name
     * @param string|null $background The style background color name
     */
    public function __construct(string $foreground = null, string $background = null, array $options = [])
    {
        $this->color = new Color($this->foreground = $foreground ?: '', $this->background = $background ?: '', $this->options = $options);
    }
    /**
     * {@inheritdoc}
     */
    public function setForeground(string $color = null)
    {
        $this->color = new Color($this->foreground = $color ?: '', $this->background, $this->options);
    }
    /**
     * {@inheritdoc}
     */
    public function setBackground(string $color = null)
    {
        $this->color = new Color($this->foreground, $this->background = $color ?: '', $this->options);
    }
    public function setHref(string $url) : void
    {
        $this->href = $url;
    }
    /**
     * {@inheritdoc}
     */
    public function setOption(string $option)
    {
        $this->options[] = $option;
        $this->color = new Color($this->foreground, $this->background, $this->options);
    }
    /**
     * {@inheritdoc}
     */
    public function unsetOption(string $option)
    {
        $pos = \array_search($option, $this->options);
        if (\false !== $pos) {
            unset($this->options[$pos]);
        }
        $this->color = new Color($this->foreground, $this->background, $this->options);
    }
    /**
     * {@inheritdoc}
     */
    public function setOptions(array $options)
    {
        $this->color = new Color($this->foreground, $this->background, $this->options = $options);
    }
    /**
     * {@inheritdoc}
     */
    public function apply(string $text)
    {
        if (null === $this->handlesHrefGracefully) {
            $this->handlesHrefGracefully = 'JetBrains-JediTerm' !== \getenv('TERMINAL_EMULATOR') && (!\getenv('KONSOLE_VERSION') || (int) \getenv('KONSOLE_VERSION') > 201100);
        }
        if (null !== $this->href && $this->handlesHrefGracefully) {
            $text = "\x1b]8;;{$this->href}\x1b\\{$text}\x1b]8;;\x1b\\";
        }
        return $this->color->apply($text);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

/**
 * Formatter interface for console output.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 */
interface OutputFormatterInterface
{
    /**
     * Sets the decorated flag.
     */
    public function setDecorated(bool $decorated);
    /**
     * Whether the output will decorate messages.
     *
     * @return bool
     */
    public function isDecorated();
    /**
     * Sets a new style.
     */
    public function setStyle(string $name, OutputFormatterStyleInterface $style);
    /**
     * Checks if output formatter has style with specified name.
     *
     * @return bool
     */
    public function hasStyle(string $name);
    /**
     * Gets style options from style with specified name.
     *
     * @return OutputFormatterStyleInterface
     *
     * @throws \InvalidArgumentException When style isn't defined
     */
    public function getStyle(string $name);
    /**
     * Formats a message according to the given styles.
     *
     * @return string|null
     */
    public function format(?string $message);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

/**
 * @author Tien Xuan Vo <tien.xuan.vo@gmail.com>
 */
final class NullOutputFormatter implements OutputFormatterInterface
{
    private $style;
    /**
     * {@inheritdoc}
     */
    public function format(?string $message) : ?string
    {
        return null;
    }
    /**
     * {@inheritdoc}
     */
    public function getStyle(string $name) : OutputFormatterStyleInterface
    {
        // to comply with the interface we must return a OutputFormatterStyleInterface
        return $this->style ?? ($this->style = new NullOutputFormatterStyle());
    }
    /**
     * {@inheritdoc}
     */
    public function hasStyle(string $name) : bool
    {
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function isDecorated() : bool
    {
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated) : void
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function setStyle(string $name, OutputFormatterStyleInterface $style) : void
    {
        // do nothing
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
/**
 * Formatter class for console output.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
class OutputFormatter implements WrappableOutputFormatterInterface
{
    private $decorated;
    private $styles = [];
    private $styleStack;
    public function __clone()
    {
        $this->styleStack = clone $this->styleStack;
        foreach ($this->styles as $key => $value) {
            $this->styles[$key] = clone $value;
        }
    }
    /**
     * Escapes "<" and ">" special chars in given text.
     *
     * @return string
     */
    public static function escape(string $text)
    {
        $text = \preg_replace('/([^\\\\]|^)([<>])/', '$1\\\\$2', $text);
        return self::escapeTrailingBackslash($text);
    }
    /**
     * Escapes trailing "\" in given text.
     *
     * @internal
     */
    public static function escapeTrailingBackslash(string $text) : string
    {
        if (\str_ends_with($text, '\\')) {
            $len = \strlen($text);
            $text = \rtrim($text, '\\');
            $text = \str_replace("\x00", '', $text);
            $text .= \str_repeat("\x00", $len - \strlen($text));
        }
        return $text;
    }
    /**
     * Initializes console output formatter.
     *
     * @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances
     */
    public function __construct(bool $decorated = \false, array $styles = [])
    {
        $this->decorated = $decorated;
        $this->setStyle('error', new OutputFormatterStyle('white', 'red'));
        $this->setStyle('info', new OutputFormatterStyle('green'));
        $this->setStyle('comment', new OutputFormatterStyle('yellow'));
        $this->setStyle('question', new OutputFormatterStyle('black', 'cyan'));
        foreach ($styles as $name => $style) {
            $this->setStyle($name, $style);
        }
        $this->styleStack = new OutputFormatterStyleStack();
    }
    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        $this->decorated = $decorated;
    }
    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return $this->decorated;
    }
    /**
     * {@inheritdoc}
     */
    public function setStyle(string $name, OutputFormatterStyleInterface $style)
    {
        $this->styles[\strtolower($name)] = $style;
    }
    /**
     * {@inheritdoc}
     */
    public function hasStyle(string $name)
    {
        return isset($this->styles[\strtolower($name)]);
    }
    /**
     * {@inheritdoc}
     */
    public function getStyle(string $name)
    {
        if (!$this->hasStyle($name)) {
            throw new InvalidArgumentException(\sprintf('Undefined style: "%s".', $name));
        }
        return $this->styles[\strtolower($name)];
    }
    /**
     * {@inheritdoc}
     */
    public function format(?string $message)
    {
        return $this->formatAndWrap($message, 0);
    }
    /**
     * {@inheritdoc}
     */
    public function formatAndWrap(?string $message, int $width)
    {
        if (null === $message) {
            return '';
        }
        $offset = 0;
        $output = '';
        $openTagRegex = '[a-z](?:[^\\\\<>]*+ | \\\\.)*';
        $closeTagRegex = '[a-z][^<>]*+';
        $currentLineLength = 0;
        \preg_match_all("#<(({$openTagRegex}) | /({$closeTagRegex})?)>#ix", $message, $matches, \PREG_OFFSET_CAPTURE);
        foreach ($matches[0] as $i => $match) {
            $pos = $match[1];
            $text = $match[0];
            if (0 != $pos && '\\' == $message[$pos - 1]) {
                continue;
            }
            // add the text up to the next tag
            $output .= $this->applyCurrentStyle(\substr($message, $offset, $pos - $offset), $output, $width, $currentLineLength);
            $offset = $pos + \strlen($text);
            // opening tag?
            if ($open = '/' != $text[1]) {
                $tag = $matches[1][$i][0];
            } else {
                $tag = $matches[3][$i][0] ?? '';
            }
            if (!$open && !$tag) {
                // </>
                $this->styleStack->pop();
            } elseif (null === ($style = $this->createStyleFromString($tag))) {
                $output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength);
            } elseif ($open) {
                $this->styleStack->push($style);
            } else {
                $this->styleStack->pop($style);
            }
        }
        $output .= $this->applyCurrentStyle(\substr($message, $offset), $output, $width, $currentLineLength);
        return \strtr($output, ["\x00" => '\\', '\\<' => '<', '\\>' => '>']);
    }
    /**
     * @return OutputFormatterStyleStack
     */
    public function getStyleStack()
    {
        return $this->styleStack;
    }
    /**
     * Tries to create new style instance from string.
     */
    private function createStyleFromString(string $string) : ?OutputFormatterStyleInterface
    {
        if (isset($this->styles[$string])) {
            return $this->styles[$string];
        }
        if (!\preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, \PREG_SET_ORDER)) {
            return null;
        }
        $style = new OutputFormatterStyle();
        foreach ($matches as $match) {
            \array_shift($match);
            $match[0] = \strtolower($match[0]);
            if ('fg' == $match[0]) {
                $style->setForeground(\strtolower($match[1]));
            } elseif ('bg' == $match[0]) {
                $style->setBackground(\strtolower($match[1]));
            } elseif ('href' === $match[0]) {
                $url = \preg_replace('{\\\\([<>])}', '$1', $match[1]);
                $style->setHref($url);
            } elseif ('options' === $match[0]) {
                \preg_match_all('([^,;]+)', \strtolower($match[1]), $options);
                $options = \array_shift($options);
                foreach ($options as $option) {
                    $style->setOption($option);
                }
            } else {
                return null;
            }
        }
        return $style;
    }
    /**
     * Applies current style from stack to text, if must be applied.
     */
    private function applyCurrentStyle(string $text, string $current, int $width, int &$currentLineLength) : string
    {
        if ('' === $text) {
            return '';
        }
        if (!$width) {
            return $this->isDecorated() ? $this->styleStack->getCurrent()->apply($text) : $text;
        }
        if (!$currentLineLength && '' !== $current) {
            $text = \ltrim($text);
        }
        if ($currentLineLength) {
            $prefix = \substr($text, 0, $i = $width - $currentLineLength) . "\n";
            $text = \substr($text, $i);
        } else {
            $prefix = '';
        }
        \preg_match('~(\\n)$~', $text, $matches);
        $text = $prefix . \preg_replace('~([^\\n]{' . $width . '})\\ *~', "\$1\n", $text);
        $text = \rtrim($text, "\n") . ($matches[1] ?? '');
        if (!$currentLineLength && '' !== $current && "\n" !== \substr($current, -1)) {
            $text = "\n" . $text;
        }
        $lines = \explode("\n", $text);
        foreach ($lines as $line) {
            $currentLineLength += \strlen($line);
            if ($width <= $currentLineLength) {
                $currentLineLength = 0;
            }
        }
        if ($this->isDecorated()) {
            foreach ($lines as $i => $line) {
                $lines[$i] = $this->styleStack->getCurrent()->apply($line);
            }
        }
        return \implode("\n", $lines);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

/**
 * Formatter interface for console output that supports word wrapping.
 *
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
interface WrappableOutputFormatterInterface extends OutputFormatterInterface
{
    /**
     * Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping).
     */
    public function formatAndWrap(?string $message, int $width);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

/**
 * @author Tien Xuan Vo <tien.xuan.vo@gmail.com>
 */
final class NullOutputFormatterStyle implements OutputFormatterStyleInterface
{
    /**
     * {@inheritdoc}
     */
    public function apply(string $text) : string
    {
        return $text;
    }
    /**
     * {@inheritdoc}
     */
    public function setBackground(string $color = null) : void
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function setForeground(string $color = null) : void
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function setOption(string $option) : void
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function setOptions(array $options) : void
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function unsetOption(string $option) : void
    {
        // do nothing
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter;

/**
 * Formatter style interface for defining styles.
 *
 * @author Konstantin Kudryashov <ever.zet@gmail.com>
 */
interface OutputFormatterStyleInterface
{
    /**
     * Sets style foreground color.
     */
    public function setForeground(string $color = null);
    /**
     * Sets style background color.
     */
    public function setBackground(string $color = null);
    /**
     * Sets some specific style option.
     */
    public function setOption(string $option);
    /**
     * Unsets some specific style option.
     */
    public function unsetOption(string $option);
    /**
     * Sets multiple style options at once.
     */
    public function setOptions(array $options);
    /**
     * Applies the style to a given text.
     *
     * @return string
     */
    public function apply(string $text);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion;

/**
 * Represents a single suggested value.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
class Suggestion
{
    private $value;
    public function __construct(string $value)
    {
        $this->value = $value;
    }
    public function getValue() : string
    {
        return $this->value;
    }
    public function __toString() : string
    {
        return $this->getValue();
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
/**
 * Stores all completion suggestions for the current input.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class CompletionSuggestions
{
    private $valueSuggestions = [];
    private $optionSuggestions = [];
    /**
     * Add a suggested value for an input option or argument.
     *
     * @param string|Suggestion $value
     *
     * @return $this
     */
    public function suggestValue($value) : self
    {
        $this->valueSuggestions[] = !$value instanceof Suggestion ? new Suggestion($value) : $value;
        return $this;
    }
    /**
     * Add multiple suggested values at once for an input option or argument.
     *
     * @param list<string|Suggestion> $values
     *
     * @return $this
     */
    public function suggestValues(array $values) : self
    {
        foreach ($values as $value) {
            $this->suggestValue($value);
        }
        return $this;
    }
    /**
     * Add a suggestion for an input option name.
     *
     * @return $this
     */
    public function suggestOption(InputOption $option) : self
    {
        $this->optionSuggestions[] = $option;
        return $this;
    }
    /**
     * Add multiple suggestions for input option names at once.
     *
     * @param InputOption[] $options
     *
     * @return $this
     */
    public function suggestOptions(array $options) : self
    {
        foreach ($options as $option) {
            $this->suggestOption($option);
        }
        return $this;
    }
    /**
     * @return InputOption[]
     */
    public function getOptionSuggestions() : array
    {
        return $this->optionSuggestions;
    }
    /**
     * @return Suggestion[]
     */
    public function getValueSuggestions() : array
    {
        return $this->valueSuggestions;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\ArgvInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
/**
 * An input specialized for shell completion.
 *
 * This input allows unfinished option names or values and exposes what kind of
 * completion is expected.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
final class CompletionInput extends ArgvInput
{
    public const TYPE_ARGUMENT_VALUE = 'argument_value';
    public const TYPE_OPTION_VALUE = 'option_value';
    public const TYPE_OPTION_NAME = 'option_name';
    public const TYPE_NONE = 'none';
    private $tokens;
    private $currentIndex;
    private $completionType;
    private $completionName = null;
    private $completionValue = '';
    /**
     * Converts a terminal string into tokens.
     *
     * This is required for shell completions without COMP_WORDS support.
     */
    public static function fromString(string $inputStr, int $currentIndex) : self
    {
        \preg_match_all('/(?<=^|\\s)([\'"]?)(.+?)(?<!\\\\)\\1(?=$|\\s)/', $inputStr, $tokens);
        return self::fromTokens($tokens[0], $currentIndex);
    }
    /**
     * Create an input based on an COMP_WORDS token list.
     *
     * @param string[] $tokens       the set of split tokens (e.g. COMP_WORDS or argv)
     * @param          $currentIndex the index of the cursor (e.g. COMP_CWORD)
     */
    public static function fromTokens(array $tokens, int $currentIndex) : self
    {
        $input = new self($tokens);
        $input->tokens = $tokens;
        $input->currentIndex = $currentIndex;
        return $input;
    }
    /**
     * {@inheritdoc}
     */
    public function bind(InputDefinition $definition) : void
    {
        parent::bind($definition);
        $relevantToken = $this->getRelevantToken();
        if ('-' === $relevantToken[0]) {
            // the current token is an input option: complete either option name or option value
            [$optionToken, $optionValue] = \explode('=', $relevantToken, 2) + ['', ''];
            $option = $this->getOptionFromToken($optionToken);
            if (null === $option && !$this->isCursorFree()) {
                $this->completionType = self::TYPE_OPTION_NAME;
                $this->completionValue = $relevantToken;
                return;
            }
            if (null !== $option && $option->acceptValue()) {
                $this->completionType = self::TYPE_OPTION_VALUE;
                $this->completionName = $option->getName();
                $this->completionValue = $optionValue ?: (!\str_starts_with($optionToken, '--') ? \substr($optionToken, 2) : '');
                return;
            }
        }
        $previousToken = $this->tokens[$this->currentIndex - 1];
        if ('-' === $previousToken[0] && '' !== \trim($previousToken, '-')) {
            // check if previous option accepted a value
            $previousOption = $this->getOptionFromToken($previousToken);
            if (null !== $previousOption && $previousOption->acceptValue()) {
                $this->completionType = self::TYPE_OPTION_VALUE;
                $this->completionName = $previousOption->getName();
                $this->completionValue = $relevantToken;
                return;
            }
        }
        // complete argument value
        $this->completionType = self::TYPE_ARGUMENT_VALUE;
        foreach ($this->definition->getArguments() as $argumentName => $argument) {
            if (!isset($this->arguments[$argumentName])) {
                break;
            }
            $argumentValue = $this->arguments[$argumentName];
            $this->completionName = $argumentName;
            if (\is_array($argumentValue)) {
                $this->completionValue = $argumentValue ? $argumentValue[\array_key_last($argumentValue)] : null;
            } else {
                $this->completionValue = $argumentValue;
            }
        }
        if ($this->currentIndex >= \count($this->tokens)) {
            if (!isset($this->arguments[$argumentName]) || $this->definition->getArgument($argumentName)->isArray()) {
                $this->completionName = $argumentName;
                $this->completionValue = '';
            } else {
                // we've reached the end
                $this->completionType = self::TYPE_NONE;
                $this->completionName = null;
                $this->completionValue = '';
            }
        }
    }
    /**
     * Returns the type of completion required.
     *
     * TYPE_ARGUMENT_VALUE when completing the value of an input argument
     * TYPE_OPTION_VALUE   when completing the value of an input option
     * TYPE_OPTION_NAME    when completing the name of an input option
     * TYPE_NONE           when nothing should be completed
     *
     * @return string One of self::TYPE_* constants. TYPE_OPTION_NAME and TYPE_NONE are already implemented by the Console component
     */
    public function getCompletionType() : string
    {
        return $this->completionType;
    }
    /**
     * The name of the input option or argument when completing a value.
     *
     * @return string|null returns null when completing an option name
     */
    public function getCompletionName() : ?string
    {
        return $this->completionName;
    }
    /**
     * The value already typed by the user (or empty string).
     */
    public function getCompletionValue() : string
    {
        return $this->completionValue;
    }
    public function mustSuggestOptionValuesFor(string $optionName) : bool
    {
        return self::TYPE_OPTION_VALUE === $this->getCompletionType() && $optionName === $this->getCompletionName();
    }
    public function mustSuggestArgumentValuesFor(string $argumentName) : bool
    {
        return self::TYPE_ARGUMENT_VALUE === $this->getCompletionType() && $argumentName === $this->getCompletionName();
    }
    protected function parseToken(string $token, bool $parseOptions) : bool
    {
        try {
            return parent::parseToken($token, $parseOptions);
        } catch (RuntimeException $e) {
            // suppress errors, completed input is almost never valid
        }
        return $parseOptions;
    }
    private function getOptionFromToken(string $optionToken) : ?InputOption
    {
        $optionName = \ltrim($optionToken, '-');
        if (!$optionName) {
            return null;
        }
        if ('-' === ($optionToken[1] ?? ' ')) {
            // long option name
            return $this->definition->hasOption($optionName) ? $this->definition->getOption($optionName) : null;
        }
        // short option name
        return $this->definition->hasShortcut($optionName[0]) ? $this->definition->getOptionForShortcut($optionName[0]) : null;
    }
    /**
     * The token of the cursor, or the last token if the cursor is at the end of the input.
     */
    private function getRelevantToken() : string
    {
        return $this->tokens[$this->isCursorFree() ? $this->currentIndex - 1 : $this->currentIndex];
    }
    /**
     * Whether the cursor is "free" (i.e. at the end of the input preceded by a space).
     */
    private function isCursorFree() : bool
    {
        $nrOfTokens = \count($this->tokens);
        if ($this->currentIndex > $nrOfTokens) {
            throw new \LogicException('Current index is invalid, it must be the number of input tokens or one more.');
        }
        return $this->currentIndex >= $nrOfTokens;
    }
    public function __toString()
    {
        $str = '';
        foreach ($this->tokens as $i => $token) {
            $str .= $token;
            if ($this->currentIndex === $i) {
                $str .= '|';
            }
            $str .= ' ';
        }
        if ($this->currentIndex > $i) {
            $str .= '|';
        }
        return \rtrim($str);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Transforms the {@see CompletionSuggestions} object into output readable by the shell completion.
 *
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
interface CompletionOutputInterface
{
    public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void;
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * @author Wouter de Jong <wouter@wouterj.nl>
 */
class BashCompletionOutput implements CompletionOutputInterface
{
    public function write(CompletionSuggestions $suggestions, OutputInterface $output) : void
    {
        $values = $suggestions->getValueSuggestions();
        foreach ($suggestions->getOptionSuggestions() as $option) {
            $values[] = '--' . $option->getName();
            if ($option->isNegatable()) {
                $values[] = '--no-' . $option->getName();
            }
        }
        $output->writeln(\implode("\n", $values));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
/**
 * @author Fabien Potencier <fabien@symfony.com>
 */
final class Color
{
    private const COLORS = ['black' => 0, 'red' => 1, 'green' => 2, 'yellow' => 3, 'blue' => 4, 'magenta' => 5, 'cyan' => 6, 'white' => 7, 'default' => 9];
    private const BRIGHT_COLORS = ['gray' => 0, 'bright-red' => 1, 'bright-green' => 2, 'bright-yellow' => 3, 'bright-blue' => 4, 'bright-magenta' => 5, 'bright-cyan' => 6, 'bright-white' => 7];
    private const AVAILABLE_OPTIONS = ['bold' => ['set' => 1, 'unset' => 22], 'underscore' => ['set' => 4, 'unset' => 24], 'blink' => ['set' => 5, 'unset' => 25], 'reverse' => ['set' => 7, 'unset' => 27], 'conceal' => ['set' => 8, 'unset' => 28]];
    private $foreground;
    private $background;
    private $options = [];
    public function __construct(string $foreground = '', string $background = '', array $options = [])
    {
        $this->foreground = $this->parseColor($foreground);
        $this->background = $this->parseColor($background, \true);
        foreach ($options as $option) {
            if (!isset(self::AVAILABLE_OPTIONS[$option])) {
                throw new InvalidArgumentException(\sprintf('Invalid option specified: "%s". Expected one of (%s).', $option, \implode(', ', \array_keys(self::AVAILABLE_OPTIONS))));
            }
            $this->options[$option] = self::AVAILABLE_OPTIONS[$option];
        }
    }
    public function apply(string $text) : string
    {
        return $this->set() . $text . $this->unset();
    }
    public function set() : string
    {
        $setCodes = [];
        if ('' !== $this->foreground) {
            $setCodes[] = $this->foreground;
        }
        if ('' !== $this->background) {
            $setCodes[] = $this->background;
        }
        foreach ($this->options as $option) {
            $setCodes[] = $option['set'];
        }
        if (0 === \count($setCodes)) {
            return '';
        }
        return \sprintf("\x1b[%sm", \implode(';', $setCodes));
    }
    public function unset() : string
    {
        $unsetCodes = [];
        if ('' !== $this->foreground) {
            $unsetCodes[] = 39;
        }
        if ('' !== $this->background) {
            $unsetCodes[] = 49;
        }
        foreach ($this->options as $option) {
            $unsetCodes[] = $option['unset'];
        }
        if (0 === \count($unsetCodes)) {
            return '';
        }
        return \sprintf("\x1b[%sm", \implode(';', $unsetCodes));
    }
    private function parseColor(string $color, bool $background = \false) : string
    {
        if ('' === $color) {
            return '';
        }
        if ('#' === $color[0]) {
            $color = \substr($color, 1);
            if (3 === \strlen($color)) {
                $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2];
            }
            if (6 !== \strlen($color)) {
                throw new InvalidArgumentException(\sprintf('Invalid "%s" color.', $color));
            }
            return ($background ? '4' : '3') . $this->convertHexColorToAnsi(\hexdec($color));
        }
        if (isset(self::COLORS[$color])) {
            return ($background ? '4' : '3') . self::COLORS[$color];
        }
        if (isset(self::BRIGHT_COLORS[$color])) {
            return ($background ? '10' : '9') . self::BRIGHT_COLORS[$color];
        }
        throw new InvalidArgumentException(\sprintf('Invalid "%s" color; expected one of (%s).', $color, \implode(', ', \array_merge(\array_keys(self::COLORS), \array_keys(self::BRIGHT_COLORS)))));
    }
    private function convertHexColorToAnsi(int $color) : string
    {
        $r = $color >> 16 & 255;
        $g = $color >> 8 & 255;
        $b = $color & 255;
        // see https://github.com/termstandard/colors/ for more information about true color support
        if ('truecolor' !== \getenv('COLORTERM')) {
            return (string) $this->degradeHexColorToAnsi($r, $g, $b);
        }
        return \sprintf('8;2;%d;%d;%d', $r, $g, $b);
    }
    private function degradeHexColorToAnsi(int $r, int $g, int $b) : int
    {
        if (0 === \round($this->getSaturation($r, $g, $b) / 50)) {
            return 0;
        }
        return \round($b / 255) << 2 | \round($g / 255) << 1 | \round($r / 255);
    }
    private function getSaturation(int $r, int $g, int $b) : int
    {
        $r = $r / 255;
        $g = $g / 255;
        $b = $b / 255;
        $v = \max($r, $g, $b);
        if (0 === ($diff = $v - \min($r, $g, $b))) {
            return 0;
        }
        return (int) $diff * 100 / $v;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\DependencyInjection;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\LazyCommand;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use _HumbugBox1cb33d1f20f1\Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use _HumbugBox1cb33d1f20f1\Symfony\Component\DependencyInjection\ContainerBuilder;
use _HumbugBox1cb33d1f20f1\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\DependencyInjection\Reference;
use _HumbugBox1cb33d1f20f1\Symfony\Component\DependencyInjection\TypedReference;
/**
 * Registers console commands.
 *
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
class AddConsoleCommandPass implements CompilerPassInterface
{
    private $commandLoaderServiceId;
    private $commandTag;
    private $noPreloadTag;
    private $privateTagName;
    public function __construct(string $commandLoaderServiceId = 'console.command_loader', string $commandTag = 'console.command', string $noPreloadTag = 'container.no_preload', string $privateTagName = 'container.private')
    {
        if (0 < \func_num_args()) {
            trigger_deprecation('symfony/console', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
        }
        $this->commandLoaderServiceId = $commandLoaderServiceId;
        $this->commandTag = $commandTag;
        $this->noPreloadTag = $noPreloadTag;
        $this->privateTagName = $privateTagName;
    }
    public function process(ContainerBuilder $container)
    {
        $commandServices = $container->findTaggedServiceIds($this->commandTag, \true);
        $lazyCommandMap = [];
        $lazyCommandRefs = [];
        $serviceIds = [];
        foreach ($commandServices as $id => $tags) {
            $definition = $container->getDefinition($id);
            $definition->addTag($this->noPreloadTag);
            $class = $container->getParameterBag()->resolveValue($definition->getClass());
            if (isset($tags[0]['command'])) {
                $aliases = $tags[0]['command'];
            } else {
                if (!($r = $container->getReflectionClass($class))) {
                    throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
                }
                if (!$r->isSubclassOf(Command::class)) {
                    throw new InvalidArgumentException(\sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class));
                }
                $aliases = \str_replace('%', '%%', $class::getDefaultName() ?? '');
            }
            $aliases = \explode('|', $aliases ?? '');
            $commandName = \array_shift($aliases);
            if ($isHidden = '' === $commandName) {
                $commandName = \array_shift($aliases);
            }
            if (null === $commandName) {
                if (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag($this->privateTagName)) {
                    $commandId = 'console.command.public_alias.' . $id;
                    $container->setAlias($commandId, $id)->setPublic(\true);
                    $id = $commandId;
                }
                $serviceIds[] = $id;
                continue;
            }
            $description = $tags[0]['description'] ?? null;
            unset($tags[0]);
            $lazyCommandMap[$commandName] = $id;
            $lazyCommandRefs[$id] = new TypedReference($id, $class);
            foreach ($aliases as $alias) {
                $lazyCommandMap[$alias] = $id;
            }
            foreach ($tags as $tag) {
                if (isset($tag['command'])) {
                    $aliases[] = $tag['command'];
                    $lazyCommandMap[$tag['command']] = $id;
                }
                $description = $description ?? $tag['description'] ?? null;
            }
            $definition->addMethodCall('setName', [$commandName]);
            if ($aliases) {
                $definition->addMethodCall('setAliases', [$aliases]);
            }
            if ($isHidden) {
                $definition->addMethodCall('setHidden', [\true]);
            }
            if (!$description) {
                if (!($r = $container->getReflectionClass($class))) {
                    throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
                }
                if (!$r->isSubclassOf(Command::class)) {
                    throw new InvalidArgumentException(\sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class));
                }
                $description = \str_replace('%', '%%', $class::getDefaultDescription() ?? '');
            }
            if ($description) {
                $definition->addMethodCall('setDescription', [$description]);
                $container->register('.' . $id . '.lazy', LazyCommand::class)->setArguments([$commandName, $aliases, $description, $isHidden, new ServiceClosureArgument($lazyCommandRefs[$id])]);
                $lazyCommandRefs[$id] = new Reference('.' . $id . '.lazy');
            }
        }
        $container->register($this->commandLoaderServiceId, ContainerCommandLoader::class)->setPublic(\true)->addTag($this->noPreloadTag)->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]);
        $container->setParameter('console.command.ids', $serviceIds);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\CI;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Utility class for Github actions.
 *
 * @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
 */
class GithubActionReporter
{
    private $output;
    /**
     * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L80-L85
     */
    private const ESCAPED_DATA = ['%' => '%25', "\r" => '%0D', "\n" => '%0A'];
    /**
     * @see https://github.com/actions/toolkit/blob/5e5e1b7aacba68a53836a34db4a288c3c1c1585b/packages/core/src/command.ts#L87-L94
     */
    private const ESCAPED_PROPERTIES = ['%' => '%25', "\r" => '%0D', "\n" => '%0A', ':' => '%3A', ',' => '%2C'];
    public function __construct(OutputInterface $output)
    {
        $this->output = $output;
    }
    public static function isGithubActionEnvironment() : bool
    {
        return \false !== \getenv('GITHUB_ACTIONS');
    }
    /**
     * Output an error using the Github annotations format.
     *
     * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
     */
    public function error(string $message, string $file = null, int $line = null, int $col = null) : void
    {
        $this->log('error', $message, $file, $line, $col);
    }
    /**
     * Output a warning using the Github annotations format.
     *
     * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-warning-message
     */
    public function warning(string $message, string $file = null, int $line = null, int $col = null) : void
    {
        $this->log('warning', $message, $file, $line, $col);
    }
    /**
     * Output a debug log using the Github annotations format.
     *
     * @see https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-a-debug-message
     */
    public function debug(string $message, string $file = null, int $line = null, int $col = null) : void
    {
        $this->log('debug', $message, $file, $line, $col);
    }
    private function log(string $type, string $message, string $file = null, int $line = null, int $col = null) : void
    {
        // Some values must be encoded.
        $message = \strtr($message, self::ESCAPED_DATA);
        if (!$file) {
            // No file provided, output the message solely:
            $this->output->writeln(\sprintf('::%s::%s', $type, $message));
            return;
        }
        $this->output->writeln(\sprintf('::%s file=%s,line=%s,col=%s::%s', $type, \strtr($file, self::ESCAPED_PROPERTIES), \strtr($line ?? 1, self::ESCAPED_PROPERTIES), \strtr($col ?? 0, self::ESCAPED_PROPERTIES), $message));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\EventListener;

use _HumbugBox1cb33d1f20f1\Psr\Log\LoggerInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\ConsoleEvents;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleErrorEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Event\ConsoleTerminateEvent;
use _HumbugBox1cb33d1f20f1\Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
 * @author James Halsall <james.t.halsall@googlemail.com>
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class ErrorListener implements EventSubscriberInterface
{
    private $logger;
    public function __construct(LoggerInterface $logger = null)
    {
        $this->logger = $logger;
    }
    public function onConsoleError(ConsoleErrorEvent $event)
    {
        if (null === $this->logger) {
            return;
        }
        $error = $event->getError();
        if (!($inputString = $this->getInputString($event))) {
            $this->logger->critical('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]);
            return;
        }
        $this->logger->critical('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]);
    }
    public function onConsoleTerminate(ConsoleTerminateEvent $event)
    {
        if (null === $this->logger) {
            return;
        }
        $exitCode = $event->getExitCode();
        if (0 === $exitCode) {
            return;
        }
        if (!($inputString = $this->getInputString($event))) {
            $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]);
            return;
        }
        $this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]);
    }
    public static function getSubscribedEvents()
    {
        return [ConsoleEvents::ERROR => ['onConsoleError', -128], ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128]];
    }
    private static function getInputString(ConsoleEvent $event) : ?string
    {
        $commandName = $event->getCommand() ? $event->getCommand()->getName() : null;
        $input = $event->getInput();
        if (\method_exists($input, '__toString')) {
            if ($commandName) {
                return \str_replace(["'{$commandName}'", "\"{$commandName}\""], $commandName, (string) $input);
            }
            return (string) $input;
        }
        return $commandName;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Logger;

use _HumbugBox1cb33d1f20f1\Psr\Log\AbstractLogger;
use _HumbugBox1cb33d1f20f1\Psr\Log\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Psr\Log\LogLevel;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * PSR-3 compliant console logger.
 *
 * @author Kévin Dunglas <dunglas@gmail.com>
 *
 * @see https://www.php-fig.org/psr/psr-3/
 */
class ConsoleLogger extends AbstractLogger
{
    public const INFO = 'info';
    public const ERROR = 'error';
    private $output;
    private $verbosityLevelMap = [LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL, LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL, LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL, LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL, LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL, LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE, LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE, LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG];
    private $formatLevelMap = [LogLevel::EMERGENCY => self::ERROR, LogLevel::ALERT => self::ERROR, LogLevel::CRITICAL => self::ERROR, LogLevel::ERROR => self::ERROR, LogLevel::WARNING => self::INFO, LogLevel::NOTICE => self::INFO, LogLevel::INFO => self::INFO, LogLevel::DEBUG => self::INFO];
    private $errored = \false;
    public function __construct(OutputInterface $output, array $verbosityLevelMap = [], array $formatLevelMap = [])
    {
        $this->output = $output;
        $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap;
        $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap;
    }
    /**
     * {@inheritdoc}
     *
     * @return void
     */
    public function log($level, $message, array $context = [])
    {
        if (!isset($this->verbosityLevelMap[$level])) {
            throw new InvalidArgumentException(\sprintf('The log level "%s" does not exist.', $level));
        }
        $output = $this->output;
        // Write to the error output if necessary and available
        if (self::ERROR === $this->formatLevelMap[$level]) {
            if ($this->output instanceof ConsoleOutputInterface) {
                $output = $output->getErrorOutput();
            }
            $this->errored = \true;
        }
        // the if condition check isn't necessary -- it's the same one that $output will do internally anyway.
        // We only do it for efficiency here as the message formatting is relatively expensive.
        if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) {
            $output->writeln(\sprintf('<%1$s>[%2$s] %3$s</%1$s>', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)), $this->verbosityLevelMap[$level]);
        }
    }
    /**
     * Returns true when any messages have been logged at error levels.
     *
     * @return bool
     */
    public function hasErrored()
    {
        return $this->errored;
    }
    /**
     * Interpolates context values into the message placeholders.
     *
     * @author PHP Framework Interoperability Group
     */
    private function interpolate(string $message, array $context) : string
    {
        if (!\str_contains($message, '{')) {
            return $message;
        }
        $replacements = [];
        foreach ($context as $key => $val) {
            if (null === $val || \is_scalar($val) || \is_object($val) && \method_exists($val, '__toString')) {
                $replacements["{{$key}}"] = $val;
            } elseif ($val instanceof \DateTimeInterface) {
                $replacements["{{$key}}"] = $val->format(\DateTime::RFC3339);
            } elseif (\is_object($val)) {
                $replacements["{{$key}}"] = '[object ' . \get_class($val) . ']';
            } else {
                $replacements["{{$key}}"] = '[' . \gettype($val) . ']';
            }
        }
        return \strtr($message, $replacements);
    }
}
Copyright (c) 2004-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
/**
 * Represents a choice question.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ChoiceQuestion extends Question
{
    private $choices;
    private $multiselect = \false;
    private $prompt = ' > ';
    private $errorMessage = 'Value "%s" is invalid';
    /**
     * @param string $question The question to ask to the user
     * @param array  $choices  The list of available choices
     * @param mixed  $default  The default answer to return
     */
    public function __construct(string $question, array $choices, $default = null)
    {
        if (!$choices) {
            throw new \LogicException('Choice question must have at least 1 choice available.');
        }
        parent::__construct($question, $default);
        $this->choices = $choices;
        $this->setValidator($this->getDefaultValidator());
        $this->setAutocompleterValues($choices);
    }
    /**
     * Returns available choices.
     *
     * @return array
     */
    public function getChoices()
    {
        return $this->choices;
    }
    /**
     * Sets multiselect option.
     *
     * When multiselect is set to true, multiple choices can be answered.
     *
     * @return $this
     */
    public function setMultiselect(bool $multiselect)
    {
        $this->multiselect = $multiselect;
        $this->setValidator($this->getDefaultValidator());
        return $this;
    }
    /**
     * Returns whether the choices are multiselect.
     *
     * @return bool
     */
    public function isMultiselect()
    {
        return $this->multiselect;
    }
    /**
     * Gets the prompt for choices.
     *
     * @return string
     */
    public function getPrompt()
    {
        return $this->prompt;
    }
    /**
     * Sets the prompt for choices.
     *
     * @return $this
     */
    public function setPrompt(string $prompt)
    {
        $this->prompt = $prompt;
        return $this;
    }
    /**
     * Sets the error message for invalid values.
     *
     * The error message has a string placeholder (%s) for the invalid value.
     *
     * @return $this
     */
    public function setErrorMessage(string $errorMessage)
    {
        $this->errorMessage = $errorMessage;
        $this->setValidator($this->getDefaultValidator());
        return $this;
    }
    private function getDefaultValidator() : callable
    {
        $choices = $this->choices;
        $errorMessage = $this->errorMessage;
        $multiselect = $this->multiselect;
        $isAssoc = $this->isAssoc($choices);
        return function ($selected) use($choices, $errorMessage, $multiselect, $isAssoc) {
            if ($multiselect) {
                // Check for a separated comma values
                if (!\preg_match('/^[^,]+(?:,[^,]+)*$/', (string) $selected, $matches)) {
                    throw new InvalidArgumentException(\sprintf($errorMessage, $selected));
                }
                $selectedChoices = \explode(',', (string) $selected);
            } else {
                $selectedChoices = [$selected];
            }
            if ($this->isTrimmable()) {
                foreach ($selectedChoices as $k => $v) {
                    $selectedChoices[$k] = \trim((string) $v);
                }
            }
            $multiselectChoices = [];
            foreach ($selectedChoices as $value) {
                $results = [];
                foreach ($choices as $key => $choice) {
                    if ($choice === $value) {
                        $results[] = $key;
                    }
                }
                if (\count($results) > 1) {
                    throw new InvalidArgumentException(\sprintf('The provided answer is ambiguous. Value should be one of "%s".', \implode('" or "', $results)));
                }
                $result = \array_search($value, $choices);
                if (!$isAssoc) {
                    if (\false !== $result) {
                        $result = $choices[$result];
                    } elseif (isset($choices[$value])) {
                        $result = $choices[$value];
                    }
                } elseif (\false === $result && isset($choices[$value])) {
                    $result = $value;
                }
                if (\false === $result) {
                    throw new InvalidArgumentException(\sprintf($errorMessage, $value));
                }
                // For associative choices, consistently return the key as string:
                $multiselectChoices[] = $isAssoc ? (string) $result : $result;
            }
            if ($multiselect) {
                return $multiselectChoices;
            }
            return \current($multiselectChoices);
        };
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question;

/**
 * Represents a yes/no question.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ConfirmationQuestion extends Question
{
    private $trueAnswerRegex;
    /**
     * @param string $question        The question to ask to the user
     * @param bool   $default         The default answer to return, true or false
     * @param string $trueAnswerRegex A regex to match the "yes" answer
     */
    public function __construct(string $question, bool $default = \true, string $trueAnswerRegex = '/^y/i')
    {
        parent::__construct($question, $default);
        $this->trueAnswerRegex = $trueAnswerRegex;
        $this->setNormalizer($this->getDefaultNormalizer());
    }
    /**
     * Returns the default answer normalizer.
     */
    private function getDefaultNormalizer() : callable
    {
        $default = $this->getDefault();
        $regex = $this->trueAnswerRegex;
        return function ($answer) use($default, $regex) {
            if (\is_bool($answer)) {
                return $answer;
            }
            $answerIsTrue = (bool) \preg_match($regex, $answer);
            if (\false === $default) {
                return $answer && $answerIsTrue;
            }
            return '' === $answer || $answerIsTrue;
        };
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
/**
 * Represents a Question.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Question
{
    private $question;
    private $attempts;
    private $hidden = \false;
    private $hiddenFallback = \true;
    private $autocompleterCallback;
    private $validator;
    private $default;
    private $normalizer;
    private $trimmable = \true;
    private $multiline = \false;
    /**
     * @param string                     $question The question to ask to the user
     * @param string|bool|int|float|null $default  The default answer to return if the user enters nothing
     */
    public function __construct(string $question, $default = null)
    {
        $this->question = $question;
        $this->default = $default;
    }
    /**
     * Returns the question.
     *
     * @return string
     */
    public function getQuestion()
    {
        return $this->question;
    }
    /**
     * Returns the default answer.
     *
     * @return string|bool|int|float|null
     */
    public function getDefault()
    {
        return $this->default;
    }
    /**
     * Returns whether the user response accepts newline characters.
     */
    public function isMultiline() : bool
    {
        return $this->multiline;
    }
    /**
     * Sets whether the user response should accept newline characters.
     *
     * @return $this
     */
    public function setMultiline(bool $multiline) : self
    {
        $this->multiline = $multiline;
        return $this;
    }
    /**
     * Returns whether the user response must be hidden.
     *
     * @return bool
     */
    public function isHidden()
    {
        return $this->hidden;
    }
    /**
     * Sets whether the user response must be hidden or not.
     *
     * @return $this
     *
     * @throws LogicException In case the autocompleter is also used
     */
    public function setHidden(bool $hidden)
    {
        if ($this->autocompleterCallback) {
            throw new LogicException('A hidden question cannot use the autocompleter.');
        }
        $this->hidden = $hidden;
        return $this;
    }
    /**
     * In case the response cannot be hidden, whether to fallback on non-hidden question or not.
     *
     * @return bool
     */
    public function isHiddenFallback()
    {
        return $this->hiddenFallback;
    }
    /**
     * Sets whether to fallback on non-hidden question if the response cannot be hidden.
     *
     * @return $this
     */
    public function setHiddenFallback(bool $fallback)
    {
        $this->hiddenFallback = $fallback;
        return $this;
    }
    /**
     * Gets values for the autocompleter.
     *
     * @return iterable|null
     */
    public function getAutocompleterValues()
    {
        $callback = $this->getAutocompleterCallback();
        return $callback ? $callback('') : null;
    }
    /**
     * Sets values for the autocompleter.
     *
     * @return $this
     *
     * @throws LogicException
     */
    public function setAutocompleterValues(?iterable $values)
    {
        if (\is_array($values)) {
            $values = $this->isAssoc($values) ? \array_merge(\array_keys($values), \array_values($values)) : \array_values($values);
            $callback = static function () use($values) {
                return $values;
            };
        } elseif ($values instanceof \Traversable) {
            $valueCache = null;
            $callback = static function () use($values, &$valueCache) {
                return $valueCache ?? ($valueCache = \iterator_to_array($values, \false));
            };
        } else {
            $callback = null;
        }
        return $this->setAutocompleterCallback($callback);
    }
    /**
     * Gets the callback function used for the autocompleter.
     */
    public function getAutocompleterCallback() : ?callable
    {
        return $this->autocompleterCallback;
    }
    /**
     * Sets the callback function used for the autocompleter.
     *
     * The callback is passed the user input as argument and should return an iterable of corresponding suggestions.
     *
     * @return $this
     */
    public function setAutocompleterCallback(callable $callback = null) : self
    {
        if ($this->hidden && null !== $callback) {
            throw new LogicException('A hidden question cannot use the autocompleter.');
        }
        $this->autocompleterCallback = $callback;
        return $this;
    }
    /**
     * Sets a validator for the question.
     *
     * @return $this
     */
    public function setValidator(callable $validator = null)
    {
        $this->validator = $validator;
        return $this;
    }
    /**
     * Gets the validator for the question.
     *
     * @return callable|null
     */
    public function getValidator()
    {
        return $this->validator;
    }
    /**
     * Sets the maximum number of attempts.
     *
     * Null means an unlimited number of attempts.
     *
     * @return $this
     *
     * @throws InvalidArgumentException in case the number of attempts is invalid
     */
    public function setMaxAttempts(?int $attempts)
    {
        if (null !== $attempts && $attempts < 1) {
            throw new InvalidArgumentException('Maximum number of attempts must be a positive value.');
        }
        $this->attempts = $attempts;
        return $this;
    }
    /**
     * Gets the maximum number of attempts.
     *
     * Null means an unlimited number of attempts.
     *
     * @return int|null
     */
    public function getMaxAttempts()
    {
        return $this->attempts;
    }
    /**
     * Sets a normalizer for the response.
     *
     * The normalizer can be a callable (a string), a closure or a class implementing __invoke.
     *
     * @return $this
     */
    public function setNormalizer(callable $normalizer)
    {
        $this->normalizer = $normalizer;
        return $this;
    }
    /**
     * Gets the normalizer for the response.
     *
     * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.
     *
     * @return callable|null
     */
    public function getNormalizer()
    {
        return $this->normalizer;
    }
    protected function isAssoc(array $array)
    {
        return (bool) \count(\array_filter(\array_keys($array), 'is_string'));
    }
    public function isTrimmable() : bool
    {
        return $this->trimmable;
    }
    /**
     * @return $this
     */
    public function setTrimmable(bool $trimmable) : self
    {
        $this->trimmable = $trimmable;
        return $this;
    }
}
MZ����@���	�!�L�!This program cannot be run in DOS mode.

$�,�;�B�;�B�;�B�2�מ:�B�2��-�B�2�ƞ9�B�2�ў?�B�a9�8�B�;�C��B�2�Ȟ:�B�2�֞:�B�2�Ӟ:�B�Rich;�B�PEL�MoO�	
8 @`?�@��"P@ Pp!8!@ �.text	
 `.rdata�	 
@@.data�0@�.rsrc @@@.reloc�P"@Bj$��@�xj�� @�e���E�PV� @�EЃ�PV� @�M�X @�e��E�P�5H @�L @YY�5\ @�E�P�5` @�D @YY��P @�M���M�T @3��H�;
0@u���h�@��l3@�$40@�5h3@�40@h$0@h(0@h 0@�� @���00@��}j�Y�jh"@�3ۉ]�d��p�]俀3@SVW�0 @;�t;�u3�F�u��h��4 @��3�F�|3@;�u
j�\Y�;�|3@��u,�5|3@h� @h� @�YY��t�E����������5<0@�|3@;�uh� @h� @�lYY�|3@9]�uSW�8 @9�3@th�3@�Y��t
SjS��3@�$0@�
� @��5$0@�5(0@�5 0@�������80@9,0@u7P�� @�E��	�M�PQ�YYËe�E�80@3�9,0@uP�h @9<0@u�� @�E������80@�øMZf9@t3��M�<@��@�8PEu��H��t��uՃ��v�3�9����xtv�3�9������j�,0@�p @j��l @YY��3@��3@�� @�
t3@��� @�
p3@��� @��x3@�V��=0@uh�@�� @Y�g�=0@�u	j��� @Y3���{�����U���(�H1@�
D1@�@1@�<1@�581@�=41@f�`1@f�
T1@f�01@f�,1@f�%(1@f�-$1@��X1@�E�L1@�E�P1@�E�\1@������0@�P1@�L0@�@0@	��D0@�0@������0@������ @��0@j�?Yj�  @h!@�$ @�=�0@uj�Yh	��( @P�, @�Ë�U��E��8csm�u*�xu$�@= �t=!�t="�t=@�u��3�]�hH@�  @3��%� @jh("@�b�5�3@�5� @��Y�E��u�u�� @Y�gj�Y�e��5�3@�։E�5�3@��YY�E�E�P�E�P�u�5l @��YP�U�E�u�֣�3@�u�փ���3@�E������	�E���j�YË�U��u�N��������YH]Ë�V��!@��!@W��;�s���t�Ѓ�;�r�_^Ë�V�"@�"@W��;�s���t�Ѓ�;�r�_^�%� @���̋�U��M�MZf9t3�]ËA<��8PEu�3ҹf9H�‹�]�����������̋�U��E�H<��ASV�q3�W�D��v�}�H;�r	�X�;�r
B��(;�r�3�_^[]������������̋�U��j�hH"@he@d�P��SVW�0@1E�3�P�E�d��e��E�h@�*�������tU�E-@Ph@�P�������t;�@$���Ѓ��E������M�d�
Y_^[��]ËE��3�=��‹�Ëe��E�����3��M�d�
Y_^[��]��%� @�%� @��he@d�5�D$�l$�l$+�SVW�0@1E�3�P�e�u��E��E������E��E�d�ËM�d�
Y__^[��]Q�U��u�u�u�uh�@h0@����]�Vhh3�V������t
VVVVV����^�3��U����0@�e��e�SW�N�@����;�t
��t	�У0@�`V�E�P�< @�u�3u�� @3� @3� @3�E�P� @�E�3E�3�;�u�O�@����u����50@�։50@^_[��%t @�%x @�%| @�%� @�%� @�%� @�%� @�%� @�%� @Pd�5�D$+d$SVW�(��0@3�P�E�u��E������E�d�ËM�d�
Y__^[��]QËM�3���������M�%T @�T$�B�J�3�����J�3�����l"@�s����#�#�#�)r)b)H)4))�(�(�(�(�(�(�)�#�$%�%&d&�&�$('�'�'�'�'(((6(�'H(Z(t(�('''�'�'l'^'R'F'>'>(0'�'�)�@W@�@�MoOl�!�@0@�0@bad allocationH0@�!@RSDSь���J�!���LZc:\users\seld\documents\visual studio 2010\Projects\hiddeninp\Release\hiddeninp.pdbe������������@@�����������:@������������@�@�����@"�d"@�"�# $#�&D H#(h �#�#�#�)r)b)H)4))�(�(�(�(�(�(�)�#�$%�%&d&�&�$('�'�'�'�'(((6(�'H(Z(t(�('''�'�'l'^'R'F'>'>(0'�'�)�GetConsoleMode�SetConsoleMode;GetStdHandleKERNEL32.dll??$?6DU?$char_traits@D@std@@V?$allocator@D@1@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z�?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@AJ?cin@std@@3V?$basic_istream@DU?$char_traits@D@std@@@1@A�??$getline@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@YAAAV?$basic_istream@DU?$char_traits@D@std@@@0@AAV10@AAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@0@@Z??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z_??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ{??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ�?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@ZMSVCP90.dll_amsg_exit�__getmainargs,_cexit|_exitf_XcptFilter�exit�__initenv_initterm_initterm_e<_configthreadlocale�__setusermatherr_adjust_fdiv�__p__commode�__p__fmodej_encode_pointer�__set_app_typeK_crt_debugger_hookC?terminate@@YAXXZMSVCR90.dll�_unlock�__dllonexitv_lock_onexit`_decode_pointers_except_handler4_common_invoke_watson?_controlfp_s�InterlockedExchange!Sleep�InterlockedCompareExchange-TerminateProcess�GetCurrentProcess>UnhandledExceptionFilterSetUnhandledExceptionFilter�IsDebuggerPresentTQueryPerformanceCounterfGetTickCount�GetCurrentThreadId�GetCurrentProcessIdOGetSystemTimeAsFileTimes__CxxFrameHandler3N�@���D������������$!@ �8�P�h�	�	��@(��CV�(4VS_VERSION_INFO���StringFileInfob040904b0�QFileDescriptionReads from stdin without leaking info to the terminal and outputs back to stdout6FileVersion1, 0, 0, 08InternalNamehiddeninputPLegalCopyrightJordi Boggiano - 2012HOriginalFilenamehiddeninput.exe:
ProductNameHidden Input:ProductVersion1, 0, 0, 0DVarFileInfo$Translation	�<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>PAPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDINGPADDINGXXPADDING@00!0/080F0L0T0^0d0n0{0�0�0�0�0�0�0�0�0�0�0�0�0�01#1-1@1J1O1T1v1{1�1�1�1�1�1�1�1�1�1�1�1�1�1�12"2*23292A2M2_2j2p2�2�2�2�2�2�2�2�2�2�2�2333%303N3T3Z3`3f3l3s3z3�3�3�3�3�3�3�3�3�3�3�3�3�3�3�3�34444%4;4B4�4�4�4�4�4�4�4�4�4�45!5^5c5�5�5�5H6M6_6}6�6�677
7*7w7|7�7�7�7�78
88=8E8P8V8\8b8h8n8t8z8�8�8�89 $�0�0�01 1t1x12 2@2\2`2h2t200# This file is part of the Symfony package.
#
# (c) Fabien Potencier <fabien@symfony.com>
#
# For the full copyright and license information, please view
# https://symfony.com/doc/current/contributing/code/license.html

_sf_{{ COMMAND_NAME }}() {
    # Use newline as only separator to allow space in completion values
    IFS=$'\n'
    local sf_cmd="${COMP_WORDS[0]}"

    # for an alias, get the real script behind it
    sf_cmd_type=$(type -t $sf_cmd)
    if [[ $sf_cmd_type == "alias" ]]; then
        sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/")
    elif [[ $sf_cmd_type == "file" ]]; then
        sf_cmd=$(type -p $sf_cmd)
    fi

    if [[ $sf_cmd_type != "function" && ! -x $sf_cmd ]]; then
        return 1
    fi

    local cur prev words cword
    _get_comp_words_by_ref -n := cur prev words cword

    local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-S{{ VERSION }}")
    for w in ${words[@]}; do
        w=$(printf -- '%b' "$w")
        # remove quotes from typed values
        quote="${w:0:1}"
        if [ "$quote" == \' ]; then
            w="${w%\'}"
            w="${w#\'}"
        elif [ "$quote" == \" ]; then
            w="${w%\"}"
            w="${w#\"}"
        fi
        # empty values are ignored
        if [ ! -z "$w" ]; then
            completecmd+=("-i$w")
        fi
    done

    local sfcomplete
    if sfcomplete=$(${completecmd[@]} 2>&1); then
        local quote suggestions
        quote=${cur:0:1}

        # Use single quotes by default if suggestions contains backslash (FQCN)
        if [ "$quote" == '' ] && [[ "$sfcomplete" =~ \\ ]]; then
            quote=\'
        fi

        if [ "$quote" == \' ]; then
            # single quotes: no additional escaping (does not accept ' in values)
            suggestions=$(for s in $sfcomplete; do printf $'%q%q%q\n' "$quote" "$s" "$quote"; done)
        elif [ "$quote" == \" ]; then
            # double quotes: double escaping for \ $ ` "
            suggestions=$(for s in $sfcomplete; do
                s=${s//\\/\\\\}
                s=${s//\$/\\\$}
                s=${s//\`/\\\`}
                s=${s//\"/\\\"}
                printf $'%q%q%q\n' "$quote" "$s" "$quote";
            done)
        else
            # no quotes: double escaping
            suggestions=$(for s in $sfcomplete; do printf $'%q\n' $(printf '%q' "$s"); done)
        fi
        COMPREPLY=($(IFS=$'\n' compgen -W "$suggestions" -- $(printf -- "%q" "$cur")))
        __ltrim_colon_completions "$cur"
    else
        if [[ "$sfcomplete" != *"Command \"_complete\" is not defined."* ]]; then
            >&2 echo
            >&2 echo $sfcomplete
        fi

        return 1
    fi
}

complete -F _sf_{{ COMMAND_NAME }} {{ COMMAND_NAME }}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\UnicodeString;
/**
 * Helper is the base class for all helper classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Helper implements HelperInterface
{
    protected $helperSet = null;
    /**
     * {@inheritdoc}
     */
    public function setHelperSet(HelperSet $helperSet = null)
    {
        $this->helperSet = $helperSet;
    }
    /**
     * {@inheritdoc}
     */
    public function getHelperSet()
    {
        return $this->helperSet;
    }
    /**
     * Returns the length of a string, using mb_strwidth if it is available.
     *
     * @deprecated since Symfony 5.3
     *
     * @return int
     */
    public static function strlen(?string $string)
    {
        trigger_deprecation('symfony/console', '5.3', 'Method "%s()" is deprecated and will be removed in Symfony 6.0. Use Helper::width() or Helper::length() instead.', __METHOD__);
        return self::width($string);
    }
    /**
     * Returns the width of a string, using mb_strwidth if it is available.
     * The width is how many characters positions the string will use.
     */
    public static function width(?string $string) : int
    {
        $string ?? ($string = '');
        if (\preg_match('//u', $string)) {
            return (new UnicodeString($string))->width(\false);
        }
        if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) {
            return \strlen($string);
        }
        return \mb_strwidth($string, $encoding);
    }
    /**
     * Returns the length of a string, using mb_strlen if it is available.
     * The length is related to how many bytes the string will use.
     */
    public static function length(?string $string) : int
    {
        $string ?? ($string = '');
        if (\preg_match('//u', $string)) {
            return (new UnicodeString($string))->length();
        }
        if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) {
            return \strlen($string);
        }
        return \mb_strlen($string, $encoding);
    }
    /**
     * Returns the subset of a string, using mb_substr if it is available.
     *
     * @return string
     */
    public static function substr(?string $string, int $from, int $length = null)
    {
        $string ?? ($string = '');
        if (\false === ($encoding = \mb_detect_encoding($string, null, \true))) {
            return \substr($string, $from, $length);
        }
        return \mb_substr($string, $from, $length, $encoding);
    }
    public static function formatTime($secs)
    {
        static $timeFormats = [[0, '< 1 sec'], [1, '1 sec'], [2, 'secs', 1], [60, '1 min'], [120, 'mins', 60], [3600, '1 hr'], [7200, 'hrs', 3600], [86400, '1 day'], [172800, 'days', 86400]];
        foreach ($timeFormats as $index => $format) {
            if ($secs >= $format[0]) {
                if (isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0] || $index == \count($timeFormats) - 1) {
                    if (2 == \count($format)) {
                        return $format[1];
                    }
                    return \floor($secs / $format[2]) . ' ' . $format[1];
                }
            }
        }
    }
    public static function formatMemory(int $memory)
    {
        if ($memory >= 1024 * 1024 * 1024) {
            return \sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024);
        }
        if ($memory >= 1024 * 1024) {
            return \sprintf('%.1f MiB', $memory / 1024 / 1024);
        }
        if ($memory >= 1024) {
            return \sprintf('%d KiB', $memory / 1024);
        }
        return \sprintf('%d B', $memory);
    }
    /**
     * @deprecated since Symfony 5.3
     */
    public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, ?string $string)
    {
        trigger_deprecation('symfony/console', '5.3', 'Method "%s()" is deprecated and will be removed in Symfony 6.0. Use Helper::removeDecoration() instead.', __METHOD__);
        return self::width(self::removeDecoration($formatter, $string));
    }
    public static function removeDecoration(OutputFormatterInterface $formatter, ?string $string)
    {
        $isDecorated = $formatter->isDecorated();
        $formatter->setDecorated(\false);
        // remove <...> formatting
        $string = $formatter->format($string ?? '');
        // remove already formatted characters
        $string = \preg_replace("/\x1b\\[[^m]*m/", '', $string ?? '');
        // remove terminal hyperlinks
        $string = \preg_replace('/\\033]8;[^;]*;[^\\033]*\\033\\\\/', '', $string ?? '');
        $formatter->setDecorated($isDecorated);
        return $string;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Cursor;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\MissingInputException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterStyle;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\StreamableInputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleSectionOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\ChoiceQuestion;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\Question;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Terminal;
use function _HumbugBox1cb33d1f20f1\Symfony\Component\String\s;
/**
 * The QuestionHelper class provides helpers to interact with the user.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class QuestionHelper extends Helper
{
    /**
     * @var resource|null
     */
    private $inputStream;
    private static $stty = \true;
    private static $stdinIsInteractive;
    /**
     * Asks a question to the user.
     *
     * @return mixed The user answer
     *
     * @throws RuntimeException If there is no data to read in the input stream
     */
    public function ask(InputInterface $input, OutputInterface $output, Question $question)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }
        if (!$input->isInteractive()) {
            return $this->getDefaultAnswer($question);
        }
        if ($input instanceof StreamableInputInterface && ($stream = $input->getStream())) {
            $this->inputStream = $stream;
        }
        try {
            if (!$question->getValidator()) {
                return $this->doAsk($output, $question);
            }
            $interviewer = function () use($output, $question) {
                return $this->doAsk($output, $question);
            };
            return $this->validateAttempts($interviewer, $output, $question);
        } catch (MissingInputException $exception) {
            $input->setInteractive(\false);
            if (null === ($fallbackOutput = $this->getDefaultAnswer($question))) {
                throw $exception;
            }
            return $fallbackOutput;
        }
    }
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'question';
    }
    /**
     * Prevents usage of stty.
     */
    public static function disableStty()
    {
        self::$stty = \false;
    }
    /**
     * Asks the question to the user.
     *
     * @return mixed
     *
     * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
     */
    private function doAsk(OutputInterface $output, Question $question)
    {
        $this->writePrompt($output, $question);
        $inputStream = $this->inputStream ?: \STDIN;
        $autocomplete = $question->getAutocompleterCallback();
        if (null === $autocomplete || !self::$stty || !Terminal::hasSttyAvailable()) {
            $ret = \false;
            if ($question->isHidden()) {
                try {
                    $hiddenResponse = $this->getHiddenResponse($output, $inputStream, $question->isTrimmable());
                    $ret = $question->isTrimmable() ? \trim($hiddenResponse) : $hiddenResponse;
                } catch (RuntimeException $e) {
                    if (!$question->isHiddenFallback()) {
                        throw $e;
                    }
                }
            }
            if (\false === $ret) {
                $ret = $this->readInput($inputStream, $question);
                if (\false === $ret) {
                    throw new MissingInputException('Aborted.');
                }
                if ($question->isTrimmable()) {
                    $ret = \trim($ret);
                }
            }
        } else {
            $autocomplete = $this->autocomplete($output, $question, $inputStream, $autocomplete);
            $ret = $question->isTrimmable() ? \trim($autocomplete) : $autocomplete;
        }
        if ($output instanceof ConsoleSectionOutput) {
            $output->addContent($ret);
        }
        $ret = \strlen($ret) > 0 ? $ret : $question->getDefault();
        if ($normalizer = $question->getNormalizer()) {
            return $normalizer($ret);
        }
        return $ret;
    }
    /**
     * @return mixed
     */
    private function getDefaultAnswer(Question $question)
    {
        $default = $question->getDefault();
        if (null === $default) {
            return $default;
        }
        if ($validator = $question->getValidator()) {
            return \call_user_func($question->getValidator(), $default);
        } elseif ($question instanceof ChoiceQuestion) {
            $choices = $question->getChoices();
            if (!$question->isMultiselect()) {
                return $choices[$default] ?? $default;
            }
            $default = \explode(',', $default);
            foreach ($default as $k => $v) {
                $v = $question->isTrimmable() ? \trim($v) : $v;
                $default[$k] = $choices[$v] ?? $v;
            }
        }
        return $default;
    }
    /**
     * Outputs the question prompt.
     */
    protected function writePrompt(OutputInterface $output, Question $question)
    {
        $message = $question->getQuestion();
        if ($question instanceof ChoiceQuestion) {
            $output->writeln(\array_merge([$question->getQuestion()], $this->formatChoiceQuestionChoices($question, 'info')));
            $message = $question->getPrompt();
        }
        $output->write($message);
    }
    /**
     * @return string[]
     */
    protected function formatChoiceQuestionChoices(ChoiceQuestion $question, string $tag)
    {
        $messages = [];
        $maxWidth = \max(\array_map([__CLASS__, 'width'], \array_keys($choices = $question->getChoices())));
        foreach ($choices as $key => $value) {
            $padding = \str_repeat(' ', $maxWidth - self::width($key));
            $messages[] = \sprintf("  [<{$tag}>%s{$padding}</{$tag}>] %s", $key, $value);
        }
        return $messages;
    }
    /**
     * Outputs an error message.
     */
    protected function writeError(OutputInterface $output, \Exception $error)
    {
        if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) {
            $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error');
        } else {
            $message = '<error>' . $error->getMessage() . '</error>';
        }
        $output->writeln($message);
    }
    /**
     * Autocompletes a question.
     *
     * @param resource $inputStream
     */
    private function autocomplete(OutputInterface $output, Question $question, $inputStream, callable $autocomplete) : string
    {
        $cursor = new Cursor($output, $inputStream);
        $fullChoice = '';
        $ret = '';
        $i = 0;
        $ofs = -1;
        $matches = $autocomplete($ret);
        $numMatches = \count($matches);
        $sttyMode = \shell_exec('stty -g');
        $isStdin = 'php://stdin' === (\stream_get_meta_data($inputStream)['uri'] ?? null);
        $r = [$inputStream];
        $w = [];
        // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead)
        \shell_exec('stty -icanon -echo');
        // Add highlighted text style
        $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white'));
        // Read a keypress
        while (!\feof($inputStream)) {
            while ($isStdin && 0 === @\stream_select($r, $w, $w, 0, 100)) {
                // Give signal handlers a chance to run
                $r = [$inputStream];
            }
            $c = \fread($inputStream, 1);
            // as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
            if (\false === $c || '' === $ret && '' === $c && null === $question->getDefault()) {
                \shell_exec('stty ' . $sttyMode);
                throw new MissingInputException('Aborted.');
            } elseif ("" === $c) {
                // Backspace Character
                if (0 === $numMatches && 0 !== $i) {
                    --$i;
                    $cursor->moveLeft(s($fullChoice)->slice(-1)->width(\false));
                    $fullChoice = self::substr($fullChoice, 0, $i);
                }
                if (0 === $i) {
                    $ofs = -1;
                    $matches = $autocomplete($ret);
                    $numMatches = \count($matches);
                } else {
                    $numMatches = 0;
                }
                // Pop the last character off the end of our string
                $ret = self::substr($ret, 0, $i);
            } elseif ("\x1b" === $c) {
                // Did we read an escape sequence?
                $c .= \fread($inputStream, 2);
                // A = Up Arrow. B = Down Arrow
                if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {
                    if ('A' === $c[2] && -1 === $ofs) {
                        $ofs = 0;
                    }
                    if (0 === $numMatches) {
                        continue;
                    }
                    $ofs += 'A' === $c[2] ? -1 : 1;
                    $ofs = ($numMatches + $ofs) % $numMatches;
                }
            } elseif (\ord($c) < 32) {
                if ("\t" === $c || "\n" === $c) {
                    if ($numMatches > 0 && -1 !== $ofs) {
                        $ret = (string) $matches[$ofs];
                        // Echo out remaining chars for current match
                        $remainingCharacters = \substr($ret, \strlen(\trim($this->mostRecentlyEnteredValue($fullChoice))));
                        $output->write($remainingCharacters);
                        $fullChoice .= $remainingCharacters;
                        $i = \false === ($encoding = \mb_detect_encoding($fullChoice, null, \true)) ? \strlen($fullChoice) : \mb_strlen($fullChoice, $encoding);
                        $matches = \array_filter($autocomplete($ret), function ($match) use($ret) {
                            return '' === $ret || \str_starts_with($match, $ret);
                        });
                        $numMatches = \count($matches);
                        $ofs = -1;
                    }
                    if ("\n" === $c) {
                        $output->write($c);
                        break;
                    }
                    $numMatches = 0;
                }
                continue;
            } else {
                if ("\x80" <= $c) {
                    $c .= \fread($inputStream, ["\xc0" => 1, "\xd0" => 1, "\xe0" => 2, "\xf0" => 3][$c & "\xf0"]);
                }
                $output->write($c);
                $ret .= $c;
                $fullChoice .= $c;
                ++$i;
                $tempRet = $ret;
                if ($question instanceof ChoiceQuestion && $question->isMultiselect()) {
                    $tempRet = $this->mostRecentlyEnteredValue($fullChoice);
                }
                $numMatches = 0;
                $ofs = 0;
                foreach ($autocomplete($ret) as $value) {
                    // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle)
                    if (\str_starts_with($value, $tempRet)) {
                        $matches[$numMatches++] = $value;
                    }
                }
            }
            $cursor->clearLineAfter();
            if ($numMatches > 0 && -1 !== $ofs) {
                $cursor->savePosition();
                // Write highlighted text, complete the partially entered response
                $charactersEntered = \strlen(\trim($this->mostRecentlyEnteredValue($fullChoice)));
                $output->write('<hl>' . OutputFormatter::escapeTrailingBackslash(\substr($matches[$ofs], $charactersEntered)) . '</hl>');
                $cursor->restorePosition();
            }
        }
        // Reset stty so it behaves normally again
        \shell_exec('stty ' . $sttyMode);
        return $fullChoice;
    }
    private function mostRecentlyEnteredValue(string $entered) : string
    {
        // Determine the most recent value that the user entered
        if (!\str_contains($entered, ',')) {
            return $entered;
        }
        $choices = \explode(',', $entered);
        if ('' !== ($lastChoice = \trim($choices[\count($choices) - 1]))) {
            return $lastChoice;
        }
        return $entered;
    }
    /**
     * Gets a hidden response from user.
     *
     * @param resource $inputStream The handler resource
     * @param bool     $trimmable   Is the answer trimmable
     *
     * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden
     */
    private function getHiddenResponse(OutputInterface $output, $inputStream, bool $trimmable = \true) : string
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $exe = __DIR__ . '/../Resources/bin/hiddeninput.exe';
            // handle code running from a phar
            if ('phar:' === \substr(__FILE__, 0, 5)) {
                $tmpExe = \sys_get_temp_dir() . '/hiddeninput.exe';
                \copy($exe, $tmpExe);
                $exe = $tmpExe;
            }
            $sExec = \shell_exec('"' . $exe . '"');
            $value = $trimmable ? \rtrim($sExec) : $sExec;
            $output->writeln('');
            if (isset($tmpExe)) {
                \unlink($tmpExe);
            }
            return $value;
        }
        if (self::$stty && Terminal::hasSttyAvailable()) {
            $sttyMode = \shell_exec('stty -g');
            \shell_exec('stty -echo');
        } elseif ($this->isInteractiveInput($inputStream)) {
            throw new RuntimeException('Unable to hide the response.');
        }
        $value = \fgets($inputStream, 4096);
        if (self::$stty && Terminal::hasSttyAvailable()) {
            \shell_exec('stty ' . $sttyMode);
        }
        if (\false === $value) {
            throw new MissingInputException('Aborted.');
        }
        if ($trimmable) {
            $value = \trim($value);
        }
        $output->writeln('');
        return $value;
    }
    /**
     * Validates an attempt.
     *
     * @param callable $interviewer A callable that will ask for a question and return the result
     *
     * @return mixed The validated response
     *
     * @throws \Exception In case the max number of attempts has been reached and no valid response has been given
     */
    private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question)
    {
        $error = null;
        $attempts = $question->getMaxAttempts();
        while (null === $attempts || $attempts--) {
            if (null !== $error) {
                $this->writeError($output, $error);
            }
            try {
                return $question->getValidator()($interviewer());
            } catch (RuntimeException $e) {
                throw $e;
            } catch (\Exception $error) {
            }
        }
        throw $error;
    }
    private function isInteractiveInput($inputStream) : bool
    {
        if ('php://stdin' !== (\stream_get_meta_data($inputStream)['uri'] ?? null)) {
            return \false;
        }
        if (null !== self::$stdinIsInteractive) {
            return self::$stdinIsInteractive;
        }
        if (\function_exists('stream_isatty')) {
            return self::$stdinIsInteractive = @\stream_isatty(\fopen('php://stdin', 'r'));
        }
        if (\function_exists('posix_isatty')) {
            return self::$stdinIsInteractive = @\posix_isatty(\fopen('php://stdin', 'r'));
        }
        if (!\function_exists('exec')) {
            return self::$stdinIsInteractive = \true;
        }
        \exec('stty 2> /dev/null', $output, $status);
        return self::$stdinIsInteractive = 1 !== $status;
    }
    /**
     * Reads one or more lines of input and returns what is read.
     *
     * @param resource $inputStream The handler resource
     * @param Question $question    The question being asked
     *
     * @return string|false The input received, false in case input could not be read
     */
    private function readInput($inputStream, Question $question)
    {
        if (!$question->isMultiline()) {
            $cp = $this->setIOCodepage();
            $ret = \fgets($inputStream, 4096);
            return $this->resetIOCodepage($cp, $ret);
        }
        $multiLineStreamReader = $this->cloneInputStream($inputStream);
        if (null === $multiLineStreamReader) {
            return \false;
        }
        $ret = '';
        $cp = $this->setIOCodepage();
        while (\false !== ($char = \fgetc($multiLineStreamReader))) {
            if (\PHP_EOL === "{$ret}{$char}") {
                break;
            }
            $ret .= $char;
        }
        return $this->resetIOCodepage($cp, $ret);
    }
    /**
     * Sets console I/O to the host code page.
     *
     * @return int Previous code page in IBM/EBCDIC format
     */
    private function setIOCodepage() : int
    {
        if (\function_exists('sapi_windows_cp_set')) {
            $cp = \sapi_windows_cp_get();
            \sapi_windows_cp_set(\sapi_windows_cp_get('oem'));
            return $cp;
        }
        return 0;
    }
    /**
     * Sets console I/O to the specified code page and converts the user input.
     *
     * @param string|false $input
     *
     * @return string|false
     */
    private function resetIOCodepage(int $cp, $input)
    {
        if (0 !== $cp) {
            \sapi_windows_cp_set($cp);
            if (\false !== $input && '' !== $input) {
                $input = \sapi_windows_cp_conv(\sapi_windows_cp_get('oem'), $cp, $input);
            }
        }
        return $input;
    }
    /**
     * Clones an input stream in order to act on one instance of the same
     * stream without affecting the other instance.
     *
     * @param resource $inputStream The handler resource
     *
     * @return resource|null The cloned resource, null in case it could not be cloned
     */
    private function cloneInputStream($inputStream)
    {
        $streamMetaData = \stream_get_meta_data($inputStream);
        $seekable = $streamMetaData['seekable'] ?? \false;
        $mode = $streamMetaData['mode'] ?? 'rb';
        $uri = $streamMetaData['uri'] ?? null;
        if (null === $uri) {
            return null;
        }
        $cloneStream = \fopen($uri, $mode);
        // For seekable and writable streams, add all the same data to the
        // cloned stream and then seek to the same offset.
        if (\true === $seekable && !\in_array($mode, ['r', 'rb', 'rt'])) {
            $offset = \ftell($inputStream);
            \rewind($inputStream);
            \stream_copy_to_stream($inputStream, $cloneStream);
            \fseek($inputStream, $offset);
            \fseek($cloneStream, $offset);
        }
        return $cloneStream;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
/**
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 */
class TableCell
{
    private $value;
    private $options = ['rowspan' => 1, 'colspan' => 1, 'style' => null];
    public function __construct(string $value = '', array $options = [])
    {
        $this->value = $value;
        // check option names
        if ($diff = \array_diff(\array_keys($options), \array_keys($this->options))) {
            throw new InvalidArgumentException(\sprintf('The TableCell does not support the following options: \'%s\'.', \implode('\', \'', $diff)));
        }
        if (isset($options['style']) && !$options['style'] instanceof TableCellStyle) {
            throw new InvalidArgumentException('The style option must be an instance of "TableCellStyle".');
        }
        $this->options = \array_merge($this->options, $options);
    }
    /**
     * Returns the cell value.
     *
     * @return string
     */
    public function __toString()
    {
        return $this->value;
    }
    /**
     * Gets number of colspan.
     *
     * @return int
     */
    public function getColspan()
    {
        return (int) $this->options['colspan'];
    }
    /**
     * Gets number of rowspan.
     *
     * @return int
     */
    public function getRowspan()
    {
        return (int) $this->options['rowspan'];
    }
    public function getStyle() : ?TableCellStyle
    {
        return $this->options['style'];
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class ProgressIndicator
{
    private const FORMATS = ['normal' => ' %indicator% %message%', 'normal_no_ansi' => ' %message%', 'verbose' => ' %indicator% %message% (%elapsed:6s%)', 'verbose_no_ansi' => ' %message% (%elapsed:6s%)', 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)', 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)'];
    private $output;
    private $startTime;
    private $format;
    private $message;
    private $indicatorValues;
    private $indicatorCurrent;
    private $indicatorChangeInterval;
    private $indicatorUpdateTime;
    private $started = \false;
    /**
     * @var array<string, callable>
     */
    private static $formatters;
    /**
     * @param int        $indicatorChangeInterval Change interval in milliseconds
     * @param array|null $indicatorValues         Animated indicator characters
     */
    public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null)
    {
        $this->output = $output;
        if (null === $format) {
            $format = $this->determineBestFormat();
        }
        if (null === $indicatorValues) {
            $indicatorValues = ['-', '\\', '|', '/'];
        }
        $indicatorValues = \array_values($indicatorValues);
        if (2 > \count($indicatorValues)) {
            throw new InvalidArgumentException('Must have at least 2 indicator value characters.');
        }
        $this->format = self::getFormatDefinition($format);
        $this->indicatorChangeInterval = $indicatorChangeInterval;
        $this->indicatorValues = $indicatorValues;
        $this->startTime = \time();
    }
    /**
     * Sets the current indicator message.
     */
    public function setMessage(?string $message)
    {
        $this->message = $message;
        $this->display();
    }
    /**
     * Starts the indicator output.
     */
    public function start(string $message)
    {
        if ($this->started) {
            throw new LogicException('Progress indicator already started.');
        }
        $this->message = $message;
        $this->started = \true;
        $this->startTime = \time();
        $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval;
        $this->indicatorCurrent = 0;
        $this->display();
    }
    /**
     * Advances the indicator.
     */
    public function advance()
    {
        if (!$this->started) {
            throw new LogicException('Progress indicator has not yet been started.');
        }
        if (!$this->output->isDecorated()) {
            return;
        }
        $currentTime = $this->getCurrentTimeInMilliseconds();
        if ($currentTime < $this->indicatorUpdateTime) {
            return;
        }
        $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval;
        ++$this->indicatorCurrent;
        $this->display();
    }
    /**
     * Finish the indicator with message.
     *
     * @param $message
     */
    public function finish(string $message)
    {
        if (!$this->started) {
            throw new LogicException('Progress indicator has not yet been started.');
        }
        $this->message = $message;
        $this->display();
        $this->output->writeln('');
        $this->started = \false;
    }
    /**
     * Gets the format for a given name.
     *
     * @return string|null
     */
    public static function getFormatDefinition(string $name)
    {
        return self::FORMATS[$name] ?? null;
    }
    /**
     * Sets a placeholder formatter for a given name.
     *
     * This method also allow you to override an existing placeholder.
     */
    public static function setPlaceholderFormatterDefinition(string $name, callable $callable)
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }
        self::$formatters[$name] = $callable;
    }
    /**
     * Gets the placeholder formatter for a given name (including the delimiter char like %).
     *
     * @return callable|null
     */
    public static function getPlaceholderFormatterDefinition(string $name)
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }
        return self::$formatters[$name] ?? null;
    }
    private function display()
    {
        if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
            return;
        }
        $this->overwrite(\preg_replace_callback("{%([a-z\\-_]+)(?:\\:([^%]+))?%}i", function ($matches) {
            if ($formatter = self::getPlaceholderFormatterDefinition($matches[1])) {
                return $formatter($this);
            }
            return $matches[0];
        }, $this->format ?? ''));
    }
    private function determineBestFormat() : string
    {
        switch ($this->output->getVerbosity()) {
            // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
            case OutputInterface::VERBOSITY_VERBOSE:
                return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi';
            case OutputInterface::VERBOSITY_VERY_VERBOSE:
            case OutputInterface::VERBOSITY_DEBUG:
                return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi';
            default:
                return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi';
        }
    }
    /**
     * Overwrites a previous message to the output.
     */
    private function overwrite(string $message)
    {
        if ($this->output->isDecorated()) {
            $this->output->write("\r\x1b[2K");
            $this->output->write($message);
        } else {
            $this->output->writeln($message);
        }
    }
    private function getCurrentTimeInMilliseconds() : float
    {
        return \round(\microtime(\true) * 1000);
    }
    private static function initPlaceholderFormatters() : array
    {
        return ['indicator' => function (self $indicator) {
            return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)];
        }, 'message' => function (self $indicator) {
            return $indicator->message;
        }, 'elapsed' => function (self $indicator) {
            return Helper::formatTime(\time() - $indicator->startTime);
        }, 'memory' => function () {
            return Helper::formatMemory(\memory_get_usage(\true));
        }];
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
/**
 * The Formatter class provides helpers to format messages.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class FormatterHelper extends Helper
{
    /**
     * Formats a message within a section.
     *
     * @return string
     */
    public function formatSection(string $section, string $message, string $style = 'info')
    {
        return \sprintf('<%s>[%s]</%s> %s', $style, $section, $style, $message);
    }
    /**
     * Formats a message as a block of text.
     *
     * @param string|array $messages The message to write in the block
     *
     * @return string
     */
    public function formatBlock($messages, string $style, bool $large = \false)
    {
        if (!\is_array($messages)) {
            $messages = [$messages];
        }
        $len = 0;
        $lines = [];
        foreach ($messages as $message) {
            $message = OutputFormatter::escape($message);
            $lines[] = \sprintf($large ? '  %s  ' : ' %s ', $message);
            $len = \max(self::width($message) + ($large ? 4 : 2), $len);
        }
        $messages = $large ? [\str_repeat(' ', $len)] : [];
        for ($i = 0; isset($lines[$i]); ++$i) {
            $messages[] = $lines[$i] . \str_repeat(' ', $len - self::width($lines[$i]));
        }
        if ($large) {
            $messages[] = \str_repeat(' ', $len);
        }
        for ($i = 0; isset($messages[$i]); ++$i) {
            $messages[$i] = \sprintf('<%s>%s</%s>', $style, $messages[$i], $style);
        }
        return \implode("\n", $messages);
    }
    /**
     * Truncates a message to the given length.
     *
     * @return string
     */
    public function truncate(string $message, int $length, string $suffix = '...')
    {
        $computedLength = $length - self::width($suffix);
        if ($computedLength > self::width($message)) {
            return $message;
        }
        return self::substr($message, 0, $length) . $suffix;
    }
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'formatter';
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
/**
 * Defines the styles for a Table.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Саша Стаменковић <umpirsky@gmail.com>
 * @author Dany Maillard <danymaillard93b@gmail.com>
 */
class TableStyle
{
    private $paddingChar = ' ';
    private $horizontalOutsideBorderChar = '-';
    private $horizontalInsideBorderChar = '-';
    private $verticalOutsideBorderChar = '|';
    private $verticalInsideBorderChar = '|';
    private $crossingChar = '+';
    private $crossingTopRightChar = '+';
    private $crossingTopMidChar = '+';
    private $crossingTopLeftChar = '+';
    private $crossingMidRightChar = '+';
    private $crossingBottomRightChar = '+';
    private $crossingBottomMidChar = '+';
    private $crossingBottomLeftChar = '+';
    private $crossingMidLeftChar = '+';
    private $crossingTopLeftBottomChar = '+';
    private $crossingTopMidBottomChar = '+';
    private $crossingTopRightBottomChar = '+';
    private $headerTitleFormat = '<fg=black;bg=white;options=bold> %s </>';
    private $footerTitleFormat = '<fg=black;bg=white;options=bold> %s </>';
    private $cellHeaderFormat = '<info>%s</info>';
    private $cellRowFormat = '%s';
    private $cellRowContentFormat = ' %s ';
    private $borderFormat = '%s';
    private $padType = \STR_PAD_RIGHT;
    /**
     * Sets padding character, used for cell padding.
     *
     * @return $this
     */
    public function setPaddingChar(string $paddingChar)
    {
        if (!$paddingChar) {
            throw new LogicException('The padding char must not be empty.');
        }
        $this->paddingChar = $paddingChar;
        return $this;
    }
    /**
     * Gets padding character, used for cell padding.
     *
     * @return string
     */
    public function getPaddingChar()
    {
        return $this->paddingChar;
    }
    /**
     * Sets horizontal border characters.
     *
     * <code>
     * ╔═══════════════╤══════════════════════════╤══════════════════╗
     * 1 ISBN          2 Title                    │ Author           ║
     * ╠═══════════════╪══════════════════════════╪══════════════════╣
     * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║
     * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║
     * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║
     * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║
     * ╚═══════════════╧══════════════════════════╧══════════════════╝
     * </code>
     *
     * @return $this
     */
    public function setHorizontalBorderChars(string $outside, string $inside = null) : self
    {
        $this->horizontalOutsideBorderChar = $outside;
        $this->horizontalInsideBorderChar = $inside ?? $outside;
        return $this;
    }
    /**
     * Sets vertical border characters.
     *
     * <code>
     * ╔═══════════════╤══════════════════════════╤══════════════════╗
     * ║ ISBN          │ Title                    │ Author           ║
     * ╠═══════1═══════╪══════════════════════════╪══════════════════╣
     * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║
     * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║
     * ╟───────2───────┼──────────────────────────┼──────────────────╢
     * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║
     * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║
     * ╚═══════════════╧══════════════════════════╧══════════════════╝
     * </code>
     *
     * @return $this
     */
    public function setVerticalBorderChars(string $outside, string $inside = null) : self
    {
        $this->verticalOutsideBorderChar = $outside;
        $this->verticalInsideBorderChar = $inside ?? $outside;
        return $this;
    }
    /**
     * Gets border characters.
     *
     * @internal
     */
    public function getBorderChars() : array
    {
        return [$this->horizontalOutsideBorderChar, $this->verticalOutsideBorderChar, $this->horizontalInsideBorderChar, $this->verticalInsideBorderChar];
    }
    /**
     * Sets crossing characters.
     *
     * Example:
     * <code>
     * 1═══════════════2══════════════════════════2══════════════════3
     * ║ ISBN          │ Title                    │ Author           ║
     * 8'══════════════0'═════════════════════════0'═════════════════4'
     * ║ 99921-58-10-7 │ Divine Comedy            │ Dante Alighieri  ║
     * ║ 9971-5-0210-0 │ A Tale of Two Cities     │ Charles Dickens  ║
     * 8───────────────0──────────────────────────0──────────────────4
     * ║ 960-425-059-0 │ The Lord of the Rings    │ J. R. R. Tolkien ║
     * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie  ║
     * 7═══════════════6══════════════════════════6══════════════════5
     * </code>
     *
     * @param string      $cross          Crossing char (see #0 of example)
     * @param string      $topLeft        Top left char (see #1 of example)
     * @param string      $topMid         Top mid char (see #2 of example)
     * @param string      $topRight       Top right char (see #3 of example)
     * @param string      $midRight       Mid right char (see #4 of example)
     * @param string      $bottomRight    Bottom right char (see #5 of example)
     * @param string      $bottomMid      Bottom mid char (see #6 of example)
     * @param string      $bottomLeft     Bottom left char (see #7 of example)
     * @param string      $midLeft        Mid left char (see #8 of example)
     * @param string|null $topLeftBottom  Top left bottom char (see #8' of example), equals to $midLeft if null
     * @param string|null $topMidBottom   Top mid bottom char (see #0' of example), equals to $cross if null
     * @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null
     *
     * @return $this
     */
    public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null) : self
    {
        $this->crossingChar = $cross;
        $this->crossingTopLeftChar = $topLeft;
        $this->crossingTopMidChar = $topMid;
        $this->crossingTopRightChar = $topRight;
        $this->crossingMidRightChar = $midRight;
        $this->crossingBottomRightChar = $bottomRight;
        $this->crossingBottomMidChar = $bottomMid;
        $this->crossingBottomLeftChar = $bottomLeft;
        $this->crossingMidLeftChar = $midLeft;
        $this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft;
        $this->crossingTopMidBottomChar = $topMidBottom ?? $cross;
        $this->crossingTopRightBottomChar = $topRightBottom ?? $midRight;
        return $this;
    }
    /**
     * Sets default crossing character used for each cross.
     *
     * @see {@link setCrossingChars()} for setting each crossing individually.
     */
    public function setDefaultCrossingChar(string $char) : self
    {
        return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char);
    }
    /**
     * Gets crossing character.
     *
     * @return string
     */
    public function getCrossingChar()
    {
        return $this->crossingChar;
    }
    /**
     * Gets crossing characters.
     *
     * @internal
     */
    public function getCrossingChars() : array
    {
        return [$this->crossingChar, $this->crossingTopLeftChar, $this->crossingTopMidChar, $this->crossingTopRightChar, $this->crossingMidRightChar, $this->crossingBottomRightChar, $this->crossingBottomMidChar, $this->crossingBottomLeftChar, $this->crossingMidLeftChar, $this->crossingTopLeftBottomChar, $this->crossingTopMidBottomChar, $this->crossingTopRightBottomChar];
    }
    /**
     * Sets header cell format.
     *
     * @return $this
     */
    public function setCellHeaderFormat(string $cellHeaderFormat)
    {
        $this->cellHeaderFormat = $cellHeaderFormat;
        return $this;
    }
    /**
     * Gets header cell format.
     *
     * @return string
     */
    public function getCellHeaderFormat()
    {
        return $this->cellHeaderFormat;
    }
    /**
     * Sets row cell format.
     *
     * @return $this
     */
    public function setCellRowFormat(string $cellRowFormat)
    {
        $this->cellRowFormat = $cellRowFormat;
        return $this;
    }
    /**
     * Gets row cell format.
     *
     * @return string
     */
    public function getCellRowFormat()
    {
        return $this->cellRowFormat;
    }
    /**
     * Sets row cell content format.
     *
     * @return $this
     */
    public function setCellRowContentFormat(string $cellRowContentFormat)
    {
        $this->cellRowContentFormat = $cellRowContentFormat;
        return $this;
    }
    /**
     * Gets row cell content format.
     *
     * @return string
     */
    public function getCellRowContentFormat()
    {
        return $this->cellRowContentFormat;
    }
    /**
     * Sets table border format.
     *
     * @return $this
     */
    public function setBorderFormat(string $borderFormat)
    {
        $this->borderFormat = $borderFormat;
        return $this;
    }
    /**
     * Gets table border format.
     *
     * @return string
     */
    public function getBorderFormat()
    {
        return $this->borderFormat;
    }
    /**
     * Sets cell padding type.
     *
     * @return $this
     */
    public function setPadType(int $padType)
    {
        if (!\in_array($padType, [\STR_PAD_LEFT, \STR_PAD_RIGHT, \STR_PAD_BOTH], \true)) {
            throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).');
        }
        $this->padType = $padType;
        return $this;
    }
    /**
     * Gets cell padding type.
     *
     * @return int
     */
    public function getPadType()
    {
        return $this->padType;
    }
    public function getHeaderTitleFormat() : string
    {
        return $this->headerTitleFormat;
    }
    /**
     * @return $this
     */
    public function setHeaderTitleFormat(string $format) : self
    {
        $this->headerTitleFormat = $format;
        return $this;
    }
    public function getFooterTitleFormat() : string
    {
        return $this->footerTitleFormat;
    }
    /**
     * @return $this
     */
    public function setFooterTitleFormat(string $format) : self
    {
        $this->footerTitleFormat = $format;
        return $this;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor\DescriptorInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor\JsonDescriptor;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor\MarkdownDescriptor;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor\TextDescriptor;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor\XmlDescriptor;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * This class adds helper method to describe objects in various formats.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class DescriptorHelper extends Helper
{
    /**
     * @var DescriptorInterface[]
     */
    private $descriptors = [];
    public function __construct()
    {
        $this->register('txt', new TextDescriptor())->register('xml', new XmlDescriptor())->register('json', new JsonDescriptor())->register('md', new MarkdownDescriptor());
    }
    /**
     * Describes an object if supported.
     *
     * Available options are:
     * * format: string, the output format name
     * * raw_text: boolean, sets output type as raw
     *
     * @throws InvalidArgumentException when the given format is not supported
     */
    public function describe(OutputInterface $output, ?object $object, array $options = [])
    {
        $options = \array_merge(['raw_text' => \false, 'format' => 'txt'], $options);
        if (!isset($this->descriptors[$options['format']])) {
            throw new InvalidArgumentException(\sprintf('Unsupported format "%s".', $options['format']));
        }
        $descriptor = $this->descriptors[$options['format']];
        $descriptor->describe($output, $object, $options);
    }
    /**
     * Registers a descriptor.
     *
     * @return $this
     */
    public function register(string $format, DescriptorInterface $descriptor)
    {
        $this->descriptors[$format] = $descriptor;
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'descriptor';
    }
    public function getFormats() : array
    {
        return \array_keys($this->descriptors);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\ChoiceQuestion;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\ConfirmationQuestion;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Question\Question;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style\SymfonyStyle;
/**
 * Symfony Style Guide compliant question helper.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
class SymfonyQuestionHelper extends QuestionHelper
{
    /**
     * {@inheritdoc}
     */
    protected function writePrompt(OutputInterface $output, Question $question)
    {
        $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion());
        $default = $question->getDefault();
        if ($question->isMultiline()) {
            $text .= \sprintf(' (press %s to continue)', $this->getEofShortcut());
        }
        switch (\true) {
            case null === $default:
                $text = \sprintf(' <info>%s</info>:', $text);
                break;
            case $question instanceof ConfirmationQuestion:
                $text = \sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no');
                break;
            case $question instanceof ChoiceQuestion && $question->isMultiselect():
                $choices = $question->getChoices();
                $default = \explode(',', $default);
                foreach ($default as $key => $value) {
                    $default[$key] = $choices[\trim($value)];
                }
                $text = \sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape(\implode(', ', $default)));
                break;
            case $question instanceof ChoiceQuestion:
                $choices = $question->getChoices();
                $text = \sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($choices[$default] ?? $default));
                break;
            default:
                $text = \sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, OutputFormatter::escape($default));
        }
        $output->writeln($text);
        $prompt = ' > ';
        if ($question instanceof ChoiceQuestion) {
            $output->writeln($this->formatChoiceQuestionChoices($question, 'comment'));
            $prompt = $question->getPrompt();
        }
        $output->write($prompt);
    }
    /**
     * {@inheritdoc}
     */
    protected function writeError(OutputInterface $output, \Exception $error)
    {
        if ($output instanceof SymfonyStyle) {
            $output->newLine();
            $output->error($error->getMessage());
            return;
        }
        parent::writeError($output, $error);
    }
    private function getEofShortcut() : string
    {
        if ('Windows' === \PHP_OS_FAMILY) {
            return '<comment>Ctrl+Z</comment> then <comment>Enter</comment>';
        }
        return '<comment>Ctrl+D</comment>';
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
/**
 * @author Yewhen Khoptynskyi <khoptynskyi@gmail.com>
 */
class TableCellStyle
{
    public const DEFAULT_ALIGN = 'left';
    private const TAG_OPTIONS = ['fg', 'bg', 'options'];
    private const ALIGN_MAP = ['left' => \STR_PAD_RIGHT, 'center' => \STR_PAD_BOTH, 'right' => \STR_PAD_LEFT];
    private $options = ['fg' => 'default', 'bg' => 'default', 'options' => null, 'align' => self::DEFAULT_ALIGN, 'cellFormat' => null];
    public function __construct(array $options = [])
    {
        if ($diff = \array_diff(\array_keys($options), \array_keys($this->options))) {
            throw new InvalidArgumentException(\sprintf('The TableCellStyle does not support the following options: \'%s\'.', \implode('\', \'', $diff)));
        }
        if (isset($options['align']) && !\array_key_exists($options['align'], self::ALIGN_MAP)) {
            throw new InvalidArgumentException(\sprintf('Wrong align value. Value must be following: \'%s\'.', \implode('\', \'', \array_keys(self::ALIGN_MAP))));
        }
        $this->options = \array_merge($this->options, $options);
    }
    public function getOptions() : array
    {
        return $this->options;
    }
    /**
     * Gets options we need for tag for example fg, bg.
     *
     * @return string[]
     */
    public function getTagOptions()
    {
        return \array_filter($this->getOptions(), function ($key) {
            return \in_array($key, self::TAG_OPTIONS) && isset($this->options[$key]);
        }, \ARRAY_FILTER_USE_KEY);
    }
    /**
     * @return int
     */
    public function getPadByAlign()
    {
        return self::ALIGN_MAP[$this->getOptions()['align']];
    }
    public function getCellFormat() : ?string
    {
        return $this->getOptions()['cellFormat'];
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
/**
 * HelperSet represents a set of helpers to be used with a command.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @implements \IteratorAggregate<string, Helper>
 */
class HelperSet implements \IteratorAggregate
{
    /** @var array<string, Helper> */
    private $helpers = [];
    private $command;
    /**
     * @param Helper[] $helpers An array of helper
     */
    public function __construct(array $helpers = [])
    {
        foreach ($helpers as $alias => $helper) {
            $this->set($helper, \is_int($alias) ? null : $alias);
        }
    }
    public function set(HelperInterface $helper, string $alias = null)
    {
        $this->helpers[$helper->getName()] = $helper;
        if (null !== $alias) {
            $this->helpers[$alias] = $helper;
        }
        $helper->setHelperSet($this);
    }
    /**
     * Returns true if the helper if defined.
     *
     * @return bool
     */
    public function has(string $name)
    {
        return isset($this->helpers[$name]);
    }
    /**
     * Gets a helper value.
     *
     * @return HelperInterface
     *
     * @throws InvalidArgumentException if the helper is not defined
     */
    public function get(string $name)
    {
        if (!$this->has($name)) {
            throw new InvalidArgumentException(\sprintf('The helper "%s" is not defined.', $name));
        }
        return $this->helpers[$name];
    }
    /**
     * @deprecated since Symfony 5.4
     */
    public function setCommand(Command $command = null)
    {
        trigger_deprecation('symfony/console', '5.4', 'Method "%s()" is deprecated.', __METHOD__);
        $this->command = $command;
    }
    /**
     * Gets the command associated with this helper set.
     *
     * @return Command
     *
     * @deprecated since Symfony 5.4
     */
    public function getCommand()
    {
        trigger_deprecation('symfony/console', '5.4', 'Method "%s()" is deprecated.', __METHOD__);
        return $this->command;
    }
    /**
     * @return \Traversable<string, Helper>
     */
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new \ArrayIterator($this->helpers);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

/**
 * Marks a row as being a separator.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class TableSeparator extends TableCell
{
    public function __construct(array $options = [])
    {
        parent::__construct('', $options);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

/**
 * Helps outputting debug information when running an external program from a command.
 *
 * An external program can be a Process, an HTTP request, or anything else.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class DebugFormatterHelper extends Helper
{
    private const COLORS = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default'];
    private $started = [];
    private $count = -1;
    /**
     * Starts a debug formatting session.
     *
     * @return string
     */
    public function start(string $id, string $message, string $prefix = 'RUN')
    {
        $this->started[$id] = ['border' => ++$this->count % \count(self::COLORS)];
        return \sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
    }
    /**
     * Adds progress to a formatting session.
     *
     * @return string
     */
    public function progress(string $id, string $buffer, bool $error = \false, string $prefix = 'OUT', string $errorPrefix = 'ERR')
    {
        $message = '';
        if ($error) {
            if (isset($this->started[$id]['out'])) {
                $message .= "\n";
                unset($this->started[$id]['out']);
            }
            if (!isset($this->started[$id]['err'])) {
                $message .= \sprintf('%s<bg=red;fg=white> %s </> ', $this->getBorder($id), $errorPrefix);
                $this->started[$id]['err'] = \true;
            }
            $message .= \str_replace("\n", \sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
        } else {
            if (isset($this->started[$id]['err'])) {
                $message .= "\n";
                unset($this->started[$id]['err']);
            }
            if (!isset($this->started[$id]['out'])) {
                $message .= \sprintf('%s<bg=green;fg=white> %s </> ', $this->getBorder($id), $prefix);
                $this->started[$id]['out'] = \true;
            }
            $message .= \str_replace("\n", \sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
        }
        return $message;
    }
    /**
     * Stops a formatting session.
     *
     * @return string
     */
    public function stop(string $id, string $message, bool $successful, string $prefix = 'RES')
    {
        $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
        if ($successful) {
            return \sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
        }
        $message = \sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
        unset($this->started[$id]['out'], $this->started[$id]['err']);
        return $message;
    }
    private function getBorder(string $id) : string
    {
        return \sprintf('<bg=%s> </>', self::COLORS[$this->started[$id]['border']]);
    }
    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'debug_formatter';
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

/**
 * HelperInterface is the interface all helpers must implement.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface HelperInterface
{
    /**
     * Sets the helper set associated with this helper.
     */
    public function setHelperSet(HelperSet $helperSet = null);
    /**
     * Gets the helper set associated with this helper.
     *
     * @return HelperSet|null
     */
    public function getHelperSet();
    /**
     * Returns the canonical name of this helper.
     *
     * @return string
     */
    public function getName();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Process\Exception\ProcessFailedException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Process\Process;
/**
 * The ProcessHelper class provides helpers to run external processes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 *
 * @final
 */
class ProcessHelper extends Helper
{
    /**
     * Runs an external process.
     *
     * @param array|Process $cmd      An instance of Process or an array of the command and arguments
     * @param callable|null $callback A PHP callback to run whenever there is some
     *                                output available on STDOUT or STDERR
     */
    public function run(OutputInterface $output, $cmd, string $error = null, callable $callback = null, int $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) : Process
    {
        if (!\class_exists(Process::class)) {
            throw new \LogicException('The ProcessHelper cannot be run as the Process component is not installed. Try running "compose require symfony/process".');
        }
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }
        $formatter = $this->getHelperSet()->get('debug_formatter');
        if ($cmd instanceof Process) {
            $cmd = [$cmd];
        }
        if (!\is_array($cmd)) {
            throw new \TypeError(\sprintf('The "command" argument of "%s()" must be an array or a "%s" instance, "%s" given.', __METHOD__, Process::class, \get_debug_type($cmd)));
        }
        if (\is_string($cmd[0] ?? null)) {
            $process = new Process($cmd);
            $cmd = [];
        } elseif (($cmd[0] ?? null) instanceof Process) {
            $process = $cmd[0];
            unset($cmd[0]);
        } else {
            throw new \InvalidArgumentException(\sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__));
        }
        if ($verbosity <= $output->getVerbosity()) {
            $output->write($formatter->start(\spl_object_hash($process), $this->escapeString($process->getCommandLine())));
        }
        if ($output->isDebug()) {
            $callback = $this->wrapCallback($output, $process, $callback);
        }
        $process->run($callback, $cmd);
        if ($verbosity <= $output->getVerbosity()) {
            $message = $process->isSuccessful() ? 'Command ran successfully' : \sprintf('%s Command did not run successfully', $process->getExitCode());
            $output->write($formatter->stop(\spl_object_hash($process), $message, $process->isSuccessful()));
        }
        if (!$process->isSuccessful() && null !== $error) {
            $output->writeln(\sprintf('<error>%s</error>', $this->escapeString($error)));
        }
        return $process;
    }
    /**
     * Runs the process.
     *
     * This is identical to run() except that an exception is thrown if the process
     * exits with a non-zero exit code.
     *
     * @param array|Process $cmd      An instance of Process or a command to run
     * @param callable|null $callback A PHP callback to run whenever there is some
     *                                output available on STDOUT or STDERR
     *
     * @throws ProcessFailedException
     *
     * @see run()
     */
    public function mustRun(OutputInterface $output, $cmd, string $error = null, callable $callback = null) : Process
    {
        $process = $this->run($output, $cmd, $error, $callback);
        if (!$process->isSuccessful()) {
            throw new ProcessFailedException($process);
        }
        return $process;
    }
    /**
     * Wraps a Process callback to add debugging output.
     */
    public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null) : callable
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }
        $formatter = $this->getHelperSet()->get('debug_formatter');
        return function ($type, $buffer) use($output, $process, $callback, $formatter) {
            $output->write($formatter->progress(\spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type));
            if (null !== $callback) {
                $callback($type, $buffer);
            }
        };
    }
    private function escapeString(string $str) : string
    {
        return \str_replace('<', '\\<', $str);
    }
    /**
     * {@inheritdoc}
     */
    public function getName() : string
    {
        return 'process';
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\RuntimeException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleSectionOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Provides helpers to display a table.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Саша Стаменковић <umpirsky@gmail.com>
 * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
 * @author Max Grigorian <maxakawizard@gmail.com>
 * @author Dany Maillard <danymaillard93b@gmail.com>
 */
class Table
{
    private const SEPARATOR_TOP = 0;
    private const SEPARATOR_TOP_BOTTOM = 1;
    private const SEPARATOR_MID = 2;
    private const SEPARATOR_BOTTOM = 3;
    private const BORDER_OUTSIDE = 0;
    private const BORDER_INSIDE = 1;
    private $headerTitle;
    private $footerTitle;
    /**
     * Table headers.
     */
    private $headers = [];
    /**
     * Table rows.
     */
    private $rows = [];
    private $horizontal = \false;
    /**
     * Column widths cache.
     */
    private $effectiveColumnWidths = [];
    /**
     * Number of columns cache.
     *
     * @var int
     */
    private $numberOfColumns;
    /**
     * @var OutputInterface
     */
    private $output;
    /**
     * @var TableStyle
     */
    private $style;
    /**
     * @var array
     */
    private $columnStyles = [];
    /**
     * User set column widths.
     *
     * @var array
     */
    private $columnWidths = [];
    private $columnMaxWidths = [];
    /**
     * @var array<string, TableStyle>|null
     */
    private static $styles;
    private $rendered = \false;
    public function __construct(OutputInterface $output)
    {
        $this->output = $output;
        if (!self::$styles) {
            self::$styles = self::initStyles();
        }
        $this->setStyle('default');
    }
    /**
     * Sets a style definition.
     */
    public static function setStyleDefinition(string $name, TableStyle $style)
    {
        if (!self::$styles) {
            self::$styles = self::initStyles();
        }
        self::$styles[$name] = $style;
    }
    /**
     * Gets a style definition by name.
     *
     * @return TableStyle
     */
    public static function getStyleDefinition(string $name)
    {
        if (!self::$styles) {
            self::$styles = self::initStyles();
        }
        if (isset(self::$styles[$name])) {
            return self::$styles[$name];
        }
        throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name));
    }
    /**
     * Sets table style.
     *
     * @param TableStyle|string $name The style name or a TableStyle instance
     *
     * @return $this
     */
    public function setStyle($name)
    {
        $this->style = $this->resolveStyle($name);
        return $this;
    }
    /**
     * Gets the current table style.
     *
     * @return TableStyle
     */
    public function getStyle()
    {
        return $this->style;
    }
    /**
     * Sets table column style.
     *
     * @param TableStyle|string $name The style name or a TableStyle instance
     *
     * @return $this
     */
    public function setColumnStyle(int $columnIndex, $name)
    {
        $this->columnStyles[$columnIndex] = $this->resolveStyle($name);
        return $this;
    }
    /**
     * Gets the current style for a column.
     *
     * If style was not set, it returns the global table style.
     *
     * @return TableStyle
     */
    public function getColumnStyle(int $columnIndex)
    {
        return $this->columnStyles[$columnIndex] ?? $this->getStyle();
    }
    /**
     * Sets the minimum width of a column.
     *
     * @return $this
     */
    public function setColumnWidth(int $columnIndex, int $width)
    {
        $this->columnWidths[$columnIndex] = $width;
        return $this;
    }
    /**
     * Sets the minimum width of all columns.
     *
     * @return $this
     */
    public function setColumnWidths(array $widths)
    {
        $this->columnWidths = [];
        foreach ($widths as $index => $width) {
            $this->setColumnWidth($index, $width);
        }
        return $this;
    }
    /**
     * Sets the maximum width of a column.
     *
     * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while
     * formatted strings are preserved.
     *
     * @return $this
     */
    public function setColumnMaxWidth(int $columnIndex, int $width) : self
    {
        if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) {
            throw new \LogicException(\sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, \get_debug_type($this->output->getFormatter())));
        }
        $this->columnMaxWidths[$columnIndex] = $width;
        return $this;
    }
    /**
     * @return $this
     */
    public function setHeaders(array $headers)
    {
        $headers = \array_values($headers);
        if (!empty($headers) && !\is_array($headers[0])) {
            $headers = [$headers];
        }
        $this->headers = $headers;
        return $this;
    }
    public function setRows(array $rows)
    {
        $this->rows = [];
        return $this->addRows($rows);
    }
    /**
     * @return $this
     */
    public function addRows(array $rows)
    {
        foreach ($rows as $row) {
            $this->addRow($row);
        }
        return $this;
    }
    /**
     * @return $this
     */
    public function addRow($row)
    {
        if ($row instanceof TableSeparator) {
            $this->rows[] = $row;
            return $this;
        }
        if (!\is_array($row)) {
            throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.');
        }
        $this->rows[] = \array_values($row);
        return $this;
    }
    /**
     * Adds a row to the table, and re-renders the table.
     *
     * @return $this
     */
    public function appendRow($row) : self
    {
        if (!$this->output instanceof ConsoleSectionOutput) {
            throw new RuntimeException(\sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__));
        }
        if ($this->rendered) {
            $this->output->clear($this->calculateRowCount());
        }
        $this->addRow($row);
        $this->render();
        return $this;
    }
    /**
     * @return $this
     */
    public function setRow($column, array $row)
    {
        $this->rows[$column] = $row;
        return $this;
    }
    /**
     * @return $this
     */
    public function setHeaderTitle(?string $title) : self
    {
        $this->headerTitle = $title;
        return $this;
    }
    /**
     * @return $this
     */
    public function setFooterTitle(?string $title) : self
    {
        $this->footerTitle = $title;
        return $this;
    }
    /**
     * @return $this
     */
    public function setHorizontal(bool $horizontal = \true) : self
    {
        $this->horizontal = $horizontal;
        return $this;
    }
    /**
     * Renders table to output.
     *
     * Example:
     *
     *     +---------------+-----------------------+------------------+
     *     | ISBN          | Title                 | Author           |
     *     +---------------+-----------------------+------------------+
     *     | 99921-58-10-7 | Divine Comedy         | Dante Alighieri  |
     *     | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  |
     *     | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
     *     +---------------+-----------------------+------------------+
     */
    public function render()
    {
        $divider = new TableSeparator();
        if ($this->horizontal) {
            $rows = [];
            foreach ($this->headers[0] ?? [] as $i => $header) {
                $rows[$i] = [$header];
                foreach ($this->rows as $row) {
                    if ($row instanceof TableSeparator) {
                        continue;
                    }
                    if (isset($row[$i])) {
                        $rows[$i][] = $row[$i];
                    } elseif ($rows[$i][0] instanceof TableCell && $rows[$i][0]->getColspan() >= 2) {
                        // Noop, there is a "title"
                    } else {
                        $rows[$i][] = null;
                    }
                }
            }
        } else {
            $rows = \array_merge($this->headers, [$divider], $this->rows);
        }
        $this->calculateNumberOfColumns($rows);
        $rowGroups = $this->buildTableRows($rows);
        $this->calculateColumnsWidth($rowGroups);
        $isHeader = !$this->horizontal;
        $isFirstRow = $this->horizontal;
        $hasTitle = (bool) $this->headerTitle;
        foreach ($rowGroups as $rowGroup) {
            $isHeaderSeparatorRendered = \false;
            foreach ($rowGroup as $row) {
                if ($divider === $row) {
                    $isHeader = \false;
                    $isFirstRow = \true;
                    continue;
                }
                if ($row instanceof TableSeparator) {
                    $this->renderRowSeparator();
                    continue;
                }
                if (!$row) {
                    continue;
                }
                if ($isHeader && !$isHeaderSeparatorRendered) {
                    $this->renderRowSeparator($isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, $hasTitle ? $this->headerTitle : null, $hasTitle ? $this->style->getHeaderTitleFormat() : null);
                    $hasTitle = \false;
                    $isHeaderSeparatorRendered = \true;
                }
                if ($isFirstRow) {
                    $this->renderRowSeparator($isHeader ? self::SEPARATOR_TOP : self::SEPARATOR_TOP_BOTTOM, $hasTitle ? $this->headerTitle : null, $hasTitle ? $this->style->getHeaderTitleFormat() : null);
                    $isFirstRow = \false;
                    $hasTitle = \false;
                }
                if ($this->horizontal) {
                    $this->renderRow($row, $this->style->getCellRowFormat(), $this->style->getCellHeaderFormat());
                } else {
                    $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
                }
            }
        }
        $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat());
        $this->cleanup();
        $this->rendered = \true;
    }
    /**
     * Renders horizontal header separator.
     *
     * Example:
     *
     *     +-----+-----------+-------+
     */
    private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null)
    {
        if (0 === ($count = $this->numberOfColumns)) {
            return;
        }
        $borders = $this->style->getBorderChars();
        if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) {
            return;
        }
        $crossings = $this->style->getCrossingChars();
        if (self::SEPARATOR_MID === $type) {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[2], $crossings[8], $crossings[0], $crossings[4]];
        } elseif (self::SEPARATOR_TOP === $type) {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[1], $crossings[2], $crossings[3]];
        } elseif (self::SEPARATOR_TOP_BOTTOM === $type) {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[9], $crossings[10], $crossings[11]];
        } else {
            [$horizontal, $leftChar, $midChar, $rightChar] = [$borders[0], $crossings[7], $crossings[6], $crossings[5]];
        }
        $markup = $leftChar;
        for ($column = 0; $column < $count; ++$column) {
            $markup .= \str_repeat($horizontal, $this->effectiveColumnWidths[$column]);
            $markup .= $column === $count - 1 ? $rightChar : $midChar;
        }
        if (null !== $title) {
            $titleLength = Helper::width(Helper::removeDecoration($formatter = $this->output->getFormatter(), $formattedTitle = \sprintf($titleFormat, $title)));
            $markupLength = Helper::width($markup);
            if ($titleLength > ($limit = $markupLength - 4)) {
                $titleLength = $limit;
                $formatLength = Helper::width(Helper::removeDecoration($formatter, \sprintf($titleFormat, '')));
                $formattedTitle = \sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3) . '...');
            }
            $titleStart = \intdiv($markupLength - $titleLength, 2);
            if (\false === \mb_detect_encoding($markup, null, \true)) {
                $markup = \substr_replace($markup, $formattedTitle, $titleStart, $titleLength);
            } else {
                $markup = \mb_substr($markup, 0, $titleStart) . $formattedTitle . \mb_substr($markup, $titleStart + $titleLength);
            }
        }
        $this->output->writeln(\sprintf($this->style->getBorderFormat(), $markup));
    }
    /**
     * Renders vertical column separator.
     */
    private function renderColumnSeparator(int $type = self::BORDER_OUTSIDE) : string
    {
        $borders = $this->style->getBorderChars();
        return \sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]);
    }
    /**
     * Renders table row.
     *
     * Example:
     *
     *     | 9971-5-0210-0 | A Tale of Two Cities  | Charles Dickens  |
     */
    private function renderRow(array $row, string $cellFormat, string $firstCellFormat = null)
    {
        $rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE);
        $columns = $this->getRowColumns($row);
        $last = \count($columns) - 1;
        foreach ($columns as $i => $column) {
            if ($firstCellFormat && 0 === $i) {
                $rowContent .= $this->renderCell($row, $column, $firstCellFormat);
            } else {
                $rowContent .= $this->renderCell($row, $column, $cellFormat);
            }
            $rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE);
        }
        $this->output->writeln($rowContent);
    }
    /**
     * Renders table cell with padding.
     */
    private function renderCell(array $row, int $column, string $cellFormat) : string
    {
        $cell = $row[$column] ?? '';
        $width = $this->effectiveColumnWidths[$column];
        if ($cell instanceof TableCell && $cell->getColspan() > 1) {
            // add the width of the following columns(numbers of colspan).
            foreach (\range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) {
                $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn];
            }
        }
        // str_pad won't work properly with multi-byte strings, we need to fix the padding
        if (\false !== ($encoding = \mb_detect_encoding($cell, null, \true))) {
            $width += \strlen($cell) - \mb_strwidth($cell, $encoding);
        }
        $style = $this->getColumnStyle($column);
        if ($cell instanceof TableSeparator) {
            return \sprintf($style->getBorderFormat(), \str_repeat($style->getBorderChars()[2], $width));
        }
        $width += Helper::length($cell) - Helper::length(Helper::removeDecoration($this->output->getFormatter(), $cell));
        $content = \sprintf($style->getCellRowContentFormat(), $cell);
        $padType = $style->getPadType();
        if ($cell instanceof TableCell && $cell->getStyle() instanceof TableCellStyle) {
            $isNotStyledByTag = !\preg_match('/^<(\\w+|(\\w+=[\\w,]+;?)*)>.+<\\/(\\w+|(\\w+=\\w+;?)*)?>$/', $cell);
            if ($isNotStyledByTag) {
                $cellFormat = $cell->getStyle()->getCellFormat();
                if (!\is_string($cellFormat)) {
                    $tag = \http_build_query($cell->getStyle()->getTagOptions(), '', ';');
                    $cellFormat = '<' . $tag . '>%s</>';
                }
                if (\strstr($content, '</>')) {
                    $content = \str_replace('</>', '', $content);
                    $width -= 3;
                }
                if (\strstr($content, '<fg=default;bg=default>')) {
                    $content = \str_replace('<fg=default;bg=default>', '', $content);
                    $width -= \strlen('<fg=default;bg=default>');
                }
            }
            $padType = $cell->getStyle()->getPadByAlign();
        }
        return \sprintf($cellFormat, \str_pad($content, $width, $style->getPaddingChar(), $padType));
    }
    /**
     * Calculate number of columns for this table.
     */
    private function calculateNumberOfColumns(array $rows)
    {
        $columns = [0];
        foreach ($rows as $row) {
            if ($row instanceof TableSeparator) {
                continue;
            }
            $columns[] = $this->getNumberOfColumns($row);
        }
        $this->numberOfColumns = \max($columns);
    }
    private function buildTableRows(array $rows) : TableRows
    {
        /** @var WrappableOutputFormatterInterface $formatter */
        $formatter = $this->output->getFormatter();
        $unmergedRows = [];
        for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) {
            $rows = $this->fillNextRows($rows, $rowKey);
            // Remove any new line breaks and replace it with a new line
            foreach ($rows[$rowKey] as $column => $cell) {
                $colspan = $cell instanceof TableCell ? $cell->getColspan() : 1;
                if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) {
                    $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
                }
                if (!\strstr($cell ?? '', "\n")) {
                    continue;
                }
                $escaped = \implode("\n", \array_map([OutputFormatter::class, 'escapeTrailingBackslash'], \explode("\n", $cell)));
                $cell = $cell instanceof TableCell ? new TableCell($escaped, ['colspan' => $cell->getColspan()]) : $escaped;
                $lines = \explode("\n", \str_replace("\n", "<fg=default;bg=default></>\n", $cell));
                foreach ($lines as $lineKey => $line) {
                    if ($colspan > 1) {
                        $line = new TableCell($line, ['colspan' => $colspan]);
                    }
                    if (0 === $lineKey) {
                        $rows[$rowKey][$column] = $line;
                    } else {
                        if (!\array_key_exists($rowKey, $unmergedRows) || !\array_key_exists($lineKey, $unmergedRows[$rowKey])) {
                            $unmergedRows[$rowKey][$lineKey] = $this->copyRow($rows, $rowKey);
                        }
                        $unmergedRows[$rowKey][$lineKey][$column] = $line;
                    }
                }
            }
        }
        return new TableRows(function () use($rows, $unmergedRows) : \Traversable {
            foreach ($rows as $rowKey => $row) {
                $rowGroup = [$row instanceof TableSeparator ? $row : $this->fillCells($row)];
                if (isset($unmergedRows[$rowKey])) {
                    foreach ($unmergedRows[$rowKey] as $row) {
                        $rowGroup[] = $row instanceof TableSeparator ? $row : $this->fillCells($row);
                    }
                }
                (yield $rowGroup);
            }
        });
    }
    private function calculateRowCount() : int
    {
        $numberOfRows = \count(\iterator_to_array($this->buildTableRows(\array_merge($this->headers, [new TableSeparator()], $this->rows))));
        if ($this->headers) {
            ++$numberOfRows;
            // Add row for header separator
        }
        if (\count($this->rows) > 0) {
            ++$numberOfRows;
            // Add row for footer separator
        }
        return $numberOfRows;
    }
    /**
     * fill rows that contains rowspan > 1.
     *
     * @throws InvalidArgumentException
     */
    private function fillNextRows(array $rows, int $line) : array
    {
        $unmergedRows = [];
        foreach ($rows[$line] as $column => $cell) {
            if (null !== $cell && !$cell instanceof TableCell && !\is_scalar($cell) && !(\is_object($cell) && \method_exists($cell, '__toString'))) {
                throw new InvalidArgumentException(\sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', \get_debug_type($cell)));
            }
            if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
                $nbLines = $cell->getRowspan() - 1;
                $lines = [$cell];
                if (\strstr($cell, "\n")) {
                    $lines = \explode("\n", \str_replace("\n", "<fg=default;bg=default>\n</>", $cell));
                    $nbLines = \count($lines) > $nbLines ? \substr_count($cell, "\n") : $nbLines;
                    $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
                    unset($lines[0]);
                }
                // create a two dimensional array (rowspan x colspan)
                $unmergedRows = \array_replace_recursive(\array_fill($line + 1, $nbLines, []), $unmergedRows);
                foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
                    $value = $lines[$unmergedRowKey - $line] ?? '';
                    $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan(), 'style' => $cell->getStyle()]);
                    if ($nbLines === $unmergedRowKey - $line) {
                        break;
                    }
                }
            }
        }
        foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) {
            // we need to know if $unmergedRow will be merged or inserted into $rows
            if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && $this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns) {
                foreach ($unmergedRow as $cellKey => $cell) {
                    // insert cell into row at cellKey position
                    \array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]);
                }
            } else {
                $row = $this->copyRow($rows, $unmergedRowKey - 1);
                foreach ($unmergedRow as $column => $cell) {
                    if (!empty($cell)) {
                        $row[$column] = $unmergedRow[$column];
                    }
                }
                \array_splice($rows, $unmergedRowKey, 0, [$row]);
            }
        }
        return $rows;
    }
    /**
     * fill cells for a row that contains colspan > 1.
     */
    private function fillCells(iterable $row)
    {
        $newRow = [];
        foreach ($row as $column => $cell) {
            $newRow[] = $cell;
            if ($cell instanceof TableCell && $cell->getColspan() > 1) {
                foreach (\range($column + 1, $column + $cell->getColspan() - 1) as $position) {
                    // insert empty value at column position
                    $newRow[] = '';
                }
            }
        }
        return $newRow ?: $row;
    }
    private function copyRow(array $rows, int $line) : array
    {
        $row = $rows[$line];
        foreach ($row as $cellKey => $cellValue) {
            $row[$cellKey] = '';
            if ($cellValue instanceof TableCell) {
                $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]);
            }
        }
        return $row;
    }
    /**
     * Gets number of columns by row.
     */
    private function getNumberOfColumns(array $row) : int
    {
        $columns = \count($row);
        foreach ($row as $column) {
            $columns += $column instanceof TableCell ? $column->getColspan() - 1 : 0;
        }
        return $columns;
    }
    /**
     * Gets list of columns for the given row.
     */
    private function getRowColumns(array $row) : array
    {
        $columns = \range(0, $this->numberOfColumns - 1);
        foreach ($row as $cellKey => $cell) {
            if ($cell instanceof TableCell && $cell->getColspan() > 1) {
                // exclude grouped columns.
                $columns = \array_diff($columns, \range($cellKey + 1, $cellKey + $cell->getColspan() - 1));
            }
        }
        return $columns;
    }
    /**
     * Calculates columns widths.
     */
    private function calculateColumnsWidth(iterable $groups)
    {
        for ($column = 0; $column < $this->numberOfColumns; ++$column) {
            $lengths = [];
            foreach ($groups as $group) {
                foreach ($group as $row) {
                    if ($row instanceof TableSeparator) {
                        continue;
                    }
                    foreach ($row as $i => $cell) {
                        if ($cell instanceof TableCell) {
                            $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell);
                            $textLength = Helper::width($textContent);
                            if ($textLength > 0) {
                                $contentColumns = \str_split($textContent, \ceil($textLength / $cell->getColspan()));
                                foreach ($contentColumns as $position => $content) {
                                    $row[$i + $position] = $content;
                                }
                            }
                        }
                    }
                    $lengths[] = $this->getCellWidth($row, $column);
                }
            }
            $this->effectiveColumnWidths[$column] = \max($lengths) + Helper::width($this->style->getCellRowContentFormat()) - 2;
        }
    }
    private function getColumnSeparatorWidth() : int
    {
        return Helper::width(\sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3]));
    }
    private function getCellWidth(array $row, int $column) : int
    {
        $cellWidth = 0;
        if (isset($row[$column])) {
            $cell = $row[$column];
            $cellWidth = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $cell));
        }
        $columnWidth = $this->columnWidths[$column] ?? 0;
        $cellWidth = \max($cellWidth, $columnWidth);
        return isset($this->columnMaxWidths[$column]) ? \min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth;
    }
    /**
     * Called after rendering to cleanup cache data.
     */
    private function cleanup()
    {
        $this->effectiveColumnWidths = [];
        $this->numberOfColumns = null;
    }
    /**
     * @return array<string, TableStyle>
     */
    private static function initStyles() : array
    {
        $borderless = new TableStyle();
        $borderless->setHorizontalBorderChars('=')->setVerticalBorderChars(' ')->setDefaultCrossingChar(' ');
        $compact = new TableStyle();
        $compact->setHorizontalBorderChars('')->setVerticalBorderChars('')->setDefaultCrossingChar('')->setCellRowContentFormat('%s ');
        $styleGuide = new TableStyle();
        $styleGuide->setHorizontalBorderChars('-')->setVerticalBorderChars(' ')->setDefaultCrossingChar(' ')->setCellHeaderFormat('%s');
        $box = (new TableStyle())->setHorizontalBorderChars('─')->setVerticalBorderChars('│')->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├');
        $boxDouble = (new TableStyle())->setHorizontalBorderChars('═', '─')->setVerticalBorderChars('║', '│')->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣');
        return ['default' => new TableStyle(), 'borderless' => $borderless, 'compact' => $compact, 'symfony-style-guide' => $styleGuide, 'box' => $box, 'box-double' => $boxDouble];
    }
    private function resolveStyle($name) : TableStyle
    {
        if ($name instanceof TableStyle) {
            return $name;
        }
        if (isset(self::$styles[$name])) {
            return self::$styles[$name];
        }
        throw new InvalidArgumentException(\sprintf('Style "%s" is not defined.', $name));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Cursor;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\LogicException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleSectionOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Terminal;
/**
 * The ProgressBar provides helpers to display progress output.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Chris Jones <leeked@gmail.com>
 */
final class ProgressBar
{
    public const FORMAT_VERBOSE = 'verbose';
    public const FORMAT_VERY_VERBOSE = 'very_verbose';
    public const FORMAT_DEBUG = 'debug';
    public const FORMAT_NORMAL = 'normal';
    private const FORMAT_VERBOSE_NOMAX = 'verbose_nomax';
    private const FORMAT_VERY_VERBOSE_NOMAX = 'very_verbose_nomax';
    private const FORMAT_DEBUG_NOMAX = 'debug_nomax';
    private const FORMAT_NORMAL_NOMAX = 'normal_nomax';
    private $barWidth = 28;
    private $barChar;
    private $emptyBarChar = '-';
    private $progressChar = '>';
    private $format;
    private $internalFormat;
    private $redrawFreq = 1;
    private $writeCount;
    private $lastWriteTime;
    private $minSecondsBetweenRedraws = 0;
    private $maxSecondsBetweenRedraws = 1;
    private $output;
    private $step = 0;
    private $max;
    private $startTime;
    private $stepWidth;
    private $percent = 0.0;
    private $messages = [];
    private $overwrite = \true;
    private $terminal;
    private $previousMessage;
    private $cursor;
    private static $formatters;
    private static $formats;
    /**
     * @param int $max Maximum steps (0 if unknown)
     */
    public function __construct(OutputInterface $output, int $max = 0, float $minSecondsBetweenRedraws = 1 / 25)
    {
        if ($output instanceof ConsoleOutputInterface) {
            $output = $output->getErrorOutput();
        }
        $this->output = $output;
        $this->setMaxSteps($max);
        $this->terminal = new Terminal();
        if (0 < $minSecondsBetweenRedraws) {
            $this->redrawFreq = null;
            $this->minSecondsBetweenRedraws = $minSecondsBetweenRedraws;
        }
        if (!$this->output->isDecorated()) {
            // disable overwrite when output does not support ANSI codes.
            $this->overwrite = \false;
            // set a reasonable redraw frequency so output isn't flooded
            $this->redrawFreq = null;
        }
        $this->startTime = \time();
        $this->cursor = new Cursor($output);
    }
    /**
     * Sets a placeholder formatter for a given name.
     *
     * This method also allow you to override an existing placeholder.
     *
     * @param string   $name     The placeholder name (including the delimiter char like %)
     * @param callable $callable A PHP callable
     */
    public static function setPlaceholderFormatterDefinition(string $name, callable $callable) : void
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }
        self::$formatters[$name] = $callable;
    }
    /**
     * Gets the placeholder formatter for a given name.
     *
     * @param string $name The placeholder name (including the delimiter char like %)
     */
    public static function getPlaceholderFormatterDefinition(string $name) : ?callable
    {
        if (!self::$formatters) {
            self::$formatters = self::initPlaceholderFormatters();
        }
        return self::$formatters[$name] ?? null;
    }
    /**
     * Sets a format for a given name.
     *
     * This method also allow you to override an existing format.
     *
     * @param string $name   The format name
     * @param string $format A format string
     */
    public static function setFormatDefinition(string $name, string $format) : void
    {
        if (!self::$formats) {
            self::$formats = self::initFormats();
        }
        self::$formats[$name] = $format;
    }
    /**
     * Gets the format for a given name.
     *
     * @param string $name The format name
     */
    public static function getFormatDefinition(string $name) : ?string
    {
        if (!self::$formats) {
            self::$formats = self::initFormats();
        }
        return self::$formats[$name] ?? null;
    }
    /**
     * Associates a text with a named placeholder.
     *
     * The text is displayed when the progress bar is rendered but only
     * when the corresponding placeholder is part of the custom format line
     * (by wrapping the name with %).
     *
     * @param string $message The text to associate with the placeholder
     * @param string $name    The name of the placeholder
     */
    public function setMessage(string $message, string $name = 'message')
    {
        $this->messages[$name] = $message;
    }
    public function getMessage(string $name = 'message')
    {
        return $this->messages[$name];
    }
    public function getStartTime() : int
    {
        return $this->startTime;
    }
    public function getMaxSteps() : int
    {
        return $this->max;
    }
    public function getProgress() : int
    {
        return $this->step;
    }
    private function getStepWidth() : int
    {
        return $this->stepWidth;
    }
    public function getProgressPercent() : float
    {
        return $this->percent;
    }
    public function getBarOffset() : float
    {
        return \floor($this->max ? $this->percent * $this->barWidth : (null === $this->redrawFreq ? (int) (\min(5, $this->barWidth / 15) * $this->writeCount) : $this->step) % $this->barWidth);
    }
    public function getEstimated() : float
    {
        if (!$this->step) {
            return 0;
        }
        return \round((\time() - $this->startTime) / $this->step * $this->max);
    }
    public function getRemaining() : float
    {
        if (!$this->step) {
            return 0;
        }
        return \round((\time() - $this->startTime) / $this->step * ($this->max - $this->step));
    }
    public function setBarWidth(int $size)
    {
        $this->barWidth = \max(1, $size);
    }
    public function getBarWidth() : int
    {
        return $this->barWidth;
    }
    public function setBarCharacter(string $char)
    {
        $this->barChar = $char;
    }
    public function getBarCharacter() : string
    {
        return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar);
    }
    public function setEmptyBarCharacter(string $char)
    {
        $this->emptyBarChar = $char;
    }
    public function getEmptyBarCharacter() : string
    {
        return $this->emptyBarChar;
    }
    public function setProgressCharacter(string $char)
    {
        $this->progressChar = $char;
    }
    public function getProgressCharacter() : string
    {
        return $this->progressChar;
    }
    public function setFormat(string $format)
    {
        $this->format = null;
        $this->internalFormat = $format;
    }
    /**
     * Sets the redraw frequency.
     *
     * @param int|null $freq The frequency in steps
     */
    public function setRedrawFrequency(?int $freq)
    {
        $this->redrawFreq = null !== $freq ? \max(1, $freq) : null;
    }
    public function minSecondsBetweenRedraws(float $seconds) : void
    {
        $this->minSecondsBetweenRedraws = $seconds;
    }
    public function maxSecondsBetweenRedraws(float $seconds) : void
    {
        $this->maxSecondsBetweenRedraws = $seconds;
    }
    /**
     * Returns an iterator that will automatically update the progress bar when iterated.
     *
     * @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
     */
    public function iterate(iterable $iterable, int $max = null) : iterable
    {
        $this->start($max ?? (\is_countable($iterable) ? \count($iterable) : 0));
        foreach ($iterable as $key => $value) {
            (yield $key => $value);
            $this->advance();
        }
        $this->finish();
    }
    /**
     * Starts the progress output.
     *
     * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
     */
    public function start(int $max = null)
    {
        $this->startTime = \time();
        $this->step = 0;
        $this->percent = 0.0;
        if (null !== $max) {
            $this->setMaxSteps($max);
        }
        $this->display();
    }
    /**
     * Advances the progress output X steps.
     *
     * @param int $step Number of steps to advance
     */
    public function advance(int $step = 1)
    {
        $this->setProgress($this->step + $step);
    }
    /**
     * Sets whether to overwrite the progressbar, false for new line.
     */
    public function setOverwrite(bool $overwrite)
    {
        $this->overwrite = $overwrite;
    }
    public function setProgress(int $step)
    {
        if ($this->max && $step > $this->max) {
            $this->max = $step;
        } elseif ($step < 0) {
            $step = 0;
        }
        $redrawFreq = $this->redrawFreq ?? ($this->max ?: 10) / 10;
        $prevPeriod = (int) ($this->step / $redrawFreq);
        $currPeriod = (int) ($step / $redrawFreq);
        $this->step = $step;
        $this->percent = $this->max ? (float) $this->step / $this->max : 0;
        $timeInterval = \microtime(\true) - $this->lastWriteTime;
        // Draw regardless of other limits
        if ($this->max === $step) {
            $this->display();
            return;
        }
        // Throttling
        if ($timeInterval < $this->minSecondsBetweenRedraws) {
            return;
        }
        // Draw each step period, but not too late
        if ($prevPeriod !== $currPeriod || $timeInterval >= $this->maxSecondsBetweenRedraws) {
            $this->display();
        }
    }
    public function setMaxSteps(int $max)
    {
        $this->format = null;
        $this->max = \max(0, $max);
        $this->stepWidth = $this->max ? Helper::width((string) $this->max) : 4;
    }
    /**
     * Finishes the progress output.
     */
    public function finish() : void
    {
        if (!$this->max) {
            $this->max = $this->step;
        }
        if ($this->step === $this->max && !$this->overwrite) {
            // prevent double 100% output
            return;
        }
        $this->setProgress($this->max);
    }
    /**
     * Outputs the current progress string.
     */
    public function display() : void
    {
        if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) {
            return;
        }
        if (null === $this->format) {
            $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
        }
        $this->overwrite($this->buildLine());
    }
    /**
     * Removes the progress bar from the current line.
     *
     * This is useful if you wish to write some output
     * while a progress bar is running.
     * Call display() to show the progress bar again.
     */
    public function clear() : void
    {
        if (!$this->overwrite) {
            return;
        }
        if (null === $this->format) {
            $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat());
        }
        $this->overwrite('');
    }
    private function setRealFormat(string $format)
    {
        // try to use the _nomax variant if available
        if (!$this->max && null !== self::getFormatDefinition($format . '_nomax')) {
            $this->format = self::getFormatDefinition($format . '_nomax');
        } elseif (null !== self::getFormatDefinition($format)) {
            $this->format = self::getFormatDefinition($format);
        } else {
            $this->format = $format;
        }
    }
    /**
     * Overwrites a previous message to the output.
     */
    private function overwrite(string $message) : void
    {
        if ($this->previousMessage === $message) {
            return;
        }
        $originalMessage = $message;
        if ($this->overwrite) {
            if (null !== $this->previousMessage) {
                if ($this->output instanceof ConsoleSectionOutput) {
                    $messageLines = \explode("\n", $this->previousMessage);
                    $lineCount = \count($messageLines);
                    foreach ($messageLines as $messageLine) {
                        $messageLineLength = Helper::width(Helper::removeDecoration($this->output->getFormatter(), $messageLine));
                        if ($messageLineLength > $this->terminal->getWidth()) {
                            $lineCount += \floor($messageLineLength / $this->terminal->getWidth());
                        }
                    }
                    $this->output->clear($lineCount);
                } else {
                    $lineCount = \substr_count($this->previousMessage, "\n");
                    for ($i = 0; $i < $lineCount; ++$i) {
                        $this->cursor->moveToColumn(1);
                        $this->cursor->clearLine();
                        $this->cursor->moveUp();
                    }
                    $this->cursor->moveToColumn(1);
                    $this->cursor->clearLine();
                }
            }
        } elseif ($this->step > 0) {
            $message = \PHP_EOL . $message;
        }
        $this->previousMessage = $originalMessage;
        $this->lastWriteTime = \microtime(\true);
        $this->output->write($message);
        ++$this->writeCount;
    }
    private function determineBestFormat() : string
    {
        switch ($this->output->getVerbosity()) {
            // OutputInterface::VERBOSITY_QUIET: display is disabled anyway
            case OutputInterface::VERBOSITY_VERBOSE:
                return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX;
            case OutputInterface::VERBOSITY_VERY_VERBOSE:
                return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX;
            case OutputInterface::VERBOSITY_DEBUG:
                return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX;
            default:
                return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX;
        }
    }
    private static function initPlaceholderFormatters() : array
    {
        return ['bar' => function (self $bar, OutputInterface $output) {
            $completeBars = $bar->getBarOffset();
            $display = \str_repeat($bar->getBarCharacter(), $completeBars);
            if ($completeBars < $bar->getBarWidth()) {
                $emptyBars = $bar->getBarWidth() - $completeBars - Helper::length(Helper::removeDecoration($output->getFormatter(), $bar->getProgressCharacter()));
                $display .= $bar->getProgressCharacter() . \str_repeat($bar->getEmptyBarCharacter(), $emptyBars);
            }
            return $display;
        }, 'elapsed' => function (self $bar) {
            return Helper::formatTime(\time() - $bar->getStartTime());
        }, 'remaining' => function (self $bar) {
            if (!$bar->getMaxSteps()) {
                throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
            }
            return Helper::formatTime($bar->getRemaining());
        }, 'estimated' => function (self $bar) {
            if (!$bar->getMaxSteps()) {
                throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
            }
            return Helper::formatTime($bar->getEstimated());
        }, 'memory' => function (self $bar) {
            return Helper::formatMemory(\memory_get_usage(\true));
        }, 'current' => function (self $bar) {
            return \str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT);
        }, 'max' => function (self $bar) {
            return $bar->getMaxSteps();
        }, 'percent' => function (self $bar) {
            return \floor($bar->getProgressPercent() * 100);
        }];
    }
    private static function initFormats() : array
    {
        return [self::FORMAT_NORMAL => ' %current%/%max% [%bar%] %percent:3s%%', self::FORMAT_NORMAL_NOMAX => ' %current% [%bar%]', self::FORMAT_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%', self::FORMAT_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', self::FORMAT_VERY_VERBOSE => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%', self::FORMAT_VERY_VERBOSE_NOMAX => ' %current% [%bar%] %elapsed:6s%', self::FORMAT_DEBUG => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%', self::FORMAT_DEBUG_NOMAX => ' %current% [%bar%] %elapsed:6s% %memory:6s%'];
    }
    private function buildLine() : string
    {
        $regex = "{%([a-z\\-_]+)(?:\\:([^%]+))?%}i";
        $callback = function ($matches) {
            if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
                $text = $formatter($this, $this->output);
            } elseif (isset($this->messages[$matches[1]])) {
                $text = $this->messages[$matches[1]];
            } else {
                return $matches[0];
            }
            if (isset($matches[2])) {
                $text = \sprintf('%' . $matches[2], $text);
            }
            return $text;
        };
        $line = \preg_replace_callback($regex, $callback, $this->format);
        // gets string length for each sub line with multiline format
        $linesLength = \array_map(function ($subLine) {
            return Helper::width(Helper::removeDecoration($this->output->getFormatter(), \rtrim($subLine, "\r")));
        }, \explode("\n", $line));
        $linesWidth = \max($linesLength);
        $terminalWidth = $this->terminal->getWidth();
        if ($linesWidth <= $terminalWidth) {
            return $line;
        }
        $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth);
        return \preg_replace_callback($regex, $callback, $this->format);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputAwareInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
/**
 * An implementation of InputAwareInterface for Helpers.
 *
 * @author Wouter J <waldio.webdesign@gmail.com>
 */
abstract class InputAwareHelper extends Helper implements InputAwareInterface
{
    protected $input;
    /**
     * {@inheritdoc}
     */
    public function setInput(InputInterface $input)
    {
        $this->input = $input;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\VarDumper\Cloner\ClonerInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\VarDumper\Cloner\VarCloner;
use _HumbugBox1cb33d1f20f1\Symfony\Component\VarDumper\Dumper\CliDumper;
/**
 * @author Roland Franssen <franssen.roland@gmail.com>
 */
final class Dumper
{
    private $output;
    private $dumper;
    private $cloner;
    private $handler;
    public function __construct(OutputInterface $output, CliDumper $dumper = null, ClonerInterface $cloner = null)
    {
        $this->output = $output;
        $this->dumper = $dumper;
        $this->cloner = $cloner;
        if (\class_exists(CliDumper::class)) {
            $this->handler = function ($var) : string {
                $dumper = $this->dumper ?? ($this->dumper = new CliDumper(null, null, CliDumper::DUMP_LIGHT_ARRAY | CliDumper::DUMP_COMMA_SEPARATOR));
                $dumper->setColors($this->output->isDecorated());
                return \rtrim($dumper->dump(($this->cloner ?? ($this->cloner = new VarCloner()))->cloneVar($var)->withRefHandles(\false), \true));
            };
        } else {
            $this->handler = function ($var) : string {
                switch (\true) {
                    case null === $var:
                        return 'null';
                    case \true === $var:
                        return 'true';
                    case \false === $var:
                        return 'false';
                    case \is_string($var):
                        return '"' . $var . '"';
                    default:
                        return \rtrim(\print_r($var, \true));
                }
            };
        }
    }
    public function __invoke($var) : string
    {
        return ($this->handler)($var);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper;

/**
 * @internal
 */
class TableRows implements \IteratorAggregate
{
    private $generator;
    public function __construct(\Closure $generator)
    {
        $this->generator = $generator;
    }
    public function getIterator() : \Traversable
    {
        return ($this->generator)();
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
 * A BufferedOutput that keeps only the last N chars.
 *
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
class TrimmedBufferOutput extends Output
{
    private $maxLength;
    private $buffer = '';
    public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = \false, OutputFormatterInterface $formatter = null)
    {
        if ($maxLength <= 0) {
            throw new InvalidArgumentException(\sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength));
        }
        parent::__construct($verbosity, $decorated, $formatter);
        $this->maxLength = $maxLength;
    }
    /**
     * Empties buffer and returns its content.
     *
     * @return string
     */
    public function fetch()
    {
        $content = $this->buffer;
        $this->buffer = '';
        return $content;
    }
    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        $this->buffer .= $message;
        if ($newline) {
            $this->buffer .= \PHP_EOL;
        }
        $this->buffer = \substr($this->buffer, 0 - $this->maxLength);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
 * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR.
 *
 * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR.
 *
 *     $output = new ConsoleOutput();
 *
 * This is equivalent to:
 *
 *     $output = new StreamOutput(fopen('php://stdout', 'w'));
 *     $stdErr = new StreamOutput(fopen('php://stderr', 'w'));
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
{
    private $stderr;
    private $consoleSectionOutputs = [];
    /**
     * @param int                           $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
     * @param bool|null                     $decorated Whether to decorate messages (null for auto-guessing)
     * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
     */
    public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
    {
        parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
        if (null === $formatter) {
            // for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter.
            $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated);
            return;
        }
        $actualDecorated = $this->isDecorated();
        $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
        if (null === $decorated) {
            $this->setDecorated($actualDecorated && $this->stderr->isDecorated());
        }
    }
    /**
     * Creates a new output section.
     */
    public function section() : ConsoleSectionOutput
    {
        return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
    }
    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        parent::setDecorated($decorated);
        $this->stderr->setDecorated($decorated);
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        parent::setFormatter($formatter);
        $this->stderr->setFormatter($formatter);
    }
    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        parent::setVerbosity($level);
        $this->stderr->setVerbosity($level);
    }
    /**
     * {@inheritdoc}
     */
    public function getErrorOutput()
    {
        return $this->stderr;
    }
    /**
     * {@inheritdoc}
     */
    public function setErrorOutput(OutputInterface $error)
    {
        $this->stderr = $error;
    }
    /**
     * Returns true if current environment supports writing console output to
     * STDOUT.
     *
     * @return bool
     */
    protected function hasStdoutSupport()
    {
        return \false === $this->isRunningOS400();
    }
    /**
     * Returns true if current environment supports writing console output to
     * STDERR.
     *
     * @return bool
     */
    protected function hasStderrSupport()
    {
        return \false === $this->isRunningOS400();
    }
    /**
     * Checks if current executing environment is IBM iSeries (OS400), which
     * doesn't properly convert character-encodings between ASCII to EBCDIC.
     */
    private function isRunningOS400() : bool
    {
        $checks = [\function_exists('php_uname') ? \php_uname('s') : '', \getenv('OSTYPE'), \PHP_OS];
        return \false !== \stripos(\implode(';', $checks), 'OS400');
    }
    /**
     * @return resource
     */
    private function openOutputStream()
    {
        if (!$this->hasStdoutSupport()) {
            return \fopen('php://output', 'w');
        }
        // Use STDOUT when possible to prevent from opening too many file descriptors
        return \defined('STDOUT') ? \STDOUT : (@\fopen('php://stdout', 'w') ?: \fopen('php://output', 'w'));
    }
    /**
     * @return resource
     */
    private function openErrorStream()
    {
        if (!$this->hasStderrSupport()) {
            return \fopen('php://output', 'w');
        }
        // Use STDERR when possible to prevent from opening too many file descriptors
        return \defined('STDERR') ? \STDERR : (@\fopen('php://stderr', 'w') ?: \fopen('php://output', 'w'));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
 * OutputInterface is the interface implemented by all Output classes.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface OutputInterface
{
    public const VERBOSITY_QUIET = 16;
    public const VERBOSITY_NORMAL = 32;
    public const VERBOSITY_VERBOSE = 64;
    public const VERBOSITY_VERY_VERBOSE = 128;
    public const VERBOSITY_DEBUG = 256;
    public const OUTPUT_NORMAL = 1;
    public const OUTPUT_RAW = 2;
    public const OUTPUT_PLAIN = 4;
    /**
     * Writes a message to the output.
     *
     * @param string|iterable $messages The message as an iterable of strings or a single string
     * @param bool            $newline  Whether to add a newline
     * @param int             $options  A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
     */
    public function write($messages, bool $newline = \false, int $options = 0);
    /**
     * Writes a message to the output and adds a newline at the end.
     *
     * @param string|iterable $messages The message as an iterable of strings or a single string
     * @param int             $options  A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
     */
    public function writeln($messages, int $options = 0);
    /**
     * Sets the verbosity of the output.
     */
    public function setVerbosity(int $level);
    /**
     * Gets the current verbosity of the output.
     *
     * @return int
     */
    public function getVerbosity();
    /**
     * Returns whether verbosity is quiet (-q).
     *
     * @return bool
     */
    public function isQuiet();
    /**
     * Returns whether verbosity is verbose (-v).
     *
     * @return bool
     */
    public function isVerbose();
    /**
     * Returns whether verbosity is very verbose (-vv).
     *
     * @return bool
     */
    public function isVeryVerbose();
    /**
     * Returns whether verbosity is debug (-vvv).
     *
     * @return bool
     */
    public function isDebug();
    /**
     * Sets the decorated flag.
     */
    public function setDecorated(bool $decorated);
    /**
     * Gets the decorated flag.
     *
     * @return bool
     */
    public function isDecorated();
    public function setFormatter(OutputFormatterInterface $formatter);
    /**
     * Returns current output formatter instance.
     *
     * @return OutputFormatterInterface
     */
    public function getFormatter();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

/**
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
class BufferedOutput extends Output
{
    private $buffer = '';
    /**
     * Empties buffer and returns its content.
     *
     * @return string
     */
    public function fetch()
    {
        $content = $this->buffer;
        $this->buffer = '';
        return $content;
    }
    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        $this->buffer .= $message;
        if ($newline) {
            $this->buffer .= \PHP_EOL;
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
 * StreamOutput writes the output to a given stream.
 *
 * Usage:
 *
 *     $output = new StreamOutput(fopen('php://stdout', 'w'));
 *
 * As `StreamOutput` can use any stream, you can also use a file:
 *
 *     $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class StreamOutput extends Output
{
    private $stream;
    /**
     * @param resource                      $stream    A stream resource
     * @param int                           $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
     * @param bool|null                     $decorated Whether to decorate messages (null for auto-guessing)
     * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
     *
     * @throws InvalidArgumentException When first argument is not a real stream
     */
    public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null)
    {
        if (!\is_resource($stream) || 'stream' !== \get_resource_type($stream)) {
            throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.');
        }
        $this->stream = $stream;
        if (null === $decorated) {
            $decorated = $this->hasColorSupport();
        }
        parent::__construct($verbosity, $decorated, $formatter);
    }
    /**
     * Gets the stream attached to this StreamOutput instance.
     *
     * @return resource
     */
    public function getStream()
    {
        return $this->stream;
    }
    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        if ($newline) {
            $message .= \PHP_EOL;
        }
        @\fwrite($this->stream, $message);
        \fflush($this->stream);
    }
    /**
     * Returns true if the stream supports colorization.
     *
     * Colorization is disabled if not supported by the stream:
     *
     * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo
     * terminals via named pipes, so we can only check the environment.
     *
     * Reference: Composer\XdebugHandler\Process::supportsColor
     * https://github.com/composer/xdebug-handler
     *
     * @return bool true if the stream supports colorization, false otherwise
     */
    protected function hasColorSupport()
    {
        // Follow https://no-color.org/
        if (isset($_SERVER['NO_COLOR']) || \false !== \getenv('NO_COLOR')) {
            return \false;
        }
        if ('Hyper' === \getenv('TERM_PROGRAM')) {
            return \true;
        }
        if (\DIRECTORY_SEPARATOR === '\\') {
            return \function_exists('sapi_windows_vt100_support') && @\sapi_windows_vt100_support($this->stream) || \false !== \getenv('ANSICON') || 'ON' === \getenv('ConEmuANSI') || 'xterm' === \getenv('TERM');
        }
        return \stream_isatty($this->stream);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
 * Base class for output classes.
 *
 * There are five levels of verbosity:
 *
 *  * normal: no option passed (normal output)
 *  * verbose: -v (more output)
 *  * very verbose: -vv (highly extended output)
 *  * debug: -vvv (all debug output)
 *  * quiet: -q (no output)
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
abstract class Output implements OutputInterface
{
    private $verbosity;
    private $formatter;
    /**
     * @param int|null                      $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
     * @param bool                          $decorated Whether to decorate messages
     * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
     */
    public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = \false, OutputFormatterInterface $formatter = null)
    {
        $this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL;
        $this->formatter = $formatter ?? new OutputFormatter();
        $this->formatter->setDecorated($decorated);
    }
    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        $this->formatter = $formatter;
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        return $this->formatter;
    }
    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        $this->formatter->setDecorated($decorated);
    }
    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return $this->formatter->isDecorated();
    }
    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        $this->verbosity = $level;
    }
    /**
     * {@inheritdoc}
     */
    public function getVerbosity()
    {
        return $this->verbosity;
    }
    /**
     * {@inheritdoc}
     */
    public function isQuiet()
    {
        return self::VERBOSITY_QUIET === $this->verbosity;
    }
    /**
     * {@inheritdoc}
     */
    public function isVerbose()
    {
        return self::VERBOSITY_VERBOSE <= $this->verbosity;
    }
    /**
     * {@inheritdoc}
     */
    public function isVeryVerbose()
    {
        return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
    }
    /**
     * {@inheritdoc}
     */
    public function isDebug()
    {
        return self::VERBOSITY_DEBUG <= $this->verbosity;
    }
    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $options = self::OUTPUT_NORMAL)
    {
        $this->write($messages, \true, $options);
    }
    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = \false, int $options = self::OUTPUT_NORMAL)
    {
        if (!\is_iterable($messages)) {
            $messages = [$messages];
        }
        $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
        $type = $types & $options ?: self::OUTPUT_NORMAL;
        $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
        $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;
        if ($verbosity > $this->getVerbosity()) {
            return;
        }
        foreach ($messages as $message) {
            switch ($type) {
                case OutputInterface::OUTPUT_NORMAL:
                    $message = $this->formatter->format($message);
                    break;
                case OutputInterface::OUTPUT_RAW:
                    break;
                case OutputInterface::OUTPUT_PLAIN:
                    $message = \strip_tags($this->formatter->format($message));
                    break;
            }
            $this->doWrite($message ?? '', $newline);
        }
    }
    /**
     * Writes a message to the output.
     */
    protected abstract function doWrite(string $message, bool $newline);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\Helper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Terminal;
/**
 * @author Pierre du Plessis <pdples@gmail.com>
 * @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
 */
class ConsoleSectionOutput extends StreamOutput
{
    private $content = [];
    private $lines = 0;
    private $sections;
    private $terminal;
    /**
     * @param resource               $stream
     * @param ConsoleSectionOutput[] $sections
     */
    public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter)
    {
        parent::__construct($stream, $verbosity, $decorated, $formatter);
        \array_unshift($sections, $this);
        $this->sections =& $sections;
        $this->terminal = new Terminal();
    }
    /**
     * Clears previous output for this section.
     *
     * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared
     */
    public function clear(int $lines = null)
    {
        if (empty($this->content) || !$this->isDecorated()) {
            return;
        }
        if ($lines) {
            \array_splice($this->content, -($lines * 2));
            // Multiply lines by 2 to cater for each new line added between content
        } else {
            $lines = $this->lines;
            $this->content = [];
        }
        $this->lines -= $lines;
        parent::doWrite($this->popStreamContentUntilCurrentSection($lines), \false);
    }
    /**
     * Overwrites the previous output with a new message.
     *
     * @param array|string $message
     */
    public function overwrite($message)
    {
        $this->clear();
        $this->writeln($message);
    }
    public function getContent() : string
    {
        return \implode('', $this->content);
    }
    /**
     * @internal
     */
    public function addContent(string $input)
    {
        foreach (\explode(\PHP_EOL, $input) as $lineContent) {
            $this->lines += \ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1;
            $this->content[] = $lineContent;
            $this->content[] = \PHP_EOL;
        }
    }
    /**
     * {@inheritdoc}
     */
    protected function doWrite(string $message, bool $newline)
    {
        if (!$this->isDecorated()) {
            parent::doWrite($message, $newline);
            return;
        }
        $erasedContent = $this->popStreamContentUntilCurrentSection();
        $this->addContent($message);
        parent::doWrite($message, \true);
        parent::doWrite($erasedContent, \false);
    }
    /**
     * At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits
     * current section. Then it erases content it crawled through. Optionally, it erases part of current section too.
     */
    private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0) : string
    {
        $numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection;
        $erasedContent = [];
        foreach ($this->sections as $section) {
            if ($section === $this) {
                break;
            }
            $numberOfLinesToClear += $section->lines;
            $erasedContent[] = $section->getContent();
        }
        if ($numberOfLinesToClear > 0) {
            // move cursor up n lines
            parent::doWrite(\sprintf("\x1b[%dA", $numberOfLinesToClear), \false);
            // erase to end of screen
            parent::doWrite("\x1b[0J", \false);
        }
        return \implode('', \array_reverse($erasedContent));
    }
    private function getDisplayLength(string $text) : int
    {
        return Helper::width(Helper::removeDecoration($this->getFormatter(), \str_replace("\t", '        ', $text)));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

/**
 * ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
 * This adds information about stderr and section output stream.
 *
 * @author Dariusz Górecki <darek.krk@gmail.com>
 */
interface ConsoleOutputInterface extends OutputInterface
{
    /**
     * Gets the OutputInterface for errors.
     *
     * @return OutputInterface
     */
    public function getErrorOutput();
    public function setErrorOutput(OutputInterface $error);
    public function section() : ConsoleSectionOutput;
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\NullOutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
 * NullOutput suppresses all output.
 *
 *     $output = new NullOutput();
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Tobias Schultze <http://tobion.de>
 */
class NullOutput implements OutputInterface
{
    private $formatter;
    /**
     * {@inheritdoc}
     */
    public function setFormatter(OutputFormatterInterface $formatter)
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function getFormatter()
    {
        if ($this->formatter) {
            return $this->formatter;
        }
        // to comply with the interface we must return a OutputFormatterInterface
        return $this->formatter = new NullOutputFormatter();
    }
    /**
     * {@inheritdoc}
     */
    public function setDecorated(bool $decorated)
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function isDecorated()
    {
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function setVerbosity(int $level)
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function getVerbosity()
    {
        return self::VERBOSITY_QUIET;
    }
    /**
     * {@inheritdoc}
     */
    public function isQuiet()
    {
        return \true;
    }
    /**
     * {@inheritdoc}
     */
    public function isVerbose()
    {
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function isVeryVerbose()
    {
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function isDebug()
    {
        return \false;
    }
    /**
     * {@inheritdoc}
     */
    public function writeln($messages, int $options = self::OUTPUT_NORMAL)
    {
        // do nothing
    }
    /**
     * {@inheritdoc}
     */
    public function write($messages, bool $newline = \false, int $options = self::OUTPUT_NORMAL)
    {
        // do nothing
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * @author Grégoire Pineau <lyrixx@lyrixx.info>
 */
class SingleCommandApplication extends Command
{
    private $version = 'UNKNOWN';
    private $autoExit = \true;
    private $running = \false;
    /**
     * @return $this
     */
    public function setVersion(string $version) : self
    {
        $this->version = $version;
        return $this;
    }
    /**
     * @final
     *
     * @return $this
     */
    public function setAutoExit(bool $autoExit) : self
    {
        $this->autoExit = $autoExit;
        return $this;
    }
    public function run(InputInterface $input = null, OutputInterface $output = null) : int
    {
        if ($this->running) {
            return parent::run($input, $output);
        }
        // We use the command name as the application name
        $application = new Application($this->getName() ?: 'UNKNOWN', $this->version);
        $application->setAutoExit($this->autoExit);
        // Fix the usage of the command displayed with "--help"
        $this->setName($_SERVER['argv'][0]);
        $application->add($this);
        $application->setDefaultCommand($this->getName(), \true);
        $this->running = \true;
        try {
            $ret = $application->run($input, $output);
        } finally {
            $this->running = \false;
        }
        return $ret ?? 1;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Tester;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\ArrayInput;
/**
 * Eases the testing of console applications.
 *
 * When testing an application, don't forget to disable the auto exit flag:
 *
 *     $application = new Application();
 *     $application->setAutoExit(false);
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class ApplicationTester
{
    use TesterTrait;
    private $application;
    public function __construct(Application $application)
    {
        $this->application = $application;
    }
    /**
     * Executes the application.
     *
     * Available options:
     *
     *  * interactive:               Sets the input interactive flag
     *  * decorated:                 Sets the output decorated flag
     *  * verbosity:                 Sets the output verbosity flag
     *  * capture_stderr_separately: Make output of stdOut and stdErr separately available
     *
     * @return int The command exit code
     */
    public function run(array $input, array $options = [])
    {
        $prevShellVerbosity = \getenv('SHELL_VERBOSITY');
        try {
            $this->input = new ArrayInput($input);
            if (isset($options['interactive'])) {
                $this->input->setInteractive($options['interactive']);
            }
            if ($this->inputs) {
                $this->input->setStream(self::createStream($this->inputs));
            }
            $this->initOutput($options);
            return $this->statusCode = $this->application->run($this->input, $this->output);
        } finally {
            // SHELL_VERBOSITY is set by Application::configureIO so we need to unset/reset it
            // to its previous value to avoid one test's verbosity to spread to the following tests
            if (\false === $prevShellVerbosity) {
                if (\function_exists('putenv')) {
                    @\putenv('SHELL_VERBOSITY');
                }
                unset($_ENV['SHELL_VERBOSITY']);
                unset($_SERVER['SHELL_VERBOSITY']);
            } else {
                if (\function_exists('putenv')) {
                    @\putenv('SHELL_VERBOSITY=' . $prevShellVerbosity);
                }
                $_ENV['SHELL_VERBOSITY'] = $prevShellVerbosity;
                $_SERVER['SHELL_VERBOSITY'] = $prevShellVerbosity;
            }
        }
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Tester;

use _HumbugBox1cb33d1f20f1\PHPUnit\Framework\Assert;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\ConsoleOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\StreamOutput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Tester\Constraint\CommandIsSuccessful;
/**
 * @author Amrouche Hamza <hamza.simperfit@gmail.com>
 */
trait TesterTrait
{
    /** @var StreamOutput */
    private $output;
    private $inputs = [];
    private $captureStreamsIndependently = \false;
    /** @var InputInterface */
    private $input;
    /** @var int */
    private $statusCode;
    /**
     * Gets the display returned by the last execution of the command or application.
     *
     * @throws \RuntimeException If it's called before the execute method
     *
     * @return string
     */
    public function getDisplay(bool $normalize = \false)
    {
        if (null === $this->output) {
            throw new \RuntimeException('Output not initialized, did you execute the command before requesting the display?');
        }
        \rewind($this->output->getStream());
        $display = \stream_get_contents($this->output->getStream());
        if ($normalize) {
            $display = \str_replace(\PHP_EOL, "\n", $display);
        }
        return $display;
    }
    /**
     * Gets the output written to STDERR by the application.
     *
     * @param bool $normalize Whether to normalize end of lines to \n or not
     *
     * @return string
     */
    public function getErrorOutput(bool $normalize = \false)
    {
        if (!$this->captureStreamsIndependently) {
            throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.');
        }
        \rewind($this->output->getErrorOutput()->getStream());
        $display = \stream_get_contents($this->output->getErrorOutput()->getStream());
        if ($normalize) {
            $display = \str_replace(\PHP_EOL, "\n", $display);
        }
        return $display;
    }
    /**
     * Gets the input instance used by the last execution of the command or application.
     *
     * @return InputInterface
     */
    public function getInput()
    {
        return $this->input;
    }
    /**
     * Gets the output instance used by the last execution of the command or application.
     *
     * @return OutputInterface
     */
    public function getOutput()
    {
        return $this->output;
    }
    /**
     * Gets the status code returned by the last execution of the command or application.
     *
     * @throws \RuntimeException If it's called before the execute method
     *
     * @return int
     */
    public function getStatusCode()
    {
        if (null === $this->statusCode) {
            throw new \RuntimeException('Status code not initialized, did you execute the command before requesting the status code?');
        }
        return $this->statusCode;
    }
    public function assertCommandIsSuccessful(string $message = '') : void
    {
        Assert::assertThat($this->statusCode, new CommandIsSuccessful(), $message);
    }
    /**
     * Sets the user inputs.
     *
     * @param array $inputs An array of strings representing each input
     *                      passed to the command input stream
     *
     * @return $this
     */
    public function setInputs(array $inputs)
    {
        $this->inputs = $inputs;
        return $this;
    }
    /**
     * Initializes the output property.
     *
     * Available options:
     *
     *  * decorated:                 Sets the output decorated flag
     *  * verbosity:                 Sets the output verbosity flag
     *  * capture_stderr_separately: Make output of stdOut and stdErr separately available
     */
    private function initOutput(array $options)
    {
        $this->captureStreamsIndependently = \array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately'];
        if (!$this->captureStreamsIndependently) {
            $this->output = new StreamOutput(\fopen('php://memory', 'w', \false));
            if (isset($options['decorated'])) {
                $this->output->setDecorated($options['decorated']);
            }
            if (isset($options['verbosity'])) {
                $this->output->setVerbosity($options['verbosity']);
            }
        } else {
            $this->output = new ConsoleOutput($options['verbosity'] ?? ConsoleOutput::VERBOSITY_NORMAL, $options['decorated'] ?? null);
            $errorOutput = new StreamOutput(\fopen('php://memory', 'w', \false));
            $errorOutput->setFormatter($this->output->getFormatter());
            $errorOutput->setVerbosity($this->output->getVerbosity());
            $errorOutput->setDecorated($this->output->isDecorated());
            $reflectedOutput = new \ReflectionObject($this->output);
            $strErrProperty = $reflectedOutput->getProperty('stderr');
            $strErrProperty->setAccessible(\true);
            $strErrProperty->setValue($this->output, $errorOutput);
            $reflectedParent = $reflectedOutput->getParentClass();
            $streamProperty = $reflectedParent->getProperty('stream');
            $streamProperty->setAccessible(\true);
            $streamProperty->setValue($this->output, \fopen('php://memory', 'w', \false));
        }
    }
    /**
     * @return resource
     */
    private static function createStream(array $inputs)
    {
        $stream = \fopen('php://memory', 'r+', \false);
        foreach ($inputs as $input) {
            \fwrite($stream, $input . \PHP_EOL);
        }
        \rewind($stream);
        return $stream;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Tester;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionInput;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Completion\CompletionSuggestions;
/**
 * Eases the testing of command completion.
 *
 * @author Jérôme Tamarelle <jerome@tamarelle.net>
 */
class CommandCompletionTester
{
    private $command;
    public function __construct(Command $command)
    {
        $this->command = $command;
    }
    /**
     * Create completion suggestions from input tokens.
     */
    public function complete(array $input) : array
    {
        $currentIndex = \count($input);
        if ('' === \end($input)) {
            \array_pop($input);
        }
        \array_unshift($input, $this->command->getName());
        $completionInput = CompletionInput::fromTokens($input, $currentIndex);
        $completionInput->bind($this->command->getDefinition());
        $suggestions = new CompletionSuggestions();
        $this->command->complete($completionInput, $suggestions);
        $options = [];
        foreach ($suggestions->getOptionSuggestions() as $option) {
            $options[] = '--' . $option->getName();
        }
        return \array_map('strval', \array_merge($options, $suggestions->getValueSuggestions()));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Tester\Constraint;

use _HumbugBox1cb33d1f20f1\PHPUnit\Framework\Constraint\Constraint;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
final class CommandIsSuccessful extends Constraint
{
    /**
     * {@inheritdoc}
     */
    public function toString() : string
    {
        return 'is successful';
    }
    /**
     * {@inheritdoc}
     */
    protected function matches($other) : bool
    {
        return Command::SUCCESS === $other;
    }
    /**
     * {@inheritdoc}
     */
    protected function failureDescription($other) : string
    {
        return 'the command ' . $this->toString();
    }
    /**
     * {@inheritdoc}
     */
    protected function additionalFailureDescription($other) : string
    {
        $mapping = [Command::FAILURE => 'Command failed.', Command::INVALID => 'Command was invalid.'];
        return $mapping[$other] ?? \sprintf('Command returned exit status %d.', $other);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Tester;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\ArrayInput;
/**
 * Eases the testing of console commands.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Robin Chalas <robin.chalas@gmail.com>
 */
class CommandTester
{
    use TesterTrait;
    private $command;
    public function __construct(Command $command)
    {
        $this->command = $command;
    }
    /**
     * Executes the command.
     *
     * Available execution options:
     *
     *  * interactive:               Sets the input interactive flag
     *  * decorated:                 Sets the output decorated flag
     *  * verbosity:                 Sets the output verbosity flag
     *  * capture_stderr_separately: Make output of stdOut and stdErr separately available
     *
     * @param array $input   An array of command arguments and options
     * @param array $options An array of execution options
     *
     * @return int The command exit code
     */
    public function execute(array $input, array $options = [])
    {
        // set the command name automatically if the application requires
        // this argument and no command name was passed
        if (!isset($input['command']) && null !== ($application = $this->command->getApplication()) && $application->getDefinition()->hasArgument('command')) {
            $input = \array_merge(['command' => $this->command->getName()], $input);
        }
        $this->input = new ArrayInput($input);
        // Use an in-memory input stream even if no inputs are set so that QuestionHelper::ask() does not rely on the blocking STDIN.
        $this->input->setStream(self::createStream($this->inputs));
        if (isset($options['interactive'])) {
            $this->input->setInteractive($options['interactive']);
        }
        if (!isset($options['decorated'])) {
            $options['decorated'] = \false;
        }
        $this->initOutput($options);
        return $this->statusCode = $this->command->run($this->input, $this->output);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * @author Pierre du Plessis <pdples@gmail.com>
 */
final class Cursor
{
    private $output;
    private $input;
    /**
     * @param resource|null $input
     */
    public function __construct(OutputInterface $output, $input = null)
    {
        $this->output = $output;
        $this->input = $input ?? (\defined('STDIN') ? \STDIN : \fopen('php://input', 'r+'));
    }
    /**
     * @return $this
     */
    public function moveUp(int $lines = 1) : self
    {
        $this->output->write(\sprintf("\x1b[%dA", $lines));
        return $this;
    }
    /**
     * @return $this
     */
    public function moveDown(int $lines = 1) : self
    {
        $this->output->write(\sprintf("\x1b[%dB", $lines));
        return $this;
    }
    /**
     * @return $this
     */
    public function moveRight(int $columns = 1) : self
    {
        $this->output->write(\sprintf("\x1b[%dC", $columns));
        return $this;
    }
    /**
     * @return $this
     */
    public function moveLeft(int $columns = 1) : self
    {
        $this->output->write(\sprintf("\x1b[%dD", $columns));
        return $this;
    }
    /**
     * @return $this
     */
    public function moveToColumn(int $column) : self
    {
        $this->output->write(\sprintf("\x1b[%dG", $column));
        return $this;
    }
    /**
     * @return $this
     */
    public function moveToPosition(int $column, int $row) : self
    {
        $this->output->write(\sprintf("\x1b[%d;%dH", $row + 1, $column));
        return $this;
    }
    /**
     * @return $this
     */
    public function savePosition() : self
    {
        $this->output->write("\x1b7");
        return $this;
    }
    /**
     * @return $this
     */
    public function restorePosition() : self
    {
        $this->output->write("\x1b8");
        return $this;
    }
    /**
     * @return $this
     */
    public function hide() : self
    {
        $this->output->write("\x1b[?25l");
        return $this;
    }
    /**
     * @return $this
     */
    public function show() : self
    {
        $this->output->write("\x1b[?25h\x1b[?0c");
        return $this;
    }
    /**
     * Clears all the output from the current line.
     *
     * @return $this
     */
    public function clearLine() : self
    {
        $this->output->write("\x1b[2K");
        return $this;
    }
    /**
     * Clears all the output from the current line after the current position.
     */
    public function clearLineAfter() : self
    {
        $this->output->write("\x1b[K");
        return $this;
    }
    /**
     * Clears all the output from the cursors' current position to the end of the screen.
     *
     * @return $this
     */
    public function clearOutput() : self
    {
        $this->output->write("\x1b[0J");
        return $this;
    }
    /**
     * Clears the entire screen.
     *
     * @return $this
     */
    public function clearScreen() : self
    {
        $this->output->write("\x1b[2J");
        return $this;
    }
    /**
     * Returns the current cursor position as x,y coordinates.
     */
    public function getCurrentPosition() : array
    {
        static $isTtySupported;
        if (null === $isTtySupported && \function_exists('proc_open')) {
            $isTtySupported = (bool) @\proc_open('echo 1 >/dev/null', [['file', '/dev/tty', 'r'], ['file', '/dev/tty', 'w'], ['file', '/dev/tty', 'w']], $pipes);
        }
        if (!$isTtySupported) {
            return [1, 1];
        }
        $sttyMode = \shell_exec('stty -g');
        \shell_exec('stty -icanon -echo');
        @\fwrite($this->input, "\x1b[6n");
        $code = \trim(\fread($this->input, 1024));
        \shell_exec(\sprintf('stty %s', $sttyMode));
        \sscanf($code, "\x1b[%d;%dR", $row, $col);
        return [$col, $row];
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
/**
 * JSON descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class JsonDescriptor extends Descriptor
{
    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        $this->writeData($this->getInputArgumentData($argument), $options);
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        $this->writeData($this->getInputOptionData($option), $options);
        if ($option->isNegatable()) {
            $this->writeData($this->getInputOptionData($option, \true), $options);
        }
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        $this->writeData($this->getInputDefinitionData($definition), $options);
    }
    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        $this->writeData($this->getCommandData($command, $options['short'] ?? \false), $options);
    }
    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $describedNamespace = $options['namespace'] ?? null;
        $description = new ApplicationDescription($application, $describedNamespace, \true);
        $commands = [];
        foreach ($description->getCommands() as $command) {
            $commands[] = $this->getCommandData($command, $options['short'] ?? \false);
        }
        $data = [];
        if ('UNKNOWN' !== $application->getName()) {
            $data['application']['name'] = $application->getName();
            if ('UNKNOWN' !== $application->getVersion()) {
                $data['application']['version'] = $application->getVersion();
            }
        }
        $data['commands'] = $commands;
        if ($describedNamespace) {
            $data['namespace'] = $describedNamespace;
        } else {
            $data['namespaces'] = \array_values($description->getNamespaces());
        }
        $this->writeData($data, $options);
    }
    /**
     * Writes data as json.
     */
    private function writeData(array $data, array $options)
    {
        $flags = $options['json_encoding'] ?? 0;
        $this->write(\json_encode($data, $flags));
    }
    private function getInputArgumentData(InputArgument $argument) : array
    {
        return ['name' => $argument->getName(), 'is_required' => $argument->isRequired(), 'is_array' => $argument->isArray(), 'description' => \preg_replace('/\\s*[\\r\\n]\\s*/', ' ', $argument->getDescription()), 'default' => \INF === $argument->getDefault() ? 'INF' : $argument->getDefault()];
    }
    private function getInputOptionData(InputOption $option, bool $negated = \false) : array
    {
        return $negated ? ['name' => '--no-' . $option->getName(), 'shortcut' => '', 'accept_value' => \false, 'is_value_required' => \false, 'is_multiple' => \false, 'description' => 'Negate the "--' . $option->getName() . '" option', 'default' => \false] : ['name' => '--' . $option->getName(), 'shortcut' => $option->getShortcut() ? '-' . \str_replace('|', '|-', $option->getShortcut()) : '', 'accept_value' => $option->acceptValue(), 'is_value_required' => $option->isValueRequired(), 'is_multiple' => $option->isArray(), 'description' => \preg_replace('/\\s*[\\r\\n]\\s*/', ' ', $option->getDescription()), 'default' => \INF === $option->getDefault() ? 'INF' : $option->getDefault()];
    }
    private function getInputDefinitionData(InputDefinition $definition) : array
    {
        $inputArguments = [];
        foreach ($definition->getArguments() as $name => $argument) {
            $inputArguments[$name] = $this->getInputArgumentData($argument);
        }
        $inputOptions = [];
        foreach ($definition->getOptions() as $name => $option) {
            $inputOptions[$name] = $this->getInputOptionData($option);
            if ($option->isNegatable()) {
                $inputOptions['no-' . $name] = $this->getInputOptionData($option, \true);
            }
        }
        return ['arguments' => $inputArguments, 'options' => $inputOptions];
    }
    private function getCommandData(Command $command, bool $short = \false) : array
    {
        $data = ['name' => $command->getName(), 'description' => $command->getDescription()];
        if ($short) {
            $data += ['usage' => $command->getAliases()];
        } else {
            $command->mergeApplicationDefinition(\false);
            $data += ['usage' => \array_merge([$command->getSynopsis()], $command->getUsages(), $command->getAliases()), 'help' => $command->getProcessedHelp(), 'definition' => $this->getInputDefinitionData($command->getDefinition())];
        }
        $data['hidden'] = $command->isHidden();
        return $data;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\CommandNotFoundException;
/**
 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
 *
 * @internal
 */
class ApplicationDescription
{
    public const GLOBAL_NAMESPACE = '_global';
    private $application;
    private $namespace;
    private $showHidden;
    /**
     * @var array
     */
    private $namespaces;
    /**
     * @var array<string, Command>
     */
    private $commands;
    /**
     * @var array<string, Command>
     */
    private $aliases;
    public function __construct(Application $application, string $namespace = null, bool $showHidden = \false)
    {
        $this->application = $application;
        $this->namespace = $namespace;
        $this->showHidden = $showHidden;
    }
    public function getNamespaces() : array
    {
        if (null === $this->namespaces) {
            $this->inspectApplication();
        }
        return $this->namespaces;
    }
    /**
     * @return Command[]
     */
    public function getCommands() : array
    {
        if (null === $this->commands) {
            $this->inspectApplication();
        }
        return $this->commands;
    }
    /**
     * @throws CommandNotFoundException
     */
    public function getCommand(string $name) : Command
    {
        if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
            throw new CommandNotFoundException(\sprintf('Command "%s" does not exist.', $name));
        }
        return $this->commands[$name] ?? $this->aliases[$name];
    }
    private function inspectApplication()
    {
        $this->commands = [];
        $this->namespaces = [];
        $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null);
        foreach ($this->sortCommands($all) as $namespace => $commands) {
            $names = [];
            /** @var Command $command */
            foreach ($commands as $name => $command) {
                if (!$command->getName() || !$this->showHidden && $command->isHidden()) {
                    continue;
                }
                if ($command->getName() === $name) {
                    $this->commands[$name] = $command;
                } else {
                    $this->aliases[$name] = $command;
                }
                $names[] = $name;
            }
            $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];
        }
    }
    private function sortCommands(array $commands) : array
    {
        $namespacedCommands = [];
        $globalCommands = [];
        $sortedCommands = [];
        foreach ($commands as $name => $command) {
            $key = $this->application->extractNamespace($name, 1);
            if (\in_array($key, ['', self::GLOBAL_NAMESPACE], \true)) {
                $globalCommands[$name] = $command;
            } else {
                $namespacedCommands[$key][$name] = $command;
            }
        }
        if ($globalCommands) {
            \ksort($globalCommands);
            $sortedCommands[self::GLOBAL_NAMESPACE] = $globalCommands;
        }
        if ($namespacedCommands) {
            \ksort($namespacedCommands, \SORT_STRING);
            foreach ($namespacedCommands as $key => $commandsSet) {
                \ksort($commandsSet);
                $sortedCommands[$key] = $commandsSet;
            }
        }
        return $sortedCommands;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
/**
 * XML descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class XmlDescriptor extends Descriptor
{
    public function getInputDefinitionDocument(InputDefinition $definition) : \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($definitionXML = $dom->createElement('definition'));
        $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments'));
        foreach ($definition->getArguments() as $argument) {
            $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument));
        }
        $definitionXML->appendChild($optionsXML = $dom->createElement('options'));
        foreach ($definition->getOptions() as $option) {
            $this->appendDocument($optionsXML, $this->getInputOptionDocument($option));
        }
        return $dom;
    }
    public function getCommandDocument(Command $command, bool $short = \false) : \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($commandXML = $dom->createElement('command'));
        $commandXML->setAttribute('id', $command->getName());
        $commandXML->setAttribute('name', $command->getName());
        $commandXML->setAttribute('hidden', $command->isHidden() ? 1 : 0);
        $commandXML->appendChild($usagesXML = $dom->createElement('usages'));
        $commandXML->appendChild($descriptionXML = $dom->createElement('description'));
        $descriptionXML->appendChild($dom->createTextNode(\str_replace("\n", "\n ", $command->getDescription())));
        if ($short) {
            foreach ($command->getAliases() as $usage) {
                $usagesXML->appendChild($dom->createElement('usage', $usage));
            }
        } else {
            $command->mergeApplicationDefinition(\false);
            foreach (\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()) as $usage) {
                $usagesXML->appendChild($dom->createElement('usage', $usage));
            }
            $commandXML->appendChild($helpXML = $dom->createElement('help'));
            $helpXML->appendChild($dom->createTextNode(\str_replace("\n", "\n ", $command->getProcessedHelp())));
            $definitionXML = $this->getInputDefinitionDocument($command->getDefinition());
            $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0));
        }
        return $dom;
    }
    public function getApplicationDocument(Application $application, string $namespace = null, bool $short = \false) : \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($rootXml = $dom->createElement('symfony'));
        if ('UNKNOWN' !== $application->getName()) {
            $rootXml->setAttribute('name', $application->getName());
            if ('UNKNOWN' !== $application->getVersion()) {
                $rootXml->setAttribute('version', $application->getVersion());
            }
        }
        $rootXml->appendChild($commandsXML = $dom->createElement('commands'));
        $description = new ApplicationDescription($application, $namespace, \true);
        if ($namespace) {
            $commandsXML->setAttribute('namespace', $namespace);
        }
        foreach ($description->getCommands() as $command) {
            $this->appendDocument($commandsXML, $this->getCommandDocument($command, $short));
        }
        if (!$namespace) {
            $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces'));
            foreach ($description->getNamespaces() as $namespaceDescription) {
                $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace'));
                $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']);
                foreach ($namespaceDescription['commands'] as $name) {
                    $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command'));
                    $commandXML->appendChild($dom->createTextNode($name));
                }
            }
        }
        return $dom;
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        $this->writeDocument($this->getInputArgumentDocument($argument));
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        $this->writeDocument($this->getInputOptionDocument($option));
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        $this->writeDocument($this->getInputDefinitionDocument($definition));
    }
    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        $this->writeDocument($this->getCommandDocument($command, $options['short'] ?? \false));
    }
    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $this->writeDocument($this->getApplicationDocument($application, $options['namespace'] ?? null, $options['short'] ?? \false));
    }
    /**
     * Appends document children to parent node.
     */
    private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent)
    {
        foreach ($importedParent->childNodes as $childNode) {
            $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, \true));
        }
    }
    /**
     * Writes DOM document.
     */
    private function writeDocument(\DOMDocument $dom)
    {
        $dom->formatOutput = \true;
        $this->write($dom->saveXML());
    }
    private function getInputArgumentDocument(InputArgument $argument) : \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($objectXML = $dom->createElement('argument'));
        $objectXML->setAttribute('name', $argument->getName());
        $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0);
        $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0);
        $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
        $descriptionXML->appendChild($dom->createTextNode($argument->getDescription()));
        $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
        $defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? [\var_export($argument->getDefault(), \true)] : ($argument->getDefault() ? [$argument->getDefault()] : []));
        foreach ($defaults as $default) {
            $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
            $defaultXML->appendChild($dom->createTextNode($default));
        }
        return $dom;
    }
    private function getInputOptionDocument(InputOption $option) : \DOMDocument
    {
        $dom = new \DOMDocument('1.0', 'UTF-8');
        $dom->appendChild($objectXML = $dom->createElement('option'));
        $objectXML->setAttribute('name', '--' . $option->getName());
        $pos = \strpos($option->getShortcut() ?? '', '|');
        if (\false !== $pos) {
            $objectXML->setAttribute('shortcut', '-' . \substr($option->getShortcut(), 0, $pos));
            $objectXML->setAttribute('shortcuts', '-' . \str_replace('|', '|-', $option->getShortcut()));
        } else {
            $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-' . $option->getShortcut() : '');
        }
        $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0);
        $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0);
        $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0);
        $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
        $descriptionXML->appendChild($dom->createTextNode($option->getDescription()));
        if ($option->acceptValue()) {
            $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [\var_export($option->getDefault(), \true)] : ($option->getDefault() ? [$option->getDefault()] : []));
            $objectXML->appendChild($defaultsXML = $dom->createElement('defaults'));
            if (!empty($defaults)) {
                foreach ($defaults as $default) {
                    $defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
                    $defaultXML->appendChild($dom->createTextNode($default));
                }
            }
        }
        if ($option->isNegatable()) {
            $dom->appendChild($objectXML = $dom->createElement('option'));
            $objectXML->setAttribute('name', '--no-' . $option->getName());
            $objectXML->setAttribute('shortcut', '');
            $objectXML->setAttribute('accept_value', 0);
            $objectXML->setAttribute('is_value_required', 0);
            $objectXML->setAttribute('is_multiple', 0);
            $objectXML->appendChild($descriptionXML = $dom->createElement('description'));
            $descriptionXML->appendChild($dom->createTextNode('Negate the "--' . $option->getName() . '" option'));
        }
        return $dom;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\Helper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Markdown descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class MarkdownDescriptor extends Descriptor
{
    /**
     * {@inheritdoc}
     */
    public function describe(OutputInterface $output, object $object, array $options = [])
    {
        $decorated = $output->isDecorated();
        $output->setDecorated(\false);
        parent::describe($output, $object, $options);
        $output->setDecorated($decorated);
    }
    /**
     * {@inheritdoc}
     */
    protected function write(string $content, bool $decorated = \true)
    {
        parent::write($content, $decorated);
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        $this->write('#### `' . ($argument->getName() ?: '<none>') . "`\n\n" . ($argument->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $argument->getDescription()) . "\n\n" : '') . '* Is required: ' . ($argument->isRequired() ? 'yes' : 'no') . "\n" . '* Is array: ' . ($argument->isArray() ? 'yes' : 'no') . "\n" . '* Default: `' . \str_replace("\n", '', \var_export($argument->getDefault(), \true)) . '`');
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        $name = '--' . $option->getName();
        if ($option->isNegatable()) {
            $name .= '|--no-' . $option->getName();
        }
        if ($option->getShortcut()) {
            $name .= '|-' . \str_replace('|', '|-', $option->getShortcut()) . '';
        }
        $this->write('#### `' . $name . '`' . "\n\n" . ($option->getDescription() ? \preg_replace('/\\s*[\\r\\n]\\s*/', "\n", $option->getDescription()) . "\n\n" : '') . '* Accept value: ' . ($option->acceptValue() ? 'yes' : 'no') . "\n" . '* Is value required: ' . ($option->isValueRequired() ? 'yes' : 'no') . "\n" . '* Is multiple: ' . ($option->isArray() ? 'yes' : 'no') . "\n" . '* Is negatable: ' . ($option->isNegatable() ? 'yes' : 'no') . "\n" . '* Default: `' . \str_replace("\n", '', \var_export($option->getDefault(), \true)) . '`');
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        if ($showArguments = \count($definition->getArguments()) > 0) {
            $this->write('### Arguments');
            foreach ($definition->getArguments() as $argument) {
                $this->write("\n\n");
                if (null !== ($describeInputArgument = $this->describeInputArgument($argument))) {
                    $this->write($describeInputArgument);
                }
            }
        }
        if (\count($definition->getOptions()) > 0) {
            if ($showArguments) {
                $this->write("\n\n");
            }
            $this->write('### Options');
            foreach ($definition->getOptions() as $option) {
                $this->write("\n\n");
                if (null !== ($describeInputOption = $this->describeInputOption($option))) {
                    $this->write($describeInputOption);
                }
            }
        }
    }
    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        if ($options['short'] ?? \false) {
            $this->write('`' . $command->getName() . "`\n" . \str_repeat('-', Helper::width($command->getName()) + 2) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . '### Usage' . "\n\n" . \array_reduce($command->getAliases(), function ($carry, $usage) {
                return $carry . '* `' . $usage . '`' . "\n";
            }));
            return;
        }
        $command->mergeApplicationDefinition(\false);
        $this->write('`' . $command->getName() . "`\n" . \str_repeat('-', Helper::width($command->getName()) + 2) . "\n\n" . ($command->getDescription() ? $command->getDescription() . "\n\n" : '') . '### Usage' . "\n\n" . \array_reduce(\array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) {
            return $carry . '* `' . $usage . '`' . "\n";
        }));
        if ($help = $command->getProcessedHelp()) {
            $this->write("\n");
            $this->write($help);
        }
        $definition = $command->getDefinition();
        if ($definition->getOptions() || $definition->getArguments()) {
            $this->write("\n\n");
            $this->describeInputDefinition($definition);
        }
    }
    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $describedNamespace = $options['namespace'] ?? null;
        $description = new ApplicationDescription($application, $describedNamespace);
        $title = $this->getApplicationTitle($application);
        $this->write($title . "\n" . \str_repeat('=', Helper::width($title)));
        foreach ($description->getNamespaces() as $namespace) {
            if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
                $this->write("\n\n");
                $this->write('**' . $namespace['id'] . ':**');
            }
            $this->write("\n\n");
            $this->write(\implode("\n", \array_map(function ($commandName) use($description) {
                return \sprintf('* [`%s`](#%s)', $commandName, \str_replace(':', '', $description->getCommand($commandName)->getName()));
            }, $namespace['commands'])));
        }
        foreach ($description->getCommands() as $command) {
            $this->write("\n\n");
            if (null !== ($describeCommand = $this->describeCommand($command, $options))) {
                $this->write($describeCommand);
            }
        }
    }
    private function getApplicationTitle(Application $application) : string
    {
        if ('UNKNOWN' !== $application->getName()) {
            if ('UNKNOWN' !== $application->getVersion()) {
                return \sprintf('%s %s', $application->getName(), $application->getVersion());
            }
            return $application->getName();
        }
        return 'Console Tool';
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Formatter\OutputFormatter;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\Helper;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
/**
 * Text descriptor.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 *
 * @internal
 */
class TextDescriptor extends Descriptor
{
    /**
     * {@inheritdoc}
     */
    protected function describeInputArgument(InputArgument $argument, array $options = [])
    {
        if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) {
            $default = \sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));
        } else {
            $default = '';
        }
        $totalWidth = $options['total_width'] ?? Helper::width($argument->getName());
        $spacingWidth = $totalWidth - \strlen($argument->getName());
        $this->writeText(\sprintf(
            '  <info>%s</info>  %s%s%s',
            $argument->getName(),
            \str_repeat(' ', $spacingWidth),
            // + 4 = 2 spaces before <info>, 2 spaces after </info>
            \preg_replace('/\\s*[\\r\\n]\\s*/', "\n" . \str_repeat(' ', $totalWidth + 4), $argument->getDescription()),
            $default
        ), $options);
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputOption(InputOption $option, array $options = [])
    {
        if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) {
            $default = \sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));
        } else {
            $default = '';
        }
        $value = '';
        if ($option->acceptValue()) {
            $value = '=' . \strtoupper($option->getName());
            if ($option->isValueOptional()) {
                $value = '[' . $value . ']';
            }
        }
        $totalWidth = $options['total_width'] ?? $this->calculateTotalWidthForOptions([$option]);
        $synopsis = \sprintf('%s%s', $option->getShortcut() ? \sprintf('-%s, ', $option->getShortcut()) : '    ', \sprintf($option->isNegatable() ? '--%1$s|--no-%1$s' : '--%1$s%2$s', $option->getName(), $value));
        $spacingWidth = $totalWidth - Helper::width($synopsis);
        $this->writeText(\sprintf(
            '  <info>%s</info>  %s%s%s%s',
            $synopsis,
            \str_repeat(' ', $spacingWidth),
            // + 4 = 2 spaces before <info>, 2 spaces after </info>
            \preg_replace('/\\s*[\\r\\n]\\s*/', "\n" . \str_repeat(' ', $totalWidth + 4), $option->getDescription()),
            $default,
            $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''
        ), $options);
    }
    /**
     * {@inheritdoc}
     */
    protected function describeInputDefinition(InputDefinition $definition, array $options = [])
    {
        $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());
        foreach ($definition->getArguments() as $argument) {
            $totalWidth = \max($totalWidth, Helper::width($argument->getName()));
        }
        if ($definition->getArguments()) {
            $this->writeText('<comment>Arguments:</comment>', $options);
            $this->writeText("\n");
            foreach ($definition->getArguments() as $argument) {
                $this->describeInputArgument($argument, \array_merge($options, ['total_width' => $totalWidth]));
                $this->writeText("\n");
            }
        }
        if ($definition->getArguments() && $definition->getOptions()) {
            $this->writeText("\n");
        }
        if ($definition->getOptions()) {
            $laterOptions = [];
            $this->writeText('<comment>Options:</comment>', $options);
            foreach ($definition->getOptions() as $option) {
                if (\strlen($option->getShortcut() ?? '') > 1) {
                    $laterOptions[] = $option;
                    continue;
                }
                $this->writeText("\n");
                $this->describeInputOption($option, \array_merge($options, ['total_width' => $totalWidth]));
            }
            foreach ($laterOptions as $option) {
                $this->writeText("\n");
                $this->describeInputOption($option, \array_merge($options, ['total_width' => $totalWidth]));
            }
        }
    }
    /**
     * {@inheritdoc}
     */
    protected function describeCommand(Command $command, array $options = [])
    {
        $command->mergeApplicationDefinition(\false);
        if ($description = $command->getDescription()) {
            $this->writeText('<comment>Description:</comment>', $options);
            $this->writeText("\n");
            $this->writeText('  ' . $description);
            $this->writeText("\n\n");
        }
        $this->writeText('<comment>Usage:</comment>', $options);
        foreach (\array_merge([$command->getSynopsis(\true)], $command->getAliases(), $command->getUsages()) as $usage) {
            $this->writeText("\n");
            $this->writeText('  ' . OutputFormatter::escape($usage), $options);
        }
        $this->writeText("\n");
        $definition = $command->getDefinition();
        if ($definition->getOptions() || $definition->getArguments()) {
            $this->writeText("\n");
            $this->describeInputDefinition($definition, $options);
            $this->writeText("\n");
        }
        $help = $command->getProcessedHelp();
        if ($help && $help !== $description) {
            $this->writeText("\n");
            $this->writeText('<comment>Help:</comment>', $options);
            $this->writeText("\n");
            $this->writeText('  ' . \str_replace("\n", "\n  ", $help), $options);
            $this->writeText("\n");
        }
    }
    /**
     * {@inheritdoc}
     */
    protected function describeApplication(Application $application, array $options = [])
    {
        $describedNamespace = $options['namespace'] ?? null;
        $description = new ApplicationDescription($application, $describedNamespace);
        if (isset($options['raw_text']) && $options['raw_text']) {
            $width = $this->getColumnWidth($description->getCommands());
            foreach ($description->getCommands() as $command) {
                $this->writeText(\sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options);
                $this->writeText("\n");
            }
        } else {
            if ('' != ($help = $application->getHelp())) {
                $this->writeText("{$help}\n\n", $options);
            }
            $this->writeText("<comment>Usage:</comment>\n", $options);
            $this->writeText("  command [options] [arguments]\n\n", $options);
            $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options);
            $this->writeText("\n");
            $this->writeText("\n");
            $commands = $description->getCommands();
            $namespaces = $description->getNamespaces();
            if ($describedNamespace && $namespaces) {
                // make sure all alias commands are included when describing a specific namespace
                $describedNamespaceInfo = \reset($namespaces);
                foreach ($describedNamespaceInfo['commands'] as $name) {
                    $commands[$name] = $description->getCommand($name);
                }
            }
            // calculate max. width based on available commands per namespace
            $width = $this->getColumnWidth(\array_merge(...\array_values(\array_map(function ($namespace) use($commands) {
                return \array_intersect($namespace['commands'], \array_keys($commands));
            }, \array_values($namespaces)))));
            if ($describedNamespace) {
                $this->writeText(\sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
            } else {
                $this->writeText('<comment>Available commands:</comment>', $options);
            }
            foreach ($namespaces as $namespace) {
                $namespace['commands'] = \array_filter($namespace['commands'], function ($name) use($commands) {
                    return isset($commands[$name]);
                });
                if (!$namespace['commands']) {
                    continue;
                }
                if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) {
                    $this->writeText("\n");
                    $this->writeText(' <comment>' . $namespace['id'] . '</comment>', $options);
                }
                foreach ($namespace['commands'] as $name) {
                    $this->writeText("\n");
                    $spacingWidth = $width - Helper::width($name);
                    $command = $commands[$name];
                    $commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : '';
                    $this->writeText(\sprintf('  <info>%s</info>%s%s', $name, \str_repeat(' ', $spacingWidth), $commandAliases . $command->getDescription()), $options);
                }
            }
            $this->writeText("\n");
        }
    }
    /**
     * {@inheritdoc}
     */
    private function writeText(string $content, array $options = [])
    {
        $this->write(isset($options['raw_text']) && $options['raw_text'] ? \strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : \true);
    }
    /**
     * Formats command aliases to show them in the command description.
     */
    private function getCommandAliasesText(Command $command) : string
    {
        $text = '';
        $aliases = $command->getAliases();
        if ($aliases) {
            $text = '[' . \implode('|', $aliases) . '] ';
        }
        return $text;
    }
    /**
     * Formats input option/argument default value.
     *
     * @param mixed $default
     */
    private function formatDefaultValue($default) : string
    {
        if (\INF === $default) {
            return 'INF';
        }
        if (\is_string($default)) {
            $default = OutputFormatter::escape($default);
        } elseif (\is_array($default)) {
            foreach ($default as $key => $value) {
                if (\is_string($value)) {
                    $default[$key] = OutputFormatter::escape($value);
                }
            }
        }
        return \str_replace('\\\\', '\\', \json_encode($default, \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE));
    }
    /**
     * @param array<Command|string> $commands
     */
    private function getColumnWidth(array $commands) : int
    {
        $widths = [];
        foreach ($commands as $command) {
            if ($command instanceof Command) {
                $widths[] = Helper::width($command->getName());
                foreach ($command->getAliases() as $alias) {
                    $widths[] = Helper::width($alias);
                }
            } else {
                $widths[] = Helper::width($command);
            }
        }
        return $widths ? \max($widths) + 2 : 0;
    }
    /**
     * @param InputOption[] $options
     */
    private function calculateTotalWidthForOptions(array $options) : int
    {
        $totalWidth = 0;
        foreach ($options as $option) {
            // "-" + shortcut + ", --" + name
            $nameLength = 1 + \max(Helper::width($option->getShortcut()), 1) + 4 + Helper::width($option->getName());
            if ($option->isNegatable()) {
                $nameLength += 6 + Helper::width($option->getName());
                // |--no- + name
            } elseif ($option->acceptValue()) {
                $valueLength = 1 + Helper::width($option->getName());
                // = + value
                $valueLength += $option->isValueOptional() ? 2 : 0;
                // [ + ]
                $nameLength += $valueLength;
            }
            $totalWidth = \max($totalWidth, $nameLength);
        }
        return $totalWidth;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputDefinition;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
 *
 * @internal
 */
abstract class Descriptor implements DescriptorInterface
{
    /**
     * @var OutputInterface
     */
    protected $output;
    /**
     * {@inheritdoc}
     */
    public function describe(OutputInterface $output, object $object, array $options = [])
    {
        $this->output = $output;
        switch (\true) {
            case $object instanceof InputArgument:
                $this->describeInputArgument($object, $options);
                break;
            case $object instanceof InputOption:
                $this->describeInputOption($object, $options);
                break;
            case $object instanceof InputDefinition:
                $this->describeInputDefinition($object, $options);
                break;
            case $object instanceof Command:
                $this->describeCommand($object, $options);
                break;
            case $object instanceof Application:
                $this->describeApplication($object, $options);
                break;
            default:
                throw new InvalidArgumentException(\sprintf('Object of type "%s" is not describable.', \get_debug_type($object)));
        }
    }
    /**
     * Writes content to output.
     */
    protected function write(string $content, bool $decorated = \false)
    {
        $this->output->write($content, \false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
    }
    /**
     * Describes an InputArgument instance.
     */
    protected abstract function describeInputArgument(InputArgument $argument, array $options = []);
    /**
     * Describes an InputOption instance.
     */
    protected abstract function describeInputOption(InputOption $option, array $options = []);
    /**
     * Describes an InputDefinition instance.
     */
    protected abstract function describeInputDefinition(InputDefinition $definition, array $options = []);
    /**
     * Describes a Command instance.
     */
    protected abstract function describeCommand(Command $command, array $options = []);
    /**
     * Describes an Application instance.
     */
    protected abstract function describeApplication(Application $application, array $options = []);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Descriptor;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
/**
 * Descriptor interface.
 *
 * @author Jean-François Simon <contact@jfsimon.fr>
 */
interface DescriptorInterface
{
    public function describe(OutputInterface $output, object $object, array $options = []);
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Slugger;

use _HumbugBox1cb33d1f20f1\Symfony\Component\String\AbstractUnicodeString;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\UnicodeString;
use _HumbugBox1cb33d1f20f1\Symfony\Contracts\Translation\LocaleAwareInterface;
if (!\interface_exists(LocaleAwareInterface::class)) {
    throw new \LogicException('You cannot use the "Symfony\\Component\\String\\Slugger\\AsciiSlugger" as the "symfony/translation-contracts" package is not installed. Try running "composer require symfony/translation-contracts".');
}
/**
 * @author Titouan Galopin <galopintitouan@gmail.com>
 */
class AsciiSlugger implements SluggerInterface, LocaleAwareInterface
{
    private const LOCALE_TO_TRANSLITERATOR_ID = ['am' => 'Amharic-Latin', 'ar' => 'Arabic-Latin', 'az' => 'Azerbaijani-Latin', 'be' => 'Belarusian-Latin', 'bg' => 'Bulgarian-Latin', 'bn' => 'Bengali-Latin', 'de' => 'de-ASCII', 'el' => 'Greek-Latin', 'fa' => 'Persian-Latin', 'he' => 'Hebrew-Latin', 'hy' => 'Armenian-Latin', 'ka' => 'Georgian-Latin', 'kk' => 'Kazakh-Latin', 'ky' => 'Kirghiz-Latin', 'ko' => 'Korean-Latin', 'mk' => 'Macedonian-Latin', 'mn' => 'Mongolian-Latin', 'or' => 'Oriya-Latin', 'ps' => 'Pashto-Latin', 'ru' => 'Russian-Latin', 'sr' => 'Serbian-Latin', 'sr_Cyrl' => 'Serbian-Latin', 'th' => 'Thai-Latin', 'tk' => 'Turkmen-Latin', 'uk' => 'Ukrainian-Latin', 'uz' => 'Uzbek-Latin', 'zh' => 'Han-Latin'];
    private $defaultLocale;
    private $symbolsMap = ['en' => ['@' => 'at', '&' => 'and']];
    /**
     * Cache of transliterators per locale.
     *
     * @var \Transliterator[]
     */
    private $transliterators = [];
    /**
     * @param array|\Closure|null $symbolsMap
     */
    public function __construct(string $defaultLocale = null, $symbolsMap = null)
    {
        if (null !== $symbolsMap && !\is_array($symbolsMap) && !$symbolsMap instanceof \Closure) {
            throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be array, Closure or null, "%s" given.', __METHOD__, \gettype($symbolsMap)));
        }
        $this->defaultLocale = $defaultLocale;
        $this->symbolsMap = $symbolsMap ?? $this->symbolsMap;
    }
    /**
     * {@inheritdoc}
     */
    public function setLocale($locale)
    {
        $this->defaultLocale = $locale;
    }
    /**
     * {@inheritdoc}
     */
    public function getLocale()
    {
        return $this->defaultLocale;
    }
    /**
     * {@inheritdoc}
     */
    public function slug(string $string, string $separator = '-', string $locale = null) : AbstractUnicodeString
    {
        $locale = $locale ?? $this->defaultLocale;
        $transliterator = [];
        if ($locale && ('de' === $locale || 0 === \strpos($locale, 'de_'))) {
            // Use the shortcut for German in UnicodeString::ascii() if possible (faster and no requirement on intl)
            $transliterator = ['de-ASCII'];
        } elseif (\function_exists('transliterator_transliterate') && $locale) {
            $transliterator = (array) $this->createTransliterator($locale);
        }
        if ($this->symbolsMap instanceof \Closure) {
            // If the symbols map is passed as a closure, there is no need to fallback to the parent locale
            // as the closure can just provide substitutions for all locales of interest.
            $symbolsMap = $this->symbolsMap;
            \array_unshift($transliterator, static function ($s) use($symbolsMap, $locale) {
                return $symbolsMap($s, $locale);
            });
        }
        $unicodeString = (new UnicodeString($string))->ascii($transliterator);
        if (\is_array($this->symbolsMap)) {
            $map = null;
            if (isset($this->symbolsMap[$locale])) {
                $map = $this->symbolsMap[$locale];
            } else {
                $parent = self::getParentLocale($locale);
                if ($parent && isset($this->symbolsMap[$parent])) {
                    $map = $this->symbolsMap[$parent];
                }
            }
            if ($map) {
                foreach ($map as $char => $replace) {
                    $unicodeString = $unicodeString->replace($char, ' ' . $replace . ' ');
                }
            }
        }
        return $unicodeString->replaceMatches('/[^A-Za-z0-9]++/', $separator)->trim($separator);
    }
    private function createTransliterator(string $locale) : ?\Transliterator
    {
        if (\array_key_exists($locale, $this->transliterators)) {
            return $this->transliterators[$locale];
        }
        // Exact locale supported, cache and return
        if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$locale] ?? null) {
            return $this->transliterators[$locale] = \Transliterator::create($id . '/BGN') ?? \Transliterator::create($id);
        }
        // Locale not supported and no parent, fallback to any-latin
        if (!($parent = self::getParentLocale($locale))) {
            return $this->transliterators[$locale] = null;
        }
        // Try to use the parent locale (ie. try "de" for "de_AT") and cache both locales
        if ($id = self::LOCALE_TO_TRANSLITERATOR_ID[$parent] ?? null) {
            $transliterator = \Transliterator::create($id . '/BGN') ?? \Transliterator::create($id);
        }
        return $this->transliterators[$locale] = $this->transliterators[$parent] = $transliterator ?? null;
    }
    private static function getParentLocale(?string $locale) : ?string
    {
        if (!$locale) {
            return null;
        }
        if (\false === ($str = \strrchr($locale, '_'))) {
            // no parent locale
            return null;
        }
        return \substr($locale, 0, -\strlen($str));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Slugger;

use _HumbugBox1cb33d1f20f1\Symfony\Component\String\AbstractUnicodeString;
/**
 * Creates a URL-friendly slug from a given string.
 *
 * @author Titouan Galopin <galopintitouan@gmail.com>
 */
interface SluggerInterface
{
    /**
     * Creates a slug for the given string and locale, using appropriate transliteration when needed.
     */
    public function slug(string $string, string $separator = '-', string $locale = null) : AbstractUnicodeString;
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String;

/**
 * A string whose value is computed lazily by a callback.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class LazyString implements \Stringable, \JsonSerializable
{
    private $value;
    /**
     * @param callable|array $callback A callable or a [Closure, method] lazy-callable
     *
     * @return static
     */
    public static function fromCallable($callback, ...$arguments) : self
    {
        if (!\is_callable($callback) && !(\is_array($callback) && isset($callback[0]) && $callback[0] instanceof \Closure && 2 >= \count($callback))) {
            throw new \TypeError(\sprintf('Argument 1 passed to "%s()" must be a callable or a [Closure, method] lazy-callable, "%s" given.', __METHOD__, \get_debug_type($callback)));
        }
        $lazyString = new static();
        $lazyString->value = static function () use(&$callback, &$arguments, &$value) : string {
            if (null !== $arguments) {
                if (!\is_callable($callback)) {
                    $callback[0] = $callback[0]();
                    $callback[1] = $callback[1] ?? '__invoke';
                }
                $value = $callback(...$arguments);
                $callback = self::getPrettyName($callback);
                $arguments = null;
            }
            return $value ?? '';
        };
        return $lazyString;
    }
    /**
     * @param string|int|float|bool|\Stringable $value
     *
     * @return static
     */
    public static function fromStringable($value) : self
    {
        if (!self::isStringable($value)) {
            throw new \TypeError(\sprintf('Argument 1 passed to "%s()" must be a scalar or a stringable object, "%s" given.', __METHOD__, \get_debug_type($value)));
        }
        if (\is_object($value)) {
            return static::fromCallable([$value, '__toString']);
        }
        $lazyString = new static();
        $lazyString->value = (string) $value;
        return $lazyString;
    }
    /**
     * Tells whether the provided value can be cast to string.
     */
    public static final function isStringable($value) : bool
    {
        return \is_string($value) || $value instanceof self || (\is_object($value) ? \method_exists($value, '__toString') : \is_scalar($value));
    }
    /**
     * Casts scalars and stringable objects to strings.
     *
     * @param object|string|int|float|bool $value
     *
     * @throws \TypeError When the provided value is not stringable
     */
    public static final function resolve($value) : string
    {
        return $value;
    }
    /**
     * @return string
     */
    public function __toString()
    {
        if (\is_string($this->value)) {
            return $this->value;
        }
        try {
            return $this->value = ($this->value)();
        } catch (\Throwable $e) {
            if (\TypeError::class === \get_class($e) && __FILE__ === $e->getFile()) {
                $type = \explode(', ', $e->getMessage());
                $type = \substr(\array_pop($type), 0, -\strlen(' returned'));
                $r = new \ReflectionFunction($this->value);
                $callback = $r->getStaticVariables()['callback'];
                $e = new \TypeError(\sprintf('Return value of %s() passed to %s::fromCallable() must be of the type string, %s returned.', $callback, static::class, $type));
            }
            if (\PHP_VERSION_ID < 70400) {
                // leverage the ErrorHandler component with graceful fallback when it's not available
                return \trigger_error($e, \E_USER_ERROR);
            }
            throw $e;
        }
    }
    public function __sleep() : array
    {
        $this->__toString();
        return ['value'];
    }
    public function jsonSerialize() : string
    {
        return $this->__toString();
    }
    private function __construct()
    {
    }
    private static function getPrettyName(callable $callback) : string
    {
        if (\is_string($callback)) {
            return $callback;
        }
        if (\is_array($callback)) {
            $class = \is_object($callback[0]) ? \get_debug_type($callback[0]) : $callback[0];
            $method = $callback[1];
        } elseif ($callback instanceof \Closure) {
            $r = new \ReflectionFunction($callback);
            if (\false !== \strpos($r->name, '{closure}') || !($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass())) {
                return $r->name;
            }
            $class = $class->name;
            $method = $r->name;
        } else {
            $class = \get_debug_type($callback);
            $method = '__invoke';
        }
        return $class . '::' . $method;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Inflector;

/**
 * French inflector.
 *
 * This class does only inflect nouns; not adjectives nor composed words like "soixante-dix".
 */
final class FrenchInflector implements InflectorInterface
{
    /**
     * A list of all rules for pluralise.
     *
     * @see https://la-conjugaison.nouvelobs.com/regles/grammaire/le-pluriel-des-noms-121.php
     */
    private const PLURALIZE_REGEXP = [
        // First entry: regexp
        // Second entry: replacement
        // Words finishing with "s", "x" or "z" are invariables
        // Les mots finissant par "s", "x" ou "z" sont invariables
        ['/(s|x|z)$/i', '\\1'],
        // Words finishing with "eau" are pluralized with a "x"
        // Les mots finissant par "eau" prennent tous un "x" au pluriel
        ['/(eau)$/i', '\\1x'],
        // Words finishing with "au" are pluralized with a "x" excepted "landau"
        // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau"
        ['/^(landau)$/i', '\\1s'],
        ['/(au)$/i', '\\1x'],
        // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu"
        // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu"
        ['/^(pneu|bleu|émeu)$/i', '\\1s'],
        ['/(eu)$/i', '\\1x'],
        // Words finishing with "al" are pluralized with a "aux" excepted
        // Les mots finissant en "al" se terminent en "aux" sauf
        ['/^(bal|carnaval|caracal|chacal|choral|corral|étal|festival|récital|val)$/i', '\\1s'],
        ['/al$/i', '\\1aux'],
        // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux
        ['/^(aspir|b|cor|ém|ferm|soupir|trav|vant|vitr)ail$/i', '\\1aux'],
        // Bijou, caillou, chou, genou, hibou, joujou et pou qui prennent un x au pluriel
        ['/^(bij|caill|ch|gen|hib|jouj|p)ou$/i', '\\1oux'],
        // Invariable words
        ['/^(cinquante|soixante|mille)$/i', '\\1'],
        // French titles
        ['/^(mon|ma)(sieur|dame|demoiselle|seigneur)$/', '_HumbugBox1cb33d1f20f1\\mes\\2s'],
        ['/^(Mon|Ma)(sieur|dame|demoiselle|seigneur)$/', '_HumbugBox1cb33d1f20f1\\Mes\\2s'],
    ];
    /**
     * A list of all rules for singularize.
     */
    private const SINGULARIZE_REGEXP = [
        // First entry: regexp
        // Second entry: replacement
        // Aspirail, bail, corail, émail, fermail, soupirail, travail, vantail et vitrail font leur pluriel en -aux
        ['/((aspir|b|cor|ém|ferm|soupir|trav|vant|vitr))aux$/i', '\\1ail'],
        // Words finishing with "eau" are pluralized with a "x"
        // Les mots finissant par "eau" prennent tous un "x" au pluriel
        ['/(eau)x$/i', '\\1'],
        // Words finishing with "al" are pluralized with a "aux" expected
        // Les mots finissant en "al" se terminent en "aux" sauf
        ['/(amir|anim|arsen|boc|can|capit|capor|chev|crist|génér|hopit|hôpit|idé|journ|littor|loc|m|mét|minér|princip|radic|termin)aux$/i', '\\1al'],
        // Words finishing with "au" are pluralized with a "x" excepted "landau"
        // Les mots finissant par "au" prennent un "x" au pluriel sauf "landau"
        ['/(au)x$/i', '\\1'],
        // Words finishing with "eu" are pluralized with a "x" excepted "pneu", "bleu", "émeu"
        // Les mots finissant en "eu" prennent un "x" au pluriel sauf "pneu", "bleu", "émeu"
        ['/(eu)x$/i', '\\1'],
        //  Words finishing with "ou" are pluralized with a "s" excepted bijou, caillou, chou, genou, hibou, joujou, pou
        // Les mots finissant par "ou" prennent un "s" sauf bijou, caillou, chou, genou, hibou, joujou, pou
        ['/(bij|caill|ch|gen|hib|jouj|p)oux$/i', '\\1ou'],
        // French titles
        ['/^mes(dame|demoiselle)s$/', '_HumbugBox1cb33d1f20f1\\ma\\1'],
        ['/^Mes(dame|demoiselle)s$/', '_HumbugBox1cb33d1f20f1\\Ma\\1'],
        ['/^mes(sieur|seigneur)s$/', '_HumbugBox1cb33d1f20f1\\mon\\1'],
        ['/^Mes(sieur|seigneur)s$/', '_HumbugBox1cb33d1f20f1\\Mon\\1'],
        // Default rule
        ['/s$/i', ''],
    ];
    /**
     * A list of words which should not be inflected.
     * This list is only used by singularize.
     */
    private const UNINFLECTED = '/^(abcès|accès|abus|albatros|anchois|anglais|autobus|bois|brebis|carquois|cas|chas|colis|concours|corps|cours|cyprès|décès|devis|discours|dos|embarras|engrais|entrelacs|excès|fils|fois|gâchis|gars|glas|héros|intrus|jars|jus|kermès|lacis|legs|lilas|marais|mars|matelas|mépris|mets|mois|mors|obus|os|palais|paradis|parcours|pardessus|pays|plusieurs|poids|pois|pouls|printemps|processus|progrès|puits|pus|rabais|radis|recors|recours|refus|relais|remords|remous|rictus|rhinocéros|repas|rubis|sans|sas|secours|sens|souris|succès|talus|tapis|tas|taudis|temps|tiers|univers|velours|verglas|vernis|virus)$/i';
    /**
     * {@inheritdoc}
     */
    public function singularize(string $plural) : array
    {
        if ($this->isInflectedWord($plural)) {
            return [$plural];
        }
        foreach (self::SINGULARIZE_REGEXP as $rule) {
            [$regexp, $replace] = $rule;
            if (1 === \preg_match($regexp, $plural)) {
                return [\preg_replace($regexp, $replace, $plural)];
            }
        }
        return [$plural];
    }
    /**
     * {@inheritdoc}
     */
    public function pluralize(string $singular) : array
    {
        if ($this->isInflectedWord($singular)) {
            return [$singular];
        }
        foreach (self::PLURALIZE_REGEXP as $rule) {
            [$regexp, $replace] = $rule;
            if (1 === \preg_match($regexp, $singular)) {
                return [\preg_replace($regexp, $replace, $singular)];
            }
        }
        return [$singular . 's'];
    }
    private function isInflectedWord(string $word) : bool
    {
        return 1 === \preg_match(self::UNINFLECTED, $word);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Inflector;

interface InflectorInterface
{
    /**
     * Returns the singular forms of a string.
     *
     * If the method can't determine the form with certainty, several possible singulars are returned.
     *
     * @return string[]
     */
    public function singularize(string $plural) : array;
    /**
     * Returns the plural forms of a string.
     *
     * If the method can't determine the form with certainty, several possible plurals are returned.
     *
     * @return string[]
     */
    public function pluralize(string $singular) : array;
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Inflector;

final class EnglishInflector implements InflectorInterface
{
    /**
     * Map English plural to singular suffixes.
     *
     * @see http://english-zone.com/spelling/plurals.html
     */
    private const PLURAL_MAP = [
        // First entry: plural suffix, reversed
        // Second entry: length of plural suffix
        // Third entry: Whether the suffix may succeed a vocal
        // Fourth entry: Whether the suffix may succeed a consonant
        // Fifth entry: singular suffix, normal
        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['a', 1, \true, \true, ['on', 'um']],
        // nebulae (nebula)
        ['ea', 2, \true, \true, 'a'],
        // services (service)
        ['secivres', 8, \true, \true, 'service'],
        // mice (mouse), lice (louse)
        ['eci', 3, \false, \true, 'ouse'],
        // geese (goose)
        ['esee', 4, \false, \true, 'oose'],
        // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius)
        ['i', 1, \true, \true, 'us'],
        // men (man), women (woman)
        ['nem', 3, \true, \true, 'man'],
        // children (child)
        ['nerdlihc', 8, \true, \true, 'child'],
        // oxen (ox)
        ['nexo', 4, \false, \false, 'ox'],
        // indices (index), appendices (appendix), prices (price)
        ['seci', 4, \false, \true, ['ex', 'ix', 'ice']],
        // selfies (selfie)
        ['seifles', 7, \true, \true, 'selfie'],
        // zombies (zombie)
        ['seibmoz', 7, \true, \true, 'zombie'],
        // movies (movie)
        ['seivom', 6, \true, \true, 'movie'],
        // conspectuses (conspectus), prospectuses (prospectus)
        ['sesutcep', 8, \true, \true, 'pectus'],
        // feet (foot)
        ['teef', 4, \true, \true, 'foot'],
        // geese (goose)
        ['eseeg', 5, \true, \true, 'goose'],
        // teeth (tooth)
        ['hteet', 5, \true, \true, 'tooth'],
        // news (news)
        ['swen', 4, \true, \true, 'news'],
        // series (series)
        ['seires', 6, \true, \true, 'series'],
        // babies (baby)
        ['sei', 3, \false, \true, 'y'],
        // accesses (access), addresses (address), kisses (kiss)
        ['sess', 4, \true, \false, 'ss'],
        // analyses (analysis), ellipses (ellipsis), fungi (fungus),
        // neuroses (neurosis), theses (thesis), emphases (emphasis),
        // oases (oasis), crises (crisis), houses (house), bases (base),
        // atlases (atlas)
        ['ses', 3, \true, \true, ['s', 'se', 'sis']],
        // objectives (objective), alternative (alternatives)
        ['sevit', 5, \true, \true, 'tive'],
        // drives (drive)
        ['sevird', 6, \false, \true, 'drive'],
        // lives (life), wives (wife)
        ['sevi', 4, \false, \true, 'ife'],
        // moves (move)
        ['sevom', 5, \true, \true, 'move'],
        // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf), caves (cave), staves (staff)
        ['sev', 3, \true, \true, ['f', 've', 'ff']],
        // axes (axis), axes (ax), axes (axe)
        ['sexa', 4, \false, \false, ['ax', 'axe', 'axis']],
        // indexes (index), matrixes (matrix)
        ['sex', 3, \true, \false, 'x'],
        // quizzes (quiz)
        ['sezz', 4, \true, \false, 'z'],
        // bureaus (bureau)
        ['suae', 4, \false, \true, 'eau'],
        // fees (fee), trees (tree), employees (employee)
        ['see', 3, \true, \true, 'ee'],
        // edges (edge)
        ['segd', 4, \true, \true, 'dge'],
        // roses (rose), garages (garage), cassettes (cassette),
        // waltzes (waltz), heroes (hero), bushes (bush), arches (arch),
        // shoes (shoe)
        ['se', 2, \true, \true, ['', 'e']],
        // tags (tag)
        ['s', 1, \true, \true, ''],
        // chateaux (chateau)
        ['xuae', 4, \false, \true, 'eau'],
        // people (person)
        ['elpoep', 6, \true, \true, 'person'],
    ];
    /**
     * Map English singular to plural suffixes.
     *
     * @see http://english-zone.com/spelling/plurals.html
     */
    private const SINGULAR_MAP = [
        // First entry: singular suffix, reversed
        // Second entry: length of singular suffix
        // Third entry: Whether the suffix may succeed a vocal
        // Fourth entry: Whether the suffix may succeed a consonant
        // Fifth entry: plural suffix, normal
        // criterion (criteria)
        ['airetirc', 8, \false, \false, 'criterion'],
        // nebulae (nebula)
        ['aluben', 6, \false, \false, 'nebulae'],
        // children (child)
        ['dlihc', 5, \true, \true, 'children'],
        // prices (price)
        ['eci', 3, \false, \true, 'ices'],
        // services (service)
        ['ecivres', 7, \true, \true, 'services'],
        // lives (life), wives (wife)
        ['efi', 3, \false, \true, 'ives'],
        // selfies (selfie)
        ['eifles', 6, \true, \true, 'selfies'],
        // movies (movie)
        ['eivom', 5, \true, \true, 'movies'],
        // lice (louse)
        ['esuol', 5, \false, \true, 'lice'],
        // mice (mouse)
        ['esuom', 5, \false, \true, 'mice'],
        // geese (goose)
        ['esoo', 4, \false, \true, 'eese'],
        // houses (house), bases (base)
        ['es', 2, \true, \true, 'ses'],
        // geese (goose)
        ['esoog', 5, \true, \true, 'geese'],
        // caves (cave)
        ['ev', 2, \true, \true, 'ves'],
        // drives (drive)
        ['evird', 5, \false, \true, 'drives'],
        // objectives (objective), alternative (alternatives)
        ['evit', 4, \true, \true, 'tives'],
        // moves (move)
        ['evom', 4, \true, \true, 'moves'],
        // staves (staff)
        ['ffats', 5, \true, \true, 'staves'],
        // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf)
        ['ff', 2, \true, \true, 'ffs'],
        // hooves (hoof), dwarves (dwarf), elves (elf), leaves (leaf)
        ['f', 1, \true, \true, ['fs', 'ves']],
        // arches (arch)
        ['hc', 2, \true, \true, 'ches'],
        // bushes (bush)
        ['hs', 2, \true, \true, 'shes'],
        // teeth (tooth)
        ['htoot', 5, \true, \true, 'teeth'],
        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['mu', 2, \true, \true, 'a'],
        // men (man), women (woman)
        ['nam', 3, \true, \true, 'men'],
        // people (person)
        ['nosrep', 6, \true, \true, ['persons', 'people']],
        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['noi', 3, \true, \true, 'ions'],
        // coupon (coupons)
        ['nop', 3, \true, \true, 'pons'],
        // seasons (season), treasons (treason), poisons (poison), lessons (lesson)
        ['nos', 3, \true, \true, 'sons'],
        // bacteria (bacterium), criteria (criterion), phenomena (phenomenon)
        ['no', 2, \true, \true, 'a'],
        // echoes (echo)
        ['ohce', 4, \true, \true, 'echoes'],
        // heroes (hero)
        ['oreh', 4, \true, \true, 'heroes'],
        // atlases (atlas)
        ['salta', 5, \true, \true, 'atlases'],
        // irises (iris)
        ['siri', 4, \true, \true, 'irises'],
        // analyses (analysis), ellipses (ellipsis), neuroses (neurosis)
        // theses (thesis), emphases (emphasis), oases (oasis),
        // crises (crisis)
        ['sis', 3, \true, \true, 'ses'],
        // accesses (access), addresses (address), kisses (kiss)
        ['ss', 2, \true, \false, 'sses'],
        // syllabi (syllabus)
        ['suballys', 8, \true, \true, 'syllabi'],
        // buses (bus)
        ['sub', 3, \true, \true, 'buses'],
        // circuses (circus)
        ['suc', 3, \true, \true, 'cuses'],
        // conspectuses (conspectus), prospectuses (prospectus)
        ['sutcep', 6, \true, \true, 'pectuses'],
        // fungi (fungus), alumni (alumnus), syllabi (syllabus), radii (radius)
        ['su', 2, \true, \true, 'i'],
        // news (news)
        ['swen', 4, \true, \true, 'news'],
        // feet (foot)
        ['toof', 4, \true, \true, 'feet'],
        // chateaux (chateau), bureaus (bureau)
        ['uae', 3, \false, \true, ['eaus', 'eaux']],
        // oxen (ox)
        ['xo', 2, \false, \false, 'oxen'],
        // hoaxes (hoax)
        ['xaoh', 4, \true, \false, 'hoaxes'],
        // indices (index)
        ['xedni', 5, \false, \true, ['indicies', 'indexes']],
        // boxes (box)
        ['xo', 2, \false, \true, 'oxes'],
        // indexes (index), matrixes (matrix)
        ['x', 1, \true, \false, ['cies', 'xes']],
        // appendices (appendix)
        ['xi', 2, \false, \true, 'ices'],
        // babies (baby)
        ['y', 1, \false, \true, 'ies'],
        // quizzes (quiz)
        ['ziuq', 4, \true, \false, 'quizzes'],
        // waltzes (waltz)
        ['z', 1, \true, \true, 'zes'],
    ];
    /**
     * A list of words which should not be inflected, reversed.
     */
    private const UNINFLECTED = [
        '',
        // data
        'atad',
        // deer
        'reed',
        // feedback
        'kcabdeef',
        // fish
        'hsif',
        // info
        'ofni',
        // moose
        'esoom',
        // series
        'seires',
        // sheep
        'peehs',
        // species
        'seiceps',
    ];
    /**
     * {@inheritdoc}
     */
    public function singularize(string $plural) : array
    {
        $pluralRev = \strrev($plural);
        $lowerPluralRev = \strtolower($pluralRev);
        $pluralLength = \strlen($lowerPluralRev);
        // Check if the word is one which is not inflected, return early if so
        if (\in_array($lowerPluralRev, self::UNINFLECTED, \true)) {
            return [$plural];
        }
        // The outer loop iterates over the entries of the plural table
        // The inner loop $j iterates over the characters of the plural suffix
        // in the plural table to compare them with the characters of the actual
        // given plural suffix
        foreach (self::PLURAL_MAP as $map) {
            $suffix = $map[0];
            $suffixLength = $map[1];
            $j = 0;
            // Compare characters in the plural table and of the suffix of the
            // given plural one by one
            while ($suffix[$j] === $lowerPluralRev[$j]) {
                // Let $j point to the next character
                ++$j;
                // Successfully compared the last character
                // Add an entry with the singular suffix to the singular array
                if ($j === $suffixLength) {
                    // Is there any character preceding the suffix in the plural string?
                    if ($j < $pluralLength) {
                        $nextIsVocal = \false !== \strpos('aeiou', $lowerPluralRev[$j]);
                        if (!$map[2] && $nextIsVocal) {
                            // suffix may not succeed a vocal but next char is one
                            break;
                        }
                        if (!$map[3] && !$nextIsVocal) {
                            // suffix may not succeed a consonant but next char is one
                            break;
                        }
                    }
                    $newBase = \substr($plural, 0, $pluralLength - $suffixLength);
                    $newSuffix = $map[4];
                    // Check whether the first character in the plural suffix
                    // is uppercased. If yes, uppercase the first character in
                    // the singular suffix too
                    $firstUpper = \ctype_upper($pluralRev[$j - 1]);
                    if (\is_array($newSuffix)) {
                        $singulars = [];
                        foreach ($newSuffix as $newSuffixEntry) {
                            $singulars[] = $newBase . ($firstUpper ? \ucfirst($newSuffixEntry) : $newSuffixEntry);
                        }
                        return $singulars;
                    }
                    return [$newBase . ($firstUpper ? \ucfirst($newSuffix) : $newSuffix)];
                }
                // Suffix is longer than word
                if ($j === $pluralLength) {
                    break;
                }
            }
        }
        // Assume that plural and singular is identical
        return [$plural];
    }
    /**
     * {@inheritdoc}
     */
    public function pluralize(string $singular) : array
    {
        $singularRev = \strrev($singular);
        $lowerSingularRev = \strtolower($singularRev);
        $singularLength = \strlen($lowerSingularRev);
        // Check if the word is one which is not inflected, return early if so
        if (\in_array($lowerSingularRev, self::UNINFLECTED, \true)) {
            return [$singular];
        }
        // The outer loop iterates over the entries of the singular table
        // The inner loop $j iterates over the characters of the singular suffix
        // in the singular table to compare them with the characters of the actual
        // given singular suffix
        foreach (self::SINGULAR_MAP as $map) {
            $suffix = $map[0];
            $suffixLength = $map[1];
            $j = 0;
            // Compare characters in the singular table and of the suffix of the
            // given plural one by one
            while ($suffix[$j] === $lowerSingularRev[$j]) {
                // Let $j point to the next character
                ++$j;
                // Successfully compared the last character
                // Add an entry with the plural suffix to the plural array
                if ($j === $suffixLength) {
                    // Is there any character preceding the suffix in the plural string?
                    if ($j < $singularLength) {
                        $nextIsVocal = \false !== \strpos('aeiou', $lowerSingularRev[$j]);
                        if (!$map[2] && $nextIsVocal) {
                            // suffix may not succeed a vocal but next char is one
                            break;
                        }
                        if (!$map[3] && !$nextIsVocal) {
                            // suffix may not succeed a consonant but next char is one
                            break;
                        }
                    }
                    $newBase = \substr($singular, 0, $singularLength - $suffixLength);
                    $newSuffix = $map[4];
                    // Check whether the first character in the singular suffix
                    // is uppercased. If yes, uppercase the first character in
                    // the singular suffix too
                    $firstUpper = \ctype_upper($singularRev[$j - 1]);
                    if (\is_array($newSuffix)) {
                        $plurals = [];
                        foreach ($newSuffix as $newSuffixEntry) {
                            $plurals[] = $newBase . ($firstUpper ? \ucfirst($newSuffixEntry) : $newSuffixEntry);
                        }
                        return $plurals;
                    }
                    return [$newBase . ($firstUpper ? \ucfirst($newSuffix) : $newSuffix)];
                }
                // Suffix is longer than word
                if ($j === $singularLength) {
                    break;
                }
            }
        }
        // Assume that plural is singular with a trailing `s`
        return [$singular . 's'];
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception;

interface ExceptionInterface extends \Throwable
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception;

class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception;

class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String;

use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\InvalidArgumentException;
/**
 * Represents a string of Unicode code points encoded as UTF-8.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
class CodePointString extends AbstractUnicodeString
{
    public function __construct(string $string = '')
    {
        if ('' !== $string && !\preg_match('//u', $string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        $this->string = $string;
    }
    public function append(string ...$suffix) : AbstractString
    {
        $str = clone $this;
        $str->string .= 1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix);
        if (!\preg_match('//u', $str->string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        return $str;
    }
    public function chunk(int $length = 1) : array
    {
        if (1 > $length) {
            throw new InvalidArgumentException('The chunk length must be greater than zero.');
        }
        if ('' === $this->string) {
            return [];
        }
        $rx = '/(';
        while (65535 < $length) {
            $rx .= '.{65535}';
            $length -= 65535;
        }
        $rx .= '.{' . $length . '})/us';
        $str = clone $this;
        $chunks = [];
        foreach (\preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) {
            $str->string = $chunk;
            $chunks[] = clone $str;
        }
        return $chunks;
    }
    public function codePointsAt(int $offset) : array
    {
        $str = $offset ? $this->slice($offset, 1) : $this;
        return '' === $str->string ? [] : [\mb_ord($str->string, 'UTF-8')];
    }
    public function endsWith($suffix) : bool
    {
        if ($suffix instanceof AbstractString) {
            $suffix = $suffix->string;
        } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
            return parent::endsWith($suffix);
        } else {
            $suffix = (string) $suffix;
        }
        if ('' === $suffix || !\preg_match('//u', $suffix)) {
            return \false;
        }
        if ($this->ignoreCase) {
            return \preg_match('{' . \preg_quote($suffix) . '$}iuD', $this->string);
        }
        return \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix));
    }
    public function equalsTo($string) : bool
    {
        if ($string instanceof AbstractString) {
            $string = $string->string;
        } elseif (\is_array($string) || $string instanceof \Traversable) {
            return parent::equalsTo($string);
        } else {
            $string = (string) $string;
        }
        if ('' !== $string && $this->ignoreCase) {
            return \strlen($string) === \strlen($this->string) && 0 === \mb_stripos($this->string, $string, 0, 'UTF-8');
        }
        return $string === $this->string;
    }
    public function indexOf($needle, int $offset = 0) : ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOf($needle, $offset);
        } else {
            $needle = (string) $needle;
        }
        if ('' === $needle) {
            return null;
        }
        $i = $this->ignoreCase ? \mb_stripos($this->string, $needle, $offset, 'UTF-8') : \mb_strpos($this->string, $needle, $offset, 'UTF-8');
        return \false === $i ? null : $i;
    }
    public function indexOfLast($needle, int $offset = 0) : ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOfLast($needle, $offset);
        } else {
            $needle = (string) $needle;
        }
        if ('' === $needle) {
            return null;
        }
        $i = $this->ignoreCase ? \mb_strripos($this->string, $needle, $offset, 'UTF-8') : \mb_strrpos($this->string, $needle, $offset, 'UTF-8');
        return \false === $i ? null : $i;
    }
    public function length() : int
    {
        return \mb_strlen($this->string, 'UTF-8');
    }
    public function prepend(string ...$prefix) : AbstractString
    {
        $str = clone $this;
        $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $this->string;
        if (!\preg_match('//u', $str->string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        return $str;
    }
    public function replace(string $from, string $to) : AbstractString
    {
        $str = clone $this;
        if ('' === $from || !\preg_match('//u', $from)) {
            return $str;
        }
        if ('' !== $to && !\preg_match('//u', $to)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        if ($this->ignoreCase) {
            $str->string = \implode($to, \preg_split('{' . \preg_quote($from) . '}iuD', $this->string));
        } else {
            $str->string = \str_replace($from, $to, $this->string);
        }
        return $str;
    }
    public function slice(int $start = 0, int $length = null) : AbstractString
    {
        $str = clone $this;
        $str->string = \mb_substr($this->string, $start, $length, 'UTF-8');
        return $str;
    }
    public function splice(string $replacement, int $start = 0, int $length = null) : AbstractString
    {
        if (!\preg_match('//u', $replacement)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        $str = clone $this;
        $start = $start ? \strlen(\mb_substr($this->string, 0, $start, 'UTF-8')) : 0;
        $length = $length ? \strlen(\mb_substr($this->string, $start, $length, 'UTF-8')) : $length;
        $str->string = \substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);
        return $str;
    }
    public function split(string $delimiter, int $limit = null, int $flags = null) : array
    {
        if (1 > ($limit = $limit ?? \PHP_INT_MAX)) {
            throw new InvalidArgumentException('Split limit must be a positive integer.');
        }
        if ('' === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is empty.');
        }
        if (null !== $flags) {
            return parent::split($delimiter . 'u', $limit, $flags);
        }
        if (!\preg_match('//u', $delimiter)) {
            throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.');
        }
        $str = clone $this;
        $chunks = $this->ignoreCase ? \preg_split('{' . \preg_quote($delimiter) . '}iuD', $this->string, $limit) : \explode($delimiter, $this->string, $limit);
        foreach ($chunks as &$chunk) {
            $str->string = $chunk;
            $chunk = clone $str;
        }
        return $chunks;
    }
    public function startsWith($prefix) : bool
    {
        if ($prefix instanceof AbstractString) {
            $prefix = $prefix->string;
        } elseif (\is_array($prefix) || $prefix instanceof \Traversable) {
            return parent::startsWith($prefix);
        } else {
            $prefix = (string) $prefix;
        }
        if ('' === $prefix || !\preg_match('//u', $prefix)) {
            return \false;
        }
        if ($this->ignoreCase) {
            return 0 === \mb_stripos($this->string, $prefix, 0, 'UTF-8');
        }
        return 0 === \strncmp($this->string, $prefix, \strlen($prefix));
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String;

use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\InvalidArgumentException;
/**
 * Represents a string of Unicode grapheme clusters encoded as UTF-8.
 *
 * A letter followed by combining characters (accents typically) form what Unicode defines
 * as a grapheme cluster: a character as humans mean it in written texts. This class knows
 * about the concept and won't split a letter apart from its combining accents. It also
 * ensures all string comparisons happen on their canonically-composed representation,
 * ignoring e.g. the order in which accents are listed when a letter has many of them.
 *
 * @see https://unicode.org/reports/tr15/
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
class UnicodeString extends AbstractUnicodeString
{
    public function __construct(string $string = '')
    {
        $this->string = \normalizer_is_normalized($string) ? $string : \normalizer_normalize($string);
        if (\false === $this->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
    }
    public function append(string ...$suffix) : AbstractString
    {
        $str = clone $this;
        $str->string = $this->string . (1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix));
        \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
        if (\false === $str->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        return $str;
    }
    public function chunk(int $length = 1) : array
    {
        if (1 > $length) {
            throw new InvalidArgumentException('The chunk length must be greater than zero.');
        }
        if ('' === $this->string) {
            return [];
        }
        $rx = '/(';
        while (65535 < $length) {
            $rx .= '\\X{65535}';
            $length -= 65535;
        }
        $rx .= '\\X{' . $length . '})/u';
        $str = clone $this;
        $chunks = [];
        foreach (\preg_split($rx, $this->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY) as $chunk) {
            $str->string = $chunk;
            $chunks[] = clone $str;
        }
        return $chunks;
    }
    public function endsWith($suffix) : bool
    {
        if ($suffix instanceof AbstractString) {
            $suffix = $suffix->string;
        } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
            return parent::endsWith($suffix);
        } else {
            $suffix = (string) $suffix;
        }
        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        \normalizer_is_normalized($suffix, $form) ?: ($suffix = \normalizer_normalize($suffix, $form));
        if ('' === $suffix || \false === $suffix) {
            return \false;
        }
        if ($this->ignoreCase) {
            return 0 === \mb_stripos(\grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix)), $suffix, 0, 'UTF-8');
        }
        return $suffix === \grapheme_extract($this->string, \strlen($suffix), \GRAPHEME_EXTR_MAXBYTES, \strlen($this->string) - \strlen($suffix));
    }
    public function equalsTo($string) : bool
    {
        if ($string instanceof AbstractString) {
            $string = $string->string;
        } elseif (\is_array($string) || $string instanceof \Traversable) {
            return parent::equalsTo($string);
        } else {
            $string = (string) $string;
        }
        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        \normalizer_is_normalized($string, $form) ?: ($string = \normalizer_normalize($string, $form));
        if ('' !== $string && \false !== $string && $this->ignoreCase) {
            return \strlen($string) === \strlen($this->string) && 0 === \mb_stripos($this->string, $string, 0, 'UTF-8');
        }
        return $string === $this->string;
    }
    public function indexOf($needle, int $offset = 0) : ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOf($needle, $offset);
        } else {
            $needle = (string) $needle;
        }
        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        \normalizer_is_normalized($needle, $form) ?: ($needle = \normalizer_normalize($needle, $form));
        if ('' === $needle || \false === $needle) {
            return null;
        }
        try {
            $i = $this->ignoreCase ? \grapheme_stripos($this->string, $needle, $offset) : \grapheme_strpos($this->string, $needle, $offset);
        } catch (\ValueError $e) {
            return null;
        }
        return \false === $i ? null : $i;
    }
    public function indexOfLast($needle, int $offset = 0) : ?int
    {
        if ($needle instanceof AbstractString) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOfLast($needle, $offset);
        } else {
            $needle = (string) $needle;
        }
        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        \normalizer_is_normalized($needle, $form) ?: ($needle = \normalizer_normalize($needle, $form));
        if ('' === $needle || \false === $needle) {
            return null;
        }
        $string = $this->string;
        if (0 > $offset) {
            // workaround https://bugs.php.net/74264
            if (0 > ($offset += \grapheme_strlen($needle))) {
                $string = \grapheme_substr($string, 0, $offset);
            }
            $offset = 0;
        }
        $i = $this->ignoreCase ? \grapheme_strripos($string, $needle, $offset) : \grapheme_strrpos($string, $needle, $offset);
        return \false === $i ? null : $i;
    }
    public function join(array $strings, string $lastGlue = null) : AbstractString
    {
        $str = parent::join($strings, $lastGlue);
        \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
        return $str;
    }
    public function length() : int
    {
        return \grapheme_strlen($this->string);
    }
    /**
     * @return static
     */
    public function normalize(int $form = self::NFC) : parent
    {
        $str = clone $this;
        if (\in_array($form, [self::NFC, self::NFKC], \true)) {
            \normalizer_is_normalized($str->string, $form) ?: ($str->string = \normalizer_normalize($str->string, $form));
        } elseif (!\in_array($form, [self::NFD, self::NFKD], \true)) {
            throw new InvalidArgumentException('Unsupported normalization form.');
        } elseif (!\normalizer_is_normalized($str->string, $form)) {
            $str->string = \normalizer_normalize($str->string, $form);
            $str->ignoreCase = null;
        }
        return $str;
    }
    public function prepend(string ...$prefix) : AbstractString
    {
        $str = clone $this;
        $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $this->string;
        \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
        if (\false === $str->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        return $str;
    }
    public function replace(string $from, string $to) : AbstractString
    {
        $str = clone $this;
        \normalizer_is_normalized($from) ?: ($from = \normalizer_normalize($from));
        if ('' !== $from && \false !== $from) {
            $tail = $str->string;
            $result = '';
            $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos';
            while ('' !== $tail && \false !== ($i = $indexOf($tail, $from))) {
                $slice = \grapheme_substr($tail, 0, $i);
                $result .= $slice . $to;
                $tail = \substr($tail, \strlen($slice) + \strlen($from));
            }
            $str->string = $result . $tail;
            \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
            if (\false === $str->string) {
                throw new InvalidArgumentException('Invalid UTF-8 string.');
            }
        }
        return $str;
    }
    public function replaceMatches(string $fromRegexp, $to) : AbstractString
    {
        $str = parent::replaceMatches($fromRegexp, $to);
        \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
        return $str;
    }
    public function slice(int $start = 0, int $length = null) : AbstractString
    {
        $str = clone $this;
        if (\PHP_VERSION_ID < 80000 && 0 > $start && \grapheme_strlen($this->string) < -$start) {
            $start = 0;
        }
        $str->string = (string) \grapheme_substr($this->string, $start, $length ?? 2147483647);
        return $str;
    }
    public function splice(string $replacement, int $start = 0, int $length = null) : AbstractString
    {
        $str = clone $this;
        if (\PHP_VERSION_ID < 80000 && 0 > $start && \grapheme_strlen($this->string) < -$start) {
            $start = 0;
        }
        $start = $start ? \strlen(\grapheme_substr($this->string, 0, $start)) : 0;
        $length = $length ? \strlen(\grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length;
        $str->string = \substr_replace($this->string, $replacement, $start, $length ?? 2147483647);
        \normalizer_is_normalized($str->string) ?: ($str->string = \normalizer_normalize($str->string));
        if (\false === $str->string) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        return $str;
    }
    public function split(string $delimiter, int $limit = null, int $flags = null) : array
    {
        if (1 > ($limit = $limit ?? 2147483647)) {
            throw new InvalidArgumentException('Split limit must be a positive integer.');
        }
        if ('' === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is empty.');
        }
        if (null !== $flags) {
            return parent::split($delimiter . 'u', $limit, $flags);
        }
        \normalizer_is_normalized($delimiter) ?: ($delimiter = \normalizer_normalize($delimiter));
        if (\false === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is not a valid UTF-8 string.');
        }
        $str = clone $this;
        $tail = $this->string;
        $chunks = [];
        $indexOf = $this->ignoreCase ? 'grapheme_stripos' : 'grapheme_strpos';
        while (1 < $limit && \false !== ($i = $indexOf($tail, $delimiter))) {
            $str->string = \grapheme_substr($tail, 0, $i);
            $chunks[] = clone $str;
            $tail = \substr($tail, \strlen($str->string) + \strlen($delimiter));
            --$limit;
        }
        $str->string = $tail;
        $chunks[] = clone $str;
        return $chunks;
    }
    public function startsWith($prefix) : bool
    {
        if ($prefix instanceof AbstractString) {
            $prefix = $prefix->string;
        } elseif (\is_array($prefix) || $prefix instanceof \Traversable) {
            return parent::startsWith($prefix);
        } else {
            $prefix = (string) $prefix;
        }
        $form = null === $this->ignoreCase ? \Normalizer::NFD : \Normalizer::NFC;
        \normalizer_is_normalized($prefix, $form) ?: ($prefix = \normalizer_normalize($prefix, $form));
        if ('' === $prefix || \false === $prefix) {
            return \false;
        }
        if ($this->ignoreCase) {
            return 0 === \mb_stripos(\grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES), $prefix, 0, 'UTF-8');
        }
        return $prefix === \grapheme_extract($this->string, \strlen($prefix), \GRAPHEME_EXTR_MAXBYTES);
    }
    public function __wakeup()
    {
        if (!\is_string($this->string)) {
            throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__);
        }
        \normalizer_is_normalized($this->string) ?: ($this->string = \normalizer_normalize($this->string));
    }
    public function __clone()
    {
        if (null === $this->ignoreCase) {
            \normalizer_is_normalized($this->string) ?: ($this->string = \normalizer_normalize($this->string));
        }
        $this->ignoreCase = \false;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String;

use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\RuntimeException;
/**
 * Represents a binary-safe string of bytes.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
class ByteString extends AbstractString
{
    private const ALPHABET_ALPHANUMERIC = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
    public function __construct(string $string = '')
    {
        $this->string = $string;
    }
    /*
     * The following method was derived from code of the Hack Standard Library (v4.40 - 2020-05-03)
     *
     * https://github.com/hhvm/hsl/blob/80a42c02f036f72a42f0415e80d6b847f4bf62d5/src/random/private.php#L16
     *
     * Code subject to the MIT license (https://github.com/hhvm/hsl/blob/master/LICENSE).
     *
     * Copyright (c) 2004-2020, Facebook, Inc. (https://www.facebook.com/)
     */
    public static function fromRandom(int $length = 16, string $alphabet = null) : self
    {
        if ($length <= 0) {
            throw new InvalidArgumentException(\sprintf('A strictly positive length is expected, "%d" given.', $length));
        }
        $alphabet = $alphabet ?? self::ALPHABET_ALPHANUMERIC;
        $alphabetSize = \strlen($alphabet);
        $bits = (int) \ceil(\log($alphabetSize, 2.0));
        if ($bits <= 0 || $bits > 56) {
            throw new InvalidArgumentException('The length of the alphabet must in the [2^1, 2^56] range.');
        }
        $ret = '';
        while ($length > 0) {
            $urandomLength = (int) \ceil(2 * $length * $bits / 8.0);
            $data = \random_bytes($urandomLength);
            $unpackedData = 0;
            $unpackedBits = 0;
            for ($i = 0; $i < $urandomLength && $length > 0; ++$i) {
                // Unpack 8 bits
                $unpackedData = $unpackedData << 8 | \ord($data[$i]);
                $unpackedBits += 8;
                // While we have enough bits to select a character from the alphabet, keep
                // consuming the random data
                for (; $unpackedBits >= $bits && $length > 0; $unpackedBits -= $bits) {
                    $index = $unpackedData & (1 << $bits) - 1;
                    $unpackedData >>= $bits;
                    // Unfortunately, the alphabet size is not necessarily a power of two.
                    // Worst case, it is 2^k + 1, which means we need (k+1) bits and we
                    // have around a 50% chance of missing as k gets larger
                    if ($index < $alphabetSize) {
                        $ret .= $alphabet[$index];
                        --$length;
                    }
                }
            }
        }
        return new static($ret);
    }
    public function bytesAt(int $offset) : array
    {
        $str = $this->string[$offset] ?? '';
        return '' === $str ? [] : [\ord($str)];
    }
    public function append(string ...$suffix) : parent
    {
        $str = clone $this;
        $str->string .= 1 >= \count($suffix) ? $suffix[0] ?? '' : \implode('', $suffix);
        return $str;
    }
    public function camel() : parent
    {
        $str = clone $this;
        $parts = \explode(' ', \trim(\ucwords(\preg_replace('/[^a-zA-Z0-9\\x7f-\\xff]++/', ' ', $this->string))));
        $parts[0] = 1 !== \strlen($parts[0]) && \ctype_upper($parts[0]) ? $parts[0] : \lcfirst($parts[0]);
        $str->string = \implode('', $parts);
        return $str;
    }
    public function chunk(int $length = 1) : array
    {
        if (1 > $length) {
            throw new InvalidArgumentException('The chunk length must be greater than zero.');
        }
        if ('' === $this->string) {
            return [];
        }
        $str = clone $this;
        $chunks = [];
        foreach (\str_split($this->string, $length) as $chunk) {
            $str->string = $chunk;
            $chunks[] = clone $str;
        }
        return $chunks;
    }
    public function endsWith($suffix) : bool
    {
        if ($suffix instanceof parent) {
            $suffix = $suffix->string;
        } elseif (\is_array($suffix) || $suffix instanceof \Traversable) {
            return parent::endsWith($suffix);
        } else {
            $suffix = (string) $suffix;
        }
        return '' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase);
    }
    public function equalsTo($string) : bool
    {
        if ($string instanceof parent) {
            $string = $string->string;
        } elseif (\is_array($string) || $string instanceof \Traversable) {
            return parent::equalsTo($string);
        } else {
            $string = (string) $string;
        }
        if ('' !== $string && $this->ignoreCase) {
            return 0 === \strcasecmp($string, $this->string);
        }
        return $string === $this->string;
    }
    public function folded() : parent
    {
        $str = clone $this;
        $str->string = \strtolower($str->string);
        return $str;
    }
    public function indexOf($needle, int $offset = 0) : ?int
    {
        if ($needle instanceof parent) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOf($needle, $offset);
        } else {
            $needle = (string) $needle;
        }
        if ('' === $needle) {
            return null;
        }
        $i = $this->ignoreCase ? \stripos($this->string, $needle, $offset) : \strpos($this->string, $needle, $offset);
        return \false === $i ? null : $i;
    }
    public function indexOfLast($needle, int $offset = 0) : ?int
    {
        if ($needle instanceof parent) {
            $needle = $needle->string;
        } elseif (\is_array($needle) || $needle instanceof \Traversable) {
            return parent::indexOfLast($needle, $offset);
        } else {
            $needle = (string) $needle;
        }
        if ('' === $needle) {
            return null;
        }
        $i = $this->ignoreCase ? \strripos($this->string, $needle, $offset) : \strrpos($this->string, $needle, $offset);
        return \false === $i ? null : $i;
    }
    public function isUtf8() : bool
    {
        return '' === $this->string || \preg_match('//u', $this->string);
    }
    public function join(array $strings, string $lastGlue = null) : parent
    {
        $str = clone $this;
        $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue . \array_pop($strings) : '';
        $str->string = \implode($this->string, $strings) . $tail;
        return $str;
    }
    public function length() : int
    {
        return \strlen($this->string);
    }
    public function lower() : parent
    {
        $str = clone $this;
        $str->string = \strtolower($str->string);
        return $str;
    }
    public function match(string $regexp, int $flags = 0, int $offset = 0) : array
    {
        $match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
        if ($this->ignoreCase) {
            $regexp .= 'i';
        }
        \set_error_handler(static function ($t, $m) {
            throw new InvalidArgumentException($m);
        });
        try {
            if (\false === $match($regexp, $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
                $lastError = \preg_last_error();
                foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
                        throw new RuntimeException('Matching failed with ' . $k . '.');
                    }
                }
                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            \restore_error_handler();
        }
        return $matches;
    }
    public function padBoth(int $length, string $padStr = ' ') : parent
    {
        $str = clone $this;
        $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_BOTH);
        return $str;
    }
    public function padEnd(int $length, string $padStr = ' ') : parent
    {
        $str = clone $this;
        $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_RIGHT);
        return $str;
    }
    public function padStart(int $length, string $padStr = ' ') : parent
    {
        $str = clone $this;
        $str->string = \str_pad($this->string, $length, $padStr, \STR_PAD_LEFT);
        return $str;
    }
    public function prepend(string ...$prefix) : parent
    {
        $str = clone $this;
        $str->string = (1 >= \count($prefix) ? $prefix[0] ?? '' : \implode('', $prefix)) . $str->string;
        return $str;
    }
    public function replace(string $from, string $to) : parent
    {
        $str = clone $this;
        if ('' !== $from) {
            $str->string = $this->ignoreCase ? \str_ireplace($from, $to, $this->string) : \str_replace($from, $to, $this->string);
        }
        return $str;
    }
    public function replaceMatches(string $fromRegexp, $to) : parent
    {
        if ($this->ignoreCase) {
            $fromRegexp .= 'i';
        }
        if (\is_array($to)) {
            if (!\is_callable($to)) {
                throw new \TypeError(\sprintf('Argument 2 passed to "%s::replaceMatches()" must be callable, array given.', static::class));
            }
            $replace = 'preg_replace_callback';
        } else {
            $replace = $to instanceof \Closure ? 'preg_replace_callback' : 'preg_replace';
        }
        \set_error_handler(static function ($t, $m) {
            throw new InvalidArgumentException($m);
        });
        try {
            if (null === ($string = $replace($fromRegexp, $to, $this->string))) {
                $lastError = \preg_last_error();
                foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
                        throw new RuntimeException('Matching failed with ' . $k . '.');
                    }
                }
                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            \restore_error_handler();
        }
        $str = clone $this;
        $str->string = $string;
        return $str;
    }
    public function reverse() : parent
    {
        $str = clone $this;
        $str->string = \strrev($str->string);
        return $str;
    }
    public function slice(int $start = 0, int $length = null) : parent
    {
        $str = clone $this;
        $str->string = (string) \substr($this->string, $start, $length ?? \PHP_INT_MAX);
        return $str;
    }
    public function snake() : parent
    {
        $str = $this->camel();
        $str->string = \strtolower(\preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\\d])([A-Z])/'], '_HumbugBox1cb33d1f20f1\\1_\\2', $str->string));
        return $str;
    }
    public function splice(string $replacement, int $start = 0, int $length = null) : parent
    {
        $str = clone $this;
        $str->string = \substr_replace($this->string, $replacement, $start, $length ?? \PHP_INT_MAX);
        return $str;
    }
    public function split(string $delimiter, int $limit = null, int $flags = null) : array
    {
        if (1 > ($limit = $limit ?? \PHP_INT_MAX)) {
            throw new InvalidArgumentException('Split limit must be a positive integer.');
        }
        if ('' === $delimiter) {
            throw new InvalidArgumentException('Split delimiter is empty.');
        }
        if (null !== $flags) {
            return parent::split($delimiter, $limit, $flags);
        }
        $str = clone $this;
        $chunks = $this->ignoreCase ? \preg_split('{' . \preg_quote($delimiter) . '}iD', $this->string, $limit) : \explode($delimiter, $this->string, $limit);
        foreach ($chunks as &$chunk) {
            $str->string = $chunk;
            $chunk = clone $str;
        }
        return $chunks;
    }
    public function startsWith($prefix) : bool
    {
        if ($prefix instanceof parent) {
            $prefix = $prefix->string;
        } elseif (!\is_string($prefix)) {
            return parent::startsWith($prefix);
        }
        return '' !== $prefix && 0 === ($this->ignoreCase ? \strncasecmp($this->string, $prefix, \strlen($prefix)) : \strncmp($this->string, $prefix, \strlen($prefix)));
    }
    public function title(bool $allWords = \false) : parent
    {
        $str = clone $this;
        $str->string = $allWords ? \ucwords($str->string) : \ucfirst($str->string);
        return $str;
    }
    public function toUnicodeString(string $fromEncoding = null) : UnicodeString
    {
        return new UnicodeString($this->toCodePointString($fromEncoding)->string);
    }
    public function toCodePointString(string $fromEncoding = null) : CodePointString
    {
        $u = new CodePointString();
        if (\in_array($fromEncoding, [null, 'utf8', 'utf-8', 'UTF8', 'UTF-8'], \true) && \preg_match('//u', $this->string)) {
            $u->string = $this->string;
            return $u;
        }
        \set_error_handler(static function ($t, $m) {
            throw new InvalidArgumentException($m);
        });
        try {
            try {
                $validEncoding = \false !== \mb_detect_encoding($this->string, $fromEncoding ?? 'Windows-1252', \true);
            } catch (InvalidArgumentException $e) {
                if (!\function_exists('iconv')) {
                    throw $e;
                }
                $u->string = \iconv($fromEncoding ?? 'Windows-1252', 'UTF-8', $this->string);
                return $u;
            }
        } finally {
            \restore_error_handler();
        }
        if (!$validEncoding) {
            throw new InvalidArgumentException(\sprintf('Invalid "%s" string.', $fromEncoding ?? 'Windows-1252'));
        }
        $u->string = \mb_convert_encoding($this->string, 'UTF-8', $fromEncoding ?? 'Windows-1252');
        return $u;
    }
    public function trim(string $chars = " \t\n\r\x00\v\f") : parent
    {
        $str = clone $this;
        $str->string = \trim($str->string, $chars);
        return $str;
    }
    public function trimEnd(string $chars = " \t\n\r\x00\v\f") : parent
    {
        $str = clone $this;
        $str->string = \rtrim($str->string, $chars);
        return $str;
    }
    public function trimStart(string $chars = " \t\n\r\x00\v\f") : parent
    {
        $str = clone $this;
        $str->string = \ltrim($str->string, $chars);
        return $str;
    }
    public function upper() : parent
    {
        $str = clone $this;
        $str->string = \strtoupper($str->string);
        return $str;
    }
    public function width(bool $ignoreAnsiDecoration = \true) : int
    {
        $string = \preg_match('//u', $this->string) ? $this->string : \preg_replace('/[\\x80-\\xFF]/', '?', $this->string);
        return (new CodePointString($string))->width($ignoreAnsiDecoration);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String;

use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\RuntimeException;
/**
 * Represents a string of abstract Unicode characters.
 *
 * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters).
 * This class is the abstract type to use as a type-hint when the logic you want to
 * implement is Unicode-aware but doesn't care about code points vs grapheme clusters.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @throws ExceptionInterface
 */
abstract class AbstractUnicodeString extends AbstractString
{
    public const NFC = \Normalizer::NFC;
    public const NFD = \Normalizer::NFD;
    public const NFKC = \Normalizer::NFKC;
    public const NFKD = \Normalizer::NFKD;
    // all ASCII letters sorted by typical frequency of occurrence
    private const ASCII = " eiasntrolud][cmp'\ng|hv.fb,:=-q10C2*yx)(L9AS/P\"EjMIk3>5T<D4}B{8FwR67UGN;JzV#HOW_&!K?XQ%Y\\\tZ+~^\$@`\x00\x01\x02\x03\x04\x05\x06\x07\x08\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
    // the subset of folded case mappings that is not in lower case mappings
    private const FOLD_FROM = ['İ', 'µ', 'ſ', "ͅ", 'ς', 'ϐ', 'ϑ', 'ϕ', 'ϖ', 'ϰ', 'ϱ', 'ϵ', 'ẛ', "ι", 'ß', 'İ', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'և', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ẞ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'ᾐ', 'ᾑ', 'ᾒ', 'ᾓ', 'ᾔ', 'ᾕ', 'ᾖ', 'ᾗ', 'ᾘ', 'ᾙ', 'ᾚ', 'ᾛ', 'ᾜ', 'ᾝ', 'ᾞ', 'ᾟ', 'ᾠ', 'ᾡ', 'ᾢ', 'ᾣ', 'ᾤ', 'ᾥ', 'ᾦ', 'ᾧ', 'ᾨ', 'ᾩ', 'ᾪ', 'ᾫ', 'ᾬ', 'ᾭ', 'ᾮ', 'ᾯ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'ᾼ', 'ῂ', 'ῃ', 'ῄ', 'ῆ', 'ῇ', 'ῌ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῲ', 'ῳ', 'ῴ', 'ῶ', 'ῷ', 'ῼ', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ'];
    private const FOLD_TO = ['i̇', 'μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', 'ṡ', 'ι', 'ss', 'i̇', 'ʼn', 'ǰ', 'ΐ', 'ΰ', 'եւ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'aʾ', 'ss', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἀι', 'ἁι', 'ἂι', 'ἃι', 'ἄι', 'ἅι', 'ἆι', 'ἇι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ἠι', 'ἡι', 'ἢι', 'ἣι', 'ἤι', 'ἥι', 'ἦι', 'ἧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὠι', 'ὡι', 'ὢι', 'ὣι', 'ὤι', 'ὥι', 'ὦι', 'ὧι', 'ὰι', 'αι', 'άι', 'ᾶ', 'ᾶι', 'αι', 'ὴι', 'ηι', 'ήι', 'ῆ', 'ῆι', 'ηι', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ὼι', 'ωι', 'ώι', 'ῶ', 'ῶι', 'ωι', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'st', 'st', 'մն', 'մե', 'մի', 'վն', 'մխ'];
    // the subset of upper case mappings that map one code point to many code points
    private const UPPER_FROM = ['ß', 'ff', 'fi', 'fl', 'ffi', 'ffl', 'ſt', 'st', 'և', 'ﬓ', 'ﬔ', 'ﬕ', 'ﬖ', 'ﬗ', 'ʼn', 'ΐ', 'ΰ', 'ǰ', 'ẖ', 'ẗ', 'ẘ', 'ẙ', 'ẚ', 'ὐ', 'ὒ', 'ὔ', 'ὖ', 'ᾶ', 'ῆ', 'ῒ', 'ΐ', 'ῖ', 'ῗ', 'ῢ', 'ΰ', 'ῤ', 'ῦ', 'ῧ', 'ῶ'];
    private const UPPER_TO = ['SS', 'FF', 'FI', 'FL', 'FFI', 'FFL', 'ST', 'ST', 'ԵՒ', 'ՄՆ', 'ՄԵ', 'ՄԻ', 'ՎՆ', 'ՄԽ', 'ʼN', 'Ϊ́', 'Ϋ́', 'J̌', 'H̱', 'T̈', 'W̊', 'Y̊', 'Aʾ', 'Υ̓', 'Υ̓̀', 'Υ̓́', 'Υ̓͂', 'Α͂', 'Η͂', 'Ϊ̀', 'Ϊ́', 'Ι͂', 'Ϊ͂', 'Ϋ̀', 'Ϋ́', 'Ρ̓', 'Υ͂', 'Ϋ͂', 'Ω͂'];
    // the subset of https://github.com/unicode-org/cldr/blob/master/common/transforms/Latin-ASCII.xml that is not in NFKD
    private const TRANSLIT_FROM = ['Æ', 'Ð', 'Ø', 'Þ', 'ß', 'æ', 'ð', 'ø', 'þ', 'Đ', 'đ', 'Ħ', 'ħ', 'ı', 'ĸ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'ʼn', 'Ŋ', 'ŋ', 'Œ', 'œ', 'Ŧ', 'ŧ', 'ƀ', 'Ɓ', 'Ƃ', 'ƃ', 'Ƈ', 'ƈ', 'Ɖ', 'Ɗ', 'Ƌ', 'ƌ', 'Ɛ', 'Ƒ', 'ƒ', 'Ɠ', 'ƕ', 'Ɩ', 'Ɨ', 'Ƙ', 'ƙ', 'ƚ', 'Ɲ', 'ƞ', 'Ƣ', 'ƣ', 'Ƥ', 'ƥ', 'ƫ', 'Ƭ', 'ƭ', 'Ʈ', 'Ʋ', 'Ƴ', 'ƴ', 'Ƶ', 'ƶ', 'DŽ', 'Dž', 'dž', 'Ǥ', 'ǥ', 'ȡ', 'Ȥ', 'ȥ', 'ȴ', 'ȵ', 'ȶ', 'ȷ', 'ȸ', 'ȹ', 'Ⱥ', 'Ȼ', 'ȼ', 'Ƚ', 'Ⱦ', 'ȿ', 'ɀ', 'Ƀ', 'Ʉ', 'Ɇ', 'ɇ', 'Ɉ', 'ɉ', 'Ɍ', 'ɍ', 'Ɏ', 'ɏ', 'ɓ', 'ɕ', 'ɖ', 'ɗ', 'ɛ', 'ɟ', 'ɠ', 'ɡ', 'ɢ', 'ɦ', 'ɧ', 'ɨ', 'ɪ', 'ɫ', 'ɬ', 'ɭ', 'ɱ', 'ɲ', 'ɳ', 'ɴ', 'ɶ', 'ɼ', 'ɽ', 'ɾ', 'ʀ', 'ʂ', 'ʈ', 'ʉ', 'ʋ', 'ʏ', 'ʐ', 'ʑ', 'ʙ', 'ʛ', 'ʜ', 'ʝ', 'ʟ', 'ʠ', 'ʣ', 'ʥ', 'ʦ', 'ʪ', 'ʫ', 'ᴀ', 'ᴁ', 'ᴃ', 'ᴄ', 'ᴅ', 'ᴆ', 'ᴇ', 'ᴊ', 'ᴋ', 'ᴌ', 'ᴍ', 'ᴏ', 'ᴘ', 'ᴛ', 'ᴜ', 'ᴠ', 'ᴡ', 'ᴢ', 'ᵫ', 'ᵬ', 'ᵭ', 'ᵮ', 'ᵯ', 'ᵰ', 'ᵱ', 'ᵲ', 'ᵳ', 'ᵴ', 'ᵵ', 'ᵶ', 'ᵺ', 'ᵻ', 'ᵽ', 'ᵾ', 'ᶀ', 'ᶁ', 'ᶂ', 'ᶃ', 'ᶄ', 'ᶅ', 'ᶆ', 'ᶇ', 'ᶈ', 'ᶉ', 'ᶊ', 'ᶌ', 'ᶍ', 'ᶎ', 'ᶏ', 'ᶑ', 'ᶒ', 'ᶓ', 'ᶖ', 'ᶙ', 'ẚ', 'ẜ', 'ẝ', 'ẞ', 'Ỻ', 'ỻ', 'Ỽ', 'ỽ', 'Ỿ', 'ỿ', '©', '®', '₠', '₢', '₣', '₤', '₧', '₺', '₹', 'ℌ', '℞', '㎧', '㎮', '㏆', '㏗', '㏞', '㏟', '¼', '½', '¾', '⅓', '⅔', '⅕', '⅖', '⅗', '⅘', '⅙', '⅚', '⅛', '⅜', '⅝', '⅞', '⅟', '〇', '‘', '’', '‚', '‛', '“', '”', '„', '‟', '′', '″', '〝', '〞', '«', '»', '‹', '›', '‐', '‑', '‒', '–', '—', '―', '︱', '︲', '﹘', '‖', '⁄', '⁅', '⁆', '⁎', '、', '。', '〈', '〉', '《', '》', '〔', '〕', '〘', '〙', '〚', '〛', '︑', '︒', '︹', '︺', '︽', '︾', '︿', '﹀', '﹑', '﹝', '﹞', '⦅', '⦆', '。', '、', '×', '÷', '−', '∕', '∖', '∣', '∥', '≪', '≫', '⦅', '⦆'];
    private const TRANSLIT_TO = ['AE', 'D', 'O', 'TH', 'ss', 'ae', 'd', 'o', 'th', 'D', 'd', 'H', 'h', 'i', 'q', 'L', 'l', 'L', 'l', '\'n', 'N', 'n', 'OE', 'oe', 'T', 't', 'b', 'B', 'B', 'b', 'C', 'c', 'D', 'D', 'D', 'd', 'E', 'F', 'f', 'G', 'hv', 'I', 'I', 'K', 'k', 'l', 'N', 'n', 'OI', 'oi', 'P', 'p', 't', 'T', 't', 'T', 'V', 'Y', 'y', 'Z', 'z', 'DZ', 'Dz', 'dz', 'G', 'g', 'd', 'Z', 'z', 'l', 'n', 't', 'j', 'db', 'qp', 'A', 'C', 'c', 'L', 'T', 's', 'z', 'B', 'U', 'E', 'e', 'J', 'j', 'R', 'r', 'Y', 'y', 'b', 'c', 'd', 'd', 'e', 'j', 'g', 'g', 'G', 'h', 'h', 'i', 'I', 'l', 'l', 'l', 'm', 'n', 'n', 'N', 'OE', 'r', 'r', 'r', 'R', 's', 't', 'u', 'v', 'Y', 'z', 'z', 'B', 'G', 'H', 'j', 'L', 'q', 'dz', 'dz', 'ts', 'ls', 'lz', 'A', 'AE', 'B', 'C', 'D', 'D', 'E', 'J', 'K', 'L', 'M', 'O', 'P', 'T', 'U', 'V', 'W', 'Z', 'ue', 'b', 'd', 'f', 'm', 'n', 'p', 'r', 'r', 's', 't', 'z', 'th', 'I', 'p', 'U', 'b', 'd', 'f', 'g', 'k', 'l', 'm', 'n', 'p', 'r', 's', 'v', 'x', 'z', 'a', 'd', 'e', 'e', 'i', 'u', 'a', 's', 's', 'SS', 'LL', 'll', 'V', 'v', 'Y', 'y', '(C)', '(R)', 'CE', 'Cr', 'Fr.', 'L.', 'Pts', 'TL', 'Rs', 'x', 'Rx', 'm/s', 'rad/s', 'C/kg', 'pH', 'V/m', 'A/m', ' 1/4', ' 1/2', ' 3/4', ' 1/3', ' 2/3', ' 1/5', ' 2/5', ' 3/5', ' 4/5', ' 1/6', ' 5/6', ' 1/8', ' 3/8', ' 5/8', ' 7/8', ' 1/', '0', '\'', '\'', ',', '\'', '"', '"', ',,', '"', '\'', '"', '"', '"', '<<', '>>', '<', '>', '-', '-', '-', '-', '-', '-', '-', '-', '-', '||', '/', '[', ']', '*', ',', '.', '<', '>', '<<', '>>', '[', ']', '[', ']', '[', ']', ',', '.', '[', ']', '<<', '>>', '<', '>', ',', '[', ']', '((', '))', '.', ',', '*', '/', '-', '/', '\\', '|', '||', '<<', '>>', '((', '))'];
    private static $transliterators = [];
    private static $tableZero;
    private static $tableWide;
    /**
     * @return static
     */
    public static function fromCodePoints(int ...$codes) : self
    {
        $string = '';
        foreach ($codes as $code) {
            if (0x80 > ($code %= 0x200000)) {
                $string .= \chr($code);
            } elseif (0x800 > $code) {
                $string .= \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f);
            } elseif (0x10000 > $code) {
                $string .= \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
            } else {
                $string .= \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
            }
        }
        return new static($string);
    }
    /**
     * Generic UTF-8 to ASCII transliteration.
     *
     * Install the intl extension for best results.
     *
     * @param string[]|\Transliterator[]|\Closure[] $rules See "*-Latin" rules from Transliterator::listIDs()
     */
    public function ascii(array $rules = []) : self
    {
        $str = clone $this;
        $s = $str->string;
        $str->string = '';
        \array_unshift($rules, 'nfd');
        $rules[] = 'latin-ascii';
        if (\function_exists('transliterator_transliterate')) {
            $rules[] = 'any-latin/bgn';
        }
        $rules[] = 'nfkd';
        $rules[] = '[:nonspacing mark:] remove';
        while (\strlen($s) - 1 > ($i = \strspn($s, self::ASCII))) {
            if (0 < --$i) {
                $str->string .= \substr($s, 0, $i);
                $s = \substr($s, $i);
            }
            if (!($rule = \array_shift($rules))) {
                $rules = [];
                // An empty rule interrupts the next ones
            }
            if ($rule instanceof \Transliterator) {
                $s = $rule->transliterate($s);
            } elseif ($rule instanceof \Closure) {
                $s = $rule($s);
            } elseif ($rule) {
                if ('nfd' === ($rule = \strtolower($rule))) {
                    \normalizer_is_normalized($s, self::NFD) ?: ($s = \normalizer_normalize($s, self::NFD));
                } elseif ('nfkd' === $rule) {
                    \normalizer_is_normalized($s, self::NFKD) ?: ($s = \normalizer_normalize($s, self::NFKD));
                } elseif ('[:nonspacing mark:] remove' === $rule) {
                    $s = \preg_replace('/\\p{Mn}++/u', '', $s);
                } elseif ('latin-ascii' === $rule) {
                    $s = \str_replace(self::TRANSLIT_FROM, self::TRANSLIT_TO, $s);
                } elseif ('de-ascii' === $rule) {
                    $s = \preg_replace("/([AUO])̈(?=\\p{Ll})/u", '$1e', $s);
                    $s = \str_replace(["ä", "ö", "ü", "Ä", "Ö", "Ü"], ['ae', 'oe', 'ue', 'AE', 'OE', 'UE'], $s);
                } elseif (\function_exists('transliterator_transliterate')) {
                    if (null === ($transliterator = self::$transliterators[$rule] ?? (self::$transliterators[$rule] = \Transliterator::create($rule)))) {
                        if ('any-latin/bgn' === $rule) {
                            $rule = 'any-latin';
                            $transliterator = self::$transliterators[$rule] ?? (self::$transliterators[$rule] = \Transliterator::create($rule));
                        }
                        if (null === $transliterator) {
                            throw new InvalidArgumentException(\sprintf('Unknown transliteration rule "%s".', $rule));
                        }
                        self::$transliterators['any-latin/bgn'] = $transliterator;
                    }
                    $s = $transliterator->transliterate($s);
                }
            } elseif (!\function_exists('iconv')) {
                $s = \preg_replace('/[^\\x00-\\x7F]/u', '?', $s);
            } else {
                $s = @\preg_replace_callback('/[^\\x00-\\x7F]/u', static function ($c) {
                    $c = (string) \iconv('UTF-8', 'ASCII//TRANSLIT', $c[0]);
                    if ('' === $c && '' === \iconv('UTF-8', 'ASCII//TRANSLIT', '²')) {
                        throw new \LogicException(\sprintf('"%s" requires a translit-able iconv implementation, try installing "gnu-libiconv" if you\'re using Alpine Linux.', static::class));
                    }
                    return 1 < \strlen($c) ? \ltrim($c, '\'`"^~') : ('' !== $c ? $c : '?');
                }, $s);
            }
        }
        $str->string .= $s;
        return $str;
    }
    public function camel() : parent
    {
        $str = clone $this;
        $str->string = \str_replace(' ', '', \preg_replace_callback('/\\b.(?![A-Z]{2,})/u', static function ($m) use(&$i) {
            return 1 === ++$i ? 'İ' === $m[0] ? 'i̇' : \mb_strtolower($m[0], 'UTF-8') : \mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8');
        }, \preg_replace('/[^\\pL0-9]++/u', ' ', $this->string)));
        return $str;
    }
    /**
     * @return int[]
     */
    public function codePointsAt(int $offset) : array
    {
        $str = $this->slice($offset, 1);
        if ('' === $str->string) {
            return [];
        }
        $codePoints = [];
        foreach (\preg_split('//u', $str->string, -1, \PREG_SPLIT_NO_EMPTY) as $c) {
            $codePoints[] = \mb_ord($c, 'UTF-8');
        }
        return $codePoints;
    }
    public function folded(bool $compat = \true) : parent
    {
        $str = clone $this;
        if (!$compat || \PHP_VERSION_ID < 70300 || !\defined('Normalizer::NFKC_CF')) {
            $str->string = \normalizer_normalize($str->string, $compat ? \Normalizer::NFKC : \Normalizer::NFC);
            $str->string = \mb_strtolower(\str_replace(self::FOLD_FROM, self::FOLD_TO, $this->string), 'UTF-8');
        } else {
            $str->string = \normalizer_normalize($str->string, \Normalizer::NFKC_CF);
        }
        return $str;
    }
    public function join(array $strings, string $lastGlue = null) : parent
    {
        $str = clone $this;
        $tail = null !== $lastGlue && 1 < \count($strings) ? $lastGlue . \array_pop($strings) : '';
        $str->string = \implode($this->string, $strings) . $tail;
        if (!\preg_match('//u', $str->string)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        return $str;
    }
    public function lower() : parent
    {
        $str = clone $this;
        $str->string = \mb_strtolower(\str_replace('İ', 'i̇', $str->string), 'UTF-8');
        return $str;
    }
    public function match(string $regexp, int $flags = 0, int $offset = 0) : array
    {
        $match = (\PREG_PATTERN_ORDER | \PREG_SET_ORDER) & $flags ? 'preg_match_all' : 'preg_match';
        if ($this->ignoreCase) {
            $regexp .= 'i';
        }
        \set_error_handler(static function ($t, $m) {
            throw new InvalidArgumentException($m);
        });
        try {
            if (\false === $match($regexp . 'u', $this->string, $matches, $flags | \PREG_UNMATCHED_AS_NULL, $offset)) {
                $lastError = \preg_last_error();
                foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
                        throw new RuntimeException('Matching failed with ' . $k . '.');
                    }
                }
                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            \restore_error_handler();
        }
        return $matches;
    }
    /**
     * @return static
     */
    public function normalize(int $form = self::NFC) : self
    {
        if (!\in_array($form, [self::NFC, self::NFD, self::NFKC, self::NFKD])) {
            throw new InvalidArgumentException('Unsupported normalization form.');
        }
        $str = clone $this;
        \normalizer_is_normalized($str->string, $form) ?: ($str->string = \normalizer_normalize($str->string, $form));
        return $str;
    }
    public function padBoth(int $length, string $padStr = ' ') : parent
    {
        if ('' === $padStr || !\preg_match('//u', $padStr)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        $pad = clone $this;
        $pad->string = $padStr;
        return $this->pad($length, $pad, \STR_PAD_BOTH);
    }
    public function padEnd(int $length, string $padStr = ' ') : parent
    {
        if ('' === $padStr || !\preg_match('//u', $padStr)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        $pad = clone $this;
        $pad->string = $padStr;
        return $this->pad($length, $pad, \STR_PAD_RIGHT);
    }
    public function padStart(int $length, string $padStr = ' ') : parent
    {
        if ('' === $padStr || !\preg_match('//u', $padStr)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        }
        $pad = clone $this;
        $pad->string = $padStr;
        return $this->pad($length, $pad, \STR_PAD_LEFT);
    }
    public function replaceMatches(string $fromRegexp, $to) : parent
    {
        if ($this->ignoreCase) {
            $fromRegexp .= 'i';
        }
        if (\is_array($to) || $to instanceof \Closure) {
            if (!\is_callable($to)) {
                throw new \TypeError(\sprintf('Argument 2 passed to "%s::replaceMatches()" must be callable, array given.', static::class));
            }
            $replace = 'preg_replace_callback';
            $to = static function (array $m) use($to) : string {
                $to = $to($m);
                if ('' !== $to && (!\is_string($to) || !\preg_match('//u', $to))) {
                    throw new InvalidArgumentException('Replace callback must return a valid UTF-8 string.');
                }
                return $to;
            };
        } elseif ('' !== $to && !\preg_match('//u', $to)) {
            throw new InvalidArgumentException('Invalid UTF-8 string.');
        } else {
            $replace = 'preg_replace';
        }
        \set_error_handler(static function ($t, $m) {
            throw new InvalidArgumentException($m);
        });
        try {
            if (null === ($string = $replace($fromRegexp . 'u', $to, $this->string))) {
                $lastError = \preg_last_error();
                foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
                        throw new RuntimeException('Matching failed with ' . $k . '.');
                    }
                }
                throw new RuntimeException('Matching failed with unknown error code.');
            }
        } finally {
            \restore_error_handler();
        }
        $str = clone $this;
        $str->string = $string;
        return $str;
    }
    public function reverse() : parent
    {
        $str = clone $this;
        $str->string = \implode('', \array_reverse(\preg_split('/(\\X)/u', $str->string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY)));
        return $str;
    }
    public function snake() : parent
    {
        $str = $this->camel();
        $str->string = \mb_strtolower(\preg_replace(['/(\\p{Lu}+)(\\p{Lu}\\p{Ll})/u', '/([\\p{Ll}0-9])(\\p{Lu})/u'], '_HumbugBox1cb33d1f20f1\\1_\\2', $str->string), 'UTF-8');
        return $str;
    }
    public function title(bool $allWords = \false) : parent
    {
        $str = clone $this;
        $limit = $allWords ? -1 : 1;
        $str->string = \preg_replace_callback('/\\b./u', static function (array $m) : string {
            return \mb_convert_case($m[0], \MB_CASE_TITLE, 'UTF-8');
        }, $str->string, $limit);
        return $str;
    }
    public function trim(string $chars = " \t\n\r\x00\v\f ") : parent
    {
        if (" \t\n\r\x00\v\f " !== $chars && !\preg_match('//u', $chars)) {
            throw new InvalidArgumentException('Invalid UTF-8 chars.');
        }
        $chars = \preg_quote($chars);
        $str = clone $this;
        $str->string = \preg_replace("{^[{$chars}]++|[{$chars}]++\$}uD", '', $str->string);
        return $str;
    }
    public function trimEnd(string $chars = " \t\n\r\x00\v\f ") : parent
    {
        if (" \t\n\r\x00\v\f " !== $chars && !\preg_match('//u', $chars)) {
            throw new InvalidArgumentException('Invalid UTF-8 chars.');
        }
        $chars = \preg_quote($chars);
        $str = clone $this;
        $str->string = \preg_replace("{[{$chars}]++\$}uD", '', $str->string);
        return $str;
    }
    public function trimPrefix($prefix) : parent
    {
        if (!$this->ignoreCase) {
            return parent::trimPrefix($prefix);
        }
        $str = clone $this;
        if ($prefix instanceof \Traversable) {
            $prefix = \iterator_to_array($prefix, \false);
        } elseif ($prefix instanceof parent) {
            $prefix = $prefix->string;
        }
        $prefix = \implode('|', \array_map('preg_quote', (array) $prefix));
        $str->string = \preg_replace("{^(?:{$prefix})}iuD", '', $this->string);
        return $str;
    }
    public function trimStart(string $chars = " \t\n\r\x00\v\f ") : parent
    {
        if (" \t\n\r\x00\v\f " !== $chars && !\preg_match('//u', $chars)) {
            throw new InvalidArgumentException('Invalid UTF-8 chars.');
        }
        $chars = \preg_quote($chars);
        $str = clone $this;
        $str->string = \preg_replace("{^[{$chars}]++}uD", '', $str->string);
        return $str;
    }
    public function trimSuffix($suffix) : parent
    {
        if (!$this->ignoreCase) {
            return parent::trimSuffix($suffix);
        }
        $str = clone $this;
        if ($suffix instanceof \Traversable) {
            $suffix = \iterator_to_array($suffix, \false);
        } elseif ($suffix instanceof parent) {
            $suffix = $suffix->string;
        }
        $suffix = \implode('|', \array_map('preg_quote', (array) $suffix));
        $str->string = \preg_replace("{(?:{$suffix})\$}iuD", '', $this->string);
        return $str;
    }
    public function upper() : parent
    {
        $str = clone $this;
        $str->string = \mb_strtoupper($str->string, 'UTF-8');
        if (\PHP_VERSION_ID < 70300) {
            $str->string = \str_replace(self::UPPER_FROM, self::UPPER_TO, $str->string);
        }
        return $str;
    }
    public function width(bool $ignoreAnsiDecoration = \true) : int
    {
        $width = 0;
        $s = \str_replace(["\x00", "\x05", "\x07"], '', $this->string);
        if (\false !== \strpos($s, "\r")) {
            $s = \str_replace(["\r\n", "\r"], "\n", $s);
        }
        if (!$ignoreAnsiDecoration) {
            $s = \preg_replace('/[\\p{Cc}\\x7F]++/u', '', $s);
        }
        foreach (\explode("\n", $s) as $s) {
            if ($ignoreAnsiDecoration) {
                $s = \preg_replace('/(?:\\x1B(?:
                    \\[ [\\x30-\\x3F]*+ [\\x20-\\x2F]*+ [\\x40-\\x7E]
                    | [P\\]X^_] .*? \\x1B\\\\
                    | [\\x41-\\x7E]
                )|[\\p{Cc}\\x7F]++)/xu', '', $s);
            }
            $lineWidth = $this->wcswidth($s);
            if ($lineWidth > $width) {
                $width = $lineWidth;
            }
        }
        return $width;
    }
    /**
     * @return static
     */
    private function pad(int $len, self $pad, int $type) : parent
    {
        $sLen = $this->length();
        if ($len <= $sLen) {
            return clone $this;
        }
        $padLen = $pad->length();
        $freeLen = $len - $sLen;
        $len = $freeLen % $padLen;
        switch ($type) {
            case \STR_PAD_RIGHT:
                return $this->append(\str_repeat($pad->string, \intdiv($freeLen, $padLen)) . ($len ? $pad->slice(0, $len) : ''));
            case \STR_PAD_LEFT:
                return $this->prepend(\str_repeat($pad->string, \intdiv($freeLen, $padLen)) . ($len ? $pad->slice(0, $len) : ''));
            case \STR_PAD_BOTH:
                $freeLen /= 2;
                $rightLen = \ceil($freeLen);
                $len = $rightLen % $padLen;
                $str = $this->append(\str_repeat($pad->string, \intdiv($rightLen, $padLen)) . ($len ? $pad->slice(0, $len) : ''));
                $leftLen = \floor($freeLen);
                $len = $leftLen % $padLen;
                return $str->prepend(\str_repeat($pad->string, \intdiv($leftLen, $padLen)) . ($len ? $pad->slice(0, $len) : ''));
            default:
                throw new InvalidArgumentException('Invalid padding type.');
        }
    }
    /**
     * Based on https://github.com/jquast/wcwidth, a Python implementation of https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c.
     */
    private function wcswidth(string $string) : int
    {
        $width = 0;
        foreach (\preg_split('//u', $string, -1, \PREG_SPLIT_NO_EMPTY) as $c) {
            $codePoint = \mb_ord($c, 'UTF-8');
            if (0 === $codePoint || 0x34f === $codePoint || 0x200b <= $codePoint && 0x200f >= $codePoint || 0x2028 === $codePoint || 0x2029 === $codePoint || 0x202a <= $codePoint && 0x202e >= $codePoint || 0x2060 <= $codePoint && 0x2063 >= $codePoint) {
                continue;
            }
            // Non printable characters
            if (32 > $codePoint || 0x7f <= $codePoint && 0xa0 > $codePoint) {
                return -1;
            }
            if (null === self::$tableZero) {
                self::$tableZero = (require __DIR__ . '/Resources/data/wcswidth_table_zero.php');
            }
            if ($codePoint >= self::$tableZero[0][0] && $codePoint <= self::$tableZero[$ubound = \count(self::$tableZero) - 1][1]) {
                $lbound = 0;
                while ($ubound >= $lbound) {
                    $mid = \floor(($lbound + $ubound) / 2);
                    if ($codePoint > self::$tableZero[$mid][1]) {
                        $lbound = $mid + 1;
                    } elseif ($codePoint < self::$tableZero[$mid][0]) {
                        $ubound = $mid - 1;
                    } else {
                        continue 2;
                    }
                }
            }
            if (null === self::$tableWide) {
                self::$tableWide = (require __DIR__ . '/Resources/data/wcswidth_table_wide.php');
            }
            if ($codePoint >= self::$tableWide[0][0] && $codePoint <= self::$tableWide[$ubound = \count(self::$tableWide) - 1][1]) {
                $lbound = 0;
                while ($ubound >= $lbound) {
                    $mid = \floor(($lbound + $ubound) / 2);
                    if ($codePoint > self::$tableWide[$mid][1]) {
                        $lbound = $mid + 1;
                    } elseif ($codePoint < self::$tableWide[$mid][0]) {
                        $ubound = $mid - 1;
                    } else {
                        $width += 2;
                        continue 2;
                    }
                }
            }
            ++$width;
        }
        return $width;
    }
}
Copyright (c) 2019-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file has been auto-generated by the Symfony String Component for internal use.
 *
 * Unicode version: 15.0.0
 * Date: 2022-10-05T17:16:36+02:00
 */
return [[4352, 4447], [8986, 8987], [9001, 9001], [9002, 9002], [9193, 9196], [9200, 9200], [9203, 9203], [9725, 9726], [9748, 9749], [9800, 9811], [9855, 9855], [9875, 9875], [9889, 9889], [9898, 9899], [9917, 9918], [9924, 9925], [9934, 9934], [9940, 9940], [9962, 9962], [9970, 9971], [9973, 9973], [9978, 9978], [9981, 9981], [9989, 9989], [9994, 9995], [10024, 10024], [10060, 10060], [10062, 10062], [10067, 10069], [10071, 10071], [10133, 10135], [10160, 10160], [10175, 10175], [11035, 11036], [11088, 11088], [11093, 11093], [11904, 11929], [11931, 12019], [12032, 12245], [12272, 12283], [12288, 12288], [12289, 12291], [12292, 12292], [12293, 12293], [12294, 12294], [12295, 12295], [12296, 12296], [12297, 12297], [12298, 12298], [12299, 12299], [12300, 12300], [12301, 12301], [12302, 12302], [12303, 12303], [12304, 12304], [12305, 12305], [12306, 12307], [12308, 12308], [12309, 12309], [12310, 12310], [12311, 12311], [12312, 12312], [12313, 12313], [12314, 12314], [12315, 12315], [12316, 12316], [12317, 12317], [12318, 12319], [12320, 12320], [12321, 12329], [12330, 12333], [12334, 12335], [12336, 12336], [12337, 12341], [12342, 12343], [12344, 12346], [12347, 12347], [12348, 12348], [12349, 12349], [12350, 12350], [12353, 12438], [12441, 12442], [12443, 12444], [12445, 12446], [12447, 12447], [12448, 12448], [12449, 12538], [12539, 12539], [12540, 12542], [12543, 12543], [12549, 12591], [12593, 12686], [12688, 12689], [12690, 12693], [12694, 12703], [12704, 12735], [12736, 12771], [12784, 12799], [12800, 12830], [12832, 12841], [12842, 12871], [12880, 12880], [12881, 12895], [12896, 12927], [12928, 12937], [12938, 12976], [12977, 12991], [12992, 13055], [13056, 13311], [13312, 19903], [19968, 40959], [40960, 40980], [40981, 40981], [40982, 42124], [42128, 42182], [43360, 43388], [44032, 55203], [63744, 64109], [64110, 64111], [64112, 64217], [64218, 64255], [65040, 65046], [65047, 65047], [65048, 65048], [65049, 65049], [65072, 65072], [65073, 65074], [65075, 65076], [65077, 65077], [65078, 65078], [65079, 65079], [65080, 65080], [65081, 65081], [65082, 65082], [65083, 65083], [65084, 65084], [65085, 65085], [65086, 65086], [65087, 65087], [65088, 65088], [65089, 65089], [65090, 65090], [65091, 65091], [65092, 65092], [65093, 65094], [65095, 65095], [65096, 65096], [65097, 65100], [65101, 65103], [65104, 65106], [65108, 65111], [65112, 65112], [65113, 65113], [65114, 65114], [65115, 65115], [65116, 65116], [65117, 65117], [65118, 65118], [65119, 65121], [65122, 65122], [65123, 65123], [65124, 65126], [65128, 65128], [65129, 65129], [65130, 65131], [65281, 65283], [65284, 65284], [65285, 65287], [65288, 65288], [65289, 65289], [65290, 65290], [65291, 65291], [65292, 65292], [65293, 65293], [65294, 65295], [65296, 65305], [65306, 65307], [65308, 65310], [65311, 65312], [65313, 65338], [65339, 65339], [65340, 65340], [65341, 65341], [65342, 65342], [65343, 65343], [65344, 65344], [65345, 65370], [65371, 65371], [65372, 65372], [65373, 65373], [65374, 65374], [65375, 65375], [65376, 65376], [65504, 65505], [65506, 65506], [65507, 65507], [65508, 65508], [65509, 65510], [94176, 94177], [94178, 94178], [94179, 94179], [94180, 94180], [94192, 94193], [94208, 100343], [100352, 101119], [101120, 101589], [101632, 101640], [110576, 110579], [110581, 110587], [110589, 110590], [110592, 110847], [110848, 110882], [110898, 110898], [110928, 110930], [110933, 110933], [110948, 110951], [110960, 111355], [126980, 126980], [127183, 127183], [127374, 127374], [127377, 127386], [127488, 127490], [127504, 127547], [127552, 127560], [127568, 127569], [127584, 127589], [127744, 127776], [127789, 127797], [127799, 127868], [127870, 127891], [127904, 127946], [127951, 127955], [127968, 127984], [127988, 127988], [127992, 127994], [127995, 127999], [128000, 128062], [128064, 128064], [128066, 128252], [128255, 128317], [128331, 128334], [128336, 128359], [128378, 128378], [128405, 128406], [128420, 128420], [128507, 128511], [128512, 128591], [128640, 128709], [128716, 128716], [128720, 128722], [128725, 128727], [128732, 128735], [128747, 128748], [128756, 128764], [128992, 129003], [129008, 129008], [129292, 129338], [129340, 129349], [129351, 129535], [129648, 129660], [129664, 129672], [129680, 129725], [129727, 129733], [129742, 129755], [129760, 129768], [129776, 129784], [131072, 173791], [173792, 173823], [173824, 177977], [177978, 177983], [177984, 178205], [178206, 178207], [178208, 183969], [183970, 183983], [183984, 191456], [191457, 194559], [194560, 195101], [195102, 195103], [195104, 196605], [196608, 201546], [201547, 201551], [201552, 205743], [205744, 262141]];
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file has been auto-generated by the Symfony String Component for internal use.
 *
 * Unicode version: 15.0.0
 * Date: 2022-10-05T17:16:37+02:00
 */
return [[768, 879], [1155, 1159], [1160, 1161], [1425, 1469], [1471, 1471], [1473, 1474], [1476, 1477], [1479, 1479], [1552, 1562], [1611, 1631], [1648, 1648], [1750, 1756], [1759, 1764], [1767, 1768], [1770, 1773], [1809, 1809], [1840, 1866], [1958, 1968], [2027, 2035], [2045, 2045], [2070, 2073], [2075, 2083], [2085, 2087], [2089, 2093], [2137, 2139], [2200, 2207], [2250, 2273], [2275, 2306], [2362, 2362], [2364, 2364], [2369, 2376], [2381, 2381], [2385, 2391], [2402, 2403], [2433, 2433], [2492, 2492], [2497, 2500], [2509, 2509], [2530, 2531], [2558, 2558], [2561, 2562], [2620, 2620], [2625, 2626], [2631, 2632], [2635, 2637], [2641, 2641], [2672, 2673], [2677, 2677], [2689, 2690], [2748, 2748], [2753, 2757], [2759, 2760], [2765, 2765], [2786, 2787], [2810, 2815], [2817, 2817], [2876, 2876], [2879, 2879], [2881, 2884], [2893, 2893], [2901, 2902], [2914, 2915], [2946, 2946], [3008, 3008], [3021, 3021], [3072, 3072], [3076, 3076], [3132, 3132], [3134, 3136], [3142, 3144], [3146, 3149], [3157, 3158], [3170, 3171], [3201, 3201], [3260, 3260], [3263, 3263], [3270, 3270], [3276, 3277], [3298, 3299], [3328, 3329], [3387, 3388], [3393, 3396], [3405, 3405], [3426, 3427], [3457, 3457], [3530, 3530], [3538, 3540], [3542, 3542], [3633, 3633], [3636, 3642], [3655, 3662], [3761, 3761], [3764, 3772], [3784, 3790], [3864, 3865], [3893, 3893], [3895, 3895], [3897, 3897], [3953, 3966], [3968, 3972], [3974, 3975], [3981, 3991], [3993, 4028], [4038, 4038], [4141, 4144], [4146, 4151], [4153, 4154], [4157, 4158], [4184, 4185], [4190, 4192], [4209, 4212], [4226, 4226], [4229, 4230], [4237, 4237], [4253, 4253], [4957, 4959], [5906, 5908], [5938, 5939], [5970, 5971], [6002, 6003], [6068, 6069], [6071, 6077], [6086, 6086], [6089, 6099], [6109, 6109], [6155, 6157], [6159, 6159], [6277, 6278], [6313, 6313], [6432, 6434], [6439, 6440], [6450, 6450], [6457, 6459], [6679, 6680], [6683, 6683], [6742, 6742], [6744, 6750], [6752, 6752], [6754, 6754], [6757, 6764], [6771, 6780], [6783, 6783], [6832, 6845], [6846, 6846], [6847, 6862], [6912, 6915], [6964, 6964], [6966, 6970], [6972, 6972], [6978, 6978], [7019, 7027], [7040, 7041], [7074, 7077], [7080, 7081], [7083, 7085], [7142, 7142], [7144, 7145], [7149, 7149], [7151, 7153], [7212, 7219], [7222, 7223], [7376, 7378], [7380, 7392], [7394, 7400], [7405, 7405], [7412, 7412], [7416, 7417], [7616, 7679], [8400, 8412], [8413, 8416], [8417, 8417], [8418, 8420], [8421, 8432], [11503, 11505], [11647, 11647], [11744, 11775], [12330, 12333], [12441, 12442], [42607, 42607], [42608, 42610], [42612, 42621], [42654, 42655], [42736, 42737], [43010, 43010], [43014, 43014], [43019, 43019], [43045, 43046], [43052, 43052], [43204, 43205], [43232, 43249], [43263, 43263], [43302, 43309], [43335, 43345], [43392, 43394], [43443, 43443], [43446, 43449], [43452, 43453], [43493, 43493], [43561, 43566], [43569, 43570], [43573, 43574], [43587, 43587], [43596, 43596], [43644, 43644], [43696, 43696], [43698, 43700], [43703, 43704], [43710, 43711], [43713, 43713], [43756, 43757], [43766, 43766], [44005, 44005], [44008, 44008], [44013, 44013], [64286, 64286], [65024, 65039], [65056, 65071], [66045, 66045], [66272, 66272], [66422, 66426], [68097, 68099], [68101, 68102], [68108, 68111], [68152, 68154], [68159, 68159], [68325, 68326], [68900, 68903], [69291, 69292], [69373, 69375], [69446, 69456], [69506, 69509], [69633, 69633], [69688, 69702], [69744, 69744], [69747, 69748], [69759, 69761], [69811, 69814], [69817, 69818], [69826, 69826], [69888, 69890], [69927, 69931], [69933, 69940], [70003, 70003], [70016, 70017], [70070, 70078], [70089, 70092], [70095, 70095], [70191, 70193], [70196, 70196], [70198, 70199], [70206, 70206], [70209, 70209], [70367, 70367], [70371, 70378], [70400, 70401], [70459, 70460], [70464, 70464], [70502, 70508], [70512, 70516], [70712, 70719], [70722, 70724], [70726, 70726], [70750, 70750], [70835, 70840], [70842, 70842], [70847, 70848], [70850, 70851], [71090, 71093], [71100, 71101], [71103, 71104], [71132, 71133], [71219, 71226], [71229, 71229], [71231, 71232], [71339, 71339], [71341, 71341], [71344, 71349], [71351, 71351], [71453, 71455], [71458, 71461], [71463, 71467], [71727, 71735], [71737, 71738], [71995, 71996], [71998, 71998], [72003, 72003], [72148, 72151], [72154, 72155], [72160, 72160], [72193, 72202], [72243, 72248], [72251, 72254], [72263, 72263], [72273, 72278], [72281, 72283], [72330, 72342], [72344, 72345], [72752, 72758], [72760, 72765], [72767, 72767], [72850, 72871], [72874, 72880], [72882, 72883], [72885, 72886], [73009, 73014], [73018, 73018], [73020, 73021], [73023, 73029], [73031, 73031], [73104, 73105], [73109, 73109], [73111, 73111], [73459, 73460], [73472, 73473], [73526, 73530], [73536, 73536], [73538, 73538], [78912, 78912], [78919, 78933], [92912, 92916], [92976, 92982], [94031, 94031], [94095, 94098], [94180, 94180], [113821, 113822], [118528, 118573], [118576, 118598], [119143, 119145], [119163, 119170], [119173, 119179], [119210, 119213], [119362, 119364], [121344, 121398], [121403, 121452], [121461, 121461], [121476, 121476], [121499, 121503], [121505, 121519], [122880, 122886], [122888, 122904], [122907, 122913], [122915, 122916], [122918, 122922], [123023, 123023], [123184, 123190], [123566, 123566], [123628, 123631], [124140, 124143], [125136, 125142], [125252, 125258], [917760, 917999]];
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String;

if (!\function_exists(u::class)) {
    function u(?string $string = '') : UnicodeString
    {
        return new UnicodeString($string ?? '');
    }
}
if (!\function_exists(b::class)) {
    function b(?string $string = '') : ByteString
    {
        return new ByteString($string ?? '');
    }
}
if (!\function_exists(s::class)) {
    /**
     * @return UnicodeString|ByteString
     */
    function s(?string $string = '') : AbstractString
    {
        $string = $string ?? '';
        return \preg_match('//u', $string) ? new UnicodeString($string) : new ByteString($string);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\String;

use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\ExceptionInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\String\Exception\RuntimeException;
/**
 * Represents a string of abstract characters.
 *
 * Unicode defines 3 types of "characters" (bytes, code points and grapheme clusters).
 * This class is the abstract type to use as a type-hint when the logic you want to
 * implement doesn't care about the exact variant it deals with.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Hugo Hamon <hugohamon@neuf.fr>
 *
 * @throws ExceptionInterface
 */
abstract class AbstractString implements \Stringable, \JsonSerializable
{
    public const PREG_PATTERN_ORDER = \PREG_PATTERN_ORDER;
    public const PREG_SET_ORDER = \PREG_SET_ORDER;
    public const PREG_OFFSET_CAPTURE = \PREG_OFFSET_CAPTURE;
    public const PREG_UNMATCHED_AS_NULL = \PREG_UNMATCHED_AS_NULL;
    public const PREG_SPLIT = 0;
    public const PREG_SPLIT_NO_EMPTY = \PREG_SPLIT_NO_EMPTY;
    public const PREG_SPLIT_DELIM_CAPTURE = \PREG_SPLIT_DELIM_CAPTURE;
    public const PREG_SPLIT_OFFSET_CAPTURE = \PREG_SPLIT_OFFSET_CAPTURE;
    protected $string = '';
    protected $ignoreCase = \false;
    public abstract function __construct(string $string = '');
    /**
     * Unwraps instances of AbstractString back to strings.
     *
     * @return string[]|array
     */
    public static function unwrap(array $values) : array
    {
        foreach ($values as $k => $v) {
            if ($v instanceof self) {
                $values[$k] = $v->__toString();
            } elseif (\is_array($v) && $values[$k] !== ($v = static::unwrap($v))) {
                $values[$k] = $v;
            }
        }
        return $values;
    }
    /**
     * Wraps (and normalizes) strings in instances of AbstractString.
     *
     * @return static[]|array
     */
    public static function wrap(array $values) : array
    {
        $i = 0;
        $keys = null;
        foreach ($values as $k => $v) {
            if (\is_string($k) && '' !== $k && $k !== ($j = (string) new static($k))) {
                $keys = $keys ?? \array_keys($values);
                $keys[$i] = $j;
            }
            if (\is_string($v)) {
                $values[$k] = new static($v);
            } elseif (\is_array($v) && $values[$k] !== ($v = static::wrap($v))) {
                $values[$k] = $v;
            }
            ++$i;
        }
        return null !== $keys ? \array_combine($keys, $values) : $values;
    }
    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function after($needle, bool $includeNeedle = \false, int $offset = 0) : self
    {
        $str = clone $this;
        $i = \PHP_INT_MAX;
        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOf($n, $offset);
            if (null !== $j && $j < $i) {
                $i = $j;
                $str->string = $n;
            }
        }
        if (\PHP_INT_MAX === $i) {
            return $str;
        }
        if (!$includeNeedle) {
            $i += $str->length();
        }
        return $this->slice($i);
    }
    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function afterLast($needle, bool $includeNeedle = \false, int $offset = 0) : self
    {
        $str = clone $this;
        $i = null;
        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOfLast($n, $offset);
            if (null !== $j && $j >= $i) {
                $i = $offset = $j;
                $str->string = $n;
            }
        }
        if (null === $i) {
            return $str;
        }
        if (!$includeNeedle) {
            $i += $str->length();
        }
        return $this->slice($i);
    }
    /**
     * @return static
     */
    public abstract function append(string ...$suffix) : self;
    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function before($needle, bool $includeNeedle = \false, int $offset = 0) : self
    {
        $str = clone $this;
        $i = \PHP_INT_MAX;
        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOf($n, $offset);
            if (null !== $j && $j < $i) {
                $i = $j;
                $str->string = $n;
            }
        }
        if (\PHP_INT_MAX === $i) {
            return $str;
        }
        if ($includeNeedle) {
            $i += $str->length();
        }
        return $this->slice(0, $i);
    }
    /**
     * @param string|string[] $needle
     *
     * @return static
     */
    public function beforeLast($needle, bool $includeNeedle = \false, int $offset = 0) : self
    {
        $str = clone $this;
        $i = null;
        foreach ((array) $needle as $n) {
            $n = (string) $n;
            $j = $this->indexOfLast($n, $offset);
            if (null !== $j && $j >= $i) {
                $i = $offset = $j;
                $str->string = $n;
            }
        }
        if (null === $i) {
            return $str;
        }
        if ($includeNeedle) {
            $i += $str->length();
        }
        return $this->slice(0, $i);
    }
    /**
     * @return int[]
     */
    public function bytesAt(int $offset) : array
    {
        $str = $this->slice($offset, 1);
        return '' === $str->string ? [] : \array_values(\unpack('C*', $str->string));
    }
    /**
     * @return static
     */
    public abstract function camel() : self;
    /**
     * @return static[]
     */
    public abstract function chunk(int $length = 1) : array;
    /**
     * @return static
     */
    public function collapseWhitespace() : self
    {
        $str = clone $this;
        $str->string = \trim(\preg_replace("/(?:[ \n\r\t\f]{2,}+|[\n\r\t\f])/", ' ', $str->string), " \n\r\t\f");
        return $str;
    }
    /**
     * @param string|string[] $needle
     */
    public function containsAny($needle) : bool
    {
        return null !== $this->indexOf($needle);
    }
    /**
     * @param string|string[] $suffix
     */
    public function endsWith($suffix) : bool
    {
        if (!\is_array($suffix) && !$suffix instanceof \Traversable) {
            throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }
        foreach ($suffix as $s) {
            if ($this->endsWith((string) $s)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @return static
     */
    public function ensureEnd(string $suffix) : self
    {
        if (!$this->endsWith($suffix)) {
            return $this->append($suffix);
        }
        $suffix = \preg_quote($suffix);
        $regex = '{(' . $suffix . ')(?:' . $suffix . ')++$}D';
        return $this->replaceMatches($regex . ($this->ignoreCase ? 'i' : ''), '$1');
    }
    /**
     * @return static
     */
    public function ensureStart(string $prefix) : self
    {
        $prefix = new static($prefix);
        if (!$this->startsWith($prefix)) {
            return $this->prepend($prefix);
        }
        $str = clone $this;
        $i = $prefixLen = $prefix->length();
        while ($this->indexOf($prefix, $i) === $i) {
            $str = $str->slice($prefixLen);
            $i += $prefixLen;
        }
        return $str;
    }
    /**
     * @param string|string[] $string
     */
    public function equalsTo($string) : bool
    {
        if (!\is_array($string) && !$string instanceof \Traversable) {
            throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }
        foreach ($string as $s) {
            if ($this->equalsTo((string) $s)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @return static
     */
    public abstract function folded() : self;
    /**
     * @return static
     */
    public function ignoreCase() : self
    {
        $str = clone $this;
        $str->ignoreCase = \true;
        return $str;
    }
    /**
     * @param string|string[] $needle
     */
    public function indexOf($needle, int $offset = 0) : ?int
    {
        if (!\is_array($needle) && !$needle instanceof \Traversable) {
            throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }
        $i = \PHP_INT_MAX;
        foreach ($needle as $n) {
            $j = $this->indexOf((string) $n, $offset);
            if (null !== $j && $j < $i) {
                $i = $j;
            }
        }
        return \PHP_INT_MAX === $i ? null : $i;
    }
    /**
     * @param string|string[] $needle
     */
    public function indexOfLast($needle, int $offset = 0) : ?int
    {
        if (!\is_array($needle) && !$needle instanceof \Traversable) {
            throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }
        $i = null;
        foreach ($needle as $n) {
            $j = $this->indexOfLast((string) $n, $offset);
            if (null !== $j && $j >= $i) {
                $i = $offset = $j;
            }
        }
        return $i;
    }
    public function isEmpty() : bool
    {
        return '' === $this->string;
    }
    /**
     * @return static
     */
    public abstract function join(array $strings, string $lastGlue = null) : self;
    public function jsonSerialize() : string
    {
        return $this->string;
    }
    public abstract function length() : int;
    /**
     * @return static
     */
    public abstract function lower() : self;
    /**
     * Matches the string using a regular expression.
     *
     * Pass PREG_PATTERN_ORDER or PREG_SET_ORDER as $flags to get all occurrences matching the regular expression.
     *
     * @return array All matches in a multi-dimensional array ordered according to flags
     */
    public abstract function match(string $regexp, int $flags = 0, int $offset = 0) : array;
    /**
     * @return static
     */
    public abstract function padBoth(int $length, string $padStr = ' ') : self;
    /**
     * @return static
     */
    public abstract function padEnd(int $length, string $padStr = ' ') : self;
    /**
     * @return static
     */
    public abstract function padStart(int $length, string $padStr = ' ') : self;
    /**
     * @return static
     */
    public abstract function prepend(string ...$prefix) : self;
    /**
     * @return static
     */
    public function repeat(int $multiplier) : self
    {
        if (0 > $multiplier) {
            throw new InvalidArgumentException(\sprintf('Multiplier must be positive, %d given.', $multiplier));
        }
        $str = clone $this;
        $str->string = \str_repeat($str->string, $multiplier);
        return $str;
    }
    /**
     * @return static
     */
    public abstract function replace(string $from, string $to) : self;
    /**
     * @param string|callable $to
     *
     * @return static
     */
    public abstract function replaceMatches(string $fromRegexp, $to) : self;
    /**
     * @return static
     */
    public abstract function reverse() : self;
    /**
     * @return static
     */
    public abstract function slice(int $start = 0, int $length = null) : self;
    /**
     * @return static
     */
    public abstract function snake() : self;
    /**
     * @return static
     */
    public abstract function splice(string $replacement, int $start = 0, int $length = null) : self;
    /**
     * @return static[]
     */
    public function split(string $delimiter, int $limit = null, int $flags = null) : array
    {
        if (null === $flags) {
            throw new \TypeError('Split behavior when $flags is null must be implemented by child classes.');
        }
        if ($this->ignoreCase) {
            $delimiter .= 'i';
        }
        \set_error_handler(static function ($t, $m) {
            throw new InvalidArgumentException($m);
        });
        try {
            if (\false === ($chunks = \preg_split($delimiter, $this->string, $limit, $flags))) {
                $lastError = \preg_last_error();
                foreach (\get_defined_constants(\true)['pcre'] as $k => $v) {
                    if ($lastError === $v && '_ERROR' === \substr($k, -6)) {
                        throw new RuntimeException('Splitting failed with ' . $k . '.');
                    }
                }
                throw new RuntimeException('Splitting failed with unknown error code.');
            }
        } finally {
            \restore_error_handler();
        }
        $str = clone $this;
        if (self::PREG_SPLIT_OFFSET_CAPTURE & $flags) {
            foreach ($chunks as &$chunk) {
                $str->string = $chunk[0];
                $chunk[0] = clone $str;
            }
        } else {
            foreach ($chunks as &$chunk) {
                $str->string = $chunk;
                $chunk = clone $str;
            }
        }
        return $chunks;
    }
    /**
     * @param string|string[] $prefix
     */
    public function startsWith($prefix) : bool
    {
        if (!\is_array($prefix) && !$prefix instanceof \Traversable) {
            throw new \TypeError(\sprintf('Method "%s()" must be overridden by class "%s" to deal with non-iterable values.', __FUNCTION__, static::class));
        }
        foreach ($prefix as $prefix) {
            if ($this->startsWith((string) $prefix)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @return static
     */
    public abstract function title(bool $allWords = \false) : self;
    public function toByteString(string $toEncoding = null) : ByteString
    {
        $b = new ByteString();
        $toEncoding = \in_array($toEncoding, ['utf8', 'utf-8', 'UTF8'], \true) ? 'UTF-8' : $toEncoding;
        if (null === $toEncoding || $toEncoding === ($fromEncoding = $this instanceof AbstractUnicodeString || \preg_match('//u', $b->string) ? 'UTF-8' : 'Windows-1252')) {
            $b->string = $this->string;
            return $b;
        }
        \set_error_handler(static function ($t, $m) {
            throw new InvalidArgumentException($m);
        });
        try {
            try {
                $b->string = \mb_convert_encoding($this->string, $toEncoding, 'UTF-8');
            } catch (InvalidArgumentException $e) {
                if (!\function_exists('iconv')) {
                    throw $e;
                }
                $b->string = \iconv('UTF-8', $toEncoding, $this->string);
            }
        } finally {
            \restore_error_handler();
        }
        return $b;
    }
    public function toCodePointString() : CodePointString
    {
        return new CodePointString($this->string);
    }
    public function toString() : string
    {
        return $this->string;
    }
    public function toUnicodeString() : UnicodeString
    {
        return new UnicodeString($this->string);
    }
    /**
     * @return static
     */
    public abstract function trim(string $chars = " \t\n\r\x00\v\f ") : self;
    /**
     * @return static
     */
    public abstract function trimEnd(string $chars = " \t\n\r\x00\v\f ") : self;
    /**
     * @param string|string[] $prefix
     *
     * @return static
     */
    public function trimPrefix($prefix) : self
    {
        if (\is_array($prefix) || $prefix instanceof \Traversable) {
            foreach ($prefix as $s) {
                $t = $this->trimPrefix($s);
                if ($t->string !== $this->string) {
                    return $t;
                }
            }
            return clone $this;
        }
        $str = clone $this;
        if ($prefix instanceof self) {
            $prefix = $prefix->string;
        } else {
            $prefix = (string) $prefix;
        }
        if ('' !== $prefix && \strlen($this->string) >= \strlen($prefix) && 0 === \substr_compare($this->string, $prefix, 0, \strlen($prefix), $this->ignoreCase)) {
            $str->string = \substr($this->string, \strlen($prefix));
        }
        return $str;
    }
    /**
     * @return static
     */
    public abstract function trimStart(string $chars = " \t\n\r\x00\v\f ") : self;
    /**
     * @param string|string[] $suffix
     *
     * @return static
     */
    public function trimSuffix($suffix) : self
    {
        if (\is_array($suffix) || $suffix instanceof \Traversable) {
            foreach ($suffix as $s) {
                $t = $this->trimSuffix($s);
                if ($t->string !== $this->string) {
                    return $t;
                }
            }
            return clone $this;
        }
        $str = clone $this;
        if ($suffix instanceof self) {
            $suffix = $suffix->string;
        } else {
            $suffix = (string) $suffix;
        }
        if ('' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === \substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase)) {
            $str->string = \substr($this->string, 0, -\strlen($suffix));
        }
        return $str;
    }
    /**
     * @return static
     */
    public function truncate(int $length, string $ellipsis = '', bool $cut = \true) : self
    {
        $stringLength = $this->length();
        if ($stringLength <= $length) {
            return clone $this;
        }
        $ellipsisLength = '' !== $ellipsis ? (new static($ellipsis))->length() : 0;
        if ($length < $ellipsisLength) {
            $ellipsisLength = 0;
        }
        if (!$cut) {
            if (null === ($length = $this->indexOf([' ', "\r", "\n", "\t"], ($length ?: 1) - 1))) {
                return clone $this;
            }
            $length += $ellipsisLength;
        }
        $str = $this->slice(0, $length - $ellipsisLength);
        return $ellipsisLength ? $str->trimEnd()->append($ellipsis) : $str;
    }
    /**
     * @return static
     */
    public abstract function upper() : self;
    /**
     * Returns the printable length on a terminal.
     */
    public abstract function width(bool $ignoreAnsiDecoration = \true) : int;
    /**
     * @return static
     */
    public function wordwrap(int $width = 75, string $break = "\n", bool $cut = \false) : self
    {
        $lines = '' !== $break ? $this->split($break) : [clone $this];
        $chars = [];
        $mask = '';
        if (1 === \count($lines) && '' === $lines[0]->string) {
            return $lines[0];
        }
        foreach ($lines as $i => $line) {
            if ($i) {
                $chars[] = $break;
                $mask .= '#';
            }
            foreach ($line->chunk() as $char) {
                $chars[] = $char->string;
                $mask .= ' ' === $char->string ? ' ' : '?';
            }
        }
        $string = '';
        $j = 0;
        $b = $i = -1;
        $mask = \wordwrap($mask, $width, '#', $cut);
        while (\false !== ($b = \strpos($mask, '#', $b + 1))) {
            for (++$i; $i < $b; ++$i) {
                $string .= $chars[$j];
                unset($chars[$j++]);
            }
            if ($break === $chars[$j] || ' ' === $chars[$j]) {
                unset($chars[$j++]);
            }
            $string .= $break;
        }
        $str = clone $this;
        $str->string = $string . \implode('', $chars);
        return $str;
    }
    public function __sleep() : array
    {
        return ['string'];
    }
    public function __clone()
    {
        $this->ignoreCase = \false;
    }
    public function __toString() : string
    {
        return $this->string;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Ctype as p;
if (\PHP_VERSION_ID >= 80000) {
    return require __DIR__ . '/bootstrap80.php';
}
if (!\function_exists('ctype_alnum')) {
    function ctype_alnum($text)
    {
        return p\Ctype::ctype_alnum($text);
    }
}
if (!\function_exists('ctype_alpha')) {
    function ctype_alpha($text)
    {
        return p\Ctype::ctype_alpha($text);
    }
}
if (!\function_exists('ctype_cntrl')) {
    function ctype_cntrl($text)
    {
        return p\Ctype::ctype_cntrl($text);
    }
}
if (!\function_exists('ctype_digit')) {
    function ctype_digit($text)
    {
        return p\Ctype::ctype_digit($text);
    }
}
if (!\function_exists('ctype_graph')) {
    function ctype_graph($text)
    {
        return p\Ctype::ctype_graph($text);
    }
}
if (!\function_exists('ctype_lower')) {
    function ctype_lower($text)
    {
        return p\Ctype::ctype_lower($text);
    }
}
if (!\function_exists('ctype_print')) {
    function ctype_print($text)
    {
        return p\Ctype::ctype_print($text);
    }
}
if (!\function_exists('ctype_punct')) {
    function ctype_punct($text)
    {
        return p\Ctype::ctype_punct($text);
    }
}
if (!\function_exists('ctype_space')) {
    function ctype_space($text)
    {
        return p\Ctype::ctype_space($text);
    }
}
if (!\function_exists('ctype_upper')) {
    function ctype_upper($text)
    {
        return p\Ctype::ctype_upper($text);
    }
}
if (!\function_exists('ctype_xdigit')) {
    function ctype_xdigit($text)
    {
        return p\Ctype::ctype_xdigit($text);
    }
}
Copyright (c) 2018-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Ctype;

/**
 * Ctype implementation through regex.
 *
 * @internal
 *
 * @author Gert de Pagter <BackEndTea@gmail.com>
 */
final class Ctype
{
    /**
     * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise.
     *
     * @see https://php.net/ctype-alnum
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_alnum($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^A-Za-z0-9]/', $text);
    }
    /**
     * Returns TRUE if every character in text is a letter, FALSE otherwise.
     *
     * @see https://php.net/ctype-alpha
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_alpha($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^A-Za-z]/', $text);
    }
    /**
     * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise.
     *
     * @see https://php.net/ctype-cntrl
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_cntrl($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^\\x00-\\x1f\\x7f]/', $text);
    }
    /**
     * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise.
     *
     * @see https://php.net/ctype-digit
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_digit($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^0-9]/', $text);
    }
    /**
     * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise.
     *
     * @see https://php.net/ctype-graph
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_graph($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^!-~]/', $text);
    }
    /**
     * Returns TRUE if every character in text is a lowercase letter.
     *
     * @see https://php.net/ctype-lower
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_lower($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^a-z]/', $text);
    }
    /**
     * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all.
     *
     * @see https://php.net/ctype-print
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_print($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^ -~]/', $text);
    }
    /**
     * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise.
     *
     * @see https://php.net/ctype-punct
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_punct($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^!-\\/\\:-@\\[-`\\{-~]/', $text);
    }
    /**
     * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters.
     *
     * @see https://php.net/ctype-space
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_space($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^\\s]/', $text);
    }
    /**
     * Returns TRUE if every character in text is an uppercase letter.
     *
     * @see https://php.net/ctype-upper
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_upper($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^A-Z]/', $text);
    }
    /**
     * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise.
     *
     * @see https://php.net/ctype-xdigit
     *
     * @param mixed $text
     *
     * @return bool
     */
    public static function ctype_xdigit($text)
    {
        $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
        return \is_string($text) && '' !== $text && !\preg_match('/[^A-Fa-f0-9]/', $text);
    }
    /**
     * Converts integers to their char versions according to normal ctype behaviour, if needed.
     *
     * If an integer between -128 and 255 inclusive is provided,
     * it is interpreted as the ASCII value of a single character
     * (negative values have 256 added in order to allow characters in the Extended ASCII range).
     * Any other integer is interpreted as a string containing the decimal digits of the integer.
     *
     * @param mixed  $int
     * @param string $function
     *
     * @return mixed
     */
    private static function convert_int_to_char_for_ctype($int, $function)
    {
        if (!\is_int($int)) {
            return $int;
        }
        if ($int < -128 || $int > 255) {
            return (string) $int;
        }
        if (\PHP_VERSION_ID >= 80100) {
            @\trigger_error($function . '(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED);
        }
        if ($int < 0) {
            $int += 256;
        }
        return \chr($int);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Ctype as p;
if (!\function_exists('ctype_alnum')) {
    function ctype_alnum(mixed $text) : bool
    {
        return p\Ctype::ctype_alnum($text);
    }
}
if (!\function_exists('ctype_alpha')) {
    function ctype_alpha(mixed $text) : bool
    {
        return p\Ctype::ctype_alpha($text);
    }
}
if (!\function_exists('ctype_cntrl')) {
    function ctype_cntrl(mixed $text) : bool
    {
        return p\Ctype::ctype_cntrl($text);
    }
}
if (!\function_exists('ctype_digit')) {
    function ctype_digit(mixed $text) : bool
    {
        return p\Ctype::ctype_digit($text);
    }
}
if (!\function_exists('ctype_graph')) {
    function ctype_graph(mixed $text) : bool
    {
        return p\Ctype::ctype_graph($text);
    }
}
if (!\function_exists('ctype_lower')) {
    function ctype_lower(mixed $text) : bool
    {
        return p\Ctype::ctype_lower($text);
    }
}
if (!\function_exists('ctype_print')) {
    function ctype_print(mixed $text) : bool
    {
        return p\Ctype::ctype_print($text);
    }
}
if (!\function_exists('ctype_punct')) {
    function ctype_punct(mixed $text) : bool
    {
        return p\Ctype::ctype_punct($text);
    }
}
if (!\function_exists('ctype_space')) {
    function ctype_space(mixed $text) : bool
    {
        return p\Ctype::ctype_space($text);
    }
}
if (!\function_exists('ctype_upper')) {
    function ctype_upper(mixed $text) : bool
    {
        return p\Ctype::ctype_upper($text);
    }
}
if (!\function_exists('ctype_xdigit')) {
    function ctype_xdigit(mixed $text) : bool
    {
        return p\Ctype::ctype_xdigit($text);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service;

use _HumbugBox1cb33d1f20f1\Psr\Container\ContainerExceptionInterface;
use _HumbugBox1cb33d1f20f1\Psr\Container\NotFoundExceptionInterface;
// Help opcache.preload discover always-needed symbols
\class_exists(ContainerExceptionInterface::class);
\class_exists(NotFoundExceptionInterface::class);
/**
 * A trait to help implement ServiceProviderInterface.
 *
 * @author Robin Chalas <robin.chalas@gmail.com>
 * @author Nicolas Grekas <p@tchwork.com>
 */
trait ServiceLocatorTrait
{
    private $factories;
    private $loading = [];
    private $providedTypes;
    /**
     * @param callable[] $factories
     */
    public function __construct(array $factories)
    {
        $this->factories = $factories;
    }
    /**
     * {@inheritdoc}
     *
     * @return bool
     */
    public function has(string $id)
    {
        return isset($this->factories[$id]);
    }
    /**
     * {@inheritdoc}
     *
     * @return mixed
     */
    public function get(string $id)
    {
        if (!isset($this->factories[$id])) {
            throw $this->createNotFoundException($id);
        }
        if (isset($this->loading[$id])) {
            $ids = \array_values($this->loading);
            $ids = \array_slice($this->loading, \array_search($id, $ids));
            $ids[] = $id;
            throw $this->createCircularReferenceException($id, $ids);
        }
        $this->loading[$id] = $id;
        try {
            return $this->factories[$id]($this);
        } finally {
            unset($this->loading[$id]);
        }
    }
    /**
     * {@inheritdoc}
     */
    public function getProvidedServices() : array
    {
        if (null === $this->providedTypes) {
            $this->providedTypes = [];
            foreach ($this->factories as $name => $factory) {
                if (!\is_callable($factory)) {
                    $this->providedTypes[$name] = '?';
                } else {
                    $type = (new \ReflectionFunction($factory))->getReturnType();
                    $this->providedTypes[$name] = $type ? ($type->allowsNull() ? '?' : '') . ($type instanceof \ReflectionNamedType ? $type->getName() : $type) : '?';
                }
            }
        }
        return $this->providedTypes;
    }
    private function createNotFoundException(string $id) : NotFoundExceptionInterface
    {
        if (!($alternatives = \array_keys($this->factories))) {
            $message = 'is empty...';
        } else {
            $last = \array_pop($alternatives);
            if ($alternatives) {
                $message = \sprintf('only knows about the "%s" and "%s" services.', \implode('", "', $alternatives), $last);
            } else {
                $message = \sprintf('only knows about the "%s" service.', $last);
            }
        }
        if ($this->loading) {
            $message = \sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', \end($this->loading), $id, $message);
        } else {
            $message = \sprintf('Service "%s" not found: the current service locator %s', $id, $message);
        }
        return new class($message) extends \InvalidArgumentException implements NotFoundExceptionInterface
        {
        };
    }
    private function createCircularReferenceException(string $id, array $path) : ContainerExceptionInterface
    {
        return new class(\sprintf('Circular reference detected for service "%s", path: "%s".', $id, \implode(' -> ', $path))) extends \RuntimeException implements ContainerExceptionInterface
        {
        };
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service;

use _HumbugBox1cb33d1f20f1\Psr\Container\ContainerInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service\Attribute\SubscribedService;
/**
 * Implementation of ServiceSubscriberInterface that determines subscribed services from
 * method return types. Service ids are available as "ClassName::methodName".
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
trait ServiceSubscriberTrait
{
    /** @var ContainerInterface */
    protected $container;
    /**
     * {@inheritdoc}
     */
    public static function getSubscribedServices() : array
    {
        $services = \method_exists(\get_parent_class(self::class) ?: '', __FUNCTION__) ? parent::getSubscribedServices() : [];
        $attributeOptIn = \false;
        if (\PHP_VERSION_ID >= 80000) {
            foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
                if (self::class !== $method->getDeclaringClass()->name) {
                    continue;
                }
                if (!($attribute = $method->getAttributes(SubscribedService::class)[0] ?? null)) {
                    continue;
                }
                if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
                    throw new \LogicException(\sprintf('Cannot use "%s" on method "%s::%s()" (can only be used on non-static, non-abstract methods with no parameters).', SubscribedService::class, self::class, $method->name));
                }
                if (!($returnType = $method->getReturnType())) {
                    throw new \LogicException(\sprintf('Cannot use "%s" on methods without a return type in "%s::%s()".', SubscribedService::class, $method->name, self::class));
                }
                $serviceId = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : (string) $returnType;
                if ($returnType->allowsNull()) {
                    $serviceId = '?' . $serviceId;
                }
                $services[$attribute->newInstance()->key ?? self::class . '::' . $method->name] = $serviceId;
                $attributeOptIn = \true;
            }
        }
        if (!$attributeOptIn) {
            foreach ((new \ReflectionClass(self::class))->getMethods() as $method) {
                if ($method->isStatic() || $method->isAbstract() || $method->isGenerator() || $method->isInternal() || $method->getNumberOfRequiredParameters()) {
                    continue;
                }
                if (self::class !== $method->getDeclaringClass()->name) {
                    continue;
                }
                if (!($returnType = $method->getReturnType()) instanceof \ReflectionNamedType) {
                    continue;
                }
                if ($returnType->isBuiltin()) {
                    continue;
                }
                if (\PHP_VERSION_ID >= 80000) {
                    trigger_deprecation('symfony/service-contracts', '2.5', 'Using "%s" in "%s" without using the "%s" attribute on any method is deprecated.', ServiceSubscriberTrait::class, self::class, SubscribedService::class);
                }
                $services[self::class . '::' . $method->name] = '?' . ($returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType);
            }
        }
        return $services;
    }
    /**
     * @required
     *
     * @return ContainerInterface|null
     */
    public function setContainer(ContainerInterface $container)
    {
        $this->container = $container;
        if (\method_exists(\get_parent_class(self::class) ?: '', __FUNCTION__)) {
            return parent::setContainer($container);
        }
        return null;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service\Attribute;

use _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service\ServiceSubscriberTrait;
/**
 * Use with {@see ServiceSubscriberTrait} to mark a method's return type
 * as a subscribed service.
 *
 * @author Kevin Bond <kevinbond@gmail.com>
 */
#[\Attribute(\Attribute::TARGET_METHOD)]
final class SubscribedService
{
    /**
     * @param string|null $key The key to use for the service
     *                         If null, use "ClassName::methodName"
     */
    public function __construct(public ?string $key = null)
    {
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service\Attribute;

/**
 * A required dependency.
 *
 * This attribute indicates that a property holds a required dependency. The annotated property or method should be
 * considered during the instantiation process of the containing class.
 *
 * @author Alexander M. Turek <me@derrabus.de>
 */
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
final class Required
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service;

/**
 * Provides a way to reset an object to its initial state.
 *
 * When calling the "reset()" method on an object, it should be put back to its
 * initial state. This usually means clearing any internal buffers and forwarding
 * the call to internal dependencies. All properties of the object should be put
 * back to the same state it had when it was first ready to use.
 *
 * This method could be called, for example, to recycle objects that are used as
 * services, so that they can be used to handle several requests in the same
 * process loop (note that we advise making your services stateless instead of
 * implementing this interface when possible.)
 */
interface ResetInterface
{
    public function reset();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service;

/**
 * A ServiceSubscriber exposes its dependencies via the static {@link getSubscribedServices} method.
 *
 * The getSubscribedServices method returns an array of service types required by such instances,
 * optionally keyed by the service names used internally. Service types that start with an interrogation
 * mark "?" are optional, while the other ones are mandatory service dependencies.
 *
 * The injected service locators SHOULD NOT allow access to any other services not specified by the method.
 *
 * It is expected that ServiceSubscriber instances consume PSR-11-based service locators internally.
 * This interface does not dictate any injection method for these service locators, although constructor
 * injection is recommended.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
interface ServiceSubscriberInterface
{
    /**
     * Returns an array of service types required by such instances, optionally keyed by the service names used internally.
     *
     * For mandatory dependencies:
     *
     *  * ['logger' => 'Psr\Log\LoggerInterface'] means the objects use the "logger" name
     *    internally to fetch a service which must implement Psr\Log\LoggerInterface.
     *  * ['loggers' => 'Psr\Log\LoggerInterface[]'] means the objects use the "loggers" name
     *    internally to fetch an iterable of Psr\Log\LoggerInterface instances.
     *  * ['Psr\Log\LoggerInterface'] is a shortcut for
     *  * ['Psr\Log\LoggerInterface' => 'Psr\Log\LoggerInterface']
     *
     * otherwise:
     *
     *  * ['logger' => '?Psr\Log\LoggerInterface'] denotes an optional dependency
     *  * ['loggers' => '?Psr\Log\LoggerInterface[]'] denotes an optional iterable dependency
     *  * ['?Psr\Log\LoggerInterface'] is a shortcut for
     *  * ['Psr\Log\LoggerInterface' => '?Psr\Log\LoggerInterface']
     *
     * @return string[] The required service types, optionally keyed by service names
     */
    public static function getSubscribedServices();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Contracts\Service;

use _HumbugBox1cb33d1f20f1\Psr\Container\ContainerInterface;
/**
 * A ServiceProviderInterface exposes the identifiers and the types of services provided by a container.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 * @author Mateusz Sip <mateusz.sip@gmail.com>
 */
interface ServiceProviderInterface extends ContainerInterface
{
    /**
     * Returns an associative array of service types keyed by the identifiers provided by the current container.
     *
     * Examples:
     *
     *  * ['logger' => 'Psr\Log\LoggerInterface'] means the object provides a service named "logger" that implements Psr\Log\LoggerInterface
     *  * ['foo' => '?'] means the container provides service name "foo" of unspecified type
     *  * ['bar' => '?Bar\Baz'] means the container provides a service "bar" of type Bar\Baz|null
     *
     * @return string[] The provided service types, keyed by service names
     */
    public function getProvidedServices() : array;
}
Copyright (c) 2018-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception\RuntimeException;
/**
 * Contains utility methods for handling path strings.
 *
 * The methods in this class are able to deal with both UNIX and Windows paths
 * with both forward and backward slashes. All methods return normalized parts
 * containing only forward slashes and no excess "." and ".." segments.
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 * @author Thomas Schulz <mail@king2500.net>
 * @author Théo Fidry <theo.fidry@gmail.com>
 */
final class Path
{
    /**
     * The number of buffer entries that triggers a cleanup operation.
     */
    private const CLEANUP_THRESHOLD = 1250;
    /**
     * The buffer size after the cleanup operation.
     */
    private const CLEANUP_SIZE = 1000;
    /**
     * Buffers input/output of {@link canonicalize()}.
     *
     * @var array<string, string>
     */
    private static $buffer = [];
    /**
     * @var int
     */
    private static $bufferSize = 0;
    /**
     * Canonicalizes the given path.
     *
     * During normalization, all slashes are replaced by forward slashes ("/").
     * Furthermore, all "." and ".." segments are removed as far as possible.
     * ".." segments at the beginning of relative paths are not removed.
     *
     * ```php
     * echo Path::canonicalize("\symfony\puli\..\css\style.css");
     * // => /symfony/css/style.css
     *
     * echo Path::canonicalize("../css/./style.css");
     * // => ../css/style.css
     * ```
     *
     * This method is able to deal with both UNIX and Windows paths.
     */
    public static function canonicalize(string $path) : string
    {
        if ('' === $path) {
            return '';
        }
        // This method is called by many other methods in this class. Buffer
        // the canonicalized paths to make up for the severe performance
        // decrease.
        if (isset(self::$buffer[$path])) {
            return self::$buffer[$path];
        }
        // Replace "~" with user's home directory.
        if ('~' === $path[0]) {
            $path = self::getHomeDirectory() . \substr($path, 1);
        }
        $path = self::normalize($path);
        [$root, $pathWithoutRoot] = self::split($path);
        $canonicalParts = self::findCanonicalParts($root, $pathWithoutRoot);
        // Add the root directory again
        self::$buffer[$path] = $canonicalPath = $root . \implode('/', $canonicalParts);
        ++self::$bufferSize;
        // Clean up regularly to prevent memory leaks
        if (self::$bufferSize > self::CLEANUP_THRESHOLD) {
            self::$buffer = \array_slice(self::$buffer, -self::CLEANUP_SIZE, null, \true);
            self::$bufferSize = self::CLEANUP_SIZE;
        }
        return $canonicalPath;
    }
    /**
     * Normalizes the given path.
     *
     * During normalization, all slashes are replaced by forward slashes ("/").
     * Contrary to {@link canonicalize()}, this method does not remove invalid
     * or dot path segments. Consequently, it is much more efficient and should
     * be used whenever the given path is known to be a valid, absolute system
     * path.
     *
     * This method is able to deal with both UNIX and Windows paths.
     */
    public static function normalize(string $path) : string
    {
        return \str_replace('\\', '/', $path);
    }
    /**
     * Returns the directory part of the path.
     *
     * This method is similar to PHP's dirname(), but handles various cases
     * where dirname() returns a weird result:
     *
     *  - dirname() does not accept backslashes on UNIX
     *  - dirname("C:/symfony") returns "C:", not "C:/"
     *  - dirname("C:/") returns ".", not "C:/"
     *  - dirname("C:") returns ".", not "C:/"
     *  - dirname("symfony") returns ".", not ""
     *  - dirname() does not canonicalize the result
     *
     * This method fixes these shortcomings and behaves like dirname()
     * otherwise.
     *
     * The result is a canonical path.
     *
     * @return string The canonical directory part. Returns the root directory
     *                if the root directory is passed. Returns an empty string
     *                if a relative path is passed that contains no slashes.
     *                Returns an empty string if an empty string is passed.
     */
    public static function getDirectory(string $path) : string
    {
        if ('' === $path) {
            return '';
        }
        $path = self::canonicalize($path);
        // Maintain scheme
        if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) {
            $scheme = \substr($path, 0, $schemeSeparatorPosition + 3);
            $path = \substr($path, $schemeSeparatorPosition + 3);
        } else {
            $scheme = '';
        }
        if (\false === ($dirSeparatorPosition = \strrpos($path, '/'))) {
            return '';
        }
        // Directory equals root directory "/"
        if (0 === $dirSeparatorPosition) {
            return $scheme . '/';
        }
        // Directory equals Windows root "C:/"
        if (2 === $dirSeparatorPosition && \ctype_alpha($path[0]) && ':' === $path[1]) {
            return $scheme . \substr($path, 0, 3);
        }
        return $scheme . \substr($path, 0, $dirSeparatorPosition);
    }
    /**
     * Returns canonical path of the user's home directory.
     *
     * Supported operating systems:
     *
     *  - UNIX
     *  - Windows8 and upper
     *
     * If your operating system or environment isn't supported, an exception is thrown.
     *
     * The result is a canonical path.
     *
     * @throws RuntimeException If your operating system or environment isn't supported
     */
    public static function getHomeDirectory() : string
    {
        // For UNIX support
        if (\getenv('HOME')) {
            return self::canonicalize(\getenv('HOME'));
        }
        // For >= Windows8 support
        if (\getenv('HOMEDRIVE') && \getenv('HOMEPATH')) {
            return self::canonicalize(\getenv('HOMEDRIVE') . \getenv('HOMEPATH'));
        }
        throw new RuntimeException("Cannot find the home directory path: Your environment or operating system isn't supported.");
    }
    /**
     * Returns the root directory of a path.
     *
     * The result is a canonical path.
     *
     * @return string The canonical root directory. Returns an empty string if
     *                the given path is relative or empty.
     */
    public static function getRoot(string $path) : string
    {
        if ('' === $path) {
            return '';
        }
        // Maintain scheme
        if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) {
            $scheme = \substr($path, 0, $schemeSeparatorPosition + 3);
            $path = \substr($path, $schemeSeparatorPosition + 3);
        } else {
            $scheme = '';
        }
        $firstCharacter = $path[0];
        // UNIX root "/" or "\" (Windows style)
        if ('/' === $firstCharacter || '\\' === $firstCharacter) {
            return $scheme . '/';
        }
        $length = \strlen($path);
        // Windows root
        if ($length > 1 && ':' === $path[1] && \ctype_alpha($firstCharacter)) {
            // Special case: "C:"
            if (2 === $length) {
                return $scheme . $path . '/';
            }
            // Normal case: "C:/ or "C:\"
            if ('/' === $path[2] || '\\' === $path[2]) {
                return $scheme . $firstCharacter . $path[1] . '/';
            }
        }
        return '';
    }
    /**
     * Returns the file name without the extension from a file path.
     *
     * @param string|null $extension if specified, only that extension is cut
     *                               off (may contain leading dot)
     */
    public static function getFilenameWithoutExtension(string $path, string $extension = null) : string
    {
        if ('' === $path) {
            return '';
        }
        if (null !== $extension) {
            // remove extension and trailing dot
            return \rtrim(\basename($path, $extension), '.');
        }
        return \pathinfo($path, \PATHINFO_FILENAME);
    }
    /**
     * Returns the extension from a file path (without leading dot).
     *
     * @param bool $forceLowerCase forces the extension to be lower-case
     */
    public static function getExtension(string $path, bool $forceLowerCase = \false) : string
    {
        if ('' === $path) {
            return '';
        }
        $extension = \pathinfo($path, \PATHINFO_EXTENSION);
        if ($forceLowerCase) {
            $extension = self::toLower($extension);
        }
        return $extension;
    }
    /**
     * Returns whether the path has an (or the specified) extension.
     *
     * @param string               $path       the path string
     * @param string|string[]|null $extensions if null or not provided, checks if
     *                                         an extension exists, otherwise
     *                                         checks for the specified extension
     *                                         or array of extensions (with or
     *                                         without leading dot)
     * @param bool                 $ignoreCase whether to ignore case-sensitivity
     */
    public static function hasExtension(string $path, $extensions = null, bool $ignoreCase = \false) : bool
    {
        if ('' === $path) {
            return \false;
        }
        $actualExtension = self::getExtension($path, $ignoreCase);
        // Only check if path has any extension
        if ([] === $extensions || null === $extensions) {
            return '' !== $actualExtension;
        }
        if (\is_string($extensions)) {
            $extensions = [$extensions];
        }
        foreach ($extensions as $key => $extension) {
            if ($ignoreCase) {
                $extension = self::toLower($extension);
            }
            // remove leading '.' in extensions array
            $extensions[$key] = \ltrim($extension, '.');
        }
        return \in_array($actualExtension, $extensions, \true);
    }
    /**
     * Changes the extension of a path string.
     *
     * @param string $path      The path string with filename.ext to change.
     * @param string $extension new extension (with or without leading dot)
     *
     * @return string the path string with new file extension
     */
    public static function changeExtension(string $path, string $extension) : string
    {
        if ('' === $path) {
            return '';
        }
        $actualExtension = self::getExtension($path);
        $extension = \ltrim($extension, '.');
        // No extension for paths
        if ('/' === \substr($path, -1)) {
            return $path;
        }
        // No actual extension in path
        if (empty($actualExtension)) {
            return $path . ('.' === \substr($path, -1) ? '' : '.') . $extension;
        }
        return \substr($path, 0, -\strlen($actualExtension)) . $extension;
    }
    public static function isAbsolute(string $path) : bool
    {
        if ('' === $path) {
            return \false;
        }
        // Strip scheme
        if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) {
            $path = \substr($path, $schemeSeparatorPosition + 3);
        }
        $firstCharacter = $path[0];
        // UNIX root "/" or "\" (Windows style)
        if ('/' === $firstCharacter || '\\' === $firstCharacter) {
            return \true;
        }
        // Windows root
        if (\strlen($path) > 1 && \ctype_alpha($firstCharacter) && ':' === $path[1]) {
            // Special case: "C:"
            if (2 === \strlen($path)) {
                return \true;
            }
            // Normal case: "C:/ or "C:\"
            if ('/' === $path[2] || '\\' === $path[2]) {
                return \true;
            }
        }
        return \false;
    }
    public static function isRelative(string $path) : bool
    {
        return !self::isAbsolute($path);
    }
    /**
     * Turns a relative path into an absolute path in canonical form.
     *
     * Usually, the relative path is appended to the given base path. Dot
     * segments ("." and "..") are removed/collapsed and all slashes turned
     * into forward slashes.
     *
     * ```php
     * echo Path::makeAbsolute("../style.css", "/symfony/puli/css");
     * // => /symfony/puli/style.css
     * ```
     *
     * If an absolute path is passed, that path is returned unless its root
     * directory is different than the one of the base path. In that case, an
     * exception is thrown.
     *
     * ```php
     * Path::makeAbsolute("/style.css", "/symfony/puli/css");
     * // => /style.css
     *
     * Path::makeAbsolute("C:/style.css", "C:/symfony/puli/css");
     * // => C:/style.css
     *
     * Path::makeAbsolute("C:/style.css", "/symfony/puli/css");
     * // InvalidArgumentException
     * ```
     *
     * If the base path is not an absolute path, an exception is thrown.
     *
     * The result is a canonical path.
     *
     * @param string $basePath an absolute base path
     *
     * @throws InvalidArgumentException if the base path is not absolute or if
     *                                  the given path is an absolute path with
     *                                  a different root than the base path
     */
    public static function makeAbsolute(string $path, string $basePath) : string
    {
        if ('' === $basePath) {
            throw new InvalidArgumentException(\sprintf('The base path must be a non-empty string. Got: "%s".', $basePath));
        }
        if (!self::isAbsolute($basePath)) {
            throw new InvalidArgumentException(\sprintf('The base path "%s" is not an absolute path.', $basePath));
        }
        if (self::isAbsolute($path)) {
            return self::canonicalize($path);
        }
        if (\false !== ($schemeSeparatorPosition = \strpos($basePath, '://'))) {
            $scheme = \substr($basePath, 0, $schemeSeparatorPosition + 3);
            $basePath = \substr($basePath, $schemeSeparatorPosition + 3);
        } else {
            $scheme = '';
        }
        return $scheme . self::canonicalize(\rtrim($basePath, '/\\') . '/' . $path);
    }
    /**
     * Turns a path into a relative path.
     *
     * The relative path is created relative to the given base path:
     *
     * ```php
     * echo Path::makeRelative("/symfony/style.css", "/symfony/puli");
     * // => ../style.css
     * ```
     *
     * If a relative path is passed and the base path is absolute, the relative
     * path is returned unchanged:
     *
     * ```php
     * Path::makeRelative("style.css", "/symfony/puli/css");
     * // => style.css
     * ```
     *
     * If both paths are relative, the relative path is created with the
     * assumption that both paths are relative to the same directory:
     *
     * ```php
     * Path::makeRelative("style.css", "symfony/puli/css");
     * // => ../../../style.css
     * ```
     *
     * If both paths are absolute, their root directory must be the same,
     * otherwise an exception is thrown:
     *
     * ```php
     * Path::makeRelative("C:/symfony/style.css", "/symfony/puli");
     * // InvalidArgumentException
     * ```
     *
     * If the passed path is absolute, but the base path is not, an exception
     * is thrown as well:
     *
     * ```php
     * Path::makeRelative("/symfony/style.css", "symfony/puli");
     * // InvalidArgumentException
     * ```
     *
     * If the base path is not an absolute path, an exception is thrown.
     *
     * The result is a canonical path.
     *
     * @throws InvalidArgumentException if the base path is not absolute or if
     *                                  the given path has a different root
     *                                  than the base path
     */
    public static function makeRelative(string $path, string $basePath) : string
    {
        $path = self::canonicalize($path);
        $basePath = self::canonicalize($basePath);
        [$root, $relativePath] = self::split($path);
        [$baseRoot, $relativeBasePath] = self::split($basePath);
        // If the base path is given as absolute path and the path is already
        // relative, consider it to be relative to the given absolute path
        // already
        if ('' === $root && '' !== $baseRoot) {
            // If base path is already in its root
            if ('' === $relativeBasePath) {
                $relativePath = \ltrim($relativePath, './\\');
            }
            return $relativePath;
        }
        // If the passed path is absolute, but the base path is not, we
        // cannot generate a relative path
        if ('' !== $root && '' === $baseRoot) {
            throw new InvalidArgumentException(\sprintf('The absolute path "%s" cannot be made relative to the relative path "%s". You should provide an absolute base path instead.', $path, $basePath));
        }
        // Fail if the roots of the two paths are different
        if ($baseRoot && $root !== $baseRoot) {
            throw new InvalidArgumentException(\sprintf('The path "%s" cannot be made relative to "%s", because they have different roots ("%s" and "%s").', $path, $basePath, $root, $baseRoot));
        }
        if ('' === $relativeBasePath) {
            return $relativePath;
        }
        // Build a "../../" prefix with as many "../" parts as necessary
        $parts = \explode('/', $relativePath);
        $baseParts = \explode('/', $relativeBasePath);
        $dotDotPrefix = '';
        // Once we found a non-matching part in the prefix, we need to add
        // "../" parts for all remaining parts
        $match = \true;
        foreach ($baseParts as $index => $basePart) {
            if ($match && isset($parts[$index]) && $basePart === $parts[$index]) {
                unset($parts[$index]);
                continue;
            }
            $match = \false;
            $dotDotPrefix .= '../';
        }
        return \rtrim($dotDotPrefix . \implode('/', $parts), '/');
    }
    /**
     * Returns whether the given path is on the local filesystem.
     */
    public static function isLocal(string $path) : bool
    {
        return '' !== $path && \false === \strpos($path, '://');
    }
    /**
     * Returns the longest common base path in canonical form of a set of paths or
     * `null` if the paths are on different Windows partitions.
     *
     * Dot segments ("." and "..") are removed/collapsed and all slashes turned
     * into forward slashes.
     *
     * ```php
     * $basePath = Path::getLongestCommonBasePath(
     *     '/symfony/css/style.css',
     *     '/symfony/css/..'
     * );
     * // => /symfony
     * ```
     *
     * The root is returned if no common base path can be found:
     *
     * ```php
     * $basePath = Path::getLongestCommonBasePath(
     *     '/symfony/css/style.css',
     *     '/puli/css/..'
     * );
     * // => /
     * ```
     *
     * If the paths are located on different Windows partitions, `null` is
     * returned.
     *
     * ```php
     * $basePath = Path::getLongestCommonBasePath(
     *     'C:/symfony/css/style.css',
     *     'D:/symfony/css/..'
     * );
     * // => null
     * ```
     */
    public static function getLongestCommonBasePath(string ...$paths) : ?string
    {
        [$bpRoot, $basePath] = self::split(self::canonicalize(\reset($paths)));
        for (\next($paths); null !== \key($paths) && '' !== $basePath; \next($paths)) {
            [$root, $path] = self::split(self::canonicalize(\current($paths)));
            // If we deal with different roots (e.g. C:/ vs. D:/), it's time
            // to quit
            if ($root !== $bpRoot) {
                return null;
            }
            // Make the base path shorter until it fits into path
            while (\true) {
                if ('.' === $basePath) {
                    // No more base paths
                    $basePath = '';
                    // next path
                    continue 2;
                }
                // Prevent false positives for common prefixes
                // see isBasePath()
                if (0 === \strpos($path . '/', $basePath . '/')) {
                    // next path
                    continue 2;
                }
                $basePath = \dirname($basePath);
            }
        }
        return $bpRoot . $basePath;
    }
    /**
     * Joins two or more path strings into a canonical path.
     */
    public static function join(string ...$paths) : string
    {
        $finalPath = null;
        $wasScheme = \false;
        foreach ($paths as $path) {
            if ('' === $path) {
                continue;
            }
            if (null === $finalPath) {
                // For first part we keep slashes, like '/top', 'C:\' or 'phar://'
                $finalPath = $path;
                $wasScheme = \false !== \strpos($path, '://');
                continue;
            }
            // Only add slash if previous part didn't end with '/' or '\'
            if (!\in_array(\substr($finalPath, -1), ['/', '\\'])) {
                $finalPath .= '/';
            }
            // If first part included a scheme like 'phar://' we allow \current part to start with '/', otherwise trim
            $finalPath .= $wasScheme ? $path : \ltrim($path, '/');
            $wasScheme = \false;
        }
        if (null === $finalPath) {
            return '';
        }
        return self::canonicalize($finalPath);
    }
    /**
     * Returns whether a path is a base path of another path.
     *
     * Dot segments ("." and "..") are removed/collapsed and all slashes turned
     * into forward slashes.
     *
     * ```php
     * Path::isBasePath('/symfony', '/symfony/css');
     * // => true
     *
     * Path::isBasePath('/symfony', '/symfony');
     * // => true
     *
     * Path::isBasePath('/symfony', '/symfony/..');
     * // => false
     *
     * Path::isBasePath('/symfony', '/puli');
     * // => false
     * ```
     */
    public static function isBasePath(string $basePath, string $ofPath) : bool
    {
        $basePath = self::canonicalize($basePath);
        $ofPath = self::canonicalize($ofPath);
        // Append slashes to prevent false positives when two paths have
        // a common prefix, for example /base/foo and /base/foobar.
        // Don't append a slash for the root "/", because then that root
        // won't be discovered as common prefix ("//" is not a prefix of
        // "/foobar/").
        return 0 === \strpos($ofPath . '/', \rtrim($basePath, '/') . '/');
    }
    /**
     * @return string[]
     */
    private static function findCanonicalParts(string $root, string $pathWithoutRoot) : array
    {
        $parts = \explode('/', $pathWithoutRoot);
        $canonicalParts = [];
        // Collapse "." and "..", if possible
        foreach ($parts as $part) {
            if ('.' === $part || '' === $part) {
                continue;
            }
            // Collapse ".." with the previous part, if one exists
            // Don't collapse ".." if the previous part is also ".."
            if ('..' === $part && \count($canonicalParts) > 0 && '..' !== $canonicalParts[\count($canonicalParts) - 1]) {
                \array_pop($canonicalParts);
                continue;
            }
            // Only add ".." prefixes for relative paths
            if ('..' !== $part || '' === $root) {
                $canonicalParts[] = $part;
            }
        }
        return $canonicalParts;
    }
    /**
     * Splits a canonical path into its root directory and the remainder.
     *
     * If the path has no root directory, an empty root directory will be
     * returned.
     *
     * If the root directory is a Windows style partition, the resulting root
     * will always contain a trailing slash.
     *
     * list ($root, $path) = Path::split("C:/symfony")
     * // => ["C:/", "symfony"]
     *
     * list ($root, $path) = Path::split("C:")
     * // => ["C:/", ""]
     *
     * @return array{string, string} an array with the root directory and the remaining relative path
     */
    private static function split(string $path) : array
    {
        if ('' === $path) {
            return ['', ''];
        }
        // Remember scheme as part of the root, if any
        if (\false !== ($schemeSeparatorPosition = \strpos($path, '://'))) {
            $root = \substr($path, 0, $schemeSeparatorPosition + 3);
            $path = \substr($path, $schemeSeparatorPosition + 3);
        } else {
            $root = '';
        }
        $length = \strlen($path);
        // Remove and remember root directory
        if (0 === \strpos($path, '/')) {
            $root .= '/';
            $path = $length > 1 ? \substr($path, 1) : '';
        } elseif ($length > 1 && \ctype_alpha($path[0]) && ':' === $path[1]) {
            if (2 === $length) {
                // Windows special case: "C:"
                $root .= $path . '/';
                $path = '';
            } elseif ('/' === $path[2]) {
                // Windows normal case: "C:/"..
                $root .= \substr($path, 0, 3);
                $path = $length > 3 ? \substr($path, 3) : '';
            }
        }
        return [$root, $path];
    }
    private static function toLower(string $string) : string
    {
        if (\false !== ($encoding = \mb_detect_encoding($string, null, \true))) {
            return \mb_strtolower($string, $encoding);
        }
        return \strtolower($string);
    }
    private function __construct()
    {
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception;

/**
 * Exception interface for all exceptions thrown by the component.
 *
 * @author Romain Neutron <imprec@gmail.com>
 */
interface ExceptionInterface extends \Throwable
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception;

/**
 * Exception class thrown when a file couldn't be found.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Christian Gärtner <christiangaertner.film@googlemail.com>
 */
class FileNotFoundException extends IOException
{
    public function __construct(string $message = null, int $code = 0, \Throwable $previous = null, string $path = null)
    {
        if (null === $message) {
            if (null === $path) {
                $message = 'File could not be found.';
            } else {
                $message = \sprintf('File "%s" could not be found.', $path);
            }
        }
        parent::__construct($message, $code, $previous, $path);
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception;

/**
 * @author Théo Fidry <theo.fidry@gmail.com>
 */
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception;

/**
 * Exception class thrown when a filesystem operation failure happens.
 *
 * @author Romain Neutron <imprec@gmail.com>
 * @author Christian Gärtner <christiangaertner.film@googlemail.com>
 * @author Fabien Potencier <fabien@symfony.com>
 */
class IOException extends \RuntimeException implements IOExceptionInterface
{
    private $path;
    public function __construct(string $message, int $code = 0, \Throwable $previous = null, string $path = null)
    {
        $this->path = $path;
        parent::__construct($message, $code, $previous);
    }
    /**
     * {@inheritdoc}
     */
    public function getPath()
    {
        return $this->path;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception;

/**
 * IOException interface for file and input/output stream related exceptions thrown by the component.
 *
 * @author Christian Gärtner <christiangaertner.film@googlemail.com>
 */
interface IOExceptionInterface extends ExceptionInterface
{
    /**
     * Returns the associated path for the exception.
     *
     * @return string|null
     */
    public function getPath();
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception;

/**
 * @author Christian Flothmann <christian.flothmann@sensiolabs.de>
 */
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
{
}
Copyright (c) 2004-2022 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem;

use _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception\FileNotFoundException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception\InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Exception\IOException;
/**
 * Provides basic utility to manipulate the file system.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
class Filesystem
{
    private static $lastError;
    /**
     * Copies a file.
     *
     * If the target file is older than the origin file, it's always overwritten.
     * If the target file is newer, it is overwritten only when the
     * $overwriteNewerFiles option is set to true.
     *
     * @throws FileNotFoundException When originFile doesn't exist
     * @throws IOException           When copy fails
     */
    public function copy(string $originFile, string $targetFile, bool $overwriteNewerFiles = \false)
    {
        $originIsLocal = \stream_is_local($originFile) || 0 === \stripos($originFile, 'file://');
        if ($originIsLocal && !\is_file($originFile)) {
            throw new FileNotFoundException(\sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile);
        }
        $this->mkdir(\dirname($targetFile));
        $doCopy = \true;
        if (!$overwriteNewerFiles && null === \parse_url($originFile, \PHP_URL_HOST) && \is_file($targetFile)) {
            $doCopy = \filemtime($originFile) > \filemtime($targetFile);
        }
        if ($doCopy) {
            // https://bugs.php.net/64634
            if (!($source = self::box('fopen', $originFile, 'r'))) {
                throw new IOException(\sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading: ', $originFile, $targetFile) . self::$lastError, 0, null, $originFile);
            }
            // Stream context created to allow files overwrite when using FTP stream wrapper - disabled by default
            if (!($target = self::box('fopen', $targetFile, 'w', \false, \stream_context_create(['ftp' => ['overwrite' => \true]])))) {
                throw new IOException(\sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing: ', $originFile, $targetFile) . self::$lastError, 0, null, $originFile);
            }
            $bytesCopied = \stream_copy_to_stream($source, $target);
            \fclose($source);
            \fclose($target);
            unset($source, $target);
            if (!\is_file($targetFile)) {
                throw new IOException(\sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile);
            }
            if ($originIsLocal) {
                // Like `cp`, preserve executable permission bits
                self::box('chmod', $targetFile, \fileperms($targetFile) | \fileperms($originFile) & 0111);
                if ($bytesCopied !== ($bytesOrigin = \filesize($originFile))) {
                    throw new IOException(\sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile);
                }
            }
        }
    }
    /**
     * Creates a directory recursively.
     *
     * @param string|iterable $dirs The directory path
     *
     * @throws IOException On any directory creation failure
     */
    public function mkdir($dirs, int $mode = 0777)
    {
        foreach ($this->toIterable($dirs) as $dir) {
            if (\is_dir($dir)) {
                continue;
            }
            if (!self::box('mkdir', $dir, $mode, \true) && !\is_dir($dir)) {
                throw new IOException(\sprintf('Failed to create "%s": ', $dir) . self::$lastError, 0, null, $dir);
            }
        }
    }
    /**
     * Checks the existence of files or directories.
     *
     * @param string|iterable $files A filename, an array of files, or a \Traversable instance to check
     *
     * @return bool
     */
    public function exists($files)
    {
        $maxPathLength = \PHP_MAXPATHLEN - 2;
        foreach ($this->toIterable($files) as $file) {
            if (\strlen($file) > $maxPathLength) {
                throw new IOException(\sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file);
            }
            if (!\file_exists($file)) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * Sets access and modification time of file.
     *
     * @param string|iterable $files A filename, an array of files, or a \Traversable instance to create
     * @param int|null        $time  The touch time as a Unix timestamp, if not supplied the current system time is used
     * @param int|null        $atime The access time as a Unix timestamp, if not supplied the current system time is used
     *
     * @throws IOException When touch fails
     */
    public function touch($files, int $time = null, int $atime = null)
    {
        foreach ($this->toIterable($files) as $file) {
            if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) {
                throw new IOException(\sprintf('Failed to touch "%s": ', $file) . self::$lastError, 0, null, $file);
            }
        }
    }
    /**
     * Removes files or directories.
     *
     * @param string|iterable $files A filename, an array of files, or a \Traversable instance to remove
     *
     * @throws IOException When removal fails
     */
    public function remove($files)
    {
        if ($files instanceof \Traversable) {
            $files = \iterator_to_array($files, \false);
        } elseif (!\is_array($files)) {
            $files = [$files];
        }
        self::doRemove($files, \false);
    }
    private static function doRemove(array $files, bool $isRecursive) : void
    {
        $files = \array_reverse($files);
        foreach ($files as $file) {
            if (\is_link($file)) {
                // See https://bugs.php.net/52176
                if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && \file_exists($file)) {
                    throw new IOException(\sprintf('Failed to remove symlink "%s": ', $file) . self::$lastError);
                }
            } elseif (\is_dir($file)) {
                if (!$isRecursive) {
                    $tmpName = \dirname(\realpath($file)) . '/.' . \strrev(\strtr(\base64_encode(\random_bytes(2)), '/=', '-.'));
                    if (\file_exists($tmpName)) {
                        try {
                            self::doRemove([$tmpName], \true);
                        } catch (IOException $e) {
                        }
                    }
                    if (!\file_exists($tmpName) && self::box('rename', $file, $tmpName)) {
                        $origFile = $file;
                        $file = $tmpName;
                    } else {
                        $origFile = null;
                    }
                }
                $files = new \FilesystemIterator($file, \FilesystemIterator::CURRENT_AS_PATHNAME | \FilesystemIterator::SKIP_DOTS);
                self::doRemove(\iterator_to_array($files, \true), \true);
                if (!self::box('rmdir', $file) && \file_exists($file) && !$isRecursive) {
                    $lastError = self::$lastError;
                    if (null !== $origFile && self::box('rename', $file, $origFile)) {
                        $file = $origFile;
                    }
                    throw new IOException(\sprintf('Failed to remove directory "%s": ', $file) . $lastError);
                }
            } elseif (!self::box('unlink', $file) && (\str_contains(self::$lastError, 'Permission denied') || \file_exists($file))) {
                throw new IOException(\sprintf('Failed to remove file "%s": ', $file) . self::$lastError);
            }
        }
    }
    /**
     * Change mode for an array of files or directories.
     *
     * @param string|iterable $files     A filename, an array of files, or a \Traversable instance to change mode
     * @param int             $mode      The new mode (octal)
     * @param int             $umask     The mode mask (octal)
     * @param bool            $recursive Whether change the mod recursively or not
     *
     * @throws IOException When the change fails
     */
    public function chmod($files, int $mode, int $umask = 00, bool $recursive = \false)
    {
        foreach ($this->toIterable($files) as $file) {
            if ((\PHP_VERSION_ID < 80000 || \is_int($mode)) && !self::box('chmod', $file, $mode & ~$umask)) {
                throw new IOException(\sprintf('Failed to chmod file "%s": ', $file) . self::$lastError, 0, null, $file);
            }
            if ($recursive && \is_dir($file) && !\is_link($file)) {
                $this->chmod(new \FilesystemIterator($file), $mode, $umask, \true);
            }
        }
    }
    /**
     * Change the owner of an array of files or directories.
     *
     * @param string|iterable $files     A filename, an array of files, or a \Traversable instance to change owner
     * @param string|int      $user      A user name or number
     * @param bool            $recursive Whether change the owner recursively or not
     *
     * @throws IOException When the change fails
     */
    public function chown($files, $user, bool $recursive = \false)
    {
        foreach ($this->toIterable($files) as $file) {
            if ($recursive && \is_dir($file) && !\is_link($file)) {
                $this->chown(new \FilesystemIterator($file), $user, \true);
            }
            if (\is_link($file) && \function_exists('lchown')) {
                if (!self::box('lchown', $file, $user)) {
                    throw new IOException(\sprintf('Failed to chown file "%s": ', $file) . self::$lastError, 0, null, $file);
                }
            } else {
                if (!self::box('chown', $file, $user)) {
                    throw new IOException(\sprintf('Failed to chown file "%s": ', $file) . self::$lastError, 0, null, $file);
                }
            }
        }
    }
    /**
     * Change the group of an array of files or directories.
     *
     * @param string|iterable $files     A filename, an array of files, or a \Traversable instance to change group
     * @param string|int      $group     A group name or number
     * @param bool            $recursive Whether change the group recursively or not
     *
     * @throws IOException When the change fails
     */
    public function chgrp($files, $group, bool $recursive = \false)
    {
        foreach ($this->toIterable($files) as $file) {
            if ($recursive && \is_dir($file) && !\is_link($file)) {
                $this->chgrp(new \FilesystemIterator($file), $group, \true);
            }
            if (\is_link($file) && \function_exists('lchgrp')) {
                if (!self::box('lchgrp', $file, $group)) {
                    throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file) . self::$lastError, 0, null, $file);
                }
            } else {
                if (!self::box('chgrp', $file, $group)) {
                    throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file) . self::$lastError, 0, null, $file);
                }
            }
        }
    }
    /**
     * Renames a file or a directory.
     *
     * @throws IOException When target file or directory already exists
     * @throws IOException When origin cannot be renamed
     */
    public function rename(string $origin, string $target, bool $overwrite = \false)
    {
        // we check that target does not exist
        if (!$overwrite && $this->isReadable($target)) {
            throw new IOException(\sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target);
        }
        if (!self::box('rename', $origin, $target)) {
            if (\is_dir($origin)) {
                // See https://bugs.php.net/54097 & https://php.net/rename#113943
                $this->mirror($origin, $target, null, ['override' => $overwrite, 'delete' => $overwrite]);
                $this->remove($origin);
                return;
            }
            throw new IOException(\sprintf('Cannot rename "%s" to "%s": ', $origin, $target) . self::$lastError, 0, null, $target);
        }
    }
    /**
     * Tells whether a file exists and is readable.
     *
     * @throws IOException When windows path is longer than 258 characters
     */
    private function isReadable(string $filename) : bool
    {
        $maxPathLength = \PHP_MAXPATHLEN - 2;
        if (\strlen($filename) > $maxPathLength) {
            throw new IOException(\sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename);
        }
        return \is_readable($filename);
    }
    /**
     * Creates a symbolic link or copy a directory.
     *
     * @throws IOException When symlink fails
     */
    public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = \false)
    {
        self::assertFunctionExists('symlink');
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $originDir = \strtr($originDir, '/', '\\');
            $targetDir = \strtr($targetDir, '/', '\\');
            if ($copyOnWindows) {
                $this->mirror($originDir, $targetDir);
                return;
            }
        }
        $this->mkdir(\dirname($targetDir));
        if (\is_link($targetDir)) {
            if (\readlink($targetDir) === $originDir) {
                return;
            }
            $this->remove($targetDir);
        }
        if (!self::box('symlink', $originDir, $targetDir)) {
            $this->linkException($originDir, $targetDir, 'symbolic');
        }
    }
    /**
     * Creates a hard link, or several hard links to a file.
     *
     * @param string|string[] $targetFiles The target file(s)
     *
     * @throws FileNotFoundException When original file is missing or not a file
     * @throws IOException           When link fails, including if link already exists
     */
    public function hardlink(string $originFile, $targetFiles)
    {
        self::assertFunctionExists('link');
        if (!$this->exists($originFile)) {
            throw new FileNotFoundException(null, 0, null, $originFile);
        }
        if (!\is_file($originFile)) {
            throw new FileNotFoundException(\sprintf('Origin file "%s" is not a file.', $originFile));
        }
        foreach ($this->toIterable($targetFiles) as $targetFile) {
            if (\is_file($targetFile)) {
                if (\fileinode($originFile) === \fileinode($targetFile)) {
                    continue;
                }
                $this->remove($targetFile);
            }
            if (!self::box('link', $originFile, $targetFile)) {
                $this->linkException($originFile, $targetFile, 'hard');
            }
        }
    }
    /**
     * @param string $linkType Name of the link type, typically 'symbolic' or 'hard'
     */
    private function linkException(string $origin, string $target, string $linkType)
    {
        if (self::$lastError) {
            if ('\\' === \DIRECTORY_SEPARATOR && \str_contains(self::$lastError, 'error code(1314)')) {
                throw new IOException(\sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target);
            }
        }
        throw new IOException(\sprintf('Failed to create "%s" link from "%s" to "%s": ', $linkType, $origin, $target) . self::$lastError, 0, null, $target);
    }
    /**
     * Resolves links in paths.
     *
     * With $canonicalize = false (default)
     *      - if $path does not exist or is not a link, returns null
     *      - if $path is a link, returns the next direct target of the link without considering the existence of the target
     *
     * With $canonicalize = true
     *      - if $path does not exist, returns null
     *      - if $path exists, returns its absolute fully resolved final version
     *
     * @return string|null
     */
    public function readlink(string $path, bool $canonicalize = \false)
    {
        if (!$canonicalize && !\is_link($path)) {
            return null;
        }
        if ($canonicalize) {
            if (!$this->exists($path)) {
                return null;
            }
            if ('\\' === \DIRECTORY_SEPARATOR && \PHP_VERSION_ID < 70410) {
                $path = \readlink($path);
            }
            return \realpath($path);
        }
        if ('\\' === \DIRECTORY_SEPARATOR && \PHP_VERSION_ID < 70400) {
            return \realpath($path);
        }
        return \readlink($path);
    }
    /**
     * Given an existing path, convert it to a path relative to a given starting path.
     *
     * @return string
     */
    public function makePathRelative(string $endPath, string $startPath)
    {
        if (!$this->isAbsolutePath($startPath)) {
            throw new InvalidArgumentException(\sprintf('The start path "%s" is not absolute.', $startPath));
        }
        if (!$this->isAbsolutePath($endPath)) {
            throw new InvalidArgumentException(\sprintf('The end path "%s" is not absolute.', $endPath));
        }
        // Normalize separators on Windows
        if ('\\' === \DIRECTORY_SEPARATOR) {
            $endPath = \str_replace('\\', '/', $endPath);
            $startPath = \str_replace('\\', '/', $startPath);
        }
        $splitDriveLetter = function ($path) {
            return \strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && \ctype_alpha($path[0]) ? [\substr($path, 2), \strtoupper($path[0])] : [$path, null];
        };
        $splitPath = function ($path) {
            $result = [];
            foreach (\explode('/', \trim($path, '/')) as $segment) {
                if ('..' === $segment) {
                    \array_pop($result);
                } elseif ('.' !== $segment && '' !== $segment) {
                    $result[] = $segment;
                }
            }
            return $result;
        };
        [$endPath, $endDriveLetter] = $splitDriveLetter($endPath);
        [$startPath, $startDriveLetter] = $splitDriveLetter($startPath);
        $startPathArr = $splitPath($startPath);
        $endPathArr = $splitPath($endPath);
        if ($endDriveLetter && $startDriveLetter && $endDriveLetter != $startDriveLetter) {
            // End path is on another drive, so no relative path exists
            return $endDriveLetter . ':/' . ($endPathArr ? \implode('/', $endPathArr) . '/' : '');
        }
        // Find for which directory the common path stops
        $index = 0;
        while (isset($startPathArr[$index]) && isset($endPathArr[$index]) && $startPathArr[$index] === $endPathArr[$index]) {
            ++$index;
        }
        // Determine how deep the start path is relative to the common path (ie, "web/bundles" = 2 levels)
        if (1 === \count($startPathArr) && '' === $startPathArr[0]) {
            $depth = 0;
        } else {
            $depth = \count($startPathArr) - $index;
        }
        // Repeated "../" for each level need to reach the common path
        $traverser = \str_repeat('../', $depth);
        $endPathRemainder = \implode('/', \array_slice($endPathArr, $index));
        // Construct $endPath from traversing to the common path, then to the remaining $endPath
        $relativePath = $traverser . ('' !== $endPathRemainder ? $endPathRemainder . '/' : '');
        return '' === $relativePath ? './' : $relativePath;
    }
    /**
     * Mirrors a directory to another.
     *
     * Copies files and directories from the origin directory into the target directory. By default:
     *
     *  - existing files in the target directory will be overwritten, except if they are newer (see the `override` option)
     *  - files in the target directory that do not exist in the source directory will not be deleted (see the `delete` option)
     *
     * @param \Traversable|null $iterator Iterator that filters which files and directories to copy, if null a recursive iterator is created
     * @param array             $options  An array of boolean options
     *                                    Valid options are:
     *                                    - $options['override'] If true, target files newer than origin files are overwritten (see copy(), defaults to false)
     *                                    - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false)
     *                                    - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
     *
     * @throws IOException When file type is unknown
     */
    public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = [])
    {
        $targetDir = \rtrim($targetDir, '/\\');
        $originDir = \rtrim($originDir, '/\\');
        $originDirLen = \strlen($originDir);
        if (!$this->exists($originDir)) {
            throw new IOException(\sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir);
        }
        // Iterate in destination folder to remove obsolete entries
        if ($this->exists($targetDir) && isset($options['delete']) && $options['delete']) {
            $deleteIterator = $iterator;
            if (null === $deleteIterator) {
                $flags = \FilesystemIterator::SKIP_DOTS;
                $deleteIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($targetDir, $flags), \RecursiveIteratorIterator::CHILD_FIRST);
            }
            $targetDirLen = \strlen($targetDir);
            foreach ($deleteIterator as $file) {
                $origin = $originDir . \substr($file->getPathname(), $targetDirLen);
                if (!$this->exists($origin)) {
                    $this->remove($file);
                }
            }
        }
        $copyOnWindows = $options['copy_on_windows'] ?? \false;
        if (null === $iterator) {
            $flags = $copyOnWindows ? \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS : \FilesystemIterator::SKIP_DOTS;
            $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($originDir, $flags), \RecursiveIteratorIterator::SELF_FIRST);
        }
        $this->mkdir($targetDir);
        $filesCreatedWhileMirroring = [];
        foreach ($iterator as $file) {
            if ($file->getPathname() === $targetDir || $file->getRealPath() === $targetDir || isset($filesCreatedWhileMirroring[$file->getRealPath()])) {
                continue;
            }
            $target = $targetDir . \substr($file->getPathname(), $originDirLen);
            $filesCreatedWhileMirroring[$target] = \true;
            if (!$copyOnWindows && \is_link($file)) {
                $this->symlink($file->getLinkTarget(), $target);
            } elseif (\is_dir($file)) {
                $this->mkdir($target);
            } elseif (\is_file($file)) {
                $this->copy($file, $target, $options['override'] ?? \false);
            } else {
                throw new IOException(\sprintf('Unable to guess "%s" file type.', $file), 0, null, $file);
            }
        }
    }
    /**
     * Returns whether the file path is an absolute path.
     *
     * @return bool
     */
    public function isAbsolutePath(string $file)
    {
        return '' !== $file && (\strspn($file, '/\\', 0, 1) || \strlen($file) > 3 && \ctype_alpha($file[0]) && ':' === $file[1] && \strspn($file, '/\\', 2, 1) || null !== \parse_url($file, \PHP_URL_SCHEME));
    }
    /**
     * Creates a temporary file with support for custom stream wrappers.
     *
     * @param string $prefix The prefix of the generated temporary filename
     *                       Note: Windows uses only the first three characters of prefix
     * @param string $suffix The suffix of the generated temporary filename
     *
     * @return string The new temporary filename (with path), or throw an exception on failure
     */
    public function tempnam(string $dir, string $prefix)
    {
        $suffix = \func_num_args() > 2 ? \func_get_arg(2) : '';
        [$scheme, $hierarchy] = $this->getSchemeAndHierarchy($dir);
        // If no scheme or scheme is "file" or "gs" (Google Cloud) create temp file in local filesystem
        if ((null === $scheme || 'file' === $scheme || 'gs' === $scheme) && '' === $suffix) {
            // If tempnam failed or no scheme return the filename otherwise prepend the scheme
            if ($tmpFile = self::box('tempnam', $hierarchy, $prefix)) {
                if (null !== $scheme && 'gs' !== $scheme) {
                    return $scheme . '://' . $tmpFile;
                }
                return $tmpFile;
            }
            throw new IOException('A temporary file could not be created: ' . self::$lastError);
        }
        // Loop until we create a valid temp file or have reached 10 attempts
        for ($i = 0; $i < 10; ++$i) {
            // Create a unique filename
            $tmpFile = $dir . '/' . $prefix . \uniqid(\mt_rand(), \true) . $suffix;
            // Use fopen instead of file_exists as some streams do not support stat
            // Use mode 'x+' to atomically check existence and create to avoid a TOCTOU vulnerability
            if (!($handle = self::box('fopen', $tmpFile, 'x+'))) {
                continue;
            }
            // Close the file if it was successfully opened
            self::box('fclose', $handle);
            return $tmpFile;
        }
        throw new IOException('A temporary file could not be created: ' . self::$lastError);
    }
    /**
     * Atomically dumps content into a file.
     *
     * @param string|resource $content The data to write into the file
     *
     * @throws IOException if the file cannot be written to
     */
    public function dumpFile(string $filename, $content)
    {
        if (\is_array($content)) {
            throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
        }
        $dir = \dirname($filename);
        if (!\is_dir($dir)) {
            $this->mkdir($dir);
        }
        // Will create a temp file with 0600 access rights
        // when the filesystem supports chmod.
        $tmpFile = $this->tempnam($dir, \basename($filename));
        try {
            if (\false === self::box('file_put_contents', $tmpFile, $content)) {
                throw new IOException(\sprintf('Failed to write file "%s": ', $filename) . self::$lastError, 0, null, $filename);
            }
            self::box('chmod', $tmpFile, \file_exists($filename) ? \fileperms($filename) : 0666 & ~\umask());
            $this->rename($tmpFile, $filename, \true);
        } finally {
            if (\file_exists($tmpFile)) {
                self::box('unlink', $tmpFile);
            }
        }
    }
    /**
     * Appends content to an existing file.
     *
     * @param string|resource $content The content to append
     * @param bool            $lock    Whether the file should be locked when writing to it
     *
     * @throws IOException If the file is not writable
     */
    public function appendToFile(string $filename, $content)
    {
        if (\is_array($content)) {
            throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__));
        }
        $dir = \dirname($filename);
        if (!\is_dir($dir)) {
            $this->mkdir($dir);
        }
        $lock = \func_num_args() > 2 && \func_get_arg(2);
        if (\false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) {
            throw new IOException(\sprintf('Failed to write file "%s": ', $filename) . self::$lastError, 0, null, $filename);
        }
    }
    private function toIterable($files) : iterable
    {
        return \is_iterable($files) ? $files : [$files];
    }
    /**
     * Gets a 2-tuple of scheme (may be null) and hierarchical part of a filename (e.g. file:///tmp -> [file, tmp]).
     */
    private function getSchemeAndHierarchy(string $filename) : array
    {
        $components = \explode('://', $filename, 2);
        return 2 === \count($components) ? [$components[0], $components[1]] : [null, $components[0]];
    }
    private static function assertFunctionExists(string $func) : void
    {
        if (!\function_exists($func)) {
            throw new IOException(\sprintf('Unable to perform filesystem operation because the "%s()" function has been disabled.', $func));
        }
    }
    /**
     * @param mixed ...$args
     *
     * @return mixed
     */
    private static function box(string $func, ...$args)
    {
        self::assertFunctionExists($func);
        self::$lastError = null;
        \set_error_handler(__CLASS__ . '::handleError');
        try {
            return $func(...$args);
        } finally {
            \restore_error_handler();
        }
    }
    /**
     * @internal
     */
    public static function handleError(int $type, string $msg)
    {
        self::$lastError = $msg;
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Intl\Grapheme;

\define('_HumbugBox1cb33d1f20f1\\SYMFONY_GRAPHEME_CLUSTER_RX', ((float) \PCRE_VERSION < 10 ? (float) \PCRE_VERSION >= 8.32 : (float) \PCRE_VERSION >= 10.39) ? '\\X' : Grapheme::GRAPHEME_CLUSTER_RX);
/**
 * Partial intl implementation in pure PHP.
 *
 * Implemented:
 * - grapheme_extract  - Extract a sequence of grapheme clusters from a text buffer, which must be encoded in UTF-8
 * - grapheme_stripos  - Find position (in grapheme units) of first occurrence of a case-insensitive string
 * - grapheme_stristr  - Returns part of haystack string from the first occurrence of case-insensitive needle to the end of haystack
 * - grapheme_strlen   - Get string length in grapheme units
 * - grapheme_strpos   - Find position (in grapheme units) of first occurrence of a string
 * - grapheme_strripos - Find position (in grapheme units) of last occurrence of a case-insensitive string
 * - grapheme_strrpos  - Find position (in grapheme units) of last occurrence of a string
 * - grapheme_strstr   - Returns part of haystack string from the first occurrence of needle to the end of haystack
 * - grapheme_substr   - Return part of a string
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
final class Grapheme
{
    // (CRLF|([ZWNJ-ZWJ]|T+|L*(LV?V+|LV|LVT)T*|L+|[^Control])[Extend]*|[Control])
    // This regular expression is a work around for http://bugs.exim.org/1279
    public const GRAPHEME_CLUSTER_RX = '(?:\\r\\n|(?:[ -~\\x{200C}\\x{200D}]|[ᆨ-ᇹ]+|[ᄀ-ᅟ]*(?:[가개갸걔거게겨계고과괘괴교구궈궤귀규그긔기까깨꺄꺠꺼께껴꼐꼬꽈꽤꾀꾜꾸꿔꿰뀌뀨끄끠끼나내냐냬너네녀녜노놔놰뇌뇨누눠눼뉘뉴느늬니다대댜댸더데뎌뎨도돠돼되됴두둬뒈뒤듀드듸디따때땨떄떠떼뗘뗴또똬뙈뙤뚀뚜뚸뛔뛰뜌뜨띄띠라래랴럐러레려례로롸뢔뢰료루뤄뤠뤼류르릐리마매먀먜머메며몌모뫄뫠뫼묘무뭐뭬뮈뮤므믜미바배뱌뱨버베벼볘보봐봬뵈뵤부붜붸뷔뷰브븨비빠빼뺘뺴뻐뻬뼈뼤뽀뽜뽸뾔뾰뿌뿨쀄쀠쀼쁘쁴삐사새샤섀서세셔셰소솨쇄쇠쇼수숴쉐쉬슈스싀시싸쌔쌰썌써쎄쎠쎼쏘쏴쐐쐬쑈쑤쒀쒜쒸쓔쓰씌씨아애야얘어에여예오와왜외요우워웨위유으의이자재쟈쟤저제져졔조좌좨죄죠주줘줴쥐쥬즈즤지짜째쨔쨰쩌쩨쪄쪠쪼쫘쫴쬐쬬쭈쭤쮀쮜쮸쯔쯰찌차채챠챼처체쳐쳬초촤쵀최쵸추춰췌취츄츠츼치카캐캬컈커케켜켸코콰쾌쾨쿄쿠쿼퀘퀴큐크킈키타태탸턔터테텨톄토톼퇘퇴툐투퉈퉤튀튜트틔티파패퍄퍠퍼페펴폐포퐈퐤푀표푸풔풰퓌퓨프픠피하해햐햬허헤혀혜호화홰회효후훠훼휘휴흐희히]?[ᅠ-ᆢ]+|[가-힣])[ᆨ-ᇹ]*|[ᄀ-ᅟ]+|[^\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}])[\\p{Mn}\\p{Me}\\x{09BE}\\x{09D7}\\x{0B3E}\\x{0B57}\\x{0BBE}\\x{0BD7}\\x{0CC2}\\x{0CD5}\\x{0CD6}\\x{0D3E}\\x{0D57}\\x{0DCF}\\x{0DDF}\\x{200C}\\x{200D}\\x{1D165}\\x{1D16E}-\\x{1D172}]*|[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}])';
    private const CASE_FOLD = [['µ', 'ſ', "ͅ", 'ς', "ϐ", "ϑ", "ϕ", "ϖ", "ϰ", "ϱ", "ϵ", "ẛ", "ι"], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "ṡ", 'ι']];
    public static function grapheme_extract($s, $size, $type = \GRAPHEME_EXTR_COUNT, $start = 0, &$next = 0)
    {
        if (0 > $start) {
            $start = \strlen($s) + $start;
        }
        if (!\is_scalar($s)) {
            $hasError = \false;
            \set_error_handler(function () use(&$hasError) {
                $hasError = \true;
            });
            $next = \substr($s, $start);
            \restore_error_handler();
            if ($hasError) {
                \substr($s, $start);
                $s = '';
            } else {
                $s = $next;
            }
        } else {
            $s = \substr($s, $start);
        }
        $size = (int) $size;
        $type = (int) $type;
        $start = (int) $start;
        if (\GRAPHEME_EXTR_COUNT !== $type && \GRAPHEME_EXTR_MAXBYTES !== $type && \GRAPHEME_EXTR_MAXCHARS !== $type) {
            if (80000 > \PHP_VERSION_ID) {
                return \false;
            }
            throw new \ValueError('grapheme_extract(): Argument #3 ($type) must be one of GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS');
        }
        if (!isset($s[0]) || 0 > $size || 0 > $start) {
            return \false;
        }
        if (0 === $size) {
            return '';
        }
        $next = $start;
        $s = \preg_split('/(' . SYMFONY_GRAPHEME_CLUSTER_RX . ')/u', "\r\n" . $s, $size + 1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE);
        if (!isset($s[1])) {
            return \false;
        }
        $i = 1;
        $ret = '';
        do {
            if (\GRAPHEME_EXTR_COUNT === $type) {
                --$size;
            } elseif (\GRAPHEME_EXTR_MAXBYTES === $type) {
                $size -= \strlen($s[$i]);
            } else {
                $size -= \iconv_strlen($s[$i], 'UTF-8//IGNORE');
            }
            if ($size >= 0) {
                $ret .= $s[$i];
            }
        } while (isset($s[++$i]) && $size > 0);
        $next += \strlen($ret);
        return $ret;
    }
    public static function grapheme_strlen($s)
    {
        \preg_replace('/' . SYMFONY_GRAPHEME_CLUSTER_RX . '/u', '', $s, -1, $len);
        return 0 === $len && '' !== $s ? null : $len;
    }
    public static function grapheme_substr($s, $start, $len = null)
    {
        if (null === $len) {
            $len = 2147483647;
        }
        \preg_match_all('/' . SYMFONY_GRAPHEME_CLUSTER_RX . '/u', $s, $s);
        $slen = \count($s[0]);
        $start = (int) $start;
        if (0 > $start) {
            $start += $slen;
        }
        if (0 > $start) {
            if (\PHP_VERSION_ID < 80000) {
                return \false;
            }
            $start = 0;
        }
        if ($start >= $slen) {
            return \PHP_VERSION_ID >= 80000 ? '' : \false;
        }
        $rem = $slen - $start;
        if (0 > $len) {
            $len += $rem;
        }
        if (0 === $len) {
            return '';
        }
        if (0 > $len) {
            return \PHP_VERSION_ID >= 80000 ? '' : \false;
        }
        if ($len > $rem) {
            $len = $rem;
        }
        return \implode('', \array_slice($s[0], $start, $len));
    }
    public static function grapheme_strpos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 0);
    }
    public static function grapheme_stripos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 1);
    }
    public static function grapheme_strrpos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 2);
    }
    public static function grapheme_strripos($s, $needle, $offset = 0)
    {
        return self::grapheme_position($s, $needle, $offset, 3);
    }
    public static function grapheme_stristr($s, $needle, $beforeNeedle = \false)
    {
        return \mb_stristr($s, $needle, $beforeNeedle, 'UTF-8');
    }
    public static function grapheme_strstr($s, $needle, $beforeNeedle = \false)
    {
        return \mb_strstr($s, $needle, $beforeNeedle, 'UTF-8');
    }
    private static function grapheme_position($s, $needle, $offset, $mode)
    {
        $needle = (string) $needle;
        if (80000 > \PHP_VERSION_ID && !\preg_match('/./us', $needle)) {
            return \false;
        }
        $s = (string) $s;
        if (!\preg_match('/./us', $s)) {
            return \false;
        }
        if ($offset > 0) {
            $s = self::grapheme_substr($s, $offset);
        } elseif ($offset < 0) {
            if (2 > $mode) {
                $offset += self::grapheme_strlen($s);
                $s = self::grapheme_substr($s, $offset);
                if (0 > $offset) {
                    $offset = 0;
                }
            } elseif (0 > ($offset += self::grapheme_strlen($needle))) {
                $s = self::grapheme_substr($s, 0, $offset);
                $offset = 0;
            } else {
                $offset = 0;
            }
        }
        // As UTF-8 is self-synchronizing, and we have ensured the strings are valid UTF-8,
        // we can use normal binary string functions here. For case-insensitive searches,
        // case fold the strings first.
        $caseInsensitive = $mode & 1;
        $reverse = $mode & 2;
        if ($caseInsensitive) {
            // Use the same case folding mode as mbstring does for mb_stripos().
            // Stick to SIMPLE case folding to avoid changing the length of the string, which
            // might result in offsets being shifted.
            $mode = \defined('MB_CASE_FOLD_SIMPLE') ? \MB_CASE_FOLD_SIMPLE : \MB_CASE_LOWER;
            $s = \mb_convert_case($s, $mode, 'UTF-8');
            $needle = \mb_convert_case($needle, $mode, 'UTF-8');
            if (!\defined('MB_CASE_FOLD_SIMPLE')) {
                $s = \str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $s);
                $needle = \str_replace(self::CASE_FOLD[0], self::CASE_FOLD[1], $needle);
            }
        }
        if ($reverse) {
            $needlePos = \strrpos($s, $needle);
        } else {
            $needlePos = \strpos($s, $needle);
        }
        return \false !== $needlePos ? self::grapheme_strlen(\substr($s, 0, $needlePos)) + $offset : \false;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Intl\Grapheme as p;
if (\extension_loaded('intl')) {
    return;
}
if (\PHP_VERSION_ID >= 80000) {
    return require __DIR__ . '/bootstrap80.php';
}
if (!\defined('GRAPHEME_EXTR_COUNT')) {
    \define('GRAPHEME_EXTR_COUNT', 0);
}
if (!\defined('GRAPHEME_EXTR_MAXBYTES')) {
    \define('GRAPHEME_EXTR_MAXBYTES', 1);
}
if (!\defined('GRAPHEME_EXTR_MAXCHARS')) {
    \define('GRAPHEME_EXTR_MAXCHARS', 2);
}
if (!\function_exists('grapheme_extract')) {
    function grapheme_extract($haystack, $size, $type = 0, $start = 0, &$next = 0)
    {
        return p\Grapheme::grapheme_extract($haystack, $size, $type, $start, $next);
    }
}
if (!\function_exists('grapheme_stripos')) {
    function grapheme_stripos($haystack, $needle, $offset = 0)
    {
        return p\Grapheme::grapheme_stripos($haystack, $needle, $offset);
    }
}
if (!\function_exists('grapheme_stristr')) {
    function grapheme_stristr($haystack, $needle, $beforeNeedle = \false)
    {
        return p\Grapheme::grapheme_stristr($haystack, $needle, $beforeNeedle);
    }
}
if (!\function_exists('grapheme_strlen')) {
    function grapheme_strlen($input)
    {
        return p\Grapheme::grapheme_strlen($input);
    }
}
if (!\function_exists('grapheme_strpos')) {
    function grapheme_strpos($haystack, $needle, $offset = 0)
    {
        return p\Grapheme::grapheme_strpos($haystack, $needle, $offset);
    }
}
if (!\function_exists('grapheme_strripos')) {
    function grapheme_strripos($haystack, $needle, $offset = 0)
    {
        return p\Grapheme::grapheme_strripos($haystack, $needle, $offset);
    }
}
if (!\function_exists('grapheme_strrpos')) {
    function grapheme_strrpos($haystack, $needle, $offset = 0)
    {
        return p\Grapheme::grapheme_strrpos($haystack, $needle, $offset);
    }
}
if (!\function_exists('grapheme_strstr')) {
    function grapheme_strstr($haystack, $needle, $beforeNeedle = \false)
    {
        return p\Grapheme::grapheme_strstr($haystack, $needle, $beforeNeedle);
    }
}
if (!\function_exists('grapheme_substr')) {
    function grapheme_substr($string, $offset, $length = null)
    {
        return p\Grapheme::grapheme_substr($string, $offset, $length);
    }
}
Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Intl\Grapheme as p;
if (!\defined('GRAPHEME_EXTR_COUNT')) {
    \define('GRAPHEME_EXTR_COUNT', 0);
}
if (!\defined('GRAPHEME_EXTR_MAXBYTES')) {
    \define('GRAPHEME_EXTR_MAXBYTES', 1);
}
if (!\defined('GRAPHEME_EXTR_MAXCHARS')) {
    \define('GRAPHEME_EXTR_MAXCHARS', 2);
}
if (!\function_exists('grapheme_extract')) {
    function grapheme_extract(?string $haystack, ?int $size, ?int $type = \GRAPHEME_EXTR_COUNT, ?int $offset = 0, &$next = null) : string|false
    {
        return p\Grapheme::grapheme_extract((string) $haystack, (int) $size, (int) $type, (int) $offset, $next);
    }
}
if (!\function_exists('grapheme_stripos')) {
    function grapheme_stripos(?string $haystack, ?string $needle, ?int $offset = 0) : int|false
    {
        return p\Grapheme::grapheme_stripos((string) $haystack, (string) $needle, (int) $offset);
    }
}
if (!\function_exists('grapheme_stristr')) {
    function grapheme_stristr(?string $haystack, ?string $needle, ?bool $beforeNeedle = \false) : string|false
    {
        return p\Grapheme::grapheme_stristr((string) $haystack, (string) $needle, (bool) $beforeNeedle);
    }
}
if (!\function_exists('grapheme_strlen')) {
    function grapheme_strlen(?string $string) : int|false|null
    {
        return p\Grapheme::grapheme_strlen((string) $string);
    }
}
if (!\function_exists('grapheme_strpos')) {
    function grapheme_strpos(?string $haystack, ?string $needle, ?int $offset = 0) : int|false
    {
        return p\Grapheme::grapheme_strpos((string) $haystack, (string) $needle, (int) $offset);
    }
}
if (!\function_exists('grapheme_strripos')) {
    function grapheme_strripos(?string $haystack, ?string $needle, ?int $offset = 0) : int|false
    {
        return p\Grapheme::grapheme_strripos((string) $haystack, (string) $needle, (int) $offset);
    }
}
if (!\function_exists('grapheme_strrpos')) {
    function grapheme_strrpos(?string $haystack, ?string $needle, ?int $offset = 0) : int|false
    {
        return p\Grapheme::grapheme_strrpos((string) $haystack, (string) $needle, (int) $offset);
    }
}
if (!\function_exists('grapheme_strstr')) {
    function grapheme_strstr(?string $haystack, ?string $needle, ?bool $beforeNeedle = \false) : string|false
    {
        return p\Grapheme::grapheme_strstr((string) $haystack, (string) $needle, (bool) $beforeNeedle);
    }
}
if (!\function_exists('grapheme_substr')) {
    function grapheme_substr(?string $string, ?int $offset, ?int $length = null) : string|false
    {
        return p\Grapheme::grapheme_substr((string) $string, (int) $offset, $length);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Intl\Normalizer as p;
if (\PHP_VERSION_ID >= 80000) {
    return require __DIR__ . '/bootstrap80.php';
}
if (!\function_exists('normalizer_is_normalized')) {
    function normalizer_is_normalized($string, $form = p\Normalizer::FORM_C)
    {
        return p\Normalizer::isNormalized($string, $form);
    }
}
if (!\function_exists('normalizer_normalize')) {
    function normalizer_normalize($string, $form = p\Normalizer::FORM_C)
    {
        return p\Normalizer::normalize($string, $form);
    }
}
Copyright (c) 2015-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Intl\Normalizer;

/**
 * Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
 *
 * It has been validated with Unicode 6.3 Normalization Conformance Test.
 * See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 *
 * @internal
 */
class Normalizer
{
    public const FORM_D = \Normalizer::FORM_D;
    public const FORM_KD = \Normalizer::FORM_KD;
    public const FORM_C = \Normalizer::FORM_C;
    public const FORM_KC = \Normalizer::FORM_KC;
    public const NFD = \Normalizer::NFD;
    public const NFKD = \Normalizer::NFKD;
    public const NFC = \Normalizer::NFC;
    public const NFKC = \Normalizer::NFKC;
    private static $C;
    private static $D;
    private static $KD;
    private static $cC;
    private static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
    private static $ASCII = " eiasntrolud][cmp'\ng|hv.fb,:=-q10C2*yx)(L9AS/P\"EjMIk3>5T<D4}B{8FwR67UGN;JzV#HOW_&!K?XQ%Y\\\tZ+~^\$@`\x00\x01\x02\x03\x04\x05\x06\x07\x08\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
    public static function isNormalized(string $s, int $form = self::FORM_C)
    {
        if (!\in_array($form, [self::NFD, self::NFKD, self::NFC, self::NFKC])) {
            return \false;
        }
        if (!isset($s[\strspn($s, self::$ASCII)])) {
            return \true;
        }
        if (self::NFC == $form && \preg_match('//u', $s) && !\preg_match('/[^\\x00-\\x{2FF}]/u', $s)) {
            return \true;
        }
        return self::normalize($s, $form) === $s;
    }
    public static function normalize(string $s, int $form = self::FORM_C)
    {
        if (!\preg_match('//u', $s)) {
            return \false;
        }
        switch ($form) {
            case self::NFC:
                $C = \true;
                $K = \false;
                break;
            case self::NFD:
                $C = \false;
                $K = \false;
                break;
            case self::NFKC:
                $C = \true;
                $K = \true;
                break;
            case self::NFKD:
                $C = \false;
                $K = \true;
                break;
            default:
                if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) {
                    return $s;
                }
                if (80000 > \PHP_VERSION_ID) {
                    return \false;
                }
                throw new \ValueError('normalizer_normalize(): Argument #2 ($form) must be a a valid normalization form');
        }
        if ('' === $s) {
            return '';
        }
        if ($K && null === self::$KD) {
            self::$KD = self::getData('compatibilityDecomposition');
        }
        if (null === self::$D) {
            self::$D = self::getData('canonicalDecomposition');
            self::$cC = self::getData('combiningClass');
        }
        if (null !== ($mbEncoding = 2 & (int) \ini_get('mbstring.func_overload') ? \mb_internal_encoding() : null)) {
            \mb_internal_encoding('8bit');
        }
        $r = self::decompose($s, $K);
        if ($C) {
            if (null === self::$C) {
                self::$C = self::getData('canonicalComposition');
            }
            $r = self::recompose($r);
        }
        if (null !== $mbEncoding) {
            \mb_internal_encoding($mbEncoding);
        }
        return $r;
    }
    private static function recompose($s)
    {
        $ASCII = self::$ASCII;
        $compMap = self::$C;
        $combClass = self::$cC;
        $ulenMask = self::$ulenMask;
        $result = $tail = '';
        $i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xf0"];
        $len = \strlen($s);
        $lastUchr = \substr($s, 0, $i);
        $lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;
        while ($i < $len) {
            if ($s[$i] < "\x80") {
                // ASCII chars
                if ($tail) {
                    $lastUchr .= $tail;
                    $tail = '';
                }
                if ($j = \strspn($s, $ASCII, $i + 1)) {
                    $lastUchr .= \substr($s, $i, $j);
                    $i += $j;
                }
                $result .= $lastUchr;
                $lastUchr = $s[$i];
                $lastUcls = 0;
                ++$i;
                continue;
            }
            $ulen = $ulenMask[$s[$i] & "\xf0"];
            $uchr = \substr($s, $i, $ulen);
            if ($lastUchr < "ᄀ" || "ᄒ" < $lastUchr || $uchr < "ᅡ" || "ᅵ" < $uchr || $lastUcls) {
                // Table lookup and combining chars composition
                $ucls = $combClass[$uchr] ?? 0;
                if (isset($compMap[$lastUchr . $uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
                    $lastUchr = $compMap[$lastUchr . $uchr];
                } elseif ($lastUcls = $ucls) {
                    $tail .= $uchr;
                } else {
                    if ($tail) {
                        $lastUchr .= $tail;
                        $tail = '';
                    }
                    $result .= $lastUchr;
                    $lastUchr = $uchr;
                }
            } else {
                // Hangul chars
                $L = \ord($lastUchr[2]) - 0x80;
                $V = \ord($uchr[2]) - 0xa1;
                $T = 0;
                $uchr = \substr($s, $i + $ulen, 3);
                if ("ᆧ" <= $uchr && $uchr <= "ᇂ") {
                    $T = \ord($uchr[2]) - 0xa7;
                    0 > $T && ($T += 0x40);
                    $ulen += 3;
                }
                $L = 0xac00 + ($L * 21 + $V) * 28 + $T;
                $lastUchr = \chr(0xe0 | $L >> 12) . \chr(0x80 | $L >> 6 & 0x3f) . \chr(0x80 | $L & 0x3f);
            }
            $i += $ulen;
        }
        return $result . $lastUchr . $tail;
    }
    private static function decompose($s, $c)
    {
        $result = '';
        $ASCII = self::$ASCII;
        $decompMap = self::$D;
        $combClass = self::$cC;
        $ulenMask = self::$ulenMask;
        if ($c) {
            $compatMap = self::$KD;
        }
        $c = [];
        $i = 0;
        $len = \strlen($s);
        while ($i < $len) {
            if ($s[$i] < "\x80") {
                // ASCII chars
                if ($c) {
                    \ksort($c);
                    $result .= \implode('', $c);
                    $c = [];
                }
                $j = 1 + \strspn($s, $ASCII, $i + 1);
                $result .= \substr($s, $i, $j);
                $i += $j;
                continue;
            }
            $ulen = $ulenMask[$s[$i] & "\xf0"];
            $uchr = \substr($s, $i, $ulen);
            $i += $ulen;
            if ($uchr < "가" || "힣" < $uchr) {
                // Table lookup
                if ($uchr !== ($j = $compatMap[$uchr] ?? $decompMap[$uchr] ?? $uchr)) {
                    $uchr = $j;
                    $j = \strlen($uchr);
                    $ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xf0"];
                    if ($ulen != $j) {
                        // Put trailing chars in $s
                        $j -= $ulen;
                        $i -= $j;
                        if (0 > $i) {
                            $s = \str_repeat(' ', -$i) . $s;
                            $len -= $i;
                            $i = 0;
                        }
                        while ($j--) {
                            $s[$i + $j] = $uchr[$ulen + $j];
                        }
                        $uchr = \substr($uchr, 0, $ulen);
                    }
                }
                if (isset($combClass[$uchr])) {
                    // Combining chars, for sorting
                    if (!isset($c[$combClass[$uchr]])) {
                        $c[$combClass[$uchr]] = '';
                    }
                    $c[$combClass[$uchr]] .= $uchr;
                    continue;
                }
            } else {
                // Hangul chars
                $uchr = \unpack('C*', $uchr);
                $j = ($uchr[1] - 224 << 12) + ($uchr[2] - 128 << 6) + $uchr[3] - 0xac80;
                $uchr = "\xe1\x84" . \chr(0x80 + (int) ($j / 588)) . "\xe1\x85" . \chr(0xa1 + (int) ($j % 588 / 28));
                if ($j %= 28) {
                    $uchr .= $j < 25 ? "\xe1\x86" . \chr(0xa7 + $j) : "\xe1\x87" . \chr(0x67 + $j);
                }
            }
            if ($c) {
                \ksort($c);
                $result .= \implode('', $c);
                $c = [];
            }
            $result .= $uchr;
        }
        if ($c) {
            \ksort($c);
            $result .= \implode('', $c);
        }
        return $result;
    }
    private static function getData($file)
    {
        if (\file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) {
            return require $file;
        }
        return \false;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

class Normalizer extends Symfony\Polyfill\Intl\Normalizer\Normalizer
{
    /**
     * @deprecated since ICU 56 and removed in PHP 8
     */
    public const NONE = 2;
    public const FORM_D = 4;
    public const FORM_KD = 8;
    public const FORM_C = 16;
    public const FORM_KC = 32;
    public const NFD = 4;
    public const NFKD = 8;
    public const NFC = 16;
    public const NFKC = 32;
}
<?php

namespace _HumbugBox1cb33d1f20f1;

return array(' ' => ' ', '¨' => ' ̈', 'ª' => 'a', '¯' => ' ̄', '²' => '2', '³' => '3', '´' => ' ́', 'µ' => 'μ', '¸' => ' ̧', '¹' => '1', 'º' => 'o', '¼' => '1⁄4', '½' => '1⁄2', '¾' => '3⁄4', 'IJ' => 'IJ', 'ij' => 'ij', 'Ŀ' => 'L·', 'ŀ' => 'l·', 'ʼn' => 'ʼn', 'ſ' => 's', 'DŽ' => 'DŽ', 'Dž' => 'Dž', 'dž' => 'dž', 'LJ' => 'LJ', 'Lj' => 'Lj', 'lj' => 'lj', 'NJ' => 'NJ', 'Nj' => 'Nj', 'nj' => 'nj', 'DZ' => 'DZ', 'Dz' => 'Dz', 'dz' => 'dz', 'ʰ' => 'h', 'ʱ' => 'ɦ', 'ʲ' => 'j', 'ʳ' => 'r', 'ʴ' => 'ɹ', 'ʵ' => 'ɻ', 'ʶ' => 'ʁ', 'ʷ' => 'w', 'ʸ' => 'y', '˘' => ' ̆', '˙' => ' ̇', '˚' => ' ̊', '˛' => ' ̨', '˜' => ' ̃', '˝' => ' ̋', 'ˠ' => 'ɣ', 'ˡ' => 'l', 'ˢ' => 's', 'ˣ' => 'x', 'ˤ' => 'ʕ', 'ͺ' => ' ͅ', '΄' => ' ́', '΅' => ' ̈́', 'ϐ' => 'β', 'ϑ' => 'θ', 'ϒ' => 'Υ', 'ϓ' => 'Ύ', 'ϔ' => 'Ϋ', 'ϕ' => 'φ', 'ϖ' => 'π', 'ϰ' => 'κ', 'ϱ' => 'ρ', 'ϲ' => 'ς', 'ϴ' => 'Θ', 'ϵ' => 'ε', 'Ϲ' => 'Σ', 'և' => 'եւ', 'ٵ' => 'اٴ', 'ٶ' => 'وٴ', 'ٷ' => 'ۇٴ', 'ٸ' => 'يٴ', 'ำ' => 'ํา', 'ຳ' => 'ໍາ', 'ໜ' => 'ຫນ', 'ໝ' => 'ຫມ', '༌' => '་', 'ཷ' => 'ྲཱྀ', 'ཹ' => 'ླཱྀ', 'ჼ' => 'ნ', 'ᴬ' => 'A', 'ᴭ' => 'Æ', 'ᴮ' => 'B', 'ᴰ' => 'D', 'ᴱ' => 'E', 'ᴲ' => 'Ǝ', 'ᴳ' => 'G', 'ᴴ' => 'H', 'ᴵ' => 'I', 'ᴶ' => 'J', 'ᴷ' => 'K', 'ᴸ' => 'L', 'ᴹ' => 'M', 'ᴺ' => 'N', 'ᴼ' => 'O', 'ᴽ' => 'Ȣ', 'ᴾ' => 'P', 'ᴿ' => 'R', 'ᵀ' => 'T', 'ᵁ' => 'U', 'ᵂ' => 'W', 'ᵃ' => 'a', 'ᵄ' => 'ɐ', 'ᵅ' => 'ɑ', 'ᵆ' => 'ᴂ', 'ᵇ' => 'b', 'ᵈ' => 'd', 'ᵉ' => 'e', 'ᵊ' => 'ə', 'ᵋ' => 'ɛ', 'ᵌ' => 'ɜ', 'ᵍ' => 'g', 'ᵏ' => 'k', 'ᵐ' => 'm', 'ᵑ' => 'ŋ', 'ᵒ' => 'o', 'ᵓ' => 'ɔ', 'ᵔ' => 'ᴖ', 'ᵕ' => 'ᴗ', 'ᵖ' => 'p', 'ᵗ' => 't', 'ᵘ' => 'u', 'ᵙ' => 'ᴝ', 'ᵚ' => 'ɯ', 'ᵛ' => 'v', 'ᵜ' => 'ᴥ', 'ᵝ' => 'β', 'ᵞ' => 'γ', 'ᵟ' => 'δ', 'ᵠ' => 'φ', 'ᵡ' => 'χ', 'ᵢ' => 'i', 'ᵣ' => 'r', 'ᵤ' => 'u', 'ᵥ' => 'v', 'ᵦ' => 'β', 'ᵧ' => 'γ', 'ᵨ' => 'ρ', 'ᵩ' => 'φ', 'ᵪ' => 'χ', 'ᵸ' => 'н', 'ᶛ' => 'ɒ', 'ᶜ' => 'c', 'ᶝ' => 'ɕ', 'ᶞ' => 'ð', 'ᶟ' => 'ɜ', 'ᶠ' => 'f', 'ᶡ' => 'ɟ', 'ᶢ' => 'ɡ', 'ᶣ' => 'ɥ', 'ᶤ' => 'ɨ', 'ᶥ' => 'ɩ', 'ᶦ' => 'ɪ', 'ᶧ' => 'ᵻ', 'ᶨ' => 'ʝ', 'ᶩ' => 'ɭ', 'ᶪ' => 'ᶅ', 'ᶫ' => 'ʟ', 'ᶬ' => 'ɱ', 'ᶭ' => 'ɰ', 'ᶮ' => 'ɲ', 'ᶯ' => 'ɳ', 'ᶰ' => 'ɴ', 'ᶱ' => 'ɵ', 'ᶲ' => 'ɸ', 'ᶳ' => 'ʂ', 'ᶴ' => 'ʃ', 'ᶵ' => 'ƫ', 'ᶶ' => 'ʉ', 'ᶷ' => 'ʊ', 'ᶸ' => 'ᴜ', 'ᶹ' => 'ʋ', 'ᶺ' => 'ʌ', 'ᶻ' => 'z', 'ᶼ' => 'ʐ', 'ᶽ' => 'ʑ', 'ᶾ' => 'ʒ', 'ᶿ' => 'θ', 'ẚ' => 'aʾ', 'ẛ' => 'ṡ', '᾽' => ' ̓', '᾿' => ' ̓', '῀' => ' ͂', '῁' => ' ̈͂', '῍' => ' ̓̀', '῎' => ' ̓́', '῏' => ' ̓͂', '῝' => ' ̔̀', '῞' => ' ̔́', '῟' => ' ̔͂', '῭' => ' ̈̀', '΅' => ' ̈́', '´' => ' ́', '῾' => ' ̔', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', ' ' => ' ', '‑' => '‐', '‗' => ' ̳', '․' => '.', '‥' => '..', '…' => '...', ' ' => ' ', '″' => '′′', '‴' => '′′′', '‶' => '‵‵', '‷' => '‵‵‵', '‼' => '!!', '‾' => ' ̅', '⁇' => '??', '⁈' => '?!', '⁉' => '!?', '⁗' => '′′′′', ' ' => ' ', '⁰' => '0', 'ⁱ' => 'i', '⁴' => '4', '⁵' => '5', '⁶' => '6', '⁷' => '7', '⁸' => '8', '⁹' => '9', '⁺' => '+', '⁻' => '−', '⁼' => '=', '⁽' => '(', '⁾' => ')', 'ⁿ' => 'n', '₀' => '0', '₁' => '1', '₂' => '2', '₃' => '3', '₄' => '4', '₅' => '5', '₆' => '6', '₇' => '7', '₈' => '8', '₉' => '9', '₊' => '+', '₋' => '−', '₌' => '=', '₍' => '(', '₎' => ')', 'ₐ' => 'a', 'ₑ' => 'e', 'ₒ' => 'o', 'ₓ' => 'x', 'ₔ' => 'ə', 'ₕ' => 'h', 'ₖ' => 'k', 'ₗ' => 'l', 'ₘ' => 'm', 'ₙ' => 'n', 'ₚ' => 'p', 'ₛ' => 's', 'ₜ' => 't', '₨' => 'Rs', '℀' => 'a/c', '℁' => 'a/s', 'ℂ' => 'C', '℃' => '°C', '℅' => 'c/o', '℆' => 'c/u', 'ℇ' => 'Ɛ', '℉' => '°F', 'ℊ' => 'g', 'ℋ' => 'H', 'ℌ' => 'H', 'ℍ' => 'H', 'ℎ' => 'h', 'ℏ' => 'ħ', 'ℐ' => 'I', 'ℑ' => 'I', 'ℒ' => 'L', 'ℓ' => 'l', 'ℕ' => 'N', '№' => 'No', 'ℙ' => 'P', 'ℚ' => 'Q', 'ℛ' => 'R', 'ℜ' => 'R', 'ℝ' => 'R', '℠' => 'SM', '℡' => 'TEL', '™' => 'TM', 'ℤ' => 'Z', 'ℨ' => 'Z', 'ℬ' => 'B', 'ℭ' => 'C', 'ℯ' => 'e', 'ℰ' => 'E', 'ℱ' => 'F', 'ℳ' => 'M', 'ℴ' => 'o', 'ℵ' => 'א', 'ℶ' => 'ב', 'ℷ' => 'ג', 'ℸ' => 'ד', 'ℹ' => 'i', '℻' => 'FAX', 'ℼ' => 'π', 'ℽ' => 'γ', 'ℾ' => 'Γ', 'ℿ' => 'Π', '⅀' => '∑', 'ⅅ' => 'D', 'ⅆ' => 'd', 'ⅇ' => 'e', 'ⅈ' => 'i', 'ⅉ' => 'j', '⅐' => '1⁄7', '⅑' => '1⁄9', '⅒' => '1⁄10', '⅓' => '1⁄3', '⅔' => '2⁄3', '⅕' => '1⁄5', '⅖' => '2⁄5', '⅗' => '3⁄5', '⅘' => '4⁄5', '⅙' => '1⁄6', '⅚' => '5⁄6', '⅛' => '1⁄8', '⅜' => '3⁄8', '⅝' => '5⁄8', '⅞' => '7⁄8', '⅟' => '1⁄', 'Ⅰ' => 'I', 'Ⅱ' => 'II', 'Ⅲ' => 'III', 'Ⅳ' => 'IV', 'Ⅴ' => 'V', 'Ⅵ' => 'VI', 'Ⅶ' => 'VII', 'Ⅷ' => 'VIII', 'Ⅸ' => 'IX', 'Ⅹ' => 'X', 'Ⅺ' => 'XI', 'Ⅻ' => 'XII', 'Ⅼ' => 'L', 'Ⅽ' => 'C', 'Ⅾ' => 'D', 'Ⅿ' => 'M', 'ⅰ' => 'i', 'ⅱ' => 'ii', 'ⅲ' => 'iii', 'ⅳ' => 'iv', 'ⅴ' => 'v', 'ⅵ' => 'vi', 'ⅶ' => 'vii', 'ⅷ' => 'viii', 'ⅸ' => 'ix', 'ⅹ' => 'x', 'ⅺ' => 'xi', 'ⅻ' => 'xii', 'ⅼ' => 'l', 'ⅽ' => 'c', 'ⅾ' => 'd', 'ⅿ' => 'm', '↉' => '0⁄3', '∬' => '∫∫', '∭' => '∫∫∫', '∯' => '∮∮', '∰' => '∮∮∮', '①' => '1', '②' => '2', '③' => '3', '④' => '4', '⑤' => '5', '⑥' => '6', '⑦' => '7', '⑧' => '8', '⑨' => '9', '⑩' => '10', '⑪' => '11', '⑫' => '12', '⑬' => '13', '⑭' => '14', '⑮' => '15', '⑯' => '16', '⑰' => '17', '⑱' => '18', '⑲' => '19', '⑳' => '20', '⑴' => '(1)', '⑵' => '(2)', '⑶' => '(3)', '⑷' => '(4)', '⑸' => '(5)', '⑹' => '(6)', '⑺' => '(7)', '⑻' => '(8)', '⑼' => '(9)', '⑽' => '(10)', '⑾' => '(11)', '⑿' => '(12)', '⒀' => '(13)', '⒁' => '(14)', '⒂' => '(15)', '⒃' => '(16)', '⒄' => '(17)', '⒅' => '(18)', '⒆' => '(19)', '⒇' => '(20)', '⒈' => '1.', '⒉' => '2.', '⒊' => '3.', '⒋' => '4.', '⒌' => '5.', '⒍' => '6.', '⒎' => '7.', '⒏' => '8.', '⒐' => '9.', '⒑' => '10.', '⒒' => '11.', '⒓' => '12.', '⒔' => '13.', '⒕' => '14.', '⒖' => '15.', '⒗' => '16.', '⒘' => '17.', '⒙' => '18.', '⒚' => '19.', '⒛' => '20.', '⒜' => '(a)', '⒝' => '(b)', '⒞' => '(c)', '⒟' => '(d)', '⒠' => '(e)', '⒡' => '(f)', '⒢' => '(g)', '⒣' => '(h)', '⒤' => '(i)', '⒥' => '(j)', '⒦' => '(k)', '⒧' => '(l)', '⒨' => '(m)', '⒩' => '(n)', '⒪' => '(o)', '⒫' => '(p)', '⒬' => '(q)', '⒭' => '(r)', '⒮' => '(s)', '⒯' => '(t)', '⒰' => '(u)', '⒱' => '(v)', '⒲' => '(w)', '⒳' => '(x)', '⒴' => '(y)', '⒵' => '(z)', 'Ⓐ' => 'A', 'Ⓑ' => 'B', 'Ⓒ' => 'C', 'Ⓓ' => 'D', 'Ⓔ' => 'E', 'Ⓕ' => 'F', 'Ⓖ' => 'G', 'Ⓗ' => 'H', 'Ⓘ' => 'I', 'Ⓙ' => 'J', 'Ⓚ' => 'K', 'Ⓛ' => 'L', 'Ⓜ' => 'M', 'Ⓝ' => 'N', 'Ⓞ' => 'O', 'Ⓟ' => 'P', 'Ⓠ' => 'Q', 'Ⓡ' => 'R', 'Ⓢ' => 'S', 'Ⓣ' => 'T', 'Ⓤ' => 'U', 'Ⓥ' => 'V', 'Ⓦ' => 'W', 'Ⓧ' => 'X', 'Ⓨ' => 'Y', 'Ⓩ' => 'Z', 'ⓐ' => 'a', 'ⓑ' => 'b', 'ⓒ' => 'c', 'ⓓ' => 'd', 'ⓔ' => 'e', 'ⓕ' => 'f', 'ⓖ' => 'g', 'ⓗ' => 'h', 'ⓘ' => 'i', 'ⓙ' => 'j', 'ⓚ' => 'k', 'ⓛ' => 'l', 'ⓜ' => 'm', 'ⓝ' => 'n', 'ⓞ' => 'o', 'ⓟ' => 'p', 'ⓠ' => 'q', 'ⓡ' => 'r', 'ⓢ' => 's', 'ⓣ' => 't', 'ⓤ' => 'u', 'ⓥ' => 'v', 'ⓦ' => 'w', 'ⓧ' => 'x', 'ⓨ' => 'y', 'ⓩ' => 'z', '⓪' => '0', '⨌' => '∫∫∫∫', '⩴' => '::=', '⩵' => '==', '⩶' => '===', 'ⱼ' => 'j', 'ⱽ' => 'V', 'ⵯ' => 'ⵡ', '⺟' => '母', '⻳' => '龟', '⼀' => '一', '⼁' => '丨', '⼂' => '丶', '⼃' => '丿', '⼄' => '乙', '⼅' => '亅', '⼆' => '二', '⼇' => '亠', '⼈' => '人', '⼉' => '儿', '⼊' => '入', '⼋' => '八', '⼌' => '冂', '⼍' => '冖', '⼎' => '冫', '⼏' => '几', '⼐' => '凵', '⼑' => '刀', '⼒' => '力', '⼓' => '勹', '⼔' => '匕', '⼕' => '匚', '⼖' => '匸', '⼗' => '十', '⼘' => '卜', '⼙' => '卩', '⼚' => '厂', '⼛' => '厶', '⼜' => '又', '⼝' => '口', '⼞' => '囗', '⼟' => '土', '⼠' => '士', '⼡' => '夂', '⼢' => '夊', '⼣' => '夕', '⼤' => '大', '⼥' => '女', '⼦' => '子', '⼧' => '宀', '⼨' => '寸', '⼩' => '小', '⼪' => '尢', '⼫' => '尸', '⼬' => '屮', '⼭' => '山', '⼮' => '巛', '⼯' => '工', '⼰' => '己', '⼱' => '巾', '⼲' => '干', '⼳' => '幺', '⼴' => '广', '⼵' => '廴', '⼶' => '廾', '⼷' => '弋', '⼸' => '弓', '⼹' => '彐', '⼺' => '彡', '⼻' => '彳', '⼼' => '心', '⼽' => '戈', '⼾' => '戶', '⼿' => '手', '⽀' => '支', '⽁' => '攴', '⽂' => '文', '⽃' => '斗', '⽄' => '斤', '⽅' => '方', '⽆' => '无', '⽇' => '日', '⽈' => '曰', '⽉' => '月', '⽊' => '木', '⽋' => '欠', '⽌' => '止', '⽍' => '歹', '⽎' => '殳', '⽏' => '毋', '⽐' => '比', '⽑' => '毛', '⽒' => '氏', '⽓' => '气', '⽔' => '水', '⽕' => '火', '⽖' => '爪', '⽗' => '父', '⽘' => '爻', '⽙' => '爿', '⽚' => '片', '⽛' => '牙', '⽜' => '牛', '⽝' => '犬', '⽞' => '玄', '⽟' => '玉', '⽠' => '瓜', '⽡' => '瓦', '⽢' => '甘', '⽣' => '生', '⽤' => '用', '⽥' => '田', '⽦' => '疋', '⽧' => '疒', '⽨' => '癶', '⽩' => '白', '⽪' => '皮', '⽫' => '皿', '⽬' => '目', '⽭' => '矛', '⽮' => '矢', '⽯' => '石', '⽰' => '示', '⽱' => '禸', '⽲' => '禾', '⽳' => '穴', '⽴' => '立', '⽵' => '竹', '⽶' => '米', '⽷' => '糸', '⽸' => '缶', '⽹' => '网', '⽺' => '羊', '⽻' => '羽', '⽼' => '老', '⽽' => '而', '⽾' => '耒', '⽿' => '耳', '⾀' => '聿', '⾁' => '肉', '⾂' => '臣', '⾃' => '自', '⾄' => '至', '⾅' => '臼', '⾆' => '舌', '⾇' => '舛', '⾈' => '舟', '⾉' => '艮', '⾊' => '色', '⾋' => '艸', '⾌' => '虍', '⾍' => '虫', '⾎' => '血', '⾏' => '行', '⾐' => '衣', '⾑' => '襾', '⾒' => '見', '⾓' => '角', '⾔' => '言', '⾕' => '谷', '⾖' => '豆', '⾗' => '豕', '⾘' => '豸', '⾙' => '貝', '⾚' => '赤', '⾛' => '走', '⾜' => '足', '⾝' => '身', '⾞' => '車', '⾟' => '辛', '⾠' => '辰', '⾡' => '辵', '⾢' => '邑', '⾣' => '酉', '⾤' => '釆', '⾥' => '里', '⾦' => '金', '⾧' => '長', '⾨' => '門', '⾩' => '阜', '⾪' => '隶', '⾫' => '隹', '⾬' => '雨', '⾭' => '靑', '⾮' => '非', '⾯' => '面', '⾰' => '革', '⾱' => '韋', '⾲' => '韭', '⾳' => '音', '⾴' => '頁', '⾵' => '風', '⾶' => '飛', '⾷' => '食', '⾸' => '首', '⾹' => '香', '⾺' => '馬', '⾻' => '骨', '⾼' => '高', '⾽' => '髟', '⾾' => '鬥', '⾿' => '鬯', '⿀' => '鬲', '⿁' => '鬼', '⿂' => '魚', '⿃' => '鳥', '⿄' => '鹵', '⿅' => '鹿', '⿆' => '麥', '⿇' => '麻', '⿈' => '黃', '⿉' => '黍', '⿊' => '黑', '⿋' => '黹', '⿌' => '黽', '⿍' => '鼎', '⿎' => '鼓', '⿏' => '鼠', '⿐' => '鼻', '⿑' => '齊', '⿒' => '齒', '⿓' => '龍', '⿔' => '龜', '⿕' => '龠', ' ' => ' ', '〶' => '〒', '〸' => '十', '〹' => '卄', '〺' => '卅', '゛' => ' ゙', '゜' => ' ゚', 'ゟ' => 'より', 'ヿ' => 'コト', 'ㄱ' => 'ᄀ', 'ㄲ' => 'ᄁ', 'ㄳ' => 'ᆪ', 'ㄴ' => 'ᄂ', 'ㄵ' => 'ᆬ', 'ㄶ' => 'ᆭ', 'ㄷ' => 'ᄃ', 'ㄸ' => 'ᄄ', 'ㄹ' => 'ᄅ', 'ㄺ' => 'ᆰ', 'ㄻ' => 'ᆱ', 'ㄼ' => 'ᆲ', 'ㄽ' => 'ᆳ', 'ㄾ' => 'ᆴ', 'ㄿ' => 'ᆵ', 'ㅀ' => 'ᄚ', 'ㅁ' => 'ᄆ', 'ㅂ' => 'ᄇ', 'ㅃ' => 'ᄈ', 'ㅄ' => 'ᄡ', 'ㅅ' => 'ᄉ', 'ㅆ' => 'ᄊ', 'ㅇ' => 'ᄋ', 'ㅈ' => 'ᄌ', 'ㅉ' => 'ᄍ', 'ㅊ' => 'ᄎ', 'ㅋ' => 'ᄏ', 'ㅌ' => 'ᄐ', 'ㅍ' => 'ᄑ', 'ㅎ' => 'ᄒ', 'ㅏ' => 'ᅡ', 'ㅐ' => 'ᅢ', 'ㅑ' => 'ᅣ', 'ㅒ' => 'ᅤ', 'ㅓ' => 'ᅥ', 'ㅔ' => 'ᅦ', 'ㅕ' => 'ᅧ', 'ㅖ' => 'ᅨ', 'ㅗ' => 'ᅩ', 'ㅘ' => 'ᅪ', 'ㅙ' => 'ᅫ', 'ㅚ' => 'ᅬ', 'ㅛ' => 'ᅭ', 'ㅜ' => 'ᅮ', 'ㅝ' => 'ᅯ', 'ㅞ' => 'ᅰ', 'ㅟ' => 'ᅱ', 'ㅠ' => 'ᅲ', 'ㅡ' => 'ᅳ', 'ㅢ' => 'ᅴ', 'ㅣ' => 'ᅵ', 'ㅤ' => 'ᅠ', 'ㅥ' => 'ᄔ', 'ㅦ' => 'ᄕ', 'ㅧ' => 'ᇇ', 'ㅨ' => 'ᇈ', 'ㅩ' => 'ᇌ', 'ㅪ' => 'ᇎ', 'ㅫ' => 'ᇓ', 'ㅬ' => 'ᇗ', 'ㅭ' => 'ᇙ', 'ㅮ' => 'ᄜ', 'ㅯ' => 'ᇝ', 'ㅰ' => 'ᇟ', 'ㅱ' => 'ᄝ', 'ㅲ' => 'ᄞ', 'ㅳ' => 'ᄠ', 'ㅴ' => 'ᄢ', 'ㅵ' => 'ᄣ', 'ㅶ' => 'ᄧ', 'ㅷ' => 'ᄩ', 'ㅸ' => 'ᄫ', 'ㅹ' => 'ᄬ', 'ㅺ' => 'ᄭ', 'ㅻ' => 'ᄮ', 'ㅼ' => 'ᄯ', 'ㅽ' => 'ᄲ', 'ㅾ' => 'ᄶ', 'ㅿ' => 'ᅀ', 'ㆀ' => 'ᅇ', 'ㆁ' => 'ᅌ', 'ㆂ' => 'ᇱ', 'ㆃ' => 'ᇲ', 'ㆄ' => 'ᅗ', 'ㆅ' => 'ᅘ', 'ㆆ' => 'ᅙ', 'ㆇ' => 'ᆄ', 'ㆈ' => 'ᆅ', 'ㆉ' => 'ᆈ', 'ㆊ' => 'ᆑ', 'ㆋ' => 'ᆒ', 'ㆌ' => 'ᆔ', 'ㆍ' => 'ᆞ', 'ㆎ' => 'ᆡ', '㆒' => '一', '㆓' => '二', '㆔' => '三', '㆕' => '四', '㆖' => '上', '㆗' => '中', '㆘' => '下', '㆙' => '甲', '㆚' => '乙', '㆛' => '丙', '㆜' => '丁', '㆝' => '天', '㆞' => '地', '㆟' => '人', '㈀' => '(ᄀ)', '㈁' => '(ᄂ)', '㈂' => '(ᄃ)', '㈃' => '(ᄅ)', '㈄' => '(ᄆ)', '㈅' => '(ᄇ)', '㈆' => '(ᄉ)', '㈇' => '(ᄋ)', '㈈' => '(ᄌ)', '㈉' => '(ᄎ)', '㈊' => '(ᄏ)', '㈋' => '(ᄐ)', '㈌' => '(ᄑ)', '㈍' => '(ᄒ)', '㈎' => '(가)', '㈏' => '(나)', '㈐' => '(다)', '㈑' => '(라)', '㈒' => '(마)', '㈓' => '(바)', '㈔' => '(사)', '㈕' => '(아)', '㈖' => '(자)', '㈗' => '(차)', '㈘' => '(카)', '㈙' => '(타)', '㈚' => '(파)', '㈛' => '(하)', '㈜' => '(주)', '㈝' => '(오전)', '㈞' => '(오후)', '㈠' => '(一)', '㈡' => '(二)', '㈢' => '(三)', '㈣' => '(四)', '㈤' => '(五)', '㈥' => '(六)', '㈦' => '(七)', '㈧' => '(八)', '㈨' => '(九)', '㈩' => '(十)', '㈪' => '(月)', '㈫' => '(火)', '㈬' => '(水)', '㈭' => '(木)', '㈮' => '(金)', '㈯' => '(土)', '㈰' => '(日)', '㈱' => '(株)', '㈲' => '(有)', '㈳' => '(社)', '㈴' => '(名)', '㈵' => '(特)', '㈶' => '(財)', '㈷' => '(祝)', '㈸' => '(労)', '㈹' => '(代)', '㈺' => '(呼)', '㈻' => '(学)', '㈼' => '(監)', '㈽' => '(企)', '㈾' => '(資)', '㈿' => '(協)', '㉀' => '(祭)', '㉁' => '(休)', '㉂' => '(自)', '㉃' => '(至)', '㉄' => '問', '㉅' => '幼', '㉆' => '文', '㉇' => '箏', '㉐' => 'PTE', '㉑' => '21', '㉒' => '22', '㉓' => '23', '㉔' => '24', '㉕' => '25', '㉖' => '26', '㉗' => '27', '㉘' => '28', '㉙' => '29', '㉚' => '30', '㉛' => '31', '㉜' => '32', '㉝' => '33', '㉞' => '34', '㉟' => '35', '㉠' => 'ᄀ', '㉡' => 'ᄂ', '㉢' => 'ᄃ', '㉣' => 'ᄅ', '㉤' => 'ᄆ', '㉥' => 'ᄇ', '㉦' => 'ᄉ', '㉧' => 'ᄋ', '㉨' => 'ᄌ', '㉩' => 'ᄎ', '㉪' => 'ᄏ', '㉫' => 'ᄐ', '㉬' => 'ᄑ', '㉭' => 'ᄒ', '㉮' => '가', '㉯' => '나', '㉰' => '다', '㉱' => '라', '㉲' => '마', '㉳' => '바', '㉴' => '사', '㉵' => '아', '㉶' => '자', '㉷' => '차', '㉸' => '카', '㉹' => '타', '㉺' => '파', '㉻' => '하', '㉼' => '참고', '㉽' => '주의', '㉾' => '우', '㊀' => '一', '㊁' => '二', '㊂' => '三', '㊃' => '四', '㊄' => '五', '㊅' => '六', '㊆' => '七', '㊇' => '八', '㊈' => '九', '㊉' => '十', '㊊' => '月', '㊋' => '火', '㊌' => '水', '㊍' => '木', '㊎' => '金', '㊏' => '土', '㊐' => '日', '㊑' => '株', '㊒' => '有', '㊓' => '社', '㊔' => '名', '㊕' => '特', '㊖' => '財', '㊗' => '祝', '㊘' => '労', '㊙' => '秘', '㊚' => '男', '㊛' => '女', '㊜' => '適', '㊝' => '優', '㊞' => '印', '㊟' => '注', '㊠' => '項', '㊡' => '休', '㊢' => '写', '㊣' => '正', '㊤' => '上', '㊥' => '中', '㊦' => '下', '㊧' => '左', '㊨' => '右', '㊩' => '医', '㊪' => '宗', '㊫' => '学', '㊬' => '監', '㊭' => '企', '㊮' => '資', '㊯' => '協', '㊰' => '夜', '㊱' => '36', '㊲' => '37', '㊳' => '38', '㊴' => '39', '㊵' => '40', '㊶' => '41', '㊷' => '42', '㊸' => '43', '㊹' => '44', '㊺' => '45', '㊻' => '46', '㊼' => '47', '㊽' => '48', '㊾' => '49', '㊿' => '50', '㋀' => '1月', '㋁' => '2月', '㋂' => '3月', '㋃' => '4月', '㋄' => '5月', '㋅' => '6月', '㋆' => '7月', '㋇' => '8月', '㋈' => '9月', '㋉' => '10月', '㋊' => '11月', '㋋' => '12月', '㋌' => 'Hg', '㋍' => 'erg', '㋎' => 'eV', '㋏' => 'LTD', '㋐' => 'ア', '㋑' => 'イ', '㋒' => 'ウ', '㋓' => 'エ', '㋔' => 'オ', '㋕' => 'カ', '㋖' => 'キ', '㋗' => 'ク', '㋘' => 'ケ', '㋙' => 'コ', '㋚' => 'サ', '㋛' => 'シ', '㋜' => 'ス', '㋝' => 'セ', '㋞' => 'ソ', '㋟' => 'タ', '㋠' => 'チ', '㋡' => 'ツ', '㋢' => 'テ', '㋣' => 'ト', '㋤' => 'ナ', '㋥' => 'ニ', '㋦' => 'ヌ', '㋧' => 'ネ', '㋨' => 'ノ', '㋩' => 'ハ', '㋪' => 'ヒ', '㋫' => 'フ', '㋬' => 'ヘ', '㋭' => 'ホ', '㋮' => 'マ', '㋯' => 'ミ', '㋰' => 'ム', '㋱' => 'メ', '㋲' => 'モ', '㋳' => 'ヤ', '㋴' => 'ユ', '㋵' => 'ヨ', '㋶' => 'ラ', '㋷' => 'リ', '㋸' => 'ル', '㋹' => 'レ', '㋺' => 'ロ', '㋻' => 'ワ', '㋼' => 'ヰ', '㋽' => 'ヱ', '㋾' => 'ヲ', '㋿' => '令和', '㌀' => 'アパート', '㌁' => 'アルファ', '㌂' => 'アンペア', '㌃' => 'アール', '㌄' => 'イニング', '㌅' => 'インチ', '㌆' => 'ウォン', '㌇' => 'エスクード', '㌈' => 'エーカー', '㌉' => 'オンス', '㌊' => 'オーム', '㌋' => 'カイリ', '㌌' => 'カラット', '㌍' => 'カロリー', '㌎' => 'ガロン', '㌏' => 'ガンマ', '㌐' => 'ギガ', '㌑' => 'ギニー', '㌒' => 'キュリー', '㌓' => 'ギルダー', '㌔' => 'キロ', '㌕' => 'キログラム', '㌖' => 'キロメートル', '㌗' => 'キロワット', '㌘' => 'グラム', '㌙' => 'グラムトン', '㌚' => 'クルゼイロ', '㌛' => 'クローネ', '㌜' => 'ケース', '㌝' => 'コルナ', '㌞' => 'コーポ', '㌟' => 'サイクル', '㌠' => 'サンチーム', '㌡' => 'シリング', '㌢' => 'センチ', '㌣' => 'セント', '㌤' => 'ダース', '㌥' => 'デシ', '㌦' => 'ドル', '㌧' => 'トン', '㌨' => 'ナノ', '㌩' => 'ノット', '㌪' => 'ハイツ', '㌫' => 'パーセント', '㌬' => 'パーツ', '㌭' => 'バーレル', '㌮' => 'ピアストル', '㌯' => 'ピクル', '㌰' => 'ピコ', '㌱' => 'ビル', '㌲' => 'ファラッド', '㌳' => 'フィート', '㌴' => 'ブッシェル', '㌵' => 'フラン', '㌶' => 'ヘクタール', '㌷' => 'ペソ', '㌸' => 'ペニヒ', '㌹' => 'ヘルツ', '㌺' => 'ペンス', '㌻' => 'ページ', '㌼' => 'ベータ', '㌽' => 'ポイント', '㌾' => 'ボルト', '㌿' => 'ホン', '㍀' => 'ポンド', '㍁' => 'ホール', '㍂' => 'ホーン', '㍃' => 'マイクロ', '㍄' => 'マイル', '㍅' => 'マッハ', '㍆' => 'マルク', '㍇' => 'マンション', '㍈' => 'ミクロン', '㍉' => 'ミリ', '㍊' => 'ミリバール', '㍋' => 'メガ', '㍌' => 'メガトン', '㍍' => 'メートル', '㍎' => 'ヤード', '㍏' => 'ヤール', '㍐' => 'ユアン', '㍑' => 'リットル', '㍒' => 'リラ', '㍓' => 'ルピー', '㍔' => 'ルーブル', '㍕' => 'レム', '㍖' => 'レントゲン', '㍗' => 'ワット', '㍘' => '0点', '㍙' => '1点', '㍚' => '2点', '㍛' => '3点', '㍜' => '4点', '㍝' => '5点', '㍞' => '6点', '㍟' => '7点', '㍠' => '8点', '㍡' => '9点', '㍢' => '10点', '㍣' => '11点', '㍤' => '12点', '㍥' => '13点', '㍦' => '14点', '㍧' => '15点', '㍨' => '16点', '㍩' => '17点', '㍪' => '18点', '㍫' => '19点', '㍬' => '20点', '㍭' => '21点', '㍮' => '22点', '㍯' => '23点', '㍰' => '24点', '㍱' => 'hPa', '㍲' => 'da', '㍳' => 'AU', '㍴' => 'bar', '㍵' => 'oV', '㍶' => 'pc', '㍷' => 'dm', '㍸' => 'dm2', '㍹' => 'dm3', '㍺' => 'IU', '㍻' => '平成', '㍼' => '昭和', '㍽' => '大正', '㍾' => '明治', '㍿' => '株式会社', '㎀' => 'pA', '㎁' => 'nA', '㎂' => 'μA', '㎃' => 'mA', '㎄' => 'kA', '㎅' => 'KB', '㎆' => 'MB', '㎇' => 'GB', '㎈' => 'cal', '㎉' => 'kcal', '㎊' => 'pF', '㎋' => 'nF', '㎌' => 'μF', '㎍' => 'μg', '㎎' => 'mg', '㎏' => 'kg', '㎐' => 'Hz', '㎑' => 'kHz', '㎒' => 'MHz', '㎓' => 'GHz', '㎔' => 'THz', '㎕' => 'μl', '㎖' => 'ml', '㎗' => 'dl', '㎘' => 'kl', '㎙' => 'fm', '㎚' => 'nm', '㎛' => 'μm', '㎜' => 'mm', '㎝' => 'cm', '㎞' => 'km', '㎟' => 'mm2', '㎠' => 'cm2', '㎡' => 'm2', '㎢' => 'km2', '㎣' => 'mm3', '㎤' => 'cm3', '㎥' => 'm3', '㎦' => 'km3', '㎧' => 'm∕s', '㎨' => 'm∕s2', '㎩' => 'Pa', '㎪' => 'kPa', '㎫' => 'MPa', '㎬' => 'GPa', '㎭' => 'rad', '㎮' => 'rad∕s', '㎯' => 'rad∕s2', '㎰' => 'ps', '㎱' => 'ns', '㎲' => 'μs', '㎳' => 'ms', '㎴' => 'pV', '㎵' => 'nV', '㎶' => 'μV', '㎷' => 'mV', '㎸' => 'kV', '㎹' => 'MV', '㎺' => 'pW', '㎻' => 'nW', '㎼' => 'μW', '㎽' => 'mW', '㎾' => 'kW', '㎿' => 'MW', '㏀' => 'kΩ', '㏁' => 'MΩ', '㏂' => 'a.m.', '㏃' => 'Bq', '㏄' => 'cc', '㏅' => 'cd', '㏆' => 'C∕kg', '㏇' => 'Co.', '㏈' => 'dB', '㏉' => 'Gy', '㏊' => 'ha', '㏋' => 'HP', '㏌' => 'in', '㏍' => 'KK', '㏎' => 'KM', '㏏' => 'kt', '㏐' => 'lm', '㏑' => 'ln', '㏒' => 'log', '㏓' => 'lx', '㏔' => 'mb', '㏕' => 'mil', '㏖' => 'mol', '㏗' => 'PH', '㏘' => 'p.m.', '㏙' => 'PPM', '㏚' => 'PR', '㏛' => 'sr', '㏜' => 'Sv', '㏝' => 'Wb', '㏞' => 'V∕m', '㏟' => 'A∕m', '㏠' => '1日', '㏡' => '2日', '㏢' => '3日', '㏣' => '4日', '㏤' => '5日', '㏥' => '6日', '㏦' => '7日', '㏧' => '8日', '㏨' => '9日', '㏩' => '10日', '㏪' => '11日', '㏫' => '12日', '㏬' => '13日', '㏭' => '14日', '㏮' => '15日', '㏯' => '16日', '㏰' => '17日', '㏱' => '18日', '㏲' => '19日', '㏳' => '20日', '㏴' => '21日', '㏵' => '22日', '㏶' => '23日', '㏷' => '24日', '㏸' => '25日', '㏹' => '26日', '㏺' => '27日', '㏻' => '28日', '㏼' => '29日', '㏽' => '30日', '㏾' => '31日', '㏿' => 'gal', 'ꚜ' => 'ъ', 'ꚝ' => 'ь', 'ꝰ' => 'ꝯ', 'ꟸ' => 'Ħ', 'ꟹ' => 'œ', 'ꭜ' => 'ꜧ', 'ꭝ' => 'ꬷ', 'ꭞ' => 'ɫ', 'ꭟ' => 'ꭒ', 'ꭩ' => 'ʍ', 'ff' => 'ff', 'fi' => 'fi', 'fl' => 'fl', 'ffi' => 'ffi', 'ffl' => 'ffl', 'ſt' => 'st', 'st' => 'st', 'ﬓ' => 'մն', 'ﬔ' => 'մե', 'ﬕ' => 'մի', 'ﬖ' => 'վն', 'ﬗ' => 'մխ', 'ﬠ' => 'ע', 'ﬡ' => 'א', 'ﬢ' => 'ד', 'ﬣ' => 'ה', 'ﬤ' => 'כ', 'ﬥ' => 'ל', 'ﬦ' => 'ם', 'ﬧ' => 'ר', 'ﬨ' => 'ת', '﬩' => '+', 'ﭏ' => 'אל', 'ﭐ' => 'ٱ', 'ﭑ' => 'ٱ', 'ﭒ' => 'ٻ', 'ﭓ' => 'ٻ', 'ﭔ' => 'ٻ', 'ﭕ' => 'ٻ', 'ﭖ' => 'پ', 'ﭗ' => 'پ', 'ﭘ' => 'پ', 'ﭙ' => 'پ', 'ﭚ' => 'ڀ', 'ﭛ' => 'ڀ', 'ﭜ' => 'ڀ', 'ﭝ' => 'ڀ', 'ﭞ' => 'ٺ', 'ﭟ' => 'ٺ', 'ﭠ' => 'ٺ', 'ﭡ' => 'ٺ', 'ﭢ' => 'ٿ', 'ﭣ' => 'ٿ', 'ﭤ' => 'ٿ', 'ﭥ' => 'ٿ', 'ﭦ' => 'ٹ', 'ﭧ' => 'ٹ', 'ﭨ' => 'ٹ', 'ﭩ' => 'ٹ', 'ﭪ' => 'ڤ', 'ﭫ' => 'ڤ', 'ﭬ' => 'ڤ', 'ﭭ' => 'ڤ', 'ﭮ' => 'ڦ', 'ﭯ' => 'ڦ', 'ﭰ' => 'ڦ', 'ﭱ' => 'ڦ', 'ﭲ' => 'ڄ', 'ﭳ' => 'ڄ', 'ﭴ' => 'ڄ', 'ﭵ' => 'ڄ', 'ﭶ' => 'ڃ', 'ﭷ' => 'ڃ', 'ﭸ' => 'ڃ', 'ﭹ' => 'ڃ', 'ﭺ' => 'چ', 'ﭻ' => 'چ', 'ﭼ' => 'چ', 'ﭽ' => 'چ', 'ﭾ' => 'ڇ', 'ﭿ' => 'ڇ', 'ﮀ' => 'ڇ', 'ﮁ' => 'ڇ', 'ﮂ' => 'ڍ', 'ﮃ' => 'ڍ', 'ﮄ' => 'ڌ', 'ﮅ' => 'ڌ', 'ﮆ' => 'ڎ', 'ﮇ' => 'ڎ', 'ﮈ' => 'ڈ', 'ﮉ' => 'ڈ', 'ﮊ' => 'ژ', 'ﮋ' => 'ژ', 'ﮌ' => 'ڑ', 'ﮍ' => 'ڑ', 'ﮎ' => 'ک', 'ﮏ' => 'ک', 'ﮐ' => 'ک', 'ﮑ' => 'ک', 'ﮒ' => 'گ', 'ﮓ' => 'گ', 'ﮔ' => 'گ', 'ﮕ' => 'گ', 'ﮖ' => 'ڳ', 'ﮗ' => 'ڳ', 'ﮘ' => 'ڳ', 'ﮙ' => 'ڳ', 'ﮚ' => 'ڱ', 'ﮛ' => 'ڱ', 'ﮜ' => 'ڱ', 'ﮝ' => 'ڱ', 'ﮞ' => 'ں', 'ﮟ' => 'ں', 'ﮠ' => 'ڻ', 'ﮡ' => 'ڻ', 'ﮢ' => 'ڻ', 'ﮣ' => 'ڻ', 'ﮤ' => 'ۀ', 'ﮥ' => 'ۀ', 'ﮦ' => 'ہ', 'ﮧ' => 'ہ', 'ﮨ' => 'ہ', 'ﮩ' => 'ہ', 'ﮪ' => 'ھ', 'ﮫ' => 'ھ', 'ﮬ' => 'ھ', 'ﮭ' => 'ھ', 'ﮮ' => 'ے', 'ﮯ' => 'ے', 'ﮰ' => 'ۓ', 'ﮱ' => 'ۓ', 'ﯓ' => 'ڭ', 'ﯔ' => 'ڭ', 'ﯕ' => 'ڭ', 'ﯖ' => 'ڭ', 'ﯗ' => 'ۇ', 'ﯘ' => 'ۇ', 'ﯙ' => 'ۆ', 'ﯚ' => 'ۆ', 'ﯛ' => 'ۈ', 'ﯜ' => 'ۈ', 'ﯝ' => 'ۇٴ', 'ﯞ' => 'ۋ', 'ﯟ' => 'ۋ', 'ﯠ' => 'ۅ', 'ﯡ' => 'ۅ', 'ﯢ' => 'ۉ', 'ﯣ' => 'ۉ', 'ﯤ' => 'ې', 'ﯥ' => 'ې', 'ﯦ' => 'ې', 'ﯧ' => 'ې', 'ﯨ' => 'ى', 'ﯩ' => 'ى', 'ﯪ' => 'ئا', 'ﯫ' => 'ئا', 'ﯬ' => 'ئە', 'ﯭ' => 'ئە', 'ﯮ' => 'ئو', 'ﯯ' => 'ئو', 'ﯰ' => 'ئۇ', 'ﯱ' => 'ئۇ', 'ﯲ' => 'ئۆ', 'ﯳ' => 'ئۆ', 'ﯴ' => 'ئۈ', 'ﯵ' => 'ئۈ', 'ﯶ' => 'ئې', 'ﯷ' => 'ئې', 'ﯸ' => 'ئې', 'ﯹ' => 'ئى', 'ﯺ' => 'ئى', 'ﯻ' => 'ئى', 'ﯼ' => 'ی', 'ﯽ' => 'ی', 'ﯾ' => 'ی', 'ﯿ' => 'ی', 'ﰀ' => 'ئج', 'ﰁ' => 'ئح', 'ﰂ' => 'ئم', 'ﰃ' => 'ئى', 'ﰄ' => 'ئي', 'ﰅ' => 'بج', 'ﰆ' => 'بح', 'ﰇ' => 'بخ', 'ﰈ' => 'بم', 'ﰉ' => 'بى', 'ﰊ' => 'بي', 'ﰋ' => 'تج', 'ﰌ' => 'تح', 'ﰍ' => 'تخ', 'ﰎ' => 'تم', 'ﰏ' => 'تى', 'ﰐ' => 'تي', 'ﰑ' => 'ثج', 'ﰒ' => 'ثم', 'ﰓ' => 'ثى', 'ﰔ' => 'ثي', 'ﰕ' => 'جح', 'ﰖ' => 'جم', 'ﰗ' => 'حج', 'ﰘ' => 'حم', 'ﰙ' => 'خج', 'ﰚ' => 'خح', 'ﰛ' => 'خم', 'ﰜ' => 'سج', 'ﰝ' => 'سح', 'ﰞ' => 'سخ', 'ﰟ' => 'سم', 'ﰠ' => 'صح', 'ﰡ' => 'صم', 'ﰢ' => 'ضج', 'ﰣ' => 'ضح', 'ﰤ' => 'ضخ', 'ﰥ' => 'ضم', 'ﰦ' => 'طح', 'ﰧ' => 'طم', 'ﰨ' => 'ظم', 'ﰩ' => 'عج', 'ﰪ' => 'عم', 'ﰫ' => 'غج', 'ﰬ' => 'غم', 'ﰭ' => 'فج', 'ﰮ' => 'فح', 'ﰯ' => 'فخ', 'ﰰ' => 'فم', 'ﰱ' => 'فى', 'ﰲ' => 'في', 'ﰳ' => 'قح', 'ﰴ' => 'قم', 'ﰵ' => 'قى', 'ﰶ' => 'قي', 'ﰷ' => 'كا', 'ﰸ' => 'كج', 'ﰹ' => 'كح', 'ﰺ' => 'كخ', 'ﰻ' => 'كل', 'ﰼ' => 'كم', 'ﰽ' => 'كى', 'ﰾ' => 'كي', 'ﰿ' => 'لج', 'ﱀ' => 'لح', 'ﱁ' => 'لخ', 'ﱂ' => 'لم', 'ﱃ' => 'لى', 'ﱄ' => 'لي', 'ﱅ' => 'مج', 'ﱆ' => 'مح', 'ﱇ' => 'مخ', 'ﱈ' => 'مم', 'ﱉ' => 'مى', 'ﱊ' => 'مي', 'ﱋ' => 'نج', 'ﱌ' => 'نح', 'ﱍ' => 'نخ', 'ﱎ' => 'نم', 'ﱏ' => 'نى', 'ﱐ' => 'ني', 'ﱑ' => 'هج', 'ﱒ' => 'هم', 'ﱓ' => 'هى', 'ﱔ' => 'هي', 'ﱕ' => 'يج', 'ﱖ' => 'يح', 'ﱗ' => 'يخ', 'ﱘ' => 'يم', 'ﱙ' => 'يى', 'ﱚ' => 'يي', 'ﱛ' => 'ذٰ', 'ﱜ' => 'رٰ', 'ﱝ' => 'ىٰ', 'ﱞ' => ' ٌّ', 'ﱟ' => ' ٍّ', 'ﱠ' => ' َّ', 'ﱡ' => ' ُّ', 'ﱢ' => ' ِّ', 'ﱣ' => ' ّٰ', 'ﱤ' => 'ئر', 'ﱥ' => 'ئز', 'ﱦ' => 'ئم', 'ﱧ' => 'ئن', 'ﱨ' => 'ئى', 'ﱩ' => 'ئي', 'ﱪ' => 'بر', 'ﱫ' => 'بز', 'ﱬ' => 'بم', 'ﱭ' => 'بن', 'ﱮ' => 'بى', 'ﱯ' => 'بي', 'ﱰ' => 'تر', 'ﱱ' => 'تز', 'ﱲ' => 'تم', 'ﱳ' => 'تن', 'ﱴ' => 'تى', 'ﱵ' => 'تي', 'ﱶ' => 'ثر', 'ﱷ' => 'ثز', 'ﱸ' => 'ثم', 'ﱹ' => 'ثن', 'ﱺ' => 'ثى', 'ﱻ' => 'ثي', 'ﱼ' => 'فى', 'ﱽ' => 'في', 'ﱾ' => 'قى', 'ﱿ' => 'قي', 'ﲀ' => 'كا', 'ﲁ' => 'كل', 'ﲂ' => 'كم', 'ﲃ' => 'كى', 'ﲄ' => 'كي', 'ﲅ' => 'لم', 'ﲆ' => 'لى', 'ﲇ' => 'لي', 'ﲈ' => 'ما', 'ﲉ' => 'مم', 'ﲊ' => 'نر', 'ﲋ' => 'نز', 'ﲌ' => 'نم', 'ﲍ' => 'نن', 'ﲎ' => 'نى', 'ﲏ' => 'ني', 'ﲐ' => 'ىٰ', 'ﲑ' => 'ير', 'ﲒ' => 'يز', 'ﲓ' => 'يم', 'ﲔ' => 'ين', 'ﲕ' => 'يى', 'ﲖ' => 'يي', 'ﲗ' => 'ئج', 'ﲘ' => 'ئح', 'ﲙ' => 'ئخ', 'ﲚ' => 'ئم', 'ﲛ' => 'ئه', 'ﲜ' => 'بج', 'ﲝ' => 'بح', 'ﲞ' => 'بخ', 'ﲟ' => 'بم', 'ﲠ' => 'به', 'ﲡ' => 'تج', 'ﲢ' => 'تح', 'ﲣ' => 'تخ', 'ﲤ' => 'تم', 'ﲥ' => 'ته', 'ﲦ' => 'ثم', 'ﲧ' => 'جح', 'ﲨ' => 'جم', 'ﲩ' => 'حج', 'ﲪ' => 'حم', 'ﲫ' => 'خج', 'ﲬ' => 'خم', 'ﲭ' => 'سج', 'ﲮ' => 'سح', 'ﲯ' => 'سخ', 'ﲰ' => 'سم', 'ﲱ' => 'صح', 'ﲲ' => 'صخ', 'ﲳ' => 'صم', 'ﲴ' => 'ضج', 'ﲵ' => 'ضح', 'ﲶ' => 'ضخ', 'ﲷ' => 'ضم', 'ﲸ' => 'طح', 'ﲹ' => 'ظم', 'ﲺ' => 'عج', 'ﲻ' => 'عم', 'ﲼ' => 'غج', 'ﲽ' => 'غم', 'ﲾ' => 'فج', 'ﲿ' => 'فح', 'ﳀ' => 'فخ', 'ﳁ' => 'فم', 'ﳂ' => 'قح', 'ﳃ' => 'قم', 'ﳄ' => 'كج', 'ﳅ' => 'كح', 'ﳆ' => 'كخ', 'ﳇ' => 'كل', 'ﳈ' => 'كم', 'ﳉ' => 'لج', 'ﳊ' => 'لح', 'ﳋ' => 'لخ', 'ﳌ' => 'لم', 'ﳍ' => 'له', 'ﳎ' => 'مج', 'ﳏ' => 'مح', 'ﳐ' => 'مخ', 'ﳑ' => 'مم', 'ﳒ' => 'نج', 'ﳓ' => 'نح', 'ﳔ' => 'نخ', 'ﳕ' => 'نم', 'ﳖ' => 'نه', 'ﳗ' => 'هج', 'ﳘ' => 'هم', 'ﳙ' => 'هٰ', 'ﳚ' => 'يج', 'ﳛ' => 'يح', 'ﳜ' => 'يخ', 'ﳝ' => 'يم', 'ﳞ' => 'يه', 'ﳟ' => 'ئم', 'ﳠ' => 'ئه', 'ﳡ' => 'بم', 'ﳢ' => 'به', 'ﳣ' => 'تم', 'ﳤ' => 'ته', 'ﳥ' => 'ثم', 'ﳦ' => 'ثه', 'ﳧ' => 'سم', 'ﳨ' => 'سه', 'ﳩ' => 'شم', 'ﳪ' => 'شه', 'ﳫ' => 'كل', 'ﳬ' => 'كم', 'ﳭ' => 'لم', 'ﳮ' => 'نم', 'ﳯ' => 'نه', 'ﳰ' => 'يم', 'ﳱ' => 'يه', 'ﳲ' => 'ـَّ', 'ﳳ' => 'ـُّ', 'ﳴ' => 'ـِّ', 'ﳵ' => 'طى', 'ﳶ' => 'طي', 'ﳷ' => 'عى', 'ﳸ' => 'عي', 'ﳹ' => 'غى', 'ﳺ' => 'غي', 'ﳻ' => 'سى', 'ﳼ' => 'سي', 'ﳽ' => 'شى', 'ﳾ' => 'شي', 'ﳿ' => 'حى', 'ﴀ' => 'حي', 'ﴁ' => 'جى', 'ﴂ' => 'جي', 'ﴃ' => 'خى', 'ﴄ' => 'خي', 'ﴅ' => 'صى', 'ﴆ' => 'صي', 'ﴇ' => 'ضى', 'ﴈ' => 'ضي', 'ﴉ' => 'شج', 'ﴊ' => 'شح', 'ﴋ' => 'شخ', 'ﴌ' => 'شم', 'ﴍ' => 'شر', 'ﴎ' => 'سر', 'ﴏ' => 'صر', 'ﴐ' => 'ضر', 'ﴑ' => 'طى', 'ﴒ' => 'طي', 'ﴓ' => 'عى', 'ﴔ' => 'عي', 'ﴕ' => 'غى', 'ﴖ' => 'غي', 'ﴗ' => 'سى', 'ﴘ' => 'سي', 'ﴙ' => 'شى', 'ﴚ' => 'شي', 'ﴛ' => 'حى', 'ﴜ' => 'حي', 'ﴝ' => 'جى', 'ﴞ' => 'جي', 'ﴟ' => 'خى', 'ﴠ' => 'خي', 'ﴡ' => 'صى', 'ﴢ' => 'صي', 'ﴣ' => 'ضى', 'ﴤ' => 'ضي', 'ﴥ' => 'شج', 'ﴦ' => 'شح', 'ﴧ' => 'شخ', 'ﴨ' => 'شم', 'ﴩ' => 'شر', 'ﴪ' => 'سر', 'ﴫ' => 'صر', 'ﴬ' => 'ضر', 'ﴭ' => 'شج', 'ﴮ' => 'شح', 'ﴯ' => 'شخ', 'ﴰ' => 'شم', 'ﴱ' => 'سه', 'ﴲ' => 'شه', 'ﴳ' => 'طم', 'ﴴ' => 'سج', 'ﴵ' => 'سح', 'ﴶ' => 'سخ', 'ﴷ' => 'شج', 'ﴸ' => 'شح', 'ﴹ' => 'شخ', 'ﴺ' => 'طم', 'ﴻ' => 'ظم', 'ﴼ' => 'اً', 'ﴽ' => 'اً', 'ﵐ' => 'تجم', 'ﵑ' => 'تحج', 'ﵒ' => 'تحج', 'ﵓ' => 'تحم', 'ﵔ' => 'تخم', 'ﵕ' => 'تمج', 'ﵖ' => 'تمح', 'ﵗ' => 'تمخ', 'ﵘ' => 'جمح', 'ﵙ' => 'جمح', 'ﵚ' => 'حمي', 'ﵛ' => 'حمى', 'ﵜ' => 'سحج', 'ﵝ' => 'سجح', 'ﵞ' => 'سجى', 'ﵟ' => 'سمح', 'ﵠ' => 'سمح', 'ﵡ' => 'سمج', 'ﵢ' => 'سمم', 'ﵣ' => 'سمم', 'ﵤ' => 'صحح', 'ﵥ' => 'صحح', 'ﵦ' => 'صمم', 'ﵧ' => 'شحم', 'ﵨ' => 'شحم', 'ﵩ' => 'شجي', 'ﵪ' => 'شمخ', 'ﵫ' => 'شمخ', 'ﵬ' => 'شمم', 'ﵭ' => 'شمم', 'ﵮ' => 'ضحى', 'ﵯ' => 'ضخم', 'ﵰ' => 'ضخم', 'ﵱ' => 'طمح', 'ﵲ' => 'طمح', 'ﵳ' => 'طمم', 'ﵴ' => 'طمي', 'ﵵ' => 'عجم', 'ﵶ' => 'عمم', 'ﵷ' => 'عمم', 'ﵸ' => 'عمى', 'ﵹ' => 'غمم', 'ﵺ' => 'غمي', 'ﵻ' => 'غمى', 'ﵼ' => 'فخم', 'ﵽ' => 'فخم', 'ﵾ' => 'قمح', 'ﵿ' => 'قمم', 'ﶀ' => 'لحم', 'ﶁ' => 'لحي', 'ﶂ' => 'لحى', 'ﶃ' => 'لجج', 'ﶄ' => 'لجج', 'ﶅ' => 'لخم', 'ﶆ' => 'لخم', 'ﶇ' => 'لمح', 'ﶈ' => 'لمح', 'ﶉ' => 'محج', 'ﶊ' => 'محم', 'ﶋ' => 'محي', 'ﶌ' => 'مجح', 'ﶍ' => 'مجم', 'ﶎ' => 'مخج', 'ﶏ' => 'مخم', 'ﶒ' => 'مجخ', 'ﶓ' => 'همج', 'ﶔ' => 'همم', 'ﶕ' => 'نحم', 'ﶖ' => 'نحى', 'ﶗ' => 'نجم', 'ﶘ' => 'نجم', 'ﶙ' => 'نجى', 'ﶚ' => 'نمي', 'ﶛ' => 'نمى', 'ﶜ' => 'يمم', 'ﶝ' => 'يمم', 'ﶞ' => 'بخي', 'ﶟ' => 'تجي', 'ﶠ' => 'تجى', 'ﶡ' => 'تخي', 'ﶢ' => 'تخى', 'ﶣ' => 'تمي', 'ﶤ' => 'تمى', 'ﶥ' => 'جمي', 'ﶦ' => 'جحى', 'ﶧ' => 'جمى', 'ﶨ' => 'سخى', 'ﶩ' => 'صحي', 'ﶪ' => 'شحي', 'ﶫ' => 'ضحي', 'ﶬ' => 'لجي', 'ﶭ' => 'لمي', 'ﶮ' => 'يحي', 'ﶯ' => 'يجي', 'ﶰ' => 'يمي', 'ﶱ' => 'ممي', 'ﶲ' => 'قمي', 'ﶳ' => 'نحي', 'ﶴ' => 'قمح', 'ﶵ' => 'لحم', 'ﶶ' => 'عمي', 'ﶷ' => 'كمي', 'ﶸ' => 'نجح', 'ﶹ' => 'مخي', 'ﶺ' => 'لجم', 'ﶻ' => 'كمم', 'ﶼ' => 'لجم', 'ﶽ' => 'نجح', 'ﶾ' => 'جحي', 'ﶿ' => 'حجي', 'ﷀ' => 'مجي', 'ﷁ' => 'فمي', 'ﷂ' => 'بحي', 'ﷃ' => 'كمم', 'ﷄ' => 'عجم', 'ﷅ' => 'صمم', 'ﷆ' => 'سخي', 'ﷇ' => 'نجي', 'ﷰ' => 'صلے', 'ﷱ' => 'قلے', 'ﷲ' => 'الله', 'ﷳ' => 'اكبر', 'ﷴ' => 'محمد', 'ﷵ' => 'صلعم', 'ﷶ' => 'رسول', 'ﷷ' => 'عليه', 'ﷸ' => 'وسلم', 'ﷹ' => 'صلى', 'ﷺ' => 'صلى الله عليه وسلم', 'ﷻ' => 'جل جلاله', '﷼' => 'ریال', '︐' => ',', '︑' => '、', '︒' => '。', '︓' => ':', '︔' => ';', '︕' => '!', '︖' => '?', '︗' => '〖', '︘' => '〗', '︙' => '...', '︰' => '..', '︱' => '—', '︲' => '–', '︳' => '_', '︴' => '_', '︵' => '(', '︶' => ')', '︷' => '{', '︸' => '}', '︹' => '〔', '︺' => '〕', '︻' => '【', '︼' => '】', '︽' => '《', '︾' => '》', '︿' => '〈', '﹀' => '〉', '﹁' => '「', '﹂' => '」', '﹃' => '『', '﹄' => '』', '﹇' => '[', '﹈' => ']', '﹉' => ' ̅', '﹊' => ' ̅', '﹋' => ' ̅', '﹌' => ' ̅', '﹍' => '_', '﹎' => '_', '﹏' => '_', '﹐' => ',', '﹑' => '、', '﹒' => '.', '﹔' => ';', '﹕' => ':', '﹖' => '?', '﹗' => '!', '﹘' => '—', '﹙' => '(', '﹚' => ')', '﹛' => '{', '﹜' => '}', '﹝' => '〔', '﹞' => '〕', '﹟' => '#', '﹠' => '&', '﹡' => '*', '﹢' => '+', '﹣' => '-', '﹤' => '<', '﹥' => '>', '﹦' => '=', '﹨' => '\\', '﹩' => '$', '﹪' => '%', '﹫' => '@', 'ﹰ' => ' ً', 'ﹱ' => 'ـً', 'ﹲ' => ' ٌ', 'ﹴ' => ' ٍ', 'ﹶ' => ' َ', 'ﹷ' => 'ـَ', 'ﹸ' => ' ُ', 'ﹹ' => 'ـُ', 'ﹺ' => ' ِ', 'ﹻ' => 'ـِ', 'ﹼ' => ' ّ', 'ﹽ' => 'ـّ', 'ﹾ' => ' ْ', 'ﹿ' => 'ـْ', 'ﺀ' => 'ء', 'ﺁ' => 'آ', 'ﺂ' => 'آ', 'ﺃ' => 'أ', 'ﺄ' => 'أ', 'ﺅ' => 'ؤ', 'ﺆ' => 'ؤ', 'ﺇ' => 'إ', 'ﺈ' => 'إ', 'ﺉ' => 'ئ', 'ﺊ' => 'ئ', 'ﺋ' => 'ئ', 'ﺌ' => 'ئ', 'ﺍ' => 'ا', 'ﺎ' => 'ا', 'ﺏ' => 'ب', 'ﺐ' => 'ب', 'ﺑ' => 'ب', 'ﺒ' => 'ب', 'ﺓ' => 'ة', 'ﺔ' => 'ة', 'ﺕ' => 'ت', 'ﺖ' => 'ت', 'ﺗ' => 'ت', 'ﺘ' => 'ت', 'ﺙ' => 'ث', 'ﺚ' => 'ث', 'ﺛ' => 'ث', 'ﺜ' => 'ث', 'ﺝ' => 'ج', 'ﺞ' => 'ج', 'ﺟ' => 'ج', 'ﺠ' => 'ج', 'ﺡ' => 'ح', 'ﺢ' => 'ح', 'ﺣ' => 'ح', 'ﺤ' => 'ح', 'ﺥ' => 'خ', 'ﺦ' => 'خ', 'ﺧ' => 'خ', 'ﺨ' => 'خ', 'ﺩ' => 'د', 'ﺪ' => 'د', 'ﺫ' => 'ذ', 'ﺬ' => 'ذ', 'ﺭ' => 'ر', 'ﺮ' => 'ر', 'ﺯ' => 'ز', 'ﺰ' => 'ز', 'ﺱ' => 'س', 'ﺲ' => 'س', 'ﺳ' => 'س', 'ﺴ' => 'س', 'ﺵ' => 'ش', 'ﺶ' => 'ش', 'ﺷ' => 'ش', 'ﺸ' => 'ش', 'ﺹ' => 'ص', 'ﺺ' => 'ص', 'ﺻ' => 'ص', 'ﺼ' => 'ص', 'ﺽ' => 'ض', 'ﺾ' => 'ض', 'ﺿ' => 'ض', 'ﻀ' => 'ض', 'ﻁ' => 'ط', 'ﻂ' => 'ط', 'ﻃ' => 'ط', 'ﻄ' => 'ط', 'ﻅ' => 'ظ', 'ﻆ' => 'ظ', 'ﻇ' => 'ظ', 'ﻈ' => 'ظ', 'ﻉ' => 'ع', 'ﻊ' => 'ع', 'ﻋ' => 'ع', 'ﻌ' => 'ع', 'ﻍ' => 'غ', 'ﻎ' => 'غ', 'ﻏ' => 'غ', 'ﻐ' => 'غ', 'ﻑ' => 'ف', 'ﻒ' => 'ف', 'ﻓ' => 'ف', 'ﻔ' => 'ف', 'ﻕ' => 'ق', 'ﻖ' => 'ق', 'ﻗ' => 'ق', 'ﻘ' => 'ق', 'ﻙ' => 'ك', 'ﻚ' => 'ك', 'ﻛ' => 'ك', 'ﻜ' => 'ك', 'ﻝ' => 'ل', 'ﻞ' => 'ل', 'ﻟ' => 'ل', 'ﻠ' => 'ل', 'ﻡ' => 'م', 'ﻢ' => 'م', 'ﻣ' => 'م', 'ﻤ' => 'م', 'ﻥ' => 'ن', 'ﻦ' => 'ن', 'ﻧ' => 'ن', 'ﻨ' => 'ن', 'ﻩ' => 'ه', 'ﻪ' => 'ه', 'ﻫ' => 'ه', 'ﻬ' => 'ه', 'ﻭ' => 'و', 'ﻮ' => 'و', 'ﻯ' => 'ى', 'ﻰ' => 'ى', 'ﻱ' => 'ي', 'ﻲ' => 'ي', 'ﻳ' => 'ي', 'ﻴ' => 'ي', 'ﻵ' => 'لآ', 'ﻶ' => 'لآ', 'ﻷ' => 'لأ', 'ﻸ' => 'لأ', 'ﻹ' => 'لإ', 'ﻺ' => 'لإ', 'ﻻ' => 'لا', 'ﻼ' => 'لا', '!' => '!', '"' => '"', '#' => '#', '$' => '$', '%' => '%', '&' => '&', ''' => '\'', '(' => '(', ')' => ')', '*' => '*', '+' => '+', ',' => ',', '-' => '-', '.' => '.', '/' => '/', '0' => '0', '1' => '1', '2' => '2', '3' => '3', '4' => '4', '5' => '5', '6' => '6', '7' => '7', '8' => '8', '9' => '9', ':' => ':', ';' => ';', '<' => '<', '=' => '=', '>' => '>', '?' => '?', '@' => '@', 'A' => 'A', 'B' => 'B', 'C' => 'C', 'D' => 'D', 'E' => 'E', 'F' => 'F', 'G' => 'G', 'H' => 'H', 'I' => 'I', 'J' => 'J', 'K' => 'K', 'L' => 'L', 'M' => 'M', 'N' => 'N', 'O' => 'O', 'P' => 'P', 'Q' => 'Q', 'R' => 'R', 'S' => 'S', 'T' => 'T', 'U' => 'U', 'V' => 'V', 'W' => 'W', 'X' => 'X', 'Y' => 'Y', 'Z' => 'Z', '[' => '[', '\' => '\\', ']' => ']', '^' => '^', '_' => '_', '`' => '`', 'a' => 'a', 'b' => 'b', 'c' => 'c', 'd' => 'd', 'e' => 'e', 'f' => 'f', 'g' => 'g', 'h' => 'h', 'i' => 'i', 'j' => 'j', 'k' => 'k', 'l' => 'l', 'm' => 'm', 'n' => 'n', 'o' => 'o', 'p' => 'p', 'q' => 'q', 'r' => 'r', 's' => 's', 't' => 't', 'u' => 'u', 'v' => 'v', 'w' => 'w', 'x' => 'x', 'y' => 'y', 'z' => 'z', '{' => '{', '|' => '|', '}' => '}', '~' => '~', '⦅' => '⦅', '⦆' => '⦆', '。' => '。', '「' => '「', '」' => '」', '、' => '、', '・' => '・', 'ヲ' => 'ヲ', 'ァ' => 'ァ', 'ィ' => 'ィ', 'ゥ' => 'ゥ', 'ェ' => 'ェ', 'ォ' => 'ォ', 'ャ' => 'ャ', 'ュ' => 'ュ', 'ョ' => 'ョ', 'ッ' => 'ッ', 'ー' => 'ー', 'ア' => 'ア', 'イ' => 'イ', 'ウ' => 'ウ', 'エ' => 'エ', 'オ' => 'オ', 'カ' => 'カ', 'キ' => 'キ', 'ク' => 'ク', 'ケ' => 'ケ', 'コ' => 'コ', 'サ' => 'サ', 'シ' => 'シ', 'ス' => 'ス', 'セ' => 'セ', 'ソ' => 'ソ', 'タ' => 'タ', 'チ' => 'チ', 'ツ' => 'ツ', 'テ' => 'テ', 'ト' => 'ト', 'ナ' => 'ナ', 'ニ' => 'ニ', 'ヌ' => 'ヌ', 'ネ' => 'ネ', 'ノ' => 'ノ', 'ハ' => 'ハ', 'ヒ' => 'ヒ', 'フ' => 'フ', 'ヘ' => 'ヘ', 'ホ' => 'ホ', 'マ' => 'マ', 'ミ' => 'ミ', 'ム' => 'ム', 'メ' => 'メ', 'モ' => 'モ', 'ヤ' => 'ヤ', 'ユ' => 'ユ', 'ヨ' => 'ヨ', 'ラ' => 'ラ', 'リ' => 'リ', 'ル' => 'ル', 'レ' => 'レ', 'ロ' => 'ロ', 'ワ' => 'ワ', 'ン' => 'ン', '゙' => '゙', '゚' => '゚', 'ᅠ' => 'ᅠ', 'ᄀ' => 'ᄀ', 'ᄁ' => 'ᄁ', 'ᆪ' => 'ᆪ', 'ᄂ' => 'ᄂ', 'ᆬ' => 'ᆬ', 'ᆭ' => 'ᆭ', 'ᄃ' => 'ᄃ', 'ᄄ' => 'ᄄ', 'ᄅ' => 'ᄅ', 'ᆰ' => 'ᆰ', 'ᆱ' => 'ᆱ', 'ᆲ' => 'ᆲ', 'ᆳ' => 'ᆳ', 'ᆴ' => 'ᆴ', 'ᆵ' => 'ᆵ', 'ᄚ' => 'ᄚ', 'ᄆ' => 'ᄆ', 'ᄇ' => 'ᄇ', 'ᄈ' => 'ᄈ', 'ᄡ' => 'ᄡ', 'ᄉ' => 'ᄉ', 'ᄊ' => 'ᄊ', 'ᄋ' => 'ᄋ', 'ᄌ' => 'ᄌ', 'ᄍ' => 'ᄍ', 'ᄎ' => 'ᄎ', 'ᄏ' => 'ᄏ', 'ᄐ' => 'ᄐ', 'ᄑ' => 'ᄑ', 'ᄒ' => 'ᄒ', 'ᅡ' => 'ᅡ', 'ᅢ' => 'ᅢ', 'ᅣ' => 'ᅣ', 'ᅤ' => 'ᅤ', 'ᅥ' => 'ᅥ', 'ᅦ' => 'ᅦ', 'ᅧ' => 'ᅧ', 'ᅨ' => 'ᅨ', 'ᅩ' => 'ᅩ', 'ᅪ' => 'ᅪ', 'ᅫ' => 'ᅫ', 'ᅬ' => 'ᅬ', 'ᅭ' => 'ᅭ', 'ᅮ' => 'ᅮ', 'ᅯ' => 'ᅯ', 'ᅰ' => 'ᅰ', 'ᅱ' => 'ᅱ', 'ᅲ' => 'ᅲ', 'ᅳ' => 'ᅳ', 'ᅴ' => 'ᅴ', 'ᅵ' => 'ᅵ', '¢' => '¢', '£' => '£', '¬' => '¬', ' ̄' => ' ̄', '¦' => '¦', '¥' => '¥', '₩' => '₩', '│' => '│', '←' => '←', '↑' => '↑', '→' => '→', '↓' => '↓', '■' => '■', '○' => '○', '𝐀' => 'A', '𝐁' => 'B', '𝐂' => 'C', '𝐃' => 'D', '𝐄' => 'E', '𝐅' => 'F', '𝐆' => 'G', '𝐇' => 'H', '𝐈' => 'I', '𝐉' => 'J', '𝐊' => 'K', '𝐋' => 'L', '𝐌' => 'M', '𝐍' => 'N', '𝐎' => 'O', '𝐏' => 'P', '𝐐' => 'Q', '𝐑' => 'R', '𝐒' => 'S', '𝐓' => 'T', '𝐔' => 'U', '𝐕' => 'V', '𝐖' => 'W', '𝐗' => 'X', '𝐘' => 'Y', '𝐙' => 'Z', '𝐚' => 'a', '𝐛' => 'b', '𝐜' => 'c', '𝐝' => 'd', '𝐞' => 'e', '𝐟' => 'f', '𝐠' => 'g', '𝐡' => 'h', '𝐢' => 'i', '𝐣' => 'j', '𝐤' => 'k', '𝐥' => 'l', '𝐦' => 'm', '𝐧' => 'n', '𝐨' => 'o', '𝐩' => 'p', '𝐪' => 'q', '𝐫' => 'r', '𝐬' => 's', '𝐭' => 't', '𝐮' => 'u', '𝐯' => 'v', '𝐰' => 'w', '𝐱' => 'x', '𝐲' => 'y', '𝐳' => 'z', '𝐴' => 'A', '𝐵' => 'B', '𝐶' => 'C', '𝐷' => 'D', '𝐸' => 'E', '𝐹' => 'F', '𝐺' => 'G', '𝐻' => 'H', '𝐼' => 'I', '𝐽' => 'J', '𝐾' => 'K', '𝐿' => 'L', '𝑀' => 'M', '𝑁' => 'N', '𝑂' => 'O', '𝑃' => 'P', '𝑄' => 'Q', '𝑅' => 'R', '𝑆' => 'S', '𝑇' => 'T', '𝑈' => 'U', '𝑉' => 'V', '𝑊' => 'W', '𝑋' => 'X', '𝑌' => 'Y', '𝑍' => 'Z', '𝑎' => 'a', '𝑏' => 'b', '𝑐' => 'c', '𝑑' => 'd', '𝑒' => 'e', '𝑓' => 'f', '𝑔' => 'g', '𝑖' => 'i', '𝑗' => 'j', '𝑘' => 'k', '𝑙' => 'l', '𝑚' => 'm', '𝑛' => 'n', '𝑜' => 'o', '𝑝' => 'p', '𝑞' => 'q', '𝑟' => 'r', '𝑠' => 's', '𝑡' => 't', '𝑢' => 'u', '𝑣' => 'v', '𝑤' => 'w', '𝑥' => 'x', '𝑦' => 'y', '𝑧' => 'z', '𝑨' => 'A', '𝑩' => 'B', '𝑪' => 'C', '𝑫' => 'D', '𝑬' => 'E', '𝑭' => 'F', '𝑮' => 'G', '𝑯' => 'H', '𝑰' => 'I', '𝑱' => 'J', '𝑲' => 'K', '𝑳' => 'L', '𝑴' => 'M', '𝑵' => 'N', '𝑶' => 'O', '𝑷' => 'P', '𝑸' => 'Q', '𝑹' => 'R', '𝑺' => 'S', '𝑻' => 'T', '𝑼' => 'U', '𝑽' => 'V', '𝑾' => 'W', '𝑿' => 'X', '𝒀' => 'Y', '𝒁' => 'Z', '𝒂' => 'a', '𝒃' => 'b', '𝒄' => 'c', '𝒅' => 'd', '𝒆' => 'e', '𝒇' => 'f', '𝒈' => 'g', '𝒉' => 'h', '𝒊' => 'i', '𝒋' => 'j', '𝒌' => 'k', '𝒍' => 'l', '𝒎' => 'm', '𝒏' => 'n', '𝒐' => 'o', '𝒑' => 'p', '𝒒' => 'q', '𝒓' => 'r', '𝒔' => 's', '𝒕' => 't', '𝒖' => 'u', '𝒗' => 'v', '𝒘' => 'w', '𝒙' => 'x', '𝒚' => 'y', '𝒛' => 'z', '𝒜' => 'A', '𝒞' => 'C', '𝒟' => 'D', '𝒢' => 'G', '𝒥' => 'J', '𝒦' => 'K', '𝒩' => 'N', '𝒪' => 'O', '𝒫' => 'P', '𝒬' => 'Q', '𝒮' => 'S', '𝒯' => 'T', '𝒰' => 'U', '𝒱' => 'V', '𝒲' => 'W', '𝒳' => 'X', '𝒴' => 'Y', '𝒵' => 'Z', '𝒶' => 'a', '𝒷' => 'b', '𝒸' => 'c', '𝒹' => 'd', '𝒻' => 'f', '𝒽' => 'h', '𝒾' => 'i', '𝒿' => 'j', '𝓀' => 'k', '𝓁' => 'l', '𝓂' => 'm', '𝓃' => 'n', '𝓅' => 'p', '𝓆' => 'q', '𝓇' => 'r', '𝓈' => 's', '𝓉' => 't', '𝓊' => 'u', '𝓋' => 'v', '𝓌' => 'w', '𝓍' => 'x', '𝓎' => 'y', '𝓏' => 'z', '𝓐' => 'A', '𝓑' => 'B', '𝓒' => 'C', '𝓓' => 'D', '𝓔' => 'E', '𝓕' => 'F', '𝓖' => 'G', '𝓗' => 'H', '𝓘' => 'I', '𝓙' => 'J', '𝓚' => 'K', '𝓛' => 'L', '𝓜' => 'M', '𝓝' => 'N', '𝓞' => 'O', '𝓟' => 'P', '𝓠' => 'Q', '𝓡' => 'R', '𝓢' => 'S', '𝓣' => 'T', '𝓤' => 'U', '𝓥' => 'V', '𝓦' => 'W', '𝓧' => 'X', '𝓨' => 'Y', '𝓩' => 'Z', '𝓪' => 'a', '𝓫' => 'b', '𝓬' => 'c', '𝓭' => 'd', '𝓮' => 'e', '𝓯' => 'f', '𝓰' => 'g', '𝓱' => 'h', '𝓲' => 'i', '𝓳' => 'j', '𝓴' => 'k', '𝓵' => 'l', '𝓶' => 'm', '𝓷' => 'n', '𝓸' => 'o', '𝓹' => 'p', '𝓺' => 'q', '𝓻' => 'r', '𝓼' => 's', '𝓽' => 't', '𝓾' => 'u', '𝓿' => 'v', '𝔀' => 'w', '𝔁' => 'x', '𝔂' => 'y', '𝔃' => 'z', '𝔄' => 'A', '𝔅' => 'B', '𝔇' => 'D', '𝔈' => 'E', '𝔉' => 'F', '𝔊' => 'G', '𝔍' => 'J', '𝔎' => 'K', '𝔏' => 'L', '𝔐' => 'M', '𝔑' => 'N', '𝔒' => 'O', '𝔓' => 'P', '𝔔' => 'Q', '𝔖' => 'S', '𝔗' => 'T', '𝔘' => 'U', '𝔙' => 'V', '𝔚' => 'W', '𝔛' => 'X', '𝔜' => 'Y', '𝔞' => 'a', '𝔟' => 'b', '𝔠' => 'c', '𝔡' => 'd', '𝔢' => 'e', '𝔣' => 'f', '𝔤' => 'g', '𝔥' => 'h', '𝔦' => 'i', '𝔧' => 'j', '𝔨' => 'k', '𝔩' => 'l', '𝔪' => 'm', '𝔫' => 'n', '𝔬' => 'o', '𝔭' => 'p', '𝔮' => 'q', '𝔯' => 'r', '𝔰' => 's', '𝔱' => 't', '𝔲' => 'u', '𝔳' => 'v', '𝔴' => 'w', '𝔵' => 'x', '𝔶' => 'y', '𝔷' => 'z', '𝔸' => 'A', '𝔹' => 'B', '𝔻' => 'D', '𝔼' => 'E', '𝔽' => 'F', '𝔾' => 'G', '𝕀' => 'I', '𝕁' => 'J', '𝕂' => 'K', '𝕃' => 'L', '𝕄' => 'M', '𝕆' => 'O', '𝕊' => 'S', '𝕋' => 'T', '𝕌' => 'U', '𝕍' => 'V', '𝕎' => 'W', '𝕏' => 'X', '𝕐' => 'Y', '𝕒' => 'a', '𝕓' => 'b', '𝕔' => 'c', '𝕕' => 'd', '𝕖' => 'e', '𝕗' => 'f', '𝕘' => 'g', '𝕙' => 'h', '𝕚' => 'i', '𝕛' => 'j', '𝕜' => 'k', '𝕝' => 'l', '𝕞' => 'm', '𝕟' => 'n', '𝕠' => 'o', '𝕡' => 'p', '𝕢' => 'q', '𝕣' => 'r', '𝕤' => 's', '𝕥' => 't', '𝕦' => 'u', '𝕧' => 'v', '𝕨' => 'w', '𝕩' => 'x', '𝕪' => 'y', '𝕫' => 'z', '𝕬' => 'A', '𝕭' => 'B', '𝕮' => 'C', '𝕯' => 'D', '𝕰' => 'E', '𝕱' => 'F', '𝕲' => 'G', '𝕳' => 'H', '𝕴' => 'I', '𝕵' => 'J', '𝕶' => 'K', '𝕷' => 'L', '𝕸' => 'M', '𝕹' => 'N', '𝕺' => 'O', '𝕻' => 'P', '𝕼' => 'Q', '𝕽' => 'R', '𝕾' => 'S', '𝕿' => 'T', '𝖀' => 'U', '𝖁' => 'V', '𝖂' => 'W', '𝖃' => 'X', '𝖄' => 'Y', '𝖅' => 'Z', '𝖆' => 'a', '𝖇' => 'b', '𝖈' => 'c', '𝖉' => 'd', '𝖊' => 'e', '𝖋' => 'f', '𝖌' => 'g', '𝖍' => 'h', '𝖎' => 'i', '𝖏' => 'j', '𝖐' => 'k', '𝖑' => 'l', '𝖒' => 'm', '𝖓' => 'n', '𝖔' => 'o', '𝖕' => 'p', '𝖖' => 'q', '𝖗' => 'r', '𝖘' => 's', '𝖙' => 't', '𝖚' => 'u', '𝖛' => 'v', '𝖜' => 'w', '𝖝' => 'x', '𝖞' => 'y', '𝖟' => 'z', '𝖠' => 'A', '𝖡' => 'B', '𝖢' => 'C', '𝖣' => 'D', '𝖤' => 'E', '𝖥' => 'F', '𝖦' => 'G', '𝖧' => 'H', '𝖨' => 'I', '𝖩' => 'J', '𝖪' => 'K', '𝖫' => 'L', '𝖬' => 'M', '𝖭' => 'N', '𝖮' => 'O', '𝖯' => 'P', '𝖰' => 'Q', '𝖱' => 'R', '𝖲' => 'S', '𝖳' => 'T', '𝖴' => 'U', '𝖵' => 'V', '𝖶' => 'W', '𝖷' => 'X', '𝖸' => 'Y', '𝖹' => 'Z', '𝖺' => 'a', '𝖻' => 'b', '𝖼' => 'c', '𝖽' => 'd', '𝖾' => 'e', '𝖿' => 'f', '𝗀' => 'g', '𝗁' => 'h', '𝗂' => 'i', '𝗃' => 'j', '𝗄' => 'k', '𝗅' => 'l', '𝗆' => 'm', '𝗇' => 'n', '𝗈' => 'o', '𝗉' => 'p', '𝗊' => 'q', '𝗋' => 'r', '𝗌' => 's', '𝗍' => 't', '𝗎' => 'u', '𝗏' => 'v', '𝗐' => 'w', '𝗑' => 'x', '𝗒' => 'y', '𝗓' => 'z', '𝗔' => 'A', '𝗕' => 'B', '𝗖' => 'C', '𝗗' => 'D', '𝗘' => 'E', '𝗙' => 'F', '𝗚' => 'G', '𝗛' => 'H', '𝗜' => 'I', '𝗝' => 'J', '𝗞' => 'K', '𝗟' => 'L', '𝗠' => 'M', '𝗡' => 'N', '𝗢' => 'O', '𝗣' => 'P', '𝗤' => 'Q', '𝗥' => 'R', '𝗦' => 'S', '𝗧' => 'T', '𝗨' => 'U', '𝗩' => 'V', '𝗪' => 'W', '𝗫' => 'X', '𝗬' => 'Y', '𝗭' => 'Z', '𝗮' => 'a', '𝗯' => 'b', '𝗰' => 'c', '𝗱' => 'd', '𝗲' => 'e', '𝗳' => 'f', '𝗴' => 'g', '𝗵' => 'h', '𝗶' => 'i', '𝗷' => 'j', '𝗸' => 'k', '𝗹' => 'l', '𝗺' => 'm', '𝗻' => 'n', '𝗼' => 'o', '𝗽' => 'p', '𝗾' => 'q', '𝗿' => 'r', '𝘀' => 's', '𝘁' => 't', '𝘂' => 'u', '𝘃' => 'v', '𝘄' => 'w', '𝘅' => 'x', '𝘆' => 'y', '𝘇' => 'z', '𝘈' => 'A', '𝘉' => 'B', '𝘊' => 'C', '𝘋' => 'D', '𝘌' => 'E', '𝘍' => 'F', '𝘎' => 'G', '𝘏' => 'H', '𝘐' => 'I', '𝘑' => 'J', '𝘒' => 'K', '𝘓' => 'L', '𝘔' => 'M', '𝘕' => 'N', '𝘖' => 'O', '𝘗' => 'P', '𝘘' => 'Q', '𝘙' => 'R', '𝘚' => 'S', '𝘛' => 'T', '𝘜' => 'U', '𝘝' => 'V', '𝘞' => 'W', '𝘟' => 'X', '𝘠' => 'Y', '𝘡' => 'Z', '𝘢' => 'a', '𝘣' => 'b', '𝘤' => 'c', '𝘥' => 'd', '𝘦' => 'e', '𝘧' => 'f', '𝘨' => 'g', '𝘩' => 'h', '𝘪' => 'i', '𝘫' => 'j', '𝘬' => 'k', '𝘭' => 'l', '𝘮' => 'm', '𝘯' => 'n', '𝘰' => 'o', '𝘱' => 'p', '𝘲' => 'q', '𝘳' => 'r', '𝘴' => 's', '𝘵' => 't', '𝘶' => 'u', '𝘷' => 'v', '𝘸' => 'w', '𝘹' => 'x', '𝘺' => 'y', '𝘻' => 'z', '𝘼' => 'A', '𝘽' => 'B', '𝘾' => 'C', '𝘿' => 'D', '𝙀' => 'E', '𝙁' => 'F', '𝙂' => 'G', '𝙃' => 'H', '𝙄' => 'I', '𝙅' => 'J', '𝙆' => 'K', '𝙇' => 'L', '𝙈' => 'M', '𝙉' => 'N', '𝙊' => 'O', '𝙋' => 'P', '𝙌' => 'Q', '𝙍' => 'R', '𝙎' => 'S', '𝙏' => 'T', '𝙐' => 'U', '𝙑' => 'V', '𝙒' => 'W', '𝙓' => 'X', '𝙔' => 'Y', '𝙕' => 'Z', '𝙖' => 'a', '𝙗' => 'b', '𝙘' => 'c', '𝙙' => 'd', '𝙚' => 'e', '𝙛' => 'f', '𝙜' => 'g', '𝙝' => 'h', '𝙞' => 'i', '𝙟' => 'j', '𝙠' => 'k', '𝙡' => 'l', '𝙢' => 'm', '𝙣' => 'n', '𝙤' => 'o', '𝙥' => 'p', '𝙦' => 'q', '𝙧' => 'r', '𝙨' => 's', '𝙩' => 't', '𝙪' => 'u', '𝙫' => 'v', '𝙬' => 'w', '𝙭' => 'x', '𝙮' => 'y', '𝙯' => 'z', '𝙰' => 'A', '𝙱' => 'B', '𝙲' => 'C', '𝙳' => 'D', '𝙴' => 'E', '𝙵' => 'F', '𝙶' => 'G', '𝙷' => 'H', '𝙸' => 'I', '𝙹' => 'J', '𝙺' => 'K', '𝙻' => 'L', '𝙼' => 'M', '𝙽' => 'N', '𝙾' => 'O', '𝙿' => 'P', '𝚀' => 'Q', '𝚁' => 'R', '𝚂' => 'S', '𝚃' => 'T', '𝚄' => 'U', '𝚅' => 'V', '𝚆' => 'W', '𝚇' => 'X', '𝚈' => 'Y', '𝚉' => 'Z', '𝚊' => 'a', '𝚋' => 'b', '𝚌' => 'c', '𝚍' => 'd', '𝚎' => 'e', '𝚏' => 'f', '𝚐' => 'g', '𝚑' => 'h', '𝚒' => 'i', '𝚓' => 'j', '𝚔' => 'k', '𝚕' => 'l', '𝚖' => 'm', '𝚗' => 'n', '𝚘' => 'o', '𝚙' => 'p', '𝚚' => 'q', '𝚛' => 'r', '𝚜' => 's', '𝚝' => 't', '𝚞' => 'u', '𝚟' => 'v', '𝚠' => 'w', '𝚡' => 'x', '𝚢' => 'y', '𝚣' => 'z', '𝚤' => 'ı', '𝚥' => 'ȷ', '𝚨' => 'Α', '𝚩' => 'Β', '𝚪' => 'Γ', '𝚫' => 'Δ', '𝚬' => 'Ε', '𝚭' => 'Ζ', '𝚮' => 'Η', '𝚯' => 'Θ', '𝚰' => 'Ι', '𝚱' => 'Κ', '𝚲' => 'Λ', '𝚳' => 'Μ', '𝚴' => 'Ν', '𝚵' => 'Ξ', '𝚶' => 'Ο', '𝚷' => 'Π', '𝚸' => 'Ρ', '𝚹' => 'Θ', '𝚺' => 'Σ', '𝚻' => 'Τ', '𝚼' => 'Υ', '𝚽' => 'Φ', '𝚾' => 'Χ', '𝚿' => 'Ψ', '𝛀' => 'Ω', '𝛁' => '∇', '𝛂' => 'α', '𝛃' => 'β', '𝛄' => 'γ', '𝛅' => 'δ', '𝛆' => 'ε', '𝛇' => 'ζ', '𝛈' => 'η', '𝛉' => 'θ', '𝛊' => 'ι', '𝛋' => 'κ', '𝛌' => 'λ', '𝛍' => 'μ', '𝛎' => 'ν', '𝛏' => 'ξ', '𝛐' => 'ο', '𝛑' => 'π', '𝛒' => 'ρ', '𝛓' => 'ς', '𝛔' => 'σ', '𝛕' => 'τ', '𝛖' => 'υ', '𝛗' => 'φ', '𝛘' => 'χ', '𝛙' => 'ψ', '𝛚' => 'ω', '𝛛' => '∂', '𝛜' => 'ε', '𝛝' => 'θ', '𝛞' => 'κ', '𝛟' => 'φ', '𝛠' => 'ρ', '𝛡' => 'π', '𝛢' => 'Α', '𝛣' => 'Β', '𝛤' => 'Γ', '𝛥' => 'Δ', '𝛦' => 'Ε', '𝛧' => 'Ζ', '𝛨' => 'Η', '𝛩' => 'Θ', '𝛪' => 'Ι', '𝛫' => 'Κ', '𝛬' => 'Λ', '𝛭' => 'Μ', '𝛮' => 'Ν', '𝛯' => 'Ξ', '𝛰' => 'Ο', '𝛱' => 'Π', '𝛲' => 'Ρ', '𝛳' => 'Θ', '𝛴' => 'Σ', '𝛵' => 'Τ', '𝛶' => 'Υ', '𝛷' => 'Φ', '𝛸' => 'Χ', '𝛹' => 'Ψ', '𝛺' => 'Ω', '𝛻' => '∇', '𝛼' => 'α', '𝛽' => 'β', '𝛾' => 'γ', '𝛿' => 'δ', '𝜀' => 'ε', '𝜁' => 'ζ', '𝜂' => 'η', '𝜃' => 'θ', '𝜄' => 'ι', '𝜅' => 'κ', '𝜆' => 'λ', '𝜇' => 'μ', '𝜈' => 'ν', '𝜉' => 'ξ', '𝜊' => 'ο', '𝜋' => 'π', '𝜌' => 'ρ', '𝜍' => 'ς', '𝜎' => 'σ', '𝜏' => 'τ', '𝜐' => 'υ', '𝜑' => 'φ', '𝜒' => 'χ', '𝜓' => 'ψ', '𝜔' => 'ω', '𝜕' => '∂', '𝜖' => 'ε', '𝜗' => 'θ', '𝜘' => 'κ', '𝜙' => 'φ', '𝜚' => 'ρ', '𝜛' => 'π', '𝜜' => 'Α', '𝜝' => 'Β', '𝜞' => 'Γ', '𝜟' => 'Δ', '𝜠' => 'Ε', '𝜡' => 'Ζ', '𝜢' => 'Η', '𝜣' => 'Θ', '𝜤' => 'Ι', '𝜥' => 'Κ', '𝜦' => 'Λ', '𝜧' => 'Μ', '𝜨' => 'Ν', '𝜩' => 'Ξ', '𝜪' => 'Ο', '𝜫' => 'Π', '𝜬' => 'Ρ', '𝜭' => 'Θ', '𝜮' => 'Σ', '𝜯' => 'Τ', '𝜰' => 'Υ', '𝜱' => 'Φ', '𝜲' => 'Χ', '𝜳' => 'Ψ', '𝜴' => 'Ω', '𝜵' => '∇', '𝜶' => 'α', '𝜷' => 'β', '𝜸' => 'γ', '𝜹' => 'δ', '𝜺' => 'ε', '𝜻' => 'ζ', '𝜼' => 'η', '𝜽' => 'θ', '𝜾' => 'ι', '𝜿' => 'κ', '𝝀' => 'λ', '𝝁' => 'μ', '𝝂' => 'ν', '𝝃' => 'ξ', '𝝄' => 'ο', '𝝅' => 'π', '𝝆' => 'ρ', '𝝇' => 'ς', '𝝈' => 'σ', '𝝉' => 'τ', '𝝊' => 'υ', '𝝋' => 'φ', '𝝌' => 'χ', '𝝍' => 'ψ', '𝝎' => 'ω', '𝝏' => '∂', '𝝐' => 'ε', '𝝑' => 'θ', '𝝒' => 'κ', '𝝓' => 'φ', '𝝔' => 'ρ', '𝝕' => 'π', '𝝖' => 'Α', '𝝗' => 'Β', '𝝘' => 'Γ', '𝝙' => 'Δ', '𝝚' => 'Ε', '𝝛' => 'Ζ', '𝝜' => 'Η', '𝝝' => 'Θ', '𝝞' => 'Ι', '𝝟' => 'Κ', '𝝠' => 'Λ', '𝝡' => 'Μ', '𝝢' => 'Ν', '𝝣' => 'Ξ', '𝝤' => 'Ο', '𝝥' => 'Π', '𝝦' => 'Ρ', '𝝧' => 'Θ', '𝝨' => 'Σ', '𝝩' => 'Τ', '𝝪' => 'Υ', '𝝫' => 'Φ', '𝝬' => 'Χ', '𝝭' => 'Ψ', '𝝮' => 'Ω', '𝝯' => '∇', '𝝰' => 'α', '𝝱' => 'β', '𝝲' => 'γ', '𝝳' => 'δ', '𝝴' => 'ε', '𝝵' => 'ζ', '𝝶' => 'η', '𝝷' => 'θ', '𝝸' => 'ι', '𝝹' => 'κ', '𝝺' => 'λ', '𝝻' => 'μ', '𝝼' => 'ν', '𝝽' => 'ξ', '𝝾' => 'ο', '𝝿' => 'π', '𝞀' => 'ρ', '𝞁' => 'ς', '𝞂' => 'σ', '𝞃' => 'τ', '𝞄' => 'υ', '𝞅' => 'φ', '𝞆' => 'χ', '𝞇' => 'ψ', '𝞈' => 'ω', '𝞉' => '∂', '𝞊' => 'ε', '𝞋' => 'θ', '𝞌' => 'κ', '𝞍' => 'φ', '𝞎' => 'ρ', '𝞏' => 'π', '𝞐' => 'Α', '𝞑' => 'Β', '𝞒' => 'Γ', '𝞓' => 'Δ', '𝞔' => 'Ε', '𝞕' => 'Ζ', '𝞖' => 'Η', '𝞗' => 'Θ', '𝞘' => 'Ι', '𝞙' => 'Κ', '𝞚' => 'Λ', '𝞛' => 'Μ', '𝞜' => 'Ν', '𝞝' => 'Ξ', '𝞞' => 'Ο', '𝞟' => 'Π', '𝞠' => 'Ρ', '𝞡' => 'Θ', '𝞢' => 'Σ', '𝞣' => 'Τ', '𝞤' => 'Υ', '𝞥' => 'Φ', '𝞦' => 'Χ', '𝞧' => 'Ψ', '𝞨' => 'Ω', '𝞩' => '∇', '𝞪' => 'α', '𝞫' => 'β', '𝞬' => 'γ', '𝞭' => 'δ', '𝞮' => 'ε', '𝞯' => 'ζ', '𝞰' => 'η', '𝞱' => 'θ', '𝞲' => 'ι', '𝞳' => 'κ', '𝞴' => 'λ', '𝞵' => 'μ', '𝞶' => 'ν', '𝞷' => 'ξ', '𝞸' => 'ο', '𝞹' => 'π', '𝞺' => 'ρ', '𝞻' => 'ς', '𝞼' => 'σ', '𝞽' => 'τ', '𝞾' => 'υ', '𝞿' => 'φ', '𝟀' => 'χ', '𝟁' => 'ψ', '𝟂' => 'ω', '𝟃' => '∂', '𝟄' => 'ε', '𝟅' => 'θ', '𝟆' => 'κ', '𝟇' => 'φ', '𝟈' => 'ρ', '𝟉' => 'π', '𝟊' => 'Ϝ', '𝟋' => 'ϝ', '𝟎' => '0', '𝟏' => '1', '𝟐' => '2', '𝟑' => '3', '𝟒' => '4', '𝟓' => '5', '𝟔' => '6', '𝟕' => '7', '𝟖' => '8', '𝟗' => '9', '𝟘' => '0', '𝟙' => '1', '𝟚' => '2', '𝟛' => '3', '𝟜' => '4', '𝟝' => '5', '𝟞' => '6', '𝟟' => '7', '𝟠' => '8', '𝟡' => '9', '𝟢' => '0', '𝟣' => '1', '𝟤' => '2', '𝟥' => '3', '𝟦' => '4', '𝟧' => '5', '𝟨' => '6', '𝟩' => '7', '𝟪' => '8', '𝟫' => '9', '𝟬' => '0', '𝟭' => '1', '𝟮' => '2', '𝟯' => '3', '𝟰' => '4', '𝟱' => '5', '𝟲' => '6', '𝟳' => '7', '𝟴' => '8', '𝟵' => '9', '𝟶' => '0', '𝟷' => '1', '𝟸' => '2', '𝟹' => '3', '𝟺' => '4', '𝟻' => '5', '𝟼' => '6', '𝟽' => '7', '𝟾' => '8', '𝟿' => '9', '𞸀' => 'ا', '𞸁' => 'ب', '𞸂' => 'ج', '𞸃' => 'د', '𞸅' => 'و', '𞸆' => 'ز', '𞸇' => 'ح', '𞸈' => 'ط', '𞸉' => 'ي', '𞸊' => 'ك', '𞸋' => 'ل', '𞸌' => 'م', '𞸍' => 'ن', '𞸎' => 'س', '𞸏' => 'ع', '𞸐' => 'ف', '𞸑' => 'ص', '𞸒' => 'ق', '𞸓' => 'ر', '𞸔' => 'ش', '𞸕' => 'ت', '𞸖' => 'ث', '𞸗' => 'خ', '𞸘' => 'ذ', '𞸙' => 'ض', '𞸚' => 'ظ', '𞸛' => 'غ', '𞸜' => 'ٮ', '𞸝' => 'ں', '𞸞' => 'ڡ', '𞸟' => 'ٯ', '𞸡' => 'ب', '𞸢' => 'ج', '𞸤' => 'ه', '𞸧' => 'ح', '𞸩' => 'ي', '𞸪' => 'ك', '𞸫' => 'ل', '𞸬' => 'م', '𞸭' => 'ن', '𞸮' => 'س', '𞸯' => 'ع', '𞸰' => 'ف', '𞸱' => 'ص', '𞸲' => 'ق', '𞸴' => 'ش', '𞸵' => 'ت', '𞸶' => 'ث', '𞸷' => 'خ', '𞸹' => 'ض', '𞸻' => 'غ', '𞹂' => 'ج', '𞹇' => 'ح', '𞹉' => 'ي', '𞹋' => 'ل', '𞹍' => 'ن', '𞹎' => 'س', '𞹏' => 'ع', '𞹑' => 'ص', '𞹒' => 'ق', '𞹔' => 'ش', '𞹗' => 'خ', '𞹙' => 'ض', '𞹛' => 'غ', '𞹝' => 'ں', '𞹟' => 'ٯ', '𞹡' => 'ب', '𞹢' => 'ج', '𞹤' => 'ه', '𞹧' => 'ح', '𞹨' => 'ط', '𞹩' => 'ي', '𞹪' => 'ك', '𞹬' => 'م', '𞹭' => 'ن', '𞹮' => 'س', '𞹯' => 'ع', '𞹰' => 'ف', '𞹱' => 'ص', '𞹲' => 'ق', '𞹴' => 'ش', '𞹵' => 'ت', '𞹶' => 'ث', '𞹷' => 'خ', '𞹹' => 'ض', '𞹺' => 'ظ', '𞹻' => 'غ', '𞹼' => 'ٮ', '𞹾' => 'ڡ', '𞺀' => 'ا', '𞺁' => 'ب', '𞺂' => 'ج', '𞺃' => 'د', '𞺄' => 'ه', '𞺅' => 'و', '𞺆' => 'ز', '𞺇' => 'ح', '𞺈' => 'ط', '𞺉' => 'ي', '𞺋' => 'ل', '𞺌' => 'م', '𞺍' => 'ن', '𞺎' => 'س', '𞺏' => 'ع', '𞺐' => 'ف', '𞺑' => 'ص', '𞺒' => 'ق', '𞺓' => 'ر', '𞺔' => 'ش', '𞺕' => 'ت', '𞺖' => 'ث', '𞺗' => 'خ', '𞺘' => 'ذ', '𞺙' => 'ض', '𞺚' => 'ظ', '𞺛' => 'غ', '𞺡' => 'ب', '𞺢' => 'ج', '𞺣' => 'د', '𞺥' => 'و', '𞺦' => 'ز', '𞺧' => 'ح', '𞺨' => 'ط', '𞺩' => 'ي', '𞺫' => 'ل', '𞺬' => 'م', '𞺭' => 'ن', '𞺮' => 'س', '𞺯' => 'ع', '𞺰' => 'ف', '𞺱' => 'ص', '𞺲' => 'ق', '𞺳' => 'ر', '𞺴' => 'ش', '𞺵' => 'ت', '𞺶' => 'ث', '𞺷' => 'خ', '𞺸' => 'ذ', '𞺹' => 'ض', '𞺺' => 'ظ', '𞺻' => 'غ', '🄀' => '0.', '🄁' => '0,', '🄂' => '1,', '🄃' => '2,', '🄄' => '3,', '🄅' => '4,', '🄆' => '5,', '🄇' => '6,', '🄈' => '7,', '🄉' => '8,', '🄊' => '9,', '🄐' => '(A)', '🄑' => '(B)', '🄒' => '(C)', '🄓' => '(D)', '🄔' => '(E)', '🄕' => '(F)', '🄖' => '(G)', '🄗' => '(H)', '🄘' => '(I)', '🄙' => '(J)', '🄚' => '(K)', '🄛' => '(L)', '🄜' => '(M)', '🄝' => '(N)', '🄞' => '(O)', '🄟' => '(P)', '🄠' => '(Q)', '🄡' => '(R)', '🄢' => '(S)', '🄣' => '(T)', '🄤' => '(U)', '🄥' => '(V)', '🄦' => '(W)', '🄧' => '(X)', '🄨' => '(Y)', '🄩' => '(Z)', '🄪' => '〔S〕', '🄫' => 'C', '🄬' => 'R', '🄭' => 'CD', '🄮' => 'WZ', '🄰' => 'A', '🄱' => 'B', '🄲' => 'C', '🄳' => 'D', '🄴' => 'E', '🄵' => 'F', '🄶' => 'G', '🄷' => 'H', '🄸' => 'I', '🄹' => 'J', '🄺' => 'K', '🄻' => 'L', '🄼' => 'M', '🄽' => 'N', '🄾' => 'O', '🄿' => 'P', '🅀' => 'Q', '🅁' => 'R', '🅂' => 'S', '🅃' => 'T', '🅄' => 'U', '🅅' => 'V', '🅆' => 'W', '🅇' => 'X', '🅈' => 'Y', '🅉' => 'Z', '🅊' => 'HV', '🅋' => 'MV', '🅌' => 'SD', '🅍' => 'SS', '🅎' => 'PPV', '🅏' => 'WC', '🅪' => 'MC', '🅫' => 'MD', '🅬' => 'MR', '🆐' => 'DJ', '🈀' => 'ほか', '🈁' => 'ココ', '🈂' => 'サ', '🈐' => '手', '🈑' => '字', '🈒' => '双', '🈓' => 'デ', '🈔' => '二', '🈕' => '多', '🈖' => '解', '🈗' => '天', '🈘' => '交', '🈙' => '映', '🈚' => '無', '🈛' => '料', '🈜' => '前', '🈝' => '後', '🈞' => '再', '🈟' => '新', '🈠' => '初', '🈡' => '終', '🈢' => '生', '🈣' => '販', '🈤' => '声', '🈥' => '吹', '🈦' => '演', '🈧' => '投', '🈨' => '捕', '🈩' => '一', '🈪' => '三', '🈫' => '遊', '🈬' => '左', '🈭' => '中', '🈮' => '右', '🈯' => '指', '🈰' => '走', '🈱' => '打', '🈲' => '禁', '🈳' => '空', '🈴' => '合', '🈵' => '満', '🈶' => '有', '🈷' => '月', '🈸' => '申', '🈹' => '割', '🈺' => '営', '🈻' => '配', '🉀' => '〔本〕', '🉁' => '〔三〕', '🉂' => '〔二〕', '🉃' => '〔安〕', '🉄' => '〔点〕', '🉅' => '〔打〕', '🉆' => '〔盗〕', '🉇' => '〔勝〕', '🉈' => '〔敗〕', '🉐' => '得', '🉑' => '可', '🯰' => '0', '🯱' => '1', '🯲' => '2', '🯳' => '3', '🯴' => '4', '🯵' => '5', '🯶' => '6', '🯷' => '7', '🯸' => '8', '🯹' => '9');
<?php

namespace _HumbugBox1cb33d1f20f1;

return array('À' => 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', 'Ç' => 'Ç', 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'ç' => 'ç', 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'ÿ' => 'ÿ', 'Ā' => 'Ā', 'ā' => 'ā', 'Ă' => 'Ă', 'ă' => 'ă', 'Ą' => 'Ą', 'ą' => 'ą', 'Ć' => 'Ć', 'ć' => 'ć', 'Ĉ' => 'Ĉ', 'ĉ' => 'ĉ', 'Ċ' => 'Ċ', 'ċ' => 'ċ', 'Č' => 'Č', 'č' => 'č', 'Ď' => 'Ď', 'ď' => 'ď', 'Ē' => 'Ē', 'ē' => 'ē', 'Ĕ' => 'Ĕ', 'ĕ' => 'ĕ', 'Ė' => 'Ė', 'ė' => 'ė', 'Ę' => 'Ę', 'ę' => 'ę', 'Ě' => 'Ě', 'ě' => 'ě', 'Ĝ' => 'Ĝ', 'ĝ' => 'ĝ', 'Ğ' => 'Ğ', 'ğ' => 'ğ', 'Ġ' => 'Ġ', 'ġ' => 'ġ', 'Ģ' => 'Ģ', 'ģ' => 'ģ', 'Ĥ' => 'Ĥ', 'ĥ' => 'ĥ', 'Ĩ' => 'Ĩ', 'ĩ' => 'ĩ', 'Ī' => 'Ī', 'ī' => 'ī', 'Ĭ' => 'Ĭ', 'ĭ' => 'ĭ', 'Į' => 'Į', 'į' => 'į', 'İ' => 'İ', 'Ĵ' => 'Ĵ', 'ĵ' => 'ĵ', 'Ķ' => 'Ķ', 'ķ' => 'ķ', 'Ĺ' => 'Ĺ', 'ĺ' => 'ĺ', 'Ļ' => 'Ļ', 'ļ' => 'ļ', 'Ľ' => 'Ľ', 'ľ' => 'ľ', 'Ń' => 'Ń', 'ń' => 'ń', 'Ņ' => 'Ņ', 'ņ' => 'ņ', 'Ň' => 'Ň', 'ň' => 'ň', 'Ō' => 'Ō', 'ō' => 'ō', 'Ŏ' => 'Ŏ', 'ŏ' => 'ŏ', 'Ő' => 'Ő', 'ő' => 'ő', 'Ŕ' => 'Ŕ', 'ŕ' => 'ŕ', 'Ŗ' => 'Ŗ', 'ŗ' => 'ŗ', 'Ř' => 'Ř', 'ř' => 'ř', 'Ś' => 'Ś', 'ś' => 'ś', 'Ŝ' => 'Ŝ', 'ŝ' => 'ŝ', 'Ş' => 'Ş', 'ş' => 'ş', 'Š' => 'Š', 'š' => 'š', 'Ţ' => 'Ţ', 'ţ' => 'ţ', 'Ť' => 'Ť', 'ť' => 'ť', 'Ũ' => 'Ũ', 'ũ' => 'ũ', 'Ū' => 'Ū', 'ū' => 'ū', 'Ŭ' => 'Ŭ', 'ŭ' => 'ŭ', 'Ů' => 'Ů', 'ů' => 'ů', 'Ű' => 'Ű', 'ű' => 'ű', 'Ų' => 'Ų', 'ų' => 'ų', 'Ŵ' => 'Ŵ', 'ŵ' => 'ŵ', 'Ŷ' => 'Ŷ', 'ŷ' => 'ŷ', 'Ÿ' => 'Ÿ', 'Ź' => 'Ź', 'ź' => 'ź', 'Ż' => 'Ż', 'ż' => 'ż', 'Ž' => 'Ž', 'ž' => 'ž', 'Ơ' => 'Ơ', 'ơ' => 'ơ', 'Ư' => 'Ư', 'ư' => 'ư', 'Ǎ' => 'Ǎ', 'ǎ' => 'ǎ', 'Ǐ' => 'Ǐ', 'ǐ' => 'ǐ', 'Ǒ' => 'Ǒ', 'ǒ' => 'ǒ', 'Ǔ' => 'Ǔ', 'ǔ' => 'ǔ', 'Ǖ' => 'Ǖ', 'ǖ' => 'ǖ', 'Ǘ' => 'Ǘ', 'ǘ' => 'ǘ', 'Ǚ' => 'Ǚ', 'ǚ' => 'ǚ', 'Ǜ' => 'Ǜ', 'ǜ' => 'ǜ', 'Ǟ' => 'Ǟ', 'ǟ' => 'ǟ', 'Ǡ' => 'Ǡ', 'ǡ' => 'ǡ', 'Ǣ' => 'Ǣ', 'ǣ' => 'ǣ', 'Ǧ' => 'Ǧ', 'ǧ' => 'ǧ', 'Ǩ' => 'Ǩ', 'ǩ' => 'ǩ', 'Ǫ' => 'Ǫ', 'ǫ' => 'ǫ', 'Ǭ' => 'Ǭ', 'ǭ' => 'ǭ', 'Ǯ' => 'Ǯ', 'ǯ' => 'ǯ', 'ǰ' => 'ǰ', 'Ǵ' => 'Ǵ', 'ǵ' => 'ǵ', 'Ǹ' => 'Ǹ', 'ǹ' => 'ǹ', 'Ǻ' => 'Ǻ', 'ǻ' => 'ǻ', 'Ǽ' => 'Ǽ', 'ǽ' => 'ǽ', 'Ǿ' => 'Ǿ', 'ǿ' => 'ǿ', 'Ȁ' => 'Ȁ', 'ȁ' => 'ȁ', 'Ȃ' => 'Ȃ', 'ȃ' => 'ȃ', 'Ȅ' => 'Ȅ', 'ȅ' => 'ȅ', 'Ȇ' => 'Ȇ', 'ȇ' => 'ȇ', 'Ȉ' => 'Ȉ', 'ȉ' => 'ȉ', 'Ȋ' => 'Ȋ', 'ȋ' => 'ȋ', 'Ȍ' => 'Ȍ', 'ȍ' => 'ȍ', 'Ȏ' => 'Ȏ', 'ȏ' => 'ȏ', 'Ȑ' => 'Ȑ', 'ȑ' => 'ȑ', 'Ȓ' => 'Ȓ', 'ȓ' => 'ȓ', 'Ȕ' => 'Ȕ', 'ȕ' => 'ȕ', 'Ȗ' => 'Ȗ', 'ȗ' => 'ȗ', 'Ș' => 'Ș', 'ș' => 'ș', 'Ț' => 'Ț', 'ț' => 'ț', 'Ȟ' => 'Ȟ', 'ȟ' => 'ȟ', 'Ȧ' => 'Ȧ', 'ȧ' => 'ȧ', 'Ȩ' => 'Ȩ', 'ȩ' => 'ȩ', 'Ȫ' => 'Ȫ', 'ȫ' => 'ȫ', 'Ȭ' => 'Ȭ', 'ȭ' => 'ȭ', 'Ȯ' => 'Ȯ', 'ȯ' => 'ȯ', 'Ȱ' => 'Ȱ', 'ȱ' => 'ȱ', 'Ȳ' => 'Ȳ', 'ȳ' => 'ȳ', '΅' => '΅', 'Ά' => 'Ά', 'Έ' => 'Έ', 'Ή' => 'Ή', 'Ί' => 'Ί', 'Ό' => 'Ό', 'Ύ' => 'Ύ', 'Ώ' => 'Ώ', 'ΐ' => 'ΐ', 'Ϊ' => 'Ϊ', 'Ϋ' => 'Ϋ', 'ά' => 'ά', 'έ' => 'έ', 'ή' => 'ή', 'ί' => 'ί', 'ΰ' => 'ΰ', 'ϊ' => 'ϊ', 'ϋ' => 'ϋ', 'ό' => 'ό', 'ύ' => 'ύ', 'ώ' => 'ώ', 'ϓ' => 'ϓ', 'ϔ' => 'ϔ', 'Ѐ' => 'Ѐ', 'Ё' => 'Ё', 'Ѓ' => 'Ѓ', 'Ї' => 'Ї', 'Ќ' => 'Ќ', 'Ѝ' => 'Ѝ', 'Ў' => 'Ў', 'Й' => 'Й', 'й' => 'й', 'ѐ' => 'ѐ', 'ё' => 'ё', 'ѓ' => 'ѓ', 'ї' => 'ї', 'ќ' => 'ќ', 'ѝ' => 'ѝ', 'ў' => 'ў', 'Ѷ' => 'Ѷ', 'ѷ' => 'ѷ', 'Ӂ' => 'Ӂ', 'ӂ' => 'ӂ', 'Ӑ' => 'Ӑ', 'ӑ' => 'ӑ', 'Ӓ' => 'Ӓ', 'ӓ' => 'ӓ', 'Ӗ' => 'Ӗ', 'ӗ' => 'ӗ', 'Ӛ' => 'Ӛ', 'ӛ' => 'ӛ', 'Ӝ' => 'Ӝ', 'ӝ' => 'ӝ', 'Ӟ' => 'Ӟ', 'ӟ' => 'ӟ', 'Ӣ' => 'Ӣ', 'ӣ' => 'ӣ', 'Ӥ' => 'Ӥ', 'ӥ' => 'ӥ', 'Ӧ' => 'Ӧ', 'ӧ' => 'ӧ', 'Ӫ' => 'Ӫ', 'ӫ' => 'ӫ', 'Ӭ' => 'Ӭ', 'ӭ' => 'ӭ', 'Ӯ' => 'Ӯ', 'ӯ' => 'ӯ', 'Ӱ' => 'Ӱ', 'ӱ' => 'ӱ', 'Ӳ' => 'Ӳ', 'ӳ' => 'ӳ', 'Ӵ' => 'Ӵ', 'ӵ' => 'ӵ', 'Ӹ' => 'Ӹ', 'ӹ' => 'ӹ', 'آ' => 'آ', 'أ' => 'أ', 'ؤ' => 'ؤ', 'إ' => 'إ', 'ئ' => 'ئ', 'ۀ' => 'ۀ', 'ۂ' => 'ۂ', 'ۓ' => 'ۓ', 'ऩ' => 'ऩ', 'ऱ' => 'ऱ', 'ऴ' => 'ऴ', 'ো' => 'ো', 'ৌ' => 'ৌ', 'ୈ' => 'ୈ', 'ୋ' => 'ୋ', 'ୌ' => 'ୌ', 'ஔ' => 'ஔ', 'ொ' => 'ொ', 'ோ' => 'ோ', 'ௌ' => 'ௌ', 'ై' => 'ై', 'ೀ' => 'ೀ', 'ೇ' => 'ೇ', 'ೈ' => 'ೈ', 'ೊ' => 'ೊ', 'ೋ' => 'ೋ', 'ൊ' => 'ൊ', 'ോ' => 'ോ', 'ൌ' => 'ൌ', 'ේ' => 'ේ', 'ො' => 'ො', 'ෝ' => 'ෝ', 'ෞ' => 'ෞ', 'ဦ' => 'ဦ', 'ᬆ' => 'ᬆ', 'ᬈ' => 'ᬈ', 'ᬊ' => 'ᬊ', 'ᬌ' => 'ᬌ', 'ᬎ' => 'ᬎ', 'ᬒ' => 'ᬒ', 'ᬻ' => 'ᬻ', 'ᬽ' => 'ᬽ', 'ᭀ' => 'ᭀ', 'ᭁ' => 'ᭁ', 'ᭃ' => 'ᭃ', 'Ḁ' => 'Ḁ', 'ḁ' => 'ḁ', 'Ḃ' => 'Ḃ', 'ḃ' => 'ḃ', 'Ḅ' => 'Ḅ', 'ḅ' => 'ḅ', 'Ḇ' => 'Ḇ', 'ḇ' => 'ḇ', 'Ḉ' => 'Ḉ', 'ḉ' => 'ḉ', 'Ḋ' => 'Ḋ', 'ḋ' => 'ḋ', 'Ḍ' => 'Ḍ', 'ḍ' => 'ḍ', 'Ḏ' => 'Ḏ', 'ḏ' => 'ḏ', 'Ḑ' => 'Ḑ', 'ḑ' => 'ḑ', 'Ḓ' => 'Ḓ', 'ḓ' => 'ḓ', 'Ḕ' => 'Ḕ', 'ḕ' => 'ḕ', 'Ḗ' => 'Ḗ', 'ḗ' => 'ḗ', 'Ḙ' => 'Ḙ', 'ḙ' => 'ḙ', 'Ḛ' => 'Ḛ', 'ḛ' => 'ḛ', 'Ḝ' => 'Ḝ', 'ḝ' => 'ḝ', 'Ḟ' => 'Ḟ', 'ḟ' => 'ḟ', 'Ḡ' => 'Ḡ', 'ḡ' => 'ḡ', 'Ḣ' => 'Ḣ', 'ḣ' => 'ḣ', 'Ḥ' => 'Ḥ', 'ḥ' => 'ḥ', 'Ḧ' => 'Ḧ', 'ḧ' => 'ḧ', 'Ḩ' => 'Ḩ', 'ḩ' => 'ḩ', 'Ḫ' => 'Ḫ', 'ḫ' => 'ḫ', 'Ḭ' => 'Ḭ', 'ḭ' => 'ḭ', 'Ḯ' => 'Ḯ', 'ḯ' => 'ḯ', 'Ḱ' => 'Ḱ', 'ḱ' => 'ḱ', 'Ḳ' => 'Ḳ', 'ḳ' => 'ḳ', 'Ḵ' => 'Ḵ', 'ḵ' => 'ḵ', 'Ḷ' => 'Ḷ', 'ḷ' => 'ḷ', 'Ḹ' => 'Ḹ', 'ḹ' => 'ḹ', 'Ḻ' => 'Ḻ', 'ḻ' => 'ḻ', 'Ḽ' => 'Ḽ', 'ḽ' => 'ḽ', 'Ḿ' => 'Ḿ', 'ḿ' => 'ḿ', 'Ṁ' => 'Ṁ', 'ṁ' => 'ṁ', 'Ṃ' => 'Ṃ', 'ṃ' => 'ṃ', 'Ṅ' => 'Ṅ', 'ṅ' => 'ṅ', 'Ṇ' => 'Ṇ', 'ṇ' => 'ṇ', 'Ṉ' => 'Ṉ', 'ṉ' => 'ṉ', 'Ṋ' => 'Ṋ', 'ṋ' => 'ṋ', 'Ṍ' => 'Ṍ', 'ṍ' => 'ṍ', 'Ṏ' => 'Ṏ', 'ṏ' => 'ṏ', 'Ṑ' => 'Ṑ', 'ṑ' => 'ṑ', 'Ṓ' => 'Ṓ', 'ṓ' => 'ṓ', 'Ṕ' => 'Ṕ', 'ṕ' => 'ṕ', 'Ṗ' => 'Ṗ', 'ṗ' => 'ṗ', 'Ṙ' => 'Ṙ', 'ṙ' => 'ṙ', 'Ṛ' => 'Ṛ', 'ṛ' => 'ṛ', 'Ṝ' => 'Ṝ', 'ṝ' => 'ṝ', 'Ṟ' => 'Ṟ', 'ṟ' => 'ṟ', 'Ṡ' => 'Ṡ', 'ṡ' => 'ṡ', 'Ṣ' => 'Ṣ', 'ṣ' => 'ṣ', 'Ṥ' => 'Ṥ', 'ṥ' => 'ṥ', 'Ṧ' => 'Ṧ', 'ṧ' => 'ṧ', 'Ṩ' => 'Ṩ', 'ṩ' => 'ṩ', 'Ṫ' => 'Ṫ', 'ṫ' => 'ṫ', 'Ṭ' => 'Ṭ', 'ṭ' => 'ṭ', 'Ṯ' => 'Ṯ', 'ṯ' => 'ṯ', 'Ṱ' => 'Ṱ', 'ṱ' => 'ṱ', 'Ṳ' => 'Ṳ', 'ṳ' => 'ṳ', 'Ṵ' => 'Ṵ', 'ṵ' => 'ṵ', 'Ṷ' => 'Ṷ', 'ṷ' => 'ṷ', 'Ṹ' => 'Ṹ', 'ṹ' => 'ṹ', 'Ṻ' => 'Ṻ', 'ṻ' => 'ṻ', 'Ṽ' => 'Ṽ', 'ṽ' => 'ṽ', 'Ṿ' => 'Ṿ', 'ṿ' => 'ṿ', 'Ẁ' => 'Ẁ', 'ẁ' => 'ẁ', 'Ẃ' => 'Ẃ', 'ẃ' => 'ẃ', 'Ẅ' => 'Ẅ', 'ẅ' => 'ẅ', 'Ẇ' => 'Ẇ', 'ẇ' => 'ẇ', 'Ẉ' => 'Ẉ', 'ẉ' => 'ẉ', 'Ẋ' => 'Ẋ', 'ẋ' => 'ẋ', 'Ẍ' => 'Ẍ', 'ẍ' => 'ẍ', 'Ẏ' => 'Ẏ', 'ẏ' => 'ẏ', 'Ẑ' => 'Ẑ', 'ẑ' => 'ẑ', 'Ẓ' => 'Ẓ', 'ẓ' => 'ẓ', 'Ẕ' => 'Ẕ', 'ẕ' => 'ẕ', 'ẖ' => 'ẖ', 'ẗ' => 'ẗ', 'ẘ' => 'ẘ', 'ẙ' => 'ẙ', 'ẛ' => 'ẛ', 'Ạ' => 'Ạ', 'ạ' => 'ạ', 'Ả' => 'Ả', 'ả' => 'ả', 'Ấ' => 'Ấ', 'ấ' => 'ấ', 'Ầ' => 'Ầ', 'ầ' => 'ầ', 'Ẩ' => 'Ẩ', 'ẩ' => 'ẩ', 'Ẫ' => 'Ẫ', 'ẫ' => 'ẫ', 'Ậ' => 'Ậ', 'ậ' => 'ậ', 'Ắ' => 'Ắ', 'ắ' => 'ắ', 'Ằ' => 'Ằ', 'ằ' => 'ằ', 'Ẳ' => 'Ẳ', 'ẳ' => 'ẳ', 'Ẵ' => 'Ẵ', 'ẵ' => 'ẵ', 'Ặ' => 'Ặ', 'ặ' => 'ặ', 'Ẹ' => 'Ẹ', 'ẹ' => 'ẹ', 'Ẻ' => 'Ẻ', 'ẻ' => 'ẻ', 'Ẽ' => 'Ẽ', 'ẽ' => 'ẽ', 'Ế' => 'Ế', 'ế' => 'ế', 'Ề' => 'Ề', 'ề' => 'ề', 'Ể' => 'Ể', 'ể' => 'ể', 'Ễ' => 'Ễ', 'ễ' => 'ễ', 'Ệ' => 'Ệ', 'ệ' => 'ệ', 'Ỉ' => 'Ỉ', 'ỉ' => 'ỉ', 'Ị' => 'Ị', 'ị' => 'ị', 'Ọ' => 'Ọ', 'ọ' => 'ọ', 'Ỏ' => 'Ỏ', 'ỏ' => 'ỏ', 'Ố' => 'Ố', 'ố' => 'ố', 'Ồ' => 'Ồ', 'ồ' => 'ồ', 'Ổ' => 'Ổ', 'ổ' => 'ổ', 'Ỗ' => 'Ỗ', 'ỗ' => 'ỗ', 'Ộ' => 'Ộ', 'ộ' => 'ộ', 'Ớ' => 'Ớ', 'ớ' => 'ớ', 'Ờ' => 'Ờ', 'ờ' => 'ờ', 'Ở' => 'Ở', 'ở' => 'ở', 'Ỡ' => 'Ỡ', 'ỡ' => 'ỡ', 'Ợ' => 'Ợ', 'ợ' => 'ợ', 'Ụ' => 'Ụ', 'ụ' => 'ụ', 'Ủ' => 'Ủ', 'ủ' => 'ủ', 'Ứ' => 'Ứ', 'ứ' => 'ứ', 'Ừ' => 'Ừ', 'ừ' => 'ừ', 'Ử' => 'Ử', 'ử' => 'ử', 'Ữ' => 'Ữ', 'ữ' => 'ữ', 'Ự' => 'Ự', 'ự' => 'ự', 'Ỳ' => 'Ỳ', 'ỳ' => 'ỳ', 'Ỵ' => 'Ỵ', 'ỵ' => 'ỵ', 'Ỷ' => 'Ỷ', 'ỷ' => 'ỷ', 'Ỹ' => 'Ỹ', 'ỹ' => 'ỹ', 'ἀ' => 'ἀ', 'ἁ' => 'ἁ', 'ἂ' => 'ἂ', 'ἃ' => 'ἃ', 'ἄ' => 'ἄ', 'ἅ' => 'ἅ', 'ἆ' => 'ἆ', 'ἇ' => 'ἇ', 'Ἀ' => 'Ἀ', 'Ἁ' => 'Ἁ', 'Ἂ' => 'Ἂ', 'Ἃ' => 'Ἃ', 'Ἄ' => 'Ἄ', 'Ἅ' => 'Ἅ', 'Ἆ' => 'Ἆ', 'Ἇ' => 'Ἇ', 'ἐ' => 'ἐ', 'ἑ' => 'ἑ', 'ἒ' => 'ἒ', 'ἓ' => 'ἓ', 'ἔ' => 'ἔ', 'ἕ' => 'ἕ', 'Ἐ' => 'Ἐ', 'Ἑ' => 'Ἑ', 'Ἒ' => 'Ἒ', 'Ἓ' => 'Ἓ', 'Ἔ' => 'Ἔ', 'Ἕ' => 'Ἕ', 'ἠ' => 'ἠ', 'ἡ' => 'ἡ', 'ἢ' => 'ἢ', 'ἣ' => 'ἣ', 'ἤ' => 'ἤ', 'ἥ' => 'ἥ', 'ἦ' => 'ἦ', 'ἧ' => 'ἧ', 'Ἠ' => 'Ἠ', 'Ἡ' => 'Ἡ', 'Ἢ' => 'Ἢ', 'Ἣ' => 'Ἣ', 'Ἤ' => 'Ἤ', 'Ἥ' => 'Ἥ', 'Ἦ' => 'Ἦ', 'Ἧ' => 'Ἧ', 'ἰ' => 'ἰ', 'ἱ' => 'ἱ', 'ἲ' => 'ἲ', 'ἳ' => 'ἳ', 'ἴ' => 'ἴ', 'ἵ' => 'ἵ', 'ἶ' => 'ἶ', 'ἷ' => 'ἷ', 'Ἰ' => 'Ἰ', 'Ἱ' => 'Ἱ', 'Ἲ' => 'Ἲ', 'Ἳ' => 'Ἳ', 'Ἴ' => 'Ἴ', 'Ἵ' => 'Ἵ', 'Ἶ' => 'Ἶ', 'Ἷ' => 'Ἷ', 'ὀ' => 'ὀ', 'ὁ' => 'ὁ', 'ὂ' => 'ὂ', 'ὃ' => 'ὃ', 'ὄ' => 'ὄ', 'ὅ' => 'ὅ', 'Ὀ' => 'Ὀ', 'Ὁ' => 'Ὁ', 'Ὂ' => 'Ὂ', 'Ὃ' => 'Ὃ', 'Ὄ' => 'Ὄ', 'Ὅ' => 'Ὅ', 'ὐ' => 'ὐ', 'ὑ' => 'ὑ', 'ὒ' => 'ὒ', 'ὓ' => 'ὓ', 'ὔ' => 'ὔ', 'ὕ' => 'ὕ', 'ὖ' => 'ὖ', 'ὗ' => 'ὗ', 'Ὑ' => 'Ὑ', 'Ὓ' => 'Ὓ', 'Ὕ' => 'Ὕ', 'Ὗ' => 'Ὗ', 'ὠ' => 'ὠ', 'ὡ' => 'ὡ', 'ὢ' => 'ὢ', 'ὣ' => 'ὣ', 'ὤ' => 'ὤ', 'ὥ' => 'ὥ', 'ὦ' => 'ὦ', 'ὧ' => 'ὧ', 'Ὠ' => 'Ὠ', 'Ὡ' => 'Ὡ', 'Ὢ' => 'Ὢ', 'Ὣ' => 'Ὣ', 'Ὤ' => 'Ὤ', 'Ὥ' => 'Ὥ', 'Ὦ' => 'Ὦ', 'Ὧ' => 'Ὧ', 'ὰ' => 'ὰ', 'ὲ' => 'ὲ', 'ὴ' => 'ὴ', 'ὶ' => 'ὶ', 'ὸ' => 'ὸ', 'ὺ' => 'ὺ', 'ὼ' => 'ὼ', 'ᾀ' => 'ᾀ', 'ᾁ' => 'ᾁ', 'ᾂ' => 'ᾂ', 'ᾃ' => 'ᾃ', 'ᾄ' => 'ᾄ', 'ᾅ' => 'ᾅ', 'ᾆ' => 'ᾆ', 'ᾇ' => 'ᾇ', 'ᾈ' => 'ᾈ', 'ᾉ' => 'ᾉ', 'ᾊ' => 'ᾊ', 'ᾋ' => 'ᾋ', 'ᾌ' => 'ᾌ', 'ᾍ' => 'ᾍ', 'ᾎ' => 'ᾎ', 'ᾏ' => 'ᾏ', 'ᾐ' => 'ᾐ', 'ᾑ' => 'ᾑ', 'ᾒ' => 'ᾒ', 'ᾓ' => 'ᾓ', 'ᾔ' => 'ᾔ', 'ᾕ' => 'ᾕ', 'ᾖ' => 'ᾖ', 'ᾗ' => 'ᾗ', 'ᾘ' => 'ᾘ', 'ᾙ' => 'ᾙ', 'ᾚ' => 'ᾚ', 'ᾛ' => 'ᾛ', 'ᾜ' => 'ᾜ', 'ᾝ' => 'ᾝ', 'ᾞ' => 'ᾞ', 'ᾟ' => 'ᾟ', 'ᾠ' => 'ᾠ', 'ᾡ' => 'ᾡ', 'ᾢ' => 'ᾢ', 'ᾣ' => 'ᾣ', 'ᾤ' => 'ᾤ', 'ᾥ' => 'ᾥ', 'ᾦ' => 'ᾦ', 'ᾧ' => 'ᾧ', 'ᾨ' => 'ᾨ', 'ᾩ' => 'ᾩ', 'ᾪ' => 'ᾪ', 'ᾫ' => 'ᾫ', 'ᾬ' => 'ᾬ', 'ᾭ' => 'ᾭ', 'ᾮ' => 'ᾮ', 'ᾯ' => 'ᾯ', 'ᾰ' => 'ᾰ', 'ᾱ' => 'ᾱ', 'ᾲ' => 'ᾲ', 'ᾳ' => 'ᾳ', 'ᾴ' => 'ᾴ', 'ᾶ' => 'ᾶ', 'ᾷ' => 'ᾷ', 'Ᾰ' => 'Ᾰ', 'Ᾱ' => 'Ᾱ', 'Ὰ' => 'Ὰ', 'ᾼ' => 'ᾼ', '῁' => '῁', 'ῂ' => 'ῂ', 'ῃ' => 'ῃ', 'ῄ' => 'ῄ', 'ῆ' => 'ῆ', 'ῇ' => 'ῇ', 'Ὲ' => 'Ὲ', 'Ὴ' => 'Ὴ', 'ῌ' => 'ῌ', '῍' => '῍', '῎' => '῎', '῏' => '῏', 'ῐ' => 'ῐ', 'ῑ' => 'ῑ', 'ῒ' => 'ῒ', 'ῖ' => 'ῖ', 'ῗ' => 'ῗ', 'Ῐ' => 'Ῐ', 'Ῑ' => 'Ῑ', 'Ὶ' => 'Ὶ', '῝' => '῝', '῞' => '῞', '῟' => '῟', 'ῠ' => 'ῠ', 'ῡ' => 'ῡ', 'ῢ' => 'ῢ', 'ῤ' => 'ῤ', 'ῥ' => 'ῥ', 'ῦ' => 'ῦ', 'ῧ' => 'ῧ', 'Ῠ' => 'Ῠ', 'Ῡ' => 'Ῡ', 'Ὺ' => 'Ὺ', 'Ῥ' => 'Ῥ', '῭' => '῭', 'ῲ' => 'ῲ', 'ῳ' => 'ῳ', 'ῴ' => 'ῴ', 'ῶ' => 'ῶ', 'ῷ' => 'ῷ', 'Ὸ' => 'Ὸ', 'Ὼ' => 'Ὼ', 'ῼ' => 'ῼ', '↚' => '↚', '↛' => '↛', '↮' => '↮', '⇍' => '⇍', '⇎' => '⇎', '⇏' => '⇏', '∄' => '∄', '∉' => '∉', '∌' => '∌', '∤' => '∤', '∦' => '∦', '≁' => '≁', '≄' => '≄', '≇' => '≇', '≉' => '≉', '≠' => '≠', '≢' => '≢', '≭' => '≭', '≮' => '≮', '≯' => '≯', '≰' => '≰', '≱' => '≱', '≴' => '≴', '≵' => '≵', '≸' => '≸', '≹' => '≹', '⊀' => '⊀', '⊁' => '⊁', '⊄' => '⊄', '⊅' => '⊅', '⊈' => '⊈', '⊉' => '⊉', '⊬' => '⊬', '⊭' => '⊭', '⊮' => '⊮', '⊯' => '⊯', '⋠' => '⋠', '⋡' => '⋡', '⋢' => '⋢', '⋣' => '⋣', '⋪' => '⋪', '⋫' => '⋫', '⋬' => '⋬', '⋭' => '⋭', 'が' => 'が', 'ぎ' => 'ぎ', 'ぐ' => 'ぐ', 'げ' => 'げ', 'ご' => 'ご', 'ざ' => 'ざ', 'じ' => 'じ', 'ず' => 'ず', 'ぜ' => 'ぜ', 'ぞ' => 'ぞ', 'だ' => 'だ', 'ぢ' => 'ぢ', 'づ' => 'づ', 'で' => 'で', 'ど' => 'ど', 'ば' => 'ば', 'ぱ' => 'ぱ', 'び' => 'び', 'ぴ' => 'ぴ', 'ぶ' => 'ぶ', 'ぷ' => 'ぷ', 'べ' => 'べ', 'ぺ' => 'ぺ', 'ぼ' => 'ぼ', 'ぽ' => 'ぽ', 'ゔ' => 'ゔ', 'ゞ' => 'ゞ', 'ガ' => 'ガ', 'ギ' => 'ギ', 'グ' => 'グ', 'ゲ' => 'ゲ', 'ゴ' => 'ゴ', 'ザ' => 'ザ', 'ジ' => 'ジ', 'ズ' => 'ズ', 'ゼ' => 'ゼ', 'ゾ' => 'ゾ', 'ダ' => 'ダ', 'ヂ' => 'ヂ', 'ヅ' => 'ヅ', 'デ' => 'デ', 'ド' => 'ド', 'バ' => 'バ', 'パ' => 'パ', 'ビ' => 'ビ', 'ピ' => 'ピ', 'ブ' => 'ブ', 'プ' => 'プ', 'ベ' => 'ベ', 'ペ' => 'ペ', 'ボ' => 'ボ', 'ポ' => 'ポ', 'ヴ' => 'ヴ', 'ヷ' => 'ヷ', 'ヸ' => 'ヸ', 'ヹ' => 'ヹ', 'ヺ' => 'ヺ', 'ヾ' => 'ヾ', '𑂚' => '𑂚', '𑂜' => '𑂜', '𑂫' => '𑂫', '𑄮' => '𑄮', '𑄯' => '𑄯', '𑍋' => '𑍋', '𑍌' => '𑍌', '𑒻' => '𑒻', '𑒼' => '𑒼', '𑒾' => '𑒾', '𑖺' => '𑖺', '𑖻' => '𑖻', '𑤸' => '𑤸');
<?php

namespace _HumbugBox1cb33d1f20f1;

return array('À' => 'À', 'Á' => 'Á', 'Â' => 'Â', 'Ã' => 'Ã', 'Ä' => 'Ä', 'Å' => 'Å', 'Ç' => 'Ç', 'È' => 'È', 'É' => 'É', 'Ê' => 'Ê', 'Ë' => 'Ë', 'Ì' => 'Ì', 'Í' => 'Í', 'Î' => 'Î', 'Ï' => 'Ï', 'Ñ' => 'Ñ', 'Ò' => 'Ò', 'Ó' => 'Ó', 'Ô' => 'Ô', 'Õ' => 'Õ', 'Ö' => 'Ö', 'Ù' => 'Ù', 'Ú' => 'Ú', 'Û' => 'Û', 'Ü' => 'Ü', 'Ý' => 'Ý', 'à' => 'à', 'á' => 'á', 'â' => 'â', 'ã' => 'ã', 'ä' => 'ä', 'å' => 'å', 'ç' => 'ç', 'è' => 'è', 'é' => 'é', 'ê' => 'ê', 'ë' => 'ë', 'ì' => 'ì', 'í' => 'í', 'î' => 'î', 'ï' => 'ï', 'ñ' => 'ñ', 'ò' => 'ò', 'ó' => 'ó', 'ô' => 'ô', 'õ' => 'õ', 'ö' => 'ö', 'ù' => 'ù', 'ú' => 'ú', 'û' => 'û', 'ü' => 'ü', 'ý' => 'ý', 'ÿ' => 'ÿ', 'Ā' => 'Ā', 'ā' => 'ā', 'Ă' => 'Ă', 'ă' => 'ă', 'Ą' => 'Ą', 'ą' => 'ą', 'Ć' => 'Ć', 'ć' => 'ć', 'Ĉ' => 'Ĉ', 'ĉ' => 'ĉ', 'Ċ' => 'Ċ', 'ċ' => 'ċ', 'Č' => 'Č', 'č' => 'č', 'Ď' => 'Ď', 'ď' => 'ď', 'Ē' => 'Ē', 'ē' => 'ē', 'Ĕ' => 'Ĕ', 'ĕ' => 'ĕ', 'Ė' => 'Ė', 'ė' => 'ė', 'Ę' => 'Ę', 'ę' => 'ę', 'Ě' => 'Ě', 'ě' => 'ě', 'Ĝ' => 'Ĝ', 'ĝ' => 'ĝ', 'Ğ' => 'Ğ', 'ğ' => 'ğ', 'Ġ' => 'Ġ', 'ġ' => 'ġ', 'Ģ' => 'Ģ', 'ģ' => 'ģ', 'Ĥ' => 'Ĥ', 'ĥ' => 'ĥ', 'Ĩ' => 'Ĩ', 'ĩ' => 'ĩ', 'Ī' => 'Ī', 'ī' => 'ī', 'Ĭ' => 'Ĭ', 'ĭ' => 'ĭ', 'Į' => 'Į', 'į' => 'į', 'İ' => 'İ', 'Ĵ' => 'Ĵ', 'ĵ' => 'ĵ', 'Ķ' => 'Ķ', 'ķ' => 'ķ', 'Ĺ' => 'Ĺ', 'ĺ' => 'ĺ', 'Ļ' => 'Ļ', 'ļ' => 'ļ', 'Ľ' => 'Ľ', 'ľ' => 'ľ', 'Ń' => 'Ń', 'ń' => 'ń', 'Ņ' => 'Ņ', 'ņ' => 'ņ', 'Ň' => 'Ň', 'ň' => 'ň', 'Ō' => 'Ō', 'ō' => 'ō', 'Ŏ' => 'Ŏ', 'ŏ' => 'ŏ', 'Ő' => 'Ő', 'ő' => 'ő', 'Ŕ' => 'Ŕ', 'ŕ' => 'ŕ', 'Ŗ' => 'Ŗ', 'ŗ' => 'ŗ', 'Ř' => 'Ř', 'ř' => 'ř', 'Ś' => 'Ś', 'ś' => 'ś', 'Ŝ' => 'Ŝ', 'ŝ' => 'ŝ', 'Ş' => 'Ş', 'ş' => 'ş', 'Š' => 'Š', 'š' => 'š', 'Ţ' => 'Ţ', 'ţ' => 'ţ', 'Ť' => 'Ť', 'ť' => 'ť', 'Ũ' => 'Ũ', 'ũ' => 'ũ', 'Ū' => 'Ū', 'ū' => 'ū', 'Ŭ' => 'Ŭ', 'ŭ' => 'ŭ', 'Ů' => 'Ů', 'ů' => 'ů', 'Ű' => 'Ű', 'ű' => 'ű', 'Ų' => 'Ų', 'ų' => 'ų', 'Ŵ' => 'Ŵ', 'ŵ' => 'ŵ', 'Ŷ' => 'Ŷ', 'ŷ' => 'ŷ', 'Ÿ' => 'Ÿ', 'Ź' => 'Ź', 'ź' => 'ź', 'Ż' => 'Ż', 'ż' => 'ż', 'Ž' => 'Ž', 'ž' => 'ž', 'Ơ' => 'Ơ', 'ơ' => 'ơ', 'Ư' => 'Ư', 'ư' => 'ư', 'Ǎ' => 'Ǎ', 'ǎ' => 'ǎ', 'Ǐ' => 'Ǐ', 'ǐ' => 'ǐ', 'Ǒ' => 'Ǒ', 'ǒ' => 'ǒ', 'Ǔ' => 'Ǔ', 'ǔ' => 'ǔ', 'Ǖ' => 'Ǖ', 'ǖ' => 'ǖ', 'Ǘ' => 'Ǘ', 'ǘ' => 'ǘ', 'Ǚ' => 'Ǚ', 'ǚ' => 'ǚ', 'Ǜ' => 'Ǜ', 'ǜ' => 'ǜ', 'Ǟ' => 'Ǟ', 'ǟ' => 'ǟ', 'Ǡ' => 'Ǡ', 'ǡ' => 'ǡ', 'Ǣ' => 'Ǣ', 'ǣ' => 'ǣ', 'Ǧ' => 'Ǧ', 'ǧ' => 'ǧ', 'Ǩ' => 'Ǩ', 'ǩ' => 'ǩ', 'Ǫ' => 'Ǫ', 'ǫ' => 'ǫ', 'Ǭ' => 'Ǭ', 'ǭ' => 'ǭ', 'Ǯ' => 'Ǯ', 'ǯ' => 'ǯ', 'ǰ' => 'ǰ', 'Ǵ' => 'Ǵ', 'ǵ' => 'ǵ', 'Ǹ' => 'Ǹ', 'ǹ' => 'ǹ', 'Ǻ' => 'Ǻ', 'ǻ' => 'ǻ', 'Ǽ' => 'Ǽ', 'ǽ' => 'ǽ', 'Ǿ' => 'Ǿ', 'ǿ' => 'ǿ', 'Ȁ' => 'Ȁ', 'ȁ' => 'ȁ', 'Ȃ' => 'Ȃ', 'ȃ' => 'ȃ', 'Ȅ' => 'Ȅ', 'ȅ' => 'ȅ', 'Ȇ' => 'Ȇ', 'ȇ' => 'ȇ', 'Ȉ' => 'Ȉ', 'ȉ' => 'ȉ', 'Ȋ' => 'Ȋ', 'ȋ' => 'ȋ', 'Ȍ' => 'Ȍ', 'ȍ' => 'ȍ', 'Ȏ' => 'Ȏ', 'ȏ' => 'ȏ', 'Ȑ' => 'Ȑ', 'ȑ' => 'ȑ', 'Ȓ' => 'Ȓ', 'ȓ' => 'ȓ', 'Ȕ' => 'Ȕ', 'ȕ' => 'ȕ', 'Ȗ' => 'Ȗ', 'ȗ' => 'ȗ', 'Ș' => 'Ș', 'ș' => 'ș', 'Ț' => 'Ț', 'ț' => 'ț', 'Ȟ' => 'Ȟ', 'ȟ' => 'ȟ', 'Ȧ' => 'Ȧ', 'ȧ' => 'ȧ', 'Ȩ' => 'Ȩ', 'ȩ' => 'ȩ', 'Ȫ' => 'Ȫ', 'ȫ' => 'ȫ', 'Ȭ' => 'Ȭ', 'ȭ' => 'ȭ', 'Ȯ' => 'Ȯ', 'ȯ' => 'ȯ', 'Ȱ' => 'Ȱ', 'ȱ' => 'ȱ', 'Ȳ' => 'Ȳ', 'ȳ' => 'ȳ', '̀' => '̀', '́' => '́', '̓' => '̓', '̈́' => '̈́', 'ʹ' => 'ʹ', ';' => ';', '΅' => '΅', 'Ά' => 'Ά', '·' => '·', 'Έ' => 'Έ', 'Ή' => 'Ή', 'Ί' => 'Ί', 'Ό' => 'Ό', 'Ύ' => 'Ύ', 'Ώ' => 'Ώ', 'ΐ' => 'ΐ', 'Ϊ' => 'Ϊ', 'Ϋ' => 'Ϋ', 'ά' => 'ά', 'έ' => 'έ', 'ή' => 'ή', 'ί' => 'ί', 'ΰ' => 'ΰ', 'ϊ' => 'ϊ', 'ϋ' => 'ϋ', 'ό' => 'ό', 'ύ' => 'ύ', 'ώ' => 'ώ', 'ϓ' => 'ϓ', 'ϔ' => 'ϔ', 'Ѐ' => 'Ѐ', 'Ё' => 'Ё', 'Ѓ' => 'Ѓ', 'Ї' => 'Ї', 'Ќ' => 'Ќ', 'Ѝ' => 'Ѝ', 'Ў' => 'Ў', 'Й' => 'Й', 'й' => 'й', 'ѐ' => 'ѐ', 'ё' => 'ё', 'ѓ' => 'ѓ', 'ї' => 'ї', 'ќ' => 'ќ', 'ѝ' => 'ѝ', 'ў' => 'ў', 'Ѷ' => 'Ѷ', 'ѷ' => 'ѷ', 'Ӂ' => 'Ӂ', 'ӂ' => 'ӂ', 'Ӑ' => 'Ӑ', 'ӑ' => 'ӑ', 'Ӓ' => 'Ӓ', 'ӓ' => 'ӓ', 'Ӗ' => 'Ӗ', 'ӗ' => 'ӗ', 'Ӛ' => 'Ӛ', 'ӛ' => 'ӛ', 'Ӝ' => 'Ӝ', 'ӝ' => 'ӝ', 'Ӟ' => 'Ӟ', 'ӟ' => 'ӟ', 'Ӣ' => 'Ӣ', 'ӣ' => 'ӣ', 'Ӥ' => 'Ӥ', 'ӥ' => 'ӥ', 'Ӧ' => 'Ӧ', 'ӧ' => 'ӧ', 'Ӫ' => 'Ӫ', 'ӫ' => 'ӫ', 'Ӭ' => 'Ӭ', 'ӭ' => 'ӭ', 'Ӯ' => 'Ӯ', 'ӯ' => 'ӯ', 'Ӱ' => 'Ӱ', 'ӱ' => 'ӱ', 'Ӳ' => 'Ӳ', 'ӳ' => 'ӳ', 'Ӵ' => 'Ӵ', 'ӵ' => 'ӵ', 'Ӹ' => 'Ӹ', 'ӹ' => 'ӹ', 'آ' => 'آ', 'أ' => 'أ', 'ؤ' => 'ؤ', 'إ' => 'إ', 'ئ' => 'ئ', 'ۀ' => 'ۀ', 'ۂ' => 'ۂ', 'ۓ' => 'ۓ', 'ऩ' => 'ऩ', 'ऱ' => 'ऱ', 'ऴ' => 'ऴ', 'क़' => 'क़', 'ख़' => 'ख़', 'ग़' => 'ग़', 'ज़' => 'ज़', 'ड़' => 'ड़', 'ढ़' => 'ढ़', 'फ़' => 'फ़', 'य़' => 'य़', 'ো' => 'ো', 'ৌ' => 'ৌ', 'ড়' => 'ড়', 'ঢ়' => 'ঢ়', 'য়' => 'য়', 'ਲ਼' => 'ਲ਼', 'ਸ਼' => 'ਸ਼', 'ਖ਼' => 'ਖ਼', 'ਗ਼' => 'ਗ਼', 'ਜ਼' => 'ਜ਼', 'ਫ਼' => 'ਫ਼', 'ୈ' => 'ୈ', 'ୋ' => 'ୋ', 'ୌ' => 'ୌ', 'ଡ଼' => 'ଡ଼', 'ଢ଼' => 'ଢ଼', 'ஔ' => 'ஔ', 'ொ' => 'ொ', 'ோ' => 'ோ', 'ௌ' => 'ௌ', 'ై' => 'ై', 'ೀ' => 'ೀ', 'ೇ' => 'ೇ', 'ೈ' => 'ೈ', 'ೊ' => 'ೊ', 'ೋ' => 'ೋ', 'ൊ' => 'ൊ', 'ോ' => 'ോ', 'ൌ' => 'ൌ', 'ේ' => 'ේ', 'ො' => 'ො', 'ෝ' => 'ෝ', 'ෞ' => 'ෞ', 'གྷ' => 'གྷ', 'ཌྷ' => 'ཌྷ', 'དྷ' => 'དྷ', 'བྷ' => 'བྷ', 'ཛྷ' => 'ཛྷ', 'ཀྵ' => 'ཀྵ', 'ཱི' => 'ཱི', 'ཱུ' => 'ཱུ', 'ྲྀ' => 'ྲྀ', 'ླྀ' => 'ླྀ', 'ཱྀ' => 'ཱྀ', 'ྒྷ' => 'ྒྷ', 'ྜྷ' => 'ྜྷ', 'ྡྷ' => 'ྡྷ', 'ྦྷ' => 'ྦྷ', 'ྫྷ' => 'ྫྷ', 'ྐྵ' => 'ྐྵ', 'ဦ' => 'ဦ', 'ᬆ' => 'ᬆ', 'ᬈ' => 'ᬈ', 'ᬊ' => 'ᬊ', 'ᬌ' => 'ᬌ', 'ᬎ' => 'ᬎ', 'ᬒ' => 'ᬒ', 'ᬻ' => 'ᬻ', 'ᬽ' => 'ᬽ', 'ᭀ' => 'ᭀ', 'ᭁ' => 'ᭁ', 'ᭃ' => 'ᭃ', 'Ḁ' => 'Ḁ', 'ḁ' => 'ḁ', 'Ḃ' => 'Ḃ', 'ḃ' => 'ḃ', 'Ḅ' => 'Ḅ', 'ḅ' => 'ḅ', 'Ḇ' => 'Ḇ', 'ḇ' => 'ḇ', 'Ḉ' => 'Ḉ', 'ḉ' => 'ḉ', 'Ḋ' => 'Ḋ', 'ḋ' => 'ḋ', 'Ḍ' => 'Ḍ', 'ḍ' => 'ḍ', 'Ḏ' => 'Ḏ', 'ḏ' => 'ḏ', 'Ḑ' => 'Ḑ', 'ḑ' => 'ḑ', 'Ḓ' => 'Ḓ', 'ḓ' => 'ḓ', 'Ḕ' => 'Ḕ', 'ḕ' => 'ḕ', 'Ḗ' => 'Ḗ', 'ḗ' => 'ḗ', 'Ḙ' => 'Ḙ', 'ḙ' => 'ḙ', 'Ḛ' => 'Ḛ', 'ḛ' => 'ḛ', 'Ḝ' => 'Ḝ', 'ḝ' => 'ḝ', 'Ḟ' => 'Ḟ', 'ḟ' => 'ḟ', 'Ḡ' => 'Ḡ', 'ḡ' => 'ḡ', 'Ḣ' => 'Ḣ', 'ḣ' => 'ḣ', 'Ḥ' => 'Ḥ', 'ḥ' => 'ḥ', 'Ḧ' => 'Ḧ', 'ḧ' => 'ḧ', 'Ḩ' => 'Ḩ', 'ḩ' => 'ḩ', 'Ḫ' => 'Ḫ', 'ḫ' => 'ḫ', 'Ḭ' => 'Ḭ', 'ḭ' => 'ḭ', 'Ḯ' => 'Ḯ', 'ḯ' => 'ḯ', 'Ḱ' => 'Ḱ', 'ḱ' => 'ḱ', 'Ḳ' => 'Ḳ', 'ḳ' => 'ḳ', 'Ḵ' => 'Ḵ', 'ḵ' => 'ḵ', 'Ḷ' => 'Ḷ', 'ḷ' => 'ḷ', 'Ḹ' => 'Ḹ', 'ḹ' => 'ḹ', 'Ḻ' => 'Ḻ', 'ḻ' => 'ḻ', 'Ḽ' => 'Ḽ', 'ḽ' => 'ḽ', 'Ḿ' => 'Ḿ', 'ḿ' => 'ḿ', 'Ṁ' => 'Ṁ', 'ṁ' => 'ṁ', 'Ṃ' => 'Ṃ', 'ṃ' => 'ṃ', 'Ṅ' => 'Ṅ', 'ṅ' => 'ṅ', 'Ṇ' => 'Ṇ', 'ṇ' => 'ṇ', 'Ṉ' => 'Ṉ', 'ṉ' => 'ṉ', 'Ṋ' => 'Ṋ', 'ṋ' => 'ṋ', 'Ṍ' => 'Ṍ', 'ṍ' => 'ṍ', 'Ṏ' => 'Ṏ', 'ṏ' => 'ṏ', 'Ṑ' => 'Ṑ', 'ṑ' => 'ṑ', 'Ṓ' => 'Ṓ', 'ṓ' => 'ṓ', 'Ṕ' => 'Ṕ', 'ṕ' => 'ṕ', 'Ṗ' => 'Ṗ', 'ṗ' => 'ṗ', 'Ṙ' => 'Ṙ', 'ṙ' => 'ṙ', 'Ṛ' => 'Ṛ', 'ṛ' => 'ṛ', 'Ṝ' => 'Ṝ', 'ṝ' => 'ṝ', 'Ṟ' => 'Ṟ', 'ṟ' => 'ṟ', 'Ṡ' => 'Ṡ', 'ṡ' => 'ṡ', 'Ṣ' => 'Ṣ', 'ṣ' => 'ṣ', 'Ṥ' => 'Ṥ', 'ṥ' => 'ṥ', 'Ṧ' => 'Ṧ', 'ṧ' => 'ṧ', 'Ṩ' => 'Ṩ', 'ṩ' => 'ṩ', 'Ṫ' => 'Ṫ', 'ṫ' => 'ṫ', 'Ṭ' => 'Ṭ', 'ṭ' => 'ṭ', 'Ṯ' => 'Ṯ', 'ṯ' => 'ṯ', 'Ṱ' => 'Ṱ', 'ṱ' => 'ṱ', 'Ṳ' => 'Ṳ', 'ṳ' => 'ṳ', 'Ṵ' => 'Ṵ', 'ṵ' => 'ṵ', 'Ṷ' => 'Ṷ', 'ṷ' => 'ṷ', 'Ṹ' => 'Ṹ', 'ṹ' => 'ṹ', 'Ṻ' => 'Ṻ', 'ṻ' => 'ṻ', 'Ṽ' => 'Ṽ', 'ṽ' => 'ṽ', 'Ṿ' => 'Ṿ', 'ṿ' => 'ṿ', 'Ẁ' => 'Ẁ', 'ẁ' => 'ẁ', 'Ẃ' => 'Ẃ', 'ẃ' => 'ẃ', 'Ẅ' => 'Ẅ', 'ẅ' => 'ẅ', 'Ẇ' => 'Ẇ', 'ẇ' => 'ẇ', 'Ẉ' => 'Ẉ', 'ẉ' => 'ẉ', 'Ẋ' => 'Ẋ', 'ẋ' => 'ẋ', 'Ẍ' => 'Ẍ', 'ẍ' => 'ẍ', 'Ẏ' => 'Ẏ', 'ẏ' => 'ẏ', 'Ẑ' => 'Ẑ', 'ẑ' => 'ẑ', 'Ẓ' => 'Ẓ', 'ẓ' => 'ẓ', 'Ẕ' => 'Ẕ', 'ẕ' => 'ẕ', 'ẖ' => 'ẖ', 'ẗ' => 'ẗ', 'ẘ' => 'ẘ', 'ẙ' => 'ẙ', 'ẛ' => 'ẛ', 'Ạ' => 'Ạ', 'ạ' => 'ạ', 'Ả' => 'Ả', 'ả' => 'ả', 'Ấ' => 'Ấ', 'ấ' => 'ấ', 'Ầ' => 'Ầ', 'ầ' => 'ầ', 'Ẩ' => 'Ẩ', 'ẩ' => 'ẩ', 'Ẫ' => 'Ẫ', 'ẫ' => 'ẫ', 'Ậ' => 'Ậ', 'ậ' => 'ậ', 'Ắ' => 'Ắ', 'ắ' => 'ắ', 'Ằ' => 'Ằ', 'ằ' => 'ằ', 'Ẳ' => 'Ẳ', 'ẳ' => 'ẳ', 'Ẵ' => 'Ẵ', 'ẵ' => 'ẵ', 'Ặ' => 'Ặ', 'ặ' => 'ặ', 'Ẹ' => 'Ẹ', 'ẹ' => 'ẹ', 'Ẻ' => 'Ẻ', 'ẻ' => 'ẻ', 'Ẽ' => 'Ẽ', 'ẽ' => 'ẽ', 'Ế' => 'Ế', 'ế' => 'ế', 'Ề' => 'Ề', 'ề' => 'ề', 'Ể' => 'Ể', 'ể' => 'ể', 'Ễ' => 'Ễ', 'ễ' => 'ễ', 'Ệ' => 'Ệ', 'ệ' => 'ệ', 'Ỉ' => 'Ỉ', 'ỉ' => 'ỉ', 'Ị' => 'Ị', 'ị' => 'ị', 'Ọ' => 'Ọ', 'ọ' => 'ọ', 'Ỏ' => 'Ỏ', 'ỏ' => 'ỏ', 'Ố' => 'Ố', 'ố' => 'ố', 'Ồ' => 'Ồ', 'ồ' => 'ồ', 'Ổ' => 'Ổ', 'ổ' => 'ổ', 'Ỗ' => 'Ỗ', 'ỗ' => 'ỗ', 'Ộ' => 'Ộ', 'ộ' => 'ộ', 'Ớ' => 'Ớ', 'ớ' => 'ớ', 'Ờ' => 'Ờ', 'ờ' => 'ờ', 'Ở' => 'Ở', 'ở' => 'ở', 'Ỡ' => 'Ỡ', 'ỡ' => 'ỡ', 'Ợ' => 'Ợ', 'ợ' => 'ợ', 'Ụ' => 'Ụ', 'ụ' => 'ụ', 'Ủ' => 'Ủ', 'ủ' => 'ủ', 'Ứ' => 'Ứ', 'ứ' => 'ứ', 'Ừ' => 'Ừ', 'ừ' => 'ừ', 'Ử' => 'Ử', 'ử' => 'ử', 'Ữ' => 'Ữ', 'ữ' => 'ữ', 'Ự' => 'Ự', 'ự' => 'ự', 'Ỳ' => 'Ỳ', 'ỳ' => 'ỳ', 'Ỵ' => 'Ỵ', 'ỵ' => 'ỵ', 'Ỷ' => 'Ỷ', 'ỷ' => 'ỷ', 'Ỹ' => 'Ỹ', 'ỹ' => 'ỹ', 'ἀ' => 'ἀ', 'ἁ' => 'ἁ', 'ἂ' => 'ἂ', 'ἃ' => 'ἃ', 'ἄ' => 'ἄ', 'ἅ' => 'ἅ', 'ἆ' => 'ἆ', 'ἇ' => 'ἇ', 'Ἀ' => 'Ἀ', 'Ἁ' => 'Ἁ', 'Ἂ' => 'Ἂ', 'Ἃ' => 'Ἃ', 'Ἄ' => 'Ἄ', 'Ἅ' => 'Ἅ', 'Ἆ' => 'Ἆ', 'Ἇ' => 'Ἇ', 'ἐ' => 'ἐ', 'ἑ' => 'ἑ', 'ἒ' => 'ἒ', 'ἓ' => 'ἓ', 'ἔ' => 'ἔ', 'ἕ' => 'ἕ', 'Ἐ' => 'Ἐ', 'Ἑ' => 'Ἑ', 'Ἒ' => 'Ἒ', 'Ἓ' => 'Ἓ', 'Ἔ' => 'Ἔ', 'Ἕ' => 'Ἕ', 'ἠ' => 'ἠ', 'ἡ' => 'ἡ', 'ἢ' => 'ἢ', 'ἣ' => 'ἣ', 'ἤ' => 'ἤ', 'ἥ' => 'ἥ', 'ἦ' => 'ἦ', 'ἧ' => 'ἧ', 'Ἠ' => 'Ἠ', 'Ἡ' => 'Ἡ', 'Ἢ' => 'Ἢ', 'Ἣ' => 'Ἣ', 'Ἤ' => 'Ἤ', 'Ἥ' => 'Ἥ', 'Ἦ' => 'Ἦ', 'Ἧ' => 'Ἧ', 'ἰ' => 'ἰ', 'ἱ' => 'ἱ', 'ἲ' => 'ἲ', 'ἳ' => 'ἳ', 'ἴ' => 'ἴ', 'ἵ' => 'ἵ', 'ἶ' => 'ἶ', 'ἷ' => 'ἷ', 'Ἰ' => 'Ἰ', 'Ἱ' => 'Ἱ', 'Ἲ' => 'Ἲ', 'Ἳ' => 'Ἳ', 'Ἴ' => 'Ἴ', 'Ἵ' => 'Ἵ', 'Ἶ' => 'Ἶ', 'Ἷ' => 'Ἷ', 'ὀ' => 'ὀ', 'ὁ' => 'ὁ', 'ὂ' => 'ὂ', 'ὃ' => 'ὃ', 'ὄ' => 'ὄ', 'ὅ' => 'ὅ', 'Ὀ' => 'Ὀ', 'Ὁ' => 'Ὁ', 'Ὂ' => 'Ὂ', 'Ὃ' => 'Ὃ', 'Ὄ' => 'Ὄ', 'Ὅ' => 'Ὅ', 'ὐ' => 'ὐ', 'ὑ' => 'ὑ', 'ὒ' => 'ὒ', 'ὓ' => 'ὓ', 'ὔ' => 'ὔ', 'ὕ' => 'ὕ', 'ὖ' => 'ὖ', 'ὗ' => 'ὗ', 'Ὑ' => 'Ὑ', 'Ὓ' => 'Ὓ', 'Ὕ' => 'Ὕ', 'Ὗ' => 'Ὗ', 'ὠ' => 'ὠ', 'ὡ' => 'ὡ', 'ὢ' => 'ὢ', 'ὣ' => 'ὣ', 'ὤ' => 'ὤ', 'ὥ' => 'ὥ', 'ὦ' => 'ὦ', 'ὧ' => 'ὧ', 'Ὠ' => 'Ὠ', 'Ὡ' => 'Ὡ', 'Ὢ' => 'Ὢ', 'Ὣ' => 'Ὣ', 'Ὤ' => 'Ὤ', 'Ὥ' => 'Ὥ', 'Ὦ' => 'Ὦ', 'Ὧ' => 'Ὧ', 'ὰ' => 'ὰ', 'ά' => 'ά', 'ὲ' => 'ὲ', 'έ' => 'έ', 'ὴ' => 'ὴ', 'ή' => 'ή', 'ὶ' => 'ὶ', 'ί' => 'ί', 'ὸ' => 'ὸ', 'ό' => 'ό', 'ὺ' => 'ὺ', 'ύ' => 'ύ', 'ὼ' => 'ὼ', 'ώ' => 'ώ', 'ᾀ' => 'ᾀ', 'ᾁ' => 'ᾁ', 'ᾂ' => 'ᾂ', 'ᾃ' => 'ᾃ', 'ᾄ' => 'ᾄ', 'ᾅ' => 'ᾅ', 'ᾆ' => 'ᾆ', 'ᾇ' => 'ᾇ', 'ᾈ' => 'ᾈ', 'ᾉ' => 'ᾉ', 'ᾊ' => 'ᾊ', 'ᾋ' => 'ᾋ', 'ᾌ' => 'ᾌ', 'ᾍ' => 'ᾍ', 'ᾎ' => 'ᾎ', 'ᾏ' => 'ᾏ', 'ᾐ' => 'ᾐ', 'ᾑ' => 'ᾑ', 'ᾒ' => 'ᾒ', 'ᾓ' => 'ᾓ', 'ᾔ' => 'ᾔ', 'ᾕ' => 'ᾕ', 'ᾖ' => 'ᾖ', 'ᾗ' => 'ᾗ', 'ᾘ' => 'ᾘ', 'ᾙ' => 'ᾙ', 'ᾚ' => 'ᾚ', 'ᾛ' => 'ᾛ', 'ᾜ' => 'ᾜ', 'ᾝ' => 'ᾝ', 'ᾞ' => 'ᾞ', 'ᾟ' => 'ᾟ', 'ᾠ' => 'ᾠ', 'ᾡ' => 'ᾡ', 'ᾢ' => 'ᾢ', 'ᾣ' => 'ᾣ', 'ᾤ' => 'ᾤ', 'ᾥ' => 'ᾥ', 'ᾦ' => 'ᾦ', 'ᾧ' => 'ᾧ', 'ᾨ' => 'ᾨ', 'ᾩ' => 'ᾩ', 'ᾪ' => 'ᾪ', 'ᾫ' => 'ᾫ', 'ᾬ' => 'ᾬ', 'ᾭ' => 'ᾭ', 'ᾮ' => 'ᾮ', 'ᾯ' => 'ᾯ', 'ᾰ' => 'ᾰ', 'ᾱ' => 'ᾱ', 'ᾲ' => 'ᾲ', 'ᾳ' => 'ᾳ', 'ᾴ' => 'ᾴ', 'ᾶ' => 'ᾶ', 'ᾷ' => 'ᾷ', 'Ᾰ' => 'Ᾰ', 'Ᾱ' => 'Ᾱ', 'Ὰ' => 'Ὰ', 'Ά' => 'Ά', 'ᾼ' => 'ᾼ', 'ι' => 'ι', '῁' => '῁', 'ῂ' => 'ῂ', 'ῃ' => 'ῃ', 'ῄ' => 'ῄ', 'ῆ' => 'ῆ', 'ῇ' => 'ῇ', 'Ὲ' => 'Ὲ', 'Έ' => 'Έ', 'Ὴ' => 'Ὴ', 'Ή' => 'Ή', 'ῌ' => 'ῌ', '῍' => '῍', '῎' => '῎', '῏' => '῏', 'ῐ' => 'ῐ', 'ῑ' => 'ῑ', 'ῒ' => 'ῒ', 'ΐ' => 'ΐ', 'ῖ' => 'ῖ', 'ῗ' => 'ῗ', 'Ῐ' => 'Ῐ', 'Ῑ' => 'Ῑ', 'Ὶ' => 'Ὶ', 'Ί' => 'Ί', '῝' => '῝', '῞' => '῞', '῟' => '῟', 'ῠ' => 'ῠ', 'ῡ' => 'ῡ', 'ῢ' => 'ῢ', 'ΰ' => 'ΰ', 'ῤ' => 'ῤ', 'ῥ' => 'ῥ', 'ῦ' => 'ῦ', 'ῧ' => 'ῧ', 'Ῠ' => 'Ῠ', 'Ῡ' => 'Ῡ', 'Ὺ' => 'Ὺ', 'Ύ' => 'Ύ', 'Ῥ' => 'Ῥ', '῭' => '῭', '΅' => '΅', '`' => '`', 'ῲ' => 'ῲ', 'ῳ' => 'ῳ', 'ῴ' => 'ῴ', 'ῶ' => 'ῶ', 'ῷ' => 'ῷ', 'Ὸ' => 'Ὸ', 'Ό' => 'Ό', 'Ὼ' => 'Ὼ', 'Ώ' => 'Ώ', 'ῼ' => 'ῼ', '´' => '´', ' ' => ' ', ' ' => ' ', 'Ω' => 'Ω', 'K' => 'K', 'Å' => 'Å', '↚' => '↚', '↛' => '↛', '↮' => '↮', '⇍' => '⇍', '⇎' => '⇎', '⇏' => '⇏', '∄' => '∄', '∉' => '∉', '∌' => '∌', '∤' => '∤', '∦' => '∦', '≁' => '≁', '≄' => '≄', '≇' => '≇', '≉' => '≉', '≠' => '≠', '≢' => '≢', '≭' => '≭', '≮' => '≮', '≯' => '≯', '≰' => '≰', '≱' => '≱', '≴' => '≴', '≵' => '≵', '≸' => '≸', '≹' => '≹', '⊀' => '⊀', '⊁' => '⊁', '⊄' => '⊄', '⊅' => '⊅', '⊈' => '⊈', '⊉' => '⊉', '⊬' => '⊬', '⊭' => '⊭', '⊮' => '⊮', '⊯' => '⊯', '⋠' => '⋠', '⋡' => '⋡', '⋢' => '⋢', '⋣' => '⋣', '⋪' => '⋪', '⋫' => '⋫', '⋬' => '⋬', '⋭' => '⋭', '〈' => '〈', '〉' => '〉', '⫝̸' => '⫝̸', 'が' => 'が', 'ぎ' => 'ぎ', 'ぐ' => 'ぐ', 'げ' => 'げ', 'ご' => 'ご', 'ざ' => 'ざ', 'じ' => 'じ', 'ず' => 'ず', 'ぜ' => 'ぜ', 'ぞ' => 'ぞ', 'だ' => 'だ', 'ぢ' => 'ぢ', 'づ' => 'づ', 'で' => 'で', 'ど' => 'ど', 'ば' => 'ば', 'ぱ' => 'ぱ', 'び' => 'び', 'ぴ' => 'ぴ', 'ぶ' => 'ぶ', 'ぷ' => 'ぷ', 'べ' => 'べ', 'ぺ' => 'ぺ', 'ぼ' => 'ぼ', 'ぽ' => 'ぽ', 'ゔ' => 'ゔ', 'ゞ' => 'ゞ', 'ガ' => 'ガ', 'ギ' => 'ギ', 'グ' => 'グ', 'ゲ' => 'ゲ', 'ゴ' => 'ゴ', 'ザ' => 'ザ', 'ジ' => 'ジ', 'ズ' => 'ズ', 'ゼ' => 'ゼ', 'ゾ' => 'ゾ', 'ダ' => 'ダ', 'ヂ' => 'ヂ', 'ヅ' => 'ヅ', 'デ' => 'デ', 'ド' => 'ド', 'バ' => 'バ', 'パ' => 'パ', 'ビ' => 'ビ', 'ピ' => 'ピ', 'ブ' => 'ブ', 'プ' => 'プ', 'ベ' => 'ベ', 'ペ' => 'ペ', 'ボ' => 'ボ', 'ポ' => 'ポ', 'ヴ' => 'ヴ', 'ヷ' => 'ヷ', 'ヸ' => 'ヸ', 'ヹ' => 'ヹ', 'ヺ' => 'ヺ', 'ヾ' => 'ヾ', '豈' => '豈', '更' => '更', '車' => '車', '賈' => '賈', '滑' => '滑', '串' => '串', '句' => '句', '龜' => '龜', '龜' => '龜', '契' => '契', '金' => '金', '喇' => '喇', '奈' => '奈', '懶' => '懶', '癩' => '癩', '羅' => '羅', '蘿' => '蘿', '螺' => '螺', '裸' => '裸', '邏' => '邏', '樂' => '樂', '洛' => '洛', '烙' => '烙', '珞' => '珞', '落' => '落', '酪' => '酪', '駱' => '駱', '亂' => '亂', '卵' => '卵', '欄' => '欄', '爛' => '爛', '蘭' => '蘭', '鸞' => '鸞', '嵐' => '嵐', '濫' => '濫', '藍' => '藍', '襤' => '襤', '拉' => '拉', '臘' => '臘', '蠟' => '蠟', '廊' => '廊', '朗' => '朗', '浪' => '浪', '狼' => '狼', '郎' => '郎', '來' => '來', '冷' => '冷', '勞' => '勞', '擄' => '擄', '櫓' => '櫓', '爐' => '爐', '盧' => '盧', '老' => '老', '蘆' => '蘆', '虜' => '虜', '路' => '路', '露' => '露', '魯' => '魯', '鷺' => '鷺', '碌' => '碌', '祿' => '祿', '綠' => '綠', '菉' => '菉', '錄' => '錄', '鹿' => '鹿', '論' => '論', '壟' => '壟', '弄' => '弄', '籠' => '籠', '聾' => '聾', '牢' => '牢', '磊' => '磊', '賂' => '賂', '雷' => '雷', '壘' => '壘', '屢' => '屢', '樓' => '樓', '淚' => '淚', '漏' => '漏', '累' => '累', '縷' => '縷', '陋' => '陋', '勒' => '勒', '肋' => '肋', '凜' => '凜', '凌' => '凌', '稜' => '稜', '綾' => '綾', '菱' => '菱', '陵' => '陵', '讀' => '讀', '拏' => '拏', '樂' => '樂', '諾' => '諾', '丹' => '丹', '寧' => '寧', '怒' => '怒', '率' => '率', '異' => '異', '北' => '北', '磻' => '磻', '便' => '便', '復' => '復', '不' => '不', '泌' => '泌', '數' => '數', '索' => '索', '參' => '參', '塞' => '塞', '省' => '省', '葉' => '葉', '說' => '說', '殺' => '殺', '辰' => '辰', '沈' => '沈', '拾' => '拾', '若' => '若', '掠' => '掠', '略' => '略', '亮' => '亮', '兩' => '兩', '凉' => '凉', '梁' => '梁', '糧' => '糧', '良' => '良', '諒' => '諒', '量' => '量', '勵' => '勵', '呂' => '呂', '女' => '女', '廬' => '廬', '旅' => '旅', '濾' => '濾', '礪' => '礪', '閭' => '閭', '驪' => '驪', '麗' => '麗', '黎' => '黎', '力' => '力', '曆' => '曆', '歷' => '歷', '轢' => '轢', '年' => '年', '憐' => '憐', '戀' => '戀', '撚' => '撚', '漣' => '漣', '煉' => '煉', '璉' => '璉', '秊' => '秊', '練' => '練', '聯' => '聯', '輦' => '輦', '蓮' => '蓮', '連' => '連', '鍊' => '鍊', '列' => '列', '劣' => '劣', '咽' => '咽', '烈' => '烈', '裂' => '裂', '說' => '說', '廉' => '廉', '念' => '念', '捻' => '捻', '殮' => '殮', '簾' => '簾', '獵' => '獵', '令' => '令', '囹' => '囹', '寧' => '寧', '嶺' => '嶺', '怜' => '怜', '玲' => '玲', '瑩' => '瑩', '羚' => '羚', '聆' => '聆', '鈴' => '鈴', '零' => '零', '靈' => '靈', '領' => '領', '例' => '例', '禮' => '禮', '醴' => '醴', '隸' => '隸', '惡' => '惡', '了' => '了', '僚' => '僚', '寮' => '寮', '尿' => '尿', '料' => '料', '樂' => '樂', '燎' => '燎', '療' => '療', '蓼' => '蓼', '遼' => '遼', '龍' => '龍', '暈' => '暈', '阮' => '阮', '劉' => '劉', '杻' => '杻', '柳' => '柳', '流' => '流', '溜' => '溜', '琉' => '琉', '留' => '留', '硫' => '硫', '紐' => '紐', '類' => '類', '六' => '六', '戮' => '戮', '陸' => '陸', '倫' => '倫', '崙' => '崙', '淪' => '淪', '輪' => '輪', '律' => '律', '慄' => '慄', '栗' => '栗', '率' => '率', '隆' => '隆', '利' => '利', '吏' => '吏', '履' => '履', '易' => '易', '李' => '李', '梨' => '梨', '泥' => '泥', '理' => '理', '痢' => '痢', '罹' => '罹', '裏' => '裏', '裡' => '裡', '里' => '里', '離' => '離', '匿' => '匿', '溺' => '溺', '吝' => '吝', '燐' => '燐', '璘' => '璘', '藺' => '藺', '隣' => '隣', '鱗' => '鱗', '麟' => '麟', '林' => '林', '淋' => '淋', '臨' => '臨', '立' => '立', '笠' => '笠', '粒' => '粒', '狀' => '狀', '炙' => '炙', '識' => '識', '什' => '什', '茶' => '茶', '刺' => '刺', '切' => '切', '度' => '度', '拓' => '拓', '糖' => '糖', '宅' => '宅', '洞' => '洞', '暴' => '暴', '輻' => '輻', '行' => '行', '降' => '降', '見' => '見', '廓' => '廓', '兀' => '兀', '嗀' => '嗀', '塚' => '塚', '晴' => '晴', '凞' => '凞', '猪' => '猪', '益' => '益', '礼' => '礼', '神' => '神', '祥' => '祥', '福' => '福', '靖' => '靖', '精' => '精', '羽' => '羽', '蘒' => '蘒', '諸' => '諸', '逸' => '逸', '都' => '都', '飯' => '飯', '飼' => '飼', '館' => '館', '鶴' => '鶴', '郞' => '郞', '隷' => '隷', '侮' => '侮', '僧' => '僧', '免' => '免', '勉' => '勉', '勤' => '勤', '卑' => '卑', '喝' => '喝', '嘆' => '嘆', '器' => '器', '塀' => '塀', '墨' => '墨', '層' => '層', '屮' => '屮', '悔' => '悔', '慨' => '慨', '憎' => '憎', '懲' => '懲', '敏' => '敏', '既' => '既', '暑' => '暑', '梅' => '梅', '海' => '海', '渚' => '渚', '漢' => '漢', '煮' => '煮', '爫' => '爫', '琢' => '琢', '碑' => '碑', '社' => '社', '祉' => '祉', '祈' => '祈', '祐' => '祐', '祖' => '祖', '祝' => '祝', '禍' => '禍', '禎' => '禎', '穀' => '穀', '突' => '突', '節' => '節', '練' => '練', '縉' => '縉', '繁' => '繁', '署' => '署', '者' => '者', '臭' => '臭', '艹' => '艹', '艹' => '艹', '著' => '著', '褐' => '褐', '視' => '視', '謁' => '謁', '謹' => '謹', '賓' => '賓', '贈' => '贈', '辶' => '辶', '逸' => '逸', '難' => '難', '響' => '響', '頻' => '頻', '恵' => '恵', '𤋮' => '𤋮', '舘' => '舘', '並' => '並', '况' => '况', '全' => '全', '侀' => '侀', '充' => '充', '冀' => '冀', '勇' => '勇', '勺' => '勺', '喝' => '喝', '啕' => '啕', '喙' => '喙', '嗢' => '嗢', '塚' => '塚', '墳' => '墳', '奄' => '奄', '奔' => '奔', '婢' => '婢', '嬨' => '嬨', '廒' => '廒', '廙' => '廙', '彩' => '彩', '徭' => '徭', '惘' => '惘', '慎' => '慎', '愈' => '愈', '憎' => '憎', '慠' => '慠', '懲' => '懲', '戴' => '戴', '揄' => '揄', '搜' => '搜', '摒' => '摒', '敖' => '敖', '晴' => '晴', '朗' => '朗', '望' => '望', '杖' => '杖', '歹' => '歹', '殺' => '殺', '流' => '流', '滛' => '滛', '滋' => '滋', '漢' => '漢', '瀞' => '瀞', '煮' => '煮', '瞧' => '瞧', '爵' => '爵', '犯' => '犯', '猪' => '猪', '瑱' => '瑱', '甆' => '甆', '画' => '画', '瘝' => '瘝', '瘟' => '瘟', '益' => '益', '盛' => '盛', '直' => '直', '睊' => '睊', '着' => '着', '磌' => '磌', '窱' => '窱', '節' => '節', '类' => '类', '絛' => '絛', '練' => '練', '缾' => '缾', '者' => '者', '荒' => '荒', '華' => '華', '蝹' => '蝹', '襁' => '襁', '覆' => '覆', '視' => '視', '調' => '調', '諸' => '諸', '請' => '請', '謁' => '謁', '諾' => '諾', '諭' => '諭', '謹' => '謹', '變' => '變', '贈' => '贈', '輸' => '輸', '遲' => '遲', '醙' => '醙', '鉶' => '鉶', '陼' => '陼', '難' => '難', '靖' => '靖', '韛' => '韛', '響' => '響', '頋' => '頋', '頻' => '頻', '鬒' => '鬒', '龜' => '龜', '𢡊' => '𢡊', '𢡄' => '𢡄', '𣏕' => '𣏕', '㮝' => '㮝', '䀘' => '䀘', '䀹' => '䀹', '𥉉' => '𥉉', '𥳐' => '𥳐', '𧻓' => '𧻓', '齃' => '齃', '龎' => '龎', 'יִ' => 'יִ', 'ײַ' => 'ײַ', 'שׁ' => 'שׁ', 'שׂ' => 'שׂ', 'שּׁ' => 'שּׁ', 'שּׂ' => 'שּׂ', 'אַ' => 'אַ', 'אָ' => 'אָ', 'אּ' => 'אּ', 'בּ' => 'בּ', 'גּ' => 'גּ', 'דּ' => 'דּ', 'הּ' => 'הּ', 'וּ' => 'וּ', 'זּ' => 'זּ', 'טּ' => 'טּ', 'יּ' => 'יּ', 'ךּ' => 'ךּ', 'כּ' => 'כּ', 'לּ' => 'לּ', 'מּ' => 'מּ', 'נּ' => 'נּ', 'סּ' => 'סּ', 'ףּ' => 'ףּ', 'פּ' => 'פּ', 'צּ' => 'צּ', 'קּ' => 'קּ', 'רּ' => 'רּ', 'שּ' => 'שּ', 'תּ' => 'תּ', 'וֹ' => 'וֹ', 'בֿ' => 'בֿ', 'כֿ' => 'כֿ', 'פֿ' => 'פֿ', '𑂚' => '𑂚', '𑂜' => '𑂜', '𑂫' => '𑂫', '𑄮' => '𑄮', '𑄯' => '𑄯', '𑍋' => '𑍋', '𑍌' => '𑍌', '𑒻' => '𑒻', '𑒼' => '𑒼', '𑒾' => '𑒾', '𑖺' => '𑖺', '𑖻' => '𑖻', '𑤸' => '𑤸', '𝅗𝅥' => '𝅗𝅥', '𝅘𝅥' => '𝅘𝅥', '𝅘𝅥𝅮' => '𝅘𝅥𝅮', '𝅘𝅥𝅯' => '𝅘𝅥𝅯', '𝅘𝅥𝅰' => '𝅘𝅥𝅰', '𝅘𝅥𝅱' => '𝅘𝅥𝅱', '𝅘𝅥𝅲' => '𝅘𝅥𝅲', '𝆹𝅥' => '𝆹𝅥', '𝆺𝅥' => '𝆺𝅥', '𝆹𝅥𝅮' => '𝆹𝅥𝅮', '𝆺𝅥𝅮' => '𝆺𝅥𝅮', '𝆹𝅥𝅯' => '𝆹𝅥𝅯', '𝆺𝅥𝅯' => '𝆺𝅥𝅯', '丽' => '丽', '丸' => '丸', '乁' => '乁', '𠄢' => '𠄢', '你' => '你', '侮' => '侮', '侻' => '侻', '倂' => '倂', '偺' => '偺', '備' => '備', '僧' => '僧', '像' => '像', '㒞' => '㒞', '𠘺' => '𠘺', '免' => '免', '兔' => '兔', '兤' => '兤', '具' => '具', '𠔜' => '𠔜', '㒹' => '㒹', '內' => '內', '再' => '再', '𠕋' => '𠕋', '冗' => '冗', '冤' => '冤', '仌' => '仌', '冬' => '冬', '况' => '况', '𩇟' => '𩇟', '凵' => '凵', '刃' => '刃', '㓟' => '㓟', '刻' => '刻', '剆' => '剆', '割' => '割', '剷' => '剷', '㔕' => '㔕', '勇' => '勇', '勉' => '勉', '勤' => '勤', '勺' => '勺', '包' => '包', '匆' => '匆', '北' => '北', '卉' => '卉', '卑' => '卑', '博' => '博', '即' => '即', '卽' => '卽', '卿' => '卿', '卿' => '卿', '卿' => '卿', '𠨬' => '𠨬', '灰' => '灰', '及' => '及', '叟' => '叟', '𠭣' => '𠭣', '叫' => '叫', '叱' => '叱', '吆' => '吆', '咞' => '咞', '吸' => '吸', '呈' => '呈', '周' => '周', '咢' => '咢', '哶' => '哶', '唐' => '唐', '啓' => '啓', '啣' => '啣', '善' => '善', '善' => '善', '喙' => '喙', '喫' => '喫', '喳' => '喳', '嗂' => '嗂', '圖' => '圖', '嘆' => '嘆', '圗' => '圗', '噑' => '噑', '噴' => '噴', '切' => '切', '壮' => '壮', '城' => '城', '埴' => '埴', '堍' => '堍', '型' => '型', '堲' => '堲', '報' => '報', '墬' => '墬', '𡓤' => '𡓤', '売' => '売', '壷' => '壷', '夆' => '夆', '多' => '多', '夢' => '夢', '奢' => '奢', '𡚨' => '𡚨', '𡛪' => '𡛪', '姬' => '姬', '娛' => '娛', '娧' => '娧', '姘' => '姘', '婦' => '婦', '㛮' => '㛮', '㛼' => '㛼', '嬈' => '嬈', '嬾' => '嬾', '嬾' => '嬾', '𡧈' => '𡧈', '寃' => '寃', '寘' => '寘', '寧' => '寧', '寳' => '寳', '𡬘' => '𡬘', '寿' => '寿', '将' => '将', '当' => '当', '尢' => '尢', '㞁' => '㞁', '屠' => '屠', '屮' => '屮', '峀' => '峀', '岍' => '岍', '𡷤' => '𡷤', '嵃' => '嵃', '𡷦' => '𡷦', '嵮' => '嵮', '嵫' => '嵫', '嵼' => '嵼', '巡' => '巡', '巢' => '巢', '㠯' => '㠯', '巽' => '巽', '帨' => '帨', '帽' => '帽', '幩' => '幩', '㡢' => '㡢', '𢆃' => '𢆃', '㡼' => '㡼', '庰' => '庰', '庳' => '庳', '庶' => '庶', '廊' => '廊', '𪎒' => '𪎒', '廾' => '廾', '𢌱' => '𢌱', '𢌱' => '𢌱', '舁' => '舁', '弢' => '弢', '弢' => '弢', '㣇' => '㣇', '𣊸' => '𣊸', '𦇚' => '𦇚', '形' => '形', '彫' => '彫', '㣣' => '㣣', '徚' => '徚', '忍' => '忍', '志' => '志', '忹' => '忹', '悁' => '悁', '㤺' => '㤺', '㤜' => '㤜', '悔' => '悔', '𢛔' => '𢛔', '惇' => '惇', '慈' => '慈', '慌' => '慌', '慎' => '慎', '慌' => '慌', '慺' => '慺', '憎' => '憎', '憲' => '憲', '憤' => '憤', '憯' => '憯', '懞' => '懞', '懲' => '懲', '懶' => '懶', '成' => '成', '戛' => '戛', '扝' => '扝', '抱' => '抱', '拔' => '拔', '捐' => '捐', '𢬌' => '𢬌', '挽' => '挽', '拼' => '拼', '捨' => '捨', '掃' => '掃', '揤' => '揤', '𢯱' => '𢯱', '搢' => '搢', '揅' => '揅', '掩' => '掩', '㨮' => '㨮', '摩' => '摩', '摾' => '摾', '撝' => '撝', '摷' => '摷', '㩬' => '㩬', '敏' => '敏', '敬' => '敬', '𣀊' => '𣀊', '旣' => '旣', '書' => '書', '晉' => '晉', '㬙' => '㬙', '暑' => '暑', '㬈' => '㬈', '㫤' => '㫤', '冒' => '冒', '冕' => '冕', '最' => '最', '暜' => '暜', '肭' => '肭', '䏙' => '䏙', '朗' => '朗', '望' => '望', '朡' => '朡', '杞' => '杞', '杓' => '杓', '𣏃' => '𣏃', '㭉' => '㭉', '柺' => '柺', '枅' => '枅', '桒' => '桒', '梅' => '梅', '𣑭' => '𣑭', '梎' => '梎', '栟' => '栟', '椔' => '椔', '㮝' => '㮝', '楂' => '楂', '榣' => '榣', '槪' => '槪', '檨' => '檨', '𣚣' => '𣚣', '櫛' => '櫛', '㰘' => '㰘', '次' => '次', '𣢧' => '𣢧', '歔' => '歔', '㱎' => '㱎', '歲' => '歲', '殟' => '殟', '殺' => '殺', '殻' => '殻', '𣪍' => '𣪍', '𡴋' => '𡴋', '𣫺' => '𣫺', '汎' => '汎', '𣲼' => '𣲼', '沿' => '沿', '泍' => '泍', '汧' => '汧', '洖' => '洖', '派' => '派', '海' => '海', '流' => '流', '浩' => '浩', '浸' => '浸', '涅' => '涅', '𣴞' => '𣴞', '洴' => '洴', '港' => '港', '湮' => '湮', '㴳' => '㴳', '滋' => '滋', '滇' => '滇', '𣻑' => '𣻑', '淹' => '淹', '潮' => '潮', '𣽞' => '𣽞', '𣾎' => '𣾎', '濆' => '濆', '瀹' => '瀹', '瀞' => '瀞', '瀛' => '瀛', '㶖' => '㶖', '灊' => '灊', '災' => '災', '灷' => '灷', '炭' => '炭', '𠔥' => '𠔥', '煅' => '煅', '𤉣' => '𤉣', '熜' => '熜', '𤎫' => '𤎫', '爨' => '爨', '爵' => '爵', '牐' => '牐', '𤘈' => '𤘈', '犀' => '犀', '犕' => '犕', '𤜵' => '𤜵', '𤠔' => '𤠔', '獺' => '獺', '王' => '王', '㺬' => '㺬', '玥' => '玥', '㺸' => '㺸', '㺸' => '㺸', '瑇' => '瑇', '瑜' => '瑜', '瑱' => '瑱', '璅' => '璅', '瓊' => '瓊', '㼛' => '㼛', '甤' => '甤', '𤰶' => '𤰶', '甾' => '甾', '𤲒' => '𤲒', '異' => '異', '𢆟' => '𢆟', '瘐' => '瘐', '𤾡' => '𤾡', '𤾸' => '𤾸', '𥁄' => '𥁄', '㿼' => '㿼', '䀈' => '䀈', '直' => '直', '𥃳' => '𥃳', '𥃲' => '𥃲', '𥄙' => '𥄙', '𥄳' => '𥄳', '眞' => '眞', '真' => '真', '真' => '真', '睊' => '睊', '䀹' => '䀹', '瞋' => '瞋', '䁆' => '䁆', '䂖' => '䂖', '𥐝' => '𥐝', '硎' => '硎', '碌' => '碌', '磌' => '磌', '䃣' => '䃣', '𥘦' => '𥘦', '祖' => '祖', '𥚚' => '𥚚', '𥛅' => '𥛅', '福' => '福', '秫' => '秫', '䄯' => '䄯', '穀' => '穀', '穊' => '穊', '穏' => '穏', '𥥼' => '𥥼', '𥪧' => '𥪧', '𥪧' => '𥪧', '竮' => '竮', '䈂' => '䈂', '𥮫' => '𥮫', '篆' => '篆', '築' => '築', '䈧' => '䈧', '𥲀' => '𥲀', '糒' => '糒', '䊠' => '䊠', '糨' => '糨', '糣' => '糣', '紀' => '紀', '𥾆' => '𥾆', '絣' => '絣', '䌁' => '䌁', '緇' => '緇', '縂' => '縂', '繅' => '繅', '䌴' => '䌴', '𦈨' => '𦈨', '𦉇' => '𦉇', '䍙' => '䍙', '𦋙' => '𦋙', '罺' => '罺', '𦌾' => '𦌾', '羕' => '羕', '翺' => '翺', '者' => '者', '𦓚' => '𦓚', '𦔣' => '𦔣', '聠' => '聠', '𦖨' => '𦖨', '聰' => '聰', '𣍟' => '𣍟', '䏕' => '䏕', '育' => '育', '脃' => '脃', '䐋' => '䐋', '脾' => '脾', '媵' => '媵', '𦞧' => '𦞧', '𦞵' => '𦞵', '𣎓' => '𣎓', '𣎜' => '𣎜', '舁' => '舁', '舄' => '舄', '辞' => '辞', '䑫' => '䑫', '芑' => '芑', '芋' => '芋', '芝' => '芝', '劳' => '劳', '花' => '花', '芳' => '芳', '芽' => '芽', '苦' => '苦', '𦬼' => '𦬼', '若' => '若', '茝' => '茝', '荣' => '荣', '莭' => '莭', '茣' => '茣', '莽' => '莽', '菧' => '菧', '著' => '著', '荓' => '荓', '菊' => '菊', '菌' => '菌', '菜' => '菜', '𦰶' => '𦰶', '𦵫' => '𦵫', '𦳕' => '𦳕', '䔫' => '䔫', '蓱' => '蓱', '蓳' => '蓳', '蔖' => '蔖', '𧏊' => '𧏊', '蕤' => '蕤', '𦼬' => '𦼬', '䕝' => '䕝', '䕡' => '䕡', '𦾱' => '𦾱', '𧃒' => '𧃒', '䕫' => '䕫', '虐' => '虐', '虜' => '虜', '虧' => '虧', '虩' => '虩', '蚩' => '蚩', '蚈' => '蚈', '蜎' => '蜎', '蛢' => '蛢', '蝹' => '蝹', '蜨' => '蜨', '蝫' => '蝫', '螆' => '螆', '䗗' => '䗗', '蟡' => '蟡', '蠁' => '蠁', '䗹' => '䗹', '衠' => '衠', '衣' => '衣', '𧙧' => '𧙧', '裗' => '裗', '裞' => '裞', '䘵' => '䘵', '裺' => '裺', '㒻' => '㒻', '𧢮' => '𧢮', '𧥦' => '𧥦', '䚾' => '䚾', '䛇' => '䛇', '誠' => '誠', '諭' => '諭', '變' => '變', '豕' => '豕', '𧲨' => '𧲨', '貫' => '貫', '賁' => '賁', '贛' => '贛', '起' => '起', '𧼯' => '𧼯', '𠠄' => '𠠄', '跋' => '跋', '趼' => '趼', '跰' => '跰', '𠣞' => '𠣞', '軔' => '軔', '輸' => '輸', '𨗒' => '𨗒', '𨗭' => '𨗭', '邔' => '邔', '郱' => '郱', '鄑' => '鄑', '𨜮' => '𨜮', '鄛' => '鄛', '鈸' => '鈸', '鋗' => '鋗', '鋘' => '鋘', '鉼' => '鉼', '鏹' => '鏹', '鐕' => '鐕', '𨯺' => '𨯺', '開' => '開', '䦕' => '䦕', '閷' => '閷', '𨵷' => '𨵷', '䧦' => '䧦', '雃' => '雃', '嶲' => '嶲', '霣' => '霣', '𩅅' => '𩅅', '𩈚' => '𩈚', '䩮' => '䩮', '䩶' => '䩶', '韠' => '韠', '𩐊' => '𩐊', '䪲' => '䪲', '𩒖' => '𩒖', '頋' => '頋', '頋' => '頋', '頩' => '頩', '𩖶' => '𩖶', '飢' => '飢', '䬳' => '䬳', '餩' => '餩', '馧' => '馧', '駂' => '駂', '駾' => '駾', '䯎' => '䯎', '𩬰' => '𩬰', '鬒' => '鬒', '鱀' => '鱀', '鳽' => '鳽', '䳎' => '䳎', '䳭' => '䳭', '鵧' => '鵧', '𪃎' => '𪃎', '䳸' => '䳸', '𪄅' => '𪄅', '𪈎' => '𪈎', '𪊑' => '𪊑', '麻' => '麻', '䵖' => '䵖', '黹' => '黹', '黾' => '黾', '鼅' => '鼅', '鼏' => '鼏', '鼖' => '鼖', '鼻' => '鼻', '𪘀' => '𪘀');
<?php

namespace _HumbugBox1cb33d1f20f1;

return array('̀' => 230, '́' => 230, '̂' => 230, '̃' => 230, '̄' => 230, '̅' => 230, '̆' => 230, '̇' => 230, '̈' => 230, '̉' => 230, '̊' => 230, '̋' => 230, '̌' => 230, '̍' => 230, '̎' => 230, '̏' => 230, '̐' => 230, '̑' => 230, '̒' => 230, '̓' => 230, '̔' => 230, '̕' => 232, '̖' => 220, '̗' => 220, '̘' => 220, '̙' => 220, '̚' => 232, '̛' => 216, '̜' => 220, '̝' => 220, '̞' => 220, '̟' => 220, '̠' => 220, '̡' => 202, '̢' => 202, '̣' => 220, '̤' => 220, '̥' => 220, '̦' => 220, '̧' => 202, '̨' => 202, '̩' => 220, '̪' => 220, '̫' => 220, '̬' => 220, '̭' => 220, '̮' => 220, '̯' => 220, '̰' => 220, '̱' => 220, '̲' => 220, '̳' => 220, '̴' => 1, '̵' => 1, '̶' => 1, '̷' => 1, '̸' => 1, '̹' => 220, '̺' => 220, '̻' => 220, '̼' => 220, '̽' => 230, '̾' => 230, '̿' => 230, '̀' => 230, '́' => 230, '͂' => 230, '̓' => 230, '̈́' => 230, 'ͅ' => 240, '͆' => 230, '͇' => 220, '͈' => 220, '͉' => 220, '͊' => 230, '͋' => 230, '͌' => 230, '͍' => 220, '͎' => 220, '͐' => 230, '͑' => 230, '͒' => 230, '͓' => 220, '͔' => 220, '͕' => 220, '͖' => 220, '͗' => 230, '͘' => 232, '͙' => 220, '͚' => 220, '͛' => 230, '͜' => 233, '͝' => 234, '͞' => 234, '͟' => 233, '͠' => 234, '͡' => 234, '͢' => 233, 'ͣ' => 230, 'ͤ' => 230, 'ͥ' => 230, 'ͦ' => 230, 'ͧ' => 230, 'ͨ' => 230, 'ͩ' => 230, 'ͪ' => 230, 'ͫ' => 230, 'ͬ' => 230, 'ͭ' => 230, 'ͮ' => 230, 'ͯ' => 230, '҃' => 230, '҄' => 230, '҅' => 230, '҆' => 230, '҇' => 230, '֑' => 220, '֒' => 230, '֓' => 230, '֔' => 230, '֕' => 230, '֖' => 220, '֗' => 230, '֘' => 230, '֙' => 230, '֚' => 222, '֛' => 220, '֜' => 230, '֝' => 230, '֞' => 230, '֟' => 230, '֠' => 230, '֡' => 230, '֢' => 220, '֣' => 220, '֤' => 220, '֥' => 220, '֦' => 220, '֧' => 220, '֨' => 230, '֩' => 230, '֪' => 220, '֫' => 230, '֬' => 230, '֭' => 222, '֮' => 228, '֯' => 230, 'ְ' => 10, 'ֱ' => 11, 'ֲ' => 12, 'ֳ' => 13, 'ִ' => 14, 'ֵ' => 15, 'ֶ' => 16, 'ַ' => 17, 'ָ' => 18, 'ֹ' => 19, 'ֺ' => 19, 'ֻ' => 20, 'ּ' => 21, 'ֽ' => 22, 'ֿ' => 23, 'ׁ' => 24, 'ׂ' => 25, 'ׄ' => 230, 'ׅ' => 220, 'ׇ' => 18, 'ؐ' => 230, 'ؑ' => 230, 'ؒ' => 230, 'ؓ' => 230, 'ؔ' => 230, 'ؕ' => 230, 'ؖ' => 230, 'ؗ' => 230, 'ؘ' => 30, 'ؙ' => 31, 'ؚ' => 32, 'ً' => 27, 'ٌ' => 28, 'ٍ' => 29, 'َ' => 30, 'ُ' => 31, 'ِ' => 32, 'ّ' => 33, 'ْ' => 34, 'ٓ' => 230, 'ٔ' => 230, 'ٕ' => 220, 'ٖ' => 220, 'ٗ' => 230, '٘' => 230, 'ٙ' => 230, 'ٚ' => 230, 'ٛ' => 230, 'ٜ' => 220, 'ٝ' => 230, 'ٞ' => 230, 'ٟ' => 220, 'ٰ' => 35, 'ۖ' => 230, 'ۗ' => 230, 'ۘ' => 230, 'ۙ' => 230, 'ۚ' => 230, 'ۛ' => 230, 'ۜ' => 230, '۟' => 230, '۠' => 230, 'ۡ' => 230, 'ۢ' => 230, 'ۣ' => 220, 'ۤ' => 230, 'ۧ' => 230, 'ۨ' => 230, '۪' => 220, '۫' => 230, '۬' => 230, 'ۭ' => 220, 'ܑ' => 36, 'ܰ' => 230, 'ܱ' => 220, 'ܲ' => 230, 'ܳ' => 230, 'ܴ' => 220, 'ܵ' => 230, 'ܶ' => 230, 'ܷ' => 220, 'ܸ' => 220, 'ܹ' => 220, 'ܺ' => 230, 'ܻ' => 220, 'ܼ' => 220, 'ܽ' => 230, 'ܾ' => 220, 'ܿ' => 230, '݀' => 230, '݁' => 230, '݂' => 220, '݃' => 230, '݄' => 220, '݅' => 230, '݆' => 220, '݇' => 230, '݈' => 220, '݉' => 230, '݊' => 230, '߫' => 230, '߬' => 230, '߭' => 230, '߮' => 230, '߯' => 230, '߰' => 230, '߱' => 230, '߲' => 220, '߳' => 230, '߽' => 220, 'ࠖ' => 230, 'ࠗ' => 230, '࠘' => 230, '࠙' => 230, 'ࠛ' => 230, 'ࠜ' => 230, 'ࠝ' => 230, 'ࠞ' => 230, 'ࠟ' => 230, 'ࠠ' => 230, 'ࠡ' => 230, 'ࠢ' => 230, 'ࠣ' => 230, 'ࠥ' => 230, 'ࠦ' => 230, 'ࠧ' => 230, 'ࠩ' => 230, 'ࠪ' => 230, 'ࠫ' => 230, 'ࠬ' => 230, '࠭' => 230, '࡙' => 220, '࡚' => 220, '࡛' => 220, '࣓' => 220, 'ࣔ' => 230, 'ࣕ' => 230, 'ࣖ' => 230, 'ࣗ' => 230, 'ࣘ' => 230, 'ࣙ' => 230, 'ࣚ' => 230, 'ࣛ' => 230, 'ࣜ' => 230, 'ࣝ' => 230, 'ࣞ' => 230, 'ࣟ' => 230, '࣠' => 230, '࣡' => 230, 'ࣣ' => 220, 'ࣤ' => 230, 'ࣥ' => 230, 'ࣦ' => 220, 'ࣧ' => 230, 'ࣨ' => 230, 'ࣩ' => 220, '࣪' => 230, '࣫' => 230, '࣬' => 230, '࣭' => 220, '࣮' => 220, '࣯' => 220, 'ࣰ' => 27, 'ࣱ' => 28, 'ࣲ' => 29, 'ࣳ' => 230, 'ࣴ' => 230, 'ࣵ' => 230, 'ࣶ' => 220, 'ࣷ' => 230, 'ࣸ' => 230, 'ࣹ' => 220, 'ࣺ' => 220, 'ࣻ' => 230, 'ࣼ' => 230, 'ࣽ' => 230, 'ࣾ' => 230, 'ࣿ' => 230, '़' => 7, '्' => 9, '॑' => 230, '॒' => 220, '॓' => 230, '॔' => 230, '়' => 7, '্' => 9, '৾' => 230, '਼' => 7, '੍' => 9, '઼' => 7, '્' => 9, '଼' => 7, '୍' => 9, '்' => 9, '్' => 9, 'ౕ' => 84, 'ౖ' => 91, '಼' => 7, '್' => 9, '഻' => 9, '഼' => 9, '്' => 9, '්' => 9, 'ุ' => 103, 'ู' => 103, 'ฺ' => 9, '่' => 107, '้' => 107, '๊' => 107, '๋' => 107, 'ຸ' => 118, 'ູ' => 118, '຺' => 9, '່' => 122, '້' => 122, '໊' => 122, '໋' => 122, '༘' => 220, '༙' => 220, '༵' => 220, '༷' => 220, '༹' => 216, 'ཱ' => 129, 'ི' => 130, 'ུ' => 132, 'ེ' => 130, 'ཻ' => 130, 'ོ' => 130, 'ཽ' => 130, 'ྀ' => 130, 'ྂ' => 230, 'ྃ' => 230, '྄' => 9, '྆' => 230, '྇' => 230, '࿆' => 220, '့' => 7, '္' => 9, '်' => 9, 'ႍ' => 220, '፝' => 230, '፞' => 230, '፟' => 230, '᜔' => 9, '᜴' => 9, '្' => 9, '៝' => 230, 'ᢩ' => 228, '᤹' => 222, '᤺' => 230, '᤻' => 220, 'ᨗ' => 230, 'ᨘ' => 220, '᩠' => 9, '᩵' => 230, '᩶' => 230, '᩷' => 230, '᩸' => 230, '᩹' => 230, '᩺' => 230, '᩻' => 230, '᩼' => 230, '᩿' => 220, '᪰' => 230, '᪱' => 230, '᪲' => 230, '᪳' => 230, '᪴' => 230, '᪵' => 220, '᪶' => 220, '᪷' => 220, '᪸' => 220, '᪹' => 220, '᪺' => 220, '᪻' => 230, '᪼' => 230, '᪽' => 220, 'ᪿ' => 220, 'ᫀ' => 220, '᬴' => 7, '᭄' => 9, '᭫' => 230, '᭬' => 220, '᭭' => 230, '᭮' => 230, '᭯' => 230, '᭰' => 230, '᭱' => 230, '᭲' => 230, '᭳' => 230, '᮪' => 9, '᮫' => 9, '᯦' => 7, '᯲' => 9, '᯳' => 9, '᰷' => 7, '᳐' => 230, '᳑' => 230, '᳒' => 230, '᳔' => 1, '᳕' => 220, '᳖' => 220, '᳗' => 220, '᳘' => 220, '᳙' => 220, '᳚' => 230, '᳛' => 230, '᳜' => 220, '᳝' => 220, '᳞' => 220, '᳟' => 220, '᳠' => 230, '᳢' => 1, '᳣' => 1, '᳤' => 1, '᳥' => 1, '᳦' => 1, '᳧' => 1, '᳨' => 1, '᳭' => 220, '᳴' => 230, '᳸' => 230, '᳹' => 230, '᷀' => 230, '᷁' => 230, '᷂' => 220, '᷃' => 230, '᷄' => 230, '᷅' => 230, '᷆' => 230, '᷇' => 230, '᷈' => 230, '᷉' => 230, '᷊' => 220, '᷋' => 230, '᷌' => 230, '᷍' => 234, '᷎' => 214, '᷏' => 220, '᷐' => 202, '᷑' => 230, '᷒' => 230, 'ᷓ' => 230, 'ᷔ' => 230, 'ᷕ' => 230, 'ᷖ' => 230, 'ᷗ' => 230, 'ᷘ' => 230, 'ᷙ' => 230, 'ᷚ' => 230, 'ᷛ' => 230, 'ᷜ' => 230, 'ᷝ' => 230, 'ᷞ' => 230, 'ᷟ' => 230, 'ᷠ' => 230, 'ᷡ' => 230, 'ᷢ' => 230, 'ᷣ' => 230, 'ᷤ' => 230, 'ᷥ' => 230, 'ᷦ' => 230, 'ᷧ' => 230, 'ᷨ' => 230, 'ᷩ' => 230, 'ᷪ' => 230, 'ᷫ' => 230, 'ᷬ' => 230, 'ᷭ' => 230, 'ᷮ' => 230, 'ᷯ' => 230, 'ᷰ' => 230, 'ᷱ' => 230, 'ᷲ' => 230, 'ᷳ' => 230, 'ᷴ' => 230, '᷵' => 230, '᷶' => 232, '᷷' => 228, '᷸' => 228, '᷹' => 220, '᷻' => 230, '᷼' => 233, '᷽' => 220, '᷾' => 230, '᷿' => 220, '⃐' => 230, '⃑' => 230, '⃒' => 1, '⃓' => 1, '⃔' => 230, '⃕' => 230, '⃖' => 230, '⃗' => 230, '⃘' => 1, '⃙' => 1, '⃚' => 1, '⃛' => 230, '⃜' => 230, '⃡' => 230, '⃥' => 1, '⃦' => 1, '⃧' => 230, '⃨' => 220, '⃩' => 230, '⃪' => 1, '⃫' => 1, '⃬' => 220, '⃭' => 220, '⃮' => 220, '⃯' => 220, '⃰' => 230, '⳯' => 230, '⳰' => 230, '⳱' => 230, '⵿' => 9, 'ⷠ' => 230, 'ⷡ' => 230, 'ⷢ' => 230, 'ⷣ' => 230, 'ⷤ' => 230, 'ⷥ' => 230, 'ⷦ' => 230, 'ⷧ' => 230, 'ⷨ' => 230, 'ⷩ' => 230, 'ⷪ' => 230, 'ⷫ' => 230, 'ⷬ' => 230, 'ⷭ' => 230, 'ⷮ' => 230, 'ⷯ' => 230, 'ⷰ' => 230, 'ⷱ' => 230, 'ⷲ' => 230, 'ⷳ' => 230, 'ⷴ' => 230, 'ⷵ' => 230, 'ⷶ' => 230, 'ⷷ' => 230, 'ⷸ' => 230, 'ⷹ' => 230, 'ⷺ' => 230, 'ⷻ' => 230, 'ⷼ' => 230, 'ⷽ' => 230, 'ⷾ' => 230, 'ⷿ' => 230, '〪' => 218, '〫' => 228, '〬' => 232, '〭' => 222, '〮' => 224, '〯' => 224, '゙' => 8, '゚' => 8, '꙯' => 230, 'ꙴ' => 230, 'ꙵ' => 230, 'ꙶ' => 230, 'ꙷ' => 230, 'ꙸ' => 230, 'ꙹ' => 230, 'ꙺ' => 230, 'ꙻ' => 230, '꙼' => 230, '꙽' => 230, 'ꚞ' => 230, 'ꚟ' => 230, '꛰' => 230, '꛱' => 230, '꠆' => 9, '꠬' => 9, '꣄' => 9, '꣠' => 230, '꣡' => 230, '꣢' => 230, '꣣' => 230, '꣤' => 230, '꣥' => 230, '꣦' => 230, '꣧' => 230, '꣨' => 230, '꣩' => 230, '꣪' => 230, '꣫' => 230, '꣬' => 230, '꣭' => 230, '꣮' => 230, '꣯' => 230, '꣰' => 230, '꣱' => 230, '꤫' => 220, '꤬' => 220, '꤭' => 220, '꥓' => 9, '꦳' => 7, '꧀' => 9, 'ꪰ' => 230, 'ꪲ' => 230, 'ꪳ' => 230, 'ꪴ' => 220, 'ꪷ' => 230, 'ꪸ' => 230, 'ꪾ' => 230, '꪿' => 230, '꫁' => 230, '꫶' => 9, '꯭' => 9, 'ﬞ' => 26, '︠' => 230, '︡' => 230, '︢' => 230, '︣' => 230, '︤' => 230, '︥' => 230, '︦' => 230, '︧' => 220, '︨' => 220, '︩' => 220, '︪' => 220, '︫' => 220, '︬' => 220, '︭' => 220, '︮' => 230, '︯' => 230, '𐇽' => 220, '𐋠' => 220, '𐍶' => 230, '𐍷' => 230, '𐍸' => 230, '𐍹' => 230, '𐍺' => 230, '𐨍' => 220, '𐨏' => 230, '𐨸' => 230, '𐨹' => 1, '𐨺' => 220, '𐨿' => 9, '𐫥' => 230, '𐫦' => 220, '𐴤' => 230, '𐴥' => 230, '𐴦' => 230, '𐴧' => 230, '𐺫' => 230, '𐺬' => 230, '𐽆' => 220, '𐽇' => 220, '𐽈' => 230, '𐽉' => 230, '𐽊' => 230, '𐽋' => 220, '𐽌' => 230, '𐽍' => 220, '𐽎' => 220, '𐽏' => 220, '𐽐' => 220, '𑁆' => 9, '𑁿' => 9, '𑂹' => 9, '𑂺' => 7, '𑄀' => 230, '𑄁' => 230, '𑄂' => 230, '𑄳' => 9, '𑄴' => 9, '𑅳' => 7, '𑇀' => 9, '𑇊' => 7, '𑈵' => 9, '𑈶' => 7, '𑋩' => 7, '𑋪' => 9, '𑌻' => 7, '𑌼' => 7, '𑍍' => 9, '𑍦' => 230, '𑍧' => 230, '𑍨' => 230, '𑍩' => 230, '𑍪' => 230, '𑍫' => 230, '𑍬' => 230, '𑍰' => 230, '𑍱' => 230, '𑍲' => 230, '𑍳' => 230, '𑍴' => 230, '𑑂' => 9, '𑑆' => 7, '𑑞' => 230, '𑓂' => 9, '𑓃' => 7, '𑖿' => 9, '𑗀' => 7, '𑘿' => 9, '𑚶' => 9, '𑚷' => 7, '𑜫' => 9, '𑠹' => 9, '𑠺' => 7, '𑤽' => 9, '𑤾' => 9, '𑥃' => 7, '𑧠' => 9, '𑨴' => 9, '𑩇' => 9, '𑪙' => 9, '𑰿' => 9, '𑵂' => 7, '𑵄' => 9, '𑵅' => 9, '𑶗' => 9, '𖫰' => 1, '𖫱' => 1, '𖫲' => 1, '𖫳' => 1, '𖫴' => 1, '𖬰' => 230, '𖬱' => 230, '𖬲' => 230, '𖬳' => 230, '𖬴' => 230, '𖬵' => 230, '𖬶' => 230, '𖿰' => 6, '𖿱' => 6, '𛲞' => 1, '𝅥' => 216, '𝅦' => 216, '𝅧' => 1, '𝅨' => 1, '𝅩' => 1, '𝅭' => 226, '𝅮' => 216, '𝅯' => 216, '𝅰' => 216, '𝅱' => 216, '𝅲' => 216, '𝅻' => 220, '𝅼' => 220, '𝅽' => 220, '𝅾' => 220, '𝅿' => 220, '𝆀' => 220, '𝆁' => 220, '𝆂' => 220, '𝆅' => 230, '𝆆' => 230, '𝆇' => 230, '𝆈' => 230, '𝆉' => 230, '𝆊' => 220, '𝆋' => 220, '𝆪' => 230, '𝆫' => 230, '𝆬' => 230, '𝆭' => 230, '𝉂' => 230, '𝉃' => 230, '𝉄' => 230, '𞀀' => 230, '𞀁' => 230, '𞀂' => 230, '𞀃' => 230, '𞀄' => 230, '𞀅' => 230, '𞀆' => 230, '𞀈' => 230, '𞀉' => 230, '𞀊' => 230, '𞀋' => 230, '𞀌' => 230, '𞀍' => 230, '𞀎' => 230, '𞀏' => 230, '𞀐' => 230, '𞀑' => 230, '𞀒' => 230, '𞀓' => 230, '𞀔' => 230, '𞀕' => 230, '𞀖' => 230, '𞀗' => 230, '𞀘' => 230, '𞀛' => 230, '𞀜' => 230, '𞀝' => 230, '𞀞' => 230, '𞀟' => 230, '𞀠' => 230, '𞀡' => 230, '𞀣' => 230, '𞀤' => 230, '𞀦' => 230, '𞀧' => 230, '𞀨' => 230, '𞀩' => 230, '𞀪' => 230, '𞄰' => 230, '𞄱' => 230, '𞄲' => 230, '𞄳' => 230, '𞄴' => 230, '𞄵' => 230, '𞄶' => 230, '𞋬' => 230, '𞋭' => 230, '𞋮' => 230, '𞋯' => 230, '𞣐' => 220, '𞣑' => 220, '𞣒' => 220, '𞣓' => 220, '𞣔' => 220, '𞣕' => 220, '𞣖' => 220, '𞥄' => 230, '𞥅' => 230, '𞥆' => 230, '𞥇' => 230, '𞥈' => 230, '𞥉' => 230, '𞥊' => 7);
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Intl\Normalizer as p;
if (!\function_exists('normalizer_is_normalized')) {
    function normalizer_is_normalized(?string $string, ?int $form = p\Normalizer::FORM_C) : bool
    {
        return p\Normalizer::isNormalized((string) $string, (int) $form);
    }
}
if (!\function_exists('normalizer_normalize')) {
    function normalizer_normalize(?string $string, ?int $form = p\Normalizer::FORM_C) : string|false
    {
        return p\Normalizer::normalize((string) $string, (int) $form);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
use _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Php73 as p;
if (\PHP_VERSION_ID >= 70300) {
    return;
}
if (!\function_exists('is_countable')) {
    function is_countable($value)
    {
        return \is_array($value) || $value instanceof \Countable || $value instanceof \ResourceBundle || $value instanceof \SimpleXmlElement;
    }
}
if (!\function_exists('hrtime')) {
    require_once __DIR__ . '/Php73.php';
    p\Php73::$startAt = (int) \microtime(\true);
    function hrtime($as_number = \false)
    {
        return p\Php73::hrtime($as_number);
    }
}
if (!\function_exists('array_key_first')) {
    function array_key_first(array $array)
    {
        foreach ($array as $key => $value) {
            return $key;
        }
    }
}
if (!\function_exists('array_key_last')) {
    function array_key_last(array $array)
    {
        return \key(\array_slice($array, -1, 1, \true));
    }
}
Copyright (c) 2018-2019 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1;

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
if (\PHP_VERSION_ID < 70300) {
    class JsonException extends \Exception
    {
    }
}
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Symfony\Polyfill\Php73;

/**
 * @author Gabriel Caruso <carusogabriel34@gmail.com>
 * @author Ion Bazan <ion.bazan@gmail.com>
 *
 * @internal
 */
final class Php73
{
    public static $startAt = 1533462603;
    /**
     * @param bool $asNum
     *
     * @return array|float|int
     */
    public static function hrtime($asNum = \false)
    {
        $ns = \microtime(\false);
        $s = \substr($ns, 11) - self::$startAt;
        $ns = 1000000000.0 * (float) $ns;
        if ($asNum) {
            $ns += $s * 1000000000.0;
            return \PHP_INT_SIZE === 4 ? $ns : (int) $ns;
        }
        return [$s, (int) $ns];
    }
}
<?php

/*
 * This file is part of the webmozart/assert package.
 *
 * (c) Bernhard Schussek <bschussek@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Webmozart\Assert;

use ArrayAccess;
use BadMethodCallException;
use Closure;
use Countable;
use DateTime;
use DateTimeImmutable;
use Exception;
use ResourceBundle;
use SimpleXMLElement;
use Throwable;
use Traversable;
/**
 * Efficient assertions to validate the input/output of your methods.
 *
 * @since  1.0
 *
 * @author Bernhard Schussek <bschussek@gmail.com>
 */
class Assert
{
    use Mixin;
    /**
     * @psalm-pure
     * @psalm-assert string $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function string($value, $message = '')
    {
        if (!\is_string($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a string. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert non-empty-string $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function stringNotEmpty($value, $message = '')
    {
        static::string($value, $message);
        static::notEq($value, '', $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert int $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function integer($value, $message = '')
    {
        if (!\is_int($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an integer. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert numeric $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function integerish($value, $message = '')
    {
        if (!\is_numeric($value) || $value != (int) $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an integerish value. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert positive-int $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function positiveInteger($value, $message = '')
    {
        if (!(\is_int($value) && $value > 0)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a positive integer. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert float $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function float($value, $message = '')
    {
        if (!\is_float($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a float. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert numeric $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function numeric($value, $message = '')
    {
        if (!\is_numeric($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a numeric. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert positive-int|0 $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function natural($value, $message = '')
    {
        if (!\is_int($value) || $value < 0) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a non-negative integer. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert bool $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function boolean($value, $message = '')
    {
        if (!\is_bool($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a boolean. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert scalar $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function scalar($value, $message = '')
    {
        if (!\is_scalar($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a scalar. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert object $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function object($value, $message = '')
    {
        if (!\is_object($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an object. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert resource $value
     *
     * @param mixed       $value
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
     * @param string      $message
     *
     * @throws InvalidArgumentException
     */
    public static function resource($value, $type = null, $message = '')
    {
        if (!\is_resource($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a resource. Got: %s', static::typeToString($value)));
        }
        if ($type && $type !== \get_resource_type($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a resource of type %2$s. Got: %s', static::typeToString($value), $type));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert callable $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isCallable($value, $message = '')
    {
        if (!\is_callable($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a callable. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert array $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isArray($value, $message = '')
    {
        if (!\is_array($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an array. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable $value
     *
     * @deprecated use "isIterable" or "isInstanceOf" instead
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isTraversable($value, $message = '')
    {
        @\trigger_error(\sprintf('The "%s" assertion is deprecated. You should stop using it, as it will soon be removed in 2.0 version. Use "isIterable" or "isInstanceOf" instead.', __METHOD__), \E_USER_DEPRECATED);
        if (!\is_array($value) && !$value instanceof Traversable) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a traversable. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert array|ArrayAccess $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isArrayAccessible($value, $message = '')
    {
        if (!\is_array($value) && !$value instanceof ArrayAccess) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an array accessible. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert countable $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isCountable($value, $message = '')
    {
        if (!\is_array($value) && !$value instanceof Countable && !$value instanceof ResourceBundle && !$value instanceof SimpleXMLElement) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a countable. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isIterable($value, $message = '')
    {
        if (!\is_array($value) && !$value instanceof Traversable) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an iterable. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert ExpectedType $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function isInstanceOf($value, $class, $message = '')
    {
        if (!$value instanceof $class) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of %2$s. Got: %s', static::typeToString($value), $class));
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert !ExpectedType $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function notInstanceOf($value, $class, $message = '')
    {
        if ($value instanceof $class) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance other than %2$s. Got: %s', static::typeToString($value), $class));
        }
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param mixed                $value
     * @param array<object|string> $classes
     * @param string               $message
     *
     * @throws InvalidArgumentException
     */
    public static function isInstanceOfAny($value, array $classes, $message = '')
    {
        foreach ($classes as $class) {
            if ($value instanceof $class) {
                return;
            }
        }
        static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of any of %2$s. Got: %s', static::typeToString($value), \implode(', ', \array_map(array(static::class, 'valueToString'), $classes))));
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert ExpectedType|class-string<ExpectedType> $value
     *
     * @param object|string $value
     * @param string        $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function isAOf($value, $class, $message = '')
    {
        static::string($class, 'Expected class as a string. Got: %s');
        if (!\is_a($value, $class, \is_string($value))) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of this class or to this class among its parents "%2$s". Got: %s', static::valueToString($value), $class));
        }
    }
    /**
     * @psalm-pure
     * @psalm-template UnexpectedType of object
     * @psalm-param class-string<UnexpectedType> $class
     * @psalm-assert !UnexpectedType $value
     * @psalm-assert !class-string<UnexpectedType> $value
     *
     * @param object|string $value
     * @param string        $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function isNotA($value, $class, $message = '')
    {
        static::string($class, 'Expected class as a string. Got: %s');
        if (\is_a($value, $class, \is_string($value))) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of this class or to this class among its parents other than "%2$s". Got: %s', static::valueToString($value), $class));
        }
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param object|string $value
     * @param string[]      $classes
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function isAnyOf($value, array $classes, $message = '')
    {
        foreach ($classes as $class) {
            static::string($class, 'Expected class as a string. Got: %s');
            if (\is_a($value, $class, \is_string($value))) {
                return;
            }
        }
        static::reportInvalidArgument(\sprintf($message ?: 'Expected an instance of any of this classes or any of those classes among their parents "%2$s". Got: %s', static::valueToString($value), \implode(', ', $classes)));
    }
    /**
     * @psalm-pure
     * @psalm-assert empty $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isEmpty($value, $message = '')
    {
        if (!empty($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an empty value. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert !empty $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notEmpty($value, $message = '')
    {
        if (empty($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a non-empty value. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function null($value, $message = '')
    {
        if (null !== $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected null. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert !null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notNull($value, $message = '')
    {
        if (null === $value) {
            static::reportInvalidArgument($message ?: 'Expected a value other than null.');
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert true $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function true($value, $message = '')
    {
        if (\true !== $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be true. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert false $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function false($value, $message = '')
    {
        if (\false !== $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be false. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert !false $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notFalse($value, $message = '')
    {
        if (\false === $value) {
            static::reportInvalidArgument($message ?: 'Expected a value other than false.');
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function ip($value, $message = '')
    {
        if (\false === \filter_var($value, \FILTER_VALIDATE_IP)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be an IP. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function ipv4($value, $message = '')
    {
        if (\false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be an IPv4. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function ipv6($value, $message = '')
    {
        if (\false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be an IPv6. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function email($value, $message = '')
    {
        if (\false === \filter_var($value, \FILTER_VALIDATE_EMAIL)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to be a valid e-mail address. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * Does non strict comparisons on the items, so ['3', 3] will not pass the assertion.
     *
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function uniqueValues(array $values, $message = '')
    {
        $allValues = \count($values);
        $uniqueValues = \count(\array_unique($values));
        if ($allValues !== $uniqueValues) {
            $difference = $allValues - $uniqueValues;
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an array of unique values, but %s of them %s duplicated', $difference, 1 === $difference ? 'is' : 'are'));
        }
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function eq($value, $expect, $message = '')
    {
        if ($expect != $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($expect)));
        }
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notEq($value, $expect, $message = '')
    {
        if ($expect == $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a different value than %s.', static::valueToString($expect)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function same($value, $expect, $message = '')
    {
        if ($expect !== $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value identical to %2$s. Got: %s', static::valueToString($value), static::valueToString($expect)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notSame($value, $expect, $message = '')
    {
        if ($expect === $value) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value not identical to %s.', static::valueToString($expect)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function greaterThan($value, $limit, $message = '')
    {
        if ($value <= $limit) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value greater than %2$s. Got: %s', static::valueToString($value), static::valueToString($limit)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function greaterThanEq($value, $limit, $message = '')
    {
        if ($value < $limit) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value greater than or equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($limit)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function lessThan($value, $limit, $message = '')
    {
        if ($value >= $limit) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value less than %2$s. Got: %s', static::valueToString($value), static::valueToString($limit)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function lessThanEq($value, $limit, $message = '')
    {
        if ($value > $limit) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value less than or equal to %2$s. Got: %s', static::valueToString($value), static::valueToString($limit)));
        }
    }
    /**
     * Inclusive range, so Assert::(3, 3, 5) passes.
     *
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $min
     * @param mixed  $max
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function range($value, $min, $max, $message = '')
    {
        if ($value < $min || $value > $max) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value between %2$s and %3$s. Got: %s', static::valueToString($value), static::valueToString($min), static::valueToString($max)));
        }
    }
    /**
     * A more human-readable alias of Assert::inArray().
     *
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function oneOf($value, array $values, $message = '')
    {
        static::inArray($value, $values, $message);
    }
    /**
     * Does strict comparison, so Assert::inArray(3, ['3']) does not pass the assertion.
     *
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function inArray($value, array $values, $message = '')
    {
        if (!\in_array($value, $values, \true)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected one of: %2$s. Got: %s', static::valueToString($value), \implode(', ', \array_map(array(static::class, 'valueToString'), $values))));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $subString
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function contains($value, $subString, $message = '')
    {
        if (\false === \strpos($value, $subString)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain %2$s. Got: %s', static::valueToString($value), static::valueToString($subString)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $subString
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notContains($value, $subString, $message = '')
    {
        if (\false !== \strpos($value, $subString)) {
            static::reportInvalidArgument(\sprintf($message ?: '%2$s was not expected to be contained in a value. Got: %s', static::valueToString($value), static::valueToString($subString)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notWhitespaceOnly($value, $message = '')
    {
        if (\preg_match('/^\\s*$/', $value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a non-whitespace string. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $prefix
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function startsWith($value, $prefix, $message = '')
    {
        if (0 !== \strpos($value, $prefix)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to start with %2$s. Got: %s', static::valueToString($value), static::valueToString($prefix)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $prefix
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notStartsWith($value, $prefix, $message = '')
    {
        if (0 === \strpos($value, $prefix)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value not to start with %2$s. Got: %s', static::valueToString($value), static::valueToString($prefix)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function startsWithLetter($value, $message = '')
    {
        static::string($value);
        $valid = isset($value[0]);
        if ($valid) {
            $locale = \setlocale(\LC_CTYPE, 0);
            \setlocale(\LC_CTYPE, 'C');
            $valid = \ctype_alpha($value[0]);
            \setlocale(\LC_CTYPE, $locale);
        }
        if (!$valid) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to start with a letter. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $suffix
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function endsWith($value, $suffix, $message = '')
    {
        if ($suffix !== \substr($value, -\strlen($suffix))) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to end with %2$s. Got: %s', static::valueToString($value), static::valueToString($suffix)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $suffix
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notEndsWith($value, $suffix, $message = '')
    {
        if ($suffix === \substr($value, -\strlen($suffix))) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value not to end with %2$s. Got: %s', static::valueToString($value), static::valueToString($suffix)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $pattern
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function regex($value, $pattern, $message = '')
    {
        if (!\preg_match($pattern, $value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'The value %s does not match the expected pattern.', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $pattern
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function notRegex($value, $pattern, $message = '')
    {
        if (\preg_match($pattern, $value, $matches, \PREG_OFFSET_CAPTURE)) {
            static::reportInvalidArgument(\sprintf($message ?: 'The value %s matches the pattern %s (at offset %d).', static::valueToString($value), static::valueToString($pattern), $matches[0][1]));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function unicodeLetters($value, $message = '')
    {
        static::string($value);
        if (!\preg_match('/^\\p{L}+$/u', $value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain only Unicode letters. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function alpha($value, $message = '')
    {
        static::string($value);
        $locale = \setlocale(\LC_CTYPE, 0);
        \setlocale(\LC_CTYPE, 'C');
        $valid = !\ctype_alpha($value);
        \setlocale(\LC_CTYPE, $locale);
        if ($valid) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain only letters. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function digits($value, $message = '')
    {
        $locale = \setlocale(\LC_CTYPE, 0);
        \setlocale(\LC_CTYPE, 'C');
        $valid = !\ctype_digit($value);
        \setlocale(\LC_CTYPE, $locale);
        if ($valid) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain digits only. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function alnum($value, $message = '')
    {
        $locale = \setlocale(\LC_CTYPE, 0);
        \setlocale(\LC_CTYPE, 'C');
        $valid = !\ctype_alnum($value);
        \setlocale(\LC_CTYPE, $locale);
        if ($valid) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain letters and digits only. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert lowercase-string $value
     *
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function lower($value, $message = '')
    {
        $locale = \setlocale(\LC_CTYPE, 0);
        \setlocale(\LC_CTYPE, 'C');
        $valid = !\ctype_lower($value);
        \setlocale(\LC_CTYPE, $locale);
        if ($valid) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain lowercase characters only. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert !lowercase-string $value
     *
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function upper($value, $message = '')
    {
        $locale = \setlocale(\LC_CTYPE, 0);
        \setlocale(\LC_CTYPE, 'C');
        $valid = !\ctype_upper($value);
        \setlocale(\LC_CTYPE, $locale);
        if ($valid) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain uppercase characters only. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param int    $length
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function length($value, $length, $message = '')
    {
        if ($length !== static::strlen($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain %2$s characters. Got: %s', static::valueToString($value), $length));
        }
    }
    /**
     * Inclusive min.
     *
     * @psalm-pure
     *
     * @param string    $value
     * @param int|float $min
     * @param string    $message
     *
     * @throws InvalidArgumentException
     */
    public static function minLength($value, $min, $message = '')
    {
        if (static::strlen($value) < $min) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain at least %2$s characters. Got: %s', static::valueToString($value), $min));
        }
    }
    /**
     * Inclusive max.
     *
     * @psalm-pure
     *
     * @param string    $value
     * @param int|float $max
     * @param string    $message
     *
     * @throws InvalidArgumentException
     */
    public static function maxLength($value, $max, $message = '')
    {
        if (static::strlen($value) > $max) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain at most %2$s characters. Got: %s', static::valueToString($value), $max));
        }
    }
    /**
     * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion.
     *
     * @psalm-pure
     *
     * @param string    $value
     * @param int|float $min
     * @param int|float $max
     * @param string    $message
     *
     * @throws InvalidArgumentException
     */
    public static function lengthBetween($value, $min, $max, $message = '')
    {
        $length = static::strlen($value);
        if ($length < $min || $length > $max) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s', static::valueToString($value), $min, $max));
        }
    }
    /**
     * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file.
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function fileExists($value, $message = '')
    {
        static::string($value);
        if (!\file_exists($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'The file %s does not exist.', static::valueToString($value)));
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function file($value, $message = '')
    {
        static::fileExists($value, $message);
        if (!\is_file($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'The path %s is not a file.', static::valueToString($value)));
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function directory($value, $message = '')
    {
        static::fileExists($value, $message);
        if (!\is_dir($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'The path %s is no directory.', static::valueToString($value)));
        }
    }
    /**
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function readable($value, $message = '')
    {
        if (!\is_readable($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'The path %s is not readable.', static::valueToString($value)));
        }
    }
    /**
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function writable($value, $message = '')
    {
        if (!\is_writable($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'The path %s is not writable.', static::valueToString($value)));
        }
    }
    /**
     * @psalm-assert class-string $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function classExists($value, $message = '')
    {
        if (!\class_exists($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an existing class name. Got: %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert class-string<ExpectedType>|ExpectedType $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function subclassOf($value, $class, $message = '')
    {
        if (!\is_subclass_of($value, $class)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected a sub-class of %2$s. Got: %s', static::valueToString($value), static::valueToString($class)));
        }
    }
    /**
     * @psalm-assert class-string $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function interfaceExists($value, $message = '')
    {
        if (!\interface_exists($value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an existing interface name. got %s', static::valueToString($value)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $interface
     * @psalm-assert class-string<ExpectedType> $value
     *
     * @param mixed  $value
     * @param mixed  $interface
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function implementsInterface($value, $interface, $message = '')
    {
        if (!\in_array($interface, \class_implements($value))) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an implementation of %2$s. Got: %s', static::valueToString($value), static::valueToString($interface)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object $classOrObject
     *
     * @param string|object $classOrObject
     * @param mixed         $property
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function propertyExists($classOrObject, $property, $message = '')
    {
        if (!\property_exists($classOrObject, $property)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected the property %s to exist.', static::valueToString($property)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object $classOrObject
     *
     * @param string|object $classOrObject
     * @param mixed         $property
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function propertyNotExists($classOrObject, $property, $message = '')
    {
        if (\property_exists($classOrObject, $property)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected the property %s to not exist.', static::valueToString($property)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object $classOrObject
     *
     * @param string|object $classOrObject
     * @param mixed         $method
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function methodExists($classOrObject, $method, $message = '')
    {
        if (!(\is_string($classOrObject) || \is_object($classOrObject)) || !\method_exists($classOrObject, $method)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected the method %s to exist.', static::valueToString($method)));
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object $classOrObject
     *
     * @param string|object $classOrObject
     * @param mixed         $method
     * @param string        $message
     *
     * @throws InvalidArgumentException
     */
    public static function methodNotExists($classOrObject, $method, $message = '')
    {
        if ((\is_string($classOrObject) || \is_object($classOrObject)) && \method_exists($classOrObject, $method)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected the method %s to not exist.', static::valueToString($method)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param array      $array
     * @param string|int $key
     * @param string     $message
     *
     * @throws InvalidArgumentException
     */
    public static function keyExists($array, $key, $message = '')
    {
        if (!(isset($array[$key]) || \array_key_exists($key, $array))) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected the key %s to exist.', static::valueToString($key)));
        }
    }
    /**
     * @psalm-pure
     *
     * @param array      $array
     * @param string|int $key
     * @param string     $message
     *
     * @throws InvalidArgumentException
     */
    public static function keyNotExists($array, $key, $message = '')
    {
        if (isset($array[$key]) || \array_key_exists($key, $array)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected the key %s to not exist.', static::valueToString($key)));
        }
    }
    /**
     * Checks if a value is a valid array key (int or string).
     *
     * @psalm-pure
     * @psalm-assert array-key $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function validArrayKey($value, $message = '')
    {
        if (!(\is_int($value) || \is_string($value))) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected string or integer. Got: %s', static::typeToString($value)));
        }
    }
    /**
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
     *
     * @param Countable|array $array
     * @param int             $number
     * @param string          $message
     *
     * @throws InvalidArgumentException
     */
    public static function count($array, $number, $message = '')
    {
        static::eq(\count($array), $number, \sprintf($message ?: 'Expected an array to contain %d elements. Got: %d.', $number, \count($array)));
    }
    /**
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
     *
     * @param Countable|array $array
     * @param int|float       $min
     * @param string          $message
     *
     * @throws InvalidArgumentException
     */
    public static function minCount($array, $min, $message = '')
    {
        if (\count($array) < $min) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an array to contain at least %2$d elements. Got: %d', \count($array), $min));
        }
    }
    /**
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
     *
     * @param Countable|array $array
     * @param int|float       $max
     * @param string          $message
     *
     * @throws InvalidArgumentException
     */
    public static function maxCount($array, $max, $message = '')
    {
        if (\count($array) > $max) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an array to contain at most %2$d elements. Got: %d', \count($array), $max));
        }
    }
    /**
     * Does not check if $array is countable, this can generate a warning on php versions after 7.2.
     *
     * @param Countable|array $array
     * @param int|float       $min
     * @param int|float       $max
     * @param string          $message
     *
     * @throws InvalidArgumentException
     */
    public static function countBetween($array, $min, $max, $message = '')
    {
        $count = \count($array);
        if ($count < $min || $count > $max) {
            static::reportInvalidArgument(\sprintf($message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d', $count, $min, $max));
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert list $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isList($array, $message = '')
    {
        if (!\is_array($array)) {
            static::reportInvalidArgument($message ?: 'Expected list - non-associative array.');
        }
        if ($array === \array_values($array)) {
            return;
        }
        $nextKey = -1;
        foreach ($array as $k => $v) {
            if ($k !== ++$nextKey) {
                static::reportInvalidArgument($message ?: 'Expected list - non-associative array.');
            }
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert non-empty-list $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isNonEmptyList($array, $message = '')
    {
        static::isList($array, $message);
        static::notEmpty($array, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param mixed|array<T> $array
     * @psalm-assert array<string, T> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isMap($array, $message = '')
    {
        if (!\is_array($array) || \array_keys($array) !== \array_filter(\array_keys($array), '\\is_string')) {
            static::reportInvalidArgument($message ?: 'Expected map - associative array with string keys.');
        }
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param mixed|array<T> $array
     * @psalm-assert array<string, T> $array
     * @psalm-assert !empty $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function isNonEmptyMap($array, $message = '')
    {
        static::isMap($array, $message);
        static::notEmpty($array, $message);
    }
    /**
     * @psalm-pure
     *
     * @param string $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     */
    public static function uuid($value, $message = '')
    {
        $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value);
        // The nil UUID is special form of UUID that is specified to have all
        // 128 bits set to zero.
        if ('00000000-0000-0000-0000-000000000000' === $value) {
            return;
        }
        if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) {
            static::reportInvalidArgument(\sprintf($message ?: 'Value %s is not a valid UUID.', static::valueToString($value)));
        }
    }
    /**
     * @psalm-param class-string<Throwable> $class
     *
     * @param Closure $expression
     * @param string  $class
     * @param string  $message
     *
     * @throws InvalidArgumentException
     */
    public static function throws(Closure $expression, $class = 'Exception', $message = '')
    {
        static::string($class);
        $actual = 'none';
        try {
            $expression();
        } catch (Exception $e) {
            $actual = \get_class($e);
            if ($e instanceof $class) {
                return;
            }
        } catch (Throwable $e) {
            $actual = \get_class($e);
            if ($e instanceof $class) {
                return;
            }
        }
        static::reportInvalidArgument($message ?: \sprintf('Expected to throw "%s", got "%s"', $class, $actual));
    }
    /**
     * @throws BadMethodCallException
     */
    public static function __callStatic($name, $arguments)
    {
        if ('nullOr' === \substr($name, 0, 6)) {
            if (null !== $arguments[0]) {
                $method = \lcfirst(\substr($name, 6));
                \call_user_func_array(array(static::class, $method), $arguments);
            }
            return;
        }
        if ('all' === \substr($name, 0, 3)) {
            static::isIterable($arguments[0]);
            $method = \lcfirst(\substr($name, 3));
            $args = $arguments;
            foreach ($arguments[0] as $entry) {
                $args[0] = $entry;
                \call_user_func_array(array(static::class, $method), $args);
            }
            return;
        }
        throw new BadMethodCallException('No such method: ' . $name);
    }
    /**
     * @param mixed $value
     *
     * @return string
     */
    protected static function valueToString($value)
    {
        if (null === $value) {
            return 'null';
        }
        if (\true === $value) {
            return 'true';
        }
        if (\false === $value) {
            return 'false';
        }
        if (\is_array($value)) {
            return 'array';
        }
        if (\is_object($value)) {
            if (\method_exists($value, '__toString')) {
                return \get_class($value) . ': ' . self::valueToString($value->__toString());
            }
            if ($value instanceof DateTime || $value instanceof DateTimeImmutable) {
                return \get_class($value) . ': ' . self::valueToString($value->format('c'));
            }
            return \get_class($value);
        }
        if (\is_resource($value)) {
            return 'resource';
        }
        if (\is_string($value)) {
            return '"' . $value . '"';
        }
        return (string) $value;
    }
    /**
     * @param mixed $value
     *
     * @return string
     */
    protected static function typeToString($value)
    {
        return \is_object($value) ? \get_class($value) : \gettype($value);
    }
    protected static function strlen($value)
    {
        if (!\function_exists('mb_detect_encoding')) {
            return \strlen($value);
        }
        if (\false === ($encoding = \mb_detect_encoding($value))) {
            return \strlen($value);
        }
        return \mb_strlen($value, $encoding);
    }
    /**
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @psalm-pure this method is not supposed to perform side-effects
     * @psalm-return never
     */
    protected static function reportInvalidArgument($message)
    {
        throw new InvalidArgumentException($message);
    }
    private function __construct()
    {
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Webmozart\Assert;

use ArrayAccess;
use Closure;
use Countable;
use Throwable;
/**
 * This trait provides nurllOr*, all* and allNullOr* variants of assertion base methods.
 * Do not use this trait directly: it will change, and is not designed for reuse.
 */
trait Mixin
{
    /**
     * @psalm-pure
     * @psalm-assert string|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrString($value, $message = '')
    {
        null === $value || static::string($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<string> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allString($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::string($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<string|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrString($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::string($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert non-empty-string|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrStringNotEmpty($value, $message = '')
    {
        null === $value || static::stringNotEmpty($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<non-empty-string> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allStringNotEmpty($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::stringNotEmpty($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<non-empty-string|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrStringNotEmpty($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::stringNotEmpty($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert int|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrInteger($value, $message = '')
    {
        null === $value || static::integer($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<int> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allInteger($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::integer($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<int|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrInteger($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::integer($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert numeric|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIntegerish($value, $message = '')
    {
        null === $value || static::integerish($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<numeric> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIntegerish($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::integerish($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<numeric|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIntegerish($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::integerish($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert positive-int|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrPositiveInteger($value, $message = '')
    {
        null === $value || static::positiveInteger($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<positive-int> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allPositiveInteger($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::positiveInteger($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<positive-int|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrPositiveInteger($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::positiveInteger($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert float|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrFloat($value, $message = '')
    {
        null === $value || static::float($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<float> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allFloat($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::float($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<float|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrFloat($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::float($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert numeric|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNumeric($value, $message = '')
    {
        null === $value || static::numeric($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<numeric> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNumeric($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::numeric($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<numeric|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNumeric($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::numeric($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert positive-int|0|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNatural($value, $message = '')
    {
        null === $value || static::natural($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<positive-int|0> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNatural($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::natural($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<positive-int|0|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNatural($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::natural($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert bool|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrBoolean($value, $message = '')
    {
        null === $value || static::boolean($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<bool> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allBoolean($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::boolean($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<bool|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrBoolean($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::boolean($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert scalar|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrScalar($value, $message = '')
    {
        null === $value || static::scalar($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<scalar> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allScalar($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::scalar($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<scalar|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrScalar($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::scalar($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert object|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrObject($value, $message = '')
    {
        null === $value || static::object($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<object> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allObject($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::object($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<object|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrObject($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::object($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert resource|null $value
     *
     * @param mixed       $value
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrResource($value, $type = null, $message = '')
    {
        null === $value || static::resource($value, $type, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<resource> $value
     *
     * @param mixed       $value
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allResource($value, $type = null, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::resource($entry, $type, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<resource|null> $value
     *
     * @param mixed       $value
     * @param string|null $type    type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrResource($value, $type = null, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::resource($entry, $type, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert callable|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsCallable($value, $message = '')
    {
        null === $value || static::isCallable($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<callable> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsCallable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isCallable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<callable|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsCallable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isCallable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert array|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsArray($value, $message = '')
    {
        null === $value || static::isArray($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<array> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsArray($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isArray($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<array|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsArray($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isArray($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable|null $value
     *
     * @deprecated use "isIterable" or "isInstanceOf" instead
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsTraversable($value, $message = '')
    {
        null === $value || static::isTraversable($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<iterable> $value
     *
     * @deprecated use "isIterable" or "isInstanceOf" instead
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsTraversable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isTraversable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<iterable|null> $value
     *
     * @deprecated use "isIterable" or "isInstanceOf" instead
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsTraversable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isTraversable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert array|ArrayAccess|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsArrayAccessible($value, $message = '')
    {
        null === $value || static::isArrayAccessible($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<array|ArrayAccess> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsArrayAccessible($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isArrayAccessible($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<array|ArrayAccess|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsArrayAccessible($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isArrayAccessible($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert countable|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsCountable($value, $message = '')
    {
        null === $value || static::isCountable($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<countable> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsCountable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isCountable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<countable|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsCountable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isCountable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsIterable($value, $message = '')
    {
        null === $value || static::isIterable($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<iterable> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsIterable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isIterable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<iterable|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsIterable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isIterable($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert ExpectedType|null $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsInstanceOf($value, $class, $message = '')
    {
        null === $value || static::isInstanceOf($value, $class, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert iterable<ExpectedType> $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsInstanceOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isInstanceOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert iterable<ExpectedType|null> $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsInstanceOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isInstanceOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotInstanceOf($value, $class, $message = '')
    {
        null === $value || static::notInstanceOf($value, $class, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotInstanceOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notInstanceOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert iterable<!ExpectedType|null> $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotInstanceOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notInstanceOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param mixed                $value
     * @param array<object|string> $classes
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsInstanceOfAny($value, $classes, $message = '')
    {
        null === $value || static::isInstanceOfAny($value, $classes, $message);
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param mixed                $value
     * @param array<object|string> $classes
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsInstanceOfAny($value, $classes, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isInstanceOfAny($entry, $classes, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param mixed                $value
     * @param array<object|string> $classes
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsInstanceOfAny($value, $classes, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isInstanceOfAny($entry, $classes, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert ExpectedType|class-string<ExpectedType>|null $value
     *
     * @param object|string|null $value
     * @param string             $class
     * @param string             $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsAOf($value, $class, $message = '')
    {
        null === $value || static::isAOf($value, $class, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert iterable<ExpectedType|class-string<ExpectedType>> $value
     *
     * @param iterable<object|string> $value
     * @param string                  $class
     * @param string                  $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsAOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isAOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert iterable<ExpectedType|class-string<ExpectedType>|null> $value
     *
     * @param iterable<object|string|null> $value
     * @param string                       $class
     * @param string                       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsAOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isAOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template UnexpectedType of object
     * @psalm-param class-string<UnexpectedType> $class
     *
     * @param object|string|null $value
     * @param string             $class
     * @param string             $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsNotA($value, $class, $message = '')
    {
        null === $value || static::isNotA($value, $class, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template UnexpectedType of object
     * @psalm-param class-string<UnexpectedType> $class
     *
     * @param iterable<object|string> $value
     * @param string                  $class
     * @param string                  $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsNotA($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isNotA($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template UnexpectedType of object
     * @psalm-param class-string<UnexpectedType> $class
     * @psalm-assert iterable<!UnexpectedType|null> $value
     * @psalm-assert iterable<!class-string<UnexpectedType>|null> $value
     *
     * @param iterable<object|string|null> $value
     * @param string                       $class
     * @param string                       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsNotA($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isNotA($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param object|string|null $value
     * @param string[]           $classes
     * @param string             $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsAnyOf($value, $classes, $message = '')
    {
        null === $value || static::isAnyOf($value, $classes, $message);
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param iterable<object|string> $value
     * @param string[]                $classes
     * @param string                  $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsAnyOf($value, $classes, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isAnyOf($entry, $classes, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param array<class-string> $classes
     *
     * @param iterable<object|string|null> $value
     * @param string[]                     $classes
     * @param string                       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsAnyOf($value, $classes, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isAnyOf($entry, $classes, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert empty $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsEmpty($value, $message = '')
    {
        null === $value || static::isEmpty($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<empty> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsEmpty($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::isEmpty($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<empty|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsEmpty($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::isEmpty($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotEmpty($value, $message = '')
    {
        null === $value || static::notEmpty($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotEmpty($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notEmpty($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<!empty|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotEmpty($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notEmpty($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNull($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::null($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotNull($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notNull($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert true|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrTrue($value, $message = '')
    {
        null === $value || static::true($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<true> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allTrue($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::true($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<true|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrTrue($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::true($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert false|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrFalse($value, $message = '')
    {
        null === $value || static::false($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<false> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allFalse($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::false($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<false|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrFalse($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::false($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotFalse($value, $message = '')
    {
        null === $value || static::notFalse($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotFalse($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notFalse($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<!false|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotFalse($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notFalse($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIp($value, $message = '')
    {
        null === $value || static::ip($value, $message);
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIp($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::ip($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIp($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::ip($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIpv4($value, $message = '')
    {
        null === $value || static::ipv4($value, $message);
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIpv4($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::ipv4($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIpv4($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::ipv4($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIpv6($value, $message = '')
    {
        null === $value || static::ipv6($value, $message);
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIpv6($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::ipv6($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIpv6($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::ipv6($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrEmail($value, $message = '')
    {
        null === $value || static::email($value, $message);
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allEmail($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::email($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrEmail($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::email($entry, $message);
        }
    }
    /**
     * @param array|null $values
     * @param string     $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrUniqueValues($values, $message = '')
    {
        null === $values || static::uniqueValues($values, $message);
    }
    /**
     * @param iterable<array> $values
     * @param string          $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allUniqueValues($values, $message = '')
    {
        static::isIterable($values);
        foreach ($values as $entry) {
            static::uniqueValues($entry, $message);
        }
    }
    /**
     * @param iterable<array|null> $values
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrUniqueValues($values, $message = '')
    {
        static::isIterable($values);
        foreach ($values as $entry) {
            null === $entry || static::uniqueValues($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrEq($value, $expect, $message = '')
    {
        null === $value || static::eq($value, $expect, $message);
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allEq($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::eq($entry, $expect, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrEq($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::eq($entry, $expect, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotEq($value, $expect, $message = '')
    {
        null === $value || static::notEq($value, $expect, $message);
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotEq($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notEq($entry, $expect, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotEq($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notEq($entry, $expect, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrSame($value, $expect, $message = '')
    {
        null === $value || static::same($value, $expect, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allSame($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::same($entry, $expect, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrSame($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::same($entry, $expect, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotSame($value, $expect, $message = '')
    {
        null === $value || static::notSame($value, $expect, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotSame($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notSame($entry, $expect, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $expect
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotSame($value, $expect, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notSame($entry, $expect, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrGreaterThan($value, $limit, $message = '')
    {
        null === $value || static::greaterThan($value, $limit, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allGreaterThan($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::greaterThan($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrGreaterThan($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::greaterThan($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrGreaterThanEq($value, $limit, $message = '')
    {
        null === $value || static::greaterThanEq($value, $limit, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allGreaterThanEq($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::greaterThanEq($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrGreaterThanEq($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::greaterThanEq($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrLessThan($value, $limit, $message = '')
    {
        null === $value || static::lessThan($value, $limit, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allLessThan($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::lessThan($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrLessThan($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::lessThan($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrLessThanEq($value, $limit, $message = '')
    {
        null === $value || static::lessThanEq($value, $limit, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allLessThanEq($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::lessThanEq($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $limit
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrLessThanEq($value, $limit, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::lessThanEq($entry, $limit, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $min
     * @param mixed  $max
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrRange($value, $min, $max, $message = '')
    {
        null === $value || static::range($value, $min, $max, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $min
     * @param mixed  $max
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allRange($value, $min, $max, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::range($entry, $min, $max, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param mixed  $min
     * @param mixed  $max
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrRange($value, $min, $max, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::range($entry, $min, $max, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrOneOf($value, $values, $message = '')
    {
        null === $value || static::oneOf($value, $values, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allOneOf($value, $values, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::oneOf($entry, $values, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrOneOf($value, $values, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::oneOf($entry, $values, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrInArray($value, $values, $message = '')
    {
        null === $value || static::inArray($value, $values, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allInArray($value, $values, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::inArray($entry, $values, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param array  $values
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrInArray($value, $values, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::inArray($entry, $values, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $subString
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrContains($value, $subString, $message = '')
    {
        null === $value || static::contains($value, $subString, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $subString
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allContains($value, $subString, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::contains($entry, $subString, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $subString
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrContains($value, $subString, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::contains($entry, $subString, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $subString
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotContains($value, $subString, $message = '')
    {
        null === $value || static::notContains($value, $subString, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $subString
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotContains($value, $subString, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notContains($entry, $subString, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $subString
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotContains($value, $subString, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notContains($entry, $subString, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotWhitespaceOnly($value, $message = '')
    {
        null === $value || static::notWhitespaceOnly($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotWhitespaceOnly($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notWhitespaceOnly($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotWhitespaceOnly($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notWhitespaceOnly($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $prefix
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrStartsWith($value, $prefix, $message = '')
    {
        null === $value || static::startsWith($value, $prefix, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $prefix
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allStartsWith($value, $prefix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::startsWith($entry, $prefix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $prefix
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrStartsWith($value, $prefix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::startsWith($entry, $prefix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $prefix
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotStartsWith($value, $prefix, $message = '')
    {
        null === $value || static::notStartsWith($value, $prefix, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $prefix
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotStartsWith($value, $prefix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notStartsWith($entry, $prefix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $prefix
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotStartsWith($value, $prefix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notStartsWith($entry, $prefix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrStartsWithLetter($value, $message = '')
    {
        null === $value || static::startsWithLetter($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allStartsWithLetter($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::startsWithLetter($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrStartsWithLetter($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::startsWithLetter($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $suffix
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrEndsWith($value, $suffix, $message = '')
    {
        null === $value || static::endsWith($value, $suffix, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $suffix
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allEndsWith($value, $suffix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::endsWith($entry, $suffix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $suffix
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrEndsWith($value, $suffix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::endsWith($entry, $suffix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $suffix
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotEndsWith($value, $suffix, $message = '')
    {
        null === $value || static::notEndsWith($value, $suffix, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $suffix
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotEndsWith($value, $suffix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notEndsWith($entry, $suffix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $suffix
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotEndsWith($value, $suffix, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notEndsWith($entry, $suffix, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $pattern
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrRegex($value, $pattern, $message = '')
    {
        null === $value || static::regex($value, $pattern, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $pattern
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allRegex($value, $pattern, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::regex($entry, $pattern, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $pattern
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrRegex($value, $pattern, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::regex($entry, $pattern, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $pattern
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrNotRegex($value, $pattern, $message = '')
    {
        null === $value || static::notRegex($value, $pattern, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $pattern
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNotRegex($value, $pattern, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::notRegex($entry, $pattern, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $pattern
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrNotRegex($value, $pattern, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::notRegex($entry, $pattern, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrUnicodeLetters($value, $message = '')
    {
        null === $value || static::unicodeLetters($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allUnicodeLetters($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::unicodeLetters($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrUnicodeLetters($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::unicodeLetters($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrAlpha($value, $message = '')
    {
        null === $value || static::alpha($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allAlpha($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::alpha($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrAlpha($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::alpha($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrDigits($value, $message = '')
    {
        null === $value || static::digits($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allDigits($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::digits($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrDigits($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::digits($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrAlnum($value, $message = '')
    {
        null === $value || static::alnum($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allAlnum($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::alnum($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrAlnum($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::alnum($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert lowercase-string|null $value
     *
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrLower($value, $message = '')
    {
        null === $value || static::lower($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<lowercase-string> $value
     *
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allLower($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::lower($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<lowercase-string|null> $value
     *
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrLower($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::lower($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrUpper($value, $message = '')
    {
        null === $value || static::upper($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allUpper($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::upper($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<!lowercase-string|null> $value
     *
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrUpper($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::upper($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param int         $length
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrLength($value, $length, $message = '')
    {
        null === $value || static::length($value, $length, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param int              $length
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allLength($value, $length, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::length($entry, $length, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param int                   $length
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrLength($value, $length, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::length($entry, $length, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param int|float   $min
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrMinLength($value, $min, $message = '')
    {
        null === $value || static::minLength($value, $min, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param int|float        $min
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allMinLength($value, $min, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::minLength($entry, $min, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param int|float             $min
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrMinLength($value, $min, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::minLength($entry, $min, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param int|float   $max
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrMaxLength($value, $max, $message = '')
    {
        null === $value || static::maxLength($value, $max, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param int|float        $max
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allMaxLength($value, $max, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::maxLength($entry, $max, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param int|float             $max
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrMaxLength($value, $max, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::maxLength($entry, $max, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param int|float   $min
     * @param int|float   $max
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrLengthBetween($value, $min, $max, $message = '')
    {
        null === $value || static::lengthBetween($value, $min, $max, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param int|float        $min
     * @param int|float        $max
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allLengthBetween($value, $min, $max, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::lengthBetween($entry, $min, $max, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param int|float             $min
     * @param int|float             $max
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrLengthBetween($value, $min, $max, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::lengthBetween($entry, $min, $max, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrFileExists($value, $message = '')
    {
        null === $value || static::fileExists($value, $message);
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allFileExists($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::fileExists($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrFileExists($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::fileExists($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrFile($value, $message = '')
    {
        null === $value || static::file($value, $message);
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allFile($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::file($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrFile($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::file($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrDirectory($value, $message = '')
    {
        null === $value || static::directory($value, $message);
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allDirectory($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::directory($entry, $message);
        }
    }
    /**
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrDirectory($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::directory($entry, $message);
        }
    }
    /**
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrReadable($value, $message = '')
    {
        null === $value || static::readable($value, $message);
    }
    /**
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allReadable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::readable($entry, $message);
        }
    }
    /**
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrReadable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::readable($entry, $message);
        }
    }
    /**
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrWritable($value, $message = '')
    {
        null === $value || static::writable($value, $message);
    }
    /**
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allWritable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::writable($entry, $message);
        }
    }
    /**
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrWritable($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::writable($entry, $message);
        }
    }
    /**
     * @psalm-assert class-string|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrClassExists($value, $message = '')
    {
        null === $value || static::classExists($value, $message);
    }
    /**
     * @psalm-assert iterable<class-string> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allClassExists($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::classExists($entry, $message);
        }
    }
    /**
     * @psalm-assert iterable<class-string|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrClassExists($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::classExists($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert class-string<ExpectedType>|ExpectedType|null $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrSubclassOf($value, $class, $message = '')
    {
        null === $value || static::subclassOf($value, $class, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert iterable<class-string<ExpectedType>|ExpectedType> $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allSubclassOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::subclassOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $class
     * @psalm-assert iterable<class-string<ExpectedType>|ExpectedType|null> $value
     *
     * @param mixed         $value
     * @param string|object $class
     * @param string        $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrSubclassOf($value, $class, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::subclassOf($entry, $class, $message);
        }
    }
    /**
     * @psalm-assert class-string|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrInterfaceExists($value, $message = '')
    {
        null === $value || static::interfaceExists($value, $message);
    }
    /**
     * @psalm-assert iterable<class-string> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allInterfaceExists($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::interfaceExists($entry, $message);
        }
    }
    /**
     * @psalm-assert iterable<class-string|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrInterfaceExists($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::interfaceExists($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $interface
     * @psalm-assert class-string<ExpectedType>|null $value
     *
     * @param mixed  $value
     * @param mixed  $interface
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrImplementsInterface($value, $interface, $message = '')
    {
        null === $value || static::implementsInterface($value, $interface, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $interface
     * @psalm-assert iterable<class-string<ExpectedType>> $value
     *
     * @param mixed  $value
     * @param mixed  $interface
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allImplementsInterface($value, $interface, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::implementsInterface($entry, $interface, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template ExpectedType of object
     * @psalm-param class-string<ExpectedType> $interface
     * @psalm-assert iterable<class-string<ExpectedType>|null> $value
     *
     * @param mixed  $value
     * @param mixed  $interface
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrImplementsInterface($value, $interface, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::implementsInterface($entry, $interface, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object|null $classOrObject
     *
     * @param string|object|null $classOrObject
     * @param mixed              $property
     * @param string             $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrPropertyExists($classOrObject, $property, $message = '')
    {
        null === $classOrObject || static::propertyExists($classOrObject, $property, $message);
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object> $classOrObject
     *
     * @param iterable<string|object> $classOrObject
     * @param mixed                   $property
     * @param string                  $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allPropertyExists($classOrObject, $property, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            static::propertyExists($entry, $property, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object|null> $classOrObject
     *
     * @param iterable<string|object|null> $classOrObject
     * @param mixed                        $property
     * @param string                       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrPropertyExists($classOrObject, $property, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            null === $entry || static::propertyExists($entry, $property, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object|null $classOrObject
     *
     * @param string|object|null $classOrObject
     * @param mixed              $property
     * @param string             $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrPropertyNotExists($classOrObject, $property, $message = '')
    {
        null === $classOrObject || static::propertyNotExists($classOrObject, $property, $message);
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object> $classOrObject
     *
     * @param iterable<string|object> $classOrObject
     * @param mixed                   $property
     * @param string                  $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allPropertyNotExists($classOrObject, $property, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            static::propertyNotExists($entry, $property, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object|null> $classOrObject
     *
     * @param iterable<string|object|null> $classOrObject
     * @param mixed                        $property
     * @param string                       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrPropertyNotExists($classOrObject, $property, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            null === $entry || static::propertyNotExists($entry, $property, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object|null $classOrObject
     *
     * @param string|object|null $classOrObject
     * @param mixed              $method
     * @param string             $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrMethodExists($classOrObject, $method, $message = '')
    {
        null === $classOrObject || static::methodExists($classOrObject, $method, $message);
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object> $classOrObject
     *
     * @param iterable<string|object> $classOrObject
     * @param mixed                   $method
     * @param string                  $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allMethodExists($classOrObject, $method, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            static::methodExists($entry, $method, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object|null> $classOrObject
     *
     * @param iterable<string|object|null> $classOrObject
     * @param mixed                        $method
     * @param string                       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrMethodExists($classOrObject, $method, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            null === $entry || static::methodExists($entry, $method, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param class-string|object|null $classOrObject
     *
     * @param string|object|null $classOrObject
     * @param mixed              $method
     * @param string             $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrMethodNotExists($classOrObject, $method, $message = '')
    {
        null === $classOrObject || static::methodNotExists($classOrObject, $method, $message);
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object> $classOrObject
     *
     * @param iterable<string|object> $classOrObject
     * @param mixed                   $method
     * @param string                  $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allMethodNotExists($classOrObject, $method, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            static::methodNotExists($entry, $method, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-param iterable<class-string|object|null> $classOrObject
     *
     * @param iterable<string|object|null> $classOrObject
     * @param mixed                        $method
     * @param string                       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrMethodNotExists($classOrObject, $method, $message = '')
    {
        static::isIterable($classOrObject);
        foreach ($classOrObject as $entry) {
            null === $entry || static::methodNotExists($entry, $method, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param array|null $array
     * @param string|int $key
     * @param string     $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrKeyExists($array, $key, $message = '')
    {
        null === $array || static::keyExists($array, $key, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<array> $array
     * @param string|int      $key
     * @param string          $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allKeyExists($array, $key, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::keyExists($entry, $key, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<array|null> $array
     * @param string|int           $key
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrKeyExists($array, $key, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::keyExists($entry, $key, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param array|null $array
     * @param string|int $key
     * @param string     $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrKeyNotExists($array, $key, $message = '')
    {
        null === $array || static::keyNotExists($array, $key, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<array> $array
     * @param string|int      $key
     * @param string          $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allKeyNotExists($array, $key, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::keyNotExists($entry, $key, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<array|null> $array
     * @param string|int           $key
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrKeyNotExists($array, $key, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::keyNotExists($entry, $key, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert array-key|null $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrValidArrayKey($value, $message = '')
    {
        null === $value || static::validArrayKey($value, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<array-key> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allValidArrayKey($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::validArrayKey($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<array-key|null> $value
     *
     * @param mixed  $value
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrValidArrayKey($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::validArrayKey($entry, $message);
        }
    }
    /**
     * @param Countable|array|null $array
     * @param int                  $number
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrCount($array, $number, $message = '')
    {
        null === $array || static::count($array, $number, $message);
    }
    /**
     * @param iterable<Countable|array> $array
     * @param int                       $number
     * @param string                    $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allCount($array, $number, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::count($entry, $number, $message);
        }
    }
    /**
     * @param iterable<Countable|array|null> $array
     * @param int                            $number
     * @param string                         $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrCount($array, $number, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::count($entry, $number, $message);
        }
    }
    /**
     * @param Countable|array|null $array
     * @param int|float            $min
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrMinCount($array, $min, $message = '')
    {
        null === $array || static::minCount($array, $min, $message);
    }
    /**
     * @param iterable<Countable|array> $array
     * @param int|float                 $min
     * @param string                    $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allMinCount($array, $min, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::minCount($entry, $min, $message);
        }
    }
    /**
     * @param iterable<Countable|array|null> $array
     * @param int|float                      $min
     * @param string                         $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrMinCount($array, $min, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::minCount($entry, $min, $message);
        }
    }
    /**
     * @param Countable|array|null $array
     * @param int|float            $max
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrMaxCount($array, $max, $message = '')
    {
        null === $array || static::maxCount($array, $max, $message);
    }
    /**
     * @param iterable<Countable|array> $array
     * @param int|float                 $max
     * @param string                    $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allMaxCount($array, $max, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::maxCount($entry, $max, $message);
        }
    }
    /**
     * @param iterable<Countable|array|null> $array
     * @param int|float                      $max
     * @param string                         $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrMaxCount($array, $max, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::maxCount($entry, $max, $message);
        }
    }
    /**
     * @param Countable|array|null $array
     * @param int|float            $min
     * @param int|float            $max
     * @param string               $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrCountBetween($array, $min, $max, $message = '')
    {
        null === $array || static::countBetween($array, $min, $max, $message);
    }
    /**
     * @param iterable<Countable|array> $array
     * @param int|float                 $min
     * @param int|float                 $max
     * @param string                    $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allCountBetween($array, $min, $max, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::countBetween($entry, $min, $max, $message);
        }
    }
    /**
     * @param iterable<Countable|array|null> $array
     * @param int|float                      $min
     * @param int|float                      $max
     * @param string                         $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrCountBetween($array, $min, $max, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::countBetween($entry, $min, $max, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert list|null $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsList($array, $message = '')
    {
        null === $array || static::isList($array, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<list> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsList($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::isList($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<list|null> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsList($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::isList($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert non-empty-list|null $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsNonEmptyList($array, $message = '')
    {
        null === $array || static::isNonEmptyList($array, $message);
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<non-empty-list> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsNonEmptyList($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::isNonEmptyList($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-assert iterable<non-empty-list|null> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsNonEmptyList($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::isNonEmptyList($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param mixed|array<T>|null $array
     * @psalm-assert array<string, T>|null $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsMap($array, $message = '')
    {
        null === $array || static::isMap($array, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param iterable<mixed|array<T>> $array
     * @psalm-assert iterable<array<string, T>> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsMap($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::isMap($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param iterable<mixed|array<T>|null> $array
     * @psalm-assert iterable<array<string, T>|null> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsMap($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::isMap($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param mixed|array<T>|null $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrIsNonEmptyMap($array, $message = '')
    {
        null === $array || static::isNonEmptyMap($array, $message);
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param iterable<mixed|array<T>> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allIsNonEmptyMap($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            static::isNonEmptyMap($entry, $message);
        }
    }
    /**
     * @psalm-pure
     * @psalm-template T
     * @psalm-param iterable<mixed|array<T>|null> $array
     * @psalm-assert iterable<array<string, T>|null> $array
     * @psalm-assert iterable<!empty|null> $array
     *
     * @param mixed  $array
     * @param string $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrIsNonEmptyMap($array, $message = '')
    {
        static::isIterable($array);
        foreach ($array as $entry) {
            null === $entry || static::isNonEmptyMap($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param string|null $value
     * @param string      $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrUuid($value, $message = '')
    {
        null === $value || static::uuid($value, $message);
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string> $value
     * @param string           $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allUuid($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            static::uuid($entry, $message);
        }
    }
    /**
     * @psalm-pure
     *
     * @param iterable<string|null> $value
     * @param string                $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrUuid($value, $message = '')
    {
        static::isIterable($value);
        foreach ($value as $entry) {
            null === $entry || static::uuid($entry, $message);
        }
    }
    /**
     * @psalm-param class-string<Throwable> $class
     *
     * @param Closure|null $expression
     * @param string       $class
     * @param string       $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function nullOrThrows($expression, $class = 'Exception', $message = '')
    {
        null === $expression || static::throws($expression, $class, $message);
    }
    /**
     * @psalm-param class-string<Throwable> $class
     *
     * @param iterable<Closure> $expression
     * @param string            $class
     * @param string            $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allThrows($expression, $class = 'Exception', $message = '')
    {
        static::isIterable($expression);
        foreach ($expression as $entry) {
            static::throws($entry, $class, $message);
        }
    }
    /**
     * @psalm-param class-string<Throwable> $class
     *
     * @param iterable<Closure|null> $expression
     * @param string                 $class
     * @param string                 $message
     *
     * @throws InvalidArgumentException
     *
     * @return void
     */
    public static function allNullOrThrows($expression, $class = 'Exception', $message = '')
    {
        static::isIterable($expression);
        foreach ($expression as $entry) {
            null === $entry || static::throws($entry, $class, $message);
        }
    }
}
<?php

/*
 * This file is part of the webmozart/assert package.
 *
 * (c) Bernhard Schussek <bschussek@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\Webmozart\Assert;

class InvalidArgumentException extends \InvalidArgumentException
{
}
The MIT License (MIT)

Copyright (c) 2014 Bernhard Schussek

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Container;

/**
 * No entry was found in the container.
 */
interface NotFoundExceptionInterface extends ContainerExceptionInterface
{
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Container;

use Throwable;
/**
 * Base interface representing a generic exception in a container.
 */
interface ContainerExceptionInterface extends Throwable
{
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Psr\Container;

/**
 * Describes the interface of a container that exposes methods to read its entries.
 */
interface ContainerInterface
{
    /**
     * Finds an entry of the container by its identifier and returns it.
     *
     * @param string $id Identifier of the entry to look for.
     *
     * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
     * @throws ContainerExceptionInterface Error while retrieving the entry.
     *
     * @return mixed Entry.
     */
    public function get(string $id);
    /**
     * Returns true if the container can return an entry for the given identifier.
     * Returns false otherwise.
     *
     * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
     * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
     *
     * @param string $id Identifier of the entry to look for.
     *
     * @return bool
     */
    public function has(string $id);
}
The MIT License (MIT)

Copyright (c) 2013-2016 container-interop
Copyright (c) 2016 PHP Framework Interoperability Group

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Copyright (c) 2012 PHP Framework Interoperability Group

Permission is hereby granted, free of charge, to any person obtaining a copy 
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights 
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
copies of the Software, and to permit persons to whom the Software is 
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in 
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

/**
 * Describes a logger instance.
 *
 * The message MUST be a string or object implementing __toString().
 *
 * The message MAY contain placeholders in the form: {foo} where foo
 * will be replaced by the context data in key "foo".
 *
 * The context array can contain arbitrary data. The only assumption that
 * can be made by implementors is that if an Exception instance is given
 * to produce a stack trace, it MUST be in a key named "exception".
 *
 * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
 * for the full interface specification.
 */
interface LoggerInterface
{
    /**
     * System is unusable.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function emergency($message, array $context = array());
    /**
     * Action must be taken immediately.
     *
     * Example: Entire website down, database unavailable, etc. This should
     * trigger the SMS alerts and wake you up.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function alert($message, array $context = array());
    /**
     * Critical conditions.
     *
     * Example: Application component unavailable, unexpected exception.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function critical($message, array $context = array());
    /**
     * Runtime errors that do not require immediate action but should typically
     * be logged and monitored.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function error($message, array $context = array());
    /**
     * Exceptional occurrences that are not errors.
     *
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
     * that are not necessarily wrong.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function warning($message, array $context = array());
    /**
     * Normal but significant events.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function notice($message, array $context = array());
    /**
     * Interesting events.
     *
     * Example: User logs in, SQL logs.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function info($message, array $context = array());
    /**
     * Detailed debug information.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function debug($message, array $context = array());
    /**
     * Logs with an arbitrary level.
     *
     * @param mixed   $level
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     *
     * @throws \Psr\Log\InvalidArgumentException
     */
    public function log($level, $message, array $context = array());
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

/**
 * Describes a logger-aware instance.
 */
interface LoggerAwareInterface
{
    /**
     * Sets a logger instance on the object.
     *
     * @param LoggerInterface $logger
     *
     * @return void
     */
    public function setLogger(LoggerInterface $logger);
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

/**
 * This is a simple Logger implementation that other Loggers can inherit from.
 *
 * It simply delegates all log-level-specific methods to the `log` method to
 * reduce boilerplate code that a simple Logger that does the same thing with
 * messages regardless of the error level has to implement.
 */
abstract class AbstractLogger implements LoggerInterface
{
    /**
     * System is unusable.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function emergency($message, array $context = array())
    {
        $this->log(LogLevel::EMERGENCY, $message, $context);
    }
    /**
     * Action must be taken immediately.
     *
     * Example: Entire website down, database unavailable, etc. This should
     * trigger the SMS alerts and wake you up.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function alert($message, array $context = array())
    {
        $this->log(LogLevel::ALERT, $message, $context);
    }
    /**
     * Critical conditions.
     *
     * Example: Application component unavailable, unexpected exception.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function critical($message, array $context = array())
    {
        $this->log(LogLevel::CRITICAL, $message, $context);
    }
    /**
     * Runtime errors that do not require immediate action but should typically
     * be logged and monitored.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function error($message, array $context = array())
    {
        $this->log(LogLevel::ERROR, $message, $context);
    }
    /**
     * Exceptional occurrences that are not errors.
     *
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
     * that are not necessarily wrong.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function warning($message, array $context = array())
    {
        $this->log(LogLevel::WARNING, $message, $context);
    }
    /**
     * Normal but significant events.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function notice($message, array $context = array())
    {
        $this->log(LogLevel::NOTICE, $message, $context);
    }
    /**
     * Interesting events.
     *
     * Example: User logs in, SQL logs.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function info($message, array $context = array())
    {
        $this->log(LogLevel::INFO, $message, $context);
    }
    /**
     * Detailed debug information.
     *
     * @param string  $message
     * @param mixed[] $context
     *
     * @return void
     */
    public function debug($message, array $context = array())
    {
        $this->log(LogLevel::DEBUG, $message, $context);
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

/**
 * Describes log levels.
 */
class LogLevel
{
    const EMERGENCY = 'emergency';
    const ALERT = 'alert';
    const CRITICAL = 'critical';
    const ERROR = 'error';
    const WARNING = 'warning';
    const NOTICE = 'notice';
    const INFO = 'info';
    const DEBUG = 'debug';
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

/**
 * This is a simple Logger trait that classes unable to extend AbstractLogger
 * (because they extend another class, etc) can include.
 *
 * It simply delegates all log-level-specific methods to the `log` method to
 * reduce boilerplate code that a simple Logger that does the same thing with
 * messages regardless of the error level has to implement.
 */
trait LoggerTrait
{
    /**
     * System is unusable.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function emergency($message, array $context = array())
    {
        $this->log(LogLevel::EMERGENCY, $message, $context);
    }
    /**
     * Action must be taken immediately.
     *
     * Example: Entire website down, database unavailable, etc. This should
     * trigger the SMS alerts and wake you up.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function alert($message, array $context = array())
    {
        $this->log(LogLevel::ALERT, $message, $context);
    }
    /**
     * Critical conditions.
     *
     * Example: Application component unavailable, unexpected exception.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function critical($message, array $context = array())
    {
        $this->log(LogLevel::CRITICAL, $message, $context);
    }
    /**
     * Runtime errors that do not require immediate action but should typically
     * be logged and monitored.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function error($message, array $context = array())
    {
        $this->log(LogLevel::ERROR, $message, $context);
    }
    /**
     * Exceptional occurrences that are not errors.
     *
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
     * that are not necessarily wrong.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function warning($message, array $context = array())
    {
        $this->log(LogLevel::WARNING, $message, $context);
    }
    /**
     * Normal but significant events.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function notice($message, array $context = array())
    {
        $this->log(LogLevel::NOTICE, $message, $context);
    }
    /**
     * Interesting events.
     *
     * Example: User logs in, SQL logs.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function info($message, array $context = array())
    {
        $this->log(LogLevel::INFO, $message, $context);
    }
    /**
     * Detailed debug information.
     *
     * @param string $message
     * @param array  $context
     *
     * @return void
     */
    public function debug($message, array $context = array())
    {
        $this->log(LogLevel::DEBUG, $message, $context);
    }
    /**
     * Logs with an arbitrary level.
     *
     * @param mixed  $level
     * @param string $message
     * @param array  $context
     *
     * @return void
     *
     * @throws \Psr\Log\InvalidArgumentException
     */
    public abstract function log($level, $message, array $context = array());
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

/**
 * This Logger can be used to avoid conditional log calls.
 *
 * Logging should always be optional, and if no logger is provided to your
 * library creating a NullLogger instance to have something to throw logs at
 * is a good way to avoid littering your code with `if ($this->logger) { }`
 * blocks.
 */
class NullLogger extends AbstractLogger
{
    /**
     * Logs with an arbitrary level.
     *
     * @param mixed  $level
     * @param string $message
     * @param array  $context
     *
     * @return void
     *
     * @throws \Psr\Log\InvalidArgumentException
     */
    public function log($level, $message, array $context = array())
    {
        // noop
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

/**
 * Basic Implementation of LoggerAwareInterface.
 */
trait LoggerAwareTrait
{
    /**
     * The logger instance.
     *
     * @var LoggerInterface|null
     */
    protected $logger;
    /**
     * Sets a logger.
     *
     * @param LoggerInterface $logger
     */
    public function setLogger(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\Psr\Log;

class InvalidArgumentException extends \InvalidArgumentException
{
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

final class Line
{
    public const ADDED = 1;
    public const REMOVED = 2;
    public const UNCHANGED = 3;
    /**
     * @var int
     */
    private $type;
    /**
     * @var string
     */
    private $content;
    public function __construct(int $type = self::UNCHANGED, string $content = '')
    {
        $this->type = $type;
        $this->content = $content;
    }
    public function getContent() : string
    {
        return $this->content;
    }
    public function getType() : int
    {
        return $this->type;
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

interface LongestCommonSubsequenceCalculator
{
    /**
     * Calculates the longest common subsequence of two arrays.
     */
    public function calculate(array $from, array $to) : array;
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

use function get_class;
use function gettype;
use function is_object;
use function sprintf;
use Exception;
final class ConfigurationException extends InvalidArgumentException
{
    public function __construct(string $option, string $expected, $value, int $code = 0, Exception $previous = null)
    {
        parent::__construct(sprintf('Option "%s" must be %s, got "%s".', $option, $expected, is_object($value) ? get_class($value) : (null === $value ? '<null>' : gettype($value) . '#' . $value)), $code, $previous);
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

use Throwable;
interface Exception extends Throwable
{
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

class InvalidArgumentException extends \InvalidArgumentException implements Exception
{
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

final class Chunk
{
    /**
     * @var int
     */
    private $start;
    /**
     * @var int
     */
    private $startRange;
    /**
     * @var int
     */
    private $end;
    /**
     * @var int
     */
    private $endRange;
    /**
     * @var Line[]
     */
    private $lines;
    public function __construct(int $start = 0, int $startRange = 1, int $end = 0, int $endRange = 1, array $lines = [])
    {
        $this->start = $start;
        $this->startRange = $startRange;
        $this->end = $end;
        $this->endRange = $endRange;
        $this->lines = $lines;
    }
    public function getStart() : int
    {
        return $this->start;
    }
    public function getStartRange() : int
    {
        return $this->startRange;
    }
    public function getEnd() : int
    {
        return $this->end;
    }
    public function getEndRange() : int
    {
        return $this->endRange;
    }
    /**
     * @return Line[]
     */
    public function getLines() : array
    {
        return $this->lines;
    }
    /**
     * @param Line[] $lines
     */
    public function setLines(array $lines) : void
    {
        foreach ($lines as $line) {
            if (!$line instanceof Line) {
                throw new InvalidArgumentException();
            }
        }
        $this->lines = $lines;
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

use function array_fill;
use function array_merge;
use function array_reverse;
use function array_slice;
use function count;
use function in_array;
use function max;
final class MemoryEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
{
    /**
     * {@inheritdoc}
     */
    public function calculate(array $from, array $to) : array
    {
        $cFrom = count($from);
        $cTo = count($to);
        if ($cFrom === 0) {
            return [];
        }
        if ($cFrom === 1) {
            if (in_array($from[0], $to, \true)) {
                return [$from[0]];
            }
            return [];
        }
        $i = (int) ($cFrom / 2);
        $fromStart = array_slice($from, 0, $i);
        $fromEnd = array_slice($from, $i);
        $llB = $this->length($fromStart, $to);
        $llE = $this->length(array_reverse($fromEnd), array_reverse($to));
        $jMax = 0;
        $max = 0;
        for ($j = 0; $j <= $cTo; $j++) {
            $m = $llB[$j] + $llE[$cTo - $j];
            if ($m >= $max) {
                $max = $m;
                $jMax = $j;
            }
        }
        $toStart = array_slice($to, 0, $jMax);
        $toEnd = array_slice($to, $jMax);
        return array_merge($this->calculate($fromStart, $toStart), $this->calculate($fromEnd, $toEnd));
    }
    private function length(array $from, array $to) : array
    {
        $current = array_fill(0, count($to) + 1, 0);
        $cFrom = count($from);
        $cTo = count($to);
        for ($i = 0; $i < $cFrom; $i++) {
            $prev = $current;
            for ($j = 0; $j < $cTo; $j++) {
                if ($from[$i] === $to[$j]) {
                    $current[$j + 1] = $prev[$j] + 1;
                } else {
                    $current[$j + 1] = max($current[$j], $prev[$j + 1]);
                }
            }
        }
        return $current;
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

final class Diff
{
    /**
     * @var string
     */
    private $from;
    /**
     * @var string
     */
    private $to;
    /**
     * @var Chunk[]
     */
    private $chunks;
    /**
     * @param Chunk[] $chunks
     */
    public function __construct(string $from, string $to, array $chunks = [])
    {
        $this->from = $from;
        $this->to = $to;
        $this->chunks = $chunks;
    }
    public function getFrom() : string
    {
        return $this->from;
    }
    public function getTo() : string
    {
        return $this->to;
    }
    /**
     * @return Chunk[]
     */
    public function getChunks() : array
    {
        return $this->chunks;
    }
    /**
     * @param Chunk[] $chunks
     */
    public function setChunks(array $chunks) : void
    {
        $this->chunks = $chunks;
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

use const PHP_INT_SIZE;
use const PREG_SPLIT_DELIM_CAPTURE;
use const PREG_SPLIT_NO_EMPTY;
use function array_shift;
use function array_unshift;
use function array_values;
use function count;
use function current;
use function end;
use function get_class;
use function gettype;
use function is_array;
use function is_object;
use function is_string;
use function key;
use function min;
use function preg_split;
use function prev;
use function reset;
use function sprintf;
use function substr;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output\DiffOutputBuilderInterface;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;
final class Differ
{
    public const OLD = 0;
    public const ADDED = 1;
    public const REMOVED = 2;
    public const DIFF_LINE_END_WARNING = 3;
    public const NO_LINE_END_EOF_WARNING = 4;
    /**
     * @var DiffOutputBuilderInterface
     */
    private $outputBuilder;
    /**
     * @param DiffOutputBuilderInterface $outputBuilder
     *
     * @throws InvalidArgumentException
     */
    public function __construct($outputBuilder = null)
    {
        if ($outputBuilder instanceof DiffOutputBuilderInterface) {
            $this->outputBuilder = $outputBuilder;
        } elseif (null === $outputBuilder) {
            $this->outputBuilder = new UnifiedDiffOutputBuilder();
        } elseif (is_string($outputBuilder)) {
            // PHPUnit 6.1.4, 6.2.0, 6.2.1, 6.2.2, and 6.2.3 support
            // @see https://github.com/sebastianbergmann/phpunit/issues/2734#issuecomment-314514056
            // @deprecated
            $this->outputBuilder = new UnifiedDiffOutputBuilder($outputBuilder);
        } else {
            throw new InvalidArgumentException(sprintf('Expected builder to be an instance of DiffOutputBuilderInterface, <null> or a string, got %s.', is_object($outputBuilder) ? 'instance of "' . get_class($outputBuilder) . '"' : gettype($outputBuilder) . ' "' . $outputBuilder . '"'));
        }
    }
    /**
     * Returns the diff between two arrays or strings as string.
     *
     * @param array|string $from
     * @param array|string $to
     */
    public function diff($from, $to, LongestCommonSubsequenceCalculator $lcs = null) : string
    {
        $diff = $this->diffToArray($this->normalizeDiffInput($from), $this->normalizeDiffInput($to), $lcs);
        return $this->outputBuilder->getDiff($diff);
    }
    /**
     * Returns the diff between two arrays or strings as array.
     *
     * Each array element contains two elements:
     *   - [0] => mixed $token
     *   - [1] => 2|1|0
     *
     * - 2: REMOVED: $token was removed from $from
     * - 1: ADDED: $token was added to $from
     * - 0: OLD: $token is not changed in $to
     *
     * @param array|string                       $from
     * @param array|string                       $to
     * @param LongestCommonSubsequenceCalculator $lcs
     */
    public function diffToArray($from, $to, LongestCommonSubsequenceCalculator $lcs = null) : array
    {
        if (is_string($from)) {
            $from = $this->splitStringByLines($from);
        } elseif (!is_array($from)) {
            throw new InvalidArgumentException('"from" must be an array or string.');
        }
        if (is_string($to)) {
            $to = $this->splitStringByLines($to);
        } elseif (!is_array($to)) {
            throw new InvalidArgumentException('"to" must be an array or string.');
        }
        [$from, $to, $start, $end] = self::getArrayDiffParted($from, $to);
        if ($lcs === null) {
            $lcs = $this->selectLcsImplementation($from, $to);
        }
        $common = $lcs->calculate(array_values($from), array_values($to));
        $diff = [];
        foreach ($start as $token) {
            $diff[] = [$token, self::OLD];
        }
        reset($from);
        reset($to);
        foreach ($common as $token) {
            while (($fromToken = reset($from)) !== $token) {
                $diff[] = [array_shift($from), self::REMOVED];
            }
            while (($toToken = reset($to)) !== $token) {
                $diff[] = [array_shift($to), self::ADDED];
            }
            $diff[] = [$token, self::OLD];
            array_shift($from);
            array_shift($to);
        }
        while (($token = array_shift($from)) !== null) {
            $diff[] = [$token, self::REMOVED];
        }
        while (($token = array_shift($to)) !== null) {
            $diff[] = [$token, self::ADDED];
        }
        foreach ($end as $token) {
            $diff[] = [$token, self::OLD];
        }
        if ($this->detectUnmatchedLineEndings($diff)) {
            array_unshift($diff, ["#Warning: Strings contain different line endings!\n", self::DIFF_LINE_END_WARNING]);
        }
        return $diff;
    }
    /**
     * Casts variable to string if it is not a string or array.
     *
     * @return array|string
     */
    private function normalizeDiffInput($input)
    {
        if (!is_array($input) && !is_string($input)) {
            return (string) $input;
        }
        return $input;
    }
    /**
     * Checks if input is string, if so it will split it line-by-line.
     */
    private function splitStringByLines(string $input) : array
    {
        return preg_split('/(.*\\R)/', $input, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
    }
    private function selectLcsImplementation(array $from, array $to) : LongestCommonSubsequenceCalculator
    {
        // We do not want to use the time-efficient implementation if its memory
        // footprint will probably exceed this value. Note that the footprint
        // calculation is only an estimation for the matrix and the LCS method
        // will typically allocate a bit more memory than this.
        $memoryLimit = 100 * 1024 * 1024;
        if ($this->calculateEstimatedFootprint($from, $to) > $memoryLimit) {
            return new MemoryEfficientLongestCommonSubsequenceCalculator();
        }
        return new TimeEfficientLongestCommonSubsequenceCalculator();
    }
    /**
     * Calculates the estimated memory footprint for the DP-based method.
     *
     * @return float|int
     */
    private function calculateEstimatedFootprint(array $from, array $to)
    {
        $itemSize = PHP_INT_SIZE === 4 ? 76 : 144;
        return $itemSize * min(count($from), count($to)) ** 2;
    }
    /**
     * Returns true if line ends don't match in a diff.
     */
    private function detectUnmatchedLineEndings(array $diff) : bool
    {
        $newLineBreaks = ['' => \true];
        $oldLineBreaks = ['' => \true];
        foreach ($diff as $entry) {
            if (self::OLD === $entry[1]) {
                $ln = $this->getLinebreak($entry[0]);
                $oldLineBreaks[$ln] = \true;
                $newLineBreaks[$ln] = \true;
            } elseif (self::ADDED === $entry[1]) {
                $newLineBreaks[$this->getLinebreak($entry[0])] = \true;
            } elseif (self::REMOVED === $entry[1]) {
                $oldLineBreaks[$this->getLinebreak($entry[0])] = \true;
            }
        }
        // if either input or output is a single line without breaks than no warning should be raised
        if (['' => \true] === $newLineBreaks || ['' => \true] === $oldLineBreaks) {
            return \false;
        }
        // two way compare
        foreach ($newLineBreaks as $break => $set) {
            if (!isset($oldLineBreaks[$break])) {
                return \true;
            }
        }
        foreach ($oldLineBreaks as $break => $set) {
            if (!isset($newLineBreaks[$break])) {
                return \true;
            }
        }
        return \false;
    }
    private function getLinebreak($line) : string
    {
        if (!is_string($line)) {
            return '';
        }
        $lc = substr($line, -1);
        if ("\r" === $lc) {
            return "\r";
        }
        if ("\n" !== $lc) {
            return '';
        }
        if ("\r\n" === substr($line, -2)) {
            return "\r\n";
        }
        return "\n";
    }
    private static function getArrayDiffParted(array &$from, array &$to) : array
    {
        $start = [];
        $end = [];
        reset($to);
        foreach ($from as $k => $v) {
            $toK = key($to);
            if ($toK === $k && $v === $to[$k]) {
                $start[$k] = $v;
                unset($from[$k], $to[$k]);
            } else {
                break;
            }
        }
        end($from);
        end($to);
        do {
            $fromK = key($from);
            $toK = key($to);
            if (null === $fromK || null === $toK || current($from) !== current($to)) {
                break;
            }
            prev($from);
            prev($to);
            $end = [$fromK => $from[$fromK]] + $end;
            unset($from[$fromK], $to[$toK]);
        } while (\true);
        return [$from, $to, $start, $end];
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

use function array_pop;
use function count;
use function max;
use function preg_match;
use function preg_split;
/**
 * Unified diff parser.
 */
final class Parser
{
    /**
     * @return Diff[]
     */
    public function parse(string $string) : array
    {
        $lines = preg_split('(\\r\\n|\\r|\\n)', $string);
        if (!empty($lines) && $lines[count($lines) - 1] === '') {
            array_pop($lines);
        }
        $lineCount = count($lines);
        $diffs = [];
        $diff = null;
        $collected = [];
        for ($i = 0; $i < $lineCount; ++$i) {
            if (preg_match('#^---\\h+"?(?P<file>[^\\v\\t"]+)#', $lines[$i], $fromMatch) && preg_match('#^\\+\\+\\+\\h+"?(?P<file>[^\\v\\t"]+)#', $lines[$i + 1], $toMatch)) {
                if ($diff !== null) {
                    $this->parseFileDiff($diff, $collected);
                    $diffs[] = $diff;
                    $collected = [];
                }
                $diff = new Diff($fromMatch['file'], $toMatch['file']);
                ++$i;
            } else {
                if (preg_match('/^(?:diff --git |index [\\da-f\\.]+|[+-]{3} [ab])/', $lines[$i])) {
                    continue;
                }
                $collected[] = $lines[$i];
            }
        }
        if ($diff !== null && count($collected)) {
            $this->parseFileDiff($diff, $collected);
            $diffs[] = $diff;
        }
        return $diffs;
    }
    private function parseFileDiff(Diff $diff, array $lines) : void
    {
        $chunks = [];
        $chunk = null;
        $diffLines = [];
        foreach ($lines as $line) {
            if (preg_match('/^@@\\s+-(?P<start>\\d+)(?:,\\s*(?P<startrange>\\d+))?\\s+\\+(?P<end>\\d+)(?:,\\s*(?P<endrange>\\d+))?\\s+@@/', $line, $match)) {
                $chunk = new Chunk((int) $match['start'], isset($match['startrange']) ? max(1, (int) $match['startrange']) : 1, (int) $match['end'], isset($match['endrange']) ? max(1, (int) $match['endrange']) : 1);
                $chunks[] = $chunk;
                $diffLines = [];
                continue;
            }
            if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
                $type = Line::UNCHANGED;
                if ($match['type'] === '+') {
                    $type = Line::ADDED;
                } elseif ($match['type'] === '-') {
                    $type = Line::REMOVED;
                }
                $diffLines[] = new Line($type, $match['line']);
                if (null !== $chunk) {
                    $chunk->setLines($diffLines);
                }
            }
        }
        $diff->setChunks($chunks);
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output;

use function count;
abstract class AbstractChunkOutputBuilder implements DiffOutputBuilderInterface
{
    /**
     * Takes input of the diff array and returns the common parts.
     * Iterates through diff line by line.
     */
    protected function getCommonChunks(array $diff, int $lineThreshold = 5) : array
    {
        $diffSize = count($diff);
        $capturing = \false;
        $chunkStart = 0;
        $chunkSize = 0;
        $commonChunks = [];
        for ($i = 0; $i < $diffSize; ++$i) {
            if ($diff[$i][1] === 0) {
                if ($capturing === \false) {
                    $capturing = \true;
                    $chunkStart = $i;
                    $chunkSize = 0;
                } else {
                    ++$chunkSize;
                }
            } elseif ($capturing !== \false) {
                if ($chunkSize >= $lineThreshold) {
                    $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
                }
                $capturing = \false;
            }
        }
        if ($capturing !== \false && $chunkSize >= $lineThreshold) {
            $commonChunks[$chunkStart] = $chunkStart + $chunkSize;
        }
        return $commonChunks;
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output;

use function fclose;
use function fopen;
use function fwrite;
use function stream_get_contents;
use function substr;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Differ;
/**
 * Builds a diff string representation in a loose unified diff format
 * listing only changes lines. Does not include line numbers.
 */
final class DiffOnlyOutputBuilder implements DiffOutputBuilderInterface
{
    /**
     * @var string
     */
    private $header;
    public function __construct(string $header = "--- Original\n+++ New\n")
    {
        $this->header = $header;
    }
    public function getDiff(array $diff) : string
    {
        $buffer = fopen('php://memory', 'r+b');
        if ('' !== $this->header) {
            fwrite($buffer, $this->header);
            if ("\n" !== substr($this->header, -1, 1)) {
                fwrite($buffer, "\n");
            }
        }
        foreach ($diff as $diffEntry) {
            if ($diffEntry[1] === Differ::ADDED) {
                fwrite($buffer, '+' . $diffEntry[0]);
            } elseif ($diffEntry[1] === Differ::REMOVED) {
                fwrite($buffer, '-' . $diffEntry[0]);
            } elseif ($diffEntry[1] === Differ::DIFF_LINE_END_WARNING) {
                fwrite($buffer, ' ' . $diffEntry[0]);
                continue;
                // Warnings should not be tested for line break, it will always be there
            } else {
                /* Not changed (old) 0 */
                continue;
                // we didn't write the non changs line, so do not add a line break either
            }
            $lc = substr($diffEntry[0], -1);
            if ($lc !== "\n" && $lc !== "\r") {
                fwrite($buffer, "\n");
                // \No newline at end of file
            }
        }
        $diff = stream_get_contents($buffer, -1, 0);
        fclose($buffer);
        return $diff;
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output;

use function array_splice;
use function count;
use function fclose;
use function fopen;
use function fwrite;
use function max;
use function min;
use function stream_get_contents;
use function strlen;
use function substr;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Differ;
/**
 * Builds a diff string representation in unified diff format in chunks.
 */
final class UnifiedDiffOutputBuilder extends AbstractChunkOutputBuilder
{
    /**
     * @var bool
     */
    private $collapseRanges = \true;
    /**
     * @var int >= 0
     */
    private $commonLineThreshold = 6;
    /**
     * @var int >= 0
     */
    private $contextLines = 3;
    /**
     * @var string
     */
    private $header;
    /**
     * @var bool
     */
    private $addLineNumbers;
    public function __construct(string $header = "--- Original\n+++ New\n", bool $addLineNumbers = \false)
    {
        $this->header = $header;
        $this->addLineNumbers = $addLineNumbers;
    }
    public function getDiff(array $diff) : string
    {
        $buffer = fopen('php://memory', 'r+b');
        if ('' !== $this->header) {
            fwrite($buffer, $this->header);
            if ("\n" !== substr($this->header, -1, 1)) {
                fwrite($buffer, "\n");
            }
        }
        if (0 !== count($diff)) {
            $this->writeDiffHunks($buffer, $diff);
        }
        $diff = stream_get_contents($buffer, -1, 0);
        fclose($buffer);
        // If the diff is non-empty and last char is not a linebreak: add it.
        // This might happen when both the `from` and `to` do not have a trailing linebreak
        $last = substr($diff, -1);
        return 0 !== strlen($diff) && "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff;
    }
    private function writeDiffHunks($output, array $diff) : void
    {
        // detect "No newline at end of file" and insert into `$diff` if needed
        $upperLimit = count($diff);
        if (0 === $diff[$upperLimit - 1][1]) {
            $lc = substr($diff[$upperLimit - 1][0], -1);
            if ("\n" !== $lc) {
                array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
            }
        } else {
            // search back for the last `+` and `-` line,
            // check if has trailing linebreak, else add under it warning under it
            $toFind = [1 => \true, 2 => \true];
            for ($i = $upperLimit - 1; $i >= 0; --$i) {
                if (isset($toFind[$diff[$i][1]])) {
                    unset($toFind[$diff[$i][1]]);
                    $lc = substr($diff[$i][0], -1);
                    if ("\n" !== $lc) {
                        array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
                    }
                    if (!count($toFind)) {
                        break;
                    }
                }
            }
        }
        // write hunks to output buffer
        $cutOff = max($this->commonLineThreshold, $this->contextLines);
        $hunkCapture = \false;
        $sameCount = $toRange = $fromRange = 0;
        $toStart = $fromStart = 1;
        $i = 0;
        /** @var int $i */
        foreach ($diff as $i => $entry) {
            if (0 === $entry[1]) {
                // same
                if (\false === $hunkCapture) {
                    ++$fromStart;
                    ++$toStart;
                    continue;
                }
                ++$sameCount;
                ++$toRange;
                ++$fromRange;
                if ($sameCount === $cutOff) {
                    $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
                    // note: $contextEndOffset = $this->contextLines;
                    //
                    // because we never go beyond the end of the diff.
                    // with the cutoff/contextlines here the follow is never true;
                    //
                    // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
                    //    $contextEndOffset = count($diff) - 1;
                    // }
                    //
                    // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
                    $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output);
                    $fromStart += $fromRange;
                    $toStart += $toRange;
                    $hunkCapture = \false;
                    $sameCount = $toRange = $fromRange = 0;
                }
                continue;
            }
            $sameCount = 0;
            if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
                continue;
            }
            if (\false === $hunkCapture) {
                $hunkCapture = $i;
            }
            if (Differ::ADDED === $entry[1]) {
                ++$toRange;
            }
            if (Differ::REMOVED === $entry[1]) {
                ++$fromRange;
            }
        }
        if (\false === $hunkCapture) {
            return;
        }
        // we end here when cutoff (commonLineThreshold) was not reached, but we where capturing a hunk,
        // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
        $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
        // prevent trying to write out more common lines than there are in the diff _and_
        // do not write more than configured through the context lines
        $contextEndOffset = min($sameCount, $this->contextLines);
        $fromRange -= $sameCount;
        $toRange -= $sameCount;
        $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output);
    }
    private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output) : void
    {
        if ($this->addLineNumbers) {
            fwrite($output, '@@ -' . $fromStart);
            if (!$this->collapseRanges || 1 !== $fromRange) {
                fwrite($output, ',' . $fromRange);
            }
            fwrite($output, ' +' . $toStart);
            if (!$this->collapseRanges || 1 !== $toRange) {
                fwrite($output, ',' . $toRange);
            }
            fwrite($output, " @@\n");
        } else {
            fwrite($output, "@@ @@\n");
        }
        for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) {
            if ($diff[$i][1] === Differ::ADDED) {
                fwrite($output, '+' . $diff[$i][0]);
            } elseif ($diff[$i][1] === Differ::REMOVED) {
                fwrite($output, '-' . $diff[$i][0]);
            } elseif ($diff[$i][1] === Differ::OLD) {
                fwrite($output, ' ' . $diff[$i][0]);
            } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
                fwrite($output, "\n");
                // $diff[$i][0]
            } else {
                /* Not changed (old) Differ::OLD or Warning Differ::DIFF_LINE_END_WARNING */
                fwrite($output, ' ' . $diff[$i][0]);
            }
        }
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output;

use function array_merge;
use function array_splice;
use function count;
use function fclose;
use function fopen;
use function fwrite;
use function is_bool;
use function is_int;
use function is_string;
use function max;
use function min;
use function sprintf;
use function stream_get_contents;
use function substr;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\ConfigurationException;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Differ;
/**
 * Strict Unified diff output builder.
 *
 * Generates (strict) Unified diff's (unidiffs) with hunks.
 */
final class StrictUnifiedDiffOutputBuilder implements DiffOutputBuilderInterface
{
    private static $default = [
        'collapseRanges' => \true,
        // ranges of length one are rendered with the trailing `,1`
        'commonLineThreshold' => 6,
        // number of same lines before ending a new hunk and creating a new one (if needed)
        'contextLines' => 3,
        // like `diff:  -u, -U NUM, --unified[=NUM]`, for patch/git apply compatibility best to keep at least @ 3
        'fromFile' => null,
        'fromFileDate' => null,
        'toFile' => null,
        'toFileDate' => null,
    ];
    /**
     * @var bool
     */
    private $changed;
    /**
     * @var bool
     */
    private $collapseRanges;
    /**
     * @var int >= 0
     */
    private $commonLineThreshold;
    /**
     * @var string
     */
    private $header;
    /**
     * @var int >= 0
     */
    private $contextLines;
    public function __construct(array $options = [])
    {
        $options = array_merge(self::$default, $options);
        if (!is_bool($options['collapseRanges'])) {
            throw new ConfigurationException('collapseRanges', 'a bool', $options['collapseRanges']);
        }
        if (!is_int($options['contextLines']) || $options['contextLines'] < 0) {
            throw new ConfigurationException('contextLines', 'an int >= 0', $options['contextLines']);
        }
        if (!is_int($options['commonLineThreshold']) || $options['commonLineThreshold'] <= 0) {
            throw new ConfigurationException('commonLineThreshold', 'an int > 0', $options['commonLineThreshold']);
        }
        $this->assertString($options, 'fromFile');
        $this->assertString($options, 'toFile');
        $this->assertStringOrNull($options, 'fromFileDate');
        $this->assertStringOrNull($options, 'toFileDate');
        $this->header = sprintf("--- %s%s\n+++ %s%s\n", $options['fromFile'], null === $options['fromFileDate'] ? '' : "\t" . $options['fromFileDate'], $options['toFile'], null === $options['toFileDate'] ? '' : "\t" . $options['toFileDate']);
        $this->collapseRanges = $options['collapseRanges'];
        $this->commonLineThreshold = $options['commonLineThreshold'];
        $this->contextLines = $options['contextLines'];
    }
    public function getDiff(array $diff) : string
    {
        if (0 === count($diff)) {
            return '';
        }
        $this->changed = \false;
        $buffer = fopen('php://memory', 'r+b');
        fwrite($buffer, $this->header);
        $this->writeDiffHunks($buffer, $diff);
        if (!$this->changed) {
            fclose($buffer);
            return '';
        }
        $diff = stream_get_contents($buffer, -1, 0);
        fclose($buffer);
        // If the last char is not a linebreak: add it.
        // This might happen when both the `from` and `to` do not have a trailing linebreak
        $last = substr($diff, -1);
        return "\n" !== $last && "\r" !== $last ? $diff . "\n" : $diff;
    }
    private function writeDiffHunks($output, array $diff) : void
    {
        // detect "No newline at end of file" and insert into `$diff` if needed
        $upperLimit = count($diff);
        if (0 === $diff[$upperLimit - 1][1]) {
            $lc = substr($diff[$upperLimit - 1][0], -1);
            if ("\n" !== $lc) {
                array_splice($diff, $upperLimit, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
            }
        } else {
            // search back for the last `+` and `-` line,
            // check if has trailing linebreak, else add under it warning under it
            $toFind = [1 => \true, 2 => \true];
            for ($i = $upperLimit - 1; $i >= 0; --$i) {
                if (isset($toFind[$diff[$i][1]])) {
                    unset($toFind[$diff[$i][1]]);
                    $lc = substr($diff[$i][0], -1);
                    if ("\n" !== $lc) {
                        array_splice($diff, $i + 1, 0, [["\n\\ No newline at end of file\n", Differ::NO_LINE_END_EOF_WARNING]]);
                    }
                    if (!count($toFind)) {
                        break;
                    }
                }
            }
        }
        // write hunks to output buffer
        $cutOff = max($this->commonLineThreshold, $this->contextLines);
        $hunkCapture = \false;
        $sameCount = $toRange = $fromRange = 0;
        $toStart = $fromStart = 1;
        $i = 0;
        /** @var int $i */
        foreach ($diff as $i => $entry) {
            if (0 === $entry[1]) {
                // same
                if (\false === $hunkCapture) {
                    ++$fromStart;
                    ++$toStart;
                    continue;
                }
                ++$sameCount;
                ++$toRange;
                ++$fromRange;
                if ($sameCount === $cutOff) {
                    $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
                    // note: $contextEndOffset = $this->contextLines;
                    //
                    // because we never go beyond the end of the diff.
                    // with the cutoff/contextlines here the follow is never true;
                    //
                    // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
                    //    $contextEndOffset = count($diff) - 1;
                    // }
                    //
                    // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
                    $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output);
                    $fromStart += $fromRange;
                    $toStart += $toRange;
                    $hunkCapture = \false;
                    $sameCount = $toRange = $fromRange = 0;
                }
                continue;
            }
            $sameCount = 0;
            if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
                continue;
            }
            $this->changed = \true;
            if (\false === $hunkCapture) {
                $hunkCapture = $i;
            }
            if (Differ::ADDED === $entry[1]) {
                // added
                ++$toRange;
            }
            if (Differ::REMOVED === $entry[1]) {
                // removed
                ++$fromRange;
            }
        }
        if (\false === $hunkCapture) {
            return;
        }
        // we end here when cutoff (commonLineThreshold) was not reached, but we where capturing a hunk,
        // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
        $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
        // prevent trying to write out more common lines than there are in the diff _and_
        // do not write more than configured through the context lines
        $contextEndOffset = min($sameCount, $this->contextLines);
        $fromRange -= $sameCount;
        $toRange -= $sameCount;
        $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output);
    }
    private function writeHunk(array $diff, int $diffStartIndex, int $diffEndIndex, int $fromStart, int $fromRange, int $toStart, int $toRange, $output) : void
    {
        fwrite($output, '@@ -' . $fromStart);
        if (!$this->collapseRanges || 1 !== $fromRange) {
            fwrite($output, ',' . $fromRange);
        }
        fwrite($output, ' +' . $toStart);
        if (!$this->collapseRanges || 1 !== $toRange) {
            fwrite($output, ',' . $toRange);
        }
        fwrite($output, " @@\n");
        for ($i = $diffStartIndex; $i < $diffEndIndex; ++$i) {
            if ($diff[$i][1] === Differ::ADDED) {
                $this->changed = \true;
                fwrite($output, '+' . $diff[$i][0]);
            } elseif ($diff[$i][1] === Differ::REMOVED) {
                $this->changed = \true;
                fwrite($output, '-' . $diff[$i][0]);
            } elseif ($diff[$i][1] === Differ::OLD) {
                fwrite($output, ' ' . $diff[$i][0]);
            } elseif ($diff[$i][1] === Differ::NO_LINE_END_EOF_WARNING) {
                $this->changed = \true;
                fwrite($output, $diff[$i][0]);
            }
            //} elseif ($diff[$i][1] === Differ::DIFF_LINE_END_WARNING) { // custom comment inserted by PHPUnit/diff package
            //  skip
            //} else {
            //  unknown/invalid
            //}
        }
    }
    private function assertString(array $options, string $option) : void
    {
        if (!is_string($options[$option])) {
            throw new ConfigurationException($option, 'a string', $options[$option]);
        }
    }
    private function assertStringOrNull(array $options, string $option) : void
    {
        if (null !== $options[$option] && !is_string($options[$option])) {
            throw new ConfigurationException($option, 'a string or <null>', $options[$option]);
        }
    }
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output;

/**
 * Defines how an output builder should take a generated
 * diff array and return a string representation of that diff.
 */
interface DiffOutputBuilderInterface
{
    public function getDiff(array $diff) : string;
}
<?php

declare (strict_types=1);
/*
 * This file is part of sebastian/diff.
 *
 * (c) Sebastian Bergmann <sebastian@phpunit.de>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
namespace _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff;

use function array_reverse;
use function count;
use function max;
use SplFixedArray;
final class TimeEfficientLongestCommonSubsequenceCalculator implements LongestCommonSubsequenceCalculator
{
    /**
     * {@inheritdoc}
     */
    public function calculate(array $from, array $to) : array
    {
        $common = [];
        $fromLength = count($from);
        $toLength = count($to);
        $width = $fromLength + 1;
        $matrix = new SplFixedArray($width * ($toLength + 1));
        for ($i = 0; $i <= $fromLength; ++$i) {
            $matrix[$i] = 0;
        }
        for ($j = 0; $j <= $toLength; ++$j) {
            $matrix[$j * $width] = 0;
        }
        for ($i = 1; $i <= $fromLength; ++$i) {
            for ($j = 1; $j <= $toLength; ++$j) {
                $o = $j * $width + $i;
                $matrix[$o] = max($matrix[$o - 1], $matrix[$o - $width], $from[$i - 1] === $to[$j - 1] ? $matrix[$o - $width - 1] + 1 : 0);
            }
        }
        $i = $fromLength;
        $j = $toLength;
        while ($i > 0 && $j > 0) {
            if ($from[$i - 1] === $to[$j - 1]) {
                $common[] = $from[$i - 1];
                --$i;
                --$j;
            } else {
                $o = $j * $width + $i;
                if ($matrix[$o - $width] > $matrix[$o - 1]) {
                    --$j;
                } else {
                    --$i;
                }
            }
        }
        return array_reverse($common);
    }
}
sebastian/diff

Copyright (c) 2002-2020, Sebastian Bergmann <sebastian@phpunit.de>.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

 * Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in
   the documentation and/or other materials provided with the
   distribution.

 * Neither the name of Sebastian Bergmann nor the names of his
   contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

/**
 * When a rpc call is made, the Server MUST reply with a Response, except for in the case of Notifications. The Response
 * is expressed as a single JSON Object, with the following members:
 */
class ErrorResponse extends Response
{
    /**
     * This member is REQUIRED on error. This member MUST NOT exist if there was no error triggered during invocation.
     * The value for this member MUST be an Object as defined in section 5.1.
     *
     * @var \AdvancedJsonRpc\Error
     */
    public $error;
    /**
     * A message is considered a Response if it has an ID and either a result or an error
     *
     * @param object $msg A decoded message body
     * @return bool
     */
    public static function isErrorResponse($msg) : bool
    {
        return \is_object($msg) && isset($msg->id) && isset($msg->error);
    }
    /**
     * @param int|string $id
     * @param \AdvancedJsonRpc\Error $error
     */
    public function __construct($id, Error $error)
    {
        parent::__construct($id);
        $this->error = $error;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

/**
 * When a rpc call is made, the Server MUST reply with a Response, except for in the case of Notifications. The Response
 * is expressed as a single JSON Object, with the following members:
 */
abstract class Response extends Message
{
    /**
     * This member is REQUIRED. It MUST be the same as the value of the id member in the Request Object. If there was an
     * error in detecting the id in the Request object (e.g. Parse error/Invalid Request), it MUST be Null.
     *
     * @var int|string
     */
    public $id;
    /**
     * A message is considered a Response if it has an ID and either a result or an error
     *
     * @param object $msg A decoded message body
     * @return bool
     */
    public static function isResponse($msg) : bool
    {
        return \is_object($msg) && \property_exists($msg, 'id') && (\property_exists($msg, 'result') || isset($msg->error));
    }
    /**
     * @param int|string $id
     * @param mixed $result
     * @param ResponseError $error
     */
    public function __construct($id)
    {
        $this->id = $id;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

/**
 * The error codes from and including -32768 to -32000 are reserved for pre-defined errors. Any code within this range,
 * but not defined explicitly below is reserved for future use. The error codes are nearly the same as those suggested
 * for XML-RPC at the following url: http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php
 * The remainder of the space is available for application defined errors.
 */
abstract class ErrorCode
{
    /**
     * Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.
     */
    const PARSE_ERROR = -32700;
    /**
     * The JSON sent is not a valid Request object.
     */
    const INVALID_REQUEST = -32600;
    /**
     * The method does not exist / is not available.
     */
    const METHOD_NOT_FOUND = -32601;
    /**
     * Invalid method parameter(s).
     */
    const INVALID_PARAMS = -32602;
    /**
     * Internal JSON-RPC error.
     */
    const INTERNAL_ERROR = -32603;
    /**
     * Reserved for implementation-defined server-errors.
     */
    const SERVER_ERROR_START = -32099;
    /**
     * Reserved for implementation-defined server-errors.
     */
    const SERVER_ERROR_END = -32000;
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

/**
 * When a rpc call is made, the Server MUST reply with a Response, except for in the case of Notifications. The Response
 * is expressed as a single JSON Object, with the following members:
 */
class SuccessResponse extends Response
{
    /**
     * This member is REQUIRED on success. This member MUST NOT exist if there was an error invoking the method. The
     * value of this member is determined by the method invoked on the Server.
     *
     * @var mixed
     */
    public $result;
    /**
     * A message is considered a SuccessResponse if it has an ID and either a result
     *
     * @param object $msg A decoded message body
     * @return bool
     */
    public static function isSuccessResponse($msg) : bool
    {
        return \is_object($msg) && \property_exists($msg, 'id') && \property_exists($msg, 'result');
    }
    /**
     * @param int|string $id
     * @param mixed $result
     */
    public function __construct($id, $result)
    {
        parent::__construct($id);
        $this->result = $result;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

/**
 * A Notification is a Request object without an "id" member. A Request object that is a Notification signifies the
 * Client's lack of interest in the corresponding Response object, and as such no Response object needs to be returned
 * to the client. The Server MUST NOT reply to a Notification, including those that are within a batch request.
 * Notifications are not confirmable by definition, since they do not have a Response object to be returned. As such,
 * the Client would not be aware of any errors (like e.g. "Invalid params","Internal error").
 */
class Notification extends Message
{
    /**
     * A String containing the name of the method to be invoked. Method names that begin with the word rpc followed by a
     * period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and MUST NOT be used
     * for anything else.
     *
     * @var string
     */
    public $method;
    /**
     * A Structured value that holds the parameter values to be used during the invocation of the method. This member
     * MAY be omitted. If present, parameters for the rpc call MUST be provided as a Structured value. Either
     * by-position through an Array or by-name through an Object. by-position: params MUST be an Array, containing the
     * values in the Server expected order. by-name: params MUST be an Object, with member names that match the Server
     * expected parameter names. The absence of expected names MAY result in an error being generated. The names MUST
     * match exactly, including case, to the method's expected parameters.
     *
     * @var object|array|null
     */
    public $params;
    /**
     * A message is considered a Notification if it has a method but no ID.
     *
     * @param object $msg A decoded message body
     * @return bool
     */
    public static function isNotification($msg) : bool
    {
        return \is_object($msg) && !\property_exists($msg, 'id') && isset($msg->method);
    }
    /**
     * @param string $method
     * @param mixed $params
     */
    public function __construct(string $method, $params = null)
    {
        $this->method = $method;
        $this->params = $params;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

use _HumbugBox1cb33d1f20f1\JsonMapper;
use _HumbugBox1cb33d1f20f1\JsonMapper_Exception;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\DocBlockFactory;
use _HumbugBox1cb33d1f20f1\phpDocumentor\Reflection\Types;
use ReflectionException;
use ReflectionMethod;
use ReflectionNamedType;
class Dispatcher
{
    /**
     * @var object
     */
    private $target;
    /**
     * @var string
     */
    private $delimiter;
    /**
     * method => ReflectionMethod[]
     *
     * @var ReflectionMethod
     */
    private $methods;
    /**
     * @var \phpDocumentor\Reflection\DocBlockFactory
     */
    private $docBlockFactory;
    /**
     * @var \phpDocumentor\Reflection\Types\ContextFactory
     */
    private $contextFactory;
    /**
     * @param object $target    The target object that should receive the method calls
     * @param string $delimiter A delimiter for method calls on properties, for example someProperty->someMethod
     */
    public function __construct($target, $delimiter = '->')
    {
        $this->target = $target;
        $this->delimiter = $delimiter;
        $this->docBlockFactory = DocBlockFactory::createInstance();
        $this->contextFactory = new Types\ContextFactory();
        $this->mapper = new JsonMapper();
    }
    /**
     * Calls the appropriate method handler for an incoming Message
     *
     * @param string|object $msg The incoming message
     * @return mixed
     */
    public function dispatch($msg)
    {
        if (\is_string($msg)) {
            $msg = \json_decode($msg);
            if (\json_last_error() !== \JSON_ERROR_NONE) {
                throw new Error(\json_last_error_msg(), ErrorCode::PARSE_ERROR);
            }
        }
        // Find out the object and function that should be called
        $obj = $this->target;
        $parts = \explode($this->delimiter, $msg->method);
        // The function to call is always the last part of the method
        $fn = \array_pop($parts);
        // For namespaced methods like textDocument/didOpen, call the didOpen method on the $textDocument property
        // For simple methods like initialize, shutdown, exit, this loop will simply not be entered and $obj will be
        // the target
        foreach ($parts as $part) {
            if (!isset($obj->{$part})) {
                throw new Error("Method {$msg->method} is not implemented", ErrorCode::METHOD_NOT_FOUND);
            }
            $obj = $obj->{$part};
        }
        if (!isset($this->methods[$msg->method])) {
            try {
                $method = new ReflectionMethod($obj, $fn);
                $this->methods[$msg->method] = $method;
            } catch (ReflectionException $e) {
                throw new Error($e->getMessage(), ErrorCode::METHOD_NOT_FOUND, null, $e);
            }
        }
        $method = $this->methods[$msg->method];
        $parameters = $method->getParameters();
        if ($method->getDocComment()) {
            $docBlock = $this->docBlockFactory->create($method->getDocComment(), $this->contextFactory->createFromReflector($method->getDeclaringClass()));
            $paramTags = $docBlock->getTagsByName('param');
        }
        $args = [];
        if (isset($msg->params)) {
            // Find out the position
            if (\is_array($msg->params)) {
                $args = $msg->params;
            } else {
                if (\is_object($msg->params)) {
                    foreach ($parameters as $pos => $parameter) {
                        $value = null;
                        foreach (\get_object_vars($msg->params) as $key => $val) {
                            if ($parameter->name === $key) {
                                $value = $val;
                                break;
                            }
                        }
                        $args[$pos] = $value;
                    }
                } else {
                    throw new Error('Params must be structured or omitted', ErrorCode::INVALID_REQUEST);
                }
            }
            foreach ($args as $position => $value) {
                try {
                    // If the type is structured (array or object), map it with JsonMapper
                    if (\is_object($value)) {
                        // Does the parameter have a type hint?
                        $param = $parameters[$position];
                        if ($param->hasType()) {
                            $paramType = $param->getType();
                            if ($paramType instanceof ReflectionNamedType) {
                                // We have object data to map and want the class name.
                                // This should not include the `?` if the type was nullable.
                                $class = $paramType->getName();
                            } else {
                                // Fallback for php 7.0, which is still supported (and doesn't have nullable).
                                $class = (string) $paramType;
                            }
                            $value = $this->mapper->map($value, new $class());
                        }
                    } else {
                        if (\is_array($value) && isset($docBlock)) {
                            // Get the array type from the DocBlock
                            $type = $paramTags[$position]->getType();
                            // For union types, use the first one that is a class array (often it is SomeClass[]|null)
                            if ($type instanceof Types\Compound) {
                                for ($i = 0; $t = $type->get($i); $i++) {
                                    if ($t instanceof Types\Array_ && $t->getValueType() instanceof Types\Object_ && (string) $t->getValueType() !== 'object') {
                                        $class = (string) $t->getValueType()->getFqsen();
                                        $value = $this->mapper->mapArray($value, [], $class);
                                        break;
                                    }
                                }
                            } else {
                                if ($type instanceof Types\Array_) {
                                    $class = (string) $type->getValueType()->getFqsen();
                                    $value = $this->mapper->mapArray($value, [], $class);
                                } else {
                                    throw new Error('Type is not matching @param tag', ErrorCode::INVALID_PARAMS);
                                }
                            }
                        }
                    }
                } catch (JsonMapper_Exception $e) {
                    throw new Error($e->getMessage(), ErrorCode::INVALID_PARAMS, null, $e);
                }
                $args[$position] = $value;
            }
        }
        \ksort($args);
        $result = $obj->{$fn}(...$args);
        return $result;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

/**
 * Base message
 */
abstract class Message
{
    /**
     * A String specifying the version of the JSON-RPC protocol. MUST be exactly "2.0".
     *
     * @var string
     */
    public $jsonrpc = '2.0';
    /**
     * Returns the appropriate Message subclass
     *
     * @param string $msg
     * @return Message
     */
    public static function parse(string $msg) : Message
    {
        $decoded = \json_decode($msg);
        if (\json_last_error() !== \JSON_ERROR_NONE) {
            throw new Error(\json_last_error_msg(), ErrorCode::PARSE_ERROR);
        }
        if (Notification::isNotification($decoded)) {
            $obj = new Notification($decoded->method, $decoded->params ?? null);
        } else {
            if (Request::isRequest($decoded)) {
                $obj = new Request($decoded->id, $decoded->method, $decoded->params ?? null);
            } else {
                if (SuccessResponse::isSuccessResponse($decoded)) {
                    $obj = new SuccessResponse($decoded->id, $decoded->result);
                } else {
                    if (ErrorResponse::isErrorResponse($decoded)) {
                        $obj = new ErrorResponse($decoded->id, new Error($decoded->error->message, $decoded->error->code, $decoded->error->data ?? null));
                    } else {
                        throw new Error('Invalid message', ErrorCode::INVALID_REQUEST);
                    }
                }
            }
        }
        return $obj;
    }
    public function __toString() : string
    {
        $encoded = \json_encode($this);
        if ($encoded === \false) {
            throw new Error(\json_last_error_msg(), ErrorCode::INTERNAL_ERROR);
        }
        return $encoded;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

use Exception;
use Throwable;
class Error extends Exception
{
    /**
     * A Number that indicates the error type that occurred. This MUST be an integer.
     *
     * @var int
     */
    public $code;
    /**
     * A String providing a short description of the error. The message SHOULD be limited to a concise single sentence.
     *
     * @var string
     */
    public $message;
    /**
     * A Primitive or Structured value that contains additional information about the error. This may be omitted. The
     * value of this member is defined by the Server (e.g. detailed error information, nested errors etc.).
     *
     * @var mixed
     */
    public $data;
    public function __construct(string $message, int $code, $data = null, Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
        $this->data = $data;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\AdvancedJsonRpc;

/**
 * A rpc call is represented by sending a Request object to a Server
 */
class Request extends Message
{
    /**
     * An identifier established by the Client that MUST contain a String, Number, or NULL value if included. If it is
     * not included it is assumed to be a notification. The value SHOULD normally not be NULL and Numbers SHOULD NOT
     * contain fractional parts.
     *
     * @var int|string
     */
    public $id;
    /**
     * A String containing the name of the method to be invoked. Method names that begin with the word rpc followed by a
     * period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and MUST NOT be used
     * for anything else.
     *
     * @var string
     */
    public $method;
    /**
     * A Structured value that holds the parameter values to be used during the invocation of the method. This member
     * MAY be omitted. If present, parameters for the rpc call MUST be provided as a Structured value. Either
     * by-position through an Array or by-name through an Object. by-position: params MUST be an Array, containing the
     * values in the Server expected order. by-name: params MUST be an Object, with member names that match the Server
     * expected parameter names. The absence of expected names MAY result in an error being generated. The names MUST
     * match exactly, including case, to the method's expected parameters.
     *
     * @var object|array|null
     */
    public $params;
    /**
     * A message is considered a Request if it has an ID and a method.
     *
     * @param object $msg A decoded message body
     * @return bool
     */
    public static function isRequest($msg) : bool
    {
        return \is_object($msg) && \property_exists($msg, 'id') && isset($msg->method);
    }
    /**
     * @param string|int $id
     * @param string $method
     * @param object|array $params
     */
    public function __construct($id, string $method, $params = null)
    {
        $this->id = $id;
        $this->method = $method;
        $this->params = $params;
    }
}
ISC License

Copyright (c) 2016, Felix Frederick Becker

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
{
  "name": "php-language-server-protocol",
  "version": "1.0.0",
  "lockfileVersion": 1,
  "requires": true,
  "dependencies": {
    "@mrmlnc/readdir-enhanced": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
      "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
      "dev": true,
      "requires": {
        "call-me-maybe": "^1.0.1",
        "glob-to-regexp": "^0.3.0"
      }
    },
    "@nodelib/fs.stat": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.2.tgz",
      "integrity": "sha512-yprFYuno9FtNsSHVlSWd+nRlmGoAbqbeCwOryP6sC/zoCjhpArcRMYp19EvpSUSizJAlsXEwJv+wcWS9XaXdMw==",
      "dev": true
    },
    "@octokit/rest": {
      "version": "15.12.0",
      "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.12.0.tgz",
      "integrity": "sha512-5wRag4kHRkp0JDo++L9x9FkDlHEALbLnbSede16D8u+a2/t+gX32uhDs8cukVLyyrZR79nmh1lNpxZmffwoNoQ==",
      "dev": true,
      "requires": {
        "before-after-hook": "^1.1.0",
        "btoa-lite": "^1.0.0",
        "debug": "^3.1.0",
        "http-proxy-agent": "^2.1.0",
        "https-proxy-agent": "^2.2.0",
        "lodash": "^4.17.4",
        "node-fetch": "^2.1.1",
        "universal-user-agent": "^2.0.0",
        "url-template": "^2.0.8"
      },
      "dependencies": {
        "debug": {
          "version": "3.2.5",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
          "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
          "dev": true,
          "requires": {
            "ms": "^2.1.1"
          }
        }
      }
    },
    "@semantic-release/commit-analyzer": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-6.0.1.tgz",
      "integrity": "sha512-ENCRn1tm1D08CCBnIPsID8GjboWT6E97s0Lk3XrpAh+IMx615uAU1X2FoXyOGGc6zmqp9Ff4s8KECd/GjMcodQ==",
      "dev": true,
      "requires": {
        "conventional-changelog-angular": "^5.0.0",
        "conventional-commits-filter": "^2.0.0",
        "conventional-commits-parser": "^3.0.0",
        "debug": "^4.0.0",
        "import-from": "^2.1.0",
        "lodash": "^4.17.4"
      }
    },
    "@semantic-release/error": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz",
      "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==",
      "dev": true
    },
    "@semantic-release/github": {
      "version": "5.0.5",
      "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-5.0.5.tgz",
      "integrity": "sha512-Hdt6b8ST2pg6pl151PlcsnTcdsC2UJhA5FdbmunbZG/TVmlnKCZ4WUzpji7YqJtDLjbQTuFm/vhM6atW3XjMWg==",
      "dev": true,
      "requires": {
        "@octokit/rest": "^15.2.0",
        "@semantic-release/error": "^2.2.0",
        "aggregate-error": "^1.0.0",
        "bottleneck": "^2.0.1",
        "debug": "^4.0.0",
        "dir-glob": "^2.0.0",
        "fs-extra": "^7.0.0",
        "globby": "^8.0.0",
        "http-proxy-agent": "^2.1.0",
        "https-proxy-agent": "^2.2.1",
        "issue-parser": "^3.0.0",
        "lodash": "^4.17.4",
        "mime": "^2.0.3",
        "p-filter": "^1.0.0",
        "p-retry": "^2.0.0",
        "parse-github-url": "^1.0.1",
        "url-join": "^4.0.0"
      }
    },
    "@semantic-release/npm": {
      "version": "5.0.4",
      "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-5.0.4.tgz",
      "integrity": "sha512-ExGXP9GnM2hqUIgTnp6sXKB1G0Yh+fuLftmIopq5KHBWj34Wd2YbM/3iLkXXnAP1YZ9YCp7hsAdsR014ctbwHg==",
      "dev": true,
      "requires": {
        "@semantic-release/error": "^2.2.0",
        "aggregate-error": "^1.0.0",
        "detect-indent": "^5.0.0",
        "detect-newline": "^2.1.0",
        "execa": "^1.0.0",
        "fs-extra": "^7.0.0",
        "lodash": "^4.17.4",
        "nerf-dart": "^1.0.0",
        "normalize-url": "^3.0.0",
        "npm": "^6.3.0",
        "parse-json": "^4.0.0",
        "rc": "^1.2.8",
        "read-pkg": "^4.0.0",
        "registry-auth-token": "^3.3.1"
      },
      "dependencies": {
        "read-pkg": {
          "version": "4.0.1",
          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz",
          "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=",
          "dev": true,
          "requires": {
            "normalize-package-data": "^2.3.2",
            "parse-json": "^4.0.0",
            "pify": "^3.0.0"
          }
        }
      }
    },
    "@semantic-release/release-notes-generator": {
      "version": "7.0.2",
      "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-7.0.2.tgz",
      "integrity": "sha512-fomHrGq/gfZIAQYZk0MLRwfQ8d+DbTcI3kuO1hU2L0fDJYKHZHuPmKnsfVa5KoNdVVPHx878D/ojgyStRqhc9g==",
      "dev": true,
      "requires": {
        "conventional-changelog-angular": "^5.0.0",
        "conventional-changelog-writer": "^4.0.0",
        "conventional-commits-filter": "^2.0.0",
        "conventional-commits-parser": "^3.0.0",
        "debug": "^4.0.0",
        "get-stream": "^4.0.0",
        "git-url-parse": "^10.0.1",
        "import-from": "^2.1.0",
        "into-stream": "^3.1.0",
        "lodash": "^4.17.4"
      }
    },
    "JSONStream": {
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.4.tgz",
      "integrity": "sha512-Y7vfi3I5oMOYIr+WxV8NZxDSwcbNgzdKYsTNInmycOq9bUYwGg9ryu57Wg5NLmCjqdFPNUmpMBo3kSJN9tCbXg==",
      "dev": true,
      "requires": {
        "jsonparse": "^1.2.0",
        "through": ">=2.2.7 <3"
      }
    },
    "agent-base": {
      "version": "4.2.1",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
      "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
      "dev": true,
      "requires": {
        "es6-promisify": "^5.0.0"
      }
    },
    "aggregate-error": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-1.0.0.tgz",
      "integrity": "sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w=",
      "dev": true,
      "requires": {
        "clean-stack": "^1.0.0",
        "indent-string": "^3.0.0"
      }
    },
    "ansi-regex": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
      "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
      "dev": true
    },
    "ansi-styles": {
      "version": "3.2.1",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
      "dev": true,
      "requires": {
        "color-convert": "^1.9.0"
      }
    },
    "ansicolors": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz",
      "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=",
      "dev": true
    },
    "argparse": {
      "version": "1.0.10",
      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
      "dev": true,
      "requires": {
        "sprintf-js": "~1.0.2"
      }
    },
    "argv-formatter": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz",
      "integrity": "sha1-oMoMvCmltz6Dbuvhy/bF4OTrgvk=",
      "dev": true
    },
    "arr-diff": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
      "dev": true
    },
    "arr-flatten": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
      "dev": true
    },
    "arr-union": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
      "dev": true
    },
    "array-find-index": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
      "dev": true
    },
    "array-ify": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
      "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=",
      "dev": true
    },
    "array-union": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
      "dev": true,
      "requires": {
        "array-uniq": "^1.0.1"
      }
    },
    "array-uniq": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
      "dev": true
    },
    "array-unique": {
      "version": "0.3.2",
      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
      "dev": true
    },
    "arrify": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
      "dev": true
    },
    "assign-symbols": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
      "dev": true
    },
    "async": {
      "version": "2.6.1",
      "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
      "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
      "dev": true,
      "requires": {
        "lodash": "^4.17.10"
      }
    },
    "atob": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
      "dev": true
    },
    "balanced-match": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
      "dev": true
    },
    "base": {
      "version": "0.11.2",
      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
      "dev": true,
      "requires": {
        "cache-base": "^1.0.1",
        "class-utils": "^0.3.5",
        "component-emitter": "^1.2.1",
        "define-property": "^1.0.0",
        "isobject": "^3.0.1",
        "mixin-deep": "^1.2.0",
        "pascalcase": "^0.1.1"
      },
      "dependencies": {
        "define-property": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^1.0.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-data-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-descriptor": {
          "version": "1.0.2",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^1.0.0",
            "is-data-descriptor": "^1.0.0",
            "kind-of": "^6.0.2"
          }
        }
      }
    },
    "before-after-hook": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.1.0.tgz",
      "integrity": "sha512-VOMDtYPwLbIncTxNoSzRyvaMxtXmLWLUqr8k5AfC1BzLk34HvBXaQX8snOwQZ4c0aX8aSERqtJSiI9/m2u5kuA==",
      "dev": true
    },
    "bottleneck": {
      "version": "2.11.0",
      "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.11.0.tgz",
      "integrity": "sha512-DvKiYR1kG1qRVoLBUtPlmJffktoBZIz3qtdUbINlwzQXDhlhZdF8gWesPjwp05xqr5QZ7wXA2k1w78/COCweTg==",
      "dev": true
    },
    "brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "dev": true,
      "requires": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "braces": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
      "dev": true,
      "requires": {
        "arr-flatten": "^1.1.0",
        "array-unique": "^0.3.2",
        "extend-shallow": "^2.0.1",
        "fill-range": "^4.0.0",
        "isobject": "^3.0.1",
        "repeat-element": "^1.1.2",
        "snapdragon": "^0.8.1",
        "snapdragon-node": "^2.0.1",
        "split-string": "^3.0.2",
        "to-regex": "^3.0.1"
      },
      "dependencies": {
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        }
      }
    },
    "btoa-lite": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
      "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=",
      "dev": true
    },
    "builtin-modules": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
      "dev": true
    },
    "cache-base": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
      "dev": true,
      "requires": {
        "collection-visit": "^1.0.0",
        "component-emitter": "^1.2.1",
        "get-value": "^2.0.6",
        "has-value": "^1.0.0",
        "isobject": "^3.0.1",
        "set-value": "^2.0.0",
        "to-object-path": "^0.3.0",
        "union-value": "^1.0.0",
        "unset-value": "^1.0.0"
      }
    },
    "call-me-maybe": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
      "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
      "dev": true
    },
    "camelcase": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
      "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
      "dev": true
    },
    "camelcase-keys": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz",
      "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=",
      "dev": true,
      "requires": {
        "camelcase": "^4.1.0",
        "map-obj": "^2.0.0",
        "quick-lru": "^1.0.0"
      }
    },
    "cardinal": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz",
      "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=",
      "dev": true,
      "requires": {
        "ansicolors": "~0.3.2",
        "redeyed": "~2.1.0"
      }
    },
    "chalk": {
      "version": "2.4.1",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
      "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
      "dev": true,
      "requires": {
        "ansi-styles": "^3.2.1",
        "escape-string-regexp": "^1.0.5",
        "supports-color": "^5.3.0"
      }
    },
    "class-utils": {
      "version": "0.3.6",
      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
      "dev": true,
      "requires": {
        "arr-union": "^3.1.0",
        "define-property": "^0.2.5",
        "isobject": "^3.0.0",
        "static-extend": "^0.1.1"
      },
      "dependencies": {
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        }
      }
    },
    "clean-stack": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz",
      "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=",
      "dev": true
    },
    "cli-table": {
      "version": "0.3.1",
      "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
      "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
      "dev": true,
      "requires": {
        "colors": "1.0.3"
      }
    },
    "cliui": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
      "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
      "dev": true,
      "requires": {
        "string-width": "^2.1.1",
        "strip-ansi": "^4.0.0",
        "wrap-ansi": "^2.0.0"
      }
    },
    "code-point-at": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
      "dev": true
    },
    "collection-visit": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
      "dev": true,
      "requires": {
        "map-visit": "^1.0.0",
        "object-visit": "^1.0.0"
      }
    },
    "color-convert": {
      "version": "1.9.3",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
      "dev": true,
      "requires": {
        "color-name": "1.1.3"
      }
    },
    "color-name": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
      "dev": true
    },
    "colors": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
      "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
      "dev": true
    },
    "commander": {
      "version": "2.17.1",
      "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
      "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
      "dev": true,
      "optional": true
    },
    "compare-func": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz",
      "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=",
      "dev": true,
      "requires": {
        "array-ify": "^1.0.0",
        "dot-prop": "^3.0.0"
      }
    },
    "component-emitter": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
      "dev": true
    },
    "concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
      "dev": true
    },
    "conventional-changelog-angular": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.1.tgz",
      "integrity": "sha512-q4ylJ68fWZDdrFC9z4zKcf97HW6hp7Mo2YlqD4owfXhecFKy/PJCU/1oVFF4TqochchChqmZ0Vb0e0g8/MKNlA==",
      "dev": true,
      "requires": {
        "compare-func": "^1.3.1",
        "q": "^1.5.1"
      }
    },
    "conventional-changelog-writer": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.0.tgz",
      "integrity": "sha512-hMZPe0AQ6Bi05epeK/7hz80xxk59nPA5z/b63TOHq2wigM0/akreOc8N4Jam5b9nFgKWX1e9PdPv2ewgW6bcfg==",
      "dev": true,
      "requires": {
        "compare-func": "^1.3.1",
        "conventional-commits-filter": "^2.0.0",
        "dateformat": "^3.0.0",
        "handlebars": "^4.0.2",
        "json-stringify-safe": "^5.0.1",
        "lodash": "^4.2.1",
        "meow": "^4.0.0",
        "semver": "^5.5.0",
        "split": "^1.0.0",
        "through2": "^2.0.0"
      }
    },
    "conventional-commits-filter": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.0.tgz",
      "integrity": "sha512-Cfl0j1/NquB/TMVx7Wrmyq7uRM+/rPQbtVVGwzfkhZ6/yH6fcMmP0Q/9044TBZPTNdGzm46vXFXL14wbET0/Mg==",
      "dev": true,
      "requires": {
        "is-subset": "^0.1.1",
        "modify-values": "^1.0.0"
      }
    },
    "conventional-commits-parser": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.0.tgz",
      "integrity": "sha512-GWh71U26BLWgMykCp+VghZ4s64wVbtseECcKQ/PvcPZR2cUnz+FUc2J9KjxNl7/ZbCxST8R03c9fc+Vi0umS9Q==",
      "dev": true,
      "requires": {
        "JSONStream": "^1.0.4",
        "is-text-path": "^1.0.0",
        "lodash": "^4.2.1",
        "meow": "^4.0.0",
        "split2": "^2.0.0",
        "through2": "^2.0.0",
        "trim-off-newlines": "^1.0.0"
      }
    },
    "copy-descriptor": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
      "dev": true
    },
    "core-util-is": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
      "dev": true
    },
    "cosmiconfig": {
      "version": "5.0.6",
      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.6.tgz",
      "integrity": "sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ==",
      "dev": true,
      "requires": {
        "is-directory": "^0.3.1",
        "js-yaml": "^3.9.0",
        "parse-json": "^4.0.0"
      }
    },
    "cross-spawn": {
      "version": "6.0.5",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
      "dev": true,
      "requires": {
        "nice-try": "^1.0.4",
        "path-key": "^2.0.1",
        "semver": "^5.5.0",
        "shebang-command": "^1.2.0",
        "which": "^1.2.9"
      }
    },
    "currently-unhandled": {
      "version": "0.4.1",
      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
      "dev": true,
      "requires": {
        "array-find-index": "^1.0.1"
      }
    },
    "dateformat": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
      "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
      "dev": true
    },
    "debug": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.0.1.tgz",
      "integrity": "sha512-K23FHJ/Mt404FSlp6gSZCevIbTMLX0j3fmHhUEhQ3Wq0FMODW3+cUSoLdy1Gx4polAf4t/lphhmHH35BB8cLYw==",
      "dev": true,
      "requires": {
        "ms": "^2.1.1"
      }
    },
    "decamelize": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
      "dev": true
    },
    "decamelize-keys": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
      "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
      "dev": true,
      "requires": {
        "decamelize": "^1.1.0",
        "map-obj": "^1.0.0"
      },
      "dependencies": {
        "map-obj": {
          "version": "1.0.1",
          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
          "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
          "dev": true
        }
      }
    },
    "decode-uri-component": {
      "version": "0.2.0",
      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
      "dev": true
    },
    "deep-extend": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
      "dev": true
    },
    "define-property": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
      "dev": true,
      "requires": {
        "is-descriptor": "^1.0.2",
        "isobject": "^3.0.1"
      },
      "dependencies": {
        "is-accessor-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-data-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-descriptor": {
          "version": "1.0.2",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^1.0.0",
            "is-data-descriptor": "^1.0.0",
            "kind-of": "^6.0.2"
          }
        }
      }
    },
    "detect-indent": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz",
      "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=",
      "dev": true
    },
    "detect-newline": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
      "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
      "dev": true
    },
    "dir-glob": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz",
      "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==",
      "dev": true,
      "requires": {
        "arrify": "^1.0.1",
        "path-type": "^3.0.0"
      }
    },
    "dot-prop": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz",
      "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=",
      "dev": true,
      "requires": {
        "is-obj": "^1.0.0"
      }
    },
    "duplexer2": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
      "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
      "dev": true,
      "requires": {
        "readable-stream": "^2.0.2"
      }
    },
    "end-of-stream": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
      "dev": true,
      "requires": {
        "once": "^1.4.0"
      }
    },
    "env-ci": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-3.0.0.tgz",
      "integrity": "sha512-3Xt4Cfjdy9MTTrg/eWTnJNQIrtU1DDV0KyuWOGlrR2oa9dOdzoOMbQBFbfrTiv+GypdiWWIw5HdmtakZO+rzWA==",
      "dev": true,
      "requires": {
        "execa": "^1.0.0",
        "java-properties": "^0.2.9"
      }
    },
    "error-ex": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
      "dev": true,
      "requires": {
        "is-arrayish": "^0.2.1"
      }
    },
    "es6-promise": {
      "version": "4.2.5",
      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz",
      "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
      "dev": true
    },
    "es6-promisify": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
      "dev": true,
      "requires": {
        "es6-promise": "^4.0.3"
      }
    },
    "escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
      "dev": true
    },
    "esprima": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
      "dev": true
    },
    "execa": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
      "dev": true,
      "requires": {
        "cross-spawn": "^6.0.0",
        "get-stream": "^4.0.0",
        "is-stream": "^1.1.0",
        "npm-run-path": "^2.0.0",
        "p-finally": "^1.0.0",
        "signal-exit": "^3.0.0",
        "strip-eof": "^1.0.0"
      }
    },
    "expand-brackets": {
      "version": "2.1.4",
      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
      "dev": true,
      "requires": {
        "debug": "^2.3.3",
        "define-property": "^0.2.5",
        "extend-shallow": "^2.0.1",
        "posix-character-classes": "^0.1.0",
        "regex-not": "^1.0.0",
        "snapdragon": "^0.8.1",
        "to-regex": "^3.0.1"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "extend-shallow": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
      "dev": true,
      "requires": {
        "assign-symbols": "^1.0.0",
        "is-extendable": "^1.0.1"
      },
      "dependencies": {
        "is-extendable": {
          "version": "1.0.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
          "dev": true,
          "requires": {
            "is-plain-object": "^2.0.4"
          }
        }
      }
    },
    "extglob": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
      "dev": true,
      "requires": {
        "array-unique": "^0.3.2",
        "define-property": "^1.0.0",
        "expand-brackets": "^2.1.4",
        "extend-shallow": "^2.0.1",
        "fragment-cache": "^0.2.1",
        "regex-not": "^1.0.0",
        "snapdragon": "^0.8.1",
        "to-regex": "^3.0.1"
      },
      "dependencies": {
        "define-property": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^1.0.0"
          }
        },
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-data-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-descriptor": {
          "version": "1.0.2",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^1.0.0",
            "is-data-descriptor": "^1.0.0",
            "kind-of": "^6.0.2"
          }
        }
      }
    },
    "fast-glob": {
      "version": "2.2.2",
      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.2.tgz",
      "integrity": "sha512-TR6zxCKftDQnUAPvkrCWdBgDq/gbqx8A3ApnBrR5rMvpp6+KMJI0Igw7fkWPgeVK0uhRXTXdvO3O+YP0CaUX2g==",
      "dev": true,
      "requires": {
        "@mrmlnc/readdir-enhanced": "^2.2.1",
        "@nodelib/fs.stat": "^1.0.1",
        "glob-parent": "^3.1.0",
        "is-glob": "^4.0.0",
        "merge2": "^1.2.1",
        "micromatch": "^3.1.10"
      }
    },
    "figures": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
      "dev": true,
      "requires": {
        "escape-string-regexp": "^1.0.5"
      }
    },
    "fill-range": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
      "dev": true,
      "requires": {
        "extend-shallow": "^2.0.1",
        "is-number": "^3.0.0",
        "repeat-string": "^1.6.1",
        "to-regex-range": "^2.1.0"
      },
      "dependencies": {
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        }
      }
    },
    "find-up": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
      "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
      "dev": true,
      "requires": {
        "locate-path": "^2.0.0"
      }
    },
    "find-versions": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-2.0.0.tgz",
      "integrity": "sha1-KtkNSQ9oKMGqQCks9wmsMxghDDw=",
      "dev": true,
      "requires": {
        "array-uniq": "^1.0.0",
        "semver-regex": "^1.0.0"
      }
    },
    "for-in": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
      "dev": true
    },
    "fragment-cache": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
      "dev": true,
      "requires": {
        "map-cache": "^0.2.2"
      }
    },
    "from2": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
      "dev": true,
      "requires": {
        "inherits": "^2.0.1",
        "readable-stream": "^2.0.0"
      }
    },
    "fs-extra": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz",
      "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==",
      "dev": true,
      "requires": {
        "graceful-fs": "^4.1.2",
        "jsonfile": "^4.0.0",
        "universalify": "^0.1.0"
      }
    },
    "fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
      "dev": true
    },
    "get-caller-file": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
      "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
      "dev": true
    },
    "get-stream": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.0.0.tgz",
      "integrity": "sha512-FneLKMENeOR7wOK0/ZXCh+lwqtnPwkeunJjRN28LPqzGvNAhYvrTAhXv6xDm4vsJ0M7lcRbIYHQudKsSy2RtSQ==",
      "dev": true,
      "requires": {
        "pump": "^3.0.0"
      }
    },
    "get-value": {
      "version": "2.0.6",
      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
      "dev": true
    },
    "git-log-parser": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz",
      "integrity": "sha1-LmpMGxP8AAKCB7p5WnrDFme5/Uo=",
      "dev": true,
      "requires": {
        "argv-formatter": "~1.0.0",
        "spawn-error-forwarder": "~1.0.0",
        "split2": "~1.0.0",
        "stream-combiner2": "~1.1.1",
        "through2": "~2.0.0",
        "traverse": "~0.6.6"
      },
      "dependencies": {
        "split2": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz",
          "integrity": "sha1-UuLiIdiMdfmnP5BVbiY/+WdysxQ=",
          "dev": true,
          "requires": {
            "through2": "~2.0.0"
          }
        }
      }
    },
    "git-up": {
      "version": "2.0.10",
      "resolved": "https://registry.npmjs.org/git-up/-/git-up-2.0.10.tgz",
      "integrity": "sha512-2v4UN3qV2RGypD9QpmUjpk+4+RlYpW8GFuiZqQnKmvei08HsFPd0RfbDvEhnE4wBvnYs8ORVtYpOFuuCEmBVBw==",
      "dev": true,
      "requires": {
        "is-ssh": "^1.3.0",
        "parse-url": "^1.3.0"
      }
    },
    "git-url-parse": {
      "version": "10.0.1",
      "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-10.0.1.tgz",
      "integrity": "sha512-Tq2u8UPXc/FawC/dO8bvh8jcck0Lkor5OhuZvmVSeyJGRucDBfw9y2zy/GNCx28lMYh1N12IzPwDexjUNFyAeg==",
      "dev": true,
      "requires": {
        "git-up": "^2.0.0"
      }
    },
    "glob": {
      "version": "7.1.3",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
      "dev": true,
      "requires": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.0.4",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      }
    },
    "glob-parent": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
      "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
      "dev": true,
      "requires": {
        "is-glob": "^3.1.0",
        "path-dirname": "^1.0.0"
      },
      "dependencies": {
        "is-glob": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
          "dev": true,
          "requires": {
            "is-extglob": "^2.1.0"
          }
        }
      }
    },
    "glob-to-regexp": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
      "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
      "dev": true
    },
    "globby": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
      "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==",
      "dev": true,
      "requires": {
        "array-union": "^1.0.1",
        "dir-glob": "^2.0.0",
        "fast-glob": "^2.0.2",
        "glob": "^7.1.2",
        "ignore": "^3.3.5",
        "pify": "^3.0.0",
        "slash": "^1.0.0"
      }
    },
    "graceful-fs": {
      "version": "4.1.11",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
      "dev": true
    },
    "handlebars": {
      "version": "4.0.12",
      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz",
      "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==",
      "dev": true,
      "requires": {
        "async": "^2.5.0",
        "optimist": "^0.6.1",
        "source-map": "^0.6.1",
        "uglify-js": "^3.1.4"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true
        }
      }
    },
    "has-flag": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
      "dev": true
    },
    "has-value": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
      "dev": true,
      "requires": {
        "get-value": "^2.0.6",
        "has-values": "^1.0.0",
        "isobject": "^3.0.0"
      }
    },
    "has-values": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
      "dev": true,
      "requires": {
        "is-number": "^3.0.0",
        "kind-of": "^4.0.0"
      },
      "dependencies": {
        "kind-of": {
          "version": "4.0.0",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "hook-std": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-1.1.0.tgz",
      "integrity": "sha512-aIyBZbZl3NS8XoSwIDQ+ZaiBuPOhhPWoBFA3QX0Q8hOMO8Tx4xGRTDnn/nl/LAtZWdieXzFC9ohAtTSnWrlHCQ==",
      "dev": true
    },
    "hosted-git-info": {
      "version": "2.7.1",
      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
      "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
      "dev": true
    },
    "http-proxy-agent": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
      "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
      "dev": true,
      "requires": {
        "agent-base": "4",
        "debug": "3.1.0"
      },
      "dependencies": {
        "debug": {
          "version": "3.1.0",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "https-proxy-agent": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
      "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
      "dev": true,
      "requires": {
        "agent-base": "^4.1.0",
        "debug": "^3.1.0"
      },
      "dependencies": {
        "debug": {
          "version": "3.2.5",
          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz",
          "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==",
          "dev": true,
          "requires": {
            "ms": "^2.1.1"
          }
        }
      }
    },
    "ignore": {
      "version": "3.3.10",
      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
      "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
      "dev": true
    },
    "import-from": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
      "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
      "dev": true,
      "requires": {
        "resolve-from": "^3.0.0"
      },
      "dependencies": {
        "resolve-from": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
          "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
          "dev": true
        }
      }
    },
    "indent-string": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
      "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
      "dev": true
    },
    "inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
      "dev": true,
      "requires": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "inherits": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
      "dev": true
    },
    "ini": {
      "version": "1.3.5",
      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
      "dev": true
    },
    "into-stream": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
      "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=",
      "dev": true,
      "requires": {
        "from2": "^2.1.1",
        "p-is-promise": "^1.1.0"
      }
    },
    "invert-kv": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
      "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
      "dev": true
    },
    "is-accessor-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
      "dev": true,
      "requires": {
        "kind-of": "^3.0.2"
      },
      "dependencies": {
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "is-arrayish": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
      "dev": true
    },
    "is-buffer": {
      "version": "1.1.6",
      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
      "dev": true
    },
    "is-builtin-module": {
      "version": "1.0.0",
      "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
      "dev": true,
      "requires": {
        "builtin-modules": "^1.0.0"
      }
    },
    "is-data-descriptor": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
      "dev": true,
      "requires": {
        "kind-of": "^3.0.2"
      },
      "dependencies": {
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "is-descriptor": {
      "version": "0.1.6",
      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
      "dev": true,
      "requires": {
        "is-accessor-descriptor": "^0.1.6",
        "is-data-descriptor": "^0.1.4",
        "kind-of": "^5.0.0"
      },
      "dependencies": {
        "kind-of": {
          "version": "5.1.0",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
          "dev": true
        }
      }
    },
    "is-directory": {
      "version": "0.3.1",
      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
      "dev": true
    },
    "is-extendable": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
      "dev": true
    },
    "is-extglob": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
      "dev": true
    },
    "is-fullwidth-code-point": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
      "dev": true
    },
    "is-glob": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
      "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
      "dev": true,
      "requires": {
        "is-extglob": "^2.1.1"
      }
    },
    "is-number": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
      "dev": true,
      "requires": {
        "kind-of": "^3.0.2"
      },
      "dependencies": {
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "is-obj": {
      "version": "1.0.1",
      "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
      "dev": true
    },
    "is-plain-obj": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
      "dev": true
    },
    "is-plain-object": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
      "dev": true,
      "requires": {
        "isobject": "^3.0.1"
      }
    },
    "is-ssh": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.0.tgz",
      "integrity": "sha1-6+oRaaJhTaOSpjdANmw84EnY3/Y=",
      "dev": true,
      "requires": {
        "protocols": "^1.1.0"
      }
    },
    "is-stream": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
      "dev": true
    },
    "is-subset": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
      "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=",
      "dev": true
    },
    "is-text-path": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz",
      "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=",
      "dev": true,
      "requires": {
        "text-extensions": "^1.0.0"
      }
    },
    "is-windows": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
      "dev": true
    },
    "isarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
      "dev": true
    },
    "isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
      "dev": true
    },
    "isobject": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
      "dev": true
    },
    "issue-parser": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-3.0.0.tgz",
      "integrity": "sha512-VWIhBdy0eOhlvpxOOMecBCHMpjx7lWVZcYpSzjD4dSdxptzI9TBR/cQEh057HL8+7jQKTLs+uCtezY/9VoveCA==",
      "dev": true,
      "requires": {
        "lodash.capitalize": "^4.2.1",
        "lodash.escaperegexp": "^4.1.2",
        "lodash.isplainobject": "^4.0.6",
        "lodash.isstring": "^4.0.1",
        "lodash.uniqby": "^4.7.0"
      }
    },
    "java-properties": {
      "version": "0.2.10",
      "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-0.2.10.tgz",
      "integrity": "sha512-CpKJh9VRNhS+XqZtg1UMejETGEiqwCGDC/uwPEEQwc2nfdbSm73SIE29TplG2gLYuBOOTNDqxzG6A9NtEPLt0w==",
      "dev": true
    },
    "js-yaml": {
      "version": "3.12.0",
      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
      "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==",
      "dev": true,
      "requires": {
        "argparse": "^1.0.7",
        "esprima": "^4.0.0"
      }
    },
    "json-parse-better-errors": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
      "dev": true
    },
    "json-stringify-safe": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
      "dev": true
    },
    "jsonfile": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
      "dev": true,
      "requires": {
        "graceful-fs": "^4.1.6"
      }
    },
    "jsonparse": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
      "dev": true
    },
    "kind-of": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
      "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
      "dev": true
    },
    "lcid": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
      "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
      "dev": true,
      "requires": {
        "invert-kv": "^2.0.0"
      }
    },
    "load-json-file": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
      "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
      "dev": true,
      "requires": {
        "graceful-fs": "^4.1.2",
        "parse-json": "^4.0.0",
        "pify": "^3.0.0",
        "strip-bom": "^3.0.0"
      }
    },
    "locate-path": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
      "dev": true,
      "requires": {
        "p-locate": "^2.0.0",
        "path-exists": "^3.0.0"
      },
      "dependencies": {
        "p-locate": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
          "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
          "dev": true,
          "requires": {
            "p-limit": "^1.1.0"
          }
        }
      }
    },
    "lodash": {
      "version": "4.17.11",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
      "dev": true
    },
    "lodash.assign": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
      "dev": true
    },
    "lodash.capitalize": {
      "version": "4.2.1",
      "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz",
      "integrity": "sha1-+CbJtOKoUR2E46yinbBeGk87cqk=",
      "dev": true
    },
    "lodash.escaperegexp": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
      "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=",
      "dev": true
    },
    "lodash.isplainobject": {
      "version": "4.0.6",
      "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
      "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
      "dev": true
    },
    "lodash.isstring": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
      "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=",
      "dev": true
    },
    "lodash.toarray": {
      "version": "4.4.0",
      "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
      "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
      "dev": true
    },
    "lodash.uniqby": {
      "version": "4.7.0",
      "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz",
      "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=",
      "dev": true
    },
    "loud-rejection": {
      "version": "1.6.0",
      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
      "dev": true,
      "requires": {
        "currently-unhandled": "^0.4.1",
        "signal-exit": "^3.0.0"
      }
    },
    "macos-release": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-1.1.0.tgz",
      "integrity": "sha512-mmLbumEYMi5nXReB9js3WGsB8UE6cDBWyIO62Z4DNx6GbRhDxHNjA1MlzSpJ2S2KM1wyiPRA0d19uHWYYvMHjA==",
      "dev": true
    },
    "map-age-cleaner": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz",
      "integrity": "sha512-UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ==",
      "dev": true,
      "requires": {
        "p-defer": "^1.0.0"
      }
    },
    "map-cache": {
      "version": "0.2.2",
      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
      "dev": true
    },
    "map-obj": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
      "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=",
      "dev": true
    },
    "map-visit": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
      "dev": true,
      "requires": {
        "object-visit": "^1.0.0"
      }
    },
    "marked": {
      "version": "0.5.0",
      "resolved": "https://registry.npmjs.org/marked/-/marked-0.5.0.tgz",
      "integrity": "sha512-UhjmkCWKu1SS/BIePL2a59BMJ7V42EYtTfksodPRXzPEGEph3Inp5dylseqt+KbU9Jglsx8xcMKmlumfJMBXAA==",
      "dev": true
    },
    "marked-terminal": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-3.1.1.tgz",
      "integrity": "sha512-7UBFww1rdx0w9HehLMCVYa8/AxXaiDigDfMsJcj82/wgLQG9cj+oiMAVlJpeWD57VFJY2OYY+bKeEVIjIlxi+w==",
      "dev": true,
      "requires": {
        "cardinal": "^2.1.1",
        "chalk": "^2.4.1",
        "cli-table": "^0.3.1",
        "lodash.assign": "^4.2.0",
        "node-emoji": "^1.4.1"
      }
    },
    "mem": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz",
      "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==",
      "dev": true,
      "requires": {
        "map-age-cleaner": "^0.1.1",
        "mimic-fn": "^1.0.0",
        "p-is-promise": "^1.1.0"
      }
    },
    "meow": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz",
      "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==",
      "dev": true,
      "requires": {
        "camelcase-keys": "^4.0.0",
        "decamelize-keys": "^1.0.0",
        "loud-rejection": "^1.0.0",
        "minimist": "^1.1.3",
        "minimist-options": "^3.0.1",
        "normalize-package-data": "^2.3.4",
        "read-pkg-up": "^3.0.0",
        "redent": "^2.0.0",
        "trim-newlines": "^2.0.0"
      },
      "dependencies": {
        "read-pkg-up": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
          "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
          "dev": true,
          "requires": {
            "find-up": "^2.0.0",
            "read-pkg": "^3.0.0"
          }
        }
      }
    },
    "merge2": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz",
      "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==",
      "dev": true
    },
    "micromatch": {
      "version": "3.1.10",
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
      "dev": true,
      "requires": {
        "arr-diff": "^4.0.0",
        "array-unique": "^0.3.2",
        "braces": "^2.3.1",
        "define-property": "^2.0.2",
        "extend-shallow": "^3.0.2",
        "extglob": "^2.0.4",
        "fragment-cache": "^0.2.1",
        "kind-of": "^6.0.2",
        "nanomatch": "^1.2.9",
        "object.pick": "^1.3.0",
        "regex-not": "^1.0.0",
        "snapdragon": "^0.8.1",
        "to-regex": "^3.0.2"
      }
    },
    "mime": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
      "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
      "dev": true
    },
    "mimic-fn": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
      "dev": true
    },
    "minimatch": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
      "dev": true,
      "requires": {
        "brace-expansion": "^1.1.7"
      }
    },
    "minimist": {
      "version": "1.2.0",
      "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
      "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
      "dev": true
    },
    "minimist-options": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz",
      "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==",
      "dev": true,
      "requires": {
        "arrify": "^1.0.1",
        "is-plain-obj": "^1.1.0"
      }
    },
    "mixin-deep": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
      "dev": true,
      "requires": {
        "for-in": "^1.0.2",
        "is-extendable": "^1.0.1"
      },
      "dependencies": {
        "is-extendable": {
          "version": "1.0.1",
          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
          "dev": true,
          "requires": {
            "is-plain-object": "^2.0.4"
          }
        }
      }
    },
    "modify-values": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
      "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==",
      "dev": true
    },
    "ms": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
      "dev": true
    },
    "nanomatch": {
      "version": "1.2.13",
      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
      "dev": true,
      "requires": {
        "arr-diff": "^4.0.0",
        "array-unique": "^0.3.2",
        "define-property": "^2.0.2",
        "extend-shallow": "^3.0.2",
        "fragment-cache": "^0.2.1",
        "is-windows": "^1.0.2",
        "kind-of": "^6.0.2",
        "object.pick": "^1.3.0",
        "regex-not": "^1.0.0",
        "snapdragon": "^0.8.1",
        "to-regex": "^3.0.1"
      }
    },
    "nerf-dart": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz",
      "integrity": "sha1-5tq3/r9a2Bbqgc9cYpxaDr3nLBo=",
      "dev": true
    },
    "nice-try": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
      "dev": true
    },
    "node-emoji": {
      "version": "1.8.1",
      "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz",
      "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==",
      "dev": true,
      "requires": {
        "lodash.toarray": "^4.4.0"
      }
    },
    "node-fetch": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz",
      "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==",
      "dev": true
    },
    "normalize-package-data": {
      "version": "2.4.0",
      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
      "dev": true,
      "requires": {
        "hosted-git-info": "^2.1.4",
        "is-builtin-module": "^1.0.0",
        "semver": "2 || 3 || 4 || 5",
        "validate-npm-package-license": "^3.0.1"
      }
    },
    "normalize-url": {
      "version": "3.3.0",
      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
      "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
      "dev": true
    },
    "npm": {
      "version": "6.4.1",
      "resolved": "https://registry.npmjs.org/npm/-/npm-6.4.1.tgz",
      "integrity": "sha512-mXJL1NTVU136PtuopXCUQaNWuHlXCTp4McwlSW8S9/Aj8OEPAlSBgo8og7kJ01MjCDrkmqFQTvN5tTEhBMhXQg==",
      "dev": true,
      "requires": {
        "JSONStream": "^1.3.4",
        "abbrev": "~1.1.1",
        "ansicolors": "~0.3.2",
        "ansistyles": "~0.1.3",
        "aproba": "~1.2.0",
        "archy": "~1.0.0",
        "bin-links": "^1.1.2",
        "bluebird": "~3.5.1",
        "byte-size": "^4.0.3",
        "cacache": "^11.2.0",
        "call-limit": "~1.1.0",
        "chownr": "~1.0.1",
        "ci-info": "^1.4.0",
        "cli-columns": "^3.1.2",
        "cli-table3": "^0.5.0",
        "cmd-shim": "~2.0.2",
        "columnify": "~1.5.4",
        "config-chain": "~1.1.11",
        "debuglog": "*",
        "detect-indent": "~5.0.0",
        "detect-newline": "^2.1.0",
        "dezalgo": "~1.0.3",
        "editor": "~1.0.0",
        "figgy-pudding": "^3.4.1",
        "find-npm-prefix": "^1.0.2",
        "fs-vacuum": "~1.2.10",
        "fs-write-stream-atomic": "~1.0.10",
        "gentle-fs": "^2.0.1",
        "glob": "~7.1.2",
        "graceful-fs": "~4.1.11",
        "has-unicode": "~2.0.1",
        "hosted-git-info": "^2.7.1",
        "iferr": "^1.0.2",
        "imurmurhash": "*",
        "inflight": "~1.0.6",
        "inherits": "~2.0.3",
        "ini": "^1.3.5",
        "init-package-json": "^1.10.3",
        "is-cidr": "^2.0.6",
        "json-parse-better-errors": "^1.0.2",
        "lazy-property": "~1.0.0",
        "libcipm": "^2.0.2",
        "libnpmhook": "^4.0.1",
        "libnpx": "^10.2.0",
        "lock-verify": "^2.0.2",
        "lockfile": "^1.0.4",
        "lodash._baseindexof": "*",
        "lodash._baseuniq": "~4.6.0",
        "lodash._bindcallback": "*",
        "lodash._cacheindexof": "*",
        "lodash._createcache": "*",
        "lodash._getnative": "*",
        "lodash.clonedeep": "~4.5.0",
        "lodash.restparam": "*",
        "lodash.union": "~4.6.0",
        "lodash.uniq": "~4.5.0",
        "lodash.without": "~4.4.0",
        "lru-cache": "^4.1.3",
        "meant": "~1.0.1",
        "mississippi": "^3.0.0",
        "mkdirp": "~0.5.1",
        "move-concurrently": "^1.0.1",
        "node-gyp": "^3.8.0",
        "nopt": "~4.0.1",
        "normalize-package-data": "~2.4.0",
        "npm-audit-report": "^1.3.1",
        "npm-cache-filename": "~1.0.2",
        "npm-install-checks": "~3.0.0",
        "npm-lifecycle": "^2.1.0",
        "npm-package-arg": "^6.1.0",
        "npm-packlist": "^1.1.11",
        "npm-pick-manifest": "^2.1.0",
        "npm-profile": "^3.0.2",
        "npm-registry-client": "^8.6.0",
        "npm-registry-fetch": "^1.1.0",
        "npm-user-validate": "~1.0.0",
        "npmlog": "~4.1.2",
        "once": "~1.4.0",
        "opener": "^1.5.0",
        "osenv": "^0.1.5",
        "pacote": "^8.1.6",
        "path-is-inside": "~1.0.2",
        "promise-inflight": "~1.0.1",
        "qrcode-terminal": "^0.12.0",
        "query-string": "^6.1.0",
        "qw": "~1.0.1",
        "read": "~1.0.7",
        "read-cmd-shim": "~1.0.1",
        "read-installed": "~4.0.3",
        "read-package-json": "^2.0.13",
        "read-package-tree": "^5.2.1",
        "readable-stream": "^2.3.6",
        "readdir-scoped-modules": "*",
        "request": "^2.88.0",
        "retry": "^0.12.0",
        "rimraf": "~2.6.2",
        "safe-buffer": "^5.1.2",
        "semver": "^5.5.0",
        "sha": "~2.0.1",
        "slide": "~1.1.6",
        "sorted-object": "~2.0.1",
        "sorted-union-stream": "~2.1.3",
        "ssri": "^6.0.0",
        "stringify-package": "^1.0.0",
        "tar": "^4.4.6",
        "text-table": "~0.2.0",
        "tiny-relative-date": "^1.3.0",
        "uid-number": "0.0.6",
        "umask": "~1.1.0",
        "unique-filename": "~1.1.0",
        "unpipe": "~1.0.0",
        "update-notifier": "^2.5.0",
        "uuid": "^3.3.2",
        "validate-npm-package-license": "^3.0.4",
        "validate-npm-package-name": "~3.0.0",
        "which": "^1.3.1",
        "worker-farm": "^1.6.0",
        "write-file-atomic": "^2.3.0"
      },
      "dependencies": {
        "JSONStream": {
          "version": "1.3.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "jsonparse": "^1.2.0",
            "through": ">=2.2.7 <3"
          }
        },
        "abbrev": {
          "version": "1.1.1",
          "bundled": true,
          "dev": true
        },
        "agent-base": {
          "version": "4.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "es6-promisify": "^5.0.0"
          }
        },
        "agentkeepalive": {
          "version": "3.4.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "humanize-ms": "^1.2.1"
          }
        },
        "ajv": {
          "version": "5.5.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "co": "^4.6.0",
            "fast-deep-equal": "^1.0.0",
            "fast-json-stable-stringify": "^2.0.0",
            "json-schema-traverse": "^0.3.0"
          }
        },
        "ansi-align": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "string-width": "^2.0.0"
          }
        },
        "ansi-regex": {
          "version": "2.1.1",
          "bundled": true,
          "dev": true
        },
        "ansi-styles": {
          "version": "3.2.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "color-convert": "^1.9.0"
          }
        },
        "ansicolors": {
          "version": "0.3.2",
          "bundled": true,
          "dev": true
        },
        "ansistyles": {
          "version": "0.1.3",
          "bundled": true,
          "dev": true
        },
        "aproba": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true
        },
        "archy": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "are-we-there-yet": {
          "version": "1.1.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "delegates": "^1.0.0",
            "readable-stream": "^2.0.6"
          }
        },
        "asap": {
          "version": "2.0.6",
          "bundled": true,
          "dev": true
        },
        "asn1": {
          "version": "0.2.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "safer-buffer": "~2.1.0"
          }
        },
        "assert-plus": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "asynckit": {
          "version": "0.4.0",
          "bundled": true,
          "dev": true
        },
        "aws-sign2": {
          "version": "0.7.0",
          "bundled": true,
          "dev": true
        },
        "aws4": {
          "version": "1.8.0",
          "bundled": true,
          "dev": true
        },
        "balanced-match": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "bcrypt-pbkdf": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true,
          "optional": true,
          "requires": {
            "tweetnacl": "^0.14.3"
          }
        },
        "bin-links": {
          "version": "1.1.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "bluebird": "^3.5.0",
            "cmd-shim": "^2.0.2",
            "gentle-fs": "^2.0.0",
            "graceful-fs": "^4.1.11",
            "write-file-atomic": "^2.3.0"
          }
        },
        "block-stream": {
          "version": "0.0.9",
          "bundled": true,
          "dev": true,
          "requires": {
            "inherits": "~2.0.0"
          }
        },
        "bluebird": {
          "version": "3.5.1",
          "bundled": true,
          "dev": true
        },
        "boxen": {
          "version": "1.3.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "ansi-align": "^2.0.0",
            "camelcase": "^4.0.0",
            "chalk": "^2.0.1",
            "cli-boxes": "^1.0.0",
            "string-width": "^2.0.0",
            "term-size": "^1.2.0",
            "widest-line": "^2.0.0"
          }
        },
        "brace-expansion": {
          "version": "1.1.11",
          "bundled": true,
          "dev": true,
          "requires": {
            "balanced-match": "^1.0.0",
            "concat-map": "0.0.1"
          }
        },
        "buffer-from": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "builtin-modules": {
          "version": "1.1.1",
          "bundled": true,
          "dev": true
        },
        "builtins": {
          "version": "1.0.3",
          "bundled": true,
          "dev": true
        },
        "byline": {
          "version": "5.0.0",
          "bundled": true,
          "dev": true
        },
        "byte-size": {
          "version": "4.0.3",
          "bundled": true,
          "dev": true
        },
        "cacache": {
          "version": "11.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "bluebird": "^3.5.1",
            "chownr": "^1.0.1",
            "figgy-pudding": "^3.1.0",
            "glob": "^7.1.2",
            "graceful-fs": "^4.1.11",
            "lru-cache": "^4.1.3",
            "mississippi": "^3.0.0",
            "mkdirp": "^0.5.1",
            "move-concurrently": "^1.0.1",
            "promise-inflight": "^1.0.1",
            "rimraf": "^2.6.2",
            "ssri": "^6.0.0",
            "unique-filename": "^1.1.0",
            "y18n": "^4.0.0"
          }
        },
        "call-limit": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true
        },
        "camelcase": {
          "version": "4.1.0",
          "bundled": true,
          "dev": true
        },
        "capture-stack-trace": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "caseless": {
          "version": "0.12.0",
          "bundled": true,
          "dev": true
        },
        "chalk": {
          "version": "2.4.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "ansi-styles": "^3.2.1",
            "escape-string-regexp": "^1.0.5",
            "supports-color": "^5.3.0"
          }
        },
        "chownr": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "ci-info": {
          "version": "1.4.0",
          "bundled": true,
          "dev": true
        },
        "cidr-regex": {
          "version": "2.0.9",
          "bundled": true,
          "dev": true,
          "requires": {
            "ip-regex": "^2.1.0"
          }
        },
        "cli-boxes": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "cli-columns": {
          "version": "3.1.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "string-width": "^2.0.0",
            "strip-ansi": "^3.0.1"
          }
        },
        "cli-table3": {
          "version": "0.5.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "colors": "^1.1.2",
            "object-assign": "^4.1.0",
            "string-width": "^2.1.1"
          }
        },
        "cliui": {
          "version": "4.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "string-width": "^2.1.1",
            "strip-ansi": "^4.0.0",
            "wrap-ansi": "^2.0.0"
          },
          "dependencies": {
            "ansi-regex": {
              "version": "3.0.0",
              "bundled": true,
              "dev": true
            },
            "strip-ansi": {
              "version": "4.0.0",
              "bundled": true,
              "dev": true,
              "requires": {
                "ansi-regex": "^3.0.0"
              }
            }
          }
        },
        "clone": {
          "version": "1.0.4",
          "bundled": true,
          "dev": true
        },
        "cmd-shim": {
          "version": "2.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.2",
            "mkdirp": "~0.5.0"
          }
        },
        "co": {
          "version": "4.6.0",
          "bundled": true,
          "dev": true
        },
        "code-point-at": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true
        },
        "color-convert": {
          "version": "1.9.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "color-name": "^1.1.1"
          }
        },
        "color-name": {
          "version": "1.1.3",
          "bundled": true,
          "dev": true
        },
        "colors": {
          "version": "1.1.2",
          "bundled": true,
          "dev": true,
          "optional": true
        },
        "columnify": {
          "version": "1.5.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "strip-ansi": "^3.0.0",
            "wcwidth": "^1.0.0"
          }
        },
        "combined-stream": {
          "version": "1.0.6",
          "bundled": true,
          "dev": true,
          "requires": {
            "delayed-stream": "~1.0.0"
          }
        },
        "concat-map": {
          "version": "0.0.1",
          "bundled": true,
          "dev": true
        },
        "concat-stream": {
          "version": "1.6.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "buffer-from": "^1.0.0",
            "inherits": "^2.0.3",
            "readable-stream": "^2.2.2",
            "typedarray": "^0.0.6"
          }
        },
        "config-chain": {
          "version": "1.1.11",
          "bundled": true,
          "dev": true,
          "requires": {
            "ini": "^1.3.4",
            "proto-list": "~1.2.1"
          }
        },
        "configstore": {
          "version": "3.1.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "dot-prop": "^4.1.0",
            "graceful-fs": "^4.1.2",
            "make-dir": "^1.0.0",
            "unique-string": "^1.0.0",
            "write-file-atomic": "^2.0.0",
            "xdg-basedir": "^3.0.0"
          }
        },
        "console-control-strings": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true
        },
        "copy-concurrently": {
          "version": "1.0.5",
          "bundled": true,
          "dev": true,
          "requires": {
            "aproba": "^1.1.1",
            "fs-write-stream-atomic": "^1.0.8",
            "iferr": "^0.1.5",
            "mkdirp": "^0.5.1",
            "rimraf": "^2.5.4",
            "run-queue": "^1.0.0"
          },
          "dependencies": {
            "iferr": {
              "version": "0.1.5",
              "bundled": true,
              "dev": true
            }
          }
        },
        "core-util-is": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "create-error-class": {
          "version": "3.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "capture-stack-trace": "^1.0.0"
          }
        },
        "cross-spawn": {
          "version": "5.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "lru-cache": "^4.0.1",
            "shebang-command": "^1.2.0",
            "which": "^1.2.9"
          }
        },
        "crypto-random-string": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "cyclist": {
          "version": "0.2.2",
          "bundled": true,
          "dev": true
        },
        "dashdash": {
          "version": "1.14.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "assert-plus": "^1.0.0"
          }
        },
        "debug": {
          "version": "3.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          },
          "dependencies": {
            "ms": {
              "version": "2.0.0",
              "bundled": true,
              "dev": true
            }
          }
        },
        "debuglog": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "decamelize": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true
        },
        "decode-uri-component": {
          "version": "0.2.0",
          "bundled": true,
          "dev": true
        },
        "deep-extend": {
          "version": "0.5.1",
          "bundled": true,
          "dev": true
        },
        "defaults": {
          "version": "1.0.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "clone": "^1.0.2"
          }
        },
        "delayed-stream": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "delegates": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "detect-indent": {
          "version": "5.0.0",
          "bundled": true,
          "dev": true
        },
        "detect-newline": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true
        },
        "dezalgo": {
          "version": "1.0.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "asap": "^2.0.0",
            "wrappy": "1"
          }
        },
        "dot-prop": {
          "version": "4.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "is-obj": "^1.0.0"
          }
        },
        "dotenv": {
          "version": "5.0.1",
          "bundled": true,
          "dev": true
        },
        "duplexer3": {
          "version": "0.1.4",
          "bundled": true,
          "dev": true
        },
        "duplexify": {
          "version": "3.6.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "end-of-stream": "^1.0.0",
            "inherits": "^2.0.1",
            "readable-stream": "^2.0.0",
            "stream-shift": "^1.0.0"
          }
        },
        "ecc-jsbn": {
          "version": "0.1.2",
          "bundled": true,
          "dev": true,
          "optional": true,
          "requires": {
            "jsbn": "~0.1.0",
            "safer-buffer": "^2.1.0"
          }
        },
        "editor": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "encoding": {
          "version": "0.1.12",
          "bundled": true,
          "dev": true,
          "requires": {
            "iconv-lite": "~0.4.13"
          }
        },
        "end-of-stream": {
          "version": "1.4.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "once": "^1.4.0"
          }
        },
        "err-code": {
          "version": "1.1.2",
          "bundled": true,
          "dev": true
        },
        "errno": {
          "version": "0.1.7",
          "bundled": true,
          "dev": true,
          "requires": {
            "prr": "~1.0.1"
          }
        },
        "es6-promise": {
          "version": "4.2.4",
          "bundled": true,
          "dev": true
        },
        "es6-promisify": {
          "version": "5.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "es6-promise": "^4.0.3"
          }
        },
        "escape-string-regexp": {
          "version": "1.0.5",
          "bundled": true,
          "dev": true
        },
        "execa": {
          "version": "0.7.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "cross-spawn": "^5.0.1",
            "get-stream": "^3.0.0",
            "is-stream": "^1.1.0",
            "npm-run-path": "^2.0.0",
            "p-finally": "^1.0.0",
            "signal-exit": "^3.0.0",
            "strip-eof": "^1.0.0"
          }
        },
        "extend": {
          "version": "3.0.2",
          "bundled": true,
          "dev": true
        },
        "extsprintf": {
          "version": "1.3.0",
          "bundled": true,
          "dev": true
        },
        "fast-deep-equal": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true
        },
        "fast-json-stable-stringify": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true
        },
        "figgy-pudding": {
          "version": "3.4.1",
          "bundled": true,
          "dev": true
        },
        "find-npm-prefix": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "find-up": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "locate-path": "^2.0.0"
          }
        },
        "flush-write-stream": {
          "version": "1.0.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "inherits": "^2.0.1",
            "readable-stream": "^2.0.4"
          }
        },
        "forever-agent": {
          "version": "0.6.1",
          "bundled": true,
          "dev": true
        },
        "form-data": {
          "version": "2.3.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "asynckit": "^0.4.0",
            "combined-stream": "1.0.6",
            "mime-types": "^2.1.12"
          }
        },
        "from2": {
          "version": "2.3.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "inherits": "^2.0.1",
            "readable-stream": "^2.0.0"
          }
        },
        "fs-minipass": {
          "version": "1.2.5",
          "bundled": true,
          "dev": true,
          "requires": {
            "minipass": "^2.2.1"
          }
        },
        "fs-vacuum": {
          "version": "1.2.10",
          "bundled": true,
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.2",
            "path-is-inside": "^1.0.1",
            "rimraf": "^2.5.2"
          }
        },
        "fs-write-stream-atomic": {
          "version": "1.0.10",
          "bundled": true,
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.2",
            "iferr": "^0.1.5",
            "imurmurhash": "^0.1.4",
            "readable-stream": "1 || 2"
          },
          "dependencies": {
            "iferr": {
              "version": "0.1.5",
              "bundled": true,
              "dev": true
            }
          }
        },
        "fs.realpath": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "fstream": {
          "version": "1.0.11",
          "bundled": true,
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.2",
            "inherits": "~2.0.0",
            "mkdirp": ">=0.5 0",
            "rimraf": "2"
          }
        },
        "gauge": {
          "version": "2.7.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "aproba": "^1.0.3",
            "console-control-strings": "^1.0.0",
            "has-unicode": "^2.0.0",
            "object-assign": "^4.1.0",
            "signal-exit": "^3.0.0",
            "string-width": "^1.0.1",
            "strip-ansi": "^3.0.1",
            "wide-align": "^1.1.0"
          },
          "dependencies": {
            "string-width": {
              "version": "1.0.2",
              "bundled": true,
              "dev": true,
              "requires": {
                "code-point-at": "^1.0.0",
                "is-fullwidth-code-point": "^1.0.0",
                "strip-ansi": "^3.0.0"
              }
            }
          }
        },
        "genfun": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true
        },
        "gentle-fs": {
          "version": "2.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "aproba": "^1.1.2",
            "fs-vacuum": "^1.2.10",
            "graceful-fs": "^4.1.11",
            "iferr": "^0.1.5",
            "mkdirp": "^0.5.1",
            "path-is-inside": "^1.0.2",
            "read-cmd-shim": "^1.0.1",
            "slide": "^1.1.6"
          },
          "dependencies": {
            "iferr": {
              "version": "0.1.5",
              "bundled": true,
              "dev": true
            }
          }
        },
        "get-caller-file": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "get-stream": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true
        },
        "getpass": {
          "version": "0.1.7",
          "bundled": true,
          "dev": true,
          "requires": {
            "assert-plus": "^1.0.0"
          }
        },
        "glob": {
          "version": "7.1.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "fs.realpath": "^1.0.0",
            "inflight": "^1.0.4",
            "inherits": "2",
            "minimatch": "^3.0.4",
            "once": "^1.3.0",
            "path-is-absolute": "^1.0.0"
          }
        },
        "global-dirs": {
          "version": "0.1.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "ini": "^1.3.4"
          }
        },
        "got": {
          "version": "6.7.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "create-error-class": "^3.0.0",
            "duplexer3": "^0.1.4",
            "get-stream": "^3.0.0",
            "is-redirect": "^1.0.0",
            "is-retry-allowed": "^1.0.0",
            "is-stream": "^1.0.0",
            "lowercase-keys": "^1.0.0",
            "safe-buffer": "^5.0.1",
            "timed-out": "^4.0.0",
            "unzip-response": "^2.0.1",
            "url-parse-lax": "^1.0.0"
          }
        },
        "graceful-fs": {
          "version": "4.1.11",
          "bundled": true,
          "dev": true
        },
        "har-schema": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true
        },
        "har-validator": {
          "version": "5.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "ajv": "^5.3.0",
            "har-schema": "^2.0.0"
          }
        },
        "has-flag": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true
        },
        "has-unicode": {
          "version": "2.0.1",
          "bundled": true,
          "dev": true
        },
        "hosted-git-info": {
          "version": "2.7.1",
          "bundled": true,
          "dev": true
        },
        "http-cache-semantics": {
          "version": "3.8.1",
          "bundled": true,
          "dev": true
        },
        "http-proxy-agent": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "agent-base": "4",
            "debug": "3.1.0"
          }
        },
        "http-signature": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "assert-plus": "^1.0.0",
            "jsprim": "^1.2.2",
            "sshpk": "^1.7.0"
          }
        },
        "https-proxy-agent": {
          "version": "2.2.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "agent-base": "^4.1.0",
            "debug": "^3.1.0"
          }
        },
        "humanize-ms": {
          "version": "1.2.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "ms": "^2.0.0"
          }
        },
        "iconv-lite": {
          "version": "0.4.23",
          "bundled": true,
          "dev": true,
          "requires": {
            "safer-buffer": ">= 2.1.2 < 3"
          }
        },
        "iferr": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "ignore-walk": {
          "version": "3.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "minimatch": "^3.0.4"
          }
        },
        "import-lazy": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true
        },
        "imurmurhash": {
          "version": "0.1.4",
          "bundled": true,
          "dev": true
        },
        "inflight": {
          "version": "1.0.6",
          "bundled": true,
          "dev": true,
          "requires": {
            "once": "^1.3.0",
            "wrappy": "1"
          }
        },
        "inherits": {
          "version": "2.0.3",
          "bundled": true,
          "dev": true
        },
        "ini": {
          "version": "1.3.5",
          "bundled": true,
          "dev": true
        },
        "init-package-json": {
          "version": "1.10.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "glob": "^7.1.1",
            "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0",
            "promzard": "^0.3.0",
            "read": "~1.0.1",
            "read-package-json": "1 || 2",
            "semver": "2.x || 3.x || 4 || 5",
            "validate-npm-package-license": "^3.0.1",
            "validate-npm-package-name": "^3.0.0"
          }
        },
        "invert-kv": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "ip": {
          "version": "1.1.5",
          "bundled": true,
          "dev": true
        },
        "ip-regex": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true
        },
        "is-builtin-module": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "builtin-modules": "^1.0.0"
          }
        },
        "is-ci": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "ci-info": "^1.0.0"
          }
        },
        "is-cidr": {
          "version": "2.0.6",
          "bundled": true,
          "dev": true,
          "requires": {
            "cidr-regex": "^2.0.8"
          }
        },
        "is-fullwidth-code-point": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "number-is-nan": "^1.0.0"
          }
        },
        "is-installed-globally": {
          "version": "0.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "global-dirs": "^0.1.0",
            "is-path-inside": "^1.0.0"
          }
        },
        "is-npm": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "is-obj": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "is-path-inside": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "path-is-inside": "^1.0.1"
          }
        },
        "is-redirect": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "is-retry-allowed": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true
        },
        "is-stream": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true
        },
        "is-typedarray": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "isarray": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "isexe": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true
        },
        "isstream": {
          "version": "0.1.2",
          "bundled": true,
          "dev": true
        },
        "jsbn": {
          "version": "0.1.1",
          "bundled": true,
          "dev": true,
          "optional": true
        },
        "json-parse-better-errors": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "json-schema": {
          "version": "0.2.3",
          "bundled": true,
          "dev": true
        },
        "json-schema-traverse": {
          "version": "0.3.1",
          "bundled": true,
          "dev": true
        },
        "json-stringify-safe": {
          "version": "5.0.1",
          "bundled": true,
          "dev": true
        },
        "jsonparse": {
          "version": "1.3.1",
          "bundled": true,
          "dev": true
        },
        "jsprim": {
          "version": "1.4.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "assert-plus": "1.0.0",
            "extsprintf": "1.3.0",
            "json-schema": "0.2.3",
            "verror": "1.10.0"
          }
        },
        "latest-version": {
          "version": "3.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "package-json": "^4.0.0"
          }
        },
        "lazy-property": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "lcid": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "invert-kv": "^1.0.0"
          }
        },
        "libcipm": {
          "version": "2.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "bin-links": "^1.1.2",
            "bluebird": "^3.5.1",
            "find-npm-prefix": "^1.0.2",
            "graceful-fs": "^4.1.11",
            "lock-verify": "^2.0.2",
            "mkdirp": "^0.5.1",
            "npm-lifecycle": "^2.0.3",
            "npm-logical-tree": "^1.2.1",
            "npm-package-arg": "^6.1.0",
            "pacote": "^8.1.6",
            "protoduck": "^5.0.0",
            "read-package-json": "^2.0.13",
            "rimraf": "^2.6.2",
            "worker-farm": "^1.6.0"
          }
        },
        "libnpmhook": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "figgy-pudding": "^3.1.0",
            "npm-registry-fetch": "^3.0.0"
          },
          "dependencies": {
            "npm-registry-fetch": {
              "version": "3.1.1",
              "bundled": true,
              "dev": true,
              "requires": {
                "bluebird": "^3.5.1",
                "figgy-pudding": "^3.1.0",
                "lru-cache": "^4.1.2",
                "make-fetch-happen": "^4.0.0",
                "npm-package-arg": "^6.0.0"
              }
            }
          }
        },
        "libnpx": {
          "version": "10.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "dotenv": "^5.0.1",
            "npm-package-arg": "^6.0.0",
            "rimraf": "^2.6.2",
            "safe-buffer": "^5.1.0",
            "update-notifier": "^2.3.0",
            "which": "^1.3.0",
            "y18n": "^4.0.0",
            "yargs": "^11.0.0"
          }
        },
        "locate-path": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "p-locate": "^2.0.0",
            "path-exists": "^3.0.0"
          }
        },
        "lock-verify": {
          "version": "2.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "npm-package-arg": "^5.1.2 || 6",
            "semver": "^5.4.1"
          }
        },
        "lockfile": {
          "version": "1.0.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "signal-exit": "^3.0.2"
          }
        },
        "lodash._baseindexof": {
          "version": "3.1.0",
          "bundled": true,
          "dev": true
        },
        "lodash._baseuniq": {
          "version": "4.6.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "lodash._createset": "~4.0.0",
            "lodash._root": "~3.0.0"
          }
        },
        "lodash._bindcallback": {
          "version": "3.0.1",
          "bundled": true,
          "dev": true
        },
        "lodash._cacheindexof": {
          "version": "3.0.2",
          "bundled": true,
          "dev": true
        },
        "lodash._createcache": {
          "version": "3.1.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "lodash._getnative": "^3.0.0"
          }
        },
        "lodash._createset": {
          "version": "4.0.3",
          "bundled": true,
          "dev": true
        },
        "lodash._getnative": {
          "version": "3.9.1",
          "bundled": true,
          "dev": true
        },
        "lodash._root": {
          "version": "3.0.1",
          "bundled": true,
          "dev": true
        },
        "lodash.clonedeep": {
          "version": "4.5.0",
          "bundled": true,
          "dev": true
        },
        "lodash.restparam": {
          "version": "3.6.1",
          "bundled": true,
          "dev": true
        },
        "lodash.union": {
          "version": "4.6.0",
          "bundled": true,
          "dev": true
        },
        "lodash.uniq": {
          "version": "4.5.0",
          "bundled": true,
          "dev": true
        },
        "lodash.without": {
          "version": "4.4.0",
          "bundled": true,
          "dev": true
        },
        "lowercase-keys": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "lru-cache": {
          "version": "4.1.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "pseudomap": "^1.0.2",
            "yallist": "^2.1.2"
          }
        },
        "make-dir": {
          "version": "1.3.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "pify": "^3.0.0"
          }
        },
        "make-fetch-happen": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "agentkeepalive": "^3.4.1",
            "cacache": "^11.0.1",
            "http-cache-semantics": "^3.8.1",
            "http-proxy-agent": "^2.1.0",
            "https-proxy-agent": "^2.2.1",
            "lru-cache": "^4.1.2",
            "mississippi": "^3.0.0",
            "node-fetch-npm": "^2.0.2",
            "promise-retry": "^1.1.1",
            "socks-proxy-agent": "^4.0.0",
            "ssri": "^6.0.0"
          }
        },
        "meant": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "mem": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "mimic-fn": "^1.0.0"
          }
        },
        "mime-db": {
          "version": "1.35.0",
          "bundled": true,
          "dev": true
        },
        "mime-types": {
          "version": "2.1.19",
          "bundled": true,
          "dev": true,
          "requires": {
            "mime-db": "~1.35.0"
          }
        },
        "mimic-fn": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true
        },
        "minimatch": {
          "version": "3.0.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "brace-expansion": "^1.1.7"
          }
        },
        "minimist": {
          "version": "0.0.8",
          "bundled": true,
          "dev": true
        },
        "minipass": {
          "version": "2.3.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "safe-buffer": "^5.1.2",
            "yallist": "^3.0.0"
          },
          "dependencies": {
            "yallist": {
              "version": "3.0.2",
              "bundled": true,
              "dev": true
            }
          }
        },
        "minizlib": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "minipass": "^2.2.1"
          }
        },
        "mississippi": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "concat-stream": "^1.5.0",
            "duplexify": "^3.4.2",
            "end-of-stream": "^1.1.0",
            "flush-write-stream": "^1.0.0",
            "from2": "^2.1.0",
            "parallel-transform": "^1.1.0",
            "pump": "^3.0.0",
            "pumpify": "^1.3.3",
            "stream-each": "^1.1.0",
            "through2": "^2.0.0"
          }
        },
        "mkdirp": {
          "version": "0.5.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "minimist": "0.0.8"
          }
        },
        "move-concurrently": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "aproba": "^1.1.1",
            "copy-concurrently": "^1.0.0",
            "fs-write-stream-atomic": "^1.0.8",
            "mkdirp": "^0.5.1",
            "rimraf": "^2.5.4",
            "run-queue": "^1.0.3"
          }
        },
        "ms": {
          "version": "2.1.1",
          "bundled": true,
          "dev": true
        },
        "mute-stream": {
          "version": "0.0.7",
          "bundled": true,
          "dev": true
        },
        "node-fetch-npm": {
          "version": "2.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "encoding": "^0.1.11",
            "json-parse-better-errors": "^1.0.0",
            "safe-buffer": "^5.1.1"
          }
        },
        "node-gyp": {
          "version": "3.8.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "fstream": "^1.0.0",
            "glob": "^7.0.3",
            "graceful-fs": "^4.1.2",
            "mkdirp": "^0.5.0",
            "nopt": "2 || 3",
            "npmlog": "0 || 1 || 2 || 3 || 4",
            "osenv": "0",
            "request": "^2.87.0",
            "rimraf": "2",
            "semver": "~5.3.0",
            "tar": "^2.0.0",
            "which": "1"
          },
          "dependencies": {
            "nopt": {
              "version": "3.0.6",
              "bundled": true,
              "dev": true,
              "requires": {
                "abbrev": "1"
              }
            },
            "semver": {
              "version": "5.3.0",
              "bundled": true,
              "dev": true
            },
            "tar": {
              "version": "2.2.1",
              "bundled": true,
              "dev": true,
              "requires": {
                "block-stream": "*",
                "fstream": "^1.0.2",
                "inherits": "2"
              }
            }
          }
        },
        "nopt": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "abbrev": "1",
            "osenv": "^0.1.4"
          }
        },
        "normalize-package-data": {
          "version": "2.4.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "hosted-git-info": "^2.1.4",
            "is-builtin-module": "^1.0.0",
            "semver": "2 || 3 || 4 || 5",
            "validate-npm-package-license": "^3.0.1"
          }
        },
        "npm-audit-report": {
          "version": "1.3.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "cli-table3": "^0.5.0",
            "console-control-strings": "^1.1.0"
          }
        },
        "npm-bundled": {
          "version": "1.0.5",
          "bundled": true,
          "dev": true
        },
        "npm-cache-filename": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "npm-install-checks": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "semver": "^2.3.0 || 3.x || 4 || 5"
          }
        },
        "npm-lifecycle": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "byline": "^5.0.0",
            "graceful-fs": "^4.1.11",
            "node-gyp": "^3.8.0",
            "resolve-from": "^4.0.0",
            "slide": "^1.1.6",
            "uid-number": "0.0.6",
            "umask": "^1.1.0",
            "which": "^1.3.1"
          }
        },
        "npm-logical-tree": {
          "version": "1.2.1",
          "bundled": true,
          "dev": true
        },
        "npm-package-arg": {
          "version": "6.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "hosted-git-info": "^2.6.0",
            "osenv": "^0.1.5",
            "semver": "^5.5.0",
            "validate-npm-package-name": "^3.0.0"
          }
        },
        "npm-packlist": {
          "version": "1.1.11",
          "bundled": true,
          "dev": true,
          "requires": {
            "ignore-walk": "^3.0.1",
            "npm-bundled": "^1.0.1"
          }
        },
        "npm-pick-manifest": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "npm-package-arg": "^6.0.0",
            "semver": "^5.4.1"
          }
        },
        "npm-profile": {
          "version": "3.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "aproba": "^1.1.2 || 2",
            "make-fetch-happen": "^2.5.0 || 3 || 4"
          }
        },
        "npm-registry-client": {
          "version": "8.6.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "concat-stream": "^1.5.2",
            "graceful-fs": "^4.1.6",
            "normalize-package-data": "~1.0.1 || ^2.0.0",
            "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0",
            "npmlog": "2 || ^3.1.0 || ^4.0.0",
            "once": "^1.3.3",
            "request": "^2.74.0",
            "retry": "^0.10.0",
            "safe-buffer": "^5.1.1",
            "semver": "2 >=2.2.1 || 3.x || 4 || 5",
            "slide": "^1.1.3",
            "ssri": "^5.2.4"
          },
          "dependencies": {
            "retry": {
              "version": "0.10.1",
              "bundled": true,
              "dev": true
            },
            "ssri": {
              "version": "5.3.0",
              "bundled": true,
              "dev": true,
              "requires": {
                "safe-buffer": "^5.1.1"
              }
            }
          }
        },
        "npm-registry-fetch": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "bluebird": "^3.5.1",
            "figgy-pudding": "^2.0.1",
            "lru-cache": "^4.1.2",
            "make-fetch-happen": "^3.0.0",
            "npm-package-arg": "^6.0.0",
            "safe-buffer": "^5.1.1"
          },
          "dependencies": {
            "cacache": {
              "version": "10.0.4",
              "bundled": true,
              "dev": true,
              "requires": {
                "bluebird": "^3.5.1",
                "chownr": "^1.0.1",
                "glob": "^7.1.2",
                "graceful-fs": "^4.1.11",
                "lru-cache": "^4.1.1",
                "mississippi": "^2.0.0",
                "mkdirp": "^0.5.1",
                "move-concurrently": "^1.0.1",
                "promise-inflight": "^1.0.1",
                "rimraf": "^2.6.2",
                "ssri": "^5.2.4",
                "unique-filename": "^1.1.0",
                "y18n": "^4.0.0"
              },
              "dependencies": {
                "mississippi": {
                  "version": "2.0.0",
                  "bundled": true,
                  "dev": true,
                  "requires": {
                    "concat-stream": "^1.5.0",
                    "duplexify": "^3.4.2",
                    "end-of-stream": "^1.1.0",
                    "flush-write-stream": "^1.0.0",
                    "from2": "^2.1.0",
                    "parallel-transform": "^1.1.0",
                    "pump": "^2.0.1",
                    "pumpify": "^1.3.3",
                    "stream-each": "^1.1.0",
                    "through2": "^2.0.0"
                  }
                }
              }
            },
            "figgy-pudding": {
              "version": "2.0.1",
              "bundled": true,
              "dev": true
            },
            "make-fetch-happen": {
              "version": "3.0.0",
              "bundled": true,
              "dev": true,
              "requires": {
                "agentkeepalive": "^3.4.1",
                "cacache": "^10.0.4",
                "http-cache-semantics": "^3.8.1",
                "http-proxy-agent": "^2.1.0",
                "https-proxy-agent": "^2.2.0",
                "lru-cache": "^4.1.2",
                "mississippi": "^3.0.0",
                "node-fetch-npm": "^2.0.2",
                "promise-retry": "^1.1.1",
                "socks-proxy-agent": "^3.0.1",
                "ssri": "^5.2.4"
              }
            },
            "pump": {
              "version": "2.0.1",
              "bundled": true,
              "dev": true,
              "requires": {
                "end-of-stream": "^1.1.0",
                "once": "^1.3.1"
              }
            },
            "smart-buffer": {
              "version": "1.1.15",
              "bundled": true,
              "dev": true
            },
            "socks": {
              "version": "1.1.10",
              "bundled": true,
              "dev": true,
              "requires": {
                "ip": "^1.1.4",
                "smart-buffer": "^1.0.13"
              }
            },
            "socks-proxy-agent": {
              "version": "3.0.1",
              "bundled": true,
              "dev": true,
              "requires": {
                "agent-base": "^4.1.0",
                "socks": "^1.1.10"
              }
            },
            "ssri": {
              "version": "5.3.0",
              "bundled": true,
              "dev": true,
              "requires": {
                "safe-buffer": "^5.1.1"
              }
            }
          }
        },
        "npm-run-path": {
          "version": "2.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "path-key": "^2.0.0"
          }
        },
        "npm-user-validate": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "npmlog": {
          "version": "4.1.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "are-we-there-yet": "~1.1.2",
            "console-control-strings": "~1.1.0",
            "gauge": "~2.7.3",
            "set-blocking": "~2.0.0"
          }
        },
        "number-is-nan": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "oauth-sign": {
          "version": "0.9.0",
          "bundled": true,
          "dev": true
        },
        "object-assign": {
          "version": "4.1.1",
          "bundled": true,
          "dev": true
        },
        "once": {
          "version": "1.4.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "wrappy": "1"
          }
        },
        "opener": {
          "version": "1.5.0",
          "bundled": true,
          "dev": true
        },
        "os-homedir": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "os-locale": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "execa": "^0.7.0",
            "lcid": "^1.0.0",
            "mem": "^1.1.0"
          }
        },
        "os-tmpdir": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "osenv": {
          "version": "0.1.5",
          "bundled": true,
          "dev": true,
          "requires": {
            "os-homedir": "^1.0.0",
            "os-tmpdir": "^1.0.0"
          }
        },
        "p-finally": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "p-limit": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "p-try": "^1.0.0"
          }
        },
        "p-locate": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "p-limit": "^1.1.0"
          }
        },
        "p-try": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "package-json": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "got": "^6.7.1",
            "registry-auth-token": "^3.0.1",
            "registry-url": "^3.0.3",
            "semver": "^5.1.0"
          }
        },
        "pacote": {
          "version": "8.1.6",
          "bundled": true,
          "dev": true,
          "requires": {
            "bluebird": "^3.5.1",
            "cacache": "^11.0.2",
            "get-stream": "^3.0.0",
            "glob": "^7.1.2",
            "lru-cache": "^4.1.3",
            "make-fetch-happen": "^4.0.1",
            "minimatch": "^3.0.4",
            "minipass": "^2.3.3",
            "mississippi": "^3.0.0",
            "mkdirp": "^0.5.1",
            "normalize-package-data": "^2.4.0",
            "npm-package-arg": "^6.1.0",
            "npm-packlist": "^1.1.10",
            "npm-pick-manifest": "^2.1.0",
            "osenv": "^0.1.5",
            "promise-inflight": "^1.0.1",
            "promise-retry": "^1.1.1",
            "protoduck": "^5.0.0",
            "rimraf": "^2.6.2",
            "safe-buffer": "^5.1.2",
            "semver": "^5.5.0",
            "ssri": "^6.0.0",
            "tar": "^4.4.3",
            "unique-filename": "^1.1.0",
            "which": "^1.3.0"
          }
        },
        "parallel-transform": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "cyclist": "~0.2.2",
            "inherits": "^2.0.3",
            "readable-stream": "^2.1.5"
          }
        },
        "path-exists": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true
        },
        "path-is-absolute": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "path-is-inside": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "path-key": {
          "version": "2.0.1",
          "bundled": true,
          "dev": true
        },
        "performance-now": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true
        },
        "pify": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true
        },
        "prepend-http": {
          "version": "1.0.4",
          "bundled": true,
          "dev": true
        },
        "process-nextick-args": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true
        },
        "promise-inflight": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "promise-retry": {
          "version": "1.1.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "err-code": "^1.0.0",
            "retry": "^0.10.0"
          },
          "dependencies": {
            "retry": {
              "version": "0.10.1",
              "bundled": true,
              "dev": true
            }
          }
        },
        "promzard": {
          "version": "0.3.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "read": "1"
          }
        },
        "proto-list": {
          "version": "1.2.4",
          "bundled": true,
          "dev": true
        },
        "protoduck": {
          "version": "5.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "genfun": "^4.0.1"
          }
        },
        "prr": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "pseudomap": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "psl": {
          "version": "1.1.29",
          "bundled": true,
          "dev": true
        },
        "pump": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "end-of-stream": "^1.1.0",
            "once": "^1.3.1"
          }
        },
        "pumpify": {
          "version": "1.5.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "duplexify": "^3.6.0",
            "inherits": "^2.0.3",
            "pump": "^2.0.0"
          },
          "dependencies": {
            "pump": {
              "version": "2.0.1",
              "bundled": true,
              "dev": true,
              "requires": {
                "end-of-stream": "^1.1.0",
                "once": "^1.3.1"
              }
            }
          }
        },
        "punycode": {
          "version": "1.4.1",
          "bundled": true,
          "dev": true
        },
        "qrcode-terminal": {
          "version": "0.12.0",
          "bundled": true,
          "dev": true
        },
        "qs": {
          "version": "6.5.2",
          "bundled": true,
          "dev": true
        },
        "query-string": {
          "version": "6.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "decode-uri-component": "^0.2.0",
            "strict-uri-encode": "^2.0.0"
          }
        },
        "qw": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "rc": {
          "version": "1.2.7",
          "bundled": true,
          "dev": true,
          "requires": {
            "deep-extend": "^0.5.1",
            "ini": "~1.3.0",
            "minimist": "^1.2.0",
            "strip-json-comments": "~2.0.1"
          },
          "dependencies": {
            "minimist": {
              "version": "1.2.0",
              "bundled": true,
              "dev": true
            }
          }
        },
        "read": {
          "version": "1.0.7",
          "bundled": true,
          "dev": true,
          "requires": {
            "mute-stream": "~0.0.4"
          }
        },
        "read-cmd-shim": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.2"
          }
        },
        "read-installed": {
          "version": "4.0.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "debuglog": "^1.0.1",
            "graceful-fs": "^4.1.2",
            "read-package-json": "^2.0.0",
            "readdir-scoped-modules": "^1.0.0",
            "semver": "2 || 3 || 4 || 5",
            "slide": "~1.1.3",
            "util-extend": "^1.0.1"
          }
        },
        "read-package-json": {
          "version": "2.0.13",
          "bundled": true,
          "dev": true,
          "requires": {
            "glob": "^7.1.1",
            "graceful-fs": "^4.1.2",
            "json-parse-better-errors": "^1.0.1",
            "normalize-package-data": "^2.0.0",
            "slash": "^1.0.0"
          }
        },
        "read-package-tree": {
          "version": "5.2.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "debuglog": "^1.0.1",
            "dezalgo": "^1.0.0",
            "once": "^1.3.0",
            "read-package-json": "^2.0.0",
            "readdir-scoped-modules": "^1.0.0"
          }
        },
        "readable-stream": {
          "version": "2.3.6",
          "bundled": true,
          "dev": true,
          "requires": {
            "core-util-is": "~1.0.0",
            "inherits": "~2.0.3",
            "isarray": "~1.0.0",
            "process-nextick-args": "~2.0.0",
            "safe-buffer": "~5.1.1",
            "string_decoder": "~1.1.1",
            "util-deprecate": "~1.0.1"
          }
        },
        "readdir-scoped-modules": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "debuglog": "^1.0.1",
            "dezalgo": "^1.0.0",
            "graceful-fs": "^4.1.2",
            "once": "^1.3.0"
          }
        },
        "registry-auth-token": {
          "version": "3.3.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "rc": "^1.1.6",
            "safe-buffer": "^5.0.1"
          }
        },
        "registry-url": {
          "version": "3.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "rc": "^1.0.1"
          }
        },
        "request": {
          "version": "2.88.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "aws-sign2": "~0.7.0",
            "aws4": "^1.8.0",
            "caseless": "~0.12.0",
            "combined-stream": "~1.0.6",
            "extend": "~3.0.2",
            "forever-agent": "~0.6.1",
            "form-data": "~2.3.2",
            "har-validator": "~5.1.0",
            "http-signature": "~1.2.0",
            "is-typedarray": "~1.0.0",
            "isstream": "~0.1.2",
            "json-stringify-safe": "~5.0.1",
            "mime-types": "~2.1.19",
            "oauth-sign": "~0.9.0",
            "performance-now": "^2.1.0",
            "qs": "~6.5.2",
            "safe-buffer": "^5.1.2",
            "tough-cookie": "~2.4.3",
            "tunnel-agent": "^0.6.0",
            "uuid": "^3.3.2"
          }
        },
        "require-directory": {
          "version": "2.1.1",
          "bundled": true,
          "dev": true
        },
        "require-main-filename": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true
        },
        "resolve-from": {
          "version": "4.0.0",
          "bundled": true,
          "dev": true
        },
        "retry": {
          "version": "0.12.0",
          "bundled": true,
          "dev": true
        },
        "rimraf": {
          "version": "2.6.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "glob": "^7.0.5"
          }
        },
        "run-queue": {
          "version": "1.0.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "aproba": "^1.1.1"
          }
        },
        "safe-buffer": {
          "version": "5.1.2",
          "bundled": true,
          "dev": true
        },
        "safer-buffer": {
          "version": "2.1.2",
          "bundled": true,
          "dev": true
        },
        "semver": {
          "version": "5.5.0",
          "bundled": true,
          "dev": true
        },
        "semver-diff": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "semver": "^5.0.3"
          }
        },
        "set-blocking": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true
        },
        "sha": {
          "version": "2.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.2",
            "readable-stream": "^2.0.2"
          }
        },
        "shebang-command": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "shebang-regex": "^1.0.0"
          }
        },
        "shebang-regex": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "signal-exit": {
          "version": "3.0.2",
          "bundled": true,
          "dev": true
        },
        "slash": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "slide": {
          "version": "1.1.6",
          "bundled": true,
          "dev": true
        },
        "smart-buffer": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true
        },
        "socks": {
          "version": "2.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "ip": "^1.1.5",
            "smart-buffer": "^4.0.1"
          }
        },
        "socks-proxy-agent": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "agent-base": "~4.2.0",
            "socks": "~2.2.0"
          }
        },
        "sorted-object": {
          "version": "2.0.1",
          "bundled": true,
          "dev": true
        },
        "sorted-union-stream": {
          "version": "2.1.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "from2": "^1.3.0",
            "stream-iterate": "^1.1.0"
          },
          "dependencies": {
            "from2": {
              "version": "1.3.0",
              "bundled": true,
              "dev": true,
              "requires": {
                "inherits": "~2.0.1",
                "readable-stream": "~1.1.10"
              }
            },
            "isarray": {
              "version": "0.0.1",
              "bundled": true,
              "dev": true
            },
            "readable-stream": {
              "version": "1.1.14",
              "bundled": true,
              "dev": true,
              "requires": {
                "core-util-is": "~1.0.0",
                "inherits": "~2.0.1",
                "isarray": "0.0.1",
                "string_decoder": "~0.10.x"
              }
            },
            "string_decoder": {
              "version": "0.10.31",
              "bundled": true,
              "dev": true
            }
          }
        },
        "spdx-correct": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "spdx-expression-parse": "^3.0.0",
            "spdx-license-ids": "^3.0.0"
          }
        },
        "spdx-exceptions": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true
        },
        "spdx-expression-parse": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "spdx-exceptions": "^2.1.0",
            "spdx-license-ids": "^3.0.0"
          }
        },
        "spdx-license-ids": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true
        },
        "sshpk": {
          "version": "1.14.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "asn1": "~0.2.3",
            "assert-plus": "^1.0.0",
            "bcrypt-pbkdf": "^1.0.0",
            "dashdash": "^1.12.0",
            "ecc-jsbn": "~0.1.1",
            "getpass": "^0.1.1",
            "jsbn": "~0.1.0",
            "safer-buffer": "^2.0.2",
            "tweetnacl": "~0.14.0"
          }
        },
        "ssri": {
          "version": "6.0.0",
          "bundled": true,
          "dev": true
        },
        "stream-each": {
          "version": "1.2.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "end-of-stream": "^1.1.0",
            "stream-shift": "^1.0.0"
          }
        },
        "stream-iterate": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "readable-stream": "^2.1.5",
            "stream-shift": "^1.0.0"
          }
        },
        "stream-shift": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "strict-uri-encode": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true
        },
        "string-width": {
          "version": "2.1.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "is-fullwidth-code-point": "^2.0.0",
            "strip-ansi": "^4.0.0"
          },
          "dependencies": {
            "ansi-regex": {
              "version": "3.0.0",
              "bundled": true,
              "dev": true
            },
            "is-fullwidth-code-point": {
              "version": "2.0.0",
              "bundled": true,
              "dev": true
            },
            "strip-ansi": {
              "version": "4.0.0",
              "bundled": true,
              "dev": true,
              "requires": {
                "ansi-regex": "^3.0.0"
              }
            }
          }
        },
        "string_decoder": {
          "version": "1.1.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "safe-buffer": "~5.1.0"
          }
        },
        "stringify-package": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "strip-ansi": {
          "version": "3.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "ansi-regex": "^2.0.0"
          }
        },
        "strip-eof": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "strip-json-comments": {
          "version": "2.0.1",
          "bundled": true,
          "dev": true
        },
        "supports-color": {
          "version": "5.4.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "has-flag": "^3.0.0"
          }
        },
        "tar": {
          "version": "4.4.6",
          "bundled": true,
          "dev": true,
          "requires": {
            "chownr": "^1.0.1",
            "fs-minipass": "^1.2.5",
            "minipass": "^2.3.3",
            "minizlib": "^1.1.0",
            "mkdirp": "^0.5.0",
            "safe-buffer": "^5.1.2",
            "yallist": "^3.0.2"
          },
          "dependencies": {
            "yallist": {
              "version": "3.0.2",
              "bundled": true,
              "dev": true
            }
          }
        },
        "term-size": {
          "version": "1.2.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "execa": "^0.7.0"
          }
        },
        "text-table": {
          "version": "0.2.0",
          "bundled": true,
          "dev": true
        },
        "through": {
          "version": "2.3.8",
          "bundled": true,
          "dev": true
        },
        "through2": {
          "version": "2.0.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "readable-stream": "^2.1.5",
            "xtend": "~4.0.1"
          }
        },
        "timed-out": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true
        },
        "tiny-relative-date": {
          "version": "1.3.0",
          "bundled": true,
          "dev": true
        },
        "tough-cookie": {
          "version": "2.4.3",
          "bundled": true,
          "dev": true,
          "requires": {
            "psl": "^1.1.24",
            "punycode": "^1.4.1"
          }
        },
        "tunnel-agent": {
          "version": "0.6.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "safe-buffer": "^5.0.1"
          }
        },
        "tweetnacl": {
          "version": "0.14.5",
          "bundled": true,
          "dev": true,
          "optional": true
        },
        "typedarray": {
          "version": "0.0.6",
          "bundled": true,
          "dev": true
        },
        "uid-number": {
          "version": "0.0.6",
          "bundled": true,
          "dev": true
        },
        "umask": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true
        },
        "unique-filename": {
          "version": "1.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "unique-slug": "^2.0.0"
          }
        },
        "unique-slug": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "imurmurhash": "^0.1.4"
          }
        },
        "unique-string": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "crypto-random-string": "^1.0.0"
          }
        },
        "unpipe": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true
        },
        "unzip-response": {
          "version": "2.0.1",
          "bundled": true,
          "dev": true
        },
        "update-notifier": {
          "version": "2.5.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "boxen": "^1.2.1",
            "chalk": "^2.0.1",
            "configstore": "^3.0.0",
            "import-lazy": "^2.1.0",
            "is-ci": "^1.0.10",
            "is-installed-globally": "^0.1.0",
            "is-npm": "^1.0.0",
            "latest-version": "^3.0.0",
            "semver-diff": "^2.0.0",
            "xdg-basedir": "^3.0.0"
          }
        },
        "url-parse-lax": {
          "version": "1.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "prepend-http": "^1.0.1"
          }
        },
        "util-deprecate": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "util-extend": {
          "version": "1.0.3",
          "bundled": true,
          "dev": true
        },
        "uuid": {
          "version": "3.3.2",
          "bundled": true,
          "dev": true
        },
        "validate-npm-package-license": {
          "version": "3.0.4",
          "bundled": true,
          "dev": true,
          "requires": {
            "spdx-correct": "^3.0.0",
            "spdx-expression-parse": "^3.0.0"
          }
        },
        "validate-npm-package-name": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "builtins": "^1.0.3"
          }
        },
        "verror": {
          "version": "1.10.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "assert-plus": "^1.0.0",
            "core-util-is": "1.0.2",
            "extsprintf": "^1.2.0"
          }
        },
        "wcwidth": {
          "version": "1.0.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "defaults": "^1.0.3"
          }
        },
        "which": {
          "version": "1.3.1",
          "bundled": true,
          "dev": true,
          "requires": {
            "isexe": "^2.0.0"
          }
        },
        "which-module": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true
        },
        "wide-align": {
          "version": "1.1.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "string-width": "^1.0.2"
          },
          "dependencies": {
            "string-width": {
              "version": "1.0.2",
              "bundled": true,
              "dev": true,
              "requires": {
                "code-point-at": "^1.0.0",
                "is-fullwidth-code-point": "^1.0.0",
                "strip-ansi": "^3.0.0"
              }
            }
          }
        },
        "widest-line": {
          "version": "2.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "string-width": "^2.1.1"
          }
        },
        "worker-farm": {
          "version": "1.6.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "errno": "~0.1.7"
          }
        },
        "wrap-ansi": {
          "version": "2.1.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "string-width": "^1.0.1",
            "strip-ansi": "^3.0.1"
          },
          "dependencies": {
            "string-width": {
              "version": "1.0.2",
              "bundled": true,
              "dev": true,
              "requires": {
                "code-point-at": "^1.0.0",
                "is-fullwidth-code-point": "^1.0.0",
                "strip-ansi": "^3.0.0"
              }
            }
          }
        },
        "wrappy": {
          "version": "1.0.2",
          "bundled": true,
          "dev": true
        },
        "write-file-atomic": {
          "version": "2.3.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "graceful-fs": "^4.1.11",
            "imurmurhash": "^0.1.4",
            "signal-exit": "^3.0.2"
          }
        },
        "xdg-basedir": {
          "version": "3.0.0",
          "bundled": true,
          "dev": true
        },
        "xtend": {
          "version": "4.0.1",
          "bundled": true,
          "dev": true
        },
        "y18n": {
          "version": "4.0.0",
          "bundled": true,
          "dev": true
        },
        "yallist": {
          "version": "2.1.2",
          "bundled": true,
          "dev": true
        },
        "yargs": {
          "version": "11.0.0",
          "bundled": true,
          "dev": true,
          "requires": {
            "cliui": "^4.0.0",
            "decamelize": "^1.1.1",
            "find-up": "^2.1.0",
            "get-caller-file": "^1.0.1",
            "os-locale": "^2.0.0",
            "require-directory": "^2.1.1",
            "require-main-filename": "^1.0.1",
            "set-blocking": "^2.0.0",
            "string-width": "^2.0.0",
            "which-module": "^2.0.0",
            "y18n": "^3.2.1",
            "yargs-parser": "^9.0.2"
          },
          "dependencies": {
            "y18n": {
              "version": "3.2.1",
              "bundled": true,
              "dev": true
            }
          }
        },
        "yargs-parser": {
          "version": "9.0.2",
          "bundled": true,
          "dev": true,
          "requires": {
            "camelcase": "^4.1.0"
          }
        }
      }
    },
    "npm-run-path": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
      "dev": true,
      "requires": {
        "path-key": "^2.0.0"
      }
    },
    "number-is-nan": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
      "dev": true
    },
    "object-copy": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
      "dev": true,
      "requires": {
        "copy-descriptor": "^0.1.0",
        "define-property": "^0.2.5",
        "kind-of": "^3.0.3"
      },
      "dependencies": {
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "object-visit": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
      "dev": true,
      "requires": {
        "isobject": "^3.0.0"
      }
    },
    "object.pick": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
      "dev": true,
      "requires": {
        "isobject": "^3.0.1"
      }
    },
    "once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
      "dev": true,
      "requires": {
        "wrappy": "1"
      }
    },
    "optimist": {
      "version": "0.6.1",
      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
      "dev": true,
      "requires": {
        "minimist": "~0.0.1",
        "wordwrap": "~0.0.2"
      },
      "dependencies": {
        "minimist": {
          "version": "0.0.10",
          "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
          "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
          "dev": true
        }
      }
    },
    "os-locale": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.0.1.tgz",
      "integrity": "sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw==",
      "dev": true,
      "requires": {
        "execa": "^0.10.0",
        "lcid": "^2.0.0",
        "mem": "^4.0.0"
      },
      "dependencies": {
        "execa": {
          "version": "0.10.0",
          "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
          "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
          "dev": true,
          "requires": {
            "cross-spawn": "^6.0.0",
            "get-stream": "^3.0.0",
            "is-stream": "^1.1.0",
            "npm-run-path": "^2.0.0",
            "p-finally": "^1.0.0",
            "signal-exit": "^3.0.0",
            "strip-eof": "^1.0.0"
          }
        },
        "get-stream": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
          "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
          "dev": true
        }
      }
    },
    "os-name": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/os-name/-/os-name-2.0.1.tgz",
      "integrity": "sha1-uaOGNhwXrjohc27wWZQFyajF3F4=",
      "dev": true,
      "requires": {
        "macos-release": "^1.0.0",
        "win-release": "^1.0.0"
      }
    },
    "p-defer": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
      "dev": true
    },
    "p-filter": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-1.0.0.tgz",
      "integrity": "sha1-Yp0xcVAgnI/VCLoTdxPvS7kg6ds=",
      "dev": true,
      "requires": {
        "p-map": "^1.0.0"
      }
    },
    "p-finally": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
      "dev": true
    },
    "p-is-promise": {
      "version": "1.1.0",
      "resolved": "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
      "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
      "dev": true
    },
    "p-limit": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
      "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
      "dev": true,
      "requires": {
        "p-try": "^1.0.0"
      }
    },
    "p-locate": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
      "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
      "dev": true,
      "requires": {
        "p-limit": "^2.0.0"
      },
      "dependencies": {
        "p-limit": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.0.0.tgz",
          "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==",
          "dev": true,
          "requires": {
            "p-try": "^2.0.0"
          }
        },
        "p-try": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
          "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
          "dev": true
        }
      }
    },
    "p-map": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
      "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
      "dev": true
    },
    "p-reduce": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
      "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=",
      "dev": true
    },
    "p-retry": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-2.0.0.tgz",
      "integrity": "sha512-ZbCuzAmiwJ45q4evp/IG9D+5MUllGSUeCWwPt3j/tdYSi1KPkSD+46uqmAA1LhccDhOXv8kYZKNb8x78VflzfA==",
      "dev": true,
      "requires": {
        "retry": "^0.12.0"
      }
    },
    "p-try": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
      "dev": true
    },
    "parse-github-url": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz",
      "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==",
      "dev": true
    },
    "parse-json": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
      "dev": true,
      "requires": {
        "error-ex": "^1.3.1",
        "json-parse-better-errors": "^1.0.1"
      }
    },
    "parse-url": {
      "version": "1.3.11",
      "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-1.3.11.tgz",
      "integrity": "sha1-V8FUKKuKiSsfQ4aWRccR0OFEtVQ=",
      "dev": true,
      "requires": {
        "is-ssh": "^1.3.0",
        "protocols": "^1.4.0"
      }
    },
    "pascalcase": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
      "dev": true
    },
    "path-dirname": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
      "dev": true
    },
    "path-exists": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
      "dev": true
    },
    "path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
      "dev": true
    },
    "path-key": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
      "dev": true
    },
    "path-type": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
      "dev": true,
      "requires": {
        "pify": "^3.0.0"
      }
    },
    "pify": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
      "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
      "dev": true
    },
    "pkg-conf": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
      "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=",
      "dev": true,
      "requires": {
        "find-up": "^2.0.0",
        "load-json-file": "^4.0.0"
      }
    },
    "posix-character-classes": {
      "version": "0.1.1",
      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
      "dev": true
    },
    "process-nextick-args": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
      "dev": true
    },
    "protocols": {
      "version": "1.4.6",
      "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.6.tgz",
      "integrity": "sha1-+LsmPqG1/Xp2BNJri+Ob13Z4v4o=",
      "dev": true
    },
    "pump": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
      "dev": true,
      "requires": {
        "end-of-stream": "^1.1.0",
        "once": "^1.3.1"
      }
    },
    "q": {
      "version": "1.5.1",
      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
      "dev": true
    },
    "quick-lru": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
      "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=",
      "dev": true
    },
    "rc": {
      "version": "1.2.8",
      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
      "dev": true,
      "requires": {
        "deep-extend": "^0.6.0",
        "ini": "~1.3.0",
        "minimist": "^1.2.0",
        "strip-json-comments": "~2.0.1"
      }
    },
    "read-pkg": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
      "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
      "dev": true,
      "requires": {
        "load-json-file": "^4.0.0",
        "normalize-package-data": "^2.3.2",
        "path-type": "^3.0.0"
      }
    },
    "read-pkg-up": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
      "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
      "dev": true,
      "requires": {
        "find-up": "^3.0.0",
        "read-pkg": "^3.0.0"
      },
      "dependencies": {
        "find-up": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
          "dev": true,
          "requires": {
            "locate-path": "^3.0.0"
          }
        },
        "locate-path": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
          "dev": true,
          "requires": {
            "p-locate": "^3.0.0",
            "path-exists": "^3.0.0"
          }
        }
      }
    },
    "readable-stream": {
      "version": "2.3.6",
      "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
      "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
      "dev": true,
      "requires": {
        "core-util-is": "~1.0.0",
        "inherits": "~2.0.3",
        "isarray": "~1.0.0",
        "process-nextick-args": "~2.0.0",
        "safe-buffer": "~5.1.1",
        "string_decoder": "~1.1.1",
        "util-deprecate": "~1.0.1"
      }
    },
    "redent": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
      "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=",
      "dev": true,
      "requires": {
        "indent-string": "^3.0.0",
        "strip-indent": "^2.0.0"
      }
    },
    "redeyed": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz",
      "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=",
      "dev": true,
      "requires": {
        "esprima": "~4.0.0"
      }
    },
    "regex-not": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
      "dev": true,
      "requires": {
        "extend-shallow": "^3.0.2",
        "safe-regex": "^1.1.0"
      }
    },
    "registry-auth-token": {
      "version": "3.3.2",
      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
      "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
      "dev": true,
      "requires": {
        "rc": "^1.1.6",
        "safe-buffer": "^5.0.1"
      }
    },
    "repeat-element": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
      "dev": true
    },
    "repeat-string": {
      "version": "1.6.1",
      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
      "dev": true
    },
    "require-directory": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
      "dev": true
    },
    "require-main-filename": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
      "dev": true
    },
    "resolve-from": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
      "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
      "dev": true
    },
    "resolve-url": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
      "dev": true
    },
    "ret": {
      "version": "0.1.15",
      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
      "dev": true
    },
    "retry": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
      "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
      "dev": true
    },
    "safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
      "dev": true
    },
    "safe-regex": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
      "dev": true,
      "requires": {
        "ret": "~0.1.10"
      }
    },
    "semantic-release": {
      "version": "15.9.16",
      "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-15.9.16.tgz",
      "integrity": "sha512-5RWqMFwDBXzIaNGUdnJxI4aCd4DtKtdc+5ZNjNWXABEmkimZVuuzZhMaTVNhHYfSuVUqWG9GuATEKhjlVoTzfQ==",
      "dev": true,
      "requires": {
        "@semantic-release/commit-analyzer": "^6.0.0",
        "@semantic-release/error": "^2.2.0",
        "@semantic-release/github": "^5.0.0",
        "@semantic-release/npm": "^5.0.1",
        "@semantic-release/release-notes-generator": "^7.0.0",
        "aggregate-error": "^1.0.0",
        "cosmiconfig": "^5.0.1",
        "debug": "^4.0.0",
        "env-ci": "^3.0.0",
        "execa": "^1.0.0",
        "figures": "^2.0.0",
        "find-versions": "^2.0.0",
        "get-stream": "^4.0.0",
        "git-log-parser": "^1.2.0",
        "git-url-parse": "^10.0.1",
        "hook-std": "^1.1.0",
        "hosted-git-info": "^2.7.1",
        "lodash": "^4.17.4",
        "marked": "^0.5.0",
        "marked-terminal": "^3.0.0",
        "p-locate": "^3.0.0",
        "p-reduce": "^1.0.0",
        "read-pkg-up": "^4.0.0",
        "resolve-from": "^4.0.0",
        "semver": "^5.4.1",
        "signale": "^1.2.1",
        "yargs": "^12.0.0"
      }
    },
    "semver": {
      "version": "5.5.1",
      "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
      "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==",
      "dev": true
    },
    "semver-regex": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz",
      "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=",
      "dev": true
    },
    "set-blocking": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
      "dev": true
    },
    "set-value": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
      "dev": true,
      "requires": {
        "extend-shallow": "^2.0.1",
        "is-extendable": "^0.1.1",
        "is-plain-object": "^2.0.3",
        "split-string": "^3.0.1"
      },
      "dependencies": {
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        }
      }
    },
    "shebang-command": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
      "dev": true,
      "requires": {
        "shebang-regex": "^1.0.0"
      }
    },
    "shebang-regex": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
      "dev": true
    },
    "signal-exit": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
      "dev": true
    },
    "signale": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/signale/-/signale-1.3.0.tgz",
      "integrity": "sha512-TyFhsQ9wZDYDfsPqWMyjCxsDoMwfpsT0130Mce7wDiVCSDdtWSg83dOqoj8aGpGCs3n1YPcam6sT1OFPuGT/OQ==",
      "dev": true,
      "requires": {
        "chalk": "^2.3.2",
        "figures": "^2.0.0",
        "pkg-conf": "^2.1.0"
      }
    },
    "slash": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
      "dev": true
    },
    "snapdragon": {
      "version": "0.8.2",
      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
      "dev": true,
      "requires": {
        "base": "^0.11.1",
        "debug": "^2.2.0",
        "define-property": "^0.2.5",
        "extend-shallow": "^2.0.1",
        "map-cache": "^0.2.2",
        "source-map": "^0.5.6",
        "source-map-resolve": "^0.5.0",
        "use": "^3.1.0"
      },
      "dependencies": {
        "debug": {
          "version": "2.6.9",
          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
          "dev": true,
          "requires": {
            "ms": "2.0.0"
          }
        },
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        },
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "ms": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
          "dev": true
        }
      }
    },
    "snapdragon-node": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
      "dev": true,
      "requires": {
        "define-property": "^1.0.0",
        "isobject": "^3.0.0",
        "snapdragon-util": "^3.0.1"
      },
      "dependencies": {
        "define-property": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^1.0.0"
          }
        },
        "is-accessor-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-data-descriptor": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
          "dev": true,
          "requires": {
            "kind-of": "^6.0.0"
          }
        },
        "is-descriptor": {
          "version": "1.0.2",
          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
          "dev": true,
          "requires": {
            "is-accessor-descriptor": "^1.0.0",
            "is-data-descriptor": "^1.0.0",
            "kind-of": "^6.0.2"
          }
        }
      }
    },
    "snapdragon-util": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
      "dev": true,
      "requires": {
        "kind-of": "^3.2.0"
      },
      "dependencies": {
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "source-map": {
      "version": "0.5.7",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
      "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
      "dev": true
    },
    "source-map-resolve": {
      "version": "0.5.2",
      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
      "dev": true,
      "requires": {
        "atob": "^2.1.1",
        "decode-uri-component": "^0.2.0",
        "resolve-url": "^0.2.1",
        "source-map-url": "^0.4.0",
        "urix": "^0.1.0"
      }
    },
    "source-map-url": {
      "version": "0.4.0",
      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
      "dev": true
    },
    "spawn-error-forwarder": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz",
      "integrity": "sha1-Gv2Uc46ZmwNG17n8NzvlXgdXcCk=",
      "dev": true
    },
    "spdx-correct": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
      "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
      "dev": true,
      "requires": {
        "spdx-expression-parse": "^3.0.0",
        "spdx-license-ids": "^3.0.0"
      }
    },
    "spdx-exceptions": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
      "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
      "dev": true
    },
    "spdx-expression-parse": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
      "dev": true,
      "requires": {
        "spdx-exceptions": "^2.1.0",
        "spdx-license-ids": "^3.0.0"
      }
    },
    "spdx-license-ids": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.1.tgz",
      "integrity": "sha512-TfOfPcYGBB5sDuPn3deByxPhmfegAhpDYKSOXZQN81Oyrrif8ZCodOLzK3AesELnCx03kikhyDwh0pfvvQvF8w==",
      "dev": true
    },
    "split": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
      "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
      "dev": true,
      "requires": {
        "through": "2"
      }
    },
    "split-string": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
      "dev": true,
      "requires": {
        "extend-shallow": "^3.0.0"
      }
    },
    "split2": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
      "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
      "dev": true,
      "requires": {
        "through2": "^2.0.2"
      }
    },
    "sprintf-js": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
      "dev": true
    },
    "static-extend": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
      "dev": true,
      "requires": {
        "define-property": "^0.2.5",
        "object-copy": "^0.1.0"
      },
      "dependencies": {
        "define-property": {
          "version": "0.2.5",
          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
          "dev": true,
          "requires": {
            "is-descriptor": "^0.1.0"
          }
        }
      }
    },
    "stream-combiner2": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
      "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
      "dev": true,
      "requires": {
        "duplexer2": "~0.1.0",
        "readable-stream": "^2.0.2"
      }
    },
    "string-width": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
      "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
      "dev": true,
      "requires": {
        "is-fullwidth-code-point": "^2.0.0",
        "strip-ansi": "^4.0.0"
      }
    },
    "string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dev": true,
      "requires": {
        "safe-buffer": "~5.1.0"
      }
    },
    "strip-ansi": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
      "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
      "dev": true,
      "requires": {
        "ansi-regex": "^3.0.0"
      }
    },
    "strip-bom": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
      "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
      "dev": true
    },
    "strip-eof": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
      "dev": true
    },
    "strip-indent": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
      "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
      "dev": true
    },
    "strip-json-comments": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
      "dev": true
    },
    "supports-color": {
      "version": "5.5.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
      "dev": true,
      "requires": {
        "has-flag": "^3.0.0"
      }
    },
    "text-extensions": {
      "version": "1.8.0",
      "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.8.0.tgz",
      "integrity": "sha512-mVzjRxuWnDKs/qH1rbOJEVHLlSX9kty9lpi7lMvLgU9S74mQ8/Ozg9UPcKxShh0qG2NZ+NyPOPpcZU4C1Eld9A==",
      "dev": true
    },
    "through": {
      "version": "2.3.8",
      "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
      "dev": true
    },
    "through2": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
      "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
      "dev": true,
      "requires": {
        "readable-stream": "^2.1.5",
        "xtend": "~4.0.1"
      }
    },
    "to-object-path": {
      "version": "0.3.0",
      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
      "dev": true,
      "requires": {
        "kind-of": "^3.0.2"
      },
      "dependencies": {
        "kind-of": {
          "version": "3.2.2",
          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
          "dev": true,
          "requires": {
            "is-buffer": "^1.1.5"
          }
        }
      }
    },
    "to-regex": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
      "dev": true,
      "requires": {
        "define-property": "^2.0.2",
        "extend-shallow": "^3.0.2",
        "regex-not": "^1.0.2",
        "safe-regex": "^1.1.0"
      }
    },
    "to-regex-range": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
      "dev": true,
      "requires": {
        "is-number": "^3.0.0",
        "repeat-string": "^1.6.1"
      }
    },
    "traverse": {
      "version": "0.6.6",
      "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
      "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=",
      "dev": true
    },
    "trim-newlines": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
      "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=",
      "dev": true
    },
    "trim-off-newlines": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz",
      "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=",
      "dev": true
    },
    "uglify-js": {
      "version": "3.4.9",
      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
      "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
      "dev": true,
      "optional": true,
      "requires": {
        "commander": "~2.17.1",
        "source-map": "~0.6.1"
      },
      "dependencies": {
        "source-map": {
          "version": "0.6.1",
          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
          "dev": true,
          "optional": true
        }
      }
    },
    "union-value": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
      "dev": true,
      "requires": {
        "arr-union": "^3.1.0",
        "get-value": "^2.0.6",
        "is-extendable": "^0.1.1",
        "set-value": "^0.4.3"
      },
      "dependencies": {
        "extend-shallow": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
          "dev": true,
          "requires": {
            "is-extendable": "^0.1.0"
          }
        },
        "set-value": {
          "version": "0.4.3",
          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
          "dev": true,
          "requires": {
            "extend-shallow": "^2.0.1",
            "is-extendable": "^0.1.1",
            "is-plain-object": "^2.0.1",
            "to-object-path": "^0.3.0"
          }
        }
      }
    },
    "universal-user-agent": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.0.1.tgz",
      "integrity": "sha512-vz+heWVydO0iyYAa65VHD7WZkYzhl7BeNVy4i54p4TF8OMiLSXdbuQe4hm+fmWAsL+rVibaQHXfhvkw3c1Ws2w==",
      "dev": true,
      "requires": {
        "os-name": "^2.0.1"
      }
    },
    "universalify": {
      "version": "0.1.2",
      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
      "dev": true
    },
    "unset-value": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
      "dev": true,
      "requires": {
        "has-value": "^0.3.1",
        "isobject": "^3.0.0"
      },
      "dependencies": {
        "has-value": {
          "version": "0.3.1",
          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
          "dev": true,
          "requires": {
            "get-value": "^2.0.3",
            "has-values": "^0.1.4",
            "isobject": "^2.0.0"
          },
          "dependencies": {
            "isobject": {
              "version": "2.1.0",
              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
              "dev": true,
              "requires": {
                "isarray": "1.0.0"
              }
            }
          }
        },
        "has-values": {
          "version": "0.1.4",
          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
          "dev": true
        }
      }
    },
    "urix": {
      "version": "0.1.0",
      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
      "dev": true
    },
    "url-join": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.0.tgz",
      "integrity": "sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=",
      "dev": true
    },
    "url-template": {
      "version": "2.0.8",
      "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
      "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=",
      "dev": true
    },
    "use": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
      "dev": true
    },
    "util-deprecate": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
      "dev": true
    },
    "validate-npm-package-license": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
      "dev": true,
      "requires": {
        "spdx-correct": "^3.0.0",
        "spdx-expression-parse": "^3.0.0"
      }
    },
    "which": {
      "version": "1.3.1",
      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
      "dev": true,
      "requires": {
        "isexe": "^2.0.0"
      }
    },
    "which-module": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
      "dev": true
    },
    "win-release": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz",
      "integrity": "sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk=",
      "dev": true,
      "requires": {
        "semver": "^5.0.1"
      }
    },
    "wordwrap": {
      "version": "0.0.3",
      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
      "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
      "dev": true
    },
    "wrap-ansi": {
      "version": "2.1.0",
      "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
      "dev": true,
      "requires": {
        "string-width": "^1.0.1",
        "strip-ansi": "^3.0.1"
      },
      "dependencies": {
        "ansi-regex": {
          "version": "2.1.1",
          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
          "dev": true
        },
        "is-fullwidth-code-point": {
          "version": "1.0.0",
          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
          "dev": true,
          "requires": {
            "number-is-nan": "^1.0.0"
          }
        },
        "string-width": {
          "version": "1.0.2",
          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
          "dev": true,
          "requires": {
            "code-point-at": "^1.0.0",
            "is-fullwidth-code-point": "^1.0.0",
            "strip-ansi": "^3.0.0"
          }
        },
        "strip-ansi": {
          "version": "3.0.1",
          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
          "dev": true,
          "requires": {
            "ansi-regex": "^2.0.0"
          }
        }
      }
    },
    "wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
      "dev": true
    },
    "xregexp": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz",
      "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==",
      "dev": true
    },
    "xtend": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
      "dev": true
    },
    "y18n": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
      "dev": true
    },
    "yargs": {
      "version": "12.0.2",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz",
      "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==",
      "dev": true,
      "requires": {
        "cliui": "^4.0.0",
        "decamelize": "^2.0.0",
        "find-up": "^3.0.0",
        "get-caller-file": "^1.0.1",
        "os-locale": "^3.0.0",
        "require-directory": "^2.1.1",
        "require-main-filename": "^1.0.1",
        "set-blocking": "^2.0.0",
        "string-width": "^2.0.0",
        "which-module": "^2.0.0",
        "y18n": "^3.2.1 || ^4.0.0",
        "yargs-parser": "^10.1.0"
      },
      "dependencies": {
        "decamelize": {
          "version": "2.0.0",
          "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz",
          "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==",
          "dev": true,
          "requires": {
            "xregexp": "4.0.0"
          }
        },
        "find-up": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
          "dev": true,
          "requires": {
            "locate-path": "^3.0.0"
          }
        },
        "locate-path": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
          "dev": true,
          "requires": {
            "p-locate": "^3.0.0",
            "path-exists": "^3.0.0"
          }
        }
      }
    },
    "yargs-parser": {
      "version": "10.1.0",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
      "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
      "dev": true,
      "requires": {
        "camelcase": "^4.1.0"
      }
    }
  }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Signature help options.
 */
class SignatureHelpOptions
{
    /**
     * The characters that trigger signature help automatically.
     *
     * @var string[]|null
     */
    public $triggerCharacters;
    /**
     * @param string[]|null $triggerCharacters
     */
    public function __construct(array $triggerCharacters = null)
    {
        $this->triggerCharacters = $triggerCharacters;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class SemanticTokensClientCapabilitiesRequests
{
    /**
     * The client will send the `textDocument/semanticTokens/range` request
     * if the server provides a corresponding handler.
     *
     * @var mixed|null
     */
    public $range;
    /**
     * The client will send the `textDocument/semanticTokens/full` request
     * if the server provides a corresponding handler.
     *
     * @var mixed|null
     */
    public $full;
    public function __construct(bool $range = null, bool $full = null)
    {
        $this->range = $range;
        $this->full = $full;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * The result of a hover request.
 */
class Hover
{
    /**
     * The hover's content
     *
     * @var string|MarkedString|string[]|MarkedString[]|MarkupContent
     */
    public $contents;
    /**
     * An optional range
     *
     * @var Range|null
     */
    public $range;
    /**
     * @param string|MarkedString|string[]|MarkedString[]|MarkupContent $contents The hover's content
     * @param Range $range An optional range
     */
    public function __construct($contents = null, $range = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->contents = $contents;
        $this->range = $range;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentRangeFormattingClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class TypeDefinitionClientCapabilities
{
    /**
     * Whether implementation supports dynamic registration. If this is set to
     * `true` the client supports the new `TypeDefinitionRegistrationOptions`
     * return value for the corresponding server capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports additional metadata in the form of definition links.
     *
     * @since 3.14.0
     *
     * @var boolean|null
     */
    public $linkSupport;
    public function __construct(bool $dynamicRegistration = null, bool $linkSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->linkSupport = $linkSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class InitializeResultServerInfo
{
    /**
     * The name of the server as defined by the server.
     *
     * @var string
     */
    public $name;
    /**
     * The server's version as defined by the server.
     *
     * @var string|null
     */
    public $version;
    public function __construct(string $name, string $version = null)
    {
        $this->name = $name;
        $this->version = $version;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionClientCapabilitiesCompletionItem
{
    /**
     * Client supports snippets as insert text.
     *
     * A snippet can define tab stops and placeholders with `$1`, `$2`
     * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
     * the end of the snippet. Placeholders with equal identifiers are
     * linked, that is typing in one will update others too.
     *
     * @var bool|null
     */
    public $snippetSupport;
    /**
     * Client supports commit characters on a completion item.
     *
     * @var bool|null
     */
    public $commitCharactersSupport;
    /**
     * Client supports the follow content formats for the documentation
     * property. The order describes the preferred format of the client.
     *
     * @var string[]|null
     */
    public $documentationFormat;
    /**
     * Client supports the deprecated property on a completion item.
     *
     * @var bool|null
     */
    public $deprecatedSupport;
    /**
     * Client supports the preselect property on a completion item.
     *
     * @var bool|null
     */
    public $preselectSupport;
    /**
     * Client supports the tag property on a completion item. Clients
     * supporting tags have to handle unknown tags gracefully. Clients
     * especially need to preserve unknown tags when sending a completion
     * item back to the server in a resolve call.
     *
     * @since 3.15.0
     *
     * @var CompletionClientCapabilitiesCompletionItemTagSupport|null
     */
    public $tagSupport;
    /**
     * Client supports insert replace edit to control different behavior if
     * a completion item is inserted in the text or should replace text.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $insertReplaceSupport;
    /**
     * Indicates which properties a client can resolve lazily on a
     * completion item. Before version 3.16.0 only the predefined properties
     * `documentation` and `detail` could be resolved lazily.
     *
     * @since 3.16.0
     *
     * @var CompletionClientCapabilitiesCompletionItemResolveSupport|null
     */
    public $resolveSupport;
    /**
     * The client supports the `insertTextMode` property on
     * a completion item to override the whitespace handling mode
     * as defined by the client (see `insertTextMode`).
     *
     * @since 3.16.0
     *
     * @var CompletionClientCapabilitiesCompletionItemInsertTextModeSupport|null
     */
    public $insertTextModeSupport;
    /**
     * The client has support for completion item label
     * details (see also `CompletionItemLabelDetails`).
     *
     * @since 3.17.0 - proposed state
     *
     * @var bool|null
     */
    public $labelDetailsSupport;
    /**
     * Undocumented function
     *
     * @param boolean|null $snippetSupport
     * @param boolean|null $commitCharactersSupport
     * @param string[]|null $documentationFormat
     * @param boolean|null $deprecatedSupport
     * @param boolean|null $preselectSupport
     * @param CompletionClientCapabilitiesCompletionItemTagSupport|null $tagSupport
     * @param boolean|null $insertReplaceSupport
     * @param CompletionClientCapabilitiesCompletionItemResolveSupport|null $resolveSupport
     * @param CompletionClientCapabilitiesCompletionItemInsertTextModeSupport|null $insertTextModeSupport
     * @param boolean|null $labelDetailsSupport
     */
    public function __construct(bool $snippetSupport = null, bool $commitCharactersSupport = null, array $documentationFormat = null, bool $deprecatedSupport = null, bool $preselectSupport = null, CompletionClientCapabilitiesCompletionItemTagSupport $tagSupport = null, bool $insertReplaceSupport = null, CompletionClientCapabilitiesCompletionItemResolveSupport $resolveSupport = null, CompletionClientCapabilitiesCompletionItemInsertTextModeSupport $insertTextModeSupport = null, bool $labelDetailsSupport = null)
    {
        $this->snippetSupport = $snippetSupport;
        $this->commitCharactersSupport = $commitCharactersSupport;
        $this->documentationFormat = $documentationFormat;
        $this->deprecatedSupport = $deprecatedSupport;
        $this->preselectSupport = $preselectSupport;
        $this->tagSupport = $tagSupport;
        $this->insertReplaceSupport = $insertReplaceSupport;
        $this->resolveSupport = $resolveSupport;
        $this->insertTextModeSupport = $insertTextModeSupport;
        $this->labelDetailsSupport = $labelDetailsSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Structure to capture a description for an error code.
 *
 * @since 3.16.0
 */
class CodeDescription
{
    /**
     * An URI to open with more information about the diagnostic error.
     *
     * @var string
     */
    public $href;
    public function __construct(string $href)
    {
        $this->href = $href;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

abstract class DiagnosticSeverity
{
    /**
     * Reports an error.
     */
    const ERROR = 1;
    /**
     * Reports a warning.
     */
    const WARNING = 2;
    /**
     * Reports an information.
     */
    const INFORMATION = 3;
    /**
     * Reports a hint.
     */
    const HINT = 4;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Value-object describing what options formatting should use.
 */
class FormattingOptions
{
    /**
     * Size of a tab in spaces.
     *
     * @var int
     */
    public $tabSize;
    /**
     * Prefer spaces over tabs.
     *
     * @var bool
     */
    public $insertSpaces;
    // Can be extended with further properties.
    public function __construct(int $tabSize = null, bool $insertSpaces = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->tabSize = $tabSize;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->insertSpaces = $insertSpaces;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Additional details for a completion item label.
 *
 * @since 3.17.0 - proposed state
 */
class CompletionItemLabelDetails
{
    /**
     * An optional string which is rendered less prominently directly after
     * {@link CompletionItem.label label}, without any spacing. Should be
     * used for function signatures or type annotations.
     *
     * @var string|null
     */
    public $detail;
    /**
     * An optional string which is rendered less prominently after
     * {@link CompletionItemLabelDetails.detail}. Should be used for fully qualified
     * names or file path.
     *
     * @var string|null
     */
    public $description;
    public function __construct(string $detail = null, string $description = null)
    {
        $this->detail = $detail;
        $this->description = $description;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents a location inside a resource, such as a line inside a text file.
 */
class Location
{
    /**
     * @var string
     */
    public $uri;
    /**
     * @var Range
     */
    public $range;
    public function __construct(string $uri = null, Range $range = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->uri = $uri;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->range = $range;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionItem
{
    /**
     * The label of this completion item. By default
     * also the text that is inserted when selecting
     * this completion.
     *
     * @var string
     */
    public $label;
    /**
     * Additional details for the label
     *
     * @since 3.17.0 - proposed state
     *
     * @var CompletionItemLabelDetails|null
     */
    public $labelDetails;
    /**
     * The kind of this completion item. Based of the kind
     * an icon is chosen by the editor.
     *
     * @var int|null
     * @see CompletionItemKind
     */
    public $kind;
    /**
     * Tags for this completion item.
     *
     * @since 3.15.0
     *
     * @var CompletionItemTag[]|null
     */
    public $tags;
    /**
     * A human-readable string with additional information
     * about this item, like type or symbol information.
     *
     * @var string|null
     */
    public $detail;
    /**
     * A human-readable string that represents a doc-comment.
     *
     * @var string|null
     */
    public $documentation;
    /**
     * Indicates if this item is deprecated.
     *
     * @deprecated Use `tags` instead if supported.
     *
     * @var bool|null
     */
    public $deprecated;
    /**
     * Select this item when showing.
     *
     * *Note* that only one completion item can be selected and that the
     * tool / client decides which item that is. The rule is that the *first*
     * item of those that match best is selected.
     *
     * @var bool|null
     */
    public $preselect;
    /**
     * A string that should be used when comparing this item
     * with other items. When `falsy` the label is used.
     *
     * @var string|null
     */
    public $sortText;
    /**
     * A string that should be used when filtering a set of
     * completion items. When `falsy` the label is used.
     *
     * @var string|null
     */
    public $filterText;
    /**
     * A string that should be inserted into a document when selecting
     * this completion. When `falsy` the label is used as the insert text
     * for this item.
     *
     * The `insertText` is subject to interpretation by the client side.
     * Some tools might not take the string literally. For example
     * VS Code when code complete is requested in this example
     * `con<cursor position>` and a completion item with an `insertText` of
     * `console` is provided it will only insert `sole`. Therefore it is
     * recommended to use `textEdit` instead since it avoids additional client
     * side interpretation.
     *
     * @var string|null
     */
    public $insertText;
    /**
     * The format of the insert text. The format applies to both the
     * `insertText` property and the `newText` property of a provided
     * `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.
     *
     * Please note that the insertTextFormat doesn't apply to
     * `additionalTextEdits`.
     *
     * @var int|null
     * @see InsertTextFormat
     */
    public $insertTextFormat;
    /**
     * How whitespace and indentation is handled during completion
     * item insertion. If not provided the client's default value depends on
     * the `textDocument.completion.insertTextMode` client capability.
     *
     * @since 3.16.0
     * @since 3.17.0 - support for `textDocument.completion.insertTextMode`
     *
     * @var int|null
     * @see InsertTextMode
     */
    public $insertTextMode;
    /**
     * An edit which is applied to a document when selecting this completion.
     * When an edit is provided the value of `insertText` is ignored.
     *
     * *Note:* The range of the edit must be a single line range and it must
     * contain the position at which completion has been requested.
     *
     * Most editors support two different operations when accepting a completion
     * item. One is to insert a completion text and the other is to replace an
     * existing text with a completion text. Since this can usually not be
     * predetermined by a server it can report both ranges. Clients need to
     * signal support for `InsertReplaceEdit`s via the
     * `textDocument.completion.completionItem.insertReplaceSupport` client
     * capability property.
     *
     * *Note 1:* The text edit's range as well as both ranges from an insert
     * replace edit must be a [single line] and they must contain the position
     * at which completion has been requested.
     * *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range
     * must be a prefix of the edit's replace range, that means it must be
     * contained and starting at the same position.
     *
     * @since 3.16.0 additional type `InsertReplaceEdit`
     *
     * @var TextEdit|null
     */
    public $textEdit;
    /**
     * An optional array of additional text edits that are applied when
     * selecting this completion. Edits must not overlap (including the same
     * insert position) with the main edit nor with themselves.
     *
     * Additional text edits should be used to change text unrelated to the
     * current cursor position (for example adding an import statement at the
     * top of the file if the completion item will insert an unqualified type).
     *
     * @var TextEdit[]|null
     */
    public $additionalTextEdits;
    /**
     * An optional set of characters that when pressed while this completion is
     * active will accept it first and then type that character. *Note* that all
     * commit characters should have `length=1` and that superfluous characters
     * will be ignored.
     *
     * @var string[]|null
     */
    public $commitCharacters;
    /**
     * An optional command that is executed *after* inserting this completion. *Note* that
     * additional modifications to the current document should be described with the
     * additionalTextEdits-property.
     *
     * @var Command|null
     */
    public $command;
    /**
     * An data entry field that is preserved on a completion item between
     * a completion and a completion resolve request.
     *
     * @var mixed
     */
    public $data;
    /**
     * @param string          $label
     * @param int|null        $kind
     * @param string|null     $detail
     * @param string|null     $documentation
     * @param string|null     $sortText
     * @param string|null     $filterText
     * @param string|null     $insertText
     * @param TextEdit|null   $textEdit
     * @param TextEdit[]|null $additionalTextEdits
     * @param Command|null    $command
     * @param mixed|null      $data
     * @param int|null        $insertTextFormat
     */
    public function __construct(string $label = null, int $kind = null, string $detail = null, string $documentation = null, string $sortText = null, string $filterText = null, string $insertText = null, TextEdit $textEdit = null, array $additionalTextEdits = null, Command $command = null, $data = null, int $insertTextFormat = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->label = $label;
        $this->kind = $kind;
        $this->detail = $detail;
        $this->documentation = $documentation;
        $this->sortText = $sortText;
        $this->filterText = $filterText;
        $this->insertText = $insertText;
        $this->textEdit = $textEdit;
        $this->additionalTextEdits = $additionalTextEdits;
        $this->command = $command;
        $this->data = $data;
        $this->insertTextFormat = $insertTextFormat;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A detailed structure defining expected notifications from the client of changes to text documents.
 */
class TextDocumentSyncOptions
{
    /**
     * Open and close notifications are sent to the server.
     * @var bool|null
     */
    public $openClose;
    /**
     * Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
     * and TextDocumentSyncKindIncremental.
     * @var int|null
     */
    public $change;
    /**
     * Will save notifications get sent to the server.
     * @var bool|null
     */
    public $willSave;
    /**
     * Will save wait until requests get sent to the server.
     * @var bool|null
     */
    public $willSaveWaitUntil;
    /**
     * Save notifications are sent to the server.
     * @var SaveOptions|null
     */
    public $save;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class RenameClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * Client supports testing for validity of rename operations
     * before execution.
     *
     * @since version 3.12.0
     *
     * @var bool|null
     */
    public $prepareSupport;
    /**
     * Client supports the default behavior result
     * (`{ defaultBehavior: boolean }`).
     *
     * The value indicates the default behavior used by the
     * client.
     *
     * @since version 3.16.0
     *
     * @var int|null
     */
    public $prepareSupportDefaultBehavior;
    /**
     * Whether th client honors the change annotations in
     * text edits and resource operations returned via the
     * rename request's workspace edit by for example presenting
     * the workspace edit in the user interface and asking
     * for confirmation.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $honorsChangeAnnotations;
    /**
     * @param boolean|null $dynamicRegistration
     * @param boolean|null $prepareSupport
     * @param integer|null $prepareSupportDefaultBehavior PrepareSupportDefaultBehavior
     * @param boolean|null $honorsChangeAnnotations
     */
    public function __construct(bool $dynamicRegistration = null, bool $prepareSupport = null, int $prepareSupportDefaultBehavior = null, bool $honorsChangeAnnotations = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->prepareSupport = $prepareSupport;
        $this->prepareSupportDefaultBehavior = $prepareSupportDefaultBehavior;
        $this->honorsChangeAnnotations = $honorsChangeAnnotations;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Defines whether the insert text in a completion item should be interpreted as
 * plain text or a snippet.
 */
abstract class InsertTextFormat
{
    /**
     * The primary text to be inserted is treated as a plain string.
     */
    const PLAIN_TEXT = 1;
    /**
     * The primary text to be inserted is treated as a snippet.
     *
     * A snippet can define tab stops and placeholders with `$1`, `$2`
     * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
     * the end of the snippet. Placeholders with equal identifiers are linked,
     * that is typing in one will update others too.
     */
    const SNIPPET = 2;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A document highlight is a range inside a text document which deserves
 * special attention. Usually a document highlight is visualized by changing
 * the background color of its range.
 */
class DocumentHighlight
{
    /**
     * The range this highlight applies to.
     *
     * @var Range
     */
    public $range;
    /**
     * The highlight kind, default is DocumentHighlightKind::TEXT.
     *
     * @var int|null
     */
    public $kind;
    public function __construct(Range $range = null, int $kind = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->range = $range;
        $this->kind = $kind;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ShowMessageRequestClientCapabilities
{
    /**
     * Capabilities specific to the `MessageActionItem` type.
     *
     * @var ShowMessageRequestClientCapabilitiesMessageActionItem|null
     */
    public $messageActionItem;
    public function __construct(ShowMessageRequestClientCapabilitiesMessageActionItem $messageActionItem = null)
    {
        $this->messageActionItem = $messageActionItem;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ReferenceContext
{
    /**
     * Include the declaration of the current symbol.
     *
     * @var bool
     */
    public $includeDeclaration;
    public function __construct(bool $includeDeclaration = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->includeDeclaration = $includeDeclaration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * How whitespace and indentation is handled during completion
 * item insertion.
 *
 * @since 3.16.0
 */
abstract class DiagnosticTag
{
    /**
     * Unused or unnecessary code.
     *
     * Clients are allowed to render diagnostics with this tag faded out
     * instead of having an error squiggle.
     */
    const UNNECESSARY = 1;
    /**
     * Deprecated or obsolete code.
     *
     * Clients are allowed to rendered diagnostics with this tag strike through.
     */
    const DEPRECATED = 2;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class TextDocumentSyncClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports sending will save notifications.
     *
     * @var bool|null
     */
    public $willSave;
    /**
     * The client supports sending a will save request and
     * waits for a response providing text edits which will
     * be applied to the document before it is saved.
     *
     * @var bool|null
     */
    public $willSaveWaitUntil;
    /**
     * The client supports did save notifications.
     *
     * @var bool|null
     */
    public $didSave;
    public function __construct(bool $dynamicRegistration = null, bool $willSave = null, bool $willSaveWaitUntil = null, bool $didSave = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->willSave = $willSave;
        $this->willSaveWaitUntil = $willSaveWaitUntil;
        $this->didSave = $didSave;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents information about programming constructs like variables, classes,
 * interfaces etc.
 */
class SymbolInformation
{
    /**
     * The name of this symbol.
     *
     * @var string
     */
    public $name;
    /**
     * The kind of this symbol.
     *
     * @var int
     */
    public $kind;
    /**
     * The location of this symbol.
     *
     * @var Location
     */
    public $location;
    /**
     * The name of the symbol containing this symbol.
     *
     * @var string|null
     */
    public $containerName;
    /**
     * @param string $name
     * @param int $kind
     * @param Location $location
     * @param string $containerName
     */
    public function __construct($name = null, $kind = null, $location = null, $containerName = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->name = $name;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->kind = $kind;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->location = $location;
        $this->containerName = $containerName;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * An event describing a change to a text document. If range and rangeLength are omitted
 * the new text is considered to be the full content of the document.
 */
class TextDocumentContentChangeEvent
{
    /**
     * The range of the document that changed.
     *
     * @var Range|null
     */
    public $range;
    /**
     * The length of the range that got replaced.
     *
     * @var int|null
     */
    public $rangeLength;
    /**
     * The new text of the document.
     *
     * @var string
     */
    public $text;
    public function __construct(Range $range = null, int $rangeLength = null, string $text = null)
    {
        $this->range = $range;
        $this->rangeLength = $rangeLength;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->text = $text;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Defines how the host (editor) should sync document changes to the language server.
 */
abstract class FailureHandlingKind
{
    /**
     * Applying the workspace change is simply aborted if one of the changes
     * provided fails. All operations executed before the failing operation
     * stay executed.
     */
    const ABORT = 'abort';
    /**
     * All operations are executed transactional. That means they either all
     * succeed or no changes at all are applied to the workspace.
     */
    const TRANSACTIONAL = 'transactional';
    /**
     * If the workspace edit contains only textual file changes they are
     * executed transactional. If resource changes (create, rename or delete
     * file) are part of the change the failure handling strategy is abort.
     */
    const TEXT_ONLY_TRANSACTIONAL = 'textOnlyTransactional';
    /**
     * The client tries to undo the operations already executed. But there is no
     * guarantee that this is succeeding.
     */
    const UNDO = 'undo';
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A symbol kind.
 */
abstract class SymbolKind
{
    const FILE = 1;
    const MODULE = 2;
    const NAMESPACE = 3;
    const PACKAGE = 4;
    const CLASS_ = 5;
    const METHOD = 6;
    const PROPERTY = 7;
    const FIELD = 8;
    const CONSTRUCTOR = 9;
    const ENUM = 10;
    const INTERFACE = 11;
    const FUNCTION = 12;
    const VARIABLE = 13;
    const CONSTANT = 14;
    const STRING = 15;
    const NUMBER = 16;
    const BOOLEAN = 17;
    const ARRAY = 18;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentHighlightClientCapabilities
{
    /**
     * Whether references supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class WorkspaceEditClientCapabilitiesChangeAnnotationSupport
{
    /**
     * Whether the client groups edits with equal labels into tree nodes,
     * for instance all edits labelled with "Changes in Strings" would
     * be a tree node.
     *
     * @var bool|null
     */
    public $groupsOnLabel;
    public function __construct(bool $groupsOnLabel = null)
    {
        $this->groupsOnLabel = $groupsOnLabel;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Options controlling what is sent to the server with save notifications.
 */
class SaveOptions
{
    /**
     * The client is supposed to include the content on save.
     * @var bool|null
     */
    public $includeText;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * The kind of a completion entry.
 */
abstract class CompletionItemKind
{
    const TEXT = 1;
    const METHOD = 2;
    const FUNCTION = 3;
    const CONSTRUCTOR = 4;
    const FIELD = 5;
    const VARIABLE = 6;
    const CLASS_ = 7;
    const INTERFACE = 8;
    const MODULE = 9;
    const PROPERTY = 10;
    const UNIT = 11;
    const VALUE = 12;
    const ENUM = 13;
    const KEYWORD = 14;
    const SNIPPET = 15;
    const COLOR = 16;
    const FILE = 17;
    const REFERENCE = 18;
    /**
     * Returns the CompletionItemKind for a SymbolKind
     *
     * @param int $kind A SymbolKind
     * @return int The CompletionItemKind
     */
    public static function fromSymbolKind(int $kind) : int
    {
        switch ($kind) {
            case SymbolKind::PROPERTY:
            case SymbolKind::FIELD:
                return self::PROPERTY;
            case SymbolKind::METHOD:
                return self::METHOD;
            case SymbolKind::CLASS_:
                return self::CLASS_;
            case SymbolKind::INTERFACE:
                return self::INTERFACE;
            case SymbolKind::FUNCTION:
                return self::FUNCTION;
            case SymbolKind::NAMESPACE:
            case SymbolKind::MODULE:
            case SymbolKind::PACKAGE:
                return self::MODULE;
            case SymbolKind::FILE:
                return self::FILE;
            case SymbolKind::NUMBER:
            case SymbolKind::BOOLEAN:
            case SymbolKind::ARRAY:
                return self::VALUE;
            case SymbolKind::ENUM:
                return self::ENUM;
            case SymbolKind::CONSTRUCTOR:
                return self::CONSTRUCTOR;
            case SymbolKind::VARIABLE:
            case SymbolKind::CONSTANT:
                return self::VARIABLE;
            case SymbolKind::STRING:
            default:
                return self::TEXT;
        }
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionClientCapabilitiesCompletionList
{
    /**
     * The client supports the the following itemDefaults on
     * a completion list.
     *
     * The value lists the supported property names of the
     * `CompletionList.itemDefaults` object. If omitted
     * no properties are supported.
     *
     * @since 3.17.0 - proposed state
     *
     * @var string[]|null
     */
    public $itemDefaults;
    /**
     * @param string[]|null $itemDefaults
     */
    public function __construct(array $itemDefaults = null)
    {
        $this->itemDefaults = $itemDefaults;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class MarkdownClientCapabilities
{
    /**
     * The name of the parser.
     *
     * @var string
     */
    public $parser;
    /**
     * The version of the parser.
     *
     * @var string|null
     */
    public $version;
    /**
     * A list of HTML tags that the client allows / supports in
     * Markdown.
     *
     * @since 3.17.0
     *
     * @var string[]|null
     */
    public $allowedTags;
    /**
     * @param string|null $parser
     * @param string|null $version
     * @param string[]|null $allowedTags
     */
    public function __construct(string $parser = null, string $version = null, array $allowedTags = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->parser = $parser;
        $this->version = $version;
        $this->allowedTags = $allowedTags;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A range in a text document expressed as (zero-based) start and end positions.
 */
class Range
{
    /**
     * The range's start position.
     *
     * @var Position
     */
    public $start;
    /**
     * The range's end position.
     *
     * @var Position
     */
    public $end;
    public function __construct(Position $start = null, Position $end = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->start = $start;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->end = $end;
    }
    /**
     * Checks if a position is within the range
     *
     * @param Position $position
     * @return bool
     */
    public function includes(Position $position) : bool
    {
        return $this->start->compare($position) <= 0 && $this->end->compare($position) >= 0;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ClientCapabilitiesGeneral
{
    /**
     * Client capabilities specific to regular expressions.
     *
     * @since 3.16.0
     *
     * @var RegularExpressionsClientCapabilities|null
     */
    public $regularExpressions;
    /**
     * Client capabilities specific to the client's markdown parser.
     *
     * @since 3.16.0
     *
     * @var MarkdownClientCapabilities|null
     */
    public $markdown;
    public function __construct(RegularExpressionsClientCapabilities $regularExpressions = null, MarkdownClientCapabilities $markdown = null)
    {
        $this->regularExpressions = $regularExpressions;
        $this->markdown = $markdown;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Position in a text document expressed as zero-based line and character offset.
 */
class Position
{
    /**
     * Line position in a document (zero-based).
     *
     * @var int
     */
    public $line;
    /**
     * Character offset on a line in a document (zero-based).
     *
     * @var int
     */
    public $character;
    public function __construct(int $line = null, int $character = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->line = $line;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->character = $character;
    }
    /**
     * Compares this position to another position
     * Returns
     *  - 0 if the positions match
     *  - a negative number if $this is before $position
     *  - a positive number otherwise
     *
     * @param Position $position
     * @return int
     */
    public function compare(Position $position) : int
    {
        if ($this->line === $position->line && $this->character === $position->character) {
            return 0;
        }
        if ($this->line !== $position->line) {
            return $this->line - $position->line;
        }
        return $this->character - $position->character;
    }
    /**
     * Returns the offset of the position in a string
     *
     * @param string $content
     * @return int
     */
    public function toOffset(string $content) : int
    {
        $lines = \explode("\n", $content);
        $slice = \array_slice($lines, 0, $this->line);
        return \array_sum(\array_map('strlen', $slice)) + \count($slice) + $this->character;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Uniquely identifies a symbol
 */
class SymbolDescriptor
{
    /**
     * The fully qualified structural element name, a globally unique identifier for the symbol.
     *
     * @var string
     */
    public $fqsen;
    /**
     * Identifies the Composer package the symbol is defined in (if any)
     *
     * @var PackageDescriptor|null
     */
    public $package;
    /**
     * @param string $fqsen              The fully qualified structural element name, a globally
     *                                   unique identifier for the symbol.
     * @param PackageDescriptor $package Identifies the Composer package the symbol is defined in
     */
    public function __construct(string $fqsen = null, PackageDescriptor $package = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->fqsen = $fqsen;
        $this->package = $package;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentColorClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DefinitionClientCapabilities
{
    /**
     * Whether definition supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports additional metadata in the form of definition links.
     *
     * @since 3.14.0
     *
     * @var bool|null
     */
    public $linkSupport;
    public function __construct(bool $dynamicRegistration = null, bool $linkSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->linkSupport = $linkSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Signature help represents the signature of something
 * callable. There can be multiple signature but only one
 * active and only one active parameter.
 */
class SignatureHelp
{
    /**
     * One or more signatures. If no signatures are available the signature help
     * request should return `null`.
     *
     * @var SignatureInformation[]|null
     */
    public $signatures;
    /**
     * The active signature. If omitted or the value lies outside the
     * range of `signatures` the value defaults to zero or is ignore if
     * the `SignatureHelp` as no signatures.
     *
     * Whenever possible implementors should make an active decision about
     * the active signature and shouldn't rely on a default value.
     *
     * In future version of the protocol this property might become
     * mandatory to better express this.
     *
     * @var int|null
     */
    public $activeSignature;
    /**
     * The active parameter of the active signature. If omitted or the value
     * lies outside the range of `signatures[activeSignature].parameters`
     * defaults to 0 if the active signature has parameters. If
     * the active signature has no parameters it is ignored.
     * In future version of the protocol this property might become
     * mandatory to better express the active parameter if the
     * active signature does have any.
     *
     * @var int|null
     */
    public $activeParameter;
    /**
     * Create a SignatureHelp
     *
     * @param SignatureInformation[]|null $signatures      List of signature information
     * @param int|null               $activeSignature The active signature, zero based
     * @param int|null               $activeParameter The active parameter, zero based
     */
    public function __construct(array $signatures = null, $activeSignature = null, int $activeParameter = null)
    {
        $this->signatures = $signatures;
        $this->activeSignature = $activeSignature;
        $this->activeParameter = $activeParameter;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DependencyReference
{
    /**
     * @var mixed
     */
    public $hints;
    /**
     * @var object
     */
    public $attributes;
    /**
     * @param object $attributes
     * @param mixed  $hints
     */
    public function __construct($attributes = null, $hints = null)
    {
        $this->attributes = $attributes ?? new \stdClass();
        $this->hints = $hints;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class TextDocumentIdentifier
{
    /**
     * The text document's URI.
     *
     * @var string
     */
    public $uri;
    /**
     * @param string $uri The text document's URI.
     */
    public function __construct(string $uri = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->uri = $uri;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class HoverClientCapabilities
{
    /**
     * Whether hover supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * Client supports the follow content formats if the content
     * property refers to a `literal of type MarkupContent`.
     * The order describes the preferred format of the client.
     *
     * @var string[]|null
     * @see MarkupKind
     */
    public $contentFormat;
    /**
     * @param boolean|null $dynamicRegistration
     * @param string[]|null $contentFormat
     */
    public function __construct(bool $dynamicRegistration = null, array $contentFormat = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->contentFormat = $contentFormat;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CallHierarchyClientCapabilities
{
    /**
     * Whether implementation supports dynamic registration. If this is set to
     * `true` the client supports the new `(TextDocumentRegistrationOptions &
     * StaticRegistrationOptions)` return value for the corresponding server
     * capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(?bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class PublishDiagnosticsClientCapabilities
{
    /**
     * Whether the clients accepts diagnostics with related information.
     *
     * @var bool|null
     */
    public $relatedInformation;
    /**
     * Client supports the tag property to provide meta data about a diagnostic.
     * Clients supporting tags have to handle unknown tags gracefully.
     *
     * @since 3.15.0
     *
     * @var PublishDiagnosticsClientCapabilitiesTagSupport|null
     */
    public $tagSupport;
    /**
     * Whether the client interprets the version property of the
     * `textDocument/publishDiagnostics` notification's parameter.
     *
     * @since 3.15.0
     *
     * @var bool|null
     */
    public $versionSupport;
    /**
     * Client supports a codeDescription property
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $codeDescriptionSupport;
    /**
     * Whether code action supports the `data` property which is
     * preserved between a `textDocument/publishDiagnostics` and
     * `textDocument/codeAction` request.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $dataSupport;
    public function __construct(bool $relatedInformation = null, PublishDiagnosticsClientCapabilitiesTagSupport $tagSupport = null, bool $versionSupport = null, bool $codeDescriptionSupport = null, bool $dataSupport = null)
    {
        $this->relatedInformation = $relatedInformation;
        $this->tagSupport = $tagSupport;
        $this->versionSupport = $versionSupport;
        $this->codeDescriptionSupport = $codeDescriptionSupport;
        $this->dataSupport = $dataSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionClientCapabilitiesCompletionItemInsertTextModeSupport
{
    /**
     * The tags supported by the client.
     *
     * @var int[]
     */
    public $valueSet;
    /**
     * @param int[] $valueSet InsertTextMode
     */
    public function __construct(array $valueSet = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ClientCapabilitiesWorkspaceFileOperations
{
    /**
     * Whether the client supports dynamic registration for file
     * requests/notifications.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client has support for sending didCreateFiles notifications.
     *
     * @var bool|null
     */
    public $didCreate;
    /**
     * The client has support for sending willCreateFiles requests.
     *
     * @var bool|null
     */
    public $willCreate;
    /**
     * The client has support for sending didRenameFiles notifications.
     *
     * @var bool|null
     */
    public $didRename;
    /**
     * The client has support for sending willRenameFiles requests.
     *
     * @var bool|null
     */
    public $willRename;
    /**
     * The client has support for sending didDeleteFiles notifications.
     *
     * @var bool|null
     */
    public $didDelete;
    /**
     * The client has support for sending willDeleteFiles requests.
     *
     * @var bool|null
     */
    public $willDelete;
    public function __construct(bool $dynamicRegistration = null, bool $didCreate = null, bool $willCreate = null, bool $didRename = null, bool $willRename = null, bool $didDelete = null, bool $willDelete = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->didCreate = $didCreate;
        $this->willCreate = $willCreate;
        $this->didRename = $didRename;
        $this->willRename = $willRename;
        $this->didDelete = $didDelete;
        $this->willDelete = $willDelete;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class MessageActionItem
{
    /**
     * A short title like 'Retry', 'Open Log' etc.
     *
     * @var string
     */
    public $title;
    public function __construct(string $title = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->title = $title;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Enum
 */
abstract class ErrorCode
{
    const PARSE_ERROR = -32700;
    const INVALID_REQUEST = -32600;
    const METHOD_NOT_FOUND = -32601;
    const INVALID_PARAMS = -32602;
    const INTERNAL_ERROR = -32603;
    const SERVER_ERROR_START = -32099;
    const SERVER_ERROR_END = -32000;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Describes the content type that a client supports in various
 * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
 *
 * Please note that `MarkupKinds` must not start with a `$`. This kinds
 * are reserved for internal usage.
 */
abstract class MarkupKind
{
    /**
     * Plain text is supported as a content format
     */
    const PLAINTEXT = 'plaintext';
    /**
     * Markdown is supported as a content format
     */
    const MARKDOWN = 'markdown';
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

abstract class TokenFormat
{
    const RELATIVE = 'relative';
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class WorkspaceSymbolClientCapabilitiesResolveSupport
{
    /**
     * The properties that a client can resolve lazily. Usually
     * `location.range`
     *
     * @var string[]
     */
    public $properties;
    /**
     * @param string[] $properties
     */
    public function __construct(array $properties = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->properties = $properties;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentSymbolClientCapabilitiesTagSupport
{
    /**
     * The symbol kind values the client supports. When this
     * property exists the client also guarantees that it will
     * handle values outside its set gracefully and falls back
     * to a default value when unknown.
     *
     * If this property is not present the client only supports
     * the symbol kinds from `File` to `Array` as defined in
     * the initial version of the protocol.
     *
     * @var int[]
     */
    public $valueSet;
    /**
     * Undocumented function
     *
     * @param int[]|null $valueSet
     */
    public function __construct(array $valueSet = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class MarkedString
{
    /**
     * @var string
     */
    public $language;
    /**
     * @var string
     */
    public $value;
    public function __construct(string $language = null, string $value = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->language = $language;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->value = $value;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * The log message notification is sent from the server to the client to ask the client to log a particular message.
 */
class LogMessage
{
    /**
     * The message type. See {@link MessageType}
     *
     * @var int
     * @see MessageType
     */
    public $type;
    /**
     * The actual message
     *
     * @var string
     */
    public $message;
    public function __construct(int $type, string $message)
    {
        $this->type = $type;
        $this->message = $message;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class InitializeResult
{
    /**
     * The capabilities the language server provides.
     *
     * @var ServerCapabilities
     */
    public $capabilities;
    /**
     * Information about the server.
     *
     * @since 3.15.0
     *
     * @var InitializeResultServerInfo|null
     */
    public $serverInfo;
    public function __construct(ServerCapabilities $capabilities = null, InitializeResultServerInfo $serverInfo = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->capabilities = $capabilities;
        $this->serverInfo = $serverInfo;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

use JsonSerializable;
/**
 * A workspace edit represents changes to many resources managed in the workspace.
 */
class WorkspaceEdit implements JsonSerializable
{
    /**
     * Holds changes to existing resources. Associative Array from URI to TextEdit
     *
     * @var array<string, TextEdit[]>
     */
    public $changes;
    /**
     * Depending on the client capability
     * `workspace.workspaceEdit.resourceOperations` document changes are either
     * an array of `TextDocumentEdit`s to express changes to n different text
     * documents where each text document edit addresses a specific version of
     * a text document. Or it can contain above `TextDocumentEdit`s mixed with
     * create, rename and delete file / folder operations.
     *
     * Whether a client supports versioned document edits is expressed via
     * `workspace.workspaceEdit.documentChanges` client capability.
     *
     * If a client neither supports `documentChanges` nor
     * `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
     * using the `changes` property are supported.
     *
     * @var mixed
     */
    public $documentChanges;
    /**
     * A map of change annotations that can be referenced in
     * `AnnotatedTextEdit`s or create, rename and delete file / folder
     * operations.
     *
     * Whether clients honor this property depends on the client capability
     * `workspace.changeAnnotationSupport`.
     *
     * @since 3.16.0
     *
     * @var array<string, ChangeAnnotation>|null
     */
    public $changeAnnotations;
    /**
     * @param array<string, TextEdit[]> $changes
     * @param mixed $documentChanges
     * @param array<string, ChangeAnnotation>|null $changeAnnotations
     */
    public function __construct(array $changes = [], $documentChanges = null, array $changeAnnotations = null)
    {
        $this->changes = $changes;
        $this->documentChanges = $documentChanges;
        $this->changeAnnotations = $changeAnnotations;
    }
    /**
     * This is needed because VSCode Does not like nulls
     * meaning if a null is sent then this will not compute
     *
     * @return mixed
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
        return \array_filter(\get_object_vars($this));
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Uniquely identifies a Composer package
 */
class PackageDescriptor
{
    /**
     * The package name
     *
     * @var string
     */
    public $name;
    /**
     * @param string $name The package name
     */
    public function __construct(string $name = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->name = $name;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ExecuteCommandClientCapabilities
{
    /**
     * Execute command supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents a diagnostic, such as a compiler error or warning. Diagnostic objects are only valid in the scope of a
 * resource.
 */
class Diagnostic
{
    /**
     * The range at which the message applies.
     *
     * @var Range
     */
    public $range;
    /**
     * The diagnostic's severity. Can be omitted. If omitted it is up to the
     * client to interpret diagnostics as error, warning, info or hint.
     *
     * @var int|null
     */
    public $severity;
    /**
     * The diagnostic's code. which might appear in the user interface
     *
     * @var int|null
     */
    public $code;
    /**
     * An optional property to describe the error code.
     *
     * @since 3.16.0
     *
     * @var CodeDescription|null
     */
    public $codeDescription;
    /**
     * A human-readable string describing the source of this
     * diagnostic, e.g. 'typescript' or 'super lint'.
     *
     * @var string|null
     */
    public $source;
    /**
     * The diagnostic's message.
     *
     * @var string
     */
    public $message;
    /**
     * Additional metadata about the diagnostic.
     *
     * @since 3.15.0
     *
     * @var int[]|null
     * @see DiagnosticTag
     */
    public $tags;
    /**
     * An array of related diagnostic information, e.g. when symbol-names within
     * a scope collide all definitions can be marked via this property.
     *
     * @var DiagnosticRelatedInformation[]|null
     */
    public $relatedInformation;
    /**
     * A data entry field that is preserved between a
     * `textDocument/publishDiagnostics` notification and
     * `textDocument/codeAction` request.
     *
     * @since 3.16.0
     *
     * @var mixed|null
     */
    public $data;
    /**
     * @param  string|null $message  The diagnostic's message
     * @param  Range|null  $range    The range at which the message applies
     * @param  int|null    $code     The diagnostic's code
     * @param  int|null    $severity DiagnosticSeverity
     * @param  string|null $source   A human-readable string describing the source of this diagnostic
     * @param  CodeDescription|null $codeDescription
     * @param  int[]|null  $tags     Additional metadata about the diagnostic
     * @param  DiagnosticRelatedInformation[]|null  $relatedInformation Related diagnostic information
     * @param  mixed  $data     A data entry field that is preserved between a `textDocument/publishDiagnostics`
     *                          notification and `textDocument/codeAction` request
     */
    public function __construct(string $message = null, Range $range = null, int $code = null, int $severity = null, string $source = null, CodeDescription $codeDescription = null, array $tags = null, array $relatedInformation = null, $data = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->message = $message;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->range = $range;
        $this->code = $code;
        $this->severity = $severity;
        $this->source = $source;
        $this->codeDescription = $codeDescription;
        $this->tags = $tags;
        $this->relatedInformation = $relatedInformation;
        $this->data = $data;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class WorkspaceSymbolClientCapabilitiesTagSupport
{
    /**
     * The symbol kind values the client supports. When this
     * property exists the client also guarantees that it will
     * handle values outside its set gracefully and falls back
     * to a default value when unknown.
     *
     * If this property is not present the client only supports
     * the symbol kinds from `File` to `Array` as defined in
     * the initial version of the protocol.
     *
     * @var int[]|null
     * @see SymbolTag
     */
    public $valueSet;
    /**
     * @param int[]|null $valueSet
     */
    public function __construct(array $valueSet = null)
    {
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class LinkedEditingRangeClientCapabilities
{
    /**
     * Whether implementation supports dynamic registration.
     * If this is set to `true` the client supports the new
     * `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
     * return value for the corresponding server capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class SignatureHelpClientCapabilities
{
    /**
     * Whether signature help supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports the following `SignatureInformation`
     * specific properties.
     *
     * @var SignatureHelpClientCapabilitiesSignatureInformation|null
     */
    public $signatureInformation;
    /**
     * The client supports to send additional context information for a
     * `textDocument/signatureHelp` request. A client that opts into
     * contextSupport will also support the `retriggerCharacters` on
     * `SignatureHelpOptions`.
     *
     * @since 3.15.0
     *
     * @var bool|null
     */
    public $contextSupport;
    public function __construct(bool $dynamicRegistration = null, SignatureHelpClientCapabilitiesSignatureInformation $signatureInformation = null, bool $contextSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->signatureInformation = $signatureInformation;
        $this->contextSupport = $contextSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ReferenceClientCapabilities
{
    /**
     * Whether references supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class SymbolLocationInformation
{
    /**
     * The location where the symbol is defined, if any.
     *
     * @var Location|null
     */
    public $location;
    /**
     * Metadata about the symbol that can be used to identify or locate its
     * definition.
     *
     * @var SymbolDescriptor
     */
    public $symbol;
    /**
     * @param SymbolDescriptor $symbol   The location where the symbol is defined, if any
     * @param Location         $location Metadata about the symbol that can be used to identify or locate its definition
     */
    public function __construct(SymbolDescriptor $symbol = null, Location $location = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->symbol = $symbol;
        $this->location = $location;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ShowDocumentClientCapabilities
{
    /**
     * The client has support for the show document
     * request.
     *
     * @var bool|null
     */
    public $support;
    public function __construct(?bool $support = null)
    {
        $this->support = $support;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A set of predefined code action kinds.
 */
abstract class CodeActionKind
{
    /**
     * Empty kind.
     */
    const EMPTY = '';
    /**
     * Base kind for quickfix actions: 'quickfix'.
     */
    const QUICK_FIX = 'quickfix';
    /**
     * Base kind for refactoring actions: 'refactor'.
     */
    const REFACTOR = 'refactor';
    /**
     * Base kind for refactoring extraction actions: 'refactor.extract'.
     *
     * Example extract actions:
     *
     * - Extract method
     * - Extract function
     * - Extract variable
     * - Extract interface from class
     * - ...
     */
    const REFACTOR_EXTRACT = 'refactor.extract';
    /**
     * Base kind for refactoring inline actions: 'refactor.inline'.
     *
     * Example inline actions:
     *
     * - Inline function
     * - Inline variable
     * - Inline constant
     * - ...
     */
    const REFACTOR_INLINE = 'refactor.inline';
    /**
     * Base kind for refactoring rewrite actions: 'refactor.rewrite'.
     *
     * Example rewrite actions:
     *
     * - Convert JavaScript function to class
     * - Add or remove parameter
     * - Encapsulate field
     * - Make method static
     * - Move method to base class
     * - ...
     */
    const REFACTOR_REWRITE = 'refactor.rewrite';
    /**
     * Base kind for source actions: `source`.
     *
     * Source code actions apply to the entire file.
     */
    const SOURCE = 'source';
    /**
     * Base kind for an organize imports source action:
     * `source.organizeImports`.
     */
    const SOURCE_ORGANIZE_IMPORTS = 'source.organizeImports';
    /**
     * Base kind for a 'fix all' source action: `source.fixAll`.
     *
     * 'Fix all' actions automatically fix errors that have a clear fix that
     * do not require user input. They should not suppress errors or perform
     * unsafe fixes such as generating new types or classes.
     *
     * @since 3.17.0
     */
    const SOURCE_FIX_ALL = 'source.fixAll';
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ClientCapabilities
{
    /**
     * Workspace specific client capabilities.
     *
     * @var ClientCapabilitiesWorkspace|null
     */
    public $workspace;
    /**
     * Text document specific client capabilities.
     *
     * @var TextDocumentClientCapabilities|null
     */
    public $textDocument;
    /**
     * Window specific client capabilities.
     *
     * @var ClientCapabilitiesWindow|null
     */
    public $window;
    /**
     * General client capabilities.
     *
     * @since 3.16.0
     *
     * @var ClientCapabilitiesGeneral|null
     */
    public $general;
    /**
     * Experimental client capabilities.
     *
     * @var mixed|null
     */
    public $experimental;
    /**
     * The client supports workspace/xfiles requests
     *
     * @var bool|null
     */
    public $xfilesProvider;
    /**
     * The client supports textDocument/xcontent requests
     *
     * @var bool|null
     */
    public $xcontentProvider;
    /**
     * The client supports xcache/* requests
     *
     * @var bool|null
     */
    public $xcacheProvider;
    /**
     * Undocumented function
     *
     * @param ClientCapabilitiesWorkspace|null $workspace
     * @param TextDocumentClientCapabilities|null $textDocument
     * @param ClientCapabilitiesWindow|null $window
     * @param ClientCapabilitiesGeneral|null $general
     * @param mixed|null $experimental
     * @param bool|null $xfilesProvider
     * @param bool|null $xcontentProvider
     * @param bool|null $xcacheProvider
     */
    public function __construct(ClientCapabilitiesWorkspace $workspace = null, TextDocumentClientCapabilities $textDocument = null, ClientCapabilitiesWindow $window = null, ClientCapabilitiesGeneral $general = null, $experimental = null, bool $xfilesProvider = null, bool $xcontentProvider = null, bool $xcacheProvider = null)
    {
        $this->workspace = $workspace;
        $this->textDocument = $textDocument;
        $this->window = $window;
        $this->general = $general;
        $this->experimental = $experimental;
        $this->xfilesProvider = $xfilesProvider;
        $this->xcontentProvider = $xcontentProvider;
        $this->xcacheProvider = $xcacheProvider;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class VersionedTextDocumentIdentifier extends TextDocumentIdentifier
{
    /**
     * The version number of this document.
     *
     * @var int
     */
    public $version;
    public function __construct(string $uri = null, int $version = null)
    {
        parent::__construct($uri);
        $this->version = $version;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Defines how the host (editor) should sync document changes to the language server.
 */
abstract class TextDocumentSyncKind
{
    /**
     * Documents should not be synced at all.
     */
    const NONE = 0;
    /**
     * Documents are synced by always sending the full content of the document.
     */
    const FULL = 1;
    /**
     * Documents are synced by sending the full content on open. After that only
     * incremental updates to the document are sent.
     */
    const INCREMENTAL = 2;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class RegularExpressionsClientCapabilities
{
    /**
     * The engine's name.
     *
     * @var string
     */
    public $engine;
    /**
     * The engine's version.
     *
     * @var string|null
     */
    public $version;
    /**
     * @param string $engine
     * @param string|null $version
     */
    public function __construct(string $engine = null, string $version = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->engine = $engine;
        $this->version = $version;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ShowMessageRequestClientCapabilitiesMessageActionItem
{
    /**
     * Whether the client supports additional attributes which
     * are preserved and sent back to the server in the
     * request's response.
     *
     * @var bool|null
     */
    public $additionalPropertiesSupport;
    public function __construct(bool $additionalPropertiesSupport = null)
    {
        $this->additionalPropertiesSupport = $additionalPropertiesSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CodeActionDisabled
{
    /**
     * Human readable description of why the code action is currently
     * disabled.
     *
     * This is displayed in the code actions UI.
     *
     * @var string
     */
    public $reason;
    public function __construct(string $reason)
    {
        $this->reason = $reason;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class WorkspaceSymbolClientCapabilities
{
    /**
     * Symbol request supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * Specific capabilities for the `SymbolKind` in the `workspace/symbol`
     * request.
     *
     * @var WorkspaceSymbolClientCapabilitiesSymbolKind|null
     */
    public $symbolKind;
    /**
     * The client supports tags on `SymbolInformation` and `WorkspaceSymbol`.
     * Clients supporting tags have to handle unknown tags gracefully.
     *
     * @since 3.16.0
     *
     * @var WorkspaceSymbolClientCapabilitiesTagSupport|null
     */
    public $tagSupport;
    /**
     * The client support partial workspace symbols. The client will send the
     * request `workspaceSymbol/resolve` to the server to resolve additional
     * properties.
     *
     * @since 3.17.0 - proposedState
     *
     * @var WorkspaceSymbolClientCapabilitiesResolveSupport|null
     */
    public $resolveSupport;
    public function __construct(bool $dynamicRegistration = null, WorkspaceSymbolClientCapabilitiesSymbolKind $symbolKind = null, WorkspaceSymbolClientCapabilitiesTagSupport $tagSupport = null, WorkspaceSymbolClientCapabilitiesResolveSupport $resolveSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->symbolKind = $symbolKind;
        $this->tagSupport = $tagSupport;
        $this->resolveSupport = $resolveSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Contains additional information about the context in which a completion request is triggered.
 */
class CompletionContext
{
    /**
     * How the completion was triggered.
     *
     * @var int
     */
    public $triggerKind;
    /**
     * The trigger character (a single character) that has trigger code complete.
     * Is null if `triggerKind !== CompletionTriggerKind::TRIGGER_CHARACTER`
     *
     * @var string|null
     */
    public $triggerCharacter;
    public function __construct(int $triggerKind = null, string $triggerCharacter = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->triggerKind = $triggerKind;
        $this->triggerCharacter = $triggerCharacter;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ClientCapabilitiesWorkspace
{
    /**
     * The client supports applying batch edits
     * to the workspace by supporting the request
     * 'workspace/applyEdit'
     *
     * @var bool|null
     */
    public $applyEdit;
    /**
     * Capabilities specific to `WorkspaceEdit`s
     *
     * @var WorkspaceEditClientCapabilities|null
     */
    public $workspaceEdit;
    /**
     * Capabilities specific to the `workspace/didChangeConfiguration`
     * notification.
     *
     * @var DidChangeConfigurationClientCapabilities|null
     */
    public $didChangeConfiguration;
    /**
     * Capabilities specific to the `workspace/didChangeWatchedFiles`
     * notification.
     *
     * @var DidChangeWatchedFilesClientCapabilities|null
     */
    public $didChangeWatchedFiles;
    /**
     * Capabilities specific to the `workspace/symbol` request.
     *
     * @var WorkspaceSymbolClientCapabilities|null
     */
    public $symbol;
    /**
     * Capabilities specific to the `workspace/executeCommand` request.
     *
     * @var ExecuteCommandClientCapabilities|null
     */
    public $executeCommand;
    /**
     * The client has support for workspace folders.
     *
     * @since 3.6.0
     *
     * @var bool|null
     */
    public $workspaceFolders;
    /**
     * The client supports `workspace/configuration` requests.
     *
     * @since 3.6.0
     *
     * @var bool|null
     */
    public $configuration;
    /**
     * Capabilities specific to the semantic token requests scoped to the
     * workspace.
     *
     * @since 3.16.0
     *
     * @var SemanticTokensWorkspaceClientCapabilities|null
     */
    public $semanticTokens;
    /**
     * Capabilities specific to the code lens requests scoped to the
     * workspace.
     *
     * @since 3.16.0
     *
     * @var CodeLensWorkspaceClientCapabilities|null
     */
    public $codeLens;
    /**
     * The client has support for file requests/notifications.
     *
     * @since 3.16.0
     *
     * @var ClientCapabilitiesWorkspaceFileOperations|null
     */
    public $fileOperations;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class SelectionRangeClientCapabilities
{
    /**
     * Whether implementation supports dynamic registration for selection range
     * providers. If this is set to `true` the client supports the new
     * `SelectionRangeRegistrationOptions` return value for the corresponding
     * server capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class TextDocumentClientCapabilities
{
    /**
     * @var TextDocumentSyncClientCapabilities|null
     */
    public $synchronization;
    /**
     * Capabilities specific to the `textDocument/completion` request.
     *
     * @var CompletionClientCapabilities|null
     */
    public $completion;
    /**
     * Capabilities specific to the `textDocument/hover` request.
     *
     * @var HoverClientCapabilities|null
     */
    public $hover;
    /**
     * Capabilities specific to the `textDocument/signatureHelp` request.
     *
     * @var SignatureHelpClientCapabilities|null
     */
    public $signatureHelp;
    /**
     * Capabilities specific to the `textDocument/declaration` request.
     *
     * @since 3.14.0
     *
     * @var DeclarationClientCapabilities|null
     */
    public $declaration;
    /**
     * Capabilities specific to the `textDocument/definition` request.
     *
     * @var DefinitionClientCapabilities|null
     */
    public $definition;
    /**
     * Capabilities specific to the `textDocument/typeDefinition` request.
     *
     * @since 3.6.0
     *
     * @var TypeDefinitionClientCapabilities|null
     */
    public $typeDefinition;
    /**
     * Capabilities specific to the `textDocument/implementation` request.
     *
     * @since 3.6.0
     *
     * @var ImplementationClientCapabilities|null
     */
    public $implementation;
    /**
     * Capabilities specific to the `textDocument/references` request.
     *
     * @var ReferenceClientCapabilities|null
     */
    public $references;
    /**
     * Capabilities specific to the `textDocument/documentHighlight` request.
     *
     * @var DocumentHighlightClientCapabilities|null
     */
    public $documentHighlight;
    /**
     * Capabilities specific to the `textDocument/documentSymbol` request.
     *
     * @var DocumentSymbolClientCapabilities|null
     */
    public $documentSymbol;
    /**
     * Capabilities specific to the `textDocument/codeAction` request.
     *
     * @var CodeActionClientCapabilities|null
     */
    public $codeAction;
    /**
     * Capabilities specific to the `textDocument/codeLens` request.
     *
     * @var CodeLensClientCapabilities|null
     */
    public $codeLens;
    /**
     * Capabilities specific to the `textDocument/documentLink` request.
     *
     * @var DocumentLinkClientCapabilities|null
     */
    public $documentLink;
    /**
     * Capabilities specific to the `textDocument/documentColor` and the
     * `textDocument/colorPresentation` request.
     *
     * @since 3.6.0
     *
     * @var DocumentColorClientCapabilities|null
     */
    public $colorProvider;
    /**
     * Capabilities specific to the `textDocument/formatting` request.
     *
     * @var DocumentFormattingClientCapabilities|null
     */
    public $formatting;
    /**
     * Capabilities specific to the `textDocument/rangeFormatting` request.
     *
     * @var DocumentRangeFormattingClientCapabilities|null
     */
    public $rangeFormatting;
    /** request.
     * Capabilities specific to the `textDocument/onTypeFormatting` request.
     *
     * @var DocumentOnTypeFormattingClientCapabilities|null
     */
    public $onTypeFormatting;
    /**
     * Capabilities specific to the `textDocument/rename` request.
     *
     * @var RenameClientCapabilities|null
     */
    public $rename;
    /**
     * Capabilities specific to the `textDocument/publishDiagnostics`
     * notification.
     *
     * @var PublishDiagnosticsClientCapabilities|null
     */
    public $publishDiagnostics;
    /**
     * Capabilities specific to the `textDocument/foldingRange` request.
     *
     * @since 3.10.0
     *
     * @var FoldingRangeClientCapabilities|null
     */
    public $foldingRange;
    /**
     * Capabilities specific to the `textDocument/selectionRange` request.
     *
     * @since 3.15.0
     *
     * @var SelectionRangeClientCapabilities|null
     */
    public $selectionRange;
    /**
     * Capabilities specific to the `textDocument/linkedEditingRange` request.
     *
     * @since 3.16.0
     *
     * @var LinkedEditingRangeClientCapabilities|null
     */
    public $linkedEditingRange;
    /**
     * Capabilities specific to the various call hierarchy requests.
     *
     * @since 3.16.0
     *
     * @var CallHierarchyClientCapabilities|null
     */
    public $callHierarchy;
    /**
     * Capabilities specific to the various semantic token requests.
     *
     * @since 3.16.0
     *
     * @var SemanticTokensClientCapabilities|null
     */
    public $semanticTokens;
    /**
     * Capabilities specific to the `textDocument/moniker` request.
     *
     * @since 3.16.0
     *
     * @var MonikerClientCapabilities|null
     */
    public $moniker;
    public function __construct(TextDocumentSyncClientCapabilities $synchronization = null, CompletionClientCapabilities $completion = null, HoverClientCapabilities $hover = null, SignatureHelpClientCapabilities $signatureHelp = null, DeclarationClientCapabilities $declaration = null, DefinitionClientCapabilities $definition = null, TypeDefinitionClientCapabilities $typeDefinition = null, ImplementationClientCapabilities $implementation = null, ReferenceClientCapabilities $references = null, DocumentHighlightClientCapabilities $documentHighlight = null, DocumentSymbolClientCapabilities $documentSymbol = null, CodeActionClientCapabilities $codeAction = null, CodeLensClientCapabilities $codeLens = null, DocumentLinkClientCapabilities $documentLink = null, DocumentColorClientCapabilities $colorProvider = null, DocumentFormattingClientCapabilities $formatting = null, DocumentRangeFormattingClientCapabilities $rangeFormatting = null, DocumentOnTypeFormattingClientCapabilities $onTypeFormatting = null, RenameClientCapabilities $rename = null, PublishDiagnosticsClientCapabilities $publishDiagnostics = null, FoldingRangeClientCapabilities $foldingRange = null, SelectionRangeClientCapabilities $selectionRange = null, LinkedEditingRangeClientCapabilities $linkedEditingRange = null, CallHierarchyClientCapabilities $callHierarchy = null, SemanticTokensClientCapabilities $semanticTokens = null, MonikerClientCapabilities $moniker = null)
    {
        $this->synchronization = $synchronization;
        $this->completion = $completion;
        $this->hover = $hover;
        $this->signatureHelp = $signatureHelp;
        $this->declaration = $declaration;
        $this->definition = $definition;
        $this->typeDefinition = $typeDefinition;
        $this->implementation = $implementation;
        $this->references = $references;
        $this->documentHighlight = $documentHighlight;
        $this->documentSymbol = $documentSymbol;
        $this->codeAction = $codeAction;
        $this->codeLens = $codeLens;
        $this->documentLink = $documentLink;
        $this->colorProvider = $colorProvider;
        $this->formatting = $formatting;
        $this->rangeFormatting = $rangeFormatting;
        $this->onTypeFormatting = $onTypeFormatting;
        $this->rename = $rename;
        $this->publishDiagnostics = $publishDiagnostics;
        $this->foldingRange = $foldingRange;
        $this->selectionRange = $selectionRange;
        $this->linkedEditingRange = $linkedEditingRange;
        $this->callHierarchy = $callHierarchy;
        $this->semanticTokens = $semanticTokens;
        $this->moniker = $moniker;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class SemanticTokensClientCapabilities
{
    /**
     * Whether implementation supports dynamic registration. If this is set to
     * `true` the client supports the new `(TextDocumentRegistrationOptions &
     * StaticRegistrationOptions)` return value for the corresponding server
     * capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * Which requests the client supports and might send to the server
     * depending on the server's capability. Please note that clients might not
     * show semantic tokens or degrade some of the user experience if a range
     * or full request is advertised by the client but not provided by the
     * server. If for example the client capability `requests.full` and
     * `request.range` are both set to true but the server only provides a
     * range provider the client might not render a minimap correctly or might
     * even decide to not show any semantic tokens at all.
     *
     * @var SemanticTokensClientCapabilitiesRequests
     */
    public $requests;
    /**
     * The token types that the client supports.
     *
     * @var string[]
     */
    public $tokenTypes;
    /**
     * The token modifiers that the client supports.
     *
     * @var string[]
     */
    public $tokenModifiers;
    /**
     * The formats the clients supports.
     *
     * @var string[]
     * @see TokenFormat
     */
    public $formats;
    /**
     * Whether the client supports tokens that can overlap each other.
     *
     * @var bool|null
     */
    public $overlappingTokenSupport;
    /**
     * Whether the client supports tokens that can span multiple lines.
     *
     * @var bool|null
     */
    public $multilineTokenSupport;
    /**
     * Whether the client allows the server to actively cancel a
     * semantic token request, e.g. supports returning
     * ErrorCodes.ServerCancelled. If a server does the client
     * needs to retrigger the request.
     *
     * @since 3.17.0
     *
     * @var bool|null
     */
    public $serverCancelSupport;
    /**
     * Whether the client uses semantic tokens to augment existing
     * syntax tokens. If set to `true` client side created syntax
     * tokens and semantic tokens are both used for colorization. If
     * set to `false` the client only uses the returned semantic tokens
     * for colorization.
     *
     * If the value is `undefined` then the client behavior is not
     * specified.
     *
     * @since 3.17.0
     *
     * @var bool|null
     */
    public $augmentsSyntaxTokens;
    /**
     * Undocumented function
     *
     * @param SemanticTokensClientCapabilitiesRequests|null $requests
     * @param string[]|null $tokenTypes
     * @param string[]|null $tokenModifiers
     * @param string[]|null $formats
     * @param boolean|null $dynamicRegistration
     * @param boolean|null $overlappingTokenSupport
     * @param boolean|null $multilineTokenSupport
     * @param boolean|null $serverCancelSupport
     * @param boolean|null $augmentsSyntaxTokens
     */
    public function __construct(SemanticTokensClientCapabilitiesRequests $requests = null, array $tokenTypes = null, array $tokenModifiers = null, array $formats = null, bool $dynamicRegistration = null, bool $overlappingTokenSupport = null, bool $multilineTokenSupport = null, bool $serverCancelSupport = null, bool $augmentsSyntaxTokens = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->requests = $requests;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->tokenTypes = $tokenTypes;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->tokenModifiers = $tokenModifiers;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->formats = $formats;
        $this->dynamicRegistration = $dynamicRegistration;
        $this->overlappingTokenSupport = $overlappingTokenSupport;
        $this->multilineTokenSupport = $multilineTokenSupport;
        $this->serverCancelSupport = $serverCancelSupport;
        $this->augmentsSyntaxTokens = $augmentsSyntaxTokens;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Specific capabilities for the `SymbolKind` in the
 * `textDocument/documentSymbol` request.
 */
class DocumentSymbolClientCapabilitiesSymbolKind
{
    /**
     * The symbol kind values the client supports. When this
     * property exists the client also guarantees that it will
     * handle values outside its set gracefully and falls back
     * to a default value when unknown.
     *
     * If this property is not present the client only supports
     * the symbol kinds from `File` to `Array` as defined in
     * the initial version of the protocol.
     *
     * @var int[]
     * @see SymbolKind
     */
    public $valueSet;
    /**
     * Undocumented function
     *
     * @param int[]|null $valueSet
     */
    public function __construct(array $valueSet = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * An item to transfer a text document from the client to the server.
 */
class TextDocumentItem
{
    /**
     * The text document's URI.
     *
     * @var string
     */
    public $uri;
    /**
     * The text document's language identifier.
     *
     * @var string
     */
    public $languageId;
    /**
     * The version number of this document (it will strictly increase after each
     * change, including undo/redo).
     *
     * @var int
     */
    public $version;
    /**
     * The content of the opened text document.
     *
     * @var string
     */
    public $text;
    public function __construct(string $uri = null, string $languageId = null, int $version = null, string $text = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->uri = $uri;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->languageId = $languageId;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->version = $version;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->text = $text;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ChangeAnnotation
{
    /**
     * A human-readable string describing the actual change. The string
     * is rendered prominent in the user interface.
     *
     * @var string
     */
    public $label;
    /**
     * A flag which indicates that user confirmation is needed
     * before applying the change.
     *
     * @var bool|null
     */
    public $needsConfirmation;
    /**
     * A human-readable string which is rendered less prominent in
     * the user interface.
     *
     * @var string|null
     */
    public $description;
    public function __construct(string $label = null, bool $needsConfirmation = null, string $description = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->label = $label;
        $this->needsConfirmation = $needsConfirmation;
        $this->description = $description;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ClientInfo
{
    /**
     * The name of the client as defined by the client.
     *
     * @var string
     */
    public $name;
    /**
     * The client's version as defined by the client.
     *
     * @var string|null
     */
    public $version;
    public function __construct(string $name = null, string $version = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->name = $name;
        $this->version = $version;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CodeLensWorkspaceClientCapabilities
{
    /**
     * Whether the client implementation supports a refresh request sent from the
     * server to the client.
     *
     * Note that this event is global and will force the client to refresh all
     * code lenses currently shown. It should be used with absolute care and is
     * useful for situation where a server for example detect a project wide
     * change that requires such a calculation.
     *
     * @var bool|null
     */
    public $refreshSupport;
    public function __construct(bool $refreshSupport = null)
    {
        $this->refreshSupport = $refreshSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

abstract class PrepareSupportDefaultBehavior
{
    /**
     * The client's default behavior is to select the identifier
     * according the to language's syntax rule.
     */
    const IDENTIFIER = 1;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Symbol tags are extra annotations that tweak the rendering of a symbol.
 *
 * @since 3.16
 */
abstract class SymbolTag
{
    /**
     * Render a symbol as obsolete, usually using a strike-out.
     */
    const DEPRECATED = 1;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentOnTypeFormattingClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CodeActionClientCapabilitiesCodeActionLiteralSupport
{
    /**
     * The code action kind is supported with the following value
     * set.
     *
     * @var CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind
     */
    public $codeActionKind;
    public function __construct(CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind $codeActionKind)
    {
        $this->codeActionKind = $codeActionKind;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionClientCapabilitiesCompletionItemResolveSupport
{
    /**
     * The properties that a client can resolve lazily.
     *
     * @var string[]
     */
    public $properties;
    /**
     * @param string[] $properties
     */
    public function __construct(array $properties = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->properties = $properties;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * How whitespace and indentation is handled during completion
 * item insertion.
 *
 * @since 3.16.0
 */
abstract class InsertTextMode
{
    /**
     * The insertion or replace strings is taken as it is. If the
     * value is multi line the lines below the cursor will be
     * inserted using the indentation defined in the string value.
     * The client will not apply any kind of adjustments to the
     * string.
     */
    const AS_IS = 1;
    /**
     * The editor adjusts leading whitespace of new lines so that
     * they match the indentation up to the cursor of the line for
     * which the item is accepted.
     *
     * Consider a line like this: <2tabs><cursor><3tabs>foo. Accepting a
     * multi line completion item is indented using 2 tabs and all
     * following lines inserted will be indented using 2 tabs as well.
     */
    const ADJUST_INDENTATION = 2;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class WorkspaceFolder
{
    /**
     * The associated URI for this workspace folder.
     *
     * @var string
     */
    public $uri;
    /**
     * The name of the workspace folder. Used to refer to this
     * workspace folder in the user interface.
     *
     * @var string
     */
    public $name;
    public function __construct(string $uri = null, string $name = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->uri = $uri;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->name = $name;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CodeActionClientCapabilitiesResolveSupport
{
    /**
     * The properties that a client can resolve lazily.
     *
     * @var string[]
     */
    public $properties;
    /**
     * @param string[] $properties
     */
    public function __construct(array $properties)
    {
        $this->properties = $properties;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class SignatureHelpClientCapabilitiesSignatureInformation
{
    /**
     * Client supports the follow content formats for the documentation
     * property. The order describes the preferred format of the client.
     *
     * @var string[]|null
     * @see MarkupKind
     */
    public $documentationFormat;
    /**
     * Client capabilities specific to parameter information.
     *
     * @var SignatureHelpClientCapabilitiesSignatureInformationParameterInformation|null
     */
    public $parameterInformation;
    /**
     * The client supports the `activeParameter` property on
     * `SignatureInformation` literal.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $activeParameterSupport;
    /**
     * Undocumented function
     *
     * @param string[]|null $documentationFormat
     * @param SignatureHelpClientCapabilitiesSignatureInformationParameterInformation|null $parameterInformation
     * @param boolean|null $activeParameterSupport
     */
    public function __construct(array $documentationFormat = null, SignatureHelpClientCapabilitiesSignatureInformationParameterInformation $parameterInformation = null, bool $activeParameterSupport = null)
    {
        $this->documentationFormat = $documentationFormat;
        $this->parameterInformation = $parameterInformation;
        $this->activeParameterSupport = $activeParameterSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Contains additional diagnostic information about the context in which
 * a code action is run.
 */
class CodeActionContext
{
    /**
     * An array of diagnostics known on the client side overlapping the range
     * provided to the `textDocument/codeAction` request. They are provided so
     * that the server knows which errors are currently presented to the user
     * for the given range. There is no guarantee that these accurately reflect
     * the error state of the resource. The primary parameter
     * to compute code actions is the provided range.
     *
     * @var Diagnostic[]
     */
    public $diagnostics;
    /**
     * Requested kind of actions to return.
     *
     * Actions not of this kind are filtered out by the client before being
     * shown. So servers can omit computing them.
     *
     * @var string[]|null
     * @see CodeActionKind
     */
    public $only;
    /**
     * The reason why code actions were requested.
     *
     * @since 3.17.0
     *
     * @var int|null
     * @see CodeActionTriggerKind
     */
    public $triggerKind;
    /**
     * @param Diagnostic[] $diagnostics
     */
    public function __construct(array $diagnostics = [])
    {
        $this->diagnostics = $diagnostics;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentLinkClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * Whether the client supports the `tooltip` property on `DocumentLink`.
     *
     * @since 3.15.0
     *
     * @var bool|null
     */
    public $tooltipSupport;
    public function __construct(bool $dynamicRegistration = null, bool $tooltipSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->tooltipSupport = $tooltipSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents a related message and source code location for a diagnostic.
 * This should be used to point to code locations that cause or are related to
 * a diagnostics, e.g when duplicating a symbol in a scope.
 */
class DiagnosticRelatedInformation
{
    /**
     * The location of this related diagnostic information.
     *
     * @var Location
     */
    public $location;
    /**
     * The message of this related diagnostic information.
     *
     * @var string
     */
    public $message;
    public function __construct(Location $location, string $message)
    {
        $this->location = $location;
        $this->message = $message;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Defines how the host (editor) should sync document changes to the language server.
 */
abstract class ResourceOperationKind
{
    /**
     * Supports creating new files and folders.
     */
    const CREATE = 'create';
    /**
     * Supports renaming existing files and folders.
     */
    const RENAME = 'rename';
    /**
     * Supports deleting existing files and folders.
     */
    const DELETE = 'delete';
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents a reference to a command. Provides a title which will be used to represent a command in the UI and,
 * optionally, an array of arguments which will be passed to the command handler function when invoked.
 */
class Command
{
    /**
     * Title of the command, like `save`.
     *
     * @var string|null
     */
    public $title;
    /**
     * The identifier of the actual command handler.
     *
     * @var string|null
     */
    public $command;
    /**
     * Arguments that the command handler should be
     * invoked with.
     *
     * @var mixed[]|null
     */
    public $arguments;
    /**
     * @param mixed[]|null $arguments
     */
    public function __construct(string $title = null, string $command = null, array $arguments = null)
    {
        $this->title = $title;
        $this->command = $command;
        $this->arguments = $arguments;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Format document on type options
 */
class DocumentOnTypeFormattingOptions
{
    /**
     * A character on which formatting should be triggered, like `}`.
     *
     * @var string
     */
    public $firstTriggerCharacter;
    /**
     * More trigger characters.
     *
     * @var string[]|null
     */
    public $moreTriggerCharacter;
    /**
     * @param string[]|null $moreTriggerCharacter
     */
    public function __construct(string $firstTriggerCharacter = null, array $moreTriggerCharacter = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->firstTriggerCharacter = $firstTriggerCharacter;
        $this->moreTriggerCharacter = $moreTriggerCharacter;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ExecuteCommandOptions
{
    /**
     * The commands to be executed on the server
     *
     * @var string[]
     */
    public $commands;
    /**
     * @param string[] $commands
     */
    public function __construct(array $commands)
    {
        $this->commands = $commands;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ClientCapabilitiesWindow
{
    /**
     * Whether client supports handling progress notifications. If set
     * servers are allowed to report in `workDoneProgress` property in the
     * request specific server capabilities.
     *
     * @since 3.15.0
     *
     * @var boolean|null
     */
    public $workDoneProgress;
    /**
     * Capabilities specific to the showMessage request
     *
     * @since 3.16.0
     *
     * @var ShowMessageRequestClientCapabilities|null
     */
    public $showMessage;
    /**
     * Client capabilities for the show document request.
     *
     * @since 3.16.0
     *
     * @var ShowDocumentClientCapabilities|null
     */
    public $showDocument;
    public function __construct(bool $workDoneProgress = null, ShowMessageRequestClientCapabilities $showMessage = null, ShowDocumentClientCapabilities $showDocument = null)
    {
        $this->workDoneProgress = $workDoneProgress;
        $this->showMessage = $showMessage;
        $this->showDocument = $showDocument;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CodeActionClientCapabilities
{
    /**
     * Whether code action supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports code action literals as a valid
     * response of the `textDocument/codeAction` request.
     *
     * @since 3.8.0
     *
     * @var CodeActionClientCapabilitiesCodeActionLiteralSupport|null
     */
    public $codeActionLiteralSupport;
    /**
     * Whether code action supports the `isPreferred` property.
     *
     * @since 3.15.0
     *
     * @var bool|null
     */
    public $isPreferredSupport;
    /**
     * Whether code action supports the `disabled` property.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $disabledSupport;
    /**
     * Whether code action supports the `data` property which is
     * preserved between a `textDocument/codeAction` and a
     * `codeAction/resolve` request.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $dataSupport;
    /**
     * Whether the client supports resolving additional code action
     * properties via a separate `codeAction/resolve` request.
     *
     * @since 3.16.0
     *
     * @var CodeActionClientCapabilitiesResolveSupport|null
     */
    public $resolveSupport;
    /**
     * Whether the client honors the change annotations in
     * text edits and resource operations returned via the
     * `CodeAction#edit` property by for example presenting
     * the workspace edit in the user interface and asking
     * for confirmation.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $honorsChangeAnnotations;
    public function __construct(bool $dynamicRegistration = null, CodeActionClientCapabilitiesCodeActionLiteralSupport $codeActionLiteralSupport = null, bool $isPreferredSupport = null, bool $disabledSupport = null, bool $dataSupport = null, CodeActionClientCapabilitiesResolveSupport $resolveSupport = null, bool $honorsChangeAnnotations = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->codeActionLiteralSupport = $codeActionLiteralSupport;
        $this->isPreferredSupport = $isPreferredSupport;
        $this->disabledSupport = $disabledSupport;
        $this->dataSupport = $dataSupport;
        $this->resolveSupport = $resolveSupport;
        $this->honorsChangeAnnotations = $honorsChangeAnnotations;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionClientCapabilitiesCompletionItemTagSupport
{
    /**
     * The tags supported by the client.
     *
     * @var int[]
     */
    public $valueSet;
    /**
     * @param int[]|null $valueSet CompletionItemTag
     */
    public function __construct(array $valueSet = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class WorkspaceEditClientCapabilities
{
    /**
     * The client supports versioned document changes in `WorkspaceEdit`s
     *
     * @var bool|null
     */
    public $documentChanges;
    /**
     * The resource operations the client supports. Clients should at least
     * support 'create', 'rename' and 'delete' files and folders.
     *
     * @since 3.13.0
     *
     * @var string[]|null
     * @see ResourceOperationKind
     */
    public $resourceOperations;
    /**
     * The failure handling strategy of a client if applying the workspace edit
     * fails.
     *
     * @since 3.13.0
     *
     * @var string|null
     * @see FailureHandlingKind
     */
    public $failureHandling;
    /**
     * Whether the client normalizes line endings to the client specific
     * setting.
     * If set to `true` the client will normalize line ending characters
     * in a workspace edit to the client specific new line character(s).
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $normalizesLineEndings;
    /**
     * Whether the client in general supports change annotations on text edits,
     * create file, rename file and delete file changes.
     *
     * @since 3.16.0
     *
     * @var WorkspaceEditClientCapabilitiesChangeAnnotationSupport|null
     */
    public $changeAnnotationSupport;
    /**
     * Undocumented function
     *
     * @param boolean|null $documentChanges
     * @param string[]|null $resourceOperations
     * @param string|null $failureHandling
     * @param boolean|null $normalizesLineEndings
     * @param WorkspaceEditClientCapabilitiesChangeAnnotationSupport|null $changeAnnotationSupport
     */
    public function __construct(bool $documentChanges = null, array $resourceOperations = null, string $failureHandling = null, bool $normalizesLineEndings = null, WorkspaceEditClientCapabilitiesChangeAnnotationSupport $changeAnnotationSupport = null)
    {
        $this->documentChanges = $documentChanges;
        $this->resourceOperations = $resourceOperations;
        $this->failureHandling = $failureHandling;
        $this->normalizesLineEndings = $normalizesLineEndings;
        $this->changeAnnotationSupport = $changeAnnotationSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ImplementationClientCapabilities
{
    /**
     * Whether implementation supports dynamic registration. If this is set to
     * `true` the client supports the new `ImplementationRegistrationOptions`
     * return value for the corresponding server capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports additional metadata in the form of definition links.
     *
     * @since 3.14.0
     *
     * @var boolean|null
     */
    public $linkSupport;
    public function __construct(bool $dynamicRegistration = null, bool $linkSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->linkSupport = $linkSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentSymbolClientCapabilities
{
    /**
     * Whether document symbol supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * Specific capabilities for the `SymbolKind` in the
     * `textDocument/documentSymbol` request.
     *
     * @var DocumentSymbolClientCapabilitiesSymbolKind|null
     */
    public $symbolKind;
    /**
     * The client supports hierarchical document symbols.
     *
     * @var bool|null
     */
    public $hierarchicalDocumentSymbolSupport;
    /**
     * The client supports tags on `SymbolInformation`. Tags are supported on
     * `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true.
     * Clients supporting tags have to handle unknown tags gracefully.
     *
     * @since 3.16.0
     *
     * @var DocumentSymbolClientCapabilitiesTagSupport|null
     */
    public $tagSupport;
    /**
     * The client supports an additional label presented in the UI when
     * registering a document symbol provider.
     *
     * @since 3.16.0
     *
     * @var bool|null
     */
    public $labelSupport;
    public function __construct(bool $dynamicRegistration = null, DocumentSymbolClientCapabilitiesSymbolKind $symbolKind = null, bool $hierarchicalDocumentSymbolSupport = null, DocumentSymbolClientCapabilitiesTagSupport $tagSupport = null, bool $labelSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->symbolKind = $symbolKind;
        $this->hierarchicalDocumentSymbolSupport = $hierarchicalDocumentSymbolSupport;
        $this->tagSupport = $tagSupport;
        $this->labelSupport = $labelSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A document highlight kind.
 */
abstract class DocumentHighlightKind
{
    /**
     * A textual occurrence.
     */
    const TEXT = 1;
    /**
     * Read-access of a symbol, like reading a variable.
     */
    const READ = 2;
    /**
     * Write-access of a symbol, like writing to a variable.
     */
    const WRITE = 3;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents a parameter of a callable-signature. A parameter can
 * have a label and a doc-comment.
 */
class ParameterInformation
{
    /**
     * The label of this parameter information.
     *
     * Either a string or an inclusive start and exclusive end offsets within its containing
     * signature label. (see SignatureInformation.label). The offsets are based on a UTF-16
     * string representation as `Position` and `Range` does.
     *
     * *Note*: a label of type string should be a substring of its containing signature label.
     * Its intended use case is to highlight the parameter label part in the `SignatureInformation.label`.
     *
     * @var string|int[]
     */
    public $label;
    /**
     * The human-readable doc-comment of this signature. Will be shown
     * in the UI but can be omitted.
     *
     * @var MarkupContent|string|null
     */
    public $documentation;
    /**
     * Create ParameterInformation
     *
     * @param string|int[] $label   The label of this parameter information.
     * @param MarkupContent|string|null $documentation The human-readable doc-comment of this signature.
     *                                  Will be shown in the UI but can be omitted.
     */
    public function __construct($label, $documentation = null)
    {
        $this->label = $label;
        $this->documentation = $documentation;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class PublishDiagnosticsClientCapabilitiesTagSupport
{
    /**
     * The tags supported by the client.
     *
     * @var int[]
     * @see DiagnosticTag
     */
    public $valueSet;
    /**
     * @param int[]|null $valueSet
     */
    public function __construct(array $valueSet = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Completion options.
 */
class CompletionOptions
{
    /**
     * The server provides support to resolve additional information for a completion
     * item.
     *
     * @var bool|null
     */
    public $resolveProvider;
    /**
     * The characters that trigger completion automatically.
     *
     * @var string[]|null
     */
    public $triggerCharacters;
    /**
     * @param string[]|null $triggerCharacters
     */
    public function __construct(bool $resolveProvider = null, array $triggerCharacters = null)
    {
        $this->resolveProvider = $resolveProvider;
        $this->triggerCharacters = $triggerCharacters;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A `MarkupContent` literal represents a string value which content is interpreted base on its
 * kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
 *
 * If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
 * See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
 *
 * Here is an example how such a string can be constructed using JavaScript / TypeScript:
 * ```ts
 * let markdown: MarkdownContent = {
 *  kind: MarkupKind.Markdown,
 *  value: [
 *      '# Header',
 *      'Some text',
 *      '```typescript',
 *      'someCode();',
 *      '```'
 *  ].join('\n')
 * };
 * ```
 *
 * *Please Note* that clients might sanitize the return markdown. A client could decide to
 * remove HTML from the markdown to avoid script execution.
 */
class MarkupContent
{
    /**
     * @var string the type of the Markup (from MarkupKind)
     */
    public $kind;
    /**
     * @var string the content itself
     */
    public $value;
    /**
     * @param string $kind the type of the Markup
     * @param string $value the content itself
     */
    public function __construct(string $kind = null, string $value = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->kind = $kind;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->value = $value;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

use JsonSerializable;
/**
 * A code action represents a change that can be performed in code, e.g. to fix
 * a problem or to refactor code.
 *
 * A CodeAction must set either `edit` and/or a `command`. If both are supplied,
 * the `edit` is applied first, then the `command` is executed.
 */
class CodeAction implements JsonSerializable
{
    /**
     * A short, human-readable, title for this code action.
     *
     * @var string
     */
    public $title;
    /**
     * The kind of the code action.
     *
     * Used to filter code actions.
     *
     * @var string|null
     * @see CodeActionKind
     */
    public $kind;
    /**
     * The diagnostics that this code action resolves.
     * @var Diagnostic[]|null
     */
    public $diagnostics;
    /**
     * Marks this as a preferred action. Preferred actions are used by the
     * `auto fix` command and can be targeted by keybindings.
     *
     * A quick fix should be marked preferred if it properly addresses the
     * underlying error. A refactoring should be marked preferred if it is the
     * most reasonable choice of actions to take.
     *
     * @since 3.15.0
     *
     * @var bool|null
     */
    public $isPreferred;
    /**
     * Marks that the code action cannot currently be applied.
     *
     * Clients should follow the following guidelines regarding disabled code
     * actions:
     *
     * - Disabled code actions are not shown in automatic lightbulbs code
     *   action menus.
     *
     * - Disabled actions are shown as faded out in the code action menu when
     *   the user request a more specific type of code action, such as
     *   refactorings.
     *
     * - If the user has a keybinding that auto applies a code action and only
     *   a disabled code actions are returned, the client should show the user
     *   an error message with `reason` in the editor.
     *
     * @since 3.16.0
     *
     * @var CodeActionDisabled|null
     */
    public $disabled;
    /**
     * The workspace edit this code action performs.
     *
     * @var WorkspaceEdit|null
     */
    public $edit;
    /**
     * A command this code action executes. If a code action
     * provides an edit and a command, first the edit is
     * executed and then the command.
     *
     * @var Command|null
     */
    public $command;
    /**
     * A data entry field that is preserved on a code action between
     * a `textDocument/codeAction` and a `codeAction/resolve` request.
     *
     * @since 3.16.0
     *
     * @var mixed|null
     */
    public $data;
    /**
     * Undocumented function
     *
     * @param string|null $title
     * @param string|null $kind
     * @param Diagnostic[]|null $diagnostics
     * @param boolean|null $isPreferred
     * @param CodeActionDisabled|null $disabled
     * @param WorkspaceEdit|null $edit
     * @param Command|null $command
     * @param mixed $data
     */
    public function __construct(string $title = null, string $kind = null, array $diagnostics = null, bool $isPreferred = null, CodeActionDisabled $disabled = null, WorkspaceEdit $edit = null, Command $command = null, $data = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->title = $title;
        $this->kind = $kind;
        $this->diagnostics = $diagnostics;
        $this->isPreferred = $isPreferred;
        $this->disabled = $disabled;
        $this->edit = $edit;
        $this->command = $command;
        $this->data = $data;
    }
    /**
     * This is needed because VSCode Does not like nulls
     * meaning if a null is sent then this will not compute
     *
     * @return mixed
     */
    #[\ReturnTypeWillChange]
    public function jsonSerialize()
    {
        return \array_filter(\get_object_vars($this));
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CodeActionClientCapabilitiesCodeActionLiteralSupportcodeActionKind
{
    /**
     * The code action kind values the client supports. When this
     * property exists the client also guarantees that it will
     * handle values outside its set gracefully and falls back
     * to a default value when unknown.
     *
     * @var string[]
     * @see CodeActionKind
     */
    public $valueSet;
    /**
     * Undocumented function
     *
     * @param string[] $valueSet
     */
    public function __construct(array $valueSet)
    {
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DeclarationClientCapabilities
{
    /**
     * Whether declaration supports dynamic registration. If this is set to
     * `true` the client supports the new `DeclarationRegistrationOptions`
     * return value for the corresponding server capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports additional metadata in the form of declaration links.
     *
     * @var bool|null
     */
    public $linkSupport;
    public function __construct(bool $dynamicRegistration = null, bool $linkSupport = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->linkSupport = $linkSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class SemanticTokensWorkspaceClientCapabilities
{
    /**
     * Whether the client implementation supports a refresh request sent from
     * the server to the client.
     *
     * Note that this event is global and will force the client to refresh all
     * semantic tokens currently shown. It should be used with absolute care
     * and is useful for situation where a server for example detect a project
     * wide change that requires such a calculation.
     *
     * @var bool|null
     */
    public $refreshSupport;
    public function __construct(bool $refreshSupport = null)
    {
        $this->refreshSupport = $refreshSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DidChangeConfigurationClientCapabilities
{
    /**
     * Did change configuration notification supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DocumentFormattingClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Client capabilities specific to parameter information.
 */
class SignatureHelpClientCapabilitiesSignatureInformationParameterInformation
{
    /**
     * The client supports processing label offsets instead of a
     * simple label string.
     *
     * @since 3.14.0
     *
     * @var bool|null
     */
    public $labelOffsetSupport;
    public function __construct(bool $labelOffsetSupport = null)
    {
        $this->labelOffsetSupport = $labelOffsetSupport;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CodeLensClientCapabilities
{
    /**
     * Whether text document synchronization supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class DidChangeWatchedFilesClientCapabilities
{
    /**
     * Did change watched files notification supports dynamic registration.
     * Please note that the current protocol doesn't support static
     * configuration for file changes from the server side.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class MonikerClientCapabilities
{
    /**
     * Whether implementation supports dynamic registration. If this is set to
     * `true` the client supports the new `(TextDocumentRegistrationOptions &
     * StaticRegistrationOptions)` return value for the corresponding server
     * capability as well.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    public function __construct(bool $dynamicRegistration = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * An event describing a change to a text document. If range and rangeLength are
 * omitted the new text is considered to be the full content of the document.
 */
class ContentChangeEvent
{
    /**
     * The range of the document that changed.
     *
     * @var Range|null
     */
    public $range;
    /**
     * The length of the range that got replaced.
     *
     * @var int|null
     */
    public $rangeLength;
    /**
     * The new text of the document.
     *
     * @var string
     */
    public $text;
    public function __construct(Range $range = null, int $rangeLength = null, string $text = null)
    {
        $this->range = $range;
        $this->rangeLength = $rangeLength;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->text = $text;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents the signature of something callable. A signature
 * can have a label, like a function-name, a doc-comment, and
 * a set of parameters.
 */
class SignatureInformation
{
    /**
     * The label of this signature. Will be shown in
     * the UI.
     *
     * @var string
     */
    public $label;
    /**
     * The human-readable doc-comment of this signature. Will be shown
     * in the UI but can be omitted.
     *
     * @var MarkupContent|string|null
     */
    public $documentation;
    /**
     * The parameters of this signature.
     *
     * @var ParameterInformation[]|null
     */
    public $parameters;
    /**
     * The index of the active parameter.
     *
     * If provided, this is used in place of `SignatureHelp.activeParameter`.
     *
     * @since 3.16.0
     *
     * @var int|null
     */
    public $activeParameter;
    /**
     * Create a SignatureInformation
     *
     * @param string $label                           The label of this signature. Will be shown in the UI.
     * @param ParameterInformation[]|null $parameters The parameters of this signature
     * @param MarkupContent|string|null $documentation  The human-readable doc-comment of this signature.
     *                                                  Will be shown in the UI but can be omitted.
     * @param int|null $activeParameter The index of the active parameter.
     */
    public function __construct(string $label, array $parameters = null, $documentation = null, int $activeParameter = null)
    {
        $this->label = $label;
        $this->parameters = $parameters;
        $this->documentation = $documentation;
        $this->activeParameter = $activeParameter;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A textual edit applicable to a text document.
 */
class TextEdit
{
    /**
     * The range of the text document to be manipulated. To insert
     * text into a document create a range where start === end.
     *
     * @var Range
     */
    public $range;
    /**
     * The string to be inserted. For delete operations use an
     * empty string.
     *
     * @var string
     */
    public $newText;
    public function __construct(Range $range = null, string $newText = null)
    {
        $this->range = $range;
        $this->newText = $newText;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * An event describing a file change.
 */
class FileEvent
{
    /**
     * The file's URI.
     *
     * @var string
     */
    public $uri;
    /**
     * The change type.
     *
     * @var int
     */
    public $type;
    /**
     * @param string $uri
     * @param int $type
     */
    public function __construct(string $uri, int $type)
    {
        $this->uri = $uri;
        $this->type = $type;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class FoldingRangeClientCapabilities
{
    /**
     * Whether hover supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The maximum number of folding ranges that the client prefers to receive
     * per document. The value serves as a hint, servers are free to follow the
     * limit.
     *
     * @var int|null
     */
    public $rangeLimit;
    /**
     * If set, the client signals that it only supports folding complete lines.
     * If set, client will ignore specified `startCharacter` and `endCharacter`
     * properties in a FoldingRange.
     *
     * @var bool|null
     */
    public $lineFoldingOnly;
    public function __construct(bool $dynamicRegistration = null, int $rangeLimit = null, bool $lineFoldingOnly = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->rangeLimit = $rangeLimit;
        $this->lineFoldingOnly = $lineFoldingOnly;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A notification to log the trace of the server’s execution.
 * The amount and content of these notifications depends on the
 * current trace configuration. If trace is 'off', the server
 * should not send any logTrace notification. If trace is
 * 'messages', the server should not add the 'verbose' field in
 * the LogTraceParams.
 *
 * $/logTrace should be used for systematic trace reporting.
 * For single debugging messages, the server should send
 * window/logMessage notifications.
 */
class LogTrace
{
    /**
     * The message to be logged.
     *
     * @var string
     */
    public $message;
    /**
     * Additional information that can be computed if the `trace` configuration
     * is set to `'verbose'`
     *
     * @var string|null
     */
    public $verbose;
    public function __construct(string $message, string $verbose = null)
    {
        $this->message = $message;
        $this->verbose = $verbose;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionTriggerKind
{
    /**
     * Completion was triggered by invoking it manuall or using API.
     */
    const INVOKED = 1;
    /**
     * Completion was triggered by a trigger character.
     */
    const TRIGGER_CHARACTER = 2;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Code Lens options.
 */
class CodeLensOptions
{
    /**
     * Code lens has a resolve provider as well.
     *
     * @var bool|null
     */
    public $resolveProvider;
    public function __construct(bool $resolveProvider = null)
    {
        $this->resolveProvider = $resolveProvider;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class CompletionClientCapabilities
{
    /**
     * Whether completion supports dynamic registration.
     *
     * @var bool|null
     */
    public $dynamicRegistration;
    /**
     * The client supports the following `CompletionItem` specific
     * capabilities.
     *
     * @var CompletionClientCapabilitiesCompletionItem|null
     */
    public $completionItem;
    /**
     * The client supports to send additional context information for a
     * `textDocument/completion` request.
     *
     * @var bool|null
     */
    public $contextSupport;
    /**
     * The client's default when the completion item doesn't provide a
     * `insertTextMode` property.
     *
     * @since 3.17.0 - proposed state
     *
     * @var int|null
     * @see InsertTextFormat
     */
    public $insertTextMode;
    /**
     * The client supports the following `CompletionList` specific
     * capabilities.
     *
     * @since 3.17.0 - proposed state
     *
     * @var CompletionClientCapabilitiesCompletionList|null
     */
    public $completionList;
    public function __construct(bool $dynamicRegistration = null, CompletionClientCapabilitiesCompletionItem $completionItem = null, bool $contextSupport = null, int $insertTextMode = null, CompletionClientCapabilitiesCompletionList $completionList = null)
    {
        $this->dynamicRegistration = $dynamicRegistration;
        $this->completionItem = $completionItem;
        $this->contextSupport = $contextSupport;
        $this->insertTextMode = $insertTextMode;
        $this->completionList = $completionList;
    }
}
<?php

declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Metadata about the symbol that can be used to identify or locate its
 * definition.
 */
class ReferenceInformation
{
    /**
     * The location in the workspace where the `symbol` is referenced.
     *
     * @var Location
     */
    public $reference;
    /**
     * Metadata about the symbol that can be used to identify or locate its
     * definition.
     *
     * @var SymbolDescriptor
     */
    public $symbol;
    /**
     * @param Location         $reference The location in the workspace where the `symbol` is referenced.
     * @param SymbolDescriptor $symbol    Metadata about the symbol that
     *                                    can be used to identify or locate its definition.
     */
    public function __construct(Location $reference = null, SymbolDescriptor $symbol = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->reference = $reference;
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->symbol = $symbol;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class WorkspaceSymbolClientCapabilitiesSymbolKind
{
    /**
     * The symbol kind values the client supports. When this
     * property exists the client also guarantees that it will
     * handle values outside its set gracefully and falls back
     * to a default value when unknown.
     *
     * If this property is not present the client only supports
     * the symbol kinds from `File` to `Array` as defined in
     * the initial version of the protocol.
     *
     * @var int[]|null
     * @see SymbolKind
     */
    public $valueSet;
    /**
     * @param int[]|null $valueSet
     */
    public function __construct(array $valueSet = null)
    {
        $this->valueSet = $valueSet;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

abstract class CompletionItemTag
{
    /**
     * Render a completion as obsolete, usually using a strike-out.
     */
    const DEPRECATED = 1;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

class ServerCapabilities
{
    /**
     * Defines how text documents are synced.
     *
     * @var TextDocumentSyncOptions|int|null
     */
    public $textDocumentSync;
    /**
     * The server provides hover support.
     *
     * @var bool|null
     */
    public $hoverProvider;
    /**
     * The server provides completion support.
     *
     * @var CompletionOptions|null
     */
    public $completionProvider;
    /**
     * The server provides signature help support.
     *
     * @var SignatureHelpOptions|null
     */
    public $signatureHelpProvider;
    /**
     * The server provides goto definition support.
     *
     * @var bool|null
     */
    public $definitionProvider;
    /**
     * The server provides goto type definition support.
     *
     * @since 3.6.0
     *
     * @var bool|null
     */
    public $typeDefinitionProvider;
    /**
     * The server provides goto implementation support.
     *
     * @since 3.6.0
     *
     * @var bool|null
     */
    public $implementationProvider;
    /**
     * The server provides find references support.
     *
     * @var bool|null
     */
    public $referencesProvider;
    /**
     * The server provides document highlight support.
     *
     * @var bool|null
     */
    public $documentHighlightProvider;
    /**
     * The server provides document symbol support.
     *
     * @var bool|null
     */
    public $documentSymbolProvider;
    /**
     * The server provides workspace symbol support.
     *
     * @var bool|null
     */
    public $workspaceSymbolProvider;
    /**
     * The server provides code actions.
     *
     * @var bool|null
     */
    public $codeActionProvider;
    /**
     * The server provides code lens.
     *
     * @var CodeLensOptions|null
     */
    public $codeLensProvider;
    /**
     * The server provides document formatting.
     *
     * @var bool|null
     */
    public $documentFormattingProvider;
    /**
     * The server provides document range formatting.
     *
     * @var bool|null
     */
    public $documentRangeFormattingProvider;
    /**
     * The server provides document formatting on typing.
     *
     * @var DocumentOnTypeFormattingOptions|null
     */
    public $documentOnTypeFormattingProvider;
    /**
     * The server provides rename support.
     *
     * @var bool|null
     */
    public $renameProvider;
    /**
     * The server provides execute command support.
     *
     * @var ExecuteCommandOptions|null
     */
    public $executeCommandProvider;
    /**
     * The server provides workspace references exporting support.
     *
     * @var bool|null
     */
    public $xworkspaceReferencesProvider;
    /**
     * The server provides extended text document definition support.
     *
     * @var bool|null
     */
    public $xdefinitionProvider;
    /**
     * The server provides workspace dependencies support.
     *
     * @var bool|null
     */
    public $dependenciesProvider;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Enum
 */
abstract class MessageType
{
    /**
     * An error message.
     */
    const ERROR = 1;
    /**
     * A warning message.
     */
    const WARNING = 2;
    /**
     * An information message.
     */
    const INFO = 3;
    /**
     * A log message.
     */
    const LOG = 4;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A code lens represents a command that should be shown along with
 * source text, like the number of references, a way to run tests, etc.
 *
 * A code lens is _unresolved_ when no command is associated to it. For performance
 * reasons the creation of a code lens and resolving should be done in two stages.
 */
class CodeLens
{
    /**
     * The range in which this code lens is valid. Should only span a single line.
     *
     * @var Range
     */
    public $range;
    /**
     * The command this code lens represents.
     *
     * @var Command|null
     */
    public $command;
    /**
     * A data entry field that is preserved on a code lens item between
     * a code lens and a code lens resolve request.
     *
     * @var mixed|null
     */
    public $data;
    /**
     * @param mixed $data
     */
    public function __construct(Range $range = null, Command $command = null, $data = null)
    {
        /** @psalm-suppress PossiblyNullPropertyAssignmentValue */
        $this->range = $range;
        $this->command = $command;
        $this->data = $data;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * Represents a collection of completion items to be presented in
 * the editor.
 */
class CompletionList
{
    /**
     * This list is not complete. Further typing should result in recomputing
     * this list.
     *
     * Recomputed lists have all their items replaced (not appended) in the
     * incomplete completion sessions.
     *
     * @var bool
     */
    public $isIncomplete;
    /**
     * The completion items.
     *
     * @var CompletionItem[]
     */
    public $items;
    /**
     * @param CompletionItem[] $items        The completion items.
     * @param bool             $isIncomplete This list it not complete.
     *                                       Further typing should result in recomputing this list.
     */
    public function __construct(array $items = [], bool $isIncomplete = \false)
    {
        $this->items = $items;
        $this->isIncomplete = $isIncomplete;
    }
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * The file event type. Enum
 */
abstract class FileChangeType
{
    /**
     * The file got created.
     */
    const CREATED = 1;
    /**
     * The file got changed.
     */
    const CHANGED = 2;
    /**
     * The file got deleted.
     */
    const DELETED = 3;
}
<?php

namespace _HumbugBox1cb33d1f20f1\LanguageServerProtocol;

/**
 * A set of predefined code action kinds.
 */
abstract class CodeActionTriggerKind
{
    /**
     * Code actions were explicitly requested by the user or by an extension.
     */
    const INVOKED = 1;
    /**
     * Code actions were requested automatically.
     *
     * This typically happens when current selection in a file changes, but can
     * also be triggered when file content changes.
     */
    const AUTOMATIC = 2;
}
{
  "private": true,
  "repository": {
    "type": "git",
    "url": "https://github.com/felixfbecker/php-language-server-protocol"
  },
  "release": {
    "verifyConditions": "@semantic-release/github",
    "prepare": [],
    "publish": "@semantic-release/github"
  },
  "devDependencies": {
    "semantic-release": "^15.9.16"
  }
}
ISC License

Copyright (c) 2016, Felix Frederick Becker

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter;

use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder\CpuCoreFinder;
use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder\FinderRegistry;
final class CpuCoreCounter
{
    /**
     * @var list<CpuCoreFinder>
     */
    private $finders;
    /**
     * @var positive-int|null
     */
    private $count;
    /**
     * @param list<CpuCoreFinder>|null $finders
     */
    public function __construct(?array $finders = null)
    {
        $this->finders = $finders ?? FinderRegistry::getDefaultLogicalFinders();
    }
    /**
     * @throws NumberOfCpuCoreNotFound
     *
     * @return positive-int
     */
    public function getCount() : int
    {
        // Memoize result
        if (null === $this->count) {
            $this->count = $this->findCount();
        }
        return $this->count;
    }
    /**
     * @throws NumberOfCpuCoreNotFound
     *
     * @return positive-int
     */
    private function findCount() : int
    {
        foreach ($this->finders as $finder) {
            $cores = $finder->find();
            if (null !== $cores) {
                return $cores;
            }
        }
        throw NumberOfCpuCoreNotFound::create();
    }
    /**
     * @throws NumberOfCpuCoreNotFound
     *
     * @return array{CpuCoreFinder, positive-int}
     */
    public function getFinderAndCores() : array
    {
        foreach ($this->finders as $finder) {
            $cores = $finder->find();
            if (null !== $cores) {
                return [$finder, $cores];
            }
        }
        throw NumberOfCpuCoreNotFound::create();
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter;

use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder\CpuCoreFinder;
use function array_map;
use function explode;
use function implode;
use function max;
use function str_repeat;
use const PHP_EOL;
/**
 * Utility to debug.
 *
 * @private
 */
final class Diagnoser
{
    /**
     * Provides an aggregated diagnosis based on each finders diagnosis.
     *
     * @param list<CpuCoreFinder> $finders
     */
    public static function diagnose(array $finders) : string
    {
        $diagnoses = array_map(static function (CpuCoreFinder $finder) : string {
            return self::diagnoseFinder($finder);
        }, $finders);
        return implode(PHP_EOL, $diagnoses);
    }
    /**
     * Executes each finders.
     *
     * @param list<CpuCoreFinder> $finders
     */
    public static function execute(array $finders) : string
    {
        $diagnoses = array_map(static function (CpuCoreFinder $finder) : string {
            $coresCount = $finder->find();
            return implode('', [$finder->toString(), ': ', null === $coresCount ? 'NULL' : $coresCount]);
        }, $finders);
        return implode(PHP_EOL, $diagnoses);
    }
    private static function diagnoseFinder(CpuCoreFinder $finder) : string
    {
        $diagnosis = $finder->diagnose();
        $maxLineLength = max(array_map('strlen', explode(PHP_EOL, $diagnosis)));
        $separator = str_repeat('-', $maxLineLength);
        return implode('', [$finder->toString() . ':' . PHP_EOL, $separator . PHP_EOL, $diagnosis . PHP_EOL, $separator . PHP_EOL]);
    }
    private function __construct()
    {
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Exec;

use function fclose;
use function is_resource;
use function proc_close;
use function proc_open;
use function stream_get_contents;
final class ProcOpen
{
    /**
     * @return array{string, string} STDOUT & STDERR tuple
     */
    public static function execute(string $command) : ?array
    {
        $pipes = [];
        $process = @proc_open($command, [
            ['pipe', 'rb'],
            ['pipe', 'wb'],
            // stdout
            ['pipe', 'wb'],
        ], $pipes);
        if (!is_resource($process)) {
            return null;
        }
        fclose($pipes[0]);
        $stdout = (string) stream_get_contents($pipes[1]);
        $stderr = (string) stream_get_contents($pipes[2]);
        proc_close($process);
        return [$stdout, $stderr];
    }
    private function __construct()
    {
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter;

use RuntimeException;
final class NumberOfCpuCoreNotFound extends RuntimeException
{
    public static function create() : self
    {
        return new self('Could not find the number of CPU cores available.');
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use function file_get_contents;
use function is_file;
use function sprintf;
use function substr_count;
use const PHP_EOL;
/**
 * Find the number of CPU cores looking up at the cpuinfo file which is available
 * on Linux systems and Windows systems with a Linux sub-system.
 *
 * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L903-L909
 * @see https://unix.stackexchange.com/questions/146051/number-of-processors-in-proc-cpuinfo
 */
final class CpuInfoFinder implements CpuCoreFinder
{
    private const CPU_INFO_PATH = '/proc/cpuinfo';
    public function diagnose() : string
    {
        if (!is_file(self::CPU_INFO_PATH)) {
            return sprintf('The file "%s" could not be found.', self::CPU_INFO_PATH);
        }
        $cpuInfo = file_get_contents(self::CPU_INFO_PATH);
        if (\false === $cpuInfo) {
            return sprintf('Could not get the content of the file "%s".', self::CPU_INFO_PATH);
        }
        return sprintf('Found the file "%s" with the content:%s%s', self::CPU_INFO_PATH, PHP_EOL, $cpuInfo);
    }
    /**
     * @return positive-int|null
     */
    public function find() : ?int
    {
        $cpuInfo = self::getCpuInfo();
        return null === $cpuInfo ? null : self::countCpuCores($cpuInfo);
    }
    public function toString() : string
    {
        return 'CpuInfoFinder';
    }
    private static function getCpuInfo() : ?string
    {
        if (!@is_file(self::CPU_INFO_PATH)) {
            return null;
        }
        $cpuInfo = @file_get_contents(self::CPU_INFO_PATH);
        return \false === $cpuInfo ? null : $cpuInfo;
    }
    /**
     * @internal
     *
     * @return positive-int|null
     */
    public static function countCpuCores(string $cpuInfo) : ?int
    {
        $processorCount = substr_count($cpuInfo, 'processor');
        return $processorCount > 0 ? $processorCount : null;
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

final class FinderRegistry
{
    /**
     * @return list<CpuCoreFinder> List of all the known finders with all their variants.
     */
    public static function getAllVariants() : array
    {
        return [new CpuInfoFinder(), new DummyCpuCoreFinder(1), new HwLogicalFinder(), new HwPhysicalFinder(), new _NProcessorFinder(), new NProcessorFinder(), new NProcFinder(\true), new NProcFinder(\false), new NullCpuCoreFinder(), new OnlyOnWindowsFinder(new DummyCpuCoreFinder(1)), new SkipOnWindowsFinder(new DummyCpuCoreFinder(1)), new WmicPhysicalFinder(), new WmicLogicalFinder()];
    }
    /**
     * @return list<CpuCoreFinder>
     */
    public static function getDefaultLogicalFinders() : array
    {
        return [new OnlyOnWindowsFinder(new WmicLogicalFinder()), new NProcFinder(), new HwLogicalFinder(), new _NProcessorFinder(), new NProcessorFinder(), new CpuInfoFinder()];
    }
    /**
     * @return list<CpuCoreFinder>
     */
    public static function getDefaultPhysicalFinders() : array
    {
        return [new OnlyOnWindowsFinder(new WmicPhysicalFinder()), new HwPhysicalFinder()];
    }
    private function __construct()
    {
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

/**
 * Find the number of physical CPU cores for Linux, BSD and OSX.
 *
 * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L903-L909
 * @see https://opensource.apple.com/source/xnu/xnu-792.2.4/libkern/libkern/sysctl.h.auto.html
 */
final class HwPhysicalFinder extends ProcOpenBasedFinder
{
    protected function getCommand() : string
    {
        return 'sysctl -n hw.physicalcpu';
    }
    public function toString() : string
    {
        return 'HwPhysicalFinder';
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use function defined;
use function sprintf;
final class SkipOnWindowsFinder implements CpuCoreFinder
{
    /**
     * @var CpuCoreFinder
     */
    private $decoratedFinder;
    public function __construct(CpuCoreFinder $decoratedFinder)
    {
        $this->decoratedFinder = $decoratedFinder;
    }
    public function diagnose() : string
    {
        return self::skip() ? 'Windows platform detected (PHP_WINDOWS_VERSION_MAJOR is set).' : $this->decoratedFinder->diagnose();
    }
    public function find() : ?int
    {
        return self::skip() ? null : $this->decoratedFinder->find();
    }
    public function toString() : string
    {
        return sprintf('SkipOnWindowsFinder(%s)', $this->decoratedFinder->toString());
    }
    private static function skip() : bool
    {
        // Skip if on Windows. Rely on PHP to detect the platform
        // rather than reading the platform name or others.
        return defined('PHP_WINDOWS_VERSION_MAJOR');
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

/**
 * Find the number of logical CPU cores for FreeSBD, Solaris and the likes.
 *
 * @see https://twitter.com/freebsdfrau/status/1052016199452700678?s=20&t=M2pHkRqmmna-UF68lfL2hw
 */
final class NProcessorFinder extends ProcOpenBasedFinder
{
    protected function getCommand() : string
    {
        return 'getconf NPROCESSORS_ONLN';
    }
    public function toString() : string
    {
        return 'NProcessorFinder';
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Exec\ProcOpen;
use function filter_var;
use function function_exists;
use function is_int;
use function sprintf;
use function trim;
use const FILTER_VALIDATE_INT;
use const PHP_EOL;
abstract class ProcOpenBasedFinder implements CpuCoreFinder
{
    public function diagnose() : string
    {
        if (!function_exists('proc_open')) {
            return 'The function "proc_open" is not available.';
        }
        $command = $this->getCommand();
        $output = ProcOpen::execute($command);
        if (null === $output) {
            return sprintf('Failed to execute the command "%s".', $command);
        }
        [$stdout, $stderr] = $output;
        $failed = '' !== trim($stderr);
        return $failed ? sprintf('Executed the command "%s" which wrote the following output to the STDERR:%s%s', $command, PHP_EOL, $stderr) : sprintf('Executed the command "%s" and got the following (STDOUT) output:%s%s', $command, PHP_EOL, $stdout);
    }
    /**
     * @return positive-int|null
     */
    public function find() : ?int
    {
        if (!function_exists('proc_open')) {
            return null;
        }
        $output = ProcOpen::execute($this->getCommand());
        if (null === $output) {
            return null;
        }
        [$stdout, $stderr] = $output;
        $failed = '' !== trim($stderr);
        return $failed ? null : static::countCpuCores($stdout);
    }
    /**
     * @internal
     *
     * @return positive-int|null
     */
    public static function countCpuCores(string $process) : ?int
    {
        $cpuCount = filter_var($process, FILTER_VALIDATE_INT);
        return is_int($cpuCount) && $cpuCount > 0 ? $cpuCount : null;
    }
    protected abstract function getCommand() : string;
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

interface CpuCoreFinder
{
    /**
     * Provides an explanation which may offer some insight as to what the finder
     * will be able to find.
     *
     * This is practical to have an idea of what each finder will find collect
     * information for the unit tests, since integration tests are quite complicated
     * as dependent on complex infrastructures.
     */
    public function diagnose() : string;
    /**
     * Find the number of CPU cores. If it could not find it, returns null. The
     * means used to find the cores are at the implementation discretion.
     *
     * @return positive-int|null
     */
    public function find() : ?int;
    public function toString() : string;
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

/**
 * This finder returns whatever value you gave to it. This is useful for testing.
 */
final class NullCpuCoreFinder implements CpuCoreFinder
{
    public function diagnose() : string
    {
        return 'Will return "null".';
    }
    public function find() : ?int
    {
        return null;
    }
    public function toString() : string
    {
        return 'NullCpuCoreFinder';
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

/**
 * Find the number of logical CPU cores for Linux and the likes.
 *
 * @see https://twitter.com/freebsdfrau/status/1052016199452700678?s=20&t=M2pHkRqmmna-UF68lfL2hw
 */
final class _NProcessorFinder extends ProcOpenBasedFinder
{
    protected function getCommand() : string
    {
        return 'getconf _NPROCESSORS_ONLN';
    }
    public function toString() : string
    {
        return '_NProcessorFinder';
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use function preg_match;
/**
 * Find the number of logical CPU cores for Windows.
 *
 * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L912-L916
 */
final class WmicLogicalFinder extends ProcOpenBasedFinder
{
    private const CPU_CORE_COUNT_REGEX = '/NumberOfLogicalProcessors[\\s\\n]+(?<count>\\d+)/';
    protected function getCommand() : string
    {
        return 'wmic cpu get NumberOfLogicalProcessors';
    }
    public function toString() : string
    {
        return 'WmicLogicalFinder';
    }
    public static function countCpuCores(string $process) : ?int
    {
        if (0 === preg_match(self::CPU_CORE_COUNT_REGEX, $process, $matches)) {
            return parent::countCpuCores($process);
        }
        $count = $matches['count'];
        return parent::countCpuCores($count);
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use function preg_match;
/**
 * Find the number of physical CPU cores for Windows.
 *
 * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L912-L916
 */
final class WmicPhysicalFinder extends ProcOpenBasedFinder
{
    private const CPU_CORE_COUNT_REGEX = '/NumberOfCores[\\s\\n]+(?<count>\\d+)/';
    protected function getCommand() : string
    {
        return 'wmic cpu get NumberOfCores';
    }
    public function toString() : string
    {
        return 'WmicPhysicalFinder';
    }
    public static function countCpuCores(string $process) : ?int
    {
        if (0 === preg_match(self::CPU_CORE_COUNT_REGEX, $process, $matches)) {
            return parent::countCpuCores($process);
        }
        $count = $matches['count'];
        return parent::countCpuCores($count);
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use function sprintf;
/**
 * This finder returns whatever value you gave to it. This is useful for testing
 * or as a fallback to avoid to catch the NumberOfCpuCoreNotFound exception.
 */
final class DummyCpuCoreFinder implements CpuCoreFinder
{
    /**
     * @var positive-int
     */
    private $count;
    public function diagnose() : string
    {
        return sprintf('Will return "%d".', $this->count);
    }
    /**
     * @param positive-int $count
     */
    public function __construct(int $count)
    {
        $this->count = $count;
    }
    public function find() : ?int
    {
        return $this->count;
    }
    public function toString() : string
    {
        return sprintf('DummyCpuCoreFinder(value=%d)', $this->count);
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use function filter_var;
use function is_int;
use function sprintf;
use const FILTER_VALIDATE_INT;
/**
 * The number of (logical) cores.
 *
 * @see https://github.com/infection/infection/blob/fbd8c44/src/Resource/Processor/CpuCoresCountProvider.php#L69-L82
 * @see https://unix.stackexchange.com/questions/146051/number-of-processors-in-proc-cpuinfo
 */
final class NProcFinder extends ProcOpenBasedFinder
{
    /**
     * @var bool
     */
    private $all;
    /**
     * @param bool $all If disabled will give the number of cores available for the current process only.
     */
    public function __construct(bool $all = \true)
    {
        $this->all = $all;
    }
    public function toString() : string
    {
        return sprintf('NProcFinder(all=%s)', $this->all ? 'true' : 'false');
    }
    protected function getCommand() : string
    {
        return 'nproc' . ($this->all ? ' --all' : '') . ' 2>&1';
    }
    /**
     * @return positive-int|null
     */
    public static function countCpuCores(string $nproc) : ?int
    {
        $cpuCount = filter_var($nproc, FILTER_VALIDATE_INT);
        return is_int($cpuCount) && $cpuCount > 0 ? $cpuCount : null;
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

use function defined;
use function sprintf;
final class OnlyOnWindowsFinder implements CpuCoreFinder
{
    /**
     * @var CpuCoreFinder
     */
    private $decoratedFinder;
    public function __construct(CpuCoreFinder $decoratedFinder)
    {
        $this->decoratedFinder = $decoratedFinder;
    }
    public function diagnose() : string
    {
        return self::skip() ? 'Non-windows platform detected (PHP_WINDOWS_VERSION_MAJOR is not set).' : $this->decoratedFinder->diagnose();
    }
    public function find() : ?int
    {
        return self::skip() ? null : $this->decoratedFinder->find();
    }
    public function toString() : string
    {
        return sprintf('OnlyOnWindowsFinder(%s)', $this->decoratedFinder->toString());
    }
    private static function skip() : bool
    {
        // Skip if not on Windows. Rely on PHP to detect the platform
        // rather than reading the platform name or others.
        return !defined('PHP_WINDOWS_VERSION_MAJOR');
    }
}
<?php

/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder;

/**
 * Find the number of logical CPU cores for Linux, BSD and OSX.
 *
 * @see https://github.com/paratestphp/paratest/blob/c163539818fd96308ca8dc60f46088461e366ed4/src/Runners/PHPUnit/Options.php#L903-L909
 * @see https://opensource.apple.com/source/xnu/xnu-792.2.4/libkern/libkern/sysctl.h.auto.html
 */
final class HwLogicalFinder extends ProcOpenBasedFinder
{
    protected function getCommand() : string
    {
        return 'sysctl -n hw.logicalcpu';
    }
    public function toString() : string
    {
        return 'HwLogicalFinder';
    }
}
#!/usr/bin/env php
<?php 
/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1;

use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Diagnoser;
use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder\FinderRegistry;
require_once __DIR__ . '/../vendor/autoload.php';
echo 'Running diagnosis...' . \PHP_EOL . \PHP_EOL;
echo Diagnoser::diagnose(FinderRegistry::getAllVariants()) . \PHP_EOL;
#!/usr/bin/env php
<?php 
/*
 * This file is part of the Fidry CPUCounter Config package.
 *
 * (c) Théo FIDRY <theo.fidry@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
declare (strict_types=1);
namespace _HumbugBox1cb33d1f20f1;

use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Diagnoser;
use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\Finder\FinderRegistry;
require_once __DIR__ . '/../vendor/autoload.php';
echo 'Executing finders...' . \PHP_EOL . \PHP_EOL;
echo Diagnoser::execute(FinderRegistry::getAllVariants()) . \PHP_EOL;
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="https://getpsalm.org/schema/config"
    targetNamespace="https://getpsalm.org/schema/config"
    elementFormDefault="qualified"
>
    <xs:element name="psalm" type="PsalmType" />

    <xs:complexType name="PsalmType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="projectFiles" type="ProjectFilesType" minOccurs="1" maxOccurs="1" />
            <xs:element name="extraFiles" type="ProjectFilesType" minOccurs="0" maxOccurs="1" />
            <xs:element name="taintAnalysis" type="TaintAnalysisType" minOccurs="0" maxOccurs="1" />
            <xs:element name="fileExtensions" type="FileExtensionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="mockClasses" type="MockClassesType" minOccurs="0" maxOccurs="1" />
            <xs:element name="stubs" type="StubsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="plugins" type="PluginsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="forbiddenFunctions" type="ExitFunctionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="issueHandlers" type="IssueHandlersType" minOccurs="0" maxOccurs="1" />
            <xs:element name="ignoreExceptions" type="ExceptionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="globals" type="GlobalsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="universalObjectCrates" type="UniversalObjectCratesType" minOccurs="0" maxOccurs="1" />
            <xs:element name="enableExtensions" type="ExtensionsType" minOccurs="0" maxOccurs="1" />
            <xs:element name="disableExtensions" type="ExtensionsType" minOccurs="0" maxOccurs="1" />
        </xs:choice>

        <xs:attribute name="autoloader" type="xs:string" />
        <xs:attribute name="cacheDirectory" type="xs:string" />
        <xs:attribute name="errorBaseline" type="xs:string" />
        <xs:attribute name="maxStringLength" type="xs:string" />
        <xs:attribute name="maxShapedArraySize" type="xs:string" default="100" />
        <xs:attribute name="name" type="xs:string" />
        <xs:attribute name="phpVersion" type="xs:string" />
        <xs:attribute name="serializer" type="xs:string" />

        <xs:attribute name="addParamDefaultToDocblockType" type="xs:boolean" default="false" />
        <xs:attribute name="allowFileIncludes" type="xs:boolean" default="true" />
        <xs:attribute name="allowStringToStandInForClass" type="xs:boolean" default="false" />
        <xs:attribute name="checkForThrowsDocblock" type="xs:boolean" default="false" />
        <xs:attribute name="checkForThrowsInGlobalScope" type="xs:boolean" default="false" />
        <xs:attribute name="ensureArrayIntOffsetsExist" type="xs:boolean" default="false" />
        <xs:attribute name="ensureArrayStringOffsetsExist" type="xs:boolean" default="false" />
        <xs:attribute name="findUnusedCode" type="xs:boolean" default="false" />
        <xs:attribute name="findUnusedVariablesAndParams" type="xs:boolean" default="false" />
        <xs:attribute name="findUnusedPsalmSuppress" type="xs:boolean" default="false" />
        <!-- TODO: Update default to true in Psalm 6 -->
        <xs:attribute name="findUnusedBaselineEntry" type="xs:boolean" default="false" />
        <xs:attribute name="hideExternalErrors" type="xs:boolean" default="false" />
        <xs:attribute name="hoistConstants" type="xs:boolean" default="false" />
        <xs:attribute name="ignoreInternalFunctionFalseReturn" type="xs:boolean" default="true" />
        <xs:attribute name="ignoreInternalFunctionNullReturn" type="xs:boolean" default="true" />
        <xs:attribute name="includePhpVersionsInErrorBaseline" type="xs:boolean" default="false" />
        <xs:attribute name="inferPropertyTypesFromConstructor" type="xs:boolean" default="true" />
        <xs:attribute name="memoizeMethodCallResults" type="xs:boolean" default="false" />
        <xs:attribute name="rememberPropertyAssignmentsAfterCall" type="xs:boolean" default="true" />
        <xs:attribute name="resolveFromConfigFile" type="xs:boolean" default="true" />
        <xs:attribute name="strictBinaryOperands" type="xs:boolean" default="false" />
        <xs:attribute name="throwExceptionOnError" type="xs:boolean" default="false" />
        <xs:attribute name="disableVarParsing" type="xs:boolean" default="false" />
        <xs:attribute name="errorLevel" type="xs:integer" default="2" />
        <xs:attribute name="reportMixedIssues" type="xs:boolean" default="true" />
        <xs:attribute name="useDocblockTypes" type="xs:boolean" default="true" />
        <xs:attribute name="useDocblockPropertyTypes" type="xs:boolean" default="false" />
        <xs:attribute name="usePhpDocMethodsWithoutMagicCall" type="xs:boolean" default="false" />
        <xs:attribute name="usePhpDocPropertiesWithoutMagicCall" type="xs:boolean" default="false" />
        <xs:attribute name="skipChecksOnUnresolvableIncludes" type="xs:boolean" default="false" />
        <xs:attribute name="sealAllMethods" type="xs:boolean" default="false" />
        <xs:attribute name="sealAllProperties" type="xs:boolean" default="false" />
        <xs:attribute name="runTaintAnalysis" type="xs:boolean" default="false" />
        <xs:attribute name="usePhpStormMetaPath" type="xs:boolean" default="true" />
        <xs:attribute name="allowInternalNamedArgumentCalls" type="xs:boolean" default="true" />
        <xs:attribute name="allowNamedArgumentCalls" type="xs:boolean" default="true" />
        <xs:attribute name="reportInfo" type="xs:boolean" default="true" />
        <xs:attribute name="restrictReturnTypes" type="xs:boolean" default="false" />
        <xs:attribute name="limitMethodComplexity" type="xs:boolean" default="false" />
        <xs:attribute name="disableSuppressAll" type="xs:boolean" default="false" />
        <xs:attribute name="triggerErrorExits" type="TriggerErrorExitsType" default="default" />
        <xs:attribute name="threads" type="xs:integer" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ProjectFilesType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="ProjectDirectoryAttributeType" />
            <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
            <xs:element name="ignoreFiles" minOccurs="0" maxOccurs="1" type="IgnoreFilesType" />
        </xs:choice>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="TaintAnalysisType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="ignoreFiles" minOccurs="0" maxOccurs="1" type="IgnoreFilesType" />
        </xs:choice>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="NameAttributeType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="StubsAttributeType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="preloadClasses" type="xs:boolean" default="false" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="IgnoreFilesType">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
            <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:choice>

        <xs:attribute name="allowMissingFiles" type="xs:string" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ProjectDirectoryAttributeType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="ignoreTypeStats" type="xs:string" />
        <xs:attribute name="resolveSymlinks" type="xs:boolean" />
        <xs:attribute name="useStrictTypes" type="xs:string" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="FileExtensionsType">
        <xs:sequence>
            <xs:element name="extension" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="name" type="xs:string" use="required" />
                    <xs:attribute name="scanner" type="xs:string" />
                    <xs:attribute name="checker" type="xs:string" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="MockClassesType">
        <xs:sequence>
            <xs:element name="class" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:sequence>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="UniversalObjectCratesType">
        <xs:sequence>
            <xs:element name="class" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:sequence>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ExceptionsType">
        <xs:sequence>
            <xs:element name="class" minOccurs="0" maxOccurs="unbounded" type="ExceptionType" />
            <xs:element name="classAndDescendants" minOccurs="0" maxOccurs="unbounded" type="ExceptionType" />
        </xs:sequence>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="StubsType">
        <xs:sequence>
            <xs:element name="file" maxOccurs="unbounded" type="StubsAttributeType" />
        </xs:sequence>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ExitFunctionsType">
        <xs:sequence>
            <xs:element name="function" maxOccurs="unbounded" type="NameAttributeType" />
        </xs:sequence>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="PluginsType">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="plugin">
                <xs:complexType>
                    <xs:attribute name="filename" type="xs:string" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
            <xs:element name="pluginClass">
                <xs:complexType>
                    <xs:sequence>
                        <xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
                    </xs:sequence>
                    <xs:attribute name="class" type="xs:string" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:choice>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="IssueHandlersType">
        <xs:choice minOccurs="0" maxOccurs="unbounded">
            <xs:element name="AbstractInstantiation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="AbstractMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="AmbiguousConstantInheritance" type="ClassConstantIssueHandlerType" minOccurs="0" />
            <xs:element name="ArgumentTypeCoercion" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="AssignmentToVoid" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="CheckType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="CircularReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ComplexFunction" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ComplexMethod" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ConfigIssue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ConflictingReferenceConstraint" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ConstantDeclarationInTrait" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ConstructorSignatureMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ContinueOutsideLoop" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedConstant" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedFunction" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedInterface" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="DeprecatedTrait" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DocblockTypeContradiction" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateArrayKey" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateClass" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateConstant" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateEnumCase" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateEnumCaseValue" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateFunction" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="DuplicateParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="EmptyArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ExtensionRequirementViolation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="FalsableReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="FalseOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ForbiddenCode" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="IfThisIsMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImplementationRequirementViolation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImplementedParamTypeMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImplementedReturnTypeMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImplicitToStringCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureByReferenceAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpurePropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpurePropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureStaticProperty" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureStaticVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ImpureVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InaccessibleClassConstant" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InaccessibleMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="InaccessibleProperty" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InterfaceInstantiation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InternalClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InternalMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="InternalProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidAttribute" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidCatch" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidClassConstantType" type="ClassConstantIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidClone" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidConstantAssignmentValue" type="ClassConstantIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidDocblock" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidDocblockParamName" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidEnumBackingType" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidEnumCaseValue" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidEnumMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidExtendClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidFalsableReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidGlobal" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidLiteralArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidNamedArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidNullableReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidParamDefault" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidParent" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPassByReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPropertyAssignmentValue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidScalarArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidScope" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidStaticInvocation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidStringClass" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidTemplateParam" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidThrow" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidToString" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidTraversableImplementation" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="InvalidTypeImport" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LessSpecificClassConstantType" type="ClassConstantIssueHandlerType" minOccurs="0" />
            <xs:element name="LessSpecificImplementedReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LessSpecificReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LessSpecificReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="LoopInvalidation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MethodSignatureMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MethodSignatureMustOmitReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MethodSignatureMustProvideReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MismatchingDocblockParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MismatchingDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MismatchingDocblockReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingClosureParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingClosureReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingConstructor" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingDependency" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingDocblockType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingFile" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingImmutableAnnotation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingPropertyType" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="MissingReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingTemplateParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MissingThrowsDocblock" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArgumentTypeCoercion" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedArrayTypeCoercion" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedClone" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="MixedFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedInferredReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedPropertyTypeCoercion" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="MixedReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedReturnTypeCoercion" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MixedStringOffsetAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MoreSpecificImplementedParamType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MoreSpecificReturnType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="MutableDependency" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="NamedArgumentNotAllowed" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="NoEnumProperties" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="NoInterfaceProperties" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="NonInvariantDocblockPropertyType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NonInvariantPropertyType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NonStaticSelfCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NoValue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullableReturnStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="NullArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="NullPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="NullPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="NullReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="OverriddenFinalConstant" type="ClassConstantIssueHandlerType" minOccurs="0" />
            <xs:element name="OverriddenInterfaceConstant" type="ClassConstantIssueHandlerType" minOccurs="0" />
            <xs:element name="OverriddenMethodAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="OverriddenPropertyAccess" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="ParadoxicalCondition" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ParamNameMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ParentNotFound" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PluginIssue" type="PluginIssueHandlerType" minOccurs="0" />
            <xs:element name="PossibleRawObjectIteration" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalsePropertyAssignmentValue" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyFalseReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidClone" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidDocblockTag" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidMethodCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidPropertyAssignmentValue" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyInvalidPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArgument" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArrayAccess" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArrayAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullIterator" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullOperand" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullPropertyAssignment" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullPropertyAssignmentValue" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullPropertyFetch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyNullReference" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedGlobalVariable" type="VariableIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedIntArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedStringArrayOffset" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUndefinedVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUnusedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUnusedParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUnusedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PossiblyUnusedReturnValue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="PropertyNotSetInConstructor" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="PropertyTypeCoercion" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="RawObjectIteration" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantCastGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantCondition" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantConditionGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantFunctionCall" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantFunctionCallGivenDocblockType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantIdentityWithTrue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RedundantPropertyInitializationCheck" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ReferenceConstraintViolation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ReferenceReusedFromConfusingScope" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="ReservedWord" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="RiskyCast" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="StringIncrement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedCallable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedCookie" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedCustom" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedEval" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedFile" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedHeader" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedHtml" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedInclude" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedInput" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedLdap" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedShell" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedSql" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedSSRF" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedSystemSecret" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedTextWithQuotes" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedUnserialize" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TaintedUserSecret" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TooFewArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="TooManyArguments" type="ArgumentIssueHandlerType" minOccurs="0" />
            <xs:element name="TooManyTemplateParams" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="Trace" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TraitMethodSignatureMismatch" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TypeDoesNotContainNull" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="TypeDoesNotContainType" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UncaughtThrowInGlobalScope" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedAttributeClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedConstant" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedDocblockClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedFunction" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedGlobalVariable" type="VariableIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedInterface" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedInterfaceMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMagicMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMagicPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMagicPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedThisPropertyAssignment" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedThisPropertyFetch" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedTrace" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedTrait" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UndefinedVariable" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnevaluatedCode" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnhandledMatchCondition" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnimplementedAbstractMethod" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnimplementedInterfaceMethod" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UninitializedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UnnecessaryVarAnnotation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnrecognizedExpression" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnrecognizedStatement" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnresolvableConstant" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnresolvableInclude" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnsafeGenericInstantiation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnsafeInstantiation" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnsupportedReferenceUsage" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedBaselineEntry" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedClass" type="ClassIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedClosureParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedConstructor" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedForeachValue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedFunctionCall" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedMethod" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedMethodCall" type="MethodIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedParam" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedProperty" type="PropertyIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedPsalmSuppress" type="FunctionIssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedReturnValue" type="IssueHandlerType" minOccurs="0" />
            <xs:element name="UnusedVariable" type="IssueHandlerType" minOccurs="0" />
        </xs:choice>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="IssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="PluginIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:anyAttribute processContents="skip"/>
    </xs:complexType>

    <xs:complexType name="MethodIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedMethod" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="FunctionIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedFunction" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ArgumentIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedFunction" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ClassIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedClass" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="PropertyIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedProperty" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ClassConstantIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedConstant" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
    </xs:complexType>

    <xs:complexType name="VariableIssueHandlerType">
        <xs:sequence>
            <xs:element name="errorLevel" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element name="directory" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="file" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                        <xs:element name="referencedVariable" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
                    </xs:choice>

                    <xs:attribute name="type" type="ErrorLevelType" use="required" />
                    <xs:anyAttribute processContents="skip" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>

        <xs:attribute name="errorLevel" type="ErrorLevelType" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="GlobalsType">
        <xs:sequence>
            <xs:element name="var" maxOccurs="unbounded" type="IdentifierType" />
        </xs:sequence>
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="IdentifierType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="type" type="xs:string" use="required" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:complexType name="ExceptionType">
        <xs:attribute name="name" type="xs:string" use="required" />
        <xs:attribute name="onlyGlobalScope" type="xs:string" />
        <xs:anyAttribute processContents="skip" />
    </xs:complexType>

    <xs:simpleType name="ErrorLevelType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="error"/>
            <xs:enumeration value="info"/>
            <xs:enumeration value="suppress"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="TriggerErrorExitsType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="default"/>
            <xs:enumeration value="never"/>
            <xs:enumeration value="always"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="ExtensionsType">
        <xs:sequence>
            <xs:element name="extension" maxOccurs="unbounded" type="ExtensionAttributeType" />
        </xs:sequence>
    </xs:complexType>

    <xs:simpleType name="ExtensionType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="apcu"/>
            <xs:enumeration value="decimal"/>
            <xs:enumeration value="dom"/>
            <xs:enumeration value="ds"/>
            <xs:enumeration value="ffi"/>
            <xs:enumeration value="geos"/>
            <xs:enumeration value="gmp"/>
            <xs:enumeration value="mongodb"/>
            <xs:enumeration value="mysqli"/>
            <xs:enumeration value="pdo"/>
            <xs:enumeration value="random"/>
            <xs:enumeration value="redis"/>
            <xs:enumeration value="simplexml"/>
            <xs:enumeration value="soap"/>
            <xs:enumeration value="xdebug"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="ExtensionAttributeType">
        <xs:attribute name="name" type="ExtensionType" use="required" />
    </xs:complexType>
</xs:schema>
<?php

namespace Psalm;

use Psalm\Type\Union;
interface StatementsSource extends \Psalm\FileSource
{
    public function getNamespace() : ?string;
    /**
     * @return array<lowercase-string, string>
     */
    public function getAliasedClassesFlipped() : array;
    /**
     * @return array<string, string>
     */
    public function getAliasedClassesFlippedReplaceable() : array;
    public function getFQCLN() : ?string;
    public function getClassName() : ?string;
    public function getParentFQCLN() : ?string;
    /**
     * @return array<string, array<string, Union>>|null
     */
    public function getTemplateTypeMap() : ?array;
    public function setRootFilePath(string $file_path, string $file_name) : void;
    public function hasParentFilePath(string $file_path) : bool;
    public function hasAlreadyRequiredFilePath(string $file_path) : bool;
    public function getRequireNesting() : int;
    public function isStatic() : bool;
    public function getSource() : \Psalm\StatementsSource;
    public function getCodebase() : \Psalm\Codebase;
    /**
     * Get a list of suppressed issues
     *
     * @return array<string>
     */
    public function getSuppressedIssues() : array;
    /**
     * @param list<string> $new_issues
     */
    public function addSuppressedIssues(array $new_issues) : void;
    /**
     * @param list<string> $new_issues
     */
    public function removeSuppressedIssues(array $new_issues) : void;
    public function getNodeTypeProvider() : \Psalm\NodeTypeProvider;
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Internal\Json\Json;
use Psalm\Report;
use function max;
/**
 * JSON report format suitable for import into SonarQube or SonarCloud as
 * generic (external) issue data via `sonar.externalIssuesReportPaths`.
 *
 * https://docs.sonarqube.org/latest/analysis/generic-issue/
 */
final class SonarqubeReport extends Report
{
    public function create() : string
    {
        $report = ['issues' => []];
        foreach ($this->issues_data as $issue_data) {
            $report['issues'][] = ['engineId' => 'Psalm', 'ruleId' => $issue_data->type, 'primaryLocation' => ['message' => $issue_data->message, 'filePath' => $issue_data->file_name, 'textRange' => [
                'startLine' => $issue_data->line_from,
                'endLine' => $issue_data->line_to,
                // Columns in external issue reports are indexed from 0
                'startColumn' => max(0, $issue_data->column_from - 1),
                'endColumn' => max(0, $issue_data->column_to - 1),
            ]], 'type' => 'CODE_SMELL', 'severity' => $issue_data->severity === Config::REPORT_ERROR ? 'CRITICAL' : 'MINOR'];
        }
        $options = $this->pretty ? Json::PRETTY : Json::DEFAULT;
        return Json::encode($report, $options) . "\n";
    }
}
<?php

namespace Psalm\Report;

use Psalm\Internal\Json\Json;
use Psalm\Report;
final class JsonSummaryReport extends Report
{
    public function create() : string
    {
        $type_counts = [];
        foreach ($this->issues_data as $issue_data) {
            $type = $issue_data->type;
            if (!isset($type_counts[$type])) {
                $type_counts[$type] = 0;
            }
            ++$type_counts[$type];
        }
        $options = $this->pretty ? Json::PRETTY : Json::DEFAULT;
        return Json::encode(['issue_counts' => $type_counts, 'mixed_expression_count' => $this->mixed_expression_count, 'total_expression_count' => $this->total_expression_count], $options) . "\n";
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Json\Json;
use Psalm\Report;
use function array_map;
use function array_values;
use function md5;
/**
 * CodeClimate format
 * This is the format used by Gitlab for CodeQuality
 *
 * @see https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html
 * @see https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types
 * @author Olivier Doucet <webmaster@ajeux.com>
 */
final class CodeClimateReport extends Report
{
    public function create() : string
    {
        $options = $this->pretty ? Json::PRETTY : Json::DEFAULT;
        $issues_data = array_map([$this, 'mapToNewStructure'], $this->issues_data);
        return Json::encode(array_values($issues_data), $options) . "\n";
    }
    /**
     * convert our own severity to CodeClimate format
     * Values can be : info, minor, major, critical, or blocker
     */
    protected function convertSeverity(string $input) : string
    {
        if (Config::REPORT_INFO === $input) {
            return 'info';
        }
        if (Config::REPORT_ERROR === $input) {
            return 'critical';
        }
        if (Config::REPORT_SUPPRESS === $input) {
            return 'minor';
        }
        // unknown cases ? fallback
        return 'critical';
    }
    /**
     * calculate a unique fingerprint for a given issue
     */
    protected function calculateFingerprint(IssueData $issue) : string
    {
        return md5($issue->type . $issue->message . $issue->file_name . $issue->from . $issue->to);
    }
    /**
     * map fields to new structure.
     * Expected fields:
     * - type
     * - check_name
     * - description*
     * - content
     * - categories[]
     * - severity
     * - fingerprint*
     * - location.path*
     * - location.lines.begin*
     *
     * Fields with * are the one used by Gitlab for Code Quality
     */
    private function mapToNewStructure(IssueData $issue) : array
    {
        return ['type' => 'issue', 'check_name' => $issue->type, 'description' => $issue->message, 'categories' => [$issue->type], 'severity' => $this->convertSeverity($issue->severity), 'fingerprint' => $this->calculateFingerprint($issue), 'location' => ['path' => $issue->file_name, 'lines' => ['begin' => $issue->line_from, 'end' => $issue->line_to]]];
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Report;

use Psalm\Report;
use function array_key_exists;
use function uksort;
class CountReport extends Report
{
    public function create() : string
    {
        $issue_type_counts = [];
        foreach ($this->issues_data as $issue_data) {
            if (array_key_exists($issue_data->type, $issue_type_counts)) {
                $issue_type_counts[$issue_data->type]++;
            } else {
                $issue_type_counts[$issue_data->type] = 1;
            }
        }
        uksort($issue_type_counts, function (string $a, string $b) use($issue_type_counts) : int {
            $cmp_result = $issue_type_counts[$a] <=> $issue_type_counts[$b];
            if ($cmp_result === 0) {
                return $a <=> $b;
            } else {
                return $cmp_result;
            }
        });
        $output = '';
        foreach ($issue_type_counts as $issue_type => $count) {
            $output .= "{$issue_type}: {$count}\n";
        }
        return $output;
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Internal\Analyzer\DataFlowNodeData;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report;
use function basename;
use function get_cfg_var;
use function ini_get;
use function strlen;
use function strtr;
use function substr;
final class ConsoleReport extends Report
{
    private ?string $link_format = null;
    public function create() : string
    {
        $output = '';
        foreach ($this->issues_data as $issue_data) {
            $output .= $this->format($issue_data) . "\n" . "\n";
        }
        return $output;
    }
    private function format(IssueData $issue_data) : string
    {
        $issue_string = '';
        $is_error = $issue_data->severity === Config::REPORT_ERROR;
        if ($is_error) {
            $issue_string .= $this->use_color ? "\x1b[0;31mERROR\x1b[0m" : 'ERROR';
        } else {
            $issue_string .= 'INFO';
        }
        $issue_reference = $issue_data->link ? ' (see ' . $issue_data->link . ')' : '';
        $issue_string .= ': ' . $issue_data->type . ' - ' . $this->getFileReference($issue_data) . ' - ' . $issue_data->message . $issue_reference . "\n";
        if ($issue_data->taint_trace) {
            $issue_string .= $this->getTaintSnippets($issue_data->taint_trace);
        } elseif ($this->show_snippet) {
            $snippet = $issue_data->snippet;
            if (!$this->use_color) {
                $issue_string .= $snippet;
            } else {
                $selection_start = $issue_data->from - $issue_data->snippet_from;
                $selection_length = $issue_data->to - $issue_data->from;
                $issue_string .= substr($snippet, 0, $selection_start) . ($is_error ? "\x1b[97;41m" : "\x1b[30;47m") . substr($snippet, $selection_start, $selection_length) . "\x1b[0m" . substr($snippet, $selection_length + $selection_start) . "\n";
            }
        }
        if ($issue_data->other_references) {
            if ($this->show_snippet) {
                $issue_string .= "\n";
            }
            $issue_string .= $this->getTaintSnippets($issue_data->other_references);
        }
        return $issue_string;
    }
    /**
     * @param non-empty-list<DataFlowNodeData|array{label: string, entry_path_type: string}> $taint_trace
     */
    private function getTaintSnippets(array $taint_trace) : string
    {
        $snippets = '';
        foreach ($taint_trace as $node_data) {
            if ($node_data instanceof DataFlowNodeData) {
                $snippets .= '  ' . $node_data->label . ' - ' . $this->getFileReference($node_data) . "\n";
                if ($this->show_snippet) {
                    $snippet = $node_data->snippet;
                    if (!$this->use_color) {
                        $snippets .= $snippet . "\n\n";
                    } else {
                        $selection_start = $node_data->from - $node_data->snippet_from;
                        $selection_length = $node_data->to - $node_data->from;
                        $snippets .= substr($snippet, 0, $selection_start) . "\x1b[30;47m" . substr($snippet, $selection_start, $selection_length) . "\x1b[0m" . substr($snippet, $selection_length + $selection_start) . "\n\n";
                    }
                }
            } else {
                $snippets .= '  ' . $node_data['label'] . "\n";
                $snippets .= '    <no known location>' . "\n\n";
            }
        }
        return $snippets;
    }
    /**
     * @param IssueData|DataFlowNodeData $data
     */
    private function getFileReference($data) : string
    {
        $reference = $data->file_name . ':' . $data->line_from . ':' . $data->column_from;
        if (!$this->use_color) {
            return $reference;
        }
        $file_basename = basename($data->file_name);
        $file_path = substr($data->file_name, 0, -strlen($file_basename));
        $reference = $file_path . "\x1b[1;31m" . $file_basename . ':' . $data->line_from . ':' . $data->column_from . "\x1b[0m";
        if ($this->in_ci) {
            return $reference;
        }
        if (null === $this->link_format) {
            // if xdebug is not enabled, use `get_cfg_var` to get the value directly from php.ini
            $this->link_format = (ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format')) ?: 'file://%f#L%l';
        }
        $link = strtr($this->link_format, ['%f' => $data->file_path, '%l' => $data->line_from]);
        // $reference = $data->file_name . ':' . $data->line_from . ':' . $data->column_from;
        return "\x1b]8;;" . $link . "\x1b\\" . $reference . "\x1b]8;;\x1b\\";
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Report;
use function sprintf;
use function strtr;
final class GithubActionsReport extends Report
{
    public function create() : string
    {
        $output = '';
        foreach ($this->issues_data as $issue_data) {
            $issue_reference = $issue_data->link ? ' (see ' . $issue_data->link . ')' : '';
            $properties = sprintf('file=%1$s,line=%2$d,col=%3$d,title=%4$s', $this->escapeProperty($issue_data->file_name), $this->escapeProperty($issue_data->line_from), $this->escapeProperty($issue_data->column_from), $this->escapeProperty($issue_data->type));
            $data = $this->escapeData(sprintf('%1$s:%2$d:%3$d: %4$s: %5$s', $issue_data->file_name, $issue_data->line_from, $issue_data->column_from, $issue_data->type, $issue_data->message . $issue_reference));
            $output .= sprintf('::%1$s %2$s::%3$s', $issue_data->severity === Config::REPORT_ERROR ? 'error' : 'warning', $properties, $data) . "\n";
        }
        return $output;
    }
    private function escapeData(string $data) : string
    {
        return strtr($data, ['%' => '%25', "\r" => '%0D', "\n" => '%0A']);
    }
    /** @param mixed $value */
    private function escapeProperty($value) : string
    {
        return strtr((string) $value, ['%' => '%25', "\r" => '%0D', "\n" => '%0A', ':' => '%3A', ',' => '%2C']);
    }
}
<?php

namespace Psalm\Report;

use Psalm\Report;
final class ReportOptions
{
    /**
     * @var bool
     */
    public $use_color = \true;
    /**
     * @var bool
     */
    public $show_snippet = \true;
    /**
     * @var bool
     */
    public $show_info = \true;
    /**
     * @var Report::TYPE_*
     */
    public $format = Report::TYPE_CONSOLE;
    /**
     * @var bool
     */
    public $pretty = \false;
    /**
     * @var ?string
     */
    public $output_path;
    /**
     * @var bool
     */
    public $show_suggestions = \true;
    /** @var bool */
    public $in_ci = \false;
}
<?php

namespace Psalm\Report;

use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Json\Json;
use Psalm\Report;
use function array_map;
use function array_values;
final class JsonReport extends Report
{
    public function create() : string
    {
        $options = $this->pretty ? Json::PRETTY : Json::DEFAULT;
        $issues_data = array_map(static function (IssueData $issue_data) : array {
            $issue_data = (array) $issue_data;
            unset($issue_data['dupe_key']);
            return $issue_data;
        }, $this->issues_data);
        return Json::encode(array_values($issues_data), $options) . "\n";
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Report;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Helper\Table;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\BufferedOutput;
use function count;
use function implode;
use function str_split;
use function strlen;
use function strtoupper;
final class CompactReport extends Report
{
    /**
     * @psalm-suppress PossiblyNullReference
     */
    public function create() : string
    {
        /** @var BufferedOutput|null $buffer */
        $buffer = null;
        /** @var Table|null $table */
        $table = null;
        /** @var string|null $current_file */
        $current_file = null;
        $output = [];
        foreach ($this->issues_data as $i => $issue_data) {
            if (!$this->show_info && $issue_data->severity === Config::REPORT_INFO) {
                continue;
            }
            if ($current_file === null || $current_file !== $issue_data->file_name) {
                // If we're processing a new file, then wrap up the last table and render it out.
                if ($buffer !== null) {
                    $table->render();
                    $output[] = $buffer->fetch();
                }
                $output[] = 'FILE: ' . $issue_data->file_name . "\n";
                $buffer = new BufferedOutput();
                $table = new Table($buffer);
                $table->setHeaders(['SEVERITY', 'LINE', 'ISSUE', 'DESCRIPTION']);
            }
            $is_error = $issue_data->severity === Config::REPORT_ERROR;
            if ($is_error) {
                $severity = $this->use_color ? "\x1b[0;31mERROR\x1b[0m" : 'ERROR';
            } else {
                $severity = strtoupper($issue_data->severity);
            }
            // Since `Table::setColumnMaxWidth` is only available in symfony/console 4.2+ we need do something similar
            // so we have clean tables.
            $message = $issue_data->message;
            if (strlen($message) > 70) {
                $message = implode("\n", str_split($message, 70));
            }
            $table->addRow([$severity, $issue_data->line_from, $issue_data->type, $message]);
            $current_file = $issue_data->file_name;
            // If we're at the end of the issue sets, then wrap up the last table and render it out.
            if ($i === count($this->issues_data) - 1) {
                $table->render();
                $output[] = $buffer->fetch();
            }
        }
        return implode("\n", $output);
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Internal\Analyzer\DataFlowNodeData;
use Psalm\Internal\Json\Json;
use Psalm\Report;
use function file_exists;
use function file_get_contents;
use function strpos;
/**
 * SARIF report format suitable for import into any SARIF compatible solution
 *
 * https://docs.oasis-open.org/sarif/sarif/v2.1.0/cs01/sarif-v2.1.0-cs01.html
 */
final class SarifReport extends Report
{
    public function create() : string
    {
        $report = ['version' => '2.1.0', '$schema' => 'https://json.schemastore.org/sarif-2.1.0.json', 'runs' => [['tool' => ['driver' => ['name' => 'Psalm', 'informationUri' => 'https://psalm.dev', 'version' => \PSALM_VERSION]], 'results' => []]]];
        $rules = [];
        foreach ($this->issues_data as $issue_data) {
            $rules[$issue_data->shortcode] = ['id' => (string) $issue_data->shortcode, 'name' => $issue_data->type, 'shortDescription' => ['text' => $issue_data->type], 'properties' => ['tags' => [strpos($issue_data->type, 'Tainted') === 0 ? 'security' : 'maintainability']], 'helpUri' => $issue_data->link];
            $markdown_documentation_path = __DIR__ . '/../../../docs/running_psalm/issues/' . $issue_data->type . '.md';
            if (file_exists($markdown_documentation_path)) {
                $markdown_documentation = file_get_contents($markdown_documentation_path);
                $rules[$issue_data->shortcode]['help']['markdown'] = $markdown_documentation;
                $rules[$issue_data->shortcode]['help']['text'] = $markdown_documentation;
            }
            $jsonEntry = ['ruleId' => (string) $issue_data->shortcode, 'message' => ['text' => $issue_data->message], 'level' => $issue_data->severity === Config::REPORT_ERROR ? 'error' : 'note', 'locations' => [['physicalLocation' => ['artifactLocation' => ['uri' => $issue_data->file_name], 'region' => ['startLine' => $issue_data->line_from, 'endLine' => $issue_data->line_to, 'startColumn' => $issue_data->column_from, 'endColumn' => $issue_data->column_to]]]]];
            if ($issue_data->taint_trace != null) {
                $jsonEntry['codeFlows'] = [['message' => ['text' => 'Tracing the path from user input to insecure usage'], 'threadFlows' => [['locations' => []]]]];
                foreach ($issue_data->taint_trace as $trace) {
                    if ($trace instanceof DataFlowNodeData && $trace->line_from > 0) {
                        $jsonEntry['codeFlows'][0]['threadFlows'][0]['locations'][] = ['location' => ['physicalLocation' => ['artifactLocation' => ['uri' => $trace->file_name], 'region' => ['startLine' => $trace->line_from, 'endLine' => $trace->line_to, 'startColumn' => $trace->column_from, 'endColumn' => $trace->column_to]]]];
                    }
                }
            }
            $report['runs'][0]['results'][] = $jsonEntry;
        }
        foreach ($rules as $rule) {
            $report['runs'][0]['tool']['driver']['rules'][] = $rule;
        }
        $options = $this->pretty ? Json::PRETTY : Json::DEFAULT;
        return Json::encode($report, $options) . "\n";
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Report;
use function sprintf;
final class EmacsReport extends Report
{
    public function create() : string
    {
        $output = '';
        foreach ($this->issues_data as $issue_data) {
            $output .= sprintf('%s:%s:%s:%s - %s', $issue_data->file_path, $issue_data->line_from, $issue_data->column_from, $issue_data->severity === Config::REPORT_ERROR ? 'error' : 'warning', $issue_data->message) . "\n";
        }
        return $output;
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Report;
use function sprintf;
final class TextReport extends Report
{
    public function create() : string
    {
        $output = '';
        foreach ($this->issues_data as $issue_data) {
            $output .= sprintf('%s:%s:%s:%s - %s: %s', $issue_data->file_path, $issue_data->line_from, $issue_data->column_from, $issue_data->severity === Config::REPORT_ERROR ? 'error' : 'warning', $issue_data->type, $issue_data->message) . "\n";
        }
        return $output;
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Internal\Analyzer\DataFlowNodeData;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report;
use function basename;
use function get_cfg_var;
use function ini_get;
use function strlen;
use function strtr;
use function substr;
use function usort;
final class ByIssueLevelAndTypeReport extends Report
{
    private ?string $link_format = null;
    public function create() : string
    {
        $this->sortIssuesByLevelAndType();
        $output = <<<HEADING
|----------------------------------------------------------------------------------------|
|    Issues have been sorted by level and type. Feature-specific issues and the          |
|    most serious issues that will always be reported are listed first, with             |
|    remaining issues in level order. Issues near the top are usually the most serious.  |
|    Reducing the errorLevel in psalm.xml will suppress output of issues further down    |
|    this report.                                                                        |
|                                                                                        |
|    The level at which issue is reported as an error is given in brackets - e.g.        |
|    `ERROR (2): MissingReturnType` indicates that MissingReturnType is only reported    |
|    as an error when Psalm's level is set to 2 or below.                                |
|                                                                                        |
|    Issues are shown or hidden in this report according to current settings. For        |
|    the most complete report set Psalm's error level to 0 or use --show-info=true       |
|    See https://psalm.dev/docs/running_psalm/error_levels/                              |
|----------------------------------------------------------------------------------------|


HEADING;
        foreach ($this->issues_data as $issue_data) {
            $output .= $this->format($issue_data) . "\n" . "\n";
        }
        return $output;
    }
    /**
     * Copied from ConsoleReport with only very minor changes.
     */
    private function format(IssueData $issue_data) : string
    {
        $issue_string = '';
        $is_error = $issue_data->severity === Config::REPORT_ERROR;
        if ($is_error) {
            $issue_string .= $this->use_color ? "\x1b[0;31mERROR\x1b[0m" : 'ERROR';
        } else {
            $issue_string .= 'INFO';
        }
        $issue_reference = $issue_data->link ? ' (see ' . $issue_data->link . ')' : '';
        $level = $issue_data->error_level;
        $issue_string .= ($level > 0 ? " ({$level}): " : ": ") . $issue_data->type . ' - ' . $this->getFileReference($issue_data) . ' - ' . $issue_data->message . $issue_reference . "\n";
        if ($issue_data->taint_trace) {
            $issue_string .= $this->getTaintSnippets($issue_data->taint_trace);
        } elseif ($this->show_snippet) {
            $snippet = $issue_data->snippet;
            if (!$this->use_color) {
                $issue_string .= $snippet;
            } else {
                $selection_start = $issue_data->from - $issue_data->snippet_from;
                $selection_length = $issue_data->to - $issue_data->from;
                $issue_string .= substr($snippet, 0, $selection_start) . ($is_error ? "\x1b[97;41m" : "\x1b[30;47m") . substr($snippet, $selection_start, $selection_length) . "\x1b[0m" . substr($snippet, $selection_length + $selection_start) . "\n";
            }
        }
        if ($issue_data->other_references) {
            if ($this->show_snippet) {
                $issue_string .= "\n";
            }
            $issue_string .= $this->getTaintSnippets($issue_data->other_references);
        }
        return $issue_string;
    }
    /**
     * Copied from ConsoleReport unchanged. We could consider moving to another class to reduce duplication.
     *
     * @param non-empty-list<DataFlowNodeData|array{label: string, entry_path_type: string}> $taint_trace
     */
    private function getTaintSnippets(array $taint_trace) : string
    {
        $snippets = '';
        foreach ($taint_trace as $node_data) {
            if ($node_data instanceof DataFlowNodeData) {
                $snippets .= '  ' . $node_data->label . ' - ' . $this->getFileReference($node_data) . "\n";
                if ($this->show_snippet) {
                    $snippet = $node_data->snippet;
                    if (!$this->use_color) {
                        $snippets .= $snippet . "\n\n";
                    } else {
                        $selection_start = $node_data->from - $node_data->snippet_from;
                        $selection_length = $node_data->to - $node_data->from;
                        $snippets .= substr($snippet, 0, $selection_start) . "\x1b[30;47m" . substr($snippet, $selection_start, $selection_length) . "\x1b[0m" . substr($snippet, $selection_length + $selection_start) . "\n\n";
                    }
                }
            } else {
                $snippets .= '  ' . $node_data['label'] . "\n";
                $snippets .= '    <no known location>' . "\n\n";
            }
        }
        return $snippets;
    }
    /**
     * Copied from ConsoleReport unchanged. We could consider moving to another class to reduce duplication.
     *
     * @param IssueData|DataFlowNodeData $data
     */
    private function getFileReference($data) : string
    {
        $reference = $data->file_name . ':' . $data->line_from . ':' . $data->column_from;
        if (!$this->use_color) {
            return $reference;
        }
        $file_basename = basename($data->file_name);
        $file_path = substr($data->file_name, 0, -strlen($file_basename));
        $reference = $file_path . "\x1b[1;31m" . $file_basename . ':' . $data->line_from . ':' . $data->column_from . "\x1b[0m";
        if ($this->in_ci) {
            return $reference;
        }
        if (null === $this->link_format) {
            // if xdebug is not enabled, use `get_cfg_var` to get the value directly from php.ini
            $this->link_format = (ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format')) ?: 'file://%f#L%l';
        }
        $link = strtr($this->link_format, ['%f' => $data->file_path, '%l' => $data->line_from]);
        // $reference = $data->file_name . ':' . $data->line_from . ':' . $data->column_from;
        return "\x1b]8;;" . $link . "\x1b\\" . $reference . "\x1b]8;;\x1b\\";
    }
    private function sortIssuesByLevelAndType() : void
    {
        usort($this->issues_data, fn(IssueData $left, IssueData $right): int => [$left->error_level > 0, -$left->error_level, $left->type, $left->file_path, $left->file_name, $left->line_from] <=> [$right->error_level > 0, -$right->error_level, $right->type, $right->file_path, $right->file_name, $right->line_from]);
    }
}
<?php

namespace Psalm\Report;

use Psalm\Report;
use function sprintf;
final class CheckstyleReport extends Report
{
    public function create() : string
    {
        $output = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        $output .= '<checkstyle>' . "\n";
        foreach ($this->issues_data as $issue_data) {
            $message = sprintf('%s: %s', $issue_data->type, $issue_data->message);
            $output .= '<file name="' . $this->xmlEncode($issue_data->file_name) . '">' . "\n";
            $output .= ' ';
            $output .= '<error';
            $output .= ' line="' . $issue_data->line_from . '"';
            $output .= ' column="' . $issue_data->column_from . '"';
            $output .= ' severity="' . $issue_data->severity . '"';
            $output .= ' message="' . $this->xmlEncode($message) . '"';
            $output .= '/>' . "\n";
            $output .= '</file>' . "\n";
        }
        $output .= '</checkstyle>' . "\n";
        return $output;
    }
}
<?php

namespace Psalm\Report;

use Psalm\Internal\Analyzer\DataFlowNodeData;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report;
use _HumbugBox1cb33d1f20f1\Spatie\ArrayToXml\ArrayToXml;
use function array_map;
use function get_object_vars;
final class XmlReport extends Report
{
    public function create() : string
    {
        $xml = (string) ArrayToXml::convert(['item' => array_map(static function (IssueData $issue_data) : array {
            $issue_data = get_object_vars($issue_data);
            unset($issue_data['dupe_key']);
            if (null !== $issue_data['taint_trace']) {
                $issue_data['taint_trace'] = array_map(static fn($trace): array => (array) $trace, $issue_data['taint_trace']);
            }
            // replace null values, as XML serializers tend to have problems with them
            $issue_data['taint_trace'] ??= '';
            if (null !== $issue_data['other_references']) {
                $issue_data['other_references'] = array_map(static fn(DataFlowNodeData $reference): array => (array) $reference, $issue_data['other_references']);
            }
            // replace null values, as XML serializers tend to have problems with them
            $issue_data['other_references'] ??= '';
            return $issue_data;
        }, $this->issues_data)], 'report', \true, 'UTF-8', '1.0', ['preserveWhiteSpace' => \false, 'formatOutput' => \true]);
        return $xml;
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report;
use function sprintf;
final class PylintReport extends Report
{
    public function create() : string
    {
        $output = '';
        foreach ($this->issues_data as $issue_data) {
            $output .= $this->format($issue_data) . "\n";
        }
        return $output;
    }
    private function format(IssueData $issue_data) : string
    {
        $message = sprintf('%s: %s', $issue_data->type, $issue_data->message);
        if ($issue_data->severity === Config::REPORT_ERROR) {
            $code = 'E0001';
        } else {
            $code = 'W0001';
        }
        // https://docs.pylint.org/en/1.6.0/output.html doesn't mention what to do about 'column',
        // but it's still useful for users.
        // E.g. jenkins can't parse %s:%d:%d.
        $message = sprintf('%s (column %d)', $message, $issue_data->column_from);
        return sprintf('%s:%d: [%s] %s', $issue_data->file_name, $issue_data->line_from, $code, $message);
    }
}
<?php

namespace Psalm\Report;

use Psalm\Config;
use Psalm\Internal\Analyzer\DataFlowNodeData;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report;
use function substr;
final class PhpStormReport extends Report
{
    public function create() : string
    {
        $output = '';
        foreach ($this->issues_data as $issue_data) {
            $output .= $this->format($issue_data) . "\n" . "\n";
        }
        return $output;
    }
    private function format(IssueData $issue_data) : string
    {
        $issue_string = '';
        $is_error = $issue_data->severity === Config::REPORT_ERROR;
        if ($is_error) {
            $issue_string .= $this->use_color ? "\x1b[0;31mERROR\x1b[0m" : 'ERROR';
        } else {
            $issue_string .= 'INFO';
        }
        $issue_reference = $issue_data->link ? ' (see ' . $issue_data->link . ')' : '';
        $issue_string .= ': ' . $issue_data->type . "\nat " . $issue_data->file_path . ':' . $issue_data->line_from . ':' . $issue_data->column_from . "\n" . $issue_data->message . $issue_reference . "\n";
        if ($issue_data->taint_trace) {
            $issue_string .= $this->getTaintSnippets($issue_data->taint_trace);
        } elseif ($this->show_snippet) {
            $snippet = $issue_data->snippet;
            if (!$this->use_color) {
                $issue_string .= $snippet;
            } else {
                $selection_start = $issue_data->from - $issue_data->snippet_from;
                $selection_length = $issue_data->to - $issue_data->from;
                $issue_string .= substr($snippet, 0, $selection_start) . ($is_error ? "\x1b[97;41m" : "\x1b[30;47m") . substr($snippet, $selection_start, $selection_length) . "\x1b[0m" . substr($snippet, $selection_length + $selection_start) . "\n";
            }
        }
        return $issue_string;
    }
    /**
     * @param non-empty-list<DataFlowNodeData|array{label: string, entry_path_type: string}> $taint_trace
     */
    private function getTaintSnippets(array $taint_trace) : string
    {
        $snippets = '';
        foreach ($taint_trace as $node_data) {
            if ($node_data instanceof DataFlowNodeData) {
                $snippets .= '  ' . $node_data->label . ' - ' . $node_data->file_name . ':' . $node_data->line_from . ':' . $node_data->column_from . "\n";
                if ($this->show_snippet) {
                    $snippet = $node_data->snippet;
                    if (!$this->use_color) {
                        $snippets .= $snippet . "\n\n";
                    } else {
                        $selection_start = $node_data->from - $node_data->snippet_from;
                        $selection_length = $node_data->to - $node_data->from;
                        $snippets .= substr($snippet, 0, $selection_start) . "\x1b[30;47m" . substr($snippet, $selection_start, $selection_length) . "\x1b[0m" . substr($snippet, $selection_length + $selection_start) . "\n\n";
                    }
                }
            } else {
                $snippets .= '  ' . $node_data['label'] . "\n";
                $snippets .= '    <no known location>' . "\n\n";
            }
        }
        return $snippets;
    }
}
<?php

namespace Psalm\Report;

use DOMDocument;
use DOMElement;
use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report;
use function count;
use function trim;
/**
 * based on https://github.com/m50/psalm-json-to-junit
 * Copyright (c) Marisa Clardy marisa@clardy.eu
 *
 * with a few modifications
 */
final class JunitReport extends Report
{
    public function create() : string
    {
        $errors = 0;
        $tests = 0;
        $ndata = [];
        foreach ($this->issues_data as $error) {
            $is_error = $error->severity === Config::REPORT_ERROR;
            $is_warning = $error->severity === Config::REPORT_INFO;
            if (!$is_error && !$is_warning) {
                continue;
            }
            if ($is_error) {
                $errors++;
            }
            $tests++;
            $fname = $error->file_name;
            if (!isset($ndata[$fname])) {
                $ndata[$fname] = ['errors' => $is_error ? 1 : 0, 'warnings' => $is_warning ? 1 : 0, 'failures' => []];
            } else {
                if ($is_error) {
                    $ndata[$fname]['errors']++;
                } else {
                    $ndata[$fname]['warnings']++;
                }
            }
            $ndata[$fname]['failures'][] = $error;
        }
        $dom = new DOMDocument('1.0', 'UTF-8');
        $dom->formatOutput = \true;
        $schema = 'https://raw.githubusercontent.com/junit-team/' . 'junit5/r5.5.1/platform-tests/src/test/resources/jenkins-junit.xsd';
        $suites = $dom->createElement('testsuites');
        $suites->setAttribute('failures', (string) $errors);
        $suites->setAttribute('errors', '0');
        $suites->setAttribute('name', 'psalm');
        $suites->setAttribute('tests', (string) $tests);
        $suites->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
        $suites->setAttribute('xsi:noNamespaceSchemaLocation', $schema);
        $dom->appendChild($suites);
        if (!count($ndata)) {
            $suites->setAttribute('tests', '1');
            $testsuite = $dom->createElement('testsuite');
            $testsuite->setAttribute('name', 'psalm');
            $testsuite->setAttribute('failures', '0');
            $testsuite->setAttribute('errors', '0');
            $testsuite->setAttribute('tests', '1');
            $testcase = $dom->createElement('testcase');
            $testcase->setAttribute('name', 'psalm');
            $testsuite->appendChild($testcase);
            $suites->appendChild($testsuite);
        } else {
            foreach ($ndata as $file => $report) {
                $this->createTestSuite($dom, $suites, $file, $report);
            }
        }
        return $dom->saveXML();
    }
    /**
     * @param  array{
     *         errors: int,
     *         warnings: int,
     *         failures: list<IssueData>
     *         } $report
     */
    private function createTestSuite(DOMDocument $dom, DOMElement $parent, string $file, array $report) : void
    {
        $totalTests = $report['errors'] + $report['warnings'];
        if ($totalTests < 1) {
            $totalTests = 1;
        }
        $testsuite = $dom->createElement('testsuite');
        $testsuite->setAttribute('name', $file);
        $testsuite->setAttribute('failures', (string) $report['errors']);
        $testsuite->setAttribute('errors', '0');
        $testsuite->setAttribute('tests', (string) $totalTests);
        $failuresByType = $this->groupByType($report['failures']);
        foreach ($failuresByType as $type => $data) {
            foreach ($data as $d) {
                $testcase = $dom->createElement('testcase');
                $testcase->setAttribute('name', "{$file}:{$d->line_from}");
                $testcase->setAttribute('classname', $type);
                $testcase->setAttribute('assertions', (string) count($data));
                if ($d->severity === Config::REPORT_ERROR) {
                    $issue = $dom->createElement('failure');
                    $issue->setAttribute('type', $type);
                } else {
                    $issue = $dom->createElement('skipped');
                }
                $issue->nodeValue = $this->dataToOutput($d);
                $testcase->appendChild($issue);
                $testsuite->appendChild($testcase);
            }
        }
        $parent->appendChild($testsuite);
    }
    /**
     * @param  list<IssueData> $failures
     * @return array<string, non-empty-list<IssueData>>
     */
    private function groupByType(array $failures) : array
    {
        $nfailures = [];
        foreach ($failures as $failure) {
            $nfailures[$failure->type][] = $failure;
        }
        return $nfailures;
    }
    private function dataToOutput(IssueData $data) : string
    {
        $ret = 'message: ' . $this->xmlEncode(trim($data->message)) . "\n";
        $ret .= 'type: ' . trim($data->type) . "\n";
        $ret .= 'snippet: ' . $this->xmlEncode(trim($data->snippet)) . "\n";
        $ret .= 'selected_text: ' . $this->xmlEncode(trim($data->selected_text)) . "\n";
        $ret .= 'line: ' . $data->line_from . "\n";
        $ret .= 'column_from: ' . $data->column_from . "\n";
        $ret .= 'column_to: ' . $data->column_to . "\n";
        return $ret;
    }
}
<?php

namespace Psalm\Config;

use Psalm\Config;
use Psalm\Exception\ConfigException;
use SimpleXMLElement;
use function array_filter;
use function array_map;
use function dirname;
use function in_array;
use function scandir;
use function strtolower;
use function substr;
use const SCANDIR_SORT_NONE;
/** @internal */
final class IssueHandler
{
    private string $error_level = Config::REPORT_ERROR;
    /**
     * @var array<ErrorLevelFileFilter>
     */
    private array $custom_levels = [];
    public static function loadFromXMLElement(SimpleXMLElement $e, string $base_dir) : \Psalm\Config\IssueHandler
    {
        $handler = new self();
        if (isset($e['errorLevel'])) {
            $handler->error_level = (string) $e['errorLevel'];
            if (!in_array($handler->error_level, Config::$ERROR_LEVELS, \true)) {
                throw new ConfigException('Unexpected error level ' . $handler->error_level);
            }
        }
        /** @var SimpleXMLElement $error_level */
        foreach ($e->errorLevel as $error_level) {
            $handler->custom_levels[] = \Psalm\Config\ErrorLevelFileFilter::loadFromXMLElement($error_level, $base_dir, \true);
        }
        return $handler;
    }
    public function setCustomLevels(array $customLevels, string $base_dir) : void
    {
        /** @var array $customLevel */
        foreach ($customLevels as $customLevel) {
            $this->custom_levels[] = \Psalm\Config\ErrorLevelFileFilter::loadFromArray($customLevel, $base_dir, \true);
        }
    }
    public function setErrorLevel(string $error_level) : void
    {
        if (!in_array($error_level, Config::$ERROR_LEVELS, \true)) {
            throw new ConfigException('Unexpected error level ' . $error_level);
        }
        $this->error_level = $error_level;
    }
    public function getReportingLevelForFile(string $file_path) : string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allows($file_path)) {
                return $custom_level->getErrorLevel();
            }
        }
        return $this->error_level;
    }
    public function getReportingLevelForClass(string $fq_classlike_name) : ?string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allowsClass($fq_classlike_name)) {
                return $custom_level->getErrorLevel();
            }
        }
        return null;
    }
    public function getReportingLevelForMethod(string $method_id) : ?string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allowsMethod(strtolower($method_id))) {
                return $custom_level->getErrorLevel();
            }
        }
        return null;
    }
    public function getReportingLevelForFunction(string $function_id) : ?string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allowsMethod(strtolower($function_id))) {
                return $custom_level->getErrorLevel();
            }
        }
        return null;
    }
    public function getReportingLevelForArgument(string $function_id) : ?string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allowsMethod(strtolower($function_id))) {
                return $custom_level->getErrorLevel();
            }
        }
        return null;
    }
    public function getReportingLevelForProperty(string $property_id) : ?string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allowsProperty($property_id)) {
                return $custom_level->getErrorLevel();
            }
        }
        return null;
    }
    public function getReportingLevelForClassConstant(string $constant_id) : ?string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allowsClassConstant($constant_id)) {
                return $custom_level->getErrorLevel();
            }
        }
        return null;
    }
    public function getReportingLevelForVariable(string $var_name) : ?string
    {
        foreach ($this->custom_levels as $custom_level) {
            if ($custom_level->allowsVariable($var_name)) {
                return $custom_level->getErrorLevel();
            }
        }
        return null;
    }
    /**
     * @return array<int, string>
     */
    public static function getAllIssueTypes() : array
    {
        return array_filter(array_map(static fn(string $file_name): string => substr($file_name, 0, -4), scandir(dirname(__DIR__) . '/Issue', SCANDIR_SORT_NONE)), static fn(string $issue_name): bool => $issue_name !== '' && $issue_name !== 'MethodIssue' && $issue_name !== 'PropertyIssue' && $issue_name !== 'ClassConstantIssue' && $issue_name !== 'FunctionIssue' && $issue_name !== 'ArgumentIssue' && $issue_name !== 'VariableIssue' && $issue_name !== 'ClassIssue' && $issue_name !== 'CodeIssue' && $issue_name !== 'PsalmInternalError' && $issue_name !== 'ParseError' && $issue_name !== 'PluginIssue' && $issue_name !== 'MixedIssue' && $issue_name !== 'MixedIssueTrait');
    }
}
<?php

namespace Psalm\Config;

use Psalm\Exception\ConfigException;
use SimpleXMLElement;
use function stripos;
use function strpos;
/** @internal */
final class ProjectFileFilter extends \Psalm\Config\FileFilter
{
    private ?\Psalm\Config\ProjectFileFilter $file_filter = null;
    /**
     * @return static
     */
    public static function loadFromXMLElement(SimpleXMLElement $e, string $base_dir, bool $inclusive) : \Psalm\Config\ProjectFileFilter
    {
        $filter = parent::loadFromXMLElement($e, $base_dir, $inclusive);
        if (isset($e->ignoreFiles)) {
            if (!$inclusive) {
                throw new ConfigException('Cannot nest ignoreFiles inside itself');
            }
            /** @var SimpleXMLElement $e->ignoreFiles */
            $filter->file_filter = static::loadFromXMLElement($e->ignoreFiles, $base_dir, \false);
        }
        return $filter;
    }
    public function allows(string $file_name, bool $case_sensitive = \false) : bool
    {
        if ($this->inclusive && $this->file_filter) {
            if (!$this->file_filter->allows($file_name, $case_sensitive)) {
                return \false;
            }
        }
        return parent::allows($file_name, $case_sensitive);
    }
    public function forbids(string $file_name, bool $case_sensitive = \false) : bool
    {
        if ($this->inclusive && $this->file_filter) {
            if (!$this->file_filter->allows($file_name, $case_sensitive)) {
                return \true;
            }
        }
        return \false;
    }
    public function reportTypeStats(string $file_name, bool $case_sensitive = \false) : bool
    {
        foreach ($this->ignore_type_stats as $exclude_dir => $_) {
            if ($case_sensitive) {
                if (strpos($file_name, $exclude_dir) === 0) {
                    return \false;
                }
            } else {
                if (stripos($file_name, $exclude_dir) === 0) {
                    return \false;
                }
            }
        }
        return \true;
    }
    public function useStrictTypes(string $file_name, bool $case_sensitive = \false) : bool
    {
        foreach ($this->declare_strict_types as $exclude_dir => $_) {
            if ($case_sensitive) {
                if (strpos($file_name, $exclude_dir) === 0) {
                    return \true;
                }
            } else {
                if (stripos($file_name, $exclude_dir) === 0) {
                    return \true;
                }
            }
        }
        return \false;
    }
}
<?php

namespace Psalm\Config;

use JsonException;
use Psalm\Config;
use Psalm\Exception\ConfigCreationException;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Composer;
use function array_filter;
use function array_keys;
use function array_merge;
use function array_shift;
use function array_sum;
use function array_unique;
use function array_values;
use function count;
use function explode;
use function file_exists;
use function file_get_contents;
use function glob;
use function implode;
use function is_array;
use function is_dir;
use function json_decode;
use function ksort;
use function max;
use function preg_replace;
use function sort;
use function str_replace;
use function strpos;
use const DIRECTORY_SEPARATOR;
use const GLOB_NOSORT;
use const JSON_THROW_ON_ERROR;
/** @internal */
final class Creator
{
    private const TEMPLATE = '<?xml version="1.0"?>
<psalm
    errorLevel="1"
    resolveFromConfigFile="true"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://getpsalm.org/schema/config"
    xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
    findUnusedBaselineEntry="true"
>
    <projectFiles>
        <directory name="src" />
        <ignoreFiles>
            <directory name="vendor" />
        </ignoreFiles>
    </projectFiles>
</psalm>
';
    /**
     * @return non-empty-string
     */
    public static function getContents(string $current_dir, ?string $suggested_dir, int $level, string $vendor_dir) : string
    {
        $paths = self::getPaths($current_dir, $suggested_dir);
        $template = str_replace('<directory name="src" />', implode("\n        ", $paths), self::TEMPLATE);
        if (is_dir($current_dir . DIRECTORY_SEPARATOR . $vendor_dir)) {
            $template = str_replace('<directory name="vendor" />', '<directory name="' . $vendor_dir . '" />', $template);
        } else {
            $template = str_replace('<directory name="vendor" />', '', $template);
        }
        /** @var non-empty-string */
        return str_replace('errorLevel="1"', 'errorLevel="' . $level . '"', $template);
    }
    public static function createBareConfig(string $current_dir, ?string $suggested_dir, string $vendor_dir) : Config
    {
        $config_contents = self::getContents($current_dir, $suggested_dir, 1, $vendor_dir);
        return Config::loadFromXML($current_dir, $config_contents);
    }
    /**
     * @param  array<IssueData>  $issues
     */
    public static function getLevel(array $issues, int $counted_types) : int
    {
        if ($counted_types === 0) {
            $counted_types = 1;
        }
        $issues_at_level = [];
        foreach ($issues as $issue) {
            $issue_type = $issue->type;
            $issue_level = $issue->error_level;
            if ($issue_level < 1) {
                continue;
            }
            // exclude some directories that are probably ignorable
            if (strpos($issue->file_path, 'vendor') || strpos($issue->file_path, 'stub')) {
                continue;
            }
            if (!isset($issues_at_level[$issue_level][$issue_type])) {
                $issues_at_level[$issue_level][$issue_type] = 0;
            }
            $issues_at_level[$issue_level][$issue_type] += 100 / $counted_types;
        }
        foreach ($issues_at_level as $level => $issues) {
            ksort($issues);
            // remove any issues where < 0.1% of expressions are affected
            $filtered_issues = array_filter($issues, static fn($amount): bool => $amount > 0.1);
            if (array_sum($filtered_issues) > 0.5) {
                $issues_at_level[$level] = $filtered_issues;
            } else {
                unset($issues_at_level[$level]);
            }
        }
        if (!$issues_at_level) {
            return 1;
        }
        if (count($issues_at_level) === 1) {
            return array_keys($issues_at_level)[0] + 1;
        }
        return max(...array_keys($issues_at_level)) + 1;
    }
    /**
     * @return non-empty-list<string>
     */
    public static function getPaths(string $current_dir, ?string $suggested_dir) : array
    {
        $replacements = [];
        if ($suggested_dir) {
            if (is_dir($current_dir . DIRECTORY_SEPARATOR . $suggested_dir)) {
                $replacements[] = '<directory name="' . $suggested_dir . '" />';
            } else {
                $bad_dir_path = $current_dir . DIRECTORY_SEPARATOR . $suggested_dir;
                throw new ConfigCreationException('The given path "' . $bad_dir_path . '" does not appear to be a directory');
            }
        } elseif (is_dir($current_dir . DIRECTORY_SEPARATOR . 'src')) {
            $replacements[] = '<directory name="src" />';
        } else {
            $composer_json_location = Composer::getJsonFilePath($current_dir);
            if (!file_exists($composer_json_location)) {
                throw new ConfigCreationException('Problem during source autodiscovery - could not find composer.json during initialization. ' . 'If your project doesn\'t use Composer autoloader you will need to run ' . '`psalm --init source_folder`, e.g. `psalm --init library` if your source files ' . 'reside in `library` folder');
            }
            try {
                $composer_json = json_decode(file_get_contents($composer_json_location), \true, 512, JSON_THROW_ON_ERROR);
            } catch (JsonException $e) {
                throw new ConfigCreationException('Invalid composer.json at ' . $composer_json_location . ': ' . $e->getMessage());
            }
            if (!$composer_json) {
                throw new ConfigCreationException('Invalid composer.json at ' . $composer_json_location);
            }
            if (!is_array($composer_json)) {
                throw new ConfigCreationException('Invalid composer.json at ' . $composer_json_location);
            }
            $replacements = self::getPsr4Or0Paths($current_dir, $composer_json);
            if (!$replacements) {
                throw new ConfigCreationException('Could not located any PSR-0 or PSR-4-compatible paths in ' . $composer_json_location);
            }
        }
        return $replacements;
    }
    /**
     * @return list<string>
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedArgument
     */
    private static function getPsr4Or0Paths(string $current_dir, array $composer_json) : array
    {
        $psr_paths = array_merge($composer_json['autoload']['psr-4'] ?? [], $composer_json['autoload']['psr-0'] ?? []);
        if (!$psr_paths) {
            return self::guessPhpFileDirs($current_dir);
        }
        $nodes = [];
        foreach ($psr_paths as $paths) {
            if (!is_array($paths)) {
                $paths = [$paths];
            }
            foreach ($paths as $path) {
                if ($path === '') {
                    $nodes = [...$nodes, ...self::guessPhpFileDirs($current_dir)];
                    continue;
                }
                $path = preg_replace('@[/\\\\]$@', '', $path, 1);
                if ($path !== 'tests') {
                    $nodes[] = '<directory name="' . $path . '" />';
                }
            }
        }
        $nodes = array_unique($nodes);
        sort($nodes);
        return $nodes;
    }
    /**
     * @return list<string>
     */
    private static function guessPhpFileDirs(string $current_dir) : array
    {
        $nodes = [];
        /** @var string[] */
        $php_files = array_merge(glob($current_dir . DIRECTORY_SEPARATOR . '*.php', GLOB_NOSORT), glob($current_dir . DIRECTORY_SEPARATOR . '**/*.php', GLOB_NOSORT), glob($current_dir . DIRECTORY_SEPARATOR . '**/**/*.php', GLOB_NOSORT));
        foreach ($php_files as $php_file) {
            $php_file = str_replace($current_dir . DIRECTORY_SEPARATOR, '', $php_file);
            $parts = explode(DIRECTORY_SEPARATOR, $php_file);
            if (!$parts[0]) {
                array_shift($parts);
            }
            if ($parts[0] === 'vendor' || $parts[0] === 'tests') {
                continue;
            }
            if (count($parts) === 1) {
                $nodes[] = '<file name="' . $php_file . '" />';
            } else {
                $nodes[] = '<directory name="' . $parts[0] . '" />';
            }
        }
        return array_values(array_unique($nodes));
    }
}
<?php

namespace Psalm\Config;

use FilesystemIterator;
use Psalm\Exception\ConfigException;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SimpleXMLElement;
use function array_filter;
use function array_map;
use function explode;
use function glob;
use function in_array;
use function is_dir;
use function is_iterable;
use function preg_match;
use function readlink;
use function realpath;
use function restore_error_handler;
use function rtrim;
use function set_error_handler;
use function str_replace;
use function stripos;
use function strpos;
use function strtolower;
use const DIRECTORY_SEPARATOR;
use const E_WARNING;
use const GLOB_NOSORT;
use const GLOB_ONLYDIR;
/**
 * @psalm-consistent-constructor
 */
class FileFilter
{
    /**
     * @var array<string>
     */
    protected $directories = [];
    /**
     * @var array<string>
     */
    protected $files = [];
    /**
     * @var array<string>
     */
    protected $fq_classlike_names = [];
    /**
     * @var array<string>
     */
    protected $fq_classlike_patterns = [];
    /**
     * @var array<string>
     */
    protected $method_ids = [];
    /**
     * @var array<string>
     */
    protected $property_ids = [];
    /**
     * @var array<string>
     */
    protected $class_constant_ids = [];
    /**
     * @var array<string>
     */
    protected $var_names = [];
    /**
     * @var array<string>
     */
    protected $files_lowercase = [];
    /**
     * @var bool
     */
    protected $inclusive;
    /**
     * @var array<string, bool>
     */
    protected $ignore_type_stats = [];
    /**
     * @var array<string, bool>
     */
    protected $declare_strict_types = [];
    public function __construct(bool $inclusive)
    {
        $this->inclusive = $inclusive;
    }
    /**
     * @return static
     */
    public static function loadFromArray(array $config, string $base_dir, bool $inclusive)
    {
        $allow_missing_files = ($config['allowMissingFiles'] ?? \false) === \true;
        $filter = new static($inclusive);
        if (isset($config['directory']) && is_iterable($config['directory'])) {
            /** @var array $directory */
            foreach ($config['directory'] as $directory) {
                $directory_path = (string) ($directory['name'] ?? '');
                $ignore_type_stats = (bool) ($directory['ignoreTypeStats'] ?? \false);
                $resolve_symlinks = (bool) ($directory['resolveSymlinks'] ?? \false);
                $declare_strict_types = (bool) ($directory['useStrictTypes'] ?? \false);
                if ($directory_path[0] === '/' && DIRECTORY_SEPARATOR === '/') {
                    $prospective_directory_path = $directory_path;
                } else {
                    $prospective_directory_path = $base_dir . DIRECTORY_SEPARATOR . $directory_path;
                }
                if (strpos($prospective_directory_path, '*') !== \false) {
                    $globs = array_map('realpath', glob($prospective_directory_path, GLOB_ONLYDIR));
                    if (empty($globs)) {
                        if ($allow_missing_files) {
                            continue;
                        }
                        throw new ConfigException('Could not resolve config path to ' . $base_dir . DIRECTORY_SEPARATOR . $directory_path);
                    }
                    foreach ($globs as $glob_index => $directory_path) {
                        if (!$directory_path) {
                            if ($allow_missing_files) {
                                continue;
                            }
                            throw new ConfigException('Could not resolve config path to ' . $base_dir . DIRECTORY_SEPARATOR . $directory_path . ':' . $glob_index);
                        }
                        if ($ignore_type_stats && $filter instanceof \Psalm\Config\ProjectFileFilter) {
                            $filter->ignore_type_stats[$directory_path] = \true;
                        }
                        if ($declare_strict_types && $filter instanceof \Psalm\Config\ProjectFileFilter) {
                            $filter->declare_strict_types[$directory_path] = \true;
                        }
                        $filter->addDirectory($directory_path);
                    }
                    continue;
                }
                $directory_path = realpath($prospective_directory_path);
                if (!$directory_path) {
                    if ($allow_missing_files) {
                        continue;
                    }
                    throw new ConfigException('Could not resolve config path to ' . $prospective_directory_path);
                }
                if (!is_dir($directory_path)) {
                    throw new ConfigException($base_dir . DIRECTORY_SEPARATOR . $directory_path . ' is not a directory');
                }
                if ($resolve_symlinks) {
                    /** @var RecursiveDirectoryIterator */
                    $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory_path, FilesystemIterator::SKIP_DOTS));
                    $iterator->rewind();
                    while ($iterator->valid()) {
                        if ($iterator->isLink()) {
                            $linked_path = readlink($iterator->getPathname());
                            if (stripos($linked_path, $directory_path) !== 0) {
                                if ($ignore_type_stats && $filter instanceof \Psalm\Config\ProjectFileFilter) {
                                    $filter->ignore_type_stats[$directory_path] = \true;
                                }
                                if ($declare_strict_types && $filter instanceof \Psalm\Config\ProjectFileFilter) {
                                    $filter->declare_strict_types[$directory_path] = \true;
                                }
                                if (is_dir($linked_path)) {
                                    $filter->addDirectory($linked_path);
                                }
                            }
                        }
                        $iterator->next();
                    }
                    $iterator->next();
                }
                if ($ignore_type_stats && $filter instanceof \Psalm\Config\ProjectFileFilter) {
                    $filter->ignore_type_stats[$directory_path] = \true;
                }
                if ($declare_strict_types && $filter instanceof \Psalm\Config\ProjectFileFilter) {
                    $filter->declare_strict_types[$directory_path] = \true;
                }
                $filter->addDirectory($directory_path);
            }
        }
        if (isset($config['file']) && is_iterable($config['file'])) {
            /** @var array $file */
            foreach ($config['file'] as $file) {
                $file_path = (string) ($file['name'] ?? '');
                if ($file_path[0] === '/' && DIRECTORY_SEPARATOR === '/') {
                    $prospective_file_path = $file_path;
                } else {
                    $prospective_file_path = $base_dir . DIRECTORY_SEPARATOR . $file_path;
                }
                if (strpos($prospective_file_path, '*') !== \false) {
                    $globs = array_map('realpath', array_filter(glob($prospective_file_path, GLOB_NOSORT), 'file_exists'));
                    if (empty($globs)) {
                        if ($allow_missing_files) {
                            continue;
                        }
                        throw new ConfigException('Could not resolve config path to ' . $base_dir . DIRECTORY_SEPARATOR . $file_path);
                    }
                    foreach ($globs as $glob_index => $file_path) {
                        if (!$file_path && !$allow_missing_files) {
                            throw new ConfigException('Could not resolve config path to ' . $base_dir . DIRECTORY_SEPARATOR . $file_path . ':' . $glob_index);
                        }
                        $filter->addFile($file_path);
                    }
                    continue;
                }
                $file_path = realpath($prospective_file_path);
                if (!$file_path && !$allow_missing_files) {
                    throw new ConfigException('Could not resolve config path to ' . $prospective_file_path);
                }
                $filter->addFile($file_path);
            }
        }
        if (isset($config['referencedClass']) && is_iterable($config['referencedClass'])) {
            /** @var array $referenced_class */
            foreach ($config['referencedClass'] as $referenced_class) {
                $class_name = strtolower((string) ($referenced_class['name'] ?? ''));
                if (strpos($class_name, '*') !== \false) {
                    $regex = '/' . str_replace('*', '.*', str_replace('\\', '\\\\', $class_name)) . '/i';
                    $filter->fq_classlike_patterns[] = $regex;
                } else {
                    $filter->fq_classlike_names[] = $class_name;
                }
            }
        }
        if (isset($config['referencedMethod']) && is_iterable($config['referencedMethod'])) {
            /** @var array $referenced_method */
            foreach ($config['referencedMethod'] as $referenced_method) {
                $method_id = (string) ($referenced_method['name'] ?? '');
                if (!preg_match('/^[^:]+::[^:]+$/', $method_id) && !static::isRegularExpression($method_id)) {
                    throw new ConfigException('Invalid referencedMethod ' . $method_id);
                }
                $filter->method_ids[] = strtolower($method_id);
            }
        }
        if (isset($config['referencedFunction']) && is_iterable($config['referencedFunction'])) {
            /** @var array $referenced_function */
            foreach ($config['referencedFunction'] as $referenced_function) {
                $filter->method_ids[] = strtolower((string) ($referenced_function['name'] ?? ''));
            }
        }
        if (isset($config['referencedProperty']) && is_iterable($config['referencedProperty'])) {
            /** @var array $referenced_property */
            foreach ($config['referencedProperty'] as $referenced_property) {
                $filter->property_ids[] = strtolower((string) ($referenced_property['name'] ?? ''));
            }
        }
        if (isset($config['referencedConstant']) && is_iterable($config['referencedConstant'])) {
            /** @var array $referenced_constant */
            foreach ($config['referencedConstant'] as $referenced_constant) {
                $filter->class_constant_ids[] = strtolower((string) ($referenced_constant['name'] ?? ''));
            }
        }
        if (isset($config['referencedVariable']) && is_iterable($config['referencedVariable'])) {
            /** @var array $referenced_variable */
            foreach ($config['referencedVariable'] as $referenced_variable) {
                $filter->var_names[] = strtolower((string) ($referenced_variable['name'] ?? ''));
            }
        }
        return $filter;
    }
    /**
     * @return static
     */
    public static function loadFromXMLElement(SimpleXMLElement $e, string $base_dir, bool $inclusive)
    {
        $config = [];
        $config['allowMissingFiles'] = (string) $e['allowMissingFiles'] === 'true';
        if ($e->directory) {
            $config['directory'] = [];
            /** @var SimpleXMLElement $directory */
            foreach ($e->directory as $directory) {
                $config['directory'][] = ['name' => (string) $directory['name'], 'ignoreTypeStats' => strtolower((string) ($directory['ignoreTypeStats'] ?? '')) === 'true', 'resolveSymlinks' => strtolower((string) ($directory['resolveSymlinks'] ?? '')) === 'true', 'useStrictTypes' => strtolower((string) ($directory['useStrictTypes'] ?? '')) === 'true'];
            }
        }
        if ($e->file) {
            $config['file'] = [];
            /** @var SimpleXMLElement $file */
            foreach ($e->file as $file) {
                $config['file'][]['name'] = (string) $file['name'];
            }
        }
        if ($e->referencedClass) {
            $config['referencedClass'] = [];
            /** @var SimpleXMLElement $referenced_class */
            foreach ($e->referencedClass as $referenced_class) {
                $config['referencedClass'][]['name'] = strtolower((string) $referenced_class['name']);
            }
        }
        if ($e->referencedMethod) {
            $config['referencedMethod'] = [];
            /** @var SimpleXMLElement $referenced_method */
            foreach ($e->referencedMethod as $referenced_method) {
                $config['referencedMethod'][]['name'] = (string) $referenced_method['name'];
            }
        }
        if ($e->referencedFunction) {
            $config['referencedFunction'] = [];
            /** @var SimpleXMLElement $referenced_function */
            foreach ($e->referencedFunction as $referenced_function) {
                $config['referencedFunction'][]['name'] = strtolower((string) $referenced_function['name']);
            }
        }
        if ($e->referencedProperty) {
            $config['referencedProperty'] = [];
            /** @var SimpleXMLElement $referenced_property */
            foreach ($e->referencedProperty as $referenced_property) {
                $config['referencedProperty'][]['name'] = strtolower((string) $referenced_property['name']);
            }
        }
        if ($e->referencedConstant) {
            $config['referencedConstant'] = [];
            /** @var SimpleXMLElement $referenced_constant */
            foreach ($e->referencedConstant as $referenced_constant) {
                $config['referencedConstant'][]['name'] = strtolower((string) $referenced_constant['name']);
            }
        }
        if ($e->referencedVariable) {
            $config['referencedVariable'] = [];
            /** @var SimpleXMLElement $referenced_variable */
            foreach ($e->referencedVariable as $referenced_variable) {
                $config['referencedVariable'][]['name'] = strtolower((string) $referenced_variable['name']);
            }
        }
        return self::loadFromArray($config, $base_dir, $inclusive);
    }
    private static function isRegularExpression(string $string) : bool
    {
        set_error_handler(static fn(): bool => \true, E_WARNING);
        $is_regexp = preg_match($string, '') !== \false;
        restore_error_handler();
        return $is_regexp;
    }
    /**
     * @psalm-pure
     */
    protected static function slashify(string $str) : string
    {
        return rtrim($str, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
    }
    public function allows(string $file_name, bool $case_sensitive = \false) : bool
    {
        if ($this->inclusive) {
            foreach ($this->directories as $include_dir) {
                if ($case_sensitive) {
                    if (strpos($file_name, $include_dir) === 0) {
                        return \true;
                    }
                } else {
                    if (stripos($file_name, $include_dir) === 0) {
                        return \true;
                    }
                }
            }
            if ($case_sensitive) {
                if (in_array($file_name, $this->files, \true)) {
                    return \true;
                }
            } else {
                if (in_array(strtolower($file_name), $this->files_lowercase, \true)) {
                    return \true;
                }
            }
            return \false;
        }
        // exclusive
        foreach ($this->directories as $exclude_dir) {
            if ($case_sensitive) {
                if (strpos($file_name, $exclude_dir) === 0) {
                    return \false;
                }
            } else {
                if (stripos($file_name, $exclude_dir) === 0) {
                    return \false;
                }
            }
        }
        if ($case_sensitive) {
            if (in_array($file_name, $this->files, \true)) {
                return \false;
            }
        } else {
            if (in_array(strtolower($file_name), $this->files_lowercase, \true)) {
                return \false;
            }
        }
        return \true;
    }
    public function allowsClass(string $fq_classlike_name) : bool
    {
        if ($this->fq_classlike_patterns) {
            foreach ($this->fq_classlike_patterns as $pattern) {
                if (preg_match($pattern, $fq_classlike_name)) {
                    return \true;
                }
            }
        }
        return in_array(strtolower($fq_classlike_name), $this->fq_classlike_names, \true);
    }
    public function allowsMethod(string $method_id) : bool
    {
        if (!$this->method_ids) {
            return \false;
        }
        if (preg_match('/^[^:]+::[^:]+$/', $method_id)) {
            $method_stub = '*::' . explode('::', $method_id)[1];
            foreach ($this->method_ids as $config_method_id) {
                if ($config_method_id === $method_id) {
                    return \true;
                }
                if ($config_method_id === $method_stub) {
                    return \true;
                }
                if ($config_method_id[0] === '/' && preg_match($config_method_id, $method_id)) {
                    return \true;
                }
            }
            return \false;
        }
        return in_array($method_id, $this->method_ids, \true);
    }
    public function allowsProperty(string $property_id) : bool
    {
        return in_array(strtolower($property_id), $this->property_ids, \true);
    }
    public function allowsClassConstant(string $constant_id) : bool
    {
        return in_array(strtolower($constant_id), $this->class_constant_ids, \true);
    }
    public function allowsVariable(string $var_name) : bool
    {
        return in_array(strtolower($var_name), $this->var_names, \true);
    }
    /**
     * @return array<string>
     */
    public function getDirectories() : array
    {
        return $this->directories;
    }
    /**
     * @return array<string>
     */
    public function getFiles() : array
    {
        return $this->files;
    }
    public function addFile(string $file_name) : void
    {
        $this->files[] = $file_name;
        $this->files_lowercase[] = strtolower($file_name);
    }
    public function addDirectory(string $dir_name) : void
    {
        $this->directories[] = self::slashify($dir_name);
    }
}
<?php

namespace Psalm\Config;

/** @internal */
final class TaintAnalysisFileFilter extends \Psalm\Config\FileFilter
{
}
<?php

namespace Psalm\Config;

use Psalm\Config;
use Psalm\Exception\ConfigException;
use SimpleXMLElement;
use function in_array;
/** @internal */
final class ErrorLevelFileFilter extends \Psalm\Config\FileFilter
{
    private string $error_level = '';
    /**
     * @return static
     */
    public static function loadFromArray(array $config, string $base_dir, bool $inclusive) : \Psalm\Config\ErrorLevelFileFilter
    {
        $filter = parent::loadFromArray($config, $base_dir, $inclusive);
        if (isset($config['type'])) {
            $filter->error_level = (string) $config['type'];
            if (!in_array($filter->error_level, Config::$ERROR_LEVELS, \true)) {
                throw new ConfigException('Unexpected error level ' . $filter->error_level);
            }
        } else {
            throw new ConfigException('<type> element expects a level');
        }
        return $filter;
    }
    /**
     * @return static
     */
    public static function loadFromXMLElement(SimpleXMLElement $e, string $base_dir, bool $inclusive) : \Psalm\Config\ErrorLevelFileFilter
    {
        $filter = parent::loadFromXMLElement($e, $base_dir, $inclusive);
        if (isset($e['type'])) {
            $filter->error_level = (string) $e['type'];
            if (!in_array($filter->error_level, Config::$ERROR_LEVELS, \true)) {
                throw new ConfigException('Unexpected error level ' . $filter->error_level);
            }
        } else {
            throw new ConfigException('<type> element expects a level');
        }
        return $filter;
    }
    public function getErrorLevel() : string
    {
        return $this->error_level;
    }
}
<?php

namespace Psalm\Progress;

use function error_reporting;
use function function_exists;
use function fwrite;
use function sapi_windows_cp_is_utf8;
use function stripos;
use const E_ERROR;
use const PHP_EOL;
use const PHP_OS;
use const STDERR;
abstract class Progress
{
    public function setErrorReporting() : void
    {
        error_reporting(E_ERROR);
    }
    public function debug(string $message) : void
    {
    }
    public function startScanningFiles() : void
    {
    }
    public function startAnalyzingFiles() : void
    {
    }
    public function startAlteringFiles() : void
    {
    }
    public function alterFileDone(string $file_name) : void
    {
    }
    public function start(int $number_of_tasks) : void
    {
    }
    public function taskDone(int $level) : void
    {
    }
    public function finish() : void
    {
    }
    public function write(string $message) : void
    {
        fwrite(STDERR, $message);
    }
    public function warning(string $message) : void
    {
        $this->write('Warning: ' . $message . PHP_EOL);
    }
    protected static function doesTerminalSupportUtf8() : bool
    {
        if (stripos(PHP_OS, 'WIN') === 0) {
            if (!function_exists('sapi_windows_cp_is_utf8') || !sapi_windows_cp_is_utf8()) {
                return \false;
            }
        }
        return \true;
    }
}
<?php

namespace Psalm\Progress;

use function max;
use function microtime;
use function str_repeat;
use function strlen;
class DefaultProgress extends \Psalm\Progress\LongProgress
{
    private const TOO_MANY_FILES = 1500;
    // Update the progress bar at most once per 0.1 seconds.
    // This reduces flickering and reduces the amount of time spent writing to STDERR and updating the terminal.
    private const PROGRESS_BAR_SAMPLE_INTERVAL = 0.1;
    /** @var float the last time when the progress bar UI was updated */
    private float $previous_update_time = 0.0;
    public function taskDone(int $level) : void
    {
        if ($this->number_of_tasks > self::TOO_MANY_FILES) {
            ++$this->progress;
            // Source for rate limiting:
            // https://github.com/phan/phan/blob/9a788581ee1a4e1c35bebf89c435fd8a238c1d17/src/Phan/CLI.php
            $time = microtime(\true);
            // If not enough time has elapsed, then don't update the progress bar.
            // Making the update frequency based on time (instead of the number of files)
            // prevents the terminal from rapidly flickering while processing small/empty files,
            // and reduces the time spent writing to stderr.
            if ($time - $this->previous_update_time < self::PROGRESS_BAR_SAMPLE_INTERVAL) {
                // Make sure to output the section for 100% completion regardless of limits, to avoid confusion.
                if ($this->progress !== $this->number_of_tasks) {
                    return;
                }
            }
            $this->previous_update_time = $time;
            $inner_progress = self::renderInnerProgressBar(self::NUMBER_OF_COLUMNS, $this->progress / $this->number_of_tasks);
            $this->write($inner_progress . ' ' . $this->getOverview() . "\r");
        } else {
            parent::taskDone($level);
        }
    }
    /**
     * Fully stolen from
     * https://github.com/phan/phan/blob/d61a624b1384ea220f39927d53fd656a65a75fac/src/Phan/CLI.php
     * Renders a unicode progress bar that goes from light (left) to dark (right)
     * The length in the console is the positive integer $length
     *
     * @see https://en.wikipedia.org/wiki/Block_Elements
     */
    private static function renderInnerProgressBar(int $length, float $p) : string
    {
        $current_float = $p * $length;
        $current = (int) $current_float;
        $rest = max($length - $current, 0);
        if (!self::doesTerminalSupportUtf8()) {
            // Show a progress bar of "XXXX>------" in Windows when utf-8 is unsupported.
            $progress_bar = str_repeat('X', $current);
            $delta = $current_float - $current;
            if ($delta > 0.5) {
                $progress_bar .= '>' . str_repeat('-', $rest - 1);
            } else {
                $progress_bar .= str_repeat('-', $rest);
            }
            return $progress_bar;
        }
        // The left-most characters are "Light shade"
        $progress_bar = str_repeat("█", $current);
        $delta = $current_float - $current;
        if ($delta > 3.0 / 4) {
            $progress_bar .= "▊" . str_repeat("░", $rest - 1);
        } elseif ($delta > 2.0 / 4) {
            $progress_bar .= "▌" . str_repeat("░", $rest - 1);
        } elseif ($delta > 1.0 / 4) {
            $progress_bar .= "▎" . str_repeat("░", $rest - 1);
        } else {
            $progress_bar .= str_repeat("░", $rest);
        }
        return $progress_bar;
    }
    public function finish() : void
    {
        if ($this->number_of_tasks > self::TOO_MANY_FILES) {
            $this->write(str_repeat(' ', self::NUMBER_OF_COLUMNS + strlen($this->getOverview()) + 1) . "\r");
        } else {
            parent::finish();
        }
    }
}
<?php

namespace Psalm\Progress;

use LogicException;
use function floor;
use function sprintf;
use function str_repeat;
use function strlen;
use const PHP_EOL;
class LongProgress extends \Psalm\Progress\Progress
{
    public const NUMBER_OF_COLUMNS = 60;
    /** @var int|null */
    protected $number_of_tasks;
    /** @var int */
    protected $progress = 0;
    /** @var bool */
    protected $print_errors = \false;
    /** @var bool */
    protected $print_infos = \false;
    public function __construct(bool $print_errors = \true, bool $print_infos = \true)
    {
        $this->print_errors = $print_errors;
        $this->print_infos = $print_infos;
    }
    public function startScanningFiles() : void
    {
        $this->write('Scanning files...' . "\n");
    }
    public function startAnalyzingFiles() : void
    {
        $this->write('Analyzing files...' . "\n\n");
    }
    public function startAlteringFiles() : void
    {
        $this->write('Altering files...' . "\n");
    }
    public function alterFileDone(string $file_name) : void
    {
        $this->write('Altered ' . $file_name . "\n");
    }
    public function start(int $number_of_tasks) : void
    {
        $this->number_of_tasks = $number_of_tasks;
        $this->progress = 0;
    }
    public function taskDone(int $level) : void
    {
        if ($level === 0 || $level === 1 && !$this->print_infos || !$this->print_errors) {
            $this->write(self::doesTerminalSupportUtf8() ? '░' : '_');
        } elseif ($level === 1) {
            $this->write('I');
        } else {
            $this->write('E');
        }
        ++$this->progress;
        if ($this->progress % self::NUMBER_OF_COLUMNS !== 0) {
            return;
        }
        $this->printOverview();
        $this->write(PHP_EOL);
    }
    public function finish() : void
    {
        $this->write(PHP_EOL);
    }
    protected function getOverview() : string
    {
        if ($this->number_of_tasks === null) {
            throw new LogicException('Progress::start() should be called before Progress::startDone()');
        }
        $leadingSpaces = 1 + strlen((string) $this->number_of_tasks) - strlen((string) $this->progress);
        // Don't show 100% unless this is the last line of the progress bar.
        $percentage = floor($this->progress / $this->number_of_tasks * 100);
        return sprintf('%s%s / %s (%s%%)', str_repeat(' ', $leadingSpaces), $this->progress, $this->number_of_tasks, $percentage);
    }
    private function printOverview() : void
    {
        $this->write($this->getOverview());
    }
}
<?php

namespace Psalm\Progress;

final class VoidProgress extends \Psalm\Progress\Progress
{
    public function write(string $message) : void
    {
    }
}
<?php

namespace Psalm\Progress;

use function error_reporting;
use const E_ALL;
final class DebugProgress extends \Psalm\Progress\Progress
{
    public function setErrorReporting() : void
    {
        error_reporting(E_ALL);
    }
    public function debug(string $message) : void
    {
        $this->write($message);
    }
    public function startScanningFiles() : void
    {
        $this->write('Scanning files...' . "\n");
    }
    public function startAnalyzingFiles() : void
    {
        $this->write('Analyzing files...' . "\n");
    }
    public function startAlteringFiles() : void
    {
        $this->write('Updating files...' . "\n");
    }
    public function alterFileDone(string $file_name) : void
    {
        $this->write('Altered ' . $file_name . "\n");
    }
}
<?php

namespace Psalm\Issue;

final class InvalidOperand extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 58;
}
<?php

namespace Psalm\Issue;

final class TaintedUnserialize extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 250;
}
<?php

namespace Psalm\Issue;

final class UndefinedInterfaceMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 181;
}
<?php

namespace Psalm\Issue;

final class MixedReturnStatement extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 138;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class MixedArrayTypeCoercion extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 195;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 78;
}
<?php

namespace Psalm\Issue;

final class InvalidArrayOffset extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 115;
}
<?php

namespace Psalm\Issue;

final class UndefinedDocblockClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 200;
}
<?php

namespace Psalm\Issue;

final class MissingReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 50;
}
<?php

namespace Psalm\Issue;

final class MismatchingDocblockPropertyType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 264;
}
<?php

namespace Psalm\Issue;

final class DeprecatedProperty extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 99;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullIterator extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 97;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
final class PossiblyUnusedMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 87;
    public function __construct(string $message, CodeLocation $code_location, string $method_id)
    {
        parent::__construct($message, $code_location, $method_id);
        $this->dupe_key = strtolower($method_id);
    }
}
<?php

namespace Psalm\Issue;

final class RedundantFunctionCallGivenDocblockType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 281;
}
<?php

namespace Psalm\Issue;

final class DuplicateConstant extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 302;
}
<?php

namespace Psalm\Issue;

final class MismatchingDocblockParamType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 141;
}
<?php

namespace Psalm\Issue;

final class InvalidEnumCaseValue extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 278;
}
<?php

namespace Psalm\Issue;

final class TraitMethodSignatureMismatch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 192;
}
<?php

namespace Psalm\Issue;

final class UnimplementedAbstractMethod extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 101;
}
<?php

namespace Psalm\Issue;

/**
 * This is different from PossiblyNullReference, as PHP throws a notice (vs the possibility of a fatal error with a null
 * reference)
 */
final class PossiblyNullPropertyFetch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 82;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
abstract class FunctionIssue extends \Psalm\Issue\CodeIssue
{
    /**
     * @var string
     */
    public $function_id;
    public function __construct(string $message, CodeLocation $code_location, string $function_id)
    {
        parent::__construct($message, $code_location);
        $this->function_id = strtolower($function_id);
    }
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidMethodCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 113;
}
<?php

namespace Psalm\Issue;

final class MismatchingDocblockReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 142;
}
<?php

namespace Psalm\Issue;

final class ImpureVariable extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 235;
}
<?php

namespace Psalm\Issue;

use function array_pop;
use function count;
use function implode;
use function reset;
final class InternalClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 174;
    /** @param non-empty-list<non-empty-string> $words */
    public static function listToPhrase(array $words) : string
    {
        if (count($words) === 1) {
            return reset($words);
        }
        if (count($words) === 2) {
            return implode(" and ", $words);
        }
        $last_word = array_pop($words);
        $phrase = implode(", ", $words);
        $phrase = "{$phrase}, and {$last_word}";
        return $phrase;
    }
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
final class MixedArgumentTypeCoercion extends \Psalm\Issue\ArgumentIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 194;
    use \Psalm\Issue\MixedIssueTrait;
    public function __construct(string $message, CodeLocation $code_location, ?string $function_id = null, ?CodeLocation $origin_location = null)
    {
        $this->code_location = $code_location;
        $this->message = $message;
        $this->function_id = $function_id ? strtolower($function_id) : null;
        $this->origin_location = $origin_location;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Issue;

final class NonInvariantDocblockPropertyType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 267;
}
<?php

namespace Psalm\Issue;

final class ForbiddenCode extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 2;
}
<?php

namespace Psalm\Issue;

final class TaintedCustom extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 249;
}
<?php

namespace Psalm\Issue;

final class TaintedInclude extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 251;
}
<?php

namespace Psalm\Issue;

final class TaintedCookie extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 257;
}
<?php

namespace Psalm\Issue;

final class InvalidReturnStatement extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 128;
}
<?php

namespace Psalm\Issue;

final class ParseError extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 173;
}
<?php

namespace Psalm\Issue;

final class NoEnumProperties extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 301;
}
<?php

namespace Psalm\Issue;

final class MixedStringOffsetAssignment extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 35;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class InvalidPropertyFetch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 29;
}
<?php

namespace Psalm\Issue;

final class PossiblyUndefinedIntArrayOffset extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 215;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullPropertyAssignmentValue extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 148;
}
<?php

namespace Psalm\Issue;

final class DuplicateEnumCase extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 277;
}
<?php

namespace Psalm\Issue;

final class InvalidTemplateParam extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 183;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
final class UnusedMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 76;
    public function __construct(string $message, CodeLocation $code_location, string $method_id)
    {
        parent::__construct($message, $code_location, $method_id);
        $this->dupe_key = strtolower($method_id);
    }
}
<?php

namespace Psalm\Issue;

final class PossiblyUndefinedVariable extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 18;
}
<?php

namespace Psalm\Issue;

final class DeprecatedConstant extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 170;
}
<?php

namespace Psalm\Issue;

final class PossiblyUndefinedStringArrayOffset extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 216;
}
<?php

namespace Psalm\Issue;

final class MissingTemplateParam extends \Psalm\Issue\CodeIssue
{
    public const SHORTCODE = 182;
}
<?php

namespace Psalm\Issue;

final class ContinueOutsideLoop extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 43;
}
<?php

namespace Psalm\Issue;

final class ImpureByReferenceAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 220;
}
<?php

namespace Psalm\Issue;

final class InvalidExtendClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 232;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
abstract class MethodIssue extends \Psalm\Issue\CodeIssue
{
    /**
     * @var string
     */
    public $method_id;
    public function __construct(string $message, CodeLocation $code_location, string $method_id)
    {
        parent::__construct($message, $code_location);
        $this->method_id = strtolower($method_id);
    }
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
abstract class VariableIssue extends \Psalm\Issue\CodeIssue
{
    /**
     * @var string
     */
    public $var_name;
    public function __construct(string $message, CodeLocation $code_location, string $var_name)
    {
        parent::__construct($message, $code_location);
        $this->var_name = strtolower($var_name);
    }
}
<?php

namespace Psalm\Issue;

final class InvalidParent extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 214;
}
<?php

namespace Psalm\Issue;

final class InvalidScope extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 13;
}
<?php

namespace Psalm\Issue;

final class InvalidTraversableImplementation extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 266;
}
<?php

namespace Psalm\Issue;

final class ComplexMethod extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 260;
}
<?php

namespace Psalm\Issue;

final class PsalmInternalError extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 177;
}
<?php

namespace Psalm\Issue;

final class InvalidDocblockParamName extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 187;
}
<?php

namespace Psalm\Issue;

final class UnrecognizedExpression extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 48;
}
<?php

namespace Psalm\Issue;

final class TaintedHeader extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 256;
}
<?php

namespace Psalm\Issue;

final class DuplicateEnumCaseValue extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 279;
}
<?php

namespace Psalm\Issue;

final class ParamNameMismatch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 230;
}
<?php

namespace Psalm\Issue;

final class DeprecatedFunction extends \Psalm\Issue\FunctionIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 201;
}
<?php

namespace Psalm\Issue;

/**
 * This is different from NullReference, as PHP throws a notice (vs the possibility of a fatal error with a null
 * reference)
 */
final class NullPropertyAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 36;
}
<?php

namespace Psalm\Issue;

final class NullArrayOffset extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 124;
}
<?php

namespace Psalm\Issue;

final class UndefinedPropertyFetch extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 39;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidArrayOffset extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 116;
}
<?php

namespace Psalm\Issue;

final class DeprecatedTrait extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 171;
}
<?php

namespace Psalm\Issue;

final class NullOperand extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 61;
}
<?php

namespace Psalm\Issue;

final class OverriddenFinalConstant extends \Psalm\Issue\ClassConstantIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 310;
}
<?php

namespace Psalm\Issue;

final class InternalProperty extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 176;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidCast extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 190;
}
<?php

namespace Psalm\Issue;

final class MixedFunctionCall extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 185;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class RedundantCastGivenDocblockType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 263;
}
<?php

namespace Psalm\Issue;

final class UndefinedTrace extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 225;
}
<?php

namespace Psalm\Issue;

final class TaintedFile extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 255;
}
<?php

namespace Psalm\Issue;

/**
 * This is different from PossiblyNullReference, as PHP throws a notice (vs the possibility of a fatal error with a null
 * reference)
 */
final class PossiblyNullArrayAccess extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 79;
}
<?php

namespace Psalm\Issue;

final class UndefinedTrait extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 23;
}
<?php

namespace Psalm\Issue;

final class InvalidCast extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 103;
}
<?php

namespace Psalm\Issue;

final class LessSpecificImplementedReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 166;
}
<?php

namespace Psalm\Issue;

final class UndefinedMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 22;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidOperand extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 163;
}
<?php

namespace Psalm\Issue;

final class InvalidToString extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 55;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidPropertyFetch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 114;
}
<?php

namespace Psalm\Issue;

final class MissingClosureReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 68;
}
<?php

namespace Psalm\Issue;

final class InvalidClone extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 69;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class MixedPropertyTypeCoercion extends \Psalm\Issue\PropertyIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 196;
    use \Psalm\Issue\MixedIssueTrait;
    public function __construct(string $message, CodeLocation $code_location, string $property_id, ?CodeLocation $origin_location = null)
    {
        parent::__construct($message, $code_location, $property_id);
        $this->origin_location = $origin_location;
    }
}
<?php

namespace Psalm\Issue;

final class ReferenceConstraintViolation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 86;
}
<?php

namespace Psalm\Issue;

final class ImpureStaticVariable extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 210;
}
<?php

namespace Psalm\Issue;

final class ImplicitToStringCast extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 60;
}
<?php

namespace Psalm\Issue;

final class UndefinedFunction extends \Psalm\Issue\FunctionIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 21;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullOperand extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 80;
}
<?php

namespace Psalm\Issue;

final class RedundantPropertyInitializationCheck extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 261;
}
<?php

declare (strict_types=1);
namespace Psalm\Issue;

final class ConstantDeclarationInTrait extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 315;
}
<?php

namespace Psalm\Issue;

final class Trace extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 224;
}
<?php

namespace Psalm\Issue;

final class TaintedTextWithQuotes extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 274;
}
<?php

namespace Psalm\Issue;

final class ConstructorSignatureMismatch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 231;
}
<?php

namespace Psalm\Issue;

final class UninitializedProperty extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 186;
}
<?php

namespace Psalm\Issue;

final class InaccessibleClassConstant extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 53;
}
<?php

namespace Psalm\Issue;

final class UnusedVariable extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 77;
}
<?php

namespace Psalm\Issue;

final class UndefinedThisPropertyAssignment extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 40;
}
<?php

namespace Psalm\Issue;

final class InvalidPassByReference extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 102;
}
<?php

namespace Psalm\Issue;

final class InvalidDocblock extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 8;
}
<?php

namespace Psalm\Issue;

final class InvalidConstantAssignmentValue extends \Psalm\Issue\ClassConstantIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 304;
}
<?php

namespace Psalm\Issue;

final class UnusedReturnValue extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 272;
}
<?php

namespace Psalm\Issue;

final class OverriddenPropertyAccess extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 159;
}
<?php

namespace Psalm\Issue;

final class InvalidLiteralArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 237;
}
<?php

namespace Psalm\Issue;

final class MixedInferredReturnType extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 47;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class UnresolvableInclude extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 106;
}
<?php

namespace Psalm\Issue;

final class MoreSpecificReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 70;
}
<?php

namespace Psalm\Issue;

final class UnusedFunctionCall extends \Psalm\Issue\FunctionIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 206;
}
<?php

namespace Psalm\Issue;

final class UnsafeInstantiation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 229;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class TypeDoesNotContainNull extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 90;
    public function __construct(string $message, CodeLocation $code_location, ?string $dupe_key)
    {
        parent::__construct($message, $code_location);
        $this->dupe_key = $dupe_key;
    }
}
<?php

namespace Psalm\Issue;

final class ImpureFunctionCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 202;
}
<?php

namespace Psalm\Issue;

final class NonStaticSelfCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 63;
}
<?php

namespace Psalm\Issue;

final class InvalidArrayAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 6;
}
<?php

namespace Psalm\Issue;

final class OverriddenInterfaceConstant extends \Psalm\Issue\ClassConstantIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 306;
}
<?php

namespace Psalm\Issue;

final class MixedArrayAssignment extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 117;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class UnimplementedInterfaceMethod extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 44;
}
<?php

namespace Psalm\Issue;

final class TaintedShell extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 246;
}
<?php

namespace Psalm\Issue;

final class OverriddenMethodAccess extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 66;
}
<?php

namespace Psalm\Issue;

final class MixedPropertyFetch extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 34;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class MoreSpecificImplementedParamType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 140;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class PropertyNotSetInConstructor extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 74;
    public function __construct(string $message, CodeLocation $code_location, string $property_id)
    {
        parent::__construct($message, $code_location, $property_id);
        $this->dupe_key = $property_id;
    }
}
<?php

namespace Psalm\Issue;

class RiskyCast extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 313;
}
<?php

namespace Psalm\Issue;

final class UndefinedMagicPropertyAssignment extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 217;
}
<?php

namespace Psalm\Issue;

final class PossiblyFalseArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 104;
}
<?php

namespace Psalm\Issue;

final class PossiblyFalseOperand extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 162;
}
<?php

namespace Psalm\Issue;

final class IfThisIsMismatch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 300;
}
<?php

namespace Psalm\Issue;

final class DeprecatedMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 1;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidPropertyAssignmentValue extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 147;
}
<?php

namespace Psalm\Issue;

final class UnresolvableConstant extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 303;
}
<?php

namespace Psalm\Issue;

final class InaccessibleMethod extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 3;
}
<?php

namespace Psalm\Issue;

final class InvalidArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 4;
}
<?php

namespace Psalm\Issue;

final class LessSpecificClassConstantType extends \Psalm\Issue\ClassConstantIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 307;
}
<?php

namespace Psalm\Issue;

final class PossiblyUnusedReturnValue extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 273;
}
<?php

namespace Psalm\Issue;

final class DeprecatedClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 98;
}
<?php

namespace Psalm\Issue;

final class NullIterator extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 96;
}
<?php

namespace Psalm\Issue;

final class PropertyTypeCoercion extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 198;
}
<?php

namespace Psalm\Issue;

final class InvalidGlobal extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 46;
}
<?php

namespace Psalm\Issue;

final class MixedArrayOffset extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 31;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
abstract class ClassIssue extends \Psalm\Issue\CodeIssue
{
    /**
     * @var string
     */
    public $fq_classlike_name;
    public function __construct(string $message, CodeLocation $code_location, string $fq_classlike_name)
    {
        parent::__construct($message, $code_location);
        $this->fq_classlike_name = $fq_classlike_name;
    }
}
<?php

namespace Psalm\Issue;

final class RedundantFunctionCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 280;
}
<?php

namespace Psalm\Issue;

final class MixedArrayAccess extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 51;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class UnusedClosureParam extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 188;
}
<?php

namespace Psalm\Issue;

final class InvalidEnumBackingType extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 276;
}
<?php

namespace Psalm\Issue;

final class InvalidReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 11;
}
<?php

namespace Psalm\Issue;

final class UndefinedClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 19;
}
<?php

namespace Psalm\Issue;

final class MissingImmutableAnnotation extends \Psalm\Issue\CodeIssue
{
    public const SHORTCODE = 213;
}
<?php

namespace Psalm\Issue;

final class AbstractMethodCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 223;
}
<?php

namespace Psalm\Issue;

final class InvalidMethodCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 91;
}
<?php

namespace Psalm\Issue;

final class UndefinedInterface extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 189;
}
<?php

namespace Psalm\Issue;

final class MissingDependency extends \Psalm\Issue\ClassIssue
{
    public const SHORTCODE = 157;
}
<?php

namespace Psalm\Issue;

final class ExtensionRequirementViolation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 239;
}
<?php

namespace Psalm\Issue;

final class ConfigIssue extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 271;
}
<?php

namespace Psalm\Issue;

final class InvalidPropertyAssignmentValue extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 145;
}
<?php

namespace Psalm\Issue;

final class NullReference extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 16;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidFunctionCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 136;
}
<?php

namespace Psalm\Issue;

final class InvalidFunctionCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 64;
}
<?php

namespace Psalm\Issue;

final class EmptyArrayAccess extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 100;
}
<?php

namespace Psalm\Issue;

final class InternalMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 175;
}
<?php

namespace Psalm\Issue;

final class InterfaceInstantiation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 158;
}
<?php

namespace Psalm\Issue;

final class InvalidClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 7;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 92;
}
<?php

namespace Psalm\Issue;

final class TooFewArguments extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 25;
}
<?php

namespace Psalm\Issue;

final class TaintedUserSecret extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 247;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullArrayOffset extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 125;
}
<?php

namespace Psalm\Issue;

final class UncaughtThrowInGlobalScope extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 191;
}
<?php

declare (strict_types=1);
namespace Psalm\Issue;

final class NonInvariantPropertyType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 265;
}
<?php

namespace Psalm\Issue;

final class InvalidNullableReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 144;
}
<?php

namespace Psalm\Issue;

final class MissingPropertyType extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 45;
}
<?php

namespace Psalm\Issue;

final class MixedMethodCall extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 15;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class ReservedWord extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 95;
}
<?php

namespace Psalm\Issue;

final class NullArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 57;
}
<?php

declare (strict_types=1);
namespace Psalm\Issue;

class UnusedBaselineEntry extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 316;
}
<?php

namespace Psalm\Issue;

final class ReferenceReusedFromConfusingScope extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 308;
}
<?php

namespace Psalm\Issue;

final class MixedReturnTypeCoercion extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 197;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class ImpureStaticProperty extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 221;
}
<?php

namespace Psalm\Issue;

final class ImpureMethodCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 203;
}
<?php

namespace Psalm\Issue;

final class UnusedPsalmSuppress extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 207;
}
<?php

namespace Psalm\Issue;

final class AbstractInstantiation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 72;
}
<?php

namespace Psalm\Issue;

final class RawObjectIteration extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 111;
}
<?php

namespace Psalm\Issue;

final class InaccessibleProperty extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 54;
}
<?php

namespace Psalm\Issue;

final class DeprecatedInterface extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 152;
}
<?php

namespace Psalm\Issue;

final class InvalidIterator extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 9;
}
<?php

namespace Psalm\Issue;

final class InvalidAttribute extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 242;
}
<?php

namespace Psalm\Issue;

final class TaintedSql extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 244;
}
<?php

namespace Psalm\Issue;

final class UndefinedConstant extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 20;
}
<?php

namespace Psalm\Issue;

final class TaintedSSRF extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 253;
}
<?php

namespace Psalm\Issue;

final class NamedArgumentNotAllowed extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 268;
}
<?php

namespace Psalm\Issue;

final class LoopInvalidation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 130;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
trait MixedIssueTrait
{
    /**
     * @var ?CodeLocation
     * @readonly
     */
    public $origin_location;
    public function __construct(string $message, CodeLocation $code_location, ?CodeLocation $origin_location = null)
    {
        $this->code_location = $code_location;
        $this->message = $message;
        $this->origin_location = $origin_location;
    }
    public function getMixedOriginMessage() : string
    {
        return $this->message . ($this->origin_location ? '. Consider improving the type at ' . $this->origin_location->getShortSummary() : '');
    }
    public function getOriginalLocation() : ?CodeLocation
    {
        return $this->origin_location;
    }
}
<?php

namespace Psalm\Issue;

final class TaintedSystemSecret extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 248;
}
<?php

namespace Psalm\Issue;

final class NullableReturnStatement extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 139;
}
<?php

namespace Psalm\Issue;

final class UnnecessaryVarAnnotation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 212;
}
<?php

namespace Psalm\Issue;

final class UndefinedPropertyAssignment extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 38;
}
<?php

namespace Psalm\Issue;

final class UndefinedVariable extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 24;
}
<?php

namespace Psalm\Issue;

final class UnusedConstructor extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 258;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class TypeDoesNotContainType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 56;
    public function __construct(string $message, CodeLocation $code_location, ?string $dupe_key)
    {
        parent::__construct($message, $code_location);
        $this->dupe_key = $dupe_key;
    }
}
<?php

namespace Psalm\Issue;

final class NoValue extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 179;
}
<?php

namespace Psalm\Issue;

final class DuplicateMethod extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 178;
}
<?php

namespace Psalm\Issue;

final class InvalidNamedArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 238;
}
<?php

namespace Psalm\Issue;

final class UnhandledMatchCondition extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 236;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidDocblockTag extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 270;
}
<?php

namespace Psalm\Issue;

final class InvalidTypeImport extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 233;
}
<?php

namespace Psalm\Issue;

final class DuplicateFunction extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 180;
}
<?php

namespace Psalm\Issue;

final class MixedAssignment extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 32;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class TooManyTemplateParams extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 184;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
final class MixedArgument extends \Psalm\Issue\ArgumentIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 30;
    use \Psalm\Issue\MixedIssueTrait;
    public function __construct(string $message, CodeLocation $code_location, ?string $function_id = null, ?CodeLocation $origin_location = null)
    {
        $this->code_location = $code_location;
        $this->message = $message;
        $this->function_id = $function_id ? strtolower($function_id) : null;
        $this->origin_location = $origin_location;
    }
}
<?php

namespace Psalm\Issue;

final class MissingClosureParamType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 153;
}
<?php

namespace Psalm\Issue;

final class InvalidParamDefault extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 62;
}
<?php

namespace Psalm\Issue;

final class FalseOperand extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 161;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullFunctionCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 94;
}
<?php

namespace Psalm\Issue;

final class MixedPropertyAssignment extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 33;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

final class MethodSignatureMustProvideReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 282;
}
<?php

namespace Psalm\Issue;

final class InvalidStaticInvocation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 14;
}
<?php

namespace Psalm\Issue;

final class MixedClone extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 227;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
interface MixedIssue
{
    public function getMixedOriginMessage() : string;
    public function getOriginalLocation() : ?CodeLocation;
}
<?php

namespace Psalm\Issue;

final class PossibleRawObjectIteration extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 208;
}
<?php

namespace Psalm\Issue;

final class InvalidStringClass extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 160;
}
<?php

namespace Psalm\Issue;

final class UndefinedThisPropertyFetch extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 41;
}
<?php

namespace Psalm\Issue;

final class MethodSignatureMustOmitReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 168;
}
<?php

namespace Psalm\Issue;

final class ConflictingReferenceConstraint extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 85;
}
<?php

namespace Psalm\Issue;

final class MissingDocblockType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 110;
}
<?php

namespace Psalm\Issue;

final class ParentNotFound extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 17;
}
<?php

namespace Psalm\Issue;

final class ImplementationRequirementViolation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 240;
}
<?php

namespace Psalm\Issue;

final class FalsableReturnStatement extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 5;
    public const SHORTCODE = 137;
}
<?php

namespace Psalm\Issue;

final class TaintedHtml extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 245;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
abstract class PropertyIssue extends \Psalm\Issue\CodeIssue
{
    /**
     * @var string
     */
    public $property_id;
    public function __construct(string $message, CodeLocation $code_location, string $property_id)
    {
        parent::__construct($message, $code_location);
        $this->property_id = $property_id;
    }
}
<?php

namespace Psalm\Issue;

final class StringIncrement extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 211;
}
<?php

namespace Psalm\Issue;

final class MutableDependency extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 222;
}
<?php

namespace Psalm\Issue;

final class InvalidArrayAccess extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 5;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
abstract class ClassConstantIssue extends \Psalm\Issue\CodeIssue
{
    /**
     * @var string
     */
    public $const_id;
    public function __construct(string $message, CodeLocation $code_location, string $const_id)
    {
        parent::__construct($message, $code_location);
        $this->const_id = $const_id;
    }
}
<?php

namespace Psalm\Issue;

abstract class PluginIssue extends \Psalm\Issue\CodeIssue
{
}
<?php

namespace Psalm\Issue;

final class UnsafeGenericInstantiation extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 269;
}
<?php

namespace Psalm\Issue;

final class UndefinedMagicPropertyFetch extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 218;
}
<?php

namespace Psalm\Issue;

final class PossiblyFalseIterator extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 164;
}
<?php

namespace Psalm\Issue;

final class DuplicateParam extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 65;
}
<?php

namespace Psalm\Issue;

final class UnevaluatedCode extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 84;
}
<?php

namespace Psalm\Issue;

final class ImplementedParamTypeMismatch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 199;
}
<?php

namespace Psalm\Issue;

final class InvalidCatch extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 132;
}
<?php

namespace Psalm\Issue;

final class PossiblyUndefinedArrayOffset extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 167;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidArrayAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 118;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidPropertyAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 112;
}
<?php

namespace Psalm\Issue;

final class AssignmentToVoid extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 121;
}
<?php

namespace Psalm\Issue;

final class DuplicateArrayKey extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 151;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullArrayAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 120;
}
<?php

namespace Psalm\Issue;

final class MissingThrowsDocblock extends \Psalm\Issue\CodeIssue
{
    public const SHORTCODE = 169;
}
<?php

namespace Psalm\Issue;

final class InvalidClassConstantType extends \Psalm\Issue\ClassConstantIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 309;
}
<?php

namespace Psalm\Issue;

final class CheckType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 8;
    public const SHORTCODE = 311;
}
<?php

namespace Psalm\Issue;

final class ImpurePropertyFetch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 234;
}
<?php

namespace Psalm\Issue;

/**
 * This is different from NullReference, as PHP throws a notice (vs the possibility of a fatal error with a null
 * reference)
 */
final class NullArrayAccess extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 52;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class DocblockTypeContradiction extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 155;
    public function __construct(string $message, CodeLocation $code_location, ?string $dupe_key)
    {
        parent::__construct($message, $code_location);
        $this->dupe_key = $dupe_key;
    }
}
<?php

namespace Psalm\Issue;

final class ImpurePropertyAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 204;
}
<?php

namespace Psalm\Issue;

final class NullFunctionCall extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 93;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidArrayAccess extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 109;
}
<?php

namespace Psalm\Issue;

final class RedundantIdentityWithTrue extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 228;
}
<?php

namespace Psalm\Issue;

final class UnusedMethodCall extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 209;
}
<?php

namespace Psalm\Issue;

final class AmbiguousConstantInheritance extends \Psalm\Issue\ClassConstantIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 305;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidClone extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 226;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class UnusedProperty extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 150;
    public function __construct(string $message, CodeLocation $code_location, string $property_id)
    {
        parent::__construct($message, $code_location, $property_id);
        $this->dupe_key = $property_id;
    }
}
<?php

namespace Psalm\Issue;

final class MissingFile extends \Psalm\Issue\CodeIssue
{
    public const SHORTCODE = 107;
}
<?php

namespace Psalm\Issue;

final class UnusedClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 75;
}
<?php

namespace Psalm\Issue;

final class UnrecognizedStatement extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 49;
}
<?php

namespace Psalm\Issue;

final class UnsupportedReferenceUsage extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 312;
}
<?php

namespace Psalm\Issue;

final class ImplementedReturnTypeMismatch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 123;
}
<?php

namespace Psalm\Issue;

final class LessSpecificReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 88;
}
<?php

namespace Psalm\Issue;

final class PossiblyInvalidIterator extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 165;
}
<?php

namespace Psalm\Issue;

final class UnusedForeachValue extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 275;
}
<?php

namespace Psalm\Issue;

final class PossiblyUnusedParam extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 134;
}
<?php

namespace Psalm\Issue;

final class NoInterfaceProperties extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 28;
}
<?php

namespace Psalm\Issue;

final class UndefinedAttributeClass extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 241;
}
<?php

namespace Psalm\Issue;

final class ParadoxicalCondition extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 89;
}
<?php

namespace Psalm\Issue;

/**
 * This is different from PossiblyNullReference, as PHP throws a notice (vs the possibility of a fatal error with a null
 * reference)
 */
final class PossiblyNullPropertyAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 81;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class RedundantCondition extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 122;
    public function __construct(string $message, CodeLocation $code_location, ?string $dupe_key)
    {
        parent::__construct($message, $code_location);
        $this->dupe_key = $dupe_key;
    }
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\IssueData;
use function array_pop;
use function explode;
abstract class CodeIssue
{
    /** @var int */
    public const ERROR_LEVEL = -1;
    /** @var int<0, max> */
    public const SHORTCODE = 0;
    /**
     * @var CodeLocation
     * @readonly
     */
    public $code_location;
    /**
     * @var string
     * @readonly
     */
    public $message;
    /**
     * @var ?string
     */
    public $dupe_key;
    public function __construct(string $message, CodeLocation $code_location)
    {
        $this->code_location = $code_location;
        $this->message = $message;
    }
    public function getShortLocationWithPrevious() : string
    {
        $previous_text = '';
        if ($this->code_location->previous_location) {
            $previous_location = $this->code_location->previous_location;
            $previous_text = ' from ' . $previous_location->file_name . ':' . $previous_location->getLineNumber();
        }
        return $this->code_location->file_name . ':' . $this->code_location->getLineNumber() . $previous_text;
    }
    public function getShortLocation() : string
    {
        return $this->code_location->file_name . ':' . $this->code_location->getLineNumber();
    }
    public function getFilePath() : string
    {
        return $this->code_location->file_path;
    }
    public static function getIssueType() : string
    {
        $fqcn_parts = explode('\\', static::class);
        return array_pop($fqcn_parts);
    }
    public function toIssueData(string $severity) : IssueData
    {
        $location = $this->code_location;
        $selection_bounds = $location->getSelectionBounds();
        $snippet_bounds = $location->getSnippetBounds();
        return new IssueData($severity, $location->getLineNumber(), $location->getEndLineNumber(), static::getIssueType(), $this->message, $location->file_name, $location->file_path, $location->getSnippet(), $location->getSelectedText(), $selection_bounds[0], $selection_bounds[1], $snippet_bounds[0], $snippet_bounds[1], $location->getColumn(), $location->getEndColumn(), static::SHORTCODE, static::ERROR_LEVEL, $this instanceof \Psalm\Issue\TaintedInput ? $this->getTaintTrace() : null, $this instanceof \Psalm\Issue\MixedIssue && ($origin_location = $this->getOriginalLocation()) ? [\Psalm\Issue\TaintedInput::nodeToDataFlowNodeData($origin_location, 'The type of ' . $location->getSelectedText() . ' is sourced from here')] : null, $this->dupe_key);
    }
}
<?php

namespace Psalm\Issue;

final class UndefinedGlobalVariable extends \Psalm\Issue\VariableIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 127;
}
<?php

namespace Psalm\Issue;

/**
 * This is different from NullReference, as PHP throws a notice (vs the possibility of a fatal error with a null
 * reference)
 */
final class NullPropertyFetch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 27;
}
<?php

namespace Psalm\Issue;

final class PossiblyUndefinedGlobalVariable extends \Psalm\Issue\VariableIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 126;
}
<?php

namespace Psalm\Issue;

final class InvalidThrow extends \Psalm\Issue\ClassIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 133;
}
<?php

namespace Psalm\Issue;

final class InvalidScalarArgument extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 12;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class PossiblyUnusedProperty extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 149;
    public function __construct(string $message, CodeLocation $code_location, string $property_id)
    {
        parent::__construct($message, $code_location, $property_id);
        $this->dupe_key = $property_id;
    }
}
<?php

namespace Psalm\Issue;

final class LessSpecificReturnStatement extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 129;
}
<?php

namespace Psalm\Issue;

final class DuplicateClass extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 71;
}
<?php

namespace Psalm\Issue;

final class InvalidPropertyAssignment extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 6;
    public const SHORTCODE = 10;
}
<?php

namespace Psalm\Issue;

final class ComplexFunction extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 259;
}
<?php

namespace Psalm\Issue;

final class UndefinedMagicMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 219;
}
<?php

namespace Psalm\Issue;

final class TaintedEval extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 252;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use function strtolower;
abstract class ArgumentIssue extends \Psalm\Issue\CodeIssue
{
    /**
     * @var ?string
     */
    public $function_id;
    public function __construct(string $message, CodeLocation $code_location, ?string $function_id = null)
    {
        parent::__construct($message, $code_location);
        $this->function_id = $function_id ? strtolower($function_id) : null;
    }
}
<?php

namespace Psalm\Issue;

final class RedundantCast extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 262;
}
<?php

namespace Psalm\Issue;

final class PossiblyNullReference extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 83;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class RedundantConditionGivenDocblockType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 156;
    public function __construct(string $message, CodeLocation $code_location, ?string $dupe_key)
    {
        parent::__construct($message, $code_location);
        $this->dupe_key = $dupe_key;
    }
}
<?php

namespace Psalm\Issue;

final class MixedOperand extends \Psalm\Issue\CodeIssue implements \Psalm\Issue\MixedIssue
{
    public const ERROR_LEVEL = 1;
    public const SHORTCODE = 59;
    use \Psalm\Issue\MixedIssueTrait;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
final class MissingConstructor extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 73;
    public function __construct(string $message, CodeLocation $code_location, ?string $dupe_key)
    {
        parent::__construct($message, $code_location);
        $this->dupe_key = $dupe_key;
    }
}
<?php

namespace Psalm\Issue;

final class PossiblyFalsePropertyAssignmentValue extends \Psalm\Issue\PropertyIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 146;
}
<?php

namespace Psalm\Issue;

final class TooManyArguments extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 4;
    public const SHORTCODE = 26;
}
<?php

namespace Psalm\Issue;

final class CircularReference extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 131;
}
<?php

namespace Psalm\Issue;

final class PossiblyUndefinedMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 108;
}
<?php

namespace Psalm\Issue;

final class PossiblyFalseReference extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 105;
}
<?php

namespace Psalm\Issue;

use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\DataFlowNodeData;
abstract class TaintedInput extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    /** @var int<0, max> */
    public const SHORTCODE = 205;
    /**
     * @var string
     * @readonly
     */
    public $journey_text;
    /**
     * @var list<array{location: ?CodeLocation, label: string, entry_path_type: string}>
     * @readonly
     */
    public $journey = [];
    /**
     * @param list<array{location: ?CodeLocation, label: string, entry_path_type: string}> $journey
     */
    public function __construct(string $message, CodeLocation $code_location, array $journey, string $journey_text)
    {
        parent::__construct($message, $code_location);
        $this->journey = $journey;
        $this->journey_text = $journey_text;
    }
    /**
     * @return list<DataFlowNodeData|array{label: string, entry_path_type: string}>
     */
    public function getTaintTrace() : array
    {
        $nodes = [];
        foreach ($this->journey as ['location' => $location, 'label' => $label, 'entry_path_type' => $path_type]) {
            if ($location) {
                $nodes[] = self::nodeToDataFlowNodeData($location, $label);
            } else {
                $nodes[] = ['label' => $label, 'entry_path_type' => $path_type];
            }
        }
        return $nodes;
    }
    public static function nodeToDataFlowNodeData(CodeLocation $location, string $label) : DataFlowNodeData
    {
        $selection_bounds = $location->getSelectionBounds();
        $snippet_bounds = $location->getSnippetBounds();
        return new DataFlowNodeData($label, $location->getLineNumber(), $location->getEndLineNumber(), $location->file_name, $location->file_path, $location->getSnippet(), $selection_bounds[0], $selection_bounds[1], $snippet_bounds[0], $location->getColumn(), $location->getEndColumn());
    }
    public function getJourneyMessage() : string
    {
        return $this->message . ' in path: ' . $this->journey_text;
    }
}
<?php

namespace Psalm\Issue;

final class MethodSignatureMismatch extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 7;
    public const SHORTCODE = 42;
}
<?php

namespace Psalm\Issue;

final class MissingParamType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 154;
}
<?php

namespace Psalm\Issue;

final class InvalidFalsableReturnType extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = 2;
    public const SHORTCODE = 143;
}
<?php

namespace Psalm\Issue;

final class TaintedLdap extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 254;
}
<?php

namespace Psalm\Issue;

final class ArgumentTypeCoercion extends \Psalm\Issue\ArgumentIssue
{
    public const ERROR_LEVEL = 3;
    public const SHORTCODE = 193;
}
<?php

namespace Psalm\Issue;

final class TaintedCallable extends \Psalm\Issue\TaintedInput
{
    public const SHORTCODE = 243;
}
<?php

namespace Psalm\Issue;

final class InvalidEnumMethod extends \Psalm\Issue\MethodIssue
{
    public const ERROR_LEVEL = -1;
    public const SHORTCODE = 314;
}
<?php

namespace Psalm\Issue;

final class UnusedParam extends \Psalm\Issue\CodeIssue
{
    public const ERROR_LEVEL = -2;
    public const SHORTCODE = 135;
}
<?php

namespace Psalm\Internal\Stubs\Generator;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Codebase;
use Psalm\Internal\Codebase\ConstantTypeResolver;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\Stmt\VirtualClass;
use Psalm\Node\Stmt\VirtualClassConst;
use Psalm\Node\Stmt\VirtualClassMethod;
use Psalm\Node\Stmt\VirtualInterface;
use Psalm\Node\Stmt\VirtualProperty;
use Psalm\Node\Stmt\VirtualPropertyProperty;
use Psalm\Node\Stmt\VirtualTrait;
use Psalm\Node\VirtualConst;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Scanner\ParsedDocblock;
use Psalm\Type;
use Psalm\Type\Union;
use ReflectionProperty;
use UnexpectedValueException;
use function array_slice;
use function rtrim;
/**
 * @internal
 */
class ClassLikeStubGenerator
{
    /**
     * @return PhpParser\Node\Stmt\Class_|PhpParser\Node\Stmt\Interface_|PhpParser\Node\Stmt\Trait_
     */
    public static function getClassLikeNode(Codebase $codebase, ClassLikeStorage $storage, string $classlike_name) : PhpParser\Node\Stmt\ClassLike
    {
        $subnodes = ['stmts' => [...self::getConstantNodes($codebase, $storage), ...self::getPropertyNodes($storage), ...self::getMethodNodes($storage)]];
        $docblock = new ParsedDocblock('', []);
        $template_offset = 0;
        foreach ($storage->template_types ?: [] as $template_name => $map) {
            $type = \array_values($map)[0];
            $key = isset($storage->template_covariants[$template_offset]) ? 'template-covariant' : 'template';
            $docblock->tags[$key][] = $template_name . ' as ' . $type->toNamespacedString(null, [], null, \false);
            $template_offset++;
        }
        $attrs = ['comments' => $docblock->tags ? [new PhpParser\Comment\Doc(rtrim($docblock->render('        ')))] : []];
        if ($storage->is_interface) {
            if ($storage->direct_interface_parents) {
                $subnodes['extends'] = [];
                foreach ($storage->direct_interface_parents as $direct_interface_parent) {
                    $subnodes['extends'][] = new VirtualFullyQualified($direct_interface_parent);
                }
            }
            return new VirtualInterface($classlike_name, $subnodes, $attrs);
        }
        if ($storage->is_trait) {
            return new VirtualTrait($classlike_name, $subnodes, $attrs);
        }
        if ($storage->parent_class) {
            $subnodes['extends'] = new VirtualFullyQualified($storage->parent_class);
        } else {
            if ($storage->direct_class_interfaces) {
                $subnodes['implements'] = [];
                foreach ($storage->direct_class_interfaces as $direct_class_interface) {
                    $subnodes['implements'][] = new VirtualFullyQualified($direct_class_interface);
                }
            }
        }
        return new VirtualClass($classlike_name, $subnodes, $attrs);
    }
    /**
     * @return list<PhpParser\Node\Stmt\ClassConst>
     */
    private static function getConstantNodes(Codebase $codebase, ClassLikeStorage $storage) : array
    {
        $constant_nodes = [];
        foreach ($storage->constants as $constant_name => $constant_storage) {
            if ($constant_storage->unresolved_node) {
                $type = new Union([ConstantTypeResolver::resolve($codebase->classlikes, $constant_storage->unresolved_node)]);
            } elseif ($constant_storage->type) {
                $type = $constant_storage->type;
            } else {
                throw new UnexpectedValueException('bad');
            }
            $constant_nodes[] = new VirtualClassConst([new VirtualConst($constant_name, \Psalm\Internal\Stubs\Generator\StubsGenerator::getExpressionFromType($type))], $constant_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC ? PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC : ($constant_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PROTECTED ? PhpParser\Node\Stmt\Class_::MODIFIER_PROTECTED : PhpParser\Node\Stmt\Class_::MODIFIER_PRIVATE));
        }
        return $constant_nodes;
    }
    /**
     * @return list<PhpParser\Node\Stmt\Property>
     */
    private static function getPropertyNodes(ClassLikeStorage $storage) : array
    {
        $namespace_name = \implode('\\', array_slice(\explode('\\', $storage->name), 0, -1));
        $property_nodes = [];
        foreach ($storage->properties as $property_name => $property_storage) {
            switch ($property_storage->visibility) {
                case ClassLikeAnalyzer::VISIBILITY_PRIVATE:
                    $flag = PhpParser\Node\Stmt\Class_::MODIFIER_PRIVATE;
                    break;
                case ClassLikeAnalyzer::VISIBILITY_PROTECTED:
                    $flag = PhpParser\Node\Stmt\Class_::MODIFIER_PROTECTED;
                    break;
                default:
                    $flag = PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC;
                    break;
            }
            $docblock = new ParsedDocblock('', []);
            if ($property_storage->type && $property_storage->signature_type !== $property_storage->type) {
                $docblock->tags['var'][] = $property_storage->type->toNamespacedString($namespace_name, [], null, \false);
            }
            $property_nodes[] = new VirtualProperty($flag | ($property_storage->is_static ? PhpParser\Node\Stmt\Class_::MODIFIER_STATIC : 0), [new VirtualPropertyProperty($property_name, $property_storage->suggested_type ? \Psalm\Internal\Stubs\Generator\StubsGenerator::getExpressionFromType($property_storage->suggested_type) : null)], ['comments' => $docblock->tags ? [new PhpParser\Comment\Doc(rtrim($docblock->render('        ')))] : []], $property_storage->signature_type ? \Psalm\Internal\Stubs\Generator\StubsGenerator::getParserTypeFromPsalmType($property_storage->signature_type) : null);
        }
        return $property_nodes;
    }
    /**
     * @return list<PhpParser\Node\Stmt\ClassMethod>
     */
    private static function getMethodNodes(ClassLikeStorage $storage) : array
    {
        $namespace_name = \implode('\\', array_slice(\explode('\\', $storage->name), 0, -1));
        $method_nodes = [];
        foreach ($storage->methods as $method_storage) {
            if (!$method_storage->cased_name) {
                throw new UnexpectedValueException('very bad');
            }
            switch ($method_storage->visibility) {
                case ReflectionProperty::IS_PRIVATE:
                    $flag = PhpParser\Node\Stmt\Class_::MODIFIER_PRIVATE;
                    break;
                case ReflectionProperty::IS_PROTECTED:
                    $flag = PhpParser\Node\Stmt\Class_::MODIFIER_PROTECTED;
                    break;
                default:
                    $flag = PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC;
                    break;
            }
            $docblock = new ParsedDocblock('', []);
            foreach ($method_storage->template_types ?: [] as $template_name => $map) {
                $type = \array_values($map)[0];
                $docblock->tags['template'][] = $template_name . ' as ' . $type->toNamespacedString($namespace_name, [], null, \false);
            }
            foreach ($method_storage->params as $param) {
                if ($param->type && $param->type !== $param->signature_type) {
                    $docblock->tags['param'][] = $param->type->toNamespacedString($namespace_name, [], null, \false) . ' $' . $param->name;
                }
            }
            if ($method_storage->return_type && $method_storage->signature_return_type !== $method_storage->return_type) {
                $docblock->tags['return'][] = $method_storage->return_type->toNamespacedString($namespace_name, [], null, \false);
            }
            foreach ($method_storage->throws ?: [] as $exception_name => $_) {
                $docblock->tags['throws'][] = Type::getStringFromFQCLN($exception_name, $namespace_name, [], null, \false);
            }
            $method_nodes[] = new VirtualClassMethod($method_storage->cased_name, ['flags' => $flag | ($method_storage->is_static ? PhpParser\Node\Stmt\Class_::MODIFIER_STATIC : 0) | ($method_storage->abstract ? PhpParser\Node\Stmt\Class_::MODIFIER_ABSTRACT : 0), 'params' => \Psalm\Internal\Stubs\Generator\StubsGenerator::getFunctionParamNodes($method_storage), 'returnType' => $method_storage->signature_return_type ? \Psalm\Internal\Stubs\Generator\StubsGenerator::getParserTypeFromPsalmType($method_storage->signature_return_type) : null, 'stmts' => $storage->is_interface || $method_storage->abstract ? null : []], ['comments' => $docblock->tags ? [new PhpParser\Comment\Doc(rtrim($docblock->render('        ')))] : []]);
        }
        return $method_nodes;
    }
}
<?php

namespace Psalm\Internal\Stubs\Generator;

use Psalm\Codebase;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Atomic\Scalar;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\Scanner\ParsedDocblock;
use Psalm\Node\Expr\VirtualArray;
use Psalm\Node\Expr\VirtualArrayItem;
use Psalm\Node\Expr\VirtualClassConstFetch;
use Psalm\Node\Expr\VirtualConstFetch;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\Scalar\VirtualDNumber;
use Psalm\Node\Scalar\VirtualLNumber;
use Psalm\Node\Scalar\VirtualString;
use Psalm\Node\Stmt\VirtualFunction;
use Psalm\Node\Stmt\VirtualNamespace;
use Psalm\Node\VirtualConst;
use Psalm\Node\Stmt\VirtualConst as StmtVirtualConst_;
use Psalm\Node\VirtualIdentifier;
use Psalm\Node\VirtualName;
use Psalm\Node\VirtualNullableType;
use Psalm\Node\VirtualParam;
use Psalm\Type;
use Psalm\Type\Union;
use UnexpectedValueException;
use function dirname;
use function is_int;
use function rtrim;
use function strpos;
/**
 * @internal
 */
class StubsGenerator
{
    public static function getAll(Codebase $codebase, ClassLikeStorageProvider $class_provider, FileStorageProvider $file_provider) : string
    {
        $namespaced_nodes = [];
        $psalm_base = dirname(__DIR__, 5);
        foreach ($class_provider->getAll() as $storage) {
            if (strpos($storage->name, 'Psalm\\') === 0) {
                continue;
            }
            if ($storage->location && strpos($storage->location->file_path, $psalm_base) === 0) {
                continue;
            }
            if ($storage->stubbed) {
                continue;
            }
            $name_parts = \explode('\\', $storage->name);
            $classlike_name = \array_pop($name_parts);
            $namespace_name = \implode('\\', $name_parts);
            if (!isset($namespaced_nodes[$namespace_name])) {
                $namespaced_nodes[$namespace_name] = [];
            }
            $namespaced_nodes[$namespace_name][$classlike_name] = \Psalm\Internal\Stubs\Generator\ClassLikeStubGenerator::getClassLikeNode($codebase, $storage, $classlike_name);
        }
        $all_function_names = [];
        foreach ($codebase->functions->getAllStubbedFunctions() as $function_storage) {
            if ($function_storage->location && strpos($function_storage->location->file_path, $psalm_base) === 0) {
                continue;
            }
            if (!$function_storage->cased_name) {
                throw new UnexpectedValueException('very bad');
            }
            $fq_name = $function_storage->cased_name;
            $all_function_names[$fq_name] = \true;
            $name_parts = \explode('\\', $fq_name);
            $function_name = \array_pop($name_parts);
            $namespace_name = \implode('\\', $name_parts);
            $namespaced_nodes[$namespace_name][$fq_name] = self::getFunctionNode($function_storage, $function_name, $namespace_name);
        }
        foreach ($codebase->getAllStubbedConstants() as $fq_name => $type) {
            if ($type->isMixed()) {
                continue;
            }
            $name_parts = \explode('\\', $fq_name);
            $constant_name = \array_pop($name_parts);
            $namespace_name = \implode('\\', $name_parts);
            $namespaced_nodes[$namespace_name][$fq_name] = new StmtVirtualConst_([new VirtualConst($constant_name, self::getExpressionFromType($type))]);
        }
        foreach ($file_provider->getAll() as $file_storage) {
            if (strpos($file_storage->file_path, $psalm_base) === 0) {
                continue;
            }
            foreach ($file_storage->functions as $function_storage) {
                if (!$function_storage->cased_name) {
                    continue;
                }
                $fq_name = $function_storage->cased_name;
                if (isset($all_function_names[$fq_name])) {
                    continue;
                }
                $all_function_names[$fq_name] = \true;
                $name_parts = \explode('\\', $fq_name);
                $function_name = \array_pop($name_parts);
                $namespace_name = \implode('\\', $name_parts);
                $namespaced_nodes[$namespace_name][$fq_name] = self::getFunctionNode($function_storage, $function_name, $namespace_name);
            }
            foreach ($file_storage->constants as $fq_name => $type) {
                if ($type->isMixed()) {
                    continue;
                }
                $name_parts = \explode('\\', $fq_name);
                $constant_name = \array_pop($name_parts);
                $namespace_name = \implode('\\', $name_parts);
                $namespaced_nodes[$namespace_name][$fq_name] = new StmtVirtualConst_([new VirtualConst($constant_name, self::getExpressionFromType($type))]);
            }
        }
        \ksort($namespaced_nodes);
        $namespace_stmts = [];
        foreach ($namespaced_nodes as $namespace_name => $stmts) {
            \ksort($stmts);
            $namespace_stmts[] = new VirtualNamespace($namespace_name ? new VirtualName($namespace_name) : null, \array_values($stmts), ['kind' => PhpParser\Node\Stmt\Namespace_::KIND_BRACED]);
        }
        $prettyPrinter = new PhpParser\PrettyPrinter\Standard();
        return $prettyPrinter->prettyPrintFile($namespace_stmts);
    }
    private static function getFunctionNode(FunctionLikeStorage $function_storage, string $function_name, string $namespace_name) : PhpParser\Node\Stmt\Function_
    {
        $docblock = new ParsedDocblock('', []);
        foreach ($function_storage->template_types ?: [] as $template_name => $map) {
            $type = \array_values($map)[0];
            $docblock->tags['template'][] = $template_name . ' as ' . $type->toNamespacedString($namespace_name, [], null, \false);
        }
        foreach ($function_storage->params as $param) {
            if ($param->type && $param->type !== $param->signature_type) {
                $docblock->tags['param'][] = $param->type->toNamespacedString($namespace_name, [], null, \false) . ' $' . $param->name;
            }
        }
        if ($function_storage->return_type && $function_storage->signature_return_type !== $function_storage->return_type) {
            $docblock->tags['return'][] = $function_storage->return_type->toNamespacedString($namespace_name, [], null, \false);
        }
        foreach ($function_storage->throws ?: [] as $exception_name => $_) {
            $docblock->tags['throws'][] = Type::getStringFromFQCLN($exception_name, $namespace_name, [], null, \false);
        }
        return new VirtualFunction($function_name, ['params' => self::getFunctionParamNodes($function_storage), 'returnType' => $function_storage->signature_return_type ? self::getParserTypeFromPsalmType($function_storage->signature_return_type) : null, 'stmts' => []], ['comments' => $docblock->tags ? [new PhpParser\Comment\Doc(rtrim($docblock->render('        ')))] : []]);
    }
    /**
     * @return list<PhpParser\Node\Param>
     */
    public static function getFunctionParamNodes(FunctionLikeStorage $method_storage) : array
    {
        $param_nodes = [];
        foreach ($method_storage->params as $param) {
            $param_nodes[] = new VirtualParam(new VirtualVariable($param->name), $param->default_type instanceof Union ? self::getExpressionFromType($param->default_type) : null, $param->signature_type ? self::getParserTypeFromPsalmType($param->signature_type) : null, $param->by_ref, $param->is_variadic);
        }
        return $param_nodes;
    }
    /**
     * @return PhpParser\Node\Identifier|PhpParser\Node\Name\FullyQualified|PhpParser\Node\NullableType|null
     */
    public static function getParserTypeFromPsalmType(Union $type) : ?PhpParser\NodeAbstract
    {
        $nullable = $type->isNullable();
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TNull) {
                continue;
            }
            if ($atomic_type instanceof Scalar || $atomic_type instanceof TObject || $atomic_type instanceof TArray || $atomic_type instanceof TIterable) {
                $identifier_string = $atomic_type->toPhpString(null, [], null, 80000);
                if ($identifier_string === null) {
                    throw new UnexpectedValueException($atomic_type->getId() . ' could not be converted to an identifier');
                }
                $identifier = new VirtualIdentifier($identifier_string);
                if ($nullable) {
                    return new VirtualNullableType($identifier);
                }
                return $identifier;
            }
            if ($atomic_type instanceof TNamedObject) {
                $name_node = new VirtualFullyQualified($atomic_type->value);
                if ($nullable) {
                    return new VirtualNullableType($name_node);
                }
                return $name_node;
            }
        }
        return null;
    }
    public static function getExpressionFromType(Union $type) : PhpParser\Node\Expr
    {
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TLiteralClassString) {
                return new VirtualClassConstFetch(new VirtualName('\\' . $atomic_type->value), new VirtualIdentifier('class'));
            }
            if ($atomic_type instanceof TLiteralString) {
                return new VirtualString($atomic_type->value);
            }
            if ($atomic_type instanceof TLiteralInt) {
                return new VirtualLNumber($atomic_type->value);
            }
            if ($atomic_type instanceof TLiteralFloat) {
                return new VirtualDNumber($atomic_type->value);
            }
            if ($atomic_type instanceof TFalse) {
                return new VirtualConstFetch(new VirtualName('false'));
            }
            if ($atomic_type instanceof TTrue) {
                return new VirtualConstFetch(new VirtualName('true'));
            }
            if ($atomic_type instanceof TNull) {
                return new VirtualConstFetch(new VirtualName('null'));
            }
            if ($atomic_type instanceof TArray) {
                return new VirtualArray([]);
            }
            if ($atomic_type instanceof TKeyedArray) {
                $new_items = [];
                foreach ($atomic_type->properties as $property_name => $property_type) {
                    if ($atomic_type->is_list) {
                        $key_type = null;
                    } elseif (is_int($property_name)) {
                        $key_type = new VirtualLNumber($property_name);
                    } else {
                        $key_type = new VirtualString($property_name);
                    }
                    $new_items[] = new VirtualArrayItem(self::getExpressionFromType($property_type), $key_type);
                }
                return new VirtualArray($new_items);
            }
            if ($atomic_type instanceof TEnumCase) {
                return new VirtualClassConstFetch(new VirtualName('\\' . $atomic_type->value), new VirtualIdentifier($atomic_type->case_name));
            }
        }
        return new VirtualString('Psalm could not infer this type');
    }
}
<?php

namespace Psalm\Internal\Provider;

use InvalidArgumentException;
use LogicException;
use Psalm\Storage\ClassLikeStorage;
use function array_merge;
use function strtolower;
/**
 * @internal
 */
class ClassLikeStorageProvider
{
    /**
     * Storing this statically is much faster (at least in PHP 7.2.1)
     *
     * @var array<string, ClassLikeStorage>
     */
    private static array $storage = [];
    /**
     * @var array<string, ClassLikeStorage>
     */
    private static array $new_storage = [];
    public ?\Psalm\Internal\Provider\ClassLikeStorageCacheProvider $cache = null;
    public function __construct(?\Psalm\Internal\Provider\ClassLikeStorageCacheProvider $cache = null)
    {
        $this->cache = $cache;
    }
    /**
     * @psalm-mutation-free
     * @throws InvalidArgumentException when class does not exist
     */
    public function get(string $fq_classlike_name) : ClassLikeStorage
    {
        $fq_classlike_name_lc = strtolower($fq_classlike_name);
        /** @psalm-suppress ImpureStaticProperty Used only for caching */
        if (!isset(self::$storage[$fq_classlike_name_lc])) {
            throw new InvalidArgumentException('Could not get class storage for ' . $fq_classlike_name_lc);
        }
        /** @psalm-suppress ImpureStaticProperty Used only for caching */
        return self::$storage[$fq_classlike_name_lc];
    }
    public function has(string $fq_classlike_name) : bool
    {
        $fq_classlike_name_lc = strtolower($fq_classlike_name);
        return isset(self::$storage[$fq_classlike_name_lc]);
    }
    public function exhume(string $fq_classlike_name, string $file_path, string $file_contents) : ClassLikeStorage
    {
        $fq_classlike_name_lc = strtolower($fq_classlike_name);
        if (isset(self::$storage[$fq_classlike_name_lc])) {
            return self::$storage[$fq_classlike_name_lc];
        }
        if (!$this->cache) {
            throw new LogicException('Cannot exhume when there’s no cache');
        }
        $cached_value = $this->cache->getLatestFromCache($fq_classlike_name_lc, $file_path, $file_contents);
        self::$storage[$fq_classlike_name_lc] = $cached_value;
        self::$new_storage[$fq_classlike_name_lc] = $cached_value;
        return $cached_value;
    }
    /**
     * @return array<string, ClassLikeStorage>
     */
    public function getAll() : array
    {
        return self::$storage;
    }
    /**
     * @return array<string, ClassLikeStorage>
     */
    public function getNew() : array
    {
        return self::$new_storage;
    }
    /**
     * @param array<string, ClassLikeStorage> $more
     */
    public function addMore(array $more) : void
    {
        self::$new_storage = array_merge(self::$new_storage, $more);
        self::$storage = array_merge(self::$storage, $more);
    }
    public function makeNew(string $fq_classlike_name_lc) : void
    {
        self::$new_storage[$fq_classlike_name_lc] = self::$storage[$fq_classlike_name_lc];
    }
    public function create(string $fq_classlike_name) : ClassLikeStorage
    {
        $fq_classlike_name_lc = strtolower($fq_classlike_name);
        $storage = new ClassLikeStorage($fq_classlike_name);
        self::$storage[$fq_classlike_name_lc] = $storage;
        self::$new_storage[$fq_classlike_name_lc] = $storage;
        return $storage;
    }
    public function remove(string $fq_classlike_name) : void
    {
        $fq_classlike_name_lc = strtolower($fq_classlike_name);
        unset(self::$storage[$fq_classlike_name_lc]);
    }
    public static function deleteAll() : void
    {
        self::$storage = [];
        self::$new_storage = [];
    }
    public static function populated() : void
    {
        self::$new_storage = [];
    }
}
<?php

namespace Psalm\Internal\Provider;

use Psalm\Config;
use Psalm\Storage\FileStorage;
use RuntimeException;
use UnexpectedValueException;
use function array_merge;
use function dirname;
use function file_exists;
use function file_put_contents;
use function filemtime;
use function get_class;
use function hash;
use function igbinary_serialize;
use function igbinary_unserialize;
use function is_dir;
use function mkdir;
use function serialize;
use function strtolower;
use function unlink;
use function unserialize;
use const DIRECTORY_SEPARATOR;
use const LOCK_EX;
use const PHP_VERSION_ID;
/**
 * @internal
 */
class FileStorageCacheProvider
{
    private string $modified_timestamps = '';
    private Config $config;
    private const FILE_STORAGE_CACHE_DIRECTORY = 'file_cache';
    public function __construct(Config $config)
    {
        $this->config = $config;
        $storage_dir = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'Storage' . DIRECTORY_SEPARATOR;
        $dependent_files = [$storage_dir . 'FileStorage.php', $storage_dir . 'FunctionLikeStorage.php', $storage_dir . 'ClassLikeStorage.php', $storage_dir . 'MethodStorage.php', $storage_dir . 'FunctionLikeParameter.php'];
        if ($config->eventDispatcher->hasAfterClassLikeVisitHandlers()) {
            $dependent_files = array_merge($dependent_files, $config->plugin_paths);
        }
        foreach ($dependent_files as $dependent_file_path) {
            if (!file_exists($dependent_file_path)) {
                throw new UnexpectedValueException($dependent_file_path . ' must exist');
            }
            $this->modified_timestamps .= ' ' . filemtime($dependent_file_path);
        }
        $this->modified_timestamps .= $this->config->computeHash();
    }
    public function writeToCache(FileStorage $storage, string $file_contents) : void
    {
        $file_path = strtolower($storage->file_path);
        $cache_location = $this->getCacheLocationForPath($file_path, \true);
        $storage->hash = $this->getCacheHash($file_path, $file_contents);
        if ($this->config->use_igbinary) {
            file_put_contents($cache_location, igbinary_serialize($storage), LOCK_EX);
        } else {
            file_put_contents($cache_location, serialize($storage), LOCK_EX);
        }
    }
    public function getLatestFromCache(string $file_path, string $file_contents) : ?FileStorage
    {
        $file_path = strtolower($file_path);
        $cached_value = $this->loadFromCache($file_path);
        if (!$cached_value) {
            return null;
        }
        $cache_hash = $this->getCacheHash($file_path, $file_contents);
        /** @psalm-suppress TypeDoesNotContainType */
        if (@get_class($cached_value) === '__PHP_Incomplete_Class' || $cache_hash !== $cached_value->hash) {
            $this->removeCacheForFile($file_path);
            return null;
        }
        return $cached_value;
    }
    public function removeCacheForFile(string $file_path) : void
    {
        $cache_path = $this->getCacheLocationForPath($file_path);
        if (file_exists($cache_path)) {
            unlink($cache_path);
        }
    }
    private function getCacheHash(string $_unused_file_path, string $file_contents) : string
    {
        // do not concatenate, as $file_contents can be big and performance will be bad
        // the timestamp is only needed if we don't have file contents
        // as same contents should give same results, independent of when file was modified
        $data = $file_contents ? $file_contents : $this->modified_timestamps;
        return PHP_VERSION_ID >= 80100 ? hash('xxh128', $data) : hash('md4', $data);
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    private function loadFromCache(string $file_path) : ?FileStorage
    {
        $cache_location = $this->getCacheLocationForPath($file_path);
        if (file_exists($cache_location)) {
            if ($this->config->use_igbinary) {
                $storage = igbinary_unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location));
                if ($storage instanceof FileStorage) {
                    return $storage;
                }
                return null;
            }
            $storage = unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location));
            if ($storage instanceof FileStorage) {
                return $storage;
            }
            return null;
        }
        return null;
    }
    private function getCacheLocationForPath(string $file_path, bool $create_directory = \false) : string
    {
        $root_cache_directory = $this->config->getCacheDirectory();
        if (!$root_cache_directory) {
            throw new UnexpectedValueException('No cache directory defined');
        }
        $parser_cache_directory = $root_cache_directory . DIRECTORY_SEPARATOR . self::FILE_STORAGE_CACHE_DIRECTORY;
        if ($create_directory && !is_dir($parser_cache_directory)) {
            try {
                if (mkdir($parser_cache_directory, 0777, \true) === \false) {
                    // any other error than directory already exists/permissions issue
                    throw new RuntimeException('Failed to create ' . $parser_cache_directory . ' cache directory for unknown reasons');
                }
            } catch (RuntimeException $e) {
                // Race condition (#4483)
                if (!is_dir($parser_cache_directory)) {
                    // rethrow the error with default message
                    // it contains the reason why creation failed
                    throw $e;
                }
            }
        }
        if (PHP_VERSION_ID >= 80100) {
            $hash = hash('xxh128', $file_path);
        } else {
            $hash = hash('md4', $file_path);
        }
        return $parser_cache_directory . DIRECTORY_SEPARATOR . $hash . ($this->config->use_igbinary ? '-igbinary' : '');
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Plugin\EventHandler\Event\PropertyVisibilityProviderEvent;
use Psalm\Plugin\EventHandler\PropertyVisibilityProviderInterface;
use Psalm\StatementsSource;
use function strtolower;
/**
 * @internal
 */
class PropertyVisibilityProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(PropertyVisibilityProviderEvent): ?bool>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
    }
    /**
     * @param class-string<PropertyVisibilityProviderInterface> $class
     */
    public function registerClass(string $class) : void
    {
        $callable = Closure::fromCallable([$class, 'isPropertyVisible']);
        foreach ($class::getClassLikeNames() as $fq_classlike_name) {
            $this->registerClosure($fq_classlike_name, $callable);
        }
    }
    /**
     * @param Closure(PropertyVisibilityProviderEvent): ?bool $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    public function isPropertyVisible(StatementsSource $source, string $fq_classlike_name, string $property_name, bool $read_mode, Context $context, CodeLocation $code_location) : ?bool
    {
        foreach (self::$handlers[strtolower($fq_classlike_name)] ?? [] as $property_handler) {
            $event = new PropertyVisibilityProviderEvent($source, $fq_classlike_name, $property_name, $read_mode, $context, $code_location);
            $property_visible = $property_handler($event);
            if ($property_visible !== null) {
                return $property_visible;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use RuntimeException;
use function fclose;
use function filesize;
use function flock;
use function fopen;
use function fread;
use function usleep;
use const LOCK_SH;
/**
 * @internal
 */
class Providers
{
    public \Psalm\Internal\Provider\FileProvider $file_provider;
    public ?\Psalm\Internal\Provider\ParserCacheProvider $parser_cache_provider = null;
    public \Psalm\Internal\Provider\FileStorageProvider $file_storage_provider;
    public \Psalm\Internal\Provider\ClassLikeStorageProvider $classlike_storage_provider;
    public \Psalm\Internal\Provider\StatementsProvider $statements_provider;
    public \Psalm\Internal\Provider\FileReferenceProvider $file_reference_provider;
    public ?\Psalm\Internal\Provider\ProjectCacheProvider $project_cache_provider = null;
    public function __construct(\Psalm\Internal\Provider\FileProvider $file_provider, ?\Psalm\Internal\Provider\ParserCacheProvider $parser_cache_provider = null, ?\Psalm\Internal\Provider\FileStorageCacheProvider $file_storage_cache_provider = null, ?\Psalm\Internal\Provider\ClassLikeStorageCacheProvider $classlike_storage_cache_provider = null, ?\Psalm\Internal\Provider\FileReferenceCacheProvider $file_reference_cache_provider = null, ?\Psalm\Internal\Provider\ProjectCacheProvider $project_cache_provider = null)
    {
        $this->file_provider = $file_provider;
        $this->parser_cache_provider = $parser_cache_provider;
        $this->project_cache_provider = $project_cache_provider;
        $this->file_storage_provider = new \Psalm\Internal\Provider\FileStorageProvider($file_storage_cache_provider);
        $this->classlike_storage_provider = new \Psalm\Internal\Provider\ClassLikeStorageProvider($classlike_storage_cache_provider);
        $this->statements_provider = new \Psalm\Internal\Provider\StatementsProvider($file_provider, $parser_cache_provider, $file_storage_cache_provider);
        $this->file_reference_provider = new \Psalm\Internal\Provider\FileReferenceProvider($file_reference_cache_provider);
    }
    public static function safeFileGetContents(string $path) : string
    {
        // no readable validation as that must be done in the caller
        $fp = fopen($path, 'r');
        if ($fp === \false) {
            return '';
        }
        $max_wait_cycles = 5;
        $has_lock = \false;
        while ($max_wait_cycles > 0) {
            if (flock($fp, LOCK_SH)) {
                $has_lock = \true;
                break;
            }
            $max_wait_cycles--;
            usleep(50000);
        }
        if (!$has_lock) {
            fclose($fp);
            throw new RuntimeException('Could not acquire lock for ' . $path);
        }
        $file_size = filesize($path);
        $content = '';
        if ($file_size > 0) {
            $content = (string) fread($fp, $file_size);
        }
        fclose($fp);
        return $content;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Provider\ReturnTypeProvider\PdoStatementSetFetchMode;
use Psalm\Plugin\EventHandler\Event\MethodParamsProviderEvent;
use Psalm\Plugin\EventHandler\MethodParamsProviderInterface;
use Psalm\StatementsSource;
use Psalm\Storage\FunctionLikeParameter;
use function array_values;
use function is_subclass_of;
use function strtolower;
/**
 * @internal
 */
class MethodParamsProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(MethodParamsProviderEvent): ?array<int, FunctionLikeParameter>>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
        $this->registerClass(PdoStatementSetFetchMode::class);
    }
    /**
     * @param class-string $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, MethodParamsProviderInterface::class, \true)) {
            $callable = Closure::fromCallable([$class, 'getMethodParams']);
            foreach ($class::getClassLikeNames() as $fq_classlike_name) {
                $this->registerClosure($fq_classlike_name, $callable);
            }
        }
    }
    /**
     * @param Closure(MethodParamsProviderEvent): ?array<int, FunctionLikeParameter> $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    /**
     * @param ?list<Arg>  $call_args
     * @return  ?list<FunctionLikeParameter>
     */
    public function getMethodParams(string $fq_classlike_name, string $method_name_lowercase, ?array $call_args = null, ?StatementsSource $statements_source = null, ?Context $context = null, ?CodeLocation $code_location = null) : ?array
    {
        foreach (self::$handlers[strtolower($fq_classlike_name)] ?? [] as $class_handler) {
            $event = new MethodParamsProviderEvent($fq_classlike_name, $method_name_lowercase, $call_args, $statements_source, $context, $code_location);
            $result = $class_handler($event);
            if ($result !== null) {
                return array_values($result);
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use Psalm\Context;
use Psalm\Internal\Provider\PropertyTypeProvider\DomDocumentPropertyTypeProvider;
use Psalm\Plugin\EventHandler\Event\PropertyTypeProviderEvent;
use Psalm\Plugin\EventHandler\PropertyTypeProviderInterface;
use Psalm\StatementsSource;
use Psalm\Type\Union;
use function is_subclass_of;
use function strtolower;
/**
 * @internal
 */
class PropertyTypeProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(PropertyTypeProviderEvent): ?Union>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
        $this->registerClass(DomDocumentPropertyTypeProvider::class);
    }
    /**
     * @param class-string $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, PropertyTypeProviderInterface::class, \true)) {
            $callable = Closure::fromCallable([$class, 'getPropertyType']);
            foreach ($class::getClassLikeNames() as $fq_classlike_name) {
                $this->registerClosure($fq_classlike_name, $callable);
            }
        }
    }
    /**
     * @param Closure(PropertyTypeProviderEvent): ?Union $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    public function getPropertyType(string $fq_classlike_name, string $property_name, bool $read_mode, ?StatementsSource $source = null, ?Context $context = null) : ?Union
    {
        if ($source) {
            $source->addSuppressedIssues(['NonInvariantDocblockPropertyType']);
        }
        foreach (self::$handlers[strtolower($fq_classlike_name)] ?? [] as $property_handler) {
            $event = new PropertyTypeProviderEvent($fq_classlike_name, $property_name, $read_mode, $source, $context);
            $property_type = $property_handler($event);
            if ($property_type !== null) {
                return $property_type;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler\Collecting;
use _HumbugBox1cb33d1f20f1\PhpParser\Lexer\Emulative;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use _HumbugBox1cb33d1f20f1\PhpParser\Parser;
use Psalm\CodeLocation\ParseErrorLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Internal\Diff\FileDiffer;
use Psalm\Internal\Diff\FileStatementsDiffer;
use Psalm\Internal\PhpTraverser\CustomTraverser;
use Psalm\Internal\PhpVisitor\CloningVisitor;
use Psalm\Internal\PhpVisitor\PartialParserVisitor;
use Psalm\Internal\PhpVisitor\SimpleNameResolver;
use Psalm\Issue\ParseError;
use Psalm\IssueBuffer;
use Psalm\Progress\Progress;
use Psalm\Progress\VoidProgress;
use Throwable;
use function abs;
use function array_fill_keys;
use function array_intersect_key;
use function array_map;
use function array_merge;
use function count;
use function filemtime;
use function hash;
use function md5;
use function strlen;
use function strpos;
use const PHP_VERSION_ID;
/**
 * @internal
 */
class StatementsProvider
{
    private \Psalm\Internal\Provider\FileProvider $file_provider;
    public ?\Psalm\Internal\Provider\ParserCacheProvider $parser_cache_provider = null;
    /**
     * @var int|bool
     */
    private $this_modified_time;
    private ?\Psalm\Internal\Provider\FileStorageCacheProvider $file_storage_cache_provider = null;
    private \Psalm\Internal\Provider\StatementsVolatileCache $statements_volatile_cache;
    /**
     * @var array<string, array<string, bool>>
     */
    private array $unchanged_members = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private array $unchanged_signature_members = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private array $changed_members = [];
    /**
     * @var array<string, bool>
     */
    private array $errors = [];
    /**
     * @var array<string, array<int, array{int, int, int, int}>>
     */
    private array $diff_map = [];
    /**
     * @var array<string, array<int, array{int, int}>>
     */
    private array $deletion_ranges = [];
    private static ?Emulative $lexer = null;
    private static ?Parser $parser = null;
    public function __construct(\Psalm\Internal\Provider\FileProvider $file_provider, ?\Psalm\Internal\Provider\ParserCacheProvider $parser_cache_provider = null, ?\Psalm\Internal\Provider\FileStorageCacheProvider $file_storage_cache_provider = null)
    {
        $this->file_provider = $file_provider;
        $this->parser_cache_provider = $parser_cache_provider;
        $this->this_modified_time = filemtime(__FILE__);
        $this->file_storage_cache_provider = $file_storage_cache_provider;
        $this->statements_volatile_cache = \Psalm\Internal\Provider\StatementsVolatileCache::getInstance();
    }
    /**
     * @return list<Stmt>
     */
    public function getStatementsForFile(string $file_path, int $analysis_php_version_id, ?Progress $progress = null) : array
    {
        unset($this->errors[$file_path]);
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $from_cache = \false;
        $version = \PHP_PARSER_VERSION . $this->this_modified_time;
        $file_contents = $this->file_provider->getContents($file_path);
        $modified_time = $this->file_provider->getModifiedTime($file_path);
        $config = Config::getInstance();
        if (PHP_VERSION_ID >= 80100) {
            $file_content_hash = hash('xxh128', $version . $file_contents);
        } else {
            $file_content_hash = hash('md4', $version . $file_contents);
        }
        if (!$this->parser_cache_provider || !$config->isInProjectDirs($file_path) && strpos($file_path, 'vendor')) {
            $cache_key = "{$file_content_hash}:{$analysis_php_version_id}";
            if ($this->statements_volatile_cache->has($cache_key)) {
                return $this->statements_volatile_cache->get($cache_key);
            }
            $progress->debug('Parsing ' . $file_path . "\n");
            $has_errors = \false;
            $stmts = self::parseStatements($file_contents, $analysis_php_version_id, $has_errors, $file_path);
            $this->statements_volatile_cache->set($cache_key, $stmts);
            return $stmts;
        }
        $stmts = $this->parser_cache_provider->loadStatementsFromCache($file_path, $modified_time, $file_content_hash);
        if ($stmts === null) {
            $progress->debug('Parsing ' . $file_path . "\n");
            $existing_statements = $this->parser_cache_provider->loadExistingStatementsFromCache($file_path);
            $existing_file_contents = $this->parser_cache_provider->loadExistingFileContentsFromCache($file_path);
            // this happens after editing temporary file
            if ($existing_file_contents === $file_contents && $existing_statements) {
                $this->diff_map[$file_path] = [];
                $this->parser_cache_provider->saveStatementsToCache($file_path, $file_content_hash, $existing_statements, \true);
                return $existing_statements;
            }
            $file_changes = null;
            $existing_statements_copy = null;
            if ($existing_statements && $existing_file_contents && abs(strlen($existing_file_contents) - strlen($file_contents)) < 5000) {
                $file_changes = FileDiffer::getDiff($existing_file_contents, $file_contents);
                if (count($file_changes) < 10) {
                    $traverser = new PhpParser\NodeTraverser();
                    $traverser->addVisitor(new CloningVisitor());
                    // performs a deep clone
                    /** @var list<PhpParser\Node\Stmt> */
                    $existing_statements_copy = $traverser->traverse($existing_statements);
                } else {
                    $file_changes = null;
                }
            }
            $has_errors = \false;
            $stmts = self::parseStatements($file_contents, $analysis_php_version_id, $has_errors, $file_path, $existing_file_contents, $existing_statements_copy, $file_changes);
            if ($existing_file_contents && $existing_statements && (!$has_errors || $stmts)) {
                [$unchanged_members, $unchanged_signature_members, $changed_members, $diff_map, $deletion_ranges] = FileStatementsDiffer::diff($existing_statements, $stmts, $existing_file_contents, $file_contents);
                $unchanged_members = array_fill_keys($unchanged_members, \true);
                $unchanged_signature_members = array_fill_keys($unchanged_signature_members, \true);
                // do NOT change this to hash, it will fail on Windows for whatever reason
                $file_path_hash = md5($file_path);
                $changed_members = array_map(static function (string $key) use($file_path_hash) : string {
                    if (strpos($key, 'use:') === 0) {
                        return $key . ':' . $file_path_hash;
                    }
                    return $key;
                }, $changed_members);
                $changed_members = array_fill_keys($changed_members, \true);
                if (isset($this->unchanged_members[$file_path])) {
                    $this->unchanged_members[$file_path] = array_intersect_key($this->unchanged_members[$file_path], $unchanged_members);
                } else {
                    $this->unchanged_members[$file_path] = $unchanged_members;
                }
                if (isset($this->unchanged_signature_members[$file_path])) {
                    $this->unchanged_signature_members[$file_path] = array_intersect_key($this->unchanged_signature_members[$file_path], $unchanged_signature_members);
                } else {
                    $this->unchanged_signature_members[$file_path] = $unchanged_signature_members;
                }
                if (isset($this->changed_members[$file_path])) {
                    $this->changed_members[$file_path] = array_merge($this->changed_members[$file_path], $changed_members);
                } else {
                    $this->changed_members[$file_path] = $changed_members;
                }
                $this->diff_map[$file_path] = $diff_map;
                $this->deletion_ranges[$file_path] = $deletion_ranges;
            } elseif ($has_errors && !$stmts) {
                $this->errors[$file_path] = \true;
            }
            if ($this->file_storage_cache_provider) {
                $this->file_storage_cache_provider->removeCacheForFile($file_path);
            }
            $this->parser_cache_provider->cacheFileContents($file_path, $file_contents);
        } else {
            $from_cache = \true;
            $this->diff_map[$file_path] = [];
            $this->deletion_ranges[$file_path] = [];
        }
        $this->parser_cache_provider->saveStatementsToCache($file_path, $file_content_hash, $stmts, $from_cache);
        if (!$stmts) {
            return [];
        }
        return $stmts;
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getChangedMembers() : array
    {
        return $this->changed_members;
    }
    /**
     * @param array<string, array<string, bool>> $more_changed_members
     */
    public function addChangedMembers(array $more_changed_members) : void
    {
        $this->changed_members = array_merge($more_changed_members, $this->changed_members);
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getUnchangedSignatureMembers() : array
    {
        return $this->unchanged_signature_members;
    }
    /**
     * @param array<string, array<string, bool>> $more_unchanged_members
     */
    public function addUnchangedSignatureMembers(array $more_unchanged_members) : void
    {
        $this->unchanged_signature_members = array_merge($more_unchanged_members, $this->unchanged_signature_members);
    }
    /**
     * @return array<string, bool>
     */
    public function getErrors() : array
    {
        return $this->errors;
    }
    /**
     * @param array<string, bool> $errors
     */
    public function addErrors(array $errors) : void
    {
        $this->errors += $errors;
    }
    public function setUnchangedFile(string $file_path) : void
    {
        if (!isset($this->diff_map[$file_path])) {
            $this->diff_map[$file_path] = [];
        }
        if (!isset($this->deletion_ranges[$file_path])) {
            $this->deletion_ranges[$file_path] = [];
        }
    }
    /**
     * @return array<string, array<int, array{int, int, int, int}>>
     */
    public function getDiffMap() : array
    {
        return $this->diff_map;
    }
    /**
     * @return array<string, array<int, array{int, int}>>
     */
    public function getDeletionRanges() : array
    {
        return $this->deletion_ranges;
    }
    /**
     * @param array<string, array<int, array{int, int, int, int}>> $diff_map
     */
    public function addDiffMap(array $diff_map) : void
    {
        $this->diff_map = array_merge($diff_map, $this->diff_map);
    }
    /**
     * @param array<string, array<int, array{int, int}>> $deletion_ranges
     */
    public function addDeletionRanges(array $deletion_ranges) : void
    {
        $this->deletion_ranges = array_merge($deletion_ranges, $this->deletion_ranges);
    }
    public function resetDiffs() : void
    {
        $this->changed_members = [];
        $this->unchanged_members = [];
        $this->unchanged_signature_members = [];
        $this->diff_map = [];
        $this->deletion_ranges = [];
    }
    /**
     * @param  list<Stmt> $existing_statements
     * @param  array<int, array{0: int, 1: int, 2: int, 3: int, 4: int, 5: string}> $file_changes
     * @return list<Stmt>
     */
    public static function parseStatements(string $file_contents, int $analysis_php_version_id, bool &$has_errors, ?string $file_path = null, ?string $existing_file_contents = null, ?array $existing_statements = null, ?array $file_changes = null) : array
    {
        $attributes = ['comments', 'startLine', 'startFilePos', 'endFilePos'];
        if (!self::$lexer) {
            $major_version = Codebase::transformPhpVersionId($analysis_php_version_id, 10000);
            $minor_version = Codebase::transformPhpVersionId($analysis_php_version_id % 10000, 100);
            self::$lexer = new Emulative(['usedAttributes' => $attributes, 'phpVersion' => $major_version . '.' . $minor_version]);
        }
        if (!self::$parser) {
            self::$parser = (new PhpParser\ParserFactory())->create(PhpParser\ParserFactory::ONLY_PHP7, self::$lexer);
        }
        $used_cached_statements = \false;
        $error_handler = new Collecting();
        if ($existing_statements && $file_changes && $existing_file_contents) {
            $clashing_traverser = new CustomTraverser();
            $offset_analyzer = new PartialParserVisitor(self::$parser, $error_handler, $file_changes, $existing_file_contents, $file_contents);
            $clashing_traverser->addVisitor($offset_analyzer);
            $clashing_traverser->traverse($existing_statements);
            if (!$offset_analyzer->mustRescan()) {
                $used_cached_statements = \true;
                $stmts = $existing_statements;
            } else {
                try {
                    /** @var list<Stmt> */
                    $stmts = self::$parser->parse($file_contents, $error_handler) ?: [];
                } catch (Throwable $t) {
                    $stmts = [];
                    // hope this got caught below
                }
            }
        } else {
            try {
                /** @var list<Stmt> */
                $stmts = self::$parser->parse($file_contents, $error_handler) ?: [];
            } catch (Throwable $t) {
                $stmts = [];
                // hope this got caught below
            }
        }
        if ($error_handler->hasErrors() && $file_path) {
            $config = Config::getInstance();
            $has_errors = \true;
            foreach ($error_handler->getErrors() as $error) {
                if ($error->hasColumnInfo()) {
                    IssueBuffer::maybeAdd(new ParseError($error->getMessage(), new ParseErrorLocation($error, $file_contents, $file_path, $config->shortenFileName($file_path))));
                }
            }
        }
        $error_handler->clearErrors();
        $resolving_traverser = new PhpParser\NodeTraverser();
        $name_resolver = new SimpleNameResolver($error_handler, $used_cached_statements ? $file_changes : []);
        $resolving_traverser->addVisitor($name_resolver);
        $resolving_traverser->traverse($stmts);
        return $stmts;
    }
    public static function clearLexer() : void
    {
        self::$lexer = null;
    }
    public static function clearParser() : void
    {
        self::$parser = null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayChunkReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayColumnReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayCombineReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayFillKeysReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayFillReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayFilterReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayMapReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayMergeReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayPadReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayPointerAdjustmentReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayPopReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayRandReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayReduceReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayReverseReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArraySliceReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArraySpliceReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArrayUniqueReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\BasenameReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\DirnameReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\FilterVarReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\FirstArgStringReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\GetClassMethodsReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\GetObjectVarsReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\HexdecReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\InArrayReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\IteratorToArrayReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\MbInternalEncodingReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\MinMaxReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\MktimeReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ParseUrlReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\RandReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\RoundReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\StrReplaceReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\StrTrReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\TriggerErrorReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\VersionCompareReturnTypeProvider;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\StatementsSource;
use Psalm\Type\Union;
use function is_subclass_of;
use function strtolower;
/**
 * @internal
 */
class FunctionReturnTypeProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(FunctionReturnTypeProviderEvent): ?Union>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
        $this->registerClass(ArrayChunkReturnTypeProvider::class);
        $this->registerClass(ArrayColumnReturnTypeProvider::class);
        $this->registerClass(ArrayCombineReturnTypeProvider::class);
        $this->registerClass(ArrayFilterReturnTypeProvider::class);
        $this->registerClass(ArrayMapReturnTypeProvider::class);
        $this->registerClass(ArrayMergeReturnTypeProvider::class);
        $this->registerClass(ArrayPadReturnTypeProvider::class);
        $this->registerClass(ArrayPointerAdjustmentReturnTypeProvider::class);
        $this->registerClass(ArrayPopReturnTypeProvider::class);
        $this->registerClass(ArrayRandReturnTypeProvider::class);
        $this->registerClass(ArrayReduceReturnTypeProvider::class);
        $this->registerClass(ArraySliceReturnTypeProvider::class);
        $this->registerClass(ArraySpliceReturnTypeProvider::class);
        $this->registerClass(ArrayReverseReturnTypeProvider::class);
        $this->registerClass(ArrayUniqueReturnTypeProvider::class);
        $this->registerClass(ArrayFillReturnTypeProvider::class);
        $this->registerClass(ArrayFillKeysReturnTypeProvider::class);
        $this->registerClass(FilterVarReturnTypeProvider::class);
        $this->registerClass(IteratorToArrayReturnTypeProvider::class);
        $this->registerClass(ParseUrlReturnTypeProvider::class);
        $this->registerClass(StrReplaceReturnTypeProvider::class);
        $this->registerClass(StrTrReturnTypeProvider::class);
        $this->registerClass(VersionCompareReturnTypeProvider::class);
        $this->registerClass(MktimeReturnTypeProvider::class);
        $this->registerClass(BasenameReturnTypeProvider::class);
        $this->registerClass(DirnameReturnTypeProvider::class);
        $this->registerClass(GetObjectVarsReturnTypeProvider::class);
        $this->registerClass(GetClassMethodsReturnTypeProvider::class);
        $this->registerClass(FirstArgStringReturnTypeProvider::class);
        $this->registerClass(HexdecReturnTypeProvider::class);
        $this->registerClass(MinMaxReturnTypeProvider::class);
        $this->registerClass(TriggerErrorReturnTypeProvider::class);
        $this->registerClass(RandReturnTypeProvider::class);
        $this->registerClass(InArrayReturnTypeProvider::class);
        $this->registerClass(RoundReturnTypeProvider::class);
        $this->registerClass(MbInternalEncodingReturnTypeProvider::class);
    }
    /**
     * @param class-string $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, FunctionReturnTypeProviderInterface::class, \true)) {
            $callable = Closure::fromCallable([$class, 'getFunctionReturnType']);
            foreach ($class::getFunctionIds() as $function_id) {
                $this->registerClosure($function_id, $callable);
            }
        }
    }
    /**
     * @param lowercase-string $function_id
     * @param Closure(FunctionReturnTypeProviderEvent): ?Union $c
     */
    public function registerClosure(string $function_id, Closure $c) : void
    {
        self::$handlers[$function_id][] = $c;
    }
    public function has(string $function_id) : bool
    {
        return isset(self::$handlers[strtolower($function_id)]);
    }
    /**
     * @param  non-empty-string $function_id
     */
    public function getReturnType(StatementsSource $statements_source, string $function_id, PhpParser\Node\Expr\FuncCall $stmt, Context $context, CodeLocation $code_location) : ?Union
    {
        foreach (self::$handlers[strtolower($function_id)] ?? [] as $function_handler) {
            $event = new FunctionReturnTypeProviderEvent($statements_source, $function_id, $stmt, $context, $code_location);
            $return_type = $function_handler($event);
            if ($return_type) {
                return $return_type;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\AddRemoveTaints;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\AddTaintsInterface;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Plugin\EventHandler\RemoveTaintsInterface;
use function count;
use function strtolower;
use const ENT_QUOTES;
/**
 * @internal
 */
class HtmlFunctionTainter implements AddTaintsInterface, RemoveTaintsInterface
{
    /**
     * Called to see what taints should be added
     *
     * @return list<string>
     */
    public static function addTaints(AddRemoveTaintsEvent $event) : array
    {
        $item = $event->getExpr();
        $statements_analyzer = $event->getStatementsSource();
        if (!$statements_analyzer instanceof StatementsAnalyzer || !$item instanceof PhpParser\Node\Expr\FuncCall || $item->isFirstClassCallable() || !$item->name instanceof PhpParser\Node\Name || count($item->name->parts) !== 1 || count($item->getArgs()) === 0) {
            return [];
        }
        $function_id = strtolower($item->name->parts[0]);
        if ($function_id === 'html_entity_decode' || $function_id === 'htmlspecialchars_decode') {
            $second_arg = $item->getArgs()[1]->value ?? null;
            if ($second_arg === null) {
                return ['html'];
            }
            $second_arg_value = $statements_analyzer->node_data->getType($second_arg);
            if (!$second_arg_value || !$second_arg_value->isSingleIntLiteral()) {
                return ['html'];
            }
            $second_arg_value = $second_arg_value->getSingleIntLiteral()->value;
            if (($second_arg_value & ENT_QUOTES) === ENT_QUOTES) {
                return ['html', 'has_quotes'];
            }
            return ['html'];
        }
        return [];
    }
    /**
     * Called to see what taints should be removed
     *
     * @return list<string>
     */
    public static function removeTaints(AddRemoveTaintsEvent $event) : array
    {
        $item = $event->getExpr();
        $statements_analyzer = $event->getStatementsSource();
        if (!$statements_analyzer instanceof StatementsAnalyzer || !$item instanceof PhpParser\Node\Expr\FuncCall || $item->isFirstClassCallable() || !$item->name instanceof PhpParser\Node\Name || count($item->name->parts) !== 1 || count($item->getArgs()) === 0) {
            return [];
        }
        $function_id = strtolower($item->name->parts[0]);
        if ($function_id === 'htmlentities' || $function_id === 'htmlspecialchars') {
            $second_arg = $item->getArgs()[1]->value ?? null;
            if ($second_arg === null) {
                return ['html'];
            }
            $second_arg_value = $statements_analyzer->node_data->getType($second_arg);
            if (!$second_arg_value || !$second_arg_value->isSingleIntLiteral()) {
                return ['html'];
            }
            $second_arg_value = $second_arg_value->getSingleIntLiteral()->value;
            if (($second_arg_value & ENT_QUOTES) === ENT_QUOTES) {
                return ['html', 'has_quotes'];
            }
            return ['html'];
        }
        return [];
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Type\ArrayType;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
use function count;
/**
 * @internal
 */
class ArrayPadReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_pad'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $type_provider = $statements_source->getNodeTypeProvider();
        if (count($call_args) >= 3 && ($array_arg_type = $type_provider->getType($call_args[0]->value)) && ($size_arg_type = $type_provider->getType($call_args[1]->value)) && ($value_arg_type = $type_provider->getType($call_args[2]->value)) && $array_arg_type->isSingle() && $array_arg_type->hasArray() && ($array_type = ArrayType::infer($array_arg_type->getArray()))) {
            $codebase = $statements_source->getCodebase();
            $key_type = Type::combineUnionTypes($array_type->key, Type::getInt(), $codebase);
            $value_type = Type::combineUnionTypes($array_type->value, $value_arg_type, $codebase);
            $can_return_empty = !$size_arg_type->isSingleIntLiteral() || $size_arg_type->getSingleIntLiteral()->value === 0;
            return new Union([$array_type->is_list ? $can_return_empty ? Type::getListAtomic($value_type) : Type::getNonEmptyListAtomic($value_type) : ($can_return_empty ? new TArray([$key_type, $value_type]) : new TNonEmptyArray([$key_type, $value_type]))]);
        }
        return Type::getArray();
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Union;
/**
 * @internal
 */
class GetClassMethodsReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['get_class_methods'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer || !$call_args) {
            return Type::getMixed();
        }
        if (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value)) && ($first_arg_type->hasObjectType() || $first_arg_type->hasString())) {
            return Type::parseString('array<string>');
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ArrayFetchAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_merge;
use function array_shift;
use function in_array;
/**
 * @internal
 */
class ArrayPointerAdjustmentReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * These functions are already handled by the CoreGenericFunctions stub
     */
    const IGNORE_FUNCTION_IDS_FOR_FALSE_RETURN_TYPE = ['reset', 'end', 'current'];
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['current', 'next', 'prev', 'reset', 'end'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $function_id = $event->getFunctionId();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $first_arg = $call_args[0]->value ?? null;
        if (!$first_arg) {
            return Type::getMixed();
        }
        $first_arg_type = $statements_source->node_data->getType($first_arg);
        if (!$first_arg_type) {
            return Type::getMixed();
        }
        $atomic_types = $first_arg_type->getAtomicTypes();
        $value_type = null;
        $definitely_has_items = \false;
        while ($atomic_type = array_shift($atomic_types)) {
            if ($atomic_type instanceof TTemplateParam) {
                $atomic_types = array_merge($atomic_types, $atomic_type->as->getAtomicTypes());
                continue;
            }
            if ($atomic_type instanceof TList) {
                $atomic_type = $atomic_type->getKeyedArray();
            }
            if ($atomic_type instanceof TArray) {
                $value_type = $atomic_type->type_params[1];
                $definitely_has_items = $atomic_type instanceof TNonEmptyArray;
            } elseif ($atomic_type instanceof TKeyedArray) {
                $value_type = $atomic_type->getGenericValueType();
                $definitely_has_items = $atomic_type->getGenericArrayType() instanceof TNonEmptyArray;
            } else {
                return Type::getMixed();
            }
        }
        if (!$value_type) {
            throw new UnexpectedValueException('This should never happen');
        }
        if ($value_type->isNever()) {
            $value_type = Type::getFalse();
        } elseif (!$definitely_has_items || self::isFunctionAlreadyHandledByStub($function_id)) {
            $value_type = $value_type->getBuilder()->addType(new TFalse());
            $codebase = $statements_source->getCodebase();
            if ($codebase->config->ignore_internal_falsable_issues) {
                $value_type->ignore_falsable_issues = \true;
            }
            $value_type = $value_type->freeze();
        }
        $temp = Type::getMixed();
        ArrayFetchAnalyzer::taintArrayFetch($statements_source, $first_arg, null, $value_type, $temp);
        return $value_type;
    }
    private static function isFunctionAlreadyHandledByStub(string $function_id) : bool
    {
        return !in_array($function_id, self::IGNORE_FUNCTION_IDS_FOR_FALSE_RETURN_TYPE, \true);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\MethodParamsProviderEvent;
use Psalm\Plugin\EventHandler\MethodParamsProviderInterface;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
/**
 * @internal
 */
class PdoStatementSetFetchMode implements MethodParamsProviderInterface
{
    public static function getClassLikeNames() : array
    {
        return ['PDOStatement'];
    }
    /**
     * @return ?array<int, FunctionLikeParameter>
     */
    public static function getMethodParams(MethodParamsProviderEvent $event) : ?array
    {
        $statements_source = $event->getStatementsSource();
        $method_name_lowercase = $event->getMethodNameLowercase();
        $context = $event->getContext();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return null;
        }
        if ($method_name_lowercase === 'setfetchmode') {
            if (!$context || !$call_args || ExpressionAnalyzer::analyze($statements_source, $call_args[0]->value, $context) === \false) {
                return null;
            }
            if (($first_call_arg_type = $statements_source->node_data->getType($call_args[0]->value)) && $first_call_arg_type->isSingleIntLiteral()) {
                $params = [new FunctionLikeParameter('mode', \false, Type::getInt(), Type::getInt(), null, null, \false)];
                $value = $first_call_arg_type->getSingleIntLiteral()->value;
                switch ($value) {
                    case 7:
                        // PDO::FETCH_COLUMN
                        $params[] = new FunctionLikeParameter('colno', \false, Type::getInt(), Type::getInt(), null, null, \false);
                        break;
                    case 8:
                        // PDO::FETCH_CLASS
                        $params[] = new FunctionLikeParameter('classname', \false, Type::getClassString(), Type::getClassString(), null, null, \false);
                        $params[] = new FunctionLikeParameter('ctorargs', \false, Type::getArray(), Type::getArray(), null, null, \true);
                        break;
                    case 9:
                        // PDO::FETCH_INTO
                        $params[] = new FunctionLikeParameter('object', \false, Type::getObject(), Type::getObject(), null, null, \false);
                        break;
                }
                return $params;
            }
        }
        return null;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassAnalyzer;
use Psalm\Internal\Analyzer\SourceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Union;
use UnitEnum;
use stdClass;
use function is_int;
use function is_string;
use function reset;
use function strtolower;
/**
 * @internal
 */
class GetObjectVarsReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    public static function getFunctionIds() : array
    {
        return ['get_object_vars'];
    }
    private static ?TArray $fallback = null;
    /**
     * @return TArray|TKeyedArray
     */
    public static function getGetObjectVarsReturnType(Union $first_arg_type, SourceAnalyzer $statements_source, Context $context, CodeLocation $location) : Atomic
    {
        self::$fallback ??= new TArray([Type::getString(), Type::getMixed()]);
        if ($first_arg_type->isSingle()) {
            $atomics = $first_arg_type->getAtomicTypes();
            $object_type = reset($atomics);
            if ($object_type instanceof Atomic\TEnumCase) {
                $properties = ['name' => new Union([new Atomic\TLiteralString($object_type->case_name)])];
                $codebase = $statements_source->getCodebase();
                $enum_classlike_storage = $codebase->classlike_storage_provider->get($object_type->value);
                if ($enum_classlike_storage->enum_type === null) {
                    return new TKeyedArray($properties);
                }
                $enum_case_storage = $enum_classlike_storage->enum_cases[$object_type->case_name];
                if (is_int($enum_case_storage->value)) {
                    $properties['value'] = new Union([new Atomic\TLiteralInt($enum_case_storage->value)]);
                } elseif (is_string($enum_case_storage->value)) {
                    $properties['value'] = new Union([new Atomic\TLiteralString($enum_case_storage->value)]);
                }
                return new TKeyedArray($properties);
            }
            if ($object_type instanceof TObjectWithProperties) {
                if ([] === $object_type->properties) {
                    return self::$fallback;
                }
                return new TKeyedArray($object_type->properties);
            }
            if ($object_type instanceof TNamedObject) {
                if (strtolower($object_type->value) === strtolower(stdClass::class)) {
                    return self::$fallback;
                }
                $codebase = $statements_source->getCodebase();
                $class_storage = $codebase->classlikes->getStorageFor($object_type->value);
                if (null === $class_storage) {
                    return self::$fallback;
                }
                if ([] === $class_storage->appearing_property_ids) {
                    if ($class_storage->final) {
                        return Type::getEmptyArrayAtomic();
                    }
                    return self::$fallback;
                }
                $properties = [];
                foreach ($class_storage->appearing_property_ids as $name => $property_id) {
                    if (ClassAnalyzer::checkPropertyVisibility($property_id, $context, $statements_source, $location, $statements_source->getSuppressedIssues(), \false) === \true) {
                        $property_type = $codebase->properties->getPropertyType($property_id, \false, $statements_source, $context);
                        if (!$property_type) {
                            continue;
                        }
                        $property_type = $object_type instanceof TGenericObject ? AtomicPropertyFetchAnalyzer::localizePropertyType($codebase, $property_type, $object_type, $class_storage, $class_storage) : $property_type;
                        $properties[$name] = $property_type;
                    }
                }
                if ([] === $properties) {
                    if ($class_storage->final) {
                        return Type::getEmptyArrayAtomic();
                    }
                    return self::$fallback;
                }
                return new TKeyedArray($properties, null, $class_storage->final || $class_storage->name === UnitEnum::class || $codebase->interfaceExtends($class_storage->name, UnitEnum::class) ? null : [Type::getString(), Type::getMixed()]);
            }
        }
        return self::$fallback;
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer || !$call_args) {
            return Type::getMixed();
        }
        if (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value)) && $first_arg_type->isObjectType()) {
            return new Union([self::getGetObjectVarsReturnType($first_arg_type, $statements_source, $event->getContext(), $event->getCodeLocation())]);
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Union;
use function count;
/**
 * @internal
 */
class SimpleXmlElementAsXml implements MethodReturnTypeProviderInterface
{
    public static function getClassLikeNames() : array
    {
        return ['SimpleXMLElement'];
    }
    public static function getMethodReturnType(MethodReturnTypeProviderEvent $event) : ?Union
    {
        $call_args = $event->getCallArgs();
        $method_name_lowercase = $event->getMethodNameLowercase();
        if ($method_name_lowercase === 'asxml' && !count($call_args)) {
            return Type::parseString('string|false');
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Union;
use function count;
/**
 * @internal
 */
class ArrayFillKeysReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_fill_keys'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        if (count($call_args) !== 2) {
            return Type::getNever();
        }
        $first_arg_type = isset($call_args[0]) ? $statements_source->node_data->getType($call_args[0]->value) : null;
        $second_arg_type = isset($call_args[1]) ? $statements_source->node_data->getType($call_args[1]->value) : null;
        if ($first_arg_type && $first_arg_type->isArray() && $second_arg_type) {
            $array = $first_arg_type->getArray();
            if ($array instanceof TArray && $array->isEmptyArray()) {
                return $first_arg_type;
            } elseif ($array instanceof TKeyedArray && !$array->fallback_params) {
                $is_list = $array->is_list;
                $array = $array->properties;
            } else {
                return null;
            }
            $result = [];
            $prev_key = -1;
            $had_possibly_undefined = \false;
            foreach ($array as $key_k) {
                if ($had_possibly_undefined && !$key_k->possibly_undefined) {
                    $is_list = \false;
                }
                $had_possibly_undefined = $had_possibly_undefined || $key_k->possibly_undefined;
                if ($key_k->isSingleIntLiteral()) {
                    $key = $key_k->getSingleIntLiteral()->value;
                    if ($prev_key !== $key - 1) {
                        $is_list = \false;
                    }
                    $prev_key = $key;
                } elseif ($key_k->isSingleStringLiteral()) {
                    $key = $key_k->getSingleStringLiteral()->value;
                    $is_list = \false;
                } else {
                    return null;
                }
                $result[$key] = $second_arg_type->setPossiblyUndefined($key_k->possibly_undefined);
            }
            return new Union([new TKeyedArray($result, null, null, $is_list)]);
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\InvalidArgument;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use function count;
use function explode;
use function in_array;
use function reset;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class ArrayReduceReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_reduce'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $context = $event->getContext();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        if (!isset($call_args[0]) || !isset($call_args[1])) {
            return Type::getMixed();
        }
        $codebase = $statements_source->getCodebase();
        $array_arg = $call_args[0]->value;
        $function_call_arg = $call_args[1]->value;
        $array_arg_type = $statements_source->node_data->getType($array_arg);
        $function_call_arg_type = $statements_source->node_data->getType($function_call_arg);
        if (!$array_arg_type || !$function_call_arg_type) {
            return Type::getMixed();
        }
        $array_arg_types = $array_arg_type->getAtomicTypes();
        $array_arg_atomic_type = null;
        if (isset($array_arg_types['array']) && ($array_arg_types['array'] instanceof TArray || $array_arg_types['array'] instanceof TList || $array_arg_types['array'] instanceof TKeyedArray)) {
            $array_arg_atomic_type = $array_arg_types['array'];
            if ($array_arg_atomic_type instanceof TList) {
                $array_arg_atomic_type = $array_arg_atomic_type->getKeyedArray();
            }
            if ($array_arg_atomic_type instanceof TKeyedArray) {
                $array_arg_atomic_type = $array_arg_atomic_type->getGenericArrayType();
            }
        }
        if (!isset($call_args[2])) {
            $reduce_return_type = new Union([new TNull()], ['ignore_nullable_issues' => \true]);
        } else {
            $reduce_return_type = $statements_source->node_data->getType($call_args[2]->value);
            if (!$reduce_return_type) {
                return Type::getMixed();
            }
            if ($reduce_return_type->hasMixed()) {
                return Type::getMixed();
            }
        }
        $initial_type = $reduce_return_type;
        $closure_types = $function_call_arg_type->getClosureTypes() ?: $function_call_arg_type->getCallableTypes();
        if ($closure_types) {
            $closure_atomic_type = reset($closure_types);
            $closure_return_type = $closure_atomic_type->return_type ?: Type::getMixed();
            if ($closure_return_type->isVoid()) {
                $closure_return_type = Type::getNull();
            }
            $reduce_return_type = Type::combineUnionTypes($closure_return_type, $reduce_return_type);
            if ($closure_atomic_type->params !== null) {
                if (count($closure_atomic_type->params) < 1) {
                    IssueBuffer::maybeAdd(new InvalidArgument('The closure passed to array_reduce at least one parameter', new CodeLocation($statements_source, $function_call_arg)), $statements_source->getSuppressedIssues());
                    return Type::getMixed();
                }
                $carry_param = $closure_atomic_type->params[0];
                $item_param = $closure_atomic_type->params[1] ?? null;
                if ($carry_param->type && (!UnionTypeComparator::isContainedBy($codebase, $initial_type, $carry_param->type) || !$reduce_return_type->hasMixed() && !UnionTypeComparator::isContainedBy($codebase, $reduce_return_type, $carry_param->type))) {
                    IssueBuffer::maybeAdd(new InvalidArgument('The first param of the closure passed to array_reduce must take ' . $reduce_return_type . ' but only accepts ' . $carry_param->type, $carry_param->type_location ?: new CodeLocation($statements_source, $function_call_arg)), $statements_source->getSuppressedIssues());
                    return Type::getMixed();
                }
                if ($item_param && $item_param->type && $array_arg_atomic_type && !$array_arg_atomic_type->type_params[1]->hasMixed() && !UnionTypeComparator::isContainedBy($codebase, $array_arg_atomic_type->type_params[1], $item_param->type)) {
                    IssueBuffer::maybeAdd(new InvalidArgument('The second param of the closure passed to array_reduce must take ' . $array_arg_atomic_type->type_params[1] . ' but only accepts ' . $item_param->type, $item_param->type_location ?: new CodeLocation($statements_source, $function_call_arg)), $statements_source->getSuppressedIssues());
                    return Type::getMixed();
                }
            }
            return $reduce_return_type;
        }
        if ($function_call_arg instanceof PhpParser\Node\Scalar\String_ || $function_call_arg instanceof PhpParser\Node\Expr\Array_ || $function_call_arg instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
            $mapping_function_ids = CallAnalyzer::getFunctionIdsFromCallableArg($statements_source, $function_call_arg);
            $call_map = InternalCallMapHandler::getCallMap();
            foreach ($mapping_function_ids as $mapping_function_id) {
                $mapping_function_id_parts = explode('&', $mapping_function_id);
                $part_match_found = \false;
                foreach ($mapping_function_id_parts as $mapping_function_id_part) {
                    if (isset($call_map[$mapping_function_id_part][0])) {
                        if ($call_map[$mapping_function_id_part][0]) {
                            $mapped_function_return = Type::parseString($call_map[$mapping_function_id_part][0]);
                            $reduce_return_type = Type::combineUnionTypes($reduce_return_type, $mapped_function_return);
                            $part_match_found = \true;
                        }
                    } elseif ($mapping_function_id_part) {
                        if (strpos($mapping_function_id_part, '::') !== \false) {
                            if ($mapping_function_id_part[0] === '$') {
                                $mapping_function_id_part = substr($mapping_function_id_part, 1);
                            }
                            [$callable_fq_class_name, $method_name] = explode('::', $mapping_function_id_part);
                            if (in_array($callable_fq_class_name, ['self', 'static'], \true)) {
                                $callable_fq_class_name = $statements_source->getFQCLN();
                                if ($callable_fq_class_name === null) {
                                    continue;
                                }
                            }
                            if ($callable_fq_class_name === 'parent') {
                                continue;
                            }
                            $method_id = new MethodIdentifier($callable_fq_class_name, strtolower($method_name));
                            if (!$codebase->methods->methodExists($method_id, !$context->collect_initializations && !$context->collect_mutations ? $context->calling_method_id : null, $codebase->collect_locations ? new CodeLocation($statements_source, $function_call_arg) : null, null, $statements_source->getFilePath())) {
                                continue;
                            }
                            $part_match_found = \true;
                            $self_class = 'self';
                            $return_type = $codebase->methods->getMethodReturnType($method_id, $self_class) ?? Type::getMixed();
                        } else {
                            if (!$codebase->functions->functionExists($statements_source, strtolower($mapping_function_id_part))) {
                                return Type::getMixed();
                            }
                            $part_match_found = \true;
                            $function_storage = $codebase->functions->getStorage($statements_source, strtolower($mapping_function_id_part));
                            $return_type = $function_storage->return_type ?: Type::getMixed();
                        }
                        $reduce_return_type = Type::combineUnionTypes($reduce_return_type, $return_type);
                    }
                }
                if ($part_match_found === \false) {
                    return Type::getMixed();
                }
            }
            return $reduce_return_type;
        }
        return Type::getMixed();
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\Statements\Expression\IncludeAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Union;
use function array_values;
use function count;
use function dirname;
/**
 * @internal
 */
class DirnameReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['dirname'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $call_args = $event->getCallArgs();
        if (count($call_args) === 0) {
            return null;
        }
        $statements_source = $event->getStatementsSource();
        $node_type_provider = $statements_source->getNodeTypeProvider();
        $dir_level = 1;
        if (isset($call_args[1])) {
            $type = $node_type_provider->getType($call_args[1]->value);
            if ($type !== null && $type->isSingle()) {
                $atomic_type = array_values($type->getAtomicTypes())[0];
                if ($atomic_type instanceof TLiteralInt && $atomic_type->value > 0) {
                    $dir_level = $atomic_type->value;
                } else {
                    return Type::getString();
                }
            }
        }
        $evaled_path = IncludeAnalyzer::getPathTo($call_args[0]->value, null, null, $statements_source->getFileName(), $statements_source->getCodebase()->config);
        if ($evaled_path === null) {
            return Type::getString();
        }
        $path_to_file = dirname($evaled_path, $dir_level);
        return Type::getString($path_to_file);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\Statements\Expression\IncludeAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Union;
use function basename;
use function count;
/**
 * @internal
 */
class BasenameReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['basename'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $call_args = $event->getCallArgs();
        if (count($call_args) === 0) {
            return null;
        }
        $statements_source = $event->getStatementsSource();
        $evaled_path = IncludeAnalyzer::getPathTo($call_args[0]->value, null, null, $statements_source->getFileName(), $statements_source->getCodebase()->config);
        if ($evaled_path === null) {
            return Type::getString();
        }
        $basename = basename($evaled_path);
        return Type::getString($basename);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Type\Comparator\AtomicTypeComparator;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_merge;
use function array_shift;
use function assert;
/**
 * @internal
 */
class IteratorToArrayReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['iterator_to_array'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $function_id = $event->getFunctionId();
        $context = $event->getContext();
        if (!$statements_source instanceof StatementsAnalyzer || !$call_args) {
            return Type::getMixed();
        }
        if ($first_arg_type = $statements_source->node_data->getType($call_args[0]->value)) {
            $key_type = null;
            $value_type = null;
            $codebase = $statements_source->getCodebase();
            $atomic_types = $first_arg_type->getAtomicTypes();
            while ($call_arg_atomic_type = array_shift($atomic_types)) {
                if ($call_arg_atomic_type instanceof TTemplateParam) {
                    $atomic_types = array_merge($atomic_types, $call_arg_atomic_type->as->getAtomicTypes());
                    continue;
                }
                if ($call_arg_atomic_type instanceof TNamedObject && AtomicTypeComparator::isContainedBy($codebase, $call_arg_atomic_type, new TIterable([Type::getMixed(), Type::getMixed()]))) {
                    $has_valid_iterator = \true;
                    ForeachAnalyzer::handleIterable($statements_source, $call_arg_atomic_type, $call_args[0]->value, $codebase, $context, $key_type, $value_type, $has_valid_iterator);
                }
            }
            if ($value_type) {
                $second_arg_type = isset($call_args[1]) ? $statements_source->node_data->getType($call_args[1]->value) : null;
                if ($second_arg_type && (string) $second_arg_type === 'false') {
                    return Type::getList($value_type);
                }
                $key_type = $key_type && (!isset($call_args[1]) || $second_arg_type && (string) $second_arg_type === 'true') ? $key_type : Type::getArrayKey();
                if ($key_type->hasMixed()) {
                    $key_type = Type::getArrayKey();
                }
                if ($key_type->isSingle() && $key_type->hasTemplate()) {
                    $template_types = $key_type->getTemplateTypes();
                    $template_type = array_shift($template_types);
                    if ($template_type->as->hasMixed()) {
                        $template_type = $template_type->replaceAs(Type::getArrayKey());
                        $key_type = new Union([$template_type]);
                    }
                }
                return new Union([new TArray([$key_type, $value_type])]);
            }
        }
        $callmap_callables = InternalCallMapHandler::getCallablesFromCallMap($function_id);
        assert($callmap_callables && $callmap_callables[0]->return_type);
        return $callmap_callables[0]->return_type;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Union;
/**
 * @internal
 */
class DomNodeAppendChild implements MethodReturnTypeProviderInterface
{
    public static function getClassLikeNames() : array
    {
        return ['DomNode'];
    }
    public static function getMethodReturnType(MethodReturnTypeProviderEvent $event) : ?Union
    {
        $source = $event->getSource();
        $call_args = $event->getCallArgs();
        $method_name_lowercase = $event->getMethodNameLowercase();
        if ($method_name_lowercase !== 'appendchild') {
            return null;
        }
        if (!$source instanceof StatementsAnalyzer || !$call_args) {
            return Type::getMixed();
        }
        if (($first_arg_type = $source->node_data->getType($call_args[0]->value)) && $first_arg_type->hasObjectType()) {
            return $first_arg_type;
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArrayRandReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_rand'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $first_arg = $call_args[0]->value ?? null;
        $second_arg = $call_args[1]->value ?? null;
        $first_arg_array = $first_arg && ($first_arg_type = $statements_source->node_data->getType($first_arg)) && $first_arg_type->hasType('array') && ($array_atomic_type = $first_arg_type->getArray()) && ($array_atomic_type instanceof TArray || $array_atomic_type instanceof TKeyedArray) ? $array_atomic_type : null;
        if (!$first_arg_array) {
            return Type::getMixed();
        }
        if ($first_arg_array instanceof TArray) {
            $key_type = $first_arg_array->type_params[0];
        } else {
            $key_type = $first_arg_array->getGenericKeyType();
        }
        if (!$second_arg) {
            return $key_type;
        }
        $second_arg_type = $statements_source->node_data->getType($second_arg);
        if ($second_arg_type && $second_arg_type->isSingleIntLiteral() && $second_arg_type->getSingleIntLiteral()->value === 1) {
            return $key_type;
        }
        $arr_type = Type::getList($key_type);
        if ($second_arg_type && $second_arg_type->isSingleIntLiteral()) {
            return $arr_type;
        }
        return Type::combineUnionTypes($key_type, $arr_type);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use function array_merge;
use function array_values;
use function count;
use function is_string;
use function max;
/**
 * @internal
 */
class ArrayMergeReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_merge', 'array_replace'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer || !$call_args) {
            return Type::getMixed();
        }
        $is_replace = $event->getFunctionId() === 'array_replace';
        $inner_value_types = [];
        $inner_key_types = [];
        $codebase = $statements_source->getCodebase();
        $generic_properties = [];
        $class_strings = [];
        $all_keyed_arrays = \true;
        $all_int_offsets = \true;
        $all_nonempty_lists = \true;
        $any_nonempty = \false;
        $all_empty = \true;
        $max_keyed_array_size = 0;
        foreach ($call_args as $call_arg) {
            if (!($call_arg_type = $statements_source->node_data->getType($call_arg->value))) {
                return Type::getArray();
            }
            foreach ($call_arg_type->getAtomicTypes() as $type_part) {
                if ($type_part instanceof TList) {
                    $type_part = $type_part->getKeyedArray();
                }
                $unpacking_indefinite_number_of_args = \false;
                $unpacking_possibly_empty = \false;
                if ($call_arg->unpack) {
                    if ($type_part instanceof TKeyedArray) {
                        if (!$type_part->fallback_params && $type_part->getMinCount() === $type_part->getMaxCount()) {
                            $unpacked_type_parts = [];
                            foreach ($type_part->properties as $t) {
                                $unpacked_type_parts = array_merge($unpacked_type_parts, $t->getAtomicTypes());
                            }
                        } else {
                            $unpacked_type_parts = $type_part->getGenericValueType()->getAtomicTypes();
                            $unpacking_indefinite_number_of_args = \true;
                        }
                        $unpacking_possibly_empty = !$type_part->isNonEmpty();
                    } elseif ($type_part instanceof TArray) {
                        $unpacked_type_parts = $type_part->type_params[1];
                        $unpacking_indefinite_number_of_args = \true;
                        $unpacking_possibly_empty = !$type_part instanceof TNonEmptyArray;
                        $unpacked_type_parts = $unpacked_type_parts->getAtomicTypes();
                    } else {
                        return Type::getArray();
                    }
                } else {
                    $unpacked_type_parts = [$type_part];
                }
                foreach ($unpacked_type_parts as $unpacked_type_part) {
                    if ($unpacked_type_part instanceof TFalse && $call_arg_type->ignore_falsable_issues || $unpacked_type_part instanceof TNull && $call_arg_type->ignore_nullable_issues) {
                        continue;
                    }
                    if ($unpacked_type_part instanceof TKeyedArray) {
                        $all_empty = \false;
                        $max_keyed_array_size = max($max_keyed_array_size, count($unpacked_type_part->properties));
                        $added_inner_values = \false;
                        foreach ($unpacked_type_part->properties as $key => $type) {
                            if (!$type->possibly_undefined && !$unpacking_possibly_empty) {
                                $any_nonempty = \true;
                            }
                            if (is_string($key)) {
                                $all_int_offsets = \false;
                            } elseif (!$is_replace) {
                                if ($unpacking_indefinite_number_of_args || $type->possibly_undefined) {
                                    $added_inner_values = \true;
                                    $inner_value_types = array_merge($inner_value_types, array_values($type->getAtomicTypes()));
                                } else {
                                    $generic_properties[] = $type;
                                }
                                continue;
                            }
                            if (isset($unpacked_type_part->class_strings[$key])) {
                                $class_strings[$key] = \true;
                            }
                            if (!isset($generic_properties[$key]) || !$type->possibly_undefined && !$unpacking_possibly_empty) {
                                if ($unpacking_possibly_empty) {
                                    $type = $type->setPossiblyUndefined(\true);
                                }
                                $generic_properties[$key] = $type;
                            } else {
                                $was_possibly_undefined = $generic_properties[$key]->possibly_undefined || $unpacking_possibly_empty;
                                $generic_properties[$key] = Type::combineUnionTypes($generic_properties[$key], $type, $codebase, \false, \true, 500, $was_possibly_undefined);
                            }
                        }
                        if (!$unpacked_type_part->is_list) {
                            $all_nonempty_lists = \false;
                        }
                        if ($added_inner_values) {
                            $all_keyed_arrays = \false;
                            $inner_key_types[] = new TInt();
                        }
                        if ($unpacked_type_part->fallback_params !== null) {
                            $all_keyed_arrays = \false;
                            $inner_value_types = array_merge($inner_value_types, array_values($unpacked_type_part->fallback_params[1]->getAtomicTypes()));
                            $inner_key_types = array_merge($inner_key_types, array_values($unpacked_type_part->fallback_params[0]->getAtomicTypes()));
                        }
                        continue;
                    }
                    if ($unpacked_type_part instanceof TMixed && $unpacked_type_part->from_loop_isset) {
                        $unpacked_type_part = new TArray([Type::getArrayKey(), Type::getMixed(\true)]);
                    }
                    if ($unpacked_type_part instanceof TArray) {
                        if ($unpacked_type_part->isEmptyArray()) {
                            continue;
                        }
                        foreach ($generic_properties as $key => $keyed_type) {
                            $generic_properties[$key] = Type::combineUnionTypes($keyed_type, $unpacked_type_part->type_params[1], $codebase);
                        }
                        $all_keyed_arrays = \false;
                        $all_nonempty_lists = \false;
                        if (!$unpacked_type_part->type_params[0]->isInt()) {
                            $all_int_offsets = \false;
                        }
                        if ($unpacked_type_part instanceof TNonEmptyArray && !$unpacking_possibly_empty) {
                            $any_nonempty = \true;
                        }
                    } else {
                        return Type::getArray();
                    }
                    $all_empty = \false;
                    $inner_key_types = array_merge($inner_key_types, array_values($unpacked_type_part->type_params[0]->getAtomicTypes()));
                    $inner_value_types = array_merge($inner_value_types, array_values($unpacked_type_part->type_params[1]->getAtomicTypes()));
                }
            }
        }
        $inner_key_type = null;
        $inner_value_type = null;
        if ($inner_key_types) {
            $inner_key_type = TypeCombiner::combine($inner_key_types, $codebase, \true);
        }
        if ($inner_value_types) {
            $inner_value_type = TypeCombiner::combine($inner_value_types, $codebase, \true);
        }
        $generic_property_count = count($generic_properties);
        if ($generic_properties && $generic_property_count < 64 && ($generic_property_count < $max_keyed_array_size * 2 || $generic_property_count < 16)) {
            $objectlike = new TKeyedArray($generic_properties, $class_strings ?: null, $all_keyed_arrays || $inner_key_type === null || $inner_value_type === null ? null : [$inner_key_type, $inner_value_type], $all_nonempty_lists || $all_int_offsets);
            return new Union([$objectlike]);
        }
        if ($all_empty) {
            return Type::getEmptyArray();
        }
        if ($inner_value_type) {
            if ($all_int_offsets) {
                if ($any_nonempty) {
                    return Type::getNonEmptyList($inner_value_type);
                }
                return Type::getList($inner_value_type);
            }
            $inner_key_type ??= Type::getArrayKey();
            if ($any_nonempty) {
                return new Union([new TNonEmptyArray([$inner_key_type, $inner_value_type])]);
            }
            return new Union([new TArray([$inner_key_type, $inner_value_type])]);
        }
        return Type::getArray();
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\Comparator\CallableTypeComparator;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Union;
/**
 * @internal
 */
class ClosureFromCallableReturnTypeProvider implements MethodReturnTypeProviderInterface
{
    public static function getClassLikeNames() : array
    {
        return ['Closure'];
    }
    public static function getMethodReturnType(MethodReturnTypeProviderEvent $event) : ?Union
    {
        $source = $event->getSource();
        $method_name_lowercase = $event->getMethodNameLowercase();
        $call_args = $event->getCallArgs();
        if (!$source instanceof StatementsAnalyzer) {
            return null;
        }
        $type_provider = $source->getNodeTypeProvider();
        $codebase = $source->getCodebase();
        if ($method_name_lowercase === 'fromcallable') {
            $closure_types = [];
            if (isset($call_args[0]) && ($input_type = $type_provider->getType($call_args[0]->value))) {
                foreach ($input_type->getAtomicTypes() as $atomic_type) {
                    $candidate_callable = CallableTypeComparator::getCallableFromAtomic($codebase, $atomic_type, null, $source, \true);
                    if ($candidate_callable) {
                        $closure_types[] = new TClosure('Closure', $candidate_callable->params, $candidate_callable->return_type, $candidate_callable->is_pure);
                    } else {
                        return Type::getClosure();
                    }
                }
            }
            if ($closure_types) {
                return TypeCombiner::combine($closure_types, $codebase);
            }
            return Type::getClosure();
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\SourceAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
use function count;
/**
 * @internal
 */
class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_column'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer || count($call_args) < 2) {
            return Type::getMixed();
        }
        $context = $event->getContext();
        $code_location = $event->getCodeLocation();
        $value_column_name = null;
        $value_column_name_is_null = \false;
        // calculate value column name
        if ($second_arg_type = $statements_source->node_data->getType($call_args[1]->value)) {
            if ($second_arg_type->isSingleIntLiteral()) {
                $value_column_name = $second_arg_type->getSingleIntLiteral()->value;
            } elseif ($second_arg_type->isSingleStringLiteral()) {
                $value_column_name = $second_arg_type->getSingleStringLiteral()->value;
            }
            $value_column_name_is_null = $second_arg_type->isNull();
        }
        $key_column_name = null;
        $key_column_name_is_null = \false;
        $third_arg_type = null;
        // calculate key column name
        if (isset($call_args[2])) {
            $third_arg_type = $statements_source->node_data->getType($call_args[2]->value);
            if ($third_arg_type) {
                if ($third_arg_type->isSingleIntLiteral()) {
                    $key_column_name = $third_arg_type->getSingleIntLiteral()->value;
                } elseif ($third_arg_type->isSingleStringLiteral()) {
                    $key_column_name = $third_arg_type->getSingleStringLiteral()->value;
                }
                $key_column_name_is_null = $third_arg_type->isNull();
            }
        }
        $row_type = $row_shape = null;
        $input_array_not_empty = \false;
        // calculate row shape
        if (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value)) && $first_arg_type->isSingle() && $first_arg_type->hasArray()) {
            $input_array = $first_arg_type->getArray();
            if ($input_array instanceof TKeyedArray && !$input_array->fallback_params && ($value_column_name !== null || $value_column_name_is_null) && !($third_arg_type && !$key_column_name)) {
                $properties = [];
                $ok = \true;
                $last_custom_key = -1;
                $is_list = \true;
                $had_possibly_undefined = \false;
                // This incorrectly assumes that the array is sorted, may be problematic
                // Will be fixed when order is enforced
                $key = -1;
                foreach ($input_array->properties as $property) {
                    $row_shape = self::getRowShape($property, $statements_source, $context, $code_location);
                    if (!$row_shape) {
                        continue;
                    }
                    if (!$row_shape instanceof TKeyedArray) {
                        if ($row_shape instanceof TArray && $row_shape->isEmptyArray()) {
                            continue;
                        }
                        $ok = \false;
                        break;
                    }
                    if ($value_column_name !== null) {
                        if (isset($row_shape->properties[$value_column_name])) {
                            $result_element_type = $row_shape->properties[$value_column_name];
                        } elseif ($row_shape->fallback_params) {
                            $ok = \false;
                            break;
                        } else {
                            continue;
                        }
                    } else {
                        $result_element_type = $property;
                    }
                    if ($key_column_name !== null) {
                        if (isset($row_shape->properties[$key_column_name])) {
                            $result_key_type = $row_shape->properties[$key_column_name];
                            if ($result_key_type->isSingleIntLiteral()) {
                                $key = $result_key_type->getSingleIntLiteral()->value;
                                if ($is_list && $last_custom_key != $key - 1) {
                                    $is_list = \false;
                                }
                                $last_custom_key = $key;
                            } elseif ($result_key_type->isSingleStringLiteral()) {
                                $key = $result_key_type->getSingleStringLiteral()->value;
                                $is_list = \false;
                            } else {
                                $ok = \false;
                                break;
                            }
                        } else {
                            $ok = \false;
                            break;
                        }
                    } else {
                        /** @psalm-suppress StringIncrement Actually always an int in this branch */
                        ++$key;
                    }
                    $properties[$key] = $result_element_type->setPossiblyUndefined($property->possibly_undefined);
                    if (!$property->possibly_undefined && $had_possibly_undefined) {
                        $is_list = \false;
                    }
                    $had_possibly_undefined = $had_possibly_undefined || $property->possibly_undefined;
                }
                if ($ok) {
                    if (!$properties) {
                        return Type::getEmptyArray();
                    }
                    return new Union([new TKeyedArray($properties, null, $input_array->fallback_params, $is_list)]);
                }
            }
            if ($input_array instanceof TKeyedArray) {
                $row_type = $input_array->getGenericValueType();
            } elseif ($input_array instanceof TArray) {
                $row_type = $input_array->type_params[1];
            }
            $row_shape = self::getRowShape($row_type, $statements_source, $context, $code_location);
            $input_array_not_empty = $input_array instanceof TNonEmptyArray || $input_array instanceof TKeyedArray && $input_array->isNonEmpty();
        }
        $result_key_type = Type::getArrayKey();
        $result_element_type = null !== $row_type && $value_column_name_is_null ? $row_type : null;
        $have_at_least_one_res = \false;
        // calculate results
        if ($row_shape instanceof TKeyedArray) {
            if (null !== $value_column_name && isset($row_shape->properties[$value_column_name])) {
                $result_element_type = $row_shape->properties[$value_column_name];
                // When the selected key is possibly_undefined, the resulting array can be empty
                if ($input_array_not_empty && $result_element_type->possibly_undefined !== \true) {
                    $have_at_least_one_res = \true;
                }
                //array_column skips undefined elements so resulting type is necessarily defined
                $result_element_type = $result_element_type->setPossiblyUndefined(\false);
            } elseif (!$value_column_name_is_null) {
                $result_element_type = Type::getMixed();
            }
            if (null !== $key_column_name && isset($row_shape->properties[$key_column_name])) {
                $result_key_type = $row_shape->properties[$key_column_name];
            }
        }
        if ($third_arg_type && !$key_column_name_is_null) {
            $type = $have_at_least_one_res ? new TNonEmptyArray([$result_key_type, $result_element_type ?? Type::getMixed()]) : new TArray([$result_key_type, $result_element_type ?? Type::getMixed()]);
        } else {
            $type = $have_at_least_one_res ? Type::getNonEmptyListAtomic($result_element_type ?? Type::getMixed()) : Type::getListAtomic($result_element_type ?? Type::getMixed());
        }
        return new Union([$type]);
    }
    /**
     * @return TArray|TKeyedArray|TClassStringMap|null
     */
    private static function getRowShape(?Union $row_type, SourceAnalyzer $statements_source, Context $context, CodeLocation $code_location) : ?Atomic
    {
        if ($row_type && $row_type->isSingle()) {
            if ($row_type->hasArray()) {
                return $row_type->getArray();
            } elseif ($row_type->hasObjectType()) {
                return \Psalm\Internal\Provider\ReturnTypeProvider\GetObjectVarsReturnTypeProvider::getGetObjectVarsReturnType($row_type, $statements_source, $context, $code_location);
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use DateTime;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
/**
 * @internal
 */
class DateTimeModifyReturnTypeProvider implements MethodReturnTypeProviderInterface
{
    public static function getClassLikeNames() : array
    {
        return ['DateTime', 'DateTimeImmutable'];
    }
    public static function getMethodReturnType(MethodReturnTypeProviderEvent $event) : ?Union
    {
        $statements_source = $event->getSource();
        $call_args = $event->getCallArgs();
        $method_name_lowercase = $event->getMethodNameLowercase();
        if (!$statements_source instanceof StatementsAnalyzer || $method_name_lowercase !== 'modify' || !isset($call_args[0])) {
            return null;
        }
        $first_arg = $call_args[0]->value;
        $first_arg_type = $statements_source->node_data->getType($first_arg);
        if (!$first_arg_type) {
            return null;
        }
        $has_date_time = \false;
        $has_false = \false;
        foreach ($first_arg_type->getAtomicTypes() as $type_part) {
            if (!$type_part instanceof TLiteralString) {
                return null;
            }
            if (@(new DateTime())->modify($type_part->value) === \false) {
                $has_false = \true;
            } else {
                $has_date_time = \true;
            }
        }
        if ($has_false && !$has_date_time) {
            return Type::getFalse();
        }
        if ($has_date_time && !$has_false) {
            return Type::intersectUnionTypes(Type::parseString($event->getCalledFqClasslikeName() ?? $event->getFqClasslikeName()), new Union([new TNamedObject('static')]), $statements_source->getCodebase());
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Union;
/**
 * @internal
 */
class HexdecReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['hexdec'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        return Type::getInt(\true);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Union;
/**
 * @internal
 */
class InArrayReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['in_array'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $call_args = $event->getCallArgs();
        $bool = Type::getBool();
        if (!isset($call_args[0]) || !isset($call_args[1])) {
            return $bool;
        }
        $needle_type = $event->getStatementsSource()->getNodeTypeProvider()->getType($call_args[0]->value);
        $haystack_type = $event->getStatementsSource()->getNodeTypeProvider()->getType($call_args[1]->value);
        if ($needle_type === null || $haystack_type === null) {
            return $bool;
        }
        $false = Type::getFalse();
        /** @psalm-suppress InaccessibleProperty We just created these types */
        $false->from_docblock = $bool->from_docblock = $needle_type->from_docblock || $haystack_type->from_docblock;
        if (!isset($call_args[2])) {
            return $bool;
        }
        $strict_type = $event->getStatementsSource()->getNodeTypeProvider()->getType($call_args[2]->value);
        if ($strict_type === null || !$strict_type->isTrue()) {
            return $bool;
        }
        /**
         * @var TKeyedArray|TArray|null
         */
        $array_arg_type = ($types = $haystack_type->getAtomicTypes()) && isset($types['array']) ? $types['array'] : null;
        if ($array_arg_type instanceof TKeyedArray) {
            $array_arg_type = $array_arg_type->getGenericArrayType();
        }
        if (!$array_arg_type instanceof TArray) {
            return $bool;
        }
        $haystack_item_type = $array_arg_type->type_params[1];
        if (UnionTypeComparator::canExpressionTypesBeIdentical($event->getStatementsSource()->getCodebase(), $needle_type, $haystack_item_type)) {
            return $bool;
        }
        return $false;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Union;
use function assert;
use function in_array;
/**
 * @internal
 */
class ImagickPixelColorReturnTypeProvider implements MethodReturnTypeProviderInterface
{
    public static function getClassLikeNames() : array
    {
        return ['imagickpixel'];
    }
    public static function getMethodReturnType(MethodReturnTypeProviderEvent $event) : ?Union
    {
        $source = $event->getSource();
        $call_args = $event->getCallArgs();
        $method_name_lowercase = $event->getMethodNameLowercase();
        if ($method_name_lowercase !== 'getcolor') {
            return null;
        }
        if (!$source instanceof StatementsAnalyzer) {
            return null;
        }
        if (!$call_args) {
            $formats = [0 => \true];
        } else {
            $normalized = $source->node_data->getType($call_args[0]->value) ?? Type::getMixed();
            $formats = [];
            foreach ($normalized->getAtomicTypes() as $t) {
                if ($t instanceof TLiteralInt && in_array($t->value, [0, 1, 2], \true)) {
                    $formats[$t->value] = \true;
                } else {
                    $formats[0] = \true;
                    $formats[1] = \true;
                    $formats[2] = \true;
                }
            }
        }
        $types = [];
        if (isset($formats[0])) {
            $types[] = new Union([new TKeyedArray(['r' => new Union([new TIntRange(0, 255)]), 'g' => new Union([new TIntRange(0, 255)]), 'b' => new Union([new TIntRange(0, 255)]), 'a' => new Union([new TIntRange(0, 1)])])]);
        }
        if (isset($formats[1])) {
            $types[] = new Union([new TKeyedArray(['r' => Type::getFloat(), 'g' => Type::getFloat(), 'b' => Type::getFloat(), 'a' => Type::getFloat()])]);
        }
        if (isset($formats[2])) {
            $types[] = new Union([new TKeyedArray(['r' => new Union([new TIntRange(0, 255)]), 'g' => new Union([new TIntRange(0, 255)]), 'b' => new Union([new TIntRange(0, 255)]), 'a' => new Union([new TIntRange(0, 255)])])]);
        }
        assert($types !== []);
        return Type::combineUnionTypeArray($types, $event->getSource()->getCodebase());
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use UnexpectedValueException;
use function in_array;
use const FILTER_NULL_ON_FAILURE;
use const FILTER_VALIDATE_BOOLEAN;
use const FILTER_VALIDATE_DOMAIN;
use const FILTER_VALIDATE_EMAIL;
use const FILTER_VALIDATE_FLOAT;
use const FILTER_VALIDATE_INT;
use const FILTER_VALIDATE_IP;
use const FILTER_VALIDATE_MAC;
use const FILTER_VALIDATE_REGEXP;
use const FILTER_VALIDATE_URL;
/**
 * @internal
 */
class FilterVarReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['filter_var'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $function_id = $event->getFunctionId();
        $code_location = $event->getCodeLocation();
        if (!$statements_source instanceof StatementsAnalyzer) {
            throw new UnexpectedValueException();
        }
        $filter_type = null;
        if (isset($call_args[1]) && ($second_arg_type = $statements_source->node_data->getType($call_args[1]->value)) && $second_arg_type->isSingleIntLiteral()) {
            $filter_type_type = $second_arg_type->getSingleIntLiteral();
            switch ($filter_type_type->value) {
                case FILTER_VALIDATE_INT:
                    $filter_type = Type::getInt();
                    break;
                case FILTER_VALIDATE_FLOAT:
                    $filter_type = Type::getFloat();
                    break;
                case FILTER_VALIDATE_BOOLEAN:
                    $filter_type = Type::getBool();
                    break;
                case FILTER_VALIDATE_IP:
                case FILTER_VALIDATE_MAC:
                case FILTER_VALIDATE_REGEXP:
                case FILTER_VALIDATE_URL:
                case FILTER_VALIDATE_EMAIL:
                case FILTER_VALIDATE_DOMAIN:
                    $filter_type = Type::getString();
                    break;
            }
            $has_object_like = \false;
            $filter_null = \false;
            if (isset($call_args[2]) && ($third_arg_type = $statements_source->node_data->getType($call_args[2]->value)) && $filter_type) {
                foreach ($third_arg_type->getAtomicTypes() as $atomic_type) {
                    if ($atomic_type instanceof TKeyedArray) {
                        $has_object_like = \true;
                        if (isset($atomic_type->properties['options']) && $atomic_type->properties['options']->hasArray() && ($options_array = $atomic_type->properties['options']->getArray()) && $options_array instanceof TKeyedArray && isset($options_array->properties['default'])) {
                            $filter_type = Type::combineUnionTypes($filter_type, $options_array->properties['default']);
                        } else {
                            $filter_type = $filter_type->getBuilder()->addType(new TFalse())->freeze();
                        }
                        if (isset($atomic_type->properties['flags']) && $atomic_type->properties['flags']->isSingleIntLiteral()) {
                            $filter_flag_type = $atomic_type->properties['flags']->getSingleIntLiteral();
                            if ($filter_type->hasBool() && $filter_flag_type->value === FILTER_NULL_ON_FAILURE) {
                                $filter_type = $filter_type->getBuilder()->addType(new TNull())->freeze();
                            }
                        }
                    } elseif ($atomic_type instanceof TLiteralInt) {
                        if ($atomic_type->value === FILTER_NULL_ON_FAILURE) {
                            $filter_null = \true;
                            $filter_type = $filter_type->getBuilder()->addType(new TNull())->freeze();
                        }
                    }
                }
            }
            if (!$has_object_like && !$filter_null && $filter_type) {
                $filter_type = $filter_type->getBuilder()->addType(new TFalse())->freeze();
            }
        }
        if (!$filter_type) {
            $filter_type = Type::getMixed();
        }
        if ($statements_source->data_flow_graph && !in_array('TaintedInput', $statements_source->getSuppressedIssues())) {
            $function_return_sink = DataFlowNode::getForMethodReturn($function_id, $function_id, null, $code_location);
            $statements_source->data_flow_graph->addNode($function_return_sink);
            $function_param_sink = DataFlowNode::getForMethodArgument($function_id, $function_id, 0, null, $code_location);
            $statements_source->data_flow_graph->addNode($function_param_sink);
            $statements_source->data_flow_graph->addPath($function_param_sink, $function_return_sink, 'arg');
            return $filter_type->setParentNodes([$function_return_sink->id => $function_return_sink]);
        }
        return $filter_type;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use function array_values;
use function count;
use function round;
use const PHP_ROUND_HALF_UP;
/**
 * @internal
 */
class RoundReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['round'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Type\Union
    {
        $call_args = $event->getCallArgs();
        if (count($call_args) === 0) {
            return null;
        }
        $statements_source = $event->getStatementsSource();
        $nodeTypeProvider = $statements_source->getNodeTypeProvider();
        $num_arg = $nodeTypeProvider->getType($call_args[0]->value);
        $precision_val = 0;
        if ($statements_source instanceof StatementsAnalyzer && count($call_args) > 1) {
            $type = $statements_source->node_data->getType($call_args[1]->value);
            if ($type !== null && $type->isSingle()) {
                $atomic_type = array_values($type->getAtomicTypes())[0];
                if ($atomic_type instanceof Type\Atomic\TLiteralInt) {
                    $precision_val = $atomic_type->value;
                }
            }
        }
        $mode_val = PHP_ROUND_HALF_UP;
        if ($statements_source instanceof StatementsAnalyzer && count($call_args) > 2) {
            $type = $statements_source->node_data->getType($call_args[2]->value);
            if ($type !== null && $type->isSingle()) {
                $atomic_type = array_values($type->getAtomicTypes())[0];
                if ($atomic_type instanceof Type\Atomic\TLiteralInt) {
                    /** @var positive-int|0 $mode_val */
                    $mode_val = $atomic_type->value;
                }
            }
        }
        if ($num_arg !== null && $num_arg->isSingle()) {
            $num_type = array_values($num_arg->getAtomicTypes())[0];
            if ($num_type instanceof Type\Atomic\TLiteralFloat || $num_type instanceof Type\Atomic\TLiteralInt) {
                $rounded_val = round($num_type->value, $precision_val, $mode_val);
                return new Type\Union([new Type\Atomic\TLiteralFloat($rounded_val)]);
            }
        }
        return new Type\Union([new Type\Atomic\TFloat()]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Union;
use function array_reverse;
/**
 * @internal
 */
class ArrayReverseReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_reverse'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $first_arg = $call_args[0]->value ?? null;
        $first_arg_type = null;
        $first_arg_array = $first_arg && ($first_arg_type = $statements_source->node_data->getType($first_arg)) && $first_arg_type->hasType('array') && $first_arg_type->isArray() && ($array_atomic_type = $first_arg_type->getArray()) && ($array_atomic_type instanceof TArray || $array_atomic_type instanceof TKeyedArray) ? $array_atomic_type : null;
        if (!$first_arg_array || !$first_arg_type) {
            return Type::getArray();
        }
        if ($first_arg_array instanceof TArray) {
            return $first_arg_type;
        }
        if ($first_arg_array->is_list) {
            $second_arg = $call_args[1]->value ?? null;
            if (!$second_arg || ($second_arg_type = $statements_source->node_data->getType($second_arg)) && $second_arg_type->isFalse()) {
                return $first_arg_array->fallback_params ? $first_arg_array->isNonEmpty() ? Type::getNonEmptyList($first_arg_array->getGenericValueType()) : Type::getList($first_arg_array->getGenericValueType()) : new Union([$first_arg_array->setProperties(array_reverse($first_arg_array->properties))]);
            }
            return new Union([new TKeyedArray($first_arg_array->properties, null, $first_arg_array->fallback_params, \false)]);
        }
        return new Union([$first_arg_array->getGenericArrayType()]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Union;
/**
 * @internal
 */
class MktimeReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['mktime'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        foreach ($call_args as $call_arg) {
            if (!($call_arg_type = $statements_source->node_data->getType($call_arg->value)) || !$call_arg_type->isInt()) {
                $codebase = $statements_source->getCodebase();
                return new Union([new TInt(), new TFalse()], ['ignore_falsable_issues' => $codebase->config->ignore_internal_falsable_issues]);
            }
        }
        return Type::getInt();
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArrayPopReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_pop', 'array_shift'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $function_id = $event->getFunctionId();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $first_arg = $call_args[0]->value ?? null;
        $first_arg_array = $first_arg && ($first_arg_type = $statements_source->node_data->getType($first_arg)) && $first_arg_type->hasType('array') && !$first_arg_type->hasMixed() && ($array_atomic_type = $first_arg_type->getArray()) && ($array_atomic_type instanceof TArray || $array_atomic_type instanceof TKeyedArray) ? $array_atomic_type : null;
        if (!$first_arg_array) {
            return Type::getMixed();
        }
        $nullable = \false;
        if ($first_arg_array instanceof TArray) {
            $value_type = $first_arg_array->type_params[1];
            if ($first_arg_array->isEmptyArray()) {
                return Type::getNull();
            }
            if (!$first_arg_array instanceof TNonEmptyArray) {
                $nullable = \true;
            }
        } else {
            // special case where we know the type of the first element
            if ($function_id === 'array_shift' && $first_arg_array->is_list && isset($first_arg_array->properties[0])) {
                $value_type = $first_arg_array->properties[0];
                if ($value_type->possibly_undefined) {
                    $value_type = $value_type->setPossiblyUndefined(\false);
                    $nullable = \true;
                }
            } else {
                $value_type = $first_arg_array->getGenericValueType();
                if (!$first_arg_array->isNonEmpty()) {
                    $nullable = \true;
                }
            }
        }
        if ($nullable) {
            $value_type = $value_type->getBuilder()->addType(new TNull());
            $codebase = $statements_source->getCodebase();
            if ($codebase->config->ignore_internal_nullable_issues) {
                $value_type->ignore_nullable_issues = \true;
            }
            $value_type = $value_type->freeze();
        }
        return $value_type;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
use function assert;
use function count;
/**
 * @internal
 */
class MbInternalEncodingReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['mb_internal_encoding'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $call_args = $event->getCallArgs();
        if (count($call_args) === 0) {
            return Type::getString();
        }
        $statements_source = $event->getStatementsSource();
        $nodeTypeProvider = $statements_source->getNodeTypeProvider();
        $codebase = $statements_source->getCodebase();
        $first_arg_type = $nodeTypeProvider->getType($call_args[0]->value);
        if ($first_arg_type === null) {
            if ($codebase->analysis_php_version_id >= 80000) {
                return new Union([new TString(), new TTrue()]);
            } else {
                return new Union([new TString(), new TBool()]);
            }
        }
        $has_stringable = \false;
        $has_tostring = \false;
        $has_string = \false;
        $has_null = \false;
        $has_unknown = \false;
        foreach ($first_arg_type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof Type\Atomic\TNamedObject && $codebase->classlikes->classImplements($atomic_type->value, 'Stringable')) {
                $has_stringable = \true;
                continue;
            }
            if ($atomic_type instanceof Type\Atomic\TObjectWithProperties && isset($atomic_type->methods['__tostring'])) {
                $has_tostring = \true;
                continue;
            }
            if ($atomic_type instanceof TString) {
                $has_string = \true;
                continue;
            }
            if ($atomic_type instanceof TNull) {
                $has_null = \true;
                continue;
            }
            $has_unknown = \true;
        }
        $list_return_atomics = [];
        if ($has_string || $has_stringable || $has_tostring) {
            if ($codebase->analysis_php_version_id >= 80000) {
                $list_return_atomics[] = new TTrue();
            } else {
                $list_return_atomics[] = new TBool();
            }
        }
        if ($has_null) {
            if ($codebase->analysis_php_version_id >= 80000) {
                $list_return_atomics[] = new TString();
            } else {
                $list_return_atomics[] = new TFalse();
            }
        }
        if ($has_unknown) {
            if ($codebase->analysis_php_version_id >= 80000) {
                $list_return_atomics[] = new TNever();
            } else {
                $list_return_atomics[] = new TNull();
            }
        }
        assert($list_return_atomics !== []);
        return new Union($list_return_atomics);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Config;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Union;
/**
 * @internal
 */
class PdoStatementReturnTypeProvider implements MethodReturnTypeProviderInterface
{
    public static function getClassLikeNames() : array
    {
        return ['PDOStatement'];
    }
    public static function getMethodReturnType(MethodReturnTypeProviderEvent $event) : ?Union
    {
        $config = Config::getInstance();
        $source = $event->getSource();
        $call_args = $event->getCallArgs();
        $method_name_lowercase = $event->getMethodNameLowercase();
        if ($method_name_lowercase === 'fetch' && $config->php_extensions["pdo"] && isset($call_args[0]) && ($first_arg_type = $source->getNodeTypeProvider()->getType($call_args[0]->value)) && $first_arg_type->isSingleIntLiteral()) {
            $fetch_mode = $first_arg_type->getSingleIntLiteral()->value;
            switch ($fetch_mode) {
                case 2:
                    // PDO::FETCH_ASSOC - array<string,scalar|null>|false
                    return new Union([new TArray([Type::getString(), new Union([new TScalar(), new TNull()])]), new TFalse()]);
                case 4:
                    // PDO::FETCH_BOTH - array<array-key,scalar|null>|false
                    return new Union([new TArray([Type::getArrayKey(), new Union([new TScalar(), new TNull()])]), new TFalse()]);
                case 6:
                    // PDO::FETCH_BOUND - bool
                    return Type::getBool();
                case 8:
                    // PDO::FETCH_CLASS - object|false
                    return new Union([new TObject(), new TFalse()]);
                case 1:
                    // PDO::FETCH_LAZY - object|false
                    // This actually returns a PDORow object, but that class is
                    // undocumented, and its attributes are all dynamic anyway
                    return new Union([new TObject(), new TFalse()]);
                case 11:
                    // PDO::FETCH_NAMED - array<string, scalar|list<scalar>>|false
                    return new Union([new TArray([Type::getString(), new Union([new TScalar(), Type::getListAtomic(Type::getScalar())])]), new TFalse()]);
                case 3:
                    // PDO::FETCH_NUM - list<scalar|null>|false
                    return new Union([Type::getListAtomic(new Union([new TScalar(), new TNull()])), new TFalse()]);
                case 5:
                    // PDO::FETCH_OBJ - stdClass|false
                    return new Union([new TNamedObject('stdClass'), new TFalse()]);
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\AssertionFinder;
use Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\ArrayType;
use Psalm\Node\Expr\VirtualArrayDimFetch;
use Psalm\Node\Expr\VirtualFuncCall;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\Expr\VirtualStaticCall;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualIdentifier;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Storage\Assertion;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_map;
use function array_shift;
use function array_slice;
use function array_values;
use function count;
use function explode;
use function in_array;
use function mt_rand;
use function reset;
use function strpos;
use function substr;
/**
 * @internal
 */
class ArrayMapReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_map'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $context = $event->getContext();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $function_call_arg = $call_args[0] ?? null;
        $function_call_type = $function_call_arg ? $statements_source->node_data->getType($function_call_arg->value) : null;
        if ($function_call_type && $function_call_type->isNull()) {
            array_shift($call_args);
            if (!$call_args) {
                return Type::getNever();
            }
            $array_arg_types = [];
            $orig_types = [];
            foreach ($call_args as $call_arg) {
                $call_arg_type = $statements_source->node_data->getType($call_arg->value);
                if ($call_arg_type && $call_arg_type->isSingle() && ($call_arg_atomic = $call_arg_type->getSingleAtomic()) instanceof TKeyedArray && $call_arg_atomic->fallback_params === null) {
                    $array_arg_types[] = array_values($call_arg_atomic->properties);
                    $orig_types[] = $call_arg_type;
                } elseif ($call_arg_type && $call_arg_type->isSingle() && ($call_arg_atomic = $call_arg_type->getSingleAtomic()) instanceof TArray && $call_arg_atomic->isEmptyArray()) {
                    $array_arg_types[] = [];
                    $orig_types[] = $call_arg_type;
                } else {
                    return Type::getArray();
                }
            }
            if (count($orig_types) === 1) {
                return $orig_types[0];
            }
            $null = Type::getNull();
            $array_arg_types = array_map(null, ...$array_arg_types);
            $array_arg_types = array_map(
                /** @param non-empty-array<?Union> $sub */
                function (array $sub) use($null) {
                    $sub = array_map(fn(?Union $t) => $t ?? $null, $sub);
                    return new Union([new TKeyedArray($sub, null, null, \true)]);
                },
                $array_arg_types
            );
            if (!$array_arg_types) {
                return Type::getEmptyArray();
            }
            return new Union([new TKeyedArray($array_arg_types, null, null, \true)]);
        }
        $array_arg = $call_args[1] ?? null;
        if (!$array_arg) {
            return Type::getArray();
        }
        $array_arg_atomic_type = null;
        $array_arg_type = null;
        if ($array_arg_union_type = $statements_source->node_data->getType($array_arg->value)) {
            $arg_types = $array_arg_union_type->getAtomicTypes();
            if (isset($arg_types['array'])) {
                $array_arg_atomic_type = $arg_types['array'];
                if ($array_arg_atomic_type instanceof TList) {
                    $array_arg_atomic_type = $array_arg_atomic_type->getKeyedArray();
                }
                $array_arg_type = ArrayType::infer($array_arg_atomic_type);
            }
        }
        $generic_key_type = null;
        $mapping_return_type = null;
        if ($function_call_arg && $function_call_type) {
            if (count($call_args) === 2) {
                $generic_key_type = $array_arg_type->key ?? Type::getArrayKey();
            } else {
                $generic_key_type = Type::getInt();
            }
            if ($function_call_type->hasCallableType()) {
                $closure_types = $function_call_type->getClosureTypes() ?: $function_call_type->getCallableTypes();
                $closure_atomic_type = reset($closure_types);
                $closure_return_type = $closure_atomic_type->return_type ?: Type::getMixed();
                if ($closure_return_type->isVoid()) {
                    $closure_return_type = Type::getNull();
                }
                $mapping_return_type = $closure_return_type;
            } elseif ($function_call_arg->value instanceof PhpParser\Node\Scalar\String_ || $function_call_arg->value instanceof PhpParser\Node\Expr\Array_ || $function_call_arg->value instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
                $mapping_function_ids = CallAnalyzer::getFunctionIdsFromCallableArg($statements_source, $function_call_arg->value);
                if ($mapping_function_ids) {
                    $mapping_return_type = self::getReturnTypeFromMappingIds($statements_source, $mapping_function_ids, $context, $function_call_arg, array_slice($call_args, 1));
                }
                if ($function_call_arg->value instanceof PhpParser\Node\Expr\Array_ && isset($function_call_arg->value->items[0]) && isset($function_call_arg->value->items[1]) && $function_call_arg->value->items[1]->value instanceof PhpParser\Node\Scalar\String_ && $function_call_arg->value->items[0]->value instanceof PhpParser\Node\Expr\Variable && ($variable_type = $statements_source->node_data->getType($function_call_arg->value->items[0]->value))) {
                    $fake_method_call = null;
                    foreach ($variable_type->getAtomicTypes() as $variable_atomic_type) {
                        if ($variable_atomic_type instanceof TTemplateParam || $variable_atomic_type instanceof TTemplateParamClass) {
                            $fake_method_call = new VirtualStaticCall($function_call_arg->value->items[0]->value, $function_call_arg->value->items[1]->value->value, []);
                        }
                    }
                    if ($fake_method_call) {
                        $fake_method_return_type = self::executeFakeCall($statements_source, $fake_method_call, $context);
                        if ($fake_method_return_type) {
                            $mapping_return_type = $fake_method_return_type;
                        }
                    }
                }
            }
        }
        if ($mapping_return_type && $generic_key_type) {
            if ($array_arg_atomic_type instanceof TKeyedArray && count($call_args) === 2) {
                $atomic_type = new TKeyedArray(array_map(static fn(Union $in): Union => $mapping_return_type->setPossiblyUndefined($in->possibly_undefined), $array_arg_atomic_type->properties), null, $array_arg_atomic_type->fallback_params === null ? null : [$array_arg_atomic_type->fallback_params[0], $mapping_return_type], $array_arg_atomic_type->is_list);
                return new Union([$atomic_type]);
            }
            if ($array_arg_atomic_type instanceof TKeyedArray && $array_arg_atomic_type->is_list || count($call_args) !== 2) {
                if ($array_arg_atomic_type instanceof TKeyedArray && $array_arg_atomic_type->isNonEmpty()) {
                    return Type::getNonEmptyList($mapping_return_type);
                }
                return Type::getList($mapping_return_type);
            }
            if ($array_arg_atomic_type instanceof TNonEmptyArray) {
                return new Union([new TNonEmptyArray([$generic_key_type, $mapping_return_type])]);
            }
            return new Union([new TArray([$generic_key_type, $mapping_return_type])]);
        }
        return count($call_args) === 2 && !($array_arg_type->is_list ?? \false) ? new Union([new TArray([$array_arg_type->key ?? Type::getArrayKey(), Type::getMixed()])]) : Type::getList();
    }
    /**
     * @param array<string, array<array<int, Assertion>>>|null $assertions
     */
    private static function executeFakeCall(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $fake_call, Context $context, ?array &$assertions = null) : ?Union
    {
        $old_data_provider = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['PossiblyInvalidMethodCall']);
        }
        if (!in_array('MixedArrayOffset', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['MixedArrayOffset']);
        }
        $was_inside_call = $context->inside_call;
        $context->inside_call = \true;
        if ($fake_call instanceof PhpParser\Node\Expr\StaticCall) {
            StaticCallAnalyzer::analyze($statements_analyzer, $fake_call, $context);
        } elseif ($fake_call instanceof PhpParser\Node\Expr\MethodCall) {
            MethodCallAnalyzer::analyze($statements_analyzer, $fake_call, $context);
        } elseif ($fake_call instanceof PhpParser\Node\Expr\FuncCall) {
            FunctionCallAnalyzer::analyze($statements_analyzer, $fake_call, $context);
        } else {
            throw new UnexpectedValueException('UnrecognizedCall');
        }
        $codebase = $statements_analyzer->getCodebase();
        if ($assertions !== null) {
            $anded_assertions = AssertionFinder::scrapeAssertions($fake_call, null, $statements_analyzer, $codebase);
            $assertions = $anded_assertions[0] ?? [];
        }
        $context->inside_call = $was_inside_call;
        if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['PossiblyInvalidMethodCall']);
        }
        if (!in_array('MixedArrayOffset', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['MixedArrayOffset']);
        }
        $return_type = $statements_analyzer->node_data->getType($fake_call) ?? null;
        $statements_analyzer->node_data = $old_data_provider;
        return $return_type;
    }
    /**
     * @param non-empty-array<int, string> $mapping_function_ids
     * @param list<PhpParser\Node\Arg> $array_args
     * @param int|null $fake_var_discriminator Set the fake variable id to a known value with the discriminator
     *                                         as a substring, and don't clear it from the context.
     * @param array<string, array<array<int, Assertion>>>|null $assertions
     */
    public static function getReturnTypeFromMappingIds(StatementsAnalyzer $statements_source, array $mapping_function_ids, Context $context, PhpParser\Node\Arg $function_call_arg, array $array_args, ?array &$assertions = null, ?int $fake_var_discriminator = null) : Union
    {
        $mapping_return_type = null;
        $codebase = $statements_source->getCodebase();
        $clean_context = \false;
        foreach ($mapping_function_ids as $mapping_function_id) {
            $mapping_function_id_parts = explode('&', $mapping_function_id);
            if ($fake_var_discriminator === null) {
                $fake_var_discriminator = mt_rand();
                $clean_context = \true;
            }
            foreach ($mapping_function_id_parts as $mapping_function_id_part) {
                $fake_args = [];
                foreach ($array_args as $array_arg) {
                    $fake_args[] = new VirtualArg(new VirtualArrayDimFetch($array_arg->value, new VirtualVariable("__fake_{$fake_var_discriminator}_offset_var__", $array_arg->value->getAttributes()), $array_arg->value->getAttributes()), \false, \false, $array_arg->getAttributes());
                }
                if (strpos($mapping_function_id_part, '::') !== \false) {
                    $is_instance = \false;
                    if ($mapping_function_id_part[0] === '$') {
                        $mapping_function_id_part = substr($mapping_function_id_part, 1);
                        $is_instance = \true;
                    }
                    $method_id_parts = explode('::', $mapping_function_id_part);
                    [$callable_fq_class_name, $callable_method_name] = $method_id_parts;
                    if ($is_instance) {
                        $fake_method_call = new VirtualMethodCall(new VirtualVariable("__fake_{$fake_var_discriminator}_method_call_var__", $function_call_arg->getAttributes()), new VirtualIdentifier($callable_method_name, $function_call_arg->getAttributes()), $fake_args, $function_call_arg->getAttributes());
                        $lhs_instance_type = null;
                        $callable_type = $statements_source->node_data->getType($function_call_arg->value);
                        if ($callable_type) {
                            foreach ($callable_type->getAtomicTypes() as $atomic_type) {
                                if ($atomic_type instanceof TKeyedArray && count($atomic_type->properties) === 2 && isset($atomic_type->properties[0])) {
                                    $lhs_instance_type = $atomic_type->properties[0];
                                }
                            }
                        }
                        $context->vars_in_scope["\$__fake_{$fake_var_discriminator}_offset_var__"] = Type::getMixed();
                        $context->vars_in_scope["\$__fake_{$fake_var_discriminator}_method_call_var__"] = $lhs_instance_type ?: new Union([new TNamedObject($callable_fq_class_name)]);
                    } else {
                        $fake_method_call = new VirtualStaticCall(new VirtualFullyQualified($callable_fq_class_name, $function_call_arg->getAttributes()), new VirtualIdentifier($callable_method_name, $function_call_arg->getAttributes()), $fake_args, $function_call_arg->getAttributes());
                        $context->vars_in_scope["\$__fake_{$fake_var_discriminator}_offset_var__"] = Type::getMixed();
                    }
                    $fake_method_return_type = self::executeFakeCall($statements_source, $fake_method_call, $context, $assertions);
                    $function_id_return_type = $fake_method_return_type ?? Type::getMixed();
                } else {
                    $fake_function_call = new VirtualFuncCall(new VirtualFullyQualified($mapping_function_id_part, $function_call_arg->getAttributes()), $fake_args, $function_call_arg->getAttributes());
                    $context->vars_in_scope["\$__fake_{$fake_var_discriminator}_offset_var__"] = Type::getMixed();
                    $fake_function_return_type = self::executeFakeCall($statements_source, $fake_function_call, $context, $assertions);
                    $function_id_return_type = $fake_function_return_type ?? Type::getMixed();
                }
            }
            if ($clean_context) {
                self::cleanContext($context, $fake_var_discriminator);
            }
            $fake_var_discriminator = null;
            $mapping_return_type = Type::combineUnionTypes($function_id_return_type, $mapping_return_type, $codebase);
        }
        return $mapping_return_type;
    }
    public static function cleanContext(Context $context, int $fake_var_discriminator) : void
    {
        foreach ($context->vars_in_scope as $var_in_scope => $_) {
            if (strpos($var_in_scope, "__fake_{$fake_var_discriminator}_") !== \false) {
                unset($context->vars_in_scope[$var_in_scope]);
            }
        }
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
use function array_fill_keys;
use const PHP_URL_FRAGMENT;
use const PHP_URL_HOST;
use const PHP_URL_PASS;
use const PHP_URL_PATH;
use const PHP_URL_PORT;
use const PHP_URL_QUERY;
use const PHP_URL_SCHEME;
use const PHP_URL_USER;
/**
 * @internal
 */
class ParseUrlReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['parse_url'];
    }
    private static ?Union $acceptable_int_component_type = null;
    private static ?Union $acceptable_string_component_type = null;
    private static ?Union $nullable_falsable_int = null;
    private static ?Union $nullable_falsable_string = null;
    private static ?Union $nullable_string_or_int = null;
    private static ?Union $return_type = null;
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        if (isset($call_args[1])) {
            $is_default_component = \false;
            if ($component_type = $statements_source->node_data->getType($call_args[1]->value)) {
                if (!$component_type->hasMixed()) {
                    $codebase = $statements_source->getCodebase();
                    self::$acceptable_string_component_type ??= new Union([new TLiteralInt(PHP_URL_SCHEME), new TLiteralInt(PHP_URL_USER), new TLiteralInt(PHP_URL_PASS), new TLiteralInt(PHP_URL_HOST), new TLiteralInt(PHP_URL_PATH), new TLiteralInt(PHP_URL_QUERY), new TLiteralInt(PHP_URL_FRAGMENT)]);
                    self::$acceptable_int_component_type ??= new Union([new TLiteralInt(PHP_URL_PORT)]);
                    if (UnionTypeComparator::isContainedBy($codebase, $component_type, self::$acceptable_string_component_type)) {
                        self::$nullable_falsable_string ??= new Union([new TString(), new TFalse(), new TNull()], ['ignore_nullable_issues' => $statements_source->getCodebase()->config->ignore_internal_nullable_issues, 'ignore_falsable_issues' => $statements_source->getCodebase()->config->ignore_internal_falsable_issues]);
                        return self::$nullable_falsable_string;
                    }
                    if (UnionTypeComparator::isContainedBy($codebase, $component_type, self::$acceptable_int_component_type)) {
                        self::$nullable_falsable_int ??= new Union([new TInt(), new TFalse(), new TNull()], ['ignore_nullable_issues' => $statements_source->getCodebase()->config->ignore_internal_nullable_issues, 'ignore_falsable_issues' => $statements_source->getCodebase()->config->ignore_internal_falsable_issues]);
                        return self::$nullable_falsable_int;
                    }
                    if ($component_type->isSingleIntLiteral()) {
                        $component_type_type = $component_type->getSingleIntLiteral();
                        $is_default_component = $component_type_type->value <= -1;
                    }
                }
            }
            if (!$is_default_component) {
                self::$nullable_string_or_int ??= new Union([new TString(), new TInt(), new TNull()], ['ignore_nullable_issues' => $statements_source->getCodebase()->config->ignore_internal_nullable_issues]);
                return self::$nullable_string_or_int;
            }
        }
        if (!self::$return_type) {
            $component_types = array_fill_keys(['scheme', 'user', 'pass', 'host', 'path', 'query', 'fragment'], new Union([new TString()], ['possibly_undefined' => \true]));
            $component_types['port'] = new Union([new TInt()], ['possibly_undefined' => \true]);
            self::$return_type = new Union([new TKeyedArray($component_types, null), new TFalse()], ['ignore_falsable_issues' => $statements_source->getCodebase()->config->ignore_internal_falsable_issues]);
        }
        return self::$return_type;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Type\ArrayType;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_filter;
use function assert;
use function count;
use function get_class;
use function in_array;
use function max;
use function min;
/**
 * @internal
 */
class MinMaxReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['min', 'max'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $call_args = $event->getCallArgs();
        if (count($call_args) === 0) {
            return null;
        }
        $statements_source = $event->getStatementsSource();
        $nodeTypeProvider = $statements_source->getNodeTypeProvider();
        if (count($call_args) === 1 && ($array_arg_type = $nodeTypeProvider->getType($call_args[0]->value)) && $array_arg_type->isSingle() && $array_arg_type->hasArray() && ($array_type = ArrayType::infer($array_arg_type->getSingleAtomic()))) {
            return $array_type->value;
        }
        $all_int = \true;
        $min_bounds = [];
        $max_bounds = [];
        foreach ($call_args as $arg) {
            if ($arg_type = $nodeTypeProvider->getType($arg->value)) {
                if ($arg->unpack) {
                    if (!$arg_type->isSingle() || !$arg_type->isArray()) {
                        return Type::getMixed();
                    } else {
                        $array_arg_type = $arg_type->getArray();
                        if ($array_arg_type instanceof TKeyedArray) {
                            $possibly_unpacked_arg_types = $array_arg_type->properties;
                        } else {
                            assert($array_arg_type instanceof TArray);
                            $possibly_unpacked_arg_types = [$array_arg_type->type_params[1]];
                        }
                    }
                } else {
                    $possibly_unpacked_arg_types = [$arg_type];
                }
                foreach ($possibly_unpacked_arg_types as $possibly_unpacked_arg_type) {
                    foreach ($possibly_unpacked_arg_type->getAtomicTypes() as $atomic_type) {
                        if (!$atomic_type instanceof TInt) {
                            $all_int = \false;
                            break 2;
                        }
                        if ($atomic_type instanceof TLiteralInt) {
                            $min_bounds[] = $atomic_type->value;
                            $max_bounds[] = $atomic_type->value;
                        } elseif ($atomic_type instanceof TIntRange) {
                            $min_bounds[] = $atomic_type->min_bound;
                            $max_bounds[] = $atomic_type->max_bound;
                        } elseif (get_class($atomic_type) === TInt::class) {
                            $min_bounds[] = null;
                            $max_bounds[] = null;
                        } else {
                            throw new UnexpectedValueException('Unexpected type');
                        }
                    }
                }
            } else {
                return Type::getMixed();
            }
        }
        if ($all_int) {
            if ($event->getFunctionId() === 'min') {
                assert(count($min_bounds) !== 0);
                //null values in $max_bounds doesn't make sense for min() so we remove them
                $max_bounds = array_filter($max_bounds, static fn($v): bool => $v !== null) ?: [null];
                $min_potential_int = in_array(null, $min_bounds, \true) ? null : min($min_bounds);
                $max_potential_int = in_array(null, $max_bounds, \true) ? null : min($max_bounds);
            } else {
                assert(count($max_bounds) !== 0);
                //null values in $min_bounds doesn't make sense for max() so we remove them
                $min_bounds = array_filter($min_bounds, static fn($v): bool => $v !== null) ?: [null];
                $min_potential_int = in_array(null, $min_bounds, \true) ? null : max($min_bounds);
                $max_potential_int = in_array(null, $max_bounds, \true) ? null : max($max_bounds);
            }
            if ($min_potential_int === null && $max_potential_int === null) {
                return Type::getInt();
            }
            if ($min_potential_int === $max_potential_int) {
                return Type::getInt(\false, $min_potential_int);
            }
            return new Union([new TIntRange($min_potential_int, $max_potential_int)]);
        }
        //if we're dealing with non-int elements, just combine them all together
        $return_type = null;
        foreach ($call_args as $arg) {
            if ($arg_type = $nodeTypeProvider->getType($arg->value)) {
                if ($arg->unpack) {
                    if ($arg_type->isSingle() && $arg_type->isArray()) {
                        $array_type = ArrayType::infer($arg_type->getSingleAtomic());
                        assert($array_type !== null);
                        $additional_type = $array_type->value;
                    } else {
                        $additional_type = Type::getMixed();
                    }
                } else {
                    $additional_type = $arg_type;
                }
                $return_type = Type::combineUnionTypes($return_type, $additional_type);
            } else {
                return Type::getMixed();
            }
        }
        return $return_type;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\AssertionReconciler;
use Psalm\Issue\InvalidReturnType;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use function array_filter;
use function array_map;
use function array_slice;
use function count;
use function is_string;
use function mt_rand;
use function reset;
use function spl_object_id;
/**
 * @internal
 */
class ArrayFilterReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_filter'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $context = $event->getContext();
        $code_location = $event->getCodeLocation();
        if (!$statements_source instanceof StatementsAnalyzer || !$call_args) {
            return Type::getMixed();
        }
        $array_arg = $call_args[0]->value ?? null;
        $first_arg_array = $array_arg && ($first_arg_type = $statements_source->node_data->getType($array_arg)) && $first_arg_type->hasType('array') && ($array_atomic_type = $first_arg_type->getArray()) && ($array_atomic_type instanceof TArray || $array_atomic_type instanceof TKeyedArray) ? $array_atomic_type : null;
        if (!$first_arg_array) {
            return Type::getArray();
        }
        if ($first_arg_array instanceof TArray) {
            $inner_type = $first_arg_array->type_params[1];
            $key_type = $first_arg_array->type_params[0];
        } else {
            $inner_type = $first_arg_array->getGenericValueType();
            $key_type = $first_arg_array->getGenericKeyType();
            if (!isset($call_args[1]) && $first_arg_array->fallback_params === null) {
                $had_one = count($first_arg_array->properties) === 1;
                $new_properties = array_filter(array_map(static function ($keyed_type) use($statements_source, $context) {
                    $prev_keyed_type = $keyed_type;
                    $keyed_type = AssertionReconciler::reconcile(new Truthy(), $keyed_type, '', $statements_source, $context->inside_loop, [], null, $statements_source->getSuppressedIssues());
                    return $keyed_type->setPossiblyUndefined(!$prev_keyed_type->isAlwaysTruthy());
                }, $first_arg_array->properties), static fn($keyed_type) => !$keyed_type->isNever());
                if (!$new_properties) {
                    return Type::getEmptyArray();
                }
                return new Union([new TKeyedArray($new_properties, null, $first_arg_array->fallback_params, $first_arg_array->is_list && $had_one)]);
            }
        }
        if (!isset($call_args[1])) {
            $inner_type = AssertionReconciler::reconcile(new Truthy(), $inner_type, '', $statements_source, $context->inside_loop, [], null, $statements_source->getSuppressedIssues());
            if ($first_arg_array instanceof TKeyedArray && $first_arg_array->is_list && $key_type->isSingleIntLiteral() && $key_type->getSingleIntLiteral()->value === 0) {
                return Type::getList($inner_type);
            }
            if ($key_type->getLiteralStrings()) {
                $key_type = $key_type->getBuilder()->addType(new TString())->freeze();
            }
            if ($key_type->getLiteralInts()) {
                $key_type = $key_type->getBuilder()->addType(new TInt())->freeze();
            }
            if ($inner_type->isUnionEmpty()) {
                return Type::getEmptyArray();
            }
            return new Union([new TArray([$key_type, $inner_type])]);
        }
        if (!isset($call_args[2])) {
            $function_call_arg = $call_args[1];
            if ($function_call_arg->value instanceof PhpParser\Node\Scalar\String_ || $function_call_arg->value instanceof PhpParser\Node\Expr\Array_ || $function_call_arg->value instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
                $mapping_function_ids = CallAnalyzer::getFunctionIdsFromCallableArg($statements_source, $function_call_arg->value);
                if ($array_arg && $mapping_function_ids) {
                    $assertions = [];
                    $fake_var_discriminator = mt_rand();
                    \Psalm\Internal\Provider\ReturnTypeProvider\ArrayMapReturnTypeProvider::getReturnTypeFromMappingIds($statements_source, $mapping_function_ids, $context, $function_call_arg, array_slice($call_args, 0, 1), $assertions, $fake_var_discriminator);
                    $extended_var_id = ExpressionIdentifier::getExtendedVarId($array_arg, null, $statements_source);
                    $assertion_id = $extended_var_id . "[\$__fake_{$fake_var_discriminator}_offset_var__]";
                    if (isset($assertions[$assertion_id])) {
                        $changed_var_ids = [];
                        $assertions = ['$inner_type' => $assertions[$assertion_id]];
                        [$reconciled_types, $_] = Reconciler::reconcileKeyedTypes($assertions, $assertions, ['$inner_type' => $inner_type], [], $changed_var_ids, ['$inner_type' => \true], $statements_source, $statements_source->getTemplateTypeMap() ?: [], \false, new CodeLocation($statements_source, $function_call_arg->value));
                        if (isset($reconciled_types['$inner_type'])) {
                            $inner_type = $reconciled_types['$inner_type'];
                        }
                    }
                    \Psalm\Internal\Provider\ReturnTypeProvider\ArrayMapReturnTypeProvider::cleanContext($context, $fake_var_discriminator);
                }
            } elseif (($function_call_arg->value instanceof PhpParser\Node\Expr\Closure || $function_call_arg->value instanceof PhpParser\Node\Expr\ArrowFunction) && ($second_arg_type = $statements_source->node_data->getType($function_call_arg->value)) && ($closure_types = $second_arg_type->getClosureTypes())) {
                $closure_atomic_type = reset($closure_types);
                $closure_return_type = $closure_atomic_type->return_type ?: Type::getMixed();
                if ($closure_return_type->isVoid()) {
                    IssueBuffer::maybeAdd(new InvalidReturnType('No return type could be found in the closure passed to array_filter', $code_location), $statements_source->getSuppressedIssues());
                    return Type::getArray();
                }
                /** @var list<PhpParser\Node\Stmt> */
                $function_call_stmts = $function_call_arg->value->getStmts();
                if (count($function_call_stmts) === 1 && count($function_call_arg->value->params)) {
                    $first_param = $function_call_arg->value->params[0];
                    $stmt = $function_call_stmts[0];
                    if ($first_param->variadic === \false && $first_param->var instanceof PhpParser\Node\Expr\Variable && is_string($first_param->var->name) && $stmt instanceof PhpParser\Node\Stmt\Return_ && $stmt->expr) {
                        $codebase = $statements_source->getCodebase();
                        $cond_object_id = spl_object_id($stmt->expr);
                        try {
                            $filter_clauses = FormulaGenerator::getFormula($cond_object_id, $cond_object_id, $stmt->expr, $context->self, $statements_source, $codebase);
                        } catch (ComplicatedExpressionException $e) {
                            $filter_clauses = [];
                        }
                        $assertions = Algebra::getTruthsFromFormula($filter_clauses, $cond_object_id);
                        if (isset($assertions['$' . $first_param->var->name])) {
                            $changed_var_ids = [];
                            $assertions = ['$inner_type' => $assertions['$' . $first_param->var->name]];
                            [$reconciled_types, $_] = Reconciler::reconcileKeyedTypes($assertions, $assertions, ['$inner_type' => $inner_type], [], $changed_var_ids, ['$inner_type' => \true], $statements_source, $statements_source->getTemplateTypeMap() ?: [], \false, new CodeLocation($statements_source, $stmt));
                            if (isset($reconciled_types['$inner_type'])) {
                                $inner_type = $reconciled_types['$inner_type'];
                            }
                        }
                    }
                }
            }
            return new Union([new TArray([$key_type, $inner_type])]);
        }
        if ($inner_type->isUnionEmpty()) {
            return Type::getEmptyArray();
        }
        return new Union([new TArray([$key_type, $inner_type])]);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Union;
use function count;
/**
 * @internal
 */
class RandReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['rand', 'mt_rand', 'random_int'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $call_args = $event->getCallArgs();
        if (count($call_args) === 0) {
            return Type::getInt();
        }
        if (count($call_args) !== 2) {
            return null;
        }
        $statements_source = $event->getStatementsSource();
        $nodeTypeProvider = $statements_source->getNodeTypeProvider();
        $first_arg = $nodeTypeProvider->getType($call_args[0]->value);
        $second_arg = $nodeTypeProvider->getType($call_args[1]->value);
        $min_value = null;
        if ($first_arg !== null && $first_arg->isSingle()) {
            $first_atomic_type = $first_arg->getSingleAtomic();
            if ($first_atomic_type instanceof TLiteralInt) {
                $min_value = $first_atomic_type->value;
            } elseif ($first_atomic_type instanceof TIntRange) {
                $min_value = $first_atomic_type->min_bound;
            }
        }
        $max_value = null;
        if ($second_arg !== null && $second_arg->isSingle()) {
            $second_atomic_type = $second_arg->getSingleAtomic();
            if ($second_atomic_type instanceof TLiteralInt) {
                $max_value = $second_atomic_type->value;
            } elseif ($second_atomic_type instanceof TIntRange) {
                $max_value = $second_atomic_type->max_bound;
            }
        }
        return new Union([new TIntRange($min_value, $max_value)]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use function count;
/**
 * @internal
 */
class VersionCompareReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['version_compare'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        if (count($call_args) > 2) {
            $operator_type = $statements_source->node_data->getType($call_args[2]->value);
            if ($operator_type) {
                if (!$operator_type->hasMixed()) {
                    $acceptable_operator_type = new Union([new TLiteralString('<'), new TLiteralString('lt'), new TLiteralString('<='), new TLiteralString('le'), new TLiteralString('>'), new TLiteralString('gt'), new TLiteralString('>='), new TLiteralString('ge'), new TLiteralString('=='), new TLiteralString('='), new TLiteralString('eq'), new TLiteralString('!='), new TLiteralString('<>'), new TLiteralString('ne')]);
                    $codebase = $statements_source->getCodebase();
                    if (UnionTypeComparator::isContainedBy($codebase, $operator_type, $acceptable_operator_type)) {
                        return Type::getBool();
                    }
                }
            }
            return new Union([new TBool(), new TNull()]);
        }
        return new Union([new TLiteralInt(-1), new TLiteralInt(0), new TLiteralInt(1)]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArrayUniqueReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_unique'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $first_arg = $call_args[0]->value ?? null;
        $first_arg_array = $first_arg && ($first_arg_type = $statements_source->node_data->getType($first_arg)) && $first_arg_type->hasType('array') && ($array_atomic_type = $first_arg_type->getArray()) && ($array_atomic_type instanceof TArray || $array_atomic_type instanceof TKeyedArray) ? $array_atomic_type : null;
        if (!$first_arg_array) {
            return Type::getArray();
        }
        if ($first_arg_array instanceof TArray) {
            if ($first_arg_array instanceof TNonEmptyArray) {
                $first_arg_array = $first_arg_array->setCount(null);
            }
            return new Union([$first_arg_array]);
        }
        return new Union([$first_arg_array->getGenericArrayType()]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
use function call_user_func;
use function count;
use function in_array;
/**
 * @internal
 */
class StrReplaceReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['str_replace', 'str_ireplace', 'substr_replace', 'preg_replace', 'preg_replace_callback'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $function_id = $event->getFunctionId();
        if (!$statements_source instanceof StatementsAnalyzer || count($call_args) < 3) {
            return Type::getMixed();
        }
        if ($subject_type = $statements_source->node_data->getType($call_args[2]->value)) {
            if (!$subject_type->hasString() && $subject_type->hasArray()) {
                return Type::getArray();
            }
            $return_type = Type::getString();
            if (in_array($function_id, ['str_replace', 'str_ireplace'], \true) && $subject_type->isSingleStringLiteral()) {
                $first_arg = $statements_source->node_data->getType($call_args[0]->value);
                $second_arg = $statements_source->node_data->getType($call_args[1]->value);
                if ($first_arg && $second_arg && $first_arg->isSingleStringLiteral() && $second_arg->isSingleStringLiteral()) {
                    /**
                     * @var string $replaced_string
                     */
                    $replaced_string = call_user_func($function_id, $first_arg->getSingleStringLiteral()->value, $second_arg->getSingleStringLiteral()->value, $subject_type->getSingleStringLiteral()->value);
                    $return_type = Type::getString($replaced_string);
                }
            } elseif (in_array($function_id, ['preg_replace', 'preg_replace_callback'], \true)) {
                $codebase = $statements_source->getCodebase();
                $return_type = new Union([new TString(), new TNull()], ['ignore_nullable_issues' => $codebase->config->ignore_internal_nullable_issues]);
            }
            return $return_type;
        }
        return Type::getMixed();
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Union;
use UnexpectedValueException;
use function in_array;
/**
 * @internal
 */
class StrTrReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['strtr'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        $function_id = $event->getFunctionId();
        $code_location = $event->getCodeLocation();
        if (!$statements_source instanceof StatementsAnalyzer) {
            throw new UnexpectedValueException();
        }
        $type = Type::getString();
        if ($statements_source->data_flow_graph && !in_array('TaintedInput', $statements_source->getSuppressedIssues())) {
            $function_return_sink = DataFlowNode::getForMethodReturn($function_id, $function_id, null, $code_location);
            $statements_source->data_flow_graph->addNode($function_return_sink);
            foreach ($call_args as $i => $_) {
                $function_param_sink = DataFlowNode::getForMethodArgument($function_id, $function_id, $i, null, $code_location);
                $statements_source->data_flow_graph->addNode($function_param_sink);
                $statements_source->data_flow_graph->addPath($function_param_sink, $function_return_sink, 'arg');
            }
            return $type->setParentNodes([$function_return_sink->id => $function_return_sink]);
        }
        return $type;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_merge;
use function array_shift;
/**
 * @internal
 */
class ArraySliceReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_slice'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $first_arg = $call_args[0]->value ?? null;
        if (!$first_arg) {
            return Type::getArray();
        }
        $first_arg_type = $statements_source->node_data->getType($first_arg);
        if (!$first_arg_type) {
            return Type::getArray();
        }
        $atomic_types = $first_arg_type->getAtomicTypes();
        $return_atomic_type = null;
        while ($atomic_type = array_shift($atomic_types)) {
            if ($atomic_type instanceof TTemplateParam) {
                $atomic_types = array_merge($atomic_types, $atomic_type->as->getAtomicTypes());
                continue;
            }
            if ($atomic_type instanceof TList) {
                $atomic_type = $atomic_type->getKeyedArray();
            }
            if ($atomic_type instanceof TKeyedArray) {
                $atomic_type = $atomic_type->getGenericArrayType();
            }
            if ($atomic_type instanceof TArray) {
                $return_atomic_type = new TArray($atomic_type->type_params);
                continue;
            }
            return Type::getArray();
        }
        if (!$return_atomic_type) {
            throw new UnexpectedValueException('This should never happen');
        }
        $dont_preserve_int_keys = !isset($call_args[3]->value) || ($third_arg_type = $statements_source->node_data->getType($call_args[3]->value)) && (string) $third_arg_type === 'false';
        if ($dont_preserve_int_keys && $return_atomic_type->type_params[0]->isInt()) {
            $return_atomic_type = Type::getListAtomic($return_atomic_type->type_params[1]);
        }
        return new Union([$return_atomic_type]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
/**
 * @internal
 */
class FirstArgStringReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['crypt'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer || !$call_args) {
            return Type::getMixed();
        }
        if (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value)) && $first_arg_type->isString()) {
            return new Union([new TString()]);
        }
        return new Union([new TString(), new TNull()], ['ignore_nullable_issues' => \true]);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Type\TypeCombiner;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
use function in_array;
use const E_USER_DEPRECATED;
use const E_USER_ERROR;
use const E_USER_NOTICE;
use const E_USER_WARNING;
/**
 * @internal
 */
class TriggerErrorReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['trigger_error'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $codebase = $event->getStatementsSource()->getCodebase();
        $config = $codebase->config;
        if ($config->trigger_error_exits === 'always') {
            return Type::getNever();
        }
        if ($config->trigger_error_exits === 'never') {
            return new Union([new TTrue()]);
        }
        //default behaviour
        $call_args = $event->getCallArgs();
        $statements_source = $event->getStatementsSource();
        if (isset($call_args[1]) && ($array_arg_type = $statements_source->getNodeTypeProvider()->getType($call_args[1]->value))) {
            $return_types = [];
            foreach ($array_arg_type->getAtomicTypes() as $atomicType) {
                if ($atomicType instanceof TLiteralInt) {
                    if (in_array($atomicType->value, [E_USER_WARNING, E_USER_DEPRECATED, E_USER_NOTICE], \true)) {
                        $return_types[] = new TTrue();
                    } elseif ($atomicType->value === E_USER_ERROR) {
                        $return_types[] = new TNever();
                    } else {
                        // not recognized int literal. return false before PHP8, fatal error since
                        $return_types[] = new TFalse();
                    }
                } else {
                    $return_types[] = new TBool();
                }
            }
            return TypeCombiner::combine($return_types, $codebase);
        }
        //default value is E_USER_NOTICE, so return true
        return new Union([new TTrue()]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArrayFillReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_fill'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $codebase = $statements_source->getCodebase();
        $first_arg_type = isset($call_args[0]) ? $statements_source->node_data->getType($call_args[0]->value) : null;
        $second_arg_type = isset($call_args[1]) ? $statements_source->node_data->getType($call_args[1]->value) : null;
        $third_arg_type = isset($call_args[2]) ? $statements_source->node_data->getType($call_args[2]->value) : null;
        $value_type_from_third_arg = $third_arg_type ? $third_arg_type : Type::getMixed();
        if ($first_arg_type && $second_arg_type && $third_arg_type && $first_arg_type->isSingleIntLiteral() && $second_arg_type->isSingleIntLiteral()) {
            $first_arg_type = $first_arg_type->getSingleIntLiteral()->value;
            $second_arg_type = $second_arg_type->getSingleIntLiteral()->value;
            $is_list = $first_arg_type === 0;
            if ($second_arg_type < 0) {
                if ($codebase->analysis_php_version_id < 80000) {
                    return Type::getFalse();
                }
                return Type::getNever();
            }
            $result = [];
            if ($first_arg_type < 0 && $codebase->analysis_php_version_id < 80000) {
                $result[$first_arg_type] = $third_arg_type;
                $first_arg_type = 0;
                $second_arg_type--;
            }
            while ($second_arg_type > 0) {
                $result[$first_arg_type++] = $third_arg_type;
                $second_arg_type--;
            }
            if (!$result) {
                return Type::getEmptyArray();
            }
            return new Union([new TKeyedArray($result, null, null, $is_list)]);
        }
        if ($first_arg_type && $first_arg_type->isSingleIntLiteral() && $first_arg_type->getSingleIntLiteral()->value === 0) {
            if ($second_arg_type && self::isPositiveNumericType($second_arg_type)) {
                return Type::getNonEmptyList($value_type_from_third_arg);
            }
            return Type::getList($value_type_from_third_arg);
        }
        if ($second_arg_type && self::isPositiveNumericType($second_arg_type)) {
            if ($first_arg_type && $first_arg_type->isSingleIntLiteral() && $second_arg_type->isSingleIntLiteral()) {
                return new Union([new TNonEmptyArray([new Union([new TIntRange($first_arg_type->getSingleIntLiteral()->value, $second_arg_type->getSingleIntLiteral()->value)]), $value_type_from_third_arg])]);
            }
            return new Union([new TNonEmptyArray([Type::getInt(), $value_type_from_third_arg])]);
        }
        return new Union([new TArray([Type::getInt(), $value_type_from_third_arg])]);
    }
    private static function isPositiveNumericType(Union $arg) : bool
    {
        if ($arg->isSingle()) {
            foreach ($arg->getRangeInts() as $range_int) {
                if ($range_int->isPositive()) {
                    return \true;
                }
            }
        }
        return $arg->isSingleIntLiteral() && $arg->getSingleIntLiteral()->value > 0;
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArraySpliceReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_splice'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer) {
            return Type::getMixed();
        }
        $first_arg = $call_args[0]->value ?? null;
        $array_type = $first_arg && ($first_arg_type = $statements_source->node_data->getType($first_arg)) && $first_arg_type->hasType('array') && ($array_atomic_type = $first_arg_type->getArray()) && ($array_atomic_type instanceof TArray || $array_atomic_type instanceof TKeyedArray) ? $array_atomic_type : null;
        if (!$array_type) {
            return Type::getArray();
        }
        if ($array_type instanceof TKeyedArray) {
            $array_type = $array_type->getGenericArrayType();
        }
        if (!$array_type->type_params[0]->hasString()) {
            if ($array_type->type_params[1]->isString()) {
                $array_type = Type::getListAtomic(Type::getString());
            } elseif ($array_type->type_params[1]->isInt()) {
                $array_type = Type::getListAtomic(Type::getInt());
            } else {
                $array_type = Type::getListAtomic(Type::getMixed());
            }
        }
        return new Union([$array_type]);
    }
}
<?php

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Issue\InvalidArgument;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Union;
use function array_combine;
use function assert;
use function count;
/**
 * @internal
 */
class ArrayCombineReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_combine'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $statements_source = $event->getStatementsSource();
        $call_args = $event->getCallArgs();
        if (!$statements_source instanceof StatementsAnalyzer || count($call_args) < 2) {
            return Type::getNever();
        }
        if (!($keys_type = $statements_source->node_data->getType($call_args[0]->value))) {
            return null;
        }
        if (!$keys_type->isArray()) {
            return null;
        }
        $keys = $keys_type->getArray();
        if ($keys instanceof TArray && $keys->isEmptyArray()) {
            $keys = [];
        } elseif (!$keys instanceof TKeyedArray || $keys->fallback_params) {
            return null;
        } else {
            $keys = $keys->properties;
        }
        if (!($values_type = $statements_source->node_data->getType($call_args[1]->value))) {
            return null;
        }
        if (!$values_type->isArray()) {
            return null;
        }
        $values = $values_type->getArray();
        if ($values instanceof TArray && $values->isEmptyArray()) {
            $values = [];
        } elseif (!$values instanceof TKeyedArray || $values->fallback_params) {
            return null;
        } else {
            $values = $values->properties;
        }
        $keys_array = [];
        $is_list = \true;
        $prev_key = -1;
        foreach ($keys as $key) {
            if ($key->possibly_undefined) {
                return null;
            }
            if ($key->isSingleIntLiteral()) {
                $key = $key->getSingleIntLiteral()->value;
                $keys_array[] = $key;
                if ($is_list && $key - 1 !== $prev_key) {
                    $is_list = \false;
                }
                $prev_key = $key;
            } elseif ($key->isSingleStringLiteral()) {
                $keys_array[] = $key->getSingleStringLiteral()->value;
                $is_list = \false;
            } else {
                return null;
            }
        }
        foreach ($values as $value) {
            if ($value->possibly_undefined) {
                return null;
            }
        }
        if (count($keys_array) !== count($values)) {
            IssueBuffer::maybeAdd(new InvalidArgument('The keys array ' . $keys_type->getId() . ' must have exactly the same ' . 'number of elements as the values array ' . $values_type->getId(), $event->getCodeLocation(), 'array_combine'), $statements_source->getSuppressedIssues());
            return $statements_source->getCodebase()->analysis_php_version_id >= 80000 ? Type::getNever() : Type::getFalse();
        }
        $result = array_combine($keys_array, $values);
        assert($result !== \false);
        if (!$result) {
            return Type::getEmptyArray();
        }
        return new Union([new TKeyedArray($result, null, null, $is_list)]);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Internal\Type\ArrayType;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
use function count;
/**
 * @internal
 */
class ArrayChunkReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array
    {
        return ['array_chunk'];
    }
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union
    {
        $call_args = $event->getCallArgs();
        $statements_source = $event->getStatementsSource();
        if (count($call_args) >= 2 && ($array_arg_type = $statements_source->getNodeTypeProvider()->getType($call_args[0]->value)) && $array_arg_type->isSingle() && $array_arg_type->hasArray() && ($array_type = ArrayType::infer($array_arg_type->getArray()))) {
            $preserve_keys = isset($call_args[2]) && ($preserve_keys_arg_type = $statements_source->getNodeTypeProvider()->getType($call_args[2]->value)) && (string) $preserve_keys_arg_type !== 'false';
            return Type::getList(new Union([$preserve_keys ? new TNonEmptyArray([$array_type->key, $array_type->value]) : Type::getNonEmptyListAtomic($array_type->value)]));
        }
        return new Union([Type::getListAtomic(Type::getArray())]);
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Plugin\EventHandler\Event\PropertyExistenceProviderEvent;
use Psalm\Plugin\EventHandler\PropertyExistenceProviderInterface;
use Psalm\StatementsSource;
use function is_subclass_of;
use function strtolower;
/**
 * @internal
 */
class PropertyExistenceProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(PropertyExistenceProviderEvent): ?bool>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
    }
    /**
     * @param class-string<LegacyPropertyExistenceProviderInterface>
     *     |class-string<PropertyExistenceProviderInterface> $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, PropertyExistenceProviderInterface::class, \true)) {
            $callable = Closure::fromCallable([$class, 'doesPropertyExist']);
            foreach ($class::getClassLikeNames() as $fq_classlike_name) {
                $this->registerClosure($fq_classlike_name, $callable);
            }
        }
    }
    /**
     * @param Closure(PropertyExistenceProviderEvent): ?bool $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    public function doesPropertyExist(string $fq_classlike_name, string $property_name, bool $read_mode, ?StatementsSource $source = null, ?Context $context = null, ?CodeLocation $code_location = null) : ?bool
    {
        foreach (self::$handlers[strtolower($fq_classlike_name)] ?? [] as $property_handler) {
            $event = new PropertyExistenceProviderEvent($fq_classlike_name, $property_name, $read_mode, $source, $context, $code_location);
            $property_exists = $property_handler($event);
            if ($property_exists !== null) {
                return $property_exists;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Plugin\EventHandler\Event\FunctionParamsProviderEvent;
use Psalm\Plugin\EventHandler\FunctionParamsProviderInterface;
use Psalm\StatementsSource;
use Psalm\Storage\FunctionLikeParameter;
use function strtolower;
/**
 * @internal
 */
class FunctionParamsProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(FunctionParamsProviderEvent): ?array<int, FunctionLikeParameter>>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
    }
    /**
     * @param class-string<FunctionParamsProviderInterface> $class
     */
    public function registerClass(string $class) : void
    {
        $callable = Closure::fromCallable([$class, 'getFunctionParams']);
        foreach ($class::getFunctionIds() as $function_id) {
            $this->registerClosure($function_id, $callable);
        }
    }
    /**
     * @param Closure(FunctionParamsProviderEvent): ?array<int, FunctionLikeParameter> $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    /**
     * @param list<Arg> $call_args
     * @return  ?array<int, FunctionLikeParameter>
     */
    public function getFunctionParams(StatementsSource $statements_source, string $function_id, array $call_args, ?Context $context = null, ?CodeLocation $code_location = null) : ?array
    {
        foreach (self::$handlers[strtolower($function_id)] ?? [] as $class_handler) {
            $event = new FunctionParamsProviderEvent($statements_source, $function_id, $call_args, $context, $code_location);
            $result = $class_handler($event);
            if ($result) {
                return $result;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use InvalidArgumentException;
use Psalm\Storage\FileStorage;
use function array_merge;
use function strtolower;
/**
 * @internal
 */
class FileStorageProvider
{
    /**
     * A list of data useful to analyse files
     * Storing this statically is much faster (at least in PHP 7.2.1)
     *
     * @var array<lowercase-string, FileStorage>
     */
    private static array $storage = [];
    /**
     * A list of data useful to analyse new files
     * Storing this statically is much faster (at least in PHP 7.2.1)
     *
     * @var array<string, FileStorage>
     */
    private static array $new_storage = [];
    public ?\Psalm\Internal\Provider\FileStorageCacheProvider $cache = null;
    public function __construct(?\Psalm\Internal\Provider\FileStorageCacheProvider $cache = null)
    {
        $this->cache = $cache;
    }
    public function get(string $file_path) : FileStorage
    {
        $file_path = strtolower($file_path);
        if (!isset(self::$storage[$file_path])) {
            throw new InvalidArgumentException('Could not get file storage for ' . $file_path);
        }
        return self::$storage[$file_path];
    }
    public function remove(string $file_path) : void
    {
        unset(self::$storage[strtolower($file_path)]);
    }
    public function has(string $file_path, ?string $file_contents = null) : bool
    {
        $file_path = strtolower($file_path);
        if (isset(self::$storage[$file_path])) {
            return \true;
        }
        if ($file_contents === null) {
            return \false;
        }
        if (!$this->cache) {
            return \false;
        }
        $cached_value = $this->cache->getLatestFromCache($file_path, $file_contents);
        if (!$cached_value) {
            return \false;
        }
        self::$storage[$file_path] = $cached_value;
        self::$new_storage[$file_path] = $cached_value;
        return \true;
    }
    /**
     * @return array<lowercase-string, FileStorage>
     */
    public function getAll() : array
    {
        return self::$storage;
    }
    /**
     * @return array<string, FileStorage>
     */
    public function getNew() : array
    {
        return self::$new_storage;
    }
    /**
     * @param array<lowercase-string, FileStorage> $more
     */
    public function addMore(array $more) : void
    {
        self::$new_storage = array_merge(self::$new_storage, $more);
        self::$storage = array_merge(self::$storage, $more);
    }
    public function create(string $file_path) : FileStorage
    {
        $file_path_lc = strtolower($file_path);
        $storage = new FileStorage($file_path);
        self::$storage[$file_path_lc] = $storage;
        self::$new_storage[$file_path_lc] = $storage;
        return $storage;
    }
    public static function deleteAll() : void
    {
        self::$storage = [];
    }
    public static function populated() : void
    {
        self::$new_storage = [];
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider;

use Closure;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\ArgTypeInferer;
use Psalm\Plugin\DynamicFunctionStorage;
use Psalm\Plugin\DynamicTemplateProvider;
use Psalm\Plugin\EventHandler\DynamicFunctionStorageProviderInterface;
use Psalm\Plugin\EventHandler\Event\DynamicFunctionStorageProviderEvent;
use Psalm\Storage\FunctionStorage;
use function strtolower;
/**
 * For each function call analysis will be created individual FunctionStorage in plugin hook.
 * If it is created be aware, it shadows the FunctionStorage Psalm may generate during the scanning phase.
 *
 * @internal
 */
final class DynamicFunctionStorageProvider
{
    /** @var array<lowercase-string, array<Closure(DynamicFunctionStorageProviderEvent): ?DynamicFunctionStorage>> */
    private static array $handlers = [];
    /** @var array<lowercase-string, ?FunctionStorage> */
    private static array $dynamic_storages = [];
    /**
     * @param class-string<DynamicFunctionStorageProviderInterface> $class
     */
    public function registerClass(string $class) : void
    {
        $callable = Closure::fromCallable([$class, 'getFunctionStorage']);
        foreach ($class::getFunctionIds() as $function_id) {
            $this->registerClosure($function_id, $callable);
        }
    }
    /**
     * @param Closure(DynamicFunctionStorageProviderEvent): ?DynamicFunctionStorage $c
     */
    public function registerClosure(string $fq_function_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_function_name)][] = $c;
    }
    public function has(string $fq_function_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_function_name)]);
    }
    public function getFunctionStorage(PhpParser\Node\Expr\FuncCall $stmt, StatementsAnalyzer $statements_analyzer, string $function_id, Context $context, CodeLocation $code_location) : ?FunctionStorage
    {
        if ($stmt->isFirstClassCallable()) {
            return null;
        }
        $dynamic_storage_id = strtolower($statements_analyzer->getFilePath()) . ':' . $stmt->getLine() . ':' . (int) $stmt->getAttribute('startFilePos') . ':dynamic-storage' . ':-:' . strtolower($function_id);
        if (isset(self::$dynamic_storages[$dynamic_storage_id])) {
            return self::$dynamic_storages[$dynamic_storage_id];
        }
        foreach (self::$handlers[strtolower($function_id)] ?? [] as $class_handler) {
            $event = new DynamicFunctionStorageProviderEvent(new ArgTypeInferer($context, $statements_analyzer), new DynamicTemplateProvider('fn-' . strtolower($function_id)), $statements_analyzer, $function_id, $stmt, $context, $code_location);
            $result = $class_handler($event);
            return self::$dynamic_storages[$dynamic_storage_id] = $result ? $result->toFunctionStorage($function_id) : null;
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use function microtime;
use function strpos;
/**
 * @internal
 */
class FakeFileProvider extends \Psalm\Internal\Provider\FileProvider
{
    /**
     * @var array<string, string>
     */
    public array $fake_files = [];
    /**
     * @var array<string, int>
     */
    public array $fake_file_times = [];
    public function fileExists(string $file_path) : bool
    {
        return isset($this->fake_files[$file_path]) || parent::fileExists($file_path);
    }
    /** @psalm-external-mutation-free */
    public function getContents(string $file_path, bool $go_to_source = \false) : string
    {
        if (!$go_to_source && isset($this->temp_files[$file_path])) {
            return $this->temp_files[$file_path];
        }
        return $this->fake_files[$file_path] ?? parent::getContents($file_path);
    }
    public function setContents(string $file_path, string $file_contents) : void
    {
        $this->fake_files[$file_path] = $file_contents;
    }
    public function setOpenContents(string $file_path, string $file_contents) : void
    {
        if (isset($this->fake_files[$file_path])) {
            $this->fake_files[$file_path] = $file_contents;
        }
    }
    public function getModifiedTime(string $file_path) : int
    {
        return $this->fake_file_times[$file_path] ?? parent::getModifiedTime($file_path);
    }
    public function registerFile(string $file_path, string $file_contents) : void
    {
        $this->fake_files[$file_path] = $file_contents;
        $this->fake_file_times[$file_path] = (int) microtime(\true);
    }
    /**
     * @param array<string> $file_extensions
     * @param null|callable(string):bool $filter
     * @return list<string>
     */
    public function getFilesInDir(string $dir_path, array $file_extensions, callable $filter = null) : array
    {
        $file_paths = parent::getFilesInDir($dir_path, $file_extensions, $filter);
        foreach ($this->fake_files as $file_path => $_) {
            if (strpos($file_path, $dir_path) === 0) {
                $file_paths[] = $file_path;
            }
        }
        return $file_paths;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use Psalm\Plugin\EventHandler\Event\FunctionExistenceProviderEvent;
use Psalm\Plugin\EventHandler\FunctionExistenceProviderInterface;
use Psalm\StatementsSource;
use function is_subclass_of;
use function strtolower;
/**
 * @internal
 */
class FunctionExistenceProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(FunctionExistenceProviderEvent): ?bool>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
    }
    /**
     * @param class-string $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, FunctionExistenceProviderInterface::class, \true)) {
            $callable = Closure::fromCallable([$class, 'doesFunctionExist']);
            foreach ($class::getFunctionIds() as $function_id) {
                $this->registerClosure($function_id, $callable);
            }
        }
    }
    /**
     * @param lowercase-string $function_id
     * @param Closure(FunctionExistenceProviderEvent): ?bool $c
     */
    public function registerClosure(string $function_id, Closure $c) : void
    {
        self::$handlers[$function_id][] = $c;
    }
    public function has(string $function_id) : bool
    {
        return isset(self::$handlers[strtolower($function_id)]);
    }
    public function doesFunctionExist(StatementsSource $statements_source, string $function_id) : ?bool
    {
        foreach (self::$handlers[strtolower($function_id)] ?? [] as $function_handler) {
            $event = new FunctionExistenceProviderEvent($statements_source, $function_id);
            $function_exists = $function_handler($event);
            if ($function_exists !== null) {
                return $function_exists;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use FilesystemIterator;
use RecursiveCallbackFilterIterator;
use RecursiveDirectoryIterator;
use RecursiveIterator;
use RecursiveIteratorIterator;
use UnexpectedValueException;
use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function filemtime;
use function in_array;
use function is_dir;
use const DIRECTORY_SEPARATOR;
/**
 * @internal
 */
class FileProvider
{
    /**
     * @var array<string, string>
     */
    protected array $temp_files = [];
    /**
     * @var array<string, string>
     */
    protected static array $open_files = [];
    /** @psalm-mutation-free */
    public function getContents(string $file_path, bool $go_to_source = \false) : string
    {
        if (!$go_to_source && isset($this->temp_files[$file_path])) {
            return $this->temp_files[$file_path];
        }
        /** @psalm-suppress ImpureStaticProperty Used only for caching */
        if (isset(self::$open_files[$file_path])) {
            return self::$open_files[$file_path];
        }
        /** @psalm-suppress ImpureFunctionCall For our purposes, this should not mutate external state */
        if (!file_exists($file_path)) {
            throw new UnexpectedValueException('File ' . $file_path . ' should exist to get contents');
        }
        /** @psalm-suppress ImpureFunctionCall For our purposes, this should not mutate external state */
        if (is_dir($file_path)) {
            throw new UnexpectedValueException('File ' . $file_path . ' is a directory');
        }
        /** @psalm-suppress ImpureFunctionCall For our purposes, this should not mutate external state */
        $file_contents = (string) file_get_contents($file_path);
        /** @psalm-suppress ImpureStaticProperty Used only for caching */
        self::$open_files[$file_path] = $file_contents;
        return $file_contents;
    }
    public function setContents(string $file_path, string $file_contents) : void
    {
        if (isset(self::$open_files[$file_path])) {
            self::$open_files[$file_path] = $file_contents;
        }
        if (isset($this->temp_files[$file_path])) {
            $this->temp_files[$file_path] = $file_contents;
        }
        file_put_contents($file_path, $file_contents);
    }
    public function setOpenContents(string $file_path, string $file_contents) : void
    {
        if (isset(self::$open_files[$file_path])) {
            self::$open_files[$file_path] = $file_contents;
        }
    }
    public function getModifiedTime(string $file_path) : int
    {
        if (!file_exists($file_path)) {
            throw new UnexpectedValueException('File should exist to get modified time');
        }
        return (int) filemtime($file_path);
    }
    public function addTemporaryFileChanges(string $file_path, string $new_content) : void
    {
        $this->temp_files[$file_path] = $new_content;
    }
    public function removeTemporaryFileChanges(string $file_path) : void
    {
        unset($this->temp_files[$file_path]);
    }
    public function openFile(string $file_path) : void
    {
        self::$open_files[$file_path] = $this->getContents($file_path, \true);
    }
    public function isOpen(string $file_path) : bool
    {
        return isset($this->temp_files[$file_path]) || isset(self::$open_files[$file_path]);
    }
    public function closeFile(string $file_path) : void
    {
        unset($this->temp_files[$file_path], self::$open_files[$file_path]);
    }
    public function fileExists(string $file_path) : bool
    {
        return file_exists($file_path);
    }
    /**
     * @param array<string> $file_extensions
     * @param null|callable(string):bool $filter
     * @return list<string>
     */
    public function getFilesInDir(string $dir_path, array $file_extensions, callable $filter = null) : array
    {
        $file_paths = [];
        $iterator = new RecursiveDirectoryIterator($dir_path, FilesystemIterator::CURRENT_AS_PATHNAME | FilesystemIterator::SKIP_DOTS);
        if ($filter !== null) {
            $iterator = new RecursiveCallbackFilterIterator(
                $iterator,
                /** @param mixed $_ */
                static function (string $current, $_, RecursiveIterator $iterator) use($filter) : bool {
                    if ($iterator->hasChildren()) {
                        $path = $current . DIRECTORY_SEPARATOR;
                    } else {
                        $path = $current;
                    }
                    return $filter($path);
                }
            );
        }
        /** @var RecursiveDirectoryIterator */
        $iterator = new RecursiveIteratorIterator($iterator);
        $iterator->rewind();
        while ($iterator->valid()) {
            $extension = $iterator->getExtension();
            if (in_array($extension, $file_extensions, \true)) {
                $file_paths[] = (string) $iterator->getRealPath();
            }
            $iterator->next();
        }
        return $file_paths;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Psalm\Config;
use Psalm\Storage\ClassLikeStorage;
use RuntimeException;
use UnexpectedValueException;
use function array_merge;
use function dirname;
use function file_exists;
use function file_put_contents;
use function filemtime;
use function get_class;
use function hash;
use function igbinary_serialize;
use function igbinary_unserialize;
use function is_dir;
use function is_null;
use function mkdir;
use function serialize;
use function strtolower;
use function unlink;
use function unserialize;
use const DIRECTORY_SEPARATOR;
use const LOCK_EX;
use const PHP_VERSION_ID;
/**
 * @internal
 */
class ClassLikeStorageCacheProvider
{
    private Config $config;
    private string $modified_timestamps = '';
    private const CLASS_CACHE_DIRECTORY = 'class_cache';
    public function __construct(Config $config)
    {
        $this->config = $config;
        $storage_dir = dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . 'Storage' . DIRECTORY_SEPARATOR;
        $dependent_files = [$storage_dir . 'FileStorage.php', $storage_dir . 'FunctionLikeStorage.php', $storage_dir . 'ClassLikeStorage.php', $storage_dir . 'MethodStorage.php'];
        if ($config->eventDispatcher->hasAfterClassLikeVisitHandlers()) {
            $dependent_files = array_merge($dependent_files, $config->plugin_paths);
        }
        foreach ($dependent_files as $dependent_file_path) {
            if (!file_exists($dependent_file_path)) {
                throw new UnexpectedValueException($dependent_file_path . ' must exist');
            }
            $this->modified_timestamps .= ' ' . filemtime($dependent_file_path);
        }
        $this->modified_timestamps .= $this->config->computeHash();
    }
    public function writeToCache(ClassLikeStorage $storage, string $file_path, string $file_contents) : void
    {
        $fq_classlike_name_lc = strtolower($storage->name);
        $storage->hash = $this->getCacheHash($file_path, $file_contents);
        // check if we have it in cache already
        $cached_value = $this->loadFromCache($fq_classlike_name_lc, $file_path);
        if (!is_null($cached_value) && $cached_value->hash === $storage->hash) {
            return;
        }
        $cache_location = $this->getCacheLocationForClass($fq_classlike_name_lc, $file_path, \true);
        if ($this->config->use_igbinary) {
            file_put_contents($cache_location, igbinary_serialize($storage), LOCK_EX);
        } else {
            file_put_contents($cache_location, serialize($storage), LOCK_EX);
        }
    }
    public function getLatestFromCache(string $fq_classlike_name_lc, ?string $file_path, ?string $file_contents) : ClassLikeStorage
    {
        $cached_value = $this->loadFromCache($fq_classlike_name_lc, $file_path);
        if (!$cached_value) {
            throw new UnexpectedValueException($fq_classlike_name_lc . ' should be in cache');
        }
        $cache_hash = $this->getCacheHash($file_path, $file_contents);
        /** @psalm-suppress TypeDoesNotContainType */
        if (@get_class($cached_value) === '__PHP_Incomplete_Class' || $cache_hash !== $cached_value->hash) {
            unlink($this->getCacheLocationForClass($fq_classlike_name_lc, $file_path));
            throw new UnexpectedValueException($fq_classlike_name_lc . ' should not be outdated');
        }
        return $cached_value;
    }
    private function getCacheHash(?string $_unused_file_path, ?string $file_contents) : string
    {
        $data = $file_contents ? $file_contents : $this->modified_timestamps;
        return PHP_VERSION_ID >= 80100 ? hash('xxh128', $data) : hash('md4', $data);
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    private function loadFromCache(string $fq_classlike_name_lc, ?string $file_path) : ?ClassLikeStorage
    {
        $cache_location = $this->getCacheLocationForClass($fq_classlike_name_lc, $file_path);
        if (file_exists($cache_location)) {
            if ($this->config->use_igbinary) {
                $storage = igbinary_unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location));
                if ($storage instanceof ClassLikeStorage) {
                    return $storage;
                }
                return null;
            }
            $storage = unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location));
            if ($storage instanceof ClassLikeStorage) {
                return $storage;
            }
            return null;
        }
        return null;
    }
    private function getCacheLocationForClass(string $fq_classlike_name_lc, ?string $file_path, bool $create_directory = \false) : string
    {
        $root_cache_directory = $this->config->getCacheDirectory();
        if (!$root_cache_directory) {
            throw new UnexpectedValueException('No cache directory defined');
        }
        $parser_cache_directory = $root_cache_directory . DIRECTORY_SEPARATOR . self::CLASS_CACHE_DIRECTORY;
        if ($create_directory && !is_dir($parser_cache_directory)) {
            try {
                if (mkdir($parser_cache_directory, 0777, \true) === \false) {
                    // any other error than directory already exists/permissions issue
                    throw new RuntimeException('Failed to create ' . $parser_cache_directory . ' cache directory for unknown reasons');
                }
            } catch (RuntimeException $e) {
                // Race condition (#4483)
                if (!is_dir($parser_cache_directory)) {
                    // rethrow the error with default message
                    // it contains the reason why creation failed
                    throw $e;
                }
            }
        }
        $data = $file_path ? strtolower($file_path) . ' ' : '';
        $data .= $fq_classlike_name_lc;
        $file_path_sha = PHP_VERSION_ID >= 80100 ? hash('xxh128', $data) : hash('md4', $data);
        return $parser_cache_directory . DIRECTORY_SEPARATOR . $file_path_sha . ($this->config->use_igbinary ? '-igbinary' : '');
    }
}
<?php

namespace Psalm\Internal\Provider;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use function array_key_exists;
use function array_search;
use function array_splice;
use function count;
use function is_null;
use function key;
use function reset;
/**
 * @internal Owned by StatementsProvider
 * @todo: track variables size instead
 */
final class StatementsVolatileCache
{
    /**
     * @var array<string, list<Stmt>>
     */
    protected array $cache = [];
    /**
     * @var array<int, string>
     */
    protected array $access = [];
    protected int $max_size;
    protected static ?\Psalm\Internal\Provider\StatementsVolatileCache $instance = null;
    public function __construct(int $max_size = 4096)
    {
        $this->max_size = $max_size;
    }
    public static function getInstance() : \Psalm\Internal\Provider\StatementsVolatileCache
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    public function has(string $key) : bool
    {
        return array_key_exists($key, $this->cache);
    }
    /**
     * @return list<Stmt>
     * @throws InvalidArgumentException
     */
    public function get(string $key) : array
    {
        if (!$this->has($key)) {
            throw new InvalidArgumentException('Given $key does not exists');
        }
        $access_index = array_search($key, $this->access);
        if (\false !== $access_index) {
            array_splice($this->access, $access_index, 1);
        }
        $this->access[] = $key;
        return $this->cache[$key];
    }
    /**
     * @param list<Stmt> $content
     */
    public function set(string $key, array $content) : void
    {
        if (count($this->cache) > $this->max_size) {
            reset($this->access);
            $oldest_key_index = key($this->access);
            if (!is_null($oldest_key_index)) {
                $oldest_key = $this->access[$oldest_key_index];
                unset($this->cache[$oldest_key]);
                unset($this->access[$oldest_key_index]);
            }
        }
        $this->cache[$key] = $content;
        $this->access[] = $key;
    }
    public function clearCache() : void
    {
        $this->cache = [];
        $this->access = [];
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Provider\ReturnTypeProvider\ClosureFromCallableReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\DateTimeModifyReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\DomNodeAppendChild;
use Psalm\Internal\Provider\ReturnTypeProvider\ImagickPixelColorReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\PdoStatementReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\SimpleXmlElementAsXml;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\StatementsSource;
use Psalm\Type\Union;
use function is_subclass_of;
use function strtolower;
/**
 * @internal
 */
class MethodReturnTypeProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(MethodReturnTypeProviderEvent): ?Union>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
        $this->registerClass(DomNodeAppendChild::class);
        $this->registerClass(ImagickPixelColorReturnTypeProvider::class);
        $this->registerClass(SimpleXmlElementAsXml::class);
        $this->registerClass(PdoStatementReturnTypeProvider::class);
        $this->registerClass(ClosureFromCallableReturnTypeProvider::class);
        $this->registerClass(DateTimeModifyReturnTypeProvider::class);
    }
    /**
     * @param class-string $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, MethodReturnTypeProviderInterface::class, \true)) {
            $callable = Closure::fromCallable([$class, 'getMethodReturnType']);
            foreach ($class::getClassLikeNames() as $fq_classlike_name) {
                $this->registerClosure($fq_classlike_name, $callable);
            }
        }
    }
    /**
     * @param Closure(MethodReturnTypeProviderEvent): ?Union $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    /**
     * @param PhpParser\Node\Expr\MethodCall|PhpParser\Node\Expr\StaticCall $stmt
     * @param non-empty-list<Union>|null $template_type_parameters
     */
    public function getReturnType(StatementsSource $statements_source, string $fq_classlike_name, string $method_name, $stmt, Context $context, CodeLocation $code_location, ?array $template_type_parameters = null, ?string $called_fq_classlike_name = null, ?string $called_method_name = null) : ?Union
    {
        foreach (self::$handlers[strtolower($fq_classlike_name)] ?? [] as $class_handler) {
            $event = new MethodReturnTypeProviderEvent($statements_source, $fq_classlike_name, strtolower($method_name), $stmt, $context, $code_location, $template_type_parameters, $called_fq_classlike_name, $called_method_name ? strtolower($called_method_name) : null);
            $result = $class_handler($event);
            if ($result) {
                return $result;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Psalm\Config;
use Psalm\Internal\Codebase\Analyzer;
use Psalm\Internal\Provider\Providers;
use RuntimeException;
use UnexpectedValueException;
use function file_exists;
use function file_put_contents;
use function igbinary_serialize;
use function igbinary_unserialize;
use function is_array;
use function is_dir;
use function is_readable;
use function mkdir;
use function serialize;
use function unserialize;
use const DIRECTORY_SEPARATOR;
use const LOCK_EX;
/**
 * @psalm-import-type FileMapType from Analyzer
 *
 * Used to determine which files reference other files, necessary for using the --diff
 * option from the command line.
 * @internal
 */
class FileReferenceCacheProvider
{
    private const REFERENCE_CACHE_NAME = 'references';
    private const CLASSLIKE_FILE_CACHE_NAME = 'classlike_files';
    private const NONMETHOD_CLASS_REFERENCE_CACHE_NAME = 'file_class_references';
    private const METHOD_CLASS_REFERENCE_CACHE_NAME = 'method_class_references';
    private const ANALYZED_METHODS_CACHE_NAME = 'analyzed_methods';
    private const CLASS_METHOD_CACHE_NAME = 'class_method_references';
    private const METHOD_DEPENDENCIES_CACHE_NAME = 'class_method_dependencies';
    private const CLASS_PROPERTY_CACHE_NAME = 'class_property_references';
    private const CLASS_METHOD_RETURN_CACHE_NAME = 'class_method_return_references';
    private const FILE_METHOD_RETURN_CACHE_NAME = 'file_method_return_references';
    private const FILE_CLASS_MEMBER_CACHE_NAME = 'file_class_member_references';
    private const FILE_CLASS_PROPERTY_CACHE_NAME = 'file_class_property_references';
    private const ISSUES_CACHE_NAME = 'issues';
    private const FILE_MAPS_CACHE_NAME = 'file_maps';
    private const TYPE_COVERAGE_CACHE_NAME = 'type_coverage';
    private const CONFIG_HASH_CACHE_NAME = 'config';
    private const METHOD_MISSING_MEMBER_CACHE_NAME = 'method_missing_member';
    private const FILE_MISSING_MEMBER_CACHE_NAME = 'file_missing_member';
    private const UNKNOWN_MEMBER_CACHE_NAME = 'unknown_member_references';
    private const METHOD_PARAM_USE_CACHE_NAME = 'method_param_uses';
    protected Config $config;
    public function __construct(Config $config)
    {
        $this->config = $config;
    }
    public function hasConfigChanged() : bool
    {
        $new_hash = $this->config->computeHash();
        return $new_hash !== $this->getConfigHashCache();
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedFileReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::REFERENCE_CACHE_NAME;
        if (!is_readable($reference_cache_location)) {
            return null;
        }
        if ($this->config->use_igbinary) {
            $reference_cache = igbinary_unserialize(Providers::safeFileGetContents($reference_cache_location));
        } else {
            $reference_cache = unserialize(Providers::safeFileGetContents($reference_cache_location));
        }
        if (!is_array($reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedClassLikeFiles() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASSLIKE_FILE_CACHE_NAME;
        if (!is_readable($reference_cache_location)) {
            return null;
        }
        if ($this->config->use_igbinary) {
            $reference_cache = igbinary_unserialize(Providers::safeFileGetContents($reference_cache_location));
        } else {
            $reference_cache = unserialize(Providers::safeFileGetContents($reference_cache_location));
        }
        if (!is_array($reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedNonMethodClassReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::NONMETHOD_CLASS_REFERENCE_CACHE_NAME;
        if (!is_readable($reference_cache_location)) {
            return null;
        }
        if ($this->config->use_igbinary) {
            $reference_cache = igbinary_unserialize(Providers::safeFileGetContents($reference_cache_location));
        } else {
            $reference_cache = unserialize(Providers::safeFileGetContents($reference_cache_location));
        }
        if (!is_array($reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMethodClassReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_CLASS_REFERENCE_CACHE_NAME;
        if (!is_readable($reference_cache_location)) {
            return null;
        }
        if ($this->config->use_igbinary) {
            $reference_cache = igbinary_unserialize(Providers::safeFileGetContents($reference_cache_location));
        } else {
            $reference_cache = unserialize(Providers::safeFileGetContents($reference_cache_location));
        }
        if (!is_array($reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMethodMemberReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASS_METHOD_CACHE_NAME;
        if (!is_readable($class_member_cache_location)) {
            return null;
        }
        $class_member_reference_cache = Providers::safeFileGetContents($class_member_cache_location);
        if ($this->config->use_igbinary) {
            $class_member_reference_cache = igbinary_unserialize($class_member_reference_cache);
        } else {
            $class_member_reference_cache = unserialize($class_member_reference_cache);
        }
        if (!is_array($class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMethodDependencies() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $method_dependencies_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_DEPENDENCIES_CACHE_NAME;
        if (!is_readable($method_dependencies_cache_location)) {
            return null;
        }
        $method_dependencies_cache = Providers::safeFileGetContents($method_dependencies_cache_location);
        if ($this->config->use_igbinary) {
            $method_dependencies_cache = igbinary_unserialize($method_dependencies_cache);
        } else {
            $method_dependencies_cache = unserialize($method_dependencies_cache);
        }
        if (!is_array($method_dependencies_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $method_dependencies_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMethodPropertyReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASS_PROPERTY_CACHE_NAME;
        if (!is_readable($class_member_cache_location)) {
            return null;
        }
        $class_member_reference_cache = Providers::safeFileGetContents($class_member_cache_location);
        if ($this->config->use_igbinary) {
            $class_member_reference_cache = igbinary_unserialize($class_member_reference_cache);
        } else {
            $class_member_reference_cache = unserialize($class_member_reference_cache);
        }
        if (!is_array($class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMethodMethodReturnReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASS_METHOD_RETURN_CACHE_NAME;
        if (!is_readable($class_member_cache_location)) {
            return null;
        }
        $class_member_reference_cache = Providers::safeFileGetContents($class_member_cache_location);
        if ($this->config->use_igbinary) {
            $class_member_reference_cache = igbinary_unserialize($class_member_reference_cache);
        } else {
            $class_member_reference_cache = unserialize($class_member_reference_cache);
        }
        if (!is_array($class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMethodMissingMemberReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_MISSING_MEMBER_CACHE_NAME;
        if (!is_readable($class_member_cache_location)) {
            return null;
        }
        $class_member_reference_cache = Providers::safeFileGetContents($class_member_cache_location);
        if ($this->config->use_igbinary) {
            $class_member_reference_cache = igbinary_unserialize($class_member_reference_cache);
        } else {
            $class_member_reference_cache = unserialize($class_member_reference_cache);
        }
        if (!is_array($class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedFileMemberReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $file_class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_CLASS_MEMBER_CACHE_NAME;
        if (!is_readable($file_class_member_cache_location)) {
            return null;
        }
        $file_class_member_reference_cache = Providers::safeFileGetContents($file_class_member_cache_location);
        if ($this->config->use_igbinary) {
            $file_class_member_reference_cache = igbinary_unserialize($file_class_member_reference_cache);
        } else {
            $file_class_member_reference_cache = unserialize($file_class_member_reference_cache);
        }
        if (!is_array($file_class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $file_class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedFilePropertyReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $file_class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_CLASS_PROPERTY_CACHE_NAME;
        if (!is_readable($file_class_member_cache_location)) {
            return null;
        }
        $file_class_member_reference_cache = Providers::safeFileGetContents($file_class_member_cache_location);
        if ($this->config->use_igbinary) {
            $file_class_member_reference_cache = igbinary_unserialize($file_class_member_reference_cache);
        } else {
            $file_class_member_reference_cache = unserialize($file_class_member_reference_cache);
        }
        if (!is_array($file_class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $file_class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedFileMethodReturnReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $file_class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_METHOD_RETURN_CACHE_NAME;
        if (!is_readable($file_class_member_cache_location)) {
            return null;
        }
        $file_class_member_reference_cache = Providers::safeFileGetContents($file_class_member_cache_location);
        if ($this->config->use_igbinary) {
            $file_class_member_reference_cache = igbinary_unserialize($file_class_member_reference_cache);
        } else {
            $file_class_member_reference_cache = unserialize($file_class_member_reference_cache);
        }
        if (!is_array($file_class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $file_class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedFileMissingMemberReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $file_class_member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_MISSING_MEMBER_CACHE_NAME;
        if (!is_readable($file_class_member_cache_location)) {
            return null;
        }
        $file_class_member_reference_cache = Providers::safeFileGetContents($file_class_member_cache_location);
        if ($this->config->use_igbinary) {
            $file_class_member_reference_cache = igbinary_unserialize($file_class_member_reference_cache);
        } else {
            $file_class_member_reference_cache = unserialize($file_class_member_reference_cache);
        }
        if (!is_array($file_class_member_reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $file_class_member_reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMixedMemberNameReferences() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::UNKNOWN_MEMBER_CACHE_NAME;
        if (!is_readable($reference_cache_location)) {
            return null;
        }
        if ($this->config->use_igbinary) {
            $reference_cache = igbinary_unserialize(Providers::safeFileGetContents($reference_cache_location));
        } else {
            $reference_cache = unserialize(Providers::safeFileGetContents($reference_cache_location));
        }
        if (!is_array($reference_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedMethodParamUses() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_PARAM_USE_CACHE_NAME;
        if (!is_readable($reference_cache_location)) {
            return null;
        }
        if ($this->config->use_igbinary) {
            $reference_cache = igbinary_unserialize(Providers::safeFileGetContents($reference_cache_location));
        } else {
            $reference_cache = unserialize(Providers::safeFileGetContents($reference_cache_location));
        }
        if (!is_array($reference_cache)) {
            throw new UnexpectedValueException('The method param use cache must be an array');
        }
        return $reference_cache;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public function getCachedIssues() : ?array
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return null;
        }
        $issues_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::ISSUES_CACHE_NAME;
        if (!is_readable($issues_cache_location)) {
            return null;
        }
        if ($this->config->use_igbinary) {
            $issues_cache = igbinary_unserialize(Providers::safeFileGetContents($issues_cache_location));
        } else {
            $issues_cache = unserialize(Providers::safeFileGetContents($issues_cache_location));
        }
        if (!is_array($issues_cache)) {
            throw new UnexpectedValueException('The reference cache must be an array');
        }
        return $issues_cache;
    }
    public function setCachedFileReferences(array $file_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::REFERENCE_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($reference_cache_location, igbinary_serialize($file_references), LOCK_EX);
        } else {
            file_put_contents($reference_cache_location, serialize($file_references), LOCK_EX);
        }
    }
    public function setCachedClassLikeFiles(array $file_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASSLIKE_FILE_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($reference_cache_location, igbinary_serialize($file_references), LOCK_EX);
        } else {
            file_put_contents($reference_cache_location, serialize($file_references), LOCK_EX);
        }
    }
    public function setCachedNonMethodClassReferences(array $file_class_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::NONMETHOD_CLASS_REFERENCE_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($reference_cache_location, igbinary_serialize($file_class_references), LOCK_EX);
        } else {
            file_put_contents($reference_cache_location, serialize($file_class_references), LOCK_EX);
        }
    }
    public function setCachedMethodClassReferences(array $method_class_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_CLASS_REFERENCE_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($reference_cache_location, igbinary_serialize($method_class_references), LOCK_EX);
        } else {
            file_put_contents($reference_cache_location, serialize($method_class_references), LOCK_EX);
        }
    }
    public function setCachedMethodMemberReferences(array $member_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASS_METHOD_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($member_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($member_references), LOCK_EX);
        }
    }
    public function setCachedMethodDependencies(array $member_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_DEPENDENCIES_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($member_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($member_references), LOCK_EX);
        }
    }
    public function setCachedMethodPropertyReferences(array $property_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASS_PROPERTY_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($property_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($property_references), LOCK_EX);
        }
    }
    public function setCachedMethodMethodReturnReferences(array $method_return_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CLASS_METHOD_RETURN_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($method_return_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($method_return_references), LOCK_EX);
        }
    }
    public function setCachedMethodMissingMemberReferences(array $member_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_MISSING_MEMBER_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($member_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($member_references), LOCK_EX);
        }
    }
    public function setCachedFileMemberReferences(array $member_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_CLASS_MEMBER_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($member_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($member_references), LOCK_EX);
        }
    }
    public function setCachedFilePropertyReferences(array $property_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_CLASS_PROPERTY_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($property_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($property_references), LOCK_EX);
        }
    }
    public function setCachedFileMethodReturnReferences(array $method_return_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_METHOD_RETURN_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($method_return_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($method_return_references), LOCK_EX);
        }
    }
    public function setCachedFileMissingMemberReferences(array $member_references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $member_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_MISSING_MEMBER_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($member_cache_location, igbinary_serialize($member_references), LOCK_EX);
        } else {
            file_put_contents($member_cache_location, serialize($member_references), LOCK_EX);
        }
    }
    public function setCachedMixedMemberNameReferences(array $references) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::UNKNOWN_MEMBER_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($reference_cache_location, igbinary_serialize($references), LOCK_EX);
        } else {
            file_put_contents($reference_cache_location, serialize($references), LOCK_EX);
        }
    }
    public function setCachedMethodParamUses(array $uses) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $reference_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::METHOD_PARAM_USE_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($reference_cache_location, igbinary_serialize($uses), LOCK_EX);
        } else {
            file_put_contents($reference_cache_location, serialize($uses), LOCK_EX);
        }
    }
    public function setCachedIssues(array $issues) : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $issues_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::ISSUES_CACHE_NAME;
        if ($this->config->use_igbinary) {
            file_put_contents($issues_cache_location, igbinary_serialize($issues), LOCK_EX);
        } else {
            file_put_contents($issues_cache_location, serialize($issues), LOCK_EX);
        }
    }
    /**
     * @return array<string, array<string, int>>|false
     */
    public function getAnalyzedMethodCache()
    {
        $cache_directory = $this->config->getCacheDirectory();
        $analyzed_methods_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::ANALYZED_METHODS_CACHE_NAME;
        if ($cache_directory && file_exists($analyzed_methods_cache_location)) {
            if ($this->config->use_igbinary) {
                /** @var array<string, array<string, int>> */
                return igbinary_unserialize(Providers::safeFileGetContents($analyzed_methods_cache_location));
            } else {
                /** @var array<string, array<string, int>> */
                return unserialize(Providers::safeFileGetContents($analyzed_methods_cache_location));
            }
        }
        return \false;
    }
    /**
     * @param array<string, array<string, int>> $analyzed_methods
     */
    public function setAnalyzedMethodCache(array $analyzed_methods) : void
    {
        $cache_directory = Config::getInstance()->getCacheDirectory();
        if ($cache_directory) {
            $analyzed_methods_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::ANALYZED_METHODS_CACHE_NAME;
            if ($this->config->use_igbinary) {
                file_put_contents($analyzed_methods_cache_location, igbinary_serialize($analyzed_methods), LOCK_EX);
            } else {
                file_put_contents($analyzed_methods_cache_location, serialize($analyzed_methods), LOCK_EX);
            }
        }
    }
    /**
     * @return array<string, FileMapType>|false
     */
    public function getFileMapCache()
    {
        $cache_directory = $this->config->getCacheDirectory();
        $file_maps_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_MAPS_CACHE_NAME;
        if ($cache_directory && file_exists($file_maps_cache_location)) {
            if ($this->config->use_igbinary) {
                /**
                 * @var array<string, FileMapType>
                 */
                $file_maps_cache = igbinary_unserialize(Providers::safeFileGetContents($file_maps_cache_location));
            } else {
                /**
                 * @var array<string, FileMapType>
                 */
                $file_maps_cache = unserialize(Providers::safeFileGetContents($file_maps_cache_location));
            }
            return $file_maps_cache;
        }
        return \false;
    }
    /**
     * @param array<string, FileMapType> $file_maps
     */
    public function setFileMapCache(array $file_maps) : void
    {
        $cache_directory = Config::getInstance()->getCacheDirectory();
        if ($cache_directory) {
            $file_maps_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::FILE_MAPS_CACHE_NAME;
            if ($this->config->use_igbinary) {
                file_put_contents($file_maps_cache_location, igbinary_serialize($file_maps), LOCK_EX);
            } else {
                file_put_contents($file_maps_cache_location, serialize($file_maps), LOCK_EX);
            }
        }
    }
    //phpcs:disable -- Remove this once the phpstan phpdoc parser MR is merged
    /**
     * @return array<string, array{int, int}>|false
     */
    public function getTypeCoverage()
    {
        //phpcs:enable -- Remove this once the phpstan phpdoc parser MR is merged
        $cache_directory = Config::getInstance()->getCacheDirectory();
        $type_coverage_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::TYPE_COVERAGE_CACHE_NAME;
        if ($cache_directory && file_exists($type_coverage_cache_location)) {
            if ($this->config->use_igbinary) {
                /** @var array<string, array{int, int}> */
                $type_coverage_cache = igbinary_unserialize(Providers::safeFileGetContents($type_coverage_cache_location));
            } else {
                /** @var array<string, array{int, int}> */
                $type_coverage_cache = unserialize(Providers::safeFileGetContents($type_coverage_cache_location));
            }
            return $type_coverage_cache;
        }
        return \false;
    }
    /**
     * @param array<string, array{int, int}> $mixed_counts
     */
    public function setTypeCoverage(array $mixed_counts) : void
    {
        $cache_directory = Config::getInstance()->getCacheDirectory();
        if ($cache_directory) {
            $type_coverage_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::TYPE_COVERAGE_CACHE_NAME;
            if ($this->config->use_igbinary) {
                file_put_contents($type_coverage_cache_location, igbinary_serialize($mixed_counts), LOCK_EX);
            } else {
                file_put_contents($type_coverage_cache_location, serialize($mixed_counts), LOCK_EX);
            }
        }
    }
    /**
     * @return string|false
     */
    public function getConfigHashCache()
    {
        $cache_directory = $this->config->getCacheDirectory();
        $config_hash_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CONFIG_HASH_CACHE_NAME;
        if ($cache_directory && file_exists($config_hash_cache_location)) {
            return Providers::safeFileGetContents($config_hash_cache_location);
        }
        return \false;
    }
    public function setConfigHashCache(string $hash = '') : void
    {
        $cache_directory = Config::getInstance()->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        if ($hash === '') {
            $hash = $this->config->computeHash();
        }
        if (!is_dir($cache_directory)) {
            try {
                if (mkdir($cache_directory, 0777, \true) === \false) {
                    // any other error than directory already exists/permissions issue
                    throw new RuntimeException('Failed to create ' . $cache_directory . ' cache directory for unknown reasons');
                }
            } catch (RuntimeException $e) {
                // Race condition (#4483)
                if (!is_dir($cache_directory)) {
                    // rethrow the error with default message
                    // it contains the reason why creation failed
                    throw $e;
                }
            }
        }
        $config_hash_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::CONFIG_HASH_CACHE_NAME;
        file_put_contents($config_hash_cache_location, $hash, LOCK_EX);
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Plugin\EventHandler\Event\MethodVisibilityProviderEvent;
use Psalm\Plugin\EventHandler\MethodVisibilityProviderInterface;
use Psalm\StatementsSource;
use function is_subclass_of;
use function strtolower;
/**
 * @internal
 */
class MethodVisibilityProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(MethodVisibilityProviderEvent): ?bool>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
    }
    /**
     * @param class-string<LegacyMethodVisibilityProviderInterface>
     *     |class-string<MethodVisibilityProviderInterface> $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, MethodVisibilityProviderInterface::class, \true)) {
            $callable = Closure::fromCallable([$class, 'isMethodVisible']);
            foreach ($class::getClassLikeNames() as $fq_classlike_name) {
                $this->registerClosure($fq_classlike_name, $callable);
            }
        }
    }
    /**
     * @param Closure(MethodVisibilityProviderEvent): ?bool $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    public function isMethodVisible(StatementsSource $source, string $fq_classlike_name, string $method_name, Context $context, ?CodeLocation $code_location = null) : ?bool
    {
        foreach (self::$handlers[strtolower($fq_classlike_name)] ?? [] as $method_handler) {
            $event = new MethodVisibilityProviderEvent($source, $fq_classlike_name, $method_name, $context, $code_location);
            $method_visible = $method_handler($event);
            if ($method_visible !== null) {
                return $method_visible;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Codebase\Analyzer;
use UnexpectedValueException;
use function array_filter;
use function array_keys;
use function array_merge;
use function array_unique;
use function explode;
use function file_exists;
/**
 * @psalm-import-type FileMapType from Analyzer
 *
 * Used to determine which files reference other files, necessary for using the --diff
 * option from the command line.
 * @internal
 */
class FileReferenceProvider
{
    private bool $loaded_from_cache = \false;
    /**
     * A lookup table used for getting all the references to a class not inside a method
     * indexed by file
     *
     * @var array<string, array<string,bool>>
     */
    private static array $nonmethod_references_to_classes = [];
    /**
     * A lookup table used for getting all the methods that reference a class
     *
     * @var array<string, array<string,bool>>
     */
    private static array $method_references_to_classes = [];
    /**
     * A lookup table used for getting all the files that reference a class member
     *
     * @var array<string, array<string,bool>>
     */
    private static array $file_references_to_class_members = [];
    /**
     * A lookup table used for getting all the files that reference a class property
     *
     * @var array<string, array<string,bool>>
     */
    private static array $file_references_to_class_properties = [];
    /**
     * A lookup table used for getting all the files that reference a method's return value
     *
     * @var array<string, array<string,bool>>
     */
    private static array $file_references_to_method_returns = [];
    /**
     * A lookup table used for getting all the files that reference a missing class member
     *
     * @var array<string, array<string,bool>>
     */
    private static array $file_references_to_missing_class_members = [];
    /**
     * @var array<string, array<string, true>>
     */
    private static array $files_inheriting_classes = [];
    /**
     * A list of all files deleted since the last successful run
     *
     * @var array<int, string>|null
     */
    private static ?array $deleted_files = null;
    /**
     * A lookup table used for getting all the files referenced by a file
     *
     * @var array<string, array{a:array<int, string>, i:array<int, string>}>
     */
    private static array $file_references = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private static array $method_references_to_class_members = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private static array $method_dependencies = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private static array $method_references_to_class_properties = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private static array $method_references_to_method_returns = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private static array $method_references_to_missing_class_members = [];
    /**
     * @var array<string, array<string, bool>>
     */
    private static array $references_to_mixed_member_names = [];
    /**
     * @var array<string, array<int, CodeLocation>>
     */
    private static array $class_method_locations = [];
    /**
     * @var array<string, array<int, CodeLocation>>
     */
    private static array $class_property_locations = [];
    /**
     * @var array<string, array<int, CodeLocation>>
     */
    private static array $class_locations = [];
    /**
     * @var array<string, string>
     */
    private static array $classlike_files = [];
    /**
     * @var array<string, array<string, int>>
     */
    private static array $analyzed_methods = [];
    /**
     * @var array<string, array<int, IssueData>>
     */
    private static array $issues = [];
    /**
     * @var array<string, FileMapType>
     */
    private static array $file_maps = [];
    /**
     * @var array<string, array{int, int}>
     */
    private static array $mixed_counts = [];
    /**
     * @var array<string, array<int, array<string, bool>>>
     */
    private static array $method_param_uses = [];
    public ?\Psalm\Internal\Provider\FileReferenceCacheProvider $cache = null;
    public function __construct(?\Psalm\Internal\Provider\FileReferenceCacheProvider $cache = null)
    {
        $this->cache = $cache;
    }
    /**
     * @return array<int, string>
     */
    public function getDeletedReferencedFiles() : array
    {
        if (self::$deleted_files === null) {
            self::$deleted_files = array_filter(array_keys(self::$file_references), static fn(string $file_name): bool => !file_exists($file_name));
        }
        return self::$deleted_files;
    }
    /**
     * @param lowercase-string $fq_class_name_lc
     */
    public function addNonMethodReferenceToClass(string $source_file, string $fq_class_name_lc) : void
    {
        self::$nonmethod_references_to_classes[$fq_class_name_lc][$source_file] = \true;
    }
    /**
     * @return array<string, array<string,bool>>
     */
    public function getAllNonMethodReferencesToClasses() : array
    {
        return self::$nonmethod_references_to_classes;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addNonMethodReferencesToClasses(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$nonmethod_references_to_classes[$key])) {
                self::$nonmethod_references_to_classes[$key] = array_merge($reference, self::$nonmethod_references_to_classes[$key]);
            } else {
                self::$nonmethod_references_to_classes[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, string> $map
     */
    public function addClassLikeFiles(array $map) : void
    {
        self::$classlike_files += $map;
    }
    public function addFileReferenceToClassMember(string $source_file, string $referenced_member_id, bool $inside_return) : void
    {
        self::$file_references_to_class_members[$referenced_member_id][$source_file] = \true;
        if ($inside_return) {
            self::$file_references_to_method_returns[$referenced_member_id][$source_file] = \true;
        }
    }
    public function addFileReferenceToClassProperty(string $source_file, string $referenced_property_id) : void
    {
        self::$file_references_to_class_properties[$referenced_property_id][$source_file] = \true;
    }
    public function addFileReferenceToMissingClassMember(string $source_file, string $referenced_member_id) : void
    {
        self::$file_references_to_missing_class_members[$referenced_member_id][$source_file] = \true;
    }
    /**
     * @return array<string, array<string,bool>>
     */
    public function getAllFileReferencesToClassMembers() : array
    {
        return self::$file_references_to_class_members;
    }
    /**
     * @return array<string, array<string,bool>>
     */
    public function getAllFileReferencesToClassProperties() : array
    {
        return self::$file_references_to_class_properties;
    }
    /**
     * @return array<string, array<string,bool>>
     */
    public function getAllFileReferencesToMethodReturns() : array
    {
        return self::$file_references_to_method_returns;
    }
    /**
     * @return array<string, array<string,bool>>
     */
    public function getAllFileReferencesToMissingClassMembers() : array
    {
        return self::$file_references_to_missing_class_members;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addFileReferencesToClassMembers(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$file_references_to_class_members[$key])) {
                self::$file_references_to_class_members[$key] = array_merge($reference, self::$file_references_to_class_members[$key]);
            } else {
                self::$file_references_to_class_members[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addFileReferencesToClassProperties(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$file_references_to_class_properties[$key])) {
                self::$file_references_to_class_properties[$key] = array_merge($reference, self::$file_references_to_class_properties[$key]);
            } else {
                self::$file_references_to_class_properties[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addFileReferencesToMethodReturns(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$file_references_to_method_returns[$key])) {
                self::$file_references_to_method_returns[$key] = array_merge($reference, self::$file_references_to_method_returns[$key]);
            } else {
                self::$file_references_to_method_returns[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addFileReferencesToMissingClassMembers(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$file_references_to_missing_class_members[$key])) {
                self::$file_references_to_missing_class_members[$key] = array_merge($reference, self::$file_references_to_missing_class_members[$key]);
            } else {
                self::$file_references_to_missing_class_members[$key] = $reference;
            }
        }
    }
    public function addFileInheritanceToClass(string $source_file, string $fq_class_name_lc) : void
    {
        self::$files_inheriting_classes[$fq_class_name_lc][$source_file] = \true;
    }
    public function addMethodParamUse(string $method_id, int $offset, string $referencing_method_id) : void
    {
        self::$method_param_uses[$method_id][$offset][$referencing_method_id] = \true;
    }
    /**
     * @return  array<int, string>
     */
    private function calculateFilesReferencingFile(Codebase $codebase, string $file) : array
    {
        $referenced_files = [];
        $file_classes = ClassLikeAnalyzer::getClassesForFile($codebase, $file);
        foreach ($file_classes as $file_class_lc => $_) {
            if (isset(self::$nonmethod_references_to_classes[$file_class_lc])) {
                $new_files = array_keys(self::$nonmethod_references_to_classes[$file_class_lc]);
                $referenced_files = [...$referenced_files, ...$new_files];
            }
            if (isset(self::$method_references_to_classes[$file_class_lc])) {
                $new_referencing_methods = array_keys(self::$method_references_to_classes[$file_class_lc]);
                foreach ($new_referencing_methods as $new_referencing_method_id) {
                    $fq_class_name_lc = explode('::', $new_referencing_method_id)[0];
                    try {
                        $referenced_files[] = $codebase->scanner->getClassLikeFilePath($fq_class_name_lc);
                    } catch (UnexpectedValueException $e) {
                        if (isset(self::$classlike_files[$fq_class_name_lc])) {
                            $referenced_files[] = self::$classlike_files[$fq_class_name_lc];
                        }
                    }
                }
            }
        }
        return array_unique($referenced_files);
    }
    /**
     * @return  array<int, string>
     */
    private function calculateFilesInheritingFile(Codebase $codebase, string $file) : array
    {
        $referenced_files = [];
        $file_classes = ClassLikeAnalyzer::getClassesForFile($codebase, $file);
        foreach ($file_classes as $file_class_lc => $_) {
            if (isset(self::$files_inheriting_classes[$file_class_lc])) {
                $referenced_files = [...$referenced_files, ...array_keys(self::$files_inheriting_classes[$file_class_lc])];
            }
        }
        return array_unique($referenced_files);
    }
    public function removeDeletedFilesFromReferences() : void
    {
        $deleted_files = $this->getDeletedReferencedFiles();
        if ($deleted_files) {
            foreach ($deleted_files as $file) {
                unset(self::$file_references[$file]);
            }
            if ($this->cache) {
                $this->cache->setCachedFileReferences(self::$file_references);
            }
        }
    }
    /**
     * @return array<int, string>
     */
    public function getFilesReferencingFile(string $file) : array
    {
        return self::$file_references[$file]['a'] ?? [];
    }
    /**
     * @return array<int, string>
     */
    public function getFilesInheritingFromFile(string $file) : array
    {
        return self::$file_references[$file]['i'] ?? [];
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getAllMethodReferencesToClassMembers() : array
    {
        return self::$method_references_to_class_members;
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getAllMethodDependencies() : array
    {
        return self::$method_dependencies;
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getAllMethodReferencesToClassProperties() : array
    {
        return self::$method_references_to_class_properties;
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getAllMethodReferencesToMethodReturns() : array
    {
        return self::$method_references_to_method_returns;
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getAllMethodReferencesToClasses() : array
    {
        return self::$method_references_to_classes;
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getAllMethodReferencesToMissingClassMembers() : array
    {
        return self::$method_references_to_missing_class_members;
    }
    /**
     * @return array<string, array<string,bool>>
     */
    public function getAllReferencesToMixedMemberNames() : array
    {
        return self::$references_to_mixed_member_names;
    }
    /**
     * @return array<string, array<int, array<string, bool>>>
     */
    public function getAllMethodParamUses() : array
    {
        return self::$method_param_uses;
    }
    /**
     * @psalm-suppress MixedPropertyTypeCoercion
     */
    public function loadReferenceCache(bool $force_reload = \true) : bool
    {
        if ($this->cache && (!$this->loaded_from_cache || $force_reload)) {
            $this->loaded_from_cache = \true;
            $file_references = $this->cache->getCachedFileReferences();
            if ($file_references === null) {
                return \false;
            }
            self::$file_references = $file_references;
            $nonmethod_references_to_classes = $this->cache->getCachedNonMethodClassReferences();
            if ($nonmethod_references_to_classes === null) {
                return \false;
            }
            self::$nonmethod_references_to_classes = $nonmethod_references_to_classes;
            $method_references_to_classes = $this->cache->getCachedMethodClassReferences();
            if ($method_references_to_classes === null) {
                return \false;
            }
            self::$method_references_to_classes = $method_references_to_classes;
            $method_references_to_class_members = $this->cache->getCachedMethodMemberReferences();
            if ($method_references_to_class_members === null) {
                return \false;
            }
            self::$method_references_to_class_members = $method_references_to_class_members;
            $method_dependencies = $this->cache->getCachedMethodDependencies();
            if ($method_dependencies === null) {
                return \false;
            }
            self::$method_dependencies = $method_dependencies;
            $method_references_to_class_properties = $this->cache->getCachedMethodPropertyReferences();
            if ($method_references_to_class_properties === null) {
                return \false;
            }
            self::$method_references_to_class_properties = $method_references_to_class_properties;
            $method_references_to_method_returns = $this->cache->getCachedMethodMethodReturnReferences();
            if ($method_references_to_method_returns === null) {
                return \false;
            }
            self::$method_references_to_method_returns = $method_references_to_method_returns;
            $method_references_to_missing_class_members = $this->cache->getCachedMethodMissingMemberReferences();
            if ($method_references_to_missing_class_members === null) {
                return \false;
            }
            self::$method_references_to_missing_class_members = $method_references_to_missing_class_members;
            $file_references_to_class_members = $this->cache->getCachedFileMemberReferences();
            if ($file_references_to_class_members === null) {
                return \false;
            }
            self::$file_references_to_class_members = $file_references_to_class_members;
            $file_references_to_class_properties = $this->cache->getCachedFilePropertyReferences();
            if ($file_references_to_class_properties === null) {
                return \false;
            }
            self::$file_references_to_class_properties = $file_references_to_class_properties;
            $file_references_to_method_returns = $this->cache->getCachedFileMethodReturnReferences();
            if ($file_references_to_method_returns === null) {
                return \false;
            }
            self::$file_references_to_method_returns = $file_references_to_method_returns;
            $file_references_to_missing_class_members = $this->cache->getCachedFileMissingMemberReferences();
            if ($file_references_to_missing_class_members === null) {
                return \false;
            }
            self::$file_references_to_missing_class_members = $file_references_to_missing_class_members;
            $references_to_mixed_member_names = $this->cache->getCachedMixedMemberNameReferences();
            if ($references_to_mixed_member_names === null) {
                return \false;
            }
            self::$references_to_mixed_member_names = $references_to_mixed_member_names;
            $analyzed_methods = $this->cache->getAnalyzedMethodCache();
            if ($analyzed_methods === \false) {
                return \false;
            }
            self::$analyzed_methods = $analyzed_methods;
            $issues = $this->cache->getCachedIssues();
            if ($issues === null) {
                return \false;
            }
            self::$issues = $issues;
            $method_param_uses = $this->cache->getCachedMethodParamUses();
            if ($method_param_uses === null) {
                return \false;
            }
            self::$method_param_uses = $method_param_uses;
            $mixed_counts = $this->cache->getTypeCoverage();
            if ($mixed_counts === \false) {
                return \false;
            }
            self::$mixed_counts = $mixed_counts;
            $classlike_files = $this->cache->getCachedClassLikeFiles();
            if ($classlike_files === null) {
                return \false;
            }
            self::$classlike_files = $classlike_files;
            self::$file_maps = $this->cache->getFileMapCache() ?: [];
            return \true;
        }
        return \false;
    }
    /**
     * @param  array<string, string|bool>  $visited_files
     */
    public function updateReferenceCache(Codebase $codebase, array $visited_files) : void
    {
        foreach ($visited_files as $file => $_) {
            $all_file_references = array_unique(array_merge(self::$file_references[$file]['a'] ?? [], $this->calculateFilesReferencingFile($codebase, $file)));
            $inheritance_references = array_unique(array_merge(self::$file_references[$file]['i'] ?? [], $this->calculateFilesInheritingFile($codebase, $file)));
            self::$file_references[$file] = ['a' => $all_file_references, 'i' => $inheritance_references];
        }
        if ($this->cache) {
            $this->cache->setCachedFileReferences(self::$file_references);
            $this->cache->setCachedMethodClassReferences(self::$method_references_to_classes);
            $this->cache->setCachedNonMethodClassReferences(self::$nonmethod_references_to_classes);
            $this->cache->setCachedMethodMemberReferences(self::$method_references_to_class_members);
            $this->cache->setCachedMethodDependencies(self::$method_dependencies);
            $this->cache->setCachedMethodPropertyReferences(self::$method_references_to_class_properties);
            $this->cache->setCachedMethodMethodReturnReferences(self::$method_references_to_method_returns);
            $this->cache->setCachedFileMemberReferences(self::$file_references_to_class_members);
            $this->cache->setCachedFilePropertyReferences(self::$file_references_to_class_properties);
            $this->cache->setCachedFileMethodReturnReferences(self::$file_references_to_method_returns);
            $this->cache->setCachedMethodMissingMemberReferences(self::$method_references_to_missing_class_members);
            $this->cache->setCachedFileMissingMemberReferences(self::$file_references_to_missing_class_members);
            $this->cache->setCachedMixedMemberNameReferences(self::$references_to_mixed_member_names);
            $this->cache->setCachedMethodParamUses(self::$method_param_uses);
            $this->cache->setCachedIssues(self::$issues);
            $this->cache->setCachedClassLikeFiles(self::$classlike_files);
            $this->cache->setFileMapCache(self::$file_maps);
            $this->cache->setTypeCoverage(self::$mixed_counts);
            $this->cache->setAnalyzedMethodCache(self::$analyzed_methods);
        }
    }
    /**
     * @param lowercase-string $fq_class_name_lc
     */
    public function addMethodReferenceToClass(string $calling_function_id, string $fq_class_name_lc) : void
    {
        if (!isset(self::$method_references_to_classes[$fq_class_name_lc])) {
            self::$method_references_to_classes[$fq_class_name_lc] = [$calling_function_id => \true];
        } else {
            self::$method_references_to_classes[$fq_class_name_lc][$calling_function_id] = \true;
        }
    }
    public function addMethodReferenceToClassMember(string $calling_function_id, string $referenced_member_id, bool $inside_return) : void
    {
        if (!isset(self::$method_references_to_class_members[$referenced_member_id])) {
            self::$method_references_to_class_members[$referenced_member_id] = [$calling_function_id => \true];
        } else {
            self::$method_references_to_class_members[$referenced_member_id][$calling_function_id] = \true;
        }
        if ($inside_return) {
            if (!isset(self::$method_references_to_method_returns[$referenced_member_id])) {
                self::$method_references_to_method_returns[$referenced_member_id] = [$calling_function_id => \true];
            } else {
                self::$method_references_to_method_returns[$referenced_member_id][$calling_function_id] = \true;
            }
        }
    }
    public function addMethodDependencyToClassMember(string $calling_function_id, string $referenced_member_id) : void
    {
        if (!isset(self::$method_dependencies[$referenced_member_id])) {
            self::$method_dependencies[$referenced_member_id] = [$calling_function_id => \true];
        } else {
            self::$method_dependencies[$referenced_member_id][$calling_function_id] = \true;
        }
    }
    public function addMethodReferenceToClassProperty(string $calling_function_id, string $referenced_property_id) : void
    {
        if (!isset(self::$method_references_to_class_properties[$referenced_property_id])) {
            self::$method_references_to_class_properties[$referenced_property_id] = [$calling_function_id => \true];
        } else {
            self::$method_references_to_class_properties[$referenced_property_id][$calling_function_id] = \true;
        }
    }
    public function addMethodReferenceToMissingClassMember(string $calling_function_id, string $referenced_member_id) : void
    {
        if (!isset(self::$method_references_to_missing_class_members[$referenced_member_id])) {
            self::$method_references_to_missing_class_members[$referenced_member_id] = [$calling_function_id => \true];
        } else {
            self::$method_references_to_missing_class_members[$referenced_member_id][$calling_function_id] = \true;
        }
    }
    public function addCallingLocationForClassMethod(CodeLocation $code_location, string $referenced_member_id) : void
    {
        if (!isset(self::$class_method_locations[$referenced_member_id])) {
            self::$class_method_locations[$referenced_member_id] = [$code_location];
        } else {
            self::$class_method_locations[$referenced_member_id][] = $code_location;
        }
    }
    public function addCallingLocationForClassProperty(CodeLocation $code_location, string $referenced_property_id) : void
    {
        if (!isset(self::$class_property_locations[$referenced_property_id])) {
            self::$class_property_locations[$referenced_property_id] = [$code_location];
        } else {
            self::$class_property_locations[$referenced_property_id][] = $code_location;
        }
    }
    public function addCallingLocationForClass(CodeLocation $code_location, string $referenced_class) : void
    {
        if (!isset(self::$class_locations[$referenced_class])) {
            self::$class_locations[$referenced_class] = [$code_location];
        } else {
            self::$class_locations[$referenced_class][] = $code_location;
        }
    }
    public function isClassMethodReferenced(string $method_id) : bool
    {
        return !empty(self::$file_references_to_class_members[$method_id]) || !empty(self::$method_references_to_class_members[$method_id]);
    }
    public function isClassPropertyReferenced(string $property_id) : bool
    {
        return !empty(self::$file_references_to_class_properties[$property_id]) || !empty(self::$method_references_to_class_properties[$property_id]);
    }
    public function isMethodReturnReferenced(string $method_id) : bool
    {
        return !empty(self::$file_references_to_method_returns[$method_id]) || !empty(self::$method_references_to_method_returns[$method_id]);
    }
    public function isClassReferenced(string $fq_class_name_lc) : bool
    {
        return isset(self::$method_references_to_classes[$fq_class_name_lc]) || isset(self::$nonmethod_references_to_classes[$fq_class_name_lc]);
    }
    public function isMethodParamUsed(string $method_id, int $offset) : bool
    {
        return !empty(self::$method_param_uses[$method_id][$offset]);
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setNonMethodReferencesToClasses(array $references) : void
    {
        self::$nonmethod_references_to_classes = $references;
    }
    /**
     * @return array<string, array<int, CodeLocation>>
     */
    public function getAllClassMethodLocations() : array
    {
        return self::$class_method_locations;
    }
    /**
     * @return array<string, array<int, CodeLocation>>
     */
    public function getAllClassPropertyLocations() : array
    {
        return self::$class_property_locations;
    }
    /**
     * @return array<string, array<int, CodeLocation>>
     */
    public function getAllClassLocations() : array
    {
        return self::$class_locations;
    }
    /**
     * @return array<int, CodeLocation>
     */
    public function getClassMethodLocations(string $method_id) : array
    {
        return self::$class_method_locations[$method_id] ?? [];
    }
    /**
     * @return array<int, CodeLocation>
     */
    public function getClassPropertyLocations(string $property_id) : array
    {
        return self::$class_property_locations[$property_id] ?? [];
    }
    /**
     * @return array<int, CodeLocation>
     */
    public function getClassLocations(string $fq_class_name_lc) : array
    {
        return self::$class_locations[$fq_class_name_lc] ?? [];
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addMethodReferencesToClassMembers(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$method_references_to_class_members[$key])) {
                self::$method_references_to_class_members[$key] = array_merge($reference, self::$method_references_to_class_members[$key]);
            } else {
                self::$method_references_to_class_members[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addMethodDependencies(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$method_dependencies[$key])) {
                self::$method_dependencies[$key] = array_merge($reference, self::$method_dependencies[$key]);
            } else {
                self::$method_dependencies[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addMethodReferencesToClassProperties(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$method_references_to_class_properties[$key])) {
                self::$method_references_to_class_properties[$key] = array_merge($reference, self::$method_references_to_class_properties[$key]);
            } else {
                self::$method_references_to_class_properties[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addMethodReferencesToMethodReturns(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$method_references_to_method_returns[$key])) {
                self::$method_references_to_method_returns[$key] = array_merge($reference, self::$method_references_to_method_returns[$key]);
            } else {
                self::$method_references_to_method_returns[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addMethodReferencesToClasses(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$method_references_to_classes[$key])) {
                self::$method_references_to_classes[$key] = array_merge($reference, self::$method_references_to_classes[$key]);
            } else {
                self::$method_references_to_classes[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function addMethodReferencesToMissingClassMembers(array $references) : void
    {
        foreach ($references as $key => $reference) {
            if (isset(self::$method_references_to_missing_class_members[$key])) {
                self::$method_references_to_missing_class_members[$key] = array_merge($reference, self::$method_references_to_missing_class_members[$key]);
            } else {
                self::$method_references_to_missing_class_members[$key] = $reference;
            }
        }
    }
    /**
     * @param array<string, array<int, array<string, bool>>> $references
     */
    public function addMethodParamUses(array $references) : void
    {
        foreach ($references as $method_id => $method_param_uses) {
            if (isset(self::$method_param_uses[$method_id])) {
                foreach ($method_param_uses as $offset => $reference_map) {
                    if (isset(self::$method_param_uses[$method_id][$offset])) {
                        self::$method_param_uses[$method_id][$offset] = array_merge(self::$method_param_uses[$method_id][$offset], $reference_map);
                    } else {
                        self::$method_param_uses[$method_id][$offset] = $reference_map;
                    }
                }
            } else {
                self::$method_param_uses[$method_id] = $method_param_uses;
            }
        }
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setCallingMethodReferencesToClasses(array $references) : void
    {
        self::$method_references_to_classes = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setCallingMethodReferencesToClassMembers(array $references) : void
    {
        self::$method_references_to_class_members = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setMethodDependencies(array $references) : void
    {
        self::$method_dependencies = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setCallingMethodReferencesToClassProperties(array $references) : void
    {
        self::$method_references_to_class_properties = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setCallingMethodReferencesToMethodReturns(array $references) : void
    {
        self::$method_references_to_method_returns = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setCallingMethodReferencesToMissingClassMembers(array $references) : void
    {
        self::$method_references_to_missing_class_members = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setFileReferencesToClassMembers(array $references) : void
    {
        self::$file_references_to_class_members = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setFileReferencesToClassProperties(array $references) : void
    {
        self::$file_references_to_class_properties = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setFileReferencesToMethodReturns(array $references) : void
    {
        self::$file_references_to_method_returns = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setFileReferencesToMissingClassMembers(array $references) : void
    {
        self::$file_references_to_missing_class_members = $references;
    }
    /**
     * @param array<string, array<string,bool>> $references
     */
    public function setReferencesToMixedMemberNames(array $references) : void
    {
        self::$references_to_mixed_member_names = $references;
    }
    /**
     * @param array<string, array<int, array<string, bool>>> $references
     */
    public function setMethodParamUses(array $references) : void
    {
        self::$method_param_uses = $references;
    }
    /**
     * @param array<string, array<int, CodeLocation>> $references
     */
    public function addClassMethodLocations(array $references) : void
    {
        foreach ($references as $referenced_member_id => $locations) {
            if (isset(self::$class_method_locations[$referenced_member_id])) {
                self::$class_method_locations[$referenced_member_id] = [...self::$class_method_locations[$referenced_member_id], ...$locations];
            } else {
                self::$class_method_locations[$referenced_member_id] = $locations;
            }
        }
    }
    /**
     * @param array<string, array<int, CodeLocation>> $references
     */
    public function addClassPropertyLocations(array $references) : void
    {
        foreach ($references as $referenced_member_id => $locations) {
            if (isset(self::$class_property_locations[$referenced_member_id])) {
                self::$class_property_locations[$referenced_member_id] = [...self::$class_property_locations[$referenced_member_id], ...$locations];
            } else {
                self::$class_property_locations[$referenced_member_id] = $locations;
            }
        }
    }
    /**
     * @param array<string, array<int, CodeLocation>> $references
     */
    public function addClassLocations(array $references) : void
    {
        foreach ($references as $referenced_member_id => $locations) {
            if (isset(self::$class_locations[$referenced_member_id])) {
                self::$class_locations[$referenced_member_id] = [...self::$class_locations[$referenced_member_id], ...$locations];
            } else {
                self::$class_locations[$referenced_member_id] = $locations;
            }
        }
    }
    /**
     * @return array<string, array<int, IssueData>>
     */
    public function getExistingIssues() : array
    {
        return self::$issues;
    }
    public function clearExistingIssuesForFile(string $file_path) : void
    {
        unset(self::$issues[$file_path]);
    }
    public function clearExistingFileMapsForFile(string $file_path) : void
    {
        unset(self::$file_maps[$file_path]);
    }
    public function addIssue(string $file_path, IssueData $issue) : void
    {
        // don’t save parse errors ever, as they're not responsive to AST diffing
        if ($issue->type === 'ParseError') {
            return;
        }
        if (!isset(self::$issues[$file_path])) {
            self::$issues[$file_path] = [$issue];
        } else {
            self::$issues[$file_path][] = $issue;
        }
    }
    /**
     * @param array<string, array<string, int>> $analyzed_methods
     */
    public function setAnalyzedMethods(array $analyzed_methods) : void
    {
        self::$analyzed_methods = $analyzed_methods;
    }
    /**
     * @param array<string, FileMapType> $file_maps
     */
    public function setFileMaps(array $file_maps) : void
    {
        self::$file_maps = $file_maps;
    }
    /**
     * @return array<string, array{int, int}>
     */
    public function getTypeCoverage() : array
    {
        return self::$mixed_counts;
    }
    /**
     * @param array<string, array{int, int}> $mixed_counts
     */
    public function setTypeCoverage(array $mixed_counts) : void
    {
        self::$mixed_counts = array_merge(self::$mixed_counts, $mixed_counts);
    }
    /**
     * @return array<string, array<string, int>>
     */
    public function getAnalyzedMethods() : array
    {
        return self::$analyzed_methods;
    }
    /**
     * @return array<string, FileMapType>
     */
    public function getFileMaps() : array
    {
        return self::$file_maps;
    }
    public static function clearCache() : void
    {
        self::$files_inheriting_classes = [];
        self::$deleted_files = null;
        self::$file_references = [];
        self::$file_references_to_class_members = [];
        self::$file_references_to_class_properties = [];
        self::$file_references_to_method_returns = [];
        self::$method_references_to_class_members = [];
        self::$method_dependencies = [];
        self::$method_references_to_class_properties = [];
        self::$method_references_to_method_returns = [];
        self::$method_references_to_classes = [];
        self::$nonmethod_references_to_classes = [];
        self::$file_references_to_missing_class_members = [];
        self::$method_references_to_missing_class_members = [];
        self::$references_to_mixed_member_names = [];
        self::$class_method_locations = [];
        self::$class_property_locations = [];
        self::$class_locations = [];
        self::$analyzed_methods = [];
        self::$issues = [];
        self::$file_maps = [];
        self::$method_param_uses = [];
        self::$classlike_files = [];
        self::$mixed_counts = [];
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Provider\PropertyTypeProvider;

use Psalm\Plugin\EventHandler\Event\PropertyTypeProviderEvent;
use Psalm\Plugin\EventHandler\PropertyTypeProviderInterface;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use function strtolower;
/**
 * @internal
 */
class DomDocumentPropertyTypeProvider implements PropertyTypeProviderInterface
{
    private static ?Union $cache = null;
    public static function getPropertyType(PropertyTypeProviderEvent $event) : ?Union
    {
        if (strtolower($event->getPropertyName()) === 'documentelement') {
            self::$cache ??= new Union([new TNamedObject('DOMElement'), new TNull()], ['ignore_nullable_issues' => \true]);
            return self::$cache;
        }
        return null;
    }
    public static function getClassLikeNames() : array
    {
        return ['domdocument'];
    }
}
<?php

namespace Psalm\Internal\Provider;

use JsonException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use Psalm\Config;
use RuntimeException;
use UnexpectedValueException;
use function clearstatcache;
use function error_log;
use function file_put_contents;
use function filemtime;
use function gettype;
use function hash;
use function igbinary_serialize;
use function igbinary_unserialize;
use function is_array;
use function is_dir;
use function is_readable;
use function is_writable;
use function json_decode;
use function json_encode;
use function mkdir;
use function scandir;
use function serialize;
use function touch;
use function unlink;
use function unserialize;
use const DIRECTORY_SEPARATOR;
use const JSON_THROW_ON_ERROR;
use const LOCK_EX;
use const PHP_VERSION_ID;
use const SCANDIR_SORT_NONE;
/**
 * @internal
 */
class ParserCacheProvider
{
    private const FILE_HASHES = 'file_hashes_json';
    private const PARSER_CACHE_DIRECTORY = 'php-parser';
    private const FILE_CONTENTS_CACHE_DIRECTORY = 'file-caches';
    private Config $config;
    /**
     * A map of filename hashes to contents hashes
     *
     * @var array<string, string>|null
     */
    protected ?array $existing_file_content_hashes = null;
    /**
     * A map of recently-added filename hashes to contents hashes
     *
     * @var array<string, string>
     */
    protected array $new_file_content_hashes = [];
    private bool $use_file_cache;
    public function __construct(Config $config, bool $use_file_cache = \true)
    {
        $this->config = $config;
        $this->use_file_cache = $use_file_cache;
    }
    /**
     * @return list<PhpParser\Node\Stmt>|null
     */
    public function loadStatementsFromCache(string $file_path, int $file_modified_time, string $file_content_hash) : ?array
    {
        if (!$this->use_file_cache) {
            return null;
        }
        $cache_location = $this->getCacheLocationForPath($file_path, self::PARSER_CACHE_DIRECTORY);
        $file_cache_key = $this->getParserCacheKey($file_path);
        $file_content_hashes = $this->new_file_content_hashes + $this->getExistingFileContentHashes();
        if (isset($file_content_hashes[$file_cache_key]) && $file_content_hash === $file_content_hashes[$file_cache_key] && is_readable($cache_location) && filemtime($cache_location) > $file_modified_time) {
            if ($this->config->use_igbinary) {
                /** @var list<Stmt> */
                $stmts = igbinary_unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location));
            } else {
                /** @var list<Stmt> */
                $stmts = unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location));
            }
            return $stmts;
        }
        return null;
    }
    /**
     * @return list<PhpParser\Node\Stmt>|null
     */
    public function loadExistingStatementsFromCache(string $file_path) : ?array
    {
        if (!$this->use_file_cache) {
            return null;
        }
        $cache_location = $this->getCacheLocationForPath($file_path, self::PARSER_CACHE_DIRECTORY);
        if (is_readable($cache_location)) {
            if ($this->config->use_igbinary) {
                /** @var list<Stmt> */
                return igbinary_unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location)) ?: null;
            }
            /** @var list<Stmt> */
            return unserialize(\Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location)) ?: null;
        }
        return null;
    }
    public function loadExistingFileContentsFromCache(string $file_path) : ?string
    {
        if (!$this->use_file_cache) {
            return null;
        }
        $cache_location = $this->getCacheLocationForPath($file_path, self::FILE_CONTENTS_CACHE_DIRECTORY);
        if (is_readable($cache_location)) {
            return \Psalm\Internal\Provider\Providers::safeFileGetContents($cache_location);
        }
        return null;
    }
    /**
     * @return array<string, string>
     */
    private function getExistingFileContentHashes() : array
    {
        if (!$this->use_file_cache) {
            return [];
        }
        if ($this->existing_file_content_hashes === null) {
            $root_cache_directory = $this->config->getCacheDirectory();
            $file_hashes_path = $root_cache_directory . DIRECTORY_SEPARATOR . self::FILE_HASHES;
            if (!$root_cache_directory) {
                throw new UnexpectedValueException('No cache directory defined');
            }
            if (is_readable($file_hashes_path)) {
                $hashes_encoded = \Psalm\Internal\Provider\Providers::safeFileGetContents($file_hashes_path);
                if (!$hashes_encoded) {
                    error_log('Unexpected value when loading from file content hashes');
                    $this->existing_file_content_hashes = [];
                    return [];
                }
                try {
                    $hashes_decoded = json_decode($hashes_encoded, \true, 512, JSON_THROW_ON_ERROR);
                } catch (JsonException $e) {
                    error_log('Failed to parse hashes: ' . $e->getMessage());
                    $this->existing_file_content_hashes = [];
                    return [];
                }
                if (!is_array($hashes_decoded)) {
                    error_log('Unexpected value ' . gettype($hashes_decoded));
                    $this->existing_file_content_hashes = [];
                    return [];
                }
                /** @var array<string, string> $hashes_decoded */
                $this->existing_file_content_hashes = $hashes_decoded;
            } else {
                $this->existing_file_content_hashes = [];
            }
            if (!is_readable($file_hashes_path)) {
                // might not exist yet
                $this->existing_file_content_hashes = [];
                return $this->existing_file_content_hashes;
            }
            $hashes_encoded = \Psalm\Internal\Provider\Providers::safeFileGetContents($file_hashes_path);
            if (!$hashes_encoded) {
                throw new UnexpectedValueException('File content hashes should be in cache');
            }
            /** @psalm-suppress MixedAssignment */
            $hashes_decoded = json_decode($hashes_encoded, \true);
            if (!is_array($hashes_decoded)) {
                throw new UnexpectedValueException('File content hashes are of invalid type ' . gettype($hashes_decoded));
            }
            /** @var array<string, string> $hashes_decoded */
            $this->existing_file_content_hashes = $hashes_decoded;
        }
        return $this->existing_file_content_hashes;
    }
    /**
     * @param  list<PhpParser\Node\Stmt>        $stmts
     */
    public function saveStatementsToCache(string $file_path, string $file_content_hash, array $stmts, bool $touch_only) : void
    {
        $cache_location = $this->getCacheLocationForPath($file_path, self::PARSER_CACHE_DIRECTORY, !$touch_only);
        if ($touch_only) {
            touch($cache_location);
        } else {
            if ($this->config->use_igbinary) {
                file_put_contents($cache_location, igbinary_serialize($stmts), LOCK_EX);
            } else {
                file_put_contents($cache_location, serialize($stmts), LOCK_EX);
            }
            $file_cache_key = $this->getParserCacheKey($file_path);
            $this->new_file_content_hashes[$file_cache_key] = $file_content_hash;
        }
    }
    /**
     * @return array<string, string>
     */
    public function getNewFileContentHashes() : array
    {
        return $this->new_file_content_hashes;
    }
    /**
     * @param array<string, string> $file_content_hashes
     */
    public function addNewFileContentHashes(array $file_content_hashes) : void
    {
        $this->new_file_content_hashes = $file_content_hashes + $this->new_file_content_hashes;
    }
    public function saveFileContentHashes() : void
    {
        if (!$this->use_file_cache) {
            return;
        }
        $root_cache_directory = $this->config->getCacheDirectory();
        if (!$root_cache_directory) {
            return;
        }
        // directory was removed most likely due to a race condition
        // with other psalm instances that were manually started at
        // the same time
        clearstatcache(\true, $root_cache_directory);
        if (!is_dir($root_cache_directory)) {
            return;
        }
        $file_content_hashes = $this->new_file_content_hashes + $this->getExistingFileContentHashes();
        $file_hashes_path = $root_cache_directory . DIRECTORY_SEPARATOR . self::FILE_HASHES;
        file_put_contents($file_hashes_path, json_encode($file_content_hashes, JSON_THROW_ON_ERROR), LOCK_EX);
    }
    public function cacheFileContents(string $file_path, string $file_contents) : void
    {
        if (!$this->use_file_cache) {
            return;
        }
        $cache_location = $this->getCacheLocationForPath($file_path, self::FILE_CONTENTS_CACHE_DIRECTORY, \true);
        file_put_contents($cache_location, $file_contents, LOCK_EX);
    }
    public function deleteOldParserCaches(float $time_before) : int
    {
        $cache_directory = $this->config->getCacheDirectory();
        $this->existing_file_content_hashes = null;
        $this->new_file_content_hashes = [];
        if (!$cache_directory) {
            return 0;
        }
        $removed_count = 0;
        $cache_directory .= DIRECTORY_SEPARATOR . self::PARSER_CACHE_DIRECTORY;
        if (is_dir($cache_directory)) {
            $directory_files = scandir($cache_directory, SCANDIR_SORT_NONE);
            foreach ($directory_files as $directory_file) {
                $full_path = $cache_directory . DIRECTORY_SEPARATOR . $directory_file;
                if ($directory_file[0] === '.') {
                    continue;
                }
                if (filemtime($full_path) < $time_before && is_writable($full_path)) {
                    unlink($full_path);
                    ++$removed_count;
                }
            }
        }
        return $removed_count;
    }
    private function getParserCacheKey(string $file_path) : string
    {
        if (PHP_VERSION_ID >= 80100) {
            $hash = hash('xxh128', $file_path);
        } else {
            $hash = hash('md4', $file_path);
        }
        return $hash . ($this->config->use_igbinary ? '-igbinary' : '') . '-r';
    }
    private function getCacheLocationForPath(string $file_path, string $subdirectory, bool $create_directory = \false) : string
    {
        $root_cache_directory = $this->config->getCacheDirectory();
        if (!$root_cache_directory) {
            throw new UnexpectedValueException('No cache directory defined');
        }
        $parser_cache_directory = $root_cache_directory . DIRECTORY_SEPARATOR . $subdirectory;
        if ($create_directory && !is_dir($parser_cache_directory)) {
            try {
                if (mkdir($parser_cache_directory, 0777, \true) === \false) {
                    // any other error than directory already exists/permissions issue
                    throw new RuntimeException('Failed to create ' . $parser_cache_directory . ' cache directory for unknown reasons');
                }
            } catch (RuntimeException $e) {
                // Race condition (#4483)
                if (!is_dir($parser_cache_directory)) {
                    // rethrow the error with default message
                    // it contains the reason why creation failed
                    throw $e;
                }
            }
        }
        return $parser_cache_directory . DIRECTORY_SEPARATOR . $this->getParserCacheKey($file_path);
    }
}
<?php

namespace Psalm\Internal\Provider;

use Psalm\Config;
use function file_exists;
use function file_put_contents;
use function filemtime;
use function hash;
use function mkdir;
use function touch;
use const DIRECTORY_SEPARATOR;
use const PHP_VERSION_ID;
/**
 * Used to determine which files reference other files, necessary for using the --diff
 * option from the command line.
 *
 * @internal
 */
class ProjectCacheProvider
{
    private const GOOD_RUN_NAME = 'good_run';
    private const COMPOSER_LOCK_HASH = 'composer_lock_hash';
    private ?int $last_run = null;
    private ?string $composer_lock_hash = null;
    private string $composer_lock_location;
    public function __construct(string $composer_lock_location)
    {
        $this->composer_lock_location = $composer_lock_location;
    }
    public function canDiffFiles() : bool
    {
        $cache_directory = Config::getInstance()->getCacheDirectory();
        return $cache_directory && file_exists($cache_directory . DIRECTORY_SEPARATOR . self::GOOD_RUN_NAME);
    }
    public function processSuccessfulRun(float $start_time, string $psalm_version) : void
    {
        $cache_directory = Config::getInstance()->getCacheDirectory();
        if (!$cache_directory) {
            return;
        }
        $run_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::GOOD_RUN_NAME;
        file_put_contents($run_cache_location, $psalm_version);
        touch($run_cache_location, (int) $start_time);
    }
    public function getLastRun(string $psalm_version) : int
    {
        if ($this->last_run === null) {
            $cache_directory = Config::getInstance()->getCacheDirectory();
            $run_cache_location = $cache_directory . DIRECTORY_SEPARATOR . self::GOOD_RUN_NAME;
            if (file_exists($run_cache_location) && \Psalm\Internal\Provider\Providers::safeFileGetContents($run_cache_location) === $psalm_version) {
                $this->last_run = filemtime($run_cache_location);
            } else {
                $this->last_run = 0;
            }
        }
        return $this->last_run;
    }
    public function hasLockfileChanged() : bool
    {
        if (!file_exists($this->composer_lock_location)) {
            return \true;
        }
        $lockfile_contents = \Psalm\Internal\Provider\Providers::safeFileGetContents($this->composer_lock_location);
        if (!$lockfile_contents) {
            return \true;
        }
        if (PHP_VERSION_ID >= 80100) {
            $hash = hash('xxh128', $lockfile_contents);
        } else {
            $hash = hash('md4', $lockfile_contents);
        }
        $changed = $hash !== $this->getComposerLockHash();
        $this->composer_lock_hash = $hash;
        return $changed;
    }
    public function updateComposerLockHash() : void
    {
        $cache_directory = Config::getInstance()->getCacheDirectory();
        if (!$cache_directory || !$this->composer_lock_hash) {
            return;
        }
        if (!file_exists($cache_directory)) {
            mkdir($cache_directory, 0777, \true);
        }
        $lock_hash_location = $cache_directory . DIRECTORY_SEPARATOR . self::COMPOSER_LOCK_HASH;
        file_put_contents($lock_hash_location, $this->composer_lock_hash);
    }
    protected function getComposerLockHash() : string
    {
        if ($this->composer_lock_hash === null) {
            $cache_directory = Config::getInstance()->getCacheDirectory();
            $lock_hash_location = $cache_directory . DIRECTORY_SEPARATOR . self::COMPOSER_LOCK_HASH;
            if (file_exists($lock_hash_location)) {
                $this->composer_lock_hash = \Psalm\Internal\Provider\Providers::safeFileGetContents($lock_hash_location) ?: '';
            } else {
                $this->composer_lock_hash = '';
            }
        }
        return $this->composer_lock_hash;
    }
}
<?php

namespace Psalm\Internal\Provider;

use Closure;
use Psalm\CodeLocation;
use Psalm\Plugin\EventHandler\Event\MethodExistenceProviderEvent;
use Psalm\Plugin\EventHandler\MethodExistenceProviderInterface;
use Psalm\StatementsSource;
use function strtolower;
/**
 * @internal
 */
class MethodExistenceProvider
{
    /**
     * @var array<
     *   lowercase-string,
     *   array<Closure(MethodExistenceProviderEvent): ?bool>
     * >
     */
    private static array $handlers = [];
    public function __construct()
    {
        self::$handlers = [];
    }
    /**
     * @param class-string<MethodExistenceProviderInterface> $class
     */
    public function registerClass(string $class) : void
    {
        $callable = Closure::fromCallable([$class, 'doesMethodExist']);
        foreach ($class::getClassLikeNames() as $fq_classlike_name) {
            $this->registerClosure($fq_classlike_name, $callable);
        }
    }
    /**
     * @param Closure(MethodExistenceProviderEvent): ?bool $c
     */
    public function registerClosure(string $fq_classlike_name, Closure $c) : void
    {
        self::$handlers[strtolower($fq_classlike_name)][] = $c;
    }
    public function has(string $fq_classlike_name) : bool
    {
        return isset(self::$handlers[strtolower($fq_classlike_name)]);
    }
    public function doesMethodExist(string $fq_classlike_name, string $method_name_lowercase, ?StatementsSource $source = null, ?CodeLocation $code_location = null) : ?bool
    {
        foreach (self::$handlers[strtolower($fq_classlike_name)] ?? [] as $method_handler) {
            $event = new MethodExistenceProviderEvent($fq_classlike_name, $method_name_lowercase, $source, $code_location);
            $method_exists = $method_handler($event);
            if ($method_exists !== null) {
                return $method_exists;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Provider;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\FuncCall;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\MethodCall;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\New_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\StaticCall;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Return_;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeAbstract;
use Psalm\NodeTypeProvider;
use Psalm\Storage\Assertion;
use Psalm\Storage\Possibilities;
use Psalm\Type\Union;
use SplObjectStorage;
/**
 * @internal
 */
class NodeDataProvider implements NodeTypeProvider
{
    /** @var SplObjectStorage<Node, Union> */
    private SplObjectStorage $node_types;
    /**
     * @var SplObjectStorage<Node,list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>|null>
     */
    private SplObjectStorage $node_assertions;
    /** @var SplObjectStorage<Node, array<int, Possibilities>> */
    private SplObjectStorage $node_if_true_assertions;
    /** @var SplObjectStorage<Node, array<int, Possibilities>> */
    private SplObjectStorage $node_if_false_assertions;
    public bool $cache_assertions = \true;
    public function __construct()
    {
        $this->node_types = new SplObjectStorage();
        $this->node_assertions = new SplObjectStorage();
        $this->node_if_true_assertions = new SplObjectStorage();
        $this->node_if_false_assertions = new SplObjectStorage();
    }
    /**
     * @param Expr|Name|Return_ $node
     */
    public function setType(NodeAbstract $node, Union $type) : void
    {
        $this->node_types[$node] = $type;
    }
    /**
     * @param Expr|Name|Return_ $node
     */
    public function getType(NodeAbstract $node) : ?Union
    {
        return $this->node_types[$node] ?? null;
    }
    /**
     * @param list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>|null $assertions
     */
    public function setAssertions(Expr $node, ?array $assertions) : void
    {
        if (!$this->cache_assertions) {
            return;
        }
        $this->node_assertions[$node] = $assertions;
    }
    /**
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>|null
     */
    public function getAssertions(Expr $node) : ?array
    {
        if (!$this->cache_assertions) {
            return null;
        }
        return $this->node_assertions[$node] ?? null;
    }
    /**
     * @param FuncCall|MethodCall|StaticCall|New_ $node
     * @param array<int, Possibilities>  $assertions
     */
    public function setIfTrueAssertions(Expr $node, array $assertions) : void
    {
        $this->node_if_true_assertions[$node] = $assertions;
    }
    /**
     * @param Expr\FuncCall|MethodCall|StaticCall|New_ $node
     * @return array<int, Possibilities>|null
     */
    public function getIfTrueAssertions(Expr $node) : ?array
    {
        return $this->node_if_true_assertions[$node] ?? null;
    }
    /**
     * @param FuncCall|MethodCall|StaticCall|New_ $node
     * @param array<int, Possibilities>  $assertions
     */
    public function setIfFalseAssertions(Expr $node, array $assertions) : void
    {
        $this->node_if_false_assertions[$node] = $assertions;
    }
    /**
     * @param FuncCall|MethodCall|StaticCall|New_ $node
     * @return array<int, Possibilities>|null
     */
    public function getIfFalseAssertions(Expr $node) : ?array
    {
        return $this->node_if_false_assertions[$node] ?? null;
    }
    public function isPureCompatible(Expr $node) : bool
    {
        $node_type = $this->getType($node);
        return $node_type && $node_type->reference_free || $node->getAttribute('pure', \false);
    }
    public function clearNodeOfTypeAndAssertions(Expr $node) : void
    {
        unset($this->node_types[$node], $this->node_assertions[$node]);
    }
}
<?php

namespace Psalm\Internal;

use Psalm\Plugin\EventHandler\AddTaintsInterface;
use Psalm\Plugin\EventHandler\AfterAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterClassLikeAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterClassLikeExistenceCheckInterface;
use Psalm\Plugin\EventHandler\AfterClassLikeVisitInterface;
use Psalm\Plugin\EventHandler\AfterCodebasePopulatedInterface;
use Psalm\Plugin\EventHandler\AfterEveryFunctionCallAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterExpressionAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterFileAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterFunctionCallAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterFunctionLikeAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterMethodCallAnalysisInterface;
use Psalm\Plugin\EventHandler\AfterStatementAnalysisInterface;
use Psalm\Plugin\EventHandler\BeforeAddIssueInterface;
use Psalm\Plugin\EventHandler\BeforeFileAnalysisInterface;
use Psalm\Plugin\EventHandler\BeforeStatementAnalysisInterface;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Plugin\EventHandler\Event\AfterAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterClassLikeAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterClassLikeExistenceCheckEvent;
use Psalm\Plugin\EventHandler\Event\AfterClassLikeVisitEvent;
use Psalm\Plugin\EventHandler\Event\AfterCodebasePopulatedEvent;
use Psalm\Plugin\EventHandler\Event\AfterEveryFunctionCallAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterExpressionAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterFileAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterFunctionCallAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterFunctionLikeAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterMethodCallAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\AfterStatementAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\BeforeAddIssueEvent;
use Psalm\Plugin\EventHandler\Event\BeforeFileAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\BeforeStatementAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\StringInterpreterEvent;
use Psalm\Plugin\EventHandler\RemoveTaintsInterface;
use Psalm\Plugin\EventHandler\StringInterpreterInterface;
use Psalm\Type\Atomic\TLiteralString;
use function count;
use function is_bool;
use function is_subclass_of;
/**
 * @internal
 */
class EventDispatcher
{
    /**
     * Static methods to be called after method checks have completed
     *
     * @var list<class-string<AfterMethodCallAnalysisInterface>>
     */
    private array $after_method_checks = [];
    /**
     * Static methods to be called after project function checks have completed
     *
     * Called after function calls to functions defined in the project.
     *
     * Allows influencing the return type and adding of modifications.
     *
     * @var list<class-string<AfterFunctionCallAnalysisInterface>>
     */
    public array $after_function_checks = [];
    /**
     * Static methods to be called after every function call
     *
     * Called after each function call, including php internal functions.
     *
     * Cannot change the call or influence its return type
     *
     * @var list<class-string<AfterEveryFunctionCallAnalysisInterface>>
     */
    public array $after_every_function_checks = [];
    /**
     * Static methods to be called after expression checks have completed
     *
     * @var list<class-string<AfterExpressionAnalysisInterface>>
     */
    public array $after_expression_checks = [];
    /**
     * Static methods to be called before statement checks are processed
     *
     * @var list<class-string<BeforeStatementAnalysisInterface>>
     */
    public array $before_statement_checks = [];
    /**
     * Static methods to be called after statement checks have completed
     *
     * @var list<class-string<AfterStatementAnalysisInterface>>
     */
    public array $after_statement_checks = [];
    /**
     * Static methods to be called after method checks have completed
     *
     * @var list<class-string<StringInterpreterInterface>>
     */
    public array $string_interpreters = [];
    /**
     * Static methods to be called after classlike exists checks have completed
     *
     * @var list<class-string<AfterClassLikeExistenceCheckInterface>>
     */
    public array $after_classlike_exists_checks = [];
    /**
     * Static methods to be called after classlike checks have completed
     *
     * @var list<class-string<AfterClassLikeAnalysisInterface>>
     */
    public array $after_classlike_checks = [];
    /**
     * Static methods to be called after classlikes have been scanned
     *
     * @var list<class-string<AfterClassLikeVisitInterface>>
     */
    private array $after_visit_classlikes = [];
    /**
     * Static methods to be called after codebase has been populated
     *
     * @var list<class-string<AfterCodebasePopulatedInterface>>
     */
    public array $after_codebase_populated = [];
    /**
     * @var list<class-string<BeforeAddIssueInterface>>
     */
    private array $before_add_issue = [];
    /**
     * Static methods to be called after codebase has been populated
     *
     * @var list<class-string<AfterAnalysisInterface>>
     */
    public array $after_analysis = [];
    /**
     * Static methods to be called after a file has been analyzed
     *
     * @var list<class-string<AfterFileAnalysisInterface>>
     */
    public array $after_file_checks = [];
    /**
     * Static methods to be called before a file is analyzed
     *
     * @var list<class-string<BeforeFileAnalysisInterface>>
     */
    public array $before_file_checks = [];
    /**
     * Static methods to be called after functionlike checks have completed
     *
     * @var list<class-string<AfterFunctionLikeAnalysisInterface>>
     */
    public array $after_functionlike_checks = [];
    /**
     * Static methods to be called to see if taints should be added
     *
     * @var list<class-string<AddTaintsInterface>>
     */
    public array $add_taints_checks = [];
    /**
     * Static methods to be called to see if taints should be removed
     *
     * @var list<class-string<RemoveTaintsInterface>>
     */
    public array $remove_taints_checks = [];
    /**
     * @param class-string $class
     */
    public function registerClass(string $class) : void
    {
        if (is_subclass_of($class, AfterMethodCallAnalysisInterface::class)) {
            $this->after_method_checks[] = $class;
        }
        if (is_subclass_of($class, AfterFunctionCallAnalysisInterface::class)) {
            $this->after_function_checks[] = $class;
        }
        if (is_subclass_of($class, AfterEveryFunctionCallAnalysisInterface::class)) {
            $this->after_every_function_checks[] = $class;
        }
        if (is_subclass_of($class, AfterExpressionAnalysisInterface::class)) {
            $this->after_expression_checks[] = $class;
        }
        if (is_subclass_of($class, BeforeStatementAnalysisInterface::class)) {
            $this->before_statement_checks[] = $class;
        }
        if (is_subclass_of($class, AfterStatementAnalysisInterface::class)) {
            $this->after_statement_checks[] = $class;
        }
        if (is_subclass_of($class, StringInterpreterInterface::class)) {
            $this->string_interpreters[] = $class;
        }
        if (is_subclass_of($class, AfterClassLikeExistenceCheckInterface::class)) {
            $this->after_classlike_exists_checks[] = $class;
        }
        if (is_subclass_of($class, AfterClassLikeAnalysisInterface::class)) {
            $this->after_classlike_checks[] = $class;
        }
        if (is_subclass_of($class, AfterClassLikeVisitInterface::class)) {
            $this->after_visit_classlikes[] = $class;
        }
        if (is_subclass_of($class, AfterCodebasePopulatedInterface::class)) {
            $this->after_codebase_populated[] = $class;
        }
        if (is_subclass_of($class, BeforeAddIssueInterface::class)) {
            $this->before_add_issue[] = $class;
        }
        if (is_subclass_of($class, AfterAnalysisInterface::class)) {
            $this->after_analysis[] = $class;
        }
        if (is_subclass_of($class, AfterFileAnalysisInterface::class)) {
            $this->after_file_checks[] = $class;
        }
        if (is_subclass_of($class, BeforeFileAnalysisInterface::class)) {
            $this->before_file_checks[] = $class;
        }
        if (is_subclass_of($class, AfterFunctionLikeAnalysisInterface::class)) {
            $this->after_functionlike_checks[] = $class;
        }
        if (is_subclass_of($class, AddTaintsInterface::class)) {
            $this->add_taints_checks[] = $class;
        }
        if (is_subclass_of($class, RemoveTaintsInterface::class)) {
            $this->remove_taints_checks[] = $class;
        }
    }
    public function hasAfterMethodCallAnalysisHandlers() : bool
    {
        return count($this->after_method_checks) > 0;
    }
    public function dispatchAfterMethodCallAnalysis(AfterMethodCallAnalysisEvent $event) : void
    {
        foreach ($this->after_method_checks as $handler) {
            $handler::afterMethodCallAnalysis($event);
        }
    }
    public function dispatchAfterFunctionCallAnalysis(AfterFunctionCallAnalysisEvent $event) : void
    {
        foreach ($this->after_function_checks as $handler) {
            $handler::afterFunctionCallAnalysis($event);
        }
    }
    public function dispatchAfterEveryFunctionCallAnalysis(AfterEveryFunctionCallAnalysisEvent $event) : void
    {
        foreach ($this->after_every_function_checks as $handler) {
            $handler::afterEveryFunctionCallAnalysis($event);
        }
    }
    public function dispatchAfterExpressionAnalysis(AfterExpressionAnalysisEvent $event) : ?bool
    {
        foreach ($this->after_expression_checks as $handler) {
            if ($handler::afterExpressionAnalysis($event) === \false) {
                return \false;
            }
        }
        return null;
    }
    public function dispatchBeforeStatementAnalysis(BeforeStatementAnalysisEvent $event) : ?bool
    {
        foreach ($this->before_statement_checks as $handler) {
            if ($handler::beforeStatementAnalysis($event) === \false) {
                return \false;
            }
        }
        return null;
    }
    public function dispatchAfterStatementAnalysis(AfterStatementAnalysisEvent $event) : ?bool
    {
        foreach ($this->after_statement_checks as $handler) {
            if ($handler::afterStatementAnalysis($event) === \false) {
                return \false;
            }
        }
        return null;
    }
    public function dispatchStringInterpreter(StringInterpreterEvent $event) : ?TLiteralString
    {
        foreach ($this->string_interpreters as $handler) {
            if ($type = $handler::getTypeFromValue($event)) {
                return $type;
            }
        }
        return null;
    }
    public function dispatchAfterClassLikeExistenceCheck(AfterClassLikeExistenceCheckEvent $event) : void
    {
        foreach ($this->after_classlike_exists_checks as $handler) {
            $handler::afterClassLikeExistenceCheck($event);
        }
    }
    public function dispatchAfterClassLikeAnalysis(AfterClassLikeAnalysisEvent $event) : ?bool
    {
        foreach ($this->after_classlike_checks as $handler) {
            if ($handler::afterStatementAnalysis($event) === \false) {
                return \false;
            }
        }
        return null;
    }
    public function hasAfterClassLikeVisitHandlers() : bool
    {
        return count($this->after_visit_classlikes) > 0;
    }
    public function dispatchAfterClassLikeVisit(AfterClassLikeVisitEvent $event) : void
    {
        foreach ($this->after_visit_classlikes as $handler) {
            $handler::afterClassLikeVisit($event);
        }
    }
    public function dispatchAfterCodebasePopulated(AfterCodebasePopulatedEvent $event) : void
    {
        foreach ($this->after_codebase_populated as $handler) {
            $handler::afterCodebasePopulated($event);
        }
    }
    public function dispatchBeforeAddIssue(BeforeAddIssueEvent $event) : ?bool
    {
        foreach ($this->before_add_issue as $handler) {
            $result = $handler::beforeAddIssue($event);
            if (is_bool($result)) {
                return $result;
            }
        }
        return null;
    }
    public function dispatchAfterAnalysis(AfterAnalysisEvent $event) : void
    {
        foreach ($this->after_analysis as $handler) {
            $handler::afterAnalysis($event);
        }
    }
    public function dispatchAfterFileAnalysis(AfterFileAnalysisEvent $event) : void
    {
        foreach ($this->after_file_checks as $handler) {
            $handler::afterAnalyzeFile($event);
        }
    }
    public function dispatchBeforeFileAnalysis(BeforeFileAnalysisEvent $event) : void
    {
        foreach ($this->before_file_checks as $handler) {
            $handler::beforeAnalyzeFile($event);
        }
    }
    public function dispatchAfterFunctionLikeAnalysis(AfterFunctionLikeAnalysisEvent $event) : ?bool
    {
        foreach ($this->after_functionlike_checks as $handler) {
            if ($handler::afterStatementAnalysis($event) === \false) {
                return \false;
            }
        }
        return null;
    }
    /**
     * @return list<string>
     */
    public function dispatchAddTaints(AddRemoveTaintsEvent $event) : array
    {
        $added_taints = [];
        foreach ($this->add_taints_checks as $handler) {
            $added_taints = [...$added_taints, ...$handler::addTaints($event)];
        }
        return $added_taints;
    }
    /**
     * @return list<string>
     */
    public function dispatchRemoveTaints(AddRemoveTaintsEvent $event) : array
    {
        $removed_taints = [];
        foreach ($this->remove_taints_checks as $handler) {
            $removed_taints = [...$removed_taints, ...$handler::removeTaints($event)];
        }
        return $removed_taints;
    }
}
<?php

namespace Psalm\Internal;

use RuntimeException;
use Throwable;
use function defined;
use function error_reporting;
use function fwrite;
use function implode;
use function ini_set;
use function set_error_handler;
use function set_exception_handler;
use const E_ALL;
use const E_STRICT;
use const STDERR;
/**
 * @internal
 */
final class ErrorHandler
{
    private static bool $exceptions_enabled = \true;
    private static string $args = '';
    /**
     * @param array<int,string> $argv
     */
    public static function install(array $argv = array()) : void
    {
        self::$args = implode(' ', $argv);
        self::setErrorReporting();
        self::installErrorHandler();
        self::installExceptionHandler();
    }
    /**
     * @template T
     * @param callable():T $f
     * @return T
     */
    public static function runWithExceptionsSuppressed(callable $f)
    {
        try {
            self::$exceptions_enabled = \false;
            return $f();
        } finally {
            self::$exceptions_enabled = \true;
        }
    }
    /** @psalm-suppress UnusedConstructor added to prevent instantiations */
    private function __construct()
    {
    }
    private static function setErrorReporting() : void
    {
        error_reporting(E_ALL | E_STRICT);
        ini_set('display_errors', '1');
    }
    private static function installErrorHandler() : void
    {
        set_error_handler(static function (int $error_code, string $error_message, string $error_filename = 'unknown', int $error_line = -1) : bool {
            if (\Psalm\Internal\ErrorHandler::$exceptions_enabled && $error_code & error_reporting()) {
                throw new RuntimeException('PHP Error: ' . $error_message . ' in ' . $error_filename . ':' . $error_line . ' for command with CLI args "' . \Psalm\Internal\ErrorHandler::$args . '"', $error_code);
            }
            // let PHP handle suppressed errors how it sees fit
            return \false;
        });
    }
    private static function installExceptionHandler() : void
    {
        /**
         * If there is an uncaught exception,
         * then print more of the backtrace than is done by default to stderr,
         * then exit with a non-zero exit code to indicate failure.
         */
        set_exception_handler(static function (Throwable $throwable) : void {
            fwrite(STDERR, "Uncaught {$throwable}\n");
            $version = defined('PSALM_VERSION') ? \PSALM_VERSION : '(unknown version)';
            fwrite(STDERR, "(Psalm {$version} crashed due to an uncaught Throwable)\n");
            exit(1);
        });
    }
}
<?php

namespace Psalm\Internal\Cli;

use AssertionError;
use _HumbugBox1cb33d1f20f1\Composer\XdebugHandler\XdebugHandler;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\CliUtils;
use Psalm\Internal\Composer;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\IncludeCollector;
use Psalm\Internal\Provider\ClassLikeStorageCacheProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileStorageCacheProvider;
use Psalm\Internal\Provider\ParserCacheProvider;
use Psalm\Internal\Provider\ProjectCacheProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\IssueBuffer;
use Psalm\Progress\DebugProgress;
use Psalm\Progress\DefaultProgress;
use Psalm\Report;
use Psalm\Report\ReportOptions;
use function array_key_exists;
use function array_map;
use function array_slice;
use function chdir;
use function end;
use function explode;
use function fwrite;
use function gc_collect_cycles;
use function gc_disable;
use function getcwd;
use function getopt;
use function implode;
use function in_array;
use function ini_set;
use function is_array;
use function is_numeric;
use function is_string;
use function max;
use function microtime;
use function preg_last_error_msg;
use function preg_replace;
use function preg_split;
use function realpath;
use function strpos;
use function substr;
use const DIRECTORY_SEPARATOR;
use const PHP_EOL;
use const STDERR;
// phpcs:disable PSR1.Files.SideEffects
require_once __DIR__ . '/../ErrorHandler.php';
require_once __DIR__ . '/../CliUtils.php';
require_once __DIR__ . '/../Composer.php';
require_once __DIR__ . '/../IncludeCollector.php';
require_once __DIR__ . '/../../IssueBuffer.php';
/**
 * @internal
 */
final class Refactor
{
    /** @param array<int,string> $argv */
    public static function run(array $argv) : void
    {
        CliUtils::checkRuntimeRequirements();
        ini_set('memory_limit', '8192M');
        gc_collect_cycles();
        gc_disable();
        ErrorHandler::install($argv);
        $args = array_slice($argv, 1);
        $valid_short_options = ['f:', 'm', 'h', 'r:', 'c:'];
        $valid_long_options = ['help', 'debug', 'debug-by-line', 'debug-emitted-issues', 'config:', 'root:', 'threads:', 'move:', 'into:', 'rename:', 'to:'];
        // get options from command line
        $options = getopt(implode('', $valid_short_options), $valid_long_options);
        array_map(static function (string $arg) use($valid_long_options) : void {
            if (strpos($arg, '--') === 0 && $arg !== '--') {
                $arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);
                if ($arg_name === 'refactor') {
                    // valid option for psalm, ignored by psalter
                    return;
                }
                if (!in_array($arg_name, $valid_long_options) && !in_array($arg_name . ':', $valid_long_options) && !in_array($arg_name . '::', $valid_long_options)) {
                    fwrite(STDERR, 'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL . 'Type --help to see a list of supported arguments' . PHP_EOL);
                    exit(1);
                }
            }
        }, $args);
        if (array_key_exists('help', $options)) {
            $options['h'] = \false;
        }
        if (isset($options['config'])) {
            $options['c'] = $options['config'];
        }
        if (isset($options['c']) && is_array($options['c'])) {
            die('Too many config files provided' . PHP_EOL);
        }
        if (array_key_exists('h', $options)) {
            echo <<<HELP
Usage:
    psalm-refactor [options] [symbol1] into [symbol2]

Options:
    -h, --help
        Display this help message

    --debug, --debug-by-line, --debug-emitted-issues
        Debug information

    -c, --config=psalm.xml
        Path to a psalm.xml configuration file. Run psalm --init to create one.

    -r, --root
        If running Psalm globally you'll need to specify a project root. Defaults to cwd

    --threads=auto
        If greater than one, Psalm will run analysis on multiple threads, speeding things up.
        By default

    --move "[Identifier]" --into "[Class]"
        Moves the specified item into the class. More than one item can be moved into a class
        by passing a comma-separated list of values e.g.

        --move "Ns\\Foo::bar,Ns\\Foo::baz" --into "Biz\\Bang\\DestinationClass"

    --rename "[Identifier]" --to "[NewIdentifier]"
        Renames a specified item (e.g. method) and updates all references to it that Psalm can
        identify.

HELP;
            exit;
        }
        if (isset($options['root'])) {
            $options['r'] = $options['root'];
        }
        $current_dir = (string) getcwd() . DIRECTORY_SEPARATOR;
        if (isset($options['r']) && is_string($options['r'])) {
            $root_path = realpath($options['r']);
            if (!$root_path) {
                die('Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL);
            }
            $current_dir = $root_path . DIRECTORY_SEPARATOR;
        }
        $vendor_dir = CliUtils::getVendorDir($current_dir);
        // capture environment before registering autoloader (it may destroy it)
        IssueBuffer::captureServer($_SERVER);
        $include_collector = new IncludeCollector();
        $first_autoloader = $include_collector->runAndCollect(
            // we ignore the FQN because of a hack in scoper.inc that needs full path
            // phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName
            static fn(): ?\Composer\Autoload\ClassLoader => CliUtils::requireAutoloaders($current_dir, isset($options['r']), $vendor_dir)
        );
        // If Xdebug is enabled, restart without it
        (new XdebugHandler('PSALTER'))->check();
        $path_to_config = CliUtils::getPathToConfig($options);
        $args = CliUtils::getArguments();
        $operation = null;
        $last_arg = null;
        $to_refactor = [];
        foreach ($args as $arg) {
            if ($arg === '--move') {
                $operation = 'move';
                continue;
            }
            if ($arg === '--into') {
                if ($operation !== 'move' || !$last_arg) {
                    die('--into is not expected here' . PHP_EOL);
                }
                $operation = 'move_into';
                continue;
            }
            if ($arg === '--rename') {
                $operation = 'rename';
                continue;
            }
            if ($arg === '--to') {
                if ($operation !== 'rename' || !$last_arg) {
                    die('--to is not expected here' . PHP_EOL);
                }
                $operation = 'rename_to';
                continue;
            }
            if ($arg[0] === '-') {
                $operation = null;
                continue;
            }
            if ($operation === 'move_into' || $operation === 'rename_to') {
                if (!$last_arg) {
                    die('Expecting a previous argument' . PHP_EOL);
                }
                if ($operation === 'move_into') {
                    $last_arg_parts = preg_split('/, ?/', $last_arg);
                    if ($last_arg_parts === \false) {
                        throw new AssertionError(preg_last_error_msg());
                    }
                    foreach ($last_arg_parts as $last_arg_part) {
                        if (strpos($last_arg_part, '::')) {
                            [, $identifier_name] = explode('::', $last_arg_part);
                            $to_refactor[$last_arg_part] = $arg . '::' . $identifier_name;
                        } else {
                            $namespace_parts = explode('\\', $last_arg_part);
                            $class_name = end($namespace_parts);
                            $to_refactor[$last_arg_part] = $arg . '\\' . $class_name;
                        }
                    }
                } else {
                    $to_refactor[$last_arg] = $arg;
                }
                $last_arg = null;
                $operation = null;
                continue;
            }
            if ($operation === 'move' || $operation === 'rename') {
                $last_arg = $arg;
                continue;
            }
            die('Unexpected argument "' . $arg . '"' . PHP_EOL);
        }
        if (!$to_refactor) {
            die('No --move or --rename arguments supplied' . PHP_EOL);
        }
        $config = CliUtils::initializeConfig($path_to_config, $current_dir, Report::TYPE_CONSOLE, $first_autoloader);
        $config->setIncludeCollector($include_collector);
        if ($config->resolve_from_config_file) {
            $current_dir = $config->base_dir;
            chdir($current_dir);
        }
        $threads = isset($options['threads']) && is_numeric($options['threads']) ? (int) $options['threads'] : max(1, ProjectAnalyzer::getCpuCount() - 2);
        $providers = new Providers(new FileProvider(), new ParserCacheProvider($config, \false), new FileStorageCacheProvider($config), new ClassLikeStorageCacheProvider($config), null, new ProjectCacheProvider(Composer::getLockFilePath($current_dir)));
        $debug = array_key_exists('debug', $options) || array_key_exists('debug-by-line', $options);
        $progress = $debug ? new DebugProgress() : new DefaultProgress();
        if (array_key_exists('debug-emitted-issues', $options)) {
            $config->debug_emitted_issues = \true;
        }
        $project_analyzer = new ProjectAnalyzer($config, $providers, new ReportOptions(), [], $threads, $progress);
        if (array_key_exists('debug-by-line', $options)) {
            $project_analyzer->debug_lines = \true;
        }
        $project_analyzer->refactorCodeAfterCompletion($to_refactor);
        $start_time = microtime(\true);
        $project_analyzer->check($current_dir);
        IssueBuffer::finish($project_analyzer, \false, $start_time);
    }
}
<?php

namespace Psalm\Internal\Cli;

use Psalm\Internal\CliUtils;
use Psalm\Internal\PluginManager\Command\DisableCommand;
use Psalm\Internal\PluginManager\Command\EnableCommand;
use Psalm\Internal\PluginManager\Command\ShowCommand;
use Psalm\Internal\PluginManager\PluginListFactory;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Application;
use function dirname;
use function getcwd;
use const DIRECTORY_SEPARATOR;
// phpcs:disable PSR1.Files.SideEffects
require_once __DIR__ . '/../CliUtils.php';
require_once __DIR__ . '/../Composer.php';
/**
 * @internal
 */
final class Plugin
{
    public static function run() : void
    {
        CliUtils::checkRuntimeRequirements();
        $current_dir = (string) getcwd() . DIRECTORY_SEPARATOR;
        $vendor_dir = CliUtils::getVendorDir($current_dir);
        CliUtils::requireAutoloaders($current_dir, \false, $vendor_dir);
        $app = new Application('psalm-plugin', \PSALM_VERSION);
        $psalm_root = dirname(__DIR__, 4) . DIRECTORY_SEPARATOR;
        $plugin_list_factory = new PluginListFactory($current_dir, $psalm_root);
        $app->addCommands([new ShowCommand($plugin_list_factory), new EnableCommand($plugin_list_factory), new DisableCommand($plugin_list_factory)]);
        $app->setDefaultCommand('show');
        $app->run();
    }
}
<?php

namespace Psalm\Internal\Cli;

use Psalm\Config;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\CliUtils;
use Psalm\Internal\Composer;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\Fork\PsalmRestarter;
use Psalm\Internal\IncludeCollector;
use Psalm\Internal\Provider\ClassLikeStorageCacheProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceCacheProvider;
use Psalm\Internal\Provider\FileStorageCacheProvider;
use Psalm\Internal\Provider\ParserCacheProvider;
use Psalm\Internal\Provider\ProjectCacheProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\Report;
use function array_key_exists;
use function array_map;
use function array_search;
use function array_slice;
use function chdir;
use function error_log;
use function fwrite;
use function gc_disable;
use function getcwd;
use function getopt;
use function implode;
use function in_array;
use function ini_set;
use function is_array;
use function is_numeric;
use function is_string;
use function preg_replace;
use function realpath;
use function setlocale;
use function strpos;
use function strtolower;
use function substr;
use const DIRECTORY_SEPARATOR;
use const LC_CTYPE;
use const PHP_EOL;
use const STDERR;
// phpcs:disable PSR1.Files.SideEffects
require_once __DIR__ . '/../ErrorHandler.php';
require_once __DIR__ . '/../CliUtils.php';
require_once __DIR__ . '/../Composer.php';
require_once __DIR__ . '/../IncludeCollector.php';
/**
 * @internal
 */
final class LanguageServer
{
    /** @param array<int,string> $argv */
    public static function run(array $argv) : void
    {
        CliUtils::checkRuntimeRequirements();
        gc_disable();
        ErrorHandler::install($argv);
        $valid_short_options = ['h', 'v', 'c:', 'r:'];
        $valid_long_options = ['clear-cache', 'config:', 'find-dead-code', 'help', 'root:', 'use-ini-defaults', 'version', 'tcp:', 'tcp-server', 'disable-on-change::', 'enable-autocomplete::', 'use-extended-diagnostic-codes', 'verbose'];
        $args = array_slice($argv, 1);
        $psalm_proxy = array_search('--language-server', $args, \true);
        if ($psalm_proxy !== \false) {
            unset($args[$psalm_proxy]);
        }
        array_map(static function (string $arg) use($valid_long_options) : void {
            if (strpos($arg, '--') === 0 && $arg !== '--') {
                $arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);
                if (!in_array($arg_name, $valid_long_options, \true) && !in_array($arg_name . ':', $valid_long_options, \true) && !in_array($arg_name . '::', $valid_long_options, \true)) {
                    fwrite(STDERR, 'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL . 'Type --help to see a list of supported arguments' . PHP_EOL);
                    error_log('Bad argument');
                    exit(1);
                }
            }
        }, $args);
        // get options from command line
        $options = getopt(implode('', $valid_short_options), $valid_long_options);
        if (!array_key_exists('use-ini-defaults', $options)) {
            ini_set('display_errors', '1');
            ini_set('display_startup_errors', '1');
            ini_set('memory_limit', (string) (8 * 1024 * 1024 * 1024));
        }
        if (array_key_exists('help', $options)) {
            $options['h'] = \false;
        }
        if (array_key_exists('version', $options)) {
            $options['v'] = \false;
        }
        if (isset($options['config'])) {
            $options['c'] = $options['config'];
        }
        if (isset($options['c']) && is_array($options['c'])) {
            fwrite(STDERR, 'Too many config files provided' . PHP_EOL);
            exit(1);
        }
        if (array_key_exists('h', $options)) {
            echo <<<HELP
Usage:
    psalm-language-server [options]

Options:
    -h, --help
        Display this help message

    -v, --version
        Display the Psalm version

    -c, --config=psalm.xml
        Path to a psalm.xml configuration file. Run psalm --init to create one.

    -r, --root
        If running Psalm globally you'll need to specify a project root. Defaults to cwd

    --find-dead-code
        Look for dead code

    --clear-cache
        Clears all cache files that the language server uses for this specific project

    --use-ini-defaults
        Use PHP-provided ini defaults for memory and error display

    --tcp=url
        Use TCP mode (by default Psalm uses STDIO)

    --tcp-server
        Use TCP in server mode (default is client)

    --disable-on-change[=line-number-threshold]
        If added, the language server will not respond to onChange events.
        You can also specify a line count over which Psalm will not run on-change events.

    --enable-autocomplete[=BOOL]
        Enables or disables autocomplete on methods and properties. Default is true.

    --use-extended-diagnostic-codes
        Enables sending help uri links with the code in diagnostic messages.

    --verbose
        Will send log messages to the client with information.

HELP;
            exit;
        }
        if (getcwd() === \false) {
            fwrite(STDERR, 'Cannot get current working directory' . PHP_EOL);
            exit(1);
        }
        if (isset($options['root'])) {
            $options['r'] = $options['root'];
        }
        $current_dir = (string) getcwd() . DIRECTORY_SEPARATOR;
        if (isset($options['r']) && is_string($options['r'])) {
            $root_path = realpath($options['r']);
            if (!$root_path) {
                fwrite(STDERR, 'Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL);
                exit(1);
            }
            $current_dir = $root_path . DIRECTORY_SEPARATOR;
        }
        $vendor_dir = CliUtils::getVendorDir($current_dir);
        $include_collector = new IncludeCollector();
        $first_autoloader = $include_collector->runAndCollect(
            // we ignore the FQN because of a hack in scoper.inc that needs full path
            // phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName
            static fn(): ?\Composer\Autoload\ClassLoader => CliUtils::requireAutoloaders($current_dir, isset($options['r']), $vendor_dir)
        );
        if (array_key_exists('v', $options)) {
            echo 'Psalm ' . \PSALM_VERSION . PHP_EOL;
            exit;
        }
        $ini_handler = new PsalmRestarter('PSALM');
        $ini_handler->disableExtension('grpc');
        // If Xdebug is enabled, restart without it
        $ini_handler->check();
        setlocale(LC_CTYPE, 'C');
        $path_to_config = CliUtils::getPathToConfig($options);
        if (isset($options['tcp'])) {
            if (!is_string($options['tcp'])) {
                fwrite(STDERR, 'tcp url should be a string' . PHP_EOL);
                exit(1);
            }
        }
        $find_unused_code = isset($options['find-dead-code']) ? 'auto' : null;
        $config = CliUtils::initializeConfig($path_to_config, $current_dir, Report::TYPE_CONSOLE, $first_autoloader);
        $config->setIncludeCollector($include_collector);
        if ($config->resolve_from_config_file) {
            $current_dir = $config->base_dir;
            chdir($current_dir);
        }
        $config->setServerMode();
        if (isset($options['clear-cache'])) {
            $cache_directory = $config->getCacheDirectory();
            if ($cache_directory !== null) {
                Config::removeCacheDirectory($cache_directory);
            }
            echo 'Cache directory deleted' . PHP_EOL;
            exit;
        }
        $providers = new Providers(new FileProvider(), new ParserCacheProvider($config), new FileStorageCacheProvider($config), new ClassLikeStorageCacheProvider($config), new FileReferenceCacheProvider($config), new ProjectCacheProvider(Composer::getLockFilePath($current_dir)));
        $project_analyzer = new ProjectAnalyzer($config, $providers);
        if ($config->find_unused_variables) {
            $project_analyzer->getCodebase()->reportUnusedVariables();
        }
        if ($config->find_unused_code) {
            $find_unused_code = 'auto';
        }
        if (isset($options['disable-on-change']) && is_numeric($options['disable-on-change'])) {
            $project_analyzer->onchange_line_limit = (int) $options['disable-on-change'];
        }
        $project_analyzer->provide_completion = !isset($options['enable-autocomplete']) || !is_string($options['enable-autocomplete']) || strtolower($options['enable-autocomplete']) !== 'false';
        if ($find_unused_code) {
            $project_analyzer->getCodebase()->reportUnusedCode($find_unused_code);
        }
        if (isset($options['use-extended-diagnostic-codes'])) {
            $project_analyzer->language_server_use_extended_diagnostic_codes = \true;
        }
        if (isset($options['verbose'])) {
            $project_analyzer->language_server_verbose = \true;
        }
        $project_analyzer->server($options['tcp'] ?? null, isset($options['tcp-server']));
    }
}
<?php

namespace Psalm\Internal\Cli;

use AssertionError;
use _HumbugBox1cb33d1f20f1\Composer\XdebugHandler\XdebugHandler;
use Psalm\Config;
use Psalm\Exception\UnsupportedIssueToFixException;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\CliUtils;
use Psalm\Internal\Composer;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\IncludeCollector;
use Psalm\Internal\Provider\ClassLikeStorageCacheProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileStorageCacheProvider;
use Psalm\Internal\Provider\ParserCacheProvider;
use Psalm\Internal\Provider\ProjectCacheProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\Internal\Scanner\ParsedDocblock;
use Psalm\IssueBuffer;
use Psalm\Progress\DebugProgress;
use Psalm\Progress\DefaultProgress;
use Psalm\Progress\VoidProgress;
use Psalm\Report;
use Psalm\Report\ReportOptions;
use function array_filter;
use function array_key_exists;
use function array_map;
use function array_shift;
use function array_slice;
use function chdir;
use function count;
use function explode;
use function file_exists;
use function file_get_contents;
use function filter_var;
use function fwrite;
use function gc_collect_cycles;
use function gc_disable;
use function getcwd;
use function getopt;
use function implode;
use function in_array;
use function ini_set;
use function is_array;
use function is_dir;
use function is_numeric;
use function is_string;
use function microtime;
use function pathinfo;
use function preg_last_error_msg;
use function preg_replace;
use function preg_split;
use function realpath;
use function strpos;
use function strtolower;
use function substr;
use function trim;
use const DIRECTORY_SEPARATOR;
use const FILTER_NULL_ON_FAILURE;
use const FILTER_VALIDATE_BOOLEAN;
use const PATHINFO_EXTENSION;
use const PHP_EOL;
use const STDERR;
// phpcs:disable PSR1.Files.SideEffects
require_once __DIR__ . '/../ErrorHandler.php';
require_once __DIR__ . '/../CliUtils.php';
require_once __DIR__ . '/../Composer.php';
require_once __DIR__ . '/../IncludeCollector.php';
require_once __DIR__ . '/../../IssueBuffer.php';
/**
 * @internal
 */
final class Psalter
{
    private const SHORT_OPTIONS = ['f:', 'm', 'h', 'r:', 'c:'];
    private const LONG_OPTIONS = ['help', 'debug', 'debug-by-line', 'debug-emitted-issues', 'config:', 'file:', 'root:', 'plugin:', 'issues:', 'list-supported-issues', 'php-version:', 'dry-run', 'safe-types', 'find-unused-code', 'threads:', 'codeowner:', 'allow-backwards-incompatible-changes:', 'add-newline-between-docblock-annotations:', 'no-cache', 'no-progress'];
    /** @param array<int,string> $argv */
    public static function run(array $argv) : void
    {
        CliUtils::checkRuntimeRequirements();
        gc_collect_cycles();
        gc_disable();
        ErrorHandler::install($argv);
        self::setMemoryLimit();
        $args = array_slice($argv, 1);
        // get options from command line
        $options = getopt(implode('', self::SHORT_OPTIONS), self::LONG_OPTIONS);
        self::validateCliArguments($args);
        self::syncShortOptions($options);
        if (isset($options['c']) && is_array($options['c'])) {
            die('Too many config files provided' . PHP_EOL);
        }
        if (array_key_exists('h', $options)) {
            echo <<<HELP
Usage:
    psalter [options] [file...]

Options:
    -h, --help
        Display this help message

    --debug, --debug-by-line, --debug-emitted-issues
        Debug information

    -c, --config=psalm.xml
        Path to a psalm.xml configuration file. Run psalm --init to create one.

    -m, --monochrome
        Enable monochrome output

    --no-progress
        Disable the progress indicator

    -r, --root
        If running Psalm globally you'll need to specify a project root. Defaults to cwd

    --plugin=PATH
        Executes a plugin, an alternative to using the Psalm config

    --dry-run
        Shows a diff of all the changes, without making them

    --safe-types
        Only update PHP types when the new type information comes from other PHP types,
        as opposed to type information that just comes from docblocks

    --php-version=PHP_MAJOR_VERSION.PHP_MINOR_VERSION

    --issues=IssueType1,IssueType2
        If any issues can be fixed automatically, Psalm will update the codebase. To fix as many issues as
        possible, use --issues=all

    --list-supported-issues
        Display the list of issues that psalter knows how to fix

    --find-unused-code
        Include unused code as a candidate for removal

    --threads=INT
        If greater than one, Psalm will run analysis on multiple threads, speeding things up.

    --codeowner=[codeowner]
        You can specify a GitHub code ownership group, and only that owner's code will be updated.

    --allow-backwards-incompatible-changes=BOOL
        Allow Psalm modify method signatures that could break code outside the project. Defaults to true.

    --add-newline-between-docblock-annotations=BOOL
        Whether to add or not add a new line between docblock annotations. Defaults to true.

    --no-cache
        Runs Psalm without using cache

HELP;
            exit;
        }
        if (!isset($options['issues']) && !isset($options['list-supported-issues']) && (!isset($options['plugin']) || $options['plugin'] === \false)) {
            fwrite(STDERR, 'Please specify the issues you want to fix with --issues=IssueOne,IssueTwo or --issues=all, ' . 'or provide a plugin that has its own manipulations with --plugin=path/to/plugin.php' . PHP_EOL);
            exit(1);
        }
        $current_dir = (string) getcwd() . DIRECTORY_SEPARATOR;
        if (isset($options['r']) && is_string($options['r'])) {
            $root_path = realpath($options['r']);
            if (!$root_path) {
                die('Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL);
            }
            $current_dir = $root_path . DIRECTORY_SEPARATOR;
        }
        $vendor_dir = CliUtils::getVendorDir($current_dir);
        // capture environment before registering autoloader (it may destroy it)
        IssueBuffer::captureServer($_SERVER);
        $include_collector = new IncludeCollector();
        $first_autoloader = $include_collector->runAndCollect(
            // we ignore the FQN because of a hack in scoper.inc that needs full path
            // phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName
            static fn(): ?\Composer\Autoload\ClassLoader => CliUtils::requireAutoloaders($current_dir, isset($options['r']), $vendor_dir)
        );
        // If Xdebug is enabled, restart without it
        (new XdebugHandler('PSALTER'))->check();
        $paths_to_check = CliUtils::getPathsToCheck($options['f'] ?? null);
        $path_to_config = CliUtils::getPathToConfig($options);
        $config = CliUtils::initializeConfig($path_to_config, $current_dir, Report::TYPE_CONSOLE, $first_autoloader);
        if (isset($options['no-cache'])) {
            $config->cache_directory = null;
        }
        $config->setIncludeCollector($include_collector);
        if ($config->resolve_from_config_file) {
            $current_dir = $config->base_dir;
            chdir($current_dir);
        }
        $threads = isset($options['threads']) && is_numeric($options['threads']) ? (int) $options['threads'] : 1;
        if (isset($options['no-cache'])) {
            $providers = new Providers(new FileProvider());
        } else {
            $providers = new Providers(new FileProvider(), new ParserCacheProvider($config, \false), new FileStorageCacheProvider($config), new ClassLikeStorageCacheProvider($config), null, new ProjectCacheProvider(Composer::getLockFilePath($current_dir)));
        }
        if (array_key_exists('list-supported-issues', $options)) {
            echo implode(',', ProjectAnalyzer::getSupportedIssuesToFix()) . PHP_EOL;
            exit;
        }
        $debug = array_key_exists('debug', $options) || array_key_exists('debug-by-line', $options);
        if ($debug) {
            $progress = new DebugProgress();
        } elseif (isset($options['no-progress'])) {
            $progress = new VoidProgress();
        } else {
            $progress = new DefaultProgress();
        }
        $stdout_report_options = new ReportOptions();
        $stdout_report_options->use_color = !array_key_exists('m', $options);
        $project_analyzer = new ProjectAnalyzer($config, $providers, $stdout_report_options, [], $threads, $progress);
        if (array_key_exists('debug-by-line', $options)) {
            $project_analyzer->debug_lines = \true;
        }
        if (array_key_exists('debug-emitted-issues', $options)) {
            $config->debug_emitted_issues = \true;
        }
        if (array_key_exists('issues', $options)) {
            if (!is_string($options['issues']) || !$options['issues']) {
                die('Expecting a comma-separated list of issues' . PHP_EOL);
            }
            $issues = explode(',', $options['issues']);
            $keyed_issues = [];
            foreach ($issues as $issue) {
                $keyed_issues[$issue] = \true;
            }
        } else {
            $keyed_issues = [];
        }
        CliUtils::initPhpVersion($options, $config, $project_analyzer);
        if (isset($options['codeowner'])) {
            $codeowner_files = self::loadCodeowners($providers);
            $desired_codeowners = is_array($options['codeowner']) ? $options['codeowner'] : [$options['codeowner']];
            $files_for_codeowners = self::loadCodeownersFiles($desired_codeowners, $codeowner_files);
            $paths_to_check = is_array($paths_to_check) ? [...$paths_to_check, ...$files_for_codeowners] : $files_for_codeowners;
        }
        if (isset($options['allow-backwards-incompatible-changes'])) {
            $allow_backwards_incompatible_changes = filter_var($options['allow-backwards-incompatible-changes'], FILTER_VALIDATE_BOOLEAN, ['flags' => FILTER_NULL_ON_FAILURE]);
            if ($allow_backwards_incompatible_changes === null) {
                die('--allow-backwards-incompatible-changes expects a boolean value [true|false|1|0]' . PHP_EOL);
            }
            $project_analyzer->getCodebase()->allow_backwards_incompatible_changes = $allow_backwards_incompatible_changes;
        }
        if (isset($options['add-newline-between-docblock-annotations'])) {
            $doc_block_add_new_line_before_return = filter_var($options['add-newline-between-docblock-annotations'], FILTER_VALIDATE_BOOLEAN, ['flags' => FILTER_NULL_ON_FAILURE]);
            if ($doc_block_add_new_line_before_return === null) {
                die('--add-newline-between-docblock-annotations expects a boolean value [true|false|1|0]' . PHP_EOL);
            }
            ParsedDocblock::addNewLineBetweenAnnotations($doc_block_add_new_line_before_return);
        }
        $plugins = [];
        if (isset($options['plugin'])) {
            $plugins = $options['plugin'];
            if (!is_array($plugins)) {
                $plugins = [$plugins];
            }
        }
        /** @var string $plugin_path */
        foreach ($plugins as $plugin_path) {
            Config::getInstance()->addPluginPath($current_dir . $plugin_path);
        }
        $find_unused_code = array_key_exists('find-unused-code', $options);
        foreach ($keyed_issues as $issue_name => $_) {
            // MissingParamType requires the scanning of all files to inform possible params
            if (strpos($issue_name, 'Unused') !== \false || $issue_name === 'MissingParamType' || $issue_name === 'UnnecessaryVarAnnotation' || $issue_name === 'all') {
                $find_unused_code = \true;
                break;
            }
        }
        if ($find_unused_code) {
            $project_analyzer->getCodebase()->reportUnusedCode();
        }
        $project_analyzer->alterCodeAfterCompletion(array_key_exists('dry-run', $options), array_key_exists('safe-types', $options));
        if ($keyed_issues === ['all' => \true]) {
            $project_analyzer->setAllIssuesToFix();
        } else {
            try {
                $project_analyzer->setIssuesToFix($keyed_issues);
            } catch (UnsupportedIssueToFixException $e) {
                fwrite(STDERR, $e->getMessage() . PHP_EOL);
                exit(1);
            }
        }
        $start_time = microtime(\true);
        if ($paths_to_check === null || count($paths_to_check) > 1 || $find_unused_code) {
            if ($paths_to_check) {
                $files_to_update = [];
                foreach ($paths_to_check as $path_to_check) {
                    if (!is_dir($path_to_check)) {
                        $files_to_update[] = (string) realpath($path_to_check);
                    } else {
                        foreach ($providers->file_provider->getFilesInDir($path_to_check, ['php']) as $php_file_path) {
                            $files_to_update[] = $php_file_path;
                        }
                    }
                }
                $project_analyzer->getCodebase()->analyzer->setFilesToUpdate($files_to_update);
            }
            $project_analyzer->check($current_dir);
        } elseif ($paths_to_check) {
            foreach ($paths_to_check as $path_to_check) {
                if (is_dir($path_to_check)) {
                    $project_analyzer->checkDir($path_to_check);
                } else {
                    $project_analyzer->checkFile($path_to_check);
                }
            }
        }
        IssueBuffer::finish($project_analyzer, \false, $start_time);
    }
    private static function setMemoryLimit() : void
    {
        $memLimit = CliUtils::getMemoryLimitInBytes();
        // Magic number is 4096M in bytes
        if ($memLimit > 0 && $memLimit < 8 * 1024 * 1024 * 1024) {
            ini_set('memory_limit', (string) (8 * 1024 * 1024 * 1024));
        }
    }
    /** @param array<int,string> $args */
    private static function validateCliArguments(array $args) : void
    {
        array_map(static function (string $arg) : void {
            if (strpos($arg, '--') === 0 && $arg !== '--') {
                $arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);
                if ($arg_name === 'alter') {
                    // valid option for psalm, ignored by psalter
                    return;
                }
                if (!in_array($arg_name, self::LONG_OPTIONS) && !in_array($arg_name . ':', self::LONG_OPTIONS) && !in_array($arg_name . '::', self::LONG_OPTIONS)) {
                    fwrite(STDERR, 'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL . 'Type --help to see a list of supported arguments' . PHP_EOL);
                    exit(1);
                }
            }
        }, $args);
    }
    /**
     * @param array<string, false|list<mixed>|string> $options
     * @param-out array<string, false|list<mixed>|string> $options
     */
    private static function syncShortOptions(array &$options) : void
    {
        if (array_key_exists('help', $options)) {
            $options['h'] = \false;
        }
        if (array_key_exists('monochrome', $options)) {
            $options['m'] = \false;
        }
        if (isset($options['config'])) {
            $options['c'] = $options['config'];
        }
        if (isset($options['root'])) {
            $options['r'] = $options['root'];
        }
    }
    /** @return array<string, array<int, string>> */
    private static function loadCodeowners(Providers $providers) : array
    {
        if (file_exists('CODEOWNERS')) {
            $codeowners_file_path = realpath('CODEOWNERS');
        } elseif (file_exists('.github/CODEOWNERS')) {
            $codeowners_file_path = realpath('.github/CODEOWNERS');
        } elseif (file_exists('docs/CODEOWNERS')) {
            $codeowners_file_path = realpath('docs/CODEOWNERS');
        } else {
            die('Cannot use --codeowner without a CODEOWNERS file' . PHP_EOL);
        }
        $codeowners_file = file_get_contents($codeowners_file_path);
        $codeowner_lines = array_map(static function (string $line) : array {
            $line_parts = preg_split('/\\s+/', $line);
            if ($line_parts === \false) {
                throw new AssertionError("An error occurred: " . preg_last_error_msg());
            }
            $file_selector = substr(array_shift($line_parts), 1);
            return [$file_selector, $line_parts];
        }, array_filter(explode("\n", $codeowners_file), static function (string $line) : bool {
            $line = trim($line);
            // currently we don’t match wildcard files or files that could appear anywhere
            // in the repo
            return $line && $line[0] === '/' && strpos($line, '*') === \false;
        }));
        $codeowner_files = [];
        foreach ($codeowner_lines as [$path, $owners]) {
            if (!file_exists($path)) {
                continue;
            }
            foreach ($owners as $i => $owner) {
                $owners[$i] = strtolower($owner);
            }
            if (!is_dir($path)) {
                if (pathinfo($path, PATHINFO_EXTENSION) === 'php') {
                    $codeowner_files[$path] = $owners;
                }
            } else {
                foreach ($providers->file_provider->getFilesInDir($path, ['php']) as $php_file_path) {
                    $codeowner_files[$php_file_path] = $owners;
                }
            }
        }
        if (!$codeowner_files) {
            die('Could not find any available entries in CODEOWNERS' . PHP_EOL);
        }
        return $codeowner_files;
    }
    /**
     * @param array<string, array<int, string>> $codeowner_files
     * @return list<string>
     */
    private static function loadCodeownersFiles(array $desired_codeowners, array $codeowner_files) : array
    {
        $paths_to_check = [];
        /** @psalm-suppress MixedAssignment */
        foreach ($desired_codeowners as $desired_codeowner) {
            if (!is_string($desired_codeowner)) {
                die('Invalid --codeowner ' . (string) $desired_codeowner . PHP_EOL);
            }
            if ($desired_codeowner[0] !== '@') {
                die('--codeowner option must start with @' . PHP_EOL);
            }
            $matched_file = \false;
            foreach ($codeowner_files as $file_path => $owners) {
                if (in_array(strtolower($desired_codeowner), $owners)) {
                    $paths_to_check[] = $file_path;
                    $matched_file = \true;
                }
            }
            if (!$matched_file) {
                die('User/group ' . $desired_codeowner . ' does not own any PHP files' . PHP_EOL);
            }
        }
        return $paths_to_check;
    }
}
<?php

namespace Psalm\Internal\Cli;

use Composer\Autoload\ClassLoader;
use Psalm\Config;
use Psalm\Config\Creator;
use Psalm\ErrorBaseline;
use Psalm\Exception\ConfigCreationException;
use Psalm\Exception\ConfigException;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\CliUtils;
use Psalm\Internal\Codebase\ReferenceMapGenerator;
use Psalm\Internal\Composer;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\Fork\Pool;
use Psalm\Internal\Fork\PsalmRestarter;
use Psalm\Internal\IncludeCollector;
use Psalm\Internal\Provider\ClassLikeStorageCacheProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceCacheProvider;
use Psalm\Internal\Provider\FileStorageCacheProvider;
use Psalm\Internal\Provider\ParserCacheProvider;
use Psalm\Internal\Provider\ProjectCacheProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\Internal\Stubs\Generator\StubsGenerator;
use Psalm\IssueBuffer;
use Psalm\Progress\DebugProgress;
use Psalm\Progress\DefaultProgress;
use Psalm\Progress\LongProgress;
use Psalm\Progress\Progress;
use Psalm\Progress\VoidProgress;
use Psalm\Report;
use Psalm\Report\ReportOptions;
use RuntimeException;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Path;
use function array_filter;
use function array_key_exists;
use function array_map;
use function array_merge;
use function array_slice;
use function array_sum;
use function array_values;
use function chdir;
use function count;
use function file_exists;
use function file_put_contents;
use function fwrite;
use function gc_collect_cycles;
use function gc_disable;
use function getcwd;
use function getenv;
use function getopt;
use function implode;
use function in_array;
use function ini_get;
use function ini_set;
use function is_array;
use function is_numeric;
use function is_scalar;
use function is_string;
use function json_encode;
use function max;
use function microtime;
use function parse_url;
use function preg_match;
use function preg_replace;
use function realpath;
use function setlocale;
use function str_repeat;
use function str_replace;
use function strlen;
use function strpos;
use function substr;
use function version_compare;
use const DIRECTORY_SEPARATOR;
use const JSON_THROW_ON_ERROR;
use const LC_CTYPE;
use const PHP_EOL;
use const PHP_OS;
use const PHP_URL_SCHEME;
use const PHP_VERSION;
use const STDERR;
// phpcs:disable PSR1.Files.SideEffects
require_once __DIR__ . '/../ErrorHandler.php';
require_once __DIR__ . '/../CliUtils.php';
require_once __DIR__ . '/../Composer.php';
require_once __DIR__ . '/../IncludeCollector.php';
require_once __DIR__ . '/../../IssueBuffer.php';
/**
 * @internal
 */
final class Psalm
{
    private const SHORT_OPTIONS = ['f:', 'm', 'h', 'v', 'c:', 'i', 'r:'];
    private const LONG_OPTIONS = [
        'clear-cache',
        'clear-global-cache',
        'config:',
        'debug',
        'debug-by-line',
        'debug-performance',
        'debug-emitted-issues',
        'diff',
        'disable-extension:',
        'find-dead-code::',
        'find-unused-code::',
        'find-unused-variables',
        'find-references-to:',
        'help',
        'ignore-baseline',
        'init',
        'memory-limit:',
        'monochrome',
        'no-diff',
        'no-cache',
        'no-reflection-cache',
        'no-file-cache',
        'output-format:',
        'plugin:',
        'report:',
        'report-show-info:',
        'root:',
        'set-baseline:',
        'show-info:',
        'show-snippet:',
        'stats',
        'threads:',
        'update-baseline',
        'use-baseline:',
        'use-ini-defaults',
        'version',
        'php-version:',
        'generate-json-map:',
        'generate-stubs:',
        'alter',
        'language-server',
        'refactor',
        'shepherd::',
        'no-progress',
        'long-progress',
        'no-suggestions',
        'include-php-versions',
        // used for baseline
        'pretty-print',
        // used for JSON reports
        'track-tainted-input',
        'taint-analysis',
        'security-analysis',
        'dump-taint-graph:',
        'find-unused-psalm-suppress',
        'error-level:',
    ];
    /**
     * @param array<int,string> $argv
     */
    public static function run(array $argv) : void
    {
        CliUtils::checkRuntimeRequirements();
        gc_collect_cycles();
        gc_disable();
        ErrorHandler::install($argv);
        $args = array_slice($argv, 1);
        // get options from command line
        $options = getopt(implode('', self::SHORT_OPTIONS), self::LONG_OPTIONS);
        if (\false === $options) {
            throw new RuntimeException('Failed to parse CLI options');
        }
        self::forwardCliCall($options, $argv);
        self::validateCliArguments($args);
        self::setMemoryLimit($options);
        self::syncShortOptions($options);
        if (isset($options['c']) && is_array($options['c'])) {
            fwrite(STDERR, 'Too many config files provided' . PHP_EOL);
            exit(1);
        }
        if (array_key_exists('h', $options)) {
            echo self::getHelpText();
            /*
            --shepherd[=endpoint]
                Send analysis statistics to Shepherd server.
                `endpoint` is the URL to the Shepherd server. It defaults to shepherd.dev
            */
            exit;
        }
        $current_dir = self::getCurrentDir($options);
        $path_to_config = CliUtils::getPathToConfig($options);
        $vendor_dir = CliUtils::getVendorDir($current_dir);
        // capture environment before registering autoloader (it may destroy it)
        IssueBuffer::captureServer($_SERVER);
        $include_collector = new IncludeCollector();
        $first_autoloader = $include_collector->runAndCollect(
            // we ignore the FQN because of a hack in scoper.inc that needs full path
            // phpcs:ignore SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName
            static fn(): ?\Composer\Autoload\ClassLoader => CliUtils::requireAutoloaders($current_dir, isset($options['r']), $vendor_dir)
        );
        $run_taint_analysis = self::shouldRunTaintAnalysis($options);
        if (array_key_exists('v', $options)) {
            echo 'Psalm ' . \PSALM_VERSION . PHP_EOL;
            exit;
        }
        $output_format = self::initOutputFormat($options);
        [$config, $init_source_dir] = self::initConfig($current_dir, $args, $vendor_dir, $first_autoloader, $path_to_config, $output_format, $run_taint_analysis, $options);
        if (isset($options['no-cache'])) {
            $config->cache_directory = null;
        }
        $config->setIncludeCollector($include_collector);
        $in_ci = CliUtils::runningInCI();
        // disable progressbar on CI
        if ($in_ci) {
            $options['long-progress'] = \true;
        }
        $threads = self::detectThreads($options, $config, $in_ci);
        self::emitMacPcreWarning($options, $threads);
        self::restart($options, $threads);
        if (isset($options['debug-emitted-issues'])) {
            $config->debug_emitted_issues = \true;
        }
        setlocale(LC_CTYPE, 'C');
        if (isset($options['set-baseline'])) {
            if (is_array($options['set-baseline'])) {
                die('Only one baseline file can be created at a time' . PHP_EOL);
            }
        }
        $paths_to_check = CliUtils::getPathsToCheck($options['f'] ?? null);
        if ($config->resolve_from_config_file) {
            $current_dir = $config->base_dir;
            chdir($current_dir);
        }
        /** @var list<string> $plugins List of paths to plugin files */
        $plugins = [];
        if (isset($options['plugin'])) {
            $plugins_from_options = $options['plugin'];
            if (is_array($plugins_from_options)) {
                $plugins = $plugins_from_options;
            } elseif (is_string($plugins_from_options)) {
                $plugins = [$plugins_from_options];
            }
        }
        $show_info = self::initShowInfo($options);
        $is_diff = self::initIsDiff($options);
        $find_unused_code = self::shouldFindUnusedCode($options, $config);
        $find_unused_variables = isset($options['find-unused-variables']);
        $find_references_to = isset($options['find-references-to']) && is_string($options['find-references-to']) ? $options['find-references-to'] : null;
        self::configureShepherd($config, $options, $plugins);
        if (isset($options['clear-cache'])) {
            self::clearCache($config);
        }
        if (isset($options['clear-global-cache'])) {
            self::clearGlobalCache($config);
        }
        $progress = self::initProgress($options, $config);
        $providers = self::initProviders($options, $config, $current_dir);
        $stdout_report_options = self::initStdoutReportOptions($options, $show_info, $output_format, $in_ci);
        /** @var list<string>|string $report_file_paths type guaranteed by argument to getopt() */
        $report_file_paths = $options['report'] ?? [];
        if (is_string($report_file_paths)) {
            $report_file_paths = [$report_file_paths];
        }
        $project_analyzer = new ProjectAnalyzer($config, $providers, $stdout_report_options, ProjectAnalyzer::getFileReportOptions($report_file_paths, isset($options['report-show-info']) ? $options['report-show-info'] !== 'false' && $options['report-show-info'] !== '0' : \true), $threads, $progress);
        CliUtils::initPhpVersion($options, $config, $project_analyzer);
        $start_time = microtime(\true);
        self::configureProjectAnalyzer($options, $config, $project_analyzer, $find_references_to, $find_unused_code, $find_unused_variables, $run_taint_analysis);
        if ($config->run_taint_analysis || $run_taint_analysis) {
            $is_diff = \false;
        }
        /** @var string $plugin_path */
        foreach ($plugins as $plugin_path) {
            $config->addPluginPath($plugin_path);
        }
        if ($paths_to_check === null) {
            $project_analyzer->check($current_dir, $is_diff);
        } elseif ($paths_to_check) {
            $project_analyzer->checkPaths($paths_to_check);
        }
        if ($find_references_to) {
            $project_analyzer->findReferencesTo($find_references_to);
        }
        self::storeFlowGraph($options, $project_analyzer);
        if (isset($options['generate-json-map']) && is_string($options['generate-json-map'])) {
            self::storeTypeMap($providers, $config, $options['generate-json-map']);
        }
        if (isset($options['generate-stubs'])) {
            self::generateStubs($options, $providers, $project_analyzer);
        }
        if (!isset($options['i'])) {
            IssueBuffer::finish($project_analyzer, !$paths_to_check, $start_time, isset($options['stats']), self::initBaseline($options, $config, $current_dir, $path_to_config));
        } else {
            self::autoGenerateConfig($project_analyzer, $current_dir, $init_source_dir, $vendor_dir);
        }
    }
    private static function initOutputFormat(array $options) : string
    {
        return isset($options['output-format']) && is_string($options['output-format']) ? $options['output-format'] : Report::TYPE_CONSOLE;
    }
    private static function initShowInfo(array $options) : bool
    {
        return isset($options['show-info']) ? $options['show-info'] === 'true' || $options['show-info'] === '1' : \false;
    }
    private static function initIsDiff(array $options) : bool
    {
        return !isset($options['no-diff']) && !isset($options['set-baseline']) && !isset($options['update-baseline']);
    }
    /**
     * @param array<int,string> $args
     */
    private static function validateCliArguments(array $args) : void
    {
        array_map(static function (string $arg) : void {
            if (strpos($arg, '--') === 0 && $arg !== '--') {
                $arg_name = preg_replace('/=.*$/', '', substr($arg, 2), 1);
                if (!in_array($arg_name, self::LONG_OPTIONS) && !in_array($arg_name . ':', self::LONG_OPTIONS) && !in_array($arg_name . '::', self::LONG_OPTIONS)) {
                    fwrite(STDERR, 'Unrecognised argument "--' . $arg_name . '"' . PHP_EOL . 'Type --help to see a list of supported arguments' . PHP_EOL);
                    exit(1);
                }
            } elseif (strpos($arg, '-') === 0 && $arg !== '-' && $arg !== '--') {
                $arg_name = preg_replace('/=.*$/', '', substr($arg, 1));
                if (!in_array($arg_name, self::SHORT_OPTIONS) && !in_array($arg_name . ':', self::SHORT_OPTIONS)) {
                    fwrite(STDERR, 'Unrecognised argument "-' . $arg_name . '"' . PHP_EOL . 'Type --help to see a list of supported arguments' . PHP_EOL);
                    exit(1);
                }
            }
        }, $args);
    }
    /**
     * @param array<string,string|false|list<mixed>> $options
     */
    private static function setMemoryLimit(array $options) : void
    {
        if (!array_key_exists('use-ini-defaults', $options)) {
            ini_set('display_errors', 'stderr');
            ini_set('display_startup_errors', '1');
            $memoryLimit = 8 * 1024 * 1024 * 1024;
            if (array_key_exists('memory-limit', $options)) {
                $memoryLimit = $options['memory-limit'];
                if (!is_scalar($memoryLimit)) {
                    throw new ConfigException('Invalid memory limit specified.');
                }
            }
            ini_set('memory_limit', (string) $memoryLimit);
        }
    }
    /**
     * @param array<int, string> $args
     */
    private static function generateConfig(string $current_dir, array &$args) : void
    {
        if (file_exists($current_dir . 'psalm.xml')) {
            die('A config file already exists in the current directory' . PHP_EOL);
        }
        $args = array_values(array_filter($args, static fn(string $arg): bool => $arg !== '--ansi' && $arg !== '--no-ansi' && $arg !== '-i' && $arg !== '--init' && $arg !== '--debug' && $arg !== '--debug-by-line' && $arg !== '--debug-emitted-issues' && strpos($arg, '--disable-extension=') !== 0 && strpos($arg, '--root=') !== 0 && strpos($arg, '--r=') !== 0));
        $init_level = null;
        $init_source_dir = null;
        if (count($args)) {
            if (count($args) > 2) {
                die('Too many arguments provided for psalm --init' . PHP_EOL);
            }
            if (isset($args[1])) {
                if (!preg_match('/^[1-8]$/', $args[1])) {
                    die('Config strictness must be a number between 1 and 8 inclusive' . PHP_EOL);
                }
                $init_level = (int) $args[1];
            }
            $init_source_dir = $args[0];
        }
        $vendor_dir = CliUtils::getVendorDir($current_dir);
        if (null !== $init_level) {
            try {
                $template_contents = Creator::getContents($current_dir, $init_source_dir, $init_level, $vendor_dir);
            } catch (ConfigCreationException $e) {
                die($e->getMessage() . PHP_EOL);
            }
            if (!file_put_contents($current_dir . 'psalm.xml', $template_contents)) {
                die('Could not write to psalm.xml' . PHP_EOL);
            }
            exit('Config file created successfully. Please re-run psalm.' . PHP_EOL);
        }
    }
    private static function loadConfig(?string $path_to_config, string $current_dir, string $output_format, ?ClassLoader $first_autoloader, bool $run_taint_analysis, array $options) : Config
    {
        $config = CliUtils::initializeConfig($path_to_config, $current_dir, $output_format, $first_autoloader, $run_taint_analysis);
        if (isset($options['error-level']) && is_numeric($options['error-level'])) {
            $config_level = (int) $options['error-level'];
            if (!in_array($config_level, [1, 2, 3, 4, 5, 6, 7, 8], \true)) {
                throw new ConfigException('Invalid error level ' . $config_level);
            }
            $config->level = $config_level;
        }
        return $config;
    }
    private static function initProgress(array $options, Config $config) : Progress
    {
        $debug = array_key_exists('debug', $options) || array_key_exists('debug-by-line', $options);
        $show_info = isset($options['show-info']) ? $options['show-info'] === 'true' || $options['show-info'] === '1' : \false;
        if ($debug) {
            $progress = new DebugProgress();
        } elseif (isset($options['no-progress'])) {
            $progress = new VoidProgress();
        } else {
            $show_errors = !$config->error_baseline || isset($options['ignore-baseline']);
            if (isset($options['long-progress'])) {
                $progress = new LongProgress($show_errors, $show_info);
            } else {
                $progress = new DefaultProgress($show_errors, $show_info);
            }
        }
        // output buffered warnings
        foreach ($config->config_warnings as $warning) {
            $progress->warning($warning);
        }
        return $progress;
    }
    private static function initProviders(array $options, Config $config, string $current_dir) : Providers
    {
        if (isset($options['no-cache']) || isset($options['i'])) {
            $providers = new Providers(new FileProvider());
        } else {
            $no_reflection_cache = isset($options['no-reflection-cache']);
            $no_file_cache = isset($options['no-file-cache']);
            $file_storage_cache_provider = $no_reflection_cache ? null : new FileStorageCacheProvider($config);
            $classlike_storage_cache_provider = $no_reflection_cache ? null : new ClassLikeStorageCacheProvider($config);
            $providers = new Providers(new FileProvider(), new ParserCacheProvider($config, !$no_file_cache), $file_storage_cache_provider, $classlike_storage_cache_provider, new FileReferenceCacheProvider($config), new ProjectCacheProvider(Composer::getLockFilePath($current_dir)));
        }
        return $providers;
    }
    /**
     * @param array{"set-baseline": string, ...} $options
     * @return array<string,array<string,array{o:int, s: list<string>}>>
     */
    private static function generateBaseline(array $options, Config $config, string $current_dir, ?string $path_to_config) : array
    {
        fwrite(STDERR, 'Writing error baseline to file...' . PHP_EOL);
        try {
            $issue_baseline = ErrorBaseline::read(new FileProvider(), $options['set-baseline']);
        } catch (ConfigException $e) {
            $issue_baseline = [];
        }
        ErrorBaseline::create(new FileProvider(), $options['set-baseline'], IssueBuffer::getIssuesData(), $config->include_php_versions_in_error_baseline || isset($options['include-php-versions']));
        fwrite(STDERR, "Baseline saved to {$options['set-baseline']}.");
        CliUtils::updateConfigFile($config, $path_to_config ?? $current_dir, $options['set-baseline']);
        fwrite(STDERR, PHP_EOL);
        return $issue_baseline;
    }
    /**
     * @return array<string,array<string,array{o:int, s: list<string>}>>
     */
    private static function updateBaseline(array $options, Config $config) : array
    {
        $baselineFile = $config->error_baseline;
        if (empty($baselineFile)) {
            die('Cannot update baseline, because no baseline file is configured.' . PHP_EOL);
        }
        try {
            $issue_current_baseline = ErrorBaseline::read(new FileProvider(), $baselineFile);
            $total_issues_current_baseline = ErrorBaseline::countTotalIssues($issue_current_baseline);
            $issue_baseline = ErrorBaseline::update(new FileProvider(), $baselineFile, IssueBuffer::getIssuesData(), $config->include_php_versions_in_error_baseline || isset($options['include-php-versions']));
            $total_issues_updated_baseline = ErrorBaseline::countTotalIssues($issue_baseline);
            $total_fixed_issues = $total_issues_current_baseline - $total_issues_updated_baseline;
            if ($total_fixed_issues > 0) {
                echo str_repeat('-', 30) . "\n";
                echo $total_fixed_issues . ' errors fixed' . "\n";
            }
        } catch (ConfigException $exception) {
            fwrite(STDERR, 'Could not update baseline file: ' . $exception->getMessage() . PHP_EOL);
            exit(1);
        }
        return $issue_baseline;
    }
    private static function storeTypeMap(Providers $providers, Config $config, string $type_map_location) : void
    {
        $file_map = $providers->file_reference_provider->getFileMaps();
        $name_file_map = [];
        $expected_references = [];
        foreach ($file_map as $file_path => $map) {
            $file_name = $config->shortenFileName($file_path);
            foreach ($map[0] as $map_parts) {
                $expected_references[$map_parts[1]] = \true;
            }
            $map[2] = [];
            $name_file_map[$file_name] = $map;
        }
        $reference_dictionary = ReferenceMapGenerator::getReferenceMap($providers->classlike_storage_provider, $expected_references);
        $type_map_string = json_encode(['files' => $name_file_map, 'references' => $reference_dictionary], JSON_THROW_ON_ERROR);
        $providers->file_provider->setContents($type_map_location, $type_map_string);
    }
    private static function autoGenerateConfig(ProjectAnalyzer $project_analyzer, string $current_dir, ?string $init_source_dir, string $vendor_dir) : void
    {
        $issues_by_file = IssueBuffer::getIssuesData();
        if (!$issues_by_file) {
            $init_level = 1;
        } else {
            $codebase = $project_analyzer->getCodebase();
            $mixed_counts = $codebase->analyzer->getTotalTypeCoverage($codebase);
            $init_level = Creator::getLevel(array_merge(...array_values($issues_by_file)), array_sum($mixed_counts));
        }
        echo "\n" . 'Detected level ' . $init_level . ' as a suitable initial default' . "\n";
        try {
            $template_contents = Creator::getContents($current_dir, $init_source_dir, $init_level, $vendor_dir);
        } catch (ConfigCreationException $e) {
            die($e->getMessage() . PHP_EOL);
        }
        if (!file_put_contents($current_dir . 'psalm.xml', $template_contents)) {
            die('Could not write to psalm.xml' . PHP_EOL);
        }
        exit('Config file created successfully. Please re-run psalm.' . PHP_EOL);
    }
    private static function initStdoutReportOptions(array $options, bool $show_info, string $output_format, bool $in_ci) : ReportOptions
    {
        $stdout_report_options = new ReportOptions();
        $stdout_report_options->use_color = !array_key_exists('m', $options);
        $stdout_report_options->show_info = $show_info;
        $stdout_report_options->show_suggestions = !array_key_exists('no-suggestions', $options);
        /**
         * @psalm-suppress PropertyTypeCoercion
         */
        $stdout_report_options->format = $output_format;
        $stdout_report_options->show_snippet = !isset($options['show-snippet']) || $options['show-snippet'] !== "false";
        $stdout_report_options->pretty = isset($options['pretty-print']) && $options['pretty-print'] !== "false";
        $stdout_report_options->in_ci = $in_ci;
        return $stdout_report_options;
    }
    /** @return never */
    private static function clearGlobalCache(Config $config) : void
    {
        $cache_directory = $config->getGlobalCacheDirectory();
        if ($cache_directory) {
            Config::removeCacheDirectory($cache_directory);
            echo 'Global cache directory deleted' . PHP_EOL;
        }
        exit;
    }
    /** @return never */
    private static function clearCache(Config $config) : void
    {
        $cache_directory = $config->getCacheDirectory();
        if ($cache_directory !== null) {
            Config::removeCacheDirectory($cache_directory);
        }
        echo 'Cache directory deleted' . PHP_EOL;
        exit;
    }
    private static function getCurrentDir(array $options) : string
    {
        $cwd = getcwd();
        if (\false === $cwd) {
            fwrite(STDERR, 'Cannot get current working directory' . PHP_EOL);
            exit(1);
        }
        $current_dir = $cwd . DIRECTORY_SEPARATOR;
        if (isset($options['r']) && is_string($options['r'])) {
            $root_path = realpath($options['r']);
            if (!$root_path) {
                fwrite(STDERR, 'Could not locate root directory ' . $current_dir . DIRECTORY_SEPARATOR . $options['r'] . PHP_EOL);
                exit(1);
            }
            $current_dir = $root_path . DIRECTORY_SEPARATOR;
        }
        return $current_dir;
    }
    private static function emitMacPcreWarning(array $options, int $threads) : void
    {
        if (!isset($options['threads']) && !isset($options['debug']) && $threads === 1 && ini_get('pcre.jit') === '1' && PHP_OS === 'Darwin' && version_compare(PHP_VERSION, '7.3.0') >= 0 && version_compare(PHP_VERSION, '7.4.0') < 0) {
            echo 'If you want to run Psalm as a language server, or run Psalm with' . PHP_EOL . 'multiple processes (--threads=4), beware:' . PHP_EOL . Pool::MAC_PCRE_MESSAGE . PHP_EOL . PHP_EOL;
        }
    }
    private static function restart(array $options, int $threads) : void
    {
        $ini_handler = new PsalmRestarter('PSALM');
        if (isset($options['disable-extension'])) {
            if (is_array($options['disable-extension'])) {
                /** @psalm-suppress MixedAssignment */
                foreach ($options['disable-extension'] as $extension) {
                    if (is_string($extension)) {
                        $ini_handler->disableExtension($extension);
                    }
                }
            } elseif (is_string($options['disable-extension'])) {
                $ini_handler->disableExtension($options['disable-extension']);
            }
        }
        if ($threads > 1) {
            $ini_handler->disableExtension('grpc');
        }
        $ini_handler->disableExtension('uopz');
        // If Xdebug is enabled, restart without it
        $ini_handler->check();
    }
    private static function detectThreads(array $options, Config $config, bool $in_ci) : int
    {
        if (isset($options['threads'])) {
            $threads = (int) $options['threads'];
        } elseif (isset($options['debug']) || $in_ci) {
            $threads = 1;
        } elseif ($config->threads) {
            $threads = $config->threads;
        } else {
            $threads = max(1, ProjectAnalyzer::getCpuCount() - 1);
        }
        return $threads;
    }
    /** @psalm-suppress UnusedParam $argv is being reported as unused */
    private static function forwardCliCall(array $options, array $argv) : void
    {
        if (isset($options['alter'])) {
            require_once __DIR__ . '/Psalter.php';
            \Psalm\Internal\Cli\Psalter::run($argv);
            exit;
        }
        if (isset($options['language-server'])) {
            require_once __DIR__ . '/LanguageServer.php';
            \Psalm\Internal\Cli\LanguageServer::run($argv);
            exit;
        }
        if (isset($options['refactor'])) {
            require_once __DIR__ . '/Refactor.php';
            \Psalm\Internal\Cli\Refactor::run($argv);
            exit;
        }
    }
    /**
     * @param array<string, false|list<mixed>|string> $options
     * @param-out array<string, false|list<mixed>|string> $options
     */
    private static function syncShortOptions(array &$options) : void
    {
        if (array_key_exists('help', $options)) {
            $options['h'] = \false;
        }
        if (array_key_exists('version', $options)) {
            $options['v'] = \false;
        }
        if (array_key_exists('init', $options)) {
            $options['i'] = \false;
        }
        if (array_key_exists('monochrome', $options)) {
            $options['m'] = \false;
        }
        if (isset($options['config'])) {
            $options['c'] = $options['config'];
        }
        if (isset($options['root'])) {
            $options['r'] = $options['root'];
        }
    }
    /**
     * @param array<int, string> $args
     * @return array{Config,?string}
     */
    private static function initConfig(string $current_dir, array $args, string $vendor_dir, ?ClassLoader $first_autoloader, ?string $path_to_config, string $output_format, bool $run_taint_analysis, array $options) : array
    {
        $init_source_dir = null;
        if (isset($options['i'])) {
            self::generateConfig($current_dir, $args);
            // if we ever got here, it means we need to run Psalm once and generate the config
            // based on the errors we find
            $init_source_dir = $args[0] ?? null;
            echo "Calculating best config level based on project files\n";
            Creator::createBareConfig($current_dir, $init_source_dir, $vendor_dir);
            $config = Config::getInstance();
            $config->setComposerClassLoader($first_autoloader);
        } else {
            $config = self::loadConfig($path_to_config, $current_dir, $output_format, $first_autoloader, $run_taint_analysis, $options);
        }
        return [$config, $init_source_dir];
    }
    /**
     * @return array<string,array<string,array{o:int, s: list<string>}>>
     */
    private static function initBaseline(array $options, Config $config, string $current_dir, ?string $path_to_config) : array
    {
        $issue_baseline = [];
        if (isset($options['set-baseline']) && is_string($options['set-baseline'])) {
            $issue_baseline = self::generateBaseline($options, $config, $current_dir, $path_to_config);
        }
        if (isset($options['use-baseline'])) {
            if (!is_string($options['use-baseline'])) {
                fwrite(STDERR, '--use-baseline must be a string' . PHP_EOL);
                exit(1);
            }
            $baseline_file_path = $options['use-baseline'];
            $config->error_baseline = $baseline_file_path;
        } else {
            $baseline_file_path = $config->error_baseline;
        }
        if (isset($options['update-baseline'])) {
            $issue_baseline = self::updateBaseline($options, $config);
        }
        if (!$issue_baseline && $baseline_file_path && !isset($options['ignore-baseline'])) {
            try {
                $issue_baseline = ErrorBaseline::read(new FileProvider(), $baseline_file_path);
            } catch (ConfigException $exception) {
                fwrite(STDERR, 'Error while reading baseline: ' . $exception->getMessage() . PHP_EOL);
                exit(1);
            }
        }
        return $issue_baseline;
    }
    private static function storeFlowGraph(array $options, ProjectAnalyzer $project_analyzer) : void
    {
        /** @var string|null $dump_taint_graph */
        $dump_taint_graph = $options['dump-taint-graph'] ?? null;
        $flow_graph = $project_analyzer->getCodebase()->taint_flow_graph;
        if ($flow_graph !== null && $dump_taint_graph !== null) {
            file_put_contents($dump_taint_graph, "digraph Taints {\n\t" . implode("\n\t", array_map(static fn(array $edges) => '"' . implode('" -> "', $edges) . '"', $flow_graph->summarizeEdges())) . "\n}\n");
        }
    }
    /** @return false|'always'|'auto' */
    private static function shouldFindUnusedCode(array $options, Config $config)
    {
        $find_unused_code = \false;
        if (isset($options['find-dead-code'])) {
            $options['find-unused-code'] = $options['find-dead-code'] === 'always' ? 'always' : 'auto';
        }
        if (isset($options['find-unused-code'])) {
            if ($options['find-unused-code'] === 'always') {
                $find_unused_code = 'always';
            } else {
                $find_unused_code = 'auto';
            }
        }
        if ($config->find_unused_code) {
            $find_unused_code = 'auto';
        }
        return $find_unused_code;
    }
    private static function shouldRunTaintAnalysis(array $options) : bool
    {
        return isset($options['track-tainted-input']) || isset($options['security-analysis']) || isset($options['taint-analysis']);
    }
    /**
     * @param string|bool|null $find_references_to
     * @param false|'always'|'auto' $find_unused_code
     */
    private static function configureProjectAnalyzer(array $options, Config $config, ProjectAnalyzer $project_analyzer, $find_references_to, $find_unused_code, bool $find_unused_variables, bool $run_taint_analysis) : void
    {
        if (isset($options['generate-json-map']) && is_string($options['generate-json-map'])) {
            $project_analyzer->getCodebase()->store_node_types = \true;
        }
        if (array_key_exists('debug-by-line', $options)) {
            $project_analyzer->debug_lines = \true;
        }
        if (array_key_exists('debug-performance', $options)) {
            $project_analyzer->debug_performance = \true;
        }
        if ($find_references_to !== null) {
            $project_analyzer->getCodebase()->collectLocations();
            $project_analyzer->show_issues = \false;
        }
        if ($find_unused_code) {
            $project_analyzer->getCodebase()->reportUnusedCode($find_unused_code);
        }
        if ($config->find_unused_variables || $find_unused_variables) {
            $project_analyzer->getCodebase()->reportUnusedVariables();
        }
        if ($config->run_taint_analysis || $run_taint_analysis) {
            $project_analyzer->trackTaintedInputs();
        }
        if ($config->find_unused_psalm_suppress || isset($options['find-unused-psalm-suppress'])) {
            $project_analyzer->trackUnusedSuppressions();
        }
    }
    private static function configureShepherd(Config $config, array $options, array &$plugins) : void
    {
        if (is_string(getenv('PSALM_SHEPHERD_HOST'))) {
            // remove this block in Psalm 6
            fwrite(STDERR, 'PSALM_SHEPHERD_HOST env variable is deprecated and will be removed in Psalm 6.' . ' Please use "--shepherd" cli option or PSALM_SHEPHERD env variable' . ' to specify a custom Shepherd host/endpoint.' . PHP_EOL);
        }
        $is_shepherd_enabled = isset($options['shepherd']) || getenv('PSALM_SHEPHERD');
        if (!$is_shepherd_enabled) {
            return;
        }
        $plugins[] = Path::canonicalize(__DIR__ . '/../../Plugin/Shepherd.php');
        /** @psalm-suppress MixedAssignment */
        $custom_shepherd_endpoint = $options['shepherd'] ?? getenv('PSALM_SHEPHERD');
        if (is_string($custom_shepherd_endpoint) && strlen($custom_shepherd_endpoint) > 2) {
            if (parse_url($custom_shepherd_endpoint, PHP_URL_SCHEME) === null) {
                $custom_shepherd_endpoint = 'https://' . $custom_shepherd_endpoint;
            }
            /** @psalm-suppress DeprecatedProperty */
            $config->shepherd_host = str_replace('/hooks/psalm', '', $custom_shepherd_endpoint);
            $config->shepherd_endpoint = $custom_shepherd_endpoint;
            return;
        }
        // Legacy part, will be removed in Psalm 6
        $custom_shepherd_host = getenv('PSALM_SHEPHERD_HOST');
        if (is_string($custom_shepherd_host)) {
            if (parse_url($custom_shepherd_host, PHP_URL_SCHEME) === null) {
                $custom_shepherd_host = 'https://' . $custom_shepherd_host;
            }
            /** @psalm-suppress DeprecatedProperty */
            $config->shepherd_host = $custom_shepherd_host;
            $config->shepherd_endpoint = $custom_shepherd_host . '/hooks/psalm';
        }
    }
    private static function generateStubs(array $options, Providers $providers, ProjectAnalyzer $project_analyzer) : void
    {
        if (isset($options['generate-stubs']) && is_string($options['generate-stubs'])) {
            $stubs_location = $options['generate-stubs'];
            $providers->file_provider->setContents($stubs_location, StubsGenerator::getAll($project_analyzer->getCodebase(), $providers->classlike_storage_provider, $providers->file_storage_provider));
        }
    }
    /**
     * @psalm-pure
     */
    private static function getHelpText() : string
    {
        return <<<HELP
Usage:
    psalm [options] [file...]

Basic configuration:
    -c, --config=psalm.xml
        Path to a psalm.xml configuration file. Run psalm --init to create one.

    --use-ini-defaults
        Use PHP-provided ini defaults for memory and error display

    --memory-limit=LIMIT
        Use a specific memory limit. Cannot be combined with --use-ini-defaults

    --disable-extension=[extension]
        Used to disable certain extensions while Psalm is running.

    --threads=INT
        If greater than one, Psalm will run analysis on multiple threads, speeding things up.

    --no-diff
        Turns off Psalm’s diff mode, checks all files regardless of whether they’ve changed.

    --php-version=PHP_VERSION
        Explicitly set PHP version to analyse code against.

Surfacing issues:
    --show-info[=BOOLEAN]
        Show non-exception parser findings (defaults to false).

    --show-snippet[=true]
        Show code snippets with errors. Options are 'true' or 'false'

    --find-dead-code[=auto]
    --find-unused-code[=auto]
        Look for unused code. Options are 'auto' or 'always'. If no value is specified, default is 'auto'

    --find-unused-psalm-suppress
        Finds all @psalm-suppress annotations that aren’t used

    --find-references-to=[class|method|property]
        Searches the codebase for references to the given fully-qualified class or method,
        where method is in the format class::methodName

    --no-suggestions
        Hide suggestions

    --taint-analysis
        Run Psalm in taint analysis mode – see https://psalm.dev/docs/security_analysis for more info

    --dump-taint-graph=OUTPUT_PATH
        Output the taint graph using the DOT language – requires --taint-analysis

Issue baselines:
    --set-baseline=PATH
        Save all current error level issues to a file, to mark them as info in subsequent runs

        Add --include-php-versions to also include a list of PHP extension versions

    --use-baseline=PATH
        Allows you to use a baseline other than the default baseline provided in your config

    --ignore-baseline
        Ignore the error baseline

    --update-baseline
        Update the baseline by removing fixed issues. This will not add new issues to the baseline

        Add --include-php-versions to also include a list of PHP extension versions

Plugins:
    --plugin=PATH
        Executes a plugin, an alternative to using the Psalm config

Output:
    -m, --monochrome
        Enable monochrome output

    --output-format=console
        Changes the output format.
        Available formats: compact, console, text, emacs, json, pylint, xml, checkstyle, junit, sonarqube,
                           github, phpstorm, codeclimate, by-issue-level

    --no-progress
        Disable the progress indicator

    --long-progress
        Use a progress indicator suitable for Continuous Integration logs

    --stats
        Shows a breakdown of Psalm’s ability to infer types in the codebase

Reports:
    --report=PATH
        The path where to output report file. The output format is based on the file extension.
        (Currently supported formats: ".json", ".xml", ".txt", ".emacs", ".pylint", ".console",
        ".sarif", "checkstyle.xml", "sonarqube.json", "codeclimate.json", "summary.json", "junit.xml")

    --report-show-info[=BOOLEAN]
        Whether the report should include non-errors in its output (defaults to true)

Caching:
    --clear-cache
        Clears all cache files that Psalm uses for this specific project

    --clear-global-cache
        Clears all cache files that Psalm uses for all projects

    --no-cache
        Runs Psalm without using cache

    --no-reflection-cache
        Runs Psalm without using cached representations of unchanged classes and files.
        Useful if you want the afterClassLikeVisit plugin hook to run every time you visit a file.

    --no-file-cache
        Runs Psalm without using caching every single file for later diffing.
        This reduces the space Psalm uses on disk and file I/O.

Miscellaneous:
    -h, --help
        Display this help message

    -v, --version
        Display the Psalm version

    -i, --init [source_dir=src] [level=3]
        Create a psalm config file in the current directory that points to [source_dir]
        at the required level, from 1, most strict, to 8, most permissive.

    --debug
        Debug information

    --debug-by-line
        Debug information on a line-by-line level

    --debug-emitted-issues
        Print a php backtrace to stderr when emitting issues.

    -r, --root
        If running Psalm globally you’ll need to specify a project root. Defaults to cwd

    --generate-json-map=PATH
        Generate a map of node references and types in JSON format, saved to the given path.

    --generate-stubs=PATH
        Generate stubs for the project and dump the file in the given path

    --shepherd[=endpoint]
        Send analysis statistics to Shepherd (shepherd.dev) or your server.

    --alter
        Run Psalter

    --language-server
        Run Psalm Language Server

HELP;
    }
}
<?php

namespace Psalm\Internal\Scope;

use Psalm\Context;
use Psalm\Internal\Clause;
use Psalm\Storage\Assertion;
use Psalm\Type\Union;
/**
 * @internal
 */
class IfScope
{
    /**
     * @var array<string, Union>|null
     */
    public ?array $new_vars = null;
    /**
     * @var array<string, bool>
     */
    public array $new_vars_possibly_in_scope = [];
    /**
     * @var array<string, Union>|null
     */
    public ?array $redefined_vars = null;
    /**
     * @var array<string, int>|null
     */
    public ?array $assigned_var_ids = null;
    /**
     * @var array<string, bool>
     */
    public array $possibly_assigned_var_ids = [];
    /**
     * @var array<string, Union>
     */
    public array $possibly_redefined_vars = [];
    /**
     * @var array<string, bool>
     */
    public array $updated_vars = [];
    /**
     * @var array<string, list<array<int, Assertion>>>
     */
    public array $negated_types = [];
    /**
     * @var array<string, bool>
     */
    public array $if_cond_changed_var_ids = [];
    /**
     * @var array<string, string>|null
     */
    public ?array $negatable_if_types = null;
    /**
     * @var list<Clause>
     */
    public array $negated_clauses = [];
    /**
     * These are the set of clauses that could be applied after the `if`
     * statement, if the `if` statement contains branches with leaving statements,
     * and the else leaves too
     *
     * @var list<Clause>
     */
    public array $reasonable_clauses = [];
    /**
     * @var string[]
     */
    public array $if_actions = [];
    /**
     * @var string[]
     */
    public array $final_actions = [];
    public ?Context $post_leaving_if_context = null;
}
<?php

namespace Psalm\Internal\Scope;

use Psalm\Context;
use Psalm\Internal\Clause;
/**
 * @internal
 */
class IfConditionalScope
{
    public Context $if_context;
    public Context $post_if_context;
    /**
     * @var array<string, bool>
     */
    public array $cond_referenced_var_ids;
    /**
     * @var array<string, int>
     */
    public array $assigned_in_conditional_var_ids;
    /** @var list<Clause> */
    public array $entry_clauses;
    /**
     * @param array<string, bool>   $cond_referenced_var_ids
     * @param array<string, int>   $assigned_in_conditional_var_ids
     * @param list<Clause> $entry_clauses
     */
    public function __construct(Context $if_context, Context $post_if_context, array $cond_referenced_var_ids, array $assigned_in_conditional_var_ids, array $entry_clauses)
    {
        $this->if_context = $if_context;
        $this->post_if_context = $post_if_context;
        $this->cond_referenced_var_ids = $cond_referenced_var_ids;
        $this->assigned_in_conditional_var_ids = $assigned_in_conditional_var_ids;
        $this->entry_clauses = $entry_clauses;
    }
}
<?php

namespace Psalm\Internal\Scope;

use Psalm\Context;
use Psalm\Type\Union;
/**
 * @internal
 */
class CaseScope
{
    public Context $parent_context;
    /**
     * @var array<string, Union>|null
     */
    public ?array $break_vars = null;
    public function __construct(Context $parent_context)
    {
        $this->parent_context = $parent_context;
    }
    public function __destruct()
    {
        unset($this->parent_context);
    }
}
<?php

namespace Psalm\Internal\Scope;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\Clause;
use Psalm\Type\Union;
/**
 * @internal
 */
class SwitchScope
{
    /**
     * @var array<string, Union>|null
     */
    public ?array $new_vars_in_scope = null;
    /**
     * @var array<string, bool>
     */
    public array $new_vars_possibly_in_scope = [];
    /**
     * @var array<string, Union>|null
     */
    public ?array $redefined_vars = null;
    /**
     * @var array<string, Union>|null
     */
    public ?array $possibly_redefined_vars = null;
    /**
     * @var array<PhpParser\Node\Stmt>
     */
    public array $leftover_statements = [];
    public ?PhpParser\Node\Expr $leftover_case_equality_expr = null;
    /**
     * @var list<Clause>
     */
    public array $negated_clauses = [];
    /**
     * @var array<string, bool>|null
     */
    public ?array $new_assigned_var_ids = null;
}
<?php

namespace Psalm\Internal\Scope;

use Psalm\Context;
use Psalm\Type\Union;
/**
 * @internal
 */
class LoopScope
{
    public int $iteration_count = 0;
    public Context $loop_context;
    public Context $loop_parent_context;
    /**
     * @var array<string, Union>
     */
    public array $redefined_loop_vars = [];
    /**
     * @var array<string, Union>
     */
    public array $possibly_redefined_loop_vars = [];
    /**
     * @var array<string, Union>
     */
    public array $possibly_redefined_loop_parent_vars = [];
    /**
     * @var array<string, Union>
     */
    public array $possibly_defined_loop_parent_vars = [];
    /**
     * @var array<string, bool>
     */
    public array $vars_possibly_in_scope = [];
    /**
     * @var array<string, bool>
     */
    public array $protected_var_ids = [];
    /**
     * @var string[]
     */
    public array $final_actions = [];
    public function __construct(Context $loop_context, Context $parent_context)
    {
        $this->loop_context = $loop_context;
        $this->loop_parent_context = $parent_context;
    }
    public function __destruct()
    {
        unset($this->loop_context);
        unset($this->loop_parent_context);
    }
}
<?php

namespace Psalm\Internal\Scope;

use Psalm\Type\Union;
/**
 * @internal
 */
class FinallyScope
{
    /**
     * @var array<string, Union>
     */
    public array $vars_in_scope = [];
    /**
     * @param array<string, Union> $vars_in_scope
     */
    public function __construct(array $vars_in_scope)
    {
        $this->vars_in_scope = $vars_in_scope;
    }
}
<?php

namespace Psalm\Internal;

use Composer\Autoload\ClassLoader;
use JsonException;
use Phar;
use Psalm\Config;
use Psalm\Config\Creator;
use Psalm\Exception\ConfigException;
use Psalm\Exception\ConfigNotFoundException;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Report;
use RuntimeException;
use function array_filter;
use function array_slice;
use function assert;
use function count;
use function define;
use function dirname;
use function extension_loaded;
use function fgets;
use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function fwrite;
use function implode;
use function in_array;
use function ini_get;
use function is_array;
use function is_dir;
use function is_string;
use function json_decode;
use function preg_last_error_msg;
use function preg_match;
use function preg_replace;
use function preg_split;
use function realpath;
use function stream_get_meta_data;
use function stream_set_blocking;
use function strlen;
use function strpos;
use function strtoupper;
use function substr;
use function substr_replace;
use function trim;
use const DIRECTORY_SEPARATOR;
use const JSON_THROW_ON_ERROR;
use const PHP_EOL;
use const PHP_VERSION;
use const PHP_VERSION_ID;
use const STDERR;
use const STDIN;
/**
 * @internal
 */
final class CliUtils
{
    public static function requireAutoloaders(string $current_dir, bool $has_explicit_root, string $vendor_dir) : ?ClassLoader
    {
        $autoload_roots = [$current_dir];
        $psalm_dir = dirname(__DIR__, 3);
        $in_phar = Phar::running() || strpos(__NAMESPACE__, 'HumbugBox');
        if ($in_phar) {
            require_once __DIR__ . '/../../../vendor/autoload.php';
            // hack required for JsonMapper
            require_once __DIR__ . '/../../../vendor/netresearch/jsonmapper/src/JsonMapper.php';
            require_once __DIR__ . '/../../../vendor/netresearch/jsonmapper/src/JsonMapper/Exception.php';
        }
        if (!$in_phar && realpath($psalm_dir) !== realpath($current_dir)) {
            $autoload_roots[] = $psalm_dir;
        }
        $autoload_files = [];
        foreach ($autoload_roots as $autoload_root) {
            $has_autoloader = \false;
            $nested_autoload_file = dirname($autoload_root, 2) . DIRECTORY_SEPARATOR . 'autoload.php';
            // note: don't realpath $nested_autoload_file, or phar version will fail
            if (file_exists($nested_autoload_file)) {
                if (!in_array($nested_autoload_file, $autoload_files, \false)) {
                    $autoload_files[] = $nested_autoload_file;
                }
                $has_autoloader = \true;
            }
            $vendor_autoload_file = $autoload_root . DIRECTORY_SEPARATOR . $vendor_dir . DIRECTORY_SEPARATOR . 'autoload.php';
            // note: don't realpath $vendor_autoload_file, or phar version will fail
            if (file_exists($vendor_autoload_file)) {
                if (!in_array($vendor_autoload_file, $autoload_files, \false)) {
                    $autoload_files[] = $vendor_autoload_file;
                }
                $has_autoloader = \true;
            }
            $composer_json_file = \Psalm\Internal\Composer::getJsonFilePath($autoload_root);
            if (!$has_autoloader && file_exists($composer_json_file)) {
                $error_message = 'Could not find any composer autoloaders in ' . $autoload_root;
                if (!$has_explicit_root) {
                    $error_message .= PHP_EOL . 'Add a --root=[your/project/directory] flag ' . 'to specify a particular project to run Psalm on.';
                }
                fwrite(STDERR, $error_message . PHP_EOL);
                exit(1);
            }
        }
        $first_autoloader = null;
        foreach ($autoload_files as $file) {
            /**
             * @psalm-suppress UnresolvableInclude
             * @var mixed
             */
            $autoloader = (require_once $file);
            if (!$first_autoloader && $autoloader instanceof ClassLoader) {
                $first_autoloader = $autoloader;
            }
        }
        if ($first_autoloader === null && !$in_phar) {
            if (!$autoload_files) {
                fwrite(STDERR, 'Failed to find a valid Composer autoloader' . "\n");
            } else {
                fwrite(STDERR, 'Failed to find a valid Composer autoloader in ' . implode(', ', $autoload_files) . "\n");
            }
            fwrite(STDERR, 'Please make sure you’ve run `composer install` in the current directory before using Psalm.' . "\n");
            exit(1);
        }
        define('PSALM_VERSION', \Psalm\Internal\VersionUtils::getPsalmVersion());
        define('PHP_PARSER_VERSION', \Psalm\Internal\VersionUtils::getPhpParserVersion());
        return $first_autoloader;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public static function getVendorDir(string $current_dir) : string
    {
        $composer_json_path = \Psalm\Internal\Composer::getJsonFilePath($current_dir);
        if (!file_exists($composer_json_path)) {
            return 'vendor';
        }
        try {
            $composer_json = json_decode(file_get_contents($composer_json_path), \true, 512, JSON_THROW_ON_ERROR);
        } catch (JsonException $e) {
            fwrite(STDERR, 'Invalid composer.json at ' . $composer_json_path . "\n" . $e->getMessage() . "\n");
            exit(1);
        }
        if (!$composer_json) {
            fwrite(STDERR, 'Invalid composer.json at ' . $composer_json_path . "\n");
            exit(1);
        }
        if (is_array($composer_json) && isset($composer_json['config']) && is_array($composer_json['config']) && isset($composer_json['config']['vendor-dir']) && is_string($composer_json['config']['vendor-dir'])) {
            return $composer_json['config']['vendor-dir'];
        }
        return 'vendor';
    }
    /**
     * @return list<string>
     */
    public static function getRawCliArguments() : array
    {
        global $argv;
        if (!$argv) {
            return [];
        }
        return array_slice($argv, 1);
    }
    /**
     * @return list<string>
     */
    public static function getArguments() : array
    {
        $argv = self::getRawCliArguments();
        $filtered_input_paths = [];
        for ($i = 0, $iMax = count($argv); $i < $iMax; ++$i) {
            $input_path = $argv[$i];
            if (realpath($input_path) !== \false) {
                continue;
            }
            if ($input_path[0] === '-' && strlen($input_path) === 2) {
                if ($input_path[1] === 'c' || $input_path[1] === 'f') {
                    ++$i;
                }
                continue;
            }
            if ($input_path[0] === '-' && $input_path[2] === '=') {
                continue;
            }
            $filtered_input_paths[] = $input_path;
        }
        return $filtered_input_paths;
    }
    /**
     * @param  string|array|null|false $f_paths
     * @return list<string>|null
     */
    public static function getPathsToCheck($f_paths) : ?array
    {
        $paths_to_check = [];
        if ($f_paths) {
            $input_paths = is_array($f_paths) ? $f_paths : [$f_paths];
        } else {
            $input_paths = self::getRawCliArguments();
            if (!$input_paths) {
                return null;
            }
        }
        $filtered_input_paths = [];
        for ($i = 0, $iMax = count($input_paths); $i < $iMax; ++$i) {
            /** @var string */
            $input_path = $input_paths[$i];
            if ($input_path[0] === '-' && strlen($input_path) === 2) {
                if ($input_path[1] === 'c' || $input_path[1] === 'f') {
                    ++$i;
                }
                continue;
            }
            if ($input_path[0] === '-' && $input_path[2] === '=') {
                continue;
            }
            if (strpos($input_path, '--') === 0 && strlen($input_path) > 2) {
                if (substr($input_path, 2) === 'config') {
                    ++$i;
                }
                continue;
            }
            $filtered_input_paths[] = $input_path;
        }
        if ($filtered_input_paths === ['-']) {
            $meta = stream_get_meta_data(STDIN);
            stream_set_blocking(STDIN, \false);
            if ($stdin = fgets(STDIN)) {
                $filtered_input_paths = preg_split('/\\s+/', trim($stdin));
                if ($filtered_input_paths === \false) {
                    throw new RuntimeException('Invalid paths: ' . preg_last_error_msg());
                }
            }
            $blocked = $meta['blocked'];
            stream_set_blocking(STDIN, $blocked);
        }
        foreach ($filtered_input_paths as $path_to_check) {
            if ($path_to_check[0] === '-') {
                fwrite(STDERR, 'Invalid usage, expecting psalm [options] [file...]' . PHP_EOL);
                exit(1);
            }
            if (!file_exists($path_to_check)) {
                fwrite(STDERR, 'Cannot locate ' . $path_to_check . PHP_EOL);
                exit(1);
            }
            $path_to_check = realpath($path_to_check);
            if (!$path_to_check) {
                fwrite(STDERR, 'Error getting realpath for file' . PHP_EOL);
                exit(1);
            }
            $paths_to_check[] = $path_to_check;
        }
        if (!$paths_to_check) {
            $paths_to_check = null;
        }
        return $paths_to_check;
    }
    public static function initializeConfig(?string $path_to_config, string $current_dir, string $output_format, ?ClassLoader $first_autoloader, bool $create_if_non_existent = \false) : Config
    {
        try {
            if ($path_to_config) {
                $config = Config::loadFromXMLFile($path_to_config, $current_dir);
            } else {
                try {
                    $config = Config::getConfigForPath($current_dir, $current_dir);
                } catch (ConfigNotFoundException $e) {
                    if (!$create_if_non_existent) {
                        if (in_array($output_format, [Report::TYPE_CONSOLE, Report::TYPE_PHP_STORM])) {
                            fwrite(STDERR, 'Could not locate a config XML file in path ' . $current_dir . '. Have you run \'psalm --init\' ?' . PHP_EOL);
                            exit(1);
                        }
                        throw $e;
                    }
                    $config = Creator::createBareConfig($current_dir, null, self::getVendorDir($current_dir));
                }
            }
        } catch (ConfigException $e) {
            fwrite(STDERR, $e->getMessage() . PHP_EOL);
            exit(1);
        }
        $config->setComposerClassLoader($first_autoloader);
        return $config;
    }
    public static function updateConfigFile(Config $config, string $config_file_path, string $baseline_path) : void
    {
        if ($config->error_baseline === $baseline_path) {
            return;
        }
        $config_file = $config_file_path;
        if (is_dir($config_file_path)) {
            $config_file = Config::locateConfigFile($config_file_path);
        }
        if (!$config_file) {
            fwrite(STDERR, "Don't forget to set errorBaseline=\"{$baseline_path}\" to your config.");
            return;
        }
        $config_file_contents = file_get_contents($config_file);
        if ($config->error_baseline) {
            $amended_config_file_contents = preg_replace('/errorBaseline=".*?"/', "errorBaseline=\"{$baseline_path}\"", $config_file_contents);
        } else {
            $end_psalm_open_tag = strpos($config_file_contents, '>', (int) strpos($config_file_contents, '<psalm'));
            if (!$end_psalm_open_tag) {
                fwrite(STDERR, " Don't forget to set errorBaseline=\"{$baseline_path}\" in your config.");
                return;
            }
            if ($config_file_contents[$end_psalm_open_tag - 1] === "\n") {
                $amended_config_file_contents = substr_replace($config_file_contents, "    errorBaseline=\"{$baseline_path}\"\n>", $end_psalm_open_tag, 1);
            } else {
                $amended_config_file_contents = substr_replace($config_file_contents, " errorBaseline=\"{$baseline_path}\">", $end_psalm_open_tag, 1);
            }
        }
        file_put_contents($config_file, $amended_config_file_contents);
    }
    public static function getPathToConfig(array $options) : ?string
    {
        $path_to_config = isset($options['c']) && is_string($options['c']) ? realpath($options['c']) : null;
        if ($path_to_config === \false) {
            fwrite(STDERR, 'Could not resolve path to config ' . (string) ($options['c'] ?? '') . PHP_EOL);
            exit(1);
        }
        return $path_to_config;
    }
    /**
     * @psalm-pure
     */
    public static function getMemoryLimitInBytes() : int
    {
        return self::convertMemoryLimitToBytes(ini_get('memory_limit'));
    }
    /** @psalm-pure */
    public static function convertMemoryLimitToBytes(string $limit) : int
    {
        // for unlimited = -1
        if ($limit < 0) {
            return -1;
        }
        if (preg_match('/^(\\d+)(\\D?)$/', $limit, $matches)) {
            assert(isset($matches[1]));
            $limit = (int) $matches[1];
            switch (strtoupper($matches[2] ?? '')) {
                case 'G':
                    $limit *= 1024 * 1024 * 1024;
                    break;
                case 'M':
                    $limit *= 1024 * 1024;
                    break;
                case 'K':
                    $limit *= 1024;
                    break;
            }
        }
        return (int) $limit;
    }
    public static function initPhpVersion(array $options, Config $config, ProjectAnalyzer $project_analyzer) : void
    {
        $source = null;
        if (isset($options['php-version'])) {
            if (!is_string($options['php-version'])) {
                die('Expecting a version number in the format x.y' . PHP_EOL);
            }
            $version = $options['php-version'];
            $source = 'cli';
        } elseif ($version = $config->getPhpVersionFromConfig()) {
            $source = 'config';
        } elseif ($version = $config->getPHPVersionFromComposerJson()) {
            $source = 'composer';
        }
        if ($version !== null && $source !== null) {
            $project_analyzer->setPhpVersion($version, $source);
        }
    }
    public static function runningInCI() : bool
    {
        return isset($_SERVER['TRAVIS']) || isset($_SERVER['CIRCLECI']) || isset($_SERVER['APPVEYOR']) || isset($_SERVER['JENKINS_URL']) || isset($_SERVER['SCRUTINIZER']) || isset($_SERVER['GITLAB_CI']) || isset($_SERVER['GITHUB_WORKFLOW']) || isset($_SERVER['DRONE']);
    }
    public static function checkRuntimeRequirements() : void
    {
        $required_php_version = 70400;
        $required_php_version_text = '7.4.0';
        // the following list was taken from vendor/composer/platform_check.php
        // It includes both Psalm's requirements (from composer.json) and the
        // requirements of our dependencies `netresearch/jsonmapper` and
        // `phpdocumentor/reflection-docblock`. The latter is transitive
        // dependency of `felixfbecker/advanced-json-rpc`
        $required_extensions = ['dom', 'filter', 'json', 'libxml', 'pcre', 'reflection', 'simplexml', 'spl', 'tokenizer'];
        $issues = [];
        if (PHP_VERSION_ID < $required_php_version) {
            $issues[] = 'Psalm requires a PHP version ">= ' . $required_php_version_text . '".' . ' You are running ' . PHP_VERSION . '.';
        }
        $missing_extensions = array_filter($required_extensions, static fn(string $ext) => !extension_loaded($ext));
        if ($missing_extensions) {
            $issues[] = 'Psalm requires the following PHP extensions to be installed: ' . implode(', ', $missing_extensions) . '.';
        }
        if ($issues) {
            fwrite(STDERR, 'Psalm has detected issues in your platform:' . PHP_EOL . PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL . PHP_EOL);
            exit(1);
        }
    }
}
<?php

namespace Psalm\Internal\FileManipulation;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Class_;
use Psalm\DocComment;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Scanner\ParsedDocblock;
use function ltrim;
use function str_replace;
use function strlen;
use function strrpos;
use function substr;
/**
 * @internal
 */
class ClassDocblockManipulator
{
    /**
     * @var array<string, array<int, self>>
     */
    private static array $manipulators = [];
    private Class_ $stmt;
    private int $docblock_start;
    private int $docblock_end;
    private bool $immutable = \false;
    private string $indentation;
    public static function getForClass(ProjectAnalyzer $project_analyzer, string $file_path, Class_ $stmt) : self
    {
        if (isset(self::$manipulators[$file_path][$stmt->getLine()])) {
            return self::$manipulators[$file_path][$stmt->getLine()];
        }
        $manipulator = self::$manipulators[$file_path][$stmt->getLine()] = new self($project_analyzer, $stmt, $file_path);
        return $manipulator;
    }
    private function __construct(ProjectAnalyzer $project_analyzer, Class_ $stmt, string $file_path)
    {
        $this->stmt = $stmt;
        $docblock = $stmt->getDocComment();
        $this->docblock_start = $docblock ? $docblock->getStartFilePos() : (int) $stmt->getAttribute('startFilePos');
        $this->docblock_end = (int) $stmt->getAttribute('startFilePos');
        $codebase = $project_analyzer->getCodebase();
        $file_contents = $codebase->getFileContents($file_path);
        $preceding_newline_pos = (int) strrpos($file_contents, "\n", $this->docblock_end - strlen($file_contents));
        $first_line = substr($file_contents, $preceding_newline_pos + 1, $this->docblock_end - $preceding_newline_pos);
        $this->indentation = str_replace(ltrim($first_line), '', $first_line);
    }
    public function makeImmutable() : void
    {
        $this->immutable = \true;
    }
    /**
     * Gets a new docblock given the existing docblock, if one exists, and the updated return types
     * and/or parameters
     */
    private function getDocblock() : string
    {
        $docblock = $this->stmt->getDocComment();
        if ($docblock) {
            $parsed_docblock = DocComment::parsePreservingLength($docblock);
        } else {
            $parsed_docblock = new ParsedDocblock('', []);
        }
        $modified_docblock = \false;
        if ($this->immutable) {
            $modified_docblock = \true;
            $parsed_docblock->tags['psalm-immutable'] = [''];
        }
        if (!$modified_docblock) {
            return (string) $docblock . "\n" . $this->indentation;
        }
        return $parsed_docblock->render($this->indentation);
    }
    /**
     * @return array<int, FileManipulation>
     */
    public static function getManipulationsForFile(string $file_path) : array
    {
        if (!isset(self::$manipulators[$file_path])) {
            return [];
        }
        $file_manipulations = [];
        foreach (self::$manipulators[$file_path] as $manipulator) {
            if ($manipulator->immutable) {
                $file_manipulations[$manipulator->docblock_start] = new FileManipulation($manipulator->docblock_start, $manipulator->docblock_end, $manipulator->getDocblock());
            }
        }
        return $file_manipulations;
    }
    public static function clearCache() : void
    {
        self::$manipulators = [];
    }
}
<?php

namespace Psalm\Internal\FileManipulation;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ArrowFunction;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Closure;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\FunctionLike;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Function_;
use Psalm\DocComment;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Scanner\ParsedDocblock;
use function array_key_exists;
use function array_merge;
use function array_reduce;
use function count;
use function is_string;
use function ltrim;
use function preg_match;
use function reset;
use function str_replace;
use function str_split;
use function strlen;
use function strpos;
use function strrpos;
use function substr;
/**
 * @internal
 */
class FunctionDocblockManipulator
{
    /**
     * Manipulators ordered by line number
     *
     * @var array<string, array<int, FunctionDocblockManipulator>>
     */
    private static array $manipulators = [];
    /** @var Closure|Function_|ClassMethod|ArrowFunction */
    private $stmt;
    private int $docblock_start;
    private int $docblock_end;
    private int $return_typehint_area_start;
    private ?int $return_typehint_colon_start = null;
    private ?int $return_typehint_start = null;
    private ?int $return_typehint_end = null;
    private ?string $new_php_return_type = null;
    private bool $return_type_is_php_compatible = \false;
    private ?string $new_phpdoc_return_type = null;
    private ?string $new_psalm_return_type = null;
    /** @var array<string, string> */
    private array $new_php_param_types = [];
    /** @var array<string, string> */
    private array $new_phpdoc_param_types = [];
    /** @var array<string, string> */
    private array $new_psalm_param_types = [];
    private string $indentation;
    private ?string $return_type_description = null;
    /** @var array<string, int> */
    private array $param_offsets = [];
    /** @var array<string, array{int, int}> */
    private array $param_typehint_offsets = [];
    private bool $is_pure = \false;
    /** @var list<string> */
    private array $throwsExceptions = [];
    /**
     * @param  Closure|Function_|ClassMethod|ArrowFunction $stmt
     */
    public static function getForFunction(ProjectAnalyzer $project_analyzer, string $file_path, FunctionLike $stmt) : \Psalm\Internal\FileManipulation\FunctionDocblockManipulator
    {
        if (isset(self::$manipulators[$file_path][$stmt->getLine()])) {
            return self::$manipulators[$file_path][$stmt->getLine()];
        }
        $manipulator = self::$manipulators[$file_path][$stmt->getLine()] = new self($file_path, $stmt, $project_analyzer);
        return $manipulator;
    }
    /**
     * @param Closure|Function_|ClassMethod|ArrowFunction $stmt
     */
    private function __construct(string $file_path, FunctionLike $stmt, ProjectAnalyzer $project_analyzer)
    {
        $this->stmt = $stmt;
        $docblock = $stmt->getDocComment();
        $this->docblock_start = $docblock ? $docblock->getStartFilePos() : (int) $stmt->getAttribute('startFilePos');
        $this->docblock_end = $function_start = (int) $stmt->getAttribute('startFilePos');
        $function_end = (int) $stmt->getAttribute('endFilePos');
        $attributes = $stmt->getAttrGroups();
        foreach ($attributes as $attribute) {
            // if we have attribute groups, we need to consider that the function starts after them
            if ((int) $attribute->getAttribute('endFilePos') > $function_start) {
                $function_start = (int) $attribute->getAttribute('endFilePos');
            }
        }
        foreach ($stmt->params as $param) {
            if ($param->var instanceof PhpParser\Node\Expr\Variable && is_string($param->var->name)) {
                $this->param_offsets[$param->var->name] = (int) $param->getAttribute('startFilePos');
                if ($param->type) {
                    $this->param_typehint_offsets[$param->var->name] = [(int) $param->type->getAttribute('startFilePos'), (int) $param->type->getAttribute('endFilePos')];
                }
            }
        }
        $codebase = $project_analyzer->getCodebase();
        $file_contents = $codebase->getFileContents($file_path);
        $last_arg_position = $stmt->params ? (int) $stmt->params[count($stmt->params) - 1]->getAttribute('endFilePos') + 1 : null;
        if ($stmt instanceof Closure && $stmt->uses) {
            $last_arg_position = (int) $stmt->uses[count($stmt->uses) - 1]->getAttribute('endFilePos') + 1;
        }
        $end_bracket_position = (int) strpos($file_contents, ')', $last_arg_position ?: $function_start);
        $this->return_typehint_area_start = $end_bracket_position + 1;
        $function_code = substr($file_contents, $function_start, $function_end);
        $function_code_after_bracket = substr($function_code, $end_bracket_position + 1 - $function_start);
        // do a little parsing here
        $chars = str_split($function_code_after_bracket);
        $in_single_line_comment = $in_multi_line_comment = \false;
        for ($i = 0, $iMax = count($chars); $i < $iMax; ++$i) {
            $char = $chars[$i];
            switch ($char) {
                case "\n":
                    $in_single_line_comment = \false;
                    continue 2;
                case ':':
                    if ($in_multi_line_comment || $in_single_line_comment) {
                        continue 2;
                    }
                    $this->return_typehint_colon_start = $i + $end_bracket_position + 1;
                    continue 2;
                case '/':
                    if ($in_multi_line_comment || $in_single_line_comment) {
                        continue 2;
                    }
                    if ($chars[$i + 1] === '*') {
                        $in_multi_line_comment = \true;
                        ++$i;
                    }
                    if ($chars[$i + 1] === '/') {
                        $in_single_line_comment = \true;
                        ++$i;
                    }
                    continue 2;
                case '*':
                    if ($in_single_line_comment) {
                        continue 2;
                    }
                    if ($chars[$i + 1] === '/') {
                        $in_multi_line_comment = \false;
                        ++$i;
                    }
                    continue 2;
                case '{':
                    if ($in_multi_line_comment || $in_single_line_comment) {
                        continue 2;
                    }
                    break 2;
                case '=':
                    if ($in_multi_line_comment || $in_single_line_comment) {
                        continue 2;
                    }
                    break 2;
                case '?':
                    if ($in_multi_line_comment || $in_single_line_comment) {
                        continue 2;
                    }
                    $this->return_typehint_start = $i + $end_bracket_position + 1;
                    break;
            }
            if ($in_multi_line_comment || $in_single_line_comment) {
                continue;
            }
            if ($chars[$i] === '\\' || preg_match('/\\w/', $char)) {
                if ($this->return_typehint_start === null) {
                    $this->return_typehint_start = $i + $end_bracket_position + 1;
                }
                if ($chars[$i + 1] !== '\\' && !preg_match('/[\\w]/', $chars[$i + 1])) {
                    $this->return_typehint_end = $i + $end_bracket_position + 2;
                    break;
                }
            }
        }
        $preceding_newline_pos = strrpos($file_contents, "\n", $this->docblock_end - strlen($file_contents));
        if ($preceding_newline_pos === \false) {
            $this->indentation = '';
            return;
        }
        $first_line = substr($file_contents, $preceding_newline_pos + 1, $this->docblock_end - $preceding_newline_pos);
        $this->indentation = str_replace(ltrim($first_line), '', $first_line);
    }
    /**
     * Sets the new return type
     */
    public function setReturnType(?string $php_type, string $new_type, string $phpdoc_type, bool $is_php_compatible, ?string $description) : void
    {
        $new_type = str_replace(['<mixed, mixed>', '<array-key, mixed>'], '', $new_type);
        $this->new_php_return_type = $php_type;
        $this->new_phpdoc_return_type = $phpdoc_type;
        $this->new_psalm_return_type = $new_type;
        $this->return_type_is_php_compatible = $is_php_compatible;
        $this->return_type_description = $description;
    }
    /**
     * Sets a new param type
     */
    public function setParamType(string $param_name, ?string $php_type, string $new_type, string $phpdoc_type) : void
    {
        $new_type = str_replace(['<mixed, mixed>', '<array-key, mixed>', '<never, never>'], '', $new_type);
        if ($php_type === 'static') {
            $php_type = '';
        }
        if ($php_type) {
            $this->new_php_param_types[$param_name] = $php_type;
        }
        if ($php_type !== $phpdoc_type) {
            $this->new_phpdoc_param_types[$param_name] = $phpdoc_type;
        }
        if ($php_type !== $new_type && $phpdoc_type !== $new_type) {
            $this->new_psalm_param_types[$param_name] = $new_type;
        }
    }
    /**
     * Gets a new docblock given the existing docblock, if one exists, and the updated return types
     * and/or parameters
     */
    private function getDocblock() : string
    {
        $docblock = $this->stmt->getDocComment();
        if ($docblock) {
            $parsed_docblock = DocComment::parsePreservingLength($docblock);
        } else {
            $parsed_docblock = new ParsedDocblock('', []);
        }
        $modified_docblock = \false;
        foreach ($this->new_phpdoc_param_types as $param_name => $phpdoc_type) {
            $found_in_params = \false;
            $new_param_block = $phpdoc_type . ' ' . '$' . $param_name;
            if (isset($parsed_docblock->tags['param'])) {
                foreach ($parsed_docblock->tags['param'] as &$param_block) {
                    $doc_parts = CommentAnalyzer::splitDocLine($param_block);
                    if (($doc_parts[1] ?? null) === '$' . $param_name) {
                        if ($param_block !== $new_param_block) {
                            $modified_docblock = \true;
                        }
                        $param_block = $new_param_block;
                        $found_in_params = \true;
                        break;
                    }
                }
                unset($param_block);
            }
            if (!$found_in_params) {
                $modified_docblock = \true;
                $parsed_docblock->tags['param'][] = $new_param_block;
            }
        }
        foreach ($this->new_psalm_param_types as $param_name => $psalm_type) {
            $found_in_params = \false;
            $new_param_block = $psalm_type . ' ' . '$' . $param_name;
            if (isset($parsed_docblock->tags['psalm-param'])) {
                foreach ($parsed_docblock->tags['psalm-param'] as &$param_block) {
                    $doc_parts = CommentAnalyzer::splitDocLine($param_block);
                    if (($doc_parts[1] ?? null) === '$' . $param_name) {
                        if ($param_block !== $new_param_block) {
                            $modified_docblock = \true;
                        }
                        $param_block = $new_param_block;
                        $found_in_params = \true;
                        break;
                    }
                }
                unset($param_block);
            }
            if (!$found_in_params) {
                $modified_docblock = \true;
                $parsed_docblock->tags['psalm-param'][] = $new_param_block;
            }
        }
        $old_phpdoc_return_type = null;
        if (isset($parsed_docblock->tags['return'])) {
            $old_phpdoc_return_type = reset($parsed_docblock->tags['return']);
        }
        if ($this->is_pure) {
            $modified_docblock = \true;
            $parsed_docblock->tags['psalm-pure'] = [''];
        }
        if (count($this->throwsExceptions) > 0) {
            $modified_docblock = \true;
            $inferredThrowsClause = array_reduce($this->throwsExceptions, fn(string $throwsClause, string $exception) => $throwsClause === '' ? $exception : $throwsClause . '|' . $exception, '');
            if (array_key_exists('throws', $parsed_docblock->tags)) {
                $parsed_docblock->tags['throws'][] = $inferredThrowsClause;
            } else {
                $parsed_docblock->tags['throws'] = [$inferredThrowsClause];
            }
        }
        if ($this->new_phpdoc_return_type && $this->new_phpdoc_return_type !== $old_phpdoc_return_type) {
            $modified_docblock = \true;
            if ($this->new_phpdoc_return_type !== $this->new_php_return_type || $this->return_type_description) {
                //only add the type if it's different than signature or if there's a description
                $parsed_docblock->tags['return'] = [$this->new_phpdoc_return_type . ($this->return_type_description ? ' ' . $this->return_type_description : '')];
            } else {
                unset($parsed_docblock->tags['return']);
            }
        }
        $old_psalm_return_type = null;
        if (isset($parsed_docblock->tags['psalm-return'])) {
            $old_psalm_return_type = reset($parsed_docblock->tags['psalm-return']);
        }
        if ($this->new_psalm_return_type && $this->new_phpdoc_return_type !== $this->new_psalm_return_type && $this->new_psalm_return_type !== $old_psalm_return_type) {
            $modified_docblock = \true;
            $parsed_docblock->tags['psalm-return'] = [$this->new_psalm_return_type];
        }
        if (!$parsed_docblock->tags && !$parsed_docblock->description) {
            return '';
        }
        if (!$modified_docblock) {
            return (string) $docblock . "\n" . $this->indentation;
        }
        return $parsed_docblock->render($this->indentation);
    }
    /**
     * @return array<int, FileManipulation>
     */
    public static function getManipulationsForFile(string $file_path) : array
    {
        if (!isset(self::$manipulators[$file_path])) {
            return [];
        }
        $file_manipulations = [];
        foreach (self::$manipulators[$file_path] as $manipulator) {
            if ($manipulator->new_php_return_type) {
                if ($manipulator->return_typehint_start && $manipulator->return_typehint_end) {
                    $file_manipulations[$manipulator->return_typehint_start] = new FileManipulation($manipulator->return_typehint_start, $manipulator->return_typehint_end, $manipulator->new_php_return_type);
                } else {
                    $file_manipulations[$manipulator->return_typehint_area_start] = new FileManipulation($manipulator->return_typehint_area_start, $manipulator->return_typehint_area_start, ': ' . $manipulator->new_php_return_type);
                }
            } elseif ($manipulator->new_php_return_type === '' && $manipulator->return_typehint_colon_start && $manipulator->new_phpdoc_return_type && $manipulator->return_typehint_start && $manipulator->return_typehint_end) {
                $file_manipulations[$manipulator->return_typehint_start] = new FileManipulation($manipulator->return_typehint_colon_start, $manipulator->return_typehint_end, '');
            }
            if (!$manipulator->new_php_return_type || !$manipulator->return_type_is_php_compatible || $manipulator->docblock_start !== $manipulator->docblock_end || $manipulator->is_pure) {
                $file_manipulations[$manipulator->docblock_start] = new FileManipulation($manipulator->docblock_start, $manipulator->docblock_end, $manipulator->getDocblock());
            }
            foreach ($manipulator->new_php_param_types as $param_name => $new_php_param_type) {
                if (!isset($manipulator->param_offsets[$param_name])) {
                    continue;
                }
                $param_offset = $manipulator->param_offsets[$param_name];
                $typehint_offsets = $manipulator->param_typehint_offsets[$param_name] ?? null;
                if ($new_php_param_type) {
                    if ($typehint_offsets) {
                        $file_manipulations[$typehint_offsets[0]] = new FileManipulation($typehint_offsets[0], $typehint_offsets[1], $new_php_param_type);
                    } else {
                        $file_manipulations[$param_offset] = new FileManipulation($param_offset, $param_offset, $new_php_param_type . ' ');
                    }
                } elseif ($new_php_param_type === '' && $typehint_offsets) {
                    $file_manipulations[$typehint_offsets[0]] = new FileManipulation($typehint_offsets[0], $param_offset, '');
                }
            }
        }
        return $file_manipulations;
    }
    public function makePure() : void
    {
        $this->is_pure = \true;
    }
    /**
     * @param list<string> $exceptions
     */
    public function addThrowsDocblock(array $exceptions) : void
    {
        $this->throwsExceptions = $exceptions;
    }
    public static function clearCache() : void
    {
        self::$manipulators = [];
    }
    /**
     * @param array<string, array<int, FunctionDocblockManipulator>> $manipulators
     */
    public static function addManipulators(array $manipulators) : void
    {
        self::$manipulators = array_merge($manipulators, self::$manipulators);
    }
    /**
     * @return array<string, array<int, FunctionDocblockManipulator>>
     */
    public static function getManipulators() : array
    {
        return self::$manipulators;
    }
}
<?php

namespace Psalm\Internal\FileManipulation;

use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Provider\FileProvider;
use function array_merge;
use function preg_match;
use function strlen;
use function strpos;
use function strrpos;
use function substr;
use function substr_replace;
/**
 * @internal
 */
class FileManipulationBuffer
{
    /** @var array<string, FileManipulation[]> */
    private static array $file_manipulations = [];
    /** @var CodeMigration[] */
    private static array $code_migrations = [];
    /**
     * @param FileManipulation[] $file_manipulations
     */
    public static function add(string $file_path, array $file_manipulations) : void
    {
        if (!isset(self::$file_manipulations[$file_path])) {
            self::$file_manipulations[$file_path] = [];
        }
        foreach ($file_manipulations as $file_manipulation) {
            self::$file_manipulations[$file_path][$file_manipulation->getKey()] = $file_manipulation;
        }
    }
    /** @param CodeMigration[] $code_migrations */
    public static function addCodeMigrations(array $code_migrations) : void
    {
        self::$code_migrations = array_merge(self::$code_migrations, $code_migrations);
    }
    /**
     * @return array{int, int}
     */
    private static function getCodeOffsets(string $source_file_path, int $source_start, int $source_end) : array
    {
        if (!isset(self::$file_manipulations[$source_file_path])) {
            return [0, 0];
        }
        $start_offset = 0;
        $middle_offset = 0;
        foreach (self::$file_manipulations[$source_file_path] as $fm) {
            $offset = strlen($fm->insertion_text) - $fm->end + $fm->start;
            if ($fm->end < $source_start) {
                $start_offset += $offset;
                $middle_offset += $offset;
            } elseif ($fm->start > $source_start && $fm->end < $source_end) {
                $middle_offset += $offset;
            }
        }
        return [$start_offset, $middle_offset];
    }
    public static function addForCodeLocation(CodeLocation $code_location, string $replacement_text, bool $swallow_newlines = \false) : void
    {
        $bounds = $code_location->getSnippetBounds();
        if ($swallow_newlines) {
            $project_analyzer = ProjectAnalyzer::getInstance();
            $codebase = $project_analyzer->getCodebase();
            $file_contents = $codebase->getFileContents($code_location->file_path);
            if (($file_contents[$bounds[0] - 1] ?? null) === "\n" && ($file_contents[$bounds[0] - 2] ?? null) === "\n") {
                $bounds[0] -= 2;
            }
        }
        self::add($code_location->file_path, [new FileManipulation($bounds[0], $bounds[1], $replacement_text)]);
    }
    public static function addVarAnnotationToRemove(DocblockTypeLocation $code_location) : void
    {
        $bounds = $code_location->getSelectionBounds();
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        $file_contents = $codebase->getFileContents($code_location->file_path);
        $comment_start = strrpos($file_contents, '/**', $bounds[0] - strlen($file_contents));
        if ($comment_start === \false) {
            return;
        }
        $comment_end = strpos($file_contents, '*/', $bounds[1]);
        if ($comment_end === \false) {
            return;
        }
        $comment_end += 2;
        $comment_text = substr($file_contents, $comment_start, $comment_end - $comment_start);
        $var_type_comment_start = $bounds[0] - $comment_start;
        $var_type_comment_end = $bounds[1] - $comment_start;
        $var_start = strrpos($comment_text, '@var', $var_type_comment_start - strlen($comment_text));
        $var_end = strpos($comment_text, "\n", $var_type_comment_end);
        if ($var_start && $var_end) {
            $var_start = strrpos($comment_text, "\n", $var_start - strlen($comment_text)) ?: $var_start;
            $comment_text = substr_replace($comment_text, '', $var_start, $var_end - $var_start);
            if (preg_match('@^/\\*\\*\\n(\\s*\\*\\s*\\n)*\\s*\\*?\\*/$@', $comment_text)) {
                $comment_text = '';
            }
        } else {
            $comment_text = '';
        }
        self::add($code_location->file_path, [new FileManipulation($comment_start, $comment_end, $comment_text, \false, $comment_text === '')]);
    }
    /**
     * @return FileManipulation[]
     */
    public static function getManipulationsForFile(string $file_path) : array
    {
        return self::$file_manipulations[$file_path] ?? [];
    }
    /**
     * @return array<string, FileManipulation[]>
     */
    public static function getMigrationManipulations(FileProvider $file_provider) : array
    {
        $code_migration_manipulations = [];
        foreach (self::$code_migrations as $code_migration) {
            [$start_offset, $middle_offset] = self::getCodeOffsets($code_migration->source_file_path, $code_migration->source_start, $code_migration->source_end);
            if (!isset($code_migration_manipulations[$code_migration->source_file_path])) {
                $code_migration_manipulations[$code_migration->source_file_path] = [];
            }
            if (!isset($code_migration_manipulations[$code_migration->destination_file_path])) {
                $code_migration_manipulations[$code_migration->destination_file_path] = [];
            }
            $delete_file_manipulation = new FileManipulation($code_migration->source_start + $start_offset, $code_migration->source_end + $middle_offset, '');
            $code_migration_manipulations[$code_migration->source_file_path][] = $delete_file_manipulation;
            [$destination_start_offset] = self::getCodeOffsets($code_migration->destination_file_path, $code_migration->destination_start, $code_migration->destination_start);
            $manipulation = new FileManipulation($code_migration->destination_start + $destination_start_offset, $code_migration->destination_start + $destination_start_offset, "\n" . substr($file_provider->getContents($code_migration->source_file_path), $delete_file_manipulation->start, $delete_file_manipulation->end - $delete_file_manipulation->start) . "\n");
            $code_migration_manipulations[$code_migration->destination_file_path][$manipulation->getKey()] = $manipulation;
        }
        return $code_migration_manipulations;
    }
    /**
     * @return array<string, FileManipulation[]>
     */
    public static function getAll() : array
    {
        return self::$file_manipulations;
    }
    public static function clearCache() : void
    {
        self::$file_manipulations = [];
        self::$code_migrations = [];
    }
}
<?php

namespace Psalm\Internal\FileManipulation;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class CodeMigration
{
    use ImmutableNonCloneableTrait;
    public string $source_file_path;
    public int $source_start;
    public int $source_end;
    public string $destination_file_path;
    public int $destination_start;
    public function __construct(string $source_file_path, int $source_start, int $source_end, string $destination_file_path, int $destination_start)
    {
        $this->source_file_path = $source_file_path;
        $this->source_start = $source_start;
        $this->source_end = $source_end;
        $this->destination_file_path = $destination_file_path;
        $this->destination_start = $destination_start;
    }
}
<?php

namespace Psalm\Internal\FileManipulation;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Property;
use Psalm\Config;
use Psalm\DocComment;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Scanner\ParsedDocblock;
use UnexpectedValueException;
use function array_shift;
use function count;
use function ltrim;
use function str_replace;
use function strlen;
use function strrpos;
use function substr;
use function substr_count;
/**
 * @internal
 */
class PropertyDocblockManipulator
{
    /**
     * @var array<string, array<int, self>>
     */
    private static array $manipulators = [];
    private Property $stmt;
    private int $docblock_start;
    private int $docblock_end;
    private ?int $typehint_start = null;
    private int $typehint_area_start;
    private ?int $typehint_end = null;
    private ?string $new_php_type = null;
    private bool $type_is_php_compatible = \false;
    private ?string $new_phpdoc_type = null;
    private ?string $new_psalm_type = null;
    private string $indentation;
    private bool $add_newline = \false;
    private ?string $type_description = null;
    public static function getForProperty(ProjectAnalyzer $project_analyzer, string $file_path, Property $stmt) : self
    {
        if (isset(self::$manipulators[$file_path][$stmt->getLine()])) {
            return self::$manipulators[$file_path][$stmt->getLine()];
        }
        $manipulator = self::$manipulators[$file_path][$stmt->getLine()] = new self($project_analyzer, $stmt, $file_path);
        return $manipulator;
    }
    private function __construct(ProjectAnalyzer $project_analyzer, Property $stmt, string $file_path)
    {
        $this->stmt = $stmt;
        $docblock = $stmt->getDocComment();
        $this->docblock_start = $docblock ? $docblock->getStartFilePos() : (int) $stmt->getAttribute('startFilePos');
        $this->docblock_end = (int) $stmt->getAttribute('startFilePos');
        $codebase = $project_analyzer->getCodebase();
        $file_contents = $codebase->getFileContents($file_path);
        if (count($stmt->props) > 1) {
            $config = Config::getInstance();
            if ($config->isInProjectDirs($file_path)) {
                throw new UnexpectedValueException('Cannot replace multiple inline properties in ' . $file_path);
            }
            $this->indentation = '';
            return;
        }
        $prop = $stmt->props[0];
        if ($stmt->type) {
            $this->typehint_start = (int) $stmt->type->getAttribute('startFilePos');
            $this->typehint_end = (int) $stmt->type->getAttribute('endFilePos');
        }
        $this->typehint_area_start = (int) $prop->getAttribute('startFilePos') - 1;
        $preceding_newline_pos = strrpos($file_contents, "\n", $this->docblock_end - strlen($file_contents));
        if ($preceding_newline_pos === \false) {
            $this->indentation = '';
            return;
        }
        if (!$docblock) {
            $preceding_semicolon_pos = strrpos($file_contents, ";", $preceding_newline_pos - strlen($file_contents));
            if ($preceding_semicolon_pos) {
                $preceding_space = substr($file_contents, $preceding_semicolon_pos + 1, $preceding_newline_pos - $preceding_semicolon_pos - 1);
                if (!substr_count($preceding_space, "\n")) {
                    $this->add_newline = \true;
                }
            }
        }
        $first_line = substr($file_contents, $preceding_newline_pos + 1, $this->docblock_end - $preceding_newline_pos);
        $this->indentation = str_replace(ltrim($first_line), '', $first_line);
    }
    public function setType(?string $php_type, string $new_type, string $phpdoc_type, bool $is_php_compatible, ?string $description = null) : void
    {
        $new_type = str_replace(['<mixed, mixed>', '<array-key, mixed>', '<never, never>'], '', $new_type);
        $this->new_php_type = $php_type;
        $this->new_phpdoc_type = $phpdoc_type;
        $this->new_psalm_type = $new_type;
        $this->type_is_php_compatible = $is_php_compatible;
        $this->type_description = $description;
    }
    /**
     * Gets a new docblock given the existing docblock, if one exists, and the updated return types
     * and/or parameters
     */
    private function getDocblock() : string
    {
        $docblock = $this->stmt->getDocComment();
        if ($docblock) {
            $parsed_docblock = DocComment::parsePreservingLength($docblock);
        } else {
            $parsed_docblock = new ParsedDocblock('', []);
        }
        $modified_docblock = \false;
        $old_phpdoc_type = null;
        if (isset($parsed_docblock->tags['var'])) {
            $old_phpdoc_type = array_shift($parsed_docblock->tags['var']);
        }
        if ($this->new_phpdoc_type && $this->new_phpdoc_type !== $old_phpdoc_type) {
            $modified_docblock = \true;
            $parsed_docblock->tags['var'] = [$this->new_phpdoc_type . ($this->type_description ? ' ' . $this->type_description : '')];
        }
        $old_psalm_type = null;
        if (isset($parsed_docblock->tags['psalm-var'])) {
            $old_psalm_type = array_shift($parsed_docblock->tags['psalm-var']);
        }
        if ($this->new_psalm_type && $this->new_phpdoc_type !== $this->new_psalm_type && $this->new_psalm_type !== $old_psalm_type) {
            $modified_docblock = \true;
            $parsed_docblock->tags['psalm-var'] = [$this->new_psalm_type];
        }
        if (!$parsed_docblock->tags && !$parsed_docblock->description) {
            return '';
        }
        if (!$modified_docblock) {
            return (string) $docblock . "\n" . $this->indentation;
        }
        return $parsed_docblock->render($this->indentation);
    }
    /**
     * @return array<int, FileManipulation>
     */
    public static function getManipulationsForFile(string $file_path) : array
    {
        if (!isset(self::$manipulators[$file_path])) {
            return [];
        }
        $file_manipulations = [];
        foreach (self::$manipulators[$file_path] as $manipulator) {
            if ($manipulator->new_php_type) {
                if ($manipulator->typehint_start && $manipulator->typehint_end) {
                    $file_manipulations[$manipulator->typehint_start] = new FileManipulation($manipulator->typehint_start, $manipulator->typehint_end, $manipulator->new_php_type);
                } else {
                    $file_manipulations[$manipulator->typehint_area_start] = new FileManipulation($manipulator->typehint_area_start, $manipulator->typehint_area_start, ' ' . $manipulator->new_php_type);
                }
            } elseif ($manipulator->new_php_type === '' && $manipulator->new_phpdoc_type && $manipulator->typehint_start && $manipulator->typehint_end) {
                $file_manipulations[$manipulator->typehint_start] = new FileManipulation($manipulator->typehint_start, $manipulator->typehint_end, '');
            }
            if (!$manipulator->new_php_type || !$manipulator->type_is_php_compatible || $manipulator->docblock_start !== $manipulator->docblock_end) {
                $file_manipulations[$manipulator->docblock_start] = new FileManipulation($manipulator->docblock_start - ($manipulator->add_newline ? strlen($manipulator->indentation) : 0), $manipulator->docblock_end, ($manipulator->add_newline ? "\n" . $manipulator->indentation : '') . $manipulator->getDocblock());
            }
        }
        return $file_manipulations;
    }
    public static function clearCache() : void
    {
        self::$manipulators = [];
    }
}
<?php

namespace Psalm\Internal\Fork;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class ForkProcessDoneMessage implements \Psalm\Internal\Fork\ForkMessage
{
    use ImmutableNonCloneableTrait;
    /** @var mixed */
    public $data;
    /**
     * @param mixed $data
     */
    public function __construct($data)
    {
        $this->data = $data;
    }
}
<?php

namespace Psalm\Internal\Fork;

use Closure;
use Exception;
use Psalm\Config;
use Throwable;
use function array_fill_keys;
use function array_keys;
use function array_map;
use function array_pop;
use function array_values;
use function assert;
use function base64_decode;
use function base64_encode;
use function count;
use function error_get_last;
use function error_log;
use function explode;
use function extension_loaded;
use function fclose;
use function feof;
use function fread;
use function fwrite;
use function get_class;
use function gettype;
use function igbinary_serialize;
use function igbinary_unserialize;
use function in_array;
use function ini_get;
use function pcntl_fork;
use function pcntl_waitpid;
use function pcntl_wexitstatus;
use function pcntl_wifsignaled;
use function pcntl_wtermsig;
use function posix_get_last_error;
use function posix_kill;
use function posix_strerror;
use function serialize;
use function stream_select;
use function stream_set_blocking;
use function stream_socket_pair;
use function stripos;
use function strlen;
use function strpos;
use function substr;
use function unserialize;
use function usleep;
use function version_compare;
use const PHP_EOL;
use const PHP_OS;
use const PHP_VERSION;
use const SIGALRM;
use const SIGTERM;
use const STREAM_IPPROTO_IP;
use const STREAM_PF_UNIX;
use const STREAM_SOCK_STREAM;
/**
 * Adapted with relatively few changes from
 * https://github.com/etsy/phan/blob/1ccbe7a43a6151ca7c0759d6c53e2c3686994e53/src/Phan/ForkPool.php
 *
 * Authors: https://github.com/morria, https://github.com/TysonAndre
 *
 * Fork off to n-processes and divide up tasks between
 * each process.
 *
 * @internal
 */
class Pool
{
    private const EXIT_SUCCESS = 0;
    private const EXIT_FAILURE = 1;
    private Config $config;
    /** @var int[] */
    private array $child_pid_list = [];
    /** @var resource[] */
    private array $read_streams = [];
    private bool $did_have_error = \false;
    /** @var ?Closure(mixed): void */
    private ?Closure $task_done_closure = null;
    public const MAC_PCRE_MESSAGE = 'Mac users: pcre.jit is set to 1 in your PHP config.' . PHP_EOL . 'The pcre jit is known to cause segfaults in PHP 7.3 on Macs, and Psalm' . PHP_EOL . 'will not execute in threaded mode to avoid indecipherable errors.' . PHP_EOL . 'Consider adding pcre.jit=0 to your PHP config, or upgrade to PHP 7.4.' . PHP_EOL . 'Relevant info: https://bugs.php.net/bug.php?id=77260';
    /**
     * @param array<int, array<int, mixed>> $process_task_data_iterator
     * An array of task data items to be divided up among the
     * workers. The size of this is the number of forked processes.
     * @param Closure $startup_closure
     * A closure to execute upon starting a child
     * @param Closure(int, mixed):mixed $task_closure
     * A method to execute on each task data.
     * This closure must return an array (to be gathered).
     * @param Closure():mixed $shutdown_closure
     * A closure to execute upon shutting down a child
     * @param Closure(mixed $data):void $task_done_closure
     * A closure to execute when a task is done
     * @psalm-suppress MixedAssignment
     */
    public function __construct(Config $config, array $process_task_data_iterator, Closure $startup_closure, Closure $task_closure, Closure $shutdown_closure, ?Closure $task_done_closure = null)
    {
        $pool_size = count($process_task_data_iterator);
        $this->task_done_closure = $task_done_closure;
        $this->config = $config;
        assert($pool_size > 1, 'The pool size must be >= 2 to use the fork pool.');
        if (!extension_loaded('pcntl') || !extension_loaded('posix')) {
            echo 'The pcntl & posix extensions must be loaded in order for Psalm to be able to use multiple processes.' . PHP_EOL;
            exit(1);
        }
        $disabled_functions = array_map('trim', explode(',', ini_get('disable_functions')));
        if (in_array('pcntl_fork', $disabled_functions)) {
            echo "pcntl_fork() is disabled by php configuration (disable_functions directive).\n" . "Please enable it or run Psalm single-threaded with --threads=1 cli switch.\n";
            exit(1);
        }
        if (ini_get('pcre.jit') === '1' && PHP_OS === 'Darwin' && version_compare(PHP_VERSION, '7.3.0') >= 0 && version_compare(PHP_VERSION, '7.4.0') < 0) {
            die(self::MAC_PCRE_MESSAGE . PHP_EOL);
        }
        // We'll keep track of if this is the parent process
        // so that we can tell who will be doing the waiting
        $is_parent = \false;
        $sockets = [];
        // Fork as many times as requested to get the given
        // pool size
        for ($proc_id = 0; $proc_id < $pool_size; ++$proc_id) {
            // Create an IPC socket pair.
            $sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
            if (!$sockets) {
                error_log('unable to create stream socket pair');
                exit(self::EXIT_FAILURE);
            }
            // Fork
            if (($pid = pcntl_fork()) < 0) {
                error_log(posix_strerror(posix_get_last_error()));
                exit(self::EXIT_FAILURE);
            }
            // Parent
            if ($pid > 0) {
                $is_parent = \true;
                $this->child_pid_list[] = $pid;
                $this->read_streams[] = self::streamForParent($sockets);
                continue;
            }
            // Child
            if ($pid === 0) {
                $is_parent = \false;
                break;
            }
        }
        // If we're the parent, return
        if ($is_parent) {
            return;
        }
        // Get the write stream for the child.
        $write_stream = self::streamForChild($sockets);
        // Execute anything the children wanted to execute upon
        // starting up
        $startup_closure();
        // Get the work for this process
        $task_data_iterator = array_values($process_task_data_iterator)[$proc_id];
        $task_done_buffer = '';
        try {
            foreach ($task_data_iterator as $i => $task_data) {
                $task_result = $task_closure($i, $task_data);
                $task_done_message = new \Psalm\Internal\Fork\ForkTaskDoneMessage($task_result);
                if ($this->config->use_igbinary) {
                    $encoded_message = base64_encode(igbinary_serialize($task_done_message));
                } else {
                    $encoded_message = base64_encode(serialize($task_done_message));
                }
                $serialized_message = $task_done_buffer . $encoded_message . "\n";
                if (strlen($serialized_message) > 200) {
                    $bytes_written = @fwrite($write_stream, $serialized_message);
                    if (strlen($serialized_message) !== $bytes_written) {
                        $task_done_buffer = substr($serialized_message, $bytes_written);
                    } else {
                        $task_done_buffer = '';
                    }
                } else {
                    $task_done_buffer = $serialized_message;
                }
            }
            // Execute each child's shutdown closure before
            // exiting the process
            $results = $shutdown_closure();
            // Serialize this child's produced results and send them to the parent.
            $process_done_message = new \Psalm\Internal\Fork\ForkProcessDoneMessage($results ?: []);
        } catch (Throwable $t) {
            // This can happen when developing Psalm from source without running `composer update`,
            // or because of rare bugs in Psalm.
            $process_done_message = new \Psalm\Internal\Fork\ForkProcessErrorMessage(get_class($t) . ' ' . $t->getMessage() . "\n" . "Emitted in " . $t->getFile() . ":" . $t->getLine() . "\n" . "Stack trace in the forked worker:\n" . $t->getTraceAsString());
        }
        if ($this->config->use_igbinary) {
            $encoded_message = base64_encode(igbinary_serialize($process_done_message));
        } else {
            $encoded_message = base64_encode(serialize($process_done_message));
        }
        $serialized_message = $task_done_buffer . $encoded_message . "\n";
        $bytes_to_write = strlen($serialized_message);
        $bytes_written = 0;
        while ($bytes_written < $bytes_to_write && !feof($write_stream)) {
            // attempt to write the remaining unsent part
            $bytes_written += @fwrite($write_stream, substr($serialized_message, $bytes_written));
            if ($bytes_written < $bytes_to_write) {
                // wait a bit
                usleep(500000);
            }
        }
        fclose($write_stream);
        // Children exit after completing their work
        exit(self::EXIT_SUCCESS);
    }
    /**
     * Prepare the socket pair to be used in a parent process and
     * return the stream the parent will use to read results.
     *
     * @param resource[] $sockets the socket pair for IPC
     * @return resource
     */
    private static function streamForParent(array $sockets)
    {
        [$for_read, $for_write] = $sockets;
        // The parent will not use the write channel, so it
        // must be closed to prevent deadlock.
        fclose($for_write);
        // stream_select will be used to read multiple streams, so these
        // must be set to non-blocking mode.
        if (!stream_set_blocking($for_read, \false)) {
            error_log('unable to set read stream to non-blocking');
            exit(self::EXIT_FAILURE);
        }
        return $for_read;
    }
    /**
     * Prepare the socket pair to be used in a child process and return
     * the stream the child will use to write results.
     *
     * @param resource[] $sockets the socket pair for IPC
     * @return resource
     */
    private static function streamForChild(array $sockets)
    {
        [$for_read, $for_write] = $sockets;
        // The while will not use the read channel, so it must
        // be closed to prevent deadlock.
        fclose($for_read);
        return $for_write;
    }
    /**
     * Read the results that each child process has serialized on their write streams.
     * The results are returned in an array, one for each worker. The order of the results
     * is not maintained.
     *
     * @psalm-suppress MixedAssignment
     * @return list<mixed>
     */
    private function readResultsFromChildren() : array
    {
        // Create an array of all active streams, indexed by
        // resource id.
        $streams = [];
        foreach ($this->read_streams as $stream) {
            $streams[(int) $stream] = $stream;
        }
        // Create an array for the content received on each stream,
        // indexed by resource id.
        $content = array_fill_keys(array_keys($streams), '');
        $terminationMessages = [];
        // Read the data off of all the stream.
        while (count($streams) > 0) {
            $needs_read = array_values($streams);
            $needs_write = null;
            $needs_except = null;
            // Wait for data on at least one stream.
            $num = @stream_select($needs_read, $needs_write, $needs_except, null);
            if ($num === \false) {
                $err = error_get_last();
                // stream_select returns false when the `select` system call is interrupted by an incoming signal
                if (isset($err['message']) && stripos($err['message'], 'interrupted system call') === \false) {
                    error_log('unable to select on read stream');
                    exit(self::EXIT_FAILURE);
                }
                continue;
            }
            // For each stream that was ready, read the content.
            foreach ($needs_read as $file) {
                $buffer = fread($file, 1024);
                if ($buffer !== \false) {
                    $content[(int) $file] .= $buffer;
                }
                if (strpos($buffer, "\n") !== \false) {
                    $serialized_messages = explode("\n", $content[(int) $file]);
                    $content[(int) $file] = array_pop($serialized_messages);
                    foreach ($serialized_messages as $serialized_message) {
                        if ($this->config->use_igbinary) {
                            $message = igbinary_unserialize(base64_decode($serialized_message, \true));
                        } else {
                            $message = unserialize(base64_decode($serialized_message, \true));
                        }
                        if ($message instanceof \Psalm\Internal\Fork\ForkProcessDoneMessage) {
                            $terminationMessages[] = $message->data;
                        } elseif ($message instanceof \Psalm\Internal\Fork\ForkTaskDoneMessage) {
                            if ($this->task_done_closure !== null) {
                                ($this->task_done_closure)($message->data);
                            }
                        } elseif ($message instanceof \Psalm\Internal\Fork\ForkProcessErrorMessage) {
                            // Kill all children
                            foreach ($this->child_pid_list as $child_pid) {
                                /**
                                 * SIGTERM does not exist on windows
                                 *
                                 * @psalm-suppress UnusedPsalmSuppress
                                 * @psalm-suppress UndefinedConstant
                                 * @psalm-suppress MixedArgument
                                 */
                                posix_kill($child_pid, SIGTERM);
                            }
                            throw new Exception($message->message);
                        } else {
                            error_log('Child should return ForkMessage - response type=' . gettype($message));
                            $this->did_have_error = \true;
                        }
                    }
                }
                // If the stream has closed, stop trying to select on it.
                if (feof($file)) {
                    if ($content[(int) $file] !== '') {
                        error_log('Child did not send full message before closing the connection');
                        $this->did_have_error = \true;
                    }
                    fclose($file);
                    unset($streams[(int) $file]);
                }
            }
        }
        return $terminationMessages;
    }
    /**
     * Wait for all child processes to complete
     *
     * @return list<mixed>
     */
    public function wait() : array
    {
        $ignore_return_code = \false;
        try {
            // Read all the streams from child processes into an array.
            $content = $this->readResultsFromChildren();
        } catch (Throwable $e) {
            // If children were killed because one of them threw an exception we don't care about return codes.
            $ignore_return_code = \true;
            // PHP guarantees finally is run even after throwing
            throw $e;
        } finally {
            // Wait for all children to return
            foreach ($this->child_pid_list as $child_pid) {
                $process_lookup = posix_kill($child_pid, 0);
                $status = 0;
                if ($process_lookup) {
                    /**
                     * SIGALRM does not exist on windows
                     *
                     * @psalm-suppress UnusedPsalmSuppress
                     * @psalm-suppress UndefinedConstant
                     * @psalm-suppress MixedArgument
                     */
                    posix_kill($child_pid, SIGALRM);
                    if (pcntl_waitpid($child_pid, $status) < 0) {
                        error_log(posix_strerror(posix_get_last_error()));
                    }
                }
                // Check to see if the child died a graceful death
                if (!$ignore_return_code && pcntl_wifsignaled($status)) {
                    $return_code = pcntl_wexitstatus($status);
                    $term_sig = pcntl_wtermsig($status);
                    /**
                     * SIGALRM does not exist on windows
                     *
                     * @psalm-suppress UnusedPsalmSuppress
                     * @psalm-suppress UndefinedConstant
                     */
                    if ($term_sig !== SIGALRM) {
                        $this->did_have_error = \true;
                        error_log("Child terminated with return code {$return_code} and signal {$term_sig}");
                    }
                }
            }
        }
        return $content;
    }
    /**
     * Returns true if this had an error, e.g. due to memory limits or due to a child process crashing.
     */
    public function didHaveError() : bool
    {
        return $this->did_have_error;
    }
}
<?php

namespace Psalm\Internal\Fork;

use _HumbugBox1cb33d1f20f1\Composer\XdebugHandler\XdebugHandler;
use function array_filter;
use function extension_loaded;
use function file_get_contents;
use function file_put_contents;
use function implode;
use function preg_replace;
/**
 * @internal
 */
class PsalmRestarter extends XdebugHandler
{
    private bool $required = \false;
    /**
     * @var string[]
     */
    private array $disabledExtensions = [];
    public function disableExtension(string $disabledExtension) : void
    {
        $this->disabledExtensions[] = $disabledExtension;
    }
    /**
     * No type hint to allow xdebug-handler v1 and v2 usage
     *
     * @param bool $default
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
     */
    protected function requiresRestart($default) : bool
    {
        $this->required = (bool) array_filter($this->disabledExtensions, static fn(string $extension): bool => extension_loaded($extension));
        return $default || $this->required;
    }
    /**
     * No type hint to allow xdebug-handler v1 and v2 usage
     *
     * @param string|string[] $command
     */
    protected function restart($command) : void
    {
        if ($this->required && $this->tmpIni) {
            $regex = '/^\\s*(extension\\s*=.*(' . implode('|', $this->disabledExtensions) . ').*)$/mi';
            $content = file_get_contents($this->tmpIni);
            $content = preg_replace($regex, ';$1', $content);
            file_put_contents($this->tmpIni, $content);
        }
        /** @psalm-suppress PossiblyInvalidArgument */
        parent::restart($command);
    }
}
<?php

namespace Psalm\Internal\Fork;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class ForkTaskDoneMessage implements \Psalm\Internal\Fork\ForkMessage
{
    use ImmutableNonCloneableTrait;
    /** @var mixed */
    public $data;
    /**
     * @param mixed $data
     */
    public function __construct($data)
    {
        $this->data = $data;
    }
}
<?php

namespace Psalm\Internal\Fork;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class ForkProcessErrorMessage implements \Psalm\Internal\Fork\ForkMessage
{
    use ImmutableNonCloneableTrait;
    public string $message;
    public function __construct(string $message)
    {
        $this->message = $message;
    }
}
<?php

namespace Psalm\Internal\Fork;

interface ForkMessage
{
}
<?php

namespace Psalm\Internal\ExecutionEnvironment;

use Psalm\SourceControl\Git\CommitInfo;
use Psalm\SourceControl\Git\GitInfo;
use function explode;
use function file_get_contents;
use function json_decode;
use function str_replace;
use function strpos;
use function strtotime;
use const JSON_THROW_ON_ERROR;
/**
 * Environment variables collector for CI environment.
 *
 * @author Kitamura Satoshi <with.no.parachute@gmail.com>
 * @internal
 */
class BuildInfoCollector
{
    /**
     * Environment variables.
     *
     * Overwritten through collection process.
     */
    protected array $env;
    /**
     * Read environment variables.
     */
    protected array $readEnv = [];
    public function __construct(array $env)
    {
        $this->env = $env;
    }
    // API
    /**
     * Collect environment variables.
     */
    public function collect() : array
    {
        $this->readEnv = [];
        $this->fillTravisCi()->fillCircleCi()->fillAppVeyor()->fillJenkins()->fillScrutinizer()->fillGithubActions();
        return $this->readEnv;
    }
    // internal method
    /**
     * Fill Travis CI environment variables.
     *
     * "TRAVIS", "TRAVIS_JOB_ID" must be set.
     *
     * @return $this
     * @psalm-suppress PossiblyUndefinedStringArrayOffset
     */
    protected function fillTravisCi() : self
    {
        if (isset($this->env['TRAVIS']) && $this->env['TRAVIS'] && isset($this->env['TRAVIS_JOB_ID'])) {
            $this->readEnv['CI_JOB_ID'] = $this->env['TRAVIS_JOB_ID'];
            $this->env['CI_NAME'] = 'travis-ci';
            // backup
            $this->readEnv['TRAVIS'] = $this->env['TRAVIS'];
            $this->readEnv['TRAVIS_JOB_ID'] = $this->env['TRAVIS_JOB_ID'];
            $this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
            $this->readEnv['TRAVIS_TAG'] = $this->env['TRAVIS_TAG'] ?? '';
            $repo_slug = (string) $this->env['TRAVIS_REPO_SLUG'];
            if ($repo_slug) {
                $slug_parts = explode('/', $repo_slug);
                $this->readEnv['CI_REPO_OWNER'] = $slug_parts[0];
                $this->readEnv['CI_REPO_NAME'] = $slug_parts[1];
            }
            $pr_slug = (string) ($this->env['TRAVIS_PULL_REQUEST_SLUG'] ?? '');
            if ($pr_slug) {
                $slug_parts = explode('/', $pr_slug);
                $this->readEnv['CI_PR_REPO_OWNER'] = $slug_parts[0];
                $this->readEnv['CI_PR_REPO_NAME'] = $slug_parts[1];
            }
            $this->readEnv['CI_PR_NUMBER'] = $this->env['TRAVIS_PULL_REQUEST'];
            $this->readEnv['CI_BRANCH'] = $this->env['TRAVIS_BRANCH'];
        }
        return $this;
    }
    /**
     * Fill CircleCI environment variables.
     *
     * "CIRCLECI", "CIRCLE_BUILD_NUM" must be set.
     *
     * @return $this
     */
    protected function fillCircleCi() : self
    {
        if (isset($this->env['CIRCLECI']) && $this->env['CIRCLECI'] && isset($this->env['CIRCLE_BUILD_NUM'])) {
            $this->env['CI_BUILD_NUMBER'] = $this->env['CIRCLE_BUILD_NUM'];
            $this->env['CI_NAME'] = 'circleci';
            // backup
            $this->readEnv['CIRCLECI'] = $this->env['CIRCLECI'];
            $this->readEnv['CIRCLE_BUILD_NUM'] = $this->env['CIRCLE_BUILD_NUM'];
            $this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
            $this->readEnv['CI_PR_REPO_OWNER'] = $this->env['CIRCLE_PR_USERNAME'] ?? null;
            $this->readEnv['CI_PR_REPO_NAME'] = $this->env['CIRCLE_PR_REPONAME'] ?? null;
            $this->readEnv['CI_REPO_OWNER'] = $this->env['CIRCLE_PROJECT_USERNAME'] ?? null;
            $this->readEnv['CI_REPO_NAME'] = $this->env['CIRCLE_PROJECT_REPONAME'] ?? null;
            $this->readEnv['CI_PR_NUMBER'] = $this->env['CIRCLE_PR_NUMBER'] ?? null;
            $this->readEnv['CI_BRANCH'] = $this->env['CIRCLE_BRANCH'] ?? null;
        }
        return $this;
    }
    /**
     * Fill AppVeyor environment variables.
     *
     * "APPVEYOR", "APPVEYOR_BUILD_NUMBER" must be set.
     *
     * @psalm-suppress PossiblyUndefinedStringArrayOffset
     * @return $this
     */
    protected function fillAppVeyor() : self
    {
        if (isset($this->env['APPVEYOR']) && $this->env['APPVEYOR'] && isset($this->env['APPVEYOR_BUILD_NUMBER'])) {
            $this->readEnv['CI_BUILD_NUMBER'] = $this->env['APPVEYOR_BUILD_NUMBER'];
            $this->readEnv['CI_JOB_ID'] = $this->env['APPVEYOR_JOB_NUMBER'];
            $this->readEnv['CI_PR_NUMBER'] = $this->env['APPVEYOR_PULL_REQUEST_NUMBER'] ?? '';
            $this->env['CI_NAME'] = 'AppVeyor';
            // backup
            $this->readEnv['APPVEYOR'] = $this->env['APPVEYOR'];
            $this->readEnv['APPVEYOR_BUILD_NUMBER'] = $this->env['APPVEYOR_BUILD_NUMBER'];
            $this->readEnv['APPVEYOR_JOB_NUMBER'] = $this->env['APPVEYOR_JOB_NUMBER'];
            $this->readEnv['APPVEYOR_REPO_BRANCH'] = $this->env['APPVEYOR_REPO_BRANCH'];
            $this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
            $repo_slug = (string) ($this->env['APPVEYOR_REPO_NAME'] ?? '');
            if ($repo_slug) {
                $slug_parts = explode('/', $repo_slug);
                $this->readEnv['CI_REPO_OWNER'] = $slug_parts[0];
                $this->readEnv['CI_REPO_NAME'] = $slug_parts[1];
            }
            $pr_slug = (string) ($this->env['APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME'] ?? '');
            if ($pr_slug) {
                $slug_parts = explode('/', $pr_slug);
                $this->readEnv['CI_PR_REPO_OWNER'] = $slug_parts[0];
                $this->readEnv['CI_PR_REPO_NAME'] = $slug_parts[1];
            }
            $this->readEnv['CI_BRANCH'] = $this->env['APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH'] ?? $this->env['APPVEYOR_REPO_BRANCH'];
        }
        return $this;
    }
    /**
     * Fill Jenkins environment variables.
     *
     * "JENKINS_URL", "BUILD_NUMBER" must be set.
     *
     * @return $this
     */
    protected function fillJenkins() : self
    {
        if (isset($this->env['JENKINS_URL']) && isset($this->env['BUILD_NUMBER'])) {
            $this->readEnv['CI_BUILD_NUMBER'] = $this->env['BUILD_NUMBER'];
            $this->readEnv['CI_BUILD_URL'] = $this->env['JENKINS_URL'];
            $this->env['CI_NAME'] = 'jenkins';
            // backup
            $this->readEnv['BUILD_NUMBER'] = $this->env['BUILD_NUMBER'];
            $this->readEnv['JENKINS_URL'] = $this->env['JENKINS_URL'];
            $this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
        }
        return $this;
    }
    /**
     * Fill Scrutinizer environment variables.
     *
     * "JENKINS_URL", "BUILD_NUMBER" must be set.
     *
     * @psalm-suppress PossiblyUndefinedStringArrayOffset
     * @return $this
     */
    protected function fillScrutinizer() : self
    {
        if (isset($this->env['SCRUTINIZER']) && $this->env['SCRUTINIZER']) {
            $this->readEnv['CI_JOB_ID'] = $this->env['SCRUTINIZER_INSPECTION_UUID'];
            $this->readEnv['CI_BRANCH'] = $this->env['SCRUTINIZER_BRANCH'];
            $this->readEnv['CI_PR_NUMBER'] = $this->env['SCRUTINIZER_PR_NUMBER'] ?? '';
            // backup
            $this->readEnv['CI_NAME'] = 'Scrutinizer';
            $repo_slug = (string) ($this->env['SCRUTINIZER_PROJECT'] ?? '');
            if ($repo_slug) {
                $slug_parts = explode('/', $repo_slug);
                if ($this->readEnv['CI_PR_NUMBER']) {
                    $this->readEnv['CI_PR_REPO_OWNER'] = $slug_parts[1];
                    $this->readEnv['CI_PR_REPO_NAME'] = $slug_parts[2];
                } else {
                    $this->readEnv['CI_REPO_OWNER'] = $slug_parts[1];
                    $this->readEnv['CI_REPO_NAME'] = $slug_parts[2];
                }
            }
        }
        return $this;
    }
    /**
     * Fill Github Actions environment variables.
     *
     * @return $this
     * @psalm-suppress PossiblyUndefinedStringArrayOffset
     */
    protected function fillGithubActions() : \Psalm\Internal\ExecutionEnvironment\BuildInfoCollector
    {
        if (isset($this->env['GITHUB_ACTIONS'])) {
            $this->env['CI_NAME'] = 'github-actions';
            $this->env['CI_JOB_ID'] = $this->env['GITHUB_ACTIONS'];
            $githubRef = (string) $this->env['GITHUB_REF'];
            if (strpos($githubRef, 'refs/heads/') !== \false) {
                $githubRef = str_replace('refs/heads/', '', $githubRef);
            } elseif (strpos($githubRef, 'refs/tags/') !== \false) {
                $githubRef = str_replace('refs/tags/', '', $githubRef);
            }
            $this->env['CI_BRANCH'] = $githubRef;
            $this->readEnv['GITHUB_ACTIONS'] = $this->env['GITHUB_ACTIONS'];
            $this->readEnv['GITHUB_REF'] = $this->env['GITHUB_REF'];
            $this->readEnv['CI_NAME'] = $this->env['CI_NAME'];
            $this->readEnv['CI_BRANCH'] = $this->env['CI_BRANCH'];
            $slug_parts = explode('/', (string) $this->env['GITHUB_REPOSITORY']);
            $this->readEnv['CI_REPO_OWNER'] = $slug_parts[0];
            $this->readEnv['CI_REPO_NAME'] = $slug_parts[1];
            if (isset($this->env['GITHUB_EVENT_PATH'])) {
                $event_json = file_get_contents((string) $this->env['GITHUB_EVENT_PATH']);
                /** @var array */
                $event_data = json_decode($event_json, \true, 512, JSON_THROW_ON_ERROR);
                if (isset($event_data['head_commit'])) {
                    /**
                     * @var array{
                     *    id: string,
                     *    author: array{name: string, email: string},
                     *    committer: array{name: string, email: string},
                     *    message: string,
                     *    timestamp: string
                     * }
                     */
                    $head_commit_data = $event_data['head_commit'];
                    $gitinfo = new GitInfo($githubRef, (new CommitInfo())->setId($head_commit_data['id'])->setAuthorName($head_commit_data['author']['name'])->setAuthorEmail($head_commit_data['author']['email'])->setCommitterName($head_commit_data['committer']['name'])->setCommitterEmail($head_commit_data['committer']['email'])->setMessage($head_commit_data['message'])->setDate(strtotime($head_commit_data['timestamp'])), []);
                    $this->readEnv['git'] = $gitinfo->toArray();
                }
                if ($this->env['GITHUB_EVENT_PATH'] === 'pull_request') {
                    $this->readEnv['CI_PR_NUMBER'] = $event_data['number'];
                }
            }
        }
        return $this;
    }
}
<?php

namespace Psalm\Internal\ExecutionEnvironment;

use RuntimeException;
use function exec;
use function function_exists;
use function sprintf;
/**
 * @author Kitamura Satoshi <with.no.parachute@gmail.com>
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 * @internal
 */
final class SystemCommandExecutor
{
    /**
     * Execute command.
     *
     * @throws RuntimeException
     * @return string[]
     */
    public function execute(string $command) : array
    {
        if (!function_exists('exec')) {
            throw new RuntimeException(sprintf('exec does not exist, failed to execute command: %s', $command));
        }
        exec($command, $result, $returnValue);
        if ($returnValue === 0) {
            /** @var string[] */
            return $result;
        }
        throw new RuntimeException(sprintf('Failed to execute command: %s', $command), $returnValue);
    }
}
<?php

namespace Psalm\Internal\ExecutionEnvironment;

use Psalm\SourceControl\Git\CommitInfo;
use Psalm\SourceControl\Git\GitInfo;
use Psalm\SourceControl\Git\RemoteInfo;
use RuntimeException;
use function array_keys;
use function array_unique;
use function count;
use function explode;
use function range;
use function strpos;
use function trim;
/**
 * Git repository info collector.
 *
 * @author Kitamura Satoshi <with.no.parachute@gmail.com>
 * @internal
 */
class GitInfoCollector
{
    /**
     * Git command.
     */
    protected \Psalm\Internal\ExecutionEnvironment\SystemCommandExecutor $executor;
    /**
     * Constructor.
     */
    public function __construct()
    {
        $this->executor = new \Psalm\Internal\ExecutionEnvironment\SystemCommandExecutor();
    }
    // API
    /**
     * Collect git repository info.
     */
    public function collect() : GitInfo
    {
        $branch = $this->collectBranch();
        $commit = $this->collectCommit();
        $remotes = $this->collectRemotes();
        return new GitInfo($branch, $commit, $remotes);
    }
    /**
     * Collect branch name.
     *
     * @throws RuntimeException
     */
    protected function collectBranch() : string
    {
        $branchesResult = $this->executor->execute('git branch');
        foreach ($branchesResult as $result) {
            if (strpos($result, '* ') === 0) {
                $exploded = explode('* ', $result, 2);
                return $exploded[1];
            }
        }
        throw new RuntimeException();
    }
    /**
     * Collect commit info.
     *
     * @throws RuntimeException
     */
    protected function collectCommit() : CommitInfo
    {
        $commitResult = $this->executor->execute('git log -1 --pretty=format:%H%n%aN%n%ae%n%cN%n%ce%n%s%n%at');
        if (count($commitResult) !== 7 || array_keys($commitResult) !== range(0, 6)) {
            throw new RuntimeException();
        }
        $commit = new CommitInfo();
        return $commit->setId(trim($commitResult[0]))->setAuthorName(trim($commitResult[1]))->setAuthorEmail(trim($commitResult[2]))->setCommitterName(trim($commitResult[3]))->setCommitterEmail(trim($commitResult[4]))->setMessage($commitResult[5])->setDate((int) $commitResult[6]);
    }
    /**
     * Collect remotes info.
     *
     * @throws RuntimeException
     * @return list<RemoteInfo>
     */
    protected function collectRemotes() : array
    {
        $remotesResult = $this->executor->execute('git remote -v');
        if (count($remotesResult) === 0) {
            throw new RuntimeException();
        }
        // parse command result
        $results = [];
        foreach ($remotesResult as $result) {
            if (strpos($result, ' ') !== \false) {
                [$remote] = explode(' ', $result, 2);
                $results[] = $remote;
            }
        }
        // filter
        $results = array_unique($results);
        // create Remote instances
        $remotes = [];
        foreach ($results as $result) {
            if (strpos($result, "\t") !== \false) {
                [$name, $url] = explode("\t", $result, 2);
                $remote = new RemoteInfo();
                $remotes[] = $remote->setName(trim($name))->setUrl(trim($url));
            }
        }
        return $remotes;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNonEmptyMixed;
use Psalm\Type\Union;
use function count;
use function is_int;
/**
 * @internal
 */
class UnsetAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Unset_ $stmt, Context $context) : void
    {
        $context->inside_unset = \true;
        foreach ($stmt->vars as $var) {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            \Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze($statements_analyzer, $var, $context);
            $context->inside_general_use = $was_inside_general_use;
            $var_id = ExpressionIdentifier::getExtendedVarId($var, $statements_analyzer->getFQCLN(), $statements_analyzer);
            if ($var_id) {
                $context->remove($var_id);
                unset($context->references_possibly_from_confusing_scope[$var_id]);
            }
            if ($var instanceof PhpParser\Node\Expr\ArrayDimFetch && $var->dim) {
                $root_var_id = ExpressionIdentifier::getExtendedVarId($var->var, $statements_analyzer->getFQCLN(), $statements_analyzer);
                $key_type = $statements_analyzer->node_data->getType($var->dim);
                if ($root_var_id && isset($context->vars_in_scope[$root_var_id]) && $key_type) {
                    $root_types = [];
                    foreach ($context->vars_in_scope[$root_var_id]->getAtomicTypes() as $atomic_root_type) {
                        if ($atomic_root_type instanceof TList) {
                            $atomic_root_type = $atomic_root_type->getKeyedArray();
                        }
                        if ($atomic_root_type instanceof TKeyedArray) {
                            $key_value = null;
                            if ($key_type->isSingleIntLiteral()) {
                                $key_value = $key_type->getSingleIntLiteral()->value;
                            } elseif ($key_type->isSingleStringLiteral()) {
                                $key_value = $key_type->getSingleStringLiteral()->value;
                            }
                            if ($key_value !== null) {
                                $properties = $atomic_root_type->properties;
                                $is_list = $atomic_root_type->is_list;
                                $list_key = null;
                                if ($atomic_root_type->fallback_params) {
                                    $is_list = \false;
                                } elseif (isset($properties[$key_value])) {
                                    if ($is_list && $key_value !== count($properties) - 1) {
                                        $is_list = \false;
                                    }
                                }
                                unset($properties[$key_value]);
                                if ($atomic_root_type->is_list && !$is_list && is_int($key_value)) {
                                    if ($key_value === 0) {
                                        $list_key = new Union([new TIntRange(1, null)]);
                                    } elseif ($key_value === 1) {
                                        $list_key = new Union([new TLiteralInt(0), new TIntRange(2, null)]);
                                    } else {
                                        $list_key = new Union([new TIntRange(0, $key_value - 1), new TIntRange($key_value + 1, null)]);
                                    }
                                }
                                if (!$properties) {
                                    if ($atomic_root_type->fallback_params) {
                                        $root_types[] = new TArray([$list_key ?? $atomic_root_type->fallback_params[0], $atomic_root_type->fallback_params[1]]);
                                    } else {
                                        $root_types[] = new TArray([new Union([new TNever()]), new Union([new TNever()])]);
                                    }
                                } else {
                                    $root_types[] = new TKeyedArray($properties, null, $atomic_root_type->fallback_params ? [$list_key ?? $atomic_root_type->fallback_params[0], $atomic_root_type->fallback_params[1]] : null, $is_list);
                                }
                            } else {
                                $properties = [];
                                foreach ($atomic_root_type->properties as $key => $type) {
                                    $properties[$key] = $type->setPossiblyUndefined(\true);
                                }
                                $root_types[] = new TKeyedArray($properties, null, $atomic_root_type->fallback_params, \false);
                            }
                        } elseif ($atomic_root_type instanceof TNonEmptyArray) {
                            $root_types[] = new TArray($atomic_root_type->type_params);
                        } elseif ($atomic_root_type instanceof TNonEmptyMixed) {
                            $root_types[] = new TMixed();
                        } else {
                            $root_types[] = $atomic_root_type;
                        }
                    }
                    $context->vars_in_scope[$root_var_id] = new Union($root_types);
                    $context->removeVarFromConflictingClauses($root_var_id, $context->vars_in_scope[$root_var_id], $statements_analyzer);
                }
            }
        }
        $context->inside_unset = \false;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\InvalidThrow;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
/**
 * @internal
 */
class ThrowAnalyzer
{
    /**
     * @param PhpParser\Node\Stmt\Throw_|PhpParser\Node\Expr\Throw_ $stmt
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node $stmt, Context $context) : bool
    {
        $context->inside_throw = \true;
        if (\Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            $context->has_returned = \true;
            return \false;
        }
        $context->inside_throw = \false;
        $context->has_returned = \true;
        if ($context->finally_scope) {
            foreach ($context->vars_in_scope as $var_id => &$type) {
                if (isset($context->finally_scope->vars_in_scope[$var_id])) {
                    $context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes($context->finally_scope->vars_in_scope[$var_id], $type, $statements_analyzer->getCodebase());
                } else {
                    $type = $type->setPossiblyUndefined(\true, \true);
                    $context->finally_scope->vars_in_scope[$var_id] = $type;
                }
            }
        }
        if ($context->check_classes && ($throw_type = $statements_analyzer->node_data->getType($stmt->expr)) && !$throw_type->hasMixed()) {
            $exception_type = new Union([new TNamedObject('Exception'), new TNamedObject('Throwable')]);
            $file_analyzer = $statements_analyzer->getFileAnalyzer();
            $codebase = $statements_analyzer->getCodebase();
            foreach ($throw_type->getAtomicTypes() as $throw_type_part) {
                $throw_type_candidate = new Union([$throw_type_part]);
                if (!UnionTypeComparator::isContainedBy($codebase, $throw_type_candidate, $exception_type)) {
                    if (IssueBuffer::accepts(new InvalidThrow('Cannot throw ' . $throw_type_part . ' as it does not extend Exception or implement Throwable', new CodeLocation($file_analyzer, $stmt), (string) $throw_type_part), $statements_analyzer->getSuppressedIssues())) {
                        return \false;
                    }
                } elseif (!$context->isSuppressingExceptions($statements_analyzer)) {
                    $codelocation = new CodeLocation($file_analyzer, $stmt);
                    $hash = $codelocation->getHash();
                    foreach ($throw_type->getAtomicTypes() as $throw_atomic_type) {
                        if ($throw_atomic_type instanceof TNamedObject) {
                            $context->possibly_thrown_exceptions[$throw_atomic_type->value][$hash] = $codelocation;
                        }
                    }
                }
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\Throw_) {
            $statements_analyzer->node_data->setType($stmt, Type::getNever());
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Context;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\ReferenceConstraint;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ImpureStaticVariable;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\MissingDocblockType;
use Psalm\Issue\ReferenceConstraintViolation;
use Psalm\IssueBuffer;
use Psalm\Type;
use UnexpectedValueException;
use function is_string;
/**
 * @internal
 */
class StaticAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Static_ $stmt, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        if ($context->mutation_free) {
            IssueBuffer::maybeAdd(new ImpureStaticVariable('Cannot use a static variable in a mutation-free context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        foreach ($stmt->vars as $var) {
            if (!is_string($var->var->name)) {
                continue;
            }
            $var_id = '$' . $var->var->name;
            $doc_comment = $stmt->getDocComment();
            $comment_type = null;
            if ($doc_comment && ($parsed_docblock = $statements_analyzer->getParsedDocblock())) {
                $var_comments = [];
                try {
                    $var_comments = $codebase->config->disable_var_parsing ? [] : CommentAnalyzer::arrayToDocblocks($doc_comment, $parsed_docblock, $statements_analyzer->getSource(), $statements_analyzer->getSource()->getAliases(), $statements_analyzer->getSource()->getTemplateTypeMap());
                } catch (IncorrectDocblockException $e) {
                    IssueBuffer::maybeAdd(new MissingDocblockType($e->getMessage(), new CodeLocation($statements_analyzer, $var)));
                } catch (DocblockParseException $e) {
                    IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $var)));
                }
                foreach ($var_comments as $var_comment) {
                    if (!$var_comment->type) {
                        continue;
                    }
                    try {
                        $var_comment_type = TypeExpander::expandUnion($codebase, $var_comment->type, $context->self, $context->self, $statements_analyzer->getParentFQCLN());
                        $var_comment_type = $var_comment_type->setFromDocblock();
                        /** @psalm-suppress UnusedMethodCall */
                        $var_comment_type->check($statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $var), $statements_analyzer->getSuppressedIssues());
                        if ($codebase->alter_code && $var_comment->type_start && $var_comment->type_end && $var_comment->line_number) {
                            $type_location = new DocblockTypeLocation($statements_analyzer, $var_comment->type_start, $var_comment->type_end, $var_comment->line_number);
                            $codebase->classlikes->handleDocblockTypeInMigration($codebase, $statements_analyzer, $var_comment_type, $type_location, $context->calling_method_id);
                        }
                        if (!$var_comment->var_id || $var_comment->var_id === $var_id) {
                            $comment_type = $var_comment_type;
                            continue;
                        }
                        $context->vars_in_scope[$var_comment->var_id] = $var_comment_type;
                    } catch (UnexpectedValueException $e) {
                        IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer, $var)));
                    }
                }
                if ($comment_type) {
                    $context->byref_constraints[$var_id] = new ReferenceConstraint($comment_type);
                }
            }
            if ($var->default) {
                if (\Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze($statements_analyzer, $var->default, $context) === \false) {
                    return;
                }
                if ($comment_type && ($var_default_type = $statements_analyzer->node_data->getType($var->default)) && !UnionTypeComparator::isContainedBy($codebase, $var_default_type, $comment_type)) {
                    IssueBuffer::maybeAdd(new ReferenceConstraintViolation($var_id . ' of type ' . $comment_type->getId() . ' cannot be assigned type ' . $var_default_type->getId(), new CodeLocation($statements_analyzer, $var)));
                }
            }
            if ($context->check_variables) {
                $context->vars_in_scope[$var_id] = $comment_type ? $comment_type : Type::getMixed();
                $context->vars_possibly_in_scope[$var_id] = \true;
                $context->assigned_var_ids[$var_id] = (int) $stmt->getAttribute('startFilePos');
                $statements_analyzer->byref_uses[$var_id] = \true;
                $location = new CodeLocation($statements_analyzer, $var);
                $statements_analyzer->registerVariable($var_id, $location, $context->branch_point);
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\DocblockParseException;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\ClosureAnalyzer;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\FalsableReturnStatement;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\InvalidReturnStatement;
use Psalm\Issue\LessSpecificReturnStatement;
use Psalm\Issue\MixedReturnStatement;
use Psalm\Issue\MixedReturnTypeCoercion;
use Psalm\Issue\NoValue;
use Psalm\Issue\NullableReturnStatement;
use Psalm\IssueBuffer;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Union;
use function count;
use function explode;
use function implode;
use function reset;
use function strtolower;
/**
 * @internal
 */
class ReturnAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Return_ $stmt, Context $context) : void
    {
        $doc_comment = $stmt->getDocComment();
        $var_comments = [];
        $var_comment_type = null;
        $source = $statements_analyzer->getSource();
        $codebase = $statements_analyzer->getCodebase();
        if ($doc_comment && ($parsed_docblock = $statements_analyzer->getParsedDocblock())) {
            $file_storage_provider = $codebase->file_storage_provider;
            $file_storage = $file_storage_provider->get($statements_analyzer->getFilePath());
            try {
                $var_comments = $codebase->config->disable_var_parsing ? [] : CommentAnalyzer::arrayToDocblocks($doc_comment, $parsed_docblock, $statements_analyzer->getSource(), $statements_analyzer->getAliases(), $statements_analyzer->getTemplateTypeMap(), $file_storage->type_aliases);
            } catch (DocblockParseException $e) {
                IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($source, $stmt)));
            }
            foreach ($var_comments as $var_comment) {
                if (!$var_comment->type) {
                    continue;
                }
                $comment_type = TypeExpander::expandUnion($codebase, $var_comment->type, $context->self, $context->self, $statements_analyzer->getParentFQCLN());
                if ($codebase->alter_code && $var_comment->type_start && $var_comment->type_end && $var_comment->line_number) {
                    $type_location = new DocblockTypeLocation($statements_analyzer, $var_comment->type_start, $var_comment->type_end, $var_comment->line_number);
                    $codebase->classlikes->handleDocblockTypeInMigration($codebase, $statements_analyzer, $comment_type, $type_location, $context->calling_method_id);
                }
                if (!$var_comment->var_id) {
                    $var_comment_type = $comment_type;
                    continue;
                }
                if (isset($context->vars_in_scope[$var_comment->var_id])) {
                    $comment_type = $comment_type->setParentNodes($context->vars_in_scope[$var_comment->var_id]->parent_nodes);
                }
                $context->vars_in_scope[$var_comment->var_id] = $comment_type;
            }
        }
        if ($stmt->expr) {
            $context->inside_return = \true;
            if ($stmt->expr instanceof PhpParser\Node\Expr\Closure || $stmt->expr instanceof PhpParser\Node\Expr\ArrowFunction) {
                self::potentiallyInferTypesOnClosureFromParentReturnType($statements_analyzer, $stmt->expr, $context);
            }
            if (\Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                $context->inside_return = \false;
                $context->has_returned = \true;
                return;
            }
            $stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr);
            if ($var_comment_type) {
                $stmt_type = $var_comment_type;
                if ($stmt_expr_type && $stmt_expr_type->parent_nodes) {
                    $stmt_type = $stmt_type->setParentNodes($stmt_expr_type->parent_nodes);
                }
                $statements_analyzer->node_data->setType($stmt, $var_comment_type);
            } elseif ($stmt_expr_type) {
                $stmt_type = $stmt_expr_type;
                if ($stmt_type->isNever()) {
                    IssueBuffer::maybeAdd(new NoValue('All possible types for this return were invalidated - This may be dead code', new CodeLocation($source, $stmt)), $statements_analyzer->getSuppressedIssues());
                    $stmt_type = Type::getNever();
                }
                if ($stmt_type->isVoid()) {
                    $stmt_type = Type::getNull();
                }
            } else {
                $stmt_type = Type::getMixed();
            }
            $context->inside_return = \false;
        } else {
            $stmt_type = Type::getVoid();
        }
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
        if ($context->finally_scope) {
            foreach ($context->vars_in_scope as $var_id => &$type) {
                if (isset($context->finally_scope->vars_in_scope[$var_id])) {
                    $context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes($context->finally_scope->vars_in_scope[$var_id], $type, $statements_analyzer->getCodebase());
                } else {
                    $type = $type->setPossiblyUndefined(\true, \true);
                    $context->finally_scope->vars_in_scope[$var_id] = $type;
                }
            }
        }
        $context->has_returned = \true;
        if ($source instanceof FunctionLikeAnalyzer && !$source->getSource() instanceof TraitAnalyzer) {
            $source->addReturnTypes($context);
            $source->examineParamTypes($statements_analyzer, $context, $codebase, $stmt);
            $storage = $source->getFunctionLikeStorage($statements_analyzer);
            $cased_method_id = $source->getCorrectlyCasedMethodId();
            if ($stmt->expr && $storage->location) {
                $inferred_type = TypeExpander::expandUnion($codebase, $stmt_type, $source->getFQCLN(), $source->getFQCLN(), $source->getParentFQCLN());
                if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
                    self::handleTaints($statements_analyzer, $stmt, $cased_method_id, $inferred_type, $storage);
                }
                if ($storage instanceof MethodStorage && $context->self) {
                    $self_class = $context->self;
                    $declared_return_type = $codebase->methods->getMethodReturnType(MethodIdentifier::wrap($cased_method_id), $self_class, $statements_analyzer, null);
                } else {
                    $declared_return_type = $storage->return_type;
                }
                if ($declared_return_type && !$declared_return_type->hasMixed()) {
                    $local_return_type = $source->getLocalReturnType($declared_return_type, $storage instanceof MethodStorage && $storage->final);
                    if ($storage instanceof MethodStorage) {
                        [$fq_class_name, $method_name] = explode('::', $cased_method_id);
                        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
                        $found_generic_params = ClassTemplateParamCollector::collect($codebase, $class_storage, $class_storage, strtolower($method_name), null, \true);
                        if ($found_generic_params) {
                            foreach ($found_generic_params as $template_name => $_) {
                                unset($found_generic_params[$template_name][$fq_class_name]);
                            }
                            $local_return_type = TemplateInferredTypeReplacer::replace($local_return_type, new TemplateResult([], $found_generic_params), $codebase);
                        }
                    }
                    if ($local_return_type->isGenerator() && $storage->has_yield) {
                        return;
                    }
                    if ($stmt_type->hasMixed()) {
                        if ($local_return_type->isVoid() || $local_return_type->isNever()) {
                            if (IssueBuffer::accepts(new InvalidReturnStatement('No return values are expected for ' . $cased_method_id, new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues())) {
                                return;
                            }
                        }
                        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && !$source->getSource() instanceof TraitAnalyzer) {
                            $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
                        }
                        if ($stmt_type->isMixed()) {
                            $origin_locations = [];
                            if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                                foreach ($stmt_type->parent_nodes as $parent_node) {
                                    $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                                }
                            }
                            $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
                            $return_location = new CodeLocation($source, $stmt->expr);
                            if ($origin_location && $origin_location->getHash() === $return_location->getHash()) {
                                $origin_location = null;
                            }
                            IssueBuffer::maybeAdd(new MixedReturnStatement('Could not infer a return type', $return_location, $origin_location), $statements_analyzer->getSuppressedIssues());
                            return;
                        }
                        IssueBuffer::maybeAdd(new MixedReturnStatement('Possibly-mixed return value', new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                    }
                    if ($local_return_type->isMixed()) {
                        return;
                    }
                    if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && !$source->getSource() instanceof TraitAnalyzer) {
                        $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
                    }
                    if ($local_return_type->isVoid()) {
                        IssueBuffer::maybeAdd(new InvalidReturnStatement('No return values are expected for ' . $cased_method_id, new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                        return;
                    }
                    $union_comparison_results = new TypeComparisonResult();
                    if (!UnionTypeComparator::isContainedBy($codebase, $inferred_type, $local_return_type, \true, \true, $union_comparison_results)) {
                        // is the declared return type more specific than the inferred one?
                        if ($union_comparison_results->type_coerced) {
                            if ($union_comparison_results->type_coerced_from_mixed) {
                                if (!$union_comparison_results->type_coerced_from_as_mixed) {
                                    if ($inferred_type->hasMixed()) {
                                        IssueBuffer::maybeAdd(new MixedReturnStatement('Could not infer a return type', new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                                    } else {
                                        IssueBuffer::maybeAdd(new MixedReturnTypeCoercion('The type \'' . $stmt_type->getId() . '\' is more general than the' . ' declared return type \'' . $local_return_type->getId() . '\'' . ' for ' . $cased_method_id, new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                                    }
                                }
                            } else {
                                IssueBuffer::maybeAdd(new LessSpecificReturnStatement('The type \'' . $stmt_type->getId() . '\' is more general than the' . ' declared return type \'' . $local_return_type->getId() . '\'' . ' for ' . $cased_method_id, new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                            }
                            foreach ($local_return_type->getAtomicTypes() as $local_type_part) {
                                if ($local_type_part instanceof TClassString && $stmt->expr instanceof PhpParser\Node\Scalar\String_) {
                                    if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $stmt->expr->value, new CodeLocation($source, $stmt->expr), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true)) === \false) {
                                        return;
                                    }
                                } elseif ($local_type_part instanceof TArray && $stmt->expr instanceof PhpParser\Node\Expr\Array_) {
                                    $value_param = $local_type_part->type_params[1];
                                    foreach ($value_param->getAtomicTypes() as $local_array_type_part) {
                                        if ($local_array_type_part instanceof TClassString) {
                                            foreach ($stmt->expr->items as $item) {
                                                if ($item && $item->value instanceof PhpParser\Node\Scalar\String_) {
                                                    if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $item->value->value, new CodeLocation($source, $item->value), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true)) === \false) {
                                                        return;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        } else {
                            IssueBuffer::maybeAdd(new InvalidReturnStatement('The inferred type \'' . $inferred_type->getId() . '\' does not match the declared return ' . 'type \'' . $local_return_type->getId() . '\' for ' . $cased_method_id . ($union_comparison_results->missing_shape_fields ? ' due to additional array shape fields (' . implode(', ', $union_comparison_results->missing_shape_fields) . ')' : ''), new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                        }
                    }
                    if (!$stmt_type->ignore_nullable_issues && $inferred_type->isNullable() && !$local_return_type->isNullable() && !$local_return_type->hasTemplate()) {
                        IssueBuffer::maybeAdd(new NullableReturnStatement('The declared return type \'' . $local_return_type->getId() . '\' for ' . $cased_method_id . ' is not nullable, but the function returns \'' . $inferred_type->getId() . '\'', new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                    }
                    if (!$stmt_type->ignore_falsable_issues && $inferred_type->isFalsable() && !$local_return_type->isFalsable() && (!$local_return_type->hasBool() || $local_return_type->isTrue()) && !$local_return_type->hasScalar()) {
                        IssueBuffer::maybeAdd(new FalsableReturnStatement('The declared return type \'' . $local_return_type . '\' for ' . $cased_method_id . ' does not allow false, but the function returns \'' . $inferred_type . '\'', new CodeLocation($source, $stmt->expr)), $statements_analyzer->getSuppressedIssues());
                    }
                }
            } else {
                if ($storage->signature_return_type && !$storage->signature_return_type->isVoid() && !$storage->has_yield) {
                    IssueBuffer::maybeAdd(new InvalidReturnStatement('Empty return statement is not expected in ' . $cased_method_id, new CodeLocation($source, $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
    }
    private static function handleTaints(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Return_ $stmt, string $cased_method_id, Union $inferred_type, FunctionLikeStorage $storage) : void
    {
        if (!$statements_analyzer->data_flow_graph instanceof TaintFlowGraph || !$stmt->expr || !$storage->location) {
            return;
        }
        $method_node = DataFlowNode::getForMethodReturn(strtolower($cased_method_id), $cased_method_id, $storage->signature_return_type_location ?: $storage->location);
        $statements_analyzer->data_flow_graph->addNode($method_node);
        if ($inferred_type->parent_nodes) {
            foreach ($inferred_type->parent_nodes as $parent_node) {
                $statements_analyzer->data_flow_graph->addPath($parent_node, $method_node, 'return', $storage->added_taints, $storage->removed_taints);
            }
        }
    }
    /**
     * If a function returns a closure, we try to infer the param/return types of
     * the inner closure.
     *
     * @see \Psalm\Tests\ReturnTypeTest:756
     * @param PhpParser\Node\Expr\Closure|PhpParser\Node\Expr\ArrowFunction $expr
     */
    private static function potentiallyInferTypesOnClosureFromParentReturnType(StatementsAnalyzer $statements_analyzer, PhpParser\Node\FunctionLike $expr, Context $context) : void
    {
        // if not returning from inside of a function, return
        if (!$context->calling_method_id && !$context->calling_function_id) {
            return;
        }
        $closure_id = (new ClosureAnalyzer($expr, $statements_analyzer))->getClosureId();
        $closure_storage = $statements_analyzer->getCodebase()->getFunctionLikeStorage($statements_analyzer, $closure_id);
        $parent_fn_storage = $statements_analyzer->getCodebase()->getFunctionLikeStorage($statements_analyzer, $context->calling_function_id ?: $context->calling_method_id);
        if ($parent_fn_storage->return_type === null) {
            return;
        }
        // can't infer returned closure if the parent doesn't have a callable return type
        if (!$parent_fn_storage->return_type->hasCallableType()) {
            return;
        }
        // cannot infer if we have union/intersection types
        if (!$parent_fn_storage->return_type->isSingle()) {
            return;
        }
        /** @var TClosure|TCallable $parent_callable_return_type */
        $parent_callable_return_type = $parent_fn_storage->return_type->getSingleAtomic();
        if ($parent_callable_return_type->params === null && $parent_callable_return_type->return_type === null) {
            return;
        }
        foreach ($closure_storage->params as $key => $param) {
            $parent_param = $parent_callable_return_type->params[$key] ?? null;
            $param->type = self::inferInnerClosureTypeFromParent($statements_analyzer->getCodebase(), $param->type, $parent_param->type ?? null);
        }
        $closure_storage->return_type = self::inferInnerClosureTypeFromParent($statements_analyzer->getCodebase(), $closure_storage->return_type, $parent_callable_return_type->return_type);
    }
    /**
     * - If non parent type, do nothing
     * - If no return type, infer from parent
     * - If parent return type is more specific, infer from parent
     * - else, do nothing
     */
    private static function inferInnerClosureTypeFromParent(Codebase $codebase, ?Union $return_type, ?Union $parent_return_type) : ?Union
    {
        if (!$parent_return_type) {
            return $return_type;
        }
        if (!$return_type || UnionTypeComparator::isContainedBy($codebase, $parent_return_type, $return_type)) {
            return $parent_return_type;
        }
        return $return_type;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CastAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Issue\ForbiddenCode;
use Psalm\Issue\ImpureFunctionCall;
use Psalm\IssueBuffer;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\TaintKind;
/**
 * @internal
 */
class EchoAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Echo_ $stmt, Context $context) : bool
    {
        $echo_param = new FunctionLikeParameter('var', \false);
        $codebase = $statements_analyzer->getCodebase();
        foreach ($stmt->exprs as $i => $expr) {
            $context->inside_call = \true;
            \Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze($statements_analyzer, $expr, $context);
            $context->inside_call = \false;
            $expr_type = $statements_analyzer->node_data->getType($expr);
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
                if ($expr_type && $expr_type->hasObjectType()) {
                    $expr_type = CastAnalyzer::castStringAttempt($statements_analyzer, $context, $expr_type, $expr, \false);
                }
                $call_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                $echo_param_sink = TaintSink::getForMethodArgument('echo', 'echo', (int) $i, null, $call_location);
                $echo_param_sink->taints = [TaintKind::INPUT_HTML, TaintKind::INPUT_HAS_QUOTES, TaintKind::USER_SECRET, TaintKind::SYSTEM_SECRET];
                $statements_analyzer->data_flow_graph->addSink($echo_param_sink);
            }
            if (ArgumentAnalyzer::verifyType($statements_analyzer, $expr_type ?? Type::getMixed(), Type::getString(), null, 'echo', null, (int) $i, new CodeLocation($statements_analyzer->getSource(), $expr), $expr, $context, $echo_param, \false, null, \true, \true, new CodeLocation($statements_analyzer, $stmt)) === \false) {
                return \false;
            }
        }
        if (isset($codebase->config->forbidden_functions['echo'])) {
            IssueBuffer::maybeAdd(new ForbiddenCode('Use of echo', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSource()->getSuppressedIssues());
        }
        if (!$context->collect_initializations && !$context->collect_mutations) {
            if ($context->mutation_free || $context->external_mutation_free) {
                IssueBuffer::maybeAdd(new ImpureFunctionCall('Cannot call echo from a mutation-free context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                $statements_analyzer->getSource()->inferred_has_mutation = \true;
                $statements_analyzer->getSource()->inferred_impure = \true;
            }
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\MethodAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallProhibitionAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Issue\InvalidClone;
use Psalm\Issue\MixedClone;
use Psalm\Issue\PossiblyInvalidClone;
use Psalm\IssueBuffer;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TTemplateParam;
use function array_merge;
use function array_pop;
/**
 * @internal
 */
class CloneAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Clone_ $stmt, Context $context) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $codebase_methods = $codebase->methods;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            return \false;
        }
        $location = new CodeLocation($statements_analyzer->getSource(), $stmt);
        $stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr);
        if ($stmt_expr_type) {
            $clone_type = $stmt_expr_type;
            $immutable_cloned = \false;
            $invalid_clones = [];
            $mixed_clone = \false;
            $possibly_valid = \false;
            $atomic_types = $clone_type->getAtomicTypes();
            while ($atomic_types) {
                $clone_type_part = array_pop($atomic_types);
                if ($clone_type_part instanceof TMixed) {
                    $mixed_clone = \true;
                } elseif ($clone_type_part instanceof TObject) {
                    $possibly_valid = \true;
                } elseif ($clone_type_part instanceof TNamedObject) {
                    if (!$codebase->classlikes->classOrInterfaceExists($clone_type_part->value)) {
                        $invalid_clones[] = $clone_type_part->getId();
                    } else {
                        $clone_method_id = new MethodIdentifier($clone_type_part->value, '__clone');
                        $does_method_exist = $codebase_methods->methodExists($clone_method_id, $context->calling_method_id, $location);
                        $is_method_visible = MethodAnalyzer::isMethodVisible($clone_method_id, $context, $statements_analyzer->getSource());
                        if ($does_method_exist && !$is_method_visible) {
                            $invalid_clones[] = $clone_type_part->getId();
                        } else {
                            MethodCallProhibitionAnalyzer::analyze($codebase, $context, $clone_method_id, $statements_analyzer->getNamespace(), $location, $statements_analyzer->getSuppressedIssues());
                            $possibly_valid = \true;
                            $immutable_cloned = \true;
                        }
                    }
                } elseif ($clone_type_part instanceof TTemplateParam) {
                    $atomic_types = array_merge($atomic_types, $clone_type_part->as->getAtomicTypes());
                } else {
                    if ($clone_type_part instanceof TFalse && $clone_type->ignore_falsable_issues) {
                        continue;
                    }
                    if ($clone_type_part instanceof TNull && $clone_type->ignore_nullable_issues) {
                        continue;
                    }
                    $invalid_clones[] = $clone_type_part->getId();
                }
            }
            if ($mixed_clone) {
                IssueBuffer::maybeAdd(new MixedClone('Cannot clone mixed', $location), $statements_analyzer->getSuppressedIssues());
            }
            if ($invalid_clones) {
                if ($possibly_valid) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidClone('Cannot clone ' . $invalid_clones[0], $location), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new InvalidClone('Cannot clone ' . $invalid_clones[0], $location), $statements_analyzer->getSuppressedIssues());
                }
                return \true;
            }
            if ($immutable_cloned) {
                $stmt_expr_type = $stmt_expr_type->setProperties(['reference_free' => \true, 'allow_mutations' => \true]);
            }
            $statements_analyzer->node_data->setType($stmt, $stmt_expr_type);
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Issue\ForbiddenCode;
use Psalm\Issue\InvalidArgument;
use Psalm\IssueBuffer;
use Psalm\Type;
/**
 * @internal
 */
class EmptyAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Empty_ $stmt, Context $context) : void
    {
        \Psalm\Internal\Analyzer\Statements\Expression\IssetAnalyzer::analyzeIssetVar($statements_analyzer, $stmt->expr, $context);
        $codebase = $statements_analyzer->getCodebase();
        if (isset($codebase->config->forbidden_functions['empty'])) {
            IssueBuffer::maybeAdd(new ForbiddenCode('You have forbidden the use of empty', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        if (($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) && $stmt_expr_type->hasBool() && $stmt_expr_type->isSingle() && !$stmt_expr_type->from_docblock) {
            IssueBuffer::maybeAdd(new InvalidArgument('Calling empty on a boolean value is almost certainly unintended', new CodeLocation($statements_analyzer->getSource(), $stmt->expr), 'empty'), $statements_analyzer->getSuppressedIssues());
        }
        $statements_analyzer->node_data->setType($stmt, Type::getBool());
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallReturnTypeFetcher;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Issue\InvalidCast;
use Psalm\Issue\PossiblyInvalidCast;
use Psalm\Issue\RedundantCast;
use Psalm\Issue\RedundantCastGivenDocblockType;
use Psalm\Issue\RiskyCast;
use Psalm\Issue\UnrecognizedExpression;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TClosedResource;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonspecificLiteralInt;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TResource;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
use function array_merge;
use function array_pop;
use function array_values;
use function get_class;
use function strtolower;
/**
 * @internal
 */
class CastAnalyzer
{
    /** @var string[] */
    private const PSEUDO_CASTABLE_CLASSES = ['SimpleXMLElement', 'DOMNode', 'GMP', '_HumbugBox1cb33d1f20f1\\Decimal\\Decimal'];
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Cast $stmt, Context $context) : bool
    {
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Int_) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                return \false;
            }
            $maybe_type = $statements_analyzer->node_data->getType($stmt->expr);
            if ($maybe_type) {
                if ($maybe_type->isInt()) {
                    if (!$maybe_type->from_calculation) {
                        self::handleRedundantCast($maybe_type, $statements_analyzer, $stmt);
                    }
                }
                $type = self::castIntAttempt($statements_analyzer, $maybe_type, $stmt->expr, \true);
            } else {
                $type = Type::getInt();
            }
            $statements_analyzer->node_data->setType($stmt, $type);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Double) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                return \false;
            }
            $maybe_type = $statements_analyzer->node_data->getType($stmt->expr);
            if ($maybe_type) {
                if ($maybe_type->isFloat()) {
                    self::handleRedundantCast($maybe_type, $statements_analyzer, $stmt);
                }
                $type = self::castFloatAttempt($statements_analyzer, $maybe_type, $stmt->expr, \true);
            } else {
                $type = Type::getFloat();
            }
            $statements_analyzer->node_data->setType($stmt, $type);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Bool_) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                return \false;
            }
            $maybe_type = $statements_analyzer->node_data->getType($stmt->expr);
            if ($maybe_type) {
                if ($maybe_type->isBool()) {
                    self::handleRedundantCast($maybe_type, $statements_analyzer, $stmt);
                }
            }
            if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                $type = new Union([new TBool()], ['parent_nodes' => $maybe_type->parent_nodes ?? []]);
            } else {
                $type = Type::getBool();
            }
            $statements_analyzer->node_data->setType($stmt, $type);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\String_) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                return \false;
            }
            $stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr);
            if ($stmt_expr_type) {
                if ($stmt_expr_type->isString()) {
                    self::handleRedundantCast($stmt_expr_type, $statements_analyzer, $stmt);
                }
                $stmt_type = self::castStringAttempt($statements_analyzer, $context, $stmt_expr_type, $stmt->expr, \true);
            } else {
                $stmt_type = Type::getString();
            }
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Object_) {
            if (!self::checkExprGeneralUse($statements_analyzer, $stmt, $context)) {
                return \false;
            }
            $permissible_atomic_types = [];
            $all_permissible = \false;
            if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
                if ($stmt_expr_type->isObjectType()) {
                    self::handleRedundantCast($stmt_expr_type, $statements_analyzer, $stmt);
                }
                $all_permissible = \true;
                foreach ($stmt_expr_type->getAtomicTypes() as $type) {
                    if ($type instanceof TList) {
                        $type = $type->getKeyedArray();
                    }
                    if ($type instanceof Scalar) {
                        $objWithProps = new TObjectWithProperties(['scalar' => new Union([$type])]);
                        $permissible_atomic_types[] = $objWithProps;
                    } elseif ($type instanceof TKeyedArray) {
                        $permissible_atomic_types[] = new TObjectWithProperties($type->properties);
                    } else {
                        $all_permissible = \false;
                        break;
                    }
                }
            }
            if ($permissible_atomic_types && $all_permissible) {
                $type = TypeCombiner::combine($permissible_atomic_types);
            } else {
                $type = Type::getObject();
            }
            if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                $type = $type->setParentNodes($stmt_expr_type->parent_nodes ?? []);
            }
            $statements_analyzer->node_data->setType($stmt, $type);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Array_) {
            if (!self::checkExprGeneralUse($statements_analyzer, $stmt, $context)) {
                return \false;
            }
            $permissible_atomic_types = [];
            $all_permissible = \false;
            if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
                if ($stmt_expr_type->isArray()) {
                    self::handleRedundantCast($stmt_expr_type, $statements_analyzer, $stmt);
                }
                $all_permissible = \true;
                foreach ($stmt_expr_type->getAtomicTypes() as $type) {
                    if ($type instanceof TList) {
                        $type = $type->getKeyedArray();
                    }
                    if ($type instanceof Scalar) {
                        $keyed_array = new TKeyedArray([new Union([$type])], null, null, \true);
                        $permissible_atomic_types[] = $keyed_array;
                    } elseif ($type instanceof TNull) {
                        $permissible_atomic_types[] = new TArray([Type::getNever(), Type::getNever()]);
                    } elseif ($type instanceof TArray || $type instanceof TKeyedArray) {
                        $permissible_atomic_types[] = $type;
                    } elseif ($type instanceof TObjectWithProperties) {
                        $array_type = $type->properties === [] ? new TArray([Type::getArrayKey(), Type::getMixed()]) : new TKeyedArray($type->properties, null, [Type::getArrayKey(), Type::getMixed()]);
                        $permissible_atomic_types[] = $array_type;
                    } else {
                        $all_permissible = \false;
                        break;
                    }
                }
            }
            if ($permissible_atomic_types && $all_permissible) {
                $type = TypeCombiner::combine($permissible_atomic_types);
            } else {
                $type = Type::getArray();
            }
            if ($statements_analyzer->data_flow_graph) {
                $type = $type->setParentNodes($stmt_expr_type->parent_nodes ?? []);
            }
            $statements_analyzer->node_data->setType($stmt, $type);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Unset_ && $statements_analyzer->getCodebase()->analysis_php_version_id <= 70400) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                return \false;
            }
            $statements_analyzer->node_data->setType($stmt, Type::getNull());
            return \true;
        }
        IssueBuffer::maybeAdd(new UnrecognizedExpression('Psalm does not understand the cast ' . get_class($stmt), new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        return \false;
    }
    public static function castIntAttempt(StatementsAnalyzer $statements_analyzer, Union $stmt_type, PhpParser\Node\Expr $stmt, bool $explicit_cast = \false) : Union
    {
        $codebase = $statements_analyzer->getCodebase();
        $risky_cast = [];
        $invalid_casts = [];
        $valid_ints = [];
        $castable_types = [];
        $atomic_types = $stmt_type->getAtomicTypes();
        $parent_nodes = [];
        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
            $parent_nodes = $stmt_type->parent_nodes;
        }
        while ($atomic_types) {
            $atomic_type = array_pop($atomic_types);
            if ($atomic_type instanceof TList) {
                $atomic_type = $atomic_type->getKeyedArray();
            }
            if ($atomic_type instanceof TInt) {
                $valid_ints[] = $atomic_type;
                continue;
            }
            if ($atomic_type instanceof TFloat) {
                if ($atomic_type instanceof TLiteralFloat) {
                    $valid_ints[] = new TLiteralInt((int) $atomic_type->value);
                } else {
                    $castable_types[] = new TInt();
                }
                continue;
            }
            if ($atomic_type instanceof TString) {
                if ($atomic_type instanceof TLiteralString) {
                    $valid_ints[] = new TLiteralInt((int) $atomic_type->value);
                } elseif ($atomic_type instanceof TNumericString) {
                    $castable_types[] = new TInt();
                } else {
                    // any normal string is technically $valid_int[] = new TLiteralInt(0);
                    // however we cannot be certain that it's not inferred, therefore less strict
                    $castable_types[] = new TInt();
                }
                continue;
            }
            if ($atomic_type instanceof TNull || $atomic_type instanceof TFalse) {
                $valid_ints[] = new TLiteralInt(0);
                continue;
            }
            if ($atomic_type instanceof TTrue) {
                $valid_ints[] = new TLiteralInt(1);
                continue;
            }
            if ($atomic_type instanceof TBool) {
                // do NOT use TIntRange here, as it will cause invalid behavior, e.g. bitwiseAssignment
                $valid_ints[] = new TLiteralInt(0);
                $valid_ints[] = new TLiteralInt(1);
                continue;
            }
            // could be invalid, but allow it, as it is allowed for TString below too
            if ($atomic_type instanceof TMixed || $atomic_type instanceof TClosedResource || $atomic_type instanceof TResource || $atomic_type instanceof Scalar) {
                $castable_types[] = new TInt();
                continue;
            }
            if ($atomic_type instanceof TNamedObject) {
                $intersection_types = [$atomic_type];
                if ($atomic_type->extra_types) {
                    $intersection_types = array_merge($intersection_types, $atomic_type->extra_types);
                }
                foreach ($intersection_types as $intersection_type) {
                    if (!$intersection_type instanceof TNamedObject) {
                        continue;
                    }
                    // prevent "Could not get class storage for mixed"
                    if (!$codebase->classExists($intersection_type->value)) {
                        continue;
                    }
                    foreach (self::PSEUDO_CASTABLE_CLASSES as $pseudo_castable_class) {
                        if (strtolower($intersection_type->value) === strtolower($pseudo_castable_class) || $codebase->classExtends($intersection_type->value, $pseudo_castable_class)) {
                            $castable_types[] = new TInt();
                            continue 3;
                        }
                    }
                }
            }
            if ($atomic_type instanceof TNonEmptyArray || $atomic_type instanceof TKeyedArray && $atomic_type->isNonEmpty()) {
                $risky_cast[] = $atomic_type->getId();
                $valid_ints[] = new TLiteralInt(1);
                continue;
            }
            if ($atomic_type instanceof TArray || $atomic_type instanceof TKeyedArray) {
                // if type is not specific, it can be both 0 or 1, depending on whether the array has data or not
                // welcome to off-by-one hell if that happens :-)
                $risky_cast[] = $atomic_type->getId();
                $valid_ints[] = new TLiteralInt(0);
                $valid_ints[] = new TLiteralInt(1);
                continue;
            }
            if ($atomic_type instanceof TTemplateParam) {
                $atomic_types = array_merge($atomic_types, $atomic_type->as->getAtomicTypes());
                continue;
            }
            // always 1 for "error" cases
            $valid_ints[] = new TLiteralInt(1);
            $invalid_casts[] = $atomic_type->getId();
        }
        if ($invalid_casts) {
            IssueBuffer::maybeAdd(new InvalidCast($invalid_casts[0] . ' cannot be cast to int', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        } elseif ($risky_cast) {
            IssueBuffer::maybeAdd(new RiskyCast('Casting ' . $risky_cast[0] . ' to int has possibly unintended value of 0/1', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        } elseif ($explicit_cast && !$castable_types) {
            // todo: emit error here
        }
        $valid_types = array_merge($valid_ints, $castable_types);
        if (!$valid_types) {
            $int_type = Type::getInt();
        } else {
            $int_type = TypeCombiner::combine($valid_types, $codebase);
        }
        if ($statements_analyzer->data_flow_graph) {
            $int_type = $int_type->setParentNodes($parent_nodes);
        }
        return $int_type;
    }
    public static function castFloatAttempt(StatementsAnalyzer $statements_analyzer, Union $stmt_type, PhpParser\Node\Expr $stmt, bool $explicit_cast = \false) : Union
    {
        $codebase = $statements_analyzer->getCodebase();
        $risky_cast = [];
        $invalid_casts = [];
        $valid_floats = [];
        $castable_types = [];
        $atomic_types = $stmt_type->getAtomicTypes();
        $parent_nodes = [];
        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
            $parent_nodes = $stmt_type->parent_nodes;
        }
        while ($atomic_types) {
            $atomic_type = array_pop($atomic_types);
            if ($atomic_type instanceof TList) {
                $atomic_type = $atomic_type->getKeyedArray();
            }
            if ($atomic_type instanceof TFloat) {
                $valid_floats[] = $atomic_type;
                continue;
            }
            if ($atomic_type instanceof TInt) {
                if ($atomic_type instanceof TLiteralInt) {
                    $valid_floats[] = new TLiteralFloat((float) $atomic_type->value);
                } else {
                    $castable_types[] = new TFloat();
                }
                continue;
            }
            if ($atomic_type instanceof TString) {
                if ($atomic_type instanceof TLiteralString) {
                    $valid_floats[] = new TLiteralFloat((float) $atomic_type->value);
                } elseif ($atomic_type instanceof TNumericString) {
                    $castable_types[] = new TFloat();
                } else {
                    // any normal string is technically $valid_floats[] = new TLiteralFloat(0.0);
                    // however we cannot be certain that it's not inferred, therefore less strict
                    $castable_types[] = new TFloat();
                }
                continue;
            }
            if ($atomic_type instanceof TNull || $atomic_type instanceof TFalse) {
                $valid_floats[] = new TLiteralFloat(0.0);
                continue;
            }
            if ($atomic_type instanceof TTrue) {
                $valid_floats[] = new TLiteralFloat(1.0);
                continue;
            }
            if ($atomic_type instanceof TBool) {
                $valid_floats[] = new TLiteralFloat(0.0);
                $valid_floats[] = new TLiteralFloat(1.0);
                continue;
            }
            // could be invalid, but allow it, as it is allowed for TString below too
            if ($atomic_type instanceof TMixed || $atomic_type instanceof TClosedResource || $atomic_type instanceof TResource || $atomic_type instanceof Scalar) {
                $castable_types[] = new TFloat();
                continue;
            }
            if ($atomic_type instanceof TNamedObject) {
                $intersection_types = [$atomic_type];
                if ($atomic_type->extra_types) {
                    $intersection_types = array_merge($intersection_types, $atomic_type->extra_types);
                }
                foreach ($intersection_types as $intersection_type) {
                    if (!$intersection_type instanceof TNamedObject) {
                        continue;
                    }
                    // prevent "Could not get class storage for mixed"
                    if (!$codebase->classExists($intersection_type->value)) {
                        continue;
                    }
                    foreach (self::PSEUDO_CASTABLE_CLASSES as $pseudo_castable_class) {
                        if (strtolower($intersection_type->value) === strtolower($pseudo_castable_class) || $codebase->classExtends($intersection_type->value, $pseudo_castable_class)) {
                            $castable_types[] = new TFloat();
                            continue 3;
                        }
                    }
                }
            }
            if ($atomic_type instanceof TNonEmptyArray || $atomic_type instanceof TKeyedArray && $atomic_type->isNonEmpty()) {
                $risky_cast[] = $atomic_type->getId();
                $valid_floats[] = new TLiteralFloat(1.0);
                continue;
            }
            if ($atomic_type instanceof TArray || $atomic_type instanceof TKeyedArray) {
                // if type is not specific, it can be both 0 or 1, depending on whether the array has data or not
                // welcome to off-by-one hell if that happens :-)
                $risky_cast[] = $atomic_type->getId();
                $valid_floats[] = new TLiteralFloat(0.0);
                $valid_floats[] = new TLiteralFloat(1.0);
                continue;
            }
            if ($atomic_type instanceof TTemplateParam) {
                $atomic_types = array_merge($atomic_types, $atomic_type->as->getAtomicTypes());
                continue;
            }
            // always 1.0 for "error" cases
            $valid_floats[] = new TLiteralFloat(1.0);
            $invalid_casts[] = $atomic_type->getId();
        }
        if ($invalid_casts) {
            IssueBuffer::maybeAdd(new InvalidCast($invalid_casts[0] . ' cannot be cast to float', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        } elseif ($risky_cast) {
            IssueBuffer::maybeAdd(new RiskyCast('Casting ' . $risky_cast[0] . ' to float has possibly unintended value of 0.0/1.0', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        } elseif ($explicit_cast && !$castable_types) {
            // todo: emit error here
        }
        $valid_types = array_merge($valid_floats, $castable_types);
        if (!$valid_types) {
            $float_type = Type::getFloat();
        } else {
            $float_type = TypeCombiner::combine($valid_types, $codebase);
        }
        if ($statements_analyzer->data_flow_graph) {
            $float_type = $float_type->setParentNodes($parent_nodes);
        }
        return $float_type;
    }
    public static function castStringAttempt(StatementsAnalyzer $statements_analyzer, Context $context, Union $stmt_type, PhpParser\Node\Expr $stmt, bool $explicit_cast = \false) : Union
    {
        $codebase = $statements_analyzer->getCodebase();
        $invalid_casts = [];
        $valid_strings = [];
        $castable_types = [];
        $atomic_types = $stmt_type->getAtomicTypes();
        $parent_nodes = [];
        if ($statements_analyzer->data_flow_graph) {
            $parent_nodes = $stmt_type->parent_nodes;
        }
        while ($atomic_types) {
            $atomic_type = array_pop($atomic_types);
            if ($atomic_type instanceof TFloat || $atomic_type instanceof TInt || $atomic_type instanceof TNumeric) {
                if ($atomic_type instanceof TLiteralInt || $atomic_type instanceof TLiteralFloat) {
                    $castable_types[] = new TLiteralString((string) $atomic_type->value);
                } elseif ($atomic_type instanceof TNonspecificLiteralInt) {
                    $castable_types[] = new TNonspecificLiteralString();
                } else {
                    $castable_types[] = new TNumericString();
                }
                continue;
            }
            if ($atomic_type instanceof TString) {
                $valid_strings[] = $atomic_type;
                continue;
            }
            if ($atomic_type instanceof TNull || $atomic_type instanceof TFalse) {
                $valid_strings[] = new TLiteralString('');
                continue;
            }
            if ($atomic_type instanceof TTrue) {
                $valid_strings[] = new TLiteralString('1');
                continue;
            }
            if ($atomic_type instanceof TBool) {
                $valid_strings[] = new TLiteralString('1');
                $valid_strings[] = new TLiteralString('');
                continue;
            }
            if ($atomic_type instanceof TClosedResource || $atomic_type instanceof TResource) {
                $castable_types[] = new TNonEmptyString();
                continue;
            }
            if ($atomic_type instanceof TMixed || $atomic_type instanceof Scalar) {
                $castable_types[] = new TString();
                continue;
            }
            if ($atomic_type instanceof TNamedObject || $atomic_type instanceof TObjectWithProperties) {
                $intersection_types = [$atomic_type];
                if ($atomic_type->extra_types) {
                    $intersection_types = array_merge($intersection_types, $atomic_type->extra_types);
                }
                foreach ($intersection_types as $intersection_type) {
                    if ($intersection_type instanceof TNamedObject) {
                        $intersection_method_id = new MethodIdentifier($intersection_type->value, '__tostring');
                        if ($codebase->methods->methodExists($intersection_method_id, $context->calling_method_id, new CodeLocation($statements_analyzer->getSource(), $stmt))) {
                            $return_type = $codebase->methods->getMethodReturnType($intersection_method_id, $self_class) ?? Type::getString();
                            $declaring_method_id = $codebase->methods->getDeclaringMethodId($intersection_method_id);
                            MethodCallReturnTypeFetcher::taintMethodCallResult($statements_analyzer, $return_type, $stmt, $stmt, [], $intersection_method_id, $declaring_method_id, $intersection_type->value . '::__toString', $context);
                            if ($statements_analyzer->data_flow_graph) {
                                $parent_nodes = array_merge($return_type->parent_nodes, $parent_nodes);
                            }
                            $castable_types = array_merge($castable_types, array_values($return_type->getAtomicTypes()));
                            continue 2;
                        }
                    }
                    if ($intersection_type instanceof TObjectWithProperties && isset($intersection_type->methods['__tostring'])) {
                        $castable_types[] = new TString();
                        continue 2;
                    }
                }
            }
            if ($atomic_type instanceof TTemplateParam) {
                $atomic_types = array_merge($atomic_types, $atomic_type->as->getAtomicTypes());
                continue;
            }
            $invalid_casts[] = $atomic_type->getId();
        }
        if ($invalid_casts) {
            if ($valid_strings || $castable_types) {
                IssueBuffer::maybeAdd(new PossiblyInvalidCast($invalid_casts[0] . ' cannot be cast to string', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new InvalidCast($invalid_casts[0] . ' cannot be cast to string', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
        } elseif ($explicit_cast && !$castable_types) {
            // todo: emit error here
        }
        $valid_types = [...$valid_strings, ...$castable_types];
        if (!$valid_types) {
            $str_type = Type::getString();
        } else {
            $str_type = TypeCombiner::combine($valid_types, $codebase);
        }
        if ($statements_analyzer->data_flow_graph) {
            $str_type = $str_type->setParentNodes($parent_nodes);
        }
        return $str_type;
    }
    private static function checkExprGeneralUse(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Cast $stmt, Context $context) : bool
    {
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        $retVal = ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context);
        $context->inside_general_use = $was_inside_general_use;
        return $retVal;
    }
    private static function handleRedundantCast(Union $maybe_type, StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Cast $stmt) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $project_analyzer = $statements_analyzer->getProjectAnalyzer();
        $file_manipulation = null;
        if ($maybe_type->from_docblock) {
            $issue = new RedundantCastGivenDocblockType('Redundant cast to ' . $maybe_type->getKey() . ' given docblock-provided type', new CodeLocation($statements_analyzer->getSource(), $stmt));
            if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['RedundantCastGivenDocblockType'])) {
                $file_manipulation = new FileManipulation((int) $stmt->getAttribute('startFilePos'), (int) $stmt->expr->getAttribute('startFilePos'), '');
            }
        } else {
            $issue = new RedundantCast('Redundant cast to ' . $maybe_type->getKey(), new CodeLocation($statements_analyzer->getSource(), $stmt));
            if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['RedundantCast'])) {
                $file_manipulation = new FileManipulation((int) $stmt->getAttribute('startFilePos'), (int) $stmt->expr->getAttribute('startFilePos'), '');
            }
        }
        if ($file_manipulation) {
            FileManipulationBuffer::add($statements_analyzer->getFilePath(), [$file_manipulation]);
        }
        IssueBuffer::maybeAdd($issue, $statements_analyzer->getSuppressedIssues());
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
/**
 * @internal
 */
class IssetAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Isset_ $stmt, Context $context) : void
    {
        foreach ($stmt->vars as $isset_var) {
            if ($isset_var instanceof PhpParser\Node\Expr\PropertyFetch && $isset_var->var instanceof PhpParser\Node\Expr\Variable && $isset_var->var->name === 'this' && $isset_var->name instanceof PhpParser\Node\Identifier) {
                $var_id = '$this->' . $isset_var->name->name;
                if (!isset($context->vars_in_scope[$var_id])) {
                    $context->vars_in_scope[$var_id] = Type::getMixed();
                    $context->vars_possibly_in_scope[$var_id] = \true;
                }
            }
            self::analyzeIssetVar($statements_analyzer, $isset_var, $context);
        }
        $statements_analyzer->node_data->setType($stmt, Type::getBool());
    }
    public static function analyzeIssetVar(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Context $context) : void
    {
        $context->inside_isset = \true;
        ExpressionAnalyzer::analyze($statements_analyzer, $stmt, $context);
        $context->inside_isset = \false;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Comment\Doc;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ArrayDimFetch;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PropertyFetch;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\ArrayAssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\InstancePropertyAssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\StaticPropertyAssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ArrayFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\VariableFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Codebase\DataFlowGraph;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\ReferenceConstraint;
use Psalm\Internal\Scanner\VarDocblockComment;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\AssignmentToVoid;
use Psalm\Issue\ImpureByReferenceAssignment;
use Psalm\Issue\ImpurePropertyAssignment;
use Psalm\Issue\InvalidArrayAccess;
use Psalm\Issue\InvalidArrayOffset;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\InvalidScope;
use Psalm\Issue\LoopInvalidation;
use Psalm\Issue\MissingDocblockType;
use Psalm\Issue\MixedArrayAccess;
use Psalm\Issue\MixedAssignment;
use Psalm\Issue\NoValue;
use Psalm\Issue\NullReference;
use Psalm\Issue\PossiblyInvalidArrayAccess;
use Psalm\Issue\PossiblyNullArrayAccess;
use Psalm\Issue\PossiblyUndefinedArrayOffset;
use Psalm\Issue\PossiblyUndefinedIntArrayOffset;
use Psalm\Issue\ReferenceConstraintViolation;
use Psalm\Issue\ReferenceReusedFromConfusingScope;
use Psalm\Issue\UnnecessaryVarAnnotation;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\BinaryOp\VirtualBitwiseAnd;
use Psalm\Node\Expr\BinaryOp\VirtualBitwiseOr;
use Psalm\Node\Expr\BinaryOp\VirtualBitwiseXor;
use Psalm\Node\Expr\BinaryOp\VirtualCoalesce;
use Psalm\Node\Expr\BinaryOp\VirtualConcat;
use Psalm\Node\Expr\BinaryOp\VirtualDiv;
use Psalm\Node\Expr\BinaryOp\VirtualMinus;
use Psalm\Node\Expr\BinaryOp\VirtualMod;
use Psalm\Node\Expr\BinaryOp\VirtualMul;
use Psalm\Node\Expr\BinaryOp\VirtualPlus;
use Psalm\Node\Expr\BinaryOp\VirtualPow;
use Psalm\Node\Expr\BinaryOp\VirtualShiftLeft;
use Psalm\Node\Expr\BinaryOp\VirtualShiftRight;
use Psalm\Node\Expr\VirtualAssign;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Storage\Assertion\Falsy;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use UnexpectedValueException;
use function count;
use function in_array;
use function is_string;
use function reset;
use function spl_object_id;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class AssignmentAnalyzer
{
    /**
     * @param  PhpParser\Node\Expr|null $assign_value  This has to be null to support list destructuring
     * @return false|Union
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $assign_var, ?PhpParser\Node\Expr $assign_value, ?Union $assign_value_type, Context $context, ?PhpParser\Comment\Doc $doc_comment, array $not_ignored_docblock_var_ids = [], ?PhpParser\Node\Expr $assign_expr = null)
    {
        $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getVarId($assign_var, $statements_analyzer->getFQCLN(), $statements_analyzer);
        // gets a variable id that *may* contain array keys
        $extended_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($assign_var, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $var_comments = [];
        $comment_type = null;
        $comment_type_location = null;
        $was_in_assignment = $context->inside_assignment;
        $context->inside_assignment = \true;
        $codebase = $statements_analyzer->getCodebase();
        $base_assign_value = $assign_value;
        while ($base_assign_value instanceof PhpParser\Node\Expr\Assign) {
            $base_assign_value = $base_assign_value->expr;
        }
        if ($base_assign_value !== $assign_value) {
            ExpressionAnalyzer::analyze($statements_analyzer, $base_assign_value, $context);
            $assign_value_type = $statements_analyzer->node_data->getType($base_assign_value) ?? $assign_value_type;
        }
        $removed_taints = [];
        if ($doc_comment) {
            $file_path = $statements_analyzer->getRootFilePath();
            $file_storage_provider = $codebase->file_storage_provider;
            $file_storage = $file_storage_provider->get($file_path);
            $template_type_map = $statements_analyzer->getTemplateTypeMap();
            try {
                $var_comments = $codebase->config->disable_var_parsing ? [] : CommentAnalyzer::getTypeFromComment($doc_comment, $statements_analyzer->getSource(), $statements_analyzer->getAliases(), $template_type_map, $file_storage->type_aliases);
            } catch (IncorrectDocblockException $e) {
                IssueBuffer::maybeAdd(new MissingDocblockType($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $assign_var)));
            } catch (DocblockParseException $e) {
                IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $assign_var)));
            }
            foreach ($var_comments as $var_comment) {
                if ($var_comment->removed_taints) {
                    $removed_taints = $var_comment->removed_taints;
                }
                self::assignTypeFromVarDocblock($statements_analyzer, $assign_var, $var_comment, $context, $var_id, $comment_type, $comment_type_location, $not_ignored_docblock_var_ids, $var_id === $var_comment->var_id && $assign_value_type && $comment_type && $assign_value_type->by_ref);
            }
        }
        if ($extended_var_id) {
            unset($context->cond_referenced_var_ids[$extended_var_id]);
            $context->assigned_var_ids[$extended_var_id] = (int) $assign_var->getAttribute('startFilePos');
            $context->possibly_assigned_var_ids[$extended_var_id] = \true;
        }
        if ($assign_value) {
            if ($var_id && $assign_value instanceof PhpParser\Node\Expr\Closure) {
                foreach ($assign_value->uses as $closure_use) {
                    if ($closure_use->byRef && is_string($closure_use->var->name) && $var_id === '$' . $closure_use->var->name) {
                        $context->vars_in_scope[$var_id] = Type::getClosure();
                        $context->vars_possibly_in_scope[$var_id] = \true;
                    }
                }
            }
            $was_inside_general_use = $context->inside_general_use;
            $root_expr = $assign_var;
            while ($root_expr instanceof PhpParser\Node\Expr\ArrayDimFetch) {
                $root_expr = $root_expr->var;
            }
            // if we don't know where this data is going, treat as a dead-end usage
            if (!$root_expr instanceof PhpParser\Node\Expr\Variable || is_string($root_expr->name) && in_array('$' . $root_expr->name, VariableFetchAnalyzer::SUPER_GLOBALS, \true)) {
                $context->inside_general_use = \true;
            }
            if (ExpressionAnalyzer::analyze($statements_analyzer, $assign_value, $context) === \false) {
                $context->inside_general_use = $was_inside_general_use;
                if ($var_id) {
                    if ($extended_var_id && isset($context->vars_in_scope[$extended_var_id])) {
                        $context->removeDescendents($extended_var_id, $context->vars_in_scope[$extended_var_id], $assign_value_type);
                    }
                    // if we're not exiting immediately, make everything mixed
                    $context->vars_in_scope[$var_id] = $comment_type ?? Type::getMixed();
                }
                return \false;
            }
            $context->inside_general_use = $was_inside_general_use;
        }
        if ($comment_type && $comment_type_location) {
            $temp_assign_value_type = $assign_value_type ?? ($assign_value ? $statements_analyzer->node_data->getType($assign_value) : null);
            if ($codebase->find_unused_variables && $temp_assign_value_type && $extended_var_id && (!$not_ignored_docblock_var_ids || isset($not_ignored_docblock_var_ids[$extended_var_id])) && $temp_assign_value_type->getId() === $comment_type->getId() && !$comment_type->isMixed()) {
                if ($codebase->alter_code && isset($statements_analyzer->getProjectAnalyzer()->getIssuesToFix()['UnnecessaryVarAnnotation'])) {
                    FileManipulationBuffer::addVarAnnotationToRemove($comment_type_location);
                } else {
                    IssueBuffer::maybeAdd(new UnnecessaryVarAnnotation('The @var ' . $comment_type . ' annotation for ' . $extended_var_id . ' is unnecessary', $comment_type_location), $statements_analyzer->getSuppressedIssues(), \true);
                }
            }
            $parent_nodes = $temp_assign_value_type->parent_nodes ?? [];
            $assign_value_type = $comment_type->setParentNodes($parent_nodes);
        } elseif (!$assign_value_type) {
            if ($assign_value) {
                $assign_value_type = $statements_analyzer->node_data->getType($assign_value);
            }
            if ($assign_value_type) {
                $assign_value_type = $assign_value_type->setProperties(['from_property' => \false, 'from_static_property' => \false, 'ignore_isset' => \false]);
            } else {
                $assign_value_type = Type::getMixed();
            }
        }
        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && !$assign_value_type->parent_nodes) {
            if ($extended_var_id) {
                $assignment_node = DataFlowNode::getForAssignment($extended_var_id, new CodeLocation($statements_analyzer->getSource(), $assign_var));
            } else {
                $assignment_node = new DataFlowNode('unknown-origin', 'unknown origin', null);
            }
            $parent_nodes = [$assignment_node->id => $assignment_node];
            if ($context->inside_try) {
                // Copy previous assignment's parent nodes inside a try. Since an exception could be thrown at any
                // point this is a workaround to ensure that use of a variable also uses all previous assignments.
                if (isset($context->vars_in_scope[$extended_var_id])) {
                    $parent_nodes += $context->vars_in_scope[$extended_var_id]->parent_nodes;
                }
            }
            $assign_value_type = $assign_value_type->setParentNodes($parent_nodes);
        }
        if ($extended_var_id && isset($context->vars_in_scope[$extended_var_id])) {
            if ($context->vars_in_scope[$extended_var_id]->by_ref) {
                if ($context->mutation_free) {
                    IssueBuffer::maybeAdd(new ImpureByReferenceAssignment('Variable ' . $extended_var_id . ' cannot be assigned to as it is passed by reference', new CodeLocation($statements_analyzer->getSource(), $assign_var)));
                } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                    $statements_analyzer->getSource()->inferred_impure = \true;
                    $statements_analyzer->getSource()->inferred_has_mutation = \true;
                }
                $assign_value_type = $assign_value_type->setByRef(\true);
            }
            // removes dependent vars from $context
            $context->removeDescendents($extended_var_id, $context->vars_in_scope[$extended_var_id], $assign_value_type, $statements_analyzer);
        } else {
            $root_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getRootVarId($assign_var, $statements_analyzer->getFQCLN(), $statements_analyzer);
            if ($root_var_id && isset($context->vars_in_scope[$root_var_id])) {
                $context->removeVarFromConflictingClauses($root_var_id, $context->vars_in_scope[$root_var_id], $statements_analyzer);
            }
        }
        $codebase = $statements_analyzer->getCodebase();
        if ($assign_value_type->hasMixed()) {
            $root_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getRootVarId($assign_var, $statements_analyzer->getFQCLN(), $statements_analyzer);
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
            }
            if (!$assign_var instanceof PhpParser\Node\Expr\PropertyFetch && !strpos($root_var_id ?? '', '->') && !$comment_type && strpos($var_id ?? '', '$_') !== 0) {
                $origin_locations = [];
                if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                    foreach ($assign_value_type->parent_nodes as $parent_node) {
                        $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                    }
                }
                $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
                $message = $var_id ? 'Unable to determine the type that ' . $var_id . ' is being assigned to' : 'Unable to determine the type of this assignment';
                $issue_location = new CodeLocation($statements_analyzer->getSource(), $assign_var);
                if ($origin_location && $origin_location->getHash() === $issue_location->getHash()) {
                    $origin_location = null;
                }
                IssueBuffer::maybeAdd(new MixedAssignment($message, $issue_location, $origin_location), $statements_analyzer->getSuppressedIssues());
            }
        } else {
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
            }
            if ($var_id && isset($context->byref_constraints[$var_id]) && ($outer_constraint_type = $context->byref_constraints[$var_id]->type)) {
                if (!UnionTypeComparator::isContainedBy($codebase, $assign_value_type, $outer_constraint_type, $assign_value_type->ignore_nullable_issues, $assign_value_type->ignore_falsable_issues)) {
                    IssueBuffer::maybeAdd(new ReferenceConstraintViolation('Variable ' . $var_id . ' is limited to values of type ' . $context->byref_constraints[$var_id]->type . ' because it is passed by reference, ' . $assign_value_type->getId() . ' type found', new CodeLocation($statements_analyzer->getSource(), $assign_var)), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
        if ($var_id === '$this' && IssueBuffer::accepts(new InvalidScope('Cannot re-assign ' . $var_id, new CodeLocation($statements_analyzer->getSource(), $assign_var)), $statements_analyzer->getSuppressedIssues())) {
            return \false;
        }
        if (isset($context->protected_var_ids[$var_id]) && $assign_value_type->hasLiteralInt()) {
            IssueBuffer::maybeAdd(new LoopInvalidation('Variable ' . $var_id . ' has already been assigned in a for/foreach loop', new CodeLocation($statements_analyzer->getSource(), $assign_var)), $statements_analyzer->getSuppressedIssues());
        }
        if (self::analyzeAssignment($assign_var, $statements_analyzer, $codebase, $assign_value, $assign_value_type, $var_id, $context, $doc_comment, $extended_var_id, $var_comments, $removed_taints) === \false) {
            return \false;
        }
        if ($var_id && isset($context->vars_in_scope[$var_id])) {
            if ($context->vars_in_scope[$var_id]->isVoid()) {
                IssueBuffer::maybeAdd(new AssignmentToVoid('Cannot assign ' . $var_id . ' to type void', new CodeLocation($statements_analyzer->getSource(), $assign_var)), $statements_analyzer->getSuppressedIssues());
                $context->vars_in_scope[$var_id] = Type::getNull();
                $context->inside_assignment = $was_in_assignment;
                return $context->vars_in_scope[$var_id];
            }
            if ($context->vars_in_scope[$var_id]->isNever()) {
                if (IssueBuffer::accepts(new NoValue('All possible types for this assignment were invalidated - This may be dead code', new CodeLocation($statements_analyzer->getSource(), $assign_var)), $statements_analyzer->getSuppressedIssues())) {
                    return \false;
                }
                $context->vars_in_scope[$var_id] = Type::getNever();
                $context->inside_assignment = $was_in_assignment;
                return $context->vars_in_scope[$var_id];
            }
            if ($statements_analyzer->data_flow_graph) {
                $data_flow_graph = $statements_analyzer->data_flow_graph;
                if ($context->vars_in_scope[$var_id]->parent_nodes) {
                    if ($data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                        $context->vars_in_scope[$var_id] = $context->vars_in_scope[$var_id]->setParentNodes([]);
                    } else {
                        $var_location = new CodeLocation($statements_analyzer->getSource(), $assign_var);
                        $event = new AddRemoveTaintsEvent($assign_var, $context, $statements_analyzer, $codebase);
                        $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                        $removed_taints = [...$removed_taints, ...$codebase->config->eventDispatcher->dispatchRemoveTaints($event)];
                        self::taintAssignment($context->vars_in_scope[$var_id], $data_flow_graph, $var_id, $var_location, $removed_taints, $added_taints);
                    }
                    if ($assign_expr) {
                        $new_parent_node = DataFlowNode::getForAssignment('assignment_expr', new CodeLocation($statements_analyzer->getSource(), $assign_expr));
                        $data_flow_graph->addNode($new_parent_node);
                        foreach ($context->vars_in_scope[$var_id]->parent_nodes as $old_parent_node) {
                            $data_flow_graph->addPath($old_parent_node, $new_parent_node, '=');
                        }
                        $assign_value_type = $assign_value_type->setParentNodes([$new_parent_node->id => $new_parent_node]);
                    }
                }
            }
        }
        $context->inside_assignment = $was_in_assignment;
        return $assign_value_type;
    }
    /**
     * @param list<VarDocblockComment> $var_comments
     * @param list<string> $removed_taints
     * @return null|false
     */
    private static function analyzeAssignment(Expr $assign_var, StatementsAnalyzer $statements_analyzer, Codebase $codebase, ?Expr $assign_value, Union $assign_value_type, ?string $var_id, Context $context, ?Doc $doc_comment, ?string $extended_var_id, array $var_comments, array $removed_taints) : ?bool
    {
        if ($assign_var instanceof PhpParser\Node\Expr\Variable) {
            self::analyzeAssignmentToVariable($statements_analyzer, $codebase, $assign_var, $assign_value, $assign_value_type, $var_id, $context);
        } elseif ($assign_var instanceof PhpParser\Node\Expr\List_ || $assign_var instanceof PhpParser\Node\Expr\Array_) {
            self::analyzeDestructuringAssignment($statements_analyzer, $codebase, $assign_var, $assign_value, $assign_value_type, $context, $doc_comment, $extended_var_id, $var_comments, $removed_taints);
        } elseif ($assign_var instanceof PhpParser\Node\Expr\ArrayDimFetch) {
            ArrayAssignmentAnalyzer::analyze($statements_analyzer, $assign_var, $context, $assign_value, $assign_value_type);
        } elseif ($assign_var instanceof PhpParser\Node\Expr\PropertyFetch) {
            self::analyzePropertyAssignment($statements_analyzer, $codebase, $assign_var, $context, $assign_value, $assign_value_type, $var_id);
        } elseif ($assign_var instanceof PhpParser\Node\Expr\StaticPropertyFetch && $assign_var->class instanceof PhpParser\Node\Name) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $assign_var, $context) === \false) {
                return \false;
            }
            if ($context->check_classes) {
                if (StaticPropertyAssignmentAnalyzer::analyze($statements_analyzer, $assign_var, $assign_value, $assign_value_type, $context) === \false) {
                    return \false;
                }
            }
            if ($var_id) {
                $context->vars_possibly_in_scope[$var_id] = \true;
            }
        }
        return null;
    }
    public static function assignTypeFromVarDocblock(StatementsAnalyzer $statements_analyzer, PhpParser\Node $stmt, VarDocblockComment $var_comment, Context $context, ?string $var_id = null, ?Union &$comment_type = null, ?DocblockTypeLocation &$comment_type_location = null, array $not_ignored_docblock_var_ids = [], bool $by_ref = \false) : void
    {
        if (!$var_comment->type) {
            return;
        }
        $codebase = $statements_analyzer->getCodebase();
        try {
            $var_comment_type = TypeExpander::expandUnion($codebase, $var_comment->type, $context->self, $context->self, $statements_analyzer->getParentFQCLN());
            $var_comment_type = $var_comment_type->setProperties(['from_docblock' => \true, 'by_ref' => $by_ref]);
            /** @psalm-suppress UnusedMethodCall This actually has the side effect of generating issues */
            $var_comment_type->check($statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues(), [], \false, \false, \false, $context->calling_method_id);
            $type_location = null;
            if ($var_comment->type_start && $var_comment->type_end && $var_comment->line_number) {
                $type_location = new DocblockTypeLocation($statements_analyzer, $var_comment->type_start, $var_comment->type_end, $var_comment->line_number);
                if ($codebase->alter_code) {
                    $codebase->classlikes->handleDocblockTypeInMigration($codebase, $statements_analyzer, $var_comment_type, $type_location, $context->calling_method_id);
                }
            }
            if (!$var_comment->var_id || $var_comment->var_id === $var_id) {
                $comment_type = $var_comment_type;
                $comment_type_location = $type_location;
                return;
            }
            $project_analyzer = $statements_analyzer->getProjectAnalyzer();
            if ($codebase->find_unused_variables && $type_location && (!$not_ignored_docblock_var_ids || isset($not_ignored_docblock_var_ids[$var_comment->var_id])) && isset($context->vars_in_scope[$var_comment->var_id]) && $context->vars_in_scope[$var_comment->var_id]->getId() === $var_comment_type->getId() && !$var_comment_type->isMixed()) {
                if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['UnnecessaryVarAnnotation'])) {
                    FileManipulationBuffer::addVarAnnotationToRemove($type_location);
                } else {
                    IssueBuffer::maybeAdd(new UnnecessaryVarAnnotation('The @var ' . $var_comment_type . ' annotation for ' . $var_comment->var_id . ' is unnecessary', $type_location), $statements_analyzer->getSuppressedIssues(), \true);
                }
            }
            $parent_nodes = $context->vars_in_scope[$var_comment->var_id]->parent_nodes ?? [];
            $var_comment_type = $var_comment_type->setParentNodes($parent_nodes);
            $context->vars_in_scope[$var_comment->var_id] = $var_comment_type;
        } catch (UnexpectedValueException $e) {
            IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt)));
        }
    }
    /**
     * @param  array<string> $removed_taints
     * @param  array<string> $added_taints
     */
    private static function taintAssignment(Union &$type, DataFlowGraph $data_flow_graph, string $var_id, CodeLocation $var_location, array $removed_taints, array $added_taints) : void
    {
        $parent_nodes = $type->parent_nodes;
        $new_parent_node = DataFlowNode::getForAssignment($var_id, $var_location);
        $data_flow_graph->addNode($new_parent_node);
        $new_parent_nodes = [$new_parent_node->id => $new_parent_node];
        foreach ($parent_nodes as $parent_node) {
            $data_flow_graph->addPath($parent_node, $new_parent_node, '=', $added_taints, $removed_taints);
        }
        $type = $type->setParentNodes($new_parent_nodes, \false);
    }
    public static function analyzeAssignmentOperation(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\AssignOp $stmt, Context $context) : bool
    {
        if ($stmt instanceof PhpParser\Node\Expr\AssignOp\BitwiseAnd) {
            $operation = new VirtualBitwiseAnd($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\BitwiseOr) {
            $operation = new VirtualBitwiseOr($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\BitwiseXor) {
            $operation = new VirtualBitwiseXor($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Coalesce) {
            $operation = new VirtualCoalesce($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Concat) {
            $operation = new VirtualConcat($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Div) {
            $operation = new VirtualDiv($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Minus) {
            $operation = new VirtualMinus($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Mod) {
            $operation = new VirtualMod($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Mul) {
            $operation = new VirtualMul($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Plus) {
            $operation = new VirtualPlus($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\Pow) {
            $operation = new VirtualPow($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\ShiftLeft) {
            $operation = new VirtualShiftLeft($stmt->var, $stmt->expr, $stmt->getAttributes());
        } elseif ($stmt instanceof PhpParser\Node\Expr\AssignOp\ShiftRight) {
            $operation = new VirtualShiftRight($stmt->var, $stmt->expr, $stmt->getAttributes());
        } else {
            throw new UnexpectedValueException('Unknown assign op');
        }
        $fake_assignment = new VirtualAssign($stmt->var, $operation, $stmt->getAttributes());
        $old_node_data = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $fake_assignment, $context) === \false) {
            return \false;
        }
        $old_node_data->setType($stmt, $statements_analyzer->node_data->getType($operation) ?? Type::getMixed());
        $statements_analyzer->node_data = $old_node_data;
        return \true;
    }
    public static function analyzeAssignmentRef(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\AssignRef $stmt, Context $context) : bool
    {
        ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context, \false, null, \false, null, \true);
        $lhs_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($stmt->var, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $rhs_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($stmt->expr, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $doc_comment = $stmt->getDocComment();
        if ($doc_comment) {
            try {
                $var_comments = CommentAnalyzer::getTypeFromComment($doc_comment, $statements_analyzer->getSource(), $statements_analyzer->getAliases());
            } catch (IncorrectDocblockException $e) {
                IssueBuffer::maybeAdd(new MissingDocblockType($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt)));
            } catch (DocblockParseException $e) {
                IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt)));
            }
            if (!empty($var_comments) && $var_comments[0]->type !== null && $var_comments[0]->var_id === null) {
                IssueBuffer::maybeAdd(new InvalidDocblock("Docblock type cannot be used for reference assignment", new CodeLocation($statements_analyzer->getSource(), $stmt)));
            }
        }
        if ($lhs_var_id === null || $rhs_var_id === null) {
            return \false;
        }
        if (!isset($context->vars_in_scope[$rhs_var_id])) {
            // Sometimes the $rhs_var_id isn't set in $vars_in_scope, for example if it's an unknown array offset.
            $context->vars_in_scope[$rhs_var_id] = $statements_analyzer->node_data->getType($stmt->expr) ?? Type::getMixed();
        }
        if (isset($context->references_in_scope[$lhs_var_id])) {
            // Decrement old referenced variable's reference count
            $context->decrementReferenceCount($lhs_var_id);
            // Remove old reference parent node so previously referenced variable usage doesn't count as reference usage
            $old_type = $context->vars_in_scope[$lhs_var_id];
            foreach ($old_type->parent_nodes as $old_parent_node_id => $_) {
                if (strpos($old_parent_node_id, "{$lhs_var_id}-") === 0) {
                    unset($old_type->parent_nodes[$old_parent_node_id]);
                }
            }
        }
        // When assigning an existing reference as a reference it removes the
        // old reference, so it's no longer potentially from a confusing scope.
        unset($context->references_possibly_from_confusing_scope[$lhs_var_id]);
        $context->vars_in_scope[$lhs_var_id] =& $context->vars_in_scope[$rhs_var_id];
        $context->hasVariable($lhs_var_id);
        $context->references_in_scope[$lhs_var_id] = $rhs_var_id;
        $context->referenced_counts[$rhs_var_id] = ($context->referenced_counts[$rhs_var_id] ?? 0) + 1;
        if (strpos($rhs_var_id, '[') !== \false) {
            // Reference to array item, we always consider array items to be an external scope for references
            // TODO handle differently so it's detected as unused if the array is unused?
            $context->references_to_external_scope[$lhs_var_id] = \true;
        }
        if (strpos($rhs_var_id, '->') !== \false) {
            // Reference to object property, we always consider object properties to be an external scope for references
            // TODO handle differently so it's detected as unused if the object is unused?
            $context->references_to_external_scope[$lhs_var_id] = \true;
        }
        $lhs_location = new CodeLocation($statements_analyzer->getSource(), $stmt->var);
        if (!$stmt->var instanceof ArrayDimFetch && !$stmt->var instanceof PropertyFetch) {
            // If left-hand-side is an array offset or object property, usage is too difficult to track,
            // so it's not registered as an unused variable (this mirrors behavior for non-references).
            $statements_analyzer->registerVariableAssignment($lhs_var_id, $lhs_location);
        }
        $lhs_node = DataFlowNode::getForAssignment($lhs_var_id, $lhs_location);
        $context->vars_in_scope[$lhs_var_id] = $context->vars_in_scope[$lhs_var_id]->addParentNodes([$lhs_node->id => $lhs_node]);
        if ($stmt->var instanceof ArrayDimFetch && $stmt->var->dim !== null) {
            // Analyze offset so that variables in the offset get marked as used
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var->dim, $context);
            $context->inside_general_use = $was_inside_general_use;
        }
        return \true;
    }
    public static function assignByRefParam(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Union $by_ref_type, Union $by_ref_out_type, Context $context, bool $constrain_type = \true, bool $prevent_null = \false) : void
    {
        if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch && $stmt->name instanceof PhpParser\Node\Identifier) {
            $prop_name = $stmt->name->name;
            InstancePropertyAssignmentAnalyzer::analyze($statements_analyzer, $stmt, $prop_name, null, $by_ref_out_type, $context);
            return;
        }
        $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getVarId($stmt, $statements_analyzer->getFQCLN(), $statements_analyzer);
        if ($var_id) {
            $var_not_in_scope = \false;
            if (!$by_ref_type->hasMixed() && $constrain_type) {
                $context->byref_constraints[$var_id] = new ReferenceConstraint($by_ref_type);
            }
            if (!$context->hasVariable($var_id)) {
                $context->vars_possibly_in_scope[$var_id] = \true;
                $location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                if (!$statements_analyzer->hasVariable($var_id)) {
                    if ($constrain_type && $prevent_null && !$by_ref_type->isMixed() && !$by_ref_type->isNullable() && !strpos($var_id, '->') && !strpos($var_id, '::')) {
                        IssueBuffer::maybeAdd(new NullReference('Not expecting null argument passed by reference', $location), $statements_analyzer->getSuppressedIssues());
                    }
                    if ($stmt instanceof PhpParser\Node\Expr\Variable) {
                        $statements_analyzer->registerVariable($var_id, $location, $context->branch_point);
                        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                            $byref_node = DataFlowNode::getForAssignment($var_id, $location);
                            $statements_analyzer->data_flow_graph->addPath($byref_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                        }
                    }
                    $context->hasVariable($var_id);
                } else {
                    $var_not_in_scope = \true;
                }
            } elseif ($var_id === '$this') {
                // don't allow changing $this
                return;
            } else {
                $existing_type = $context->vars_in_scope[$var_id];
                // removes dependent vars from $context
                $context->removeDescendents($var_id, $existing_type, $by_ref_type, $statements_analyzer);
                $by_ref_out_type = $by_ref_out_type->addParentNodes($existing_type->parent_nodes);
                if (!$context->inside_conditional) {
                    $context->vars_in_scope[$var_id] = $by_ref_out_type;
                    if (!($stmt_type = $statements_analyzer->node_data->getType($stmt)) || $stmt_type->isNever()) {
                        $statements_analyzer->node_data->setType($stmt, $by_ref_type);
                    }
                    return;
                }
            }
            $context->assigned_var_ids[$var_id] = (int) $stmt->getAttribute('startFilePos');
            $context->vars_in_scope[$var_id] = $by_ref_out_type;
            $stmt_type = $statements_analyzer->node_data->getType($stmt);
            if (!$stmt_type || $stmt_type->isNever()) {
                $statements_analyzer->node_data->setType($stmt, $by_ref_type);
            }
            if ($var_not_in_scope && $stmt instanceof PhpParser\Node\Expr\Variable) {
                $statements_analyzer->registerPossiblyUndefinedVariable($var_id, $stmt);
            }
        }
    }
    /**
     * @param PhpParser\Node\Expr\List_|PhpParser\Node\Expr\Array_ $assign_var
     * @param list<VarDocblockComment> $var_comments
     * @param list<string> $removed_taints
     */
    private static function analyzeDestructuringAssignment(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr $assign_var, ?PhpParser\Node\Expr $assign_value, Union $assign_value_type, Context $context, ?PhpParser\Comment\Doc $doc_comment, ?string $extended_var_id, array $var_comments, array $removed_taints) : void
    {
        if (!$assign_value_type->hasArray() && !$assign_value_type->isMixed() && !$assign_value_type->hasArrayAccessInterface($codebase)) {
            IssueBuffer::maybeAdd(new InvalidArrayOffset('Cannot destructure non-array of type ' . $assign_value_type->getId(), new CodeLocation($statements_analyzer->getSource(), $assign_var)), $statements_analyzer->getSuppressedIssues());
        }
        $can_be_empty = \true;
        foreach ($assign_var->items as $offset => $assign_var_item) {
            // $assign_var_item can be null e.g. list($a, ) = ['a', 'b']
            if (!$assign_var_item) {
                continue;
            }
            $var = $assign_var_item->value;
            if ($assign_value instanceof PhpParser\Node\Expr\Array_ && $statements_analyzer->node_data->getType($assign_var_item->value)) {
                self::analyze($statements_analyzer, $var, $assign_var_item->value, null, $context, $doc_comment);
                continue;
            }
            $offset_value = null;
            if (!$assign_var_item->key) {
                $offset_value = $offset;
            } elseif ($assign_var_item->key instanceof PhpParser\Node\Scalar\String_) {
                $offset_value = $assign_var_item->key->value;
            }
            $list_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($var, $statements_analyzer->getFQCLN(), $statements_analyzer);
            $new_assign_type = null;
            $assigned = \false;
            $has_null = \false;
            foreach ($assign_value_type->getAtomicTypes() as $assign_value_atomic_type) {
                if ($assign_value_atomic_type instanceof TList) {
                    $assign_value_atomic_type = $assign_value_atomic_type->getKeyedArray();
                }
                if ($assign_value_atomic_type instanceof TKeyedArray && !$assign_var_item->key) {
                    // if object-like has int offsets
                    if ($offset_value !== null && isset($assign_value_atomic_type->properties[$offset_value])) {
                        $value_type = $assign_value_atomic_type->properties[$offset_value];
                        if ($value_type->possibly_undefined) {
                            IssueBuffer::maybeAdd(new PossiblyUndefinedArrayOffset('Possibly undefined array key', new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                            $value_type = $value_type->setPossiblyUndefined(\false);
                        } else {
                            $can_be_empty = \false;
                        }
                        if ($statements_analyzer->data_flow_graph && $assign_value) {
                            $assign_value_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($assign_value, $statements_analyzer->getFQCLN(), $statements_analyzer);
                            $keyed_array_var_id = null;
                            if ($assign_value_id) {
                                $keyed_array_var_id = $assign_value_id . '[\'' . $offset_value . '\']';
                            }
                            $temp = Type::getString((string) $offset_value);
                            ArrayFetchAnalyzer::taintArrayFetch($statements_analyzer, $assign_value, $keyed_array_var_id, $value_type, $temp);
                        }
                        self::analyze($statements_analyzer, $var, null, $value_type, $context, $doc_comment);
                        $assigned = \true;
                        continue;
                    }
                    if ($assign_value_atomic_type->fallback_params === null) {
                        IssueBuffer::maybeAdd(new InvalidArrayOffset('Cannot access value with offset ' . $offset, new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                    }
                }
                if ($assign_value_atomic_type instanceof TMixed) {
                    IssueBuffer::maybeAdd(new MixedArrayAccess('Cannot access array value on mixed variable ' . $extended_var_id, new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                } elseif ($assign_value_atomic_type instanceof TNull) {
                    $has_null = \true;
                } elseif (!$assign_value_atomic_type instanceof TArray && !$assign_value_atomic_type instanceof TKeyedArray && !$assign_value_type->hasArrayAccessInterface($codebase)) {
                    if ($assign_value_type->hasArray()) {
                        if ($assign_value_atomic_type instanceof TFalse && $assign_value_type->ignore_falsable_issues) {
                            // do nothing
                        } else {
                            IssueBuffer::maybeAdd(new PossiblyInvalidArrayAccess('Cannot access array value on non-array variable ' . $extended_var_id . ' of type ' . $assign_value_atomic_type->getId(), new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                        }
                    } else {
                        IssueBuffer::maybeAdd(new InvalidArrayAccess('Cannot access array value on non-array variable ' . $extended_var_id . ' of type ' . $assign_value_atomic_type->getId(), new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                    }
                }
                if ($var instanceof PhpParser\Node\Expr\List_ || $var instanceof PhpParser\Node\Expr\Array_) {
                    if ($assign_value_atomic_type instanceof TKeyedArray) {
                        $assign_value_atomic_type = $assign_value_atomic_type->getGenericArrayType();
                    }
                    $array_value_type = $assign_value_atomic_type instanceof TArray ? $assign_value_atomic_type->type_params[1] : Type::getMixed();
                    self::analyze($statements_analyzer, $var, null, $array_value_type, $context, $doc_comment);
                    continue;
                }
                if ($list_var_id) {
                    $context->vars_possibly_in_scope[$list_var_id] = \true;
                    $context->assigned_var_ids[$list_var_id] = (int) $var->getAttribute('startFilePos');
                    $context->possibly_assigned_var_ids[$list_var_id] = \true;
                    $already_in_scope = isset($context->vars_in_scope[$list_var_id]);
                    if (strpos($list_var_id, '-') === \false && strpos($list_var_id, '[') === \false) {
                        $location = new CodeLocation($statements_analyzer, $var);
                        if (!$statements_analyzer->hasVariable($list_var_id)) {
                            $statements_analyzer->registerVariable($list_var_id, $location, $context->branch_point);
                        } else {
                            $statements_analyzer->registerVariableAssignment($list_var_id, $location);
                        }
                        if (isset($context->byref_constraints[$list_var_id])) {
                            // something
                        }
                    }
                    if ($assign_value_atomic_type instanceof TArray) {
                        $new_assign_type = $assign_value_atomic_type->type_params[1];
                        if ($statements_analyzer->data_flow_graph && $assign_value) {
                            $temp = Type::getArrayKey();
                            ArrayFetchAnalyzer::taintArrayFetch($statements_analyzer, $assign_value, null, $new_assign_type, $temp);
                        }
                        $can_be_empty = !$assign_value_atomic_type instanceof TNonEmptyArray;
                    } elseif ($assign_value_atomic_type instanceof TKeyedArray) {
                        if (($assign_var_item->key instanceof PhpParser\Node\Scalar\String_ || $assign_var_item->key instanceof PhpParser\Node\Scalar\LNumber) && isset($assign_value_atomic_type->properties[$assign_var_item->key->value])) {
                            $new_assign_type = $assign_value_atomic_type->properties[$assign_var_item->key->value];
                            if ($new_assign_type->possibly_undefined) {
                                IssueBuffer::maybeAdd(new PossiblyUndefinedArrayOffset('Possibly undefined array key', new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                                $new_assign_type = $new_assign_type->setPossiblyUndefined(\false);
                            } else {
                                $can_be_empty = \false;
                            }
                        } elseif (!$assign_var_item->key instanceof PhpParser\Node\Scalar\String_ && $assign_value_atomic_type->is_list && $assign_value_atomic_type->fallback_params) {
                            if ($codebase->config->ensure_array_int_offsets_exist) {
                                IssueBuffer::maybeAdd(new PossiblyUndefinedIntArrayOffset('Possibly undefined array key', new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                            }
                            $new_assign_type = $assign_value_atomic_type->fallback_params[1];
                        }
                        if ($statements_analyzer->data_flow_graph && $assign_value && $new_assign_type) {
                            $temp = Type::getArrayKey();
                            ArrayFetchAnalyzer::taintArrayFetch($statements_analyzer, $assign_value, null, $new_assign_type, $temp);
                        }
                    } elseif ($assign_value_atomic_type->hasArrayAccessInterface($codebase)) {
                        ForeachAnalyzer::getKeyValueParamsForTraversableObject($assign_value_atomic_type, $codebase, $array_access_key_type, $array_access_value_type);
                        $new_assign_type = $array_access_value_type;
                    }
                    if ($already_in_scope) {
                        // removes dependent vars from $context
                        $context->removeDescendents($list_var_id, $context->vars_in_scope[$list_var_id], $new_assign_type, $statements_analyzer);
                    }
                }
            }
            if (!$assigned) {
                if ($has_null) {
                    IssueBuffer::maybeAdd(new PossiblyNullArrayAccess('Cannot access array value on null variable ' . $extended_var_id, new CodeLocation($statements_analyzer->getSource(), $var)), $statements_analyzer->getSuppressedIssues());
                }
                foreach ($var_comments as $var_comment) {
                    if (!$var_comment->type) {
                        continue;
                    }
                    try {
                        if ($var_comment->var_id === $list_var_id) {
                            $var_comment_type = TypeExpander::expandUnion($codebase, $var_comment->type, $context->self, $context->self, $statements_analyzer->getParentFQCLN());
                            $var_comment_type = $var_comment_type->setFromDocblock();
                            $new_assign_type = $var_comment_type;
                            break;
                        }
                    } catch (UnexpectedValueException $e) {
                        IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $assign_var)));
                    }
                }
                if ($list_var_id) {
                    $context->vars_in_scope[$list_var_id] = $new_assign_type ?: Type::getMixed();
                    if ($statements_analyzer->data_flow_graph) {
                        $data_flow_graph = $statements_analyzer->data_flow_graph;
                        $var_location = new CodeLocation($statements_analyzer->getSource(), $var);
                        if (!$context->vars_in_scope[$list_var_id]->parent_nodes) {
                            $assignment_node = DataFlowNode::getForAssignment($list_var_id, $var_location);
                            $context->vars_in_scope[$list_var_id] = $context->vars_in_scope[$list_var_id]->setParentNodes([$assignment_node->id => $assignment_node]);
                        } else {
                            if ($data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                                $context->vars_in_scope[$list_var_id] = $context->vars_in_scope[$list_var_id]->setParentNodes([]);
                            } else {
                                $event = new AddRemoveTaintsEvent($var, $context, $statements_analyzer, $codebase);
                                $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                                $removed_taints = [...$removed_taints, ...$codebase->config->eventDispatcher->dispatchRemoveTaints($event)];
                                self::taintAssignment($context->vars_in_scope[$list_var_id], $data_flow_graph, $list_var_id, $var_location, $removed_taints, $added_taints);
                            }
                        }
                    }
                }
            }
            if ($list_var_id) {
                if ($context->error_suppressing && ($offset || $can_be_empty) || $has_null) {
                    $context->vars_in_scope[$list_var_id] = $context->vars_in_scope[$list_var_id]->getBuilder()->addType(new TNull())->freeze();
                }
            }
        }
    }
    private static function analyzePropertyAssignment(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\PropertyFetch $assign_var, Context $context, ?PhpParser\Node\Expr $assign_value, Union $assign_value_type, ?string $var_id) : void
    {
        if (!$assign_var->name instanceof PhpParser\Node\Identifier) {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            // this can happen when the user actually means to type $this-><autocompleted>, but there's
            // a variable on the next line
            if (ExpressionAnalyzer::analyze($statements_analyzer, $assign_var->var, $context) === \false) {
                $context->inside_general_use = $was_inside_general_use;
                return;
            }
            if (ExpressionAnalyzer::analyze($statements_analyzer, $assign_var->name, $context) === \false) {
                $context->inside_general_use = $was_inside_general_use;
                return;
            }
            $context->inside_general_use = $was_inside_general_use;
        }
        if ($assign_var->name instanceof PhpParser\Node\Identifier) {
            $prop_name = $assign_var->name->name;
        } elseif (($assign_var_name_type = $statements_analyzer->node_data->getType($assign_var->name)) && $assign_var_name_type->isSingleStringLiteral()) {
            $prop_name = $assign_var_name_type->getSingleStringLiteral()->value;
        } else {
            $prop_name = null;
        }
        if ($prop_name) {
            InstancePropertyAssignmentAnalyzer::analyze($statements_analyzer, $assign_var, $prop_name, $assign_value, $assign_value_type, $context);
        } else {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $assign_var->var, $context) === \false) {
                return;
            }
            if (($assign_var_type = $statements_analyzer->node_data->getType($assign_var->var)) && !$context->ignore_variable_property) {
                $stmt_var_type = $assign_var_type;
                if ($stmt_var_type->hasObjectType()) {
                    foreach ($stmt_var_type->getAtomicTypes() as $type) {
                        if ($type instanceof TNamedObject) {
                            $codebase->analyzer->addMixedMemberName(strtolower($type->value) . '::$', $context->calling_method_id ?: $statements_analyzer->getFileName());
                        }
                    }
                }
            }
        }
        if ($var_id) {
            $context->vars_possibly_in_scope[$var_id] = \true;
        }
        $property_var_pure_compatible = $statements_analyzer->node_data->isPureCompatible($assign_var->var);
        // prevents writing to any properties in a mutation-free context
        if (!$property_var_pure_compatible && !$context->collect_mutations && !$context->collect_initializations) {
            if ($context->mutation_free || $context->external_mutation_free) {
                IssueBuffer::maybeAdd(new ImpurePropertyAssignment('Cannot assign to a property from a mutation-free context', new CodeLocation($statements_analyzer, $assign_var)), $statements_analyzer->getSuppressedIssues());
            } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                if (!$assign_var->var instanceof PhpParser\Node\Expr\Variable || $assign_var->var->name !== 'this') {
                    $statements_analyzer->getSource()->inferred_has_mutation = \true;
                }
                $statements_analyzer->getSource()->inferred_impure = \true;
            }
        }
    }
    private static function analyzeAssignmentToVariable(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\Variable $assign_var, ?PhpParser\Node\Expr $assign_value, Union $assign_value_type, ?string $var_id, Context $context) : void
    {
        if (is_string($assign_var->name)) {
            if ($var_id) {
                $original_type = $context->vars_in_scope[$var_id] ?? null;
                $context->vars_in_scope[$var_id] = $assign_value_type;
                $context->vars_possibly_in_scope[$var_id] = \true;
                $location = new CodeLocation($statements_analyzer, $assign_var);
                if (!$statements_analyzer->hasVariable($var_id)) {
                    $statements_analyzer->registerVariable($var_id, $location, $context->branch_point);
                } elseif (!$context->inside_isset) {
                    $statements_analyzer->registerVariableAssignment($var_id, $location);
                }
                if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                    $location = new CodeLocation($statements_analyzer, $assign_var);
                    $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $assign_var, $location->raw_file_start . '-' . $location->raw_file_end . ':' . $assign_value_type->getId());
                }
                if (isset($context->byref_constraints[$var_id])) {
                    $assign_value_type = $assign_value_type->setByRef(\true);
                }
                if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $assign_value_type->parent_nodes) {
                    if (isset($context->references_to_external_scope[$var_id]) || isset($context->references_in_scope[$var_id]) || isset($context->referenced_counts[$var_id]) && $context->referenced_counts[$var_id] > 0) {
                        $location = new CodeLocation($statements_analyzer, $assign_var);
                        $assignment_node = DataFlowNode::getForAssignment($var_id, $location);
                        $parent_nodes = $assign_value_type->parent_nodes;
                        if ($original_type !== null) {
                            $parent_nodes += $original_type->parent_nodes;
                        }
                        foreach ($parent_nodes as $parent_node) {
                            $statements_analyzer->data_flow_graph->addPath($parent_node, $assignment_node, '&=');
                        }
                        if (isset($context->references_to_external_scope[$var_id])) {
                            // Mark reference to an external scope as used when a value is assigned to it
                            $statements_analyzer->data_flow_graph->addPath($assignment_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                        }
                    }
                }
                if (isset($context->references_possibly_from_confusing_scope[$var_id])) {
                    IssueBuffer::maybeAdd(new ReferenceReusedFromConfusingScope("{$var_id} is possibly a reference defined at" . " {$context->references_possibly_from_confusing_scope[$var_id]->getShortSummary()}." . " Reusing this variable may cause the referenced value to change.", new CodeLocation($statements_analyzer, $assign_var)), $statements_analyzer->getSuppressedIssues());
                }
                if ($assign_value_type->getId() === 'bool' && ($assign_value instanceof PhpParser\Node\Expr\BinaryOp || $assign_value instanceof PhpParser\Node\Expr\BooleanNot && $assign_value->expr instanceof PhpParser\Node\Expr\BinaryOp)) {
                    $var_object_id = spl_object_id($assign_var);
                    $cond_object_id = spl_object_id($assign_value);
                    $right_clauses = FormulaGenerator::getFormula($cond_object_id, $cond_object_id, $assign_value, $context->self, $statements_analyzer, $codebase);
                    $right_clauses = Context::filterClauses($var_id, $right_clauses);
                    $assignment_clauses = Algebra::combineOredClauses([new Clause([$var_id => ['falsy' => new Falsy()]], $var_object_id, $var_object_id)], $right_clauses, $cond_object_id);
                    $context->clauses = [...$context->clauses, ...$assignment_clauses];
                }
            }
        } else {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $assign_var->name, $context) === \false) {
                $context->inside_general_use = $was_inside_general_use;
                return;
            }
            $context->inside_general_use = $was_inside_general_use;
            if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $assign_value_type->parent_nodes) {
                foreach ($assign_value_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
/**
 * @internal
 */
class BooleanNotAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BooleanNot $stmt, Context $context) : bool
    {
        $inside_negation = $context->inside_negation;
        $context->inside_negation = !$inside_negation;
        $result = ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context);
        $context->inside_negation = $inside_negation;
        $expr_type = $statements_analyzer->node_data->getType($stmt->expr);
        if ($expr_type) {
            if ($expr_type->isAlwaysTruthy()) {
                $stmt_type = new TFalse($expr_type->from_docblock);
            } elseif ($expr_type->isAlwaysFalsy()) {
                $stmt_type = new TTrue($expr_type->from_docblock);
            } else {
                $stmt_type = new TBool();
            }
            $stmt_type = new Union([$stmt_type], ['parent_nodes' => $expr_type->parent_nodes]);
        } else {
            $stmt_type = Type::getBool();
        }
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
        return $result;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Exception\ScopeAnalysisException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\Statements\Block\IfConditionalAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfElse\IfAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfElseAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Scope\IfScope;
use Psalm\Internal\Type\AssertionReconciler;
use Psalm\Node\Expr\VirtualBooleanNot;
use Psalm\Node\Stmt\VirtualExpression;
use Psalm\Node\Stmt\VirtualIf;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Type;
use Psalm\Type\Reconciler;
use function array_diff_key;
use function array_filter;
use function array_merge;
use function array_values;
use function count;
use function in_array;
use function spl_object_id;
/**
 * @internal
 */
class OrAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BinaryOp $stmt, Context $context, bool $from_stmt = \false) : bool
    {
        if ($from_stmt) {
            $fake_if_stmt = new VirtualIf(new VirtualBooleanNot($stmt->left, $stmt->left->getAttributes()), ['stmts' => [new VirtualExpression($stmt->right)]], $stmt->getAttributes());
            return IfElseAnalyzer::analyze($statements_analyzer, $fake_if_stmt, $context) !== \false;
        }
        $codebase = $statements_analyzer->getCodebase();
        $post_leaving_if_context = null;
        // we cap this at max depth of 4 to prevent quadratic behaviour
        // when analysing <expr> || <expr> || <expr> || <expr> || <expr>
        if (!$stmt->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || !$stmt->left->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || !$stmt->left->left->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
            $if_scope = new IfScope();
            try {
                $if_conditional_scope = IfConditionalAnalyzer::analyze($statements_analyzer, $stmt->left, $context, $codebase, $if_scope, $context->branch_point ?: (int) $stmt->getAttribute('startFilePos'));
                $left_context = $if_conditional_scope->if_context;
                $left_referenced_var_ids = $if_conditional_scope->cond_referenced_var_ids;
                $left_assigned_var_ids = $if_conditional_scope->assigned_in_conditional_var_ids;
                if ($stmt->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
                    $post_leaving_if_context = clone $context;
                }
            } catch (ScopeAnalysisException $e) {
                return \false;
            }
        } else {
            $pre_referenced_var_ids = $context->cond_referenced_var_ids;
            $context->cond_referenced_var_ids = [];
            $pre_assigned_var_ids = $context->assigned_var_ids;
            $post_leaving_if_context = clone $context;
            $left_context = clone $context;
            $left_context->if_body_context = null;
            $left_context->assigned_var_ids = [];
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, $left_context) === \false) {
                return \false;
            }
            foreach ($left_context->parent_remove_vars as $var_id => $_) {
                $context->removeVarFromConflictingClauses($var_id);
            }
            IfConditionalAnalyzer::handleParadoxicalCondition($statements_analyzer, $stmt->left);
            foreach ($left_context->vars_in_scope as $var_id => $type) {
                if (!isset($context->vars_in_scope[$var_id])) {
                    if (isset($left_context->assigned_var_ids[$var_id])) {
                        $context->vars_in_scope[$var_id] = $type;
                    }
                } else {
                    $context->vars_in_scope[$var_id] = Type::combineUnionTypes($context->vars_in_scope[$var_id], $type, $codebase);
                }
            }
            $left_referenced_var_ids = $left_context->cond_referenced_var_ids;
            $left_context->cond_referenced_var_ids = array_merge($pre_referenced_var_ids, $left_referenced_var_ids);
            $left_assigned_var_ids = array_diff_key($left_context->assigned_var_ids, $pre_assigned_var_ids);
            $left_context->assigned_var_ids = array_merge($pre_assigned_var_ids, $left_context->assigned_var_ids);
            $left_referenced_var_ids = array_diff_key($left_referenced_var_ids, $left_assigned_var_ids);
        }
        $left_cond_id = spl_object_id($stmt->left);
        $left_clauses = FormulaGenerator::getFormula($left_cond_id, $left_cond_id, $stmt->left, $context->self, $statements_analyzer, $codebase);
        try {
            $negated_left_clauses = Algebra::negateFormula($left_clauses);
        } catch (ComplicatedExpressionException $e) {
            try {
                $negated_left_clauses = FormulaGenerator::getFormula($left_cond_id, $left_cond_id, new VirtualBooleanNot($stmt->left), $context->self, $statements_analyzer, $codebase, \false);
            } catch (ComplicatedExpressionException $e) {
                return \false;
            }
        }
        if ($left_context->reconciled_expression_clauses) {
            $reconciled_expression_clauses = $left_context->reconciled_expression_clauses;
            $negated_left_clauses = array_values(array_filter($negated_left_clauses, static fn(Clause $c): bool => !in_array($c->hash, $reconciled_expression_clauses)));
            if (count($negated_left_clauses) === 1 && $negated_left_clauses[0]->wedge && !$negated_left_clauses[0]->possibilities) {
                $negated_left_clauses = [];
            }
        }
        $clauses_for_right_analysis = Algebra::simplifyCNF([...$context->clauses, ...$negated_left_clauses]);
        $active_negated_type_assertions = [];
        $negated_type_assertions = Algebra::getTruthsFromFormula($clauses_for_right_analysis, $left_cond_id, $left_referenced_var_ids, $active_negated_type_assertions);
        $changed_var_ids = [];
        $right_context = clone $context;
        if ($stmt->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr && $left_assigned_var_ids && $post_leaving_if_context) {
            IfAnalyzer::addConditionallyAssignedVarsToContext($statements_analyzer, $stmt->left, $post_leaving_if_context, $right_context, $left_assigned_var_ids);
        }
        if ($negated_type_assertions) {
            // while in an or, we allow scope to boil over to support
            // statements of the form if ($x === null || $x->foo())
            [$right_context->vars_in_scope, $right_context->references_in_scope] = Reconciler::reconcileKeyedTypes($negated_type_assertions, $active_negated_type_assertions, $right_context->vars_in_scope, $right_context->references_in_scope, $changed_var_ids, $left_referenced_var_ids, $statements_analyzer, [], $left_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $stmt->left), !$context->inside_negation);
        }
        $right_context->clauses = $clauses_for_right_analysis;
        if ($changed_var_ids) {
            $partitioned_clauses = Context::removeReconciledClauses($right_context->clauses, $changed_var_ids);
            $right_context->clauses = $partitioned_clauses[0];
            $right_context->reconciled_expression_clauses = $context->reconciled_expression_clauses;
            foreach ($partitioned_clauses[1] as $clause) {
                $right_context->reconciled_expression_clauses[] = $clause->hash;
            }
            $partitioned_clauses = Context::removeReconciledClauses($context->clauses, $changed_var_ids);
            $context->clauses = $partitioned_clauses[0];
            foreach ($partitioned_clauses[1] as $clause) {
                $context->reconciled_expression_clauses[] = $clause->hash;
            }
        }
        $right_context->if_body_context = null;
        $pre_referenced_var_ids = $right_context->cond_referenced_var_ids;
        $right_context->cond_referenced_var_ids = [];
        $pre_assigned_var_ids = $right_context->assigned_var_ids;
        $right_context->assigned_var_ids = [];
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->right, $right_context) === \false) {
            return \false;
        }
        IfConditionalAnalyzer::handleParadoxicalCondition($statements_analyzer, $stmt->right);
        $right_referenced_var_ids = $right_context->cond_referenced_var_ids;
        $right_context->cond_referenced_var_ids = array_merge($pre_referenced_var_ids, $right_referenced_var_ids);
        $right_assigned_var_ids = $right_context->assigned_var_ids;
        $right_context->assigned_var_ids = array_merge($pre_assigned_var_ids, $right_assigned_var_ids);
        $right_cond_id = spl_object_id($stmt->right);
        $right_clauses = FormulaGenerator::getFormula($right_cond_id, $right_cond_id, $stmt->right, $context->self, $statements_analyzer, $codebase);
        $clauses_for_right_analysis = Context::removeReconciledClauses($clauses_for_right_analysis, $right_assigned_var_ids)[0];
        $combined_right_clauses = Algebra::simplifyCNF([...$clauses_for_right_analysis, ...$right_clauses]);
        $active_right_type_assertions = [];
        $right_type_assertions = Algebra::getTruthsFromFormula($combined_right_clauses, $right_cond_id, $right_referenced_var_ids, $active_right_type_assertions);
        if ($right_type_assertions) {
            $right_changed_var_ids = [];
            Reconciler::reconcileKeyedTypes($right_type_assertions, $active_right_type_assertions, $right_context->vars_in_scope, $right_context->references_in_scope, $right_changed_var_ids, $right_referenced_var_ids, $statements_analyzer, [], $left_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $stmt->right), $context->inside_negation);
        }
        if (!$stmt->right instanceof PhpParser\Node\Expr\Exit_) {
            foreach ($right_context->vars_in_scope as $var_id => $type) {
                if (isset($context->vars_in_scope[$var_id])) {
                    $context->vars_in_scope[$var_id] = Type::combineUnionTypes($context->vars_in_scope[$var_id], $type, $codebase);
                }
            }
        } elseif ($stmt->left instanceof PhpParser\Node\Expr\Assign) {
            $var_id = ExpressionIdentifier::getVarId($stmt->left->var, $context->self);
            if ($var_id && isset($left_context->vars_in_scope[$var_id])) {
                $left_inferred_reconciled = AssertionReconciler::reconcile(new Truthy(), $left_context->vars_in_scope[$var_id], '', $statements_analyzer, $context->inside_loop, [], new CodeLocation($statements_analyzer->getSource(), $stmt->left), $statements_analyzer->getSuppressedIssues());
                $context->vars_in_scope[$var_id] = $left_inferred_reconciled;
            }
        }
        if ($context->inside_conditional) {
            $context->updateChecks($right_context);
        }
        $context->cond_referenced_var_ids = array_merge($right_context->cond_referenced_var_ids, $context->cond_referenced_var_ids);
        $context->assigned_var_ids = array_merge($context->assigned_var_ids, $right_context->assigned_var_ids);
        if ($context->if_body_context) {
            $if_body_context = $context->if_body_context;
            foreach ($right_context->vars_in_scope as $var_id => $type) {
                if (isset($if_body_context->vars_in_scope[$var_id])) {
                    $if_body_context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $if_body_context->vars_in_scope[$var_id], $codebase);
                } elseif (isset($left_context->vars_in_scope[$var_id])) {
                    $if_body_context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $left_context->vars_in_scope[$var_id], $codebase);
                }
            }
            $if_body_context->cond_referenced_var_ids = array_merge($context->cond_referenced_var_ids, $if_body_context->cond_referenced_var_ids);
            $if_body_context->assigned_var_ids = array_merge($context->assigned_var_ids, $if_body_context->assigned_var_ids);
            $if_body_context->updateChecks($context);
        }
        $context->vars_possibly_in_scope = array_merge($right_context->vars_possibly_in_scope, $context->vars_possibly_in_scope);
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Node\Expr\VirtualIsset;
use Psalm\Node\Expr\VirtualTernary;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Type;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Union;
use function substr;
/**
 * @internal
 */
class CoalesceAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BinaryOp\Coalesce $stmt, Context $context) : bool
    {
        $left_expr = $stmt->left;
        $root_expr = $left_expr;
        while ($root_expr instanceof PhpParser\Node\Expr\ArrayDimFetch || $root_expr instanceof PhpParser\Node\Expr\PropertyFetch) {
            $root_expr = $root_expr->var;
        }
        if ($root_expr instanceof PhpParser\Node\Expr\FuncCall || $root_expr instanceof PhpParser\Node\Expr\MethodCall || $root_expr instanceof PhpParser\Node\Expr\StaticCall || $root_expr instanceof PhpParser\Node\Expr\Cast || $root_expr instanceof PhpParser\Node\Expr\NullsafePropertyFetch || $root_expr instanceof PhpParser\Node\Expr\NullsafeMethodCall || $root_expr instanceof PhpParser\Node\Expr\Ternary) {
            $left_var_id = '$<tmp coalesce var>' . (int) $left_expr->getAttribute('startFilePos');
            $cloned = clone $context;
            $cloned->inside_isset = \true;
            ExpressionAnalyzer::analyze($statements_analyzer, $left_expr, $cloned);
            if ($root_expr !== $left_expr) {
                $condition_type = $statements_analyzer->node_data->getType($left_expr);
                if ($condition_type) {
                    $condition_type = $condition_type->setPossiblyUndefined(\true);
                } else {
                    $condition_type = new Union([new TMixed()], ['possibly_undefined' => \true]);
                }
            } else {
                $condition_type = $statements_analyzer->node_data->getType($left_expr) ?? Type::getMixed();
            }
            $context->vars_in_scope[$left_var_id] = $condition_type;
            $left_expr = new VirtualVariable(substr($left_var_id, 1), $left_expr->getAttributes());
        }
        $ternary = new VirtualTernary(new VirtualIsset([$left_expr], $stmt->left->getAttributes()), $left_expr, $stmt->right, $stmt->getAttributes());
        $old_node_data = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        ExpressionAnalyzer::analyze($statements_analyzer, $ternary, $context);
        $ternary_type = $statements_analyzer->node_data->getType($ternary) ?? Type::getMixed();
        $statements_analyzer->node_data = $old_node_data;
        $statements_analyzer->node_data->setType($stmt, $ternary_type);
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\Statements\Block\IfConditionalAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfElseAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Node\Stmt\VirtualExpression;
use Psalm\Node\Stmt\VirtualIf;
use Psalm\Type\Reconciler;
use function array_diff_key;
use function array_filter;
use function array_map;
use function array_merge;
use function array_values;
use function count;
use function in_array;
use function spl_object_id;
/**
 * @internal
 */
class AndAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BinaryOp $stmt, Context $context, bool $from_stmt = \false) : bool
    {
        if ($from_stmt) {
            $fake_if_stmt = new VirtualIf($stmt->left, ['stmts' => [new VirtualExpression($stmt->right)]], $stmt->getAttributes());
            return IfElseAnalyzer::analyze($statements_analyzer, $fake_if_stmt, $context) !== \false;
        }
        $pre_referenced_var_ids = $context->cond_referenced_var_ids;
        $pre_assigned_var_ids = $context->assigned_var_ids;
        $left_context = clone $context;
        $left_context->cond_referenced_var_ids = [];
        $left_context->assigned_var_ids = [];
        /** @var list<string> $left_context->reconciled_expression_clauses */
        $left_context->reconciled_expression_clauses = [];
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, $left_context) === \false) {
            return \false;
        }
        IfConditionalAnalyzer::handleParadoxicalCondition($statements_analyzer, $stmt->left);
        $codebase = $statements_analyzer->getCodebase();
        $left_cond_id = spl_object_id($stmt->left);
        $left_clauses = FormulaGenerator::getFormula($left_cond_id, $left_cond_id, $stmt->left, $context->self, $statements_analyzer, $codebase);
        foreach ($left_context->vars_in_scope as $var_id => $type) {
            if (isset($left_context->assigned_var_ids[$var_id])) {
                $context->vars_in_scope[$var_id] = $type;
            }
        }
        /** @var array<string, bool> */
        $left_referenced_var_ids = $left_context->cond_referenced_var_ids;
        $context->cond_referenced_var_ids = array_merge($pre_referenced_var_ids, $left_referenced_var_ids);
        $left_assigned_var_ids = array_diff_key($left_context->assigned_var_ids, $pre_assigned_var_ids);
        $left_referenced_var_ids = array_diff_key($left_referenced_var_ids, $left_assigned_var_ids);
        $context_clauses = array_merge($left_context->clauses, $left_clauses);
        if ($left_context->reconciled_expression_clauses) {
            $reconciled_expression_clauses = $left_context->reconciled_expression_clauses;
            $context_clauses = array_values(array_filter($context_clauses, static fn(Clause $c): bool => !in_array($c->hash, $reconciled_expression_clauses, \true)));
            if (count($context_clauses) === 1 && $context_clauses[0]->wedge && !$context_clauses[0]->possibilities) {
                $context_clauses = [];
            }
        }
        $simplified_clauses = Algebra::simplifyCNF($context_clauses);
        $active_left_assertions = [];
        $left_type_assertions = Algebra::getTruthsFromFormula($simplified_clauses, $left_cond_id, $left_referenced_var_ids, $active_left_assertions);
        $changed_var_ids = [];
        if ($left_type_assertions) {
            $right_context = clone $context;
            // while in an and, we allow scope to boil over to support
            // statements of the form if ($x && $x->foo())
            [$right_context->vars_in_scope, $right_context->references_in_scope] = Reconciler::reconcileKeyedTypes($left_type_assertions, $active_left_assertions, $right_context->vars_in_scope, $context->references_in_scope, $changed_var_ids, $left_referenced_var_ids, $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $stmt->left), $context->inside_negation);
        } else {
            $right_context = clone $left_context;
        }
        $partitioned_clauses = Context::removeReconciledClauses($left_clauses, $changed_var_ids);
        $right_context->clauses = $partitioned_clauses[0];
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->right, $right_context) === \false) {
            return \false;
        }
        IfConditionalAnalyzer::handleParadoxicalCondition($statements_analyzer, $stmt->right);
        $context->cond_referenced_var_ids = array_merge($right_context->cond_referenced_var_ids, $left_context->cond_referenced_var_ids);
        if ($context->inside_conditional) {
            $context->updateChecks($right_context);
            $context->vars_possibly_in_scope = array_merge($right_context->vars_possibly_in_scope, $left_context->vars_possibly_in_scope);
            $context->assigned_var_ids = array_merge($left_context->assigned_var_ids, $right_context->assigned_var_ids);
        }
        if ($context->if_body_context && !$context->inside_negation) {
            $if_body_context = $context->if_body_context;
            $context->vars_in_scope = $right_context->vars_in_scope;
            $if_body_context->vars_in_scope = array_merge($if_body_context->vars_in_scope, $context->vars_in_scope);
            $if_body_context->cond_referenced_var_ids = array_merge($if_body_context->cond_referenced_var_ids, $context->cond_referenced_var_ids);
            $if_body_context->assigned_var_ids = array_merge($if_body_context->assigned_var_ids, $context->assigned_var_ids);
            $if_body_context->reconciled_expression_clauses = [...$if_body_context->reconciled_expression_clauses, ...array_map(
                /** @return string|int */
                static fn(Clause $c) => $c->hash,
                $partitioned_clauses[1]
            )];
            $if_body_context->vars_possibly_in_scope = array_merge($if_body_context->vars_possibly_in_scope, $context->vars_possibly_in_scope);
            $if_body_context->updateChecks($context);
        } else {
            $context->vars_in_scope = $left_context->vars_in_scope;
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\AtomicTypeComparator;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\FalseOperand;
use Psalm\Issue\ImplicitToStringCast;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\InvalidOperand;
use Psalm\Issue\MixedOperand;
use Psalm\Issue\NullOperand;
use Psalm\Issue\PossiblyFalseOperand;
use Psalm\Issue\PossiblyInvalidOperand;
use Psalm\Issue\PossiblyNullOperand;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyNonspecificLiteralString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function assert;
use function count;
use function reset;
use function strlen;
/**
 * @internal
 */
class ConcatAnalyzer
{
    private const MAX_LITERALS = 64;
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $left, PhpParser\Node\Expr $right, Context $context, Union &$result_type = null) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $left_type = $statements_analyzer->node_data->getType($left);
        $right_type = $statements_analyzer->node_data->getType($right);
        $config = Config::getInstance();
        if ($left_type && $right_type) {
            $result_type = Type::getString();
            if ($left_type->hasMixed() || $right_type->hasMixed()) {
                if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                    $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
                }
                if ($left_type->hasMixed()) {
                    $arg_location = new CodeLocation($statements_analyzer->getSource(), $left);
                    $origin_locations = [];
                    if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                        foreach ($left_type->parent_nodes as $parent_node) {
                            $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                        }
                    }
                    $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
                    if ($origin_location && $origin_location->getHash() === $arg_location->getHash()) {
                        $origin_location = null;
                    }
                    IssueBuffer::maybeAdd(new MixedOperand('Left operand cannot be mixed', $arg_location, $origin_location), $statements_analyzer->getSuppressedIssues());
                } else {
                    $arg_location = new CodeLocation($statements_analyzer->getSource(), $right);
                    $origin_locations = [];
                    if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                        foreach ($right_type->parent_nodes as $parent_node) {
                            $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                        }
                    }
                    $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
                    if ($origin_location && $origin_location->getHash() === $arg_location->getHash()) {
                        $origin_location = null;
                    }
                    IssueBuffer::maybeAdd(new MixedOperand('Right operand cannot be mixed', $arg_location, $origin_location), $statements_analyzer->getSuppressedIssues());
                }
                return;
            }
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
            }
            self::analyzeOperand($statements_analyzer, $left, $left_type, 'Left', $context);
            self::analyzeOperand($statements_analyzer, $right, $right_type, 'Right', $context);
            // If both types are specific literals, combine them into new literals
            $literal_concat = \false;
            if ($left_type->allSpecificLiterals() && $right_type->allSpecificLiterals()) {
                $left_type_parts = $left_type->getAtomicTypes();
                $right_type_parts = $right_type->getAtomicTypes();
                $combinations = count($left_type_parts) * count($right_type_parts);
                if ($combinations < self::MAX_LITERALS) {
                    $literal_concat = \true;
                    $result_type_parts = [];
                    foreach ($left_type->getAtomicTypes() as $left_type_part) {
                        foreach ($right_type->getAtomicTypes() as $right_type_part) {
                            $literal = $left_type_part->value . $right_type_part->value;
                            if (strlen($literal) >= $config->max_string_length) {
                                // Literal too long, use non-literal type instead
                                $literal_concat = \false;
                                break 2;
                            }
                            $result_type_parts[] = new TLiteralString($literal);
                        }
                    }
                    if ($literal_concat) {
                        assert(count($result_type_parts) === $combinations);
                        assert(count($result_type_parts) !== 0);
                        // #8163
                        $result_type = new Union($result_type_parts);
                    }
                }
            }
            if (!$literal_concat) {
                $numeric_type = new Union([new TNumericString(), new TInt(), new TFloat()]);
                $left_is_numeric = UnionTypeComparator::isContainedBy($codebase, $left_type, $numeric_type);
                $right_is_numeric = UnionTypeComparator::isContainedBy($codebase, $right_type, $numeric_type);
                $has_numeric_type = $left_is_numeric || $right_is_numeric;
                if ($left_is_numeric) {
                    $right_uint = Type::getListKey();
                    $right_is_uint = UnionTypeComparator::isContainedBy($codebase, $right_type, $right_uint);
                    if ($right_is_uint) {
                        $result_type = Type::getNumericString();
                        return;
                    }
                }
                $lowercase_type = $numeric_type->getBuilder()->addType(new TLowercaseString())->freeze();
                $all_lowercase = UnionTypeComparator::isContainedBy($codebase, $left_type, $lowercase_type) && UnionTypeComparator::isContainedBy($codebase, $right_type, $lowercase_type);
                $non_empty_string = $numeric_type->getBuilder()->addType(new TNonEmptyString())->freeze();
                $left_non_empty = UnionTypeComparator::isContainedBy($codebase, $left_type, $non_empty_string);
                $right_non_empty = UnionTypeComparator::isContainedBy($codebase, $right_type, $non_empty_string);
                $has_non_empty = $left_non_empty || $right_non_empty;
                $all_non_empty = $left_non_empty && $right_non_empty;
                $has_numeric_and_non_empty = $has_numeric_type && $has_non_empty;
                $all_literals = $left_type->allLiterals() && $right_type->allLiterals();
                if ($has_non_empty) {
                    if ($all_literals) {
                        $result_type = new Union([new TNonEmptyNonspecificLiteralString()]);
                    } elseif ($all_lowercase) {
                        $result_type = Type::getNonEmptyLowercaseString();
                    } else {
                        $result_type = $all_non_empty || $has_numeric_and_non_empty ? Type::getNonFalsyString() : Type::getNonEmptyString();
                    }
                } else {
                    if ($all_literals) {
                        $result_type = new Union([new TNonspecificLiteralString()]);
                    } elseif ($all_lowercase) {
                        $result_type = Type::getLowercaseString();
                    } else {
                        $result_type = Type::getString();
                    }
                }
            }
        }
    }
    private static function analyzeOperand(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $operand, Union $operand_type, string $side, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $config = Config::getInstance();
        if ($operand_type->isNull()) {
            IssueBuffer::maybeAdd(new NullOperand('Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
            return;
        }
        if ($operand_type->isFalse()) {
            IssueBuffer::maybeAdd(new FalseOperand('Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
            return;
        }
        if ($operand_type->isNullable() && !$operand_type->ignore_nullable_issues) {
            IssueBuffer::maybeAdd(new PossiblyNullOperand('Cannot concatenate with a possibly null ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
        }
        if ($operand_type->isFalsable() && !$operand_type->ignore_falsable_issues) {
            IssueBuffer::maybeAdd(new PossiblyFalseOperand('Cannot concatenate with a possibly false ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
        }
        $operand_type_match = \true;
        $has_valid_operand = \false;
        $comparison_result = new TypeComparisonResult();
        foreach ($operand_type->getAtomicTypes() as $operand_type_part) {
            if ($operand_type_part instanceof TTemplateParam && !$operand_type_part->as->isString()) {
                IssueBuffer::maybeAdd(new MixedOperand("{$side} operand cannot be a non-string template param", new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
                return;
            }
            if ($operand_type_part instanceof TNull || $operand_type_part instanceof TFalse) {
                continue;
            }
            $operand_type_part_match = AtomicTypeComparator::isContainedBy($codebase, $operand_type_part, new TString(), \false, \false, $comparison_result);
            $operand_type_match = $operand_type_match && $operand_type_part_match;
            $has_valid_operand = $has_valid_operand || $operand_type_part_match;
            if ($comparison_result->to_string_cast && $config->strict_binary_operands) {
                IssueBuffer::maybeAdd(new ImplicitToStringCast("{$side} side of concat op expects string, '{$operand_type}' provided with a __toString method", new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
            }
            foreach ($operand_type->getAtomicTypes() as $atomic_type) {
                if ($atomic_type instanceof TNamedObject) {
                    $to_string_method_id = new MethodIdentifier($atomic_type->value, '__tostring');
                    if ($codebase->methods->methodExists($to_string_method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $operand) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath())) {
                        try {
                            $storage = $codebase->methods->getStorage($to_string_method_id);
                        } catch (UnexpectedValueException $e) {
                            continue;
                        }
                        if ($context->mutation_free && !$storage->mutation_free) {
                            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating method ' . $atomic_type->value . '::__toString from a pure context', new CodeLocation($statements_analyzer, $operand)), $statements_analyzer->getSuppressedIssues());
                        } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                            $statements_analyzer->getSource()->inferred_has_mutation = \true;
                            $statements_analyzer->getSource()->inferred_impure = \true;
                        }
                    }
                }
            }
        }
        if (!$operand_type_match && (!$comparison_result->scalar_type_match_found || $config->strict_binary_operands)) {
            if ($has_valid_operand) {
                IssueBuffer::maybeAdd(new PossiblyInvalidOperand('Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new InvalidOperand('Cannot concatenate with a ' . $operand_type, new CodeLocation($statements_analyzer->getSource(), $operand)), $statements_analyzer->getSuppressedIssues());
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOpAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Union;
/**
 * @internal
 */
class NonComparisonOpAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BinaryOp $stmt, Context $context) : void
    {
        $stmt_left_type = $statements_analyzer->node_data->getType($stmt->left);
        $stmt_right_type = $statements_analyzer->node_data->getType($stmt->right);
        if (!$stmt_left_type || !$stmt_right_type) {
            return;
        }
        if (($stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseAnd) && $stmt_left_type->hasString() && $stmt_right_type->hasString()) {
            $stmt_type = Type::getString();
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            BinaryOpAnalyzer::addDataFlow($statements_analyzer, $stmt, $stmt->left, $stmt->right, 'nondivop');
            return;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Plus || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Minus || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Mod || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Mul || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Pow || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseAnd || $stmt instanceof PhpParser\Node\Expr\BinaryOp\ShiftLeft || $stmt instanceof PhpParser\Node\Expr\BinaryOp\ShiftRight) {
            \Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\ArithmeticOpAnalyzer::analyze($statements_analyzer, $statements_analyzer->node_data, $stmt->left, $stmt->right, $stmt, $result_type, $context);
            if (!$result_type) {
                $result_type = new Union([new TInt(), new TFloat()]);
            }
            $statements_analyzer->node_data->setType($stmt, $result_type);
            BinaryOpAnalyzer::addDataFlow($statements_analyzer, $stmt, $stmt->left, $stmt->right, 'nondivop');
            return;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalXor) {
            if ($stmt_left_type->hasBool() || $stmt_right_type->hasBool()) {
                $statements_analyzer->node_data->setType($stmt, Type::getBool());
            }
            BinaryOpAnalyzer::addDataFlow($statements_analyzer, $stmt, $stmt->left, $stmt->right, 'xor');
            return;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Div) {
            \Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\ArithmeticOpAnalyzer::analyze($statements_analyzer, $statements_analyzer->node_data, $stmt->left, $stmt->right, $stmt, $result_type, $context);
            if (!$result_type) {
                $result_type = new Union([new TInt(), new TFloat()]);
            }
            $statements_analyzer->node_data->setType($stmt, $result_type);
            BinaryOpAnalyzer::addDataFlow($statements_analyzer, $stmt, $stmt->left, $stmt->right, 'div');
            return;
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\ArrayAssignmentAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Issue\FalseOperand;
use Psalm\Issue\InvalidOperand;
use Psalm\Issue\MixedOperand;
use Psalm\Issue\NullOperand;
use Psalm\Issue\PossiblyFalseOperand;
use Psalm\Issue\PossiblyInvalidOperand;
use Psalm\Issue\PossiblyNullOperand;
use Psalm\Issue\StringIncrement;
use Psalm\IssueBuffer;
use Psalm\StatementsSource;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_diff_key;
use function array_values;
use function count;
use function get_class;
use function is_int;
use function is_numeric;
use function max;
use function min;
use function preg_match;
use function strtolower;
/**
 * @internal
 */
class ArithmeticOpAnalyzer
{
    public static function analyze(?StatementsSource $statements_source, NodeDataProvider $nodes, PhpParser\Node\Expr $left, PhpParser\Node\Expr $right, PhpParser\Node $parent, ?Union &$result_type = null, ?Context $context = null) : void
    {
        $codebase = $statements_source ? $statements_source->getCodebase() : null;
        $left_type = $nodes->getType($left);
        $right_type = $nodes->getType($right);
        $config = Config::getInstance();
        if ($left_type && $left_type->isNever()) {
            $left_type = $right_type;
        } elseif ($right_type && $right_type->isNever()) {
            $right_type = $left_type;
        }
        if ($left_type && $right_type) {
            if ($left_type->isNull()) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new NullOperand('Left operand cannot be null', new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                }
                $result_type = Type::getMixed();
                return;
            }
            if ($left_type->isNullable() && !$left_type->ignore_nullable_issues) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new PossiblyNullOperand('Left operand cannot be nullable, got ' . $left_type, new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                }
            }
            if ($right_type->isNull()) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new NullOperand('Right operand cannot be null', new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                }
                $result_type = Type::getMixed();
                return;
            }
            if ($right_type->isNullable() && !$right_type->ignore_nullable_issues) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new PossiblyNullOperand('Right operand cannot be nullable, got ' . $right_type, new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                }
            }
            if ($left_type->isFalse()) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new FalseOperand('Left operand cannot be false', new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                }
                return;
            }
            if ($left_type->isFalsable() && !$left_type->ignore_falsable_issues) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new PossiblyFalseOperand('Left operand cannot be falsable, got ' . $left_type, new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                }
            }
            if ($right_type->isFalse()) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new FalseOperand('Right operand cannot be false', new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                }
                return;
            }
            if ($right_type->isFalsable() && !$right_type->ignore_falsable_issues) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new PossiblyFalseOperand('Right operand cannot be falsable, got ' . $right_type, new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                }
            }
            $invalid_left_messages = [];
            $invalid_right_messages = [];
            $has_valid_left_operand = \false;
            $has_valid_right_operand = \false;
            $has_string_increment = \false;
            foreach ($left_type->getAtomicTypes() as $left_type_part) {
                foreach ($right_type->getAtomicTypes() as $right_type_part) {
                    $candidate_result_type = self::analyzeOperands($statements_source, $codebase, $config, $context, $left, $right, $parent, $left_type_part, $right_type_part, $invalid_left_messages, $invalid_right_messages, $has_valid_left_operand, $has_valid_right_operand, $has_string_increment, $result_type);
                    if ($candidate_result_type) {
                        $result_type = $candidate_result_type;
                        return;
                    }
                }
            }
            if ($invalid_left_messages && $statements_source) {
                $first_left_message = $invalid_left_messages[0];
                if ($has_valid_left_operand) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidOperand($first_left_message, new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new InvalidOperand($first_left_message, new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                }
            }
            if ($invalid_right_messages && $statements_source) {
                $first_right_message = $invalid_right_messages[0];
                if ($has_valid_right_operand) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidOperand($first_right_message, new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new InvalidOperand($first_right_message, new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                }
            }
            if ($has_string_increment && $statements_source) {
                IssueBuffer::maybeAdd(new StringIncrement('Possibly unintended string increment', new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
            }
        }
    }
    /**
     * @param int|float $result
     */
    private static function getNumericalType($result) : Union
    {
        if (is_int($result)) {
            return Type::getInt(\false, $result);
        }
        return Type::getFloat($result);
    }
    /**
     * @param string[] $invalid_left_messages
     * @param string[] $invalid_right_messages
     * @psalm-suppress ComplexMethod Unavoidably complex method.
     */
    private static function analyzeOperands(?StatementsSource $statements_source, ?Codebase $codebase, Config $config, ?Context $context, PhpParser\Node\Expr $left, PhpParser\Node\Expr $right, PhpParser\Node $parent, Atomic $left_type_part, Atomic $right_type_part, array &$invalid_left_messages, array &$invalid_right_messages, bool &$has_valid_left_operand, bool &$has_valid_right_operand, bool &$has_string_increment, Union &$result_type = null) : ?Union
    {
        if (($left_type_part instanceof TLiteralInt || $left_type_part instanceof TLiteralFloat) && ($right_type_part instanceof TLiteralInt || $right_type_part instanceof TLiteralFloat) && ($context === null || $context->inside_loop === \false || !$left instanceof PhpParser\Node\Expr\Variable && !$right instanceof PhpParser\Node\Expr\Variable)) {
            // get_class is fine here because both classes are final.
            if ($statements_source !== null && $config->strict_binary_operands && get_class($left_type_part) !== get_class($right_type_part)) {
                IssueBuffer::maybeAdd(new InvalidOperand('Cannot process numeric types together in strict operands mode, ' . 'please cast explicitly', new CodeLocation($statements_source, $parent)), $statements_source->getSuppressedIssues());
            }
            // time for some arithmetic!
            $calculated_type = self::arithmeticOperation($parent, $left_type_part->value, $right_type_part->value, \true);
            if ($calculated_type) {
                $result_type = Type::combineUnionTypes($calculated_type, $result_type);
                $has_valid_left_operand = \true;
                $has_valid_right_operand = \true;
                return null;
            }
        }
        if ($left_type_part instanceof TNull || $right_type_part instanceof TNull) {
            // null case is handled above
            return null;
        }
        if ($left_type_part instanceof TFalse || $right_type_part instanceof TFalse) {
            // null case is handled above
            return null;
        }
        if ($left_type_part instanceof TString && $right_type_part instanceof TInt && ($parent instanceof PhpParser\Node\Expr\PostInc || $parent instanceof PhpParser\Node\Expr\PreInc)) {
            if ($left_type_part instanceof TNumericString || $left_type_part instanceof TLiteralString && is_numeric($left_type_part->value)) {
                $new_result_type = new Union([new TFloat(), new TInt()], ['from_calculation' => \true]);
            } else {
                $new_result_type = Type::getNonEmptyString();
                $has_string_increment = \true;
            }
            $result_type = Type::combineUnionTypes($new_result_type, $result_type);
            $has_valid_left_operand = \true;
            $has_valid_right_operand = \true;
            return null;
        }
        if ($left_type_part instanceof TTemplateParam && $right_type_part instanceof TTemplateParam) {
            $combined_type = Type::combineUnionTypes($left_type_part->as, $right_type_part->as);
            $combined_atomic_types = array_values($combined_type->getAtomicTypes());
            if (count($combined_atomic_types) <= 2) {
                $left_type_part = $combined_atomic_types[0];
                $right_type_part = $combined_atomic_types[1] ?? $combined_atomic_types[0];
            }
        }
        if ($left_type_part instanceof TMixed || $right_type_part instanceof TMixed) {
            if ($statements_source && $codebase && $context) {
                if (!$context->collect_initializations && !$context->collect_mutations && $statements_source->getFilePath() === $statements_source->getRootFilePath() && (!($source = $statements_source->getSource()) instanceof FunctionLikeAnalyzer || !$source->getSource() instanceof TraitAnalyzer)) {
                    $codebase->analyzer->incrementMixedCount($statements_source->getFilePath());
                }
            }
            if ($left_type_part instanceof TMixed) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new MixedOperand('Left operand cannot be mixed', new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                }
            } else {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new MixedOperand('Right operand cannot be mixed', new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                }
            }
            if ($left_type_part instanceof TMixed && $left_type_part->from_loop_isset && $parent instanceof PhpParser\Node\Expr\AssignOp\Plus && !$right_type_part instanceof TMixed) {
                $result_type = Type::combineUnionTypes(new Union([$right_type_part]), $result_type);
                return null;
            }
            $from_loop_isset = (!$left_type_part instanceof TMixed || $left_type_part->from_loop_isset) && (!$right_type_part instanceof TMixed || $right_type_part->from_loop_isset);
            $result_type = Type::getMixed($from_loop_isset);
            return $result_type;
        }
        if ($left_type_part instanceof TTemplateParam || $right_type_part instanceof TTemplateParam) {
            if ($left_type_part instanceof TTemplateParam && !$left_type_part->as->isInt() && !$left_type_part->as->isFloat()) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new MixedOperand('Left operand cannot be a non-numeric template', new CodeLocation($statements_source, $left)), $statements_source->getSuppressedIssues());
                }
            } elseif ($right_type_part instanceof TTemplateParam && !$right_type_part->as->isInt() && !$right_type_part->as->isFloat()) {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new MixedOperand('Right operand cannot be a non-numeric template', new CodeLocation($statements_source, $right)), $statements_source->getSuppressedIssues());
                }
            }
            return null;
        }
        if ($statements_source && $codebase && $context) {
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_source->getFilePath() === $statements_source->getRootFilePath() && (!($parent_source = $statements_source->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementNonMixedCount($statements_source->getFilePath());
            }
        }
        if ($left_type_part instanceof TArray || $right_type_part instanceof TArray || $left_type_part instanceof TKeyedArray || $right_type_part instanceof TKeyedArray || $left_type_part instanceof TList || $right_type_part instanceof TList) {
            if ($left_type_part instanceof TList) {
                $left_type_part = $left_type_part->getKeyedArray();
            }
            if ($right_type_part instanceof TList) {
                $right_type_part = $right_type_part->getKeyedArray();
            }
            if (!$right_type_part instanceof TArray && !$right_type_part instanceof TKeyedArray || !$left_type_part instanceof TArray && !$left_type_part instanceof TKeyedArray) {
                if (!$left_type_part instanceof TArray && !$left_type_part instanceof TKeyedArray) {
                    $invalid_left_messages[] = 'Cannot add an array to a non-array ' . $left_type_part;
                } else {
                    $invalid_right_messages[] = 'Cannot add an array to a non-array ' . $right_type_part;
                }
                if ($left_type_part instanceof TArray || $left_type_part instanceof TKeyedArray) {
                    $has_valid_left_operand = \true;
                } elseif ($right_type_part instanceof TArray || $right_type_part instanceof TKeyedArray) {
                    $has_valid_right_operand = \true;
                }
                $result_type = Type::getArray();
                return null;
            }
            $has_valid_right_operand = \true;
            $has_valid_left_operand = \true;
            if ($left_type_part instanceof TKeyedArray && $right_type_part instanceof TKeyedArray) {
                $definitely_existing_mixed_right_properties = array_diff_key($right_type_part->properties, $left_type_part->properties);
                $properties = $left_type_part->properties;
                foreach ($right_type_part->properties as $key => $type) {
                    if (!isset($properties[$key])) {
                        $properties[$key] = $type;
                    } elseif ($properties[$key]->possibly_undefined) {
                        $properties[$key] = Type::combineUnionTypes($properties[$key], $type, $codebase, \false, \true, 500, $type->possibly_undefined);
                    }
                }
                if ($left_type_part->fallback_params !== null) {
                    foreach ($definitely_existing_mixed_right_properties as $key => $type) {
                        $properties[$key] = Type::combineUnionTypes(Type::getMixed(), $type);
                    }
                }
                if ($left_type_part->fallback_params === null && $right_type_part->fallback_params === null) {
                    $fallback_params = null;
                } elseif ($left_type_part->fallback_params !== null && $right_type_part->fallback_params !== null) {
                    $fallback_params = [Type::combineUnionTypes($left_type_part->fallback_params[0], $right_type_part->fallback_params[0]), Type::combineUnionTypes($left_type_part->fallback_params[1], $right_type_part->fallback_params[1])];
                } else {
                    $fallback_params = $left_type_part->fallback_params ?: $right_type_part->fallback_params;
                }
                $new_keyed_array = new TKeyedArray($properties, null, $fallback_params);
                $result_type_member = new Union([$new_keyed_array]);
            } else {
                $result_type_member = TypeCombiner::combine([$left_type_part, $right_type_part], $codebase, \true);
            }
            $result_type = Type::combineUnionTypes($result_type_member, $result_type, $codebase, \true);
            if ($left instanceof PhpParser\Node\Expr\ArrayDimFetch && $context && $statements_source instanceof StatementsAnalyzer) {
                ArrayAssignmentAnalyzer::updateArrayType($statements_source, $left, $right, $result_type, $context);
            }
            return null;
        }
        if ($left_type_part instanceof TNamedObject && strtolower($left_type_part->value) === 'gmp' || $right_type_part instanceof TNamedObject && strtolower($right_type_part->value) === 'gmp') {
            if ($left_type_part instanceof TNamedObject && strtolower($left_type_part->value) === 'gmp' && ($right_type_part instanceof TNamedObject && strtolower($right_type_part->value) === 'gmp' || ($right_type_part->isNumericType() || $right_type_part instanceof TMixed)) || $right_type_part instanceof TNamedObject && strtolower($right_type_part->value) === 'gmp' && ($left_type_part instanceof TNamedObject && strtolower($left_type_part->value) === 'gmp' || ($left_type_part->isNumericType() || $left_type_part instanceof TMixed))) {
                $result_type = Type::combineUnionTypes(new Union([new TNamedObject('GMP')]), $result_type);
            } else {
                if ($statements_source) {
                    IssueBuffer::maybeAdd(new InvalidOperand('Cannot add GMP to non-numeric type', new CodeLocation($statements_source, $parent)), $statements_source->getSuppressedIssues());
                }
            }
            return null;
        }
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Plus || $parent instanceof PhpParser\Node\Expr\BinaryOp\Minus || $parent instanceof PhpParser\Node\Expr\BinaryOp\Mul || $parent instanceof PhpParser\Node\Expr\BinaryOp\Div || $parent instanceof PhpParser\Node\Expr\BinaryOp\Mod || $parent instanceof PhpParser\Node\Expr\BinaryOp\Pow) {
            $non_decimal_type = null;
            if ($left_type_part instanceof TNamedObject && strtolower($left_type_part->value) === "decimal\\decimal") {
                $non_decimal_type = $right_type_part;
            } elseif ($right_type_part instanceof TNamedObject && strtolower($right_type_part->value) === "decimal\\decimal") {
                $non_decimal_type = $left_type_part;
            }
            if ($non_decimal_type !== null) {
                if ($non_decimal_type instanceof TInt || $non_decimal_type instanceof TNumericString || $non_decimal_type instanceof TNamedObject && strtolower($non_decimal_type->value) === "decimal\\decimal") {
                    $result_type = Type::combineUnionTypes(new Union([new TNamedObject("_HumbugBox1cb33d1f20f1\\Decimal\\Decimal")]), $result_type);
                } else {
                    if ($statements_source) {
                        IssueBuffer::maybeAdd(new InvalidOperand("Cannot add Decimal\\Decimal to {$non_decimal_type->getId()}", new CodeLocation($statements_source, $parent)), $statements_source->getSuppressedIssues());
                    }
                }
                return null;
            }
        }
        if ($left_type_part instanceof TLiteralString) {
            if (preg_match('/^\\-?\\d+$/', $left_type_part->value)) {
                $left_type_part = new TLiteralInt((int) $left_type_part->value);
            } elseif (preg_match('/^\\-?\\d?\\.\\d+$/', $left_type_part->value)) {
                $left_type_part = new TLiteralFloat((float) $left_type_part->value);
            }
        }
        if ($right_type_part instanceof TLiteralString) {
            if (preg_match('/^\\-?\\d+$/', $right_type_part->value)) {
                $right_type_part = new TLiteralInt((int) $right_type_part->value);
            } elseif (preg_match('/^\\-?\\d?\\.\\d+$/', $right_type_part->value)) {
                $right_type_part = new TLiteralFloat((float) $right_type_part->value);
            }
        }
        if ($left_type_part->isNumericType() || $right_type_part->isNumericType()) {
            if (($left_type_part instanceof TNumeric || $right_type_part instanceof TNumeric) && ($left_type_part->isNumericType() && $right_type_part->isNumericType())) {
                if ($config->strict_binary_operands) {
                    if ($statements_source) {
                        IssueBuffer::maybeAdd(new InvalidOperand('Cannot process different numeric types together in strict binary operands mode, ' . 'please cast explicitly', new CodeLocation($statements_source, $parent)), $statements_source->getSuppressedIssues());
                    }
                }
                if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) {
                    $new_result_type = Type::getInt();
                } else {
                    $new_result_type = new Union([new TFloat(), new TInt()]);
                }
                $result_type = Type::combineUnionTypes($new_result_type, $result_type);
                $has_valid_right_operand = \true;
                $has_valid_left_operand = \true;
                return null;
            }
            if ($left_type_part instanceof TIntRange && $right_type_part instanceof TIntRange) {
                self::analyzeOperandsBetweenIntRange($parent, $result_type, $left_type_part, $right_type_part);
                return null;
            }
            if ($left_type_part instanceof TIntRange && $right_type_part instanceof TInt || $left_type_part instanceof TInt && $right_type_part instanceof TIntRange) {
                self::analyzeOperandsBetweenIntRangeAndInt($parent, $result_type, $left_type_part, $right_type_part);
                return null;
            }
            if ($left_type_part instanceof TInt && $right_type_part instanceof TInt) {
                if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Div) {
                    $result_type = new Union([new TInt(), new TFloat()]);
                } else {
                    $left_is_positive = $left_type_part instanceof TLiteralInt && $left_type_part->value > 0 || $left_type_part instanceof TIntRange && $left_type_part->isPositive();
                    $right_is_positive = $right_type_part instanceof TLiteralInt && $right_type_part->value > 0 || $right_type_part instanceof TIntRange && $right_type_part->isPositive();
                    if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Minus) {
                        $always_positive = \false;
                    } elseif ($left_is_positive && $right_is_positive) {
                        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor || $parent instanceof PhpParser\Node\Expr\BinaryOp\BitwiseAnd || $parent instanceof PhpParser\Node\Expr\BinaryOp\ShiftLeft || $parent instanceof PhpParser\Node\Expr\BinaryOp\ShiftRight) {
                            $always_positive = \false;
                        } else {
                            $always_positive = \true;
                        }
                    } elseif ($parent instanceof PhpParser\Node\Expr\BinaryOp\Plus && ($left_type_part instanceof TLiteralInt && $left_type_part->value === 0) && $right_is_positive) {
                        $always_positive = \true;
                    } elseif ($parent instanceof PhpParser\Node\Expr\BinaryOp\Plus && ($right_type_part instanceof TLiteralInt && $right_type_part->value === 0) && $left_is_positive) {
                        $always_positive = \true;
                    } else {
                        $always_positive = \false;
                    }
                    if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) {
                        if ($right_type_part instanceof TLiteralInt) {
                            $literal_value_max = $right_type_part->value - 1;
                            if ($always_positive) {
                                $result_type = new Union([new TIntRange(0, $literal_value_max)]);
                            } else {
                                $result_type = new Union([new TIntRange(-$literal_value_max, $literal_value_max)]);
                            }
                        } else {
                            if ($always_positive) {
                                $result_type = Type::getListKey();
                            } else {
                                $result_type = Type::getInt();
                            }
                        }
                    } else {
                        $result_type = Type::combineUnionTypes($always_positive ? new Union([new TIntRange(1, null)]) : Type::getInt(\true), $result_type);
                    }
                }
                $has_valid_right_operand = \true;
                $has_valid_left_operand = \true;
                return null;
            }
            if ($left_type_part instanceof TFloat && $right_type_part instanceof TFloat) {
                if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) {
                    $result_type = Type::getInt();
                } else {
                    $result_type = Type::combineUnionTypes(Type::getFloat(), $result_type);
                }
                $has_valid_right_operand = \true;
                $has_valid_left_operand = \true;
                return null;
            }
            if ($left_type_part instanceof TFloat && $right_type_part instanceof TInt || $left_type_part instanceof TInt && $right_type_part instanceof TFloat) {
                if ($config->strict_binary_operands) {
                    if ($statements_source) {
                        IssueBuffer::maybeAdd(new InvalidOperand('Cannot process ints and floats in strict binary operands mode, ' . 'please cast explicitly', new CodeLocation($statements_source, $parent)), $statements_source->getSuppressedIssues());
                    }
                }
                if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) {
                    $result_type = Type::getInt();
                } else {
                    $result_type = Type::combineUnionTypes(Type::getFloat(), $result_type);
                }
                $has_valid_right_operand = \true;
                $has_valid_left_operand = \true;
                return null;
            }
            if ($left_type_part->isNumericType() && $right_type_part->isNumericType()) {
                if ($config->strict_binary_operands) {
                    if ($statements_source) {
                        IssueBuffer::maybeAdd(new InvalidOperand('Cannot process numeric types together in strict operands mode, ' . 'please cast explicitly', new CodeLocation($statements_source, $parent)), $statements_source->getSuppressedIssues());
                    }
                }
                if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) {
                    $result_type = Type::getInt();
                } else {
                    $result_type = new Union([new TInt(), new TFloat()]);
                }
                $has_valid_right_operand = \true;
                $has_valid_left_operand = \true;
                return null;
            }
            if (!$left_type_part->isNumericType()) {
                $invalid_left_messages[] = 'Cannot perform a numeric operation with a non-numeric type ' . $left_type_part;
                $has_valid_right_operand = \true;
            } else {
                $invalid_right_messages[] = 'Cannot perform a numeric operation with a non-numeric type ' . $right_type_part;
                $has_valid_left_operand = \true;
            }
        } else {
            $invalid_left_messages[] = 'Cannot perform a numeric operation with non-numeric types ' . $left_type_part . ' and ' . $right_type_part;
        }
        return null;
    }
    /**
     * @param float|int      $operand1
     * @param float|int      $operand2
     */
    public static function arithmeticOperation(PhpParser\Node $operation, $operand1, $operand2, bool $allow_float_result) : ?Union
    {
        if ($operation instanceof PhpParser\Node\Expr\BinaryOp\Plus) {
            $result = $operand1 + $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\Minus) {
            $result = $operand1 - $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\Mod) {
            if ($operand2 === 0) {
                return Type::getNever();
            }
            $result = $operand1 % $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\Mul) {
            $result = $operand1 * $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\Pow) {
            $result = $operand1 ** $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\BitwiseOr) {
            $result = $operand1 | $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\BitwiseAnd) {
            $result = $operand1 & $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor) {
            $result = $operand1 ^ $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\ShiftLeft) {
            $result = $operand1 << $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\ShiftRight) {
            $result = $operand1 >> $operand2;
        } elseif ($operation instanceof PhpParser\Node\Expr\BinaryOp\Div) {
            if ($operand2 === 0) {
                return Type::getNever();
            }
            $result = $operand1 / $operand2;
        } else {
            return null;
        }
        $calculated_type = self::getNumericalType($result);
        if (!$allow_float_result && $calculated_type->isFloat()) {
            return null;
        }
        return $calculated_type;
    }
    private static function analyzeOperandsBetweenIntRange(PhpParser\Node $parent, ?Union &$result_type, TIntRange $left_type_part, TIntRange $right_type_part) : void
    {
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Div) {
            //can't assume an int range will stay int after division
            $result_type = Type::combineUnionTypes(new Union([new TInt(), new TFloat()]), $result_type);
            return;
        }
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mod) {
            self::analyzeModBetweenIntRange($result_type, $left_type_part, $right_type_part);
            return;
        }
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\BitwiseAnd || $parent instanceof PhpParser\Node\Expr\BinaryOp\BitwiseOr || $parent instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor) {
            //really complex to calculate
            $result_type = Type::combineUnionTypes(Type::getInt(), $result_type);
            return;
        }
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\ShiftLeft || $parent instanceof PhpParser\Node\Expr\BinaryOp\ShiftRight) {
            //really complex to calculate
            $result_type = Type::combineUnionTypes(new Union([new TInt()]), $result_type);
            return;
        }
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Mul) {
            self::analyzeMulBetweenIntRange($parent, $result_type, $left_type_part, $right_type_part);
            return;
        }
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Pow) {
            self::analyzePowBetweenIntRange($result_type, $left_type_part, $right_type_part);
            return;
        }
        if ($parent instanceof PhpParser\Node\Expr\BinaryOp\Minus) {
            //for Minus, we have to assume the min is the min from first range minus the max from the second
            $min_operand1 = $left_type_part->min_bound;
            $min_operand2 = $right_type_part->max_bound;
            //and the max is the max from first range minus the min from the second
            $max_operand1 = $left_type_part->max_bound;
            $max_operand2 = $right_type_part->min_bound;
        } else {
            $min_operand1 = $left_type_part->min_bound;
            $min_operand2 = $right_type_part->min_bound;
            $max_operand1 = $left_type_part->max_bound;
            $max_operand2 = $right_type_part->max_bound;
        }
        $calculated_min_type = null;
        if ($min_operand1 !== null && $min_operand2 !== null) {
            // when there are two valid numbers, make any operation
            $calculated_min_type = self::arithmeticOperation($parent, $min_operand1, $min_operand2, \false);
        }
        $calculated_max_type = null;
        if ($max_operand1 !== null && $max_operand2 !== null) {
            // when there are two valid numbers, make any operation
            $calculated_max_type = self::arithmeticOperation($parent, $max_operand1, $max_operand2, \false);
        }
        $min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
        $max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;
        $new_result_type = new Union([new TIntRange($min_value, $max_value)]);
        $result_type = Type::combineUnionTypes($new_result_type, $result_type);
    }
    /**
     * @param TIntRange|TInt $left_type_part
     * @param TIntRange|TInt $right_type_part
     */
    private static function analyzeOperandsBetweenIntRangeAndInt(PhpParser\Node $parent, ?Union &$result_type, Atomic $left_type_part, Atomic $right_type_part) : void
    {
        if (!$left_type_part instanceof TIntRange) {
            $left_type_part = TIntRange::convertToIntRange($left_type_part);
        }
        if (!$right_type_part instanceof TIntRange) {
            $right_type_part = TIntRange::convertToIntRange($right_type_part);
        }
        self::analyzeOperandsBetweenIntRange($parent, $result_type, $left_type_part, $right_type_part);
    }
    private static function analyzeMulBetweenIntRange(PhpParser\Node\Expr\BinaryOp\Mul $parent, ?Union &$result_type, TIntRange $left_type_part, TIntRange $right_type_part) : void
    {
        //Mul is a special case because of double negatives. We can only infer when we know both signs strictly
        if ($right_type_part->min_bound !== null && $right_type_part->max_bound !== null && $left_type_part->min_bound !== null && $left_type_part->max_bound !== null) {
            //everything is known, we can do calculations
            //[ x_1 , x_2 ] ⋆ [ y_1 , y_2 ] =
            //      [
            //          min(x_1 ⋆ y_1 , x_1 ⋆ y_2 , x_2 ⋆ y_1 , x_2 ⋆ y_2),
            //          max(x_1 ⋆ y_1 , x_1 ⋆ y_2 , x_2 ⋆ y_1 , x_2 ⋆ y_2)
            //      ]
            $x_1 = $right_type_part->min_bound;
            $x_2 = $right_type_part->max_bound;
            $y_1 = $left_type_part->min_bound;
            $y_2 = $left_type_part->max_bound;
            $min_value = min($x_1 * $y_1, $x_1 * $y_2, $x_2 * $y_1, $x_2 * $y_2);
            $max_value = max($x_1 * $y_1, $x_1 * $y_2, $x_2 * $y_1, $x_2 * $y_2);
            $new_result_type = new Union([new TIntRange($min_value, $max_value)]);
        } elseif ($right_type_part->isPositiveOrZero() && $left_type_part->isPositiveOrZero()) {
            // both operands are positive, result will be only positive
            $min_operand1 = $left_type_part->min_bound;
            $min_operand2 = $right_type_part->min_bound;
            $max_operand1 = $left_type_part->max_bound;
            $max_operand2 = $right_type_part->max_bound;
            $calculated_min_type = null;
            if ($min_operand1 !== null && $min_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_min_type = self::arithmeticOperation($parent, $min_operand1, $min_operand2, \false);
            }
            $calculated_max_type = null;
            if ($max_operand1 !== null && $max_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_max_type = self::arithmeticOperation($parent, $max_operand1, $max_operand2, \false);
            }
            $min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
            $max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;
            $new_result_type = new Union([new TIntRange($min_value, $max_value)]);
        } elseif ($right_type_part->isPositiveOrZero() && $left_type_part->isNegativeOrZero()) {
            // one operand is negative, result will be negative and we have to check min vs max
            $min_operand1 = $left_type_part->max_bound;
            $min_operand2 = $right_type_part->min_bound;
            $max_operand1 = $left_type_part->min_bound;
            $max_operand2 = $right_type_part->max_bound;
            $calculated_min_type = null;
            if ($min_operand1 !== null && $min_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_min_type = self::arithmeticOperation($parent, $min_operand1, $min_operand2, \false);
            }
            $calculated_max_type = null;
            if ($max_operand1 !== null && $max_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_max_type = self::arithmeticOperation($parent, $max_operand1, $max_operand2, \false);
            }
            $min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
            $max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;
            if ($min_value > $max_value) {
                [$min_value, $max_value] = [$max_value, $min_value];
            }
            $new_result_type = new Union([new TIntRange($min_value, $max_value)]);
        } elseif ($right_type_part->isNegativeOrZero() && $left_type_part->isPositiveOrZero()) {
            // one operand is negative, result will be negative and we have to check min vs max
            $min_operand1 = $left_type_part->min_bound;
            $min_operand2 = $right_type_part->max_bound;
            $max_operand1 = $left_type_part->max_bound;
            $max_operand2 = $right_type_part->min_bound;
            $calculated_min_type = null;
            if ($min_operand1 !== null && $min_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_min_type = self::arithmeticOperation($parent, $min_operand1, $min_operand2, \false);
            }
            $calculated_max_type = null;
            if ($max_operand1 !== null && $max_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_max_type = self::arithmeticOperation($parent, $max_operand1, $max_operand2, \false);
            }
            $min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
            $max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;
            if ($min_value > $max_value) {
                [$min_value, $max_value] = [$max_value, $min_value];
            }
            $new_result_type = new Union([new TIntRange($min_value, $max_value)]);
        } elseif ($right_type_part->isNegativeOrZero() && $left_type_part->isNegativeOrZero()) {
            // both operand are negative, result will be positive
            $min_operand1 = $left_type_part->max_bound;
            $min_operand2 = $right_type_part->max_bound;
            $max_operand1 = $left_type_part->min_bound;
            $max_operand2 = $right_type_part->min_bound;
            $calculated_min_type = null;
            if ($min_operand1 !== null && $min_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_min_type = self::arithmeticOperation($parent, $min_operand1, $min_operand2, \false);
            }
            $calculated_max_type = null;
            if ($max_operand1 !== null && $max_operand2 !== null) {
                // when there are two valid numbers, make any operation
                $calculated_max_type = self::arithmeticOperation($parent, $max_operand1, $max_operand2, \false);
            }
            $min_value = $calculated_min_type !== null ? $calculated_min_type->getSingleIntLiteral()->value : null;
            $max_value = $calculated_max_type !== null ? $calculated_max_type->getSingleIntLiteral()->value : null;
            $new_result_type = new Union([new TIntRange($min_value, $max_value)]);
        } else {
            $new_result_type = Type::getInt(\true);
        }
        $result_type = Type::combineUnionTypes($new_result_type, $result_type);
    }
    private static function analyzePowBetweenIntRange(?Union &$result_type, TIntRange $left_type_part, TIntRange $right_type_part) : void
    {
        //If Pow first operand is negative, the result could be positive or negative, else it will be positive
        //If Pow second operand is negative, the result will be float, if it's 0, it will be 1/-1, else positive
        if ($left_type_part->isPositive()) {
            if ($right_type_part->isPositive()) {
                $new_result_type = new Union([new TIntRange(1, null)]);
            } elseif ($right_type_part->isNegative()) {
                $new_result_type = Type::getFloat();
            } elseif ($right_type_part->min_bound === 0 && $right_type_part->max_bound === 0) {
                $new_result_type = Type::getInt(\true, 1);
            } else {
                //$right_type_part may be a mix of positive, negative and 0
                $new_result_type = new Union([new TInt(), new TFloat()]);
            }
        } elseif ($left_type_part->isNegative()) {
            if ($right_type_part->isPositive()) {
                if ($right_type_part->min_bound === $right_type_part->max_bound) {
                    if ($right_type_part->max_bound % 2 === 0) {
                        $new_result_type = new Union([new TIntRange(1, null)]);
                    } else {
                        $new_result_type = new Union([new TIntRange(null, -1)]);
                    }
                } else {
                    $new_result_type = Type::getInt(\true);
                }
            } elseif ($right_type_part->isNegative()) {
                $new_result_type = Type::getFloat();
            } elseif ($right_type_part->min_bound === 0 && $right_type_part->max_bound === 0) {
                $new_result_type = Type::getInt(\true, -1);
            } else {
                //$right_type_part may be a mix of positive, negative and 0
                $new_result_type = new Union([new TInt(), new TFloat()]);
            }
        } elseif ($left_type_part->min_bound === 0 && $left_type_part->max_bound === 0) {
            if ($right_type_part->isPositive()) {
                $new_result_type = Type::getInt(\true, 0);
            } elseif ($right_type_part->min_bound === 0 && $right_type_part->max_bound === 0) {
                $new_result_type = Type::getInt(\true, 1);
            } elseif ($right_type_part->isNegative()) {
                $new_result_type = Type::getFloat();
            } else {
                $new_result_type = new Union([new TFloat(), new TLiteralInt(0), new TLiteralInt(1)], ['from_calculation' => \true]);
            }
        } else {
            //$left_type_part may be a mix of positive, negative and 0
            if ($right_type_part->isPositive()) {
                if ($right_type_part->min_bound === $right_type_part->max_bound && $right_type_part->max_bound % 2 === 0) {
                    $new_result_type = new Union([new TIntRange(1, null)]);
                } else {
                    $new_result_type = Type::getInt(\true);
                }
            } elseif ($right_type_part->isNegative()) {
                $new_result_type = Type::getFloat();
            } elseif ($right_type_part->min_bound === 0 && $right_type_part->max_bound === 0) {
                $new_result_type = Type::getInt(\true, 1);
            } else {
                //$left_type_part may be a mix of positive, negative and 0
                $new_result_type = new Union([new TInt(), new TFloat()]);
            }
        }
        $result_type = Type::combineUnionTypes($new_result_type, $result_type);
    }
    private static function analyzeModBetweenIntRange(?Union &$result_type, TIntRange $left_type_part, TIntRange $right_type_part) : void
    {
        //result of Mod is not directly dependant on the bounds of the range
        if ($right_type_part->min_bound !== null && $right_type_part->min_bound === $right_type_part->max_bound) {
            //if the second operand is a literal, we can be pretty detailed
            if ($right_type_part->max_bound === 0) {
                $new_result_type = Type::getNever();
            } else {
                if ($left_type_part->isPositiveOrZero()) {
                    if ($right_type_part->isPositive()) {
                        $max = $right_type_part->min_bound - 1;
                        $new_result_type = new Union([new TIntRange(0, $max)]);
                    } else {
                        $max = $right_type_part->min_bound + 1;
                        $new_result_type = new Union([new TIntRange($max, 0)]);
                    }
                } elseif ($left_type_part->isNegativeOrZero()) {
                    if ($right_type_part->isPositive()) {
                        $max = $right_type_part->min_bound - 1;
                        $new_result_type = new Union([new TIntRange(-$max, 0)]);
                    } else {
                        $max = $right_type_part->min_bound + 1;
                        $new_result_type = new Union([new TIntRange(-$max, 0)]);
                    }
                } else {
                    if ($right_type_part->isPositive()) {
                        $max = $right_type_part->min_bound - 1;
                    } else {
                        $max = -$right_type_part->min_bound - 1;
                    }
                    $new_result_type = new Union([new TIntRange(-$max, $max)]);
                }
            }
        } elseif ($right_type_part->isPositive()) {
            if ($left_type_part->isPositiveOrZero()) {
                if ($right_type_part->max_bound !== null) {
                    //we now that the result will be a range between 0 and $right->max - 1
                    $new_result_type = new Union([new TIntRange(0, $right_type_part->max_bound - 1)]);
                } else {
                    $new_result_type = Type::getListKey();
                }
            } elseif ($left_type_part->isNegativeOrZero()) {
                $new_result_type = new Union([new TIntRange(null, 0)]);
            } else {
                $new_result_type = Type::getInt(\true);
            }
        } elseif ($right_type_part->isNegative()) {
            if ($left_type_part->isPositiveOrZero()) {
                $new_result_type = new Union([new TIntRange(null, 0)]);
            } elseif ($left_type_part->isNegativeOrZero()) {
                $new_result_type = new Union([new TIntRange(null, 0)]);
            } else {
                $new_result_type = Type::getInt(\true);
            }
        } else {
            $new_result_type = Type::getInt(\true);
        }
        $result_type = Type::combineUnionTypes($new_result_type, $result_type);
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Node\Expr\BinaryOp\VirtualIdentical;
use Psalm\Node\Expr\VirtualConstFetch;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\Expr\VirtualPropertyFetch;
use Psalm\Node\Expr\VirtualTernary;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\VirtualName;
use Psalm\Type;
/**
 * @internal
 */
class NullsafeAnalyzer
{
    /**
     * @param PhpParser\Node\Expr\NullsafePropertyFetch|PhpParser\Node\Expr\NullsafeMethodCall $stmt
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Context $context) : bool
    {
        if (!$stmt->var instanceof PhpParser\Node\Expr\Variable) {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context);
            $context->inside_general_use = $was_inside_general_use;
            $tmp_name = '__tmp_nullsafe__' . (int) $stmt->var->getAttribute('startFilePos');
            $condition_type = $statements_analyzer->node_data->getType($stmt->var);
            if ($condition_type) {
                $context->vars_in_scope['$' . $tmp_name] = $condition_type;
                $tmp_var = new VirtualVariable($tmp_name, $stmt->var->getAttributes());
            } else {
                $tmp_var = $stmt->var;
            }
        } else {
            $tmp_var = $stmt->var;
        }
        $old_node_data = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        $null_value1 = new VirtualConstFetch(new VirtualName('null'), $stmt->var->getAttributes());
        $null_comparison = new VirtualIdentical($tmp_var, $null_value1, $stmt->var->getAttributes());
        $null_value2 = new VirtualConstFetch(new VirtualName('null'), $stmt->var->getAttributes());
        if ($stmt instanceof PhpParser\Node\Expr\NullsafePropertyFetch) {
            $ternary = new VirtualTernary($null_comparison, $null_value2, new VirtualPropertyFetch($tmp_var, $stmt->name, $stmt->getAttributes()), $stmt->getAttributes());
        } else {
            $ternary = new VirtualTernary($null_comparison, $null_value2, new VirtualMethodCall($tmp_var, $stmt->name, $stmt->args, $stmt->getAttributes()), $stmt->getAttributes());
        }
        ExpressionAnalyzer::analyze($statements_analyzer, $ternary, $context);
        $ternary_type = $statements_analyzer->node_data->getType($ternary);
        $statements_analyzer->node_data = $old_node_data;
        $statements_analyzer->node_data->setType($stmt, $ternary_type ?? Type::getMixed());
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Exception\ScopeAnalysisException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\AlgebraAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfConditionalAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Scope\IfScope;
use Psalm\Internal\Type\AssertionReconciler;
use Psalm\Node\Expr\VirtualBooleanNot;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Type;
use Psalm\Type\Reconciler;
use function array_diff;
use function array_filter;
use function array_intersect;
use function array_intersect_key;
use function array_keys;
use function array_map;
use function array_merge;
use function array_values;
use function count;
use function in_array;
use function preg_match;
use function preg_quote;
use function spl_object_id;
/**
 * @internal
 */
class TernaryAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Ternary $stmt, Context $context) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $if_scope = new IfScope();
        try {
            $if_conditional_scope = IfConditionalAnalyzer::analyze($statements_analyzer, $stmt->cond, $context, $codebase, $if_scope, $context->branch_point ?: (int) $stmt->getAttribute('startFilePos'));
            // this is the context for stuff that happens within the first operand of the ternary
            $if_context = $if_conditional_scope->if_context;
            $cond_referenced_var_ids = $if_conditional_scope->cond_referenced_var_ids;
            $assigned_in_conditional_var_ids = $if_conditional_scope->assigned_in_conditional_var_ids;
        } catch (ScopeAnalysisException $e) {
            return \false;
        }
        $cond_object_id = spl_object_id($stmt->cond);
        $if_clauses = FormulaGenerator::getFormula($cond_object_id, $cond_object_id, $stmt->cond, $context->self, $statements_analyzer, $codebase);
        if (count($if_clauses) > 200) {
            $if_clauses = [];
        }
        $mixed_var_ids = [];
        foreach ($context->vars_in_scope as $var_id => $type) {
            if ($type->hasMixed()) {
                $mixed_var_ids[] = $var_id;
            }
        }
        foreach ($context->vars_possibly_in_scope as $var_id => $_) {
            if (!isset($context->vars_in_scope[$var_id])) {
                $mixed_var_ids[] = $var_id;
            }
        }
        $if_clauses = array_map(static function (Clause $c) use($mixed_var_ids, $cond_object_id) : Clause {
            $keys = array_keys($c->possibilities);
            $mixed_var_ids = array_diff($mixed_var_ids, $keys);
            foreach ($keys as $key) {
                foreach ($mixed_var_ids as $mixed_var_id) {
                    if (preg_match('/^' . preg_quote($mixed_var_id, '/') . '(\\[|-)/', $key)) {
                        return new Clause([], $cond_object_id, $cond_object_id, \true);
                    }
                }
            }
            return $c;
        }, $if_clauses);
        $entry_clauses = $context->clauses;
        // this will see whether any of the clauses in set A conflict with the clauses in set B
        AlgebraAnalyzer::checkForParadox($context->clauses, $if_clauses, $statements_analyzer, $stmt->cond, $assigned_in_conditional_var_ids);
        $if_clauses = Algebra::simplifyCNF($if_clauses);
        $ternary_context_clauses = $entry_clauses ? Algebra::simplifyCNF([...$entry_clauses, ...$if_clauses]) : $if_clauses;
        if ($if_context->reconciled_expression_clauses) {
            $reconciled_expression_clauses = $if_context->reconciled_expression_clauses;
            $ternary_context_clauses = array_values(array_filter($ternary_context_clauses, static fn(Clause $c): bool => !in_array($c->hash, $reconciled_expression_clauses)));
            if (count($if_context->clauses) === 1 && $if_context->clauses[0]->wedge && !$if_context->clauses[0]->possibilities) {
                $if_context->clauses = [];
                $if_context->reconciled_expression_clauses = [];
            }
        }
        try {
            $if_scope->negated_clauses = Algebra::negateFormula($if_clauses);
        } catch (ComplicatedExpressionException $e) {
            try {
                $if_scope->negated_clauses = FormulaGenerator::getFormula($cond_object_id, $cond_object_id, new VirtualBooleanNot($stmt->cond), $context->self, $statements_analyzer, $codebase, \false);
            } catch (ComplicatedExpressionException $e) {
                $if_scope->negated_clauses = [];
            }
        }
        $if_scope->negated_types = Algebra::getTruthsFromFormula(Algebra::simplifyCNF([...$context->clauses, ...$if_scope->negated_clauses]));
        $active_if_types = [];
        $reconcilable_if_types = Algebra::getTruthsFromFormula($ternary_context_clauses, $cond_object_id, $cond_referenced_var_ids, $active_if_types);
        $changed_var_ids = [];
        if ($reconcilable_if_types) {
            [$if_context->vars_in_scope, $if_context->references_in_scope] = Reconciler::reconcileKeyedTypes($reconcilable_if_types, $active_if_types, $if_context->vars_in_scope, $if_context->references_in_scope, $changed_var_ids, $cond_referenced_var_ids, $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $if_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $stmt->cond));
        }
        $t_else_context = clone $context;
        if ($stmt->if) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->if, $if_context) === \false) {
                return \false;
            }
            $context->cond_referenced_var_ids = array_merge($context->cond_referenced_var_ids, $if_context->cond_referenced_var_ids);
        }
        $t_else_context->clauses = Algebra::simplifyCNF([...$t_else_context->clauses, ...$if_scope->negated_clauses]);
        $changed_var_ids = [];
        if ($if_scope->negated_types) {
            [$t_else_context->vars_in_scope, $t_else_context->references_in_scope] = Reconciler::reconcileKeyedTypes($if_scope->negated_types, $if_scope->negated_types, $t_else_context->vars_in_scope, $t_else_context->references_in_scope, $changed_var_ids, $cond_referenced_var_ids, $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $t_else_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $stmt->else));
            $t_else_context->clauses = Context::removeReconciledClauses($t_else_context->clauses, $changed_var_ids)[0];
        }
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->else, $t_else_context) === \false) {
            return \false;
        }
        $assign_var_ifs = $if_context->assigned_var_ids;
        $assign_var_else = $t_else_context->assigned_var_ids;
        $assign_all = array_intersect_key($assign_var_ifs, $assign_var_else);
        //if the same var was assigned in both branches
        foreach ($assign_all as $var_id => $_) {
            if (isset($if_context->vars_in_scope[$var_id]) && isset($t_else_context->vars_in_scope[$var_id])) {
                $context->vars_in_scope[$var_id] = Type::combineUnionTypes($if_context->vars_in_scope[$var_id], $t_else_context->vars_in_scope[$var_id]);
            }
        }
        $redef_var_ifs = array_keys($if_context->getRedefinedVars($context->vars_in_scope));
        $redef_var_else = array_keys($t_else_context->getRedefinedVars($context->vars_in_scope));
        $redef_all = array_intersect($redef_var_ifs, $redef_var_else);
        //these vars were changed in both branches
        foreach ($redef_all as $redef_var_id) {
            $context->vars_in_scope[$redef_var_id] = Type::combineUnionTypes($if_context->vars_in_scope[$redef_var_id], $t_else_context->vars_in_scope[$redef_var_id]);
        }
        //these vars were changed in the if and existed before
        foreach ($redef_var_ifs as $redef_var_ifs_id) {
            if (isset($context->vars_in_scope[$redef_var_ifs_id])) {
                $context->vars_in_scope[$redef_var_ifs_id] = Type::combineUnionTypes($context->vars_in_scope[$redef_var_ifs_id], $if_context->vars_in_scope[$redef_var_ifs_id]);
            }
        }
        //these vars were changed in the else and existed before
        foreach ($redef_var_else as $redef_var_else_id) {
            if (isset($context->vars_in_scope[$redef_var_else_id])) {
                $context->vars_in_scope[$redef_var_else_id] = Type::combineUnionTypes($context->vars_in_scope[$redef_var_else_id], $t_else_context->vars_in_scope[$redef_var_else_id]);
            }
        }
        $context->vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $if_context->vars_possibly_in_scope, $t_else_context->vars_possibly_in_scope);
        $context->cond_referenced_var_ids = array_merge($context->cond_referenced_var_ids, $t_else_context->cond_referenced_var_ids);
        $lhs_type = null;
        $stmt_cond_type = $statements_analyzer->node_data->getType($stmt->cond);
        if ($stmt->if) {
            if ($stmt_if_type = $statements_analyzer->node_data->getType($stmt->if)) {
                $lhs_type = $stmt_if_type;
            }
        } elseif ($stmt_cond_type) {
            $if_return_type_reconciled = AssertionReconciler::reconcile(new Truthy(), $stmt_cond_type, '', $statements_analyzer, $context->inside_loop, [], new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues());
            $lhs_type = $if_return_type_reconciled;
        }
        if ($lhs_type && ($stmt_else_type = $statements_analyzer->node_data->getType($stmt->else))) {
            if ($stmt_cond_type !== null && $stmt_cond_type->isAlwaysFalsy()) {
                $statements_analyzer->node_data->setType($stmt, $stmt_else_type);
            } elseif ($stmt_cond_type !== null && $stmt_cond_type->isAlwaysTruthy()) {
                $statements_analyzer->node_data->setType($stmt, $lhs_type);
            } else {
                $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes($lhs_type, $stmt_else_type));
            }
        } else {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\CircularReferenceException;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\AmbiguousConstantInheritance;
use Psalm\Issue\CircularReference;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\DeprecatedConstant;
use Psalm\Issue\InaccessibleClassConstant;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InvalidClassConstantType;
use Psalm\Issue\InvalidConstantAssignmentValue;
use Psalm\Issue\LessSpecificClassConstantType;
use Psalm\Issue\NonStaticSelfCall;
use Psalm\Issue\OverriddenFinalConstant;
use Psalm\Issue\OverriddenInterfaceConstant;
use Psalm\Issue\ParentNotFound;
use Psalm\Issue\ParseError;
use Psalm\Issue\UndefinedConstant;
use Psalm\IssueBuffer;
use Psalm\Storage\ClassConstantStorage;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Union;
use ReflectionProperty;
use function assert;
use function explode;
use function in_array;
use function strtolower;
/**
 * @internal
 */
class ClassConstAnalyzer
{
    /**
     * @psalm-suppress ComplexMethod to be refactored. We should probably regroup the two big if about $stmt->class and
     * analyse the ::class int $stmt->name separately
     */
    public static function analyzeFetch(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ClassConstFetch $stmt, Context $context) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        if ($stmt->class instanceof PhpParser\Node\Name) {
            $first_part_lc = strtolower($stmt->class->parts[0]);
            if ($first_part_lc === 'self' || $first_part_lc === 'static') {
                if (!$context->self) {
                    return !IssueBuffer::accepts(new NonStaticSelfCall('Cannot use ' . $first_part_lc . ' outside class context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                $fq_class_name = $context->self;
            } elseif ($first_part_lc === 'parent') {
                $fq_class_name = $statements_analyzer->getParentFQCLN();
                if ($fq_class_name === null) {
                    return !IssueBuffer::accepts(new ParentNotFound('Cannot check property fetch on parent as this class does not extend another', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            } else {
                $fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $statements_analyzer->getAliases());
                if ($stmt->name instanceof PhpParser\Node\Identifier) {
                    if ((!$context->inside_class_exists || $stmt->name->name !== 'class') && !isset($context->phantom_classes[strtolower($fq_class_name)])) {
                        if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($statements_analyzer->getSource(), $stmt->class), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\false, \true)) === \false) {
                            return \true;
                        }
                    }
                }
            }
            $fq_class_name_lc = strtolower($fq_class_name);
            $moved_class = \false;
            if ($codebase->alter_code && !in_array($stmt->class->parts[0], ['parent', 'static'])) {
                $moved_class = $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id, \false, $stmt->class->parts[0] === 'self');
            }
            if ($codebase->classlikes->classExists($fq_class_name)) {
                $fq_class_name = $codebase->classlikes->getUnAliasedName($fq_class_name);
            }
            if ($stmt->name instanceof PhpParser\Node\Identifier && $stmt->name->name === 'class') {
                if ($codebase->classlikes->classExists($fq_class_name)) {
                    $const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
                    $fq_class_name = $const_class_storage->name;
                    if ($const_class_storage->deprecated && $fq_class_name !== $context->self) {
                        IssueBuffer::maybeAdd(new DeprecatedClass('Class ' . $fq_class_name . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
                    }
                }
                if ($first_part_lc === 'static') {
                    $static_named_object = new TNamedObject($fq_class_name, \true);
                    $statements_analyzer->node_data->setType($stmt, new Union([new TClassString($fq_class_name, $static_named_object)]));
                } else {
                    $statements_analyzer->node_data->setType($stmt, Type::getLiteralClassString($fq_class_name, \true));
                }
                if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                    $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->class, $fq_class_name);
                }
                return \true;
            }
            // if we're ignoring that the class doesn't exist, exit anyway
            if (!$codebase->classlikes->classOrInterfaceOrEnumExists($fq_class_name)) {
                return \true;
            }
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->class, $fq_class_name);
            }
            if (!$stmt->name instanceof PhpParser\Node\Identifier) {
                return \true;
            }
            $const_id = $fq_class_name . '::' . $stmt->name;
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $const_id);
            }
            $const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
            if ($const_class_storage->is_enum) {
                $case = $const_class_storage->enum_cases[(string) $stmt->name] ?? null;
                if ($case && $case->deprecated) {
                    IssueBuffer::maybeAdd(new DeprecatedConstant("Enum Case {$const_id} is marked as deprecated", new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            }
            if ($fq_class_name === $context->self || $statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer && $fq_class_name === $statements_analyzer->getSource()->getFQCLN()) {
                $class_visibility = ReflectionProperty::IS_PRIVATE;
            } elseif ($context->self && ($codebase->classlikes->classExtends($context->self, $fq_class_name) || $codebase->classlikes->classExtends($fq_class_name, $context->self))) {
                $class_visibility = ReflectionProperty::IS_PROTECTED;
            } else {
                $class_visibility = ReflectionProperty::IS_PUBLIC;
            }
            try {
                $class_constant_type = $codebase->classlikes->getClassConstantType($fq_class_name, $stmt->name->name, $class_visibility, $statements_analyzer, [], $stmt->class->parts[0] === "static");
            } catch (InvalidArgumentException $_) {
                return \true;
            } catch (CircularReferenceException $e) {
                IssueBuffer::maybeAdd(new CircularReference('Constant ' . $const_id . ' contains a circular reference', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                return \true;
            }
            if (!$class_constant_type) {
                if ($fq_class_name !== $context->self) {
                    $class_constant_type = $codebase->classlikes->getClassConstantType($fq_class_name, $stmt->name->name, ReflectionProperty::IS_PRIVATE, $statements_analyzer);
                }
                if ($class_constant_type) {
                    IssueBuffer::maybeAdd(new InaccessibleClassConstant('Constant ' . $const_id . ' is not visible in this context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } elseif ($context->check_consts) {
                    IssueBuffer::maybeAdd(new UndefinedConstant('Constant ' . $const_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                return \true;
            }
            if ($context->calling_method_id) {
                $codebase->file_reference_provider->addMethodReferenceToClassMember($context->calling_method_id, $fq_class_name_lc . '::' . $stmt->name->name, \false);
            }
            $declaring_const_id = $fq_class_name_lc . '::' . $stmt->name->name;
            if ($codebase->alter_code && !$moved_class) {
                foreach ($codebase->class_constant_transforms as $original_pattern => $transformation) {
                    if ($declaring_const_id === $original_pattern) {
                        [$new_fq_class_name, $new_const_name] = explode('::', $transformation);
                        $file_manipulations = [];
                        if (strtolower($new_fq_class_name) !== $fq_class_name_lc) {
                            $file_manipulations[] = new FileManipulation((int) $stmt->class->getAttribute('startFilePos'), (int) $stmt->class->getAttribute('endFilePos') + 1, Type::getStringFromFQCLN($new_fq_class_name, $statements_analyzer->getNamespace(), $statements_analyzer->getAliasedClassesFlipped(), null));
                        }
                        $file_manipulations[] = new FileManipulation((int) $stmt->name->getAttribute('startFilePos'), (int) $stmt->name->getAttribute('endFilePos') + 1, $new_const_name);
                        FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                    }
                }
            }
            if ($context->self && !$context->collect_initializations && !$context->collect_mutations && !NamespaceAnalyzer::isWithinAny($context->self, $const_class_storage->internal)) {
                IssueBuffer::maybeAdd(new InternalClass($fq_class_name . ' is internal to ' . InternalClass::listToPhrase($const_class_storage->internal) . ' but called from ' . $context->self, new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
            }
            if ($const_class_storage->deprecated && $fq_class_name !== $context->self) {
                IssueBuffer::maybeAdd(new DeprecatedClass('Class ' . $fq_class_name . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
            } elseif (isset($const_class_storage->constants[$stmt->name->name]) && $const_class_storage->constants[$stmt->name->name]->deprecated) {
                IssueBuffer::maybeAdd(new DeprecatedConstant('Constant ' . $const_id . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            if ($first_part_lc !== 'static' || $const_class_storage->final || $class_constant_type->from_docblock) {
                $stmt_type = $class_constant_type;
                $statements_analyzer->node_data->setType($stmt, $stmt_type);
                $context->vars_in_scope[$const_id] = $stmt_type;
            }
            return \true;
        }
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->class, $context) === \false) {
            $context->inside_general_use = $was_inside_general_use;
            return \false;
        }
        $context->inside_general_use = $was_inside_general_use;
        $lhs_type = $statements_analyzer->node_data->getType($stmt->class);
        if ($lhs_type === null) {
            return \true;
        }
        if ($stmt->name instanceof PhpParser\Node\Identifier && $stmt->name->name === 'class') {
            $class_string_types = [];
            $has_mixed_or_object = \false;
            foreach ($lhs_type->getAtomicTypes() as $lhs_atomic_type) {
                if ($lhs_atomic_type instanceof TNamedObject) {
                    $class_string_types[] = new TClassString($lhs_atomic_type->value, $lhs_atomic_type);
                } elseif ($lhs_atomic_type instanceof TTemplateParam && $lhs_atomic_type->as->isSingle()) {
                    $as_atomic_type = $lhs_atomic_type->as->getSingleAtomic();
                    if ($as_atomic_type instanceof TObject) {
                        $class_string_types[] = new TTemplateParamClass($lhs_atomic_type->param_name, 'object', null, $lhs_atomic_type->defining_class);
                    } elseif ($as_atomic_type instanceof TNamedObject) {
                        $class_string_types[] = new TTemplateParamClass($lhs_atomic_type->param_name, $as_atomic_type->value, $as_atomic_type, $lhs_atomic_type->defining_class);
                    }
                } elseif ($lhs_atomic_type instanceof TObject || $lhs_atomic_type instanceof TMixed) {
                    $has_mixed_or_object = \true;
                }
            }
            if ($has_mixed_or_object) {
                $statements_analyzer->node_data->setType($stmt, new Union([new TClassString()]));
            } elseif ($class_string_types) {
                $statements_analyzer->node_data->setType($stmt, new Union($class_string_types));
            }
            return \true;
        }
        if ($stmt->class instanceof PhpParser\Node\Expr\Variable) {
            $fq_class_name = null;
            $lhs_type_definite_class = null;
            if ($lhs_type->isSingle()) {
                $atomic_type = $lhs_type->getSingleAtomic();
                if ($atomic_type instanceof TNamedObject) {
                    $fq_class_name = $atomic_type->value;
                    $lhs_type_definite_class = $atomic_type->definite_class;
                } elseif ($atomic_type instanceof TLiteralClassString) {
                    $fq_class_name = $atomic_type->value;
                    $lhs_type_definite_class = $atomic_type->definite_class;
                }
            }
            if ($fq_class_name === null || $lhs_type_definite_class === null) {
                return \true;
            }
            if ($codebase->classlikes->classExists($fq_class_name)) {
                $fq_class_name = $codebase->classlikes->getUnAliasedName($fq_class_name);
            }
            $moved_class = \false;
            if ($codebase->alter_code) {
                $moved_class = $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id);
            }
            // if we're ignoring that the class doesn't exist, exit anyway
            if (!$codebase->classlikes->classOrInterfaceOrEnumExists($fq_class_name)) {
                return \true;
            }
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->class, $fq_class_name);
            }
            if (!$stmt->name instanceof PhpParser\Node\Identifier) {
                return \true;
            }
            $const_id = $fq_class_name . '::' . $stmt->name;
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $const_id);
            }
            $const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
            if ($fq_class_name === $context->self || $statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer && $fq_class_name === $statements_analyzer->getSource()->getFQCLN()) {
                $class_visibility = ReflectionProperty::IS_PRIVATE;
            } elseif ($context->self && ($codebase->classlikes->classExtends($context->self, $fq_class_name) || $codebase->classlikes->classExtends($fq_class_name, $context->self))) {
                $class_visibility = ReflectionProperty::IS_PROTECTED;
            } else {
                $class_visibility = ReflectionProperty::IS_PUBLIC;
            }
            try {
                $class_constant_type = $codebase->classlikes->getClassConstantType($fq_class_name, $stmt->name->name, $class_visibility, $statements_analyzer);
            } catch (InvalidArgumentException $_) {
                return \true;
            } catch (CircularReferenceException $e) {
                IssueBuffer::maybeAdd(new CircularReference('Constant ' . $const_id . ' contains a circular reference', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                return \true;
            }
            if (!$class_constant_type) {
                if ($fq_class_name !== $context->self) {
                    $class_constant_type = $codebase->classlikes->getClassConstantType($fq_class_name, $stmt->name->name, ReflectionProperty::IS_PRIVATE, $statements_analyzer);
                }
                if ($class_constant_type) {
                    IssueBuffer::maybeAdd(new InaccessibleClassConstant('Constant ' . $const_id . ' is not visible in this context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } elseif ($context->check_consts) {
                    IssueBuffer::maybeAdd(new UndefinedConstant('Constant ' . $const_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                return \true;
            }
            if ($context->calling_method_id) {
                $codebase->file_reference_provider->addMethodReferenceToClassMember($context->calling_method_id, strtolower($fq_class_name) . '::' . $stmt->name->name, \false);
            }
            $declaring_const_id = strtolower($fq_class_name) . '::' . $stmt->name->name;
            if ($codebase->alter_code && !$moved_class) {
                foreach ($codebase->class_constant_transforms as $original_pattern => $transformation) {
                    if ($declaring_const_id === $original_pattern) {
                        [, $new_const_name] = explode('::', $transformation);
                        $file_manipulations = [];
                        $file_manipulations[] = new FileManipulation((int) $stmt->name->getAttribute('startFilePos'), (int) $stmt->name->getAttribute('endFilePos') + 1, $new_const_name);
                        FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                    }
                }
            }
            if ($context->self && !$context->collect_initializations && !$context->collect_mutations && !NamespaceAnalyzer::isWithinAny($context->self, $const_class_storage->internal)) {
                IssueBuffer::maybeAdd(new InternalClass($fq_class_name . ' is internal to ' . InternalClass::listToPhrase($const_class_storage->internal) . ' but called from ' . $context->self, new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
            }
            if ($const_class_storage->deprecated && $fq_class_name !== $context->self) {
                IssueBuffer::maybeAdd(new DeprecatedClass('Class ' . $fq_class_name . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
            } elseif (isset($const_class_storage->constants[$stmt->name->name]) && $const_class_storage->constants[$stmt->name->name]->deprecated) {
                IssueBuffer::maybeAdd(new DeprecatedConstant('Constant ' . $const_id . ' is deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            if ($const_class_storage->final || $lhs_type_definite_class === \true) {
                $stmt_type = $class_constant_type;
                $statements_analyzer->node_data->setType($stmt, $stmt_type);
                $context->vars_in_scope[$const_id] = $stmt_type;
            }
            return \true;
        }
        return \true;
    }
    public static function analyzeAssignment(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\ClassConst $stmt, Context $context) : void
    {
        assert($context->self !== null);
        $class_storage = $statements_analyzer->getCodebase()->classlike_storage_provider->get($context->self);
        foreach ($stmt->consts as $const) {
            ExpressionAnalyzer::analyze($statements_analyzer, $const->value, $context);
            $const_storage = $class_storage->constants[$const->name->name];
            // Check assigned type matches docblock type
            if ($assigned_type = $statements_analyzer->node_data->getType($const->value)) {
                if ($const_storage->type !== null && $const_storage->stmt_location !== null && $assigned_type !== $const_storage->type && !UnionTypeComparator::isContainedBy($statements_analyzer->getCodebase(), $assigned_type, $const_storage->type)) {
                    IssueBuffer::maybeAdd(new InvalidConstantAssignmentValue("{$class_storage->name}::{$const->name->name} with declared type " . "{$const_storage->type->getId()} cannot be assigned type {$assigned_type->getId()}", $const_storage->stmt_location, "{$class_storage->name}::{$const->name->name}"), $const_storage->suppressed_issues);
                }
            }
        }
    }
    public static function analyze(ClassLikeStorage $class_storage, Codebase $codebase) : void
    {
        foreach ($class_storage->constants as $const_name => $const_storage) {
            [$parent_classlike_storage, $parent_const_storage] = self::getOverriddenConstant($class_storage, $const_storage, $const_name, $codebase);
            $type_location = $const_storage->location ?? $const_storage->stmt_location;
            if ($type_location === null) {
                continue;
            }
            if ($parent_const_storage !== null) {
                assert($parent_classlike_storage !== null);
                // Check covariance
                if ($const_storage->type !== null && $parent_const_storage->type !== null && !UnionTypeComparator::isContainedBy($codebase, $const_storage->type, $parent_const_storage->type)) {
                    if (UnionTypeComparator::isContainedBy($codebase, $parent_const_storage->type, $const_storage->type)) {
                        // Contravariant
                        IssueBuffer::maybeAdd(new LessSpecificClassConstantType("The type \"{$const_storage->type->getId()}\" for {$class_storage->name}::" . "{$const_name} is more general than the type " . "\"{$parent_const_storage->type->getId()}\" inherited from " . "{$parent_classlike_storage->name}::{$const_name}", $type_location, "{$class_storage->name}::{$const_name}"), $const_storage->suppressed_issues);
                    } else {
                        // Completely different
                        IssueBuffer::maybeAdd(new InvalidClassConstantType("The type \"{$const_storage->type->getId()}\" for {$class_storage->name}::" . "{$const_name} does not satisfy the type " . "\"{$parent_const_storage->type->getId()}\" inherited from " . "{$parent_classlike_storage->name}::{$const_name}", $type_location, "{$class_storage->name}::{$const_name}"), $const_storage->suppressed_issues);
                    }
                }
                // Check overridden final
                if ($parent_const_storage->final && $parent_const_storage !== $const_storage) {
                    IssueBuffer::maybeAdd(new OverriddenFinalConstant("{$const_name} cannot be overridden because it is marked as final in " . $parent_classlike_storage->name, $type_location, "{$class_storage->name}::{$const_name}"), $const_storage->suppressed_issues);
                }
            }
            if ($const_storage->stmt_location !== null) {
                // Check final in PHP < 8.1
                if ($codebase->analysis_php_version_id < 80100 && $const_storage->final) {
                    IssueBuffer::maybeAdd(new ParseError("Class constants cannot be marked final before PHP 8.1", $const_storage->stmt_location), $const_storage->suppressed_issues);
                }
            }
        }
    }
    /**
     * Get the const storage from the parent or interface that this class is overriding.
     *
     * @return array{ClassLikeStorage, ClassConstantStorage}|null
     */
    private static function getOverriddenConstant(ClassLikeStorage $class_storage, ClassConstantStorage $const_storage, string $const_name, Codebase $codebase) : ?array
    {
        $parent_classlike_storage = $interface_const_storage = $parent_const_storage = null;
        $interface_overrides = [];
        foreach ($class_storage->class_implements ?: $class_storage->direct_interface_parents as $interface) {
            $interface_storage = $codebase->classlike_storage_provider->get($interface);
            $parent_const_storage = $interface_storage->constants[$const_name] ?? null;
            if ($parent_const_storage !== null) {
                if ($const_storage->location && $const_storage !== $parent_const_storage && $codebase->analysis_php_version_id < 80100) {
                    $interface_overrides[strtolower($interface)] = new OverriddenInterfaceConstant("{$class_storage->name}::{$const_name} cannot override constant from {$interface}", $const_storage->location, "{$class_storage->name}::{$const_name}");
                }
                if ($interface_const_storage !== null && $const_storage->location !== null) {
                    assert($parent_classlike_storage !== null);
                    if (!isset($parent_classlike_storage->parent_interfaces[strtolower($interface)]) && !isset($interface_storage->parent_interfaces[strtolower($parent_classlike_storage->name)])) {
                        IssueBuffer::maybeAdd(new AmbiguousConstantInheritance("Ambiguous inheritance of {$class_storage->name}::{$const_name} from {$interface} and " . $parent_classlike_storage->name, $const_storage->location, "{$class_storage->name}::{$const_name}"), $const_storage->suppressed_issues);
                    }
                }
                $interface_const_storage = $parent_const_storage;
                $parent_classlike_storage = $interface_storage;
            }
        }
        foreach ($class_storage->parent_classes as $parent_class) {
            $parent_class_storage = $codebase->classlike_storage_provider->get($parent_class);
            $parent_const_storage = $parent_class_storage->constants[$const_name] ?? null;
            if ($parent_const_storage !== null) {
                if ($const_storage->location !== null && $interface_const_storage !== null) {
                    assert($parent_classlike_storage !== null);
                    if (!isset($parent_class_storage->class_implements[strtolower($parent_classlike_storage->name)])) {
                        IssueBuffer::maybeAdd(new AmbiguousConstantInheritance("Ambiguous inheritance of {$class_storage->name}::{$const_name} from " . "{$parent_classlike_storage->name} and {$parent_class}", $const_storage->location, "{$class_storage->name}::{$const_name}"), $const_storage->suppressed_issues);
                    }
                }
                foreach ($interface_overrides as $interface_lc => $_) {
                    // If the parent is the one with the const that's overriding the interface const, and the parent
                    // doesn't implement the interface, it's just an AmbiguousConstantInheritance, not an
                    // OverriddenInterfaceConstant
                    if (!isset($parent_class_storage->class_implements[$interface_lc]) && $parent_const_storage === $const_storage) {
                        unset($interface_overrides[$interface_lc]);
                    }
                }
                $parent_classlike_storage = $parent_class_storage;
                break;
            }
        }
        if ($parent_const_storage === null) {
            $parent_const_storage = $interface_const_storage;
        }
        foreach ($interface_overrides as $_ => $issue) {
            IssueBuffer::maybeAdd($issue, $const_storage->suppressed_issues);
        }
        if ($parent_classlike_storage !== null) {
            assert($parent_const_storage !== null);
            return [$parent_classlike_storage, $parent_const_storage];
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use AssertionError;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\Exception\FileIncludeException;
use Psalm\Exception\UnpreparedAnalysisException;
use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Issue\MissingFile;
use Psalm\Issue\UnresolvableInclude;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Type\TaintKind;
use function constant;
use function defined;
use function dirname;
use function explode;
use function file_exists;
use function get_include_path;
use function get_included_files;
use function implode;
use function in_array;
use function is_string;
use function preg_last_error_msg;
use function preg_match;
use function preg_replace;
use function preg_split;
use function realpath;
use function str_repeat;
use function str_replace;
use function substr;
use const DIRECTORY_SEPARATOR;
use const PATH_SEPARATOR;
use const PHP_EOL;
/**
 * @internal
 */
class IncludeAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Include_ $stmt, Context $context, ?Context $global_context = null) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $config = $codebase->config;
        if (!$config->allow_includes) {
            throw new FileIncludeException('File includes are not allowed per your Psalm config - check the allowFileIncludes flag.');
        }
        $was_inside_call = $context->inside_call;
        $context->inside_call = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            $context->inside_call = $was_inside_call;
            return \false;
        }
        $context->inside_call = $was_inside_call;
        $stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr);
        if ($stmt->expr instanceof PhpParser\Node\Scalar\String_ || $stmt_expr_type && $stmt_expr_type->isSingleStringLiteral()) {
            if ($stmt->expr instanceof PhpParser\Node\Scalar\String_) {
                $path_to_file = $stmt->expr->value;
            } else {
                $path_to_file = $stmt_expr_type->getSingleStringLiteral()->value;
            }
            $path_to_file = str_replace('/', DIRECTORY_SEPARATOR, $path_to_file);
            // attempts to resolve using get_include_path dirs
            $include_path = self::resolveIncludePath($path_to_file, dirname($statements_analyzer->getFilePath()));
            $path_to_file = $include_path ?: $path_to_file;
            if (DIRECTORY_SEPARATOR === '/') {
                $is_path_relative = $path_to_file[0] !== DIRECTORY_SEPARATOR;
            } else {
                $is_path_relative = !preg_match('~^[A-Z]:\\\\~i', $path_to_file);
            }
            if ($is_path_relative) {
                $path_to_file = $config->base_dir . DIRECTORY_SEPARATOR . $path_to_file;
            }
        } else {
            $path_to_file = self::getPathTo($stmt->expr, $statements_analyzer->node_data, $statements_analyzer, $statements_analyzer->getFileName(), $config);
        }
        if ($stmt_expr_type && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $stmt_expr_type->parent_nodes && !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
            $arg_location = new CodeLocation($statements_analyzer->getSource(), $stmt->expr);
            $include_param_sink = TaintSink::getForMethodArgument('include', 'include', 0, $arg_location, $arg_location);
            $include_param_sink->taints = [TaintKind::INPUT_INCLUDE];
            $statements_analyzer->data_flow_graph->addSink($include_param_sink);
            $codebase = $statements_analyzer->getCodebase();
            $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
            $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
            $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
            foreach ($stmt_expr_type->parent_nodes as $parent_node) {
                $statements_analyzer->data_flow_graph->addPath($parent_node, $include_param_sink, 'arg', $added_taints, $removed_taints);
            }
        }
        if ($path_to_file) {
            $path_to_file = self::normalizeFilePath($path_to_file);
            // if the file is already included, we can't check much more
            if (in_array(realpath($path_to_file), get_included_files(), \true)) {
                return \true;
            }
            $current_file_analyzer = $statements_analyzer->getFileAnalyzer();
            if ($current_file_analyzer->project_analyzer->fileExists($path_to_file)) {
                if ($statements_analyzer->hasParentFilePath($path_to_file) || !$codebase->file_storage_provider->has($path_to_file) || $statements_analyzer->hasAlreadyRequiredFilePath($path_to_file) && !$codebase->file_storage_provider->get($path_to_file)->has_extra_statements) {
                    return \true;
                }
                if ($config->mustBeIgnored($path_to_file)) {
                    return \true;
                }
                $current_file_analyzer->addRequiredFilePath($path_to_file);
                $file_name = $config->shortenFileName($path_to_file);
                $nesting = $statements_analyzer->getRequireNesting() + 1;
                $current_file_analyzer->project_analyzer->progress->debug(str_repeat('  ', $nesting) . 'checking ' . $file_name . PHP_EOL);
                $include_file_analyzer = new FileAnalyzer($current_file_analyzer->project_analyzer, $path_to_file, $file_name);
                $include_file_analyzer->setRootFilePath($current_file_analyzer->getRootFilePath(), $current_file_analyzer->getRootFileName());
                $include_file_analyzer->addParentFilePath($current_file_analyzer->getFilePath());
                $include_file_analyzer->addRequiredFilePath($current_file_analyzer->getFilePath());
                foreach ($current_file_analyzer->getRequiredFilePaths() as $required_file_path) {
                    $include_file_analyzer->addRequiredFilePath($required_file_path);
                }
                foreach ($current_file_analyzer->getParentFilePaths() as $parent_file_path) {
                    $include_file_analyzer->addParentFilePath($parent_file_path);
                }
                try {
                    $include_file_analyzer->analyze($context, $global_context);
                } catch (UnpreparedAnalysisException $e) {
                    if ($config->skip_checks_on_unresolvable_includes) {
                        $context->check_classes = \false;
                        $context->check_variables = \false;
                        $context->check_functions = \false;
                    }
                }
                $included_return_type = $include_file_analyzer->getReturnType();
                if ($included_return_type) {
                    $statements_analyzer->node_data->setType($stmt, $included_return_type);
                }
                $context->has_returned = \false;
                foreach ($include_file_analyzer->getRequiredFilePaths() as $required_file_path) {
                    $current_file_analyzer->addRequiredFilePath($required_file_path);
                }
                $include_file_analyzer->clearSourceBeforeDestruction();
                return \true;
            }
            if (isset($context->phantom_files[$path_to_file])) {
                return \true;
            }
            $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($stmt->expr, null);
            if ($var_id && isset($context->phantom_files[$var_id])) {
                return \true;
            }
            $source = $statements_analyzer->getSource();
            IssueBuffer::maybeAdd(new MissingFile('Cannot find file ' . $path_to_file . ' to include', new CodeLocation($source, $stmt)), $source->getSuppressedIssues());
        } else {
            $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($stmt->expr, null);
            if (!$var_id || !isset($context->phantom_files[$var_id])) {
                $source = $statements_analyzer->getSource();
                IssueBuffer::maybeAdd(new UnresolvableInclude('Cannot resolve the given expression to a file path', new CodeLocation($source, $stmt)), $source->getSuppressedIssues());
            }
        }
        if ($config->skip_checks_on_unresolvable_includes) {
            $context->check_classes = \false;
            $context->check_variables = \false;
            $context->check_functions = \false;
        }
        return \true;
    }
    /**
     * @psalm-suppress MixedAssignment
     */
    public static function getPathTo(PhpParser\Node\Expr $stmt, ?NodeDataProvider $type_provider, ?StatementsAnalyzer $statements_analyzer, string $file_name, Config $config) : ?string
    {
        if (DIRECTORY_SEPARATOR === '/') {
            $is_path_relative = $file_name[0] !== DIRECTORY_SEPARATOR;
        } else {
            $is_path_relative = !preg_match('~^[A-Z]:\\\\~i', $file_name);
        }
        if ($is_path_relative) {
            $file_name = $config->base_dir . DIRECTORY_SEPARATOR . $file_name;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\String_) {
            if (DIRECTORY_SEPARATOR !== '/') {
                return str_replace('/', DIRECTORY_SEPARATOR, $stmt->value);
            }
            return $stmt->value;
        }
        $stmt_type = $type_provider ? $type_provider->getType($stmt) : null;
        if ($stmt_type && $stmt_type->isSingleStringLiteral()) {
            if (DIRECTORY_SEPARATOR !== '/') {
                return str_replace('/', DIRECTORY_SEPARATOR, $stmt_type->getSingleStringLiteral()->value);
            }
            return $stmt_type->getSingleStringLiteral()->value;
        }
        if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch) {
            if ($stmt->var instanceof PhpParser\Node\Expr\Variable && $stmt->var->name === 'GLOBALS' && $stmt->dim instanceof PhpParser\Node\Scalar\String_) {
                if (isset($GLOBALS[$stmt->dim->value]) && is_string($GLOBALS[$stmt->dim->value])) {
                    /** @var string */
                    return $GLOBALS[$stmt->dim->value];
                }
            }
        } elseif ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
            $left_string = self::getPathTo($stmt->left, $type_provider, $statements_analyzer, $file_name, $config);
            $right_string = self::getPathTo($stmt->right, $type_provider, $statements_analyzer, $file_name, $config);
            if ($left_string && $right_string) {
                return $left_string . $right_string;
            }
        } elseif ($stmt instanceof PhpParser\Node\Expr\FuncCall && $stmt->name instanceof PhpParser\Node\Name && $stmt->name->parts === ['dirname']) {
            if ($stmt->getArgs()) {
                $dir_level = 1;
                if (isset($stmt->getArgs()[1])) {
                    if ($stmt->getArgs()[1]->value instanceof PhpParser\Node\Scalar\LNumber) {
                        $dir_level = $stmt->getArgs()[1]->value->value;
                    } else {
                        if ($statements_analyzer) {
                            $t = $statements_analyzer->node_data->getType($stmt->getArgs()[1]->value);
                            if ($t && $t->isSingleIntLiteral()) {
                                $dir_level = $t->getSingleIntLiteral()->value;
                            } else {
                                return null;
                            }
                        } else {
                            return null;
                        }
                    }
                }
                $evaled_path = self::getPathTo($stmt->getArgs()[0]->value, $type_provider, $statements_analyzer, $file_name, $config);
                if (!$evaled_path) {
                    return null;
                }
                return dirname($evaled_path, $dir_level);
            }
        } elseif ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
            $const_name = implode('', $stmt->name->parts);
            if (defined($const_name)) {
                $constant_value = constant($const_name);
                if (is_string($constant_value)) {
                    return $constant_value;
                }
            }
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Dir) {
            return dirname($file_name);
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\File) {
            return $file_name;
        }
        return null;
    }
    public static function resolveIncludePath(string $file_name, string $current_directory) : ?string
    {
        if (!$current_directory) {
            return $file_name;
        }
        $paths = PATH_SEPARATOR === ':' ? preg_split('#(?<!phar):#', get_include_path()) : explode(PATH_SEPARATOR, get_include_path());
        if ($paths === \false) {
            throw new AssertionError(preg_last_error_msg());
        }
        foreach ($paths as $prefix) {
            $ds = substr($prefix, -1) === DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
            if ($prefix === '.') {
                $prefix = $current_directory;
            }
            $file = $prefix . $ds . $file_name;
            if (file_exists($file)) {
                return $file;
            }
        }
        return null;
    }
    /**
     * @psalm-pure
     */
    public static function normalizeFilePath(string $path_to_file) : string
    {
        // replace all \ with / for normalization
        $path_to_file = str_replace('\\', '/', $path_to_file);
        $path_to_file = str_replace('/./', '/', $path_to_file);
        // first remove unnecessary / duplicates
        $path_to_file = preg_replace('/\\/[\\/]+/', '/', $path_to_file);
        $reduce_pattern = '/\\/[^\\/]+\\/\\.\\.\\//';
        while (preg_match($reduce_pattern, $path_to_file)) {
            $path_to_file = preg_replace($reduce_pattern, '/', $path_to_file, 1);
        }
        if (DIRECTORY_SEPARATOR !== '/') {
            $path_to_file = str_replace('/', DIRECTORY_SEPARATOR, $path_to_file);
        }
        return $path_to_file;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Equal;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Greater;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\GreaterOrEqual;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Identical;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\NotEqual;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\NotIdentical;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Smaller;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\SmallerOrEqual;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\UnaryMinus;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\UnaryPlus;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\LNumber;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\FileSource;
use Psalm\Internal\Algebra;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DocblockTypeContradiction;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\RedundantCondition;
use Psalm\Issue\RedundantConditionGivenDocblockType;
use Psalm\Issue\RedundantIdentityWithTrue;
use Psalm\Issue\TypeDoesNotContainNull;
use Psalm\Issue\TypeDoesNotContainType;
use Psalm\Issue\UnevaluatedCode;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\BinaryOp\VirtualIdentical;
use Psalm\Node\Expr\BinaryOp\VirtualNotIdentical;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\ArrayKeyExists;
use Psalm\Storage\Assertion\DoesNotHaveAtLeastCount;
use Psalm\Storage\Assertion\DoesNotHaveExactCount;
use Psalm\Storage\Assertion\Empty_;
use Psalm\Storage\Assertion\Falsy;
use Psalm\Storage\Assertion\HasAtLeastCount;
use Psalm\Storage\Assertion\HasExactCount;
use Psalm\Storage\Assertion\HasMethod;
use Psalm\Storage\Assertion\InArray;
use Psalm\Storage\Assertion\IsAClass;
use Psalm\Storage\Assertion\IsClassEqual;
use Psalm\Storage\Assertion\IsClassNotEqual;
use Psalm\Storage\Assertion\IsCountable;
use Psalm\Storage\Assertion\IsEqualIsset;
use Psalm\Storage\Assertion\IsGreaterThan;
use Psalm\Storage\Assertion\IsGreaterThanOrEqualTo;
use Psalm\Storage\Assertion\IsIdentical;
use Psalm\Storage\Assertion\IsIsset;
use Psalm\Storage\Assertion\IsLessThan;
use Psalm\Storage\Assertion\IsLessThanOrEqualTo;
use Psalm\Storage\Assertion\IsLooselyEqual;
use Psalm\Storage\Assertion\IsNotIdentical;
use Psalm\Storage\Assertion\IsNotLooselyEqual;
use Psalm\Storage\Assertion\IsNotType;
use Psalm\Storage\Assertion\IsType;
use Psalm\Storage\Assertion\NestedAssertions;
use Psalm\Storage\Assertion\NonEmptyCountable;
use Psalm\Storage\Assertion\NotNonEmptyCountable;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Storage\Possibilities;
use Psalm\Storage\PropertyStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosedResource;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TResource;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTraitString;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_key_exists;
use function assert;
use function count;
use function explode;
use function in_array;
use function is_int;
use function is_numeric;
use function is_string;
use function sprintf;
use function str_replace;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 * This class transform conditions in code into "assertions" that will be reconciled with the type already known of a
 * given variable to narrow the type or find paradox.
 * For example if $a is an int, if($a > 0) will be turned into an assertion to make psalm understand that in the
 * if block, $a is a positive-int
 */
class AssertionFinder
{
    public const ASSIGNMENT_TO_RIGHT = 1;
    public const ASSIGNMENT_TO_LEFT = -1;
    /**
     * Gets all the type assertions in a conditional
     *
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    public static function scrapeAssertions(PhpParser\Node\Expr $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase = null, bool $inside_negation = \false, bool $cache = \true, bool $inside_conditional = \true) : array
    {
        $if_types = [];
        if ($conditional instanceof PhpParser\Node\Expr\Instanceof_) {
            return self::getAndCheckInstanceofAssertions($conditional, $codebase, $source, $this_class_name, $inside_negation);
        }
        if ($conditional instanceof PhpParser\Node\Expr\Assign) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->var, $this_class_name, $source);
            $candidate_if_types = $inside_conditional ? self::scrapeAssertions($conditional->expr, $this_class_name, $source, $codebase, $inside_negation, $cache, $inside_conditional) : [];
            if ($var_name) {
                if ($candidate_if_types) {
                    $if_types[$var_name] = [[new NestedAssertions($candidate_if_types[0])]];
                } else {
                    $if_types[$var_name] = [[new Truthy()]];
                }
            }
            return $if_types ? [$if_types] : [];
        }
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional, $this_class_name, $source);
        if ($var_name) {
            $if_types[$var_name] = [[new Truthy()]];
            if (!$conditional instanceof PhpParser\Node\Expr\MethodCall && !$conditional instanceof PhpParser\Node\Expr\StaticCall) {
                return [$if_types];
            }
        }
        if ($conditional instanceof PhpParser\Node\Expr\BooleanNot) {
            return [];
        }
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical || $conditional instanceof PhpParser\Node\Expr\BinaryOp\Equal) {
            return self::scrapeEqualityAssertions($conditional, $this_class_name, $source, $codebase, $cache, $inside_conditional);
        }
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical || $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotEqual) {
            return self::scrapeInequalityAssertions($conditional, $this_class_name, $source, $codebase, $cache, $inside_conditional);
        }
        //A nullsafe method call basically adds an assertion !null for the checked variable
        if ($conditional instanceof PhpParser\Node\Expr\NullsafeMethodCall) {
            $if_types = [];
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->var, $this_class_name, $source);
            if ($var_name) {
                $if_types[$var_name] = [[new IsNotType(new TNull())]];
            }
            //we may throw a RedundantNullsafeMethodCall here in the future if $var_name is never null
            return $if_types ? [$if_types] : [];
        }
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Greater || $conditional instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual) {
            return self::getGreaterAssertions($conditional, $source, $this_class_name);
        }
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Smaller || $conditional instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual) {
            return self::getSmallerAssertions($conditional, $source, $this_class_name);
        }
        if ($conditional instanceof PhpParser\Node\Expr\FuncCall && !$conditional->isFirstClassCallable()) {
            return self::processFunctionCall($conditional, $this_class_name, $source, $codebase, $inside_negation);
        }
        if (($conditional instanceof PhpParser\Node\Expr\MethodCall || $conditional instanceof PhpParser\Node\Expr\StaticCall) && !$conditional->isFirstClassCallable()) {
            $custom_assertions = self::processCustomAssertion($conditional, $this_class_name, $source);
            if ($custom_assertions) {
                return $custom_assertions;
            }
            return $if_types ? [$if_types] : [];
        }
        if ($conditional instanceof PhpParser\Node\Expr\Empty_) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->expr, $this_class_name, $source);
            if ($var_name) {
                if ($conditional->expr instanceof PhpParser\Node\Expr\Variable && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($conditional->expr)) && !$var_type->isMixed() && !$var_type->possibly_undefined) {
                    $if_types[$var_name] = [[new Falsy()]];
                } else {
                    $if_types[$var_name] = [[new Empty_()]];
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if ($conditional instanceof PhpParser\Node\Expr\Isset_) {
            foreach ($conditional->vars as $isset_var) {
                $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($isset_var, $this_class_name, $source);
                if ($var_name) {
                    if ($isset_var instanceof PhpParser\Node\Expr\Variable && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($isset_var)) && !$var_type->isMixed() && !$var_type->possibly_undefined && !$var_type->possibly_undefined_from_try) {
                        $if_types[$var_name] = [[new IsNotType(new TNull())]];
                    } else {
                        $if_types[$var_name] = [[new IsIsset()]];
                    }
                } else {
                    // look for any variables we *can* use for an isset assertion
                    $array_root = $isset_var;
                    while ($array_root instanceof PhpParser\Node\Expr\ArrayDimFetch && !$var_name) {
                        $array_root = $array_root->var;
                        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($array_root, $this_class_name, $source);
                    }
                    if ($var_name) {
                        $if_types[$var_name] = [[new IsEqualIsset()]];
                    }
                }
            }
            return $if_types ? [$if_types] : [];
        }
        return [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function scrapeEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase = null, bool $cache = \true, bool $inside_conditional = \true) : array
    {
        $null_position = self::hasNullVariable($conditional, $source);
        if ($null_position !== null) {
            return self::getNullEqualityAssertions($conditional, $this_class_name, $source, $codebase, $null_position);
        }
        $false_position = self::hasFalseVariable($conditional);
        if ($false_position) {
            return self::getFalseEqualityAssertions($conditional, $this_class_name, $source, $codebase, $false_position, $cache, $inside_conditional);
        }
        $true_position = self::hasTrueVariable($conditional);
        if ($true_position) {
            return self::getTrueEqualityAssertions($conditional, $this_class_name, $source, $codebase, $true_position, $cache, $inside_conditional);
        }
        $empty_array_position = self::hasEmptyArrayVariable($conditional);
        if ($empty_array_position !== null) {
            return self::getEmptyArrayEqualityAssertions($conditional, $this_class_name, $source, $codebase, $empty_array_position);
        }
        $gettype_position = self::hasGetTypeCheck($conditional);
        if ($gettype_position) {
            return self::getGettypeEqualityAssertions($conditional, $this_class_name, $source, $gettype_position);
        }
        $get_debug_type_position = self::hasGetDebugTypeCheck($conditional);
        if ($get_debug_type_position) {
            return self::getGetdebugtypeEqualityAssertions($conditional, $this_class_name, $source, $get_debug_type_position);
        }
        $count = null;
        $count_equality_position = self::hasCountEqualityCheck($conditional, $count);
        if ($count_equality_position) {
            $if_types = [];
            if ($count_equality_position === self::ASSIGNMENT_TO_RIGHT) {
                $count_expr = $conditional->left;
            } elseif ($count_equality_position === self::ASSIGNMENT_TO_LEFT) {
                $count_expr = $conditional->right;
            } else {
                throw new UnexpectedValueException('$count_equality_position value');
            }
            /** @var PhpParser\Node\Expr\FuncCall $count_expr */
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($count_expr->getArgs()[0]->value, $this_class_name, $source);
            if ($source instanceof StatementsAnalyzer) {
                $var_type = $source->node_data->getType($conditional->left);
                $other_type = $source->node_data->getType($conditional->right);
                if ($codebase && $other_type && $var_type && $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
                    self::handleParadoxicalAssertions($source, $var_type, $this_class_name, $other_type, $codebase, $conditional);
                }
            }
            if ($var_name) {
                if ($count > 0) {
                    $if_types[$var_name] = [[new HasExactCount($count)]];
                } else {
                    $if_types[$var_name] = [[new NotNonEmptyCountable()]];
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if (!$source instanceof StatementsAnalyzer) {
            return [];
        }
        $getclass_position = self::hasGetClassCheck($conditional, $source);
        if ($getclass_position) {
            return self::getGetclassEqualityAssertions($conditional, $this_class_name, $source, $getclass_position);
        }
        $typed_value_position = self::hasTypedValueComparison($conditional, $source);
        if ($typed_value_position) {
            return self::getTypedValueEqualityAssertions($conditional, $this_class_name, $source, $codebase, $typed_value_position);
        }
        $var_type = $source->node_data->getType($conditional->left);
        $other_type = $source->node_data->getType($conditional->right);
        if ($codebase && $var_type && $other_type && $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
            if (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $var_type, $other_type)) {
                IssueBuffer::maybeAdd(new TypeDoesNotContainType($var_type->getId() . ' cannot be identical to ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId()), $source->getSuppressedIssues());
            } else {
                // both side of the Identical can be asserted to the intersection of both
                $intersection_type = Type::intersectUnionTypes($var_type, $other_type, $codebase);
                if ($intersection_type !== null && $intersection_type->isSingle()) {
                    $if_types = [];
                    $var_name_left = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->left, $this_class_name, $source);
                    $var_assertion_different = $var_type->getId() !== $intersection_type->getId();
                    if ($var_name_left && $var_assertion_different) {
                        $if_types[$var_name_left] = [[new IsIdentical($intersection_type->getSingleAtomic())]];
                    }
                    $var_name_right = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->right, $this_class_name, $source);
                    $other_assertion_different = $other_type->getId() !== $intersection_type->getId();
                    if ($var_name_right && $other_assertion_different) {
                        $if_types[$var_name_right] = [[new IsIdentical($intersection_type->getSingleAtomic())]];
                    }
                    return $if_types ? [$if_types] : [];
                }
            }
        }
        return [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function scrapeInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase = null, bool $cache = \true, bool $inside_conditional = \true) : array
    {
        $null_position = self::hasNullVariable($conditional, $source);
        if ($null_position !== null) {
            return self::getNullInequalityAssertions($conditional, $source, $this_class_name, $codebase, $null_position);
        }
        $false_position = self::hasFalseVariable($conditional);
        if ($false_position) {
            return self::getFalseInequalityAssertions($conditional, $this_class_name, $source, $codebase, $false_position, $cache, $inside_conditional);
        }
        $true_position = self::hasTrueVariable($conditional);
        if ($true_position) {
            return self::getTrueInequalityAssertions($conditional, $this_class_name, $source, $codebase, $true_position, $cache, $inside_conditional);
        }
        $empty_array_position = self::hasEmptyArrayVariable($conditional);
        if ($empty_array_position !== null) {
            return self::getEmptyInequalityAssertions($conditional, $this_class_name, $source, $codebase, $empty_array_position);
        }
        $gettype_position = self::hasGetTypeCheck($conditional);
        if ($gettype_position) {
            return self::getGettypeInequalityAssertions($conditional, $this_class_name, $source, $gettype_position);
        }
        $get_debug_type_position = self::hasGetDebugTypeCheck($conditional);
        if ($get_debug_type_position) {
            return self::getGetdebugTypeInequalityAssertions($conditional, $this_class_name, $source, $get_debug_type_position);
        }
        $count = null;
        $count_inequality_position = self::hasCountEqualityCheck($conditional, $count);
        if ($count_inequality_position) {
            $if_types = [];
            if ($count_inequality_position === self::ASSIGNMENT_TO_RIGHT) {
                $count_expr = $conditional->left;
            } elseif ($count_inequality_position === self::ASSIGNMENT_TO_LEFT) {
                $count_expr = $conditional->right;
            } else {
                throw new UnexpectedValueException('$count_inequality_position value');
            }
            /** @var PhpParser\Node\Expr\FuncCall $count_expr */
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($count_expr->getArgs()[0]->value, $this_class_name, $source);
            if ($source instanceof StatementsAnalyzer) {
                $var_type = $source->node_data->getType($conditional->left);
                $other_type = $source->node_data->getType($conditional->right);
                if ($codebase && $other_type && $var_type && $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                    self::handleParadoxicalAssertions($source, $var_type, $this_class_name, $other_type, $codebase, $conditional);
                }
            }
            if ($var_name) {
                if ($count > 0) {
                    $if_types[$var_name] = [[new DoesNotHaveExactCount($count)]];
                } else {
                    $if_types[$var_name] = [[new NonEmptyCountable(\true)]];
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if (!$source instanceof StatementsAnalyzer) {
            return [];
        }
        $getclass_position = self::hasGetClassCheck($conditional, $source);
        if ($getclass_position) {
            return self::getGetclassInequalityAssertions($conditional, $this_class_name, $source, $getclass_position);
        }
        $typed_value_position = self::hasTypedValueComparison($conditional, $source);
        if ($typed_value_position) {
            return self::getTypedValueInequalityAssertions($conditional, $this_class_name, $source, $codebase, $typed_value_position);
        }
        return [];
    }
    /**
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    public static function processFunctionCall(PhpParser\Node\Expr\FuncCall $expr, ?string $this_class_name, FileSource $source, ?Codebase $codebase = null, bool $negate = \false) : array
    {
        $first_var_name = isset($expr->getArgs()[0]->value) ? \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->getArgs()[0]->value, $this_class_name, $source) : null;
        $if_types = [];
        $first_var_type = isset($expr->getArgs()[0]->value) && $source instanceof StatementsAnalyzer ? $source->node_data->getType($expr->getArgs()[0]->value) : null;
        if ($tmp_if_types = self::handleIsTypeCheck($codebase, $source, $expr, $first_var_name, $first_var_type, $expr, $negate)) {
            $if_types = $tmp_if_types;
        } elseif ($source instanceof StatementsAnalyzer && self::hasIsACheck($expr, $source)) {
            return self::getIsaAssertions($expr, $source, $this_class_name, $first_var_name);
        } elseif (self::hasCallableCheck($expr)) {
            if ($first_var_name) {
                $if_types[$first_var_name] = [[new IsType(new TCallable())]];
            } elseif ($expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\Array_ && isset($expr->getArgs()[0]->value->items[0], $expr->getArgs()[0]->value->items[1]) && $expr->getArgs()[0]->value->items[1]->value instanceof PhpParser\Node\Scalar\String_) {
                $first_var_name_in_array_argument = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->getArgs()[0]->value->items[0]->value, $this_class_name, $source);
                if ($first_var_name_in_array_argument) {
                    $if_types[$first_var_name_in_array_argument] = [[new HasMethod($expr->getArgs()[0]->value->items[1]->value->value)]];
                }
            }
        } elseif ($class_exists_check_type = self::hasClassExistsCheck($expr)) {
            if ($first_var_name) {
                $class_string_type = new TClassString('object', null, $class_exists_check_type === 1);
                $if_types[$first_var_name] = [[new IsType($class_string_type)]];
            }
        } elseif ($class_exists_check_type = self::hasTraitExistsCheck($expr)) {
            if ($first_var_name) {
                if ($class_exists_check_type === 2) {
                    $if_types[$first_var_name] = [[new IsType(new TTraitString())]];
                } else {
                    $if_types[$first_var_name] = [[new IsIdentical(new TTraitString())]];
                }
            }
        } elseif (self::hasEnumExistsCheck($expr)) {
            if ($first_var_name) {
                $class_string = new TClassString('object', null, \false, \false, \true);
                $if_types[$first_var_name] = [[new IsType($class_string)]];
            }
        } elseif (self::hasInterfaceExistsCheck($expr)) {
            if ($first_var_name) {
                $class_string = new TClassString('object', null, \false, \true, \false);
                $if_types[$first_var_name] = [[new IsType($class_string)]];
            }
        } elseif (self::hasFunctionExistsCheck($expr)) {
            if ($first_var_name) {
                $if_types[$first_var_name] = [[new IsType(new TCallableString())]];
            }
        } elseif ($expr->name instanceof PhpParser\Node\Name && strtolower($expr->name->parts[0]) === 'method_exists' && isset($expr->getArgs()[1]) && $expr->getArgs()[1]->value instanceof PhpParser\Node\Scalar\String_) {
            if ($first_var_name) {
                $if_types[$first_var_name] = [[new HasMethod($expr->getArgs()[1]->value->value)]];
            }
        } elseif (self::hasInArrayCheck($expr) && $source instanceof StatementsAnalyzer) {
            return self::getInarrayAssertions($expr, $source, $first_var_name);
        } elseif (self::hasArrayKeyExistsCheck($expr)) {
            return self::getArrayKeyExistsAssertions($expr, $first_var_type, $first_var_name, $source, $this_class_name);
        } elseif (self::hasNonEmptyCountCheck($expr)) {
            if ($first_var_name) {
                $if_types[$first_var_name] = [[new NonEmptyCountable(\true)]];
            }
        } else {
            return self::processCustomAssertion($expr, $this_class_name, $source);
        }
        return $if_types ? [$if_types] : [];
    }
    private static function processIrreconcilableFunctionCall(Union $first_var_type, Union $expected_type, PhpParser\Node\Expr $expr, StatementsAnalyzer $source, Codebase $codebase, bool $negate) : void
    {
        if ($first_var_type->hasMixed()) {
            return;
        }
        if (!UnionTypeComparator::isContainedBy($codebase, $first_var_type, $expected_type)) {
            return;
        }
        if (!$negate) {
            if ($first_var_type->from_docblock) {
                IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType('Docblock type ' . $first_var_type . ' always contains ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type), $source->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new RedundantCondition($first_var_type . ' always contains ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type), $source->getSuppressedIssues());
            }
        } else {
            if ($first_var_type->from_docblock) {
                IssueBuffer::maybeAdd(new DocblockTypeContradiction('Docblock type !' . $first_var_type . ' does not contain ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type), $source->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new TypeDoesNotContainType('!' . $first_var_type . ' does not contain ' . $expected_type, new CodeLocation($source, $expr), $first_var_type . ' ' . $expected_type), $source->getSuppressedIssues());
            }
        }
    }
    /**
     * @param  PhpParser\Node\Expr\FuncCall|PhpParser\Node\Expr\MethodCall|PhpParser\Node\Expr\StaticCall $expr
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    protected static function processCustomAssertion(PhpParser\Node\Expr $expr, ?string $this_class_name, FileSource $source) : array
    {
        if (!$source instanceof StatementsAnalyzer) {
            return [];
        }
        $if_true_assertions = $source->node_data->getIfTrueAssertions($expr);
        $if_false_assertions = $source->node_data->getIfFalseAssertions($expr);
        if ($if_true_assertions === null && $if_false_assertions === null) {
            return [];
        }
        $first_var_name = isset($expr->getArgs()[0]->value) ? \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->getArgs()[0]->value, $this_class_name, $source) : null;
        $anded_types = [];
        if ($if_true_assertions) {
            foreach ($if_true_assertions as $assertion) {
                $if_types = [];
                $newRules = [];
                foreach ($assertion->rule as $rule) {
                    $rule_type = $rule->getAtomicType();
                    if ($rule_type instanceof TClassConstant) {
                        $codebase = $source->getCodebase();
                        $newRules[] = $rule->setAtomicType(TypeExpander::expandAtomic($codebase, $rule_type, null, null, null)[0]);
                    } else {
                        $newRules[] = $rule;
                    }
                }
                $assertion = new Possibilities($assertion->var_id, $newRules);
                if (is_int($assertion->var_id) && isset($expr->getArgs()[$assertion->var_id])) {
                    if ($assertion->var_id === 0) {
                        $var_name = $first_var_name;
                    } else {
                        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->getArgs()[$assertion->var_id]->value, $this_class_name, $source);
                    }
                    if ($var_name) {
                        $if_types[$var_name] = [[$assertion->rule[0]]];
                    }
                } elseif ($assertion->var_id === '$this') {
                    if (!$expr instanceof PhpParser\Node\Expr\MethodCall) {
                        IssueBuffer::maybeAdd(new InvalidDocblock('Assertion of $this can be done only on method of a class', new CodeLocation($source, $expr)));
                        continue;
                    }
                    $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->var, $this_class_name, $source);
                    if ($var_id) {
                        $if_types[$var_id] = [[$assertion->rule[0]]];
                    }
                } elseif (is_string($assertion->var_id)) {
                    $is_function = substr($assertion->var_id, -2) === '()';
                    $exploded_id = explode('->', $assertion->var_id);
                    $var_id = $exploded_id[0] ?? null;
                    $property = $exploded_id[1] ?? null;
                    if (is_numeric($var_id) && null !== $property && !$is_function) {
                        $var_id_int = (int) $var_id;
                        assert($var_id_int >= 0);
                        $args = $expr->getArgs();
                        if (!array_key_exists($var_id_int, $args)) {
                            IssueBuffer::maybeAdd(new InvalidDocblock('Variable ' . $var_id . ' is not an argument so cannot be asserted', new CodeLocation($source, $expr)));
                            continue;
                        }
                        $arg_value = $args[$var_id_int]->value;
                        assert($arg_value instanceof PhpParser\Node\Expr\Variable);
                        $arg_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($arg_value, null, $source);
                        if (null === $arg_var_id) {
                            IssueBuffer::maybeAdd(new InvalidDocblock('Variable being asserted as argument ' . ($var_id + 1) . ' cannot be found
                                    in local scope', new CodeLocation($source, $expr)));
                            continue;
                        }
                        if (count($exploded_id) === 2) {
                            $failedMessage = self::isPropertyImmutableOnArgument($property, $source->getNodeTypeProvider(), $source->getCodebase()->classlike_storage_provider, $arg_value);
                            if (null !== $failedMessage) {
                                IssueBuffer::maybeAdd(new InvalidDocblock($failedMessage, new CodeLocation($source, $expr)));
                                continue;
                            }
                        }
                        $assertion_var_id = str_replace($var_id, $arg_var_id, $assertion->var_id);
                    } elseif (!$expr instanceof PhpParser\Node\Expr\FuncCall) {
                        $assertion_var_id = $assertion->var_id;
                        if (strpos($assertion_var_id, 'self::') === 0) {
                            $assertion_var_id = $this_class_name . '::' . substr($assertion_var_id, 6);
                        }
                    } else {
                        IssueBuffer::maybeAdd(new InvalidDocblock(sprintf('Assertion of variable "%s" cannot be recognized', $assertion->var_id), new CodeLocation($source, $expr)));
                        continue;
                    }
                    $if_types[$assertion_var_id] = [[$assertion->rule[0]]];
                }
                if ($if_types) {
                    $anded_types[] = $if_types;
                }
            }
        }
        if ($if_false_assertions) {
            foreach ($if_false_assertions as $assertion) {
                $if_types = [];
                $newRules = [];
                foreach ($assertion->rule as $rule) {
                    $rule_type = $rule->getAtomicType();
                    if ($rule_type instanceof TClassConstant) {
                        $codebase = $source->getCodebase();
                        $newRules[] = $rule->setAtomicType(TypeExpander::expandAtomic($codebase, $rule_type, null, null, null)[0]);
                    } else {
                        $newRules[] = $rule;
                    }
                }
                $assertion = new Possibilities($assertion->var_id, $newRules);
                if (is_int($assertion->var_id) && isset($expr->getArgs()[$assertion->var_id])) {
                    if ($assertion->var_id === 0) {
                        $var_name = $first_var_name;
                    } else {
                        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->getArgs()[$assertion->var_id]->value, $this_class_name, $source);
                    }
                    if ($var_name) {
                        $if_types[$var_name] = [[$assertion->rule[0]->getNegation()]];
                    }
                } elseif ($assertion->var_id === '$this' && $expr instanceof PhpParser\Node\Expr\MethodCall) {
                    $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->var, $this_class_name, $source);
                    if ($var_id) {
                        $if_types[$var_id] = [[$assertion->rule[0]->getNegation()]];
                    }
                } elseif (is_string($assertion->var_id)) {
                    $is_function = substr($assertion->var_id, -2) === '()';
                    $exploded_id = explode('->', $assertion->var_id);
                    $var_id = $exploded_id[0] ?? null;
                    $property = $exploded_id[1] ?? null;
                    if (is_numeric($var_id) && null !== $property && !$is_function) {
                        $args = $expr->getArgs();
                        $var_id_int = (int) $var_id;
                        if (!array_key_exists($var_id_int, $args)) {
                            IssueBuffer::maybeAdd(new InvalidDocblock('Variable ' . $var_id . ' is not an argument so cannot be asserted', new CodeLocation($source, $expr)));
                            continue;
                        }
                        /** @var PhpParser\Node\Expr\Variable $arg_value */
                        $arg_value = $args[$var_id_int]->value;
                        $arg_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($arg_value, null, $source);
                        if (null === $arg_var_id) {
                            IssueBuffer::maybeAdd(new InvalidDocblock('Variable being asserted as argument ' . ($var_id + 1) . ' cannot be found
                                     in local scope', new CodeLocation($source, $expr)));
                            continue;
                        }
                        if (count($exploded_id) === 2) {
                            $failedMessage = self::isPropertyImmutableOnArgument($property, $source->getNodeTypeProvider(), $source->getCodebase()->classlike_storage_provider, $arg_value);
                            if (null !== $failedMessage) {
                                IssueBuffer::maybeAdd(new InvalidDocblock($failedMessage, new CodeLocation($source, $expr)));
                                continue;
                            }
                        }
                        $rule = $assertion->rule[0]->getNegation();
                        $assertion_var_id = str_replace($var_id, $arg_var_id, $assertion->var_id);
                        $if_types[$assertion_var_id] = [[$rule]];
                    } elseif (!$expr instanceof PhpParser\Node\Expr\FuncCall) {
                        $var_id = $assertion->var_id;
                        if (strpos($var_id, 'self::') === 0) {
                            $var_id = $this_class_name . '::' . substr($var_id, 6);
                        }
                        $if_types[$var_id] = [[$assertion->rule[0]->getNegation()]];
                    } else {
                        IssueBuffer::maybeAdd(new InvalidDocblock(sprintf('Assertion of variable "%s" cannot be recognized', $assertion->var_id), new CodeLocation($source, $expr)));
                    }
                }
                if ($if_types) {
                    $anded_types[] = $if_types;
                }
            }
        }
        return $anded_types;
    }
    /**
     * @return list<Assertion>
     */
    protected static function getInstanceOfAssertions(PhpParser\Node\Expr\Instanceof_ $stmt, ?string $this_class_name, FileSource $source) : array
    {
        if ($stmt->class instanceof PhpParser\Node\Name) {
            if (!in_array(strtolower($stmt->class->parts[0]), ['self', 'static', 'parent'], \true)) {
                $instanceof_class = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $source->getAliases());
                if ($source instanceof StatementsAnalyzer) {
                    $codebase = $source->getCodebase();
                    $instanceof_class = $codebase->classlikes->getUnAliasedName($instanceof_class);
                }
                return [new IsType(TNamedObject::createFromName($instanceof_class))];
            }
            if ($this_class_name && in_array(strtolower($stmt->class->parts[0]), ['self', 'static'], \true)) {
                $is_static = $stmt->class->parts[0] === 'static';
                $named_object = new TNamedObject($this_class_name, $is_static);
                if ($is_static) {
                    return [new IsIdentical($named_object)];
                }
                return [new IsType($named_object)];
            }
        } elseif ($source instanceof StatementsAnalyzer) {
            $stmt_class_type = $source->node_data->getType($stmt->class);
            if ($stmt_class_type) {
                $literal_class_strings = [];
                foreach ($stmt_class_type->getAtomicTypes() as $atomic_type) {
                    if ($atomic_type instanceof TLiteralClassString) {
                        $literal_class_strings[] = new IsType(new TNamedObject($atomic_type->value));
                    } elseif ($atomic_type instanceof TTemplateParamClass) {
                        $literal_class_strings[] = new IsType(new TTemplateParam($atomic_type->param_name, new Union([$atomic_type->as_type ?: new TObject()]), $atomic_type->defining_class));
                    } elseif ($atomic_type instanceof TClassString && $atomic_type->as !== 'object') {
                        $literal_class_strings[] = new IsType($atomic_type->as_type ?: new TNamedObject($atomic_type->as));
                    }
                }
                return $literal_class_strings;
            }
        }
        return [];
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     */
    protected static function hasNullVariable(PhpParser\Node\Expr\BinaryOp $conditional, FileSource $source) : ?int
    {
        if ($conditional->right instanceof PhpParser\Node\Expr\ConstFetch && strtolower($conditional->right->name->parts[0]) === 'null') {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        if ($conditional->left instanceof PhpParser\Node\Expr\ConstFetch && strtolower($conditional->left->name->parts[0]) === 'null') {
            return self::ASSIGNMENT_TO_LEFT;
        }
        if ($source instanceof StatementsAnalyzer && ($right_type = $source->node_data->getType($conditional->right)) && $right_type->isNull()) {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        return null;
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     */
    public static function hasFalseVariable(PhpParser\Node\Expr\BinaryOp $conditional) : ?int
    {
        if ($conditional->right instanceof PhpParser\Node\Expr\ConstFetch && strtolower($conditional->right->name->parts[0]) === 'false') {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        if ($conditional->left instanceof PhpParser\Node\Expr\ConstFetch && strtolower($conditional->left->name->parts[0]) === 'false') {
            return self::ASSIGNMENT_TO_LEFT;
        }
        return null;
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     */
    public static function hasTrueVariable(PhpParser\Node\Expr\BinaryOp $conditional) : ?int
    {
        if ($conditional->right instanceof PhpParser\Node\Expr\ConstFetch && strtolower($conditional->right->name->parts[0]) === 'true') {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        if ($conditional->left instanceof PhpParser\Node\Expr\ConstFetch && strtolower($conditional->left->name->parts[0]) === 'true') {
            return self::ASSIGNMENT_TO_LEFT;
        }
        return null;
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     */
    protected static function hasEmptyArrayVariable(PhpParser\Node\Expr\BinaryOp $conditional) : ?int
    {
        if ($conditional->right instanceof PhpParser\Node\Expr\Array_ && !$conditional->right->items) {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        if ($conditional->left instanceof PhpParser\Node\Expr\Array_ && !$conditional->left->items) {
            return self::ASSIGNMENT_TO_LEFT;
        }
        return null;
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     * @return false|int
     */
    protected static function hasGetTypeCheck(PhpParser\Node\Expr\BinaryOp $conditional)
    {
        if ($conditional->right instanceof PhpParser\Node\Expr\FuncCall && $conditional->right->name instanceof PhpParser\Node\Name && strtolower($conditional->right->name->parts[0]) === 'gettype' && $conditional->right->getArgs() && $conditional->left instanceof PhpParser\Node\Scalar\String_) {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        if ($conditional->left instanceof PhpParser\Node\Expr\FuncCall && $conditional->left->name instanceof PhpParser\Node\Name && strtolower($conditional->left->name->parts[0]) === 'gettype' && $conditional->left->getArgs() && $conditional->right instanceof PhpParser\Node\Scalar\String_) {
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     * @return false|int
     */
    protected static function hasGetDebugTypeCheck(PhpParser\Node\Expr\BinaryOp $conditional)
    {
        if ($conditional->right instanceof PhpParser\Node\Expr\FuncCall && $conditional->right->name instanceof PhpParser\Node\Name && strtolower($conditional->right->name->parts[0]) === 'get_debug_type' && $conditional->right->getArgs() && ($conditional->left instanceof PhpParser\Node\Scalar\String_ || $conditional->left instanceof PhpParser\Node\Expr\ClassConstFetch)) {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        if ($conditional->left instanceof PhpParser\Node\Expr\FuncCall && $conditional->left->name instanceof PhpParser\Node\Name && strtolower($conditional->left->name->parts[0]) === 'get_debug_type' && $conditional->left->getArgs() && ($conditional->right instanceof PhpParser\Node\Scalar\String_ || $conditional->right instanceof PhpParser\Node\Expr\ClassConstFetch)) {
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     * @return false|int
     */
    protected static function hasGetClassCheck(PhpParser\Node\Expr\BinaryOp $conditional, FileSource $source)
    {
        if (!$source instanceof StatementsAnalyzer) {
            return \false;
        }
        $right_get_class = $conditional->right instanceof PhpParser\Node\Expr\FuncCall && $conditional->right->name instanceof PhpParser\Node\Name && strtolower($conditional->right->name->parts[0]) === 'get_class';
        $right_static_class = $conditional->right instanceof PhpParser\Node\Expr\ClassConstFetch && $conditional->right->class instanceof PhpParser\Node\Name && $conditional->right->class->parts === ['static'] && $conditional->right->name instanceof PhpParser\Node\Identifier && strtolower($conditional->right->name->name) === 'class';
        $right_variable_class_const = $conditional->right instanceof PhpParser\Node\Expr\ClassConstFetch && $conditional->right->class instanceof PhpParser\Node\Expr\Variable && $conditional->right->name instanceof PhpParser\Node\Identifier && strtolower($conditional->right->name->name) === 'class';
        $left_class_string = $conditional->left instanceof PhpParser\Node\Expr\ClassConstFetch && $conditional->left->class instanceof PhpParser\Node\Name && $conditional->left->name instanceof PhpParser\Node\Identifier && strtolower($conditional->left->name->name) === 'class';
        $left_type = $source->node_data->getType($conditional->left);
        $left_class_string_t = \false;
        if ($left_type && $left_type->isSingle()) {
            foreach ($left_type->getAtomicTypes() as $type_part) {
                if ($type_part instanceof TClassString) {
                    $left_class_string_t = \true;
                    break;
                }
            }
        }
        if (($right_get_class || $right_static_class || $right_variable_class_const) && ($left_class_string || $left_class_string_t)) {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        $left_get_class = $conditional->left instanceof PhpParser\Node\Expr\FuncCall && $conditional->left->name instanceof PhpParser\Node\Name && strtolower($conditional->left->name->parts[0]) === 'get_class';
        $left_static_class = $conditional->left instanceof PhpParser\Node\Expr\ClassConstFetch && $conditional->left->class instanceof PhpParser\Node\Name && $conditional->left->class->parts === ['static'] && $conditional->left->name instanceof PhpParser\Node\Identifier && strtolower($conditional->left->name->name) === 'class';
        $left_variable_class_const = $conditional->left instanceof PhpParser\Node\Expr\ClassConstFetch && $conditional->left->class instanceof PhpParser\Node\Expr\Variable && $conditional->left->name instanceof PhpParser\Node\Identifier && strtolower($conditional->left->name->name) === 'class';
        $right_class_string = $conditional->right instanceof PhpParser\Node\Expr\ClassConstFetch && $conditional->right->class instanceof PhpParser\Node\Name && $conditional->right->name instanceof PhpParser\Node\Identifier && strtolower($conditional->right->name->name) === 'class';
        $right_type = $source->node_data->getType($conditional->right);
        $right_class_string_t = \false;
        if ($right_type && $right_type->isSingle()) {
            foreach ($right_type->getAtomicTypes() as $type_part) {
                if ($type_part instanceof TClassString) {
                    $right_class_string_t = \true;
                    break;
                }
            }
        }
        if (($left_get_class || $left_static_class || $left_variable_class_const) && ($right_class_string || $right_class_string_t)) {
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    /**
     * @param Greater|GreaterOrEqual|Smaller|SmallerOrEqual $conditional
     * @return false|int
     */
    protected static function hasNonEmptyCountEqualityCheck(PhpParser\Node\Expr\BinaryOp $conditional, ?int &$min_count)
    {
        if ($conditional->left instanceof PhpParser\Node\Expr\FuncCall && $conditional->left->name instanceof PhpParser\Node\Name && strtolower($conditional->left->name->parts[0]) === 'count' && $conditional->left->getArgs() && ($conditional instanceof BinaryOp\Greater || $conditional instanceof BinaryOp\GreaterOrEqual)) {
            $assignment_to = self::ASSIGNMENT_TO_RIGHT;
            $compare_to = $conditional->right;
            $comparison_adjustment = $conditional instanceof BinaryOp\Greater ? 1 : 0;
        } elseif ($conditional->right instanceof PhpParser\Node\Expr\FuncCall && $conditional->right->name instanceof PhpParser\Node\Name && strtolower($conditional->right->name->parts[0]) === 'count' && $conditional->right->getArgs() && ($conditional instanceof BinaryOp\Smaller || $conditional instanceof BinaryOp\SmallerOrEqual)) {
            $assignment_to = self::ASSIGNMENT_TO_LEFT;
            $compare_to = $conditional->left;
            $comparison_adjustment = $conditional instanceof BinaryOp\Smaller ? 1 : 0;
        } else {
            return \false;
        }
        // TODO get node type provider here somehow and check literal ints and int ranges
        if ($compare_to instanceof PhpParser\Node\Scalar\LNumber && $compare_to->value > -1 * $comparison_adjustment) {
            $min_count = $compare_to->value + $comparison_adjustment;
            return $assignment_to;
        }
        return \false;
    }
    /**
     * @param Greater|GreaterOrEqual|Smaller|SmallerOrEqual $conditional
     * @return false|int
     */
    protected static function hasLessThanCountEqualityCheck(PhpParser\Node\Expr\BinaryOp $conditional, ?int &$max_count)
    {
        $left_count = $conditional->left instanceof PhpParser\Node\Expr\FuncCall && $conditional->left->name instanceof PhpParser\Node\Name && strtolower($conditional->left->name->parts[0]) === 'count' && $conditional->left->getArgs();
        $operator_less_than_or_equal = $conditional instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual || $conditional instanceof PhpParser\Node\Expr\BinaryOp\Smaller;
        if ($left_count && $operator_less_than_or_equal && $conditional->right instanceof PhpParser\Node\Scalar\LNumber) {
            $max_count = $conditional->right->value - ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Smaller ? 1 : 0);
            return self::ASSIGNMENT_TO_RIGHT;
        }
        $right_count = $conditional->right instanceof PhpParser\Node\Expr\FuncCall && $conditional->right->name instanceof PhpParser\Node\Name && strtolower($conditional->right->name->parts[0]) === 'count' && $conditional->right->getArgs();
        $operator_greater_than_or_equal = $conditional instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual || $conditional instanceof PhpParser\Node\Expr\BinaryOp\Greater;
        if ($right_count && $operator_greater_than_or_equal && $conditional->left instanceof PhpParser\Node\Scalar\LNumber) {
            $max_count = $conditional->left->value - ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Greater ? 1 : 0);
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    /**
     * @param Equal|Identical|NotEqual|NotIdentical $conditional
     * @return false|int
     */
    protected static function hasCountEqualityCheck(PhpParser\Node\Expr\BinaryOp $conditional, ?int &$count)
    {
        $left_count = $conditional->left instanceof PhpParser\Node\Expr\FuncCall && $conditional->left->name instanceof PhpParser\Node\Name && strtolower($conditional->left->name->parts[0]) === 'count' && $conditional->left->getArgs();
        if ($left_count && $conditional->right instanceof PhpParser\Node\Scalar\LNumber) {
            $count = $conditional->right->value;
            return self::ASSIGNMENT_TO_RIGHT;
        }
        $right_count = $conditional->right instanceof PhpParser\Node\Expr\FuncCall && $conditional->right->name instanceof PhpParser\Node\Name && strtolower($conditional->right->name->parts[0]) === 'count' && $conditional->right->getArgs();
        if ($right_count && $conditional->left instanceof PhpParser\Node\Scalar\LNumber) {
            $count = $conditional->left->value;
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Greater|PhpParser\Node\Expr\BinaryOp\GreaterOrEqual $conditional
     * @return false|int
     */
    protected static function hasSuperiorNumberCheck(FileSource $source, PhpParser\Node\Expr\BinaryOp $conditional, ?int &$literal_value_comparison)
    {
        $right_assignment = \false;
        $value_right = null;
        if ($source instanceof StatementsAnalyzer && ($type = $source->node_data->getType($conditional->right)) && $type->isSingleIntLiteral()) {
            $right_assignment = \true;
            $value_right = $type->getSingleIntLiteral()->value;
        } elseif ($conditional->right instanceof LNumber) {
            $right_assignment = \true;
            $value_right = $conditional->right->value;
        } elseif ($conditional->right instanceof UnaryMinus && $conditional->right->expr instanceof LNumber) {
            $right_assignment = \true;
            $value_right = -$conditional->right->expr->value;
        } elseif ($conditional->right instanceof UnaryPlus && $conditional->right->expr instanceof LNumber) {
            $right_assignment = \true;
            $value_right = $conditional->right->expr->value;
        }
        if ($right_assignment === \true && $value_right !== null) {
            $literal_value_comparison = $value_right;
            return self::ASSIGNMENT_TO_RIGHT;
        }
        $left_assignment = \false;
        $value_left = null;
        if ($source instanceof StatementsAnalyzer && ($type = $source->node_data->getType($conditional->left)) && $type->isSingleIntLiteral()) {
            $left_assignment = \true;
            $value_left = $type->getSingleIntLiteral()->value;
        } elseif ($conditional->left instanceof LNumber) {
            $left_assignment = \true;
            $value_left = $conditional->left->value;
        } elseif ($conditional->left instanceof UnaryMinus && $conditional->left->expr instanceof LNumber) {
            $left_assignment = \true;
            $value_left = -$conditional->left->expr->value;
        } elseif ($conditional->left instanceof UnaryPlus && $conditional->left->expr instanceof LNumber) {
            $left_assignment = \true;
            $value_left = $conditional->left->expr->value;
        }
        if ($left_assignment === \true && $value_left !== null) {
            $literal_value_comparison = $value_left;
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Smaller|PhpParser\Node\Expr\BinaryOp\SmallerOrEqual $conditional
     * @return false|int
     */
    protected static function hasInferiorNumberCheck(FileSource $source, PhpParser\Node\Expr\BinaryOp $conditional, ?int &$literal_value_comparison)
    {
        $right_assignment = \false;
        $value_right = null;
        if ($source instanceof StatementsAnalyzer && ($type = $source->node_data->getType($conditional->right)) && $type->isSingleIntLiteral()) {
            $right_assignment = \true;
            $value_right = $type->getSingleIntLiteral()->value;
        } elseif ($conditional->right instanceof LNumber) {
            $right_assignment = \true;
            $value_right = $conditional->right->value;
        } elseif ($conditional->right instanceof UnaryMinus && $conditional->right->expr instanceof LNumber) {
            $right_assignment = \true;
            $value_right = -$conditional->right->expr->value;
        } elseif ($conditional->right instanceof UnaryPlus && $conditional->right->expr instanceof LNumber) {
            $right_assignment = \true;
            $value_right = $conditional->right->expr->value;
        }
        if ($right_assignment === \true && $value_right !== null) {
            $literal_value_comparison = $value_right;
            return self::ASSIGNMENT_TO_RIGHT;
        }
        $left_assignment = \false;
        $value_left = null;
        if ($source instanceof StatementsAnalyzer && ($type = $source->node_data->getType($conditional->left)) && $type->isSingleIntLiteral()) {
            $left_assignment = \true;
            $value_left = $type->getSingleIntLiteral()->value;
        } elseif ($conditional->left instanceof LNumber) {
            $left_assignment = \true;
            $value_left = $conditional->left->value;
        } elseif ($conditional->left instanceof UnaryMinus && $conditional->left->expr instanceof LNumber) {
            $left_assignment = \true;
            $value_left = -$conditional->left->expr->value;
        } elseif ($conditional->left instanceof UnaryPlus && $conditional->left->expr instanceof LNumber) {
            $left_assignment = \true;
            $value_left = $conditional->left->expr->value;
        }
        if ($left_assignment === \true && $value_left !== null) {
            $literal_value_comparison = $value_left;
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Greater|PhpParser\Node\Expr\BinaryOp\GreaterOrEqual $conditional
     * @return false|int
     */
    protected static function hasReconcilableNonEmptyCountEqualityCheck(PhpParser\Node\Expr\BinaryOp $conditional)
    {
        $left_count = $conditional->left instanceof PhpParser\Node\Expr\FuncCall && $conditional->left->name instanceof PhpParser\Node\Name && strtolower($conditional->left->name->parts[0]) === 'count';
        $right_number = $conditional->right instanceof PhpParser\Node\Scalar\LNumber && $conditional->right->value === ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Greater ? 0 : 1);
        if ($left_count && $right_number) {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        return \false;
    }
    /**
     * @param Identical|Equal|NotIdentical|NotEqual $conditional
     * @return false|int
     */
    protected static function hasTypedValueComparison(PhpParser\Node\Expr\BinaryOp $conditional, FileSource $source)
    {
        if (!$source instanceof StatementsAnalyzer) {
            return \false;
        }
        if (($right_type = $source->node_data->getType($conditional->right)) && (!$conditional->right instanceof PhpParser\Node\Expr\Variable && !$conditional->right instanceof PhpParser\Node\Expr\PropertyFetch && !$conditional->right instanceof PhpParser\Node\Expr\StaticPropertyFetch || $conditional->left instanceof PhpParser\Node\Expr\Variable || $conditional->left instanceof PhpParser\Node\Expr\PropertyFetch || $conditional->left instanceof PhpParser\Node\Expr\StaticPropertyFetch) && count($right_type->getAtomicTypes()) === 1 && !$right_type->hasMixed()) {
            return self::ASSIGNMENT_TO_RIGHT;
        }
        if (($left_type = $source->node_data->getType($conditional->left)) && !$conditional->left instanceof PhpParser\Node\Expr\Variable && !$conditional->left instanceof PhpParser\Node\Expr\PropertyFetch && !$conditional->left instanceof PhpParser\Node\Expr\StaticPropertyFetch && count($left_type->getAtomicTypes()) === 1 && !$left_type->hasMixed()) {
            return self::ASSIGNMENT_TO_LEFT;
        }
        return \false;
    }
    protected static function hasIsACheck(PhpParser\Node\Expr\FuncCall $stmt, StatementsAnalyzer $source) : bool
    {
        if ($stmt->name instanceof PhpParser\Node\Name && (strtolower($stmt->name->parts[0]) === 'is_a' || strtolower($stmt->name->parts[0]) === 'is_subclass_of') && isset($stmt->getArgs()[1])) {
            $second_arg = $stmt->getArgs()[1]->value;
            if ($second_arg instanceof PhpParser\Node\Scalar\String_ || $second_arg instanceof PhpParser\Node\Expr\ClassConstFetch && $second_arg->class instanceof PhpParser\Node\Name && $second_arg->name instanceof PhpParser\Node\Identifier && strtolower($second_arg->name->name) === 'class' || ($second_arg_type = $source->node_data->getType($second_arg)) && $second_arg_type->hasString()) {
                return \true;
            }
        }
        return \false;
    }
    private static function getIsAssertion(string $function_name) : ?Assertion
    {
        switch ($function_name) {
            case 'is_string':
                return new IsType(new Atomic\TString());
            case 'is_int':
            case 'is_integer':
                return new IsType(new Atomic\TInt());
            case 'is_float':
            case 'is_long':
            case 'is_double':
            case 'is_real':
                return new IsType(new Atomic\TFloat());
            case 'is_scalar':
                return new IsType(new Atomic\TScalar());
            case 'is_bool':
                return new IsType(new Atomic\TBool());
            case 'is_resource':
                return new IsType(new Atomic\TResource());
            case 'is_object':
                return new IsType(new Atomic\TObject());
            case 'array_is_list':
                return new IsType(Type::getListAtomic(Type::getMixed()));
            case 'is_array':
                return new IsType(new Atomic\TArray([Type::getArrayKey(), Type::getMixed()]));
            case 'is_numeric':
                return new IsType(new Atomic\TNumeric());
            case 'is_null':
                return new IsType(new Atomic\TNull());
            case 'is_iterable':
                return new IsType(new Atomic\TIterable());
            case 'is_countable':
                return new IsCountable();
            case 'ctype_digit':
                return new IsType(new Atomic\TNumericString());
            case 'ctype_lower':
                return new IsType(new Atomic\TNonEmptyLowercaseString());
        }
        return null;
    }
    /**
     * @return array<string, non-empty-list<non-empty-list<Assertion>>>
     */
    private static function handleIsTypeCheck(?Codebase $codebase, FileSource $source, PhpParser\Node\Expr\FuncCall $stmt, ?string $first_var_name, ?Union $first_var_type, PhpParser\Node\Expr\FuncCall $expr, bool $negate) : array
    {
        $if_types = [];
        if ($stmt->name instanceof PhpParser\Node\Name && ($function_name = strtolower($stmt->name->parts[0])) && ($assertion_type = self::getIsAssertion($function_name)) && $source instanceof StatementsAnalyzer && ($source->getNamespace() === null || $stmt->name instanceof PhpParser\Node\Name\FullyQualified || isset($source->getAliases()->functions[$function_name]) || $codebase && !$codebase->functions->functionExists($source, strtolower($source->getNamespace() . "\\" . $function_name)))) {
            if ($first_var_name) {
                $if_types[$first_var_name] = [[$assertion_type]];
            } elseif ($first_var_type && $codebase && $assertion_type instanceof IsType) {
                self::processIrreconcilableFunctionCall($first_var_type, new Union([$assertion_type->type]), $expr, $source, $codebase, $negate);
            }
        }
        return $if_types;
    }
    protected static function hasCallableCheck(PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        return $stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'is_callable';
    }
    /**
     * @return Reconciler::RECONCILIATION_*
     */
    protected static function hasClassExistsCheck(PhpParser\Node\Expr\FuncCall $stmt) : int
    {
        if ($stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'class_exists') {
            if (!isset($stmt->getArgs()[1])) {
                return 2;
            }
            $second_arg = $stmt->getArgs()[1]->value;
            if ($second_arg instanceof PhpParser\Node\Expr\ConstFetch && strtolower($second_arg->name->parts[0]) === 'true') {
                return 2;
            }
            return 1;
        }
        return 0;
    }
    /**
     * @return  0|1|2
     */
    protected static function hasTraitExistsCheck(PhpParser\Node\Expr\FuncCall $stmt) : int
    {
        if ($stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'trait_exists') {
            if (!isset($stmt->getArgs()[1])) {
                return 2;
            }
            $second_arg = $stmt->getArgs()[1]->value;
            if ($second_arg instanceof PhpParser\Node\Expr\ConstFetch && strtolower($second_arg->name->parts[0]) === 'true') {
                return 2;
            }
            return 1;
        }
        return 0;
    }
    protected static function hasEnumExistsCheck(PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        return $stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'enum_exists';
    }
    protected static function hasInterfaceExistsCheck(PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        return $stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'interface_exists';
    }
    protected static function hasFunctionExistsCheck(PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        return $stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'function_exists';
    }
    protected static function hasInArrayCheck(PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        if ($stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'in_array' && isset($stmt->getArgs()[2])) {
            $second_arg = $stmt->getArgs()[2]->value;
            if ($second_arg instanceof PhpParser\Node\Expr\ConstFetch && strtolower($second_arg->name->parts[0]) === 'true') {
                return \true;
            }
        }
        return \false;
    }
    protected static function hasNonEmptyCountCheck(PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        return $stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'count';
    }
    protected static function hasArrayKeyExistsCheck(PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        return $stmt->name instanceof PhpParser\Node\Name && strtolower($stmt->name->parts[0]) === 'array_key_exists';
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getNullInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, FileSource $source, ?string $this_class_name, ?Codebase $codebase, int $null_position) : array
    {
        $if_types = [];
        if ($null_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($null_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('Bad null variable position');
        }
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
        if ($var_name) {
            if ($base_conditional instanceof PhpParser\Node\Expr\Assign) {
                $var_name = '=' . $var_name;
            }
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                $if_types[$var_name] = [[new IsNotType(new TNull())]];
            } else {
                $if_types[$var_name] = [[new Truthy()]];
            }
        }
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional))) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                $null_type = Type::getNull();
                if (!UnionTypeComparator::isContainedBy($codebase, $var_type, $null_type) && !UnionTypeComparator::isContainedBy($codebase, $null_type, $var_type)) {
                    if ($var_type->from_docblock) {
                        IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType('Docblock-defined type ' . $var_type . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null'), $source->getSuppressedIssues());
                    } else {
                        IssueBuffer::maybeAdd(new RedundantCondition($var_type . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null'), $source->getSuppressedIssues());
                    }
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getFalseInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase, int $false_position, bool $cache, bool $inside_conditional) : array
    {
        $if_types = [];
        if ($false_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($false_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('Bad false variable position');
        }
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
        if ($var_name) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                $if_types[$var_name] = [[new IsNotType(new TFalse())]];
            } else {
                $if_types[$var_name] = [[new Truthy()]];
            }
            $if_types = [$if_types];
        } else {
            $if_types = null;
            if ($source instanceof StatementsAnalyzer && $cache) {
                $if_types = $source->node_data->getAssertions($base_conditional);
            }
            if ($if_types === null) {
                $if_types = self::scrapeAssertions($base_conditional, $this_class_name, $source, $codebase, \false, $cache, $inside_conditional);
                if ($source instanceof StatementsAnalyzer && $cache) {
                    $source->node_data->setAssertions($base_conditional, $if_types);
                }
            }
        }
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional)) && $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
            $config = $source->getCodebase()->config;
            if ($config->strict_binary_operands && $var_type->isSingle() && $var_type->hasBool() && !$var_type->from_docblock && !$conditional instanceof VirtualNotIdentical) {
                IssueBuffer::maybeAdd(new RedundantIdentityWithTrue('The "!== false" part of this comparison is redundant', new CodeLocation($source, $conditional)), $source->getSuppressedIssues());
            }
            $false_type = Type::getFalse();
            if (!UnionTypeComparator::isContainedBy($codebase, $var_type, $false_type) && !UnionTypeComparator::isContainedBy($codebase, $false_type, $var_type)) {
                if ($var_type->from_docblock) {
                    IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType('Docblock-defined type ' . $var_type . ' can never contain false', new CodeLocation($source, $conditional), $var_type->getId() . ' false'), $source->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new RedundantCondition($var_type . ' can never contain false', new CodeLocation($source, $conditional), $var_type->getId() . ' false'), $source->getSuppressedIssues());
                }
            }
        }
        return $if_types;
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getTrueInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase, int $true_position, bool $cache, bool $inside_conditional) : array
    {
        $if_types = [];
        if ($true_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($true_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('Bad null variable position');
        }
        if ($base_conditional instanceof PhpParser\Node\Expr\FuncCall) {
            $notif_types = self::processFunctionCall($base_conditional, $this_class_name, $source, $codebase, \true);
        } else {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
            if ($var_name) {
                if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                    $if_types[$var_name] = [[new IsNotType(new TTrue())]];
                } else {
                    $if_types[$var_name] = [[new Falsy()]];
                }
                $notif_types = [];
            } else {
                $notif_types = null;
                if ($source instanceof StatementsAnalyzer && $cache) {
                    $notif_types = $source->node_data->getAssertions($base_conditional);
                }
                if ($notif_types === null) {
                    $notif_types = self::scrapeAssertions($base_conditional, $this_class_name, $source, $codebase, \false, $cache, $inside_conditional);
                    if ($source instanceof StatementsAnalyzer && $cache) {
                        $source->node_data->setAssertions($base_conditional, $notif_types);
                    }
                }
            }
        }
        if (count($notif_types) === 1) {
            $notif_types = $notif_types[0];
            if (count($notif_types) === 1) {
                $if_types = Algebra::negateTypes($notif_types);
            }
        }
        $if_types = $if_types ? [$if_types] : [];
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional))) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                $true_type = Type::getTrue();
                if (!UnionTypeComparator::isContainedBy($codebase, $var_type, $true_type) && !UnionTypeComparator::isContainedBy($codebase, $true_type, $var_type)) {
                    if ($var_type->from_docblock) {
                        IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType('Docblock-defined type ' . $var_type . ' can never contain true', new CodeLocation($source, $conditional), $var_type->getId() . ' true'), $source->getSuppressedIssues());
                    } else {
                        IssueBuffer::maybeAdd(new RedundantCondition($var_type . ' can never contain ' . $true_type, new CodeLocation($source, $conditional), $var_type->getId() . ' true'), $source->getSuppressedIssues());
                    }
                }
            }
        }
        return $if_types;
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getEmptyInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase, int $empty_array_position) : array
    {
        $if_types = [];
        if ($empty_array_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($empty_array_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('Bad empty array variable position');
        }
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
        if ($var_name) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                $if_types[$var_name] = [[new NonEmptyCountable(\true)]];
            } else {
                $if_types[$var_name] = [[new Truthy()]];
            }
        }
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional))) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                $empty_array_type = Type::getEmptyArray();
                if (!UnionTypeComparator::isContainedBy($codebase, $var_type, $empty_array_type) && !UnionTypeComparator::isContainedBy($codebase, $empty_array_type, $var_type)) {
                    if ($var_type->from_docblock) {
                        IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType('Docblock-defined type ' . $var_type->getId() . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null'), $source->getSuppressedIssues());
                    } else {
                        IssueBuffer::maybeAdd(new RedundantCondition($var_type->getId() . ' can never contain null', new CodeLocation($source, $conditional), $var_type->getId() . ' null'), $source->getSuppressedIssues());
                    }
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getGettypeInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, int $gettype_position) : array
    {
        $if_types = [];
        if ($gettype_position === self::ASSIGNMENT_TO_RIGHT) {
            $whichclass_expr = $conditional->left;
            $gettype_expr = $conditional->right;
        } elseif ($gettype_position === self::ASSIGNMENT_TO_LEFT) {
            $whichclass_expr = $conditional->right;
            $gettype_expr = $conditional->left;
        } else {
            throw new UnexpectedValueException('$gettype_position value');
        }
        /** @var PhpParser\Node\Expr\FuncCall $gettype_expr */
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($gettype_expr->getArgs()[0]->value, $this_class_name, $source);
        if ($whichclass_expr instanceof PhpParser\Node\Scalar\String_) {
            $var_type = $whichclass_expr->value;
        } elseif ($whichclass_expr instanceof PhpParser\Node\Expr\ClassConstFetch && $whichclass_expr->class instanceof PhpParser\Node\Name) {
            $var_type = ClassLikeAnalyzer::getFQCLNFromNameObject($whichclass_expr->class, $source->getAliases());
        } else {
            throw new UnexpectedValueException('Shouldn’t get here');
        }
        if (!isset(ClassLikeAnalyzer::GETTYPE_TYPES[$var_type])) {
            IssueBuffer::maybeAdd(new UnevaluatedCode('gettype cannot return this value', new CodeLocation($source, $whichclass_expr)));
        } else {
            if ($var_name && $var_type) {
                if ($var_type === 'class@anonymous') {
                    $if_types[$var_name] = [[new IsNotIdentical(new TObject())]];
                } elseif ($var_type === 'resource (closed)') {
                    $if_types[$var_name] = [[new IsNotType(new TClosedResource())]];
                } elseif (strpos($var_type, 'resource (') === 0) {
                    $if_types[$var_name] = [[new IsNotIdentical(new TResource())]];
                } else {
                    $if_types[$var_name] = [[new IsNotType(Atomic::create($var_type))]];
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getGetdebugTypeInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, int $get_debug_type_position) : array
    {
        $if_types = [];
        if ($get_debug_type_position === self::ASSIGNMENT_TO_RIGHT) {
            $whichclass_expr = $conditional->left;
            $get_debug_type_expr = $conditional->right;
        } elseif ($get_debug_type_position === self::ASSIGNMENT_TO_LEFT) {
            $whichclass_expr = $conditional->right;
            $get_debug_type_expr = $conditional->left;
        } else {
            throw new UnexpectedValueException('$gettype_position value');
        }
        /** @var PhpParser\Node\Expr\FuncCall $get_debug_type_expr */
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($get_debug_type_expr->getArgs()[0]->value, $this_class_name, $source);
        if ($whichclass_expr instanceof PhpParser\Node\Scalar\String_) {
            $var_type = $whichclass_expr->value;
        } elseif ($whichclass_expr instanceof PhpParser\Node\Expr\ClassConstFetch && $whichclass_expr->class instanceof PhpParser\Node\Name) {
            $var_type = ClassLikeAnalyzer::getFQCLNFromNameObject($whichclass_expr->class, $source->getAliases());
        } else {
            throw new UnexpectedValueException('Shouldn’t get here');
        }
        if ($var_name && $var_type) {
            if ($var_type === 'class@anonymous') {
                $if_types[$var_name] = [[new IsNotIdentical(new TObject())]];
            } elseif ($var_type === 'resource (closed)') {
                $if_types[$var_name] = [[new IsNotType(new TClosedResource())]];
            } elseif (strpos($var_type, 'resource (') === 0) {
                $if_types[$var_name] = [[new IsNotIdentical(new TResource())]];
            } else {
                $if_types[$var_name] = [[new IsNotType(Atomic::create($var_type))]];
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getGetclassInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, StatementsAnalyzer $source, int $getclass_position) : array
    {
        $if_types = [];
        if ($getclass_position === self::ASSIGNMENT_TO_RIGHT) {
            $whichclass_expr = $conditional->left;
            $getclass_expr = $conditional->right;
        } elseif ($getclass_position === self::ASSIGNMENT_TO_LEFT) {
            $whichclass_expr = $conditional->right;
            $getclass_expr = $conditional->left;
        } else {
            throw new UnexpectedValueException('$getclass_position value');
        }
        if ($getclass_expr instanceof PhpParser\Node\Expr\FuncCall) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($getclass_expr->getArgs()[0]->value, $this_class_name, $source);
        } elseif ($getclass_expr instanceof PhpParser\Node\Expr\ClassConstFetch && $getclass_expr->class instanceof PhpParser\Node\Expr) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($getclass_expr->class, $this_class_name, $source);
        } else {
            $var_name = '$this';
        }
        if ($whichclass_expr instanceof PhpParser\Node\Scalar\String_) {
            $var_type = $whichclass_expr->value;
        } elseif ($whichclass_expr instanceof PhpParser\Node\Expr\ClassConstFetch && $whichclass_expr->class instanceof PhpParser\Node\Name) {
            $var_type = ClassLikeAnalyzer::getFQCLNFromNameObject($whichclass_expr->class, $source->getAliases());
            if ($var_type === 'self' || $var_type === 'static') {
                $var_type = $this_class_name;
            } elseif ($var_type === 'parent') {
                $var_type = null;
            }
        } else {
            $type = $source->node_data->getType($whichclass_expr);
            if ($type && $var_name) {
                foreach ($type->getAtomicTypes() as $type_part) {
                    if ($type_part instanceof TTemplateParamClass) {
                        $if_types[$var_name] = [[new IsNotIdentical(new TTemplateParam($type_part->param_name, new Union([$type_part->as_type ?: new TObject()]), $type_part->defining_class))]];
                    }
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if (!$var_type || ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($source, $var_type, new CodeLocation($source, $whichclass_expr), null, null, $source->getSuppressedIssues()) !== \false) {
            if ($var_name && $var_type) {
                $if_types[$var_name] = [[new IsClassNotEqual($var_type)]];
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\NotIdentical|PhpParser\Node\Expr\BinaryOp\NotEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getTypedValueInequalityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, StatementsAnalyzer $source, ?Codebase $codebase, int $typed_value_position) : array
    {
        $if_types = [];
        if ($typed_value_position === self::ASSIGNMENT_TO_RIGHT) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->left, $this_class_name, $source);
            $other_type = $source->node_data->getType($conditional->left);
            $var_type = $source->node_data->getType($conditional->right);
        } elseif ($typed_value_position === self::ASSIGNMENT_TO_LEFT) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->right, $this_class_name, $source);
            $var_type = $source->node_data->getType($conditional->left);
            $other_type = $source->node_data->getType($conditional->right);
        } else {
            throw new UnexpectedValueException('$typed_value_position value');
        }
        if ($var_type) {
            if ($var_name) {
                $not_identical = $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical || $other_type && ($var_type->isInt() && $other_type->isInt() || $var_type->isFloat() && $other_type->isFloat());
                $anded_types = [];
                foreach ($var_type->getAtomicTypes() as $atomic_var_type) {
                    if ($not_identical) {
                        $anded_types[] = [new IsNotIdentical($atomic_var_type)];
                    } else {
                        $anded_types[] = [new IsNotLooselyEqual($atomic_var_type)];
                    }
                }
                $if_types[$var_name] = $anded_types;
            }
            if ($codebase && $other_type && $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
                self::handleParadoxicalAssertions($source, $var_type, $this_class_name, $other_type, $codebase, $conditional);
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getNullEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase, int $null_position) : array
    {
        $if_types = [];
        if ($null_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($null_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('$null_position value');
        }
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
        if ($var_name && $base_conditional instanceof PhpParser\Node\Expr\Assign) {
            $var_name = '=' . $var_name;
        }
        if ($var_name) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
                $if_types[$var_name] = [[new IsType(new TNull())]];
            } else {
                $if_types[$var_name] = [[new Falsy()]];
            }
        }
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional)) && $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
            $null_type = Type::getNull();
            if (!UnionTypeComparator::isContainedBy($codebase, $var_type, $null_type) && !UnionTypeComparator::isContainedBy($codebase, $null_type, $var_type)) {
                if ($var_type->from_docblock) {
                    IssueBuffer::maybeAdd(new DocblockTypeContradiction($var_type . ' does not contain null', new CodeLocation($source, $conditional), $var_type . ' null'), $source->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new TypeDoesNotContainNull($var_type . ' does not contain null', new CodeLocation($source, $conditional), $var_type->getId()), $source->getSuppressedIssues());
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getTrueEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase, int $true_position, bool $cache, bool $inside_conditional) : array
    {
        $if_types = [];
        if ($true_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($true_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('Unrecognised position');
        }
        if ($base_conditional instanceof PhpParser\Node\Expr\FuncCall) {
            $if_types = self::processFunctionCall($base_conditional, $this_class_name, $source, $codebase, \false);
        } else {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
            if ($var_name) {
                if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
                    $if_types[$var_name] = [[new IsType(new TTrue())]];
                } else {
                    $if_types[$var_name] = [[new Truthy()]];
                }
                $if_types = [$if_types];
            } else {
                $base_assertions = null;
                if ($source instanceof StatementsAnalyzer && $cache) {
                    $base_assertions = $source->node_data->getAssertions($base_conditional);
                }
                if ($base_assertions === null) {
                    $base_assertions = self::scrapeAssertions($base_conditional, $this_class_name, $source, $codebase, \false, $cache, $inside_conditional);
                    if ($source instanceof StatementsAnalyzer && $cache) {
                        $source->node_data->setAssertions($base_conditional, $base_assertions);
                    }
                }
                $if_types = $base_assertions;
            }
        }
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional)) && $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
            $config = $source->getCodebase()->config;
            if ($config->strict_binary_operands && $var_type->isSingle() && $var_type->hasBool() && !$var_type->from_docblock && !$conditional instanceof VirtualIdentical) {
                IssueBuffer::maybeAdd(new RedundantIdentityWithTrue('The "=== true" part of this comparison is redundant', new CodeLocation($source, $conditional)), $source->getSuppressedIssues());
            }
            $true_type = Type::getTrue();
            if (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $true_type, $var_type)) {
                if ($var_type->from_docblock) {
                    IssueBuffer::maybeAdd(new DocblockTypeContradiction($var_type . ' does not contain true', new CodeLocation($source, $conditional), $var_type . ' true'), $source->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new TypeDoesNotContainType($var_type . ' does not contain true', new CodeLocation($source, $conditional), $var_type . ' true'), $source->getSuppressedIssues());
                }
            }
        }
        return $if_types;
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getFalseEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase, int $false_position, bool $cache, bool $inside_conditional) : array
    {
        $if_types = [];
        if ($false_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($false_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('$false_position value');
        }
        if ($base_conditional instanceof PhpParser\Node\Expr\FuncCall) {
            $notif_types = self::processFunctionCall($base_conditional, $this_class_name, $source, $codebase, \true);
        } else {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
            if ($var_name) {
                if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
                    $if_types[$var_name] = [[new IsType(new TFalse())]];
                } else {
                    $if_types[$var_name] = [[new Falsy()]];
                }
                $notif_types = [];
            } else {
                $notif_types = null;
                if ($source instanceof StatementsAnalyzer && $cache) {
                    $notif_types = $source->node_data->getAssertions($base_conditional);
                }
                if ($notif_types === null) {
                    $notif_types = self::scrapeAssertions($base_conditional, $this_class_name, $source, $codebase, \false, $cache, $inside_conditional);
                    if ($source instanceof StatementsAnalyzer && $cache) {
                        $source->node_data->setAssertions($base_conditional, $notif_types);
                    }
                }
            }
        }
        if (count($notif_types) === 1) {
            $notif_types = $notif_types[0];
            if (count($notif_types) === 1) {
                $if_types = Algebra::negateTypes($notif_types);
            }
        }
        $if_types = $if_types ? [$if_types] : [];
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional))) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
                $false_type = Type::getFalse();
                if (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $false_type, $var_type)) {
                    if ($var_type->from_docblock) {
                        IssueBuffer::maybeAdd(new DocblockTypeContradiction($var_type . ' does not contain false', new CodeLocation($source, $conditional), $var_type . ' false'), $source->getSuppressedIssues());
                    } else {
                        IssueBuffer::maybeAdd(new TypeDoesNotContainType($var_type . ' does not contain false', new CodeLocation($source, $conditional), $var_type . ' false'), $source->getSuppressedIssues());
                    }
                }
            }
        }
        return $if_types;
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getEmptyArrayEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase, int $empty_array_position) : array
    {
        $if_types = [];
        if ($empty_array_position === self::ASSIGNMENT_TO_RIGHT) {
            $base_conditional = $conditional->left;
        } elseif ($empty_array_position === self::ASSIGNMENT_TO_LEFT) {
            $base_conditional = $conditional->right;
        } else {
            throw new UnexpectedValueException('$empty_array_position value');
        }
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($base_conditional, $this_class_name, $source);
        if ($var_name) {
            if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
                $if_types[$var_name] = [[new NotNonEmptyCountable()]];
            } else {
                $if_types[$var_name] = [[new Falsy()]];
            }
        }
        if ($codebase && $source instanceof StatementsAnalyzer && ($var_type = $source->node_data->getType($base_conditional)) && $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
            $empty_array_type = Type::getEmptyArray();
            if (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $empty_array_type, $var_type)) {
                if ($var_type->from_docblock) {
                    IssueBuffer::maybeAdd(new DocblockTypeContradiction($var_type . ' does not contain an empty array', new CodeLocation($source, $conditional), $var_type . ' !== []'), $source->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new TypeDoesNotContainType($var_type . ' does not contain empty array', new CodeLocation($source, $conditional), $var_type . ' !== []'), $source->getSuppressedIssues());
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getGettypeEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, int $gettype_position) : array
    {
        $if_types = [];
        if ($gettype_position === self::ASSIGNMENT_TO_RIGHT) {
            $string_expr = $conditional->left;
            $gettype_expr = $conditional->right;
        } elseif ($gettype_position === self::ASSIGNMENT_TO_LEFT) {
            $string_expr = $conditional->right;
            $gettype_expr = $conditional->left;
        } else {
            throw new UnexpectedValueException('$gettype_position value');
        }
        /** @var PhpParser\Node\Expr\FuncCall $gettype_expr */
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($gettype_expr->getArgs()[0]->value, $this_class_name, $source);
        /** @var PhpParser\Node\Scalar\String_ $string_expr */
        $var_type = $string_expr->value;
        if (!isset(ClassLikeAnalyzer::GETTYPE_TYPES[$var_type])) {
            IssueBuffer::maybeAdd(new UnevaluatedCode('gettype cannot return this value', new CodeLocation($source, $string_expr)));
        } else {
            if ($var_name && $var_type) {
                if ($var_type === 'class@anonymous') {
                    $if_types[$var_name] = [[new IsIdentical(new TObject())]];
                } elseif ($var_type === 'resource (closed)') {
                    $if_types[$var_name] = [[new IsType(new TClosedResource())]];
                } elseif (strpos($var_type, 'resource (') === 0) {
                    $if_types[$var_name] = [[new IsIdentical(new TResource())]];
                } elseif ($var_type === 'integer') {
                    $if_types[$var_name] = [[new IsType(new Atomic\TInt())]];
                } elseif ($var_type === 'double') {
                    $if_types[$var_name] = [[new IsType(new Atomic\TFloat())]];
                } elseif ($var_type === 'boolean') {
                    $if_types[$var_name] = [[new IsType(new Atomic\TBool())]];
                } else {
                    $if_types[$var_name] = [[new IsType(Atomic::create($var_type))]];
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getGetdebugtypeEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, FileSource $source, int $get_debug_type_position) : array
    {
        $if_types = [];
        if ($get_debug_type_position === self::ASSIGNMENT_TO_RIGHT) {
            $whichclass_expr = $conditional->left;
            $get_debug_type_expr = $conditional->right;
        } elseif ($get_debug_type_position === self::ASSIGNMENT_TO_LEFT) {
            $whichclass_expr = $conditional->right;
            $get_debug_type_expr = $conditional->left;
        } else {
            throw new UnexpectedValueException('$gettype_position value');
        }
        /** @var PhpParser\Node\Expr\FuncCall $get_debug_type_expr */
        $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($get_debug_type_expr->getArgs()[0]->value, $this_class_name, $source);
        if ($whichclass_expr instanceof PhpParser\Node\Scalar\String_) {
            $var_type = $whichclass_expr->value;
        } elseif ($whichclass_expr instanceof PhpParser\Node\Expr\ClassConstFetch && $whichclass_expr->class instanceof PhpParser\Node\Name) {
            $var_type = ClassLikeAnalyzer::getFQCLNFromNameObject($whichclass_expr->class, $source->getAliases());
        } else {
            throw new UnexpectedValueException('Shouldn’t get here');
        }
        if ($var_name && $var_type) {
            if ($var_type === 'class@anonymous') {
                $if_types[$var_name] = [[new IsIdentical(new TObject())]];
            } elseif ($var_type === 'resource (closed)') {
                $if_types[$var_name] = [[new IsType(new TClosedResource())]];
            } elseif (strpos($var_type, 'resource (') === 0) {
                $if_types[$var_name] = [[new IsIdentical(new TResource())]];
            } elseif ($var_type === 'integer') {
                $if_types[$var_name] = [[new IsType(new Atomic\TInt())]];
            } elseif ($var_type === 'double') {
                $if_types[$var_name] = [[new IsType(new Atomic\TFloat())]];
            } elseif ($var_type === 'boolean') {
                $if_types[$var_name] = [[new IsType(new Atomic\TBool())]];
            } else {
                $if_types[$var_name] = [[new IsType(Atomic::create($var_type))]];
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getGetclassEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, StatementsAnalyzer $source, int $getclass_position) : array
    {
        $if_types = [];
        if ($getclass_position === self::ASSIGNMENT_TO_RIGHT) {
            $whichclass_expr = $conditional->left;
            $getclass_expr = $conditional->right;
        } elseif ($getclass_position === self::ASSIGNMENT_TO_LEFT) {
            $whichclass_expr = $conditional->right;
            $getclass_expr = $conditional->left;
        } else {
            throw new UnexpectedValueException('$getclass_position value');
        }
        if ($getclass_expr instanceof PhpParser\Node\Expr\FuncCall && isset($getclass_expr->getArgs()[0])) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($getclass_expr->getArgs()[0]->value, $this_class_name, $source);
        } elseif ($getclass_expr instanceof PhpParser\Node\Expr\ClassConstFetch && $getclass_expr->class instanceof PhpParser\Node\Expr) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($getclass_expr->class, $this_class_name, $source);
        } else {
            $var_name = '$this';
        }
        if ($whichclass_expr instanceof PhpParser\Node\Expr\ClassConstFetch && $whichclass_expr->class instanceof PhpParser\Node\Name) {
            $var_type = ClassLikeAnalyzer::getFQCLNFromNameObject($whichclass_expr->class, $source->getAliases());
            if ($var_type === 'self' || $var_type === 'static') {
                $var_type = $this_class_name;
            } elseif ($var_type === 'parent') {
                $var_type = null;
            }
            if ($var_type) {
                if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($source, $var_type, new CodeLocation($source, $whichclass_expr), null, null, $source->getSuppressedIssues(), new ClassLikeNameOptions(\true)) === \false) {
                    return [];
                }
            }
            if ($var_name && $var_type) {
                $if_types[$var_name] = [[new IsClassEqual($var_type)]];
            }
        } else {
            $type = $source->node_data->getType($whichclass_expr);
            if ($type && $var_name) {
                foreach ($type->getAtomicTypes() as $type_part) {
                    if ($type_part instanceof TTemplateParamClass) {
                        $if_types[$var_name] = [[new IsIdentical(new TTemplateParam($type_part->param_name, $type_part->as_type ? new Union([$type_part->as_type]) : Type::getObject(), $type_part->defining_class))]];
                    }
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Identical|PhpParser\Node\Expr\BinaryOp\Equal $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getTypedValueEqualityAssertions(PhpParser\Node\Expr\BinaryOp $conditional, ?string $this_class_name, StatementsAnalyzer $source, ?Codebase $codebase, int $typed_value_position) : array
    {
        $if_types = [];
        if ($typed_value_position === self::ASSIGNMENT_TO_RIGHT) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->left, $this_class_name, $source);
            $other_var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->right, $this_class_name, $source);
            $other_type = $source->node_data->getType($conditional->left);
            $var_type = $source->node_data->getType($conditional->right);
        } elseif ($typed_value_position === self::ASSIGNMENT_TO_LEFT) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->right, $this_class_name, $source);
            $other_var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->left, $this_class_name, $source);
            $var_type = $source->node_data->getType($conditional->left);
            $other_type = $source->node_data->getType($conditional->right);
        } else {
            throw new UnexpectedValueException('$typed_value_position value');
        }
        if ($var_name && $var_type) {
            $identical = $conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical || $other_type && ($var_type->isString(\true) && $other_type->isString(\true) || $var_type->isInt(\true) && $other_type->isInt(\true) || $var_type->isFloat() && $other_type->isFloat());
            if (count($var_type->getAtomicTypes()) === 1) {
                $orred_types = [];
                foreach ($var_type->getAtomicTypes() as $atomic_var_type) {
                    if ($identical) {
                        $orred_types[] = new IsIdentical($atomic_var_type);
                    } else {
                        $orred_types[] = new IsLooselyEqual($atomic_var_type);
                    }
                }
                $if_types[$var_name] = [$orred_types];
            }
            if ($other_var_name && $other_type && !$other_type->isMixed() && count($other_type->getAtomicTypes()) === 1) {
                $orred_types = [];
                foreach ($other_type->getAtomicTypes() as $atomic_other_type) {
                    if ($identical) {
                        $orred_types[] = new IsIdentical($atomic_other_type);
                    } else {
                        $orred_types[] = new IsLooselyEqual($atomic_other_type);
                    }
                }
                $if_types[$other_var_name] = [$orred_types];
            }
        }
        if ($codebase && $other_type && $var_type && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical || $other_type->isString() && $var_type->isString())) {
            self::handleParadoxicalAssertions($source, $var_type, $this_class_name, $other_type, $codebase, $conditional);
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getIsaAssertions(PhpParser\Node\Expr\FuncCall $expr, StatementsAnalyzer $source, ?string $this_class_name, ?string $first_var_name) : array
    {
        $if_types = [];
        if ($expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\ClassConstFetch && $expr->getArgs()[0]->value->name instanceof PhpParser\Node\Identifier && strtolower($expr->getArgs()[0]->value->name->name) === 'class' && $expr->getArgs()[0]->value->class instanceof PhpParser\Node\Name && count($expr->getArgs()[0]->value->class->parts) === 1 && strtolower($expr->getArgs()[0]->value->class->parts[0]) === 'static') {
            $first_var_name = '$this';
        }
        if ($first_var_name) {
            $first_arg = $expr->getArgs()[0]->value;
            $second_arg = $expr->getArgs()[1]->value;
            $third_arg = $expr->getArgs()[2]->value ?? null;
            if ($third_arg instanceof PhpParser\Node\Expr\ConstFetch) {
                if (!in_array(strtolower($third_arg->name->parts[0]), ['true', 'false'])) {
                    return [];
                }
                $third_arg_value = strtolower($third_arg->name->parts[0]);
            } else {
                $third_arg_value = $expr->name instanceof PhpParser\Node\Name && strtolower($expr->name->parts[0]) === 'is_subclass_of' ? 'true' : 'false';
            }
            if (($first_arg_type = $source->node_data->getType($first_arg)) && $first_arg_type->isSingleStringLiteral() && $source->getSource()->getSource() instanceof TraitAnalyzer && $first_arg_type->getSingleStringLiteral()->value === $this_class_name) {
                // do nothing
            } else {
                if ($second_arg instanceof PhpParser\Node\Scalar\String_) {
                    $fq_class_name = $second_arg->value;
                    if ($fq_class_name[0] === '\\') {
                        $fq_class_name = substr($fq_class_name, 1);
                    }
                    $obj = new TNamedObject($fq_class_name);
                    $if_types[$first_var_name] = [[new IsAClass($obj, $third_arg_value === 'true')]];
                } elseif ($second_arg instanceof PhpParser\Node\Expr\ClassConstFetch && $second_arg->class instanceof PhpParser\Node\Name && $second_arg->name instanceof PhpParser\Node\Identifier && strtolower($second_arg->name->name) === 'class') {
                    $class_node = $second_arg->class;
                    if ($class_node->parts === ['static']) {
                        if ($this_class_name) {
                            $object = new TNamedObject($this_class_name, \true);
                            $if_types[$first_var_name] = [[new IsAClass($object, $third_arg_value === 'true')]];
                        }
                    } elseif ($class_node->parts === ['self']) {
                        if ($this_class_name) {
                            $object = new TNamedObject($this_class_name);
                            $if_types[$first_var_name] = [[new IsAClass($object, $third_arg_value === 'true')]];
                        }
                    } elseif ($class_node->parts === ['parent']) {
                        // do nothing
                    } else {
                        $object = new TNamedObject(ClassLikeAnalyzer::getFQCLNFromNameObject($class_node, $source->getAliases()));
                        $if_types[$first_var_name] = [[new IsAClass($object, $third_arg_value === 'true')]];
                    }
                } elseif (($second_arg_type = $source->node_data->getType($second_arg)) && $second_arg_type->hasString()) {
                    $vals = [];
                    foreach ($second_arg_type->getAtomicTypes() as $second_arg_atomic_type) {
                        if ($second_arg_atomic_type instanceof TTemplateParamClass) {
                            $vals[] = [new IsAClass($second_arg_atomic_type, $third_arg_value === 'true')];
                        }
                    }
                    if ($vals) {
                        $if_types[$first_var_name] = $vals;
                    }
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getInarrayAssertions(PhpParser\Node\Expr\FuncCall $expr, StatementsAnalyzer $source, ?string $first_var_name) : array
    {
        $if_types = [];
        if ($first_var_name && ($second_arg_type = $source->node_data->getType($expr->getArgs()[1]->value)) && isset($expr->getArgs()[0]->value) && !$expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\ClassConstFetch) {
            foreach ($second_arg_type->getAtomicTypes() as $atomic_type) {
                if ($atomic_type instanceof TList) {
                    $atomic_type = $atomic_type->getKeyedArray();
                }
                if ($atomic_type instanceof TArray || $atomic_type instanceof TKeyedArray) {
                    $is_sealed = \false;
                    if ($atomic_type instanceof TKeyedArray) {
                        $value_type = $atomic_type->getGenericValueType();
                        $is_sealed = $atomic_type->fallback_params === null;
                    } else {
                        $value_type = $atomic_type->type_params[1];
                    }
                    $assertions = [];
                    if (!$is_sealed) {
                        // `in-array-*` has special handling in the detection of paradoxical
                        // conditions and the fact the negation doesn't imply anything.
                        //
                        // In the vast majority of cases, the negation of `in-array-*`
                        // (`Algebra::negateType`) doesn't imply anything because:
                        // - The array can be empty, or
                        // - The array may have one of the types but not the others.
                        //
                        // NOTE: the negation of the negation is the original assertion.
                        if ($value_type->getId() !== '' && !$value_type->isMixed() && !$value_type->hasTemplate()) {
                            $assertions[] = new InArray($value_type);
                        }
                    } else {
                        foreach ($value_type->getAtomicTypes() as $atomic_value_type) {
                            if ($atomic_value_type instanceof TLiteralInt || $atomic_value_type instanceof TLiteralString || $atomic_value_type instanceof TLiteralFloat || $atomic_value_type instanceof TEnumCase) {
                                $assertions[] = new IsIdentical($atomic_value_type);
                            } elseif ($atomic_value_type instanceof TFalse || $atomic_value_type instanceof TTrue || $atomic_value_type instanceof TNull) {
                                $assertions[] = new IsType($atomic_value_type);
                            } elseif (!$atomic_value_type instanceof TMixed) {
                                // mixed doesn't tell us anything and can be omitted.
                                //
                                // For the meaning of in-array, see the above comment.
                                $assertions[] = new InArray($value_type);
                            }
                        }
                    }
                    if ($assertions !== []) {
                        $if_types[$first_var_name] = [$assertions];
                    }
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getArrayKeyExistsAssertions(PhpParser\Node\Expr\FuncCall $expr, ?Union $first_var_type, ?string $first_var_name, FileSource $source, ?string $this_class_name) : array
    {
        $if_types = [];
        $literal_assertions = [];
        $safe_to_track_literals = \true;
        if (isset($expr->getArgs()[0]) && isset($expr->getArgs()[1]) && $first_var_type && $first_var_name && !$expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\ClassConstFetch && $source instanceof StatementsAnalyzer && ($second_var_type = $source->node_data->getType($expr->getArgs()[1]->value))) {
            foreach ($second_var_type->getAtomicTypes() as $atomic_type) {
                if ($atomic_type instanceof TList) {
                    $atomic_type = $atomic_type->getKeyedArray();
                }
                if ($atomic_type instanceof TArray || $atomic_type instanceof TKeyedArray) {
                    if ($atomic_type instanceof TKeyedArray) {
                        $key_type = $atomic_type->getGenericKeyType(!$atomic_type->allShapeKeysAlwaysDefined());
                    } else {
                        $key_type = $atomic_type->type_params[0];
                    }
                    if ($key_type->allStringLiterals() && !$key_type->possibly_undefined) {
                        foreach ($key_type->getLiteralStrings() as $array_literal_type) {
                            $literal_assertions[] = new IsIdentical($array_literal_type);
                        }
                    } elseif ($key_type->allIntLiterals() && !$key_type->possibly_undefined) {
                        foreach ($key_type->getLiteralInts() as $array_literal_type) {
                            $literal_assertions[] = new IsLooselyEqual($array_literal_type);
                        }
                    } else {
                        $safe_to_track_literals = \false;
                    }
                }
            }
        }
        if ($literal_assertions && $first_var_name && $safe_to_track_literals) {
            $if_types[$first_var_name] = [$literal_assertions];
        } else {
            $array_root = isset($expr->getArgs()[1]->value) ? \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($expr->getArgs()[1]->value, $this_class_name, $source) : null;
            if ($array_root && isset($expr->getArgs()[0])) {
                if ($first_var_name === null) {
                    $first_arg = $expr->getArgs()[0];
                    if ($first_arg->value instanceof PhpParser\Node\Scalar\String_) {
                        $first_var_name = '\'' . $first_arg->value->value . '\'';
                    } elseif ($first_arg->value instanceof PhpParser\Node\Scalar\LNumber) {
                        $first_var_name = (string) $first_arg->value->value;
                    }
                }
                if ($expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\ClassConstFetch && $expr->getArgs()[0]->value->name instanceof PhpParser\Node\Identifier && $expr->getArgs()[0]->value->name->name !== 'class') {
                    $const_type = null;
                    if ($source instanceof StatementsAnalyzer) {
                        $const_type = $source->node_data->getType($expr->getArgs()[0]->value);
                    }
                    if ($const_type) {
                        if ($const_type->isSingleStringLiteral()) {
                            $first_var_name = '\'' . $const_type->getSingleStringLiteral()->value . '\'';
                        } elseif ($const_type->isSingleIntLiteral()) {
                            $first_var_name = (string) $const_type->getSingleIntLiteral()->value;
                        } else {
                            $first_var_name = null;
                        }
                    } else {
                        $first_var_name = null;
                    }
                } elseif (($expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\Variable || $expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\PropertyFetch || $expr->getArgs()[0]->value instanceof PhpParser\Node\Expr\StaticPropertyFetch) && $source instanceof StatementsAnalyzer && ($first_var_type = $source->node_data->getType($expr->getArgs()[0]->value))) {
                    foreach ($first_var_type->getLiteralStrings() as $array_literal_type) {
                        $if_types[$array_root . "['" . $array_literal_type->value . "']"] = [[new ArrayKeyExists()]];
                    }
                    foreach ($first_var_type->getLiteralInts() as $array_literal_type) {
                        $if_types[$array_root . "[" . $array_literal_type->value . "]"] = [[new ArrayKeyExists()]];
                    }
                }
                if ($first_var_name !== null && !strpos($first_var_name, '->') && !strpos($first_var_name, '[')) {
                    $if_types[$array_root . '[' . $first_var_name . ']'] = [[new ArrayKeyExists()]];
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Greater|PhpParser\Node\Expr\BinaryOp\GreaterOrEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getGreaterAssertions(PhpParser\Node\Expr $conditional, FileSource $source, ?string $this_class_name) : array
    {
        $if_types = [];
        $min_count = null;
        $count_equality_position = self::hasNonEmptyCountEqualityCheck($conditional, $min_count);
        $max_count = null;
        $count_inequality_position = self::hasLessThanCountEqualityCheck($conditional, $max_count);
        $superior_value_comparison = null;
        $superior_value_position = self::hasSuperiorNumberCheck($source, $conditional, $superior_value_comparison);
        if ($count_equality_position) {
            if ($count_equality_position === self::ASSIGNMENT_TO_RIGHT) {
                $counted_expr = $conditional->left;
            } else {
                throw new UnexpectedValueException('$count_equality_position value');
            }
            /** @var PhpParser\Node\Expr\FuncCall $counted_expr */
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($counted_expr->getArgs()[0]->value, $this_class_name, $source);
            if ($var_name) {
                if (self::hasReconcilableNonEmptyCountEqualityCheck($conditional)) {
                    $if_types[$var_name] = [[new NonEmptyCountable(\true)]];
                } else {
                    if ($min_count > 0) {
                        $if_types[$var_name] = [[new HasAtLeastCount($min_count)]];
                    } else {
                        $if_types[$var_name] = [[new NonEmptyCountable(\false)]];
                    }
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if ($count_inequality_position) {
            if ($count_inequality_position === self::ASSIGNMENT_TO_LEFT) {
                $count_expr = $conditional->right;
            } else {
                throw new UnexpectedValueException('$count_inequality_position value');
            }
            /** @var PhpParser\Node\Expr\FuncCall $count_expr */
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($count_expr->getArgs()[0]->value, $this_class_name, $source);
            if ($var_name) {
                if ($max_count > 0) {
                    $if_types[$var_name] = [[new DoesNotHaveAtLeastCount($max_count + 1)]];
                } else {
                    $if_types[$var_name] = [[new NotNonEmptyCountable()]];
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if ($superior_value_position && $superior_value_comparison !== null) {
            if ($superior_value_position === self::ASSIGNMENT_TO_RIGHT) {
                $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->left, $this_class_name, $source);
            } else {
                $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->right, $this_class_name, $source);
            }
            if ($var_name !== null) {
                if ($superior_value_position === self::ASSIGNMENT_TO_RIGHT) {
                    if ($conditional instanceof GreaterOrEqual) {
                        $if_types[$var_name] = [[new IsGreaterThanOrEqualTo($superior_value_comparison)]];
                    } else {
                        $if_types[$var_name] = [[new IsGreaterThan($superior_value_comparison)]];
                    }
                } else {
                    if ($conditional instanceof GreaterOrEqual) {
                        $if_types[$var_name] = [[new IsLessThanOrEqualTo($superior_value_comparison)]];
                    } else {
                        $if_types[$var_name] = [[new IsLessThan($superior_value_comparison)]];
                    }
                }
            }
            return $if_types ? [$if_types] : [];
        }
        return [];
    }
    /**
     * @param PhpParser\Node\Expr\BinaryOp\Smaller|PhpParser\Node\Expr\BinaryOp\SmallerOrEqual $conditional
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getSmallerAssertions(PhpParser\Node\Expr $conditional, FileSource $source, ?string $this_class_name) : array
    {
        $if_types = [];
        $min_count = null;
        $count_equality_position = self::hasNonEmptyCountEqualityCheck($conditional, $min_count);
        $max_count = null;
        $count_inequality_position = self::hasLessThanCountEqualityCheck($conditional, $max_count);
        $inferior_value_comparison = null;
        $inferior_value_position = self::hasInferiorNumberCheck($source, $conditional, $inferior_value_comparison);
        if ($count_equality_position) {
            if ($count_equality_position === self::ASSIGNMENT_TO_LEFT) {
                $count_expr = $conditional->right;
            } else {
                throw new UnexpectedValueException('$count_equality_position value');
            }
            /** @var PhpParser\Node\Expr\FuncCall $count_expr */
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($count_expr->getArgs()[0]->value, $this_class_name, $source);
            if ($var_name) {
                if ($min_count > 0) {
                    $if_types[$var_name] = [[new HasAtLeastCount($min_count)]];
                } else {
                    $if_types[$var_name] = [[new NonEmptyCountable(\false)]];
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if ($count_inequality_position) {
            if ($count_inequality_position === self::ASSIGNMENT_TO_RIGHT) {
                $count_expr = $conditional->left;
            } else {
                throw new UnexpectedValueException('$count_inequality_position value');
            }
            /** @var PhpParser\Node\Expr\FuncCall $count_expr */
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($count_expr->getArgs()[0]->value, $this_class_name, $source);
            if ($var_name) {
                if ($max_count > 0) {
                    $if_types[$var_name] = [[new DoesNotHaveAtLeastCount($max_count + 1)]];
                } else {
                    $if_types[$var_name] = [[new NotNonEmptyCountable()]];
                }
            }
            return $if_types ? [$if_types] : [];
        }
        if ($inferior_value_position) {
            if ($inferior_value_position === self::ASSIGNMENT_TO_RIGHT) {
                $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->left, $this_class_name, $source);
            } else {
                $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->right, $this_class_name, $source);
            }
            if ($var_name !== null && $inferior_value_comparison !== null) {
                if ($inferior_value_position === self::ASSIGNMENT_TO_RIGHT) {
                    if ($conditional instanceof SmallerOrEqual) {
                        $if_types[$var_name] = [[new IsLessThanOrEqualTo($inferior_value_comparison)]];
                    } else {
                        $if_types[$var_name] = [[new IsLessThan($inferior_value_comparison)]];
                    }
                } else {
                    if ($conditional instanceof SmallerOrEqual) {
                        $if_types[$var_name] = [[new IsGreaterThanOrEqualTo($inferior_value_comparison)]];
                    } else {
                        $if_types[$var_name] = [[new IsGreaterThan($inferior_value_comparison)]];
                    }
                }
            }
            return $if_types ? [$if_types] : [];
        }
        return [];
    }
    /**
     * @return list<non-empty-array<string, non-empty-list<non-empty-list<Assertion>>>>
     */
    private static function getAndCheckInstanceofAssertions(PhpParser\Node\Expr\Instanceof_ $conditional, ?Codebase $codebase, FileSource $source, ?string $this_class_name, bool $inside_negation) : array
    {
        $if_types = [];
        $instanceof_assertions = self::getInstanceOfAssertions($conditional, $this_class_name, $source);
        if ($instanceof_assertions) {
            $var_name = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($conditional->expr, $this_class_name, $source);
            if ($var_name) {
                $if_types[$var_name] = [$instanceof_assertions];
                $var_type = $source instanceof StatementsAnalyzer ? $source->node_data->getType($conditional->expr) : null;
                foreach ($instanceof_assertions as $instanceof_assertion) {
                    $instanceof_type = $instanceof_assertion->getAtomicType();
                    if (!$instanceof_type instanceof TNamedObject) {
                        continue;
                    }
                    if ($codebase && $var_type && $inside_negation && $source instanceof StatementsAnalyzer) {
                        if ($codebase->interfaceExists($instanceof_type->value)) {
                            continue;
                        }
                        $instanceof_type = new Union([$instanceof_type]);
                        if (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $instanceof_type, $var_type)) {
                            if ($var_type->from_docblock) {
                                IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType($var_type->getId() . ' does not contain ' . $instanceof_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $instanceof_type->getId()), $source->getSuppressedIssues());
                            } else {
                                IssueBuffer::maybeAdd(new RedundantCondition($var_type->getId() . ' cannot be identical to ' . $instanceof_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $instanceof_type->getId()), $source->getSuppressedIssues());
                            }
                        }
                    }
                }
            }
        }
        return $if_types ? [$if_types] : [];
    }
    /**
     * @param NotIdentical|NotEqual|Identical|Equal $conditional
     */
    private static function handleParadoxicalAssertions(StatementsAnalyzer $source, Union $var_type, ?string $this_class_name, Union $other_type, Codebase $codebase, PhpParser\Node\Expr\BinaryOp $conditional) : void
    {
        $parent_source = $source->getSource();
        if ($parent_source->getSource() instanceof TraitAnalyzer && ($var_type->isSingleStringLiteral() && $var_type->getSingleStringLiteral()->value === $this_class_name || $other_type->isSingleStringLiteral() && $other_type->getSingleStringLiteral()->value === $this_class_name)) {
            // do nothing
        } elseif (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $other_type, $var_type)) {
            if ($var_type->from_docblock || $other_type->from_docblock) {
                IssueBuffer::maybeAdd(new DocblockTypeContradiction($var_type->getId() . ' does not contain ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId()), $source->getSuppressedIssues());
            } else {
                if ($conditional instanceof NotEqual || $conditional instanceof NotIdentical) {
                    IssueBuffer::maybeAdd(new RedundantCondition($var_type->getId() . ' can never contain ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId()), $source->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new TypeDoesNotContainType($var_type->getId() . ' cannot be identical to ' . $other_type->getId(), new CodeLocation($source, $conditional), $var_type->getId() . ' ' . $other_type->getId()), $source->getSuppressedIssues());
                }
            }
        }
    }
    public static function isPropertyImmutableOnArgument(string $property, NodeDataProvider $node_provider, ClassLikeStorageProvider $class_provider, PhpParser\Node\Expr\Variable $arg_expr) : ?string
    {
        $type = $node_provider->getType($arg_expr);
        /** @var string $name */
        $name = $arg_expr->name;
        if (null === $type) {
            return 'Cannot resolve a type of variable ' . $name;
        }
        foreach ($type->getAtomicTypes() as $type) {
            if (!$type instanceof TNamedObject) {
                return 'Variable ' . $name . ' is not an object so the assertion cannot be applied';
            }
            $class_definition = $class_provider->get($type->value);
            $property_definition = $class_definition->properties[$property] ?? null;
            if (!$property_definition instanceof PropertyStorage) {
                $magic_type = $class_definition->pseudo_property_get_types['$' . $property] ?? null;
                if ($magic_type === null) {
                    return sprintf('Property %s is not defined on variable %s so the assertion cannot be applied', $property, $name);
                }
                $magic_getter = $class_definition->methods['__get'] ?? null;
                if ($magic_getter === null || !$magic_getter->mutation_free) {
                    return "{$class_definition->name}::__get is not mutation-free, so the assertion cannot be applied";
                }
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PostDec;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PostInc;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PreDec;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PreInc;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\ArithmeticOpAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Node\Expr\BinaryOp\VirtualMinus;
use Psalm\Node\Expr\BinaryOp\VirtualPlus;
use Psalm\Node\Expr\VirtualAssign;
use Psalm\Node\Scalar\VirtualLNumber;
use Psalm\Type;
/**
 * @internal
 */
class IncDecExpressionAnalyzer
{
    /**
     * @param PostInc|PostDec|PreInc|PreDec $stmt
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Context $context) : bool
    {
        $was_inside_assignment = $context->inside_assignment;
        $context->inside_assignment = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context) === \false) {
            $context->inside_assignment = $was_inside_assignment;
            return \false;
        }
        $context->inside_assignment = $was_inside_assignment;
        $stmt_var_type = $statements_analyzer->node_data->getType($stmt->var);
        if ($stmt instanceof PostInc || $stmt instanceof PostDec) {
            $statements_analyzer->node_data->setType($stmt, $stmt_var_type ?? Type::getMixed());
        }
        if (($stmt_var_type = $statements_analyzer->node_data->getType($stmt->var)) && $stmt_var_type->hasString() && ($stmt instanceof PostInc || $stmt instanceof PreInc)) {
            $return_type = null;
            $fake_right_expr = new VirtualLNumber(1, $stmt->getAttributes());
            $statements_analyzer->node_data->setType($fake_right_expr, Type::getInt());
            ArithmeticOpAnalyzer::analyze($statements_analyzer, $statements_analyzer->node_data, $stmt->var, $fake_right_expr, $stmt, $return_type, $context);
            $result_type = $return_type ?? Type::getMixed();
            $statements_analyzer->node_data->setType($stmt, $result_type);
            \Psalm\Internal\Analyzer\Statements\Expression\BinaryOpAnalyzer::addDataFlow($statements_analyzer, $stmt, $stmt->var, $fake_right_expr, 'inc');
            $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($stmt->var, null);
            $codebase = $statements_analyzer->getCodebase();
            if ($var_id && isset($context->vars_in_scope[$var_id])) {
                $context->vars_in_scope[$var_id] = $result_type;
                if ($codebase->find_unused_variables && $stmt->var instanceof PhpParser\Node\Expr\Variable) {
                    $context->assigned_var_ids[$var_id] = (int) $stmt->var->getAttribute('startFilePos');
                    $context->possibly_assigned_var_ids[$var_id] = \true;
                }
                // removes dependent vars from $context
                $context->removeDescendents($var_id, $context->vars_in_scope[$var_id], $return_type, $statements_analyzer);
            }
        } else {
            $fake_right_expr = new VirtualLNumber(1, $stmt->getAttributes());
            $operation = $stmt instanceof PostInc || $stmt instanceof PreInc ? new VirtualPlus($stmt->var, $fake_right_expr, $stmt->var->getAttributes()) : new VirtualMinus($stmt->var, $fake_right_expr, $stmt->var->getAttributes());
            $fake_assignment = new VirtualAssign($stmt->var, $operation, $stmt->getAttributes());
            $old_node_data = $statements_analyzer->node_data;
            $statements_analyzer->node_data = clone $statements_analyzer->node_data;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $fake_assignment, $context) === \false) {
                return \false;
            }
            if ($stmt instanceof PreInc || $stmt instanceof PreDec) {
                $old_node_data->setType($stmt, $statements_analyzer->node_data->getType($fake_assignment) ?? Type::getMixed());
            }
            $statements_analyzer->node_data = $old_node_data;
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Assignment;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PropertyFetch;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\PropertyProperty;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ClassAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\Methods;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DeprecatedProperty;
use Psalm\Issue\ImplicitToStringCast;
use Psalm\Issue\ImpurePropertyAssignment;
use Psalm\Issue\InaccessibleProperty;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InternalProperty;
use Psalm\Issue\InvalidPropertyAssignment;
use Psalm\Issue\InvalidPropertyAssignmentValue;
use Psalm\Issue\LoopInvalidation;
use Psalm\Issue\MixedAssignment;
use Psalm\Issue\MixedPropertyAssignment;
use Psalm\Issue\MixedPropertyTypeCoercion;
use Psalm\Issue\NoInterfaceProperties;
use Psalm\Issue\NullPropertyAssignment;
use Psalm\Issue\PossiblyFalsePropertyAssignmentValue;
use Psalm\Issue\PossiblyInvalidPropertyAssignment;
use Psalm\Issue\PossiblyInvalidPropertyAssignmentValue;
use Psalm\Issue\PossiblyNullPropertyAssignment;
use Psalm\Issue\PossiblyNullPropertyAssignmentValue;
use Psalm\Issue\PropertyTypeCoercion;
use Psalm\Issue\UndefinedClass;
use Psalm\Issue\UndefinedMagicPropertyAssignment;
use Psalm\Issue\UndefinedPropertyAssignment;
use Psalm\Issue\UndefinedThisPropertyAssignment;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\Scalar\VirtualString;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualIdentifier;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\PropertyStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_merge;
use function array_pop;
use function count;
use function in_array;
use function reset;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class InstancePropertyAssignmentAnalyzer
{
    /**
     * @param   PropertyFetch|PropertyProperty  $stmt
     * @param   bool                            $direct_assignment whether the variable is assigned explicitly
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\NodeAbstract $stmt, string $prop_name, ?PhpParser\Node\Expr $assignment_value, Union $assignment_value_type, Context $context, bool $direct_assignment = \true) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        if ($stmt instanceof PropertyProperty) {
            if (!$context->self || !$stmt->default) {
                return;
            }
            $property_id = $context->self . '::$' . $prop_name;
            $class_property_type = null;
            try {
                $class_property_type = $codebase->properties->getPropertyType($property_id, \true, $statements_analyzer, $context);
            } catch (UnexpectedValueException $e) {
                // do nothing
            }
            if ($class_property_type) {
                $class_storage = $codebase->classlike_storage_provider->get($context->self);
                $class_property_type = self::getExpandedPropertyType($codebase, $context->self, $prop_name, $class_storage);
            }
            $var_id = '$this->' . $prop_name;
            $assigned_properties = [new \Psalm\Internal\Analyzer\Statements\Expression\Assignment\AssignedProperty($class_property_type ?? Type::getMixed(), $property_id, $assignment_value_type)];
        } else {
            $assigned_properties = self::analyzeRegularAssignment($statements_analyzer, $stmt, $assignment_value, $context, $direct_assignment, $codebase, $assignment_value_type, $prop_name, $var_id);
        }
        if (!$assigned_properties) {
            return;
        }
        if ($assignment_value_type->hasMixed()) {
            return;
        }
        $invalid_assignment_value_types = [];
        $has_valid_assignment_value_type = \false;
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations && count($assigned_properties) === 1) {
            $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $assigned_properties[0]->property_type->getId());
        }
        foreach ($assigned_properties as $assigned_property) {
            $class_property_type = $assigned_property->property_type;
            $assignment_type = $assigned_property->assignment_type;
            if ($class_property_type->hasMixed()) {
                continue;
            }
            $union_comparison_results = new TypeComparisonResult();
            $type_match_found = UnionTypeComparator::isContainedBy($codebase, $assignment_type, $class_property_type, \true, \true, $union_comparison_results);
            if ($type_match_found && $union_comparison_results->replacement_union_type) {
                if ($var_id) {
                    $context->vars_in_scope[$var_id] = $union_comparison_results->replacement_union_type;
                }
            }
            if ($union_comparison_results->type_coerced) {
                if ($union_comparison_results->type_coerced_from_mixed) {
                    IssueBuffer::maybeAdd(new MixedPropertyTypeCoercion($var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type `' . $assignment_type->getId() . '` provided', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $assigned_property->id), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new PropertyTypeCoercion($var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type \'' . $assignment_type->getId() . '\' provided', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $assigned_property->id), $statements_analyzer->getSuppressedIssues());
                }
            }
            if ($union_comparison_results->to_string_cast) {
                IssueBuffer::maybeAdd(new ImplicitToStringCast($var_id . ' expects \'' . $class_property_type . '\', ' . '\'' . $assignment_type . '\' provided with a __toString method', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location)), $statements_analyzer->getSuppressedIssues());
            }
            if (!$type_match_found && !$union_comparison_results->type_coerced) {
                if (UnionTypeComparator::canBeContainedBy($codebase, $assignment_type, $class_property_type, \true, \true)) {
                    $has_valid_assignment_value_type = \true;
                }
                $invalid_assignment_value_types[$assigned_property->id] = $class_property_type->getId();
            } else {
                $has_valid_assignment_value_type = \true;
            }
            if ($type_match_found) {
                if (!$assignment_type->ignore_nullable_issues && $assignment_type->isNullable() && !$class_property_type->isNullable()) {
                    if (IssueBuffer::accepts(new PossiblyNullPropertyAssignmentValue($var_id . ' with non-nullable declared type \'' . $class_property_type . '\' cannot be assigned nullable type \'' . $assignment_type . '\'', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $assigned_property->id), $statements_analyzer->getSuppressedIssues())) {
                        return;
                    }
                }
                if (!$assignment_type->ignore_falsable_issues && $assignment_type->isFalsable() && !$class_property_type->hasBool() && !$class_property_type->hasScalar()) {
                    if (IssueBuffer::accepts(new PossiblyFalsePropertyAssignmentValue($var_id . ' with non-falsable declared type \'' . $class_property_type . '\' cannot be assigned possibly false type \'' . $assignment_type . '\'', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $assigned_property->id), $statements_analyzer->getSuppressedIssues())) {
                        return;
                    }
                }
            }
        }
        foreach ($invalid_assignment_value_types as $property_id => $invalid_class_property_type) {
            if (!$has_valid_assignment_value_type) {
                if (IssueBuffer::accepts(new InvalidPropertyAssignmentValue($var_id . ' with declared type \'' . $invalid_class_property_type . '\' cannot be assigned type \'' . $assignment_value_type->getId() . '\'', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $property_id), $statements_analyzer->getSuppressedIssues())) {
                    return;
                }
            } else {
                if (IssueBuffer::accepts(new PossiblyInvalidPropertyAssignmentValue($var_id . ' with declared type \'' . $invalid_class_property_type . '\' cannot be assigned possibly different type \'' . $assignment_value_type->getId() . '\'', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $property_id), $statements_analyzer->getSuppressedIssues())) {
                    return;
                }
            }
        }
    }
    public static function trackPropertyImpurity(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, string $property_id, PropertyStorage $property_storage, ClassLikeStorage $declaring_class_storage, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $stmt_var_type = $statements_analyzer->node_data->getType($stmt->var);
        $property_var_pure_compatible = $stmt_var_type && $stmt_var_type->reference_free && $stmt_var_type->allow_mutations;
        $appearing_property_class = $codebase->properties->getAppearingClassForProperty($property_id, \true);
        $project_analyzer = $statements_analyzer->getProjectAnalyzer();
        if ($appearing_property_class && ($property_storage->readonly || $codebase->alter_code)) {
            $can_set_readonly_property = $context->self && $context->calling_method_id && ($appearing_property_class === $context->self || $codebase->classExtends($context->self, $appearing_property_class)) && (strpos($context->calling_method_id, '::__construct') || strpos($context->calling_method_id, '::unserialize') || strpos($context->calling_method_id, '::__unserialize') || strpos($context->calling_method_id, '::__clone') || $property_storage->allow_private_mutation || $property_var_pure_compatible);
            if (!$can_set_readonly_property) {
                if ($property_storage->readonly) {
                    IssueBuffer::maybeAdd(new InaccessibleProperty($property_id . ' is marked readonly', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } elseif (!$declaring_class_storage->mutation_free && isset($project_analyzer->getIssuesToFix()['MissingImmutableAnnotation']) && $statements_analyzer->getSource() instanceof FunctionLikeAnalyzer) {
                    $codebase->analyzer->addMutableClass($declaring_class_storage->name);
                }
            }
        }
    }
    public static function analyzeStatement(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Property $stmt, Context $context) : void
    {
        foreach ($stmt->props as $prop) {
            if ($prop->default) {
                if ($stmt->isReadonly()) {
                    IssueBuffer::maybeAdd(new InvalidPropertyAssignment('Readonly property ' . $context->self . '::$' . $prop->name->name . ' cannot have a default', new CodeLocation($statements_analyzer->getSource(), $prop->default)));
                }
                ExpressionAnalyzer::analyze($statements_analyzer, $prop->default, $context);
                if ($prop_default_type = $statements_analyzer->node_data->getType($prop->default)) {
                    self::analyze($statements_analyzer, $prop, $prop->name->name, $prop->default, $prop_default_type, $context);
                }
            }
        }
    }
    private static function taintProperty(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, string $property_id, ClassLikeStorage $class_storage, Union &$assignment_value_type, Context $context) : void
    {
        if (!$statements_analyzer->data_flow_graph) {
            return;
        }
        $codebase = $statements_analyzer->getCodebase();
        $data_flow_graph = $statements_analyzer->data_flow_graph;
        if ($class_storage->specialize_instance) {
            $var_id = ExpressionIdentifier::getExtendedVarId($stmt->var, null, $statements_analyzer);
            $var_property_id = ExpressionIdentifier::getExtendedVarId($stmt, null, $statements_analyzer);
            if ($var_id) {
                if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                    $context->vars_in_scope[$var_id] = $context->vars_in_scope[$var_id]->setParentNodes([]);
                    return;
                }
                $var_location = new CodeLocation($statements_analyzer->getSource(), $stmt->var);
                $var_node = DataFlowNode::getForAssignment($var_id, $var_location);
                $data_flow_graph->addNode($var_node);
                $property_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                $property_node = DataFlowNode::getForAssignment($var_property_id ?: $var_id . '->$property', $property_location);
                $data_flow_graph->addNode($property_node);
                $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
                $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                $data_flow_graph->addPath($property_node, $var_node, 'property-assignment' . ($stmt->name instanceof PhpParser\Node\Identifier ? '-' . $stmt->name : ''), $added_taints, $removed_taints);
                if ($assignment_value_type->parent_nodes) {
                    foreach ($assignment_value_type->parent_nodes as $parent_node) {
                        $data_flow_graph->addPath($parent_node, $property_node, '=', $added_taints, $removed_taints);
                    }
                }
                if (isset($context->vars_in_scope[$var_id])) {
                    $stmt_var_type = $context->vars_in_scope[$var_id]->setParentNodes([$var_node->id => $var_node]);
                    if ($context->vars_in_scope[$var_id]->parent_nodes) {
                        foreach ($context->vars_in_scope[$var_id]->parent_nodes as $parent_node) {
                            $data_flow_graph->addPath($parent_node, $var_node, '=', $added_taints, $removed_taints);
                        }
                    }
                    $context->vars_in_scope[$var_id] = $stmt_var_type;
                }
            }
        } else {
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                $assignment_value_type = $assignment_value_type->setParentNodes([]);
                return;
            }
            $var_property_id = ExpressionIdentifier::getExtendedVarId($stmt, null, $statements_analyzer);
            self::taintUnspecializedProperty($statements_analyzer, $stmt, $property_id, $class_storage, $assignment_value_type, $context, $var_property_id);
        }
    }
    public static function taintUnspecializedProperty(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, string $property_id, ClassLikeStorage $class_storage, Union $assignment_value_type, Context $context, ?string $var_property_id) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $data_flow_graph = $statements_analyzer->data_flow_graph;
        if (!$data_flow_graph) {
            return;
        }
        $property_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
        $localized_property_node = DataFlowNode::getForAssignment($var_property_id ?: $property_id, $property_location);
        $data_flow_graph->addNode($localized_property_node);
        $property_node = new DataFlowNode($property_id, $property_id, null, null);
        $data_flow_graph->addNode($property_node);
        $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
        $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
        $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
        $data_flow_graph->addPath($localized_property_node, $property_node, 'property-assignment', $added_taints, $removed_taints);
        if ($assignment_value_type->parent_nodes) {
            foreach ($assignment_value_type->parent_nodes as $parent_node) {
                $data_flow_graph->addPath($parent_node, $localized_property_node, '=', $added_taints, $removed_taints);
            }
        }
        $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($property_id, \false, $statements_analyzer);
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $declaring_property_class && $declaring_property_class !== $class_storage->name && ($stmt instanceof PhpParser\Node\Expr\PropertyFetch || $stmt instanceof PhpParser\Node\Expr\StaticPropertyFetch) && $stmt->name instanceof PhpParser\Node\Identifier) {
            $declaring_property_node = new DataFlowNode($declaring_property_class . '::$' . $stmt->name, $declaring_property_class . '::$' . $stmt->name, null, null);
            $data_flow_graph->addNode($declaring_property_node);
            $data_flow_graph->addPath($property_node, $declaring_property_node, 'property-assignment', $added_taints, $removed_taints);
        }
    }
    /**
     * @return list<AssignedProperty>
     */
    private static function analyzeRegularAssignment(StatementsAnalyzer $statements_analyzer, PropertyFetch $stmt, ?PhpParser\Node\Expr $assignment_value, Context $context, bool $direct_assignment, Codebase $codebase, Union $assignment_value_type, string $prop_name, ?string &$var_id) : array
    {
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context);
        $context->inside_general_use = $was_inside_general_use;
        $lhs_type = $statements_analyzer->node_data->getType($stmt->var);
        if ($lhs_type === null) {
            return [];
        }
        $lhs_var_id = ExpressionIdentifier::getVarId($stmt->var, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $var_id = ExpressionIdentifier::getVarId($stmt, $statements_analyzer->getFQCLN(), $statements_analyzer);
        if ($var_id) {
            $context->assigned_var_ids[$var_id] = (int) $stmt->var->getAttribute('startFilePos');
            if ($direct_assignment && isset($context->protected_var_ids[$var_id])) {
                IssueBuffer::maybeAdd(new LoopInvalidation('Variable ' . $var_id . ' has already been assigned in a for/foreach loop', new CodeLocation($statements_analyzer->getSource(), $stmt->var)), $statements_analyzer->getSuppressedIssues());
            }
        }
        if ($lhs_type->hasMixed()) {
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
            }
            if ($stmt->name instanceof PhpParser\Node\Identifier) {
                $codebase->analyzer->addMixedMemberName('$' . $stmt->name->name, $context->calling_method_id ?: $statements_analyzer->getFileName());
            }
            IssueBuffer::maybeAdd(new MixedPropertyAssignment($lhs_var_id . ' of type mixed cannot be assigned to', new CodeLocation($statements_analyzer->getSource(), $stmt->var)), $statements_analyzer->getSuppressedIssues());
            return [];
        }
        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
            $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
        }
        if ($lhs_type->isNull()) {
            IssueBuffer::maybeAdd(new NullPropertyAssignment($lhs_var_id . ' of type null cannot be assigned to', new CodeLocation($statements_analyzer->getSource(), $stmt->var)), $statements_analyzer->getSuppressedIssues());
            return [];
        }
        if ($lhs_type->isNullable() && !$lhs_type->ignore_nullable_issues) {
            IssueBuffer::maybeAdd(new PossiblyNullPropertyAssignment($lhs_var_id . ' with possibly null type \'' . $lhs_type . '\' cannot be assigned to', new CodeLocation($statements_analyzer->getSource(), $stmt->var)), $statements_analyzer->getSuppressedIssues());
        }
        $has_regular_setter = \false;
        $invalid_assignment_types = [];
        $has_valid_assignment_type = \false;
        $lhs_atomic_types = $lhs_type->getAtomicTypes();
        $assigned_properties = [];
        $context_type = null;
        while ($lhs_atomic_types) {
            $lhs_type_part = array_pop($lhs_atomic_types);
            if ($lhs_type_part instanceof TTemplateParam) {
                $lhs_atomic_types = array_merge($lhs_atomic_types, $lhs_type_part->as->getAtomicTypes());
                continue;
            }
            $assigned_property = self::analyzeAtomicAssignment($statements_analyzer, $codebase, $stmt, $assignment_value, $prop_name, $context, $lhs_type, $lhs_type_part, $invalid_assignment_types, $var_id, $assignment_value_type, $lhs_var_id, $has_valid_assignment_type, $has_regular_setter);
            if ($assigned_property) {
                $assigned_properties[] = $assigned_property;
                if ($context_type) {
                    $context_type = Type::combineUnionTypes($context_type, $assigned_property->assignment_type, $codebase);
                } else {
                    $context_type = $assigned_property->assignment_type;
                }
            }
        }
        if ($invalid_assignment_types) {
            $invalid_assignment_type = $invalid_assignment_types[0];
            if (!$has_valid_assignment_type) {
                IssueBuffer::maybeAdd(new InvalidPropertyAssignment($lhs_var_id . ' with non-object type \'' . $invalid_assignment_type . '\' cannot treated as an object', new CodeLocation($statements_analyzer->getSource(), $stmt->var)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new PossiblyInvalidPropertyAssignment($lhs_var_id . ' with possible non-object type \'' . $invalid_assignment_type . '\' cannot treated as an object', new CodeLocation($statements_analyzer->getSource(), $stmt->var)), $statements_analyzer->getSuppressedIssues());
            }
        }
        if (!$has_regular_setter) {
            return [];
        }
        $context_type = $context_type ?: $assignment_value_type;
        if ($var_id) {
            if ($context->collect_initializations && $lhs_var_id === '$this') {
                $context_type = $context_type->setProperties(['initialized_class' => $context->self]);
            }
            // because we don't want to be assigning for property declarations
            $context->vars_in_scope[$var_id] = $context_type;
        }
        return $assigned_properties;
    }
    /**
     * @param list<string> $invalid_assignment_types
     * @psalm-suppress ComplexMethod Unavoidably complex method
     */
    private static function analyzeAtomicAssignment(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PropertyFetch $stmt, ?PhpParser\Node\Expr $assignment_value, string $prop_name, Context $context, Union $lhs_type, Atomic $lhs_type_part, array &$invalid_assignment_types, ?string $var_id, Union $assignment_value_type, ?string $lhs_var_id, bool &$has_valid_assignment_type, bool &$has_regular_setter) : ?\Psalm\Internal\Analyzer\Statements\Expression\Assignment\AssignedProperty
    {
        if ($lhs_type_part instanceof TNull) {
            return null;
        }
        if ($lhs_type_part instanceof TFalse && $lhs_type->ignore_falsable_issues && count($lhs_type->getAtomicTypes()) > 1) {
            return null;
        }
        if (!$lhs_type_part instanceof TObject && !$lhs_type_part instanceof TNamedObject) {
            $invalid_assignment_types[] = (string) $lhs_type_part;
            return null;
        }
        $has_valid_assignment_type = \true;
        // stdClass and SimpleXMLElement are special cases where we cannot infer the return types
        // but we don't want to throw an error
        // Hack has a similar issue: https://github.com/facebook/hhvm/issues/5164
        if ($lhs_type_part instanceof TObject || in_array(strtolower($lhs_type_part->value), Config::getInstance()->getUniversalObjectCrates() + ['dateinterval', 'domdocument', 'domnode'], \true)) {
            if ($var_id) {
                if ($lhs_type_part instanceof TNamedObject && strtolower($lhs_type_part->value) === 'stdclass') {
                    $context->vars_in_scope[$var_id] = $assignment_value_type;
                } else {
                    $context->vars_in_scope[$var_id] = Type::getMixed();
                }
            }
            return null;
        }
        if (ExpressionAnalyzer::isMock($lhs_type_part->value)) {
            if ($var_id) {
                $context->vars_in_scope[$var_id] = Type::getMixed();
            }
            return null;
        }
        $intersection_types = $lhs_type_part->getIntersectionTypes() ?: [];
        $fq_class_name = $lhs_type_part->value;
        $override_property_visibility = \false;
        $class_exists = \false;
        $interface_exists = \false;
        if (!$codebase->classExists($lhs_type_part->value)) {
            if ($codebase->interfaceExists($lhs_type_part->value)) {
                $interface_exists = \true;
                $interface_storage = $codebase->classlike_storage_provider->get(strtolower($lhs_type_part->value));
                $override_property_visibility = $interface_storage->override_property_visibility;
                foreach ($intersection_types as $intersection_type) {
                    if ($intersection_type instanceof TNamedObject && $codebase->classExists($intersection_type->value)) {
                        $fq_class_name = $intersection_type->value;
                        $class_exists = \true;
                        break;
                    }
                }
                if (!$class_exists) {
                    if (IssueBuffer::accepts(new NoInterfaceProperties('Interfaces cannot have properties', new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value), $statements_analyzer->getSuppressedIssues())) {
                        return null;
                    }
                    if (!$codebase->methods->methodExists(new MethodIdentifier($fq_class_name, '__set'))) {
                        return null;
                    }
                }
            }
            if (!$class_exists && !$interface_exists) {
                IssueBuffer::maybeAdd(new UndefinedClass('Cannot set properties of undefined class ' . $lhs_type_part->value, new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value), $statements_analyzer->getSuppressedIssues());
                return null;
            }
        } else {
            $class_exists = \true;
        }
        $property_id = $fq_class_name . '::$' . $prop_name;
        $has_magic_setter = \false;
        $set_method_id = new MethodIdentifier($fq_class_name, '__set');
        if ((!$codebase->properties->propertyExists($property_id, \false, $statements_analyzer, $context) || $lhs_var_id !== '$this' && $fq_class_name !== $context->self && ClassLikeAnalyzer::checkPropertyVisibility($property_id, $context, $statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues(), \false) !== \true) && $codebase->methods->methodExists($set_method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath())) {
            $has_magic_setter = \true;
            $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
            if ($var_id) {
                if (isset($class_storage->pseudo_property_set_types['$' . $prop_name])) {
                    $class_property_type = TypeExpander::expandUnion($codebase, $class_storage->pseudo_property_set_types['$' . $prop_name], $fq_class_name, $fq_class_name, $class_storage->parent_class);
                    $has_regular_setter = \true;
                    if (!$context->collect_initializations && !$context->collect_mutations) {
                        self::taintProperty($statements_analyzer, $stmt, $property_id, $class_storage, $assignment_value_type, $context);
                    }
                    return new \Psalm\Internal\Analyzer\Statements\Expression\Assignment\AssignedProperty($class_property_type, $property_id, $assignment_value_type);
                }
            }
            if ($assignment_value) {
                self::analyzeSetCall($var_id, $context, $statements_analyzer, $stmt, $prop_name, $assignment_value);
            }
            /*
             * If we have an explicit list of all allowed magic properties on the class, and we're
             * not in that list, fall through
             */
            if (!$var_id || !$class_storage->sealed_properties) {
                if (!$context->collect_initializations && !$context->collect_mutations) {
                    self::taintProperty($statements_analyzer, $stmt, $property_id, $class_storage, $assignment_value_type, $context);
                }
                return null;
            }
            if (!$class_exists) {
                IssueBuffer::maybeAdd(new UndefinedMagicPropertyAssignment('Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
        }
        if (!$class_exists) {
            return null;
        }
        $has_regular_setter = \true;
        if ($stmt->var instanceof PhpParser\Node\Expr\Variable && $stmt->var->name === 'this' && $context->self) {
            $self_property_id = $context->self . '::$' . $prop_name;
            if ($self_property_id !== $property_id && $codebase->properties->propertyExists($self_property_id, \false, $statements_analyzer, $context)) {
                $property_id = $self_property_id;
            }
        }
        if ($statements_analyzer->data_flow_graph && !$context->collect_initializations && !$context->collect_mutations) {
            $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
            self::taintProperty($statements_analyzer, $stmt, $property_id, $class_storage, $assignment_value_type, $context);
        }
        if (!$codebase->properties->propertyExists($property_id, \false, $statements_analyzer, $context, new CodeLocation($statements_analyzer->getSource(), $stmt)) || $codebase->properties->hasStorage($property_id) && $codebase->properties->getStorage($property_id)->is_static) {
            if ($stmt->var instanceof PhpParser\Node\Expr\Variable && $stmt->var->name === 'this') {
                // if this is a proper error, we'll see it on the first pass
                if ($context->collect_mutations) {
                    return null;
                }
                IssueBuffer::maybeAdd(new UndefinedThisPropertyAssignment('Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            } else {
                if ($has_magic_setter) {
                    IssueBuffer::maybeAdd(new UndefinedMagicPropertyAssignment('Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new UndefinedPropertyAssignment('Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                }
            }
            return null;
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $property_id);
        }
        if (!$override_property_visibility) {
            if (!$context->collect_mutations) {
                if (ClassLikeAnalyzer::checkPropertyVisibility($property_id, $context, $statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues()) === \false) {
                    return null;
                }
            } else {
                if (ClassLikeAnalyzer::checkPropertyVisibility($property_id, $context, $statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues(), \false) !== \true) {
                    return null;
                }
            }
        }
        $declaring_property_class = (string) $codebase->properties->getDeclaringClassForProperty($property_id, \false);
        self::handlePropertyRenames($codebase, $declaring_property_class, $prop_name, $stmt, $statements_analyzer->getFilePath());
        $declaring_class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
        if (isset($declaring_class_storage->properties[$prop_name])) {
            $property_storage = $declaring_class_storage->properties[$prop_name];
            if ($property_storage->deprecated) {
                IssueBuffer::maybeAdd(new DeprecatedProperty($property_id . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
            if ($context->self && !NamespaceAnalyzer::isWithinAny($context->self, $property_storage->internal)) {
                IssueBuffer::maybeAdd(new InternalProperty($property_id . ' is internal to ' . InternalClass::listToPhrase($property_storage->internal) . ' but called from ' . $context->self, new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
            self::trackPropertyImpurity($statements_analyzer, $stmt, $property_id, $property_storage, $declaring_class_storage, $context);
            if (!$property_storage->readonly && !$context->collect_mutations && !$context->collect_initializations && isset($context->vars_in_scope[$lhs_var_id]) && !$context->vars_in_scope[$lhs_var_id]->allow_mutations) {
                if ($context->mutation_free) {
                    IssueBuffer::maybeAdd(new ImpurePropertyAssignment('Cannot assign to a property from a mutation-free context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                    $statements_analyzer->getSource()->inferred_impure = \true;
                }
            }
            if ($property_storage->getter_method) {
                $getter_id = $lhs_var_id . '->' . $property_storage->getter_method . '()';
                unset($context->vars_in_scope[$getter_id]);
            }
        }
        $class_property_type = $codebase->properties->getPropertyType($property_id, \true, $statements_analyzer, $context);
        if (!$class_property_type || isset($declaring_class_storage->properties[$prop_name]) && !$declaring_class_storage->properties[$prop_name]->type_location) {
            if (!$class_property_type) {
                $class_property_type = Type::getMixed();
            }
            $source_analyzer = $statements_analyzer->getSource()->getSource();
            if ($lhs_var_id === '$this' && $source_analyzer instanceof ClassAnalyzer) {
                $source_analyzer->inferred_property_types[$prop_name] = Type::combineUnionTypes($assignment_value_type, $source_analyzer->inferred_property_types[$prop_name] ?? null);
            }
        }
        if (!$class_property_type->isMixed()) {
            $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
            $class_property_type = TypeExpander::expandUnion($codebase, $class_property_type, $fq_class_name, $lhs_type_part, $declaring_class_storage->parent_class, \true, \false, $class_storage->final);
            $class_property_type = Methods::localizeType($codebase, $class_property_type, $fq_class_name, $declaring_property_class);
            if ($lhs_type_part instanceof TGenericObject) {
                $class_property_type = AtomicPropertyFetchAnalyzer::localizePropertyType($codebase, $class_property_type, $lhs_type_part, $class_storage, $declaring_class_storage);
            }
            $assignment_value_type = Methods::localizeType($codebase, $assignment_value_type, $fq_class_name, $declaring_property_class);
            if (!$class_property_type->hasMixed() && $assignment_value_type->hasMixed()) {
                $origin_locations = [];
                if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                    foreach ($assignment_value_type->parent_nodes as $parent_node) {
                        $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                    }
                }
                $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
                $message = $var_id ? 'Unable to determine the type that ' . $var_id . ' is being assigned to' : 'Unable to determine the type of this assignment';
                if ($origin_location && $origin_location->getLineNumber() === $stmt->getLine()) {
                    $origin_location = null;
                }
                IssueBuffer::maybeAdd(new MixedAssignment($message, new CodeLocation($statements_analyzer->getSource(), $stmt), $origin_location), $statements_analyzer->getSuppressedIssues());
            }
        }
        return new \Psalm\Internal\Analyzer\Statements\Expression\Assignment\AssignedProperty($class_property_type, $property_id, $assignment_value_type);
    }
    private static function handlePropertyRenames(Codebase $codebase, string $declaring_property_class, string $prop_name, PropertyFetch $stmt, string $file_path) : void
    {
        if (!$codebase->properties_to_rename) {
            return;
        }
        $declaring_property_id = strtolower($declaring_property_class) . '::$' . $prop_name;
        foreach ($codebase->properties_to_rename as $original_property_id => $new_property_name) {
            if ($declaring_property_id === $original_property_id) {
                $file_manipulations = [new FileManipulation((int) $stmt->name->getAttribute('startFilePos'), (int) $stmt->name->getAttribute('endFilePos') + 1, $new_property_name)];
                FileManipulationBuffer::add($file_path, $file_manipulations);
            }
        }
    }
    public static function getExpandedPropertyType(Codebase $codebase, string $fq_class_name, string $property_name, ClassLikeStorage $storage) : ?Union
    {
        $property_class_name = $codebase->properties->getDeclaringClassForProperty($fq_class_name . '::$' . $property_name, \true);
        if ($property_class_name === null) {
            return null;
        }
        $property_class_storage = $codebase->classlike_storage_provider->get($property_class_name);
        $property_storage = $property_class_storage->properties[$property_name];
        if (!$property_storage->type) {
            return null;
        }
        $property_type = $property_storage->type;
        $fleshed_out_type = !$property_type->isMixed() ? TypeExpander::expandUnion($codebase, $property_type, $fq_class_name, $fq_class_name, $storage->parent_class, \true, \false, $storage->final) : $property_type;
        $class_template_params = ClassTemplateParamCollector::collect($codebase, $property_class_storage, $storage, null, new TNamedObject($fq_class_name), \true);
        $template_result = new TemplateResult($class_template_params ?: [], []);
        if ($class_template_params) {
            $fleshed_out_type = TemplateStandinTypeReplacer::replace($fleshed_out_type, $template_result, $codebase, null, null, null);
        }
        return $fleshed_out_type;
    }
    private static function analyzeSetCall(?string $var_id, Context $context, StatementsAnalyzer $statements_analyzer, PropertyFetch $stmt, string $prop_name, Expr $assignment_value) : void
    {
        if ($var_id) {
            $context->removeVarFromConflictingClauses($var_id, Type::getMixed(), $statements_analyzer);
            $context->removePossibleReference($var_id);
        }
        $old_data_provider = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        $fake_method_call = new VirtualMethodCall($stmt->var, new VirtualIdentifier('__set', $stmt->name->getAttributes()), [new VirtualArg(new VirtualString($prop_name, $stmt->name->getAttributes())), new VirtualArg($assignment_value)]);
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        if (!in_array('PossiblyNullReference', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['PossiblyNullReference']);
        }
        MethodCallAnalyzer::analyze($statements_analyzer, $fake_method_call, $context, \false);
        if (!in_array('PossiblyNullReference', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['PossiblyNullReference']);
        }
        $statements_analyzer->node_data = $old_data_provider;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Assignment;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Variable;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ArrayFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Issue\InvalidArrayAssignment;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TDependentListKey;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateIndexedAccess;
use Psalm\Type\Atomic\TTemplateKeyOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Union;
use function array_fill;
use function array_pop;
use function array_reverse;
use function array_shift;
use function array_slice;
use function assert;
use function count;
use function end;
use function implode;
use function in_array;
use function is_string;
use function preg_match;
use function strlen;
use function strpos;
/**
 * @internal
 */
class ArrayAssignmentAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ArrayDimFetch $stmt, Context $context, ?PhpParser\Node\Expr $assign_value, Union $assignment_value_type) : void
    {
        $nesting = 0;
        $var_id = ExpressionIdentifier::getVarId($stmt->var, $statements_analyzer->getFQCLN(), $statements_analyzer, $nesting);
        self::updateArrayType($statements_analyzer, $stmt, $assign_value, $assignment_value_type, $context);
        if (!$statements_analyzer->node_data->getType($stmt->var) && $var_id) {
            $context->vars_in_scope[$var_id] = Type::getMixed();
        }
    }
    /**
     * @return false|null
     * @psalm-suppress PossiblyUnusedReturnValue not used but seems important
     */
    public static function updateArrayType(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ArrayDimFetch $stmt, ?PhpParser\Node\Expr $assign_value, Union $assignment_type, Context $context) : ?bool
    {
        $root_array_expr = $stmt;
        $child_stmts = [];
        while ($root_array_expr->var instanceof PhpParser\Node\Expr\ArrayDimFetch) {
            $child_stmts[] = $root_array_expr;
            $root_array_expr = $root_array_expr->var;
        }
        $child_stmts[] = $root_array_expr;
        $root_array_expr = $root_array_expr->var;
        ExpressionAnalyzer::analyze($statements_analyzer, $root_array_expr, $context, \true);
        $codebase = $statements_analyzer->getCodebase();
        $root_type = $statements_analyzer->node_data->getType($root_array_expr) ?? Type::getMixed();
        if ($root_type->hasMixed()) {
            ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context, \true);
            if ($stmt->dim) {
                ExpressionAnalyzer::analyze($statements_analyzer, $stmt->dim, $context);
            }
        }
        $current_type = $root_type;
        $current_dim = $stmt->dim;
        // gets a variable id that *may* contain array keys
        $root_var_id = ExpressionIdentifier::getExtendedVarId($root_array_expr, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $parent_var_id = null;
        $offset_already_existed = \false;
        self::analyzeNestedArrayAssignment($statements_analyzer, $codebase, $context, $assign_value, $assignment_type, $child_stmts, $root_var_id, $parent_var_id, $root_type, $current_type, $current_dim, $offset_already_existed);
        $root_is_string = $root_type->isString();
        $key_values = [];
        if ($current_dim instanceof PhpParser\Node\Scalar\String_) {
            $key_values[] = new TLiteralString($current_dim->value);
        } elseif ($current_dim instanceof PhpParser\Node\Scalar\LNumber && !$root_is_string) {
            $key_values[] = new TLiteralInt($current_dim->value);
        } elseif ($current_dim && ($key_type = $statements_analyzer->node_data->getType($current_dim)) && !$root_is_string) {
            $string_literals = $key_type->getLiteralStrings();
            $int_literals = $key_type->getLiteralInts();
            $all_atomic_types = $key_type->getAtomicTypes();
            if (count($string_literals) + count($int_literals) === count($all_atomic_types)) {
                foreach ($string_literals as $string_literal) {
                    $key_values[] = $string_literal;
                }
                foreach ($int_literals as $int_literal) {
                    $key_values[] = $int_literal;
                }
            }
        }
        if ($key_values) {
            $new_child_type = self::updateTypeWithKeyValues($codebase, $root_type, $current_type, $key_values);
        } elseif (!$root_is_string) {
            $new_child_type = self::updateArrayAssignmentChildType($statements_analyzer, $codebase, $current_dim, $context, $current_type, $root_type, $offset_already_existed, $parent_var_id);
        } else {
            $new_child_type = $root_type;
        }
        $new_child_type = $new_child_type->getBuilder();
        $new_child_type->removeType('null');
        $new_child_type = $new_child_type->freeze();
        if (!$root_type->hasObjectType()) {
            $root_type = $new_child_type;
        }
        $statements_analyzer->node_data->setType($root_array_expr, $root_type);
        if ($root_array_expr instanceof PhpParser\Node\Expr\PropertyFetch) {
            if ($root_array_expr->name instanceof PhpParser\Node\Identifier) {
                \Psalm\Internal\Analyzer\Statements\Expression\Assignment\InstancePropertyAssignmentAnalyzer::analyze($statements_analyzer, $root_array_expr, $root_array_expr->name->name, null, $root_type, $context, \false);
            } else {
                if (ExpressionAnalyzer::analyze($statements_analyzer, $root_array_expr->name, $context) === \false) {
                    return \false;
                }
                if (ExpressionAnalyzer::analyze($statements_analyzer, $root_array_expr->var, $context) === \false) {
                    return \false;
                }
            }
        } elseif ($root_array_expr instanceof PhpParser\Node\Expr\StaticPropertyFetch && $root_array_expr->name instanceof PhpParser\Node\Identifier) {
            if (\Psalm\Internal\Analyzer\Statements\Expression\Assignment\StaticPropertyAssignmentAnalyzer::analyze($statements_analyzer, $root_array_expr, null, $root_type, $context) === \false) {
                return \false;
            }
        } elseif ($root_var_id) {
            $context->vars_in_scope[$root_var_id] = $root_type;
        }
        if ($root_array_expr instanceof PhpParser\Node\Expr\MethodCall || $root_array_expr instanceof PhpParser\Node\Expr\StaticCall || $root_array_expr instanceof PhpParser\Node\Expr\FuncCall) {
            if ($root_type->hasArray()) {
                IssueBuffer::maybeAdd(new InvalidArrayAssignment('Assigning to the output of a function has no effect', new CodeLocation($statements_analyzer->getSource(), $root_array_expr)), $statements_analyzer->getSuppressedIssues());
            }
        }
        return null;
    }
    /**
     * @param non-empty-list<TLiteralInt|TLiteralString> $key_values
     */
    private static function updateTypeWithKeyValues(Codebase $codebase, Union $child_stmt_type, Union $current_type, array $key_values) : Union
    {
        $has_matching_objectlike_property = \false;
        $has_matching_string = \false;
        $changed = \false;
        $types = [];
        foreach ($child_stmt_type->getAtomicTypes() as $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            $old_type = $type;
            if ($type instanceof TTemplateParam) {
                $type = $type->replaceAs(self::updateTypeWithKeyValues($codebase, $type->as, $current_type, $key_values));
                $has_matching_objectlike_property = \true;
            } elseif ($type instanceof TKeyedArray) {
                $properties = $type->properties;
                foreach ($key_values as $key_value) {
                    if (isset($properties[$key_value->value])) {
                        $has_matching_objectlike_property = \true;
                        $properties[$key_value->value] = $current_type;
                    }
                }
                $type = $type->setProperties($properties);
            } elseif ($type instanceof TString) {
                foreach ($key_values as $key_value) {
                    if ($key_value instanceof TLiteralInt) {
                        $has_matching_string = \true;
                        if ($type instanceof TLiteralString && $current_type->isSingleStringLiteral()) {
                            $new_char = $current_type->getSingleStringLiteral()->value;
                            if (strlen($new_char) === 1 && $type->value[0] !== $new_char) {
                                $v = $type->value;
                                $v[0] = $new_char;
                                $changed = \true;
                                $type = new TLiteralString($v);
                                break;
                            }
                        }
                    }
                }
            }
            $types[$type->getKey()] = $type;
            $changed = $changed || $old_type !== $type;
        }
        if ($changed) {
            $child_stmt_type = $child_stmt_type->getBuilder()->setTypes($types)->freeze();
        }
        if (!$has_matching_objectlike_property && !$has_matching_string) {
            if (count($key_values) === 1) {
                $key_value = $key_values[0];
                $object_like = new TKeyedArray([$key_value->value => $current_type], $key_value instanceof TLiteralClassString ? [$key_value->value => \true] : null);
                $array_assignment_type = new Union([$object_like]);
            } else {
                $array_assignment_literals = $key_values;
                $array_assignment_type = new Union([new TNonEmptyArray([new Union($array_assignment_literals), $current_type])]);
            }
            return Type::combineUnionTypes($child_stmt_type, $array_assignment_type, $codebase, \true, \false);
        }
        return $child_stmt_type;
    }
    /**
     * @param list<TLiteralInt|TLiteralString> $key_values $key_values
     */
    private static function taintArrayAssignment(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ArrayDimFetch $expr, Union &$stmt_type, Union $child_stmt_type, ?string $var_var_id, array $key_values) : void
    {
        if ($statements_analyzer->data_flow_graph && ($statements_analyzer->data_flow_graph instanceof VariableUseGraph || !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues()))) {
            $var_location = new CodeLocation($statements_analyzer->getSource(), $expr->var);
            $parent_node = DataFlowNode::getForAssignment($var_var_id ?: 'assignment', $var_location);
            $statements_analyzer->data_flow_graph->addNode($parent_node);
            $old_parent_nodes = $stmt_type->parent_nodes;
            $stmt_type = $stmt_type->setParentNodes([$parent_node->id => $parent_node]);
            foreach ($old_parent_nodes as $old_parent_node) {
                $statements_analyzer->data_flow_graph->addPath($old_parent_node, $parent_node, '=');
                if ($stmt_type->by_ref) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $old_parent_node, '=');
                }
            }
            foreach ($stmt_type->parent_nodes as $parent_node) {
                foreach ($child_stmt_type->parent_nodes as $child_parent_node) {
                    if ($key_values) {
                        foreach ($key_values as $key_value) {
                            $statements_analyzer->data_flow_graph->addPath($child_parent_node, $parent_node, 'arrayvalue-assignment-\'' . $key_value->value . '\'');
                        }
                    } else {
                        $statements_analyzer->data_flow_graph->addPath($child_parent_node, $parent_node, 'arrayvalue-assignment');
                    }
                }
            }
        }
    }
    private static function updateArrayAssignmentChildType(StatementsAnalyzer $statements_analyzer, Codebase $codebase, ?PhpParser\Node\Expr $current_dim, Context $context, Union $value_type, Union $root_type, bool $offset_already_existed, ?string $parent_var_id) : Union
    {
        $templated_assignment = \false;
        $array_atomic_type_class_string = null;
        $array_atomic_type_array = null;
        $array_atomic_type_list = null;
        if ($current_dim) {
            $key_type = $statements_analyzer->node_data->getType($current_dim);
            if ($key_type) {
                if ($key_type->hasMixed()) {
                    $key_type = Type::getArrayKey();
                }
                if ($key_type->isSingle()) {
                    $key_type_type = $key_type->getSingleAtomic();
                    if ($key_type_type instanceof TIntRange && $key_type_type->dependent_list_key === $parent_var_id || $key_type_type instanceof TDependentListKey && $key_type_type->var_id === $parent_var_id) {
                        $offset_already_existed = \true;
                    }
                    if ($key_type_type instanceof TTemplateParam && $key_type_type->as->isSingle() && $root_type->isSingle() && $value_type->isSingle()) {
                        $key_type_as_type = $key_type_type->as->getSingleAtomic();
                        $value_atomic_type = $value_type->getSingleAtomic();
                        $root_atomic_type = $root_type->getSingleAtomic();
                        if ($key_type_as_type instanceof TTemplateKeyOf && $root_atomic_type instanceof TTemplateParam && $value_atomic_type instanceof TTemplateIndexedAccess && $key_type_as_type->param_name === $root_atomic_type->param_name && $key_type_as_type->defining_class === $root_atomic_type->defining_class && $value_atomic_type->array_param_name === $root_atomic_type->param_name && $value_atomic_type->offset_param_name === $key_type_type->param_name && $value_atomic_type->defining_class === $root_atomic_type->defining_class) {
                            $templated_assignment = \true;
                            $offset_already_existed = \true;
                        }
                    }
                }
                $array_atomic_key_type = ArrayFetchAnalyzer::replaceOffsetTypeWithInts($key_type);
            } else {
                $array_atomic_key_type = Type::getArrayKey();
            }
            if ($offset_already_existed && $parent_var_id && ($parent_type = $context->vars_in_scope[$parent_var_id] ?? null)) {
                if ($parent_type->hasList() && strpos($parent_var_id, '[') === \false) {
                    $array_atomic_type_list = $value_type;
                } elseif ($parent_type->hasClassStringMap() && $key_type && $key_type->isTemplatedClassString()) {
                    /**
                     * @var TClassStringMap
                     */
                    $class_string_map = $parent_type->getArray();
                    /**
                     * @var TTemplateParamClass
                     */
                    $offset_type_part = $key_type->getSingleAtomic();
                    $template_result = new TemplateResult([], [$offset_type_part->param_name => [$offset_type_part->defining_class => new Union([new TTemplateParam($class_string_map->param_name, $offset_type_part->as_type ? new Union([$offset_type_part->as_type]) : Type::getObject(), 'class-string-map')])]]);
                    $value_type = TemplateInferredTypeReplacer::replace($value_type, $template_result, $codebase);
                    $array_atomic_type_class_string = new TClassStringMap($class_string_map->param_name, $class_string_map->as_type, $value_type);
                } else {
                    $array_atomic_type_array = [$array_atomic_key_type, $value_type];
                }
            } else {
                $array_atomic_type_array = [$array_atomic_key_type, $value_type];
            }
        } else {
            $array_atomic_type_list = $value_type;
        }
        $from_countable_object_like = \false;
        $new_child_type = null;
        $array_atomic_type = null;
        if (!$current_dim && !$context->inside_loop) {
            $atomic_root_types = $root_type->getAtomicTypes();
            if (isset($atomic_root_types['array'])) {
                $atomic_root_type_array = $atomic_root_types['array'];
                if ($atomic_root_type_array instanceof TList) {
                    $atomic_root_type_array = $atomic_root_type_array->getKeyedArray();
                }
                if ($array_atomic_type_class_string) {
                    $array_atomic_type = new TNonEmptyArray([$array_atomic_type_class_string->getStandinKeyParam(), $array_atomic_type_class_string->value_param]);
                } elseif ($atomic_root_type_array instanceof TKeyedArray && $atomic_root_type_array->is_list && $atomic_root_type_array->fallback_params === null) {
                    $array_atomic_type = $atomic_root_type_array;
                } elseif ($atomic_root_type_array instanceof TNonEmptyArray || $atomic_root_type_array instanceof TKeyedArray && $atomic_root_type_array->is_list && $atomic_root_type_array->isNonEmpty()) {
                    $prop_count = null;
                    if ($atomic_root_type_array instanceof TNonEmptyArray) {
                        $prop_count = $atomic_root_type_array->count;
                    } else {
                        $min_count = $atomic_root_type_array->getMinCount();
                        if ($min_count === $atomic_root_type_array->getMaxCount()) {
                            $prop_count = $min_count;
                        }
                    }
                    if ($array_atomic_type_array) {
                        $array_atomic_type = new TNonEmptyArray($array_atomic_type_array, $prop_count);
                    } elseif ($prop_count !== null) {
                        assert($array_atomic_type_list !== null);
                        $array_atomic_type = new TKeyedArray(array_fill(0, $prop_count, $array_atomic_type_list), null, [Type::getListKey(), $array_atomic_type_list], \true);
                    }
                } elseif ($atomic_root_type_array instanceof TKeyedArray && $atomic_root_type_array->fallback_params === null) {
                    if ($array_atomic_type_array) {
                        $array_atomic_type = new TNonEmptyArray($array_atomic_type_array, count($atomic_root_type_array->properties));
                    } elseif ($atomic_root_type_array->is_list) {
                        $array_atomic_type = $atomic_root_type_array;
                        $new_child_type = new Union([$array_atomic_type], ['parent_nodes' => $root_type->parent_nodes]);
                    } else {
                        assert($array_atomic_type_list !== null);
                        $array_atomic_type = array_fill($atomic_root_type_array->getMinCount(), count($atomic_root_type_array->properties) - 1, $array_atomic_type_list);
                        assert(count($array_atomic_type) > 0);
                        $array_atomic_type = new TKeyedArray($array_atomic_type, null, null, \true);
                    }
                    $from_countable_object_like = \true;
                } elseif ($array_atomic_type_list) {
                    $array_atomic_type = Type::getNonEmptyListAtomic($array_atomic_type_list);
                } else {
                    assert($array_atomic_type_array !== null);
                    $array_atomic_type = new TNonEmptyArray($array_atomic_type_array);
                }
            }
        }
        $array_atomic_type ??= $array_atomic_type_class_string ?? ($array_atomic_type_list !== null ? Type::getNonEmptyListAtomic($array_atomic_type_list) : null) ?? ($array_atomic_type_array !== null ? new TNonEmptyArray($array_atomic_type_array) : null);
        assert($array_atomic_type !== null);
        $array_assignment_type = new Union([$array_atomic_type]);
        if (!$new_child_type) {
            if ($templated_assignment) {
                $new_child_type = $root_type;
            } else {
                $new_child_type = Type::combineUnionTypes($root_type, $array_assignment_type, $codebase, \true, \true);
            }
        }
        if ($from_countable_object_like) {
            $atomic_root_types = $new_child_type->getAtomicTypes();
            if (isset($atomic_root_types['array'])) {
                $atomic_root_type_array = $atomic_root_types['array'];
                if ($atomic_root_type_array instanceof TList) {
                    $atomic_root_type_array = $atomic_root_type_array->getKeyedArray();
                }
                if ($atomic_root_type_array instanceof TNonEmptyArray && $atomic_root_type_array->count !== null) {
                    $atomic_root_types['array'] = $atomic_root_type_array->setCount($atomic_root_type_array->count + 1);
                    $new_child_type = new Union($atomic_root_types);
                } elseif ($atomic_root_type_array instanceof TKeyedArray && $atomic_root_type_array->is_list) {
                    $properties = $atomic_root_type_array->properties;
                    $had_undefined = \false;
                    foreach ($properties as &$property) {
                        if ($property->possibly_undefined) {
                            $property = $property->setPossiblyUndefined(\true);
                            $had_undefined = \true;
                            break;
                        }
                    }
                    if (!$had_undefined && $atomic_root_type_array->fallback_params) {
                        $properties[] = $atomic_root_type_array->fallback_params[1];
                    }
                    $atomic_root_types['array'] = $atomic_root_type_array->setProperties($properties);
                    $new_child_type = new Union($atomic_root_types);
                }
            }
        }
        return $new_child_type;
    }
    /**
     * @param  non-empty-list<PhpParser\Node\Expr\ArrayDimFetch>  $child_stmts
     * @param-out PhpParser\Node\Expr $child_stmt
     */
    private static function analyzeNestedArrayAssignment(StatementsAnalyzer $statements_analyzer, Codebase $codebase, Context $context, ?PhpParser\Node\Expr $assign_value, Union $assignment_type, array $child_stmts, ?string $root_var_id, ?string &$parent_var_id, Union &$root_type, Union &$current_type, ?PhpParser\Node\Expr &$current_dim, bool &$offset_already_existed) : void
    {
        $var_id_additions = [];
        $root_var = end($child_stmts)->var;
        // First go from the root element up, and go as far as we can to figure out what
        // array types there are
        foreach (array_reverse($child_stmts) as $i => $child_stmt) {
            $child_stmt_dim_type = null;
            $offset_type = null;
            if ($child_stmt->dim) {
                $was_inside_general_use = $context->inside_general_use;
                $context->inside_general_use = \true;
                if (ExpressionAnalyzer::analyze($statements_analyzer, $child_stmt->dim, $context) === \false) {
                    $context->inside_general_use = $was_inside_general_use;
                    return;
                }
                $context->inside_general_use = $was_inside_general_use;
                if (!($child_stmt_dim_type = $statements_analyzer->node_data->getType($child_stmt->dim))) {
                    return;
                }
                [$offset_type, $var_id_addition, $full_var_id] = self::getArrayAssignmentOffsetType($statements_analyzer, $child_stmt, $child_stmt_dim_type);
                $var_id_additions[] = $var_id_addition;
            } else {
                $var_id_additions[] = '';
                $full_var_id = \false;
            }
            if (!($array_type = $statements_analyzer->node_data->getType($child_stmt->var))) {
                return;
            }
            if ($array_type->isNever()) {
                $array_type = Type::getEmptyArray();
                $statements_analyzer->node_data->setType($child_stmt->var, $array_type);
            }
            $extended_var_id = $root_var_id . implode('', $var_id_additions);
            if ($parent_var_id && isset($context->vars_in_scope[$parent_var_id])) {
                $array_type = $context->vars_in_scope[$parent_var_id];
                $statements_analyzer->node_data->setType($child_stmt->var, $array_type);
            }
            $is_last = $i === count($child_stmts) - 1;
            $child_stmt_dim_type_or_int = $child_stmt_dim_type ?? Type::getInt();
            $child_stmt_type = ArrayFetchAnalyzer::getArrayAccessTypeGivenOffset($statements_analyzer, $child_stmt, $array_type, $child_stmt_dim_type_or_int, \true, $extended_var_id, $context, $assign_value, !$is_last ? null : $assignment_type);
            if ($child_stmt->dim) {
                $statements_analyzer->node_data->setType($child_stmt->dim, $child_stmt_dim_type_or_int);
            }
            $statements_analyzer->node_data->setType($child_stmt, $child_stmt_type);
            if ($is_last) {
                // we need this slight hack as the type we're putting it has to be
                // different from the type we're getting out
                if ($array_type->isSingle() && $array_type->hasClassStringMap()) {
                    $assignment_type = $child_stmt_type;
                }
                $child_stmt_type = $assignment_type;
                $statements_analyzer->node_data->setType($child_stmt, $assignment_type);
                if ($statements_analyzer->data_flow_graph) {
                    self::taintArrayAssignment($statements_analyzer, $child_stmt, $array_type, $assignment_type, ExpressionIdentifier::getExtendedVarId($child_stmt->var, $statements_analyzer->getFQCLN(), $statements_analyzer), $offset_type !== null ? [$offset_type] : []);
                }
            }
            $statements_analyzer->node_data->setType($child_stmt->var, $array_type);
            if ($root_var_id) {
                if (!$parent_var_id) {
                    $rooted_parent_id = $root_var_id;
                    $root_type = $array_type;
                } else {
                    $rooted_parent_id = $parent_var_id;
                }
                $context->vars_in_scope[$rooted_parent_id] = $array_type;
                $context->possibly_assigned_var_ids[$rooted_parent_id] = \true;
            }
            $current_type = $child_stmt_type;
            $current_dim = $child_stmt->dim;
            $parent_var_id = $extended_var_id;
        }
        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $root_var_id !== null && isset($context->references_to_external_scope[$root_var_id]) && $root_var instanceof Variable && is_string($root_var->name) && $root_var_id === '$' . $root_var->name) {
            // Array is a reference to an external scope, mark it as used
            $statements_analyzer->data_flow_graph->addPath(DataFlowNode::getForAssignment($root_var_id, new CodeLocation($statements_analyzer->getSource(), $root_var)), new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
        }
        if ($root_var_id && $full_var_id && ($child_stmt_var_type = $statements_analyzer->node_data->getType($child_stmt->var)) && !$child_stmt_var_type->hasObjectType()) {
            $extended_var_id = $root_var_id . implode('', $var_id_additions);
            $parent_var_id = $root_var_id . implode('', array_slice($var_id_additions, 0, -1));
            if (isset($context->vars_in_scope[$extended_var_id]) && !$context->vars_in_scope[$extended_var_id]->possibly_undefined) {
                $offset_already_existed = \true;
            }
            $context->vars_in_scope[$extended_var_id] = $assignment_type;
            $context->possibly_assigned_var_ids[$extended_var_id] = \true;
        }
        array_shift($child_stmts);
        // only update as many child stmts are we were able to process above
        foreach ($child_stmts as $child_stmt) {
            $child_stmt_type = $statements_analyzer->node_data->getType($child_stmt);
            if (!$child_stmt_type) {
                throw new InvalidArgumentException('Should never get here');
            }
            $key_values = $current_dim ? self::getDimKeyValues($statements_analyzer, $current_dim) : [];
            if ($key_values) {
                $new_child_type = self::updateTypeWithKeyValues($codebase, $child_stmt_type, $current_type, $key_values);
            } else {
                if (!$current_dim) {
                    $array_assignment_type = Type::getList($current_type);
                } else {
                    $key_type = $statements_analyzer->node_data->getType($current_dim);
                    $array_assignment_type = new Union([new TArray([$key_type && !$key_type->hasMixed() ? $key_type : Type::getArrayKey(), $current_type])]);
                }
                $new_child_type = Type::combineUnionTypes($child_stmt_type, $array_assignment_type, $codebase, \true, \true);
            }
            if ($new_child_type->hasNull() || $new_child_type->possibly_undefined) {
                $new_child_type = $new_child_type->getBuilder();
                $new_child_type->removeType('null');
                $new_child_type->possibly_undefined = \false;
                $new_child_type = $new_child_type->freeze();
            }
            if (!$child_stmt_type->hasObjectType()) {
                $child_stmt_type = $new_child_type;
                $statements_analyzer->node_data->setType($child_stmt, $new_child_type);
            }
            $current_type = $child_stmt_type;
            $current_dim = $child_stmt->dim;
            array_pop($var_id_additions);
            $parent_array_var_id = null;
            if ($root_var_id) {
                $extended_var_id = $root_var_id . implode('', $var_id_additions);
                $parent_array_var_id = $root_var_id . implode('', array_slice($var_id_additions, 0, -1));
                $context->vars_in_scope[$extended_var_id] = $child_stmt_type;
                $context->possibly_assigned_var_ids[$extended_var_id] = \true;
            }
            if ($statements_analyzer->data_flow_graph) {
                $t_orig = $statements_analyzer->node_data->getType($child_stmt->var);
                $array_type = $t_orig ?? Type::getMixed();
                self::taintArrayAssignment($statements_analyzer, $child_stmt, $array_type, $new_child_type, $parent_array_var_id, $child_stmt->dim ? self::getDimKeyValues($statements_analyzer, $child_stmt->dim) : []);
                if ($t_orig) {
                    $statements_analyzer->node_data->setType($child_stmt->var, $array_type);
                }
                if ($root_var_id) {
                    if ($parent_array_var_id === $root_var_id) {
                        $rooted_parent_id = $root_var_id;
                        $root_type = $array_type;
                    } else {
                        assert($parent_array_var_id !== null);
                        $rooted_parent_id = $parent_array_var_id;
                    }
                    $context->vars_in_scope[$rooted_parent_id] = $array_type;
                }
            }
        }
    }
    /**
     * @return list<TLiteralInt|TLiteralString>
     */
    private static function getDimKeyValues(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $dim) : array
    {
        $key_values = [];
        if ($dim instanceof PhpParser\Node\Scalar\String_) {
            $key_values[] = new TLiteralString($dim->value);
        } elseif ($dim instanceof PhpParser\Node\Scalar\LNumber) {
            $key_values[] = new TLiteralInt($dim->value);
        } else {
            $key_type = $statements_analyzer->node_data->getType($dim);
            if ($key_type) {
                $string_literals = $key_type->getLiteralStrings();
                $int_literals = $key_type->getLiteralInts();
                $all_atomic_types = $key_type->getAtomicTypes();
                if (count($string_literals) + count($int_literals) === count($all_atomic_types)) {
                    foreach ($string_literals as $string_literal) {
                        $key_values[] = $string_literal;
                    }
                    foreach ($int_literals as $int_literal) {
                        $key_values[] = $int_literal;
                    }
                }
            }
        }
        return $key_values;
    }
    /**
     * @return array{TLiteralInt|TLiteralString|null, string, bool}
     */
    private static function getArrayAssignmentOffsetType(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ArrayDimFetch $child_stmt, Union $child_stmt_dim_type) : array
    {
        if ($child_stmt->dim instanceof PhpParser\Node\Scalar\String_ || ($child_stmt->dim instanceof PhpParser\Node\Expr\ConstFetch || $child_stmt->dim instanceof PhpParser\Node\Expr\ClassConstFetch) && $child_stmt_dim_type->isSingleStringLiteral()) {
            if ($child_stmt->dim instanceof PhpParser\Node\Scalar\String_) {
                $offset_type = new TLiteralString($child_stmt->dim->value);
            } else {
                $offset_type = $child_stmt_dim_type->getSingleStringLiteral();
            }
            if (preg_match('/^(0|[1-9][0-9]*)$/', $offset_type->value)) {
                $var_id_addition = '[' . $offset_type->value . ']';
            } else {
                $var_id_addition = '[\'' . $offset_type->value . '\']';
            }
            return [$offset_type, $var_id_addition, \true];
        }
        if ($child_stmt->dim instanceof PhpParser\Node\Scalar\LNumber || ($child_stmt->dim instanceof PhpParser\Node\Expr\ConstFetch || $child_stmt->dim instanceof PhpParser\Node\Expr\ClassConstFetch) && $child_stmt_dim_type->isSingleIntLiteral()) {
            if ($child_stmt->dim instanceof PhpParser\Node\Scalar\LNumber) {
                $offset_type = new TLiteralInt($child_stmt->dim->value);
            } else {
                $offset_type = $child_stmt_dim_type->getSingleIntLiteral();
            }
            $var_id_addition = '[' . $offset_type->value . ']';
            return [$offset_type, $var_id_addition, \true];
        }
        if ($child_stmt->dim instanceof PhpParser\Node\Expr\Variable && is_string($child_stmt->dim->name)) {
            $var_id_addition = '[$' . $child_stmt->dim->name . ']';
            return [null, $var_id_addition, \true];
        }
        if ($child_stmt->dim instanceof PhpParser\Node\Expr\PropertyFetch && $child_stmt->dim->name instanceof PhpParser\Node\Identifier) {
            $object_id = ExpressionIdentifier::getExtendedVarId($child_stmt->dim->var, $statements_analyzer->getFQCLN(), $statements_analyzer);
            if ($object_id) {
                $var_id_addition = '[' . $object_id . '->' . $child_stmt->dim->name->name . ']';
            } else {
                $var_id_addition = '[' . $child_stmt_dim_type . ']';
            }
            return [null, $var_id_addition, \true];
        }
        if ($child_stmt->dim instanceof PhpParser\Node\Expr\ClassConstFetch && $child_stmt->dim->name instanceof PhpParser\Node\Identifier && $child_stmt->dim->class instanceof PhpParser\Node\Name) {
            $object_name = ClassLikeAnalyzer::getFQCLNFromNameObject($child_stmt->dim->class, $statements_analyzer->getAliases());
            $var_id_addition = '[' . $object_name . '::' . $child_stmt->dim->name->name . ']';
            return [null, $var_id_addition, \true];
        }
        $var_id_addition = '[' . $child_stmt_dim_type . ']';
        return [null, $var_id_addition, \false];
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Assignment;

use Psalm\Type\Union;
/**
 * @internal
 */
class AssignedProperty
{
    public Union $property_type;
    public string $id;
    public Union $assignment_type;
    public function __construct(Union $property_type, string $id, Union $assignment_type)
    {
        $this->property_type = $property_type;
        $this->id = $id;
        $this->assignment_type = $assignment_type;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Assignment;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ClassAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ImplicitToStringCast;
use Psalm\Issue\InvalidPropertyAssignmentValue;
use Psalm\Issue\MixedPropertyTypeCoercion;
use Psalm\Issue\PossiblyInvalidPropertyAssignmentValue;
use Psalm\Issue\PropertyTypeCoercion;
use Psalm\Issue\UndefinedPropertyAssignment;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function explode;
use function strtolower;
/**
 * @internal
 */
class StaticPropertyAssignmentAnalyzer
{
    /**
     * @return  false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticPropertyFetch $stmt, ?PhpParser\Node\Expr $assignment_value, Union $assignment_value_type, Context $context) : ?bool
    {
        $var_id = ExpressionIdentifier::getExtendedVarId($stmt, $context->self, $statements_analyzer);
        $lhs_type = $statements_analyzer->node_data->getType($stmt->class);
        if (!$lhs_type) {
            return null;
        }
        $codebase = $statements_analyzer->getCodebase();
        $prop_name = $stmt->name;
        foreach ($lhs_type->getAtomicTypes() as $lhs_atomic_type) {
            if ($lhs_atomic_type instanceof TClassString) {
                if (!$lhs_atomic_type->as_type) {
                    continue;
                }
                $lhs_atomic_type = $lhs_atomic_type->as_type;
            }
            if (!$lhs_atomic_type instanceof TNamedObject) {
                continue;
            }
            $fq_class_name = $lhs_atomic_type->value;
            if (!$prop_name instanceof PhpParser\Node\Identifier) {
                $was_inside_general_use = $context->inside_general_use;
                $context->inside_general_use = \true;
                if (ExpressionAnalyzer::analyze($statements_analyzer, $prop_name, $context) === \false) {
                    $context->inside_general_use = $was_inside_general_use;
                    return \false;
                }
                $context->inside_general_use = $was_inside_general_use;
                if (!$context->ignore_variable_property) {
                    $codebase->analyzer->addMixedMemberName(strtolower($fq_class_name) . '::$', $context->calling_method_id ?: $statements_analyzer->getFileName());
                }
                return null;
            }
            $property_id = $fq_class_name . '::$' . $prop_name;
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->class, $fq_class_name);
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $property_id);
            }
            if (!$codebase->properties->propertyExists($property_id, \false, $statements_analyzer, $context)) {
                IssueBuffer::maybeAdd(new UndefinedPropertyAssignment('Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                return null;
            }
            if (ClassLikeAnalyzer::checkPropertyVisibility($property_id, $context, $statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues()) === \false) {
                return \false;
            }
            $declaring_property_class = (string) $codebase->properties->getDeclaringClassForProperty($fq_class_name . '::$' . $prop_name->name, \false);
            $declaring_property_id = strtolower($declaring_property_class) . '::$' . $prop_name;
            if ($codebase->alter_code && $stmt->class instanceof PhpParser\Node\Name) {
                $moved_class = $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id);
                if (!$moved_class) {
                    foreach ($codebase->property_transforms as $original_pattern => $transformation) {
                        if ($declaring_property_id === $original_pattern) {
                            [$old_declaring_fq_class_name] = explode('::$', $declaring_property_id);
                            [$new_fq_class_name, $new_property_name] = explode('::$', $transformation);
                            $file_manipulations = [];
                            if (strtolower($new_fq_class_name) !== $old_declaring_fq_class_name) {
                                $file_manipulations[] = new FileManipulation((int) $stmt->class->getAttribute('startFilePos'), (int) $stmt->class->getAttribute('endFilePos') + 1, Type::getStringFromFQCLN($new_fq_class_name, $statements_analyzer->getNamespace(), $statements_analyzer->getAliasedClassesFlipped(), null));
                            }
                            $file_manipulations[] = new FileManipulation((int) $stmt->name->getAttribute('startFilePos'), (int) $stmt->name->getAttribute('endFilePos') + 1, '$' . $new_property_name);
                            FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                        }
                    }
                }
            }
            $class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
            if ($var_id) {
                $context->vars_in_scope[$var_id] = $assignment_value_type;
            }
            \Psalm\Internal\Analyzer\Statements\Expression\Assignment\InstancePropertyAssignmentAnalyzer::taintUnspecializedProperty($statements_analyzer, $stmt, $property_id, $class_storage, $assignment_value_type, $context, null);
            $class_property_type = $codebase->properties->getPropertyType($property_id, \true, $statements_analyzer, $context);
            if (!$class_property_type) {
                $class_property_type = Type::getMixed();
                $source_analyzer = $statements_analyzer->getSource()->getSource();
                $prop_name_name = $prop_name->name;
                if ($source_analyzer instanceof ClassAnalyzer && $fq_class_name === $source_analyzer->getFQCLN()) {
                    $source_analyzer->inferred_property_types[$prop_name_name] = Type::combineUnionTypes($assignment_value_type, $source_analyzer->inferred_property_types[$prop_name_name] ?? null);
                }
            }
            if ($assignment_value_type->hasMixed()) {
                return null;
            }
            if ($class_property_type->hasMixed()) {
                return null;
            }
            $class_property_type = TypeExpander::expandUnion($codebase, $class_property_type, $fq_class_name, $fq_class_name, $class_storage->parent_class);
            $union_comparison_results = new TypeComparisonResult();
            $type_match_found = UnionTypeComparator::isContainedBy($codebase, $assignment_value_type, $class_property_type, \true, \true, $union_comparison_results);
            if ($union_comparison_results->type_coerced) {
                if ($union_comparison_results->type_coerced_from_mixed) {
                    IssueBuffer::maybeAdd(new MixedPropertyTypeCoercion($var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type `' . $assignment_value_type->getId() . '` provided', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $property_id), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new PropertyTypeCoercion($var_id . ' expects \'' . $class_property_type->getId() . '\', ' . ' parent type \'' . $assignment_value_type->getId() . '\' provided', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location), $property_id), $statements_analyzer->getSuppressedIssues());
                }
            }
            if ($union_comparison_results->to_string_cast) {
                IssueBuffer::maybeAdd(new ImplicitToStringCast($var_id . ' expects \'' . $class_property_type . '\', ' . '\'' . $assignment_value_type . '\' provided with a __toString method', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt, $context->include_location)), $statements_analyzer->getSuppressedIssues());
            }
            if (!$type_match_found && !$union_comparison_results->type_coerced) {
                if (UnionTypeComparator::canBeContainedBy($codebase, $assignment_value_type, $class_property_type)) {
                    if (IssueBuffer::accepts(new PossiblyInvalidPropertyAssignmentValue($var_id . ' with declared type \'' . $class_property_type->getId() . '\' cannot be assigned type \'' . $assignment_value_type->getId() . '\'', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt), $property_id), $statements_analyzer->getSuppressedIssues())) {
                        return \false;
                    }
                } else {
                    if (IssueBuffer::accepts(new InvalidPropertyAssignmentValue($var_id . ' with declared type \'' . $class_property_type->getId() . '\' cannot be assigned type \'' . $assignment_value_type->getId() . '\'', new CodeLocation($statements_analyzer->getSource(), $assignment_value ?? $stmt), $property_id), $statements_analyzer->getSuppressedIssues())) {
                        return \false;
                    }
                }
            }
            if ($var_id) {
                $context->vars_in_scope[$var_id] = $assignment_value_type;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileSource;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateBound;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ArgumentTypeCoercion;
use Psalm\Issue\InvalidArgument;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\InvalidScalarArgument;
use Psalm\Issue\MixedArgumentTypeCoercion;
use Psalm\Issue\TypeDoesNotContainType;
use Psalm\Issue\UndefinedFunction;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\BinaryOp\VirtualIdentical;
use Psalm\Node\Expr\VirtualConstFetch;
use Psalm\Node\VirtualName;
use Psalm\Storage\Assertion\Falsy;
use Psalm\Storage\Assertion\IsIdentical;
use Psalm\Storage\Assertion\IsType;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\Possibilities;
use Psalm\Type;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_filter;
use function array_map;
use function array_merge;
use function array_unique;
use function assert;
use function count;
use function explode;
use function implode;
use function in_array;
use function is_int;
use function is_numeric;
use function mt_rand;
use function preg_match;
use function preg_replace;
use function spl_object_id;
use function str_replace;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class CallAnalyzer
{
    public static function collectSpecialInformation(FunctionLikeAnalyzer $source, string $method_name, Context $context) : void
    {
        $method_name_lc = strtolower($method_name);
        $fq_class_name = (string) $source->getFQCLN();
        $project_analyzer = $source->getFileAnalyzer()->project_analyzer;
        $codebase = $source->getCodebase();
        if ($context->collect_mutations && $context->self && ($context->self === $fq_class_name || $codebase->classExtends($context->self, $fq_class_name))) {
            $method_id = new MethodIdentifier($fq_class_name, $method_name_lc);
            if ((string) $method_id !== $source->getId()) {
                if ($context->collect_initializations) {
                    if (isset($context->initialized_methods[(string) $method_id])) {
                        return;
                    }
                    if ($context->initialized_methods === null) {
                        $context->initialized_methods = [];
                    }
                    $context->initialized_methods[(string) $method_id] = \true;
                }
                $project_analyzer->getMethodMutations($method_id, $context, $source->getRootFilePath(), $source->getRootFileName());
            }
        } elseif ($context->collect_initializations && $context->self && ($context->self === $fq_class_name || $codebase->classlikes->classExtends($context->self, $fq_class_name)) && $source->getMethodName() !== $method_name) {
            $method_id = new MethodIdentifier($fq_class_name, $method_name_lc);
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
            if (isset($context->vars_in_scope['$this'])) {
                foreach ($context->vars_in_scope['$this']->getAtomicTypes() as $atomic_type) {
                    if ($atomic_type instanceof TNamedObject) {
                        if ($fq_class_name === $atomic_type->value) {
                            $alt_declaring_method_id = $declaring_method_id;
                        } else {
                            $fq_class_name = $atomic_type->value;
                            $method_id = new MethodIdentifier($fq_class_name, $method_name_lc);
                            $alt_declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
                        }
                        if ($alt_declaring_method_id) {
                            $declaring_method_id = $alt_declaring_method_id;
                            break;
                        }
                        if (!$atomic_type->extra_types) {
                            continue;
                        }
                        foreach ($atomic_type->extra_types as $intersection_type) {
                            if ($intersection_type instanceof TNamedObject) {
                                $fq_class_name = $intersection_type->value;
                                $method_id = new MethodIdentifier($fq_class_name, $method_name_lc);
                                $alt_declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
                                if ($alt_declaring_method_id) {
                                    $declaring_method_id = $alt_declaring_method_id;
                                    break 2;
                                }
                            }
                        }
                    }
                }
            }
            if (!$declaring_method_id) {
                // can happen for __call
                return;
            }
            if (isset($context->initialized_methods[(string) $declaring_method_id])) {
                return;
            }
            if ($context->initialized_methods === null) {
                $context->initialized_methods = [];
            }
            $context->initialized_methods[(string) $declaring_method_id] = \true;
            $method_storage = $codebase->methods->getStorage($declaring_method_id);
            $class_analyzer = $source->getSource();
            $is_final = $method_storage->final;
            if ($method_name !== $declaring_method_id->method_name) {
                $appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
                if ($appearing_method_id) {
                    $appearing_class_storage = $codebase->classlike_storage_provider->get($appearing_method_id->fq_class_name);
                    if (isset($appearing_class_storage->trait_final_map[$method_name_lc])) {
                        $is_final = \true;
                    }
                }
            }
            if ($class_analyzer instanceof ClassLikeAnalyzer && !$method_storage->is_static && ($context->collect_nonprivate_initializations || $method_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE || $is_final)) {
                $local_vars_in_scope = [];
                foreach ($context->vars_in_scope as $var_id => $type) {
                    if (strpos($var_id, '$this->') === 0) {
                        if ($type->initialized) {
                            $local_vars_in_scope[$var_id] = $context->vars_in_scope[$var_id];
                            $context->remove($var_id, \false);
                        }
                    } elseif ($var_id !== '$this') {
                        $local_vars_in_scope[$var_id] = $context->vars_in_scope[$var_id];
                    }
                }
                $local_vars_possibly_in_scope = $context->vars_possibly_in_scope;
                $old_calling_method_id = $context->calling_method_id;
                if ($fq_class_name === $source->getFQCLN()) {
                    $class_analyzer->getMethodMutations($declaring_method_id->method_name, $context);
                } else {
                    $declaring_fq_class_name = $declaring_method_id->fq_class_name;
                    $old_self = $context->self;
                    $context->self = $declaring_fq_class_name;
                    $project_analyzer->getMethodMutations($declaring_method_id, $context, $source->getRootFilePath(), $source->getRootFileName());
                    $context->self = $old_self;
                }
                $context->calling_method_id = $old_calling_method_id;
                foreach ($local_vars_in_scope as $var => $type) {
                    $context->vars_in_scope[$var] = $type;
                }
                foreach ($local_vars_possibly_in_scope as $var => $_) {
                    $context->vars_possibly_in_scope[$var] = \true;
                }
            }
        }
    }
    /**
     * @param  list<PhpParser\Node\Arg>   $args
     */
    public static function checkMethodArgs(?MethodIdentifier $method_id, array $args, TemplateResult $template_result, Context $context, CodeLocation $code_location, StatementsAnalyzer $statements_analyzer) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        if (!$method_id) {
            return ArgumentsAnalyzer::analyze($statements_analyzer, $args, null, null, \true, $context, $template_result) !== \false;
        }
        $method_params = $codebase->methods->getMethodParams($method_id, $statements_analyzer, $args, $context);
        $fq_class_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        $fq_class_name = strtolower($codebase->classlikes->getUnAliasedName($fq_class_name));
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $method_storage = null;
        if (isset($class_storage->declaring_method_ids[$method_name])) {
            $declaring_method_id = $class_storage->declaring_method_ids[$method_name];
            $declaring_fq_class_name = $declaring_method_id->fq_class_name;
            $declaring_method_name = $declaring_method_id->method_name;
            if ($declaring_fq_class_name !== $fq_class_name) {
                $declaring_class_storage = $codebase->classlike_storage_provider->get($declaring_fq_class_name);
            } else {
                $declaring_class_storage = $class_storage;
            }
            if (!isset($declaring_class_storage->methods[$declaring_method_name])) {
                throw new UnexpectedValueException('Storage should not be empty here');
            }
            $method_storage = $declaring_class_storage->methods[$declaring_method_name];
            if ($declaring_class_storage->user_defined && !$method_storage->has_docblock_param_types && isset($declaring_class_storage->documenting_method_ids[$method_name])) {
                $documenting_method_id = $declaring_class_storage->documenting_method_ids[$method_name];
                $documenting_method_storage = $codebase->methods->getStorage($documenting_method_id);
                if ($documenting_method_storage->template_types) {
                    $method_storage = $documenting_method_storage;
                }
            }
            if (!$context->isSuppressingExceptions($statements_analyzer)) {
                $context->mergeFunctionExceptions($method_storage, $code_location);
            }
        }
        if (ArgumentsAnalyzer::analyze($statements_analyzer, $args, $method_params, (string) $method_id, $method_storage->allow_named_arg_calls ?? \true, $context, $template_result) === \false) {
            return \false;
        }
        if (ArgumentsAnalyzer::checkArgumentsMatch($statements_analyzer, $args, $method_id, $method_params, $method_storage, $class_storage, $template_result, $code_location, $context) === \false) {
            return \false;
        }
        if ($template_result->template_types) {
            self::checkTemplateResult($statements_analyzer, $template_result, $code_location, strtolower((string) $method_id));
        }
        return \true;
    }
    /**
     * This gets all the template params (and their types) that we think
     * we'll need to know about
     *
     * @return array<string, array<string, Union>>
     * @param array<string, non-empty-array<string, Union>> $existing_template_types
     * @param array<string, array<string, Union>> $class_template_params
     */
    public static function getTemplateTypesForCall(Codebase $codebase, ?ClassLikeStorage $declaring_class_storage, ?string $appearing_class_name, ?ClassLikeStorage $calling_class_storage, array $existing_template_types = [], array $class_template_params = []) : array
    {
        $template_types = $existing_template_types;
        if ($declaring_class_storage) {
            if ($calling_class_storage && $declaring_class_storage !== $calling_class_storage && $calling_class_storage->template_extended_params) {
                foreach ($calling_class_storage->template_extended_params as $class_name => $type_map) {
                    foreach ($type_map as $template_name => $type) {
                        if ($class_name === $declaring_class_storage->name) {
                            $output_type = null;
                            foreach ($type->getAtomicTypes() as $atomic_type) {
                                if ($atomic_type instanceof TTemplateParam) {
                                    $output_type_candidate = self::getGenericParamForOffset($atomic_type->defining_class, $atomic_type->param_name, $calling_class_storage->template_extended_params, $class_template_params + $template_types);
                                } else {
                                    $output_type_candidate = new Union([$atomic_type]);
                                }
                                $output_type = Type::combineUnionTypes($output_type_candidate, $output_type);
                            }
                            $template_types[$template_name][$declaring_class_storage->name] = $output_type;
                        }
                    }
                }
            } elseif ($declaring_class_storage->template_types) {
                foreach ($declaring_class_storage->template_types as $template_name => $type_map) {
                    foreach ($type_map as $key => $type) {
                        $template_types[$template_name][$key] = $class_template_params[$template_name][$key] ?? $type;
                    }
                }
            }
        }
        foreach ($template_types as $key => $type_map) {
            foreach ($type_map as $class => $type) {
                $template_types[$key][$class] = TypeExpander::expandUnion($codebase, $type, $appearing_class_name, $calling_class_storage->name ?? null, null, \true, \false, $calling_class_storage->final ?? \false);
            }
        }
        return $template_types;
    }
    /**
     * @param  array<string, array<string, Union>>  $template_extended_params
     * @param  array<string, array<string, Union>>  $found_generic_params
     */
    public static function getGenericParamForOffset(string $fq_class_name, string $template_name, array $template_extended_params, array $found_generic_params) : Union
    {
        if (isset($found_generic_params[$template_name][$fq_class_name])) {
            return $found_generic_params[$template_name][$fq_class_name];
        }
        foreach ($template_extended_params as $extended_class_name => $type_map) {
            foreach ($type_map as $extended_template_name => $extended_type) {
                foreach ($extended_type->getAtomicTypes() as $extended_atomic_type) {
                    if ($extended_atomic_type instanceof TTemplateParam && $extended_atomic_type->param_name === $template_name && $extended_atomic_type->defining_class === $fq_class_name) {
                        return self::getGenericParamForOffset($extended_class_name, $extended_template_name, $template_extended_params, $found_generic_params);
                    }
                }
            }
        }
        return Type::getMixed();
    }
    /**
     * @param PhpParser\Node\Scalar\String_|PhpParser\Node\Expr\Array_|PhpParser\Node\Expr\BinaryOp\Concat $callable_arg
     * @return list<non-empty-string>
     */
    public static function getFunctionIdsFromCallableArg(FileSource $file_source, PhpParser\Node\Expr $callable_arg) : array
    {
        if ($callable_arg instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
            if ($callable_arg->left instanceof PhpParser\Node\Expr\ClassConstFetch && $callable_arg->left->class instanceof Name && $callable_arg->left->name instanceof Identifier && strtolower($callable_arg->left->name->name) === 'class' && !in_array(strtolower($callable_arg->left->class->parts[0]), ['self', 'static', 'parent']) && $callable_arg->right instanceof PhpParser\Node\Scalar\String_ && preg_match('/^::[A-Za-z0-9]+$/', $callable_arg->right->value)) {
                $r = (string) $callable_arg->left->class->getAttribute('resolvedName') . $callable_arg->right->value;
                assert($r !== '');
                return [$r];
            }
            return [];
        }
        if ($callable_arg instanceof PhpParser\Node\Scalar\String_) {
            $potential_id = preg_replace('/^\\\\/', '', $callable_arg->value, 1);
            if (preg_match('/^[A-Za-z0-9_]+(\\\\[A-Za-z0-9_]+)*(::[A-Za-z0-9_]+)?$/', $potential_id)) {
                assert($potential_id !== '');
                return [$potential_id];
            }
            return [];
        }
        if (count($callable_arg->items) !== 2) {
            return [];
        }
        /** @psalm-suppress PossiblyNullPropertyFetch */
        if ($callable_arg->items[0]->key || $callable_arg->items[1]->key) {
            return [];
        }
        if (!isset($callable_arg->items[0]) || !isset($callable_arg->items[1])) {
            throw new UnexpectedValueException('These should never be unset');
        }
        $class_arg = $callable_arg->items[0]->value;
        $method_name_arg = $callable_arg->items[1]->value;
        if (!$method_name_arg instanceof PhpParser\Node\Scalar\String_) {
            return [];
        }
        if ($class_arg instanceof PhpParser\Node\Scalar\String_) {
            return [preg_replace('/^\\\\/', '', $class_arg->value, 1) . '::' . $method_name_arg->value];
        }
        if ($class_arg instanceof PhpParser\Node\Expr\ClassConstFetch && $class_arg->name instanceof Identifier && strtolower($class_arg->name->name) === 'class' && $class_arg->class instanceof Name) {
            $fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($class_arg->class, $file_source->getAliases());
            return [$fq_class_name . '::' . $method_name_arg->value];
        }
        if (!$file_source instanceof StatementsAnalyzer || !($class_arg_type = $file_source->node_data->getType($class_arg))) {
            return [];
        }
        $method_ids = [];
        foreach ($class_arg_type->getAtomicTypes() as $type_part) {
            if ($type_part instanceof TNamedObject) {
                $method_id = $type_part->value . '::' . $method_name_arg->value;
                foreach ($type_part->extra_types as $extra_type) {
                    if ($extra_type instanceof TTemplateParam || $extra_type instanceof TObjectWithProperties) {
                        throw new UnexpectedValueException('Shouldn’t get a generic param here');
                    }
                    $method_id .= '&' . $extra_type->value . '::' . $method_name_arg->value;
                }
                $method_ids[] = '$' . $method_id;
            }
        }
        return $method_ids;
    }
    /**
     * @param  non-empty-string     $function_id
     * @param  bool                 $can_be_in_root_scope if true, the function can be shortened to the root version
     */
    public static function checkFunctionExists(StatementsAnalyzer $statements_analyzer, string &$function_id, CodeLocation $code_location, bool $can_be_in_root_scope) : bool
    {
        $cased_function_id = $function_id;
        $function_id = strtolower($function_id);
        $codebase = $statements_analyzer->getCodebase();
        if (!$codebase->functions->functionExists($statements_analyzer, $function_id)) {
            /** @var non-empty-lowercase-string */
            $root_function_id = preg_replace('/.*\\\\/', '', $function_id);
            if ($can_be_in_root_scope && $function_id !== $root_function_id && $codebase->functions->functionExists($statements_analyzer, $root_function_id)) {
                $function_id = $root_function_id;
            } else {
                IssueBuffer::maybeAdd(new UndefinedFunction('Function ' . $cased_function_id . ' does not exist', $code_location, $function_id), $statements_analyzer->getSuppressedIssues());
                return \false;
            }
        }
        return \true;
    }
    /**
     * @param Identifier|Name $expr
     * @param  Possibilities[] $var_assertions
     * @param  list<PhpParser\Node\Arg> $args
     */
    public static function applyAssertionsToContext(PhpParser\NodeAbstract $expr, ?string $thisName, array $var_assertions, array $args, TemplateResult $template_result, Context $context, StatementsAnalyzer $statements_analyzer) : void
    {
        $type_assertions = [];
        $asserted_keys = [];
        foreach ($var_assertions as $var_possibilities) {
            $assertion_var_id = null;
            $arg_value = null;
            if (is_int($var_possibilities->var_id)) {
                if (!isset($args[$var_possibilities->var_id])) {
                    continue;
                }
                $arg_value = $args[$var_possibilities->var_id]->value;
                $arg_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($arg_value, null, $statements_analyzer);
                if ($arg_var_id) {
                    $assertion_var_id = $arg_var_id;
                }
            } elseif ($var_possibilities->var_id === '$this' && $thisName !== null) {
                $assertion_var_id = $thisName;
            } elseif (strpos($var_possibilities->var_id, '$this->') === 0 && $thisName !== null) {
                $assertion_var_id = $thisName . str_replace('$this->', '->', $var_possibilities->var_id);
            } elseif (strpos($var_possibilities->var_id, 'self::') === 0 && $context->self) {
                $assertion_var_id = $context->self . str_replace('self::', '::', $var_possibilities->var_id);
            } elseif (strpos($var_possibilities->var_id, '::$') !== \false) {
                // allow assertions to bring external static props into scope
                $assertion_var_id = $var_possibilities->var_id;
            } elseif (isset($context->vars_in_scope[$var_possibilities->var_id])) {
                $assertion_var_id = $var_possibilities->var_id;
            } elseif (strpos($var_possibilities->var_id, '->') !== \false) {
                $exploded = explode('->', $var_possibilities->var_id);
                if (count($exploded) < 2) {
                    IssueBuffer::maybeAdd(new InvalidDocblock('Assert notation is malformed', new CodeLocation($statements_analyzer, $expr)));
                    continue;
                }
                [$var_id, $property] = $exploded;
                $var_id = is_numeric($var_id) ? (int) $var_id : $var_id;
                if (!is_int($var_id) || !isset($args[$var_id])) {
                    IssueBuffer::maybeAdd(new InvalidDocblock('Variable ' . $var_id . ' is not an argument so cannot be asserted', new CodeLocation($statements_analyzer, $expr)));
                    continue;
                }
                /** @var PhpParser\Node\Expr\Variable $arg_value */
                $arg_value = $args[$var_id]->value;
                $arg_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($arg_value, null, $statements_analyzer);
                if (!$arg_var_id) {
                    IssueBuffer::maybeAdd(new InvalidDocblock('Variable being asserted as argument ' . ($var_id + 1) . ' cannot be found in local scope', new CodeLocation($statements_analyzer, $expr)));
                    continue;
                }
                if (count($exploded) === 2) {
                    $failedMessage = \Psalm\Internal\Analyzer\Statements\Expression\AssertionFinder::isPropertyImmutableOnArgument($property, $statements_analyzer->getNodeTypeProvider(), $statements_analyzer->getCodebase()->classlike_storage_provider, $arg_value);
                    if (null !== $failedMessage) {
                        IssueBuffer::maybeAdd(new InvalidDocblock($failedMessage, new CodeLocation($statements_analyzer, $expr)));
                        continue;
                    }
                }
                $assertion_var_id = str_replace((string) $var_id, $arg_var_id, $var_possibilities->var_id);
            }
            $codebase = $statements_analyzer->getCodebase();
            if ($assertion_var_id) {
                $orred_rules = [];
                foreach ($var_possibilities->rule as $assertion_rule) {
                    $assertion_type_atomic = $assertion_rule->getAtomicType();
                    if ($assertion_type_atomic) {
                        $assertion_type = TemplateInferredTypeReplacer::replace(new Union([$assertion_type_atomic]), $template_result, $codebase);
                        if (count($assertion_type->getAtomicTypes()) === 1) {
                            foreach ($assertion_type->getAtomicTypes() as $atomic_type) {
                                if ($assertion_type_atomic instanceof TTemplateParam && $assertion_type_atomic->as->getId() === $atomic_type->getId()) {
                                    continue;
                                }
                                $assertion_rule = $assertion_rule->setAtomicType($atomic_type);
                                $orred_rules[] = $assertion_rule;
                            }
                        } elseif (isset($context->vars_in_scope[$assertion_var_id])) {
                            $asserted_type = $context->vars_in_scope[$assertion_var_id];
                            if ($assertion_rule instanceof IsIdentical) {
                                $intersection = Type::intersectUnionTypes($assertion_type, $asserted_type, $codebase);
                                if ($intersection === null) {
                                    IssueBuffer::maybeAdd(new TypeDoesNotContainType($asserted_type->getId() . ' is not contained by ' . $assertion_type->getId(), new CodeLocation($statements_analyzer->getSource(), $expr), $asserted_type->getId() . ' ' . $assertion_type->getId()), $statements_analyzer->getSuppressedIssues());
                                    $intersection = Type::getNever();
                                } elseif ($intersection->getId(\true) === $asserted_type->getId(\true)) {
                                    continue;
                                }
                                foreach ($intersection->getAtomicTypes() as $atomic_type) {
                                    $orred_rules[] = new IsIdentical($atomic_type);
                                }
                            } elseif ($assertion_rule instanceof IsType) {
                                if (!UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $assertion_type, $asserted_type)) {
                                    IssueBuffer::maybeAdd(new TypeDoesNotContainType($asserted_type->getId() . ' is not contained by ' . $assertion_type->getId(), new CodeLocation($statements_analyzer->getSource(), $expr), $asserted_type->getId() . ' ' . $assertion_type->getId()), $statements_analyzer->getSuppressedIssues());
                                }
                            } else {
                                // Ignore negations and loose assertions with union types
                            }
                        }
                    } else {
                        $orred_rules[] = $assertion_rule;
                    }
                }
                if ($orred_rules) {
                    if (isset($type_assertions[$assertion_var_id])) {
                        $type_assertions[$assertion_var_id] = array_merge($type_assertions[$assertion_var_id], [$orred_rules]);
                    } else {
                        $type_assertions[$assertion_var_id] = [$orred_rules];
                    }
                }
            } elseif ($arg_value && count($var_possibilities->rule) === 1) {
                $assert_clauses = [];
                $single_rule = $var_possibilities->rule[0];
                if ($single_rule instanceof Truthy) {
                    $assert_clauses = FormulaGenerator::getFormula(spl_object_id($arg_value), spl_object_id($arg_value), $arg_value, $context->self, $statements_analyzer, $statements_analyzer->getCodebase());
                } elseif ($single_rule instanceof Falsy) {
                    $assert_clauses = Algebra::negateFormula(FormulaGenerator::getFormula(spl_object_id($arg_value), spl_object_id($arg_value), $arg_value, $context->self, $statements_analyzer, $codebase));
                } elseif ($single_rule instanceof IsType && $single_rule->type instanceof TTrue) {
                    $conditional = new VirtualIdentical($arg_value, new VirtualConstFetch(new VirtualName('true')));
                    $assert_clauses = FormulaGenerator::getFormula(mt_rand(0, 1000000), mt_rand(0, 1000000), $conditional, $context->self, $statements_analyzer, $codebase);
                }
                $simplified_clauses = Algebra::simplifyCNF([...$context->clauses, ...$assert_clauses]);
                $assert_type_assertions = Algebra::getTruthsFromFormula($simplified_clauses);
                $type_assertions = array_merge($type_assertions, $assert_type_assertions);
            }
        }
        $changed_var_ids = [];
        foreach ($type_assertions as $var_id => $_) {
            $asserted_keys[$var_id] = \true;
        }
        $codebase = $statements_analyzer->getCodebase();
        if ($type_assertions) {
            $template_type_map = [];
            // while in an and, we allow scope to boil over to support
            // statements of the form if ($x && $x->foo())
            [$op_vars_in_scope, $op_references_in_scope] = Reconciler::reconcileKeyedTypes($type_assertions, $type_assertions, $context->vars_in_scope, $context->references_in_scope, $changed_var_ids, $asserted_keys, $statements_analyzer, $template_type_map, $context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $expr));
            foreach ($changed_var_ids as $var_id => $_) {
                if (isset($op_vars_in_scope[$var_id])) {
                    $first_appearance = $statements_analyzer->getFirstAppearance($var_id);
                    if ($first_appearance && isset($context->vars_in_scope[$var_id]) && $context->vars_in_scope[$var_id]->hasMixed()) {
                        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                            $codebase->analyzer->decrementMixedCount($statements_analyzer->getFilePath());
                        }
                        IssueBuffer::remove($statements_analyzer->getFilePath(), 'MixedAssignment', $first_appearance->raw_file_start);
                    }
                    $op_vars_in_scope[$var_id] = $op_vars_in_scope[$var_id]->setFromDocblock(\true);
                }
            }
            $context->vars_in_scope = $op_vars_in_scope;
            $context->references_in_scope = $op_references_in_scope;
        }
    }
    /**
     * This method looks for problems with a generated TemplateResult.
     *
     * The TemplateResult object contains upper bounds and lower bounds for each template param.
     *
     * Those upper bounds represent a series of constraints like
     *
     * Lower bound:
     * T >: X (the type param T matches X, or is a supertype of X)
     * Upper bound:
     * T <: Y (the type param T matches Y, or is a subtype of Y)
     * Equality (currently represented as an upper bound with a special flag)
     * T = Z  (the template T must match Z)
     *
     * This method attempts to reconcile those constraints.
     *
     * Valid constraints:
     *
     * T <: int|float, T >: int --- implies T is an int
     * T = int --- implies T is an int
     *
     * Invalid constraints:
     *
     * T <: int|string, T >: string|float --- implies T <: int and T >: float, which is impossible
     * T = int, T = string --- implies T is a string _and_ and int, which is impossible
     */
    public static function checkTemplateResult(StatementsAnalyzer $statements_analyzer, TemplateResult $template_result, CodeLocation $code_location, ?string $function_id) : void
    {
        if ($template_result->lower_bounds && $template_result->upper_bounds) {
            foreach ($template_result->upper_bounds as $template_name => $defining_map) {
                foreach ($defining_map as $defining_id => $upper_bound) {
                    if (isset($template_result->lower_bounds[$template_name][$defining_id])) {
                        $lower_bound_type = TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($template_result->lower_bounds[$template_name][$defining_id], $statements_analyzer->getCodebase());
                        $upper_bound_type = $upper_bound->type;
                        $union_comparison_result = new TypeComparisonResult();
                        if (count($template_result->upper_bounds_unintersectable_types) > 1) {
                            [$lower_bound_type, $upper_bound_type] = $template_result->upper_bounds_unintersectable_types;
                        }
                        if (!UnionTypeComparator::isContainedBy($statements_analyzer->getCodebase(), $lower_bound_type, $upper_bound_type, \false, \false, $union_comparison_result)) {
                            if ($union_comparison_result->type_coerced) {
                                if ($union_comparison_result->type_coerced_from_mixed) {
                                    IssueBuffer::maybeAdd(new MixedArgumentTypeCoercion('Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), $code_location, $function_id), $statements_analyzer->getSuppressedIssues());
                                } else {
                                    IssueBuffer::maybeAdd(new ArgumentTypeCoercion('Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), $code_location, $function_id), $statements_analyzer->getSuppressedIssues());
                                }
                            } elseif ($union_comparison_result->scalar_type_match_found) {
                                IssueBuffer::maybeAdd(new InvalidScalarArgument('Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), $code_location, $function_id), $statements_analyzer->getSuppressedIssues());
                            } else {
                                IssueBuffer::maybeAdd(new InvalidArgument('Type ' . $lower_bound_type->getId() . ' should be a subtype of ' . $upper_bound_type->getId(), $code_location, $function_id), $statements_analyzer->getSuppressedIssues());
                            }
                        }
                    } else {
                        $template_result->lower_bounds[$template_name][$defining_id] = [new TemplateBound($upper_bound->type)];
                    }
                }
            }
        }
        // Attempt to identify invalid lower bounds
        foreach ($template_result->lower_bounds as $template_name => $lower_bounds) {
            foreach ($lower_bounds as $lower_bounds) {
                if (count($lower_bounds) > 1) {
                    $bounds_with_equality = array_filter($lower_bounds, static fn($lower_bound): bool => (bool) $lower_bound->equality_bound_classlike);
                    if (!$bounds_with_equality) {
                        continue;
                    }
                    $equality_types = array_unique(array_map(static fn($bound_with_equality) => $bound_with_equality->type->getId(), $bounds_with_equality));
                    if (count($equality_types) > 1) {
                        IssueBuffer::maybeAdd(new InvalidArgument('Incompatible types found for ' . $template_name . ' (must have only one of ' . implode(', ', $equality_types) . ')', $code_location, $function_id), $statements_analyzer->getSuppressedIssues());
                    } else {
                        foreach ($lower_bounds as $lower_bound) {
                            if ($lower_bound->equality_bound_classlike === null) {
                                foreach ($bounds_with_equality as $bound_with_equality) {
                                    if (UnionTypeComparator::isContainedBy($statements_analyzer->getCodebase(), $lower_bound->type, $bound_with_equality->type)) {
                                        continue 2;
                                    }
                                }
                                IssueBuffer::maybeAdd(new InvalidArgument('Incompatible types found for ' . $template_name . ' (' . $lower_bound->type->getId() . ' is not in ' . implode(', ', $equality_types) . ')', $code_location, $function_id), $statements_analyzer->getSuppressedIssues());
                            }
                        }
                    }
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\Codebase;
use Psalm\Exception\CircularReferenceException;
use Psalm\FileSource;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\ArithmeticOpAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\StatementsSource;
use Psalm\Storage\ClassConstantStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
use ReflectionProperty;
use function array_merge;
use function array_values;
use function count;
use function is_string;
use function preg_match;
use function strtolower;
use const PHP_INT_MAX;
/**
 * This class takes a statement and return its type by analyzing each part of the statement if necessary
 *
 * @internal
 */
class SimpleTypeInferer
{
    /**
     * @param   ?array<string, ClassConstantStorage> $existing_class_constants
     */
    public static function infer(Codebase $codebase, NodeDataProvider $nodes, PhpParser\Node\Expr $stmt, Aliases $aliases, FileSource $file_source = null, ?array $existing_class_constants = null, ?string $fq_classlike_name = null) : ?Union
    {
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
                $left = self::infer($codebase, $nodes, $stmt->left, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
                $right = self::infer($codebase, $nodes, $stmt->right, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
                if ($left && $right) {
                    if ($left->isSingleStringLiteral() && $right->isSingleStringLiteral()) {
                        $result = $left->getSingleStringLiteral()->value . $right->getSingleStringLiteral()->value;
                        return Type::getString($result);
                    }
                    if ($left->isSingle() && $left->getSingleAtomic() instanceof TNonEmptyString) {
                        return new Union([new TNonEmptyString()]);
                    }
                    if ($right->isSingle() && $right->getSingleAtomic() instanceof TNonEmptyString) {
                        return new Union([new TNonEmptyString()]);
                    }
                }
                return Type::getString();
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalAnd || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Greater || $stmt instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Smaller || $stmt instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual) {
                return Type::getBool();
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Coalesce) {
                return null;
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Spaceship) {
                return new Union([new TLiteralInt(-1), new TLiteralInt(0), new TLiteralInt(1)]);
            }
            $stmt_left_type = self::infer($codebase, $nodes, $stmt->left, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
            $stmt_right_type = self::infer($codebase, $nodes, $stmt->right, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
            if (!$stmt_left_type || !$stmt_right_type) {
                return null;
            }
            $nodes->setType($stmt->left, $stmt_left_type);
            $nodes->setType($stmt->right, $stmt_right_type);
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Plus || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Minus || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Mod || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Mul || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Pow || $stmt instanceof PhpParser\Node\Expr\BinaryOp\ShiftRight || $stmt instanceof PhpParser\Node\Expr\BinaryOp\ShiftLeft || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseAnd) {
                ArithmeticOpAnalyzer::analyze($file_source instanceof StatementsSource ? $file_source : null, $nodes, $stmt->left, $stmt->right, $stmt, $result_type);
                if ($result_type) {
                    return $result_type;
                }
                return null;
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Div && ($stmt_left_type->hasInt() || $stmt_left_type->hasFloat()) && ($stmt_right_type->hasInt() || $stmt_right_type->hasFloat())) {
                return Type::combineUnionTypes(Type::getFloat(), Type::getInt());
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\BitwiseNot) {
            $stmt_expr_type = self::infer($codebase, $nodes, $stmt->expr, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
            if ($stmt_expr_type === null) {
                return null;
            }
            $invalidTypes = $stmt_expr_type->getBuilder();
            $invalidTypes->removeType('string');
            $invalidTypes->removeType('int');
            $invalidTypes->removeType('float');
            if (!$invalidTypes->isUnionEmpty()) {
                return null;
            }
            $types = [];
            if ($stmt_expr_type->hasString()) {
                $types[] = Type::getString();
            }
            if ($stmt_expr_type->hasInt() || $stmt_expr_type->hasFloat()) {
                $types[] = Type::getInt();
            }
            return $types ? Type::combineUnionTypeArray($types, null) : null;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BooleanNot) {
            $stmt_expr_type = self::infer($codebase, $nodes, $stmt->expr, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
            if ($stmt_expr_type === null) {
                return null;
            } elseif ($stmt_expr_type->isAlwaysFalsy()) {
                return Type::getTrue();
            } elseif ($stmt_expr_type->isAlwaysTruthy()) {
                return Type::getFalse();
            } else {
                return Type::getBool();
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
            $name = strtolower($stmt->name->parts[0]);
            if ($name === 'false') {
                return Type::getFalse();
            }
            if ($name === 'true') {
                return Type::getTrue();
            }
            if ($name === 'null') {
                return Type::getNull();
            }
            if ($stmt->name->parts[0] === '__NAMESPACE__') {
                return Type::getString($aliases->namespace);
            }
            return null;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Dir || $stmt instanceof PhpParser\Node\Scalar\MagicConst\File) {
            return new Union([new TNonEmptyString()]);
        }
        if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Line) {
            return Type::getInt();
        }
        if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Class_ || $stmt instanceof PhpParser\Node\Scalar\MagicConst\Method || $stmt instanceof PhpParser\Node\Scalar\MagicConst\Trait_ || $stmt instanceof PhpParser\Node\Scalar\MagicConst\Function_) {
            return Type::getString();
        }
        if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Namespace_) {
            return Type::getString($aliases->namespace);
        }
        if ($stmt instanceof PhpParser\Node\Expr\ClassConstFetch) {
            if ($stmt->class instanceof PhpParser\Node\Name && $stmt->name instanceof PhpParser\Node\Identifier && $fq_classlike_name && $stmt->class->parts !== ['static'] && $stmt->class->parts !== ['parent']) {
                if (isset($existing_class_constants[$stmt->name->name]) && $existing_class_constants[$stmt->name->name]->type) {
                    if ($stmt->class->parts === ['self']) {
                        return $existing_class_constants[$stmt->name->name]->type;
                    }
                }
                if ($stmt->class->parts === ['self']) {
                    $const_fq_class_name = $fq_classlike_name;
                } else {
                    $const_fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $aliases);
                }
                if (strtolower($const_fq_class_name) === strtolower($fq_classlike_name) && isset($existing_class_constants[$stmt->name->name]) && $existing_class_constants[$stmt->name->name]->type) {
                    return $existing_class_constants[$stmt->name->name]->type;
                }
                if (strtolower($stmt->name->name) === 'class') {
                    return Type::getLiteralClassString($const_fq_class_name, \true);
                }
                if ($existing_class_constants === null && $file_source instanceof StatementsAnalyzer) {
                    try {
                        $foreign_class_constant = $codebase->classlikes->getClassConstantType($const_fq_class_name, $stmt->name->name, ReflectionProperty::IS_PRIVATE, $file_source);
                        if ($foreign_class_constant) {
                            return $foreign_class_constant;
                        }
                        return null;
                    } catch (InvalidArgumentException|CircularReferenceException $e) {
                        return null;
                    }
                }
            }
            if ($stmt->name instanceof PhpParser\Node\Identifier && strtolower($stmt->name->name) === 'class') {
                return Type::getClassString();
            }
            return null;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\String_) {
            return Type::getString($stmt->value);
        }
        if ($stmt instanceof PhpParser\Node\Scalar\LNumber) {
            return Type::getInt(\false, $stmt->value);
        }
        if ($stmt instanceof PhpParser\Node\Scalar\DNumber) {
            return Type::getFloat($stmt->value);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Array_) {
            return self::inferArrayType($codebase, $nodes, $stmt, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Int_) {
            return Type::getInt();
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Double) {
            return Type::getFloat();
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Bool_) {
            return Type::getBool();
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\String_) {
            return Type::getString();
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Object_) {
            return Type::getObject();
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast\Array_) {
            return Type::getArray();
        }
        if ($stmt instanceof PhpParser\Node\Expr\UnaryMinus || $stmt instanceof PhpParser\Node\Expr\UnaryPlus) {
            $type_to_invert = self::infer($codebase, $nodes, $stmt->expr, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
            if (!$type_to_invert) {
                return null;
            }
            $new_types = [];
            foreach ($type_to_invert->getAtomicTypes() as $type_part) {
                if ($type_part instanceof TLiteralInt && $stmt instanceof PhpParser\Node\Expr\UnaryMinus) {
                    $new_types[] = new TLiteralInt(-$type_part->value);
                } elseif ($type_part instanceof TLiteralFloat && $stmt instanceof PhpParser\Node\Expr\UnaryMinus) {
                    $new_types[] = new TLiteralFloat(-$type_part->value);
                } else {
                    $new_types[] = $type_part;
                }
            }
            return new Union($new_types);
        }
        if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch) {
            if ($stmt->var instanceof PhpParser\Node\Expr\ClassConstFetch && $stmt->dim) {
                $array_type = self::infer($codebase, $nodes, $stmt->var, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
                $dim_type = self::infer($codebase, $nodes, $stmt->dim, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
                if ($array_type !== null && $dim_type !== null) {
                    if ($dim_type->isSingleStringLiteral()) {
                        $dim_value = $dim_type->getSingleStringLiteral()->value;
                    } elseif ($dim_type->isSingleIntLiteral()) {
                        $dim_value = $dim_type->getSingleIntLiteral()->value;
                    } else {
                        return null;
                    }
                    foreach ($array_type->getAtomicTypes() as $array_atomic_type) {
                        if ($array_atomic_type instanceof TKeyedArray) {
                            if (isset($array_atomic_type->properties[$dim_value])) {
                                return $array_atomic_type->properties[$dim_value];
                            }
                            return null;
                        }
                    }
                }
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\New_) {
            $resolved_class_name = $stmt->class->getAttribute('resolvedName');
            if (!is_string($resolved_class_name)) {
                return null;
            }
            return new Union([new Type\Atomic\TNamedObject($resolved_class_name)]);
        }
        return null;
    }
    /**
     * @param   ?array<string, ClassConstantStorage> $existing_class_constants
     */
    private static function inferArrayType(Codebase $codebase, NodeDataProvider $nodes, PhpParser\Node\Expr\Array_ $stmt, Aliases $aliases, FileSource $file_source = null, ?array $existing_class_constants = null, ?string $fq_classlike_name = null) : ?Union
    {
        if (count($stmt->items) === 0) {
            return Type::getEmptyArray();
        }
        $array_creation_info = new \Psalm\Internal\Analyzer\Statements\Expression\ArrayCreationInfo();
        foreach ($stmt->items as $item) {
            if ($item === null) {
                continue;
            }
            if (!self::handleArrayItem($codebase, $nodes, $array_creation_info, $item, $aliases, $file_source, $existing_class_constants, $fq_classlike_name)) {
                return null;
            }
        }
        $item_key_type = null;
        if ($array_creation_info->item_key_atomic_types) {
            $item_key_type = TypeCombiner::combine($array_creation_info->item_key_atomic_types);
        }
        $item_value_type = null;
        if ($array_creation_info->item_value_atomic_types) {
            $item_value_type = TypeCombiner::combine($array_creation_info->item_value_atomic_types);
        }
        // if this array looks like an object-like array, let's return that instead
        if ($item_value_type && $item_key_type && ($item_key_type->hasString() || $item_key_type->hasInt()) && $array_creation_info->can_create_objectlike && $array_creation_info->property_types) {
            $objectlike = new TKeyedArray($array_creation_info->property_types, $array_creation_info->class_strings, null, $array_creation_info->all_list);
            return new Union([$objectlike]);
        }
        if (!$item_key_type || !$item_value_type) {
            return null;
        }
        if ($array_creation_info->all_list) {
            return Type::getNonEmptyList($item_value_type);
        }
        return new Union([new TNonEmptyArray([$item_key_type, $item_value_type])]);
    }
    /**
     * @param   ?array<string, ClassConstantStorage> $existing_class_constants
     */
    private static function handleArrayItem(Codebase $codebase, NodeDataProvider $nodes, \Psalm\Internal\Analyzer\Statements\Expression\ArrayCreationInfo $array_creation_info, PhpParser\Node\Expr\ArrayItem $item, Aliases $aliases, FileSource $file_source = null, ?array $existing_class_constants = null, ?string $fq_classlike_name = null) : bool
    {
        if ($item->unpack) {
            $unpacked_array_type = self::infer($codebase, $nodes, $item->value, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
            if (!$unpacked_array_type) {
                return \false;
            }
            return self::handleUnpackedArray($array_creation_info, $unpacked_array_type);
        }
        $single_item_key_type = null;
        $item_is_list_item = \false;
        $item_key_value = null;
        if ($item->key) {
            $single_item_key_type = self::infer($codebase, $nodes, $item->key, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
            if ($single_item_key_type) {
                $key_type = $single_item_key_type;
                if ($key_type->isNull()) {
                    $key_type = Type::getString('');
                }
                if ($item->key instanceof PhpParser\Node\Scalar\String_ && preg_match('/^(0|[1-9][0-9]*)$/', $item->key->value) && ((int) $item->key->value < PHP_INT_MAX || $item->key->value === (string) PHP_INT_MAX)) {
                    $key_type = Type::getInt(\false, (int) $item->key->value);
                }
                $array_creation_info->item_key_atomic_types = array_merge($array_creation_info->item_key_atomic_types, array_values($key_type->getAtomicTypes()));
                if ($key_type->isSingleStringLiteral()) {
                    $item_key_literal_type = $key_type->getSingleStringLiteral();
                    $item_key_value = $item_key_literal_type->value;
                    if ($item_key_literal_type instanceof TLiteralClassString) {
                        $array_creation_info->class_strings[$item_key_value] = \true;
                    }
                } elseif ($key_type->isSingleIntLiteral()) {
                    $item_key_value = $key_type->getSingleIntLiteral()->value;
                    if ($item_key_value >= $array_creation_info->int_offset) {
                        if ($item_key_value === $array_creation_info->int_offset) {
                            $item_is_list_item = \true;
                        }
                        $array_creation_info->int_offset = $item_key_value + 1;
                    }
                }
            }
        } else {
            $item_is_list_item = \true;
            $item_key_value = $array_creation_info->int_offset++;
            $array_creation_info->item_key_atomic_types[] = new TLiteralInt($item_key_value);
        }
        $single_item_value_type = self::infer($codebase, $nodes, $item->value, $aliases, $file_source, $existing_class_constants, $fq_classlike_name);
        if (!$single_item_value_type) {
            return \false;
        }
        $config = $codebase->config;
        $array_creation_info->all_list = $array_creation_info->all_list && $item_is_list_item;
        if ($item->key instanceof PhpParser\Node\Scalar\String_ || $item->key instanceof PhpParser\Node\Scalar\LNumber || !$item->key) {
            if ($item_key_value !== null && count($array_creation_info->property_types) <= $config->max_shaped_array_size) {
                $array_creation_info->property_types[$item_key_value] = $single_item_value_type;
            } else {
                $array_creation_info->can_create_objectlike = \false;
            }
        } else {
            $dim_type = $single_item_key_type;
            if (!$dim_type) {
                return \false;
            }
            if (count($dim_type->getAtomicTypes()) > 1 || $dim_type->hasMixed() || count($array_creation_info->property_types) > $config->max_shaped_array_size) {
                $array_creation_info->can_create_objectlike = \false;
            } else {
                $atomic_type = $dim_type->getSingleAtomic();
                if ($atomic_type instanceof TLiteralInt || $atomic_type instanceof TLiteralString) {
                    if ($atomic_type instanceof TLiteralClassString) {
                        $array_creation_info->class_strings[$atomic_type->value] = \true;
                    }
                    $array_creation_info->property_types[$atomic_type->value] = $single_item_value_type;
                } else {
                    $array_creation_info->can_create_objectlike = \false;
                }
            }
        }
        $array_creation_info->item_value_atomic_types = array_merge($array_creation_info->item_value_atomic_types, array_values($single_item_value_type->getAtomicTypes()));
        return \true;
    }
    private static function handleUnpackedArray(\Psalm\Internal\Analyzer\Statements\Expression\ArrayCreationInfo $array_creation_info, Union $unpacked_array_type) : bool
    {
        foreach ($unpacked_array_type->getAtomicTypes() as $unpacked_atomic_type) {
            if ($unpacked_atomic_type instanceof TList) {
                $unpacked_atomic_type = $unpacked_atomic_type->getKeyedArray();
            }
            if ($unpacked_atomic_type instanceof TKeyedArray) {
                foreach ($unpacked_atomic_type->properties as $key => $property_value) {
                    if (is_string($key)) {
                        $new_offset = $key;
                        $array_creation_info->item_key_atomic_types[] = new TLiteralString($new_offset);
                    } else {
                        $new_offset = $array_creation_info->int_offset++;
                        $array_creation_info->item_key_atomic_types[] = new TLiteralInt($new_offset);
                    }
                    $array_creation_info->item_value_atomic_types = array_merge($array_creation_info->item_value_atomic_types, array_values($property_value->getAtomicTypes()));
                    $array_creation_info->array_keys[$new_offset] = \true;
                    $array_creation_info->property_types[$new_offset] = $property_value;
                }
                if ($unpacked_atomic_type->fallback_params !== null) {
                    // Not sure if this is needed
                    //$array_creation_info->can_create_objectlike = false;
                    if ($unpacked_atomic_type->fallback_params[0]->hasString()) {
                        $array_creation_info->item_key_atomic_types[] = new TString();
                    }
                    if ($unpacked_atomic_type->fallback_params[0]->hasInt()) {
                        $array_creation_info->item_key_atomic_types[] = new TInt();
                    }
                    $array_creation_info->item_value_atomic_types = array_merge($array_creation_info->item_value_atomic_types, array_values($unpacked_atomic_type->fallback_params[1]->getAtomicTypes()));
                }
            } elseif ($unpacked_atomic_type instanceof TArray) {
                if ($unpacked_atomic_type->isEmptyArray()) {
                    continue;
                }
                $array_creation_info->can_create_objectlike = \false;
                if ($unpacked_atomic_type->type_params[0]->hasString()) {
                    $array_creation_info->item_key_atomic_types[] = new TString();
                }
                if ($unpacked_atomic_type->type_params[0]->hasInt()) {
                    $array_creation_info->item_key_atomic_types[] = new TInt();
                }
                $array_creation_info->item_value_atomic_types = array_merge($array_creation_info->item_value_atomic_types, array_values(isset($unpacked_atomic_type->type_params[1]) ? $unpacked_atomic_type->type_params[1]->getAtomicTypes() : [new TMixed()]));
            }
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArrayCreationInfo
{
    /**
     * @var list<Atomic>
     */
    public array $item_key_atomic_types = [];
    /**
     * @var list<Atomic>
     */
    public array $item_value_atomic_types = [];
    /**
     * @var array<int|string, Union>
     */
    public array $property_types = [];
    /**
     * @var array<string, true>
     */
    public array $class_strings = [];
    public bool $can_create_objectlike = \true;
    /**
     * @var array<int|string, true>
     */
    public array $array_keys = [];
    public int $int_offset = 0;
    public bool $all_list = \true;
    /**
     * @var array<string, DataFlowNode>
     */
    public array $parent_taint_nodes = [];
    public bool $can_be_empty = \true;
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Issue\InvalidOperand;
use Psalm\Issue\PossiblyInvalidOperand;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
/**
 * @internal
 */
class BitwiseNotAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BitwiseNot $stmt, Context $context) : bool
    {
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            return \false;
        }
        if (!($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr))) {
            $statements_analyzer->node_data->setType($stmt, new Union([new TInt(), new TString()]));
        } elseif ($stmt_expr_type->isMixed()) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        } else {
            $acceptable_types = [];
            $unacceptable_type = null;
            $has_valid_operand = \false;
            $stmt_expr_type = $stmt_expr_type->getBuilder();
            foreach ($stmt_expr_type->getAtomicTypes() as $type_string => $type_part) {
                if ($type_part instanceof TInt || $type_part instanceof TString) {
                    if ($type_part instanceof TLiteralInt) {
                        $type_part = new TLiteralInt(~$type_part->value);
                    } elseif ($type_part instanceof TLiteralString) {
                        $type_part = new TLiteralString(~$type_part->value);
                    }
                    $acceptable_types[] = $type_part;
                    $has_valid_operand = \true;
                } elseif ($type_part instanceof TFloat) {
                    $type_part = $type_part instanceof TLiteralFloat ? new TLiteralInt(~$type_part->value) : new TInt();
                    $stmt_expr_type->removeType($type_string);
                    $stmt_expr_type->addType($type_part);
                    $acceptable_types[] = $type_part;
                    $has_valid_operand = \true;
                } elseif (!$unacceptable_type) {
                    $unacceptable_type = $type_part;
                }
            }
            if ($unacceptable_type || !$acceptable_types) {
                $message = 'Cannot negate a non-numeric non-string type ' . $unacceptable_type;
                if ($has_valid_operand) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidOperand($message, new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new InvalidOperand($message, new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            } else {
                $statements_analyzer->node_data->setType($stmt, new Union($acceptable_types));
            }
        }
        self::addDataFlow($statements_analyzer, $stmt, $stmt->expr);
        return \true;
    }
    private static function addDataFlow(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, PhpParser\Node\Expr $value) : void
    {
        $result_type = $statements_analyzer->node_data->getType($stmt);
        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $result_type) {
            $var_location = new CodeLocation($statements_analyzer, $stmt);
            $stmt_value_type = $statements_analyzer->node_data->getType($value);
            $new_parent_node = DataFlowNode::getForAssignment('bitwisenot', $var_location);
            $statements_analyzer->data_flow_graph->addNode($new_parent_node);
            $result_type = $result_type->setParentNodes([$new_parent_node->id => $new_parent_node]);
            $statements_analyzer->node_data->setType($stmt, $result_type);
            if ($stmt_value_type && $stmt_value_type->parent_nodes) {
                foreach ($stmt_value_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, 'bitwisenot');
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Issue\ForbiddenCode;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Type\TaintKind;
use function in_array;
/**
 * @internal
 */
class EvalAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Eval_ $stmt, Context $context) : void
    {
        ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context);
        $codebase = $statements_analyzer->getCodebase();
        $expr_type = $statements_analyzer->node_data->getType($stmt->expr);
        if ($expr_type) {
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $expr_type->parent_nodes && !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                $arg_location = new CodeLocation($statements_analyzer->getSource(), $stmt->expr);
                $eval_param_sink = TaintSink::getForMethodArgument('eval', 'eval', 0, $arg_location, $arg_location);
                $eval_param_sink->taints = [TaintKind::INPUT_EVAL];
                $statements_analyzer->data_flow_graph->addSink($eval_param_sink);
                $codebase = $statements_analyzer->getCodebase();
                $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
                $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                foreach ($expr_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $eval_param_sink, 'arg', $added_taints, $removed_taints);
                }
            }
        }
        if (isset($codebase->config->forbidden_functions['eval'])) {
            IssueBuffer::maybeAdd(new ForbiddenCode('You have forbidden the use of eval', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        $context->check_classes = \false;
        $context->check_variables = \false;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\UnaryMinus;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Type;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
use RuntimeException;
/**
 * @internal
 */
class UnaryPlusMinusAnalyzer
{
    /**
     * @param PhpParser\Node\Expr\UnaryMinus|PhpParser\Node\Expr\UnaryPlus $stmt
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Context $context) : bool
    {
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            return \false;
        }
        if (!($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr))) {
            $statements_analyzer->node_data->setType($stmt, new Union([new TInt(), new TFloat()]));
        } elseif ($stmt_expr_type->isMixed()) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        } else {
            $acceptable_types = [];
            foreach ($stmt_expr_type->getAtomicTypes() as $type_part) {
                if ($type_part instanceof TInt || $type_part instanceof TFloat) {
                    if (!$stmt instanceof PhpParser\Node\Expr\UnaryMinus) {
                        $acceptable_types[] = $type_part;
                        continue;
                    }
                    if ($type_part instanceof TLiteralInt) {
                        $type_part = new TLiteralInt(-$type_part->value);
                    } elseif ($type_part instanceof TLiteralFloat) {
                        $type_part = new TLiteralFloat(-$type_part->value);
                    } elseif ($type_part instanceof TIntRange) {
                        //we'll have to inverse min and max bound and negate any literal
                        $old_min_bound = $type_part->min_bound;
                        $old_max_bound = $type_part->max_bound;
                        if ($old_min_bound === null) {
                            //min bound is null, max bound will be null
                            $new_max_bound = null;
                        } elseif ($old_min_bound === 0) {
                            $new_max_bound = 0;
                        } else {
                            $new_max_bound = -$old_min_bound;
                        }
                        if ($old_max_bound === null) {
                            //max bound is null, min bound will be null
                            $new_min_bound = null;
                        } elseif ($old_max_bound === 0) {
                            $new_min_bound = 0;
                        } else {
                            $new_min_bound = -$old_max_bound;
                        }
                        $type_part = new TIntRange($new_min_bound, $new_max_bound);
                    }
                    $acceptable_types[] = $type_part;
                } elseif ($type_part instanceof TString) {
                    $acceptable_types[] = new TInt();
                    $acceptable_types[] = new TFloat();
                } else {
                    $acceptable_types[] = new TInt();
                }
            }
            if (!$acceptable_types) {
                throw new RuntimeException("Impossible!");
            }
            $statements_analyzer->node_data->setType($stmt, new Union($acceptable_types));
        }
        self::addDataFlow($statements_analyzer, $stmt, $stmt->expr, $stmt instanceof UnaryMinus ? 'unary-minus' : 'unary-plus');
        return \true;
    }
    private static function addDataFlow(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, PhpParser\Node\Expr $value, string $type) : void
    {
        $result_type = $statements_analyzer->node_data->getType($stmt);
        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $result_type) {
            $var_location = new CodeLocation($statements_analyzer, $stmt);
            $stmt_value_type = $statements_analyzer->node_data->getType($value);
            $new_parent_node = DataFlowNode::getForAssignment($type, $var_location);
            $statements_analyzer->data_flow_graph->addNode($new_parent_node);
            $statements_analyzer->node_data->setType($stmt, $result_type->setParentNodes([$new_parent_node->id => $new_parent_node]));
            if ($stmt_value_type && $stmt_value_type->parent_nodes) {
                foreach ($stmt_value_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, $type);
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\AndAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\CoalesceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\ConcatAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\NonComparisonOpAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\OrAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\MethodIdentifier;
use Psalm\Issue\DocblockTypeContradiction;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\InvalidOperand;
use Psalm\Issue\RedundantCondition;
use Psalm\Issue\RedundantConditionGivenDocblockType;
use Psalm\Issue\TypeDoesNotContainType;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Type;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use UnexpectedValueException;
use function in_array;
use function strlen;
/**
 * @internal
 */
class BinaryOpAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BinaryOp $stmt, Context $context, int $nesting = 0, bool $from_stmt = \false) : bool
    {
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat && $nesting > 100) {
            $statements_analyzer->node_data->setType($stmt, Type::getString());
            // ignore deeply-nested string concatenation
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalAnd) {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            $expr_result = AndAnalyzer::analyze($statements_analyzer, $stmt, $context, $from_stmt);
            $context->inside_general_use = $was_inside_general_use;
            $statements_analyzer->node_data->setType($stmt, Type::getBool());
            return $expr_result;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalOr) {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            $expr_result = OrAnalyzer::analyze($statements_analyzer, $stmt, $context, $from_stmt);
            $context->inside_general_use = $was_inside_general_use;
            $statements_analyzer->node_data->setType($stmt, Type::getBool());
            return $expr_result;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Coalesce) {
            $expr_result = CoalesceAnalyzer::analyze($statements_analyzer, $stmt, $context);
            self::addDataFlow($statements_analyzer, $stmt, $stmt->left, $stmt->right, 'coalesce');
            return $expr_result;
        }
        if ($stmt->left instanceof PhpParser\Node\Expr\BinaryOp) {
            if (self::analyze($statements_analyzer, $stmt->left, $context, $nesting + 1) === \false) {
                return \false;
            }
        } else {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->left, $context) === \false) {
                return \false;
            }
        }
        if ($stmt->right instanceof PhpParser\Node\Expr\BinaryOp) {
            if (self::analyze($statements_analyzer, $stmt->right, $context, $nesting + 1) === \false) {
                return \false;
            }
        } else {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->right, $context) === \false) {
                return \false;
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
            $stmt_type = Type::getString();
            ConcatAnalyzer::analyze($statements_analyzer, $stmt->left, $stmt->right, $context, $result_type);
            if ($result_type) {
                $stmt_type = $result_type;
            }
            if ($statements_analyzer->data_flow_graph && ($statements_analyzer->data_flow_graph instanceof VariableUseGraph || !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues()))) {
                $stmt_left_type = $statements_analyzer->node_data->getType($stmt->left);
                $stmt_right_type = $statements_analyzer->node_data->getType($stmt->right);
                $var_location = new CodeLocation($statements_analyzer, $stmt);
                $new_parent_node = DataFlowNode::getForAssignment('concat', $var_location);
                $statements_analyzer->data_flow_graph->addNode($new_parent_node);
                $stmt_type = $stmt_type->setParentNodes([$new_parent_node->id => $new_parent_node]);
                $codebase = $statements_analyzer->getCodebase();
                $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
                $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                if ($stmt_left_type && $stmt_left_type->parent_nodes) {
                    foreach ($stmt_left_type->parent_nodes as $parent_node) {
                        $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, 'concat', $added_taints, $removed_taints);
                    }
                }
                if ($stmt_right_type && $stmt_right_type->parent_nodes) {
                    foreach ($stmt_right_type->parent_nodes as $parent_node) {
                        $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, 'concat', $added_taints, $removed_taints);
                    }
                }
            }
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Spaceship) {
            $statements_analyzer->node_data->setType($stmt, new Union([new TLiteralInt(-1), new TLiteralInt(0), new TLiteralInt(1)]));
            self::addDataFlow($statements_analyzer, $stmt, $stmt->left, $stmt->right, '<=>');
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Greater || $stmt instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Smaller || $stmt instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual) {
            $statements_analyzer->node_data->setType($stmt, Type::getBool());
            $stmt_left_type = $statements_analyzer->node_data->getType($stmt->left);
            $stmt_right_type = $statements_analyzer->node_data->getType($stmt->right);
            if (($stmt instanceof PhpParser\Node\Expr\BinaryOp\Greater || $stmt instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Smaller || $stmt instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual) && $statements_analyzer->getCodebase()->config->strict_binary_operands && $stmt_left_type && $stmt_right_type && ($stmt_left_type->isSingle() && $stmt_left_type->hasBool() || $stmt_right_type->isSingle() && $stmt_right_type->hasBool())) {
                IssueBuffer::maybeAdd(new InvalidOperand('Cannot compare ' . $stmt_left_type->getId() . ' to ' . $stmt_right_type->getId(), new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            if (($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical || $stmt instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) && $stmt->left instanceof PhpParser\Node\Expr\FuncCall && $stmt->left->name instanceof PhpParser\Node\Name && $stmt->left->name->parts === ['substr'] && isset($stmt->left->getArgs()[1]) && $stmt_right_type && $stmt_right_type->hasLiteralString()) {
                $from_type = $statements_analyzer->node_data->getType($stmt->left->getArgs()[1]->value);
                $length_type = isset($stmt->left->getArgs()[2]) ? $statements_analyzer->node_data->getType($stmt->left->getArgs()[2]->value) ?? Type::getMixed() : null;
                $string_length = null;
                if ($from_type && $from_type->isSingleIntLiteral() && $length_type === null) {
                    $string_length = -$from_type->getSingleIntLiteral()->value;
                } elseif ($length_type && $length_type->isSingleIntLiteral()) {
                    $string_length = $length_type->getSingleIntLiteral()->value;
                }
                if ($string_length > 0) {
                    foreach ($stmt_right_type->getAtomicTypes() as $atomic_right_type) {
                        if ($atomic_right_type instanceof TLiteralString) {
                            if (strlen($atomic_right_type->value) !== $string_length) {
                                if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
                                    if ($atomic_right_type->from_docblock) {
                                        IssueBuffer::maybeAdd(new DocblockTypeContradiction($atomic_right_type . ' string length is not ' . $string_length, new CodeLocation($statements_analyzer, $stmt), "strlen({$atomic_right_type}) !== {$string_length}"), $statements_analyzer->getSuppressedIssues());
                                    } else {
                                        IssueBuffer::maybeAdd(new TypeDoesNotContainType($atomic_right_type . ' string length is not ' . $string_length, new CodeLocation($statements_analyzer, $stmt), "strlen({$atomic_right_type}) !== {$string_length}"), $statements_analyzer->getSuppressedIssues());
                                    }
                                } else {
                                    if ($atomic_right_type->from_docblock) {
                                        IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType($atomic_right_type . ' string length is never ' . $string_length, new CodeLocation($statements_analyzer, $stmt), "strlen({$atomic_right_type}) !== {$string_length}"), $statements_analyzer->getSuppressedIssues());
                                    } else {
                                        IssueBuffer::maybeAdd(new RedundantCondition($atomic_right_type . ' string length is never ' . $string_length, new CodeLocation($statements_analyzer, $stmt), "strlen({$atomic_right_type}) !== {$string_length}"), $statements_analyzer->getSuppressedIssues());
                                    }
                                }
                            }
                        }
                    }
                }
            }
            $codebase = $statements_analyzer->getCodebase();
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal && $stmt_left_type && $stmt_right_type && ($context->mutation_free || $codebase->alter_code)) {
                self::checkForImpureEqualityComparison($statements_analyzer, $stmt, $stmt_left_type, $stmt_right_type);
            }
            self::addDataFlow($statements_analyzer, $stmt, $stmt->left, $stmt->right, 'comparison');
            return \true;
        }
        NonComparisonOpAnalyzer::analyze($statements_analyzer, $stmt, $context);
        return \true;
    }
    public static function addDataFlow(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, PhpParser\Node\Expr $left, PhpParser\Node\Expr $right, string $type = 'binaryop') : void
    {
        if ($stmt->getLine() === -1) {
            throw new UnexpectedValueException('bad');
        }
        $result_type = $statements_analyzer->node_data->getType($stmt);
        if (!$result_type) {
            return;
        }
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $stmt instanceof PhpParser\Node\Expr\BinaryOp && !$stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat && !$stmt instanceof PhpParser\Node\Expr\BinaryOp\Coalesce && (!$stmt instanceof PhpParser\Node\Expr\BinaryOp\Plus || !$result_type->hasArray())) {
            //among BinaryOp, only Concat and Coalesce can pass tainted value to the result. Also Plus on arrays only
            return;
        }
        if ($statements_analyzer->data_flow_graph) {
            $stmt_left_type = $statements_analyzer->node_data->getType($left);
            $stmt_right_type = $statements_analyzer->node_data->getType($right);
            $var_location = new CodeLocation($statements_analyzer, $stmt);
            $new_parent_node = DataFlowNode::getForAssignment($type, $var_location);
            $statements_analyzer->data_flow_graph->addNode($new_parent_node);
            $result_type = $result_type->setParentNodes([$new_parent_node->id => $new_parent_node]);
            $statements_analyzer->node_data->setType($stmt, $result_type);
            if ($stmt_left_type && $stmt_left_type->parent_nodes) {
                foreach ($stmt_left_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, $type);
                }
            }
            if ($stmt_right_type && $stmt_right_type->parent_nodes) {
                foreach ($stmt_right_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, $type);
                }
            }
            if ($stmt instanceof PhpParser\Node\Expr\AssignOp && $statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                $root_expr = $left;
                while ($root_expr instanceof PhpParser\Node\Expr\ArrayDimFetch) {
                    $root_expr = $root_expr->var;
                }
                if ($left instanceof PhpParser\Node\Expr\PropertyFetch) {
                    $statements_analyzer->data_flow_graph->addPath($new_parent_node, new DataFlowNode('variable-use', 'variable use', null), 'used-by-instance-property');
                }
                if ($left instanceof PhpParser\Node\Expr\StaticPropertyFetch) {
                    $statements_analyzer->data_flow_graph->addPath($new_parent_node, new DataFlowNode('variable-use', 'variable use', null), 'use-in-static-property');
                } elseif (!$left instanceof PhpParser\Node\Expr\Variable) {
                    $statements_analyzer->data_flow_graph->addPath($new_parent_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                }
            }
        }
    }
    private static function checkForImpureEqualityComparison(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\BinaryOp\Equal $stmt, Union $stmt_left_type, Union $stmt_right_type) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        if ($stmt_left_type->hasString() && $stmt_right_type->hasObjectType()) {
            foreach ($stmt_right_type->getAtomicTypes() as $atomic_type) {
                if ($atomic_type instanceof TNamedObject) {
                    try {
                        $storage = $codebase->methods->getStorage(new MethodIdentifier($atomic_type->value, '__tostring'));
                    } catch (UnexpectedValueException $e) {
                        continue;
                    }
                    if (!$storage->mutation_free) {
                        if ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                            $statements_analyzer->getSource()->inferred_has_mutation = \true;
                            $statements_analyzer->getSource()->inferred_impure = \true;
                        } else {
                            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating method ' . $atomic_type->value . '::__toString from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                        }
                    }
                }
            }
        } elseif ($stmt_right_type->hasString() && $stmt_left_type->hasObjectType()) {
            foreach ($stmt_left_type->getAtomicTypes() as $atomic_type) {
                if ($atomic_type instanceof TNamedObject) {
                    try {
                        $storage = $codebase->methods->getStorage(new MethodIdentifier($atomic_type->value, '__tostring'));
                    } catch (UnexpectedValueException $e) {
                        continue;
                    }
                    if (!$storage->mutation_free) {
                        if ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                            $statements_analyzer->getSource()->inferred_has_mutation = \true;
                            $statements_analyzer->getSource()->inferred_impure = \true;
                        } else {
                            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating method ' . $atomic_type->value . '::__toString from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                        }
                    }
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TKeyedArray;
use function strtolower;
/**
 * @internal
 */
class YieldFromAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\YieldFrom $stmt, Context $context) : bool
    {
        $was_inside_call = $context->inside_call;
        $context->inside_call = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            $context->inside_call = $was_inside_call;
            return \false;
        }
        if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
            $key_type = null;
            $value_type = null;
            $always_non_empty_array = \true;
            if (ForeachAnalyzer::checkIteratorType($statements_analyzer, $stmt, $stmt->expr, $stmt_expr_type, $statements_analyzer->getCodebase(), $context, $key_type, $value_type, $always_non_empty_array) === \false) {
                $context->inside_call = $was_inside_call;
                return \false;
            }
            $yield_from_type = null;
            foreach ($stmt_expr_type->getAtomicTypes() as $atomic_type) {
                if ($yield_from_type === null) {
                    if ($atomic_type instanceof TGenericObject && strtolower($atomic_type->value) === 'generator' && isset($atomic_type->type_params[3])) {
                        $yield_from_type = $atomic_type->type_params[3];
                    } elseif ($atomic_type instanceof TArray) {
                        $yield_from_type = $atomic_type->type_params[1];
                    } elseif ($atomic_type instanceof TKeyedArray) {
                        $yield_from_type = $atomic_type->getGenericValueType();
                    }
                } else {
                    $yield_from_type = Type::getMixed();
                }
            }
            // this should be whatever the generator above returns, but *not* the return type
            $statements_analyzer->node_data->setType($stmt, $yield_from_type ?: Type::getMixed());
        }
        $context->inside_call = $was_inside_call;
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionAnalyzer;
use Psalm\Internal\Analyzer\MethodAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Issue\UndefinedConstant;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Union;
use function dirname;
/**
 * @internal
 */
class MagicConstAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Scalar\MagicConst $stmt, Context $context) : void
    {
        if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Line) {
            $statements_analyzer->node_data->setType($stmt, Type::getInt());
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Class_) {
            $codebase = $statements_analyzer->getCodebase();
            if (!$context->self) {
                IssueBuffer::maybeAdd(new UndefinedConstant('Cannot get __class__ outside a class', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                $statements_analyzer->node_data->setType($stmt, Type::getClassString());
            } else {
                if ($codebase->alter_code) {
                    $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt, $context->self, $context->calling_method_id);
                }
                $statements_analyzer->node_data->setType($stmt, Type::getLiteralClassString($context->self));
            }
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Namespace_) {
            $namespace = $statements_analyzer->getNamespace();
            if ($namespace === null) {
                IssueBuffer::maybeAdd(new UndefinedConstant('Cannot get __namespace__ outside a namespace', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            $statements_analyzer->node_data->setType($stmt, Type::getString($namespace));
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Method || $stmt instanceof PhpParser\Node\Scalar\MagicConst\Function_) {
            $source = $statements_analyzer->getSource();
            if ($source instanceof MethodAnalyzer) {
                if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Function_) {
                    $statements_analyzer->node_data->setType($stmt, Type::getString($source->getMethodName()));
                } else {
                    $statements_analyzer->node_data->setType($stmt, Type::getString($source->getCorrectlyCasedMethodId()));
                }
            } elseif ($source instanceof FunctionAnalyzer) {
                $statements_analyzer->node_data->setType($stmt, Type::getString($source->getCorrectlyCasedMethodId()));
            } else {
                $statements_analyzer->node_data->setType($stmt, new Union([new TCallableString()]));
            }
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Dir) {
            $statements_analyzer->node_data->setType($stmt, Type::getString(dirname($statements_analyzer->getSource()->getFilePath())));
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\File) {
            $statements_analyzer->node_data->setType($stmt, Type::getString($statements_analyzer->getSource()->getFilePath()));
        } elseif ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Trait_) {
            if ($statements_analyzer->getSource() instanceof TraitAnalyzer) {
                $statements_analyzer->node_data->setType($stmt, new Union([new TNonEmptyString()]));
            } else {
                $statements_analyzer->node_data->setType($stmt, Type::getString());
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Issue\ForbiddenCode;
use Psalm\Issue\ImpureFunctionCall;
use Psalm\IssueBuffer;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\TaintKind;
/**
 * @internal
 */
class PrintAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Print_ $stmt, Context $context) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            return \false;
        }
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            $call_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
            $print_param_sink = TaintSink::getForMethodArgument('print', 'print', 0, null, $call_location);
            $print_param_sink->taints = [TaintKind::INPUT_HTML, TaintKind::INPUT_HAS_QUOTES, TaintKind::USER_SECRET, TaintKind::SYSTEM_SECRET];
            $statements_analyzer->data_flow_graph->addSink($print_param_sink);
        }
        if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
            if (ArgumentAnalyzer::verifyType($statements_analyzer, $stmt_expr_type, Type::getString(), null, 'print', null, 0, new CodeLocation($statements_analyzer->getSource(), $stmt->expr), $stmt->expr, $context, new FunctionLikeParameter('var', \false), \false, null, \true, \true, new CodeLocation($statements_analyzer->getSource(), $stmt)) === \false) {
                return \false;
            }
        }
        if (isset($codebase->config->forbidden_functions['print'])) {
            IssueBuffer::maybeAdd(new ForbiddenCode('You have forbidden the use of print', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        if (!$context->collect_initializations && !$context->collect_mutations) {
            if ($context->mutation_free || $context->external_mutation_free) {
                IssueBuffer::maybeAdd(new ImpureFunctionCall('Cannot call print from a mutation-free context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                $statements_analyzer->getSource()->inferred_has_mutation = \true;
                $statements_analyzer->getSource()->inferred_impure = \true;
            }
        }
        $statements_analyzer->node_data->setType($stmt, Type::getInt(\false, 1));
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Config;
use Psalm\FileSource;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use function count;
use function implode;
use function in_array;
use function is_string;
use function strtolower;
/**
 * @internal
 */
class ExpressionIdentifier
{
    public static function getVarId(PhpParser\Node\Expr $stmt, ?string $this_class_name, ?FileSource $source = null, ?int &$nesting = null) : ?string
    {
        if ($stmt instanceof PhpParser\Node\Expr\Variable && is_string($stmt->name)) {
            return '$' . $stmt->name;
        }
        if ($stmt instanceof PhpParser\Node\Expr\StaticPropertyFetch && $stmt->name instanceof PhpParser\Node\Identifier && $stmt->class instanceof PhpParser\Node\Name) {
            if (count($stmt->class->parts) === 1 && in_array(strtolower($stmt->class->parts[0]), ['self', 'static', 'parent'], \true)) {
                if (!$this_class_name) {
                    $fq_class_name = $stmt->class->parts[0];
                } else {
                    $fq_class_name = $this_class_name;
                }
            } else {
                $fq_class_name = $source ? ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $source->getAliases()) : implode('\\', $stmt->class->parts);
            }
            return $fq_class_name . '::$' . $stmt->name->name;
        }
        if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch && $stmt->name instanceof PhpParser\Node\Identifier) {
            $object_id = self::getVarId($stmt->var, $this_class_name, $source);
            if (!$object_id) {
                return null;
            }
            return $object_id . '->' . $stmt->name->name;
        }
        if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch && $nesting !== null) {
            ++$nesting;
            return self::getVarId($stmt->var, $this_class_name, $source, $nesting);
        }
        return null;
    }
    public static function getRootVarId(PhpParser\Node\Expr $stmt, ?string $this_class_name, ?FileSource $source = null) : ?string
    {
        if ($stmt instanceof PhpParser\Node\Expr\Variable || $stmt instanceof PhpParser\Node\Expr\StaticPropertyFetch) {
            return self::getVarId($stmt, $this_class_name, $source);
        }
        if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch && $stmt->name instanceof PhpParser\Node\Identifier) {
            $property_root = self::getRootVarId($stmt->var, $this_class_name, $source);
            if ($property_root) {
                return $property_root . '->' . $stmt->name->name;
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch) {
            return self::getRootVarId($stmt->var, $this_class_name, $source);
        }
        return null;
    }
    public static function getExtendedVarId(PhpParser\Node\Expr $stmt, ?string $this_class_name, ?FileSource $source = null) : ?string
    {
        if ($stmt instanceof PhpParser\Node\Expr\Assign) {
            return self::getExtendedVarId($stmt->var, $this_class_name, $source);
        }
        if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch) {
            $root_var_id = self::getExtendedVarId($stmt->var, $this_class_name, $source);
            $offset = null;
            if ($root_var_id) {
                if ($stmt->dim instanceof PhpParser\Node\Scalar\String_ || $stmt->dim instanceof PhpParser\Node\Scalar\LNumber) {
                    $offset = $stmt->dim instanceof PhpParser\Node\Scalar\String_ ? '\'' . $stmt->dim->value . '\'' : $stmt->dim->value;
                } elseif ($stmt->dim instanceof PhpParser\Node\Expr\Variable && is_string($stmt->dim->name)) {
                    $offset = '$' . $stmt->dim->name;
                } elseif ($stmt->dim instanceof PhpParser\Node\Expr\ConstFetch) {
                    $offset = implode('\\', $stmt->dim->name->parts);
                } elseif ($stmt->dim instanceof PhpParser\Node\Expr\PropertyFetch) {
                    $object_id = self::getExtendedVarId($stmt->dim->var, $this_class_name, $source);
                    if ($object_id && $stmt->dim->name instanceof PhpParser\Node\Identifier) {
                        $offset = $object_id . '->' . $stmt->dim->name;
                    }
                } elseif ($stmt->dim instanceof PhpParser\Node\Expr\ClassConstFetch && $stmt->dim->name instanceof PhpParser\Node\Identifier && $stmt->dim->class instanceof PhpParser\Node\Name && $stmt->dim->class->parts[0] === 'static') {
                    $offset = 'static::' . $stmt->dim->name;
                } elseif ($stmt->dim && $source instanceof StatementsAnalyzer && ($stmt_dim_type = $source->node_data->getType($stmt->dim)) && (!$stmt->dim instanceof PhpParser\Node\Expr\ClassConstFetch || !$stmt->dim->name instanceof PhpParser\Node\Identifier || $stmt->dim->name->name !== 'class')) {
                    if ($stmt_dim_type->isSingleStringLiteral()) {
                        $offset = '\'' . $stmt_dim_type->getSingleStringLiteral()->value . '\'';
                    } elseif ($stmt_dim_type->isSingleIntLiteral()) {
                        $offset = $stmt_dim_type->getSingleIntLiteral()->value;
                    }
                } elseif ($stmt->dim instanceof PhpParser\Node\Expr\ClassConstFetch && $stmt->dim->name instanceof PhpParser\Node\Identifier) {
                    /** @var string|null */
                    $resolved_name = $stmt->dim->class->getAttribute('resolvedName');
                    if ($resolved_name) {
                        $offset = $resolved_name . '::' . $stmt->dim->name;
                    }
                }
                return $offset !== null ? $root_var_id . '[' . $offset . ']' : null;
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch) {
            $object_id = self::getExtendedVarId($stmt->var, $this_class_name, $source);
            if (!$object_id) {
                return null;
            }
            if ($stmt->name instanceof PhpParser\Node\Identifier) {
                return $object_id . '->' . $stmt->name;
            }
            if ($source instanceof StatementsAnalyzer && ($stmt_name_type = $source->node_data->getType($stmt->name)) && $stmt_name_type->isSingleStringLiteral()) {
                return $object_id . '->' . $stmt_name_type->getSingleStringLiteral()->value;
            }
            return null;
        }
        if ($stmt instanceof PhpParser\Node\Expr\ClassConstFetch && $stmt->name instanceof PhpParser\Node\Identifier) {
            /** @var string|null */
            $resolved_name = $stmt->class->getAttribute('resolvedName');
            if ($resolved_name) {
                if (($resolved_name === 'self' || $resolved_name === 'static') && $this_class_name) {
                    $resolved_name = $this_class_name;
                }
                return $resolved_name . '::' . $stmt->name;
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\MethodCall && $stmt->name instanceof PhpParser\Node\Identifier && !$stmt->isFirstClassCallable() && !$stmt->getArgs()) {
            $config = Config::getInstance();
            if ($config->memoize_method_calls || $stmt->getAttribute('memoizable', \false)) {
                $lhs_var_name = self::getExtendedVarId($stmt->var, $this_class_name, $source);
                if (!$lhs_var_name) {
                    return null;
                }
                return $lhs_var_name . '->' . strtolower($stmt->name->name) . '()';
            }
        }
        return self::getVarId($stmt, $this_class_name, $source);
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
use function implode;
use function in_array;
use function strtolower;
/**
 * @internal
 */
class InstanceofAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Instanceof_ $stmt, Context $context) : bool
    {
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            $context->inside_general_use = $was_inside_general_use;
            return \false;
        }
        $context->inside_general_use = $was_inside_general_use;
        if ($stmt->class instanceof PhpParser\Node\Expr) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->class, $context) === \false) {
                return \false;
            }
        } elseif (!in_array(strtolower($stmt->class->parts[0]), ['self', 'static', 'parent'], \true)) {
            if ($context->check_classes) {
                $codebase = $statements_analyzer->getCodebase();
                $fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $statements_analyzer->getAliases());
                if ($codebase->store_node_types && $fq_class_name && !$context->collect_initializations && !$context->collect_mutations) {
                    $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->class, $codebase->classlikes->classOrInterfaceOrEnumExists($fq_class_name) ? $fq_class_name : '*' . ($stmt->class instanceof PhpParser\Node\Name\FullyQualified ? '\\' : $statements_analyzer->getNamespace() . '-') . implode('\\', $stmt->class->parts));
                }
                if (!isset($context->phantom_classes[strtolower($fq_class_name)])) {
                    if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($statements_analyzer->getSource(), $stmt->class), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues()) === \false) {
                        return \false;
                    }
                }
                if ($codebase->alter_code) {
                    $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id);
                }
            }
        }
        $statements_analyzer->node_data->setType($stmt, Type::getBool());
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use AssertionError;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Issue\InvalidMethodCall;
use Psalm\Issue\InvalidScope;
use Psalm\Issue\NullReference;
use Psalm\Issue\PossiblyFalseReference;
use Psalm\Issue\PossiblyInvalidMethodCall;
use Psalm\Issue\PossiblyNullReference;
use Psalm\Issue\PossiblyUndefinedMethod;
use Psalm\Issue\TooFewArguments;
use Psalm\Issue\TooManyArguments;
use Psalm\Issue\UndefinedInterfaceMethod;
use Psalm\Issue\UndefinedMagicMethod;
use Psalm\Issue\UndefinedMethod;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_reduce;
use function count;
use function is_string;
use function strtolower;
/**
 * @internal
 */
class MethodCallAnalyzer extends CallAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\MethodCall $stmt, Context $context, bool $real_method_call = \true, ?TemplateResult $template_result = null) : bool
    {
        $was_inside_call = $context->inside_call;
        $context->inside_call = \true;
        $existing_stmt_var_type = null;
        if (!$real_method_call) {
            $existing_stmt_var_type = $statements_analyzer->node_data->getType($stmt->var);
        }
        if ($existing_stmt_var_type) {
            $statements_analyzer->node_data->setType($stmt->var, $existing_stmt_var_type);
        } elseif (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context) === \false) {
            $context->inside_call = $was_inside_call;
            return \false;
        }
        if (!$stmt->name instanceof PhpParser\Node\Identifier) {
            $context->inside_call = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->name, $context) === \false) {
                $context->inside_call = $was_inside_call;
                return \false;
            }
        }
        $context->inside_call = $was_inside_call;
        if ($stmt->var instanceof PhpParser\Node\Expr\Variable) {
            if (is_string($stmt->var->name) && $stmt->var->name === 'this' && !$statements_analyzer->getFQCLN()) {
                if (IssueBuffer::accepts(new InvalidScope('Use of $this in non-class context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues())) {
                    return \false;
                }
            }
        }
        $lhs_var_id = ExpressionIdentifier::getExtendedVarId($stmt->var, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $class_type = $lhs_var_id && $context->hasVariable($lhs_var_id) ? $context->vars_in_scope[$lhs_var_id] : null;
        if ($stmt_var_type = $statements_analyzer->node_data->getType($stmt->var)) {
            $class_type = $stmt_var_type;
        } elseif (!$class_type) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        }
        if (!$context->check_classes) {
            if (\Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context) === \false) {
                return \false;
            }
            return \true;
        }
        if ($class_type && $stmt->name instanceof PhpParser\Node\Identifier && ($class_type->isNull() || $class_type->isVoid())) {
            return !IssueBuffer::accepts(new NullReference('Cannot call method ' . $stmt->name->name . ' on null value', new CodeLocation($statements_analyzer->getSource(), $stmt->name)), $statements_analyzer->getSuppressedIssues());
        }
        if ($class_type && $stmt->name instanceof PhpParser\Node\Identifier && $class_type->isNullable() && !$class_type->ignore_nullable_issues && !($stmt->name->name === 'offsetGet' && $context->inside_isset) && !self::hasNullsafe($stmt->var)) {
            IssueBuffer::maybeAdd(new PossiblyNullReference('Cannot call method ' . $stmt->name->name . ' on possibly null value', new CodeLocation($statements_analyzer->getSource(), $stmt->name)), $statements_analyzer->getSuppressedIssues());
        }
        if ($class_type && $stmt->name instanceof PhpParser\Node\Identifier && $class_type->isFalsable() && !$class_type->ignore_falsable_issues) {
            IssueBuffer::maybeAdd(new PossiblyFalseReference('Cannot call method ' . $stmt->name->name . ' on possibly false value', new CodeLocation($statements_analyzer->getSource(), $stmt->name)), $statements_analyzer->getSuppressedIssues());
        }
        $codebase = $statements_analyzer->getCodebase();
        $source = $statements_analyzer->getSource();
        if (!$class_type) {
            $class_type = Type::getMixed();
        }
        $lhs_types = $class_type->getAtomicTypes();
        $result = new AtomicMethodCallAnalysisResult();
        $possible_new_class_types = [];
        foreach ($lhs_types as $lhs_type_part) {
            AtomicMethodCallAnalyzer::analyze($statements_analyzer, $stmt, $codebase, $context, $class_type, $lhs_type_part, $lhs_type_part instanceof TNamedObject || $lhs_type_part instanceof TTemplateParam ? $lhs_type_part : null, \false, $lhs_var_id, $result, $template_result);
            if (isset($context->vars_in_scope[$lhs_var_id]) && ($possible_new_class_type = $context->vars_in_scope[$lhs_var_id]) instanceof Union && !$possible_new_class_type->equals($class_type)) {
                $possible_new_class_types[] = $context->vars_in_scope[$lhs_var_id];
            }
        }
        if (!$stmt->isFirstClassCallable() && !$stmt->getArgs() && $lhs_var_id && $stmt->name instanceof PhpParser\Node\Identifier) {
            if ($codebase->config->memoize_method_calls || $result->can_memoize) {
                $method_var_id = $lhs_var_id . '->' . strtolower($stmt->name->name) . '()';
                if (isset($context->vars_in_scope[$method_var_id])) {
                    $result->return_type = $context->vars_in_scope[$method_var_id];
                } elseif ($result->return_type !== null) {
                    $context->vars_in_scope[$method_var_id] = $result->return_type->setProperties(['has_mutations' => \false]);
                }
                if ($result->can_memoize) {
                    $stmt->setAttribute('memoizable', \true);
                }
            }
        }
        if (count($possible_new_class_types) > 0) {
            $class_type = array_reduce($possible_new_class_types, static fn(?Union $type_1, Union $type_2): Union => Type::combineUnionTypes($type_1, $type_2, $codebase));
        }
        if ($result->invalid_method_call_types) {
            $invalid_class_type = $result->invalid_method_call_types[0];
            if ($result->has_valid_method_call_type || $result->has_mixed_method_call) {
                IssueBuffer::maybeAdd(new PossiblyInvalidMethodCall('Cannot call method on possible ' . $invalid_class_type . ' variable ' . $lhs_var_id, new CodeLocation($source, $stmt->name)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new InvalidMethodCall('Cannot call method on ' . $invalid_class_type . ' variable ' . $lhs_var_id, new CodeLocation($source, $stmt->name)), $statements_analyzer->getSuppressedIssues());
            }
        }
        if ($result->non_existent_magic_method_ids) {
            if ($context->check_methods) {
                IssueBuffer::maybeAdd(new UndefinedMagicMethod('Magic method ' . $result->non_existent_magic_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_magic_method_ids[0]), $statements_analyzer->getSuppressedIssues());
            }
        }
        if ($result->non_existent_class_method_ids) {
            if ($context->check_methods) {
                if ($result->existent_method_ids || $result->has_mixed_method_call) {
                    IssueBuffer::maybeAdd(new PossiblyUndefinedMethod('Method ' . $result->non_existent_class_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_class_method_ids[0]), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new UndefinedMethod('Method ' . $result->non_existent_class_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_class_method_ids[0]), $statements_analyzer->getSuppressedIssues());
                }
            }
            return \true;
        }
        if ($result->non_existent_interface_method_ids) {
            if ($context->check_methods) {
                if ($result->existent_method_ids || $result->has_mixed_method_call) {
                    IssueBuffer::maybeAdd(new PossiblyUndefinedMethod('Method ' . $result->non_existent_interface_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_interface_method_ids[0]), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new UndefinedInterfaceMethod('Method ' . $result->non_existent_interface_method_ids[0] . ' does not exist', new CodeLocation($source, $stmt->name), $result->non_existent_interface_method_ids[0]), $statements_analyzer->getSuppressedIssues());
                }
            }
            return \true;
        }
        if ($result->too_many_arguments && $result->too_many_arguments_method_ids) {
            $error_method_id = $result->too_many_arguments_method_ids[0];
            IssueBuffer::maybeAdd(new TooManyArguments('Too many arguments for method ' . $error_method_id . ' - saw ' . count($stmt->getArgs()), new CodeLocation($source, $stmt->name), (string) $error_method_id), $statements_analyzer->getSuppressedIssues());
        }
        if ($result->too_few_arguments && $result->too_few_arguments_method_ids) {
            $error_method_id = $result->too_few_arguments_method_ids[0];
            IssueBuffer::maybeAdd(new TooFewArguments('Too few arguments for method ' . $error_method_id . ' saw ' . count($stmt->getArgs()), new CodeLocation($source, $stmt->name), (string) $error_method_id), $statements_analyzer->getSuppressedIssues());
        }
        $stmt_type = $result->return_type;
        if ($stmt_type) {
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            if ($stmt_type->isNever()) {
                $context->has_returned = \true;
            }
        }
        if ($result->returns_by_ref) {
            if (!$stmt_type) {
                $stmt_type = Type::getMixed();
                $statements_analyzer->node_data->setType($stmt, $stmt_type);
            }
            $stmt_type = $stmt_type->setByRef($result->returns_by_ref);
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations && $stmt_type) {
            $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_type->getId(), $stmt);
        }
        if (!$result->existent_method_ids) {
            return $stmt->isFirstClassCallable() || self::checkMethodArgs(null, $stmt->getArgs(), new TemplateResult([], []), $context, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer);
        }
        // if we called a method on this nullable variable, remove the nullable status here
        // because any further calls must have worked
        if ($lhs_var_id && !$class_type->isMixed() && $result->has_valid_method_call_type && !$result->has_mixed_method_call && !$result->invalid_method_call_types && ($class_type->from_docblock || $class_type->isNullable()) && $real_method_call) {
            $types = $class_type->getAtomicTypes();
            foreach ($types as $key => &$type) {
                if (!$type instanceof TNamedObject) {
                    unset($types[$key]);
                } else {
                    $type = $type->setFromDocblock(\false);
                }
            }
            if (!$types) {
                throw new AssertionError("We must have some types here!");
            }
            $context->removeVarFromConflictingClauses($lhs_var_id, null, $statements_analyzer);
            $class_type = $class_type->getBuilder()->setTypes($types);
            $class_type->from_docblock = \false;
            $context->vars_in_scope[$lhs_var_id] = $class_type->freeze();
        }
        return \true;
    }
    public static function hasNullsafe(PhpParser\Node\Expr $expr) : bool
    {
        if ($expr instanceof PhpParser\Node\Expr\MethodCall || $expr instanceof PhpParser\Node\Expr\PropertyFetch) {
            return self::hasNullsafe($expr->var);
        }
        return $expr instanceof PhpParser\Node\Expr\NullsafeMethodCall || $expr instanceof PhpParser\Node\Expr\NullsafePropertyFetch;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssertionFinder;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ConstFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\IncludeAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\ForbiddenCode;
use Psalm\Issue\PossibleRawObjectIteration;
use Psalm\Issue\RawObjectIteration;
use Psalm\Issue\RedundantFunctionCall;
use Psalm\Issue\RedundantFunctionCallGivenDocblockType;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualArray;
use Psalm\Node\Expr\VirtualArrayItem;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Scalar\VirtualString;
use Psalm\Type;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosedResource;
use Psalm\Type\Atomic\TDependentGetClass;
use Psalm\Type\Atomic\TDependentGetDebugType;
use Psalm\Type\Atomic\TDependentGetType;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use function array_map;
use function extension_loaded;
use function in_array;
use function is_string;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class NamedFunctionCallHandler
{
    /**
     * @param lowercase-string $function_id
     */
    public static function handle(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node\Expr\FuncCall $real_stmt, PhpParser\Node\Name $function_name, string $function_id, Context $context) : void
    {
        if ($function_id === 'get_class' || $function_id === 'gettype' || $function_id === 'get_debug_type') {
            self::handleDependentTypeFunction($statements_analyzer, $stmt, $real_stmt, $function_id, $context);
            return;
        }
        if ($stmt->isFirstClassCallable()) {
            return;
        }
        $first_arg = $stmt->getArgs()[0] ?? null;
        if ($function_id === 'method_exists') {
            $second_arg = $stmt->getArgs()[1] ?? null;
            if ($first_arg && $first_arg->value instanceof PhpParser\Node\Expr\Variable && $second_arg && $second_arg->value instanceof PhpParser\Node\Scalar\String_) {
                // do nothing
            } else {
                $context->check_methods = \false;
            }
            return;
        }
        if ($function_id === 'class_exists') {
            if ($first_arg) {
                if ($first_arg->value instanceof PhpParser\Node\Scalar\String_) {
                    if (!$codebase->classlikes->classExists($first_arg->value->value)) {
                        $context->phantom_classes[strtolower($first_arg->value->value)] = \true;
                    }
                } elseif ($first_arg->value instanceof PhpParser\Node\Expr\ClassConstFetch && $first_arg->value->class instanceof PhpParser\Node\Name && $first_arg->value->name instanceof PhpParser\Node\Identifier && $first_arg->value->name->name === 'class') {
                    $resolved_name = (string) $first_arg->value->class->getAttribute('resolvedName');
                    if (!$codebase->classlikes->classExists($resolved_name)) {
                        $context->phantom_classes[strtolower($resolved_name)] = \true;
                    }
                }
            }
            return;
        }
        if ($function_id === 'interface_exists') {
            if ($first_arg) {
                if ($first_arg->value instanceof PhpParser\Node\Scalar\String_) {
                    if (!$codebase->classlikes->interfaceExists($first_arg->value->value)) {
                        $context->phantom_classes[strtolower($first_arg->value->value)] = \true;
                    }
                } elseif ($first_arg->value instanceof PhpParser\Node\Expr\ClassConstFetch && $first_arg->value->class instanceof PhpParser\Node\Name && $first_arg->value->name instanceof PhpParser\Node\Identifier && $first_arg->value->name->name === 'class') {
                    $resolved_name = (string) $first_arg->value->class->getAttribute('resolvedName');
                    if (!$codebase->classlikes->interfaceExists($resolved_name)) {
                        $context->phantom_classes[strtolower($resolved_name)] = \true;
                    }
                }
            }
            return;
        }
        if ($function_id === 'enum_exists') {
            if ($first_arg) {
                if ($first_arg->value instanceof PhpParser\Node\Scalar\String_) {
                    if (!$codebase->classlikes->enumExists($first_arg->value->value)) {
                        $context->phantom_classes[strtolower($first_arg->value->value)] = \true;
                    }
                } elseif ($first_arg->value instanceof PhpParser\Node\Expr\ClassConstFetch && $first_arg->value->class instanceof PhpParser\Node\Name && $first_arg->value->name instanceof PhpParser\Node\Identifier && $first_arg->value->name->name === 'class') {
                    $resolved_name = (string) $first_arg->value->class->getAttribute('resolvedName');
                    if (!$codebase->classlikes->enumExists($resolved_name)) {
                        $context->phantom_classes[strtolower($resolved_name)] = \true;
                    }
                }
            }
            return;
        }
        if (in_array($function_id, ['is_file', 'file_exists']) && $first_arg) {
            $var_id = ExpressionIdentifier::getExtendedVarId($first_arg->value, null);
            if ($var_id) {
                $context->phantom_files[$var_id] = \true;
                return;
            }
            // literal string or (magic) const in file path
            $codebase = $statements_analyzer->getCodebase();
            $config = $codebase->config;
            $path_to_file = IncludeAnalyzer::getPathTo($first_arg->value, $statements_analyzer->node_data, $statements_analyzer, $statements_analyzer->getFileName(), $config);
            if ($path_to_file) {
                $context->phantom_files[$path_to_file] = \true;
            }
            return;
        }
        if ($function_id === 'extension_loaded') {
            if ($first_arg && $first_arg->value instanceof PhpParser\Node\Scalar\String_) {
                if (@extension_loaded($first_arg->value->value)) {
                    // do nothing
                } else {
                    $context->check_classes = \false;
                }
            }
            return;
        }
        if ($function_id === 'function_exists') {
            $context->check_functions = \false;
            return;
        }
        if ($function_id === 'is_callable') {
            $context->check_methods = \false;
            $context->check_functions = \false;
            return;
        }
        if ($function_id === 'defined') {
            $context->check_consts = \false;
            return;
        }
        if ($function_id === 'extract') {
            $context->check_variables = \false;
            foreach ($context->vars_in_scope as $var_id => $_) {
                if ($var_id === '$this' || strpos($var_id, '[') || strpos($var_id, '>')) {
                    continue;
                }
                $mixed_type = new Union([new TMixed()], ['parent_nodes' => $context->vars_in_scope[$var_id]->parent_nodes]);
                $context->vars_in_scope[$var_id] = $mixed_type;
                $context->assigned_var_ids[$var_id] = (int) $stmt->getAttribute('startFilePos');
                $context->possibly_assigned_var_ids[$var_id] = \true;
            }
            return;
        }
        if ($function_id === 'compact') {
            $all_args_string_literals = \true;
            $new_items = [];
            foreach ($stmt->getArgs() as $arg) {
                $arg_type = $statements_analyzer->node_data->getType($arg->value);
                if (!$arg_type || !$arg_type->isSingleStringLiteral()) {
                    $all_args_string_literals = \false;
                    break;
                }
                $var_name = $arg_type->getSingleStringLiteral()->value;
                $new_items[] = new VirtualArrayItem(new VirtualVariable($var_name, $arg->value->getAttributes()), new VirtualString($var_name, $arg->value->getAttributes()), \false, $arg->getAttributes());
            }
            if ($all_args_string_literals) {
                $arr = new VirtualArray($new_items, $stmt->getAttributes());
                $old_node_data = $statements_analyzer->node_data;
                $statements_analyzer->node_data = clone $statements_analyzer->node_data;
                ExpressionAnalyzer::analyze($statements_analyzer, $arr, $context);
                $arr_type = $statements_analyzer->node_data->getType($arr);
                $statements_analyzer->node_data = $old_node_data;
                if ($arr_type) {
                    $statements_analyzer->node_data->setType($stmt, $arr_type);
                }
            }
            return;
        }
        if ($function_id === 'func_get_args') {
            $source = $statements_analyzer->getSource();
            if ($source instanceof FunctionLikeAnalyzer) {
                if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                    foreach ($source->param_nodes as $param_node) {
                        $statements_analyzer->data_flow_graph->addPath($param_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                    }
                }
            }
            return;
        }
        if ($function_id === 'var_dump' || $function_id === 'shell_exec') {
            IssueBuffer::maybeAdd(new ForbiddenCode('Unsafe ' . $function_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        if (isset($codebase->config->forbidden_functions[$function_id])) {
            IssueBuffer::maybeAdd(new ForbiddenCode('You have forbidden the use of ' . $function_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            return;
        }
        if ($function_id === 'define') {
            if ($first_arg) {
                $fq_const_name = ConstFetchAnalyzer::getConstName($first_arg->value, $statements_analyzer->node_data, $codebase, $statements_analyzer->getAliases());
                if ($fq_const_name !== null && isset($stmt->getArgs()[1])) {
                    $second_arg = $stmt->getArgs()[1];
                    $was_in_call = $context->inside_call;
                    $context->inside_call = \true;
                    ExpressionAnalyzer::analyze($statements_analyzer, $second_arg->value, $context);
                    $context->inside_call = $was_in_call;
                    ConstFetchAnalyzer::setConstType($statements_analyzer, $fq_const_name, $statements_analyzer->node_data->getType($second_arg->value) ?? Type::getMixed(), $context);
                }
            } else {
                $context->check_consts = \false;
            }
            return;
        }
        if ($function_id === 'constant') {
            if ($first_arg) {
                $fq_const_name = ConstFetchAnalyzer::getConstName($first_arg->value, $statements_analyzer->node_data, $codebase, $statements_analyzer->getAliases());
                if ($fq_const_name !== null) {
                    $const_type = ConstFetchAnalyzer::getConstType($statements_analyzer, $fq_const_name, \true, $context);
                    if ($const_type) {
                        $statements_analyzer->node_data->setType($real_stmt, $const_type);
                    }
                }
            } else {
                $context->check_consts = \false;
            }
        }
        if ($first_arg && $function_id && strpos($function_id, 'is_') === 0 && $function_id !== 'is_a' && !$context->inside_negation) {
            $stmt_assertions = $statements_analyzer->node_data->getAssertions($stmt);
            $anded_assertions = $stmt_assertions ?? AssertionFinder::processFunctionCall($stmt, $context->self, $statements_analyzer, $codebase, $context->inside_negation);
            $changed_vars = [];
            foreach ($anded_assertions as $assertions) {
                $referenced_var_ids = array_map(static fn(array $_): bool => \true, $assertions);
                Reconciler::reconcileKeyedTypes($assertions, $assertions, $context->vars_in_scope, $context->references_in_scope, $changed_vars, $referenced_var_ids, $statements_analyzer, [], $context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $stmt));
            }
            return;
        }
        if ($first_arg && ($function_id === 'array_values' || $function_id === 'ksort')) {
            $first_arg_type = $statements_analyzer->node_data->getType($first_arg->value);
            if ($first_arg_type && UnionTypeComparator::isContainedBy($codebase, $first_arg_type, Type::getList())) {
                if ($first_arg_type->from_docblock) {
                    IssueBuffer::maybeAdd(new RedundantFunctionCallGivenDocblockType("The call to {$function_id} is unnecessary given the list docblock type {$first_arg_type}", new CodeLocation($statements_analyzer, $function_name)), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new RedundantFunctionCall("The call to {$function_id} is unnecessary, {$first_arg_type} is already a list", new CodeLocation($statements_analyzer, $function_name)), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
        if ($first_arg && $function_id === 'strtolower') {
            $first_arg_type = $statements_analyzer->node_data->getType($first_arg->value);
            if ($first_arg_type && UnionTypeComparator::isContainedBy($codebase, $first_arg_type, new Union([new TLowercaseString()]))) {
                if ($first_arg_type->from_docblock) {
                    IssueBuffer::maybeAdd(new RedundantFunctionCallGivenDocblockType('The call to strtolower is unnecessary given the docblock type', new CodeLocation($statements_analyzer, $function_name)), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new RedundantFunctionCall('The call to strtolower is unnecessary', new CodeLocation($statements_analyzer, $function_name)), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
        if ($first_arg && ($function_id === 'array_walk' || $function_id === 'array_walk_recursive')) {
            $first_arg_type = $statements_analyzer->node_data->getType($first_arg->value);
            if ($first_arg_type && $first_arg_type->hasObjectType()) {
                if ($first_arg_type->isSingle()) {
                    IssueBuffer::maybeAdd(new RawObjectIteration('Possibly undesired iteration over object properties', new CodeLocation($statements_analyzer, $function_name)));
                } else {
                    IssueBuffer::maybeAdd(new PossibleRawObjectIteration('Possibly undesired iteration over object properties', new CodeLocation($statements_analyzer, $function_name)));
                }
            }
        }
    }
    private static function handleDependentTypeFunction(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node\Expr\FuncCall $real_stmt, string $function_id, Context $context) : void
    {
        $first_arg = $stmt->getArgs()[0] ?? null;
        if ($first_arg) {
            $var = $first_arg->value;
            if ($var instanceof PhpParser\Node\Expr\Variable && is_string($var->name)) {
                $var_id = '$' . $var->name;
                if (isset($context->vars_in_scope[$var_id])) {
                    if (!$context->vars_in_scope[$var_id]->hasTemplate()) {
                        if ($function_id === 'get_class') {
                            $atomic_type = new TDependentGetClass($var_id, $context->vars_in_scope[$var_id]->hasMixed() ? Type::getObject() : $context->vars_in_scope[$var_id]);
                        } elseif ($function_id === 'gettype') {
                            $atomic_type = new TDependentGetType($var_id);
                        } else {
                            $atomic_type = new TDependentGetDebugType($var_id);
                        }
                        $statements_analyzer->node_data->setType($real_stmt, new Union([$atomic_type]));
                        return;
                    }
                }
            }
            if (($var_type = $statements_analyzer->node_data->getType($var)) && ($function_id === 'get_class' || $function_id === 'get_debug_type')) {
                $class_string_types = [];
                foreach ($var_type->getAtomicTypes() as $class_type) {
                    if ($class_type instanceof TNamedObject) {
                        $class_string_types[] = new TClassString($class_type->value, $class_type);
                    } elseif ($class_type instanceof TTemplateParam && $class_type->as->isSingle()) {
                        $as_atomic_type = $class_type->as->getSingleAtomic();
                        if ($as_atomic_type instanceof TObject) {
                            $class_string_types[] = new TTemplateParamClass($class_type->param_name, 'object', null, $class_type->defining_class);
                        } elseif ($as_atomic_type instanceof TNamedObject) {
                            $class_string_types[] = new TTemplateParamClass($class_type->param_name, $as_atomic_type->value, $as_atomic_type, $class_type->defining_class);
                        }
                    } elseif ($function_id === 'get_class') {
                        $class_string_types[] = new TClassString();
                    } else {
                        if ($class_type instanceof TInt) {
                            $class_string_types[] = new TLiteralString('int');
                        } elseif ($class_type instanceof TString) {
                            $class_string_types[] = new TLiteralString('string');
                        } elseif ($class_type instanceof TFloat) {
                            $class_string_types[] = new TLiteralString('float');
                        } elseif ($class_type instanceof TBool) {
                            $class_string_types[] = new TLiteralString('bool');
                        } elseif ($class_type instanceof TClosedResource) {
                            $class_string_types[] = new TLiteralString('resource (closed)');
                        } elseif ($class_type instanceof TNull) {
                            $class_string_types[] = new TLiteralString('null');
                        } else {
                            $class_string_types[] = new TString();
                        }
                    }
                }
                if ($class_string_types) {
                    $statements_analyzer->node_data->setType($real_stmt, new Union($class_string_types));
                }
            }
        } elseif ($function_id === 'get_class' && ($get_class_name = $statements_analyzer->getFQCLN())) {
            $statements_analyzer->node_data->setType($real_stmt, new Union([new TClassString($get_class_name, new TNamedObject($get_class_name))]));
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\AtomicStaticCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\TaintSource;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\NonStaticSelfCall;
use Psalm\Issue\ParentNotFound;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function array_merge;
use function count;
use function in_array;
use function md5;
use function strtolower;
/**
 * @internal
 */
class StaticCallAnalyzer extends CallAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, Context $context, ?TemplateResult $template_result = null) : bool
    {
        $method_id = null;
        $lhs_type = null;
        $codebase = $statements_analyzer->getCodebase();
        $source = $statements_analyzer->getSource();
        $config = $codebase->config;
        if ($stmt->class instanceof PhpParser\Node\Name) {
            $fq_class_name = null;
            if (count($stmt->class->parts) === 1 && in_array(strtolower($stmt->class->parts[0]), ['self', 'static', 'parent'], \true)) {
                if ($stmt->class->parts[0] === 'parent') {
                    $child_fq_class_name = $context->self;
                    $class_storage = $child_fq_class_name ? $codebase->classlike_storage_provider->get($child_fq_class_name) : null;
                    if (!$class_storage || !$class_storage->parent_class) {
                        return !IssueBuffer::accepts(new ParentNotFound('Cannot call method on parent as this class does not extend another', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    }
                    $fq_class_name = $class_storage->parent_class;
                    $fq_class_name = $codebase->classlikes->getUnAliasedName($fq_class_name);
                    $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
                    $fq_class_name = $class_storage->name;
                } elseif ($context->self) {
                    if ($stmt->class->parts[0] === 'static' && isset($context->vars_in_scope['$this'])) {
                        $fq_class_name = (string) $context->vars_in_scope['$this'];
                        $lhs_type = $context->vars_in_scope['$this'];
                    } else {
                        $fq_class_name = $context->self;
                    }
                } else {
                    return !IssueBuffer::accepts(new NonStaticSelfCall('Cannot use ' . $stmt->class->parts[0] . ' outside class context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                if ($context->isPhantomClass($fq_class_name)) {
                    return \true;
                }
            } elseif ($context->check_classes) {
                $aliases = $statements_analyzer->getAliases();
                if ($context->calling_method_id && !$stmt->class instanceof PhpParser\Node\Name\FullyQualified) {
                    $codebase->file_reference_provider->addMethodReferenceToClassMember($context->calling_method_id, 'use:' . $stmt->class->parts[0] . ':' . md5($statements_analyzer->getFilePath()), \false);
                }
                $fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $aliases);
                if ($context->isPhantomClass($fq_class_name)) {
                    return \true;
                }
                $does_class_exist = \false;
                if ($context->self) {
                    $self_storage = $codebase->classlike_storage_provider->get($context->self);
                    if (isset($self_storage->used_traits[strtolower($fq_class_name)])) {
                        $fq_class_name = $context->self;
                        $does_class_exist = \true;
                    }
                }
                if (!isset($context->phantom_classes[strtolower($fq_class_name)]) && !$does_class_exist) {
                    $does_class_exist = ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($source, $stmt->class), !$context->collect_initializations && !$context->collect_mutations ? $context->self : null, !$context->collect_initializations && !$context->collect_mutations ? $context->calling_method_id : null, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\false, \false, \false, \true));
                }
                if (!$does_class_exist) {
                    return $does_class_exist !== \false;
                }
            }
            if ($codebase->store_node_types && $fq_class_name && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->class, $fq_class_name);
            }
            if ($fq_class_name && !$lhs_type) {
                $lhs_type = new Union([new TNamedObject($fq_class_name)]);
            }
        } else {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            ExpressionAnalyzer::analyze($statements_analyzer, $stmt->class, $context);
            $context->inside_general_use = $was_inside_general_use;
            $lhs_type = $statements_analyzer->node_data->getType($stmt->class) ?? Type::getMixed();
        }
        if (!$lhs_type) {
            if (\Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context) === \false) {
                return \false;
            }
            return \true;
        }
        $has_mock = \false;
        $moved_call = \false;
        $has_existing_method = \false;
        foreach ($lhs_type->getAtomicTypes() as $lhs_type_part) {
            AtomicStaticCallAnalyzer::analyze($statements_analyzer, $stmt, $context, $lhs_type_part, $lhs_type->ignore_nullable_issues, $moved_call, $has_mock, $has_existing_method, $template_result);
        }
        if (!$stmt->isFirstClassCallable() && !$has_existing_method) {
            return self::checkMethodArgs($method_id, $stmt->getArgs(), new TemplateResult([], []), $context, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer);
        }
        if (!$config->remember_property_assignments_after_call && !$context->collect_initializations) {
            $context->removeMutableObjectVars();
        }
        if (!$statements_analyzer->node_data->getType($stmt)) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        }
        return \true;
    }
    public static function taintReturnType(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, MethodIdentifier $method_id, string $cased_method_id, Union &$return_type_candidate, ?MethodStorage $method_storage, ?TemplateResult $template_result, ?Context $context = null) : void
    {
        if (!$statements_analyzer->data_flow_graph) {
            return;
        }
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
            return;
        }
        $node_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
        $method_location = $method_storage ? $statements_analyzer->data_flow_graph instanceof TaintFlowGraph ? $method_storage->signature_return_type_location ?: $method_storage->location : ($method_storage->return_type_location ?: $method_storage->location) : null;
        if ($method_storage && $method_storage->specialize_call) {
            $method_source = DataFlowNode::getForMethodReturn((string) $method_id, $cased_method_id, $method_location, $node_location);
        } else {
            $method_source = DataFlowNode::getForMethodReturn((string) $method_id, $cased_method_id, $method_location);
        }
        $statements_analyzer->data_flow_graph->addNode($method_source);
        $codebase = $statements_analyzer->getCodebase();
        $conditionally_removed_taints = [];
        if ($method_storage && $template_result) {
            foreach ($method_storage->conditionally_removed_taints as $conditionally_removed_taint) {
                $conditionally_removed_taint = TemplateInferredTypeReplacer::replace($conditionally_removed_taint, $template_result, $codebase);
                $expanded_type = TypeExpander::expandUnion($statements_analyzer->getCodebase(), $conditionally_removed_taint, null, null, null, \true, \true);
                foreach ($expanded_type->getLiteralStrings() as $literal_string) {
                    $conditionally_removed_taints[] = $literal_string->value;
                }
            }
        }
        $added_taints = [];
        $removed_taints = [];
        if ($context) {
            $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
            $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
            $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
        }
        if ($conditionally_removed_taints && $method_location) {
            $assignment_node = DataFlowNode::getForAssignment($method_id . '-escaped', $method_location, $method_source->specialization_key);
            $statements_analyzer->data_flow_graph->addPath($method_source, $assignment_node, 'conditionally-escaped', $added_taints, [...$conditionally_removed_taints, ...$removed_taints]);
            $return_type_candidate = $return_type_candidate->addParentNodes([$assignment_node->id => $assignment_node]);
        } else {
            $return_type_candidate = $return_type_candidate->setParentNodes([$method_source->id => $method_source]);
        }
        if ($method_storage && $method_storage->taint_source_types && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            $method_node = TaintSource::getForMethodReturn((string) $method_id, $cased_method_id, $method_storage->signature_return_type_location ?: $method_storage->location);
            $method_node->taints = $method_storage->taint_source_types;
            $statements_analyzer->data_flow_graph->addSource($method_node);
        }
        if ($method_storage && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            \Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallReturnTypeFetcher::taintUsingFlows($statements_analyzer, $method_storage, $statements_analyzer->data_flow_graph, (string) $method_id, $stmt->getArgs(), $node_location, $method_source, array_merge($method_storage->removed_taints, $removed_taints), $added_taints);
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\MethodAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CastAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\ConstantTypeResolver;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\CallableTypeComparator;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateBound;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ArgumentTypeCoercion;
use Psalm\Issue\ImplicitToStringCast;
use Psalm\Issue\InvalidArgument;
use Psalm\Issue\InvalidLiteralArgument;
use Psalm\Issue\InvalidScalarArgument;
use Psalm\Issue\MixedArgument;
use Psalm\Issue\MixedArgumentTypeCoercion;
use Psalm\Issue\NamedArgumentNotAllowed;
use Psalm\Issue\NoValue;
use Psalm\Issue\NullArgument;
use Psalm\Issue\PossiblyFalseArgument;
use Psalm\Issue\PossiblyInvalidArgument;
use Psalm\Issue\PossiblyNullArgument;
use Psalm\IssueBuffer;
use Psalm\Node\VirtualArg;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function count;
use function explode;
use function implode;
use function in_array;
use function ord;
use function preg_split;
use function reset;
use function strpos;
use function strtolower;
use function substr;
use const PREG_SPLIT_NO_EMPTY;
/**
 * @internal
 */
class ArgumentAnalyzer
{
    /**
     * @param  array<string, array<string, Union>> $class_generic_params
     * @return false|null
     */
    public static function checkArgumentMatches(StatementsAnalyzer $statements_analyzer, ?string $cased_method_id, ?MethodIdentifier $method_id, ?string $self_fq_class_name, ?string $static_fq_class_name, CodeLocation $function_call_location, ?FunctionLikeParameter $function_param, int $argument_offset, int $unpacked_argument_offset, bool $allow_named_args, PhpParser\Node\Arg $arg, ?Union $arg_value_type, Context $context, array $class_generic_params, ?TemplateResult $template_result, bool $specialize_taint, bool $in_call_map) : ?bool
    {
        $codebase = $statements_analyzer->getCodebase();
        if (!$arg_value_type) {
            if ($function_param && !$function_param->by_ref) {
                if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                    $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
                }
                $param_type = $function_param->type;
                if ($function_param->is_variadic && $param_type && $param_type->hasArray()) {
                    $array_type = $param_type->getArray();
                    if ($array_type instanceof TKeyedArray && $array_type->is_list) {
                        $param_type = $array_type->getGenericValueType();
                    } elseif ($array_type instanceof TArray) {
                        $param_type = $array_type->type_params[1];
                    }
                }
                if ($param_type && !$param_type->hasMixed()) {
                    IssueBuffer::maybeAdd(new MixedArgument('Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' cannot be mixed, expecting ' . $param_type, new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                }
            }
            return null;
        }
        if (!$function_param) {
            return null;
        }
        if ($function_param->expect_variable && $arg_value_type->isSingleStringLiteral() && !$arg->value instanceof PhpParser\Node\Scalar\MagicConst && !$arg->value instanceof PhpParser\Node\Expr\ConstFetch && !$arg->value instanceof PhpParser\Node\Expr\ClassConstFetch) {
            $values = preg_split('//u', $arg_value_type->getSingleStringLiteral()->value, -1, PREG_SPLIT_NO_EMPTY);
            if ($values !== \false) {
                $prev_ord = 0;
                $gt_count = 0;
                foreach ($values as $value) {
                    $ord = ord($value);
                    if ($ord > $prev_ord) {
                        $gt_count++;
                    }
                    $prev_ord = $ord;
                }
                if (count($values) < 12 || $gt_count / count($values) < 0.8) {
                    IssueBuffer::maybeAdd(new InvalidLiteralArgument('Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' expects a non-literal value, but ' . $arg_value_type->getId() . ' provided', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
        if (self::checkFunctionLikeTypeMatches($statements_analyzer, $codebase, $cased_method_id, $method_id, $self_fq_class_name, $static_fq_class_name, $function_call_location, $function_param, $allow_named_args, $arg_value_type, $argument_offset, $unpacked_argument_offset, $arg, $context, $class_generic_params, $template_result, $specialize_taint, $in_call_map) === \false) {
            return \false;
        }
        return null;
    }
    /**
     * @param  array<string, array<string, Union>> $class_generic_params
     * @return false|null
     */
    private static function checkFunctionLikeTypeMatches(StatementsAnalyzer $statements_analyzer, Codebase $codebase, ?string $cased_method_id, ?MethodIdentifier $method_id, ?string $self_fq_class_name, ?string $static_fq_class_name, CodeLocation $function_call_location, FunctionLikeParameter $function_param, bool $allow_named_args, Union $arg_value_type, int $argument_offset, int $unpacked_argument_offset, PhpParser\Node\Arg $arg, Context $context, ?array $class_generic_params, ?TemplateResult $template_result, bool $specialize_taint, bool $in_call_map) : ?bool
    {
        if (!$function_param->type) {
            if (!$codebase->infer_types_from_usage && !$statements_analyzer->data_flow_graph) {
                return null;
            }
            $param_type = Type::getMixed();
        } else {
            $param_type = $function_param->type;
        }
        $bindable_template_params = [];
        if ($template_result) {
            $bindable_template_params = $param_type->getTemplateTypes();
        }
        $parent_class = null;
        $classlike_storage = null;
        $static_classlike_storage = null;
        if ($self_fq_class_name) {
            $classlike_storage = $codebase->classlike_storage_provider->get($self_fq_class_name);
            $parent_class = $classlike_storage->parent_class;
            $static_classlike_storage = $classlike_storage;
            if ($static_fq_class_name && $static_fq_class_name !== $self_fq_class_name) {
                $static_classlike_storage = $codebase->classlike_storage_provider->get($static_fq_class_name);
            }
        }
        $param_type = TypeExpander::expandUnion($codebase, $param_type, $classlike_storage->name ?? null, $static_classlike_storage->name ?? null, $parent_class, \true, \false, $static_classlike_storage->final ?? \false, \true);
        if ($class_generic_params) {
            // here we're replacing the param types and arg types with the bound
            // class template params.
            //
            // For example, if we're operating on a class Foo with params TKey and TValue,
            // and we're calling a method "add(TKey $key, TValue $value)" on an instance
            // of that class where we know that TKey is int and TValue is string, then we
            // want to substitute the expected parameters so it's as if we were actually
            // calling "add(int $key, string $value)"
            $readonly_template_result = new TemplateResult($class_generic_params, []);
            // This flag ensures that the template results will never be written to
            // It also supercedes the `$add_lower_bounds` flag so that closure params
            // don’t get overwritten
            $readonly_template_result->readonly = \true;
            $param_type = TemplateStandinTypeReplacer::replace($param_type, $readonly_template_result, $codebase, $statements_analyzer, $arg_value_type, $argument_offset, $context->self, $context->calling_function_id ?: $context->calling_method_id);
            $arg_value_type = TemplateStandinTypeReplacer::replace($arg_value_type, $readonly_template_result, $codebase, $statements_analyzer, $arg_value_type, $argument_offset, $context->self, $context->calling_function_id ?: $context->calling_method_id);
        }
        if ($template_result && $template_result->template_types) {
            $arg_type_param = $arg_value_type;
            if ($arg->unpack) {
                $arg_type_param = null;
                foreach ($arg_value_type->getAtomicTypes() as $arg_atomic_type) {
                    if ($arg_atomic_type instanceof TList) {
                        $arg_atomic_type = $arg_atomic_type->getKeyedArray();
                    }
                    if ($arg_atomic_type instanceof TArray || $arg_atomic_type instanceof TKeyedArray) {
                        if ($arg_atomic_type instanceof TKeyedArray) {
                            $arg_type_param = $arg_atomic_type->getGenericValueType();
                        } else {
                            $arg_type_param = $arg_atomic_type->type_params[1];
                        }
                    } elseif ($arg_atomic_type instanceof TIterable) {
                        $arg_type_param = $arg_atomic_type->type_params[1];
                    } elseif ($arg_atomic_type instanceof TNamedObject) {
                        ForeachAnalyzer::getKeyValueParamsForTraversableObject($arg_atomic_type, $codebase, $key_type, $arg_type_param);
                    }
                }
                if (!$arg_type_param) {
                    $arg_type_param = new Union([new TMixed()], ['parent_nodes' => $arg_value_type->parent_nodes]);
                }
            }
            $param_type = TemplateStandinTypeReplacer::replace($param_type, $template_result, $codebase, $statements_analyzer, $arg_type_param, $argument_offset, !$statements_analyzer->isStatic() && (!$method_id || $method_id->method_name !== '__construct') ? $context->self : null, $context->calling_method_id ?: $context->calling_function_id);
            foreach ($bindable_template_params as $template_type) {
                if (!isset($template_result->lower_bounds[$template_type->param_name][$template_type->defining_class])) {
                    if (isset($template_result->upper_bounds[$template_type->param_name][$template_type->defining_class])) {
                        $template_result->lower_bounds[$template_type->param_name][$template_type->defining_class] = [new TemplateBound($template_result->upper_bounds[$template_type->param_name][$template_type->defining_class]->type)];
                    } else {
                        $template_result->lower_bounds[$template_type->param_name][$template_type->defining_class] = [new TemplateBound($template_type->as)];
                    }
                }
            }
            $param_type = TypeExpander::expandUnion($codebase, $param_type, $classlike_storage->name ?? null, $static_classlike_storage->name ?? null, $parent_class, \true, \false, $static_classlike_storage->final ?? \false, \true);
        }
        $fleshed_out_signature_type = $function_param->signature_type ? TypeExpander::expandUnion($codebase, $function_param->signature_type, $classlike_storage->name ?? null, $static_classlike_storage->name ?? null, $parent_class) : null;
        $unpacked_atomic_array = null;
        if ($arg->unpack) {
            if ($arg_value_type->hasMixed()) {
                if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                    $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
                }
                IssueBuffer::maybeAdd(new MixedArgument('Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' cannot unpack ' . $arg_value_type->getId() . ', expecting iterable', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                if ($cased_method_id) {
                    $arg_location = new CodeLocation($statements_analyzer->getSource(), $arg->value);
                    self::processTaintedness($statements_analyzer, $cased_method_id, $method_id, $argument_offset, $arg_location, $function_call_location, $function_param, $arg_value_type, $arg->value, $context, $specialize_taint);
                }
                return null;
            }
            if ($arg_value_type->hasArray()) {
                $unpacked_atomic_array = $arg_value_type->getArray();
                $arg_key_allowed = \true;
                if ($unpacked_atomic_array instanceof TKeyedArray) {
                    if (!$allow_named_args && !$unpacked_atomic_array->getGenericKeyType()->isInt()) {
                        $arg_key_allowed = \false;
                    }
                    if ($function_param->is_variadic) {
                        $arg_value_type = $unpacked_atomic_array->getGenericValueType();
                    } elseif ($codebase->analysis_php_version_id >= 80000 && $allow_named_args && isset($unpacked_atomic_array->properties[$function_param->name])) {
                        $arg_value_type = $unpacked_atomic_array->properties[$function_param->name];
                    } elseif ($unpacked_atomic_array->is_list && isset($unpacked_atomic_array->properties[$unpacked_argument_offset])) {
                        $arg_value_type = $unpacked_atomic_array->properties[$unpacked_argument_offset];
                    } elseif ($unpacked_atomic_array->fallback_params) {
                        $arg_value_type = $unpacked_atomic_array->fallback_params[1];
                    } elseif ($function_param->is_optional && $function_param->default_type) {
                        if ($function_param->default_type instanceof Union) {
                            $arg_value_type = $function_param->default_type;
                        } else {
                            $arg_value_type_atomic = ConstantTypeResolver::resolve($codebase->classlikes, $function_param->default_type, $statements_analyzer);
                            $arg_value_type = new Union([$arg_value_type_atomic]);
                        }
                    } else {
                        $arg_value_type = Type::getMixed();
                    }
                } elseif ($unpacked_atomic_array instanceof TClassStringMap) {
                    $arg_value_type = Type::getMixed();
                } else {
                    if (!$allow_named_args && !$unpacked_atomic_array->type_params[0]->isInt()) {
                        $arg_key_allowed = \false;
                    }
                    $arg_value_type = $unpacked_atomic_array->type_params[1];
                }
                if (!$arg_key_allowed) {
                    IssueBuffer::maybeAdd(new NamedArgumentNotAllowed('Method ' . $cased_method_id . ' called with named unpacked array ' . $unpacked_atomic_array->getId() . ' (array with string keys)', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                }
            } else {
                $non_iterable = \false;
                $invalid_key = \false;
                $invalid_string_key = \false;
                $possibly_matches = \false;
                foreach ($arg_value_type->getAtomicTypes() as $atomic_type) {
                    if (!$atomic_type->isIterable($codebase)) {
                        $non_iterable = \true;
                    } else {
                        $key_type = $codebase->getKeyValueParamsForTraversableObject($atomic_type)[0];
                        if (!UnionTypeComparator::isContainedBy($codebase, $key_type, Type::getArrayKey())) {
                            $invalid_key = \true;
                            continue;
                        }
                        if (($codebase->analysis_php_version_id < 80000 || !$allow_named_args) && !$key_type->isInt()) {
                            $invalid_string_key = \true;
                            continue;
                        }
                        $possibly_matches = \true;
                    }
                }
                $issue_type = $possibly_matches ? PossiblyInvalidArgument::class : InvalidArgument::class;
                if ($non_iterable) {
                    IssueBuffer::maybeAdd(new $issue_type('Tried to unpack non-iterable ' . $arg_value_type->getId(), new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                }
                if ($invalid_key) {
                    IssueBuffer::maybeAdd(new $issue_type('Method ' . $cased_method_id . ' called with unpacked iterable ' . $arg_value_type->getId() . ' with invalid key (must be ' . ($codebase->analysis_php_version_id < 80000 ? 'int' : 'int|string') . ')', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                }
                if ($invalid_string_key) {
                    if ($codebase->analysis_php_version_id < 80000) {
                        IssueBuffer::maybeAdd(new $issue_type('String keys not supported in unpacked arguments', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                    } else {
                        IssueBuffer::maybeAdd(new NamedArgumentNotAllowed('Method ' . $cased_method_id . ' called with named unpacked iterable ' . $arg_value_type->getId() . ' (iterable with string keys)', new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
                    }
                }
                return null;
            }
        } else {
            if (!$allow_named_args && $arg->name !== null) {
                IssueBuffer::maybeAdd(new NamedArgumentNotAllowed('Method ' . $cased_method_id . ' called with named argument ' . $arg->name->name, new CodeLocation($statements_analyzer->getSource(), $arg->value), $cased_method_id), $statements_analyzer->getSuppressedIssues());
            }
        }
        // bypass verifying argument types when collecting initialisations,
        // because the argument locations are not reliable (file names normally differ)
        // See https://github.com/vimeo/psalm/issues/5662
        if ($arg instanceof VirtualArg && $context->collect_initializations) {
            return null;
        }
        if (self::verifyType($statements_analyzer, $arg_value_type, $param_type, $fleshed_out_signature_type, $cased_method_id, $method_id, $argument_offset, new CodeLocation($statements_analyzer->getSource(), $arg->value), $arg->value, $context, $function_param, $arg->unpack, $unpacked_atomic_array, $specialize_taint, $in_call_map, $function_call_location) === \false) {
            return \false;
        }
        return null;
    }
    /**
     * @param TKeyedArray|TArray|TClassStringMap|null $unpacked_atomic_array
     * @return  null|false
     */
    public static function verifyType(StatementsAnalyzer $statements_analyzer, Union $input_type, Union $param_type, ?Union $signature_param_type, ?string $cased_method_id, ?MethodIdentifier $method_id, int $argument_offset, CodeLocation $arg_location, PhpParser\Node\Expr $input_expr, Context $context, FunctionLikeParameter $function_param, bool $unpack, ?Atomic $unpacked_atomic_array, bool $specialize_taint, bool $in_call_map, CodeLocation $function_call_location) : ?bool
    {
        $codebase = $statements_analyzer->getCodebase();
        if ($param_type->hasMixed()) {
            if ($codebase->infer_types_from_usage && !$input_type->hasMixed() && !$param_type->from_docblock && !$param_type->had_template && $method_id && strpos($method_id->method_name, '__') !== 0) {
                $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
                if ($declaring_method_id) {
                    $id_lc = strtolower((string) $declaring_method_id);
                    $codebase->analyzer->possible_method_param_types[$id_lc][$argument_offset] = Type::combineUnionTypes($codebase->analyzer->possible_method_param_types[$id_lc][$argument_offset] ?? null, $input_type, $codebase);
                }
            }
            if ($cased_method_id) {
                self::processTaintedness($statements_analyzer, $cased_method_id, $method_id, $argument_offset, $arg_location, $function_call_location, $function_param, $input_type, $input_expr, $context, $specialize_taint);
            }
            return null;
        }
        $method_identifier = $cased_method_id ? ' of ' . $cased_method_id : '';
        if ($input_type->hasMixed()) {
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
            }
            $origin_locations = [];
            if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                foreach ($input_type->parent_nodes as $parent_node) {
                    $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                }
            }
            $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
            if ($origin_location && $origin_location->getHash() === $arg_location->getHash()) {
                $origin_location = null;
            }
            IssueBuffer::maybeAdd(new MixedArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be ' . $input_type->getId() . ', expecting ' . $param_type, $arg_location, $cased_method_id, $origin_location), $statements_analyzer->getSuppressedIssues());
            if ($input_type->isMixed()) {
                if (!$function_param->by_ref && !($function_param->is_variadic xor $unpack) && $cased_method_id !== 'echo' && $cased_method_id !== 'print' && (!$in_call_map || $context->strict_types)) {
                    self::coerceValueAfterGatekeeperArgument($statements_analyzer, $input_type, \false, $input_expr, $param_type, $signature_param_type, $context, $unpack, $unpacked_atomic_array);
                }
            }
            if ($cased_method_id) {
                self::processTaintedness($statements_analyzer, $cased_method_id, $method_id, $argument_offset, $arg_location, $function_call_location, $function_param, $input_type, $input_expr, $context, $specialize_taint);
            }
            if ($input_type->isMixed()) {
                return null;
            }
        }
        if ($input_type->isNever()) {
            IssueBuffer::maybeAdd(new NoValue('All possible types for this argument were invalidated - This may be dead code', $arg_location), $statements_analyzer->getSuppressedIssues());
            return null;
        }
        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
            $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
        }
        if ($function_param->by_ref || $function_param->is_optional) {
            //if the param is optional or a ref, we'll allow the input to be possibly_undefined
            $param_type = $param_type->setPossiblyUndefined(\true);
        }
        if ($param_type->hasCallableType() && $param_type->isSingle()) {
            // we do this replacement early because later we don't have access to the
            // $statements_analyzer, which is necessary to understand string function names
            $input_type = $input_type->getBuilder();
            foreach ($input_type->getAtomicTypes() as $key => $atomic_type) {
                if (!$atomic_type instanceof TLiteralString || InternalCallMapHandler::inCallMap($atomic_type->value)) {
                    continue;
                }
                $candidate_callable = CallableTypeComparator::getCallableFromAtomic($codebase, $atomic_type, null, $statements_analyzer, \true);
                if ($candidate_callable) {
                    $input_type->removeType($key);
                    $input_type->addType($candidate_callable);
                }
            }
            $input_type = $input_type->freeze();
        }
        $union_comparison_results = new TypeComparisonResult();
        $type_match_found = UnionTypeComparator::isContainedBy($codebase, $input_type, $param_type, \true, \true, $union_comparison_results);
        $replace_input_type = \false;
        if ($union_comparison_results->replacement_union_type) {
            $replace_input_type = \true;
            $input_type = $union_comparison_results->replacement_union_type;
        }
        if ($cased_method_id) {
            self::processTaintedness($statements_analyzer, $cased_method_id, $method_id, $argument_offset, $arg_location, $function_call_location, $function_param, $input_type, $input_expr, $context, $specialize_taint);
            if ($function_param->assert_untainted) {
                $input_type = $input_type->setParentNodes([]);
                $replace_input_type = \true;
            }
        }
        if ($type_match_found && $param_type->hasCallableType()) {
            $potential_method_ids = [];
            foreach ($input_type->getAtomicTypes() as $input_type_part) {
                if ($input_type_part instanceof TList) {
                    $input_type_part = $input_type_part->getKeyedArray();
                }
                if ($input_type_part instanceof TKeyedArray) {
                    $potential_method_id = CallableTypeComparator::getCallableMethodIdFromTKeyedArray($input_type_part, $codebase, $context->calling_method_id, $statements_analyzer->getFilePath());
                    if ($potential_method_id && $potential_method_id !== 'not-callable') {
                        $potential_method_ids[] = $potential_method_id;
                    }
                } elseif ($input_type_part instanceof TLiteralString && strpos($input_type_part->value, '::')) {
                    $parts = explode('::', $input_type_part->value);
                    $potential_method_ids[] = new MethodIdentifier($parts[0], strtolower($parts[1]));
                }
            }
            foreach ($potential_method_ids as $potential_method_id) {
                $codebase->methods->methodExists($potential_method_id, $context->calling_method_id, null, $statements_analyzer, $statements_analyzer->getFilePath(), \true, $context->insideUse());
            }
        }
        if ($context->strict_types && !$input_type->hasArray() && !$param_type->from_docblock && $cased_method_id !== 'echo' && $cased_method_id !== 'print' && $cased_method_id !== 'sprintf') {
            $union_comparison_results->scalar_type_match_found = \false;
            if ($union_comparison_results->to_string_cast) {
                $union_comparison_results->to_string_cast = \false;
                $type_match_found = \false;
            }
        }
        if ($union_comparison_results->type_coerced && !$input_type->hasMixed()) {
            if ($union_comparison_results->type_coerced_from_mixed) {
                $origin_locations = [];
                if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                    foreach ($input_type->parent_nodes as $parent_node) {
                        $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                    }
                }
                $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
                if ($origin_location && $origin_location->getHash() === $arg_location->getHash()) {
                    $origin_location = null;
                }
                IssueBuffer::maybeAdd(new MixedArgumentTypeCoercion('Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', but parent type ' . $input_type->getId() . ' provided', $arg_location, $cased_method_id, $origin_location), $statements_analyzer->getSuppressedIssues());
            } elseif ($cased_method_id !== 'echo' && $cased_method_id !== 'print') {
                IssueBuffer::maybeAdd(new ArgumentTypeCoercion('Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', but parent type ' . $input_type->getId() . ' provided', $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
            }
        }
        if ($union_comparison_results->to_string_cast && $cased_method_id !== 'echo' && $cased_method_id !== 'print') {
            IssueBuffer::maybeAdd(new ImplicitToStringCast('Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', but ' . $input_type->getId() . ' provided with a __toString method', $arg_location), $statements_analyzer->getSuppressedIssues());
        }
        if (!$type_match_found && !$union_comparison_results->type_coerced) {
            $types_can_be_identical = UnionTypeComparator::canBeContainedBy($codebase, $input_type, $param_type, \true, \true);
            $type = ($input_type->possibly_undefined ? 'possibly undefined ' : '') . $input_type->getId();
            if ($union_comparison_results->scalar_type_match_found) {
                if ($cased_method_id !== 'echo' && $cased_method_id !== 'print') {
                    IssueBuffer::maybeAdd(new InvalidScalarArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', but ' . $type . ' provided', $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
                }
            } elseif ($types_can_be_identical) {
                IssueBuffer::maybeAdd(new PossiblyInvalidArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', but possibly different type ' . $type . ' provided', $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new InvalidArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' expects ' . $param_type->getId() . ', but ' . $type . ($union_comparison_results->missing_shape_fields ? ' with additional array shape fields (' . implode(', ', $union_comparison_results->missing_shape_fields) . ') was' : '') . ' provided', $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
            }
            return null;
        }
        if ($input_expr instanceof PhpParser\Node\Scalar\String_ || $input_expr instanceof PhpParser\Node\Expr\Array_ || $input_expr instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
            self::verifyExplicitParam($statements_analyzer, $param_type, $arg_location, $input_expr, $context);
            return null;
        }
        if (!$param_type->isNullable() && $cased_method_id !== 'echo' && $cased_method_id !== 'print') {
            if ($input_type->isNull()) {
                IssueBuffer::maybeAdd(new NullArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be null, ' . 'null value provided to parameter with type ' . $param_type->getId(), $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
                return null;
            }
            if ($input_type->isNullable() && !$input_type->ignore_nullable_issues) {
                IssueBuffer::maybeAdd(new PossiblyNullArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be null, possibly ' . 'null value provided', $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
            }
        }
        if (!$param_type->isFalsable() && !$param_type->hasBool() && !$param_type->hasScalar() && $cased_method_id !== 'echo' && $cased_method_id !== 'print') {
            if ($input_type->isFalse()) {
                IssueBuffer::maybeAdd(new InvalidArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be false, ' . $param_type->getId() . ' value expected', $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
                return null;
            }
            if ($input_type->isFalsable() && !$input_type->ignore_falsable_issues) {
                IssueBuffer::maybeAdd(new PossiblyFalseArgument('Argument ' . ($argument_offset + 1) . $method_identifier . ' cannot be false, possibly ' . $param_type->getId() . ' value expected', $arg_location, $cased_method_id), $statements_analyzer->getSuppressedIssues());
            }
        }
        if (($type_match_found || $input_type->hasMixed()) && !$function_param->by_ref && !($function_param->is_variadic xor $unpack) && $cased_method_id !== 'echo' && $cased_method_id !== 'print' && (!$in_call_map || $context->strict_types)) {
            self::coerceValueAfterGatekeeperArgument($statements_analyzer, $input_type, $replace_input_type, $input_expr, $param_type, $signature_param_type, $context, $unpack, $unpacked_atomic_array);
        }
        return null;
    }
    /**
     * @param PhpParser\Node\Scalar\String_|PhpParser\Node\Expr\Array_|PhpParser\Node\Expr\BinaryOp\Concat $input_expr
     */
    private static function verifyExplicitParam(StatementsAnalyzer $statements_analyzer, Union $param_type, CodeLocation $arg_location, PhpParser\Node\Expr $input_expr, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        foreach ($param_type->getAtomicTypes() as $param_type_part) {
            if ($param_type_part instanceof TClassString && $input_expr instanceof PhpParser\Node\Scalar\String_ && $param_type->isSingle()) {
                if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $input_expr->value, $arg_location, $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true)) === \false) {
                    return;
                }
            } elseif ($param_type_part instanceof TArray && $input_expr instanceof PhpParser\Node\Expr\Array_) {
                foreach ($param_type_part->type_params[1]->getAtomicTypes() as $param_array_type_part) {
                    if ($param_array_type_part instanceof TClassString) {
                        foreach ($input_expr->items as $item) {
                            if ($item && $item->value instanceof PhpParser\Node\Scalar\String_) {
                                if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $item->value->value, $arg_location, $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true)) === \false) {
                                    return;
                                }
                            }
                        }
                    }
                }
            } elseif ($param_type_part instanceof TCallable) {
                $can_be_callable_like_array = \false;
                if ($param_type->hasArray()) {
                    $param_array_type = $param_type->getArray();
                    $row_type = null;
                    if ($param_array_type instanceof TArray) {
                        $row_type = $param_array_type->type_params[1];
                    } elseif ($param_array_type instanceof TKeyedArray) {
                        $row_type = $param_array_type->getGenericValueType();
                    }
                    if ($row_type && ($row_type->hasMixed() || $row_type->hasString())) {
                        $can_be_callable_like_array = \true;
                    }
                }
                if (!$can_be_callable_like_array) {
                    $function_ids = CallAnalyzer::getFunctionIdsFromCallableArg($statements_analyzer, $input_expr);
                    foreach ($function_ids as $function_id) {
                        if (strpos($function_id, '::') !== \false) {
                            if ($function_id[0] === '$') {
                                $function_id = substr($function_id, 1);
                            }
                            $function_id_parts = explode('&', $function_id);
                            $non_existent_method_ids = [];
                            foreach ($function_id_parts as $function_id_part) {
                                [$callable_fq_class_name, $method_name] = explode('::', $function_id_part);
                                switch ($callable_fq_class_name) {
                                    case 'self':
                                    case 'static':
                                    case 'parent':
                                        $container_class = $statements_analyzer->getFQCLN();
                                        if ($callable_fq_class_name === 'parent') {
                                            $container_class = $statements_analyzer->getParentFQCLN();
                                        }
                                        if (!$container_class) {
                                            continue 2;
                                        }
                                        $callable_fq_class_name = $container_class;
                                }
                                if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $callable_fq_class_name, $arg_location, $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true)) === \false) {
                                    return;
                                }
                                $function_id_part = new MethodIdentifier($callable_fq_class_name, strtolower($method_name));
                                $call_method_id = new MethodIdentifier($callable_fq_class_name, '__call');
                                if (!$codebase->classOrInterfaceOrEnumExists($callable_fq_class_name)) {
                                    return;
                                }
                                if (!$codebase->methods->methodExists($function_id_part) && !$codebase->methods->methodExists($call_method_id)) {
                                    $non_existent_method_ids[] = $function_id_part;
                                }
                            }
                            if ($non_existent_method_ids && !$param_type->hasString() && !$param_type->hasArray()) {
                                if (MethodAnalyzer::checkMethodExists($codebase, $non_existent_method_ids[0], $arg_location, $statements_analyzer->getSuppressedIssues()) === \false) {
                                    return;
                                }
                            }
                        } else {
                            if (!$param_type->hasString() && !$param_type->hasArray() && CallAnalyzer::checkFunctionExists($statements_analyzer, $function_id, $arg_location, \false) === \false) {
                                return;
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * @param TKeyedArray|TArray|TClassStringMap $unpacked_atomic_array
     */
    private static function coerceValueAfterGatekeeperArgument(StatementsAnalyzer $statements_analyzer, Union $input_type, bool $input_type_changed, PhpParser\Node\Expr $input_expr, Union $param_type, ?Union $signature_param_type, Context $context, bool $unpack, ?Atomic $unpacked_atomic_array) : void
    {
        if ($param_type->hasMixed()) {
            return;
        }
        if (!$input_type_changed && $param_type->from_docblock && !$input_type->hasMixed()) {
            $types = $input_type->getAtomicTypes();
            foreach ($param_type->getAtomicTypes() as $param_atomic_type) {
                if ($param_atomic_type instanceof TGenericObject) {
                    foreach ($types as &$input_atomic_type) {
                        if ($input_atomic_type instanceof TGenericObject && $input_atomic_type->value === $param_atomic_type->value) {
                            $new_type_params = [];
                            foreach ($input_atomic_type->type_params as $i => $type_param) {
                                if ($type_param->isNever() && isset($param_atomic_type->type_params[$i])) {
                                    $input_type_changed = \true;
                                    $new_type_params[$i] = $param_atomic_type->type_params[$i];
                                }
                            }
                            if ($new_type_params) {
                                $input_atomic_type = new TGenericObject($input_atomic_type->value, [...$input_atomic_type->type_params, ...$new_type_params], $input_atomic_type->remapped_params, \false, $input_atomic_type->extra_types);
                            }
                        }
                    }
                    unset($input_atomic_type);
                }
            }
            if (!$input_type_changed) {
                return;
            }
            $input_type = new Union($types);
        }
        $var_id = ExpressionIdentifier::getVarId($input_expr, $statements_analyzer->getFQCLN(), $statements_analyzer);
        if ($var_id) {
            $was_cloned = \false;
            if ($input_type->isNullable() && !$param_type->isNullable()) {
                $input_type = $input_type->getBuilder();
                $was_cloned = \true;
                $input_type->removeType('null');
                $input_type = $input_type->freeze();
            }
            if ($input_type->getId() === $param_type->getId()) {
                if ($input_type->from_docblock) {
                    $input_type = $input_type->setFromDocblock(\false);
                }
            } elseif ($input_type->hasMixed() && $signature_param_type) {
                $was_cloned = \true;
                $parent_nodes = $input_type->parent_nodes;
                $by_ref = $input_type->by_ref;
                $input_type = $signature_param_type->setProperties(['ignore_nullable_issues' => $signature_param_type->isNullable(), 'parent_nodes' => $parent_nodes, 'by_ref' => $by_ref]);
            }
            if ($context->inside_conditional && !isset($context->assigned_var_ids[$var_id])) {
                $context->assigned_var_ids[$var_id] = 0;
            }
            if ($was_cloned) {
                $context->removeVarFromConflictingClauses($var_id, null, $statements_analyzer);
            }
            if ($unpack) {
                if ($unpacked_atomic_array instanceof TArray) {
                    $unpacked_atomic_array = $unpacked_atomic_array->setTypeParams([$unpacked_atomic_array->type_params[0], $input_type]);
                    $context->vars_in_scope[$var_id] = new Union([$unpacked_atomic_array]);
                } elseif ($unpacked_atomic_array instanceof TKeyedArray && $unpacked_atomic_array->is_list) {
                    if ($unpacked_atomic_array->isNonEmpty()) {
                        $unpacked_atomic_array = Type::getNonEmptyListAtomic($input_type);
                    } else {
                        $unpacked_atomic_array = Type::getListAtomic($input_type);
                    }
                    $context->vars_in_scope[$var_id] = new Union([$unpacked_atomic_array]);
                } else {
                    $context->vars_in_scope[$var_id] = new Union([new TArray([Type::getInt(), $input_type])]);
                }
            } else {
                $context->vars_in_scope[$var_id] = $input_type;
            }
        }
    }
    private static function processTaintedness(StatementsAnalyzer $statements_analyzer, string $cased_method_id, ?MethodIdentifier $method_id, int $argument_offset, CodeLocation $arg_location, CodeLocation $function_call_location, FunctionLikeParameter $function_param, Union $input_type, PhpParser\Node\Expr $expr, Context $context, bool $specialize_taint) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        if (!$statements_analyzer->data_flow_graph || $statements_analyzer->data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
            return;
        }
        // literal data can’t be tainted
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $input_type->isSingle() && $input_type->hasLiteralValue()) {
            return;
        }
        // numeric types can't be tainted, neither can bool
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $input_type->isSingle() && ($input_type->isInt() || $input_type->isFloat() || $input_type->isBool())) {
            return;
        }
        $event = new AddRemoveTaintsEvent($expr, $context, $statements_analyzer, $codebase);
        $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
        $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
        if ($function_param->type && $function_param->type->isString() && !$input_type->isString()) {
            $input_type = CastAnalyzer::castStringAttempt($statements_analyzer, $context, $input_type, $expr, \false);
        }
        if ($specialize_taint) {
            $method_node = DataFlowNode::getForMethodArgument($cased_method_id, $cased_method_id, $argument_offset, $statements_analyzer->data_flow_graph instanceof TaintFlowGraph ? $function_param->location : null, $function_call_location);
        } else {
            $method_node = DataFlowNode::getForMethodArgument($cased_method_id, $cased_method_id, $argument_offset, $statements_analyzer->data_flow_graph instanceof TaintFlowGraph ? $function_param->location : null);
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $method_id && $method_id->method_name !== '__construct') {
                $fq_classlike_name = $method_id->fq_class_name;
                $method_name = $method_id->method_name;
                $cased_method_name = explode('::', $cased_method_id)[1];
                $class_storage = $codebase->classlike_storage_provider->get($fq_classlike_name);
                foreach ($class_storage->dependent_classlikes as $dependent_classlike_lc => $_) {
                    $dependent_classlike_storage = $codebase->classlike_storage_provider->get($dependent_classlike_lc);
                    $new_sink = DataFlowNode::getForMethodArgument($dependent_classlike_lc . '::' . $method_name, $dependent_classlike_storage->name . '::' . $cased_method_name, $argument_offset, $arg_location, null);
                    $statements_analyzer->data_flow_graph->addNode($new_sink);
                    $statements_analyzer->data_flow_graph->addPath($method_node, $new_sink, 'arg', $added_taints, $removed_taints);
                }
            }
        }
        if ($method_id && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
            if ($declaring_method_id && (string) $declaring_method_id !== (string) $method_id) {
                $new_sink = DataFlowNode::getForMethodArgument((string) $declaring_method_id, $codebase->methods->getCasedMethodId($declaring_method_id), $argument_offset, $arg_location, null);
                $statements_analyzer->data_flow_graph->addNode($new_sink);
                $statements_analyzer->data_flow_graph->addPath($method_node, $new_sink, 'arg', $added_taints, $removed_taints);
            }
        }
        $statements_analyzer->data_flow_graph->addNode($method_node);
        $argument_value_node = DataFlowNode::getForAssignment('call to ' . $cased_method_id, $arg_location);
        $statements_analyzer->data_flow_graph->addNode($argument_value_node);
        $statements_analyzer->data_flow_graph->addPath($argument_value_node, $method_node, 'arg', $added_taints, $removed_taints);
        foreach ($input_type->parent_nodes as $parent_node) {
            $statements_analyzer->data_flow_graph->addNode($method_node);
            $statements_analyzer->data_flow_graph->addPath($parent_node, $argument_value_node, 'arg', $added_taints, $removed_taints);
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\AlgebraAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\CallableTypeComparator;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Issue\DeprecatedFunction;
use Psalm\Issue\ImpureFunctionCall;
use Psalm\Issue\InvalidFunctionCall;
use Psalm\Issue\MixedFunctionCall;
use Psalm\Issue\NullFunctionCall;
use Psalm\Issue\PossiblyInvalidFunctionCall;
use Psalm\Issue\PossiblyNullFunctionCall;
use Psalm\Issue\UnusedFunctionCall;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualFuncCall;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualIdentifier;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Plugin\EventHandler\Event\AfterEveryFunctionCallAnalysisEvent;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionStorage;
use Psalm\Storage\Possibilities;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableObject;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Reconciler;
use Psalm\Type\TaintKind;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_map;
use function array_merge;
use function array_shift;
use function array_slice;
use function count;
use function explode;
use function implode;
use function in_array;
use function preg_replace;
use function reset;
use function spl_object_id;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class FunctionCallAnalyzer extends CallAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\FuncCall $stmt, Context $context, ?TemplateResult $template_result = null) : bool
    {
        $function_name = $stmt->name;
        $codebase = $statements_analyzer->getCodebase();
        $code_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
        $config = $codebase->config;
        $is_first_class_callable = $stmt->isFirstClassCallable();
        $real_stmt = $stmt;
        if ($function_name instanceof PhpParser\Node\Name && !$is_first_class_callable && isset($stmt->getArgs()[0]) && !$stmt->getArgs()[0]->unpack) {
            $original_function_id = implode('\\', $function_name->parts);
            if ($original_function_id === 'call_user_func') {
                $other_args = array_slice($stmt->getArgs(), 1);
                $function_name = $stmt->getArgs()[0]->value;
                $stmt = new VirtualFuncCall($function_name, $other_args, $stmt->getAttributes());
            }
            if ($original_function_id === 'call_user_func_array' && isset($stmt->getArgs()[1])) {
                $function_name = $stmt->getArgs()[0]->value;
                $stmt = new VirtualFuncCall($function_name, [new VirtualArg($stmt->getArgs()[1]->value, \false, \true)], $stmt->getAttributes());
            }
        }
        if ($function_name instanceof PhpParser\Node\Expr) {
            $function_call_info = self::getAnalyzeNamedExpression($statements_analyzer, $stmt, $real_stmt, $function_name, $context);
            if ($function_call_info->function_exists === \false) {
                return \true;
            }
            if ($function_call_info->new_function_name) {
                $function_name = $function_call_info->new_function_name;
            }
        } else {
            $function_call_info = self::handleNamedFunction($statements_analyzer, $stmt, $function_name, $context, $code_location);
            if (!$function_call_info->function_exists) {
                return \true;
            }
        }
        $set_inside_conditional = \false;
        if ($function_name instanceof PhpParser\Node\Name && $function_name->parts === ['assert'] && !$context->inside_conditional) {
            $context->inside_conditional = \true;
            $set_inside_conditional = \true;
        }
        if (!$template_result) {
            $template_result = new TemplateResult([], []);
        }
        if (!$is_first_class_callable) {
            if (isset($function_call_info->function_storage->template_types)) {
                $template_result->template_types += $function_call_info->function_storage->template_types ?: [];
            }
            \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), $function_call_info->function_params, $function_call_info->function_id, $function_call_info->allow_named_args, $context, $template_result);
        }
        if ($set_inside_conditional) {
            $context->inside_conditional = \false;
        }
        $function_callable = null;
        if (!$is_first_class_callable && $function_name instanceof PhpParser\Node\Name && $function_call_info->function_id) {
            if (!$function_call_info->is_stubbed && $function_call_info->in_call_map) {
                $function_callable = InternalCallMapHandler::getCallableFromCallMapById($codebase, $function_call_info->function_id, $stmt->getArgs(), $statements_analyzer->node_data);
                $function_call_info->function_params = $function_callable->params;
            }
        }
        $already_inferred_lower_bounds = $template_result->lower_bounds;
        $template_result = new TemplateResult([], []);
        // do this here to allow closure param checks
        if (!$is_first_class_callable && $function_call_info->function_params !== null) {
            \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::checkArgumentsMatch($statements_analyzer, $stmt->getArgs(), $function_call_info->function_id, $function_call_info->function_params, $function_call_info->function_storage, null, $template_result, $code_location, $context);
        }
        CallAnalyzer::checkTemplateResult($statements_analyzer, $template_result, $code_location, $function_call_info->function_id);
        $template_result->lower_bounds += $already_inferred_lower_bounds;
        if ($function_name instanceof PhpParser\Node\Name && $function_call_info->function_id) {
            $stmt_type = \Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallReturnTypeFetcher::fetch($statements_analyzer, $codebase, $stmt, $function_name, $function_call_info->function_id, $function_call_info->in_call_map, $function_call_info->is_stubbed, $function_call_info->function_storage, $function_callable, $template_result, $context);
            $statements_analyzer->node_data->setType($real_stmt, $stmt_type);
            if ($stmt_type->isNever()) {
                $context->has_returned = \true;
            }
            $event = new AfterEveryFunctionCallAnalysisEvent($stmt, $function_call_info->function_id, $context, $statements_analyzer->getSource(), $codebase);
            $config->eventDispatcher->dispatchAfterEveryFunctionCallAnalysis($event);
            if ($is_first_class_callable) {
                return \true;
            }
        }
        if ($is_first_class_callable) {
            $type_provider = $statements_analyzer->getNodeTypeProvider();
            $closure_types = [];
            if ($input_type = $type_provider->getType($function_name)) {
                foreach ($input_type->getAtomicTypes() as $atomic_type) {
                    $candidate_callable = CallableTypeComparator::getCallableFromAtomic($codebase, $atomic_type, null, $statements_analyzer);
                    if ($candidate_callable) {
                        $closure_types[] = new TClosure('Closure', $candidate_callable->params, $candidate_callable->return_type, $candidate_callable->is_pure);
                    }
                }
            }
            if ($closure_types) {
                $stmt_type = TypeCombiner::combine($closure_types, $codebase);
            } else {
                $stmt_type = Type::getClosure();
            }
            $statements_analyzer->node_data->setType($real_stmt, $stmt_type);
            return \true;
        }
        foreach ($function_call_info->defined_constants as $const_name => $const_type) {
            $context->constants[$const_name] = $const_type;
            $context->vars_in_scope[$const_name] = $const_type;
        }
        foreach ($function_call_info->global_variables as $var_id => $_) {
            $context->vars_in_scope[$var_id] = Type::getMixed();
            $context->vars_possibly_in_scope[$var_id] = \true;
        }
        if ($function_name instanceof PhpParser\Node\Name && $function_name->parts === ['assert'] && isset($stmt->getArgs()[0])) {
            self::processAssertFunctionEffects($statements_analyzer, $codebase, $stmt, $stmt->getArgs()[0], $context);
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations && ($stmt_type = $statements_analyzer->node_data->getType($real_stmt))) {
            $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt, $stmt_type->getId());
        }
        self::checkFunctionCallPurity($statements_analyzer, $codebase, $stmt, $function_name, $function_call_info, $context);
        if ($function_call_info->function_storage) {
            if ($function_call_info->function_storage->assertions && $function_name instanceof PhpParser\Node\Name) {
                self::applyAssertionsToContext($function_name, null, $function_call_info->function_storage->assertions, $stmt->getArgs(), $template_result, $context, $statements_analyzer);
            }
            if ($function_call_info->function_storage->if_true_assertions) {
                $statements_analyzer->node_data->setIfTrueAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, null, $codebase), $function_call_info->function_storage->if_true_assertions));
            }
            if ($function_call_info->function_storage->if_false_assertions) {
                $statements_analyzer->node_data->setIfFalseAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, null, $codebase), $function_call_info->function_storage->if_false_assertions));
            }
            if ($function_call_info->function_storage->deprecated && $function_call_info->function_id) {
                IssueBuffer::maybeAdd(new DeprecatedFunction('The function ' . $function_call_info->function_id . ' has been marked as deprecated', $code_location, $function_call_info->function_id), $statements_analyzer->getSuppressedIssues());
            }
        }
        if ($function_call_info->byref_uses) {
            foreach ($function_call_info->byref_uses as $byref_use_var => $_) {
                $context->vars_in_scope['$' . $byref_use_var] = Type::getMixed();
                $context->vars_possibly_in_scope['$' . $byref_use_var] = \true;
            }
        }
        if ($function_name instanceof PhpParser\Node\Name && $function_call_info->function_id) {
            \Psalm\Internal\Analyzer\Statements\Expression\Call\NamedFunctionCallHandler::handle($statements_analyzer, $codebase, $stmt, $real_stmt, $function_name, strtolower($function_call_info->function_id), $context);
        }
        if (!$statements_analyzer->node_data->getType($real_stmt)) {
            $statements_analyzer->node_data->setType($real_stmt, Type::getMixed());
        }
        return \true;
    }
    private static function handleNamedFunction(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node\Name $function_name, Context $context, CodeLocation $code_location) : \Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallInfo
    {
        $function_call_info = new \Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallInfo();
        $codebase = $statements_analyzer->getCodebase();
        $codebase_functions = $codebase->functions;
        $original_function_id = implode('\\', $function_name->parts);
        if (!$function_name instanceof PhpParser\Node\Name\FullyQualified) {
            $function_call_info->function_id = $codebase_functions->getFullyQualifiedFunctionNameFromString($original_function_id, $statements_analyzer);
        } else {
            $function_call_info->function_id = $original_function_id;
        }
        $namespaced_function_exists = $codebase_functions->functionExists($statements_analyzer, strtolower($function_call_info->function_id));
        if (!$namespaced_function_exists && !$function_name instanceof PhpParser\Node\Name\FullyQualified) {
            $function_call_info->in_call_map = InternalCallMapHandler::inCallMap($original_function_id);
            $function_call_info->is_stubbed = $codebase_functions->hasStubbedFunction($original_function_id);
            if ($function_call_info->is_stubbed || $function_call_info->in_call_map) {
                $function_call_info->function_id = $original_function_id;
            }
        } else {
            $function_call_info->in_call_map = InternalCallMapHandler::inCallMap($function_call_info->function_id);
            $function_call_info->is_stubbed = $codebase_functions->hasStubbedFunction($function_call_info->function_id);
        }
        $function_call_info->function_exists = $function_call_info->is_stubbed || $function_call_info->in_call_map || $namespaced_function_exists;
        if ($function_call_info->function_exists && $codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentMapPopulator::recordArgumentPositions($statements_analyzer, $stmt, $codebase, $function_call_info->function_id);
        }
        $is_predefined = \true;
        $is_maybe_root_function = !$function_name instanceof PhpParser\Node\Name\FullyQualified && count($function_name->parts) === 1;
        $args = $stmt->isFirstClassCallable() ? [] : $stmt->getArgs();
        if (!$function_call_info->in_call_map) {
            $predefined_functions = $codebase->config->getPredefinedFunctions();
            $is_predefined = isset($predefined_functions[strtolower($original_function_id)]) || isset($predefined_functions[strtolower($function_call_info->function_id)]);
            if ($context->check_functions) {
                if (self::checkFunctionExists($statements_analyzer, $function_call_info->function_id, $code_location, $is_maybe_root_function) === \false) {
                    if ($args) {
                        \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $args, null, null, \true, $context);
                    }
                    return $function_call_info;
                }
                $function_call_info->function_exists = \true;
            }
        } else {
            $function_call_info->function_exists = \true;
        }
        $function_call_info->function_params = null;
        $function_call_info->defined_constants = [];
        $function_call_info->global_variables = [];
        $args = $stmt->isFirstClassCallable() ? [] : $stmt->getArgs();
        $dynamic_function_storage = null;
        if ($codebase->functions->dynamic_storage_provider->has($function_call_info->function_id)) {
            $dynamic_function_storage = $codebase->functions->dynamic_storage_provider->getFunctionStorage($stmt, $statements_analyzer, $function_call_info->function_id, $context, $code_location);
        }
        if ($function_call_info->function_exists) {
            if ($dynamic_function_storage) {
                $function_call_info->function_storage = $dynamic_function_storage;
                $function_call_info->function_params = $dynamic_function_storage->params;
                $function_call_info->allow_named_args = $dynamic_function_storage->allow_named_arg_calls;
                $function_call_info->defined_constants = $dynamic_function_storage->defined_constants;
                $function_call_info->global_variables = $dynamic_function_storage->global_variables;
            } elseif (!$function_call_info->in_call_map || $function_call_info->is_stubbed) {
                try {
                    $function_call_info->function_storage = $function_storage = $codebase_functions->getStorage($statements_analyzer, strtolower($function_call_info->function_id));
                    $function_call_info->function_params = $function_call_info->function_storage->params;
                    if (!$function_storage->allow_named_arg_calls) {
                        $function_call_info->allow_named_args = \false;
                    }
                    if (!$is_predefined) {
                        $function_call_info->defined_constants = $function_storage->defined_constants;
                        $function_call_info->global_variables = $function_storage->global_variables;
                    }
                } catch (UnexpectedValueException $e) {
                    $function_call_info->function_params = [new FunctionLikeParameter('args', \false, null, null, null, null, \false, \false, \true)];
                }
            } else {
                $function_callable = InternalCallMapHandler::getCallableFromCallMapById($codebase, $function_call_info->function_id, $args, $statements_analyzer->node_data);
                $function_call_info->function_params = $function_callable->params;
            }
            if ($codebase->functions->params_provider->has($function_call_info->function_id)) {
                $function_call_info->function_params = $codebase->functions->params_provider->getFunctionParams($statements_analyzer, $function_call_info->function_id, $args, $context, $code_location);
            }
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $function_name, $function_call_info->function_id . '()');
            }
        }
        return $function_call_info;
    }
    private static function getAnalyzeNamedExpression(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node\Expr\FuncCall $real_stmt, PhpParser\Node\Expr $function_name, Context $context) : \Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallInfo
    {
        $function_call_info = new \Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallInfo();
        $codebase = $statements_analyzer->getCodebase();
        $was_in_call = $context->inside_call;
        $context->inside_call = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $function_name, $context) === \false) {
            $context->inside_call = $was_in_call;
            return $function_call_info;
        }
        $context->inside_call = $was_in_call;
        $function_call_info->byref_uses = [];
        if ($stmt_name_type = $statements_analyzer->node_data->getType($function_name)) {
            if ($stmt_name_type->isNull()) {
                IssueBuffer::maybeAdd(new NullFunctionCall('Cannot call function on null value', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                return $function_call_info;
            }
            if ($stmt_name_type->isNullable()) {
                IssueBuffer::maybeAdd(new PossiblyNullFunctionCall('Cannot call function on possibly null value', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            $invalid_function_call_types = [];
            $has_valid_function_call_type = \false;
            $var_atomic_types = $stmt_name_type->getAtomicTypes();
            while ($var_atomic_types) {
                $var_type_part = array_shift($var_atomic_types);
                if ($var_type_part instanceof TTemplateParam) {
                    $var_atomic_types = array_merge($var_atomic_types, $var_type_part->as->getAtomicTypes());
                    continue;
                }
                if ($var_type_part instanceof TList) {
                    $var_type_part = $var_type_part->getKeyedArray();
                }
                if ($var_type_part instanceof TClosure || $var_type_part instanceof TCallable) {
                    if (!$var_type_part->is_pure) {
                        if ($context->pure || $context->mutation_free) {
                            IssueBuffer::maybeAdd(new ImpureFunctionCall('Cannot call an impure function from a mutation-free context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                        }
                        if (!$function_call_info->function_storage) {
                            $function_call_info->function_storage = new FunctionStorage();
                        }
                        $function_call_info->function_storage->pure = \false;
                        $function_call_info->function_storage->mutation_free = \false;
                    }
                    $function_call_info->function_params = $var_type_part->params;
                    if (($stmt_type = $statements_analyzer->node_data->getType($real_stmt)) && $var_type_part->return_type) {
                        $statements_analyzer->node_data->setType($real_stmt, Type::combineUnionTypes($stmt_type, $var_type_part->return_type));
                    } else {
                        $statements_analyzer->node_data->setType($real_stmt, $var_type_part->return_type ?? Type::getMixed());
                    }
                    if ($var_type_part instanceof TClosure) {
                        $function_call_info->byref_uses += $var_type_part->byref_uses;
                    }
                    $function_call_info->function_exists = \true;
                    $has_valid_function_call_type = \true;
                } elseif ($var_type_part instanceof TMixed) {
                    $has_valid_function_call_type = \true;
                    IssueBuffer::maybeAdd(new MixedFunctionCall('Cannot call function on ' . $var_type_part->getId(), new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } elseif ($var_type_part instanceof TCallableObject || $var_type_part instanceof TCallableString || $var_type_part instanceof TNamedObject && $var_type_part->value === 'Closure' || $var_type_part instanceof TObjectWithProperties && isset($var_type_part->methods['__invoke'])) {
                    // this is fine
                    $has_valid_function_call_type = \true;
                } elseif ($var_type_part instanceof TString || $var_type_part instanceof TArray || $var_type_part instanceof TKeyedArray && count($var_type_part->properties) === 2) {
                    $potential_method_id = null;
                    if ($var_type_part instanceof TKeyedArray) {
                        $potential_method_id = CallableTypeComparator::getCallableMethodIdFromTKeyedArray($var_type_part, $codebase, $context->calling_method_id, $statements_analyzer->getFilePath());
                        if ($potential_method_id === 'not-callable') {
                            $potential_method_id = null;
                        }
                    } elseif ($var_type_part instanceof TLiteralString) {
                        if (!$var_type_part->value) {
                            $invalid_function_call_types[] = '\'\'';
                            continue;
                        }
                        if (strpos($var_type_part->value, '::')) {
                            $parts = explode('::', strtolower($var_type_part->value));
                            $fq_class_name = $parts[0];
                            $fq_class_name = preg_replace('/^\\\\/', '', $fq_class_name, 1);
                            $potential_method_id = new MethodIdentifier($fq_class_name, $parts[1]);
                        } else {
                            $function_call_info->new_function_name = new VirtualFullyQualified($var_type_part->value, $function_name->getAttributes());
                        }
                    }
                    if ($potential_method_id) {
                        $codebase->methods->methodExists($potential_method_id, $context->calling_method_id, null, $statements_analyzer, $statements_analyzer->getFilePath());
                    }
                    // this is also kind of fine
                    $has_valid_function_call_type = \true;
                } elseif ($var_type_part instanceof TNull) {
                    // handled above
                } elseif (!$var_type_part instanceof TNamedObject || !$codebase->classlikes->classOrInterfaceExists($var_type_part->value) || !$codebase->methods->methodExists(new MethodIdentifier($var_type_part->value, '__invoke'))) {
                    $invalid_function_call_types[] = (string) $var_type_part;
                } else {
                    self::analyzeInvokeCall($statements_analyzer, $stmt, $real_stmt, $function_name, $context, $var_type_part);
                }
            }
            if ($invalid_function_call_types) {
                $var_type_part = reset($invalid_function_call_types);
                if ($has_valid_function_call_type) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidFunctionCall('Cannot treat type ' . $var_type_part . ' as callable', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new InvalidFunctionCall('Cannot treat type ' . $var_type_part . ' as callable', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                return $function_call_info;
            }
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $stmt_name_type->parent_nodes && !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                $arg_location = new CodeLocation($statements_analyzer->getSource(), $function_name);
                $custom_call_sink = TaintSink::getForMethodArgument('variable-call', 'variable-call', 0, $arg_location, $arg_location);
                $custom_call_sink->taints = [TaintKind::INPUT_CALLABLE];
                $statements_analyzer->data_flow_graph->addSink($custom_call_sink);
                $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
                $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                foreach ($stmt_name_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $custom_call_sink, 'call', $added_taints, $removed_taints);
                }
            }
        }
        if (!$statements_analyzer->node_data->getType($real_stmt)) {
            $statements_analyzer->node_data->setType($real_stmt, Type::getMixed());
        }
        return $function_call_info;
    }
    private static function analyzeInvokeCall(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node\Expr\FuncCall $real_stmt, PhpParser\Node\Expr $function_name, Context $context, Atomic $atomic_type) : void
    {
        $old_data_provider = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        $fake_method_call = new VirtualMethodCall($function_name, new VirtualIdentifier('__invoke', $function_name->getAttributes()), $stmt->args);
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        if (!in_array('InternalMethod', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['InternalMethod']);
        }
        $statements_analyzer->node_data->setType($function_name, new Union([$atomic_type]));
        \Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer::analyze($statements_analyzer, $fake_method_call, $context, \false);
        if (!in_array('InternalMethod', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['InternalMethod']);
        }
        $fake_method_call_type = $statements_analyzer->node_data->getType($fake_method_call);
        $statements_analyzer->node_data = $old_data_provider;
        if ($stmt_type = $statements_analyzer->node_data->getType($real_stmt)) {
            $statements_analyzer->node_data->setType($real_stmt, Type::combineUnionTypes($fake_method_call_type ?? Type::getMixed(), $stmt_type));
        } else {
            $statements_analyzer->node_data->setType($real_stmt, $fake_method_call_type ?? Type::getMixed());
        }
    }
    private static function processAssertFunctionEffects(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node\Arg $first_arg, Context $context) : void
    {
        $first_arg_value_id = spl_object_id($first_arg->value);
        $assert_clauses = FormulaGenerator::getFormula($first_arg_value_id, $first_arg_value_id, $first_arg->value, $context->self, $statements_analyzer, $codebase);
        AlgebraAnalyzer::checkForParadox($context->clauses, $assert_clauses, $statements_analyzer, $stmt, []);
        $simplified_clauses = Algebra::simplifyCNF([...$context->clauses, ...$assert_clauses]);
        $assert_type_assertions = Algebra::getTruthsFromFormula($simplified_clauses);
        $changed_var_ids = [];
        if ($assert_type_assertions) {
            // while in an and, we allow scope to boil over to support
            // statements of the form if ($x && $x->foo())
            [$op_vars_in_scope, $op_references_in_scope] = Reconciler::reconcileKeyedTypes($assert_type_assertions, $assert_type_assertions, $context->vars_in_scope, $context->references_in_scope, $changed_var_ids, array_map(static fn($_): bool => \true, $assert_type_assertions), $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $stmt));
            foreach ($changed_var_ids as $var_id => $_) {
                $first_appearance = $statements_analyzer->getFirstAppearance($var_id);
                if ($first_appearance && isset($context->vars_in_scope[$var_id]) && $context->vars_in_scope[$var_id]->hasMixed()) {
                    if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                        $codebase->analyzer->decrementMixedCount($statements_analyzer->getFilePath());
                    }
                    IssueBuffer::remove($statements_analyzer->getFilePath(), 'MixedAssignment', $first_appearance->raw_file_start);
                }
                if (isset($op_vars_in_scope[$var_id])) {
                    $op_vars_in_scope[$var_id] = $op_vars_in_scope[$var_id]->setProperties(['from_docblock' => \true]);
                }
            }
            $context->vars_in_scope = $op_vars_in_scope;
            $context->references_in_scope = $op_references_in_scope;
        }
        if ($changed_var_ids) {
            $simplified_clauses = Context::removeReconciledClauses($simplified_clauses, $changed_var_ids)[0];
        }
        $context->clauses = $simplified_clauses;
    }
    private static function checkFunctionCallPurity(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node $function_name, \Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallInfo $function_call_info, Context $context) : void
    {
        $config = $codebase->config;
        if (!$context->collect_initializations && !$context->collect_mutations && ($context->mutation_free || $context->external_mutation_free || $codebase->find_unused_variables || !$config->remember_property_assignments_after_call || $statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations)) {
            $must_use = \true;
            $callmap_function_pure = $function_call_info->function_id && $function_call_info->in_call_map ? $codebase->functions->isCallMapFunctionPure($codebase, $statements_analyzer->node_data, $function_call_info->function_id, $stmt->isFirstClassCallable() ? [] : $stmt->getArgs(), $must_use) : null;
            if (!$function_call_info->in_call_map && $function_call_info->function_storage && !$function_call_info->function_storage->pure && !$function_call_info->function_storage->mutation_free || $callmap_function_pure === \false) {
                if ($context->mutation_free || $context->external_mutation_free) {
                    IssueBuffer::maybeAdd(new ImpureFunctionCall('Cannot call an impure function from a mutation-free context', new CodeLocation($statements_analyzer, $function_name)), $statements_analyzer->getSuppressedIssues());
                } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                    $statements_analyzer->getSource()->inferred_has_mutation = \true;
                    $statements_analyzer->getSource()->inferred_impure = \true;
                }
                if (!$config->remember_property_assignments_after_call) {
                    $context->removeMutableObjectVars();
                }
            } elseif ($function_call_info->function_id && ($function_call_info->function_storage && $function_call_info->function_storage->pure && !$function_call_info->function_storage->assertions && $must_use || $callmap_function_pure === \true && $must_use) && $codebase->find_unused_variables && !$context->inside_conditional && !$context->inside_unset) {
                /**
                 * If a function is pure, and has the return type of 'no-return',
                 * it's okay to dismiss it's return value.
                 */
                if (!$context->insideUse() && !self::callUsesByReferenceArguments($function_call_info, $stmt) && !($function_call_info->function_storage && $function_call_info->function_storage->return_type && $function_call_info->function_storage->return_type->isNever())) {
                    IssueBuffer::maybeAdd(new UnusedFunctionCall('The call to ' . $function_call_info->function_id . ' is not used', new CodeLocation($statements_analyzer, $function_name), $function_call_info->function_id), $statements_analyzer->getSuppressedIssues());
                } else {
                    $stmt->setAttribute('pure', \true);
                }
            }
        }
    }
    private static function callUsesByReferenceArguments(\Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallInfo $function_call_info, PhpParser\Node\Expr\FuncCall $stmt) : bool
    {
        // If the function doesn't have any by-reference parameters
        // we shouldn't look any further.
        if (!$function_call_info->hasByReferenceParameters() || null === $function_call_info->function_params) {
            return \false;
        }
        $parameters = $function_call_info->function_params;
        // If no arguments were passed
        if (0 === count($stmt->getArgs())) {
            return \false;
        }
        foreach ($stmt->getArgs() as $index => $argument) {
            $parameter = null;
            if (null !== $argument->name) {
                $argument_name = $argument->name->toString();
                foreach ($parameters as $param) {
                    if ($param->name === $argument_name) {
                        $parameter = $param;
                        break;
                    }
                }
            } else {
                $parameter = $parameters[$index] ?? null;
            }
            if ($parameter && $parameter->by_ref) {
                return \true;
            }
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodVisibilityAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Issue\AbstractInstantiation;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\InterfaceInstantiation;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InternalMethod;
use Psalm\Issue\InvalidStringClass;
use Psalm\Issue\MixedMethodCall;
use Psalm\Issue\TooManyArguments;
use Psalm\Issue\UndefinedClass;
use Psalm\Issue\UnsafeGenericInstantiation;
use Psalm\Issue\UnsafeInstantiation;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Storage\Possibilities;
use Psalm\Type;
use Psalm\Type\Atomic\TAnonymousClassInstance;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TDependentGetClass;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\TaintKind;
use Psalm\Type\Union;
use function array_map;
use function array_merge;
use function array_shift;
use function array_values;
use function implode;
use function in_array;
use function md5;
use function preg_match;
use function reset;
use function strtolower;
/**
 * @internal
 */
class NewAnalyzer extends CallAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\New_ $stmt, Context $context) : bool
    {
        $fq_class_name = null;
        $codebase = $statements_analyzer->getCodebase();
        $config = $codebase->config;
        $can_extend = \false;
        $from_static = \false;
        if ($stmt->class instanceof PhpParser\Node\Name) {
            if (!in_array(strtolower($stmt->class->parts[0]), ['self', 'static', 'parent'], \true)) {
                $aliases = $statements_analyzer->getAliases();
                if ($context->calling_method_id && !$stmt->class instanceof PhpParser\Node\Name\FullyQualified) {
                    $codebase->file_reference_provider->addMethodReferenceToClassMember($context->calling_method_id, 'use:' . $stmt->class->parts[0] . ':' . md5($statements_analyzer->getFilePath()), \false);
                }
                $fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $aliases);
                $fq_class_name = $codebase->classlikes->getUnAliasedName($fq_class_name);
            } elseif ($context->self !== null) {
                switch ($stmt->class->parts[0]) {
                    case 'self':
                        $class_storage = $codebase->classlike_storage_provider->get($context->self);
                        $fq_class_name = $class_storage->name;
                        break;
                    case 'parent':
                        $fq_class_name = $context->parent;
                        break;
                    case 'static':
                        // @todo maybe we can do better here
                        $class_storage = $codebase->classlike_storage_provider->get($context->self);
                        $fq_class_name = $class_storage->name;
                        if (!$class_storage->final) {
                            $can_extend = \true;
                            $from_static = \true;
                        }
                        break;
                }
            }
            if ($codebase->store_node_types && $fq_class_name && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->class, $codebase->classlikes->classExists($fq_class_name) ? $fq_class_name : '*' . ($stmt->class instanceof PhpParser\Node\Name\FullyQualified ? '\\' : $statements_analyzer->getNamespace() . '-') . implode('\\', $stmt->class->parts));
            }
        } elseif ($stmt->class instanceof PhpParser\Node\Stmt\Class_) {
            $statements_analyzer->analyze([$stmt->class], $context);
            $fq_class_name = ClassAnalyzer::getAnonymousClassName($stmt->class, $statements_analyzer->getFilePath());
        } else {
            self::analyzeConstructorExpression($statements_analyzer, $codebase, $context, $stmt, $stmt->class, $config, $fq_class_name, $can_extend);
        }
        if ($fq_class_name) {
            if ($codebase->alter_code && $stmt->class instanceof PhpParser\Node\Name && !in_array($stmt->class->parts[0], ['parent', 'static'])) {
                $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id);
            }
            if ($context->check_classes) {
                if ($context->isPhantomClass($fq_class_name)) {
                    \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
                    return \true;
                }
                if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($statements_analyzer->getSource(), $stmt->class), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues()) === \false) {
                    \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
                    return \true;
                }
                if ($codebase->interfaceExists($fq_class_name)) {
                    IssueBuffer::maybeAdd(new InterfaceInstantiation('Interface ' . $fq_class_name . ' cannot be instantiated', new CodeLocation($statements_analyzer->getSource(), $stmt->class)), $statements_analyzer->getSuppressedIssues());
                    return \true;
                }
            }
            if ($stmt->class instanceof PhpParser\Node\Stmt\Class_) {
                $extends = $stmt->class->extends ? (string) $stmt->class->extends : null;
                $result_atomic_type = new TAnonymousClassInstance($fq_class_name, \false, $extends);
            } else {
                //if the class is a Name, it can't represent a child
                $definite_class = $stmt->class instanceof PhpParser\Node\Name;
                $result_atomic_type = new TNamedObject($fq_class_name, $from_static, $definite_class);
            }
            $statements_analyzer->node_data->setType($stmt, new Union([$result_atomic_type]));
            if (strtolower($fq_class_name) !== 'stdclass' && $codebase->classlikes->classExists($fq_class_name)) {
                self::analyzeNamedConstructor($statements_analyzer, $codebase, $stmt, $context, $fq_class_name, $from_static, $can_extend);
            } else {
                \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
                if ($codebase->classlikes->enumExists($fq_class_name)) {
                    IssueBuffer::maybeAdd(new UndefinedClass('Enums cannot be instantiated', new CodeLocation($statements_analyzer, $stmt), $fq_class_name));
                }
            }
        }
        if (!$config->remember_property_assignments_after_call && !$context->collect_initializations) {
            $context->removeMutableObjectVars();
        }
        return \true;
    }
    private static function analyzeNamedConstructor(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\New_ $stmt, Context $context, string $fq_class_name, bool $from_static, bool $can_extend) : void
    {
        $storage = $codebase->classlike_storage_provider->get($fq_class_name);
        if ($from_static) {
            if (!$storage->preserve_constructor_signature) {
                IssueBuffer::maybeAdd(new UnsafeInstantiation('Cannot safely instantiate class ' . $fq_class_name . ' with "new static" as' . ' its constructor might change in child classes', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($storage->template_types && !$storage->enforce_template_inheritance) {
                $source = $statements_analyzer->getSource();
                if ($source instanceof FunctionLikeAnalyzer) {
                    $function_storage = $source->getFunctionLikeStorage($statements_analyzer);
                    if ($function_storage->return_type && preg_match('/\\bstatic\\b/', $function_storage->return_type->getId())) {
                        IssueBuffer::maybeAdd(new UnsafeGenericInstantiation('Cannot safely instantiate generic class ' . $fq_class_name . ' with "new static" as' . ' its generic parameters may be constrained in child classes.', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    }
                }
            }
        }
        // if we're not calling this constructor via new static()
        if ($storage->abstract && !$can_extend) {
            if (IssueBuffer::accepts(new AbstractInstantiation('Unable to instantiate a abstract class ' . $fq_class_name, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues())) {
                return;
            }
        }
        if ($storage->deprecated && strtolower($fq_class_name) !== strtolower((string) $context->self)) {
            IssueBuffer::maybeAdd(new DeprecatedClass($fq_class_name . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
        }
        if ($context->self && !$context->collect_initializations && !$context->collect_mutations && !NamespaceAnalyzer::isWithinAny($context->self, $storage->internal)) {
            IssueBuffer::maybeAdd(new InternalClass($fq_class_name . ' is internal to ' . InternalClass::listToPhrase($storage->internal) . ' but called from ' . $context->self, new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
        }
        $method_id = new MethodIdentifier($fq_class_name, '__construct');
        if ($codebase->methods->methodExists($method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null, $statements_analyzer, $statements_analyzer->getFilePath())) {
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentMapPopulator::recordArgumentPositions($statements_analyzer, $stmt, $codebase, (string) $method_id);
            }
            $template_result = new TemplateResult([], []);
            if (self::checkMethodArgs($method_id, $stmt->getArgs(), $template_result, $context, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer) === \false) {
                return;
            }
            if (MethodVisibilityAnalyzer::analyze($method_id, $context, $statements_analyzer->getSource(), new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues()) === \false) {
                return;
            }
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
            if ($declaring_method_id) {
                $method_storage = $codebase->methods->getStorage($declaring_method_id);
                $caller_identifier = $statements_analyzer->getFullyQualifiedFunctionMethodOrNamespaceName() ?: '';
                if (!NamespaceAnalyzer::isWithinAny($caller_identifier, $method_storage->internal)) {
                    IssueBuffer::maybeAdd(new InternalMethod('Constructor ' . $codebase->methods->getCasedMethodId($declaring_method_id) . ' is internal to ' . InternalClass::listToPhrase($method_storage->internal) . ' but called from ' . ($caller_identifier ?: 'root namespace'), new CodeLocation($statements_analyzer, $stmt), (string) $method_id), $statements_analyzer->getSuppressedIssues());
                }
                if (!$method_storage->external_mutation_free && !$context->inside_throw) {
                    if ($context->pure) {
                        IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call an impure constructor from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                    } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                        $statements_analyzer->getSource()->inferred_has_mutation = \true;
                        $statements_analyzer->getSource()->inferred_impure = \true;
                    }
                }
                if ($method_storage->assertions && $stmt->class instanceof PhpParser\Node\Name) {
                    self::applyAssertionsToContext($stmt->class, null, $method_storage->assertions, $stmt->getArgs(), $template_result, $context, $statements_analyzer);
                }
                if ($method_storage->if_true_assertions) {
                    $statements_analyzer->node_data->setIfTrueAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, null, $codebase), $method_storage->if_true_assertions));
                }
                if ($method_storage->if_false_assertions) {
                    $statements_analyzer->node_data->setIfFalseAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, null, $codebase), $method_storage->if_false_assertions));
                }
            }
            $generic_param_types = null;
            if ($storage->template_types) {
                foreach ($storage->template_types as $template_name => $base_type) {
                    if (isset($template_result->lower_bounds[$template_name][$fq_class_name])) {
                        $generic_param_type = TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($template_result->lower_bounds[$template_name][$fq_class_name], $codebase);
                    } elseif ($storage->template_extended_params && $template_result->lower_bounds) {
                        $generic_param_type = self::getGenericParamForOffset($fq_class_name, $template_name, $storage->template_extended_params, array_map(static fn(array $type_map): array => array_map(static fn(array $bounds): Union => TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($bounds, $codebase), $type_map), $template_result->lower_bounds));
                    } else {
                        if ($fq_class_name === 'SplObjectStorage') {
                            $generic_param_type = Type::getNever();
                        } else {
                            $generic_param_type = array_values($base_type)[0];
                        }
                    }
                    $generic_param_types[] = $generic_param_type->setProperties(['had_template' => \true]);
                }
            }
            if ($generic_param_types) {
                $result_atomic_type = new TGenericObject($fq_class_name, $generic_param_types, \false, $from_static);
                $statements_analyzer->node_data->setType($stmt, new Union([$result_atomic_type]));
            }
        } elseif ($stmt->getArgs()) {
            IssueBuffer::maybeAdd(new TooManyArguments('Class ' . $fq_class_name . ' has no __construct, but arguments were passed', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name . '::__construct'), $statements_analyzer->getSuppressedIssues());
        } elseif ($storage->template_types) {
            $result_atomic_type = new TGenericObject($fq_class_name, array_values(array_map(static fn($map) => reset($map), $storage->template_types)), \false, $from_static);
            $statements_analyzer->node_data->setType($stmt, new Union([$result_atomic_type]));
        }
        if ($storage->external_mutation_free) {
            $stmt->setAttribute('external_mutation_free', \true);
            $stmt_type = $statements_analyzer->node_data->getType($stmt);
            if ($stmt_type) {
                $stmt_type = $stmt_type->setProperties(['reference_free' => \true]);
                $statements_analyzer->node_data->setType($stmt, $stmt_type);
            }
        }
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues()) && ($stmt_type = $statements_analyzer->node_data->getType($stmt))) {
            $code_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
            $method_storage = null;
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
            if ($declaring_method_id) {
                $method_storage = $codebase->methods->getStorage($declaring_method_id);
            }
            if ($storage->external_mutation_free || $method_storage && $method_storage->specialize_call) {
                $method_source = DataFlowNode::getForMethodReturn((string) $method_id, $fq_class_name . '::__construct', $storage->location, $code_location);
            } else {
                $method_source = DataFlowNode::getForMethodReturn((string) $method_id, $fq_class_name . '::__construct', $storage->location);
            }
            $statements_analyzer->data_flow_graph->addNode($method_source);
            $stmt_type = $stmt_type->setParentNodes([$method_source->id => $method_source]);
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
        }
    }
    private static function analyzeConstructorExpression(StatementsAnalyzer $statements_analyzer, Codebase $codebase, Context $context, PhpParser\Node\Expr\New_ $stmt, PhpParser\Node\Expr $stmt_class, Config $config, ?string &$fq_class_name, bool &$can_extend) : void
    {
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        ExpressionAnalyzer::analyze($statements_analyzer, $stmt_class, $context);
        $context->inside_general_use = $was_inside_general_use;
        $stmt_class_type = $statements_analyzer->node_data->getType($stmt_class);
        if (!$stmt_class_type) {
            \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
            return;
        }
        $has_single_class = $stmt_class_type->isSingleStringLiteral();
        if ($has_single_class) {
            $fq_class_name = $stmt_class_type->getSingleStringLiteral()->value;
        } else {
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $stmt_class_type->parent_nodes && !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                $arg_location = new CodeLocation($statements_analyzer->getSource(), $stmt_class);
                $custom_call_sink = TaintSink::getForMethodArgument('variable-call', 'variable-call', 0, $arg_location, $arg_location);
                $custom_call_sink->taints = [TaintKind::INPUT_CALLABLE];
                $statements_analyzer->data_flow_graph->addSink($custom_call_sink);
                $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
                $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                foreach ($stmt_class_type->parent_nodes as $parent_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $custom_call_sink, 'call', $added_taints, $removed_taints);
                }
            }
            if (self::checkMethodArgs(null, $stmt->getArgs(), new TemplateResult([], []), $context, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer) === \false) {
                return;
            }
        }
        $new_type = null;
        $stmt_class_types = $stmt_class_type->getAtomicTypes();
        while ($stmt_class_types) {
            $lhs_type_part = array_shift($stmt_class_types);
            if ($lhs_type_part instanceof TTemplateParam) {
                $stmt_class_types = array_merge($stmt_class_types, $lhs_type_part->as->getAtomicTypes());
                continue;
            }
            if ($lhs_type_part instanceof TTemplateParamClass) {
                if (!$statements_analyzer->node_data->getType($stmt)) {
                    $new_type_part = new TTemplateParam($lhs_type_part->param_name, $lhs_type_part->as_type ? new Union([$lhs_type_part->as_type]) : Type::getObject(), $lhs_type_part->defining_class);
                    if (!$lhs_type_part->as_type) {
                        IssueBuffer::maybeAdd(new MixedMethodCall('Cannot call constructor on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    }
                    $new_type = Type::combineUnionTypes($new_type, new Union([$new_type_part]));
                    if ($lhs_type_part->as_type && $codebase->classlikes->classExists($lhs_type_part->as_type->value)) {
                        $as_storage = $codebase->classlike_storage_provider->get($lhs_type_part->as_type->value);
                        if (!$as_storage->preserve_constructor_signature) {
                            IssueBuffer::maybeAdd(new UnsafeInstantiation('Cannot safely instantiate class ' . $lhs_type_part->as_type->value . ' with "new $class_name" as' . ' its constructor might change in child classes', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                        }
                    }
                }
                if ($lhs_type_part->as_type) {
                    $codebase->methods->methodExists(new MethodIdentifier($lhs_type_part->as_type->value, '__construct'), $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null, $statements_analyzer, $statements_analyzer->getFilePath());
                }
                continue;
            }
            if ($lhs_type_part instanceof TLiteralClassString || $lhs_type_part instanceof TClassString || $lhs_type_part instanceof TDependentGetClass) {
                if (!$statements_analyzer->node_data->getType($stmt)) {
                    if ($lhs_type_part instanceof TClassString) {
                        $generated_type = $lhs_type_part->as_type ? $lhs_type_part->as_type : new TObject();
                        if ($lhs_type_part->as_type && $codebase->classlikes->classExists($lhs_type_part->as_type->value)) {
                            $as_storage = $codebase->classlike_storage_provider->get($lhs_type_part->as_type->value);
                            if (!$as_storage->preserve_constructor_signature) {
                                IssueBuffer::maybeAdd(new UnsafeInstantiation('Cannot safely instantiate class ' . $lhs_type_part->as_type->value . ' with "new $class_name" as' . ' its constructor might change in child classes', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                            }
                        }
                    } elseif ($lhs_type_part instanceof TDependentGetClass) {
                        $generated_type = new TObject();
                        if ($lhs_type_part->as_type->hasObjectType() && $lhs_type_part->as_type->isSingle()) {
                            foreach ($lhs_type_part->as_type->getAtomicTypes() as $typeof_type_atomic) {
                                if ($typeof_type_atomic instanceof TNamedObject) {
                                    $generated_type = new TNamedObject($typeof_type_atomic->value);
                                }
                            }
                        }
                    } else {
                        $generated_type = new TNamedObject($lhs_type_part->value);
                    }
                    if ($lhs_type_part instanceof TClassString) {
                        $can_extend = \true;
                    }
                    if ($generated_type instanceof TObject) {
                        IssueBuffer::maybeAdd(new MixedMethodCall('Cannot call constructor on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    }
                    $new_type = Type::combineUnionTypes($new_type, new Union([$generated_type]));
                }
                continue;
            }
            if ($lhs_type_part instanceof TString) {
                if (!$config->allow_string_standin_for_class || $lhs_type_part instanceof TNumericString) {
                    IssueBuffer::maybeAdd(new InvalidStringClass('String cannot be used as a class', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            } elseif ($lhs_type_part instanceof TMixed || $lhs_type_part instanceof TObject) {
                IssueBuffer::maybeAdd(new MixedMethodCall('Cannot call constructor on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($lhs_type_part instanceof TFalse && $stmt_class_type->ignore_falsable_issues) {
                // do nothing
            } elseif ($lhs_type_part instanceof TNull && $stmt_class_type->ignore_nullable_issues) {
                // do nothing
            } elseif ($lhs_type_part instanceof TNamedObject) {
                $new_type = Type::combineUnionTypes($new_type, new Union([$lhs_type_part]));
                continue;
            } else {
                IssueBuffer::maybeAdd(new UndefinedClass('Type ' . $lhs_type_part . ' cannot be called as a class', new CodeLocation($statements_analyzer->getSource(), $stmt), (string) $lhs_type_part), $statements_analyzer->getSuppressedIssues());
            }
            $new_type = Type::combineUnionTypes($new_type, Type::getObject());
        }
        if (!$has_single_class) {
            if ($new_type) {
                $statements_analyzer->node_data->setType($stmt, $new_type);
            }
            \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
            return;
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\FuncCall;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\MethodCall;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\New_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\StaticCall;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use function array_reverse;
use function array_shift;
use function is_string;
use function reset;
use function strlen;
use function substr;
use function token_get_all;
/**
 * @internal
 */
class ArgumentMapPopulator
{
    /**
     * @param MethodCall|StaticCall|FuncCall|New_ $stmt
     */
    public static function recordArgumentPositions(StatementsAnalyzer $statements_analyzer, Expr $stmt, Codebase $codebase, string $function_reference) : void
    {
        $file_content = $codebase->file_provider->getContents($statements_analyzer->getFilePath());
        // Find opening paren
        $first_argument = $stmt->getArgs()[0] ?? null;
        $first_argument_character = $first_argument !== null ? $first_argument->getStartFilePos() : $stmt->getEndFilePos();
        $method_name_and_first_paren_source_code_length = $first_argument_character - $stmt->getStartFilePos();
        // FIXME: There are weird ::__construct calls in the AST for `extends`
        if ($method_name_and_first_paren_source_code_length <= 0) {
            return;
        }
        $method_name_and_first_paren_source_code = substr($file_content, $stmt->getStartFilePos(), $method_name_and_first_paren_source_code_length);
        $method_name_and_first_paren_tokens = token_get_all('<?php ' . $method_name_and_first_paren_source_code);
        $opening_paren_position = $first_argument_character;
        foreach (array_reverse($method_name_and_first_paren_tokens) as $token) {
            $token = is_string($token) ? $token : $token[1];
            $opening_paren_position -= strlen($token);
            if ($token === '(') {
                break;
            }
        }
        // New instances can be created without parens
        if ($opening_paren_position < $stmt->getStartFilePos()) {
            return;
        }
        // Record ranges of the source code that need to be tokenized to find commas
        /** @var array{0: int, 1: int}[] $ranges */
        $ranges = [];
        // Add range between opening paren and first argument
        $first_argument = $stmt->getArgs()[0] ?? null;
        $first_argument_starting_position = $first_argument !== null ? $first_argument->getStartFilePos() : $stmt->getEndFilePos();
        $first_range_starting_position = $opening_paren_position + 1;
        if ($first_range_starting_position !== $first_argument_starting_position) {
            $ranges[] = [$first_range_starting_position, $first_argument_starting_position];
        }
        // Add range between arguments
        foreach ($stmt->getArgs() as $i => $argument) {
            $range_start = $argument->getEndFilePos() + 1;
            $next_argument = $stmt->getArgs()[$i + 1] ?? null;
            $range_end = $next_argument !== null ? $next_argument->getStartFilePos() : $stmt->getEndFilePos();
            if ($range_start !== $range_end) {
                $ranges[] = [$range_start, $range_end];
            }
        }
        $commas = [];
        foreach ($ranges as $range) {
            $position = $range[0];
            $length = $range[1] - $position;
            if ($length > 0) {
                $range_source_code = substr($file_content, $position, $length);
                $range_tokens = token_get_all('<?php ' . $range_source_code);
                array_shift($range_tokens);
                $current_position = $position;
                foreach ($range_tokens as $token) {
                    $token = is_string($token) ? $token : $token[1];
                    if ($token === ',') {
                        $commas[] = $current_position;
                    }
                    $current_position += strlen($token);
                }
            }
        }
        $argument_start_position = $opening_paren_position + 1;
        $argument_number = 0;
        while (!empty($commas)) {
            $comma = reset($commas);
            array_shift($commas);
            $codebase->analyzer->addNodeArgument($statements_analyzer->getFilePath(), $argument_start_position, $comma, $function_reference, $argument_number);
            ++$argument_number;
            $argument_start_position = $comma + 1;
        }
        $codebase->analyzer->addNodeArgument($statements_analyzer->getFilePath(), $argument_start_position, $stmt->getEndFilePos(), $function_reference, $argument_number);
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Type\Union;
/**
 * @internal
 */
class FunctionCallInfo
{
    public ?string $function_id = null;
    public ?bool $function_exists = null;
    public bool $is_stubbed = \false;
    public bool $in_call_map = \false;
    /**
     * @var array<string, Union>
     */
    public array $defined_constants = [];
    /**
     * @var array<string, bool>
     */
    public array $global_variables = [];
    /**
     * @var ?array<int, FunctionLikeParameter>
     */
    public ?array $function_params = null;
    public ?FunctionLikeStorage $function_storage = null;
    public ?PhpParser\Node\Name $new_function_name = null;
    public bool $allow_named_args = \true;
    public array $byref_uses = [];
    /**
     * @mutation-free
     */
    public function hasByReferenceParameters() : bool
    {
        if (null === $this->function_params) {
            return \false;
        }
        foreach ($this->function_params as $value) {
            if ($value->by_ref) {
                return \true;
            }
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use AssertionError;
use Psalm\Codebase;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_keys;
use function array_merge;
use function array_search;
/**
 * @internal
 */
class ClassTemplateParamCollector
{
    /**
     * @param lowercase-string $method_name
     * @return array<string, non-empty-array<string, Union>>|null
     * @psalm-suppress MoreSpecificReturnType
     * @psalm-suppress LessSpecificReturnStatement
     */
    public static function collect(Codebase $codebase, ClassLikeStorage $class_storage, ClassLikeStorage $static_class_storage, ?string $method_name = null, ?Atomic $lhs_type_part = null, bool $self_call = \false) : ?array
    {
        $non_trait_class_storage = $class_storage->is_trait ? $static_class_storage : $class_storage;
        $template_types = $class_storage->template_types;
        $candidate_class_storages = [$class_storage];
        if ($static_class_storage->template_extended_params && $method_name && !empty($non_trait_class_storage->overridden_method_ids[$method_name]) && isset($class_storage->methods[$method_name]) && (!isset($non_trait_class_storage->methods[$method_name]->return_type) || $class_storage->methods[$method_name]->inherited_return_type)) {
            foreach ($non_trait_class_storage->overridden_method_ids[$method_name] as $overridden_method_id) {
                $overridden_storage = $codebase->methods->getStorage($overridden_method_id);
                if (!$overridden_storage->return_type) {
                    continue;
                }
                if ($overridden_storage->return_type->isNull()) {
                    continue;
                }
                $fq_overridden_class = $overridden_method_id->fq_class_name;
                $overridden_class_storage = $codebase->classlike_storage_provider->get($fq_overridden_class);
                $overridden_template_types = $overridden_class_storage->template_types;
                if (!$template_types) {
                    $template_types = $overridden_template_types;
                } elseif ($overridden_template_types) {
                    foreach ($overridden_template_types as $template_name => $template_map) {
                        if (isset($template_types[$template_name])) {
                            $template_types[$template_name] = array_merge($template_types[$template_name], $template_map);
                        } else {
                            $template_types[$template_name] = $template_map;
                        }
                    }
                }
                $candidate_class_storages[] = $overridden_class_storage;
            }
        }
        if (!$template_types) {
            return null;
        }
        $class_template_params = [];
        $e = $static_class_storage->template_extended_params;
        if ($lhs_type_part instanceof TGenericObject) {
            if ($class_storage === $static_class_storage && $class_storage->template_types) {
                $i = 0;
                foreach ($class_storage->template_types as $type_name => $_) {
                    if (isset($lhs_type_part->type_params[$i])) {
                        $class_template_params[$type_name][$class_storage->name] = $lhs_type_part->type_params[$i];
                    }
                    $i++;
                }
            }
            $template_result = null;
            if ($class_storage !== $static_class_storage && $static_class_storage->template_types) {
                $templates = self::collect($codebase, $static_class_storage, $static_class_storage, null, $lhs_type_part);
                if ($templates === null) {
                    throw new AssertionError("Could not collect templates!");
                }
                $template_result = new TemplateResult($static_class_storage->template_types, $templates);
            }
            foreach ($template_types as $type_name => $_) {
                if (isset($class_template_params[$type_name])) {
                    continue;
                }
                if ($class_storage !== $static_class_storage && isset($e[$class_storage->name][$type_name])) {
                    $input_type_extends = $e[$class_storage->name][$type_name];
                    $output_type_extends = self::resolveTemplateParam($codebase, $input_type_extends, $static_class_storage, $lhs_type_part, $template_result);
                    $class_template_params[$type_name][$class_storage->name] = $output_type_extends ?? Type::getMixed();
                }
                if (!isset($class_template_params[$type_name][$class_storage->name])) {
                    $class_template_params[$type_name] = [$class_storage->name => Type::getMixed()];
                }
            }
        }
        foreach ($template_types as $type_name => $type_map) {
            foreach ($type_map as $type) {
                foreach ($candidate_class_storages as $candidate_class_storage) {
                    if ($candidate_class_storage !== $static_class_storage && isset($e[$candidate_class_storage->name][$type_name]) && !isset($class_template_params[$type_name][$candidate_class_storage->name])) {
                        $class_template_params[$type_name][$candidate_class_storage->name] = new Union(self::expandType($codebase, $e[$candidate_class_storage->name][$type_name], $e, $static_class_storage->name, $static_class_storage->template_types));
                    }
                }
                if (!$self_call) {
                    if (!isset($class_template_params[$type_name])) {
                        $class_template_params[$type_name][$class_storage->name] = $type;
                    }
                }
            }
        }
        return $class_template_params;
    }
    private static function resolveTemplateParam(Codebase $codebase, Union $input_type_extends, ClassLikeStorage $static_class_storage, TGenericObject $lhs_type_part, ?TemplateResult $template_result = null) : ?Union
    {
        $output_type_extends = null;
        foreach ($input_type_extends->getAtomicTypes() as $type_extends_atomic) {
            if ($type_extends_atomic instanceof TTemplateParam) {
                if (isset($static_class_storage->template_types[$type_extends_atomic->param_name][$type_extends_atomic->defining_class])) {
                    $mapped_offset = array_search($type_extends_atomic->param_name, array_keys($static_class_storage->template_types), \true);
                    if ($mapped_offset !== \false && isset($lhs_type_part->type_params[$mapped_offset])) {
                        $output_type_extends = Type::combineUnionTypes($lhs_type_part->type_params[$mapped_offset], $output_type_extends);
                    }
                } elseif (isset($static_class_storage->template_extended_params[$type_extends_atomic->defining_class][$type_extends_atomic->param_name])) {
                    $nested_output_type = self::resolveTemplateParam($codebase, $static_class_storage->template_extended_params[$type_extends_atomic->defining_class][$type_extends_atomic->param_name], $static_class_storage, $lhs_type_part, $template_result);
                    if ($nested_output_type !== null) {
                        $output_type_extends = Type::combineUnionTypes($nested_output_type, $output_type_extends);
                    }
                }
            } else {
                if ($template_result !== null) {
                    $type_extends_atomic = $type_extends_atomic->replaceTemplateTypesWithArgTypes($template_result, $codebase);
                }
                $output_type_extends = Type::combineUnionTypes(new Union([$type_extends_atomic]), $output_type_extends);
            }
        }
        return $output_type_extends;
    }
    /**
     * @param array<string, array<string, Union>> $e
     * @return non-empty-list<Atomic>
     */
    private static function expandType(Codebase $codebase, Union $input_type_extends, array $e, string $static_fq_class_name, ?array $static_template_types) : array
    {
        $output_type_extends = [];
        foreach ($input_type_extends->getAtomicTypes() as $type_extends_atomic) {
            if ($type_extends_atomic instanceof TTemplateParam && ($static_fq_class_name !== $type_extends_atomic->defining_class || !isset($static_template_types[$type_extends_atomic->param_name])) && isset($e[$type_extends_atomic->defining_class][$type_extends_atomic->param_name])) {
                $output_type_extends = [...$output_type_extends, ...self::expandType($codebase, $e[$type_extends_atomic->defining_class][$type_extends_atomic->param_name], $e, $static_fq_class_name, $static_template_types)];
            } elseif ($type_extends_atomic instanceof TClassConstant) {
                $expanded = TypeExpander::expandAtomic($codebase, $type_extends_atomic, $type_extends_atomic->fq_classlike_name, $type_extends_atomic->fq_classlike_name, null, \true, \true);
                foreach ($expanded as $type) {
                    $output_type_extends[] = $type;
                }
            } else {
                $output_type_extends[] = $type_extends_atomic;
            }
        }
        return $output_type_extends;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Issue\DeprecatedMethod;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InternalMethod;
use Psalm\IssueBuffer;
/**
 * @internal
 */
class MethodCallProhibitionAnalyzer
{
    /**
     * @param  string[]     $suppressed_issues
     */
    public static function analyze(Codebase $codebase, Context $context, MethodIdentifier $method_id, ?string $caller_identifier, CodeLocation $code_location, array $suppressed_issues) : void
    {
        $codebase_methods = $codebase->methods;
        $method_id = $codebase_methods->getDeclaringMethodId($method_id);
        if ($method_id === null) {
            return;
        }
        $storage = $codebase_methods->getStorage($method_id);
        if ($storage->deprecated) {
            IssueBuffer::maybeAdd(new DeprecatedMethod('The method ' . $codebase_methods->getCasedMethodId($method_id) . ' has been marked as deprecated', $code_location, (string) $method_id), $suppressed_issues);
        }
        if (!$context->collect_initializations && !$context->collect_mutations) {
            if (!NamespaceAnalyzer::isWithinAny($caller_identifier ?? "", $storage->internal)) {
                IssueBuffer::maybeAdd(new InternalMethod('The method ' . $codebase_methods->getCasedMethodId($method_id) . ' is internal to ' . InternalClass::listToPhrase($storage->internal) . ' but called from ' . ($caller_identifier ?: 'root namespace'), $code_location, (string) $method_id), $suppressed_issues);
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\MethodIdentifier;
use Psalm\Issue\InaccessibleMethod;
use Psalm\IssueBuffer;
use Psalm\StatementsSource;
use UnexpectedValueException;
use function array_pop;
use function end;
use function strtolower;
/**
 * @internal
 */
class MethodVisibilityAnalyzer
{
    /**
     * @param  string[]         $suppressed_issues
     * @return false|null
     */
    public static function analyze(MethodIdentifier $method_id, Context $context, StatementsSource $source, CodeLocation $code_location, array $suppressed_issues) : ?bool
    {
        $codebase = $source->getCodebase();
        $codebase_methods = $codebase->methods;
        $codebase_classlikes = $codebase->classlikes;
        $fq_classlike_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        if ($codebase_methods->visibility_provider->has($fq_classlike_name)) {
            $method_visible = $codebase_methods->visibility_provider->isMethodVisible($source, $fq_classlike_name, $method_name, $context, $code_location);
            if ($method_visible === \false) {
                if (IssueBuffer::accepts(new InaccessibleMethod('Cannot access method ' . $codebase_methods->getCasedMethodId($method_id) . ' from context ' . $context->self, $code_location), $suppressed_issues)) {
                    return \false;
                }
            } elseif ($method_visible === \true) {
                return \false;
            }
        }
        $declaring_method_id = $codebase_methods->getDeclaringMethodId($method_id);
        if (!$declaring_method_id) {
            if ($method_name === '__construct' || $method_id->fq_class_name === 'Closure' && ($method_id->method_name === 'fromcallable' || $method_id->method_name === '__invoke')) {
                return null;
            }
            if (InternalCallMapHandler::inCallMap((string) $method_id)) {
                return null;
            }
            throw new UnexpectedValueException('$declaring_method_id not expected to be null here');
        }
        $appearing_method_id = $codebase_methods->getAppearingMethodId($method_id);
        $appearing_method_class = null;
        $appearing_class_storage = null;
        $appearing_method_name = null;
        if ($appearing_method_id) {
            $appearing_method_class = $appearing_method_id->fq_class_name;
            $appearing_method_name = $appearing_method_id->method_name;
            // if the calling class is the same, we know the method exists, so it must be visible
            if ($appearing_method_class === $context->self) {
                return null;
            }
            $appearing_class_storage = $codebase->classlike_storage_provider->get($appearing_method_class);
        }
        $declaring_method_class = $declaring_method_id->fq_class_name;
        if ($source->getSource() instanceof TraitAnalyzer && strtolower($declaring_method_class) === strtolower((string) $source->getFQCLN())) {
            return null;
        }
        $storage = $codebase->methods->getStorage($declaring_method_id);
        $visibility = $storage->visibility;
        if ($appearing_method_name && isset($appearing_class_storage->trait_visibility_map[$appearing_method_name])) {
            $visibility = $appearing_class_storage->trait_visibility_map[$appearing_method_name];
        }
        // Get oldest ancestor declaring $method_id
        $overridden_method_ids = $codebase_methods->getOverriddenMethodIds($method_id);
        // Remove traits and interfaces
        while (($oldest_declaring_method_id = end($overridden_method_ids)) && !$codebase_classlikes->hasFullyQualifiedClassName($oldest_declaring_method_id->fq_class_name)) {
            array_pop($overridden_method_ids);
        }
        if (empty($overridden_method_ids)) {
            // We prefer appearing method id over declaring method id because declaring method id could be a trait
            $oldest_ancestor_declaring_method_id = $appearing_method_id;
        } else {
            // Oldest ancestor is at end of array
            $oldest_ancestor_declaring_method_id = array_pop($overridden_method_ids);
        }
        $oldest_ancestor_declaring_method_class = $oldest_ancestor_declaring_method_id->fq_class_name ?? null;
        switch ($visibility) {
            case ClassLikeAnalyzer::VISIBILITY_PUBLIC:
                return null;
            case ClassLikeAnalyzer::VISIBILITY_PRIVATE:
                if (!$context->self || $appearing_method_class !== $context->self) {
                    if (IssueBuffer::accepts(new InaccessibleMethod('Cannot access private method ' . $codebase_methods->getCasedMethodId($method_id) . ' from context ' . $context->self, $code_location), $suppressed_issues)) {
                        return \false;
                    }
                }
                return null;
            case ClassLikeAnalyzer::VISIBILITY_PROTECTED:
                if (!$context->self) {
                    if (IssueBuffer::accepts(new InaccessibleMethod('Cannot access protected method ' . $method_id, $code_location), $suppressed_issues)) {
                        return \false;
                    }
                    return null;
                }
                if ($oldest_ancestor_declaring_method_class !== null && $codebase_classlikes->classExtends($oldest_ancestor_declaring_method_class, $context->self)) {
                    return null;
                }
                if ($oldest_ancestor_declaring_method_class !== null && !$codebase_classlikes->classExtends($context->self, $oldest_ancestor_declaring_method_class) && !$codebase_classlikes->classExtends($declaring_method_class, $context->self)) {
                    if (IssueBuffer::accepts(new InaccessibleMethod('Cannot access protected method ' . $codebase_methods->getCasedMethodId($method_id) . ' from context ' . $context->self, $code_location), $suppressed_issues)) {
                        return \false;
                    }
                }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Node\Expr\VirtualArray;
use Psalm\Node\Expr\VirtualArrayItem;
use Psalm\Node\Scalar\VirtualString;
use Psalm\Node\VirtualArg;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Union;
use function array_map;
use function array_merge;
/**
 * @internal
 */
class MissingMethodCallHandler
{
    public static function handleMagicMethod(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\MethodCall $stmt, MethodIdentifier $method_id, ClassLikeStorage $class_storage, Context $context, Config $config, ?Union $all_intersection_return_type, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result, ?Atomic $lhs_type_part) : ?\Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicCallContext
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name_lc = $method_id->method_name;
        if ($stmt->isFirstClassCallable()) {
            if (isset($class_storage->pseudo_methods[$method_name_lc])) {
                $result->has_valid_method_call_type = \true;
                $result->existent_method_ids[] = $method_id->__toString();
                $result->return_type = self::createFirstClassCallableReturnType($class_storage->pseudo_methods[$method_name_lc]);
            } else {
                $result->non_existent_magic_method_ids[] = $method_id->__toString();
                $result->return_type = self::createFirstClassCallableReturnType();
            }
            return null;
        }
        if ($codebase->methods->return_type_provider->has($fq_class_name)) {
            $return_type_candidate = $codebase->methods->return_type_provider->getReturnType($statements_analyzer, $method_id->fq_class_name, $method_id->method_name, $stmt, $context, new CodeLocation($statements_analyzer->getSource(), $stmt->name));
            if ($return_type_candidate) {
                if ($all_intersection_return_type) {
                    $return_type_candidate = Type::intersectUnionTypes($all_intersection_return_type, $return_type_candidate, $codebase) ?? Type::getMixed();
                }
                $result->return_type = Type::combineUnionTypes($return_type_candidate, $result->return_type, $codebase);
                CallAnalyzer::checkMethodArgs($method_id, $stmt->getArgs(), new TemplateResult([], []), $context, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer);
                return null;
            }
        }
        $found_method_and_class_storage = self::findPseudoMethodAndClassStorages($codebase, $class_storage, $method_name_lc);
        if ($found_method_and_class_storage) {
            $result->has_valid_method_call_type = \true;
            $result->existent_method_ids[] = $method_id->__toString();
            [$pseudo_method_storage, $defining_class_storage] = $found_method_and_class_storage;
            $found_generic_params = ClassTemplateParamCollector::collect($codebase, $defining_class_storage, $class_storage, $method_name_lc, $lhs_type_part, !$statements_analyzer->isStatic() && $method_id->fq_class_name === $context->self);
            ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), $pseudo_method_storage->params, (string) $method_id, \true, $context, $found_generic_params ? new TemplateResult([], $found_generic_params) : null);
            ArgumentsAnalyzer::checkArgumentsMatch($statements_analyzer, $stmt->getArgs(), null, $pseudo_method_storage->params, $pseudo_method_storage, null, new TemplateResult([], $found_generic_params ?: []), new CodeLocation($statements_analyzer, $stmt), $context);
            if ($pseudo_method_storage->return_type) {
                $return_type_candidate = $pseudo_method_storage->return_type;
                if ($found_generic_params) {
                    $return_type_candidate = TemplateInferredTypeReplacer::replace($return_type_candidate, new TemplateResult([], $found_generic_params), $codebase);
                }
                $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, $defining_class_storage->name, $lhs_type_part instanceof Atomic\TNamedObject ? $lhs_type_part : $fq_class_name, $defining_class_storage->parent_class);
                if ($all_intersection_return_type) {
                    $return_type_candidate = Type::intersectUnionTypes($all_intersection_return_type, $return_type_candidate, $codebase) ?? Type::getMixed();
                }
                $result->return_type = Type::combineUnionTypes($return_type_candidate, $result->return_type, $codebase);
                return null;
            }
        } elseif ($all_intersection_return_type === null) {
            ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
            if ($class_storage->sealed_methods || $config->seal_all_methods) {
                $result->non_existent_magic_method_ids[] = $method_id->__toString();
                return null;
            }
        }
        $result->has_valid_method_call_type = \true;
        $result->existent_method_ids[] = $method_id->__toString();
        $array_values = array_map(static fn(PhpParser\Node\Arg $arg): PhpParser\Node\Expr\ArrayItem => new VirtualArrayItem($arg->value, null, \false, $arg->getAttributes()), $stmt->getArgs());
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        return new \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicCallContext(new MethodIdentifier($fq_class_name, '__call'), [new VirtualArg(new VirtualString($method_name_lc), \false, \false, $stmt->getAttributes()), new VirtualArg(new VirtualArray($array_values, $stmt->getAttributes()), \false, \false, $stmt->getAttributes())]);
    }
    /**
     * @param array<string> $all_intersection_existent_method_ids
     */
    public static function handleMissingOrMagicMethod(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\MethodCall $stmt, MethodIdentifier $method_id, bool $is_interface, Context $context, Config $config, ?Union $all_intersection_return_type, array $all_intersection_existent_method_ids, ?string $intersection_method_id, string $cased_method_id, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result, ?Atomic $lhs_type_part) : void
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name_lc = $method_id->method_name;
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $found_method_and_class_storage = self::findPseudoMethodAndClassStorages($codebase, $class_storage, $method_name_lc);
        if (($is_interface || $config->use_phpdoc_method_without_magic_or_parent) && $found_method_and_class_storage) {
            $result->has_valid_method_call_type = \true;
            $result->existent_method_ids[] = $method_id->__toString();
            [$pseudo_method_storage, $defining_class_storage] = $found_method_and_class_storage;
            if ($stmt->isFirstClassCallable()) {
                $result->return_type = self::createFirstClassCallableReturnType($pseudo_method_storage);
                return;
            }
            $found_generic_params = ClassTemplateParamCollector::collect($codebase, $defining_class_storage, $class_storage, $method_name_lc, $lhs_type_part, !$statements_analyzer->isStatic() && $method_id->fq_class_name === $context->self);
            if (ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), $pseudo_method_storage->params, (string) $method_id, \true, $context, $found_generic_params ? new TemplateResult([], $found_generic_params) : null) === \false) {
                return;
            }
            if (ArgumentsAnalyzer::checkArgumentsMatch($statements_analyzer, $stmt->getArgs(), null, $pseudo_method_storage->params, $pseudo_method_storage, null, new TemplateResult([], $found_generic_params ?: []), new CodeLocation($statements_analyzer, $stmt->name), $context) === \false) {
                return;
            }
            if ($pseudo_method_storage->return_type) {
                $return_type_candidate = $pseudo_method_storage->return_type;
                if ($found_generic_params) {
                    $return_type_candidate = TemplateInferredTypeReplacer::replace($return_type_candidate, new TemplateResult([], $found_generic_params), $codebase);
                }
                if ($all_intersection_return_type) {
                    $return_type_candidate = Type::intersectUnionTypes($all_intersection_return_type, $return_type_candidate, $codebase) ?? Type::getMixed();
                }
                $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, $defining_class_storage->name, $lhs_type_part instanceof Atomic\TNamedObject ? $lhs_type_part : $fq_class_name, $defining_class_storage->parent_class, \true, \false, $class_storage->final);
                $result->return_type = Type::combineUnionTypes($return_type_candidate, $result->return_type);
                return;
            }
            $result->return_type = Type::getMixed();
            return;
        }
        if ($stmt->isFirstClassCallable()) {
            $result->non_existent_class_method_ids[] = $method_id->__toString();
            $result->return_type = self::createFirstClassCallableReturnType();
            return;
        }
        if (ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context) === \false) {
            return;
        }
        if ($all_intersection_return_type && $all_intersection_existent_method_ids) {
            $result->existent_method_ids = array_merge($result->existent_method_ids, $all_intersection_existent_method_ids);
            $result->return_type = Type::combineUnionTypes($all_intersection_return_type, $result->return_type);
            return;
        }
        if (!$is_interface && !$config->use_phpdoc_method_without_magic_or_parent || !isset($class_storage->pseudo_methods[$method_name_lc])) {
            if ($is_interface) {
                $result->non_existent_interface_method_ids[] = $intersection_method_id ?: $cased_method_id;
            } else {
                $result->non_existent_class_method_ids[] = $intersection_method_id ?: $cased_method_id;
            }
        }
    }
    private static function createFirstClassCallableReturnType(?MethodStorage $method_storage = null) : Union
    {
        if ($method_storage) {
            return new Union([new TClosure('Closure', $method_storage->params, $method_storage->return_type, $method_storage->pure)]);
        }
        return Type::getClosure();
    }
    /**
     * Try to find matching pseudo method over ancestors (including interfaces).
     *
     * Returns the pseudo method if exists, with its defining class storage.
     * If the method is not declared, null is returned.
     *
     * @param ClassLikeStorage $static_class_storage The called class
     * @param lowercase-string $method_name_lc
     * @return array{MethodStorage, ClassLikeStorage}
     */
    private static function findPseudoMethodAndClassStorages(Codebase $codebase, ClassLikeStorage $static_class_storage, string $method_name_lc) : ?array
    {
        if (isset($static_class_storage->declaring_pseudo_method_ids[$method_name_lc])) {
            $method_id = $static_class_storage->declaring_pseudo_method_ids[$method_name_lc];
            $class_storage = $codebase->classlikes->getStorageFor($method_id->fq_class_name);
            if ($class_storage && isset($class_storage->pseudo_methods[$method_name_lc])) {
                return [$class_storage->pseudo_methods[$method_name_lc], $class_storage];
            }
        }
        if ($pseudo_method_storage = $static_class_storage->pseudo_methods[$method_name_lc] ?? null) {
            return [$pseudo_method_storage, $static_class_storage];
        }
        $ancestors = $static_class_storage->class_implements;
        foreach ($ancestors as $fq_class_name => $_) {
            $class_storage = $codebase->classlikes->getStorageFor($fq_class_name);
            if ($class_storage && isset($class_storage->pseudo_methods[$method_name_lc])) {
                return [$class_storage->pseudo_methods[$method_name_lc], $class_storage];
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentMapPopulator;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\IfThisIsMismatch;
use Psalm\Issue\InvalidPropertyAssignmentValue;
use Psalm\Issue\MixedPropertyTypeCoercion;
use Psalm\Issue\PossiblyInvalidPropertyAssignmentValue;
use Psalm\Issue\PropertyTypeCoercion;
use Psalm\Issue\UndefinedThisPropertyAssignment;
use Psalm\Issue\UndefinedThisPropertyFetch;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualFuncCall;
use Psalm\Plugin\EventHandler\Event\AfterMethodCallAnalysisEvent;
use Psalm\Storage\Possibilities;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_map;
use function count;
use function explode;
use function in_array;
use function strtolower;
/**
 * @internal
 */
class ExistingAtomicMethodCallAnalyzer extends CallAnalyzer
{
    /**
     * @param  TNamedObject|TTemplateParam|null  $static_type
     * @param  list<PhpParser\Node\Arg> $args
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\MethodCall $stmt, PhpParser\Node\Identifier $stmt_name, array $args, Codebase $codebase, Context $context, TNamedObject $lhs_type_part, ?Atomic $static_type, ?string $lhs_var_id, MethodIdentifier $method_id, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result, ?TemplateResult $inferred_template_result = null) : Union
    {
        $config = $codebase->config;
        $fq_class_name = $lhs_type_part->value;
        if ($fq_class_name === 'static') {
            $fq_class_name = (string) $context->self;
        }
        $method_name_lc = $method_id->method_name;
        $cased_method_id = $fq_class_name . '::' . $stmt_name->name;
        $result->existent_method_ids[] = $method_id->__toString();
        if ($context->collect_initializations && $context->calling_method_id) {
            [$calling_method_class] = explode('::', $context->calling_method_id);
            $codebase->file_reference_provider->addMethodReferenceToClassMember($calling_method_class . '::__construct', strtolower((string) $method_id), \false);
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            ArgumentMapPopulator::recordArgumentPositions($statements_analyzer, $stmt, $codebase, (string) $method_id);
        }
        if ($fq_class_name === 'Closure' && $method_name_lc === '__invoke') {
            $statements_analyzer->node_data = clone $statements_analyzer->node_data;
            $fake_function_call = new VirtualFuncCall($stmt->var, $args, $stmt->getAttributes());
            FunctionCallAnalyzer::analyze($statements_analyzer, $fake_function_call, $context);
            return $statements_analyzer->node_data->getType($fake_function_call) ?? Type::getMixed();
        }
        $source = $statements_analyzer->getSource();
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt_name, $method_id . '()');
        }
        if ($context->collect_initializations && $context->calling_method_id) {
            [$calling_method_class] = explode('::', $context->calling_method_id);
            $codebase->file_reference_provider->addMethodReferenceToClassMember($calling_method_class . '::__construct', strtolower((string) $method_id), \false);
        }
        if ($stmt->var instanceof PhpParser\Node\Expr\Variable && ($context->collect_initializations || $context->collect_mutations) && $stmt->var->name === 'this' && $source instanceof FunctionLikeAnalyzer) {
            self::collectSpecialInformation($source, $stmt_name->name, $context);
        }
        $fq_class_name = $codebase->classlikes->getUnAliasedName($fq_class_name);
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $parent_source = $statements_analyzer->getSource();
        $class_template_params = ClassTemplateParamCollector::collect($codebase, $codebase->methods->getClassLikeStorageForMethod($method_id), $class_storage, $method_name_lc, $lhs_type_part, $lhs_var_id === '$this');
        if ($lhs_var_id === '$this' && $parent_source instanceof FunctionLikeAnalyzer) {
            $grandparent_source = $parent_source->getSource();
            if ($grandparent_source instanceof TraitAnalyzer) {
                $fq_trait_name = $grandparent_source->getFQCLN();
                $fq_trait_name_lc = strtolower($fq_trait_name);
                $trait_storage = $codebase->classlike_storage_provider->get($fq_trait_name_lc);
                if (isset($trait_storage->methods[$method_name_lc])) {
                    $trait_method_id = new MethodIdentifier($trait_storage->name, $method_name_lc);
                    $class_template_params = ClassTemplateParamCollector::collect($codebase, $codebase->methods->getClassLikeStorageForMethod($trait_method_id), $class_storage, $method_name_lc, $lhs_type_part, \true);
                }
            }
        }
        $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
        try {
            $method_storage = $codebase->methods->getStorage($declaring_method_id ?? $method_id);
        } catch (UnexpectedValueException $e) {
            $method_storage = null;
        }
        $method_template_params = [];
        if ($method_storage && $method_storage->if_this_is_type) {
            $method_template_result = new TemplateResult($method_storage->template_types ?: [], []);
            TemplateStandinTypeReplacer::fillTemplateResult($method_storage->if_this_is_type, $method_template_result, $codebase, null, new Union([$lhs_type_part]));
            $method_template_params = $method_template_result->lower_bounds;
        }
        $template_result = new TemplateResult([], $class_template_params ?: []);
        $template_result->lower_bounds += $method_template_params;
        if ($inferred_template_result) {
            $template_result->lower_bounds += $inferred_template_result->lower_bounds;
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            ArgumentMapPopulator::recordArgumentPositions($statements_analyzer, $stmt, $codebase, (string) $method_id);
        }
        $is_first_class_callable = $stmt->isFirstClassCallable();
        if (!$is_first_class_callable && self::checkMethodArgs($method_id, $args, $template_result, $context, new CodeLocation($source, $stmt_name), $statements_analyzer) === \false) {
            return Type::getMixed();
        }
        $return_type_candidate = \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallReturnTypeFetcher::fetch($statements_analyzer, $codebase, $stmt, $context, $method_id, $declaring_method_id, $method_id, $cased_method_id, $lhs_type_part, $static_type, $args, $result, $template_result);
        if ($is_first_class_callable) {
            return $return_type_candidate;
        }
        $in_call_map = InternalCallMapHandler::inCallMap((string) ($declaring_method_id ?? $method_id));
        if (!$in_call_map) {
            $name_code_location = new CodeLocation($statements_analyzer, $stmt_name);
            \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallProhibitionAnalyzer::analyze($codebase, $context, $method_id, $statements_analyzer->getFullyQualifiedFunctionMethodOrNamespaceName(), $name_code_location, $statements_analyzer->getSuppressedIssues());
            $getter_return_type = self::getMagicGetterOrSetterProperty($statements_analyzer, $stmt, $stmt_name, $context, $fq_class_name);
            if ($getter_return_type) {
                $return_type_candidate = $getter_return_type;
            }
        }
        if ($method_storage) {
            if ($method_storage->if_this_is_type) {
                $class_type = new Union([$lhs_type_part]);
                $if_this_is_type = TemplateInferredTypeReplacer::replace($method_storage->if_this_is_type, $template_result, $codebase);
                if (!UnionTypeComparator::isContainedBy($codebase, $class_type, $if_this_is_type)) {
                    IssueBuffer::maybeAdd(new IfThisIsMismatch('Class type must be ' . $method_storage->if_this_is_type->getId() . ' current type ' . $class_type->getId(), new CodeLocation($source, $stmt->name)), $statements_analyzer->getSuppressedIssues());
                }
            }
            if ($method_storage->self_out_type && $lhs_var_id) {
                $self_out_candidate = $method_storage->self_out_type;
                if ($template_result->lower_bounds) {
                    $self_out_candidate = TypeExpander::expandUnion($codebase, $self_out_candidate, $fq_class_name, null, $class_storage->parent_class, \true, \false, $static_type instanceof TNamedObject && $codebase->classlike_storage_provider->get($static_type->value)->final, \true);
                }
                $self_out_candidate = \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallReturnTypeFetcher::replaceTemplateTypes($self_out_candidate, $template_result, $method_id, count($args), $codebase);
                $self_out_candidate = TypeExpander::expandUnion($codebase, $self_out_candidate, $fq_class_name, $static_type, $class_storage->parent_class, \true, \false, $static_type instanceof TNamedObject && $codebase->classlike_storage_provider->get($static_type->value)->final, \true);
                $context->vars_in_scope[$lhs_var_id] = $self_out_candidate;
            }
            if (!$context->collect_mutations && !$context->collect_initializations) {
                \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallPurityAnalyzer::analyze($statements_analyzer, $codebase, $stmt, $lhs_var_id, $cased_method_id, $method_id, $method_storage, $class_storage, $context, $config, $result);
            }
            $has_packed_arg = \false;
            foreach ($args as $arg) {
                $has_packed_arg = $has_packed_arg || $arg->unpack;
            }
            if (!$has_packed_arg) {
                $has_variadic_param = $method_storage->variadic;
                foreach ($method_storage->params as $param) {
                    $has_variadic_param = $has_variadic_param || $param->is_variadic;
                }
                for ($i = count($args), $j = count($method_storage->params); $i < $j; ++$i) {
                    $param = $method_storage->params[$i];
                    if (!$param->is_optional && !$param->is_variadic && !$in_call_map) {
                        $result->too_few_arguments = \true;
                        $result->too_few_arguments_method_ids[] = $declaring_method_id ?? $method_id;
                    }
                }
                if ($has_variadic_param || count($method_storage->params) >= count($args) || $in_call_map) {
                    $result->too_many_arguments = \false;
                } else {
                    $result->too_many_arguments_method_ids[] = $declaring_method_id ?? $method_id;
                }
            }
            if ($method_storage->assertions) {
                self::applyAssertionsToContext($stmt_name, ExpressionIdentifier::getExtendedVarId($stmt->var, null, $statements_analyzer), $method_storage->assertions, $args, $template_result, $context, $statements_analyzer);
            }
            if ($method_storage->if_true_assertions) {
                $statements_analyzer->node_data->setIfTrueAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, $lhs_var_id, $codebase), $method_storage->if_true_assertions));
            }
            if ($method_storage->if_false_assertions) {
                $statements_analyzer->node_data->setIfFalseAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, $lhs_var_id, $codebase), $method_storage->if_false_assertions));
            }
        }
        if ($codebase->methods_to_rename) {
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
            foreach ($codebase->methods_to_rename as $original_method_id => $new_method_name) {
                if ($declaring_method_id && strtolower((string) $declaring_method_id) === $original_method_id) {
                    $file_manipulations = [new FileManipulation((int) $stmt_name->getAttribute('startFilePos'), (int) $stmt_name->getAttribute('endFilePos') + 1, $new_method_name)];
                    FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                }
            }
        }
        if ($config->eventDispatcher->hasAfterMethodCallAnalysisHandlers()) {
            $file_manipulations = [];
            $appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
            if ($appearing_method_id !== null && $declaring_method_id !== null) {
                $event = new AfterMethodCallAnalysisEvent($stmt, (string) $method_id, (string) $appearing_method_id, (string) $declaring_method_id, $context, $statements_analyzer, $codebase, $file_manipulations, $return_type_candidate);
                $config->eventDispatcher->dispatchAfterMethodCallAnalysis($event);
                $file_manipulations = $event->getFileReplacements();
                $return_type_candidate = $event->getReturnTypeCandidate();
            }
            if ($file_manipulations) {
                FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
            }
        }
        return $return_type_candidate ?? Type::getMixed();
    }
    /**
     * Check properties accessed with magic getters and setters.
     * If `@psalm-seal-properties` is set, they must be defined.
     * If an `@property` annotation is specified, the setter must set something with the correct
     * type.
     */
    private static function getMagicGetterOrSetterProperty(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\MethodCall $stmt, PhpParser\Node\Identifier $stmt_name, Context $context, string $fq_class_name) : ?Union
    {
        $method_name = strtolower($stmt_name->name);
        if (!in_array($method_name, ['__get', '__set'], \true)) {
            return null;
        }
        $codebase = $statements_analyzer->getCodebase();
        $first_arg_value = $stmt->getArgs()[0]->value ?? null;
        if (!$first_arg_value instanceof PhpParser\Node\Scalar\String_) {
            return null;
        }
        $prop_name = $first_arg_value->value;
        $property_id = $fq_class_name . '::$' . $prop_name;
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $codebase->properties->propertyExists($property_id, $method_name === '__get', $statements_analyzer, $context, new CodeLocation($statements_analyzer->getSource(), $stmt));
        switch ($method_name) {
            case '__set':
                // If `@psalm-seal-properties` is set, the property must be defined with
                // a `@property` annotation
                if (($class_storage->sealed_properties || $codebase->config->seal_all_properties) && !isset($class_storage->pseudo_property_set_types['$' . $prop_name])) {
                    IssueBuffer::maybeAdd(new UndefinedThisPropertyAssignment('Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                }
                // If a `@property` annotation is set, the type of the value passed to the
                // magic setter must match the annotation.
                $second_arg_type = isset($stmt->getArgs()[1]) ? $statements_analyzer->node_data->getType($stmt->getArgs()[1]->value) : null;
                if (isset($class_storage->pseudo_property_set_types['$' . $prop_name]) && $second_arg_type) {
                    $pseudo_set_type = TypeExpander::expandUnion($codebase, $class_storage->pseudo_property_set_types['$' . $prop_name], $fq_class_name, new TNamedObject($fq_class_name), $class_storage->parent_class);
                    $union_comparison_results = new TypeComparisonResult();
                    $type_match_found = UnionTypeComparator::isContainedBy($codebase, $second_arg_type, $pseudo_set_type, $second_arg_type->ignore_nullable_issues, $second_arg_type->ignore_falsable_issues, $union_comparison_results);
                    if ($union_comparison_results->type_coerced) {
                        if ($union_comparison_results->type_coerced_from_mixed) {
                            IssueBuffer::maybeAdd(new MixedPropertyTypeCoercion($prop_name . ' expects \'' . $pseudo_set_type->getId() . '\', ' . ' parent type `' . $second_arg_type . '` provided', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                        } else {
                            IssueBuffer::maybeAdd(new PropertyTypeCoercion($prop_name . ' expects \'' . $pseudo_set_type->getId() . '\', ' . ' parent type `' . $second_arg_type . '` provided', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                        }
                    }
                    if (!$type_match_found && !$union_comparison_results->type_coerced_from_mixed) {
                        if (UnionTypeComparator::canBeContainedBy($codebase, $second_arg_type, $pseudo_set_type)) {
                            IssueBuffer::maybeAdd(new PossiblyInvalidPropertyAssignmentValue($prop_name . ' with declared type \'' . $pseudo_set_type . '\' cannot be assigned possibly different type \'' . $second_arg_type . '\'', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                        } else {
                            IssueBuffer::maybeAdd(new InvalidPropertyAssignmentValue($prop_name . ' with declared type \'' . $pseudo_set_type . '\' cannot be assigned type \'' . $second_arg_type . '\'', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                        }
                    }
                }
                break;
            case '__get':
                // If `@psalm-seal-properties` is set, the property must be defined with
                // a `@property` annotation
                if (($class_storage->sealed_properties || $codebase->config->seal_all_properties) && !isset($class_storage->pseudo_property_get_types['$' . $prop_name])) {
                    IssueBuffer::maybeAdd(new UndefinedThisPropertyFetch('Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                }
                if (isset($class_storage->pseudo_property_get_types['$' . $prop_name])) {
                    return $class_storage->pseudo_property_get_types['$' . $prop_name];
                }
                break;
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\InstancePropertyAssignmentAnalyzer as AssignmentAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\UnusedMethodCall;
use Psalm\IssueBuffer;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
/**
 * @internal
 */
class MethodCallPurityAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\MethodCall $stmt, ?string $lhs_var_id, string $cased_method_id, MethodIdentifier $method_id, MethodStorage $method_storage, ClassLikeStorage $class_storage, Context $context, Config $config, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result) : void
    {
        $method_pure_compatible = $method_storage->external_mutation_free && $statements_analyzer->node_data->isPureCompatible($stmt->var);
        if ($context->pure && !$method_storage->mutation_free && !$method_pure_compatible) {
            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a non-mutation-free method ' . $cased_method_id . ' from a pure context', new CodeLocation($statements_analyzer, $stmt->name)), $statements_analyzer->getSuppressedIssues());
        } elseif ($context->mutation_free && !$method_storage->mutation_free && !$method_pure_compatible) {
            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating method ' . $cased_method_id . ' from a mutation-free context', new CodeLocation($statements_analyzer, $stmt->name)), $statements_analyzer->getSuppressedIssues());
        } elseif ($context->external_mutation_free && !$method_storage->mutation_free && $method_id->fq_class_name !== $context->self && !$method_pure_compatible) {
            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating method ' . $cased_method_id . ' from a mutation-free context', new CodeLocation($statements_analyzer, $stmt->name)), $statements_analyzer->getSuppressedIssues());
        } elseif (($method_storage->mutation_free || $method_storage->external_mutation_free && ($stmt->var->getAttribute('external_mutation_free', \false) || $stmt->var->getAttribute('pure', \false))) && !$context->inside_unset) {
            if ($method_storage->mutation_free && (!$method_storage->mutation_free_inferred || $method_storage->final || $method_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) && ($method_storage->immutable || $config->remember_property_assignments_after_call)) {
                if ($context->inside_conditional && !$method_storage->assertions && !$method_storage->if_true_assertions) {
                    $stmt->setAttribute('memoizable', \true);
                    if ($method_storage->immutable) {
                        $stmt->setAttribute('pure', \true);
                    }
                }
                $result->can_memoize = \true;
            }
            if ($codebase->find_unused_variables && !$context->inside_conditional && !$context->inside_general_use && !$context->inside_throw) {
                if (!$context->inside_assignment && !$context->inside_call && !$context->inside_return && !$method_storage->assertions && !$method_storage->if_true_assertions && !$method_storage->if_false_assertions && !$method_storage->throws) {
                    IssueBuffer::maybeAdd(new UnusedMethodCall('The call to ' . $cased_method_id . ' is not used', new CodeLocation($statements_analyzer, $stmt->name), (string) $method_id), $statements_analyzer->getSuppressedIssues());
                } elseif (!$method_storage->mutation_free_inferred) {
                    $stmt->setAttribute('pure', \true);
                }
            }
        }
        if ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations && !$method_storage->mutation_free && !$method_pure_compatible) {
            $statements_analyzer->getSource()->inferred_has_mutation = \true;
            $statements_analyzer->getSource()->inferred_impure = \true;
        }
        if (!$config->remember_property_assignments_after_call && !$method_storage->mutation_free && !$method_pure_compatible) {
            $context->removeMutableObjectVars();
        } elseif ($method_storage->this_property_mutations) {
            if (!$method_pure_compatible) {
                $context->removeMutableObjectVars(\true);
            }
            foreach ($method_storage->this_property_mutations as $name => $_) {
                $mutation_var_id = $lhs_var_id . '->' . $name;
                $this_property_didnt_exist = $lhs_var_id === '$this' && isset($context->vars_in_scope[$mutation_var_id]) && !isset($class_storage->declaring_property_ids[$name]);
                if ($this_property_didnt_exist) {
                    unset($context->vars_in_scope[$mutation_var_id]);
                } else {
                    $new_type = AssignmentAnalyzer::getExpandedPropertyType($codebase, $class_storage->name, $name, $class_storage) ?? Type::getMixed();
                    $context->vars_in_scope[$mutation_var_id] = $new_type;
                    $context->possibly_assigned_var_ids[$mutation_var_id] = \true;
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use Psalm\Internal\MethodIdentifier;
use Psalm\Type\Union;
/**
 * @internal
 */
class AtomicMethodCallAnalysisResult
{
    public ?Union $return_type = null;
    public bool $returns_by_ref = \false;
    public bool $has_mock = \false;
    public bool $has_valid_method_call_type = \false;
    public bool $has_mixed_method_call = \false;
    /**
     * @var array<string>
     */
    public array $invalid_method_call_types = [];
    /**
     * @var array<string>
     */
    public array $existent_method_ids = [];
    /**
     * @var array<string>
     */
    public array $non_existent_class_method_ids = [];
    /**
     * @var array<string>
     */
    public array $non_existent_interface_method_ids = [];
    /**
     * @var array<string>
     */
    public array $non_existent_magic_method_ids = [];
    public bool $check_visibility = \true;
    public bool $too_many_arguments = \true;
    /**
     * @var list<MethodIdentifier>
     */
    public array $too_many_arguments_method_ids = [];
    public bool $too_few_arguments = \false;
    /**
     * @var list<MethodIdentifier>
     */
    public array $too_few_arguments_method_ids = [];
    public bool $can_memoize = \false;
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\MethodIdentifier;
/**
 * @internal
 */
class AtomicCallContext
{
    public MethodIdentifier $method_id;
    /** @var list<PhpParser\Node\Arg> */
    public array $args;
    /** @param list<PhpParser\Node\Arg> $args */
    public function __construct(MethodIdentifier $method_id, array $args)
    {
        $this->method_id = $method_id;
        $this->args = $args;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\MethodAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\MixedMethodCall;
use Psalm\IssueBuffer;
use Psalm\StatementsSource;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyMixed;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_keys;
use function array_merge;
use function array_search;
use function array_shift;
use function array_values;
use function count;
use function get_class;
use function reset;
use function strtolower;
/**
 * This is a bunch of complex logic to handle the potential for missing methods,
 * use of intersection types and/or mixins, together with handling for fallback magic
 * methods.
 *
 * The happy path (i.e 99% of method calls) is handled in ExistingAtomicMethodCallAnalyzer
 *
 * @internal
 */
class AtomicMethodCallAnalyzer extends CallAnalyzer
{
    /**
     * @param  TNamedObject|TTemplateParam|null $static_type
     * @psalm-suppress ComplexMethod it's really complex, but unavoidably so
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\MethodCall $stmt, Codebase $codebase, Context $context, Union $lhs_type, Atomic $lhs_type_part, ?Atomic $static_type, bool $is_intersection, ?string $lhs_var_id, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result, ?TemplateResult $inferred_template_result = null) : void
    {
        if ($lhs_type_part instanceof TTemplateParam && !$lhs_type_part->as->isMixed()) {
            $extra_types = $lhs_type_part->extra_types;
            $lhs_type_part = array_values($lhs_type_part->as->getAtomicTypes())[0];
            if ($lhs_type_part instanceof TNamedObject) {
                $lhs_type_part = $lhs_type_part->setIntersectionTypes($extra_types)->setFromDocblock(\true);
            } elseif ($lhs_type_part instanceof TObject && $extra_types) {
                $lhs_type_part = array_shift($extra_types)->setFromDocblock(\true);
                if ($extra_types) {
                    $lhs_type_part = $lhs_type_part->setIntersectionTypes($extra_types);
                }
            } else {
                $lhs_type_part = $lhs_type_part->setFromDocblock(\true);
            }
            $result->has_mixed_method_call = \true;
        }
        $source = $statements_analyzer->getSource();
        if (!$lhs_type_part instanceof TNamedObject) {
            self::handleInvalidClass($statements_analyzer, $codebase, $stmt, $lhs_type, $lhs_type_part, $lhs_var_id, $context, $is_intersection, $result);
            return;
        }
        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
            $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
        }
        $result->has_valid_method_call_type = \true;
        $fq_class_name = $lhs_type_part->value;
        $is_mock = ExpressionAnalyzer::isMock($fq_class_name);
        $result->has_mock = $result->has_mock || $is_mock;
        if ($fq_class_name === 'static') {
            $fq_class_name = (string) $context->self;
        }
        if ($is_mock || $context->isPhantomClass($fq_class_name)) {
            $result->return_type = Type::getMixed();
            ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
            return;
        }
        if ($lhs_var_id === '$this') {
            $does_class_exist = \true;
        } else {
            $does_class_exist = ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($source, $stmt->var), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true, \false, \true, \true, $lhs_type_part->from_docblock));
        }
        if (!$does_class_exist) {
            return;
        }
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $result->check_visibility = $result->check_visibility && !$class_storage->override_method_visibility;
        $intersection_types = $lhs_type_part->getIntersectionTypes();
        if (!$stmt->name instanceof PhpParser\Node\Identifier) {
            if (!$context->ignore_variable_method) {
                $codebase->analyzer->addMixedMemberName(strtolower($fq_class_name) . '::', $context->calling_method_id ?: $statements_analyzer->getFileName());
            }
            if ($stmt->isFirstClassCallable()) {
                $return_type_candidate = null;
                $method_name_type = $statements_analyzer->node_data->getType($stmt->name);
                if ($method_name_type && $method_name_type->isSingleStringLiteral()) {
                    $method_identifier = new MethodIdentifier($fq_class_name, strtolower($method_name_type->getSingleStringLiteral()->value));
                    //the call to methodExists will register that the method was called from somewhere
                    if ($codebase->methods->methodExists($method_identifier, $context->calling_method_id, null, $statements_analyzer, $statements_analyzer->getFilePath(), \true, $context->insideUse())) {
                        $method_storage = $codebase->methods->getStorage($method_identifier);
                        $return_type_candidate = new Union([new TClosure('Closure', $method_storage->params, $method_storage->return_type, $method_storage->pure)]);
                    }
                }
                $statements_analyzer->node_data->setType($stmt, $return_type_candidate ?? Type::getClosure());
                return;
            }
            ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context);
            $result->return_type = Type::getMixed();
            return;
        }
        $method_name_lc = strtolower($stmt->name->name);
        $method_id = new MethodIdentifier($fq_class_name, $method_name_lc);
        $args = $stmt->isFirstClassCallable() ? [] : $stmt->getArgs();
        $naive_method_id = $method_id;
        // this tells us whether or not we can stay on the happy path
        $naive_method_exists = $codebase->methods->methodExists($method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($source, $stmt->name) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath(), \false, $context->insideUse());
        $fake_method_exists = \false;
        if (!$naive_method_exists) {
            // if the method doesn't exist we check for any method existence providers
            if ($codebase->methods->existence_provider->has($fq_class_name)) {
                $method_exists = $codebase->methods->existence_provider->doesMethodExist($fq_class_name, $method_id->method_name, $source, null);
                if ($method_exists) {
                    $fake_method_exists = \true;
                }
            }
            $naive_method_exists = \false;
            // @mixin attributes are an absolute pain! Lots of complexity here,
            // as they can redefine the called class, method id etc.
            if ($class_storage->templatedMixins && $lhs_type_part instanceof TGenericObject && $class_storage->template_types) {
                [$lhs_type_part, $class_storage, $naive_method_exists, $method_id, $fq_class_name] = self::handleTemplatedMixins($class_storage, $lhs_type_part, $method_name_lc, $codebase, $context, $method_id, $source, $stmt, $statements_analyzer, $fq_class_name);
            } elseif ($class_storage->mixin_declaring_fqcln && $class_storage->namedMixins) {
                [$lhs_type_part, $class_storage, $naive_method_exists, $method_id, $fq_class_name] = self::handleRegularMixins($class_storage, $lhs_type_part, $method_name_lc, $codebase, $context, $method_id, $source, $stmt, $statements_analyzer, $fq_class_name, $lhs_var_id);
            }
        }
        $all_intersection_return_type = null;
        $all_intersection_existent_method_ids = [];
        // insersection types are also fun, they also complicate matters
        if ($intersection_types) {
            [$all_intersection_return_type, $all_intersection_existent_method_ids] = self::getIntersectionReturnType($statements_analyzer, $stmt, $codebase, $context, $lhs_type, $lhs_type_part, $lhs_var_id, $result, $intersection_types);
        }
        if ($fake_method_exists && $codebase->methods->methodExists(new MethodIdentifier($fq_class_name, '__call')) || !$naive_method_exists || !MethodAnalyzer::isMethodVisible($method_id, $context, $statements_analyzer->getSource())) {
            $interface_has_method = \false;
            if ($class_storage->abstract && $class_storage->class_implements) {
                foreach ($class_storage->class_implements as $interface_fqcln_lc => $_) {
                    $interface_storage = $codebase->classlike_storage_provider->get($interface_fqcln_lc);
                    if (isset($interface_storage->methods[$method_name_lc])) {
                        $interface_has_method = \true;
                        $fq_class_name = $interface_storage->name;
                        $method_id = new MethodIdentifier($fq_class_name, $method_name_lc);
                        break;
                    }
                }
            }
            if (!$interface_has_method && $codebase->methods->methodExists(new MethodIdentifier($fq_class_name, '__call'), $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($source, $stmt->name) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath(), \true, $context->insideUse())) {
                $new_call_context = \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MissingMethodCallHandler::handleMagicMethod($statements_analyzer, $codebase, $stmt, $method_id, $class_storage, $context, $codebase->config, $all_intersection_return_type, $result, $lhs_type_part);
                if ($new_call_context) {
                    if ($method_id === $new_call_context->method_id) {
                        return;
                    }
                    $method_id = $new_call_context->method_id;
                    $args = $new_call_context->args;
                } else {
                    return;
                }
            }
        }
        $intersection_method_id = $intersection_types ? '(' . $lhs_type_part . ')' . '::' . $stmt->name->name : null;
        $cased_method_id = $fq_class_name . '::' . $stmt->name->name;
        if ($lhs_var_id === '$this' && $context->self && $fq_class_name !== $context->self && $codebase->methods->methodExists(new MethodIdentifier($context->self, $method_name_lc))) {
            $method_id = new MethodIdentifier($context->self, $method_name_lc);
            $cased_method_id = $context->self . '::' . $stmt->name->name;
            $fq_class_name = $context->self;
        }
        $source_method_id = $source instanceof FunctionLikeAnalyzer ? $source->getId() : null;
        $corrected_method_exists = $naive_method_exists && $method_id === $naive_method_id || $method_id !== $naive_method_id && $codebase->methods->methodExists($method_id, $context->calling_method_id, $codebase->collect_locations && $method_id !== $source_method_id ? new CodeLocation($source, $stmt->name) : null);
        if (!$corrected_method_exists || $codebase->config->use_phpdoc_method_without_magic_or_parent && isset($class_storage->pseudo_methods[$method_name_lc])) {
            \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MissingMethodCallHandler::handleMissingOrMagicMethod($statements_analyzer, $codebase, $stmt, $method_id, $codebase->interfaceExists($fq_class_name), $context, $codebase->config, $all_intersection_return_type, $all_intersection_existent_method_ids, $intersection_method_id, $cased_method_id, $result, $lhs_type_part);
            return;
        }
        $old_node_data = $statements_analyzer->node_data;
        $return_type_candidate = \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\ExistingAtomicMethodCallAnalyzer::analyze($statements_analyzer, $stmt, $stmt->name, $args, $codebase, $context, $lhs_type_part, $static_type, $lhs_var_id, $method_id, $result, $inferred_template_result);
        $statements_analyzer->node_data = $old_node_data;
        $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
        $in_call_map = InternalCallMapHandler::inCallMap((string) ($declaring_method_id ?? $method_id));
        if (!$in_call_map) {
            if ($result->check_visibility) {
                $name_code_location = new CodeLocation($statements_analyzer, $stmt->name);
                \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodVisibilityAnalyzer::analyze($method_id, $context, $statements_analyzer->getSource(), $name_code_location, $statements_analyzer->getSuppressedIssues());
            }
        }
        self::updateResultReturnType($result, $return_type_candidate, $all_intersection_return_type, $codebase);
    }
    /**
     * @param  TNamedObject|TTemplateParam $lhs_type_part
     * @param   array<string, Atomic> $intersection_types
     * @return  array{?Union, array<string>}
     */
    private static function getIntersectionReturnType(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\MethodCall $stmt, Codebase $codebase, Context $context, Union $lhs_type, Atomic $lhs_type_part, ?string $lhs_var_id, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result, array $intersection_types) : array
    {
        $all_intersection_return_type = null;
        $all_intersection_existent_method_ids = [];
        foreach ($intersection_types as $intersection_type) {
            $intersection_result = clone $result;
            /** @var ?Union $intersection_result->return_type */
            $intersection_result->return_type = null;
            self::analyze($statements_analyzer, $stmt, $codebase, $context, $lhs_type, $intersection_type, $lhs_type_part, \true, $lhs_var_id, $intersection_result);
            $result->returns_by_ref = $intersection_result->returns_by_ref;
            $result->has_mock = $intersection_result->has_mock;
            $result->has_valid_method_call_type = $intersection_result->has_valid_method_call_type;
            $result->has_mixed_method_call = $intersection_result->has_mixed_method_call;
            $result->invalid_method_call_types = $intersection_result->invalid_method_call_types;
            $result->check_visibility = $intersection_result->check_visibility;
            $result->too_many_arguments = $intersection_result->too_many_arguments;
            $all_intersection_existent_method_ids = array_merge($all_intersection_existent_method_ids, $intersection_result->existent_method_ids);
            if ($intersection_result->return_type) {
                if (!$all_intersection_return_type || $all_intersection_return_type->isMixed()) {
                    $all_intersection_return_type = $intersection_result->return_type;
                } else {
                    $all_intersection_return_type = Type::intersectUnionTypes($all_intersection_return_type, $intersection_result->return_type, $codebase) ?? Type::getMixed();
                }
            }
        }
        return [$all_intersection_return_type, $all_intersection_existent_method_ids];
    }
    private static function updateResultReturnType(\Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result, Union $return_type_candidate, ?Union $all_intersection_return_type, Codebase $codebase) : void
    {
        if ($all_intersection_return_type) {
            $return_type_candidate = Type::intersectUnionTypes($all_intersection_return_type, $return_type_candidate, $codebase) ?? Type::getMixed();
        }
        $result->return_type = Type::combineUnionTypes($return_type_candidate, $result->return_type);
    }
    private static function handleInvalidClass(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\MethodCall $stmt, Union $lhs_type, Atomic $lhs_type_part, ?string $lhs_var_id, Context $context, bool $is_intersection, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result) : void
    {
        switch (get_class($lhs_type_part)) {
            case TNull::class:
            case TFalse::class:
                // handled above
                return;
            case TTemplateParam::class:
            case TEmptyMixed::class:
            case TNever::class:
            case TMixed::class:
            case TNonEmptyMixed::class:
            case TObject::class:
            case TObjectWithProperties::class:
                if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                    $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
                }
                $result->has_mixed_method_call = \true;
                if ($lhs_type_part instanceof TObjectWithProperties && $stmt->name instanceof PhpParser\Node\Identifier && isset($lhs_type_part->methods[strtolower($stmt->name->name)])) {
                    $result->existent_method_ids[] = $lhs_type_part->methods[strtolower($stmt->name->name)];
                } elseif (!$is_intersection) {
                    if ($stmt->name instanceof PhpParser\Node\Identifier) {
                        $codebase->analyzer->addMixedMemberName(strtolower($stmt->name->name), $context->calling_method_id ?: $statements_analyzer->getFileName());
                    }
                    if ($context->check_methods) {
                        $message = 'Cannot determine the type of the object' . ' on the left hand side of this expression';
                        if ($lhs_var_id) {
                            $message = 'Cannot determine the type of ' . $lhs_var_id;
                            if ($stmt->name instanceof PhpParser\Node\Identifier) {
                                $message .= ' when calling method ' . $stmt->name->name;
                            }
                        }
                        $origin_locations = [];
                        if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                            foreach ($lhs_type->parent_nodes as $parent_node) {
                                $origin_locations = [...$origin_locations, ...$statements_analyzer->data_flow_graph->getOriginLocations($parent_node)];
                            }
                        }
                        $origin_location = count($origin_locations) === 1 ? reset($origin_locations) : null;
                        $name_code_location = new CodeLocation($statements_analyzer, $stmt->name);
                        if ($origin_location && $origin_location->getHash() === $name_code_location->getHash()) {
                            $origin_location = null;
                        }
                        IssueBuffer::maybeAdd(new MixedMethodCall($message, $name_code_location, $origin_location), $statements_analyzer->getSuppressedIssues());
                    }
                }
                if ($stmt->isFirstClassCallable()) {
                    $result->return_type = Type::getClosure();
                } else {
                    if (ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context) === \false) {
                        return;
                    }
                    $result->return_type = Type::getMixed();
                }
                return;
            default:
                $result->invalid_method_call_types[] = (string) $lhs_type_part;
                return;
        }
    }
    /**
     * @param lowercase-string $method_name_lc
     * @return array{TNamedObject, ClassLikeStorage, bool, MethodIdentifier, string}
     */
    private static function handleTemplatedMixins(ClassLikeStorage $class_storage, TNamedObject $lhs_type_part, string $method_name_lc, Codebase $codebase, Context $context, MethodIdentifier $method_id, StatementsSource $source, PhpParser\Node\Expr\MethodCall $stmt, StatementsAnalyzer $statements_analyzer, string $fq_class_name) : array
    {
        $naive_method_exists = \false;
        if ($class_storage->templatedMixins && $lhs_type_part instanceof TGenericObject && $class_storage->template_types) {
            $template_type_keys = array_keys($class_storage->template_types);
            foreach ($class_storage->templatedMixins as $mixin) {
                $param_position = array_search($mixin->param_name, $template_type_keys);
                if ($param_position !== \false && isset($lhs_type_part->type_params[$param_position])) {
                    $current_type_param = $lhs_type_part->type_params[$param_position];
                    if ($current_type_param->isSingle()) {
                        $lhs_type_part_new = array_values($current_type_param->getAtomicTypes())[0];
                        if ($lhs_type_part_new instanceof TNamedObject) {
                            $new_method_id = new MethodIdentifier($lhs_type_part_new->value, $method_name_lc);
                            $mixin_class_storage = $codebase->classlike_storage_provider->get($lhs_type_part_new->value);
                            if ($codebase->methods->methodExists($new_method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($source, $stmt->name) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath(), \true, $context->insideUse())) {
                                $lhs_type_part = $lhs_type_part_new;
                                $class_storage = $mixin_class_storage;
                                $naive_method_exists = \true;
                                $method_id = $new_method_id;
                            } elseif (isset($mixin_class_storage->pseudo_methods[$method_name_lc])) {
                                $lhs_type_part = $lhs_type_part_new;
                                $class_storage = $mixin_class_storage;
                                $method_id = $new_method_id;
                            }
                        }
                    }
                }
            }
        }
        return [$lhs_type_part, $class_storage, $naive_method_exists, $method_id, $fq_class_name];
    }
    /**
     * @param lowercase-string $method_name_lc
     * @return array{TNamedObject, ClassLikeStorage, bool, MethodIdentifier, string}
     */
    private static function handleRegularMixins(ClassLikeStorage $class_storage, TNamedObject $lhs_type_part, string $method_name_lc, Codebase $codebase, Context $context, MethodIdentifier $method_id, StatementsSource $source, PhpParser\Node\Expr\MethodCall $stmt, StatementsAnalyzer $statements_analyzer, string $fq_class_name, ?string $lhs_var_id) : array
    {
        $naive_method_exists = \false;
        foreach ($class_storage->namedMixins as $mixin) {
            if (!$class_storage->mixin_declaring_fqcln) {
                continue;
            }
            $new_method_id = new MethodIdentifier($mixin->value, $method_name_lc);
            if ($codebase->methods->methodExists($new_method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($source, $stmt->name) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath(), \true, $context->insideUse())) {
                $mixin_declaring_class_storage = $codebase->classlike_storage_provider->get($class_storage->mixin_declaring_fqcln);
                $mixin_class_template_params = ClassTemplateParamCollector::collect($codebase, $mixin_declaring_class_storage, $codebase->classlike_storage_provider->get($fq_class_name), null, $lhs_type_part, $lhs_var_id === '$this');
                $lhs_type_part = $mixin->replaceTemplateTypesWithArgTypes(new TemplateResult([], $mixin_class_template_params ?: []), $codebase);
                $lhs_type_expanded = TypeExpander::expandUnion($codebase, new Union([$lhs_type_part]), $mixin_declaring_class_storage->name, $fq_class_name, $class_storage->parent_class, \true, \false, $class_storage->final);
                $new_lhs_type_part = $lhs_type_expanded->getSingleAtomic();
                if ($new_lhs_type_part instanceof TNamedObject) {
                    $lhs_type_part = $new_lhs_type_part;
                }
                $mixin_class_storage = $codebase->classlike_storage_provider->get($mixin->value);
                $fq_class_name = $mixin_class_storage->name;
                $mixin_class_storage->mixin_declaring_fqcln = $class_storage->mixin_declaring_fqcln;
                $class_storage = $mixin_class_storage;
                $naive_method_exists = \true;
                $method_id = $new_method_id;
            }
        }
        return [$lhs_type_part, $class_storage, $naive_method_exists, $method_id, $fq_class_name];
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\Method;

use Exception;
use PDOException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallReturnTypeFetcher;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\TaintSource;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TemplateBound;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use RuntimeException;
use Throwable;
use UnexpectedValueException;
use function array_filter;
use function count;
use function in_array;
use function strtolower;
/**
 * @internal
 */
class MethodCallReturnTypeFetcher
{
    /**
     * @param  TNamedObject|TTemplateParam|null  $static_type
     * @param list<PhpParser\Node\Arg> $args
     */
    public static function fetch(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\MethodCall $stmt, Context $context, MethodIdentifier $method_id, ?MethodIdentifier $declaring_method_id, MethodIdentifier $premixin_method_id, string $cased_method_id, Atomic $lhs_type_part, ?Atomic $static_type, array $args, \Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult $result, TemplateResult $template_result) : Union
    {
        $call_map_id = $declaring_method_id ?? $method_id;
        $fq_class_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        $class_storage = $codebase->methods->getClassLikeStorageForMethod($method_id);
        $method_storage = $class_storage->methods[$method_id->method_name] ?? null;
        if ($stmt->isFirstClassCallable()) {
            if ($method_storage) {
                return new Union([new TClosure('Closure', $method_storage->params, $method_storage->return_type, $method_storage->pure)]);
            }
            return Type::getClosure();
        }
        if ($codebase->methods->return_type_provider->has($premixin_method_id->fq_class_name)) {
            $return_type_candidate = $codebase->methods->return_type_provider->getReturnType($statements_analyzer, $premixin_method_id->fq_class_name, $premixin_method_id->method_name, $stmt, $context, new CodeLocation($statements_analyzer->getSource(), $stmt->name), $lhs_type_part instanceof TGenericObject ? $lhs_type_part->type_params : null);
            if ($return_type_candidate) {
                return $return_type_candidate;
            }
        }
        if ($premixin_method_id->method_name === 'getcode' && $premixin_method_id->fq_class_name !== Exception::class && $premixin_method_id->fq_class_name !== RuntimeException::class && $premixin_method_id->fq_class_name !== PDOException::class && ($codebase->classImplements($premixin_method_id->fq_class_name, Throwable::class) || $codebase->interfaceExtends($premixin_method_id->fq_class_name, Throwable::class))) {
            return Type::getInt();
        }
        if ($declaring_method_id && $declaring_method_id !== $method_id) {
            $declaring_fq_class_name = $declaring_method_id->fq_class_name;
            $declaring_method_name = $declaring_method_id->method_name;
            if ($codebase->methods->return_type_provider->has($declaring_fq_class_name)) {
                $return_type_candidate = $codebase->methods->return_type_provider->getReturnType($statements_analyzer, $declaring_fq_class_name, $declaring_method_name, $stmt, $context, new CodeLocation($statements_analyzer->getSource(), $stmt->name), $lhs_type_part instanceof TGenericObject ? $lhs_type_part->type_params : null, $fq_class_name, $method_name);
                if ($return_type_candidate) {
                    return $return_type_candidate;
                }
            }
        }
        if (InternalCallMapHandler::inCallMap((string) $call_map_id)) {
            if (($template_result->lower_bounds || $class_storage->stubbed) && ($method_storage = $class_storage->methods[$method_id->method_name] ?? null) && $method_storage->return_type) {
                $return_type_candidate = $method_storage->return_type;
                $return_type_candidate = self::replaceTemplateTypes($return_type_candidate, $template_result, $method_id, count($stmt->getArgs()), $codebase);
            } else {
                $callmap_callables = InternalCallMapHandler::getCallablesFromCallMap((string) $call_map_id);
                if (!$callmap_callables || $callmap_callables[0]->return_type === null) {
                    throw new UnexpectedValueException('Shouldn’t get here');
                }
                $return_type_candidate = $callmap_callables[0]->return_type;
            }
            if ($return_type_candidate->isFalsable()) {
                $return_type_candidate = $return_type_candidate->setProperties(['ignore_falsable_issues' => \true]);
            }
            $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, $fq_class_name, $static_type, $class_storage->parent_class, \true, \false, \false, \true);
        } else {
            $self_fq_class_name = $fq_class_name;
            $return_type_candidate = $codebase->methods->getMethodReturnType($method_id, $self_fq_class_name, $statements_analyzer, $args);
            if ($return_type_candidate) {
                if ($template_result->lower_bounds) {
                    $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, $fq_class_name, null, $class_storage->parent_class, \true, \false, $static_type instanceof TNamedObject && $codebase->classlike_storage_provider->get($static_type->value)->final, \true);
                }
                $return_type_candidate = self::replaceTemplateTypes($return_type_candidate, $template_result, $method_id, count($stmt->getArgs()), $codebase);
                $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, $self_fq_class_name, $static_type, $class_storage->parent_class, \true, \false, $static_type instanceof TNamedObject && $codebase->classlike_storage_provider->get($static_type->value)->final, \true);
                $return_type_location = $codebase->methods->getMethodReturnTypeLocation($method_id, $secondary_return_type_location);
                if ($secondary_return_type_location) {
                    $return_type_location = $secondary_return_type_location;
                }
                $config = Config::getInstance();
                // only check the type locally if it's defined externally
                if ($return_type_location && !$config->isInProjectDirs($return_type_location->file_path)) {
                    /** @psalm-suppress UnusedMethodCall Actually generates issues */
                    $return_type_candidate->check($statements_analyzer, new CodeLocation($statements_analyzer, $stmt), $statements_analyzer->getSuppressedIssues(), $context->phantom_classes, \true, \false, \false, $context->calling_method_id);
                }
            } else {
                $result->returns_by_ref = $result->returns_by_ref || $codebase->methods->getMethodReturnsByRef($method_id);
            }
        }
        if (!$return_type_candidate) {
            $return_type_candidate = $method_name === '__tostring' ? Type::getString() : Type::getMixed();
        }
        self::taintMethodCallResult($statements_analyzer, $return_type_candidate, $stmt->name, $stmt->var, $args, $method_id, $declaring_method_id, $cased_method_id, $context);
        return $return_type_candidate;
    }
    /**
     * @param  array<PhpParser\Node\Arg>   $args
     */
    public static function taintMethodCallResult(StatementsAnalyzer $statements_analyzer, Union &$return_type_candidate, PhpParser\Node $name_expr, PhpParser\Node\Expr $var_expr, array $args, MethodIdentifier $method_id, ?MethodIdentifier $declaring_method_id, string $cased_method_id, Context $context) : void
    {
        if (!$statements_analyzer->data_flow_graph || !$declaring_method_id) {
            return;
        }
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
            return;
        }
        $codebase = $statements_analyzer->getCodebase();
        $event = new AddRemoveTaintsEvent($var_expr, $context, $statements_analyzer, $codebase);
        $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
        $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
        $method_storage = $codebase->methods->getStorage($declaring_method_id);
        $node_location = new CodeLocation($statements_analyzer, $name_expr);
        $is_declaring = (string) $declaring_method_id === (string) $method_id;
        $var_id = ExpressionIdentifier::getExtendedVarId($var_expr, null, $statements_analyzer);
        if ($method_storage->specialize_call && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            if ($var_id && isset($context->vars_in_scope[$var_id])) {
                $var_nodes = [];
                $parent_nodes = $context->vars_in_scope[$var_id]->parent_nodes;
                $unspecialized_parent_nodes = array_filter($parent_nodes, static fn(DataFlowNode $parent_node): bool => !$parent_node->specialization_key);
                $specialized_parent_nodes = array_filter($parent_nodes, static fn(DataFlowNode $parent_node): bool => (bool) $parent_node->specialization_key);
                $var_node = DataFlowNode::getForAssignment($var_id, new CodeLocation($statements_analyzer, $var_expr));
                if ($method_storage->location) {
                    $this_parent_node = DataFlowNode::getForAssignment('$this in ' . $method_id, $method_storage->location);
                    foreach ($parent_nodes as $parent_node) {
                        $statements_analyzer->data_flow_graph->addPath($parent_node, $this_parent_node, '=', $added_taints, $removed_taints);
                    }
                }
                $var_nodes[$var_node->id] = $var_node;
                $method_call_nodes = [];
                if ($unspecialized_parent_nodes) {
                    $method_call_node = DataFlowNode::getForMethodReturn((string) $method_id, $cased_method_id, $is_declaring ? $method_storage->signature_return_type_location ?: $method_storage->location : null, $node_location);
                    $method_call_nodes[$method_call_node->id] = $method_call_node;
                }
                foreach ($specialized_parent_nodes as $parent_node) {
                    $universal_method_call_node = DataFlowNode::getForMethodReturn((string) $method_id, $cased_method_id, $is_declaring ? $method_storage->signature_return_type_location ?: $method_storage->location : null, null);
                    $method_call_node = new DataFlowNode(strtolower((string) $method_id), $cased_method_id, $is_declaring ? $method_storage->signature_return_type_location ?: $method_storage->location : null, $parent_node->specialization_key);
                    $statements_analyzer->data_flow_graph->addPath($universal_method_call_node, $method_call_node, '=', $added_taints, $removed_taints);
                    $method_call_nodes[$method_call_node->id] = $method_call_node;
                }
                if (!$method_call_nodes) {
                    return;
                }
                foreach ($method_call_nodes as $method_call_node) {
                    $statements_analyzer->data_flow_graph->addNode($method_call_node);
                    foreach ($var_nodes as $var_node) {
                        $statements_analyzer->data_flow_graph->addNode($var_node);
                        $statements_analyzer->data_flow_graph->addPath($method_call_node, $var_node, 'method-call-' . $method_id->method_name, $added_taints, $removed_taints);
                    }
                    if (!$is_declaring) {
                        $cased_declaring_method_id = $codebase->methods->getCasedMethodId($declaring_method_id);
                        $declaring_method_call_node = new DataFlowNode(strtolower((string) $declaring_method_id), $cased_declaring_method_id, $method_storage->signature_return_type_location ?: $method_storage->location, $method_call_node->specialization_key);
                        $statements_analyzer->data_flow_graph->addNode($declaring_method_call_node);
                        $statements_analyzer->data_flow_graph->addPath($declaring_method_call_node, $method_call_node, 'parent', $added_taints, $removed_taints);
                    }
                }
                $return_type_candidate = $return_type_candidate->setParentNodes($method_call_nodes);
                $stmt_var_type = $context->vars_in_scope[$var_id]->setParentNodes($var_nodes);
                $context->vars_in_scope[$var_id] = $stmt_var_type;
            } else {
                $method_call_node = DataFlowNode::getForMethodReturn((string) $method_id, $cased_method_id, $is_declaring ? $method_storage->signature_return_type_location ?: $method_storage->location : null, $node_location);
                if (!$is_declaring) {
                    $cased_declaring_method_id = $codebase->methods->getCasedMethodId($declaring_method_id);
                    $declaring_method_call_node = DataFlowNode::getForMethodReturn((string) $declaring_method_id, $cased_declaring_method_id, $method_storage->signature_return_type_location ?: $method_storage->location, $node_location);
                    $statements_analyzer->data_flow_graph->addNode($declaring_method_call_node);
                    $statements_analyzer->data_flow_graph->addPath($declaring_method_call_node, $method_call_node, 'parent', $added_taints, $removed_taints);
                }
                $statements_analyzer->data_flow_graph->addNode($method_call_node);
                $return_type_candidate = $return_type_candidate->setParentNodes([$method_call_node->id => $method_call_node]);
            }
        } else {
            $method_call_node = DataFlowNode::getForMethodReturn((string) $method_id, $cased_method_id, $is_declaring ? $statements_analyzer->data_flow_graph instanceof TaintFlowGraph ? $method_storage->signature_return_type_location ?: $method_storage->location : ($method_storage->return_type_location ?: $method_storage->location) : null, null);
            if (!$is_declaring) {
                $cased_declaring_method_id = $codebase->methods->getCasedMethodId($declaring_method_id);
                $declaring_method_call_node = DataFlowNode::getForMethodReturn((string) $declaring_method_id, $cased_declaring_method_id, $method_storage->signature_return_type_location ?: $method_storage->location, null);
                $statements_analyzer->data_flow_graph->addNode($declaring_method_call_node);
                $statements_analyzer->data_flow_graph->addPath($declaring_method_call_node, $method_call_node, 'parent', $added_taints, $removed_taints);
            }
            $statements_analyzer->data_flow_graph->addNode($method_call_node);
            $return_type_candidate = $return_type_candidate->setParentNodes([$method_call_node->id => $method_call_node]);
        }
        if (!$statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            return;
        }
        if ($method_storage->taint_source_types) {
            $method_node = TaintSource::getForMethodReturn((string) $method_id, $cased_method_id, $method_storage->signature_return_type_location ?: $method_storage->location);
            $method_node->taints = $method_storage->taint_source_types;
            $statements_analyzer->data_flow_graph->addSource($method_node);
        }
        FunctionCallReturnTypeFetcher::taintUsingFlows($statements_analyzer, $method_storage, $statements_analyzer->data_flow_graph, (string) $method_id, $args, $node_location, $method_call_node, $method_storage->removed_taints);
    }
    public static function replaceTemplateTypes(Union $return_type_candidate, TemplateResult $template_result, MethodIdentifier $method_id, int $arg_count, Codebase $codebase) : Union
    {
        if ($template_result->template_types) {
            $bindable_template_types = $return_type_candidate->getTemplateTypes();
            foreach ($bindable_template_types as $template_type) {
                if ($template_type->defining_class !== $method_id->fq_class_name && !isset($template_result->lower_bounds[$template_type->param_name][$template_type->defining_class])) {
                    if ($template_type->param_name === 'TFunctionArgCount') {
                        $template_result->lower_bounds[$template_type->param_name] = ['fn-' . strtolower((string) $method_id) => [new TemplateBound(Type::getInt(\false, $arg_count))]];
                    } elseif ($template_type->param_name === 'TPhpMajorVersion') {
                        $template_result->lower_bounds[$template_type->param_name] = ['fn-' . strtolower((string) $method_id) => [new TemplateBound(Type::getInt(\false, $codebase->getMajorAnalysisPhpVersion()))]];
                    } elseif ($template_type->param_name === 'TPhpVersionId') {
                        $template_result->lower_bounds[$template_type->param_name] = ['fn-' . strtolower((string) $method_id) => [new TemplateBound(Type::getInt(\false, $codebase->analysis_php_version_id))]];
                    } else {
                        $template_result->lower_bounds[$template_type->param_name] = [$template_type->defining_class => [new TemplateBound(Type::getNever())]];
                    }
                }
            }
        }
        if ($template_result->lower_bounds) {
            $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, null, null, null);
            $return_type_candidate = TemplateInferredTypeReplacer::replace($return_type_candidate, $template_result, $codebase);
        }
        return $return_type_candidate;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use AssertionError;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\ArrayAssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ArgumentTypeCoercion;
use Psalm\Issue\InvalidArgument;
use Psalm\Issue\InvalidScalarArgument;
use Psalm\Issue\MixedArgumentTypeCoercion;
use Psalm\Issue\PossiblyInvalidArgument;
use Psalm\Issue\TooFewArguments;
use Psalm\Issue\TooManyArguments;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualArrayDimFetch;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_filter;
use function array_pop;
use function array_shift;
use function array_unshift;
use function assert;
use function count;
use function explode;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class ArrayFunctionArgumentsAnalyzer
{
    /**
     * @param   array<int, PhpParser\Node\Arg> $args
     */
    public static function checkArgumentsMatch(StatementsAnalyzer $statements_analyzer, Context $context, array $args, string $method_id, bool $check_functions) : void
    {
        $closure_index = $method_id === 'array_map' ? 0 : 1;
        $array_arg_types = [];
        foreach ($args as $i => $arg) {
            if ($i === 0 && $method_id === 'array_map') {
                continue;
            }
            if ($i === 1 && $method_id === 'array_filter') {
                break;
            }
            /**
             * @var TKeyedArray|TArray|null
             */
            $array_arg_type = ($arg_value_type = $statements_analyzer->node_data->getType($arg->value)) && $arg_value_type->hasArray() ? $arg_value_type->getArray() : null;
            if ($array_arg_type instanceof TKeyedArray) {
                $array_arg_type = $array_arg_type->getGenericArrayType();
            }
            $array_arg_types[] = $array_arg_type;
        }
        $closure_arg = $args[$closure_index] ?? null;
        $closure_arg_type = null;
        if ($closure_arg) {
            $closure_arg_type = $statements_analyzer->node_data->getType($closure_arg->value);
        }
        if ($closure_arg && $closure_arg_type) {
            $min_closure_param_count = $max_closure_param_count = count($array_arg_types);
            if ($method_id === 'array_filter') {
                $max_closure_param_count = count($args) > 2 ? 2 : 1;
            }
            $new = [];
            foreach ($closure_arg_type->getAtomicTypes() as $closure_type) {
                self::checkClosureType($statements_analyzer, $context, $method_id, $closure_type, $closure_arg, $min_closure_param_count, $max_closure_param_count, $array_arg_types, $check_functions);
                $new[] = $closure_type;
            }
            $statements_analyzer->node_data->setType($closure_arg->value, $closure_arg_type->getBuilder()->setTypes($new)->freeze());
        }
    }
    /**
     * @param   list<PhpParser\Node\Arg>          $args
     * @return  false|null
     */
    public static function handleAddition(StatementsAnalyzer $statements_analyzer, array $args, Context $context, string $method_id) : ?bool
    {
        $array_arg = $args[0]->value;
        $nb_args = count($args);
        $unpacked_args = array_filter($args, static fn(PhpParser\Node\Arg $arg): bool => $arg->unpack);
        if ($method_id === 'array_push' && !$unpacked_args) {
            for ($i = 1; $i < $nb_args; $i++) {
                $was_inside_assignment = $context->inside_assignment;
                $context->inside_assignment = \true;
                if (ExpressionAnalyzer::analyze($statements_analyzer, $args[$i]->value, $context) === \false) {
                    $context->inside_assignment = $was_inside_assignment;
                    return \false;
                }
                $context->inside_assignment = $was_inside_assignment;
                $old_node_data = $statements_analyzer->node_data;
                $statements_analyzer->node_data = clone $statements_analyzer->node_data;
                ArrayAssignmentAnalyzer::analyze($statements_analyzer, new VirtualArrayDimFetch($args[0]->value, null, $args[$i]->value->getAttributes()), $context, $args[$i]->value, $statements_analyzer->node_data->getType($args[$i]->value) ?? Type::getMixed());
                $statements_analyzer->node_data = $old_node_data;
            }
            return null;
        }
        $context->inside_call = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $array_arg, $context) === \false) {
            return \false;
        }
        for ($i = 1; $i < $nb_args; $i++) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $args[$i]->value, $context) === \false) {
                return \false;
            }
        }
        if (($array_arg_type = $statements_analyzer->node_data->getType($array_arg)) && $array_arg_type->hasArray()) {
            $array_type = $array_arg_type->getArray();
            $objectlike_list = null;
            if ($array_type instanceof TKeyedArray) {
                if ($array_type->is_list) {
                    $objectlike_list = $array_type;
                }
            }
            $by_ref_type = new Union([$array_type]);
            foreach ($args as $argument_offset => $arg) {
                if ($argument_offset === 0) {
                    continue;
                }
                if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context) === \false) {
                    return \false;
                }
                if ($method_id === 'array_unshift' && $nb_args === 2 && !$unpacked_args) {
                    $new_offset_type = Type::getInt(\false, 0);
                } else {
                    $new_offset_type = Type::getInt();
                }
                if (!($arg_value_type = $statements_analyzer->node_data->getType($arg->value)) || $arg_value_type->hasMixed()) {
                    $by_ref_type = Type::combineUnionTypes($by_ref_type, new Union([new TArray([$new_offset_type, Type::getMixed()])]));
                } elseif ($arg->unpack) {
                    $arg_value_type = $arg_value_type->getBuilder();
                    foreach ($arg_value_type->getAtomicTypes() as $arg_value_atomic_type) {
                        if ($arg_value_atomic_type instanceof TKeyedArray) {
                            $was_list = $arg_value_atomic_type->is_list;
                            $arg_value_atomic_type = $arg_value_atomic_type->getGenericArrayType();
                            if ($was_list) {
                                if ($arg_value_atomic_type instanceof TNonEmptyArray) {
                                    $arg_value_atomic_type = Type::getNonEmptyListAtomic($arg_value_atomic_type->type_params[1]);
                                } else {
                                    $arg_value_atomic_type = Type::getListAtomic($arg_value_atomic_type->type_params[1]);
                                }
                            }
                            $arg_value_type->addType($arg_value_atomic_type);
                        }
                    }
                    $arg_value_type = $arg_value_type->freeze();
                    $by_ref_type = Type::combineUnionTypes($by_ref_type, $arg_value_type);
                } else {
                    if ($objectlike_list) {
                        $properties = $objectlike_list->properties;
                        array_unshift($properties, $arg_value_type);
                        $by_ref_type = new Union([$objectlike_list->setProperties($properties)]);
                    } elseif ($array_type instanceof TArray && $array_type->isEmptyArray()) {
                        $by_ref_type = new Union([new TKeyedArray([$arg_value_type], null, null, \true)]);
                    } else {
                        $by_ref_type = Type::combineUnionTypes($by_ref_type, new Union([new TNonEmptyArray([$new_offset_type, $arg_value_type])]), null, \true);
                    }
                }
            }
            AssignmentAnalyzer::assignByRefParam($statements_analyzer, $array_arg, $by_ref_type, $by_ref_type, $context, \false);
        }
        $context->inside_call = \false;
        return null;
    }
    /**
     * @param   list<PhpParser\Node\Arg>          $args
     * @return  false|null
     */
    public static function handleSplice(StatementsAnalyzer $statements_analyzer, array $args, Context $context) : ?bool
    {
        $context->inside_call = \true;
        $array_arg = $args[0]->value;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $array_arg, $context) === \false) {
            return \false;
        }
        $offset_arg = $args[1]->value;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $offset_arg, $context) === \false) {
            return \false;
        }
        if (!isset($args[2])) {
            return null;
        }
        $length_arg = $args[2]->value;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $length_arg, $context) === \false) {
            return \false;
        }
        if (!isset($args[3])) {
            return null;
        }
        $replacement_arg = $args[3]->value;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $replacement_arg, $context) === \false) {
            return \false;
        }
        $context->inside_call = \false;
        $replacement_arg_type = $statements_analyzer->node_data->getType($replacement_arg);
        if ($replacement_arg_type && !$replacement_arg_type->hasArray() && $replacement_arg_type->hasString() && $replacement_arg_type->isSingle()) {
            $replacement_arg_type = new Union([new TArray([Type::getInt(), $replacement_arg_type])]);
            $statements_analyzer->node_data->setType($replacement_arg, $replacement_arg_type);
        }
        if (($array_arg_type = $statements_analyzer->node_data->getType($array_arg)) && $array_arg_type->hasArray() && $replacement_arg_type && $replacement_arg_type->hasArray()) {
            /**
             * @var TArray|TKeyedArray
             */
            $array_type = $array_arg_type->getArray();
            if ($array_type instanceof TKeyedArray) {
                if ($array_type->is_list) {
                    $array_type = Type::getNonEmptyListAtomic($array_type->getGenericValueType());
                } else {
                    $array_type = $array_type->getGenericArrayType();
                }
            }
            if ($array_type instanceof TArray && $array_type->type_params[0]->hasInt() && !$array_type->type_params[0]->hasString()) {
                if ($array_type instanceof TNonEmptyArray) {
                    $array_type = Type::getNonEmptyListAtomic($array_type->type_params[1]);
                } else {
                    $array_type = Type::getListAtomic($array_type->type_params[1]);
                }
            }
            /**
             * @var TArray|TKeyedArray
             */
            $replacement_array_type = $replacement_arg_type->getArray();
            if ($replacement_array_type instanceof TKeyedArray) {
                $was_list = $replacement_array_type->is_list;
                $replacement_array_type = $replacement_array_type->getGenericArrayType();
                if ($was_list) {
                    if ($replacement_array_type instanceof TNonEmptyArray) {
                        $replacement_array_type = Type::getNonEmptyListAtomic($replacement_array_type->type_params[1]);
                    } else {
                        $replacement_array_type = Type::getListAtomic($replacement_array_type->type_params[1]);
                    }
                }
            }
            $by_ref_type = TypeCombiner::combine([$array_type, $replacement_array_type]);
            AssignmentAnalyzer::assignByRefParam($statements_analyzer, $array_arg, $by_ref_type, $by_ref_type, $context, \false);
            return null;
        }
        $array_type = Type::getArray();
        AssignmentAnalyzer::assignByRefParam($statements_analyzer, $array_arg, $array_type, $array_type, $context, \false);
        return null;
    }
    public static function handleByRefArrayAdjustment(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Arg $arg, Context $context, bool $is_array_shift) : void
    {
        $var_id = ExpressionIdentifier::getVarId($arg->value, $statements_analyzer->getFQCLN(), $statements_analyzer);
        if ($var_id) {
            $context->removeVarFromConflictingClauses($var_id, null, $statements_analyzer);
            if (isset($context->vars_in_scope[$var_id])) {
                $array_atomic_types = [];
                foreach ($context->vars_in_scope[$var_id]->getAtomicTypes() as $array_atomic_type) {
                    if ($array_atomic_type instanceof TList) {
                        $array_atomic_type = $array_atomic_type->getKeyedArray();
                    }
                    if ($array_atomic_type instanceof TKeyedArray) {
                        if ($is_array_shift && $array_atomic_type->is_list && !$context->inside_loop) {
                            $array_properties = $array_atomic_type->properties;
                            array_shift($array_properties);
                            if (!$array_properties) {
                                $array_atomic_types[] = $array_atomic_type->fallback_params ? Type::getListAtomic($array_atomic_type->fallback_params[1]) : Type::getEmptyArrayAtomic();
                            } else {
                                $array_atomic_types[] = $array_atomic_type->setProperties($array_properties);
                            }
                            continue;
                        } elseif (!$is_array_shift && $array_atomic_type->is_list && !$array_atomic_type->fallback_params && !$context->inside_loop) {
                            $array_properties = $array_atomic_type->properties;
                            array_pop($array_properties);
                            if (!$array_properties) {
                                $array_atomic_types[] = Type::getEmptyArrayAtomic();
                            } else {
                                $array_atomic_types[] = $array_atomic_type->setProperties($array_properties);
                            }
                            continue;
                        }
                        $array_atomic_type = $array_atomic_type->is_list ? Type::getListAtomic($array_atomic_type->getGenericValueType()) : $array_atomic_type->getGenericArrayType();
                    }
                    if ($array_atomic_type instanceof TNonEmptyArray) {
                        if (!$context->inside_loop && $array_atomic_type->count !== null) {
                            if ($array_atomic_type->count === 1) {
                                $array_atomic_type = new TArray([Type::getNever(), Type::getNever()]);
                            } else {
                                $array_atomic_type = $array_atomic_type->setCount($array_atomic_type->count - 1);
                            }
                        } else {
                            $array_atomic_type = new TArray($array_atomic_type->type_params);
                        }
                        $array_atomic_types[] = $array_atomic_type;
                    } elseif ($array_atomic_type instanceof TKeyedArray && $array_atomic_type->is_list) {
                        if (!$context->inside_loop && ($prop_count = $array_atomic_type->getMaxCount()) && $prop_count === $array_atomic_type->getMinCount()) {
                            if ($prop_count === 1) {
                                $array_atomic_type = new TArray([Type::getNever(), Type::getNever()]);
                            } else {
                                $properties = $array_atomic_type->properties;
                                unset($properties[$prop_count - 1]);
                                assert($properties !== []);
                                $array_atomic_type = $array_atomic_type->setProperties($properties);
                            }
                        } else {
                            $array_atomic_type = Type::getListAtomic($array_atomic_type->getGenericValueType());
                        }
                        $array_atomic_types[] = $array_atomic_type;
                    } else {
                        $array_atomic_types[] = $array_atomic_type;
                    }
                }
                if (!$array_atomic_types) {
                    throw new AssertionError("We must have some types here!");
                }
                $array_type = new Union($array_atomic_types);
                $context->removeDescendents($var_id, $array_type);
                $context->vars_in_scope[$var_id] = $array_type;
            }
        }
    }
    /**
     * @param  (TArray|null)[] $array_arg_types
     */
    private static function checkClosureType(StatementsAnalyzer $statements_analyzer, Context $context, string $method_id, Atomic &$closure_type, PhpParser\Node\Arg $closure_arg, int $min_closure_param_count, int $max_closure_param_count, array $array_arg_types, bool $check_functions) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        if (!$closure_type instanceof TClosure) {
            if ($method_id === 'array_map') {
                return;
            }
            if (!$closure_arg->value instanceof PhpParser\Node\Scalar\String_ && !$closure_arg->value instanceof PhpParser\Node\Expr\Array_ && !$closure_arg->value instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
                return;
            }
            $function_ids = CallAnalyzer::getFunctionIdsFromCallableArg($statements_analyzer, $closure_arg->value);
            $closure_types = [];
            foreach ($function_ids as $function_id) {
                $function_id = strtolower($function_id);
                if (strpos($function_id, '::') !== \false) {
                    if ($function_id[0] === '$') {
                        $function_id = substr($function_id, 1);
                    }
                    $function_id_parts = explode('&', $function_id);
                    foreach ($function_id_parts as $function_id_part) {
                        [$callable_fq_class_name, $method_name] = explode('::', $function_id_part);
                        switch ($callable_fq_class_name) {
                            case 'self':
                            case 'static':
                            case 'parent':
                                $container_class = $statements_analyzer->getFQCLN();
                                if ($callable_fq_class_name === 'parent') {
                                    $container_class = $statements_analyzer->getParentFQCLN();
                                }
                                if (!$container_class) {
                                    continue 2;
                                }
                                $callable_fq_class_name = $container_class;
                        }
                        if (!$codebase->classOrInterfaceExists($callable_fq_class_name)) {
                            return;
                        }
                        $function_id_part = new MethodIdentifier($callable_fq_class_name, strtolower($method_name));
                        try {
                            $method_storage = $codebase->methods->getStorage($function_id_part);
                        } catch (UnexpectedValueException $e) {
                            // the method may not exist, but we're suppressing that issue
                            continue;
                        }
                        $closure_types[] = new TClosure('Closure', $method_storage->params, $method_storage->return_type ?: Type::getMixed());
                    }
                } else {
                    if (!$check_functions) {
                        continue;
                    }
                    if (!$codebase->functions->functionExists($statements_analyzer, $function_id)) {
                        continue;
                    }
                    $function_storage = $codebase->functions->getStorage($statements_analyzer, $function_id);
                    if (InternalCallMapHandler::inCallMap($function_id)) {
                        $callmap_callables = InternalCallMapHandler::getCallablesFromCallMap($function_id);
                        if ($callmap_callables === null) {
                            throw new UnexpectedValueException('This should not happen');
                        }
                        $passing_callmap_callables = [];
                        foreach ($callmap_callables as $callmap_callable) {
                            $required_param_count = 0;
                            assert($callmap_callable->params !== null);
                            foreach ($callmap_callable->params as $i => $param) {
                                if (!$param->is_optional && !$param->is_variadic) {
                                    $required_param_count = $i + 1;
                                }
                            }
                            if ($required_param_count <= $max_closure_param_count) {
                                $passing_callmap_callables[] = $callmap_callable;
                            }
                        }
                        if ($passing_callmap_callables) {
                            foreach ($passing_callmap_callables as $passing_callmap_callable) {
                                $closure_types[] = $passing_callmap_callable;
                            }
                        } else {
                            $closure_types[] = $callmap_callables[0];
                        }
                    } else {
                        $closure_types[] = new TClosure('Closure', $function_storage->params, $function_storage->return_type ?: Type::getMixed());
                    }
                }
            }
        } else {
            $closure_types = [&$closure_type];
        }
        foreach ($closure_types as &$closure_type) {
            if ($closure_type->params === null) {
                continue;
            }
            self::checkClosureTypeArgs($statements_analyzer, $context, $method_id, $closure_type, $closure_arg, $min_closure_param_count, $max_closure_param_count, $array_arg_types);
        }
        unset($closure_type);
    }
    /**
     * @param  TClosure|TCallable $closure_type
     * @param  (TArray|null)[] $array_arg_types
     */
    private static function checkClosureTypeArgs(StatementsAnalyzer $statements_analyzer, Context $context, string $method_id, Atomic &$closure_type, PhpParser\Node\Arg $closure_arg, int $min_closure_param_count, int $max_closure_param_count, array $array_arg_types) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $closure_params = $closure_type->params;
        if ($closure_params === null) {
            throw new UnexpectedValueException('Closure params should not be null here');
        }
        $required_param_count = 0;
        foreach ($closure_params as $i => $param) {
            if (!$param->is_optional && !$param->is_variadic) {
                $required_param_count = $i + 1;
            }
        }
        if (count($closure_params) < $min_closure_param_count) {
            $argument_text = $min_closure_param_count === 1 ? 'one argument' : $min_closure_param_count . ' arguments';
            IssueBuffer::maybeAdd(new TooManyArguments('The callable passed to ' . $method_id . ' will be called with ' . $argument_text . ', expecting ' . $required_param_count, new CodeLocation($statements_analyzer->getSource(), $closure_arg), $method_id), $statements_analyzer->getSuppressedIssues());
            return;
        }
        if ($required_param_count > $max_closure_param_count) {
            $argument_text = $max_closure_param_count === 1 ? 'one argument' : $max_closure_param_count . ' arguments';
            IssueBuffer::maybeAdd(new TooFewArguments('The callable passed to ' . $method_id . ' will be called with ' . $argument_text . ', expecting ' . $required_param_count, new CodeLocation($statements_analyzer->getSource(), $closure_arg), $method_id), $statements_analyzer->getSuppressedIssues());
            return;
        }
        // abandon attempt to validate closure params if we have an extra arg for ARRAY_FILTER
        if ($method_id === 'array_filter' && $max_closure_param_count > 1) {
            return;
        }
        foreach ($closure_params as $i => $closure_param) {
            if (!isset($array_arg_types[$i])) {
                continue;
            }
            $array_arg_type = $array_arg_types[$i];
            $input_type = $array_arg_type->type_params[1];
            if ($input_type->hasMixed()) {
                continue;
            }
            $closure_param_type = $closure_param->type;
            if (!$closure_param_type) {
                continue;
            }
            if ($method_id === 'array_map' && $i === 0 && $closure_type->return_type && $closure_param_type->hasTemplate()) {
                $template_result = new TemplateResult([], []);
                foreach ($closure_param_type->getTemplateTypes() as $template_type) {
                    $template_result->template_types[$template_type->param_name] = [$template_type->defining_class => $template_type->as];
                }
                $closure_param_type = TemplateStandinTypeReplacer::replace($closure_param_type, $template_result, $codebase, $statements_analyzer, $input_type, $i, $context->self, $context->calling_method_id ?: $context->calling_function_id);
                $closure_type = $closure_type->replaceTemplateTypesWithArgTypes($template_result, $codebase);
            }
            $closure_param_type = TypeExpander::expandUnion($codebase, $closure_param_type, $context->self, null, $statements_analyzer->getParentFQCLN());
            $union_comparison_results = new TypeComparisonResult();
            $type_match_found = UnionTypeComparator::isContainedBy($codebase, $input_type, $closure_param_type, $input_type->ignore_nullable_issues, $input_type->ignore_falsable_issues, $union_comparison_results);
            if ($union_comparison_results->type_coerced) {
                if ($union_comparison_results->type_coerced_from_mixed) {
                    IssueBuffer::maybeAdd(new MixedArgumentTypeCoercion('Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', but parent type ' . $input_type->getId() . ' provided', new CodeLocation($statements_analyzer->getSource(), $closure_arg), $method_id), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new ArgumentTypeCoercion('Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', but parent type ' . $input_type->getId() . ' provided', new CodeLocation($statements_analyzer->getSource(), $closure_arg), $method_id), $statements_analyzer->getSuppressedIssues());
                }
            }
            if (!$union_comparison_results->type_coerced && !$type_match_found) {
                $types_can_be_identical = UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $input_type, $closure_param_type);
                if ($union_comparison_results->scalar_type_match_found) {
                    IssueBuffer::maybeAdd(new InvalidScalarArgument('Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', but ' . $input_type->getId() . ' provided', new CodeLocation($statements_analyzer->getSource(), $closure_arg), $method_id), $statements_analyzer->getSuppressedIssues());
                } elseif ($types_can_be_identical) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidArgument('Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', but possibly different type ' . $input_type->getId() . ' provided', new CodeLocation($statements_analyzer->getSource(), $closure_arg), $method_id), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new InvalidArgument('Parameter ' . ($i + 1) . ' of closure passed to function ' . $method_id . ' expects ' . $closure_param_type->getId() . ', but ' . $input_type->getId() . ' provided', new CodeLocation($statements_analyzer->getSource(), $closure_arg), $method_id), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\BuilderFactory;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\TaintSource;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Type\Comparator\CallableTypeComparator;
use Psalm\Internal\Type\TemplateBound;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Plugin\EventHandler\Event\AfterFunctionCallAnalysisEvent;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableArray;
use Psalm\Type\Atomic\TCallableKeyedArray;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_merge;
use function array_values;
use function count;
use function explode;
use function in_array;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class FunctionCallReturnTypeFetcher
{
    /**
     * @param non-empty-string $function_id
     */
    public static function fetch(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\FuncCall $stmt, PhpParser\Node\Name $function_name, string $function_id, bool $in_call_map, bool $is_stubbed, ?FunctionLikeStorage $function_storage, ?TCallable $callmap_callable, TemplateResult $template_result, Context $context) : Union
    {
        $stmt_type = null;
        $config = $codebase->config;
        if ($stmt->isFirstClassCallable()) {
            $candidate_callable = CallableTypeComparator::getCallableFromAtomic($codebase, new TLiteralString($function_id), null, $statements_analyzer, \true);
            if ($candidate_callable) {
                $stmt_type = new Union([new TClosure('Closure', $candidate_callable->params, $candidate_callable->return_type, $candidate_callable->is_pure)]);
            } else {
                $stmt_type = Type::getClosure();
            }
        } elseif ($codebase->functions->return_type_provider->has($function_id)) {
            $stmt_type = $codebase->functions->return_type_provider->getReturnType($statements_analyzer, $function_id, $stmt, $context, new CodeLocation($statements_analyzer->getSource(), $function_name));
        }
        if (!$stmt_type) {
            if (!$in_call_map || $is_stubbed) {
                if ($function_storage && $function_storage->template_types) {
                    foreach ($function_storage->template_types as $template_name => $_) {
                        if (!isset($template_result->lower_bounds[$template_name])) {
                            if ($template_name === 'TFunctionArgCount') {
                                $template_result->lower_bounds[$template_name] = ['fn-' . $function_id => [new TemplateBound(Type::getInt(\false, count($stmt->getArgs())))]];
                            } elseif ($template_name === 'TPhpMajorVersion') {
                                $template_result->lower_bounds[$template_name] = ['fn-' . $function_id => [new TemplateBound(Type::getInt(\false, $codebase->getMajorAnalysisPhpVersion()))]];
                            } elseif ($template_name === 'TPhpVersionId') {
                                $template_result->lower_bounds[$template_name] = ['fn-' . $function_id => [new TemplateBound(Type::getInt(\false, $codebase->analysis_php_version_id))]];
                            } else {
                                $template_result->lower_bounds[$template_name] = ['fn-' . $function_id => [new TemplateBound(Type::getNever())]];
                            }
                        }
                    }
                }
                if ($function_storage && !$context->isSuppressingExceptions($statements_analyzer)) {
                    $context->mergeFunctionExceptions($function_storage, new CodeLocation($statements_analyzer->getSource(), $stmt));
                }
                try {
                    if ($function_storage && $function_storage->return_type) {
                        $return_type = $function_storage->return_type;
                        if ($template_result->lower_bounds && $function_storage->template_types) {
                            $return_type = TypeExpander::expandUnion($codebase, $return_type, null, null, null);
                            $return_type = TemplateInferredTypeReplacer::replace($return_type, $template_result, $codebase);
                        }
                        $return_type = TypeExpander::expandUnion($codebase, $return_type, null, null, null, \true, \false, \false, \true);
                        $return_type_location = $function_storage->return_type_location;
                        $event = new AfterFunctionCallAnalysisEvent($stmt, $function_id, $context, $statements_analyzer->getSource(), $codebase, $return_type, []);
                        $config->eventDispatcher->dispatchAfterFunctionCallAnalysis($event);
                        $file_manipulations = $event->getFileReplacements();
                        if ($file_manipulations) {
                            FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                        }
                        $return_type = $return_type->setByRef($function_storage->returns_by_ref);
                        $stmt_type = $return_type;
                        // only check the type locally if it's defined externally
                        if ($return_type_location && !$is_stubbed && !$config->isInProjectDirs($return_type_location->file_path)) {
                            /** @psalm-suppress UnusedMethodCall Actually generates issues */
                            $return_type->check($statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues(), $context->phantom_classes, \true, \false, \false, $context->calling_method_id);
                        }
                    }
                } catch (InvalidArgumentException $e) {
                    // this can happen when the function was defined in the Config startup script
                    $stmt_type = Type::getMixed();
                }
            } else {
                if (!$callmap_callable) {
                    throw new UnexpectedValueException('We should have a callmap callable here');
                }
                $stmt_type = self::getReturnTypeFromCallMapWithArgs($statements_analyzer, $function_id, $stmt->getArgs(), $callmap_callable, $context);
            }
        }
        if (!$stmt_type) {
            $stmt_type = Type::getMixed();
        }
        if (!$statements_analyzer->data_flow_graph || !$function_storage) {
            return $stmt_type;
        }
        $return_node = self::taintReturnType($statements_analyzer, $stmt, $function_id, $function_storage, $stmt_type, $template_result, $context);
        if ($function_storage->proxy_calls !== null) {
            foreach ($function_storage->proxy_calls as $proxy_call) {
                $fake_call_arguments = [];
                foreach ($proxy_call['params'] as $i) {
                    $fake_call_arguments[] = $stmt->getArgs()[$i];
                }
                $fake_call_factory = new BuilderFactory();
                if (strpos($proxy_call['fqn'], '::') !== \false) {
                    [$fqcn, $method] = explode('::', $proxy_call['fqn']);
                    $fake_call = $fake_call_factory->staticCall($fqcn, $method, $fake_call_arguments);
                } else {
                    $fake_call = $fake_call_factory->funcCall($proxy_call['fqn'], $fake_call_arguments);
                }
                $old_node_data = $statements_analyzer->node_data;
                $statements_analyzer->node_data = clone $statements_analyzer->node_data;
                ExpressionAnalyzer::analyze($statements_analyzer, $fake_call, $context);
                $statements_analyzer->node_data = $old_node_data;
                if ($return_node && $proxy_call['return']) {
                    $fake_call_type = $statements_analyzer->node_data->getType($fake_call);
                    if (null !== $fake_call_type) {
                        foreach ($fake_call_type->parent_nodes as $fake_call_node) {
                            $statements_analyzer->data_flow_graph->addPath($fake_call_node, $return_node, 'return');
                        }
                    }
                }
            }
        }
        return $stmt_type;
    }
    /**
     * @param  list<PhpParser\Node\Arg>   $call_args
     */
    private static function getReturnTypeFromCallMapWithArgs(StatementsAnalyzer $statements_analyzer, string $function_id, array $call_args, TCallable $callmap_callable, Context $context) : Union
    {
        $call_map_key = strtolower($function_id);
        $codebase = $statements_analyzer->getCodebase();
        if (!$call_args) {
            switch ($call_map_key) {
                case 'hrtime':
                    $keyed_array = new TKeyedArray([Type::getInt(), Type::getInt()], null, null, \true);
                    return new Union([$keyed_array]);
                case 'get_called_class':
                    return new Union([new TClassString($context->self ?: 'object', $context->self ? new TNamedObject($context->self, \true) : null)]);
                case 'get_parent_class':
                    if ($context->self && $codebase->classExists($context->self)) {
                        $classlike_storage = $codebase->classlike_storage_provider->get($context->self);
                        if ($classlike_storage->parent_classes) {
                            return new Union([new TClassString(array_values($classlike_storage->parent_classes)[0])]);
                        }
                    }
            }
        } else {
            switch ($call_map_key) {
                case 'count':
                    if ($first_arg_type = $statements_analyzer->node_data->getType($call_args[0]->value)) {
                        $atomic_types = $first_arg_type->getAtomicTypes();
                        if (count($atomic_types) === 1) {
                            if (isset($atomic_types['array'])) {
                                if ($atomic_types['array'] instanceof TList) {
                                    $atomic_types['array'] = $atomic_types['array']->getKeyedArray();
                                }
                                if ($atomic_types['array'] instanceof TCallableArray || $atomic_types['array'] instanceof TCallableKeyedArray) {
                                    return Type::getInt(\false, 2);
                                }
                                if ($atomic_types['array'] instanceof TNonEmptyArray) {
                                    return new Union([$atomic_types['array']->count !== null ? new TLiteralInt($atomic_types['array']->count) : new TIntRange(1, null)]);
                                }
                                if ($atomic_types['array'] instanceof TKeyedArray) {
                                    $min = $atomic_types['array']->getMinCount();
                                    $max = $atomic_types['array']->getMaxCount();
                                    if ($min === $max) {
                                        return new Union([new TLiteralInt($max)]);
                                    }
                                    return new Union([new TIntRange($min, $max)]);
                                }
                                if ($atomic_types['array'] instanceof TArray && $atomic_types['array']->isEmptyArray()) {
                                    return Type::getInt(\false, 0);
                                }
                                return new Union([new TIntRange(0, null)]);
                            }
                        }
                    }
                    break;
                case 'hrtime':
                    if ($first_arg_type = $statements_analyzer->node_data->getType($call_args[0]->value)) {
                        if ((string) $first_arg_type === 'true') {
                            return Type::getInt(\true);
                        }
                        $keyed_array = new TKeyedArray([Type::getInt(), Type::getInt()], null, null, \true);
                        if ((string) $first_arg_type === 'false') {
                            return new Union([$keyed_array]);
                        }
                        return new Union([$keyed_array, new TInt()]);
                    }
                    return Type::getInt(\true);
                case 'min':
                case 'max':
                    if (isset($call_args[0])) {
                        $first_arg = $call_args[0]->value;
                        if ($first_arg_type = $statements_analyzer->node_data->getType($first_arg)) {
                            if ($first_arg_type->hasArray()) {
                                $array_type = $first_arg_type->getArray();
                                if ($array_type instanceof TKeyedArray) {
                                    return $array_type->getGenericValueType();
                                }
                                if ($array_type instanceof TArray) {
                                    return $array_type->type_params[1];
                                }
                            } elseif ($first_arg_type->hasScalarType() && ($second_arg = $call_args[1]->value ?? null) && ($second_arg_type = $statements_analyzer->node_data->getType($second_arg)) && $second_arg_type->hasScalarType()) {
                                return Type::combineUnionTypes($first_arg_type, $second_arg_type);
                            }
                        }
                    }
                    break;
                case 'get_parent_class':
                    // this is unreliable, as it's hard to know exactly what's wanted - attempted this in
                    // https://github.com/vimeo/psalm/commit/355ed831e1c69c96bbf9bf2654ef64786cbe9fd7
                    // but caused problems where it didn’t know exactly what level of child we
                    // were receiving.
                    //
                    // Really this should only work on instances we've created with new Foo(),
                    // but that requires more work
                    break;
                case 'fgetcsv':
                    $string_type = new Union([new TString(), new TNull()], ['ignore_nullable_issues' => \true]);
                    $call_map_return_type = new Union([Type::getNonEmptyListAtomic($string_type), new TFalse(), new TNull()], ['ignore_nullable_issues' => $codebase->config->ignore_internal_nullable_issues, 'ignore_falsable_issues' => $codebase->config->ignore_internal_falsable_issues]);
                    return $call_map_return_type;
                case 'mb_strtolower':
                    if (count($call_args) < 2) {
                        return Type::getLowercaseString();
                    } else {
                        $second_arg_type = $statements_analyzer->node_data->getType($call_args[1]->value);
                        if ($second_arg_type && $second_arg_type->isNull()) {
                            return Type::getLowercaseString();
                        }
                    }
                    return Type::getString();
            }
        }
        $stmt_type = $callmap_callable->return_type ?: Type::getMixed();
        switch ($function_id) {
            case 'mb_strpos':
            case 'mb_strrpos':
            case 'mb_stripos':
            case 'mb_strripos':
            case 'strpos':
            case 'strrpos':
            case 'stripos':
            case 'strripos':
            case 'strstr':
            case 'stristr':
            case 'strrchr':
            case 'strpbrk':
            case 'array_search':
                break;
            default:
                if ($stmt_type->isFalsable() && $codebase->config->ignore_internal_falsable_issues) {
                    $stmt_type = $stmt_type->setProperties(['ignore_falsable_issues' => \true]);
                }
        }
        return $stmt_type;
    }
    private static function taintReturnType(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\FuncCall $stmt, string $function_id, FunctionLikeStorage $function_storage, Union &$stmt_type, TemplateResult $template_result, Context $context) : ?DataFlowNode
    {
        if (!$statements_analyzer->data_flow_graph) {
            return null;
        }
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
            return null;
        }
        $codebase = $statements_analyzer->getCodebase();
        $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
        $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
        $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
        $node_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
        $function_call_node = DataFlowNode::getForMethodReturn($function_id, $function_id, $statements_analyzer->data_flow_graph instanceof TaintFlowGraph ? $function_storage->signature_return_type_location ?: $function_storage->location : ($function_storage->return_type_location ?: $function_storage->location), $function_storage->specialize_call ? $node_location : null);
        $statements_analyzer->data_flow_graph->addNode($function_call_node);
        $codebase = $statements_analyzer->getCodebase();
        $conditionally_removed_taints = [];
        foreach ($function_storage->conditionally_removed_taints as $conditionally_removed_taint) {
            $conditionally_removed_taint = TemplateInferredTypeReplacer::replace($conditionally_removed_taint, $template_result, $codebase);
            $expanded_type = TypeExpander::expandUnion($statements_analyzer->getCodebase(), $conditionally_removed_taint, null, null, null, \true, \true);
            if (!$expanded_type->isNullable()) {
                foreach ($expanded_type->getLiteralStrings() as $literal_string) {
                    $conditionally_removed_taints[] = $literal_string->value;
                }
            }
        }
        if ($conditionally_removed_taints && $function_storage->location) {
            $assignment_node = DataFlowNode::getForAssignment($function_id . '-escaped', $function_storage->signature_return_type_location ?: $function_storage->location, $function_call_node->specialization_key);
            $statements_analyzer->data_flow_graph->addPath($function_call_node, $assignment_node, 'conditionally-escaped', $added_taints, [...$removed_taints, ...$conditionally_removed_taints]);
            $stmt_type = $stmt_type->addParentNodes([$assignment_node->id => $assignment_node]);
        } else {
            $stmt_type = $stmt_type->addParentNodes([$function_call_node->id => $function_call_node]);
        }
        if ($function_storage->return_source_params && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            $removed_taints = $function_storage->removed_taints;
            if ($function_id === 'preg_replace' && count($stmt->getArgs()) > 2) {
                $first_stmt_type = $statements_analyzer->node_data->getType($stmt->getArgs()[0]->value);
                $second_stmt_type = $statements_analyzer->node_data->getType($stmt->getArgs()[1]->value);
                if ($first_stmt_type && $second_stmt_type && $first_stmt_type->isSingleStringLiteral() && $second_stmt_type->isSingleStringLiteral()) {
                    $first_arg_value = $first_stmt_type->getSingleStringLiteral()->value;
                    $pattern = substr($first_arg_value, 1, -1);
                    if ($pattern[0] === '[' && $pattern[1] === '^' && substr($pattern, -1) === ']') {
                        $pattern = substr($pattern, 2, -1);
                        if (self::simpleExclusion($pattern, $first_arg_value[0])) {
                            $removed_taints[] = 'html';
                            $removed_taints[] = 'has_quotes';
                            $removed_taints[] = 'sql';
                        }
                    }
                }
            }
            $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
            $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
            $removed_taints = array_merge($removed_taints, $codebase->config->eventDispatcher->dispatchRemoveTaints($event));
            self::taintUsingFlows($statements_analyzer, $function_storage, $statements_analyzer->data_flow_graph, $function_id, $stmt->getArgs(), $node_location, $function_call_node, $removed_taints, $added_taints);
        }
        if ($function_storage->taint_source_types && $statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
            $method_node = TaintSource::getForMethodReturn($function_id, $function_id, $node_location);
            $method_node->taints = $function_storage->taint_source_types;
            $statements_analyzer->data_flow_graph->addSource($method_node);
        }
        return $function_call_node;
    }
    /**
     * @param  array<PhpParser\Node\Arg>   $args
     * @param  array<string> $removed_taints
     * @param  array<string> $added_taints
     */
    public static function taintUsingFlows(StatementsAnalyzer $statements_analyzer, FunctionLikeStorage $function_storage, TaintFlowGraph $graph, string $function_id, array $args, CodeLocation $node_location, DataFlowNode $function_call_node, array $removed_taints, array $added_taints = []) : void
    {
        foreach ($function_storage->return_source_params as $i => $path_type) {
            if (!isset($args[$i])) {
                continue;
            }
            $current_arg_is_variadic = $function_storage->params[$i]->is_variadic;
            $taintable_arg_index = [$i];
            if ($current_arg_is_variadic) {
                $max_params = count($args) - 1;
                for ($arg_index = $i + 1; $arg_index <= $max_params; $arg_index++) {
                    $taintable_arg_index[] = $arg_index;
                }
            }
            foreach ($taintable_arg_index as $arg_index) {
                $arg_location = new CodeLocation($statements_analyzer, $args[$arg_index]->value);
                $function_param_sink = DataFlowNode::getForMethodArgument($function_id, $function_id, $arg_index, $arg_location, $function_storage->specialize_call ? $node_location : null);
                $graph->addNode($function_param_sink);
                $graph->addPath($function_param_sink, $function_call_node, $path_type, array_merge($added_taints, $function_storage->added_taints), $removed_taints);
            }
        }
    }
    /**
     * @psalm-pure
     */
    private static function simpleExclusion(string $pattern, string $escape_char) : bool
    {
        $str_length = strlen($pattern);
        for ($i = 0; $i < $str_length; $i++) {
            $current = $pattern[$i];
            $next = $pattern[$i + 1] ?? null;
            if ($current === '\\') {
                if ($next === null || $next === 'x' || $next === 'u') {
                    return \false;
                }
                if ($next === '.' || $next === '(' || $next === ')' || $next === '[' || $next === ']' || $next === 's' || $next === 'w' || $next === $escape_char) {
                    $i++;
                    continue;
                }
                return \false;
            }
            if ($next !== '-') {
                if ($current === '_' || $current === '-' || $current === '|' || $current === ':' || $current === '#' || $current === '.' || $current === ' ') {
                    continue;
                }
                return \false;
            }
            if ($current === ']') {
                return \false;
            }
            if (!isset($pattern[$i + 2])) {
                return \false;
            }
            if ($current === 'a' && $pattern[$i + 2] === 'z' || $current === 'a' && $pattern[$i + 2] === 'Z' || $current === 'A' && $pattern[$i + 2] === 'Z' || $current === '0' && $pattern[$i + 2] === '9') {
                $i += 2;
                continue;
            }
            return \false;
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\AttributesAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ArrayFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\ConstantTypeResolver;
use Psalm\Internal\Codebase\Functions;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Stubs\Generator\StubsGenerator;
use Psalm\Internal\Type\Comparator\CallableTypeComparator;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\InvalidNamedArgument;
use Psalm\Issue\InvalidPassByReference;
use Psalm\Issue\PossiblyUndefinedVariable;
use Psalm\Issue\TooFewArguments;
use Psalm\Issue\TooManyArguments;
use Psalm\IssueBuffer;
use Psalm\Node\VirtualArg;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableArray;
use Psalm\Type\Atomic\TCallableKeyedArray;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_map;
use function array_reverse;
use function array_slice;
use function array_values;
use function count;
use function in_array;
use function is_string;
use function max;
use function min;
use function reset;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class ArgumentsAnalyzer
{
    /**
     * @param   list<PhpParser\Node\Arg>          $args
     * @param   array<int, FunctionLikeParameter>|null  $function_params
     * @return  false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, array $args, ?array $function_params, ?string $method_id, bool $allow_named_args, Context $context, ?TemplateResult $template_result = null) : ?bool
    {
        $last_param = $function_params ? $function_params[count($function_params) - 1] : null;
        // if this modifies the array type based on further args
        if (in_array($method_id, ['array_push', 'array_unshift'], \true) && $function_params && isset($args[0]) && isset($args[1])) {
            if (\Psalm\Internal\Analyzer\Statements\Expression\Call\ArrayFunctionArgumentsAnalyzer::handleAddition($statements_analyzer, $args, $context, $method_id) === \false) {
                return \false;
            }
            return null;
        }
        if ($method_id === 'array_splice' && $function_params && count($args) > 1) {
            if (\Psalm\Internal\Analyzer\Statements\Expression\Call\ArrayFunctionArgumentsAnalyzer::handleSplice($statements_analyzer, $args, $context) === \false) {
                return \false;
            }
            return null;
        }
        if ($method_id === 'array_map') {
            $args = array_reverse($args, \true);
        }
        foreach ($args as $argument_offset => $arg) {
            if ($function_params === null) {
                if (self::evaluateArbitraryParam($statements_analyzer, $arg, $context) === \false) {
                    return \false;
                }
                continue;
            }
            $param = null;
            if ($arg->name && $allow_named_args) {
                foreach ($function_params as $candidate_param) {
                    if ($candidate_param->name === $arg->name->name) {
                        $param = $candidate_param;
                        break;
                    }
                }
                if ($last_param && $last_param->is_variadic) {
                    $param = $last_param;
                }
            } elseif ($argument_offset < count($function_params)) {
                $param = $function_params[$argument_offset];
            } elseif ($last_param && $last_param->is_variadic) {
                $param = $last_param;
            }
            $by_ref = $param && $param->by_ref;
            $by_ref_type = null;
            if ($by_ref) {
                $by_ref_type = $param->type ?: Type::getMixed();
            }
            if ($by_ref && $by_ref_type && !($arg->value instanceof PhpParser\Node\Expr\Closure || $arg->value instanceof PhpParser\Node\Expr\ConstFetch || $arg->value instanceof PhpParser\Node\Expr\ClassConstFetch || $arg->value instanceof PhpParser\Node\Expr\FuncCall || $arg->value instanceof PhpParser\Node\Expr\MethodCall || $arg->value instanceof PhpParser\Node\Expr\StaticCall || $arg->value instanceof PhpParser\Node\Expr\New_ || $arg->value instanceof PhpParser\Node\Expr\Assign || $arg->value instanceof PhpParser\Node\Expr\Array_ || $arg->value instanceof PhpParser\Node\Expr\Ternary || $arg->value instanceof PhpParser\Node\Expr\BinaryOp)) {
                if (self::handleByRefFunctionArg($statements_analyzer, $method_id, $argument_offset, $arg, $context) === \false) {
                    return \false;
                }
                continue;
            }
            $toggled_class_exists = \false;
            if ($method_id === 'class_exists' && $argument_offset === 0 && !$context->inside_class_exists) {
                $context->inside_class_exists = \true;
                $toggled_class_exists = \true;
            }
            $high_order_template_result = null;
            if (($arg->value instanceof PhpParser\Node\Expr\FuncCall || $arg->value instanceof PhpParser\Node\Expr\MethodCall || $arg->value instanceof PhpParser\Node\Expr\StaticCall) && $param && ($function_storage = self::getHighOrderFuncStorage($context, $statements_analyzer, $arg->value))) {
                $high_order_template_result = self::handleHighOrderFuncCallArg($statements_analyzer, $template_result ?? new TemplateResult([], []), $function_storage, $param);
            } elseif (($arg->value instanceof PhpParser\Node\Expr\Closure || $arg->value instanceof PhpParser\Node\Expr\ArrowFunction) && $param && !$arg->value->getDocComment()) {
                self::handleClosureArg($statements_analyzer, $args, $method_id, $context, $template_result ?? new TemplateResult([], []), $argument_offset, $arg, $param);
            }
            $was_inside_call = $context->inside_call;
            $context->inside_call = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context, \false, null, \false, $high_order_template_result) === \false) {
                $context->inside_call = $was_inside_call;
                return \false;
            }
            $context->inside_call = $was_inside_call;
            if ($argument_offset === 0 && $method_id === 'array_filter' && count($args) === 2 || $argument_offset > 0 && $method_id === 'array_map' && count($args) >= 2) {
                self::handleArrayMapFilterArrayArg($statements_analyzer, $method_id, $argument_offset, $arg, $context, $template_result);
            }
            $inferred_arg_type = $statements_analyzer->node_data->getType($arg->value);
            if (null !== $inferred_arg_type && null !== $template_result && null !== $param && null !== $param->type) {
                $codebase = $statements_analyzer->getCodebase();
                TemplateStandinTypeReplacer::fillTemplateResult($param->type, $template_result, $codebase, $statements_analyzer, $inferred_arg_type, $argument_offset, $context->self, $context->calling_method_id ?: $context->calling_function_id);
            }
            if ($toggled_class_exists) {
                $context->inside_class_exists = \false;
            }
        }
        if ($method_id === "ReflectionClass::getattributes" || $method_id === "ReflectionClassConstant::getattributes" || $method_id === "ReflectionFunction::getattributes" || $method_id === "ReflectionMethod::getattributes" || $method_id === "ReflectionParameter::getattributes" || $method_id === "ReflectionProperty::getattributes") {
            AttributesAnalyzer::analyzeGetAttributes($statements_analyzer, $method_id, array_values($args));
        }
        return null;
    }
    private static function handleArrayMapFilterArrayArg(StatementsAnalyzer $statements_analyzer, string $method_id, int $argument_offset, PhpParser\Node\Arg $arg, Context $context, ?TemplateResult &$template_result) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $template_types = ['ArrayValue' . $argument_offset => [$method_id => Type::getMixed()]];
        $replace_template_result = new TemplateResult($template_types, []);
        $existing_type = $statements_analyzer->node_data->getType($arg->value);
        TemplateStandinTypeReplacer::fillTemplateResult(new Union([new TArray([Type::getArrayKey(), new Union([new TTemplateParam('ArrayValue' . $argument_offset, Type::getMixed(), $method_id)])])]), $replace_template_result, $codebase, $statements_analyzer, $existing_type, $argument_offset, $context->self, $context->calling_method_id ?: $context->calling_function_id);
        if ($replace_template_result->lower_bounds) {
            if (!$template_result) {
                $template_result = new TemplateResult([], []);
            }
            $template_result->lower_bounds += $replace_template_result->lower_bounds;
        }
    }
    private static function getHighOrderFuncStorage(Context $context, StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\CallLike $function_like_call) : ?FunctionLikeStorage
    {
        $codebase = $statements_analyzer->getCodebase();
        try {
            if ($function_like_call instanceof PhpParser\Node\Expr\FuncCall && !$function_like_call->isFirstClassCallable()) {
                $function_id = strtolower((string) $function_like_call->name->getAttribute('resolvedName'));
                if (empty($function_id)) {
                    return null;
                }
                if ($codebase->functions->dynamic_storage_provider->has($function_id)) {
                    return $codebase->functions->dynamic_storage_provider->getFunctionStorage($function_like_call, $statements_analyzer, $function_id, $context, new CodeLocation($statements_analyzer, $function_like_call));
                }
                return $codebase->functions->getStorage($statements_analyzer, $function_id);
            }
            if ($function_like_call instanceof PhpParser\Node\Expr\MethodCall && $function_like_call->var instanceof PhpParser\Node\Expr\Variable && $function_like_call->name instanceof PhpParser\Node\Identifier && is_string($function_like_call->var->name) && isset($context->vars_in_scope['$' . $function_like_call->var->name])) {
                $lhs_type = $context->vars_in_scope['$' . $function_like_call->var->name]->getSingleAtomic();
                if (!$lhs_type instanceof Type\Atomic\TNamedObject) {
                    return null;
                }
                $method_id = new MethodIdentifier($lhs_type->value, strtolower((string) $function_like_call->name));
                return $codebase->methods->getStorage($method_id);
            }
            if ($function_like_call instanceof PhpParser\Node\Expr\StaticCall && $function_like_call->name instanceof PhpParser\Node\Identifier) {
                $method_id = new MethodIdentifier((string) $function_like_call->class->getAttribute('resolvedName'), strtolower($function_like_call->name->name));
                return $codebase->methods->getStorage($method_id);
            }
        } catch (UnexpectedValueException $e) {
            return null;
        }
        return null;
    }
    /**
     * Compiles TemplateResult for high-order functions ($func_call)
     * by previous template args ($inferred_template_result).
     *
     * It's need for proper template replacement:
     *
     * ```
     * * template T
     * * return Closure(T): T
     * function id(): Closure { ... }
     *
     * * template A
     * * template B
     * *
     * * param list<A> $_items
     * * param callable(A): B $_ab
     * * return list<B>
     * function map(array $items, callable $ab): array { ... }
     *
     * // list<int>
     * $numbers = [1, 2, 3];
     *
     * $result = map($numbers, id());
     * // $result is list<int> because template T of id() was inferred by previous arg.
     * ```
     */
    private static function handleHighOrderFuncCallArg(StatementsAnalyzer $statements_analyzer, TemplateResult $inferred_template_result, FunctionLikeStorage $storage, FunctionLikeParameter $actual_func_param) : ?TemplateResult
    {
        $codebase = $statements_analyzer->getCodebase();
        $input_hof_atomic = $storage->return_type && $storage->return_type->isSingle() ? $storage->return_type->getSingleAtomic() : null;
        // Try upcast invokable to callable type.
        if ($input_hof_atomic instanceof Type\Atomic\TNamedObject && $input_hof_atomic->value !== 'Closure' && $codebase->classExists($input_hof_atomic->value)) {
            $callable_from_invokable = CallableTypeComparator::getCallableFromAtomic($codebase, $input_hof_atomic);
            if ($callable_from_invokable) {
                $invoke_id = new MethodIdentifier($input_hof_atomic->value, '__invoke');
                $declaring_invoke_id = $codebase->methods->getDeclaringMethodId($invoke_id);
                $storage = $codebase->methods->getStorage($declaring_invoke_id ?? $invoke_id);
                $input_hof_atomic = $callable_from_invokable;
            }
        }
        if (!$input_hof_atomic instanceof TClosure && !$input_hof_atomic instanceof TCallable) {
            return null;
        }
        $container_hof_atomic = $actual_func_param->type && $actual_func_param->type->isSingle() ? $actual_func_param->type->getSingleAtomic() : null;
        if (!$container_hof_atomic instanceof TClosure && !$container_hof_atomic instanceof TCallable) {
            return null;
        }
        $replaced_container_hof_atomic = new Union([$container_hof_atomic]);
        // Replaces all input args in container function.
        //
        // For example:
        // The map function expects callable(A):B as second param
        // We know that previous arg type is list<int> where the int is the A template.
        // Then we can replace callable(A): B to callable(int):B using $inferred_template_result.
        $replaced_container_hof_atomic = TemplateInferredTypeReplacer::replace($replaced_container_hof_atomic, $inferred_template_result, $codebase);
        /** @var TClosure|TCallable $container_hof_atomic */
        $container_hof_atomic = $replaced_container_hof_atomic->getSingleAtomic();
        $high_order_template_result = new TemplateResult($storage->template_types ?: [], []);
        // We can replace each templated param for the input function.
        // Example:
        // map($numbers, id());
        // We know that map expects callable(int):B because the $numbers is list<int>.
        // We know that id() returns callable(T):T.
        // Then we can replace templated params sequentially using the expected callable(int):B.
        foreach ($input_hof_atomic->params ?? [] as $offset => $actual_func_param) {
            if ($actual_func_param->type && $actual_func_param->type->getTemplateTypes() && isset($container_hof_atomic->params[$offset])) {
                TemplateStandinTypeReplacer::fillTemplateResult($actual_func_param->type, $high_order_template_result, $codebase, null, $container_hof_atomic->params[$offset]->type);
            }
        }
        return $high_order_template_result;
    }
    /**
     * @param   array<int, PhpParser\Node\Arg>  $args
     */
    private static function handleClosureArg(StatementsAnalyzer $statements_analyzer, array $args, ?string $method_id, Context $context, TemplateResult $template_result, int $argument_offset, PhpParser\Node\Arg $arg, FunctionLikeParameter $param) : void
    {
        if (!$param->type) {
            return;
        }
        $codebase = $statements_analyzer->getCodebase();
        if ($argument_offset === 1 && $method_id === 'array_filter' && count($args) === 2 || $argument_offset === 0 && $method_id === 'array_map' && count($args) >= 2) {
            $function_like_params = [];
            foreach ($template_result->lower_bounds as $template_name => $_) {
                $t = new Union([new TTemplateParam($template_name, Type::getMixed(), $method_id)]);
                $function_like_params[] = new FunctionLikeParameter('function', \false, $t, $t);
            }
            $replaced_type = new Union([new TCallable('callable', array_reverse($function_like_params))]);
        } else {
            $replaced_type = $param->type;
        }
        $replace_template_result = new TemplateResult(array_map(static fn(array $template_map): array => array_map(static fn(array $lower_bounds): Union => TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($lower_bounds, $codebase), $template_map), $template_result->lower_bounds), []);
        $replaced_type = TemplateStandinTypeReplacer::replace($replaced_type, $replace_template_result, $codebase, $statements_analyzer, null, null, null, $context->calling_method_id ?: $context->calling_function_id);
        $replaced_type = TemplateInferredTypeReplacer::replace($replaced_type, $replace_template_result, $codebase);
        $closure_id = strtolower($statements_analyzer->getFilePath()) . ':' . $arg->value->getLine() . ':' . (int) $arg->value->getAttribute('startFilePos') . ':-:closure';
        try {
            $closure_storage = $codebase->getClosureStorage($statements_analyzer->getFilePath(), $closure_id);
        } catch (UnexpectedValueException $e) {
            return;
        }
        foreach ($closure_storage->params as $closure_param_offset => $param_storage) {
            $param_type_inferred = $param_storage->type_inferred;
            $newly_inferred_type = null;
            $has_different_docblock_type = \false;
            if ($param_storage->type && !$param_type_inferred) {
                if ($param_storage->type !== $param_storage->signature_type) {
                    $has_different_docblock_type = \true;
                }
            }
            if (!$has_different_docblock_type) {
                foreach ($replaced_type->getAtomicTypes() as $replaced_type_part) {
                    if ($replaced_type_part instanceof TCallable || $replaced_type_part instanceof TClosure) {
                        if (isset($replaced_type_part->params[$closure_param_offset]->type)) {
                            $replaced_param_type = $replaced_type_part->params[$closure_param_offset]->type;
                            if ($replaced_param_type->hasTemplate()) {
                                $replaced_param_type = TypeExpander::expandUnion($codebase, $replaced_param_type, null, null, null, \true, \false, \false, \true, \true);
                            }
                            if ($param_storage->type && !$param_type_inferred) {
                                $type_match_found = UnionTypeComparator::isContainedBy($codebase, $replaced_param_type, $param_storage->type);
                                if (!$type_match_found) {
                                    continue;
                                }
                            }
                            $newly_inferred_type = Type::combineUnionTypes($newly_inferred_type, $replaced_param_type, $codebase);
                        }
                    }
                }
            }
            if ($newly_inferred_type) {
                $param_storage->type = $newly_inferred_type;
                $param_storage->type_inferred = \true;
            }
            if ($param_storage->type && ($method_id === 'array_map' || $method_id === 'array_filter')) {
                $temp = Type::getMixed();
                ArrayFetchAnalyzer::taintArrayFetch($statements_analyzer, $args[1 - $argument_offset]->value, null, $param_storage->type, $temp);
            }
        }
    }
    /**
     * @param   list<PhpParser\Node\Arg>  $args
     * @param   string|MethodIdentifier|null  $method_id
     * @param   array<int,FunctionLikeParameter>        $function_params
     * @return  false|null
     * @psalm-suppress ComplexMethod there's just not much that can be done about this
     */
    public static function checkArgumentsMatch(StatementsAnalyzer $statements_analyzer, array $args, $method_id, array $function_params, ?FunctionLikeStorage $function_storage, ?ClassLikeStorage $class_storage, TemplateResult $template_result, CodeLocation $code_location, Context $context) : ?bool
    {
        $in_call_map = $method_id ? InternalCallMapHandler::inCallMap((string) $method_id) : \false;
        $cased_method_id = (string) $method_id;
        $is_variadic = \false;
        $fq_class_name = null;
        $codebase = $statements_analyzer->getCodebase();
        if ($method_id) {
            if ($method_id instanceof MethodIdentifier) {
                $fq_class_name = $method_id->fq_class_name;
            }
            if ($function_storage) {
                $is_variadic = $function_storage->variadic;
            } elseif (is_string($method_id)) {
                $is_variadic = Functions::isVariadic($codebase, strtolower($method_id), $statements_analyzer->getRootFilePath());
            } else {
                $is_variadic = $codebase->methods->isVariadic($method_id);
            }
        }
        if ($method_id instanceof MethodIdentifier) {
            $cased_method_id = $codebase->methods->getCasedMethodId($method_id);
        } elseif ($function_storage) {
            $cased_method_id = $function_storage->cased_name;
        }
        $calling_class_storage = $class_storage;
        $static_fq_class_name = $fq_class_name;
        $self_fq_class_name = $fq_class_name;
        if ($method_id instanceof MethodIdentifier) {
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
            if ($declaring_method_id && (string) $declaring_method_id !== (string) $method_id) {
                $self_fq_class_name = $declaring_method_id->fq_class_name;
                $class_storage = $codebase->classlike_storage_provider->get($self_fq_class_name);
            }
            $appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
            if ($appearing_method_id && $declaring_method_id !== $appearing_method_id) {
                $self_fq_class_name = $appearing_method_id->fq_class_name;
            }
        }
        if ($function_params && !$is_variadic) {
            foreach ($function_params as $function_param) {
                $is_variadic = $is_variadic || $function_param->is_variadic;
            }
        }
        $has_packed_var = \false;
        foreach ($args as $arg) {
            if ($arg->unpack) {
                $has_packed_var = \true;
            }
        }
        $last_param = $function_params ? $function_params[count($function_params) - 1] : null;
        $class_generic_params = [];
        foreach ($template_result->lower_bounds as $template_name => $type_map) {
            foreach ($type_map as $class => $lower_bounds) {
                if (count($lower_bounds) === 1) {
                    $class_generic_params[$template_name][$class] = reset($lower_bounds)->type;
                }
            }
        }
        if ($function_storage) {
            $template_result = self::getProvisionalTemplateResultForFunctionLike($statements_analyzer, $codebase, $context, $class_storage, $self_fq_class_name, $calling_class_storage, $function_storage, $class_generic_params, $template_result, $args, $function_params, $last_param);
        }
        $function_param_count = count($function_params);
        if (count($function_params) > count($args) && !$has_packed_var) {
            for ($i = count($args), $iMax = count($function_params); $i < $iMax; $i++) {
                if ($function_params[$i]->default_type && $function_params[$i]->type && $function_params[$i]->type->hasTemplate()) {
                    if ($function_params[$i]->default_type instanceof Union) {
                        $default_type = $function_params[$i]->default_type;
                    } else {
                        $default_type_atomic = ConstantTypeResolver::resolve($codebase->classlikes, $function_params[$i]->default_type, $statements_analyzer);
                        $default_type = new Union([$default_type_atomic]);
                    }
                    if ($default_type->hasLiteralValue()) {
                        \Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentAnalyzer::checkArgumentMatches($statements_analyzer, $cased_method_id, $method_id instanceof MethodIdentifier ? $method_id : null, $self_fq_class_name, $static_fq_class_name, $code_location, $function_params[$i], $i, $i, $function_storage->allow_named_arg_calls ?? \true, new VirtualArg(StubsGenerator::getExpressionFromType($default_type)), $default_type, $context, $class_generic_params, $template_result, $function_storage->specialize_call ?? \true, $in_call_map);
                    }
                }
            }
        }
        if (($method_id === 'preg_match_all' || $method_id === 'preg_match') && count($args) > 3) {
            $args = array_reverse($args, \true);
        }
        $arg_function_params = [];
        $matched_args = [];
        $named_args_was_used = \false;
        foreach ($args as $argument_offset => $arg) {
            if ($named_args_was_used && !$arg->name) {
                IssueBuffer::maybeAdd(new InvalidNamedArgument('Cannot use positional argument after named argument', new CodeLocation($statements_analyzer, $arg), (string) $method_id), $statements_analyzer->getSuppressedIssues());
            }
            if ($arg->unpack) {
                if ($function_param_count > $argument_offset) {
                    for ($i = $argument_offset; $i < $function_param_count; $i++) {
                        $arg_function_params[$argument_offset][] = $function_params[$i];
                    }
                }
                if (($arg_value_type = $statements_analyzer->node_data->getType($arg->value)) && $arg_value_type->hasArray()) {
                    /**
                     * @var TArray|TKeyedArray
                     */
                    $array_type = $arg_value_type->getArray();
                    if ($array_type instanceof TKeyedArray) {
                        $array_type = $array_type->getGenericArrayType();
                        $key_types = $array_type->type_params[0]->getAtomicTypes();
                        foreach ($key_types as $key_type) {
                            if (!$key_type instanceof TLiteralString || $function_storage && !$function_storage->allow_named_arg_calls) {
                                continue;
                            }
                            $param_found = \false;
                            foreach ($function_params as $candidate_param) {
                                if ($candidate_param->name === $key_type->value || $candidate_param->is_variadic) {
                                    if ($candidate_param->name === $key_type->value) {
                                        if (isset($matched_args[$candidate_param->name])) {
                                            IssueBuffer::maybeAdd(new InvalidNamedArgument('Parameter $' . $key_type->value . ' has already been used in ' . ($cased_method_id ?: $method_id), new CodeLocation($statements_analyzer, $arg), (string) $method_id), $statements_analyzer->getSuppressedIssues());
                                        }
                                        $matched_args[$candidate_param->name] = \true;
                                    }
                                    $param_found = \true;
                                    break;
                                }
                            }
                            if (!$param_found) {
                                IssueBuffer::maybeAdd(new InvalidNamedArgument('Parameter $' . $key_type->value . ' does not exist on function ' . ($cased_method_id ?: $method_id), new CodeLocation($statements_analyzer, $arg), (string) $method_id), $statements_analyzer->getSuppressedIssues());
                            }
                        }
                    }
                }
            } elseif ($arg->name && (!$function_storage || $function_storage->allow_named_arg_calls)) {
                $named_args_was_used = \true;
                foreach ($function_params as $candidate_param) {
                    if ($candidate_param->name === $arg->name->name || $candidate_param->is_variadic) {
                        if ($candidate_param->name === $arg->name->name) {
                            if (isset($matched_args[$candidate_param->name])) {
                                IssueBuffer::maybeAdd(new InvalidNamedArgument('Parameter $' . $arg->name->name . ' has already been used in ' . ($cased_method_id ?: $method_id), new CodeLocation($statements_analyzer, $arg->name), (string) $method_id), $statements_analyzer->getSuppressedIssues());
                            }
                            $matched_args[$candidate_param->name] = \true;
                        }
                        $arg_function_params[$argument_offset] = [$candidate_param];
                        break;
                    }
                }
                if (!isset($arg_function_params[$argument_offset])) {
                    IssueBuffer::maybeAdd(new InvalidNamedArgument('Parameter $' . $arg->name->name . ' does not exist on function ' . ($cased_method_id ?: $method_id), new CodeLocation($statements_analyzer, $arg->name), (string) $method_id), $statements_analyzer->getSuppressedIssues());
                }
            } elseif ($function_param_count > $argument_offset) {
                $arg_function_params[$argument_offset] = [$function_params[$argument_offset]];
                $matched_args[$function_params[$argument_offset]->name] = \true;
            } elseif ($last_param && $last_param->is_variadic) {
                $arg_function_params[$argument_offset] = [$last_param];
                $matched_args[$last_param->name] = \true;
            }
        }
        foreach ($args as $argument_offset => $arg) {
            if (!isset($arg_function_params[$argument_offset])) {
                continue;
            }
            if ($arg_function_params[$argument_offset][0]->by_ref && $method_id !== 'extract') {
                if (self::handlePossiblyMatchingByRefParam($statements_analyzer, $codebase, (string) $method_id, $cased_method_id, $last_param, $function_params, $argument_offset, $arg, $context, $template_result) === \false) {
                    return null;
                }
            }
            $arg_value_type = $statements_analyzer->node_data->getType($arg->value);
            foreach ($arg_function_params[$argument_offset] as $i => $function_param) {
                if (\Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentAnalyzer::checkArgumentMatches($statements_analyzer, $cased_method_id, $method_id instanceof MethodIdentifier ? $method_id : null, $self_fq_class_name, $static_fq_class_name, $code_location, $function_param, $argument_offset + $i, $i, $function_storage->allow_named_arg_calls ?? \true, $arg, $arg_value_type, $context, $class_generic_params, $template_result, $function_storage->specialize_call ?? \true, $in_call_map) === \false) {
                    return \false;
                }
            }
        }
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $cased_method_id) {
            foreach ($args as $argument_offset => $_) {
                if (!isset($arg_function_params[$argument_offset])) {
                    continue;
                }
                foreach ($arg_function_params[$argument_offset] as $function_param) {
                    if ($function_param->sinks) {
                        if (!$function_storage || $function_storage->specialize_call) {
                            $sink = TaintSink::getForMethodArgument($cased_method_id, $cased_method_id, $argument_offset, $function_param->location, $code_location);
                        } else {
                            $sink = TaintSink::getForMethodArgument($cased_method_id, $cased_method_id, $argument_offset, $function_param->location);
                        }
                        $sink->taints = $function_param->sinks;
                        $statements_analyzer->data_flow_graph->addSink($sink);
                    }
                }
            }
        }
        if ($method_id === 'array_map' || $method_id === 'array_filter') {
            if ($method_id === 'array_map' && count($args) < 2) {
                IssueBuffer::maybeAdd(new TooFewArguments('Too few arguments for ' . $method_id, $code_location, $method_id), $statements_analyzer->getSuppressedIssues());
            } elseif ($method_id === 'array_filter' && count($args) < 1) {
                IssueBuffer::maybeAdd(new TooFewArguments('Too few arguments for ' . $method_id, $code_location, $method_id), $statements_analyzer->getSuppressedIssues());
            }
            \Psalm\Internal\Analyzer\Statements\Expression\Call\ArrayFunctionArgumentsAnalyzer::checkArgumentsMatch($statements_analyzer, $context, $args, $method_id, $context->check_functions);
            return null;
        }
        if ($method_id === 'get_class' && $args === []) {
            //get_class without args only works when inside a class
            if (!$context->self) {
                IssueBuffer::maybeAdd(new TooFewArguments('Cannot call get_class() without argument outside of class scope', $code_location, $method_id), $statements_analyzer->getSuppressedIssues());
                return null;
            }
        }
        self::checkArgCount($statements_analyzer, $codebase, $function_storage, $context, $template_result, $is_variadic, $args, $function_params, $in_call_map, $method_id, $cased_method_id, $code_location);
        return null;
    }
    /**
     * @param  array<int, FunctionLikeParameter> $function_params
     * @return false|null
     */
    private static function handlePossiblyMatchingByRefParam(StatementsAnalyzer $statements_analyzer, Codebase $codebase, string $method_id, ?string $cased_method_id, ?FunctionLikeParameter $last_param, array $function_params, int $argument_offset, PhpParser\Node\Arg $arg, Context $context, ?TemplateResult $template_result) : ?bool
    {
        if ($arg->value instanceof PhpParser\Node\Scalar || $arg->value instanceof PhpParser\Node\Expr\Cast || $arg->value instanceof PhpParser\Node\Expr\Array_ || $arg->value instanceof PhpParser\Node\Expr\ClassConstFetch || $arg->value instanceof PhpParser\Node\Expr\BinaryOp || $arg->value instanceof PhpParser\Node\Expr\Ternary || ($arg->value instanceof PhpParser\Node\Expr\ConstFetch || $arg->value instanceof PhpParser\Node\Expr\FuncCall || $arg->value instanceof PhpParser\Node\Expr\MethodCall || $arg->value instanceof PhpParser\Node\Expr\StaticCall) && (!($arg_value_type = $statements_analyzer->node_data->getType($arg->value)) || !$arg_value_type->by_ref)) {
            IssueBuffer::maybeAdd(new InvalidPassByReference('Parameter ' . ($argument_offset + 1) . ' of ' . $cased_method_id . ' expects a variable', new CodeLocation($statements_analyzer->getSource(), $arg->value)), $statements_analyzer->getSuppressedIssues());
            return \false;
        }
        if (!in_array($method_id, ['ksort', 'asort', 'krsort', 'arsort', 'natcasesort', 'natsort', 'reset', 'end', 'next', 'prev', 'array_pop', 'array_shift', 'array_push', 'array_unshift', 'socket_select', 'array_splice'], \true)) {
            $by_ref_type = null;
            $by_ref_out_type = null;
            $check_null_ref = \true;
            if ($last_param) {
                if ($argument_offset < count($function_params)) {
                    $function_param = $function_params[$argument_offset];
                } else {
                    $function_param = $last_param;
                }
                if ($function_param->type) {
                    $by_ref_type = $function_param->type;
                }
                if ($function_param->out_type) {
                    $by_ref_out_type = $function_param->out_type;
                }
                if ($by_ref_type && $by_ref_type->isNullable()) {
                    $check_null_ref = \false;
                }
                if ($template_result && $by_ref_type) {
                    $original_by_ref_type = $by_ref_type;
                    $by_ref_type = TemplateStandinTypeReplacer::replace($by_ref_type, $template_result, $codebase, $statements_analyzer, $statements_analyzer->node_data->getType($arg->value), $argument_offset, $context->self, $context->calling_method_id ?: $context->calling_function_id);
                    if ($template_result->lower_bounds) {
                        $original_by_ref_type = TemplateInferredTypeReplacer::replace($original_by_ref_type, $template_result, $codebase);
                        $by_ref_type = $original_by_ref_type;
                    }
                }
                if ($template_result && $by_ref_out_type) {
                    $original_by_ref_out_type = $by_ref_out_type;
                    $by_ref_out_type = TemplateStandinTypeReplacer::replace($by_ref_out_type, $template_result, $codebase, $statements_analyzer, $statements_analyzer->node_data->getType($arg->value), $argument_offset, $context->self, $context->calling_method_id ?: $context->calling_function_id);
                    if ($template_result->lower_bounds) {
                        $original_by_ref_out_type = TemplateInferredTypeReplacer::replace($original_by_ref_out_type, $template_result, $codebase);
                        $by_ref_out_type = $original_by_ref_out_type;
                    }
                }
                if ($by_ref_type && $function_param->is_variadic && $arg->unpack) {
                    $by_ref_type = new Union([new TArray([Type::getInt(), $by_ref_type])]);
                }
            }
            $by_ref_type = $by_ref_type ?: Type::getMixed();
            AssignmentAnalyzer::assignByRefParam($statements_analyzer, $arg->value, $by_ref_type, $by_ref_out_type ?: $by_ref_type, $context, $method_id && (strpos($method_id, '::') !== \false || !InternalCallMapHandler::inCallMap($method_id)), $check_null_ref);
        }
        return null;
    }
    /**
     * @return false|null
     */
    private static function evaluateArbitraryParam(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Arg $arg, Context $context) : ?bool
    {
        // there are a bunch of things we want to evaluate even when we don't
        // know what function/method is being called
        if ($arg->value instanceof PhpParser\Node\Expr\Closure || $arg->value instanceof PhpParser\Node\Expr\ConstFetch || $arg->value instanceof PhpParser\Node\Expr\ClassConstFetch || $arg->value instanceof PhpParser\Node\Expr\FuncCall || $arg->value instanceof PhpParser\Node\Expr\MethodCall || $arg->value instanceof PhpParser\Node\Expr\StaticCall || $arg->value instanceof PhpParser\Node\Expr\ArrowFunction || $arg->value instanceof PhpParser\Node\Expr\New_ || $arg->value instanceof PhpParser\Node\Expr\Cast || $arg->value instanceof PhpParser\Node\Expr\Assign || $arg->value instanceof PhpParser\Node\Expr\ArrayDimFetch || $arg->value instanceof PhpParser\Node\Expr\PropertyFetch || $arg->value instanceof PhpParser\Node\Expr\Array_ || $arg->value instanceof PhpParser\Node\Expr\BinaryOp || $arg->value instanceof PhpParser\Node\Expr\Ternary || $arg->value instanceof PhpParser\Node\Scalar\Encapsed || $arg->value instanceof PhpParser\Node\Expr\PostInc || $arg->value instanceof PhpParser\Node\Expr\PostDec || $arg->value instanceof PhpParser\Node\Expr\PreInc || $arg->value instanceof PhpParser\Node\Expr\PreDec) {
            $was_inside_call = $context->inside_call;
            $context->inside_call = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context) === \false) {
                $context->inside_call = $was_inside_call;
                return \false;
            }
            $context->inside_call = $was_inside_call;
        }
        if ($arg->value instanceof PhpParser\Node\Expr\PropertyFetch && $arg->value->name instanceof PhpParser\Node\Identifier) {
            $var_id = '$' . $arg->value->name->name;
        } else {
            $var_id = ExpressionIdentifier::getVarId($arg->value, $statements_analyzer->getFQCLN(), $statements_analyzer);
        }
        if ($var_id) {
            if ($arg->value instanceof PhpParser\Node\Expr\Variable) {
                $statements_analyzer->registerPossiblyUndefinedVariable($var_id, $arg->value);
            }
            if (!$context->hasVariable($var_id) || $context->vars_in_scope[$var_id]->isNull()) {
                if (!isset($context->vars_in_scope[$var_id]) && $arg->value instanceof PhpParser\Node\Expr\Variable) {
                    IssueBuffer::maybeAdd(new PossiblyUndefinedVariable('Variable ' . $var_id . ' must be defined prior to use within an unknown function or method', new CodeLocation($statements_analyzer->getSource(), $arg->value)), $statements_analyzer->getSuppressedIssues());
                }
                // we don't know if it exists, assume it's passed by reference
                $context->vars_in_scope[$var_id] = Type::getMixed();
                $context->vars_possibly_in_scope[$var_id] = \true;
            } else {
                $was_inside_call = $context->inside_call;
                $context->inside_call = \true;
                ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context);
                $context->inside_call = $was_inside_call;
                $context->removeVarFromConflictingClauses($var_id, $context->vars_in_scope[$var_id], $statements_analyzer);
                $t = $context->vars_in_scope[$var_id]->getBuilder();
                foreach ($t->getAtomicTypes() as $type) {
                    if ($type instanceof TArray && $type->isEmptyArray()) {
                        $t->removeType('array');
                        $t->addType(new TArray([Type::getArrayKey(), Type::getMixed()]));
                    }
                }
                $context->vars_in_scope[$var_id] = $t->freeze();
            }
        }
        return null;
    }
    /**
     * @return false|null
     */
    private static function handleByRefFunctionArg(StatementsAnalyzer $statements_analyzer, ?string $method_id, int $argument_offset, PhpParser\Node\Arg $arg, Context $context) : ?bool
    {
        $var_id = ExpressionIdentifier::getVarId($arg->value, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $builtin_array_functions = ['ksort', 'asort', 'krsort', 'arsort', 'natcasesort', 'natsort', 'reset', 'end', 'next', 'prev', 'array_pop', 'array_shift'];
        if ($var_id && isset($context->vars_in_scope[$var_id]) || $method_id && in_array($method_id, $builtin_array_functions, \true)) {
            $was_inside_assignment = $context->inside_assignment;
            $context->inside_assignment = \true;
            // if the variable is in scope, get or we're in a special array function,
            // figure out its type before proceeding
            if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context) === \false) {
                $context->inside_assignment = $was_inside_assignment;
                return \false;
            }
            $context->inside_assignment = $was_inside_assignment;
        }
        // special handling for array sort
        if ($argument_offset === 0 && $method_id && in_array($method_id, $builtin_array_functions, \true)) {
            if (in_array($method_id, ['array_pop', 'array_shift'], \true)) {
                \Psalm\Internal\Analyzer\Statements\Expression\Call\ArrayFunctionArgumentsAnalyzer::handleByRefArrayAdjustment($statements_analyzer, $arg, $context, $method_id === 'array_shift');
                return null;
            }
            // noops
            if (in_array($method_id, ['reset', 'end', 'next', 'prev', 'ksort'], \true)) {
                return null;
            }
            if (($arg_value_type = $statements_analyzer->node_data->getType($arg->value)) && $arg_value_type->hasArray()) {
                /**
                 * @var TArray|TKeyedArray
                 */
                $array_type = $arg_value_type->getArray();
                if ($array_type instanceof TKeyedArray) {
                    $array_type = $array_type->getGenericArrayType();
                }
                $by_ref_type = new Union([$array_type]);
                AssignmentAnalyzer::assignByRefParam($statements_analyzer, $arg->value, $by_ref_type, $by_ref_type, $context, \false);
                return null;
            }
        }
        if ($method_id === 'socket_select') {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context) === \false) {
                return \false;
            }
        }
        if (!$arg->value instanceof PhpParser\Node\Expr\Variable) {
            $suppressed_issues = $statements_analyzer->getSuppressedIssues();
            if (!in_array('EmptyArrayAccess', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['EmptyArrayAccess']);
            }
            if (ExpressionAnalyzer::analyze($statements_analyzer, $arg->value, $context) === \false) {
                return \false;
            }
            if (!in_array('EmptyArrayAccess', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['EmptyArrayAccess']);
            }
        }
        return null;
    }
    /**
     * @param   list<PhpParser\Node\Arg> $args
     * @param   array<int,FunctionLikeParameter>        $function_params
     * @param   array<string, array<string, Union>>  $class_generic_params
     */
    private static function getProvisionalTemplateResultForFunctionLike(StatementsAnalyzer $statements_analyzer, Codebase $codebase, Context $context, ?ClassLikeStorage $class_storage, ?string $self_fq_class_name, ?ClassLikeStorage $calling_class_storage, FunctionLikeStorage $function_storage, array $class_generic_params, ?TemplateResult $template_result, array $args, array $function_params, ?FunctionLikeParameter $last_param) : ?TemplateResult
    {
        $template_types = CallAnalyzer::getTemplateTypesForCall($codebase, $class_storage, $self_fq_class_name, $calling_class_storage, $function_storage->template_types ?: [], $class_generic_params);
        if (!$template_types) {
            return null;
        }
        if (!$template_result) {
            return new TemplateResult($template_types, []);
        }
        if (!$template_result->template_types) {
            $template_result->template_types = $template_types;
        }
        foreach ($args as $argument_offset => $arg) {
            $function_param = null;
            if ($arg->name && $function_storage->allow_named_arg_calls) {
                foreach ($function_params as $candidate_param) {
                    if ($candidate_param->name === $arg->name->name) {
                        $function_param = $candidate_param;
                        break;
                    }
                }
            } elseif ($argument_offset < count($function_params)) {
                $function_param = $function_params[$argument_offset];
            } elseif ($last_param && $last_param->is_variadic) {
                $function_param = $last_param;
            }
            if (!$function_param || !$function_param->type) {
                continue;
            }
            $arg_value_type = $statements_analyzer->node_data->getType($arg->value);
            if (!$arg_value_type) {
                continue;
            }
            $fleshed_out_param_type = TypeExpander::expandUnion($codebase, $function_param->type, $class_storage->name ?? null, $calling_class_storage->name ?? null, null, \true, \false, $calling_class_storage->final ?? \false);
            TemplateStandinTypeReplacer::fillTemplateResult($fleshed_out_param_type, $template_result, $codebase, $statements_analyzer, $arg_value_type, $argument_offset, $context->self, $context->calling_method_id ?: $context->calling_function_id, \false);
        }
        return $template_result;
    }
    /**
     * @param   array<int, PhpParser\Node\Arg>  $args
     * @param   string|MethodIdentifier|null  $method_id
     * @param   array<int,FunctionLikeParameter>        $function_params
     */
    private static function checkArgCount(StatementsAnalyzer $statements_analyzer, Codebase $codebase, ?FunctionLikeStorage $function_storage, Context $context, ?TemplateResult $template_result, bool $is_variadic, array $args, array $function_params, bool $in_call_map, $method_id, ?string $cased_method_id, CodeLocation $code_location) : void
    {
        if (!$is_variadic && count($args) > count($function_params) && (!count($function_params) || $function_params[count($function_params) - 1]->name !== '...=') && ($in_call_map || !$function_storage instanceof MethodStorage || $function_storage->is_static || $method_id instanceof MethodIdentifier && $method_id->method_name === '__construct')) {
            IssueBuffer::maybeAdd(new TooManyArguments('Too many arguments for ' . ($cased_method_id ?: $method_id) . ' - expecting ' . count($function_params) . ' but saw ' . count($args), $code_location, (string) $method_id), $statements_analyzer->getSuppressedIssues());
            return;
        }
        if (count($args) < count($function_params)) {
            //we're gonna loop over given args and unset them from the function_params.
            // If some mandatory params are left at the end, we'll throw an error
            foreach ($args as $arg) {
                // when the argument is not named, we can remove the params in order
                if ($arg->name === null) {
                    // if we're unpacking, we try to unset the exact number of params, if we can't we give up and return
                    if ($arg->unpack) {
                        $arg_value_type = $statements_analyzer->node_data->getType($arg->value);
                        if (!$arg_value_type || !$arg_value_type->hasArray()) {
                            return;
                        }
                        if ($arg_value_type->isSingle() && ($atomic_arg_type = $arg_value_type->getSingleAtomic()) && $atomic_arg_type instanceof TKeyedArray && !$atomic_arg_type->is_list) {
                            //if we have a single shape, we'll check param names
                            foreach ($atomic_arg_type->properties as $property_name => $_property_type) {
                                foreach ($function_params as $k => $param) {
                                    if ($param->name === $property_name) {
                                        unset($function_params[$k]);
                                    }
                                }
                            }
                            continue;
                        }
                        foreach ($arg_value_type->getAtomicTypes() as $atomic_arg_type) {
                            if ($atomic_arg_type instanceof TList) {
                                $atomic_arg_type = $atomic_arg_type->getKeyedArray();
                            }
                            $packed_var_definite_args_tmp = [];
                            if ($atomic_arg_type instanceof TCallableArray || $atomic_arg_type instanceof TCallableKeyedArray) {
                                $packed_var_definite_args_tmp[] = 2;
                            } elseif ($atomic_arg_type instanceof TKeyedArray) {
                                if ($atomic_arg_type->fallback_params !== null) {
                                    return;
                                }
                                if (!$atomic_arg_type->allShapeKeysAlwaysDefined()) {
                                    return;
                                }
                                //we did not return. The number of packed params is the number of properties
                                $packed_var_definite_args_tmp[] = count($atomic_arg_type->properties);
                            } elseif ($atomic_arg_type instanceof TNonEmptyArray) {
                                if ($atomic_arg_type->count === null) {
                                    return;
                                }
                                $packed_var_definite_args_tmp[] = $atomic_arg_type->count;
                            } elseif ($atomic_arg_type instanceof TArray && $atomic_arg_type->type_params[1]->isNever()) {
                                $packed_var_definite_args_tmp[] = 0;
                            } else {
                                return;
                            }
                            if (min($packed_var_definite_args_tmp) === max($packed_var_definite_args_tmp)) {
                                //we have a stable number of params
                                $packed_var_definite_args = $packed_var_definite_args_tmp[0];
                            } else {
                                return;
                            }
                        }
                    } else {
                        //if we're not unpacking, we remove the first param
                        $packed_var_definite_args = 1;
                    }
                    $function_params = array_slice($function_params, $packed_var_definite_args);
                    continue;
                }
                foreach ($function_params as $k => $param) {
                    if ($param->name === $arg->name->name) {
                        unset($function_params[$k]);
                        continue;
                    }
                }
            }
            //we're now left with an array of params that were not passed.
            // If they're mandatory, throw an error. Otherwise, we compute the default value
            foreach ($function_params as $i => $param) {
                if (!$param->is_optional && !$param->is_variadic) {
                    IssueBuffer::maybeAdd(new TooFewArguments('Too few arguments for ' . $cased_method_id . ' - expecting ' . $param->name . ' to be passed', $code_location, (string) $method_id), $statements_analyzer->getSuppressedIssues());
                    continue;
                }
                if ($param->type && $param->default_type && !$param->is_variadic && $template_result) {
                    if ($param->default_type instanceof Union) {
                        $default_type = $param->default_type;
                    } else {
                        $default_type_atomic = ConstantTypeResolver::resolve($codebase->classlikes, $param->default_type, $statements_analyzer);
                        $default_type = new Union([$default_type_atomic]);
                    }
                    TemplateStandinTypeReplacer::fillTemplateResult($param->type, $template_result, $codebase, $statements_analyzer, $default_type, $i, $context->self, $context->calling_method_id ?: $context->calling_function_id, \true);
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodCallProhibitionAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateBound;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Internal\TypeVisitor\ContainsStaticVisitor;
use Psalm\Issue\AbstractMethodCall;
use Psalm\Issue\ImpureMethodCall;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AfterMethodCallAnalysisEvent;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\Possibilities;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Union;
use function array_map;
use function count;
use function explode;
use function in_array;
use function is_string;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class ExistingAtomicStaticCallAnalyzer
{
    /**
     * @param  list<PhpParser\Node\Arg> $args
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, PhpParser\Node\Identifier $stmt_name, array $args, Context $context, Atomic $lhs_type_part, MethodIdentifier $method_id, string $cased_method_id, ClassLikeStorage $class_storage, bool &$moved_call, ?TemplateResult $inferred_template_result = null) : void
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name_lc = $method_id->method_name;
        $codebase = $statements_analyzer->getCodebase();
        $config = $codebase->config;
        MethodCallProhibitionAnalyzer::analyze($codebase, $context, $method_id, $statements_analyzer->getFullyQualifiedFunctionMethodOrNamespaceName(), new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues());
        if ($class_storage->user_defined && $context->self && ($context->collect_mutations || $context->collect_initializations)) {
            $appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
            if (!$appearing_method_id) {
                return;
            }
            $appearing_method_class_name = $appearing_method_id->fq_class_name;
            if ($codebase->classExtends($context->self, $appearing_method_class_name)) {
                $old_context_include_location = $context->include_location;
                $old_self = $context->self;
                $context->include_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                $context->self = $appearing_method_class_name;
                $file_analyzer = $statements_analyzer->getFileAnalyzer();
                if ($context->collect_mutations) {
                    $file_analyzer->getMethodMutations($appearing_method_id, $context);
                } else {
                    // collecting initializations
                    $local_vars_in_scope = [];
                    $local_vars_possibly_in_scope = [];
                    foreach ($context->vars_in_scope as $var => $_) {
                        if (strpos($var, '$this->') !== 0 && $var !== '$this') {
                            $local_vars_in_scope[$var] = $context->vars_in_scope[$var];
                        }
                    }
                    foreach ($context->vars_possibly_in_scope as $var => $_) {
                        if (strpos($var, '$this->') !== 0 && $var !== '$this') {
                            $local_vars_possibly_in_scope[$var] = $context->vars_possibly_in_scope[$var];
                        }
                    }
                    if (!isset($context->initialized_methods[(string) $appearing_method_id])) {
                        if ($context->initialized_methods === null) {
                            $context->initialized_methods = [];
                        }
                        $context->initialized_methods[(string) $appearing_method_id] = \true;
                        $file_analyzer->getMethodMutations($appearing_method_id, $context);
                        foreach ($local_vars_in_scope as $var => $type) {
                            $context->vars_in_scope[$var] = $type;
                        }
                        foreach ($local_vars_possibly_in_scope as $var => $type) {
                            $context->vars_possibly_in_scope[$var] = $type;
                        }
                    }
                }
                $context->include_location = $old_context_include_location;
                $context->self = $old_self;
            }
        }
        $found_generic_params = ClassTemplateParamCollector::collect($codebase, $class_storage, $class_storage, $method_name_lc, $lhs_type_part, !$statements_analyzer->isStatic() && $method_id->fq_class_name === $context->self);
        if ($found_generic_params && $stmt->class instanceof PhpParser\Node\Name && $stmt->class->parts === ['parent'] && $context->self && ($self_class_storage = $codebase->classlike_storage_provider->get($context->self)) && $self_class_storage->template_extended_params) {
            foreach ($self_class_storage->template_extended_params as $template_fq_class_name => $extended_types) {
                foreach ($extended_types as $type_key => $extended_type) {
                    if (isset($found_generic_params[$type_key][$template_fq_class_name])) {
                        $found_generic_params[$type_key][$template_fq_class_name] = $extended_type;
                        continue;
                    }
                    foreach ($extended_type->getAtomicTypes() as $t) {
                        if ($t instanceof TTemplateParam && isset($found_generic_params[$t->param_name][$t->defining_class])) {
                            $found_generic_params[$type_key][$template_fq_class_name] = $found_generic_params[$t->param_name][$t->defining_class];
                        } else {
                            $found_generic_params[$type_key][$template_fq_class_name] = $extended_type;
                            break;
                        }
                    }
                }
            }
        }
        $template_result = new TemplateResult([], $found_generic_params ?: []);
        if ($inferred_template_result) {
            $template_result->lower_bounds += $inferred_template_result->lower_bounds;
        }
        if (CallAnalyzer::checkMethodArgs($method_id, $args, $template_result, $context, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer) === \false) {
            return;
        }
        $fq_class_name = $stmt->class instanceof PhpParser\Node\Name && $stmt->class->parts === ['parent'] ? (string) $statements_analyzer->getFQCLN() : $fq_class_name;
        $self_fq_class_name = $fq_class_name;
        $return_type_candidate = null;
        if ($codebase->methods->return_type_provider->has($fq_class_name)) {
            $return_type_candidate = $codebase->methods->return_type_provider->getReturnType($statements_analyzer, $fq_class_name, $stmt_name->name, $stmt, $context, new CodeLocation($statements_analyzer->getSource(), $stmt_name));
        }
        $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
        if (!$return_type_candidate && $declaring_method_id && (string) $declaring_method_id !== (string) $method_id) {
            $declaring_fq_class_name = $declaring_method_id->fq_class_name;
            $declaring_method_name = $declaring_method_id->method_name;
            if ($codebase->methods->return_type_provider->has($declaring_fq_class_name)) {
                $return_type_candidate = $codebase->methods->return_type_provider->getReturnType($statements_analyzer, $declaring_fq_class_name, $declaring_method_name, $stmt, $context, new CodeLocation($statements_analyzer->getSource(), $stmt_name), null, $fq_class_name, $stmt_name->name);
            }
        }
        if (!$return_type_candidate) {
            $return_type_candidate = self::getMethodReturnType($statements_analyzer, $codebase, $stmt, $method_id, $args, $template_result, $self_fq_class_name, $lhs_type_part, $context, $fq_class_name, $class_storage, $config);
        }
        $method_storage = $codebase->methods->getUserMethodStorage($method_id);
        if ($method_storage) {
            if ($method_storage->abstract && $stmt->class instanceof PhpParser\Node\Name && (!$context->self || !UnionTypeComparator::isContainedBy($codebase, $context->vars_in_scope['$this'] ?? new Union([new TNamedObject($context->self)]), new Union([new TNamedObject($method_id->fq_class_name)])))) {
                IssueBuffer::maybeAdd(new AbstractMethodCall('Cannot call an abstract static method ' . $method_id . ' directly', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            if (!$context->inside_throw) {
                if ($context->pure && !$method_storage->pure) {
                    IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call an impure method from a pure context', new CodeLocation($statements_analyzer, $stmt_name)), $statements_analyzer->getSuppressedIssues());
                } elseif ($context->mutation_free && !$method_storage->mutation_free) {
                    IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating method from a mutation-free context', new CodeLocation($statements_analyzer, $stmt_name)), $statements_analyzer->getSuppressedIssues());
                } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations && !$method_storage->pure) {
                    if (!$method_storage->mutation_free) {
                        $statements_analyzer->getSource()->inferred_has_mutation = \true;
                    }
                    $statements_analyzer->getSource()->inferred_impure = \true;
                }
            }
            if ($method_storage->assertions) {
                CallAnalyzer::applyAssertionsToContext($stmt_name, null, $method_storage->assertions, $stmt->getArgs(), $template_result, $context, $statements_analyzer);
            }
            if ($method_storage->if_true_assertions) {
                $statements_analyzer->node_data->setIfTrueAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, null, $codebase), $method_storage->if_true_assertions));
            }
            if ($method_storage->if_false_assertions) {
                $statements_analyzer->node_data->setIfFalseAssertions($stmt, array_map(static fn(Possibilities $assertion): Possibilities => $assertion->getUntemplatedCopy($template_result, null, $codebase), $method_storage->if_false_assertions));
            }
        }
        if ($codebase->alter_code) {
            foreach ($codebase->call_transforms as $original_pattern => $transformation) {
                if ($declaring_method_id && strtolower((string) $declaring_method_id) . '\\((.*\\))' === $original_pattern) {
                    if (strpos($transformation, '($1)') === strlen($transformation) - 4 && $stmt->class instanceof PhpParser\Node\Name) {
                        $new_method_id = substr($transformation, 0, -4);
                        $old_declaring_fq_class_name = $declaring_method_id->fq_class_name;
                        [$new_fq_class_name, $new_method_name] = explode('::', $new_method_id);
                        if ($codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $new_fq_class_name, $context->calling_method_id, strtolower($old_declaring_fq_class_name) !== strtolower($new_fq_class_name), $stmt->class->parts[0] === 'self')) {
                            $moved_call = \true;
                        }
                        $file_manipulations = [];
                        $file_manipulations[] = new FileManipulation((int) $stmt_name->getAttribute('startFilePos'), (int) $stmt_name->getAttribute('endFilePos') + 1, $new_method_name);
                        FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                    }
                }
            }
        }
        if ($config->eventDispatcher->hasAfterMethodCallAnalysisHandlers()) {
            $file_manipulations = [];
            $appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
            if ($appearing_method_id !== null && $declaring_method_id) {
                $event = new AfterMethodCallAnalysisEvent($stmt, (string) $method_id, (string) $appearing_method_id, (string) $declaring_method_id, $context, $statements_analyzer, $codebase, $file_manipulations, $return_type_candidate);
                $config->eventDispatcher->dispatchAfterMethodCallAnalysis($event);
                $file_manipulations = $event->getFileReplacements();
                $return_type_candidate = $event->getReturnTypeCandidate();
            }
            if ($file_manipulations) {
                FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
            }
        }
        $return_type_candidate ??= Type::getMixed();
        StaticCallAnalyzer::taintReturnType($statements_analyzer, $stmt, $method_id, $cased_method_id, $return_type_candidate, $method_storage, $template_result, $context);
        $stmt_type = $statements_analyzer->node_data->getType($stmt);
        $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes($stmt_type, $return_type_candidate));
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $method_id . '()');
            if ($stmt_type = $statements_analyzer->node_data->getType($stmt)) {
                $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_type->getId(), $stmt);
            }
        }
    }
    /**
     * @param list<PhpParser\Node\Arg> $args
     */
    private static function getMethodReturnType(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\StaticCall $stmt, MethodIdentifier $method_id, array $args, TemplateResult $template_result, ?string &$self_fq_class_name, Atomic $lhs_type_part, Context $context, string $fq_class_name, ClassLikeStorage $class_storage, Config $config) : ?Union
    {
        $return_type_candidate = $codebase->methods->getMethodReturnType($method_id, $self_fq_class_name, $statements_analyzer, $args);
        if ($return_type_candidate) {
            if ($template_result->template_types) {
                $bindable_template_types = $return_type_candidate->getTemplateTypes();
                foreach ($bindable_template_types as $template_type) {
                    if (!isset($template_result->lower_bounds[$template_type->param_name][$template_type->defining_class])) {
                        if ($template_type->param_name === 'TFunctionArgCount') {
                            $template_result->lower_bounds[$template_type->param_name] = ['fn-' . strtolower((string) $method_id) => [new TemplateBound(Type::getInt(\false, count($stmt->getArgs())))]];
                        } elseif ($template_type->param_name === 'TPhpMajorVersion') {
                            $template_result->lower_bounds[$template_type->param_name] = ['fn-' . strtolower((string) $method_id) => [new TemplateBound(Type::getInt(\false, $codebase->getMajorAnalysisPhpVersion()))]];
                        } elseif ($template_type->param_name === 'TPhpVersionId') {
                            $template_result->lower_bounds[$template_type->param_name] = ['fn-' . strtolower((string) $method_id) => [new TemplateBound(Type::getInt(\false, $codebase->analysis_php_version_id))]];
                        } else {
                            $template_result->lower_bounds[$template_type->param_name] = [$template_type->defining_class => [new TemplateBound(Type::getNever())]];
                        }
                    }
                }
            }
            $context_final = \false;
            if ($lhs_type_part instanceof TTemplateParam) {
                $static_type = $lhs_type_part;
            } elseif ($lhs_type_part instanceof TTemplateParamClass) {
                $static_type = new TTemplateParam($lhs_type_part->param_name, $lhs_type_part->as_type ? new Union([$lhs_type_part->as_type]) : Type::getObject(), $lhs_type_part->defining_class);
            } elseif ($stmt->class instanceof PhpParser\Node\Name && count($stmt->class->parts) === 1 && in_array(strtolower($stmt->class->parts[0]), ['self', 'static', 'parent'], \true) && $lhs_type_part instanceof TNamedObject && $context->self) {
                $static_type = $context->self;
                $context_final = $codebase->classlike_storage_provider->get($context->self)->final;
            } elseif ($context->calling_method_id !== null) {
                // differentiate between these cases:
                //   1. "static" comes from the CALLED static method - use $fq_class_name.
                //   2. "static" in return type comes from return type of the
                //   method CALLING the currently analyzed static method - use $context->self.
                $static_type = self::hasStaticInType($return_type_candidate) ? $fq_class_name : $context->self;
            } else {
                $static_type = $fq_class_name;
            }
            if ($template_result->lower_bounds) {
                $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, null, null, null);
                $return_type_candidate = TemplateInferredTypeReplacer::replace($return_type_candidate, $template_result, $codebase);
            }
            $return_type_candidate = TypeExpander::expandUnion($codebase, $return_type_candidate, $self_fq_class_name, $static_type, $class_storage->parent_class, \true, \false, is_string($static_type) && ($static_type !== $context->self || $class_storage->final || $context_final));
            $secondary_return_type_location = null;
            $return_type_location = $codebase->methods->getMethodReturnTypeLocation($method_id, $secondary_return_type_location);
            if ($secondary_return_type_location) {
                $return_type_location = $secondary_return_type_location;
            }
            // only check the type locally if it's defined externally
            if ($return_type_location && !$config->isInProjectDirs($return_type_location->file_path)) {
                /** @psalm-suppress UnusedMethodCall Actually generates issues */
                $return_type_candidate->check($statements_analyzer, new CodeLocation($statements_analyzer, $stmt), $statements_analyzer->getSuppressedIssues(), $context->phantom_classes, \true, \false, \false, $context->calling_method_id);
            }
        }
        return $return_type_candidate;
    }
    /**
     * Dumb way to determine whether a type contains "static" somewhere inside.
     */
    private static function hasStaticInType(Type\TypeNode $type) : bool
    {
        $visitor = new ContainsStaticVisitor();
        $visitor->traverse($type);
        return $visitor->matches();
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod;

use Exception;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\MethodAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentMapPopulator;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\Method\MethodVisibilityAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InvalidStringClass;
use Psalm\Issue\MixedMethodCall;
use Psalm\Issue\UndefinedClass;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualArray;
use Psalm\Node\Expr\VirtualArrayItem;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Scalar\VirtualString;
use Psalm\Node\VirtualArg;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TDependentGetClass;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_filter;
use function array_map;
use function array_values;
use function assert;
use function count;
use function in_array;
use function strtolower;
/**
 * @internal
 */
class AtomicStaticCallAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, Context $context, Atomic $lhs_type_part, bool $ignore_nullable_issues, bool &$moved_call, bool &$has_mock, bool &$has_existing_method, ?TemplateResult $inferred_template_result = null) : void
    {
        $intersection_types = [];
        if ($lhs_type_part instanceof TNamedObject) {
            $fq_class_name = $lhs_type_part->value;
            if (!ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($statements_analyzer, $stmt->class), !$context->collect_initializations && !$context->collect_mutations ? $context->self : null, !$context->collect_initializations && !$context->collect_mutations ? $context->calling_method_id : null, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions($stmt->class instanceof PhpParser\Node\Name && count($stmt->class->parts) === 1 && in_array(strtolower($stmt->class->parts[0]), ['self', 'static'], \true)))) {
                return;
            }
            $intersection_types = $lhs_type_part->extra_types;
        } elseif ($lhs_type_part instanceof TClassString && $lhs_type_part->as_type) {
            $fq_class_name = $lhs_type_part->as_type->value;
            if (!ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($statements_analyzer, $stmt->class), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues())) {
                return;
            }
            $intersection_types = $lhs_type_part->as_type->extra_types;
        } elseif ($lhs_type_part instanceof TDependentGetClass && !$lhs_type_part->as_type->hasObject()) {
            $fq_class_name = 'object';
            if ($lhs_type_part->as_type->hasObjectType() && $lhs_type_part->as_type->isSingle()) {
                foreach ($lhs_type_part->as_type->getAtomicTypes() as $typeof_type_atomic) {
                    if ($typeof_type_atomic instanceof TNamedObject) {
                        $fq_class_name = $typeof_type_atomic->value;
                    }
                }
            }
            if ($fq_class_name === 'object') {
                return;
            }
        } elseif ($lhs_type_part instanceof TLiteralClassString) {
            $fq_class_name = $lhs_type_part->value;
            if (!ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($statements_analyzer, $stmt->class), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues())) {
                return;
            }
        } elseif ($lhs_type_part instanceof TTemplateParam && !$lhs_type_part->as->isMixed() && !$lhs_type_part->as->hasObject()) {
            $fq_class_name = null;
            foreach ($lhs_type_part->as->getAtomicTypes() as $generic_param_type) {
                if (!$generic_param_type instanceof TNamedObject) {
                    return;
                }
                $fq_class_name = $generic_param_type->value;
                break;
            }
            if (!$fq_class_name) {
                IssueBuffer::maybeAdd(new UndefinedClass('Type ' . $lhs_type_part->as . ' cannot be called as a class', new CodeLocation($statements_analyzer->getSource(), $stmt), (string) $lhs_type_part), $statements_analyzer->getSuppressedIssues());
                return;
            }
        } else {
            self::handleNonObjectCall($statements_analyzer, $stmt, $context, $lhs_type_part, $ignore_nullable_issues);
            return;
        }
        $codebase = $statements_analyzer->getCodebase();
        $fq_class_name = $codebase->classlikes->getUnAliasedName($fq_class_name);
        $is_mock = ExpressionAnalyzer::isMock($fq_class_name);
        $has_mock = $has_mock || $is_mock;
        if ($stmt->name instanceof PhpParser\Node\Identifier && !$is_mock) {
            self::handleNamedCall($statements_analyzer, $stmt, $stmt->name, $context, $lhs_type_part, $intersection_types ?: [], $fq_class_name, $moved_call, $has_existing_method, $inferred_template_result);
        } else {
            if ($stmt->name instanceof PhpParser\Node\Expr) {
                $was_inside_general_use = $context->inside_general_use;
                $context->inside_general_use = \true;
                ExpressionAnalyzer::analyze($statements_analyzer, $stmt->name, $context);
                $context->inside_general_use = $was_inside_general_use;
            }
            if (!$context->ignore_variable_method) {
                $codebase->analyzer->addMixedMemberName(strtolower($fq_class_name) . '::', $context->calling_method_id ?: $statements_analyzer->getFileName());
            }
            if ($stmt->isFirstClassCallable()) {
                $return_type_candidate = null;
                if (!$stmt->name instanceof PhpParser\Node\Identifier) {
                    $method_name_type = $statements_analyzer->node_data->getType($stmt->name);
                    if ($method_name_type && $method_name_type->isSingleStringLiteral()) {
                        $method_identifier = new MethodIdentifier($fq_class_name, strtolower($method_name_type->getSingleStringLiteral()->value));
                        //the call to methodExists will register that the method was called from somewhere
                        if ($codebase->methods->methodExists($method_identifier, $context->calling_method_id, null, $statements_analyzer, $statements_analyzer->getFilePath(), \true, $context->insideUse())) {
                            $method_storage = $codebase->methods->getStorage($method_identifier);
                            $return_type_candidate = new Union([new TClosure('Closure', $method_storage->params, $method_storage->return_type, $method_storage->pure)]);
                        }
                    }
                }
                $statements_analyzer->node_data->setType($stmt, $return_type_candidate ?? Type::getClosure());
                return;
            }
            if (ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context) === \false) {
                return;
            }
        }
        if ($codebase->alter_code && $fq_class_name && !$moved_call && $stmt->class instanceof PhpParser\Node\Name && !in_array($stmt->class->parts[0], ['parent', 'static'])) {
            $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id, \false, $stmt->class->parts[0] === 'self');
        }
    }
    /**
     * @psalm-suppress UnusedReturnValue not used but seems important
     * @psalm-suppress ComplexMethod to be refactored
     */
    private static function handleNamedCall(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, PhpParser\Node\Identifier $stmt_name, Context $context, Atomic $lhs_type_part, array $intersection_types, string $fq_class_name, bool &$moved_call, bool &$has_existing_method, ?TemplateResult $inferred_template_result = null) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $method_name_lc = strtolower($stmt_name->name);
        $method_id = new MethodIdentifier($fq_class_name, $method_name_lc);
        $cased_method_id = $fq_class_name . '::' . $stmt_name->name;
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            ArgumentMapPopulator::recordArgumentPositions($statements_analyzer, $stmt, $codebase, (string) $method_id);
        }
        if ($intersection_types && !$codebase->methods->methodExists($method_id)) {
            foreach ($intersection_types as $intersection_type) {
                if (!$intersection_type instanceof TNamedObject) {
                    continue;
                }
                $intersection_method_id = new MethodIdentifier($intersection_type->value, $method_name_lc);
                if ($codebase->methods->methodExists($intersection_method_id)) {
                    $method_id = $intersection_method_id;
                    $cased_method_id = $intersection_type->value . '::' . $stmt_name->name;
                    $fq_class_name = $intersection_type->value;
                    break;
                }
            }
        }
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $naive_method_exists = $codebase->methods->methodExists($method_id, !$context->collect_initializations && !$context->collect_mutations ? $context->calling_method_id : null, $codebase->collect_locations ? new CodeLocation($statements_analyzer, $stmt_name) : null, $statements_analyzer, $statements_analyzer->getFilePath(), \false, $context->insideUse());
        $fake_method_exists = \false;
        if (!$naive_method_exists && $codebase->methods->existence_provider->has($fq_class_name)) {
            $fake_method_exists = $codebase->methods->existence_provider->doesMethodExist($fq_class_name, $method_id->method_name, $statements_analyzer, null) ?? \false;
        }
        $args = $stmt->isFirstClassCallable() ? [] : $stmt->getArgs();
        if (!$naive_method_exists && $class_storage->mixin_declaring_fqcln && $class_storage->namedMixins) {
            foreach ($class_storage->namedMixins as $mixin) {
                $new_method_id = new MethodIdentifier($mixin->value, $method_name_lc);
                if ($codebase->methods->methodExists($new_method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($statements_analyzer, $stmt_name) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath(), \true, $context->insideUse())) {
                    $mixin_candidates = [];
                    foreach ($class_storage->templatedMixins as $mixin_candidate) {
                        $mixin_candidates[] = $mixin_candidate;
                    }
                    foreach ($class_storage->namedMixins as $mixin_candidate) {
                        $mixin_candidates[] = $mixin_candidate;
                    }
                    $mixin_candidates_no_generic = array_filter($mixin_candidates, static fn(Atomic $check): bool => !$check instanceof TGenericObject);
                    // $mixin_candidates_no_generic will only be empty when there are TGenericObject entries.
                    // In that case, Union will be initialized with an empty array but
                    // replaced with non-empty types in the following loop.
                    /** @psalm-suppress ArgumentTypeCoercion */
                    $mixin_candidate_type = new Union($mixin_candidates_no_generic);
                    foreach ($mixin_candidates as $tGenericMixin) {
                        if (!$tGenericMixin instanceof TGenericObject) {
                            continue;
                        }
                        $mixin_declaring_class_storage = $codebase->classlike_storage_provider->get($class_storage->mixin_declaring_fqcln);
                        $new_mixin_candidate_type = AtomicPropertyFetchAnalyzer::localizePropertyType($codebase, new Union([$lhs_type_part]), $tGenericMixin, $class_storage, $mixin_declaring_class_storage)->getBuilder();
                        foreach ($mixin_candidate_type->getAtomicTypes() as $type) {
                            $new_mixin_candidate_type->addType($type);
                        }
                        $mixin_candidate_type = $new_mixin_candidate_type->freeze();
                    }
                    $new_lhs_type = TypeExpander::expandUnion($codebase, $mixin_candidate_type, $fq_class_name, $fq_class_name, $class_storage->parent_class, \true, \false, $class_storage->final);
                    $mixin_context = clone $context;
                    $mixin_context->vars_in_scope['$__tmp_mixin_var__'] = $new_lhs_type;
                    return self::forwardCallToInstanceMethod($statements_analyzer, $stmt, $stmt_name, $mixin_context, '__tmp_mixin_var__', \true);
                }
            }
        }
        $config = $codebase->config;
        $found_method_and_class_storage = self::findPseudoMethodAndClassStorages($codebase, $class_storage, $method_name_lc);
        if ($stmt->isFirstClassCallable()) {
            if ($found_method_and_class_storage) {
                [$method_storage] = $found_method_and_class_storage;
                $return_type_candidate = new Union([new TClosure('Closure', $method_storage->params, $method_storage->return_type, $method_storage->pure)]);
            } else {
                $method_exists = $naive_method_exists || $fake_method_exists || isset($class_storage->methods[$method_name_lc]) || isset($class_storage->pseudo_static_methods[$method_name_lc]);
                if ($method_exists) {
                    $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id) ?? $method_id;
                    $return_type_candidate = new Union([new TClosure('Closure', array_values($codebase->getMethodParams($method_id)), $codebase->getMethodReturnType($method_id, $fq_class_name), $codebase->methods->getStorage($declaring_method_id)->pure)]);
                } else {
                    // FIXME: perhaps Psalm should complain about nonexisting method here, or throw a logic exception?
                    $return_type_candidate = Type::getClosure();
                }
            }
            $expanded_return_type = TypeExpander::expandUnion($codebase, $return_type_candidate, $context->self, $class_storage->name, $context->parent, \true, \false, \true);
            $statements_analyzer->node_data->setType($stmt, $expanded_return_type);
            return \true;
        }
        if (!$naive_method_exists || !MethodAnalyzer::isMethodVisible($method_id, $context, $statements_analyzer->getSource()) || $fake_method_exists || $found_method_and_class_storage && ($config->use_phpdoc_method_without_magic_or_parent || $class_storage->parent_class)) {
            $callstatic_id = new MethodIdentifier($fq_class_name, '__callstatic');
            if ($codebase->methods->methodExists($callstatic_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($statements_analyzer, $stmt_name) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath(), \true, $context->insideUse())) {
                $callstatic_appearing_id = $codebase->methods->getAppearingMethodId($callstatic_id);
                assert($callstatic_appearing_id !== null);
                $callstatic_pure = \false;
                $callstatic_mutation_free = \false;
                if ($codebase->methods->hasStorage($callstatic_appearing_id)) {
                    $callstatic_storage = $codebase->methods->getStorage($callstatic_appearing_id);
                    $callstatic_pure = $callstatic_storage->pure;
                    $callstatic_mutation_free = $callstatic_storage->mutation_free;
                }
                if ($codebase->methods->return_type_provider->has($fq_class_name)) {
                    $return_type_candidate = $codebase->methods->return_type_provider->getReturnType($statements_analyzer, $method_id->fq_class_name, $method_id->method_name, $stmt, $context, new CodeLocation($statements_analyzer->getSource(), $stmt_name), null, null, strtolower($stmt_name->name));
                    if ($return_type_candidate) {
                        CallAnalyzer::checkMethodArgs($method_id, $stmt->getArgs(), new TemplateResult([], []), $context, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer);
                        $statements_analyzer->node_data->setType($stmt, $return_type_candidate);
                        return \true;
                    }
                }
                if ($found_method_and_class_storage) {
                    [$pseudo_method_storage, $defining_class_storage] = $found_method_and_class_storage;
                    if (self::checkPseudoMethod($statements_analyzer, $stmt, $method_id, $fq_class_name, $args, $defining_class_storage, $pseudo_method_storage, $context) === \false) {
                        return \false;
                    }
                    if (!$context->inside_throw) {
                        if ($context->pure && !$callstatic_pure) {
                            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call an impure method from a pure context', new CodeLocation($statements_analyzer, $stmt_name)), $statements_analyzer->getSuppressedIssues());
                        } elseif ($context->mutation_free && !$callstatic_mutation_free) {
                            IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating method from a mutation-free context', new CodeLocation($statements_analyzer, $stmt_name)), $statements_analyzer->getSuppressedIssues());
                        } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations && !$callstatic_pure) {
                            if (!$callstatic_mutation_free) {
                                $statements_analyzer->getSource()->inferred_has_mutation = \true;
                            }
                            $statements_analyzer->getSource()->inferred_impure = \true;
                        }
                    }
                    if ($pseudo_method_storage->return_type) {
                        return \true;
                    }
                } else {
                    if (ArgumentsAnalyzer::analyze($statements_analyzer, $args, null, null, \true, $context) === \false) {
                        return \false;
                    }
                }
                $array_values = array_map(static fn(PhpParser\Node\Arg $arg): PhpParser\Node\Expr\ArrayItem => new VirtualArrayItem($arg->value, null, \false, $arg->getAttributes()), $args);
                $args = [new VirtualArg(new VirtualString((string) $method_id, $stmt_name->getAttributes()), \false, \false, $stmt_name->getAttributes()), new VirtualArg(new VirtualArray($array_values, $stmt->getAttributes()), \false, \false, $stmt->getAttributes())];
                $method_id = new MethodIdentifier($fq_class_name, '__callstatic');
            } elseif ($found_method_and_class_storage && ($config->use_phpdoc_method_without_magic_or_parent || $class_storage->parent_class)) {
                [$pseudo_method_storage, $defining_class_storage] = $found_method_and_class_storage;
                if (self::checkPseudoMethod($statements_analyzer, $stmt, $method_id, $fq_class_name, $args, $defining_class_storage, $pseudo_method_storage, $context) === \false) {
                    return \false;
                }
                if ($pseudo_method_storage->return_type) {
                    return \true;
                }
            } elseif ($stmt->class instanceof PhpParser\Node\Name && $stmt->class->parts[0] === 'parent' && !$codebase->methodExists($method_id) && !$statements_analyzer->isStatic()) {
                // In case of parent::xxx() call on instance method context (i.e. not static context)
                // with nonexistent method, we try to forward to instance method call for resolve pseudo method.
                // Use parent type as static type for the method call
                $tmp_context = clone $context;
                $tmp_context->vars_in_scope['$__tmp_parent_var__'] = new Union([$lhs_type_part]);
                if (self::forwardCallToInstanceMethod($statements_analyzer, $stmt, $stmt_name, $tmp_context, '__tmp_parent_var__') === \false) {
                    return \false;
                }
                unset($tmp_context);
                // Resolve actual static return type according to caller (i.e. $this) static type
                if (isset($context->vars_in_scope['$this']) && ($method_call_type = $statements_analyzer->node_data->getType($stmt))) {
                    $method_call_type = $method_call_type->getBuilder();
                    foreach ($method_call_type->getAtomicTypes() as $name => $type) {
                        if ($type instanceof TNamedObject && $type->is_static && $type->value === $fq_class_name) {
                            // Replace parent&static type to actual static type
                            $method_call_type->removeType($name);
                            $method_call_type->addType($context->vars_in_scope['$this']->getSingleAtomic());
                        }
                    }
                    $statements_analyzer->node_data->setType($stmt, $method_call_type->freeze());
                }
                return \true;
            }
            if (!$context->check_methods) {
                if (ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context) === \false) {
                    return \false;
                }
                return \true;
            }
        }
        $does_method_exist = MethodAnalyzer::checkMethodExists($codebase, $method_id, new CodeLocation($statements_analyzer, $stmt), $statements_analyzer->getSuppressedIssues(), $context->calling_method_id);
        if (!$does_method_exist) {
            if (ArgumentsAnalyzer::analyze($statements_analyzer, $stmt->getArgs(), null, null, \true, $context) === \false) {
                return \false;
            }
            if ($codebase->alter_code && $fq_class_name && !$moved_call) {
                $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id);
            }
            return \true;
        }
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        if ($class_storage->deprecated && $fq_class_name !== $context->self) {
            IssueBuffer::maybeAdd(new DeprecatedClass($fq_class_name . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
        }
        if ($context->self && !NamespaceAnalyzer::isWithinAny($context->self, $class_storage->internal)) {
            IssueBuffer::maybeAdd(new InternalClass($fq_class_name . ' is internal to ' . InternalClass::listToPhrase($class_storage->internal) . ' but called from ' . $context->self, new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_class_name), $statements_analyzer->getSuppressedIssues());
        }
        if (MethodVisibilityAnalyzer::analyze($method_id, $context, $statements_analyzer->getSource(), new CodeLocation($statements_analyzer, $stmt), $statements_analyzer->getSuppressedIssues()) === \false) {
            return \false;
        }
        if ((!$stmt->class instanceof PhpParser\Node\Name || $stmt->class->parts[0] !== 'parent' || $statements_analyzer->isStatic()) && (!$context->self || $statements_analyzer->isStatic() || !$codebase->classExtends($context->self, $fq_class_name))) {
            MethodAnalyzer::checkStatic($method_id, $stmt->class instanceof PhpParser\Node\Name && strtolower($stmt->class->parts[0]) === 'self' || $context->self === $fq_class_name, !$statements_analyzer->isStatic(), $codebase, new CodeLocation($statements_analyzer, $stmt), $statements_analyzer->getSuppressedIssues(), $is_dynamic_this_method);
            if ($is_dynamic_this_method) {
                return self::forwardCallToInstanceMethod($statements_analyzer, $stmt, $stmt_name, $context);
            }
        }
        $has_existing_method = \true;
        \Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\ExistingAtomicStaticCallAnalyzer::analyze($statements_analyzer, $stmt, $stmt_name, $args, $context, $lhs_type_part, $method_id, $cased_method_id, $class_storage, $moved_call, $inferred_template_result);
        return \true;
    }
    /**
     * @param  list<PhpParser\Node\Arg> $args
     * @return false|null
     */
    private static function checkPseudoMethod(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, MethodIdentifier $method_id, string $static_fq_class_name, array $args, ClassLikeStorage $class_storage, MethodStorage $pseudo_method_storage, Context $context) : ?bool
    {
        if (ArgumentsAnalyzer::analyze($statements_analyzer, $args, $pseudo_method_storage->params, (string) $method_id, \true, $context) === \false) {
            return \false;
        }
        $codebase = $statements_analyzer->getCodebase();
        if (ArgumentsAnalyzer::checkArgumentsMatch($statements_analyzer, $args, $method_id, $pseudo_method_storage->params, $pseudo_method_storage, null, new TemplateResult([], []), new CodeLocation($statements_analyzer, $stmt), $context) === \false) {
            return \false;
        }
        $method_storage = null;
        if ($statements_analyzer->data_flow_graph) {
            try {
                $method_storage = $codebase->methods->getStorage($method_id);
                ArgumentsAnalyzer::analyze($statements_analyzer, $args, $method_storage->params, (string) $method_id, \true, $context);
                ArgumentsAnalyzer::checkArgumentsMatch($statements_analyzer, $args, $method_id, $method_storage->params, $method_storage, null, new TemplateResult([], []), new CodeLocation($statements_analyzer, $stmt), $context);
            } catch (Exception $e) {
                // do nothing
            }
        }
        if ($pseudo_method_storage->return_type) {
            $return_type_candidate = $pseudo_method_storage->return_type;
            $return_type_candidate = TypeExpander::expandUnion($statements_analyzer->getCodebase(), $return_type_candidate, $class_storage->name, $static_fq_class_name, $class_storage->parent_class);
            if ($method_storage) {
                StaticCallAnalyzer::taintReturnType($statements_analyzer, $stmt, $method_id, (string) $method_id, $return_type_candidate, $method_storage, null, $context);
            }
            $stmt_type = $statements_analyzer->node_data->getType($stmt);
            $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes($return_type_candidate, $stmt_type));
        }
        return null;
    }
    public static function handleNonObjectCall(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, Context $context, Atomic $lhs_type_part, bool $ignore_nullable_issues) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $config = $codebase->config;
        if ($lhs_type_part instanceof TMixed || $lhs_type_part instanceof TTemplateParam || $lhs_type_part instanceof TClassString || $lhs_type_part instanceof TObject) {
            if ($stmt->name instanceof PhpParser\Node\Identifier) {
                $codebase->analyzer->addMixedMemberName(strtolower($stmt->name->name), $context->calling_method_id ?: $statements_analyzer->getFileName());
            }
            IssueBuffer::maybeAdd(new MixedMethodCall('Cannot call method on an unknown class', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            return;
        }
        if ($lhs_type_part instanceof TString) {
            if ($config->allow_string_standin_for_class && !$lhs_type_part instanceof TNumericString) {
                return;
            }
            IssueBuffer::maybeAdd(new InvalidStringClass('String cannot be used as a class', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            return;
        }
        if ($lhs_type_part instanceof TNull && $ignore_nullable_issues) {
            return;
        }
        IssueBuffer::maybeAdd(new UndefinedClass('Type ' . $lhs_type_part . ' cannot be called as a class', new CodeLocation($statements_analyzer->getSource(), $stmt), (string) $lhs_type_part), $statements_analyzer->getSuppressedIssues());
    }
    /**
     * Try to find matching pseudo method over ancestors (including interfaces).
     *
     * Returns the pseudo method if exists, with its defining class storage.
     * If the method is not declared, null is returned.
     *
     * @param ClassLikeStorage $static_class_storage The called class
     * @param lowercase-string $method_name_lc
     * @return array{MethodStorage, ClassLikeStorage}|null
     */
    private static function findPseudoMethodAndClassStorages(Codebase $codebase, ClassLikeStorage $static_class_storage, string $method_name_lc) : ?array
    {
        if ($pseudo_method_storage = $static_class_storage->pseudo_static_methods[$method_name_lc] ?? null) {
            return [$pseudo_method_storage, $static_class_storage];
        }
        $ancestors = $static_class_storage->class_implements + $static_class_storage->parent_classes;
        foreach ($ancestors as $fq_class_name => $_) {
            $class_storage = $codebase->classlikes->getStorageFor($fq_class_name);
            if ($class_storage && isset($class_storage->pseudo_static_methods[$method_name_lc])) {
                return [$class_storage->pseudo_static_methods[$method_name_lc], $class_storage];
            }
        }
        return null;
    }
    /**
     * Forward static call to instance call, using `VirtualMethodCall` and `MethodCallAnalyzer::analyze()`
     * The resolved method return type will be set as type of the $stmt node.
     *
     * @param string $virtual_var_name Temporary var name to use for create the fake MethodCall statement.
     * @param bool $always_set_node_type If true, when the method has no declared typed, mixed will be set on node.
     * @return bool Result of analysis. False if the call is invalid.
     * @see MethodCallAnalyzer::analyze()
     */
    private static function forwardCallToInstanceMethod(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticCall $stmt, PhpParser\Node\Identifier $stmt_name, Context $context, string $virtual_var_name = 'this', bool $always_set_node_type = \false) : bool
    {
        $old_data_provider = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        $fake_method_call_expr = new VirtualMethodCall(new VirtualVariable($virtual_var_name, $stmt->class->getAttributes()), $stmt_name, $stmt->getArgs(), $stmt->getAttributes());
        if (MethodCallAnalyzer::analyze($statements_analyzer, $fake_method_call_expr, $context) === \false) {
            return \false;
        }
        $fake_method_call_type = $statements_analyzer->node_data->getType($fake_method_call_expr);
        $statements_analyzer->node_data = $old_data_provider;
        if ($fake_method_call_type) {
            $statements_analyzer->node_data->setType($stmt, $fake_method_call_type);
        } elseif ($always_set_node_type) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Issue\UnhandledMatchCondition;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\BinaryOp\VirtualIdentical;
use Psalm\Node\Expr\VirtualArray;
use Psalm\Node\Expr\VirtualArrayItem;
use Psalm\Node\Expr\VirtualConstFetch;
use Psalm\Node\Expr\VirtualFuncCall;
use Psalm\Node\Expr\VirtualNew;
use Psalm\Node\Expr\VirtualTernary;
use Psalm\Node\Expr\VirtualThrow;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\VirtualArg;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Reconciler;
use UnexpectedValueException;
use function array_filter;
use function array_map;
use function array_merge;
use function array_reverse;
use function array_shift;
use function count;
use function in_array;
use function spl_object_id;
use function substr;
/**
 * @internal
 */
class MatchAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Match_ $stmt, Context $context) : bool
    {
        $was_inside_call = $context->inside_call;
        $context->inside_call = \true;
        $was_inside_conditional = $context->inside_conditional;
        $context->inside_conditional = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->cond, $context) === \false) {
            $context->inside_conditional = $was_inside_conditional;
            return \false;
        }
        $context->inside_conditional = $was_inside_conditional;
        $switch_var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($stmt->cond, null, $statements_analyzer);
        $match_condition = $stmt->cond;
        if (!$switch_var_id) {
            if ($stmt->cond instanceof PhpParser\Node\Expr\FuncCall && $stmt->cond->name instanceof PhpParser\Node\Name && ($stmt->cond->name->parts === ['get_class'] || $stmt->cond->name->parts === ['gettype'] || $stmt->cond->name->parts === ['get_debug_type'] || $stmt->cond->name->parts === ['count']) && $stmt->cond->getArgs()) {
                $first_arg = $stmt->cond->getArgs()[0];
                if (!$first_arg->value instanceof PhpParser\Node\Expr\Variable) {
                    $switch_var_id = '$__tmp_switch__' . (int) $first_arg->value->getAttribute('startFilePos');
                    $condition_type = $statements_analyzer->node_data->getType($first_arg->value) ?? Type::getMixed();
                    $context->vars_in_scope[$switch_var_id] = $condition_type;
                    $match_condition = new VirtualFuncCall($stmt->cond->name, [new VirtualArg(new VirtualVariable(substr($switch_var_id, 1), $first_arg->value->getAttributes()), \false, \false, $first_arg->getAttributes())], $stmt->cond->getAttributes());
                }
            } elseif ($stmt->cond instanceof PhpParser\Node\Expr\FuncCall || $stmt->cond instanceof PhpParser\Node\Expr\MethodCall || $stmt->cond instanceof PhpParser\Node\Expr\StaticCall) {
                $switch_var_id = '$__tmp_switch__' . (int) $stmt->cond->getAttribute('startFilePos');
                $condition_type = $statements_analyzer->node_data->getType($stmt->cond) ?? Type::getMixed();
                $context->vars_in_scope[$switch_var_id] = $condition_type;
                $match_condition = new VirtualVariable(substr($switch_var_id, 1), $stmt->cond->getAttributes());
            }
        }
        $arms = $stmt->arms;
        foreach ($arms as $i => $arm) {
            // move default to the end
            if ($arm->conds === null) {
                unset($arms[$i]);
                $arms[] = $arm;
            }
        }
        $arms = array_reverse($arms);
        $last_arm = array_shift($arms);
        if (!$last_arm) {
            IssueBuffer::maybeAdd(new UnhandledMatchCondition('This match expression does not match anything', new CodeLocation($statements_analyzer->getSource(), $match_condition)), $statements_analyzer->getSuppressedIssues());
            return \false;
        }
        $old_node_data = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        if (!$last_arm->conds) {
            $ternary = $last_arm->body;
        } else {
            $ternary = new VirtualTernary(self::convertCondsToConditional($last_arm->conds, $match_condition, $last_arm->getAttributes()), $last_arm->body, new VirtualThrow(new VirtualNew(new VirtualFullyQualified('UnhandledMatchError', $stmt->getAttributes()), [], $stmt->getAttributes())), $stmt->getAttributes());
        }
        foreach ($arms as $arm) {
            if (!$arm->conds) {
                continue;
            }
            $ternary = new VirtualTernary(self::convertCondsToConditional($arm->conds, $match_condition, $arm->getAttributes()), $arm->body, $ternary, $arm->getAttributes());
        }
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        if (!in_array('RedundantCondition', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['RedundantCondition']);
        }
        if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['RedundantConditionGivenDocblockType']);
        }
        if (ExpressionAnalyzer::analyze($statements_analyzer, $ternary, $context) === \false) {
            return \false;
        }
        if (!in_array('RedundantCondition', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['RedundantCondition']);
        }
        if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['RedundantConditionGivenDocblockType']);
        }
        if ($switch_var_id && $last_arm->conds) {
            $codebase = $statements_analyzer->getCodebase();
            $all_conds = $last_arm->conds;
            foreach ($arms as $arm) {
                if (!$arm->conds) {
                    throw new UnexpectedValueException('bad');
                }
                $all_conds = array_merge($arm->conds, $all_conds);
            }
            $all_match_condition = self::convertCondsToConditional($all_conds, $match_condition, $match_condition->getAttributes());
            ExpressionAnalyzer::analyze($statements_analyzer, $all_match_condition, $context);
            $clauses = FormulaGenerator::getFormula(spl_object_id($all_match_condition), spl_object_id($all_match_condition), $all_match_condition, $context->self, $statements_analyzer, $codebase, \false, \false);
            $reconcilable_types = Algebra::getTruthsFromFormula(Algebra::negateFormula($clauses));
            // if the if has an || in the conditional, we cannot easily reason about it
            if ($reconcilable_types) {
                $changed_var_ids = [];
                [$vars_in_scope_reconciled, $_] = Reconciler::reconcileKeyedTypes($reconcilable_types, [], $context->vars_in_scope, $context->references_in_scope, $changed_var_ids, [], $statements_analyzer, [], $context->inside_loop, null);
                if (isset($vars_in_scope_reconciled[$switch_var_id])) {
                    $array_literal_types = array_filter($vars_in_scope_reconciled[$switch_var_id]->getAtomicTypes(), static fn(Atomic $type): bool => $type instanceof TLiteralInt || $type instanceof TLiteralString || $type instanceof TLiteralFloat || $type instanceof TEnumCase);
                    if ($array_literal_types) {
                        IssueBuffer::maybeAdd(new UnhandledMatchCondition('This match expression is not exhaustive - consider values ' . $vars_in_scope_reconciled[$switch_var_id]->getId(), new CodeLocation($statements_analyzer->getSource(), $match_condition)), $statements_analyzer->getSuppressedIssues());
                    }
                }
            }
        }
        $stmt_expr_type = $statements_analyzer->node_data->getType($ternary);
        $old_node_data->setType($stmt, $stmt_expr_type ?? Type::getMixed());
        $statements_analyzer->node_data = $old_node_data;
        $context->inside_call = $was_inside_call;
        return \true;
    }
    /**
     * @param non-empty-list<PhpParser\Node\Expr> $conds
     */
    private static function convertCondsToConditional(array $conds, PhpParser\Node\Expr $match_condition, array $attributes) : PhpParser\Node\Expr
    {
        if (count($conds) === 1) {
            return new VirtualIdentical($match_condition, $conds[0], $attributes);
        }
        $array_items = array_map(static fn(PhpParser\Node\Expr $cond): PhpParser\Node\Expr\ArrayItem => new VirtualArrayItem($cond, null, \false, $cond->getAttributes()), $conds);
        return new VirtualFuncCall(new VirtualFullyQualified(['in_array']), [new VirtualArg($match_condition, \false, \false, $attributes), new VirtualArg(new VirtualArray($array_items, $attributes), \false, \false, $attributes), new VirtualArg(new VirtualConstFetch(new VirtualFullyQualified(['true']), $attributes), \false, \false, $attributes)], $attributes);
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\ConstantTypeResolver;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Issue\DuplicateArrayKey;
use Psalm\Issue\InvalidArrayOffset;
use Psalm\Issue\InvalidOperand;
use Psalm\Issue\MixedArrayOffset;
use Psalm\Issue\ParseError;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
use function array_merge;
use function array_values;
use function count;
use function in_array;
use function is_string;
use function preg_match;
use const PHP_INT_MAX;
/**
 * @internal
 */
class ArrayAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Array_ $stmt, Context $context) : bool
    {
        // if the array is empty, this special type allows us to match any other array type against it
        if (count($stmt->items) === 0) {
            $statements_analyzer->node_data->setType($stmt, Type::getEmptyArray());
            return \true;
        }
        $codebase = $statements_analyzer->getCodebase();
        $array_creation_info = new \Psalm\Internal\Analyzer\Statements\Expression\ArrayCreationInfo();
        foreach ($stmt->items as $item) {
            if ($item === null) {
                IssueBuffer::maybeAdd(new ParseError('Array element cannot be empty', new CodeLocation($statements_analyzer, $stmt)));
                return \false;
            }
            self::analyzeArrayItem($statements_analyzer, $context, $array_creation_info, $item, $codebase);
        }
        if (count($array_creation_info->item_key_atomic_types) !== 0) {
            $item_key_type = TypeCombiner::combine($array_creation_info->item_key_atomic_types, $codebase);
        } else {
            $item_key_type = null;
        }
        if (count($array_creation_info->item_value_atomic_types) !== 0) {
            $item_value_type = TypeCombiner::combine($array_creation_info->item_value_atomic_types, $codebase);
        } else {
            $item_value_type = null;
        }
        // if this array looks like an object-like array, let's return that instead
        if (count($array_creation_info->property_types) !== 0) {
            $atomic_type = new TKeyedArray($array_creation_info->property_types, $array_creation_info->class_strings, $array_creation_info->can_create_objectlike ? null : [$item_key_type ?? Type::getArrayKey(), $item_value_type ?? Type::getMixed()], $array_creation_info->all_list);
            $stmt_type = new Union([$atomic_type], ['parent_nodes' => $array_creation_info->parent_taint_nodes]);
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            return \true;
        }
        if ($item_key_type === null && $item_value_type === null) {
            $statements_analyzer->node_data->setType($stmt, Type::getEmptyArray());
            return \true;
        }
        if ($array_creation_info->all_list) {
            if ($array_creation_info->can_be_empty) {
                $array_type = Type::getListAtomic($item_value_type ?? Type::getMixed());
            } else {
                $array_type = Type::getNonEmptyListAtomic($item_value_type ?? Type::getMixed());
            }
            $stmt_type = new Union([$array_type], ['parent_nodes' => $array_creation_info->parent_taint_nodes]);
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            return \true;
        }
        if ($item_key_type) {
            $bad_types = [];
            $good_types = [];
            foreach ($item_key_type->getAtomicTypes() as $atomic_key_type) {
                if ($atomic_key_type instanceof TMixed) {
                    IssueBuffer::maybeAdd(new MixedArrayOffset('Cannot create mixed offset – expecting array-key', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    $bad_types[] = $atomic_key_type;
                    $good_types[] = new TArrayKey();
                    continue;
                }
                if (!$atomic_key_type instanceof TString && !$atomic_key_type instanceof TInt && !$atomic_key_type instanceof TArrayKey && !$atomic_key_type instanceof TTemplateParam && !($atomic_key_type instanceof TObjectWithProperties && isset($atomic_key_type->methods['__tostring']))) {
                    IssueBuffer::maybeAdd(new InvalidArrayOffset('Cannot create offset of type ' . $item_key_type->getKey() . ', expecting array-key', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    $bad_types[] = $atomic_key_type;
                    if ($atomic_key_type instanceof TFalse) {
                        $good_types[] = new TLiteralInt(0);
                    } elseif ($atomic_key_type instanceof TTrue) {
                        $good_types[] = new TLiteralInt(1);
                    } elseif ($atomic_key_type instanceof TBool) {
                        $good_types[] = new TLiteralInt(0);
                        $good_types[] = new TLiteralInt(1);
                    } elseif ($atomic_key_type instanceof TLiteralFloat) {
                        $good_types[] = new TLiteralInt((int) $atomic_key_type->value);
                    } elseif ($atomic_key_type instanceof TFloat) {
                        $good_types[] = new TInt();
                    } else {
                        $good_types[] = new TArrayKey();
                    }
                }
            }
            if ($bad_types && $good_types) {
                $item_key_type = $item_key_type->getBuilder()->substitute(TypeCombiner::combine($bad_types, $codebase), TypeCombiner::combine($good_types, $codebase))->freeze();
            }
        }
        $array_args = [$item_key_type && !$item_key_type->hasMixed() ? $item_key_type : Type::getArrayKey(), $item_value_type ?? Type::getMixed()];
        $array_type = $array_creation_info->can_be_empty ? new TArray($array_args) : new TNonEmptyArray($array_args);
        $stmt_type = new Union([$array_type], ['parent_nodes' => $array_creation_info->parent_taint_nodes]);
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
        return \true;
    }
    private static function analyzeArrayItem(StatementsAnalyzer $statements_analyzer, Context $context, \Psalm\Internal\Analyzer\Statements\Expression\ArrayCreationInfo $array_creation_info, PhpParser\Node\Expr\ArrayItem $item, Codebase $codebase) : void
    {
        if ($item->unpack) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $item->value, $context) === \false) {
                return;
            }
            $unpacked_array_type = $statements_analyzer->node_data->getType($item->value);
            if (!$unpacked_array_type) {
                return;
            }
            self::handleUnpackedArray($statements_analyzer, $array_creation_info, $item, $unpacked_array_type, $codebase);
            if (($data_flow_graph = $statements_analyzer->data_flow_graph) && $data_flow_graph instanceof VariableUseGraph && $unpacked_array_type->parent_nodes) {
                $var_location = new CodeLocation($statements_analyzer->getSource(), $item->value);
                $new_parent_node = DataFlowNode::getForAssignment('array', $var_location);
                $data_flow_graph->addNode($new_parent_node);
                foreach ($unpacked_array_type->parent_nodes as $parent_node) {
                    $data_flow_graph->addPath($parent_node, $new_parent_node, 'arrayvalue-assignment');
                }
                $array_creation_info->parent_taint_nodes += [$new_parent_node->id => $new_parent_node];
            }
            return;
        }
        $item_key_value = null;
        $item_key_type = null;
        $item_is_list_item = \false;
        $array_creation_info->can_be_empty = \false;
        if ($item->key) {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $item->key, $context) === \false) {
                $context->inside_general_use = $was_inside_general_use;
                return;
            }
            $context->inside_general_use = $was_inside_general_use;
            if ($item_key_type = $statements_analyzer->node_data->getType($item->key)) {
                $key_type = $item_key_type;
                if ($key_type->isNull()) {
                    $key_type = Type::getString('');
                }
                if ($item->key instanceof PhpParser\Node\Scalar\String_ && preg_match('/^(0|[1-9][0-9]*)$/', $item->key->value) && ((int) $item->key->value < PHP_INT_MAX || $item->key->value === (string) PHP_INT_MAX)) {
                    $key_type = Type::getInt(\false, (int) $item->key->value);
                }
                if ($key_type->isSingleStringLiteral()) {
                    $item_key_literal_type = $key_type->getSingleStringLiteral();
                    $item_key_value = $item_key_literal_type->value;
                    if ($item_key_literal_type instanceof TLiteralClassString) {
                        $array_creation_info->class_strings[$item_key_value] = \true;
                    }
                } elseif ($key_type->isSingleIntLiteral()) {
                    $item_key_value = $key_type->getSingleIntLiteral()->value;
                    if ($item_key_value >= $array_creation_info->int_offset) {
                        if ($item_key_value === $array_creation_info->int_offset) {
                            $item_is_list_item = \true;
                        }
                        $array_creation_info->int_offset = $item_key_value + 1;
                    }
                }
            } else {
                $key_type = Type::getArrayKey();
            }
        } else {
            $item_is_list_item = \true;
            $item_key_value = $array_creation_info->int_offset++;
            $key_atomic_type = new TLiteralInt($item_key_value);
            $array_creation_info->item_key_atomic_types[] = $key_atomic_type;
            $key_type = new Union([$key_atomic_type]);
        }
        if (ExpressionAnalyzer::analyze($statements_analyzer, $item->value, $context) === \false) {
            return;
        }
        $array_creation_info->all_list = $array_creation_info->all_list && $item_is_list_item;
        if ($item_key_value !== null) {
            if (isset($array_creation_info->array_keys[$item_key_value])) {
                IssueBuffer::maybeAdd(new DuplicateArrayKey('Key \'' . $item_key_value . '\' already exists on array', new CodeLocation($statements_analyzer->getSource(), $item)), $statements_analyzer->getSuppressedIssues());
            }
            $array_creation_info->array_keys[$item_key_value] = \true;
        }
        if (($data_flow_graph = $statements_analyzer->data_flow_graph) && ($data_flow_graph instanceof VariableUseGraph || !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues()))) {
            if ($item_value_type = $statements_analyzer->node_data->getType($item->value)) {
                if ($item_value_type->parent_nodes && !($item_value_type->isSingle() && $item_value_type->hasLiteralValue() && $data_flow_graph instanceof TaintFlowGraph)) {
                    $var_location = new CodeLocation($statements_analyzer->getSource(), $item);
                    $new_parent_node = DataFlowNode::getForAssignment('array' . ($item_key_value !== null ? '[\'' . $item_key_value . '\']' : ''), $var_location);
                    $data_flow_graph->addNode($new_parent_node);
                    $event = new AddRemoveTaintsEvent($item, $context, $statements_analyzer, $codebase);
                    $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                    $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                    foreach ($item_value_type->parent_nodes as $parent_node) {
                        $data_flow_graph->addPath($parent_node, $new_parent_node, 'arrayvalue-assignment' . ($item_key_value !== null ? '-\'' . $item_key_value . '\'' : ''), $added_taints, $removed_taints);
                    }
                    $array_creation_info->parent_taint_nodes += [$new_parent_node->id => $new_parent_node];
                }
                if ($item_key_type && $item_key_type->parent_nodes && $item_key_value === null && !($item_key_type->isSingle() && $item_key_type->hasLiteralValue() && $data_flow_graph instanceof TaintFlowGraph)) {
                    $var_location = new CodeLocation($statements_analyzer->getSource(), $item);
                    $new_parent_node = DataFlowNode::getForAssignment('array', $var_location);
                    $data_flow_graph->addNode($new_parent_node);
                    $event = new AddRemoveTaintsEvent($item, $context, $statements_analyzer, $codebase);
                    $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                    $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                    foreach ($item_key_type->parent_nodes as $parent_node) {
                        $data_flow_graph->addPath($parent_node, $new_parent_node, 'arraykey-assignment', $added_taints, $removed_taints);
                    }
                    $array_creation_info->parent_taint_nodes += [$new_parent_node->id => $new_parent_node];
                }
            }
        }
        if ($item->byRef) {
            $var_id = \Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier::getExtendedVarId($item->value, $statements_analyzer->getFQCLN(), $statements_analyzer);
            if ($var_id) {
                if (isset($context->vars_in_scope[$var_id])) {
                    $context->removeDescendents($var_id, $context->vars_in_scope[$var_id], null, $statements_analyzer);
                }
                $context->vars_in_scope[$var_id] = Type::getMixed();
            }
        }
        $config = $codebase->config;
        if ($item_value_type = $statements_analyzer->node_data->getType($item->value)) {
            if ($item_key_value !== null && count($array_creation_info->property_types) <= $config->max_shaped_array_size) {
                $array_creation_info->property_types[$item_key_value] = $item_value_type;
            } else {
                $array_creation_info->can_create_objectlike = \false;
                $array_creation_info->item_key_atomic_types = array_merge($array_creation_info->item_key_atomic_types, array_values($key_type->getAtomicTypes()));
                $array_creation_info->item_value_atomic_types = array_merge($array_creation_info->item_value_atomic_types, array_values($item_value_type->getAtomicTypes()));
            }
        } else {
            if ($item_key_value !== null && count($array_creation_info->property_types) <= $config->max_shaped_array_size) {
                $array_creation_info->property_types[$item_key_value] = Type::getMixed();
            } else {
                $array_creation_info->can_create_objectlike = \false;
                $array_creation_info->item_key_atomic_types = array_merge($array_creation_info->item_key_atomic_types, array_values($key_type->getAtomicTypes()));
                $array_creation_info->item_value_atomic_types[] = new TMixed();
            }
        }
    }
    private static function handleUnpackedArray(StatementsAnalyzer $statements_analyzer, \Psalm\Internal\Analyzer\Statements\Expression\ArrayCreationInfo $array_creation_info, PhpParser\Node\Expr\ArrayItem $item, Union $unpacked_array_type, Codebase $codebase) : void
    {
        $all_non_empty = \true;
        $has_possibly_undefined = \false;
        foreach ($unpacked_array_type->getAtomicTypes() as $unpacked_atomic_type) {
            if ($unpacked_atomic_type instanceof TList) {
                $unpacked_atomic_type = $unpacked_atomic_type->getKeyedArray();
            }
            if ($unpacked_atomic_type instanceof TKeyedArray) {
                foreach ($unpacked_atomic_type->properties as $key => $property_value) {
                    if ($property_value->possibly_undefined) {
                        $has_possibly_undefined = \true;
                        continue;
                    }
                    if (is_string($key)) {
                        if ($codebase->analysis_php_version_id <= 80000) {
                            IssueBuffer::maybeAdd(new DuplicateArrayKey('String keys are not supported in unpacked arrays', new CodeLocation($statements_analyzer->getSource(), $item->value)), $statements_analyzer->getSuppressedIssues());
                            continue 2;
                        }
                        $new_offset = $key;
                        $array_creation_info->item_key_atomic_types[] = new TLiteralString($new_offset);
                        $array_creation_info->all_list = \false;
                    } else {
                        $new_offset = $array_creation_info->int_offset++;
                        $array_creation_info->item_key_atomic_types[] = new TLiteralInt($new_offset);
                    }
                    $array_creation_info->array_keys[$new_offset] = \true;
                    $array_creation_info->property_types[$new_offset] = $property_value;
                }
                if (!$unpacked_atomic_type->isNonEmpty()) {
                    $all_non_empty = \false;
                }
                if ($has_possibly_undefined) {
                    $unpacked_atomic_type = $unpacked_atomic_type->getGenericArrayType();
                } elseif (!$unpacked_atomic_type->fallback_params) {
                    continue;
                }
            } elseif (!$unpacked_atomic_type instanceof TNonEmptyArray) {
                $all_non_empty = \false;
            }
            $codebase = $statements_analyzer->getCodebase();
            if (!$unpacked_atomic_type->isIterable($codebase)) {
                $array_creation_info->can_create_objectlike = \false;
                $array_creation_info->item_key_atomic_types[] = new TArrayKey();
                $array_creation_info->item_value_atomic_types[] = new TMixed();
                IssueBuffer::maybeAdd(new InvalidOperand("Cannot use spread operator on non-iterable type {$unpacked_array_type->getId()}", new CodeLocation($statements_analyzer->getSource(), $item->value)), $statements_analyzer->getSuppressedIssues());
                continue;
            }
            $iterable_type = $unpacked_atomic_type->getIterable($codebase);
            if ($iterable_type->type_params[0]->isNever()) {
                continue;
            }
            $array_creation_info->can_create_objectlike = \false;
            if (!UnionTypeComparator::isContainedBy($codebase, $iterable_type->type_params[0], Type::getArrayKey())) {
                IssueBuffer::maybeAdd(new InvalidOperand("Cannot use spread operator on iterable with key type " . $iterable_type->type_params[0]->getId(), new CodeLocation($statements_analyzer->getSource(), $item->value)), $statements_analyzer->getSuppressedIssues());
                continue;
            }
            if ($iterable_type->type_params[0]->hasString()) {
                if ($codebase->analysis_php_version_id <= 80000) {
                    IssueBuffer::maybeAdd(new DuplicateArrayKey('String keys are not supported in unpacked arrays', new CodeLocation($statements_analyzer->getSource(), $item->value)), $statements_analyzer->getSuppressedIssues());
                    continue;
                }
                $array_creation_info->all_list = \false;
            }
            // Unpacked array might overwrite known properties, so values are merged when the keys intersect.
            foreach ($array_creation_info->property_types as $prop_key_val => $prop_val) {
                $prop_key = new Union([ConstantTypeResolver::getLiteralTypeFromScalarValue($prop_key_val)]);
                // Since $prop_key is a single literal type, the types intersect iff $prop_key is contained by the
                // template type (ie $prop_key cannot overlap with the template type without being contained by it).
                if (UnionTypeComparator::isContainedBy($codebase, $prop_key, $iterable_type->type_params[0])) {
                    $new_prop_val = Type::combineUnionTypes($prop_val, $iterable_type->type_params[1]);
                    $array_creation_info->property_types[$prop_key_val] = $new_prop_val;
                }
            }
            $array_creation_info->item_key_atomic_types = array_merge($array_creation_info->item_key_atomic_types, array_values($iterable_type->type_params[0]->getAtomicTypes()));
            $array_creation_info->item_value_atomic_types = array_merge($array_creation_info->item_value_atomic_types, array_values($iterable_type->type_params[1]->getAtomicTypes()));
        }
        if ($all_non_empty) {
            $array_creation_info->can_be_empty = \false;
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Exit_;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Issue\ForbiddenCode;
use Psalm\Issue\ImpureFunctionCall;
use Psalm\IssueBuffer;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TString;
use Psalm\Type\TaintKind;
use Psalm\Type\Union;
/**
 * @internal
 */
class ExitAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, Exit_ $stmt, Context $context) : bool
    {
        $expr_type = null;
        $config = $statements_analyzer->getProjectAnalyzer()->getConfig();
        $forbidden = null;
        if (isset($config->forbidden_functions['exit']) && $stmt->getAttribute('kind') === Exit_::KIND_EXIT) {
            $forbidden = 'exit';
        } elseif (isset($config->forbidden_functions['die']) && $stmt->getAttribute('kind') === Exit_::KIND_DIE) {
            $forbidden = 'die';
        }
        if ($forbidden) {
            IssueBuffer::maybeAdd(new ForbiddenCode('You have forbidden the use of ' . $forbidden, new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        if ($stmt->expr) {
            $context->inside_call = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                return \false;
            }
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
                $call_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                $echo_param_sink = TaintSink::getForMethodArgument('exit', 'exit', 0, null, $call_location);
                $echo_param_sink->taints = [TaintKind::INPUT_HTML, TaintKind::INPUT_HAS_QUOTES, TaintKind::USER_SECRET, TaintKind::SYSTEM_SECRET];
                $statements_analyzer->data_flow_graph->addSink($echo_param_sink);
            }
            if ($expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
                $exit_param = new FunctionLikeParameter('var', \false);
                if (ArgumentAnalyzer::verifyType($statements_analyzer, $expr_type, new Union([new TInt(), new TString()]), null, 'exit', null, 0, new CodeLocation($statements_analyzer->getSource(), $stmt->expr), $stmt->expr, $context, $exit_param, \false, null, \true, \true, new CodeLocation($statements_analyzer, $stmt)) === \false) {
                    return \false;
                }
            }
            $context->inside_call = \false;
        }
        if ($expr_type && !$expr_type->isInt() && !$context->collect_mutations && !$context->collect_initializations) {
            if ($context->mutation_free || $context->external_mutation_free) {
                $function_name = $stmt->getAttribute('kind') === Exit_::KIND_DIE ? 'die' : 'exit';
                IssueBuffer::maybeAdd(new ImpureFunctionCall('Cannot call ' . $function_name . ' with a non-integer argument from a mutation-free context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                $statements_analyzer->getSource()->inferred_has_mutation = \true;
                $statements_analyzer->getSource()->inferred_impure = \true;
            }
        }
        $statements_analyzer->node_data->setType($stmt, Type::getNever());
        $context->has_returned = \true;
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Context;
use Psalm\Exception\DocblockParseException;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\UnnecessaryVarAnnotation;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TNamedObject;
use function array_values;
/**
 * @internal
 */
class YieldAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Yield_ $stmt, Context $context) : bool
    {
        $doc_comment = $stmt->getDocComment();
        $var_comments = [];
        $var_comment_type = null;
        $codebase = $statements_analyzer->getCodebase();
        if ($doc_comment) {
            try {
                $var_comments = CommentAnalyzer::getTypeFromComment($doc_comment, $statements_analyzer, $statements_analyzer->getAliases());
            } catch (DocblockParseException $e) {
                IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt)));
            }
            foreach ($var_comments as $var_comment) {
                if (!$var_comment->type) {
                    continue;
                }
                $comment_type = TypeExpander::expandUnion($codebase, $var_comment->type, $context->self, $context->self ? new TNamedObject($context->self) : null, $statements_analyzer->getParentFQCLN());
                $type_location = null;
                if ($var_comment->type_start && $var_comment->type_end && $var_comment->line_number) {
                    $type_location = new DocblockTypeLocation($statements_analyzer, $var_comment->type_start, $var_comment->type_end, $var_comment->line_number);
                }
                if (!$var_comment->var_id) {
                    $var_comment_type = $comment_type;
                    continue;
                }
                if ($codebase->find_unused_variables && $type_location && isset($context->vars_in_scope[$var_comment->var_id]) && $context->vars_in_scope[$var_comment->var_id]->getId() === $comment_type->getId()) {
                    $project_analyzer = $statements_analyzer->getProjectAnalyzer();
                    if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['UnnecessaryVarAnnotation'])) {
                        FileManipulationBuffer::addVarAnnotationToRemove($type_location);
                    } else {
                        IssueBuffer::maybeAdd(new UnnecessaryVarAnnotation('The @var annotation for ' . $var_comment->var_id . ' is unnecessary', $type_location), $statements_analyzer->getSuppressedIssues(), \true);
                    }
                }
                if (isset($context->vars_in_scope[$var_comment->var_id])) {
                    $comment_type = $comment_type->setParentNodes($context->vars_in_scope[$var_comment->var_id]->parent_nodes);
                }
                $context->vars_in_scope[$var_comment->var_id] = $comment_type;
            }
        }
        if ($stmt->key) {
            $context->inside_call = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->key, $context) === \false) {
                return \false;
            }
            $context->inside_call = \false;
        }
        if ($stmt->value) {
            $context->inside_call = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->value, $context) === \false) {
                return \false;
            }
            $context->inside_call = \false;
            if ($var_comment_type) {
                $expression_type = $var_comment_type;
            } elseif ($stmt_var_type = $statements_analyzer->node_data->getType($stmt->value)) {
                $expression_type = $stmt_var_type;
            } else {
                $expression_type = Type::getMixed();
            }
        } else {
            $expression_type = Type::getNever();
        }
        $yield_type = null;
        foreach ($expression_type->getAtomicTypes() as $expression_atomic_type) {
            if (!$expression_atomic_type instanceof TNamedObject) {
                continue;
            }
            if (!$codebase->classlikes->classOrInterfaceExists($expression_atomic_type->value)) {
                continue;
            }
            $classlike_storage = $codebase->classlike_storage_provider->get($expression_atomic_type->value);
            if (!$classlike_storage->yield) {
                continue;
            }
            $declaring_classlike_storage = $classlike_storage->declaring_yield_fqcn ? $codebase->classlike_storage_provider->get($classlike_storage->declaring_yield_fqcn) : $classlike_storage;
            $yield_candidate_type = $classlike_storage->yield;
            $yield_candidate_type = !$yield_candidate_type->isMixed() ? TypeExpander::expandUnion($codebase, $yield_candidate_type, $expression_atomic_type->value, $expression_atomic_type->value, null, \true, \false) : $yield_candidate_type;
            $class_template_params = ClassTemplateParamCollector::collect($codebase, $declaring_classlike_storage, $classlike_storage, null, $expression_atomic_type, \true);
            if ($class_template_params) {
                if (!$expression_atomic_type instanceof TGenericObject) {
                    $type_params = [];
                    foreach ($class_template_params as $type_map) {
                        $type_params[] = array_values($type_map)[0];
                    }
                    $expression_atomic_type = new TGenericObject($expression_atomic_type->value, $type_params);
                }
                $yield_candidate_type = AtomicPropertyFetchAnalyzer::localizePropertyType($codebase, $yield_candidate_type, $expression_atomic_type, $classlike_storage, $declaring_classlike_storage);
            }
            $yield_type = Type::combineUnionTypes($yield_type, $yield_candidate_type, $codebase);
        }
        if ($yield_type) {
            $expression_type = $expression_type->getBuilder()->substitute($expression_type, $yield_type)->freeze();
        }
        $statements_analyzer->node_data->setType($stmt, $expression_type);
        $source = $statements_analyzer->getSource();
        if ($source instanceof FunctionLikeAnalyzer && !$source->getSource() instanceof TraitAnalyzer) {
            $source->examineParamTypes($statements_analyzer, $context, $codebase, $stmt);
            $storage = $source->getFunctionLikeStorage($statements_analyzer);
            if ($storage->return_type && !$yield_type) {
                foreach ($storage->return_type->getAtomicTypes() as $atomic_return_type) {
                    if ($atomic_return_type instanceof TNamedObject && $atomic_return_type->value === 'Generator') {
                        if ($atomic_return_type instanceof TGenericObject) {
                            if (!$atomic_return_type->type_params[2]->isVoid()) {
                                $statements_analyzer->node_data->setType($stmt, $atomic_return_type->type_params[2]);
                            }
                        } else {
                            $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes(Type::getMixed(), $expression_type));
                        }
                    }
                }
            }
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\EncapsedStringPart;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNonEmptyNonspecificLiteralString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonspecificLiteralInt;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
use function in_array;
/**
 * @internal
 */
class EncapsulatedStringAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Scalar\Encapsed $stmt, Context $context) : bool
    {
        $parent_nodes = [];
        $non_empty = \false;
        $all_literals = \true;
        $literal_string = "";
        foreach ($stmt->parts as $part) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $part, $context) === \false) {
                return \false;
            }
            $part_type = $statements_analyzer->node_data->getType($part);
            if ($part_type !== null) {
                $casted_part_type = \Psalm\Internal\Analyzer\Statements\Expression\CastAnalyzer::castStringAttempt($statements_analyzer, $context, $part_type, $part);
                if (!$casted_part_type->allLiterals()) {
                    $all_literals = \false;
                } elseif (!$non_empty) {
                    // Check if all literals are nonempty
                    $non_empty = \true;
                    foreach ($casted_part_type->getAtomicTypes() as $atomic_literal) {
                        if (!$atomic_literal instanceof TLiteralInt && !$atomic_literal instanceof TNonspecificLiteralInt && !$atomic_literal instanceof TLiteralFloat && !$atomic_literal instanceof TNonEmptyNonspecificLiteralString && !($atomic_literal instanceof TLiteralString && $atomic_literal->value !== "")) {
                            $non_empty = \false;
                            break;
                        }
                    }
                }
                if ($literal_string !== null) {
                    if ($casted_part_type->isSingleLiteral()) {
                        $literal_string .= $casted_part_type->getSingleLiteral()->value;
                    } else {
                        $literal_string = null;
                    }
                }
                if ($statements_analyzer->data_flow_graph && !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                    $var_location = new CodeLocation($statements_analyzer, $part);
                    $new_parent_node = DataFlowNode::getForAssignment('concat', $var_location);
                    $statements_analyzer->data_flow_graph->addNode($new_parent_node);
                    $parent_nodes[$new_parent_node->id] = $new_parent_node;
                    $codebase = $statements_analyzer->getCodebase();
                    $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
                    $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                    $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
                    if ($casted_part_type->parent_nodes) {
                        foreach ($casted_part_type->parent_nodes as $parent_node) {
                            $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, 'concat', $added_taints, $removed_taints);
                        }
                    }
                }
            } elseif ($part instanceof EncapsedStringPart) {
                if ($literal_string !== null) {
                    $literal_string .= $part->value;
                }
                $non_empty = $non_empty || $part->value !== "";
            } else {
                $all_literals = \false;
                $literal_string = null;
            }
        }
        if ($non_empty) {
            if ($literal_string !== null) {
                $stmt_type = new Union([new TLiteralString($literal_string)], ['parent_nodes' => $parent_nodes]);
            } elseif ($all_literals) {
                $stmt_type = new Union([new TNonEmptyNonspecificLiteralString()], ['parent_nodes' => $parent_nodes]);
            } else {
                $stmt_type = new Union([new TNonEmptyString()], ['parent_nodes' => $parent_nodes]);
            }
        } elseif ($all_literals) {
            $stmt_type = new Union([new TNonspecificLiteralString()], ['parent_nodes' => $parent_nodes]);
        } else {
            $stmt_type = new Union([new TString()], ['parent_nodes' => $parent_nodes]);
        }
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Fetch;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PropertyFetch;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\StaticPropertyFetch;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\InstancePropertyAssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DeprecatedProperty;
use Psalm\Issue\ImpurePropertyFetch;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InternalProperty;
use Psalm\Issue\MissingPropertyType;
use Psalm\Issue\NoInterfaceProperties;
use Psalm\Issue\UndefinedClass;
use Psalm\Issue\UndefinedDocblockClass;
use Psalm\Issue\UndefinedMagicPropertyFetch;
use Psalm\Issue\UndefinedPropertyFetch;
use Psalm\Issue\UndefinedThisPropertyFetch;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\Scalar\VirtualString;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualIdentifier;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_filter;
use function array_keys;
use function array_map;
use function array_search;
use function count;
use function in_array;
use function is_int;
use function is_string;
use function strtolower;
use const ARRAY_FILTER_USE_KEY;
/**
 * @internal
 */
class AtomicPropertyFetchAnalyzer
{
    /**
     * @param array<string> $invalid_fetch_types $invalid_fetch_types
     * @psalm-suppress ComplexMethod Unavoidably complex method.
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, Context $context, bool $in_assignment, ?string $var_id, ?string $stmt_var_id, Union $stmt_var_type, Atomic $lhs_type_part, string $prop_name, bool &$has_valid_fetch_type, array &$invalid_fetch_types, bool $is_static_access = \false) : void
    {
        if ($lhs_type_part instanceof TNull) {
            return;
        }
        if ($lhs_type_part instanceof TMixed) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            return;
        }
        if ($lhs_type_part instanceof TFalse && $stmt_var_type->ignore_falsable_issues) {
            return;
        }
        if (!$lhs_type_part instanceof TNamedObject && !$lhs_type_part instanceof TObject) {
            $invalid_fetch_types[] = (string) $lhs_type_part;
            return;
        }
        $has_valid_fetch_type = \true;
        if ($lhs_type_part instanceof TObjectWithProperties && isset($lhs_type_part->properties[$prop_name])) {
            $stmt_type = $statements_analyzer->node_data->getType($stmt);
            $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes($lhs_type_part->properties[$prop_name], $stmt_type));
            return;
        }
        // stdClass and SimpleXMLElement are special cases where we cannot infer the return types
        // but we don't want to throw an error
        // Hack has a similar issue: https://github.com/facebook/hhvm/issues/5164
        if ($lhs_type_part instanceof TObject || in_array(strtolower($lhs_type_part->value), Config::getInstance()->getUniversalObjectCrates(), \true)) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            return;
        }
        if (ExpressionAnalyzer::isMock($lhs_type_part->value)) {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            return;
        }
        $intersection_types = $lhs_type_part->getIntersectionTypes() ?: [];
        $fq_class_name = $lhs_type_part->value;
        $override_property_visibility = \false;
        $has_magic_getter = \false;
        $class_exists = \false;
        $codebase = $statements_analyzer->getCodebase();
        if (!$codebase->classExists($lhs_type_part->value) && !$codebase->classlikes->enumExists($lhs_type_part->value)) {
            $interface_exists = \false;
            self::handleNonExistentClass($statements_analyzer, $codebase, $stmt, $lhs_type_part, $intersection_types, $class_exists, $interface_exists, $fq_class_name, $override_property_visibility);
            if (!$class_exists && !$interface_exists) {
                return;
            }
        } else {
            $class_exists = \true;
        }
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $config = $statements_analyzer->getProjectAnalyzer()->getConfig();
        $property_id = $fq_class_name . '::$' . $prop_name;
        if ($class_storage->is_enum || in_array('UnitEnum', $codebase->getParentInterfaces($fq_class_name))) {
            if ($prop_name === 'value' && !$class_storage->is_enum) {
                $statements_analyzer->node_data->setType($stmt, new Union([new TString(), new TInt()]));
            } elseif ($prop_name === 'value' && $class_storage->enum_type !== null && $class_storage->enum_cases) {
                self::handleEnumValue($statements_analyzer, $stmt, $stmt_var_type, $class_storage);
            } elseif ($prop_name === 'name') {
                self::handleEnumName($statements_analyzer, $stmt, $lhs_type_part);
            } else {
                self::handleNonExistentProperty($statements_analyzer, $codebase, $stmt, $context, $config, $class_storage, $prop_name, $lhs_type_part, $fq_class_name, $property_id, $in_assignment, $stmt_var_id, $has_magic_getter, $var_id);
            }
            return;
        }
        $naive_property_exists = $codebase->properties->propertyExists($property_id, !$in_assignment, $statements_analyzer, $context, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null);
        // add method before changing fq_class_name
        $get_method_id = new MethodIdentifier($fq_class_name, '__get');
        if (!$naive_property_exists && $class_storage->namedMixins) {
            foreach ($class_storage->namedMixins as $mixin) {
                $new_property_id = $mixin->value . '::$' . $prop_name;
                try {
                    $new_class_storage = $codebase->classlike_storage_provider->get($mixin->value);
                } catch (InvalidArgumentException $e) {
                    $new_class_storage = null;
                }
                if ($new_class_storage && ($codebase->properties->propertyExists($new_property_id, !$in_assignment, $statements_analyzer, $context, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null) || isset($new_class_storage->pseudo_property_get_types['$' . $prop_name]))) {
                    $fq_class_name = $mixin->value;
                    $lhs_type_part = $mixin;
                    $class_storage = $new_class_storage;
                    if (!isset($new_class_storage->pseudo_property_get_types['$' . $prop_name])) {
                        $naive_property_exists = \true;
                    }
                    $property_id = $new_property_id;
                }
            }
        }
        $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($property_id, \true, $statements_analyzer);
        if (self::propertyFetchCanBeAnalyzed($statements_analyzer, $codebase, $stmt, $context, $fq_class_name, $prop_name, $lhs_type_part, $property_id, $has_magic_getter, $stmt_var_id, $naive_property_exists, $override_property_visibility, $class_exists, $declaring_property_class, $class_storage, $get_method_id, $in_assignment) === \false) {
            return;
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $property_id);
        }
        if (!$naive_property_exists && $fq_class_name !== $context->self && $context->self && $codebase->classlikes->classExtends($fq_class_name, $context->self) && $codebase->properties->propertyExists($context->self . '::$' . $prop_name, \true, $statements_analyzer, $context, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null)) {
            $property_id = $context->self . '::$' . $prop_name;
        } elseif (!$naive_property_exists || !$is_static_access && $codebase->properties->hasStorage($property_id) && $codebase->properties->getStorage($property_id)->is_static) {
            self::handleNonExistentProperty($statements_analyzer, $codebase, $stmt, $context, $config, $class_storage, $prop_name, $lhs_type_part, $declaring_property_class, $property_id, $in_assignment, $stmt_var_id, $has_magic_getter, $var_id);
            return;
        }
        if (!$override_property_visibility) {
            if (ClassLikeAnalyzer::checkPropertyVisibility($property_id, $context, $statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues()) === \false) {
                return;
            }
        }
        // FIXME: the following line look superfluous, but removing it makes
        // Psalm\Tests\PropertyTypeTest::testValidCode with data set "callInParentContext"
        // fail
        $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($property_id, \true, $statements_analyzer);
        if ($declaring_property_class === null) {
            return;
        }
        if ($codebase->properties_to_rename) {
            $declaring_property_id = strtolower($declaring_property_class) . '::$' . $prop_name;
            foreach ($codebase->properties_to_rename as $original_property_id => $new_property_name) {
                if ($declaring_property_id === $original_property_id) {
                    $file_manipulations = [new FileManipulation((int) $stmt->name->getAttribute('startFilePos'), (int) $stmt->name->getAttribute('endFilePos') + 1, $new_property_name)];
                    FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                }
            }
        }
        $declaring_class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
        if (isset($declaring_class_storage->properties[$prop_name])) {
            self::checkPropertyDeprecation($prop_name, $declaring_property_class, $stmt, $statements_analyzer);
            $property_storage = $declaring_class_storage->properties[$prop_name];
            if ($context->self && !NamespaceAnalyzer::isWithinAny($context->self, $property_storage->internal)) {
                IssueBuffer::maybeAdd(new InternalProperty($property_id . ' is internal to ' . InternalClass::listToPhrase($property_storage->internal) . ' but called from ' . $context->self, new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
            if ($context->inside_unset) {
                InstancePropertyAssignmentAnalyzer::trackPropertyImpurity($statements_analyzer, $stmt, $property_id, $property_storage, $declaring_class_storage, $context);
            }
        }
        $class_property_type = self::getClassPropertyType($statements_analyzer, $codebase, $config, $context, $stmt, $class_storage, $declaring_class_storage, $property_id, $fq_class_name, $prop_name, $lhs_type_part);
        if (!$context->collect_mutations && !$context->collect_initializations && !($class_storage->external_mutation_free && $class_property_type->allow_mutations)) {
            if ($context->pure) {
                IssueBuffer::maybeAdd(new ImpurePropertyFetch('Cannot access a property on a mutable object from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                $statements_analyzer->getSource()->inferred_impure = \true;
            }
        }
        self::processTaints($statements_analyzer, $stmt, $class_property_type, $property_id, $class_storage, $in_assignment, $context);
        if ($class_storage->mutation_free) {
            $class_property_type = $class_property_type->setProperties(['has_mutations' => \false]);
        }
        $stmt_type = $statements_analyzer->node_data->getType($stmt);
        $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes($class_property_type, $stmt_type));
    }
    /**
     * @param PropertyFetch|StaticPropertyFetch $stmt
     */
    public static function checkPropertyDeprecation(string $prop_name, string $declaring_property_class, PhpParser\Node\Expr $stmt, StatementsAnalyzer $statements_analyzer) : void
    {
        $property_id = $declaring_property_class . '::$' . $prop_name;
        $codebase = $statements_analyzer->getCodebase();
        $declaring_class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
        if (isset($declaring_class_storage->properties[$prop_name])) {
            $property_storage = $declaring_class_storage->properties[$prop_name];
            if ($property_storage->deprecated) {
                IssueBuffer::maybeAdd(new DeprecatedProperty($property_id . ' is marked deprecated', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
        }
    }
    private static function propertyFetchCanBeAnalyzed(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\PropertyFetch $stmt, Context $context, string $fq_class_name, string $prop_name, TNamedObject $lhs_type_part, string &$property_id, bool &$has_magic_getter, ?string $stmt_var_id, bool $naive_property_exists, bool $override_property_visibility, bool $class_exists, ?string $declaring_property_class, ClassLikeStorage $class_storage, MethodIdentifier $get_method_id, bool $in_assignment) : bool
    {
        if ((!$naive_property_exists || $stmt_var_id !== '$this' && $fq_class_name !== $context->self && ClassLikeAnalyzer::checkPropertyVisibility($property_id, $context, $statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues(), \false) !== \true) && $codebase->methods->methodExists($get_method_id, $context->calling_method_id, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null, !$context->collect_initializations && !$context->collect_mutations ? $statements_analyzer : null, $statements_analyzer->getFilePath())) {
            $has_magic_getter = \true;
            if (isset($class_storage->pseudo_property_get_types['$' . $prop_name])) {
                $stmt_type = TypeExpander::expandUnion($codebase, $class_storage->pseudo_property_get_types['$' . $prop_name], $class_storage->name, $class_storage->name, $class_storage->parent_class);
                if (count($template_types = $class_storage->getClassTemplateTypes()) !== 0) {
                    if (!$lhs_type_part instanceof TGenericObject) {
                        $lhs_type_part = new TGenericObject($lhs_type_part->value, $template_types);
                    }
                    $stmt_type = self::localizePropertyType($codebase, $stmt_type, $lhs_type_part, $class_storage, $declaring_property_class ? $codebase->classlike_storage_provider->get($declaring_property_class) : $class_storage);
                }
                self::processTaints($statements_analyzer, $stmt, $stmt_type, $property_id, $class_storage, $in_assignment, $context);
                $statements_analyzer->node_data->setType($stmt, $stmt_type);
                return \false;
            }
            $old_data_provider = $statements_analyzer->node_data;
            $statements_analyzer->node_data = clone $statements_analyzer->node_data;
            $statements_analyzer->node_data->setType($stmt->var, new Union([$lhs_type_part]));
            $fake_method_call = new VirtualMethodCall($stmt->var, new VirtualIdentifier('__get', $stmt->name->getAttributes()), [new VirtualArg(new VirtualString($prop_name, $stmt->name->getAttributes()))]);
            $suppressed_issues = $statements_analyzer->getSuppressedIssues();
            if (!in_array('InternalMethod', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['InternalMethod']);
            }
            MethodCallAnalyzer::analyze($statements_analyzer, $fake_method_call, $context, \false);
            if (!in_array('InternalMethod', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['InternalMethod']);
            }
            $fake_method_call_type = $statements_analyzer->node_data->getType($fake_method_call);
            $statements_analyzer->node_data = $old_data_provider;
            if ($fake_method_call_type) {
                $stmt_type = $statements_analyzer->node_data->getType($stmt);
                $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes($fake_method_call_type, $stmt_type));
            } else {
                $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            }
            /*
             * If we have an explicit list of all allowed magic properties on the class, and we're
             * not in that list, fall through
             */
            if (!($class_storage->sealed_properties || $codebase->config->seal_all_properties) && !$override_property_visibility) {
                return \false;
            }
            if (!$class_exists) {
                $property_id = $lhs_type_part->value . '::$' . $prop_name;
                IssueBuffer::maybeAdd(new UndefinedMagicPropertyFetch('Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
                return \false;
            }
        }
        return \true;
    }
    public static function localizePropertyType(Codebase $codebase, Union $class_property_type, TGenericObject $lhs_type_part, ClassLikeStorage $property_class_storage, ClassLikeStorage $property_declaring_class_storage) : Union
    {
        $template_types = CallAnalyzer::getTemplateTypesForCall($codebase, $property_declaring_class_storage, $property_declaring_class_storage->name, $property_class_storage, $property_class_storage->template_types ?: []);
        $extended_types = $property_class_storage->template_extended_params;
        if ($template_types) {
            if ($property_class_storage->template_types) {
                foreach ($lhs_type_part->type_params as $param_offset => $lhs_param_type) {
                    $i = -1;
                    foreach ($property_class_storage->template_types as $calling_param_name => $_) {
                        $i++;
                        if ($i === $param_offset) {
                            $template_types[$calling_param_name][$property_class_storage->name] = $lhs_param_type;
                            break;
                        }
                    }
                }
            }
            foreach ($template_types as $type_name => $_) {
                if (isset($extended_types[$property_declaring_class_storage->name][$type_name])) {
                    $mapped_type = $extended_types[$property_declaring_class_storage->name][$type_name];
                    foreach ($mapped_type->getAtomicTypes() as $mapped_type_atomic) {
                        if (!$mapped_type_atomic instanceof TTemplateParam) {
                            continue;
                        }
                        $param_name = $mapped_type_atomic->param_name;
                        $position = \false;
                        if (isset($property_class_storage->template_types[$param_name])) {
                            $position = array_search($param_name, array_keys($property_class_storage->template_types));
                        }
                        if ($position !== \false && isset($lhs_type_part->type_params[$position])) {
                            $template_types[$type_name][$property_declaring_class_storage->name] = $lhs_type_part->type_params[$position];
                        }
                    }
                }
            }
            $class_property_type = TemplateInferredTypeReplacer::replace($class_property_type, new TemplateResult([], $template_types), $codebase);
        }
        return $class_property_type;
    }
    public static function processTaints(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, Union &$type, string $property_id, ClassLikeStorage $class_storage, bool $in_assignment, ?Context $context = null) : void
    {
        if (!$statements_analyzer->data_flow_graph) {
            return;
        }
        $data_flow_graph = $statements_analyzer->data_flow_graph;
        $added_taints = [];
        $removed_taints = [];
        if ($context) {
            $codebase = $statements_analyzer->getCodebase();
            $event = new AddRemoveTaintsEvent($stmt, $context, $statements_analyzer, $codebase);
            $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
            $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
        }
        if ($class_storage->specialize_instance) {
            $var_id = ExpressionIdentifier::getExtendedVarId($stmt->var, null, $statements_analyzer);
            $var_property_id = ExpressionIdentifier::getExtendedVarId($stmt, null, $statements_analyzer);
            if ($var_id) {
                $var_type = $statements_analyzer->node_data->getType($stmt->var);
                if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && $var_type && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                    $statements_analyzer->node_data->setType($stmt->var, $var_type->setParentNodes([]));
                    return;
                }
                $var_location = new CodeLocation($statements_analyzer->getSource(), $stmt->var);
                $property_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                $var_node = DataFlowNode::getForAssignment($var_id, $var_location);
                $data_flow_graph->addNode($var_node);
                $property_node = DataFlowNode::getForAssignment($var_property_id ?: $var_id . '->$property', $property_location);
                $data_flow_graph->addNode($property_node);
                $data_flow_graph->addPath($var_node, $property_node, 'property-fetch' . ($stmt->name instanceof PhpParser\Node\Identifier ? '-' . $stmt->name : ''), $added_taints, $removed_taints);
                if ($var_type && $var_type->parent_nodes) {
                    foreach ($var_type->parent_nodes as $parent_node) {
                        $data_flow_graph->addPath($parent_node, $var_node, '=', $added_taints, $removed_taints);
                    }
                }
                $type = $type->setParentNodes([$property_node->id => $property_node], \true);
            }
        } else {
            self::processUnspecialTaints($statements_analyzer, $stmt, $type, $property_id, $in_assignment, $added_taints, $removed_taints);
        }
    }
    /**
     * @param ?array<string> $added_taints
     * @param ?array<string> $removed_taints
     */
    public static function processUnspecialTaints(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Union &$type, string $property_id, bool $in_assignment, ?array $added_taints, ?array $removed_taints) : void
    {
        if (!$statements_analyzer->data_flow_graph) {
            return;
        }
        $data_flow_graph = $statements_analyzer->data_flow_graph;
        $var_property_id = ExpressionIdentifier::getExtendedVarId($stmt, null, $statements_analyzer);
        $property_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
        $localized_property_node = DataFlowNode::getForAssignment($var_property_id ?: $property_id, $property_location);
        $data_flow_graph->addNode($localized_property_node);
        $property_node = new DataFlowNode($property_id, $property_id, null, null);
        $data_flow_graph->addNode($property_node);
        if ($in_assignment) {
            $data_flow_graph->addPath($localized_property_node, $property_node, 'property-assignment', $added_taints, $removed_taints);
        } else {
            $data_flow_graph->addPath($property_node, $localized_property_node, 'property-fetch', $added_taints, $removed_taints);
        }
        $type = $type->setParentNodes([$localized_property_node->id => $localized_property_node], \true);
    }
    private static function handleEnumName(StatementsAnalyzer $statements_analyzer, PropertyFetch $stmt, Atomic $lhs_type_part) : void
    {
        if ($lhs_type_part instanceof TEnumCase) {
            $statements_analyzer->node_data->setType($stmt, new Union([new TLiteralString($lhs_type_part->case_name)]));
        } else {
            $statements_analyzer->node_data->setType($stmt, Type::getNonEmptyString());
        }
    }
    private static function handleEnumValue(StatementsAnalyzer $statements_analyzer, PropertyFetch $stmt, Union $stmt_var_type, ClassLikeStorage $class_storage) : void
    {
        $relevant_enum_cases = array_filter($stmt_var_type->getAtomicTypes(), static fn(Atomic $type): bool => $type instanceof TEnumCase);
        $relevant_enum_case_names = array_map(static fn(TEnumCase $enumCase): string => $enumCase->case_name, $relevant_enum_cases);
        $enum_cases = $class_storage->enum_cases;
        if (!empty($relevant_enum_case_names)) {
            // If we have a known subset of enum cases, include only those
            $enum_cases = array_filter($enum_cases, static fn(string $key) => in_array($key, $relevant_enum_case_names, \true), ARRAY_FILTER_USE_KEY);
        }
        $case_values = [];
        foreach ($enum_cases as $enum_case) {
            if (is_string($enum_case->value)) {
                $case_values[] = new TLiteralString($enum_case->value);
            } elseif (is_int($enum_case->value)) {
                $case_values[] = new TLiteralInt($enum_case->value);
            } else {
                // this should never happen
                $case_values[] = new TMixed();
            }
        }
        /** @psalm-suppress ArgumentTypeCoercion */
        $statements_analyzer->node_data->setType($stmt, new Union($case_values));
    }
    private static function handleUndefinedProperty(Context $context, StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, ?string $stmt_var_id, string $property_id, bool $has_magic_getter, ?string $var_id) : void
    {
        if ($context->inside_isset || $context->collect_initializations) {
            if ($context->pure) {
                IssueBuffer::maybeAdd(new ImpurePropertyFetch('Cannot access a property on a mutable object from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($context->inside_isset && $statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                $statements_analyzer->getSource()->inferred_impure = \true;
            }
            return;
        }
        if ($stmt_var_id === '$this') {
            IssueBuffer::maybeAdd(new UndefinedThisPropertyFetch('Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
        } else {
            if ($has_magic_getter) {
                IssueBuffer::maybeAdd(new UndefinedMagicPropertyFetch('Magic instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new UndefinedPropertyFetch('Instance property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
        }
        $stmt_type = Type::getMixed();
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
        if ($var_id) {
            $context->vars_in_scope[$var_id] = $stmt_type;
        }
    }
    /**
     * @param  array<Atomic>     $intersection_types
     */
    private static function handleNonExistentClass(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\PropertyFetch $stmt, TNamedObject $lhs_type_part, array $intersection_types, bool &$class_exists, bool &$interface_exists, string &$fq_class_name, bool &$override_property_visibility) : void
    {
        if ($codebase->interfaceExists($lhs_type_part->value)) {
            $interface_exists = \true;
            $interface_storage = $codebase->classlike_storage_provider->get($lhs_type_part->value);
            $override_property_visibility = $interface_storage->override_property_visibility;
            foreach ($intersection_types as $intersection_type) {
                if ($intersection_type instanceof TNamedObject && $codebase->classExists($intersection_type->value)) {
                    $fq_class_name = $intersection_type->value;
                    $class_exists = \true;
                    return;
                }
            }
            if (!$class_exists && !in_array($fq_class_name, ['UnitEnum', 'BackedEnum'], \true) && !in_array('UnitEnum', $codebase->getParentInterfaces($fq_class_name))) {
                if (IssueBuffer::accepts(new NoInterfaceProperties('Interfaces cannot have properties', new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value), $statements_analyzer->getSuppressedIssues())) {
                    return;
                }
                if (!$codebase->methodExists($fq_class_name . '::__set')) {
                    return;
                }
            }
        }
        if (!$class_exists && !$interface_exists) {
            if ($lhs_type_part->from_docblock) {
                IssueBuffer::maybeAdd(new UndefinedDocblockClass('Cannot get properties of undefined docblock class ' . $lhs_type_part->value, new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new UndefinedClass('Cannot get properties of undefined class ' . $lhs_type_part->value, new CodeLocation($statements_analyzer->getSource(), $stmt), $lhs_type_part->value), $statements_analyzer->getSuppressedIssues());
            }
        }
    }
    private static function handleNonExistentProperty(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\PropertyFetch $stmt, Context $context, Config $config, ClassLikeStorage $class_storage, string $prop_name, TNamedObject $lhs_type_part, ?string $declaring_property_class, string $property_id, bool $in_assignment, ?string $stmt_var_id, bool $has_magic_getter, ?string $var_id) : void
    {
        if ($config->use_phpdoc_property_without_magic_or_parent && isset($class_storage->pseudo_property_get_types['$' . $prop_name])) {
            $stmt_type = $class_storage->pseudo_property_get_types['$' . $prop_name];
            if (count($template_types = $class_storage->getClassTemplateTypes()) !== 0) {
                if (!$lhs_type_part instanceof TGenericObject) {
                    $lhs_type_part = new TGenericObject($lhs_type_part->value, $template_types);
                }
                $stmt_type = self::localizePropertyType($codebase, $stmt_type, $lhs_type_part, $class_storage, $declaring_property_class ? $codebase->classlike_storage_provider->get($declaring_property_class) : $class_storage);
            }
            self::processTaints($statements_analyzer, $stmt, $stmt_type, $property_id, $class_storage, $in_assignment, $context);
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            return;
        }
        if ($class_storage->is_interface) {
            return;
        }
        self::handleUndefinedProperty($context, $statements_analyzer, $stmt, $stmt_var_id, $property_id, $has_magic_getter, $var_id);
    }
    private static function getClassPropertyType(StatementsAnalyzer $statements_analyzer, Codebase $codebase, Config $config, Context $context, PhpParser\Node\Expr\PropertyFetch $stmt, ClassLikeStorage $class_storage, ClassLikeStorage $declaring_class_storage, string $property_id, string $fq_class_name, string $prop_name, TNamedObject $lhs_type_part) : Union
    {
        $class_property_type = $codebase->properties->getPropertyType($property_id, \false, $statements_analyzer, $context);
        if (!$class_property_type) {
            if ($declaring_class_storage->location && $config->isInProjectDirs($declaring_class_storage->location->file_path)) {
                IssueBuffer::maybeAdd(new MissingPropertyType('Property ' . $fq_class_name . '::$' . $prop_name . ' does not have a declared type', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
            $class_property_type = Type::getMixed();
        } else {
            $class_property_type = TypeExpander::expandUnion($codebase, $class_property_type, $declaring_class_storage->name, $declaring_class_storage->name, $declaring_class_storage->parent_class);
            if (count($template_types = $declaring_class_storage->getClassTemplateTypes()) !== 0) {
                if (!$lhs_type_part instanceof TGenericObject) {
                    $lhs_type_part = new TGenericObject($lhs_type_part->value, $template_types);
                }
                $class_property_type = self::localizePropertyType($codebase, $class_property_type, $lhs_type_part, $class_storage, $declaring_class_storage);
            } elseif ($lhs_type_part instanceof TGenericObject) {
                $class_property_type = self::localizePropertyType($codebase, $class_property_type, $lhs_type_part, $class_storage, $declaring_class_storage);
            }
        }
        return $class_property_type;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Fetch;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\TaintSource;
use Psalm\Issue\ImpureVariable;
use Psalm\Issue\InvalidScope;
use Psalm\Issue\PossiblyUndefinedGlobalVariable;
use Psalm\Issue\PossiblyUndefinedVariable;
use Psalm\Issue\UndefinedGlobalVariable;
use Psalm\Issue\UndefinedVariable;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\TaintKindGroup;
use Psalm\Type\Union;
use function in_array;
use function is_string;
use function time;
/**
 * @internal
 */
class VariableFetchAnalyzer
{
    public const SUPER_GLOBALS = ['$GLOBALS', '$_SERVER', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_REQUEST', '$_ENV', '$http_response_header'];
    /**
     * @param bool $from_global - when used in a global keyword
     * @param bool $assigned_to_reference This is set to true when the expression being analyzed
     *                                    here is being assigned to another variable by reference.
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Variable $stmt, Context $context, bool $passed_by_reference = \false, ?Union $by_ref_type = null, bool $array_assignment = \false, bool $from_global = \false, bool $assigned_to_reference = \false) : bool
    {
        $project_analyzer = $statements_analyzer->getFileAnalyzer()->project_analyzer;
        $codebase = $statements_analyzer->getCodebase();
        if ($stmt->name === 'this') {
            if ($statements_analyzer->isStatic()) {
                return !IssueBuffer::accepts(new InvalidScope('Invalid reference to $this in a static context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            if (!isset($context->vars_in_scope['$this'])) {
                if (IssueBuffer::accepts(new InvalidScope('Invalid reference to $this in a non-class context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues())) {
                    return \false;
                }
                $context->vars_in_scope['$this'] = Type::getMixed();
                $context->vars_possibly_in_scope['$this'] = \true;
                return \true;
            }
            $statements_analyzer->node_data->setType($stmt, $context->vars_in_scope['$this']);
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations && ($stmt_type = $statements_analyzer->node_data->getType($stmt))) {
                $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt, $stmt_type->getId());
            }
            if (!$context->collect_mutations && !$context->collect_initializations) {
                if ($context->pure) {
                    IssueBuffer::maybeAdd(new ImpureVariable('Cannot reference $this in a pure context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                    $statements_analyzer->getSource()->inferred_impure = \true;
                }
            }
            return \true;
        }
        if (!$context->check_variables) {
            if (is_string($stmt->name)) {
                $var_name = '$' . $stmt->name;
                if (!$context->hasVariable($var_name)) {
                    $context->vars_in_scope[$var_name] = Type::getMixed();
                    $context->vars_possibly_in_scope[$var_name] = \true;
                    $statements_analyzer->node_data->setType($stmt, Type::getMixed());
                } else {
                    $stmt_type = $context->vars_in_scope[$var_name];
                    self::addDataFlowToVariable($statements_analyzer, $stmt, $var_name, $stmt_type, $context);
                    $context->vars_in_scope[$var_name] = $stmt_type;
                    $statements_analyzer->node_data->setType($stmt, $stmt_type);
                }
            } else {
                $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            }
            return \true;
        }
        if (is_string($stmt->name) && self::isSuperGlobal('$' . $stmt->name)) {
            $var_name = '$' . $stmt->name;
            if (isset($context->vars_in_scope[$var_name])) {
                $type = $context->vars_in_scope[$var_name];
                self::taintVariable($statements_analyzer, $var_name, $type, $stmt);
                $context->vars_in_scope[$var_name] = $type;
                $statements_analyzer->node_data->setType($stmt, $type);
                return \true;
            }
            $type = self::getGlobalType($var_name, $codebase->analysis_php_version_id);
            self::taintVariable($statements_analyzer, $var_name, $type, $stmt);
            $statements_analyzer->node_data->setType($stmt, $type);
            $context->vars_in_scope[$var_name] = $type;
            $context->vars_possibly_in_scope[$var_name] = \true;
            $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt, $var_name);
            return \true;
        }
        if (!is_string($stmt->name)) {
            if ($context->pure) {
                IssueBuffer::maybeAdd(new ImpureVariable('Cannot reference an unknown variable in a pure context', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                $statements_analyzer->getSource()->inferred_impure = \true;
            }
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            $expr_result = ExpressionAnalyzer::analyze($statements_analyzer, $stmt->name, $context);
            $context->inside_general_use = $was_inside_general_use;
            return $expr_result;
        }
        if ($passed_by_reference && $by_ref_type) {
            AssignmentAnalyzer::assignByRefParam($statements_analyzer, $stmt, $by_ref_type, $by_ref_type, $context);
            return \true;
        }
        $var_name = '$' . $stmt->name;
        if (!$context->hasVariable($var_name)) {
            if (!isset($context->vars_possibly_in_scope[$var_name]) || !$statements_analyzer->getFirstAppearance($var_name)) {
                if ($array_assignment || $assigned_to_reference) {
                    if ($array_assignment) {
                        // if we're in an array assignment, let's assign the variable because PHP allows it
                        $stmt_type = Type::getArray();
                    } else {
                        // If a variable is assigned by reference to a variable that
                        // does not exist, they are automatically initialized as `null`
                        $stmt_type = Type::getNull();
                    }
                    $context->vars_in_scope[$var_name] = $stmt_type;
                    $context->vars_possibly_in_scope[$var_name] = \true;
                    // it might have been defined first in another if/else branch
                    if (!$statements_analyzer->hasVariable($var_name)) {
                        $statements_analyzer->registerVariable($var_name, new CodeLocation($statements_analyzer, $stmt), $context->branch_point);
                    }
                    $statements_analyzer->node_data->setType($stmt, $stmt_type);
                    if ($assigned_to_reference) {
                        // Since this variable was created by being assigned to as a reference (ie for
                        // `$a = &$b` this variable is $b), we need to analyze it as an assignment to null.
                        AssignmentAnalyzer::analyze($statements_analyzer, $stmt, null, $stmt_type, $context, null);
                        // Stop here, we don't want it to be considered possibly undefined like the array case.
                        return \true;
                    }
                } elseif (!$context->inside_isset || $statements_analyzer->getSource() instanceof FunctionLikeAnalyzer) {
                    if ($context->is_global || $from_global) {
                        IssueBuffer::maybeAdd(new UndefinedGlobalVariable('Cannot find referenced variable ' . $var_name . ' in global scope', new CodeLocation($statements_analyzer->getSource(), $stmt), $var_name), $statements_analyzer->getSuppressedIssues());
                        $statements_analyzer->node_data->setType($stmt, Type::getMixed());
                        return \true;
                    }
                    IssueBuffer::maybeAdd(new UndefinedVariable('Cannot find referenced variable ' . $var_name, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    $statements_analyzer->node_data->setType($stmt, Type::getMixed());
                    return \true;
                }
            }
            $first_appearance = $statements_analyzer->getFirstAppearance($var_name);
            if ($first_appearance && !$context->inside_isset && !$context->inside_unset) {
                if ($context->is_global) {
                    if ($codebase->alter_code) {
                        if (!isset($project_analyzer->getIssuesToFix()['PossiblyUndefinedGlobalVariable'])) {
                            return \true;
                        }
                        $branch_point = $statements_analyzer->getBranchPoint($var_name);
                        if ($branch_point) {
                            $statements_analyzer->addVariableInitialization($var_name, $branch_point);
                        }
                        return \true;
                    }
                    IssueBuffer::maybeAdd(new PossiblyUndefinedGlobalVariable('Possibly undefined global variable ' . $var_name . ', first seen on line ' . $first_appearance->getLineNumber(), new CodeLocation($statements_analyzer->getSource(), $stmt), $var_name), $statements_analyzer->getSuppressedIssues(), (bool) $statements_analyzer->getBranchPoint($var_name));
                } else {
                    if ($codebase->alter_code) {
                        if (!isset($project_analyzer->getIssuesToFix()['PossiblyUndefinedVariable'])) {
                            return \true;
                        }
                        $branch_point = $statements_analyzer->getBranchPoint($var_name);
                        if ($branch_point) {
                            $statements_analyzer->addVariableInitialization($var_name, $branch_point);
                        }
                        return \true;
                    }
                    IssueBuffer::maybeAdd(new PossiblyUndefinedVariable('Possibly undefined variable ' . $var_name . ', first seen on line ' . $first_appearance->getLineNumber(), new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues(), (bool) $statements_analyzer->getBranchPoint($var_name));
                }
                if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                    $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt, $first_appearance->raw_file_start . '-' . $first_appearance->raw_file_end . ':mixed');
                }
                $stmt_type = Type::getMixed();
                self::addDataFlowToVariable($statements_analyzer, $stmt, $var_name, $stmt_type, $context);
                $statements_analyzer->node_data->setType($stmt, $stmt_type);
                $statements_analyzer->registerPossiblyUndefinedVariable($var_name, $stmt);
                return \true;
            }
        } else {
            $stmt_type = $context->vars_in_scope[$var_name];
            self::addDataFlowToVariable($statements_analyzer, $stmt, $var_name, $stmt_type, $context);
            $context->vars_in_scope[$var_name] = $stmt_type;
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            if ($stmt_type->possibly_undefined_from_try && !$context->inside_isset) {
                if ($context->is_global) {
                    IssueBuffer::maybeAdd(new PossiblyUndefinedGlobalVariable('Possibly undefined global variable ' . $var_name . ' defined in try block', new CodeLocation($statements_analyzer->getSource(), $stmt), $var_name), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new PossiblyUndefinedVariable('Possibly undefined variable ' . $var_name . ' defined in try block', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            }
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt, $stmt_type->getId());
            }
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $first_appearance = $statements_analyzer->getFirstAppearance($var_name);
                if ($first_appearance) {
                    $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt, $first_appearance->raw_file_start . '-' . $first_appearance->raw_file_end . ':' . $stmt_type->getId());
                }
            }
        }
        return \true;
    }
    private static function addDataFlowToVariable(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Variable $stmt, string $var_name, Union &$stmt_type, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        if ($statements_analyzer->data_flow_graph && $codebase->find_unused_variables && ($context->inside_return || $context->inside_call || $context->inside_general_use || $context->inside_conditional || $context->inside_throw || $context->inside_isset)) {
            if (!$stmt_type->parent_nodes) {
                $assignment_node = DataFlowNode::getForAssignment($var_name, new CodeLocation($statements_analyzer->getSource(), $stmt));
                $stmt_type = $stmt_type->setParentNodes([$assignment_node->id => $assignment_node]);
            }
            foreach ($stmt_type->parent_nodes as $parent_node) {
                if ($context->inside_call || $context->inside_return) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('variable-use', 'variable use', null), 'use-inside-call');
                } elseif ($context->inside_conditional) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('variable-use', 'variable use', null), 'use-inside-conditional');
                } elseif ($context->inside_isset) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('variable-use', 'variable use', null), 'use-inside-isset');
                } else {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                }
            }
        }
    }
    private static function taintVariable(StatementsAnalyzer $statements_analyzer, string $var_name, Union &$type, PhpParser\Node\Expr\Variable $stmt) : void
    {
        if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && !in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
            if ($var_name === '$_GET' || $var_name === '$_POST' || $var_name === '$_COOKIE' || $var_name === '$_REQUEST') {
                $taint_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                $server_taint_source = new TaintSource($var_name . ':' . $taint_location->file_name . ':' . $taint_location->raw_file_start, $var_name, null, null, TaintKindGroup::ALL_INPUT);
                $statements_analyzer->data_flow_graph->addSource($server_taint_source);
                $type = $type->setParentNodes([$server_taint_source->id => $server_taint_source]);
            }
        }
    }
    /**
     * @psalm-pure
     */
    public static function isSuperGlobal(string $var_id) : bool
    {
        return in_array($var_id, self::SUPER_GLOBALS, \true);
    }
    /** @var array<value-of<self::SUPER_GLOBALS>|'$_FILES full path'|'$argv'|'$argc', Union> */
    private static array $globalCache = [];
    public static function getGlobalType(string $var_id, int $codebase_analysis_php_version_id) : Union
    {
        $config = Config::getInstance();
        if (isset($config->globals[$var_id])) {
            return Type::parseString($config->globals[$var_id]);
        }
        if (!self::$globalCache) {
            foreach (self::SUPER_GLOBALS as $v) {
                self::$globalCache[$v] = self::getGlobalTypeInner($v);
            }
            self::$globalCache['$_FILES full path'] = self::getGlobalTypeInner('$_FILES', \true);
            self::$globalCache['$argv'] = self::getGlobalTypeInner('$argv');
            self::$globalCache['$argc'] = self::getGlobalTypeInner('$argc');
        }
        if ($codebase_analysis_php_version_id >= 80100 && $var_id === '$_FILES') {
            $var_id = '$_FILES full path';
        }
        if (isset(self::$globalCache[$var_id])) {
            return self::$globalCache[$var_id];
        }
        return Type::getMixed();
    }
    /**
     * @param value-of<self::SUPER_GLOBALS>|'$argv'|'$argc' $var_id
     */
    private static function getGlobalTypeInner(string $var_id, bool $files_full_path = \false) : Union
    {
        if ($var_id === '$argv') {
            // only in CLI, null otherwise
            return new Union([Type::getNonEmptyListAtomic(Type::getString()), new TNull()], ['ignore_nullable_issues' => \true]);
            // use TNull explicitly instead of this
            // as it will cause weird errors due to ignore_nullable_issues true
            // e.g. InvalidPropertyAssignmentValue
            // $this->argv 'list<string>' cannot be assigned type 'non-empty-list<string>'
        }
        if ($var_id === '$argc') {
            // only in CLI, null otherwise
            return new Union([new TIntRange(1, null), new TNull()], ['ignore_nullable_issues' => \true]);
        }
        if ($var_id === '$http_response_header') {
            // $http_response_header exists only in the local scope after a successful network request
            return new Union([Type::getNonEmptyListAtomic(Type::getNonFalsyString())], ['possibly_undefined' => \true]);
        }
        if ($var_id === '$GLOBALS') {
            return new Union([new TNonEmptyArray([Type::getNonEmptyString(), Type::getMixed()])]);
        }
        if ($var_id === '$_COOKIE') {
            $type = new TArray([Type::getNonEmptyString(), Type::getString()]);
            return new Union([$type]);
        }
        if (in_array($var_id, array('$_GET', '$_POST', '$_REQUEST'), \true)) {
            $array_key = new Union([new TNonEmptyString(), new TInt()]);
            $array = new TNonEmptyArray([$array_key, new Union([new TString(), new TArray([$array_key, Type::getMixed()])])]);
            $type = new TArray([$array_key, new Union([new TString(), $array])]);
            return new Union([$type]);
        }
        if ($var_id === '$_SERVER' || $var_id === '$_ENV') {
            $string_helper = new Union([new TString()], ['possibly_undefined' => \true]);
            $non_empty_string_helper = new Union([new TNonEmptyString()], ['possibly_undefined' => \true]);
            $argv_helper = new Union([Type::getNonEmptyListAtomic(Type::getString())], ['possibly_undefined' => \true]);
            $argc_helper = new Union([new TIntRange(1, null)], ['possibly_undefined' => \true]);
            $request_time_helper = new Union([new TIntRange(time(), null)], ['possibly_undefined' => \true]);
            $request_time_float_helper = new Union([new TFloat()], ['possibly_undefined' => \true]);
            $bool_string_helper = new Union([new TBool(), new TString()], ['possibly_undefined' => \true]);
            $arr = [
                // https://www.php.net/manual/en/reserved.variables.server.php
                'PHP_SELF' => $non_empty_string_helper,
                'GATEWAY_INTERFACE' => $non_empty_string_helper,
                'SERVER_ADDR' => $non_empty_string_helper,
                'SERVER_NAME' => $non_empty_string_helper,
                'SERVER_SOFTWARE' => $non_empty_string_helper,
                'SERVER_PROTOCOL' => $non_empty_string_helper,
                'REQUEST_METHOD' => $non_empty_string_helper,
                'REQUEST_TIME' => $request_time_helper,
                'REQUEST_TIME_FLOAT' => $request_time_float_helper,
                'QUERY_STRING' => $string_helper,
                'DOCUMENT_ROOT' => $non_empty_string_helper,
                'HTTP_ACCEPT' => $non_empty_string_helper,
                'HTTP_ACCEPT_CHARSET' => $non_empty_string_helper,
                'HTTP_ACCEPT_ENCODING' => $non_empty_string_helper,
                'HTTP_ACCEPT_LANGUAGE' => $non_empty_string_helper,
                'HTTP_CONNECTION' => $non_empty_string_helper,
                'HTTP_HOST' => $non_empty_string_helper,
                'HTTP_REFERER' => $non_empty_string_helper,
                'HTTP_USER_AGENT' => $non_empty_string_helper,
                'HTTPS' => $string_helper,
                'REMOTE_ADDR' => $non_empty_string_helper,
                'REMOTE_HOST' => $non_empty_string_helper,
                'REMOTE_PORT' => $string_helper,
                'REMOTE_USER' => $non_empty_string_helper,
                'REDIRECT_REMOTE_USER' => $non_empty_string_helper,
                'SCRIPT_FILENAME' => $non_empty_string_helper,
                'SERVER_ADMIN' => $non_empty_string_helper,
                'SERVER_PORT' => $non_empty_string_helper,
                'SERVER_SIGNATURE' => $non_empty_string_helper,
                'PATH_TRANSLATED' => $non_empty_string_helper,
                'SCRIPT_NAME' => $non_empty_string_helper,
                'REQUEST_URI' => $non_empty_string_helper,
                'PHP_AUTH_DIGEST' => $non_empty_string_helper,
                'PHP_AUTH_USER' => $non_empty_string_helper,
                'PHP_AUTH_PW' => $non_empty_string_helper,
                'AUTH_TYPE' => $non_empty_string_helper,
                'PATH_INFO' => $non_empty_string_helper,
                'ORIG_PATH_INFO' => $non_empty_string_helper,
                // misc from RFC not included above already http://www.faqs.org/rfcs/rfc3875.html
                'CONTENT_LENGTH' => $string_helper,
                'CONTENT_TYPE' => $string_helper,
                // common, misc stuff
                'FCGI_ROLE' => $non_empty_string_helper,
                'HOME' => $non_empty_string_helper,
                'HTTP_CACHE_CONTROL' => $non_empty_string_helper,
                'HTTP_COOKIE' => $non_empty_string_helper,
                'HTTP_PRIORITY' => $non_empty_string_helper,
                'PATH' => $non_empty_string_helper,
                'REDIRECT_STATUS' => $non_empty_string_helper,
                'REQUEST_SCHEME' => $non_empty_string_helper,
                'USER' => $non_empty_string_helper,
                // common, misc headers
                'HTTP_UPGRADE_INSECURE_REQUESTS' => $non_empty_string_helper,
                'HTTP_X_FORWARDED_PROTO' => $non_empty_string_helper,
                'HTTP_CLIENT_IP' => $non_empty_string_helper,
                'HTTP_X_REAL_IP' => $non_empty_string_helper,
                'HTTP_X_FORWARDED_FOR' => $non_empty_string_helper,
                'HTTP_CF_CONNECTING_IP' => $non_empty_string_helper,
                'HTTP_CF_IPCOUNTRY' => $non_empty_string_helper,
                'HTTP_CF_VISITOR' => $non_empty_string_helper,
                'HTTP_CDN_LOOP' => $non_empty_string_helper,
                // common, misc browser headers
                'HTTP_DNT' => $non_empty_string_helper,
                'HTTP_SEC_FETCH_DEST' => $non_empty_string_helper,
                'HTTP_SEC_FETCH_USER' => $non_empty_string_helper,
                'HTTP_SEC_FETCH_MODE' => $non_empty_string_helper,
                'HTTP_SEC_FETCH_SITE' => $non_empty_string_helper,
                'HTTP_SEC_CH_UA_PLATFORM' => $non_empty_string_helper,
                'HTTP_SEC_CH_UA_MOBILE' => $non_empty_string_helper,
                'HTTP_SEC_CH_UA' => $non_empty_string_helper,
                // phpunit
                'APP_DEBUG' => $bool_string_helper,
                'APP_ENV' => $string_helper,
            ];
            if ($var_id === '$_SERVER') {
                $arr['argv'] = $argv_helper;
                $arr['argc'] = $argc_helper;
            }
            $detailed_type = new TKeyedArray($arr, null, [Type::getNonEmptyString(), Type::getString()]);
            return new Union([$detailed_type]);
        }
        if ($var_id === '$_FILES') {
            $str = Type::getString();
            $values = ['name' => $str, 'type' => $str, 'tmp_name' => $str, 'size' => Type::getListKey(), 'error' => new Union([new TIntRange(0, 8)])];
            if ($files_full_path) {
                $values['full_path'] = $str;
            }
            $type = new Union([new TKeyedArray($values)]);
            $parent = new TArray([Type::getNonEmptyString(), $type]);
            return new Union([$parent]);
        }
        // $var_id === $_SESSION
        // keys must be string
        return new Union([new TArray([Type::getNonEmptyString(), Type::getMixed()])], ['possibly_undefined' => \true]);
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Fetch;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Issue\ImpurePropertyFetch;
use Psalm\Issue\InvalidPropertyFetch;
use Psalm\Issue\MixedPropertyFetch;
use Psalm\Issue\NullPropertyFetch;
use Psalm\Issue\PossiblyInvalidPropertyFetch;
use Psalm\Issue\PossiblyNullPropertyFetch;
use Psalm\Issue\UninitializedProperty;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TTemplateParam;
use function array_merge;
use function array_shift;
use function rtrim;
use function strtolower;
/**
 * @internal
 */
class InstancePropertyFetchAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, Context $context, bool $in_assignment = \false, bool $is_static_access = \false) : bool
    {
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        if (!$stmt->name instanceof PhpParser\Node\Identifier) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->name, $context) === \false) {
                return \false;
            }
        }
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context) === \false) {
            $context->inside_general_use = $was_inside_general_use;
            return \false;
        }
        $context->inside_general_use = $was_inside_general_use;
        if ($stmt->name instanceof PhpParser\Node\Identifier) {
            $prop_name = $stmt->name->name;
        } elseif (($stmt_name_type = $statements_analyzer->node_data->getType($stmt->name)) && $stmt_name_type->isSingleStringLiteral()) {
            $prop_name = $stmt_name_type->getSingleStringLiteral()->value;
        } else {
            $prop_name = null;
        }
        $codebase = $statements_analyzer->getCodebase();
        $stmt_var_id = ExpressionIdentifier::getExtendedVarId($stmt->var, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $var_id = ExpressionIdentifier::getExtendedVarId($stmt, $statements_analyzer->getFQCLN(), $statements_analyzer);
        if ($var_id && $context->hasVariable($var_id)) {
            self::handleScopedProperty($context, $var_id, $statements_analyzer, $stmt, $codebase, $stmt_var_id, $in_assignment);
            return \true;
        }
        if ($stmt_var_id && $context->hasVariable($stmt_var_id)) {
            $stmt_var_type = $context->vars_in_scope[$stmt_var_id];
        } else {
            $stmt_var_type = $statements_analyzer->node_data->getType($stmt->var);
        }
        if (!$stmt_var_type) {
            return \true;
        }
        if ($stmt_var_type->isNull()) {
            return !IssueBuffer::accepts(new NullPropertyFetch('Cannot get property on null variable ' . $stmt_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        if ($stmt_var_type->isNever()) {
            return !IssueBuffer::accepts(new MixedPropertyFetch('Cannot fetch property on empty var ' . $stmt_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        }
        if ($stmt_var_type->hasMixed()) {
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
            }
            if ($stmt->name instanceof PhpParser\Node\Identifier) {
                $codebase->analyzer->addMixedMemberName('$' . $stmt->name->name, $context->calling_method_id ?: $statements_analyzer->getFileName());
            }
            IssueBuffer::maybeAdd(new MixedPropertyFetch('Cannot fetch property on mixed var ' . $stmt_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_var_type->getId());
            }
        }
        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
            $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getRootFilePath());
        }
        if ($stmt_var_type->isNullable() && !$stmt_var_type->ignore_nullable_issues) {
            // we can only be sure that the variable is possibly null if we know the var_id
            if (!$context->inside_isset && $stmt->name instanceof PhpParser\Node\Identifier && !MethodCallAnalyzer::hasNullsafe($stmt->var)) {
                IssueBuffer::maybeAdd(new PossiblyNullPropertyFetch(rtrim('Cannot get property on possibly null variable ' . $stmt_var_id) . ' of type ' . $stmt_var_type, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } else {
                $statements_analyzer->node_data->setType($stmt, Type::getNull());
            }
        }
        if (!$prop_name) {
            if ($stmt_var_type->hasObjectType() && !$context->ignore_variable_property) {
                foreach ($stmt_var_type->getAtomicTypes() as $type) {
                    if ($type instanceof TNamedObject) {
                        $codebase->analyzer->addMixedMemberName(strtolower($type->value) . '::$', $context->calling_method_id ?: $statements_analyzer->getFileName());
                    }
                }
            }
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_var_type->getId());
            }
            return \true;
        }
        $invalid_fetch_types = [];
        $has_valid_fetch_type = \false;
        $var_atomic_types = $stmt_var_type->getAtomicTypes();
        while ($lhs_type_part = array_shift($var_atomic_types)) {
            if ($lhs_type_part instanceof TTemplateParam) {
                $var_atomic_types = array_merge($var_atomic_types, $lhs_type_part->as->getAtomicTypes());
                continue;
            }
            \Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer::analyze($statements_analyzer, $stmt, $context, $in_assignment, $var_id, $stmt_var_id, $stmt_var_type, $lhs_type_part, $prop_name, $has_valid_fetch_type, $invalid_fetch_types, $is_static_access);
        }
        $stmt_type = $statements_analyzer->node_data->getType($stmt);
        if ($stmt_var_type->isNullable() && !$context->inside_isset && $stmt_type) {
            $stmt_type = $stmt_type->getBuilder()->addType(new TNull());
            if ($stmt_var_type->ignore_nullable_issues) {
                $stmt_type->ignore_nullable_issues = \true;
            }
            $stmt_type = $stmt_type->freeze();
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations && ($stmt_type = $statements_analyzer->node_data->getType($stmt))) {
            $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_type->getId());
        }
        if ($invalid_fetch_types) {
            $lhs_type_part = $invalid_fetch_types[0];
            if ($has_valid_fetch_type) {
                IssueBuffer::maybeAdd(new PossiblyInvalidPropertyFetch('Cannot fetch property on possible non-object ' . $stmt_var_id . ' of type ' . $lhs_type_part, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new InvalidPropertyFetch('Cannot fetch property on non-object ' . $stmt_var_id . ' of type ' . $lhs_type_part, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
        }
        if ($var_id) {
            $context->vars_in_scope[$var_id] = $statements_analyzer->node_data->getType($stmt) ?? Type::getMixed();
        }
        return \true;
    }
    private static function handleScopedProperty(Context $context, string $var_id, StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\PropertyFetch $stmt, Codebase $codebase, ?string $stmt_var_id, bool $in_assignment) : void
    {
        $stmt_type = $context->vars_in_scope[$var_id];
        // we don't need to check anything
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
            $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
        }
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_type->getId());
        }
        if ($stmt_var_id === '$this' && !$stmt_type->initialized && $context->collect_initializations && ($stmt_var_type = $statements_analyzer->node_data->getType($stmt->var)) && $stmt_var_type->hasObjectType() && $stmt->name instanceof PhpParser\Node\Identifier) {
            $source = $statements_analyzer->getSource();
            $property_id = null;
            foreach ($stmt_var_type->getAtomicTypes() as $lhs_type_part) {
                if ($lhs_type_part instanceof TNamedObject) {
                    if (!$codebase->classExists($lhs_type_part->value)) {
                        continue;
                    }
                    $property_id = $lhs_type_part->value . '::$' . $stmt->name->name;
                }
            }
            if ($property_id && $source instanceof FunctionLikeAnalyzer && $source->getMethodName() === '__construct' && !$context->inside_unset) {
                if ($context->inside_isset || $context->inside_assignment && isset($context->vars_in_scope[$var_id]) && $context->vars_in_scope[$var_id]->isNullable()) {
                    $stmt_type = $stmt_type->setProperties(['initialized' => \true]);
                    $statements_analyzer->node_data->setType($stmt, $stmt_type);
                    $context->vars_in_scope[$var_id] = $stmt_type;
                } else {
                    IssueBuffer::maybeAdd(new UninitializedProperty('Cannot use uninitialized property ' . $var_id, new CodeLocation($statements_analyzer->getSource(), $stmt), $var_id), $statements_analyzer->getSuppressedIssues());
                    $stmt_type = $stmt_type->getBuilder()->addType(new TNull())->freeze();
                    $context->vars_in_scope[$var_id] = $stmt_type;
                    $statements_analyzer->node_data->setType($stmt, $stmt_type);
                }
            }
        }
        if (($stmt_var_type = $statements_analyzer->node_data->getType($stmt->var)) && $stmt_var_type->hasObjectType() && $stmt->name instanceof PhpParser\Node\Identifier) {
            // log the appearance
            foreach ($stmt_var_type->getAtomicTypes() as $lhs_type_part) {
                if ($lhs_type_part instanceof TNamedObject) {
                    if (!$codebase->classExists($lhs_type_part->value)) {
                        continue;
                    }
                    $property_id = $lhs_type_part->value . '::$' . $stmt->name->name;
                    $class_storage = $codebase->classlike_storage_provider->get($lhs_type_part->value);
                    \Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer::processTaints($statements_analyzer, $stmt, $stmt_type, $property_id, $class_storage, $in_assignment);
                    $context->vars_in_scope[$var_id] = $stmt_type;
                    $statements_analyzer->node_data->setType($stmt, $stmt_type);
                    $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($property_id, \true, $statements_analyzer);
                    if ($declaring_property_class) {
                        \Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer::checkPropertyDeprecation($stmt->name->name, $declaring_property_class, $stmt, $statements_analyzer);
                    }
                    $codebase->properties->propertyExists($property_id, \true, $statements_analyzer, $context, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null);
                    if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                        $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $property_id);
                    }
                    if (!$context->collect_mutations && !$context->collect_initializations && !($class_storage->external_mutation_free && $stmt_type->allow_mutations)) {
                        if ($context->pure) {
                            IssueBuffer::maybeAdd(new ImpurePropertyFetch('Cannot access a property on a mutable object from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                        } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                            $statements_analyzer->getSource()->inferred_impure = \true;
                        }
                    }
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Fetch;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Type\Comparator\AtomicTypeComparator;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\EmptyArrayAccess;
use Psalm\Issue\InvalidArrayAccess;
use Psalm\Issue\InvalidArrayAssignment;
use Psalm\Issue\InvalidArrayOffset;
use Psalm\Issue\MixedArrayAccess;
use Psalm\Issue\MixedArrayAssignment;
use Psalm\Issue\MixedArrayOffset;
use Psalm\Issue\MixedArrayTypeCoercion;
use Psalm\Issue\MixedStringOffsetAssignment;
use Psalm\Issue\NullArrayAccess;
use Psalm\Issue\NullArrayOffset;
use Psalm\Issue\PossiblyInvalidArrayAccess;
use Psalm\Issue\PossiblyInvalidArrayAssignment;
use Psalm\Issue\PossiblyInvalidArrayOffset;
use Psalm\Issue\PossiblyNullArrayAccess;
use Psalm\Issue\PossiblyNullArrayAssignment;
use Psalm\Issue\PossiblyNullArrayOffset;
use Psalm\Issue\PossiblyUndefinedArrayOffset;
use Psalm\Issue\PossiblyUndefinedIntArrayOffset;
use Psalm\Issue\PossiblyUndefinedStringArrayOffset;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualConstFetch;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualIdentifier;
use Psalm\Node\VirtualName;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TSingleLetter;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateIndexedAccess;
use Psalm\Type\Atomic\TTemplateKeyOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\MutableUnion;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_keys;
use function array_map;
use function array_pop;
use function array_values;
use function count;
use function implode;
use function in_array;
use function is_int;
use function is_numeric;
use function preg_match;
use function strlen;
use function strtolower;
/**
 * @internal
 */
class ArrayFetchAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ArrayDimFetch $stmt, Context $context) : bool
    {
        $extended_var_id = ExpressionIdentifier::getExtendedVarId($stmt->var, $statements_analyzer->getFQCLN(), $statements_analyzer);
        if ($stmt->dim) {
            $was_inside_general_use = $context->inside_general_use;
            $context->inside_general_use = \true;
            $was_inside_unset = $context->inside_unset;
            $context->inside_unset = \false;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->dim, $context) === \false) {
                $context->inside_unset = $was_inside_unset;
                $context->inside_general_use = $was_inside_general_use;
                return \false;
            }
            $context->inside_unset = $was_inside_unset;
            $context->inside_general_use = $was_inside_general_use;
        }
        $keyed_array_var_id = ExpressionIdentifier::getExtendedVarId($stmt, $statements_analyzer->getFQCLN(), $statements_analyzer);
        $dim_var_id = null;
        $new_offset_type = null;
        if ($stmt->dim) {
            $used_key_type = $statements_analyzer->node_data->getType($stmt->dim) ?? Type::getMixed();
            $dim_var_id = ExpressionIdentifier::getExtendedVarId($stmt->dim, $statements_analyzer->getFQCLN(), $statements_analyzer);
        } else {
            $used_key_type = Type::getInt();
        }
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->var, $context) === \false) {
            return \false;
        }
        $stmt_var_type = $statements_analyzer->node_data->getType($stmt->var);
        $codebase = $statements_analyzer->getCodebase();
        if ($keyed_array_var_id && $context->hasVariable($keyed_array_var_id) && !$context->vars_in_scope[$keyed_array_var_id]->possibly_undefined && $stmt_var_type && !$stmt_var_type->hasClassStringMap()) {
            $stmt_type = $context->vars_in_scope[$keyed_array_var_id];
            self::taintArrayFetch($statements_analyzer, $stmt->var, $keyed_array_var_id, $stmt_type, $used_key_type, $context);
            if ($stmt->dim && $statements_analyzer->node_data->getType($stmt->dim)) {
                $statements_analyzer->node_data->setType($stmt->dim, $used_key_type);
            }
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            return \true;
        }
        $can_store_result = \false;
        if ($stmt_var_type) {
            if ($stmt_var_type->isNull()) {
                if (!$context->inside_isset) {
                    IssueBuffer::maybeAdd(new NullArrayAccess('Cannot access array value on null variable ' . $extended_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                $stmt_type = $statements_analyzer->node_data->getType($stmt);
                $statements_analyzer->node_data->setType($stmt, Type::combineUnionTypes($stmt_type, Type::getNull()));
                return \true;
            }
            $stmt_type = self::getArrayAccessTypeGivenOffset($statements_analyzer, $stmt, $stmt_var_type, $used_key_type, \false, $extended_var_id, $context, null);
            if ($stmt->dim && $stmt_var_type->hasArray()) {
                $array_type = $stmt_var_type->getArray();
                if ($array_type instanceof TClassStringMap) {
                    $array_value_type = Type::getMixed();
                } elseif ($array_type instanceof TArray) {
                    $array_value_type = $array_type->type_params[1];
                } else {
                    $array_value_type = $array_type->getGenericValueType();
                }
                if ($context->inside_assignment || !$array_value_type->isMixed()) {
                    $can_store_result = \true;
                }
            }
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            if ($context->inside_isset && $stmt->dim && ($stmt_dim_type = $statements_analyzer->node_data->getType($stmt->dim)) && $stmt_var_type->hasArray() && ($stmt->var instanceof PhpParser\Node\Expr\ClassConstFetch || $stmt->var instanceof PhpParser\Node\Expr\ConstFetch)) {
                /**
                 * @var TArray|TKeyedArray
                 */
                $array_type = $stmt_var_type->getArray();
                if ($array_type instanceof TArray) {
                    $const_array_key_type = $array_type->type_params[0];
                } else {
                    $const_array_key_type = $array_type->getGenericKeyType();
                }
                if ($dim_var_id && !$const_array_key_type->hasMixed() && !$stmt_dim_type->hasMixed()) {
                    $new_offset_type = $stmt_dim_type->getBuilder();
                    $const_array_key_atomic_types = $const_array_key_type->getAtomicTypes();
                    foreach ($new_offset_type->getAtomicTypes() as $offset_key => $offset_atomic_type) {
                        if ($offset_atomic_type instanceof TString || $offset_atomic_type instanceof TInt) {
                            if (!isset($const_array_key_atomic_types[$offset_key]) && !UnionTypeComparator::isContainedBy($codebase, new Union([$offset_atomic_type]), $const_array_key_type)) {
                                $new_offset_type->removeType($offset_key);
                            }
                        } elseif (!UnionTypeComparator::isContainedBy($codebase, $const_array_key_type, new Union([$offset_atomic_type]))) {
                            $new_offset_type->removeType($offset_key);
                        }
                    }
                    $new_offset_type = $new_offset_type->freeze();
                }
            }
        }
        if ($keyed_array_var_id && $context->hasVariable($keyed_array_var_id) && (!($stmt_type = $statements_analyzer->node_data->getType($stmt)) || $stmt_type->isVanillaMixed())) {
            $statements_analyzer->node_data->setType($stmt, $context->vars_in_scope[$keyed_array_var_id]);
        }
        if (!($stmt_type = $statements_analyzer->node_data->getType($stmt))) {
            $stmt_type = Type::getMixed();
        } else {
            if ($stmt_type->possibly_undefined && !$context->inside_isset && !$context->inside_unset && ($stmt_var_type && !$stmt_var_type->hasMixed())) {
                IssueBuffer::maybeAdd(new PossiblyUndefinedArrayOffset('Possibly undefined array key ' . $keyed_array_var_id . ' on ' . $stmt_var_type->getId(), new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
            $stmt_type = $stmt_type->setPossiblyUndefined(\false);
        }
        if ($context->inside_isset && $dim_var_id && $new_offset_type && !$new_offset_type->isUnionEmpty()) {
            $context->vars_in_scope[$dim_var_id] = $new_offset_type;
        }
        self::taintArrayFetch($statements_analyzer, $stmt->var, $keyed_array_var_id, $stmt_type, $used_key_type, $context);
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
        if ($stmt->dim && $statements_analyzer->node_data->getType($stmt->dim)) {
            $statements_analyzer->node_data->setType($stmt->dim, $used_key_type);
        }
        if ($keyed_array_var_id && !$context->inside_isset && $can_store_result) {
            $context->vars_in_scope[$keyed_array_var_id] = $stmt_type;
            $context->vars_possibly_in_scope[$keyed_array_var_id] = \true;
            // reference the variable too
            $context->hasVariable($keyed_array_var_id);
        }
        return \true;
    }
    /**
     * Used to create a path between a variable $foo and $foo["a"]
     */
    public static function taintArrayFetch(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $var, ?string $keyed_array_var_id, Union &$stmt_type, Union &$offset_type, ?Context $context = null) : void
    {
        if ($statements_analyzer->data_flow_graph && ($stmt_var_type = $statements_analyzer->node_data->getType($var)) && $stmt_var_type->parent_nodes) {
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && in_array('TaintedInput', $statements_analyzer->getSuppressedIssues())) {
                $statements_analyzer->node_data->setType($var, $stmt_var_type->setParentNodes([]));
                return;
            }
            $added_taints = [];
            $removed_taints = [];
            if ($context) {
                $codebase = $statements_analyzer->getCodebase();
                $event = new AddRemoveTaintsEvent($var, $context, $statements_analyzer, $codebase);
                $added_taints = $codebase->config->eventDispatcher->dispatchAddTaints($event);
                $removed_taints = $codebase->config->eventDispatcher->dispatchRemoveTaints($event);
            }
            $var_location = new CodeLocation($statements_analyzer->getSource(), $var);
            $new_parent_node = DataFlowNode::getForAssignment($keyed_array_var_id ?: 'arrayvalue-fetch', $var_location);
            $array_key_node = null;
            $statements_analyzer->data_flow_graph->addNode($new_parent_node);
            $dim_value = $offset_type->isSingleStringLiteral() ? $offset_type->getSingleStringLiteral()->value : ($offset_type->isSingleIntLiteral() ? $offset_type->getSingleIntLiteral()->value : null);
            if ($keyed_array_var_id === null && $dim_value === null) {
                $array_key_node = DataFlowNode::getForAssignment('arraykey-fetch', $var_location);
                $statements_analyzer->data_flow_graph->addNode($array_key_node);
            }
            foreach ($stmt_var_type->parent_nodes as $parent_node) {
                $statements_analyzer->data_flow_graph->addPath($parent_node, $new_parent_node, 'arrayvalue-fetch' . ($dim_value !== null ? '-\'' . $dim_value . '\'' : ''), $added_taints, $removed_taints);
                if ($stmt_type->by_ref) {
                    $statements_analyzer->data_flow_graph->addPath($new_parent_node, $parent_node, 'arrayvalue-assignment' . ($dim_value !== null ? '-\'' . $dim_value . '\'' : ''), $added_taints, $removed_taints);
                }
                if ($array_key_node) {
                    $statements_analyzer->data_flow_graph->addPath($parent_node, $array_key_node, 'arraykey-fetch', $added_taints, $removed_taints);
                }
            }
            $stmt_type = $stmt_type->setParentNodes([$new_parent_node->id => $new_parent_node]);
            if ($array_key_node) {
                $offset_type = $offset_type->setParentNodes([$array_key_node->id => $array_key_node]);
            }
        }
    }
    /**
     * @psalm-suppress ComplexMethod to be refactored.
     * Good type/bad type behaviour could be mutualised with ArrayAnalyzer
     */
    public static function getArrayAccessTypeGivenOffset(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ArrayDimFetch $stmt, Union &$array_type, Union &$offset_type_original, bool $in_assignment, ?string $extended_var_id, Context $context, PhpParser\Node\Expr $assign_value = null, Union $replacement_type = null) : Union
    {
        $offset_type = $offset_type_original->getBuilder();
        $codebase = $statements_analyzer->getCodebase();
        $has_array_access = \false;
        $non_array_types = [];
        $has_valid_expected_offset = \false;
        $expected_offset_types = [];
        $key_values = [];
        if ($stmt->dim instanceof PhpParser\Node\Scalar\String_) {
            $key_values[] = new TLiteralString($stmt->dim->value);
        } elseif ($stmt->dim instanceof PhpParser\Node\Scalar\LNumber) {
            $key_values[] = new TLiteralInt($stmt->dim->value);
        } elseif ($stmt->dim && ($stmt_dim_type = $statements_analyzer->node_data->getType($stmt->dim))) {
            $string_literals = $stmt_dim_type->getLiteralStrings();
            $int_literals = $stmt_dim_type->getLiteralInts();
            $all_atomic_types = $stmt_dim_type->getAtomicTypes();
            if (count($string_literals) + count($int_literals) === count($all_atomic_types)) {
                foreach ($string_literals as $string_literal) {
                    $key_values[] = $string_literal;
                }
                foreach ($int_literals as $int_literal) {
                    $key_values[] = $int_literal;
                }
            }
        }
        $array_access_type = null;
        if ($offset_type->isNull()) {
            IssueBuffer::maybeAdd(new NullArrayOffset('Cannot access value on variable ' . $extended_var_id . ' using null offset', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            if ($in_assignment) {
                $offset_type->removeType('null');
                $offset_type->addType(new TLiteralString(''));
            }
        }
        if ($offset_type->isNullable() && !$context->inside_isset) {
            if (!$offset_type->ignore_nullable_issues) {
                IssueBuffer::maybeAdd(new PossiblyNullArrayOffset('Cannot access value on variable ' . $extended_var_id . ' using possibly null offset ' . $offset_type, new CodeLocation($statements_analyzer->getSource(), $stmt->var)), $statements_analyzer->getSuppressedIssues());
            }
            if ($in_assignment) {
                $offset_type->removeType('null');
                if (!$offset_type->ignore_nullable_issues) {
                    $offset_type->addType(new TLiteralString(''));
                }
            }
        }
        if ($array_type->isArray()) {
            $has_valid_absolute_offset = self::checkArrayOffsetType($offset_type, $offset_type->getAtomicTypes(), $codebase);
            if ($has_valid_absolute_offset === \false) {
                //we didn't find a single type that could be valid
                $expected_offset_types[] = 'array-key';
            }
        } else {
            //on not-arrays, the type is considered valid
            $has_valid_absolute_offset = \true;
        }
        $types = $array_type->getAtomicTypes();
        $changed = \false;
        foreach ($types as $type_string => $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            $original_type_real = $type;
            $original_type = $type;
            if ($type instanceof TMixed || $type instanceof TTemplateParam || $type instanceof TNever) {
                if (!$type instanceof TTemplateParam || $type->as->isMixed() || !$type->as->isSingle()) {
                    $array_access_type = self::handleMixedArrayAccess($context, $statements_analyzer, $codebase, $in_assignment, $extended_var_id, $stmt, $array_access_type, $type);
                    $has_valid_expected_offset = \true;
                    continue;
                }
                $type = $type->as->getSingleAtomic();
                $original_type = $type;
            }
            if ($type instanceof TNull) {
                if ($array_type->ignore_nullable_issues) {
                    continue;
                }
                if ($in_assignment) {
                    if ($replacement_type) {
                        $array_access_type = Type::combineUnionTypes($array_access_type, $replacement_type);
                    } else {
                        IssueBuffer::maybeAdd(new PossiblyNullArrayAssignment('Cannot access array value on possibly null variable ' . $extended_var_id . ' of type ' . $array_type, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                        $array_access_type = new Union([new TNever()]);
                    }
                } else {
                    if (!$context->inside_isset && !MethodCallAnalyzer::hasNullsafe($stmt->var)) {
                        IssueBuffer::maybeAdd(new PossiblyNullArrayAccess('Cannot access array value on possibly null variable ' . $extended_var_id . ' of type ' . $array_type, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    }
                    $array_access_type = Type::combineUnionTypes($array_access_type, Type::getNull());
                }
                continue;
            }
            if ($type instanceof TArray || $type instanceof TKeyedArray || $type instanceof TClassStringMap) {
                self::handleArrayAccessOnArray($in_assignment, $type, $key_values, $array_type->hasMixed(), $stmt, $replacement_type, $offset_type, $original_type_real, $codebase, $extended_var_id, $context, $statements_analyzer, $expected_offset_types, $array_access_type, $has_array_access, $has_valid_expected_offset);
                if ($type !== $original_type) {
                    $changed = \true;
                    unset($types[$type_string]);
                    $types[$type->getKey()] = $type;
                }
                continue;
            }
            if ($type instanceof TString) {
                self::handleArrayAccessOnString($statements_analyzer, $codebase, $stmt, $in_assignment, $context, $replacement_type, $type, $offset_type, $expected_offset_types, $array_access_type, $has_valid_expected_offset);
                continue;
            }
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
            }
            if ($type instanceof TFalse && $array_type->ignore_falsable_issues) {
                continue;
            }
            if ($type instanceof TNamedObject) {
                self::handleArrayAccessOnNamedObject($statements_analyzer, $stmt, $type, $context, $in_assignment, $assign_value, $array_access_type, $has_array_access);
            } elseif (!$array_type->hasMixed()) {
                $non_array_types[] = (string) $type;
            }
        }
        if ($changed) {
            $array_type = $array_type->getBuilder()->setTypes($types)->freeze();
        }
        if ($non_array_types) {
            if ($has_array_access) {
                if ($in_assignment) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidArrayAssignment('Cannot access array value on non-array variable ' . $extended_var_id . ' of type ' . $non_array_types[0], new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } elseif (!$context->inside_isset) {
                    IssueBuffer::maybeAdd(new PossiblyInvalidArrayAccess('Cannot access array value on non-array variable ' . $extended_var_id . ' of type ' . $non_array_types[0], new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            } else {
                if ($in_assignment) {
                    IssueBuffer::maybeAdd(new InvalidArrayAssignment('Cannot access array value on non-array variable ' . $extended_var_id . ' of type ' . $non_array_types[0], new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new InvalidArrayAccess('Cannot access array value on non-array variable ' . $extended_var_id . ' of type ' . $non_array_types[0], new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
                $array_access_type = Type::getMixed();
            }
        }
        if ($offset_type->hasMixed()) {
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
            }
            IssueBuffer::maybeAdd(new MixedArrayOffset('Cannot access value on variable ' . $extended_var_id . ' using mixed offset', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        } else {
            if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
            }
            if ($expected_offset_types) {
                $invalid_offset_type = $expected_offset_types[0];
                $used_offset = 'using a ' . $offset_type->getId() . ' offset';
                if ($key_values) {
                    $used_offset = "using offset value of '" . implode('|', array_map(static fn(Atomic $atomic_type) => $atomic_type->value, $key_values)) . "'";
                }
                if ($has_valid_expected_offset && $has_valid_absolute_offset && $context->inside_isset) {
                    // do nothing
                } elseif ($has_valid_expected_offset && $has_valid_absolute_offset) {
                    if (!$context->inside_unset) {
                        IssueBuffer::maybeAdd(new PossiblyInvalidArrayOffset('Cannot access value on variable ' . $extended_var_id . ' ' . $used_offset . ', expecting ' . $invalid_offset_type, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    }
                } else {
                    $good_types = [];
                    $bad_types = [];
                    foreach ($offset_type->getAtomicTypes() as $atomic_key_type) {
                        if (!$atomic_key_type instanceof TString && !$atomic_key_type instanceof TInt && !$atomic_key_type instanceof TArrayKey && !$atomic_key_type instanceof TMixed && !$atomic_key_type instanceof TTemplateParam && !($atomic_key_type instanceof TObjectWithProperties && isset($atomic_key_type->methods['__tostring']))) {
                            $bad_types[] = $atomic_key_type;
                            if ($atomic_key_type instanceof TFalse) {
                                $good_types[] = new TLiteralInt(0);
                            } elseif ($atomic_key_type instanceof TTrue) {
                                $good_types[] = new TLiteralInt(1);
                            } elseif ($atomic_key_type instanceof TBool) {
                                $good_types[] = new TLiteralInt(0);
                                $good_types[] = new TLiteralInt(1);
                            } elseif ($atomic_key_type instanceof TLiteralFloat) {
                                $good_types[] = new TLiteralInt((int) $atomic_key_type->value);
                            } elseif ($atomic_key_type instanceof TFloat) {
                                $good_types[] = new TInt();
                            } else {
                                $good_types[] = new TArrayKey();
                            }
                        }
                    }
                    if ($bad_types && $good_types) {
                        $offset_type->substitute(TypeCombiner::combine($bad_types, $codebase), TypeCombiner::combine($good_types, $codebase));
                    }
                    IssueBuffer::maybeAdd(new InvalidArrayOffset('Cannot access value on variable ' . $extended_var_id . ' ' . $used_offset . ', expecting ' . $invalid_offset_type, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
        $offset_type_original = $offset_type->freeze();
        if ($array_access_type === null) {
            // shouldn’t happen, but don’t crash
            return Type::getMixed();
        }
        if ($array_type->by_ref) {
            return $array_access_type->setByRef(\true);
        }
        return $array_access_type;
    }
    private static function checkLiteralIntArrayOffset(MutableUnion $offset_type, Union $expected_offset_type, ?string $extended_var_id, PhpParser\Node\Expr\ArrayDimFetch $stmt, Context $context, StatementsAnalyzer $statements_analyzer) : void
    {
        if ($context->inside_isset || $context->inside_unset) {
            return;
        }
        if ($offset_type->hasLiteralInt()) {
            $found_match = \false;
            foreach ($offset_type->getAtomicTypes() as $offset_type_part) {
                if ($extended_var_id && $offset_type_part instanceof TLiteralInt && isset($context->vars_in_scope[$extended_var_id . '[' . $offset_type_part->value . ']']) && !$context->vars_in_scope[$extended_var_id . '[' . $offset_type_part->value . ']']->possibly_undefined) {
                    $found_match = \true;
                    break;
                }
            }
            if (!$found_match) {
                IssueBuffer::maybeAdd(new PossiblyUndefinedIntArrayOffset('Possibly undefined array offset \'' . $offset_type->getId() . '\' ' . 'is risky given expected type \'' . $expected_offset_type->getId() . '\'.' . ' Consider using isset beforehand.', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
        }
    }
    private static function checkLiteralStringArrayOffset(MutableUnion $offset_type, Union $expected_offset_type, ?string $extended_var_id, PhpParser\Node\Expr\ArrayDimFetch $stmt, Context $context, StatementsAnalyzer $statements_analyzer) : void
    {
        if ($context->inside_isset || $context->inside_unset) {
            return;
        }
        if ($offset_type->hasLiteralString() && !$expected_offset_type->hasLiteralClassString()) {
            $found_match = \false;
            foreach ($offset_type->getAtomicTypes() as $offset_type_part) {
                if ($extended_var_id && $offset_type_part instanceof TLiteralString && isset($context->vars_in_scope[$extended_var_id . '[\'' . $offset_type_part->value . '\']']) && !$context->vars_in_scope[$extended_var_id . '[\'' . $offset_type_part->value . '\']']->possibly_undefined) {
                    $found_match = \true;
                    break;
                }
            }
            if (!$found_match) {
                IssueBuffer::maybeAdd(new PossiblyUndefinedStringArrayOffset('Possibly undefined array offset \'' . $offset_type->getId() . '\' ' . 'is risky given expected type \'' . $expected_offset_type->getId() . '\'.' . ' Consider using isset beforehand.', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
        }
    }
    public static function replaceOffsetTypeWithInts(Union $offset_type) : Union
    {
        $offset_type = $offset_type->getBuilder();
        $offset_types = $offset_type->getAtomicTypes();
        foreach ($offset_types as $key => $offset_type_part) {
            if ($offset_type_part instanceof TLiteralString) {
                if (preg_match('/^(0|[1-9][0-9]*)$/', $offset_type_part->value)) {
                    $offset_type->addType(new TLiteralInt((int) $offset_type_part->value));
                    $offset_type->removeType($key);
                }
            } elseif ($offset_type_part instanceof TBool) {
                if ($offset_type_part instanceof TFalse) {
                    if (!$offset_type->ignore_falsable_issues) {
                        $offset_type->addType(new TLiteralInt(0));
                        $offset_type->removeType($key);
                    }
                } elseif ($offset_type_part instanceof TTrue) {
                    $offset_type->addType(new TLiteralInt(1));
                    $offset_type->removeType($key);
                } else {
                    $offset_type->addType(new TLiteralInt(0));
                    $offset_type->addType(new TLiteralInt(1));
                    $offset_type->removeType($key);
                }
            }
        }
        return $offset_type->freeze();
    }
    /**
     * @param  TMixed|TTemplateParam|TNever $type
     */
    public static function handleMixedArrayAccess(Context $context, StatementsAnalyzer $statements_analyzer, Codebase $codebase, bool $in_assignment, ?string $extended_var_id, PhpParser\Node\Expr\ArrayDimFetch $stmt, ?Union $array_access_type, Atomic $type) : Union
    {
        if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
            $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
        }
        if (!$context->inside_isset) {
            if ($in_assignment) {
                IssueBuffer::maybeAdd(new MixedArrayAssignment('Cannot access array value on mixed variable ' . $extended_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new MixedArrayAccess('Cannot access array value on mixed variable ' . $extended_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            }
        }
        if (($data_flow_graph = $statements_analyzer->data_flow_graph) && $data_flow_graph instanceof VariableUseGraph && ($stmt_var_type = $statements_analyzer->node_data->getType($stmt->var))) {
            if ($stmt_var_type->parent_nodes) {
                $var_location = new CodeLocation($statements_analyzer->getSource(), $stmt->var);
                $new_parent_node = DataFlowNode::getForAssignment('mixed-var-array-access', $var_location);
                $data_flow_graph->addNode($new_parent_node);
                foreach ($stmt_var_type->parent_nodes as $parent_node) {
                    $data_flow_graph->addPath($parent_node, $new_parent_node, '=');
                    $data_flow_graph->addPath($parent_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                }
                $statements_analyzer->node_data->setType($stmt->var, $stmt_var_type->setParentNodes([$new_parent_node->id => $new_parent_node]));
            }
        }
        return Type::combineUnionTypes($array_access_type, Type::getMixed($type instanceof TNever));
    }
    /**
     * @param list<string> $expected_offset_types
     * @param TArray|TKeyedArray|TClassStringMap $type
     * @param-out TArray|TKeyedArray|TClassStringMap $type
     * @param list<TLiteralInt|TLiteralString> $key_values
     * @psalm-suppress ConflictingReferenceConstraint Ignore
     */
    private static function handleArrayAccessOnArray(bool $in_assignment, Atomic &$type, array &$key_values, bool $hasMixed, PhpParser\Node\Expr\ArrayDimFetch $stmt, ?Union $replacement_type, MutableUnion $offset_type, Atomic $original_type, Codebase $codebase, ?string $extended_var_id, Context $context, StatementsAnalyzer $statements_analyzer, array &$expected_offset_types, ?Union &$array_access_type, bool &$has_array_access, bool &$has_valid_offset) : void
    {
        $has_array_access = \true;
        if ($in_assignment) {
            if ($type instanceof TArray) {
                $from_empty_array = $type->isEmptyArray();
                if (count($key_values) === 1) {
                    $single_atomic = $key_values[0];
                    $from_mixed_array = $type->type_params[1]->isMixed();
                    // ok, type becomes an TKeyedArray
                    $type = new TKeyedArray([$single_atomic->value => $from_mixed_array ? Type::getMixed() : Type::getNever()], $single_atomic instanceof TLiteralClassString ? [$single_atomic->value => \true] : null, $from_empty_array ? null : $type->type_params);
                } elseif (!$stmt->dim && $from_empty_array && $replacement_type) {
                    $type = new TKeyedArray([$replacement_type], null, null, \true);
                    return;
                }
            } elseif ($type instanceof TKeyedArray && $type->fallback_params !== null && $type->fallback_params[1]->isMixed() && count($key_values) === 1) {
                $properties = $type->properties;
                $properties[$key_values[0]->value] = Type::getMixed();
                $type = $type->setProperties($properties);
            }
        }
        $offset_type = self::replaceOffsetTypeWithInts($offset_type->freeze())->getBuilder();
        if ($type instanceof TKeyedArray && $type->is_list && ($in_assignment && $stmt->dim || $original_type instanceof TTemplateParam || !$offset_type->isInt())) {
            $temp = $type->getGenericArrayType();
            self::handleArrayAccessOnTArray($statements_analyzer, $codebase, $context, $stmt, $hasMixed, $extended_var_id, $temp, $offset_type, $in_assignment, $expected_offset_types, $array_access_type, $original_type, $has_valid_offset);
        } elseif ($type instanceof TArray) {
            self::handleArrayAccessOnTArray($statements_analyzer, $codebase, $context, $stmt, $hasMixed, $extended_var_id, $type, $offset_type, $in_assignment, $expected_offset_types, $array_access_type, $original_type, $has_valid_offset);
        } elseif ($type instanceof TClassStringMap) {
            self::handleArrayAccessOnClassStringMap($codebase, $type, $offset_type, $replacement_type, $array_access_type);
        } else {
            self::handleArrayAccessOnKeyedArray($statements_analyzer, $codebase, $key_values, $replacement_type, $array_access_type, $in_assignment, $stmt, $offset_type, $extended_var_id, $context, $type, $hasMixed, $expected_offset_types, $has_valid_offset);
        }
        if ($context->inside_isset) {
            $offset_type->ignore_isset = \true;
        }
    }
    /**
     * @param list<string> $expected_offset_types
     * @param-out TArray $type
     */
    private static function handleArrayAccessOnTArray(StatementsAnalyzer $statements_analyzer, Codebase $codebase, Context $context, PhpParser\Node\Expr\ArrayDimFetch $stmt, bool $hasMixed, ?string $extended_var_id, TArray &$type, MutableUnion $offset_type, bool $in_assignment, array &$expected_offset_types, ?Union &$array_access_type, Atomic $original_type, bool &$has_valid_offset) : void
    {
        // if we're assigning to an empty array with a key offset, refashion that array
        if ($in_assignment) {
            if ($type->isEmptyArray()) {
                $type = $type->setTypeParams([$offset_type->isMixed() ? Type::getArrayKey() : $offset_type->freeze(), $type->type_params[1]]);
            }
        } elseif (!$type->isEmptyArray()) {
            $expected_offset_type = $type->type_params[0]->hasMixed() ? new Union([new TArrayKey()]) : $type->type_params[0];
            $templated_offset_type = null;
            foreach ($offset_type->getAtomicTypes() as $offset_atomic_type) {
                if ($offset_atomic_type instanceof TTemplateParam) {
                    $templated_offset_type = $offset_atomic_type;
                }
            }
            $union_comparison_results = new TypeComparisonResult();
            if ($original_type instanceof TTemplateParam && $templated_offset_type) {
                foreach ($templated_offset_type->as->getAtomicTypes() as $offset_as) {
                    if ($offset_as instanceof TTemplateKeyOf && $offset_as->param_name === $original_type->param_name && $offset_as->defining_class === $original_type->defining_class) {
                        $type = $type->setTypeParams([$type->type_params[0], new Union([new TTemplateIndexedAccess($offset_as->param_name, $templated_offset_type->param_name, $offset_as->defining_class)])]);
                        $has_valid_offset = \true;
                    }
                }
            } else {
                $offset_type_contained_by_expected = UnionTypeComparator::isContainedBy($codebase, $offset_type->freeze(), $expected_offset_type, \true, $offset_type->ignore_falsable_issues, $union_comparison_results);
                if ($codebase->config->ensure_array_string_offsets_exist && $offset_type_contained_by_expected) {
                    //we already know we found a match, so if the array is non-empty and the key is a literal,
                    //then no need to check for PossiblyUndefinedStringArrayOffset
                    if (!$type instanceof TNonEmptyArray || !$type->type_params[0]->isSingleStringLiteral()) {
                        self::checkLiteralStringArrayOffset($offset_type, $expected_offset_type, $extended_var_id, $stmt, $context, $statements_analyzer);
                    }
                }
                if ($codebase->config->ensure_array_int_offsets_exist && $offset_type_contained_by_expected) {
                    self::checkLiteralIntArrayOffset($offset_type, $expected_offset_type, $extended_var_id, $stmt, $context, $statements_analyzer);
                }
                if (!$offset_type_contained_by_expected && !$union_comparison_results->type_coerced_from_scalar || $union_comparison_results->to_string_cast) {
                    if ($union_comparison_results->type_coerced_from_mixed && !$offset_type->isMixed()) {
                        IssueBuffer::maybeAdd(new MixedArrayTypeCoercion('Coercion from array offset type \'' . $offset_type->getId() . '\' ' . 'to the expected type \'' . $expected_offset_type->getId() . '\'', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                    } else {
                        $expected_offset_types[] = $expected_offset_type->getId();
                    }
                    if (UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $offset_type->freeze(), $expected_offset_type)) {
                        $has_valid_offset = \true;
                    }
                } else {
                    $has_valid_offset = \true;
                }
            }
        }
        if (!$stmt->dim) {
            if ($type instanceof TNonEmptyArray) {
                if ($type->count !== null) {
                    $type = $type->setCount($type->count + 1);
                }
            } else {
                $type = new TNonEmptyArray($type->type_params, null, null, 'non-empty-array', $type->from_docblock);
            }
        }
        $array_access_type = Type::combineUnionTypes($array_access_type, $type->type_params[1]);
        if ($array_access_type->isNever() && !$hasMixed && !$in_assignment && !$context->inside_isset) {
            IssueBuffer::maybeAdd(new EmptyArrayAccess('Cannot access value on empty array variable ' . $extended_var_id, new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            if (!IssueBuffer::isRecording()) {
                $array_access_type = Type::getMixed(\true);
            }
        }
    }
    private static function handleArrayAccessOnClassStringMap(Codebase $codebase, TClassStringMap &$type, MutableUnion $offset_type, ?Union $replacement_type, ?Union &$array_access_type) : void
    {
        $offset_type_parts = array_values($offset_type->getAtomicTypes());
        foreach ($offset_type_parts as $offset_type_part) {
            if ($offset_type_part instanceof TClassString) {
                if ($offset_type_part instanceof TTemplateParamClass) {
                    $template_result_get = new TemplateResult([], [$type->param_name => ['class-string-map' => new Union([new TTemplateParam($offset_type_part->param_name, $offset_type_part->as_type ? new Union([$offset_type_part->as_type]) : Type::getObject(), $offset_type_part->defining_class)])]]);
                    $template_result_set = new TemplateResult([], [$offset_type_part->param_name => [$offset_type_part->defining_class => new Union([new TTemplateParam($type->param_name, $type->as_type ? new Union([$type->as_type]) : Type::getObject(), 'class-string-map')])]]);
                } else {
                    $template_result_get = new TemplateResult([], [$type->param_name => ['class-string-map' => new Union([$offset_type_part->as_type ?: new TObject()])]]);
                    $template_result_set = new TemplateResult([], []);
                }
                $expected_value_param_get = TemplateInferredTypeReplacer::replace($type->value_param, $template_result_get, $codebase);
                if ($replacement_type) {
                    $replacement_type = TemplateInferredTypeReplacer::replace($replacement_type, $template_result_set, $codebase);
                    $type = new TClassStringMap($type->param_name, $type->as_type, Type::combineUnionTypes($replacement_type, $type->value_param, $codebase));
                }
                $array_access_type = Type::combineUnionTypes($array_access_type, $expected_value_param_get, $codebase);
            }
        }
    }
    /**
     * @param list<string> $expected_offset_types
     * @param list<TLiteralString|TLiteralInt> $key_values
     * @param-out TArray|TKeyedArray $type
     */
    private static function handleArrayAccessOnKeyedArray(StatementsAnalyzer $statements_analyzer, Codebase $codebase, array &$key_values, ?Union $replacement_type, ?Union &$array_access_type, bool $in_assignment, PhpParser\Node\Expr\ArrayDimFetch $stmt, MutableUnion $offset_type, ?string $extended_var_id, Context $context, TKeyedArray &$type, bool $hasMixed, array &$expected_offset_types, bool &$has_valid_offset) : void
    {
        $generic_key_type = $type->getGenericKeyType();
        if (!$stmt->dim && $type->fallback_params === null && $type->is_list) {
            $key_values[] = new TLiteralInt(count($type->properties));
        }
        if ($key_values) {
            $properties = $type->properties;
            foreach ($key_values as $key_value) {
                if ($type->is_list && (!is_numeric($key_value->value) || $key_value->value < 0)) {
                    $expected_offset_types[] = $type->getGenericKeyType();
                    $has_valid_offset = \false;
                } elseif (isset($properties[$key_value->value]) && !($key_value->value === 0 && AtomicTypeComparator::isLegacyTListLike($type)) || $replacement_type) {
                    $has_valid_offset = \true;
                    if ($replacement_type) {
                        $properties[$key_value->value] = Type::combineUnionTypes($properties[$key_value->value] ?? null, $replacement_type);
                        if (is_int($key_value->value) && !$stmt->dim && $type->is_list && $type->properties[$key_value->value - 1]->possibly_undefined) {
                            $first = \true;
                            for ($x = 0; $x < $key_value->value; $x++) {
                                if (!$properties[$x]->possibly_undefined) {
                                    continue;
                                }
                                $properties[$x] = Type::combineUnionTypes($properties[$x], $replacement_type);
                                if ($first) {
                                    $first = \false;
                                    $properties[$x] = $properties[$x]->setPossiblyUndefined(\false);
                                }
                            }
                            $properties[$key_value->value] = $properties[$key_value->value]->setPossiblyUndefined(\true);
                        }
                    }
                    $array_access_type = Type::combineUnionTypes($array_access_type, $properties[$key_value->value]);
                } elseif ($in_assignment) {
                    $properties[$key_value->value] = new Union([new TNever()]);
                    $array_access_type = Type::combineUnionTypes($array_access_type, $properties[$key_value->value]);
                } elseif ($type->fallback_params !== null) {
                    if ($codebase->config->ensure_array_string_offsets_exist) {
                        self::checkLiteralStringArrayOffset($offset_type, $type->getGenericKeyType(), $extended_var_id, $stmt, $context, $statements_analyzer);
                    }
                    if ($codebase->config->ensure_array_int_offsets_exist) {
                        self::checkLiteralIntArrayOffset($offset_type, $type->getGenericKeyType(), $extended_var_id, $stmt, $context, $statements_analyzer);
                    }
                    $properties[$key_value->value] = $type->fallback_params[1];
                    $array_access_type = $type->fallback_params[1];
                } elseif ($hasMixed) {
                    $has_valid_offset = \true;
                    $array_access_type = Type::getMixed();
                } else {
                    $object_like_keys = array_keys($properties);
                    $last_key = array_pop($object_like_keys);
                    $key_string = '';
                    if ($object_like_keys) {
                        $formatted_keys = implode(', ', array_map(
                            /** @param int|string $key */
                            static fn($key): string => is_int($key) ? "{$key}" : '\'' . $key . '\'',
                            $object_like_keys
                        ));
                        $key_string = $formatted_keys . ' or ';
                    }
                    $key_string .= is_int($last_key) ? $last_key : '\'' . $last_key . '\'';
                    $expected_offset_types[] = $key_string;
                    $array_access_type = Type::getMixed();
                }
            }
            $type = $type->setProperties($properties);
        } else {
            $key_type = $generic_key_type->hasMixed() ? Type::getArrayKey() : $generic_key_type;
            $union_comparison_results = new TypeComparisonResult();
            $is_contained = UnionTypeComparator::isContainedBy($codebase, $offset_type->freeze(), $key_type, \true, $offset_type->ignore_falsable_issues, $union_comparison_results);
            if ($context->inside_isset && !$is_contained) {
                $is_contained = UnionTypeComparator::isContainedBy($codebase, $key_type, $offset_type->freeze(), \true, $offset_type->ignore_falsable_issues);
            }
            if (($is_contained || $union_comparison_results->type_coerced_from_scalar || $union_comparison_results->type_coerced_from_mixed || $in_assignment) && !$union_comparison_results->to_string_cast) {
                if ($replacement_type) {
                    $generic_params = Type::combineUnionTypes($type->getGenericValueType(), $replacement_type);
                    $new_key_type = Type::combineUnionTypes($generic_key_type, $offset_type->isMixed() ? Type::getArrayKey() : $offset_type->freeze());
                    if (!$stmt->dim) {
                        if ($type->is_list) {
                            $type = new TKeyedArray($type->properties, null, [$new_key_type, $generic_params], \true);
                        } else {
                            $type = new TNonEmptyArray([$new_key_type, $generic_params], null, $type->getMinCount() + 1);
                        }
                    } else {
                        $min_count = $type->getMinCount();
                        if ($min_count) {
                            $type = new TNonEmptyArray([$new_key_type, $generic_params], null, $min_count);
                        } else {
                            $type = new TArray([$new_key_type, $generic_params]);
                        }
                    }
                    $array_access_type = Type::combineUnionTypes($array_access_type, $generic_params);
                } else {
                    $array_access_type = Type::combineUnionTypes($array_access_type, $type->getGenericValueType());
                }
                $has_valid_offset = \true;
            } else {
                if (!$context->inside_isset || $type->fallback_params === null && !$union_comparison_results->type_coerced) {
                    $expected_offset_types[] = $generic_key_type->getId();
                }
                $array_access_type = Type::getMixed();
            }
        }
    }
    private static function handleArrayAccessOnNamedObject(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ArrayDimFetch $stmt, TNamedObject $type, Context $context, bool $in_assignment, ?PhpParser\Node\Expr $assign_value, ?Union &$array_access_type, bool &$has_array_access) : void
    {
        if (strtolower($type->value) === 'simplexmlelement') {
            $call_array_access_type = new Union([new TNamedObject('SimpleXMLElement')]);
        } elseif (strtolower($type->value) === 'domnodelist' && $stmt->dim) {
            $old_data_provider = $statements_analyzer->node_data;
            $statements_analyzer->node_data = clone $statements_analyzer->node_data;
            $fake_method_call = new VirtualMethodCall($stmt->var, new VirtualIdentifier('item', $stmt->var->getAttributes()), [new VirtualArg($stmt->dim)]);
            $suppressed_issues = $statements_analyzer->getSuppressedIssues();
            if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['PossiblyInvalidMethodCall']);
            }
            if (!in_array('MixedMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['MixedMethodCall']);
            }
            MethodCallAnalyzer::analyze($statements_analyzer, $fake_method_call, $context);
            if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['PossiblyInvalidMethodCall']);
            }
            if (!in_array('MixedMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['MixedMethodCall']);
            }
            $call_array_access_type = $statements_analyzer->node_data->getType($fake_method_call) ?? Type::getMixed();
            $statements_analyzer->node_data = $old_data_provider;
        } else {
            $suppressed_issues = $statements_analyzer->getSuppressedIssues();
            if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['PossiblyInvalidMethodCall']);
            }
            if (!in_array('MixedMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['MixedMethodCall']);
            }
            if ($in_assignment) {
                $old_node_data = $statements_analyzer->node_data;
                $statements_analyzer->node_data = clone $statements_analyzer->node_data;
                $fake_set_method_call = new VirtualMethodCall($stmt->var, new VirtualIdentifier('offsetSet', $stmt->var->getAttributes()), [new VirtualArg($stmt->dim ?? new VirtualConstFetch(new VirtualName('null'), $stmt->var->getAttributes())), new VirtualArg($assign_value ?? new VirtualConstFetch(new VirtualName('null'), $stmt->var->getAttributes()))]);
                MethodCallAnalyzer::analyze($statements_analyzer, $fake_set_method_call, $context);
                $statements_analyzer->node_data = $old_node_data;
            }
            if ($stmt->dim) {
                $old_node_data = $statements_analyzer->node_data;
                $statements_analyzer->node_data = clone $statements_analyzer->node_data;
                $fake_get_method_call = new VirtualMethodCall($stmt->var, new VirtualIdentifier('offsetGet', $stmt->var->getAttributes()), [new VirtualArg($stmt->dim)]);
                MethodCallAnalyzer::analyze($statements_analyzer, $fake_get_method_call, $context);
                $call_array_access_type = $statements_analyzer->node_data->getType($fake_get_method_call) ?? Type::getMixed();
                $statements_analyzer->node_data = $old_node_data;
            } else {
                $call_array_access_type = Type::getVoid();
            }
            $has_array_access = \true;
            if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['PossiblyInvalidMethodCall']);
            }
            if (!in_array('MixedMethodCall', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['MixedMethodCall']);
            }
        }
        $array_access_type = Type::combineUnionTypes($array_access_type, $call_array_access_type);
    }
    /**
     * @param list<string> $expected_offset_types
     */
    private static function handleArrayAccessOnString(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Expr\ArrayDimFetch $stmt, bool $in_assignment, Context $context, ?Union $replacement_type, TString $type, MutableUnion $offset_type, array &$expected_offset_types, ?Union &$array_access_type, bool &$has_valid_offset) : void
    {
        if ($in_assignment && $replacement_type) {
            if ($replacement_type->hasMixed()) {
                if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                    $codebase->analyzer->incrementMixedCount($statements_analyzer->getFilePath());
                }
                IssueBuffer::maybeAdd(new MixedStringOffsetAssignment('Right-hand-side of string offset assignment cannot be mixed', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            } else {
                if (!$context->collect_initializations && !$context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath() && (!($parent_source = $statements_analyzer->getSource()) instanceof FunctionLikeAnalyzer || !$parent_source->getSource() instanceof TraitAnalyzer)) {
                    $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getFilePath());
                }
            }
        }
        if ($type instanceof TSingleLetter) {
            $valid_offset_type = Type::getInt(\false, 0);
        } elseif ($type instanceof TLiteralString) {
            if ($type->value === '') {
                $valid_offset_type = Type::getNever();
            } elseif (strlen($type->value) < 10) {
                $valid_offsets = [];
                for ($i = -strlen($type->value), $l = strlen($type->value); $i < $l; $i++) {
                    $valid_offsets[] = new TLiteralInt($i);
                }
                if (!$valid_offsets) {
                    throw new UnexpectedValueException('This is weird');
                }
                $valid_offset_type = new Union($valid_offsets);
            } else {
                $valid_offset_type = Type::getInt();
            }
        } else {
            $valid_offset_type = Type::getInt();
        }
        if (!UnionTypeComparator::isContainedBy($codebase, $offset_type->freeze(), $valid_offset_type, \true)) {
            $expected_offset_types[] = $valid_offset_type->getId();
            $array_access_type = Type::getMixed();
        } else {
            $has_valid_offset = \true;
            $array_access_type = Type::combineUnionTypes($array_access_type, Type::getSingleLetter());
        }
    }
    /**
     * @param Atomic[] $offset_types
     */
    private static function checkArrayOffsetType(MutableUnion $offset_type, array $offset_types, Codebase $codebase) : bool
    {
        $has_valid_absolute_offset = \false;
        foreach ($offset_types as $atomic_offset_type) {
            if ($atomic_offset_type instanceof TClassConstant) {
                $expanded = TypeExpander::expandAtomic($codebase, $atomic_offset_type, $atomic_offset_type->fq_classlike_name, $atomic_offset_type->fq_classlike_name, null, \true, \true);
                $has_valid_absolute_offset = self::checkArrayOffsetType($offset_type, $expanded, $codebase);
                if ($has_valid_absolute_offset) {
                    break;
                }
            }
            if ($atomic_offset_type instanceof TFalse && $offset_type->ignore_falsable_issues === \true) {
                //do nothing
            } elseif ($atomic_offset_type instanceof TNull && $offset_type->ignore_nullable_issues === \true) {
                //do nothing
            } elseif ($atomic_offset_type instanceof TString || $atomic_offset_type instanceof TInt || $atomic_offset_type instanceof TArrayKey || $atomic_offset_type instanceof TMixed) {
                $has_valid_absolute_offset = \true;
                break;
            } elseif ($atomic_offset_type instanceof TTemplateParam) {
                $has_valid_absolute_offset = self::checkArrayOffsetType($offset_type, $atomic_offset_type->as->getAtomicTypes(), $codebase);
                if ($has_valid_absolute_offset) {
                    break;
                }
            }
        }
        return $has_valid_absolute_offset;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Fetch;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\SimpleTypeInferer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Issue\UndefinedConstant;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Union;
use ReflectionProperty;
use function array_key_exists;
use function array_pop;
use function explode;
use function implode;
use function strtolower;
/**
 * @internal
 */
class ConstFetchAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\ConstFetch $stmt, Context $context) : void
    {
        $const_name = implode('\\', $stmt->name->parts);
        switch (strtolower($const_name)) {
            case 'null':
                $statements_analyzer->node_data->setType($stmt, Type::getNull());
                break;
            case 'false':
                // false is a subtype of bool
                $statements_analyzer->node_data->setType($stmt, Type::getFalse());
                break;
            case 'true':
                $statements_analyzer->node_data->setType($stmt, Type::getTrue());
                break;
            case 'stdin':
                $statements_analyzer->node_data->setType($stmt, Type::getResource());
                break;
            default:
                $const_type = self::getConstType($statements_analyzer, $const_name, $stmt->name instanceof PhpParser\Node\Name\FullyQualified, $context);
                $codebase = $statements_analyzer->getCodebase();
                $aliased_constants = $statements_analyzer->getAliases()->constants;
                if (isset($aliased_constants[$const_name])) {
                    $fq_const_name = $aliased_constants[$const_name];
                } elseif ($stmt->name instanceof PhpParser\Node\Name\FullyQualified) {
                    $fq_const_name = $const_name;
                } else {
                    $fq_const_name = Type::getFQCLNFromString($const_name, $statements_analyzer->getAliases());
                }
                $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt, $const_type ? $fq_const_name : '*' . ($stmt->name instanceof PhpParser\Node\Name\FullyQualified ? '\\' : $statements_analyzer->getNamespace() . '-') . $const_name);
                if ($const_type) {
                    $statements_analyzer->node_data->setType($stmt, $const_type);
                } elseif ($context->check_consts) {
                    IssueBuffer::maybeAdd(new UndefinedConstant('Const ' . $const_name . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
        }
    }
    public static function getGlobalConstType(Codebase $codebase, string $fq_const_name, string $const_name) : ?Union
    {
        if ($const_name === 'STDERR' || $const_name === 'STDOUT' || $const_name === 'STDIN') {
            return Type::getResource();
        }
        if ($fq_const_name) {
            $stubbed_const_type = $codebase->getStubbedConstantType($fq_const_name);
            if ($stubbed_const_type) {
                return $stubbed_const_type;
            }
        }
        $stubbed_const_type = $codebase->getStubbedConstantType($const_name);
        if ($stubbed_const_type) {
            return $stubbed_const_type;
        }
        $predefined_constants = $codebase->config->getPredefinedConstants();
        if ($fq_const_name && array_key_exists($fq_const_name, $predefined_constants) || array_key_exists($const_name, $predefined_constants)) {
            switch ($const_name) {
                case 'PHP_VERSION':
                case 'DIRECTORY_SEPARATOR':
                case 'PATH_SEPARATOR':
                case 'PHP_EOL':
                    return Type::getNonEmptyString();
                case 'PEAR_EXTENSION_DIR':
                case 'PEAR_INSTALL_DIR':
                case 'PHP_BINARY':
                case 'PHP_BINDIR':
                case 'PHP_CONFIG_FILE_PATH':
                case 'PHP_CONFIG_FILE_SCAN_DIR':
                case 'PHP_DATADIR':
                case 'PHP_EXTENSION_DIR':
                case 'PHP_EXTRA_VERSION':
                case 'PHP_LIBDIR':
                case 'PHP_LOCALSTATEDIR':
                case 'PHP_MANDIR':
                case 'PHP_OS':
                case 'PHP_OS_FAMILY':
                case 'PHP_PREFIX':
                case 'PHP_SAPI':
                case 'PHP_SYSCONFDIR':
                    return Type::getString();
                case 'PHP_MAJOR_VERSION':
                case 'PHP_MINOR_VERSION':
                case 'PHP_RELEASE_VERSION':
                case 'PHP_DEBUG':
                case 'PHP_FLOAT_DIG':
                case 'PHP_INT_MIN':
                case 'PHP_ZTS':
                    return Type::getInt();
                case 'PHP_INT_MAX':
                case 'PHP_INT_SIZE':
                case 'PHP_MAXPATHLEN':
                case 'PHP_VERSION_ID':
                    return new Union([new TIntRange(1, null)]);
                case 'PHP_FLOAT_EPSILON':
                case 'PHP_FLOAT_MAX':
                case 'PHP_FLOAT_MIN':
                    return Type::getFloat();
            }
            if ($fq_const_name && array_key_exists($fq_const_name, $predefined_constants)) {
                return ClassLikeAnalyzer::getTypeFromValue($predefined_constants[$fq_const_name]);
            }
            return ClassLikeAnalyzer::getTypeFromValue($predefined_constants[$const_name]);
        }
        return null;
    }
    public static function getConstType(StatementsAnalyzer $statements_analyzer, string $const_name, bool $is_fully_qualified, ?Context $context) : ?Union
    {
        $aliased_constants = $statements_analyzer->getAliases()->constants;
        if (isset($aliased_constants[$const_name])) {
            $fq_const_name = $aliased_constants[$const_name];
        } elseif ($is_fully_qualified) {
            $fq_const_name = $const_name;
        } else {
            $fq_const_name = Type::getFQCLNFromString($const_name, $statements_analyzer->getAliases());
        }
        if ($fq_const_name) {
            $const_name_parts = explode('\\', $fq_const_name);
            $const_name = array_pop($const_name_parts);
            $namespace_name = implode('\\', $const_name_parts);
            $namespace_constants = NamespaceAnalyzer::getConstantsForNamespace($namespace_name, ReflectionProperty::IS_PUBLIC);
            if (isset($namespace_constants[$const_name])) {
                return $namespace_constants[$const_name];
            }
        }
        if ($context && $context->hasVariable($fq_const_name)) {
            return $context->vars_in_scope[$fq_const_name];
        }
        $file_path = $statements_analyzer->getRootFilePath();
        $codebase = $statements_analyzer->getCodebase();
        $file_storage_provider = $codebase->file_storage_provider;
        $file_storage = $file_storage_provider->get($file_path);
        if (isset($file_storage->declaring_constants[$const_name])) {
            $constant_file_path = $file_storage->declaring_constants[$const_name];
            return $file_storage_provider->get($constant_file_path)->constants[$const_name];
        }
        if (isset($file_storage->declaring_constants[$fq_const_name])) {
            $constant_file_path = $file_storage->declaring_constants[$fq_const_name];
            return $file_storage_provider->get($constant_file_path)->constants[$fq_const_name];
        }
        return self::getGlobalConstType($codebase, $fq_const_name, $const_name) ?? self::getGlobalConstType($codebase, $const_name, $const_name);
    }
    public static function setConstType(StatementsAnalyzer $statements_analyzer, string $const_name, Union $const_type, Context $context) : void
    {
        $context->vars_in_scope[$const_name] = $const_type;
        $context->constants[$const_name] = $const_type;
        $source = $statements_analyzer->getSource();
        if ($source instanceof NamespaceAnalyzer) {
            $source->setConstType($const_name, $const_type);
        }
    }
    public static function getConstName(PhpParser\Node\Expr $first_arg_value, NodeDataProvider $type_provider, Codebase $codebase, Aliases $aliases) : ?string
    {
        $const_name = null;
        if ($first_arg_value instanceof PhpParser\Node\Scalar\String_) {
            $const_name = $first_arg_value->value;
        } elseif ($first_arg_type = $type_provider->getType($first_arg_value)) {
            if ($first_arg_type->isSingleStringLiteral()) {
                $const_name = $first_arg_type->getSingleStringLiteral()->value;
            }
        } else {
            $simple_type = SimpleTypeInferer::infer($codebase, $type_provider, $first_arg_value, $aliases);
            if ($simple_type && $simple_type->isSingleStringLiteral()) {
                $const_name = $simple_type->getSingleStringLiteral()->value;
            }
        }
        return $const_name;
    }
    public static function analyzeConstAssignment(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Const_ $stmt, Context $context) : void
    {
        foreach ($stmt->consts as $const) {
            ExpressionAnalyzer::analyze($statements_analyzer, $const->value, $context);
            self::setConstType($statements_analyzer, $const->name->name, $statements_analyzer->node_data->getType($const->value) ?? Type::getMixed(), $context);
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Expression\Fetch;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ImpureStaticProperty;
use Psalm\Issue\ParentNotFound;
use Psalm\Issue\UndefinedPropertyAssignment;
use Psalm\Issue\UndefinedPropertyFetch;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualPropertyFetch;
use Psalm\Node\Expr\VirtualStaticPropertyFetch;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Type;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function count;
use function explode;
use function in_array;
use function md5;
use function strtolower;
/**
 * @internal
 */
class StaticPropertyFetchAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\StaticPropertyFetch $stmt, Context $context) : bool
    {
        if (!$stmt->class instanceof PhpParser\Node\Name) {
            self::analyzeVariableStaticPropertyFetch($statements_analyzer, $stmt->class, $stmt, $context);
            return \true;
        }
        $codebase = $statements_analyzer->getCodebase();
        if (count($stmt->class->parts) === 1 && in_array(strtolower($stmt->class->parts[0]), ['self', 'static', 'parent'], \true)) {
            if ($stmt->class->parts[0] === 'parent') {
                $fq_class_name = $statements_analyzer->getParentFQCLN();
                if ($fq_class_name === null) {
                    return !IssueBuffer::accepts(new ParentNotFound('Cannot check property fetch on parent as this class does not extend another', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            } else {
                $fq_class_name = (string) $context->self;
            }
            if ($context->isPhantomClass($fq_class_name)) {
                return \true;
            }
        } else {
            $aliases = $statements_analyzer->getAliases();
            if ($context->calling_method_id && !$stmt->class instanceof PhpParser\Node\Name\FullyQualified) {
                $codebase->file_reference_provider->addMethodReferenceToClassMember($context->calling_method_id, 'use:' . $stmt->class->parts[0] . ':' . md5($statements_analyzer->getFilePath()), \false);
            }
            $fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $aliases);
            if ($context->isPhantomClass($fq_class_name)) {
                return \true;
            }
            if ($context->check_classes) {
                if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_class_name, new CodeLocation($statements_analyzer->getSource(), $stmt->class), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues()) !== \true) {
                    return \false;
                }
            }
        }
        if ($fq_class_name && $codebase->methods_to_move && $context->calling_method_id && isset($codebase->methods_to_move[$context->calling_method_id])) {
            $destination_method_id = $codebase->methods_to_move[$context->calling_method_id];
            $codebase->classlikes->airliftClassLikeReference($fq_class_name, explode('::', $destination_method_id)[0], $statements_analyzer->getFilePath(), (int) $stmt->class->getAttribute('startFilePos'), (int) $stmt->class->getAttribute('endFilePos') + 1);
        }
        if ($fq_class_name) {
            $statements_analyzer->node_data->setType($stmt->class, new Union([new TNamedObject($fq_class_name)]));
        }
        if ($stmt->name instanceof PhpParser\Node\VarLikeIdentifier) {
            $prop_name = $stmt->name->name;
        } elseif (($stmt_name_type = $statements_analyzer->node_data->getType($stmt->name)) && $stmt_name_type->isSingleStringLiteral()) {
            $prop_name = $stmt_name_type->getSingleStringLiteral()->value;
        } else {
            $prop_name = null;
        }
        if (!$prop_name) {
            if ($fq_class_name) {
                $codebase->analyzer->addMixedMemberName(strtolower($fq_class_name) . '::$', $context->calling_method_id ?: $statements_analyzer->getFileName());
            }
            return \true;
        }
        if (!$fq_class_name || !$context->check_classes || !$context->check_variables || ExpressionAnalyzer::isMock($fq_class_name)) {
            return \true;
        }
        $var_id = ExpressionIdentifier::getVarId($stmt, $context->self ?: $statements_analyzer->getFQCLN(), $statements_analyzer);
        $property_id = $fq_class_name . '::$' . $prop_name;
        if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
            $codebase->analyzer->addNodeReference($statements_analyzer->getFilePath(), $stmt->name, $property_id);
        }
        if ($context->mutation_free) {
            IssueBuffer::maybeAdd(new ImpureStaticProperty('Cannot use a static property in a mutation-free context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
        } elseif ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
            $statements_analyzer->getSource()->inferred_has_mutation = \true;
            $statements_analyzer->getSource()->inferred_impure = \true;
        }
        if ($var_id && $context->hasVariable($var_id)) {
            $stmt_type = $context->vars_in_scope[$var_id];
            \Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer::processUnspecialTaints($statements_analyzer, $stmt, $stmt_type, $property_id, \false, [], []);
            $context->vars_in_scope[$var_id] = $stmt_type;
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            if ($codebase->collect_references) {
                // log the appearance
                $codebase->properties->propertyExists($property_id, \true, $statements_analyzer, $context, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null);
            }
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_type->getId());
            }
            return \true;
        }
        if (!$codebase->properties->propertyExists($property_id, \true, $statements_analyzer, $context, $codebase->collect_locations ? new CodeLocation($statements_analyzer->getSource(), $stmt) : null)) {
            if ($context->inside_isset) {
                return \true;
            }
            IssueBuffer::maybeAdd(new UndefinedPropertyFetch('Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            return \true;
        }
        $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($fq_class_name . '::$' . $prop_name, \true, $statements_analyzer);
        if ($declaring_property_class === null) {
            return \false;
        }
        \Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer::checkPropertyDeprecation($prop_name, $declaring_property_class, $stmt, $statements_analyzer);
        $class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
        $property = $class_storage->properties[$prop_name];
        if (!$property->is_static) {
            if ($context->inside_isset) {
                return \true;
            }
            if ($context->inside_assignment) {
                IssueBuffer::maybeAdd(new UndefinedPropertyAssignment('Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new UndefinedPropertyFetch('Static property ' . $property_id . ' is not defined', new CodeLocation($statements_analyzer->getSource(), $stmt), $property_id), $statements_analyzer->getSuppressedIssues());
            }
            return \true;
        }
        if (ClassLikeAnalyzer::checkPropertyVisibility($property_id, $context, $statements_analyzer, new CodeLocation($statements_analyzer->getSource(), $stmt), $statements_analyzer->getSuppressedIssues()) === \false) {
            return \false;
        }
        $declaring_property_id = strtolower($declaring_property_class) . '::$' . $prop_name;
        if ($codebase->alter_code) {
            $moved_class = $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $stmt->class, $fq_class_name, $context->calling_method_id);
            if (!$moved_class) {
                foreach ($codebase->property_transforms as $original_pattern => $transformation) {
                    if ($declaring_property_id === $original_pattern) {
                        [$old_declaring_fq_class_name] = explode('::$', $declaring_property_id);
                        [$new_fq_class_name, $new_property_name] = explode('::$', $transformation);
                        $file_manipulations = [];
                        if (strtolower($new_fq_class_name) !== $old_declaring_fq_class_name) {
                            $file_manipulations[] = new FileManipulation((int) $stmt->class->getAttribute('startFilePos'), (int) $stmt->class->getAttribute('endFilePos') + 1, Type::getStringFromFQCLN($new_fq_class_name, $statements_analyzer->getNamespace(), $statements_analyzer->getAliasedClassesFlipped(), null));
                        }
                        $file_manipulations[] = new FileManipulation((int) $stmt->name->getAttribute('startFilePos'), (int) $stmt->name->getAttribute('endFilePos') + 1, '$' . $new_property_name);
                        FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
                    }
                }
            }
            return \true;
        }
        if ($var_id) {
            if ($property->type) {
                $context->vars_in_scope[$var_id] = TypeExpander::expandUnion($codebase, $property->type, $class_storage->name, $class_storage->name, $class_storage->parent_class);
            } else {
                $context->vars_in_scope[$var_id] = Type::getMixed();
            }
            $stmt_type = $context->vars_in_scope[$var_id];
            \Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer::processUnspecialTaints($statements_analyzer, $stmt, $stmt_type, $property_id, \false, [], []);
            $context->vars_in_scope[$var_id] = $stmt_type;
            $statements_analyzer->node_data->setType($stmt, $stmt_type);
            if ($codebase->store_node_types && !$context->collect_initializations && !$context->collect_mutations) {
                $codebase->analyzer->addNodeType($statements_analyzer->getFilePath(), $stmt->name, $stmt_type->getId());
            }
        } else {
            $statements_analyzer->node_data->setType($stmt, Type::getMixed());
        }
        return \true;
    }
    private static function analyzeVariableStaticPropertyFetch(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt_class, PhpParser\Node\Expr\StaticPropertyFetch $stmt, Context $context) : void
    {
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        ExpressionAnalyzer::analyze($statements_analyzer, $stmt_class, $context);
        $context->inside_general_use = $was_inside_general_use;
        $stmt_class_type = $statements_analyzer->node_data->getType($stmt_class) ?? Type::getMixed();
        $old_data_provider = $statements_analyzer->node_data;
        $stmt_type = null;
        $codebase = $statements_analyzer->getCodebase();
        foreach ($stmt_class_type->getAtomicTypes() as $class_atomic_type) {
            $statements_analyzer->node_data = clone $statements_analyzer->node_data;
            $string_type = $class_atomic_type instanceof TClassString && $class_atomic_type->as_type !== null ? $class_atomic_type->as_type->value : ($class_atomic_type instanceof TLiteralString ? $class_atomic_type->value : null);
            if ($string_type) {
                $new_stmt_name = new VirtualFullyQualified($string_type, $stmt_class->getAttributes());
                $fake_static_property = new VirtualStaticPropertyFetch($new_stmt_name, $stmt->name, $stmt->getAttributes());
                self::analyze($statements_analyzer, $fake_static_property, $context);
                $fake_stmt_type = $statements_analyzer->node_data->getType($fake_static_property) ?? Type::getMixed();
            } else {
                $fake_var_name = '__fake_var_' . (string) $stmt->getAttribute('startFilePos');
                $fake_var = new VirtualVariable($fake_var_name, $stmt_class->getAttributes());
                $context->vars_in_scope['$' . $fake_var_name] = new Union([$class_atomic_type]);
                $fake_instance_property = new VirtualPropertyFetch($fake_var, $stmt->name, $stmt->getAttributes());
                \Psalm\Internal\Analyzer\Statements\Expression\Fetch\InstancePropertyFetchAnalyzer::analyze($statements_analyzer, $fake_instance_property, $context, \false, \true);
                $fake_stmt_type = $statements_analyzer->node_data->getType($fake_instance_property) ?? Type::getMixed();
            }
            $stmt_type = $stmt_type ? Type::combineUnionTypes($stmt_type, $fake_stmt_type, $codebase) : $fake_stmt_type;
            $statements_analyzer->node_data = $old_data_provider;
        }
        $statements_analyzer->node_data->setType($stmt, $stmt_type);
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Scope\SwitchScope;
use Psalm\Type;
use Psalm\Type\Reconciler;
use SplFixedArray;
use function array_merge;
use function count;
use function in_array;
/**
 * @internal
 */
class SwitchAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Switch_ $stmt, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $was_inside_conditional = $context->inside_conditional;
        $context->inside_conditional = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->cond, $context) === \false) {
            $context->inside_conditional = $was_inside_conditional;
            return;
        }
        $context->inside_conditional = $was_inside_conditional;
        $switch_var_id = ExpressionIdentifier::getExtendedVarId($stmt->cond, null, $statements_analyzer);
        if (!$switch_var_id && ($stmt->cond instanceof PhpParser\Node\Expr\FuncCall || $stmt->cond instanceof PhpParser\Node\Expr\MethodCall || $stmt->cond instanceof PhpParser\Node\Expr\StaticCall)) {
            $switch_var_id = '$__tmp_switch__' . (int) $stmt->cond->getAttribute('startFilePos');
            $condition_type = $statements_analyzer->node_data->getType($stmt->cond) ?? Type::getMixed();
            $context->vars_in_scope[$switch_var_id] = $condition_type;
        }
        $original_context = clone $context;
        // the last statement always breaks, by default
        $last_case_exit_type = 'break';
        $case_exit_types = new SplFixedArray(count($stmt->cases));
        $has_default = \false;
        $case_action_map = [];
        // create a map of case statement -> ultimate exit type
        for ($i = count($stmt->cases) - 1; $i >= 0; --$i) {
            $case = $stmt->cases[$i];
            $case_actions = $case_action_map[$i] = ScopeAnalyzer::getControlActions($case->stmts, $statements_analyzer->node_data, ['switch']);
            if (!in_array(ScopeAnalyzer::ACTION_NONE, $case_actions, \true)) {
                if ($case_actions === [ScopeAnalyzer::ACTION_END]) {
                    $last_case_exit_type = 'return_throw';
                } elseif ($case_actions === [ScopeAnalyzer::ACTION_CONTINUE]) {
                    $last_case_exit_type = 'continue';
                } elseif (in_array(ScopeAnalyzer::ACTION_LEAVE_SWITCH, $case_actions, \true)) {
                    $last_case_exit_type = 'break';
                }
            } elseif (count($case_actions) !== 1) {
                $last_case_exit_type = 'hybrid';
            }
            $case_exit_types[$i] = $last_case_exit_type;
        }
        $switch_scope = new SwitchScope();
        $was_caching_assertions = $statements_analyzer->node_data->cache_assertions;
        $statements_analyzer->node_data->cache_assertions = \false;
        $all_options_returned = \true;
        for ($i = 0, $l = count($stmt->cases); $i < $l; $i++) {
            $case = $stmt->cases[$i];
            /** @var string */
            $case_exit_type = $case_exit_types[$i];
            if ($case_exit_type !== 'return_throw') {
                $all_options_returned = \false;
            }
            $case_actions = $case_action_map[$i];
            if (!$case->cond) {
                $has_default = \true;
            }
            if (\Psalm\Internal\Analyzer\Statements\Block\SwitchCaseAnalyzer::analyze($statements_analyzer, $codebase, $stmt, $switch_var_id, $case, $context, $original_context, $case_exit_type, $case_actions, $i === $l - 1, $switch_scope) === \false) {
                return;
            }
        }
        $all_options_matched = $has_default;
        if (!$has_default && $switch_scope->negated_clauses && $switch_var_id) {
            $entry_clauses = Algebra::simplifyCNF([...$original_context->clauses, ...$switch_scope->negated_clauses]);
            $reconcilable_if_types = Algebra::getTruthsFromFormula($entry_clauses);
            // if the if has an || in the conditional, we cannot easily reason about it
            if ($reconcilable_if_types && isset($reconcilable_if_types[$switch_var_id])) {
                $changed_var_ids = [];
                [$case_vars_in_scope_reconciled, $_] = Reconciler::reconcileKeyedTypes($reconcilable_if_types, [], $original_context->vars_in_scope, $original_context->references_in_scope, $changed_var_ids, [], $statements_analyzer, [], $original_context->inside_loop);
                if (isset($case_vars_in_scope_reconciled[$switch_var_id]) && $case_vars_in_scope_reconciled[$switch_var_id]->isNever()) {
                    $all_options_matched = \true;
                }
            }
        }
        if ($was_caching_assertions) {
            $statements_analyzer->node_data->cache_assertions = \true;
        }
        // only update vars if there is a default or all possible cases accounted for
        // if the default has a throw/return/continue, that should be handled above
        if ($all_options_matched) {
            if ($switch_scope->new_vars_in_scope) {
                $context->vars_in_scope = array_merge($context->vars_in_scope, $switch_scope->new_vars_in_scope);
            }
            if ($switch_scope->redefined_vars) {
                $context->vars_in_scope = array_merge($context->vars_in_scope, $switch_scope->redefined_vars);
            }
            if ($switch_scope->possibly_redefined_vars) {
                foreach ($switch_scope->possibly_redefined_vars as $var_id => $type) {
                    if (!isset($switch_scope->redefined_vars[$var_id]) && !isset($switch_scope->new_vars_in_scope[$var_id]) && isset($context->vars_in_scope[$var_id])) {
                        $context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $context->vars_in_scope[$var_id]);
                    }
                }
            }
            $stmt->setAttribute('allMatched', \true);
        } elseif ($switch_scope->possibly_redefined_vars) {
            foreach ($switch_scope->possibly_redefined_vars as $var_id => $type) {
                if (isset($context->vars_in_scope[$var_id])) {
                    $context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $context->vars_in_scope[$var_id]);
                }
            }
        }
        if ($switch_scope->new_assigned_var_ids) {
            $context->assigned_var_ids += $switch_scope->new_assigned_var_ids;
        }
        $context->vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $switch_scope->new_vars_possibly_in_scope);
        //a switch can't return in all options without a default
        $context->has_returned = $all_options_returned && $has_default;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Scope\LoopScope;
use Psalm\Type;
use UnexpectedValueException;
use function array_merge;
use function in_array;
/**
 * @internal
 */
class WhileAnalyzer
{
    /**
     * @return  false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\While_ $stmt, Context $context) : ?bool
    {
        $while_true = $stmt->cond instanceof PhpParser\Node\Expr\ConstFetch && $stmt->cond->name->parts === ['true'] || ($t = $statements_analyzer->node_data->getType($stmt->cond)) && $t->isAlwaysTruthy();
        $pre_context = null;
        if ($while_true) {
            $pre_context = clone $context;
        }
        $while_context = clone $context;
        $while_context->inside_loop = \true;
        $while_context->break_types[] = 'loop';
        $codebase = $statements_analyzer->getCodebase();
        if ($codebase->alter_code) {
            $while_context->branch_point = $while_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
        }
        $loop_scope = new LoopScope($while_context, $context);
        $loop_scope->protected_var_ids = $context->protected_var_ids;
        if (\Psalm\Internal\Analyzer\Statements\Block\LoopAnalyzer::analyze($statements_analyzer, $stmt->stmts, self::getAndExpressions($stmt->cond), [], $loop_scope, $inner_loop_context) === \false) {
            return \false;
        }
        if (!$inner_loop_context) {
            throw new UnexpectedValueException('There should be an inner loop context');
        }
        $always_enters_loop = \false;
        if ($stmt_cond_type = $statements_analyzer->node_data->getType($stmt->cond)) {
            $always_enters_loop = $stmt_cond_type->isAlwaysTruthy();
        }
        if ($while_true) {
            $always_enters_loop = \true;
        }
        $can_leave_loop = !$while_true || in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, \true);
        if ($always_enters_loop && $can_leave_loop) {
            foreach ($inner_loop_context->vars_in_scope as $var_id => $type) {
                // if there are break statements in the loop it's not certain
                // that the loop has finished executing, so the assertions at the end
                // the loop in the while conditional may not hold
                if (in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, \true) || in_array(ScopeAnalyzer::ACTION_CONTINUE, $loop_scope->final_actions, \true)) {
                    if (isset($loop_scope->possibly_defined_loop_parent_vars[$var_id])) {
                        $context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $loop_scope->possibly_defined_loop_parent_vars[$var_id]);
                    }
                } else {
                    $context->vars_in_scope[$var_id] = $type;
                }
            }
        }
        $while_context->loop_scope = null;
        if ($can_leave_loop) {
            $context->vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $while_context->vars_possibly_in_scope);
        } elseif ($pre_context) {
            $context->vars_possibly_in_scope = $pre_context->vars_possibly_in_scope;
        }
        if ($context->collect_exceptions) {
            $context->mergeExceptions($while_context);
        }
        return null;
    }
    /**
     * @return list<PhpParser\Node\Expr>
     */
    public static function getAndExpressions(PhpParser\Node\Expr $expr) : array
    {
        if ($expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd) {
            return [...self::getAndExpressions($expr->left), ...self::getAndExpressions($expr->right)];
        }
        return [$expr];
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\ScopeAnalysisException;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Scope\IfConditionalScope;
use Psalm\Internal\Scope\IfScope;
use Psalm\Issue\DocblockTypeContradiction;
use Psalm\Issue\RedundantCondition;
use Psalm\Issue\RedundantConditionGivenDocblockType;
use Psalm\Issue\TypeDoesNotContainType;
use Psalm\IssueBuffer;
use Psalm\Type\Reconciler;
use function array_diff_key;
use function array_filter;
use function array_keys;
use function array_merge;
use function array_values;
use function count;
/**
 * @internal
 */
class IfConditionalAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $cond, Context $outer_context, Codebase $codebase, IfScope $if_scope, int $branch_point) : IfConditionalScope
    {
        $entry_clauses = [];
        // used when evaluating elseifs
        if ($if_scope->negated_clauses) {
            $entry_clauses = [...$outer_context->clauses, ...$if_scope->negated_clauses];
            $changed_var_ids = [];
            if ($if_scope->negated_types) {
                [$vars_reconciled, $references_reconciled] = Reconciler::reconcileKeyedTypes($if_scope->negated_types, [], $outer_context->vars_in_scope, $outer_context->references_in_scope, $changed_var_ids, [], $statements_analyzer, [], $outer_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $cond instanceof PhpParser\Node\Expr\BooleanNot ? $cond->expr : $cond, $outer_context->include_location, \false));
                if ($changed_var_ids) {
                    $outer_context = clone $outer_context;
                    $outer_context->vars_in_scope = $vars_reconciled;
                    $outer_context->references_in_scope = $references_reconciled;
                    $entry_clauses = array_values(array_filter($entry_clauses, static fn(Clause $c): bool => count($c->possibilities) > 1 || $c->wedge || !isset($changed_var_ids[array_keys($c->possibilities)[0]])));
                }
            }
        }
        // get the first expression in the if, which should be evaluated on its own
        // this allows us to update the context of $matches in
        // if (!preg_match('/a/', 'aa', $matches)) {
        //   exit
        // }
        // echo $matches[0];
        $externally_applied_if_cond_expr = self::getDefinitelyEvaluatedExpressionAfterIf($cond);
        $internally_applied_if_cond_expr = self::getDefinitelyEvaluatedExpressionInsideIf($cond);
        $pre_condition_vars_in_scope = $outer_context->vars_in_scope;
        $referenced_var_ids = $outer_context->cond_referenced_var_ids;
        $outer_context->cond_referenced_var_ids = [];
        $pre_assigned_var_ids = $outer_context->assigned_var_ids;
        $outer_context->assigned_var_ids = [];
        $if_context = null;
        if ($internally_applied_if_cond_expr !== $externally_applied_if_cond_expr) {
            $if_context = clone $outer_context;
        }
        $was_inside_conditional = $outer_context->inside_conditional;
        $outer_context->inside_conditional = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $externally_applied_if_cond_expr, $outer_context) === \false) {
            throw new ScopeAnalysisException();
        }
        $first_cond_assigned_var_ids = $outer_context->assigned_var_ids;
        $outer_context->assigned_var_ids = array_merge($pre_assigned_var_ids, $first_cond_assigned_var_ids);
        $first_cond_referenced_var_ids = $outer_context->cond_referenced_var_ids;
        $outer_context->cond_referenced_var_ids = array_merge($referenced_var_ids, $first_cond_referenced_var_ids);
        $outer_context->inside_conditional = $was_inside_conditional;
        if (!$if_context) {
            $if_context = clone $outer_context;
        }
        $if_conditional_context = clone $if_context;
        // here we set up a context specifically for the statements in the first `if`, which can
        // be affected by statements in the if condition
        $if_conditional_context->if_body_context = $if_context;
        if ($codebase->alter_code) {
            $if_context->branch_point = $branch_point;
        }
        // we need to clone the current context so our ongoing updates
        // to $outer_context don't mess with elseif/else blocks
        $post_if_context = clone $outer_context;
        if ($internally_applied_if_cond_expr !== $cond || $externally_applied_if_cond_expr !== $cond) {
            $assigned_var_ids = $first_cond_assigned_var_ids;
            $if_conditional_context->assigned_var_ids = [];
            $referenced_var_ids = $first_cond_referenced_var_ids;
            $if_conditional_context->cond_referenced_var_ids = [];
            $was_inside_conditional = $if_conditional_context->inside_conditional;
            $if_conditional_context->inside_conditional = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $cond, $if_conditional_context) === \false) {
                throw new ScopeAnalysisException();
            }
            $if_conditional_context->inside_conditional = $was_inside_conditional;
            /** @var array<string, bool> */
            $more_cond_referenced_var_ids = $if_conditional_context->cond_referenced_var_ids;
            $if_conditional_context->cond_referenced_var_ids = array_merge($more_cond_referenced_var_ids, $referenced_var_ids);
            $cond_referenced_var_ids = array_merge($first_cond_referenced_var_ids, $more_cond_referenced_var_ids);
            /** @var array<string, int> */
            $more_cond_assigned_var_ids = $if_conditional_context->assigned_var_ids;
            $if_conditional_context->assigned_var_ids = array_merge($more_cond_assigned_var_ids, $assigned_var_ids);
            $assigned_in_conditional_var_ids = array_merge($first_cond_assigned_var_ids, $more_cond_assigned_var_ids);
        } else {
            $cond_referenced_var_ids = $first_cond_referenced_var_ids;
            $assigned_in_conditional_var_ids = $first_cond_assigned_var_ids;
        }
        $newish_var_ids = [];
        foreach (array_diff_key($if_conditional_context->vars_in_scope, $pre_condition_vars_in_scope, $cond_referenced_var_ids, $assigned_in_conditional_var_ids) as $name => $_value) {
            $newish_var_ids[$name] = \true;
        }
        self::handleParadoxicalCondition($statements_analyzer, $cond, \true);
        // get all the var ids that were referenced in the conditional, but not assigned in it
        $cond_referenced_var_ids = array_diff_key($cond_referenced_var_ids, $assigned_in_conditional_var_ids);
        $cond_referenced_var_ids = array_merge($newish_var_ids, $cond_referenced_var_ids);
        return new IfConditionalScope($if_context, $post_if_context, $cond_referenced_var_ids, $assigned_in_conditional_var_ids, $entry_clauses);
    }
    /**
     * Returns statements that are definitely evaluated before any statements after the end of the
     * if/elseif/else blocks
     */
    private static function getDefinitelyEvaluatedExpressionAfterIf(PhpParser\Node\Expr $stmt) : PhpParser\Node\Expr
    {
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
            if ($stmt->left instanceof PhpParser\Node\Expr\ConstFetch && $stmt->left->name->parts === ['true']) {
                return self::getDefinitelyEvaluatedExpressionAfterIf($stmt->right);
            }
            if ($stmt->right instanceof PhpParser\Node\Expr\ConstFetch && $stmt->right->name->parts === ['true']) {
                return self::getDefinitelyEvaluatedExpressionAfterIf($stmt->left);
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalAnd || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalXor) {
                return self::getDefinitelyEvaluatedExpressionAfterIf($stmt->left);
            }
            return $stmt;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BooleanNot) {
            $inner_stmt = self::getDefinitelyEvaluatedExpressionInsideIf($stmt->expr);
            if ($inner_stmt !== $stmt->expr) {
                return $inner_stmt;
            }
        }
        return $stmt;
    }
    /**
     * Returns statements that are definitely evaluated before any statements inside
     * the if block
     */
    private static function getDefinitelyEvaluatedExpressionInsideIf(PhpParser\Node\Expr $stmt) : PhpParser\Node\Expr
    {
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Equal || $stmt instanceof PhpParser\Node\Expr\BinaryOp\Identical) {
            if ($stmt->left instanceof PhpParser\Node\Expr\ConstFetch && $stmt->left->name->parts === ['true']) {
                return self::getDefinitelyEvaluatedExpressionInsideIf($stmt->right);
            }
            if ($stmt->right instanceof PhpParser\Node\Expr\ConstFetch && $stmt->right->name->parts === ['true']) {
                return self::getDefinitelyEvaluatedExpressionInsideIf($stmt->left);
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalXor) {
                return self::getDefinitelyEvaluatedExpressionInsideIf($stmt->left);
            }
            return $stmt;
        }
        if ($stmt instanceof PhpParser\Node\Expr\BooleanNot) {
            $inner_stmt = self::getDefinitelyEvaluatedExpressionAfterIf($stmt->expr);
            if ($inner_stmt !== $stmt->expr) {
                return $inner_stmt;
            }
        }
        return $stmt;
    }
    public static function handleParadoxicalCondition(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, bool $emit_redundant_with_assignation = \false) : void
    {
        $type = $statements_analyzer->node_data->getType($stmt);
        if ($type !== null) {
            if ($type->isAlwaysFalsy()) {
                if ($type->from_docblock) {
                    IssueBuffer::maybeAdd(new DocblockTypeContradiction('Operand of type ' . $type->getId() . ' is always falsy', new CodeLocation($statements_analyzer, $stmt), $type->getId() . ' falsy'), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new TypeDoesNotContainType('Operand of type ' . $type->getId() . ' is always falsy', new CodeLocation($statements_analyzer, $stmt), $type->getId() . ' falsy'), $statements_analyzer->getSuppressedIssues());
                }
            } elseif ($type->isAlwaysTruthy() && (!$stmt instanceof PhpParser\Node\Expr\Assign || $emit_redundant_with_assignation)) {
                if ($type->from_docblock) {
                    IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType('Operand of type ' . $type->getId() . ' is always truthy', new CodeLocation($statements_analyzer, $stmt), $type->getId() . ' falsy'), $statements_analyzer->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new RedundantCondition('Operand of type ' . $type->getId() . ' is always truthy', new CodeLocation($statements_analyzer, $stmt), $type->getId() . ' falsy'), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Scope\LoopScope;
use Psalm\Type;
use Psalm\Type\Reconciler;
use UnexpectedValueException;
use function array_diff;
use function array_filter;
use function array_keys;
use function array_merge;
use function array_values;
use function in_array;
use function preg_match;
use function preg_quote;
use function spl_object_id;
/**
 * @internal
 */
class DoAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Do_ $stmt, Context $context) : ?bool
    {
        $do_context = clone $context;
        $do_context->break_types[] = 'loop';
        $do_context->inside_loop = \true;
        $codebase = $statements_analyzer->getCodebase();
        if ($codebase->alter_code) {
            $do_context->branch_point = $do_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
        }
        $loop_scope = new LoopScope($do_context, $context);
        $loop_scope->protected_var_ids = $context->protected_var_ids;
        self::analyzeDoNaively($statements_analyzer, $stmt, $do_context, $loop_scope);
        $mixed_var_ids = [];
        foreach ($do_context->vars_in_scope as $var_id => $type) {
            if ($type->hasMixed()) {
                $mixed_var_ids[] = $var_id;
            }
        }
        $cond_id = spl_object_id($stmt->cond);
        $while_clauses = FormulaGenerator::getFormula($cond_id, $cond_id, $stmt->cond, $context->self, $statements_analyzer, $codebase);
        $while_clauses = array_values(array_filter($while_clauses, static function (Clause $c) use($mixed_var_ids) : bool {
            $keys = array_keys($c->possibilities);
            $mixed_var_ids = array_diff($mixed_var_ids, $keys);
            foreach ($keys as $key) {
                foreach ($mixed_var_ids as $mixed_var_id) {
                    if (preg_match('/^' . preg_quote($mixed_var_id, '/') . '(\\[|-)/', $key)) {
                        return \false;
                    }
                }
            }
            return \true;
        }));
        if (!$while_clauses) {
            $while_clauses = [new Clause([], $cond_id, $cond_id, \true)];
        }
        if (\Psalm\Internal\Analyzer\Statements\Block\LoopAnalyzer::analyze($statements_analyzer, $stmt->stmts, \Psalm\Internal\Analyzer\Statements\Block\WhileAnalyzer::getAndExpressions($stmt->cond), [], $loop_scope, $inner_loop_context, \true, \true) === \false) {
            return \false;
        }
        // because it's a do {} while, inner loop vars belong to the main context
        if (!$inner_loop_context) {
            throw new UnexpectedValueException('There should be an inner loop context');
        }
        $negated_while_clauses = Algebra::negateFormula($while_clauses);
        $negated_while_types = Algebra::getTruthsFromFormula(Algebra::simplifyCNF([...$context->clauses, ...$negated_while_clauses]));
        if ($negated_while_types) {
            $changed_var_ids = [];
            [$inner_loop_context->vars_in_scope, $inner_loop_context->references_in_scope] = Reconciler::reconcileKeyedTypes($negated_while_types, [], $inner_loop_context->vars_in_scope, $inner_loop_context->references_in_scope, $changed_var_ids, [], $statements_analyzer, [], \true, new CodeLocation($statements_analyzer->getSource(), $stmt->cond));
        }
        foreach ($inner_loop_context->vars_in_scope as $var_id => $type) {
            // if there are break statements in the loop it's not certain
            // that the loop has finished executing, so the assertions at the end
            // the loop in the while conditional may not hold
            if (in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, \true)) {
                if (isset($loop_scope->possibly_defined_loop_parent_vars[$var_id])) {
                    $context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $loop_scope->possibly_defined_loop_parent_vars[$var_id]);
                }
            } else {
                $context->vars_in_scope[$var_id] = $type;
            }
        }
        $do_context->loop_scope = null;
        $context->vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $do_context->vars_possibly_in_scope);
        if ($context->collect_exceptions) {
            $context->mergeExceptions($inner_loop_context);
        }
        return null;
    }
    private static function analyzeDoNaively(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Do_ $stmt, Context $context, LoopScope $loop_scope) : void
    {
        $do_context = clone $context;
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        if (!in_array('RedundantCondition', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['RedundantCondition']);
        }
        if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['RedundantConditionGivenDocblockType']);
        }
        if (!in_array('TypeDoesNotContainType', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['TypeDoesNotContainType']);
        }
        $do_context->loop_scope = $loop_scope;
        $statements_analyzer->analyze($stmt->stmts, $do_context);
        if (!in_array('RedundantCondition', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['RedundantCondition']);
        }
        if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['RedundantConditionGivenDocblockType']);
        }
        if (!in_array('TypeDoesNotContainType', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['TypeDoesNotContainType']);
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\AlgebraAnalyzer;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\PhpVisitor\ConditionCloningVisitor;
use Psalm\Internal\PhpVisitor\TypeMappingVisitor;
use Psalm\Internal\Scope\CaseScope;
use Psalm\Internal\Scope\SwitchScope;
use Psalm\Issue\ContinueOutsideLoop;
use Psalm\Issue\ParadoxicalCondition;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\BinaryOp\VirtualBooleanOr;
use Psalm\Node\Expr\BinaryOp\VirtualEqual;
use Psalm\Node\Expr\BinaryOp\VirtualIdentical;
use Psalm\Node\Expr\VirtualArray;
use Psalm\Node\Expr\VirtualArrayItem;
use Psalm\Node\Expr\VirtualBooleanNot;
use Psalm\Node\Expr\VirtualConstFetch;
use Psalm\Node\Expr\VirtualFuncCall;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\Scalar\VirtualLNumber;
use Psalm\Node\Stmt\VirtualIf;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualName;
use Psalm\Type;
use Psalm\Type\Atomic\TDependentGetClass;
use Psalm\Type\Atomic\TDependentGetDebugType;
use Psalm\Type\Atomic\TDependentGetType;
use Psalm\Type\Reconciler;
use function array_diff_key;
use function array_intersect_key;
use function array_merge;
use function count;
use function in_array;
use function is_string;
use function spl_object_id;
use function strpos;
use function substr;
/**
 * @internal
 */
class SwitchCaseAnalyzer
{
    /**
     * @return null|false
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, Codebase $codebase, PhpParser\Node\Stmt\Switch_ $stmt, ?string $switch_var_id, PhpParser\Node\Stmt\Case_ $case, Context $context, Context $original_context, string $case_exit_type, array $case_actions, bool $is_last, SwitchScope $switch_scope) : ?bool
    {
        // has a return/throw at end
        $has_ending_statements = $case_actions === [ScopeAnalyzer::ACTION_END];
        $has_leaving_statements = $has_ending_statements || count($case_actions) && !in_array(ScopeAnalyzer::ACTION_NONE, $case_actions, \true);
        $case_context = clone $original_context;
        if ($codebase->alter_code) {
            $case_context->branch_point = $case_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
        }
        $case_scope = $case_context->case_scope = new CaseScope($case_context);
        $case_equality_expr = null;
        $old_node_data = $statements_analyzer->node_data;
        $fake_switch_condition = \false;
        if ($switch_var_id && strpos($switch_var_id, '$__tmp_switch__') === 0) {
            $switch_condition = new VirtualVariable(substr($switch_var_id, 1), $stmt->cond->getAttributes());
            $fake_switch_condition = \true;
        } else {
            $switch_condition = $stmt->cond;
        }
        if ($case->cond) {
            $was_inside_conditional = $case_context->inside_conditional;
            $case_context->inside_conditional = \true;
            if (ExpressionAnalyzer::analyze($statements_analyzer, $case->cond, $case_context) === \false) {
                unset($case_scope->parent_context);
                unset($case_context->case_scope);
                return \false;
            }
            $case_context->inside_conditional = $was_inside_conditional;
            $statements_analyzer->node_data = clone $statements_analyzer->node_data;
            $traverser = new PhpParser\NodeTraverser();
            $traverser->addVisitor(new ConditionCloningVisitor($statements_analyzer->node_data));
            /** @var PhpParser\Node\Expr */
            $switch_condition = $traverser->traverse([$switch_condition])[0];
            if ($fake_switch_condition) {
                $statements_analyzer->node_data->setType($switch_condition, $case_context->vars_in_scope[$switch_var_id] ?? Type::getMixed());
            }
            if ($switch_condition instanceof PhpParser\Node\Expr\Variable && is_string($switch_condition->name) && isset($context->vars_in_scope['$' . $switch_condition->name])) {
                $switch_var_type = $context->vars_in_scope['$' . $switch_condition->name];
                $type_statements = [];
                foreach ($switch_var_type->getAtomicTypes() as $type) {
                    if ($type instanceof TDependentGetClass) {
                        $type_statements[] = new VirtualFuncCall(new VirtualName(['get_class']), [new VirtualArg(new VirtualVariable(substr($type->typeof, 1), $stmt->cond->getAttributes()), \false, \false, $stmt->cond->getAttributes())], $stmt->cond->getAttributes());
                    } elseif ($type instanceof TDependentGetType) {
                        $type_statements[] = new VirtualFuncCall(new VirtualName(['gettype']), [new VirtualArg(new VirtualVariable(substr($type->typeof, 1), $stmt->cond->getAttributes()), \false, \false, $stmt->cond->getAttributes())], $stmt->cond->getAttributes());
                    } elseif ($type instanceof TDependentGetDebugType) {
                        $type_statements[] = new VirtualFuncCall(new VirtualName(['get_debug_type']), [new VirtualArg(new VirtualVariable(substr($type->typeof, 1), $stmt->cond->getAttributes()), \false, \false, $stmt->cond->getAttributes())], $stmt->cond->getAttributes());
                    } else {
                        $type_statements = null;
                        break;
                    }
                }
                if ($type_statements && count($type_statements) === 1) {
                    $switch_condition = $type_statements[0];
                    if ($fake_switch_condition) {
                        $statements_analyzer->node_data->setType($switch_condition, $case_context->vars_in_scope[$switch_var_id] ?? Type::getMixed());
                    }
                }
            }
            if ($switch_condition instanceof PhpParser\Node\Expr\ConstFetch && $switch_condition->name->parts === ['true']) {
                $case_equality_expr = $case->cond;
            } elseif (($switch_condition_type = $statements_analyzer->node_data->getType($switch_condition)) && ($case_cond_type = $statements_analyzer->node_data->getType($case->cond)) && ($switch_condition_type->isString() && $case_cond_type->isString() || $switch_condition_type->isInt() && $case_cond_type->isInt() || $switch_condition_type->isFloat() && $case_cond_type->isFloat())) {
                $case_equality_expr = new VirtualIdentical($switch_condition, $case->cond, $case->cond->getAttributes());
            } else {
                $case_equality_expr = new VirtualEqual($switch_condition, $case->cond, $case->cond->getAttributes());
            }
        }
        $continue_case_equality_expr = \false;
        if ($case->stmts) {
            $case_stmts = array_merge($switch_scope->leftover_statements, $case->stmts);
        } else {
            $continue_case_equality_expr = count($switch_scope->leftover_statements) === 1;
            $case_stmts = $switch_scope->leftover_statements;
        }
        if (!$has_leaving_statements && !$is_last) {
            if (!$case_equality_expr) {
                $case_equality_expr = new VirtualFuncCall(new VirtualFullyQualified(['rand']), [new VirtualArg(new VirtualLNumber(0)), new VirtualArg(new VirtualLNumber(1))], $case->getAttributes());
            }
            $switch_scope->leftover_case_equality_expr = $switch_scope->leftover_case_equality_expr ? new VirtualBooleanOr($switch_scope->leftover_case_equality_expr, $case_equality_expr, $case->cond ? $case->cond->getAttributes() : $case->getAttributes()) : $case_equality_expr;
            if ($continue_case_equality_expr && $switch_scope->leftover_statements[0] instanceof PhpParser\Node\Stmt\If_) {
                $case_if_stmt = $switch_scope->leftover_statements[0];
                $case_if_stmt->cond = $switch_scope->leftover_case_equality_expr;
            } else {
                $case_if_stmt = new VirtualIf($switch_scope->leftover_case_equality_expr, ['stmts' => $case_stmts], $case->getAttributes());
                $switch_scope->leftover_statements = [$case_if_stmt];
            }
            unset($case_scope->parent_context);
            unset($case_context->case_scope);
            $statements_analyzer->node_data = $old_node_data;
            return null;
        }
        if ($switch_scope->leftover_case_equality_expr) {
            $case_or_default_equality_expr = $case_equality_expr;
            if (!$case_or_default_equality_expr) {
                $case_or_default_equality_expr = new VirtualFuncCall(new VirtualFullyQualified(['rand']), [new VirtualArg(new VirtualLNumber(0)), new VirtualArg(new VirtualLNumber(1))], $case->getAttributes());
            }
            $case_equality_expr = new VirtualBooleanOr($switch_scope->leftover_case_equality_expr, $case_or_default_equality_expr, $case_or_default_equality_expr->getAttributes());
        }
        if ($case_equality_expr && $switch_condition instanceof PhpParser\Node\Expr\Variable && is_string($switch_condition->name) && isset($context->vars_in_scope['$' . $switch_condition->name])) {
            $new_case_equality_expr = self::simplifyCaseEqualityExpression($case_equality_expr, $switch_condition);
            if ($new_case_equality_expr) {
                $was_inside_conditional = $case_context->inside_conditional;
                $case_context->inside_conditional = \true;
                ExpressionAnalyzer::analyze($statements_analyzer, $new_case_equality_expr->getArgs()[1]->value, $case_context);
                $case_context->inside_conditional = $was_inside_conditional;
                $case_equality_expr = $new_case_equality_expr;
            }
        }
        $case_context->break_types[] = 'switch';
        $switch_scope->leftover_statements = [];
        $switch_scope->leftover_case_equality_expr = null;
        $case_clauses = [];
        if ($case_equality_expr) {
            $case_equality_expr_id = spl_object_id($case_equality_expr);
            $case_clauses = FormulaGenerator::getFormula($case_equality_expr_id, $case_equality_expr_id, $case_equality_expr, $context->self, $statements_analyzer, $codebase, \false, \false);
        }
        if ($switch_scope->negated_clauses && count($switch_scope->negated_clauses) < 50) {
            $entry_clauses = Algebra::simplifyCNF([...$original_context->clauses, ...$switch_scope->negated_clauses]);
        } else {
            $entry_clauses = $original_context->clauses;
        }
        if ($case_clauses && $case->cond) {
            // this will see whether any of the clauses in set A conflict with the clauses in set B
            AlgebraAnalyzer::checkForParadox($entry_clauses, $case_clauses, $statements_analyzer, $case->cond, []);
            if (count($entry_clauses) + count($case_clauses) < 50) {
                $case_context->clauses = Algebra::simplifyCNF([...$entry_clauses, ...$case_clauses]);
            } else {
                $case_context->clauses = [...$entry_clauses, ...$case_clauses];
            }
        } else {
            $case_context->clauses = $entry_clauses;
        }
        $reconcilable_if_types = Algebra::getTruthsFromFormula($case_context->clauses);
        // if the if has an || in the conditional, we cannot easily reason about it
        if ($reconcilable_if_types) {
            $changed_var_ids = [];
            $suppressed_issues = $statements_analyzer->getSuppressedIssues();
            if (!in_array('RedundantCondition', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['RedundantCondition']);
            }
            if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, \true)) {
                $statements_analyzer->addSuppressedIssues(['RedundantConditionGivenDocblockType']);
            }
            [$case_vars_in_scope_reconciled, $case_references_in_scope_reconciled] = Reconciler::reconcileKeyedTypes($reconcilable_if_types, [], $case_context->vars_in_scope, $case_context->references_in_scope, $changed_var_ids, $case->cond && $switch_var_id ? [$switch_var_id => \true] : [], $statements_analyzer, [], $case_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $case->cond ?? $case, $context->include_location));
            if (!in_array('RedundantCondition', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['RedundantCondition']);
            }
            if (!in_array('RedundantConditionGivenDocblockType', $suppressed_issues, \true)) {
                $statements_analyzer->removeSuppressedIssues(['RedundantConditionGivenDocblockType']);
            }
            $case_context->vars_in_scope = $case_vars_in_scope_reconciled;
            $case_context->references_in_scope = $case_references_in_scope_reconciled;
            foreach ($reconcilable_if_types as $var_id => $_) {
                $case_context->vars_possibly_in_scope[$var_id] = \true;
            }
            if ($changed_var_ids) {
                $case_context->clauses = Context::removeReconciledClauses($case_context->clauses, $changed_var_ids)[0];
            }
        }
        if ($case_clauses && $case_equality_expr) {
            try {
                $negated_case_clauses = Algebra::negateFormula($case_clauses);
            } catch (ComplicatedExpressionException $e) {
                $case_equality_expr_id = spl_object_id($case_equality_expr);
                try {
                    $negated_case_clauses = FormulaGenerator::getFormula($case_equality_expr_id, $case_equality_expr_id, new VirtualBooleanNot($case_equality_expr), $context->self, $statements_analyzer, $codebase, \false, \false);
                } catch (ComplicatedExpressionException $e) {
                    $negated_case_clauses = [];
                }
            }
            $switch_scope->negated_clauses = [...$switch_scope->negated_clauses, ...$negated_case_clauses];
        }
        $statements_analyzer->analyze($case_stmts, $case_context);
        $traverser = new PhpParser\NodeTraverser();
        $traverser->addVisitor(new TypeMappingVisitor($statements_analyzer->node_data, $old_node_data));
        $traverser->traverse([$case]);
        $statements_analyzer->node_data = $old_node_data;
        if ($case_exit_type !== 'return_throw') {
            if (self::handleNonReturningCase($statements_analyzer, $switch_var_id, $case, $context, $case_context, $original_context, $case_exit_type, $switch_scope) === \false) {
                unset($case_scope->parent_context);
                unset($case_context->case_scope);
                return \false;
            }
        }
        // augment the information with data from break statements
        if ($case_scope->break_vars !== null) {
            if ($switch_scope->possibly_redefined_vars === null) {
                $switch_scope->possibly_redefined_vars = array_intersect_key($case_scope->break_vars, $context->vars_in_scope);
            } else {
                foreach ($case_scope->break_vars as $var_id => $type) {
                    if (isset($context->vars_in_scope[$var_id])) {
                        $switch_scope->possibly_redefined_vars[$var_id] = Type::combineUnionTypes($type, $switch_scope->possibly_redefined_vars[$var_id] ?? null);
                    }
                }
            }
            if ($switch_scope->new_vars_in_scope !== null) {
                foreach ($switch_scope->new_vars_in_scope as $var_id => $type) {
                    if (isset($case_scope->break_vars[$var_id])) {
                        if (!isset($case_context->vars_in_scope[$var_id])) {
                            unset($switch_scope->new_vars_in_scope[$var_id]);
                        } else {
                            $switch_scope->new_vars_in_scope[$var_id] = Type::combineUnionTypes($case_scope->break_vars[$var_id], $type);
                        }
                    } else {
                        unset($switch_scope->new_vars_in_scope[$var_id]);
                    }
                }
            }
            if ($switch_scope->redefined_vars !== null) {
                foreach ($switch_scope->redefined_vars as $var_id => $type) {
                    if (isset($case_scope->break_vars[$var_id])) {
                        $switch_scope->redefined_vars[$var_id] = Type::combineUnionTypes($case_scope->break_vars[$var_id], $type);
                    } else {
                        unset($switch_scope->redefined_vars[$var_id]);
                    }
                }
            }
        }
        unset($case_scope->parent_context);
        unset($case_context->case_scope);
        return null;
    }
    /**
     * @return null|false
     */
    private static function handleNonReturningCase(StatementsAnalyzer $statements_analyzer, ?string $switch_var_id, PhpParser\Node\Stmt\Case_ $case, Context $context, Context $case_context, Context $original_context, string $case_exit_type, SwitchScope $switch_scope) : ?bool
    {
        if (!$case->cond && $switch_var_id && isset($case_context->vars_in_scope[$switch_var_id]) && $case_context->vars_in_scope[$switch_var_id]->isNever()) {
            if (IssueBuffer::accepts(new ParadoxicalCondition('All possible case statements have been met, default is impossible here', new CodeLocation($statements_analyzer->getSource(), $case)), $statements_analyzer->getSuppressedIssues())) {
                return \false;
            }
        }
        // if we're leaving this block, add vars to outer for loop scope
        if ($case_exit_type === 'continue') {
            if (!$context->loop_scope) {
                if (IssueBuffer::accepts(new ContinueOutsideLoop('Continue called when not in loop', new CodeLocation($statements_analyzer->getSource(), $case)))) {
                    return \false;
                }
            }
        } else {
            $case_redefined_vars = $case_context->getRedefinedVars($original_context->vars_in_scope);
            if ($switch_scope->possibly_redefined_vars === null) {
                $switch_scope->possibly_redefined_vars = $case_redefined_vars;
            } else {
                foreach ($case_redefined_vars as $var_id => $type) {
                    $switch_scope->possibly_redefined_vars[$var_id] = Type::combineUnionTypes($type, $switch_scope->possibly_redefined_vars[$var_id] ?? null);
                }
            }
            if ($switch_scope->redefined_vars === null) {
                $switch_scope->redefined_vars = $case_redefined_vars;
            } else {
                foreach ($switch_scope->redefined_vars as $var_id => $type) {
                    if (!isset($case_redefined_vars[$var_id])) {
                        unset($switch_scope->redefined_vars[$var_id]);
                    } else {
                        $switch_scope->redefined_vars[$var_id] = Type::combineUnionTypes($type, $case_redefined_vars[$var_id]);
                    }
                }
            }
            $context_new_vars = array_diff_key($case_context->vars_in_scope, $context->vars_in_scope);
            if ($switch_scope->new_vars_in_scope === null) {
                $switch_scope->new_vars_in_scope = $context_new_vars;
                $switch_scope->new_vars_possibly_in_scope = array_diff_key($case_context->vars_possibly_in_scope, $context->vars_possibly_in_scope);
            } else {
                foreach ($switch_scope->new_vars_in_scope as $new_var => $type) {
                    if (!$case_context->hasVariable($new_var)) {
                        unset($switch_scope->new_vars_in_scope[$new_var]);
                    } else {
                        $switch_scope->new_vars_in_scope[$new_var] = Type::combineUnionTypes($case_context->vars_in_scope[$new_var], $type);
                    }
                }
                $switch_scope->new_vars_possibly_in_scope = array_merge(array_diff_key($case_context->vars_possibly_in_scope, $context->vars_possibly_in_scope), $switch_scope->new_vars_possibly_in_scope);
            }
        }
        if ($context->collect_exceptions) {
            $context->mergeExceptions($case_context);
        }
        return null;
    }
    private static function simplifyCaseEqualityExpression(PhpParser\Node\Expr $case_equality_expr, PhpParser\Node\Expr\Variable $var) : ?PhpParser\Node\Expr\FuncCall
    {
        if ($case_equality_expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
            $nested_or_options = self::getOptionsFromNestedOr($case_equality_expr, $var);
            if ($nested_or_options) {
                return new VirtualFuncCall(new VirtualFullyQualified(['in_array']), [new VirtualArg($var, \false, \false, $var->getAttributes()), new VirtualArg(new VirtualArray($nested_or_options, $case_equality_expr->getAttributes()), \false, \false, $case_equality_expr->getAttributes()), new VirtualArg(new VirtualConstFetch(new VirtualFullyQualified(['true'])))]);
            }
        }
        return null;
    }
    /**
     * @param array<PhpParser\Node\Expr\ArrayItem> $in_array_values
     * @return ?array<PhpParser\Node\Expr\ArrayItem>
     */
    private static function getOptionsFromNestedOr(PhpParser\Node\Expr $case_equality_expr, PhpParser\Node\Expr\Variable $var, array $in_array_values = []) : ?array
    {
        if ($case_equality_expr instanceof PhpParser\Node\Expr\BinaryOp\Identical && $case_equality_expr->left instanceof PhpParser\Node\Expr\Variable && $case_equality_expr->left->name === $var->name) {
            $in_array_values[] = new VirtualArrayItem($case_equality_expr->right, null, \false, $case_equality_expr->right->getAttributes());
            return $in_array_values;
        }
        if (!$case_equality_expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
            return null;
        }
        if (!$case_equality_expr->right instanceof PhpParser\Node\Expr\BinaryOp\Identical || !$case_equality_expr->right->left instanceof PhpParser\Node\Expr\Variable || $case_equality_expr->right->left->name !== $var->name) {
            return null;
        }
        $in_array_values[] = new VirtualArrayItem($case_equality_expr->right->right, null, \false, $case_equality_expr->right->right->getAttributes());
        return self::getOptionsFromNestedOr($case_equality_expr->left, $var, $in_array_values);
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\DocblockParseException;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ArrayFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\VariableFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Scope\LoopScope;
use Psalm\Internal\Type\Comparator\AtomicTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ImpureMethodCall;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\InvalidIterator;
use Psalm\Issue\NullIterator;
use Psalm\Issue\PossibleRawObjectIteration;
use Psalm\Issue\PossiblyFalseIterator;
use Psalm\Issue\PossiblyInvalidIterator;
use Psalm\Issue\PossiblyNullIterator;
use Psalm\Issue\RawObjectIteration;
use Psalm\Issue\UnnecessaryVarAnnotation;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualMethodCall;
use Psalm\Node\VirtualIdentifier;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TVoid;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_keys;
use function array_map;
use function array_merge;
use function array_search;
use function array_values;
use function assert;
use function in_array;
use function is_string;
use function reset;
use function strtolower;
/**
 * @internal
 */
class ForeachAnalyzer
{
    /**
     * @return  false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Foreach_ $stmt, Context $context) : ?bool
    {
        $var_comments = [];
        $doc_comment = $stmt->getDocComment();
        $codebase = $statements_analyzer->getCodebase();
        $file_path = $statements_analyzer->getRootFilePath();
        $type_aliases = $codebase->file_storage_provider->get($file_path)->type_aliases;
        if ($doc_comment) {
            try {
                $var_comments = CommentAnalyzer::getTypeFromComment($doc_comment, $statements_analyzer->getSource(), $statements_analyzer->getSource()->getAliases(), $statements_analyzer->getTemplateTypeMap() ?: [], $type_aliases);
            } catch (DocblockParseException $e) {
                IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer, $stmt)));
            }
        }
        $safe_var_ids = [];
        if ($stmt->keyVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->keyVar->name)) {
            $safe_var_ids['$' . $stmt->keyVar->name] = \true;
        }
        if ($stmt->valueVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->valueVar->name)) {
            $safe_var_ids['$' . $stmt->valueVar->name] = \true;
            $statements_analyzer->foreach_var_locations['$' . $stmt->valueVar->name][] = new CodeLocation($statements_analyzer, $stmt->valueVar);
        } elseif ($stmt->valueVar instanceof PhpParser\Node\Expr\List_) {
            foreach ($stmt->valueVar->items as $list_item) {
                if (!$list_item) {
                    continue;
                }
                $list_item_key = $list_item->key;
                $list_item_value = $list_item->value;
                if ($list_item_value instanceof PhpParser\Node\Expr\Variable && is_string($list_item_value->name)) {
                    $safe_var_ids['$' . $list_item_value->name] = \true;
                }
                if ($list_item_key instanceof PhpParser\Node\Expr\Variable && is_string($list_item_key->name)) {
                    $safe_var_ids['$' . $list_item_key->name] = \true;
                }
            }
        }
        foreach ($var_comments as $var_comment) {
            if (!$var_comment->var_id || !$var_comment->type) {
                continue;
            }
            if (isset($safe_var_ids[$var_comment->var_id])) {
                continue;
            }
            $comment_type = TypeExpander::expandUnion($codebase, $var_comment->type, $context->self, $context->self, $statements_analyzer->getParentFQCLN());
            $type_location = null;
            if ($var_comment->type_start && $var_comment->type_end && $var_comment->line_number) {
                $type_location = new DocblockTypeLocation($statements_analyzer, $var_comment->type_start, $var_comment->type_end, $var_comment->line_number);
                if ($codebase->alter_code) {
                    $codebase->classlikes->handleDocblockTypeInMigration($codebase, $statements_analyzer, $comment_type, $type_location, $context->calling_method_id);
                }
            }
            if (isset($context->vars_in_scope[$var_comment->var_id]) || VariableFetchAnalyzer::isSuperGlobal($var_comment->var_id)) {
                if ($codebase->find_unused_variables && $doc_comment && $type_location && isset($context->vars_in_scope[$var_comment->var_id]) && $context->vars_in_scope[$var_comment->var_id]->getId() === $comment_type->getId() && !$comment_type->isMixed()) {
                    $project_analyzer = $statements_analyzer->getProjectAnalyzer();
                    if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['UnnecessaryVarAnnotation'])) {
                        FileManipulationBuffer::addVarAnnotationToRemove($type_location);
                    } else {
                        IssueBuffer::maybeAdd(new UnnecessaryVarAnnotation('The @var ' . $comment_type . ' annotation for ' . $var_comment->var_id . ' is unnecessary', $type_location), $statements_analyzer->getSuppressedIssues(), \true);
                    }
                }
                if (isset($context->vars_in_scope[$var_comment->var_id])) {
                    /** @psalm-suppress InaccessibleProperty We just created this type */
                    $comment_type->parent_nodes = $context->vars_in_scope[$var_comment->var_id]->parent_nodes;
                }
                $context->vars_in_scope[$var_comment->var_id] = $comment_type;
            }
        }
        $was_inside_general_use = $context->inside_general_use;
        $context->inside_general_use = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
            $context->inside_general_use = $was_inside_general_use;
            return \false;
        }
        $context->inside_general_use = $was_inside_general_use;
        $key_type = null;
        $value_type = null;
        $always_non_empty_array = \true;
        $var_id = ExpressionIdentifier::getVarId($stmt->expr, $statements_analyzer->getFQCLN(), $statements_analyzer);
        if ($stmt_expr_type = $statements_analyzer->node_data->getType($stmt->expr)) {
            $iterator_type = $stmt_expr_type;
        } elseif ($var_id && $context->hasVariable($var_id)) {
            $iterator_type = $context->vars_in_scope[$var_id];
        } else {
            $iterator_type = null;
        }
        if ($iterator_type) {
            if (self::checkIteratorType($statements_analyzer, $stmt, $stmt->expr, $iterator_type, $codebase, $context, $key_type, $value_type, $always_non_empty_array) === \false) {
                return \false;
            }
        }
        $foreach_context = clone $context;
        foreach ($foreach_context->vars_in_scope as $context_var_id => $context_type) {
            $foreach_context->vars_in_scope[$context_var_id] = $context_type;
        }
        $foreach_context->inside_loop = \true;
        $foreach_context->break_types[] = 'loop';
        if ($codebase->alter_code) {
            $foreach_context->branch_point = $foreach_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
        }
        if ($stmt->keyVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->keyVar->name)) {
            $key_type ??= Type::getMixed();
            AssignmentAnalyzer::analyze($statements_analyzer, $stmt->keyVar, $stmt->expr, $key_type, $foreach_context, $doc_comment, ['$' . $stmt->keyVar->name => \true]);
        }
        if ($value_type !== null) {
            $value_type = $value_type->setProperties(['by_ref' => $stmt->byRef]);
        } else {
            $value_type = new Union([new TMixed()], ['by_ref' => $stmt->byRef]);
        }
        if ($stmt->byRef && $stmt->valueVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->valueVar->name)) {
            // When assigning as reference, it removes any previous
            // reference, so it's no longer from a previous confusing scope
            unset($foreach_context->references_possibly_from_confusing_scope['$' . $stmt->valueVar->name]);
        }
        AssignmentAnalyzer::analyze($statements_analyzer, $stmt->valueVar, $stmt->expr, $value_type, $foreach_context, $doc_comment, $stmt->valueVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->valueVar->name) ? ['$' . $stmt->valueVar->name => \true] : []);
        if ($stmt->byRef && $stmt->valueVar instanceof PhpParser\Node\Expr\Variable && is_string($stmt->valueVar->name)) {
            // TODO support references with destructuring
            $foreach_context->references_to_external_scope['$' . $stmt->valueVar->name] = \true;
        }
        foreach ($var_comments as $var_comment) {
            if (!$var_comment->var_id || !$var_comment->type) {
                continue;
            }
            $comment_type = TypeExpander::expandUnion($codebase, $var_comment->type, $context->self, $context->self, $statements_analyzer->getParentFQCLN());
            if (isset($foreach_context->vars_in_scope[$var_comment->var_id])) {
                $existing_var_type = $foreach_context->vars_in_scope[$var_comment->var_id];
                /** @psalm-suppress InaccessibleProperty We just created this type */
                $comment_type->parent_nodes = $existing_var_type->parent_nodes;
                /** @psalm-suppress InaccessibleProperty We just created this type */
                $comment_type->by_ref = $existing_var_type->by_ref;
            }
            $foreach_context->vars_in_scope[$var_comment->var_id] = $comment_type;
        }
        $loop_scope = new LoopScope($foreach_context, $context);
        $loop_scope->protected_var_ids = $context->protected_var_ids;
        if (\Psalm\Internal\Analyzer\Statements\Block\LoopAnalyzer::analyze($statements_analyzer, $stmt->stmts, [], [], $loop_scope, $inner_loop_context, \false, $always_non_empty_array) === \false) {
            return \false;
        }
        if (!$inner_loop_context) {
            throw new UnexpectedValueException('There should be an inner loop context');
        }
        $foreach_context->loop_scope = null;
        $context->vars_possibly_in_scope = array_merge($foreach_context->vars_possibly_in_scope, $context->vars_possibly_in_scope);
        if ($context->collect_exceptions) {
            $context->mergeExceptions($foreach_context);
        }
        return null;
    }
    /**
     * @param PhpParser\Node\Stmt\Foreach_|PhpParser\Node\Expr\YieldFrom $stmt
     * @return false|null
     */
    public static function checkIteratorType(StatementsAnalyzer $statements_analyzer, PhpParser\NodeAbstract $stmt, PhpParser\Node\Expr $expr, Union $iterator_type, Codebase $codebase, Context $context, ?Union &$key_type, ?Union &$value_type, bool &$always_non_empty_array) : ?bool
    {
        if ($iterator_type->isNull()) {
            IssueBuffer::maybeAdd(new NullIterator('Cannot iterate over null', new CodeLocation($statements_analyzer->getSource(), $expr)), $statements_analyzer->getSuppressedIssues());
            return \false;
        }
        if ($iterator_type->isNullable() && !$iterator_type->ignore_nullable_issues) {
            IssueBuffer::maybeAdd(new PossiblyNullIterator('Cannot iterate over nullable var ' . $iterator_type, new CodeLocation($statements_analyzer->getSource(), $expr)), $statements_analyzer->getSuppressedIssues());
            return null;
        }
        if ($iterator_type->isFalsable() && !$iterator_type->ignore_falsable_issues) {
            IssueBuffer::maybeAdd(new PossiblyFalseIterator('Cannot iterate over falsable var ' . $iterator_type, new CodeLocation($statements_analyzer->getSource(), $expr)), $statements_analyzer->getSuppressedIssues());
            return null;
        }
        $has_valid_iterator = \false;
        $invalid_iterator_types = [];
        $raw_object_types = [];
        foreach ($iterator_type->getAtomicTypes() as $iterator_atomic_type) {
            if ($iterator_atomic_type instanceof TTemplateParam) {
                $iterator_atomic_type = $iterator_atomic_type->as->getSingleAtomic();
            }
            // if it's an empty array, we cannot iterate over it
            if ($iterator_atomic_type instanceof TArray && $iterator_atomic_type->isEmptyArray()) {
                $always_non_empty_array = \false;
                $has_valid_iterator = \true;
                continue;
            }
            if ($iterator_atomic_type instanceof TNull || $iterator_atomic_type instanceof TFalse) {
                $always_non_empty_array = \false;
                continue;
            }
            if ($iterator_atomic_type instanceof TArray || $iterator_atomic_type instanceof TKeyedArray || $iterator_atomic_type instanceof TList) {
                if ($iterator_atomic_type instanceof TList) {
                    $iterator_atomic_type = $iterator_atomic_type->getKeyedArray();
                }
                if ($iterator_atomic_type instanceof TKeyedArray) {
                    if (!$iterator_atomic_type->isNonEmpty()) {
                        $always_non_empty_array = \false;
                    }
                    $iterator_atomic_type = $iterator_atomic_type->getGenericArrayType(\true, ExpressionIdentifier::getExtendedVarId($expr, $statements_analyzer->getFQCLN(), $statements_analyzer));
                } elseif (!$iterator_atomic_type instanceof TNonEmptyArray) {
                    $always_non_empty_array = \false;
                }
                $value_type = Type::combineUnionTypes($value_type, $iterator_atomic_type->type_params[1]);
                $key_type_part = $iterator_atomic_type->type_params[0];
                $key_type = Type::combineUnionTypes($key_type, $key_type_part);
                ArrayFetchAnalyzer::taintArrayFetch($statements_analyzer, $expr, null, $value_type, $key_type);
                $has_valid_iterator = \true;
                continue;
            }
            $always_non_empty_array = \false;
            if ($iterator_atomic_type instanceof Scalar || $iterator_atomic_type instanceof TVoid) {
                $invalid_iterator_types[] = $iterator_atomic_type->getKey();
                $value_type = Type::getMixed();
            } elseif ($iterator_atomic_type instanceof TObject || $iterator_atomic_type instanceof TMixed || $iterator_atomic_type instanceof TNever) {
                $has_valid_iterator = \true;
                $value_type = Type::getMixed();
                $key_type = Type::getMixed();
                ArrayFetchAnalyzer::taintArrayFetch($statements_analyzer, $expr, null, $value_type, $key_type);
                if (!$context->pure) {
                    if ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                        $statements_analyzer->getSource()->inferred_has_mutation = \true;
                        $statements_analyzer->getSource()->inferred_impure = \true;
                    }
                } else {
                    IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating iterator from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            } elseif ($iterator_atomic_type instanceof TIterable) {
                if ($iterator_atomic_type->extra_types) {
                    $iterator_atomic_types = array_merge([$iterator_atomic_type->setIntersectionTypes([])], $iterator_atomic_type->extra_types);
                } else {
                    $iterator_atomic_types = [$iterator_atomic_type];
                }
                $intersection_value_type = null;
                $intersection_key_type = null;
                foreach ($iterator_atomic_types as $iat) {
                    if (!$iat instanceof TIterable) {
                        continue;
                    }
                    [$key_type_part, $value_type_part] = $iat->type_params;
                    if (!$intersection_value_type) {
                        $intersection_value_type = $value_type_part;
                    } else {
                        $intersection_value_type = Type::intersectUnionTypes($intersection_value_type, $value_type_part, $codebase) ?? Type::getMixed();
                    }
                    if (!$intersection_key_type) {
                        $intersection_key_type = $key_type_part;
                    } else {
                        $intersection_key_type = Type::intersectUnionTypes($intersection_key_type, $key_type_part, $codebase) ?? Type::getMixed();
                    }
                }
                if (!$intersection_value_type || !$intersection_key_type) {
                    throw new UnexpectedValueException('Should not happen');
                }
                $value_type = Type::combineUnionTypes($value_type, $intersection_value_type);
                $key_type = Type::combineUnionTypes($key_type, $intersection_key_type);
                ArrayFetchAnalyzer::taintArrayFetch($statements_analyzer, $expr, null, $value_type, $key_type);
                $has_valid_iterator = \true;
                if (!$context->pure) {
                    if ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                        $statements_analyzer->getSource()->inferred_has_mutation = \true;
                        $statements_analyzer->getSource()->inferred_impure = \true;
                    }
                } else {
                    IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating Traversable::getIterator from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            } elseif ($iterator_atomic_type instanceof TNamedObject) {
                if ($iterator_atomic_type->value !== 'Traversable' && $iterator_atomic_type->value !== $statements_analyzer->getClassName()) {
                    if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $iterator_atomic_type->value, new CodeLocation($statements_analyzer->getSource(), $expr), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true)) === \false) {
                        return \false;
                    }
                }
                if (AtomicTypeComparator::isContainedBy($codebase, $iterator_atomic_type, new TIterable([Type::getMixed(), Type::getMixed()]))) {
                    self::handleIterable($statements_analyzer, $iterator_atomic_type, $expr, $codebase, $context, $key_type, $value_type, $has_valid_iterator);
                } else {
                    $raw_object_types[] = $iterator_atomic_type->value;
                }
                if (!$context->pure) {
                    if ($statements_analyzer->getSource() instanceof FunctionLikeAnalyzer && $statements_analyzer->getSource()->track_mutations) {
                        $statements_analyzer->getSource()->inferred_has_mutation = \true;
                        $statements_analyzer->getSource()->inferred_impure = \true;
                    }
                } else {
                    IssueBuffer::maybeAdd(new ImpureMethodCall('Cannot call a possibly-mutating iterator from a pure context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                }
            }
        }
        if ($raw_object_types) {
            if ($has_valid_iterator) {
                IssueBuffer::maybeAdd(new PossibleRawObjectIteration('Possibly undesired iteration over regular object ' . reset($raw_object_types), new CodeLocation($statements_analyzer->getSource(), $expr)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new RawObjectIteration('Possibly undesired iteration over regular object ' . reset($raw_object_types), new CodeLocation($statements_analyzer->getSource(), $expr)), $statements_analyzer->getSuppressedIssues());
            }
        }
        if ($invalid_iterator_types) {
            if ($has_valid_iterator) {
                IssueBuffer::maybeAdd(new PossiblyInvalidIterator('Cannot iterate over ' . $invalid_iterator_types[0], new CodeLocation($statements_analyzer->getSource(), $expr)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new InvalidIterator('Cannot iterate over ' . $invalid_iterator_types[0], new CodeLocation($statements_analyzer->getSource(), $expr)), $statements_analyzer->getSuppressedIssues());
            }
        }
        return null;
    }
    public static function handleIterable(StatementsAnalyzer $statements_analyzer, TNamedObject $iterator_atomic_type, PhpParser\Node\Expr $foreach_expr, Codebase $codebase, Context $context, ?Union &$key_type, ?Union &$value_type, bool &$has_valid_iterator) : void
    {
        if ($iterator_atomic_type->extra_types) {
            $iterator_atomic_types = array_merge([$iterator_atomic_type->setIntersectionTypes([])], $iterator_atomic_type->extra_types);
        } else {
            $iterator_atomic_types = [$iterator_atomic_type];
        }
        foreach ($iterator_atomic_types as $iterator_atomic_type) {
            if ($iterator_atomic_type instanceof TTemplateParam || $iterator_atomic_type instanceof TObjectWithProperties) {
                throw new UnexpectedValueException('Shouldn’t get a generic param here');
            }
            $has_valid_iterator = \true;
            if ($iterator_atomic_type instanceof TNamedObject && strtolower($iterator_atomic_type->value) === 'simplexmlelement') {
                $value_type = Type::combineUnionTypes($value_type, new Union([$iterator_atomic_type]));
                $key_type = Type::combineUnionTypes($key_type, Type::getString());
            }
            if ($iterator_atomic_type instanceof TIterable || (strtolower($iterator_atomic_type->value) === 'traversable' || $codebase->classImplements($iterator_atomic_type->value, 'Traversable') || $codebase->interfaceExists($iterator_atomic_type->value) && $codebase->interfaceExtends($iterator_atomic_type->value, 'Traversable'))) {
                if (strtolower($iterator_atomic_type->value) === 'iteratoraggregate' || $codebase->classImplements($iterator_atomic_type->value, 'IteratorAggregate') || $codebase->interfaceExists($iterator_atomic_type->value) && $codebase->interfaceExtends($iterator_atomic_type->value, 'IteratorAggregate')) {
                    $old_data_provider = $statements_analyzer->node_data;
                    $statements_analyzer->node_data = clone $statements_analyzer->node_data;
                    $fake_method_call = new VirtualMethodCall($foreach_expr, new VirtualIdentifier('getIterator', $foreach_expr->getAttributes()));
                    $suppressed_issues = $statements_analyzer->getSuppressedIssues();
                    if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
                        $statements_analyzer->addSuppressedIssues(['PossiblyInvalidMethodCall']);
                    }
                    if (!in_array('PossiblyUndefinedMethod', $suppressed_issues, \true)) {
                        $statements_analyzer->addSuppressedIssues(['PossiblyUndefinedMethod']);
                    }
                    $was_inside_call = $context->inside_call;
                    $context->inside_call = \true;
                    MethodCallAnalyzer::analyze($statements_analyzer, $fake_method_call, $context);
                    $context->inside_call = $was_inside_call;
                    if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
                        $statements_analyzer->removeSuppressedIssues(['PossiblyInvalidMethodCall']);
                    }
                    if (!in_array('PossiblyUndefinedMethod', $suppressed_issues, \true)) {
                        $statements_analyzer->removeSuppressedIssues(['PossiblyUndefinedMethod']);
                    }
                    $iterator_class_type = $statements_analyzer->node_data->getType($fake_method_call) ?? null;
                    $statements_analyzer->node_data = $old_data_provider;
                    if ($iterator_class_type) {
                        foreach ($iterator_class_type->getAtomicTypes() as $array_atomic_type) {
                            $key_type_part = null;
                            $value_type_part = null;
                            if ($array_atomic_type instanceof TArray || $array_atomic_type instanceof TKeyedArray) {
                                if ($array_atomic_type instanceof TKeyedArray) {
                                    $array_atomic_type = $array_atomic_type->getGenericArrayType();
                                }
                                [$key_type_part, $value_type_part] = $array_atomic_type->type_params;
                            } else {
                                if ($array_atomic_type instanceof TNamedObject && $codebase->classExists($array_atomic_type->value) && $codebase->classImplements($array_atomic_type->value, 'Traversable')) {
                                    $generic_storage = $codebase->classlike_storage_provider->get($array_atomic_type->value);
                                    // The collection might be an iterator, in which case
                                    // we want to call the iterator function
                                    /** @psalm-suppress PossiblyUndefinedStringArrayOffset */
                                    if (!isset($generic_storage->template_extended_params['Traversable']) || $generic_storage->template_extended_params['Traversable']['TKey']->isMixed() && $generic_storage->template_extended_params['Traversable']['TValue']->isMixed()) {
                                        self::handleIterable($statements_analyzer, $array_atomic_type, $fake_method_call, $codebase, $context, $key_type, $value_type, $has_valid_iterator);
                                        continue;
                                    }
                                }
                                if ($array_atomic_type instanceof TIterable || $array_atomic_type instanceof TNamedObject && ($array_atomic_type->value === 'Traversable' || $codebase->classOrInterfaceExists($array_atomic_type->value) && $codebase->classImplements($array_atomic_type->value, 'Traversable'))) {
                                    self::getKeyValueParamsForTraversableObject($array_atomic_type, $codebase, $key_type_part, $value_type_part);
                                }
                            }
                            if (!$key_type_part || !$value_type_part) {
                                break;
                            }
                            $key_type = Type::combineUnionTypes($key_type, $key_type_part);
                            $value_type = Type::combineUnionTypes($value_type, $value_type_part);
                        }
                    }
                } elseif ($codebase->classImplements($iterator_atomic_type->value, 'Iterator') || $codebase->interfaceExists($iterator_atomic_type->value) && $codebase->interfaceExtends($iterator_atomic_type->value, 'Iterator')) {
                    $iterator_value_type = self::getFakeMethodCallType($statements_analyzer, $foreach_expr, $context, 'current');
                    $iterator_key_type = self::getFakeMethodCallType($statements_analyzer, $foreach_expr, $context, 'key');
                    if ($iterator_value_type && !$iterator_value_type->isMixed()) {
                        $value_type = Type::combineUnionTypes($value_type, $iterator_value_type);
                    }
                    if ($iterator_key_type && !$iterator_key_type->isMixed()) {
                        $key_type = Type::combineUnionTypes($key_type, $iterator_key_type);
                    }
                }
                if (!$key_type && !$value_type) {
                    self::getKeyValueParamsForTraversableObject($iterator_atomic_type, $codebase, $key_type, $value_type);
                }
                return;
            }
            if (!$codebase->classlikes->classOrInterfaceExists($iterator_atomic_type->value)) {
                return;
            }
        }
    }
    public static function getKeyValueParamsForTraversableObject(Atomic $iterator_atomic_type, Codebase $codebase, ?Union &$key_type, ?Union &$value_type) : void
    {
        if ($iterator_atomic_type instanceof TIterable || $iterator_atomic_type instanceof TGenericObject && strtolower($iterator_atomic_type->value) === 'traversable') {
            assert(isset($iterator_atomic_type->type_params[1]));
            $value_type = Type::combineUnionTypes($value_type, $iterator_atomic_type->type_params[1]);
            $key_type = Type::combineUnionTypes($key_type, $iterator_atomic_type->type_params[0]);
            return;
        }
        if ($iterator_atomic_type instanceof TNamedObject && ($codebase->classImplements($iterator_atomic_type->value, 'Traversable') || $codebase->interfaceExtends($iterator_atomic_type->value, 'Traversable'))) {
            $generic_storage = $codebase->classlike_storage_provider->get($iterator_atomic_type->value);
            if (!isset($generic_storage->template_extended_params['Traversable'])) {
                return;
            }
            if ($generic_storage->template_types || $iterator_atomic_type instanceof TGenericObject) {
                // if we're just being passed the non-generic class itself, assume
                // that it's inside the calling class
                $passed_type_params = $iterator_atomic_type instanceof TGenericObject ? $iterator_atomic_type->type_params : array_values(array_map(
                    /** @param array<string, Union> $arr */
                    static fn(array $arr): Union => $arr[$iterator_atomic_type->value] ?? Type::getMixed(),
                    $generic_storage->template_types
                ));
            } else {
                $passed_type_params = null;
            }
            $key_type = self::getExtendedType('TKey', 'Traversable', $generic_storage->name, $generic_storage->template_extended_params, $generic_storage->template_types, $passed_type_params);
            $value_type = self::getExtendedType('TValue', 'Traversable', $generic_storage->name, $generic_storage->template_extended_params, $generic_storage->template_types, $passed_type_params);
            return;
        }
    }
    private static function getFakeMethodCallType(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $foreach_expr, Context $context, string $method_name) : ?Union
    {
        $old_data_provider = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $statements_analyzer->node_data;
        $fake_method_call = new VirtualMethodCall($foreach_expr, new VirtualIdentifier($method_name, $foreach_expr->getAttributes()));
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['PossiblyInvalidMethodCall']);
        }
        if (!in_array('PossiblyUndefinedMethod', $suppressed_issues, \true)) {
            $statements_analyzer->addSuppressedIssues(['PossiblyUndefinedMethod']);
        }
        $was_inside_call = $context->inside_call;
        $context->inside_call = \true;
        MethodCallAnalyzer::analyze($statements_analyzer, $fake_method_call, $context);
        $context->inside_call = $was_inside_call;
        if (!in_array('PossiblyInvalidMethodCall', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['PossiblyInvalidMethodCall']);
        }
        if (!in_array('PossiblyUndefinedMethod', $suppressed_issues, \true)) {
            $statements_analyzer->removeSuppressedIssues(['PossiblyUndefinedMethod']);
        }
        $iterator_class_type = $statements_analyzer->node_data->getType($fake_method_call) ?? null;
        $statements_analyzer->node_data = $old_data_provider;
        return $iterator_class_type;
    }
    /**
     * @param  array<string, array<string, Union>>  $template_extended_params
     * @param  array<string, array<string, Union>>  $class_template_types
     * @param  array<int, Union> $calling_type_params
     */
    private static function getExtendedType(string $template_name, string $template_class, string $calling_class, array $template_extended_params, ?array $class_template_types = null, ?array $calling_type_params = null) : ?Union
    {
        if ($calling_class === $template_class) {
            if (isset($class_template_types[$template_name]) && $calling_type_params) {
                $offset = array_search($template_name, array_keys($class_template_types));
                if ($offset !== \false && isset($calling_type_params[$offset])) {
                    return $calling_type_params[$offset];
                }
            }
            return null;
        }
        if (isset($template_extended_params[$template_class][$template_name])) {
            $extended_type = $template_extended_params[$template_class][$template_name];
            $return_type = null;
            foreach ($extended_type->getAtomicTypes() as $extended_atomic_type) {
                if (!$extended_atomic_type instanceof TTemplateParam) {
                    $return_type = Type::combineUnionTypes($return_type, $extended_type);
                    continue;
                }
                $candidate_type = self::getExtendedType($extended_atomic_type->param_name, $extended_atomic_type->defining_class, $calling_class, $template_extended_params, $class_template_types, $calling_type_params);
                if ($candidate_type) {
                    $return_type = Type::combineUnionTypes($return_type, $candidate_type);
                }
            }
            if ($return_type) {
                return $return_type;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\PhpVisitor\AssignmentMapVisitor;
use Psalm\Internal\PhpVisitor\NodeCleanerVisitor;
use Psalm\Internal\Scope\LoopScope;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Reconciler;
use function array_keys;
use function array_merge;
use function array_unique;
use function in_array;
use function spl_object_id;
/**
 * @internal
 */
class LoopAnalyzer
{
    /**
     * Checks an array of statements in a loop
     *
     * @param  list<PhpParser\Node\Stmt>    $stmts
     * @param  list<PhpParser\Node\Expr>    $pre_conditions
     * @param  PhpParser\Node\Expr[]        $post_expressions
     * @return false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, array $stmts, array $pre_conditions, array $post_expressions, LoopScope $loop_scope, Context &$continue_context = null, bool $is_do = \false, bool $always_enters_loop = \false) : ?bool
    {
        $traverser = new PhpParser\NodeTraverser();
        $loop_context = $loop_scope->loop_context;
        $loop_parent_context = $loop_scope->loop_parent_context;
        $assignment_mapper = new AssignmentMapVisitor($loop_context->self);
        $traverser->addVisitor($assignment_mapper);
        $traverser->traverse(array_merge($pre_conditions, $stmts, $post_expressions));
        $assignment_map = $assignment_mapper->getAssignmentMap();
        $assignment_depth = 0;
        $always_assigned_before_loop_body_vars = [];
        $pre_condition_clauses = [];
        $original_protected_var_ids = $loop_parent_context->protected_var_ids;
        $codebase = $statements_analyzer->getCodebase();
        $inner_do_context = null;
        if ($pre_conditions) {
            foreach ($pre_conditions as $i => $pre_condition) {
                $pre_condition_id = spl_object_id($pre_condition);
                $pre_condition_clauses[$i] = FormulaGenerator::getFormula($pre_condition_id, $pre_condition_id, $pre_condition, $loop_context->self, $statements_analyzer, $codebase);
            }
        } else {
            $always_assigned_before_loop_body_vars = Context::getNewOrUpdatedVarIds($loop_parent_context, $loop_context);
        }
        $final_actions = ScopeAnalyzer::getControlActions($stmts, $statements_analyzer->node_data, []);
        $does_always_break = $final_actions === [ScopeAnalyzer::ACTION_BREAK];
        if ($assignment_map) {
            $first_var_id = array_keys($assignment_map)[0];
            $assignment_depth = self::getAssignmentMapDepth($first_var_id, $assignment_map);
        }
        if ($assignment_depth === 0 || $does_always_break) {
            $continue_context = clone $loop_context;
            foreach ($continue_context->vars_in_scope as $context_var_id => $context_type) {
                $continue_context->vars_in_scope[$context_var_id] = $context_type;
            }
            $continue_context->loop_scope = $loop_scope;
            foreach ($pre_conditions as $condition_offset => $pre_condition) {
                self::applyPreConditionToLoopContext($statements_analyzer, $pre_condition, $pre_condition_clauses[$condition_offset], $continue_context, $loop_parent_context, $is_do);
            }
            $continue_context->protected_var_ids = $loop_scope->protected_var_ids;
            $statements_analyzer->analyze($stmts, $continue_context);
            self::updateLoopScopeContexts($loop_scope, $loop_context, $continue_context, $loop_parent_context);
            foreach ($post_expressions as $post_expression) {
                if (ExpressionAnalyzer::analyze($statements_analyzer, $post_expression, $loop_context) === \false) {
                    return \false;
                }
            }
            $loop_parent_context->vars_possibly_in_scope = array_merge($continue_context->vars_possibly_in_scope, $loop_parent_context->vars_possibly_in_scope);
        } else {
            $original_parent_context = clone $loop_parent_context;
            $analyzer = $statements_analyzer->getCodebase()->analyzer;
            $original_mixed_counts = $analyzer->getMixedCountsForFile($statements_analyzer->getFilePath());
            // record all the vars that existed before we did the first pass through the loop
            $pre_loop_context = clone $loop_context;
            IssueBuffer::startRecording();
            if (!$is_do) {
                foreach ($pre_conditions as $condition_offset => $pre_condition) {
                    self::applyPreConditionToLoopContext($statements_analyzer, $pre_condition, $pre_condition_clauses[$condition_offset], $loop_context, $loop_parent_context, $is_do);
                }
            }
            $continue_context = clone $loop_context;
            $continue_context->loop_scope = $loop_scope;
            $continue_context->protected_var_ids = $loop_scope->protected_var_ids;
            $statements_analyzer->analyze($stmts, $continue_context);
            self::updateLoopScopeContexts($loop_scope, $loop_context, $continue_context, $original_parent_context);
            $continue_context->protected_var_ids = $original_protected_var_ids;
            if ($is_do) {
                $inner_do_context = clone $continue_context;
                foreach ($pre_conditions as $condition_offset => $pre_condition) {
                    $always_assigned_before_loop_body_vars = [...self::applyPreConditionToLoopContext($statements_analyzer, $pre_condition, $pre_condition_clauses[$condition_offset], $continue_context, $loop_parent_context, $is_do), ...$always_assigned_before_loop_body_vars];
                }
            }
            $always_assigned_before_loop_body_vars = array_unique($always_assigned_before_loop_body_vars);
            foreach ($post_expressions as $post_expression) {
                if (ExpressionAnalyzer::analyze($statements_analyzer, $post_expression, $continue_context) === \false) {
                    return \false;
                }
            }
            $recorded_issues = IssueBuffer::clearRecordingLevel();
            IssueBuffer::stopRecording();
            for ($i = 0; $i < $assignment_depth; ++$i) {
                $vars_to_remove = [];
                $loop_scope->iteration_count++;
                $has_changes = \false;
                // reset the $continue_context to what it was before we started the analysis,
                // but union the types with what's in the loop scope
                foreach ($continue_context->vars_in_scope as $var_id => $type) {
                    if (in_array($var_id, $always_assigned_before_loop_body_vars, \true)) {
                        // set the vars to whatever the while/foreach loop expects them to be
                        if (!isset($pre_loop_context->vars_in_scope[$var_id]) || !$type->equals($pre_loop_context->vars_in_scope[$var_id])) {
                            $has_changes = \true;
                        }
                    } elseif (isset($original_parent_context->vars_in_scope[$var_id])) {
                        if (!$type->equals($original_parent_context->vars_in_scope[$var_id])) {
                            $has_changes = \true;
                            // widen the foreach context type with the initial context type
                            $continue_context->vars_in_scope[$var_id] = Type::combineUnionTypes($continue_context->vars_in_scope[$var_id], $original_parent_context->vars_in_scope[$var_id]);
                            // if there's a change, invalidate related clauses
                            $pre_loop_context->removeVarFromConflictingClauses($var_id);
                            $loop_parent_context->possibly_assigned_var_ids[$var_id] = \true;
                        }
                        if (isset($loop_context->vars_in_scope[$var_id]) && !$type->equals($loop_context->vars_in_scope[$var_id])) {
                            $has_changes = \true;
                            // widen the foreach context type with the initial context type
                            $continue_context->vars_in_scope[$var_id] = Type::combineUnionTypes($continue_context->vars_in_scope[$var_id], $loop_context->vars_in_scope[$var_id]);
                            // if there's a change, invalidate related clauses
                            $pre_loop_context->removeVarFromConflictingClauses($var_id);
                        }
                    } else {
                        // give an opportunity to redeemed UndefinedVariable issues
                        if ($recorded_issues) {
                            $has_changes = \true;
                        }
                        // if we're in a do block we don't want to remove vars before evaluating
                        // the where conditional
                        if (!$is_do) {
                            $vars_to_remove[] = $var_id;
                        }
                    }
                }
                $continue_context->has_returned = \false;
                $loop_parent_context->vars_possibly_in_scope = array_merge($continue_context->vars_possibly_in_scope, $loop_parent_context->vars_possibly_in_scope);
                // if there are no changes to the types, no need to re-examine
                if (!$has_changes) {
                    break;
                }
                // remove vars that were defined in the foreach
                foreach ($vars_to_remove as $var_id) {
                    $continue_context->removePossibleReference($var_id);
                }
                $continue_context->clauses = $pre_loop_context->clauses;
                $continue_context->byref_constraints = $pre_loop_context->byref_constraints;
                $analyzer->setMixedCountsForFile($statements_analyzer->getFilePath(), $original_mixed_counts);
                IssueBuffer::startRecording();
                if (!$is_do) {
                    foreach ($pre_conditions as $condition_offset => $pre_condition) {
                        self::applyPreConditionToLoopContext($statements_analyzer, $pre_condition, $pre_condition_clauses[$condition_offset], $continue_context, $loop_parent_context, \false);
                    }
                }
                foreach ($always_assigned_before_loop_body_vars as $var_id) {
                    if (!isset($continue_context->vars_in_scope[$var_id]) || $continue_context->vars_in_scope[$var_id]->getId() !== $pre_loop_context->vars_in_scope[$var_id]->getId() || $continue_context->vars_in_scope[$var_id]->from_docblock !== $pre_loop_context->vars_in_scope[$var_id]->from_docblock) {
                        if (isset($pre_loop_context->vars_in_scope[$var_id])) {
                            $continue_context->vars_in_scope[$var_id] = $pre_loop_context->vars_in_scope[$var_id];
                        } else {
                            $continue_context->removePossibleReference($var_id);
                        }
                    }
                }
                $continue_context->clauses = $pre_loop_context->clauses;
                $continue_context->protected_var_ids = $loop_scope->protected_var_ids;
                $traverser = new PhpParser\NodeTraverser();
                $traverser->addVisitor(new NodeCleanerVisitor($statements_analyzer->node_data));
                $traverser->traverse($stmts);
                $statements_analyzer->analyze($stmts, $continue_context);
                self::updateLoopScopeContexts($loop_scope, $loop_context, $continue_context, $original_parent_context);
                $continue_context->protected_var_ids = $original_protected_var_ids;
                if ($is_do) {
                    $inner_do_context = clone $continue_context;
                    foreach ($pre_conditions as $condition_offset => $pre_condition) {
                        self::applyPreConditionToLoopContext($statements_analyzer, $pre_condition, $pre_condition_clauses[$condition_offset], $continue_context, $loop_parent_context, $is_do);
                    }
                }
                foreach ($post_expressions as $post_expression) {
                    if (ExpressionAnalyzer::analyze($statements_analyzer, $post_expression, $continue_context) === \false) {
                        return \false;
                    }
                }
                $recorded_issues = IssueBuffer::clearRecordingLevel();
                IssueBuffer::stopRecording();
            }
            if ($recorded_issues) {
                foreach ($recorded_issues as $recorded_issue) {
                    // if we're not in any loops then this will just result in the issue being emitted
                    IssueBuffer::bubbleUp($recorded_issue);
                }
            }
        }
        $does_sometimes_break = in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, \true);
        $does_always_break = $loop_scope->final_actions === [ScopeAnalyzer::ACTION_BREAK];
        if ($does_sometimes_break) {
            foreach ($loop_scope->possibly_redefined_loop_parent_vars as $var => $type) {
                $loop_parent_context->vars_in_scope[$var] = Type::combineUnionTypes($type, $loop_parent_context->vars_in_scope[$var]);
                $loop_parent_context->possibly_assigned_var_ids[$var] = \true;
            }
        }
        foreach ($loop_parent_context->vars_in_scope as $var_id => $type) {
            if (!isset($loop_context->vars_in_scope[$var_id])) {
                continue;
            }
            if ($loop_context->vars_in_scope[$var_id]->getId() !== $type->getId()) {
                $loop_parent_context->vars_in_scope[$var_id] = Type::combineUnionTypes($loop_parent_context->vars_in_scope[$var_id], $loop_context->vars_in_scope[$var_id]);
                $loop_parent_context->removeVarFromConflictingClauses($var_id);
            } else {
                $loop_parent_context->vars_in_scope[$var_id] = $loop_parent_context->vars_in_scope[$var_id]->addParentNodes($loop_context->vars_in_scope[$var_id]->parent_nodes);
            }
        }
        if (!$does_always_break) {
            foreach ($loop_parent_context->vars_in_scope as $var_id => $type) {
                if (!isset($continue_context->vars_in_scope[$var_id])) {
                    $loop_parent_context->removePossibleReference($var_id);
                    continue;
                }
                if ($continue_context->vars_in_scope[$var_id]->hasMixed()) {
                    $continue_context->vars_in_scope[$var_id] = $continue_context->vars_in_scope[$var_id]->addParentNodes($loop_parent_context->vars_in_scope[$var_id]->parent_nodes);
                    $loop_parent_context->vars_in_scope[$var_id] = $continue_context->vars_in_scope[$var_id];
                    $loop_parent_context->removeVarFromConflictingClauses($var_id);
                    continue;
                }
                if ($continue_context->vars_in_scope[$var_id]->getId() !== $type->getId()) {
                    $loop_parent_context->vars_in_scope[$var_id] = Type::combineUnionTypes($loop_parent_context->vars_in_scope[$var_id], $continue_context->vars_in_scope[$var_id]);
                    $loop_parent_context->removeVarFromConflictingClauses($var_id);
                } else {
                    $loop_parent_context->vars_in_scope[$var_id] = $loop_parent_context->vars_in_scope[$var_id]->setParentNodes(array_merge($loop_parent_context->vars_in_scope[$var_id]->parent_nodes, $continue_context->vars_in_scope[$var_id]->parent_nodes));
                }
            }
        }
        if ($pre_conditions && $pre_condition_clauses && !$does_sometimes_break) {
            // if the loop contains an assertion and there are no break statements, we can negate that assertion
            // and apply it to the current context
            try {
                $negated_pre_condition_clauses = Algebra::negateFormula(array_merge(...$pre_condition_clauses));
            } catch (ComplicatedExpressionException $e) {
                $negated_pre_condition_clauses = [];
            }
            $negated_pre_condition_types = Algebra::getTruthsFromFormula($negated_pre_condition_clauses);
            if ($negated_pre_condition_types) {
                $changed_var_ids = [];
                [$vars_in_scope_reconciled, $_] = Reconciler::reconcileKeyedTypes($negated_pre_condition_types, [], $continue_context->vars_in_scope, $continue_context->references_in_scope, $changed_var_ids, [], $statements_analyzer, [], \true, new CodeLocation($statements_analyzer->getSource(), $pre_conditions[0]));
                foreach ($changed_var_ids as $var_id => $_) {
                    if (isset($vars_in_scope_reconciled[$var_id]) && isset($loop_parent_context->vars_in_scope[$var_id])) {
                        $loop_parent_context->vars_in_scope[$var_id] = $vars_in_scope_reconciled[$var_id];
                    }
                    $loop_parent_context->removeVarFromConflictingClauses($var_id);
                }
            }
        }
        if ($always_enters_loop) {
            foreach ($continue_context->vars_in_scope as $var_id => $type) {
                // if there are break statements in the loop it's not certain
                // that the loop has finished executing, so the assertions at the end
                // the loop in the while conditional may not hold
                if (in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, \true) || in_array(ScopeAnalyzer::ACTION_CONTINUE, $loop_scope->final_actions, \true)) {
                    if (isset($loop_scope->possibly_defined_loop_parent_vars[$var_id])) {
                        $loop_parent_context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $loop_scope->possibly_defined_loop_parent_vars[$var_id]);
                    }
                } else {
                    $loop_parent_context->vars_in_scope[$var_id] = $type;
                }
            }
        }
        if ($inner_do_context) {
            $continue_context = $inner_do_context;
        }
        // Track references set in the loop to make sure they aren't reused later
        $loop_parent_context->updateReferencesPossiblyFromConfusingScope($continue_context, $statements_analyzer);
        return null;
    }
    private static function updateLoopScopeContexts(LoopScope $loop_scope, Context $loop_context, Context $continue_context, Context $pre_outer_context) : void
    {
        if (!in_array(ScopeAnalyzer::ACTION_CONTINUE, $loop_scope->final_actions, \true)) {
            $loop_context->vars_in_scope = $pre_outer_context->vars_in_scope;
        } else {
            $updated_loop_vars = [];
            foreach ($loop_scope->redefined_loop_vars as $var => $type) {
                $continue_context->vars_in_scope[$var] = $type;
                $updated_loop_vars[$var] = \true;
            }
            foreach ($loop_scope->possibly_redefined_loop_vars as $var => $type) {
                if ($continue_context->hasVariable($var)) {
                    if (!isset($updated_loop_vars[$var])) {
                        $continue_context->vars_in_scope[$var] = Type::combineUnionTypes($continue_context->vars_in_scope[$var], $type);
                    } else {
                        $continue_context->vars_in_scope[$var] = $continue_context->vars_in_scope[$var]->addParentNodes($type->parent_nodes);
                    }
                }
            }
        }
        // merge vars possibly in scope at the end of each loop
        $loop_context->vars_possibly_in_scope = array_merge($loop_context->vars_possibly_in_scope, $loop_scope->vars_possibly_in_scope);
    }
    /**
     * @param  list<Clause>  $pre_condition_clauses
     * @return list<string>
     */
    private static function applyPreConditionToLoopContext(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $pre_condition, array $pre_condition_clauses, Context $loop_context, Context $outer_context, bool $is_do) : array
    {
        $pre_referenced_var_ids = $loop_context->cond_referenced_var_ids;
        $loop_context->cond_referenced_var_ids = [];
        $was_inside_conditional = $loop_context->inside_conditional;
        $loop_context->inside_conditional = \true;
        if (ExpressionAnalyzer::analyze($statements_analyzer, $pre_condition, $loop_context) === \false) {
            $loop_context->inside_conditional = $was_inside_conditional;
            return [];
        }
        $loop_context->inside_conditional = $was_inside_conditional;
        $new_referenced_var_ids = $loop_context->cond_referenced_var_ids;
        $loop_context->cond_referenced_var_ids = array_merge($pre_referenced_var_ids, $new_referenced_var_ids);
        $always_assigned_before_loop_body_vars = Context::getNewOrUpdatedVarIds($outer_context, $loop_context);
        $loop_context->clauses = Algebra::simplifyCNF([...$outer_context->clauses, ...$pre_condition_clauses]);
        $active_while_types = [];
        $reconcilable_while_types = Algebra::getTruthsFromFormula($loop_context->clauses, spl_object_id($pre_condition), $new_referenced_var_ids, $active_while_types);
        $changed_var_ids = [];
        if ($reconcilable_while_types) {
            [$loop_context->vars_in_scope, $loop_context->references_in_scope] = Reconciler::reconcileKeyedTypes($reconcilable_while_types, $active_while_types, $loop_context->vars_in_scope, $loop_context->references_in_scope, $changed_var_ids, $new_referenced_var_ids, $statements_analyzer, [], \true, new CodeLocation($statements_analyzer->getSource(), $pre_condition));
        }
        if ($is_do) {
            return [];
        }
        foreach ($always_assigned_before_loop_body_vars as $var_id) {
            $loop_context->clauses = Context::filterClauses($var_id, $loop_context->clauses, null, $statements_analyzer);
        }
        return $always_assigned_before_loop_body_vars;
    }
    /**
     * @param  array<string, array<string, bool>>   $assignment_map
     */
    private static function getAssignmentMapDepth(string $first_var_id, array $assignment_map) : int
    {
        $max_depth = 0;
        $assignment_var_ids = $assignment_map[$first_var_id];
        unset($assignment_map[$first_var_id]);
        foreach ($assignment_var_ids as $assignment_var_id => $_) {
            $depth = 1;
            if (isset($assignment_map[$assignment_var_id])) {
                $depth = 1 + self::getAssignmentMapDepth($assignment_var_id, $assignment_map);
            }
            if ($depth > $max_depth) {
                $max_depth = $depth;
            }
        }
        return $max_depth;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Scope\FinallyScope;
use Psalm\Issue\InvalidCatch;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_intersect_key;
use function array_map;
use function array_merge;
use function in_array;
use function is_string;
use function strtolower;
use function version_compare;
use const PHP_VERSION;
/**
 * @internal
 */
class TryAnalyzer
{
    /**
     * @return  false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\TryCatch $stmt, Context $context) : ?bool
    {
        $catch_actions = [];
        $all_catches_leave = \true;
        $codebase = $statements_analyzer->getCodebase();
        /** @var int $i */
        foreach ($stmt->catches as $i => $catch) {
            $catch_actions[$i] = ScopeAnalyzer::getControlActions($catch->stmts, $statements_analyzer->node_data, []);
            $all_catches_leave = $all_catches_leave && !in_array(ScopeAnalyzer::ACTION_NONE, $catch_actions[$i], \true);
        }
        $existing_thrown_exceptions = $context->possibly_thrown_exceptions;
        /**
         * @var array<string, array<array-key, CodeLocation>> $context->possibly_thrown_exceptions
         */
        $context->possibly_thrown_exceptions = [];
        $old_context = clone $context;
        $try_context = clone $context;
        if ($codebase->alter_code) {
            $try_context->branch_point = $try_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
        }
        if ($stmt->finally) {
            $try_context->finally_scope = new FinallyScope($try_context->vars_in_scope);
        }
        $assigned_var_ids = $try_context->assigned_var_ids;
        $context->assigned_var_ids = [];
        $was_inside_try = $context->inside_try;
        $context->inside_try = \true;
        if ($statements_analyzer->analyze($stmt->stmts, $context) === \false) {
            return \false;
        }
        $context->inside_try = $was_inside_try;
        $context->has_returned = \false;
        $try_block_control_actions = ScopeAnalyzer::getControlActions($stmt->stmts, $statements_analyzer->node_data, []);
        /** @var array<string, int> */
        $newly_assigned_var_ids = $context->assigned_var_ids;
        $context->assigned_var_ids = array_merge($assigned_var_ids, $newly_assigned_var_ids);
        foreach ($context->vars_in_scope as $var_id => $type) {
            if (!isset($try_context->vars_in_scope[$var_id])) {
                $try_context->vars_in_scope[$var_id] = $type;
                $context->vars_in_scope[$var_id] = $type->setPossiblyUndefined(\true, \true);
            } else {
                $try_context->vars_in_scope[$var_id] = Type::combineUnionTypes($try_context->vars_in_scope[$var_id], $type);
            }
        }
        if ($try_context->finally_scope) {
            foreach ($context->vars_in_scope as $var_id => $type) {
                $try_context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes($try_context->finally_scope->vars_in_scope[$var_id] ?? null, $type, $statements_analyzer->getCodebase());
            }
        }
        $try_context->vars_possibly_in_scope = $context->vars_possibly_in_scope;
        $try_context->possibly_thrown_exceptions = $context->possibly_thrown_exceptions;
        $try_leaves_loop = $context->loop_scope && $context->loop_scope->final_actions && !in_array(ScopeAnalyzer::ACTION_NONE, $context->loop_scope->final_actions, \true);
        if (!$all_catches_leave) {
            foreach ($newly_assigned_var_ids as $assigned_var_id => $_) {
                $context->removeVarFromConflictingClauses($assigned_var_id);
            }
        } else {
            foreach ($newly_assigned_var_ids as $assigned_var_id => $_) {
                $try_context->removeVarFromConflictingClauses($assigned_var_id);
            }
        }
        // at this point we have two contexts – $context, in which it is assumed that everything was fine,
        // and $try_context - which allows all variables to have the union of the values before and after
        // the try was applied
        $original_context = clone $try_context;
        $issues_to_suppress = ['RedundantCondition', 'RedundantConditionGivenDocblockType', 'TypeDoesNotContainNull', 'TypeDoesNotContainType'];
        $definitely_newly_assigned_var_ids = $newly_assigned_var_ids;
        /** @var int $i */
        foreach ($stmt->catches as $i => $catch) {
            $catch_context = clone $original_context;
            $catch_context->has_returned = \false;
            foreach ($catch_context->vars_in_scope as $var_id => $type) {
                if (!isset($old_context->vars_in_scope[$var_id])) {
                    $catch_context->vars_in_scope[$var_id] = $type->setPossiblyUndefined($catch_context->vars_in_scope[$var_id]->possibly_undefined, \true);
                } else {
                    $catch_context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $old_context->vars_in_scope[$var_id]);
                }
            }
            $fq_catch_classes = [];
            if (!$catch->types) {
                throw new UnexpectedValueException('Very bad');
            }
            foreach ($catch->types as $catch_type) {
                $fq_catch_class = ClassLikeAnalyzer::getFQCLNFromNameObject($catch_type, $statements_analyzer->getAliases());
                $fq_catch_class = $codebase->classlikes->getUnAliasedName($fq_catch_class);
                if ($codebase->alter_code && $fq_catch_class) {
                    $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $statements_analyzer, $catch_type, $fq_catch_class, $context->calling_method_id);
                }
                if ($original_context->check_classes) {
                    ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $fq_catch_class, new CodeLocation($statements_analyzer->getSource(), $catch_type, $context->include_location), $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new ClassLikeNameOptions(\true));
                }
                if ($codebase->classExists($fq_catch_class) && strtolower($fq_catch_class) !== 'exception' && !($codebase->classExtends($fq_catch_class, 'Exception') || $codebase->classImplements($fq_catch_class, 'Throwable')) || $codebase->interfaceExists($fq_catch_class) && strtolower($fq_catch_class) !== 'throwable' && !$codebase->interfaceExtends($fq_catch_class, 'Throwable')) {
                    IssueBuffer::maybeAdd(new InvalidCatch('Class/interface ' . $fq_catch_class . ' cannot be caught', new CodeLocation($statements_analyzer->getSource(), $stmt), $fq_catch_class), $statements_analyzer->getSuppressedIssues());
                }
                $fq_catch_classes[] = $fq_catch_class;
            }
            if ($catch_context->collect_exceptions) {
                foreach ($fq_catch_classes as $fq_catch_class) {
                    $fq_catch_class_lower = strtolower($fq_catch_class);
                    foreach ($catch_context->possibly_thrown_exceptions as $exception_fqcln => $_) {
                        $exception_fqcln_lower = strtolower($exception_fqcln);
                        if ($exception_fqcln_lower === $fq_catch_class_lower || $codebase->classExists($exception_fqcln) && $codebase->classExtendsOrImplements($exception_fqcln, $fq_catch_class) || $codebase->interfaceExists($exception_fqcln) && $codebase->interfaceExtends($exception_fqcln, $fq_catch_class)) {
                            unset($original_context->possibly_thrown_exceptions[$exception_fqcln]);
                            unset($context->possibly_thrown_exceptions[$exception_fqcln]);
                            unset($catch_context->possibly_thrown_exceptions[$exception_fqcln]);
                        }
                    }
                }
                $catch_context->possibly_thrown_exceptions = [];
            }
            // discard all clauses because crazy stuff may have happened in try block
            $catch_context->clauses = [];
            if ($catch->var && is_string($catch->var->name)) {
                $catch_var_id = '$' . $catch->var->name;
                $catch_context->vars_in_scope[$catch_var_id] = new Union(array_map(static fn(string $fq_catch_class): TNamedObject => new TNamedObject($fq_catch_class, \false, \false, version_compare(PHP_VERSION, '7.0.0dev', '>=') && strtolower($fq_catch_class) !== 'throwable' && $codebase->interfaceExists($fq_catch_class) && !$codebase->interfaceExtends($fq_catch_class, 'Throwable') ? ['Throwable' => new TNamedObject('Throwable')] : []), $fq_catch_classes));
                // removes dependent vars from $context
                $catch_context->removeDescendents($catch_var_id, $catch_context->vars_in_scope[$catch_var_id], $catch_context->vars_in_scope[$catch_var_id], $statements_analyzer);
                $catch_context->vars_possibly_in_scope[$catch_var_id] = \true;
                $location = new CodeLocation($statements_analyzer->getSource(), $catch->var);
                if (!$statements_analyzer->hasVariable($catch_var_id)) {
                    $statements_analyzer->registerVariable($catch_var_id, $location, $catch_context->branch_point);
                } else {
                    $statements_analyzer->registerVariableAssignment($catch_var_id, $location);
                }
                if ($statements_analyzer->data_flow_graph) {
                    $catch_var_node = DataFlowNode::getForAssignment($catch_var_id, $location);
                    $catch_context->vars_in_scope[$catch_var_id] = $catch_context->vars_in_scope[$catch_var_id]->addParentNodes([$catch_var_node->id => $catch_var_node]);
                    if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                        $statements_analyzer->data_flow_graph->addPath($catch_var_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                    }
                }
            }
            $suppressed_issues = $statements_analyzer->getSuppressedIssues();
            foreach ($issues_to_suppress as $issue_to_suppress) {
                if (!in_array($issue_to_suppress, $suppressed_issues, \true)) {
                    $statements_analyzer->addSuppressedIssues([$issue_to_suppress]);
                }
            }
            $old_catch_assigned_var_ids = $catch_context->assigned_var_ids;
            $catch_context->assigned_var_ids = [];
            $statements_analyzer->analyze($catch->stmts, $catch_context);
            // recalculate in case there's a no-return clause
            $catch_actions[$i] = ScopeAnalyzer::getControlActions($catch->stmts, $statements_analyzer->node_data, []);
            foreach ($issues_to_suppress as $issue_to_suppress) {
                if (!in_array($issue_to_suppress, $suppressed_issues, \true)) {
                    $statements_analyzer->removeSuppressedIssues([$issue_to_suppress]);
                }
            }
            /** @var array<string, bool> */
            $new_catch_assigned_var_ids = $catch_context->assigned_var_ids;
            $catch_context->assigned_var_ids += $old_catch_assigned_var_ids;
            if ($catch_context->collect_exceptions) {
                $context->mergeExceptions($catch_context);
            }
            $catch_doesnt_leave_parent_scope = $catch_actions[$i] !== [ScopeAnalyzer::ACTION_END] && $catch_actions[$i] !== [ScopeAnalyzer::ACTION_CONTINUE] && $catch_actions[$i] !== [ScopeAnalyzer::ACTION_BREAK];
            if ($catch_doesnt_leave_parent_scope) {
                $definitely_newly_assigned_var_ids = array_intersect_key($new_catch_assigned_var_ids, $definitely_newly_assigned_var_ids);
                foreach ($catch_context->vars_in_scope as $var_id => $type) {
                    if ($try_block_control_actions === [ScopeAnalyzer::ACTION_END]) {
                        $context->vars_in_scope[$var_id] = $type;
                    } elseif (isset($context->vars_in_scope[$var_id])) {
                        $context->vars_in_scope[$var_id] = Type::combineUnionTypes($context->vars_in_scope[$var_id], $type);
                    }
                }
                $context->vars_possibly_in_scope = array_merge($catch_context->vars_possibly_in_scope, $context->vars_possibly_in_scope);
            } else {
                if ($stmt->finally) {
                    $context->vars_possibly_in_scope = array_merge($catch_context->vars_possibly_in_scope, $context->vars_possibly_in_scope);
                }
            }
            if ($try_context->finally_scope) {
                foreach ($catch_context->vars_in_scope as $var_id => &$type) {
                    if (isset($try_context->finally_scope->vars_in_scope[$var_id])) {
                        if ($try_context->finally_scope->vars_in_scope[$var_id] !== $type) {
                            $try_context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes($try_context->finally_scope->vars_in_scope[$var_id], $type, $statements_analyzer->getCodebase());
                        }
                    } else {
                        $try_context->finally_scope->vars_in_scope[$var_id] = $type->setPossiblyUndefined(\true, \true);
                    }
                }
                unset($type);
            }
        }
        if ($context->loop_scope && !$try_leaves_loop && !in_array(ScopeAnalyzer::ACTION_NONE, $context->loop_scope->final_actions, \true)) {
            $context->loop_scope->final_actions[] = ScopeAnalyzer::ACTION_NONE;
        }
        $finally_has_returned = \false;
        if ($stmt->finally) {
            if ($try_context->finally_scope) {
                $finally_context = clone $context;
                $finally_context->assigned_var_ids = [];
                $finally_context->possibly_assigned_var_ids = [];
                $finally_context->vars_in_scope = $try_context->finally_scope->vars_in_scope;
                $statements_analyzer->analyze($stmt->finally->stmts, $finally_context);
                $finally_has_returned = $finally_context->has_returned;
                /** @var string $var_id */
                foreach ($finally_context->assigned_var_ids as $var_id => $_) {
                    if (isset($context->vars_in_scope[$var_id]) && isset($finally_context->vars_in_scope[$var_id])) {
                        $possibly_undefined = $context->vars_in_scope[$var_id]->possibly_undefined && $context->vars_in_scope[$var_id]->possibly_undefined_from_try;
                        $context->vars_in_scope[$var_id] = Type::combineUnionTypes($context->vars_in_scope[$var_id], $finally_context->vars_in_scope[$var_id], $codebase);
                        if ($possibly_undefined) {
                            /** @psalm-suppress InaccessibleProperty We just created this type */
                            $context->vars_in_scope[$var_id]->possibly_undefined = \false;
                            /** @psalm-suppress InaccessibleProperty We just created this type */
                            $context->vars_in_scope[$var_id]->possibly_undefined_from_try = \false;
                        }
                    } elseif (isset($finally_context->vars_in_scope[$var_id])) {
                        $context->vars_in_scope[$var_id] = $finally_context->vars_in_scope[$var_id];
                    }
                }
            }
        }
        foreach ($definitely_newly_assigned_var_ids as $var_id => $_) {
            if (isset($context->vars_in_scope[$var_id])) {
                if ($context->vars_in_scope[$var_id]->possibly_undefined_from_try) {
                    $context->vars_in_scope[$var_id] = $context->vars_in_scope[$var_id]->setPossiblyUndefined(\false, \false);
                }
            }
        }
        foreach ($existing_thrown_exceptions as $possibly_thrown_exception => $codelocations) {
            foreach ($codelocations as $hash => $codelocation) {
                $context->possibly_thrown_exceptions[$possibly_thrown_exception][$hash] = $codelocation;
            }
        }
        $body_has_returned = !in_array(ScopeAnalyzer::ACTION_NONE, $try_block_control_actions, \true);
        $context->has_returned = $body_has_returned && $all_catches_leave || $finally_has_returned;
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Exception\ScopeAnalysisException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\AlgebraAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfElse\ElseAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfElse\ElseIfAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfElse\IfAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Scope\IfScope;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualBooleanNot;
use Psalm\Type;
use Psalm\Type\Reconciler;
use function array_diff;
use function array_filter;
use function array_intersect_key;
use function array_keys;
use function array_merge;
use function array_unique;
use function array_values;
use function count;
use function in_array;
use function preg_match;
use function preg_quote;
use function spl_object_id;
use function substr;
/**
 * @internal
 */
class IfElseAnalyzer
{
    /**
     * System of type substitution and deletion
     *
     * for example
     *
     * x: A|null
     *
     * if (x)
     *   (x: A)
     *   x = B  -- effects: remove A from the type of x, add B
     * else
     *   (x: null)
     *   x = C  -- effects: remove null from the type of x, add C
     *
     *
     * x: A|null
     *
     * if (!x)
     *   (x: null)
     *   throw new Exception -- effects: remove null from the type of x
     *
     * @return null|false
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\If_ $stmt, Context $context) : ?bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $if_scope = new IfScope();
        // We need to clone the original context for later use if we're exiting in this if conditional
        if ($stmt->cond instanceof PhpParser\Node\Expr\BinaryOp || $stmt->cond instanceof PhpParser\Node\Expr\BooleanNot && $stmt->cond->expr instanceof PhpParser\Node\Expr\BinaryOp) {
            $final_actions = ScopeAnalyzer::getControlActions($stmt->stmts, null, []);
            $has_leaving_statements = $final_actions === [ScopeAnalyzer::ACTION_END] || count($final_actions) && !in_array(ScopeAnalyzer::ACTION_NONE, $final_actions, \true);
            if ($has_leaving_statements) {
                $if_scope->post_leaving_if_context = clone $context;
            }
        }
        try {
            $if_conditional_scope = \Psalm\Internal\Analyzer\Statements\Block\IfConditionalAnalyzer::analyze($statements_analyzer, $stmt->cond, $context, $codebase, $if_scope, $context->branch_point ?: (int) $stmt->getAttribute('startFilePos'));
            // this is the context for stuff that happens within the `if` block
            $if_context = $if_conditional_scope->if_context;
            // this is the context for stuff that happens after the `if` block
            $post_if_context = $if_conditional_scope->post_if_context;
            $assigned_in_conditional_var_ids = $if_conditional_scope->assigned_in_conditional_var_ids;
        } catch (ScopeAnalysisException $e) {
            return \false;
        }
        $mixed_var_ids = [];
        foreach ($if_context->vars_in_scope as $var_id => $type) {
            if ($type->isMixed() && isset($context->vars_in_scope[$var_id])) {
                $mixed_var_ids[] = $var_id;
            }
        }
        $cond_object_id = spl_object_id($stmt->cond);
        $if_clauses = FormulaGenerator::getFormula($cond_object_id, $cond_object_id, $stmt->cond, $context->self, $statements_analyzer, $codebase);
        if (count($if_clauses) > 200) {
            $if_clauses = [];
        }
        $if_clauses_handled = [];
        foreach ($if_clauses as $clause) {
            $keys = array_keys($clause->possibilities);
            $mixed_var_ids = array_diff($mixed_var_ids, $keys);
            foreach ($keys as $key) {
                foreach ($mixed_var_ids as $mixed_var_id) {
                    if (preg_match('/^' . preg_quote($mixed_var_id, '/') . '(\\[|-)/', $key)) {
                        $clause = new Clause([], $cond_object_id, $cond_object_id, \true);
                        break 2;
                    }
                }
            }
            $if_clauses_handled[] = $clause;
        }
        $if_clauses = $if_clauses_handled;
        $entry_clauses = $context->clauses;
        // this will see whether any of the clauses in set A conflict with the clauses in set B
        AlgebraAnalyzer::checkForParadox($context->clauses, $if_clauses, $statements_analyzer, $stmt->cond, $assigned_in_conditional_var_ids);
        $if_clauses = Algebra::simplifyCNF($if_clauses);
        $if_context_clauses = [...$entry_clauses, ...$if_clauses];
        $if_context->clauses = $entry_clauses ? Algebra::simplifyCNF($if_context_clauses) : $if_context_clauses;
        if ($if_context->reconciled_expression_clauses) {
            $reconciled_expression_clauses = $if_context->reconciled_expression_clauses;
            $if_context->clauses = array_values(array_filter($if_context->clauses, static fn(Clause $c): bool => !in_array($c->hash, $reconciled_expression_clauses)));
            if (count($if_context->clauses) === 1 && $if_context->clauses[0]->wedge && !$if_context->clauses[0]->possibilities) {
                $if_context->clauses = [];
                $if_context->reconciled_expression_clauses = [];
            }
        }
        // define this before we alter local clauses after reconciliation
        $if_scope->reasonable_clauses = $if_context->clauses;
        try {
            $if_scope->negated_clauses = Algebra::negateFormula($if_clauses);
        } catch (ComplicatedExpressionException $e) {
            try {
                $if_scope->negated_clauses = FormulaGenerator::getFormula($cond_object_id, $cond_object_id, new VirtualBooleanNot($stmt->cond), $context->self, $statements_analyzer, $codebase, \false);
            } catch (ComplicatedExpressionException $e) {
                $if_scope->negated_clauses = [];
            }
        }
        $if_scope->negated_types = Algebra::getTruthsFromFormula(Algebra::simplifyCNF([...$context->clauses, ...$if_scope->negated_clauses]));
        $temp_else_context = clone $post_if_context;
        $changed_var_ids = [];
        if ($if_scope->negated_types) {
            [$temp_else_context->vars_in_scope, $temp_else_context->references_in_scope] = Reconciler::reconcileKeyedTypes($if_scope->negated_types, [], $temp_else_context->vars_in_scope, $temp_else_context->references_in_scope, $changed_var_ids, [], $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $context->inside_loop, $context->check_variables ? new CodeLocation($statements_analyzer->getSource(), $stmt->cond instanceof PhpParser\Node\Expr\BooleanNot ? $stmt->cond->expr : $stmt->cond, $context->include_location) : null);
        }
        // we calculate the vars redefined in a hypothetical else statement to determine
        // which vars of the if we can safely change
        $pre_assignment_else_redefined_vars = array_intersect_key($temp_else_context->getRedefinedVars($context->vars_in_scope, \true), $changed_var_ids);
        // check the if
        if (IfAnalyzer::analyze($statements_analyzer, $stmt, $if_scope, $if_conditional_scope, $if_context, $context, $pre_assignment_else_redefined_vars) === \false) {
            return \false;
        }
        // this has to go on a separate line because the phar compactor messes with precedence
        $scope_to_clone = $if_scope->post_leaving_if_context ?? $post_if_context;
        $else_context = clone $scope_to_clone;
        // check the elseifs
        foreach ($stmt->elseifs as $elseif) {
            if (ElseIfAnalyzer::analyze($statements_analyzer, $elseif, $if_scope, $else_context, $context, $codebase, $else_context->branch_point ?: (int) $stmt->getAttribute('startFilePos')) === \false) {
                return \false;
            }
        }
        if ($stmt->else) {
            if ($codebase->alter_code) {
                $else_context->branch_point = $else_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
            }
        }
        if (ElseAnalyzer::analyze($statements_analyzer, $stmt->else, $if_scope, $else_context, $context) === \false) {
            return \false;
        }
        if (count($if_scope->if_actions) && !in_array(ScopeAnalyzer::ACTION_NONE, $if_scope->if_actions, \true) && !$stmt->elseifs) {
            $context->clauses = $else_context->clauses;
            foreach ($else_context->vars_in_scope as $var_id => $type) {
                $context->vars_in_scope[$var_id] = $type;
            }
            foreach ($pre_assignment_else_redefined_vars as $var_id => $reconciled_type) {
                $first_appearance = $statements_analyzer->getFirstAppearance($var_id);
                if ($first_appearance && isset($post_if_context->vars_in_scope[$var_id]) && $post_if_context->vars_in_scope[$var_id]->hasMixed() && !$reconciled_type->hasMixed()) {
                    if (!$post_if_context->collect_initializations && !$post_if_context->collect_mutations && $statements_analyzer->getFilePath() === $statements_analyzer->getRootFilePath()) {
                        $parent_source = $statements_analyzer->getSource();
                        $functionlike_storage = $parent_source instanceof FunctionLikeAnalyzer ? $parent_source->getFunctionLikeStorage($statements_analyzer) : null;
                        if (!$functionlike_storage || !$parent_source->getSource() instanceof TraitAnalyzer && !isset($functionlike_storage->param_lookup[substr($var_id, 1)])) {
                            $codebase = $statements_analyzer->getCodebase();
                            $codebase->analyzer->decrementMixedCount($statements_analyzer->getFilePath());
                        }
                    }
                    IssueBuffer::remove($statements_analyzer->getFilePath(), 'MixedAssignment', $first_appearance->raw_file_start);
                }
            }
        }
        if ($context->loop_scope) {
            $context->loop_scope->final_actions = array_unique(array_merge($context->loop_scope->final_actions, $if_scope->final_actions));
        }
        $context->vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $if_scope->new_vars_possibly_in_scope);
        $context->possibly_assigned_var_ids = array_merge($context->possibly_assigned_var_ids, $if_scope->possibly_assigned_var_ids ?: []);
        // vars can only be defined/redefined if there was an else (defined in every block)
        $context->assigned_var_ids = array_merge($context->assigned_var_ids, $if_scope->assigned_var_ids ?: []);
        if ($if_scope->new_vars) {
            foreach ($if_scope->new_vars as $var_id => &$type) {
                if (isset($context->vars_possibly_in_scope[$var_id]) && $statements_analyzer->data_flow_graph) {
                    $type = $type->addParentNodes($statements_analyzer->getParentNodesForPossiblyUndefinedVariable($var_id));
                }
                $context->vars_in_scope[$var_id] = $type;
            }
            unset($type);
        }
        if ($if_scope->redefined_vars) {
            foreach ($if_scope->redefined_vars as $var_id => $type) {
                $context->vars_in_scope[$var_id] = $type;
                $if_scope->updated_vars[$var_id] = \true;
                if ($if_scope->reasonable_clauses) {
                    $if_scope->reasonable_clauses = Context::filterClauses($var_id, $if_scope->reasonable_clauses, $context->vars_in_scope[$var_id] ?? null, $statements_analyzer);
                }
            }
        }
        if ($if_scope->reasonable_clauses && (count($if_scope->reasonable_clauses) > 1 || !$if_scope->reasonable_clauses[0]->wedge)) {
            $context->clauses = Algebra::simplifyCNF([...$if_scope->reasonable_clauses, ...$context->clauses]);
        }
        if ($if_scope->possibly_redefined_vars) {
            foreach ($if_scope->possibly_redefined_vars as $var_id => $type) {
                if (isset($context->vars_in_scope[$var_id])) {
                    if (!$type->failed_reconciliation && !isset($if_scope->updated_vars[$var_id])) {
                        $combined_type = Type::combineUnionTypes($context->vars_in_scope[$var_id], $type, $codebase);
                        if (!$combined_type->equals($context->vars_in_scope[$var_id])) {
                            $context->removeDescendents($var_id, $combined_type);
                        }
                        $context->vars_in_scope[$var_id] = $combined_type;
                    } else {
                        $context->vars_in_scope[$var_id] = $context->vars_in_scope[$var_id]->addParentNodes($type->parent_nodes);
                    }
                }
            }
        }
        if (!in_array(ScopeAnalyzer::ACTION_NONE, $if_scope->final_actions, \true)) {
            $context->has_returned = \true;
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block\IfElse;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Scope\IfScope;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\ConflictingReferenceConstraint;
use Psalm\IssueBuffer;
use Psalm\Type\Reconciler;
use function array_diff_key;
use function array_key_exists;
use function array_keys;
use function array_merge;
use function count;
use function in_array;
use function preg_match;
use function preg_quote;
/**
 * @internal
 */
class ElseAnalyzer
{
    /**
     * @return false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, ?PhpParser\Node\Stmt\Else_ $else, IfScope $if_scope, Context $else_context, Context $outer_context) : ?bool
    {
        $codebase = $statements_analyzer->getCodebase();
        if (!$else && !$if_scope->negated_clauses && !$else_context->clauses) {
            $if_scope->final_actions = array_merge([ScopeAnalyzer::ACTION_NONE], $if_scope->final_actions);
            $if_scope->assigned_var_ids = [];
            $if_scope->new_vars = [];
            $if_scope->redefined_vars = [];
            $if_scope->reasonable_clauses = [];
            return null;
        }
        $else_context->clauses = Algebra::simplifyCNF([...$else_context->clauses, ...$if_scope->negated_clauses]);
        $else_types = Algebra::getTruthsFromFormula($else_context->clauses);
        $original_context = clone $else_context;
        if ($else_types) {
            $changed_var_ids = [];
            [$else_context->vars_in_scope, $else_context->references_in_scope] = Reconciler::reconcileKeyedTypes($else_types, [], $else_context->vars_in_scope, $else_context->references_in_scope, $changed_var_ids, [], $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $else_context->inside_loop, $else ? new CodeLocation($statements_analyzer->getSource(), $else, $outer_context->include_location) : null);
            $else_context->clauses = Context::removeReconciledClauses($else_context->clauses, $changed_var_ids)[0];
            foreach ($changed_var_ids as $changed_var_id => $_) {
                foreach ($else_context->vars_in_scope as $var_id => $_) {
                    if (preg_match('/' . preg_quote($changed_var_id, '/') . '[\\]\\[\\-]/', $var_id) && !array_key_exists($var_id, $changed_var_ids)) {
                        $else_context->removePossibleReference($var_id);
                    }
                }
            }
        }
        $old_else_context = clone $else_context;
        $pre_stmts_assigned_var_ids = $else_context->assigned_var_ids;
        $else_context->assigned_var_ids = [];
        $pre_possibly_assigned_var_ids = $else_context->possibly_assigned_var_ids;
        $else_context->possibly_assigned_var_ids = [];
        if ($else) {
            if ($statements_analyzer->analyze($else->stmts, $else_context) === \false) {
                return \false;
            }
        }
        foreach ($else_context->parent_remove_vars as $var_id => $_) {
            $outer_context->removeVarFromConflictingClauses($var_id);
        }
        /** @var array<string, int> */
        $new_assigned_var_ids = $else_context->assigned_var_ids;
        $else_context->assigned_var_ids += $pre_stmts_assigned_var_ids;
        /** @var array<string, bool> */
        $new_possibly_assigned_var_ids = $else_context->possibly_assigned_var_ids;
        $else_context->possibly_assigned_var_ids += $pre_possibly_assigned_var_ids;
        if ($else) {
            foreach ($else_context->byref_constraints as $var_id => $byref_constraint) {
                if (isset($outer_context->byref_constraints[$var_id]) && ($outer_constraint_type = $outer_context->byref_constraints[$var_id]->type) && $byref_constraint->type && !UnionTypeComparator::isContainedBy($codebase, $byref_constraint->type, $outer_constraint_type)) {
                    IssueBuffer::maybeAdd(new ConflictingReferenceConstraint('There is more than one pass-by-reference constraint on ' . $var_id, new CodeLocation($statements_analyzer, $else, $outer_context->include_location, \true)), $statements_analyzer->getSuppressedIssues());
                } else {
                    $outer_context->byref_constraints[$var_id] = $byref_constraint;
                }
            }
        }
        $final_actions = $else ? ScopeAnalyzer::getControlActions($else->stmts, $statements_analyzer->node_data, []) : [ScopeAnalyzer::ACTION_NONE];
        // has a return/throw at end
        $has_ending_statements = $final_actions === [ScopeAnalyzer::ACTION_END];
        $has_leaving_statements = $has_ending_statements || count($final_actions) && !in_array(ScopeAnalyzer::ACTION_NONE, $final_actions, \true);
        $has_break_statement = $final_actions === [ScopeAnalyzer::ACTION_BREAK];
        $has_continue_statement = $final_actions === [ScopeAnalyzer::ACTION_CONTINUE];
        $if_scope->final_actions = array_merge($final_actions, $if_scope->final_actions);
        // if it doesn't end in a return
        if (!$has_leaving_statements) {
            \Psalm\Internal\Analyzer\Statements\Block\IfElse\IfAnalyzer::updateIfScope($codebase, $if_scope, $else_context, $original_context, $new_assigned_var_ids, $new_possibly_assigned_var_ids, [], \true);
            $if_scope->reasonable_clauses = [];
        }
        // update the parent context as necessary
        if ($if_scope->negatable_if_types) {
            $outer_context->update($old_else_context, $else_context, $has_leaving_statements, array_keys($if_scope->negatable_if_types), $if_scope->updated_vars);
        }
        if (!$has_ending_statements) {
            $vars_possibly_in_scope = array_diff_key($else_context->vars_possibly_in_scope, $outer_context->vars_possibly_in_scope);
            $possibly_assigned_var_ids = $new_possibly_assigned_var_ids;
            if ($has_leaving_statements) {
                if ($else_context->loop_scope) {
                    if (!$has_continue_statement && !$has_break_statement) {
                        $if_scope->new_vars_possibly_in_scope = array_merge($vars_possibly_in_scope, $if_scope->new_vars_possibly_in_scope);
                    }
                    $else_context->loop_scope->vars_possibly_in_scope = array_merge($vars_possibly_in_scope, $else_context->loop_scope->vars_possibly_in_scope);
                }
            } else {
                $if_scope->new_vars_possibly_in_scope = array_merge($vars_possibly_in_scope, $if_scope->new_vars_possibly_in_scope);
                $if_scope->possibly_assigned_var_ids = array_merge($possibly_assigned_var_ids, $if_scope->possibly_assigned_var_ids);
            }
        }
        if ($outer_context->collect_exceptions) {
            $outer_context->mergeExceptions($else_context);
        }
        // Track references set in the else to make sure they aren't reused later
        $outer_context->updateReferencesPossiblyFromConfusingScope($else_context, $statements_analyzer);
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block\IfElse;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Exception\ScopeAnalysisException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\AlgebraAnalyzer;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfConditionalAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Scope\IfScope;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\ConflictingReferenceConstraint;
use Psalm\IssueBuffer;
use Psalm\Type\Reconciler;
use function array_combine;
use function array_diff;
use function array_diff_key;
use function array_filter;
use function array_key_exists;
use function array_keys;
use function array_merge;
use function array_reduce;
use function array_unique;
use function array_values;
use function count;
use function in_array;
use function preg_match;
use function preg_quote;
use function spl_object_id;
/**
 * @internal
 */
class ElseIfAnalyzer
{
    /**
     * @return false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\ElseIf_ $elseif, IfScope $if_scope, Context $else_context, Context $outer_context, Codebase $codebase, int $branch_point) : ?bool
    {
        $pre_conditional_context = clone $else_context;
        try {
            $if_conditional_scope = IfConditionalAnalyzer::analyze($statements_analyzer, $elseif->cond, $else_context, $codebase, $if_scope, $branch_point);
            $elseif_context = $if_conditional_scope->if_context;
            $cond_referenced_var_ids = $if_conditional_scope->cond_referenced_var_ids;
            $assigned_in_conditional_var_ids = $if_conditional_scope->assigned_in_conditional_var_ids;
        } catch (ScopeAnalysisException $e) {
            return \false;
        }
        $mixed_var_ids = [];
        foreach ($elseif_context->vars_in_scope as $var_id => $type) {
            if ($type->hasMixed()) {
                $mixed_var_ids[] = $var_id;
            }
        }
        $elseif_cond_id = spl_object_id($elseif->cond);
        $elseif_clauses = FormulaGenerator::getFormula($elseif_cond_id, $elseif_cond_id, $elseif->cond, $else_context->self, $statements_analyzer, $codebase);
        $elseif_clauses_handled = [];
        foreach ($elseif_clauses as $clause) {
            $keys = array_keys($clause->possibilities);
            $mixed_var_ids = array_diff($mixed_var_ids, $keys);
            foreach ($keys as $key) {
                foreach ($mixed_var_ids as $mixed_var_id) {
                    if (preg_match('/^' . preg_quote($mixed_var_id, '/') . '(\\[|-)/', $key)) {
                        $elseif_clauses_handled[] = new Clause([], $elseif_cond_id, $elseif_cond_id, \true);
                        break 2;
                    }
                }
            }
            $elseif_clauses_handled[] = $clause;
        }
        $elseif_clauses = $elseif_clauses_handled;
        $entry_clauses = [];
        foreach ($if_conditional_scope->entry_clauses as $c) {
            foreach ($c->possibilities as $key => $_value) {
                foreach ($assigned_in_conditional_var_ids as $conditional_assigned_var_id => $_) {
                    if (preg_match('/^' . preg_quote($conditional_assigned_var_id, '/') . '(\\[|-|$)/', $key)) {
                        $entry_clauses[] = new Clause([], $elseif_cond_id, $elseif_cond_id, \true);
                        break 2;
                    }
                }
            }
            $entry_clauses[] = $c;
        }
        // this will see whether any of the clauses in set A conflict with the clauses in set B
        AlgebraAnalyzer::checkForParadox($entry_clauses, $elseif_clauses, $statements_analyzer, $elseif->cond, $assigned_in_conditional_var_ids);
        $elseif_context_clauses = [...$entry_clauses, ...$elseif_clauses];
        if ($elseif_context->reconciled_expression_clauses) {
            $reconciled_expression_clauses = $elseif_context->reconciled_expression_clauses;
            $elseif_context_clauses = array_values(array_filter($elseif_context_clauses, static fn(Clause $c): bool => !in_array($c->hash, $reconciled_expression_clauses, \true)));
        }
        $elseif_context->clauses = Algebra::simplifyCNF($elseif_context_clauses);
        $active_elseif_types = [];
        try {
            if (array_filter($entry_clauses, static fn(Clause $clause): bool => (bool) $clause->possibilities)) {
                $omit_keys = array_reduce(
                    $entry_clauses,
                    /**
                     * @param array<string> $carry
                     * @return array<string>
                     */
                    static fn(array $carry, Clause $clause): array => array_merge($carry, array_keys($clause->possibilities)),
                    []
                );
                $omit_keys = array_combine($omit_keys, $omit_keys);
                $omit_keys = array_diff_key($omit_keys, Algebra::getTruthsFromFormula($entry_clauses));
                $cond_referenced_var_ids = array_diff_key($cond_referenced_var_ids, $omit_keys);
            }
            $reconcilable_elseif_types = Algebra::getTruthsFromFormula($elseif_context->clauses, spl_object_id($elseif->cond), $cond_referenced_var_ids, $active_elseif_types);
            $negated_elseif_types = Algebra::getTruthsFromFormula(Algebra::negateFormula($elseif_clauses));
        } catch (ComplicatedExpressionException $e) {
            $reconcilable_elseif_types = [];
            $negated_elseif_types = [];
        }
        $all_negated_vars = array_unique([...array_keys($negated_elseif_types), ...array_keys($if_scope->negated_types)]);
        foreach ($all_negated_vars as $var_id) {
            if (isset($negated_elseif_types[$var_id])) {
                if (isset($if_scope->negated_types[$var_id])) {
                    $if_scope->negated_types[$var_id] = [...$if_scope->negated_types[$var_id], ...$negated_elseif_types[$var_id]];
                } else {
                    $if_scope->negated_types[$var_id] = $negated_elseif_types[$var_id];
                }
            }
        }
        $newly_reconciled_var_ids = [];
        // if the elseif has an || in the conditional, we cannot easily reason about it
        if ($reconcilable_elseif_types) {
            [$elseif_context->vars_in_scope, $elseif_context->references_in_scope] = Reconciler::reconcileKeyedTypes($reconcilable_elseif_types, $active_elseif_types, $elseif_context->vars_in_scope, $elseif_context->references_in_scope, $newly_reconciled_var_ids, $cond_referenced_var_ids, $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $elseif_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $elseif->cond instanceof PhpParser\Node\Expr\BooleanNot ? $elseif->cond->expr : $elseif->cond, $outer_context->include_location));
            if ($newly_reconciled_var_ids) {
                $elseif_context->clauses = Context::removeReconciledClauses($elseif_context->clauses, $newly_reconciled_var_ids)[0];
                foreach ($newly_reconciled_var_ids as $changed_var_id => $_) {
                    foreach ($elseif_context->vars_in_scope as $var_id => $_) {
                        if (preg_match('/' . preg_quote($changed_var_id, '/') . '[\\]\\[\\-]/', $var_id) && !array_key_exists($var_id, $newly_reconciled_var_ids) && !array_key_exists($var_id, $cond_referenced_var_ids)) {
                            $elseif_context->removePossibleReference($var_id);
                        }
                    }
                }
            }
        }
        $pre_stmts_assigned_var_ids = $elseif_context->assigned_var_ids;
        $elseif_context->assigned_var_ids = [];
        $pre_stmts_possibly_assigned_var_ids = $elseif_context->possibly_assigned_var_ids;
        $elseif_context->possibly_assigned_var_ids = [];
        if ($statements_analyzer->analyze($elseif->stmts, $elseif_context) === \false) {
            return \false;
        }
        foreach ($elseif_context->parent_remove_vars as $var_id => $_) {
            $outer_context->removeVarFromConflictingClauses($var_id);
        }
        /** @var array<string, int> */
        $new_stmts_assigned_var_ids = $elseif_context->assigned_var_ids;
        $elseif_context->assigned_var_ids = $pre_stmts_assigned_var_ids + $new_stmts_assigned_var_ids;
        /** @var array<string, bool> */
        $new_stmts_possibly_assigned_var_ids = $elseif_context->possibly_assigned_var_ids;
        $elseif_context->possibly_assigned_var_ids = $pre_stmts_possibly_assigned_var_ids + $new_stmts_possibly_assigned_var_ids;
        foreach ($elseif_context->byref_constraints as $var_id => $byref_constraint) {
            if (isset($outer_context->byref_constraints[$var_id]) && ($outer_constraint_type = $outer_context->byref_constraints[$var_id]->type) && $byref_constraint->type && !UnionTypeComparator::isContainedBy($codebase, $byref_constraint->type, $outer_constraint_type)) {
                IssueBuffer::maybeAdd(new ConflictingReferenceConstraint('There is more than one pass-by-reference constraint on ' . $var_id, new CodeLocation($statements_analyzer, $elseif, $outer_context->include_location, \true)), $statements_analyzer->getSuppressedIssues());
            } else {
                $outer_context->byref_constraints[$var_id] = $byref_constraint;
            }
        }
        $final_actions = ScopeAnalyzer::getControlActions($elseif->stmts, $statements_analyzer->node_data, []);
        // has a return/throw at end
        $has_ending_statements = $final_actions === [ScopeAnalyzer::ACTION_END];
        $has_leaving_statements = $has_ending_statements || count($final_actions) && !in_array(ScopeAnalyzer::ACTION_NONE, $final_actions, \true);
        $has_break_statement = $final_actions === [ScopeAnalyzer::ACTION_BREAK];
        $has_continue_statement = $final_actions === [ScopeAnalyzer::ACTION_CONTINUE];
        $if_scope->final_actions = array_merge($final_actions, $if_scope->final_actions);
        // update the parent context as necessary
        if (!$has_leaving_statements) {
            \Psalm\Internal\Analyzer\Statements\Block\IfElse\IfAnalyzer::updateIfScope($codebase, $if_scope, $elseif_context, $outer_context, array_merge($new_stmts_assigned_var_ids, $assigned_in_conditional_var_ids), $new_stmts_possibly_assigned_var_ids, $newly_reconciled_var_ids);
            $reasonable_clause_count = count($if_scope->reasonable_clauses);
            if ($reasonable_clause_count && $reasonable_clause_count < 20000 && $elseif_clauses) {
                $if_scope->reasonable_clauses = Algebra::combineOredClauses($if_scope->reasonable_clauses, $elseif_clauses, $elseif_cond_id);
            } else {
                $if_scope->reasonable_clauses = [];
            }
        } else {
            $if_scope->reasonable_clauses = [];
        }
        if ($negated_elseif_types) {
            if ($has_leaving_statements) {
                $newly_reconciled_var_ids = [];
                $implied_outer_context = clone $elseif_context;
                [$implied_outer_context->vars_in_scope, $implied_outer_context->references_in_scope] = Reconciler::reconcileKeyedTypes($negated_elseif_types, [], $pre_conditional_context->vars_in_scope, $pre_conditional_context->references_in_scope, $newly_reconciled_var_ids, [], $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $elseif_context->inside_loop, new CodeLocation($statements_analyzer->getSource(), $elseif, $outer_context->include_location));
                $updated_vars = [];
                $outer_context->update($elseif_context, $implied_outer_context, \false, array_keys($negated_elseif_types), $updated_vars);
            }
        }
        if (!$has_ending_statements) {
            $vars_possibly_in_scope = array_diff_key($elseif_context->vars_possibly_in_scope, $outer_context->vars_possibly_in_scope);
            $possibly_assigned_var_ids = $new_stmts_possibly_assigned_var_ids;
            if ($has_leaving_statements && $elseif_context->loop_scope) {
                if (!$has_continue_statement && !$has_break_statement) {
                    $if_scope->new_vars_possibly_in_scope = array_merge($vars_possibly_in_scope, $if_scope->new_vars_possibly_in_scope);
                    $if_scope->possibly_assigned_var_ids = array_merge($possibly_assigned_var_ids, $if_scope->possibly_assigned_var_ids);
                }
                $elseif_context->loop_scope->vars_possibly_in_scope = array_merge($vars_possibly_in_scope, $elseif_context->loop_scope->vars_possibly_in_scope);
            } elseif (!$has_leaving_statements) {
                $if_scope->new_vars_possibly_in_scope = array_merge($vars_possibly_in_scope, $if_scope->new_vars_possibly_in_scope);
                $if_scope->possibly_assigned_var_ids = array_merge($possibly_assigned_var_ids, $if_scope->possibly_assigned_var_ids);
            }
        }
        if ($outer_context->collect_exceptions) {
            $outer_context->mergeExceptions($elseif_context);
        }
        try {
            $if_scope->negated_clauses = Algebra::simplifyCNF([...$if_scope->negated_clauses, ...Algebra::negateFormula($elseif_clauses)]);
        } catch (ComplicatedExpressionException $e) {
            $if_scope->negated_clauses = [];
        }
        // Track references set in the elseif to make sure they aren't reused later
        $outer_context->updateReferencesPossiblyFromConfusingScope($elseif_context, $statements_analyzer);
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block\IfElse;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Algebra;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\Scope\IfConditionalScope;
use Psalm\Internal\Scope\IfScope;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\ConflictingReferenceConstraint;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\BinaryOp\VirtualBooleanOr;
use Psalm\Node\Expr\VirtualBooleanNot;
use Psalm\Node\Expr\VirtualFuncCall;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\VirtualArg;
use Psalm\Type;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use function array_combine;
use function array_diff_key;
use function array_filter;
use function array_intersect;
use function array_intersect_key;
use function array_key_exists;
use function array_keys;
use function array_merge;
use function array_reduce;
use function array_unique;
use function count;
use function in_array;
use function preg_match;
use function preg_quote;
use function spl_object_id;
use function strpos;
use function substr;
/**
 * @internal
 */
class IfAnalyzer
{
    /**
     * @param  array<string, Union> $pre_assignment_else_redefined_vars
     * @return false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\If_ $stmt, IfScope $if_scope, IfConditionalScope $if_conditional_scope, Context $if_context, Context $outer_context, array $pre_assignment_else_redefined_vars) : ?bool
    {
        $cond_referenced_var_ids = $if_conditional_scope->cond_referenced_var_ids;
        $active_if_types = [];
        $reconcilable_if_types = Algebra::getTruthsFromFormula($if_context->clauses, spl_object_id($stmt->cond), $cond_referenced_var_ids, $active_if_types);
        if (array_filter($outer_context->clauses, static fn(Clause $clause): bool => (bool) $clause->possibilities)) {
            $omit_keys = array_reduce(
                $outer_context->clauses,
                /**
                 * @param array<string> $carry
                 * @return array<string>
                 */
                static fn(array $carry, Clause $clause): array => array_merge($carry, array_keys($clause->possibilities)),
                []
            );
            $omit_keys = array_combine($omit_keys, $omit_keys);
            $omit_keys = array_diff_key($omit_keys, Algebra::getTruthsFromFormula($outer_context->clauses));
            $cond_referenced_var_ids = array_diff_key($cond_referenced_var_ids, $omit_keys);
        }
        // if the if has an || in the conditional, we cannot easily reason about it
        if ($reconcilable_if_types) {
            $changed_var_ids = [];
            [$if_context->vars_in_scope, $if_context->references_in_scope] = Reconciler::reconcileKeyedTypes($reconcilable_if_types, $active_if_types, $if_context->vars_in_scope, $if_context->references_in_scope, $changed_var_ids, $cond_referenced_var_ids, $statements_analyzer, $statements_analyzer->getTemplateTypeMap() ?: [], $if_context->inside_loop, $outer_context->check_variables ? new CodeLocation($statements_analyzer->getSource(), $stmt->cond instanceof PhpParser\Node\Expr\BooleanNot ? $stmt->cond->expr : $stmt->cond, $outer_context->include_location) : null);
            foreach ($reconcilable_if_types as $var_id => $_) {
                $if_context->vars_possibly_in_scope[$var_id] = \true;
            }
            if ($changed_var_ids) {
                $if_context->clauses = Context::removeReconciledClauses($if_context->clauses, $changed_var_ids)[0];
                foreach ($changed_var_ids as $changed_var_id => $_) {
                    foreach ($if_context->vars_in_scope as $var_id => $_) {
                        if (preg_match('/' . preg_quote($changed_var_id, '/') . '[\\]\\[\\-]/', $var_id) && !array_key_exists($var_id, $changed_var_ids) && !array_key_exists($var_id, $cond_referenced_var_ids)) {
                            $if_context->removePossibleReference($var_id);
                        }
                    }
                }
            }
            $if_scope->if_cond_changed_var_ids = $changed_var_ids;
        }
        $if_context->reconciled_expression_clauses = [];
        $outer_context->vars_possibly_in_scope = array_merge($if_context->vars_possibly_in_scope, $outer_context->vars_possibly_in_scope);
        $old_if_context = clone $if_context;
        $codebase = $statements_analyzer->getCodebase();
        $assigned_var_ids = $if_context->assigned_var_ids;
        $possibly_assigned_var_ids = $if_context->possibly_assigned_var_ids;
        $if_context->assigned_var_ids = [];
        $if_context->possibly_assigned_var_ids = [];
        if ($statements_analyzer->analyze($stmt->stmts, $if_context) === \false) {
            return \false;
        }
        foreach ($if_context->parent_remove_vars as $var_id => $_) {
            $outer_context->removeVarFromConflictingClauses($var_id);
        }
        $if_scope->if_actions = $final_actions = ScopeAnalyzer::getControlActions($stmt->stmts, $statements_analyzer->node_data, []);
        $has_ending_statements = $final_actions === [ScopeAnalyzer::ACTION_END];
        $has_leaving_statements = $has_ending_statements || count($final_actions) && !in_array(ScopeAnalyzer::ACTION_NONE, $final_actions, \true);
        $has_break_statement = $final_actions === [ScopeAnalyzer::ACTION_BREAK];
        $has_continue_statement = $final_actions === [ScopeAnalyzer::ACTION_CONTINUE];
        $if_scope->if_actions = $final_actions;
        $if_scope->final_actions = $final_actions;
        /** @var array<string, int> */
        $new_assigned_var_ids = $if_context->assigned_var_ids;
        /** @var array<string, bool> */
        $new_possibly_assigned_var_ids = $if_context->possibly_assigned_var_ids;
        $if_context->assigned_var_ids = array_merge($assigned_var_ids, $new_assigned_var_ids);
        $if_context->possibly_assigned_var_ids = array_merge($possibly_assigned_var_ids, $new_possibly_assigned_var_ids);
        foreach ($if_context->byref_constraints as $var_id => $byref_constraint) {
            if (isset($outer_context->byref_constraints[$var_id]) && $byref_constraint->type && ($outer_constraint_type = $outer_context->byref_constraints[$var_id]->type) && !UnionTypeComparator::isContainedBy($codebase, $byref_constraint->type, $outer_constraint_type)) {
                IssueBuffer::maybeAdd(new ConflictingReferenceConstraint('There is more than one pass-by-reference constraint on ' . $var_id . ' between ' . $byref_constraint->type->getId() . ' and ' . $outer_constraint_type->getId(), new CodeLocation($statements_analyzer, $stmt, $outer_context->include_location, \true)), $statements_analyzer->getSuppressedIssues());
            } else {
                $outer_context->byref_constraints[$var_id] = $byref_constraint;
            }
        }
        if (!$has_leaving_statements) {
            self::updateIfScope($codebase, $if_scope, $if_context, $outer_context, $new_assigned_var_ids, $new_possibly_assigned_var_ids, $if_scope->if_cond_changed_var_ids);
            if ($if_scope->reasonable_clauses) {
                // remove all reasonable clauses that would be negated by the if stmts
                foreach ($new_assigned_var_ids as $var_id => $_) {
                    $if_scope->reasonable_clauses = Context::filterClauses($var_id, $if_scope->reasonable_clauses, $if_context->vars_in_scope[$var_id] ?? null, $statements_analyzer);
                }
            }
        } else {
            if (!$has_break_statement) {
                $if_scope->reasonable_clauses = [];
                // If we're assigning inside
                if ($if_conditional_scope->assigned_in_conditional_var_ids && $if_scope->post_leaving_if_context) {
                    self::addConditionallyAssignedVarsToContext($statements_analyzer, $stmt->cond, $if_scope->post_leaving_if_context, $outer_context, $if_conditional_scope->assigned_in_conditional_var_ids);
                }
            }
        }
        // update the parent context as necessary, but only if we can safely reason about type negation.
        // We only update vars that changed both at the start of the if block and then again by an assignment
        // in the if statement.
        if ($if_scope->negated_types) {
            $vars_to_update = array_intersect(array_keys($pre_assignment_else_redefined_vars), array_keys($if_scope->negated_types));
            $extra_vars_to_update = [];
            // if there's an object-like array in there, we also need to update the root array variable
            foreach ($vars_to_update as $var_id) {
                $bracked_pos = strpos($var_id, '[');
                if ($bracked_pos !== \false) {
                    $extra_vars_to_update[] = substr($var_id, 0, $bracked_pos);
                }
            }
            if ($extra_vars_to_update) {
                $vars_to_update = array_unique(array_merge($extra_vars_to_update, $vars_to_update));
            }
            $outer_context->update($old_if_context, $if_context, $has_leaving_statements, $vars_to_update, $if_scope->updated_vars);
        }
        if (!$has_ending_statements) {
            $vars_possibly_in_scope = array_diff_key($if_context->vars_possibly_in_scope, $outer_context->vars_possibly_in_scope);
            if ($if_context->loop_scope) {
                if (!$has_continue_statement && !$has_break_statement) {
                    $if_scope->new_vars_possibly_in_scope = $vars_possibly_in_scope;
                }
                $if_context->loop_scope->vars_possibly_in_scope = array_merge($vars_possibly_in_scope, $if_context->loop_scope->vars_possibly_in_scope);
            } elseif (!$has_leaving_statements) {
                $if_scope->new_vars_possibly_in_scope = $vars_possibly_in_scope;
            }
        }
        if ($outer_context->collect_exceptions) {
            $outer_context->mergeExceptions($if_context);
        }
        // Track references set in the if to make sure they aren't reused later
        $outer_context->updateReferencesPossiblyFromConfusingScope($if_context, $statements_analyzer);
        return null;
    }
    /**
     * @param array<string, int> $assigned_in_conditional_var_ids
     */
    public static function addConditionallyAssignedVarsToContext(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $cond, Context $post_leaving_if_context, Context $post_if_context, array $assigned_in_conditional_var_ids) : void
    {
        // this filters out coercions to expected types in ArgumentAnalyzer
        $assigned_in_conditional_var_ids = array_filter($assigned_in_conditional_var_ids);
        if (!$assigned_in_conditional_var_ids) {
            return;
        }
        $exprs = self::getDefinitelyEvaluatedOredExpressions($cond);
        // if there was no assignment in the first expression it's safe to proceed
        $old_node_data = $statements_analyzer->node_data;
        $statements_analyzer->node_data = clone $old_node_data;
        IssueBuffer::startRecording();
        foreach ($exprs as $expr) {
            if ($expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd) {
                $fake_not = new VirtualBooleanOr(self::negateExpr($expr->left), self::negateExpr($expr->right), $expr->getAttributes());
            } else {
                $fake_not = self::negateExpr($expr);
            }
            $fake_negated_expr = new VirtualFuncCall(new VirtualFullyQualified('assert'), [new VirtualArg($fake_not, \false, \false, $expr->getAttributes())], $expr->getAttributes());
            $post_leaving_if_context->inside_negation = !$post_leaving_if_context->inside_negation;
            ExpressionAnalyzer::analyze($statements_analyzer, $fake_negated_expr, $post_leaving_if_context);
            $post_leaving_if_context->inside_negation = !$post_leaving_if_context->inside_negation;
        }
        IssueBuffer::clearRecordingLevel();
        IssueBuffer::stopRecording();
        $statements_analyzer->node_data = $old_node_data;
        foreach ($assigned_in_conditional_var_ids as $var_id => $_) {
            if (isset($post_leaving_if_context->vars_in_scope[$var_id])) {
                $post_if_context->vars_in_scope[$var_id] = $post_leaving_if_context->vars_in_scope[$var_id];
            }
        }
    }
    /**
     * Returns all expressions inside an ored expression
     *
     * @return non-empty-list<PhpParser\Node\Expr>
     */
    private static function getDefinitelyEvaluatedOredExpressions(PhpParser\Node\Expr $stmt) : array
    {
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalOr || $stmt instanceof PhpParser\Node\Expr\BinaryOp\LogicalXor) {
            return [...self::getDefinitelyEvaluatedOredExpressions($stmt->left), ...self::getDefinitelyEvaluatedOredExpressions($stmt->right)];
        }
        return [$stmt];
    }
    private static function negateExpr(PhpParser\Node\Expr $expr) : PhpParser\Node\Expr
    {
        if ($expr instanceof PhpParser\Node\Expr\BooleanNot) {
            return $expr->expr;
        }
        return new VirtualBooleanNot($expr, $expr->getAttributes());
    }
    /**
     * @param  array<string, int>    $assigned_var_ids
     * @param  array<string, bool>   $possibly_assigned_var_ids
     * @param  array<string, bool>   $newly_reconciled_var_ids
     */
    public static function updateIfScope(Codebase $codebase, IfScope $if_scope, Context $if_context, Context $outer_context, array $assigned_var_ids, array $possibly_assigned_var_ids, array $newly_reconciled_var_ids, bool $update_new_vars = \true) : void
    {
        $redefined_vars = $if_context->getRedefinedVars($outer_context->vars_in_scope);
        if ($if_scope->new_vars === null) {
            if ($update_new_vars) {
                $if_scope->new_vars = array_diff_key($if_context->vars_in_scope, $outer_context->vars_in_scope);
            }
        } else {
            foreach ($if_scope->new_vars as $new_var => $type) {
                if (!$if_context->hasVariable($new_var)) {
                    unset($if_scope->new_vars[$new_var]);
                } else {
                    $if_scope->new_vars[$new_var] = Type::combineUnionTypes($type, $if_context->vars_in_scope[$new_var], $codebase);
                }
            }
        }
        $possibly_redefined_vars = $redefined_vars;
        foreach ($possibly_redefined_vars as $var_id => $_) {
            if (!isset($possibly_assigned_var_ids[$var_id]) && isset($newly_reconciled_var_ids[$var_id])) {
                unset($possibly_redefined_vars[$var_id]);
            }
        }
        if ($if_scope->assigned_var_ids === null) {
            $if_scope->assigned_var_ids = $assigned_var_ids;
        } else {
            $if_scope->assigned_var_ids = array_intersect_key($assigned_var_ids, $if_scope->assigned_var_ids);
        }
        $if_scope->possibly_assigned_var_ids += $possibly_assigned_var_ids;
        if ($if_scope->redefined_vars === null) {
            $if_scope->redefined_vars = $redefined_vars;
            $if_scope->possibly_redefined_vars = $possibly_redefined_vars;
        } else {
            foreach ($if_scope->redefined_vars as $redefined_var => $type) {
                if (!isset($redefined_vars[$redefined_var])) {
                    unset($if_scope->redefined_vars[$redefined_var]);
                } else {
                    $if_scope->redefined_vars[$redefined_var] = Type::combineUnionTypes($redefined_vars[$redefined_var], $type, $codebase);
                    if (isset($outer_context->vars_in_scope[$redefined_var]) && $if_scope->redefined_vars[$redefined_var]->equals($outer_context->vars_in_scope[$redefined_var])) {
                        unset($if_scope->redefined_vars[$redefined_var]);
                    }
                }
            }
            foreach ($possibly_redefined_vars as $var => $type) {
                $if_scope->possibly_redefined_vars[$var] = Type::combineUnionTypes($type, $if_scope->possibly_redefined_vars[$var] ?? null, $codebase);
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements\Block;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Scope\LoopScope;
use Psalm\Type;
use UnexpectedValueException;
use function array_merge;
use function count;
use function in_array;
use function is_string;
/**
 * @internal
 */
class ForAnalyzer
{
    /**
     * @return  false|null
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\For_ $stmt, Context $context) : ?bool
    {
        $pre_assigned_var_ids = $context->assigned_var_ids;
        $context->assigned_var_ids = [];
        $init_var_types = [];
        foreach ($stmt->init as $init) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $init, $context) === \false) {
                return \false;
            }
            if ($init instanceof PhpParser\Node\Expr\Assign && $init->var instanceof PhpParser\Node\Expr\Variable && is_string($init->var->name) && ($init_var_type = $statements_analyzer->node_data->getType($init->expr))) {
                $init_var_types[$init->var->name] = $init_var_type;
            }
        }
        $assigned_var_ids = $context->assigned_var_ids;
        $context->assigned_var_ids = array_merge($pre_assigned_var_ids, $assigned_var_ids);
        $while_true = !$stmt->cond && !$stmt->init && !$stmt->loop;
        $pre_context = null;
        if ($while_true) {
            $pre_context = clone $context;
        }
        $for_context = clone $context;
        $for_context->inside_loop = \true;
        $for_context->break_types[] = 'loop';
        $codebase = $statements_analyzer->getCodebase();
        if ($codebase->alter_code) {
            $for_context->branch_point = $for_context->branch_point ?: (int) $stmt->getAttribute('startFilePos');
        }
        $loop_scope = new LoopScope($for_context, $context);
        $loop_scope->protected_var_ids = array_merge($assigned_var_ids, $context->protected_var_ids);
        if (\Psalm\Internal\Analyzer\Statements\Block\LoopAnalyzer::analyze($statements_analyzer, $stmt->stmts, $stmt->cond, $stmt->loop, $loop_scope, $inner_loop_context) === \false) {
            return \false;
        }
        if (!$inner_loop_context) {
            throw new UnexpectedValueException('There should be an inner loop context');
        }
        $always_enters_loop = \false;
        foreach ($stmt->cond as $cond) {
            if ($cond_type = $statements_analyzer->node_data->getType($cond)) {
                $always_enters_loop = $cond_type->isAlwaysTruthy();
            }
            if (count($stmt->init) === 1 && count($stmt->cond) === 1 && $cond instanceof PhpParser\Node\Expr\BinaryOp && ($cond_value = $statements_analyzer->node_data->getType($cond->right)) && ($cond_value->isSingleIntLiteral() || $cond_value->isSingleStringLiteral()) && $cond->left instanceof PhpParser\Node\Expr\Variable && is_string($cond->left->name) && isset($init_var_types[$cond->left->name]) && $init_var_types[$cond->left->name]->isSingleIntLiteral()) {
                $init_value = $init_var_types[$cond->left->name]->getSingleLiteral()->value;
                $cond_value = $cond_value->getSingleLiteral()->value;
                if ($cond instanceof PhpParser\Node\Expr\BinaryOp\Smaller && $init_value < $cond_value) {
                    $always_enters_loop = \true;
                    break;
                }
                if ($cond instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual && $init_value <= $cond_value) {
                    $always_enters_loop = \true;
                    break;
                }
                if ($cond instanceof PhpParser\Node\Expr\BinaryOp\Greater && $init_value > $cond_value) {
                    $always_enters_loop = \true;
                    break;
                }
                if ($cond instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual && $init_value >= $cond_value) {
                    $always_enters_loop = \true;
                    break;
                }
            }
        }
        if ($while_true) {
            $always_enters_loop = \true;
        }
        $can_leave_loop = !$while_true || in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, \true);
        if ($always_enters_loop && $can_leave_loop) {
            foreach ($inner_loop_context->vars_in_scope as $var_id => $type) {
                // if there are break statements in the loop it's not certain
                // that the loop has finished executing, so the assertions at the end
                // the loop in the while conditional may not hold
                if (in_array(ScopeAnalyzer::ACTION_BREAK, $loop_scope->final_actions, \true) || in_array(ScopeAnalyzer::ACTION_CONTINUE, $loop_scope->final_actions, \true)) {
                    if (isset($loop_scope->possibly_defined_loop_parent_vars[$var_id])) {
                        $context->vars_in_scope[$var_id] = Type::combineUnionTypes($type, $loop_scope->possibly_defined_loop_parent_vars[$var_id]);
                    }
                } else {
                    $context->vars_in_scope[$var_id] = $type;
                }
            }
        }
        $for_context->loop_scope = null;
        if ($can_leave_loop) {
            $context->vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $for_context->vars_possibly_in_scope);
        } elseif ($pre_context) {
            $context->vars_possibly_in_scope = $pre_context->vars_possibly_in_scope;
        }
        if ($context->collect_exceptions) {
            $context->mergeExceptions($for_context);
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\FileManipulation;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\PhpVisitor\CheckTrivialExprVisitor;
use function array_key_exists;
use function array_slice;
use function count;
use function is_array;
use function is_string;
use function strlen;
use function substr;
use function token_get_all;
use function trim;
/**
 * @internal
 */
class UnusedAssignmentRemover
{
    /**
     * @var array<string, CodeLocation>
     */
    private array $removed_unref_vars = [];
    /**
     * @param array<PhpParser\Node\Stmt>   $stmts
     * @param array<string, CodeLocation> $var_loc_map
     */
    public function findUnusedAssignment(Codebase $codebase, array $stmts, array $var_loc_map, string $var_id, CodeLocation $original_location) : void
    {
        $search_result = $this->findAssignStmt($stmts, $var_id, $original_location);
        [$assign_stmt, $assign_exp] = $search_result;
        $chain_assignment = \false;
        if ($assign_stmt !== null && $assign_exp !== null) {
            // Check if we have to remove assignment statement as expression (i.e. just "$var = ")
            // Consider chain of assignments
            $rhs_exp = $assign_exp->expr;
            if ($rhs_exp instanceof PhpParser\Node\Expr\Assign || $rhs_exp instanceof PhpParser\Node\Expr\AssignOp || $rhs_exp instanceof PhpParser\Node\Expr\AssignRef) {
                $chain_assignment = \true;
                $removable_stmt = $this->checkRemovableChainAssignment($assign_exp, $var_loc_map);
            } else {
                $removable_stmt = \true;
            }
            if ($removable_stmt) {
                $traverser = new PhpParser\NodeTraverser();
                $visitor = new CheckTrivialExprVisitor();
                $traverser->addVisitor($visitor);
                $traverser->traverse([$rhs_exp]);
                $rhs_exp_trivial = count($visitor->getNonTrivialExpr()) === 0;
                if ($rhs_exp_trivial) {
                    $treat_as_expr = \false;
                } else {
                    $treat_as_expr = \true;
                }
            } else {
                $treat_as_expr = \true;
            }
            if ($treat_as_expr) {
                $is_assign_ref = $assign_exp instanceof PhpParser\Node\Expr\AssignRef;
                $new_file_manipulation = self::getPartialRemovalBounds($codebase, $original_location, $assign_stmt->getEndFilePos(), $is_assign_ref);
                $this->removed_unref_vars[$var_id] = $original_location;
            } else {
                // Remove whole assignment statement
                $new_file_manipulation = new FileManipulation($assign_stmt->getStartFilePos(), $assign_stmt->getEndFilePos() + 1, "", \false, \true);
                // If statement we are removing is a chain of assignments, mark other variables as removed
                if ($chain_assignment) {
                    $this->markRemovedChainAssignVar($assign_exp, $var_loc_map);
                } else {
                    $this->removed_unref_vars[$var_id] = $original_location;
                }
            }
            FileManipulationBuffer::add($original_location->file_path, [$new_file_manipulation]);
        } elseif ($assign_exp !== null) {
            $is_assign_ref = $assign_exp instanceof PhpParser\Node\Expr\AssignRef;
            $new_file_manipulation = self::getPartialRemovalBounds($codebase, $original_location, $assign_exp->getEndFilePos(), $is_assign_ref);
            FileManipulationBuffer::add($original_location->file_path, [$new_file_manipulation]);
            $this->removed_unref_vars[$var_id] = $original_location;
        }
    }
    private static function getPartialRemovalBounds(Codebase $codebase, CodeLocation $var_loc, int $end_bound, bool $assign_ref = \false) : FileManipulation
    {
        $var_start_loc = $var_loc->raw_file_start;
        $stmt_content = $codebase->file_provider->getContents($var_loc->file_path);
        $str_for_token = "<?php\n" . substr($stmt_content, $var_start_loc, $end_bound - $var_start_loc + 1);
        $token_list = array_slice(token_get_all($str_for_token), 1);
        //Ignore "<?php"
        $offset_count = strlen($token_list[0][1]);
        $iter = 1;
        // Check if second token is just whitespace
        if (is_array($token_list[$iter]) && trim($token_list[$iter][1]) === '') {
            $offset_count += strlen($token_list[1][1]);
            $iter++;
        }
        // Add offset for assignment operator
        if (is_string($token_list[$iter])) {
            $offset_count += 1;
        } else {
            $offset_count += strlen($token_list[$iter][1]);
        }
        $iter++;
        // Remove any whitespace following assignment operator token (e.g "=", "+=")
        if (is_array($token_list[$iter]) && trim($token_list[$iter][1]) === '') {
            $offset_count += strlen($token_list[$iter][1]);
            $iter++;
        }
        // If we are dealing with assignment by reference, we need to handle "&" and any whitespace after
        if ($assign_ref) {
            $offset_count += 1;
            $iter++;
            // Handle any whitespace after "&"
            if (is_array($token_list[$iter]) && trim($token_list[$iter][1]) === '') {
                $offset_count += strlen($token_list[$iter][1]);
            }
        }
        $file_man_start = $var_start_loc;
        $file_man_end = $var_start_loc + $offset_count;
        return new FileManipulation($file_man_start, $file_man_end, "", \false);
    }
    /**
     * @param  PhpParser\Node\Expr\Assign|PhpParser\Node\Expr\AssignOp|PhpParser\Node\Expr\AssignRef $cur_assign
     * @param  array<string, CodeLocation>    $var_loc_map
     */
    private function markRemovedChainAssignVar(PhpParser\Node\Expr $cur_assign, array $var_loc_map) : void
    {
        $var = $cur_assign->var;
        if ($var instanceof PhpParser\Node\Expr\Variable && is_string($var->name)) {
            $var_name = "\$" . $var->name;
            $var_loc = $var_loc_map[$var_name];
            $this->removed_unref_vars[$var_name] = $var_loc;
            $rhs_exp = $cur_assign->expr;
            if ($rhs_exp instanceof PhpParser\Node\Expr\Assign || $rhs_exp instanceof PhpParser\Node\Expr\AssignOp || $rhs_exp instanceof PhpParser\Node\Expr\AssignRef) {
                $this->markRemovedChainAssignVar($rhs_exp, $var_loc_map);
            }
        }
    }
    /**
     * @param  PhpParser\Node\Expr\Assign|PhpParser\Node\Expr\AssignOp|PhpParser\Node\Expr\AssignRef $cur_assign
     * @param  array<string, CodeLocation> $var_loc_map
     */
    private function checkRemovableChainAssignment(PhpParser\Node\Expr $cur_assign, array $var_loc_map) : bool
    {
        // Check if current assignment expr's variable is removable
        $var = $cur_assign->var;
        if ($var instanceof PhpParser\Node\Expr\Variable && is_string($var->name)) {
            $var_loc = $cur_assign->var->getStartFilePos();
            $var_name = "\$" . $var->name;
            if (array_key_exists($var_name, $var_loc_map) && $var_loc_map[$var_name]->raw_file_start === $var_loc) {
                $curr_removable = \true;
            } else {
                $curr_removable = \false;
            }
            if ($curr_removable) {
                $rhs_exp = $cur_assign->expr;
                if ($rhs_exp instanceof PhpParser\Node\Expr\Assign || $rhs_exp instanceof PhpParser\Node\Expr\AssignOp || $rhs_exp instanceof PhpParser\Node\Expr\AssignRef) {
                    return $this->checkRemovableChainAssignment($rhs_exp, $var_loc_map);
                }
            }
            return $curr_removable;
        }
        return \false;
    }
    /**
     * @param  array<PhpParser\Node\Stmt>   $stmts
     * @return array{
     *          0: PhpParser\Node\Stmt|null,
     *          1: PhpParser\Node\Expr\Assign|PhpParser\Node\Expr\AssignOp|PhpParser\Node\Expr\AssignRef|null
     *          }
     */
    private function findAssignStmt(array $stmts, string $var_id, CodeLocation $original_location) : array
    {
        $assign_stmt = null;
        $assign_exp = null;
        $assign_exp_found = \false;
        $i = 0;
        while ($i < count($stmts) && !$assign_exp_found) {
            $stmt = $stmts[$i];
            if ($stmt instanceof PhpParser\Node\Stmt\Expression) {
                $search_result = $this->findAssignExp($stmt->expr, $var_id, $original_location->raw_file_start);
                [$target_exp, $levels_taken] = $search_result;
                if ($target_exp !== null) {
                    $assign_exp_found = \true;
                    $assign_exp = $target_exp;
                    $assign_stmt = $levels_taken === 1 ? $stmt : null;
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\TryCatch) {
                $search_result = $this->findAssignStmt($stmt->stmts, $var_id, $original_location);
                if ($search_result[0] && $search_result[1]) {
                    return $search_result;
                }
                foreach ($stmt->catches as $catch_stmt) {
                    $search_result = $this->findAssignStmt($catch_stmt->stmts, $var_id, $original_location);
                    if ($search_result[0] && $search_result[1]) {
                        return $search_result;
                    }
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Do_ || $stmt instanceof PhpParser\Node\Stmt\While_) {
                $search_result = $this->findAssignStmt($stmt->stmts, $var_id, $original_location);
                if ($search_result[0] && $search_result[1]) {
                    return $search_result;
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Foreach_) {
                $search_result = $this->findAssignStmt($stmt->stmts, $var_id, $original_location);
                if ($search_result[0] && $search_result[1]) {
                    return $search_result;
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\For_) {
                $search_result = $this->findAssignStmt($stmt->stmts, $var_id, $original_location);
                if ($search_result[0] && $search_result[1]) {
                    return $search_result;
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\If_) {
                $search_result = $this->findAssignStmt($stmt->stmts, $var_id, $original_location);
                if ($search_result[0] && $search_result[1]) {
                    return $search_result;
                }
                foreach ($stmt->elseifs as $elseif_stmt) {
                    $search_result = $this->findAssignStmt($elseif_stmt->stmts, $var_id, $original_location);
                    if ($search_result[0] && $search_result[1]) {
                        return $search_result;
                    }
                }
                if ($stmt->else) {
                    $search_result = $this->findAssignStmt($stmt->else->stmts, $var_id, $original_location);
                    if ($search_result[0] && $search_result[1]) {
                        return $search_result;
                    }
                }
            }
            $i++;
        }
        return [$assign_stmt, $assign_exp];
    }
    /**
     * @return array{
     *          0: PhpParser\Node\Expr\Assign|PhpParser\Node\Expr\AssignOp|PhpParser\Node\Expr\AssignRef|null,
     *          1: int
     *          }
     */
    private function findAssignExp(PhpParser\Node\Expr $current_node, string $var_id, int $var_start_loc, int $search_level = 1) : array
    {
        if ($current_node instanceof PhpParser\Node\Expr\Assign || $current_node instanceof PhpParser\Node\Expr\AssignOp || $current_node instanceof PhpParser\Node\Expr\AssignRef) {
            $var = $current_node->var;
            if ($var instanceof PhpParser\Node\Expr\Variable && $var->name === substr($var_id, 1) && $var->getStartFilePos() === $var_start_loc) {
                return [$current_node, $search_level];
            }
            $rhs_exp = $current_node->expr;
            $rhs_search_result = $this->findAssignExp($rhs_exp, $var_id, $var_start_loc, $search_level + 1);
            return [$rhs_search_result[0], $rhs_search_result[1]];
        }
        return [null, $search_level];
    }
    public function checkIfVarRemoved(string $var_id, CodeLocation $var_loc) : bool
    {
        return array_key_exists($var_id, $this->removed_unref_vars) && $this->removed_unref_vars[$var_id] === $var_loc;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
use function end;
/**
 * @internal
 */
class BreakAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Break_ $stmt, Context $context) : void
    {
        $loop_scope = $context->loop_scope;
        $leaving_switch = \true;
        if ($loop_scope) {
            if ($context->break_types && end($context->break_types) === 'switch' && (!$stmt->num instanceof PhpParser\Node\Scalar\LNumber || $stmt->num->value < 2)) {
                $loop_scope->final_actions[] = ScopeAnalyzer::ACTION_LEAVE_SWITCH;
            } else {
                $leaving_switch = \false;
                $loop_scope->final_actions[] = ScopeAnalyzer::ACTION_BREAK;
            }
            $redefined_vars = $context->getRedefinedVars($loop_scope->loop_parent_context->vars_in_scope);
            foreach ($redefined_vars as $var => $type) {
                $loop_scope->possibly_redefined_loop_parent_vars[$var] = Type::combineUnionTypes($type, $loop_scope->possibly_redefined_loop_parent_vars[$var] ?? null);
            }
            if ($loop_scope->iteration_count === 0) {
                foreach ($context->vars_in_scope as $var_id => $type) {
                    if (!isset($loop_scope->loop_parent_context->vars_in_scope[$var_id])) {
                        $loop_scope->possibly_defined_loop_parent_vars[$var_id] = Type::combineUnionTypes($type, $loop_scope->possibly_defined_loop_parent_vars[$var_id] ?? null);
                    }
                }
            }
            if ($context->finally_scope) {
                foreach ($context->vars_in_scope as $var_id => &$type) {
                    if (isset($context->finally_scope->vars_in_scope[$var_id])) {
                        $context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes($context->finally_scope->vars_in_scope[$var_id], $type, $statements_analyzer->getCodebase());
                    } else {
                        $type = $type->setPossiblyUndefined(\true, \true);
                        $context->finally_scope->vars_in_scope[$var_id] = $type;
                    }
                }
                unset($type);
            }
        }
        $case_scope = $context->case_scope;
        if ($case_scope && $leaving_switch) {
            foreach ($context->vars_in_scope as $var_id => $type) {
                if ($case_scope->break_vars === null) {
                    $case_scope->break_vars = [];
                }
                $case_scope->break_vars[$var_id] = Type::combineUnionTypes($type, $case_scope->break_vars[$var_id] ?? null);
            }
        }
        $context->has_returned = \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\Internal\Analyzer\ClosureAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ArrayAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssertionFinder;
use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BinaryOpAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BitwiseNotAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\BooleanNotAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\MethodCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\NewAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CastAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ClassConstAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CloneAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\EmptyAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\EncapsulatedStringAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\EvalAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ExitAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ArrayFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ConstFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\InstancePropertyFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\StaticPropertyFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\VariableFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\IncDecExpressionAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\IncludeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\InstanceofAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\IssetAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\MagicConstAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\MatchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\NullsafeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\PrintAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\TernaryAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\UnaryPlusMinusAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\YieldAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\YieldFromAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Issue\ForbiddenCode;
use Psalm\Issue\UnrecognizedExpression;
use Psalm\Issue\UnsupportedReferenceUsage;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AfterExpressionAnalysisEvent;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\TaintKind;
use function get_class;
use function in_array;
use function strtolower;
/**
 * @internal
 */
class ExpressionAnalyzer
{
    /**
     * @param bool $assigned_to_reference This is set to true when the expression being analyzed
     *                                    here is being assigned to another variable by reference.
     */
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Context $context, bool $array_assignment = \false, ?Context $global_context = null, bool $from_stmt = \false, ?TemplateResult $template_result = null, bool $assigned_to_reference = \false) : bool
    {
        $codebase = $statements_analyzer->getCodebase();
        if (self::handleExpression($statements_analyzer, $stmt, $context, $array_assignment, $global_context, $from_stmt, $template_result, $assigned_to_reference) === \false) {
            return \false;
        }
        if (!$context->inside_conditional && ($stmt instanceof PhpParser\Node\Expr\BinaryOp || $stmt instanceof PhpParser\Node\Expr\Instanceof_ || $stmt instanceof PhpParser\Node\Expr\Assign || $stmt instanceof PhpParser\Node\Expr\BooleanNot || $stmt instanceof PhpParser\Node\Expr\Empty_ || $stmt instanceof PhpParser\Node\Expr\Isset_ || $stmt instanceof PhpParser\Node\Expr\FuncCall)) {
            $assertions = $statements_analyzer->node_data->getAssertions($stmt);
            if ($assertions === null) {
                $negate = $context->inside_negation;
                while ($stmt instanceof PhpParser\Node\Expr\BooleanNot) {
                    $stmt = $stmt->expr;
                    $negate = !$negate;
                }
                AssertionFinder::scrapeAssertions($stmt, $context->self, $statements_analyzer, $codebase, $negate, \true, \false);
            }
        }
        $event = new AfterExpressionAnalysisEvent($stmt, $context, $statements_analyzer, $codebase, []);
        if ($codebase->config->eventDispatcher->dispatchAfterExpressionAnalysis($event) === \false) {
            return \false;
        }
        $file_manipulations = $event->getFileReplacements();
        if ($file_manipulations) {
            FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
        }
        return \true;
    }
    /**
     * @param bool $assigned_to_reference This is set to true when the expression being analyzed
     *                                    here is being assigned to another variable by reference.
     */
    private static function handleExpression(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Context $context, bool $array_assignment, ?Context $global_context, bool $from_stmt, ?TemplateResult $template_result = null, bool $assigned_to_reference = \false) : bool
    {
        if ($stmt instanceof PhpParser\Node\Expr\Variable) {
            return VariableFetchAnalyzer::analyze($statements_analyzer, $stmt, $context, \false, null, $array_assignment, \false, $assigned_to_reference);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Assign) {
            return self::analyzeAssignment($statements_analyzer, $stmt, $context, $from_stmt);
        }
        if ($stmt instanceof PhpParser\Node\Expr\AssignOp) {
            return AssignmentAnalyzer::analyzeAssignmentOperation($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\MethodCall) {
            return MethodCallAnalyzer::analyze($statements_analyzer, $stmt, $context, \true, $template_result);
        }
        if ($stmt instanceof PhpParser\Node\Expr\StaticCall) {
            return StaticCallAnalyzer::analyze($statements_analyzer, $stmt, $context, $template_result);
        }
        if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
            ConstFetchAnalyzer::analyze($statements_analyzer, $stmt, $context);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\String_) {
            $statements_analyzer->node_data->setType($stmt, Type::getString($stmt->value));
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\EncapsedStringPart) {
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\MagicConst) {
            MagicConstAnalyzer::analyze($statements_analyzer, $stmt, $context);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\LNumber) {
            $statements_analyzer->node_data->setType($stmt, Type::getInt(\false, $stmt->value));
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\DNumber) {
            $statements_analyzer->node_data->setType($stmt, Type::getFloat($stmt->value));
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\UnaryMinus || $stmt instanceof PhpParser\Node\Expr\UnaryPlus) {
            return UnaryPlusMinusAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Isset_) {
            IssetAnalyzer::analyze($statements_analyzer, $stmt, $context);
            $statements_analyzer->node_data->setType($stmt, Type::getBool());
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\ClassConstFetch) {
            return ClassConstAnalyzer::analyzeFetch($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\PropertyFetch) {
            return InstancePropertyFetchAnalyzer::analyze($statements_analyzer, $stmt, $context, $array_assignment);
        }
        if ($stmt instanceof PhpParser\Node\Expr\StaticPropertyFetch) {
            return StaticPropertyFetchAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\BitwiseNot) {
            return BitwiseNotAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
            return BinaryOpAnalyzer::analyze($statements_analyzer, $stmt, $context, 0, $from_stmt);
        }
        if ($stmt instanceof PhpParser\Node\Expr\PostInc || $stmt instanceof PhpParser\Node\Expr\PostDec || $stmt instanceof PhpParser\Node\Expr\PreInc || $stmt instanceof PhpParser\Node\Expr\PreDec) {
            return IncDecExpressionAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\New_) {
            return NewAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Array_) {
            return ArrayAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Scalar\Encapsed) {
            return EncapsulatedStringAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\FuncCall) {
            return FunctionCallAnalyzer::analyze($statements_analyzer, $stmt, $context, $template_result);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Ternary) {
            return TernaryAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\BooleanNot) {
            return BooleanNotAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Empty_) {
            EmptyAnalyzer::analyze($statements_analyzer, $stmt, $context);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Closure || $stmt instanceof PhpParser\Node\Expr\ArrowFunction) {
            return ClosureAnalyzer::analyzeExpression($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch) {
            return ArrayFetchAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Cast) {
            return CastAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Clone_) {
            return CloneAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Instanceof_) {
            return InstanceofAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Exit_) {
            return ExitAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Include_) {
            return IncludeAnalyzer::analyze($statements_analyzer, $stmt, $context, $global_context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Eval_) {
            EvalAnalyzer::analyze($statements_analyzer, $stmt, $context);
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\AssignRef) {
            if (!AssignmentAnalyzer::analyzeAssignmentRef($statements_analyzer, $stmt, $context)) {
                IssueBuffer::maybeAdd(new UnsupportedReferenceUsage("This reference cannot be analyzed by Psalm", new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
                // Analyze as if it were a normal assignent and just pretend the reference doesn't exist
                return self::analyzeAssignment($statements_analyzer, $stmt, $context, $from_stmt);
            }
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\ErrorSuppress) {
            $context->error_suppressing = \true;
            if (self::analyze($statements_analyzer, $stmt->expr, $context) === \false) {
                return \false;
            }
            $context->error_suppressing = \false;
            $expr_type = $statements_analyzer->node_data->getType($stmt->expr);
            if ($expr_type) {
                $statements_analyzer->node_data->setType($stmt, $expr_type);
            }
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\ShellExec) {
            if ($statements_analyzer->data_flow_graph) {
                $call_location = new CodeLocation($statements_analyzer->getSource(), $stmt);
                if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph) {
                    $sink = TaintSink::getForMethodArgument('shell_exec', 'shell_exec', 0, null, $call_location);
                    $sink->taints = [TaintKind::INPUT_SHELL];
                    $statements_analyzer->data_flow_graph->addSink($sink);
                }
                foreach ($stmt->parts as $part) {
                    if ($part instanceof PhpParser\Node\Expr\Variable) {
                        if (self::analyze($statements_analyzer, $part, $context) === \false) {
                            break;
                        }
                        $expr_type = $statements_analyzer->node_data->getType($part);
                        if ($expr_type === null) {
                            break;
                        }
                        $shell_exec_param = new FunctionLikeParameter('var', \false);
                        if (ArgumentAnalyzer::verifyType($statements_analyzer, $expr_type, Type::getString(), null, 'shell_exec', null, 0, $call_location, $stmt, $context, $shell_exec_param, \false, null, \true, \true, new CodeLocation($statements_analyzer, $stmt)) === \false) {
                            return \false;
                        }
                        foreach ($expr_type->parent_nodes as $parent_node) {
                            $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('variable-use', 'variable use', null), 'variable-use');
                        }
                    }
                }
            }
            IssueBuffer::maybeAdd(new ForbiddenCode('Use of shell_exec', new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Print_) {
            $was_inside_call = $context->inside_call;
            $context->inside_call = \true;
            if (PrintAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                $context->inside_call = $was_inside_call;
                return \false;
            }
            $context->inside_call = $was_inside_call;
            return \true;
        }
        if ($stmt instanceof PhpParser\Node\Expr\Yield_) {
            return YieldAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\YieldFrom) {
            return YieldFromAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        $codebase = $statements_analyzer->getCodebase();
        $analysis_php_version_id = $codebase->analysis_php_version_id;
        if ($stmt instanceof PhpParser\Node\Expr\Match_ && $analysis_php_version_id >= 80000) {
            return MatchAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Throw_ && $analysis_php_version_id >= 80000) {
            return \Psalm\Internal\Analyzer\Statements\ThrowAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if (($stmt instanceof PhpParser\Node\Expr\NullsafePropertyFetch || $stmt instanceof PhpParser\Node\Expr\NullsafeMethodCall) && $analysis_php_version_id >= 80000) {
            return NullsafeAnalyzer::analyze($statements_analyzer, $stmt, $context);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Error) {
            // do nothing
            return \true;
        }
        IssueBuffer::maybeAdd(new UnrecognizedExpression('Psalm does not understand ' . get_class($stmt) . ' for PHP ' . $codebase->getMajorAnalysisPhpVersion() . '.' . $codebase->getMinorAnalysisPhpVersion(), new CodeLocation($statements_analyzer->getSource(), $stmt)), $statements_analyzer->getSuppressedIssues());
        return \false;
    }
    public static function isMock(string $fq_class_name) : bool
    {
        return in_array(strtolower($fq_class_name), Config::getInstance()->getMockClasses(), \true);
    }
    /**
     * @param PhpParser\Node\Expr\Assign|PhpParser\Node\Expr\AssignRef $stmt
     */
    private static function analyzeAssignment(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr $stmt, Context $context, bool $from_stmt) : bool
    {
        $assignment_type = AssignmentAnalyzer::analyze($statements_analyzer, $stmt->var, $stmt->expr, null, $context, $stmt->getDocComment(), [], !$from_stmt ? $stmt : null);
        if ($assignment_type === \false) {
            return \false;
        }
        if (!$from_stmt) {
            $statements_analyzer->node_data->setType($stmt, $assignment_type);
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Issue\ContinueOutsideLoop;
use Psalm\IssueBuffer;
use Psalm\Type;
use function end;
/**
 * @internal
 */
class ContinueAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Continue_ $stmt, Context $context) : void
    {
        $count = $stmt->num instanceof PhpParser\Node\Scalar\LNumber ? $stmt->num->value : 1;
        $loop_scope = $context->loop_scope;
        if ($count === 2 && isset($loop_scope->loop_parent_context->loop_scope)) {
            $loop_scope = $loop_scope->loop_parent_context->loop_scope;
        }
        if ($count === 3 && isset($loop_scope->loop_parent_context->loop_scope)) {
            $loop_scope = $loop_scope->loop_parent_context->loop_scope;
        }
        if ($loop_scope === null) {
            if (!$context->break_types) {
                if (IssueBuffer::accepts(new ContinueOutsideLoop('Continue call outside loop context', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSource()->getSuppressedIssues())) {
                    return;
                }
            }
        } else {
            if ($context->break_types && end($context->break_types) === 'switch' && $count < 2) {
                $loop_scope->final_actions[] = ScopeAnalyzer::ACTION_LEAVE_SWITCH;
            } else {
                $loop_scope->final_actions[] = ScopeAnalyzer::ACTION_CONTINUE;
            }
            $redefined_vars = $context->getRedefinedVars($loop_scope->loop_parent_context->vars_in_scope);
            foreach ($loop_scope->redefined_loop_vars as $redefined_var => $type) {
                if (!isset($redefined_vars[$redefined_var])) {
                    unset($loop_scope->redefined_loop_vars[$redefined_var]);
                } else {
                    $loop_scope->redefined_loop_vars[$redefined_var] = Type::combineUnionTypes($redefined_vars[$redefined_var], $type);
                }
            }
            foreach ($redefined_vars as $var => $type) {
                $loop_scope->possibly_redefined_loop_vars[$var] = Type::combineUnionTypes($type, $loop_scope->possibly_redefined_loop_vars[$var] ?? null);
            }
            if ($context->finally_scope) {
                foreach ($context->vars_in_scope as $var_id => &$type) {
                    if (isset($context->finally_scope->vars_in_scope[$var_id])) {
                        $context->finally_scope->vars_in_scope[$var_id] = Type::combineUnionTypes($context->finally_scope->vars_in_scope[$var_id], $type, $statements_analyzer->getCodebase());
                    } else {
                        $type = $type->setPossiblyUndefined(\true, \true);
                        $context->finally_scope->vars_in_scope[$var_id] = $type;
                    }
                }
            }
        }
        $context->has_returned = \true;
    }
}
<?php

namespace Psalm\Internal\Analyzer\Statements;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\VariableFetchAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\ReferenceConstraint;
use Psalm\Issue\InvalidGlobal;
use Psalm\IssueBuffer;
use function is_string;
/**
 * @internal
 */
class GlobalAnalyzer
{
    public static function analyze(StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Global_ $stmt, Context $context, ?Context $global_context) : void
    {
        if (!$context->collect_initializations && !$global_context) {
            IssueBuffer::maybeAdd(new InvalidGlobal('Cannot use global scope here (unless this file is included from a non-global scope)', new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSource()->getSuppressedIssues());
        }
        $codebase = $statements_analyzer->getCodebase();
        $source = $statements_analyzer->getSource();
        $function_storage = $source instanceof FunctionLikeAnalyzer ? $source->getFunctionLikeStorage($statements_analyzer) : null;
        foreach ($stmt->vars as $var) {
            if ($var instanceof PhpParser\Node\Expr\Variable) {
                if (is_string($var->name)) {
                    $var_id = '$' . $var->name;
                    if ($var->name === 'argv' || $var->name === 'argc') {
                        $context->vars_in_scope[$var_id] = VariableFetchAnalyzer::getGlobalType($var_id, $codebase->analysis_php_version_id);
                    } elseif (isset($function_storage->global_types[$var_id])) {
                        $context->vars_in_scope[$var_id] = $function_storage->global_types[$var_id];
                        $context->vars_possibly_in_scope[$var_id] = \true;
                    } else {
                        $context->vars_in_scope[$var_id] = $global_context && $global_context->hasVariable($var_id) ? $global_context->vars_in_scope[$var_id] : VariableFetchAnalyzer::getGlobalType($var_id, $codebase->analysis_php_version_id);
                        $context->vars_possibly_in_scope[$var_id] = \true;
                        $context->byref_constraints[$var_id] = new ReferenceConstraint();
                    }
                    $assignment_node = DataFlowNode::getForAssignment($var_id, new CodeLocation($statements_analyzer, $var));
                    $context->vars_in_scope[$var_id] = $context->vars_in_scope[$var_id]->setParentNodes([$assignment_node->id => $assignment_node]);
                    $context->references_to_external_scope[$var_id] = \true;
                    if (isset($context->references_in_scope[$var_id])) {
                        // Global shadows existing reference
                        $context->decrementReferenceCount($var_id);
                        unset($context->references_in_scope[$var_id]);
                    }
                    $statements_analyzer->registerVariable($var_id, new CodeLocation($statements_analyzer, $var), $context->branch_point);
                    $statements_analyzer->getCodebase()->analyzer->addNodeReference($statements_analyzer->getFilePath(), $var, $var_id);
                    if ($global_context !== null && $global_context->hasVariable($var_id)) {
                        $global_context->referenced_globals[$var_id] = \true;
                    }
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Config;
use Psalm\Context;
use UnexpectedValueException;
use function is_string;
use function strtolower;
/**
 * @internal
 * @extends FunctionLikeAnalyzer<PhpParser\Node\Stmt\Function_>
 */
class FunctionAnalyzer extends \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
{
    public function __construct(PhpParser\Node\Stmt\Function_ $function, \Psalm\Internal\Analyzer\SourceAnalyzer $source)
    {
        $codebase = $source->getCodebase();
        $file_storage_provider = $codebase->file_storage_provider;
        $file_storage = $file_storage_provider->get($source->getFilePath());
        $namespace = $source->getNamespace();
        $function_id = ($namespace ? strtolower($namespace) . '\\' : '') . strtolower($function->name->name);
        if (!isset($file_storage->functions[$function_id])) {
            throw new UnexpectedValueException('Function ' . $function_id . ' should be defined in ' . $source->getFilePath());
        }
        $storage = $file_storage->functions[$function_id];
        parent::__construct($function, $source, $storage);
    }
    /**
     * @return non-empty-lowercase-string
     * @throws UnexpectedValueException if function is closure or arrow function.
     */
    public function getFunctionId() : string
    {
        $namespace = $this->source->getNamespace();
        /** @var non-empty-lowercase-string */
        return ($namespace ? strtolower($namespace) . '\\' : '') . strtolower($this->function->name->name);
    }
    public static function analyzeStatement(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt\Function_ $stmt, Context $context) : void
    {
        foreach ($stmt->stmts as $function_stmt) {
            if ($function_stmt instanceof PhpParser\Node\Stmt\Global_) {
                foreach ($function_stmt->vars as $var) {
                    if ($var instanceof PhpParser\Node\Expr\Variable) {
                        if (is_string($var->name)) {
                            $var_id = '$' . $var->name;
                            // registers variable in global context
                            $context->hasVariable($var_id);
                        }
                    }
                }
            } elseif (!$function_stmt instanceof PhpParser\Node\Stmt\Nop) {
                break;
            }
        }
        $codebase = $statements_analyzer->getCodebase();
        if (!$codebase->register_stub_files && !$codebase->register_autoload_files) {
            $function_name = strtolower($stmt->name->name);
            if ($ns = $statements_analyzer->getNamespace()) {
                $fq_function_name = strtolower($ns) . '\\' . $function_name;
            } else {
                $fq_function_name = $function_name;
            }
            $function_context = new Context($context->self);
            $function_context->strict_types = $context->strict_types;
            $config = Config::getInstance();
            $function_context->collect_exceptions = $config->check_for_throws_docblock;
            if ($function_analyzer = $statements_analyzer->getFunctionAnalyzer($fq_function_name)) {
                $function_analyzer->analyze($function_context, $statements_analyzer->node_data, $context);
                if ($config->reportIssueInFile('InvalidReturnType', $statements_analyzer->getFilePath())) {
                    $method_id = $function_analyzer->getId();
                    $function_storage = $codebase->functions->getStorage($statements_analyzer, strtolower($method_id));
                    $return_type = $function_storage->return_type;
                    $return_type_location = $function_storage->return_type_location;
                    $function_analyzer->verifyReturnType($stmt->getStmts(), $statements_analyzer, $return_type, $statements_analyzer->getFQCLN(), $return_type_location, $function_context->has_returned);
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeTraverser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\PhpVisitor\ParamReplacementVisitor;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ConstructorSignatureMismatch;
use Psalm\Issue\ImplementedParamTypeMismatch;
use Psalm\Issue\ImplementedReturnTypeMismatch;
use Psalm\Issue\LessSpecificImplementedReturnType;
use Psalm\Issue\MethodSignatureMismatch;
use Psalm\Issue\MethodSignatureMustProvideReturnType;
use Psalm\Issue\MissingImmutableAnnotation;
use Psalm\Issue\MoreSpecificImplementedParamType;
use Psalm\Issue\OverriddenMethodAccess;
use Psalm\Issue\ParamNameMismatch;
use Psalm\Issue\TraitMethodSignatureMismatch;
use Psalm\IssueBuffer;
use Psalm\Storage\AttributeStorage;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_filter;
use function in_array;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class MethodComparator
{
    /**
     * @param  string[]         $suppressed_issues
     * @return false|null
     * @psalm-suppress PossiblyUnusedReturnValue unused but seems important
     */
    public static function compare(Codebase $codebase, ?ClassMethod $stmt, ClassLikeStorage $implementer_classlike_storage, ClassLikeStorage $guide_classlike_storage, MethodStorage $implementer_method_storage, MethodStorage $guide_method_storage, string $implementer_called_class_name, int $implementer_visibility, CodeLocation $code_location, array $suppressed_issues, bool $prevent_abstract_override = \true, bool $prevent_method_signature_mismatch = \true) : ?bool
    {
        $implementer_method_id = new MethodIdentifier($implementer_classlike_storage->name, strtolower($guide_method_storage->cased_name ?: ''));
        $implementer_declaring_method_id = $codebase->methods->getDeclaringMethodId($implementer_method_id);
        $cased_implementer_method_id = $implementer_classlike_storage->name . '::' . $implementer_method_storage->cased_name;
        $cased_guide_method_id = $guide_classlike_storage->name . '::' . $guide_method_storage->cased_name;
        $codebase->methods->file_reference_provider->addMethodDependencyToClassMember(strtolower((string) ($implementer_declaring_method_id ?? $implementer_method_id)), strtolower($guide_classlike_storage->name . '::' . $guide_method_storage->cased_name));
        self::checkForObviousMethodMismatches($guide_classlike_storage, $implementer_classlike_storage, $guide_method_storage, $implementer_method_storage, $guide_method_storage->visibility, $implementer_visibility, $cased_guide_method_id, $cased_implementer_method_id, $prevent_method_signature_mismatch, $prevent_abstract_override, $codebase->analysis_php_version_id >= 80000, $code_location, $suppressed_issues);
        if ($guide_method_storage->signature_return_type && $prevent_method_signature_mismatch) {
            self::compareMethodSignatureReturnTypes($codebase, $guide_classlike_storage, $implementer_classlike_storage, $guide_method_storage, $implementer_method_storage, $guide_method_storage->signature_return_type, $cased_guide_method_id, $implementer_called_class_name, $cased_implementer_method_id, $code_location, $suppressed_issues);
        }
        if (!$guide_classlike_storage->user_defined && $implementer_classlike_storage->user_defined && $codebase->analysis_php_version_id >= 80100 && ($guide_method_storage->return_type || $guide_method_storage->signature_return_type) && !$implementer_method_storage->signature_return_type && !array_filter($implementer_method_storage->attributes, static fn(AttributeStorage $s): bool => $s->fq_class_name === 'ReturnTypeWillChange')) {
            IssueBuffer::maybeAdd(new MethodSignatureMustProvideReturnType('Method ' . $cased_implementer_method_id . ' must have a return type signature!', $implementer_method_storage->location ?: $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
        }
        if ($guide_method_storage->return_type && $implementer_method_storage->return_type && !$implementer_method_storage->inherited_return_type && ($guide_method_storage->signature_return_type !== $guide_method_storage->return_type || $implementer_method_storage->signature_return_type !== $implementer_method_storage->return_type) && $implementer_classlike_storage->user_defined && (!$guide_classlike_storage->stubbed || $guide_classlike_storage->template_types)) {
            self::compareMethodDocblockReturnTypes($codebase, $guide_classlike_storage, $implementer_classlike_storage, $implementer_method_storage, $guide_method_storage->return_type, $implementer_method_storage->return_type, $cased_guide_method_id, $implementer_called_class_name, $implementer_declaring_method_id, $code_location, $suppressed_issues);
        }
        foreach ($guide_method_storage->params as $i => $guide_param) {
            if (!isset($implementer_method_storage->params[$i])) {
                if (!$prevent_abstract_override && $i >= $guide_method_storage->required_param_count) {
                    continue;
                }
                if (IssueBuffer::accepts(new MethodSignatureMismatch('Method ' . $cased_implementer_method_id . ' has fewer parameters than parent method ' . $cased_guide_method_id, $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues)) {
                    return \false;
                }
                return null;
            }
            self::compareMethodParams($codebase, $stmt, $implementer_classlike_storage, $guide_classlike_storage, $implementer_called_class_name, $guide_method_storage, $implementer_method_storage, $guide_param, $implementer_method_storage->params[$i], $i, $cased_guide_method_id, $cased_implementer_method_id, $prevent_method_signature_mismatch, $code_location, $suppressed_issues);
        }
        if ($guide_classlike_storage->user_defined && ($guide_classlike_storage->is_interface || $guide_classlike_storage->preserve_constructor_signature || $implementer_method_storage->cased_name !== '__construct') && $implementer_method_storage->required_param_count > $guide_method_storage->required_param_count) {
            if ($implementer_method_storage->cased_name !== '__construct') {
                if (IssueBuffer::accepts(new MethodSignatureMismatch('Method ' . $cased_implementer_method_id . ' has more required parameters than parent method ' . $cased_guide_method_id, $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues)) {
                    return \false;
                }
            } else {
                if (IssueBuffer::accepts(new ConstructorSignatureMismatch('Method ' . $cased_implementer_method_id . ' has more required parameters than parent method ' . $cased_guide_method_id, $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues)) {
                    return \false;
                }
            }
            return null;
        }
        return null;
    }
    /**
     * @param  string[]         $suppressed_issues
     */
    private static function checkForObviousMethodMismatches(ClassLikeStorage $guide_classlike_storage, ClassLikeStorage $implementer_classlike_storage, MethodStorage $guide_method_storage, MethodStorage $implementer_method_storage, int $guide_visibility, int $implementer_visibility, string $cased_guide_method_id, string $cased_implementer_method_id, bool $prevent_method_signature_mismatch, bool $prevent_abstract_override, bool $trait_mismatches_are_fatal, CodeLocation $code_location, array $suppressed_issues) : void
    {
        if ($implementer_visibility > $guide_visibility) {
            if ($trait_mismatches_are_fatal || $guide_classlike_storage->is_trait === $implementer_classlike_storage->is_trait || !in_array($guide_classlike_storage->name, $implementer_classlike_storage->used_traits) || $implementer_method_storage->defining_fqcln !== $implementer_classlike_storage->name || !$implementer_method_storage->abstract && !$guide_method_storage->abstract) {
                IssueBuffer::maybeAdd(new OverriddenMethodAccess('Method ' . $cased_implementer_method_id . ' has different access level than ' . $cased_guide_method_id, $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
            } else {
                IssueBuffer::maybeAdd(new TraitMethodSignatureMismatch('Method ' . $cased_implementer_method_id . ' has different access level than ' . $cased_guide_method_id, $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
            }
        }
        if ($guide_method_storage->final && $prevent_method_signature_mismatch && $prevent_abstract_override) {
            IssueBuffer::maybeAdd(new MethodSignatureMismatch('Method ' . $cased_guide_method_id . ' is declared final and cannot be overridden', $code_location), $guide_method_storage->final_from_docblock ? $suppressed_issues + $implementer_classlike_storage->suppressed_issues : []);
        }
        if ($prevent_abstract_override && !$guide_method_storage->abstract && $implementer_method_storage->abstract && !$guide_classlike_storage->abstract && !$guide_classlike_storage->is_interface) {
            IssueBuffer::maybeAdd(new MethodSignatureMismatch('Method ' . $cased_implementer_method_id . ' cannot be abstract when inherited method ' . $cased_guide_method_id . ' is non-abstract', $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
        }
        if ($guide_method_storage->external_mutation_free && !$implementer_method_storage->external_mutation_free && !$guide_method_storage->mutation_free_inferred && $prevent_method_signature_mismatch) {
            IssueBuffer::maybeAdd(new MissingImmutableAnnotation($cased_guide_method_id . ' is marked @psalm-immutable, but ' . $implementer_classlike_storage->name . '::' . ($guide_method_storage->cased_name ?: '') . ' is not marked @psalm-immutable', $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
        }
    }
    /**
     * @param  string[]         $suppressed_issues
     */
    private static function compareMethodParams(Codebase $codebase, ?ClassMethod $stmt, ClassLikeStorage $implementer_classlike_storage, ClassLikeStorage $guide_classlike_storage, string $implementer_called_class_name, MethodStorage $guide_method_storage, MethodStorage $implementer_method_storage, FunctionLikeParameter $guide_param, FunctionLikeParameter $implementer_param, int $i, string $cased_guide_method_id, string $cased_implementer_method_id, bool $prevent_method_signature_mismatch, CodeLocation $code_location, array $suppressed_issues) : void
    {
        if ($prevent_method_signature_mismatch) {
            if (!$guide_classlike_storage->user_defined && $guide_param->type) {
                $implementer_param_type = $implementer_param->signature_type;
                $guide_param_signature_type = $guide_param->type;
                $or_null_guide_param_signature_type = $guide_param->signature_type ? $guide_param->signature_type->getBuilder() : null;
                if ($or_null_guide_param_signature_type) {
                    $or_null_guide_param_signature_type->addType(new TNull());
                }
                if ($cased_guide_method_id === 'Serializable::unserialize') {
                    $guide_param_signature_type = null;
                    $or_null_guide_param_signature_type = null;
                }
                if (!$guide_param->type->hasMixed() && !$guide_param->type->from_docblock && ($implementer_param_type || $guide_param_signature_type)) {
                    $config = Config::getInstance();
                    if ($implementer_param_type && (!$guide_param_signature_type || strtolower($implementer_param_type->getId()) !== strtolower($guide_param_signature_type->getId())) && (!$or_null_guide_param_signature_type || strtolower($implementer_param_type->getId()) !== strtolower($or_null_guide_param_signature_type->getId()))) {
                        if ($implementer_method_storage->cased_name === '__construct') {
                            IssueBuffer::maybeAdd(new ConstructorSignatureMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' . $implementer_param_type . '\', expecting \'' . $guide_param_signature_type . '\' as defined by ' . $cased_guide_method_id, $implementer_param->location && $config->isInProjectDirs($implementer_param->location->file_path) ? $implementer_param->location : $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                        } else {
                            IssueBuffer::maybeAdd(new MethodSignatureMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' . $implementer_param_type . '\', expecting \'' . $guide_param_signature_type . '\' as defined by ' . $cased_guide_method_id, $implementer_param->location && $config->isInProjectDirs($implementer_param->location->file_path) ? $implementer_param->location : $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                        }
                        return;
                    }
                }
            }
            $config = Config::getInstance();
            if ($guide_param->name !== $implementer_param->name && $guide_method_storage->allow_named_arg_calls && $guide_classlike_storage->user_defined && $implementer_classlike_storage->user_defined && $implementer_param->location && $guide_method_storage->cased_name && strpos($guide_method_storage->cased_name, '__') !== 0 && $config->isInProjectDirs($implementer_param->location->file_path)) {
                if ($config->allow_named_arg_calls || $guide_classlike_storage->location && !$config->isInProjectDirs($guide_classlike_storage->location->file_path)) {
                    if ($codebase->alter_code) {
                        $project_analyzer = \Psalm\Internal\Analyzer\ProjectAnalyzer::getInstance();
                        if ($stmt && isset($project_analyzer->getIssuesToFix()['ParamNameMismatch'])) {
                            $param_replacer = new ParamReplacementVisitor($implementer_param->name, $guide_param->name);
                            $traverser = new NodeTraverser();
                            $traverser->addVisitor($param_replacer);
                            $traverser->traverse([$stmt]);
                            if ($replacements = $param_replacer->getReplacements()) {
                                FileManipulationBuffer::add($implementer_param->location->file_path, $replacements);
                            }
                        }
                    } else {
                        IssueBuffer::maybeAdd(new ParamNameMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong name $' . $implementer_param->name . ', expecting $' . $guide_param->name . ' as defined by ' . $cased_guide_method_id, $implementer_param->location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                    }
                }
            }
            if ($guide_classlike_storage->user_defined && $implementer_param->signature_type) {
                self::compareMethodSignatureParams($codebase, $i, $guide_classlike_storage, $implementer_classlike_storage, $guide_method_storage, $implementer_method_storage, $guide_param, $implementer_param->signature_type, $cased_guide_method_id, $cased_implementer_method_id, $code_location, $suppressed_issues);
            }
        }
        if ($implementer_param->type && $guide_param->type && $implementer_param->type->getId() !== $guide_param->type->getId()) {
            self::compareMethodDocblockParams($codebase, $i, $guide_classlike_storage, $implementer_classlike_storage, $implementer_called_class_name, $guide_method_storage, $implementer_method_storage, $cased_guide_method_id, $cased_implementer_method_id, $guide_param->type, $implementer_param->type, $code_location, $suppressed_issues);
        }
        if ($guide_classlike_storage->user_defined && $implementer_param->by_ref !== $guide_param->by_ref) {
            $config = Config::getInstance();
            IssueBuffer::maybeAdd(new MethodSignatureMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' is' . ($implementer_param->by_ref ? '' : ' not') . ' passed by reference, but argument ' . ($i + 1) . ' of ' . $cased_guide_method_id . ' is' . ($guide_param->by_ref ? '' : ' not'), $implementer_param->location && $config->isInProjectDirs($implementer_param->location->file_path) ? $implementer_param->location : $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
        }
    }
    /**
     * @param  string[]         $suppressed_issues
     */
    private static function compareMethodSignatureParams(Codebase $codebase, int $i, ClassLikeStorage $guide_classlike_storage, ClassLikeStorage $implementer_classlike_storage, MethodStorage $guide_method_storage, MethodStorage $implementer_method_storage, FunctionLikeParameter $guide_param, Union $implementer_param_signature_type, string $cased_guide_method_id, string $cased_implementer_method_id, CodeLocation $code_location, array $suppressed_issues) : void
    {
        $guide_param_signature_type = $guide_param->signature_type ? TypeExpander::expandUnion($codebase, $guide_param->signature_type, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->name : $guide_classlike_storage->name, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->name : $guide_classlike_storage->name, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->parent_class : $guide_classlike_storage->parent_class) : null;
        $implementer_param_signature_type = TypeExpander::expandUnion($codebase, $implementer_param_signature_type, $implementer_classlike_storage->name, $implementer_classlike_storage->name, $implementer_classlike_storage->parent_class);
        $is_contained_by = $codebase->analysis_php_version_id >= 70400 && $guide_param_signature_type ? UnionTypeComparator::isContainedBy($codebase, $guide_param_signature_type, $implementer_param_signature_type) : UnionTypeComparator::isContainedByInPhp($guide_param_signature_type, $implementer_param_signature_type);
        if (!$is_contained_by) {
            $config = Config::getInstance();
            if ($codebase->analysis_php_version_id >= 80000 || $guide_classlike_storage->is_trait === $implementer_classlike_storage->is_trait || !in_array($guide_classlike_storage->name, $implementer_classlike_storage->used_traits) || $implementer_method_storage->defining_fqcln !== $implementer_classlike_storage->name || !$implementer_method_storage->abstract && !$guide_method_storage->abstract) {
                if ($implementer_method_storage->cased_name === '__construct') {
                    IssueBuffer::maybeAdd(new ConstructorSignatureMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' . $implementer_param_signature_type . '\', expecting \'' . $guide_param_signature_type . '\' as defined by ' . $cased_guide_method_id, $implementer_method_storage->params[$i]->location && $config->isInProjectDirs($implementer_method_storage->params[$i]->location->file_path) ? $implementer_method_storage->params[$i]->location : $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                } else {
                    IssueBuffer::maybeAdd(new MethodSignatureMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' . $implementer_param_signature_type . '\', expecting \'' . $guide_param_signature_type . '\' as defined by ' . $cased_guide_method_id, $implementer_method_storage->params[$i]->location && $config->isInProjectDirs($implementer_method_storage->params[$i]->location->file_path) ? $implementer_method_storage->params[$i]->location : $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                }
            } else {
                IssueBuffer::maybeAdd(new TraitMethodSignatureMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' . $implementer_param_signature_type . '\', expecting \'' . $guide_param_signature_type . '\' as defined by ' . $cased_guide_method_id, $implementer_method_storage->params[$i]->location && $config->isInProjectDirs($implementer_method_storage->params[$i]->location->file_path) ? $implementer_method_storage->params[$i]->location : $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
            }
        }
    }
    /**
     * @param  string[]         $suppressed_issues
     */
    private static function compareMethodDocblockParams(Codebase $codebase, int $i, ClassLikeStorage $guide_classlike_storage, ClassLikeStorage $implementer_classlike_storage, string $implementer_called_class_name, MethodStorage $guide_method_storage, MethodStorage $implementer_method_storage, string $cased_guide_method_id, string $cased_implementer_method_id, Union $guide_param_type, Union $implementer_param_type, CodeLocation $code_location, array $suppressed_issues) : void
    {
        $implementer_method_storage_param_type = TypeExpander::expandUnion($codebase, $implementer_param_type, $implementer_classlike_storage->name, $implementer_called_class_name, $implementer_classlike_storage->parent_class);
        $guide_method_storage_param_type = TypeExpander::expandUnion($codebase, $guide_param_type, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->name : $guide_classlike_storage->name, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->name : $guide_classlike_storage->name, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->parent_class : $guide_classlike_storage->parent_class);
        $guide_class_name = $guide_classlike_storage->name;
        if ($implementer_classlike_storage->is_trait) {
            $implementer_called_class_storage = $codebase->classlike_storage_provider->get($implementer_called_class_name);
            if (isset($implementer_called_class_storage->template_extended_params[$implementer_classlike_storage->name])) {
                self::transformTemplates($implementer_called_class_storage->template_extended_params, $implementer_classlike_storage->name, $implementer_method_storage_param_type, $codebase);
                self::transformTemplates($implementer_called_class_storage->template_extended_params, $guide_class_name, $guide_method_storage_param_type, $codebase);
            }
        }
        $builder = $implementer_method_storage_param_type->getBuilder();
        foreach ($builder->getAtomicTypes() as $k => $t) {
            if ($t instanceof TTemplateParam && strpos($t->defining_class, 'fn-') === 0) {
                $builder->removeType($k);
                foreach ($t->as->getAtomicTypes() as $as_t) {
                    $builder->addType($as_t);
                }
            }
        }
        $implementer_method_storage_param_type = $builder->freeze();
        $builder = $guide_method_storage_param_type->getBuilder();
        foreach ($builder->getAtomicTypes() as $k => $t) {
            if ($t instanceof TTemplateParam && strpos($t->defining_class, 'fn-') === 0) {
                $builder->removeType($k);
                foreach ($t->as->getAtomicTypes() as $as_t) {
                    $builder->addType($as_t);
                }
            }
        }
        $guide_method_storage_param_type = $builder->freeze();
        unset($builder);
        if ($implementer_classlike_storage->template_extended_params) {
            self::transformTemplates($implementer_classlike_storage->template_extended_params, $guide_class_name, $guide_method_storage_param_type, $codebase);
        }
        $union_comparison_results = new TypeComparisonResult();
        if (!UnionTypeComparator::isContainedBy($codebase, $guide_method_storage_param_type, $implementer_method_storage_param_type, !$guide_classlike_storage->user_defined, !$guide_classlike_storage->user_defined, $union_comparison_results)) {
            // is the declared return type more specific than the inferred one?
            if ($union_comparison_results->type_coerced) {
                if ($guide_classlike_storage->user_defined) {
                    IssueBuffer::maybeAdd(new MoreSpecificImplementedParamType('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has the more specific type \'' . $implementer_method_storage_param_type->getId() . '\', expecting \'' . $guide_method_storage_param_type->getId() . '\' as defined by ' . $cased_guide_method_id, $implementer_method_storage->params[$i]->location ?: $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                }
            } else {
                if (UnionTypeComparator::isContainedBy($codebase, $implementer_method_storage_param_type, $guide_method_storage_param_type, !$guide_classlike_storage->user_defined, !$guide_classlike_storage->user_defined)) {
                    IssueBuffer::maybeAdd(new MoreSpecificImplementedParamType('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has the more specific type \'' . $implementer_method_storage_param_type->getId() . '\', expecting \'' . $guide_method_storage_param_type->getId() . '\' as defined by ' . $cased_guide_method_id, $implementer_method_storage->params[$i]->location ?: $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                } else {
                    IssueBuffer::maybeAdd(new ImplementedParamTypeMismatch('Argument ' . ($i + 1) . ' of ' . $cased_implementer_method_id . ' has wrong type \'' . $implementer_method_storage_param_type->getId() . '\', expecting \'' . $guide_method_storage_param_type->getId() . '\' as defined by ' . $cased_guide_method_id, $implementer_method_storage->params[$i]->location ?: $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
                }
            }
        }
    }
    /**
     * @param  string[]         $suppressed_issues
     */
    private static function compareMethodSignatureReturnTypes(Codebase $codebase, ClassLikeStorage $guide_classlike_storage, ClassLikeStorage $implementer_classlike_storage, MethodStorage $guide_method_storage, MethodStorage $implementer_method_storage, Union $guide_signature_return_type, string $cased_guide_method_id, string $implementer_called_class_name, string $cased_implementer_method_id, CodeLocation $code_location, array $suppressed_issues) : void
    {
        $guide_signature_return_type = TypeExpander::expandUnion($codebase, $guide_signature_return_type, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->name : $guide_classlike_storage->name, $guide_classlike_storage->is_trait && $guide_method_storage->abstract || $guide_classlike_storage->final ? $implementer_classlike_storage->name : $guide_classlike_storage->name, $guide_classlike_storage->is_trait && $guide_method_storage->abstract ? $implementer_classlike_storage->parent_class : $guide_classlike_storage->parent_class, \true, \true, $implementer_method_storage->final);
        $implementer_signature_return_type = $implementer_method_storage->signature_return_type ? TypeExpander::expandUnion($codebase, $implementer_method_storage->signature_return_type, $implementer_classlike_storage->is_trait ? $implementer_called_class_name : $implementer_classlike_storage->name, $implementer_classlike_storage->is_trait ? $implementer_called_class_name : $implementer_classlike_storage->name, $implementer_classlike_storage->parent_class) : null;
        $is_contained_by = $codebase->analysis_php_version_id >= 70400 && $implementer_signature_return_type ? UnionTypeComparator::isContainedBy($codebase, $implementer_signature_return_type, $guide_signature_return_type) : UnionTypeComparator::isContainedByInPhp($implementer_signature_return_type, $guide_signature_return_type);
        if (!$is_contained_by) {
            if ($codebase->analysis_php_version_id >= 80000 || $guide_classlike_storage->is_trait === $implementer_classlike_storage->is_trait || !in_array($guide_classlike_storage->name, $implementer_classlike_storage->used_traits) || $implementer_method_storage->defining_fqcln !== $implementer_classlike_storage->name || !$implementer_method_storage->abstract && !$guide_method_storage->abstract) {
                IssueBuffer::maybeAdd(new MethodSignatureMismatch('Method ' . $cased_implementer_method_id . ' with return type \'' . $implementer_signature_return_type . '\' is different to return type \'' . $guide_signature_return_type . '\' of inherited method ' . $cased_guide_method_id, $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
            } else {
                IssueBuffer::maybeAdd(new TraitMethodSignatureMismatch('Method ' . $cased_implementer_method_id . ' with return type \'' . $implementer_signature_return_type . '\' is different to return type \'' . $guide_signature_return_type . '\' of inherited method ' . $cased_guide_method_id, $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
            }
        }
    }
    /**
     * @param  string[]         $suppressed_issues
     */
    private static function compareMethodDocblockReturnTypes(Codebase $codebase, ClassLikeStorage $guide_classlike_storage, ClassLikeStorage $implementer_classlike_storage, MethodStorage $implementer_method_storage, Union $guide_return_type, Union $implementer_return_type, string $cased_guide_method_id, string $implementer_called_class_name, ?MethodIdentifier $implementer_declaring_method_id, CodeLocation $code_location, array $suppressed_issues) : void
    {
        $implementer_method_storage_return_type = TypeExpander::expandUnion($codebase, $implementer_return_type, $implementer_classlike_storage->is_trait ? $implementer_called_class_name : $implementer_classlike_storage->name, $implementer_called_class_name, $implementer_classlike_storage->parent_class);
        $guide_method_storage_return_type = TypeExpander::expandUnion($codebase, $guide_return_type, $guide_classlike_storage->is_trait ? $implementer_classlike_storage->name : $guide_classlike_storage->name, $guide_classlike_storage->is_trait || $implementer_method_storage->final ? $implementer_called_class_name : $guide_classlike_storage->name, $guide_classlike_storage->parent_class, \true, \true, $implementer_method_storage->final);
        $guide_class_name = $guide_classlike_storage->name;
        if ($implementer_classlike_storage->template_extended_params) {
            self::transformTemplates($implementer_classlike_storage->template_extended_params, $guide_class_name, $guide_method_storage_return_type, $codebase);
            if ($implementer_method_storage->defining_fqcln) {
                self::transformTemplates($implementer_classlike_storage->template_extended_params, $implementer_method_storage->defining_fqcln, $implementer_method_storage_return_type, $codebase);
            }
        }
        if ($implementer_classlike_storage->is_trait) {
            $implementer_called_class_storage = $codebase->classlike_storage_provider->get($implementer_called_class_name);
            if ($implementer_called_class_storage->template_extended_params) {
                self::transformTemplates($implementer_called_class_storage->template_extended_params, $implementer_classlike_storage->name, $implementer_method_storage_return_type, $codebase);
                self::transformTemplates($implementer_called_class_storage->template_extended_params, $guide_class_name, $guide_method_storage_return_type, $codebase);
            }
        }
        // treat void as null when comparing against docblock implementer
        if ($implementer_method_storage_return_type->isVoid()) {
            $implementer_method_storage_return_type = Type::getNull();
        }
        if ($guide_method_storage_return_type->isVoid()) {
            $guide_method_storage_return_type = Type::getNull();
        }
        $union_comparison_results = new TypeComparisonResult();
        if (!UnionTypeComparator::isContainedBy($codebase, $implementer_method_storage_return_type, $guide_method_storage_return_type, \false, \false, $union_comparison_results)) {
            // is the declared return type more specific than the inferred one?
            if ($union_comparison_results->type_coerced) {
                IssueBuffer::maybeAdd(new LessSpecificImplementedReturnType('The inherited return type \'' . $guide_method_storage_return_type->getId() . '\' for ' . $cased_guide_method_id . ' is more specific than the implemented ' . 'return type for ' . $implementer_declaring_method_id . ' \'' . $implementer_method_storage_return_type->getId() . '\'', $implementer_method_storage->return_type_location ?: $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
            } else {
                IssueBuffer::maybeAdd(new ImplementedReturnTypeMismatch('The inherited return type \'' . $guide_method_storage_return_type->getId() . '\' for ' . $cased_guide_method_id . ' is different to the implemented ' . 'return type for ' . $implementer_declaring_method_id . ' \'' . $implementer_method_storage_return_type->getId() . '\'', $implementer_method_storage->return_type_location ?: $code_location), $suppressed_issues + $implementer_classlike_storage->suppressed_issues);
            }
        }
    }
    /**
     * @param  array<string, array<string, Union>>  $template_extended_params
     */
    private static function transformTemplates(array $template_extended_params, string $base_class_name, Union &$templated_type, Codebase $codebase) : void
    {
        if (isset($template_extended_params[$base_class_name])) {
            $map = $template_extended_params[$base_class_name];
            $template_types = [];
            foreach ($map as $key => $mapped_type) {
                $new_bases = [];
                foreach ($mapped_type->getTemplateTypes() as $mapped_atomic_type) {
                    if ($mapped_atomic_type->defining_class === $base_class_name) {
                        continue;
                    }
                    $new_bases[] = $mapped_atomic_type->defining_class;
                }
                if ($new_bases) {
                    foreach ($new_bases as $new_base_class_name) {
                        self::transformTemplates($template_extended_params, $new_base_class_name, $mapped_type, $codebase);
                    }
                }
                $template_types[$key][$base_class_name] = $mapped_type;
            }
            $template_result = new TemplateResult([], $template_types);
            $templated_type = TemplateInferredTypeReplacer::replace($templated_type, $template_result, $codebase);
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Namespace_;
use Psalm\Context;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Type;
use Psalm\Type\Union;
use ReflectionProperty;
use UnexpectedValueException;
use function assert;
use function count;
use function implode;
use function preg_replace;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class NamespaceAnalyzer extends \Psalm\Internal\Analyzer\SourceAnalyzer
{
    use \Psalm\Internal\Analyzer\CanAlias;
    /**
     * @var FileAnalyzer
     * @psalm-suppress NonInvariantDocblockPropertyType
     */
    protected \Psalm\Internal\Analyzer\SourceAnalyzer $source;
    private Namespace_ $namespace;
    private string $namespace_name;
    /**
     * A lookup table for public namespace constants
     *
     * @var array<string, array<string, Union>>
     */
    protected static array $public_namespace_constants = [];
    public function __construct(Namespace_ $namespace, \Psalm\Internal\Analyzer\FileAnalyzer $source)
    {
        $this->source = $source;
        $this->namespace = $namespace;
        $this->namespace_name = $this->namespace->name ? implode('\\', $this->namespace->name->parts) : '';
    }
    public function collectAnalyzableInformation() : void
    {
        $leftover_stmts = [];
        if (!isset(self::$public_namespace_constants[$this->namespace_name])) {
            self::$public_namespace_constants[$this->namespace_name] = [];
        }
        $codebase = $this->getCodebase();
        foreach ($this->namespace->stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\ClassLike) {
                $this->collectAnalyzableClassLike($stmt);
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Use_) {
                $this->visitUse($stmt);
            } elseif ($stmt instanceof PhpParser\Node\Stmt\GroupUse) {
                $this->visitGroupUse($stmt);
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Const_) {
                foreach ($stmt->consts as $const) {
                    self::$public_namespace_constants[$this->namespace_name][$const->name->name] = Type::getMixed();
                }
                $leftover_stmts[] = $stmt;
            } else {
                $leftover_stmts[] = $stmt;
            }
        }
        if ($leftover_stmts) {
            $statements_analyzer = new \Psalm\Internal\Analyzer\StatementsAnalyzer($this, new NodeDataProvider());
            $file_context = $this->source->context;
            if ($file_context !== null) {
                $context = $file_context;
            } else {
                $context = new Context();
                $context->is_global = \true;
                $context->defineGlobals();
                $context->collect_exceptions = $codebase->config->check_for_throws_in_global_scope;
            }
            $statements_analyzer->analyze($leftover_stmts, $context, null, \true);
        }
    }
    public function collectAnalyzableClassLike(PhpParser\Node\Stmt\ClassLike $stmt) : void
    {
        if (!$stmt->name) {
            throw new UnexpectedValueException('Did not expect anonymous class here');
        }
        $fq_class_name = Type::getFQCLNFromString($stmt->name->name, $this->getAliases());
        if ($stmt instanceof PhpParser\Node\Stmt\Class_ || $stmt instanceof PhpParser\Node\Stmt\Enum_) {
            $this->source->addNamespacedClassAnalyzer($fq_class_name, new \Psalm\Internal\Analyzer\ClassAnalyzer($stmt, $this, $fq_class_name));
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
            $this->source->addNamespacedInterfaceAnalyzer($fq_class_name, new \Psalm\Internal\Analyzer\InterfaceAnalyzer($stmt, $this, $fq_class_name));
        }
    }
    public function getNamespace() : string
    {
        return $this->namespace_name;
    }
    public function setConstType(string $const_name, Union $const_type) : void
    {
        self::$public_namespace_constants[$this->namespace_name][$const_name] = $const_type;
    }
    /**
     * @return array<string, Union>
     */
    public static function getConstantsForNamespace(string $namespace_name, int $visibility) : array
    {
        // @todo this does not allow for loading in namespace constants not already defined in the current sweep
        if (!isset(self::$public_namespace_constants[$namespace_name])) {
            self::$public_namespace_constants[$namespace_name] = [];
        }
        if ($visibility === ReflectionProperty::IS_PUBLIC) {
            return self::$public_namespace_constants[$namespace_name];
        }
        throw new InvalidArgumentException('Given $visibility not supported');
    }
    public function getFileAnalyzer() : \Psalm\Internal\Analyzer\FileAnalyzer
    {
        return $this->source;
    }
    /**
     * Returns true if $calling_identifier is the same as, or is within with $identifier, in a
     * case-insensitive comparison. Identifiers can be namespaces, classlikes, functions, or methods.
     *
     * @psalm-pure
     * @throws InvalidArgumentException if $identifier is not a valid identifier
     */
    public static function isWithin(string $calling_identifier, string $identifier) : bool
    {
        $normalized_calling_ident = self::normalizeIdentifier($calling_identifier);
        $normalized_ident = self::normalizeIdentifier($identifier);
        if ($normalized_calling_ident === $normalized_ident) {
            return \true;
        }
        $normalized_calling_ident_parts = self::getIdentifierParts($normalized_calling_ident);
        $normalized_ident_parts = self::getIdentifierParts($normalized_ident);
        if (count($normalized_calling_ident_parts) < count($normalized_ident_parts)) {
            return \false;
        }
        for ($i = 0; $i < count($normalized_ident_parts); ++$i) {
            if ($normalized_ident_parts[$i] !== $normalized_calling_ident_parts[$i]) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * Returns true if $calling_identifier is the same as or is within any identifier
     * in $identifiers in a case-insensitive comparison, or if $identifiers is empty.
     * Identifiers can be namespaces, classlikes, functions, or methods.
     *
     * @psalm-pure
     * @psalm-assert-if-false !empty $identifiers
     * @param list<string> $identifiers
     */
    public static function isWithinAny(string $calling_identifier, array $identifiers) : bool
    {
        if (count($identifiers) === 0) {
            return \true;
        }
        foreach ($identifiers as $identifier) {
            if (self::isWithin($calling_identifier, $identifier)) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @param non-empty-string $fullyQualifiedClassName e.g. '\Psalm\Internal\Analyzer\NamespaceAnalyzer'
     * @return non-empty-string , e.g. 'Psalm'
     * @psalm-pure
     */
    public static function getNameSpaceRoot(string $fullyQualifiedClassName) : string
    {
        $root_namespace = preg_replace('/^([^\\\\]+).*/', '$1', $fullyQualifiedClassName, 1);
        if ($root_namespace === "") {
            throw new InvalidArgumentException("Invalid classname \"{$fullyQualifiedClassName}\"");
        }
        return $root_namespace;
    }
    /**
     * @return ($lowercase is true ? lowercase-string : string)
     * @psalm-pure
     */
    public static function normalizeIdentifier(string $identifier, bool $lowercase = \true) : string
    {
        if ($identifier === "") {
            return "";
        }
        $identifier = $identifier[0] === "\\" ? substr($identifier, 1) : $identifier;
        return $lowercase ? strtolower($identifier) : $identifier;
    }
    /**
     * Splits an identifier into parts, eg `Foo\Bar::baz` becomes ["Foo", "\\", "Bar", "::", "baz"].
     *
     * @return list<non-empty-string>
     * @psalm-pure
     */
    public static function getIdentifierParts(string $identifier) : array
    {
        $parts = [];
        while (($pos = strpos($identifier, "\\")) !== \false) {
            if ($pos > 0) {
                $part = substr($identifier, 0, $pos);
                assert($part !== "");
                $parts[] = $part;
            }
            $parts[] = "\\";
            $identifier = substr($identifier, $pos + 1);
        }
        if (($pos = strpos($identifier, "::")) !== \false) {
            if ($pos > 0) {
                $part = substr($identifier, 0, $pos);
                assert($part !== "");
                $parts[] = $part;
            }
            $parts[] = "::";
            $identifier = substr($identifier, $pos + 2);
        }
        if ($identifier !== "") {
            $parts[] = $identifier;
        }
        return $parts;
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ArrowFunction;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Closure;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Param;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Function_;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\UnresolvableConstantException;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\FunctionLike\ReturnTypeAnalyzer;
use Psalm\Internal\Analyzer\FunctionLike\ReturnTypeCollector;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\FileManipulation\FunctionDocblockManipulator;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\PhpVisitor\NodeCounterVisitor;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\InvalidDocblockParamName;
use Psalm\Issue\InvalidParamDefault;
use Psalm\Issue\InvalidThrow;
use Psalm\Issue\MethodSignatureMismatch;
use Psalm\Issue\MismatchingDocblockParamType;
use Psalm\Issue\MissingClosureParamType;
use Psalm\Issue\MissingParamType;
use Psalm\Issue\MissingThrowsDocblock;
use Psalm\Issue\ReferenceConstraintViolation;
use Psalm\Issue\ReservedWord;
use Psalm\Issue\UnresolvableConstant;
use Psalm\Issue\UnusedClosureParam;
use Psalm\Issue\UnusedParam;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AfterFunctionLikeAnalysisEvent;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\FunctionStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_combine;
use function array_diff_key;
use function array_key_exists;
use function array_keys;
use function array_merge;
use function array_search;
use function array_values;
use function count;
use function end;
use function in_array;
use function is_string;
use function mb_strpos;
use function md5;
use function microtime;
use function reset;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 * @template-covariant TFunction as Closure|Function_|ClassMethod|ArrowFunction
 */
abstract class FunctionLikeAnalyzer extends \Psalm\Internal\Analyzer\SourceAnalyzer
{
    /**
     * @var TFunction
     */
    protected $function;
    protected Codebase $codebase;
    /**
     * @var array<string>
     */
    protected array $suppressed_issues;
    protected bool $is_static = \false;
    /**
     * @var ?array<string, Union>
     */
    protected ?array $return_vars_in_scope = [];
    /**
     * @var ?array<string, bool>
     */
    protected ?array $return_vars_possibly_in_scope = [];
    private ?Union $local_return_type = null;
    /**
     * @var array<string, bool>
     */
    protected static array $no_effects_hashes = [];
    public bool $track_mutations = \false;
    public bool $inferred_impure = \false;
    public bool $inferred_has_mutation = \false;
    /**
     * Holds param nodes for functions with func_get_args calls
     *
     * @var array<string, DataFlowNode>
     */
    public array $param_nodes = [];
    protected FunctionLikeStorage $storage;
    /**
     * @param TFunction $function
     */
    public function __construct($function, \Psalm\Internal\Analyzer\SourceAnalyzer $source, FunctionLikeStorage $storage)
    {
        $this->function = $function;
        $this->source = $source;
        $this->suppressed_issues = $source->getSuppressedIssues();
        $this->codebase = $source->getCodebase();
        $this->storage = $storage;
    }
    /**
     * @param bool          $add_mutations  whether or not to add mutations to this method
     * @return false|null
     * @psalm-suppress PossiblyUnusedReturnValue unused but seems important
     */
    public function analyze(Context $context, NodeDataProvider $type_provider, ?Context $global_context = null, bool $add_mutations = \false) : ?bool
    {
        $storage = $this->storage;
        $function_stmts = $this->function->getStmts() ?: [];
        if ($this->function instanceof ArrowFunction && isset($function_stmts[0]) && $function_stmts[0] instanceof PhpParser\Node\Stmt\Return_ && $function_stmts[0]->expr) {
            $function_stmts[0]->setAttributes($function_stmts[0]->expr->getAttributes());
        }
        if ($global_context) {
            foreach ($global_context->constants as $const_name => $var_type) {
                if (!$context->hasVariable($const_name)) {
                    $context->vars_in_scope[$const_name] = $var_type;
                }
            }
        }
        $codebase = $this->codebase;
        $project_analyzer = $this->getProjectAnalyzer();
        if ($codebase->track_unused_suppressions && !isset($storage->suppressed_issues[0])) {
            if (count($storage->suppressed_issues) === 1 || !in_array("UnusedPsalmSuppress", $storage->suppressed_issues)) {
                foreach ($storage->suppressed_issues as $offset => $issue_name) {
                    IssueBuffer::addUnusedSuppression($this->getFilePath(), $offset, $issue_name);
                }
            }
        }
        foreach ($storage->docblock_issues as $docblock_issue) {
            IssueBuffer::maybeAdd($docblock_issue);
        }
        $function_information = $this->getFunctionInformation($context, $codebase, $type_provider, $storage, $add_mutations);
        if ($function_information === null) {
            return null;
        }
        [$real_method_id, $method_id, $appearing_class_storage, $hash, $cased_method_id, $overridden_method_ids] = $function_information;
        $this->suppressed_issues = $this->getSource()->getSuppressedIssues() + $storage->suppressed_issues;
        if ($appearing_class_storage) {
            $this->suppressed_issues += $appearing_class_storage->suppressed_issues;
        }
        if (($storage instanceof MethodStorage || $storage instanceof FunctionStorage) && $storage->is_static) {
            $this->is_static = \true;
        }
        $statements_analyzer = new \Psalm\Internal\Analyzer\StatementsAnalyzer($this, $type_provider);
        if ($this instanceof \Psalm\Internal\Analyzer\ClosureAnalyzer && $this->function instanceof Closure) {
            $byref_uses = [];
            foreach ($this->function->uses as $use) {
                if (!is_string($use->var->name)) {
                    continue;
                }
                $use_var_id = '$' . $use->var->name;
                $use_location = new CodeLocation($this, $use);
                $use_assignment = null;
                if ($statements_analyzer->data_flow_graph) {
                    $use_assignment = DataFlowNode::getForAssignment($use_var_id, $use_location);
                    $statements_analyzer->data_flow_graph->addNode($use_assignment);
                    $context->vars_in_scope[$use_var_id] = $context->vars_in_scope[$use_var_id]->addParentNodes([$use_assignment->id => $use_assignment]);
                }
                if ($use->byRef) {
                    $byref_uses[$use_var_id] = \true;
                    if ($statements_analyzer->data_flow_graph && $use_assignment) {
                        $statements_analyzer->data_flow_graph->addPath($use_assignment, new DataFlowNode('closure-use', 'closure use', null), 'closure-use');
                    }
                } else {
                    $statements_analyzer->registerVariable($use_var_id, $use_location, null);
                }
            }
            $statements_analyzer->setByRefUses($byref_uses);
        }
        if ($storage->template_types) {
            foreach ($storage->template_types as $param_name => $_) {
                $fq_classlike_name = Type::getFQCLNFromString($param_name, $this->getAliases());
                if ($codebase->classOrInterfaceExists($fq_classlike_name)) {
                    IssueBuffer::maybeAdd(new ReservedWord('Cannot use ' . $param_name . ' as template name since the class already exists', new CodeLocation($this, $this->function), 'resource'), $this->getSuppressedIssues());
                }
            }
        }
        $template_types = $storage->template_types;
        if ($appearing_class_storage && $appearing_class_storage->template_types) {
            $template_types = array_merge($template_types ?: [], $appearing_class_storage->template_types);
        }
        $params = $storage->params;
        if ($codebase->alter_code) {
            $this->alterParams($codebase, $storage, $params, $context);
        }
        foreach ($codebase->methods_to_rename as $original_method_id => $new_method_name) {
            if ($this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer && strtolower((string) $this->getMethodId()) === $original_method_id) {
                $file_manipulations = [new FileManipulation((int) $this->function->name->getAttribute('startFilePos'), (int) $this->function->name->getAttribute('endFilePos') + 1, $new_method_name)];
                FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
            }
        }
        if ($storage instanceof MethodStorage && $method_id instanceof MethodIdentifier && $overridden_method_ids) {
            $params = $codebase->methods->getMethodParams($method_id, $this);
        }
        $check_stmts = $this->processParams($statements_analyzer, $storage, $cased_method_id, $params, array_values($this->function->params), $context, (bool) $template_types);
        if ($storage->pure) {
            $context->pure = \true;
        }
        if ($storage->mutation_free && $cased_method_id && !strpos($cased_method_id, '__construct') && !($storage instanceof MethodStorage && $storage->mutation_free_inferred)) {
            $context->mutation_free = \true;
        }
        if ($storage instanceof MethodStorage && $storage->external_mutation_free && !$storage->mutation_free_inferred) {
            $context->external_mutation_free = \true;
        }
        if ($storage->unused_docblock_params) {
            foreach ($storage->unused_docblock_params as $param_name => $param_location) {
                IssueBuffer::maybeAdd(new InvalidDocblockParamName('Incorrect param name $' . $param_name . ' in docblock for ' . $cased_method_id, $param_location));
            }
        }
        if ($storage->signature_return_type && $storage->signature_return_type_location) {
            [$start, $end] = $storage->signature_return_type_location->getSelectionBounds();
            $codebase->analyzer->addOffsetReference($this->getFilePath(), $start, $end, (string) $storage->signature_return_type);
        }
        if ($storage instanceof MethodStorage && $storage->location && !$storage->allow_named_arg_calls) {
            foreach ($overridden_method_ids as $overridden_method_id) {
                $overridden_storage = $codebase->methods->getStorage($overridden_method_id);
                if ($overridden_storage->allow_named_arg_calls) {
                    IssueBuffer::maybeAdd(new MethodSignatureMismatch('Method ' . (string) $method_id . ' should accept named arguments ' . ' as ' . (string) $overridden_method_id . ' does', $storage->location));
                }
            }
        }
        if (ReturnTypeAnalyzer::checkReturnType($this->function, $project_analyzer, $this, $storage, $context) === \false) {
            $check_stmts = \false;
        }
        if (!$check_stmts) {
            return \false;
        }
        if ($context->collect_initializations || $context->collect_mutations) {
            $statements_analyzer->addSuppressedIssues(['DocblockTypeContradiction', 'InvalidReturnStatement', 'RedundantCondition', 'RedundantConditionGivenDocblockType', 'TypeDoesNotContainNull', 'TypeDoesNotContainType', 'LoopInvalidation']);
            if ($context->collect_initializations) {
                $statements_analyzer->addSuppressedIssues(['UndefinedInterfaceMethod', 'UndefinedMethod', 'PossiblyUndefinedMethod']);
            }
        } elseif ($cased_method_id && strpos($cased_method_id, '__destruct')) {
            $statements_analyzer->addSuppressedIssues(['InvalidPropertyAssignmentValue', 'PossiblyNullPropertyAssignmentValue']);
        }
        $time = microtime(\true);
        $project_analyzer = $statements_analyzer->getProjectAnalyzer();
        if ($codebase->alter_code && (isset($project_analyzer->getIssuesToFix()['MissingPureAnnotation']) || isset($project_analyzer->getIssuesToFix()['MissingImmutableAnnotation']))) {
            $this->track_mutations = \true;
        } elseif ($this->function instanceof Closure || $this->function instanceof ArrowFunction) {
            $this->track_mutations = \true;
        }
        if ($this->function instanceof ArrowFunction && (!$storage->return_type || $storage->return_type->isNever())) {
            // ArrowFunction perform a return implicitly so if the return type is never, we have to suppress the error
            // note: the never can only come from phpdoc. PHP will refuse short closures with never in signature
            $statements_analyzer->addSuppressedIssues(['NoValue']);
        }
        $statements_analyzer->analyze($function_stmts, $context, $global_context, \true);
        if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MissingPureAnnotation']) && !$this->inferred_impure && ($this->function instanceof Function_ || $this->function instanceof ClassMethod) && $storage->params && !$overridden_method_ids) {
            $manipulator = FunctionDocblockManipulator::getForFunction($project_analyzer, $this->source->getFilePath(), $this->function);
            $yield_types = [];
            $inferred_return_types = ReturnTypeCollector::getReturnTypes($codebase, $type_provider, $function_stmts, $yield_types, \true);
            $inferred_return_type = $inferred_return_types ? Type::combineUnionTypeArray($inferred_return_types, $codebase) : Type::getVoid();
            if (!$inferred_return_type->isVoid() && !$inferred_return_type->isFalse() && !$inferred_return_type->isNull() && !$inferred_return_type->isSingleIntLiteral() && !$inferred_return_type->isSingleStringLiteral() && !$inferred_return_type->isTrue() && !$inferred_return_type->isEmptyArray()) {
                $manipulator->makePure();
            }
        }
        if ($this->inferred_has_mutation && $context->self) {
            $this->codebase->analyzer->addMutableClass($context->self);
        }
        if (!$context->collect_initializations && !$context->collect_mutations && $project_analyzer->debug_performance && $cased_method_id) {
            $traverser = new PhpParser\NodeTraverser();
            $node_counter = new NodeCounterVisitor();
            $traverser->addVisitor($node_counter);
            $traverser->traverse($function_stmts);
            if ($node_counter->count > 5) {
                $time_taken = microtime(\true) - $time;
                $codebase->analyzer->addFunctionTiming($cased_method_id, $time_taken / $node_counter->count);
            }
        }
        $final_actions = \Psalm\Internal\Analyzer\ScopeAnalyzer::getControlActions($this->function->getStmts() ?: [], null, []);
        if ($final_actions !== [\Psalm\Internal\Analyzer\ScopeAnalyzer::ACTION_END]) {
            $this->examineParamTypes($statements_analyzer, $context, $codebase);
        }
        foreach ($params as $function_param) {
            // only complain if there's no type defined by a parent type
            if (!$function_param->type && $function_param->location) {
                if ($this->function instanceof Closure || $this->function instanceof ArrowFunction) {
                    IssueBuffer::maybeAdd(new MissingClosureParamType('Parameter $' . $function_param->name . ' has no provided type', $function_param->location), $storage->suppressed_issues + $this->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new MissingParamType('Parameter $' . $function_param->name . ' has no provided type', $function_param->location), $storage->suppressed_issues + $this->getSuppressedIssues());
                }
            }
        }
        if ($this->function instanceof Closure || $this->function instanceof ArrowFunction) {
            $this->verifyReturnType($function_stmts, $statements_analyzer, $storage->return_type, $this->source->getFQCLN(), $storage->return_type_location, $context->has_returned, $global_context && ($global_context->inside_call || $global_context->inside_return));
            $closure_yield_types = [];
            $closure_return_types = ReturnTypeCollector::getReturnTypes($codebase, $type_provider, $function_stmts, $closure_yield_types, \true);
            $closure_return_type = $closure_return_types ? Type::combineUnionTypeArray($closure_return_types, $codebase) : Type::getVoid();
            $closure_yield_type = $closure_yield_types ? Type::combineUnionTypeArray($closure_yield_types, $codebase) : null;
            if ($closure_yield_type) {
                $closure_return_type = $closure_yield_type;
            }
            if ($function_type = $statements_analyzer->node_data->getType($this->function)) {
                /**
                 * @var TClosure
                 */
                $closure_atomic = $function_type->getSingleAtomic();
                $new_closure_return_type = $closure_atomic->return_type;
                if ($storage->return_type === $storage->signature_return_type && (!$storage->return_type || $storage->return_type->hasMixed() || UnionTypeComparator::isContainedBy($codebase, $closure_return_type, $storage->return_type))) {
                    $new_closure_return_type = $closure_return_type;
                }
                $new_closure_is_pure = !$this->inferred_impure;
                $statements_analyzer->node_data->setType($this->function, new Union([new TClosure($closure_atomic->value, $closure_atomic->params, $new_closure_return_type, $new_closure_is_pure, $closure_atomic->byref_uses, $closure_atomic->extra_types, $closure_atomic->from_docblock)]));
            }
        }
        if ($codebase->collect_references && !$context->collect_initializations && !$context->collect_mutations && $codebase->find_unused_variables && $context->check_variables) {
            $this->checkParamReferences($statements_analyzer, $storage, $appearing_class_storage, $context);
        }
        foreach ($storage->throws as $expected_exception => $_) {
            if (($expected_exception === 'self' || $expected_exception === 'static') && $context->self) {
                $expected_exception = $context->self;
            }
            if (isset($storage->throw_locations[$expected_exception])) {
                if (\Psalm\Internal\Analyzer\ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($statements_analyzer, $expected_exception, $storage->throw_locations[$expected_exception], $context->self, $context->calling_method_id, $statements_analyzer->getSuppressedIssues(), new \Psalm\Internal\Analyzer\ClassLikeNameOptions(\false, \false, \true, \true, \true))) {
                    $input_type = new Union([new TNamedObject($expected_exception)]);
                    $container_type = new Union([new TNamedObject('Exception'), new TNamedObject('Throwable')]);
                    if (!UnionTypeComparator::isContainedBy($codebase, $input_type, $container_type)) {
                        IssueBuffer::maybeAdd(new InvalidThrow('Class supplied for @throws ' . $expected_exception . ' does not implement Throwable', $storage->throw_locations[$expected_exception], $expected_exception), $statements_analyzer->getSuppressedIssues());
                    }
                    if ($codebase->alter_code) {
                        $codebase->classlikes->handleDocblockTypeInMigration($codebase, $this, $input_type, $storage->throw_locations[$expected_exception], $context->calling_method_id);
                    }
                }
            }
        }
        $missingThrowsDocblockErrors = [];
        foreach ($statements_analyzer->getUncaughtThrows($context) as $possibly_thrown_exception => $codelocations) {
            $is_expected = \false;
            foreach ($storage->throws as $expected_exception => $_) {
                if ($expected_exception === $possibly_thrown_exception || $codebase->classExtendsOrImplements($possibly_thrown_exception, $expected_exception)) {
                    $is_expected = \true;
                    break;
                }
            }
            if (!$is_expected) {
                $missing_docblock_exception = new TNamedObject($possibly_thrown_exception);
                $missingThrowsDocblockErrors[] = $missing_docblock_exception->toNamespacedString($this->source->getNamespace(), $this->source->getAliasedClassesFlipped(), $this->source->getFQCLN(), \true);
                foreach ($codelocations as $codelocation) {
                    // issues are suppressed in ThrowAnalyzer, CallAnalyzer, etc.
                    IssueBuffer::maybeAdd(new MissingThrowsDocblock($possibly_thrown_exception . ' is thrown but not caught - please either catch' . ' or add a @throws annotation', $codelocation));
                }
            }
        }
        if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MissingThrowsDocblock'])) {
            $manipulator = FunctionDocblockManipulator::getForFunction($project_analyzer, $this->source->getFilePath(), $this->function);
            $manipulator->addThrowsDocblock($missingThrowsDocblockErrors);
        }
        if ($codebase->taint_flow_graph && $this->function instanceof ClassMethod && $cased_method_id && $storage->specialize_call && isset($context->vars_in_scope['$this']) && $context->vars_in_scope['$this']->parent_nodes) {
            $method_source = DataFlowNode::getForMethodReturn((string) $method_id, $cased_method_id, $storage->location);
            $codebase->taint_flow_graph->addNode($method_source);
            foreach ($context->vars_in_scope['$this']->parent_nodes as $parent_node) {
                $codebase->taint_flow_graph->addPath($parent_node, $method_source, '$this');
            }
        }
        if ($add_mutations) {
            if ($this->return_vars_in_scope !== null) {
                $context->vars_in_scope = \Psalm\Internal\Analyzer\TypeAnalyzer::combineKeyedTypes($context->vars_in_scope, $this->return_vars_in_scope);
            }
            if ($this->return_vars_possibly_in_scope !== null) {
                $context->vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $this->return_vars_possibly_in_scope);
            }
            foreach ($context->vars_in_scope as $var => $_) {
                if (strpos($var, '$this->') !== 0 && $var !== '$this') {
                    $context->removePossibleReference($var);
                }
            }
            foreach ($context->vars_possibly_in_scope as $var => $_) {
                if (strpos($var, '$this->') !== 0 && $var !== '$this') {
                    unset($context->vars_possibly_in_scope[$var]);
                }
            }
            if ($hash && $real_method_id && $this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer && !$context->collect_initializations) {
                $new_hash = md5($real_method_id . '::' . $context->getScopeSummary());
                if ($new_hash === $hash) {
                    self::$no_effects_hashes[$hash] = \true;
                }
            }
        }
        $event = new AfterFunctionLikeAnalysisEvent($this->function, $storage, $this, $codebase, [], $type_provider, $context);
        if ($codebase->config->eventDispatcher->dispatchAfterFunctionLikeAnalysis($event) === \false) {
            return \false;
        }
        $file_manipulations = $event->getFileReplacements();
        if ($file_manipulations) {
            FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
        }
        \Psalm\Internal\Analyzer\AttributesAnalyzer::analyze($this, $context, $storage, $this->function->attrGroups, $storage instanceof MethodStorage ? \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_METHOD : \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_FUNCTION, $storage->suppressed_issues + $this->getSuppressedIssues());
        return null;
    }
    private function checkParamReferences(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, FunctionLikeStorage $storage, ?ClassLikeStorage $class_storage, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        $unused_params = [];
        foreach ($statements_analyzer->getUnusedVarLocations() as [$var_name, $original_location]) {
            if (!array_key_exists(substr($var_name, 1), $storage->param_lookup)) {
                continue;
            }
            if (strpos($var_name, '$_') === 0 || strpos($var_name, '$unused') === 0 && $var_name !== '$unused') {
                continue;
            }
            $position = array_search(substr($var_name, 1), array_keys($storage->param_lookup), \true);
            if ($position === \false) {
                throw new UnexpectedValueException('$position should not be false here');
            }
            if ($storage->params[$position]->promoted_property) {
                continue;
            }
            $did_match_param = \false;
            foreach ($this->function->params as $param) {
                if ($param->var->getAttribute('endFilePos') === $original_location->raw_file_end) {
                    $did_match_param = \true;
                    break;
                }
            }
            if (!$did_match_param) {
                continue;
            }
            $assignment_node = DataFlowNode::getForAssignment($var_name, $original_location);
            if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $statements_analyzer->data_flow_graph->isVariableUsed($assignment_node)) {
                continue;
            }
            if (!$storage instanceof MethodStorage || !$storage->cased_name || $storage->visibility === \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                if ($this instanceof \Psalm\Internal\Analyzer\ClosureAnalyzer) {
                    IssueBuffer::maybeAdd(new UnusedClosureParam('Param ' . $var_name . ' is never referenced in this method', $original_location), $this->getSuppressedIssues());
                } else {
                    IssueBuffer::maybeAdd(new UnusedParam('Param ' . $var_name . ' is never referenced in this method', $original_location), $this->getSuppressedIssues());
                }
            } else {
                $fq_class_name = (string) $context->self;
                $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
                $method_name_lc = strtolower($storage->cased_name);
                if ($storage->abstract) {
                    continue;
                }
                if (isset($class_storage->overridden_method_ids[$method_name_lc])) {
                    $parent_method_id = end($class_storage->overridden_method_ids[$method_name_lc]);
                    if ($parent_method_id) {
                        $parent_method_storage = $codebase->methods->getStorage($parent_method_id);
                        // if the parent method has a param at that position and isn't abstract
                        if (!$parent_method_storage->abstract && isset($parent_method_storage->params[$position])) {
                            continue;
                        }
                    }
                }
                $unused_params[$position] = $original_location;
            }
        }
        if ($storage instanceof MethodStorage && $this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer && $class_storage && $storage->cased_name && $storage->visibility !== \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
            $method_id_lc = strtolower((string) $this->getMethodId());
            foreach ($storage->params as $i => $_) {
                if (!isset($unused_params[$i])) {
                    $codebase->file_reference_provider->addMethodParamUse($method_id_lc, $i, $method_id_lc);
                    $method_name_lc = strtolower($storage->cased_name);
                    if (!isset($class_storage->overridden_method_ids[$method_name_lc])) {
                        continue;
                    }
                    foreach ($class_storage->overridden_method_ids[$method_name_lc] as $parent_method_id) {
                        $codebase->file_reference_provider->addMethodParamUse(strtolower((string) $parent_method_id), $i, $method_id_lc);
                    }
                }
            }
        }
    }
    /**
     * @param list<FunctionLikeParameter> $params
     * @param list<Param> $param_stmts
     */
    private function processParams(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, FunctionLikeStorage $storage, ?string $cased_method_id, array $params, array $param_stmts, Context $context, bool $has_template_types) : bool
    {
        $check_stmts = \true;
        $codebase = $statements_analyzer->getCodebase();
        $project_analyzer = $statements_analyzer->getProjectAnalyzer();
        foreach ($params as $offset => $function_param) {
            $function_param_id = '$' . $function_param->name;
            $signature_type = $function_param->signature_type;
            $signature_type_location = $function_param->signature_type_location;
            if ($signature_type && $signature_type_location && $signature_type->hasObjectType()) {
                $referenced_type = $signature_type;
                if ($referenced_type->isNullable()) {
                    $referenced_type = $referenced_type->getBuilder();
                    $referenced_type->removeType('null');
                    $referenced_type = $referenced_type->freeze();
                }
                [$start, $end] = $signature_type_location->getSelectionBounds();
                $codebase->analyzer->addOffsetReference($this->getFilePath(), $start, $end, (string) $referenced_type);
            }
            if ($signature_type) {
                $signature_type = TypeExpander::expandUnion($codebase, $signature_type, $context->self, $context->self, $this->getParentFQCLN());
            }
            $parent_nodes = [];
            if ($statements_analyzer->data_flow_graph && $function_param->location) {
                //don't add to taint flow graph if the type can't transmit taints
                if (!$statements_analyzer->data_flow_graph instanceof TaintFlowGraph || $function_param->type === null || !$function_param->type->isSingle() || !$function_param->type->isInt() && !$function_param->type->isFloat() && !$function_param->type->isBool()) {
                    $param_assignment = DataFlowNode::getForAssignment($function_param_id, $function_param->location);
                    $statements_analyzer->data_flow_graph->addNode($param_assignment);
                    if ($cased_method_id) {
                        $type_source = DataFlowNode::getForMethodArgument($cased_method_id, $cased_method_id, $offset, $function_param->location, null);
                        $statements_analyzer->data_flow_graph->addPath($type_source, $param_assignment, 'param');
                    }
                    if ($storage->variadic) {
                        $this->param_nodes += [$param_assignment->id => $param_assignment];
                    }
                    $parent_nodes = [$param_assignment->id => $param_assignment];
                }
            }
            if ($function_param->type) {
                $param_type = $function_param->type;
                try {
                    $param_type = TypeExpander::expandUnion($codebase, $param_type, $context->self, $context->self, $this->getParentFQCLN(), \true, \false, \false, \true, \false, \true);
                } catch (UnresolvableConstantException $e) {
                    if ($function_param->type_location !== null) {
                        IssueBuffer::maybeAdd(new UnresolvableConstant("Could not resolve constant {$e->class_name}::{$e->const_name}", $function_param->type_location), $storage->suppressed_issues, \true);
                    }
                }
                if ($function_param->type_location) {
                    if ($param_type->check($this, $function_param->type_location, $storage->suppressed_issues, [], \false, \false, $this->function instanceof ClassMethod && strtolower($this->function->name->name) !== '__construct', $context->calling_method_id) === \false) {
                        $check_stmts = \false;
                    }
                }
                $param_type = $param_type->addParentNodes($parent_nodes);
            } else {
                $param_type = new Union([new TMixed()], ['by_ref' => $function_param->by_ref, 'parent_nodes' => $parent_nodes]);
            }
            $var_type = $param_type;
            if ($function_param->is_variadic) {
                if ($storage->allow_named_arg_calls) {
                    $var_type = new Union([new TArray([Type::getArrayKey(), $param_type])], ['by_ref' => $function_param->by_ref, 'parent_nodes' => $parent_nodes]);
                } else {
                    $var_type = new Union([Type::getListAtomic($param_type)], ['by_ref' => $function_param->by_ref, 'parent_nodes' => $parent_nodes]);
                }
            }
            $context->vars_in_scope[$function_param_id] = $var_type;
            $context->vars_possibly_in_scope[$function_param_id] = \true;
            if ($function_param->by_ref) {
                $context->vars_in_scope[$function_param_id] = $context->vars_in_scope[$function_param_id]->setProperties(['by_ref' => \true]);
                $context->references_to_external_scope[$function_param_id] = \true;
            }
            $parser_param = $this->function->getParams()[$offset] ?? null;
            if ($function_param->location) {
                $statements_analyzer->registerVariable($function_param_id, $function_param->location, null);
            }
            if (!$function_param->type_location || !$function_param->location) {
                if ($parser_param && $parser_param->default) {
                    ExpressionAnalyzer::analyze($statements_analyzer, $parser_param->default, $context);
                }
                continue;
            }
            if ($signature_type) {
                $union_comparison_result = new TypeComparisonResult();
                if (!UnionTypeComparator::isContainedBy($codebase, $param_type, $signature_type, \false, \false, $union_comparison_result) && !$union_comparison_result->type_coerced_from_mixed) {
                    if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MismatchingDocblockParamType'])) {
                        $this->addOrUpdateParamType($project_analyzer, $function_param->name, $signature_type, \true);
                        continue;
                    }
                    IssueBuffer::maybeAdd(new MismatchingDocblockParamType('Parameter ' . $function_param_id . ' has wrong type \'' . $param_type . '\', should be \'' . $signature_type . '\'', $function_param->type_location), $storage->suppressed_issues, \true);
                    if ($signature_type->check($this, $function_param->type_location, $storage->suppressed_issues, [], \false) === \false) {
                        $check_stmts = \false;
                    }
                    continue;
                }
            }
            if ($parser_param && $parser_param->default) {
                ExpressionAnalyzer::analyze($statements_analyzer, $parser_param->default, $context);
                $default_type = $statements_analyzer->node_data->getType($parser_param->default);
                if ($default_type && !$default_type->hasMixed() && !UnionTypeComparator::isContainedBy($codebase, $default_type, $param_type, \false, \false, null, \true)) {
                    IssueBuffer::maybeAdd(new InvalidParamDefault('Default value type ' . $default_type->getId() . ' for argument ' . ($offset + 1) . ' of method ' . $cased_method_id . ' does not match the given type ' . $param_type->getId(), $function_param->type_location));
                }
            }
            if ($has_template_types) {
                if ($param_type->check($this->source, $function_param->type_location, $this->suppressed_issues, [], \false) === \false) {
                    $check_stmts = \false;
                }
            } else {
                if ($param_type->isVoid()) {
                    IssueBuffer::maybeAdd(new ReservedWord('Parameter cannot be void', $function_param->type_location, 'void'), $this->suppressed_issues);
                }
                if ($param_type->check($this->source, $function_param->type_location, $this->suppressed_issues, [], \false) === \false) {
                    $check_stmts = \false;
                }
            }
            if ($codebase->collect_locations) {
                if ($function_param->type_location !== $function_param->signature_type_location && $function_param->signature_type_location && $function_param->signature_type) {
                    if ($function_param->signature_type->check($this->source, $function_param->signature_type_location, $this->suppressed_issues, [], \false) === \false) {
                        $check_stmts = \false;
                    }
                }
            }
            if ($function_param->by_ref) {
                // register by ref params as having been used, to avoid false positives
                // @todo change the assignment analysis *just* for byref params
                // so that we don't have to do this
                $context->hasVariable('$' . $function_param->name);
            }
            if (count($param_stmts) === count($params)) {
                \Psalm\Internal\Analyzer\AttributesAnalyzer::analyze($this, $context, $function_param, $param_stmts[$offset]->attrGroups, \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_PARAMETER | ($function_param->promoted_property ? \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_PROPERTY : 0), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
        }
        return $check_stmts;
    }
    /**
     * @param FunctionLikeParameter[] $params
     */
    private function alterParams(Codebase $codebase, FunctionLikeStorage $storage, array $params, Context $context) : void
    {
        foreach ($this->function->params as $param) {
            $param_name_node = null;
            if ($param->type instanceof PhpParser\Node\Name) {
                $param_name_node = $param->type;
            } elseif ($param->type instanceof PhpParser\Node\NullableType && $param->type->type instanceof PhpParser\Node\Name) {
                $param_name_node = $param->type->type;
            }
            if ($param_name_node) {
                $resolved_name = \Psalm\Internal\Analyzer\ClassLikeAnalyzer::getFQCLNFromNameObject($param_name_node, $this->getAliases());
                $parent_fqcln = $this->getParentFQCLN();
                if ($resolved_name === 'self' && $context->self) {
                    $resolved_name = $context->self;
                } elseif ($resolved_name === 'parent' && $parent_fqcln) {
                    $resolved_name = $parent_fqcln;
                }
                $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $this, $param_name_node, $resolved_name, $context->calling_method_id, \false, \true);
            }
        }
        if ($this->function->returnType) {
            $return_name_node = null;
            if ($this->function->returnType instanceof PhpParser\Node\Name) {
                $return_name_node = $this->function->returnType;
            } elseif ($this->function->returnType instanceof PhpParser\Node\NullableType && $this->function->returnType->type instanceof PhpParser\Node\Name) {
                $return_name_node = $this->function->returnType->type;
            }
            if ($return_name_node) {
                $resolved_name = \Psalm\Internal\Analyzer\ClassLikeAnalyzer::getFQCLNFromNameObject($return_name_node, $this->getAliases());
                $parent_fqcln = $this->getParentFQCLN();
                if ($resolved_name === 'self' && $context->self) {
                    $resolved_name = $context->self;
                } elseif ($resolved_name === 'parent' && $parent_fqcln) {
                    $resolved_name = $parent_fqcln;
                }
                $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $this, $return_name_node, $resolved_name, $context->calling_method_id, \false, \true);
            }
        }
        if ($storage->return_type && $storage->return_type_location && $storage->return_type_location !== $storage->signature_return_type_location) {
            $replace_type = TypeExpander::expandUnion($codebase, $storage->return_type, $context->self, 'static', $this->getParentFQCLN(), \false);
            $codebase->classlikes->handleDocblockTypeInMigration($codebase, $this, $replace_type, $storage->return_type_location, $context->calling_method_id);
        }
        foreach ($params as $function_param) {
            if ($function_param->type && $function_param->type_location && $function_param->type_location !== $function_param->signature_type_location && $function_param->type_location->file_path === $this->getFilePath()) {
                $replace_type = TypeExpander::expandUnion($codebase, $function_param->type, $context->self, 'static', $this->getParentFQCLN(), \false);
                $codebase->classlikes->handleDocblockTypeInMigration($codebase, $this, $replace_type, $function_param->type_location, $context->calling_method_id);
            }
        }
    }
    /**
     * @param array<PhpParser\Node\Stmt> $function_stmts
     */
    public function verifyReturnType(array $function_stmts, \Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, ?Union $return_type = null, ?string $fq_class_name = null, ?CodeLocation $return_type_location = null, bool $did_explicitly_return = \false, bool $closure_inside_call = \false) : void
    {
        ReturnTypeAnalyzer::verifyReturnType($this->function, $function_stmts, $statements_analyzer, $statements_analyzer->node_data, $this, $return_type, $fq_class_name, $fq_class_name, $return_type_location, [], $did_explicitly_return, $closure_inside_call);
    }
    public function addOrUpdateParamType(\Psalm\Internal\Analyzer\ProjectAnalyzer $project_analyzer, string $param_name, Union $inferred_return_type, bool $docblock_only = \false) : void
    {
        $manipulator = FunctionDocblockManipulator::getForFunction($project_analyzer, $this->source->getFilePath(), $this->function);
        $codebase = $project_analyzer->getCodebase();
        $is_final = \true;
        $fqcln = $this->source->getFQCLN();
        if ($fqcln !== null && $this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer) {
            $class_storage = $codebase->classlike_storage_provider->get($fqcln);
            $is_final = $this->function->isFinal() || $class_storage->final;
        }
        $allow_native_type = !$docblock_only && $codebase->analysis_php_version_id >= 70000 && ($codebase->allow_backwards_incompatible_changes || $is_final || !$this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer);
        $manipulator->setParamType($param_name, $allow_native_type ? $inferred_return_type->toPhpString($this->source->getNamespace(), $this->source->getAliasedClassesFlipped(), $this->source->getFQCLN(), $project_analyzer->getCodebase()->analysis_php_version_id) : null, $inferred_return_type->toNamespacedString($this->source->getNamespace(), $this->source->getAliasedClassesFlipped(), $this->source->getFQCLN(), \false), $inferred_return_type->toNamespacedString($this->source->getNamespace(), $this->source->getAliasedClassesFlipped(), $this->source->getFQCLN(), \true));
    }
    /**
     * Adds return types for the given function
     */
    public function addReturnTypes(Context $context) : void
    {
        if ($this->return_vars_in_scope !== null) {
            $this->return_vars_in_scope = \Psalm\Internal\Analyzer\TypeAnalyzer::combineKeyedTypes($context->vars_in_scope, $this->return_vars_in_scope);
        } else {
            $this->return_vars_in_scope = $context->vars_in_scope;
        }
        if ($this->return_vars_possibly_in_scope !== null) {
            $this->return_vars_possibly_in_scope = array_merge($context->vars_possibly_in_scope, $this->return_vars_possibly_in_scope);
        } else {
            $this->return_vars_possibly_in_scope = $context->vars_possibly_in_scope;
        }
    }
    public function examineParamTypes(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, Context $context, Codebase $codebase, PhpParser\Node $stmt = null) : void
    {
        $storage = $this->getFunctionLikeStorage($statements_analyzer);
        foreach ($storage->params as $param) {
            if ($param->by_ref && isset($context->vars_in_scope['$' . $param->name]) && !$param->is_variadic) {
                $actual_type = $context->vars_in_scope['$' . $param->name];
                $param_out_type = $param->out_type ?: $param->type;
                if ($param_out_type && !$actual_type->hasMixed() && $param->location) {
                    if (!UnionTypeComparator::isContainedBy($codebase, $actual_type, $param_out_type, $actual_type->ignore_nullable_issues, $actual_type->ignore_falsable_issues)) {
                        IssueBuffer::maybeAdd(new ReferenceConstraintViolation('Variable ' . '$' . $param->name . ' is limited to values of type ' . $param_out_type->getId() . ' because it is passed by reference, ' . $actual_type->getId() . ' type found. Use @param-out to specify ' . 'a different output type', $stmt ? new CodeLocation($this, $stmt) : $param->location), $statements_analyzer->getSuppressedIssues());
                    }
                }
            }
        }
    }
    public function getMethodName() : ?string
    {
        if ($this->function instanceof ClassMethod) {
            return (string) $this->function->name;
        }
        return null;
    }
    public function getCorrectlyCasedMethodId(?string $context_self = null) : string
    {
        if ($this->function instanceof ClassMethod) {
            $function_name = (string) $this->function->name;
            return ($context_self ?: $this->source->getFQCLN()) . '::' . $function_name;
        }
        if ($this->function instanceof Function_) {
            $namespace = $this->source->getNamespace();
            return ($namespace ? $namespace . '\\' : '') . $this->function->name;
        }
        if (!$this instanceof \Psalm\Internal\Analyzer\ClosureAnalyzer) {
            throw new UnexpectedValueException('This is weird');
        }
        return $this->getClosureId();
    }
    public function getFunctionLikeStorage(?\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer = null) : FunctionLikeStorage
    {
        $codebase = $this->codebase;
        if ($this->function instanceof ClassMethod && $this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer) {
            $method_id = $this->getMethodId();
            $codebase_methods = $codebase->methods;
            try {
                return $codebase_methods->getStorage($method_id);
            } catch (UnexpectedValueException $e) {
                $declaring_method_id = $codebase_methods->getDeclaringMethodId($method_id);
                if ($declaring_method_id === null) {
                    throw new UnexpectedValueException('Cannot get storage for function that doesn‘t exist');
                }
                // happens for fake constructors
                return $codebase_methods->getStorage($declaring_method_id);
            }
        }
        if ($this instanceof \Psalm\Internal\Analyzer\FunctionAnalyzer) {
            $function_id = $this->getFunctionId();
        } elseif ($this instanceof \Psalm\Internal\Analyzer\ClosureAnalyzer) {
            $function_id = $this->getClosureId();
        } else {
            throw new UnexpectedValueException('This is weird');
        }
        return $codebase->functions->getStorage($statements_analyzer, $function_id);
    }
    /** @return non-empty-string */
    public function getId() : string
    {
        if ($this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer) {
            return (string) $this->getMethodId();
        }
        if ($this instanceof \Psalm\Internal\Analyzer\FunctionAnalyzer) {
            return $this->getFunctionId();
        }
        if ($this instanceof \Psalm\Internal\Analyzer\ClosureAnalyzer) {
            return $this->getClosureId();
        }
        throw new UnexpectedValueException('This is weird');
    }
    /**
     * @psalm-mutation-free
     * @return array<lowercase-string, string>
     */
    public function getAliasedClassesFlipped() : array
    {
        if ($this->source instanceof \Psalm\Internal\Analyzer\NamespaceAnalyzer || $this->source instanceof \Psalm\Internal\Analyzer\FileAnalyzer || $this->source instanceof \Psalm\Internal\Analyzer\ClassLikeAnalyzer) {
            return $this->source->getAliasedClassesFlipped();
        }
        return [];
    }
    /**
     * @psalm-mutation-free
     * @return array<string, string>
     */
    public function getAliasedClassesFlippedReplaceable() : array
    {
        if ($this->source instanceof \Psalm\Internal\Analyzer\NamespaceAnalyzer || $this->source instanceof \Psalm\Internal\Analyzer\FileAnalyzer || $this->source instanceof \Psalm\Internal\Analyzer\ClassLikeAnalyzer) {
            return $this->source->getAliasedClassesFlippedReplaceable();
        }
        return [];
    }
    /**
     * @psalm-mutation-free
     * @return array<string, array<string, Union>>|null
     */
    public function getTemplateTypeMap() : ?array
    {
        if ($this->source instanceof \Psalm\Internal\Analyzer\ClassLikeAnalyzer) {
            return ($this->source->getTemplateTypeMap() ?: []) + ($this->storage->template_types ?: []);
        }
        return $this->storage->template_types;
    }
    public function isStatic() : bool
    {
        return $this->is_static;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * Get a list of suppressed issues
     *
     * @return array<string>
     */
    public function getSuppressedIssues() : array
    {
        return $this->suppressed_issues;
    }
    /**
     * @param array<int, string> $new_issues
     */
    public function addSuppressedIssues(array $new_issues) : void
    {
        if (isset($new_issues[0])) {
            $new_issues = array_combine($new_issues, $new_issues);
        }
        $this->suppressed_issues = $new_issues + $this->suppressed_issues;
    }
    /**
     * @param array<int, string> $new_issues
     */
    public function removeSuppressedIssues(array $new_issues) : void
    {
        if (isset($new_issues[0])) {
            $new_issues = array_combine($new_issues, $new_issues);
        }
        $this->suppressed_issues = array_diff_key($this->suppressed_issues, $new_issues);
    }
    /**
     * Adds a suppressed issue, useful when creating a method checker from scratch
     */
    public function addSuppressedIssue(string $issue_name) : void
    {
        $this->suppressed_issues[] = $issue_name;
    }
    public static function clearCache() : void
    {
        self::$no_effects_hashes = [];
    }
    public function getLocalReturnType(Union $storage_return_type, bool $final = \false) : Union
    {
        if ($this->local_return_type) {
            return $this->local_return_type;
        }
        $this->local_return_type = TypeExpander::expandUnion($this->codebase, $storage_return_type, $this->getFQCLN(), $this->getFQCLN(), $this->getParentFQCLN(), \true, \true, $final);
        return $this->local_return_type;
    }
    /**
     * @return array{
     *        MethodIdentifier|null,
     *        MethodIdentifier|null,
     *        ClassLikeStorage|null,
     *        ?string,
     *        ?string,
     *        array<string, MethodIdentifier>
     * }|null
     */
    private function getFunctionInformation(Context $context, Codebase $codebase, NodeDataProvider $type_provider, FunctionLikeStorage $storage, bool $add_mutations) : ?array
    {
        $classlike_storage_provider = $codebase->classlike_storage_provider;
        $real_method_id = null;
        $method_id = null;
        $cased_method_id = null;
        $hash = null;
        $appearing_class_storage = null;
        $overridden_method_ids = [];
        if ($this instanceof \Psalm\Internal\Analyzer\MethodAnalyzer) {
            if (!$storage instanceof MethodStorage) {
                throw new UnexpectedValueException('$storage must be MethodStorage');
            }
            $real_method_id = $this->getMethodId();
            $method_id = $this->getMethodId($context->self);
            $fq_class_name = (string) $context->self;
            $appearing_class_storage = $classlike_storage_provider->get($fq_class_name);
            if ($add_mutations) {
                if (!$context->collect_initializations) {
                    $hash = md5($real_method_id . '::' . $context->getScopeSummary());
                    // if we know that the function has no effects on vars, we don't bother rechecking
                    if (isset(self::$no_effects_hashes[$hash])) {
                        return null;
                    }
                }
            } elseif ($context->self) {
                if ($appearing_class_storage->template_types) {
                    $template_params = [];
                    foreach ($appearing_class_storage->template_types as $param_name => $template_map) {
                        $key = array_keys($template_map)[0];
                        $template_params[] = new Union([new TTemplateParam($param_name, reset($template_map), $key)]);
                    }
                    $this_object_type = new TGenericObject($context->self, $template_params, \false, !$storage->final);
                } else {
                    $this_object_type = new TNamedObject($context->self, !$storage->final);
                }
                $props = [];
                if ($storage->external_mutation_free && !$storage->mutation_free_inferred) {
                    $props = ['reference_free' => \true];
                    if ($this->function->name->name !== '__construct') {
                        $props['allow_mutations'] = \false;
                    }
                }
                if ($codebase->taint_flow_graph && $storage->specialize_call && $storage->location) {
                    $new_parent_node = DataFlowNode::getForAssignment('$this in ' . $method_id, $storage->location);
                    $codebase->taint_flow_graph->addNode($new_parent_node);
                    $props['parent_nodes'] = [$new_parent_node->id => $new_parent_node];
                }
                if ($this->storage instanceof MethodStorage && $this->storage->if_this_is_type) {
                    $template_result = new TemplateResult($this->getTemplateTypeMap() ?? [], []);
                    TemplateStandinTypeReplacer::fillTemplateResult(new Union([$this_object_type]), $template_result, $codebase, null, $this->storage->if_this_is_type);
                    foreach ($context->vars_in_scope as $var_name => &$var_type) {
                        if (0 === mb_strpos($var_name, '$this->')) {
                            $var_type = TemplateInferredTypeReplacer::replace($var_type, $template_result, $codebase);
                        }
                    }
                    $context->vars_in_scope['$this'] = $this->storage->if_this_is_type->setProperties($props);
                } else {
                    $context->vars_in_scope['$this'] = new Union([$this_object_type], $props);
                }
                $context->vars_possibly_in_scope['$this'] = \true;
            }
            if ($appearing_class_storage->has_visitor_issues) {
                return null;
            }
            $cased_method_id = $fq_class_name . '::' . $storage->cased_name;
            $overridden_method_ids = $codebase->methods->getOverriddenMethodIds($method_id);
            $codeLocation = new CodeLocation($this, $this->function, null, \true);
            if ($overridden_method_ids && !$context->collect_initializations && !$context->collect_mutations) {
                foreach ($overridden_method_ids as $overridden_method_id) {
                    $parent_method_storage = $codebase->methods->getStorage($overridden_method_id);
                    $overridden_fq_class_name = $overridden_method_id->fq_class_name;
                    $parent_storage = $classlike_storage_provider->get($overridden_fq_class_name);
                    if ($this->function->name->name === '__construct' && !$parent_storage->preserve_constructor_signature) {
                        continue;
                    }
                    $implementer_visibility = $storage->visibility;
                    $implementer_appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
                    $implementer_declaring_method_id = $real_method_id;
                    $declaring_class_storage = $appearing_class_storage;
                    if ($implementer_appearing_method_id && $implementer_appearing_method_id !== $implementer_declaring_method_id) {
                        $appearing_fq_class_name = $implementer_appearing_method_id->fq_class_name;
                        $appearing_method_name = $implementer_appearing_method_id->method_name;
                        $declaring_fq_class_name = $implementer_declaring_method_id->fq_class_name;
                        $appearing_class_storage = $classlike_storage_provider->get($appearing_fq_class_name);
                        $declaring_class_storage = $classlike_storage_provider->get($declaring_fq_class_name);
                        if (isset($appearing_class_storage->trait_visibility_map[$appearing_method_name])) {
                            $implementer_visibility = $appearing_class_storage->trait_visibility_map[$appearing_method_name];
                        }
                    }
                    // we've already checked this in the class checker
                    if (!isset($appearing_class_storage->class_implements[strtolower($overridden_fq_class_name)])) {
                        \Psalm\Internal\Analyzer\MethodComparator::compare($codebase, count($overridden_method_ids) === 1 ? $this->function : null, $declaring_class_storage, $parent_storage, $storage, $parent_method_storage, $fq_class_name, $implementer_visibility, $codeLocation, $storage->suppressed_issues);
                    }
                }
            }
            \Psalm\Internal\Analyzer\MethodAnalyzer::checkMethodSignatureMustOmitReturnType($storage, $codeLocation);
            if ($appearing_class_storage->is_enum) {
                \Psalm\Internal\Analyzer\MethodAnalyzer::checkForbiddenEnumMethod($storage);
            }
            if (!$context->calling_method_id || !$context->collect_initializations) {
                $context->calling_method_id = strtolower((string) $method_id);
            }
        } elseif ($this instanceof \Psalm\Internal\Analyzer\FunctionAnalyzer) {
            $function_name = $this->function->name->name;
            $namespace_prefix = $this->getNamespace();
            $cased_method_id = ($namespace_prefix !== null ? $namespace_prefix . '\\' : '') . $function_name;
            $context->calling_function_id = strtolower($cased_method_id);
        } elseif ($this instanceof \Psalm\Internal\Analyzer\ClosureAnalyzer) {
            if ($storage->return_type) {
                $closure_return_type = TypeExpander::expandUnion($codebase, $storage->return_type, $context->self, $context->self, $this->getParentFQCLN());
            } else {
                $closure_return_type = Type::getMixed();
            }
            $closure_type = new TClosure('Closure', $storage->params, $closure_return_type, $storage instanceof FunctionStorage ? $storage->pure : null, $storage instanceof FunctionStorage ? $storage->byref_uses : []);
            $type_provider->setType($this->function, new Union([$closure_type]));
        } else {
            throw new UnexpectedValueException('Impossible');
        }
        return [$real_method_id, $method_id, $appearing_class_storage, $hash, $cased_method_id, $overridden_method_ids];
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Issue\InaccessibleProperty;
use Psalm\Issue\InvalidClass;
use Psalm\Issue\InvalidTemplateParam;
use Psalm\Issue\MissingDependency;
use Psalm\Issue\MissingTemplateParam;
use Psalm\Issue\ReservedWord;
use Psalm\Issue\TooManyTemplateParams;
use Psalm\Issue\UndefinedAttributeClass;
use Psalm\Issue\UndefinedClass;
use Psalm\Issue\UndefinedDocblockClass;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AfterClassLikeExistenceCheckEvent;
use Psalm\StatementsSource;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_keys;
use function array_pop;
use function array_search;
use function count;
use function explode;
use function gettype;
use function implode;
use function in_array;
use function preg_match;
use function preg_replace;
use function strtolower;
/**
 * @internal
 */
abstract class ClassLikeAnalyzer extends \Psalm\Internal\Analyzer\SourceAnalyzer
{
    public const VISIBILITY_PUBLIC = 1;
    public const VISIBILITY_PROTECTED = 2;
    public const VISIBILITY_PRIVATE = 3;
    public const SPECIAL_TYPES = ['int' => 'int', 'string' => 'string', 'float' => 'float', 'bool' => 'bool', 'false' => 'false', 'object' => 'object', 'never' => 'never', 'callable' => 'callable', 'array' => 'array', 'iterable' => 'iterable', 'null' => 'null', 'mixed' => 'mixed'];
    public const GETTYPE_TYPES = ['boolean' => \true, 'integer' => \true, 'double' => \true, 'string' => \true, 'array' => \true, 'object' => \true, 'resource' => \true, 'resource (closed)' => \true, 'NULL' => \true, 'unknown type' => \true];
    protected PhpParser\Node\Stmt\ClassLike $class;
    public \Psalm\Internal\Analyzer\FileAnalyzer $file_analyzer;
    protected string $fq_class_name;
    /**
     * The parent class
     */
    protected ?string $parent_fq_class_name = null;
    /**
     * @var PhpParser\Node\Stmt[]
     */
    protected array $leftover_stmts = [];
    protected ClassLikeStorage $storage;
    public function __construct(PhpParser\Node\Stmt\ClassLike $class, \Psalm\Internal\Analyzer\SourceAnalyzer $source, string $fq_class_name)
    {
        $this->class = $class;
        $this->source = $source;
        $this->file_analyzer = $source->getFileAnalyzer();
        $this->fq_class_name = $fq_class_name;
        $codebase = $source->getCodebase();
        $this->storage = $codebase->classlike_storage_provider->get($fq_class_name);
    }
    public function __destruct()
    {
        unset($this->source);
        unset($this->file_analyzer);
    }
    public function getMethodMutations(string $method_name, Context $context) : void
    {
        $project_analyzer = $this->getFileAnalyzer()->project_analyzer;
        $codebase = $project_analyzer->getCodebase();
        foreach ($this->class->stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod && strtolower($stmt->name->name) === strtolower($method_name)) {
                $method_analyzer = new \Psalm\Internal\Analyzer\MethodAnalyzer($stmt, $this);
                $method_analyzer->analyze($context, new NodeDataProvider(), null, \true);
                $context->clauses = [];
            } elseif ($stmt instanceof PhpParser\Node\Stmt\TraitUse) {
                foreach ($stmt->traits as $trait) {
                    $fq_trait_name = self::getFQCLNFromNameObject($trait, $this->source->getAliases());
                    $trait_file_analyzer = $project_analyzer->getFileAnalyzerForClassLike($fq_trait_name);
                    $trait_node = $codebase->classlikes->getTraitNode($fq_trait_name);
                    $trait_storage = $codebase->classlike_storage_provider->get($fq_trait_name);
                    $trait_aliases = $trait_storage->aliases;
                    if ($trait_aliases === null) {
                        continue;
                    }
                    $trait_analyzer = new \Psalm\Internal\Analyzer\TraitAnalyzer($trait_node, $trait_file_analyzer, $fq_trait_name, $trait_aliases);
                    foreach ($trait_node->stmts as $trait_stmt) {
                        if ($trait_stmt instanceof PhpParser\Node\Stmt\ClassMethod && strtolower($trait_stmt->name->name) === strtolower($method_name)) {
                            $method_analyzer = new \Psalm\Internal\Analyzer\MethodAnalyzer($trait_stmt, $trait_analyzer);
                            $actual_method_id = $method_analyzer->getMethodId();
                            if ($context->self && $context->self !== $this->fq_class_name) {
                                $analyzed_method_id = $method_analyzer->getMethodId($context->self);
                                $declaring_method_id = $codebase->methods->getDeclaringMethodId($analyzed_method_id);
                                if ((string) $actual_method_id !== (string) $declaring_method_id) {
                                    break;
                                }
                            }
                            $method_analyzer->analyze($context, new NodeDataProvider(), null, \true);
                        }
                    }
                    $trait_file_analyzer->clearSourceBeforeDestruction();
                }
            }
        }
    }
    public function getFunctionLikeAnalyzer(string $method_name) : ?\Psalm\Internal\Analyzer\MethodAnalyzer
    {
        foreach ($this->class->stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod && strtolower($stmt->name->name) === strtolower($method_name)) {
                return new \Psalm\Internal\Analyzer\MethodAnalyzer($stmt, $this);
            }
        }
        return null;
    }
    /**
     * @param  array<string>    $suppressed_issues
     */
    public static function checkFullyQualifiedClassLikeName(StatementsSource $statements_source, string $fq_class_name, CodeLocation $code_location, ?string $calling_fq_class_name, ?string $calling_method_id, array $suppressed_issues, ?\Psalm\Internal\Analyzer\ClassLikeNameOptions $options = null) : ?bool
    {
        if ($options === null) {
            $options = new \Psalm\Internal\Analyzer\ClassLikeNameOptions();
        }
        $codebase = $statements_source->getCodebase();
        if ($fq_class_name === '') {
            if (IssueBuffer::accepts(new UndefinedClass('Class or interface <empty string> does not exist', $code_location, 'empty string'), $suppressed_issues)) {
                return \false;
            }
            return null;
        }
        $fq_class_name = preg_replace('/^\\\\/', '', $fq_class_name, 1);
        if (in_array($fq_class_name, ['callable', 'iterable', 'self', 'static', 'parent'], \true)) {
            return \true;
        }
        if (preg_match('/(^|\\\\)(int|float|bool|string|void|null|false|true|object|mixed)$/i', $fq_class_name) || strtolower($fq_class_name) === 'resource') {
            $class_name_parts = explode('\\', $fq_class_name);
            $class_name = array_pop($class_name_parts);
            IssueBuffer::maybeAdd(new ReservedWord($class_name . ' is a reserved word', $code_location, $class_name), $suppressed_issues);
            return null;
        }
        $class_exists = $codebase->classlikes->classExists($fq_class_name, !$options->inferred ? $code_location : null, $calling_fq_class_name, $calling_method_id);
        $interface_exists = $codebase->classlikes->interfaceExists($fq_class_name, !$options->inferred ? $code_location : null, $calling_fq_class_name, $calling_method_id);
        $enum_exists = $codebase->classlikes->enumExists($fq_class_name, !$options->inferred ? $code_location : null, $calling_fq_class_name, $calling_method_id);
        if (!$class_exists && !($interface_exists && $options->allow_interface) && !($enum_exists && $options->allow_enum)) {
            if (!$options->allow_trait || !$codebase->classlikes->traitExists($fq_class_name, $code_location)) {
                if ($options->from_docblock) {
                    if (IssueBuffer::accepts(new UndefinedDocblockClass('Docblock-defined class, interface or enum named ' . $fq_class_name . ' does not exist', $code_location, $fq_class_name), $suppressed_issues)) {
                        return \false;
                    }
                } elseif ($options->from_attribute) {
                    if (IssueBuffer::accepts(new UndefinedAttributeClass('Attribute class ' . $fq_class_name . ' does not exist', $code_location, $fq_class_name), $suppressed_issues)) {
                        return \false;
                    }
                } else {
                    if (IssueBuffer::accepts(new UndefinedClass('Class, interface or enum named ' . $fq_class_name . ' does not exist', $code_location, $fq_class_name), $suppressed_issues)) {
                        return \false;
                    }
                }
            }
            return null;
        }
        $aliased_name = $codebase->classlikes->getUnAliasedName($fq_class_name);
        try {
            $class_storage = $codebase->classlike_storage_provider->get($aliased_name);
        } catch (InvalidArgumentException $e) {
            if (!$options->inferred) {
                throw $e;
            }
            return null;
        }
        foreach ($class_storage->invalid_dependencies as $dependency_class_name => $_) {
            // if the implemented/extended class is stubbed, it may not yet have
            // been hydrated
            if ($codebase->classlike_storage_provider->has($dependency_class_name)) {
                continue;
            }
            if (IssueBuffer::accepts(new MissingDependency($fq_class_name . ' depends on class or interface ' . $dependency_class_name . ' that does not exist', $code_location, $fq_class_name), $suppressed_issues)) {
                return \false;
            }
        }
        if (!$options->inferred) {
            if ($class_exists && !$codebase->classHasCorrectCasing($fq_class_name) || $interface_exists && !$codebase->interfaceHasCorrectCasing($fq_class_name) || $enum_exists && !$codebase->classlikes->enumHasCorrectCasing($fq_class_name)) {
                IssueBuffer::maybeAdd(new InvalidClass('Class, interface or enum ' . $fq_class_name . ' has wrong casing', $code_location, $fq_class_name), $suppressed_issues);
            }
        }
        if (!$options->inferred) {
            $event = new AfterClassLikeExistenceCheckEvent($fq_class_name, $code_location, $statements_source, $codebase, []);
            $codebase->config->eventDispatcher->dispatchAfterClassLikeExistenceCheck($event);
            $file_manipulations = $event->getFileReplacements();
            if ($file_manipulations) {
                FileManipulationBuffer::add($code_location->file_path, $file_manipulations);
            }
        }
        return \true;
    }
    /**
     * Gets the fully-qualified class name from a Name object
     */
    public static function getFQCLNFromNameObject(PhpParser\Node\Name $class_name, Aliases $aliases) : string
    {
        /** @var string|null */
        $resolved_name = $class_name->getAttribute('resolvedName');
        if ($resolved_name) {
            return $resolved_name;
        }
        if ($class_name instanceof PhpParser\Node\Name\FullyQualified) {
            return implode('\\', $class_name->parts);
        }
        if (in_array($class_name->parts[0], ['self', 'static', 'parent'], \true)) {
            return $class_name->parts[0];
        }
        return Type::getFQCLNFromString(implode('\\', $class_name->parts), $aliases);
    }
    /**
     * @psalm-mutation-free
     * @return array<lowercase-string, string>
     */
    public function getAliasedClassesFlipped() : array
    {
        if ($this->source instanceof \Psalm\Internal\Analyzer\NamespaceAnalyzer || $this->source instanceof \Psalm\Internal\Analyzer\FileAnalyzer) {
            return $this->source->getAliasedClassesFlipped();
        }
        return [];
    }
    /**
     * @psalm-mutation-free
     * @return array<string, string>
     */
    public function getAliasedClassesFlippedReplaceable() : array
    {
        if ($this->source instanceof \Psalm\Internal\Analyzer\NamespaceAnalyzer || $this->source instanceof \Psalm\Internal\Analyzer\FileAnalyzer) {
            return $this->source->getAliasedClassesFlippedReplaceable();
        }
        return [];
    }
    /** @psalm-mutation-free */
    public function getFQCLN() : string
    {
        return $this->fq_class_name;
    }
    /** @psalm-mutation-free */
    public function getClassName() : ?string
    {
        return $this->class->name->name ?? null;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, array<string, Union>>|null
     */
    public function getTemplateTypeMap() : ?array
    {
        return $this->storage->template_types;
    }
    /** @psalm-mutation-free */
    public function getParentFQCLN() : ?string
    {
        return $this->parent_fq_class_name;
    }
    /** @psalm-mutation-free */
    public function isStatic() : bool
    {
        return \false;
    }
    /**
     * Gets the Psalm type from a particular value
     *
     * @param  mixed $value
     */
    public static function getTypeFromValue($value) : Union
    {
        switch (gettype($value)) {
            case 'boolean':
                if ($value) {
                    return Type::getTrue();
                }
                return Type::getFalse();
            case 'integer':
                return Type::getInt(\false, $value);
            case 'double':
                return Type::getFloat($value);
            case 'string':
                return Type::getString($value);
            case 'array':
                return Type::getArray();
            case 'NULL':
                return Type::getNull();
            default:
                return Type::getMixed();
        }
    }
    /**
     * @param  string[]         $suppressed_issues
     */
    public static function checkPropertyVisibility(string $property_id, Context $context, \Psalm\Internal\Analyzer\SourceAnalyzer $source, CodeLocation $code_location, array $suppressed_issues, bool $emit_issues = \true) : ?bool
    {
        [$fq_class_name, $property_name] = explode('::$', $property_id);
        $codebase = $source->getCodebase();
        if ($codebase->properties->property_visibility_provider->has($fq_class_name)) {
            $property_visible = $codebase->properties->property_visibility_provider->isPropertyVisible($source, $fq_class_name, $property_name, \true, $context, $code_location);
            if ($property_visible !== null) {
                return $property_visible;
            }
        }
        $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($property_id, \true);
        $appearing_property_class = $codebase->properties->getAppearingClassForProperty($property_id, \true);
        if (!$declaring_property_class || !$appearing_property_class) {
            throw new UnexpectedValueException('Appearing/Declaring classes are not defined for ' . $property_id);
        }
        // if the calling class is the same, we know the property exists, so it must be visible
        if ($appearing_property_class === $context->self) {
            return $emit_issues ? null : \true;
        }
        if ($source->getSource() instanceof \Psalm\Internal\Analyzer\TraitAnalyzer && strtolower($declaring_property_class) === strtolower((string) $source->getFQCLN())) {
            return $emit_issues ? null : \true;
        }
        $class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
        if (!isset($class_storage->properties[$property_name])) {
            throw new UnexpectedValueException('$storage should not be null for ' . $property_id);
        }
        $storage = $class_storage->properties[$property_name];
        switch ($storage->visibility) {
            case self::VISIBILITY_PUBLIC:
                return $emit_issues ? null : \true;
            case self::VISIBILITY_PRIVATE:
                if ($emit_issues) {
                    IssueBuffer::maybeAdd(new InaccessibleProperty('Cannot access private property ' . $property_id . ' from context ' . $context->self, $code_location), $suppressed_issues);
                }
                return null;
            case self::VISIBILITY_PROTECTED:
                if (!$context->self) {
                    if ($emit_issues) {
                        IssueBuffer::maybeAdd(new InaccessibleProperty('Cannot access protected property ' . $property_id, $code_location), $suppressed_issues);
                    }
                    return null;
                }
                if ($codebase->classExtends($appearing_property_class, $context->self)) {
                    return $emit_issues ? null : \true;
                }
                if (!$codebase->classExtends($context->self, $appearing_property_class)) {
                    if ($emit_issues) {
                        IssueBuffer::maybeAdd(new InaccessibleProperty('Cannot access protected property ' . $property_id . ' from context ' . $context->self, $code_location), $suppressed_issues);
                    }
                    return null;
                }
        }
        return $emit_issues ? null : \true;
    }
    protected function checkTemplateParams(Codebase $codebase, ClassLikeStorage $storage, ClassLikeStorage $parent_storage, CodeLocation $code_location, int $given_param_count) : void
    {
        $expected_param_count = $parent_storage->template_types === null ? 0 : count($parent_storage->template_types);
        if ($expected_param_count > $given_param_count) {
            IssueBuffer::maybeAdd(new MissingTemplateParam($storage->name . ' has missing template params when extending ' . $parent_storage->name . ', expecting ' . $expected_param_count, $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
        } elseif ($expected_param_count < $given_param_count) {
            IssueBuffer::maybeAdd(new TooManyTemplateParams($storage->name . ' has too many template params when extending ' . $parent_storage->name . ', expecting ' . $expected_param_count, $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
        }
        $storage_param_count = $storage->template_types ? count($storage->template_types) : 0;
        if ($parent_storage->enforce_template_inheritance && $expected_param_count !== $storage_param_count) {
            if ($expected_param_count > $storage_param_count) {
                IssueBuffer::maybeAdd(new MissingTemplateParam($storage->name . ' requires the same number of template params as ' . $parent_storage->name . ' but saw ' . $storage_param_count, $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new TooManyTemplateParams($storage->name . ' requires the same number of template params as ' . $parent_storage->name . ' but saw ' . $storage_param_count, $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
        }
        if ($parent_storage->template_types && $storage->template_extended_params) {
            $i = 0;
            $previous_extended = [];
            foreach ($parent_storage->template_types as $template_name => $type_map) {
                // declares the variables
                foreach ($type_map as $declaring_class => $template_type) {
                }
                if (isset($storage->template_extended_params[$parent_storage->name][$template_name])) {
                    $extended_type = $storage->template_extended_params[$parent_storage->name][$template_name];
                    if (isset($parent_storage->template_covariants[$i]) && !$parent_storage->template_covariants[$i]) {
                        foreach ($extended_type->getAtomicTypes() as $t) {
                            if ($t instanceof TTemplateParam && $storage->template_types && $storage->template_covariants && ($local_offset = array_search($t->param_name, array_keys($storage->template_types))) !== \false && !empty($storage->template_covariants[$local_offset])) {
                                IssueBuffer::maybeAdd(new InvalidTemplateParam('Cannot extend an invariant template param ' . $template_name . ' into a covariant context', $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
                            }
                        }
                    }
                    if ($parent_storage->enforce_template_inheritance) {
                        foreach ($extended_type->getAtomicTypes() as $t) {
                            if (!$t instanceof TTemplateParam || !isset($storage->template_types[$t->param_name])) {
                                IssueBuffer::maybeAdd(new InvalidTemplateParam('Cannot extend a strictly-enforced parent template param ' . $template_name . ' with a non-template type', $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
                            } elseif ($storage->template_types[$t->param_name][$storage->name]->getId() !== $template_type->getId()) {
                                IssueBuffer::maybeAdd(new InvalidTemplateParam('Cannot extend a strictly-enforced parent template param ' . $template_name . ' with constraint ' . $template_type->getId() . ' with a child template param ' . $t->param_name . ' with different constraint ' . $storage->template_types[$t->param_name][$storage->name]->getId(), $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
                            }
                        }
                    }
                    if (!$template_type->isMixed()) {
                        $template_result = new TemplateResult($previous_extended ?: [], []);
                        $template_type_copy = TemplateStandinTypeReplacer::replace($template_type, $template_result, $codebase, null, $extended_type, null, null);
                        if (!UnionTypeComparator::isContainedBy($codebase, $extended_type, $template_type_copy)) {
                            IssueBuffer::maybeAdd(new InvalidTemplateParam('Extended template param ' . $template_name . ' expects type ' . $template_type_copy->getId() . ', type ' . $extended_type->getId() . ' given', $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
                        } else {
                            $previous_extended[$template_name] = [$declaring_class => $extended_type];
                        }
                    } else {
                        $previous_extended[$template_name] = [$declaring_class => $extended_type];
                    }
                }
                $i++;
            }
        }
    }
    /**
     * @return  array<string, string>
     */
    public static function getClassesForFile(Codebase $codebase, string $file_path) : array
    {
        try {
            return $codebase->file_storage_provider->get($file_path)->classlikes_in_file;
        } catch (InvalidArgumentException $e) {
            return [];
        }
    }
    public function getFileAnalyzer() : \Psalm\Internal\Analyzer\FileAnalyzer
    {
        return $this->file_analyzer;
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\Amp\Loop;
use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\CpuCoreCounter;
use _HumbugBox1cb33d1f20f1\Fidry\CpuCoreCounter\NumberOfCpuCoreNotFound;
use InvalidArgumentException;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\Exception\RefactorException;
use Psalm\Exception\UnsupportedIssueToFixException;
use Psalm\FileManipulation;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\LanguageServer\LanguageServer;
use Psalm\Internal\LanguageServer\ProtocolStreamReader;
use Psalm\Internal\LanguageServer\ProtocolStreamWriter;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\ParserCacheProvider;
use Psalm\Internal\Provider\ProjectCacheProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\Internal\Provider\StatementsProvider;
use Psalm\Issue\CodeIssue;
use Psalm\Issue\InvalidFalsableReturnType;
use Psalm\Issue\InvalidNullableReturnType;
use Psalm\Issue\InvalidReturnType;
use Psalm\Issue\LessSpecificReturnType;
use Psalm\Issue\MismatchingDocblockParamType;
use Psalm\Issue\MismatchingDocblockReturnType;
use Psalm\Issue\MissingClosureReturnType;
use Psalm\Issue\MissingParamType;
use Psalm\Issue\MissingPropertyType;
use Psalm\Issue\MissingReturnType;
use Psalm\Issue\ParamNameMismatch;
use Psalm\Issue\PossiblyUndefinedGlobalVariable;
use Psalm\Issue\PossiblyUndefinedVariable;
use Psalm\Issue\PossiblyUnusedMethod;
use Psalm\Issue\PossiblyUnusedProperty;
use Psalm\Issue\RedundantCast;
use Psalm\Issue\RedundantCastGivenDocblockType;
use Psalm\Issue\UnnecessaryVarAnnotation;
use Psalm\Issue\UnusedMethod;
use Psalm\Issue\UnusedProperty;
use Psalm\Issue\UnusedVariable;
use Psalm\Plugin\EventHandler\Event\AfterCodebasePopulatedEvent;
use Psalm\Progress\Progress;
use Psalm\Progress\VoidProgress;
use Psalm\Report;
use Psalm\Report\ReportOptions;
use Psalm\Type;
use ReflectionProperty;
use UnexpectedValueException;
use function array_combine;
use function array_diff;
use function array_fill_keys;
use function array_filter;
use function array_keys;
use function array_map;
use function array_merge;
use function array_shift;
use function clearstatcache;
use function cli_set_process_title;
use function count;
use function defined;
use function dirname;
use function end;
use function explode;
use function extension_loaded;
use function file_exists;
use function fwrite;
use function implode;
use function in_array;
use function ini_get;
use function is_dir;
use function is_file;
use function microtime;
use function mkdir;
use function number_format;
use function pcntl_fork;
use function preg_match;
use function rename;
use function sprintf;
use function stream_set_blocking;
use function stream_socket_accept;
use function stream_socket_client;
use function stream_socket_server;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
use function usort;
use function version_compare;
use const PHP_EOL;
use const PHP_OS;
use const PHP_VERSION;
use const PSALM_VERSION;
use const STDERR;
use const STDIN;
use const STDOUT;
/**
 * @internal
 */
class ProjectAnalyzer
{
    /**
     * Cached config
     */
    private Config $config;
    public static \Psalm\Internal\Analyzer\ProjectAnalyzer $instance;
    /**
     * An object representing everything we know about the code
     */
    private Codebase $codebase;
    private FileProvider $file_provider;
    private ClassLikeStorageProvider $classlike_storage_provider;
    private ?ParserCacheProvider $parser_cache_provider = null;
    public ?ProjectCacheProvider $project_cache_provider = null;
    private FileReferenceProvider $file_reference_provider;
    public Progress $progress;
    public bool $debug_lines = \false;
    public bool $debug_performance = \false;
    public bool $show_issues = \true;
    public int $threads;
    /**
     * @var array<string, bool>
     */
    private array $issues_to_fix = [];
    public bool $dry_run = \false;
    public bool $full_run = \false;
    public bool $only_replace_php_types_with_non_docblock_types = \false;
    public ?int $onchange_line_limit = null;
    public bool $provide_completion = \false;
    /**
     * @var list<string>
     */
    public array $check_paths_files = [];
    /**
     * @var array<string,string>
     */
    private array $project_files = [];
    /**
     * @var array<string,string>
     */
    private array $extra_files = [];
    /**
     * @var array<string, string>
     */
    private array $to_refactor = [];
    public ?ReportOptions $stdout_report_options = null;
    /**
     * @var array<ReportOptions>
     */
    public array $generated_report_options;
    /**
     * @var array<int, class-string<CodeIssue>>
     */
    private const SUPPORTED_ISSUES_TO_FIX = [InvalidFalsableReturnType::class, InvalidNullableReturnType::class, InvalidReturnType::class, LessSpecificReturnType::class, MismatchingDocblockParamType::class, MismatchingDocblockReturnType::class, MissingClosureReturnType::class, MissingParamType::class, MissingPropertyType::class, MissingReturnType::class, ParamNameMismatch::class, PossiblyUndefinedGlobalVariable::class, PossiblyUndefinedVariable::class, PossiblyUnusedMethod::class, PossiblyUnusedProperty::class, RedundantCast::class, RedundantCastGivenDocblockType::class, UnusedMethod::class, UnusedProperty::class, UnusedVariable::class, UnnecessaryVarAnnotation::class];
    /**
     * When this is true, the language server will send the diagnostic code with a help link.
     */
    public bool $language_server_use_extended_diagnostic_codes = \false;
    /**
     * If this is true then the language server will send log messages to the client with additional information.
     */
    public bool $language_server_verbose = \false;
    /**
     * @param array<ReportOptions> $generated_report_options
     */
    public function __construct(Config $config, Providers $providers, ?ReportOptions $stdout_report_options = null, array $generated_report_options = [], int $threads = 1, ?Progress $progress = null)
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $this->parser_cache_provider = $providers->parser_cache_provider;
        $this->project_cache_provider = $providers->project_cache_provider;
        $this->file_provider = $providers->file_provider;
        $this->classlike_storage_provider = $providers->classlike_storage_provider;
        $this->file_reference_provider = $providers->file_reference_provider;
        $this->progress = $progress;
        $this->threads = $threads;
        $this->config = $config;
        $this->clearCacheDirectoryIfConfigOrComposerLockfileChanged();
        $this->codebase = new Codebase($config, $providers, $progress);
        $this->stdout_report_options = $stdout_report_options;
        $this->generated_report_options = $generated_report_options;
        $this->config->processPluginFileExtensions($this);
        $file_extensions = $this->config->getFileExtensions();
        foreach ($this->config->getProjectDirectories() as $dir_name) {
            $file_paths = $this->file_provider->getFilesInDir($dir_name, $file_extensions, [$this->config, 'isInProjectDirs']);
            foreach ($file_paths as $file_path) {
                $this->addProjectFile($file_path);
            }
        }
        foreach ($this->config->getExtraDirectories() as $dir_name) {
            $file_paths = $this->file_provider->getFilesInDir($dir_name, $file_extensions, [$this->config, 'isInExtraDirs']);
            foreach ($file_paths as $file_path) {
                $this->addExtraFile($file_path);
            }
        }
        foreach ($this->config->getProjectFiles() as $file_path) {
            $this->addProjectFile($file_path);
        }
        self::$instance = $this;
    }
    private function clearCacheDirectoryIfConfigOrComposerLockfileChanged() : void
    {
        $cache_directory = $this->config->getCacheDirectory();
        if ($cache_directory === null) {
            return;
        }
        if ($this->project_cache_provider && $this->project_cache_provider->hasLockfileChanged()) {
            // we only clear the cache if it actually exists
            // if it's not populated yet, we don't clear anything but populate the cache instead
            clearstatcache(\true, $cache_directory);
            if (is_dir($cache_directory)) {
                $this->progress->debug('Composer lockfile change detected, clearing cache directory ' . $cache_directory . "\n");
                Config::removeCacheDirectory($cache_directory);
            }
            if ($this->file_reference_provider->cache) {
                $this->file_reference_provider->cache->setConfigHashCache();
            }
            $this->project_cache_provider->updateComposerLockHash();
        } elseif ($this->file_reference_provider->cache && $this->file_reference_provider->cache->hasConfigChanged()) {
            clearstatcache(\true, $cache_directory);
            if (is_dir($cache_directory)) {
                $this->progress->debug('Config change detected, clearing cache directory ' . $cache_directory . "\n");
                Config::removeCacheDirectory($cache_directory);
            }
            $this->file_reference_provider->cache->setConfigHashCache();
            if ($this->project_cache_provider) {
                $this->project_cache_provider->updateComposerLockHash();
            }
        }
    }
    /**
     * @param  array<string>  $report_file_paths
     * @return list<ReportOptions>
     */
    public static function getFileReportOptions(array $report_file_paths, bool $show_info = \true) : array
    {
        $report_options = [];
        $mapping = ['checkstyle.xml' => Report::TYPE_CHECKSTYLE, 'sonarqube.json' => Report::TYPE_SONARQUBE, 'codeclimate.json' => Report::TYPE_CODECLIMATE, 'summary.json' => Report::TYPE_JSON_SUMMARY, 'junit.xml' => Report::TYPE_JUNIT, '.xml' => Report::TYPE_XML, '.json' => Report::TYPE_JSON, '.txt' => Report::TYPE_TEXT, '.emacs' => Report::TYPE_EMACS, '.pylint' => Report::TYPE_PYLINT, '.console' => Report::TYPE_CONSOLE, '.sarif' => Report::TYPE_SARIF, 'count.txt' => Report::TYPE_COUNT];
        foreach ($report_file_paths as $report_file_path) {
            foreach ($mapping as $extension => $type) {
                if (substr($report_file_path, -strlen($extension)) === $extension) {
                    $o = new ReportOptions();
                    $o->format = $type;
                    $o->show_info = $show_info;
                    $o->output_path = $report_file_path;
                    $o->use_color = \false;
                    $report_options[] = $o;
                    continue 2;
                }
            }
            throw new UnexpectedValueException('Unknown report format ' . $report_file_path);
        }
        return $report_options;
    }
    private function visitAutoloadFiles() : void
    {
        $start_time = microtime(\true);
        $this->config->visitComposerAutoloadFiles($this, $this->progress);
        $now_time = microtime(\true);
        $this->progress->debug('Visiting autoload files took ' . number_format($now_time - $start_time, 3) . 's' . "\n");
    }
    public function server(?string $address = '127.0.0.1:12345', bool $socket_server_mode = \false) : void
    {
        $this->visitAutoloadFiles();
        $this->codebase->diff_methods = \true;
        $this->file_reference_provider->loadReferenceCache();
        $this->codebase->enterServerMode();
        if (ini_get('pcre.jit') === '1' && PHP_OS === 'Darwin' && version_compare(PHP_VERSION, '7.3.0') >= 0 && version_compare(PHP_VERSION, '7.4.0') < 0) {
            // do nothing
        } else {
            $cpu_count = self::getCpuCount();
            // let's not go crazy
            $usable_cpus = $cpu_count - 2;
            if ($usable_cpus > 1) {
                $this->threads = $usable_cpus;
            }
        }
        $this->config->initializePlugins($this);
        foreach ($this->config->getProjectDirectories() as $dir_name) {
            $this->checkDirWithConfig($dir_name, $this->config);
        }
        @cli_set_process_title('Psalm ' . PSALM_VERSION . ' - PHP Language Server');
        if (!$socket_server_mode && $address) {
            // Connect to a TCP server
            $socket = stream_socket_client('tcp://' . $address, $errno, $errstr);
            if ($socket === \false) {
                fwrite(STDERR, "Could not connect to language client. Error {$errno}\n{$errstr}");
                exit(1);
            }
            stream_set_blocking($socket, \false);
            new LanguageServer(new ProtocolStreamReader($socket), new ProtocolStreamWriter($socket), $this);
            Loop::run();
        } elseif ($socket_server_mode && $address) {
            // Run a TCP Server
            $tcpServer = stream_socket_server('tcp://' . $address, $errno, $errstr);
            if ($tcpServer === \false) {
                fwrite(STDERR, "Could not listen on {$address}. Error {$errno}\n{$errstr}");
                exit(1);
            }
            fwrite(STDOUT, "Server listening on {$address}\n");
            $fork_available = \true;
            if (!extension_loaded('pcntl')) {
                fwrite(STDERR, "PCNTL is not available. Only a single connection will be accepted\n");
                $fork_available = \false;
            }
            $disabled_functions = array_map('trim', explode(',', ini_get('disable_functions')));
            if (in_array('pcntl_fork', $disabled_functions)) {
                fwrite(STDERR, "pcntl_fork() is disabled by php configuration (disable_functions directive)." . " Only a single connection will be accepted\n");
                $fork_available = \false;
            }
            while ($socket = stream_socket_accept($tcpServer, -1)) {
                fwrite(STDOUT, "Connection accepted\n");
                stream_set_blocking($socket, \false);
                if ($fork_available) {
                    // If PCNTL is available, fork a child process for the connection
                    // An exit notification will only terminate the child process
                    $pid = pcntl_fork();
                    if ($pid === -1) {
                        fwrite(STDERR, "Could not fork\n");
                        exit(1);
                    }
                    if ($pid === 0) {
                        // Child process
                        $reader = new ProtocolStreamReader($socket);
                        $reader->on('close', static function () : void {
                            fwrite(STDOUT, "Connection closed\n");
                        });
                        new LanguageServer($reader, new ProtocolStreamWriter($socket), $this);
                        // Just for safety
                        exit(0);
                    }
                } else {
                    // If PCNTL is not available, we only accept one connection.
                    // An exit notification will terminate the server
                    new LanguageServer(new ProtocolStreamReader($socket), new ProtocolStreamWriter($socket), $this);
                    Loop::run();
                }
            }
        } else {
            // Use STDIO
            stream_set_blocking(STDIN, \false);
            new LanguageServer(new ProtocolStreamReader(STDIN), new ProtocolStreamWriter(STDOUT), $this);
            Loop::run();
        }
    }
    /** @psalm-mutation-free */
    public static function getInstance() : \Psalm\Internal\Analyzer\ProjectAnalyzer
    {
        /** @psalm-suppress ImpureStaticProperty */
        return self::$instance;
    }
    /** @psalm-mutation-free */
    public function canReportIssues(string $file_path) : bool
    {
        return isset($this->project_files[$file_path]);
    }
    private function generatePHPVersionMessage() : string
    {
        $codebase = $this->codebase;
        switch ($codebase->php_version_source) {
            case 'cli':
                $source = '(set by CLI argument)';
                break;
            case 'config':
                $source = '(set by config file)';
                break;
            case 'composer':
                $source = '(inferred from composer.json)';
                break;
            case 'tests':
                $source = '(set by tests)';
                break;
            case 'runtime':
                $source = '(inferred from current PHP version)';
                break;
        }
        $unsupported_php_extensions = array_diff(array_keys($codebase->config->php_extensions_not_supported), $codebase->config->php_extensions_supported_by_psalm_callmaps);
        $message = sprintf("Target PHP version: %d.%d %s", $codebase->getMajorAnalysisPhpVersion(), $codebase->getMinorAnalysisPhpVersion(), $source);
        if (count($codebase->config->php_extensions) > 0) {
            $enabled_extensions_names = array_keys(array_filter($codebase->config->php_extensions));
            $message .= ' Enabled extensions: ' . implode(', ', $enabled_extensions_names);
        }
        if (count($unsupported_php_extensions) > 0) {
            $message .= ' (unsupported extensions: ' . implode(', ', $unsupported_php_extensions) . ')';
        }
        return "{$message}.\n";
    }
    public function check(string $base_dir, bool $is_diff = \false) : void
    {
        $start_checks = (int) microtime(\true);
        if (!$base_dir) {
            throw new InvalidArgumentException('Cannot work with empty base_dir');
        }
        $diff_files = null;
        $deleted_files = null;
        $this->full_run = \true;
        $reference_cache = $this->file_reference_provider->loadReferenceCache(\true);
        $this->codebase->diff_methods = $is_diff;
        if ($is_diff && $reference_cache && $this->project_cache_provider && $this->project_cache_provider->canDiffFiles()) {
            $deleted_files = $this->file_reference_provider->getDeletedReferencedFiles();
            $diff_files = [...$deleted_files, ...$this->getDiffFiles()];
        }
        $this->progress->write($this->generatePHPVersionMessage());
        $this->progress->startScanningFiles();
        $diff_no_files = \false;
        if ($diff_files === null || $deleted_files === null || count($diff_files) > 200) {
            $this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
            $this->visitAutoloadFiles();
            $this->codebase->scanner->addFilesToShallowScan($this->extra_files);
            $this->codebase->scanner->addFilesToDeepScan($this->project_files);
            $this->codebase->analyzer->addFilesToAnalyze($this->project_files);
            $this->config->initializePlugins($this);
            $this->codebase->scanFiles($this->threads);
            $this->codebase->infer_types_from_usage = \true;
        } else {
            $this->progress->debug(count($diff_files) . ' changed files: ' . "\n");
            $this->progress->debug('    ' . implode("\n    ", $diff_files) . "\n");
            $this->codebase->analyzer->addFilesToShowResults($this->project_files);
            if ($diff_files) {
                $file_list = $this->getReferencedFilesFromDiff($diff_files);
                // strip out deleted files
                $file_list = array_diff($file_list, $deleted_files);
                if ($file_list) {
                    $this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
                    $this->visitAutoloadFiles();
                    $this->checkDiffFilesWithConfig($this->config, $file_list);
                    $this->config->initializePlugins($this);
                    $this->codebase->scanFiles($this->threads);
                } else {
                    $diff_no_files = \true;
                }
            } else {
                $diff_no_files = \true;
            }
        }
        if (!$diff_no_files) {
            $this->config->visitStubFiles($this->codebase, $this->progress);
            $event = new AfterCodebasePopulatedEvent($this->codebase);
            $this->config->eventDispatcher->dispatchAfterCodebasePopulated($event);
        }
        $this->progress->startAnalyzingFiles();
        $this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code, \true);
        if ($this->parser_cache_provider && !$is_diff) {
            $removed_parser_files = $this->parser_cache_provider->deleteOldParserCaches($start_checks);
            if ($removed_parser_files) {
                $this->progress->debug('Removed ' . $removed_parser_files . ' old parser caches' . "\n");
            }
        }
    }
    public function consolidateAnalyzedData() : void
    {
        $this->codebase->classlikes->consolidateAnalyzedData($this->codebase->methods, $this->progress, (bool) $this->codebase->find_unused_code);
    }
    public function trackTaintedInputs() : void
    {
        $this->codebase->taint_flow_graph = new TaintFlowGraph();
    }
    public function trackUnusedSuppressions() : void
    {
        $this->codebase->track_unused_suppressions = \true;
    }
    public function interpretRefactors() : void
    {
        if (!$this->codebase->alter_code) {
            throw new UnexpectedValueException('Should not be checking references');
        }
        // interpret wildcards
        foreach ($this->to_refactor as $source => $destination) {
            if (($source_pos = strpos($source, '*')) && ($destination_pos = strpos($destination, '*')) && $source_pos === strlen($source) - 1 && $destination_pos === strlen($destination) - 1) {
                foreach ($this->codebase->classlike_storage_provider->getAll() as $class_storage) {
                    if (strpos($source, substr($class_storage->name, 0, $source_pos)) === 0) {
                        $this->to_refactor[$class_storage->name] = substr($destination, 0, -1) . substr($class_storage->name, $source_pos);
                    }
                }
                unset($this->to_refactor[$source]);
            }
        }
        foreach ($this->to_refactor as $source => $destination) {
            $source_parts = explode('::', $source);
            $destination_parts = explode('::', $destination);
            if (!$this->codebase->classlikes->hasFullyQualifiedClassName($source_parts[0])) {
                throw new RefactorException('Source class ' . $source_parts[0] . ' doesn’t exist');
            }
            if (count($source_parts) === 1 && count($destination_parts) === 1) {
                if ($this->codebase->classlikes->hasFullyQualifiedClassName($destination_parts[0])) {
                    throw new RefactorException('Destination class ' . $destination_parts[0] . ' already exists');
                }
                $source_class_storage = $this->codebase->classlike_storage_provider->get($source_parts[0]);
                $destination_parts = explode('\\', $destination, -1);
                $destination_ns = implode('\\', $destination_parts);
                $this->codebase->classes_to_move[strtolower($source)] = $destination;
                $destination_class_storage = $this->codebase->classlike_storage_provider->create($destination);
                $destination_class_storage->name = $destination;
                if ($source_class_storage->aliases) {
                    $destination_class_storage->aliases = clone $source_class_storage->aliases;
                    $destination_class_storage->aliases->namespace = $destination_ns;
                }
                $destination_class_storage->location = $source_class_storage->location;
                $destination_class_storage->stmt_location = $source_class_storage->stmt_location;
                $destination_class_storage->populated = \true;
                $this->codebase->class_transforms[strtolower($source)] = $destination;
                continue;
            }
            $source_method_id = new MethodIdentifier($source_parts[0], strtolower($source_parts[1]));
            if ($this->codebase->methods->methodExists($source_method_id)) {
                if ($this->codebase->methods->methodExists(new MethodIdentifier($destination_parts[0], strtolower($destination_parts[1])))) {
                    throw new RefactorException('Destination method ' . $destination . ' already exists');
                }
                if (!$this->codebase->classlikes->classExists($destination_parts[0])) {
                    throw new RefactorException('Destination class ' . $destination_parts[0] . ' doesn’t exist');
                }
                $source_lc = strtolower($source);
                if (strtolower($source_parts[0]) !== strtolower($destination_parts[0])) {
                    $source_method_storage = $this->codebase->methods->getStorage($source_method_id);
                    $destination_class_storage = $this->codebase->classlike_storage_provider->get($destination_parts[0]);
                    if (!$source_method_storage->is_static && !isset($destination_class_storage->parent_classes[strtolower($source_method_id->fq_class_name)])) {
                        throw new RefactorException('Cannot move non-static method ' . $source . ' into unrelated class ' . $destination_parts[0]);
                    }
                    $this->codebase->methods_to_move[$source_lc] = $destination;
                } else {
                    $this->codebase->methods_to_rename[$source_lc] = $destination_parts[1];
                }
                $this->codebase->call_transforms[$source_lc . '\\((.*\\))'] = $destination . '($1)';
                continue;
            }
            if ($source_parts[1][0] === '$') {
                if ($destination_parts[1][0] !== '$') {
                    throw new RefactorException('Destination property must be of the form Foo::$bar');
                }
                if (!$this->codebase->properties->propertyExists($source, \true)) {
                    throw new RefactorException('Property ' . $source . ' does not exist');
                }
                if ($this->codebase->properties->propertyExists($destination, \true)) {
                    throw new RefactorException('Destination property ' . $destination . ' already exists');
                }
                if (!$this->codebase->classlikes->classExists($destination_parts[0])) {
                    throw new RefactorException('Destination class ' . $destination_parts[0] . ' doesn’t exist');
                }
                $source_id = strtolower($source_parts[0]) . '::' . $source_parts[1];
                if (strtolower($source_parts[0]) !== strtolower($destination_parts[0])) {
                    $source_storage = $this->codebase->properties->getStorage($source);
                    if (!$source_storage->is_static) {
                        throw new RefactorException('Cannot move non-static property ' . $source);
                    }
                    $this->codebase->properties_to_move[$source_id] = $destination;
                } else {
                    $this->codebase->properties_to_rename[$source_id] = substr($destination_parts[1], 1);
                }
                $this->codebase->property_transforms[$source_id] = $destination;
                continue;
            }
            $source_class_constants = $this->codebase->classlikes->getConstantsForClass($source_parts[0], ReflectionProperty::IS_PRIVATE);
            if (isset($source_class_constants[$source_parts[1]])) {
                if (!$this->codebase->classlikes->hasFullyQualifiedClassName($destination_parts[0])) {
                    throw new RefactorException('Destination class ' . $destination_parts[0] . ' doesn’t exist');
                }
                $destination_class_constants = $this->codebase->classlikes->getConstantsForClass($destination_parts[0], ReflectionProperty::IS_PRIVATE);
                if (isset($destination_class_constants[$destination_parts[1]])) {
                    throw new RefactorException('Destination constant ' . $destination . ' already exists');
                }
                $source_id = strtolower($source_parts[0]) . '::' . $source_parts[1];
                if (strtolower($source_parts[0]) !== strtolower($destination_parts[0])) {
                    $this->codebase->class_constants_to_move[$source_id] = $destination;
                } else {
                    $this->codebase->class_constants_to_rename[$source_id] = $destination_parts[1];
                }
                $this->codebase->class_constant_transforms[$source_id] = $destination;
                continue;
            }
            throw new RefactorException('Psalm cannot locate ' . $source);
        }
    }
    public function prepareMigration() : void
    {
        if (!$this->codebase->alter_code) {
            throw new UnexpectedValueException('Should not be checking references');
        }
        $this->codebase->classlikes->moveMethods($this->codebase->methods, $this->progress);
        $this->codebase->classlikes->moveProperties($this->codebase->properties, $this->progress);
        $this->codebase->classlikes->moveClassConstants($this->progress);
    }
    public function migrateCode() : void
    {
        if (!$this->codebase->alter_code) {
            throw new UnexpectedValueException('Should not be checking references');
        }
        $migration_manipulations = FileManipulationBuffer::getMigrationManipulations($this->codebase->file_provider);
        if ($migration_manipulations) {
            foreach ($migration_manipulations as $file_path => $file_manipulations) {
                usort($file_manipulations, static function (FileManipulation $a, FileManipulation $b) : int {
                    if ($a->start === $b->start) {
                        if ($b->end === $a->end) {
                            return $b->insertion_text > $a->insertion_text ? 1 : -1;
                        }
                        return $b->end > $a->end ? 1 : -1;
                    }
                    return $b->start > $a->start ? 1 : -1;
                });
                $existing_contents = $this->codebase->file_provider->getContents($file_path);
                foreach ($file_manipulations as $manipulation) {
                    $existing_contents = $manipulation->transform($existing_contents);
                }
                $this->codebase->file_provider->setContents($file_path, $existing_contents);
            }
        }
        if ($this->codebase->classes_to_move) {
            foreach ($this->codebase->classes_to_move as $source => $destination) {
                $source_class_storage = $this->codebase->classlike_storage_provider->get($source);
                if (!$source_class_storage->location) {
                    continue;
                }
                $potential_file_path = $this->config->getPotentialComposerFilePathForClassLike($destination);
                if ($potential_file_path && !file_exists($potential_file_path)) {
                    $containing_dir = dirname($potential_file_path);
                    if (!file_exists($containing_dir)) {
                        mkdir($containing_dir, 0777, \true);
                    }
                    rename($source_class_storage->location->file_path, $potential_file_path);
                }
            }
        }
    }
    public function findReferencesTo(string $symbol) : void
    {
        if (!$this->stdout_report_options) {
            throw new UnexpectedValueException('Not expecting to emit output');
        }
        $locations = $this->codebase->findReferencesToSymbol($symbol);
        foreach ($locations as $location) {
            $snippet = $location->getSnippet();
            $snippet_bounds = $location->getSnippetBounds();
            $selection_bounds = $location->getSelectionBounds();
            $selection_start = $selection_bounds[0] - $snippet_bounds[0];
            $selection_length = $selection_bounds[1] - $selection_bounds[0];
            echo $location->file_name . ':' . $location->getLineNumber() . "\n" . ($this->stdout_report_options->use_color ? substr($snippet, 0, $selection_start) . "\x1b[97;42m" . substr($snippet, $selection_start, $selection_length) . "\x1b[0m" . substr($snippet, $selection_length + $selection_start) : $snippet) . "\n" . "\n";
        }
    }
    public function checkDir(string $dir_name) : void
    {
        $this->file_reference_provider->loadReferenceCache();
        $this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
        $this->checkDirWithConfig($dir_name, $this->config, \true);
        $this->progress->write($this->generatePHPVersionMessage());
        $this->progress->startScanningFiles();
        $this->config->initializePlugins($this);
        $this->codebase->scanFiles($this->threads);
        $this->config->visitStubFiles($this->codebase, $this->progress);
        $this->progress->startAnalyzingFiles();
        $this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code, $this->codebase->find_unused_code === 'always');
    }
    private function checkDirWithConfig(string $dir_name, Config $config, bool $allow_non_project_files = \false) : void
    {
        $file_extensions = $config->getFileExtensions();
        $filter = $allow_non_project_files ? null : [$this->config, 'isInProjectDirs'];
        $file_paths = $this->file_provider->getFilesInDir($dir_name, $file_extensions, $filter);
        $files_to_scan = [];
        foreach ($file_paths as $file_path) {
            $files_to_scan[$file_path] = $file_path;
        }
        $this->codebase->addFilesToAnalyze($files_to_scan);
    }
    public function addProjectFile(string $file_path) : void
    {
        $this->project_files[$file_path] = $file_path;
    }
    public function addExtraFile(string $file_path) : void
    {
        $this->extra_files[$file_path] = $file_path;
    }
    /**
     * @return list<string>
     */
    protected function getDiffFiles() : array
    {
        if (!$this->parser_cache_provider || !$this->project_cache_provider) {
            throw new UnexpectedValueException('Parser cache provider cannot be null here');
        }
        $diff_files = [];
        $last_run = $this->project_cache_provider->getLastRun(PSALM_VERSION);
        foreach ($this->project_files as $file_path) {
            if ($this->file_provider->getModifiedTime($file_path) >= $last_run && $this->parser_cache_provider->loadExistingFileContentsFromCache($file_path) !== $this->file_provider->getContents($file_path)) {
                $diff_files[] = $file_path;
            }
        }
        return $diff_files;
    }
    /**
     * @param  array<string>    $file_list
     */
    private function checkDiffFilesWithConfig(Config $config, array $file_list = []) : void
    {
        $files_to_scan = [];
        foreach ($file_list as $file_path) {
            if (!$this->file_provider->fileExists($file_path)) {
                continue;
            }
            if (!$config->isInProjectDirs($file_path)) {
                $this->progress->debug('skipping ' . $file_path . "\n");
                continue;
            }
            $files_to_scan[$file_path] = $file_path;
        }
        $this->codebase->addFilesToAnalyze($files_to_scan);
    }
    public function checkFile(string $file_path) : void
    {
        $this->progress->debug('Checking ' . $file_path . "\n");
        $this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
        $this->config->hide_external_errors = $this->config->isInProjectDirs($file_path);
        $this->codebase->addFilesToAnalyze([$file_path => $file_path]);
        $this->file_reference_provider->loadReferenceCache();
        $this->progress->write($this->generatePHPVersionMessage());
        $this->progress->startScanningFiles();
        $this->config->initializePlugins($this);
        $this->codebase->scanFiles($this->threads);
        $this->config->visitStubFiles($this->codebase, $this->progress);
        $this->progress->startAnalyzingFiles();
        $this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code, $this->codebase->find_unused_code === 'always');
    }
    /**
     * @param string[] $paths_to_check
     */
    public function checkPaths(array $paths_to_check) : void
    {
        $this->config->visitPreloadedStubFiles($this->codebase, $this->progress);
        $this->visitAutoloadFiles();
        $this->codebase->scanner->addFilesToShallowScan($this->extra_files);
        foreach ($paths_to_check as $path) {
            $this->progress->debug('Checking ' . $path . "\n");
            if (is_dir($path)) {
                $this->checkDirWithConfig($path, $this->config, \true);
            } elseif (is_file($path)) {
                $this->check_paths_files[] = $path;
                $this->codebase->addFilesToAnalyze([$path => $path]);
                $this->config->hide_external_errors = $this->config->isInProjectDirs($path);
            }
        }
        $this->file_reference_provider->loadReferenceCache();
        $this->progress->write($this->generatePHPVersionMessage());
        $this->progress->startScanningFiles();
        $this->config->initializePlugins($this);
        $this->codebase->scanFiles($this->threads);
        $this->config->visitStubFiles($this->codebase, $this->progress);
        $this->progress->startAnalyzingFiles();
        $this->codebase->analyzer->analyzeFiles($this, $this->threads, $this->codebase->alter_code, $this->codebase->find_unused_code === 'always');
        if ($this->stdout_report_options && in_array($this->stdout_report_options->format, [Report::TYPE_CONSOLE, Report::TYPE_PHP_STORM]) && $this->codebase->collect_references) {
            fwrite(STDERR, PHP_EOL . 'To whom it may concern: Psalm cannot detect unused classes, methods and properties' . PHP_EOL . 'when analyzing individual files and folders. Run on the full project to enable' . PHP_EOL . 'complete unused code detection.' . PHP_EOL);
        }
    }
    public function getConfig() : Config
    {
        return $this->config;
    }
    /**
     * @param  array<string>  $diff_files
     * @return array<string, string>
     */
    public function getReferencedFilesFromDiff(array $diff_files, bool $include_referencing_files = \true) : array
    {
        $all_inherited_files_to_check = $diff_files;
        while ($diff_files) {
            $diff_file = array_shift($diff_files);
            $dependent_files = $this->file_reference_provider->getFilesInheritingFromFile($diff_file);
            $new_dependent_files = array_diff($dependent_files, $all_inherited_files_to_check);
            $all_inherited_files_to_check = array_merge($all_inherited_files_to_check, $new_dependent_files);
            $diff_files = array_merge($diff_files, $new_dependent_files);
        }
        $all_files_to_check = $all_inherited_files_to_check;
        if ($include_referencing_files) {
            foreach ($all_inherited_files_to_check as $file_name) {
                $dependent_files = $this->file_reference_provider->getFilesReferencingFile($file_name);
                $all_files_to_check = array_merge($dependent_files, $all_files_to_check);
            }
        }
        return array_combine($all_files_to_check, $all_files_to_check);
    }
    public function fileExists(string $file_path) : bool
    {
        return $this->file_provider->fileExists($file_path);
    }
    public function alterCodeAfterCompletion(bool $dry_run = \false, bool $safe_types = \false) : void
    {
        $this->codebase->alter_code = \true;
        $this->codebase->infer_types_from_usage = \true;
        $this->show_issues = \false;
        $this->dry_run = $dry_run;
        $this->only_replace_php_types_with_non_docblock_types = $safe_types;
    }
    /**
     * @param array<string, string> $to_refactor
     */
    public function refactorCodeAfterCompletion(array $to_refactor) : void
    {
        $this->to_refactor = $to_refactor;
        $this->codebase->alter_code = \true;
        $this->show_issues = \false;
    }
    /**
     * @param 'cli'|'config'|'composer'|'tests' $source
     */
    public function setPhpVersion(string $version, string $source) : void
    {
        if (!preg_match('/^(5\\.[456]|7\\.[01234]|8\\.[012])(\\..*)?$/', $version)) {
            throw new UnexpectedValueException('Expecting a version number in the format x.y');
        }
        [$php_major_version, $php_minor_version] = explode('.', $version);
        $php_major_version = (int) $php_major_version;
        $php_minor_version = (int) $php_minor_version;
        $analysis_php_version_id = $php_major_version * 10000 + $php_minor_version * 100;
        if ($this->codebase->analysis_php_version_id !== $analysis_php_version_id) {
            // reset lexer and parser when php version changes
            StatementsProvider::clearLexer();
            StatementsProvider::clearParser();
        }
        $this->codebase->analysis_php_version_id = $analysis_php_version_id;
        $this->codebase->php_version_source = $source;
    }
    /**
     * @param array<string, bool> $issues
     * @throws UnsupportedIssueToFixException
     */
    public function setIssuesToFix(array $issues) : void
    {
        $supported_issues_to_fix = static::getSupportedIssuesToFix();
        $supported_issues_to_fix[] = 'MissingImmutableAnnotation';
        $supported_issues_to_fix[] = 'MissingPureAnnotation';
        $supported_issues_to_fix[] = 'MissingThrowsDocblock';
        $unsupportedIssues = array_diff(array_keys($issues), $supported_issues_to_fix);
        if (!empty($unsupportedIssues)) {
            throw new UnsupportedIssueToFixException('Psalm doesn\'t know how to fix issue(s): ' . implode(', ', $unsupportedIssues) . PHP_EOL . 'Supported issues to fix are: ' . implode(',', $supported_issues_to_fix));
        }
        $this->issues_to_fix = $issues;
    }
    public function setAllIssuesToFix() : void
    {
        $keyed_issues = array_fill_keys(static::getSupportedIssuesToFix(), \true);
        $this->setIssuesToFix($keyed_issues);
    }
    /**
     * @return array<string, bool>
     */
    public function getIssuesToFix() : array
    {
        return $this->issues_to_fix;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    public function getFileAnalyzerForClassLike(string $fq_class_name) : \Psalm\Internal\Analyzer\FileAnalyzer
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        $file_path = $this->codebase->scanner->getClassLikeFilePath($fq_class_name_lc);
        return new \Psalm\Internal\Analyzer\FileAnalyzer($this, $file_path, $this->config->shortenFileName($file_path));
    }
    public function getMethodMutations(MethodIdentifier $original_method_id, Context $this_context, string $root_file_path, string $root_file_name) : void
    {
        $fq_class_name = $original_method_id->fq_class_name;
        $appearing_method_id = $this->codebase->methods->getAppearingMethodId($original_method_id);
        if (!$appearing_method_id) {
            // this can happen for some abstract classes implementing (but not fully) interfaces
            return;
        }
        $appearing_fq_class_name = $appearing_method_id->fq_class_name;
        $appearing_class_storage = $this->classlike_storage_provider->get($appearing_fq_class_name);
        if (!$appearing_class_storage->user_defined) {
            return;
        }
        $file_analyzer = $this->getFileAnalyzerForClassLike($fq_class_name);
        $file_analyzer->setRootFilePath($root_file_path, $root_file_name);
        if ($appearing_fq_class_name !== $fq_class_name) {
            $file_analyzer = $this->getFileAnalyzerForClassLike($appearing_fq_class_name);
        }
        $stmts = $this->codebase->getStatementsForFile($file_analyzer->getFilePath());
        $file_analyzer->populateCheckers($stmts);
        if (!$this_context->self) {
            $this_context->self = $fq_class_name;
            $this_context->vars_in_scope['$this'] = Type::parseString($fq_class_name);
        }
        $file_analyzer->getMethodMutations($appearing_method_id, $this_context, \true);
        $file_analyzer->class_analyzers_to_analyze = [];
        $file_analyzer->interface_analyzers_to_analyze = [];
        $file_analyzer->clearSourceBeforeDestruction();
    }
    public function getFunctionLikeAnalyzer(MethodIdentifier $method_id, string $file_path) : ?\Psalm\Internal\Analyzer\FunctionLikeAnalyzer
    {
        $file_analyzer = new \Psalm\Internal\Analyzer\FileAnalyzer($this, $file_path, $this->config->shortenFileName($file_path));
        $stmts = $this->codebase->getStatementsForFile($file_analyzer->getFilePath());
        $file_analyzer->populateCheckers($stmts);
        $function_analyzer = $file_analyzer->getFunctionLikeAnalyzer($method_id);
        $file_analyzer->class_analyzers_to_analyze = [];
        $file_analyzer->interface_analyzers_to_analyze = [];
        return $function_analyzer;
    }
    /**
     * Adapted from https://gist.github.com/divinity76/01ef9ca99c111565a72d3a8a6e42f7fb
     * returns number of cpu cores
     * Copyleft 2018, license: WTFPL
     *
     * @throws NumberOfCpuCoreNotFound
     */
    public static function getCpuCount() : int
    {
        if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
            // No support desired for Windows at the moment
            return 1;
        }
        // PHP 7.3 with JIT on OSX is screwed for multi-threads
        if (ini_get('pcre.jit') === '1' && PHP_OS === 'Darwin' && version_compare(PHP_VERSION, '7.3.0') >= 0 && version_compare(PHP_VERSION, '7.4.0') < 0) {
            return 1;
        }
        if (!extension_loaded('pcntl')) {
            // Psalm requires pcntl for multi-threads support
            return 1;
        }
        return (new CpuCoreCounter())->getCount();
    }
    /**
     * @return array<int, string>
     * @psalm-pure
     */
    public static function getSupportedIssuesToFix() : array
    {
        return array_map(
            /** @param class-string $issue_class */
            static function (string $issue_class) : string {
                $parts = explode('\\', $issue_class);
                return end($parts);
            },
            self::SUPPORTED_ISSUES_TO_FIX
        );
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use function str_pad;
use const STR_PAD_LEFT;
/**
 * @internal
 */
class IssueData
{
    public string $severity;
    public int $line_from;
    public int $line_to;
    /**
     * @readonly
     */
    public string $type;
    /**
     * @readonly
     */
    public string $message;
    /**
     * @readonly
     */
    public string $file_name;
    /**
     * @readonly
     */
    public string $file_path;
    /**
     * @readonly
     */
    public string $snippet;
    /**
     * @readonly
     */
    public string $selected_text;
    public int $from;
    public int $to;
    public int $snippet_from;
    public int $snippet_to;
    /**
     * @readonly
     */
    public int $column_from;
    /**
     * @readonly
     */
    public int $column_to;
    public int $error_level;
    /**
     * @readonly
     */
    public int $shortcode;
    /**
     * @readonly
     */
    public string $link;
    /**
     * @var ?list<DataFlowNodeData|array{label: string, entry_path_type: string}>
     */
    public ?array $taint_trace = null;
    /**
     * @var ?list<DataFlowNodeData>
     */
    public ?array $other_references = null;
    /**
     * @readonly
     */
    public ?string $dupe_key = null;
    /**
     * @param ?list<DataFlowNodeData|array{label: string, entry_path_type: string}> $taint_trace
     * @param ?list<DataFlowNodeData> $other_references
     */
    public function __construct(string $severity, int $line_from, int $line_to, string $type, string $message, string $file_name, string $file_path, string $snippet, string $selected_text, int $from, int $to, int $snippet_from, int $snippet_to, int $column_from, int $column_to, int $shortcode = 0, int $error_level = -1, ?array $taint_trace = null, array $other_references = null, ?string $dupe_key = null)
    {
        $this->severity = $severity;
        $this->line_from = $line_from;
        $this->line_to = $line_to;
        $this->type = $type;
        $this->message = $message;
        $this->file_name = $file_name;
        $this->file_path = $file_path;
        $this->snippet = $snippet;
        $this->selected_text = $selected_text;
        $this->from = $from;
        $this->to = $to;
        $this->snippet_from = $snippet_from;
        $this->snippet_to = $snippet_to;
        $this->column_from = $column_from;
        $this->column_to = $column_to;
        $this->shortcode = $shortcode;
        $this->error_level = $error_level;
        $this->link = $shortcode ? 'https://psalm.dev/' . str_pad((string) $shortcode, 3, "0", STR_PAD_LEFT) : '';
        $this->taint_trace = $taint_trace;
        $this->other_references = $other_references;
        $this->dupe_key = $dupe_key;
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\FileManipulation;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use function implode;
use function strtolower;
/**
 * @internal
 */
trait CanAlias
{
    /**
     * @var array<lowercase-string, string>
     */
    private array $aliased_classes = [];
    /**
     * @var array<lowercase-string, CodeLocation>
     */
    private array $aliased_class_locations = [];
    /**
     * @var array<lowercase-string, string>
     */
    private array $aliased_classes_flipped = [];
    /**
     * @var array<lowercase-string, string>
     */
    private array $aliased_classes_flipped_replaceable = [];
    /**
     * @var array<lowercase-string, non-empty-string>
     */
    private array $aliased_functions = [];
    /**
     * @var array<string, string>
     */
    private array $aliased_constants = [];
    public function visitUse(PhpParser\Node\Stmt\Use_ $stmt) : void
    {
        $codebase = $this->getCodebase();
        foreach ($stmt->uses as $use) {
            $use_path = implode('\\', $use->name->parts);
            $use_path_lc = strtolower($use_path);
            $use_alias = $use->alias->name ?? $use->name->getLast();
            $use_alias_lc = strtolower($use_alias);
            switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $stmt->type) {
                case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
                    $this->aliased_functions[$use_alias_lc] = $use_path;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_CONSTANT:
                    $this->aliased_constants[$use_alias] = $use_path;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_NORMAL:
                    $codebase->analyzer->addOffsetReference($this->getFilePath(), (int) $use->getAttribute('startFilePos'), (int) $use->getAttribute('endFilePos'), $use_path);
                    if ($codebase->collect_locations) {
                        // register the path
                        $codebase->use_referencing_locations[$use_path_lc][] = new CodeLocation($this, $use);
                    }
                    if ($codebase->alter_code) {
                        if (isset($codebase->class_transforms[$use_path_lc])) {
                            $new_fq_class_name = $codebase->class_transforms[$use_path_lc];
                            $file_manipulations = [];
                            $file_manipulations[] = new FileManipulation((int) $use->getAttribute('startFilePos'), (int) $use->getAttribute('endFilePos') + 1, $new_fq_class_name . ($use->alias ? ' as ' . $use_alias : ''));
                            FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
                        }
                        $this->aliased_classes_flipped_replaceable[$use_path_lc] = $use_alias;
                    }
                    $this->aliased_classes[$use_alias_lc] = $use_path;
                    $this->aliased_class_locations[$use_alias_lc] = new CodeLocation($this, $stmt);
                    $this->aliased_classes_flipped[$use_path_lc] = $use_alias;
                    break;
            }
        }
    }
    public function visitGroupUse(PhpParser\Node\Stmt\GroupUse $stmt) : void
    {
        $use_prefix = implode('\\', $stmt->prefix->parts);
        $codebase = $this->getCodebase();
        foreach ($stmt->uses as $use) {
            $use_path = $use_prefix . '\\' . implode('\\', $use->name->parts);
            $use_alias = $use->alias->name ?? $use->name->getLast();
            switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $stmt->type) {
                case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
                    $this->aliased_functions[strtolower($use_alias)] = $use_path;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_CONSTANT:
                    $this->aliased_constants[$use_alias] = $use_path;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_NORMAL:
                    if ($codebase->collect_locations) {
                        // register the path
                        $codebase->use_referencing_locations[strtolower($use_path)][] = new CodeLocation($this, $use);
                    }
                    $this->aliased_classes[strtolower($use_alias)] = $use_path;
                    $this->aliased_classes_flipped[strtolower($use_path)] = $use_alias;
                    break;
            }
        }
    }
    /**
     * @psalm-mutation-free
     * @return array<lowercase-string, string>
     */
    public function getAliasedClassesFlipped() : array
    {
        return $this->aliased_classes_flipped;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, string>
     */
    public function getAliasedClassesFlippedReplaceable() : array
    {
        return $this->aliased_classes_flipped_replaceable;
    }
    /** @psalm-mutation-free */
    public function getAliases() : Aliases
    {
        return new Aliases($this->getNamespace(), $this->aliased_classes, $this->aliased_functions, $this->aliased_constants);
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\MethodIdentifier;
use Psalm\Issue\InvalidEnumMethod;
use Psalm\Issue\InvalidStaticInvocation;
use Psalm\Issue\MethodSignatureMustOmitReturnType;
use Psalm\Issue\NonStaticSelfCall;
use Psalm\Issue\UndefinedMethod;
use Psalm\IssueBuffer;
use Psalm\StatementsSource;
use Psalm\Storage\MethodStorage;
use UnexpectedValueException;
use function in_array;
use function strtolower;
/**
 * @internal
 * @extends FunctionLikeAnalyzer<PhpParser\Node\Stmt\ClassMethod>
 */
class MethodAnalyzer extends \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
{
    // https://github.com/php/php-src/blob/a83923044c48982c80804ae1b45e761c271966d3/Zend/zend_enum.c#L77-L95
    private const FORBIDDEN_ENUM_METHODS = ['__construct', '__destruct', '__clone', '__get', '__set', '__unset', '__isset', '__tostring', '__debuginfo', '__serialize', '__unserialize', '__sleep', '__wakeup', '__set_state'];
    /** @psalm-external-mutation-free */
    public function __construct(PhpParser\Node\Stmt\ClassMethod $function, \Psalm\Internal\Analyzer\SourceAnalyzer $source, ?MethodStorage $storage = null)
    {
        $codebase = $source->getCodebase();
        $method_name_lc = strtolower((string) $function->name);
        $source_fqcln = (string) $source->getFQCLN();
        $source_fqcln_lc = strtolower($source_fqcln);
        $method_id = new MethodIdentifier($source_fqcln, $method_name_lc);
        if (!$storage) {
            try {
                $storage = $codebase->methods->getStorage($method_id);
            } catch (UnexpectedValueException $e) {
                $class_storage = $codebase->classlike_storage_provider->get($source_fqcln_lc);
                if (!$class_storage->parent_classes) {
                    throw $e;
                }
                $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
                if (!$declaring_method_id) {
                    throw $e;
                }
                // happens for fake constructors
                $storage = $codebase->methods->getStorage($declaring_method_id);
            }
        }
        parent::__construct($function, $source, $storage);
    }
    /**
     * Determines whether a given method is static or not
     *
     * @param  array<string>   $suppressed_issues
     */
    public static function checkStatic(MethodIdentifier $method_id, bool $self_call, bool $is_context_dynamic, Codebase $codebase, CodeLocation $code_location, array $suppressed_issues, ?bool &$is_dynamic_this_method = \false) : void
    {
        $codebase_methods = $codebase->methods;
        if ($method_id->fq_class_name === 'Closure' && $method_id->method_name === 'fromcallable') {
            return;
        }
        $original_method_id = $method_id;
        $method_id = $codebase_methods->getDeclaringMethodId($method_id);
        if (!$method_id) {
            if (InternalCallMapHandler::inCallMap((string) $original_method_id)) {
                return;
            }
            throw new LogicException('Declaring method for ' . $original_method_id . ' should not be null');
        }
        $storage = $codebase_methods->getStorage($method_id);
        if (!$storage->is_static) {
            if ($self_call) {
                if (!$is_context_dynamic) {
                    if (IssueBuffer::accepts(new NonStaticSelfCall('Method ' . $codebase_methods->getCasedMethodId($method_id) . ' is not static, but is called ' . 'using self::', $code_location), $suppressed_issues)) {
                        return;
                    }
                } else {
                    $is_dynamic_this_method = \true;
                }
            } else {
                if (IssueBuffer::accepts(new InvalidStaticInvocation('Method ' . $codebase_methods->getCasedMethodId($method_id) . ' is not static, but is called ' . 'statically', $code_location), $suppressed_issues)) {
                    return;
                }
            }
        }
    }
    /**
     * @param  string[]     $suppressed_issues
     * @param  lowercase-string|null  $calling_method_id
     */
    public static function checkMethodExists(Codebase $codebase, MethodIdentifier $method_id, CodeLocation $code_location, array $suppressed_issues, ?string $calling_method_id = null) : ?bool
    {
        if ($codebase->methods->methodExists($method_id, $calling_method_id, !$calling_method_id || $calling_method_id !== strtolower((string) $method_id) ? $code_location : null, null, $code_location->file_path)) {
            return \true;
        }
        if (IssueBuffer::accepts(new UndefinedMethod('Method ' . $method_id . ' does not exist', $code_location, (string) $method_id), $suppressed_issues)) {
            return \false;
        }
        return null;
    }
    public static function isMethodVisible(MethodIdentifier $method_id, Context $context, StatementsSource $source) : bool
    {
        $codebase = $source->getCodebase();
        $fq_classlike_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        if ($codebase->methods->visibility_provider->has($fq_classlike_name)) {
            $method_visible = $codebase->methods->visibility_provider->isMethodVisible($source, $fq_classlike_name, $method_name, $context, null);
            if ($method_visible !== null) {
                return $method_visible;
            }
        }
        $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
        if (!$declaring_method_id) {
            // this can happen for methods in the callmap that were not reflected
            return \true;
        }
        $appearing_method_id = $codebase->methods->getAppearingMethodId($method_id);
        $appearing_method_class = null;
        if ($appearing_method_id) {
            $appearing_method_class = $appearing_method_id->fq_class_name;
            // if the calling class is the same, we know the method exists, so it must be visible
            if ($appearing_method_class === $context->self) {
                return \true;
            }
        }
        $declaring_method_class = $declaring_method_id->fq_class_name;
        if ($source->getSource() instanceof \Psalm\Internal\Analyzer\TraitAnalyzer && strtolower($declaring_method_class) === strtolower((string) $source->getFQCLN())) {
            return \true;
        }
        $storage = $codebase->methods->getStorage($declaring_method_id);
        switch ($storage->visibility) {
            case \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PUBLIC:
                return \true;
            case \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PRIVATE:
                return $context->self && $appearing_method_class === $context->self;
            case \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PROTECTED:
                if (!$context->self) {
                    return \false;
                }
                if ($appearing_method_class && $codebase->classExtends($appearing_method_class, $context->self)) {
                    return \true;
                }
                if ($appearing_method_class && !$codebase->classExtends($context->self, $appearing_method_class)) {
                    return \false;
                }
        }
        return \true;
    }
    /**
     * Check that __clone, __construct, and __destruct do not have a return type
     * hint in their signature.
     */
    public static function checkMethodSignatureMustOmitReturnType(MethodStorage $method_storage, CodeLocation $code_location) : void
    {
        if ($method_storage->signature_return_type === null) {
            return;
        }
        if ($method_storage->cased_name === null) {
            return;
        }
        $method_name_lc = strtolower($method_storage->cased_name);
        $methodsOfInterest = ['__clone', '__construct', '__destruct'];
        if (in_array($method_name_lc, $methodsOfInterest, \true)) {
            IssueBuffer::maybeAdd(new MethodSignatureMustOmitReturnType('Method ' . $method_storage->cased_name . ' must not declare a return type', $code_location));
        }
    }
    public function getMethodId(?string $context_self = null) : MethodIdentifier
    {
        $function_name = (string) $this->function->name;
        return new MethodIdentifier($context_self ?: (string) $this->source->getFQCLN(), strtolower($function_name));
    }
    public static function checkForbiddenEnumMethod(MethodStorage $method_storage) : void
    {
        if ($method_storage->cased_name === null || $method_storage->location === null) {
            return;
        }
        $method_name_lc = strtolower($method_storage->cased_name);
        if (in_array($method_name_lc, self::FORBIDDEN_ENUM_METHODS, \true)) {
            IssueBuffer::maybeAdd(new InvalidEnumMethod('Enums cannot define ' . $method_storage->cased_name, $method_storage->location, $method_storage->defining_fqcln . '::' . $method_storage->cased_name));
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Trait_;
use Psalm\Aliases;
use Psalm\Context;
use function assert;
/**
 * @internal
 */
class TraitAnalyzer extends \Psalm\Internal\Analyzer\ClassLikeAnalyzer
{
    private Aliases $aliases;
    public function __construct(Trait_ $class, \Psalm\Internal\Analyzer\SourceAnalyzer $source, string $fq_class_name, Aliases $aliases)
    {
        $this->source = $source;
        $this->file_analyzer = $source->getFileAnalyzer();
        $this->aliases = $source->getAliases();
        $this->class = $class;
        $this->fq_class_name = $fq_class_name;
        $codebase = $source->getCodebase();
        $this->storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $this->aliases = $aliases;
    }
    /** @psalm-mutation-free */
    public function getNamespace() : ?string
    {
        return $this->aliases->namespace;
    }
    /** @psalm-mutation-free */
    public function getAliases() : Aliases
    {
        return $this->aliases;
    }
    /**
     * @psalm-mutation-free
     * @return array<lowercase-string, string>
     */
    public function getAliasedClassesFlipped() : array
    {
        return [];
    }
    /**
     * @psalm-mutation-free
     * @return array<string, string>
     */
    public function getAliasedClassesFlippedReplaceable() : array
    {
        return [];
    }
    public static function analyze(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, Trait_ $stmt, Context $context) : void
    {
        assert($stmt->name !== null);
        $codebase = $statements_analyzer->getCodebase();
        if (!$codebase->classlike_storage_provider->has($stmt->name->name)) {
            return;
        }
        $storage = $codebase->classlike_storage_provider->get($stmt->name->name);
        \Psalm\Internal\Analyzer\AttributesAnalyzer::analyze($statements_analyzer, $context, $storage, $stmt->attrGroups, \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_CLASS, $storage->suppressed_issues + $statements_analyzer->getSuppressedIssues());
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use InvalidArgumentException;
use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\Statements\Expression\ClassConstAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Issue\ParseError;
use Psalm\Issue\UndefinedInterface;
use Psalm\IssueBuffer;
use UnexpectedValueException;
use function strtolower;
/**
 * @internal
 */
class InterfaceAnalyzer extends \Psalm\Internal\Analyzer\ClassLikeAnalyzer
{
    public function __construct(PhpParser\Node\Stmt\Interface_ $interface, \Psalm\Internal\Analyzer\SourceAnalyzer $source, string $fq_interface_name)
    {
        parent::__construct($interface, $source, $fq_interface_name);
    }
    public function analyze() : void
    {
        if (!$this->class instanceof PhpParser\Node\Stmt\Interface_) {
            throw new LogicException('Something went badly wrong');
        }
        $project_analyzer = $this->file_analyzer->project_analyzer;
        $codebase = $project_analyzer->getCodebase();
        $config = $project_analyzer->getConfig();
        $fq_interface_name = $this->getFQCLN();
        if (!$fq_interface_name) {
            throw new UnexpectedValueException('bad');
        }
        $class_storage = $codebase->classlike_storage_provider->get($fq_interface_name);
        if ($this->class->extends) {
            foreach ($this->class->extends as $extended_interface) {
                $extended_interface_name = self::getFQCLNFromNameObject($extended_interface, $this->getAliases());
                $parent_reference_location = new CodeLocation($this, $extended_interface);
                if (!$codebase->classOrInterfaceExists($extended_interface_name, $parent_reference_location)) {
                    // we should not normally get here
                    return;
                }
                try {
                    $extended_interface_storage = $codebase->classlike_storage_provider->get($extended_interface_name);
                } catch (InvalidArgumentException $e) {
                    continue;
                }
                $code_location = new CodeLocation($this, $extended_interface);
                if (!$extended_interface_storage->is_interface) {
                    IssueBuffer::maybeAdd(new UndefinedInterface($extended_interface_name . ' is not an interface', $code_location, $extended_interface_name), $this->getSuppressedIssues());
                }
                if ($codebase->store_node_types && $extended_interface_name) {
                    $bounds = $parent_reference_location->getSelectionBounds();
                    $codebase->analyzer->addOffsetReference($this->getFilePath(), $bounds[0], $bounds[1], $extended_interface_name);
                }
                $this->checkTemplateParams($codebase, $class_storage, $extended_interface_storage, $code_location, $class_storage->template_type_extends_count[$extended_interface_name] ?? 0);
            }
        }
        $fq_interface_name = $this->getFQCLN();
        if (!$fq_interface_name) {
            throw new UnexpectedValueException('bad');
        }
        $class_storage = $codebase->classlike_storage_provider->get($fq_interface_name);
        $interface_context = new Context($this->getFQCLN());
        \Psalm\Internal\Analyzer\AttributesAnalyzer::analyze($this, $interface_context, $class_storage, $this->class->attrGroups, \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_CLASS, $class_storage->suppressed_issues + $this->getSuppressedIssues());
        $member_stmts = [];
        foreach ($this->class->stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
                $method_analyzer = new \Psalm\Internal\Analyzer\MethodAnalyzer($stmt, $this);
                $type_provider = new NodeDataProvider();
                $method_analyzer->analyze($interface_context, $type_provider);
                $actual_method_id = $method_analyzer->getMethodId();
                if ($stmt->name->name !== '__construct' && $stmt->name->name !== '__destruct' && $config->reportIssueInFile('InvalidReturnType', $this->getFilePath())) {
                    \Psalm\Internal\Analyzer\ClassAnalyzer::analyzeClassMethodReturnType($stmt, $method_analyzer, $this, $type_provider, $codebase, $class_storage, $fq_interface_name, $actual_method_id, $actual_method_id, \false);
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Property) {
                IssueBuffer::maybeAdd(new ParseError('Interfaces cannot have properties', new CodeLocation($this, $stmt)));
                return;
            } elseif ($stmt instanceof PhpParser\Node\Stmt\ClassConst) {
                $member_stmts[] = $stmt;
                foreach ($stmt->consts as $const) {
                    $const_id = strtolower($this->fq_class_name) . '::' . $const->name;
                    foreach ($codebase->class_constants_to_rename as $original_const_id => $new_const_name) {
                        if ($const_id === $original_const_id) {
                            $file_manipulations = [new FileManipulation((int) $const->name->getAttribute('startFilePos'), (int) $const->name->getAttribute('endFilePos') + 1, $new_const_name)];
                            FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
                        }
                    }
                }
            }
        }
        $statements_analyzer = new \Psalm\Internal\Analyzer\StatementsAnalyzer($this, new NodeDataProvider());
        $statements_analyzer->analyze($member_stmts, $interface_context, null, \true);
        ClassConstAnalyzer::analyze($this->storage, $this->getCodebase());
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\NodeTypeProvider;
use function array_diff;
use function array_filter;
use function array_intersect;
use function array_unique;
use function array_values;
use function count;
use function in_array;
/**
 * @internal
 */
class ScopeAnalyzer
{
    public const ACTION_END = 'END';
    public const ACTION_BREAK = 'BREAK';
    public const ACTION_CONTINUE = 'CONTINUE';
    public const ACTION_LEAVE_SWITCH = 'LEAVE_SWITCH';
    public const ACTION_LEAVE_LOOP = 'LEAVE_LOOP';
    public const ACTION_NONE = 'NONE';
    public const ACTION_RETURN = 'RETURN';
    /**
     * @param array<PhpParser\Node> $stmts
     * @param list<'loop'|'switch'> $break_types
     * @param bool $return_is_exit Exit and Throw statements are treated differently from return if this is false
     * @return list<self::ACTION_*>
     * @psalm-suppress ComplexMethod nothing much we can do
     */
    public static function getControlActions(array $stmts, ?NodeDataProvider $nodes, array $break_types, bool $return_is_exit = \true) : array
    {
        if (empty($stmts)) {
            return [self::ACTION_NONE];
        }
        $control_actions = [];
        foreach ($stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\Return_ || $stmt instanceof PhpParser\Node\Stmt\Throw_ || $stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Exit_) {
                if (!$return_is_exit && $stmt instanceof PhpParser\Node\Stmt\Return_) {
                    $stmt_return_type = null;
                    if ($nodes && $stmt->expr) {
                        $stmt_return_type = $nodes->getType($stmt->expr);
                    }
                    // don't consider a return if the expression never returns (e.g. a throw inside a short closure)
                    if ($stmt_return_type && $stmt_return_type->isNever()) {
                        return array_values(array_unique([...$control_actions, ...[self::ACTION_END]]));
                    }
                    return array_values(array_unique([...$control_actions, ...[self::ACTION_RETURN]]));
                }
                return array_values(array_unique([...$control_actions, ...[self::ACTION_END]]));
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Expression) {
                // This allows calls to functions that always exit to act as exit statements themselves
                if ($nodes && ($stmt_expr_type = $nodes->getType($stmt->expr)) && $stmt_expr_type->isNever()) {
                    return array_values(array_unique([...$control_actions, ...[self::ACTION_END]]));
                }
                continue;
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Continue_) {
                $count = !$stmt->num ? 1 : ($stmt->num instanceof PhpParser\Node\Scalar\LNumber ? $stmt->num->value : null);
                if ($break_types && $count !== null && count($break_types) >= $count) {
                    /** @psalm-suppress InvalidArrayOffset Some int-range improvements are needed */
                    if ($break_types[count($break_types) - $count] === 'switch') {
                        return [...$control_actions, ...[self::ACTION_LEAVE_SWITCH]];
                    }
                    return array_values($control_actions);
                }
                return array_values(array_unique([...$control_actions, ...[self::ACTION_CONTINUE]]));
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Break_) {
                $count = !$stmt->num ? 1 : ($stmt->num instanceof PhpParser\Node\Scalar\LNumber ? $stmt->num->value : null);
                if ($break_types && $count !== null && count($break_types) >= $count) {
                    /** @psalm-suppress InvalidArrayOffset Some int-range improvements are needed */
                    if ($break_types[count($break_types) - $count] === 'switch') {
                        return [...$control_actions, ...[self::ACTION_LEAVE_SWITCH]];
                    }
                    /** @psalm-suppress InvalidArrayOffset Some int-range improvements are needed */
                    if ($break_types[count($break_types) - $count] === 'loop') {
                        return [...$control_actions, ...[self::ACTION_LEAVE_LOOP]];
                    }
                    return array_values($control_actions);
                }
                return array_values(array_unique([...$control_actions, ...[self::ACTION_BREAK]]));
            }
            if ($stmt instanceof PhpParser\Node\Stmt\If_) {
                $if_statement_actions = self::getControlActions($stmt->stmts, $nodes, $break_types, $return_is_exit);
                $all_leave = !array_filter($if_statement_actions, static fn(string $action): bool => $action === self::ACTION_NONE);
                $else_statement_actions = $stmt->else ? self::getControlActions($stmt->else->stmts, $nodes, $break_types, $return_is_exit) : [];
                $all_leave = $all_leave && $else_statement_actions && !array_filter($else_statement_actions, static fn(string $action): bool => $action === self::ACTION_NONE);
                $all_elseif_actions = [];
                if ($stmt->elseifs) {
                    foreach ($stmt->elseifs as $elseif) {
                        $elseif_control_actions = self::getControlActions($elseif->stmts, $nodes, $break_types, $return_is_exit);
                        $all_leave = $all_leave && !array_filter($elseif_control_actions, static fn(string $action): bool => $action === self::ACTION_NONE);
                        $all_elseif_actions = [...$elseif_control_actions, ...$all_elseif_actions];
                    }
                }
                if ($all_leave) {
                    return array_values(array_unique([...$control_actions, ...$if_statement_actions, ...$else_statement_actions, ...$all_elseif_actions]));
                }
                $control_actions = array_filter([...$control_actions, ...$if_statement_actions, ...$else_statement_actions, ...$all_elseif_actions], static fn(string $action): bool => $action !== self::ACTION_NONE);
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Switch_) {
                $has_ended = \false;
                $has_non_breaking_default = \false;
                $has_default_terminator = \false;
                $all_case_actions = [];
                // iterate backwards in a case statement
                for ($d = count($stmt->cases) - 1; $d >= 0; --$d) {
                    $case = $stmt->cases[$d];
                    $case_actions = self::getControlActions($case->stmts, $nodes, [...$break_types, ...['switch']], $return_is_exit);
                    if (array_intersect([self::ACTION_LEAVE_SWITCH, self::ACTION_BREAK, self::ACTION_CONTINUE], $case_actions)) {
                        continue 2;
                    }
                    if (!$case->cond) {
                        $has_non_breaking_default = \true;
                    }
                    $case_does_end = !array_diff($control_actions, [self::ACTION_END, self::ACTION_RETURN]);
                    if ($case_does_end) {
                        $has_ended = \true;
                    }
                    $all_case_actions = [...$all_case_actions, ...$case_actions];
                    if (!$case_does_end && !$has_ended) {
                        continue 2;
                    }
                    if ($has_non_breaking_default && $case_does_end) {
                        $has_default_terminator = \true;
                    }
                }
                $all_case_actions = array_filter($all_case_actions, static fn(string $action): bool => $action !== self::ACTION_NONE);
                if ($has_default_terminator || $stmt->getAttribute('allMatched', \false)) {
                    return array_values(array_unique([...$control_actions, ...$all_case_actions]));
                }
                $control_actions = [...$control_actions, ...$all_case_actions];
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Do_ || $stmt instanceof PhpParser\Node\Stmt\While_ || $stmt instanceof PhpParser\Node\Stmt\Foreach_ || $stmt instanceof PhpParser\Node\Stmt\For_) {
                $loop_actions = self::getControlActions($stmt->stmts, $nodes, [...$break_types, ...['loop']], $return_is_exit);
                $control_actions = array_filter([...$control_actions, ...$loop_actions], static fn(string $action): bool => $action !== self::ACTION_NONE);
                if (($stmt instanceof PhpParser\Node\Stmt\While_ || $stmt instanceof PhpParser\Node\Stmt\Do_) && $nodes && ($stmt_expr_type = $nodes->getType($stmt->cond)) && $stmt_expr_type->isAlwaysTruthy() && !in_array(self::ACTION_LEAVE_LOOP, $control_actions, \true)) {
                    //infinite while loop that only return don't have an exit path
                    $have_exit_path = (bool) array_diff($control_actions, [self::ACTION_END, self::ACTION_RETURN]);
                    if (!$have_exit_path) {
                        return array_values(array_unique($control_actions));
                    }
                }
                if ($stmt instanceof PhpParser\Node\Stmt\For_ && $nodes && !in_array(self::ACTION_LEAVE_LOOP, $control_actions, \true)) {
                    $is_infinite_loop = \true;
                    if ($stmt->cond) {
                        foreach ($stmt->cond as $cond) {
                            $stmt_expr_type = $nodes->getType($cond);
                            if (!$stmt_expr_type || !$stmt_expr_type->isAlwaysTruthy()) {
                                $is_infinite_loop = \false;
                            }
                        }
                    }
                    if ($is_infinite_loop) {
                        //infinite while loop that only return don't have an exit path
                        $have_exit_path = (bool) array_diff($control_actions, [self::ACTION_END, self::ACTION_RETURN]);
                        if (!$have_exit_path) {
                            return array_values(array_unique($control_actions));
                        }
                    }
                }
                $control_actions = array_filter($control_actions, static fn(string $action): bool => $action !== self::ACTION_LEAVE_LOOP);
            }
            if ($stmt instanceof PhpParser\Node\Stmt\TryCatch) {
                $try_statement_actions = self::getControlActions($stmt->stmts, $nodes, $break_types, $return_is_exit);
                $try_leaves = !array_filter($try_statement_actions, static fn(string $action): bool => $action === self::ACTION_NONE);
                $all_catch_actions = [];
                if ($stmt->catches) {
                    $all_leave = $try_leaves;
                    foreach ($stmt->catches as $catch) {
                        $catch_actions = self::getControlActions($catch->stmts, $nodes, $break_types, $return_is_exit);
                        $all_leave = $all_leave && !array_filter($catch_actions, static fn(string $action): bool => $action === self::ACTION_NONE);
                        if (!$all_leave) {
                            $control_actions = [...$control_actions, ...$catch_actions];
                        } else {
                            $all_catch_actions = [...$all_catch_actions, ...$catch_actions];
                        }
                    }
                    if ($all_leave && $try_statement_actions !== [self::ACTION_NONE]) {
                        return array_values(array_unique([...$control_actions, ...$try_statement_actions, ...$all_catch_actions]));
                    }
                } elseif ($try_leaves) {
                    return array_values(array_unique([...$control_actions, ...$try_statement_actions]));
                }
                if ($stmt->finally && $stmt->finally->stmts) {
                    $finally_statement_actions = self::getControlActions($stmt->finally->stmts, $nodes, $break_types, $return_is_exit);
                    if (!in_array(self::ACTION_NONE, $finally_statement_actions, \true)) {
                        return [...array_filter($control_actions, static fn(string $action): bool => $action !== self::ACTION_NONE), ...$finally_statement_actions];
                    }
                }
                $control_actions = array_filter([...$control_actions, ...$try_statement_actions], static fn(string $action): bool => $action !== self::ACTION_NONE);
            }
        }
        $control_actions[] = self::ACTION_NONE;
        return array_values(array_unique($control_actions));
    }
    /**
     * @param   array<PhpParser\Node> $stmts
     */
    public static function onlyThrowsOrExits(NodeTypeProvider $type_provider, array $stmts) : bool
    {
        if (empty($stmts)) {
            return \false;
        }
        for ($i = count($stmts) - 1; $i >= 0; --$i) {
            $stmt = $stmts[$i];
            if ($stmt instanceof PhpParser\Node\Stmt\Throw_ || $stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Exit_) {
                return \true;
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Expression) {
                $stmt_type = $type_provider->getType($stmt->expr);
                if ($stmt_type && $stmt_type->isNever()) {
                    return \true;
                }
            }
        }
        return \false;
    }
    /**
     * @param   array<PhpParser\Node> $stmts
     */
    public static function onlyThrows(array $stmts) : bool
    {
        $stmts_count = count($stmts);
        if ($stmts_count !== 1) {
            return \false;
        }
        foreach ($stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\Throw_) {
                return \true;
            }
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use Psalm\Aliases;
use Psalm\Codebase;
use Psalm\NodeTypeProvider;
use Psalm\StatementsSource;
use Psalm\Type\Union;
/**
 * @internal
 */
abstract class SourceAnalyzer implements StatementsSource
{
    protected \Psalm\Internal\Analyzer\SourceAnalyzer $source;
    public function __destruct()
    {
        unset($this->source);
    }
    /** @psalm-mutation-free */
    public function getAliases() : Aliases
    {
        return $this->source->getAliases();
    }
    /**
     * @psalm-mutation-free
     * @return array<lowercase-string, string>
     */
    public function getAliasedClassesFlipped() : array
    {
        return $this->source->getAliasedClassesFlipped();
    }
    /**
     * @psalm-mutation-free
     * @return array<string, string>
     */
    public function getAliasedClassesFlippedReplaceable() : array
    {
        return $this->source->getAliasedClassesFlippedReplaceable();
    }
    /** @psalm-mutation-free */
    public function getFQCLN() : ?string
    {
        return $this->source->getFQCLN();
    }
    /** @psalm-mutation-free */
    public function getClassName() : ?string
    {
        return $this->source->getClassName();
    }
    /** @psalm-mutation-free */
    public function getParentFQCLN() : ?string
    {
        return $this->source->getParentFQCLN();
    }
    /** @psalm-mutation-free */
    public function getFileName() : string
    {
        return $this->source->getFileName();
    }
    /** @psalm-mutation-free */
    public function getFilePath() : string
    {
        return $this->source->getFilePath();
    }
    /** @psalm-mutation-free */
    public function getRootFileName() : string
    {
        return $this->source->getRootFileName();
    }
    /** @psalm-mutation-free */
    public function getRootFilePath() : string
    {
        return $this->source->getRootFilePath();
    }
    public function setRootFilePath(string $file_path, string $file_name) : void
    {
        $this->source->setRootFilePath($file_path, $file_name);
    }
    /** @psalm-mutation-free */
    public function hasParentFilePath(string $file_path) : bool
    {
        return $this->source->hasParentFilePath($file_path);
    }
    /** @psalm-mutation-free */
    public function hasAlreadyRequiredFilePath(string $file_path) : bool
    {
        return $this->source->hasAlreadyRequiredFilePath($file_path);
    }
    /** @psalm-mutation-free */
    public function getRequireNesting() : int
    {
        return $this->source->getRequireNesting();
    }
    /**
     * @psalm-mutation-free
     */
    public function getSource() : StatementsSource
    {
        return $this->source;
    }
    /**
     * Get a list of suppressed issues
     *
     * @psalm-mutation-free
     * @return array<string>
     */
    public function getSuppressedIssues() : array
    {
        return $this->source->getSuppressedIssues();
    }
    /**
     * @param array<int, string> $new_issues
     */
    public function addSuppressedIssues(array $new_issues) : void
    {
        $this->source->addSuppressedIssues($new_issues);
    }
    /**
     * @param array<int, string> $new_issues
     */
    public function removeSuppressedIssues(array $new_issues) : void
    {
        $this->source->removeSuppressedIssues($new_issues);
    }
    /** @psalm-mutation-free */
    public function getNamespace() : ?string
    {
        return $this->source->getNamespace();
    }
    /** @psalm-mutation-free */
    public function isStatic() : bool
    {
        return $this->source->isStatic();
    }
    /**
     * @psalm-mutation-free
     */
    public function getCodebase() : Codebase
    {
        return $this->source->getCodebase();
    }
    /**
     * @psalm-mutation-free
     */
    public function getProjectAnalyzer() : \Psalm\Internal\Analyzer\ProjectAnalyzer
    {
        return $this->source->getProjectAnalyzer();
    }
    /**
     * @psalm-mutation-free
     */
    public function getFileAnalyzer() : \Psalm\Internal\Analyzer\FileAnalyzer
    {
        return $this->source->getFileAnalyzer();
    }
    /**
     * @psalm-mutation-free
     * @return array<string, array<string, Union>>|null
     */
    public function getTemplateTypeMap() : ?array
    {
        return $this->source->getTemplateTypeMap();
    }
    /** @psalm-mutation-free */
    public function getNodeTypeProvider() : NodeTypeProvider
    {
        return $this->source->getNodeTypeProvider();
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use Exception;
use InvalidArgumentException;
use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Class_;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Context;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\FunctionLike\ReturnTypeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\Statements\Expression\ClassConstAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\FileManipulation\PropertyDocblockManipulator;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\DeprecatedInterface;
use Psalm\Issue\DeprecatedTrait;
use Psalm\Issue\DuplicateEnumCaseValue;
use Psalm\Issue\ExtensionRequirementViolation;
use Psalm\Issue\ImplementationRequirementViolation;
use Psalm\Issue\InaccessibleMethod;
use Psalm\Issue\InternalClass;
use Psalm\Issue\InvalidEnumCaseValue;
use Psalm\Issue\InvalidExtendClass;
use Psalm\Issue\InvalidTraversableImplementation;
use Psalm\Issue\MethodSignatureMismatch;
use Psalm\Issue\MismatchingDocblockPropertyType;
use Psalm\Issue\MissingConstructor;
use Psalm\Issue\MissingImmutableAnnotation;
use Psalm\Issue\MissingPropertyType;
use Psalm\Issue\MutableDependency;
use Psalm\Issue\NoEnumProperties;
use Psalm\Issue\NonInvariantDocblockPropertyType;
use Psalm\Issue\NonInvariantPropertyType;
use Psalm\Issue\OverriddenPropertyAccess;
use Psalm\Issue\ParseError;
use Psalm\Issue\PropertyNotSetInConstructor;
use Psalm\Issue\ReservedWord;
use Psalm\Issue\UndefinedClass;
use Psalm\Issue\UndefinedInterface;
use Psalm\Issue\UndefinedTrait;
use Psalm\Issue\UnimplementedAbstractMethod;
use Psalm\Issue\UnimplementedInterfaceMethod;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\VirtualStaticCall;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\Stmt\VirtualClassMethod;
use Psalm\Node\Stmt\VirtualExpression;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualIdentifier;
use Psalm\Plugin\EventHandler\Event\AfterClassLikeAnalysisEvent;
use Psalm\StatementsSource;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TVoid;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_filter;
use function array_keys;
use function array_map;
use function array_merge;
use function array_pop;
use function array_values;
use function assert;
use function count;
use function explode;
use function implode;
use function in_array;
use function is_int;
use function is_string;
use function preg_match;
use function preg_replace;
use function reset;
use function str_replace;
use function strtolower;
use function substr;
/**
 * @internal
 */
class ClassAnalyzer extends \Psalm\Internal\Analyzer\ClassLikeAnalyzer
{
    /**
     * @var array<string, Union>
     */
    public array $inferred_property_types = [];
    /**
     * @param PhpParser\Node\Stmt\Class_|PhpParser\Node\Stmt\Enum_ $class
     */
    public function __construct(PhpParser\Node\Stmt $class, \Psalm\Internal\Analyzer\SourceAnalyzer $source, ?string $fq_class_name)
    {
        if (!$fq_class_name) {
            if (!$class instanceof PhpParser\Node\Stmt\Class_) {
                throw new UnexpectedValueException('Anonymous enums are not allowed');
            }
            $fq_class_name = self::getAnonymousClassName($class, $source->getFilePath());
        }
        parent::__construct($class, $source, $fq_class_name);
        if ($this->class instanceof PhpParser\Node\Stmt\Class_ && $this->class->extends) {
            $this->parent_fq_class_name = self::getFQCLNFromNameObject($this->class->extends, $this->source->getAliases());
        }
    }
    /** @return non-empty-string */
    public static function getAnonymousClassName(PhpParser\Node\Stmt\Class_ $class, string $file_path) : string
    {
        return preg_replace('/[^A-Za-z0-9]/', '_', $file_path) . '_' . $class->getLine() . '_' . (int) $class->getAttribute('startFilePos');
    }
    public function analyze(?Context $class_context = null, ?Context $global_context = null) : void
    {
        $class = $this->class;
        if (!$class instanceof PhpParser\Node\Stmt\Class_ && !$class instanceof PhpParser\Node\Stmt\Enum_) {
            throw new LogicException('Something went badly wrong');
        }
        $fq_class_name = $class_context && $class_context->self ? $class_context->self : $this->fq_class_name;
        $storage = $this->storage;
        if ($storage->has_visitor_issues) {
            return;
        }
        if ($class->name && (preg_match('/(^|\\\\)(int|float|bool|string|void|null|false|true|object|mixed)$/i', $fq_class_name) || strtolower($fq_class_name) === 'resource')) {
            $class_name_parts = explode('\\', $fq_class_name);
            $class_name = array_pop($class_name_parts);
            IssueBuffer::maybeAdd(new ReservedWord($class_name . ' is a reserved word', new CodeLocation($this, $class->name, null, \true), $class_name), $storage->suppressed_issues + $this->getSuppressedIssues());
            return;
        }
        $project_analyzer = $this->file_analyzer->project_analyzer;
        $codebase = $this->getCodebase();
        if ($codebase->alter_code && $class->name && $codebase->classes_to_move) {
            if (isset($codebase->classes_to_move[strtolower($this->fq_class_name)])) {
                $destination_class = $codebase->classes_to_move[strtolower($this->fq_class_name)];
                $source_class_parts = explode('\\', $this->fq_class_name);
                $destination_class_parts = explode('\\', $destination_class);
                array_pop($source_class_parts);
                array_pop($destination_class_parts);
                $source_ns = implode('\\', $source_class_parts);
                $destination_ns = implode('\\', $destination_class_parts);
                if (strtolower($source_ns) !== strtolower($destination_ns)) {
                    if ($storage->namespace_name_location) {
                        $bounds = $storage->namespace_name_location->getSelectionBounds();
                        $file_manipulations = [new FileManipulation($bounds[0], $bounds[1], $destination_ns)];
                        FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
                    } elseif (!$source_ns) {
                        $first_statement_pos = $this->getFileAnalyzer()->getFirstStatementOffset();
                        if ($first_statement_pos === -1) {
                            $first_statement_pos = (int) $class->getAttribute('startFilePos');
                        }
                        $file_manipulations = [new FileManipulation($first_statement_pos, $first_statement_pos, 'namespace ' . $destination_ns . ';' . "\n\n", \true)];
                        FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
                    }
                }
            }
            $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $this, $class->name, $this->fq_class_name, null);
        }
        foreach ($storage->docblock_issues as $docblock_issue) {
            IssueBuffer::maybeAdd($docblock_issue);
        }
        $classlike_storage_provider = $codebase->classlike_storage_provider;
        $parent_fq_class_name = $this->parent_fq_class_name;
        if ($class instanceof PhpParser\Node\Stmt\Class_ && $class->extends && $parent_fq_class_name) {
            $this->checkParentClass($class, $class->extends, $fq_class_name, $parent_fq_class_name, $storage, $codebase, $class_context);
        }
        if ($storage->template_types) {
            foreach ($storage->template_types as $param_name => $_) {
                $fq_classlike_name = Type::getFQCLNFromString($param_name, $this->getAliases());
                if ($codebase->classOrInterfaceExists($fq_classlike_name)) {
                    IssueBuffer::maybeAdd(new ReservedWord('Cannot use ' . $param_name . ' as template name since the class already exists', new CodeLocation($this, $this->class), 'resource'), $this->getSuppressedIssues());
                }
            }
        }
        if (($storage->templatedMixins || $storage->namedMixins) && $storage->mixin_declaring_fqcln === $storage->name) {
            /** @var non-empty-array<int, TTemplateParam|TNamedObject> $mixins */
            $mixins = array_merge($storage->templatedMixins, $storage->namedMixins);
            $union = new Union($mixins);
            $static_self = new TNamedObject($storage->name, \true);
            $union = TypeExpander::expandUnion($codebase, $union, $storage->name, $static_self, null);
            /** @psalm-suppress UnusedMethodCall This call actually has the side effect of creating issues */
            $union->check($this, new CodeLocation($this, $class->name ?: $class, null, \true), $this->getSuppressedIssues());
        }
        if ($storage->template_extended_params) {
            foreach ($storage->template_extended_params as $type_map) {
                foreach ($type_map as $atomic_type) {
                    /** @psalm-suppress UnusedMethodCall This call actually has the side effect of creating issues */
                    $atomic_type->check($this, new CodeLocation($this, $class->name ?: $class, null, \true), $this->getSuppressedIssues());
                }
            }
        }
        if (!$class_context) {
            $class_context = new Context($this->fq_class_name);
            $class_context->parent = $parent_fq_class_name;
        }
        if ($global_context) {
            $class_context->strict_types = $global_context->strict_types;
        }
        if ($this->checkImplementedInterfaces($class_context, $class, $codebase, $fq_class_name, $storage) === \false) {
            return;
        }
        if ($storage->invalid_dependencies) {
            return;
        }
        if ($this->leftover_stmts) {
            (new \Psalm\Internal\Analyzer\StatementsAnalyzer($this, new NodeDataProvider()))->analyze($this->leftover_stmts, $class_context);
        }
        if (!$storage->abstract) {
            foreach ($storage->declaring_method_ids as $declaring_method_id) {
                $method_storage = $codebase->methods->getStorage($declaring_method_id);
                $declaring_class_name = $declaring_method_id->fq_class_name;
                $method_name_lc = $declaring_method_id->method_name;
                if ($method_storage->abstract) {
                    if (IssueBuffer::accepts(new UnimplementedAbstractMethod('Method ' . $method_name_lc . ' is not defined on class ' . $this->fq_class_name . ', defined abstract in ' . $declaring_class_name, new CodeLocation($this, $class->name ?? $class, $class_context->include_location, \true)), $storage->suppressed_issues + $this->getSuppressedIssues())) {
                        return;
                    }
                }
            }
        }
        \Psalm\Internal\Analyzer\AttributesAnalyzer::analyze($this, $class_context, $storage, $class->attrGroups, \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_CLASS, $storage->suppressed_issues + $this->getSuppressedIssues());
        self::addContextProperties($this, $storage, $class_context, $this->fq_class_name, $this->parent_fq_class_name, $class->stmts);
        $constructor_analyzer = null;
        $member_stmts = [];
        foreach ($class->stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
                $method_analyzer = $this->analyzeClassMethod($stmt, $storage, $this, $class_context, $global_context);
                if ($stmt->name->name === '__construct') {
                    $constructor_analyzer = $method_analyzer;
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\TraitUse) {
                if ($this->analyzeTraitUse($this->source->getAliases(), $stmt, $project_analyzer, $storage, $class_context, $global_context, $constructor_analyzer) === \false) {
                    return;
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Property) {
                foreach ($stmt->props as $prop) {
                    if ($storage->is_enum) {
                        IssueBuffer::maybeAdd(new NoEnumProperties('Enums cannot have properties', new CodeLocation($this, $prop), $fq_class_name));
                        continue;
                    }
                    if ($prop->default) {
                        $member_stmts[] = $stmt;
                    }
                    if ($codebase->alter_code) {
                        $property_id = strtolower($this->fq_class_name) . '::$' . $prop->name;
                        $property_storage = $codebase->properties->getStorage($property_id);
                        if ($property_storage->type && $property_storage->type_location && $property_storage->type_location !== $property_storage->signature_type_location) {
                            $replace_type = TypeExpander::expandUnion($codebase, $property_storage->type, $this->getFQCLN(), $this->getFQCLN(), $this->getParentFQCLN());
                            $codebase->classlikes->handleDocblockTypeInMigration($codebase, $this, $replace_type, $property_storage->type_location, null);
                        }
                        foreach ($codebase->properties_to_rename as $original_property_id => $new_property_name) {
                            if ($property_id === $original_property_id) {
                                $file_manipulations = [new FileManipulation((int) $prop->name->getAttribute('startFilePos'), (int) $prop->name->getAttribute('endFilePos') + 1, '$' . $new_property_name)];
                                FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
                            }
                        }
                    }
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\ClassConst) {
                $member_stmts[] = $stmt;
                foreach ($stmt->consts as $const) {
                    if ($const->name->toLowerString() === 'class') {
                        IssueBuffer::maybeAdd(new ReservedWord('A class constant cannot be named \'class\'', new CodeLocation($this, $this->class), $this->fq_class_name));
                    }
                    $const_id = strtolower($this->fq_class_name) . '::' . $const->name;
                    foreach ($codebase->class_constants_to_rename as $original_const_id => $new_const_name) {
                        if ($const_id === $original_const_id) {
                            $file_manipulations = [new FileManipulation((int) $const->name->getAttribute('startFilePos'), (int) $const->name->getAttribute('endFilePos') + 1, $new_const_name)];
                            FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
                        }
                    }
                }
            }
        }
        $statements_analyzer = new \Psalm\Internal\Analyzer\StatementsAnalyzer($this, new NodeDataProvider());
        $statements_analyzer->analyze($member_stmts, $class_context, $global_context, \true);
        ClassConstAnalyzer::analyze($storage, $this->getCodebase());
        $config = Config::getInstance();
        if ($class instanceof PhpParser\Node\Stmt\Class_) {
            $this->checkPropertyInitialization($codebase, $config, $storage, $class_context, $global_context, $constructor_analyzer);
        }
        if ($class instanceof PhpParser\Node\Stmt\Enum_) {
            $this->checkEnum();
        }
        foreach ($class->stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\Property) {
                $this->analyzeProperty($this, $stmt, $class_context);
            } elseif ($stmt instanceof PhpParser\Node\Stmt\TraitUse) {
                foreach ($stmt->traits as $trait) {
                    $fq_trait_name = self::getFQCLNFromNameObject($trait, $this->source->getAliases());
                    try {
                        $trait_file_analyzer = $project_analyzer->getFileAnalyzerForClassLike($fq_trait_name);
                    } catch (Exception $e) {
                        continue;
                    }
                    $trait_storage = $codebase->classlike_storage_provider->get($fq_trait_name);
                    $trait_node = $codebase->classlikes->getTraitNode($fq_trait_name);
                    $trait_aliases = $trait_storage->aliases;
                    if ($trait_aliases === null) {
                        continue;
                    }
                    $trait_analyzer = new \Psalm\Internal\Analyzer\TraitAnalyzer($trait_node, $trait_file_analyzer, $fq_trait_name, $trait_aliases);
                    $fq_trait_name_lc = strtolower($fq_trait_name);
                    $this->checkTemplateParams($codebase, $storage, $trait_storage, new CodeLocation($this, $trait), $storage->template_type_uses_count[$fq_trait_name_lc] ?? 0);
                    foreach ($trait_node->stmts as $trait_stmt) {
                        if ($trait_stmt instanceof PhpParser\Node\Stmt\Property) {
                            $this->analyzeProperty($trait_analyzer, $trait_stmt, $class_context);
                        }
                    }
                    $trait_file_analyzer->clearSourceBeforeDestruction();
                }
            }
        }
        $pseudo_methods = $storage->pseudo_methods + $storage->pseudo_static_methods;
        foreach ($pseudo_methods as $pseudo_method_name => $pseudo_method_storage) {
            $pseudo_method_id = new MethodIdentifier($this->fq_class_name, $pseudo_method_name);
            $overridden_method_ids = $codebase->methods->getOverriddenMethodIds($pseudo_method_id);
            if ($overridden_method_ids && $pseudo_method_name !== '__construct' && $pseudo_method_storage->location) {
                foreach ($overridden_method_ids as $overridden_method_id) {
                    $parent_method_storage = $codebase->methods->getStorage($overridden_method_id);
                    $overridden_fq_class_name = $overridden_method_id->fq_class_name;
                    $parent_storage = $classlike_storage_provider->get($overridden_fq_class_name);
                    \Psalm\Internal\Analyzer\MethodComparator::compare($codebase, null, $storage, $parent_storage, $pseudo_method_storage, $parent_method_storage, $this->fq_class_name, $pseudo_method_storage->visibility ?: 0, $storage->location ?: $pseudo_method_storage->location, $storage->suppressed_issues, \true, \false);
                }
            }
        }
        $event = new AfterClassLikeAnalysisEvent($class, $storage, $this, $codebase, []);
        if ($codebase->config->eventDispatcher->dispatchAfterClassLikeAnalysis($event) === \false) {
            return;
        }
        $file_manipulations = $event->getFileReplacements();
        if ($file_manipulations) {
            FileManipulationBuffer::add($this->getFilePath(), $file_manipulations);
        }
    }
    public static function addContextProperties(StatementsSource $statements_source, ClassLikeStorage $storage, Context $class_context, string $fq_class_name, ?string $parent_fq_class_name, array $stmts = []) : void
    {
        $codebase = $statements_source->getCodebase();
        foreach ($storage->appearing_property_ids as $property_name => $appearing_property_id) {
            $property_class_name = $codebase->properties->getDeclaringClassForProperty($appearing_property_id, \true);
            if ($property_class_name === null) {
                continue;
            }
            $property_class_storage = $codebase->classlike_storage_provider->get($property_class_name);
            $property_storage = $property_class_storage->properties[$property_name];
            if (isset($storage->overridden_property_ids[$property_name])) {
                foreach ($storage->overridden_property_ids[$property_name] as $overridden_property_id) {
                    [$guide_class_name] = explode('::$', $overridden_property_id);
                    $guide_class_storage = $codebase->classlike_storage_provider->get($guide_class_name);
                    $guide_property_storage = $guide_class_storage->properties[$property_name];
                    if ($property_storage->visibility > $guide_property_storage->visibility && $property_storage->location) {
                        IssueBuffer::maybeAdd(new OverriddenPropertyAccess('Property ' . $fq_class_name . '::$' . $property_name . ' has different access level than ' . $storage->name . '::$' . $property_name, $property_storage->location));
                    }
                    if (($property_storage->signature_type && !$guide_property_storage->signature_type || !$property_storage->signature_type && $guide_property_storage->signature_type || $property_storage->signature_type && !$property_storage->signature_type->equals($guide_property_storage->signature_type)) && $property_storage->location) {
                        IssueBuffer::maybeAdd(new NonInvariantPropertyType('Property ' . $fq_class_name . '::$' . $property_name . ' has type ' . ($property_storage->signature_type ? $property_storage->signature_type->getId() : '<empty>') . ", not invariant with " . $guide_class_name . '::$' . $property_name . ' of type ' . ($guide_property_storage->signature_type ? $guide_property_storage->signature_type->getId() : '<empty>'), $property_storage->location), $property_storage->suppressed_issues);
                    }
                    if ($property_storage->type === null) {
                        // Property type not set, no need to check for docblock invariance
                        continue;
                    }
                    $property_type = $property_storage->type;
                    $guide_property_type = $guide_property_storage->type ?? Type::getMixed();
                    // Set upper bounds for all templates
                    $lower_bounds = [];
                    $extended_templates = $storage->template_extended_params ?? [];
                    foreach ($extended_templates as $et_name => $et_array) {
                        foreach ($et_array as $et_class_name => $extended_template) {
                            if (!isset($lower_bounds[$et_class_name][$et_name])) {
                                $lower_bounds[$et_class_name][$et_name] = $extended_template;
                            }
                        }
                    }
                    // Get actual types used for templates (to support @template-covariant)
                    $template_standins = new TemplateResult($lower_bounds, []);
                    TemplateStandinTypeReplacer::fillTemplateResult($guide_property_type, $template_standins, $codebase, null, $property_type);
                    // Iterate over parent classes to find template-covariants, and replace the upper bound with the
                    // standin. Since @template-covariant allows child classes, we want to use the standin type
                    // instead of the template extended type.
                    $parent_class = $storage->parent_class;
                    while ($parent_class !== null) {
                        $parent_storage = $codebase->classlike_storage_provider->get($parent_class);
                        foreach ($parent_storage->template_covariants ?? [] as $pt_offset => $covariant) {
                            if ($covariant) {
                                // If template_covariants is set template_types should also be set
                                assert($parent_storage->template_types !== null);
                                $pt_name = array_keys($parent_storage->template_types)[$pt_offset];
                                if (isset($template_standins->lower_bounds[$pt_name][$parent_class])) {
                                    $lower_bounds[$pt_name][$parent_class] = TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($template_standins->lower_bounds[$pt_name][$parent_class], $codebase);
                                }
                            }
                        }
                        $parent_class = $parent_storage->parent_class;
                    }
                    $template_result = new TemplateResult([], $lower_bounds);
                    $guide_property_type = TemplateInferredTypeReplacer::replace($guide_property_type, $template_result, $codebase);
                    $property_type = TemplateInferredTypeReplacer::replace($property_type, $template_result, $codebase);
                    if ($property_storage->location && !$property_type->equals($guide_property_type, \false) && $guide_class_storage->user_defined) {
                        IssueBuffer::maybeAdd(new NonInvariantDocblockPropertyType('Property ' . $fq_class_name . '::$' . $property_name . ' has type ' . $property_type->getId() . ", not invariant with " . $guide_class_name . '::$' . $property_name . ' of type ' . $guide_property_type->getId(), $property_storage->location), $property_storage->suppressed_issues);
                    }
                }
            }
            if ($property_storage->type) {
                $property_type = $property_storage->type;
                if (!$property_type->isMixed() && !$property_storage->is_promoted && !$property_storage->has_default && !($property_type->isNullable() && $property_type->from_docblock)) {
                    $property_type = $property_type->setProperties(['initialized' => \false, 'from_property' => \true, 'from_static_property' => $property_storage->is_static === \true]);
                }
            } else {
                if (!$property_storage->has_default && !$property_storage->is_promoted) {
                    $property_type = new Union([new TMixed()], ['initialized' => \false, 'from_property' => \true, 'from_static_property' => $property_storage->is_static === \true]);
                } else {
                    $property_type = Type::getMixed();
                }
            }
            $property_type_location = $property_storage->type_location;
            $fleshed_out_type = !$property_type->isMixed() ? TypeExpander::expandUnion($codebase, $property_type, $fq_class_name, $fq_class_name, $parent_fq_class_name, \true, \false, $storage->final) : $property_type;
            $class_template_params = ClassTemplateParamCollector::collect($codebase, $property_class_storage, $storage, null, new TNamedObject($fq_class_name), \true);
            if ($class_template_params) {
                $this_object_type = self::getThisObjectType($storage, $fq_class_name);
                if (!$this_object_type instanceof TGenericObject) {
                    $type_params = [];
                    foreach ($class_template_params as $type_map) {
                        $type_params[] = array_values($type_map)[0];
                    }
                    $this_object_type = new TGenericObject($this_object_type->value, $type_params);
                }
                $fleshed_out_type = AtomicPropertyFetchAnalyzer::localizePropertyType($codebase, $fleshed_out_type, $this_object_type, $storage, $property_class_storage);
            }
            if ($property_type_location && !$fleshed_out_type->isMixed()) {
                $stmt = array_filter($stmts, static fn($stmt): bool => $stmt instanceof PhpParser\Node\Stmt\Property && isset($stmt->props[0]->name->name) && $stmt->props[0]->name->name === $property_name);
                $suppressed = [];
                if (count($stmt) > 0) {
                    $stmt = array_pop($stmt);
                    $docComment = $stmt->getDocComment();
                    if ($docComment) {
                        try {
                            $docBlock = DocComment::parsePreservingLength($docComment);
                            $suppressed = $docBlock->tags['psalm-suppress'] ?? [];
                        } catch (DocblockParseException $e) {
                            // do nothing to keep original behavior
                        }
                    }
                }
                /** @psalm-suppress UnusedMethodCall This call actually has the side effect of creating issues */
                $fleshed_out_type->check($statements_source, $property_type_location, $storage->suppressed_issues + $statements_source->getSuppressedIssues() + $suppressed, [], \false);
                if ($property_storage->signature_type) {
                    $union_comparison_result = new TypeComparisonResult();
                    if (!UnionTypeComparator::isContainedBy($codebase, $fleshed_out_type, $property_storage->signature_type, \false, \false, $union_comparison_result) && !$union_comparison_result->type_coerced_from_mixed) {
                        IssueBuffer::maybeAdd(new MismatchingDocblockPropertyType('Parameter ' . $property_class_name . '::$' . $property_name . ' has wrong type \'' . $fleshed_out_type . '\', should be \'' . $property_storage->signature_type . '\'', $property_type_location));
                    }
                }
            }
            if ($property_storage->is_static) {
                $property_id = $fq_class_name . '::$' . $property_name;
                $class_context->vars_in_scope[$property_id] = $fleshed_out_type;
            } else {
                $class_context->vars_in_scope['$this->' . $property_name] = $fleshed_out_type;
            }
        }
        foreach ($storage->pseudo_property_get_types as $property_name => $property_type) {
            $property_name = substr($property_name, 1);
            if (isset($class_context->vars_in_scope['$this->' . $property_name])) {
                $fleshed_out_type = !$property_type->isMixed() ? TypeExpander::expandUnion($codebase, $property_type, $fq_class_name, $fq_class_name, $parent_fq_class_name) : $property_type;
                $class_context->vars_in_scope['$this->' . $property_name] = $fleshed_out_type;
            }
        }
    }
    private function checkPropertyInitialization(Codebase $codebase, Config $config, ClassLikeStorage $storage, Context $class_context, ?Context $global_context = null, ?\Psalm\Internal\Analyzer\MethodAnalyzer $constructor_analyzer = null) : void
    {
        if (!$config->reportIssueInFile('PropertyNotSetInConstructor', $this->getFilePath())) {
            return;
        }
        if (!isset($storage->declaring_method_ids['__construct']) && !$config->reportIssueInFile('MissingConstructor', $this->getFilePath())) {
            return;
        }
        $fq_class_name = $class_context->self ?: $this->fq_class_name;
        $fq_class_name_lc = strtolower($fq_class_name);
        $included_file_path = $this->getFilePath();
        $method_already_analyzed = $codebase->analyzer->isMethodAlreadyAnalyzed($included_file_path, $fq_class_name_lc . '::__construct', \true);
        if ($method_already_analyzed && !$codebase->diff_methods) {
            // this can happen when re-analysing a class that has been include()d inside another
            return;
        }
        /** @var PhpParser\Node\Stmt\Class_ */
        $class = $this->class;
        $classlike_storage_provider = $codebase->classlike_storage_provider;
        $class_storage = $classlike_storage_provider->get($fq_class_name_lc);
        $constructor_appearing_fqcln = $fq_class_name_lc;
        $uninitialized_variables = [];
        $uninitialized_properties = [];
        $uninitialized_typed_properties = [];
        $uninitialized_private_properties = \false;
        foreach ($storage->appearing_property_ids as $property_name => $appearing_property_id) {
            $property_class_name = $codebase->properties->getDeclaringClassForProperty($appearing_property_id, \true);
            if ($property_class_name === null) {
                continue;
            }
            $property_class_storage = $classlike_storage_provider->get($property_class_name);
            $property = $property_class_storage->properties[$property_name];
            $property_is_initialized = isset($property_class_storage->initialized_properties[$property_name]);
            if ($property->is_static) {
                continue;
            }
            if ($property->has_default || $property_is_initialized) {
                continue;
            }
            if ($property->type && $property->type->from_docblock && $property->type->isNullable()) {
                continue;
            }
            if ($codebase->diff_methods && $method_already_analyzed && $property->location) {
                [$start, $end] = $property->location->getSelectionBounds();
                $existing_issues = $codebase->analyzer->getExistingIssuesForFile($this->getFilePath(), $start, $end, 'PropertyNotSetInConstructor');
                if ($existing_issues) {
                    IssueBuffer::addIssues([$this->getFilePath() => $existing_issues]);
                    continue;
                }
            }
            if ($property->location) {
                $codebase->analyzer->removeExistingDataForFile($this->getFilePath(), $property->location->raw_file_start, $property->location->raw_file_end, 'PropertyNotSetInConstructor');
            }
            $codebase->file_reference_provider->addMethodReferenceToMissingClassMember($fq_class_name_lc . '::__construct', strtolower($property_class_name) . '::$' . $property_name);
            if ($property->visibility === \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                $uninitialized_private_properties = \true;
            }
            $uninitialized_variables[] = '$this->' . $property_name;
            $uninitialized_properties[$property_class_name . '::$' . $property_name] = $property;
            if ($property->type && !$property->type->isMixed()) {
                $uninitialized_typed_properties[$property_class_name . '::$' . $property_name] = $property;
            }
        }
        if (!$uninitialized_properties) {
            return;
        }
        if (!$storage->abstract && !$constructor_analyzer && isset($storage->declaring_method_ids['__construct']) && isset($storage->appearing_method_ids['__construct']) && $class->extends) {
            $constructor_declaring_fqcln = $storage->declaring_method_ids['__construct']->fq_class_name;
            $constructor_appearing_fqcln = $storage->appearing_method_ids['__construct']->fq_class_name;
            $constructor_class_storage = $classlike_storage_provider->get($constructor_declaring_fqcln);
            // ignore oldstyle constructors and classes without any declared properties
            if ($constructor_class_storage->user_defined && !$constructor_class_storage->stubbed && isset($constructor_class_storage->methods['__construct'])) {
                $constructor_storage = $constructor_class_storage->methods['__construct'];
                $fake_constructor_params = array_map(static function (FunctionLikeParameter $param) : PhpParser\Node\Param {
                    $fake_param = new PhpParser\Builder\Param($param->name);
                    if ($param->signature_type) {
                        $fake_param->setType((string) $param->signature_type);
                    }
                    $node = $fake_param->getNode();
                    $attributes = $param->location ? ['startFilePos' => $param->location->raw_file_start, 'endFilePos' => $param->location->raw_file_end, 'startLine' => $param->location->raw_line_number] : [];
                    $node->setAttributes($attributes);
                    return $node;
                }, $constructor_storage->params);
                $fake_constructor_stmt_args = array_map(static function (FunctionLikeParameter $param) : PhpParser\Node\Arg {
                    $attributes = $param->location ? ['startFilePos' => $param->location->raw_file_start, 'endFilePos' => $param->location->raw_file_end, 'startLine' => $param->location->raw_line_number] : [];
                    return new VirtualArg(new VirtualVariable($param->name, $attributes), \false, $param->is_variadic, $attributes);
                }, $constructor_storage->params);
                $fake_constructor_attributes = ['startLine' => $class->extends->getLine(), 'startFilePos' => $class->extends->getAttribute('startFilePos'), 'endFilePos' => $class->extends->getAttribute('endFilePos')];
                $fake_call_attributes = $fake_constructor_attributes + ['comments' => [new PhpParser\Comment\Doc('/** @psalm-suppress InaccessibleMethod */', $class->extends->getLine(), (int) $class->extends->getAttribute('startFilePos'))]];
                $fake_constructor_stmts = [new VirtualExpression(new VirtualStaticCall(new VirtualFullyQualified($constructor_declaring_fqcln), new VirtualIdentifier('__construct', $fake_constructor_attributes), $fake_constructor_stmt_args, $fake_call_attributes), $fake_call_attributes)];
                $fake_stmt = new VirtualClassMethod(new VirtualIdentifier('__construct'), ['type' => PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC, 'params' => $fake_constructor_params, 'stmts' => $fake_constructor_stmts], $fake_constructor_attributes);
                $codebase->analyzer->disableMixedCounts();
                $was_collecting_initializations = $class_context->collect_initializations;
                $class_context->collect_initializations = \true;
                $class_context->collect_nonprivate_initializations = !$uninitialized_private_properties;
                $constructor_analyzer = $this->analyzeClassMethod($fake_stmt, $storage, $this, $class_context, $global_context, \true);
                $class_context->collect_initializations = $was_collecting_initializations;
                $codebase->analyzer->enableMixedCounts();
            }
        }
        if ($constructor_analyzer) {
            $method_context = clone $class_context;
            $method_context->collect_initializations = \true;
            $method_context->collect_nonprivate_initializations = !$uninitialized_private_properties;
            $method_context->self = $fq_class_name;
            $this_atomic_object_type = new TNamedObject($fq_class_name, !$storage->final);
            $method_context->vars_in_scope['$this'] = new Union([$this_atomic_object_type]);
            $method_context->vars_possibly_in_scope['$this'] = \true;
            $method_context->calling_method_id = strtolower($fq_class_name) . '::__construct';
            $constructor_analyzer->analyze($method_context, new NodeDataProvider(), $global_context, \true);
            foreach ($uninitialized_properties as $property_id => $property_storage) {
                [, $property_name] = explode('::$', $property_id);
                if (!isset($method_context->vars_in_scope['$this->' . $property_name])) {
                    $end_type = new Union([new TVoid()], ['initialized' => \false]);
                } else {
                    $end_type = $method_context->vars_in_scope['$this->' . $property_name];
                }
                $constructor_class_property_storage = $property_storage;
                $error_location = $property_storage->location;
                if ($storage->declaring_property_ids[$property_name] !== $fq_class_name) {
                    $error_location = $storage->location ?: $storage->stmt_location;
                }
                if ($fq_class_name_lc !== $constructor_appearing_fqcln && $property_storage->visibility === \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                    $a_class_storage = $classlike_storage_provider->get($end_type->initialized_class ?: $constructor_appearing_fqcln);
                    if (!isset($a_class_storage->declaring_property_ids[$property_name])) {
                        $constructor_class_property_storage = null;
                    } else {
                        $declaring_property_class = $a_class_storage->declaring_property_ids[$property_name];
                        $constructor_class_property_storage = $classlike_storage_provider->get($declaring_property_class)->properties[$property_name];
                    }
                }
                if ($property_storage->location && $error_location && (!$end_type->initialized || $property_storage !== $constructor_class_property_storage)) {
                    if ($property_storage->type) {
                        $expected_visibility = $uninitialized_private_properties ? 'private or final ' : '';
                        IssueBuffer::maybeAdd(new PropertyNotSetInConstructor('Property ' . $class_storage->name . '::$' . $property_name . ' is not defined in constructor of ' . $this->fq_class_name . ' or in any ' . $expected_visibility . 'methods called in the constructor', $error_location, $property_id), $storage->suppressed_issues + $this->getSuppressedIssues());
                    } elseif (!$property_storage->has_default) {
                        if (isset($this->inferred_property_types[$property_name])) {
                            $this->inferred_property_types[$property_name] = $this->inferred_property_types[$property_name]->getBuilder()->addType(new TNull())->setFromDocblock(\true)->freeze();
                        }
                    }
                }
            }
            $codebase->analyzer->setAnalyzedMethod($included_file_path, $fq_class_name_lc . '::__construct', \true);
            return;
        }
        if (!$storage->abstract && $uninitialized_typed_properties) {
            foreach ($uninitialized_typed_properties as $id => $uninitialized_property) {
                if ($uninitialized_property->location) {
                    IssueBuffer::maybeAdd(new MissingConstructor($class_storage->name . ' has an uninitialized property ' . $id . ', but no constructor', $uninitialized_property->location, $class_storage->name . '::' . $uninitialized_variables[0]), $storage->suppressed_issues + $this->getSuppressedIssues());
                }
            }
        }
    }
    /**
     * @return false|null
     */
    private function analyzeTraitUse(Aliases $aliases, PhpParser\Node\Stmt\TraitUse $stmt, \Psalm\Internal\Analyzer\ProjectAnalyzer $project_analyzer, ClassLikeStorage $storage, Context $class_context, ?Context $global_context = null, ?\Psalm\Internal\Analyzer\MethodAnalyzer &$constructor_analyzer = null, ?\Psalm\Internal\Analyzer\TraitAnalyzer $previous_trait_analyzer = null) : ?bool
    {
        $codebase = $this->getCodebase();
        $previous_context_include_location = $class_context->include_location;
        foreach ($stmt->traits as $trait_name) {
            $trait_location = new CodeLocation($this, $trait_name, null, \true);
            $class_context->include_location = new CodeLocation($this, $trait_name, null, \true);
            $fq_trait_name = self::getFQCLNFromNameObject($trait_name, $aliases);
            if (!$codebase->classlikes->hasFullyQualifiedTraitName($fq_trait_name, $trait_location)) {
                IssueBuffer::maybeAdd(new UndefinedTrait('Trait ' . $fq_trait_name . ' does not exist', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name)), $storage->suppressed_issues + $this->getSuppressedIssues());
                return \false;
            }
            if (!$codebase->traitHasCorrectCasing($fq_trait_name)) {
                if (IssueBuffer::accepts(new UndefinedTrait('Trait ' . $fq_trait_name . ' has wrong casing', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name)), $storage->suppressed_issues + $this->getSuppressedIssues())) {
                    return \false;
                }
                continue;
            }
            $fq_trait_name_resolved = $codebase->classlikes->getUnAliasedName($fq_trait_name);
            $trait_storage = $codebase->classlike_storage_provider->get($fq_trait_name_resolved);
            if ($trait_storage->deprecated) {
                IssueBuffer::maybeAdd(new DeprecatedTrait('Trait ' . $fq_trait_name . ' is deprecated', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name)), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if ($trait_storage->extension_requirement !== null) {
                $extension_requirement = $codebase->classlikes->getUnAliasedName($trait_storage->extension_requirement);
                $extensionRequirementMet = in_array($extension_requirement, $storage->parent_classes);
                if (!$extensionRequirementMet) {
                    IssueBuffer::maybeAdd(new ExtensionRequirementViolation($fq_trait_name . ' requires using class to extend ' . $extension_requirement . ', but ' . $storage->name . ' does not', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name)), $storage->suppressed_issues + $this->getSuppressedIssues());
                }
            }
            foreach ($trait_storage->implementation_requirements as $implementation_requirement) {
                $implementation_requirement = $codebase->classlikes->getUnAliasedName($implementation_requirement);
                $implementationRequirementMet = in_array($implementation_requirement, $storage->class_implements);
                if (!$implementationRequirementMet) {
                    IssueBuffer::maybeAdd(new ImplementationRequirementViolation($fq_trait_name . ' requires using class to implement ' . $implementation_requirement . ', but ' . $storage->name . ' does not', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name)), $storage->suppressed_issues + $this->getSuppressedIssues());
                }
            }
            if ($storage->mutation_free && !$trait_storage->mutation_free) {
                IssueBuffer::maybeAdd(new MutableDependency($storage->name . ' is marked @psalm-immutable but ' . $fq_trait_name . ' is not', new CodeLocation($previous_trait_analyzer ?? $this, $trait_name)), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            $trait_file_analyzer = $project_analyzer->getFileAnalyzerForClassLike($fq_trait_name_resolved);
            $trait_node = $codebase->classlikes->getTraitNode($fq_trait_name_resolved);
            $trait_aliases = $trait_storage->aliases;
            if ($trait_aliases === null) {
                continue;
            }
            $trait_analyzer = new \Psalm\Internal\Analyzer\TraitAnalyzer($trait_node, $trait_file_analyzer, $fq_trait_name_resolved, $trait_aliases);
            foreach ($trait_node->stmts as $trait_stmt) {
                if ($trait_stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
                    $trait_method_analyzer = $this->analyzeClassMethod($trait_stmt, $storage, $trait_analyzer, $class_context, $global_context);
                    if ($trait_stmt->name->name === '__construct') {
                        $constructor_analyzer = $trait_method_analyzer;
                    }
                } elseif ($trait_stmt instanceof PhpParser\Node\Stmt\TraitUse) {
                    if ($this->analyzeTraitUse($trait_aliases, $trait_stmt, $project_analyzer, $storage, $class_context, $global_context, $constructor_analyzer, $trait_analyzer) === \false) {
                        return \false;
                    }
                }
            }
            $trait_file_analyzer->clearSourceBeforeDestruction();
        }
        $class_context->include_location = $previous_context_include_location;
        return null;
    }
    private function analyzeProperty(\Psalm\Internal\Analyzer\SourceAnalyzer $source, PhpParser\Node\Stmt\Property $stmt, Context $context) : void
    {
        $fq_class_name = $source->getFQCLN();
        $property_name = $stmt->props[0]->name->name;
        $codebase = $this->getCodebase();
        $property_id = $fq_class_name . '::$' . $property_name;
        $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($property_id, \true);
        if (!$declaring_property_class) {
            return;
        }
        $fq_class_name = $declaring_property_class;
        // gets inherited property type
        $class_property_type = $codebase->properties->getPropertyType($property_id, \false, $source, $context);
        $class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
        $property_storage = $class_storage->properties[$property_name];
        \Psalm\Internal\Analyzer\AttributesAnalyzer::analyze($source, $context, $property_storage, $stmt->attrGroups, \Psalm\Internal\Analyzer\AttributesAnalyzer::TARGET_PROPERTY, $property_storage->suppressed_issues + $this->getSuppressedIssues());
        if ($class_property_type && ($property_storage->type_location || !$codebase->alter_code)) {
            return;
        }
        $message = 'Property ' . $property_id . ' does not have a declared type';
        $suggested_type = $property_storage->suggested_type;
        if (isset($this->inferred_property_types[$property_name])) {
            $suggested_type = Type::combineUnionTypes($suggested_type, $this->inferred_property_types[$property_name] ?? null, $codebase);
        }
        if ($suggested_type && !$property_storage->has_default && $property_storage->is_static) {
            $suggested_type = $suggested_type->getBuilder()->addType(new TNull())->freeze();
        }
        if ($suggested_type && !$suggested_type->isNull()) {
            $message .= ' - consider ' . str_replace(['<array-key, mixed>', '<never, never>'], '', $suggested_type->getId(\false));
        }
        $project_analyzer = \Psalm\Internal\Analyzer\ProjectAnalyzer::getInstance();
        if ($codebase->alter_code && $source === $this && isset($project_analyzer->getIssuesToFix()['MissingPropertyType']) && !in_array('MissingPropertyType', $this->getSuppressedIssues()) && $suggested_type) {
            if ($suggested_type->hasMixed() || $suggested_type->isNull()) {
                return;
            }
            self::addOrUpdatePropertyType($project_analyzer, $stmt, $suggested_type, $this, $suggested_type->from_docblock);
            return;
        }
        IssueBuffer::maybeAdd(new MissingPropertyType($message, new CodeLocation($source, $stmt->props[0]->name), $property_id), $this->source->getSuppressedIssues() + $property_storage->suppressed_issues);
    }
    private static function addOrUpdatePropertyType(\Psalm\Internal\Analyzer\ProjectAnalyzer $project_analyzer, PhpParser\Node\Stmt\Property $property, Union $inferred_type, StatementsSource $source, bool $docblock_only = \false) : void
    {
        $manipulator = PropertyDocblockManipulator::getForProperty($project_analyzer, $source->getFilePath(), $property);
        $codebase = $project_analyzer->getCodebase();
        $allow_native_type = !$docblock_only && $codebase->analysis_php_version_id >= 70400 && $codebase->allow_backwards_incompatible_changes;
        $manipulator->setType($allow_native_type ? (string) $inferred_type->toPhpString($source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), $codebase->analysis_php_version_id) : null, $inferred_type->toNamespacedString($source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), \false), $inferred_type->toNamespacedString($source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), \true), $inferred_type->canBeFullyExpressedInPhp($codebase->analysis_php_version_id));
    }
    private function analyzeClassMethod(PhpParser\Node\Stmt\ClassMethod $stmt, ClassLikeStorage $class_storage, \Psalm\Internal\Analyzer\SourceAnalyzer $source, Context $class_context, ?Context $global_context = null, bool $is_fake = \false) : ?\Psalm\Internal\Analyzer\MethodAnalyzer
    {
        $config = Config::getInstance();
        if ($stmt->stmts === null && !$stmt->isAbstract()) {
            IssueBuffer::maybeAdd(new ParseError('Non-abstract class method must have statements', new CodeLocation($this, $stmt)));
            return null;
        }
        try {
            $method_analyzer = new \Psalm\Internal\Analyzer\MethodAnalyzer($stmt, $source);
        } catch (UnexpectedValueException $e) {
            IssueBuffer::maybeAdd(new ParseError('Problem loading method: ' . $e->getMessage(), new CodeLocation($this, $stmt)));
            return null;
        }
        $actual_method_id = $method_analyzer->getMethodId();
        $project_analyzer = $source->getProjectAnalyzer();
        $codebase = $source->getCodebase();
        $analyzed_method_id = $actual_method_id;
        $included_file_path = $source->getFilePath();
        if ($class_context->self && strtolower($class_context->self) !== strtolower((string) $source->getFQCLN())) {
            $analyzed_method_id = $method_analyzer->getMethodId($class_context->self);
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($analyzed_method_id);
            if ((string) $actual_method_id !== (string) $declaring_method_id) {
                // the method is an abstract trait method
                $declaring_method_storage = $method_analyzer->getFunctionLikeStorage();
                if (!$declaring_method_storage instanceof MethodStorage) {
                    throw new LogicException('This should never happen');
                }
                if ($declaring_method_id && $declaring_method_storage->abstract) {
                    $implementer_method_storage = $codebase->methods->getStorage($declaring_method_id);
                    $declaring_storage = $codebase->classlike_storage_provider->get($actual_method_id->fq_class_name);
                    \Psalm\Internal\Analyzer\MethodComparator::compare($codebase, null, $class_storage, $declaring_storage, $implementer_method_storage, $declaring_method_storage, $this->fq_class_name, $implementer_method_storage->visibility, new CodeLocation($source, $stmt), $implementer_method_storage->suppressed_issues, \false);
                }
                return null;
            }
        }
        $trait_safe_method_id = strtolower((string) $analyzed_method_id);
        $actual_method_id_str = strtolower((string) $actual_method_id);
        if ($actual_method_id_str !== $trait_safe_method_id) {
            $trait_safe_method_id .= '&' . $actual_method_id_str;
        }
        $method_already_analyzed = $codebase->analyzer->isMethodAlreadyAnalyzed($included_file_path, $trait_safe_method_id);
        $start = (int) $stmt->getAttribute('startFilePos');
        $end = (int) $stmt->getAttribute('endFilePos');
        $comments = $stmt->getComments();
        if ($comments) {
            $start = $comments[0]->getStartFilePos();
        }
        if ($codebase->diff_methods && $method_already_analyzed && !$class_context->collect_initializations && !$class_context->collect_mutations && !$is_fake) {
            $project_analyzer->progress->debug('Skipping analysis of pre-analyzed method ' . $analyzed_method_id . "\n");
            $existing_issues = $codebase->analyzer->getExistingIssuesForFile($source->getFilePath(), $start, $end);
            IssueBuffer::addIssues([$source->getFilePath() => $existing_issues]);
            return $method_analyzer;
        }
        $codebase->analyzer->removeExistingDataForFile($source->getFilePath(), $start, $end);
        $method_context = clone $class_context;
        foreach ($method_context->vars_in_scope as $context_var_id => $context_type) {
            $method_context->vars_in_scope[$context_var_id] = $context_type;
            if ($context_type->from_property && $stmt->name->name !== '__construct') {
                $method_context->vars_in_scope[$context_var_id] = $method_context->vars_in_scope[$context_var_id]->setProperties(['initialized' => \true]);
            }
        }
        $method_context->collect_exceptions = $config->check_for_throws_docblock;
        $type_provider = new NodeDataProvider();
        $method_analyzer->analyze($method_context, $type_provider, $global_context ? clone $global_context : null);
        if ($stmt->name->name !== '__construct' && $config->reportIssueInFile('InvalidReturnType', $source->getFilePath()) && $class_context->self) {
            self::analyzeClassMethodReturnType($stmt, $method_analyzer, $source, $type_provider, $codebase, $class_storage, $class_context->self, $analyzed_method_id, $actual_method_id, $method_context->has_returned);
        }
        if (!$method_already_analyzed && !$class_context->collect_initializations && !$class_context->collect_mutations && !$is_fake) {
            $codebase->analyzer->setAnalyzedMethod($included_file_path, $trait_safe_method_id);
        }
        return $method_analyzer;
    }
    private static function getThisObjectType(ClassLikeStorage $class_storage, string $original_fq_classlike_name) : TNamedObject
    {
        if ($class_storage->template_types) {
            $template_params = [];
            foreach ($class_storage->template_types as $param_name => $template_map) {
                $key = array_keys($template_map)[0];
                $template_params[] = new Union([new TTemplateParam($param_name, reset($template_map), $key)]);
            }
            return new TGenericObject($original_fq_classlike_name, $template_params);
        }
        return new TNamedObject($original_fq_classlike_name);
    }
    public static function analyzeClassMethodReturnType(PhpParser\Node\Stmt\ClassMethod $stmt, \Psalm\Internal\Analyzer\MethodAnalyzer $method_analyzer, \Psalm\Internal\Analyzer\SourceAnalyzer $source, NodeDataProvider $type_provider, Codebase $codebase, ClassLikeStorage $class_storage, string $fq_classlike_name, MethodIdentifier $analyzed_method_id, MethodIdentifier $actual_method_id, bool $did_explicitly_return) : void
    {
        $secondary_return_type_location = null;
        $actual_method_storage = $codebase->methods->getStorage($actual_method_id);
        $return_type_location = $codebase->methods->getMethodReturnTypeLocation($actual_method_id, $secondary_return_type_location);
        $original_fq_classlike_name = $fq_classlike_name;
        $return_type = $codebase->methods->getMethodReturnType($analyzed_method_id, $fq_classlike_name, $method_analyzer);
        if ($return_type && $class_storage->template_extended_params) {
            $declaring_method_id = $codebase->methods->getDeclaringMethodId($analyzed_method_id);
            if ($declaring_method_id) {
                $declaring_class_name = $declaring_method_id->fq_class_name;
                $class_storage = $codebase->classlike_storage_provider->get($declaring_class_name);
            }
            $this_object_type = self::getThisObjectType($class_storage, $original_fq_classlike_name);
            $class_template_params = ClassTemplateParamCollector::collect($codebase, $class_storage, $codebase->classlike_storage_provider->get($original_fq_classlike_name), strtolower($stmt->name->name), $this_object_type) ?: [];
            $template_result = new TemplateResult($class_template_params ?: [], []);
            $return_type = TemplateStandinTypeReplacer::replace($return_type, $template_result, $codebase, null, null, null, $original_fq_classlike_name);
        }
        $overridden_method_ids = $class_storage->overridden_method_ids[strtolower($stmt->name->name)] ?? [];
        if (!$return_type && !$class_storage->is_interface && $overridden_method_ids) {
            foreach ($overridden_method_ids as $interface_method_id) {
                $interface_class = $interface_method_id->fq_class_name;
                if (!$codebase->classlikes->interfaceExists($interface_class)) {
                    continue;
                }
                $interface_return_type = $codebase->methods->getMethodReturnType($interface_method_id, $interface_class);
                $interface_return_type_location = $codebase->methods->getMethodReturnTypeLocation($interface_method_id);
                ReturnTypeAnalyzer::verifyReturnType($stmt, $stmt->getStmts() ?: [], $source, $type_provider, $method_analyzer, $interface_return_type, $interface_class, $original_fq_classlike_name, $interface_return_type_location, [$analyzed_method_id->__toString()], $did_explicitly_return);
            }
        }
        $overridden_method_ids = array_map(static fn($method_id): string => $method_id->__toString(), $overridden_method_ids);
        if ($actual_method_storage->overridden_downstream) {
            $overridden_method_ids['overridden::downstream'] = 'overridden::downstream';
        }
        ReturnTypeAnalyzer::verifyReturnType($stmt, $stmt->getStmts() ?: [], $source, $type_provider, $method_analyzer, $return_type, $fq_classlike_name, $original_fq_classlike_name, $return_type_location, $overridden_method_ids, $did_explicitly_return);
    }
    /**
     * @param PhpParser\Node\Stmt\Class_|PhpParser\Node\Stmt\Enum_ $class
     */
    private function checkImplementedInterfaces(Context $class_context, PhpParser\Node\Stmt $class, Codebase $codebase, string $fq_class_name, ClassLikeStorage $storage) : bool
    {
        $classlike_storage_provider = $codebase->classlike_storage_provider;
        foreach ($class->implements as $interface_name) {
            $fq_interface_name = self::getFQCLNFromNameObject($interface_name, $this->source->getAliases());
            $fq_interface_name_lc = strtolower($fq_interface_name);
            $codebase->analyzer->addNodeReference($this->getFilePath(), $interface_name, $codebase->classlikes->interfaceExists($fq_interface_name) ? $fq_interface_name : '*' . ($interface_name instanceof PhpParser\Node\Name\FullyQualified ? '\\' : $this->getNamespace() . '-') . implode('\\', $interface_name->parts));
            $interface_location = new CodeLocation($this, $interface_name);
            if (self::checkFullyQualifiedClassLikeName($this, $fq_interface_name, $interface_location, null, null, $this->getSuppressedIssues()) === \false) {
                return \false;
            }
            if ($codebase->store_node_types && $fq_class_name) {
                $bounds = $interface_location->getSelectionBounds();
                $codebase->analyzer->addOffsetReference($this->getFilePath(), $bounds[0], $bounds[1], $fq_interface_name);
            }
            $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $this, $interface_name, $fq_interface_name, null);
            try {
                $interface_storage = $classlike_storage_provider->get($fq_interface_name);
            } catch (InvalidArgumentException $e) {
                return \false;
            }
            $code_location = new CodeLocation($this, $interface_name, $class_context->include_location, \true);
            if (!$interface_storage->is_interface) {
                IssueBuffer::maybeAdd(new UndefinedInterface($fq_interface_name . ' is not an interface', $code_location, $fq_interface_name), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            $this->checkTemplateParams($codebase, $storage, $interface_storage, $code_location, $storage->template_type_implements_count[$fq_interface_name_lc] ?? 0);
        }
        foreach ($storage->class_implements as $fq_interface_name_lc => $fq_interface_name) {
            try {
                $interface_storage = $classlike_storage_provider->get($fq_interface_name_lc);
            } catch (InvalidArgumentException $e) {
                return \false;
            }
            $code_location = new CodeLocation($this, $class->name ?? $class, $class_context->include_location, \true);
            if ($fq_interface_name_lc === 'traversable' && !$storage->abstract && !isset($storage->class_implements['iteratoraggregate']) && !isset($storage->class_implements['iterator']) && !isset($storage->parent_classes['pdostatement']) && !isset($storage->parent_classes['ds\\collection']) && !isset($storage->parent_classes['domnodelist']) && !isset($storage->parent_classes['dateperiod'])) {
                IssueBuffer::maybeAdd(new InvalidTraversableImplementation('Traversable should be implemented by implementing IteratorAggregate or Iterator', $code_location, $fq_class_name));
            }
            if ($interface_storage->deprecated) {
                IssueBuffer::maybeAdd(new DeprecatedInterface($fq_interface_name . ' is marked deprecated', $code_location, $fq_interface_name), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if ($interface_storage->external_mutation_free && !$storage->external_mutation_free) {
                IssueBuffer::maybeAdd(new MissingImmutableAnnotation($fq_interface_name . ' is marked @psalm-immutable, but ' . $fq_class_name . ' is not marked @psalm-immutable', $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            foreach ($interface_storage->methods as $interface_method_name_lc => $interface_method_storage) {
                if ($interface_method_storage->visibility === self::VISIBILITY_PUBLIC) {
                    $implementer_declaring_method_id = $codebase->methods->getDeclaringMethodId(new MethodIdentifier($this->fq_class_name, $interface_method_name_lc));
                    $implementer_method_storage = null;
                    $implementer_classlike_storage = null;
                    if ($implementer_declaring_method_id) {
                        $implementer_fq_class_name = $implementer_declaring_method_id->fq_class_name;
                        $implementer_method_storage = $codebase->methods->getStorage($implementer_declaring_method_id);
                        $implementer_classlike_storage = $classlike_storage_provider->get($implementer_fq_class_name);
                    }
                    if ($storage->is_enum) {
                        if ($interface_method_name_lc === 'cases') {
                            continue;
                        }
                        if ($storage->enum_type && in_array($interface_method_name_lc, ['from', 'tryfrom'], \true)) {
                            continue;
                        }
                    }
                    if (!$implementer_method_storage) {
                        IssueBuffer::maybeAdd(new UnimplementedInterfaceMethod('Method ' . $interface_method_name_lc . ' is not defined on class ' . $storage->name, $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
                        return \true;
                    }
                    $implementer_appearing_method_id = $codebase->methods->getAppearingMethodId(new MethodIdentifier($this->fq_class_name, $interface_method_name_lc));
                    $implementer_visibility = $implementer_method_storage->visibility;
                    if ($implementer_appearing_method_id && $implementer_appearing_method_id !== $implementer_declaring_method_id) {
                        $appearing_fq_class_name = $implementer_appearing_method_id->fq_class_name;
                        $appearing_method_name = $implementer_appearing_method_id->method_name;
                        $appearing_class_storage = $classlike_storage_provider->get($appearing_fq_class_name);
                        if (isset($appearing_class_storage->trait_visibility_map[$appearing_method_name])) {
                            $implementer_visibility = $appearing_class_storage->trait_visibility_map[$appearing_method_name];
                        }
                    }
                    if ($implementer_visibility !== self::VISIBILITY_PUBLIC) {
                        IssueBuffer::maybeAdd(new InaccessibleMethod('Interface-defined method ' . $implementer_method_storage->cased_name . ' must be public in ' . $storage->name, $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
                        return \true;
                    }
                    if ($interface_method_storage->is_static && !$implementer_method_storage->is_static) {
                        IssueBuffer::maybeAdd(new MethodSignatureMismatch('Method ' . $implementer_method_storage->cased_name . ' should be static like ' . $storage->name . '::' . $interface_method_storage->cased_name, $code_location), $implementer_method_storage->suppressed_issues);
                        return \true;
                    }
                    if ($storage->abstract && $implementer_method_storage === $interface_method_storage) {
                        continue;
                    }
                    \Psalm\Internal\Analyzer\MethodComparator::compare($codebase, null, $implementer_classlike_storage ?? $storage, $interface_storage, $implementer_method_storage, $interface_method_storage, $this->fq_class_name, $implementer_visibility, $code_location, $implementer_method_storage->suppressed_issues, \false);
                }
            }
        }
        return \true;
    }
    private function checkParentClass(Class_ $class, PhpParser\Node\Name $extended_class, string $fq_class_name, string $parent_fq_class_name, ClassLikeStorage $storage, Codebase $codebase, ?Context $class_context) : void
    {
        $classlike_storage_provider = $codebase->classlike_storage_provider;
        if (!$parent_fq_class_name) {
            throw new UnexpectedValueException('Parent class should be filled in for ' . $fq_class_name);
        }
        $parent_reference_location = new CodeLocation($this, $extended_class);
        if (self::checkFullyQualifiedClassLikeName($this->getSource(), $parent_fq_class_name, $parent_reference_location, null, null, $storage->suppressed_issues + $this->getSuppressedIssues()) === \false) {
            return;
        }
        if ($codebase->alter_code && $codebase->classes_to_move) {
            $codebase->classlikes->handleClassLikeReferenceInMigration($codebase, $this, $extended_class, $parent_fq_class_name, null);
        }
        try {
            $parent_class_storage = $classlike_storage_provider->get($parent_fq_class_name);
            $code_location = new CodeLocation($this, $extended_class, $class_context->include_location ?? null, \true);
            if ($parent_class_storage->is_trait || $parent_class_storage->is_interface) {
                IssueBuffer::maybeAdd(new UndefinedClass($parent_fq_class_name . ' is not a class', $code_location, $parent_fq_class_name . ' as class'), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if ($parent_class_storage->final) {
                IssueBuffer::maybeAdd(new InvalidExtendClass('Class ' . $fq_class_name . ' may not inherit from final class ' . $parent_fq_class_name, $code_location, $fq_class_name), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if ($parent_class_storage->deprecated) {
                IssueBuffer::maybeAdd(new DeprecatedClass($parent_fq_class_name . ' is marked deprecated', $code_location, $parent_fq_class_name), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if (!\Psalm\Internal\Analyzer\NamespaceAnalyzer::isWithinAny($fq_class_name, $parent_class_storage->internal)) {
                IssueBuffer::maybeAdd(new InternalClass($parent_fq_class_name . ' is internal to ' . InternalClass::listToPhrase($parent_class_storage->internal) . ' but called from ' . $fq_class_name, $code_location, $parent_fq_class_name), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if ($parent_class_storage->external_mutation_free && !$storage->external_mutation_free) {
                IssueBuffer::maybeAdd(new MissingImmutableAnnotation($parent_fq_class_name . ' is marked @psalm-immutable, but ' . $fq_class_name . ' is not marked @psalm-immutable', $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if ($storage->mutation_free && !$parent_class_storage->mutation_free) {
                IssueBuffer::maybeAdd(new MutableDependency($fq_class_name . ' is marked @psalm-immutable but ' . $parent_fq_class_name . ' is not', $code_location), $storage->suppressed_issues + $this->getSuppressedIssues());
            }
            if ($codebase->store_node_types) {
                $codebase->analyzer->addNodeReference($this->getFilePath(), $extended_class, $codebase->classlikes->classExists($parent_fq_class_name) ? $parent_fq_class_name : '*' . ($extended_class instanceof PhpParser\Node\Name\FullyQualified ? '\\' : $this->getNamespace() . '-') . implode('\\', $extended_class->parts));
            }
            $code_location = new CodeLocation($this, $class->name ?: $class, $class_context->include_location ?? null, \true);
            $this->checkTemplateParams($codebase, $storage, $parent_class_storage, $code_location, $storage->template_type_extends_count[$parent_fq_class_name] ?? 0);
        } catch (InvalidArgumentException $e) {
            // do nothing
        }
    }
    private function checkEnum() : void
    {
        $storage = $this->storage;
        $seen_values = [];
        foreach ($storage->enum_cases as $case_storage) {
            if ($case_storage->value !== null && $storage->enum_type === null) {
                IssueBuffer::maybeAdd(new InvalidEnumCaseValue('Case of a non-backed enum should not have a value', $case_storage->stmt_location, $storage->name));
            } elseif ($case_storage->value === null && $storage->enum_type !== null) {
                IssueBuffer::maybeAdd(new InvalidEnumCaseValue('Case of a backed enum should have a value', $case_storage->stmt_location, $storage->name));
            } elseif ($case_storage->value !== null && $storage->enum_type !== null) {
                if (is_int($case_storage->value) && $storage->enum_type === 'string' || is_string($case_storage->value) && $storage->enum_type === 'int') {
                    IssueBuffer::maybeAdd(new InvalidEnumCaseValue('Enum case value type should be ' . $storage->enum_type, $case_storage->stmt_location, $storage->name));
                }
            }
            if ($case_storage->value !== null) {
                if (in_array($case_storage->value, $seen_values, \true)) {
                    IssueBuffer::maybeAdd(new DuplicateEnumCaseValue('Enum case values should be unique', $case_storage->stmt_location, $storage->name));
                } else {
                    $seen_values[] = $case_storage->value;
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Exception\UnpreparedAnalysisException;
use Psalm\Internal\Codebase\Functions;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\Reflection;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\TypeAlias\LinkableTypeAlias;
use Psalm\Internal\Type\TypeTokenizer;
use Psalm\Issue\InvalidTypeImport;
use Psalm\Issue\UncaughtThrowInGlobalScope;
use Psalm\IssueBuffer;
use Psalm\NodeTypeProvider;
use Psalm\Plugin\EventHandler\Event\AfterFileAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\BeforeFileAnalysisEvent;
use Psalm\Type;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_combine;
use function array_diff_key;
use function array_keys;
use function count;
use function implode;
use function strpos;
use function strtolower;
/**
 * @internal
 * @psalm-consistent-constructor
 */
class FileAnalyzer extends \Psalm\Internal\Analyzer\SourceAnalyzer
{
    use \Psalm\Internal\Analyzer\CanAlias;
    protected string $file_name;
    protected string $file_path;
    protected ?string $root_file_path = null;
    protected ?string $root_file_name = null;
    /**
     * @var array<string, bool>
     */
    private array $required_file_paths = [];
    /**
     * @var array<string, bool>
     */
    private array $parent_file_paths = [];
    /**
     * @var array<string>
     */
    private array $suppressed_issues = [];
    /**
     * @var array<string, array<string, string>>
     */
    private array $namespace_aliased_classes = [];
    /**
     * @var array<string, array<lowercase-string, string>>
     */
    private array $namespace_aliased_classes_flipped = [];
    /**
     * @var array<string, array<string, string>>
     */
    private array $namespace_aliased_classes_flipped_replaceable = [];
    /**
     * @var array<lowercase-string, InterfaceAnalyzer>
     */
    public array $interface_analyzers_to_analyze = [];
    /**
     * @var array<lowercase-string, ClassAnalyzer>
     */
    public array $class_analyzers_to_analyze = [];
    public ?Context $context = null;
    public \Psalm\Internal\Analyzer\ProjectAnalyzer $project_analyzer;
    public Codebase $codebase;
    private int $first_statement_offset = -1;
    private ?NodeDataProvider $node_data = null;
    private ?Union $return_type = null;
    public function __construct(\Psalm\Internal\Analyzer\ProjectAnalyzer $project_analyzer, string $file_path, string $file_name)
    {
        $this->source = $this;
        $this->file_path = $file_path;
        $this->file_name = $file_name;
        $this->project_analyzer = $project_analyzer;
        $this->codebase = $project_analyzer->getCodebase();
    }
    public function analyze(?Context $file_context = null, ?Context $global_context = null) : void
    {
        $codebase = $this->project_analyzer->getCodebase();
        $file_storage = $codebase->file_storage_provider->get($this->file_path);
        if (!$file_storage->deep_scan && !$codebase->server_mode) {
            throw new UnpreparedAnalysisException('File ' . $this->file_path . ' has not been properly scanned');
        }
        if ($file_storage->has_visitor_issues) {
            return;
        }
        if ($file_context) {
            $this->context = $file_context;
        }
        if (!$this->context) {
            $this->context = new Context();
        }
        if ($codebase->config->useStrictTypesForFile($this->file_path)) {
            $this->context->strict_types = \true;
        }
        $this->context->is_global = \true;
        $this->context->defineGlobals();
        $this->context->collect_exceptions = $codebase->config->check_for_throws_in_global_scope;
        try {
            $stmts = $codebase->getStatementsForFile($this->file_path);
        } catch (PhpParser\Error $e) {
            return;
        }
        $event = new BeforeFileAnalysisEvent($this, $this->context, $file_storage, $codebase);
        $codebase->config->eventDispatcher->dispatchBeforeFileAnalysis($event);
        if ($codebase->alter_code) {
            foreach ($stmts as $stmt) {
                if (!$stmt instanceof PhpParser\Node\Stmt\Declare_) {
                    $this->first_statement_offset = (int) $stmt->getAttribute('startFilePos');
                    break;
                }
            }
        }
        $leftover_stmts = $this->populateCheckers($stmts);
        $this->node_data = new NodeDataProvider();
        $statements_analyzer = new \Psalm\Internal\Analyzer\StatementsAnalyzer($this, $this->node_data);
        foreach ($file_storage->docblock_issues as $docblock_issue) {
            IssueBuffer::maybeAdd($docblock_issue);
        }
        // if there are any leftover statements, evaluate them,
        // in turn causing the classes/interfaces be evaluated
        if ($leftover_stmts) {
            $statements_analyzer->analyze($leftover_stmts, $this->context, $global_context, \true);
            foreach ($leftover_stmts as $leftover_stmt) {
                if ($leftover_stmt instanceof PhpParser\Node\Stmt\Return_) {
                    if ($leftover_stmt->expr) {
                        $this->return_type = $statements_analyzer->node_data->getType($leftover_stmt->expr) ?? Type::getMixed();
                    } else {
                        $this->return_type = Type::getVoid();
                    }
                    break;
                }
            }
        }
        // check any leftover interfaces not already evaluated
        foreach ($this->interface_analyzers_to_analyze as $interface_analyzer) {
            $interface_analyzer->analyze();
        }
        // check any leftover classes not already evaluated
        foreach ($this->class_analyzers_to_analyze as $class_analyzer) {
            $class_analyzer->analyze(null, $this->context);
        }
        if ($codebase->config->check_for_throws_in_global_scope) {
            $uncaught_throws = $statements_analyzer->getUncaughtThrows($this->context);
            foreach ($uncaught_throws as $possibly_thrown_exception => $codelocations) {
                foreach ($codelocations as $codelocation) {
                    // issues are suppressed in ThrowAnalyzer, CallAnalyzer, etc.
                    IssueBuffer::maybeAdd(new UncaughtThrowInGlobalScope($possibly_thrown_exception . ' is thrown but not caught in global scope', $codelocation));
                }
            }
        }
        // validate type imports
        if ($file_storage->type_aliases) {
            foreach ($file_storage->type_aliases as $alias) {
                if ($alias instanceof LinkableTypeAlias) {
                    $location = new DocblockTypeLocation($this->getSource(), $alias->start_offset, $alias->end_offset, $alias->line_number);
                    $fq_source_classlike = $alias->declaring_fq_classlike_name;
                    if (\Psalm\Internal\Analyzer\ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($this->getSource(), $fq_source_classlike, $location, null, null, $this->suppressed_issues, new \Psalm\Internal\Analyzer\ClassLikeNameOptions(\true, \false, \true, \true, \true)) === \false) {
                        continue;
                    }
                    $referenced_class_storage = $codebase->classlike_storage_provider->get($fq_source_classlike);
                    if (!isset($referenced_class_storage->type_aliases[$alias->alias_name])) {
                        IssueBuffer::maybeAdd(new InvalidTypeImport('Type alias ' . $alias->alias_name . ' imported from ' . $fq_source_classlike . ' is not defined on the source class', $location));
                    }
                }
            }
        }
        $event = new AfterFileAnalysisEvent($this, $this->context, $file_storage, $codebase, $stmts);
        $codebase->config->eventDispatcher->dispatchAfterFileAnalysis($event);
        $this->class_analyzers_to_analyze = [];
        $this->interface_analyzers_to_analyze = [];
    }
    /**
     * @param  array<int, PhpParser\Node\Stmt>  $stmts
     * @return list<PhpParser\Node\Stmt>
     */
    public function populateCheckers(array $stmts) : array
    {
        $leftover_stmts = [];
        foreach ($stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
                $leftover_stmts[] = $stmt;
            } elseif ($stmt instanceof PhpParser\Node\Stmt\ClassLike) {
                $this->populateClassLikeAnalyzers($stmt);
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Namespace_) {
                $namespace_name = $stmt->name ? implode('\\', $stmt->name->parts) : '';
                $namespace_analyzer = new \Psalm\Internal\Analyzer\NamespaceAnalyzer($stmt, $this);
                $namespace_analyzer->collectAnalyzableInformation();
                $this->namespace_aliased_classes[$namespace_name] = $namespace_analyzer->getAliases()->uses;
                $this->namespace_aliased_classes_flipped[$namespace_name] = $namespace_analyzer->getAliasedClassesFlipped();
                $this->namespace_aliased_classes_flipped_replaceable[$namespace_name] = $namespace_analyzer->getAliasedClassesFlippedReplaceable();
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Use_) {
                $this->visitUse($stmt);
            } elseif ($stmt instanceof PhpParser\Node\Stmt\GroupUse) {
                $this->visitGroupUse($stmt);
            } else {
                if ($stmt instanceof PhpParser\Node\Stmt\If_) {
                    foreach ($stmt->stmts as $if_stmt) {
                        if ($if_stmt instanceof PhpParser\Node\Stmt\ClassLike) {
                            $this->populateClassLikeAnalyzers($if_stmt);
                        }
                    }
                }
                $leftover_stmts[] = $stmt;
            }
        }
        return $leftover_stmts;
    }
    private function populateClassLikeAnalyzers(PhpParser\Node\Stmt\ClassLike $stmt) : void
    {
        if ($stmt instanceof PhpParser\Node\Stmt\Class_ || $stmt instanceof PhpParser\Node\Stmt\Enum_) {
            if (!$stmt->name) {
                return;
            }
            // this can happen when stubbing
            if (!$this->codebase->classExists($stmt->name->name) && !$this->codebase->classlikes->enumExists($stmt->name->name)) {
                return;
            }
            $class_analyzer = new \Psalm\Internal\Analyzer\ClassAnalyzer($stmt, $this, $stmt->name->name);
            $fq_class_name = $class_analyzer->getFQCLN();
            $this->class_analyzers_to_analyze[strtolower($fq_class_name)] = $class_analyzer;
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Interface_) {
            if (!$stmt->name) {
                return;
            }
            // this can happen when stubbing
            if (!$this->codebase->interfaceExists($stmt->name->name)) {
                return;
            }
            $class_analyzer = new \Psalm\Internal\Analyzer\InterfaceAnalyzer($stmt, $this, $stmt->name->name);
            $fq_class_name = $class_analyzer->getFQCLN();
            $this->interface_analyzers_to_analyze[strtolower($fq_class_name)] = $class_analyzer;
        }
    }
    public function addNamespacedClassAnalyzer(string $fq_class_name, \Psalm\Internal\Analyzer\ClassAnalyzer $class_analyzer) : void
    {
        $this->class_analyzers_to_analyze[strtolower($fq_class_name)] = $class_analyzer;
    }
    public function addNamespacedInterfaceAnalyzer(string $fq_class_name, \Psalm\Internal\Analyzer\InterfaceAnalyzer $interface_analyzer) : void
    {
        $this->interface_analyzers_to_analyze[strtolower($fq_class_name)] = $interface_analyzer;
    }
    public function getMethodMutations(MethodIdentifier $method_id, Context $this_context, bool $from_project_analyzer = \false) : void
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        $fq_class_name_lc = strtolower($fq_class_name);
        if (isset($this->class_analyzers_to_analyze[$fq_class_name_lc])) {
            $class_analyzer_to_examine = $this->class_analyzers_to_analyze[$fq_class_name_lc];
        } else {
            if (!$from_project_analyzer) {
                $this->project_analyzer->getMethodMutations($method_id, $this_context, $this->getRootFilePath(), $this->getRootFileName());
            }
            return;
        }
        $call_context = new Context($this_context->self);
        $call_context->collect_mutations = $this_context->collect_mutations;
        $call_context->collect_initializations = $this_context->collect_initializations;
        $call_context->collect_nonprivate_initializations = $this_context->collect_nonprivate_initializations;
        $call_context->initialized_methods = $this_context->initialized_methods;
        $call_context->include_location = $this_context->include_location;
        $call_context->calling_method_id = $this_context->calling_method_id;
        foreach ($this_context->vars_possibly_in_scope as $var => $_) {
            if (strpos($var, '$this->') === 0) {
                $call_context->vars_possibly_in_scope[$var] = \true;
            }
        }
        foreach ($this_context->vars_in_scope as $var => $type) {
            if (strpos($var, '$this->') === 0) {
                $call_context->vars_in_scope[$var] = $type;
            }
        }
        if (!isset($this_context->vars_in_scope['$this'])) {
            throw new UnexpectedValueException('Should exist');
        }
        $call_context->vars_in_scope['$this'] = $this_context->vars_in_scope['$this'];
        $class_analyzer_to_examine->getMethodMutations($method_name, $call_context);
        foreach ($call_context->vars_possibly_in_scope as $var => $_) {
            $this_context->vars_possibly_in_scope[$var] = \true;
        }
        foreach ($call_context->vars_in_scope as $var => $type) {
            $this_context->vars_in_scope[$var] = $type;
        }
    }
    public function getFunctionLikeAnalyzer(MethodIdentifier $method_id) : ?\Psalm\Internal\Analyzer\MethodAnalyzer
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        $fq_class_name_lc = strtolower($fq_class_name);
        if (!isset($this->class_analyzers_to_analyze[$fq_class_name_lc])) {
            return null;
        }
        $class_analyzer_to_examine = $this->class_analyzers_to_analyze[$fq_class_name_lc];
        return $class_analyzer_to_examine->getFunctionLikeAnalyzer($method_name);
    }
    /** @psalm-mutation-free */
    public function getNamespace() : ?string
    {
        return null;
    }
    /**
     * @psalm-mutation-free
     * @return array<lowercase-string, string>
     */
    public function getAliasedClassesFlipped(?string $namespace_name = null) : array
    {
        if ($namespace_name && isset($this->namespace_aliased_classes_flipped[$namespace_name])) {
            return $this->namespace_aliased_classes_flipped[$namespace_name];
        }
        return $this->aliased_classes_flipped;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, string>
     */
    public function getAliasedClassesFlippedReplaceable(?string $namespace_name = null) : array
    {
        if ($namespace_name && isset($this->namespace_aliased_classes_flipped_replaceable[$namespace_name])) {
            return $this->namespace_aliased_classes_flipped_replaceable[$namespace_name];
        }
        return $this->aliased_classes_flipped_replaceable;
    }
    public static function clearCache() : void
    {
        TypeTokenizer::clearCache();
        Reflection::clearCache();
        Functions::clearCache();
        IssueBuffer::clearCache();
        FileManipulationBuffer::clearCache();
        \Psalm\Internal\Analyzer\FunctionLikeAnalyzer::clearCache();
        ClassLikeStorageProvider::deleteAll();
        FileStorageProvider::deleteAll();
        FileReferenceProvider::clearCache();
        InternalCallMapHandler::clearCache();
    }
    /** @psalm-mutation-free */
    public function getFileName() : string
    {
        return $this->file_name;
    }
    /** @psalm-mutation-free */
    public function getFilePath() : string
    {
        return $this->file_path;
    }
    /** @psalm-mutation-free */
    public function getRootFileName() : string
    {
        return $this->root_file_name ?: $this->file_name;
    }
    /** @psalm-mutation-free */
    public function getRootFilePath() : string
    {
        return $this->root_file_path ?: $this->file_path;
    }
    public function setRootFilePath(string $file_path, string $file_name) : void
    {
        $this->root_file_name = $file_name;
        $this->root_file_path = $file_path;
    }
    public function addRequiredFilePath(string $file_path) : void
    {
        $this->required_file_paths[$file_path] = \true;
    }
    public function addParentFilePath(string $file_path) : void
    {
        $this->parent_file_paths[$file_path] = \true;
    }
    /** @psalm-mutation-free */
    public function hasParentFilePath(string $file_path) : bool
    {
        return $this->file_path === $file_path || isset($this->parent_file_paths[$file_path]);
    }
    /** @psalm-mutation-free */
    public function hasAlreadyRequiredFilePath(string $file_path) : bool
    {
        return isset($this->required_file_paths[$file_path]);
    }
    /**
     * @psalm-mutation-free
     * @return list<string>
     */
    public function getRequiredFilePaths() : array
    {
        return array_keys($this->required_file_paths);
    }
    /**
     * @psalm-mutation-free
     * @return list<string>
     */
    public function getParentFilePaths() : array
    {
        return array_keys($this->parent_file_paths);
    }
    /** @psalm-mutation-free */
    public function getRequireNesting() : int
    {
        return count($this->parent_file_paths);
    }
    /**
     * @psalm-mutation-free
     * @return array<string>
     */
    public function getSuppressedIssues() : array
    {
        return $this->suppressed_issues;
    }
    /**
     * @param array<int, string> $new_issues
     */
    public function addSuppressedIssues(array $new_issues) : void
    {
        if (isset($new_issues[0])) {
            $new_issues = array_combine($new_issues, $new_issues);
        }
        $this->suppressed_issues = $new_issues + $this->suppressed_issues;
    }
    /**
     * @param array<int, string> $new_issues
     */
    public function removeSuppressedIssues(array $new_issues) : void
    {
        if (isset($new_issues[0])) {
            $new_issues = array_combine($new_issues, $new_issues);
        }
        $this->suppressed_issues = array_diff_key($this->suppressed_issues, $new_issues);
    }
    /** @psalm-mutation-free */
    public function getFQCLN() : ?string
    {
        return null;
    }
    /** @psalm-mutation-free */
    public function getParentFQCLN() : ?string
    {
        return null;
    }
    /** @psalm-mutation-free */
    public function getClassName() : ?string
    {
        return null;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, array<string, Union>>|null
     */
    public function getTemplateTypeMap() : ?array
    {
        return null;
    }
    /** @psalm-mutation-free */
    public function isStatic() : bool
    {
        return \false;
    }
    /**
     * @psalm-mutation-free
     */
    public function getFileAnalyzer() : \Psalm\Internal\Analyzer\FileAnalyzer
    {
        return $this;
    }
    /**
     * @psalm-mutation-free
     */
    public function getProjectAnalyzer() : \Psalm\Internal\Analyzer\ProjectAnalyzer
    {
        return $this->project_analyzer;
    }
    /** @psalm-mutation-free */
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /** @psalm-mutation-free */
    public function getFirstStatementOffset() : int
    {
        return $this->first_statement_offset;
    }
    /** @psalm-mutation-free */
    public function getNodeTypeProvider() : NodeTypeProvider
    {
        if (!$this->node_data) {
            throw new UnexpectedValueException('There should be a node type provider');
        }
        return $this->node_data;
    }
    /** @psalm-mutation-free */
    public function getReturnType() : ?Union
    {
        return $this->return_type;
    }
    public function clearSourceBeforeDestruction() : void
    {
        unset($this->source);
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use Generator;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Attribute;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\AttributeGroup;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\New_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name\FullyQualified;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Expression;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\ConstantTypeResolver;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use Psalm\Issue\InvalidAttribute;
use Psalm\Issue\UndefinedClass;
use Psalm\IssueBuffer;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\HasAttributesInterface;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Union;
use function array_shift;
use function array_values;
use function assert;
use function count;
use function reset;
use function strtolower;
/**
 * @internal
 */
class AttributesAnalyzer
{
    private const TARGET_DESCRIPTIONS = [1 => 'class', 2 => 'function', 4 => 'method', 8 => 'property', 16 => 'class constant', 32 => 'function/method parameter', 40 => 'promoted property'];
    // Copied from Attribute class since that class might not exist at runtime
    public const TARGET_CLASS = 1;
    public const TARGET_FUNCTION = 2;
    public const TARGET_METHOD = 4;
    public const TARGET_PROPERTY = 8;
    public const TARGET_CLASS_CONSTANT = 16;
    public const TARGET_PARAMETER = 32;
    public const TARGET_ALL = 63;
    public const IS_REPEATABLE = 64;
    /**
     * @param array<array-key, AttributeGroup> $attribute_groups
     * @param key-of<self::TARGET_DESCRIPTIONS> $target
     * @param array<array-key, string> $suppressed_issues
     */
    public static function analyze(\Psalm\Internal\Analyzer\SourceAnalyzer $source, Context $context, HasAttributesInterface $storage, array $attribute_groups, int $target, array $suppressed_issues) : void
    {
        $codebase = $source->getCodebase();
        $appearing_non_repeatable_attributes = [];
        foreach (self::iterateAttributeNodes($attribute_groups) as $attribute) {
            if ($attribute->name instanceof FullyQualified) {
                $fq_attribute_name = (string) $attribute->name;
            } else {
                $fq_attribute_name = \Psalm\Internal\Analyzer\ClassLikeAnalyzer::getFQCLNFromNameObject($attribute->name, $source->getAliases());
            }
            $attribute_name = (string) $attribute->name;
            $attribute_name_location = new CodeLocation($source, $attribute->name);
            $attribute_class_storage = $codebase->classlikes->classExists($fq_attribute_name) ? $codebase->classlike_storage_provider->get($fq_attribute_name) : null;
            $attribute_class_flags = self::getAttributeClassFlags($source, $attribute_name, $fq_attribute_name, $attribute_name_location, $attribute_class_storage, $suppressed_issues);
            self::analyzeAttributeConstruction($source, $context, $fq_attribute_name, $attribute, $suppressed_issues, $storage instanceof ClassLikeStorage ? $storage : null);
            if (($attribute_class_flags & self::IS_REPEATABLE) === 0) {
                // Not IS_REPEATABLE
                if (isset($appearing_non_repeatable_attributes[$fq_attribute_name])) {
                    IssueBuffer::maybeAdd(new InvalidAttribute("Attribute {$attribute_name} is not repeatable", $attribute_name_location), $suppressed_issues);
                }
                $appearing_non_repeatable_attributes[$fq_attribute_name] = \true;
            }
            if (($attribute_class_flags & $target) === 0) {
                IssueBuffer::maybeAdd(new InvalidAttribute("Attribute {$attribute_name} cannot be used on a " . self::TARGET_DESCRIPTIONS[$target], $attribute_name_location), $suppressed_issues);
            }
        }
    }
    /**
     * @param array<array-key, string> $suppressed_issues
     */
    private static function analyzeAttributeConstruction(\Psalm\Internal\Analyzer\SourceAnalyzer $source, Context $context, string $fq_attribute_name, Attribute $attribute, array $suppressed_issues, ?ClassLikeStorage $classlike_storage = null) : void
    {
        $attribute_name_location = new CodeLocation($source, $attribute->name);
        if (\Psalm\Internal\Analyzer\ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($source, $fq_attribute_name, $attribute_name_location, null, null, $suppressed_issues, new \Psalm\Internal\Analyzer\ClassLikeNameOptions(\false, \false, \false, \false, \false, \true)) === \false) {
            return;
        }
        if (strtolower($fq_attribute_name) === 'attribute' && $classlike_storage) {
            if ($classlike_storage->is_trait) {
                IssueBuffer::maybeAdd(new InvalidAttribute('Traits cannot act as attribute classes', $attribute_name_location), $suppressed_issues);
            } elseif ($classlike_storage->is_interface) {
                IssueBuffer::maybeAdd(new InvalidAttribute('Interfaces cannot act as attribute classes', $attribute_name_location), $suppressed_issues);
            } elseif ($classlike_storage->abstract) {
                IssueBuffer::maybeAdd(new InvalidAttribute('Abstract classes cannot act as attribute classes', $attribute_name_location), $suppressed_issues);
            } elseif (isset($classlike_storage->methods['__construct']) && $classlike_storage->methods['__construct']->visibility !== \Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_PUBLIC) {
                IssueBuffer::maybeAdd(new InvalidAttribute('Classes with protected/private constructors cannot act as attribute classes', $attribute_name_location), $suppressed_issues);
            } elseif ($classlike_storage->is_enum) {
                IssueBuffer::maybeAdd(new InvalidAttribute('Enums cannot act as attribute classes', $attribute_name_location), $suppressed_issues);
            }
        }
        $statements_analyzer = new StatementsAnalyzer($source, new NodeDataProvider());
        $statements_analyzer->addSuppressedIssues(array_values($suppressed_issues));
        $had_returned = $context->has_returned;
        $context->has_returned = \false;
        IssueBuffer::startRecording();
        $statements_analyzer->analyze(
            [new Expression(new New_($attribute->name, $attribute->args, $attribute->getAttributes()))],
            // Use a new Context for the Attribute attribute so that it can't access `self`
            strtolower($fq_attribute_name) === "attribute" ? new Context() : $context
        );
        $context->has_returned = $had_returned;
        $issues = IssueBuffer::clearRecordingLevel();
        IssueBuffer::stopRecording();
        foreach ($issues as $issue) {
            if ($issue instanceof UndefinedClass && $issue->fq_classlike_name === $fq_attribute_name) {
                // Remove UndefinedClass for the attribute, since we already added UndefinedAttribute
                continue;
            }
            IssueBuffer::bubbleUp($issue);
        }
    }
    /**
     * @param array<array-key, string> $suppressed_issues
     */
    private static function getAttributeClassFlags(\Psalm\Internal\Analyzer\SourceAnalyzer $source, string $attribute_name, string $fq_attribute_name, CodeLocation $attribute_name_location, ?ClassLikeStorage $attribute_class_storage, array $suppressed_issues) : int
    {
        if (strtolower($fq_attribute_name) === "attribute") {
            // We override this here because we still want to analyze attributes
            // for PHP 7.4 when the Attribute class doesn't yet exist.
            return self::TARGET_CLASS;
        }
        if ($attribute_class_storage === null) {
            return self::TARGET_ALL;
            // Defaults to TARGET_ALL
        }
        foreach ($attribute_class_storage->attributes as $attribute_attribute) {
            if ($attribute_attribute->fq_class_name === 'Attribute') {
                if (!$attribute_attribute->args) {
                    return self::TARGET_ALL;
                    // Defaults to TARGET_ALL
                }
                $first_arg = reset($attribute_attribute->args);
                $first_arg_type = $first_arg->type;
                if ($first_arg_type instanceof UnresolvedConstantComponent) {
                    $first_arg_type = new Union([ConstantTypeResolver::resolve($source->getCodebase()->classlikes, $first_arg_type, $source instanceof StatementsAnalyzer ? $source : null)]);
                }
                if (!$first_arg_type->isSingleIntLiteral()) {
                    return self::TARGET_ALL;
                    // Fall back to default if it's invalid
                }
                return $first_arg_type->getSingleIntLiteral()->value;
            }
        }
        IssueBuffer::maybeAdd(new InvalidAttribute("The class {$attribute_name} doesn't have the Attribute attribute", $attribute_name_location), $suppressed_issues);
        return self::TARGET_ALL;
        // Fall back to default if it's invalid
    }
    /**
     * @param iterable<AttributeGroup> $attribute_groups
     * @return Generator<int, Attribute>
     */
    private static function iterateAttributeNodes(iterable $attribute_groups) : Generator
    {
        foreach ($attribute_groups as $attribute_group) {
            foreach ($attribute_group->attrs as $attribute) {
                (yield $attribute);
            }
        }
    }
    /**
     * Analyze Reflection getAttributes method calls.
     * @param list<Arg> $args
     */
    public static function analyzeGetAttributes(StatementsAnalyzer $statements_analyzer, string $method_id, array $args) : void
    {
        if (count($args) !== 1) {
            // We skip this analysis if $flags is specified on getAttributes, since the only option
            // is ReflectionAttribute::IS_INSTANCEOF, which causes getAttributes to return children.
            // When returning children we don't want to limit this since a child could add a target.
            return;
        }
        switch ($method_id) {
            case "ReflectionClass::getattributes":
                $target = self::TARGET_CLASS;
                break;
            case "ReflectionFunction::getattributes":
                $target = self::TARGET_FUNCTION;
                break;
            case "ReflectionMethod::getattributes":
                $target = self::TARGET_METHOD;
                break;
            case "ReflectionProperty::getattributes":
                $target = self::TARGET_PROPERTY;
                break;
            case "ReflectionClassConstant::getattributes":
                $target = self::TARGET_CLASS_CONSTANT;
                break;
            case "ReflectionParameter::getattributes":
                $target = self::TARGET_PARAMETER;
                break;
            default:
                return;
        }
        $arg = $args[0];
        if ($arg->name !== null) {
            for (; !empty($args) && ($arg->name->name ?? null) !== "name"; $arg = array_shift($args)) {
            }
            if ($arg->name->name ?? null !== "name") {
                // No named argument for "name" parameter
                return;
            }
        }
        $arg_type = $statements_analyzer->getNodeTypeProvider()->getType($arg->value);
        if ($arg_type === null || !$arg_type->isSingle() || !$arg_type->hasLiteralString()) {
            return;
        }
        $class_string = $arg_type->getSingleAtomic();
        assert($class_string instanceof TLiteralString);
        $codebase = $statements_analyzer->getCodebase();
        if (!$codebase->classExists($class_string->value)) {
            return;
        }
        $class_storage = $codebase->classlike_storage_provider->get($class_string->value);
        $arg_location = new CodeLocation($statements_analyzer, $arg);
        $class_attribute_target = self::getAttributeClassFlags($statements_analyzer, $class_string->value, $class_string->value, $arg_location, $class_storage, $statements_analyzer->getSuppressedIssues());
        if (($class_attribute_target & $target) === 0) {
            IssueBuffer::maybeAdd(new InvalidAttribute("Attribute {$class_string->value} cannot be used on a " . self::TARGET_DESCRIPTIONS[$target], $arg_location), $statements_analyzer->getSuppressedIssues());
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer;

/**
 * @internal
 */
class ClassLikeNameOptions
{
    public bool $inferred;
    public bool $allow_trait;
    public bool $allow_interface;
    public bool $allow_enum;
    public bool $from_docblock;
    public bool $from_attribute;
    public function __construct(bool $inferred = \false, bool $allow_trait = \false, bool $allow_interface = \true, bool $allow_enum = \true, bool $from_docblock = \false, bool $from_attribute = \false)
    {
        $this->inferred = $inferred;
        $this->allow_trait = $allow_trait;
        $this->allow_interface = $allow_interface;
        $this->allow_enum = $allow_enum;
        $this->from_docblock = $from_docblock;
        $this->from_attribute = $from_attribute;
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class DataFlowNodeData
{
    use ImmutableNonCloneableTrait;
    public int $line_from;
    public int $line_to;
    public string $label;
    public string $file_name;
    public string $file_path;
    public string $snippet;
    public int $from;
    public int $to;
    public int $snippet_from;
    public int $column_from;
    public int $column_to;
    public function __construct(string $label, int $line_from, int $line_to, string $file_name, string $file_path, string $snippet, int $from, int $to, int $snippet_from, int $column_from, int $column_to)
    {
        $this->label = $label;
        $this->line_from = $line_from;
        $this->line_to = $line_to;
        $this->file_name = $file_name;
        $this->file_path = $file_path;
        $this->snippet = $snippet;
        $this->from = $from;
        $this->to = $to;
        $this->snippet_from = $snippet_from;
        $this->column_from = $column_from;
        $this->column_to = $column_to;
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\Statements\Block\DoAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\ForAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\IfElseAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\SwitchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\TryAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\WhileAnalyzer;
use Psalm\Internal\Analyzer\Statements\BreakAnalyzer;
use Psalm\Internal\Analyzer\Statements\ContinueAnalyzer;
use Psalm\Internal\Analyzer\Statements\EchoAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Assignment\InstancePropertyAssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\ClassConstAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ConstFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\VariableFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\SimpleTypeInferer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\Statements\GlobalAnalyzer;
use Psalm\Internal\Analyzer\Statements\ReturnAnalyzer;
use Psalm\Internal\Analyzer\Statements\StaticAnalyzer;
use Psalm\Internal\Analyzer\Statements\ThrowAnalyzer;
use Psalm\Internal\Analyzer\Statements\UnsetAnalyzer;
use Psalm\Internal\Analyzer\Statements\UnusedAssignmentRemover;
use Psalm\Internal\Codebase\DataFlowGraph;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\ReferenceConstraint;
use Psalm\Internal\Scanner\ParsedDocblock;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\CheckType;
use Psalm\Issue\ComplexFunction;
use Psalm\Issue\ComplexMethod;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\MissingDocblockType;
use Psalm\Issue\Trace;
use Psalm\Issue\UndefinedDocblockClass;
use Psalm\Issue\UndefinedTrace;
use Psalm\Issue\UnevaluatedCode;
use Psalm\Issue\UnrecognizedStatement;
use Psalm\Issue\UnusedForeachValue;
use Psalm\Issue\UnusedVariable;
use Psalm\IssueBuffer;
use Psalm\NodeTypeProvider;
use Psalm\Plugin\EventHandler\Event\AfterStatementAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\BeforeStatementAnalysisEvent;
use Psalm\Type;
use UnexpectedValueException;
use function array_change_key_case;
use function array_column;
use function array_combine;
use function array_keys;
use function array_map;
use function array_search;
use function assert;
use function count;
use function explode;
use function fwrite;
use function get_class;
use function in_array;
use function is_string;
use function ltrim;
use function preg_split;
use function reset;
use function round;
use function strlen;
use function strpos;
use function strrpos;
use function strtolower;
use function substr;
use function trim;
use const PREG_SPLIT_NO_EMPTY;
use const STDERR;
/**
 * @internal
 */
class StatementsAnalyzer extends \Psalm\Internal\Analyzer\SourceAnalyzer
{
    protected \Psalm\Internal\Analyzer\SourceAnalyzer $source;
    protected \Psalm\Internal\Analyzer\FileAnalyzer $file_analyzer;
    protected Codebase $codebase;
    /**
     * @var array<string, CodeLocation>
     */
    private array $all_vars = [];
    /**
     * @var array<string, int>
     */
    private array $var_branch_points = [];
    /**
     * Possibly undefined variables should be initialised if we're altering code
     *
     * @var array<string, int>|null
     */
    private ?array $vars_to_initialize = null;
    /**
     * @var array<string, FunctionAnalyzer>
     */
    private array $function_analyzers = [];
    /**
     * @var array<string, array{0: string, 1: CodeLocation}>
     */
    private array $unused_var_locations = [];
    /**
     * @var array<string, true>
     */
    public array $byref_uses = [];
    private ?ParsedDocblock $parsed_docblock = null;
    private ?string $fake_this_class = null;
    public NodeDataProvider $node_data;
    public ?DataFlowGraph $data_flow_graph = null;
    /**
     * Locations of foreach values
     *
     * Used to discern ordinary UnusedVariables from UnusedForeachValues
     *
     * @var array<string, list<CodeLocation>>
     * @psalm-internal Psalm\Internal\Analyzer
     */
    public array $foreach_var_locations = [];
    public function __construct(\Psalm\Internal\Analyzer\SourceAnalyzer $source, NodeDataProvider $node_data)
    {
        $this->source = $source;
        $this->file_analyzer = $source->getFileAnalyzer();
        $this->codebase = $source->getCodebase();
        $this->node_data = $node_data;
        if ($this->codebase->taint_flow_graph) {
            $this->data_flow_graph = new TaintFlowGraph();
        } elseif ($this->codebase->find_unused_variables) {
            $this->data_flow_graph = new VariableUseGraph();
        }
    }
    /**
     * Checks an array of statements for validity
     *
     * @param  array<PhpParser\Node\Stmt>   $stmts
     * @return null|false
     */
    public function analyze(array $stmts, Context $context, ?Context $global_context = null, bool $root_scope = \false) : ?bool
    {
        if (!$stmts) {
            return null;
        }
        // hoist functions to the top
        $this->hoistFunctions($stmts, $context);
        $project_analyzer = $this->getFileAnalyzer()->project_analyzer;
        $codebase = $project_analyzer->getCodebase();
        if ($codebase->config->hoist_constants) {
            self::hoistConstants($this, $stmts, $context);
        }
        foreach ($stmts as $stmt) {
            if (self::analyzeStatement($this, $stmt, $context, $global_context) === \false) {
                return \false;
            }
        }
        if ($root_scope && !$context->collect_initializations && !$context->collect_mutations && $codebase->find_unused_variables && $context->check_variables) {
            $this->checkUnreferencedVars($stmts, $context);
        }
        if ($codebase->alter_code && $root_scope && $this->vars_to_initialize) {
            $file_contents = $codebase->getFileContents($this->getFilePath());
            foreach ($this->vars_to_initialize as $var_id => $branch_point) {
                $newline_pos = (int) strrpos($file_contents, "\n", $branch_point - strlen($file_contents)) + 1;
                $indentation = substr($file_contents, $newline_pos, $branch_point - $newline_pos);
                FileManipulationBuffer::add($this->getFilePath(), [new FileManipulation($branch_point, $branch_point, $var_id . ' = null;' . "\n" . $indentation)]);
            }
        }
        if ($root_scope && $this->data_flow_graph instanceof TaintFlowGraph && $this->codebase->taint_flow_graph && $codebase->config->trackTaintsInPath($this->getFilePath())) {
            $this->codebase->taint_flow_graph->addGraph($this->data_flow_graph);
        }
        return null;
    }
    /**
     * @param  array<PhpParser\Node\Stmt>   $stmts
     */
    private function hoistFunctions(array $stmts, Context $context) : void
    {
        foreach ($stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\Function_) {
                $function_name = strtolower($stmt->name->name);
                if ($ns = $this->getNamespace()) {
                    $fq_function_name = strtolower($ns) . '\\' . $function_name;
                } else {
                    $fq_function_name = $function_name;
                }
                if ($this->data_flow_graph && $this->codebase->find_unused_variables) {
                    foreach ($stmt->stmts as $function_stmt) {
                        if ($function_stmt instanceof PhpParser\Node\Stmt\Global_) {
                            foreach ($function_stmt->vars as $var) {
                                if (!$var instanceof PhpParser\Node\Expr\Variable || !is_string($var->name)) {
                                    continue;
                                }
                                $var_id = '$' . $var->name;
                                if ($var_id !== '$argv' && $var_id !== '$argc') {
                                    $context->byref_constraints[$var_id] = new ReferenceConstraint();
                                }
                            }
                        }
                    }
                }
                try {
                    $function_analyzer = new \Psalm\Internal\Analyzer\FunctionAnalyzer($stmt, $this->source);
                    $this->function_analyzers[$fq_function_name] = $function_analyzer;
                } catch (UnexpectedValueException $e) {
                    // do nothing
                }
            }
        }
    }
    /**
     * @param  array<PhpParser\Node\Stmt>   $stmts
     */
    private static function hoistConstants(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, array $stmts, Context $context) : void
    {
        $codebase = $statements_analyzer->getCodebase();
        foreach ($stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\Const_) {
                foreach ($stmt->consts as $const) {
                    ConstFetchAnalyzer::setConstType($statements_analyzer, $const->name->name, SimpleTypeInferer::infer($codebase, $statements_analyzer->node_data, $const->value, $statements_analyzer->getAliases(), $statements_analyzer) ?? Type::getMixed(), $context);
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\FuncCall && $stmt->expr->name instanceof PhpParser\Node\Name && $stmt->expr->name->parts === ['define'] && isset($stmt->expr->getArgs()[1])) {
                $const_name = ConstFetchAnalyzer::getConstName($stmt->expr->getArgs()[0]->value, $statements_analyzer->node_data, $codebase, $statements_analyzer->getAliases());
                if ($const_name !== null) {
                    ConstFetchAnalyzer::setConstType($statements_analyzer, $const_name, SimpleTypeInferer::infer($codebase, $statements_analyzer->node_data, $stmt->expr->getArgs()[1]->value, $statements_analyzer->getAliases(), $statements_analyzer) ?? Type::getMixed(), $context);
                }
            }
        }
    }
    /**
     * @return false|null
     */
    private static function analyzeStatement(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, PhpParser\Node\Stmt $stmt, Context $context, ?Context $global_context) : ?bool
    {
        if (self::dispatchBeforeStatementAnalysis($stmt, $context, $statements_analyzer) === \false) {
            return \false;
        }
        $ignore_variable_property = \false;
        $ignore_variable_method = \false;
        $codebase = $statements_analyzer->getCodebase();
        if ($statements_analyzer->getProjectAnalyzer()->debug_lines) {
            fwrite(STDERR, $statements_analyzer->getFilePath() . ':' . $stmt->getLine() . "\n");
        }
        $new_issues = null;
        $traced_variables = [];
        $checked_types = [];
        if ($docblock = $stmt->getDocComment()) {
            $statements_analyzer->parseStatementDocblock($docblock, $stmt, $context);
            if (isset($statements_analyzer->parsed_docblock->tags['psalm-trace'])) {
                foreach ($statements_analyzer->parsed_docblock->tags['psalm-trace'] as $traced_variable_line) {
                    $possible_traced_variable_names = preg_split('/(?:\\s*,\\s*|\\s+)/', $traced_variable_line, -1, PREG_SPLIT_NO_EMPTY);
                    if ($possible_traced_variable_names) {
                        $traced_variables = [...$traced_variables, ...$possible_traced_variable_names];
                    }
                }
            }
            foreach ($statements_analyzer->parsed_docblock->tags['psalm-check-type'] ?? [] as $inexact_check) {
                $checked_types[] = [$inexact_check, \false];
            }
            foreach ($statements_analyzer->parsed_docblock->tags['psalm-check-type-exact'] ?? [] as $exact_check) {
                $checked_types[] = [$exact_check, \true];
            }
            if (isset($statements_analyzer->parsed_docblock->tags['psalm-ignore-variable-method'])) {
                $context->ignore_variable_method = $ignore_variable_method = \true;
            }
            if (isset($statements_analyzer->parsed_docblock->tags['psalm-ignore-variable-property'])) {
                $context->ignore_variable_property = $ignore_variable_property = \true;
            }
            if (isset($statements_analyzer->parsed_docblock->tags['psalm-suppress'])) {
                $suppressed = $statements_analyzer->parsed_docblock->tags['psalm-suppress'];
                if ($suppressed) {
                    $new_issues = [];
                    foreach ($suppressed as $offset => $suppress_entry) {
                        foreach (DocComment::parseSuppressList($suppress_entry) as $issue_offset => $issue_type) {
                            $new_issues[$issue_offset + $offset] = $issue_type;
                        }
                    }
                    if ($codebase->track_unused_suppressions && (count($new_issues) === 1 || !in_array("UnusedPsalmSuppress", $new_issues))) {
                        foreach ($new_issues as $offset => $issue_type) {
                            if ($issue_type === 'InaccessibleMethod') {
                                continue;
                            }
                            IssueBuffer::addUnusedSuppression($statements_analyzer->getFilePath(), $offset, $issue_type);
                        }
                    }
                    $statements_analyzer->addSuppressedIssues($new_issues);
                }
            }
            if (isset($statements_analyzer->parsed_docblock->combined_tags['var']) && !($stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Assign) && !$stmt instanceof PhpParser\Node\Stmt\Foreach_ && !$stmt instanceof PhpParser\Node\Stmt\Return_) {
                $file_path = $statements_analyzer->getRootFilePath();
                $file_storage_provider = $codebase->file_storage_provider;
                $file_storage = $file_storage_provider->get($file_path);
                $template_type_map = $statements_analyzer->getTemplateTypeMap();
                $var_comments = [];
                try {
                    $var_comments = $codebase->config->disable_var_parsing ? [] : \Psalm\Internal\Analyzer\CommentAnalyzer::arrayToDocblocks($docblock, $statements_analyzer->parsed_docblock, $statements_analyzer->getSource(), $statements_analyzer->getAliases(), $template_type_map, $file_storage->type_aliases);
                } catch (IncorrectDocblockException $e) {
                    IssueBuffer::maybeAdd(new MissingDocblockType($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt)));
                } catch (DocblockParseException $e) {
                    IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->getSource(), $stmt)));
                }
                foreach ($var_comments as $var_comment) {
                    AssignmentAnalyzer::assignTypeFromVarDocblock($statements_analyzer, $stmt, $var_comment, $context);
                    if ($var_comment->var_id === '$this' && $var_comment->type && $codebase->classExists((string) $var_comment->type)) {
                        $statements_analyzer->setFQCLN((string) $var_comment->type);
                    }
                }
            }
        } else {
            $statements_analyzer->parsed_docblock = null;
        }
        if ($context->has_returned && !$context->collect_initializations && !$context->collect_mutations && !$stmt instanceof PhpParser\Node\Stmt\Nop && !$stmt instanceof PhpParser\Node\Stmt\Function_ && !$stmt instanceof PhpParser\Node\Stmt\Class_ && !$stmt instanceof PhpParser\Node\Stmt\Interface_ && !$stmt instanceof PhpParser\Node\Stmt\Trait_ && !$stmt instanceof PhpParser\Node\Stmt\HaltCompiler) {
            if ($codebase->find_unused_variables) {
                IssueBuffer::maybeAdd(new UnevaluatedCode('Expressions after return/throw/continue', new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->source->getSuppressedIssues());
            }
            return null;
        }
        if ($stmt instanceof PhpParser\Node\Stmt\If_) {
            if (IfElseAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\TryCatch) {
            if (TryAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\For_) {
            if (ForAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Foreach_) {
            if (ForeachAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\While_) {
            if (WhileAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Do_) {
            if (DoAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Const_) {
            ConstFetchAnalyzer::analyzeConstAssignment($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Unset_) {
            UnsetAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Return_) {
            ReturnAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Throw_) {
            ThrowAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Switch_) {
            SwitchAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Break_) {
            BreakAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Continue_) {
            ContinueAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Static_) {
            StaticAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Echo_) {
            if (EchoAnalyzer::analyze($statements_analyzer, $stmt, $context) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Function_) {
            \Psalm\Internal\Analyzer\FunctionAnalyzer::analyzeStatement($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Expression) {
            if (ExpressionAnalyzer::analyze($statements_analyzer, $stmt->expr, $context, \false, $global_context, \true) === \false) {
                return \false;
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\InlineHTML) {
            // do nothing
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Global_) {
            GlobalAnalyzer::analyze($statements_analyzer, $stmt, $context, $global_context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Property) {
            InstancePropertyAssignmentAnalyzer::analyzeStatement($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\ClassConst) {
            ClassConstAnalyzer::analyzeAssignment($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Class_) {
            try {
                $class_analyzer = new \Psalm\Internal\Analyzer\ClassAnalyzer($stmt, $statements_analyzer->source, $stmt->name->name ?? null);
                $class_analyzer->analyze(null, $global_context);
            } catch (InvalidArgumentException $e) {
                // disregard this exception, we'll likely see it elsewhere in the form
                // of an issue
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Trait_) {
            \Psalm\Internal\Analyzer\TraitAnalyzer::analyze($statements_analyzer, $stmt, $context);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Nop) {
            // do nothing
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Goto_) {
            // do nothing
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Label) {
            // do nothing
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Declare_) {
            foreach ($stmt->declares as $declaration) {
                if ((string) $declaration->key === 'strict_types' && $declaration->value instanceof PhpParser\Node\Scalar\LNumber && $declaration->value->value === 1) {
                    $context->strict_types = \true;
                }
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\HaltCompiler) {
            $context->has_returned = \true;
        } else {
            if (IssueBuffer::accepts(new UnrecognizedStatement('Psalm does not understand ' . get_class($stmt), new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->getSuppressedIssues())) {
                return \false;
            }
        }
        if (self::dispatchAfterStatementAnalysis($stmt, $context, $statements_analyzer) === \false) {
            return \false;
        }
        if ($new_issues) {
            $statements_analyzer->removeSuppressedIssues($new_issues);
        }
        if ($ignore_variable_property) {
            $context->ignore_variable_property = \false;
        }
        if ($ignore_variable_method) {
            $context->ignore_variable_method = \false;
        }
        foreach ($traced_variables as $traced_variable) {
            if (isset($context->vars_in_scope[$traced_variable])) {
                IssueBuffer::maybeAdd(new Trace($traced_variable . ': ' . $context->vars_in_scope[$traced_variable]->getId(), new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->getSuppressedIssues());
            } else {
                IssueBuffer::maybeAdd(new UndefinedTrace('Attempt to trace undefined variable ' . $traced_variable, new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->getSuppressedIssues());
            }
        }
        foreach ($checked_types as [$check_type_line, $is_exact]) {
            [$checked_var, $check_type_string] = array_map('trim', explode('=', $check_type_line));
            if ($check_type_string === '') {
                IssueBuffer::maybeAdd(new InvalidDocblock("Invalid format for @psalm-check-type" . ($is_exact ? "-exact" : ""), new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->getSuppressedIssues());
            } else {
                $checked_var_id = $checked_var;
                $possibly_undefined = strrpos($checked_var_id, "?") === strlen($checked_var_id) - 1;
                if ($possibly_undefined) {
                    $checked_var_id = substr($checked_var_id, 0, strlen($checked_var_id) - 1);
                }
                if (!isset($context->vars_in_scope[$checked_var_id])) {
                    IssueBuffer::maybeAdd(new InvalidDocblock("Attempt to check undefined variable {$checked_var_id}", new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->getSuppressedIssues());
                } else {
                    try {
                        $checked_type = $context->vars_in_scope[$checked_var_id];
                        $check_type = Type::parseString($check_type_string);
                        /** @psalm-suppress InaccessibleProperty We just created this type */
                        $check_type->possibly_undefined = $possibly_undefined;
                        if ($check_type->possibly_undefined !== $checked_type->possibly_undefined || !UnionTypeComparator::isContainedBy($codebase, $checked_type, $check_type) || $is_exact && !UnionTypeComparator::isContainedBy($codebase, $check_type, $checked_type)) {
                            $check_var = $checked_var_id . ($checked_type->possibly_undefined ? "?" : "");
                            IssueBuffer::maybeAdd(new CheckType("Checked variable {$checked_var} = {$check_type->getId()} does not match " . "{$check_var} = {$checked_type->getId()}", new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->getSuppressedIssues());
                        }
                    } catch (TypeParseTreeException $e) {
                        IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($statements_analyzer->source, $stmt)), $statements_analyzer->getSuppressedIssues());
                    }
                }
            }
        }
        return null;
    }
    private static function dispatchAfterStatementAnalysis(PhpParser\Node\Stmt $stmt, Context $context, \Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer) : ?bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $event = new AfterStatementAnalysisEvent($stmt, $context, $statements_analyzer, $codebase, []);
        if ($codebase->config->eventDispatcher->dispatchAfterStatementAnalysis($event) === \false) {
            return \false;
        }
        $file_manipulations = $event->getFileReplacements();
        if ($file_manipulations) {
            FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
        }
        return null;
    }
    private static function dispatchBeforeStatementAnalysis(PhpParser\Node\Stmt $stmt, Context $context, \Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer) : ?bool
    {
        $codebase = $statements_analyzer->getCodebase();
        $event = new BeforeStatementAnalysisEvent($stmt, $context, $statements_analyzer, $codebase, []);
        if ($codebase->config->eventDispatcher->dispatchBeforeStatementAnalysis($event) === \false) {
            return \false;
        }
        $file_manipulations = $event->getFileReplacements();
        if ($file_manipulations) {
            FileManipulationBuffer::add($statements_analyzer->getFilePath(), $file_manipulations);
        }
        return null;
    }
    private function parseStatementDocblock(PhpParser\Comment\Doc $docblock, PhpParser\Node\Stmt $stmt, Context $context) : void
    {
        $codebase = $this->getCodebase();
        try {
            $this->parsed_docblock = DocComment::parsePreservingLength($docblock);
        } catch (DocblockParseException $e) {
            IssueBuffer::maybeAdd(new InvalidDocblock($e->getMessage(), new CodeLocation($this->getSource(), $stmt, null, \true)));
            $this->parsed_docblock = null;
        }
        $comments = $this->parsed_docblock;
        if (isset($comments->tags['psalm-scope-this'])) {
            $trimmed = trim(reset($comments->tags['psalm-scope-this']));
            $trimmed = ltrim($trimmed, '\\');
            if (!$codebase->classExists($trimmed)) {
                IssueBuffer::maybeAdd(new UndefinedDocblockClass('Scope class ' . $trimmed . ' does not exist', new CodeLocation($this->getSource(), $stmt, null, \true), $trimmed));
            } else {
                $this_type = Type::parseString($trimmed);
                $context->self = $trimmed;
                $context->vars_in_scope['$this'] = $this_type;
                $this->setFQCLN($trimmed);
            }
        }
    }
    /**
     * @param  array<PhpParser\Node\Stmt>   $stmts
     */
    public function checkUnreferencedVars(array $stmts, Context $context) : void
    {
        $source = $this->getSource();
        $codebase = $source->getCodebase();
        $function_storage = $source instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer ? $source->getFunctionLikeStorage($this) : null;
        $var_list = array_column($this->unused_var_locations, 0);
        $loc_list = array_column($this->unused_var_locations, 1);
        $project_analyzer = $this->getProjectAnalyzer();
        $unused_var_remover = new UnusedAssignmentRemover();
        if ($this->data_flow_graph instanceof VariableUseGraph && $codebase->config->limit_method_complexity && $source instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer && !$source instanceof \Psalm\Internal\Analyzer\ClosureAnalyzer && $function_storage && $function_storage->location) {
            [$count, , $unique_destinations, $mean] = $this->data_flow_graph->getEdgeStats();
            $average_destination_branches_converging = $unique_destinations > 0 ? $count / $unique_destinations : 0;
            if ($count > $codebase->config->max_graph_size && $mean > $codebase->config->max_avg_path_length && $average_destination_branches_converging > 1.1) {
                if ($source instanceof \Psalm\Internal\Analyzer\FunctionAnalyzer) {
                    IssueBuffer::maybeAdd(new ComplexFunction('This function’s complexity is greater than the project limit' . ' (method graph size = ' . $count . ', average path length = ' . round($mean) . ')', $function_storage->location), $this->getSuppressedIssues());
                } elseif ($source instanceof \Psalm\Internal\Analyzer\MethodAnalyzer) {
                    IssueBuffer::maybeAdd(new ComplexMethod('This method’s complexity is greater than the project limit' . ' (method graph size = ' . $count . ', average path length = ' . round($mean) . ')', $function_storage->location), $this->getSuppressedIssues());
                }
            }
        }
        foreach ($this->unused_var_locations as [$var_id, $original_location]) {
            if (strpos($var_id, '$_') === 0) {
                continue;
            }
            if ($function_storage) {
                $param_index = array_search(substr($var_id, 1), array_keys($function_storage->param_lookup));
                if ($param_index !== \false) {
                    $param = $function_storage->params[$param_index];
                    if ($param->location && ($original_location->raw_file_end === $param->location->raw_file_end || $param->by_ref)) {
                        continue;
                    }
                }
            }
            $assignment_node = DataFlowNode::getForAssignment($var_id, $original_location);
            if (!isset($this->byref_uses[$var_id]) && !isset($context->referenced_globals[$var_id]) && !VariableFetchAnalyzer::isSuperGlobal($var_id) && $this->data_flow_graph instanceof VariableUseGraph && !$this->data_flow_graph->isVariableUsed($assignment_node)) {
                $is_foreach_var = \false;
                if (isset($this->foreach_var_locations[$var_id])) {
                    foreach ($this->foreach_var_locations[$var_id] as $location) {
                        if ($location->raw_file_start === $original_location->raw_file_start) {
                            $is_foreach_var = \true;
                            break;
                        }
                    }
                }
                if ($is_foreach_var) {
                    $issue = new UnusedForeachValue($var_id . ' is never referenced or the value is not used', $original_location);
                } else {
                    $issue = new UnusedVariable($var_id . ' is never referenced or the value is not used', $original_location);
                }
                if ($codebase->alter_code && $issue instanceof UnusedVariable && !$unused_var_remover->checkIfVarRemoved($var_id, $original_location) && isset($project_analyzer->getIssuesToFix()['UnusedVariable']) && !IssueBuffer::isSuppressed($issue, $this->getSuppressedIssues())) {
                    $unused_var_remover->findUnusedAssignment($this->getCodebase(), $stmts, array_combine($var_list, $loc_list), $var_id, $original_location);
                }
                IssueBuffer::maybeAdd($issue, $this->getSuppressedIssues(), $issue instanceof UnusedVariable);
            }
        }
    }
    public function hasVariable(string $var_name) : bool
    {
        return isset($this->all_vars[$var_name]);
    }
    public function registerVariable(string $var_id, CodeLocation $location, ?int $branch_point) : void
    {
        $this->all_vars[$var_id] = $location;
        if ($branch_point) {
            $this->var_branch_points[$var_id] = $branch_point;
        }
        $this->registerVariableAssignment($var_id, $location);
    }
    public function registerVariableAssignment(string $var_id, CodeLocation $location) : void
    {
        $this->unused_var_locations[$location->getHash()] = [$var_id, $location];
    }
    /**
     * @return array<string, array{0: string, 1: CodeLocation}>
     */
    public function getUnusedVarLocations() : array
    {
        return $this->unused_var_locations;
    }
    public function registerPossiblyUndefinedVariable(string $undefined_var_id, PhpParser\Node\Expr\Variable $stmt) : void
    {
        if (!$this->data_flow_graph) {
            return;
        }
        $use_location = new CodeLocation($this->getSource(), $stmt);
        $use_node = DataFlowNode::getForAssignment($undefined_var_id, $use_location);
        $stmt_type = $this->node_data->getType($stmt);
        if ($stmt_type) {
            $stmt_type = $stmt_type->addParentNodes([$use_node->id => $use_node]);
            $this->node_data->setType($stmt, $stmt_type);
        }
        foreach ($this->unused_var_locations as [$var_id, $original_location]) {
            if ($var_id === $undefined_var_id) {
                $parent_node = DataFlowNode::getForAssignment($var_id, $original_location);
                $this->data_flow_graph->addPath($parent_node, $use_node, '=');
            }
        }
    }
    /**
     * @return array<string, DataFlowNode>
     */
    public function getParentNodesForPossiblyUndefinedVariable(string $undefined_var_id) : array
    {
        if (!$this->data_flow_graph) {
            return [];
        }
        $parent_nodes = [];
        foreach ($this->unused_var_locations as [$var_id, $original_location]) {
            if ($var_id === $undefined_var_id) {
                $assignment_node = DataFlowNode::getForAssignment($var_id, $original_location);
                $parent_nodes[$assignment_node->id] = $assignment_node;
            }
        }
        return $parent_nodes;
    }
    /**
     * The first appearance of the variable in this set of statements being evaluated
     */
    public function getFirstAppearance(string $var_id) : ?CodeLocation
    {
        return $this->all_vars[$var_id] ?? null;
    }
    public function getBranchPoint(string $var_id) : ?int
    {
        return $this->var_branch_points[$var_id] ?? null;
    }
    public function addVariableInitialization(string $var_id, int $branch_point) : void
    {
        $this->vars_to_initialize[$var_id] = $branch_point;
    }
    public function getFileAnalyzer() : \Psalm\Internal\Analyzer\FileAnalyzer
    {
        return $this->file_analyzer;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return array<string, FunctionAnalyzer>
     */
    public function getFunctionAnalyzers() : array
    {
        return $this->function_analyzers;
    }
    /**
     * @param array<string, true> $byref_uses
     */
    public function setByRefUses(array $byref_uses) : void
    {
        $this->byref_uses = $byref_uses;
    }
    /**
     * @return array<string, array<array-key, CodeLocation>>
     */
    public function getUncaughtThrows(Context $context) : array
    {
        $uncaught_throws = [];
        if ($context->collect_exceptions) {
            if ($context->possibly_thrown_exceptions) {
                $config = $this->codebase->config;
                $ignored_exceptions = array_change_key_case($context->is_global ? $config->ignored_exceptions_in_global_scope : $config->ignored_exceptions);
                $ignored_exceptions_and_descendants = array_change_key_case($context->is_global ? $config->ignored_exceptions_and_descendants_in_global_scope : $config->ignored_exceptions_and_descendants);
                foreach ($context->possibly_thrown_exceptions as $possibly_thrown_exception => $codelocations) {
                    if (isset($ignored_exceptions[strtolower($possibly_thrown_exception)])) {
                        continue;
                    }
                    $is_expected = \false;
                    foreach ($ignored_exceptions_and_descendants as $expected_exception => $_) {
                        try {
                            if ($expected_exception === strtolower($possibly_thrown_exception) || $this->codebase->classExtends($possibly_thrown_exception, $expected_exception) || $this->codebase->interfaceExtends($possibly_thrown_exception, $expected_exception)) {
                                $is_expected = \true;
                                break;
                            }
                        } catch (InvalidArgumentException $e) {
                            $is_expected = \true;
                            break;
                        }
                    }
                    if (!$is_expected) {
                        $uncaught_throws[$possibly_thrown_exception] = $codelocations;
                    }
                }
            }
        }
        return $uncaught_throws;
    }
    public function getFunctionAnalyzer(string $function_id) : ?\Psalm\Internal\Analyzer\FunctionAnalyzer
    {
        return $this->function_analyzers[$function_id] ?? null;
    }
    public function getParsedDocblock() : ?ParsedDocblock
    {
        return $this->parsed_docblock;
    }
    /** @psalm-mutation-free */
    public function getFQCLN() : ?string
    {
        if ($this->fake_this_class) {
            return $this->fake_this_class;
        }
        return parent::getFQCLN();
    }
    public function setFQCLN(string $fake_this_class) : void
    {
        $this->fake_this_class = $fake_this_class;
    }
    /**
     * @return NodeDataProvider
     */
    public function getNodeTypeProvider() : NodeTypeProvider
    {
        return $this->node_data;
    }
    public function getFullyQualifiedFunctionMethodOrNamespaceName() : ?string
    {
        if ($this->source instanceof \Psalm\Internal\Analyzer\MethodAnalyzer) {
            $fqcn = $this->getFQCLN();
            $method_name = $this->source->getFunctionLikeStorage($this)->cased_name;
            assert($fqcn !== null && $method_name !== null);
            return "{$fqcn}::{$method_name}";
        }
        if ($this->source instanceof \Psalm\Internal\Analyzer\FunctionAnalyzer) {
            $namespace = $this->getNamespace();
            $namespace = $namespace === "" ? "" : "{$namespace}\\";
            $function_name = $this->source->getFunctionLikeStorage($this)->cased_name;
            assert($function_name !== null);
            return "{$namespace}{$function_name}";
        }
        return $this->getNamespace();
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Clause;
use Psalm\Issue\ParadoxicalCondition;
use Psalm\Issue\RedundantCondition;
use Psalm\IssueBuffer;
use Psalm\Storage\Assertion\InArray;
use Psalm\Storage\Assertion\NotInArray;
use function array_intersect_key;
use function count;
use function implode;
/**
 * @internal
 */
class AlgebraAnalyzer
{
    /**
     * This looks to see if there are any clauses in one formula that contradict
     * clauses in another formula, or clauses that duplicate previous clauses
     *
     * e.g.
     * if ($a) { }
     * elseif ($a) { }
     *
     * @param  list<Clause>   $formula_1
     * @param  list<Clause>   $formula_2
     * @param  array<string, int>  $new_assigned_var_ids
     */
    public static function checkForParadox(array $formula_1, array $formula_2, \Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, PhpParser\Node $stmt, array $new_assigned_var_ids) : void
    {
        try {
            $negated_formula2 = Algebra::negateFormula($formula_2);
        } catch (ComplicatedExpressionException $e) {
            return;
        }
        $formula_1_hashes = [];
        foreach ($formula_1 as $formula_1_clause) {
            $formula_1_hashes[$formula_1_clause->hash] = \true;
        }
        $formula_2_hashes = [];
        foreach ($formula_2 as $formula_2_clause) {
            $hash = $formula_2_clause->hash;
            if (!$formula_2_clause->generated && !$formula_2_clause->wedge && $formula_2_clause->reconcilable && (isset($formula_1_hashes[$hash]) || isset($formula_2_hashes[$hash])) && !array_intersect_key($new_assigned_var_ids, $formula_2_clause->possibilities)) {
                IssueBuffer::maybeAdd(new RedundantCondition($formula_2_clause . ' has already been asserted', new CodeLocation($statements_analyzer, $stmt), 'already asserted ' . $formula_2_clause), $statements_analyzer->getSuppressedIssues());
            }
            $formula_2_hashes[$hash] = \true;
        }
        // remove impossible types
        foreach ($negated_formula2 as $negated_clause_2) {
            if (!$negated_clause_2->reconcilable || $negated_clause_2->wedge) {
                continue;
            }
            foreach ($formula_1 as $clause_1) {
                if ($negated_clause_2 === $clause_1 || !$clause_1->reconcilable || $clause_1->wedge) {
                    continue;
                }
                $negated_clause_2_contains_1_possibilities = \true;
                foreach ($clause_1->possibilities as $key => $keyed_possibilities) {
                    if (!isset($negated_clause_2->possibilities[$key])) {
                        $negated_clause_2_contains_1_possibilities = \false;
                        break;
                    }
                    if ($negated_clause_2->possibilities[$key] != $keyed_possibilities) {
                        $negated_clause_2_contains_1_possibilities = \false;
                        break;
                    }
                    foreach ($keyed_possibilities as $possibility) {
                        if ($possibility instanceof InArray || $possibility instanceof NotInArray) {
                            $negated_clause_2_contains_1_possibilities = \false;
                            break;
                        }
                    }
                }
                if ($negated_clause_2_contains_1_possibilities) {
                    $mini_formula_2 = Algebra::negateFormula([$negated_clause_2]);
                    if (!$mini_formula_2[0]->wedge) {
                        if (count($mini_formula_2) > 1) {
                            $paradox_message = 'Condition ((' . implode(') && (', $mini_formula_2) . '))' . ' contradicts a previously-established condition (' . $clause_1 . ')';
                        } else {
                            $paradox_message = 'Condition (' . $mini_formula_2[0] . ')' . ' contradicts a previously-established condition (' . $clause_1 . ')';
                        }
                    } else {
                        $paradox_message = 'Condition not(' . $negated_clause_2 . ')' . ' contradicts a previously-established condition (' . $clause_1 . ')';
                    }
                    IssueBuffer::maybeAdd(new ParadoxicalCondition($paradox_message, new CodeLocation($statements_analyzer, $stmt)), $statements_analyzer->getSuppressedIssues());
                    return;
                }
            }
        }
    }
}
<?php

namespace Psalm\Internal\Analyzer\FunctionLike;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeTraverser;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer;
use Psalm\Internal\PhpVisitor\YieldTypeCollector;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function array_merge;
/**
 * A class for analysing a given method call's effects in relation to $this/self and also looking at return types
 *
 * @internal
 */
class ReturnTypeCollector
{
    /**
     * Gets the return types from a list of statements
     *
     * @param  array<PhpParser\Node>     $stmts
     * @param  list<Union>               $yield_types
     * @return list<Union>               a list of return types
     * @psalm-suppress ComplexMethod to be refactored
     */
    public static function getReturnTypes(Codebase $codebase, NodeDataProvider $nodes, array $stmts, array &$yield_types, bool $collapse_types = \false) : array
    {
        $return_types = [];
        foreach ($stmts as $stmt) {
            if ($stmt instanceof PhpParser\Node\Stmt\Return_) {
                if (!$stmt->expr) {
                    $return_types[] = Type::getVoid();
                } elseif ($stmt_type = $nodes->getType($stmt)) {
                    $return_types[] = $stmt_type;
                    $yield_types = array_merge($yield_types, self::getYieldTypeFromExpression($stmt->expr, $nodes));
                } elseif ($stmt->expr instanceof PhpParser\Node\Scalar\String_) {
                    $return_types[] = Type::getString();
                } elseif ($stmt->expr instanceof PhpParser\Node\Scalar\LNumber) {
                    $return_types[] = Type::getInt();
                } elseif ($stmt->expr instanceof PhpParser\Node\Expr\ConstFetch) {
                    if ((string) $stmt->expr->name === 'true') {
                        $return_types[] = Type::getTrue();
                    } elseif ((string) $stmt->expr->name === 'false') {
                        $return_types[] = Type::getFalse();
                    } elseif ((string) $stmt->expr->name === 'null') {
                        $return_types[] = Type::getNull();
                    }
                } else {
                    $return_types[] = Type::getMixed();
                }
                break;
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Break_ || $stmt instanceof PhpParser\Node\Stmt\Continue_) {
                break;
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Throw_) {
                $return_types[] = Type::getNever();
                break;
            }
            if ($stmt instanceof PhpParser\Node\Stmt\Expression) {
                if ($stmt->expr instanceof PhpParser\Node\Expr\Exit_) {
                    $return_types[] = Type::getNever();
                    break;
                }
                if ($stmt->expr instanceof PhpParser\Node\Expr\FuncCall || $stmt->expr instanceof PhpParser\Node\Expr\MethodCall || $stmt->expr instanceof PhpParser\Node\Expr\NullsafeMethodCall || $stmt->expr instanceof PhpParser\Node\Expr\StaticCall) {
                    $stmt_type = $nodes->getType($stmt->expr);
                    if ($stmt_type && ($stmt_type->isNever() || $stmt_type->explicit_never)) {
                        $return_types[] = Type::getNever();
                        break;
                    }
                }
                if ($stmt->expr instanceof PhpParser\Node\Expr\Assign) {
                    $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, [$stmt->expr->expr], $yield_types)];
                }
                $yield_types = array_merge($yield_types, self::getYieldTypeFromExpression($stmt->expr, $nodes));
            } elseif ($stmt instanceof PhpParser\Node\Stmt\If_) {
                $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->stmts, $yield_types)];
                foreach ($stmt->elseifs as $elseif) {
                    $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $elseif->stmts, $yield_types)];
                }
                if ($stmt->else) {
                    $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->else->stmts, $yield_types)];
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\TryCatch) {
                $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->stmts, $yield_types)];
                foreach ($stmt->catches as $catch) {
                    $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $catch->stmts, $yield_types)];
                }
                if ($stmt->finally) {
                    $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->finally->stmts, $yield_types)];
                }
            } elseif ($stmt instanceof PhpParser\Node\Stmt\For_) {
                $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->stmts, $yield_types)];
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Foreach_) {
                $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->stmts, $yield_types)];
            } elseif ($stmt instanceof PhpParser\Node\Stmt\While_) {
                $yield_types = array_merge($yield_types, self::getYieldTypeFromExpression($stmt->cond, $nodes));
                $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->stmts, $yield_types)];
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Do_) {
                $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $stmt->stmts, $yield_types)];
            } elseif ($stmt instanceof PhpParser\Node\Stmt\Switch_) {
                foreach ($stmt->cases as $case) {
                    $return_types = [...$return_types, ...self::getReturnTypes($codebase, $nodes, $case->stmts, $yield_types)];
                }
            }
        }
        // if we're at the top level and we're not ending in a return, make sure to add possible null
        if ($collapse_types) {
            // if it's a generator, boil everything down to a single generator return type
            if ($yield_types) {
                $yield_types = self::processYieldTypes($codebase, $return_types, $yield_types);
            }
        }
        return $return_types;
    }
    /**
     * @param  list<Union>           $return_types
     * @param  non-empty-list<Union> $yield_types
     * @return non-empty-list<Union>
     */
    private static function processYieldTypes(Codebase $codebase, array $return_types, array $yield_types) : array
    {
        $key_type = null;
        $value_type = null;
        $yield_type = Type::combineUnionTypeArray($yield_types, null);
        foreach ($yield_type->getAtomicTypes() as $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            if ($type instanceof TKeyedArray) {
                $type = $type->getGenericArrayType();
            }
            if ($type instanceof TArray) {
                [$key_type_param, $value_type_param] = $type->type_params;
                $key_type = Type::combineUnionTypes($key_type_param, $key_type);
                $value_type = Type::combineUnionTypes($value_type_param, $value_type);
            } elseif ($type instanceof TIterable || $type instanceof TNamedObject) {
                ForeachAnalyzer::getKeyValueParamsForTraversableObject($type, $codebase, $key_type, $value_type);
            }
        }
        return [new Union([new TGenericObject('Generator', [$key_type ?? Type::getMixed(), $value_type ?? Type::getMixed(), Type::getMixed(), $return_types ? Type::combineUnionTypeArray($return_types, null) : Type::getVoid()])])];
    }
    /**
     * @return list<Union>
     */
    private static function getYieldTypeFromExpression(PhpParser\Node\Expr $stmt, NodeDataProvider $nodes) : array
    {
        $collector = new YieldTypeCollector($nodes);
        $traverser = new NodeTraverser();
        $traverser->addVisitor($collector);
        $traverser->traverse([$stmt]);
        return $collector->getYieldTypes();
    }
}
<?php

namespace Psalm\Internal\Analyzer\FunctionLike;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ArrowFunction;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Closure;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\FunctionLike;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Function_;
use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Context;
use Psalm\Exception\UnresolvableConstantException;
use Psalm\Internal\Analyzer\ClassAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\InterfaceAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\SourceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Call\ClassTemplateParamCollector;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\FileManipulation\FunctionDocblockManipulator;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\ImplicitToStringCast;
use Psalm\Issue\InvalidFalsableReturnType;
use Psalm\Issue\InvalidNullableReturnType;
use Psalm\Issue\InvalidParent;
use Psalm\Issue\InvalidReturnType;
use Psalm\Issue\InvalidToString;
use Psalm\Issue\LessSpecificReturnType;
use Psalm\Issue\MismatchingDocblockReturnType;
use Psalm\Issue\MissingClosureReturnType;
use Psalm\Issue\MissingReturnType;
use Psalm\Issue\MixedInferredReturnType;
use Psalm\Issue\MixedReturnTypeCoercion;
use Psalm\Issue\MoreSpecificReturnType;
use Psalm\Issue\UnresolvableConstant;
use Psalm\IssueBuffer;
use Psalm\StatementsSource;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use function array_diff;
use function array_filter;
use function array_values;
use function count;
use function implode;
use function in_array;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class ReturnTypeAnalyzer
{
    /**
     * @param Closure|Function_|ClassMethod|ArrowFunction $function
     * @param PhpParser\Node\Stmt[] $function_stmts
     * @param string[]            $compatible_method_ids
     * @return  false|null
     * @psalm-suppress PossiblyUnusedReturnValue unused but seems important
     * @psalm-suppress ComplexMethod Unavoidably complex method
     */
    public static function verifyReturnType(FunctionLike $function, array $function_stmts, SourceAnalyzer $source, NodeDataProvider $type_provider, FunctionLikeAnalyzer $function_like_analyzer, ?Union $return_type = null, ?string $fq_class_name = null, ?string $static_fq_class_name = null, ?CodeLocation $return_type_location = null, array $compatible_method_ids = [], bool $did_explicitly_return = \false, bool $closure_inside_call = \false) : ?bool
    {
        $suppressed_issues = $function_like_analyzer->getSuppressedIssues();
        $codebase = $source->getCodebase();
        $project_analyzer = $source->getProjectAnalyzer();
        $function_like_storage = null;
        if ($source instanceof StatementsAnalyzer) {
            $function_like_storage = $function_like_analyzer->getFunctionLikeStorage($source);
        } elseif ($source instanceof ClassAnalyzer || $source instanceof TraitAnalyzer) {
            $function_like_storage = $function_like_analyzer->getFunctionLikeStorage();
        }
        $cased_method_id = $function_like_analyzer->getCorrectlyCasedMethodId();
        if (!$function->getStmts() && ($function instanceof ClassMethod && ($source instanceof InterfaceAnalyzer || $function->isAbstract()))) {
            if (!$return_type) {
                IssueBuffer::maybeAdd(new MissingReturnType('Method ' . $cased_method_id . ' does not have a return type', new CodeLocation($function_like_analyzer, $function->name, null, \true)), $suppressed_issues);
            }
            return null;
        }
        $is_to_string = $function instanceof ClassMethod && strtolower($function->name->name) === '__tostring';
        if ($function instanceof ClassMethod && strpos($function->name->name, '__') === 0 && !$is_to_string && !$return_type) {
            // do not check __construct, __set, __get, __call etc.
            return null;
        }
        if (!$return_type_location) {
            $return_type_location = new CodeLocation($function_like_analyzer, $function instanceof Closure || $function instanceof ArrowFunction ? $function : $function->name);
        }
        $inferred_yield_types = [];
        $inferred_return_type_parts = \Psalm\Internal\Analyzer\FunctionLike\ReturnTypeCollector::getReturnTypes($codebase, $type_provider, $function_stmts, $inferred_yield_types, \true);
        if (!$inferred_return_type_parts) {
            $did_explicitly_return = \true;
        }
        if ((!$return_type || $return_type->from_docblock) && ScopeAnalyzer::getControlActions($function_stmts, $type_provider, []) !== [ScopeAnalyzer::ACTION_END] && !$inferred_yield_types && count($inferred_return_type_parts) && !$did_explicitly_return) {
            // only add null if we have a return statement elsewhere and it wasn't void or never
            foreach ($inferred_return_type_parts as $inferred_return_type_part) {
                if (!$inferred_return_type_part->isVoid() && !$inferred_return_type_part->isNever()) {
                    $atomic_null = new TNull(\true);
                    $inferred_return_type_parts[] = new Union([$atomic_null]);
                    break;
                }
            }
        }
        $control_actions = ScopeAnalyzer::getControlActions($function_stmts, $type_provider, [], \false);
        $function_always_exits = $control_actions === [ScopeAnalyzer::ACTION_END];
        $function_returns_implicitly = (bool) array_diff($control_actions, [ScopeAnalyzer::ACTION_END, ScopeAnalyzer::ACTION_RETURN]);
        /** @psalm-suppress PossiblyUndefinedStringArrayOffset */
        if ($return_type && (!$return_type->from_docblock || $return_type->isNullable() && !$return_type->hasTemplate() && !$return_type->getAtomicTypes()['null']->from_docblock) && !$return_type->isVoid() && !$inferred_yield_types && (!$function_like_storage || !$function_like_storage->has_yield) && $function_returns_implicitly) {
            if (IssueBuffer::accepts(new InvalidReturnType('Not all code paths of ' . $cased_method_id . ' end in a return statement, return type ' . $return_type . ' expected', $return_type_location), $suppressed_issues)) {
                return \false;
            }
            return null;
        }
        if ($return_type && $return_type->isNever() && !$inferred_yield_types && !$function_always_exits) {
            if (IssueBuffer::accepts(new InvalidReturnType($cased_method_id . ' is not expected to return any values but it does, ' . 'either implicitly or explicitly', $return_type_location), $suppressed_issues)) {
                return \false;
            }
            return null;
        }
        // only now after non-implicit things are checked
        if ($function_returns_implicitly) {
            $inferred_return_type_parts[] = Type::getVoid();
        }
        $inferred_return_type_parts_with_never = $inferred_return_type_parts;
        // we filter TNever that have no bearing on the return type
        if (count($inferred_return_type_parts) > 1) {
            $inferred_return_type_parts = array_filter($inferred_return_type_parts, static fn(Union $union_type): bool => !$union_type->isNever());
        }
        $inferred_return_type_parts = array_values($inferred_return_type_parts);
        $inferred_return_type = $inferred_return_type_parts ? Type::combineUnionTypeArray($inferred_return_type_parts, $codebase) : Type::getVoid();
        if ($function_always_exits) {
            $inferred_return_type = Type::getNever();
        }
        // void + never = null, so we need to check this separately
        if (count($inferred_return_type_parts_with_never) > 1 && !$function_always_exits && $inferred_return_type_parts_with_never !== $inferred_return_type_parts) {
            /**
             * see https://github.com/vimeo/psalm/issues/9045
             *
             * @psalm-suppress InvalidArgument
             */
            $inferred_return_type_with_never = Type::combineUnionTypeArray($inferred_return_type_parts_with_never, $codebase);
        } else {
            $inferred_return_type_with_never = $inferred_return_type;
        }
        $inferred_yield_type = $inferred_yield_types ? Type::combineUnionTypeArray($inferred_yield_types, $codebase) : null;
        if ($inferred_yield_type) {
            $inferred_return_type = $inferred_yield_type;
        }
        $unsafe_return_type = \false;
        // prevent any return types that do not return a value from being used in PHP typehints
        if ($codebase->alter_code && $inferred_return_type->isNullable() && !$inferred_yield_types) {
            foreach ($inferred_return_type_parts as $inferred_return_type_part) {
                if ($inferred_return_type_part->isVoid()) {
                    $unsafe_return_type = \true;
                    break;
                }
            }
        }
        $inferred_return_type = TypeExpander::expandUnion($codebase, $inferred_return_type, $source->getFQCLN(), $source->getFQCLN(), $source->getParentFQCLN());
        // hack until we have proper yield type collection
        if ($function_like_storage && $function_like_storage->has_yield && !$inferred_yield_type && !$inferred_return_type->isVoid()) {
            $inferred_return_type = new Union([new TNamedObject('Generator')]);
        }
        if ($is_to_string) {
            $union_comparison_results = new TypeComparisonResult();
            if (!$inferred_return_type->hasMixed() && !UnionTypeComparator::isContainedBy($codebase, $inferred_return_type, Type::getString(), $inferred_return_type->ignore_nullable_issues, $inferred_return_type->ignore_falsable_issues, $union_comparison_results)) {
                if (IssueBuffer::accepts(new InvalidToString('__toString methods must return a string, ' . $inferred_return_type . ' returned', $return_type_location), $suppressed_issues)) {
                    return \false;
                }
            }
            if ($union_comparison_results->to_string_cast) {
                IssueBuffer::maybeAdd(new ImplicitToStringCast('The declared return type for ' . $cased_method_id . ' expects string, ' . '\'' . $inferred_return_type . '\' provided with a __toString method', $return_type_location), $suppressed_issues);
            }
            return null;
        }
        if (!$return_type) {
            if ($function instanceof Closure || $function instanceof ArrowFunction) {
                if (!$closure_inside_call || $inferred_return_type->isMixed()) {
                    if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MissingClosureReturnType']) && !in_array('MissingClosureReturnType', $suppressed_issues)) {
                        if ($inferred_return_type->hasMixed() || $inferred_return_type->isNull()) {
                            return null;
                        }
                        self::addOrUpdateReturnType($function, $project_analyzer, $inferred_return_type, $source, ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock, $function_like_storage);
                        return null;
                    }
                    IssueBuffer::maybeAdd(new MissingClosureReturnType('Closure does not have a return type, expecting ' . $inferred_return_type->getId(), new CodeLocation($function_like_analyzer, $function, null, \true)), $suppressed_issues, !$inferred_return_type->hasMixed() && !$inferred_return_type->isNull());
                }
                return null;
            }
            if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MissingReturnType']) && !in_array('MissingReturnType', $suppressed_issues)) {
                if ($inferred_return_type->hasMixed() || $inferred_return_type->isNull()) {
                    return null;
                }
                self::addOrUpdateReturnType($function, $project_analyzer, $inferred_return_type, $source, $compatible_method_ids || !$did_explicitly_return || ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock, $function_like_storage);
                return null;
            }
            IssueBuffer::maybeAdd(new MissingReturnType('Method ' . $cased_method_id . ' does not have a return type' . (!$inferred_return_type->hasMixed() ? ', expecting ' . $inferred_return_type->getId() : ''), new CodeLocation($function_like_analyzer, $function->name, null, \true)), $suppressed_issues, !$inferred_return_type->hasMixed() && !$inferred_return_type->isNull());
            return null;
        }
        $self_fq_class_name = $fq_class_name ?: $source->getFQCLN();
        $parent_class = null;
        $classlike_storage = null;
        if ($self_fq_class_name) {
            $classlike_storage = $codebase->classlike_storage_provider->get($self_fq_class_name);
            $parent_class = $classlike_storage->parent_class;
        }
        // passing it through fleshOutTypes eradicates errant $ vars
        $declared_return_type = TypeExpander::expandUnion($codebase, $return_type, $self_fq_class_name, $static_fq_class_name, $parent_class, \true, \true, $function_like_storage instanceof MethodStorage && $function_like_storage->final || $classlike_storage && $classlike_storage->final);
        if ((!$inferred_return_type_parts || $inferred_return_type->isVoid() && $function_returns_implicitly && count($inferred_return_type_parts) === 1) && !$inferred_return_type->isNever() && !$inferred_yield_types && (!$function_like_storage || !$function_like_storage->has_yield)) {
            if ($declared_return_type->isVoid() || $declared_return_type->isNever()) {
                return null;
            }
            if (ScopeAnalyzer::onlyThrowsOrExits($type_provider, $function_stmts)) {
                // if there's a single throw statement, it's presumably an exception saying this method is not to be
                // used
                return null;
            }
            if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['InvalidReturnType']) && !in_array('InvalidReturnType', $suppressed_issues)) {
                self::addOrUpdateReturnType($function, $project_analyzer, Type::getVoid(), $source, $compatible_method_ids || ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock);
                return null;
            }
            if (!$declared_return_type->from_docblock || !$declared_return_type->isNullable()) {
                if (IssueBuffer::accepts(new InvalidReturnType('No return statements were found for method ' . $cased_method_id . ' but return type \'' . $declared_return_type . '\' was expected', $return_type_location), $suppressed_issues, \true)) {
                    return \false;
                }
            }
            return null;
        }
        if (!$declared_return_type->hasMixed()) {
            if ($inferred_return_type->isVoid() && ($declared_return_type->isVoid() || $function_like_storage && $function_like_storage->has_yield)) {
                return null;
            }
            if ($inferred_return_type->hasMixed()) {
                if (IssueBuffer::accepts(new MixedInferredReturnType('Could not verify return type \'' . $declared_return_type . '\' for ' . $cased_method_id, $return_type_location), $suppressed_issues)) {
                    return \false;
                }
                return null;
            }
            $union_comparison_results = new TypeComparisonResult();
            if ($declared_return_type->explicit_never === \true && $inferred_return_type_with_never->explicit_never === \false) {
                if (IssueBuffer::accepts(new MoreSpecificReturnType('The declared return type \'' . $declared_return_type->getId() . '|never\' for ' . $cased_method_id . ' is more specific than the inferred return type ' . '\'' . $inferred_return_type->getId() . '\'', $return_type_location), $suppressed_issues)) {
                    return \false;
                }
            }
            if (!$declared_return_type->isNever() && $function_always_exits && ($declared_return_type->from_docblock || $codebase->analysis_php_version_id >= 81000) && !ScopeAnalyzer::onlyThrows($function_stmts)) {
                if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['InvalidReturnType']) && !in_array('InvalidReturnType', $suppressed_issues)) {
                    self::addOrUpdateReturnType($function, $project_analyzer, Type::getNever(), $source, ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock, $function_like_storage);
                    return null;
                }
                if (IssueBuffer::accepts(new InvalidReturnType('The declared return type \'' . $declared_return_type->getId() . '\' for ' . $cased_method_id . ' is incorrect, got \'never\'', $return_type_location), $suppressed_issues, \true)) {
                    return \false;
                }
            }
            if (!UnionTypeComparator::isContainedBy($codebase, $inferred_return_type, $declared_return_type, \true, \true, $union_comparison_results)) {
                // is the declared return type more specific than the inferred one?
                if ($union_comparison_results->type_coerced) {
                    if ($union_comparison_results->type_coerced_from_mixed) {
                        if (!$union_comparison_results->type_coerced_from_as_mixed) {
                            if (IssueBuffer::accepts(new MixedReturnTypeCoercion('The declared return type \'' . $declared_return_type->getId() . '\' for ' . $cased_method_id . ' is more specific than the inferred return type ' . '\'' . $inferred_return_type->getId() . '\'', $return_type_location), $suppressed_issues)) {
                                return \false;
                            }
                        }
                    } else {
                        if (IssueBuffer::accepts(new MoreSpecificReturnType('The declared return type \'' . $declared_return_type->getId() . '\' for ' . $cased_method_id . ' is more specific than the inferred return type ' . '\'' . $inferred_return_type->getId() . '\'', $return_type_location), $suppressed_issues)) {
                            return \false;
                        }
                    }
                } elseif (($declared_return_type->explicit_never === \false || !$declared_return_type->isNull()) && (!$declared_return_type->isNullable() || $parent_class === null && $self_fq_class_name === $source->getFQCLN())) {
                    if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['InvalidReturnType']) && !in_array('InvalidReturnType', $suppressed_issues)) {
                        self::addOrUpdateReturnType($function, $project_analyzer, $inferred_return_type, $source, ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock, $function_like_storage);
                        return null;
                    }
                    if (IssueBuffer::accepts(new InvalidReturnType('The declared return type \'' . $declared_return_type->getId() . '\' for ' . $cased_method_id . ' is incorrect, got \'' . $inferred_return_type->getId() . '\'' . ($union_comparison_results->missing_shape_fields ? ' which is different due to additional array shape fields (' . implode(', ', $union_comparison_results->missing_shape_fields) . ')' : ''), $return_type_location), $suppressed_issues, \true)) {
                        return \false;
                    }
                }
            } elseif (!UnionTypeComparator::isContainedBy($codebase, $declared_return_type, $inferred_return_type, \false, \false)) {
                if ($codebase->alter_code) {
                    if (isset($project_analyzer->getIssuesToFix()['LessSpecificReturnType']) && !in_array('LessSpecificReturnType', $suppressed_issues) && !($function_like_storage instanceof MethodStorage && $function_like_storage->inheritdoc)) {
                        self::addOrUpdateReturnType($function, $project_analyzer, $inferred_return_type, $source, $compatible_method_ids || ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock, $function_like_storage);
                    }
                } else {
                    if ($function instanceof Function_ || $function instanceof Closure || $function instanceof ArrowFunction || $function->isPrivate()) {
                        $check_for_less_specific_type = \true;
                    } elseif ($source instanceof StatementsAnalyzer) {
                        if ($function_like_storage instanceof MethodStorage) {
                            $check_for_less_specific_type = !$function_like_storage->overridden_somewhere;
                        } else {
                            $check_for_less_specific_type = \false;
                        }
                    } else {
                        $check_for_less_specific_type = \false;
                    }
                    if ($check_for_less_specific_type && (Config::getInstance()->restrict_return_types || !$inferred_return_type->isNullable() && $declared_return_type->isNullable() || !$inferred_return_type->isFalsable() && $declared_return_type->isFalsable())) {
                        if (IssueBuffer::accepts(new LessSpecificReturnType('The inferred return type \'' . $inferred_return_type->getId() . '\' for ' . $cased_method_id . ' is more specific than the declared return type \'' . $declared_return_type->getId() . '\'', $return_type_location), $suppressed_issues, !($function_like_storage instanceof MethodStorage && $function_like_storage->inheritdoc))) {
                            return \false;
                        }
                    }
                }
            }
            if ($union_comparison_results->to_string_cast) {
                IssueBuffer::maybeAdd(new ImplicitToStringCast('The declared return type for ' . $cased_method_id . ' expects \'' . $declared_return_type . '\', ' . '\'' . $inferred_return_type . '\' provided with a __toString method', $return_type_location), $suppressed_issues);
            }
            if (!$inferred_return_type->ignore_nullable_issues && $inferred_return_type->isNullable() && !$declared_return_type->isNullable() && !$declared_return_type->hasTemplate() && !$declared_return_type->isVoid()) {
                if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['InvalidNullableReturnType']) && !in_array('InvalidNullableReturnType', $suppressed_issues) && !$inferred_return_type->isNull()) {
                    self::addOrUpdateReturnType($function, $project_analyzer, $inferred_return_type, $source, ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock, $function_like_storage);
                    return null;
                }
                if (IssueBuffer::accepts(new InvalidNullableReturnType('The declared return type \'' . $declared_return_type . '\' for ' . $cased_method_id . ' is not nullable, but \'' . $inferred_return_type . '\' contains null', $return_type_location), $suppressed_issues, !$inferred_return_type->isNull())) {
                    return \false;
                }
            }
            if (!$inferred_return_type->ignore_falsable_issues && $inferred_return_type->isFalsable() && !$declared_return_type->isFalsable() && !$declared_return_type->hasBool() && !$declared_return_type->hasScalar()) {
                if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['InvalidFalsableReturnType'])) {
                    self::addOrUpdateReturnType($function, $project_analyzer, $inferred_return_type, $source, ($project_analyzer->only_replace_php_types_with_non_docblock_types || $unsafe_return_type) && $inferred_return_type->from_docblock, $function_like_storage);
                    return null;
                }
                if (IssueBuffer::accepts(new InvalidFalsableReturnType('The declared return type \'' . $declared_return_type . '\' for ' . $cased_method_id . ' does not allow false, but \'' . $inferred_return_type . '\' contains false', $return_type_location), $suppressed_issues, \true)) {
                    return \false;
                }
            }
        }
        return null;
    }
    /**
     * @param Closure|Function_|ClassMethod|ArrowFunction $function
     * @return false|null
     */
    public static function checkReturnType(FunctionLike $function, ProjectAnalyzer $project_analyzer, FunctionLikeAnalyzer $function_like_analyzer, FunctionLikeStorage $storage, Context $context) : ?bool
    {
        $codebase = $project_analyzer->getCodebase();
        if (!$storage->return_type || !$storage->return_type_location) {
            return null;
        }
        $parent_class = null;
        $classlike_storage = null;
        if ($context->self) {
            $classlike_storage = $codebase->classlike_storage_provider->get($context->self);
            $parent_class = $classlike_storage->parent_class;
        }
        if (!$storage->signature_return_type || $storage->signature_return_type === $storage->return_type) {
            foreach ($storage->return_type->getAtomicTypes() as $type) {
                if ($type instanceof TNamedObject && 'parent' === $type->value && null === $parent_class) {
                    if (IssueBuffer::accepts(new InvalidParent('Cannot use parent as a return type when class has no parent', $storage->return_type_location), $storage->suppressed_issues)) {
                        return \false;
                    }
                    return null;
                }
            }
            $fleshed_out_return_type = TypeExpander::expandUnion($codebase, $storage->return_type, $classlike_storage->name ?? null, $classlike_storage->name ?? null, $parent_class);
            /** @psalm-suppress UnusedMethodCall This call actually has the side effect of creating issues */
            $fleshed_out_return_type->check($function_like_analyzer, $storage->return_type_location, $storage->suppressed_issues, [], \false, \false, \false, $context->calling_method_id);
            return null;
        }
        $fleshed_out_signature_type = TypeExpander::expandUnion($codebase, $storage->signature_return_type, $classlike_storage->name ?? null, $classlike_storage->name ?? null, $parent_class);
        if ($fleshed_out_signature_type->check($function_like_analyzer, $storage->signature_return_type_location ?: $storage->return_type_location, $storage->suppressed_issues, [], \false) === \false) {
            return \false;
        }
        if ($function instanceof Closure || $function instanceof ArrowFunction) {
            return null;
        }
        try {
            $fleshed_out_return_type = TypeExpander::expandUnion($codebase, $storage->return_type, $classlike_storage->name ?? null, $classlike_storage->name ?? null, $parent_class, \true, \true, \false, \false, \false, \true);
        } catch (UnresolvableConstantException $e) {
            IssueBuffer::maybeAdd(new UnresolvableConstant("Could not resolve constant {$e->class_name}::{$e->const_name}", $storage->return_type_location), $storage->suppressed_issues, \true);
            $fleshed_out_return_type = $storage->return_type;
        }
        if ($fleshed_out_return_type->check($function_like_analyzer, $storage->return_type_location, $storage->suppressed_issues, [], \false, $storage instanceof MethodStorage && $storage->inherited_return_type) === \false) {
            return \false;
        }
        if ($classlike_storage && $context->self) {
            $class_template_params = ClassTemplateParamCollector::collect($codebase, $classlike_storage, $codebase->classlike_storage_provider->get($context->self), strtolower($function->name->name), new TNamedObject($context->self), \true);
            $class_template_params = $class_template_params ?: [];
            if ($class_template_params) {
                $template_result = new TemplateResult($class_template_params, []);
                $fleshed_out_return_type = TemplateStandinTypeReplacer::replace($fleshed_out_return_type, $template_result, $codebase, null, null, null);
            }
        }
        $union_comparison_result = new TypeComparisonResult();
        if (!UnionTypeComparator::isContainedBy($codebase, $fleshed_out_return_type, $fleshed_out_signature_type, \false, \false, $union_comparison_result) && !$union_comparison_result->type_coerced_from_mixed) {
            if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MismatchingDocblockReturnType'])) {
                self::addOrUpdateReturnType($function, $project_analyzer, $storage->signature_return_type, $function_like_analyzer->getSource());
                return null;
            }
            if (IssueBuffer::accepts(new MismatchingDocblockReturnType('Docblock has incorrect return type \'' . $storage->return_type->getId() . '\', should be \'' . $storage->signature_return_type->getId() . '\'', $storage->return_type_location), $storage->suppressed_issues, \true)) {
                return \false;
            }
        }
        return null;
    }
    /**
     * @param Closure|Function_|ClassMethod|ArrowFunction $function
     */
    private static function addOrUpdateReturnType(FunctionLike $function, ProjectAnalyzer $project_analyzer, Union $inferred_return_type, StatementsSource $source, bool $docblock_only = \false, ?FunctionLikeStorage $function_like_storage = null) : void
    {
        $manipulator = FunctionDocblockManipulator::getForFunction($project_analyzer, $source->getFilePath(), $function);
        $codebase = $project_analyzer->getCodebase();
        $is_final = \true;
        $fqcln = $source->getFQCLN();
        if ($fqcln !== null && $function instanceof ClassMethod) {
            $class_storage = $codebase->classlike_storage_provider->get($fqcln);
            $is_final = $function->isFinal() || $class_storage->final;
        }
        $allow_native_type = !$docblock_only && $codebase->analysis_php_version_id >= 70000 && ($codebase->allow_backwards_incompatible_changes || $is_final || !$function instanceof PhpParser\Node\Stmt\ClassMethod);
        $manipulator->setReturnType($allow_native_type ? (string) $inferred_return_type->toPhpString($source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), $codebase->analysis_php_version_id) : null, $inferred_return_type->toNamespacedString($source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), \false), $inferred_return_type->toNamespacedString($source->getNamespace(), $source->getAliasedClassesFlipped(), $source->getFQCLN(), \true), $inferred_return_type->canBeFullyExpressedInPhp($codebase->analysis_php_version_id), $function_like_storage->return_type_description ?? null);
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\PhpVisitor\ShortClosureVisitor;
use Psalm\Issue\DuplicateParam;
use Psalm\Issue\PossiblyUndefinedVariable;
use Psalm\Issue\UndefinedVariable;
use Psalm\IssueBuffer;
use Psalm\Type;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function in_array;
use function is_string;
use function preg_match;
use function strpos;
use function strtolower;
/**
 * @internal
 * @extends FunctionLikeAnalyzer<PhpParser\Node\Expr\Closure|PhpParser\Node\Expr\ArrowFunction>
 */
class ClosureAnalyzer extends \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
{
    /**
     * @param PhpParser\Node\Expr\Closure|PhpParser\Node\Expr\ArrowFunction $function
     */
    public function __construct(PhpParser\Node\FunctionLike $function, \Psalm\Internal\Analyzer\SourceAnalyzer $source)
    {
        $codebase = $source->getCodebase();
        $function_id = strtolower($source->getFilePath()) . ':' . $function->getLine() . ':' . (int) $function->getAttribute('startFilePos') . ':-:closure';
        $storage = $codebase->getClosureStorage($source->getFilePath(), $function_id);
        parent::__construct($function, $source, $storage);
    }
    /** @psalm-mutation-free */
    public function getTemplateTypeMap() : ?array
    {
        return $this->source->getTemplateTypeMap();
    }
    /**
     * @return non-empty-lowercase-string
     */
    public function getClosureId() : string
    {
        return strtolower($this->getFilePath()) . ':' . $this->function->getLine() . ':' . (int) $this->function->getAttribute('startFilePos') . ':-:closure';
    }
    /**
     * @param PhpParser\Node\Expr\Closure|PhpParser\Node\Expr\ArrowFunction $stmt
     */
    public static function analyzeExpression(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, PhpParser\Node\FunctionLike $stmt, Context $context) : bool
    {
        $closure_analyzer = new \Psalm\Internal\Analyzer\ClosureAnalyzer($stmt, $statements_analyzer);
        if ($stmt instanceof PhpParser\Node\Expr\Closure && self::analyzeClosureUses($statements_analyzer, $stmt, $context) === \false) {
            return \false;
        }
        $use_context = new Context($context->self);
        $codebase = $statements_analyzer->getCodebase();
        if (!$statements_analyzer->isStatic() && !$closure_analyzer->isStatic()) {
            if ($context->collect_mutations && $context->self && $codebase->classExtends($context->self, (string) $statements_analyzer->getFQCLN())) {
                /** @psalm-suppress PossiblyUndefinedStringArrayOffset */
                $use_context->vars_in_scope['$this'] = $context->vars_in_scope['$this'];
            } elseif ($context->self) {
                $this_atomic = new TNamedObject($context->self, \true);
                $use_context->vars_in_scope['$this'] = new Union([$this_atomic]);
            }
        }
        foreach ($context->vars_in_scope as $var => $type) {
            if (strpos($var, '$this->') === 0) {
                $use_context->vars_in_scope[$var] = $type;
            }
        }
        if ($context->self) {
            $self_class_storage = $codebase->classlike_storage_provider->get($context->self);
            \Psalm\Internal\Analyzer\ClassAnalyzer::addContextProperties($statements_analyzer, $self_class_storage, $use_context, $context->self, $statements_analyzer->getParentFQCLN());
        }
        foreach ($context->vars_possibly_in_scope as $var => $_) {
            if (strpos($var, '$this->') === 0) {
                $use_context->vars_possibly_in_scope[$var] = \true;
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\Closure) {
            foreach ($stmt->uses as $use) {
                if (!is_string($use->var->name)) {
                    continue;
                }
                $use_var_id = '$' . $use->var->name;
                // insert the ref into the current context if passed by ref, as whatever we're passing
                // the closure to could execute it straight away.
                if ($use->byRef && !$context->hasVariable($use_var_id)) {
                    $context->vars_in_scope[$use_var_id] = new Union([new TMixed()], ['by_ref' => \true]);
                }
                if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph && $context->hasVariable($use_var_id)) {
                    $parent_nodes = $context->vars_in_scope[$use_var_id]->parent_nodes;
                    foreach ($parent_nodes as $parent_node) {
                        $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('closure-use', 'closure use', null), 'closure-use');
                    }
                }
                $use_context->vars_in_scope[$use_var_id] = $context->hasVariable($use_var_id) && !$use->byRef ? $context->vars_in_scope[$use_var_id] : Type::getMixed();
                if ($use->byRef) {
                    $use_context->vars_in_scope[$use_var_id] = $use_context->vars_in_scope[$use_var_id]->setProperties(['by_ref' => \true]);
                    $use_context->references_to_external_scope[$use_var_id] = \true;
                }
                $use_context->vars_possibly_in_scope[$use_var_id] = \true;
                foreach ($context->vars_in_scope as $var_id => $type) {
                    if (preg_match('/^\\$' . $use->var->name . '[\\[\\-]/', $var_id)) {
                        $use_context->vars_in_scope[$var_id] = $type;
                        $use_context->vars_possibly_in_scope[$var_id] = \true;
                    }
                }
            }
        } else {
            $traverser = new PhpParser\NodeTraverser();
            $short_closure_visitor = new ShortClosureVisitor();
            $traverser->addVisitor($short_closure_visitor);
            $traverser->traverse($stmt->getStmts());
            foreach ($short_closure_visitor->getUsedVariables() as $use_var_id => $_) {
                if ($context->hasVariable($use_var_id)) {
                    $use_context->vars_in_scope[$use_var_id] = $context->vars_in_scope[$use_var_id];
                    if ($statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                        $parent_nodes = $context->vars_in_scope[$use_var_id]->parent_nodes;
                        foreach ($parent_nodes as $parent_node) {
                            $statements_analyzer->data_flow_graph->addPath($parent_node, new DataFlowNode('closure-use', 'closure use', null), 'closure-use');
                        }
                    }
                }
                $use_context->vars_possibly_in_scope[$use_var_id] = \true;
            }
        }
        $use_context->calling_method_id = $context->calling_method_id;
        $closure_analyzer->analyze($use_context, $statements_analyzer->node_data, $context, \false);
        if ($closure_analyzer->inferred_impure && $statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer) {
            $statements_analyzer->getSource()->inferred_impure = \true;
        }
        if ($closure_analyzer->inferred_has_mutation && $statements_analyzer->getSource() instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer) {
            $statements_analyzer->getSource()->inferred_has_mutation = \true;
        }
        if (!$statements_analyzer->node_data->getType($stmt)) {
            $statements_analyzer->node_data->setType($stmt, Type::getClosure());
        }
        return \true;
    }
    /**
     * @return  false|null
     */
    public static function analyzeClosureUses(\Psalm\Internal\Analyzer\StatementsAnalyzer $statements_analyzer, PhpParser\Node\Expr\Closure $stmt, Context $context) : ?bool
    {
        $param_names = [];
        foreach ($stmt->params as $i => $param) {
            if ($param->var instanceof PhpParser\Node\Expr\Variable && is_string($param->var->name)) {
                $param_names[$i] = $param->var->name;
            } else {
                $param_names[$i] = '';
            }
        }
        foreach ($stmt->uses as $use) {
            if (!is_string($use->var->name)) {
                continue;
            }
            $use_var_id = '$' . $use->var->name;
            if (in_array($use->var->name, $param_names)) {
                if (IssueBuffer::accepts(new DuplicateParam('Closure use duplicates param name ' . $use_var_id, new CodeLocation($statements_analyzer->getSource(), $use->var)), $statements_analyzer->getSuppressedIssues())) {
                    return \false;
                }
            }
            if (!$context->hasVariable($use_var_id)) {
                if ($use_var_id === '$argv' || $use_var_id === '$argc') {
                    continue;
                }
                if ($use->byRef) {
                    $context->vars_in_scope[$use_var_id] = Type::getMixed();
                    $context->vars_possibly_in_scope[$use_var_id] = \true;
                    if (!$statements_analyzer->hasVariable($use_var_id)) {
                        $statements_analyzer->registerVariable($use_var_id, new CodeLocation($statements_analyzer, $use->var), null);
                    }
                    return null;
                }
                if (!isset($context->vars_possibly_in_scope[$use_var_id])) {
                    if ($context->check_variables) {
                        if (IssueBuffer::accepts(new UndefinedVariable('Cannot find referenced variable ' . $use_var_id, new CodeLocation($statements_analyzer->getSource(), $use->var)), $statements_analyzer->getSuppressedIssues())) {
                            return \false;
                        }
                        return null;
                    }
                }
                $first_appearance = $statements_analyzer->getFirstAppearance($use_var_id);
                if ($first_appearance) {
                    if (IssueBuffer::accepts(new PossiblyUndefinedVariable('Possibly undefined variable ' . $use_var_id . ', first seen on line ' . $first_appearance->getLineNumber(), new CodeLocation($statements_analyzer->getSource(), $use->var)), $statements_analyzer->getSuppressedIssues())) {
                        return \false;
                    }
                    continue;
                }
                if ($context->check_variables) {
                    if (IssueBuffer::accepts(new UndefinedVariable('Cannot find referenced variable ' . $use_var_id, new CodeLocation($statements_analyzer->getSource(), $use->var)), $statements_analyzer->getSuppressedIssues())) {
                        return \false;
                    }
                    continue;
                }
            } elseif ($use->byRef) {
                $new_type = new Union([new TMixed()], ['parent_nodes' => $context->vars_in_scope[$use_var_id]->parent_nodes]);
                $context->remove($use_var_id);
                $context->vars_in_scope[$use_var_id] = $new_type;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\FileSource;
use Psalm\Internal\Scanner\DocblockParser;
use Psalm\Internal\Scanner\ParsedDocblock;
use Psalm\Internal\Scanner\VarDocblockComment;
use Psalm\Internal\Type\TypeAlias;
use Psalm\Internal\Type\TypeParser;
use Psalm\Internal\Type\TypeTokenizer;
use Psalm\Type\Union;
use function array_merge;
use function count;
use function preg_match;
use function preg_replace;
use function preg_split;
use function rtrim;
use function str_replace;
use function strlen;
use function substr;
use function substr_count;
use function trim;
/**
 * @internal
 */
class CommentAnalyzer
{
    public const TYPE_REGEX = '(\\??\\\\?[\\(\\)A-Za-z0-9_&\\<\\.=,\\>\\[\\]\\-\\{\\}:|?\\\\]*|\\$[a-zA-Z_0-9_]+)';
    /**
     * @param  array<string, array<string, Union>>|null   $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     * @throws DocblockParseException if there was a problem parsing the docblock
     * @return list<VarDocblockComment>
     */
    public static function getTypeFromComment(PhpParser\Comment\Doc $comment, FileSource $source, Aliases $aliases, ?array $template_type_map = null, ?array $type_aliases = null) : array
    {
        $parsed_docblock = DocComment::parsePreservingLength($comment);
        return self::arrayToDocblocks($comment, $parsed_docblock, $source, $aliases, $template_type_map, $type_aliases);
    }
    /**
     * @param  array<string, array<string, Union>>|null   $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     * @return list<VarDocblockComment>
     * @throws DocblockParseException if there was a problem parsing the docblock
     */
    public static function arrayToDocblocks(PhpParser\Comment\Doc $comment, ParsedDocblock $parsed_docblock, FileSource $source, Aliases $aliases, ?array $template_type_map = null, ?array $type_aliases = null) : array
    {
        $var_id = null;
        $var_type_tokens = null;
        $original_type = null;
        $var_comments = [];
        $comment_text = $comment->getText();
        $var_line_number = $comment->getStartLine();
        if (isset($parsed_docblock->combined_tags['var'])) {
            foreach ($parsed_docblock->combined_tags['var'] as $offset => $var_line) {
                $var_line = trim($var_line);
                if (!$var_line) {
                    continue;
                }
                $type_start = null;
                $type_end = null;
                $line_parts = self::splitDocLine($var_line);
                $line_number = $comment->getStartLine() + substr_count($comment_text, "\n", 0, $offset - $comment->getStartFilePos());
                $description = $parsed_docblock->description;
                if ($line_parts[0]) {
                    $type_start = $offset;
                    $type_end = $type_start + strlen($line_parts[0]);
                    $line_parts[0] = self::sanitizeDocblockType($line_parts[0]);
                    if ($line_parts[0] === '' || $line_parts[0][0] === '$' && !preg_match('/^\\$this(\\||$)/', $line_parts[0])) {
                        throw new IncorrectDocblockException('Misplaced variable');
                    }
                    try {
                        $var_type_tokens = TypeTokenizer::getFullyQualifiedTokens($line_parts[0], $aliases, $template_type_map, $type_aliases);
                    } catch (TypeParseTreeException $e) {
                        throw new DocblockParseException($line_parts[0] . ' is not a valid type');
                    }
                    $original_type = $line_parts[0];
                    $var_line_number = $line_number;
                    if (count($line_parts) > 1) {
                        if ($line_parts[1][0] === '$') {
                            $var_id = $line_parts[1];
                            $description = trim(substr($var_line, strlen($line_parts[0]) + strlen($line_parts[1]) + 2));
                        } else {
                            $description = trim(substr($var_line, strlen($line_parts[0]) + 1));
                        }
                        $description = preg_replace('/\\n \\*\\s+/um', ' ', $description);
                    }
                }
                if (!$var_type_tokens || !$original_type) {
                    continue;
                }
                try {
                    $defined_type = TypeParser::parseTokens($var_type_tokens, null, $template_type_map ?: [], $type_aliases ?: [], \true);
                } catch (TypeParseTreeException $e) {
                    throw new DocblockParseException($line_parts[0] . ' is not a valid type' . ' (from ' . $source->getFilePath() . ':' . $comment->getStartLine() . ')');
                }
                $var_comment = new VarDocblockComment();
                $var_comment->type = $defined_type;
                $var_comment->var_id = $var_id;
                $var_comment->line_number = $var_line_number;
                $var_comment->type_start = $type_start;
                $var_comment->type_end = $type_end;
                $var_comment->description = $description;
                self::decorateVarDocblockComment($var_comment, $parsed_docblock);
                $var_comments[] = $var_comment;
            }
        }
        if (!$var_comments && (isset($parsed_docblock->tags['deprecated']) || isset($parsed_docblock->tags['internal']) || isset($parsed_docblock->tags['readonly']) || isset($parsed_docblock->tags['psalm-readonly']) || isset($parsed_docblock->tags['psalm-readonly-allow-private-mutation']) || isset($parsed_docblock->tags['psalm-allow-private-mutation']) || isset($parsed_docblock->tags['psalm-taint-escape']) || isset($parsed_docblock->tags['psalm-internal']) || isset($parsed_docblock->tags['psalm-suppress']) || $parsed_docblock->description)) {
            $var_comment = new VarDocblockComment();
            self::decorateVarDocblockComment($var_comment, $parsed_docblock);
            $var_comments[] = $var_comment;
        }
        return $var_comments;
    }
    private static function decorateVarDocblockComment(VarDocblockComment $var_comment, ParsedDocblock $parsed_docblock) : void
    {
        $var_comment->deprecated = isset($parsed_docblock->tags['deprecated']);
        $var_comment->internal = isset($parsed_docblock->tags['internal']);
        $var_comment->readonly = isset($parsed_docblock->tags['readonly']) || isset($parsed_docblock->tags['psalm-readonly']) || isset($parsed_docblock->tags['psalm-readonly-allow-private-mutation']);
        $var_comment->allow_private_mutation = isset($parsed_docblock->tags['psalm-allow-private-mutation']) || isset($parsed_docblock->tags['psalm-readonly-allow-private-mutation']);
        if (!$var_comment->description) {
            $var_comment->description = $parsed_docblock->description;
        }
        if (isset($parsed_docblock->tags['psalm-taint-escape'])) {
            foreach ($parsed_docblock->tags['psalm-taint-escape'] as $param) {
                $param = trim($param);
                $var_comment->removed_taints[] = $param;
            }
        }
        if (count($var_comment->psalm_internal = DocblockParser::handlePsalmInternal($parsed_docblock)) !== 0) {
            $var_comment->internal = \true;
        }
        if (isset($parsed_docblock->tags['psalm-suppress'])) {
            foreach ($parsed_docblock->tags['psalm-suppress'] as $offset => $suppress_entry) {
                foreach (DocComment::parseSuppressList($suppress_entry) as $issue_offset => $suppressed_issue) {
                    $var_comment->suppressed_issues[$issue_offset + $offset] = $suppressed_issue;
                }
            }
        }
    }
    /**
     * @psalm-pure
     */
    public static function sanitizeDocblockType(string $docblock_type) : string
    {
        $docblock_type = preg_replace('@^[ \\t]*\\*@m', '', $docblock_type);
        $docblock_type = preg_replace('/,\\n\\s+\\}/', '}', $docblock_type);
        return str_replace("\n", '', $docblock_type);
    }
    /**
     * @throws DocblockParseException if an invalid string is found
     * @return non-empty-list<string>
     * @psalm-pure
     */
    public static function splitDocLine(string $return_block) : array
    {
        $brackets = '';
        $type = '';
        $expects_callable_return = \false;
        $return_block = str_replace("\t", ' ', $return_block);
        $quote_char = null;
        $escaped = \false;
        for ($i = 0, $l = strlen($return_block); $i < $l; ++$i) {
            $char = $return_block[$i];
            $next_char = $i < $l - 1 ? $return_block[$i + 1] : null;
            $last_char = $i > 0 ? $return_block[$i - 1] : null;
            if ($quote_char) {
                if ($char === $quote_char && !$escaped) {
                    $quote_char = null;
                    $type .= $char;
                    continue;
                }
                if ($char === '\\' && !$escaped && ($next_char === $quote_char || $next_char === '\\')) {
                    $escaped = \true;
                    $type .= $char;
                    continue;
                }
                $escaped = \false;
                $type .= $char;
                continue;
            }
            if ($char === '"' || $char === '\'') {
                $quote_char = $char;
                $type .= $char;
                continue;
            }
            if ($char === ':' && $last_char === ')') {
                $expects_callable_return = \true;
                $type .= $char;
                continue;
            }
            if ($char === '[' || $char === '{' || $char === '(' || $char === '<') {
                $brackets .= $char;
            } elseif ($char === ']' || $char === '}' || $char === ')' || $char === '>') {
                $last_bracket = substr($brackets, -1);
                $brackets = substr($brackets, 0, -1);
                if ($char === ']' && $last_bracket !== '[' || $char === '}' && $last_bracket !== '{' || $char === ')' && $last_bracket !== '(' || $char === '>' && $last_bracket !== '<') {
                    throw new DocblockParseException('Invalid string ' . $return_block);
                }
            } elseif ($char === ' ') {
                if ($brackets) {
                    $expects_callable_return = \false;
                    $type .= ' ';
                    continue;
                }
                if ($next_char === '|' || $next_char === '&') {
                    $nexter_char = $i < $l - 2 ? $return_block[$i + 2] : null;
                    if ($nexter_char === ' ') {
                        ++$i;
                        $type .= $next_char . ' ';
                        continue;
                    }
                }
                if ($last_char === '|' || $last_char === '&') {
                    $type .= ' ';
                    continue;
                }
                if ($next_char === ':') {
                    ++$i;
                    $type .= ' :';
                    $expects_callable_return = \true;
                    continue;
                }
                if ($expects_callable_return) {
                    $type .= ' ';
                    $expects_callable_return = \false;
                    continue;
                }
                $remaining = trim(preg_replace('@^[ \\t]*\\* *@m', ' ', substr($return_block, $i + 1)));
                if ($remaining) {
                    return array_merge([rtrim($type)], preg_split('/[ \\s]+/', $remaining) ?: []);
                }
                return [$type];
            }
            $expects_callable_return = \false;
            $type .= $char;
        }
        return [$type];
    }
}
<?php

namespace Psalm\Internal\Analyzer;

use Psalm\Type;
use Psalm\Type\Union;
use function array_keys;
use function array_unique;
/**
 * @internal
 */
class TypeAnalyzer
{
    /**
     * Takes two arrays of types and merges them
     *
     * @param  array<string, Union>  $new_types
     * @param  array<string, Union>  $existing_types
     * @return array<string, Union>
     */
    public static function combineKeyedTypes(array $new_types, array $existing_types) : array
    {
        $keys = [...array_keys($new_types), ...array_keys($existing_types)];
        $keys = array_unique($keys);
        $result_types = [];
        if (empty($new_types)) {
            return $existing_types;
        }
        if (empty($existing_types)) {
            return $new_types;
        }
        foreach ($keys as $key) {
            if (!isset($existing_types[$key])) {
                $result_types[$key] = $new_types[$key];
                continue;
            }
            if (!isset($new_types[$key])) {
                $result_types[$key] = $existing_types[$key];
                continue;
            }
            $existing_var_types = $existing_types[$key];
            $new_var_types = $new_types[$key];
            if ($new_var_types->getId() === $existing_var_types->getId()) {
                $result_types[$key] = $new_var_types;
            } else {
                $result_types[$key] = Type::combineUnionTypes($new_var_types, $existing_var_types);
            }
        }
        return $result_types;
    }
}
<?php

namespace Psalm\Internal;

use function basename;
use function getenv;
use function pathinfo;
use function substr;
use function trim;
use const PATHINFO_EXTENSION;
/**
 * @internal
 */
final class Composer
{
    /**
     * Retrieve the path to composer.json file.
     *
     * @see https://github.com/composer/composer/blob/5df1797d20c6ab1eb606dc0f0d76a16ba57ddb7f/src/Composer/Factory.php#L233
     */
    public static function getJsonFilePath(string $root) : string
    {
        $file_name = getenv('COMPOSER') ?: 'composer.json';
        $file_name = basename(trim($file_name));
        return $root . '/' . $file_name;
    }
    /**
     * Retrieve the path to composer.lock file.
     *
     * @see https://github.com/composer/composer/blob/5df1797d20c6ab1eb606dc0f0d76a16ba57ddb7f/src/Composer/Factory.php#L238
     */
    public static function getLockFilePath(string $root) : string
    {
        $composer_json_path = self::getJsonFilePath($root);
        return "json" === pathinfo($composer_json_path, PATHINFO_EXTENSION) ? substr($composer_json_path, 0, -4) . 'lock' : $composer_json_path . '.lock';
    }
}
<?php

namespace Psalm\Internal\PluginManager\Command;

use InvalidArgumentException;
use Psalm\Internal\PluginManager\PluginListFactory;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style\SymfonyStyle;
use UnexpectedValueException;
use function assert;
use function getcwd;
use function is_string;
use const DIRECTORY_SEPARATOR;
/**
 * @internal
 */
class DisableCommand extends Command
{
    private PluginListFactory $plugin_list_factory;
    public function __construct(PluginListFactory $plugin_list_factory)
    {
        $this->plugin_list_factory = $plugin_list_factory;
        parent::__construct();
    }
    protected function configure() : void
    {
        $this->setName('disable')->setDescription('Disables a named plugin')->addArgument('pluginName', InputArgument::REQUIRED, 'Plugin name (fully qualified class name or composer package name)')->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Path to Psalm config file')->addUsage('vendor/plugin-package-name [-c path/to/psalm.xml]');
        $this->addUsage('\'Plugin\\Class\\Name\' [-c path/to/psalm.xml]');
    }
    protected function execute(InputInterface $input, OutputInterface $output) : int
    {
        $io = new SymfonyStyle($input, $output);
        $current_dir = (string) getcwd() . DIRECTORY_SEPARATOR;
        $config_file_path = $input->getOption('config');
        if ($config_file_path !== null && !is_string($config_file_path)) {
            throw new UnexpectedValueException('Config file path should be a string');
        }
        $plugin_list = ($this->plugin_list_factory)($current_dir, $config_file_path);
        $plugin_name = $input->getArgument('pluginName');
        assert(is_string($plugin_name));
        try {
            $plugin_class = $plugin_list->resolvePluginClass($plugin_name);
        } catch (InvalidArgumentException $e) {
            $io->error('Unknown plugin class ' . $plugin_name);
            return 2;
        }
        if (!$plugin_list->isEnabled($plugin_class)) {
            $io->note('Plugin already disabled');
            return 3;
        }
        $plugin_list->disable($plugin_class);
        $io->success('Plugin disabled');
        return 0;
    }
}
<?php

namespace Psalm\Internal\PluginManager\Command;

use InvalidArgumentException;
use Psalm\Internal\PluginManager\PluginListFactory;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputArgument;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style\SymfonyStyle;
use UnexpectedValueException;
use function assert;
use function getcwd;
use function is_string;
use const DIRECTORY_SEPARATOR;
/**
 * @internal
 */
class EnableCommand extends Command
{
    private PluginListFactory $plugin_list_factory;
    public function __construct(PluginListFactory $plugin_list_factory)
    {
        $this->plugin_list_factory = $plugin_list_factory;
        parent::__construct();
    }
    protected function configure() : void
    {
        $this->setName('enable')->setDescription('Enables a named plugin')->addArgument('pluginName', InputArgument::REQUIRED, 'Plugin name (fully qualified class name or composer package name)')->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Path to Psalm config file')->addUsage('vendor/plugin-package-name [-c path/to/psalm.xml]');
        $this->addUsage('\'Plugin\\Class\\Name\' [-c path/to/psalm.xml]');
    }
    protected function execute(InputInterface $input, OutputInterface $output) : int
    {
        $io = new SymfonyStyle($input, $output);
        $current_dir = (string) getcwd() . DIRECTORY_SEPARATOR;
        $config_file_path = $input->getOption('config');
        if ($config_file_path !== null && !is_string($config_file_path)) {
            throw new UnexpectedValueException('Config file path should be a string');
        }
        $plugin_list = ($this->plugin_list_factory)($current_dir, $config_file_path);
        $plugin_name = $input->getArgument('pluginName');
        assert(is_string($plugin_name));
        try {
            $plugin_class = $plugin_list->resolvePluginClass($plugin_name);
        } catch (InvalidArgumentException $e) {
            $io->error('Unknown plugin class ' . $plugin_name);
            return 2;
        }
        if ($plugin_list->isEnabled($plugin_class)) {
            $io->note('Plugin already enabled');
            return 3;
        }
        $plugin_list->enable($plugin_class);
        $io->success('Plugin enabled');
        return 0;
    }
}
<?php

namespace Psalm\Internal\PluginManager\Command;

use Psalm\Internal\PluginManager\PluginListFactory;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Command\Command;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Input\InputOption;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Output\OutputInterface;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Console\Style\SymfonyStyle;
use UnexpectedValueException;
use function array_keys;
use function array_map;
use function array_values;
use function count;
use function getcwd;
use function is_string;
use const DIRECTORY_SEPARATOR;
/**
 * @internal
 */
class ShowCommand extends Command
{
    private PluginListFactory $plugin_list_factory;
    public function __construct(PluginListFactory $plugin_list_factory)
    {
        $this->plugin_list_factory = $plugin_list_factory;
        parent::__construct();
    }
    protected function configure() : void
    {
        $this->setName('show')->setDescription('Lists enabled and available plugins')->addOption('config', 'c', InputOption::VALUE_REQUIRED, 'Path to Psalm config file')->addUsage('[-c path/to/psalm.xml]');
    }
    protected function execute(InputInterface $input, OutputInterface $output) : int
    {
        $io = new SymfonyStyle($input, $output);
        $current_dir = (string) getcwd() . DIRECTORY_SEPARATOR;
        $config_file_path = $input->getOption('config');
        if ($config_file_path !== null && !is_string($config_file_path)) {
            throw new UnexpectedValueException('Config file path should be a string');
        }
        $plugin_list = ($this->plugin_list_factory)($current_dir, $config_file_path);
        $enabled = $plugin_list->getEnabled();
        $available = $plugin_list->getAvailable();
        $formatRow = static fn(string $class, ?string $package): array => [$package, $class];
        $io->section('Enabled');
        if (count($enabled)) {
            $io->table(['Package', 'Class'], array_map($formatRow, array_keys($enabled), array_values($enabled)));
        } else {
            $io->note('No plugins enabled');
        }
        $io->section('Available');
        if (count($available)) {
            $io->table(['Package', 'Class'], array_map($formatRow, array_keys($available), array_values($available)));
        } else {
            $io->note('No plugins available');
        }
        return 0;
    }
}
<?php

namespace Psalm\Internal\PluginManager;

use Psalm\Internal\Composer;
use RuntimeException;
use function array_filter;
use function json_encode;
use function rtrim;
use function urlencode;
use const DIRECTORY_SEPARATOR;
use const JSON_THROW_ON_ERROR;
/**
 * @internal
 */
class PluginListFactory
{
    private string $project_root;
    private string $psalm_root;
    public function __construct(string $project_root, string $psalm_root)
    {
        $this->project_root = $project_root;
        $this->psalm_root = $psalm_root;
    }
    public function __invoke(string $current_dir, ?string $config_file_path = null) : \Psalm\Internal\PluginManager\PluginList
    {
        try {
            $config_file = new \Psalm\Internal\PluginManager\ConfigFile($current_dir, $config_file_path);
        } catch (RuntimeException $exception) {
            $config_file = null;
        }
        $composer_lock = new \Psalm\Internal\PluginManager\ComposerLock($this->findLockFiles());
        return new \Psalm\Internal\PluginManager\PluginList($config_file, $composer_lock);
    }
    /** @return non-empty-array<int,string> */
    private function findLockFiles() : array
    {
        // use cases
        // 1. plugins are installed into project vendors - composer.lock is PROJECT_ROOT/composer.lock
        // 2. plugins are installed into separate composer environment (either global or bamarni-bin)
        //  - composer.lock is PSALM_ROOT/../../../composer.lock
        // 3. plugins are installed into psalm vendors - composer.lock is PSALM_ROOT/composer.lock
        // 4. none of the above - use stub (empty virtual composer.lock)
        if ($this->psalm_root === $this->project_root) {
            // managing plugins for psalm itself
            $composer_lock_filenames = [Composer::getLockFilePath(rtrim($this->psalm_root, DIRECTORY_SEPARATOR))];
        } else {
            $composer_lock_filenames = [Composer::getLockFilePath(rtrim($this->project_root, DIRECTORY_SEPARATOR)), Composer::getLockFilePath(rtrim($this->psalm_root, DIRECTORY_SEPARATOR) . '/../../..'), Composer::getLockFilePath(rtrim($this->psalm_root, DIRECTORY_SEPARATOR))];
        }
        $composer_lock_filenames = array_filter($composer_lock_filenames, 'is_readable');
        if (empty($composer_lock_filenames)) {
            $stub_composer_lock = (object) ['packages' => [], 'packages-dev' => []];
            $composer_lock_filenames[] = 'data:application/json,' . urlencode(json_encode($stub_composer_lock, JSON_THROW_ON_ERROR));
        }
        return $composer_lock_filenames;
    }
}
<?php

namespace Psalm\Internal\PluginManager;

use RuntimeException;
use function array_merge;
use function file_get_contents;
use function is_array;
use function is_string;
use function json_decode;
use function json_last_error;
use function json_last_error_msg;
/**
 * @internal
 */
class ComposerLock
{
    /** @var string[] */
    private array $file_names;
    /** @param string[] $file_names */
    public function __construct(array $file_names)
    {
        $this->file_names = $file_names;
    }
    /**
     * @param mixed $package
     * @psalm-assert-if-true array{
     *      name: string,
     *      extra: array{psalm: array{pluginClass: string}}
     * } $package
     * @psalm-pure
     */
    public function isPlugin($package) : bool
    {
        return is_array($package) && isset($package['name'], $package['extra']['psalm']['pluginClass']) && is_string($package['name']) && is_array($package['extra']) && is_array($package['extra']['psalm']) && is_string($package['extra']['psalm']['pluginClass']);
    }
    /**
     * @return array<string,string> [packageName => pluginClass, ...]
     */
    public function getPlugins() : array
    {
        $pluginPackages = $this->getAllPluginPackages();
        $ret = [];
        foreach ($pluginPackages as $package) {
            $ret[$package['name']] = $package['extra']['psalm']['pluginClass'];
        }
        return $ret;
    }
    private function read(string $file_name) : array
    {
        $contents = json_decode(file_get_contents($file_name), \true);
        if ($error = json_last_error()) {
            throw new RuntimeException(json_last_error_msg(), $error);
        }
        if (!is_array($contents)) {
            throw new RuntimeException('Malformed ' . $file_name . ', expecting JSON-encoded object');
        }
        return $contents;
    }
    /**
     * @return list<array{name:string,extra:array{psalm:array{pluginClass:string}}}>
     */
    private function getAllPluginPackages() : array
    {
        $packages = $this->getAllPackages();
        $ret = [];
        /** @psalm-suppress MixedAssignment */
        foreach ($packages as $package) {
            if ($this->isPlugin($package)) {
                $ret[] = $package;
            }
        }
        return $ret;
    }
    private function getAllPackages() : array
    {
        $packages = [];
        foreach ($this->file_names as $file_name) {
            $composer_lock_contents = $this->read($file_name);
            if (!isset($composer_lock_contents['packages']) || !is_array($composer_lock_contents['packages'])) {
                throw new RuntimeException('packages section is missing or not an array');
            }
            if (!isset($composer_lock_contents['packages-dev']) || !is_array($composer_lock_contents['packages-dev'])) {
                throw new RuntimeException('packages-dev section is missing or not an array');
            }
            $packages = array_merge($packages, array_merge($composer_lock_contents['packages'], $composer_lock_contents['packages-dev']));
        }
        return $packages;
    }
}
<?php

namespace Psalm\Internal\PluginManager;

use DOMDocument;
use DOMElement;
use Psalm\Config;
use RuntimeException;
use function assert;
use function file_get_contents;
use function file_put_contents;
use function sprintf;
use function strpos;
use function substr;
/**
 * @internal
 */
class ConfigFile
{
    private string $path;
    private string $current_dir;
    private ?string $psalm_header = null;
    private ?int $psalm_tag_end_pos = null;
    public function __construct(string $current_dir, ?string $explicit_path)
    {
        $this->current_dir = $current_dir;
        if ($explicit_path) {
            $this->path = $explicit_path;
        } else {
            $path = Config::locateConfigFile($current_dir);
            if (!$path) {
                throw new RuntimeException('Cannot find Psalm config');
            }
            $this->path = $path;
        }
    }
    public function getConfig() : Config
    {
        return Config::loadFromXMLFile($this->path, $this->current_dir);
    }
    public function removePlugin(string $plugin_class) : void
    {
        $config_xml = $this->readXml();
        /** @var DOMElement */
        $psalm_root = $config_xml->getElementsByTagName('psalm')[0];
        $plugins_elements = $psalm_root->getElementsByTagName('plugins');
        if (!$plugins_elements->length) {
            // no plugins, nothing to remove
            return;
        }
        /** @var DOMElement */
        $plugins_element = $plugins_elements->item(0);
        $plugin_elements = $plugins_element->getElementsByTagName('pluginClass');
        foreach ($plugin_elements as $plugin_element) {
            if ($plugin_element->getAttribute('class') === $plugin_class) {
                $plugins_element->removeChild($plugin_element);
                break;
            }
        }
        if (!$plugin_elements->length) {
            // avoid breaking old psalm binaries, whose schema did not allow empty plugins
            $psalm_root->removeChild($plugins_element);
        }
        $this->saveXml($config_xml);
    }
    public function addPlugin(string $plugin_class) : void
    {
        $config_xml = $this->readXml();
        /** @var DOMElement */
        $psalm_root = $config_xml->getElementsByTagName('psalm')->item(0);
        $plugins_elements = $psalm_root->getElementsByTagName('plugins');
        if (!$plugins_elements->length) {
            $plugins_element = $config_xml->createElement('plugins');
            if ($plugins_element) {
                $psalm_root->appendChild($plugins_element);
            }
        } else {
            /** @var DOMElement */
            $plugins_element = $plugins_elements->item(0);
        }
        $plugin_class_element = $config_xml->createElement('pluginClass');
        if ($plugin_class_element) {
            $plugin_class_element->setAttribute('xmlns', Config::CONFIG_NAMESPACE);
            $plugin_class_element->setAttribute('class', $plugin_class);
            if ($plugins_element) {
                $plugins_element->appendChild($plugin_class_element);
            }
        }
        $this->saveXml($config_xml);
    }
    private function readXml() : DOMDocument
    {
        $doc = new DOMDocument();
        $file_contents = file_get_contents($this->path);
        if (($tag_start = strpos($file_contents, '<psalm')) !== \false) {
            $tag_end = strpos($file_contents, '>', $tag_start + 1);
            if ($tag_end !== \false) {
                $this->psalm_tag_end_pos = $tag_end;
                $this->psalm_header = substr($file_contents, 0, $tag_end);
            }
        }
        assert($file_contents !== '');
        $doc->loadXML($file_contents);
        return $doc;
    }
    private function saveXml(DOMDocument $config_xml) : void
    {
        $new_file_contents = $config_xml->saveXML($config_xml);
        if (($tag_start = strpos($new_file_contents, '<psalm')) !== \false) {
            $tag_end = strpos($new_file_contents, '>', $tag_start + 1);
            if ($tag_end !== \false && $new_file_contents[$tag_end - 1] !== '/' && $this->psalm_tag_end_pos && $this->psalm_header) {
                $new_file_contents = $this->psalm_header . substr($new_file_contents, $tag_end);
            }
        }
        $result = file_put_contents($this->path, $new_file_contents);
        if ($result === \false) {
            throw new RuntimeException(sprintf('Unable to save xml to %s', $this->path));
        }
    }
}
<?php

namespace Psalm\Internal\PluginManager;

use InvalidArgumentException;
use RuntimeException;
use function array_diff_key;
use function array_flip;
use function array_key_exists;
use function array_search;
use function strpos;
/**
 * @internal
 */
class PluginList
{
    private ?\Psalm\Internal\PluginManager\ConfigFile $config_file = null;
    private \Psalm\Internal\PluginManager\ComposerLock $composer_lock;
    /** @var ?array<string,string> [pluginClass => packageName] */
    private ?array $all_plugins = null;
    /** @var ?array<string,?string> [pluginClass => ?packageName] */
    private ?array $enabled_plugins = null;
    public function __construct(?\Psalm\Internal\PluginManager\ConfigFile $config_file, \Psalm\Internal\PluginManager\ComposerLock $composer_lock)
    {
        $this->config_file = $config_file;
        $this->composer_lock = $composer_lock;
    }
    /**
     * @return array<string,?string> [pluginClass => ?packageName, ...]
     */
    public function getEnabled() : array
    {
        if (!$this->enabled_plugins) {
            $this->enabled_plugins = [];
            if ($this->config_file) {
                foreach ($this->config_file->getConfig()->getPluginClasses() as $plugin_entry) {
                    $plugin_class = $plugin_entry['class'];
                    $this->enabled_plugins[$plugin_class] = $this->findPluginPackage($plugin_class);
                }
            }
        }
        return $this->enabled_plugins;
    }
    /**
     * @return array<string,?string> [pluginCLass => ?packageName]
     */
    public function getAvailable() : array
    {
        return array_diff_key($this->getAll(), $this->getEnabled());
    }
    /**
     * @return array<string,string> [pluginClass => packageName]
     */
    public function getAll() : array
    {
        if (null === $this->all_plugins) {
            $this->all_plugins = array_flip($this->composer_lock->getPlugins());
        }
        return $this->all_plugins;
    }
    public function resolvePluginClass(string $class_or_package) : string
    {
        if (\false === strpos($class_or_package, '/')) {
            return $class_or_package;
            // must be a class then
        }
        // pluginClass => ?pluginPackage
        $plugin_classes = $this->getAll();
        $class = array_search($class_or_package, $plugin_classes, \true);
        if (\false === $class) {
            throw new InvalidArgumentException('Unknown plugin: ' . $class_or_package);
        }
        return $class;
    }
    public function findPluginPackage(string $class) : ?string
    {
        // pluginClass => ?pluginPackage
        $plugin_classes = $this->getAll();
        return $plugin_classes[$class] ?? null;
    }
    public function isEnabled(string $class) : bool
    {
        return array_key_exists($class, $this->getEnabled());
    }
    public function enable(string $class) : void
    {
        if (!$this->config_file) {
            throw new RuntimeException('Cannot find Psalm config');
        }
        $this->config_file->addPlugin($class);
    }
    public function disable(string $class) : void
    {
        if (!$this->config_file) {
            throw new RuntimeException('Cannot find Psalm config');
        }
        $this->config_file->removePlugin($class);
    }
}
<?php

namespace Psalm\Internal\Algebra;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Codebase;
use Psalm\FileSource;
use Psalm\Internal\Algebra;
use Psalm\Internal\Analyzer\Statements\Expression\AssertionFinder;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Node\Expr\BinaryOp\VirtualBooleanAnd;
use Psalm\Node\Expr\BinaryOp\VirtualBooleanOr;
use Psalm\Node\Expr\VirtualBooleanNot;
use Psalm\Storage\Assertion\Truthy;
use function count;
use function spl_object_id;
use function substr;
/**
 * @internal
 */
class FormulaGenerator
{
    /**
     * @return list<Clause>
     */
    public static function getFormula(int $conditional_object_id, int $creating_object_id, PhpParser\Node\Expr $conditional, ?string $this_class_name, FileSource $source, ?Codebase $codebase = null, bool $inside_negation = \false, bool $cache = \true) : array
    {
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional instanceof PhpParser\Node\Expr\BinaryOp\LogicalAnd) {
            $left_assertions = self::getFormula($conditional_object_id, spl_object_id($conditional->left), $conditional->left, $this_class_name, $source, $codebase, $inside_negation, $cache);
            $right_assertions = self::getFormula($conditional_object_id, spl_object_id($conditional->right), $conditional->right, $this_class_name, $source, $codebase, $inside_negation, $cache);
            return [...$left_assertions, ...$right_assertions];
        }
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional instanceof PhpParser\Node\Expr\BinaryOp\LogicalOr) {
            $left_clauses = self::getFormula($conditional_object_id, spl_object_id($conditional->left), $conditional->left, $this_class_name, $source, $codebase, $inside_negation, $cache);
            $right_clauses = self::getFormula($conditional_object_id, spl_object_id($conditional->right), $conditional->right, $this_class_name, $source, $codebase, $inside_negation, $cache);
            return Algebra::combineOredClauses($left_clauses, $right_clauses, $conditional_object_id);
        }
        if ($conditional instanceof PhpParser\Node\Expr\BooleanNot) {
            if ($conditional->expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
                $and_expr = new VirtualBooleanAnd(new VirtualBooleanNot($conditional->expr->left, $conditional->getAttributes()), new VirtualBooleanNot($conditional->expr->right, $conditional->getAttributes()), $conditional->expr->getAttributes());
                return self::getFormula($conditional_object_id, $conditional_object_id, $and_expr, $this_class_name, $source, $codebase, $inside_negation, \false);
            }
            if ($conditional->expr instanceof PhpParser\Node\Expr\Isset_ && count($conditional->expr->vars) > 1) {
                $anded_assertions = null;
                if ($cache && $source instanceof StatementsAnalyzer) {
                    $anded_assertions = $source->node_data->getAssertions($conditional->expr);
                }
                if ($anded_assertions === null) {
                    $anded_assertions = AssertionFinder::scrapeAssertions($conditional->expr, $this_class_name, $source, $codebase, $inside_negation, $cache);
                    if ($cache && $source instanceof StatementsAnalyzer) {
                        $source->node_data->setAssertions($conditional->expr, $anded_assertions);
                    }
                }
                $clauses = [];
                foreach ($anded_assertions as $assertions) {
                    foreach ($assertions as $var => $anded_types) {
                        $redefined = \false;
                        if ($var[0] === '=') {
                            /** @var string */
                            $var = substr($var, 1);
                            $redefined = \true;
                        }
                        foreach ($anded_types as $orred_types) {
                            $mapped_orred_types = [];
                            foreach ($orred_types as $orred_type) {
                                $mapped_orred_types[(string) $orred_type] = $orred_type;
                            }
                            $clauses[] = new Clause([$var => $mapped_orred_types], $conditional_object_id, spl_object_id($conditional->expr), \false, \true, $orred_types[0]->hasEquality(), $redefined ? [$var => \true] : []);
                        }
                    }
                }
                return Algebra::negateFormula($clauses);
            }
            if ($conditional->expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd) {
                $and_expr = new VirtualBooleanOr(new VirtualBooleanNot($conditional->expr->left, $conditional->getAttributes()), new VirtualBooleanNot($conditional->expr->right, $conditional->getAttributes()), $conditional->expr->getAttributes());
                return self::getFormula($conditional_object_id, spl_object_id($conditional->expr), $and_expr, $this_class_name, $source, $codebase, $inside_negation, \false);
            }
            return Algebra::negateFormula(self::getFormula($conditional_object_id, spl_object_id($conditional->expr), $conditional->expr, $this_class_name, $source, $codebase, !$inside_negation));
        }
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Identical || $conditional instanceof PhpParser\Node\Expr\BinaryOp\Equal) {
            $false_pos = AssertionFinder::hasFalseVariable($conditional);
            $true_pos = AssertionFinder::hasTrueVariable($conditional);
            if ($false_pos === AssertionFinder::ASSIGNMENT_TO_RIGHT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Equal || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->left instanceof PhpParser\Node\Expr\BooleanNot)) {
                return Algebra::negateFormula(self::getFormula($conditional_object_id, spl_object_id($conditional->left), $conditional->left, $this_class_name, $source, $codebase, !$inside_negation, $cache));
            }
            if ($false_pos === AssertionFinder::ASSIGNMENT_TO_LEFT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Equal || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->right instanceof PhpParser\Node\Expr\BooleanNot)) {
                return Algebra::negateFormula(self::getFormula($conditional_object_id, spl_object_id($conditional->right), $conditional->right, $this_class_name, $source, $codebase, !$inside_negation, $cache));
            }
            if ($true_pos === AssertionFinder::ASSIGNMENT_TO_RIGHT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Equal || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->left instanceof PhpParser\Node\Expr\BooleanNot)) {
                return self::getFormula($conditional_object_id, spl_object_id($conditional->left), $conditional->left, $this_class_name, $source, $codebase, $inside_negation, $cache);
            }
            if ($true_pos === AssertionFinder::ASSIGNMENT_TO_LEFT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\Equal || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->right instanceof PhpParser\Node\Expr\BooleanNot)) {
                return self::getFormula($conditional_object_id, spl_object_id($conditional->right), $conditional->right, $this_class_name, $source, $codebase, $inside_negation, $cache);
            }
        }
        if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical || $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotEqual) {
            $false_pos = AssertionFinder::hasFalseVariable($conditional);
            $true_pos = AssertionFinder::hasTrueVariable($conditional);
            if ($true_pos === AssertionFinder::ASSIGNMENT_TO_RIGHT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->left instanceof PhpParser\Node\Expr\BooleanNot)) {
                return Algebra::negateFormula(self::getFormula($conditional_object_id, spl_object_id($conditional->left), $conditional->left, $this_class_name, $source, $codebase, !$inside_negation, $cache));
            }
            if ($true_pos === AssertionFinder::ASSIGNMENT_TO_LEFT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->right instanceof PhpParser\Node\Expr\BooleanNot)) {
                return Algebra::negateFormula(self::getFormula($conditional_object_id, spl_object_id($conditional->right), $conditional->right, $this_class_name, $source, $codebase, !$inside_negation, $cache));
            }
            if ($false_pos === AssertionFinder::ASSIGNMENT_TO_RIGHT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->left instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->left instanceof PhpParser\Node\Expr\BooleanNot)) {
                return self::getFormula($conditional_object_id, spl_object_id($conditional->left), $conditional->left, $this_class_name, $source, $codebase, $inside_negation, $cache);
            }
            if ($false_pos === AssertionFinder::ASSIGNMENT_TO_LEFT && ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotEqual || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd || $conditional->right instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr || $conditional->right instanceof PhpParser\Node\Expr\BooleanNot)) {
                return self::getFormula($conditional_object_id, spl_object_id($conditional->right), $conditional->right, $this_class_name, $source, $codebase, $inside_negation, $cache);
            }
        }
        if ($conditional instanceof PhpParser\Node\Expr\Cast\Bool_) {
            return self::getFormula($conditional_object_id, spl_object_id($conditional->expr), $conditional->expr, $this_class_name, $source, $codebase, $inside_negation, $cache);
        }
        $anded_assertions = null;
        if ($cache && $source instanceof StatementsAnalyzer) {
            $anded_assertions = $source->node_data->getAssertions($conditional);
        }
        if ($anded_assertions === null) {
            $anded_assertions = AssertionFinder::scrapeAssertions($conditional, $this_class_name, $source, $codebase, $inside_negation, $cache);
            if ($cache && $source instanceof StatementsAnalyzer) {
                $source->node_data->setAssertions($conditional, $anded_assertions);
            }
        }
        $clauses = [];
        foreach ($anded_assertions as $assertions) {
            foreach ($assertions as $var => $anded_types) {
                $redefined = \false;
                if ($var[0] === '=') {
                    /** @var string */
                    $var = substr($var, 1);
                    $redefined = \true;
                }
                foreach ($anded_types as $orred_types) {
                    $mapped_orred_types = [];
                    foreach ($orred_types as $orred_type) {
                        $mapped_orred_types[(string) $orred_type] = $orred_type;
                    }
                    $clauses[] = new Clause([$var => $mapped_orred_types], $conditional_object_id, $creating_object_id, \false, \true, $orred_types[0]->hasEquality(), $redefined ? [$var => \true] : []);
                }
            }
        }
        if ($clauses) {
            return $clauses;
        }
        /** @psalm-suppress MixedOperand */
        $conditional_ref = '*' . $conditional->getAttribute('startFilePos') . ':' . $conditional->getAttribute('endFilePos');
        return [new Clause([$conditional_ref => ['truthy' => new Truthy()]], $conditional_object_id, $creating_object_id)];
    }
}
<?php

namespace Psalm\Internal\Scanner;

use Psalm\Exception\DocblockParseException;
use function array_filter;
use function array_map;
use function array_values;
use function assert;
use function count;
use function explode;
use function implode;
use function is_string;
use function min;
use function preg_match;
use function preg_replace;
use function rtrim;
use function str_replace;
use function strlen;
use function strpos;
use function strspn;
use function substr;
use function trim;
use const PREG_OFFSET_CAPTURE;
/**
 * This class will parse Docblocks in order to extract known tags from them
 *
 * @internal
 */
class DocblockParser
{
    /**
     * $offsetStart is the absolute position of the docblock in the file. It'll be used to add to the position of some
     * special tags (like `psalm-suppress`) for future uses
     */
    public static function parse(string $docblock, int $offsetStart) : \Psalm\Internal\Scanner\ParsedDocblock
    {
        // Strip off comments.
        $docblock = trim($docblock);
        if (strpos($docblock, '/**') === 0) {
            $docblock = substr($docblock, 3);
        }
        if (substr($docblock, -2) === '*/') {
            $docblock = substr($docblock, 0, -2);
            if (substr($docblock, -1) === '*') {
                $docblock = substr($docblock, 0, -1);
            }
        }
        // Normalize multi-line @specials.
        $lines = explode("\n", $docblock);
        $special = [];
        $first_line_padding = null;
        $last = \false;
        foreach ($lines as $k => $line) {
            if (preg_match('/^[ \\t]*\\*?\\s*@\\w/i', $line)) {
                $last = $k;
            } elseif (preg_match('/^\\s*\\r?$/', $line)) {
                $last = \false;
            } elseif ($last !== \false) {
                $old_last_line = $lines[$last];
                $lines[$last] = $old_last_line . "\n" . $line;
                unset($lines[$k]);
            }
        }
        $line_offset = 0;
        foreach ($lines as $k => $line) {
            $original_line_length = strlen($line);
            $line = str_replace("\r", '', $line);
            if ($first_line_padding === null) {
                $asterisk_pos = strpos($line, '*');
                if ($asterisk_pos) {
                    $first_line_padding = substr($line, 0, $asterisk_pos - 1);
                }
            }
            if (preg_match('/^[ \\t]*\\*?\\s*@([\\w\\-\\\\:]+)[\\t ]*(.*)$/sm', $line, $matches, PREG_OFFSET_CAPTURE)) {
                /** @var array<int, array{string, int}> $matches */
                [, $type_info, $data_info] = $matches;
                [$type] = $type_info;
                [$data, $data_offset] = $data_info;
                if (strpos($data, '*')) {
                    $data = rtrim(preg_replace('/^[ \\t]*\\*\\s*$/m', '', $data));
                }
                if (empty($special[$type])) {
                    $special[$type] = [];
                }
                $data_offset += $line_offset;
                $special[$type][$data_offset + 3 + $offsetStart] = $data;
                unset($lines[$k]);
            } else {
                // Strip the leading *, if present.
                $text = $lines[$k];
                $text = str_replace("\t", ' ', $text);
                $text = preg_replace('/^ *\\*/', '', $text, 1);
                $lines[$k] = $text;
            }
            $line_offset += $original_line_length + 1;
        }
        // Smush the whole docblock to the left edge.
        $min_indent = 80;
        foreach ($lines as $k => $line) {
            $indent = strspn($line, ' ');
            if ($indent === strlen($line)) {
                // This line consists of only spaces. Trim it completely.
                $lines[$k] = '';
                continue;
            }
            $min_indent = min($indent, $min_indent);
        }
        if ($min_indent > 0) {
            foreach ($lines as $k => $line) {
                if (strlen($line) < $min_indent) {
                    continue;
                }
                $lines[$k] = substr($line, $min_indent);
            }
        }
        $docblock = implode("\n", $lines);
        $docblock = rtrim($docblock);
        // Trim any empty lines off the front, but leave the indent level if there
        // is one.
        $docblock = preg_replace('/^\\s*\\n/', '', $docblock, 1);
        $parsed = new \Psalm\Internal\Scanner\ParsedDocblock($docblock, $special, $first_line_padding ?: '');
        self::resolveTags($parsed);
        return $parsed;
    }
    private static function resolveTags(\Psalm\Internal\Scanner\ParsedDocblock $docblock) : void
    {
        if (isset($docblock->tags['template']) || isset($docblock->tags['psalm-template']) || isset($docblock->tags['phpstan-template'])) {
            $docblock->combined_tags['template'] = ($docblock->tags['template'] ?? []) + ($docblock->tags['phpstan-template'] ?? []) + ($docblock->tags['psalm-template'] ?? []);
        }
        if (isset($docblock->tags['template-covariant']) || isset($docblock->tags['psalm-template-covariant']) || isset($docblock->tags['phpstan-template-covariant'])) {
            $docblock->combined_tags['template-covariant'] = ($docblock->tags['template-covariant'] ?? []) + ($docblock->tags['phpstan-template-covariant'] ?? []) + ($docblock->tags['psalm-template-covariant'] ?? []);
        }
        if (isset($docblock->tags['template-extends']) || isset($docblock->tags['inherits']) || isset($docblock->tags['extends']) || isset($docblock->tags['psalm-extends']) || isset($docblock->tags['phpstan-extends'])) {
            $docblock->combined_tags['extends'] = ($docblock->tags['template-extends'] ?? []) + ($docblock->tags['inherits'] ?? []) + ($docblock->tags['extends'] ?? []) + ($docblock->tags['psalm-extends'] ?? []) + ($docblock->tags['phpstan-extends'] ?? []);
        }
        if (isset($docblock->tags['template-implements']) || isset($docblock->tags['implements']) || isset($docblock->tags['phpstan-implements']) || isset($docblock->tags['psalm-implements'])) {
            $docblock->combined_tags['implements'] = ($docblock->tags['template-implements'] ?? []) + ($docblock->tags['implements'] ?? []) + ($docblock->tags['phpstan-implements'] ?? []) + ($docblock->tags['psalm-implements'] ?? []);
        }
        if (isset($docblock->tags['template-use']) || isset($docblock->tags['use']) || isset($docblock->tags['phpstan-use']) || isset($docblock->tags['psalm-use'])) {
            $docblock->combined_tags['use'] = ($docblock->tags['template-use'] ?? []) + ($docblock->tags['use'] ?? []) + ($docblock->tags['phpstan-use'] ?? []) + ($docblock->tags['psalm-use'] ?? []);
        }
        if (isset($docblock->tags['method']) || isset($docblock->tags['psalm-method'])) {
            $docblock->combined_tags['method'] = ($docblock->tags['method'] ?? []) + ($docblock->tags['psalm-method'] ?? []);
        }
        if (isset($docblock->tags['return']) || isset($docblock->tags['psalm-return']) || isset($docblock->tags['phpstan-return'])) {
            if (isset($docblock->tags['psalm-return'])) {
                $docblock->combined_tags['return'] = $docblock->tags['psalm-return'];
            } elseif (isset($docblock->tags['phpstan-return'])) {
                $docblock->combined_tags['return'] = $docblock->tags['phpstan-return'];
            } else {
                $docblock->combined_tags['return'] = $docblock->tags['return'];
            }
        }
        if (isset($docblock->tags['param']) || isset($docblock->tags['psalm-param']) || isset($docblock->tags['phpstan-param'])) {
            $docblock->combined_tags['param'] = ($docblock->tags['param'] ?? []) + ($docblock->tags['phpstan-param'] ?? []) + ($docblock->tags['psalm-param'] ?? []);
        }
        if (isset($docblock->tags['var']) || isset($docblock->tags['psalm-var']) || isset($docblock->tags['phpstan-var'])) {
            if (!isset($docblock->tags['ignore-var']) && !isset($docblock->tags['psalm-ignore-var'])) {
                $docblock->combined_tags['var'] = ($docblock->tags['var'] ?? []) + ($docblock->tags['phpstan-var'] ?? []) + ($docblock->tags['psalm-var'] ?? []);
            }
        }
        if (isset($docblock->tags['param-out']) || isset($docblock->tags['psalm-param-out']) || isset($docblock->tags['phpstan-param-out'])) {
            $docblock->combined_tags['param-out'] = ($docblock->tags['param-out'] ?? []) + ($docblock->tags['phpstan-param-out'] ?? []) + ($docblock->tags['psalm-param-out'] ?? []);
        }
    }
    /**
     * @return list<non-empty-string>
     * @throws DocblockParseException when a @psalm-internal tag doesn't include a namespace
     */
    public static function handlePsalmInternal(\Psalm\Internal\Scanner\ParsedDocblock $parsed_docblock) : array
    {
        if (isset($parsed_docblock->tags['psalm-internal'])) {
            $psalm_internal = array_map("trim", $parsed_docblock->tags['psalm-internal']);
            if (count($psalm_internal) !== count(array_filter($psalm_internal))) {
                throw new DocblockParseException('psalm-internal annotation used without specifying namespace');
            }
            // assert($psalm_internal === array_filter($psalm_internal)); // TODO get this to work
            assert(self::assertArrayOfNonEmptyString($psalm_internal));
            return array_values($psalm_internal);
        }
        return [];
    }
    /** @psalm-assert-if-true array<array-key, non-empty-string> $arr */
    private static function assertArrayOfNonEmptyString(array $arr) : bool
    {
        foreach ($arr as $val) {
            if (!is_string($val) || $val === "") {
                return \false;
            }
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Scanner;

use function explode;
use function trim;
/**
 * @internal
 */
class ParsedDocblock
{
    public string $description;
    public string $first_line_padding;
    /** @var array<string, array<int, string>> */
    public array $tags = [];
    /** @var array<string, array<int, string>> */
    public array $combined_tags = [];
    private static bool $shouldAddNewLineBetweenAnnotations = \true;
    /** @param array<string, array<int, string>> $tags */
    public function __construct(string $description, array $tags, string $first_line_padding = '')
    {
        $this->description = $description;
        $this->tags = $tags;
        $this->first_line_padding = $first_line_padding;
    }
    public function render(string $left_padding) : string
    {
        $doc_comment_text = '/**' . "\n";
        $trimmed_description = trim($this->description);
        if ($trimmed_description !== '') {
            $description_lines = explode("\n", $this->description);
            foreach ($description_lines as $line) {
                $doc_comment_text .= $left_padding . ' *' . (trim($line) ? ' ' . $line : '') . "\n";
            }
        }
        if ($this->tags) {
            if ($trimmed_description !== '') {
                $doc_comment_text .= $left_padding . ' *' . "\n";
            }
            $last_type = null;
            foreach ($this->tags as $type => $lines) {
                if ($last_type !== null && $last_type !== 'psalm-return' && static::shouldAddNewLineBetweenAnnotations()) {
                    $doc_comment_text .= $left_padding . ' *' . "\n";
                }
                foreach ($lines as $line) {
                    $doc_comment_text .= $left_padding . ' * @' . $type . ($line !== '' ? ' ' . $line : '') . "\n";
                }
                $last_type = $type;
            }
        }
        $doc_comment_text .= $left_padding . ' */' . "\n" . $left_padding;
        return $doc_comment_text;
    }
    private static function shouldAddNewLineBetweenAnnotations() : bool
    {
        return static::$shouldAddNewLineBetweenAnnotations;
    }
    /**
     * Sets whether a new line should be added between the annotations or not.
     */
    public static function addNewLineBetweenAnnotations(bool $should = \true) : void
    {
        static::$shouldAddNewLineBetweenAnnotations = $should;
    }
    public static function resetNewlineBetweenAnnotations() : void
    {
        static::$shouldAddNewLineBetweenAnnotations = \true;
    }
}
<?php

namespace Psalm\Internal\Scanner;

/**
 * @internal
 */
class FunctionDocblockComment
{
    public ?string $return_type = null;
    public ?string $return_type_description = null;
    public ?int $return_type_start = null;
    public ?int $return_type_end = null;
    public ?int $return_type_line_number = null;
    /**
     * @var array<
     *     int,
     *     array{
     *         name:string,
     *         type:string,
     *         line_number: int,
     *         start: int,
     *         end: int,
     *         description?: string
     *     }
     * >
     */
    public array $params = [];
    /**
     * @var array<int, array{name:string, type:string, line_number: int}>
     */
    public array $params_out = [];
    /**
     * @var array{type:string, line_number: int}|null
     */
    public ?array $self_out = null;
    /**
     * @var array{type:string, line_number: int}|null
     */
    public ?array $if_this_is = null;
    /**
     * @var array<int, array{name:string, type:string, line_number: int}>
     */
    public array $globals = [];
    /**
     * Whether or not the function is deprecated
     */
    public bool $deprecated = \false;
    /**
     * If set, the function is internal to the given namespace.
     *
     * @var list<non-empty-string>
     */
    public array $psalm_internal = [];
    /**
     * Whether or not the function is internal
     */
    public bool $internal = \false;
    /**
     * Whether or not the function uses get_args
     */
    public bool $variadic = \false;
    /**
     * Whether or not the function is pure
     */
    public bool $pure = \false;
    /**
     * Whether or not to specialize a given call (useful for taint analysis)
     */
    public bool $specialize_call = \false;
    /**
     * Represents the flow from function params to return type
     *
     * @var array<string>
     */
    public array $flows = [];
    /**
     * @var array<string>
     */
    public array $added_taints = [];
    /**
     * @var array<string>
     */
    public array $removed_taints = [];
    /**
     * @var array<int, array{name:string, taint: string}>
     */
    public array $taint_sink_params = [];
    /**
     * @var array<string>
     */
    public array $taint_source_types = [];
    /**
     * @var array<int, array{name:string}>
     */
    public array $assert_untainted_params = [];
    /**
     * Whether or not to ignore the nullability of this function's return type
     */
    public bool $ignore_nullable_return = \false;
    /**
     * Whether or not to ignore the nullability of this function's return type
     */
    public bool $ignore_falsable_return = \false;
    /**
     * @var array<int, string>
     */
    public array $suppressed_issues = [];
    /**
     * @var array<int, array{0: string, 1: int, 2: int}>
     */
    public array $throws = [];
    /**
     * @var array<int, array{string, ?string, ?string, bool}>
     */
    public array $templates = [];
    /**
     * @var array<int, array{type: string, param_name: string}>
     */
    public array $assertions = [];
    /**
     * @var array<int, array{type: string, param_name: string}>
     */
    public array $if_true_assertions = [];
    /**
     * @var array<int, array{type: string, param_name: string}>
     */
    public array $if_false_assertions = [];
    public bool $inheritdoc = \false;
    public bool $mutation_free = \false;
    public bool $external_mutation_free = \false;
    public bool $no_named_args = \false;
    public bool $stub_override = \false;
    public int $since_php_major_version = 0;
    public int $since_php_minor_version = 0;
    public ?string $description = null;
    /** @var array<string, array{lines:list<int>, suggested_replacement?:string}> */
    public array $unexpected_tags = [];
}
<?php

namespace Psalm\Internal\Scanner;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
abstract class UnresolvedConstantComponent
{
    use ImmutableNonCloneableTrait;
}
<?php

namespace Psalm\Internal\Scanner;

use Psalm\Type\Union;
/**
 * @internal
 */
class VarDocblockComment
{
    public ?Union $type = null;
    public ?string $var_id = null;
    public ?int $line_number = null;
    public ?int $type_start = null;
    public ?int $type_end = null;
    /**
     * Whether or not the property is deprecated
     */
    public bool $deprecated = \false;
    /**
     * Whether or not the property is internal
     */
    public bool $internal = \false;
    /**
     * If set, the property is internal to the given namespace.
     *
     * @var list<non-empty-string>
     */
    public array $psalm_internal = [];
    /**
     * Whether or not the property is readonly
     */
    public bool $readonly = \false;
    /**
     * Whether or not to allow mutation by internal methods
     */
    public bool $allow_private_mutation = \false;
    /**
     * @var list<string>
     */
    public array $removed_taints = [];
    /**
     * @var array<int, string>
     */
    public array $suppressed_issues = [];
    public ?string $description = null;
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/**
 * @psalm-immutable
 * @internal
 */
class KeyValuePair extends UnresolvedConstantComponent
{
    public ?UnresolvedConstantComponent $key = null;
    public UnresolvedConstantComponent $value;
    public function __construct(?UnresolvedConstantComponent $key, UnresolvedConstantComponent $value)
    {
        $this->key = $key;
        $this->value = $value;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedBitwiseAnd extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedTernary extends UnresolvedConstantComponent
{
    use ImmutableNonCloneableTrait;
    public UnresolvedConstantComponent $cond;
    public ?UnresolvedConstantComponent $if = null;
    public UnresolvedConstantComponent $else;
    public function __construct(UnresolvedConstantComponent $cond, ?UnresolvedConstantComponent $if, UnresolvedConstantComponent $else)
    {
        $this->cond = $cond;
        $this->if = $if;
        $this->else = $else;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedAdditionOp extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/**
 * @psalm-immutable
 * @internal
 */
class ArrayOffsetFetch extends UnresolvedConstantComponent
{
    public UnresolvedConstantComponent $array;
    public UnresolvedConstantComponent $offset;
    public function __construct(UnresolvedConstantComponent $left, UnresolvedConstantComponent $right)
    {
        $this->array = $left;
        $this->offset = $right;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/**
 * @psalm-immutable
 * @internal
 */
class ScalarValue extends UnresolvedConstantComponent
{
    /** @var string|int|float|bool|null */
    public $value;
    /** @param string|int|float|bool|null $value */
    public function __construct($value)
    {
        $this->value = $value;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedSubtractionOp extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
    use ImmutableNonCloneableTrait;
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
abstract class UnresolvedBinaryOp extends UnresolvedConstantComponent
{
    use ImmutableNonCloneableTrait;
    public UnresolvedConstantComponent $left;
    public UnresolvedConstantComponent $right;
    public function __construct(UnresolvedConstantComponent $left, UnresolvedConstantComponent $right)
    {
        $this->left = $left;
        $this->right = $right;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedBitwiseOr extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedConcatOp extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
    use ImmutableNonCloneableTrait;
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/**
 * @psalm-immutable
 * @internal
 */
class ClassConstant extends UnresolvedConstantComponent
{
    public string $fqcln;
    public string $name;
    public function __construct(string $fqcln, string $name)
    {
        $this->fqcln = $fqcln;
        $this->name = $name;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedBitwiseXor extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedMultiplicationOp extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
    use ImmutableNonCloneableTrait;
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/**
 * @psalm-immutable
 * @internal
 */
class Constant extends UnresolvedConstantComponent
{
    public string $name;
    public bool $is_fully_qualified;
    public function __construct(string $name, bool $is_fully_qualified)
    {
        $this->name = $name;
        $this->is_fully_qualified = $is_fully_qualified;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/**
 * @psalm-immutable
 * @internal
 */
class ArraySpread extends UnresolvedConstantComponent
{
    public UnresolvedConstantComponent $array;
    public function __construct(UnresolvedConstantComponent $array)
    {
        $this->array = $array;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Internal\Scanner\UnresolvedConstantComponent;
/**
 * @psalm-immutable
 * @internal
 */
class ArrayValue extends UnresolvedConstantComponent
{
    /** @var array<int, KeyValuePair|ArraySpread> */
    public array $entries;
    /** @param list<KeyValuePair|ArraySpread> $entries */
    public function __construct(array $entries)
    {
        $this->entries = $entries;
    }
}
<?php

namespace Psalm\Internal\Scanner\UnresolvedConstant;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class UnresolvedDivisionOp extends \Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp
{
    use ImmutableNonCloneableTrait;
}
<?php

namespace Psalm\Internal\Scanner;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Union;
use function count;
use function implode;
use function is_string;
use function str_replace;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class PhpStormMetaScanner
{
    /**
     * @param  list<PhpParser\Node\Arg> $args
     */
    public static function handleOverride(array $args, Codebase $codebase) : void
    {
        if (count($args) < 2) {
            return;
        }
        $identifier = $args[0]->value;
        if (!$args[1]->value instanceof PhpParser\Node\Expr\FuncCall || !$args[1]->value->name instanceof PhpParser\Node\Name) {
            return;
        }
        $map = [];
        if ($args[1]->value->name->parts === ['map'] && $args[1]->value->getArgs() && $args[1]->value->getArgs()[0]->value instanceof PhpParser\Node\Expr\Array_) {
            foreach ($args[1]->value->getArgs()[0]->value->items as $array_item) {
                if ($array_item && $array_item->key instanceof PhpParser\Node\Scalar\String_) {
                    if ($array_item->value instanceof PhpParser\Node\Expr\ClassConstFetch && $array_item->value->class instanceof PhpParser\Node\Name\FullyQualified && $array_item->value->name instanceof PhpParser\Node\Identifier && strtolower($array_item->value->name->name)) {
                        $map[$array_item->key->value] = new Union([new TNamedObject(implode('\\', $array_item->value->class->parts))]);
                    } elseif ($array_item->value instanceof PhpParser\Node\Scalar\String_) {
                        $map[$array_item->key->value] = $array_item->value->value;
                    }
                }
            }
        }
        $type_offset = null;
        if ($args[1]->value->name->parts === ['type'] && $args[1]->value->getArgs() && $args[1]->value->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber) {
            $type_offset = $args[1]->value->getArgs()[0]->value->value;
        }
        $element_type_offset = null;
        if ($args[1]->value->name->parts === ['elementType'] && $args[1]->value->getArgs() && $args[1]->value->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber) {
            $element_type_offset = $args[1]->value->getArgs()[0]->value->value;
        }
        if ($identifier instanceof PhpParser\Node\Expr\StaticCall && $identifier->class instanceof PhpParser\Node\Name\FullyQualified && $identifier->name instanceof PhpParser\Node\Identifier && ($identifier->getArgs() === [] || $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber)) {
            $meta_fq_classlike_name = implode('\\', $identifier->class->parts);
            $meta_method_name = strtolower($identifier->name->name);
            if ($map) {
                $offset = 0;
                if ($identifier->getArgs() && $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber) {
                    $offset = $identifier->getArgs()[0]->value->value;
                }
                $codebase->methods->return_type_provider->registerClosure($meta_fq_classlike_name, static function (MethodReturnTypeProviderEvent $event) use($map, $offset, $meta_fq_classlike_name, $meta_method_name) : ?Union {
                    $statements_analyzer = $event->getSource();
                    $call_args = $event->getCallArgs();
                    $method_name = $event->getMethodNameLowercase();
                    $fq_classlike_name = $event->getFqClasslikeName();
                    if (!$statements_analyzer instanceof StatementsAnalyzer) {
                        return Type::getMixed();
                    }
                    if ($meta_method_name !== $method_name || $meta_fq_classlike_name !== $fq_classlike_name) {
                        return null;
                    }
                    if (isset($call_args[$offset]->value) && ($call_arg_type = $statements_analyzer->node_data->getType($call_args[$offset]->value)) && $call_arg_type->isSingleStringLiteral()) {
                        $offset_arg_value = $call_arg_type->getSingleStringLiteral()->value;
                        if ($mapped_type = $map[$offset_arg_value] ?? null) {
                            if ($mapped_type instanceof Union) {
                                return $mapped_type;
                            }
                        }
                        if (($mapped_type = $map[''] ?? null) && is_string($mapped_type)) {
                            if (strpos($mapped_type, '@') !== \false) {
                                $mapped_type = str_replace('@', $offset_arg_value, $mapped_type);
                                if (strpos($mapped_type, '.') === \false) {
                                    return new Union([new TNamedObject($mapped_type)]);
                                }
                            }
                        }
                    }
                    return null;
                });
            } elseif ($type_offset !== null) {
                $codebase->methods->return_type_provider->registerClosure($meta_fq_classlike_name, static function (MethodReturnTypeProviderEvent $event) use($type_offset, $meta_fq_classlike_name, $meta_method_name) : ?Union {
                    $statements_analyzer = $event->getSource();
                    $call_args = $event->getCallArgs();
                    $method_name = $event->getMethodNameLowercase();
                    $fq_classlike_name = $event->getFqClasslikeName();
                    if (!$statements_analyzer instanceof StatementsAnalyzer) {
                        return Type::getMixed();
                    }
                    if ($meta_method_name !== $method_name || $meta_fq_classlike_name !== $fq_classlike_name) {
                        return null;
                    }
                    if (isset($call_args[$type_offset]->value) && ($call_arg_type = $statements_analyzer->node_data->getType($call_args[$type_offset]->value))) {
                        return $call_arg_type;
                    }
                    return null;
                });
            } elseif ($element_type_offset !== null) {
                $codebase->methods->return_type_provider->registerClosure($meta_fq_classlike_name, static function (MethodReturnTypeProviderEvent $event) use($element_type_offset, $meta_fq_classlike_name, $meta_method_name) : ?Union {
                    $statements_analyzer = $event->getSource();
                    $call_args = $event->getCallArgs();
                    $method_name = $event->getMethodNameLowercase();
                    $fq_classlike_name = $event->getFqClasslikeName();
                    if (!$statements_analyzer instanceof StatementsAnalyzer) {
                        return Type::getMixed();
                    }
                    if ($meta_method_name !== $method_name || $meta_fq_classlike_name !== $fq_classlike_name) {
                        return null;
                    }
                    if (isset($call_args[$element_type_offset]->value) && ($call_arg_type = $statements_analyzer->node_data->getType($call_args[$element_type_offset]->value)) && $call_arg_type->hasArray()) {
                        /**
                         * @var TArray|TKeyedArray
                         */
                        $array_atomic_type = $call_arg_type->getArray();
                        if ($array_atomic_type instanceof TKeyedArray) {
                            return $array_atomic_type->getGenericValueType();
                        }
                        return $array_atomic_type->type_params[1];
                    }
                    return null;
                });
            }
        }
        if ($identifier instanceof PhpParser\Node\Expr\FuncCall && $identifier->name instanceof PhpParser\Node\Name\FullyQualified && ($identifier->getArgs() === [] || $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber)) {
            $function_id = strtolower(implode('\\', $identifier->name->parts));
            if ($map) {
                $offset = 0;
                if ($identifier->getArgs() && $identifier->getArgs()[0]->value instanceof PhpParser\Node\Scalar\LNumber) {
                    $offset = $identifier->getArgs()[0]->value->value;
                }
                $codebase->functions->return_type_provider->registerClosure($function_id, static function (FunctionReturnTypeProviderEvent $event) use($map, $offset) : Union {
                    $statements_analyzer = $event->getStatementsSource();
                    $call_args = $event->getCallArgs();
                    $function_id = $event->getFunctionId();
                    if (!$statements_analyzer instanceof StatementsAnalyzer) {
                        return Type::getMixed();
                    }
                    if (isset($call_args[$offset]->value) && ($call_arg_type = $statements_analyzer->node_data->getType($call_args[$offset]->value)) && $call_arg_type->isSingleStringLiteral()) {
                        $offset_arg_value = $call_arg_type->getSingleStringLiteral()->value;
                        if ($mapped_type = $map[$offset_arg_value] ?? null) {
                            if ($mapped_type instanceof Union) {
                                return $mapped_type;
                            }
                        }
                        if (($mapped_type = $map[''] ?? null) && is_string($mapped_type)) {
                            if (strpos($mapped_type, '@') !== \false) {
                                $mapped_type = str_replace('@', $offset_arg_value, $mapped_type);
                                if (strpos($mapped_type, '.') === \false) {
                                    return new Union([new TNamedObject($mapped_type)]);
                                }
                            }
                        }
                    }
                    $storage = $statements_analyzer->getCodebase()->functions->getStorage($statements_analyzer, strtolower($function_id));
                    return $storage->return_type ?: Type::getMixed();
                });
            } elseif ($type_offset !== null) {
                $codebase->functions->return_type_provider->registerClosure($function_id, static function (FunctionReturnTypeProviderEvent $event) use($type_offset) : Union {
                    $statements_analyzer = $event->getStatementsSource();
                    $call_args = $event->getCallArgs();
                    $function_id = $event->getFunctionId();
                    if (!$statements_analyzer instanceof StatementsAnalyzer) {
                        return Type::getMixed();
                    }
                    if (isset($call_args[$type_offset]->value) && ($call_arg_type = $statements_analyzer->node_data->getType($call_args[$type_offset]->value))) {
                        return $call_arg_type;
                    }
                    $storage = $statements_analyzer->getCodebase()->functions->getStorage($statements_analyzer, strtolower($function_id));
                    return $storage->return_type ?: Type::getMixed();
                });
            } elseif ($element_type_offset !== null) {
                $codebase->functions->return_type_provider->registerClosure($function_id, static function (FunctionReturnTypeProviderEvent $event) use($element_type_offset) : Union {
                    $statements_analyzer = $event->getStatementsSource();
                    $call_args = $event->getCallArgs();
                    $function_id = $event->getFunctionId();
                    if (!$statements_analyzer instanceof StatementsAnalyzer) {
                        return Type::getMixed();
                    }
                    if (isset($call_args[$element_type_offset]->value) && ($call_arg_type = $statements_analyzer->node_data->getType($call_args[$element_type_offset]->value)) && $call_arg_type->hasArray()) {
                        /**
                         * @var TArray|TKeyedArray
                         */
                        $array_atomic_type = $call_arg_type->getArray();
                        if ($array_atomic_type instanceof TKeyedArray) {
                            return $array_atomic_type->getGenericValueType();
                        }
                        return $array_atomic_type->type_params[1];
                    }
                    $storage = $statements_analyzer->getCodebase()->functions->getStorage($statements_analyzer, strtolower($function_id));
                    return $storage->return_type ?: Type::getMixed();
                });
            }
        }
    }
}
<?php

namespace Psalm\Internal\Scanner;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
/**
 * @internal
 */
class ClassLikeDocblockComment
{
    /**
     * Whether or not the class is deprecated
     */
    public bool $deprecated = \false;
    /**
     * Whether or not the class is internal
     */
    public bool $internal = \false;
    /**
     * Whether or not the class is final
     */
    public bool $final = \false;
    /**
     * If set, the class is internal to the given namespace.
     *
     * @var list<non-empty-string>
     */
    public array $psalm_internal = [];
    /**
     * @var string[]
     */
    public array $mixins = [];
    /**
     * @var array<int, array{string, ?string, ?string, bool, int}>
     */
    public array $templates = [];
    /**
     * @var array<int, string>
     */
    public array $template_extends = [];
    /**
     * @var array<int, string>
     */
    public array $template_implements = [];
    public ?string $yield = null;
    /**
     * @var array<int, array{end?: int, line_number: int, name: string, start?: int, tag: string, type: string}>
     */
    public array $properties = [];
    /**
     * @var array<int, ClassMethod>
     */
    public array $methods = [];
    public bool $sealed_properties = \false;
    public bool $sealed_methods = \false;
    public bool $override_property_visibility = \false;
    public bool $override_method_visibility = \false;
    public bool $mutation_free = \false;
    public bool $external_mutation_free = \false;
    public bool $taint_specialize = \false;
    /**
     * @var array<int, string>
     */
    public array $suppressed_issues = [];
    /**
     * @var list<array{line_number:int,start_offset:int,end_offset:int,parts:list<string>}>
     */
    public array $imported_types = [];
    public bool $consistent_constructor = \false;
    public bool $consistent_templates = \false;
    public bool $stub_override = \false;
    public ?string $extension_requirement = null;
    /**
     * @var array<int, string>
     */
    public array $implementation_requirements = [];
    public ?string $description = null;
    public bool $public_api = \false;
}
<?php

namespace Psalm\Internal\Scanner;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeTraverser;
use Psalm\Aliases;
use Psalm\Codebase;
use Psalm\FileSource;
use Psalm\Internal\PhpVisitor\ReflectorVisitor;
use Psalm\Progress\Progress;
use Psalm\Progress\VoidProgress;
use Psalm\Storage\FileStorage;
/**
 * @internal
 * @psalm-consistent-constructor
 */
class FileScanner implements FileSource
{
    public string $file_path;
    public string $file_name;
    public bool $will_analyze;
    public function __construct(string $file_path, string $file_name, bool $will_analyze)
    {
        $this->file_path = $file_path;
        $this->file_name = $file_name;
        $this->will_analyze = $will_analyze;
    }
    public function scan(Codebase $codebase, FileStorage $file_storage, bool $storage_from_cache = \false, ?Progress $progress = null) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        if ((!$this->will_analyze || $file_storage->deep_scan) && $storage_from_cache && !$codebase->register_stub_files) {
            return;
        }
        $stmts = $codebase->statements_provider->getStatementsForFile($file_storage->file_path, $codebase->analysis_php_version_id, $progress);
        foreach ($stmts as $stmt) {
            if (!$stmt instanceof PhpParser\Node\Stmt\ClassLike && !$stmt instanceof PhpParser\Node\Stmt\Function_ && !($stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Include_)) {
                $file_storage->has_extra_statements = \true;
                break;
            }
        }
        if ($this->will_analyze) {
            $progress->debug('Deep scanning ' . $file_storage->file_path . "\n");
        } else {
            $progress->debug('Scanning ' . $file_storage->file_path . "\n");
        }
        $traverser = new NodeTraverser();
        $traverser->addVisitor(new ReflectorVisitor($codebase, $this, $file_storage));
        $traverser->traverse($stmts);
        $file_storage->deep_scan = $this->will_analyze;
    }
    /** @psalm-mutation-free */
    public function getFilePath() : string
    {
        return $this->file_path;
    }
    /** @psalm-mutation-free */
    public function getFileName() : string
    {
        return $this->file_name;
    }
    /** @psalm-mutation-free */
    public function getRootFilePath() : string
    {
        return $this->file_path;
    }
    /** @psalm-mutation-free */
    public function getRootFileName() : string
    {
        return $this->file_name;
    }
    /** @psalm-mutation-free */
    public function getAliases() : Aliases
    {
        return new Aliases();
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

/**
 * Must emit a "message" event with a Message object as parameter
 * when a message comes in
 *
 * Must emit a "close" event when the stream closes
 */
interface ProtocolReader extends \Psalm\Internal\LanguageServer\EmitterInterface
{
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
interface ProtocolWriter
{
    /**
     * Sends a Message to the client
     *
     * @return Promise Resolved when the message has been fully written out to the output stream
     */
    public function write(\Psalm\Internal\LanguageServer\Message $msg) : Promise;
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Message as MessageBody;
use _HumbugBox1cb33d1f20f1\Amp\ByteStream\ResourceInputStream;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use Exception;
use Generator;
use function _HumbugBox1cb33d1f20f1\Amp\asyncCall;
use function explode;
use function strlen;
use function substr;
use function trim;
/**
 * Source: https://github.com/felixfbecker/php-language-server/tree/master/src/ProtocolStreamReader.php
 *
 * @internal
 */
class ProtocolStreamReader implements \Psalm\Internal\LanguageServer\ProtocolReader
{
    use \Psalm\Internal\LanguageServer\EmitterTrait;
    private const PARSE_HEADERS = 1;
    private const PARSE_BODY = 2;
    /**
     * This is checked by ProtocolStreamReader so that it will stop reading from streams in the forked process.
     * There could be buffered bytes in stdin/over TCP, those would be processed by TCP if it were not for this check.
     */
    private bool $is_accepting_new_requests = \true;
    private int $parsing_mode = self::PARSE_HEADERS;
    private string $buffer = '';
    /** @var string[] */
    private array $headers = [];
    private ?int $content_length = null;
    private bool $did_emit_close = \false;
    /**
     * @param resource $input
     */
    public function __construct($input)
    {
        $input = new ResourceInputStream($input);
        asyncCall(
            /**
             * @return Generator<int, Promise<?string>, ?string, void>
             */
            function () use($input) : Generator {
                while ($this->is_accepting_new_requests) {
                    $read_promise = $input->read();
                    $chunk = (yield $read_promise);
                    if ($chunk === null) {
                        break;
                    }
                    if ($this->readMessages($chunk) > 0) {
                        $this->emit('readMessageGroup');
                    }
                }
                $this->emitClose();
            }
        );
        $this->on('close', static function () use($input) : void {
            $input->close();
        });
    }
    private function readMessages(string $buffer) : int
    {
        $emitted_messages = 0;
        $i = 0;
        while (($buffer[$i] ?? '') !== '') {
            $this->buffer .= $buffer[$i++];
            switch ($this->parsing_mode) {
                case self::PARSE_HEADERS:
                    if ($this->buffer === "\r\n") {
                        $this->parsing_mode = self::PARSE_BODY;
                        $this->content_length = (int) ($this->headers['Content-Length'] ?? 0);
                        $this->buffer = '';
                    } elseif (substr($this->buffer, -2) === "\r\n") {
                        $parts = explode(':', $this->buffer);
                        $this->headers[$parts[0]] = trim($parts[1]);
                        $this->buffer = '';
                    }
                    break;
                case self::PARSE_BODY:
                    if (strlen($this->buffer) === $this->content_length) {
                        if (!$this->is_accepting_new_requests) {
                            // If we fork, don't read any bytes in the input buffer from the worker process.
                            $this->emitClose();
                            return $emitted_messages;
                        }
                        // MessageBody::parse can throw an Error, maybe log an error?
                        try {
                            $msg = new \Psalm\Internal\LanguageServer\Message(MessageBody::parse($this->buffer), $this->headers);
                        } catch (Exception $_) {
                            $msg = null;
                        }
                        if ($msg) {
                            ++$emitted_messages;
                            $this->emit('message', [$msg]);
                            /**
                             * @psalm-suppress TypeDoesNotContainType
                             */
                            if (!$this->is_accepting_new_requests) {
                                // If we fork, don't read any bytes in the input buffer from the worker process.
                                $this->emitClose();
                                return $emitted_messages;
                            }
                        }
                        $this->parsing_mode = self::PARSE_HEADERS;
                        $this->headers = [];
                        $this->buffer = '';
                    }
                    break;
            }
        }
        return $emitted_messages;
    }
    private function emitClose() : void
    {
        if ($this->did_emit_close) {
            return;
        }
        $this->did_emit_close = \true;
        $this->emit('close');
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

/**
 * Event Emitter Interface
 *
 * Anything that accepts listeners and emits events should implement this
 * interface.
 *
 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
 * @author Evert Pot (http://evertpot.com/)
 * @license http://sabre.io/license/ Modified BSD License
 */
interface EmitterInterface
{
    /**
     * Subscribe to an event.
     */
    public function on(string $eventName, callable $callBack, int $priority = 100) : void;
    /**
     * Emits an event.
     *
     * This method will return true if 0 or more listeners were successfully
     * handled. false is returned if one of the events broke the event chain.
     *
     * If the continueCallBack is specified, this callback will be called every
     * time before the next event handler is called.
     *
     * If the continueCallback returns false, event propagation stops. This
     * allows you to use the eventEmitter as a means for listeners to implement
     * functionality in your application, and break the event loop as soon as
     * some condition is fulfilled.
     *
     * Note that returning false from an event subscriber breaks propagation
     * and returns false, but if the continue-callback stops propagation, this
     * is still considered a 'successful' operation and returns true.
     *
     * Lastly, if there are 5 event handlers for an event. The continueCallback
     * will be called at most 4 times.
     *
     * @param list<mixed> $arguments
     */
    public function emit(string $eventName, array $arguments = [], ?callable $continueCallBack = null) : void;
    /**
     * Returns the list of listeners for an event.
     *
     * The list is returned as an array, and the list of events are sorted by
     * their priority.
     *
     * @return callable[]
     */
    public function listeners(string $eventName) : array;
    /**
     * Removes a specific listener from an event.
     *
     * If the listener could not be found, this method will return false. If it
     * was removed it will return true.
     *
     * @psalm-suppress PossiblyUnusedReturnValue
     */
    public function removeListener(string $eventName, callable $listener) : bool;
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer\Server;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\CompletionList;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Hover;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Location;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\MarkupContent;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\MarkupKind;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Position;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Range;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\SignatureHelp;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextDocumentContentChangeEvent;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextDocumentIdentifier;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextDocumentItem;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextEdit;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\VersionedTextDocumentIdentifier;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\WorkspaceEdit;
use Psalm\Codebase;
use Psalm\Exception\UnanalyzedFileException;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\LanguageServer\LanguageServer;
use UnexpectedValueException;
use function array_values;
use function count;
use function error_log;
use function preg_match;
use function substr_count;
/**
 * Provides method handlers for all textDocument/* methods
 *
 * @internal
 */
class TextDocument
{
    protected LanguageServer $server;
    protected Codebase $codebase;
    protected ProjectAnalyzer $project_analyzer;
    public function __construct(LanguageServer $server, Codebase $codebase, ProjectAnalyzer $project_analyzer)
    {
        $this->server = $server;
        $this->codebase = $codebase;
        $this->project_analyzer = $project_analyzer;
    }
    /**
     * The document open notification is sent from the client to the server to signal newly opened text documents. The
     * document’s content is now managed by the client and the server must not try to read the document’s content using
     * the document’s Uri. Open in this sense means it is managed by the client. It doesn’t necessarily mean that its
     * content is presented in an editor. An open notification must not be sent more than once without a corresponding
     * close notification send before. This means open and close notification must be balanced and the max open count
     * for a particular textDocument is one. Note that a server’s ability to fulfill requests is independent of whether
     * a text document is open or closed.
     *
     * @param TextDocumentItem $textDocument the document that was opened
     */
    public function didOpen(TextDocumentItem $textDocument) : void
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        if (!$this->codebase->config->isInProjectDirs($file_path)) {
            return;
        }
        $this->codebase->file_provider->openFile($file_path);
        $this->server->queueFileAnalysis($file_path, $textDocument->uri);
    }
    /**
     * The document save notification is sent from the client to the server when the document was saved in the client
     *
     * @param TextDocumentItem $textDocument the document that was opened
     * @param ?string $text the content when saved
     */
    public function didSave(TextDocumentItem $textDocument, ?string $text) : void
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        if (!$this->codebase->config->isInProjectDirs($file_path)) {
            return;
        }
        // reopen file
        $this->codebase->removeTemporaryFileChanges($file_path);
        $this->codebase->file_provider->setOpenContents($file_path, (string) $text);
        $this->server->queueFileAnalysis($file_path, $textDocument->uri);
    }
    /**
     * The document change notification is sent from the client to the server to signal changes to a text document.
     *
     * @param TextDocumentContentChangeEvent[] $contentChanges
     */
    public function didChange(VersionedTextDocumentIdentifier $textDocument, array $contentChanges) : void
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        if (!$this->codebase->config->isInProjectDirs($file_path)) {
            return;
        }
        if (count($contentChanges) === 1 && $contentChanges[0]->range === null) {
            $new_content = $contentChanges[0]->text;
        } else {
            throw new UnexpectedValueException('Not expecting partial diff');
        }
        if ($this->project_analyzer->onchange_line_limit !== null) {
            if (substr_count($new_content, "\n") > $this->project_analyzer->onchange_line_limit) {
                return;
            }
        }
        $this->codebase->addTemporaryFileChanges($file_path, $new_content);
        $this->server->queueTemporaryFileAnalysis($file_path, $textDocument->uri);
    }
    /**
     * The document close notification is sent from the client to the server when the document got closed in the client.
     * The document’s master now exists where the document’s Uri points to (e.g. if the document’s Uri is a file Uri the
     * master now exists on disk). As with the open notification the close notification is about managing the document’s
     * content. Receiving a close notification doesn’t mean that the document was open in an editor before. A close
     * notification requires a previous open notification to be sent. Note that a server’s ability to fulfill requests
     * is independent of whether a text document is open or closed.
     *
     * @param TextDocumentIdentifier $textDocument The document that was closed
     */
    public function didClose(TextDocumentIdentifier $textDocument) : void
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        $this->codebase->file_provider->closeFile($file_path);
        $this->server->client->textDocument->publishDiagnostics($textDocument->uri, []);
    }
    /**
     * The goto definition request is sent from the client to the server to resolve the definition location of a symbol
     * at a given text document position.
     *
     * @param TextDocumentIdentifier $textDocument The text document
     * @param Position $position The position inside the text document
     * @psalm-return Promise<Location>|Promise<null>
     */
    public function definition(TextDocumentIdentifier $textDocument, Position $position) : Promise
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        try {
            $reference_location = $this->codebase->getReferenceAtPosition($file_path, $position);
        } catch (UnanalyzedFileException $e) {
            $this->codebase->file_provider->openFile($file_path);
            $this->server->queueFileAnalysis($file_path, $textDocument->uri);
            return new Success(null);
        }
        if ($reference_location === null) {
            return new Success(null);
        }
        [$reference] = $reference_location;
        $code_location = $this->codebase->getSymbolLocation($file_path, $reference);
        if (!$code_location) {
            return new Success(null);
        }
        return new Success(new Location(LanguageServer::pathToUri($code_location->file_path), new Range(new Position($code_location->getLineNumber() - 1, $code_location->getColumn() - 1), new Position($code_location->getEndLineNumber() - 1, $code_location->getEndColumn() - 1))));
    }
    /**
     * The hover request is sent from the client to the server to request
     * hover information at a given text document position.
     *
     * @param TextDocumentIdentifier $textDocument The text document
     * @param Position $position The position inside the text document
     * @psalm-return Promise<Hover>|Promise<null>
     */
    public function hover(TextDocumentIdentifier $textDocument, Position $position) : Promise
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        try {
            $reference_location = $this->codebase->getReferenceAtPosition($file_path, $position);
        } catch (UnanalyzedFileException $e) {
            $this->codebase->file_provider->openFile($file_path);
            $this->server->queueFileAnalysis($file_path, $textDocument->uri);
            return new Success(null);
        }
        if ($reference_location === null) {
            return new Success(null);
        }
        [$reference, $range] = $reference_location;
        $symbol_information = $this->codebase->getSymbolInformation($file_path, $reference);
        if ($symbol_information === null) {
            return new Success(null);
        }
        $content = "```php\n" . $symbol_information['type'] . "\n```";
        if (isset($symbol_information['description'])) {
            $content .= "\n---\n" . $symbol_information['description'];
        }
        $contents = new MarkupContent(MarkupKind::MARKDOWN, $content);
        return new Success(new Hover($contents, $range));
    }
    /**
     * The Completion request is sent from the client to the server to compute completion items at a given cursor
     * position. Completion items are presented in the IntelliSense user interface. If computing full completion items
     * is expensive, servers can additionally provide a handler for the completion item resolve request
     * ('completionItem/resolve'). This request is sent when a completion item is selected in the user interface. A
     * typically use case is for example: the 'textDocument/completion' request doesn't fill in the documentation
     * property for returned completion items since it is expensive to compute. When the item is selected in the user
     * interface then a 'completionItem/resolve' request is sent with the selected completion item as a param. The
     * returned completion item should have the documentation property filled in.
     *
     * @param TextDocumentIdentifier $textDocument The text document
     * @param Position $position The position
     * @psalm-return Promise<array<never, never>>|Promise<CompletionList>
     */
    public function completion(TextDocumentIdentifier $textDocument, Position $position) : Promise
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        if (!$this->codebase->config->isInProjectDirs($file_path)) {
            return new Success([]);
        }
        try {
            $completion_data = $this->codebase->getCompletionDataAtPosition($file_path, $position);
        } catch (UnanalyzedFileException $e) {
            $this->codebase->file_provider->openFile($file_path);
            $this->server->queueFileAnalysis($file_path, $textDocument->uri);
            return new Success([]);
        }
        try {
            $type_context = $this->codebase->getTypeContextAtPosition($file_path, $position);
        } catch (UnexpectedValueException $e) {
            error_log('completion errored at ' . $position->line . ':' . $position->character . ', Reason: ' . $e->getMessage());
            return new Success([]);
        }
        if (!$completion_data && !$type_context) {
            error_log('completion not found at ' . $position->line . ':' . $position->character);
            return new Success([]);
        }
        if ($completion_data) {
            [$recent_type, $gap, $offset] = $completion_data;
            if ($gap === '->' || $gap === '::') {
                $completion_items = $this->codebase->getCompletionItemsForClassishThing($recent_type, $gap);
            } elseif ($gap === '[') {
                $completion_items = $this->codebase->getCompletionItemsForArrayKeys($recent_type);
            } else {
                $completion_items = $this->codebase->getCompletionItemsForPartialSymbol($recent_type, $offset, $file_path);
            }
        } else {
            $completion_items = $this->codebase->getCompletionItemsForType($type_context);
        }
        return new Success(new CompletionList($completion_items, \false));
    }
    /**
     * The signature help request is sent from the client to the server to request signature
     * information at a given cursor position.
     */
    public function signatureHelp(TextDocumentIdentifier $textDocument, Position $position) : Promise
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        try {
            $argument_location = $this->codebase->getFunctionArgumentAtPosition($file_path, $position);
        } catch (UnanalyzedFileException $e) {
            $this->codebase->file_provider->openFile($file_path);
            $this->server->queueFileAnalysis($file_path, $textDocument->uri);
            return new Success(new SignatureHelp());
        }
        if ($argument_location === null) {
            return new Success(new SignatureHelp());
        }
        $signature_information = $this->codebase->getSignatureInformation($argument_location[0], $file_path);
        if (!$signature_information) {
            return new Success(new SignatureHelp());
        }
        return new Success(new SignatureHelp([$signature_information], 0, $argument_location[1]));
    }
    /**
     * The code action request is sent from the client to the server to compute commands
     * for a given text document and range. These commands are typically code fixes to
     * either fix problems or to beautify/refactor code.
     */
    public function codeAction(TextDocumentIdentifier $textDocument, Range $range) : Promise
    {
        $file_path = LanguageServer::uriToPath($textDocument->uri);
        if (!$this->codebase->file_provider->isOpen($file_path)) {
            return new Success(null);
        }
        $issues = $this->server->getCurrentIssues();
        if (empty($issues[$file_path])) {
            return new Success(null);
        }
        $file_contents = $this->codebase->getFileContents($file_path);
        $offsetStart = $range->start->toOffset($file_contents);
        $offsetEnd = $range->end->toOffset($file_contents);
        $fixers = [];
        foreach ($issues[$file_path] as $issue) {
            if ($offsetStart === $issue->from && $offsetEnd === $issue->to) {
                $snippetRange = new Range(new Position($issue->line_from - 1), new Position($issue->line_to));
                $indentation = '';
                if (preg_match('/^(\\s*)/', $issue->snippet, $matches)) {
                    $indentation = $matches[1] ?? '';
                }
                /**
                 * Suppress Psalm because ther are bugs in how
                 * LanguageServer's signature of WorkspaceEdit is declared:
                 *
                 * See:
                 * https://github.com/felixfbecker/php-language-server-protocol
                 * See:
                 * https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#workspaceEdit
                 */
                $edit = new WorkspaceEdit([$textDocument->uri => [new TextEdit($snippetRange, "{$indentation}/**\n" . "{$indentation} * @psalm-suppress {$issue->type}\n" . "{$indentation} */\n" . "{$issue->snippet}\n")]]);
                //Suppress Ability
                $fixers["suppress.{$issue->type}"] = ['title' => "Suppress {$issue->type} for this line", 'kind' => 'quickfix', 'edit' => $edit];
            }
        }
        if (empty($fixers)) {
            return new Success(null);
        }
        return new Success(array_values($fixers));
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer\Server;

use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\FileChangeType;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\FileEvent;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\LanguageServer\LanguageServer;
/**
 * Provides method handlers for all workspace/* methods
 *
 * @internal
 */
class Workspace
{
    protected LanguageServer $server;
    protected Codebase $codebase;
    protected ProjectAnalyzer $project_analyzer;
    public function __construct(LanguageServer $server, Codebase $codebase, ProjectAnalyzer $project_analyzer)
    {
        $this->server = $server;
        $this->codebase = $codebase;
        $this->project_analyzer = $project_analyzer;
    }
    /**
     * The watched files notification is sent from the client to the server when the client
     * detects changes to files and folders watched by the language client (note although
     * the name suggest that only file events are sent it is about file system events
     * which include folders as well). It is recommended that servers register for these
     * file system events using the registration mechanism. In former implementations clients
     * pushed file events without the server actively asking for it.
     *
     * @param FileEvent[] $changes
     * @psalm-suppress PossiblyUnusedMethod
     */
    public function didChangeWatchedFiles(array $changes) : void
    {
        foreach ($changes as $change) {
            $file_path = LanguageServer::uriToPath($change->uri);
            if ($change->type === FileChangeType::DELETED) {
                $this->codebase->invalidateInformationForFile($file_path);
                continue;
            }
            if (!$this->codebase->config->isInProjectDirs($file_path)) {
                continue;
            }
            if ($this->project_analyzer->onchange_line_limit === 0) {
                continue;
            }
            //If the file is currently open then dont analyse it because its tracked by the client
            if (!$this->codebase->file_provider->isOpen($file_path)) {
                $this->server->queueFileAnalysis($file_path, $change->uri);
            }
        }
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

/**
 * Generates unique, incremental IDs for use as request IDs
 *
 * @internal
 */
class IdGenerator
{
    public int $counter = 1;
    /**
     * Returns a unique ID
     */
    public function generate() : int
    {
        return $this->counter++;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer\Client;

use _HumbugBox1cb33d1f20f1\Amp\Promise;
use Generator;
use _HumbugBox1cb33d1f20f1\JsonMapper;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Diagnostic;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextDocumentIdentifier;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextDocumentItem;
use Psalm\Internal\LanguageServer\ClientHandler;
use function _HumbugBox1cb33d1f20f1\Amp\call;
/**
 * Provides method handlers for all textDocument/* methods
 *
 * @internal
 */
class TextDocument
{
    private ClientHandler $handler;
    private JsonMapper $mapper;
    public function __construct(ClientHandler $handler, JsonMapper $mapper)
    {
        $this->handler = $handler;
        $this->mapper = $mapper;
    }
    /**
     * Diagnostics notification are sent from the server to the client to signal results of validation runs.
     *
     * @param Diagnostic[] $diagnostics
     */
    public function publishDiagnostics(string $uri, array $diagnostics) : void
    {
        $this->handler->notify('textDocument/publishDiagnostics', ['uri' => $uri, 'diagnostics' => $diagnostics]);
    }
    /**
     * The content request is sent from a server to a client
     * to request the current content of a text document identified by the URI
     *
     * @param TextDocumentIdentifier $textDocument The document to get the content for
     * @return Promise<TextDocumentItem> The document's current content
     * @psalm-suppress MixedReturnTypeCoercion due to Psalm bug
     */
    public function xcontent(TextDocumentIdentifier $textDocument) : Promise
    {
        return call(
            /**
             * @return Generator<int, Promise<object>, object, TextDocumentItem>
             */
            function () use($textDocument) {
                /** @var Promise<object> */
                $promise = $this->handler->request('textDocument/xcontent', ['textDocument' => $textDocument]);
                $result = (yield $promise);
                /** @var TextDocumentItem */
                return $this->mapper->map($result, new TextDocumentItem());
            }
        );
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Dispatcher;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Error;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\ErrorCode;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\ErrorResponse;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Request;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Response;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\SuccessResponse;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use _HumbugBox1cb33d1f20f1\Amp\Success;
use Generator;
use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\JsonMapper;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\ClientCapabilities;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\CompletionOptions;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Diagnostic;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\DiagnosticSeverity;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\InitializeResult;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Position;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Range;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\SaveOptions;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\ServerCapabilities;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\SignatureHelpOptions;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextDocumentSyncKind;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextDocumentSyncOptions;
use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\LanguageServer\Server\TextDocument as ServerTextDocument;
use Psalm\Internal\LanguageServer\Server\Workspace as ServerWorkspace;
use Psalm\IssueBuffer;
use Throwable;
use function _HumbugBox1cb33d1f20f1\Amp\asyncCoroutine;
use function _HumbugBox1cb33d1f20f1\Amp\call;
use function array_combine;
use function array_keys;
use function array_map;
use function array_shift;
use function array_unshift;
use function explode;
use function implode;
use function max;
use function parse_url;
use function rawurlencode;
use function realpath;
use function str_replace;
use function strpos;
use function substr;
use function trim;
use function urldecode;
/**
 * @internal
 */
class LanguageServer extends Dispatcher
{
    /**
     * Handles textDocument/* method calls
     */
    public ?ServerTextDocument $textDocument = null;
    /**
     * Handles workspace/* method calls
     */
    public ?ServerWorkspace $workspace = null;
    protected \Psalm\Internal\LanguageServer\ProtocolReader $protocolReader;
    protected \Psalm\Internal\LanguageServer\ProtocolWriter $protocolWriter;
    public \Psalm\Internal\LanguageServer\LanguageClient $client;
    protected ProjectAnalyzer $project_analyzer;
    /**
     * @var array<string, string>
     */
    protected array $onsave_paths_to_analyze = [];
    /**
     * @var array<string, string>
     */
    protected array $onchange_paths_to_analyze = [];
    /**
     * @var array<string, list<IssueData>>
     */
    protected array $current_issues = [];
    /**
     * This should actually be a private property on `parent`
     *
     * @psalm-suppress UnusedProperty
     */
    protected JsonMapper $mapper;
    public function __construct(\Psalm\Internal\LanguageServer\ProtocolReader $reader, \Psalm\Internal\LanguageServer\ProtocolWriter $writer, ProjectAnalyzer $project_analyzer)
    {
        parent::__construct($this, '/');
        $this->project_analyzer = $project_analyzer;
        $this->protocolWriter = $writer;
        $this->protocolReader = $reader;
        $this->protocolReader->on('close', function () : void {
            $this->shutdown();
            $this->exit();
        });
        $this->protocolReader->on('message', asyncCoroutine(
            /**
             * @return Generator<int, Promise, mixed, void>
             */
            function (\Psalm\Internal\LanguageServer\Message $msg) : Generator {
                if (!$msg->body) {
                    return;
                }
                // Ignore responses, this is the handler for requests and notifications
                if (Response::isResponse($msg->body)) {
                    return;
                }
                $result = null;
                $error = null;
                try {
                    // Invoke the method handler to get a result
                    /**
                     * @var Promise
                     */
                    $dispatched = $this->dispatch($msg->body);
                    $result = (yield $dispatched);
                } catch (Error $e) {
                    // If a ResponseError is thrown, send it back in the Response
                    $error = $e;
                } catch (Throwable $e) {
                    // If an unexpected error occurred, send back an INTERNAL_ERROR error response
                    $error = new Error((string) $e, ErrorCode::INTERNAL_ERROR, null, $e);
                }
                // Only send a Response for a Request
                // Notifications do not send Responses
                /**
                 * @psalm-suppress UndefinedPropertyFetch
                 * @psalm-suppress MixedArgument
                 */
                if (Request::isRequest($msg->body)) {
                    if ($error !== null) {
                        $responseBody = new ErrorResponse($msg->body->id, $error);
                    } else {
                        $responseBody = new SuccessResponse($msg->body->id, $result);
                    }
                    (yield $this->protocolWriter->write(new \Psalm\Internal\LanguageServer\Message($responseBody)));
                }
            }
        ));
        $this->protocolReader->on('readMessageGroup', function () : void {
            $this->doAnalysis();
        });
        $this->client = new \Psalm\Internal\LanguageServer\LanguageClient($reader, $writer);
        $this->verboseLog("Language server has started.");
    }
    /**
     * The initialize request is sent as the first request from the client to the server.
     *
     * @param ClientCapabilities $capabilities The capabilities provided by the client (editor)
     * @param string|null $rootPath The rootPath of the workspace. Is null if no folder is open.
     * @param int|null $processId The process Id of the parent process that started the server.
     * Is null if the process has not been started by another process. If the parent process is
     * not alive then the server should exit (see exit notification) its process.
     * @psalm-return Promise<InitializeResult>
     * @psalm-suppress PossiblyUnusedMethod
     */
    public function initialize(ClientCapabilities $capabilities, ?string $rootPath = null, ?int $processId = null) : Promise
    {
        return call(
            /** @return Generator<int, true, mixed, InitializeResult> */
            function () : Generator {
                $this->verboseLog("Initializing...");
                $this->clientStatus('initializing');
                // Eventually, this might block on something. Leave it as a generator.
                /** @psalm-suppress TypeDoesNotContainType */
                if (\false) {
                    (yield \true);
                }
                $this->verboseLog("Initializing: Getting code base...");
                $this->clientStatus('initializing', 'getting code base');
                $codebase = $this->project_analyzer->getCodebase();
                $this->verboseLog("Initializing: Scanning files...");
                $this->clientStatus('initializing', 'scanning files');
                $codebase->scanFiles($this->project_analyzer->threads);
                $this->verboseLog("Initializing: Registering stub files...");
                $this->clientStatus('initializing', 'registering stub files');
                $codebase->config->visitStubFiles($codebase);
                if ($this->textDocument === null) {
                    $this->textDocument = new ServerTextDocument($this, $codebase, $this->project_analyzer);
                }
                if ($this->workspace === null) {
                    $this->workspace = new ServerWorkspace($this, $codebase, $this->project_analyzer);
                }
                $serverCapabilities = new ServerCapabilities();
                $textDocumentSyncOptions = new TextDocumentSyncOptions();
                $textDocumentSyncOptions->openClose = \true;
                $saveOptions = new SaveOptions();
                $saveOptions->includeText = \true;
                $textDocumentSyncOptions->save = $saveOptions;
                if ($this->project_analyzer->onchange_line_limit === 0) {
                    $textDocumentSyncOptions->change = TextDocumentSyncKind::NONE;
                } else {
                    $textDocumentSyncOptions->change = TextDocumentSyncKind::FULL;
                }
                $serverCapabilities->textDocumentSync = $textDocumentSyncOptions;
                // Support "Find all symbols"
                $serverCapabilities->documentSymbolProvider = \false;
                // Support "Find all symbols in workspace"
                $serverCapabilities->workspaceSymbolProvider = \false;
                // Support "Go to definition"
                $serverCapabilities->definitionProvider = \true;
                // Support "Find all references"
                $serverCapabilities->referencesProvider = \false;
                // Support "Hover"
                $serverCapabilities->hoverProvider = \true;
                // Support "Completion"
                $serverCapabilities->codeActionProvider = \true;
                // Support "Code Actions"
                if ($this->project_analyzer->provide_completion) {
                    $serverCapabilities->completionProvider = new CompletionOptions();
                    $serverCapabilities->completionProvider->resolveProvider = \false;
                    $serverCapabilities->completionProvider->triggerCharacters = ['$', '>', ':', "[", "(", ",", " "];
                }
                $serverCapabilities->signatureHelpProvider = new SignatureHelpOptions(['(', ',']);
                // Support global references
                $serverCapabilities->xworkspaceReferencesProvider = \false;
                $serverCapabilities->xdefinitionProvider = \false;
                $serverCapabilities->dependenciesProvider = \false;
                $this->verboseLog("Initializing: Complete.");
                $this->clientStatus('initialized');
                return new InitializeResult($serverCapabilities);
            }
        );
    }
    /**
     * @psalm-suppress PossiblyUnusedMethod
     */
    public function initialized() : void
    {
        $this->clientStatus('running');
    }
    public function queueTemporaryFileAnalysis(string $file_path, string $uri) : void
    {
        $this->onchange_paths_to_analyze[$file_path] = $uri;
    }
    public function queueFileAnalysis(string $file_path, string $uri) : void
    {
        $this->onsave_paths_to_analyze[$file_path] = $uri;
    }
    public function doAnalysis() : void
    {
        $this->clientStatus('analyzing');
        try {
            $codebase = $this->project_analyzer->getCodebase();
            $all_files_to_analyze = $this->onchange_paths_to_analyze + $this->onsave_paths_to_analyze;
            if (!$all_files_to_analyze) {
                return;
            }
            if ($this->onsave_paths_to_analyze) {
                $codebase->reloadFiles($this->project_analyzer, array_keys($this->onsave_paths_to_analyze));
            }
            if ($this->onchange_paths_to_analyze) {
                $codebase->reloadFiles($this->project_analyzer, array_keys($this->onchange_paths_to_analyze));
            }
            $all_file_paths_to_analyze = array_keys($all_files_to_analyze);
            $codebase->analyzer->addFilesToAnalyze(array_combine($all_file_paths_to_analyze, $all_file_paths_to_analyze));
            $codebase->analyzer->analyzeFiles($this->project_analyzer, 1, \false);
            $this->emitIssues($all_files_to_analyze);
            $this->onchange_paths_to_analyze = [];
            $this->onsave_paths_to_analyze = [];
        } finally {
            // we are done, so set the status back to running
            $this->clientStatus('running');
        }
    }
    /**
     * @param array<string, string> $uris
     */
    public function emitIssues(array $uris) : void
    {
        $data = IssueBuffer::clear();
        $this->current_issues = $data;
        foreach ($uris as $file_path => $uri) {
            $diagnostics = [];
            foreach ($data[$file_path] ?? [] as $issue_data) {
                //$check_name = $issue->check_name;
                $description = $issue_data->message;
                $severity = $issue_data->severity;
                $start_line = max($issue_data->line_from, 1);
                $end_line = $issue_data->line_to;
                $start_column = $issue_data->column_from;
                $end_column = $issue_data->column_to;
                // Language server has 0 based lines and columns, phan has 1-based lines and columns.
                $range = new Range(new Position($start_line - 1, $start_column - 1), new Position($end_line - 1, $end_column - 1));
                switch ($severity) {
                    case Config::REPORT_INFO:
                        $diagnostic_severity = DiagnosticSeverity::WARNING;
                        break;
                    case Config::REPORT_ERROR:
                    default:
                        $diagnostic_severity = DiagnosticSeverity::ERROR;
                        break;
                }
                $diagnostic = new Diagnostic($description, $range, null, $diagnostic_severity, 'Psalm');
                //$code = 'PS' . \str_pad((string) $issue_data->shortcode, 3, "0", \STR_PAD_LEFT);
                $code = $issue_data->link;
                if ($this->project_analyzer->language_server_use_extended_diagnostic_codes) {
                    // Added in VSCode 1.43.0 and will be part of the LSP 3.16.0 standard.
                    // Since this new functionality is not backwards compatible, we use a
                    // configuration option so the end user must opt in to it using the cli argument.
                    // https://github.com/microsoft/vscode/blob/1.43.0/src/vs/vscode.d.ts#L4688-L4699
                    /** @psalm-suppress InvalidPropertyAssignmentValue */
                    $diagnostic->code = ["value" => $code, "target" => $issue_data->link];
                } else {
                    // the Diagnostic constructor only takes `int` for the code, but the property can be
                    // `int` or `string`, so we set the property directly because we want to use a `string`
                    /** @psalm-suppress InvalidPropertyAssignmentValue */
                    $diagnostic->code = $code;
                }
                $diagnostics[] = $diagnostic;
            }
            $this->client->textDocument->publishDiagnostics($uri, $diagnostics);
        }
    }
    /**
     * The shutdown request is sent from the client to the server. It asks the server to shut down,
     * but to not exit (otherwise the response might not be delivered correctly to the client).
     * There is a separate exit notification that asks the server to exit.
     *
     * @psalm-suppress PossiblyUnusedReturnValue
     */
    public function shutdown() : Promise
    {
        $this->clientStatus('closing');
        $this->verboseLog("Shutting down...");
        $codebase = $this->project_analyzer->getCodebase();
        $scanned_files = $codebase->scanner->getScannedFiles();
        $codebase->file_reference_provider->updateReferenceCache($codebase, $scanned_files);
        $this->clientStatus('closed');
        return new Success(null);
    }
    /**
     * A notification to ask the server to exit its process.
     */
    public function exit() : void
    {
        exit(0);
    }
    /**
     * Send log message to the client
     *
     * @param string $message The log message to send to the client.
     * @psalm-param 1|2|3|4 $type
     * @param int $type The log type:
     *  - 1 = Error
     *  - 2 = Warning
     *  - 3 = Info
     *  - 4 = Log
     */
    public function verboseLog(string $message, int $type = 4) : void
    {
        if ($this->project_analyzer->language_server_verbose) {
            try {
                $this->client->logMessage('[Psalm ' . \PSALM_VERSION . ' - PHP Language Server] ' . $message, $type);
            } catch (Throwable $err) {
                // do nothing
            }
        }
        new Success(null);
    }
    /**
     * Send status message to client.  This is the same as sending a log message,
     * except this is meant for parsing by the client to present status updates in a UI.
     *
     * @param string $status The log message to send to the client. Should not contain colons `:`.
     * @param string|null $additional_info This is additional info that the client
     *                                       can use as part of the display message.
     */
    private function clientStatus(string $status, ?string $additional_info = null) : void
    {
        try {
            // here we send a notification to the client using the telemetry notification method
            $this->client->logMessage($status . (!empty($additional_info) ? ': ' . $additional_info : ''), 3, 'telemetry/event');
        } catch (Throwable $err) {
            // do nothing
        }
        new Success(null);
    }
    /**
     * Transforms an absolute file path into a URI as used by the language server protocol.
     *
     * @psalm-pure
     */
    public static function pathToUri(string $filepath) : string
    {
        $filepath = trim(str_replace('\\', '/', $filepath), '/');
        $parts = explode('/', $filepath);
        // Don't %-encode the colon after a Windows drive letter
        $first = array_shift($parts);
        if (substr($first, -1) !== ':') {
            $first = rawurlencode($first);
        }
        $parts = array_map('rawurlencode', $parts);
        array_unshift($parts, $first);
        $filepath = implode('/', $parts);
        return 'file:///' . $filepath;
    }
    /**
     * Transforms URI into file path
     */
    public static function uriToPath(string $uri) : string
    {
        $fragments = parse_url($uri);
        if ($fragments === \false || !isset($fragments['scheme']) || $fragments['scheme'] !== 'file' || !isset($fragments['path'])) {
            throw new InvalidArgumentException("Not a valid file URI: {$uri}");
        }
        $filepath = urldecode($fragments['path']);
        if (strpos($filepath, ':') !== \false) {
            if ($filepath[0] === '/') {
                $filepath = substr($filepath, 1);
            }
            $filepath = str_replace('/', '\\', $filepath);
        }
        $realpath = realpath($filepath);
        if ($realpath !== \false) {
            return $realpath;
        }
        return $filepath;
    }
    /**
     * Get the value of current_issues
     *
     * @return array<string, list<IssueData>>
     */
    public function getCurrentIssues() : array
    {
        return $this->current_issues;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use _HumbugBox1cb33d1f20f1\JsonMapper;
use Psalm\Internal\LanguageServer\Client\TextDocument as ClientTextDocument;
/**
 * @internal
 */
class LanguageClient
{
    /**
     * Handles textDocument/* methods
     */
    public ClientTextDocument $textDocument;
    /**
     * The client handler
     */
    private \Psalm\Internal\LanguageServer\ClientHandler $handler;
    public function __construct(\Psalm\Internal\LanguageServer\ProtocolReader $reader, \Psalm\Internal\LanguageServer\ProtocolWriter $writer)
    {
        $this->handler = new \Psalm\Internal\LanguageServer\ClientHandler($reader, $writer);
        $mapper = new JsonMapper();
        $this->textDocument = new ClientTextDocument($this->handler, $mapper);
    }
    /**
     * Send a log message to the client.
     *
     * @param string $message The message to send to the client.
     * @psalm-param 1|2|3|4 $type
     * @param int $type The log type:
     *  - 1 = Error
     *  - 2 = Warning
     *  - 3 = Info
     *  - 4 = Log
     */
    public function logMessage(string $message, int $type = 4, string $method = 'window/logMessage') : void
    {
        // https://microsoft.github.io/language-server-protocol/specifications/specification-current/#window_logMessage
        if ($type < 1 || $type > 4) {
            $type = 4;
        }
        $this->handler->notify($method, ['type' => $type, 'message' => $message]);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Notification;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Request;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Response;
use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\SuccessResponse;
use _HumbugBox1cb33d1f20f1\Amp\Deferred;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
use Generator;
use function _HumbugBox1cb33d1f20f1\Amp\call;
use function error_log;
/**
 * @internal
 */
class ClientHandler
{
    public \Psalm\Internal\LanguageServer\ProtocolReader $protocolReader;
    public \Psalm\Internal\LanguageServer\ProtocolWriter $protocolWriter;
    public \Psalm\Internal\LanguageServer\IdGenerator $idGenerator;
    public function __construct(\Psalm\Internal\LanguageServer\ProtocolReader $protocolReader, \Psalm\Internal\LanguageServer\ProtocolWriter $protocolWriter)
    {
        $this->protocolReader = $protocolReader;
        $this->protocolWriter = $protocolWriter;
        $this->idGenerator = new \Psalm\Internal\LanguageServer\IdGenerator();
    }
    /**
     * Sends a request to the client and returns a promise that is resolved with the result or rejected with the error
     *
     * @param string $method The method to call
     * @param array|object $params The method parameters
     * @return Promise<mixed> Resolved with the result of the request or rejected with an error
     */
    public function request(string $method, $params) : Promise
    {
        $id = $this->idGenerator->generate();
        return call(
            /**
             * @return Generator<int, Promise, mixed, Promise<mixed>>
             */
            function () use($id, $method, $params) : Generator {
                (yield $this->protocolWriter->write(new \Psalm\Internal\LanguageServer\Message(new Request($id, $method, (object) $params))));
                $deferred = new Deferred();
                $listener = function (\Psalm\Internal\LanguageServer\Message $msg) use($id, $deferred, &$listener) : void {
                    error_log('request handler');
                    /**
                     * @psalm-suppress UndefinedPropertyFetch
                     * @psalm-suppress MixedArgument
                     */
                    if ($msg->body && Response::isResponse($msg->body) && $msg->body->id === $id) {
                        // Received a response
                        $this->protocolReader->removeListener('message', $listener);
                        if (SuccessResponse::isSuccessResponse($msg->body)) {
                            $deferred->resolve($msg->body->result);
                        } else {
                            $deferred->fail($msg->body->error);
                        }
                    }
                };
                $this->protocolReader->on('message', $listener);
                return $deferred->promise();
            }
        );
    }
    /**
     * Sends a notification to the client
     *
     * @param string $method The method to call
     * @param array|object $params The method parameters
     */
    public function notify(string $method, $params) : void
    {
        $this->protocolWriter->write(new \Psalm\Internal\LanguageServer\Message(new Notification($method, (object) $params)));
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use _HumbugBox1cb33d1f20f1\Amp\ByteStream\ResourceOutputStream;
use _HumbugBox1cb33d1f20f1\Amp\Promise;
/**
 * @internal
 */
class ProtocolStreamWriter implements \Psalm\Internal\LanguageServer\ProtocolWriter
{
    private ResourceOutputStream $output;
    /**
     * @param resource $output
     */
    public function __construct($output)
    {
        $this->output = new ResourceOutputStream($output);
    }
    /**
     * {@inheritdoc}
     */
    public function write(\Psalm\Internal\LanguageServer\Message $msg) : Promise
    {
        return $this->output->write((string) $msg);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use _HumbugBox1cb33d1f20f1\AdvancedJsonRpc\Message as MessageBody;
use function array_pop;
use function explode;
use function strlen;
/**
 * @internal
 */
class Message
{
    public ?MessageBody $body = null;
    /**
     * @var string[]
     */
    public array $headers;
    /**
     * Parses a message
     *
     * @psalm-suppress UnusedMethod
     */
    public static function parse(string $msg) : \Psalm\Internal\LanguageServer\Message
    {
        $obj = new self();
        $parts = explode("\r\n", $msg);
        $obj->body = MessageBody::parse(array_pop($parts));
        foreach ($parts as $line) {
            if ($line) {
                $pair = explode(': ', $line);
                $obj->headers[$pair[0]] = $pair[1];
            }
        }
        return $obj;
    }
    /**
     * @param string[] $headers
     */
    public function __construct(?MessageBody $body = null, array $headers = [])
    {
        $this->body = $body;
        if (!isset($headers['Content-Type'])) {
            $headers['Content-Type'] = 'application/vscode-jsonrpc; charset=utf8';
        }
        $this->headers = $headers;
    }
    public function __toString() : string
    {
        $body = (string) $this->body;
        $contentLength = strlen($body);
        $this->headers['Content-Length'] = (string) $contentLength;
        $headers = '';
        foreach ($this->headers as $name => $value) {
            $headers .= "{$name}: {$value}\r\n";
        }
        return $headers . "\r\n" . $body;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\LanguageServer;

use function array_multisort;
use function call_user_func_array;
use function count;
use const SORT_NUMERIC;
/**
 * Event Emitter Trait
 *
 * This trait contains all the basic functions to implement an
 * EventEmitterInterface.
 *
 * Using the trait + interface allows you to add EventEmitter capabilities
 * without having to change your base-class.
 *
 * @copyright Copyright (C) fruux GmbH (https://fruux.com/)
 * @author Evert Pot (http://evertpot.com/)
 * @license http://sabre.io/license/ Modified BSD License
 * @internal
 */
trait EmitterTrait
{
    /**
     * The list of listeners
     *
     * @var array<string, array{0: bool, 1: int[], 2: callable[]}>
     */
    protected array $listeners = [];
    /**
     * Subscribe to an event.
     */
    public function on(string $eventName, callable $callBack, int $priority = 100) : void
    {
        if (!isset($this->listeners[$eventName])) {
            $this->listeners[$eventName] = [
                \true,
                // If there's only one item, it's sorted
                [$priority],
                [$callBack],
            ];
        } else {
            $this->listeners[$eventName][0] = \false;
            // marked as unsorted
            $this->listeners[$eventName][1][] = $priority;
            $this->listeners[$eventName][2][] = $callBack;
        }
    }
    /**
     * Emits an event.
     *
     * This method will return true if 0 or more listeners were successfully
     * handled. false is returned if one of the events broke the event chain.
     *
     * If the continueCallBack is specified, this callback will be called every
     * time before the next event handler is called.
     *
     * If the continueCallback returns false, event propagation stops. This
     * allows you to use the eventEmitter as a means for listeners to implement
     * functionality in your application, and break the event loop as soon as
     * some condition is fulfilled.
     *
     * Note that returning false from an event subscriber breaks propagation
     * and returns false, but if the continue-callback stops propagation, this
     * is still considered a 'successful' operation and returns true.
     *
     * Lastly, if there are 5 event handlers for an event. The continueCallback
     * will be called at most 4 times.
     *
     * @param list<mixed> $arguments
     */
    public function emit(string $eventName, array $arguments = [], ?callable $continueCallBack = null) : void
    {
        if ($continueCallBack === null) {
            foreach ($this->listeners($eventName) as $listener) {
                /** @psalm-suppress MixedAssignment */
                $result = call_user_func_array($listener, $arguments);
                if ($result === \false) {
                    return;
                }
            }
        } else {
            $listeners = $this->listeners($eventName);
            $counter = count($listeners);
            foreach ($listeners as $listener) {
                --$counter;
                /** @psalm-suppress MixedAssignment */
                $result = call_user_func_array($listener, $arguments);
                if ($result === \false) {
                    return;
                }
                if ($counter > 0) {
                    if (!$continueCallBack()) {
                        break;
                    }
                }
            }
        }
    }
    /**
     * Returns the list of listeners for an event.
     *
     * The list is returned as an array, and the list of events are sorted by
     * their priority.
     *
     * @return callable[]
     */
    public function listeners(string $eventName) : array
    {
        if (!isset($this->listeners[$eventName])) {
            return [];
        }
        // The list is not sorted
        if (!$this->listeners[$eventName][0]) {
            // Sorting
            array_multisort($this->listeners[$eventName][1], SORT_NUMERIC, $this->listeners[$eventName][2]);
            // Marking the listeners as sorted
            $this->listeners[$eventName][0] = \true;
        }
        return $this->listeners[$eventName][2];
    }
    /**
     * Removes a specific listener from an event.
     *
     * If the listener could not be found, this method will return false. If it
     * was removed it will return true.
     */
    public function removeListener(string $eventName, callable $listener) : bool
    {
        if (!isset($this->listeners[$eventName])) {
            return \false;
        }
        foreach ($this->listeners[$eventName][2] as $index => $check) {
            if ($check === $listener) {
                unset($this->listeners[$eventName][1][$index], $this->listeners[$eventName][2][$index]);
                return \true;
            }
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal;

use function array_diff;
use function array_unique;
use function array_values;
use function get_included_files;
use function preg_grep;
use const PREG_GREP_INVERT;
/**
 * Include collector
 *
 * Used to execute code that may cause file inclusions, and report what files have been included
 * NOTE: dependencies of this class should be kept at minimum, as it's used before autoloader is
 * registered.
 *
 * @internal
 */
final class IncludeCollector
{
    /** @var list<string> */
    private array $included_files = [];
    /**
     * @template T
     * @param callable():T $f
     * @return T
     */
    public function runAndCollect(callable $f)
    {
        $before = get_included_files();
        $ret = $f();
        $after = get_included_files();
        $included = array_diff($after, $before);
        $this->included_files = array_values(array_unique([...$this->included_files, ...$included]));
        return $ret;
    }
    /** @return list<string> */
    public function getIncludedFiles() : array
    {
        return $this->included_files;
    }
    /** @return list<string> */
    public function getFilteredIncludedFiles() : array
    {
        return array_values(preg_grep('@^phar://@', $this->getIncludedFiles(), PREG_GREP_INVERT));
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function is_int;
use function is_string;
/**
 * @internal
 */
class TypeCombination
{
    /** @var array<string, Atomic> */
    public array $value_types = [];
    /** @var array<string, TNamedObject>|null */
    public ?array $named_object_types = [];
    /** @var list<Union> */
    public array $array_type_params = [];
    /** @var array<string, non-empty-list<Union>> */
    public array $builtin_type_params = [];
    /** @var array<string, non-empty-list<Union>> */
    public array $object_type_params = [];
    /** @var array<string, bool> */
    public array $object_static = [];
    /** @var array<int, bool>|null */
    public ?array $array_counts = [];
    /** @var array<int, bool>|null */
    public ?array $array_min_counts = [];
    public bool $array_sometimes_filled = \false;
    public bool $array_always_filled = \true;
    /** @var array<string|int, Union> */
    public array $objectlike_entries = [];
    public bool $objectlike_sealed = \true;
    public ?Union $objectlike_key_type = null;
    public ?Union $objectlike_value_type = null;
    public bool $empty_mixed = \false;
    public bool $non_empty_mixed = \false;
    public ?bool $mixed_from_loop_isset = null;
    /** @var array<string, TLiteralString>|null */
    public ?array $strings = [];
    /** @var array<string, TLiteralInt>|null */
    public ?array $ints = [];
    /** @var array<string, TLiteralFloat>|null */
    public ?array $floats = [];
    /** @var array<string, TNamedObject|TObject>|null */
    public ?array $class_string_types = [];
    /**
     * @var array<string, TNamedObject|TTemplateParam|TIterable|TObject>
     */
    public array $extra_types = [];
    public ?bool $all_arrays_lists = null;
    public ?bool $all_arrays_callable = null;
    public ?bool $all_arrays_class_string_maps = null;
    /** @var array<string, bool> */
    public array $class_string_map_names = [];
    /** @var array<string, ?TNamedObject> */
    public array $class_string_map_as_types = [];
    /**
     * @psalm-assert-if-true !null $this->objectlike_key_type
     * @psalm-assert-if-true !null $this->objectlike_value_type
     * @param array-key $k
     */
    public function fallbackKeyContains($k) : bool
    {
        if (!$this->objectlike_key_type) {
            return \false;
        }
        foreach ($this->objectlike_key_type->getAtomicTypes() as $t) {
            if ($t instanceof TArrayKey) {
                return \true;
            } elseif ($t instanceof TLiteralInt || $t instanceof TLiteralString) {
                if ($t->value === $k) {
                    return \true;
                }
            } elseif ($t instanceof TIntRange) {
                if (is_int($k) && $t->contains($k)) {
                    return \true;
                }
            } elseif ($t instanceof TString && is_string($k)) {
                return \true;
            } elseif ($t instanceof TInt && is_int($k)) {
                return \true;
            }
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal\Type;

use AssertionError;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\Codebase\ClassConstantByWildcardResolver;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\Any;
use Psalm\Storage\Assertion\ArrayKeyExists;
use Psalm\Storage\Assertion\HasArrayKey;
use Psalm\Storage\Assertion\HasAtLeastCount;
use Psalm\Storage\Assertion\HasExactCount;
use Psalm\Storage\Assertion\HasIntOrStringArrayAccess;
use Psalm\Storage\Assertion\HasMethod;
use Psalm\Storage\Assertion\HasStringArrayAccess;
use Psalm\Storage\Assertion\InArray;
use Psalm\Storage\Assertion\IsCountable;
use Psalm\Storage\Assertion\IsEqualIsset;
use Psalm\Storage\Assertion\IsGreaterThan;
use Psalm\Storage\Assertion\IsIsset;
use Psalm\Storage\Assertion\IsLessThan;
use Psalm\Storage\Assertion\IsLooselyEqual;
use Psalm\Storage\Assertion\IsType;
use Psalm\Storage\Assertion\NonEmpty;
use Psalm\Storage\Assertion\NonEmptyCountable;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Type;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableArray;
use Psalm\Type\Atomic\TCallableKeyedArray;
use Psalm\Type\Atomic\TCallableObject;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonEmptyMixed;
use Psalm\Type\Atomic\TNonEmptyNonspecificLiteralString;
use Psalm\Type\Atomic\TNonEmptyScalar;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonFalsyString;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TResource;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use function array_map;
use function array_merge;
use function assert;
use function count;
use function explode;
use function get_class;
use function min;
use function strlen;
use function strpos;
use function strtolower;
/**
 * This class receives a known type and an assertion (probably coming from AssertionFinder). The goal is to refine
 * the known type using the assertion. For example: old type is `int` assertion is `>5` result is `int<6, max>`.
 * Complex reconciliation takes part in AssertionReconciler if this class couldn't handle the reconciliation
 *
 * @internal
 */
class SimpleAssertionReconciler extends Reconciler
{
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    public static function reconcile(Assertion $assertion, Codebase $codebase, Union $existing_var_type, ?string $key = null, bool $negated = \false, ?CodeLocation $code_location = null, array $suppressed_issues = [], int &$failed_reconciliation = Reconciler::RECONCILIATION_OK, bool $inside_loop = \false) : ?Union
    {
        if ($assertion instanceof Any) {
            return $existing_var_type;
        }
        $old_var_type_string = $existing_var_type->getId();
        $is_equality = $assertion->hasEquality();
        if ($assertion instanceof IsIsset || $assertion instanceof IsEqualIsset) {
            return self::reconcileIsset($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $assertion instanceof IsEqualIsset, $inside_loop);
        }
        if ($assertion instanceof ArrayKeyExists) {
            return $existing_var_type->setPossiblyUndefined(\false);
        }
        if ($assertion instanceof InArray) {
            return self::reconcileInArray($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation);
        }
        if ($assertion instanceof HasArrayKey) {
            return self::reconcileHasArrayKey($existing_var_type, $assertion);
        }
        if ($assertion instanceof IsGreaterThan) {
            return self::reconcileIsGreaterThan($assertion, $existing_var_type, $inside_loop, $old_var_type_string, $key, $negated, $code_location, $suppressed_issues);
        }
        if ($assertion instanceof IsLessThan) {
            return self::reconcileIsLessThan($assertion, $existing_var_type, $inside_loop, $old_var_type_string, $key, $negated, $code_location, $suppressed_issues);
        }
        if ($assertion instanceof Truthy || $assertion instanceof NonEmpty) {
            return self::reconcileTruthyOrNonEmpty($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, \false);
        }
        if ($assertion instanceof IsCountable) {
            return self::reconcileCountable($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion instanceof HasStringArrayAccess) {
            return self::reconcileStringArrayAccess($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $inside_loop);
        }
        if ($assertion instanceof HasIntOrStringArrayAccess) {
            return self::reconcileIntArrayAccess($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $inside_loop);
        }
        if ($assertion instanceof NonEmptyCountable) {
            return self::reconcileNonEmptyCountable($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $is_equality);
        }
        if ($assertion instanceof HasAtLeastCount) {
            return self::reconcileNonEmptyCountable($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $is_equality);
        }
        if ($assertion instanceof HasExactCount) {
            return self::reconcileExactlyCountable($existing_var_type, $assertion, $key, $negated, $code_location, $suppressed_issues, $is_equality);
        }
        if ($assertion instanceof HasMethod) {
            return self::reconcileHasMethod($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation);
        }
        $assertion_type = $assertion->getAtomicType();
        if ($assertion_type instanceof TObject) {
            return self::reconcileObject($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TResource) {
            return self::reconcileResource($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TCallable) {
            return self::reconcileCallable($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TIterable && $assertion_type->type_params[0]->isMixed() && $assertion_type->type_params[1]->isMixed()) {
            return self::reconcileIterable($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TArray && $assertion_type->type_params[0]->isArrayKey() && $assertion_type->type_params[1]->isMixed()) {
            return self::reconcileArray($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TList) {
            $assertion_type = $assertion_type->getKeyedArray();
        }
        if ($assertion_type instanceof TKeyedArray && $assertion_type->is_list && $assertion_type->getGenericValueType()->isMixed()) {
            return self::reconcileList($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality, $assertion_type->isNonEmpty());
        }
        if ($assertion_type instanceof TNamedObject && $assertion_type->value === 'Traversable') {
            return self::reconcileTraversable($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TNumeric) {
            return self::reconcileNumeric($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TScalar) {
            return self::reconcileScalar($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && get_class($assertion_type) === TBool::class) {
            return self::reconcileBool($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && $assertion_type instanceof TTrue) {
            return self::reconcileTrue($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && $assertion_type instanceof TFalse) {
            return self::reconcileFalse($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && get_class($assertion_type) === TString::class) {
            return self::reconcileString($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && get_class($assertion_type) === TInt::class) {
            return self::reconcileInt($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation);
        }
        if ($assertion_type instanceof TFloat) {
            if ($existing_var_type->from_calculation && $existing_var_type->hasInt()) {
                return Type::getFloat();
            }
            if ($assertion instanceof IsLooselyEqual && $existing_var_type->isString()) {
                return Type::getNumericString();
            }
        }
        if ($assertion_type instanceof TClassConstant) {
            return self::reconcileClassConstant($codebase, $assertion_type, $existing_var_type, $failed_reconciliation);
        }
        if ($existing_var_type->isSingle() && $existing_var_type->hasTemplate()) {
            $types = $existing_var_type->getAtomicTypes();
            foreach ($types as $k => $atomic_type) {
                if ($atomic_type instanceof TTemplateParam && $assertion_type) {
                    if ($atomic_type->as->hasMixed() || $atomic_type->as->hasObject()) {
                        unset($types[$k]);
                        $atomic_type = $atomic_type->replaceAs(new Union([$assertion_type]));
                        $types[$atomic_type->getKey()] = $atomic_type;
                        return new Union($types);
                    }
                }
            }
        }
        return null;
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileIsset(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality, bool $inside_loop) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        $old_var_type_string = $existing_var_type->getId();
        // if key references an array offset
        $redundant = !($key && strpos($key, '[') || !$existing_var_type->initialized || $existing_var_type->possibly_undefined || $existing_var_type->ignore_isset);
        if ($existing_var_type->isNullable()) {
            $existing_var_type->removeType('null');
            $redundant = \false;
        }
        if (!$existing_var_type->hasMixed() && !$is_equality && ($redundant || $existing_var_type->isUnionEmpty()) && $key && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            if ($existing_var_type->isUnionEmpty()) {
                $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
                return Type::getNever();
            }
        }
        if ($inside_loop) {
            if ($existing_var_type->hasType('never')) {
                $existing_var_type->removeType('never');
                $existing_var_type->addType(new TMixed(\true));
            }
        }
        $existing_var_type->from_property = \false;
        $existing_var_type->from_static_property = \false;
        $existing_var_type->possibly_undefined = \false;
        $existing_var_type->possibly_undefined_from_try = \false;
        $existing_var_type->ignore_isset = \false;
        return $existing_var_type->freeze();
    }
    /**
     * @param NonEmptyCountable|HasAtLeastCount $assertion
     * @param   string[]  $suppressed_issues
     */
    private static function reconcileNonEmptyCountable(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_type = $existing_var_type->getBuilder();
        if ($existing_var_type->hasType('array')) {
            $array_atomic_type = $existing_var_type->getArray();
            $redundant = \true;
            if ($array_atomic_type instanceof TArray) {
                if (!$array_atomic_type instanceof TNonEmptyArray || $assertion instanceof HasAtLeastCount && $array_atomic_type->min_count < $assertion->count) {
                    if ($array_atomic_type->isEmptyArray()) {
                        $existing_var_type->removeType('array');
                    } else {
                        $non_empty_array = new TNonEmptyArray($array_atomic_type->type_params, null, $assertion instanceof HasAtLeastCount ? $assertion->count : null);
                        $existing_var_type->addType($non_empty_array);
                    }
                    $redundant = \false;
                }
            } elseif ($array_atomic_type instanceof TKeyedArray) {
                $prop_max_count = count($array_atomic_type->properties);
                $prop_min_count = $array_atomic_type->getMinCount();
                if ($assertion instanceof HasAtLeastCount) {
                    // count($a) > 3
                    // count($a) >= 4
                    // 4
                    $count = $assertion->count;
                } else {
                    // count($a) >= 1
                    $count = 1;
                }
                if ($array_atomic_type->fallback_params === null) {
                    // We're asserting that count($a) >= $count
                    // If it's impossible, remove the type
                    // If it's possible but redundant, mark as redundant
                    // If it's possible, mark as not redundant
                    // Impossible because count($a) < $count always
                    if ($prop_max_count < $count) {
                        $redundant = \false;
                        $existing_var_type->removeType('array');
                        // Redundant because count($a) >= $count always
                    } elseif ($prop_min_count >= $count) {
                        $redundant = \true;
                        // If count($a) === $count and there are possibly undefined properties
                    } elseif ($prop_max_count === $count && $prop_min_count !== $prop_max_count) {
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType($array_atomic_type->setProperties(array_map(fn(Union $union) => $union->setPossiblyUndefined(\false), $array_atomic_type->properties)));
                        $redundant = \false;
                        // Possible, alter type if we're a list
                    } elseif ($array_atomic_type->is_list) {
                        // Possible
                        $redundant = \false;
                        $properties = $array_atomic_type->properties;
                        for ($i = $prop_min_count; $i < $count; $i++) {
                            $properties[$i] = $properties[$i]->setPossiblyUndefined(\false);
                        }
                        $array_atomic_type = $array_atomic_type->setProperties($properties);
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType($array_atomic_type);
                    } else {
                        $redundant = \false;
                    }
                } elseif ($array_atomic_type->is_list) {
                    if ($count <= $prop_min_count) {
                        $redundant = \true;
                    } else {
                        $redundant = \false;
                        $properties = $array_atomic_type->properties;
                        for ($i = $prop_min_count; $i < $count; $i++) {
                            $properties[$i] = isset($properties[$i]) ? $properties[$i]->setPossiblyUndefined(\false) : $array_atomic_type->fallback_params[1];
                        }
                        $array_atomic_type = $array_atomic_type->setProperties($properties);
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType($array_atomic_type);
                    }
                } else {
                    $redundant = \false;
                }
            }
            if (!$is_equality && !$existing_var_type->hasMixed() && ($redundant || $existing_var_type->isUnionEmpty())) {
                if ($key && $code_location) {
                    self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
                }
            }
        }
        return $existing_var_type->freeze();
    }
    /**
     * @param array<string> $suppressed_issues
     */
    private static function reconcileExactlyCountable(Union $existing_var_type, HasExactCount $assertion, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, bool $is_equality) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        if ($existing_var_type->hasType('array')) {
            $old_var_type_string = $existing_var_type->getId();
            $array_atomic_type = $existing_var_type->getArray();
            $redundant = \true;
            if ($array_atomic_type instanceof TArray) {
                if (!$array_atomic_type instanceof TNonEmptyArray || $array_atomic_type->count !== $assertion->count) {
                    $non_empty_array = new TNonEmptyArray($array_atomic_type->type_params, $assertion->count);
                    $existing_var_type->removeType('array');
                    $existing_var_type->addType($non_empty_array);
                    $redundant = \false;
                } else {
                    $redundant = \true;
                }
            } elseif ($array_atomic_type instanceof TKeyedArray) {
                $prop_max_count = count($array_atomic_type->properties);
                $prop_min_count = $array_atomic_type->getMinCount();
                if ($assertion->count < $prop_min_count) {
                    // Impossible
                    $existing_var_type->removeType('array');
                    $redundant = \false;
                } elseif ($array_atomic_type->fallback_params === null) {
                    if ($assertion->count === $prop_min_count) {
                        // Redundant
                        $redundant = \true;
                    } elseif ($assertion->count > $prop_max_count) {
                        // Impossible
                        $existing_var_type->removeType('array');
                        $redundant = \false;
                    } elseif ($assertion->count === $prop_max_count) {
                        $redundant = \false;
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType($array_atomic_type->setProperties(array_map(fn(Union $union) => $union->setPossiblyUndefined(\false), $array_atomic_type->properties)));
                    } elseif ($array_atomic_type->is_list) {
                        $redundant = \false;
                        $properties = $array_atomic_type->properties;
                        for ($x = $prop_min_count; $x < $assertion->count; $x++) {
                            $properties[$x] = $properties[$x]->setPossiblyUndefined(\false);
                        }
                        $array_atomic_type = $array_atomic_type->setProperties($properties);
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType($array_atomic_type);
                    } else {
                        $redundant = \false;
                    }
                } else {
                    if ($array_atomic_type->is_list) {
                        $redundant = \false;
                        $properties = $array_atomic_type->properties;
                        for ($x = $prop_min_count; $x < $assertion->count; $x++) {
                            $properties[$x] = isset($properties[$x]) ? $properties[$x]->setPossiblyUndefined(\false) : $array_atomic_type->fallback_params[1];
                        }
                        $array_atomic_type = new TKeyedArray($properties, null, null, \true);
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType($array_atomic_type);
                    } elseif ($prop_max_count === $prop_min_count && $prop_max_count === $assertion->count) {
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType($array_atomic_type->makeSealed());
                    }
                }
            }
            if (!$is_equality && !$existing_var_type->hasMixed() && ($redundant || $existing_var_type->isUnionEmpty())) {
                if ($key && $code_location) {
                    self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
                }
            }
        }
        return $existing_var_type->freeze();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileHasMethod(HasMethod $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation) : Union
    {
        $method_name = $assertion->method;
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $object_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TNamedObject && $codebase->classOrInterfaceExists($type->value)) {
                if (!$codebase->methodExists($type->value . '::' . $method_name)) {
                    $match_found = \false;
                    $extra_types = $type->extra_types;
                    foreach ($type->extra_types as $k => $extra_type) {
                        if ($extra_type instanceof TNamedObject && $codebase->classOrInterfaceExists($extra_type->value) && $codebase->methodExists($extra_type->value . '::' . $method_name)) {
                            $match_found = \true;
                        } elseif ($extra_type instanceof TObjectWithProperties) {
                            $match_found = \true;
                            if (!isset($extra_type->methods[strtolower($method_name)])) {
                                unset($extra_types[$k]);
                                $extra_type = $extra_type->setMethods(array_merge($extra_type->methods, [strtolower($method_name) => 'object::' . $method_name]));
                                $extra_types[$extra_type->getKey()] = $extra_type;
                                $redundant = \false;
                            }
                        }
                    }
                    if (!$match_found) {
                        $extra_type = new TObjectWithProperties([], [strtolower($method_name) => $type->value . '::' . $method_name]);
                        $extra_types[$extra_type->getKey()] = $extra_type;
                        $redundant = \false;
                    }
                    $type = $type->setIntersectionTypes($extra_types);
                }
                $object_types[] = $type;
            } elseif ($type instanceof TObjectWithProperties) {
                if (!isset($type->methods[strtolower($method_name)])) {
                    $type = $type->setMethods(array_merge($type->methods, [strtolower($method_name) => 'object::' . $method_name]));
                    $redundant = \false;
                }
                $object_types[] = $type;
            } elseif ($type instanceof TObject || $type instanceof TMixed) {
                $object_types[] = new TObjectWithProperties([], [strtolower($method_name) => 'object::' . $method_name]);
                $redundant = \false;
            } elseif ($type instanceof TString) {
                // we don’t know
                $object_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                $object_types[] = $type;
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if (!$object_types || $redundant) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($object_types) {
            return new Union($object_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? new Union([new TEmptyMixed()]) : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileString(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed()) {
            if ($assertion instanceof IsLooselyEqual) {
                return $existing_var_type;
            }
            return Type::getString();
        }
        $string_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TString) {
                if (get_class($type) === TString::class) {
                    $type = $type->setFromDocblock(\false);
                }
                $string_types[] = $type;
            } elseif ($type instanceof TCallable) {
                $string_types[] = new TCallableString();
                $redundant = \false;
            } elseif ($type instanceof TNumeric) {
                $string_types[] = new TNumericString();
                $redundant = \false;
            } elseif ($type instanceof TScalar || $type instanceof TArrayKey) {
                $string_types[] = new TString();
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasString() || $type->as->hasMixed() || $type->as->hasScalar()) {
                    $type = $type->replaceAs(self::reconcileString($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $string_types[] = $type;
                }
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if (($redundant || !$string_types) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($string_types) {
            return new Union($string_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? new Union([new TEmptyMixed()]) : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileInt(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation) : Union
    {
        if ($existing_var_type->hasMixed()) {
            if ($assertion instanceof IsLooselyEqual) {
                return $existing_var_type;
            }
            return Type::getInt();
        }
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $int_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TInt) {
                if (get_class($type) === TInt::class) {
                    $type = $type->setFromDocblock(\false);
                }
                $int_types[] = $type;
                if ($existing_var_type->from_calculation) {
                    $redundant = \false;
                }
            } elseif ($type instanceof TNumeric) {
                $int_types[] = new TInt();
                $redundant = \false;
            } elseif ($type instanceof TScalar || $type instanceof TArrayKey) {
                $int_types[] = new TInt();
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasInt() || $type->as->hasMixed()) {
                    $type = $type->replaceAs(self::reconcileInt($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation));
                    $int_types[] = $type;
                }
                $redundant = \false;
            } elseif ($type instanceof TString && $assertion instanceof IsLooselyEqual) {
                $int_types[] = new TNumericString();
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if (($redundant || !$int_types) && $assertion instanceof IsType) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($int_types) {
            return new Union($int_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? new Union([new TEmptyMixed()]) : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileBool(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::getBool();
        }
        $bool_types = [];
        $redundant = \true;
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TBool) {
                $type = $type->setFromDocblock(\false);
                $bool_types[] = $type;
            } elseif ($type instanceof TScalar) {
                $bool_types[] = new TBool();
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasBool() || $type->as->hasMixed()) {
                    $type = $type->replaceAs(self::reconcileBool($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $bool_types[] = $type;
                }
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if (($redundant || !$bool_types) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($bool_types) {
            return new Union($bool_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param string[] $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileFalse(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::getFalse();
        }
        if ($existing_var_type->hasScalar()) {
            return Type::getFalse();
        }
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $false_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TFalse) {
                $false_types[] = $type;
            } elseif ($type instanceof TBool) {
                $false_types[] = new TFalse();
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam && $type->as->isMixed()) {
                $type = $type->replaceAs(Type::getFalse());
                $false_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasScalar() || $type->as->hasMixed() || $type->as->hasBool()) {
                    $type = $type->replaceAs(self::reconcileFalse($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $false_types[] = $type;
                }
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$false_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($false_types) {
            return new Union($false_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param string[] $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileTrue(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::getTrue();
        }
        if ($existing_var_type->hasScalar()) {
            return Type::getTrue();
        }
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $true_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TTrue) {
                $true_types[] = $type;
            } elseif ($type instanceof TBool) {
                $true_types[] = new TTrue();
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam && $type->as->isMixed()) {
                $type = $type->replaceAs(Type::getTrue());
                $true_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasScalar() || $type->as->hasMixed() || $type->as->hasBool()) {
                    $type = $type->replaceAs(self::reconcileTrue($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $true_types[] = $type;
                }
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$true_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($true_types) {
            return new Union($true_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileScalar(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::getScalar();
        }
        $scalar_types = [];
        $redundant = \true;
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof Scalar) {
                $scalar_types[] = $type;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasScalar() || $type->as->hasMixed()) {
                    $type = $type->replaceAs(self::reconcileScalar($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $scalar_types[] = $type;
                }
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if (($redundant || !$scalar_types) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($scalar_types) {
            return new Union($scalar_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileNumeric(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::getNumeric();
        }
        $existing_var_type = $existing_var_type->getBuilder();
        $old_var_type_string = $existing_var_type->getId();
        $numeric_types = [];
        $redundant = \true;
        if ($existing_var_type->hasString()) {
            $redundant = \false;
            $existing_var_type->removeType('string');
            $existing_var_type->addType(new TNumericString());
        }
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TNumeric || $type instanceof TNumericString) {
                // this is a workaround for a possible issue running
                // is_numeric($a) && is_string($a)
                $redundant = \false;
                $numeric_types[] = $type;
            } elseif ($type->isNumericType()) {
                $numeric_types[] = $type;
            } elseif ($type instanceof TScalar) {
                $redundant = \false;
                $numeric_types[] = new TNumeric();
            } elseif ($type instanceof TArrayKey) {
                $redundant = \false;
                $numeric_types[] = new TInt();
                $numeric_types[] = new TNumericString();
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasNumeric() || $type->as->hasMixed()) {
                    $type = $type->replaceAs(self::reconcileNumeric($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $numeric_types[] = $type;
                }
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if (($redundant || !$numeric_types) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($numeric_types) {
            return new Union($numeric_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileObject(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::getObject();
        }
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $object_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type->isObjectType()) {
                $object_types[] = $type;
            } elseif ($type instanceof TCallable) {
                $object_types[] = new TCallableObject();
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam && $type->as->isMixed()) {
                $type = $type->replaceAs(Type::getObject());
                $object_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasObject() || $type->as->hasMixed()) {
                    $type = $type->replaceAs(self::reconcileObject($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $object_types[] = $type;
                }
                $redundant = \false;
            } elseif ($type instanceof TIterable) {
                $params = $type->type_params;
                $params[0] = self::refineArrayKey($params[0]);
                $object_types[] = new TGenericObject('Traversable', $params);
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$object_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($object_types) {
            return new Union($object_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileResource(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::getResource();
        }
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $resource_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TResource) {
                $resource_types[] = $type;
            } else {
                $redundant = \false;
            }
        }
        if ((!$resource_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($resource_types) {
            return new Union($resource_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileCountable(Assertion $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed() || $existing_var_type->hasTemplate()) {
            return new Union([new TArray([Type::getArrayKey(), Type::getMixed()]), new TNamedObject('Countable')]);
        }
        $iterable_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type->isCountable($codebase)) {
                $iterable_types[] = $type;
            } elseif ($type instanceof TObject) {
                $iterable_types[] = new TNamedObject('Countable');
                $redundant = \false;
            } elseif ($type instanceof TNamedObject || $type instanceof TIterable) {
                $countable = new TNamedObject('Countable');
                $type = $type->addIntersectionType($countable);
                $iterable_types[] = $type;
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$iterable_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($iterable_types) {
            return new Union($iterable_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileIterable(Assertion $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed() || $existing_var_type->hasTemplate()) {
            return new Union([new TIterable()]);
        }
        $iterable_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type->isIterable($codebase)) {
                $iterable_types[] = $type;
            } elseif ($type instanceof TObject) {
                $iterable_types[] = new TNamedObject('Traversable');
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$iterable_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($iterable_types) {
            return new Union($iterable_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileInArray(InArray $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation) : Union
    {
        $new_var_type = $assertion->type;
        if ($new_var_type->isSingle() && $new_var_type->getSingleAtomic() instanceof TClassConstant) {
            // Can't do assertion on const with non-literal type
            return $existing_var_type;
        }
        $intersection = Type::intersectUnionTypes($new_var_type, $existing_var_type, $codebase);
        if ($intersection === null) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $existing_var_type->getId(), $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
            }
            $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
            return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
        }
        return $intersection;
    }
    private static function reconcileHasArrayKey(Union $existing_var_type, HasArrayKey $assertion) : Union
    {
        $assertion = $assertion->key;
        $types = $existing_var_type->getAtomicTypes();
        foreach ($types as &$atomic_type) {
            if ($atomic_type instanceof TList) {
                $atomic_type = $atomic_type->getKeyedArray();
            }
            if ($atomic_type instanceof TKeyedArray) {
                assert(strpos($assertion, '::class') === strlen($assertion) - 7);
                [$assertion] = explode('::', $assertion);
                $atomic_type = new TKeyedArray(array_merge($atomic_type->properties, [$assertion => Type::getMixed()]), array_merge($atomic_type->class_strings ?? [], [$assertion => \true]), $atomic_type->fallback_params, $atomic_type->is_list);
            }
        }
        unset($atomic_type);
        return $existing_var_type->setTypes($types);
    }
    /**
     * @param string[] $suppressed_issues
     */
    private static function reconcileIsGreaterThan(IsGreaterThan $assertion, Union $existing_var_type, bool $inside_loop, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        //we add 1 from the assertion value because we're on a strict operator
        $assertion_value = $assertion->value + 1;
        $redundant = \true;
        if ($assertion->doesFilterNullOrFalse() && ($existing_var_type->hasType('null') || $existing_var_type->hasType('false'))) {
            $redundant = \false;
            $existing_var_type->removeType('null');
            $existing_var_type->removeType('false');
        }
        foreach ($existing_var_type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TIntRange) {
                if ($atomic_type->contains($assertion_value)) {
                    // if the range contains the assertion, the range must be adapted
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                    $min_bound = $atomic_type->min_bound;
                    if ($min_bound === null) {
                        $min_bound = $assertion_value;
                    } else {
                        $min_bound = TIntRange::getNewHighestBound($assertion_value, $min_bound);
                    }
                    $existing_var_type->addType(new TIntRange($min_bound, $atomic_type->max_bound));
                } elseif ($atomic_type->isLesserThan($assertion_value)) {
                    // if the range is lesser than the assertion, the type must be removed
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                } elseif ($atomic_type->isGreaterThan($assertion_value)) {
                    // if the range is greater than the assertion, the check is redundant
                }
            } elseif ($atomic_type instanceof TLiteralInt) {
                if ($atomic_type->value < $assertion_value) {
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                }
                /*elseif ($inside_loop) {
                      //when inside a loop, allow the range to extends the type
                      $existing_var_type->removeType($atomic_type->getKey());
                      if ($atomic_type->value < $assertion_value) {
                          $existing_var_type->addType(new TIntRange($atomic_type->value, $assertion_value));
                      } else {
                          $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value));
                      }
                  }*/
            } elseif ($atomic_type instanceof TInt) {
                $redundant = \false;
                $existing_var_type->removeType($atomic_type->getKey());
                $existing_var_type->addType(new TIntRange($assertion_value, null));
            } else {
                // we assume that other types may have been removed (empty strings? numeric strings?)
                //It may be worth refining to improve reconciliation while keeping in mind we're on loose comparison
                $redundant = \false;
            }
        }
        if (!$inside_loop && $redundant && $var_id && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \true, $negated, $code_location, $suppressed_issues);
        }
        if ($existing_var_type->isUnionEmpty()) {
            if ($var_id && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \false, $negated, $code_location, $suppressed_issues);
            }
            $existing_var_type->addType(new TNever());
        }
        return $existing_var_type->freeze();
    }
    /**
     * @param string[] $suppressed_issues
     */
    private static function reconcileIsLessThan(IsLessThan $assertion, Union $existing_var_type, bool $inside_loop, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        //we remove 1 from the assertion value because we're on a strict operator
        $assertion_value = $assertion->value - 1;
        $existing_var_type = $existing_var_type->getBuilder();
        $redundant = \true;
        if ($assertion->doesFilterNullOrFalse() && ($existing_var_type->hasType('null') || $existing_var_type->hasType('false'))) {
            $redundant = \false;
            $existing_var_type->removeType('null');
            $existing_var_type->removeType('false');
        }
        foreach ($existing_var_type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TIntRange) {
                if ($atomic_type->contains($assertion_value)) {
                    // if the range contains the assertion, the range must be adapted
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                    $max_bound = $atomic_type->max_bound;
                    if ($max_bound === null) {
                        $max_bound = $assertion_value;
                    } else {
                        $max_bound = min($max_bound, $assertion_value);
                    }
                    $existing_var_type->addType(new TIntRange($atomic_type->min_bound, $max_bound));
                } elseif ($atomic_type->isLesserThan($assertion_value)) {
                    // if the range is lesser than the assertion, the check is redundant
                } elseif ($atomic_type->isGreaterThan($assertion_value)) {
                    // if the range is greater than the assertion, the type must be removed
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                }
            } elseif ($atomic_type instanceof TLiteralInt) {
                if ($atomic_type->value > $assertion_value) {
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                }
                /* elseif ($inside_loop) {
                       //when inside a loop, allow the range to extends the type
                       $existing_var_type->removeType($atomic_type->getKey());
                       if ($atomic_type->value < $assertion_value) {
                           $existing_var_type->addType(new TIntRange($atomic_type->value, $assertion_value));
                       } else {
                           $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value));
                       }
                   }*/
            } elseif ($atomic_type instanceof TInt) {
                $redundant = \false;
                $existing_var_type->removeType($atomic_type->getKey());
                $existing_var_type->addType(new TIntRange(null, $assertion_value));
            } else {
                // we assume that other types may have been removed (empty strings? numeric strings?)
                //It may be worth refining to improve reconciliation while keeping in mind we're on loose comparison
                $redundant = \false;
            }
        }
        if (!$inside_loop && $redundant && $var_id && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \true, $negated, $code_location, $suppressed_issues);
        }
        if ($existing_var_type->isUnionEmpty()) {
            if ($var_id && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \false, $negated, $code_location, $suppressed_issues);
            }
            $existing_var_type->addType(new TNever());
        }
        return $existing_var_type->freeze();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileTraversable(Assertion $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed() || $existing_var_type->hasTemplate()) {
            return new Union([new TNamedObject('Traversable')]);
        }
        $traversable_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type->hasTraversableInterface($codebase)) {
                $traversable_types[] = $type;
            } elseif ($type instanceof TIterable) {
                $traversable_types[] = new TGenericObject('Traversable', $type->type_params);
                $redundant = \false;
            } elseif ($type instanceof TObject) {
                $traversable_types[] = new TNamedObject('Traversable');
                $redundant = \false;
            } elseif ($type instanceof TNamedObject) {
                $traversable = new TNamedObject('Traversable');
                $type = $type->addIntersectionType($traversable);
                $traversable_types[] = $type;
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$traversable_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($traversable_types) {
            return new Union($traversable_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileArray(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed()) {
            if ($assertion->getAtomicType()) {
                return new Union([$assertion->getAtomicType()]);
            }
            return Type::getArray();
        }
        $atomic_assertion_type = $assertion->getAtomicType();
        $array_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            if ($type instanceof TArray) {
                if ($atomic_assertion_type instanceof TNonEmptyArray) {
                    $array_types[] = new TNonEmptyArray($type->type_params, $atomic_assertion_type->count, $atomic_assertion_type->min_count, 'non-empty-array', $type->from_docblock);
                } else {
                    $array_types[] = $type;
                }
            } elseif ($type instanceof TKeyedArray) {
                //we don't currently have "definitely defined" shapes so we keep the one we have even if we have
                //a non-empty-array assertion
                $array_types[] = $type;
            } elseif ($type instanceof TCallable) {
                $array_types[] = new TCallableKeyedArray([new Union([new TClassString(), new TObject()]), Type::getString()]);
                $redundant = \false;
            } elseif ($type instanceof TIterable) {
                $params = $type->type_params;
                $params[0] = self::refineArrayKey($params[0]);
                $array_types[] = new TArray($params);
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasArray() || $type->as->hasIterable() || $type->as->hasMixed()) {
                    $type = $type->replaceAs(self::reconcileArray($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                    $array_types[] = $type;
                }
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$array_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
                if ($redundant) {
                    $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
                }
            }
        }
        if ($array_types) {
            return \Psalm\Internal\Type\TypeCombiner::combine($array_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileList(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality, bool $is_non_empty) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed() || $existing_var_type->hasTemplate()) {
            return $is_non_empty ? Type::getNonEmptyList() : Type::getList();
        }
        $array_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            if ($type instanceof TKeyedArray && $type->is_list) {
                if ($is_non_empty && !$type->isNonEmpty()) {
                    $properties = $type->properties;
                    $properties[0] = $properties[0]->setPossiblyUndefined(\false);
                    $array_types[] = $type->setProperties($properties);
                    $redundant = \false;
                } else {
                    $array_types[] = $type;
                }
            } elseif ($type instanceof TArray || $type instanceof TKeyedArray && $type->fallback_params !== null) {
                if ($type instanceof TKeyedArray) {
                    $type = $type->getGenericArrayType();
                }
                if ($type->type_params[0]->hasArrayKey() || $type->type_params[0]->hasInt()) {
                    if ($type instanceof TNonEmptyArray || $is_non_empty) {
                        $array_types[] = Type::getNonEmptyListAtomic($type->type_params[1]);
                    } else {
                        $array_types[] = Type::getListAtomic($type->type_params[1]);
                    }
                }
                if ($type->isEmptyArray()) {
                    //we allow an empty array to pass as a list. We keep the type as empty array though (more precise)
                    $array_types[] = $type;
                }
                $redundant = \false;
            } elseif ($type instanceof TCallable) {
                $array_types[] = new TCallableKeyedArray([new Union([new TClassString(), new TObject()]), Type::getString()]);
                $redundant = \false;
            } elseif ($type instanceof TIterable) {
                $array_types[] = Type::getListAtomic($type->type_params[1]);
                $redundant = \false;
            } else {
                $redundant = \false;
            }
        }
        if ((!$array_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
                if ($redundant) {
                    $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
                }
            }
        }
        if ($array_types) {
            return \Psalm\Internal\Type\TypeCombiner::combine($array_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileStringArrayAccess(Assertion $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $inside_loop) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed() || $existing_var_type->hasTemplate()) {
            return new Union([new TNonEmptyArray([Type::getArrayKey(), Type::getMixed()]), new TNamedObject('ArrayAccess')]);
        }
        $array_types = [];
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            if ($type->isArrayAccessibleWithStringKey($codebase)) {
                if (get_class($type) === TArray::class) {
                    $array_types[] = new TNonEmptyArray($type->type_params);
                } elseif ($type instanceof TKeyedArray && $type->is_list) {
                    $properties = $type->properties;
                    $properties[0] = $properties[0]->setPossiblyUndefined(\false);
                    $array_types[] = $type->setProperties($properties);
                } else {
                    $array_types[] = $type;
                }
            } elseif ($type instanceof TTemplateParam) {
                $array_types[] = $type;
            }
        }
        if (!$array_types) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($array_types) {
            return new Union($array_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return Type::getMixed($inside_loop);
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileIntArrayAccess(Assertion $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $inside_loop) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if ($existing_var_type->hasMixed()) {
            return Type::getMixed();
        }
        $array_types = [];
        foreach ($existing_var_atomic_types as $type) {
            if ($type->isArrayAccessibleWithIntOrStringKey($codebase)) {
                if (get_class($type) === TArray::class) {
                    $array_types[] = new TNonEmptyArray($type->type_params);
                } else {
                    $array_types[] = $type;
                }
            } elseif ($type instanceof TTemplateParam) {
                $array_types[] = $type;
            }
        }
        if (!$array_types) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($array_types) {
            return \Psalm\Internal\Type\TypeCombiner::combine($array_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return Type::getMixed($inside_loop);
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileCallable(Assertion $assertion, Codebase $codebase, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        if ($existing_var_type->hasMixed()) {
            return Type::parseString('callable');
        }
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $callable_types = [];
        $redundant = \true;
        foreach ($existing_var_atomic_types as $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            if ($type->isCallableType()) {
                $callable_types[] = $type;
            } elseif ($type instanceof TObject) {
                $callable_types[] = new TCallableObject();
                $redundant = \false;
            } elseif ($type instanceof TNamedObject && $codebase->classExists($type->value) && $codebase->methodExists($type->value . '::__invoke')) {
                $callable_types[] = $type;
            } elseif (get_class($type) === TString::class || get_class($type) === TNonEmptyString::class || get_class($type) === TNonFalsyString::class) {
                $callable_types[] = new TCallableString();
                $redundant = \false;
            } elseif (get_class($type) === TLiteralString::class && InternalCallMapHandler::inCallMap($type->value)) {
                $callable_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TArray) {
                $type = new TCallableArray($type->type_params);
                $callable_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TKeyedArray && count($type->properties) === 2) {
                $type = new TCallableKeyedArray($type->properties);
                $callable_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TTemplateParam) {
                if ($type->as->hasCallableType() || $type->as->hasMixed()) {
                    $type = $type->replaceAs(self::reconcileCallable($assertion, $codebase, $type->as, null, $negated, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                }
                $redundant = \false;
                $callable_types[] = $type;
            } else {
                $redundant = \false;
            }
        }
        if ((!$callable_types || $redundant) && !$is_equality) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($callable_types) {
            return \Psalm\Internal\Type\TypeCombiner::combine($callable_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   Truthy|NonEmpty $assertion
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileTruthyOrNonEmpty(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $recursive_check) : Union
    {
        $types = $existing_var_type->getAtomicTypes();
        $old_var_type_string = $existing_var_type->getId();
        //empty is used a lot to check for array offset existence, so we have to silent errors a lot
        $is_empty_assertion = $assertion instanceof NonEmpty;
        $redundant = !($existing_var_type->possibly_undefined || $existing_var_type->possibly_undefined_from_try);
        foreach ($types as $existing_var_type_key => $existing_var_type_part) {
            //if any atomic in the union is either always falsy, we remove it. If not always truthy, we mark the check
            //as not redundant.
            if ($existing_var_type_part->isFalsy()) {
                $redundant = \false;
                unset($types[$existing_var_type_key]);
            } elseif ($existing_var_type->possibly_undefined || $existing_var_type->possibly_undefined_from_try || !$existing_var_type_part->isTruthy()) {
                $redundant = \false;
            }
        }
        if (!$redundant && !$types) {
            //every type was removed, this is an impossible assertion
            if ($code_location && $key && !$is_empty_assertion && !$recursive_check) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \false, $negated, $code_location, $suppressed_issues);
            }
            $failed_reconciliation = 2;
            return Type::getNever();
        }
        if ($redundant) {
            if ($code_location && $key && !$is_empty_assertion && !$recursive_check) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
            }
            $failed_reconciliation = 1;
            if (!$types) {
                throw new AssertionError("We must have some types here!");
            }
            return $existing_var_type->setTypes($types);
        }
        if (isset($types['bool'])) {
            unset($types['bool']);
            $types[] = new TTrue();
        }
        if (isset($types['array'])) {
            $array_atomic_type = $types['array'];
            if ($array_atomic_type instanceof TList) {
                $array_atomic_type = $array_atomic_type->getKeyedArray();
            }
            if ($array_atomic_type instanceof TArray && !$array_atomic_type instanceof TNonEmptyArray) {
                unset($types['array']);
                $types[] = new TNonEmptyArray($array_atomic_type->type_params);
            } elseif ($array_atomic_type instanceof TKeyedArray && $array_atomic_type->is_list && $array_atomic_type->properties[0]->possibly_undefined) {
                unset($types['array']);
                $properties = $array_atomic_type->properties;
                $properties[0] = $properties[0]->setPossiblyUndefined(\false);
                $types[] = $array_atomic_type->setProperties($properties);
            }
        }
        if (isset($types['mixed'])) {
            $mixed_atomic_type = $types['mixed'];
            if (get_class($mixed_atomic_type) === TMixed::class) {
                unset($types['mixed']);
                $types[] = new TNonEmptyMixed();
            }
        }
        if (isset($types['scalar'])) {
            $scalar_atomic_type = $types['scalar'];
            if (get_class($scalar_atomic_type) === TScalar::class) {
                unset($types['scalar']);
                $types[] = new TNonEmptyScalar();
            }
        }
        if (isset($types['string'])) {
            $string_atomic_type = $types['string'];
            if (get_class($string_atomic_type) === TString::class) {
                unset($types['string']);
                $types[] = new TNonFalsyString();
            } elseif (get_class($string_atomic_type) === TLowercaseString::class) {
                unset($types['string']);
                $types[] = new TNonEmptyLowercaseString();
            } elseif (get_class($string_atomic_type) === TNonspecificLiteralString::class) {
                unset($types['string']);
                $types[] = new TNonEmptyNonspecificLiteralString();
            } elseif (get_class($string_atomic_type) === TNonEmptyString::class) {
                unset($types['string']);
                $types[] = new TNonFalsyString();
            }
        }
        if ($existing_var_type->hasInt()) {
            $existing_range_types = $existing_var_type->getRangeInts();
            if ($existing_range_types) {
                foreach ($existing_range_types as $int_key => $literal_type) {
                    if ($literal_type->contains(0)) {
                        unset($types[$int_key]);
                        if ($literal_type->min_bound === null || $literal_type->min_bound <= -1) {
                            $types[] = new TIntRange($literal_type->min_bound, -1);
                        }
                        if ($literal_type->max_bound === null || $literal_type->max_bound >= 1) {
                            $types[] = new TIntRange(1, $literal_type->max_bound);
                        }
                    }
                }
            }
        }
        foreach ($types as $type_key => $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TTemplateParam) {
                if (!$existing_var_atomic_type->as->isMixed()) {
                    $template_did_fail = 0;
                    $existing_var_atomic_type = $existing_var_atomic_type->replaceAs(self::reconcileTruthyOrNonEmpty($assertion, $existing_var_atomic_type->as, $key, $negated, $code_location, $suppressed_issues, $template_did_fail, \true));
                    if (!$template_did_fail) {
                        unset($types[$type_key]);
                        $types[] = $existing_var_atomic_type;
                    }
                }
            }
        }
        if (!$types) {
            throw new AssertionError("We must have some types here!");
        }
        $new = $existing_var_type->setTypes($types);
        if ($new === $existing_var_type && ($new->possibly_undefined || $new->possibly_undefined_from_try)) {
            $new = $existing_var_type->setPossiblyUndefined(\false, \false);
        } else {
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $new->possibly_undefined = \false;
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $new->possibly_undefined_from_try = \false;
        }
        return $new;
    }
    /**
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileClassConstant(Codebase $codebase, TClassConstant $class_constant_expression, Union $existing_type, int &$failed_reconciliation) : Union
    {
        $class_name = $class_constant_expression->fq_classlike_name;
        $constant_pattern = $class_constant_expression->const_name;
        $resolver = new ClassConstantByWildcardResolver($codebase);
        $matched_class_constant_types = $resolver->resolve($class_name, $constant_pattern);
        if ($matched_class_constant_types === null) {
            return $existing_type;
        }
        if ($matched_class_constant_types === []) {
            $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
            return Type::getNever();
        }
        return \Psalm\Internal\Type\TypeCombiner::combine($matched_class_constant_types, $codebase);
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Type\Comparator\AtomicTypeComparator;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\IsClassNotEqual;
use Psalm\Storage\Assertion\IsNotCountable;
use Psalm\Storage\Assertion\IsNotIdentical;
use Psalm\Storage\Assertion\IsNotType;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use function array_merge;
use function array_values;
use function count;
use function get_class;
use function strtolower;
/**
 * @internal
 */
class NegatedAssertionReconciler extends Reconciler
{
    /**
     * @param  string[]   $suppressed_issues
     * @param  Reconciler::RECONCILIATION_*      $failed_reconciliation
     */
    public static function reconcile(StatementsAnalyzer $statements_analyzer, Assertion $assertion, Union $existing_var_type, string $old_var_type_string, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $inside_loop) : Union
    {
        $is_equality = $assertion->hasEquality();
        $assertion_type = $assertion->getAtomicType();
        // this is a specific value comparison type that cannot be negated
        if ($is_equality && ($assertion_type instanceof TLiteralFloat || $assertion_type instanceof TLiteralInt || $assertion_type instanceof TLiteralString || $assertion_type instanceof TEnumCase)) {
            if ($existing_var_type->hasMixed()) {
                return $existing_var_type;
            }
            return self::handleLiteralNegatedEquality($statements_analyzer, $assertion, $assertion_type, $existing_var_type, $old_var_type_string, $key, $negated, $code_location, $suppressed_issues);
        }
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $existing_var_type = $existing_var_type->getBuilder();
        $simple_negated_type = \Psalm\Internal\Type\SimpleNegatedAssertionReconciler::reconcile($statements_analyzer->getCodebase(), $assertion, $existing_var_type->freeze(), $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality, $inside_loop);
        if ($simple_negated_type) {
            return $simple_negated_type;
        }
        $assertion_type = $assertion->getAtomicType();
        if ($assertion instanceof IsNotType && $assertion_type instanceof TIterable && $assertion_type->type_params[1]->isMixed() || $assertion instanceof IsNotCountable) {
            $existing_var_type->removeType('array');
        }
        if (!$is_equality && isset($existing_var_atomic_types['int']) && $existing_var_type->from_calculation && ($assertion_type instanceof TInt || $assertion_type instanceof TFloat)) {
            $existing_var_type->removeType($assertion_type->getKey());
            if ($assertion_type instanceof TInt) {
                $existing_var_type->addType(new TFloat());
            } else {
                $existing_var_type->addType(new TInt());
            }
            $existing_var_type->from_calculation = \false;
            return $existing_var_type->freeze();
        }
        if (!$is_equality && $assertion_type instanceof TNamedObject && ($assertion_type->value === 'DateTime' || $assertion_type->value === 'DateTimeImmutable') && isset($existing_var_atomic_types['DateTimeInterface'])) {
            $existing_var_type->removeType('DateTimeInterface');
            if ($assertion_type->value === 'DateTime') {
                $existing_var_type->addType(new TNamedObject('DateTimeImmutable'));
            } else {
                $existing_var_type->addType(new TNamedObject('DateTime'));
            }
            return $existing_var_type->freeze();
        }
        if (!$is_equality && $assertion_type instanceof TNamedObject) {
            foreach ($existing_var_type->getAtomicTypes() as $key => $type) {
                if ($type instanceof TEnumCase && $type->value === $assertion_type->value) {
                    $existing_var_type->removeType($key);
                }
            }
        }
        $codebase = $statements_analyzer->getCodebase();
        if ($assertion_type instanceof TNamedObject && strtolower($assertion_type->value) === 'traversable' && isset($existing_var_atomic_types['iterable'])) {
            /** @var TIterable */
            $iterable = $existing_var_atomic_types['iterable'];
            $existing_var_type->removeType('iterable');
            $existing_var_type->addType(new TArray([$iterable->type_params[0]->hasMixed() ? Type::getArrayKey() : $iterable->type_params[0], $iterable->type_params[1]]));
        } elseif ($assertion_type !== null && get_class($assertion_type) === TInt::class && isset($existing_var_type->getAtomicTypes()['array-key']) && !$is_equality) {
            $existing_var_type->removeType('array-key');
            $existing_var_type->addType(new TString());
        } elseif ($assertion instanceof IsClassNotEqual) {
            // do nothing
        } elseif ($assertion_type instanceof TClassString && $assertion_type->is_loaded) {
            // do nothing
        } elseif ($existing_var_type->isSingle() && $existing_var_type->hasNamedObjectType() && $assertion_type instanceof TNamedObject && isset($existing_var_type->getAtomicTypes()[$assertion_type->getKey()])) {
            // checking if two types share a common parent is not enough to guarantee childs are instanceof each other
            // fall through
        } elseif ($existing_var_type->isArray() && ($assertion->getAtomicType() instanceof TArray || $assertion->getAtomicType() instanceof TKeyedArray || $assertion->getAtomicType() instanceof TList)) {
            //if both types are arrays, try to combine them
            $combined_type = \Psalm\Internal\Type\TypeCombiner::combine(array_merge(array_values($existing_var_type->getAtomicTypes()), [$assertion->getAtomicType()]), $codebase);
            $existing_var_type->removeType('array');
            if ($combined_type->isSingle()) {
                $existing_var_type->addType($combined_type->getSingleAtomic());
            }
        } elseif (!$is_equality) {
            $assertion_type = $assertion->getAtomicType();
            // if there wasn't a direct hit, go deeper, eliminating subtypes
            if ($assertion_type && !$existing_var_type->removeType($assertion_type->getKey())) {
                if ($assertion_type instanceof TNamedObject) {
                    foreach ($existing_var_type->getAtomicTypes() as $part_name => $existing_var_type_part) {
                        if (!$existing_var_type_part->isObjectType()) {
                            continue;
                        }
                        if (!$existing_var_type_part instanceof TTemplateParam && AtomicTypeComparator::isContainedBy($codebase, $existing_var_type_part, $assertion_type, \false, \false)) {
                            $existing_var_type->removeType($part_name);
                        } elseif (AtomicTypeComparator::isContainedBy($codebase, $assertion_type, $existing_var_type_part, \false, \false)) {
                            $existing_var_type->different = \true;
                        }
                    }
                }
            }
        }
        $existing_var_type = $existing_var_type->freeze();
        if ($assertion instanceof IsNotIdentical && ($key !== '$this' || !$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer)) {
            $assertion_type = new Union([$assertion->type]);
            if ($key && $code_location && !UnionTypeComparator::canExpressionTypesBeIdentical($statements_analyzer->getCodebase(), $existing_var_type, $assertion_type)) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
            }
        }
        if ($existing_var_type->isUnionEmpty()) {
            if ($key !== '$this' || !$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer) {
                if ($key && $code_location && !$is_equality) {
                    self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \false, $negated, $code_location, $suppressed_issues);
                }
            }
            $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
            return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
        }
        return $existing_var_type;
    }
    /**
     * @param  TLiteralInt|TLiteralString|TLiteralFloat|TEnumCase $assertion_type
     * @param  string[]   $suppressed_issues
     */
    private static function handleLiteralNegatedEquality(StatementsAnalyzer $statements_analyzer, Assertion $assertion, Atomic $assertion_type, Union $existing_var_type, string $old_var_type_string, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $redundant = \true;
        $did_match_literal_type = \false;
        $scalar_var_type = null;
        if ($assertion_type instanceof TLiteralInt) {
            if ($existing_var_type->hasInt()) {
                if ($existing_var_type->getLiteralInts()) {
                    $did_match_literal_type = \true;
                    if ($existing_var_type->removeType($assertion_type->getKey())) {
                        $redundant = \false;
                    }
                }
                $existing_range_types = $existing_var_type->getRangeInts();
                if ($existing_range_types) {
                    foreach ($existing_range_types as $int_key => $literal_type) {
                        if ($literal_type->contains($assertion_type->value)) {
                            $redundant = \false;
                            $existing_var_type->removeType($int_key);
                            if ($literal_type->min_bound === null || $literal_type->min_bound <= $assertion_type->value - 1) {
                                $existing_var_type->addType(new Type\Atomic\TIntRange($literal_type->min_bound, $assertion_type->value - 1));
                            }
                            if ($literal_type->max_bound === null || $literal_type->max_bound >= $assertion_type->value + 1) {
                                $existing_var_type->addType(new Type\Atomic\TIntRange($assertion_type->value + 1, $literal_type->max_bound));
                            }
                        }
                    }
                }
                if (isset($existing_var_type->getAtomicTypes()['int']) && get_class($existing_var_type->getAtomicTypes()['int']) === Type\Atomic\TInt::class) {
                    $redundant = \false;
                    //this may be used to generate a range containing any int except the one that was asserted against
                    //but this is failing some tests
                    /*$existing_var_type->removeType('int');
                      $existing_var_type->addType(new Type\Atomic\TIntRange(null, $assertion_type->value - 1));
                      $existing_var_type->addType(new Type\Atomic\TIntRange($assertion_type->value + 1, null));*/
                }
            } else {
                $scalar_var_type = $assertion_type;
            }
        } elseif ($assertion_type instanceof TLiteralString) {
            if ($existing_var_type->hasString()) {
                if ($existing_var_type->getLiteralStrings()) {
                    $did_match_literal_type = \true;
                    if ($existing_var_type->removeType($assertion_type->getKey())) {
                        $redundant = \false;
                    }
                } elseif ($assertion_type->value === "") {
                    $existing_var_type->addType(new TNonEmptyString());
                }
            } elseif (get_class($assertion_type) === TLiteralString::class) {
                $scalar_var_type = $assertion_type;
            }
        } elseif ($assertion_type instanceof TLiteralFloat) {
            if ($existing_var_type->hasFloat()) {
                if ($existing_var_type->getLiteralFloats()) {
                    $did_match_literal_type = \true;
                    if ($existing_var_type->removeType($assertion_type->getKey())) {
                        $redundant = \false;
                    }
                }
            } else {
                $scalar_var_type = $assertion_type;
            }
        } else {
            $fq_enum_name = $assertion_type->value;
            $case_name = $assertion_type->case_name;
            foreach ($existing_var_type->getAtomicTypes() as $atomic_key => $atomic_type) {
                if (get_class($atomic_type) === TNamedObject::class && $atomic_type->value === $fq_enum_name) {
                    $codebase = $statements_analyzer->getCodebase();
                    $enum_storage = $codebase->classlike_storage_provider->get($fq_enum_name);
                    if (!$enum_storage->is_enum || !$enum_storage->enum_cases) {
                        $scalar_var_type = $assertion_type;
                    } else {
                        $existing_var_type->removeType($atomic_type->getKey());
                        $redundant = \false;
                        foreach ($enum_storage->enum_cases as $alt_case_name => $_) {
                            if ($alt_case_name === $case_name) {
                                continue;
                            }
                            $existing_var_type->addType(new TEnumCase($fq_enum_name, $alt_case_name));
                        }
                    }
                } elseif ($atomic_type instanceof TEnumCase && $atomic_type->value === $fq_enum_name && $atomic_type->case_name !== $case_name) {
                    $did_match_literal_type = \true;
                } elseif ($atomic_key === $assertion_type->getKey()) {
                    $existing_var_type->removeType($assertion_type->getKey());
                    $redundant = \false;
                }
            }
        }
        $existing_var_type = $existing_var_type->freeze();
        if ($key && $code_location) {
            if ($did_match_literal_type && ($redundant || count($existing_var_atomic_types) === 1)) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            } elseif ($scalar_var_type && $assertion instanceof IsNotIdentical && ($key !== '$this' || !$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer)) {
                if (!UnionTypeComparator::canExpressionTypesBeIdentical($statements_analyzer->getCodebase(), $existing_var_type, new Union([$scalar_var_type]))) {
                    self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
                }
            }
        }
        return $existing_var_type;
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Issue\DocblockTypeContradiction;
use Psalm\Issue\RedundantPropertyInitializationCheck;
use Psalm\Issue\TypeDoesNotContainType;
use Psalm\IssueBuffer;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\ArrayKeyDoesNotExist;
use Psalm\Storage\Assertion\DoesNotHaveAtLeastCount;
use Psalm\Storage\Assertion\DoesNotHaveExactCount;
use Psalm\Storage\Assertion\Empty_;
use Psalm\Storage\Assertion\Falsy;
use Psalm\Storage\Assertion\IsGreaterThanOrEqualTo;
use Psalm\Storage\Assertion\IsLessThanOrEqualTo;
use Psalm\Storage\Assertion\IsNotIsset;
use Psalm\Storage\Assertion\NotInArray;
use Psalm\Storage\Assertion\NotNonEmptyCountable;
use Psalm\Type;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableArray;
use Psalm\Type\Atomic\TCallableObject;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TEmptyNumeric;
use Psalm\Type\Atomic\TEmptyScalar;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonEmptyNonspecificLiteralString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TResource;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use function assert;
use function get_class;
use function max;
use function strpos;
/**
 * @internal
 */
class SimpleNegatedAssertionReconciler extends Reconciler
{
    /**
     * @param  string[]   $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    public static function reconcile(Codebase $codebase, Assertion $assertion, Union $existing_var_type, ?string $key = null, bool $negated = \false, ?CodeLocation $code_location = null, array $suppressed_issues = [], int &$failed_reconciliation = Reconciler::RECONCILIATION_EMPTY, bool $is_equality = \false, bool $inside_loop = \false) : ?Union
    {
        $old_var_type_string = $existing_var_type->getId();
        if ($assertion instanceof IsNotIsset) {
            if ($existing_var_type->possibly_undefined) {
                return Type::getNever();
            }
            if (!$existing_var_type->isNullable() && $key && strpos($key, '[') === \false && (!$existing_var_type->hasMixed() || $existing_var_type->isAlwaysTruthy())) {
                if ($code_location) {
                    if ($existing_var_type->from_static_property) {
                        IssueBuffer::maybeAdd(new RedundantPropertyInitializationCheck('Static property ' . $key . ' with type ' . $existing_var_type . ' has unexpected isset check — should it be nullable?', $code_location), $suppressed_issues);
                    } elseif ($existing_var_type->from_property) {
                        IssueBuffer::maybeAdd(new RedundantPropertyInitializationCheck('Property ' . $key . ' with type ' . $existing_var_type . ' should already be set in the constructor', $code_location), $suppressed_issues);
                    } elseif ($existing_var_type->from_docblock) {
                        IssueBuffer::maybeAdd(new DocblockTypeContradiction('Cannot resolve types for ' . $key . ' with docblock-defined type ' . $existing_var_type . ' and !isset assertion', $code_location, 'cannot resolve !isset ' . $existing_var_type . ' ' . $key), $suppressed_issues);
                    } else {
                        IssueBuffer::maybeAdd(new TypeDoesNotContainType('Cannot resolve types for ' . $key . ' with type ' . $existing_var_type . ' and !isset assertion', $code_location, 'cannot resolve !isset ' . $existing_var_type . ' ' . $key), $suppressed_issues);
                    }
                }
                return $existing_var_type->from_docblock ? Type::getNull() : Type::getNever();
            }
            return Type::getNull();
        }
        if ($assertion instanceof ArrayKeyDoesNotExist) {
            return Type::getNever();
        }
        if ($assertion instanceof NotInArray) {
            $new_var_type = $assertion->type;
            $intersection = Type::intersectUnionTypes($new_var_type, $existing_var_type, $codebase);
            if ($intersection === null) {
                if ($key && $code_location) {
                    self::triggerIssueForImpossible($existing_var_type, $existing_var_type->getId(), $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
                }
                $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
            }
            return $existing_var_type;
        }
        if ($assertion instanceof Falsy || $assertion instanceof Empty_) {
            return self::reconcileFalsyOrEmpty($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, \false);
        }
        if ($assertion instanceof NotNonEmptyCountable) {
            return self::reconcileNotNonEmptyCountable($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $is_equality, null);
        }
        if ($assertion instanceof DoesNotHaveAtLeastCount) {
            return self::reconcileNotNonEmptyCountable($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $is_equality, $assertion->count);
        }
        if ($assertion instanceof DoesNotHaveExactCount) {
            return $existing_var_type;
        }
        if ($assertion instanceof IsLessThanOrEqualTo) {
            return self::reconcileIsLessThanOrEqualTo($assertion, $existing_var_type, $inside_loop, $old_var_type_string, $key, $negated, $code_location, $suppressed_issues);
        }
        if ($assertion instanceof IsGreaterThanOrEqualTo) {
            return self::reconcileIsGreaterThanOrEqualTo($assertion, $existing_var_type, $inside_loop, $old_var_type_string, $key, $negated, $code_location, $suppressed_issues);
        }
        $assertion_type = $assertion->getAtomicType();
        if ($assertion_type instanceof TObject && !$existing_var_type->hasMixed()) {
            return self::reconcileObject($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TScalar && !$existing_var_type->hasMixed()) {
            return self::reconcileScalar($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TResource && !$existing_var_type->hasMixed()) {
            return self::reconcileResource($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && get_class($assertion_type) === TBool::class && !$existing_var_type->hasMixed()) {
            return self::reconcileBool($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TNumeric && !$existing_var_type->hasMixed()) {
            return self::reconcileNumeric($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TFloat && !$existing_var_type->hasMixed()) {
            return self::reconcileFloat($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && get_class($assertion_type) === TInt::class && !$existing_var_type->hasMixed()) {
            return self::reconcileInt($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type && get_class($assertion_type) === TString::class && !$existing_var_type->hasMixed()) {
            return self::reconcileString($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TArray && !$existing_var_type->hasMixed() && $assertion_type->type_params[0]->isArrayKey() && $assertion_type->type_params[1]->isMixed()) {
            return self::reconcileArray($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TNull && !$existing_var_type->hasMixed()) {
            return self::reconcileNull($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TFalse && !$existing_var_type->hasMixed()) {
            return self::reconcileFalse($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TTrue && !$existing_var_type->hasMixed()) {
            return self::reconcileTrue($assertion, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $is_equality);
        }
        if ($assertion_type instanceof TCallable) {
            return self::reconcileCallable($existing_var_type);
        }
        return null;
    }
    private static function reconcileCallable(Union $existing_var_type) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        foreach ($existing_var_type->getAtomicTypes() as $atomic_key => $type) {
            if ($type instanceof TLiteralString && InternalCallMapHandler::inCallMap($type->value)) {
                $existing_var_type->removeType($atomic_key);
            }
            if ($type->isCallableType()) {
                $existing_var_type->removeType($atomic_key);
            }
        }
        return $existing_var_type->freeze();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileBool(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_bool_types = [];
        $redundant = \true;
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TTemplateParam) {
                if (!$type->as->hasBool()) {
                    $non_bool_types[] = $type;
                }
                $redundant = \false;
            } elseif (!$type instanceof TBool || $is_equality && get_class($type) === TBool::class) {
                if ($type instanceof TScalar) {
                    $redundant = \false;
                    $non_bool_types[] = new TString();
                    $non_bool_types[] = new TInt();
                    $non_bool_types[] = new TFloat();
                } else {
                    $non_bool_types[] = $type;
                }
            } else {
                $redundant = \false;
            }
        }
        if ($redundant || !$non_bool_types) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_bool_types) {
            return new Union($non_bool_types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     */
    private static function reconcileNotNonEmptyCountable(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, bool $is_equality, ?int $count) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        $old_var_type_string = $existing_var_type->getId();
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        if (isset($existing_var_atomic_types['array'])) {
            $array_atomic_type = $existing_var_type->getArray();
            $redundant = \true;
            if ($array_atomic_type instanceof TKeyedArray) {
                if ($count !== null) {
                    $prop_max_count = $array_atomic_type->getMaxCount();
                    $prop_min_count = $array_atomic_type->getMinCount();
                    // !(count($a) >= 3)
                    // count($a) < 3
                    // We're asserting that count($a) < $count
                    // If it's impossible, remove the type
                    // If it's possible but redundant, mark as redundant
                    // If it's possible, mark as not redundant
                    // Impossible because count($a) >= $count always
                    if ($prop_min_count >= $count) {
                        $redundant = \false;
                        $existing_var_type->removeType('array');
                        // Redundant because count($a) < $count always
                    } elseif ($prop_max_count && $prop_max_count < $count) {
                        $redundant = \true;
                        // Possible
                    } else {
                        if ($array_atomic_type->is_list && $array_atomic_type->fallback_params) {
                            $properties = [];
                            for ($x = 0; $x < $count - 1; $x++) {
                                $properties[] = $array_atomic_type->properties[$x] ?? $array_atomic_type->fallback_params[1]->setPossiblyUndefined(\true);
                            }
                            $existing_var_type->removeType('array');
                            if (!$properties) {
                                $existing_var_type->addType(Type::getEmptyArrayAtomic());
                            } else {
                                $existing_var_type->addType(new TKeyedArray($properties, null, null, \true, $array_atomic_type->from_docblock));
                            }
                        }
                        $redundant = \false;
                    }
                } else {
                    if ($array_atomic_type->isNonEmpty()) {
                        // Impossible, never empty
                        $redundant = \false;
                        $existing_var_type->removeType('array');
                    } else {
                        // Possible, can be empty
                        $redundant = \false;
                        $existing_var_type->removeType('array');
                        $existing_var_type->addType(new TArray([new Union([new TNever()]), new Union([new TNever()])]));
                    }
                }
            } elseif (!$array_atomic_type instanceof TArray || !$array_atomic_type->isEmptyArray()) {
                $redundant = \false;
                if (!$count) {
                    $existing_var_type->addType(new TArray([new Union([new TNever()]), new Union([new TNever()])]));
                }
            }
            if (!$is_equality && !$existing_var_type->hasMixed() && ($redundant || $existing_var_type->isUnionEmpty())) {
                if ($key && $code_location) {
                    self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
                }
            }
        }
        return $existing_var_type->freeze();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileNull(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $types = $existing_var_type->getAtomicTypes();
        $old_var_type_string = $existing_var_type->getId();
        $redundant = \true;
        if (isset($types['null'])) {
            $redundant = \false;
            unset($types['null']);
        }
        foreach ($types as &$type) {
            if ($type instanceof TTemplateParam) {
                $new = $type->replaceAs(self::reconcileNull($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                //if ($new !== $type) {
                //    $redundant = false;
                //}
                // TODO: This is technically wrong, but for some reason we get a
                // duplicated assertion here when using template types.
                $redundant = \false;
                $type = $new;
            }
        }
        unset($type);
        if ($redundant || !$types) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($types) {
            return $existing_var_type->setTypes($types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileFalse(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $types = $existing_var_type->getAtomicTypes();
        $old_var_type_string = $existing_var_type->getId();
        $redundant = \true;
        if (isset($types['scalar'])) {
            $redundant = \false;
        }
        if (isset($types['bool'])) {
            $redundant = \false;
            $types[] = new TTrue();
            unset($types['bool']);
        }
        if (isset($types['false'])) {
            $redundant = \false;
            unset($types['false']);
        }
        foreach ($types as &$type) {
            if ($type instanceof TTemplateParam) {
                $new = $type->replaceAs(self::reconcileFalse($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                if ($new !== $type) {
                    $redundant = \false;
                }
                $type = $new;
            }
        }
        unset($type);
        if ($redundant || !$types) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($types) {
            return $existing_var_type->setTypes($types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param string[] $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileTrue(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $types = $existing_var_type->getAtomicTypes();
        $old_var_type_string = $existing_var_type->getId();
        $redundant = \true;
        if (isset($types['scalar'])) {
            $redundant = \false;
        }
        if (isset($types['bool'])) {
            $redundant = \false;
            $types[] = new TFalse();
            unset($types['bool']);
        }
        if (isset($types['true'])) {
            $redundant = \false;
            unset($types['true']);
        }
        foreach ($types as &$type) {
            if ($type instanceof TTemplateParam) {
                $new = $type->replaceAs(self::reconcileTrue($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                if ($new !== $type) {
                    $redundant = \false;
                }
                $type = $new;
            }
        }
        unset($type);
        if ($redundant || !$types) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($types) {
            return $existing_var_type->setTypes($types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   Falsy|Empty_ $assertion
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileFalsyOrEmpty(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $recursive_check) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        $old_var_type_string = $existing_var_type->getId();
        $redundant = !($existing_var_type->possibly_undefined || $existing_var_type->possibly_undefined_from_try);
        foreach ($existing_var_type->getAtomicTypes() as $existing_var_type_key => $existing_var_type_part) {
            //if any atomic in the union is either always truthy, we remove it. If not always falsy, we mark the check
            //as not redundant.
            if (!$existing_var_type->possibly_undefined && !$existing_var_type->possibly_undefined_from_try && $existing_var_type_part->isTruthy()) {
                $redundant = \false;
                $existing_var_type->removeType($existing_var_type_key);
            } elseif (!$existing_var_type_part->isFalsy()) {
                $redundant = \false;
            }
        }
        if (!$redundant && $existing_var_type->isUnionEmpty()) {
            //every type was removed, this is an impossible assertion
            if ($code_location && $key && !$recursive_check) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \false, $negated, $code_location, $suppressed_issues);
            }
            $failed_reconciliation = 2;
            return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
        }
        if ($redundant) {
            //nothing was removed, this is a redundant assertion
            if ($code_location && $key && !$recursive_check) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
            }
            $failed_reconciliation = 1;
            return $existing_var_type->freeze();
        }
        if ($existing_var_type->hasType('bool')) {
            $existing_var_type->removeType('bool');
            $existing_var_type->addType(new TFalse());
        }
        if ($existing_var_type->hasArray()) {
            $existing_var_type->removeType('array');
            $existing_var_type->addType(new TArray([new Union([new TNever()]), new Union([new TNever()])]));
        }
        if ($existing_var_type->hasMixed()) {
            $mixed_atomic_type = $existing_var_type->getAtomicTypes()['mixed'];
            if (get_class($mixed_atomic_type) === TMixed::class) {
                $existing_var_type->removeType('mixed');
                $existing_var_type->addType(new TEmptyMixed());
            }
        }
        if ($existing_var_type->hasScalar()) {
            $scalar_atomic_type = $existing_var_type->getAtomicTypes()['scalar'];
            if (get_class($scalar_atomic_type) === TScalar::class) {
                $existing_var_type->removeType('scalar');
                $existing_var_type->addType(new TEmptyScalar());
            }
        }
        if ($existing_var_type->hasType('string')) {
            $string_atomic_type = $existing_var_type->getAtomicTypes()['string'];
            if (get_class($string_atomic_type) === TString::class) {
                $existing_var_type->removeType('string');
                $existing_var_type->addType(new TLiteralString(''));
                $existing_var_type->addType(new TLiteralString('0'));
            } elseif (get_class($string_atomic_type) === TNonEmptyString::class) {
                $existing_var_type->removeType('string');
                $existing_var_type->addType(new TLiteralString('0'));
            } elseif (get_class($string_atomic_type) === TNonEmptyLowercaseString::class) {
                $existing_var_type->removeType('string');
                $existing_var_type->addType(new TLiteralString('0'));
            } elseif (get_class($string_atomic_type) === TNonEmptyNonspecificLiteralString::class) {
                $existing_var_type->removeType('string');
                $existing_var_type->addType(new TLiteralString('0'));
            }
        }
        if ($existing_var_type->hasInt()) {
            $existing_range_types = $existing_var_type->getRangeInts();
            if ($existing_range_types) {
                foreach ($existing_range_types as $int_key => $literal_type) {
                    if ($literal_type->contains(0)) {
                        $existing_var_type->removeType($int_key);
                        $existing_var_type->addType(new TLiteralInt(0));
                    }
                }
            } else {
                $existing_var_type->removeType('int');
                $existing_var_type->addType(new TLiteralInt(0));
            }
        }
        if ($existing_var_type->hasFloat()) {
            $existing_var_type->removeType('float');
            $existing_var_type->addType(new TLiteralFloat(0.0));
        }
        if ($existing_var_type->hasNumeric()) {
            $existing_var_type->removeType('numeric');
            $existing_var_type->addType(new TEmptyNumeric());
        }
        foreach ($existing_var_type->getAtomicTypes() as $type_key => $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TTemplateParam) {
                if (!$existing_var_atomic_type->as->isMixed()) {
                    $template_did_fail = 0;
                    $existing_var_atomic_type = $existing_var_atomic_type->replaceAs(self::reconcileFalsyOrEmpty($assertion, $existing_var_atomic_type->as, $key, $negated, $code_location, $suppressed_issues, $template_did_fail, $recursive_check));
                    if (!$template_did_fail) {
                        $existing_var_type->removeType($type_key);
                        $existing_var_type->addType($existing_var_atomic_type);
                    }
                }
            }
        }
        /** @psalm-suppress RedundantCondition Psalm bug */
        assert(!$existing_var_type->isUnionEmpty());
        return $existing_var_type->freeze();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileScalar(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_scalar_types = [];
        $redundant = \true;
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TTemplateParam) {
                if (!$is_equality && !$type->as->isMixed()) {
                    $template_did_fail = 0;
                    $type = $type->replaceAs(self::reconcileScalar($assertion, $type->as, null, \false, null, $suppressed_issues, $template_did_fail, $is_equality));
                    $redundant = \false;
                    if (!$template_did_fail) {
                        $non_scalar_types[] = $type;
                    }
                } else {
                    $redundant = \false;
                    $non_scalar_types[] = $type;
                }
            } elseif (!$type instanceof Scalar) {
                $non_scalar_types[] = $type;
            } else {
                $redundant = \false;
                if ($is_equality) {
                    $non_scalar_types[] = $type;
                }
            }
        }
        if ($redundant || !$non_scalar_types) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_scalar_types) {
            return new Union($non_scalar_types, ['ignore_falsable_issues' => $existing_var_type->ignore_falsable_issues, 'ignore_nullable_issues' => $existing_var_type->ignore_nullable_issues, 'from_docblock' => $existing_var_type->from_docblock]);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileObject(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_object_types = [];
        $redundant = \true;
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TTemplateParam) {
                if (!$is_equality && !$type->as->isMixed()) {
                    $template_did_fail = 0;
                    $type = $type->replaceAs(self::reconcileObject($assertion, $type->as, null, \false, null, $suppressed_issues, $template_did_fail, $is_equality));
                    $redundant = \false;
                    if (!$template_did_fail) {
                        $non_object_types[] = $type;
                    }
                } else {
                    $redundant = \false;
                    $non_object_types[] = $type;
                }
            } elseif ($type instanceof TCallable) {
                $non_object_types[] = new TCallableArray([Type::getArrayKey(), Type::getMixed()]);
                $non_object_types[] = new TCallableString();
                $redundant = \false;
            } elseif ($type instanceof TIterable) {
                $params = $type->type_params;
                $params[0] = self::refineArrayKey($params[0]);
                $non_object_types[] = new TArray($params);
                $redundant = \false;
            } elseif (!$type->isObjectType()) {
                $non_object_types[] = $type;
            } else {
                $redundant = \false;
                if ($is_equality) {
                    $non_object_types[] = $type;
                }
            }
        }
        if (!$non_object_types || $redundant) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_object_types) {
            return new Union($non_object_types, ['ignore_falsable_issues' => $existing_var_type->ignore_falsable_issues, 'ignore_nullable_issues' => $existing_var_type->ignore_nullable_issues, 'from_docblock' => $existing_var_type->from_docblock]);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileNumeric(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_numeric_types = [];
        $redundant = !($existing_var_type->hasString() || $existing_var_type->hasScalar());
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TTemplateParam) {
                if (!$is_equality && !$type->as->isMixed()) {
                    $template_did_fail = 0;
                    $type = $type->replaceAs(self::reconcileNumeric($assertion, $type->as, null, \false, null, $suppressed_issues, $template_did_fail, $is_equality));
                    $redundant = \false;
                    if (!$template_did_fail) {
                        $non_numeric_types[] = $type;
                    }
                } else {
                    $redundant = \false;
                    $non_numeric_types[] = $type;
                }
            } elseif ($type instanceof TArrayKey) {
                $redundant = \false;
                $non_numeric_types[] = new TString();
            } elseif (!$type->isNumericType()) {
                $non_numeric_types[] = $type;
            } else {
                $redundant = \false;
                if ($is_equality) {
                    $non_numeric_types[] = $type;
                }
            }
        }
        if (!$non_numeric_types || $redundant) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_numeric_types) {
            return new Union($non_numeric_types, ['ignore_falsable_issues' => $existing_var_type->ignore_falsable_issues, 'ignore_nullable_issues' => $existing_var_type->ignore_nullable_issues, 'from_docblock' => $existing_var_type->from_docblock]);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileInt(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_int_types = [];
        $redundant = \true;
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TTemplateParam) {
                if (!$is_equality && !$type->as->isMixed()) {
                    $template_did_fail = 0;
                    $type = $type->replaceAs(self::reconcileInt($assertion, $type->as, null, \false, null, $suppressed_issues, $template_did_fail, $is_equality));
                    $redundant = \false;
                    if (!$template_did_fail) {
                        $non_int_types[] = $type;
                    }
                } else {
                    $redundant = \false;
                    $non_int_types[] = $type;
                }
            } elseif ($type instanceof TArrayKey) {
                $redundant = \false;
                $non_int_types[] = new TString();
            } elseif ($type instanceof TScalar) {
                $redundant = \false;
                $non_int_types[] = new TString();
                $non_int_types[] = new TFloat();
                $non_int_types[] = new TBool();
            } elseif ($type instanceof TInt) {
                $redundant = \false;
                if ($is_equality) {
                    $non_int_types[] = $type;
                } elseif ($existing_var_type->from_calculation) {
                    $non_int_types[] = new TFloat();
                }
            } elseif ($type instanceof TNumeric) {
                $redundant = \false;
                $non_int_types[] = new TString();
                $non_int_types[] = new TFloat();
            } else {
                $non_int_types[] = $type;
            }
        }
        if (!$non_int_types || $redundant) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_int_types) {
            return new Union($non_int_types, ['ignore_falsable_issues' => $existing_var_type->ignore_falsable_issues, 'ignore_nullable_issues' => $existing_var_type->ignore_nullable_issues, 'from_docblock' => $existing_var_type->from_docblock]);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileFloat(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_float_types = [];
        $redundant = \true;
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TTemplateParam) {
                if (!$is_equality && !$type->as->isMixed()) {
                    $template_did_fail = 0;
                    $type = $type->replaceAs(self::reconcileFloat($assertion, $type->as, null, \false, null, $suppressed_issues, $template_did_fail, $is_equality));
                    $redundant = \false;
                    if (!$template_did_fail) {
                        $non_float_types[] = $type;
                    }
                } else {
                    $redundant = \false;
                    $non_float_types[] = $type;
                }
            } elseif ($type instanceof TScalar) {
                $redundant = \false;
                $non_float_types[] = new TString();
                $non_float_types[] = new TInt();
                $non_float_types[] = new TBool();
            } elseif ($type instanceof TFloat) {
                $redundant = \false;
                if ($is_equality) {
                    $non_float_types[] = $type;
                }
            } elseif ($type instanceof TNumeric) {
                $redundant = \false;
                $non_float_types[] = new TString();
                $non_float_types[] = new TInt();
            } else {
                $non_float_types[] = $type;
            }
        }
        if (!$non_float_types || $redundant) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_float_types) {
            return new Union($non_float_types, ['ignore_falsable_issues' => $existing_var_type->ignore_falsable_issues, 'ignore_nullable_issues' => $existing_var_type->ignore_nullable_issues, 'from_docblock' => $existing_var_type->from_docblock]);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileString(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_string_types = [];
        $redundant = !$existing_var_type->hasScalar();
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TTemplateParam) {
                if (!$is_equality && !$type->as->isMixed()) {
                    $template_did_fail = 0;
                    $type = $type->replaceAs(self::reconcileString($assertion, $type->as, null, \false, null, $suppressed_issues, $template_did_fail, $is_equality));
                    $redundant = \false;
                    if (!$template_did_fail) {
                        $non_string_types[] = $type;
                    }
                } else {
                    $redundant = \false;
                    $non_string_types[] = $type;
                }
            } elseif ($type instanceof TArrayKey) {
                $non_string_types[] = new TInt();
                $redundant = \false;
            } elseif ($type instanceof TCallable) {
                $non_string_types[] = new TCallableArray([Type::getArrayKey(), Type::getMixed()]);
                $non_string_types[] = new TCallableObject();
                $redundant = \false;
            } elseif ($type instanceof TNumeric) {
                $non_string_types[] = $type;
                $redundant = \false;
            } elseif ($type instanceof TScalar) {
                $redundant = \false;
                $non_string_types[] = new TFloat();
                $non_string_types[] = new TInt();
                $non_string_types[] = new TBool();
            } elseif (!$type instanceof TString) {
                $non_string_types[] = $type;
            } else {
                $redundant = \false;
                if ($is_equality) {
                    $non_string_types[] = $type;
                }
            }
        }
        if (!$non_string_types || $redundant) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_string_types) {
            return new Union($non_string_types, ['ignore_falsable_issues' => $existing_var_type->ignore_falsable_issues, 'ignore_nullable_issues' => $existing_var_type->ignore_nullable_issues, 'from_docblock' => $existing_var_type->from_docblock]);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileArray(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $old_var_type_string = $existing_var_type->getId();
        $non_array_types = [];
        $redundant = !$existing_var_type->hasScalar();
        foreach ($existing_var_type->getAtomicTypes() as $type) {
            if ($type instanceof TList) {
                $type = $type->getKeyedArray();
            }
            if ($type instanceof TTemplateParam) {
                if (!$is_equality && !$type->as->isMixed()) {
                    $template_did_fail = 0;
                    $type = $type->replaceAs(self::reconcileArray($assertion, $type->as, null, \false, null, $suppressed_issues, $template_did_fail, $is_equality));
                    $redundant = \false;
                    if (!$template_did_fail) {
                        $non_array_types[] = $type;
                    }
                } else {
                    $redundant = \false;
                    $non_array_types[] = $type;
                }
            } elseif ($type instanceof TCallable) {
                $non_array_types[] = new TCallableString();
                $non_array_types[] = new TCallableObject();
                $redundant = \false;
            } elseif ($type instanceof TIterable) {
                if (!$type->type_params[0]->isMixed() || !$type->type_params[1]->isMixed()) {
                    $non_array_types[] = new TGenericObject('Traversable', $type->type_params);
                } else {
                    $non_array_types[] = new TNamedObject('Traversable');
                }
                $redundant = \false;
            } elseif (!$type instanceof TArray && !$type instanceof TKeyedArray) {
                $non_array_types[] = $type;
            } else {
                $redundant = \false;
                if ($is_equality) {
                    $non_array_types[] = $type;
                }
            }
        }
        if (!$non_array_types || $redundant) {
            if ($key && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($non_array_types) {
            return new Union($non_array_types, ['ignore_falsable_issues' => $existing_var_type->ignore_falsable_issues, 'ignore_nullable_issues' => $existing_var_type->ignore_nullable_issues, 'from_docblock' => $existing_var_type->from_docblock]);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param   string[]  $suppressed_issues
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function reconcileResource(Assertion $assertion, Union $existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, bool $is_equality) : Union
    {
        $types = $existing_var_type->getAtomicTypes();
        $old_var_type_string = $existing_var_type->getId();
        $redundant = \true;
        if (isset($types['resource'])) {
            $redundant = \false;
            unset($types['resource']);
        }
        foreach ($types as &$type) {
            if ($type instanceof TTemplateParam) {
                $new = $type->replaceAs(self::reconcileResource($assertion, $type->as, null, \false, null, $suppressed_issues, $failed_reconciliation, $is_equality));
                $redundant = $new === $type;
                $type = $new;
            }
        }
        unset($type);
        if ($redundant || !$types) {
            if ($key && $code_location && !$is_equality) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, $redundant, $negated, $code_location, $suppressed_issues);
            }
            if ($redundant) {
                $failed_reconciliation = Reconciler::RECONCILIATION_REDUNDANT;
            }
        }
        if ($types) {
            return $existing_var_type->setTypes($types);
        }
        $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
        return $existing_var_type->from_docblock ? Type::getMixed() : Type::getNever();
    }
    /**
     * @param string[] $suppressed_issues
     */
    private static function reconcileIsLessThanOrEqualTo(IsLessThanOrEqualTo $assertion, Union $existing_var_type, bool $inside_loop, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        $assertion_value = $assertion->value;
        $redundant = \true;
        if ($assertion->doesFilterNullOrFalse() && ($existing_var_type->hasType('null') || $existing_var_type->hasType('false'))) {
            $redundant = \false;
            $existing_var_type->removeType('null');
            $existing_var_type->removeType('false');
        }
        foreach ($existing_var_type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TIntRange) {
                if ($atomic_type->contains($assertion_value)) {
                    // if the range contains the assertion, the range must be adapted
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                    if ($atomic_type->max_bound === null) {
                        $max_bound = $assertion_value;
                    } else {
                        $max_bound = TIntRange::getNewLowestBound($assertion_value, $atomic_type->max_bound);
                    }
                    $existing_var_type->addType(new TIntRange($atomic_type->min_bound, $max_bound));
                } elseif ($atomic_type->isLesserThan($assertion_value)) {
                    // if the range is lesser than the assertion, the check is redundant
                } elseif ($atomic_type->isGreaterThan($assertion_value)) {
                    // if the range is greater than the assertion, the type must be removed
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                }
            } elseif ($atomic_type instanceof TLiteralInt) {
                if ($atomic_type->value > $assertion_value) {
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                }
                /*elseif ($inside_loop) {
                      //when inside a loop, allow the range to extends the type
                      $existing_var_type->removeType($atomic_type->getKey());
                      if ($atomic_type->value < $assertion_value) {
                          $existing_var_type->addType(new TIntRange($atomic_type->value, $assertion_value));
                      } else {
                          $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value));
                      }
                  }*/
            } elseif ($atomic_type instanceof TInt) {
                $redundant = \false;
                $existing_var_type->removeType($atomic_type->getKey());
                $existing_var_type->addType(new TIntRange(null, $assertion_value));
            } else {
                // we assume that other types may have been removed (empty strings? numeric strings?)
                //It may be worth refining to improve reconciliation while keeping in mind we're on loose comparison
                $redundant = \false;
            }
        }
        if (!$inside_loop && $redundant && $var_id && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \true, $negated, $code_location, $suppressed_issues);
        }
        if ($existing_var_type->isUnionEmpty()) {
            if ($var_id && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \false, $negated, $code_location, $suppressed_issues);
            }
            $existing_var_type->addType(new TNever());
        }
        return $existing_var_type->freeze();
    }
    /**
     * @param string[] $suppressed_issues
     */
    private static function reconcileIsGreaterThanOrEqualTo(IsGreaterThanOrEqualTo $assertion, Union $existing_var_type, bool $inside_loop, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $existing_var_type = $existing_var_type->getBuilder();
        $assertion_value = $assertion->value;
        $redundant = \true;
        if ($assertion->doesFilterNullOrFalse() && ($existing_var_type->hasType('null') || $existing_var_type->hasType('false'))) {
            $redundant = \false;
            $existing_var_type->removeType('null');
            $existing_var_type->removeType('false');
        }
        foreach ($existing_var_type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TIntRange) {
                if ($atomic_type->contains($assertion_value)) {
                    // if the range contains the assertion, the range must be adapted
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                    $min_bound = $atomic_type->min_bound;
                    if ($min_bound === null) {
                        $min_bound = $assertion_value;
                    } else {
                        $min_bound = max($min_bound, $assertion_value);
                    }
                    $existing_var_type->addType(new TIntRange($min_bound, $atomic_type->max_bound));
                } elseif ($atomic_type->isLesserThan($assertion_value)) {
                    // if the range is lesser than the assertion, the type must be removed
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                } elseif ($atomic_type->isGreaterThan($assertion_value)) {
                    // if the range is greater than the assertion, the check is redundant
                }
            } elseif ($atomic_type instanceof TLiteralInt) {
                if ($atomic_type->value < $assertion_value) {
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_type->getKey());
                }
                /* elseif ($inside_loop) {
                       //when inside a loop, allow the range to extends the type
                       $existing_var_type->removeType($atomic_type->getKey());
                       if ($atomic_type->value < $assertion_value) {
                           $existing_var_type->addType(new TIntRange($atomic_type->value, $assertion_value));
                       } else {
                           $existing_var_type->addType(new TIntRange($assertion_value, $atomic_type->value));
                       }
                   }*/
            } elseif ($atomic_type instanceof TInt) {
                $redundant = \false;
                $existing_var_type->removeType($atomic_type->getKey());
                $existing_var_type->addType(new TIntRange($assertion_value, null));
            } else {
                // we assume that other types may have been removed (empty strings? numeric strings?)
                //It may be worth refining to improve reconciliation while keeping in mind we're on loose comparison
                $redundant = \false;
            }
        }
        if (!$inside_loop && $redundant && $var_id && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \true, $negated, $code_location, $suppressed_issues);
        }
        if ($existing_var_type->isUnionEmpty()) {
            if ($var_id && $code_location) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \false, $negated, $code_location, $suppressed_issues);
            }
            $existing_var_type->addType(new TNever());
        }
        return $existing_var_type->freeze();
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\VariableFetchAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Analyzer\TraitAnalyzer;
use Psalm\Internal\Type\Comparator\AtomicTypeComparator;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Issue\DocblockTypeContradiction;
use Psalm\Issue\TypeDoesNotContainNull;
use Psalm\Issue\TypeDoesNotContainType;
use Psalm\IssueBuffer;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\ArrayKeyExists;
use Psalm\Storage\Assertion\Falsy;
use Psalm\Storage\Assertion\HasAtLeastCount;
use Psalm\Storage\Assertion\HasExactCount;
use Psalm\Storage\Assertion\IsAClass;
use Psalm\Storage\Assertion\IsClassEqual;
use Psalm\Storage\Assertion\IsEqualIsset;
use Psalm\Storage\Assertion\IsIsset;
use Psalm\Storage\Assertion\IsLooselyEqual;
use Psalm\Storage\Assertion\NestedAssertions;
use Psalm\Storage\Assertion\NonEmpty;
use Psalm\Storage\Assertion\NonEmptyCountable;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Reconciler;
use Psalm\Type\Union;
use function array_intersect_key;
use function array_merge;
use function count;
use function get_class;
use function is_string;
/**
 * @internal
 */
class AssertionReconciler extends Reconciler
{
    /**
     * Reconciles types
     *
     * think of this as a set of functions e.g. empty(T), notEmpty(T), null(T), notNull(T) etc. where
     *  - empty(Object) => null,
     *  - empty(bool) => false,
     *  - notEmpty(Object|null) => Object,
     *  - notEmpty(Object|false) => Object
     *
     * @param   string[]            $suppressed_issues
     * @param   array<string, array<string, Union>> $template_type_map
     * @param-out Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    public static function reconcile(Assertion $assertion, ?Union $existing_var_type, ?string $key, StatementsAnalyzer $statements_analyzer, bool $inside_loop, array $template_type_map, ?CodeLocation $code_location = null, array $suppressed_issues = [], ?int &$failed_reconciliation = Reconciler::RECONCILIATION_OK, bool $negated = \false) : Union
    {
        $codebase = $statements_analyzer->getCodebase();
        $failed_reconciliation = Reconciler::RECONCILIATION_OK;
        $is_negation = $assertion->isNegation();
        if ($assertion instanceof NestedAssertions) {
            $assertion = new Falsy();
            $is_negation = \true;
        }
        if ($existing_var_type === null && is_string($key) && VariableFetchAnalyzer::isSuperGlobal($key)) {
            $existing_var_type = VariableFetchAnalyzer::getGlobalType($key, $codebase->analysis_php_version_id);
        }
        if ($existing_var_type === null) {
            return self::getMissingType($assertion, $inside_loop);
        }
        $old_var_type_string = $existing_var_type->getId();
        if ($is_negation) {
            return \Psalm\Internal\Type\NegatedAssertionReconciler::reconcile($statements_analyzer, $assertion, $existing_var_type, $old_var_type_string, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $inside_loop);
        }
        $assertion_type = $assertion->getAtomicType();
        if ($assertion_type instanceof TLiteralInt || $assertion_type instanceof TLiteralString || $assertion_type instanceof TLiteralFloat || $assertion_type instanceof TEnumCase) {
            return self::handleLiteralEquality($statements_analyzer, $assertion, $assertion_type, $existing_var_type, $old_var_type_string, $key, $negated, $code_location, $suppressed_issues);
        }
        if ($assertion instanceof IsAClass) {
            $should_return = \false;
            $new_type_parts = self::handleIsA($assertion, $codebase, $existing_var_type, $code_location, $key, $suppressed_issues, $should_return);
            if ($should_return) {
                return new Union($new_type_parts);
            }
            $new_type_part = $new_type_parts[0];
        } else {
            $simply_reconciled_type = \Psalm\Internal\Type\SimpleAssertionReconciler::reconcile($assertion, $codebase, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation, $inside_loop);
            if ($simply_reconciled_type) {
                return $simply_reconciled_type;
            }
            if ($assertion instanceof IsClassEqual) {
                $new_type_part = Atomic::create($assertion->type, null, $template_type_map);
            } elseif ($assertion_type = $assertion->getAtomicType()) {
                $new_type_part = $assertion_type;
            } else {
                $new_type_part = new TMixed();
            }
        }
        if ($existing_var_type->hasMixed()) {
            if ($assertion instanceof IsLooselyEqual && $new_type_part instanceof Scalar) {
                return $existing_var_type;
            }
            return new Union([$new_type_part]);
        }
        $refined_type = self::refine($statements_analyzer, $assertion, $new_type_part, $existing_var_type, $key, $negated, $code_location, $suppressed_issues, $failed_reconciliation);
        return \Psalm\Internal\Type\TypeExpander::expandUnion($codebase, $refined_type, null, null, null, \true, \false, \false, \true);
    }
    private static function getMissingType(Assertion $assertion, bool $inside_loop) : Union
    {
        if ($assertion instanceof IsIsset || $assertion instanceof IsEqualIsset || $assertion instanceof NonEmpty) {
            return Type::getMixed($inside_loop);
        }
        if ($assertion instanceof ArrayKeyExists || $assertion instanceof NonEmptyCountable || $assertion instanceof HasExactCount || $assertion instanceof HasAtLeastCount) {
            return Type::getMixed();
        }
        if (!$assertion->isNegation()) {
            $assertion_type = $assertion->getAtomicType();
            if ($assertion_type) {
                return new Union([$assertion_type]);
            }
        }
        return Type::getMixed();
    }
    /**
     * This method is called when SimpleAssertionReconciler was not enough. It receives the existing type, the assertion
     * and also a new type created from the assertion string.
     *
     * @param Reconciler::RECONCILIATION_* $failed_reconciliation
     * @param   string[]    $suppressed_issues
     * @param-out Reconciler::RECONCILIATION_* $failed_reconciliation
     */
    private static function refine(StatementsAnalyzer $statements_analyzer, Assertion $assertion, Atomic $new_type_part, Union &$existing_var_type, ?string $key, bool $negated, ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation) : Union
    {
        $codebase = $statements_analyzer->getCodebase();
        $old_var_type_string = $existing_var_type->getId();
        if ($new_type_part instanceof TMixed) {
            return $existing_var_type;
        }
        $new_type_has_interface = \false;
        if ($new_type_part->isObjectType()) {
            if ($new_type_part instanceof TNamedObject && $codebase->interfaceExists($new_type_part->value)) {
                $new_type_has_interface = \true;
            }
        }
        $old_type_has_interface = \false;
        if ($existing_var_type->hasObjectType()) {
            foreach ($existing_var_type->getAtomicTypes() as $existing_type_part) {
                if ($existing_type_part instanceof TNamedObject && $codebase->interfaceExists($existing_type_part->value)) {
                    $old_type_has_interface = \true;
                    break;
                }
            }
        }
        if ($new_type_part instanceof TTemplateParam && $new_type_part->as->isSingle()) {
            $new_as_atomic = $new_type_part->as->getSingleAtomic();
            $acceptable_atomic_types = [];
            foreach ($existing_var_type->getAtomicTypes() as $existing_var_type_part) {
                if ($existing_var_type_part instanceof TNamedObject || $existing_var_type_part instanceof TTemplateParam) {
                    $acceptable_atomic_types[] = $existing_var_type_part;
                } else {
                    if (AtomicTypeComparator::isContainedBy($codebase, $existing_var_type_part, $new_as_atomic)) {
                        $acceptable_atomic_types[] = $existing_var_type_part;
                    }
                }
            }
            if ($acceptable_atomic_types) {
                $acceptable_atomic_types = count($acceptable_atomic_types) === count($existing_var_type->getAtomicTypes()) ? $existing_var_type : new Union($acceptable_atomic_types);
                return new Union([$new_type_part->replaceAs($acceptable_atomic_types)]);
            }
        }
        if ($new_type_part instanceof TKeyedArray) {
            $acceptable_atomic_types = [];
            foreach ($existing_var_type->getAtomicTypes() as $existing_var_type_part) {
                if ($existing_var_type_part instanceof TKeyedArray) {
                    if (!array_intersect_key($existing_var_type_part->properties, $new_type_part->properties)) {
                        $acceptable_atomic_types[] = $existing_var_type_part->setProperties(array_merge($existing_var_type_part->properties, $new_type_part->properties));
                    }
                }
            }
            if ($acceptable_atomic_types) {
                return new Union($acceptable_atomic_types);
            }
        }
        $new_type = null;
        if ($new_type_part instanceof TNamedObject && ($new_type_has_interface || $old_type_has_interface) && !UnionTypeComparator::canExpressionTypesBeIdentical($codebase, new Union([$new_type_part]), $existing_var_type, \false)) {
            $acceptable_atomic_types = [];
            foreach ($existing_var_type->getAtomicTypes() as $existing_var_type_part) {
                if (AtomicTypeComparator::isContainedBy($codebase, $existing_var_type_part, $new_type_part)) {
                    $acceptable_atomic_types[] = $existing_var_type_part;
                    continue;
                }
                if ($existing_var_type_part instanceof TNamedObject && ($codebase->classExists($existing_var_type_part->value) || $codebase->interfaceExists($existing_var_type_part->value))) {
                    $existing_var_type_part = $existing_var_type_part->addIntersectionType($new_type_part);
                    $acceptable_atomic_types[] = $existing_var_type_part;
                }
                if ($existing_var_type_part instanceof TTemplateParam) {
                    $existing_var_type_part = $existing_var_type_part->addIntersectionType($new_type_part);
                    $acceptable_atomic_types[] = $existing_var_type_part;
                }
            }
            if ($acceptable_atomic_types) {
                return new Union($acceptable_atomic_types);
            }
        } elseif (!$new_type_part instanceof TMixed) {
            $any_scalar_type_match_found = \false;
            if ($code_location && $key && !$assertion->hasEquality() && $new_type_part instanceof TNamedObject && !$new_type_has_interface && (!$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer || $key !== '$this') && UnionTypeComparator::isContainedBy($codebase, $existing_var_type, new Union([$new_type_part]), \false, \false, null, \false, \false)) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $key, $assertion, \true, $negated, $code_location, $suppressed_issues);
            }
            $intersection_type = self::filterTypeWithAnother($codebase, $existing_var_type, new Union([$new_type_part]), $any_scalar_type_match_found);
            if ($code_location && !$intersection_type && (!$assertion instanceof IsLooselyEqual || !$any_scalar_type_match_found)) {
                if ($new_type_part instanceof TNull) {
                    if ($existing_var_type->from_docblock) {
                        IssueBuffer::maybeAdd(new DocblockTypeContradiction('Cannot resolve types for ' . $key . ' - docblock-defined type ' . $existing_var_type . ' does not contain null', $code_location, $existing_var_type->getId() . ' null'), $suppressed_issues);
                    } else {
                        IssueBuffer::maybeAdd(new TypeDoesNotContainNull('Cannot resolve types for ' . $key . ' - ' . $existing_var_type . ' does not contain null', $code_location, $existing_var_type->getId()), $suppressed_issues);
                    }
                } elseif (!$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer || $key !== '$this' && !($existing_var_type->hasLiteralClassString() && $assertion instanceof IsAClass)) {
                    if ($existing_var_type->from_docblock) {
                        IssueBuffer::maybeAdd(new DocblockTypeContradiction('Cannot resolve types for ' . $key . ' - docblock-defined type ' . $existing_var_type->getId() . ' does not contain ' . $new_type_part->getId(), $code_location, $existing_var_type->getId() . ' ' . $new_type_part->getId()), $suppressed_issues);
                    } else {
                        IssueBuffer::maybeAdd(new TypeDoesNotContainType('Cannot resolve types for ' . $key . ' - ' . $existing_var_type->getId() . ' does not contain ' . $new_type_part->getId(), $code_location, $existing_var_type->getId() . ' ' . $new_type_part->getId()), $suppressed_issues);
                    }
                }
                $failed_reconciliation = Reconciler::RECONCILIATION_EMPTY;
            }
            if ($intersection_type) {
                $new_type = $intersection_type;
            }
        }
        return $new_type ?: new Union([$new_type_part]);
    }
    /**
     * This method receives two types. The goal is to use datas in the new type to reduce the existing_type to a more
     * precise version. For example: new is `array<int>` old is `list<mixed>` so the result is `list<int>`
     */
    private static function filterTypeWithAnother(Codebase $codebase, Union &$existing_type, Union $new_type, bool &$any_scalar_type_match_found = \false) : ?Union
    {
        $matching_atomic_types = [];
        $existing_types = $existing_type->getAtomicTypes();
        foreach ($new_type->getAtomicTypes() as $new_type_part) {
            foreach ($existing_types as &$existing_type_part) {
                $matching_atomic_type = self::filterAtomicWithAnother($existing_type_part, $new_type_part, $codebase, $any_scalar_type_match_found);
                if ($matching_atomic_type) {
                    $matching_atomic_types[] = $matching_atomic_type;
                }
            }
            unset($existing_type_part);
        }
        $existing_type = $existing_type->setTypes($existing_types);
        if ($matching_atomic_types) {
            return new Union($matching_atomic_types);
        }
        return null;
    }
    private static function filterAtomicWithAnother(Atomic &$type_1_atomic, Atomic $type_2_atomic, Codebase $codebase, bool &$any_scalar_type_match_found) : ?Atomic
    {
        if ($type_1_atomic instanceof TFloat && $type_2_atomic instanceof TInt) {
            $any_scalar_type_match_found = \true;
            return $type_2_atomic;
        }
        if ($type_1_atomic instanceof TNamedObject) {
            $type_1_atomic = $type_1_atomic->setIsStatic(\false);
        }
        $atomic_comparison_results = new TypeComparisonResult();
        $atomic_contained_by = AtomicTypeComparator::isContainedBy($codebase, $type_2_atomic, $type_1_atomic, !($type_1_atomic instanceof TNamedObject && $type_2_atomic instanceof TNamedObject), \false, $atomic_comparison_results);
        if ($atomic_contained_by) {
            return self::refineContainedAtomicWithAnother($type_1_atomic, $type_2_atomic, $codebase, $atomic_comparison_results->type_coerced ?? \false);
        }
        $atomic_comparison_results = new TypeComparisonResult();
        $atomic_contained_by = AtomicTypeComparator::isContainedBy($codebase, $type_1_atomic, $type_2_atomic, $type_1_atomic instanceof TClassString && $type_2_atomic instanceof TClassString, \false, $atomic_comparison_results);
        if ($atomic_contained_by) {
            return self::refineContainedAtomicWithAnother($type_2_atomic, $type_1_atomic, $codebase, $atomic_comparison_results->type_coerced ?? \false);
        }
        $matching_atomic_type = null;
        if ($type_1_atomic instanceof TNamedObject && $type_2_atomic instanceof TNamedObject && ($codebase->interfaceExists($type_1_atomic->value) || $codebase->interfaceExists($type_2_atomic->value))) {
            return $type_2_atomic->addIntersectionType($type_1_atomic);
        }
        /*if ($type_2_atomic instanceof TKeyedArray
                    && $type_1_atomic instanceof \Psalm\Type\Atomic\TList
                ) {
                    $type_2_key = $type_2_atomic->getGenericKeyType();
                    $type_2_value = $type_2_atomic->getGenericValueType();
        
                    if (!$type_2_key->hasString()) {
                        $type_1_type_param = $type_1_atomic->type_param;
                        $type_2_value = self::filterTypeWithAnother(
                            $codebase,
                            $type_1_type_param,
                            $type_2_value,
                            $any_scalar_type_match_found
                        );
                        $type_1_atomic = $type_1_atomic->setTypeParam($type_1_type_param);
        
                        if ($type_2_value === null) {
                            return null;
                        }
        
                        return new TKeyedArray(
                            $type_2_atomic->properties,
                            null,
                            [Type::getInt(), $type_2_value],
                            true
                        );
                    }
                } elseif ($type_1_atomic instanceof TKeyedArray
                    && $type_2_atomic instanceof \Psalm\Type\Atomic\TList
                ) {
                    $type_1_key = $type_1_atomic->getGenericKeyType();
                    $type_1_value = $type_1_atomic->getGenericValueType();
        
                    if (!$type_1_key->hasString()) {
                        $type_2_type_param = $type_2_atomic->type_param;
                        $type_1_value = self::filterTypeWithAnother(
                            $codebase,
                            $type_2_type_param,
                            $type_1_value,
                            $any_scalar_type_match_found
                        );
        
                        if ($type_1_value === null) {
                            return null;
                        }
        
                        return new TKeyedArray(
                            $type_1_atomic->properties,
                            null,
                            [Type::getInt(), $type_1_value],
                            true
                        );
                    }
                }*/
        if ($type_2_atomic instanceof TTemplateParam && $type_1_atomic instanceof TTemplateParam && $type_2_atomic->param_name !== $type_1_atomic->param_name && $type_2_atomic->as->hasObject() && $type_1_atomic->as->hasObject()) {
            return $type_2_atomic->addIntersectionType($type_1_atomic);
        }
        //we filter both types of standard iterables
        if (($type_2_atomic instanceof TGenericObject || $type_2_atomic instanceof TArray || $type_2_atomic instanceof TIterable) && ($type_1_atomic instanceof TGenericObject || $type_1_atomic instanceof TArray || $type_1_atomic instanceof TIterable) && count($type_2_atomic->type_params) === count($type_1_atomic->type_params)) {
            $type_1_params = $type_1_atomic->type_params;
            foreach ($type_2_atomic->type_params as $i => $type_2_param) {
                $type_1_param = $type_1_params[$i];
                $type_2_param_id = $type_2_param->getId();
                $type_2_param = self::filterTypeWithAnother($codebase, $type_1_param, $type_2_param, $any_scalar_type_match_found);
                if ($type_2_param === null) {
                    return null;
                }
                if ($type_1_params[$i]->getId() !== $type_2_param_id) {
                    $type_1_params[$i] = $type_2_param;
                }
            }
            /** @psalm-suppress InvalidArgument */
            $type_1_atomic = $type_1_atomic->setTypeParams($type_1_params);
            $matching_atomic_type = $type_1_atomic;
            $atomic_comparison_results->type_coerced = \true;
        }
        //we filter the second part of a list with the second part of standard iterables
        /*if (($type_2_atomic instanceof TArray
                        || $type_2_atomic instanceof TIterable)
                    && $type_1_atomic instanceof \Psalm\Type\Atomic\TList
                ) {
                    $type_2_param = $type_2_atomic->type_params[1];
                    $type_1_param = $type_1_atomic->type_param;
        
                    $type_2_param = self::filterTypeWithAnother(
                        $codebase,
                        $type_1_param,
                        $type_2_param,
                        $any_scalar_type_match_found
                    );
        
                    if ($type_2_param === null) {
                        return null;
                    }
        
                    if ($type_1_param->getId() !== $type_2_param->getId()) {
                        $type_1_atomic = $type_1_atomic->setTypeParam($type_2_param);
                    } elseif ($type_1_param !== $type_1_atomic->type_param) {
                        $type_1_atomic = $type_1_atomic->setTypeParam($type_1_param);
                    }
        
                    $matching_atomic_type = $type_1_atomic;
                    $atomic_comparison_results->type_coerced = true;
                }*/
        //we filter each property of a Keyed Array with the second part of standard iterables
        if (($type_2_atomic instanceof TArray || $type_2_atomic instanceof TIterable) && $type_1_atomic instanceof TKeyedArray) {
            $type_2_param = $type_2_atomic->type_params[1];
            $type_1_properties = $type_1_atomic->properties;
            foreach ($type_1_properties as &$type_1_param) {
                $type_2_param = self::filterTypeWithAnother($codebase, $type_1_param, $type_2_param, $any_scalar_type_match_found);
                if ($type_2_param === null) {
                    return null;
                }
                if ($type_1_param->getId() !== $type_2_param->getId()) {
                    $type_1_param = $type_2_param;
                }
            }
            unset($type_1_param);
            $matching_atomic_type = $type_1_atomic->setProperties($type_1_properties);
            $atomic_comparison_results->type_coerced = \true;
        }
        //These partial match wouldn't have been handled by AtomicTypeComparator
        $new_range = null;
        if ($type_2_atomic instanceof TIntRange && $type_1_atomic instanceof TIntRange) {
            $new_range = TIntRange::intersectIntRanges($type_1_atomic, $type_2_atomic);
        }
        if ($new_range !== null) {
            $matching_atomic_type = $new_range;
        }
        // Lowercase-string and non-empty-string are compatible but none is contained into the other completely
        if ($type_2_atomic instanceof TLowercaseString && $type_1_atomic instanceof TNonEmptyString || $type_2_atomic instanceof TNonEmptyString && $type_1_atomic instanceof TLowercaseString) {
            $matching_atomic_type = new TNonEmptyLowercaseString();
        }
        if (!$atomic_comparison_results->type_coerced && $atomic_comparison_results->scalar_type_match_found) {
            $any_scalar_type_match_found = \true;
        }
        return $matching_atomic_type;
    }
    private static function refineContainedAtomicWithAnother(Atomic $type_1_atomic, Atomic $type_2_atomic, Codebase $codebase, bool $type_coerced) : ?Atomic
    {
        if ($type_coerced && get_class($type_2_atomic) === TNamedObject::class && $type_1_atomic instanceof TGenericObject) {
            // this is a hack - it's not actually rigorous, as the params may be different
            return new TGenericObject($type_2_atomic->value, $type_1_atomic->type_params);
        } elseif ($type_2_atomic instanceof TNamedObject && $type_1_atomic instanceof TTemplateParam && $type_1_atomic->as->hasObjectType()) {
            $type_1_as_init = $type_1_atomic->as;
            $type_1_as = self::filterTypeWithAnother($codebase, $type_1_as_init, new Union([$type_2_atomic]));
            if ($type_1_as === null) {
                return null;
            }
            return $type_1_atomic->replaceAs($type_1_as);
        } else {
            return $type_2_atomic;
        }
    }
    /**
     * @param  TLiteralInt|TLiteralFloat|TLiteralString|TEnumCase $assertion_type
     * @param  string[]          $suppressed_issues
     */
    private static function handleLiteralEquality(StatementsAnalyzer $statements_analyzer, Assertion $assertion, Atomic $assertion_type, Union $existing_var_type, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $existing_var_atomic_types = [];
        foreach ($existing_var_type->getAtomicTypes() as $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TClassConstant) {
                $expanded = \Psalm\Internal\Type\TypeExpander::expandAtomic($statements_analyzer->getCodebase(), $existing_var_atomic_type, $existing_var_atomic_type->fq_classlike_name, $existing_var_atomic_type->fq_classlike_name, null, \true, \true);
                foreach ($expanded as $atomic_type) {
                    $existing_var_atomic_types[$atomic_type->getKey()] = $atomic_type;
                }
            } else {
                $existing_var_atomic_types[$existing_var_atomic_type->getKey()] = $existing_var_atomic_type;
            }
        }
        if ($assertion_type instanceof TLiteralInt) {
            return self::handleLiteralEqualityWithInt($statements_analyzer, $assertion, $assertion_type, $existing_var_type, $existing_var_atomic_types, $old_var_type_string, $var_id, $negated, $code_location, $suppressed_issues);
        } elseif ($assertion_type instanceof TLiteralString) {
            return self::handleLiteralEqualityWithString($statements_analyzer, $assertion, $assertion_type, $existing_var_type, $existing_var_atomic_types, $old_var_type_string, $var_id, $negated, $code_location, $suppressed_issues);
        } elseif ($assertion_type instanceof TLiteralFloat) {
            return self::handleLiteralEqualityWithFloat($statements_analyzer, $assertion, $assertion_type, $existing_var_type, $existing_var_atomic_types, $old_var_type_string, $var_id, $negated, $code_location, $suppressed_issues);
        } else {
            $fq_enum_name = $assertion_type->value;
            $case_name = $assertion_type->case_name;
            if ($existing_var_type->hasMixed()) {
                if ($assertion instanceof IsLooselyEqual) {
                    return $existing_var_type;
                }
                return new Union([new TEnumCase($fq_enum_name, $case_name)]);
            }
            $can_be_equal = \false;
            $redundant = \true;
            $existing_var_type = $existing_var_type->getBuilder();
            foreach ($existing_var_atomic_types as $atomic_key => $atomic_type) {
                if (get_class($atomic_type) === TNamedObject::class && $atomic_type->value === $fq_enum_name) {
                    $can_be_equal = \true;
                    $redundant = \false;
                    $existing_var_type->removeType($atomic_key);
                    $existing_var_type->addType(new TEnumCase($fq_enum_name, $case_name));
                } elseif ($atomic_key !== $assertion_type->getKey()) {
                    $existing_var_type->removeType($atomic_key);
                    $redundant = \false;
                } else {
                    $can_be_equal = \true;
                }
            }
            $existing_var_type = $existing_var_type->freeze();
            if ($var_id && $code_location && (!$can_be_equal || $redundant && count($existing_var_atomic_types) === 1)) {
                self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, $can_be_equal, $negated, $code_location, $suppressed_issues);
            }
        }
        return $existing_var_type;
    }
    /**
     * @param array<string, Atomic> $existing_var_atomic_types
     * @param string[]     $suppressed_issues
     */
    private static function handleLiteralEqualityWithInt(StatementsAnalyzer $statements_analyzer, Assertion $assertion, TLiteralInt $assertion_type, Union $existing_var_type, array $existing_var_atomic_types, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $value = $assertion_type->value;
        // we create the literal that is being asserted. We'll return this when we're sure this is the resulting type
        $literal_asserted_type = new Union([new TLiteralInt($value)], ['from_docblock' => $existing_var_type->from_docblock]);
        $compatible_int_type = self::getCompatibleIntType($existing_var_type, $existing_var_atomic_types, $assertion_type, $assertion instanceof IsLooselyEqual);
        if ($compatible_int_type !== null) {
            return $compatible_int_type;
        }
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TIntRange && $existing_var_atomic_type->contains($value)) {
                return $literal_asserted_type;
            }
            if ($existing_var_atomic_type instanceof TLiteralInt && $existing_var_atomic_type->value === $value) {
                //if we're here, we check that we had at least another type in the union, otherwise it's redundant
                if ($existing_var_type->isSingleIntLiteral()) {
                    if ($var_id && $code_location) {
                        self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \true, $negated, $code_location, $suppressed_issues);
                    }
                    return $existing_var_type;
                }
                return $literal_asserted_type;
            }
            if ($existing_var_atomic_type instanceof TInt && !$existing_var_atomic_type instanceof TLiteralInt) {
                return $literal_asserted_type;
            }
            if ($existing_var_atomic_type instanceof TTemplateParam) {
                $compatible_int_type = self::getCompatibleIntType($existing_var_type, $existing_var_atomic_type->as->getAtomicTypes(), $assertion_type, $assertion instanceof IsLooselyEqual);
                if ($compatible_int_type !== null) {
                    return $compatible_int_type;
                }
                $existing_var_atomic_type = $existing_var_atomic_type->replaceAs(self::handleLiteralEquality($statements_analyzer, $assertion, $assertion_type, $existing_var_atomic_type->as, $old_var_type_string, $var_id, $negated, $code_location, $suppressed_issues));
                return new Union([$existing_var_atomic_type]);
            }
            if ($assertion instanceof IsLooselyEqual && $existing_var_atomic_type instanceof TLiteralFloat && (int) $existing_var_atomic_type->value === $value) {
                return new Union([$existing_var_atomic_type]);
            }
            if ($assertion instanceof IsLooselyEqual && $existing_var_atomic_type instanceof TLiteralString && (int) $existing_var_atomic_type->value === $value) {
                return new Union([$existing_var_atomic_type]);
            }
        }
        //here we'll accept non-literal type that *could* match on loose equality and return the original type
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            //here we'll accept non-literal type that *could* match on loose equality and return the original type
            if ($assertion instanceof IsLooselyEqual) {
                if ($existing_var_atomic_type instanceof TString && !$existing_var_atomic_type instanceof TLiteralString) {
                    return $existing_var_type;
                }
                if ($existing_var_atomic_type instanceof TFloat && !$existing_var_atomic_type instanceof TLiteralFloat) {
                    return $existing_var_type;
                }
            }
        }
        //if we're here, no type was eligible for the given literal. We'll emit an impossible error for this assertion
        if ($var_id && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \false, $negated, $code_location, $suppressed_issues);
        }
        return Type::getNever();
    }
    /**
     * @param array<string, Atomic> $existing_var_atomic_types
     * @param string[]     $suppressed_issues
     */
    private static function handleLiteralEqualityWithString(StatementsAnalyzer $statements_analyzer, Assertion $assertion, TLiteralString $assertion_type, Union $existing_var_type, array $existing_var_atomic_types, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $value = $assertion_type->value;
        // we create the literal that is being asserted. We'll return this when we're sure this is the resulting type
        $literal_asserted_type_string = new Union([$assertion_type], ['from_docblock' => $existing_var_type->from_docblock]);
        $compatible_string_type = self::getCompatibleStringType($existing_var_type, $existing_var_atomic_types, $assertion_type, $assertion instanceof IsLooselyEqual);
        if ($compatible_string_type !== null) {
            return $compatible_string_type;
        }
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TLiteralString && $existing_var_atomic_type->value === $value) {
                //if we're here, we check that we had at least another type in the union, otherwise it's redundant
                if ($existing_var_type->isSingleStringLiteral()) {
                    if ($var_id && $code_location) {
                        self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \true, $negated, $code_location, $suppressed_issues);
                    }
                    return $existing_var_type;
                }
                return $literal_asserted_type_string;
            }
            if ($existing_var_atomic_type instanceof TString && !$existing_var_atomic_type instanceof TLiteralString) {
                return $literal_asserted_type_string;
            }
            if ($existing_var_atomic_type instanceof TTemplateParam) {
                $compatible_string_type = self::getCompatibleStringType($existing_var_type, $existing_var_atomic_type->as->getAtomicTypes(), $assertion_type, $assertion instanceof IsLooselyEqual);
                if ($compatible_string_type !== null) {
                    return $compatible_string_type;
                }
                if ($existing_var_atomic_type->as->hasString()) {
                    return $literal_asserted_type_string;
                }
                $existing_var_atomic_type = $existing_var_atomic_type->replaceAs(self::handleLiteralEquality($statements_analyzer, $assertion, $assertion_type, $existing_var_atomic_type->as, $old_var_type_string, $var_id, $negated, $code_location, $suppressed_issues));
                return new Union([$existing_var_atomic_type]);
            }
            if ($assertion instanceof IsLooselyEqual && $existing_var_atomic_type instanceof TLiteralInt && (string) $existing_var_atomic_type->value === $value) {
                return new Union([$existing_var_atomic_type]);
            }
            if ($assertion instanceof IsLooselyEqual && $existing_var_atomic_type instanceof TLiteralFloat && (string) $existing_var_atomic_type->value === $value) {
                return new Union([$existing_var_atomic_type]);
            }
        }
        //here we'll accept non-literal type that *could* match on loose equality and return the original type
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            //here we'll accept non-literal type that *could* match on loose equality and return the original type
            if ($assertion instanceof IsLooselyEqual) {
                if ($existing_var_atomic_type instanceof TInt && !$existing_var_atomic_type instanceof TLiteralInt) {
                    return $existing_var_type;
                }
                if ($existing_var_atomic_type instanceof TFloat && !$existing_var_atomic_type instanceof TLiteralFloat) {
                    return $existing_var_type;
                }
            }
        }
        //if we're here, no type was eligible for the given literal. We'll emit an impossible error for this assertion
        if ($var_id && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \false, $negated, $code_location, $suppressed_issues);
        }
        return Type::getNever();
    }
    /**
     * @param array<string, Atomic> $existing_var_atomic_types
     * @param string[]     $suppressed_issues
     */
    private static function handleLiteralEqualityWithFloat(StatementsAnalyzer $statements_analyzer, Assertion $assertion, TLiteralFloat $assertion_type, Union $existing_var_type, array $existing_var_atomic_types, string $old_var_type_string, ?string $var_id, bool $negated, ?CodeLocation $code_location, array $suppressed_issues) : Union
    {
        $value = $assertion_type->value;
        // we create the literal that is being asserted. We'll return this when we're sure this is the resulting type
        $literal_asserted_type = new Union([new TLiteralFloat($value)], ['from_docblock' => $existing_var_type->from_docblock]);
        $compatible_float_type = self::getCompatibleFloatType($existing_var_type, $existing_var_atomic_types, $assertion_type, $assertion instanceof IsLooselyEqual);
        if ($compatible_float_type !== null) {
            return $compatible_float_type;
        }
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TLiteralFloat && $existing_var_atomic_type->value === $value) {
                //if we're here, we check that we had at least another type in the union, otherwise it's redundant
                if ($existing_var_type->isSingleFloatLiteral()) {
                    if ($var_id && $code_location) {
                        self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \true, $negated, $code_location, $suppressed_issues);
                    }
                    return $existing_var_type;
                }
                return $literal_asserted_type;
            }
            if ($existing_var_atomic_type instanceof TFloat && !$existing_var_atomic_type instanceof TLiteralFloat) {
                return $literal_asserted_type;
            }
            if ($existing_var_atomic_type instanceof TTemplateParam) {
                $compatible_float_type = self::getCompatibleFloatType($existing_var_type, $existing_var_atomic_type->as->getAtomicTypes(), $assertion_type, $assertion instanceof IsLooselyEqual);
                if ($compatible_float_type !== null) {
                    return $compatible_float_type;
                }
                if ($existing_var_atomic_type->as->hasFloat()) {
                    return $literal_asserted_type;
                }
                $existing_var_atomic_type = $existing_var_atomic_type->replaceAs(self::handleLiteralEquality($statements_analyzer, $assertion, $assertion_type, $existing_var_atomic_type->as, $old_var_type_string, $var_id, $negated, $code_location, $suppressed_issues));
                return new Union([$existing_var_atomic_type]);
            }
            if ($assertion instanceof IsLooselyEqual && $existing_var_atomic_type instanceof TLiteralInt && (float) $existing_var_atomic_type->value === $value) {
                return new Union([$existing_var_atomic_type]);
            }
            if ($assertion instanceof IsLooselyEqual && $existing_var_atomic_type instanceof TLiteralString && (float) $existing_var_atomic_type->value === $value) {
                return new Union([$existing_var_atomic_type]);
            }
        }
        //here we'll accept non-literal type that *could* match on loose equality and return the original type
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            if ($assertion instanceof IsLooselyEqual) {
                if ($existing_var_atomic_type instanceof TInt && !$existing_var_atomic_type instanceof TLiteralInt) {
                    return $existing_var_type;
                }
                if ($existing_var_atomic_type instanceof TString && !$existing_var_atomic_type instanceof TLiteralString) {
                    return $existing_var_type;
                }
            }
        }
        //if we're here, no type was eligible for the given literal. We'll emit an impossible error for this assertion
        if ($var_id && $code_location) {
            self::triggerIssueForImpossible($existing_var_type, $old_var_type_string, $var_id, $assertion, \false, $negated, $code_location, $suppressed_issues);
        }
        return Type::getNever();
    }
    /**
     * @param array<string, Atomic> $existing_var_atomic_types
     */
    private static function getCompatibleIntType(Union $existing_var_type, array $existing_var_atomic_types, TLiteralInt $assertion_type, bool $is_loose_equality) : ?Union
    {
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TMixed || $existing_var_atomic_type instanceof TScalar || $existing_var_atomic_type instanceof TNumeric || $existing_var_atomic_type instanceof TArrayKey) {
                if ($is_loose_equality) {
                    return $existing_var_type;
                }
                return new Union([$assertion_type], ['from_docblock' => $existing_var_type->from_docblock]);
            }
        }
        return null;
    }
    /**
     * @param array<string, Atomic> $existing_var_atomic_types
     */
    private static function getCompatibleStringType(Union $existing_var_type, array $existing_var_atomic_types, TLiteralString $assertion_type, bool $is_loose_equality) : ?Union
    {
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TMixed || $existing_var_atomic_type instanceof TScalar || $existing_var_atomic_type instanceof TArrayKey) {
                if ($is_loose_equality) {
                    return $existing_var_type;
                }
                return new Union([$assertion_type], ['from_docblock' => $existing_var_type->from_docblock]);
            }
        }
        return null;
    }
    /**
     * @param array<string, Atomic> $existing_var_atomic_types
     */
    private static function getCompatibleFloatType(Union $existing_var_type, array $existing_var_atomic_types, TLiteralFloat $assertion_type, bool $is_loose_equality) : ?Union
    {
        foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
            if ($existing_var_atomic_type instanceof TMixed || $existing_var_atomic_type instanceof TScalar || $existing_var_atomic_type instanceof TNumeric) {
                if ($is_loose_equality) {
                    return $existing_var_type;
                }
                return new Union([$assertion_type], ['from_docblock' => $existing_var_type->from_docblock]);
            }
        }
        return null;
    }
    /**
     * @param array<string>           $suppressed_issues
     * @return non-empty-list<Atomic>
     */
    private static function handleIsA(IsAClass $assertion, Codebase $codebase, Union $existing_var_type, ?CodeLocation $code_location, ?string $key, array $suppressed_issues, bool &$should_return) : array
    {
        $allow_string_comparison = $assertion->allow_string;
        $assertion_type = $assertion->type;
        if ($existing_var_type->hasMixed()) {
            if (!$assertion_type instanceof TNamedObject) {
                return [$assertion_type];
            }
            $types = [$assertion_type];
            if ($allow_string_comparison) {
                $types[] = new TClassString($assertion_type->value, $assertion_type);
            }
            $should_return = \true;
            return $types;
        }
        $existing_has_object = $existing_var_type->hasObjectType();
        $existing_has_string = $existing_var_type->hasString();
        if ($existing_has_object && !$existing_has_string) {
            if ($assertion_type instanceof TTemplateParamClass) {
                return [new TTemplateParam($assertion_type->param_name, new Union([$assertion_type->as_type ? $assertion_type->as_type : new TObject()]), $assertion_type->defining_class)];
            }
            return [$assertion_type];
        }
        if ($existing_has_string && !$existing_has_object) {
            if (!$allow_string_comparison && $code_location) {
                IssueBuffer::maybeAdd(new TypeDoesNotContainType('Cannot allow string comparison to object for ' . $key, $code_location, "no string comparison to {$key}"), $suppressed_issues);
                return [new TMixed()];
            } else {
                if (!$assertion_type instanceof TNamedObject) {
                    return [$assertion_type];
                }
                $new_type_has_interface_string = $codebase->interfaceExists($assertion_type->value);
                $old_type_has_interface_string = \false;
                foreach ($existing_var_type->getAtomicTypes() as $existing_type_part) {
                    if ($existing_type_part instanceof TClassString && $existing_type_part->as_type && $codebase->interfaceExists($existing_type_part->as_type->value)) {
                        $old_type_has_interface_string = \true;
                        break;
                    }
                }
                $new_type = Type::getClassString($assertion_type->value);
                if ($new_type_has_interface_string && !UnionTypeComparator::isContainedBy($codebase, $existing_var_type, $new_type) || $old_type_has_interface_string && !UnionTypeComparator::isContainedBy($codebase, $new_type, $existing_var_type)) {
                    $new_type_part = $assertion_type;
                    $acceptable_atomic_types = [];
                    foreach ($existing_var_type->getAtomicTypes() as $existing_var_type_part) {
                        if (!$existing_var_type_part instanceof TClassString) {
                            $acceptable_atomic_types = [];
                            break;
                        }
                        if (!$existing_var_type_part->as_type instanceof TNamedObject) {
                            $acceptable_atomic_types = [];
                            break;
                        }
                        $existing_var_type_part = $existing_var_type_part->as_type;
                        if (AtomicTypeComparator::isContainedBy($codebase, $existing_var_type_part, $new_type_part)) {
                            $acceptable_atomic_types[] = $existing_var_type_part;
                            continue;
                        }
                        if ($codebase->classExists($existing_var_type_part->value) || $codebase->interfaceExists($existing_var_type_part->value)) {
                            $existing_var_type_part = $existing_var_type_part->addIntersectionType($new_type_part);
                            $acceptable_atomic_types[] = $existing_var_type_part;
                        }
                    }
                    if (count($acceptable_atomic_types) === 1) {
                        $should_return = \true;
                        return [new TClassString('object', $acceptable_atomic_types[0])];
                    }
                }
            }
            return [$new_type->getSingleAtomic()];
        } else {
            return [new TMixed()];
        }
    }
}
<?php

namespace Psalm\Internal\Type;

use InvalidArgumentException;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\Methods;
use Psalm\Internal\Type\Comparator\CallableTypeComparator;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TDependentGetClass;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TPropertiesOf;
use Psalm\Type\Atomic\TTemplateIndexedAccess;
use Psalm\Type\Atomic\TTemplateKeyOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTemplatePropertiesOf;
use Psalm\Type\Atomic\TTemplateValueOf;
use Psalm\Type\Union;
use Throwable;
use function array_fill;
use function array_keys;
use function array_merge;
use function array_search;
use function array_slice;
use function array_values;
use function count;
use function in_array;
use function reset;
use function strpos;
use function strtolower;
use function substr;
use function usort;
/**
 * @internal
 */
class TemplateStandinTypeReplacer
{
    /**
     * This method fills in the values in $template_result based on how the various atomic types
     * of $union_type match up to the types inside $input_type.
     */
    public static function fillTemplateResult(Union $union_type, \Psalm\Internal\Type\TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer, ?Union $input_type, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, ?string $bound_equality_classlike = null, int $depth = 1) : void
    {
        self::replace($union_type, $template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $bound_equality_classlike, $depth);
    }
    /**
     * This replaces template types in unions with standins (normally the template as type)
     *
     * $input_type here is normally the argument passed to a templated function or method.
     *
     * This method fills in the values in $template_result based on how the various atomic types
     * of $union_type match up to the types inside $input_type
     */
    public static function replace(Union $union_type, \Psalm\Internal\Type\TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer, ?Union $input_type, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, ?string $bound_equality_classlike = null, int $depth = 1) : Union
    {
        $atomic_types = [];
        $original_atomic_types = $union_type->getAtomicTypes();
        // here we want to subtract atomic types from the input type
        // when they're also in the union type, so those shared atomic
        // types will never be inferred as part of the generic type
        if ($input_type && !$input_type->isSingle()) {
            $new_input_type = $input_type->getBuilder();
            foreach ($original_atomic_types as $key => $_) {
                if ($new_input_type->hasType($key)) {
                    $new_input_type->removeType($key);
                }
            }
            if (!$new_input_type->isUnionEmpty()) {
                $input_type = $new_input_type->freeze();
            } else {
                return $union_type;
            }
        }
        $had_template = \false;
        foreach ($original_atomic_types as $key => $atomic_type) {
            $atomic_types = [...$atomic_types, ...self::handleAtomicStandin($atomic_type, $key, $template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $bound_equality_classlike, $depth, count($original_atomic_types) === 1, $had_template)];
        }
        if ($replace) {
            if (array_values($original_atomic_types) === $atomic_types) {
                return $union_type;
            }
            if (!$atomic_types) {
                return $union_type;
            }
            if (count($atomic_types) > 1) {
                return \Psalm\Internal\Type\TypeCombiner::combine($atomic_types, $codebase)->setProperties(['ignore_nullable_issues' => $union_type->ignore_nullable_issues, 'ignore_falsable_issues' => $union_type->ignore_falsable_issues, 'possibly_undefined' => $union_type->possibly_undefined, 'had_template' => $had_template]);
            }
            return new Union($atomic_types, ['ignore_nullable_issues' => $union_type->ignore_nullable_issues, 'ignore_falsable_issues' => $union_type->ignore_falsable_issues, 'possibly_undefined' => $union_type->possibly_undefined, 'had_template' => $had_template]);
        }
        return $union_type;
    }
    /**
     * @return list<Atomic>
     */
    private static function handleAtomicStandin(Atomic $atomic_type, string $key, \Psalm\Internal\Type\TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer, ?Union $input_type, ?int $input_arg_offset, ?string $calling_class, ?string $calling_function, bool $replace, bool $add_lower_bound, ?string $bound_equality_classlike, int $depth, bool $was_single, bool &$had_template) : array
    {
        if ($bracket_pos = strpos($key, '<')) {
            $key = substr($key, 0, $bracket_pos);
        }
        if ($atomic_type instanceof TTemplateParam && isset($template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class])) {
            return self::handleTemplateParamStandin($atomic_type, $key, $input_type, $input_arg_offset, $calling_class, $calling_function, $template_result, $codebase, $statements_analyzer, $replace, $add_lower_bound, $bound_equality_classlike, $depth, $had_template);
        }
        if ($atomic_type instanceof TTemplateParamClass && isset($template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class])) {
            if ($replace) {
                return self::handleTemplateParamClassStandin($atomic_type, $input_type, $input_arg_offset, $calling_class, $calling_function, $template_result, $codebase, $statements_analyzer, \true, $add_lower_bound, $bound_equality_classlike, $depth, $was_single);
            }
        }
        if ($atomic_type instanceof TTemplateIndexedAccess) {
            if ($replace) {
                $atomic_types = [];
                $include_first = \true;
                if (isset($template_result->template_types[$atomic_type->array_param_name][$atomic_type->defining_class]) && !empty($template_result->lower_bounds[$atomic_type->offset_param_name])) {
                    $array_template_type = $template_result->template_types[$atomic_type->array_param_name][$atomic_type->defining_class];
                    $offset_template_type = self::getMostSpecificTypeFromBounds(array_values($template_result->lower_bounds[$atomic_type->offset_param_name])[0], $codebase);
                    if ($array_template_type->isSingle() && $offset_template_type->isSingle() && !$array_template_type->isMixed() && !$offset_template_type->isMixed()) {
                        $array_template_type = $array_template_type->getSingleAtomic();
                        $offset_template_type = $offset_template_type->getSingleAtomic();
                        if ($array_template_type instanceof TList) {
                            $array_template_type = $array_template_type->getKeyedArray();
                        }
                        if ($array_template_type instanceof TKeyedArray && ($offset_template_type instanceof TLiteralString || $offset_template_type instanceof TLiteralInt) && isset($array_template_type->properties[$offset_template_type->value])) {
                            $include_first = \false;
                            $replacement_type = $array_template_type->properties[$offset_template_type->value];
                            foreach ($replacement_type->getAtomicTypes() as $replacement_atomic_type) {
                                $atomic_types[] = $replacement_atomic_type;
                            }
                        }
                    }
                }
                if ($include_first) {
                    $atomic_types[] = $atomic_type;
                }
                return $atomic_types;
            }
            return [$atomic_type];
        }
        if ($atomic_type instanceof TTemplateKeyOf || $atomic_type instanceof TTemplateValueOf) {
            if (!$replace) {
                return [$atomic_type];
            }
            $atomic_types = [];
            $include_first = \true;
            if (isset($template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class])) {
                $template_type = $template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class];
                foreach ($template_type->getAtomicTypes() as $template_atomic) {
                    if ($template_atomic instanceof TList) {
                        $template_atomic = $template_atomic->getKeyedArray();
                    }
                    if (!$template_atomic instanceof TKeyedArray && !$template_atomic instanceof TArray) {
                        return [$atomic_type];
                    }
                    if ($atomic_type instanceof TTemplateKeyOf) {
                        if ($template_atomic instanceof TKeyedArray) {
                            $template_atomic = $template_atomic->getGenericKeyType();
                        } else {
                            $template_atomic = $template_atomic->type_params[0];
                        }
                    } else {
                        if ($template_atomic instanceof TKeyedArray) {
                            $template_atomic = $template_atomic->getGenericValueType();
                        } else {
                            $template_atomic = $template_atomic->type_params[1];
                        }
                    }
                    $include_first = \false;
                    foreach ($template_atomic->getAtomicTypes() as $key_atomic_type) {
                        $atomic_types[] = $key_atomic_type;
                    }
                }
            }
            if ($include_first) {
                $atomic_types[] = $atomic_type;
            }
            return $atomic_types;
        }
        if ($atomic_type instanceof TTemplatePropertiesOf) {
            if (!$replace || !isset($template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class])) {
                return [$atomic_type];
            }
            $template_type = $template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class];
            $classlike_type = $template_type->getSingleAtomic();
            if (!$classlike_type instanceof TNamedObject) {
                return [$atomic_type];
            }
            /** @psalm-suppress ReferenceConstraintViolation Psalm bug, $atomic_type is not a reference */
            $atomic_type = new TPropertiesOf($classlike_type, $atomic_type->visibility_filter);
            return [$atomic_type];
        }
        $matching_atomic_types = [];
        if ($input_type && !$input_type->hasMixed()) {
            $matching_atomic_types = self::findMatchingAtomicTypesForTemplate($atomic_type, $key, $codebase, $statements_analyzer, $input_type);
        }
        if (!$matching_atomic_types) {
            /** @psalm-suppress ReferenceConstraintViolation Psalm bug, $atomic_type is not a reference */
            $atomic_type = $atomic_type->replaceTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, null, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth + 1);
            return [$atomic_type];
        }
        $atomic_types = [];
        foreach ($matching_atomic_types as $matching_atomic_type) {
            $atomic_types[] = $atomic_type->replaceTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $matching_atomic_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth + 1);
        }
        return $atomic_types;
    }
    /**
     * This method attempts to find bits of the input type (normally the argument type of a method call)
     * that match the base type (normally the param type of the method). These matches are used to infer
     * more template types
     *
     * Example: when passing `array<string|int>` to a function that expects `array<T>`, a rule in this method
     * identifies the matching atomic types for `T` as `string|int`
     *
     * @return list<Atomic>
     */
    private static function findMatchingAtomicTypesForTemplate(Atomic $base_type, string $key, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer, Union $input_type) : array
    {
        $matching_atomic_types = [];
        foreach ($input_type->getAtomicTypes() as $input_key => $atomic_input_type) {
            if ($atomic_input_type instanceof TList) {
                $atomic_input_type = $atomic_input_type->getKeyedArray();
            }
            if ($bracket_pos = strpos($input_key, '<')) {
                $input_key = substr($input_key, 0, $bracket_pos);
            }
            if ($input_key === $key) {
                $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                continue;
            }
            if ($atomic_input_type instanceof TClosure && $base_type instanceof TClosure) {
                $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                continue;
            }
            if ($atomic_input_type instanceof TCallable && $base_type instanceof TCallable) {
                $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                continue;
            }
            if ($atomic_input_type instanceof TClosure && $base_type instanceof TCallable) {
                $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                continue;
            }
            if (($atomic_input_type instanceof TArray || $atomic_input_type instanceof TKeyedArray) && $key === 'iterable') {
                $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                continue;
            }
            if (strpos($input_key, $key . '&') === 0) {
                $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                continue;
            }
            if ($atomic_input_type instanceof TLiteralClassString && $base_type instanceof TClassString && $base_type->as_type) {
                try {
                    $classlike_storage = $codebase->classlike_storage_provider->get($atomic_input_type->value);
                    if (!empty($classlike_storage->template_extended_params[$base_type->as_type->value])) {
                        $atomic_input_type = new TClassString($base_type->as_type->value, new TGenericObject($base_type->as_type->value, array_values($classlike_storage->template_extended_params[$base_type->as_type->value])));
                        $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                        continue;
                    }
                } catch (InvalidArgumentException $e) {
                    // do nothing
                }
            }
            if ($base_type instanceof TCallable) {
                $matching_atomic_type = CallableTypeComparator::getCallableFromAtomic($codebase, $atomic_input_type, null, $statements_analyzer);
                if ($matching_atomic_type) {
                    $matching_atomic_types[$matching_atomic_type->getId()] = $matching_atomic_type;
                    continue;
                }
            }
            if ($atomic_input_type instanceof TNamedObject && ($base_type instanceof TNamedObject || $base_type instanceof TIterable)) {
                if ($base_type instanceof TIterable) {
                    if ($atomic_input_type->value === 'Traversable') {
                        $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                        continue;
                    }
                    $base_type = new TGenericObject('Traversable', $base_type->type_params);
                }
                try {
                    $classlike_storage = $codebase->classlike_storage_provider->get($atomic_input_type->value);
                    if ($atomic_input_type instanceof TGenericObject && isset($classlike_storage->template_extended_params[$base_type->value])) {
                        $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                        continue;
                    }
                    if (!empty($classlike_storage->template_extended_params[$base_type->value])) {
                        $atomic_input_type = new TGenericObject($atomic_input_type->value, array_values($classlike_storage->template_extended_params[$base_type->value]));
                        $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                        continue;
                    }
                    if (in_array('Traversable', $classlike_storage->class_implements) && $base_type->value === 'Iterator') {
                        $matching_atomic_types[$atomic_input_type->getId()] = $atomic_input_type;
                        continue;
                    }
                } catch (InvalidArgumentException $e) {
                    // do nothing
                }
            }
            if ($atomic_input_type instanceof TTemplateParam) {
                $matching_atomic_types = array_merge($matching_atomic_types, self::findMatchingAtomicTypesForTemplate($base_type, $key, $codebase, $statements_analyzer, $atomic_input_type->as));
                continue;
            }
        }
        return array_values($matching_atomic_types);
    }
    /**
     * @return list<Atomic>
     */
    private static function handleTemplateParamStandin(TTemplateParam &$atomic_type, string $key, ?Union $input_type, ?int $input_arg_offset, ?string $calling_class, ?string $calling_function, \Psalm\Internal\Type\TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer, bool $replace, bool $add_lower_bound, ?string $bound_equality_classlike, int $depth, bool &$had_template) : array
    {
        if ($atomic_type->defining_class === $calling_class) {
            return [$atomic_type];
        }
        $template_type = $template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class];
        if ($template_type->getId() === $key) {
            return array_values($template_type->getAtomicTypes());
        }
        $replacement_type = $template_type;
        $param_name_key = $atomic_type->param_name;
        if (strpos($key, '&')) {
            $param_name_key = $key;
        }
        $extra_types = [];
        if ($atomic_type->extra_types) {
            foreach ($atomic_type->extra_types as $extra_type) {
                $extra_type = self::replace(new Union([$extra_type]), $template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $bound_equality_classlike, $depth + 1);
                if ($extra_type->isSingle()) {
                    $extra_type = $extra_type->getSingleAtomic();
                    if ($extra_type instanceof TNamedObject || $extra_type instanceof TTemplateParam || $extra_type instanceof TIterable || $extra_type instanceof TObjectWithProperties) {
                        $extra_types[$extra_type->getKey()] = $extra_type;
                    }
                }
            }
        }
        if ($replace) {
            $atomic_types = [];
            if ($replacement_type->hasMixed() && !$atomic_type->as->hasMixed()) {
                foreach ($atomic_type->as->getAtomicTypes() as $as_atomic_type) {
                    $atomic_types[] = $as_atomic_type;
                }
            } else {
                $replacement_type = \Psalm\Internal\Type\TypeExpander::expandUnion($codebase, $replacement_type, $calling_class, $calling_class, null);
                if ($depth < 10) {
                    $replacement_type = self::replace($replacement_type, $template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, \true, $add_lower_bound, $bound_equality_classlike, $depth + 1);
                }
                foreach ($replacement_type->getAtomicTypes() as $replacement_atomic_type) {
                    $replacements_found = \false;
                    // @codingStandardsIgnoreStart
                    if ($replacement_atomic_type instanceof TTemplateKeyOf && isset($template_result->template_types[$replacement_atomic_type->param_name][$replacement_atomic_type->defining_class]) && count($template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class]) === 1) {
                        $keyed_template = $template_result->template_types[$replacement_atomic_type->param_name][$replacement_atomic_type->defining_class];
                        if ($keyed_template->isSingle()) {
                            $keyed_template = $keyed_template->getSingleAtomic();
                        }
                        if ($keyed_template instanceof \Psalm\Type\Atomic\TList) {
                            $keyed_template = $keyed_template->getKeyedArray();
                        }
                        if ($keyed_template instanceof TKeyedArray || $keyed_template instanceof TArray) {
                            if ($keyed_template instanceof TKeyedArray) {
                                $key_type = $keyed_template->getGenericKeyType();
                            } else {
                                $key_type = $keyed_template->type_params[0];
                            }
                            $replacements_found = \true;
                            foreach ($key_type->getAtomicTypes() as $key_type_atomic) {
                                $atomic_types[] = $key_type_atomic;
                            }
                            $existing_lower_bound = reset($template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class]);
                            $existing_lower_bound->type = $key_type;
                        }
                    }
                    if ($replacement_atomic_type instanceof TTemplateParam && $replacement_atomic_type->defining_class !== $calling_class && $replacement_atomic_type->defining_class !== 'fn-' . $calling_function) {
                        foreach ($replacement_atomic_type->as->getAtomicTypes() as $nested_type_atomic) {
                            $replacements_found = \true;
                            $atomic_types[] = $nested_type_atomic;
                        }
                    }
                    // @codingStandardsIgnoreEnd
                    if (!$replacements_found) {
                        $atomic_types[] = $replacement_atomic_type;
                    }
                    $had_template = \true;
                }
            }
            $matching_input_keys = [];
            $as = \Psalm\Internal\Type\TypeExpander::expandUnion($codebase, $atomic_type->as, $calling_class, $calling_class, null);
            $as = self::replace($as, $template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, \true, $add_lower_bound, $bound_equality_classlike, $depth + 1);
            $atomic_type = $atomic_type->replaceAs($as);
            if ($input_type && !$template_result->readonly && ($atomic_type->as->isMixed() || UnionTypeComparator::canBeContainedBy($codebase, $input_type, $atomic_type->as, \false, \false, $matching_input_keys))) {
                $generic_param = $input_type->getBuilder();
                if ($matching_input_keys) {
                    $generic_param_keys = array_keys($generic_param->getAtomicTypes());
                    foreach ($generic_param_keys as $atomic_key) {
                        if (!isset($matching_input_keys[$atomic_key])) {
                            $generic_param->removeType($atomic_key);
                        }
                    }
                }
                if ($add_lower_bound) {
                    return array_values($generic_param->getAtomicTypes());
                }
                $generic_param->possibly_undefined = \false;
                $generic_param = $generic_param->setFromDocblock()->freeze();
                if (isset($template_result->lower_bounds[$param_name_key][$atomic_type->defining_class])) {
                    $existing_lower_bounds = $template_result->lower_bounds[$param_name_key][$atomic_type->defining_class];
                    $has_matching_lower_bound = \false;
                    foreach ($existing_lower_bounds as $existing_lower_bound) {
                        $existing_depth = $existing_lower_bound->appearance_depth;
                        $existing_arg_offset = $existing_lower_bound->arg_offset ?? $input_arg_offset;
                        if ($existing_depth === $depth && $input_arg_offset === $existing_arg_offset && $existing_lower_bound->type->getId() === $generic_param->getId() && $existing_lower_bound->equality_bound_classlike === $bound_equality_classlike) {
                            $has_matching_lower_bound = \true;
                            break;
                        }
                    }
                    if (!$has_matching_lower_bound) {
                        $template_result->lower_bounds[$param_name_key][$atomic_type->defining_class][] = new \Psalm\Internal\Type\TemplateBound($generic_param, $depth, $input_arg_offset, $bound_equality_classlike);
                    }
                } else {
                    $template_result->lower_bounds[$param_name_key][$atomic_type->defining_class] = [new \Psalm\Internal\Type\TemplateBound($generic_param, $depth, $input_arg_offset, $bound_equality_classlike)];
                }
            }
            foreach ($atomic_types as &$t) {
                if ($t instanceof TNamedObject || $t instanceof TTemplateParam || $t instanceof TIterable || $t instanceof TObjectWithProperties) {
                    $t = $t->setIntersectionTypes($extra_types);
                } elseif ($t instanceof TObject && $extra_types) {
                    $t = reset($extra_types)->setIntersectionTypes(array_slice($extra_types, 1));
                }
            }
            unset($t);
            return $atomic_types;
        }
        if ($add_lower_bound && $input_type && !$template_result->readonly) {
            $matching_input_keys = [];
            if (UnionTypeComparator::canBeContainedBy($codebase, $input_type, $replacement_type, \false, \false, $matching_input_keys)) {
                $generic_param = $input_type->getBuilder();
                if ($matching_input_keys) {
                    $generic_param_keys = array_keys($generic_param->getAtomicTypes());
                    foreach ($generic_param_keys as $atomic_key) {
                        if (!isset($matching_input_keys[$atomic_key])) {
                            $generic_param->removeType($atomic_key);
                        }
                    }
                }
                $generic_param = $generic_param->freeze();
                $upper_bound = $template_result->upper_bounds[$param_name_key][$atomic_type->defining_class] ?? null;
                if ($upper_bound) {
                    if (!UnionTypeComparator::isContainedBy($codebase, $upper_bound->type, $generic_param) || !UnionTypeComparator::isContainedBy($codebase, $generic_param, $upper_bound->type)) {
                        $intersection_type = Type::intersectUnionTypes($upper_bound->type, $generic_param, $codebase);
                    } else {
                        $intersection_type = $generic_param;
                    }
                    if ($intersection_type) {
                        $upper_bound->type = $intersection_type;
                    } else {
                        $template_result->upper_bounds_unintersectable_types[] = $upper_bound->type;
                        $template_result->upper_bounds_unintersectable_types[] = $generic_param;
                        $upper_bound->type = Type::getMixed();
                    }
                } else {
                    $template_result->upper_bounds[$param_name_key][$atomic_type->defining_class] = new \Psalm\Internal\Type\TemplateBound($generic_param);
                }
            }
        }
        return [$atomic_type];
    }
    /**
     * @return non-empty-list<TClassString>
     */
    public static function handleTemplateParamClassStandin(TTemplateParamClass $atomic_type, ?Union $input_type, ?int $input_arg_offset, ?string $calling_class, ?string $calling_function, \Psalm\Internal\Type\TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer, bool $replace, bool $add_lower_bound, ?string $bound_equality_classlike, int $depth, bool $was_single) : array
    {
        if ($atomic_type->defining_class === $calling_class) {
            return [$atomic_type];
        }
        $atomic_types = [];
        $as_type = $atomic_type->as_type;
        if ($input_type && !$template_result->readonly) {
            $valid_input_atomic_types = [];
            foreach ($input_type->getAtomicTypes() as $input_atomic_type) {
                if ($input_atomic_type instanceof TLiteralClassString) {
                    $valid_input_atomic_types[] = new TNamedObject($input_atomic_type->value, \false, \false, [], \true);
                } elseif ($input_atomic_type instanceof TTemplateParamClass) {
                    $valid_input_atomic_types[] = new TTemplateParam($input_atomic_type->param_name, $input_atomic_type->as_type ? new Union([$input_atomic_type->as_type]) : ($input_atomic_type->as === 'object' ? Type::getObject() : Type::getMixed()), $input_atomic_type->defining_class, [], \true);
                } elseif ($input_atomic_type instanceof TClassString) {
                    if ($input_atomic_type->as_type) {
                        $valid_input_atomic_types[] = $input_atomic_type->as_type->setFromDocblock(\true);
                    } elseif ($input_atomic_type->as !== 'object') {
                        $valid_input_atomic_types[] = new TNamedObject($input_atomic_type->as, \false, \false, [], \true);
                    } else {
                        $valid_input_atomic_types[] = new TObject(\true);
                    }
                } elseif ($input_atomic_type instanceof TDependentGetClass) {
                    $valid_input_atomic_types[] = new TObject(\true);
                }
            }
            $generic_param = null;
            if ($valid_input_atomic_types) {
                $generic_param = new Union($valid_input_atomic_types);
            } elseif ($was_single) {
                $generic_param = Type::getMixed();
            }
            if ($as_type) {
                // sometimes templated class-strings can contain nested templates
                // in the as type that need to be resolved as well.
                $as_type_union = self::replace(new Union([$as_type]), $template_result, $codebase, $statements_analyzer, $generic_param, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $bound_equality_classlike, $depth + 1);
                $first = $as_type_union->getSingleAtomic();
                if (count($as_type_union->getAtomicTypes()) === 1 && $first instanceof TNamedObject) {
                    $as_type = $first;
                } else {
                    $as_type = null;
                }
            }
            if ($generic_param) {
                if (isset($template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class])) {
                    $template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class] = [new \Psalm\Internal\Type\TemplateBound(Type::combineUnionTypes($generic_param, self::getMostSpecificTypeFromBounds($template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class], $codebase)), $depth)];
                } else {
                    $template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class] = [new \Psalm\Internal\Type\TemplateBound($generic_param, $depth, $input_arg_offset)];
                }
            }
        } else {
            $template_type = $template_result->template_types[$atomic_type->param_name][$atomic_type->defining_class];
            foreach ($template_type->getAtomicTypes() as $template_atomic_type) {
                if ($template_atomic_type instanceof TNamedObject) {
                    $atomic_types[] = new TClassString($template_atomic_type->value, $template_atomic_type);
                } elseif ($template_atomic_type instanceof TObject) {
                    $atomic_types[] = new TClassString();
                }
            }
        }
        $class_string = new TClassString($atomic_type->as, $as_type);
        if (!$atomic_types) {
            $atomic_types[] = $class_string;
        }
        return $atomic_types;
    }
    /**
     * @param  array<string, array<string, non-empty-list<TemplateBound>>>  $template_types
     */
    public static function getRootTemplateType(array $template_types, string $param_name, string $defining_class, array $visited_classes, ?Codebase $codebase) : ?Union
    {
        if (isset($visited_classes[$defining_class])) {
            return null;
        }
        if (isset($template_types[$param_name][$defining_class])) {
            $mapped_type = self::getMostSpecificTypeFromBounds($template_types[$param_name][$defining_class], $codebase);
            $mapped_type_atomic_types = array_values($mapped_type->getAtomicTypes());
            if (count($mapped_type_atomic_types) > 1 || !$mapped_type_atomic_types[0] instanceof TTemplateParam) {
                return $mapped_type;
            }
            $first_template = $mapped_type_atomic_types[0];
            return self::getRootTemplateType($template_types, $first_template->param_name, $first_template->defining_class, $visited_classes + [$defining_class => \true], $codebase) ?? $mapped_type;
        }
        return null;
    }
    /**
     * This takes a list of lower bounds and returns the most general type.
     *
     * If given a single bound that's just the type of that bound.
     *
     * If instead given a collection of lower bounds it normally returns a union of those
     * bound types.
     *
     * @param  non-empty-list<TemplateBound>  $lower_bounds
     */
    public static function getMostSpecificTypeFromBounds(array $lower_bounds, ?Codebase $codebase) : Union
    {
        if (count($lower_bounds) === 1) {
            return reset($lower_bounds)->type;
        }
        usort($lower_bounds, static fn(\Psalm\Internal\Type\TemplateBound $bound_a, \Psalm\Internal\Type\TemplateBound $bound_b): int => $bound_b->appearance_depth <=> $bound_a->appearance_depth);
        $current_depth = null;
        $current_type = null;
        $had_invariant = \false;
        $last_arg_offset = -1;
        foreach ($lower_bounds as $template_bound) {
            if ($current_depth === null) {
                $current_depth = $template_bound->appearance_depth;
            } elseif ($current_depth !== $template_bound->appearance_depth && $current_type) {
                if (!$current_type->isNever() && ($had_invariant || $last_arg_offset === $template_bound->arg_offset)) {
                    // escape switches when matching on invariant generic params
                    // and when matching
                    break;
                }
                $current_depth = $template_bound->appearance_depth;
            }
            $had_invariant = $had_invariant ?: $template_bound->equality_bound_classlike !== null;
            $current_type = Type::combineUnionTypes($current_type, $template_bound->type, $codebase);
            $last_arg_offset = $template_bound->arg_offset;
        }
        return $current_type ?? Type::getMixed();
    }
    /**
     * @param TGenericObject|TNamedObject|TIterable $input_type_part
     * @param TGenericObject|TIterable $container_type_part
     * @psalm-external-mutation-free
     * @return list<Union>
     */
    public static function getMappedGenericTypeParams(Codebase $codebase, Atomic $input_type_part, Atomic $container_type_part, ?array &$container_type_params_covariant = null) : array
    {
        if ($input_type_part instanceof TGenericObject || $input_type_part instanceof TIterable) {
            $input_type_params = $input_type_part->type_params;
        } elseif ($codebase->classlike_storage_provider->has($input_type_part->value)) {
            $class_storage = $codebase->classlike_storage_provider->get($input_type_part->value);
            $container_class = $container_type_part->value;
            if (strtolower($input_type_part->value) === strtolower($container_type_part->value)) {
                $input_type_params = $class_storage->getClassTemplateTypes();
            } elseif (!empty($class_storage->template_extended_params[$container_class])) {
                $input_type_params = array_values($class_storage->template_extended_params[$container_class]);
            } else {
                $input_type_params = array_fill(0, count($class_storage->template_types ?? []), Type::getMixed());
            }
        } else {
            $input_type_params = [];
        }
        try {
            $input_class_storage = $codebase->classlike_storage_provider->get($input_type_part->value);
            $container_class_storage = $codebase->classlike_storage_provider->get($container_type_part->value);
            $container_type_params_covariant = $container_class_storage->template_covariants;
        } catch (Throwable $e) {
            $input_class_storage = null;
        }
        if ($input_type_part->value !== $container_type_part->value && $input_class_storage) {
            $input_template_types = $input_class_storage->template_types;
            $i = 0;
            $replacement_templates = [];
            if ($input_template_types && (!$input_type_part instanceof TGenericObject || !$input_type_part->remapped_params) && (!$container_type_part instanceof TGenericObject || !$container_type_part->remapped_params)) {
                foreach ($input_template_types as $template_name => $_) {
                    if (!isset($input_type_params[$i])) {
                        break;
                    }
                    $replacement_templates[$template_name][$input_type_part->value] = $input_type_params[$i];
                    $i++;
                }
            }
            $template_extends = $input_class_storage->template_extended_params;
            if (isset($template_extends[$container_type_part->value])) {
                $params = $template_extends[$container_type_part->value];
                $new_input_params = [];
                foreach ($params as $extended_input_param_type) {
                    $new_input_param = null;
                    foreach ($extended_input_param_type->getAtomicTypes() as $et) {
                        if ($et instanceof TTemplateParam) {
                            $ets = Methods::getExtendedTemplatedTypes($et, $template_extends);
                        } else {
                            $ets = [];
                        }
                        if ($ets && $ets[0] instanceof TTemplateParam && isset($input_class_storage->template_types[$ets[0]->param_name][$ets[0]->defining_class])) {
                            $old_params_offset = (int) array_search($ets[0]->param_name, array_keys($input_class_storage->template_types));
                            $candidate_param_type = $input_type_params[$old_params_offset] ?? Type::getMixed();
                            $candidate_param_type = $candidate_param_type->setProperties(['from_template_default' => \true]);
                        } else {
                            $candidate_param_type = new Union([$et], ['from_template_default' => \true]);
                        }
                        $new_input_param = Type::combineUnionTypes($new_input_param, $candidate_param_type);
                    }
                    $new_input_param = \Psalm\Internal\Type\TemplateInferredTypeReplacer::replace($new_input_param, new \Psalm\Internal\Type\TemplateResult([], $replacement_templates), $codebase);
                    $new_input_params[] = $new_input_param;
                }
                $input_type_params = $new_input_params;
            }
        }
        return $input_type_params;
    }
}
<?php

namespace Psalm\Internal\Type;

use InvalidArgumentException;
use LogicException;
use Psalm\Codebase;
use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Type\ParseTree\CallableParamTree;
use Psalm\Internal\Type\ParseTree\CallableTree;
use Psalm\Internal\Type\ParseTree\CallableWithReturnTypeTree;
use Psalm\Internal\Type\ParseTree\ConditionalTree;
use Psalm\Internal\Type\ParseTree\EncapsulationTree;
use Psalm\Internal\Type\ParseTree\FieldEllipsis;
use Psalm\Internal\Type\ParseTree\GenericTree;
use Psalm\Internal\Type\ParseTree\IndexedAccessTree;
use Psalm\Internal\Type\ParseTree\IntersectionTree;
use Psalm\Internal\Type\ParseTree\KeyedArrayPropertyTree;
use Psalm\Internal\Type\ParseTree\KeyedArrayTree;
use Psalm\Internal\Type\ParseTree\MethodTree;
use Psalm\Internal\Type\ParseTree\MethodWithReturnTypeTree;
use Psalm\Internal\Type\ParseTree\NullableTree;
use Psalm\Internal\Type\ParseTree\TemplateAsTree;
use Psalm\Internal\Type\ParseTree\UnionTree;
use Psalm\Internal\Type\ParseTree\Value;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableKeyedArray;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntMask;
use Psalm\Type\Atomic\TIntMaskOf;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TPropertiesOf;
use Psalm\Type\Atomic\TTemplateIndexedAccess;
use Psalm\Type\Atomic\TTemplateKeyOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTemplatePropertiesOf;
use Psalm\Type\Atomic\TTemplateValueOf;
use Psalm\Type\Atomic\TTypeAlias;
use Psalm\Type\Atomic\TValueOf;
use Psalm\Type\TypeNode;
use Psalm\Type\Union;
use function array_key_exists;
use function array_key_first;
use function array_keys;
use function array_map;
use function array_pop;
use function array_shift;
use function array_unique;
use function array_unshift;
use function array_values;
use function assert;
use function constant;
use function count;
use function defined;
use function end;
use function explode;
use function get_class;
use function in_array;
use function is_int;
use function is_numeric;
use function preg_match;
use function preg_replace;
use function reset;
use function stripslashes;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
/**
 * @psalm-suppress InaccessibleProperty Allowed during construction
 * @internal
 */
class TypeParser
{
    /**
     * Parses a string type representation
     *
     * @param  list<array{0: string, 1: int, 2?: string}> $type_tokens
     * @param  array{int,int}|null   $php_version
     * @param  array<string, array<string, Union>> $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     */
    public static function parseTokens(array $type_tokens, ?int $analysis_php_version_id = null, array $template_type_map = [], array $type_aliases = [], bool $from_docblock = \false) : Union
    {
        if (count($type_tokens) === 1) {
            $only_token = $type_tokens[0];
            // Note: valid identifiers can include class names or $this
            if (!preg_match('@^(\\$this|\\\\?[a-zA-Z_\\x7f-\\xff][\\\\\\-0-9a-zA-Z_\\x7f-\\xff]*)$@', $only_token[0])) {
                if (!is_numeric($only_token[0]) && strpos($only_token[0], '\'') !== \false && strpos($only_token[0], '"') !== \false) {
                    throw new TypeParseTreeException("Invalid type '{$only_token[0]}'");
                }
            } else {
                $only_token[0] = \Psalm\Internal\Type\TypeTokenizer::fixScalarTerms($only_token[0], $analysis_php_version_id);
                $atomic = Atomic::create($only_token[0], $analysis_php_version_id, $template_type_map, $type_aliases, 0, strlen($only_token[0]), isset($only_token[2]) && $only_token[2] !== $only_token[0] ? $only_token[2] : null, $from_docblock);
                return new Union([$atomic], ['from_docblock' => $from_docblock]);
            }
        }
        $parse_tree = (new \Psalm\Internal\Type\ParseTreeCreator($type_tokens))->create();
        $codebase = ProjectAnalyzer::getInstance()->getCodebase();
        $parsed_type = self::getTypeFromTree($parse_tree, $codebase, $analysis_php_version_id, $template_type_map, $type_aliases, $from_docblock);
        if (!$parsed_type instanceof Union) {
            $parsed_type = new Union([$parsed_type], ['from_docblock' => $from_docblock]);
        }
        return $parsed_type;
    }
    /**
     * @param  array<string, array<string, Union>> $template_type_map
     * @param  array<string, TypeAlias>            $type_aliases
     * @return  Atomic|Union
     */
    public static function getTypeFromTree(\Psalm\Internal\Type\ParseTree $parse_tree, Codebase $codebase, ?int $analysis_php_version_id = null, array $template_type_map = [], array $type_aliases = [], bool $from_docblock = \false) : TypeNode
    {
        if ($parse_tree instanceof GenericTree) {
            return self::getTypeFromGenericTree($parse_tree, $codebase, $template_type_map, $type_aliases, $from_docblock);
        }
        if ($parse_tree instanceof UnionTree) {
            return self::getTypeFromUnionTree($parse_tree, $codebase, $template_type_map, $type_aliases, $from_docblock);
        }
        if ($parse_tree instanceof IntersectionTree) {
            return self::getTypeFromIntersectionTree($parse_tree, $codebase, $template_type_map, $type_aliases, $from_docblock);
        }
        if ($parse_tree instanceof KeyedArrayTree) {
            return self::getTypeFromKeyedArrayTree($parse_tree, $codebase, $template_type_map, $type_aliases, $from_docblock);
        }
        if ($parse_tree instanceof CallableWithReturnTypeTree) {
            $callable_type = self::getTypeFromTree($parse_tree->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            if (!$callable_type instanceof TCallable && !$callable_type instanceof TClosure) {
                throw new InvalidArgumentException('Parsing callable tree node should return TCallable');
            }
            if (!isset($parse_tree->children[1])) {
                throw new TypeParseTreeException('Invalid return type');
            }
            $return_type = self::getTypeFromTree($parse_tree->children[1], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            $callable_type->return_type = $return_type instanceof Union ? $return_type : new Union([$return_type], ['from_docblock' => $from_docblock]);
            return $callable_type;
        }
        if ($parse_tree instanceof CallableTree) {
            return self::getTypeFromCallableTree($parse_tree, $codebase, $template_type_map, $type_aliases, $from_docblock);
        }
        if ($parse_tree instanceof EncapsulationTree) {
            if (!$parse_tree->terminated) {
                throw new TypeParseTreeException('Unterminated parentheses');
            }
            if (!isset($parse_tree->children[0])) {
                throw new TypeParseTreeException('Empty parentheses');
            }
            return self::getTypeFromTree($parse_tree->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
        }
        if ($parse_tree instanceof NullableTree) {
            if (!isset($parse_tree->children[0])) {
                throw new TypeParseTreeException('Misplaced question mark');
            }
            $non_nullable_type = self::getTypeFromTree($parse_tree->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            if ($non_nullable_type instanceof Union) {
                $non_nullable_type = $non_nullable_type->getBuilder()->addType(new TNull($from_docblock))->freeze();
                return $non_nullable_type;
            }
            return \Psalm\Internal\Type\TypeCombiner::combine([new TNull($from_docblock), $non_nullable_type]);
        }
        if ($parse_tree instanceof MethodTree || $parse_tree instanceof MethodWithReturnTypeTree) {
            throw new TypeParseTreeException('Misplaced brackets');
        }
        if ($parse_tree instanceof IndexedAccessTree) {
            return self::getTypeFromIndexAccessTree($parse_tree, $template_type_map, $from_docblock);
        }
        if ($parse_tree instanceof TemplateAsTree) {
            $result = new TTemplateParam($parse_tree->param_name, new Union([new TNamedObject($parse_tree->as)]), 'class-string-map', [], $from_docblock);
            return $result;
        }
        if ($parse_tree instanceof ConditionalTree) {
            $template_param_name = $parse_tree->condition->param_name;
            if (!isset($template_type_map[$template_param_name])) {
                throw new TypeParseTreeException('Unrecognized template \'' . $template_param_name . '\'');
            }
            if (count($parse_tree->children) !== 2) {
                throw new TypeParseTreeException('Invalid conditional');
            }
            $first_class = array_keys($template_type_map[$template_param_name])[0];
            $conditional_type = self::getTypeFromTree($parse_tree->condition->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            $if_type = self::getTypeFromTree($parse_tree->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            $else_type = self::getTypeFromTree($parse_tree->children[1], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            if ($conditional_type instanceof Atomic) {
                $conditional_type = new Union([$conditional_type], ['from_docblock' => $from_docblock]);
            }
            if ($if_type instanceof Atomic) {
                $if_type = new Union([$if_type], ['from_docblock' => $from_docblock]);
            }
            if ($else_type instanceof Atomic) {
                $else_type = new Union([$else_type], ['from_docblock' => $from_docblock]);
            }
            return new TConditional($template_param_name, $first_class, $template_type_map[$template_param_name][$first_class], $conditional_type, $if_type, $else_type, $from_docblock);
        }
        if (!$parse_tree instanceof Value) {
            throw new InvalidArgumentException('Unrecognised parse tree type ' . get_class($parse_tree));
        }
        if ($parse_tree->value[0] === '"' || $parse_tree->value[0] === '\'') {
            return new TLiteralString(substr($parse_tree->value, 1, -1), $from_docblock);
        }
        if (strpos($parse_tree->value, '::')) {
            [$fq_classlike_name, $const_name] = explode('::', $parse_tree->value);
            if (isset($template_type_map[$fq_classlike_name]) && $const_name === 'class') {
                $first_class = array_keys($template_type_map[$fq_classlike_name])[0];
                return self::getGenericParamClass($fq_classlike_name, $template_type_map[$fq_classlike_name][$first_class], $first_class, $from_docblock);
            }
            if ($const_name === 'class') {
                return new TLiteralClassString($fq_classlike_name, \false, $from_docblock);
            }
            return new TClassConstant($fq_classlike_name, $const_name, $from_docblock);
        }
        if (preg_match('/^\\-?(0|[1-9][0-9]*)(\\.[0-9]{1,})$/', $parse_tree->value)) {
            return new TLiteralFloat((float) $parse_tree->value, $from_docblock);
        }
        if (preg_match('/^\\-?(0|[1-9][0-9]*)$/', $parse_tree->value)) {
            return new TLiteralInt((int) $parse_tree->value, $from_docblock);
        }
        if (!preg_match('@^(\\$this|\\\\?[a-zA-Z_\\x7f-\\xff][\\\\\\-0-9a-zA-Z_\\x7f-\\xff]*)$@', $parse_tree->value)) {
            throw new TypeParseTreeException('Invalid type \'' . $parse_tree->value . '\'');
        }
        $atomic_type_string = \Psalm\Internal\Type\TypeTokenizer::fixScalarTerms($parse_tree->value, $analysis_php_version_id);
        return Atomic::create($atomic_type_string, $analysis_php_version_id, $template_type_map, $type_aliases, $parse_tree->offset_start, $parse_tree->offset_end, $parse_tree->text, $from_docblock);
    }
    private static function getGenericParamClass(string $param_name, Union &$as, string $defining_class, bool $from_docblock = \false) : TTemplateParamClass
    {
        if ($as->hasMixed()) {
            return new TTemplateParamClass($param_name, 'object', null, $defining_class, $from_docblock);
        }
        if (!$as->isSingle()) {
            throw new TypeParseTreeException('Invalid templated classname \'' . $as . '\'');
        }
        foreach ($as->getAtomicTypes() as $t) {
            if ($t instanceof TObject) {
                return new TTemplateParamClass($param_name, 'object', null, $defining_class, $from_docblock);
            }
            if ($t instanceof TIterable) {
                $traversable = new TGenericObject('Traversable', $t->type_params, \false, \false, [], $from_docblock);
                $as = $as->getBuilder()->substitute(new Union([$t]), new Union([$traversable]))->freeze();
                return new TTemplateParamClass($param_name, $traversable->value, $traversable, $defining_class, $from_docblock);
            }
            if ($t instanceof TTemplateParam) {
                $t_atomic_type = count($t->as->getAtomicTypes()) === 1 ? $t->as->getSingleAtomic() : null;
                if (!$t_atomic_type instanceof TNamedObject) {
                    $t_atomic_type = null;
                }
                return new TTemplateParamClass($t->param_name, $t_atomic_type->value ?? 'object', $t_atomic_type, $t->defining_class, $from_docblock);
            }
            if (!$t instanceof TNamedObject) {
                throw new TypeParseTreeException('Invalid templated classname \'' . $t->getId() . '\'');
            }
            return new TTemplateParamClass($param_name, $t->value, $t, $defining_class, $from_docblock);
        }
        throw new LogicException('Should never get here');
    }
    /**
     * @param  non-empty-list<int>  $potential_ints
     * @return  non-empty-list<TLiteralInt>
     */
    public static function getComputedIntsFromMask(array $potential_ints, bool $from_docblock = \false) : array
    {
        /** @var list<int> */
        $potential_values = [];
        foreach ($potential_ints as $ith) {
            $new_values = [];
            $new_values[] = $ith;
            if ($ith !== 0) {
                foreach ($potential_values as $potential_value) {
                    $new_values[] = $ith | $potential_value;
                }
            }
            $potential_values = [...$new_values, ...$potential_values];
        }
        array_unshift($potential_values, 0);
        $potential_values = array_unique($potential_values);
        return array_map(static fn($int): TLiteralInt => new TLiteralInt($int, $from_docblock), array_values($potential_values));
    }
    /**
     * @param  array<string, array<string, Union>> $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     * @return Atomic|Union
     * @throws TypeParseTreeException
     * @psalm-suppress ComplexMethod to be refactored
     */
    private static function getTypeFromGenericTree(GenericTree $parse_tree, Codebase $codebase, array $template_type_map, array $type_aliases, bool $from_docblock = \false)
    {
        $generic_type = $parse_tree->value;
        $generic_params = [];
        foreach ($parse_tree->children as $i => $child_tree) {
            $tree_type = self::getTypeFromTree($child_tree, $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            if ($generic_type === 'class-string-map' && $i === 0) {
                if ($tree_type instanceof TTemplateParam) {
                    $template_type_map[$tree_type->param_name] = ['class-string-map' => $tree_type->as];
                } elseif ($tree_type instanceof TNamedObject) {
                    $template_type_map[$tree_type->value] = ['class-string-map' => Type::getObject()];
                }
            }
            $generic_params[] = $tree_type instanceof Union ? $tree_type : new Union([$tree_type], ['from_docblock' => $from_docblock]);
        }
        $generic_type_value = \Psalm\Internal\Type\TypeTokenizer::fixScalarTerms($generic_type);
        if (($generic_type_value === 'array' || $generic_type_value === 'non-empty-array' || $generic_type_value === 'associative-array') && count($generic_params) === 1) {
            array_unshift($generic_params, new Union([new TArrayKey($from_docblock)]));
        } elseif (count($generic_params) === 1 && in_array($generic_type_value, ['iterable', 'Traversable', 'Iterator', 'IteratorAggregate', 'arraylike-object'], \true)) {
            array_unshift($generic_params, new Union([new TMixed(\false, $from_docblock)]));
        } elseif ($generic_type_value === 'Generator') {
            if (count($generic_params) === 1) {
                array_unshift($generic_params, new Union([new TMixed(\false, $from_docblock)]));
            }
            for ($i = 0, $l = 4 - count($generic_params); $i < $l; ++$i) {
                $generic_params[] = new Union([new TMixed(\false, $from_docblock)]);
            }
        }
        if (!$generic_params) {
            throw new TypeParseTreeException('No generic params provided for type');
        }
        if ($generic_type_value === 'array' || $generic_type_value === 'associative-array') {
            if ($generic_params[0]->isMixed()) {
                $generic_params[0] = Type::getArrayKey($from_docblock);
            }
            if (count($generic_params) !== 2) {
                throw new TypeParseTreeException('Too many template parameters for array');
            }
            return new TArray($generic_params, $from_docblock);
        }
        if ($generic_type_value === 'arraylike-object') {
            $array_acccess = new TGenericObject('ArrayAccess', $generic_params, \false, \false, [], $from_docblock);
            $countable = new TNamedObject('Countable', \false, \false, [], $from_docblock);
            return new TGenericObject('Traversable', $generic_params, \false, \false, [$array_acccess->getKey() => $array_acccess, $countable->getKey() => $countable], $from_docblock);
        }
        if ($generic_type_value === 'non-empty-array') {
            if ($generic_params[0]->isMixed()) {
                $generic_params[0] = Type::getArrayKey($from_docblock);
            }
            if (count($generic_params) !== 2) {
                throw new TypeParseTreeException('Too many template parameters for non-empty-array');
            }
            return new TNonEmptyArray($generic_params, null, null, 'non-empty-array', $from_docblock);
        }
        if ($generic_type_value === 'iterable') {
            if (count($generic_params) > 2) {
                throw new TypeParseTreeException('Too many template parameters for iterable');
            }
            return new TIterable($generic_params, [], $from_docblock);
        }
        if ($generic_type_value === 'list') {
            return Type::getListAtomic($generic_params[0], $from_docblock);
        }
        if ($generic_type_value === 'non-empty-list') {
            return Type::getNonEmptyListAtomic($generic_params[0], $from_docblock);
        }
        if ($generic_type_value === 'class-string' || $generic_type_value === 'interface-string' || $generic_type_value === 'enum-string') {
            $class_name = $generic_params[0]->getId(\false);
            if (isset($template_type_map[$class_name])) {
                $first_class = array_keys($template_type_map[$class_name])[0];
                return self::getGenericParamClass($class_name, $template_type_map[$class_name][$first_class], $first_class, $from_docblock);
            }
            $types = [];
            foreach ($generic_params[0]->getAtomicTypes() as $type) {
                if (!$type instanceof TNamedObject) {
                    throw new TypeParseTreeException('Class string param should be a named object');
                }
                $types[] = new TClassString($type->value, $type, \false, \false, \false, $from_docblock);
            }
            return new Union($types);
        }
        if ($generic_type_value === 'class-string-map') {
            if (count($generic_params) !== 2) {
                throw new TypeParseTreeException('There should only be two params for class-string-map, ' . count($generic_params) . ' provided');
            }
            $template_marker_parts = array_values($generic_params[0]->getAtomicTypes());
            $template_marker = $template_marker_parts[0];
            $template_as_type = null;
            if ($template_marker instanceof TNamedObject) {
                $template_param_name = $template_marker->value;
            } elseif ($template_marker instanceof TTemplateParam) {
                $template_param_name = $template_marker->param_name;
                $template_as_type = $template_marker->as->getSingleAtomic();
                if (!$template_as_type instanceof TNamedObject) {
                    throw new TypeParseTreeException('Unrecognised as type');
                }
            } else {
                throw new TypeParseTreeException('Unrecognised class-string-map templated param');
            }
            return new TClassStringMap($template_param_name, $template_as_type, $generic_params[1], $from_docblock);
        }
        if (in_array($generic_type_value, TPropertiesOf::tokenNames())) {
            if (count($generic_params) !== 1) {
                throw new TypeParseTreeException($generic_type_value . ' requires exactly one parameter.');
            }
            $param_name = (string) $generic_params[0];
            if (isset($template_type_map[$param_name]) && ($defining_class = array_key_first($template_type_map[$param_name])) !== null) {
                $template_param = $generic_params[0]->getSingleAtomic();
                if (!$template_param instanceof TTemplateParam) {
                    throw new TypeParseTreeException($generic_type_value . '<' . $param_name . '> must be a TTemplateParam.');
                }
                if ($template_param->getIntersectionTypes()) {
                    throw new TypeParseTreeException($generic_type_value . '<' . $param_name . '> must be a TTemplateParam' . ' with no intersection types.');
                }
                return new TTemplatePropertiesOf($param_name, $defining_class, $template_param, TPropertiesOf::filterForTokenName($generic_type_value), $from_docblock);
            }
            $param_union_types = array_values($generic_params[0]->getAtomicTypes());
            if (count($param_union_types) > 1) {
                throw new TypeParseTreeException('Union types are not allowed in ' . $generic_type_value . ' param');
            }
            if (!$param_union_types[0] instanceof TNamedObject) {
                throw new TypeParseTreeException('Param should be a named object in ' . $generic_type_value);
            }
            return new TPropertiesOf($param_union_types[0], TPropertiesOf::filterForTokenName($generic_type_value), $from_docblock);
        }
        if ($generic_type_value === 'key-of') {
            $param_name = $generic_params[0]->getId(\false);
            if (isset($template_type_map[$param_name]) && ($defining_class = array_key_first($template_type_map[$param_name])) !== null) {
                return new TTemplateKeyOf($param_name, $defining_class, $generic_params[0], $from_docblock);
            }
            if (!TKeyOf::isViableTemplateType($generic_params[0])) {
                throw new TypeParseTreeException('Untemplated key-of param ' . $param_name . ' should be an array');
            }
            return new TKeyOf($generic_params[0], $from_docblock);
        }
        if ($generic_type_value === 'value-of') {
            $param_name = $generic_params[0]->getId(\false);
            if (isset($template_type_map[$param_name]) && ($defining_class = array_key_first($template_type_map[$param_name])) !== null) {
                return new TTemplateValueOf($param_name, $defining_class, $generic_params[0], $from_docblock);
            }
            if (!TValueOf::isViableTemplateType($generic_params[0])) {
                throw new TypeParseTreeException('Untemplated value-of param ' . $param_name . ' should be an array');
            }
            return new TValueOf($generic_params[0]);
        }
        if ($generic_type_value === 'int-mask') {
            $atomic_types = [];
            foreach ($generic_params as $generic_param) {
                if (!$generic_param->isSingle()) {
                    throw new TypeParseTreeException('int-mask types must all be non-union');
                }
                $generic_param_atomics = $generic_param->getAtomicTypes();
                $atomic_type = reset($generic_param_atomics);
                if ($atomic_type instanceof TNamedObject) {
                    if (defined($atomic_type->value)) {
                        /** @var mixed */
                        $constant_value = constant($atomic_type->value);
                        if (!is_int($constant_value)) {
                            throw new TypeParseTreeException('int-mask types must all be integer values');
                        }
                        $atomic_type = new TLiteralInt($constant_value, $from_docblock);
                    } else {
                        throw new TypeParseTreeException('int-mask types must all be integer values');
                    }
                }
                if (!$atomic_type instanceof TLiteralInt && !($atomic_type instanceof TClassConstant && strpos($atomic_type->const_name, '*') === \false)) {
                    throw new TypeParseTreeException('int-mask types must all be integer values or scalar class constants');
                }
                $atomic_types[] = $atomic_type;
            }
            $potential_ints = [];
            foreach ($atomic_types as $atomic_type) {
                if (!$atomic_type instanceof TLiteralInt) {
                    return new TIntMask($atomic_types, $from_docblock);
                }
                $potential_ints[] = $atomic_type->value;
            }
            return new Union(self::getComputedIntsFromMask($potential_ints, $from_docblock));
        }
        if ($generic_type_value === 'int-mask-of') {
            $param_union_types = array_values($generic_params[0]->getAtomicTypes());
            if (count($param_union_types) > 1) {
                throw new TypeParseTreeException('Union types are not allowed in value-of type');
            }
            $param_type = $param_union_types[0];
            if (!$param_type instanceof TClassConstant && !$param_type instanceof TValueOf && !$param_type instanceof TKeyOf) {
                throw new TypeParseTreeException('Invalid reference passed to int-mask-of');
            } elseif ($param_type instanceof TClassConstant && strpos($param_type->const_name, '*') === \false) {
                throw new TypeParseTreeException('Class constant passed to int-mask-of must be a wildcard type');
            }
            return new TIntMaskOf($param_type, $from_docblock);
        }
        if ($generic_type_value === 'int') {
            if (count($generic_params) !== 2) {
                throw new TypeParseTreeException('int range must have 2 params');
            }
            assert(count($parse_tree->children) === 2);
            $get_int_range_bound = function (\Psalm\Internal\Type\ParseTree $parse_tree, Union $generic_param, string $bound_name) : ?int {
                if (!$parse_tree instanceof Value || count($generic_param->getAtomicTypes()) > 1 || !$generic_param->getSingleAtomic() instanceof TLiteralInt && $parse_tree->value !== $bound_name && $parse_tree->text !== $bound_name) {
                    throw new TypeParseTreeException("Invalid type \"{$generic_param->getId()}\" as int {$bound_name} boundary");
                }
                $generic_param_atomic = $generic_param->getSingleAtomic();
                return $generic_param_atomic instanceof TLiteralInt ? $generic_param_atomic->value : null;
            };
            $min_bound = $get_int_range_bound($parse_tree->children[0], $generic_params[0], TIntRange::BOUND_MIN);
            $max_bound = $get_int_range_bound($parse_tree->children[1], $generic_params[1], TIntRange::BOUND_MAX);
            if ($min_bound === null && $max_bound === null) {
                return new TInt($from_docblock);
            }
            if (is_int($min_bound) && is_int($max_bound) && $min_bound > $max_bound) {
                throw new TypeParseTreeException("Min bound can't be greater than max bound, int<{$min_bound}, {$max_bound}> given");
            }
            if (is_int($min_bound) && is_int($max_bound) && $min_bound > $max_bound) {
                throw new TypeParseTreeException("Min bound can't be greater than max bound, int<{$min_bound}, {$max_bound}> given");
            }
            return new TIntRange($min_bound, $max_bound, $from_docblock);
        }
        if (isset(\Psalm\Internal\Type\TypeTokenizer::PSALM_RESERVED_WORDS[$generic_type_value]) && $generic_type_value !== 'self' && $generic_type_value !== 'static') {
            throw new TypeParseTreeException('Cannot create generic object with reserved word');
        }
        return new TGenericObject($generic_type_value, $generic_params, \false, \false, [], $from_docblock);
    }
    /**
     * @param  array<string, array<string, Union>> $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     * @throws TypeParseTreeException
     */
    private static function getTypeFromUnionTree(UnionTree $parse_tree, Codebase $codebase, array $template_type_map, array $type_aliases, bool $from_docblock) : Union
    {
        $has_null = \false;
        $atomic_types = [];
        foreach ($parse_tree->children as $child_tree) {
            if ($child_tree instanceof NullableTree) {
                if (!isset($child_tree->children[0])) {
                    throw new TypeParseTreeException('Invalid ? character');
                }
                $atomic_type = self::getTypeFromTree($child_tree->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
                $has_null = \true;
            } else {
                $atomic_type = self::getTypeFromTree($child_tree, $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            }
            if ($atomic_type instanceof Union) {
                foreach ($atomic_type->getAtomicTypes() as $type) {
                    $atomic_types[] = $type;
                }
                continue;
            }
            $atomic_types[] = $atomic_type;
        }
        if ($has_null) {
            $atomic_types[] = new TNull($from_docblock);
        }
        if (!$atomic_types) {
            throw new TypeParseTreeException('No atomic types found');
        }
        return \Psalm\Internal\Type\TypeCombiner::combine($atomic_types);
    }
    /**
     * @param  array<string, array<string, Union>> $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     * @throws TypeParseTreeException
     */
    private static function getTypeFromIntersectionTree(IntersectionTree $parse_tree, Codebase $codebase, array $template_type_map, array $type_aliases, bool $from_docblock) : Atomic
    {
        $intersection_types = [];
        foreach ($parse_tree->children as $name => $child_tree) {
            $atomic_type = self::getTypeFromTree($child_tree, $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            if (!$atomic_type instanceof Atomic) {
                throw new TypeParseTreeException('Intersection types cannot contain unions');
            }
            $intersection_types[$name] = $atomic_type;
        }
        $first_type = reset($intersection_types);
        $last_type = end($intersection_types);
        $onlyTKeyedArray = $first_type instanceof TKeyedArray || $last_type instanceof TKeyedArray;
        foreach ($intersection_types as $intersection_type) {
            if (!$intersection_type instanceof TKeyedArray && ($intersection_type !== $first_type || !$first_type instanceof TArray) && ($intersection_type !== $last_type || !$last_type instanceof TArray)) {
                $onlyTKeyedArray = \false;
                break;
            }
        }
        if ($onlyTKeyedArray) {
            /** @var non-empty-array<string|int, Union> */
            $properties = [];
            if ($first_type instanceof TArray) {
                array_shift($intersection_types);
            } elseif ($last_type instanceof TArray) {
                array_pop($intersection_types);
            }
            $all_sealed = \true;
            /** @var TKeyedArray $intersection_type */
            foreach ($intersection_types as $intersection_type) {
                foreach ($intersection_type->properties as $property => $property_type) {
                    if ($intersection_type->fallback_params !== null) {
                        $all_sealed = \false;
                    }
                    if (!array_key_exists($property, $properties)) {
                        $properties[$property] = $property_type;
                        continue;
                    }
                    $new_type = Type::intersectUnionTypes($properties[$property], $property_type, $codebase);
                    if ($new_type === null) {
                        throw new TypeParseTreeException('Incompatible intersection types for "' . $property . '", ' . $properties[$property] . ' and ' . $property_type . ' provided');
                    }
                    $properties[$property] = $new_type;
                }
            }
            $first_or_last_type = $first_type instanceof TArray ? $first_type : ($last_type instanceof TArray ? $last_type : null);
            $fallback_params = null;
            if ($first_or_last_type !== null) {
                $fallback_params = [$first_or_last_type->type_params[0], $first_or_last_type->type_params[1]];
            } elseif (!$all_sealed) {
                $fallback_params = [Type::getArrayKey(), Type::getMixed()];
            }
            return new TKeyedArray($properties, null, $fallback_params, \false, $from_docblock);
        }
        $keyed_intersection_types = [];
        if ($intersection_types[0] instanceof TTypeAlias) {
            foreach ($intersection_types as $intersection_type) {
                if (!$intersection_type instanceof TTypeAlias) {
                    throw new TypeParseTreeException('Intersection types with a type alias can only be comprised of other type aliases, ' . get_class($intersection_type) . ' provided');
                }
                $keyed_intersection_types[$intersection_type->getKey()] = $intersection_type;
            }
            $first_type = array_shift($keyed_intersection_types);
            if ($keyed_intersection_types) {
                return $first_type->setIntersectionTypes($keyed_intersection_types);
            }
        } else {
            foreach ($intersection_types as $intersection_type) {
                if (!$intersection_type instanceof TIterable && !$intersection_type instanceof TNamedObject && !$intersection_type instanceof TTemplateParam && !$intersection_type instanceof TObjectWithProperties) {
                    throw new TypeParseTreeException('Intersection types must be all objects, ' . get_class($intersection_type) . ' provided');
                }
                $keyed_intersection_types[$intersection_type instanceof TIterable ? $intersection_type->getId() : $intersection_type->getKey()] = $intersection_type;
            }
            $intersect_static = \false;
            if (isset($keyed_intersection_types['static'])) {
                unset($keyed_intersection_types['static']);
                $intersect_static = \true;
            }
            if (!$keyed_intersection_types && $intersect_static) {
                return new TNamedObject('static', \false, \false, [], $from_docblock);
            }
            $first_type = array_shift($keyed_intersection_types);
            if ($intersect_static && $first_type instanceof TNamedObject) {
                $first_type->is_static = \true;
            }
            if ($keyed_intersection_types) {
                return $first_type->setIntersectionTypes($keyed_intersection_types);
            }
        }
        return $first_type;
    }
    /**
     * @param  array<string, array<string, Union>> $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     * @return TCallable|TClosure
     * @throws TypeParseTreeException
     */
    private static function getTypeFromCallableTree(CallableTree $parse_tree, Codebase $codebase, array $template_type_map, array $type_aliases, bool $from_docblock)
    {
        $params = [];
        foreach ($parse_tree->children as $child_tree) {
            $is_variadic = \false;
            $is_optional = \false;
            if ($child_tree instanceof CallableParamTree) {
                if (isset($child_tree->children[0])) {
                    $tree_type = self::getTypeFromTree($child_tree->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
                } else {
                    $tree_type = new TMixed(\false, $from_docblock);
                }
                $is_variadic = $child_tree->variadic;
                $is_optional = $child_tree->has_default;
            } else {
                if ($child_tree instanceof Value && strpos($child_tree->value, '$') > 0) {
                    $child_tree->value = preg_replace('/(.+)\\$.*/', '$1', $child_tree->value);
                }
                $tree_type = self::getTypeFromTree($child_tree, $codebase, null, $template_type_map, $type_aliases, $from_docblock);
            }
            $param = new FunctionLikeParameter('', \false, $tree_type instanceof Union ? $tree_type : new Union([$tree_type]), null, null, null, $is_optional, \false, $is_variadic);
            $params[] = $param;
        }
        $pure = strpos($parse_tree->value, 'pure-') === 0 ? \true : null;
        if (in_array(strtolower($parse_tree->value), ['closure', '\\closure', 'pure-closure'], \true)) {
            return new TClosure('Closure', $params, null, $pure, [], [], $from_docblock);
        }
        return new TCallable('callable', $params, null, $pure, $from_docblock);
    }
    /**
     * @param  array<string, array<string, Union>> $template_type_map
     * @throws TypeParseTreeException
     */
    private static function getTypeFromIndexAccessTree(IndexedAccessTree $parse_tree, array $template_type_map, bool $from_docblock) : TTemplateIndexedAccess
    {
        if (!isset($parse_tree->children[0]) || !$parse_tree->children[0] instanceof Value) {
            throw new TypeParseTreeException('Unrecognised indexed access');
        }
        $offset_param_name = $parse_tree->value;
        $array_param_name = $parse_tree->children[0]->value;
        if (!isset($template_type_map[$offset_param_name])) {
            throw new TypeParseTreeException('Unrecognised template param ' . $offset_param_name);
        }
        if (!isset($template_type_map[$array_param_name])) {
            throw new TypeParseTreeException('Unrecognised template param ' . $array_param_name);
        }
        $offset_template_data = $template_type_map[$offset_param_name];
        $offset_defining_class = array_keys($offset_template_data)[0];
        if (!$offset_defining_class && isset($offset_template_data['']) && $offset_template_data['']->isSingle()) {
            $offset_template_type = $offset_template_data['']->getSingleAtomic();
            if ($offset_template_type instanceof TTemplateKeyOf) {
                $offset_defining_class = $offset_template_type->defining_class;
            }
        }
        $array_defining_class = array_keys($template_type_map[$array_param_name])[0];
        if ($offset_defining_class !== $array_defining_class && strpos($offset_defining_class, 'fn-') !== 0) {
            throw new TypeParseTreeException('Template params are defined in different locations');
        }
        return new TTemplateIndexedAccess($array_param_name, $offset_param_name, $array_defining_class, $from_docblock);
    }
    /**
     * @param  array<string, array<string, Union>> $template_type_map
     * @param  array<string, TypeAlias> $type_aliases
     * @return TCallableKeyedArray|TKeyedArray|TObjectWithProperties|TArray
     * @throws TypeParseTreeException
     */
    private static function getTypeFromKeyedArrayTree(KeyedArrayTree $parse_tree, Codebase $codebase, array $template_type_map, array $type_aliases, bool $from_docblock)
    {
        $properties = [];
        $class_strings = [];
        $type = $parse_tree->value;
        $had_optional = \false;
        $had_explicit = \false;
        $had_implicit = \false;
        $previous_property_key = -1;
        $is_list = \true;
        $sealed = \true;
        foreach ($parse_tree->children as $i => $property_branch) {
            $class_string = \false;
            if ($property_branch instanceof FieldEllipsis) {
                if ($i !== count($parse_tree->children) - 1) {
                    throw new TypeParseTreeException('Unexpected ...');
                }
                $sealed = \false;
                break;
            }
            if (!$property_branch instanceof KeyedArrayPropertyTree) {
                $property_type = self::getTypeFromTree($property_branch, $codebase, null, $template_type_map, $type_aliases, $from_docblock);
                $property_maybe_undefined = \false;
                $property_key = $i;
                $had_implicit = \true;
            } elseif (count($property_branch->children) === 1) {
                $property_type = self::getTypeFromTree($property_branch->children[0], $codebase, null, $template_type_map, $type_aliases, $from_docblock);
                $property_maybe_undefined = $property_branch->possibly_undefined;
                if (strpos($property_branch->value, '::')) {
                    [$fq_classlike_name, $const_name] = explode('::', $property_branch->value);
                    if ($const_name === 'class') {
                        $property_key = $fq_classlike_name;
                        $class_string = \true;
                    } else {
                        $property_key = $property_branch->value;
                    }
                } else {
                    $property_key = $property_branch->value;
                }
                if ($is_list && (!is_numeric($property_key) || $had_optional && !$property_maybe_undefined || $type === 'array' || $type === 'callable-array' || $previous_property_key != $property_key - 1)) {
                    $is_list = \false;
                }
                $had_explicit = \true;
                $previous_property_key = $property_key;
                if ($property_key[0] === '\'' || $property_key[0] === '"') {
                    $property_key = stripslashes(substr($property_key, 1, -1));
                }
            } else {
                throw new TypeParseTreeException('Missing property type');
            }
            if (!$property_type instanceof Union) {
                $property_type = new Union([$property_type], ['from_docblock' => $from_docblock]);
            }
            if ($property_maybe_undefined) {
                $property_type->possibly_undefined = \true;
                $had_optional = \true;
            }
            $properties[$property_key] = $property_type;
            if ($class_string) {
                $class_strings[$property_key] = \true;
            }
        }
        if ($had_explicit && $had_implicit) {
            throw new TypeParseTreeException('Cannot mix explicit and implicit keys!');
        }
        if ($type === 'object') {
            return new TObjectWithProperties($properties, [], [], $from_docblock);
        }
        $callable = strpos($type, 'callable-') === 0;
        $class = TKeyedArray::class;
        if ($callable) {
            $class = TCallableKeyedArray::class;
            $type = substr($type, 9);
        }
        if ($callable && !$properties) {
            throw new TypeParseTreeException('A callable array cannot be empty!');
        }
        if ($type !== 'array' && $type !== 'list') {
            throw new TypeParseTreeException('Unexpected brace character');
        }
        if ($type === 'list' && !$is_list) {
            throw new TypeParseTreeException('A list shape cannot describe a non-list!');
        }
        if (!$properties) {
            return new TArray([Type::getNever($from_docblock), Type::getNever($from_docblock)], $from_docblock);
        }
        return new $class($properties, $class_strings, $sealed ? null : [$is_list ? Type::getInt() : Type::getArrayKey(), Type::getMixed()], $is_list, $from_docblock);
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Type\Atomic;
use Psalm\Type\Union;
/**
 * @internal
 */
class TypeComparisonResult
{
    /**
     * This is used to trigger `InvalidScalarArgument` in situations where we know PHP
     * will try to coerce one scalar type to another.
     */
    public ?bool $scalar_type_match_found = null;
    public ?bool $type_coerced = null;
    public ?bool $type_coerced_from_mixed = null;
    public ?bool $type_coerced_from_as_mixed = null;
    public ?bool $to_string_cast = null;
    /**
     * This is primarily used for array access.
     * For example in this function we know that there are only two possible keys, 0 and 1
     * But we allow the array to be addressed by an arbitrary integer $i.
     *
     * function takesAnInt(int $i): string {
     *     return ["foo", "bar"][$i];
     * }
     */
    public ?bool $type_coerced_from_scalar = null;
    public ?Union $replacement_union_type = null;
    public ?Atomic $replacement_atomic_type = null;
    /** @var ?non-empty-list<int|string> */
    public ?array $missing_shape_fields = null;
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TNonspecificLiteralInt;
use Psalm\Type\Union;
use UnexpectedValueException;
use function count;
use function get_class;
/**
 * @internal
 */
class IntegerRangeComparator
{
    /**
     * This method is used to check if an integer range can be contained in another
     */
    public static function isContainedBy(TIntRange $input_type_part, TIntRange $container_type_part) : bool
    {
        $is_input_min = $input_type_part->min_bound === null;
        $is_input_max = $input_type_part->max_bound === null;
        $is_container_min = $container_type_part->min_bound === null;
        $is_container_max = $container_type_part->max_bound === null;
        $is_input_min_in_container = $is_container_min || !$is_input_min && $container_type_part->min_bound <= $input_type_part->min_bound;
        $is_input_max_in_container = $is_container_max || !$is_input_max && $container_type_part->max_bound >= $input_type_part->max_bound;
        return $is_input_min_in_container && $is_input_max_in_container;
    }
    /**
     * This method is used to check if an integer range can be contained by multiple int types
     * Worst case scenario, the input is `int<-50,max>` and container is `-50|int<-49,50>|positive-int|57`
     */
    public static function isContainedByUnion(TIntRange $input_type_part, Union $container_type) : bool
    {
        $container_atomic_types = $container_type->getAtomicTypes();
        $reduced_range = new TIntRange($input_type_part->min_bound, $input_type_part->max_bound, $input_type_part->from_docblock);
        if (isset($container_atomic_types['int'])) {
            if (get_class($container_atomic_types['int']) === TInt::class) {
                return \true;
            }
            if (get_class($container_atomic_types['int']) === TNonspecificLiteralInt::class) {
                return \true;
            }
            throw new UnexpectedValueException('Should not happen: unknown int key');
        }
        $new_nb_atomics = count($container_atomic_types);
        //loop until we get to a stable situation. Either we can't remove atomics or we have a definite result
        do {
            $nb_atomics = $new_nb_atomics;
            $result_reduction = self::reduceRangeIncrementally($container_atomic_types, $reduced_range);
            $new_nb_atomics = count($container_atomic_types);
        } while ($result_reduction === null && $nb_atomics !== $new_nb_atomics);
        if ($result_reduction === null && $nb_atomics === 0) {
            //the range could not be reduced enough and there is no more atomics, it's not contained
            return \false;
        }
        return $result_reduction ?? \false;
    }
    /**
     * This method receives an array of atomics from the container and a range.
     * The goal is to use values in atomics in order to reduce the range.
     * Once the range is empty, it means that every value in range was covered by some atomics combination
     *
     * @psalm-suppress InaccessibleProperty $reduced_range was just re-created
     * @param array<string, Atomic> $container_atomic_types
     */
    private static function reduceRangeIncrementally(array &$container_atomic_types, TIntRange $reduced_range) : ?bool
    {
        foreach ($container_atomic_types as $key => $container_atomic_type) {
            if ($container_atomic_type instanceof TIntRange) {
                if (self::isContainedBy($reduced_range, $container_atomic_type)) {
                    if ($container_atomic_type->max_bound === null && $container_atomic_type->min_bound === null) {
                        //this container range covers any integer
                        return \true;
                    }
                    if ($container_atomic_type->max_bound === null) {
                        //this container range is int<X, max>
                        //X-1 becomes the max of our reduced range if it was higher
                        $reduced_range->max_bound = TIntRange::getNewLowestBound($container_atomic_type->min_bound - 1, $reduced_range->max_bound ?? $container_atomic_type->min_bound - 1);
                        unset($container_atomic_types[$key]);
                        //we don't need this one anymore
                        continue;
                    }
                    if ($container_atomic_type->min_bound === null) {
                        //this container range is int<min, X>
                        //X+1 becomes the min of our reduced range if it was lower
                        $reduced_range->min_bound = TIntRange::getNewHighestBound($container_atomic_type->max_bound + 1, $reduced_range->min_bound ?? $container_atomic_type->max_bound + 1);
                        unset($container_atomic_types[$key]);
                        //we don't need this one anymore
                        continue;
                    }
                    //if the container range has no 'null' bound, it's more complex
                    //in this case, we can only reduce if the container include one bound of our reduced range
                    if ($reduced_range->min_bound !== null && $container_atomic_type->contains($reduced_range->min_bound)) {
                        //this container range is int<X, Y> and contains the min of our reduced range.
                        //the min from our reduced range becomes Y + 1
                        $reduced_range->min_bound = $container_atomic_type->max_bound + 1;
                        unset($container_atomic_types[$key]);
                        //we don't need this one anymore
                    } elseif ($reduced_range->max_bound !== null && $container_atomic_type->contains($reduced_range->max_bound)) {
                        //this container range is int<X, Y> and contains the max of our reduced range.
                        //the max from our reduced range becomes X - 1
                        $reduced_range->max_bound = $container_atomic_type->min_bound - 1;
                        unset($container_atomic_types[$key]);
                        //we don't need this one anymore
                    }
                    //there is probably a case here where we could unset containers when they're not at all in our range
                } else {
                    //the range in input is wider than container, we return false
                    return \false;
                }
            } elseif ($container_atomic_type instanceof TLiteralInt) {
                if (!$reduced_range->contains($container_atomic_type->value)) {
                    unset($container_atomic_types[$key]);
                    //we don't need this one anymore
                } elseif ($reduced_range->min_bound === $container_atomic_type->value) {
                    $reduced_range->min_bound++;
                    unset($container_atomic_types[$key]);
                    //we don't need this one anymore
                } elseif ($reduced_range->max_bound === $container_atomic_type->value) {
                    $reduced_range->max_bound--;
                    unset($container_atomic_types[$key]);
                    //we don't need this one anymore
                }
            }
        }
        //there is probably a case here if we're left only with TLiteralInt where we could return false if there's less
        //of them than numbers in the reduced range
        //there is also a case where if there's not TLiteralInt anymore and we're left with TIntRange that don't contain
        //bounds from our reduced range where we could return false
        //if our reduced range has its min bound superior to its max bound, it means the container covers it all.
        if ($reduced_range->min_bound !== null && $reduced_range->max_bound !== null && $reduced_range->min_bound > $reduced_range->max_bound) {
            return \true;
        }
        //if we didn't return true or false before then the result is inconclusive for this round
        return null;
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TDependentGetClass;
use Psalm\Type\Atomic\TDependentGetDebugType;
use Psalm\Type\Atomic\TDependentGetType;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonEmptyNonspecificLiteralString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonFalsyString;
use Psalm\Type\Atomic\TNonspecificLiteralInt;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TSingleLetter;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTraitString;
use Psalm\Type\Atomic\TTrue;
use function get_class;
use function is_numeric;
use function strtolower;
/**
 * @internal
 */
class ScalarTypeComparator
{
    public static function isContainedBy(Codebase $codebase, Scalar $input_type_part, Scalar $container_type_part, bool $allow_interface_equality = \false, bool $allow_float_int_equality = \true, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result = null) : bool
    {
        if (get_class($container_type_part) === TString::class && $input_type_part instanceof TString) {
            return \true;
        }
        if (get_class($container_type_part) === TInt::class && $input_type_part instanceof TInt) {
            return \true;
        }
        if (get_class($container_type_part) === TFloat::class && $input_type_part instanceof TFloat) {
            return \true;
        }
        if ($container_type_part instanceof TNonEmptyString && get_class($input_type_part) === TString::class) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TNonspecificLiteralString && ($input_type_part instanceof TLiteralString || $input_type_part instanceof TNonspecificLiteralString)) {
            return \true;
        }
        if ($container_type_part instanceof TNonspecificLiteralString) {
            if ($input_type_part instanceof TString) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
            }
            return \false;
        }
        if ($container_type_part instanceof TNonspecificLiteralInt && ($input_type_part instanceof TLiteralInt || $input_type_part instanceof TNonspecificLiteralInt)) {
            return \true;
        }
        if ($container_type_part instanceof TNonspecificLiteralInt) {
            if ($input_type_part instanceof TInt) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
            }
            return \false;
        }
        if ($input_type_part instanceof TCallableString && (get_class($container_type_part) === TSingleLetter::class || get_class($container_type_part) === TNonEmptyString::class || get_class($container_type_part) === TNonFalsyString::class || get_class($container_type_part) === TLowercaseString::class)) {
            return \true;
        }
        if (($container_type_part instanceof TLowercaseString || $container_type_part instanceof TNonEmptyLowercaseString) && $input_type_part instanceof TString) {
            if ($input_type_part instanceof TLowercaseString && $container_type_part instanceof TLowercaseString || $input_type_part instanceof TNonEmptyLowercaseString && $container_type_part instanceof TNonEmptyLowercaseString) {
                return \true;
            }
            if ($input_type_part instanceof TNonEmptyLowercaseString && $container_type_part instanceof TLowercaseString) {
                return \true;
            }
            if ($input_type_part instanceof TLowercaseString && $container_type_part instanceof TNonEmptyLowercaseString) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
                return \false;
            }
            if ($input_type_part instanceof TLiteralString) {
                if (strtolower($input_type_part->value) === $input_type_part->value) {
                    return $input_type_part->value || $container_type_part instanceof TLowercaseString;
                }
                return \false;
            }
            if ($input_type_part instanceof TClassString) {
                return \false;
            }
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TDependentGetClass) {
            $first_type = $container_type_part->as_type->getSingleAtomic();
            $container_type_part = new TClassString('object', $first_type instanceof TNamedObject ? $first_type : null);
        }
        if ($input_type_part instanceof TDependentGetClass) {
            $first_type = $input_type_part->as_type->getSingleAtomic();
            if ($first_type instanceof TTemplateParam) {
                $object_type = $first_type->as->getSingleAtomic();
                $input_type_part = new TTemplateParamClass($first_type->param_name, $first_type->as->getId(), $object_type instanceof TNamedObject ? $object_type : null, $first_type->defining_class);
            } else {
                $input_type_part = new TClassString('object', $first_type instanceof TNamedObject ? $first_type : null);
            }
        }
        if ($input_type_part instanceof TDependentGetType) {
            $input_type_part = new TString();
            if ($container_type_part instanceof TLiteralString) {
                return isset(ClassLikeAnalyzer::GETTYPE_TYPES[$container_type_part->value]);
            }
        }
        if ($container_type_part instanceof TDependentGetDebugType) {
            return $input_type_part instanceof TString;
        }
        if ($input_type_part instanceof TDependentGetDebugType) {
            $input_type_part = new TString();
        }
        if ($container_type_part instanceof TDependentGetType) {
            $container_type_part = new TString();
            if ($input_type_part instanceof TLiteralString) {
                return isset(ClassLikeAnalyzer::GETTYPE_TYPES[$input_type_part->value]);
            }
        }
        if ($input_type_part instanceof TFalse && $container_type_part instanceof TBool && !$container_type_part instanceof TTrue) {
            return \true;
        }
        if ($input_type_part instanceof TTrue && $container_type_part instanceof TBool && !$container_type_part instanceof TFalse) {
            return \true;
        }
        // from https://wiki.php.net/rfc/scalar_type_hints_v5:
        //
        // > int types can resolve a parameter type of float
        if ($input_type_part instanceof TInt && $container_type_part instanceof TFloat && !$container_type_part instanceof TLiteralFloat && $allow_float_int_equality) {
            return \true;
        }
        if ($container_type_part instanceof TArrayKey && $input_type_part instanceof TNumeric) {
            return \true;
        }
        if ($container_type_part instanceof TArrayKey && ($input_type_part instanceof TInt || $input_type_part instanceof TString)) {
            return \true;
        }
        if ($input_type_part instanceof TArrayKey && ($container_type_part instanceof TInt || $container_type_part instanceof TString)) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_mixed = \true;
                $atomic_comparison_result->scalar_type_match_found = !$container_type_part->from_docblock;
            }
            return \false;
        }
        if ($container_type_part instanceof TScalar && $input_type_part instanceof Scalar) {
            return \true;
        }
        if (get_class($container_type_part) === TFloat::class && $input_type_part instanceof TLiteralFloat) {
            return \true;
        }
        if ((get_class($container_type_part) === TNonEmptyString::class || get_class($container_type_part) === TNonEmptyNonspecificLiteralString::class) && $input_type_part instanceof TNonFalsyString) {
            return \true;
        }
        if ($container_type_part instanceof TNonFalsyString && $input_type_part instanceof TNonFalsyString) {
            return \true;
        }
        if ($container_type_part instanceof TNonFalsyString && ($input_type_part instanceof TNonEmptyString || $input_type_part instanceof TNonEmptyNonspecificLiteralString)) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TNonEmptyString && $input_type_part instanceof TLiteralString && $input_type_part->value === '') {
            return \false;
        }
        if ($container_type_part instanceof TNonFalsyString && $input_type_part instanceof TLiteralString && $input_type_part->value === '0') {
            return \false;
        }
        if ((get_class($container_type_part) === TNonEmptyString::class || get_class($container_type_part) === TNonFalsyString::class || get_class($container_type_part) === TSingleLetter::class) && $input_type_part instanceof TLiteralString) {
            return \true;
        }
        if (get_class($input_type_part) === TInt::class && $container_type_part instanceof TLiteralInt) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_scalar = \true;
            }
            return \false;
        }
        if ($input_type_part instanceof TIntRange && $container_type_part instanceof TIntRange) {
            return \Psalm\Internal\Type\Comparator\IntegerRangeComparator::isContainedBy($input_type_part, $container_type_part);
        }
        if ($input_type_part instanceof TInt && $container_type_part instanceof TIntRange) {
            if ($input_type_part instanceof TLiteralInt) {
                $min_bound = $container_type_part->min_bound;
                $max_bound = $container_type_part->max_bound;
                return ($min_bound === null || $min_bound <= $input_type_part->value) && ($max_bound === null || $max_bound >= $input_type_part->value);
            }
            //any int can't be pushed inside a range without coercion (unless the range is from min to max)
            if ($container_type_part->min_bound !== null || $container_type_part->max_bound !== null) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                    $atomic_comparison_result->type_coerced_from_scalar = \true;
                }
            }
            return \false;
        }
        if (get_class($input_type_part) === TFloat::class && $container_type_part instanceof TLiteralFloat) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_scalar = \true;
            }
            return \false;
        }
        if ((get_class($input_type_part) === TString::class || get_class($input_type_part) === TSingleLetter::class || $input_type_part instanceof TNonEmptyString || $input_type_part instanceof TNonspecificLiteralString) && $container_type_part instanceof TLiteralString) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_scalar = \true;
            }
            return \false;
        }
        if (($input_type_part instanceof TLowercaseString || $input_type_part instanceof TNonEmptyLowercaseString) && $container_type_part instanceof TLiteralString && strtolower($container_type_part->value) === $container_type_part->value) {
            if ($atomic_comparison_result && $container_type_part->value) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_scalar = \true;
            }
            return \false;
        }
        if (($container_type_part instanceof TClassString || $container_type_part instanceof TLiteralClassString) && ($input_type_part instanceof TClassString || $input_type_part instanceof TLiteralClassString)) {
            return \Psalm\Internal\Type\Comparator\ClassLikeStringComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
        }
        if ($container_type_part instanceof TString && $input_type_part instanceof TTraitString) {
            return \true;
        }
        if ($container_type_part instanceof TTraitString && (get_class($input_type_part) === TString::class || $input_type_part instanceof TNonEmptyString || $input_type_part instanceof TNonEmptyNonspecificLiteralString)) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if (($input_type_part instanceof TClassString || $input_type_part instanceof TLiteralClassString) && (get_class($container_type_part) === TSingleLetter::class || get_class($container_type_part) === TNonEmptyString::class || get_class($container_type_part) === TNonFalsyString::class)) {
            return \true;
        }
        if ($input_type_part instanceof TNumericString && get_class($container_type_part) === TNonEmptyString::class) {
            return \true;
        }
        if ($container_type_part instanceof TString && $input_type_part instanceof TNumericString) {
            if ($container_type_part instanceof TLiteralString) {
                if (is_numeric($container_type_part->value) && $atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
                return \false;
            }
            return \true;
        }
        if ($input_type_part instanceof TString && $container_type_part instanceof TNumericString) {
            if ($input_type_part instanceof TLiteralString) {
                return is_numeric($input_type_part->value);
            }
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TCallableString && $input_type_part instanceof TLiteralString) {
            $input_callable = \Psalm\Internal\Type\Comparator\CallableTypeComparator::getCallableFromAtomic($codebase, $input_type_part);
            $container_callable = \Psalm\Internal\Type\Comparator\CallableTypeComparator::getCallableFromAtomic($codebase, $container_type_part);
            if ($input_callable && $container_callable) {
                if (\Psalm\Internal\Type\Comparator\CallableTypeComparator::isContainedBy($codebase, $input_callable, $container_callable, $atomic_comparison_result ?? new \Psalm\Internal\Type\Comparator\TypeComparisonResult()) === \false) {
                    return \false;
                }
            }
            if (!$input_callable) {
                //we could not find a callable for the input type, so the input is not contained in the container
                return \false;
            }
            return \true;
        }
        if ($input_type_part instanceof TLowercaseString && get_class($container_type_part) === TNonEmptyString::class) {
            return \false;
        }
        if ($input_type_part->getKey() === $container_type_part->getKey()) {
            return \true;
        }
        if (($container_type_part instanceof TClassString || $container_type_part instanceof TLiteralClassString || $container_type_part instanceof TCallableString) && $input_type_part instanceof TString) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TNumeric && $input_type_part->isNumericType()) {
            return \true;
        }
        if ($input_type_part instanceof TNumeric) {
            if ($container_type_part->isNumericType()) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                    $atomic_comparison_result->scalar_type_match_found = !$container_type_part->from_docblock;
                }
            }
        }
        if (!$container_type_part instanceof TLiteralInt && !$container_type_part instanceof TLiteralString && !$container_type_part instanceof TLiteralFloat) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = $atomic_comparison_result->type_coerced_from_scalar = $input_type_part instanceof TScalar;
                $atomic_comparison_result->scalar_type_match_found = !$container_type_part->from_docblock;
            }
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTypeAlias;
use Psalm\Type\Union;
use function array_merge;
use function array_pop;
use function array_push;
use function array_reverse;
use function count;
use function is_array;
use const PHP_INT_MAX;
/**
 * @internal
 */
class UnionTypeComparator
{
    /**
     * Does the input param type match the given param type
     */
    public static function isContainedBy(Codebase $codebase, Union $input_type, Union $container_type, bool $ignore_null = \false, bool $ignore_false = \false, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $union_comparison_result = null, bool $allow_interface_equality = \false, bool $allow_float_int_equality = \true) : bool
    {
        if ($container_type->isMixed()) {
            return \true;
        }
        if ($input_type->isNever()) {
            return \true;
        }
        if ($union_comparison_result) {
            $union_comparison_result->scalar_type_match_found = \true;
        }
        if ($input_type->possibly_undefined && !$input_type->possibly_undefined_from_try && !$container_type->possibly_undefined) {
            return \false;
        }
        if ($container_type->hasMixed() && !$container_type->isEmptyMixed()) {
            return \true;
        }
        $container_has_template = $container_type->hasTemplateOrStatic();
        $input_atomic_types = array_reverse(self::getTypeParts($codebase, $input_type));
        while ($input_type_part = array_pop($input_atomic_types)) {
            if ($input_type_part instanceof TNull && $ignore_null) {
                continue;
            }
            if ($input_type_part instanceof TFalse && $ignore_false) {
                continue;
            }
            if ($input_type_part instanceof TTemplateParam && !$container_has_template && !$input_type_part->extra_types) {
                $input_atomic_types = array_merge($input_type_part->as->getAtomicTypes(), $input_atomic_types);
                continue;
            }
            $type_match_found = \false;
            $scalar_type_match_found = \false;
            $all_to_string_cast = \true;
            $all_type_coerced = null;
            $all_type_coerced_from_mixed = null;
            $all_type_coerced_from_as_mixed = null;
            $some_type_coerced = \false;
            $some_type_coerced_from_mixed = \false;
            $some_missing_shape_fields = null;
            if ($input_type_part instanceof TArrayKey && ($container_type->hasInt() && $container_type->hasString())) {
                continue;
            }
            if ($input_type_part instanceof TArrayKey && $container_type->hasTemplate()) {
                foreach ($container_type->getTemplateTypes() as $template_type) {
                    if ($template_type->as->isArrayKey()) {
                        continue 2;
                    }
                }
            }
            if ($input_type_part instanceof TIntRange && $container_type->hasInt()) {
                if (\Psalm\Internal\Type\Comparator\IntegerRangeComparator::isContainedByUnion($input_type_part, $container_type)) {
                    continue;
                }
            }
            foreach (self::getTypeParts($codebase, $container_type) as $container_type_part) {
                if ($ignore_null && $container_type_part instanceof TNull && !$input_type_part instanceof TNull) {
                    continue;
                }
                if ($ignore_false && $container_type_part instanceof TFalse && !$input_type_part instanceof TFalse) {
                    continue;
                }
                // if params are specified
                if ($container_type_part instanceof TCallable && is_array($container_type_part->params) && $input_type_part instanceof TCallable) {
                    $container_all_param_count = count($container_type_part->params);
                    $container_required_param_count = 0;
                    foreach ($container_type_part->params as $index => $container_param) {
                        if ($container_param->is_optional === \false) {
                            $container_required_param_count = $index + 1;
                        }
                        if ($container_param->is_variadic === \true) {
                            $container_all_param_count = PHP_INT_MAX;
                        }
                    }
                    $input_required_param_count = 0;
                    if (!is_array($input_type_part->params)) {
                        // it's not declared, there can be an arbitrary number of params
                        $input_all_param_count = PHP_INT_MAX;
                    } else {
                        $input_all_param_count = count($input_type_part->params);
                        foreach ($input_type_part->params as $index => $input_param) {
                            if ($input_param->is_optional === \false) {
                                $input_required_param_count = $index + 1;
                            }
                            if ($input_param->is_variadic === \true) {
                                $input_all_param_count = PHP_INT_MAX;
                            }
                        }
                    }
                    // too few or too many non-optional params provided in callback
                    if ($container_required_param_count > $input_all_param_count || $container_all_param_count < $input_required_param_count) {
                        return \false;
                    }
                }
                if ($union_comparison_result) {
                    $atomic_comparison_result = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
                } else {
                    $atomic_comparison_result = null;
                }
                $is_atomic_contained_by = \Psalm\Internal\Type\Comparator\AtomicTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result);
                if ($input_type_part instanceof TMixed && $input_type->from_template_default && $input_type->from_docblock && $atomic_comparison_result && $atomic_comparison_result->type_coerced_from_mixed) {
                    $atomic_comparison_result->type_coerced_from_as_mixed = \true;
                }
                if ($atomic_comparison_result) {
                    if ($atomic_comparison_result->scalar_type_match_found !== null) {
                        $scalar_type_match_found = $atomic_comparison_result->scalar_type_match_found;
                    }
                    if ($union_comparison_result && $atomic_comparison_result->type_coerced_from_scalar !== null) {
                        $union_comparison_result->type_coerced_from_scalar = $atomic_comparison_result->type_coerced_from_scalar;
                    }
                    if ($is_atomic_contained_by && $union_comparison_result && $atomic_comparison_result->replacement_atomic_type) {
                        if (!$union_comparison_result->replacement_union_type) {
                            $union_comparison_result->replacement_union_type = $input_type;
                        }
                        $replacement = $union_comparison_result->replacement_union_type->getBuilder();
                        $replacement->removeType($input_type->getKey());
                        $replacement->addType($atomic_comparison_result->replacement_atomic_type);
                        $union_comparison_result->replacement_union_type = $replacement->freeze();
                    }
                }
                if ($input_type_part instanceof TNumeric && $container_type->hasString() && $container_type->hasInt() && $container_type->hasFloat()) {
                    $scalar_type_match_found = \false;
                    $is_atomic_contained_by = \true;
                }
                if ($atomic_comparison_result) {
                    if ($atomic_comparison_result->type_coerced) {
                        $some_type_coerced = \true;
                    }
                    if ($atomic_comparison_result->type_coerced_from_mixed) {
                        $some_type_coerced_from_mixed = \true;
                    }
                    if ($atomic_comparison_result->type_coerced !== \true || $all_type_coerced === \false) {
                        $all_type_coerced = \false;
                    } else {
                        $all_type_coerced = \true;
                    }
                    if ($atomic_comparison_result->type_coerced_from_mixed !== \true || $all_type_coerced_from_mixed === \false) {
                        $all_type_coerced_from_mixed = \false;
                    } else {
                        $all_type_coerced_from_mixed = \true;
                    }
                    if ($atomic_comparison_result->type_coerced_from_as_mixed !== \true || $all_type_coerced_from_as_mixed === \false) {
                        $all_type_coerced_from_as_mixed = \false;
                    } else {
                        $all_type_coerced_from_as_mixed = \true;
                    }
                    if ($atomic_comparison_result->missing_shape_fields) {
                        $some_missing_shape_fields = $atomic_comparison_result->missing_shape_fields;
                    }
                }
                if ($is_atomic_contained_by) {
                    $type_match_found = \true;
                    if ($atomic_comparison_result) {
                        if ($atomic_comparison_result->to_string_cast !== \true) {
                            $all_to_string_cast = \false;
                        }
                    }
                    $all_type_coerced_from_mixed = \false;
                    $all_type_coerced_from_as_mixed = \false;
                    $all_type_coerced = \false;
                }
            }
            if ($union_comparison_result) {
                // only set this flag if we're definite that the only
                // reason the type match has been found is because there
                // was a __toString cast
                if ($all_to_string_cast && $type_match_found) {
                    $union_comparison_result->to_string_cast = \true;
                }
                if ($all_type_coerced) {
                    $union_comparison_result->type_coerced = \true;
                }
                if ($all_type_coerced_from_mixed) {
                    $union_comparison_result->type_coerced_from_mixed = \true;
                    if ($input_type->from_template_default && $input_type->from_docblock || $all_type_coerced_from_as_mixed) {
                        $union_comparison_result->type_coerced_from_as_mixed = \true;
                    }
                }
            }
            if (!$type_match_found) {
                if ($union_comparison_result) {
                    if ($some_type_coerced) {
                        $union_comparison_result->type_coerced = \true;
                    }
                    if ($some_type_coerced_from_mixed) {
                        $union_comparison_result->type_coerced_from_mixed = \true;
                        if ($input_type->from_template_default && $input_type->from_docblock || $all_type_coerced_from_as_mixed) {
                            $union_comparison_result->type_coerced_from_as_mixed = \true;
                        }
                    }
                    if (!$scalar_type_match_found) {
                        $union_comparison_result->scalar_type_match_found = \false;
                    }
                    if ($some_missing_shape_fields && !$some_type_coerced && !$scalar_type_match_found) {
                        $union_comparison_result->missing_shape_fields = $some_missing_shape_fields;
                    }
                }
                return \false;
            }
        }
        return \true;
    }
    /**
     * Used for comparing signature typehints, uses PHP's light contravariance rules
     */
    public static function isContainedByInPhp(?Union $input_type, Union $container_type) : bool
    {
        if ($container_type->isMixed()) {
            return \true;
        }
        if (!$input_type) {
            return \false;
        }
        if ($input_type->isNever()) {
            return \true;
        }
        if ($input_type->getId() === $container_type->getId()) {
            return \true;
        }
        if ($input_type->isNullable() && !$container_type->isNullable()) {
            return \false;
        }
        $input_type_not_null = $input_type->getBuilder();
        $input_type_not_null->removeType('null');
        $container_type_not_null = $container_type->getBuilder();
        $container_type_not_null->removeType('null');
        if ($input_type_not_null->getId() === $container_type_not_null->getId()) {
            return \true;
        }
        if ($input_type_not_null->hasArray() && $container_type_not_null->hasType('iterable')) {
            return \true;
        }
        return \false;
    }
    /**
     * Does the input param type match the given param type
     */
    public static function canBeContainedBy(Codebase $codebase, Union $input_type, Union $container_type, bool $ignore_null = \false, bool $ignore_false = \false, array &$matching_input_keys = []) : bool
    {
        if ($container_type->hasMixed()) {
            return \true;
        }
        if ($input_type->isNever()) {
            return \true;
        }
        if ($input_type->possibly_undefined && !$container_type->possibly_undefined) {
            return \false;
        }
        foreach (self::getTypeParts($codebase, $container_type) as $container_type_part) {
            if ($container_type_part instanceof TNull && $ignore_null) {
                continue;
            }
            if ($container_type_part instanceof TFalse && $ignore_false) {
                continue;
            }
            foreach (self::getTypeParts($codebase, $input_type) as $input_type_part) {
                $atomic_comparison_result = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
                $is_atomic_contained_by = \Psalm\Internal\Type\Comparator\AtomicTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, \false, \false, $atomic_comparison_result);
                if ($is_atomic_contained_by && !$atomic_comparison_result->to_string_cast || $atomic_comparison_result->type_coerced_from_mixed) {
                    $matching_input_keys[$input_type_part->getKey()] = \true;
                }
            }
        }
        return (bool) $matching_input_keys;
    }
    /**
     * Can any part of the $type1 be equal to any part of $type2
     */
    public static function canExpressionTypesBeIdentical(Codebase $codebase, Union $type1, Union $type2, bool $allow_interface_equality = \true) : bool
    {
        if ($type1->hasMixed() || $type2->hasMixed()) {
            return \true;
        }
        if ($type1->isNullable() && $type2->isNullable()) {
            return \true;
        }
        foreach (self::getTypeParts($codebase, $type1) as $type1_part) {
            foreach (self::getTypeParts($codebase, $type2) as $type2_part) {
                //special case for TIntRange because it can contain a part of another TIntRange.
                //For exemple int<0,10> and int<5, 15> can be identical but none contain the other
                if ($type1_part instanceof TIntRange && $type2_part instanceof TIntRange) {
                    $intersection_range = TIntRange::intersectIntRanges($type1_part, $type2_part);
                    return $intersection_range !== null;
                }
                $either_contains = \Psalm\Internal\Type\Comparator\AtomicTypeComparator::canBeIdentical($codebase, $type1_part, $type2_part, $allow_interface_equality);
                if ($either_contains) {
                    return \true;
                }
            }
        }
        return \false;
    }
    /**
     * @return list<Atomic>
     */
    private static function getTypeParts(Codebase $codebase, Union $union_type) : array
    {
        $atomic_types = [];
        foreach ($union_type->getAtomicTypes() as $atomic_type) {
            if (!$atomic_type instanceof TTypeAlias && !$atomic_type instanceof TClassConstant) {
                $atomic_types[] = $atomic_type;
                continue;
            }
            if ($atomic_type instanceof TTypeAlias) {
                $fq_classlike_name = $atomic_type->declaring_fq_classlike_name;
            } else {
                $fq_classlike_name = $atomic_type->fq_classlike_name;
            }
            $expanded = TypeExpander::expandAtomic($codebase, $atomic_type, $fq_classlike_name, $fq_classlike_name, null, \true, \true);
            array_push($atomic_types, ...$expanded);
        }
        return $atomic_types;
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArrayTypeComparator
{
    /**
     * @param TArray|TKeyedArray|TClassStringMap $input_type_part
     * @param TArray|TKeyedArray|TClassStringMap $container_type_part
     */
    public static function isContainedBy(Codebase $codebase, Atomic $input_type_part, Atomic $container_type_part, bool $allow_interface_equality, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result) : bool
    {
        $all_types_contain = \true;
        $is_empty_array = $input_type_part->equals(new TArray([new Union([new TNever()]), new Union([new TNever()])]), \false);
        if ($is_empty_array && ($container_type_part instanceof TArray && !$container_type_part instanceof TNonEmptyArray || $container_type_part instanceof TKeyedArray && !$container_type_part->isNonEmpty())) {
            return \true;
        }
        if ($container_type_part instanceof TKeyedArray && $input_type_part instanceof TArray) {
            $all_string_int_literals = \true;
            $properties = [];
            $value = $input_type_part->type_params[1]->setPossiblyUndefined(\true);
            foreach ($input_type_part->type_params[0]->getAtomicTypes() as $atomic_key_type) {
                if ($atomic_key_type instanceof TLiteralString || $atomic_key_type instanceof TLiteralInt) {
                    $properties[$atomic_key_type->value] = $value;
                } else {
                    $all_string_int_literals = \false;
                }
            }
            if ($all_string_int_literals && $properties) {
                $input_type_part = new TKeyedArray($properties);
                return \Psalm\Internal\Type\Comparator\KeyedArrayComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
            }
        }
        if ($container_type_part instanceof TKeyedArray && $container_type_part->is_list && ($input_type_part instanceof TKeyedArray && !$input_type_part->is_list || $input_type_part instanceof TArray)) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TKeyedArray && $container_type_part->is_list && $input_type_part instanceof TClassStringMap) {
            return \false;
        }
        if ($container_type_part instanceof TKeyedArray) {
            $container_type_part = $container_type_part->getGenericArrayType();
        }
        if ($input_type_part instanceof TKeyedArray) {
            $input_type_part = $input_type_part->getGenericArrayType();
        }
        if ($input_type_part instanceof TClassStringMap) {
            $input_type_part = new TArray([$input_type_part->getStandinKeyParam(), $input_type_part->value_param]);
        }
        if ($container_type_part instanceof TClassStringMap) {
            $container_type_part = new TArray([$container_type_part->getStandinKeyParam(), $container_type_part->value_param]);
        }
        foreach ($input_type_part->type_params as $i => $input_param) {
            $container_param = $container_type_part->type_params[$i];
            if ($i === 0 && $input_param->hasMixed() && $container_param->hasString() && $container_param->hasInt()) {
                continue;
            }
            if ($input_param->isNever() && $container_type_part instanceof TNonEmptyArray) {
                return \false;
            }
            $param_comparison_result = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
            if (!$input_param->isNever()) {
                if (!\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_param, $container_param, $input_param->ignore_nullable_issues, $input_param->ignore_falsable_issues, $param_comparison_result, $allow_interface_equality)) {
                    if ($atomic_comparison_result) {
                        $atomic_comparison_result->type_coerced = $param_comparison_result->type_coerced === \true && $atomic_comparison_result->type_coerced !== \false;
                        $atomic_comparison_result->type_coerced_from_mixed = $param_comparison_result->type_coerced_from_mixed === \true && $atomic_comparison_result->type_coerced_from_mixed !== \false;
                        $atomic_comparison_result->type_coerced_from_as_mixed = $param_comparison_result->type_coerced_from_as_mixed === \true && $atomic_comparison_result->type_coerced_from_as_mixed !== \false;
                        $atomic_comparison_result->type_coerced_from_scalar = $param_comparison_result->type_coerced_from_scalar === \true && $atomic_comparison_result->type_coerced_from_scalar !== \false;
                        $atomic_comparison_result->scalar_type_match_found = $param_comparison_result->scalar_type_match_found === \true && $atomic_comparison_result->scalar_type_match_found !== \false;
                    }
                    if (!$param_comparison_result->type_coerced_from_as_mixed) {
                        $all_types_contain = \false;
                    }
                } else {
                    if ($atomic_comparison_result) {
                        $atomic_comparison_result->to_string_cast = $atomic_comparison_result->to_string_cast === \true || $param_comparison_result->to_string_cast === \true;
                    }
                }
            }
        }
        if ($container_type_part instanceof TNonEmptyArray && !$input_type_part instanceof TNonEmptyArray) {
            if ($all_types_contain && $atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        return $all_types_contain;
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Exception;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Variable;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableArray;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function end;
use function strtolower;
use function substr;
/**
 * @internal
 */
class CallableTypeComparator
{
    /**
     * @param  TCallable|TClosure   $input_type_part
     * @param  TCallable|TClosure   $container_type_part
     */
    public static function isContainedBy(Codebase $codebase, Atomic $input_type_part, Atomic $container_type_part, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result) : bool
    {
        if ($container_type_part->is_pure && !$input_type_part->is_pure) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = $input_type_part->is_pure === null;
            }
            return \false;
        }
        if ($container_type_part->params !== null && $input_type_part->params === null) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_mixed = \true;
            }
            return \false;
        }
        if ($input_type_part->params !== null && $container_type_part->params !== null) {
            foreach ($input_type_part->params as $i => $input_param) {
                $container_param = null;
                if (isset($container_type_part->params[$i])) {
                    $container_param = $container_type_part->params[$i];
                } elseif ($container_type_part->params) {
                    $last_param = end($container_type_part->params);
                    if ($last_param->is_variadic) {
                        $container_param = $last_param;
                    }
                }
                if (!$container_param) {
                    if ($input_param->is_optional) {
                        break;
                    }
                    return \false;
                }
                if ($container_param->type && !$container_param->type->hasMixed() && !\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $container_param->type, $input_param->type ?: Type::getMixed(), \false, \false, $atomic_comparison_result)) {
                    return \false;
                }
            }
        }
        if (isset($container_type_part->return_type)) {
            if (!isset($input_type_part->return_type)) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                    $atomic_comparison_result->type_coerced_from_mixed = \true;
                }
                return \false;
            }
            $input_return = $input_type_part->return_type;
            if ($input_return->isVoid() && $container_type_part->return_type->isNullable()) {
                return \true;
            }
            if (!$container_type_part->return_type->isVoid() && !\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_return, $container_type_part->return_type, \false, \false, $atomic_comparison_result)) {
                return \false;
            }
        }
        return \true;
    }
    public static function isNotExplicitlyCallableTypeCallable(Codebase $codebase, Atomic $input_type_part, TCallable $container_type_part, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result) : bool
    {
        if ($input_type_part instanceof TList) {
            $input_type_part = $input_type_part->getKeyedArray();
        }
        if ($input_type_part instanceof TArray) {
            if ($input_type_part->type_params[1]->isMixed() || $input_type_part->type_params[1]->hasScalar()) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced_from_mixed = \true;
                    $atomic_comparison_result->type_coerced = \true;
                }
                return \false;
            }
            if (!$input_type_part->type_params[1]->hasString()) {
                return \false;
            }
            if (!$input_type_part instanceof TCallableArray) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced_from_mixed = \true;
                    $atomic_comparison_result->type_coerced = \true;
                }
                return \false;
            }
        } elseif ($input_type_part instanceof TKeyedArray) {
            $method_id = self::getCallableMethodIdFromTKeyedArray($input_type_part);
            if ($method_id === 'not-callable') {
                return \false;
            }
            if (!$method_id) {
                return \true;
            }
            try {
                $method_id = $codebase->methods->getDeclaringMethodId($method_id);
                if (!$method_id) {
                    return \false;
                }
                if (!$codebase->methods->hasStorage($method_id)) {
                    return \false;
                }
            } catch (Exception $e) {
                return \false;
            }
        }
        $input_callable = self::getCallableFromAtomic($codebase, $input_type_part, $container_type_part, null, \true);
        if ($input_callable) {
            if (self::isContainedBy($codebase, $input_callable, $container_type_part, $atomic_comparison_result) === \false) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @return TCallable|TClosure|null
     */
    public static function getCallableFromAtomic(Codebase $codebase, Atomic $input_type_part, ?TCallable $container_type_part = null, ?StatementsAnalyzer $statements_analyzer = null, bool $expand_callable = \false) : ?Atomic
    {
        if ($input_type_part instanceof TList) {
            $input_type_part = $input_type_part->getKeyedArray();
        }
        if ($input_type_part instanceof TCallable || $input_type_part instanceof TClosure) {
            return $input_type_part;
        }
        if ($input_type_part instanceof TLiteralString && $input_type_part->value) {
            try {
                $function_storage = $codebase->functions->getStorage($statements_analyzer, strtolower($input_type_part->value));
                if ($expand_callable) {
                    $params = [];
                    foreach ($function_storage->params as $param) {
                        if ($param->type) {
                            $param = $param->setType(TypeExpander::expandUnion($codebase, $param->type, null, null, null, \true, \true, \false, \false, \true));
                        }
                        $params[] = $param;
                    }
                    $return_type = null;
                    if ($function_storage->return_type) {
                        $return_type = TypeExpander::expandUnion($codebase, $function_storage->return_type, null, null, null, \true, \true, \false, \false, \true);
                    }
                } else {
                    $return_type = $function_storage->return_type;
                    $params = $function_storage->params;
                }
                return new TCallable('callable', $params, $return_type, $function_storage->pure);
            } catch (UnexpectedValueException $e) {
                if (InternalCallMapHandler::inCallMap($input_type_part->value)) {
                    $args = [];
                    $nodes = new NodeDataProvider();
                    if ($container_type_part && $container_type_part->params) {
                        foreach ($container_type_part->params as $i => $param) {
                            $arg = new Arg(new Variable('_' . $i));
                            if ($param->type) {
                                $nodes->setType($arg->value, $param->type);
                            }
                            $args[] = $arg;
                        }
                    }
                    $matching_callable = InternalCallMapHandler::getCallableFromCallMapById($codebase, $input_type_part->value, $args, $nodes);
                    $must_use = \false;
                    $matching_callable = $matching_callable->setIsPure($codebase->functions->isCallMapFunctionPure($codebase, $statements_analyzer->node_data ?? null, $input_type_part->value, null, $must_use));
                    return $matching_callable;
                }
            }
        } elseif ($input_type_part instanceof TKeyedArray) {
            $method_id = self::getCallableMethodIdFromTKeyedArray($input_type_part);
            if ($method_id && $method_id !== 'not-callable') {
                try {
                    $method_storage = $codebase->methods->getStorage($method_id);
                    $method_fqcln = $method_id->fq_class_name;
                    $converted_return_type = null;
                    if ($method_storage->return_type) {
                        $converted_return_type = TypeExpander::expandUnion($codebase, $method_storage->return_type, $method_fqcln, $method_fqcln, null);
                    }
                    return new TCallable('callable', $method_storage->params, $converted_return_type, $method_storage->pure);
                } catch (UnexpectedValueException $e) {
                    // do nothing
                }
            }
        } elseif ($input_type_part instanceof TNamedObject && $input_type_part->value === 'Closure') {
            return new TCallable();
        } elseif ($input_type_part instanceof TNamedObject && $codebase->classExists($input_type_part->value)) {
            $invoke_id = new MethodIdentifier($input_type_part->value, '__invoke');
            if ($codebase->methods->methodExists($invoke_id)) {
                $declaring_method_id = $codebase->methods->getDeclaringMethodId($invoke_id);
                $template_result = null;
                if ($input_type_part instanceof Atomic\TGenericObject) {
                    $invokable_storage = $codebase->methods->getClassLikeStorageForMethod($declaring_method_id ?? $invoke_id);
                    $type_params = [];
                    foreach ($invokable_storage->template_types ?? [] as $template => $for_class) {
                        foreach ($for_class as $type) {
                            $type_params[] = new Type\Union([new TTemplateParam($template, $type, $input_type_part->value)]);
                        }
                    }
                    if (!empty($type_params)) {
                        $input_with_templates = new Atomic\TGenericObject($input_type_part->value, $type_params);
                        $template_result = new TemplateResult($invokable_storage->template_types ?? [], []);
                        TemplateStandinTypeReplacer::fillTemplateResult(new Type\Union([$input_with_templates]), $template_result, $codebase, null, new Type\Union([$input_type_part]));
                    }
                }
                if ($declaring_method_id) {
                    $method_storage = $codebase->methods->getStorage($declaring_method_id);
                    $method_fqcln = $invoke_id->fq_class_name;
                    $converted_return_type = null;
                    if ($method_storage->return_type) {
                        $converted_return_type = TypeExpander::expandUnion($codebase, $method_storage->return_type, $method_fqcln, $method_fqcln, null);
                    }
                    $callable = new TCallable('callable', $method_storage->params, $converted_return_type, $method_storage->pure);
                    if ($template_result) {
                        $callable = TemplateInferredTypeReplacer::replace(new Union([$callable]), $template_result, $codebase)->getSingleAtomic();
                    }
                    return $callable;
                }
            }
        }
        return null;
    }
    /** @return null|'not-callable'|MethodIdentifier */
    public static function getCallableMethodIdFromTKeyedArray(TKeyedArray $input_type_part, ?Codebase $codebase = null, ?string $calling_method_id = null, ?string $file_name = null)
    {
        if (!isset($input_type_part->properties[0]) || !isset($input_type_part->properties[1])) {
            return 'not-callable';
        }
        [$lhs, $rhs] = $input_type_part->properties;
        $rhs_low_info = $rhs->hasMixed() || $rhs->hasScalar();
        if ($rhs_low_info || !$rhs->isSingleStringLiteral()) {
            if (!$rhs_low_info && !$rhs->hasString()) {
                return 'not-callable';
            }
            if ($codebase && ($calling_method_id || $file_name)) {
                foreach ($lhs->getAtomicTypes() as $lhs_atomic_type) {
                    if ($lhs_atomic_type instanceof TNamedObject) {
                        $codebase->analyzer->addMixedMemberName(strtolower($lhs_atomic_type->value) . '::', $calling_method_id ?: $file_name);
                    } elseif ($lhs_atomic_type instanceof TTemplateParam) {
                        $lhs_template_type = $lhs_atomic_type->as;
                        if ($lhs_template_type->isSingle()) {
                            $lhs_template_atomic_type = $lhs_template_type->getSingleAtomic();
                            $member_id = null;
                            if ($lhs_template_atomic_type instanceof TNamedObject) {
                                $member_id = $lhs_template_atomic_type->value;
                            } elseif ($lhs_template_atomic_type instanceof TClassString) {
                                $member_id = $lhs_template_atomic_type->as;
                            }
                            if ($member_id) {
                                /** @psalm-suppress PossiblyNullArgument Psalm bug */
                                $codebase->analyzer->addMixedMemberName(strtolower($member_id) . '::', $calling_method_id ?: $file_name);
                            }
                        }
                    }
                }
            }
            return null;
        }
        $method_name = $rhs->getSingleStringLiteral()->value;
        $class_name = null;
        if ($lhs->isSingleStringLiteral()) {
            $class_name = $lhs->getSingleStringLiteral()->value;
            if ($class_name[0] === '\\') {
                $class_name = substr($class_name, 1);
            }
        } elseif ($lhs->isSingle()) {
            foreach ($lhs->getAtomicTypes() as $lhs_atomic_type) {
                if ($lhs_atomic_type instanceof TNamedObject) {
                    $class_name = $lhs_atomic_type->value;
                } elseif ($lhs_atomic_type instanceof TTemplateParam) {
                    $lhs_template_type = $lhs_atomic_type->as;
                    if ($lhs_template_type->isSingle()) {
                        $lhs_template_atomic_type = $lhs_template_type->getSingleAtomic();
                        if ($lhs_template_atomic_type instanceof TNamedObject) {
                            $class_name = $lhs_template_atomic_type->value;
                        } elseif ($lhs_template_atomic_type instanceof TClassString) {
                            $class_name = $lhs_template_atomic_type->as;
                        }
                    }
                } elseif ($lhs_atomic_type instanceof TClassString && $lhs_atomic_type->as) {
                    $class_name = $lhs_atomic_type->as;
                }
            }
        }
        if ($class_name === 'self' || $class_name === 'static' || $class_name === 'parent') {
            return null;
        }
        if (!$class_name) {
            if ($codebase && ($calling_method_id || $file_name)) {
                $codebase->analyzer->addMixedMemberName(strtolower($method_name), $calling_method_id ?: $file_name);
            }
            return null;
        }
        return new MethodIdentifier($class_name, strtolower($method_name));
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use function array_keys;
use function is_string;
/**
 * @internal
 */
class KeyedArrayComparator
{
    /**
     * @param TKeyedArray|TObjectWithProperties $input_type_part
     * @param TKeyedArray|TObjectWithProperties $container_type_part
     */
    public static function isContainedBy(Codebase $codebase, Atomic $input_type_part, Atomic $container_type_part, bool $allow_interface_equality, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result) : bool
    {
        $container_sealed = $container_type_part instanceof TKeyedArray && $container_type_part->fallback_params === null;
        if ($container_sealed && $input_type_part instanceof TKeyedArray && $input_type_part->fallback_params !== null) {
            return \false;
        }
        if ($container_type_part instanceof TKeyedArray && $container_type_part->is_list && $input_type_part instanceof TKeyedArray && !$input_type_part->is_list) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        $all_types_contain = \true;
        $input_properties = $input_type_part->properties;
        foreach ($container_type_part->properties as $key => $container_property_type) {
            if (!isset($input_properties[$key])) {
                if (!$container_property_type->possibly_undefined) {
                    $all_types_contain = \false;
                }
                continue;
            }
            if ($input_properties[$key]->possibly_undefined && !$container_property_type->possibly_undefined) {
                $all_types_contain = \false;
                continue;
            }
            $input_property_type = $input_properties[$key];
            unset($input_properties[$key]);
            $property_type_comparison = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
            if (!$input_property_type->isNever()) {
                $is_input_containedby_container = \Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_property_type, $container_property_type, $input_property_type->ignore_nullable_issues, $input_property_type->ignore_falsable_issues, $property_type_comparison, $allow_interface_equality);
                if (!$is_input_containedby_container && !$property_type_comparison->type_coerced_from_scalar) {
                    $inverse_property_type_comparison = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
                    if ($atomic_comparison_result) {
                        if (\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $container_property_type, $input_property_type, \false, \false, $inverse_property_type_comparison, $allow_interface_equality) || $inverse_property_type_comparison->type_coerced_from_scalar) {
                            $atomic_comparison_result->type_coerced = \true;
                        }
                        if ($property_type_comparison->missing_shape_fields) {
                            $atomic_comparison_result->missing_shape_fields = $property_type_comparison->missing_shape_fields;
                        }
                    }
                    $all_types_contain = \false;
                } else {
                    if (!$is_input_containedby_container) {
                        $all_types_contain = \false;
                    }
                    if ($atomic_comparison_result) {
                        $atomic_comparison_result->to_string_cast = $atomic_comparison_result->to_string_cast === \true || $property_type_comparison->to_string_cast === \true;
                    }
                }
            }
        }
        if ($container_sealed && $input_properties) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->missing_shape_fields = array_keys($input_properties);
            }
            return \false;
        }
        return $all_types_contain;
    }
    public static function isContainedByObjectWithProperties(Codebase $codebase, TNamedObject $input_type_part, TObjectWithProperties $container_type_part, bool $allow_interface_equality, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result) : bool
    {
        $all_types_contain = \true;
        foreach ($container_type_part->properties as $property_name => $container_property_type) {
            if (!is_string($property_name)) {
                continue;
            }
            if (!$codebase->classlikes->classOrInterfaceExists($input_type_part->value)) {
                $all_types_contain = \false;
                continue;
            }
            if (!$codebase->properties->propertyExists($input_type_part->value . '::$' . $property_name, \true)) {
                $all_types_contain = \false;
                continue;
            }
            $property_declaring_class = (string) $codebase->properties->getDeclaringClassForProperty($input_type_part . '::$' . $property_name, \true);
            $class_storage = $codebase->classlike_storage_provider->get($property_declaring_class);
            $input_property_storage = $class_storage->properties[$property_name];
            $input_property_type = $input_property_storage->type ?: Type::getMixed();
            $property_type_comparison = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
            if (!$input_property_type->isNever() && !\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_property_type, $container_property_type, \false, \false, $property_type_comparison, $allow_interface_equality) && !$property_type_comparison->type_coerced_from_scalar) {
                $inverse_property_type_comparison = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
                if (\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $container_property_type, $input_property_type, \false, \false, $inverse_property_type_comparison, $allow_interface_equality) || $inverse_property_type_comparison->type_coerced_from_scalar) {
                    if ($atomic_comparison_result) {
                        $atomic_comparison_result->type_coerced = \true;
                    }
                }
                $all_types_contain = \false;
            }
        }
        return $all_types_contain;
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function count;
use function current;
use function in_array;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class ObjectComparator
{
    /**
     * @param  TNamedObject|TTemplateParam|TIterable  $input_type_part
     * @param  TNamedObject|TTemplateParam|TIterable  $container_type_part
     */
    public static function isShallowlyContainedBy(Codebase $codebase, Atomic $input_type_part, Atomic $container_type_part, bool $allow_interface_equality, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result) : bool
    {
        if ($container_type_part instanceof TTemplateParam && $input_type_part instanceof TTemplateParam && $container_type_part->defining_class != $input_type_part->defining_class && 1 == count($container_type_part->as->getAtomicTypes()) && 1 == count($input_type_part->as->getAtomicTypes())) {
            $containerDefinedInFunction = strpos($container_type_part->defining_class, 'fn-') === 0;
            $inputDefinedInFunction = strpos($input_type_part->defining_class, 'fn-') === 0;
            if ($inputDefinedInFunction) {
                $separatorPos = strpos($input_type_part->defining_class, '::');
                if ($separatorPos === \false) {
                    // Is that possible ? Falling back to default definition.
                    $inputDefiningClass = $input_type_part->defining_class;
                } else {
                    $inputDefiningClass = substr($input_type_part->defining_class, 3, $separatorPos - 3);
                }
            } else {
                $inputDefiningClass = $input_type_part->defining_class;
            }
            // FIXME Missing analysis for additional cases, for example :
            // - input from a parameter in a static function that is defined in the container class
            // - input and container are both defined on function parameters
            if (!$inputDefinedInFunction && !$containerDefinedInFunction || $inputDefinedInFunction && !$containerDefinedInFunction && strtolower($inputDefiningClass) != strtolower($container_type_part->defining_class)) {
                $containerAs = current($container_type_part->as->getAtomicTypes());
                $inputAs = current($input_type_part->as->getAtomicTypes());
                if ($containerAs instanceof TNamedObject && $inputAs instanceof TNamedObject) {
                    return self::isShallowlyContainedBy($codebase, $inputAs, $containerAs, $allow_interface_equality, $atomic_comparison_result);
                } elseif ($containerAs instanceof TMixed && $inputAs instanceof TMixed) {
                    return \true;
                }
            }
        }
        $intersection_input_types = self::getIntersectionTypes($input_type_part);
        $intersection_container_types = self::getIntersectionTypes($container_type_part);
        foreach ($intersection_container_types as $intersection_container_type) {
            $container_was_static = \false;
            if ($intersection_container_type instanceof TIterable) {
                $intersection_container_type_lower = 'iterable';
            } elseif ($intersection_container_type instanceof TObjectWithProperties) {
                $intersection_container_type_lower = 'object';
            } elseif ($intersection_container_type instanceof TTemplateParam) {
                $intersection_container_type_lower = null;
            } else {
                $container_was_static = $intersection_container_type->is_static;
                $intersection_container_type_lower = strtolower($codebase->classlikes->getUnAliasedName($intersection_container_type->value));
            }
            $any_inputs_contained = \false;
            $container_type_is_interface = $intersection_container_type_lower && $codebase->interfaceExists($intersection_container_type_lower);
            foreach ($intersection_input_types as $input_type_key => $intersection_input_type) {
                if ($allow_interface_equality && $container_type_is_interface && !isset($intersection_container_types[$input_type_key])) {
                    $any_inputs_contained = \true;
                } elseif (self::isIntersectionShallowlyContainedBy($codebase, $intersection_input_type, $intersection_container_type, $intersection_container_type_lower, $container_was_static, $allow_interface_equality, $atomic_comparison_result)) {
                    $any_inputs_contained = \true;
                }
            }
            if (!$any_inputs_contained) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @param  TNamedObject|TTemplateParam|TIterable  $type_part
     * @return array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties>
     */
    private static function getIntersectionTypes(Atomic $type_part) : array
    {
        if (!$type_part->extra_types) {
            if ($type_part instanceof TTemplateParam) {
                $intersection_types = [];
                foreach ($type_part->as->getAtomicTypes() as $as_atomic_type) {
                    // T1 as T2 as object becomes (T1 as object) & (T2 as object)
                    if ($as_atomic_type instanceof TTemplateParam) {
                        $intersection_types += self::getIntersectionTypes($as_atomic_type);
                        $type_part = $type_part->replaceAs($as_atomic_type->as);
                        $intersection_types[$type_part->getKey()] = $type_part;
                        return $intersection_types;
                    }
                }
            }
            return [$type_part->getKey() => $type_part];
        }
        $extra_types = $type_part->extra_types;
        $type_part = $type_part->setIntersectionTypes([]);
        $extra_types[$type_part->getKey()] = $type_part;
        return $extra_types;
    }
    /**
     * @param  TNamedObject|TTemplateParam|TIterable|TObjectWithProperties  $intersection_input_type
     * @param  TNamedObject|TTemplateParam|TIterable|TObjectWithProperties  $intersection_container_type
     */
    private static function isIntersectionShallowlyContainedBy(Codebase $codebase, Atomic $intersection_input_type, Atomic $intersection_container_type, ?string $intersection_container_type_lower, bool $container_was_static, bool $allow_interface_equality, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result) : bool
    {
        if ($intersection_container_type instanceof TTemplateParam && $intersection_input_type instanceof TTemplateParam) {
            if (!$allow_interface_equality) {
                if (strpos($intersection_container_type->defining_class, 'fn-') === 0 || strpos($intersection_input_type->defining_class, 'fn-') === 0) {
                    if (strpos($intersection_input_type->defining_class, 'fn-') === 0 && strpos($intersection_container_type->defining_class, 'fn-') === 0 && $intersection_input_type->defining_class !== $intersection_container_type->defining_class) {
                        return \true;
                    }
                    foreach ($intersection_input_type->as->getAtomicTypes() as $input_as_atomic) {
                        if ($input_as_atomic->equals($intersection_container_type, \false)) {
                            return \true;
                        }
                    }
                }
            }
            if ($intersection_container_type->param_name === $intersection_input_type->param_name && $intersection_container_type->defining_class === $intersection_input_type->defining_class) {
                return \true;
            }
            if ($intersection_container_type->param_name !== $intersection_input_type->param_name || $intersection_container_type->defining_class !== $intersection_input_type->defining_class && strpos($intersection_input_type->defining_class, 'fn-') !== 0 && strpos($intersection_container_type->defining_class, 'fn-') !== 0) {
                if (strpos($intersection_input_type->defining_class, 'fn-') === 0 || strpos($intersection_container_type->defining_class, 'fn-') === 0) {
                    return \false;
                }
                $input_class_storage = $codebase->classlike_storage_provider->get($intersection_input_type->defining_class);
                if (isset($input_class_storage->template_extended_params[$intersection_container_type->defining_class][$intersection_container_type->param_name])) {
                    return \true;
                }
            }
            return \false;
        }
        if ($intersection_container_type instanceof TTemplateParam || $intersection_container_type_lower === null) {
            return \false;
        }
        if ($intersection_input_type instanceof TTemplateParam) {
            if ($intersection_container_type instanceof TNamedObject && $intersection_container_type->is_static) {
                // this is extra check is redundant since we're comparing to a template as type
                $intersection_container_type = new TNamedObject($intersection_container_type->value, \false, $intersection_container_type->definite_class, $intersection_container_type->extra_types);
            }
            return \Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $intersection_input_type->as, new Union([$intersection_container_type]), \false, \false, $atomic_comparison_result, $allow_interface_equality);
        }
        $input_was_static = \false;
        if ($intersection_input_type instanceof TIterable) {
            $intersection_input_type_lower = 'iterable';
        } elseif ($intersection_input_type instanceof TObjectWithProperties) {
            $intersection_input_type_lower = 'object';
        } else {
            $input_was_static = $intersection_input_type->is_static;
            $intersection_input_type_lower = strtolower($codebase->classlikes->getUnAliasedName($intersection_input_type->value));
        }
        if ($intersection_container_type_lower === $intersection_input_type_lower) {
            if ($container_was_static && !$input_was_static) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
                return \false;
            }
            return \true;
        }
        if ($intersection_input_type_lower === 'generator' && in_array($intersection_container_type_lower, ['iterator', 'traversable', 'iterable'], \true)) {
            return \true;
        }
        if ($intersection_container_type_lower === 'iterable') {
            if ($intersection_input_type_lower === 'traversable' || $codebase->classlikes->classExists($intersection_input_type_lower) && $codebase->classlikes->classImplements($intersection_input_type_lower, 'Traversable') || $codebase->classlikes->interfaceExists($intersection_input_type_lower) && $codebase->classlikes->interfaceExtends($intersection_input_type_lower, 'Traversable')) {
                return \true;
            }
        }
        if ($intersection_input_type_lower === 'traversable' && $intersection_container_type_lower === 'iterable') {
            return \true;
        }
        $input_type_is_interface = $codebase->interfaceExists($intersection_input_type_lower);
        $container_type_is_interface = $codebase->interfaceExists($intersection_container_type_lower);
        if ($allow_interface_equality && $container_type_is_interface && $input_type_is_interface) {
            return \true;
        }
        if (($codebase->classExists($intersection_input_type_lower) || $codebase->classlikes->enumExists($intersection_input_type_lower)) && $codebase->classOrInterfaceExists($intersection_container_type_lower) && $codebase->classExtendsOrImplements($intersection_input_type_lower, $intersection_container_type_lower)) {
            if ($container_was_static && !$input_was_static) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
                return \false;
            }
            return \true;
        }
        if ($input_type_is_interface && $codebase->interfaceExtends($intersection_input_type_lower, $intersection_container_type_lower)) {
            return \true;
        }
        if (ExpressionAnalyzer::isMock($intersection_input_type_lower)) {
            return \true;
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParamClass;
use function get_class;
/**
 * @internal
 */
class ClassLikeStringComparator
{
    /**
     * @param TClassString|TLiteralClassString $input_type_part
     * @param TClassString|TLiteralClassString $container_type_part
     */
    public static function isContainedBy(Codebase $codebase, Scalar $input_type_part, Scalar $container_type_part, bool $allow_interface_equality, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result = null) : bool
    {
        if ($container_type_part instanceof TLiteralClassString && $input_type_part instanceof TLiteralClassString) {
            return $container_type_part->value === $input_type_part->value;
        }
        if ($container_type_part instanceof TTemplateParamClass && get_class($input_type_part) === TClassString::class) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TClassString && $container_type_part->as === 'object' && !$container_type_part->as_type) {
            return \true;
        }
        if ($input_type_part instanceof TClassString && $input_type_part->as === 'object' && !$input_type_part->as_type) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_scalar = \true;
            }
            return \false;
        }
        $fake_container_object = $container_type_part instanceof TClassString && $container_type_part->as_type ? $container_type_part->as_type : new TNamedObject($container_type_part instanceof TClassString ? $container_type_part->as : $container_type_part->value);
        $fake_input_object = $input_type_part instanceof TClassString && $input_type_part->as_type ? $input_type_part->as_type : new TNamedObject($input_type_part instanceof TClassString ? $input_type_part->as : $input_type_part->value);
        return \Psalm\Internal\Type\Comparator\AtomicTypeComparator::isContainedBy($codebase, $fake_input_object, $fake_container_object, $allow_interface_equality, \false, $atomic_comparison_result);
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TNamedObject;
/**
 * @internal
 */
class GenericTypeComparator
{
    /**
     * @param TGenericObject|TIterable $container_type_part
     */
    public static function isContainedBy(Codebase $codebase, Atomic $input_type_part, Atomic $container_type_part, bool $allow_interface_equality = \false, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result = null) : bool
    {
        $all_types_contain = \true;
        $container_was_iterable = \false;
        if ($container_type_part instanceof TIterable && !$container_type_part->extra_types && !$input_type_part instanceof TIterable) {
            $container_type_part = new TGenericObject('Traversable', $container_type_part->type_params);
            $container_was_iterable = \true;
        }
        if (!$input_type_part instanceof TNamedObject && !$input_type_part instanceof TIterable) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_mixed = \true;
            }
            return \false;
        }
        $container_type_params_covariant = [];
        $input_type_params = TemplateStandinTypeReplacer::getMappedGenericTypeParams($codebase, $input_type_part, $container_type_part, $container_type_params_covariant);
        $atomic_comparison_result_type_params = null;
        if ($atomic_comparison_result) {
            if (!$atomic_comparison_result->replacement_atomic_type) {
                $atomic_comparison_result->replacement_atomic_type = $input_type_part;
            }
            if ($atomic_comparison_result->replacement_atomic_type instanceof TGenericObject) {
                $atomic_comparison_result_type_params = $atomic_comparison_result->replacement_atomic_type->type_params;
            }
        }
        foreach ($input_type_params as $i => $input_param) {
            if (!isset($container_type_part->type_params[$i])) {
                break;
            }
            $container_param = $container_type_part->type_params[$i];
            if ($input_param->isNever()) {
                if ($atomic_comparison_result_type_params !== null) {
                    $atomic_comparison_result_type_params[$i] = $container_param;
                }
                continue;
            }
            $param_comparison_result = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
            if (!\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_param, $container_param, $input_param->ignore_nullable_issues, $input_param->ignore_falsable_issues, $param_comparison_result, $allow_interface_equality)) {
                if ($input_type_part->value === 'Generator' && $i === 2 && $param_comparison_result->type_coerced_from_mixed) {
                    continue;
                }
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = $param_comparison_result->type_coerced === \true && $atomic_comparison_result->type_coerced !== \false;
                    $atomic_comparison_result->type_coerced_from_mixed = $param_comparison_result->type_coerced_from_mixed === \true && $atomic_comparison_result->type_coerced_from_mixed !== \false;
                    $atomic_comparison_result->type_coerced_from_as_mixed = !$container_was_iterable && $param_comparison_result->type_coerced_from_as_mixed === \true && $atomic_comparison_result->type_coerced_from_as_mixed !== \false;
                    $atomic_comparison_result->to_string_cast = $param_comparison_result->to_string_cast === \true && $atomic_comparison_result->to_string_cast !== \false;
                    $atomic_comparison_result->type_coerced_from_scalar = $param_comparison_result->type_coerced_from_scalar === \true && $atomic_comparison_result->type_coerced_from_scalar !== \false;
                    $atomic_comparison_result->scalar_type_match_found = $param_comparison_result->scalar_type_match_found === \true && $atomic_comparison_result->scalar_type_match_found !== \false;
                }
                // if the container was an iterable then there was no mapping
                // from a template type
                if ($container_was_iterable || !$param_comparison_result->type_coerced_from_as_mixed) {
                    $all_types_contain = \false;
                }
            } elseif (!$input_type_part instanceof TIterable && !$container_type_part instanceof TIterable && !$container_param->hasTemplate() && !$input_param->hasTemplate()) {
                if ($input_param->containsAnyLiteral()) {
                    if ($atomic_comparison_result_type_params !== null) {
                        $atomic_comparison_result_type_params[$i] = $container_param;
                    }
                } else {
                    if (!($container_type_params_covariant[$i] ?? \false) && !$container_param->had_template) {
                        // Make sure types are basically the same
                        if (!\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $container_param, $input_param, $container_param->ignore_nullable_issues, $container_param->ignore_falsable_issues, $param_comparison_result, $allow_interface_equality) || $param_comparison_result->type_coerced) {
                            if ($container_param->hasStaticObject() && $input_param->isStaticObject()) {
                                // do nothing
                            } else {
                                $all_types_contain = \false;
                                if ($atomic_comparison_result) {
                                    $atomic_comparison_result->type_coerced = \false;
                                }
                            }
                        }
                    }
                }
            }
        }
        if ($atomic_comparison_result && $atomic_comparison_result->replacement_atomic_type instanceof TGenericObject && $atomic_comparison_result_type_params) {
            /** @psalm-suppress ArgumentTypeCoercion Psalm bug */
            $atomic_comparison_result->replacement_atomic_type = $atomic_comparison_result->replacement_atomic_type->setTypeParams($atomic_comparison_result_type_params);
        }
        if ($all_types_contain) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->to_string_cast = \false;
            }
            return \true;
        }
        return \false;
    }
}
<?php

namespace Psalm\Internal\Type\Comparator;

use Psalm\Codebase;
use Psalm\Internal\MethodIdentifier;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableKeyedArray;
use Psalm\Type\Atomic\TCallableObject;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateKeyOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateValueOf;
use Psalm\Type\Atomic\TValueOf;
use function array_merge;
use function array_values;
use function assert;
use function count;
use function get_class;
use function strtolower;
/**
 * @internal
 */
class AtomicTypeComparator
{
    /**
     * Does the input param atomic type match the given param atomic type
     */
    public static function isContainedBy(Codebase $codebase, Atomic $input_type_part, Atomic $container_type_part, bool $allow_interface_equality = \false, bool $allow_float_int_equality = \true, ?\Psalm\Internal\Type\Comparator\TypeComparisonResult $atomic_comparison_result = null) : bool
    {
        if ($input_type_part instanceof TList) {
            $input_type_part = $input_type_part->getKeyedArray();
        }
        if ($container_type_part instanceof TList) {
            $container_type_part = $container_type_part->getKeyedArray();
        }
        if (($container_type_part instanceof TTemplateParam || $container_type_part instanceof TNamedObject && $container_type_part->extra_types) && ($input_type_part instanceof TTemplateParam || $input_type_part instanceof TNamedObject && $input_type_part->extra_types)) {
            return \Psalm\Internal\Type\Comparator\ObjectComparator::isShallowlyContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
        }
        if ($container_type_part instanceof TMixed || $container_type_part instanceof TTemplateParam && $container_type_part->as->isMixed() && !$container_type_part->extra_types && $input_type_part instanceof TMixed) {
            if (get_class($container_type_part) === TEmptyMixed::class && get_class($input_type_part) === TMixed::class) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                    $atomic_comparison_result->type_coerced_from_mixed = \true;
                }
                return \false;
            }
            return \true;
        }
        if ($input_type_part instanceof TNever) {
            return \true;
        }
        if ($input_type_part instanceof TMixed || $input_type_part instanceof TTemplateParam && $input_type_part->as->isMixed() && !$input_type_part->extra_types) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
                $atomic_comparison_result->type_coerced_from_mixed = \true;
            }
            return \false;
        }
        if ($input_type_part instanceof TNull) {
            if ($container_type_part instanceof TNull) {
                return \true;
            }
            if ($container_type_part instanceof TTemplateParam && ($container_type_part->as->isNullable() || $container_type_part->as->isMixed())) {
                return \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TNull) {
            return \false;
        }
        if ($input_type_part instanceof Scalar && $container_type_part instanceof Scalar) {
            return \Psalm\Internal\Type\Comparator\ScalarTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result);
        }
        if ($input_type_part instanceof TCallableKeyedArray && $container_type_part instanceof TArray) {
            return \Psalm\Internal\Type\Comparator\ArrayTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
        }
        if ($container_type_part instanceof TCallable && $input_type_part instanceof TCallable || $container_type_part instanceof TClosure && $input_type_part instanceof TClosure) {
            return \Psalm\Internal\Type\Comparator\CallableTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $atomic_comparison_result);
        }
        if ($container_type_part instanceof TClosure) {
            if ($input_type_part instanceof TCallable) {
                if (\Psalm\Internal\Type\Comparator\CallableTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $atomic_comparison_result) === \false) {
                    return \false;
                }
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
            }
            return \false;
        }
        if ($container_type_part instanceof TCallable && $input_type_part instanceof TClosure) {
            return \Psalm\Internal\Type\Comparator\CallableTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $atomic_comparison_result);
        }
        if ($input_type_part instanceof TNamedObject && $input_type_part->value === 'Closure' && $container_type_part instanceof TCallable) {
            return \true;
        }
        if ($input_type_part instanceof TObject && $container_type_part instanceof TCallable) {
            return \true;
        }
        if ($input_type_part instanceof TCallableObject && $container_type_part instanceof TObject) {
            return \true;
        }
        if ($container_type_part instanceof TObjectWithProperties && $container_type_part->is_stringable_object_only) {
            if ($input_type_part instanceof TObjectWithProperties && $input_type_part->is_stringable_object_only || $input_type_part instanceof TNamedObject && $codebase->methodExists(new MethodIdentifier($input_type_part->value, '__tostring'))) {
                return \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TNamedObject && $container_type_part->value === 'Stringable' && $codebase->analysis_php_version_id >= 80000 && $input_type_part instanceof TObjectWithProperties && $input_type_part->is_stringable_object_only) {
            return \true;
        }
        if ($container_type_part instanceof TKeyedArray && $input_type_part instanceof TKeyedArray || $container_type_part instanceof TObjectWithProperties && $input_type_part instanceof TObjectWithProperties) {
            return \Psalm\Internal\Type\Comparator\KeyedArrayComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
        }
        if ($container_type_part instanceof TObjectWithProperties && $input_type_part instanceof TObject && !$input_type_part instanceof TObjectWithProperties && !$input_type_part instanceof TCallableObject) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if (($input_type_part instanceof TArray || $input_type_part instanceof TKeyedArray || $input_type_part instanceof TClassStringMap) && ($container_type_part instanceof TArray || $container_type_part instanceof TKeyedArray || $container_type_part instanceof TClassStringMap)) {
            return \Psalm\Internal\Type\Comparator\ArrayTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
        }
        if (get_class($container_type_part) === TNamedObject::class && $input_type_part instanceof TEnumCase && $input_type_part->value === $container_type_part->value) {
            return \true;
        }
        if (get_class($input_type_part) === TNamedObject::class && $container_type_part instanceof TEnumCase && $input_type_part->value === $container_type_part->value) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if (($input_type_part instanceof TNamedObject || $input_type_part instanceof TTemplateParam && $input_type_part->as->hasObjectType() || $input_type_part instanceof TIterable) && ($container_type_part instanceof TNamedObject || $container_type_part instanceof TTemplateParam && $container_type_part->isObjectType() || $container_type_part instanceof TIterable) && \Psalm\Internal\Type\Comparator\ObjectComparator::isShallowlyContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result)) {
            if ($container_type_part instanceof TGenericObject || $container_type_part instanceof TIterable) {
                return \Psalm\Internal\Type\Comparator\GenericTypeComparator::isContainedBy($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
            }
            if ($container_type_part instanceof TNamedObject && $input_type_part instanceof TNamedObject && $container_type_part->is_static && !$input_type_part->is_static) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->type_coerced = \true;
                }
                return \false;
            }
            if ($atomic_comparison_result) {
                $atomic_comparison_result->to_string_cast = \false;
            }
            return \true;
        }
        if (get_class($input_type_part) === TObject::class && get_class($container_type_part) === TObject::class) {
            return \true;
        }
        if ($container_type_part instanceof TTemplateKeyOf) {
            if (!$input_type_part instanceof TTemplateKeyOf) {
                return \false;
            }
            return \Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_type_part->as, $container_type_part->as);
        }
        if ($input_type_part instanceof TTemplateKeyOf) {
            $array_key_type = TKeyOf::getArrayKeyType($input_type_part->as);
            if ($array_key_type === null) {
                return \false;
            }
            foreach ($array_key_type->getAtomicTypes() as $array_key_atomic) {
                if (!self::isContainedBy($codebase, $array_key_atomic, $container_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result)) {
                    return \false;
                }
            }
            return \true;
        }
        if ($container_type_part instanceof TTemplateValueOf) {
            if (!$input_type_part instanceof TTemplateValueOf) {
                return \false;
            }
            return \Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_type_part->as, $container_type_part->as);
        }
        if ($input_type_part instanceof TTemplateValueOf) {
            $array_value_type = TValueOf::getValueType($input_type_part->as, $codebase);
            if ($array_value_type === null) {
                return \false;
            }
            foreach ($array_value_type->getAtomicTypes() as $array_value_atomic) {
                if (!self::isContainedBy($codebase, $array_value_atomic, $container_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result)) {
                    return \false;
                }
            }
            return \true;
        }
        if ($container_type_part instanceof TTemplateParam && $input_type_part instanceof TTemplateParam) {
            return \Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_type_part->as, $container_type_part->as, \false, \false, $atomic_comparison_result, $allow_interface_equality);
        }
        if ($container_type_part instanceof TTemplateParam) {
            foreach ($container_type_part->as->getAtomicTypes() as $container_as_type_part) {
                if (self::isContainedBy($codebase, $input_type_part, $container_as_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result)) {
                    if ($allow_interface_equality) {
                        return \true;
                    }
                }
            }
            return \false;
        }
        if ($container_type_part instanceof TConditional) {
            $atomic_types = array_merge(array_values($container_type_part->if_type->getAtomicTypes()), array_values($container_type_part->else_type->getAtomicTypes()));
            foreach ($atomic_types as $container_as_type_part) {
                if (self::isContainedBy($codebase, $input_type_part, $container_as_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result)) {
                    return \true;
                }
            }
            return \false;
        }
        if ($input_type_part instanceof TTemplateParam) {
            if ($input_type_part->extra_types) {
                foreach ($input_type_part->extra_types as $extra_type) {
                    if (self::isContainedBy($codebase, $extra_type, $container_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result)) {
                        return \true;
                    }
                }
            }
            foreach ($input_type_part->as->getAtomicTypes() as $input_as_type_part) {
                if (self::isContainedBy($codebase, $input_as_type_part, $container_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result)) {
                    return \true;
                }
            }
            return \false;
        }
        if ($input_type_part instanceof TConditional) {
            $input_atomic_types = array_merge(array_values($input_type_part->if_type->getAtomicTypes()), array_values($input_type_part->else_type->getAtomicTypes()));
            foreach ($input_atomic_types as $input_as_type_part) {
                if (self::isContainedBy($codebase, $input_as_type_part, $container_type_part, $allow_interface_equality, $allow_float_int_equality, $atomic_comparison_result)) {
                    return \true;
                }
            }
            return \false;
        }
        if ($input_type_part instanceof TNamedObject && $input_type_part->value === 'static' && $container_type_part instanceof TNamedObject && strtolower($container_type_part->value) === 'self') {
            return \true;
        }
        if ($container_type_part instanceof TIterable) {
            if ($input_type_part instanceof TArray || $input_type_part instanceof TKeyedArray) {
                if ($input_type_part instanceof TKeyedArray) {
                    $input_type_part = $input_type_part->getGenericArrayType();
                }
                $all_types_contain = \true;
                foreach ($input_type_part->type_params as $i => $input_param) {
                    $container_param_offset = $i - (2 - count($container_type_part->type_params));
                    $container_param = $container_type_part->type_params[$container_param_offset];
                    if ($i === 0 && $input_param->hasMixed() && $container_param->hasString() && $container_param->hasInt()) {
                        continue;
                    }
                    $array_comparison_result = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
                    if (!$input_param->isNever()) {
                        if (!\Psalm\Internal\Type\Comparator\UnionTypeComparator::isContainedBy($codebase, $input_param, $container_param, $input_param->ignore_nullable_issues, $input_param->ignore_falsable_issues, $array_comparison_result, $allow_interface_equality) && !$array_comparison_result->type_coerced_from_scalar) {
                            if ($atomic_comparison_result && $array_comparison_result->type_coerced_from_mixed) {
                                $atomic_comparison_result->type_coerced_from_mixed = \true;
                            }
                            $all_types_contain = \false;
                        } else {
                            if ($atomic_comparison_result) {
                                $atomic_comparison_result->to_string_cast = $atomic_comparison_result->to_string_cast === \true || $array_comparison_result->to_string_cast === \true;
                            }
                        }
                    }
                }
                return $all_types_contain;
            }
            if ($input_type_part->hasTraversableInterface($codebase)) {
                return \true;
            }
        }
        if ($container_type_part instanceof TString || $container_type_part instanceof TScalar) {
            if ($input_type_part instanceof TNamedObject) {
                // check whether the object has a __toString method
                if ($codebase->classOrInterfaceExists($input_type_part->value)) {
                    if ($codebase->analysis_php_version_id >= 80000 && ($input_type_part->value === 'Stringable' || $codebase->classlikes->classExists($input_type_part->value) && $codebase->classlikes->classImplements($input_type_part->value, 'Stringable') || $codebase->classlikes->interfaceExtends($input_type_part->value, 'Stringable'))) {
                        if ($atomic_comparison_result) {
                            $atomic_comparison_result->to_string_cast = \true;
                        }
                        return \true;
                    }
                    if ($codebase->methods->methodExists(new MethodIdentifier($input_type_part->value, '__tostring'))) {
                        if ($atomic_comparison_result) {
                            $atomic_comparison_result->to_string_cast = \true;
                        }
                        return \true;
                    }
                }
                // PHP 5.6 doesn't support this natively, so this introduces a bug *just* when checking PHP 5.6 code
                if ($input_type_part->value === 'ReflectionType') {
                    if ($atomic_comparison_result) {
                        $atomic_comparison_result->to_string_cast = \true;
                    }
                    return \true;
                }
            } elseif ($input_type_part instanceof TObjectWithProperties && isset($input_type_part->methods['__tostring'])) {
                if ($atomic_comparison_result) {
                    $atomic_comparison_result->to_string_cast = \true;
                }
                return \true;
            }
        }
        if ($container_type_part instanceof TCallable && ($input_type_part instanceof TLiteralString || $input_type_part instanceof TCallableString || $input_type_part instanceof TArray || $input_type_part instanceof TKeyedArray || $input_type_part instanceof TNamedObject && $codebase->classOrInterfaceExists($input_type_part->value) && $codebase->methodExists($input_type_part->value . '::__invoke'))) {
            return \Psalm\Internal\Type\Comparator\CallableTypeComparator::isNotExplicitlyCallableTypeCallable($codebase, $input_type_part, $container_type_part, $atomic_comparison_result);
        }
        if ($container_type_part instanceof TObject && $input_type_part instanceof TNamedObject) {
            if ($container_type_part instanceof TObjectWithProperties && $input_type_part->value !== 'stdClass') {
                return \Psalm\Internal\Type\Comparator\KeyedArrayComparator::isContainedByObjectWithProperties($codebase, $input_type_part, $container_type_part, $allow_interface_equality, $atomic_comparison_result);
            }
            return \true;
        }
        if ($container_type_part instanceof TNamedObject && $input_type_part instanceof TNamedObject && $container_type_part->is_static && !$input_type_part->is_static) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($input_type_part instanceof TObject && $container_type_part instanceof TNamedObject) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        if ($container_type_part instanceof TNamedObject && $input_type_part instanceof TNamedObject && $codebase->classOrInterfaceOrEnumExists($input_type_part->value) && ($codebase->classExists($container_type_part->value) && $codebase->classExtendsOrImplements($container_type_part->value, $input_type_part->value) || $codebase->interfaceExists($container_type_part->value) && $codebase->interfaceExtends($container_type_part->value, $input_type_part->value))) {
            if ($atomic_comparison_result) {
                $atomic_comparison_result->type_coerced = \true;
            }
            return \false;
        }
        return $input_type_part->getKey() === $container_type_part->getKey();
    }
    /**
     * @psalm-assert-if-true TKeyedArray $array
     */
    public static function isLegacyTListLike(Atomic $array) : bool
    {
        return $array instanceof TKeyedArray && $array->is_list && $array->fallback_params && count($array->properties) === 1 && $array->properties[0]->possibly_undefined && $array->properties[0]->equals($array->fallback_params[1], \true, \true, \false);
    }
    /**
     * @psalm-assert-if-true TKeyedArray $array
     */
    public static function isLegacyTNonEmptyListLike(Atomic $array) : bool
    {
        return $array instanceof TKeyedArray && $array->is_list && $array->fallback_params && count($array->properties) === 1 && !$array->properties[0]->possibly_undefined && $array->properties[0]->equals($array->fallback_params[1]);
    }
    /**
     * Does the input param atomic type match the given param atomic type
     */
    public static function canBeIdentical(Codebase $codebase, Atomic $type1_part, Atomic $type2_part, bool $allow_interface_equality = \true) : bool
    {
        if ($type1_part instanceof TList) {
            $type1_part = $type1_part->getKeyedArray();
        }
        if ($type2_part instanceof TList) {
            $type2_part = $type2_part->getKeyedArray();
        }
        if (self::isLegacyTListLike($type1_part) && self::isLegacyTNonEmptyListLike($type2_part) || self::isLegacyTListLike($type2_part) && self::isLegacyTNonEmptyListLike($type1_part)) {
            assert($type1_part->fallback_params !== null);
            assert($type2_part->fallback_params !== null);
            return \Psalm\Internal\Type\Comparator\UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $type1_part->fallback_params[1], $type2_part->fallback_params[1]);
        }
        if (get_class($type1_part) === TArray::class && $type2_part instanceof TNonEmptyArray || get_class($type2_part) === TArray::class && $type1_part instanceof TNonEmptyArray) {
            return \Psalm\Internal\Type\Comparator\UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $type1_part->type_params[0], $type2_part->type_params[0]) && \Psalm\Internal\Type\Comparator\UnionTypeComparator::canExpressionTypesBeIdentical($codebase, $type1_part->type_params[1], $type2_part->type_params[1]);
        }
        $first_comparison_result = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
        $second_comparison_result = new \Psalm\Internal\Type\Comparator\TypeComparisonResult();
        return self::isContainedBy($codebase, $type1_part, $type2_part, $allow_interface_equality, \false, $first_comparison_result) && !$first_comparison_result->to_string_cast || self::isContainedBy($codebase, $type2_part, $type1_part, $allow_interface_equality, \false, $second_comparison_result) && !$second_comparison_result->to_string_cast || $first_comparison_result->type_coerced && $second_comparison_result->type_coerced;
    }
}
<?php

namespace Psalm\Internal\Type;

use InvalidArgumentException;
use Psalm\Codebase;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TPropertiesOf;
use Psalm\Type\Atomic\TTemplateIndexedAccess;
use Psalm\Type\Atomic\TTemplateKeyOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTemplatePropertiesOf;
use Psalm\Type\Atomic\TTemplateValueOf;
use Psalm\Type\Atomic\TValueOf;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_merge;
use function array_shift;
use function array_values;
use function strpos;
/**
 * @internal
 */
class TemplateInferredTypeReplacer
{
    /**
     * This replaces template types in unions with the inferred types they should be
     *
     * @psalm-external-mutation-free
     */
    public static function replace(Union $union, \Psalm\Internal\Type\TemplateResult $template_result, ?Codebase $codebase) : Union
    {
        $new_types = [];
        $is_mixed = \false;
        $inferred_lower_bounds = $template_result->lower_bounds ?: [];
        $types = [];
        foreach ($union->getAtomicTypes() as $key => $atomic_type) {
            $should_set = \true;
            $atomic_type = $atomic_type->replaceTemplateTypesWithArgTypes($template_result, $codebase);
            if ($atomic_type instanceof TTemplateParam) {
                $template_type = self::replaceTemplateParam($codebase, $atomic_type, $inferred_lower_bounds, $key);
                if ($template_type) {
                    $should_set = \false;
                    foreach ($template_type->getAtomicTypes() as $template_type_part) {
                        if ($template_type_part instanceof TMixed) {
                            $is_mixed = \true;
                        }
                        $new_types[] = $template_type_part;
                    }
                }
            } elseif ($atomic_type instanceof TTemplateParamClass) {
                $template_type = isset($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class]) ? \Psalm\Internal\Type\TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class], $codebase) : null;
                $class_template_type = null;
                if ($template_type) {
                    foreach ($template_type->getAtomicTypes() as $template_type_part) {
                        if ($template_type_part instanceof TMixed || $template_type_part instanceof TObject) {
                            $class_template_type = new TClassString();
                        } elseif ($template_type_part instanceof TNamedObject) {
                            $class_template_type = new TClassString($template_type_part->value, $template_type_part);
                        } elseif ($template_type_part instanceof TTemplateParam) {
                            $first_atomic_type = $template_type_part->as->getSingleAtomic();
                            $class_template_type = new TTemplateParamClass($template_type_part->param_name, $template_type_part->as->getId(), $first_atomic_type instanceof TNamedObject ? $first_atomic_type : null, $template_type_part->defining_class);
                        }
                    }
                }
                if ($class_template_type) {
                    $should_set = \false;
                    $new_types[] = $class_template_type;
                }
            } elseif ($atomic_type instanceof TTemplateIndexedAccess) {
                $should_set = \false;
                $template_type = null;
                if (isset($inferred_lower_bounds[$atomic_type->array_param_name][$atomic_type->defining_class]) && !empty($inferred_lower_bounds[$atomic_type->offset_param_name])) {
                    $array_template_type = \Psalm\Internal\Type\TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($inferred_lower_bounds[$atomic_type->array_param_name][$atomic_type->defining_class], $codebase);
                    $offset_template_type = \Psalm\Internal\Type\TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds(array_values($inferred_lower_bounds[$atomic_type->offset_param_name])[0], $codebase);
                    if ($array_template_type->isSingle() && $offset_template_type->isSingle() && !$array_template_type->isMixed() && !$offset_template_type->isMixed()) {
                        $array_template_type = $array_template_type->getSingleAtomic();
                        $offset_template_type = $offset_template_type->getSingleAtomic();
                        if ($array_template_type instanceof TKeyedArray && ($offset_template_type instanceof TLiteralString || $offset_template_type instanceof TLiteralInt) && isset($array_template_type->properties[$offset_template_type->value])) {
                            $template_type = $array_template_type->properties[$offset_template_type->value];
                        }
                    }
                }
                if ($template_type) {
                    foreach ($template_type->getAtomicTypes() as $template_type_part) {
                        if ($template_type_part instanceof TMixed) {
                            $is_mixed = \true;
                        }
                        $new_types[] = $template_type_part;
                    }
                } else {
                    $new_types[] = new TMixed();
                }
            } elseif ($atomic_type instanceof TTemplateKeyOf || $atomic_type instanceof TTemplateValueOf) {
                $new_type = self::replaceTemplateKeyOfValueOf($codebase, $atomic_type, $inferred_lower_bounds);
                if ($new_type) {
                    $should_set = \false;
                    $new_types[] = $new_type;
                }
            } elseif ($atomic_type instanceof TTemplatePropertiesOf) {
                $new_type = self::replaceTemplatePropertiesOf($codebase, $atomic_type, $inferred_lower_bounds);
                if ($new_type) {
                    $should_set = \false;
                    $new_types[] = $new_type;
                }
            } elseif ($atomic_type instanceof TConditional && $codebase) {
                $class_template_type = self::replaceConditional($template_result, $codebase, $atomic_type, $inferred_lower_bounds);
                $should_set = \false;
                foreach ($class_template_type->getAtomicTypes() as $class_template_atomic_type) {
                    $new_types[] = $class_template_atomic_type;
                }
            }
            if ($should_set) {
                $types[] = $atomic_type;
            }
        }
        if ($is_mixed) {
            if (!$new_types) {
                throw new UnexpectedValueException('This array should be full');
            }
            return $union->getBuilder()->setTypes(\Psalm\Internal\Type\TypeCombiner::combine($new_types, $codebase)->getAtomicTypes())->freeze();
        }
        $atomic_types = array_merge($types, $new_types);
        if (!$atomic_types) {
            throw new UnexpectedValueException('This array should be full');
        }
        return $union->getBuilder()->setTypes(\Psalm\Internal\Type\TypeCombiner::combine($atomic_types, $codebase)->getAtomicTypes())->freeze();
    }
    /**
     * @param array<string, array<string, non-empty-list<TemplateBound>>> $inferred_lower_bounds
     */
    private static function replaceTemplateParam(?Codebase $codebase, TTemplateParam $atomic_type, array $inferred_lower_bounds, string $key) : ?Union
    {
        $template_type = null;
        $traversed_type = \Psalm\Internal\Type\TemplateStandinTypeReplacer::getRootTemplateType($inferred_lower_bounds, $atomic_type->param_name, $atomic_type->defining_class, [], $codebase);
        if ($traversed_type) {
            $template_type = $traversed_type;
            if ($template_type->isMixed() && !$atomic_type->as->isMixed()) {
                $template_type = $atomic_type->as;
            }
            if ($atomic_type->extra_types) {
                $types = [];
                foreach ($template_type->getAtomicTypes() as $atomic_template_type) {
                    if ($atomic_template_type instanceof TNamedObject || $atomic_template_type instanceof TTemplateParam || $atomic_template_type instanceof TIterable || $atomic_template_type instanceof TObjectWithProperties) {
                        $types[] = $atomic_template_type->setIntersectionTypes(array_merge($atomic_type->extra_types, $atomic_template_type->extra_types));
                    } elseif ($atomic_template_type instanceof TObject) {
                        $first_atomic_type = array_shift($atomic_type->extra_types);
                        if ($atomic_type->extra_types) {
                            $first_atomic_type = $first_atomic_type->setIntersectionTypes($atomic_type->extra_types);
                        }
                        $types[] = $first_atomic_type;
                    } else {
                        $types[] = $atomic_template_type;
                    }
                }
                $template_type = $template_type->getBuilder()->setTypes($types)->freeze();
            }
        } elseif ($codebase) {
            foreach ($inferred_lower_bounds as $template_type_map) {
                foreach ($template_type_map as $template_class => $_) {
                    if (strpos($template_class, 'fn-') === 0) {
                        continue;
                    }
                    try {
                        $classlike_storage = $codebase->classlike_storage_provider->get($template_class);
                        if ($classlike_storage->template_extended_params) {
                            $defining_class = $atomic_type->defining_class;
                            if (isset($classlike_storage->template_extended_params[$defining_class])) {
                                $param_map = $classlike_storage->template_extended_params[$defining_class];
                                if (isset($param_map[$key])) {
                                    $template_name = (string) $param_map[$key];
                                    if (isset($inferred_lower_bounds[$template_name][$template_class])) {
                                        $template_type = \Psalm\Internal\Type\TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($inferred_lower_bounds[$template_name][$template_class], $codebase);
                                    }
                                }
                            }
                        }
                    } catch (InvalidArgumentException $e) {
                    }
                }
            }
        }
        return $template_type;
    }
    /**
     * @param TTemplateKeyOf|TTemplateValueOf $atomic_type
     * @param array<string, array<string, non-empty-list<TemplateBound>>> $inferred_lower_bounds
     */
    private static function replaceTemplateKeyOfValueOf(?Codebase $codebase, Atomic $atomic_type, array $inferred_lower_bounds) : ?Atomic
    {
        if (!isset($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class])) {
            return null;
        }
        $template_type = \Psalm\Internal\Type\TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class], $codebase);
        if ($atomic_type instanceof TTemplateKeyOf && TKeyOf::isViableTemplateType($template_type)) {
            return new TKeyOf($template_type);
        }
        if ($atomic_type instanceof TTemplateValueOf && TValueOf::isViableTemplateType($template_type)) {
            return new TValueOf($template_type);
        }
        return null;
    }
    /**
     * @param array<string, array<string, non-empty-list<TemplateBound>>> $inferred_lower_bounds
     */
    private static function replaceTemplatePropertiesOf(?Codebase $codebase, TTemplatePropertiesOf $atomic_type, array $inferred_lower_bounds) : ?Atomic
    {
        if (!isset($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class])) {
            return null;
        }
        $template_type = \Psalm\Internal\Type\TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class], $codebase);
        $classlike_type = $template_type->getSingleAtomic();
        if (!$classlike_type instanceof TNamedObject) {
            return null;
        }
        return new TPropertiesOf($classlike_type, $atomic_type->visibility_filter);
    }
    /**
     * @param array<string, array<string, non-empty-list<TemplateBound>>> $inferred_lower_bounds
     */
    private static function replaceConditional(\Psalm\Internal\Type\TemplateResult $template_result, Codebase $codebase, TConditional &$atomic_type, array $inferred_lower_bounds) : Union
    {
        $template_type = isset($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class]) ? \Psalm\Internal\Type\TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($inferred_lower_bounds[$atomic_type->param_name][$atomic_type->defining_class], $codebase) : null;
        $if_template_type = null;
        $else_template_type = null;
        $as_type = $atomic_type->as_type;
        $conditional_type = $atomic_type->conditional_type;
        $if_type = $atomic_type->if_type;
        $else_type = $atomic_type->else_type;
        if ($template_type) {
            $as_type = self::replace($as_type, $template_result, $codebase);
            if ($as_type->isNullable() && $template_type->isVoid()) {
                $template_type = Type::getNull();
            }
            $matching_if_types = [];
            $matching_else_types = [];
            foreach ($template_type->getAtomicTypes() as $candidate_atomic_type) {
                if (UnionTypeComparator::isContainedBy($codebase, new Union([$candidate_atomic_type]), $conditional_type, \false, \false, null, \false, \false) && (!$candidate_atomic_type instanceof TInt || $conditional_type->getId() !== 'float')) {
                    $matching_if_types[] = $candidate_atomic_type;
                } elseif (!UnionTypeComparator::isContainedBy($codebase, $conditional_type, new Union([$candidate_atomic_type]), \false, \false, null, \false, \false)) {
                    $matching_else_types[] = $candidate_atomic_type;
                }
            }
            $if_candidate_type = $matching_if_types ? new Union($matching_if_types) : null;
            $else_candidate_type = $matching_else_types ? new Union($matching_else_types) : null;
            if ($if_candidate_type && UnionTypeComparator::isContainedBy($codebase, $if_candidate_type, $conditional_type, \false, \false, null, \false, \false)) {
                $if_template_type = $if_type;
                $refined_template_result = clone $template_result;
                $refined_template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class] = [new \Psalm\Internal\Type\TemplateBound($if_candidate_type)];
                $if_template_type = self::replace($if_template_type, $refined_template_result, $codebase);
            }
            if ($else_candidate_type && UnionTypeComparator::isContainedBy($codebase, $else_candidate_type, $as_type, \false, \false, null, \false, \false)) {
                $else_template_type = $else_type;
                $refined_template_result = clone $template_result;
                $refined_template_result->lower_bounds[$atomic_type->param_name][$atomic_type->defining_class] = [new \Psalm\Internal\Type\TemplateBound($else_candidate_type)];
                $else_template_type = self::replace($else_template_type, $refined_template_result, $codebase);
            }
        }
        if (!$if_template_type && !$else_template_type) {
            $if_type = self::replace($if_type, $template_result, $codebase);
            $else_type = self::replace($else_type, $template_result, $codebase);
            $class_template_type = Type::combineUnionTypes($if_type, $else_type, $codebase);
        } else {
            $class_template_type = Type::combineUnionTypes($if_template_type, $else_template_type, $codebase);
        }
        $atomic_type = $atomic_type->setTypes($as_type, $conditional_type, $if_type, $else_type);
        return $class_template_type;
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\Aliases;
use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Type\TypeAlias\InlineTypeAlias;
use Psalm\Type;
use function array_splice;
use function array_unshift;
use function count;
use function in_array;
use function is_numeric;
use function preg_match;
use function preg_replace;
use function str_split;
use function strlen;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class TypeTokenizer
{
    /**
     * @var array<string, bool>
     */
    public const PSALM_RESERVED_WORDS = ['int' => \true, 'string' => \true, 'float' => \true, 'bool' => \true, 'false' => \true, 'true' => \true, 'object' => \true, 'empty' => \true, 'callable' => \true, 'array' => \true, 'non-empty-array' => \true, 'non-empty-string' => \true, 'non-falsy-string' => \true, 'iterable' => \true, 'null' => \true, 'mixed' => \true, 'numeric-string' => \true, 'class-string' => \true, 'interface-string' => \true, 'enum-string' => \true, 'trait-string' => \true, 'callable-string' => \true, 'callable-array' => \true, 'callable-object' => \true, 'stringable-object' => \true, 'pure-callable' => \true, 'pure-Closure' => \true, 'literal-string' => \true, 'non-empty-literal-string' => \true, 'lowercase-string' => \true, 'non-empty-lowercase-string' => \true, 'positive-int' => \true, 'non-negative-int' => \true, 'negative-int' => \true, 'non-positive-int' => \true, 'literal-int' => \true, 'boolean' => \true, 'integer' => \true, 'double' => \true, 'real' => \true, 'resource' => \true, 'void' => \true, 'self' => \true, 'static' => \true, 'scalar' => \true, 'numeric' => \true, 'no-return' => \true, 'never-return' => \true, 'never-returns' => \true, 'never' => \true, 'array-key' => \true, 'key-of' => \true, 'value-of' => \true, 'properties-of' => \true, 'public-properties-of' => \true, 'protected-properties-of' => \true, 'private-properties-of' => \true, 'non-empty-countable' => \true, 'list' => \true, 'non-empty-list' => \true, 'class-string-map' => \true, 'open-resource' => \true, 'closed-resource' => \true, 'associative-array' => \true, 'arraylike-object' => \true, 'int-mask' => \true, 'int-mask-of' => \true];
    /**
     * @var array<string, list<array{0: string, 1: int}>>
     */
    private static array $memoized_tokens = [];
    /**
     * Tokenises a type string into an array of tuples where the first element
     * contains the string token and the second element contains its offset,
     *
     * @return list<array{0: string, 1: int}>
     * @psalm-suppress PossiblyUndefinedIntArrayOffset
     */
    public static function tokenize(string $string_type, bool $ignore_space = \true) : array
    {
        $type_tokens = [['', 0]];
        $was_char = \false;
        $quote_char = null;
        $escaped = \false;
        if (isset(self::$memoized_tokens[$string_type])) {
            return self::$memoized_tokens[$string_type];
        }
        // index of last type token
        $rtc = 0;
        $chars = str_split($string_type);
        $was_space = \false;
        for ($i = 0, $c = count($chars); $i < $c; ++$i) {
            $char = $chars[$i];
            if (!$quote_char && $char === ' ' && $ignore_space) {
                $was_space = \true;
                continue;
            }
            if ($was_space && ($char === '$' || $char === '.' && ($chars[$i + 1] ?? null) === '.' && ($chars[$i + 2] ?? null) === '.' && ($chars[$i + 3] ?? null) === '$')) {
                $type_tokens[++$rtc] = [' ', $i - 1];
                $type_tokens[++$rtc] = ['', $i];
            } elseif ($was_space && ($char === 'a' || $char === 'i') && ($chars[$i + 1] ?? null) === 's' && ($chars[$i + 2] ?? null) === ' ') {
                $type_tokens[++$rtc] = [$char . 's', $i - 1];
                $type_tokens[++$rtc] = ['', ++$i];
                $was_char = \false;
                continue;
            } elseif ($was_char) {
                $type_tokens[++$rtc] = ['', $i];
            }
            if ($quote_char) {
                if ($char === $quote_char && $i > 0 && !$escaped) {
                    $quote_char = null;
                    $type_tokens[$rtc][0] .= $char;
                    $was_char = \true;
                    continue;
                }
                $was_char = \false;
                if ($char === '\\' && !$escaped && $i < $c - 1 && ($chars[$i + 1] === $quote_char || $chars[$i + 1] === '\\')) {
                    $escaped = \true;
                    continue;
                }
                $escaped = \false;
                $type_tokens[$rtc][0] .= $char;
                continue;
            }
            if ($char === '"' || $char === '\'') {
                if ($type_tokens[$rtc][0] === '') {
                    $type_tokens[$rtc] = [$char, $i];
                } else {
                    $type_tokens[++$rtc] = [$char, $i];
                }
                $quote_char = $char;
                $was_char = \false;
                $was_space = \false;
                continue;
            }
            if ($char === '<' || $char === '>' || $char === '|' || $char === '?' || $char === ',' || $char === '{' || $char === '}' || $char === '[' || $char === ']' || $char === '(' || $char === ')' || $char === ' ' || $char === '&' || $char === '=') {
                if ($char === '(' && $type_tokens[$rtc][0] === 'func_num_args' && isset($chars[$i + 1]) && $chars[$i + 1] === ')') {
                    $type_tokens[$rtc][0] = 'func_num_args()';
                    ++$i;
                    continue;
                }
                if ($type_tokens[$rtc][0] === '') {
                    $type_tokens[$rtc] = [$char, $i];
                } else {
                    $type_tokens[++$rtc] = [$char, $i];
                }
                $was_char = \true;
                $was_space = \false;
                continue;
            }
            if ($char === ':') {
                if ($i + 1 < $c && $chars[$i + 1] === ':') {
                    if ($type_tokens[$rtc][0] === '') {
                        $type_tokens[$rtc] = ['::', $i];
                    } else {
                        $type_tokens[++$rtc] = ['::', $i];
                    }
                    $was_char = \true;
                    $was_space = \false;
                    ++$i;
                    continue;
                }
                if ($type_tokens[$rtc][0] === '') {
                    $type_tokens[$rtc] = [':', $i];
                } else {
                    $type_tokens[++$rtc] = [':', $i];
                }
                $was_char = \true;
                $was_space = \false;
                continue;
            }
            if ($char === '.') {
                if ($i + 1 < $c && is_numeric($chars[$i + 1]) && $i > 0 && is_numeric($chars[$i - 1])) {
                    $type_tokens[$rtc][0] .= $char;
                    $was_char = \false;
                    $was_space = \false;
                    continue;
                }
                if ($i + 2 > $c || $chars[$i + 1] !== '.' || $chars[$i + 2] !== '.') {
                    throw new TypeParseTreeException('Unexpected token ' . $char);
                }
                if ($type_tokens[$rtc][0] === '') {
                    $type_tokens[$rtc] = ['...', $i];
                } else {
                    $type_tokens[++$rtc] = ['...', $i];
                }
                $was_char = \true;
                $was_space = \false;
                $i += 2;
                continue;
            }
            $type_tokens[$rtc][0] .= $char;
            $was_char = \false;
            $was_space = \false;
        }
        /** @var list<array{0: string, 1: int}> $type_tokens */
        self::$memoized_tokens[$string_type] = $type_tokens;
        return $type_tokens;
    }
    /**
     * @psalm-pure
     */
    public static function fixScalarTerms(string $type_string, ?int $analysis_php_version_id = null) : string
    {
        $type_string_lc = strtolower($type_string);
        switch ($type_string_lc) {
            case 'int':
            case 'void':
            case 'float':
            case 'string':
            case 'bool':
            case 'callable':
            case 'iterable':
            case 'array':
            case 'object':
            case 'true':
            case 'false':
            case 'null':
            case 'mixed':
                return $type_string_lc;
        }
        switch ($type_string) {
            case 'boolean':
                return $analysis_php_version_id !== null ? $type_string : 'bool';
            case 'integer':
                return $analysis_php_version_id !== null ? $type_string : 'int';
            case 'double':
            case 'real':
                return $analysis_php_version_id !== null ? $type_string : 'float';
        }
        return $type_string;
    }
    /**
     * @param  array<string, mixed>|null       $template_type_map
     * @param  array<string, TypeAlias>|null   $type_aliases
     * @return list<array{0: string, 1: int, 2?: string}>
     */
    public static function getFullyQualifiedTokens(string $string_type, Aliases $aliases, ?array $template_type_map = null, ?array $type_aliases = null, ?string $self_fqcln = null, ?string $parent_fqcln = null, bool $allow_assertions = \false) : array
    {
        $type_tokens = self::tokenize($string_type);
        for ($i = 0, $l = count($type_tokens); $i < $l; ++$i) {
            $string_type_token = $type_tokens[$i];
            if (in_array($string_type_token[0], ['<', '>', '|', '?', ',', '{', '}', ':', '::', '[', ']', '(', ')', '&', '=', '...', 'as', 'is'], \true)) {
                continue;
            }
            if ($string_type_token[0][0] === '\\' && strlen($string_type_token[0]) === 1) {
                throw new TypeParseTreeException("Backslash \"\\\" has to be part of class name.");
            }
            if ($string_type_token[0][0] === '"' || $string_type_token[0][0] === '\'' || preg_match('/[0-9]/', $string_type_token[0][0])) {
                continue;
            }
            if ($string_type_token[0][0] === '-' && is_numeric($string_type_token[0])) {
                continue;
            }
            if (isset($type_tokens[$i + 1]) && $type_tokens[$i + 1][0] === ':' && isset($type_tokens[$i - 1]) && ($type_tokens[$i - 1][0] === '{' || $type_tokens[$i - 1][0] === ',')) {
                continue;
            }
            if ($i > 0 && $type_tokens[$i - 1][0] === '::') {
                continue;
            }
            if (strpos($string_type_token[0], '$')) {
                $string_type_token[0] = preg_replace('/(.+)\\$.*/', '$1', $string_type_token[0]);
            }
            $fixed_token = !isset($type_tokens[$i + 1]) || $type_tokens[$i + 1][0] !== '(' ? self::fixScalarTerms($string_type_token[0]) : $string_type_token[0];
            $type_tokens[$i][0] = $fixed_token;
            $string_type_token[0] = $fixed_token;
            if ($string_type_token[0] === 'self' && $self_fqcln) {
                $type_tokens[$i][0] = $self_fqcln;
                continue;
            }
            if ($string_type_token[0] === 'parent' && $parent_fqcln) {
                $type_tokens[$i][0] = $parent_fqcln;
                continue;
            }
            if (isset(self::PSALM_RESERVED_WORDS[$string_type_token[0]])) {
                continue;
            }
            if (isset($template_type_map[$string_type_token[0]])) {
                continue;
            }
            if ($i > 1 && $type_tokens[$i - 2][0] === 'class-string-map' && $type_tokens[$i - 1][0] === '<') {
                $template_type_map[$string_type_token[0]] = \true;
                continue;
            }
            if (isset($type_tokens[$i + 1]) && isset($type_tokens[$i - 1]) && ($type_tokens[$i - 1][0] === '{' || $type_tokens[$i - 1][0] === ',')) {
                $next_char = $type_tokens[$i + 1][0];
                if ($next_char === ':') {
                    continue;
                }
                if ($next_char === '?' && isset($type_tokens[$i + 2]) && $type_tokens[$i + 2][0] === ':') {
                    continue;
                }
            }
            if ($string_type_token[0][0] === '$' || $string_type_token[0][0] === ' ') {
                continue;
            }
            if (isset($type_tokens[$i + 1]) && $type_tokens[$i + 1][0] === '(') {
                continue;
            }
            if ($allow_assertions && $string_type_token[0] === 'falsy') {
                $type_tokens[$i][0] = 'false-y';
                continue;
            }
            if ($string_type_token[0] === 'func_num_args()' || $string_type_token[0] === 'PHP_MAJOR_VERSION' || $string_type_token[0] === 'PHP_VERSION_ID') {
                continue;
            }
            $type_tokens[$i][2] = $string_type_token[0];
            if (isset($type_aliases[$string_type_token[0]])) {
                $type_alias = $type_aliases[$string_type_token[0]];
                if ($type_alias instanceof InlineTypeAlias) {
                    $replacement_tokens = $type_alias->replacement_tokens;
                    array_unshift($replacement_tokens, ['(', $i]);
                    $replacement_tokens[] = [')', $i];
                    $diff = count($replacement_tokens) - 1;
                    array_splice($type_tokens, $i, 1, $replacement_tokens);
                    $i += $diff;
                    $l += $diff;
                }
            } else {
                $type_tokens[$i][0] = Type::getFQCLNFromString($string_type_token[0], $aliases);
            }
        }
        /** @var list<array{0: string, 1: int, 2?: string}> */
        return $type_tokens;
    }
    public static function clearCache() : void
    {
        self::$memoized_tokens = [];
    }
}
<?php

namespace Psalm\Internal\Type;

use InvalidArgumentException;
use Psalm\Codebase;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableArray;
use Psalm\Type\Atomic\TCallableKeyedArray;
use Psalm\Type\Atomic\TCallableObject;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonEmptyMixed;
use Psalm\Type\Atomic\TNonEmptyNonspecificLiteralString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonFalsyString;
use Psalm\Type\Atomic\TNonspecificLiteralInt;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_filter;
use function array_intersect_key;
use function array_key_exists;
use function array_keys;
use function array_merge;
use function array_values;
use function assert;
use function count;
use function get_class;
use function is_int;
use function is_numeric;
use function min;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class TypeCombiner
{
    /**
     * Combines types together
     *  - so `int + string = int|string`
     *  - so `array<int> + array<string> = array<int|string>`
     *  - and `array<int> + string = array<int>|string`
     *  - and `array<never> + array<never> = array<never>`
     *  - and `array<string> + array<never> = array<string>`
     *  - and `array + array<string> = array<mixed>`
     *
     * @psalm-external-mutation-free
     * @psalm-suppress ImpurePropertyAssignment We're not actually mutating any external instance
     * @param  non-empty-list<Atomic>    $types
     * @param  int    $literal_limit any greater number of literal types than this
     *                               will be merged to a scalar
     */
    public static function combine(array $types, ?Codebase $codebase = null, bool $overwrite_empty_array = \false, bool $allow_mixed_union = \true, int $literal_limit = 500) : Union
    {
        if (count($types) === 1) {
            return new Union([$types[0]]);
        }
        $combination = new \Psalm\Internal\Type\TypeCombination();
        $from_docblock = \false;
        foreach ($types as $type) {
            $from_docblock = $from_docblock || $type->from_docblock;
            $result = self::scrapeTypeProperties($type, $combination, $codebase, $overwrite_empty_array, $allow_mixed_union, $literal_limit);
            if ($result) {
                if ($from_docblock) {
                    return $result->setProperties(['from_docblock' => \true]);
                }
                return $result;
            }
        }
        if (count($combination->value_types) === 1 && !count($combination->objectlike_entries) && (!$combination->array_type_params || $combination->array_type_params[1]->isNever()) && !$combination->builtin_type_params && !$combination->object_type_params && !$combination->named_object_types && !$combination->strings && !$combination->class_string_types && !$combination->ints && !$combination->floats) {
            if (isset($combination->value_types['false'])) {
                return Type::getFalse($from_docblock);
            }
            if (isset($combination->value_types['true'])) {
                return Type::getTrue($from_docblock);
            }
        } elseif (isset($combination->value_types['void'])) {
            unset($combination->value_types['void']);
            // if we're merging with another type, we cannot represent it in PHP
            $from_docblock = \true;
            if (!isset($combination->value_types['null'])) {
                $combination->value_types['null'] = new TNull($from_docblock);
            }
        }
        if (isset($combination->value_types['true']) && isset($combination->value_types['false'])) {
            unset($combination->value_types['true'], $combination->value_types['false']);
            $combination->value_types['bool'] = new TBool($from_docblock);
        }
        if ($combination->array_type_params && (isset($combination->named_object_types['Traversable']) || isset($combination->builtin_type_params['Traversable'])) && (isset($combination->builtin_type_params['Traversable']) || isset($combination->named_object_types['Traversable']) && $combination->named_object_types['Traversable']->from_docblock) && !$combination->extra_types) {
            $array_param_types = $combination->array_type_params;
            $traversable_param_types = $combination->builtin_type_params['Traversable'] ?? [Type::getMixed(), Type::getMixed()];
            $combined_param_types = [];
            foreach ($array_param_types as $i => $array_param_type) {
                $combined_param_types[] = Type::combineUnionTypes($array_param_type, $traversable_param_types[$i]);
            }
            assert(count($combined_param_types) <= 2);
            $combination->value_types['iterable'] = new TIterable($combined_param_types);
            $combination->array_type_params = [];
            /**
             * @psalm-suppress PossiblyNullArrayAccess
             */
            unset($combination->value_types['array'], $combination->named_object_types['Traversable'], $combination->builtin_type_params['Traversable']);
        }
        if ($combination->empty_mixed && $combination->non_empty_mixed) {
            $combination->value_types['mixed'] = new TMixed((bool) $combination->mixed_from_loop_isset);
        }
        $new_types = [];
        if ($combination->objectlike_entries) {
            $new_types = self::handleKeyedArrayEntries($combination, $overwrite_empty_array, $from_docblock);
        }
        if ($combination->array_type_params) {
            if (count($combination->array_type_params) !== 2) {
                throw new UnexpectedValueException('Unexpected number of parameters');
            }
            $new_types[] = self::getArrayTypeFromGenericParams($codebase, $combination, $overwrite_empty_array, $allow_mixed_union, $type, $combination->array_type_params, $from_docblock);
        }
        if ($combination->extra_types) {
            /** @psalm-suppress PropertyTypeCoercion */
            $combination->extra_types = self::combine(array_values($combination->extra_types), $codebase)->getAtomicTypes();
        }
        foreach ($combination->builtin_type_params as $generic_type => $generic_type_params) {
            if ($generic_type === 'iterable') {
                assert(count($generic_type_params) <= 2);
                $new_types[] = new TIterable($generic_type_params, [], $from_docblock);
            } else {
                /** @psalm-suppress ArgumentTypeCoercion Caused by the PropertyTypeCoercion above */
                $generic_object = new TGenericObject($generic_type, $generic_type_params, \false, \false, $combination->extra_types, $from_docblock);
                $new_types[] = $generic_object;
                if ($combination->named_object_types) {
                    unset($combination->named_object_types[$generic_type]);
                }
            }
        }
        foreach ($combination->object_type_params as $generic_type => $generic_type_params) {
            $generic_type = substr($generic_type, 0, (int) strpos($generic_type, '<'));
            /** @psalm-suppress ArgumentTypeCoercion Caused by the PropertyTypeCoercion above */
            $generic_object = new TGenericObject($generic_type, $generic_type_params, \false, $combination->object_static[$generic_type] ?? \false, $combination->extra_types, $from_docblock);
            $new_types[] = $generic_object;
        }
        if ($combination->class_string_types) {
            if ($combination->strings) {
                foreach ($combination->strings as $k => $string) {
                    if ($string instanceof TLiteralClassString) {
                        $combination->class_string_types[$string->value] = new TNamedObject($string->value);
                        unset($combination->strings[$k]);
                    }
                }
            }
            $has_non_specific_string = isset($combination->value_types['string']) && get_class($combination->value_types['string']) === TString::class;
            if (!$has_non_specific_string) {
                $object_type = self::combine(array_values($combination->class_string_types), $codebase);
                foreach ($object_type->getAtomicTypes() as $object_atomic_type) {
                    if ($object_atomic_type instanceof TNamedObject) {
                        $class_type = new TClassString($object_atomic_type->value, $object_atomic_type);
                    } elseif ($object_atomic_type instanceof TObject) {
                        $class_type = new TClassString();
                    } else {
                        continue;
                    }
                    $new_types[] = $class_type->setFromDocblock($from_docblock);
                }
            }
        }
        if ($combination->strings) {
            $new_types = array_merge($new_types, array_values($combination->strings));
        }
        if ($combination->ints) {
            $new_types = array_merge($new_types, array_values($combination->ints));
        }
        if ($combination->floats) {
            $new_types = array_merge($new_types, array_values($combination->floats));
        }
        if (isset($combination->value_types['string']) && isset($combination->value_types['int']) && isset($combination->value_types['bool']) && isset($combination->value_types['float'])) {
            unset($combination->value_types['string'], $combination->value_types['int'], $combination->value_types['bool'], $combination->value_types['float']);
            $combination->value_types['scalar'] = new TScalar();
        }
        if ($combination->named_object_types !== null) {
            foreach ($combination->value_types as $key => $atomic_type) {
                if ($atomic_type instanceof TEnumCase && isset($combination->named_object_types[$atomic_type->value])) {
                    unset($combination->value_types[$key]);
                }
            }
            $combination->value_types += $combination->named_object_types;
        }
        $has_never = isset($combination->value_types['never']);
        foreach ($combination->value_types as $type) {
            if ($type instanceof TMixed && $combination->mixed_from_loop_isset && (count($combination->value_types) > 1 + (int) $has_never || count($new_types) > (int) $has_never)) {
                continue;
            }
            if ($type instanceof TNever && (count($combination->value_types) > 1 || count($new_types))) {
                $has_never = \true;
                continue;
            }
            $new_types[] = $type->setFromDocblock($from_docblock);
        }
        if (!$new_types && !$has_never) {
            throw new UnexpectedValueException('There should be types here');
        } elseif (!$new_types && $has_never) {
            $union_type = Type::getNever($from_docblock);
        } else {
            $union_type = new Union($new_types);
        }
        $union_properties = [];
        if ($from_docblock) {
            $union_properties['from_docblock'] = \true;
        }
        if ($has_never) {
            $union_properties['explicit_never'] = \true;
        }
        if ($union_properties !== []) {
            return $union_type->setProperties($union_properties);
        }
        return $union_type;
    }
    /**
     * @psalm-suppress ComplexMethod Unavoidably complex method
     */
    private static function scrapeTypeProperties(Atomic $type, \Psalm\Internal\Type\TypeCombination $combination, ?Codebase $codebase, bool $overwrite_empty_array, bool $allow_mixed_union, int $literal_limit) : ?Union
    {
        if ($type instanceof TList) {
            $type = $type->getKeyedArray();
        }
        if ($type instanceof TMixed) {
            if ($type->from_loop_isset) {
                if ($combination->mixed_from_loop_isset === null) {
                    $combination->mixed_from_loop_isset = \true;
                } else {
                    return null;
                }
            } else {
                $combination->mixed_from_loop_isset = \false;
            }
            if ($type instanceof TNonEmptyMixed) {
                $combination->non_empty_mixed = \true;
                if ($combination->empty_mixed) {
                    return null;
                }
            } elseif ($type instanceof TEmptyMixed) {
                $combination->empty_mixed = \true;
                if ($combination->non_empty_mixed) {
                    return null;
                }
            } else {
                $combination->empty_mixed = \true;
                $combination->non_empty_mixed = \true;
            }
            if (!$allow_mixed_union) {
                return Type::getMixed($combination->mixed_from_loop_isset);
            }
        }
        // deal with false|bool => bool
        if (($type instanceof TFalse || $type instanceof TTrue) && isset($combination->value_types['bool'])) {
            return null;
        }
        if (get_class($type) === TBool::class && isset($combination->value_types['false'])) {
            unset($combination->value_types['false']);
        }
        if (get_class($type) === TBool::class && isset($combination->value_types['true'])) {
            unset($combination->value_types['true']);
        }
        if ($type instanceof TArray && isset($combination->builtin_type_params['iterable'])) {
            $type_key = 'iterable';
        } elseif ($type instanceof TArray && $type->type_params[1]->isMixed() && isset($combination->value_types['iterable'])) {
            $type_key = 'iterable';
            $combination->builtin_type_params['iterable'] = [Type::getMixed(), Type::getMixed()];
        } elseif ($type instanceof TNamedObject && $type->value === 'Traversable' && (isset($combination->builtin_type_params['iterable']) || isset($combination->value_types['iterable']))) {
            $type_key = 'iterable';
            if (!isset($combination->builtin_type_params['iterable'])) {
                $combination->builtin_type_params['iterable'] = [Type::getMixed(), Type::getMixed()];
            }
            if (!$type instanceof TGenericObject) {
                $type = new TGenericObject($type->value, [Type::getMixed(), Type::getMixed()]);
            }
        } elseif ($type instanceof TNamedObject && ($type->value === 'Traversable' || $type->value === 'Generator')) {
            $type_key = $type->value;
        } else {
            $type_key = $type->getKey();
        }
        if ($type instanceof TIterable && $combination->array_type_params && ($type->has_docblock_params || $combination->array_type_params[1]->isMixed())) {
            if (!isset($combination->builtin_type_params['iterable'])) {
                $combination->builtin_type_params['iterable'] = $combination->array_type_params;
            } else {
                foreach ($combination->array_type_params as $i => $array_type_param) {
                    $iterable_type_param = $combination->builtin_type_params['iterable'][$i];
                    /** @psalm-suppress PropertyTypeCoercion */
                    $combination->builtin_type_params['iterable'][$i] = Type::combineUnionTypes($iterable_type_param, $array_type_param);
                }
            }
            $combination->array_type_params = [];
        }
        if ($type instanceof TIterable && (isset($combination->named_object_types['Traversable']) || isset($combination->builtin_type_params['Traversable']))) {
            if (!isset($combination->builtin_type_params['iterable'])) {
                $combination->builtin_type_params['iterable'] = $combination->builtin_type_params['Traversable'] ?? [Type::getMixed(), Type::getMixed()];
            } elseif (isset($combination->builtin_type_params['Traversable'])) {
                foreach ($combination->builtin_type_params['Traversable'] as $i => $array_type_param) {
                    $iterable_type_param = $combination->builtin_type_params['iterable'][$i];
                    /** @psalm-suppress PropertyTypeCoercion */
                    $combination->builtin_type_params['iterable'][$i] = Type::combineUnionTypes($iterable_type_param, $array_type_param);
                }
            } else {
                $combination->builtin_type_params['iterable'] = [Type::getMixed(), Type::getMixed()];
            }
            /** @psalm-suppress PossiblyNullArrayAccess */
            unset($combination->named_object_types['Traversable'], $combination->builtin_type_params['Traversable']);
        }
        if ($type instanceof TNamedObject || $type instanceof TTemplateParam || $type instanceof TIterable || $type instanceof TObjectWithProperties) {
            if ($type->extra_types) {
                $combination->extra_types = array_merge($combination->extra_types, $type->extra_types);
            }
        }
        if ($type instanceof TNamedObject) {
            if (array_key_exists($type->value, $combination->object_static)) {
                if ($combination->object_static[$type->value] && !$type->is_static) {
                    $combination->object_static[$type->value] = \false;
                }
            } else {
                $combination->object_static[$type->value] = $type->is_static;
            }
        }
        if ($type instanceof TArray && $type_key === 'array') {
            if ($type instanceof TCallableArray && isset($combination->value_types['callable'])) {
                return null;
            }
            foreach ($type->type_params as $i => $type_param) {
                $combination->array_type_params[$i] = Type::combineUnionTypes($combination->array_type_params[$i] ?? null, $type_param, $codebase, $overwrite_empty_array);
            }
            if ($type instanceof TNonEmptyArray) {
                if ($combination->array_counts !== null) {
                    if ($type->count === null) {
                        $combination->array_counts = null;
                    } else {
                        $combination->array_counts[$type->count] = \true;
                    }
                }
                if ($combination->array_min_counts !== null) {
                    if ($type->min_count === null) {
                        $combination->array_min_counts = null;
                    } else {
                        $combination->array_min_counts[$type->min_count] = \true;
                    }
                }
                $combination->array_sometimes_filled = \true;
            } else {
                $combination->array_always_filled = \false;
            }
            if (!$type->isEmptyArray()) {
                $combination->all_arrays_lists = \false;
                $combination->all_arrays_class_string_maps = \false;
            }
            if ($type instanceof TCallableArray) {
                if ($combination->all_arrays_callable !== \false) {
                    $combination->all_arrays_callable = \true;
                }
            } else {
                $combination->all_arrays_callable = \false;
            }
            return null;
        }
        if ($type instanceof TClassStringMap) {
            foreach ([$type->getStandinKeyParam(), $type->value_param] as $i => $type_param) {
                $combination->array_type_params[$i] = Type::combineUnionTypes($combination->array_type_params[$i] ?? null, $type_param, $codebase, $overwrite_empty_array);
            }
            $combination->array_always_filled = \false;
            if ($combination->all_arrays_class_string_maps !== \false) {
                $combination->all_arrays_class_string_maps = \true;
                $combination->class_string_map_names[$type->param_name] = \true;
                $combination->class_string_map_as_types[(string) $type->as_type] = $type->as_type;
            }
            return null;
        }
        if ($type instanceof TGenericObject && ($type->value === 'Traversable' || $type->value === 'Generator') || $type instanceof TIterable && $type->has_docblock_params || $type instanceof TArray && $type_key === 'iterable') {
            foreach ($type->type_params as $i => $type_param) {
                /** @psalm-suppress PropertyTypeCoercion */
                $combination->builtin_type_params[$type_key][$i] = Type::combineUnionTypes($combination->builtin_type_params[$type_key][$i] ?? null, $type_param, $codebase, $overwrite_empty_array);
            }
            return null;
        }
        if ($type instanceof TGenericObject) {
            foreach ($type->type_params as $i => $type_param) {
                /** @psalm-suppress PropertyTypeCoercion */
                $combination->object_type_params[$type_key][$i] = Type::combineUnionTypes($combination->object_type_params[$type_key][$i] ?? null, $type_param, $codebase, $overwrite_empty_array);
            }
            return null;
        }
        if ($type instanceof TKeyedArray) {
            if ($type instanceof TCallableKeyedArray && isset($combination->value_types['callable'])) {
                return null;
            }
            $existing_objectlike_entries = (bool) $combination->objectlike_entries;
            $missing_entries = $combination->objectlike_entries;
            $combination->objectlike_sealed = $combination->objectlike_sealed && $type->fallback_params === null;
            $has_defined_keys = \false;
            foreach ($type->properties as $candidate_property_name => $candidate_property_type) {
                $value_type = $combination->objectlike_entries[$candidate_property_name] ?? null;
                if (!$value_type) {
                    $combination->objectlike_entries[$candidate_property_name] = $candidate_property_type->setPossiblyUndefined($existing_objectlike_entries || $candidate_property_type->possibly_undefined);
                } else {
                    $combination->objectlike_entries[$candidate_property_name] = Type::combineUnionTypes($value_type, $candidate_property_type, $codebase, $overwrite_empty_array);
                    if ((!$value_type->possibly_undefined || !$candidate_property_type->possibly_undefined) && $overwrite_empty_array) {
                        $combination->objectlike_entries[$candidate_property_name] = $combination->objectlike_entries[$candidate_property_name]->setPossiblyUndefined(\false);
                    }
                }
                if (!$candidate_property_type->possibly_undefined) {
                    $has_defined_keys = \true;
                }
                if (($candidate_property_type->possibly_undefined || ($value_type->possibly_undefined ?? \true)) && $combination->fallbackKeyContains($candidate_property_name)) {
                    $combination->objectlike_entries[$candidate_property_name] = Type::combineUnionTypes($combination->objectlike_entries[$candidate_property_name], $combination->objectlike_value_type, $codebase, $overwrite_empty_array);
                }
                unset($missing_entries[$candidate_property_name]);
            }
            if ($type->fallback_params) {
                $combination->objectlike_key_type = Type::combineUnionTypes($type->fallback_params[0], $combination->objectlike_key_type, $codebase, $overwrite_empty_array);
                $combination->objectlike_value_type = Type::combineUnionTypes($type->fallback_params[1], $combination->objectlike_value_type, $codebase, $overwrite_empty_array);
            }
            if (!$has_defined_keys) {
                $combination->array_always_filled = \false;
            }
            if ($combination->array_counts !== null) {
                $combination->array_counts[count($type->properties)] = \true;
            }
            if ($combination->array_min_counts !== null) {
                $min_prop_count = count(array_filter($type->properties, static fn(Union $p): bool => !$p->possibly_undefined));
                $combination->array_min_counts[$min_prop_count] = \true;
            }
            foreach ($missing_entries as $k => $_) {
                $combination->objectlike_entries[$k] = $combination->objectlike_entries[$k]->setPossiblyUndefined(\true);
            }
            if ($combination->objectlike_value_type) {
                foreach ($missing_entries as $k => $_) {
                    if (!$combination->fallbackKeyContains($k)) {
                        continue;
                    }
                    $combination->objectlike_entries[$k] = Type::combineUnionTypes($combination->objectlike_entries[$k], $combination->objectlike_value_type, $codebase, $overwrite_empty_array);
                }
            }
            if (!$type->is_list) {
                $combination->all_arrays_lists = \false;
            } elseif ($combination->all_arrays_lists !== \false) {
                $combination->all_arrays_lists = \true;
            }
            if ($type instanceof TCallableKeyedArray) {
                if ($combination->all_arrays_callable !== \false) {
                    $combination->all_arrays_callable = \true;
                }
            } else {
                $combination->all_arrays_callable = \false;
            }
            $combination->all_arrays_class_string_maps = \false;
            return null;
        }
        if ($type instanceof TObject) {
            if ($type instanceof TCallableObject && isset($combination->value_types['callable'])) {
                return null;
            }
            $combination->named_object_types = null;
            $combination->value_types[$type_key] = $type;
            return null;
        }
        if ($type instanceof TIterable) {
            $combination->value_types[$type_key] = $type;
            return null;
        }
        if ($type instanceof TTemplateParam) {
            if (isset($combination->value_types[$type_key])) {
                /** @var TTemplateParam */
                $existing_template_type = $combination->value_types[$type_key];
                if (!$existing_template_type->as->equals($type->as)) {
                    $existing_template_type = $existing_template_type->replaceAs(Type::combineUnionTypes($type->as, $existing_template_type->as, $codebase));
                    $combination->value_types[$type_key] = $existing_template_type;
                }
                return null;
            }
            $combination->value_types[$type_key] = $type;
            return null;
        }
        if ($type instanceof TNamedObject) {
            if ($combination->named_object_types === null) {
                return null;
            }
            if (isset($combination->named_object_types[$type_key])) {
                return null;
            }
            if (!$codebase) {
                $combination->named_object_types[$type_key] = $type;
                return null;
            }
            if (!$codebase->classlikes->classOrInterfaceOrEnumExists($type_key)) {
                // write this to the main list
                $combination->value_types[$type_key] = $type;
                return null;
            }
            $is_class = $codebase->classExists($type_key);
            foreach ($combination->named_object_types as $key => $_) {
                if ($codebase->classExists($key)) {
                    if ($codebase->classExtendsOrImplements($key, $type_key)) {
                        unset($combination->named_object_types[$key]);
                        continue;
                    }
                    if ($is_class) {
                        if ($codebase->classExtends($type_key, $key)) {
                            return null;
                        }
                    }
                } else {
                    if ($codebase->interfaceExtends($key, $type_key)) {
                        unset($combination->named_object_types[$key]);
                        continue;
                    }
                    if ($is_class) {
                        if ($codebase->classImplements($type_key, $key)) {
                            return null;
                        }
                    } else {
                        if ($codebase->interfaceExtends($type_key, $key)) {
                            return null;
                        }
                    }
                }
            }
            $combination->named_object_types[$type_key] = $type;
            return null;
        }
        if ($type instanceof TScalar) {
            $combination->strings = null;
            $combination->ints = null;
            $combination->floats = null;
            unset($combination->value_types['string'], $combination->value_types['int'], $combination->value_types['bool'], $combination->value_types['true'], $combination->value_types['false'], $combination->value_types['float']);
            if (!isset($combination->value_types[$type_key]) || $combination->value_types[$type_key]->getId() === $type->getId()) {
                $combination->value_types[$type_key] = $type;
            } else {
                $combination->value_types[$type_key] = new TScalar();
            }
            return null;
        }
        if ($type instanceof Scalar && isset($combination->value_types['scalar'])) {
            return null;
        }
        if ($type instanceof TArrayKey) {
            $combination->strings = null;
            $combination->ints = null;
            unset($combination->value_types['string'], $combination->value_types['int']);
            $combination->value_types[$type_key] = $type;
            return null;
        }
        if ($type instanceof TString) {
            self::scrapeStringProperties($type_key, $type, $combination, $codebase, $literal_limit);
            return null;
        }
        if ($type instanceof TInt) {
            self::scrapeIntProperties($type_key, $type, $combination, $literal_limit);
            return null;
        }
        if ($type instanceof TFloat) {
            if ($type instanceof TLiteralFloat) {
                if ($combination->floats !== null && count($combination->floats) < $literal_limit) {
                    $combination->floats[$type_key] = $type;
                } else {
                    $combination->floats = null;
                    $combination->value_types['float'] = new TFloat();
                }
            } else {
                $combination->floats = null;
                $combination->value_types['float'] = $type;
            }
            return null;
        }
        if ($type instanceof TCallable && $type_key === 'callable') {
            if (($combination->value_types['string'] ?? null) instanceof TCallableString) {
                unset($combination->value_types['string']);
            } elseif (!empty($combination->array_type_params) && $combination->all_arrays_callable) {
                $combination->array_type_params = [];
            } elseif (isset($combination->value_types['callable-object'])) {
                unset($combination->value_types['callable-object']);
            }
        }
        $combination->value_types[$type_key] = $type;
        return null;
    }
    private static function scrapeStringProperties(string $type_key, Atomic $type, \Psalm\Internal\Type\TypeCombination $combination, ?Codebase $codebase, int $literal_limit) : void
    {
        if ($type instanceof TCallableString && isset($combination->value_types['callable'])) {
            return;
        }
        if (isset($combination->value_types['array-key'])) {
            return;
        }
        if ($type instanceof TTemplateParamClass) {
            $combination->value_types[$type_key] = $type;
        } elseif ($type instanceof TClassString) {
            if (!$type->as_type) {
                $combination->class_string_types['object'] = new TObject();
            } else {
                $combination->class_string_types[$type->as] = $type->as_type;
            }
        } elseif ($type instanceof TLiteralString) {
            if ($combination->strings !== null && count($combination->strings) < $literal_limit) {
                $combination->strings[$type_key] = $type;
            } else {
                $shared_classlikes = $codebase ? self::getSharedTypes($combination, $codebase) : [];
                $combination->strings = null;
                if (isset($combination->value_types['string']) && $combination->value_types['string'] instanceof TNumericString && is_numeric($type->value)) {
                    // do nothing
                } elseif (isset($combination->value_types['class-string']) && $type instanceof TLiteralClassString) {
                    // do nothing
                } elseif ($type instanceof TLiteralClassString) {
                    $type_classlikes = $codebase ? self::getClassLikes($codebase, $type->value) : [];
                    $mutual = array_intersect_key($type_classlikes, $shared_classlikes);
                    if ($mutual) {
                        $first_class = array_keys($mutual)[0];
                        $combination->class_string_types[$first_class] = new TNamedObject($first_class);
                    } else {
                        $combination->class_string_types['object'] = new TObject();
                    }
                } elseif (isset($combination->value_types['string']) && $combination->value_types['string'] instanceof TNonspecificLiteralString) {
                    // do nothing
                } elseif (isset($combination->value_types['string']) && $combination->value_types['string'] instanceof TLowercaseString && strtolower($type->value) === $type->value) {
                    // do nothing
                } elseif (isset($combination->value_types['string']) && $combination->value_types['string'] instanceof TNonFalsyString && $type->value) {
                    // do nothing
                } elseif (isset($combination->value_types['string']) && $combination->value_types['string'] instanceof TNonEmptyString && $type->value !== '') {
                    // do nothing
                } else {
                    $combination->value_types['string'] = new TString();
                }
            }
        } else {
            $type_key = 'string';
            if (!isset($combination->value_types['string'])) {
                if ($combination->strings) {
                    if ($type instanceof TNumericString) {
                        $has_non_numeric_string = \false;
                        foreach ($combination->strings as $string_type) {
                            if (!is_numeric($string_type->value)) {
                                $has_non_numeric_string = \true;
                                break;
                            }
                        }
                        if ($has_non_numeric_string) {
                            $combination->value_types['string'] = new TString();
                        } else {
                            $combination->value_types['string'] = $type;
                        }
                    } elseif ($type instanceof TLowercaseString) {
                        $has_non_lowercase_string = \false;
                        foreach ($combination->strings as $string_type) {
                            if (strtolower($string_type->value) !== $string_type->value) {
                                $has_non_lowercase_string = \true;
                                break;
                            }
                        }
                        if ($has_non_lowercase_string) {
                            $combination->value_types['string'] = new TString();
                        } else {
                            $combination->value_types['string'] = $type;
                        }
                    } elseif ($type instanceof TNonEmptyString) {
                        $has_empty_string = \false;
                        foreach ($combination->strings as $string_type) {
                            if (!$string_type->value) {
                                $has_empty_string = \true;
                                break;
                            }
                        }
                        if ($has_empty_string) {
                            $combination->value_types['string'] = new TString();
                        } else {
                            $combination->value_types['string'] = $type;
                        }
                    } elseif ($type instanceof TNonspecificLiteralString) {
                        $combination->value_types['string'] = $type;
                    } else {
                        $combination->value_types[$type_key] = new TString();
                    }
                } else {
                    $combination->value_types[$type_key] = $type;
                }
            } elseif (get_class($combination->value_types['string']) !== TString::class) {
                if (get_class($type) === TString::class) {
                    $combination->value_types['string'] = $type;
                } elseif (get_class($combination->value_types['string']) !== get_class($type)) {
                    if (get_class($type) === TNonEmptyString::class && get_class($combination->value_types['string']) === TNumericString::class) {
                        $combination->value_types['string'] = $type;
                    } elseif (get_class($type) === TNumericString::class && get_class($combination->value_types['string']) === TNonEmptyString::class) {
                        // do nothing
                    } elseif ((get_class($type) === TNonEmptyString::class || get_class($type) === TNumericString::class) && get_class($combination->value_types['string']) === TNonFalsyString::class) {
                        $combination->value_types['string'] = $type;
                    } elseif (get_class($type) === TNonFalsyString::class && (get_class($combination->value_types['string']) === TNonEmptyString::class || get_class($combination->value_types['string']) === TNumericString::class)) {
                        // do nothing
                    } elseif ((get_class($type) === TNonEmptyString::class || get_class($type) === TNonFalsyString::class) && get_class($combination->value_types['string']) === TNonEmptyLowercaseString::class) {
                        $combination->value_types['string'] = new TNonEmptyString();
                    } elseif ((get_class($combination->value_types['string']) === TNonEmptyString::class || get_class($combination->value_types['string']) === TNonFalsyString::class) && get_class($type) === TNonEmptyLowercaseString::class) {
                        $combination->value_types['string'] = new TNonEmptyString();
                    } elseif (get_class($type) === TLowercaseString::class && get_class($combination->value_types['string']) === TNonEmptyLowercaseString::class) {
                        $combination->value_types['string'] = $type;
                    } elseif (get_class($combination->value_types['string']) === TLowercaseString::class && get_class($type) === TNonEmptyLowercaseString::class) {
                        //no-change
                    } elseif (get_class($combination->value_types['string']) === TNonEmptyNonspecificLiteralString::class && $type instanceof TNonEmptyString) {
                        $combination->value_types['string'] = new TNonEmptyString();
                    } elseif (get_class($type) === TNonEmptyNonspecificLiteralString::class && $combination->value_types['string'] instanceof TNonEmptyString) {
                        // do nothing
                    } else {
                        $combination->value_types['string'] = new TString();
                    }
                }
            }
            $combination->strings = null;
        }
    }
    private static function scrapeIntProperties(string $type_key, Atomic $type, \Psalm\Internal\Type\TypeCombination $combination, int $literal_limit) : void
    {
        if (isset($combination->value_types['array-key'])) {
            return;
        }
        if ($type instanceof TLiteralInt) {
            if ($combination->ints !== null && count($combination->ints) < $literal_limit) {
                $combination->ints[$type_key] = $type;
            } else {
                $combination->ints[$type_key] = $type;
                $all_nonnegative = !array_filter($combination->ints, static fn($int): bool => $int->value < 0);
                if (isset($combination->value_types['int'])) {
                    $current_int_type = $combination->value_types['int'];
                    if ($current_int_type instanceof TIntRange) {
                        $min_bound = $current_int_type->min_bound;
                        $max_bound = $current_int_type->max_bound;
                        foreach ($combination->ints as $int) {
                            if (!$current_int_type->contains($int->value)) {
                                $min_bound = TIntRange::getNewLowestBound($min_bound, $int->value);
                                $max_bound = TIntRange::getNewHighestBound($max_bound, $int->value);
                            }
                        }
                        if ($min_bound !== $current_int_type->min_bound || $max_bound !== $current_int_type->max_bound) {
                            $combination->value_types['int'] = new TIntRange($min_bound, $max_bound);
                        }
                    }
                }
                $combination->ints = null;
                if (!isset($combination->value_types['int'])) {
                    $combination->value_types['int'] = $all_nonnegative ? new TIntRange(0, null) : new TNonspecificLiteralInt();
                }
            }
        } else {
            if ($type instanceof TNonspecificLiteralInt) {
                if ($combination->ints || !isset($combination->value_types['int'])) {
                    $combination->value_types['int'] = $type;
                } elseif (isset($combination->value_types['int']) && get_class($combination->value_types['int']) !== get_class($type)) {
                    $combination->value_types['int'] = new TInt();
                }
            } elseif ($type instanceof TIntRange) {
                $min_bound = $type->min_bound;
                $max_bound = $type->max_bound;
                if ($combination->ints) {
                    foreach ($combination->ints as $int) {
                        if (!$type->contains($int->value)) {
                            $min_bound = TIntRange::getNewLowestBound($min_bound, $int->value);
                            $max_bound = TIntRange::getNewHighestBound($max_bound, $int->value);
                        }
                    }
                    $type = new TIntRange($min_bound, $max_bound);
                    $combination->value_types['int'] = $type;
                } elseif (!isset($combination->value_types['int'])) {
                    $combination->value_types['int'] = $type;
                } else {
                    $old_type = $combination->value_types['int'];
                    if ($old_type instanceof TIntRange) {
                        $min_bound = TIntRange::getNewLowestBound($old_type->min_bound, $min_bound);
                        $max_bound = TIntRange::getNewHighestBound($old_type->max_bound, $max_bound);
                        $type = new TIntRange($min_bound, $max_bound);
                    } else {
                        $type = new TInt();
                    }
                    $combination->value_types['int'] = $type;
                }
            } else {
                $combination->value_types['int'] = $type;
            }
            $combination->ints = null;
        }
    }
    /**
     * @return array<string, bool>
     */
    private static function getSharedTypes(\Psalm\Internal\Type\TypeCombination $combination, Codebase $codebase) : array
    {
        /** @var array<string, bool>|null */
        $shared_classlikes = null;
        if ($combination->strings) {
            foreach ($combination->strings as $string_type) {
                $classlikes = self::getClassLikes($codebase, $string_type->value);
                if ($shared_classlikes === null) {
                    $shared_classlikes = $classlikes;
                } elseif ($shared_classlikes) {
                    $shared_classlikes = array_intersect_key($shared_classlikes, $classlikes);
                }
            }
        }
        if ($combination->class_string_types) {
            foreach ($combination->class_string_types as $value_type) {
                if ($value_type instanceof TNamedObject) {
                    $classlikes = self::getClassLikes($codebase, $value_type->value);
                    if ($shared_classlikes === null) {
                        $shared_classlikes = $classlikes;
                    } elseif ($shared_classlikes) {
                        $shared_classlikes = array_intersect_key($shared_classlikes, $classlikes);
                    }
                }
            }
        }
        return $shared_classlikes ?: [];
    }
    /**
     * @return array<string, true>
     */
    private static function getClassLikes(Codebase $codebase, string $fq_classlike_name) : array
    {
        try {
            $class_storage = $codebase->classlike_storage_provider->get($fq_classlike_name);
        } catch (InvalidArgumentException $e) {
            return [];
        }
        $classlikes = [];
        $classlikes[$fq_classlike_name] = \true;
        foreach ($class_storage->parent_classes as $parent_class) {
            $classlikes[$parent_class] = \true;
        }
        foreach ($class_storage->parent_interfaces as $parent_interface) {
            $classlikes[$parent_interface] = \true;
        }
        foreach ($class_storage->class_implements as $interface) {
            $classlikes[$interface] = \true;
        }
        return $classlikes;
    }
    /**
     * @return list<Atomic>
     */
    private static function handleKeyedArrayEntries(\Psalm\Internal\Type\TypeCombination $combination, bool $overwrite_empty_array, bool $from_docblock) : array
    {
        $new_types = [];
        if ($combination->array_type_params && $combination->array_type_params[0]->allStringLiterals() && $combination->array_always_filled) {
            foreach ($combination->array_type_params[0]->getAtomicTypes() as $atomic_key_type) {
                if ($atomic_key_type instanceof TLiteralString) {
                    $combination->objectlike_entries[$atomic_key_type->value] = $combination->array_type_params[1];
                }
            }
            $combination->array_type_params = [];
            $combination->objectlike_sealed = \false;
        }
        if (!$combination->array_type_params || $combination->array_type_params[1]->isNever()) {
            if (!$overwrite_empty_array && ($combination->array_type_params && ($combination->array_type_params[1]->isNever() || $combination->array_type_params[1]->isMixed()))) {
                foreach ($combination->objectlike_entries as &$objectlike_entry) {
                    $objectlike_entry = $objectlike_entry->setPossiblyUndefined(\true);
                }
                unset($objectlike_entry);
            }
            if ($combination->objectlike_value_type && $combination->objectlike_value_type->isMixed() && $combination->array_type_params && !$combination->array_type_params[1]->isNever()) {
                $combination->objectlike_entries = array_filter($combination->objectlike_entries, static fn(Union $type): bool => !$type->possibly_undefined);
            }
            if ($combination->objectlike_entries) {
                $fallback_key_type = null;
                if ($combination->objectlike_key_type) {
                    $fallback_key_type = $combination->objectlike_key_type;
                } elseif ($combination->array_type_params && $combination->array_type_params[0]->isArrayKey()) {
                    $fallback_key_type = $combination->array_type_params[0];
                }
                $fallback_value_type = null;
                if ($combination->objectlike_value_type) {
                    $fallback_value_type = $combination->objectlike_value_type;
                } elseif ($combination->array_type_params && $combination->array_type_params[1]->isMixed()) {
                    $fallback_value_type = $combination->array_type_params[1];
                }
                $sealed = $combination->objectlike_sealed && (!$combination->array_type_params || isset($combination->array_type_params[1]) && $combination->array_type_params[1]->isNever());
                if ($combination->all_arrays_callable) {
                    $objectlike = new TCallableKeyedArray($combination->objectlike_entries, null, $sealed || $fallback_key_type === null || $fallback_value_type === null ? null : [$fallback_key_type, $fallback_value_type], (bool) $combination->all_arrays_lists, $from_docblock);
                } else {
                    $objectlike = new TKeyedArray($combination->objectlike_entries, null, $sealed || $fallback_key_type === null || $fallback_value_type === null ? null : [$fallback_key_type, $fallback_value_type], (bool) $combination->all_arrays_lists, $from_docblock);
                }
                $new_types[] = $objectlike;
            } else {
                $key_type = $combination->objectlike_key_type ?? Type::getArrayKey();
                $value_type = $combination->objectlike_value_type ?? Type::getMixed();
                if ($combination->array_always_filled) {
                    $array_type = new TNonEmptyArray([$key_type, $value_type]);
                } else {
                    $array_type = new TArray([$key_type, $value_type]);
                }
                $new_types[] = $array_type->setFromDocblock($from_docblock);
            }
            // if we're merging an empty array with an object-like, clobber empty array
            $combination->array_type_params = [];
        }
        return $new_types;
    }
    /**
     * @param  array{Union, Union}  $generic_type_params
     */
    private static function getArrayTypeFromGenericParams(?Codebase $codebase, \Psalm\Internal\Type\TypeCombination $combination, bool $overwrite_empty_array, bool $allow_mixed_union, Atomic $type, array $generic_type_params, bool $from_docblock) : Atomic
    {
        if ($combination->objectlike_entries) {
            $objectlike_generic_type = null;
            $objectlike_keys = [];
            foreach ($combination->objectlike_entries as $property_name => $property_type) {
                $objectlike_generic_type = Type::combineUnionTypes($property_type, $objectlike_generic_type, $codebase, $overwrite_empty_array, \true, 500, \false);
                if (is_int($property_name)) {
                    $objectlike_keys[$property_name] = new TLiteralInt($property_name, $from_docblock);
                } elseif ($type instanceof TKeyedArray && isset($type->class_strings[$property_name])) {
                    $objectlike_keys[$property_name] = new TLiteralClassString($property_name, $from_docblock);
                } else {
                    $objectlike_keys[$property_name] = new TLiteralString($property_name, $from_docblock);
                }
            }
            if ($combination->objectlike_value_type) {
                $objectlike_generic_type = Type::combineUnionTypes($combination->objectlike_value_type, $objectlike_generic_type, $codebase, $overwrite_empty_array, \true, 500, \false);
            }
            $objectlike_key_type = new Union(array_values($objectlike_keys));
            $objectlike_key_type = Type::combineUnionTypes($combination->objectlike_key_type, $objectlike_key_type, $codebase, $overwrite_empty_array);
            $generic_type_params[0] = Type::combineUnionTypes($generic_type_params[0], $objectlike_key_type, $codebase, $overwrite_empty_array, $allow_mixed_union);
            if (!$generic_type_params[1]->isMixed()) {
                $generic_type_params[1] = Type::combineUnionTypes($generic_type_params[1], $objectlike_generic_type, $codebase, $overwrite_empty_array, $allow_mixed_union);
            }
        }
        if ($combination->all_arrays_callable) {
            $array_type = new TCallableArray($generic_type_params);
        } elseif ($combination->array_always_filled || $combination->array_sometimes_filled && $overwrite_empty_array || $combination->objectlike_entries && $combination->objectlike_sealed && ($combination->array_min_counts[0] ?? \false) !== \true && $overwrite_empty_array) {
            if ($combination->all_arrays_lists) {
                if ($combination->objectlike_entries && $combination->objectlike_sealed && isset($combination->array_type_params[1])) {
                    $array_type = new TKeyedArray([$generic_type_params[1]], null, [Type::getInt(), $combination->array_type_params[1]], \true);
                } elseif ($combination->array_counts && count($combination->array_counts) === 1) {
                    $cnt = array_keys($combination->array_counts)[0];
                    $properties = [];
                    for ($x = 0; $x < $cnt; $x++) {
                        $properties[] = $generic_type_params[1];
                    }
                    assert($properties !== []);
                    $array_type = new TKeyedArray($properties, null, null, \true);
                } else {
                    $cnt = $combination->array_min_counts ? min(array_keys($combination->array_min_counts)) : 0;
                    $properties = [];
                    for ($x = 0; $x < $cnt; $x++) {
                        $properties[] = $generic_type_params[1];
                    }
                    if (!$properties) {
                        $properties[] = $generic_type_params[1]->setPossiblyUndefined(\true);
                    }
                    $array_type = new TKeyedArray($properties, null, [Type::getListKey(), $generic_type_params[1]], \true);
                }
            } else {
                /** @psalm-suppress ArgumentTypeCoercion */
                $array_type = new TNonEmptyArray($generic_type_params, $combination->array_min_counts ? min(array_keys($combination->array_min_counts)) : null);
            }
        } else {
            if ($combination->all_arrays_class_string_maps && count($combination->class_string_map_as_types) === 1 && count($combination->class_string_map_names) === 1) {
                $array_type = new TClassStringMap(array_keys($combination->class_string_map_names)[0], array_values($combination->class_string_map_as_types)[0], $generic_type_params[1]);
            } elseif ($combination->all_arrays_lists) {
                $array_type = Type::getListAtomic($generic_type_params[1]);
            } else {
                $array_type = new TArray($generic_type_params);
            }
        }
        return $array_type->setFromDocblock($from_docblock);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Type;

use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Union;
/**
 * @internal
 */
class ArrayType
{
    public Union $key;
    public Union $value;
    public bool $is_list;
    public function __construct(Union $key, Union $value, bool $is_list)
    {
        $this->key = $key;
        $this->value = $value;
        $this->is_list = $is_list;
    }
    /**
     * @return (
     *     $type is TArrayKey ? self : (
     *         $type is TArray ? self : null
     *     )
     * )
     */
    public static function infer(Atomic $type) : ?self
    {
        if ($type instanceof TKeyedArray) {
            return new self($type->getGenericKeyType(), $type->getGenericValueType(), $type->is_list);
        }
        if ($type instanceof TArray) {
            return new self($type->type_params[0], $type->type_params[1], \false);
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class MethodTree extends ParseTree
{
    public string $value;
    public function __construct(string $value, ?ParseTree $parent = null)
    {
        $this->value = $value;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class TemplateIsTree extends ParseTree
{
    public string $param_name;
    public function __construct(string $param_name, ?ParseTree $parent = null)
    {
        $this->param_name = $param_name;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class Value extends ParseTree
{
    public string $value;
    public int $offset_start;
    public int $offset_end;
    public ?string $text = null;
    public function __construct(string $value, int $offset_start, int $offset_end, ?string $text, ParseTree $parent = null)
    {
        $this->offset_start = $offset_start;
        $this->offset_end = $offset_end;
        $this->value = $value;
        $this->parent = $parent;
        $this->text = $text === $value ? null : $text;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class UnionTree extends ParseTree
{
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class ConditionalTree extends ParseTree
{
    public \Psalm\Internal\Type\ParseTree\TemplateIsTree $condition;
    public function __construct(\Psalm\Internal\Type\ParseTree\TemplateIsTree $condition, ?ParseTree $parent = null)
    {
        $this->condition = $condition;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class EncapsulationTree extends ParseTree
{
    public bool $terminated = \false;
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class CallableParamTree extends ParseTree
{
    public bool $variadic = \false;
    public bool $has_default = \false;
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class IntersectionTree extends ParseTree
{
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class FieldEllipsis extends ParseTree
{
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class Root extends ParseTree
{
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class GenericTree extends ParseTree
{
    public string $value;
    public bool $terminated = \false;
    public function __construct(string $value, ?ParseTree $parent = null)
    {
        $this->value = $value;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class KeyedArrayTree extends ParseTree
{
    public string $value;
    public bool $terminated = \false;
    public function __construct(string $value, ?ParseTree $parent = null)
    {
        $this->value = $value;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class CallableWithReturnTypeTree extends ParseTree
{
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class NullableTree extends ParseTree
{
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class MethodWithReturnTypeTree extends ParseTree
{
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class MethodParamTree extends ParseTree
{
    public bool $variadic;
    public string $default = '';
    public bool $byref;
    public string $name;
    public function __construct(string $name, bool $byref, bool $variadic, ?ParseTree $parent = null)
    {
        $this->name = $name;
        $this->byref = $byref;
        $this->variadic = $variadic;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class TemplateAsTree extends ParseTree
{
    public string $param_name;
    public string $as;
    public function __construct(string $param_name, string $as, ?ParseTree $parent = null)
    {
        $this->param_name = $param_name;
        $this->as = $as;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class KeyedArrayPropertyTree extends ParseTree
{
    public string $value;
    public function __construct(string $value, ?ParseTree $parent = null)
    {
        $this->value = $value;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class CallableTree extends ParseTree
{
    public string $value;
    public bool $terminated = \false;
    public function __construct(string $value, ?ParseTree $parent = null)
    {
        $this->value = $value;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\ParseTree;

use Psalm\Internal\Type\ParseTree;
/**
 * @internal
 */
class IndexedAccessTree extends ParseTree
{
    public string $value;
    public function __construct(string $value, ?ParseTree $parent = null)
    {
        $this->value = $value;
        $this->parent = $parent;
    }
}
<?php

namespace Psalm\Internal\Type\TypeAlias;

use Psalm\Internal\Type\TypeAlias;
use Psalm\Type\Atomic;
/**
 * @internal
 */
class ClassTypeAlias implements TypeAlias
{
    /**
     * @var list<Atomic>
     */
    public array $replacement_atomic_types;
    /**
     * @param list<Atomic> $replacement_atomic_types
     */
    public function __construct(array $replacement_atomic_types)
    {
        $this->replacement_atomic_types = $replacement_atomic_types;
    }
}
<?php

namespace Psalm\Internal\Type\TypeAlias;

use Psalm\Internal\Type\TypeAlias;
use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class InlineTypeAlias implements TypeAlias
{
    use ImmutableNonCloneableTrait;
    /**
     * @var list<array{0: string, 1: int, 2?: string}>
     */
    public array $replacement_tokens;
    /**
     * @param list<array{0: string, 1: int, 2?: string}> $replacement_tokens
     */
    public function __construct(array $replacement_tokens)
    {
        $this->replacement_tokens = $replacement_tokens;
    }
}
<?php

namespace Psalm\Internal\Type\TypeAlias;

use Psalm\Internal\Type\TypeAlias;
use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class LinkableTypeAlias implements TypeAlias
{
    use ImmutableNonCloneableTrait;
    public string $declaring_fq_classlike_name;
    public string $alias_name;
    public int $line_number;
    public int $start_offset;
    public int $end_offset;
    public function __construct(string $declaring_fq_classlike_name, string $alias_name, int $line_number, int $start_offset, int $end_offset)
    {
        $this->declaring_fq_classlike_name = $declaring_fq_classlike_name;
        $this->alias_name = $alias_name;
        $this->line_number = $line_number;
        $this->start_offset = $start_offset;
        $this->end_offset = $end_offset;
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\Type\Union;
/**
 * This class captures the result of running Psalm's argument analysis with
 * regard to generic parameters.
 *
 * It captures upper and lower bounds for parameters. Mostly we just care about
 * lower bounds — those are captured when calling a function that expects a
 * non-callable templated argument.
 *
 * Upper bounds are found in callable parameter types. Given a parameter type
 * `callable(T1): void` and an argument typed as `callable(int): void`, `int` will
 * be added as an _upper_ bound for the template param `T1`. This only applies to
 * parameters — given a parameter type `callable(): T2` and an argument typed as
 * `callable(): string`, `string` will be added as a _lower_ bound for the template
 * param `T2`.
 *
 * @internal
 */
class TemplateResult
{
    /**
     * @var array<string, array<string, Union>>
     */
    public array $template_types;
    /**
     * @var array<string, array<string, non-empty-list<TemplateBound>>>
     */
    public array $lower_bounds;
    /**
     * @var array<string, array<string, TemplateBound>>
     */
    public array $upper_bounds = [];
    /**
     * If set to true then we shouldn't update the template bounds
     */
    public bool $readonly = \false;
    /**
     * @var list<Union>
     */
    public array $upper_bounds_unintersectable_types = [];
    /**
     * @param  array<string, array<string, Union>> $template_types
     * @param  array<string, array<string, Union>> $lower_bounds
     */
    public function __construct(array $template_types, array $lower_bounds)
    {
        $this->template_types = $template_types;
        $this->lower_bounds = [];
        foreach ($lower_bounds as $key1 => $boundSet) {
            foreach ($boundSet as $key2 => $bound) {
                $this->lower_bounds[$key1][$key2] = [new \Psalm\Internal\Type\TemplateBound($bound)];
            }
        }
    }
}
<?php

namespace Psalm\Internal\Type;

/**
 * @internal
 */
class ParseTree
{
    /**
     * @var list<ParseTree>
     */
    public array $children = [];
    public ?\Psalm\Internal\Type\ParseTree $parent = null;
    public bool $possibly_undefined = \false;
    public function __construct(?\Psalm\Internal\Type\ParseTree $parent = null)
    {
        $this->parent = $parent;
    }
    public function __destruct()
    {
        $this->parent = null;
    }
    public function cleanParents() : void
    {
        foreach ($this->children as $child) {
            $child->cleanParents();
        }
        $this->parent = null;
    }
}
<?php

namespace Psalm\Internal\Type;

interface TypeAlias
{
}
<?php

namespace Psalm\Internal\Type;

use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Type\ParseTree\CallableParamTree;
use Psalm\Internal\Type\ParseTree\CallableTree;
use Psalm\Internal\Type\ParseTree\CallableWithReturnTypeTree;
use Psalm\Internal\Type\ParseTree\ConditionalTree;
use Psalm\Internal\Type\ParseTree\EncapsulationTree;
use Psalm\Internal\Type\ParseTree\FieldEllipsis;
use Psalm\Internal\Type\ParseTree\GenericTree;
use Psalm\Internal\Type\ParseTree\IndexedAccessTree;
use Psalm\Internal\Type\ParseTree\IntersectionTree;
use Psalm\Internal\Type\ParseTree\KeyedArrayPropertyTree;
use Psalm\Internal\Type\ParseTree\KeyedArrayTree;
use Psalm\Internal\Type\ParseTree\MethodParamTree;
use Psalm\Internal\Type\ParseTree\MethodTree;
use Psalm\Internal\Type\ParseTree\MethodWithReturnTypeTree;
use Psalm\Internal\Type\ParseTree\NullableTree;
use Psalm\Internal\Type\ParseTree\Root;
use Psalm\Internal\Type\ParseTree\TemplateAsTree;
use Psalm\Internal\Type\ParseTree\TemplateIsTree;
use Psalm\Internal\Type\ParseTree\UnionTree;
use Psalm\Internal\Type\ParseTree\Value;
use function array_pop;
use function count;
use function in_array;
use function preg_match;
use function strlen;
use function strtolower;
/**
 * @internal
 */
class ParseTreeCreator
{
    private \Psalm\Internal\Type\ParseTree $parse_tree;
    private \Psalm\Internal\Type\ParseTree $current_leaf;
    /** @var array<int, array{0: string, 1: int, 2?: string}> */
    private array $type_tokens;
    private int $type_token_count;
    private int $t = 0;
    /**
     * @param list<array{0: string, 1: int, 2?: string}> $type_tokens
     */
    public function __construct(array $type_tokens)
    {
        $this->type_tokens = $type_tokens;
        $this->type_token_count = count($type_tokens);
        $this->parse_tree = new Root();
        $this->current_leaf = $this->parse_tree;
    }
    public function create() : \Psalm\Internal\Type\ParseTree
    {
        while ($this->t < $this->type_token_count) {
            $type_token = $this->type_tokens[$this->t];
            switch ($type_token[0]) {
                case '<':
                case '{':
                case ']':
                    throw new TypeParseTreeException('Unexpected token ' . $type_token[0]);
                case '[':
                    $this->handleOpenSquareBracket();
                    break;
                case '(':
                    $this->handleOpenRoundBracket();
                    break;
                case ')':
                    $this->handleClosedRoundBracket();
                    break;
                case '>':
                    do {
                        if ($this->current_leaf->parent === null) {
                            throw new TypeParseTreeException('Cannot parse generic type');
                        }
                        $this->current_leaf = $this->current_leaf->parent;
                    } while (!$this->current_leaf instanceof GenericTree);
                    $this->current_leaf->terminated = \true;
                    break;
                case '}':
                    do {
                        if ($this->current_leaf->parent === null) {
                            throw new TypeParseTreeException('Cannot parse array type');
                        }
                        $this->current_leaf = $this->current_leaf->parent;
                    } while (!$this->current_leaf instanceof KeyedArrayTree);
                    $this->current_leaf->terminated = \true;
                    break;
                case ',':
                    $this->handleComma();
                    break;
                case '...':
                case '=':
                    $this->handleEllipsisOrEquals($type_token);
                    break;
                case ':':
                    $this->handleColon();
                    break;
                case ' ':
                    $this->handleSpace();
                    break;
                case '?':
                    $this->handleQuestionMark();
                    break;
                case '|':
                    $this->handleBar();
                    break;
                case '&':
                    $this->handleAmpersand();
                    break;
                case 'is':
                case 'as':
                    $this->handleIsOrAs($type_token);
                    break;
                default:
                    $this->handleValue($type_token);
                    break;
            }
            $this->t++;
        }
        $this->parse_tree->cleanParents();
        if ($this->current_leaf !== $this->parse_tree && ($this->parse_tree instanceof GenericTree || $this->parse_tree instanceof CallableTree || $this->parse_tree instanceof KeyedArrayTree)) {
            throw new TypeParseTreeException('Unterminated bracket');
        }
        return $this->parse_tree;
    }
    /**
     * @param  array{0: string, 1: int, 2?: string} $current_token
     */
    private function createMethodParam(array $current_token, \Psalm\Internal\Type\ParseTree $current_parent) : void
    {
        $byref = \false;
        $variadic = \false;
        $has_default = \false;
        $default = '';
        if ($current_token[0] === '&') {
            $byref = \true;
            ++$this->t;
            $current_token = $this->t < $this->type_token_count ? $this->type_tokens[$this->t] : null;
        } elseif ($current_token[0] === '...') {
            $variadic = \true;
            ++$this->t;
            $current_token = $this->t < $this->type_token_count ? $this->type_tokens[$this->t] : null;
        }
        if (!$current_token || $current_token[0][0] !== '$') {
            throw new TypeParseTreeException('Unexpected token after space');
        }
        $new_parent_leaf = new MethodParamTree($current_token[0], $byref, $variadic, $current_parent);
        for ($j = $this->t + 1; $j < $this->type_token_count; ++$j) {
            $ahead_type_token = $this->type_tokens[$j];
            if ($ahead_type_token[0] === ',' || $ahead_type_token[0] === ')' && $this->type_tokens[$j - 1][0] !== '(') {
                $this->t = $j - 1;
                break;
            }
            if ($has_default) {
                $default .= $ahead_type_token[0];
            }
            if ($ahead_type_token[0] === '=') {
                $has_default = \true;
                continue;
            }
            if ($j === $this->type_token_count - 1) {
                throw new TypeParseTreeException('Unterminated method');
            }
        }
        $new_parent_leaf->default = $default;
        if ($this->current_leaf !== $current_parent) {
            $new_parent_leaf->children = [$this->current_leaf];
            array_pop($current_parent->children);
        }
        $current_parent->children[] = $new_parent_leaf;
        $this->current_leaf = $new_parent_leaf;
    }
    private function handleOpenSquareBracket() : void
    {
        if ($this->current_leaf instanceof Root) {
            throw new TypeParseTreeException('Unexpected token [');
        }
        $indexed_access = \false;
        $next_token = $this->t + 1 < $this->type_token_count ? $this->type_tokens[$this->t + 1] : null;
        if (!$next_token || $next_token[0] !== ']') {
            $next_next_token = $this->t + 2 < $this->type_token_count ? $this->type_tokens[$this->t + 2] : null;
            if ($next_next_token !== null && $next_next_token[0] === ']') {
                $indexed_access = \true;
                ++$this->t;
            } else {
                throw new TypeParseTreeException('Unexpected token [');
            }
        }
        $current_parent = $this->current_leaf->parent;
        if ($indexed_access) {
            if ($next_token === null) {
                throw new TypeParseTreeException('Unexpected token [');
            }
            $new_parent_leaf = new IndexedAccessTree($next_token[0], $current_parent);
        } else {
            if ($this->current_leaf instanceof KeyedArrayPropertyTree) {
                throw new TypeParseTreeException('Unexpected token [');
            }
            $new_parent_leaf = new GenericTree('array', $current_parent);
        }
        $this->current_leaf->parent = $new_parent_leaf;
        $new_parent_leaf->children = [$this->current_leaf];
        if ($current_parent) {
            array_pop($current_parent->children);
            $current_parent->children[] = $new_parent_leaf;
        } else {
            $this->parse_tree = $new_parent_leaf;
        }
        $this->current_leaf = $new_parent_leaf;
        ++$this->t;
    }
    private function handleOpenRoundBracket() : void
    {
        if ($this->current_leaf instanceof Value) {
            throw new TypeParseTreeException('Unrecognised token (');
        }
        $new_parent = !$this->current_leaf instanceof Root ? $this->current_leaf : null;
        $new_leaf = new EncapsulationTree($new_parent);
        if ($this->current_leaf instanceof Root) {
            $this->current_leaf = $this->parse_tree = $new_leaf;
            return;
        }
        if ($new_leaf->parent) {
            $new_leaf->parent->children[] = $new_leaf;
        }
        $this->current_leaf = $new_leaf;
    }
    private function handleClosedRoundBracket() : void
    {
        $prev_token = $this->t > 0 ? $this->type_tokens[$this->t - 1] : null;
        if ($prev_token !== null && $prev_token[0] === '(' && $this->current_leaf instanceof CallableTree) {
            return;
        }
        do {
            if ($this->current_leaf->parent === null) {
                break;
            }
            $this->current_leaf = $this->current_leaf->parent;
        } while (!$this->current_leaf instanceof EncapsulationTree && !$this->current_leaf instanceof CallableTree && !$this->current_leaf instanceof MethodTree);
        if ($this->current_leaf instanceof EncapsulationTree || $this->current_leaf instanceof CallableTree) {
            $this->current_leaf->terminated = \true;
        }
    }
    private function handleComma() : void
    {
        if ($this->current_leaf instanceof Root) {
            throw new TypeParseTreeException('Unexpected token ,');
        }
        if (!$this->current_leaf->parent) {
            throw new TypeParseTreeException('Cannot parse comma without a parent node');
        }
        $context_node = $this->current_leaf;
        if ($context_node instanceof GenericTree || $context_node instanceof KeyedArrayTree || $context_node instanceof CallableTree || $context_node instanceof MethodTree) {
            $context_node = $context_node->parent;
        }
        while ($context_node && !$context_node instanceof GenericTree && !$context_node instanceof KeyedArrayTree && !$context_node instanceof CallableTree && !$context_node instanceof MethodTree) {
            $context_node = $context_node->parent;
        }
        if (!$context_node) {
            throw new TypeParseTreeException('Cannot parse comma in non-generic/array type');
        }
        $this->current_leaf = $context_node;
    }
    /** @param array{0: string, 1: int, 2?: string} $type_token */
    private function handleEllipsisOrEquals(array $type_token) : void
    {
        $prev_token = $this->t > 0 ? $this->type_tokens[$this->t - 1] : null;
        if ($prev_token && ($prev_token[0] === '...' || $prev_token[0] === '=')) {
            throw new TypeParseTreeException('Cannot have duplicate tokens');
        }
        $current_parent = $this->current_leaf->parent;
        if ($this->current_leaf instanceof MethodTree && $type_token[0] === '...') {
            $this->createMethodParam($type_token, $this->current_leaf);
            return;
        }
        if ($this->current_leaf instanceof KeyedArrayTree && $type_token[0] === '...') {
            $leaf = new FieldEllipsis($this->current_leaf);
            $this->current_leaf->children[] = $leaf;
            $this->current_leaf = $leaf;
            return;
        }
        while ($current_parent && !$current_parent instanceof CallableTree && !$current_parent instanceof CallableParamTree) {
            $this->current_leaf = $current_parent;
            $current_parent = $current_parent->parent;
        }
        if (!$current_parent) {
            if ($type_token[0] === '...') {
                if ($this->current_leaf instanceof CallableTree) {
                    $current_parent = $this->current_leaf;
                } else {
                    throw new TypeParseTreeException('Unexpected token ' . $type_token[0]);
                }
            } else {
                throw new TypeParseTreeException('Unexpected token ' . $type_token[0]);
            }
        }
        if ($current_parent instanceof CallableParamTree) {
            throw new TypeParseTreeException('Cannot have variadic param with a default');
        }
        $new_leaf = new CallableParamTree($current_parent);
        $new_leaf->has_default = $type_token[0] === '=';
        $new_leaf->variadic = $type_token[0] === '...';
        if ($current_parent !== $this->current_leaf) {
            $new_leaf->children = [$this->current_leaf];
            array_pop($current_parent->children);
        }
        $current_parent->children[] = $new_leaf;
        $this->current_leaf = $new_leaf;
    }
    private function handleColon() : void
    {
        if ($this->current_leaf instanceof Root) {
            throw new TypeParseTreeException('Unexpected token :');
        }
        $current_parent = $this->current_leaf->parent;
        if ($this->current_leaf instanceof CallableTree) {
            $new_parent_leaf = new CallableWithReturnTypeTree($current_parent);
            $this->current_leaf->parent = $new_parent_leaf;
            $new_parent_leaf->children = [$this->current_leaf];
            if ($current_parent) {
                array_pop($current_parent->children);
                $current_parent->children[] = $new_parent_leaf;
            } else {
                $this->parse_tree = $new_parent_leaf;
            }
            $this->current_leaf = $new_parent_leaf;
            return;
        }
        if ($this->current_leaf instanceof MethodTree) {
            $new_parent_leaf = new MethodWithReturnTypeTree($current_parent);
            $this->current_leaf->parent = $new_parent_leaf;
            $new_parent_leaf->children = [$this->current_leaf];
            if ($current_parent) {
                array_pop($current_parent->children);
                $current_parent->children[] = $new_parent_leaf;
            } else {
                $this->parse_tree = $new_parent_leaf;
            }
            $this->current_leaf = $new_parent_leaf;
            return;
        }
        if ($current_parent instanceof KeyedArrayPropertyTree) {
            return;
        }
        while (($current_parent instanceof UnionTree || $current_parent instanceof CallableWithReturnTypeTree) && $this->current_leaf->parent) {
            $this->current_leaf = $this->current_leaf->parent;
            $current_parent = $this->current_leaf->parent;
        }
        if ($current_parent instanceof ConditionalTree) {
            if (count($current_parent->children) > 1) {
                throw new TypeParseTreeException('Cannot process colon in conditional twice');
            }
            $this->current_leaf = $current_parent;
            return;
        }
        if (!$current_parent) {
            throw new TypeParseTreeException('Cannot process colon without parent');
        }
        if (!$this->current_leaf instanceof Value) {
            throw new TypeParseTreeException('Unexpected LHS of property');
        }
        if (!$current_parent instanceof KeyedArrayTree) {
            throw new TypeParseTreeException('Saw : outside of object-like array');
        }
        $prev_token = $this->t > 0 ? $this->type_tokens[$this->t - 1] : null;
        $new_parent_leaf = new KeyedArrayPropertyTree($this->current_leaf->value, $current_parent);
        $new_parent_leaf->possibly_undefined = $prev_token !== null && $prev_token[0] === '?';
        array_pop($current_parent->children);
        $current_parent->children[] = $new_parent_leaf;
        $this->current_leaf = $new_parent_leaf;
    }
    private function handleSpace() : void
    {
        if ($this->current_leaf instanceof Root) {
            throw new TypeParseTreeException('Unexpected space');
        }
        if ($this->current_leaf instanceof KeyedArrayTree) {
            return;
        }
        $current_parent = $this->current_leaf->parent;
        if ($current_parent instanceof CallableTree) {
            return;
        }
        while ($current_parent && !$current_parent instanceof MethodTree) {
            $this->current_leaf = $current_parent;
            $current_parent = $current_parent->parent;
        }
        $next_token = $this->t + 1 < $this->type_token_count ? $this->type_tokens[$this->t + 1] : null;
        if (!$current_parent instanceof MethodTree || !$next_token) {
            throw new TypeParseTreeException('Unexpected space');
        }
        ++$this->t;
        $this->createMethodParam($next_token, $current_parent);
    }
    private function handleQuestionMark() : void
    {
        $next_token = $this->t + 1 < $this->type_token_count ? $this->type_tokens[$this->t + 1] : null;
        if ($next_token === null || $next_token[0] !== ':') {
            while (($this->current_leaf instanceof Value || $this->current_leaf instanceof UnionTree || $this->current_leaf instanceof KeyedArrayTree && $this->current_leaf->terminated || $this->current_leaf instanceof GenericTree && $this->current_leaf->terminated || $this->current_leaf instanceof EncapsulationTree && $this->current_leaf->terminated || $this->current_leaf instanceof CallableTree && $this->current_leaf->terminated || $this->current_leaf instanceof IntersectionTree) && $this->current_leaf->parent) {
                $this->current_leaf = $this->current_leaf->parent;
            }
            if ($this->current_leaf instanceof TemplateIsTree && $this->current_leaf->parent) {
                $current_parent = $this->current_leaf->parent;
                $new_leaf = new ConditionalTree($this->current_leaf, $this->current_leaf->parent);
                array_pop($current_parent->children);
                $current_parent->children[] = $new_leaf;
                $this->current_leaf = $new_leaf;
            } else {
                $new_parent = !$this->current_leaf instanceof Root ? $this->current_leaf : null;
                if (!$next_token) {
                    throw new TypeParseTreeException('Unexpected token ?');
                }
                $new_leaf = new NullableTree($new_parent);
                if ($this->current_leaf instanceof Root) {
                    $this->current_leaf = $this->parse_tree = $new_leaf;
                    return;
                }
                if ($new_leaf->parent) {
                    $new_leaf->parent->children[] = $new_leaf;
                }
                $this->current_leaf = $new_leaf;
            }
        }
    }
    private function handleBar() : void
    {
        if ($this->current_leaf instanceof Root) {
            throw new TypeParseTreeException('Unexpected token |');
        }
        $current_parent = $this->current_leaf->parent;
        if ($current_parent instanceof CallableWithReturnTypeTree) {
            $this->current_leaf = $current_parent;
            $current_parent = $current_parent->parent;
        }
        if ($current_parent instanceof NullableTree) {
            $this->current_leaf = $current_parent;
            $current_parent = $current_parent->parent;
        }
        if ($this->current_leaf instanceof UnionTree) {
            throw new TypeParseTreeException('Unexpected token |');
        }
        if ($current_parent instanceof UnionTree) {
            $this->current_leaf = $current_parent;
            return;
        }
        if ($current_parent instanceof IntersectionTree) {
            $this->current_leaf = $current_parent;
            $current_parent = $this->current_leaf->parent;
        }
        if ($current_parent instanceof TemplateIsTree) {
            $new_parent_leaf = new UnionTree($this->current_leaf);
            $new_parent_leaf->children = [$this->current_leaf];
            $new_parent_leaf->parent = $current_parent;
        } else {
            $new_parent_leaf = new UnionTree($current_parent);
            $new_parent_leaf->children = [$this->current_leaf];
        }
        if ($current_parent) {
            array_pop($current_parent->children);
            $current_parent->children[] = $new_parent_leaf;
        } else {
            $this->parse_tree = $new_parent_leaf;
        }
        $this->current_leaf = $new_parent_leaf;
    }
    private function handleAmpersand() : void
    {
        if ($this->current_leaf instanceof Root) {
            throw new TypeParseTreeException('Unexpected &');
        }
        $current_parent = $this->current_leaf->parent;
        if ($current_parent instanceof MethodTree) {
            $this->createMethodParam($this->type_tokens[$this->t], $current_parent);
            return;
        }
        if ($current_parent instanceof IntersectionTree) {
            $this->current_leaf = $current_parent;
            return;
        }
        $new_parent_leaf = new IntersectionTree($current_parent);
        $new_parent_leaf->children = [$this->current_leaf];
        if ($current_parent) {
            array_pop($current_parent->children);
            $current_parent->children[] = $new_parent_leaf;
        } else {
            $this->parse_tree = $new_parent_leaf;
        }
        $this->current_leaf = $new_parent_leaf;
    }
    /** @param array{0: string, 1: int, 2?: string} $type_token */
    private function handleIsOrAs(array $type_token) : void
    {
        if ($this->t === 0) {
            $this->handleValue($type_token);
        } else {
            $current_parent = $this->current_leaf->parent;
            if ($current_parent) {
                array_pop($current_parent->children);
            }
            if ($type_token[0] === 'as') {
                $next_token = $this->t + 1 < $this->type_token_count ? $this->type_tokens[$this->t + 1] : null;
                if (!$this->current_leaf instanceof Value || !$current_parent instanceof GenericTree || !$next_token) {
                    throw new TypeParseTreeException('Unexpected token ' . $type_token[0]);
                }
                $this->current_leaf = new TemplateAsTree($this->current_leaf->value, $next_token[0], $current_parent);
                $current_parent->children[] = $this->current_leaf;
                ++$this->t;
            } elseif ($this->current_leaf instanceof Value) {
                $this->current_leaf = new TemplateIsTree($this->current_leaf->value, $current_parent);
                if ($current_parent) {
                    $current_parent->children[] = $this->current_leaf;
                }
            }
        }
    }
    /** @param array{0: string, 1: int, 2?: string} $type_token */
    private function handleValue(array $type_token) : void
    {
        $new_parent = !$this->current_leaf instanceof Root ? $this->current_leaf : null;
        if ($this->current_leaf instanceof MethodTree && $type_token[0][0] === '$') {
            $this->createMethodParam($type_token, $this->current_leaf);
            return;
        }
        $next_token = $this->t + 1 < $this->type_token_count ? $this->type_tokens[$this->t + 1] : null;
        switch ($next_token[0] ?? null) {
            case '<':
                $new_leaf = new GenericTree($type_token[0], $new_parent);
                ++$this->t;
                break;
            case '{':
                $new_leaf = new KeyedArrayTree($type_token[0], $new_parent);
                ++$this->t;
                $nexter_token = $this->t + 1 < $this->type_token_count ? $this->type_tokens[$this->t + 1] : null;
                if ($nexter_token !== null && $nexter_token[0] === '}') {
                    $new_leaf->terminated = \true;
                    ++$this->t;
                } elseif ($nexter_token === null) {
                    throw new TypeParseTreeException('Unclosed bracket in keyed array');
                }
                break;
            case '(':
                if (in_array($type_token[0], ['callable', 'pure-callable', 'Closure', '\\Closure', 'pure-Closure'], \true)) {
                    $new_leaf = new CallableTree($type_token[0], $new_parent);
                } elseif ($type_token[0] !== 'array' && $type_token[0][0] !== '\\' && $this->current_leaf instanceof Root) {
                    $new_leaf = new MethodTree($type_token[0], $new_parent);
                } else {
                    throw new TypeParseTreeException('Parenthesis must be preceded by “Closure”, “callable”, "pure-callable" or a valid @method' . ' name');
                }
                ++$this->t;
                break;
            case '::':
                $nexter_token = $this->t + 2 < $this->type_token_count ? $this->type_tokens[$this->t + 2] : null;
                if ($this->current_leaf instanceof \Psalm\Internal\Type\ParseTree\KeyedArrayTree && $nexter_token && strtolower($nexter_token[0]) !== 'class') {
                    throw new TypeParseTreeException(':: in array key is only allowed for ::class');
                }
                if (!$nexter_token || !preg_match('/^([a-zA-Z_][a-zA-Z_0-9]*\\*?|\\*)$/', $nexter_token[0]) && strtolower($nexter_token[0]) !== 'class') {
                    throw new TypeParseTreeException('Invalid class constant ' . ($nexter_token[0] ?? '<empty>'));
                }
                $new_leaf = new Value($type_token[0] . '::' . $nexter_token[0], $type_token[1], $type_token[1] + 2 + strlen($nexter_token[0]), $type_token[2] ?? null, $new_parent);
                $this->t += 2;
                break;
            default:
                if ($type_token[0] === '$this') {
                    $type_token[0] = 'static';
                }
                $new_leaf = new Value($type_token[0], $type_token[1], $type_token[1] + strlen($type_token[0]), $type_token[2] ?? null, $new_parent);
                break;
        }
        if ($this->current_leaf instanceof Root) {
            $this->current_leaf = $this->parse_tree = $new_leaf;
            return;
        }
        if ($new_leaf->parent) {
            $new_leaf->parent->children[] = $new_leaf;
        }
        $this->current_leaf = $new_leaf;
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\Type\Union;
/**
 * @internal
 */
class TemplateBound
{
    public Union $type;
    /**
     * This is the depth at which the template appears in a given type.
     *
     * In the type Foo<T, Bar<T, array<T>>> the type T appears at three different depths.
     *
     * The shallowest-appearance of the template takes prominence when inferring the type of T.
     */
    public int $appearance_depth;
    /**
     * The argument offset where this template was set
     *
     * In the type Foo<T, string, T> the type appears at argument offsets 0 and 2
     */
    public ?int $arg_offset = null;
    /**
     * When non-null, indicates an equality template bound (vs a lower or upper bound)
     */
    public ?string $equality_bound_classlike = null;
    public function __construct(Union $type, int $appearance_depth = 0, ?int $arg_offset = null, ?string $equality_bound_classlike = null)
    {
        $this->type = $type;
        $this->appearance_depth = $appearance_depth;
        $this->arg_offset = $arg_offset;
        $this->equality_bound_classlike = $equality_bound_classlike;
    }
}
<?php

namespace Psalm\Internal\Type;

use Psalm\Codebase;
use Psalm\Exception\CircularReferenceException;
use Psalm\Exception\UnresolvableConstantException;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\AtomicPropertyFetchAnalyzer;
use Psalm\Internal\Type\SimpleAssertionReconciler;
use Psalm\Internal\Type\SimpleNegatedAssertionReconciler;
use Psalm\Internal\Type\TypeParser;
use Psalm\Storage\Assertion\IsType;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntMask;
use Psalm\Type\Atomic\TIntMaskOf;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyOf;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TPropertiesOf;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTypeAlias;
use Psalm\Type\Atomic\TValueOf;
use Psalm\Type\Atomic\TVoid;
use Psalm\Type\Union;
use ReflectionProperty;
use function array_filter;
use function array_keys;
use function array_map;
use function array_merge;
use function array_values;
use function count;
use function get_class;
use function is_string;
use function reset;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class TypeExpander
{
    /**
     * @psalm-suppress InaccessibleProperty We just created the type
     * @param string|TNamedObject|TTemplateParam|null $static_class_type
     */
    public static function expandUnion(Codebase $codebase, Union $return_type, ?string $self_class, $static_class_type, ?string $parent_class, bool $evaluate_class_constants = \true, bool $evaluate_conditional_types = \false, bool $final = \false, bool $expand_generic = \false, bool $expand_templates = \false, bool $throw_on_unresolvable_constant = \false) : Union
    {
        $new_return_type_parts = [];
        $had_split_values = \false;
        foreach ($return_type->getAtomicTypes() as $return_type_part) {
            $parts = self::expandAtomic($codebase, $return_type_part, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
            if ($return_type_part instanceof TTypeAlias || count($parts) > 1) {
                $had_split_values = \true;
            }
            $new_return_type_parts = [...$new_return_type_parts, ...$parts];
        }
        if ($had_split_values) {
            $fleshed_out_type = \Psalm\Internal\Type\TypeCombiner::combine($new_return_type_parts, $codebase);
        } else {
            $fleshed_out_type = new Union($new_return_type_parts);
        }
        $fleshed_out_type->from_docblock = $return_type->from_docblock;
        $fleshed_out_type->ignore_nullable_issues = $return_type->ignore_nullable_issues;
        $fleshed_out_type->ignore_falsable_issues = $return_type->ignore_falsable_issues;
        $fleshed_out_type->possibly_undefined = $return_type->possibly_undefined;
        $fleshed_out_type->possibly_undefined_from_try = $return_type->possibly_undefined_from_try;
        $fleshed_out_type->by_ref = $return_type->by_ref;
        $fleshed_out_type->initialized = $return_type->initialized;
        $fleshed_out_type->from_property = $return_type->from_property;
        $fleshed_out_type->from_static_property = $return_type->from_static_property;
        $fleshed_out_type->explicit_never = $return_type->explicit_never;
        $fleshed_out_type->had_template = $return_type->had_template;
        $fleshed_out_type->parent_nodes = $return_type->parent_nodes;
        return $fleshed_out_type;
    }
    /**
     * @param string|TNamedObject|TTemplateParam|null $static_class_type
     * @param-out Atomic $return_type
     * @return non-empty-list<Atomic>
     * @psalm-suppress ConflictingReferenceConstraint, ReferenceConstraintViolation The output type is always Atomic
     * @psalm-suppress ComplexMethod
     */
    public static function expandAtomic(Codebase $codebase, Atomic &$return_type, ?string $self_class, $static_class_type, ?string $parent_class, bool $evaluate_class_constants = \true, bool $evaluate_conditional_types = \false, bool $final = \false, bool $expand_generic = \false, bool $expand_templates = \false, bool $throw_on_unresolvable_constant = \false) : array
    {
        if ($return_type instanceof TNamedObject || $return_type instanceof TTemplateParam) {
            if ($return_type->extra_types) {
                $new_intersection_types = [];
                $extra_types = [];
                foreach ($return_type->extra_types as $extra_type) {
                    self::expandAtomic($codebase, $extra_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                    if ($extra_type instanceof TNamedObject && $extra_type->extra_types) {
                        $new_intersection_types = array_merge($new_intersection_types, $extra_type->extra_types);
                        $extra_type = $extra_type->setIntersectionTypes([]);
                    }
                    $extra_types[$extra_type->getKey()] = $extra_type;
                }
                /** @psalm-suppress ArgumentTypeCoercion */
                $return_type = $return_type->setIntersectionTypes(array_merge($extra_types, $new_intersection_types));
            }
            if ($return_type instanceof TNamedObject) {
                $return_type = self::expandNamedObject($codebase, $return_type, $self_class, $static_class_type, $parent_class, $final, $expand_generic);
            }
        }
        if ($return_type instanceof TClassString && $return_type->as_type) {
            $new_as_type = $return_type->as_type;
            self::expandAtomic($codebase, $new_as_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
            if ($new_as_type instanceof TNamedObject && $new_as_type !== $return_type->as_type) {
                $return_type = $return_type->setAs($new_as_type->value, $new_as_type);
            }
        } elseif ($return_type instanceof TTemplateParam) {
            $new_as_type = self::expandUnion($codebase, $return_type->as, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
            if ($expand_templates) {
                return array_values($new_as_type->getAtomicTypes());
            }
            $return_type = $return_type->replaceAs($new_as_type);
        }
        if ($return_type instanceof TClassConstant) {
            if ($self_class) {
                $return_type = $return_type->replaceClassLike('self', $self_class);
            }
            if (is_string($static_class_type) || $self_class) {
                $return_type = $return_type->replaceClassLike('static', is_string($static_class_type) ? $static_class_type : $self_class);
            }
            if ($evaluate_class_constants && $codebase->classOrInterfaceOrEnumExists($return_type->fq_classlike_name)) {
                if (strtolower($return_type->const_name) === 'class') {
                    return [new TLiteralClassString($return_type->fq_classlike_name)];
                }
                $class_storage = $codebase->classlike_storage_provider->get($return_type->fq_classlike_name);
                if (strpos($return_type->const_name, '*') !== \false) {
                    $matching_constants = [...array_keys($class_storage->constants), ...array_keys($class_storage->enum_cases)];
                    $const_name_part = substr($return_type->const_name, 0, -1);
                    if ($const_name_part) {
                        $matching_constants = array_filter($matching_constants, static fn($constant_name): bool => $constant_name !== $const_name_part && strpos($constant_name, $const_name_part) === 0);
                    }
                } else {
                    $matching_constants = [$return_type->const_name];
                }
                $matching_constant_types = [];
                foreach ($matching_constants as $matching_constant) {
                    try {
                        $class_constant = $codebase->classlikes->getClassConstantType($return_type->fq_classlike_name, $matching_constant, ReflectionProperty::IS_PRIVATE);
                    } catch (CircularReferenceException $e) {
                        $class_constant = null;
                    }
                    if ($class_constant) {
                        if ($class_constant->isSingle()) {
                            $matching_constant_types = array_merge(array_values($class_constant->getAtomicTypes()), $matching_constant_types);
                        }
                    }
                }
                if ($matching_constant_types) {
                    return $matching_constant_types;
                }
            }
            return [$return_type];
        }
        if ($return_type instanceof TPropertiesOf) {
            return self::expandPropertiesOf($codebase, $return_type, $self_class, $static_class_type);
        }
        if ($return_type instanceof TTypeAlias) {
            $declaring_fq_classlike_name = $return_type->declaring_fq_classlike_name;
            if ($declaring_fq_classlike_name === 'self' && $self_class) {
                $declaring_fq_classlike_name = $self_class;
            }
            if (!($evaluate_class_constants && $codebase->classOrInterfaceExists($declaring_fq_classlike_name))) {
                return [$return_type];
            }
            $class_storage = $codebase->classlike_storage_provider->get($declaring_fq_classlike_name);
            $type_alias_name = $return_type->alias_name;
            if (!isset($class_storage->type_aliases[$type_alias_name])) {
                return [$return_type];
            }
            $resolved_type_alias = $class_storage->type_aliases[$type_alias_name];
            $replacement_atomic_types = $resolved_type_alias->replacement_atomic_types;
            if (!$replacement_atomic_types) {
                return [$return_type];
            }
            $recursively_fleshed_out_types = [];
            foreach ($replacement_atomic_types as $replacement_atomic_type) {
                $more_recursively_fleshed_out_types = self::expandAtomic($codebase, $replacement_atomic_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                $recursively_fleshed_out_types = [...$more_recursively_fleshed_out_types, ...$recursively_fleshed_out_types];
            }
            foreach ($return_type->extra_types ?? [] as $alias) {
                $more_recursively_fleshed_out_types = self::expandAtomic($codebase, $alias, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                $recursively_fleshed_out_types = [...$more_recursively_fleshed_out_types, ...$recursively_fleshed_out_types];
            }
            return $recursively_fleshed_out_types;
        }
        if ($return_type instanceof TKeyOf || $return_type instanceof TValueOf) {
            return self::expandKeyOfValueOf($codebase, $return_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
        }
        if ($return_type instanceof TIntMask) {
            if (!$evaluate_class_constants) {
                return [new TInt()];
            }
            $potential_ints = [];
            foreach ($return_type->values as $value_type) {
                $new_value_type = self::expandAtomic($codebase, $value_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                $new_value_type = reset($new_value_type);
                if (!$new_value_type instanceof TLiteralInt) {
                    return [new TInt()];
                }
                $potential_ints[] = $new_value_type->value;
            }
            return TypeParser::getComputedIntsFromMask($potential_ints);
        }
        if ($return_type instanceof TIntMaskOf) {
            if (!$evaluate_class_constants) {
                return [new TInt()];
            }
            $value_type = $return_type->value;
            $new_value_types = self::expandAtomic($codebase, $value_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
            $potential_ints = [];
            foreach ($new_value_types as $new_value_type) {
                if (!$new_value_type instanceof TLiteralInt) {
                    return [new TInt()];
                }
                $potential_ints[] = $new_value_type->value;
            }
            return TypeParser::getComputedIntsFromMask($potential_ints);
        }
        if ($return_type instanceof TConditional) {
            return self::expandConditional($codebase, $return_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
        }
        if ($return_type instanceof TList) {
            $return_type = $return_type->getKeyedArray();
        }
        if ($return_type instanceof TArray || $return_type instanceof TGenericObject || $return_type instanceof TIterable) {
            $type_params = $return_type->type_params;
            foreach ($type_params as &$type_param) {
                $type_param = self::expandUnion($codebase, $type_param, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
            }
            unset($type_param);
            /** @psalm-suppress InvalidArgument Psalm bug */
            $return_type = $return_type->setTypeParams($type_params);
        } elseif ($return_type instanceof TKeyedArray) {
            $properties = $return_type->properties;
            $changed = \false;
            foreach ($properties as $k => $property_type) {
                $property_type = self::expandUnion($codebase, $property_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                if ($property_type !== $properties[$k]) {
                    $changed = \true;
                    $properties[$k] = $property_type;
                }
            }
            unset($property_type);
            $fallback_params = $return_type->fallback_params;
            if ($fallback_params) {
                foreach ($fallback_params as $k => $property_type) {
                    $property_type = self::expandUnion($codebase, $property_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                    if ($property_type !== $fallback_params[$k]) {
                        $changed = \true;
                        $fallback_params[$k] = $property_type;
                    }
                }
                unset($property_type);
            }
            if ($changed) {
                $return_type = new TKeyedArray($properties, $return_type->class_strings, $fallback_params, $return_type->is_list, $return_type->from_docblock);
            }
        }
        if ($return_type instanceof TObjectWithProperties) {
            $properties = $return_type->properties;
            foreach ($properties as &$property_type) {
                $property_type = self::expandUnion($codebase, $property_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
            }
            unset($property_type);
            $return_type = $return_type->setProperties($properties);
        }
        if ($return_type instanceof TCallable || $return_type instanceof TClosure) {
            $params = $return_type->params;
            if ($params) {
                foreach ($params as &$param) {
                    if ($param->type) {
                        $param = $param->setType(self::expandUnion($codebase, $param->type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant));
                    }
                }
                unset($param);
            }
            $sub_return_type = $return_type->return_type;
            if ($sub_return_type) {
                $sub_return_type = self::expandUnion($codebase, $sub_return_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
            }
            $return_type = $return_type->replace($params, $sub_return_type);
        }
        return [$return_type];
    }
    /**
     * @param string|TNamedObject|TTemplateParam|null $static_class_type
     * @param-out TNamedObject|TTemplateParam $return_type
     * @return TNamedObject|TTemplateParam
     */
    private static function expandNamedObject(Codebase $codebase, TNamedObject &$return_type, ?string $self_class, $static_class_type, ?string $parent_class, bool $final = \false, bool &$expand_generic = \false)
    {
        if ($expand_generic && get_class($return_type) === TNamedObject::class && !$return_type->extra_types && $codebase->classOrInterfaceExists($return_type->value)) {
            $value = $codebase->classlikes->getUnAliasedName($return_type->value);
            $container_class_storage = $codebase->classlike_storage_provider->get($value);
            if ($container_class_storage->template_types && array_filter($container_class_storage->template_types, static fn($type_map): bool => !reset($type_map)->hasMixed())) {
                $return_type = new TGenericObject($return_type->value, array_values(array_map(static fn($type_map) => reset($type_map), $container_class_storage->template_types)));
                // we don't want to expand generic types recursively
                $expand_generic = \false;
            }
        }
        $return_type_lc = strtolower($return_type->value);
        if ($static_class_type && ($return_type_lc === 'static' || $return_type_lc === '$this')) {
            $is_static = $return_type->is_static;
            $is_static_resolved = null;
            if (!$final) {
                $is_static = \true;
                $is_static_resolved = \true;
            }
            if (is_string($static_class_type)) {
                $return_type = $return_type->setValueIsStatic($static_class_type, $is_static, $is_static_resolved);
            } else {
                if ($return_type instanceof TGenericObject && $static_class_type instanceof TGenericObject) {
                    $return_type = $return_type->setValueIsStatic($static_class_type->value, $is_static, $is_static_resolved);
                } elseif ($static_class_type instanceof TNamedObject) {
                    $return_type = $static_class_type->setIsStatic($is_static, $is_static_resolved);
                } else {
                    $return_type = $static_class_type;
                }
            }
        } elseif ($return_type->is_static && !$return_type->is_static_resolved && ($static_class_type instanceof TNamedObject || $static_class_type instanceof TTemplateParam)) {
            $return_type_types = $return_type->getIntersectionTypes();
            $cloned_static = $static_class_type->setIntersectionTypes([]);
            $extra_static = $static_class_type->extra_types;
            if ($cloned_static->getKey(\false) !== $return_type->getKey(\false)) {
                $return_type_types[$cloned_static->getKey()] = $cloned_static;
            }
            foreach ($extra_static as $extra_static_type) {
                if ($extra_static_type->getKey(\false) !== $return_type->getKey(\false)) {
                    $return_type_types[$extra_static_type->getKey()] = $extra_static_type;
                }
            }
            $return_type = $return_type->setIntersectionTypes($return_type_types)->setIsStatic(\true, \true);
        } elseif ($return_type->is_static && is_string($static_class_type) && $final) {
            $return_type = $return_type->setValueIsStatic($static_class_type, \false);
        } elseif ($self_class && $return_type_lc === 'self') {
            $return_type = $return_type->setValue($self_class);
        } elseif ($parent_class && $return_type_lc === 'parent') {
            $return_type = $return_type->setValue($parent_class);
        } else {
            $new_value = $codebase->classlikes->getUnAliasedName($return_type->value);
            $return_type = $return_type->setValue($new_value);
        }
        return $return_type;
    }
    /**
     * @param string|TNamedObject|TTemplateParam|null $static_class_type
     * @return non-empty-list<Atomic>
     */
    private static function expandConditional(Codebase $codebase, TConditional &$return_type, ?string $self_class, $static_class_type, ?string $parent_class, bool $evaluate_class_constants = \true, bool $evaluate_conditional_types = \false, bool $final = \false, bool $expand_generic = \false, bool $expand_templates = \false, bool $throw_on_unresolvable_constant = \false) : array
    {
        $new_as_type = self::expandUnion($codebase, $return_type->as_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
        if ($evaluate_conditional_types) {
            $assertion = null;
            if ($return_type->conditional_type->isSingle()) {
                foreach ($return_type->conditional_type->getAtomicTypes() as $condition_atomic_type) {
                    $candidate = self::expandAtomic($codebase, $condition_atomic_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                    if (count($candidate) === 1) {
                        $assertion = new IsType($candidate[0]);
                    }
                }
            }
            $if_conditional_return_types = [];
            foreach ($return_type->if_type->getAtomicTypes() as $if_atomic_type) {
                $candidate_types = self::expandAtomic($codebase, $if_atomic_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                $if_conditional_return_types = [...$if_conditional_return_types, ...$candidate_types];
            }
            $else_conditional_return_types = [];
            foreach ($return_type->else_type->getAtomicTypes() as $else_atomic_type) {
                $candidate_types = self::expandAtomic($codebase, $else_atomic_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                $else_conditional_return_types = [...$else_conditional_return_types, ...$candidate_types];
            }
            if ($assertion && $return_type->param_name === (string) $return_type->if_type) {
                $if_conditional_return_type = \Psalm\Internal\Type\TypeCombiner::combine($if_conditional_return_types, $codebase);
                $if_conditional_return_type = SimpleAssertionReconciler::reconcile($assertion, $codebase, $if_conditional_return_type);
                if ($if_conditional_return_type) {
                    $if_conditional_return_types = array_values($if_conditional_return_type->getAtomicTypes());
                }
            }
            if ($assertion && $return_type->param_name === (string) $return_type->else_type) {
                $else_conditional_return_type = \Psalm\Internal\Type\TypeCombiner::combine($else_conditional_return_types, $codebase);
                $else_conditional_return_type = SimpleNegatedAssertionReconciler::reconcile($codebase, $assertion, $else_conditional_return_type);
                if ($else_conditional_return_type) {
                    $else_conditional_return_types = array_values($else_conditional_return_type->getAtomicTypes());
                }
            }
            $all_conditional_return_types = [...$if_conditional_return_types, ...$else_conditional_return_types];
            $number_of_types = count($all_conditional_return_types);
            // we filter TNever that have no bearing on the return type
            if ($number_of_types > 1) {
                $all_conditional_return_types = array_filter($all_conditional_return_types, static fn(Atomic $atomic_type): bool => !$atomic_type instanceof TNever);
            }
            // if we still have more than one type, we remove TVoid and replace it by TNull
            $number_of_types = count($all_conditional_return_types);
            if ($number_of_types > 1) {
                $all_conditional_return_types = array_filter($all_conditional_return_types, static fn(Atomic $atomic_type): bool => !$atomic_type instanceof TVoid);
                if (count($all_conditional_return_types) !== $number_of_types) {
                    $all_conditional_return_types[] = new TNull(\true);
                }
            }
            if ($all_conditional_return_types) {
                $combined = \Psalm\Internal\Type\TypeCombiner::combine(array_values($all_conditional_return_types), $codebase);
                $return_type = $return_type->setTypes($new_as_type);
                return array_values($combined->getAtomicTypes());
            }
        }
        $return_type = $return_type->setTypes($new_as_type, self::expandUnion($codebase, $return_type->conditional_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant), self::expandUnion($codebase, $return_type->if_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant), self::expandUnion($codebase, $return_type->else_type, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant));
        return [$return_type];
    }
    /**
     * @param string|TNamedObject|TTemplateParam|null $static_class_type
     * @return non-empty-list<Atomic>
     */
    private static function expandPropertiesOf(Codebase $codebase, TPropertiesOf &$return_type, ?string $self_class, $static_class_type) : array
    {
        if ($self_class) {
            $return_type = $return_type->replaceClassLike('self', $self_class);
            $return_type = $return_type->replaceClassLike('static', is_string($static_class_type) ? $static_class_type : $self_class);
        }
        $class_storage = null;
        if ($codebase->classExists($return_type->classlike_type->value)) {
            $class_storage = $codebase->classlike_storage_provider->get($return_type->classlike_type->value);
        } else {
            foreach ($return_type->classlike_type->extra_types as $type) {
                if ($type instanceof TNamedObject && $codebase->classExists($type->value)) {
                    $class_storage = $codebase->classlike_storage_provider->get($type->value);
                    break;
                }
            }
        }
        if (!$class_storage) {
            return [$return_type];
        }
        $all_sealed = \true;
        $properties = [];
        foreach ([$class_storage->name, ...array_values($class_storage->parent_classes)] as $class) {
            if (!$codebase->classExists($class)) {
                continue;
            }
            $storage = $codebase->classlike_storage_provider->get($class);
            if (!$storage->final) {
                $all_sealed = \false;
            }
            foreach ($storage->properties as $key => $property) {
                if (isset($properties[$key])) {
                    continue;
                }
                if ($return_type->visibility_filter !== null && $property->visibility !== $return_type->visibility_filter) {
                    continue;
                }
                if ($property->is_static || !$property->type) {
                    continue;
                }
                $type = $return_type->classlike_type instanceof TGenericObject ? AtomicPropertyFetchAnalyzer::localizePropertyType($codebase, $property->type, $return_type->classlike_type, $storage, $storage) : $property->type;
                $properties[$key] = $type;
            }
        }
        if ($properties === []) {
            return [$return_type];
        }
        return [new TKeyedArray($properties, null, $all_sealed ? null : [Type::getString(), Type::getMixed()])];
    }
    /**
     * @param TKeyOf|TValueOf $return_type
     * @param string|TNamedObject|TTemplateParam|null $static_class_type
     * @return non-empty-list<Atomic>
     */
    private static function expandKeyOfValueOf(Codebase $codebase, Atomic &$return_type, ?string $self_class, $static_class_type, ?string $parent_class, bool $evaluate_class_constants = \true, bool $evaluate_conditional_types = \false, bool $final = \false, bool $expand_generic = \false, bool $expand_templates = \false, bool $throw_on_unresolvable_constant = \false) : array
    {
        // Expand class constants to their atomics
        $type_atomics = [];
        foreach ($return_type->type->getAtomicTypes() as $type_param) {
            if (!$evaluate_class_constants || !$type_param instanceof TClassConstant) {
                $type_param_expanded = self::expandAtomic($codebase, $type_param, $self_class, $static_class_type, $parent_class, $evaluate_class_constants, $evaluate_conditional_types, $final, $expand_generic, $expand_templates, $throw_on_unresolvable_constant);
                $type_atomics = [...$type_atomics, ...$type_param_expanded];
                continue;
            }
            if ($self_class) {
                $type_param = $type_param->replaceClassLike('self', $self_class);
            }
            if ($throw_on_unresolvable_constant && !$codebase->classOrInterfaceExists($type_param->fq_classlike_name)) {
                throw new UnresolvableConstantException($type_param->fq_classlike_name, $type_param->const_name);
            }
            try {
                $constant_type = $codebase->classlikes->getClassConstantType($type_param->fq_classlike_name, $type_param->const_name, ReflectionProperty::IS_PRIVATE);
            } catch (CircularReferenceException $e) {
                return [$return_type];
            }
            if (!$constant_type || $return_type instanceof TKeyOf && !TKeyOf::isViableTemplateType($constant_type) || $return_type instanceof TValueOf && !TValueOf::isViableTemplateType($constant_type)) {
                if ($throw_on_unresolvable_constant) {
                    throw new UnresolvableConstantException($type_param->fq_classlike_name, $type_param->const_name);
                } else {
                    return [$return_type];
                }
            }
            $type_atomics = array_merge($type_atomics, array_values($constant_type->getAtomicTypes()));
        }
        if ($type_atomics === []) {
            return [$return_type];
        }
        if ($return_type instanceof TKeyOf) {
            $new_return_types = TKeyOf::getArrayKeyType(new Union($type_atomics));
        } else {
            $new_return_types = TValueOf::getValueType(new Union($type_atomics), $codebase);
        }
        if ($new_return_types === null) {
            return [$return_type];
        }
        return array_values($new_return_types->getAtomicTypes());
    }
}
<?php

namespace Psalm\Internal\Json;

use RuntimeException;
use function json_encode;
use function json_last_error_msg;
use const JSON_PRETTY_PRINT;
use const JSON_UNESCAPED_SLASHES;
use const JSON_UNESCAPED_UNICODE;
/**
 * Provides ability of pretty printed JSON output.
 *
 * @internal
 */
class Json
{
    public const PRETTY = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
    /**
     * @var int
     */
    public const DEFAULT = 0;
    /**
     * @param mixed $data
     * @psalm-pure
     */
    public static function encode($data, ?int $options = null) : string
    {
        if ($options === null) {
            $options = self::DEFAULT;
        }
        $result = json_encode($data, $options);
        if ($result === \false) {
            /** @psalm-suppress ImpureFunctionCall */
            throw new RuntimeException('Cannot create JSON string: ' . json_last_error_msg());
        }
        return $result;
    }
}
<?php

namespace Psalm\Internal;

use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\Falsy;
use UnexpectedValueException;
use function array_filter;
use function array_intersect_key;
use function array_keys;
use function array_merge;
use function array_pop;
use function array_values;
use function assert;
use function count;
use function in_array;
use function mt_rand;
use function reset;
/**
 * @internal
 */
class Algebra
{
    /**
     * @param array<string, non-empty-list<non-empty-list<Assertion>>>  $all_types
     * @return array<string, non-empty-list<non-empty-list<Assertion>>>
     * @psalm-pure
     */
    public static function negateTypes(array $all_types) : array
    {
        $negated_types = [];
        foreach ($all_types as $key => $anded_types) {
            if (count($anded_types) > 1) {
                $new_anded_types = [];
                foreach ($anded_types as $orred_types) {
                    if (count($orred_types) === 1) {
                        $new_anded_types[] = $orred_types[0]->getNegation();
                    } else {
                        continue 2;
                    }
                }
                assert($new_anded_types !== []);
                $negated_types[$key] = [$new_anded_types];
                continue;
            }
            $new_orred_types = [];
            foreach ($anded_types[0] as $orred_type) {
                $new_orred_types[] = [$orred_type->getNegation()];
            }
            $negated_types[$key] = $new_orred_types;
        }
        return $negated_types;
    }
    /**
     * This is a very simple simplification heuristic
     * for CNF formulae.
     *
     * It simplifies formulae:
     *     ($a) && ($a || $b) => $a
     *     (!$a) && (!$b) && ($a || $b || $c) => $c
     *
     * @param list<Clause>  $clauses
     * @return list<Clause>
     * @psalm-pure
     */
    public static function simplifyCNF(array $clauses) : array
    {
        $clause_count = count($clauses);
        //65536 seems to be a significant threshold, when put at 65537, the code https://psalm.dev/r/216f362ea6 goes
        //from seconds in analysis to many minutes
        if ($clause_count > 65536) {
            return [];
        }
        if ($clause_count > 50) {
            $all_has_unknown = \true;
            foreach ($clauses as $clause) {
                $clause_has_unknown = \false;
                foreach ($clause->possibilities as $key => $_) {
                    if ($key[0] === '*') {
                        $clause_has_unknown = \true;
                        break;
                    }
                }
                if (!$clause_has_unknown) {
                    $all_has_unknown = \false;
                    break;
                }
            }
            if ($all_has_unknown) {
                return $clauses;
            }
        }
        $cloned_clauses = [];
        // avoid strict duplicates
        foreach ($clauses as $clause) {
            $cloned_clauses[$clause->hash] = $clause;
        }
        // remove impossible types
        foreach ($cloned_clauses as $clause_a_hash => $clause_a) {
            if (!$clause_a->reconcilable || $clause_a->wedge) {
                continue;
            }
            $clause_a_keys = array_keys($clause_a->possibilities);
            if (count($clause_a->possibilities) !== 1 || count(array_values($clause_a->possibilities)[0]) !== 1) {
                foreach ($cloned_clauses as $clause_b) {
                    if ($clause_a === $clause_b || !$clause_b->reconcilable || $clause_b->wedge) {
                        continue;
                    }
                    if ($clause_a_keys === array_keys($clause_b->possibilities)) {
                        $opposing_keys = [];
                        foreach ($clause_a->possibilities as $key => $a_possibilities) {
                            $b_possibilities = $clause_b->possibilities[$key];
                            if (array_keys($clause_a->possibilities[$key]) === array_keys($clause_b->possibilities[$key])) {
                                continue;
                            }
                            if (count($a_possibilities) === 1 && count($b_possibilities) === 1) {
                                if (reset($a_possibilities)->isNegationOf(reset($b_possibilities))) {
                                    $opposing_keys[] = $key;
                                    continue;
                                }
                            }
                            continue 2;
                        }
                        if (count($opposing_keys) === 1) {
                            unset($cloned_clauses[$clause_a_hash]);
                            $clause_a = $clause_a->removePossibilities($opposing_keys[0]);
                            if (!$clause_a) {
                                continue 2;
                            }
                            $cloned_clauses[$clause_a->hash] = $clause_a;
                        }
                    }
                }
                continue;
            }
            $clause_var = array_keys($clause_a->possibilities)[0];
            $only_type = array_pop(array_values($clause_a->possibilities)[0]);
            $negated_clause_type = $only_type->getNegation();
            $negated_clause_type_string = (string) $negated_clause_type;
            foreach ($cloned_clauses as $clause_b_hash => $clause_b) {
                if ($clause_a === $clause_b || !$clause_b->reconcilable || $clause_b->wedge) {
                    continue;
                }
                if (isset($clause_b->possibilities[$clause_var])) {
                    $unmatched = [];
                    $matched = [];
                    foreach ($clause_b->possibilities[$clause_var] as $k => $possible_type) {
                        if ((string) $possible_type === $negated_clause_type_string) {
                            $matched[] = $possible_type;
                        } else {
                            $unmatched[$k] = $possible_type;
                        }
                    }
                    if ($matched) {
                        $clause_var_possibilities = $unmatched;
                        unset($cloned_clauses[$clause_b_hash]);
                        if (!$clause_var_possibilities) {
                            $updated_clause = $clause_b->removePossibilities($clause_var);
                            if ($updated_clause) {
                                $cloned_clauses[$updated_clause->hash] = $updated_clause;
                            }
                        } else {
                            $updated_clause = $clause_b->addPossibilities($clause_var, $clause_var_possibilities);
                            $cloned_clauses[$updated_clause->hash] = $updated_clause;
                        }
                    }
                }
            }
        }
        $simplified_clauses = [];
        foreach ($cloned_clauses as $clause_a) {
            $is_redundant = \false;
            foreach ($cloned_clauses as $clause_b) {
                if ($clause_a === $clause_b || !$clause_b->reconcilable || $clause_b->wedge || $clause_a->wedge) {
                    continue;
                }
                if ($clause_a->contains($clause_b)) {
                    $is_redundant = \true;
                    break;
                }
            }
            if (!$is_redundant) {
                $simplified_clauses[$clause_a->hash] = $clause_a;
            }
        }
        $clause_count = count($simplified_clauses);
        // simplify (A || X) && (!A || Y) && (X || Y)
        // to
        // simplify (A || X) && (!A || Y)
        // where X and Y are sets of orred terms
        if ($clause_count > 2 && $clause_count < 256) {
            $clauses = array_values($simplified_clauses);
            for ($i = 0; $i < $clause_count; $i++) {
                $clause_a = $clauses[$i];
                for ($k = $i + 1; $k < $clause_count; $k++) {
                    $clause_b = $clauses[$k];
                    $common_keys = array_keys(array_intersect_key($clause_a->possibilities, $clause_b->possibilities));
                    if ($common_keys) {
                        $common_negated_keys = [];
                        foreach ($common_keys as $common_key) {
                            if (count($clause_a->possibilities[$common_key]) === 1 && count($clause_b->possibilities[$common_key]) === 1 && reset($clause_a->possibilities[$common_key])->isNegationOf(reset($clause_b->possibilities[$common_key]))) {
                                $common_negated_keys[] = $common_key;
                            }
                        }
                        if ($common_negated_keys) {
                            $new_possibilities = [];
                            foreach ($clause_a->possibilities as $var_id => $possibilities) {
                                if (in_array($var_id, $common_negated_keys, \true)) {
                                    continue;
                                }
                                if (!isset($new_possibilities[$var_id])) {
                                    $new_possibilities[$var_id] = $possibilities;
                                } else {
                                    $new_possibilities[$var_id] = array_merge($new_possibilities[$var_id], $possibilities);
                                }
                            }
                            foreach ($clause_b->possibilities as $var_id => $possibilities) {
                                if (in_array($var_id, $common_negated_keys, \true)) {
                                    continue;
                                }
                                if (!isset($new_possibilities[$var_id])) {
                                    $new_possibilities[$var_id] = $possibilities;
                                } else {
                                    $new_possibilities[$var_id] = array_merge($new_possibilities[$var_id], $possibilities);
                                }
                            }
                            /** @psalm-suppress MixedArgumentTypeCoercion due I think to Psalm bug */
                            $conflict_clause = new \Psalm\Internal\Clause($new_possibilities, $clause_a->creating_conditional_id, $clause_a->creating_conditional_id, \false, \true, \true, []);
                            unset($simplified_clauses[$conflict_clause->hash]);
                        }
                    }
                }
            }
        }
        return array_values($simplified_clauses);
    }
    /**
     * Look for clauses with only one possible value
     *
     * @param  list<Clause>  $clauses
     * @param  array<string, bool> $cond_referenced_var_ids
     * @param  array<string, array<int, array<int, Assertion>>> $active_truths
     * @return array<string, list<list<Assertion>>>
     */
    public static function getTruthsFromFormula(array $clauses, ?int $creating_conditional_id = null, array &$cond_referenced_var_ids = [], array &$active_truths = []) : array
    {
        $truths = [];
        $active_truths = [];
        if ($clauses === []) {
            return [];
        }
        foreach ($clauses as $clause) {
            if (!$clause->reconcilable || count($clause->possibilities) !== 1) {
                continue;
            }
            foreach ($clause->possibilities as $var => $possible_types) {
                if ($var[0] === '*') {
                    continue;
                }
                // if there's only one possible type, return it
                if (count($possible_types) === 1) {
                    $possible_type = array_pop($possible_types);
                    if (isset($truths[$var]) && !isset($clause->redefined_vars[$var])) {
                        $truths[$var][] = [$possible_type];
                    } else {
                        $truths[$var] = [[$possible_type]];
                    }
                    if ($creating_conditional_id && $creating_conditional_id === $clause->creating_conditional_id) {
                        if (!isset($active_truths[$var])) {
                            $active_truths[$var] = [];
                        }
                        $active_truths[$var][count($truths[$var]) - 1] = [$possible_type];
                    }
                } else {
                    // if there's only one active clause, return all the non-negation clause members ORed together
                    $things_that_can_be_said = [];
                    foreach ($possible_types as $assertion) {
                        if ($assertion instanceof Falsy || !$assertion->isNegation()) {
                            $things_that_can_be_said[(string) $assertion] = $assertion;
                        }
                    }
                    if ($things_that_can_be_said && count($things_that_can_be_said) === count($possible_types)) {
                        if ($clause->generated && count($possible_types) > 1) {
                            unset($cond_referenced_var_ids[$var]);
                        }
                        $truths[$var] = [array_values($things_that_can_be_said)];
                        if ($creating_conditional_id && $creating_conditional_id === $clause->creating_conditional_id) {
                            $active_truths[$var] = [array_values($things_that_can_be_said)];
                        }
                    }
                }
            }
        }
        return $truths;
    }
    /**
     * @param non-empty-list<Clause>  $clauses
     * @return list<Clause>
     * @psalm-pure
     */
    public static function groupImpossibilities(array $clauses) : array
    {
        $complexity = 1;
        $seed_clauses = [];
        $clause = array_pop($clauses);
        if (!$clause->wedge) {
            if ($clause->impossibilities === null) {
                throw new UnexpectedValueException('$clause->impossibilities should not be null');
            }
            foreach ($clause->impossibilities as $var => $impossible_types) {
                foreach ($impossible_types as $impossible_type) {
                    $seed_clause = new \Psalm\Internal\Clause([$var => [(string) $impossible_type => $impossible_type]], $clause->creating_conditional_id, $clause->creating_object_id);
                    $seed_clauses[] = $seed_clause;
                    ++$complexity;
                }
            }
        }
        if (!$clauses || !$seed_clauses) {
            return $seed_clauses;
        }
        $complexity_upper_bound = count($seed_clauses);
        foreach ($clauses as $clause) {
            $i = 0;
            foreach ($clause->possibilities as $p) {
                $i += count($p);
            }
            $complexity_upper_bound *= $i;
            if ($complexity_upper_bound > 20000) {
                throw new ComplicatedExpressionException();
            }
        }
        while ($clauses) {
            $clause = array_pop($clauses);
            $new_clauses = [];
            foreach ($seed_clauses as $grouped_clause) {
                if ($clause->impossibilities === null) {
                    throw new UnexpectedValueException('$clause->impossibilities should not be null');
                }
                foreach ($clause->impossibilities as $var => $impossible_types) {
                    foreach ($impossible_types as $impossible_type) {
                        $new_clause_possibilities = $grouped_clause->possibilities;
                        if (isset($new_clause_possibilities[$var])) {
                            $impossible_type_string = (string) $impossible_type;
                            $new_clause_possibilities[$var][$impossible_type_string] = $impossible_type;
                            foreach ($new_clause_possibilities[$var] as $ak => $av) {
                                foreach ($new_clause_possibilities[$var] as $bk => $bv) {
                                    if ($ak == $bk) {
                                        break;
                                    }
                                    if ($ak !== $impossible_type_string && $bk !== $impossible_type_string) {
                                        continue;
                                    }
                                    if ($av->isNegationOf($bv)) {
                                        break 3;
                                    }
                                }
                            }
                        } else {
                            $new_clause_possibilities[$var] = [(string) $impossible_type => $impossible_type];
                        }
                        $new_clause = new \Psalm\Internal\Clause($new_clause_possibilities, $grouped_clause->creating_conditional_id, $clause->creating_object_id, \false, \true, \true, []);
                        $new_clauses[] = $new_clause;
                        ++$complexity;
                        if ($complexity > 20000) {
                            throw new ComplicatedExpressionException();
                        }
                    }
                }
            }
            $seed_clauses = $new_clauses;
        }
        return $seed_clauses;
    }
    /**
     * @param list<Clause>  $left_clauses
     * @param list<Clause>  $right_clauses
     * @return list<Clause>
     * @psalm-pure
     */
    public static function combineOredClauses(array $left_clauses, array $right_clauses, int $conditional_object_id) : array
    {
        if (count($left_clauses) > 60000 || count($right_clauses) > 60000) {
            return [];
        }
        $clauses = [];
        $all_wedges = \true;
        $has_wedge = \false;
        foreach ($left_clauses as $left_clause) {
            foreach ($right_clauses as $right_clause) {
                $all_wedges = $all_wedges && ($left_clause->wedge && $right_clause->wedge);
                $has_wedge = $has_wedge || $left_clause->wedge && $right_clause->wedge;
            }
        }
        if ($all_wedges) {
            return [new \Psalm\Internal\Clause([], $conditional_object_id, $conditional_object_id, \true)];
        }
        foreach ($left_clauses as $left_clause) {
            foreach ($right_clauses as $right_clause) {
                if ($left_clause->wedge && $right_clause->wedge) {
                    // handled below
                    continue;
                }
                /** @var  array<string, non-empty-array<string, Assertion>> */
                $possibilities = [];
                $can_reconcile = \true;
                if ($left_clause->wedge || $right_clause->wedge || !$left_clause->reconcilable || !$right_clause->reconcilable) {
                    $can_reconcile = \false;
                }
                foreach ($left_clause->possibilities as $var => $possible_types) {
                    if (isset($right_clause->redefined_vars[$var])) {
                        continue;
                    }
                    if (isset($possibilities[$var])) {
                        $possibilities[$var] = array_merge($possibilities[$var], $possible_types);
                    } else {
                        $possibilities[$var] = $possible_types;
                    }
                }
                foreach ($right_clause->possibilities as $var => $possible_types) {
                    if (isset($possibilities[$var])) {
                        $possibilities[$var] = array_merge($possibilities[$var], $possible_types);
                    } else {
                        $possibilities[$var] = $possible_types;
                    }
                }
                foreach ($possibilities as $var_possibilities) {
                    if (count($var_possibilities) === 2) {
                        $vals = array_values($var_possibilities);
                        /** @psalm-suppress PossiblyUndefinedIntArrayOffset */
                        if ($vals[0]->isNegationOf($vals[1])) {
                            continue 2;
                        }
                    }
                }
                $creating_conditional_id = $right_clause->creating_conditional_id === $left_clause->creating_conditional_id ? $right_clause->creating_conditional_id : $conditional_object_id;
                $clauses[] = new \Psalm\Internal\Clause($possibilities, $creating_conditional_id, $creating_conditional_id, \false, $can_reconcile, $right_clause->generated || $left_clause->generated || count($left_clauses) > 1 || count($right_clauses) > 1, []);
            }
        }
        if ($has_wedge) {
            $clauses[] = new \Psalm\Internal\Clause([], $conditional_object_id, $conditional_object_id, \true);
        }
        return $clauses;
    }
    /**
     * Negates a set of clauses
     * negateClauses([$a || $b]) => !$a && !$b
     * negateClauses([$a, $b]) => !$a || !$b
     * negateClauses([$a, $b || $c]) =>
     *   (!$a || !$b) &&
     *   (!$a || !$c)
     * negateClauses([$a, $b || $c, $d || $e || $f]) =>
     *   (!$a || !$b || !$d) &&
     *   (!$a || !$b || !$e) &&
     *   (!$a || !$b || !$f) &&
     *   (!$a || !$c || !$d) &&
     *   (!$a || !$c || !$e) &&
     *   (!$a || !$c || !$f)
     *
     * @param list<Clause>  $clauses
     * @return non-empty-list<Clause>
     */
    public static function negateFormula(array $clauses) : array
    {
        $clauses = array_filter($clauses, static fn(\Psalm\Internal\Clause $clause): bool => $clause->reconcilable);
        if (!$clauses) {
            $cond_id = mt_rand(0, 100000000);
            return [new \Psalm\Internal\Clause([], $cond_id, $cond_id, \true)];
        }
        $clauses_with_impossibilities = [];
        foreach ($clauses as $clause) {
            $clauses_with_impossibilities[] = $clause->calculateNegation();
        }
        unset($clauses);
        $impossible_clauses = self::groupImpossibilities($clauses_with_impossibilities);
        if (!$impossible_clauses) {
            $cond_id = mt_rand(0, 100000000);
            return [new \Psalm\Internal\Clause([], $cond_id, $cond_id, \true)];
        }
        $negated = self::simplifyCNF($impossible_clauses);
        if (!$negated) {
            $cond_id = mt_rand(0, 100000000);
            return [new \Psalm\Internal\Clause([], $cond_id, $cond_id, \true)];
        }
        return $negated;
    }
}
<?php

namespace Psalm\Internal;

use InvalidArgumentException;
use Psalm\Storage\ImmutableNonCloneableTrait;
use function explode;
use function is_string;
use function ltrim;
use function strpos;
use function strtolower;
/**
 * @psalm-immutable
 * @internal
 */
class MethodIdentifier
{
    use ImmutableNonCloneableTrait;
    public string $fq_class_name;
    /** @var lowercase-string  */
    public string $method_name;
    /**
     * @param lowercase-string $method_name
     */
    public function __construct(string $fq_class_name, string $method_name)
    {
        $this->fq_class_name = $fq_class_name;
        $this->method_name = $method_name;
    }
    /**
     * Takes any valid reference to a method id and converts
     * it into a MethodIdentifier
     *
     * @param string|MethodIdentifier $method_id
     * @psalm-pure
     */
    public static function wrap($method_id) : self
    {
        return is_string($method_id) ? static::fromMethodIdReference($method_id) : $method_id;
    }
    /**
     * @psalm-pure
     */
    public static function isValidMethodIdReference(string $method_id) : bool
    {
        return strpos($method_id, '::') !== \false;
    }
    /**
     * @psalm-pure
     */
    public static function fromMethodIdReference(string $method_id) : self
    {
        if (!static::isValidMethodIdReference($method_id)) {
            throw new InvalidArgumentException('Invalid method id reference provided: ' . $method_id);
        }
        // remove leading backslash if it exists
        $method_id = ltrim($method_id, '\\');
        $method_id_parts = explode('::', $method_id);
        return new self($method_id_parts[0], strtolower($method_id_parts[1]));
    }
    /** @return non-empty-string */
    public function __toString() : string
    {
        return $this->fq_class_name . '::' . $this->method_name;
    }
}
<?php

namespace Psalm\Internal;

use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Codebase\Functions;
use Psalm\Internal\Codebase\Reflection;
use Psalm\Internal\FileManipulation\ClassDocblockManipulator;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\FileManipulation\FunctionDocblockManipulator;
use Psalm\Internal\FileManipulation\PropertyDocblockManipulator;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Provider\StatementsProvider;
use Psalm\Internal\Provider\StatementsVolatileCache;
use Psalm\Internal\Scanner\ParsedDocblock;
use Psalm\Internal\Type\TypeTokenizer;
use Psalm\IssueBuffer;
/**
 * @internal
 */
abstract class RuntimeCaches
{
    public static function clearAll() : void
    {
        IssueBuffer::clearCache();
        Reflection::clearCache();
        Functions::clearCache();
        TypeTokenizer::clearCache();
        FileReferenceProvider::clearCache();
        FileManipulationBuffer::clearCache();
        ClassDocblockManipulator::clearCache();
        FunctionDocblockManipulator::clearCache();
        PropertyDocblockManipulator::clearCache();
        FileAnalyzer::clearCache();
        FunctionLikeAnalyzer::clearCache();
        ClassLikeStorageProvider::deleteAll();
        FileStorageProvider::deleteAll();
        StatementsProvider::clearLexer();
        StatementsProvider::clearParser();
        ParsedDocblock::resetNewlineBetweenAnnotations();
        StatementsVolatileCache::getInstance()->clearCache();
    }
}
<?php

namespace Psalm\Internal;

use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Union;
/**
 * @internal
 */
class ReferenceConstraint
{
    public ?Union $type = null;
    public function __construct(?Union $type = null)
    {
        if ($type) {
            $type = $type->getBuilder();
            if ($type->getLiteralStrings()) {
                $type->addType(new TString());
            }
            if ($type->getLiteralInts()) {
                $type->addType(new TInt());
            }
            if ($type->getLiteralFloats()) {
                $type->addType(new TFloat());
            }
            $this->type = $type->freeze();
        }
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use AssertionError;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Exception\InvalidMethodOverrideException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Internal\Scanner\FunctionDocblockComment;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeAlias;
use Psalm\Internal\Type\TypeParser;
use Psalm\Internal\Type\TypeTokenizer;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\PossiblyInvalidDocblockTag;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\Empty_;
use Psalm\Storage\Assertion\Falsy;
use Psalm\Storage\Assertion\IsIdentical;
use Psalm\Storage\Assertion\IsLooselyEqual;
use Psalm\Storage\Assertion\IsNotIdentical;
use Psalm\Storage\Assertion\IsNotLooselyEqual;
use Psalm\Storage\Assertion\IsNotType;
use Psalm\Storage\Assertion\IsType;
use Psalm\Storage\Assertion\NonEmpty;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Storage\Possibilities;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\TaintKindGroup;
use Psalm\Type\Union;
use function array_filter;
use function array_merge;
use function array_values;
use function count;
use function explode;
use function in_array;
use function preg_last_error_msg;
use function preg_match;
use function preg_replace;
use function preg_split;
use function str_replace;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
use function trim;
/**
 * @internal
 */
class FunctionLikeDocblockScanner
{
    /**
     * @param array<string, non-empty-array<string, Union>> $existing_function_template_types
     * @param array<string, TypeAlias> $type_aliases
     */
    public static function addDocblockInfo(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, array $type_aliases, ?ClassLikeStorage $classlike_storage, array $existing_function_template_types, FunctionLikeStorage $storage, PhpParser\Node\FunctionLike $stmt, FunctionDocblockComment $docblock_info, bool $is_functionlike_override, bool $fake_method, string $cased_function_id) : void
    {
        self::handleUnexpectedTags($docblock_info, $storage, $stmt, $file_scanner, $cased_function_id);
        $config = Config::getInstance();
        if ($docblock_info->mutation_free) {
            $storage->mutation_free = \true;
            if ($storage instanceof MethodStorage) {
                $storage->external_mutation_free = \true;
                $storage->mutation_free_inferred = \false;
            }
        }
        if ($storage instanceof MethodStorage && $docblock_info->external_mutation_free) {
            $storage->external_mutation_free = \true;
        }
        if ($docblock_info->deprecated) {
            $storage->deprecated = \true;
        }
        if (count($docblock_info->psalm_internal) !== 0) {
            $storage->internal = $docblock_info->psalm_internal;
        } elseif ($docblock_info->internal && $aliases->namespace) {
            $storage->internal = [NamespaceAnalyzer::getNameSpaceRoot($aliases->namespace)];
        }
        if (($storage->internal || $classlike_storage && $classlike_storage->internal) && !$config->allow_internal_named_arg_calls) {
            $storage->allow_named_arg_calls = \false;
        } elseif ($docblock_info->no_named_args) {
            $storage->allow_named_arg_calls = \false;
        }
        if ($docblock_info->variadic) {
            $storage->variadic = \true;
        }
        if ($docblock_info->pure) {
            $storage->pure = \true;
            $storage->specialize_call = \true;
            $storage->mutation_free = \true;
            if ($storage instanceof MethodStorage) {
                $storage->external_mutation_free = \true;
            }
        }
        if ($docblock_info->specialize_call) {
            $storage->specialize_call = \true;
        }
        // we make sure we only add ignore flag for internal stubs if the config is set to true
        if ($docblock_info->ignore_nullable_return && $storage->return_type && ($codebase->config->ignore_internal_nullable_issues || !in_array($file_storage->file_path, $codebase->config->internal_stubs))) {
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $storage->return_type->ignore_nullable_issues = \true;
        }
        // we make sure we only add ignore flag for internal stubs if the config is set to true
        if ($docblock_info->ignore_falsable_return && $storage->return_type && ($codebase->config->ignore_internal_falsable_issues || !in_array($file_storage->file_path, $codebase->config->internal_stubs))) {
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $storage->return_type->ignore_falsable_issues = \true;
        }
        if ($docblock_info->stub_override && !$is_functionlike_override) {
            throw new InvalidMethodOverrideException('Method ' . $cased_function_id . ' is marked as stub override,' . ' but no original counterpart found');
        }
        $storage->suppressed_issues = $docblock_info->suppressed_issues;
        foreach ($docblock_info->throws as [$throw, $offset, $line]) {
            $throw_location = new DocblockTypeLocation($file_scanner, $offset, $offset + strlen($throw), $line);
            foreach (explode('|', $throw) as $throw_class) {
                $throw_class = trim($throw_class);
                if ($throw_class === '') {
                    continue;
                }
                if ($throw_class !== 'self' && $throw_class !== 'static' && $throw_class !== 'parent') {
                    $exception_fqcln = Type::getFQCLNFromString($throw_class, $aliases);
                } else {
                    $exception_fqcln = $throw_class;
                }
                $codebase->scanner->queueClassLikeForScanning($exception_fqcln);
                $file_storage->referenced_classlikes[strtolower($exception_fqcln)] = $exception_fqcln;
                $storage->throws[$exception_fqcln] = \true;
                $storage->throw_locations[$exception_fqcln] = $throw_location;
            }
        }
        if (!$config->use_docblock_types) {
            return;
        }
        if ($storage instanceof MethodStorage && $docblock_info->inheritdoc) {
            $storage->inheritdoc = \true;
        }
        $template_types = $classlike_storage && $classlike_storage->template_types ? $classlike_storage->template_types : null;
        $function_template_types = $existing_function_template_types;
        $class_template_types = $classlike_storage ? $classlike_storage->template_types ?: [] : [];
        if ($docblock_info->templates) {
            $function_template_types = self::handleTemplates($storage, $docblock_info, $aliases, $template_types, $type_aliases, $file_scanner, $stmt, $cased_function_id);
        }
        self::handleAssertions($docblock_info, $storage, $codebase, $file_scanner, $file_storage, $aliases, $stmt, $class_template_types, $function_template_types, $type_aliases, $classlike_storage);
        foreach ($docblock_info->globals as $global) {
            try {
                $storage->global_types[$global['name']] = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($global['type'], $aliases, null, $type_aliases), null);
            } catch (TypeParseTreeException $e) {
                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $cased_function_id, new CodeLocation($file_scanner, $stmt, null, \true));
                continue;
            }
        }
        if ($docblock_info->params) {
            self::improveParamsFromDocblock($codebase, $file_scanner, $file_storage, $aliases, $type_aliases, $classlike_storage, $storage, $function_template_types, $class_template_types, $docblock_info->params, $stmt, $fake_method, $classlike_storage && !$classlike_storage->is_trait ? $classlike_storage->name : null);
        }
        if ($storage instanceof MethodStorage) {
            $storage->has_docblock_param_types = (bool) array_filter($storage->params, static fn(FunctionLikeParameter $p): bool => $p->type !== null && $p->has_docblock_type);
        }
        foreach ($docblock_info->params_out as $docblock_param_out) {
            self::handleParamOut($docblock_param_out, $aliases, $function_template_types, $class_template_types, $type_aliases, $cased_function_id, $file_scanner, $stmt, $storage, $codebase, $file_storage);
        }
        if ($docblock_info->self_out && $storage instanceof MethodStorage) {
            $out_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($docblock_info->self_out['type'], $aliases, $function_template_types + $class_template_types, $type_aliases, $classlike_storage ? $classlike_storage->name : null), null, $function_template_types + $class_template_types, $type_aliases);
            $storage->self_out_type = $out_type;
        }
        if ($docblock_info->if_this_is && $storage instanceof MethodStorage) {
            $out_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($docblock_info->if_this_is['type'], $aliases, $function_template_types + $class_template_types, $type_aliases, $classlike_storage ? $classlike_storage->name : null), null, $function_template_types + $class_template_types, $type_aliases);
            $storage->if_this_is_type = $out_type;
        }
        foreach ($docblock_info->taint_sink_params as $taint_sink_param) {
            $param_name = substr($taint_sink_param['name'], 1);
            foreach ($storage->params as $param_storage) {
                if ($param_storage->name === $param_name) {
                    $param_storage->sinks[] = $taint_sink_param['taint'];
                }
            }
        }
        foreach ($docblock_info->taint_source_types as $taint_source_type) {
            if ($taint_source_type === 'input') {
                $storage->taint_source_types = array_merge($storage->taint_source_types, TaintKindGroup::ALL_INPUT);
            } else {
                $storage->taint_source_types[] = $taint_source_type;
            }
        }
        $storage->added_taints = $docblock_info->added_taints;
        foreach ($docblock_info->removed_taints as $removed_taint) {
            if ($removed_taint[0] === '(') {
                self::handleRemovedTaint($codebase, $stmt, $aliases, $removed_taint, $function_template_types, $class_template_types, $type_aliases, $storage, $classlike_storage, $cased_function_id, $file_storage, $file_scanner);
            } else {
                $storage->removed_taints[] = $removed_taint;
            }
        }
        self::handleTaintFlow($docblock_info, $storage);
        foreach ($docblock_info->assert_untainted_params as $untainted_assert_param) {
            $param_name = substr($untainted_assert_param['name'], 1);
            foreach ($storage->params as $param_storage) {
                if ($param_storage->name === $param_name) {
                    $param_storage->assert_untainted = \true;
                }
            }
        }
        if ($docblock_info->return_type !== null) {
            self::handleReturn($codebase, $docblock_info, $docblock_info->return_type, $fake_method, $file_scanner, $storage, $stmt, $aliases, $function_template_types, $class_template_types, $type_aliases, $classlike_storage, $cased_function_id, $file_storage);
        }
        if ($docblock_info->description) {
            $storage->description = $docblock_info->description;
        }
    }
    /**
     * @param  array<string, array<string, Union>> $template_types
     * @param  array<string, TypeAlias>|null   $type_aliases
     * @param  array<string, array<string, Union>> $function_template_types
     * @return array{
     *     array<int, array{0: string, 1: int, 2?: string}>,
     *     array<string, array<string, Union>>
     * }
     */
    private static function getConditionalSanitizedTypeTokens(string $docblock_return_type, Aliases $aliases, array $template_types, ?array $type_aliases, FunctionLikeStorage $storage, ?ClassLikeStorage $classlike_storage, string $cased_function_id, array $function_template_types) : array
    {
        $fixed_type_tokens = TypeTokenizer::getFullyQualifiedTokens($docblock_return_type, $aliases, $template_types, $type_aliases, $classlike_storage && !$classlike_storage->is_trait ? $classlike_storage->name : null);
        $param_type_mapping = [];
        $template_function_id = 'fn-' . strtolower($cased_function_id);
        // This checks for param references in the return type tokens
        // If found, the param is replaced with a generated template param
        foreach ($fixed_type_tokens as $i => $type_token) {
            $token_body = $type_token[0];
            if ($token_body[0] === '$') {
                foreach ($storage->params as $j => $param_storage) {
                    if ('$' . $param_storage->name === $token_body) {
                        if (!isset($param_type_mapping[$token_body])) {
                            $template_name = 'TGeneratedFromParam' . $j;
                            if (isset($storage->template_types[$template_name])) {
                                $function_template_types[$template_name] = $storage->template_types[$template_name];
                                $param_type_mapping[$token_body] = $template_name;
                            } else {
                                $template_as_type = $param_storage->type ? $param_storage->type : Type::getMixed();
                                $storage->template_types[$template_name] = [$template_function_id => $template_as_type];
                                $function_template_types[$template_name] = $storage->template_types[$template_name];
                                $param_type_mapping[$token_body] = $template_name;
                                $param_storage->type = new Union([new TTemplateParam($template_name, $template_as_type, $template_function_id)]);
                            }
                        }
                        // spaces are allowed before $foo in get(string $foo) magic method
                        // definitions, but we want to remove them in this instance
                        if (isset($fixed_type_tokens[$i - 1]) && $fixed_type_tokens[$i - 1][0][0] === ' ') {
                            unset($fixed_type_tokens[$i - 1]);
                        }
                        $fixed_type_tokens[$i][0] = $param_type_mapping[$token_body];
                        continue 2;
                    }
                }
            }
            if ($token_body === 'func_num_args()') {
                $template_name = 'TFunctionArgCount';
                $storage->template_types[$template_name] = [$template_function_id => Type::getInt()];
                $function_template_types[$template_name] = $storage->template_types[$template_name];
                $fixed_type_tokens[$i][0] = $template_name;
            }
            if ($token_body === 'PHP_MAJOR_VERSION') {
                $template_name = 'TPhpMajorVersion';
                $storage->template_types[$template_name] = [$template_function_id => Type::getInt()];
                $function_template_types[$template_name] = $storage->template_types[$template_name];
                $fixed_type_tokens[$i][0] = $template_name;
            }
            if ($token_body === 'PHP_VERSION_ID') {
                $template_name = 'TPhpVersionId';
                $storage->template_types[$template_name] = [$template_function_id => Type::getInt()];
                $function_template_types[$template_name] = $storage->template_types[$template_name];
                $fixed_type_tokens[$i][0] = $template_name;
            }
        }
        return [$fixed_type_tokens, $function_template_types];
    }
    /**
     * @param array<string, array<string, Union>> $class_template_types
     * @param array<string, array<string, Union>> $function_template_types
     * @param array<string, TypeAlias> $type_aliases
     * @return non-empty-list<Assertion>|null
     */
    private static function getAssertionParts(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, PhpParser\Node\FunctionLike $stmt, FunctionLikeStorage $storage, string $assertion_type, array $class_template_types, array $function_template_types, array $type_aliases, ?string $self_fqcln) : ?array
    {
        $is_negation = \false;
        $is_loose_equality = \false;
        $is_strict_equality = \false;
        if ($assertion_type[0] === '!') {
            $is_negation = \true;
            $assertion_type = substr($assertion_type, 1);
        }
        if ($assertion_type[0] === '~') {
            $is_loose_equality = \true;
            $assertion_type = substr($assertion_type, 1);
        }
        if ($assertion_type[0] === '=') {
            $is_strict_equality = \true;
            $assertion_type = substr($assertion_type, 1);
        }
        $class_template_types = !$stmt instanceof PhpParser\Node\Stmt\ClassMethod || !$stmt->isStatic() ? $class_template_types : [];
        if ($assertion_type === 'falsy') {
            return [$is_negation ? new Truthy() : new Falsy()];
        }
        if ($assertion_type === 'truthy') {
            return [$is_negation ? new Falsy() : new Truthy()];
        }
        if ($assertion_type === 'empty') {
            return [$is_negation ? new NonEmpty() : new Empty_()];
        }
        $template_types = $function_template_types + $class_template_types;
        try {
            $namespaced_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($assertion_type, $aliases, $template_types, $type_aliases, $self_fqcln, null, \true), null, $template_types, $type_aliases);
        } catch (TypeParseTreeException $e) {
            $storage->docblock_issues[] = new InvalidDocblock('Invalid @psalm-assert union type ' . $e, new CodeLocation($file_scanner, $stmt, null, \true));
            return null;
        }
        if (($is_negation || $is_loose_equality || $is_strict_equality) && count($namespaced_type->getAtomicTypes()) > 1) {
            $storage->docblock_issues[] = new InvalidDocblock('Docblock assertions cannot contain | characters together with a prefix', new CodeLocation($file_scanner, $stmt, null, \true));
            return null;
        }
        /** @psalm-suppress UnusedMethodCall */
        $namespaced_type->queueClassLikesForScanning($codebase, $file_storage, $function_template_types + $class_template_types);
        $assertion_type_parts = [];
        foreach ($namespaced_type->getAtomicTypes() as $namespaced_type_part) {
            if ($is_negation) {
                if ($is_strict_equality) {
                    $assertion_type_parts[] = new IsNotIdentical($namespaced_type_part);
                } elseif ($is_loose_equality) {
                    $assertion_type_parts[] = new IsNotLooselyEqual($namespaced_type_part);
                } else {
                    $assertion_type_parts[] = new IsNotType($namespaced_type_part);
                }
            } else {
                if ($is_strict_equality) {
                    $assertion_type_parts[] = new IsIdentical($namespaced_type_part);
                } elseif ($is_loose_equality) {
                    $assertion_type_parts[] = new IsLooselyEqual($namespaced_type_part);
                } else {
                    $assertion_type_parts[] = new IsType($namespaced_type_part);
                }
            }
        }
        return $assertion_type_parts;
    }
    /**
     * @param array<string, array<string, Union>> $class_template_types
     * @param array<string, non-empty-array<string, Union>> $function_template_types
     * @param array<string, TypeAlias> $type_aliases
     * @param array<
     *     int,
     *     array{
     *         type:string,
     *         name:string,
     *         line_number:int,
     *         start:int,
     *         end:int,
     *         description?:string
     *     }
     * > $docblock_params
     */
    private static function improveParamsFromDocblock(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, array $type_aliases, ?ClassLikeStorage $classlike_storage, FunctionLikeStorage $storage, array &$function_template_types, array $class_template_types, array $docblock_params, PhpParser\Node\FunctionLike $function, bool $fake_method, ?string $fq_classlike_name) : void
    {
        $base = $classlike_storage ? $classlike_storage->name . '::' : '';
        $cased_method_id = $base . $storage->cased_name;
        $unused_docblock_params = [];
        $class_template_types = !$function instanceof PhpParser\Node\Stmt\ClassMethod || !$function->isStatic() ? $class_template_types : [];
        foreach ($docblock_params as $docblock_param) {
            $param_name = $docblock_param['name'];
            $docblock_param_variadic = \false;
            if (strpos($param_name, '...') === 0) {
                $docblock_param_variadic = \true;
                $param_name = substr($param_name, 3);
            }
            $param_name = substr($param_name, 1);
            $storage_param = null;
            foreach ($storage->params as $function_signature_param) {
                if ($function_signature_param->name === $param_name) {
                    $storage_param = $function_signature_param;
                    break;
                }
            }
            if (!$fake_method) {
                $docblock_type_location = new DocblockTypeLocation($file_scanner, $docblock_param['start'], $docblock_param['end'], $docblock_param['line_number']);
            } else {
                $docblock_type_location = new CodeLocation($file_scanner, $function, null, \false, CodeLocation::FUNCTION_PHPDOC_METHOD, null);
            }
            if ($storage_param === null) {
                $param_location = new CodeLocation($file_scanner, $function, null, \true, CodeLocation::FUNCTION_PARAM_VAR, null, $docblock_param['line_number']);
                $unused_docblock_params[$param_name] = $param_location;
                if (!$docblock_param_variadic || $storage->params || $file_scanner->will_analyze) {
                    continue;
                }
                $storage_param = new FunctionLikeParameter($param_name, \false, null, null, null, null, \false, \false, \true, null);
                $storage->addParam($storage_param);
            }
            try {
                $new_param_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($docblock_param['type'], $aliases, $function_template_types + $class_template_types, $type_aliases, $fq_classlike_name), null, $function_template_types + $class_template_types, $type_aliases, \true);
            } catch (TypeParseTreeException $e) {
                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $cased_method_id, $docblock_type_location);
                continue;
            }
            $storage_param->has_docblock_type = \true;
            /** @psalm-suppress UnusedMethodCall */
            $new_param_type->queueClassLikesForScanning($codebase, $file_storage, $storage->template_types ?: []);
            if ($storage->template_types) {
                foreach ($storage->template_types as $t => $type_map) {
                    foreach ($type_map as $obj => $type) {
                        if ($type->isMixed() && $docblock_param['type'] === 'class-string<' . $t . '>') {
                            $storage->template_types[$t][$obj] = Type::getObject();
                            if (isset($function_template_types[$t])) {
                                $function_template_types[$t][$obj] = $storage->template_types[$t][$obj];
                            }
                        }
                    }
                }
            }
            if (!$docblock_param_variadic && $storage_param->is_variadic && $new_param_type->hasArray()) {
                /**
                 * @var TArray|TKeyedArray
                 */
                $array_type = $new_param_type->getArray();
                if ($array_type instanceof TKeyedArray) {
                    $new_param_type = $array_type->getGenericValueType();
                } else {
                    $new_param_type = $array_type->type_params[1];
                }
            }
            $existing_param_type_nullable = $storage_param->is_nullable;
            if (isset($docblock_param['description'])) {
                $storage_param->description = $docblock_param['description'];
            }
            if (!$storage_param->type || $storage_param->type->hasMixed() || $storage->template_types) {
                if ($existing_param_type_nullable && !$new_param_type->isNullable() && !$new_param_type->hasTemplate()) {
                    $new_param_type = $new_param_type->getBuilder()->addType(new TNull())->freeze();
                }
                $config = Config::getInstance();
                if ($config->add_param_default_to_docblock_type && $storage_param->default_type instanceof Union && !$storage_param->default_type->hasMixed() && (!$storage_param->type || !$storage_param->type->hasMixed())) {
                    $new_param_type = Type::combineUnionTypes($new_param_type, $storage_param->default_type);
                }
                $storage_param->type = $new_param_type;
                $storage_param->type_location = $docblock_type_location;
                continue;
            }
            $storage_param_atomic_types = $storage_param->type->getAtomicTypes();
            $all_typehint_types_match = \true;
            foreach ($new_param_type->getAtomicTypes() as $key => $type) {
                if (isset($storage_param_atomic_types[$key])) {
                    /** @psalm-suppress InaccessibleProperty We just created this type */
                    $type->from_docblock = \false;
                    if ($storage_param_atomic_types[$key] instanceof TArray && $type instanceof TArray && $type->type_params[0]->hasArrayKey()) {
                        /** @psalm-suppress InaccessibleProperty We just created this type */
                        $type->type_params[0]->from_docblock = \false;
                    }
                } else {
                    $all_typehint_types_match = \false;
                }
            }
            if ($all_typehint_types_match) {
                /** @psalm-suppress InaccessibleProperty We just created this type */
                $new_param_type->from_docblock = \false;
            }
            if ($existing_param_type_nullable && !$new_param_type->isNullable()) {
                $new_param_type = $new_param_type->getBuilder()->addType(new TNull())->freeze();
            }
            $storage_param->type = $new_param_type;
            $storage_param->type_location = $docblock_type_location;
        }
        $params_without_docblock_type = array_filter($storage->params, static fn(FunctionLikeParameter $p): bool => !$p->has_docblock_type && (!$p->type || $p->type->hasArray()));
        if ($params_without_docblock_type) {
            $storage->unused_docblock_params = $unused_docblock_params;
        }
    }
    /**
     * @param array<string, TypeAlias> $type_aliases
     * @param array<string, non-empty-array<string, Union>> $function_template_types
     * @param array<string, non-empty-array<string, Union>> $class_template_types
     */
    private static function handleReturn(Codebase $codebase, FunctionDocblockComment $docblock_info, string $docblock_return_type, bool $fake_method, FileScanner $file_scanner, FunctionLikeStorage $storage, PhpParser\Node\FunctionLike $stmt, Aliases $aliases, array $function_template_types, array $class_template_types, array $type_aliases, ?ClassLikeStorage $classlike_storage, string $cased_function_id, FileStorage $file_storage) : void
    {
        if (!$fake_method && $docblock_info->return_type_line_number && $docblock_info->return_type_start && $docblock_info->return_type_end) {
            $storage->return_type_location = new DocblockTypeLocation($file_scanner, $docblock_info->return_type_start, $docblock_info->return_type_end, $docblock_info->return_type_line_number);
        } else {
            $storage->return_type_location = new CodeLocation($file_scanner, $stmt, null, \false, !$fake_method ? CodeLocation::FUNCTION_PHPDOC_RETURN_TYPE : CodeLocation::FUNCTION_PHPDOC_METHOD, $docblock_info->return_type, $docblock_info->return_type_line_number && !$fake_method ? $docblock_info->return_type_line_number : null);
        }
        try {
            [$fixed_type_tokens, $function_template_types] = self::getConditionalSanitizedTypeTokens($docblock_return_type, $aliases, $function_template_types + $class_template_types, $type_aliases, $storage, $classlike_storage, $cased_function_id, $function_template_types);
            $storage->return_type = TypeParser::parseTokens(array_values($fixed_type_tokens), null, $function_template_types + $class_template_types, $type_aliases, \true);
            if ($storage instanceof MethodStorage) {
                $storage->has_docblock_return_type = \true;
            }
            if ($storage->signature_return_type) {
                $all_typehint_types_match = \true;
                $signature_return_atomic_types = $storage->signature_return_type->getAtomicTypes();
                foreach ($storage->return_type->getAtomicTypes() as $key => $type) {
                    if (isset($signature_return_atomic_types[$key])) {
                        /** @psalm-suppress InaccessibleProperty We just created this atomic type */
                        $type->from_docblock = \false;
                    } else {
                        $all_typehint_types_match = \false;
                    }
                }
                if ($all_typehint_types_match) {
                    /** @psalm-suppress InaccessibleProperty We just created this type */
                    $storage->return_type->from_docblock = \false;
                    if ($storage instanceof MethodStorage) {
                        $storage->has_docblock_return_type = \true;
                    }
                }
                // if the signature type contains null, we add null into the final return type too
                if ($storage->signature_return_type->isNullable() && !$storage->return_type->isNullable() && !$storage->return_type->hasTemplate() && !$storage->return_type->hasConditional()) {
                    //don't add null to final type if signature type don't match the docblock type
                    // however, we can't check for object types at this point (#6931), so we'll assume it's ok
                    if ($storage->return_type->hasObjectType() || UnionTypeComparator::isContainedBy($codebase, $storage->return_type, $storage->signature_return_type)) {
                        $storage->return_type = $storage->return_type->getBuilder()->addType(new TNull())->freeze();
                    }
                }
            }
            /** @psalm-suppress UnusedMethodCall */
            $storage->return_type->queueClassLikesForScanning($codebase, $file_storage);
        } catch (TypeParseTreeException $e) {
            $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $cased_function_id, new CodeLocation($file_scanner, $stmt, null, \true));
        }
        // we make sure we only add ignore flag for internal stubs if the config is set to true
        if ($docblock_info->ignore_nullable_return && $storage->return_type && ($codebase->config->ignore_internal_nullable_issues || !in_array($file_storage->file_path, $codebase->config->internal_stubs))) {
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $storage->return_type->ignore_nullable_issues = \true;
        }
        // we make sure we only add ignore flag for internal stubs if the config is set to true
        if ($docblock_info->ignore_falsable_return && $storage->return_type && ($codebase->config->ignore_internal_falsable_issues || !in_array($file_storage->file_path, $codebase->config->internal_stubs))) {
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $storage->return_type->ignore_falsable_issues = \true;
        }
        if ($stmt->returnsByRef() && $storage->return_type) {
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $storage->return_type->by_ref = \true;
        }
        $storage->return_type_description = $docblock_info->return_type_description;
    }
    private static function handleTaintFlow(FunctionDocblockComment $docblock_info, FunctionLikeStorage $storage) : void
    {
        if ($docblock_info->flows) {
            foreach ($docblock_info->flows as $flow) {
                $path_type = 'arg';
                $fancy_path_regex = '/-\\(([a-z\\-]+)\\)->/';
                if (preg_match($fancy_path_regex, $flow, $matches)) {
                    if (isset($matches[1])) {
                        $path_type = $matches[1];
                    }
                    $flow = preg_replace($fancy_path_regex, '->', $flow);
                }
                $flow_parts = explode('->', $flow);
                if (isset($flow_parts[1]) && trim($flow_parts[1]) === 'return') {
                    $source_param_string = trim($flow_parts[0]);
                    if ($source_param_string[0] === '(' && substr($source_param_string, -1) === ')') {
                        $source_params = preg_split('/, ?/', substr($source_param_string, 1, -1));
                        if ($source_params === \false) {
                            throw new AssertionError(preg_last_error_msg());
                        }
                        foreach ($source_params as $source_param) {
                            $source_param = substr($source_param, 1);
                            foreach ($storage->params as $i => $param_storage) {
                                if ($param_storage->name === $source_param) {
                                    $storage->return_source_params[$i] = $path_type;
                                }
                            }
                        }
                    }
                }
                if (isset($flow_parts[0]) && strpos(trim($flow_parts[0]), 'proxy') === 0) {
                    $proxy_call = trim(substr($flow_parts[0], strlen('proxy')));
                    [$fully_qualified_name, $source_param_string] = explode('(', $proxy_call, 2);
                    if (!empty($fully_qualified_name) && !empty($source_param_string)) {
                        $source_params = preg_split('/, ?/', substr($source_param_string, 0, -1)) ?: [];
                        $call_params = [];
                        foreach ($source_params as $source_param) {
                            $source_param = substr($source_param, 1);
                            foreach ($storage->params as $i => $param_storage) {
                                if ($param_storage->name === $source_param) {
                                    $call_params[] = $i;
                                }
                            }
                        }
                        if ($storage->proxy_calls === null) {
                            $storage->proxy_calls = [];
                        }
                        $storage->proxy_calls[] = ['fqn' => $fully_qualified_name, 'params' => $call_params, 'return' => isset($flow_parts[1]) && trim($flow_parts[1]) === 'return'];
                    }
                }
            }
        }
    }
    /**
     * @param array<string, TypeAlias> $type_aliases
     * @param array<string, non-empty-array<string, Union>> $function_template_types
     * @param array<string, non-empty-array<string, Union>> $class_template_types
     */
    private static function handleRemovedTaint(Codebase $codebase, PhpParser\Node\FunctionLike $stmt, Aliases $aliases, string $removed_taint, array $function_template_types, array $class_template_types, array $type_aliases, FunctionLikeStorage $storage, ?ClassLikeStorage $classlike_storage, string $cased_function_id, FileStorage $file_storage, FileScanner $file_scanner) : void
    {
        try {
            [$fixed_type_tokens, $function_template_types] = self::getConditionalSanitizedTypeTokens($removed_taint, $aliases, $function_template_types + $class_template_types, $type_aliases, $storage, $classlike_storage, $cased_function_id, $function_template_types);
            $removed_taint = TypeParser::parseTokens(array_values($fixed_type_tokens), null, $function_template_types + $class_template_types, $type_aliases);
            /** @psalm-suppress UnusedMethodCall */
            $removed_taint->queueClassLikesForScanning($codebase, $file_storage);
            $removed_taint_single = $removed_taint->getSingleAtomic();
            if (!$removed_taint_single instanceof TConditional) {
                throw new TypeParseTreeException('Escaped taint must be a conditional');
            }
            $storage->conditionally_removed_taints[] = $removed_taint;
        } catch (TypeParseTreeException $e) {
            $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $cased_function_id, new CodeLocation($file_scanner, $stmt, null, \true));
        }
    }
    /**
     * @param array<string, TypeAlias> $type_aliases
     * @param array<string, non-empty-array<string, Union>> $function_template_types
     * @param array<string, non-empty-array<string, Union>> $class_template_types
     */
    private static function handleAssertions(FunctionDocblockComment $docblock_info, FunctionLikeStorage $storage, Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, PhpParser\Node\FunctionLike $stmt, array $class_template_types, array $function_template_types, array $type_aliases, ?ClassLikeStorage $classlike_storage) : void
    {
        if ($docblock_info->assertions) {
            $storage->assertions = [];
            foreach ($docblock_info->assertions as $assertion) {
                $assertion_type_parts = self::getAssertionParts($codebase, $file_scanner, $file_storage, $aliases, $stmt, $storage, $assertion['type'], $class_template_types, $function_template_types, $type_aliases, $classlike_storage && !$classlike_storage->is_trait ? $classlike_storage->name : null);
                if (!$assertion_type_parts) {
                    continue;
                }
                foreach ($storage->params as $i => $param) {
                    if ($param->name === $assertion['param_name']) {
                        $storage->assertions[] = new Possibilities($i, $assertion_type_parts);
                        continue 2;
                    }
                    if (strpos($assertion['param_name'], $param->name . '->') === 0) {
                        $storage->assertions[] = new Possibilities(str_replace($param->name, (string) $i, $assertion['param_name']), $assertion_type_parts);
                        continue 2;
                    }
                }
                $storage->assertions[] = new Possibilities((strpos($assertion['param_name'], '$') === \false ? '$' : '') . $assertion['param_name'], $assertion_type_parts);
            }
        }
        if ($docblock_info->if_true_assertions) {
            $storage->if_true_assertions = [];
            foreach ($docblock_info->if_true_assertions as $assertion) {
                $assertion_type_parts = self::getAssertionParts($codebase, $file_scanner, $file_storage, $aliases, $stmt, $storage, $assertion['type'], $class_template_types, $function_template_types, $type_aliases, $classlike_storage && !$classlike_storage->is_trait ? $classlike_storage->name : null);
                if (!$assertion_type_parts) {
                    continue;
                }
                foreach ($storage->params as $i => $param) {
                    if ($param->name === $assertion['param_name']) {
                        $storage->if_true_assertions[] = new Possibilities($i, $assertion_type_parts);
                        continue 2;
                    }
                    if (strpos($assertion['param_name'], $param->name . '->') === 0) {
                        $storage->if_true_assertions[] = new Possibilities(str_replace($param->name, (string) $i, $assertion['param_name']), $assertion_type_parts);
                        continue 2;
                    }
                }
                $storage->if_true_assertions[] = new Possibilities((strpos($assertion['param_name'], '$') === \false ? '$' : '') . $assertion['param_name'], $assertion_type_parts);
            }
        }
        if ($docblock_info->if_false_assertions) {
            $storage->if_false_assertions = [];
            foreach ($docblock_info->if_false_assertions as $assertion) {
                $assertion_type_parts = self::getAssertionParts($codebase, $file_scanner, $file_storage, $aliases, $stmt, $storage, $assertion['type'], $class_template_types, $function_template_types, $type_aliases, $classlike_storage && !$classlike_storage->is_trait ? $classlike_storage->name : null);
                if (!$assertion_type_parts) {
                    continue;
                }
                foreach ($storage->params as $i => $param) {
                    if ($param->name === $assertion['param_name']) {
                        $storage->if_false_assertions[] = new Possibilities($i, $assertion_type_parts);
                        continue 2;
                    }
                    if (strpos($assertion['param_name'], $param->name . '->') === 0) {
                        $storage->if_false_assertions[] = new Possibilities(str_replace($param->name, (string) $i, $assertion['param_name']), $assertion_type_parts);
                        continue 2;
                    }
                }
                $storage->if_false_assertions[] = new Possibilities((strpos($assertion['param_name'], '$') === \false ? '$' : '') . $assertion['param_name'], $assertion_type_parts);
            }
        }
    }
    /**
     * @param array<string, TypeAlias> $type_aliases
     * @param array<string, array<string, Union>> $function_template_types
     * @param array<string, non-empty-array<string, Union>> $class_template_types
     * @param  array{name:string, type:string, line_number: int} $docblock_param_out
     */
    private static function handleParamOut(array $docblock_param_out, Aliases $aliases, array $function_template_types, array $class_template_types, array $type_aliases, string $cased_function_id, FileScanner $file_scanner, PhpParser\Node\FunctionLike $stmt, FunctionLikeStorage $storage, Codebase $codebase, FileStorage $file_storage) : void
    {
        $param_name = substr($docblock_param_out['name'], 1);
        try {
            $out_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($docblock_param_out['type'], $aliases, $function_template_types + $class_template_types, $type_aliases), null, $function_template_types + $class_template_types, $type_aliases);
        } catch (TypeParseTreeException $e) {
            $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $cased_function_id, new CodeLocation($file_scanner, $stmt, null, \true));
            return;
        }
        /** @psalm-suppress UnusedMethodCall */
        $out_type->queueClassLikesForScanning($codebase, $file_storage, $storage->template_types ?: []);
        foreach ($storage->params as $param_storage) {
            if ($param_storage->name === $param_name) {
                $param_storage->out_type = $out_type;
            }
        }
    }
    /**
     * @param ?array<string, non-empty-array<string, Union>> $template_types
     * @param array<string, TypeAlias> $type_aliases
     * @return array<string, non-empty-array<string, Union>>
     */
    private static function handleTemplates(FunctionLikeStorage $storage, FunctionDocblockComment $docblock_info, Aliases $aliases, ?array $template_types, array $type_aliases, FileScanner $file_scanner, PhpParser\Node\FunctionLike $stmt, string $cased_function_id) : array
    {
        $storage->template_types = [];
        foreach ($docblock_info->templates as $template_map) {
            $template_name = $template_map[0];
            if ($template_map[1] !== null && $template_map[2] !== null) {
                if (trim($template_map[2])) {
                    try {
                        $template_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($template_map[2], $aliases, $storage->template_types + ($template_types ?: []), $type_aliases), null, $storage->template_types + ($template_types ?: []), $type_aliases);
                    } catch (TypeParseTreeException $e) {
                        $storage->docblock_issues[] = new InvalidDocblock('Template ' . $template_name . ' has invalid as type - ' . $e->getMessage(), new CodeLocation($file_scanner, $stmt, null, \true));
                        $template_type = Type::getMixed();
                    }
                } else {
                    $storage->docblock_issues[] = new InvalidDocblock('Template ' . $template_name . ' missing as type', new CodeLocation($file_scanner, $stmt, null, \true));
                    $template_type = Type::getMixed();
                }
            } else {
                $template_type = Type::getMixed();
            }
            if (isset($template_types[$template_name])) {
                $storage->docblock_issues[] = new InvalidDocblock('Duplicate template param ' . $template_name . ' in docblock for ' . $cased_function_id, new CodeLocation($file_scanner, $stmt, null, \true));
            } else {
                $storage->template_types[$template_name] = ['fn-' . strtolower($cased_function_id) => $template_type];
            }
        }
        return array_merge($template_types ?: [], $storage->template_types);
    }
    private static function handleUnexpectedTags(FunctionDocblockComment $docblock_info, FunctionLikeStorage $storage, PhpParser\Node\FunctionLike $stmt, FileScanner $file_scanner, string $cased_function_id) : void
    {
        foreach ($docblock_info->unexpected_tags as $tag => $details) {
            foreach ($details['lines'] as $line) {
                $tag_location = new CodeLocation($file_scanner, $stmt, null, \true, null, null, $line);
                $message = 'Docblock tag @' . $tag . ' is not recognized in the function docblock ' . 'for ' . $cased_function_id;
                if (isset($details['suggested_replacement'])) {
                    $message .= ', did you mean to use @' . $details['suggested_replacement'] . '?';
                }
                $storage->docblock_issues[] = new PossiblyInvalidDocblockTag($message, $tag_location);
            }
        }
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\SimpleTypeInferer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Storage\AttributeArg;
use Psalm\Storage\AttributeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Type;
use function strtolower;
/**
 * @internal
 */
class AttributeResolver
{
    public static function resolve(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, PhpParser\Node\Attribute $stmt, ?string $fq_classlike_name) : AttributeStorage
    {
        if ($stmt->name instanceof PhpParser\Node\Name\FullyQualified) {
            $fq_type_string = (string) $stmt->name;
        } else {
            $fq_type_string = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->name, $aliases);
        }
        $codebase->scanner->queueClassLikeForScanning($fq_type_string);
        $file_storage->referenced_classlikes[strtolower($fq_type_string)] = $fq_type_string;
        $args = [];
        foreach ($stmt->args as $arg_node) {
            $key = $arg_node->name->name ?? null;
            $const_type = SimpleTypeInferer::infer($codebase, new NodeDataProvider(), $arg_node->value, $aliases, null, [], $fq_classlike_name);
            if (!$const_type) {
                $const_type = \Psalm\Internal\PhpVisitor\Reflector\ExpressionResolver::getUnresolvedClassConstExpr($arg_node->value, $aliases, $fq_classlike_name);
            }
            if (!$const_type) {
                $const_type = Type::getMixed();
            }
            $args[] = new AttributeArg($key, $const_type, new CodeLocation($file_scanner, $arg_node->value));
        }
        return new AttributeStorage($fq_type_string, $args, new CodeLocation($file_scanner, $stmt), new CodeLocation($file_scanner, $stmt->name));
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\IntersectionType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\NullableType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\UnionType;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Issue\ParseError;
use Psalm\IssueBuffer;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use UnexpectedValueException;
use function implode;
use function strtolower;
/**
 * @internal
 */
class TypeHintResolver
{
    /**
     * @param Identifier|IntersectionType|Name|NullableType|UnionType $hint
     */
    public static function resolve(PhpParser\NodeAbstract $hint, CodeLocation $code_location, Codebase $codebase, FileStorage $file_storage, ?ClassLikeStorage $classlike_storage, Aliases $aliases, int $analysis_php_version_id) : Union
    {
        if ($hint instanceof PhpParser\Node\UnionType) {
            $type = null;
            if (!$hint->types) {
                throw new UnexpectedValueException('Union type should not be empty');
            }
            if ($analysis_php_version_id < 80000) {
                IssueBuffer::maybeAdd(new ParseError('Union types are not supported in PHP < 8', $code_location));
            }
            foreach ($hint->types as $atomic_typehint) {
                $resolved_type = self::resolve($atomic_typehint, $code_location, $codebase, $file_storage, $classlike_storage, $aliases, $analysis_php_version_id);
                $type = Type::combineUnionTypes($resolved_type, $type);
            }
            return $type;
        }
        if ($hint instanceof PhpParser\Node\IntersectionType) {
            $type = null;
            if (!$hint->types) {
                throw new UnexpectedValueException('Intersection type should not be empty');
            }
            if ($analysis_php_version_id < 80100) {
                IssueBuffer::maybeAdd(new ParseError('Intersection types are not supported in PHP < 8.1', $code_location));
            }
            foreach ($hint->types as $atomic_typehint) {
                $resolved_type = self::resolve($atomic_typehint, $code_location, $codebase, $file_storage, $classlike_storage, $aliases, $analysis_php_version_id);
                if ($resolved_type->hasScalarType()) {
                    IssueBuffer::maybeAdd(new ParseError('Intersection types cannot contain scalar types', $code_location));
                }
                $type = Type::intersectUnionTypes($resolved_type, $type, $codebase);
            }
            if ($type === null) {
                $type = Type::getNever();
            }
            return $type;
        }
        $is_nullable = \false;
        if ($hint instanceof PhpParser\Node\NullableType) {
            $is_nullable = \true;
            $hint = $hint->type;
        }
        $type_string = null;
        if ($hint instanceof PhpParser\Node\Identifier) {
            $fq_type_string = $hint->name;
        } elseif ($hint instanceof PhpParser\Node\Name\FullyQualified) {
            $fq_type_string = (string) $hint;
            $codebase->scanner->queueClassLikeForScanning($fq_type_string);
            $file_storage->referenced_classlikes[strtolower($fq_type_string)] = $fq_type_string;
        } else {
            $lower_hint = strtolower($hint->parts[0]);
            if ($classlike_storage && ($lower_hint === 'self' || $lower_hint === 'static') && !$classlike_storage->is_trait) {
                $fq_type_string = $classlike_storage->name;
                if ($lower_hint === 'static') {
                    $fq_type_string .= '&static';
                }
            } else {
                $type_string = implode('\\', $hint->parts);
                $fq_type_string = ClassLikeAnalyzer::getFQCLNFromNameObject($hint, $aliases);
                $codebase->scanner->queueClassLikeForScanning($fq_type_string);
                $file_storage->referenced_classlikes[strtolower($fq_type_string)] = $fq_type_string;
            }
        }
        $type = Type::parseString($fq_type_string, $analysis_php_version_id, []);
        if ($type_string) {
            $atomic_type = $type->getSingleAtomic();
            /** @psalm-suppress InaccessibleProperty We just created this type */
            $atomic_type->text = $type_string;
        }
        if ($is_nullable) {
            $type = $type->getBuilder()->addType(new TNull())->freeze();
        }
        return $type;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use Exception;
use InvalidArgumentException;
use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Concat;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\IntersectionType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\NullableType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\UnionType;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Exception\InvalidClasslikeOverrideException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Analyzer\ClassAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\SimpleTypeInferer;
use Psalm\Internal\Codebase\PropertyMap;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Scanner\ClassLikeDocblockComment;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Internal\Type\TypeAlias;
use Psalm\Internal\Type\TypeAlias\ClassTypeAlias;
use Psalm\Internal\Type\TypeAlias\InlineTypeAlias;
use Psalm\Internal\Type\TypeAlias\LinkableTypeAlias;
use Psalm\Internal\Type\TypeParser;
use Psalm\Internal\Type\TypeTokenizer;
use Psalm\Issue\ConstantDeclarationInTrait;
use Psalm\Issue\DuplicateClass;
use Psalm\Issue\DuplicateConstant;
use Psalm\Issue\DuplicateEnumCase;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\InvalidEnumBackingType;
use Psalm\Issue\InvalidEnumCaseValue;
use Psalm\Issue\InvalidTypeImport;
use Psalm\Issue\MissingDocblockType;
use Psalm\Issue\ParseError;
use Psalm\IssueBuffer;
use Psalm\Storage\AttributeStorage;
use Psalm\Storage\ClassConstantStorage;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\EnumCaseStorage;
use Psalm\Storage\FileStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Storage\PropertyStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use RuntimeException;
use UnexpectedValueException;
use function array_merge;
use function array_pop;
use function array_shift;
use function array_values;
use function assert;
use function count;
use function get_class;
use function implode;
use function is_int;
use function is_string;
use function preg_match;
use function preg_replace;
use function preg_split;
use function str_replace;
use function strtolower;
use function trim;
use function usort;
use const PREG_SPLIT_DELIM_CAPTURE;
use const PREG_SPLIT_NO_EMPTY;
/**
 * @internal
 */
class ClassLikeNodeScanner
{
    private FileScanner $file_scanner;
    private Codebase $codebase;
    private string $file_path;
    private Config $config;
    private FileStorage $file_storage;
    /**
     * @var array<string, InlineTypeAlias>
     */
    private array $classlike_type_aliases = [];
    /**
     * @var array<string, array<string, Union>>
     */
    public array $class_template_types = [];
    private ?Name $namespace_name = null;
    private Aliases $aliases;
    public ?ClassLikeStorage $storage = null;
    /**
     * @var array<string, TypeAlias>
     */
    public array $type_aliases = [];
    public function __construct(Codebase $codebase, FileStorage $file_storage, FileScanner $file_scanner, Aliases $aliases, ?Name $namespace_name)
    {
        $this->codebase = $codebase;
        $this->file_storage = $file_storage;
        $this->file_scanner = $file_scanner;
        $this->file_path = $file_storage->file_path;
        $this->aliases = $aliases;
        $this->config = Config::getInstance();
        $this->namespace_name = $namespace_name;
    }
    /**
     * @return false|null
     */
    public function start(PhpParser\Node\Stmt\ClassLike $node) : ?bool
    {
        $class_location = new CodeLocation($this->file_scanner, $node);
        $name_location = null;
        $storage = null;
        $class_name = null;
        $is_classlike_overridden = \false;
        if ($node->name === null) {
            if (!$node instanceof PhpParser\Node\Stmt\Class_) {
                throw new LogicException('Anonymous classes are always classes');
            }
            $fq_classlike_name = ClassAnalyzer::getAnonymousClassName($node, $this->file_path);
        } else {
            $name_location = new CodeLocation($this->file_scanner, $node->name);
            $fq_classlike_name = ($this->aliases->namespace ? $this->aliases->namespace . '\\' : '') . $node->name->name;
            assert($fq_classlike_name !== "");
            $fq_classlike_name_lc = strtolower($fq_classlike_name);
            $class_name = $node->name->name;
            if ($this->codebase->classlike_storage_provider->has($fq_classlike_name_lc)) {
                $duplicate_storage = $this->codebase->classlike_storage_provider->get($fq_classlike_name_lc);
                if (!$this->codebase->register_stub_files) {
                    if (!$duplicate_storage->stmt_location || $duplicate_storage->stmt_location->file_path !== $this->file_path || $class_location->getHash() !== $duplicate_storage->stmt_location->getHash()) {
                        IssueBuffer::maybeAdd(new DuplicateClass('Class ' . $fq_classlike_name . ' has already been defined' . ($duplicate_storage->location ? ' in ' . $duplicate_storage->location->file_path : ''), $name_location));
                        $this->file_storage->has_visitor_issues = \true;
                        $duplicate_storage->has_visitor_issues = \true;
                        return \false;
                    }
                } elseif (!$duplicate_storage->location || $duplicate_storage->location->file_path !== $this->file_path || $class_location->getHash() !== $duplicate_storage->location->getHash()) {
                    $is_classlike_overridden = \true;
                    // we're overwriting some methods
                    $storage = $this->storage = $duplicate_storage;
                    $this->codebase->classlike_storage_provider->makeNew(strtolower($fq_classlike_name));
                    $storage->populated = \false;
                    $storage->class_implements = [];
                    // we do this because reflection reports
                    $storage->parent_interfaces = [];
                    $storage->stubbed = \true;
                    $storage->aliases = $this->aliases;
                    foreach ($storage->dependent_classlikes as $dependent_name_lc => $_) {
                        try {
                            $dependent_storage = $this->codebase->classlike_storage_provider->get($dependent_name_lc);
                        } catch (InvalidArgumentException $exception) {
                            continue;
                        }
                        $dependent_storage->populated = \false;
                        $this->codebase->classlike_storage_provider->makeNew($dependent_name_lc);
                    }
                }
            }
        }
        $fq_classlike_name_lc = strtolower($fq_classlike_name);
        $this->file_storage->classlikes_in_file[$fq_classlike_name_lc] = $fq_classlike_name;
        if (!$storage) {
            $this->storage = $storage = $this->codebase->classlike_storage_provider->create($fq_classlike_name);
        }
        if ($class_name && isset($this->aliases->uses[strtolower($class_name)]) && $this->aliases->uses[strtolower($class_name)] !== $fq_classlike_name) {
            IssueBuffer::maybeAdd(new ParseError('Class name ' . $class_name . ' clashes with a use statement alias', $name_location ?? $class_location));
            $storage->has_visitor_issues = \true;
            $this->file_storage->has_visitor_issues = \true;
        }
        $storage->stmt_location = $class_location;
        $storage->location = $name_location;
        if ($this->namespace_name) {
            $storage->namespace_name_location = new CodeLocation($this->file_scanner, $this->namespace_name);
        }
        $storage->user_defined = !$this->codebase->register_stub_files;
        $storage->stubbed = $this->codebase->register_stub_files;
        $storage->aliases = $this->aliases;
        if ($node instanceof PhpParser\Node\Stmt\Class_) {
            $storage->abstract = $node->isAbstract();
            $storage->final = $node->isFinal();
            $this->codebase->classlikes->addFullyQualifiedClassName($fq_classlike_name, $this->file_path);
            if ($node->extends) {
                $parent_fqcln = ClassLikeAnalyzer::getFQCLNFromNameObject($node->extends, $this->aliases);
                $parent_fqcln = $this->codebase->classlikes->getUnAliasedName($parent_fqcln);
                $this->codebase->scanner->queueClassLikeForScanning($parent_fqcln, $this->file_scanner->will_analyze);
                $parent_fqcln_lc = strtolower($parent_fqcln);
                $storage->parent_class = $parent_fqcln;
                $storage->parent_classes[$parent_fqcln_lc] = $parent_fqcln;
                $this->file_storage->required_classes[strtolower($parent_fqcln)] = $parent_fqcln;
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\Interface_) {
            $storage->is_interface = \true;
            $this->codebase->classlikes->addFullyQualifiedInterfaceName($fq_classlike_name, $this->file_path);
            foreach ($node->extends as $interface) {
                $interface_fqcln = ClassLikeAnalyzer::getFQCLNFromNameObject($interface, $this->aliases);
                $interface_fqcln = $this->codebase->classlikes->getUnAliasedName($interface_fqcln);
                $interface_fqcln_lc = strtolower($interface_fqcln);
                $this->codebase->scanner->queueClassLikeForScanning($interface_fqcln);
                $storage->parent_interfaces[$interface_fqcln_lc] = $interface_fqcln;
                $storage->direct_interface_parents[$interface_fqcln_lc] = $interface_fqcln;
                $this->file_storage->required_interfaces[$interface_fqcln_lc] = $interface_fqcln;
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\Trait_) {
            $storage->is_trait = \true;
            $this->codebase->classlikes->addFullyQualifiedTraitName($fq_classlike_name, $this->file_path);
        } elseif ($node instanceof PhpParser\Node\Stmt\Enum_) {
            $storage->is_enum = \true;
            $storage->final = \true;
            if ($node->scalarType) {
                if ($node->scalarType->name === 'string' || $node->scalarType->name === 'int') {
                    $storage->enum_type = $node->scalarType->name;
                    $storage->class_implements['backedenum'] = 'BackedEnum';
                    $storage->direct_class_interfaces['backedenum'] = 'BackedEnum';
                    $this->file_storage->required_interfaces['backedenum'] = 'BackedEnum';
                    $this->codebase->scanner->queueClassLikeForScanning('BackedEnum');
                    $storage->declaring_method_ids['from'] = new MethodIdentifier('BackedEnum', 'from');
                    $storage->appearing_method_ids['from'] = $storage->declaring_method_ids['from'];
                    $storage->declaring_method_ids['tryfrom'] = new MethodIdentifier('BackedEnum', 'tryfrom');
                    $storage->appearing_method_ids['tryfrom'] = $storage->declaring_method_ids['tryfrom'];
                } else {
                    IssueBuffer::maybeAdd(new InvalidEnumBackingType('Enums cannot be backed by ' . $node->scalarType->name . ', string or int expected', new CodeLocation($this->file_scanner, $node->scalarType), $fq_classlike_name));
                    $this->file_storage->has_visitor_issues = \true;
                    $storage->has_visitor_issues = \true;
                }
            }
            $this->codebase->scanner->queueClassLikeForScanning('UnitEnum');
            $storage->class_implements['unitenum'] = 'UnitEnum';
            $storage->direct_class_interfaces['unitenum'] = 'UnitEnum';
            $this->file_storage->required_interfaces['unitenum'] = 'UnitEnum';
            $storage->final = \true;
            $storage->declaring_method_ids['cases'] = new MethodIdentifier('UnitEnum', 'cases');
            $storage->appearing_method_ids['cases'] = $storage->declaring_method_ids['cases'];
            $this->codebase->classlikes->addFullyQualifiedEnumName($fq_classlike_name, $this->file_path);
        } else {
            throw new UnexpectedValueException('Unknown classlike type');
        }
        if ($node instanceof PhpParser\Node\Stmt\Class_ || $node instanceof PhpParser\Node\Stmt\Enum_) {
            foreach ($node->implements as $interface) {
                $interface_fqcln = ClassLikeAnalyzer::getFQCLNFromNameObject($interface, $this->aliases);
                $interface_fqcln_lc = strtolower($interface_fqcln);
                $this->codebase->scanner->queueClassLikeForScanning($interface_fqcln);
                $storage->class_implements[$interface_fqcln_lc] = $interface_fqcln;
                $storage->direct_class_interfaces[$interface_fqcln_lc] = $interface_fqcln;
                $this->file_storage->required_interfaces[$interface_fqcln_lc] = $interface_fqcln;
            }
        }
        $docblock_info = null;
        $doc_comment = $node->getDocComment();
        if ($doc_comment) {
            try {
                $docblock_info = \Psalm\Internal\PhpVisitor\Reflector\ClassLikeDocblockParser::parse($node, $doc_comment, $this->aliases);
                $this->type_aliases += $this->getImportedTypeAliases($docblock_info, $fq_classlike_name);
            } catch (DocblockParseException $e) {
                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $fq_classlike_name, $name_location ?? $class_location);
            }
        }
        foreach ($node->getComments() as $comment) {
            if (!$comment instanceof PhpParser\Comment\Doc) {
                continue;
            }
            try {
                $type_aliases = self::getTypeAliasesFromComment($comment, $this->aliases, $this->type_aliases, $fq_classlike_name);
                foreach ($type_aliases as $type_alias) {
                    // finds issues, if there are any
                    TypeParser::parseTokens($type_alias->replacement_tokens);
                }
                $this->type_aliases += $type_aliases;
                if ($type_aliases) {
                    $this->classlike_type_aliases = $type_aliases;
                }
            } catch (DocblockParseException|TypeParseTreeException $e) {
                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage(), new CodeLocation($this->file_scanner, $node, null, \true));
            }
        }
        if ($docblock_info) {
            if ($docblock_info->stub_override && !$is_classlike_overridden) {
                throw new InvalidClasslikeOverrideException('Class/interface/trait ' . $fq_classlike_name . ' is marked as stub override,' . ' but no original counterpart found');
            }
            if ($docblock_info->templates) {
                $storage->template_types = [];
                usort($docblock_info->templates, static fn(array $l, array $r): int => $l[4] > $r[4] ? 1 : -1);
                foreach ($docblock_info->templates as $i => $template_map) {
                    $template_name = $template_map[0];
                    if ($template_map[1] !== null && $template_map[2] !== null) {
                        if (trim($template_map[2])) {
                            try {
                                $template_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($template_map[2], $this->aliases, $storage->template_types, $this->type_aliases), null, $storage->template_types, $this->type_aliases);
                            } catch (TypeParseTreeException $e) {
                                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $fq_classlike_name, $name_location ?? $class_location);
                                continue;
                            }
                            $storage->template_types[$template_name] = [$fq_classlike_name => $template_type];
                        } else {
                            $storage->docblock_issues[] = new InvalidDocblock('Template missing as type', $name_location ?? $class_location);
                        }
                    } else {
                        /** @psalm-suppress PropertyTypeCoercion due to a Psalm bug */
                        $storage->template_types[$template_name][$fq_classlike_name] = Type::getMixed();
                    }
                    $storage->template_covariants[$i] = $template_map[3];
                }
                $this->class_template_types = $storage->template_types;
            }
            foreach ($docblock_info->template_extends as $extended_class_name) {
                $this->extendTemplatedType($storage, $node, $extended_class_name);
            }
            foreach ($docblock_info->template_implements as $implemented_class_name) {
                $this->implementTemplatedType($storage, $node, $implemented_class_name);
            }
            if ($docblock_info->yield) {
                try {
                    $yield_type_tokens = TypeTokenizer::getFullyQualifiedTokens($docblock_info->yield, $this->aliases, $storage->template_types, $this->type_aliases);
                    $yield_type = TypeParser::parseTokens($yield_type_tokens, null, $storage->template_types ?: [], $this->type_aliases, \true);
                    /** @psalm-suppress UnusedMethodCall */
                    $yield_type->queueClassLikesForScanning($this->codebase, $this->file_storage, $storage->template_types ?: []);
                    $storage->yield = $yield_type;
                } catch (TypeParseTreeException $e) {
                    // do nothing
                }
            }
            if ($docblock_info->extension_requirement !== null) {
                $storage->extension_requirement = (string) TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($docblock_info->extension_requirement, $this->aliases, $this->class_template_types, $this->type_aliases), null, $this->class_template_types, $this->type_aliases);
            }
            foreach ($docblock_info->implementation_requirements as $implementation_requirement) {
                $storage->implementation_requirements[] = (string) TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($implementation_requirement, $this->aliases, $this->class_template_types, $this->type_aliases), null, $this->class_template_types, $this->type_aliases);
            }
            $storage->sealed_properties = $docblock_info->sealed_properties;
            $storage->sealed_methods = $docblock_info->sealed_methods;
            if ($docblock_info->properties) {
                foreach ($docblock_info->properties as $property) {
                    $pseudo_property_type_tokens = TypeTokenizer::getFullyQualifiedTokens($property['type'], $this->aliases, $this->class_template_types, $this->type_aliases);
                    try {
                        $pseudo_property_type = TypeParser::parseTokens($pseudo_property_type_tokens, null, $this->class_template_types, $this->type_aliases, \true);
                        /** @psalm-suppress UnusedMethodCall */
                        $pseudo_property_type->queueClassLikesForScanning($this->codebase, $this->file_storage, $storage->template_types ?: []);
                        if ($property['tag'] !== 'property-read' && $property['tag'] !== 'psalm-property-read') {
                            $storage->pseudo_property_set_types[$property['name']] = $pseudo_property_type;
                        }
                        if ($property['tag'] !== 'property-write' && $property['tag'] !== 'psalm-property-write') {
                            $storage->pseudo_property_get_types[$property['name']] = $pseudo_property_type;
                        }
                    } catch (TypeParseTreeException $e) {
                        $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $fq_classlike_name, $name_location ?? $class_location);
                    }
                }
                $storage->sealed_properties = \true;
            }
            foreach ($docblock_info->methods as $method) {
                $functionlike_node_scanner = new \Psalm\Internal\PhpVisitor\Reflector\FunctionLikeNodeScanner($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $this->type_aliases, $this->storage, []);
                /** @var MethodStorage */
                $pseudo_method_storage = $functionlike_node_scanner->start($method, \true);
                $lc_method_name = strtolower($method->name->name);
                if ($pseudo_method_storage->is_static) {
                    $storage->pseudo_static_methods[$lc_method_name] = $pseudo_method_storage;
                } else {
                    $storage->pseudo_methods[$lc_method_name] = $pseudo_method_storage;
                    $storage->declaring_pseudo_method_ids[$lc_method_name] = new MethodIdentifier($fq_classlike_name, $lc_method_name);
                }
                $storage->sealed_methods = \true;
            }
            $storage->deprecated = $docblock_info->deprecated;
            if (count($docblock_info->psalm_internal) !== 0) {
                $storage->internal = $docblock_info->psalm_internal;
            } elseif ($docblock_info->internal && $this->aliases->namespace) {
                $storage->internal = [NamespaceAnalyzer::getNameSpaceRoot($this->aliases->namespace)];
            }
            if ($docblock_info->final && !$storage->final) {
                $storage->final = \true;
                $storage->final_from_docblock = \true;
            }
            $storage->preserve_constructor_signature = $docblock_info->consistent_constructor;
            if ($storage->preserve_constructor_signature) {
                $has_constructor = \false;
                foreach ($node->stmts as $stmt) {
                    if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod && $stmt->name->name === '__construct') {
                        $has_constructor = \true;
                        break;
                    }
                }
                if (!$has_constructor) {
                    self::registerEmptyConstructor($storage);
                }
            }
            $storage->enforce_template_inheritance = $docblock_info->consistent_templates;
            foreach ($docblock_info->mixins as $key => $mixin) {
                $mixin_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($mixin, $this->aliases, $this->class_template_types, $this->type_aliases, $fq_classlike_name), null, $this->class_template_types, $this->type_aliases, \true);
                /** @psalm-suppress UnusedMethodCall */
                $mixin_type->queueClassLikesForScanning($this->codebase, $this->file_storage, $storage->template_types ?: []);
                if ($mixin_type->isSingle()) {
                    $mixin_type = $mixin_type->getSingleAtomic();
                    if ($mixin_type instanceof TNamedObject) {
                        $storage->namedMixins[] = $mixin_type;
                    }
                    if ($mixin_type instanceof TTemplateParam) {
                        $storage->templatedMixins[] = $mixin_type;
                    }
                }
                if ($key === 0) {
                    $storage->mixin_declaring_fqcln = $storage->name;
                }
            }
            $storage->mutation_free = $docblock_info->mutation_free;
            $storage->external_mutation_free = $docblock_info->external_mutation_free;
            $storage->specialize_instance = $docblock_info->taint_specialize;
            $storage->override_property_visibility = $docblock_info->override_property_visibility;
            $storage->override_method_visibility = $docblock_info->override_method_visibility;
            $storage->suppressed_issues = $docblock_info->suppressed_issues;
            if ($docblock_info->description) {
                $storage->description = $docblock_info->description;
            }
            $storage->public_api = $docblock_info->public_api;
        }
        foreach ($node->stmts as $node_stmt) {
            if ($node_stmt instanceof PhpParser\Node\Stmt\ClassConst) {
                $this->visitClassConstDeclaration($node_stmt, $storage, $fq_classlike_name);
            } elseif ($node_stmt instanceof PhpParser\Node\Stmt\EnumCase && $node instanceof PhpParser\Node\Stmt\Enum_) {
                $this->visitEnumDeclaration($node_stmt, $storage, $fq_classlike_name);
            }
        }
        if ($storage->is_enum) {
            $name_types = [];
            $values_types = [];
            foreach ($storage->enum_cases as $name => $enumCaseStorage) {
                $name_types[] = new Type\Atomic\TLiteralString($name);
                if ($storage->enum_type !== null) {
                    if (is_string($enumCaseStorage->value)) {
                        $values_types[] = new Type\Atomic\TLiteralString($enumCaseStorage->value);
                    } elseif (is_int($enumCaseStorage->value)) {
                        $values_types[] = new Type\Atomic\TLiteralInt($enumCaseStorage->value);
                    }
                }
            }
            if ($name_types !== []) {
                $storage->declaring_property_ids['name'] = $storage->name;
                $storage->appearing_property_ids['name'] = "{$storage->name}::\$name";
                $storage->properties['name'] = new PropertyStorage();
                $storage->properties['name']->type = new Union($name_types);
            }
            if ($values_types !== []) {
                $storage->declaring_property_ids['value'] = $storage->name;
                $storage->appearing_property_ids['value'] = "{$storage->name}::\$value";
                $storage->properties['value'] = new PropertyStorage();
                $storage->properties['value']->type = new Union($values_types);
            }
        }
        foreach ($node->stmts as $node_stmt) {
            if ($node_stmt instanceof PhpParser\Node\Stmt\Property) {
                $this->visitPropertyDeclaration($node_stmt, $this->config, $storage, $fq_classlike_name);
            }
        }
        foreach ($node->attrGroups as $attr_group) {
            foreach ($attr_group->attrs as $attr) {
                $attribute = \Psalm\Internal\PhpVisitor\Reflector\AttributeResolver::resolve($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $attr, $this->storage->name ?? null);
                if ($attribute->fq_class_name === 'Psalm\\Deprecated' || $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Deprecated') {
                    $storage->deprecated = \true;
                }
                if ($attribute->fq_class_name === 'Psalm\\Internal' && !$storage->internal) {
                    $storage->internal = [NamespaceAnalyzer::getNameSpaceRoot($fq_classlike_name)];
                }
                if ($attribute->fq_class_name === 'Psalm\\Immutable' || $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Immutable') {
                    $storage->mutation_free = \true;
                    $storage->external_mutation_free = \true;
                }
                if ($attribute->fq_class_name === 'Psalm\\ExternalMutationFree') {
                    $storage->external_mutation_free = \true;
                }
                $storage->attributes[] = $attribute;
            }
        }
        return null;
    }
    public function finish(PhpParser\Node\Stmt\ClassLike $node) : ClassLikeStorage
    {
        if (!$this->storage) {
            throw new UnexpectedValueException('Storage should exist in ' . $this->file_path . ' at ' . $node->getLine());
        }
        $classlike_storage = $this->storage;
        $fq_classlike_name = $classlike_storage->name;
        if (PropertyMap::inPropertyMap($fq_classlike_name)) {
            $mapped_properties = PropertyMap::getPropertyMap()[strtolower($fq_classlike_name)];
            foreach ($mapped_properties as $property_name => $public_mapped_property) {
                $property_type = Type::parseString($public_mapped_property);
                /** @psalm-suppress UnusedMethodCall */
                $property_type->queueClassLikesForScanning($this->codebase, $this->file_storage);
                if (!isset($classlike_storage->properties[$property_name])) {
                    $classlike_storage->properties[$property_name] = new PropertyStorage();
                }
                $classlike_storage->properties[$property_name]->type = $property_type;
                $property_id = $fq_classlike_name . '::$' . $property_name;
                $classlike_storage->declaring_property_ids[$property_name] = $fq_classlike_name;
                $classlike_storage->appearing_property_ids[$property_name] = $property_id;
            }
        }
        $converted_aliases = [];
        foreach ($this->classlike_type_aliases as $key => $type) {
            try {
                $union = TypeParser::parseTokens($type->replacement_tokens, null, [], $this->type_aliases, \true);
                $converted_aliases[$key] = new ClassTypeAlias(array_values($union->getAtomicTypes()));
            } catch (TypeParseTreeException $e) {
                $classlike_storage->docblock_issues[] = new InvalidDocblock('@psalm-type ' . $key . ' contains invalid reference: ' . $e->getMessage(), new CodeLocation($this->file_scanner, $node, null, \true));
            } catch (Exception $e) {
                $classlike_storage->docblock_issues[] = new InvalidDocblock('@psalm-type ' . $key . ' contains invalid references', new CodeLocation($this->file_scanner, $node, null, \true));
            }
        }
        $classlike_storage->type_aliases = $converted_aliases;
        return $classlike_storage;
    }
    public function handleTraitUse(PhpParser\Node\Stmt\TraitUse $node) : void
    {
        $storage = $this->storage;
        if (!$storage) {
            throw new UnexpectedValueException('bad');
        }
        foreach ($node->adaptations as $adaptation) {
            if ($adaptation instanceof PhpParser\Node\Stmt\TraitUseAdaptation\Alias) {
                $old_name = strtolower($adaptation->method->name);
                $new_name = $old_name;
                if ($adaptation->newName) {
                    $new_name = strtolower($adaptation->newName->name);
                    if ($new_name !== $old_name) {
                        $storage->trait_alias_map[$new_name] = $old_name;
                        $storage->trait_alias_map_cased[$adaptation->newName->name] = $adaptation->method->name;
                    }
                }
                if ($adaptation->newModifier) {
                    switch ($adaptation->newModifier) {
                        case 1:
                            $storage->trait_visibility_map[$new_name] = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
                            break;
                        case 2:
                            $storage->trait_visibility_map[$new_name] = ClassLikeAnalyzer::VISIBILITY_PROTECTED;
                            break;
                        case 4:
                            $storage->trait_visibility_map[$new_name] = ClassLikeAnalyzer::VISIBILITY_PRIVATE;
                            break;
                        case 32:
                            $storage->trait_final_map[$new_name] = \true;
                            break;
                    }
                }
            }
        }
        foreach ($node->traits as $trait) {
            $trait_fqcln = ClassLikeAnalyzer::getFQCLNFromNameObject($trait, $this->aliases);
            $this->codebase->scanner->queueClassLikeForScanning($trait_fqcln, $this->file_scanner->will_analyze);
            $storage->used_traits[strtolower($trait_fqcln)] = $trait_fqcln;
            $this->file_storage->required_classes[strtolower($trait_fqcln)] = $trait_fqcln;
        }
        if ($node_comment = $node->getDocComment()) {
            $comments = DocComment::parsePreservingLength($node_comment);
            if (isset($comments->combined_tags['use'])) {
                foreach ($comments->combined_tags['use'] as $template_line) {
                    $this->useTemplatedType($storage, $node, trim(preg_replace('@^[ \\t]*\\*@m', '', $template_line)));
                }
            }
            if (isset($comments->tags['template-extends']) || isset($comments->tags['extends']) || isset($comments->tags['template-implements']) || isset($comments->tags['implements'])) {
                $storage->docblock_issues[] = new InvalidDocblock('You must use @use or @template-use to parameterize traits', new CodeLocation($this->file_scanner, $node, null, \true));
            }
        }
    }
    private function extendTemplatedType(ClassLikeStorage $storage, PhpParser\Node\Stmt\ClassLike $node, string $extended_class_name) : void
    {
        if (trim($extended_class_name) === '') {
            $storage->docblock_issues[] = new InvalidDocblock('Extended class cannot be empty in docblock for ' . $storage->name, new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        try {
            $extended_union_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($extended_class_name, $this->aliases, $this->class_template_types, $this->type_aliases), null, $this->class_template_types, $this->type_aliases, \true);
        } catch (TypeParseTreeException $e) {
            $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $storage->name, new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        if (!$extended_union_type->isSingle()) {
            $storage->docblock_issues[] = new InvalidDocblock('@template-extends cannot be a union type', new CodeLocation($this->file_scanner, $node, null, \true));
        }
        /** @psalm-suppress UnusedMethodCall */
        $extended_union_type->queueClassLikesForScanning($this->codebase, $this->file_storage, $storage->template_types ?: []);
        foreach ($extended_union_type->getAtomicTypes() as $atomic_type) {
            if (!$atomic_type instanceof TGenericObject) {
                $storage->docblock_issues[] = new InvalidDocblock('@template-extends has invalid class ' . $atomic_type->getId(), new CodeLocation($this->file_scanner, $node, null, \true));
                return;
            }
            $generic_class_lc = strtolower($atomic_type->value);
            if (!isset($storage->parent_classes[$generic_class_lc]) && !isset($storage->parent_interfaces[$generic_class_lc])) {
                $storage->docblock_issues[] = new InvalidDocblock('@template-extends must include the name of an extended class,' . ' got ' . $atomic_type->getId(), new CodeLocation($this->file_scanner, $node, null, \true));
            }
            $extended_type_parameters = [];
            $storage->template_type_extends_count[$atomic_type->value] = count($atomic_type->type_params);
            foreach ($atomic_type->type_params as $type_param) {
                $extended_type_parameters[] = $type_param;
            }
            $storage->template_extended_offsets[$atomic_type->value] = $extended_type_parameters;
        }
    }
    private function implementTemplatedType(ClassLikeStorage $storage, PhpParser\Node\Stmt\ClassLike $node, string $implemented_class_name) : void
    {
        if (trim($implemented_class_name) === '') {
            $storage->docblock_issues[] = new InvalidDocblock('Extended class cannot be empty in docblock for ' . $storage->name, new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        try {
            $implemented_union_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($implemented_class_name, $this->aliases, $this->class_template_types, $this->type_aliases), null, $this->class_template_types, $this->type_aliases, \true);
        } catch (TypeParseTreeException $e) {
            $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $storage->name, new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        if (!$implemented_union_type->isSingle()) {
            $storage->docblock_issues[] = new InvalidDocblock('@template-implements cannot be a union type', new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        /** @psalm-suppress UnusedMethodCall */
        $implemented_union_type->queueClassLikesForScanning($this->codebase, $this->file_storage, $storage->template_types ?: []);
        foreach ($implemented_union_type->getAtomicTypes() as $atomic_type) {
            if (!$atomic_type instanceof TGenericObject) {
                $storage->docblock_issues[] = new InvalidDocblock('@template-implements has invalid class ' . $atomic_type->getId(), new CodeLocation($this->file_scanner, $node, null, \true));
                return;
            }
            $generic_class_lc = strtolower($atomic_type->value);
            if (!isset($storage->class_implements[$generic_class_lc])) {
                $storage->docblock_issues[] = new InvalidDocblock('@template-implements must include the name of an implemented class,' . ' got ' . $atomic_type->getId(), new CodeLocation($this->file_scanner, $node, null, \true));
                return;
            }
            $implemented_type_parameters = [];
            $storage->template_type_implements_count[$generic_class_lc] = count($atomic_type->type_params);
            foreach ($atomic_type->type_params as $type_param) {
                $implemented_type_parameters[] = $type_param;
            }
            $storage->template_extended_offsets[$atomic_type->value] = $implemented_type_parameters;
        }
    }
    private function useTemplatedType(ClassLikeStorage $storage, PhpParser\Node\Stmt\TraitUse $node, string $used_class_name) : void
    {
        if (trim($used_class_name) === '') {
            $storage->docblock_issues[] = new InvalidDocblock('Extended class cannot be empty in docblock for ' . $storage->name, new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        try {
            $used_union_type = TypeParser::parseTokens(TypeTokenizer::getFullyQualifiedTokens($used_class_name, $this->aliases, $this->class_template_types, $this->type_aliases), null, $this->class_template_types, $this->type_aliases, \true);
        } catch (TypeParseTreeException $e) {
            $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $storage->name, new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        if (!$used_union_type->isSingle()) {
            $storage->docblock_issues[] = new InvalidDocblock('@template-use cannot be a union type', new CodeLocation($this->file_scanner, $node, null, \true));
            return;
        }
        /** @psalm-suppress UnusedMethodCall */
        $used_union_type->queueClassLikesForScanning($this->codebase, $this->file_storage, $storage->template_types ?: []);
        foreach ($used_union_type->getAtomicTypes() as $atomic_type) {
            if (!$atomic_type instanceof TGenericObject) {
                $storage->docblock_issues[] = new InvalidDocblock('@template-use has invalid class ' . $atomic_type->getId(), new CodeLocation($this->file_scanner, $node, null, \true));
                return;
            }
            $generic_class_lc = strtolower($atomic_type->value);
            if (!isset($storage->used_traits[$generic_class_lc])) {
                $storage->docblock_issues[] = new InvalidDocblock('@template-use must include the name of an used class,' . ' got ' . $atomic_type->getId(), new CodeLocation($this->file_scanner, $node, null, \true));
                return;
            }
            $used_type_parameters = [];
            $storage->template_type_uses_count[$generic_class_lc] = count($atomic_type->type_params);
            foreach ($atomic_type->type_params as $type_param) {
                $used_type_parameters[] = $type_param;
            }
            $storage->template_extended_offsets[$atomic_type->value] = $used_type_parameters;
        }
    }
    private static function registerEmptyConstructor(ClassLikeStorage $class_storage) : void
    {
        $method_name_lc = '__construct';
        if (isset($class_storage->methods[$method_name_lc])) {
            return;
        }
        $storage = $class_storage->methods['__construct'] = new MethodStorage();
        $storage->cased_name = '__construct';
        $storage->defining_fqcln = $class_storage->name;
        $storage->mutation_free = $storage->external_mutation_free = \true;
        $storage->mutation_free_inferred = \true;
        $class_storage->declaring_method_ids['__construct'] = new MethodIdentifier($class_storage->name, '__construct');
        $class_storage->inheritable_method_ids['__construct'] = $class_storage->declaring_method_ids['__construct'];
        $class_storage->appearing_method_ids['__construct'] = $class_storage->declaring_method_ids['__construct'];
        $class_storage->overridden_method_ids['__construct'] = [];
        $storage->visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
    }
    private function visitClassConstDeclaration(PhpParser\Node\Stmt\ClassConst $stmt, ClassLikeStorage $storage, string $fq_classlike_name) : void
    {
        if ($storage->is_trait && $this->codebase->analysis_php_version_id < 80200) {
            IssueBuffer::maybeAdd(new ConstantDeclarationInTrait('Traits cannot declare constants until PHP 8.2.0', new CodeLocation($this->file_scanner, $stmt)));
            return;
        }
        $existing_constants = $storage->constants;
        $comment = $stmt->getDocComment();
        $var_comment = null;
        $deprecated = \false;
        $description = null;
        $config = $this->config;
        if ($comment && $comment->getText() && ($config->use_docblock_types || $config->use_docblock_property_types)) {
            $comments = DocComment::parsePreservingLength($comment);
            if (isset($comments->tags['deprecated'])) {
                $deprecated = \true;
            }
            $description = $comments->description;
            try {
                $var_comments = CommentAnalyzer::getTypeFromComment($comment, $this->file_scanner, $this->aliases, [], $this->type_aliases);
                $var_comment = array_pop($var_comments);
            } catch (IncorrectDocblockException $e) {
                $storage->docblock_issues[] = new MissingDocblockType($e->getMessage(), new CodeLocation($this->file_scanner, $stmt, null, \true));
            } catch (DocblockParseException $e) {
                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage(), new CodeLocation($this->file_scanner, $stmt, null, \true));
            }
        }
        foreach ($stmt->consts as $const) {
            if (isset($storage->constants[$const->name->name]) || isset($storage->enum_cases[$const->name->name])) {
                IssueBuffer::maybeAdd(new DuplicateConstant('Constant names should be unique', new CodeLocation($this->file_scanner, $const), $fq_classlike_name));
                continue;
            }
            $inferred_type = SimpleTypeInferer::infer($this->codebase, new NodeDataProvider(), $const->value, $this->aliases, null, $existing_constants, $fq_classlike_name);
            $type_location = null;
            $suppressed_issues = [];
            if ($var_comment !== null && $var_comment->type !== null) {
                $const_type = $var_comment->type;
                $suppressed_issues = $var_comment->suppressed_issues;
                if ($var_comment->type_start !== null && $var_comment->type_end !== null && $var_comment->line_number !== null) {
                    $type_location = new DocblockTypeLocation($this->file_scanner, $var_comment->type_start, $var_comment->type_end, $var_comment->line_number);
                }
            } else {
                $const_type = $inferred_type;
            }
            $attributes = [];
            foreach ($stmt->attrGroups as $attr_group) {
                foreach ($attr_group->attrs as $attr) {
                    $attributes[] = \Psalm\Internal\PhpVisitor\Reflector\AttributeResolver::resolve($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $attr, $this->storage->name ?? null);
                }
            }
            $unresolved_node = null;
            if ($inferred_type && !($const->value instanceof Concat && $inferred_type->isSingle() && get_class($inferred_type->getSingleAtomic()) === TString::class)) {
                $exists = \true;
            } else {
                $exists = \false;
                $unresolved_const_expr = \Psalm\Internal\PhpVisitor\Reflector\ExpressionResolver::getUnresolvedClassConstExpr($const->value, $this->aliases, $fq_classlike_name, $storage->parent_class);
                if ($unresolved_const_expr) {
                    $unresolved_node = $unresolved_const_expr;
                } else {
                    $const_type = Type::getMixed();
                }
            }
            $storage->constants[$const->name->name] = $constant_storage = new ClassConstantStorage($const_type, $inferred_type, $stmt->isProtected() ? ClassLikeAnalyzer::VISIBILITY_PROTECTED : ($stmt->isPrivate() ? ClassLikeAnalyzer::VISIBILITY_PRIVATE : ClassLikeAnalyzer::VISIBILITY_PUBLIC), new CodeLocation($this->file_scanner, $const->name), $type_location, new CodeLocation($this->file_scanner, $const), $deprecated, $stmt->isFinal(), $unresolved_node, $attributes, $suppressed_issues, $description);
            if ($exists) {
                $existing_constants[$const->name->name] = $constant_storage;
            }
        }
    }
    private function visitEnumDeclaration(PhpParser\Node\Stmt\EnumCase $stmt, ClassLikeStorage $storage, string $fq_classlike_name) : void
    {
        if (isset($storage->constants[$stmt->name->name])) {
            IssueBuffer::maybeAdd(new DuplicateConstant('Constant names should be unique', new CodeLocation($this->file_scanner, $stmt), $fq_classlike_name));
            return;
        }
        $enum_value = null;
        $case_location = new CodeLocation($this->file_scanner, $stmt);
        if ($stmt->expr !== null) {
            $case_type = SimpleTypeInferer::infer($this->codebase, new NodeDataProvider(), $stmt->expr, $this->aliases, $this->file_scanner, $storage->constants, $fq_classlike_name);
            if ($case_type) {
                if ($case_type->isSingleIntLiteral()) {
                    $enum_value = $case_type->getSingleIntLiteral()->value;
                } elseif ($case_type->isSingleStringLiteral()) {
                    $enum_value = $case_type->getSingleStringLiteral()->value;
                } else {
                    IssueBuffer::maybeAdd(new InvalidEnumCaseValue('Case of a backed enum should have either string or int value', $case_location, $fq_classlike_name));
                }
            } else {
                throw new RuntimeException('Failed to infer case value for ' . $stmt->name->name);
            }
        }
        if (!isset($storage->enum_cases[$stmt->name->name])) {
            $case = new EnumCaseStorage($enum_value, $case_location);
            $attrs = $this->getAttributeStorageFromStatement($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $stmt, $this->storage->name ?? null);
            foreach ($attrs as $attribute) {
                if ($attribute->fq_class_name === 'Psalm\\Deprecated' || $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Deprecated') {
                    $case->deprecated = \true;
                    break;
                }
            }
            $comment = $stmt->getDocComment();
            if ($comment) {
                $comments = DocComment::parsePreservingLength($comment);
                if (isset($comments->tags['deprecated'])) {
                    $case->deprecated = \true;
                }
            }
            $storage->enum_cases[$stmt->name->name] = $case;
        } else {
            IssueBuffer::maybeAdd(new DuplicateEnumCase('Enum case names should be unique', $case_location, $fq_classlike_name));
        }
    }
    /**
     * @param PhpParser\Node\Stmt\Property|PhpParser\Node\Stmt\EnumCase $stmt
     * @return list<AttributeStorage>
     */
    private function getAttributeStorageFromStatement(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, PhpParser\Node\Stmt $stmt, ?string $fq_classlike_name) : array
    {
        $storages = [];
        foreach ($stmt->attrGroups as $attr_group) {
            foreach ($attr_group->attrs as $attr) {
                $storages[] = \Psalm\Internal\PhpVisitor\Reflector\AttributeResolver::resolve($codebase, $file_scanner, $file_storage, $aliases, $attr, $fq_classlike_name);
            }
        }
        return $storages;
    }
    /**
     * @param non-empty-string $fq_classlike_name
     */
    private function visitPropertyDeclaration(PhpParser\Node\Stmt\Property $stmt, Config $config, ClassLikeStorage $storage, string $fq_classlike_name) : void
    {
        $comment = $stmt->getDocComment();
        $var_comment = null;
        $property_is_initialized = \false;
        $existing_constants = $storage->constants;
        if ($comment && $comment->getText() && ($config->use_docblock_types || $config->use_docblock_property_types)) {
            if (preg_match('/[ \\t\\*]+@psalm-suppress[ \\t]+PropertyNotSetInConstructor/', (string) $comment)) {
                $property_is_initialized = \true;
            }
            if (preg_match('/[ \\t\\*]+@property[ \\t]+/', (string) $comment)) {
                $storage->docblock_issues[] = new InvalidDocblock('@property is valid only in docblocks for class', new CodeLocation($this->file_scanner, $stmt, null, \true));
            }
            try {
                $var_comments = CommentAnalyzer::getTypeFromComment($comment, $this->file_scanner, $this->aliases, !$stmt->isStatic() ? $this->class_template_types : [], $this->type_aliases);
                $var_comment = array_pop($var_comments);
            } catch (IncorrectDocblockException $e) {
                $storage->docblock_issues[] = new MissingDocblockType($e->getMessage(), new CodeLocation($this->file_scanner, $stmt, null, \true));
            } catch (DocblockParseException $e) {
                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage(), new CodeLocation($this->file_scanner, $stmt, null, \true));
            }
        }
        $signature_type = null;
        $signature_type_location = null;
        if ($stmt->type) {
            $parser_property_type = $stmt->type;
            /** @var Identifier|IntersectionType|Name|NullableType|UnionType $parser_property_type */
            $signature_type_location = new CodeLocation($this->file_scanner, $parser_property_type, null, \false, CodeLocation::FUNCTION_RETURN_TYPE);
            $signature_type = \Psalm\Internal\PhpVisitor\Reflector\TypeHintResolver::resolve($parser_property_type, $signature_type_location, $this->codebase, $this->file_storage, $this->storage, $this->aliases, $this->codebase->analysis_php_version_id);
        }
        $doc_var_group_type = $var_comment->type ?? null;
        if ($doc_var_group_type) {
            /** @psalm-suppress UnusedMethodCall */
            $doc_var_group_type->queueClassLikesForScanning($this->codebase, $this->file_storage);
        }
        foreach ($stmt->props as $property) {
            $doc_var_location = null;
            $property_storage = $storage->properties[$property->name->name] = new PropertyStorage();
            $property_storage->is_static = $stmt->isStatic();
            $property_storage->type = $signature_type;
            $property_storage->signature_type = $signature_type;
            $property_storage->signature_type_location = $signature_type_location;
            $property_storage->type_location = $signature_type_location;
            $property_storage->location = new CodeLocation($this->file_scanner, $property->name);
            $property_storage->stmt_location = new CodeLocation($this->file_scanner, $stmt);
            $property_storage->has_default = (bool) $property->default;
            $property_storage->deprecated = $var_comment ? $var_comment->deprecated : \false;
            $property_storage->suppressed_issues = $var_comment ? $var_comment->suppressed_issues : [];
            $property_storage->internal = $var_comment ? $var_comment->psalm_internal : [];
            if (count($property_storage->internal) === 0 && $var_comment && $var_comment->internal) {
                $property_storage->internal = [NamespaceAnalyzer::getNameSpaceRoot($fq_classlike_name)];
            }
            $property_storage->readonly = $stmt->isReadonly() || $var_comment && $var_comment->readonly;
            $property_storage->allow_private_mutation = $var_comment ? $var_comment->allow_private_mutation : \false;
            $property_storage->description = $var_comment ? $var_comment->description : null;
            if (!$signature_type && !$doc_var_group_type) {
                if ($property->default) {
                    $property_storage->suggested_type = SimpleTypeInferer::infer($this->codebase, new NodeDataProvider(), $property->default, $this->aliases, null, $existing_constants, $fq_classlike_name);
                }
                $property_storage->type = null;
            } else {
                if ($var_comment && $var_comment->type_start && $var_comment->type_end && $var_comment->line_number) {
                    $doc_var_location = new DocblockTypeLocation($this->file_scanner, $var_comment->type_start, $var_comment->type_end, $var_comment->line_number);
                }
                if ($doc_var_group_type) {
                    $property_storage->type = $doc_var_group_type;
                }
            }
            if ($property_storage->type && $property_storage->type !== $property_storage->signature_type) {
                if (!$property_storage->signature_type) {
                    $property_storage->type_location = $doc_var_location;
                }
                if ($property_storage->signature_type) {
                    $all_typehint_types_match = \true;
                    $signature_atomic_types = $property_storage->signature_type->getAtomicTypes();
                    foreach ($property_storage->type->getAtomicTypes() as $key => $type) {
                        if (isset($signature_atomic_types[$key])) {
                            /** @psalm-suppress InaccessibleProperty We just created this type */
                            $type->from_docblock = \false;
                        } else {
                            $all_typehint_types_match = \false;
                        }
                    }
                    if ($all_typehint_types_match) {
                        /** @psalm-suppress InaccessibleProperty We just created this type */
                        $property_storage->type->from_docblock = \false;
                    }
                    if ($property_storage->signature_type->isNullable() && !$property_storage->type->isNullable()) {
                        $property_storage->type = $property_storage->type->getBuilder()->addType(new TNull())->freeze();
                    }
                }
                /** @psalm-suppress UnusedMethodCall */
                $property_storage->type->queueClassLikesForScanning($this->codebase, $this->file_storage);
            }
            if ($stmt->isPublic()) {
                $property_storage->visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
            } elseif ($stmt->isProtected()) {
                $property_storage->visibility = ClassLikeAnalyzer::VISIBILITY_PROTECTED;
            } elseif ($stmt->isPrivate()) {
                $property_storage->visibility = ClassLikeAnalyzer::VISIBILITY_PRIVATE;
            }
            $property_id = $fq_classlike_name . '::$' . $property->name->name;
            $storage->declaring_property_ids[$property->name->name] = $fq_classlike_name;
            $storage->appearing_property_ids[$property->name->name] = $property_id;
            if ($property_is_initialized) {
                $storage->initialized_properties[$property->name->name] = \true;
            }
            if (!$stmt->isPrivate()) {
                $storage->inheritable_property_ids[$property->name->name] = $property_id;
            }
            $attrs = $this->getAttributeStorageFromStatement($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $stmt, $this->storage->name ?? null);
            foreach ($attrs as $attribute) {
                if ($attribute->fq_class_name === 'Psalm\\Deprecated' || $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Deprecated') {
                    $property_storage->deprecated = \true;
                }
                if ($attribute->fq_class_name === 'Psalm\\Internal' && !$property_storage->internal) {
                    $property_storage->internal = [NamespaceAnalyzer::getNameSpaceRoot($fq_classlike_name)];
                }
                if ($attribute->fq_class_name === 'Psalm\\Readonly') {
                    $property_storage->readonly = \true;
                }
                $property_storage->attributes[] = $attribute;
            }
        }
    }
    /**
     * @return array<string, LinkableTypeAlias>
     */
    private function getImportedTypeAliases(ClassLikeDocblockComment $comment, string $fq_classlike_name) : array
    {
        /** @var array<string, LinkableTypeAlias> $results */
        $results = [];
        foreach ($comment->imported_types as $import_type_entry) {
            $imported_type_data = $import_type_entry['parts'];
            $location = new DocblockTypeLocation($this->file_scanner, $import_type_entry['start_offset'], $import_type_entry['end_offset'], $import_type_entry['line_number']);
            // There are two valid forms:
            // @psalm-import Thing from Something
            // @psalm-import Thing from Something as Alias
            // but there could be leftovers after that
            if (count($imported_type_data) < 3) {
                $this->file_storage->docblock_issues[] = new InvalidTypeImport('Invalid import in docblock for ' . $fq_classlike_name . ', expecting "<TypeName> from <ClassName>",' . ' got "' . implode(' ', $imported_type_data) . '" instead.', $location);
                continue;
            }
            if ($imported_type_data[1] === 'from' && !empty($imported_type_data[0]) && !empty($imported_type_data[2])) {
                $type_alias_name = $as_alias_name = $imported_type_data[0];
                $declaring_classlike_name = $imported_type_data[2];
            } else {
                $this->file_storage->docblock_issues[] = new InvalidTypeImport('Invalid import in docblock for ' . $fq_classlike_name . ', expecting "<TypeName> from <ClassName>", got "' . implode(' ', [$imported_type_data[0], $imported_type_data[1], $imported_type_data[2]]) . '" instead.', $location);
                continue;
            }
            if (count($imported_type_data) >= 4 && $imported_type_data[3] === 'as') {
                // long form
                if (empty($imported_type_data[4])) {
                    $this->file_storage->docblock_issues[] = new InvalidTypeImport('Invalid import in docblock for ' . $fq_classlike_name . ', expecting "as <TypeName>", got "' . $imported_type_data[3] . ' ' . ($imported_type_data[4] ?? '') . '" instead.', $location);
                    continue;
                }
                $as_alias_name = $imported_type_data[4];
            }
            $declaring_fq_classlike_name = Type::getFQCLNFromString($declaring_classlike_name, $this->aliases);
            $this->codebase->scanner->queueClassLikeForScanning($declaring_fq_classlike_name);
            $this->file_storage->referenced_classlikes[strtolower($declaring_fq_classlike_name)] = $declaring_fq_classlike_name;
            $results[$as_alias_name] = new LinkableTypeAlias($declaring_fq_classlike_name, $type_alias_name, $import_type_entry['line_number'], $import_type_entry['start_offset'], $import_type_entry['end_offset']);
        }
        return $results;
    }
    /**
     * @param  array<string, TypeAlias> $type_aliases
     * @return array<string, InlineTypeAlias>
     * @throws DocblockParseException if there was a problem parsing the docblock
     */
    public static function getTypeAliasesFromComment(PhpParser\Comment\Doc $comment, Aliases $aliases, ?array $type_aliases, ?string $self_fqcln) : array
    {
        $parsed_docblock = DocComment::parsePreservingLength($comment);
        if (!isset($parsed_docblock->tags['psalm-type']) && !isset($parsed_docblock->tags['phpstan-type'])) {
            return [];
        }
        $type_alias_comment_lines = array_merge($parsed_docblock->tags['phpstan-type'] ?? [], $parsed_docblock->tags['psalm-type'] ?? []);
        return self::getTypeAliasesFromCommentLines($type_alias_comment_lines, $aliases, $type_aliases, $self_fqcln);
    }
    /**
     * @param  array<string>    $type_alias_comment_lines
     * @param  array<string, TypeAlias> $type_aliases
     * @return array<string, InlineTypeAlias>
     * @throws DocblockParseException if there was a problem parsing the docblock
     */
    private static function getTypeAliasesFromCommentLines(array $type_alias_comment_lines, Aliases $aliases, ?array $type_aliases, ?string $self_fqcln) : array
    {
        $type_alias_tokens = [];
        foreach ($type_alias_comment_lines as $var_line) {
            $var_line = trim($var_line);
            if (!$var_line) {
                continue;
            }
            $var_line = preg_replace('/[ \\t]+/', ' ', preg_replace('@^[ \\t]*\\*@m', '', $var_line));
            $var_line = preg_replace('/,\\n\\s+\\}/', '}', $var_line);
            $var_line = str_replace("\n", '', $var_line);
            $var_line_parts = preg_split('/( |=)/', $var_line, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
            if (!$var_line_parts) {
                continue;
            }
            $type_alias = array_shift($var_line_parts);
            if (!isset($var_line_parts[0])) {
                continue;
            }
            if ($var_line_parts[0] === ' ') {
                array_shift($var_line_parts);
            }
            if (!isset($var_line_parts[0])) {
                continue;
            }
            if ($var_line_parts[0] === '=') {
                array_shift($var_line_parts);
            }
            if (!isset($var_line_parts[0])) {
                continue;
            }
            if ($var_line_parts[0] === ' ') {
                array_shift($var_line_parts);
            }
            $type_string = str_replace("\n", '', implode('', $var_line_parts));
            $type_string = preg_replace('/>[^>^\\}]*$/', '>', $type_string, 1);
            $type_string = preg_replace('/\\}[^>^\\}]*$/', '}', $type_string, 1);
            try {
                $type_tokens = TypeTokenizer::getFullyQualifiedTokens($type_string, $aliases, null, $type_alias_tokens + $type_aliases, $self_fqcln);
            } catch (TypeParseTreeException $e) {
                throw new DocblockParseException($type_string . ' is not a valid type');
            }
            $type_alias_tokens[$type_alias] = new InlineTypeAlias($type_tokens);
        }
        return $type_alias_tokens;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use Exception;
use _HumbugBox1cb33d1f20f1\PhpParser\Comment\Doc;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Class_;
use Psalm\Aliases;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Provider\StatementsProvider;
use Psalm\Internal\Scanner\ClassLikeDocblockComment;
use Psalm\Internal\Scanner\DocblockParser;
use Psalm\Internal\Type\ParseTree\MethodParamTree;
use Psalm\Internal\Type\ParseTree\MethodTree;
use Psalm\Internal\Type\ParseTree\MethodWithReturnTypeTree;
use Psalm\Internal\Type\ParseTreeCreator;
use Psalm\Internal\Type\TypeParser;
use Psalm\Internal\Type\TypeTokenizer;
use function array_key_first;
use function array_shift;
use function count;
use function explode;
use function implode;
use function in_array;
use function preg_last_error_msg;
use function preg_match;
use function preg_replace;
use function preg_split;
use function reset;
use function str_replace;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
use function substr_count;
use function trim;
use const PREG_OFFSET_CAPTURE;
/**
 * @internal
 */
class ClassLikeDocblockParser
{
    /**
     * @throws DocblockParseException if there was a problem parsing the docblock
     */
    public static function parse(Node $node, Doc $comment, Aliases $aliases) : ClassLikeDocblockComment
    {
        $parsed_docblock = DocComment::parsePreservingLength($comment);
        $codebase = ProjectAnalyzer::getInstance()->getCodebase();
        $info = new ClassLikeDocblockComment();
        $templates = [];
        if (isset($parsed_docblock->combined_tags['template'])) {
            foreach ($parsed_docblock->combined_tags['template'] as $offset => $template_line) {
                $template_type = preg_split('/[\\s]+/', preg_replace('@^[ \\t]*\\*@m', '', $template_line));
                if ($template_type === \false) {
                    throw new IncorrectDocblockException('Invalid @ŧemplate tag: ' . preg_last_error_msg());
                }
                $template_name = array_shift($template_type);
                if (!$template_name) {
                    throw new IncorrectDocblockException('Empty @template tag');
                }
                $source_prefix = 'none';
                if (isset($parsed_docblock->tags['psalm-template'][$offset])) {
                    $source_prefix = 'psalm';
                } elseif (isset($parsed_docblock->tags['phpstan-template'][$offset])) {
                    $source_prefix = 'phpstan';
                }
                if (count($template_type) > 1 && in_array(strtolower($template_type[0]), ['as', 'super', 'of'], \true)) {
                    $template_modifier = strtolower(array_shift($template_type));
                    $templates[$template_name][$source_prefix] = [$template_name, $template_modifier, implode(' ', $template_type), \false, $offset - $comment->getStartFilePos()];
                } else {
                    $templates[$template_name][$source_prefix] = [$template_name, null, null, \false, $offset - $comment->getStartFilePos()];
                }
            }
        }
        if (isset($parsed_docblock->combined_tags['template-covariant'])) {
            foreach ($parsed_docblock->combined_tags['template-covariant'] as $offset => $template_line) {
                $template_type = preg_split('/[\\s]+/', preg_replace('@^[ \\t]*\\*@m', '', $template_line));
                if ($template_type === \false) {
                    throw new IncorrectDocblockException('Invalid @template-covariant tag: ' . preg_last_error_msg());
                }
                $template_name = array_shift($template_type);
                if (!$template_name) {
                    throw new IncorrectDocblockException('Empty @template-covariant tag');
                }
                $source_prefix = 'none';
                if (isset($parsed_docblock->tags['psalm-template-covariant'][$offset])) {
                    $source_prefix = 'psalm';
                } elseif (isset($parsed_docblock->tags['phpstan-template-covariant'][$offset])) {
                    $source_prefix = 'phpstan';
                }
                if (count($template_type) > 1 && in_array(strtolower($template_type[0]), ['as', 'super', 'of'], \true)) {
                    $template_modifier = strtolower(array_shift($template_type));
                    $templates[$template_name][$source_prefix] = [$template_name, $template_modifier, implode(' ', $template_type), \true, $offset - $comment->getStartFilePos()];
                } else {
                    $templates[$template_name][$source_prefix] = [$template_name, null, null, \true, $offset - $comment->getStartFilePos()];
                }
            }
        }
        foreach ($templates as $template_entries) {
            foreach (['psalm', 'phpstan', 'none'] as $source_prefix) {
                if (isset($template_entries[$source_prefix])) {
                    $info->templates[] = $template_entries[$source_prefix];
                    break;
                }
            }
        }
        if (isset($parsed_docblock->combined_tags['extends'])) {
            foreach ($parsed_docblock->combined_tags['extends'] as $template_line) {
                $doc_line_parts = CommentAnalyzer::splitDocLine($template_line);
                $doc_line_parts[0] = CommentAnalyzer::sanitizeDocblockType($doc_line_parts[0]);
                $info->template_extends[] = $doc_line_parts[0];
            }
        }
        if (isset($parsed_docblock->tags['psalm-require-extends']) && count($extension_requirements = $parsed_docblock->tags['psalm-require-extends']) > 0) {
            $info->extension_requirement = trim(preg_replace('@^[ \\t]*\\*@m', '', $extension_requirements[array_key_first($extension_requirements)]));
        }
        if (isset($parsed_docblock->tags['psalm-require-implements'])) {
            foreach ($parsed_docblock->tags['psalm-require-implements'] as $implementation_requirement) {
                $info->implementation_requirements[] = trim(preg_replace('@^[ \\t]*\\*@m', '', $implementation_requirement));
            }
        }
        if (isset($parsed_docblock->combined_tags['implements'])) {
            foreach ($parsed_docblock->combined_tags['implements'] as $template_line) {
                $doc_line_parts = CommentAnalyzer::splitDocLine($template_line);
                $doc_line_parts[0] = CommentAnalyzer::sanitizeDocblockType($doc_line_parts[0]);
                $info->template_implements[] = $doc_line_parts[0];
            }
        }
        if (isset($parsed_docblock->tags['psalm-yield'])) {
            $yield = reset($parsed_docblock->tags['psalm-yield']);
            $info->yield = trim(preg_replace('@^[ \\t]*\\*@m', '', $yield));
        }
        if (isset($parsed_docblock->tags['deprecated'])) {
            $info->deprecated = \true;
        }
        if (isset($parsed_docblock->tags['internal'])) {
            $info->internal = \true;
        }
        if (isset($parsed_docblock->tags['final'])) {
            $info->final = \true;
        }
        if (isset($parsed_docblock->tags['psalm-consistent-constructor'])) {
            $info->consistent_constructor = \true;
        }
        if (isset($parsed_docblock->tags['psalm-consistent-templates'])) {
            $info->consistent_templates = \true;
        }
        if (count($info->psalm_internal = DocblockParser::handlePsalmInternal($parsed_docblock)) !== 0) {
            $info->internal = \true;
        }
        if (isset($parsed_docblock->tags['mixin'])) {
            foreach ($parsed_docblock->tags['mixin'] as $rawMixin) {
                $mixin = trim($rawMixin);
                $doc_line_parts = CommentAnalyzer::splitDocLine($mixin);
                $mixin = $doc_line_parts[0];
                if ($mixin) {
                    $info->mixins[] = $mixin;
                } else {
                    throw new DocblockParseException('@mixin annotation used without specifying class');
                }
            }
        }
        if (isset($parsed_docblock->tags['psalm-seal-properties'])) {
            $info->sealed_properties = \true;
        }
        if (isset($parsed_docblock->tags['psalm-seal-methods'])) {
            $info->sealed_methods = \true;
        }
        if (isset($parsed_docblock->tags['psalm-immutable']) || isset($parsed_docblock->tags['psalm-mutation-free'])) {
            $info->mutation_free = \true;
            $info->external_mutation_free = \true;
            $info->taint_specialize = \true;
        }
        if (isset($parsed_docblock->tags['psalm-external-mutation-free'])) {
            $info->external_mutation_free = \true;
        }
        if (isset($parsed_docblock->tags['psalm-taint-specialize'])) {
            $info->taint_specialize = \true;
        }
        if (isset($parsed_docblock->tags['psalm-override-property-visibility'])) {
            $info->override_property_visibility = \true;
        }
        if (isset($parsed_docblock->tags['psalm-override-method-visibility'])) {
            $info->override_method_visibility = \true;
        }
        if (isset($parsed_docblock->tags['psalm-suppress'])) {
            foreach ($parsed_docblock->tags['psalm-suppress'] as $offset => $suppress_entry) {
                foreach (DocComment::parseSuppressList($suppress_entry) as $issue_offset => $suppressed_issue) {
                    $info->suppressed_issues[$issue_offset + $offset] = $suppressed_issue;
                }
            }
        }
        $imported_types = ($parsed_docblock->tags['phpstan-import-type'] ?? []) + ($parsed_docblock->tags['psalm-import-type'] ?? []);
        foreach ($imported_types as $offset => $imported_type_entry) {
            $info->imported_types[] = ['line_number' => $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset - $comment->getStartFilePos()), 'start_offset' => $offset, 'end_offset' => $offset + strlen($imported_type_entry), 'parts' => CommentAnalyzer::splitDocLine($imported_type_entry)];
        }
        if (isset($parsed_docblock->combined_tags['method'])) {
            foreach ($parsed_docblock->combined_tags['method'] as $offset => $method_entry) {
                $method_entry = preg_replace('/[ \\t]+/', ' ', trim($method_entry));
                $docblock_lines = [];
                $is_static = \false;
                $has_return = \false;
                if (!preg_match('/^([a-z_A-Z][a-z_0-9A-Z]+) *\\(/', $method_entry, $matches)) {
                    $doc_line_parts = CommentAnalyzer::splitDocLine($method_entry);
                    if ($doc_line_parts[0] === 'static' && !strpos($doc_line_parts[1], '(')) {
                        $is_static = \true;
                        array_shift($doc_line_parts);
                    }
                    if (count($doc_line_parts) > 1) {
                        $docblock_lines[] = '@return ' . array_shift($doc_line_parts);
                        $has_return = \true;
                        $method_entry = implode(' ', $doc_line_parts);
                    }
                }
                $method_entry = trim(preg_replace('/\\/\\/.*/', '', $method_entry));
                $method_entry = preg_replace('/array\\(([0-9a-zA-Z_\'\\" ]+,)*([0-9a-zA-Z_\'\\" ]+)\\)/', '[]', $method_entry);
                $end_of_method_regex = '/(?<!array\\()\\) ?(\\: ?(\\??[\\\\a-zA-Z0-9_]+))?/';
                if (preg_match($end_of_method_regex, $method_entry, $matches, PREG_OFFSET_CAPTURE)) {
                    $method_entry = substr($method_entry, 0, $matches[0][1] + strlen($matches[0][0]));
                }
                $method_entry = str_replace([', ', '( '], [',', '('], $method_entry);
                $method_entry = preg_replace('/ (?!(\\$|\\.\\.\\.|&))/', '', trim($method_entry));
                // replace array bracket contents
                $method_entry = preg_replace('/\\[([0-9a-zA-Z_\'\\" ]+,)*([0-9a-zA-Z_\'\\" ]+)\\]/', '[]', $method_entry);
                if (!$method_entry) {
                    throw new DocblockParseException('No @method entry specified');
                }
                try {
                    $parse_tree_creator = new ParseTreeCreator(TypeTokenizer::getFullyQualifiedTokens($method_entry, $aliases, null));
                    $method_tree = $parse_tree_creator->create();
                } catch (TypeParseTreeException $e) {
                    throw new DocblockParseException($method_entry . ' is not a valid method');
                }
                if (!$method_tree instanceof MethodWithReturnTypeTree && !$method_tree instanceof MethodTree) {
                    throw new DocblockParseException($method_entry . ' is not a valid method');
                }
                if ($method_tree instanceof MethodWithReturnTypeTree) {
                    if (!$has_return) {
                        $docblock_lines[] = '@return ' . TypeParser::getTypeFromTree($method_tree->children[1], $codebase)->toNamespacedString($aliases->namespace, $aliases->uses, null, \false);
                    }
                    $method_tree = $method_tree->children[0];
                }
                if (!$method_tree instanceof MethodTree) {
                    throw new DocblockParseException($method_entry . ' is not a valid method');
                }
                $args = [];
                foreach ($method_tree->children as $method_tree_child) {
                    if (!$method_tree_child instanceof MethodParamTree) {
                        throw new DocblockParseException($method_entry . ' is not a valid method');
                    }
                    $args[] = ($method_tree_child->byref ? '&' : '') . ($method_tree_child->variadic ? '...' : '') . $method_tree_child->name . ($method_tree_child->default != '' ? ' = ' . $method_tree_child->default : '');
                    if ($method_tree_child->children) {
                        try {
                            $param_type = TypeParser::getTypeFromTree($method_tree_child->children[0], $codebase);
                        } catch (Exception $e) {
                            throw new DocblockParseException('Badly-formatted @method string ' . $method_entry . ' - ' . $e);
                        }
                        $param_type_string = $param_type->toNamespacedString('\\', [], null, \false);
                        $docblock_lines[] = '@param ' . $param_type_string . ' ' . ($method_tree_child->variadic ? '...' : '') . $method_tree_child->name;
                    }
                }
                $function_string = 'function ' . $method_tree->value . '(' . implode(', ', $args) . ')';
                if ($is_static) {
                    $function_string = 'static ' . $function_string;
                }
                $function_docblock = $docblock_lines ? "/**\n * " . implode("\n * ", $docblock_lines) . "\n*/\n" : "";
                $php_string = '<?php class A { ' . $function_docblock . ' public ' . $function_string . '{} }';
                try {
                    $has_errors = \false;
                    $statements = StatementsProvider::parseStatements($php_string, $codebase->analysis_php_version_id, $has_errors);
                } catch (Exception $e) {
                    throw new DocblockParseException('Badly-formatted @method string ' . $method_entry);
                }
                if (!$statements || !$statements[0] instanceof Class_ || !isset($statements[0]->stmts[0]) || !$statements[0]->stmts[0] instanceof ClassMethod) {
                    throw new DocblockParseException('Badly-formatted @method string ' . $method_entry);
                }
                /** @var Doc */
                $node_doc_comment = $node->getDocComment();
                $method_offset = self::getMethodOffset($comment, $method_entry);
                $statements[0]->stmts[0]->setAttribute('startLine', $node_doc_comment->getStartLine() + $method_offset);
                $statements[0]->stmts[0]->setAttribute('startFilePos', $node_doc_comment->getStartFilePos());
                $statements[0]->stmts[0]->setAttribute('endFilePos', $node->getAttribute('startFilePos'));
                if ($doc_comment = $statements[0]->stmts[0]->getDocComment()) {
                    $statements[0]->stmts[0]->setDocComment(new Doc($doc_comment->getText(), $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset - $comment->getStartFilePos()), $node_doc_comment->getStartFilePos()));
                }
                $info->methods[] = $statements[0]->stmts[0];
            }
        }
        if (isset($parsed_docblock->tags['psalm-stub-override'])) {
            $info->stub_override = \true;
        }
        if ($parsed_docblock->description) {
            $info->description = $parsed_docblock->description;
        }
        $info->public_api = isset($parsed_docblock->tags['psalm-api']) || isset($parsed_docblock->tags['api']);
        self::addMagicPropertyToInfo($comment, $info, $parsed_docblock->tags, 'property');
        self::addMagicPropertyToInfo($comment, $info, $parsed_docblock->tags, 'psalm-property');
        self::addMagicPropertyToInfo($comment, $info, $parsed_docblock->tags, 'property-read');
        self::addMagicPropertyToInfo($comment, $info, $parsed_docblock->tags, 'psalm-property-read');
        self::addMagicPropertyToInfo($comment, $info, $parsed_docblock->tags, 'property-write');
        self::addMagicPropertyToInfo($comment, $info, $parsed_docblock->tags, 'psalm-property-write');
        return $info;
    }
    /**
     * @param array<string, array<int, string>> $specials
     * @param 'property'|'psalm-property'|'property-read'|
     *     'psalm-property-read'|'property-write'|'psalm-property-write' $property_tag
     * @throws DocblockParseException
     */
    protected static function addMagicPropertyToInfo(Doc $comment, ClassLikeDocblockComment $info, array $specials, string $property_tag) : void
    {
        $magic_property_comments = $specials[$property_tag] ?? [];
        foreach ($magic_property_comments as $offset => $property) {
            $line_parts = CommentAnalyzer::splitDocLine($property);
            if (count($line_parts) === 1 && isset($line_parts[0][0]) && $line_parts[0][0] === '$') {
                continue;
            }
            if (count($line_parts) > 1) {
                if (preg_match('/^&?\\$[A-Za-z0-9_]+,?$/', $line_parts[1]) && $line_parts[0][0] !== '{') {
                    $line_parts[1] = str_replace('&', '', $line_parts[1]);
                    $line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);
                    $end = $offset + strlen($line_parts[0]);
                    $line_parts[0] = str_replace("\n", '', preg_replace('@^[ \\t]*\\*@m', '', $line_parts[0]));
                    if ($line_parts[0] === '' || $line_parts[0][0] === '$' && !preg_match('/^\\$this(\\||$)/', $line_parts[0])) {
                        throw new IncorrectDocblockException('Misplaced variable');
                    }
                    $name = trim($line_parts[1]);
                    if (!preg_match('/^\\$([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)$/', $name)) {
                        throw new DocblockParseException('Badly-formatted @property name');
                    }
                    $info->properties[] = ['name' => $name, 'type' => $line_parts[0], 'line_number' => $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset - $comment->getStartFilePos()), 'tag' => $property_tag, 'start' => $offset, 'end' => $end];
                }
            } else {
                throw new DocblockParseException('Badly-formatted @property');
            }
        }
    }
    private static function getMethodOffset(Doc $comment, string $method_entry) : int
    {
        $lines = explode("\n", $comment->getText());
        $method_offset = 0;
        foreach ($lines as $i => $line) {
            if (strpos($line, $method_entry) !== \false) {
                $method_offset = $i;
                break;
            }
        }
        return $method_offset;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\ConstExprEvaluationException;
use _HumbugBox1cb33d1f20f1\PhpParser\ConstExprEvaluator;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ConstFetch;
use Psalm\Aliases;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Scanner\UnresolvedConstant\ArrayOffsetFetch;
use Psalm\Internal\Scanner\UnresolvedConstant\ArraySpread;
use Psalm\Internal\Scanner\UnresolvedConstant\ArrayValue;
use Psalm\Internal\Scanner\UnresolvedConstant\ClassConstant;
use Psalm\Internal\Scanner\UnresolvedConstant\Constant;
use Psalm\Internal\Scanner\UnresolvedConstant\KeyValuePair;
use Psalm\Internal\Scanner\UnresolvedConstant\ScalarValue;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedAdditionOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBitwiseAnd;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBitwiseOr;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBitwiseXor;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedConcatOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedDivisionOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedMultiplicationOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedSubtractionOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedTernary;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use ReflectionClass;
use ReflectionFunction;
use function assert;
use function class_exists;
use function function_exists;
use function implode;
use function interface_exists;
use function strtolower;
/**
 * @internal
 */
class ExpressionResolver
{
    public static function getUnresolvedClassConstExpr(PhpParser\Node\Expr $stmt, Aliases $aliases, ?string $fq_classlike_name, ?string $parent_fq_class_name = null) : ?UnresolvedConstantComponent
    {
        if ($stmt instanceof PhpParser\Node\Expr\BinaryOp) {
            $left = self::getUnresolvedClassConstExpr($stmt->left, $aliases, $fq_classlike_name, $parent_fq_class_name);
            $right = self::getUnresolvedClassConstExpr($stmt->right, $aliases, $fq_classlike_name, $parent_fq_class_name);
            if (!$left || !$right) {
                return null;
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Plus) {
                return new UnresolvedAdditionOp($left, $right);
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Minus) {
                return new UnresolvedSubtractionOp($left, $right);
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Mul) {
                return new UnresolvedMultiplicationOp($left, $right);
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Div) {
                return new UnresolvedDivisionOp($left, $right);
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
                return new UnresolvedConcatOp($left, $right);
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseOr) {
                return new UnresolvedBitwiseOr($left, $right);
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseXor) {
                return new UnresolvedBitwiseXor($left, $right);
            }
            if ($stmt instanceof PhpParser\Node\Expr\BinaryOp\BitwiseAnd) {
                return new UnresolvedBitwiseAnd($left, $right);
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\Ternary) {
            $cond = self::getUnresolvedClassConstExpr($stmt->cond, $aliases, $fq_classlike_name, $parent_fq_class_name);
            $if = null;
            if ($stmt->if) {
                $if = self::getUnresolvedClassConstExpr($stmt->if, $aliases, $fq_classlike_name, $parent_fq_class_name);
                if ($if === null) {
                    $if = \false;
                }
            }
            $else = self::getUnresolvedClassConstExpr($stmt->else, $aliases, $fq_classlike_name, $parent_fq_class_name);
            if ($cond && $else && $if !== \false) {
                return new UnresolvedTernary($cond, $if, $else);
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
            $part0_lc = strtolower($stmt->name->parts[0]);
            if ($part0_lc === 'false') {
                return new ScalarValue(\false);
            }
            if ($part0_lc === 'true') {
                return new ScalarValue(\true);
            }
            if ($part0_lc === 'null') {
                return new ScalarValue(null);
            }
            if ($part0_lc === '__namespace__') {
                return new ScalarValue($aliases->namespace);
            }
            return new Constant(implode('\\', $stmt->name->parts), $stmt->name instanceof PhpParser\Node\Name\FullyQualified);
        }
        if ($stmt instanceof PhpParser\Node\Scalar\MagicConst\Namespace_) {
            return new ScalarValue($aliases->namespace);
        }
        if ($stmt instanceof PhpParser\Node\Expr\ArrayDimFetch && $stmt->dim) {
            $left = self::getUnresolvedClassConstExpr($stmt->var, $aliases, $fq_classlike_name, $parent_fq_class_name);
            $right = self::getUnresolvedClassConstExpr($stmt->dim, $aliases, $fq_classlike_name, $parent_fq_class_name);
            if ($left && $right) {
                return new ArrayOffsetFetch($left, $right);
            }
        }
        if ($stmt instanceof PhpParser\Node\Expr\ClassConstFetch) {
            if ($stmt->class instanceof PhpParser\Node\Name && $stmt->name instanceof PhpParser\Node\Identifier && $fq_classlike_name && $stmt->class->parts !== ['static'] && ($stmt->class->parts !== ['parent'] || $parent_fq_class_name !== null)) {
                if ($stmt->class->parts === ['self']) {
                    $const_fq_class_name = $fq_classlike_name;
                } else {
                    if ($stmt->class->parts === ['parent']) {
                        assert($parent_fq_class_name !== null);
                        $const_fq_class_name = $parent_fq_class_name;
                    } else {
                        $const_fq_class_name = ClassLikeAnalyzer::getFQCLNFromNameObject($stmt->class, $aliases);
                    }
                }
                return new ClassConstant($const_fq_class_name, $stmt->name->name);
            }
            return null;
        }
        if ($stmt instanceof PhpParser\Node\Scalar\String_ || $stmt instanceof PhpParser\Node\Scalar\LNumber || $stmt instanceof PhpParser\Node\Scalar\DNumber) {
            return new ScalarValue($stmt->value);
        }
        if ($stmt instanceof PhpParser\Node\Expr\UnaryPlus) {
            $right = self::getUnresolvedClassConstExpr($stmt->expr, $aliases, $fq_classlike_name, $parent_fq_class_name);
            if (!$right) {
                return null;
            }
            return new UnresolvedAdditionOp(new ScalarValue(0), $right);
        }
        if ($stmt instanceof PhpParser\Node\Expr\UnaryMinus) {
            $right = self::getUnresolvedClassConstExpr($stmt->expr, $aliases, $fq_classlike_name, $parent_fq_class_name);
            if (!$right) {
                return null;
            }
            return new UnresolvedSubtractionOp(new ScalarValue(0), $right);
        }
        if ($stmt instanceof PhpParser\Node\Expr\Array_) {
            $items = [];
            foreach ($stmt->items as $item) {
                if ($item === null) {
                    return null;
                }
                if ($item->key) {
                    $item_key_type = self::getUnresolvedClassConstExpr($item->key, $aliases, $fq_classlike_name, $parent_fq_class_name);
                    if (!$item_key_type) {
                        return null;
                    }
                } else {
                    $item_key_type = null;
                }
                $item_value_type = self::getUnresolvedClassConstExpr($item->value, $aliases, $fq_classlike_name, $parent_fq_class_name);
                if (!$item_value_type) {
                    return null;
                }
                if ($item->unpack) {
                    $items[] = new ArraySpread($item_value_type);
                } else {
                    $items[] = new KeyValuePair($item_key_type, $item_value_type);
                }
            }
            return new ArrayValue($items);
        }
        return null;
    }
    public static function enterConditional(Codebase $codebase, string $file_path, PhpParser\Node\Expr $expr) : ?bool
    {
        if ($expr instanceof PhpParser\Node\Expr\BooleanNot) {
            $enter_negated = self::enterConditional($codebase, $file_path, $expr->expr);
            return $enter_negated === null ? null : !$enter_negated;
        }
        if ($expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanAnd) {
            $enter_conditional_left = self::enterConditional($codebase, $file_path, $expr->left);
            $enter_conditional_right = self::enterConditional($codebase, $file_path, $expr->right);
            return $enter_conditional_left !== \false && $enter_conditional_right !== \false;
        }
        if ($expr instanceof PhpParser\Node\Expr\BinaryOp\BooleanOr) {
            $enter_conditional_left = self::enterConditional($codebase, $file_path, $expr->left);
            $enter_conditional_right = self::enterConditional($codebase, $file_path, $expr->right);
            return $enter_conditional_left !== \false || $enter_conditional_right !== \false;
        }
        if ($codebase->register_autoload_files) {
            if (($expr instanceof PhpParser\Node\Expr\BinaryOp\GreaterOrEqual || $expr instanceof PhpParser\Node\Expr\BinaryOp\Greater || $expr instanceof PhpParser\Node\Expr\BinaryOp\SmallerOrEqual || $expr instanceof PhpParser\Node\Expr\BinaryOp\Smaller) && ($expr->left instanceof PhpParser\Node\Expr\ConstFetch && $expr->left->name->parts === ['PHP_VERSION_ID'] && $expr->right instanceof PhpParser\Node\Scalar\LNumber || $expr->right instanceof PhpParser\Node\Expr\ConstFetch && $expr->right->name->parts === ['PHP_VERSION_ID'] && $expr->left instanceof PhpParser\Node\Scalar\LNumber)) {
                $php_version_id = $codebase->analysis_php_version_id;
                $evaluator = new ConstExprEvaluator(static function (Expr $expr) use($php_version_id) {
                    if ($expr instanceof ConstFetch && $expr->name->parts === ['PHP_VERSION_ID']) {
                        return $php_version_id;
                    }
                    throw new ConstExprEvaluationException('unexpected');
                });
                try {
                    return (bool) $evaluator->evaluateSilently($expr);
                } catch (ConstExprEvaluationException $e) {
                    return null;
                }
            }
        }
        if (!$expr instanceof PhpParser\Node\Expr\FuncCall) {
            return null;
        }
        return self::functionEvaluatesToTrue($codebase, $file_path, $expr);
    }
    private static function functionEvaluatesToTrue(Codebase $codebase, string $file_path, PhpParser\Node\Expr\FuncCall $function) : ?bool
    {
        if (!$function->name instanceof PhpParser\Node\Name) {
            return null;
        }
        if ($function->name->parts === ['function_exists'] && isset($function->getArgs()[0]) && $function->getArgs()[0]->value instanceof PhpParser\Node\Scalar\String_ && function_exists($function->getArgs()[0]->value->value)) {
            $reflection_function = new ReflectionFunction($function->getArgs()[0]->value->value);
            if ($reflection_function->isInternal()) {
                return \true;
            }
            return \false;
        }
        if ($function->name->parts === ['class_exists'] && isset($function->getArgs()[0])) {
            $string_value = null;
            if ($function->getArgs()[0]->value instanceof PhpParser\Node\Scalar\String_) {
                $string_value = $function->getArgs()[0]->value->value;
            } elseif ($function->getArgs()[0]->value instanceof PhpParser\Node\Expr\ClassConstFetch && $function->getArgs()[0]->value->class instanceof PhpParser\Node\Name && $function->getArgs()[0]->value->name instanceof PhpParser\Node\Identifier && strtolower($function->getArgs()[0]->value->name->name) === 'class') {
                $string_value = (string) $function->getArgs()[0]->value->class->getAttribute('resolvedName');
            }
            if ($string_value && class_exists($string_value)) {
                $reflection_class = new ReflectionClass($string_value);
                if ($reflection_class->getFileName() !== $file_path) {
                    $codebase->scanner->queueClassLikeForScanning($string_value);
                    return \true;
                }
            }
            return \false;
        }
        if ($function->name->parts === ['interface_exists'] && isset($function->getArgs()[0])) {
            $string_value = null;
            if ($function->getArgs()[0]->value instanceof PhpParser\Node\Scalar\String_) {
                $string_value = $function->getArgs()[0]->value->value;
            } elseif ($function->getArgs()[0]->value instanceof PhpParser\Node\Expr\ClassConstFetch && $function->getArgs()[0]->value->class instanceof PhpParser\Node\Name && $function->getArgs()[0]->value->name instanceof PhpParser\Node\Identifier && strtolower($function->getArgs()[0]->value->name->name) === 'class') {
                $string_value = (string) $function->getArgs()[0]->value->class->getAttribute('resolvedName');
            }
            if ($string_value && interface_exists($string_value)) {
                $reflection_class = new ReflectionClass($string_value);
                if ($reflection_class->getFileName() !== $file_path) {
                    $codebase->scanner->queueClassLikeForScanning($string_value);
                    return \true;
                }
            }
            return \false;
        }
        if ($function->name->parts === ['enum_exists'] && isset($function->getArgs()[0])) {
            $string_value = null;
            if ($function->getArgs()[0]->value instanceof PhpParser\Node\Scalar\String_) {
                $string_value = $function->getArgs()[0]->value->value;
            } elseif ($function->getArgs()[0]->value instanceof PhpParser\Node\Expr\ClassConstFetch && $function->getArgs()[0]->value->class instanceof PhpParser\Node\Name && $function->getArgs()[0]->value->name instanceof PhpParser\Node\Identifier && strtolower($function->getArgs()[0]->value->name->name) === 'class') {
                $string_value = (string) $function->getArgs()[0]->value->class->getAttribute('resolvedName');
            }
            // We're using class_exists here because enum_exists doesn't exist on old versions of PHP
            // Not sure what happens if we try to autoload or reflect on an enum on an old version of PHP though...
            if ($string_value && class_exists($string_value)) {
                $reflection_class = new ReflectionClass($string_value);
                if ($reflection_class->getFileName() !== $file_path) {
                    $codebase->scanner->queueClassLikeForScanning($string_value);
                    return \true;
                }
            }
            return \false;
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\IntersectionType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\NullableType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Class_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\UnionType;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Exception\ComplicatedExpressionException;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Internal\Algebra;
use Psalm\Internal\Algebra\FormulaGenerator;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\ScopeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\SimpleTypeInferer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Internal\Type\TypeAlias;
use Psalm\Issue\DuplicateFunction;
use Psalm\Issue\DuplicateMethod;
use Psalm\Issue\DuplicateParam;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\MissingDocblockType;
use Psalm\Issue\ParseError;
use Psalm\IssueBuffer;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\FunctionStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Storage\Possibilities;
use Psalm\Storage\PropertyStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Union;
use ReflectionFunction;
use UnexpectedValueException;
use function array_keys;
use function array_pop;
use function array_search;
use function count;
use function end;
use function explode;
use function implode;
use function in_array;
use function is_string;
use function spl_object_id;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class FunctionLikeNodeScanner
{
    private FileScanner $file_scanner;
    private Codebase $codebase;
    private string $file_path;
    private Config $config;
    private FileStorage $file_storage;
    private ?ClassLikeStorage $classlike_storage = null;
    /**
     * @var array<string, non-empty-array<string, Union>>
     */
    private array $existing_function_template_types;
    private Aliases $aliases;
    /**
     * @var array<string, TypeAlias>
     */
    private array $type_aliases;
    public ?FunctionLikeStorage $storage = null;
    /**
     * @param array<string, non-empty-array<string, Union>> $existing_function_template_types
     * @param array<string, TypeAlias> $type_aliases
     */
    public function __construct(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, array $type_aliases, ?ClassLikeStorage $classlike_storage, array $existing_function_template_types)
    {
        $this->codebase = $codebase;
        $this->file_storage = $file_storage;
        $this->file_scanner = $file_scanner;
        $this->file_path = $file_storage->file_path;
        $this->aliases = $aliases;
        $this->type_aliases = $type_aliases;
        $this->config = Config::getInstance();
        $this->classlike_storage = $classlike_storage;
        $this->existing_function_template_types = $existing_function_template_types;
    }
    /**
     * @param  bool $fake_method in the case of @method annotations we do something a little strange
     * @return FunctionStorage|MethodStorage|false
     */
    public function start(PhpParser\Node\FunctionLike $stmt, bool $fake_method = \false)
    {
        if ($stmt instanceof PhpParser\Node\Expr\Closure || $stmt instanceof PhpParser\Node\Expr\ArrowFunction) {
            $this->codebase->scanner->queueClassLikeForScanning('Closure');
        }
        $functionlike_info = $this->createStorageForFunctionLike($stmt, $fake_method);
        if ($functionlike_info === \false) {
            return \false;
        }
        [$cased_function_id, $storage, $function_id, $fq_classlike_name, $method_name_lc, $classlike_storage, $is_functionlike_override, $method_id, $is_dupe] = $functionlike_info;
        if ($is_dupe) {
            return $storage;
        }
        if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
            $storage->cased_name = $stmt->name->name;
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Function_) {
            $storage->cased_name = ($this->aliases->namespace ? $this->aliases->namespace . '\\' : '') . $stmt->name->name;
        }
        if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod || $stmt instanceof PhpParser\Node\Stmt\Function_) {
            $storage->location = new CodeLocation($this->file_scanner, $stmt->name, null, \true);
        } else {
            $storage->location = new CodeLocation($this->file_scanner, $stmt, null, \true);
        }
        $storage->stmt_location = new CodeLocation($this->file_scanner, $stmt);
        $required_param_count = 0;
        $i = 0;
        $has_optional_param = \false;
        $existing_params = [];
        $storage->setParams([]);
        foreach ($stmt->getParams() as $param) {
            if ($param->var instanceof PhpParser\Node\Expr\Error) {
                $storage->docblock_issues[] = new InvalidDocblock('Param' . ($i + 1) . ' of ' . $cased_function_id . ' has invalid syntax', new CodeLocation($this->file_scanner, $param, null, \true));
                ++$i;
                continue;
            }
            $param_storage = $this->getTranslatedFunctionParam($param, $stmt, $fake_method, $fq_classlike_name);
            foreach ($param->attrGroups as $attr_group) {
                foreach ($attr_group->attrs as $attr) {
                    $param_storage->attributes[] = \Psalm\Internal\PhpVisitor\Reflector\AttributeResolver::resolve($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $attr, $this->classlike_storage->name ?? null);
                }
            }
            if ($param_storage->name === 'haystack' && in_array($this->file_path, $this->codebase->config->internal_stubs)) {
                $param_storage->expect_variable = \true;
            }
            if (isset($existing_params['$' . $param_storage->name])) {
                $storage->docblock_issues[] = new DuplicateParam('Duplicate param $' . $param_storage->name . ' in docblock for ' . $cased_function_id, new CodeLocation($this->file_scanner, $param, null, \true));
                ++$i;
                continue;
            }
            $existing_params['$' . $param_storage->name] = $i;
            $storage->addParam($param_storage, (bool) $param->type);
            if (!$param_storage->is_optional && !$param_storage->is_variadic) {
                $required_param_count = $i + 1;
                if (!$param->variadic && $has_optional_param) {
                    foreach ($storage->params as $param) {
                        $param->is_optional = \false;
                    }
                }
            } else {
                $has_optional_param = \true;
            }
            ++$i;
        }
        $storage->required_param_count = $required_param_count;
        if ($stmt instanceof PhpParser\Node\Stmt\Function_ || $stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
            if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod && $storage instanceof MethodStorage && $classlike_storage && !$classlike_storage->mutation_free && $stmt->stmts && count($stmt->stmts) === 1 && !count($stmt->params) && $stmt->stmts[0] instanceof PhpParser\Node\Stmt\Return_ && $stmt->stmts[0]->expr instanceof PhpParser\Node\Expr\PropertyFetch && $stmt->stmts[0]->expr->var instanceof PhpParser\Node\Expr\Variable && $stmt->stmts[0]->expr->var->name === 'this' && $stmt->stmts[0]->expr->name instanceof PhpParser\Node\Identifier) {
                $property_name = $stmt->stmts[0]->expr->name->name;
                if (isset($classlike_storage->properties[$property_name]) && $classlike_storage->properties[$property_name]->type) {
                    $storage->mutation_free = \true;
                    $storage->external_mutation_free = \true;
                    $storage->mutation_free_inferred = !$stmt->isFinal() && !$classlike_storage->final;
                    $classlike_storage->properties[$property_name]->getter_method = strtolower($stmt->name->name);
                }
            } elseif (strpos($stmt->name->name, 'assert') === 0 && $stmt->stmts) {
                $var_assertions = [];
                foreach ($stmt->stmts as $function_stmt) {
                    if ($function_stmt instanceof PhpParser\Node\Stmt\If_) {
                        $final_actions = ScopeAnalyzer::getControlActions($function_stmt->stmts, null, [], \false);
                        if ($final_actions !== [ScopeAnalyzer::ACTION_END]) {
                            $var_assertions = [];
                            break;
                        }
                        $cond_id = spl_object_id($function_stmt->cond);
                        $if_clauses = FormulaGenerator::getFormula($cond_id, $cond_id, $function_stmt->cond, $this->classlike_storage->name ?? null, $this->file_scanner, null);
                        try {
                            $negated_formula = Algebra::negateFormula($if_clauses);
                        } catch (ComplicatedExpressionException $e) {
                            $var_assertions = [];
                            break;
                        }
                        $rules = Algebra::getTruthsFromFormula($negated_formula);
                        if (!$rules) {
                            $var_assertions = [];
                            break;
                        }
                        foreach ($rules as $var_id => $rule) {
                            foreach ($rule as $rule_part) {
                                if (count($rule_part) > 1) {
                                    $var_assertions = [];
                                    continue 2;
                                }
                                if (isset($existing_params[$var_id])) {
                                    $param_offset = $existing_params[$var_id];
                                    $var_assertions[] = new Possibilities($param_offset, $rule_part);
                                } elseif (strpos($var_id, '$this->') === 0) {
                                    $var_assertions[] = new Possibilities($var_id, $rule_part);
                                }
                            }
                        }
                    } else {
                        $var_assertions = [];
                        break;
                    }
                }
                $storage->assertions = $var_assertions;
            }
            if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod && $stmt->stmts && $storage instanceof MethodStorage) {
                $last_stmt = end($stmt->stmts);
                if ($last_stmt instanceof PhpParser\Node\Stmt\Return_ && $last_stmt->expr instanceof PhpParser\Node\Expr\Variable && $last_stmt->expr->name === 'this') {
                    $storage->probably_fluent = \true;
                }
            }
        }
        if (!$this->file_scanner->will_analyze && ($stmt instanceof PhpParser\Node\Stmt\Function_ || $stmt instanceof PhpParser\Node\Stmt\ClassMethod || $stmt instanceof PhpParser\Node\Expr\Closure) && $stmt->stmts) {
            // pick up func_get_args that would otherwise be missed
            foreach ($stmt->stmts as $function_stmt) {
                if ($function_stmt instanceof PhpParser\Node\Stmt\Expression && $function_stmt->expr instanceof PhpParser\Node\Expr\Assign && $function_stmt->expr->expr instanceof PhpParser\Node\Expr\FuncCall && $function_stmt->expr->expr->name instanceof PhpParser\Node\Name) {
                    $inner_function_id = implode('\\', $function_stmt->expr->expr->name->parts);
                    if ($inner_function_id === 'func_get_arg' || $inner_function_id === 'func_get_args' || $inner_function_id === 'func_num_args') {
                        $storage->variadic = \true;
                    }
                } elseif ($function_stmt instanceof PhpParser\Node\Stmt\If_ && $function_stmt->cond instanceof PhpParser\Node\Expr\BinaryOp && $function_stmt->cond->left instanceof PhpParser\Node\Expr\BinaryOp\Equal && $function_stmt->cond->left->left instanceof PhpParser\Node\Expr\FuncCall && $function_stmt->cond->left->left->name instanceof PhpParser\Node\Name) {
                    $inner_function_id = implode('\\', $function_stmt->cond->left->left->name->parts);
                    if ($inner_function_id === 'func_get_arg' || $inner_function_id === 'func_get_args' || $inner_function_id === 'func_num_args') {
                        $storage->variadic = \true;
                    }
                }
            }
        }
        $parser_return_type = $stmt->getReturnType();
        if ($parser_return_type) {
            $original_type = $parser_return_type;
            /** @var Identifier|IntersectionType|Name|NullableType|UnionType $original_type */
            $storage->return_type = \Psalm\Internal\PhpVisitor\Reflector\TypeHintResolver::resolve($original_type, new CodeLocation($this->file_scanner, $original_type), $this->codebase, $this->file_storage, $this->classlike_storage, $this->aliases, $this->codebase->analysis_php_version_id);
            $storage->return_type_location = new CodeLocation($this->file_scanner, $original_type);
            if ($stmt->returnsByRef()) {
                /** @psalm-suppress InaccessibleProperty We just created this type */
                $storage->return_type->by_ref = \true;
            }
            $storage->signature_return_type = $storage->return_type;
            $storage->signature_return_type_location = $storage->return_type_location;
        }
        if ($stmt->returnsByRef()) {
            $storage->returns_by_ref = \true;
        }
        $doc_comment = $stmt->getDocComment();
        if ($classlike_storage && !$classlike_storage->is_trait) {
            $storage->internal = [...$classlike_storage->internal, ...$storage->internal];
        }
        if ($doc_comment) {
            try {
                $code_location = new CodeLocation($this->file_scanner, $stmt, null, \true);
                $docblock_info = \Psalm\Internal\PhpVisitor\Reflector\FunctionLikeDocblockParser::parse($doc_comment, $code_location, $cased_function_id);
            } catch (IncorrectDocblockException $e) {
                $storage->docblock_issues[] = new MissingDocblockType($e->getMessage() . ' in docblock for ' . $cased_function_id, new CodeLocation($this->file_scanner, $stmt, null, \true));
                $docblock_info = null;
            } catch (DocblockParseException $e) {
                $storage->docblock_issues[] = new InvalidDocblock($e->getMessage() . ' in docblock for ' . $cased_function_id, new CodeLocation($this->file_scanner, $stmt, null, \true));
                $docblock_info = null;
            }
            if ($docblock_info) {
                if ($docblock_info->since_php_major_version && !$this->aliases->namespace) {
                    $analysis_major_php_version = $this->codebase->getMajorAnalysisPhpVersion();
                    $analysis_minor_php_version = $this->codebase->getMajorAnalysisPhpVersion();
                    if ($docblock_info->since_php_major_version > $analysis_major_php_version) {
                        return \false;
                    }
                    if ($docblock_info->since_php_major_version === $analysis_major_php_version && $docblock_info->since_php_minor_version > $analysis_minor_php_version) {
                        return \false;
                    }
                }
                if ($stmt instanceof PhpParser\Node\Expr\Closure || $stmt instanceof PhpParser\Node\Expr\ArrowFunction) {
                    if ($docblock_info->templates !== []) {
                        $docblock_info->templates = [];
                        $storage->docblock_issues[] = new InvalidDocblock('Templated closures are not supported', new CodeLocation($this->file_scanner, $stmt, null, \true));
                    }
                }
                \Psalm\Internal\PhpVisitor\Reflector\FunctionLikeDocblockScanner::addDocblockInfo($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $this->type_aliases, $this->classlike_storage, $this->existing_function_template_types, $storage, $stmt, $docblock_info, $is_functionlike_override, $fake_method, $cased_function_id);
            }
        }
        // register the functionlike once the @since check has been completed
        if ($stmt instanceof PhpParser\Node\Stmt\Function_ && $function_id && $storage instanceof FunctionStorage) {
            if ($this->codebase->register_stub_files || $this->codebase->register_autoload_files && !$this->codebase->functions->hasStubbedFunction($function_id)) {
                $this->codebase->functions->addGlobalFunction($function_id, $storage);
            }
            $this->file_storage->functions[$function_id] = $storage;
            $this->file_storage->declaring_function_ids[$function_id] = strtolower($this->file_path);
        } elseif ($stmt instanceof PhpParser\Node\Stmt\ClassMethod && $classlike_storage && $storage instanceof MethodStorage && $method_name_lc && !$fake_method && $method_id) {
            $classlike_storage->methods[$method_name_lc] = $storage;
            $classlike_storage->declaring_method_ids[$method_name_lc] = $classlike_storage->appearing_method_ids[$method_name_lc] = $method_id;
            if (!$stmt->isPrivate() || $method_name_lc === '__construct' || $method_name_lc === '__clone' || $classlike_storage->is_trait) {
                $classlike_storage->inheritable_method_ids[$method_name_lc] = $method_id;
            }
            if (!isset($classlike_storage->overridden_method_ids[$method_name_lc])) {
                $classlike_storage->overridden_method_ids[$method_name_lc] = [];
            }
            if ($storage->final && $method_name_lc === '__construct') {
                // a bit of a hack, but makes sure that `new static` works for these classes
                $classlike_storage->preserve_constructor_signature = \true;
            }
        } elseif (($stmt instanceof PhpParser\Node\Expr\Closure || $stmt instanceof PhpParser\Node\Expr\ArrowFunction) && $function_id && $storage instanceof FunctionStorage) {
            $this->file_storage->functions[$function_id] = $storage;
        }
        if ($classlike_storage && $method_name_lc === '__construct') {
            foreach ($stmt->getParams() as $param) {
                if (!$param->flags || !$param->var instanceof PhpParser\Node\Expr\Variable) {
                    continue;
                }
                $param_storage = null;
                foreach ($storage->params as $param_storage) {
                    if ($param_storage->name === $param->var->name) {
                        break;
                    }
                }
                if (!$param_storage) {
                    continue;
                }
                if (isset($classlike_storage->properties[$param_storage->name]) && $param_storage->location) {
                    IssueBuffer::maybeAdd(new ParseError('Promoted property ' . $param_storage->name . ' clashes with an existing property', $param_storage->location));
                    $storage->has_visitor_issues = \true;
                    $this->file_storage->has_visitor_issues = \true;
                    continue;
                }
                $doc_comment = $param->getDocComment();
                $var_comment_type = null;
                $var_comment_readonly = \false;
                $var_comment_allow_private_mutation = \false;
                if ($doc_comment) {
                    $template_types = ($this->existing_function_template_types ?: []) + ($classlike_storage->template_types ?: []);
                    $var_comments = CommentAnalyzer::getTypeFromComment($doc_comment, $this->file_scanner, $this->aliases, $template_types, $this->type_aliases);
                    $var_comment = array_pop($var_comments);
                    if ($var_comment !== null) {
                        $var_comment_type = $var_comment->type;
                        $var_comment_readonly = $var_comment->readonly;
                        $var_comment_allow_private_mutation = $var_comment->allow_private_mutation;
                    }
                }
                //both way to document type were used
                if ($param_storage->type && $param_storage->type->from_docblock && $var_comment_type) {
                    if (IssueBuffer::accepts(new InvalidDocblock('Param ' . $param_storage->name . ' of ' . $cased_function_id . ' should be documented as a param or a property, not both', new CodeLocation($this->file_scanner, $param, null, \true)))) {
                        return \false;
                    }
                }
                //no docblock type was provided for param but we have one for property
                if ($var_comment_type) {
                    $param_storage->type = $var_comment_type;
                }
                $property_storage = $classlike_storage->properties[$param_storage->name] = new PropertyStorage();
                $property_storage->is_static = \false;
                $property_storage->type = $param_storage->type;
                $property_storage->signature_type = $param_storage->signature_type;
                $property_storage->signature_type_location = $param_storage->signature_type_location;
                $property_storage->type_location = $param_storage->type_location;
                $property_storage->location = $param_storage->location;
                $property_storage->stmt_location = new CodeLocation($this->file_scanner, $param);
                $property_storage->has_default = (bool) $param->default;
                $param_type_readonly = (bool) ($param->flags & PhpParser\Node\Stmt\Class_::MODIFIER_READONLY);
                $property_storage->readonly = $param_type_readonly ?: $var_comment_readonly;
                $property_storage->allow_private_mutation = $var_comment_allow_private_mutation;
                $param_storage->promoted_property = \true;
                $property_storage->is_promoted = \true;
                $property_id = $fq_classlike_name . '::$' . $param_storage->name;
                switch ($param->flags & Class_::VISIBILITY_MODIFIER_MASK) {
                    case Class_::MODIFIER_PUBLIC:
                        $property_storage->visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
                        $classlike_storage->inheritable_property_ids[$param_storage->name] = $property_id;
                        break;
                    case Class_::MODIFIER_PROTECTED:
                        $property_storage->visibility = ClassLikeAnalyzer::VISIBILITY_PROTECTED;
                        $classlike_storage->inheritable_property_ids[$param_storage->name] = $property_id;
                        break;
                    case Class_::MODIFIER_PRIVATE:
                        $property_storage->visibility = ClassLikeAnalyzer::VISIBILITY_PRIVATE;
                        break;
                }
                $fq_classlike_name = $classlike_storage->name;
                $property_id = $fq_classlike_name . '::$' . $param_storage->name;
                $classlike_storage->declaring_property_ids[$param_storage->name] = $fq_classlike_name;
                $classlike_storage->appearing_property_ids[$param_storage->name] = $property_id;
                $classlike_storage->initialized_properties[$param_storage->name] = \true;
            }
            if ($stmt instanceof PhpParser\Node\Stmt\ClassMethod && $storage instanceof MethodStorage && $storage->params && $this->config->infer_property_types_from_constructor) {
                $this->inferPropertyTypeFromConstructor($stmt, $storage, $classlike_storage);
            }
        }
        foreach ($stmt->getAttrGroups() as $attr_group) {
            foreach ($attr_group->attrs as $attr) {
                $attribute = \Psalm\Internal\PhpVisitor\Reflector\AttributeResolver::resolve($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $attr, $this->classlike_storage->name ?? null);
                if ($attribute->fq_class_name === 'Psalm\\Pure' || $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Pure') {
                    $storage->specialize_call = \true;
                    $storage->mutation_free = \true;
                    if ($storage instanceof MethodStorage) {
                        $storage->external_mutation_free = \true;
                    }
                }
                if ($attribute->fq_class_name === 'Psalm\\Deprecated' || $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Deprecated') {
                    $storage->deprecated = \true;
                }
                if ($attribute->fq_class_name === 'Psalm\\Internal' && !$storage->internal && $fq_classlike_name) {
                    $storage->internal = [NamespaceAnalyzer::getNameSpaceRoot($fq_classlike_name)];
                }
                if ($attribute->fq_class_name === 'Psalm\\ExternalMutationFree' && $storage instanceof MethodStorage) {
                    $storage->external_mutation_free = \true;
                }
                if ($attribute->fq_class_name === 'JetBrains\\PhpStorm\\NoReturn') {
                    $storage->return_type = Type::getNever();
                }
                $storage->attributes[] = $attribute;
            }
        }
        return $storage;
    }
    private function inferPropertyTypeFromConstructor(PhpParser\Node\Stmt\ClassMethod $stmt, MethodStorage $storage, ClassLikeStorage $classlike_storage) : void
    {
        if (!$stmt->stmts) {
            return;
        }
        $assigned_properties = [];
        foreach ($stmt->stmts as $function_stmt) {
            if ($function_stmt instanceof PhpParser\Node\Stmt\Expression && $function_stmt->expr instanceof PhpParser\Node\Expr\Assign && $function_stmt->expr->var instanceof PhpParser\Node\Expr\PropertyFetch && $function_stmt->expr->var->var instanceof PhpParser\Node\Expr\Variable && $function_stmt->expr->var->var->name === 'this' && $function_stmt->expr->var->name instanceof PhpParser\Node\Identifier && ($property_name = $function_stmt->expr->var->name->name) && isset($classlike_storage->properties[$property_name]) && $function_stmt->expr->expr instanceof PhpParser\Node\Expr\Variable && is_string($function_stmt->expr->expr->name) && ($param_name = $function_stmt->expr->expr->name) && isset($storage->param_lookup[$param_name])) {
                if ($classlike_storage->properties[$property_name]->type || !$storage->param_lookup[$param_name]) {
                    continue;
                }
                $param_index = array_search($param_name, array_keys($storage->param_lookup), \true);
                if ($param_index === \false || !isset($storage->params[$param_index]->type)) {
                    continue;
                }
                $param_type = $storage->params[$param_index]->type;
                $assigned_properties[$property_name] = $storage->params[$param_index]->is_variadic ? new Union([new TArray([Type::getInt(), $param_type])]) : $param_type;
            } else {
                $assigned_properties = [];
                break;
            }
        }
        if (!$assigned_properties) {
            return;
        }
        $storage->external_mutation_free = \true;
        $storage->mutation_free_inferred = \true;
        foreach ($assigned_properties as $property_name => $property_type) {
            $classlike_storage->properties[$property_name]->type = $property_type;
        }
    }
    private function getTranslatedFunctionParam(PhpParser\Node\Param $param, PhpParser\Node\FunctionLike $stmt, bool $fake_method, ?string $fq_classlike_name) : FunctionLikeParameter
    {
        $param_type = null;
        $is_nullable = $param->default instanceof PhpParser\Node\Expr\ConstFetch && strtolower($param->default->name->parts[0]) === 'null';
        $param_typehint = $param->type;
        if ($param_typehint) {
            /** @var Identifier|IntersectionType|Name|NullableType|UnionType $param_typehint */
            $param_type = \Psalm\Internal\PhpVisitor\Reflector\TypeHintResolver::resolve($param_typehint, new CodeLocation($this->file_scanner, $param_typehint), $this->codebase, $this->file_storage, $this->classlike_storage, $this->aliases, $this->codebase->analysis_php_version_id);
            if ($is_nullable) {
                $param_type = $param_type->getBuilder()->addType(new TNull())->freeze();
            } else {
                $is_nullable = $param_type->isNullable();
            }
        }
        $is_optional = $param->default !== null;
        if ($param->var instanceof PhpParser\Node\Expr\Error || !is_string($param->var->name)) {
            throw new UnexpectedValueException('Not expecting param name to be non-string');
        }
        $default_type = null;
        if ($param->default) {
            $default_type = SimpleTypeInferer::infer($this->codebase, new NodeDataProvider(), $param->default, $this->aliases, null, null, $fq_classlike_name);
            if (!$default_type) {
                $default_type = \Psalm\Internal\PhpVisitor\Reflector\ExpressionResolver::getUnresolvedClassConstExpr($param->default, $this->aliases, $fq_classlike_name);
            }
        }
        return new FunctionLikeParameter($param->var->name, $param->byRef, $param_type, $param_type, new CodeLocation($this->file_scanner, $fake_method ? $stmt : $param->var, null, \false, !$fake_method ? CodeLocation::FUNCTION_PARAM_VAR : CodeLocation::FUNCTION_PHPDOC_METHOD), $param_typehint ? new CodeLocation($this->file_scanner, $fake_method ? $stmt : $param, null, \false, CodeLocation::FUNCTION_PARAM_TYPE) : null, $is_optional, $is_nullable, $param->variadic, $default_type);
    }
    //phpcs:disable -- Remove this once the phpstan phpdoc parser MR is merged
    /**
     * @return array{
     *     string,
     *     FunctionStorage|MethodStorage,
     *     null|string,
     *     null|string,
     *     null|lowercase-string,
     *     ClassLikeStorage|null,
     *     bool,
     *     MethodIdentifier|null,
     *     bool
     * }|false
     */
    private function createStorageForFunctionLike(PhpParser\Node\FunctionLike $stmt, bool $fake_method)
    {
        //phpcs:enable -- Remove this once the phpstan phpdoc parser MR is merged
        $classlike_storage = null;
        $fq_classlike_name = null;
        $is_functionlike_override = \false;
        $function_id = null;
        $method_name_lc = null;
        $method_id = null;
        if ($fake_method && $stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
            $cased_function_id = '@method ' . $stmt->name->name;
            $storage = $this->storage = new MethodStorage();
            $storage->defining_fqcln = '';
            $storage->is_static = $stmt->isStatic();
            $storage->final = $this->classlike_storage && $this->classlike_storage->final;
            $storage->final_from_docblock = $this->classlike_storage && $this->classlike_storage->final_from_docblock;
        } elseif ($stmt instanceof PhpParser\Node\Stmt\Function_) {
            $cased_function_id = ($this->aliases->namespace ? $this->aliases->namespace . '\\' : '') . $stmt->name->name;
            $function_id = strtolower($cased_function_id);
            $storage = $this->storage = new FunctionStorage();
            if ($this->codebase->register_stub_files || $this->codebase->register_autoload_files) {
                if (isset($this->file_storage->functions[$function_id]) && ($this->codebase->register_stub_files || !$this->codebase->functions->hasStubbedFunction($function_id))) {
                    $this->codebase->functions->addGlobalFunction($function_id, $this->file_storage->functions[$function_id]);
                    $storage = $this->storage = $this->file_storage->functions[$function_id];
                    return [$function_id, $storage, null, null, null, null, \false, null, \true];
                }
            } else {
                if (isset($this->file_storage->functions[$function_id])) {
                    $duplicate_function_storage = $this->file_storage->functions[$function_id];
                    if ($duplicate_function_storage->location && $duplicate_function_storage->location->getLineNumber() === $stmt->getLine()) {
                        $storage = $this->storage = $this->file_storage->functions[$function_id];
                        return [$function_id, $storage, null, null, null, null, \false, null, \true];
                    }
                    IssueBuffer::maybeAdd(new DuplicateFunction('Method ' . $function_id . ' has already been defined' . ($duplicate_function_storage->location ? ' in ' . $duplicate_function_storage->location->file_path : ''), new CodeLocation($this->file_scanner, $stmt, null, \true)));
                    $this->file_storage->has_visitor_issues = \true;
                    $duplicate_function_storage->has_visitor_issues = \true;
                    $storage = $this->storage = $this->file_storage->functions[$function_id];
                    return [$function_id, $storage, null, null, null, null, \false, null, \true];
                }
                if (isset($this->config->getPredefinedFunctions()[$function_id])) {
                    /** @psalm-suppress ArgumentTypeCoercion */
                    $reflection_function = new ReflectionFunction($function_id);
                    if ($reflection_function->getFileName() !== $this->file_path) {
                        IssueBuffer::maybeAdd(new DuplicateFunction('Method ' . $function_id . ' has already been defined as a core function', new CodeLocation($this->file_scanner, $stmt, null, \true)));
                    }
                }
            }
        } elseif ($stmt instanceof PhpParser\Node\Stmt\ClassMethod) {
            if (!$this->classlike_storage) {
                throw new LogicException('$this->classlike_storage should not be null');
            }
            $fq_classlike_name = $this->classlike_storage->name;
            $method_name_lc = strtolower($stmt->name->name);
            $function_id = $fq_classlike_name . '::' . $method_name_lc;
            $cased_function_id = $fq_classlike_name . '::' . $stmt->name->name;
            $classlike_storage = $this->classlike_storage;
            $storage = null;
            if (isset($classlike_storage->methods[$method_name_lc])) {
                if (!$this->codebase->register_stub_files) {
                    $duplicate_method_storage = $classlike_storage->methods[$method_name_lc];
                    IssueBuffer::maybeAdd(new DuplicateMethod('Method ' . $function_id . ' has already been defined' . ($duplicate_method_storage->location ? ' in ' . $duplicate_method_storage->location->file_path : ''), new CodeLocation($this->file_scanner, $stmt, null, \true)));
                    $this->file_storage->has_visitor_issues = \true;
                    $duplicate_method_storage->has_visitor_issues = \true;
                    return \false;
                }
                // skip methods based on @since docblock tag
                $doc_comment = $stmt->getDocComment();
                if ($doc_comment) {
                    $docblock_info = null;
                    try {
                        $code_location = new CodeLocation($this->file_scanner, $stmt, null, \true);
                        $docblock_info = \Psalm\Internal\PhpVisitor\Reflector\FunctionLikeDocblockParser::parse($doc_comment, $code_location, $cased_function_id);
                    } catch (IncorrectDocblockException|DocblockParseException $e) {
                    }
                    if ($docblock_info) {
                        if ($docblock_info->since_php_major_version && !$this->aliases->namespace) {
                            $analysis_major_php_version = $this->codebase->getMajorAnalysisPhpVersion();
                            $analysis_minor_php_version = $this->codebase->getMajorAnalysisPhpVersion();
                            if ($docblock_info->since_php_major_version > $analysis_major_php_version) {
                                return \false;
                            }
                            if ($docblock_info->since_php_major_version === $analysis_major_php_version && $docblock_info->since_php_minor_version > $analysis_minor_php_version) {
                                return \false;
                            }
                        }
                    }
                }
                $is_functionlike_override = \true;
                $storage = $this->storage = $classlike_storage->methods[$method_name_lc];
            }
            if (!$storage) {
                $storage = $this->storage = new MethodStorage();
            }
            $storage->stubbed = $this->codebase->register_stub_files;
            $storage->defining_fqcln = $fq_classlike_name;
            $class_name_parts = explode('\\', $fq_classlike_name);
            $class_name = array_pop($class_name_parts);
            if ($method_name_lc === strtolower($class_name) && !isset($classlike_storage->methods['__construct']) && strpos($fq_classlike_name, '\\') === \false && $this->codebase->analysis_php_version_id <= 70400) {
                $this->codebase->methods->setDeclaringMethodId($fq_classlike_name, '__construct', $fq_classlike_name, $method_name_lc);
                $this->codebase->methods->setAppearingMethodId($fq_classlike_name, '__construct', $fq_classlike_name, $method_name_lc);
            }
            $method_id = new MethodIdentifier($fq_classlike_name, $method_name_lc);
            $storage->is_static = $stmt->isStatic();
            $storage->abstract = $stmt->isAbstract();
            $storage->final = $classlike_storage->final || $stmt->isFinal();
            $storage->final_from_docblock = $classlike_storage->final_from_docblock;
            if ($stmt->isPrivate()) {
                $storage->visibility = ClassLikeAnalyzer::VISIBILITY_PRIVATE;
            } elseif ($stmt->isProtected()) {
                $storage->visibility = ClassLikeAnalyzer::VISIBILITY_PROTECTED;
            } else {
                $storage->visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
            }
        } elseif ($stmt instanceof PhpParser\Node\Expr\Closure || $stmt instanceof PhpParser\Node\Expr\ArrowFunction) {
            $function_id = $cased_function_id = strtolower($this->file_path) . ':' . $stmt->getLine() . ':' . (int) $stmt->getAttribute('startFilePos') . ':-:closure';
            $storage = $this->storage = $this->file_storage->functions[$function_id] = new FunctionStorage();
            $storage->is_static = $stmt->static;
            if ($stmt instanceof PhpParser\Node\Expr\Closure) {
                foreach ($stmt->uses as $closure_use) {
                    if ($closure_use->byRef && is_string($closure_use->var->name)) {
                        $storage->byref_uses[$closure_use->var->name] = \true;
                    }
                }
            }
        } else {
            throw new UnexpectedValueException('Unrecognized functionlike');
        }
        return [$cased_function_id, $storage, $function_id, $fq_classlike_name, $method_name_lc, $classlike_storage, $is_functionlike_override, $method_id, \false];
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use AssertionError;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\IncorrectDocblockException;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Scanner\DocblockParser;
use Psalm\Internal\Scanner\FunctionDocblockComment;
use Psalm\Internal\Scanner\ParsedDocblock;
use Psalm\Issue\InvalidDocblock;
use Psalm\IssueBuffer;
use function array_keys;
use function array_shift;
use function array_unique;
use function count;
use function explode;
use function implode;
use function in_array;
use function preg_last_error_msg;
use function preg_match;
use function preg_replace;
use function preg_split;
use function reset;
use function str_replace;
use function stripos;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
use function substr_count;
use function trim;
/**
 * @internal
 */
class FunctionLikeDocblockParser
{
    /**
     * @throws DocblockParseException if there was a problem parsing the docblock
     */
    public static function parse(PhpParser\Comment\Doc $comment, CodeLocation $code_location, string $cased_function_id) : FunctionDocblockComment
    {
        $parsed_docblock = DocComment::parsePreservingLength($comment);
        $comment_text = $comment->getText();
        $info = new FunctionDocblockComment();
        self::checkDuplicatedTags($parsed_docblock);
        self::checkUnexpectedTags($parsed_docblock, $info, $comment);
        if (isset($parsed_docblock->combined_tags['return'])) {
            self::extractReturnType($comment, $parsed_docblock->combined_tags['return'], $info, $code_location, $cased_function_id);
        }
        if (isset($parsed_docblock->combined_tags['param'])) {
            foreach ($parsed_docblock->combined_tags['param'] as $offset => $param) {
                $line_parts = CommentAnalyzer::splitDocLine($param);
                if (count($line_parts) === 1 && isset($line_parts[0][0]) && $line_parts[0][0] === '$') {
                    continue;
                }
                if (count($line_parts) > 1) {
                    if (preg_match('/^&?(\\.\\.\\.)?&?\\$[A-Za-z0-9_]+,?$/', $line_parts[1]) && ($line_parts[0] === '' || $line_parts[0][0] !== '{')) {
                        $line_parts[1] = str_replace('&', '', $line_parts[1]);
                        $line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);
                        $end = $offset + strlen($line_parts[0]);
                        $line_parts[0] = CommentAnalyzer::sanitizeDocblockType($line_parts[0]);
                        if ($line_parts[0] === '' || $line_parts[0][0] === '$' && !preg_match('/^\\$this(\\||$)/', $line_parts[0])) {
                            throw new IncorrectDocblockException('Misplaced variable');
                        }
                        $info_param = ['name' => trim($line_parts[1]), 'type' => $line_parts[0], 'line_number' => $comment->getStartLine() + substr_count($comment_text, "\n", 0, $offset - $comment->getStartFilePos()), 'start' => $offset, 'end' => $end];
                        if (isset($line_parts[1]) && isset($line_parts[2])) {
                            $description = substr($param, strlen($line_parts[0]) + strlen($line_parts[1]) + 2);
                            $info_param['description'] = trim($description);
                            // Handle multiline description.
                            $info_param['description'] = preg_replace('/\\n \\*\\s+/um', ' ', $info_param['description']);
                        }
                        $info->params[] = $info_param;
                    }
                } else {
                    IssueBuffer::maybeAdd(new InvalidDocblock('Badly-formatted @param in docblock for ' . $cased_function_id, $code_location));
                }
            }
        }
        if (isset($parsed_docblock->combined_tags['param-out'])) {
            foreach ($parsed_docblock->combined_tags['param-out'] as $offset => $param) {
                $line_parts = CommentAnalyzer::splitDocLine($param);
                if (count($line_parts) === 1 && isset($line_parts[0][0]) && $line_parts[0][0] === '$') {
                    continue;
                }
                if (count($line_parts) > 1) {
                    if (!preg_match('/\\[[^\\]]+\\]/', $line_parts[0]) && preg_match('/^(\\.\\.\\.)?&?\\$[A-Za-z0-9_]+,?$/', $line_parts[1]) && $line_parts[0][0] !== '{') {
                        if ($line_parts[1][0] === '&') {
                            $line_parts[1] = substr($line_parts[1], 1);
                        }
                        $line_parts[0] = str_replace("\n", '', preg_replace('@^[ \\t]*\\*@m', '', $line_parts[0]));
                        if ($line_parts[0] === '' || $line_parts[0][0] === '$' && !preg_match('/^\\$this(\\||$)/', $line_parts[0])) {
                            throw new IncorrectDocblockException('Misplaced variable');
                        }
                        $line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);
                        $info->params_out[] = ['name' => trim($line_parts[1]), 'type' => str_replace("\n", '', $line_parts[0]), 'line_number' => $comment->getStartLine() + substr_count($comment_text, "\n", 0, $offset - $comment->getStartFilePos())];
                    }
                } else {
                    IssueBuffer::maybeAdd(new InvalidDocblock('Badly-formatted @param in docblock for ' . $cased_function_id, $code_location));
                }
            }
        }
        foreach (['psalm-self-out', 'psalm-this-out', 'phpstan-self-out', 'phpstan-this-out'] as $alias) {
            if (isset($parsed_docblock->tags[$alias])) {
                foreach ($parsed_docblock->tags[$alias] as $offset => $param) {
                    $line_parts = CommentAnalyzer::splitDocLine($param);
                    if (count($line_parts) > 0) {
                        $line_parts[0] = str_replace("\n", '', preg_replace('@^[ \\t]*\\*@m', '', $line_parts[0]));
                        $info->self_out = ['type' => str_replace("\n", '', $line_parts[0]), 'line_number' => $comment->getStartLine() + substr_count($comment_text, "\n", 0, $offset - $comment->getStartFilePos())];
                    }
                }
                break;
            }
        }
        if (isset($parsed_docblock->tags['psalm-flow'])) {
            foreach ($parsed_docblock->tags['psalm-flow'] as $param) {
                $info->flows[] = trim($param);
            }
        }
        if (isset($parsed_docblock->tags['psalm-if-this-is'])) {
            foreach ($parsed_docblock->tags['psalm-if-this-is'] as $offset => $param) {
                $line_parts = CommentAnalyzer::splitDocLine($param);
                $line_parts[0] = str_replace("\n", '', preg_replace('@^[ \\t]*\\*@m', '', $line_parts[0]));
                $info->if_this_is = ['type' => str_replace("\n", '', $line_parts[0]), 'line_number' => $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset - $comment->getStartFilePos())];
            }
        }
        if (isset($parsed_docblock->tags['psalm-taint-sink'])) {
            foreach ($parsed_docblock->tags['psalm-taint-sink'] as $param) {
                $param_parts = preg_split('/\\s+/', trim($param));
                if ($param_parts === \false) {
                    throw new AssertionError(preg_last_error_msg());
                }
                if (count($param_parts) >= 2) {
                    $info->taint_sink_params[] = ['name' => $param_parts[1], 'taint' => $param_parts[0]];
                }
            }
        }
        // support for MediaWiki taint plugin
        if (isset($parsed_docblock->tags['param-taint'])) {
            foreach ($parsed_docblock->tags['param-taint'] as $param) {
                $param_parts = preg_split('/\\s+/', trim($param));
                if ($param_parts === \false) {
                    throw new AssertionError(preg_last_error_msg());
                }
                if (count($param_parts) === 2) {
                    $taint_type = $param_parts[1];
                    if (strpos($taint_type, 'exec_') === 0) {
                        $taint_type = substr($taint_type, 5);
                        if ($taint_type === 'tainted') {
                            $taint_type = 'input';
                        }
                        if ($taint_type === 'misc') {
                            $taint_type = 'text';
                        }
                        $info->taint_sink_params[] = ['name' => $param_parts[0], 'taint' => $taint_type];
                    }
                }
            }
        }
        if (isset($parsed_docblock->tags['psalm-taint-source'])) {
            foreach ($parsed_docblock->tags['psalm-taint-source'] as $param) {
                $param_parts = preg_split('/\\s+/', trim($param));
                if ($param_parts === \false) {
                    throw new AssertionError(preg_last_error_msg());
                }
                if ($param_parts[0]) {
                    $info->taint_source_types[] = $param_parts[0];
                }
            }
        } elseif (isset($parsed_docblock->tags['return-taint'])) {
            // support for MediaWiki taint plugin
            foreach ($parsed_docblock->tags['return-taint'] as $param) {
                $param_parts = preg_split('/\\s+/', trim($param));
                if ($param_parts === \false) {
                    throw new AssertionError(preg_last_error_msg());
                }
                if ($param_parts[0]) {
                    if ($param_parts[0] === 'tainted') {
                        $param_parts[0] = 'input';
                    }
                    if ($param_parts[0] === 'misc') {
                        $param_parts[0] = 'text';
                    }
                    if ($param_parts[0] !== 'none') {
                        $info->taint_source_types[] = $param_parts[0];
                    }
                }
            }
        }
        if (isset($parsed_docblock->tags['psalm-taint-unescape'])) {
            foreach ($parsed_docblock->tags['psalm-taint-unescape'] as $param) {
                $param = trim($param);
                $info->added_taints[] = $param;
            }
        }
        if (isset($parsed_docblock->tags['psalm-taint-escape'])) {
            foreach ($parsed_docblock->tags['psalm-taint-escape'] as $param) {
                $param = trim($param);
                if ($param[0] === '(') {
                    $line_parts = CommentAnalyzer::splitDocLine($param);
                    $info->removed_taints[] = CommentAnalyzer::sanitizeDocblockType($line_parts[0]);
                } else {
                    $info->removed_taints[] = explode(' ', $param)[0];
                }
            }
        }
        if (isset($parsed_docblock->tags['psalm-assert-untainted'])) {
            foreach ($parsed_docblock->tags['psalm-assert-untainted'] as $param) {
                $param = trim($param);
                $info->assert_untainted_params[] = ['name' => $param];
            }
        }
        if (isset($parsed_docblock->tags['psalm-taint-specialize'])) {
            $info->specialize_call = \true;
        }
        if (isset($parsed_docblock->tags['global'])) {
            foreach ($parsed_docblock->tags['global'] as $offset => $global) {
                $line_parts = CommentAnalyzer::splitDocLine($global);
                if (count($line_parts) === 1 && isset($line_parts[0][0]) && $line_parts[0][0] === '$') {
                    continue;
                }
                if (count($line_parts) > 1) {
                    if (!preg_match('/\\[[^\\]]+\\]/', $line_parts[0]) && preg_match('/^(\\.\\.\\.)?&?\\$[A-Za-z0-9_]+,?$/', $line_parts[1]) && $line_parts[0][0] !== '{') {
                        if ($line_parts[1][0] === '&') {
                            $line_parts[1] = substr($line_parts[1], 1);
                        }
                        if ($line_parts[0][0] === '$' && !preg_match('/^\\$this(\\||$)/', $line_parts[0])) {
                            throw new IncorrectDocblockException('Misplaced variable');
                        }
                        $line_parts[1] = preg_replace('/,$/', '', $line_parts[1], 1);
                        $info->globals[] = ['name' => $line_parts[1], 'type' => $line_parts[0], 'line_number' => $comment->getStartLine() + substr_count($comment_text, "\n", 0, $offset - $comment->getStartFilePos())];
                    }
                } else {
                    IssueBuffer::maybeAdd(new InvalidDocblock('Badly-formatted @param in docblock for ' . $cased_function_id, $code_location));
                }
            }
        }
        if (isset($parsed_docblock->tags['since'])) {
            $since = trim(reset($parsed_docblock->tags['since']));
            if (preg_match('/^[4578]\\.\\d(\\.\\d+)?$/', $since)) {
                $since_parts = explode('.', $since);
                $info->since_php_major_version = (int) $since_parts[0];
                $info->since_php_minor_version = (int) $since_parts[1];
            }
        }
        if (isset($parsed_docblock->tags['deprecated'])) {
            $info->deprecated = \true;
        }
        if (isset($parsed_docblock->tags['internal'])) {
            $info->internal = \true;
        }
        if (count($info->psalm_internal = DocblockParser::handlePsalmInternal($parsed_docblock)) !== 0) {
            $info->internal = \true;
        }
        if (isset($parsed_docblock->tags['psalm-suppress'])) {
            foreach ($parsed_docblock->tags['psalm-suppress'] as $offset => $suppress_entry) {
                foreach (DocComment::parseSuppressList($suppress_entry) as $issue_offset => $suppressed_issue) {
                    $info->suppressed_issues[$issue_offset + $offset] = $suppressed_issue;
                }
            }
        }
        if (isset($parsed_docblock->tags['throws'])) {
            foreach ($parsed_docblock->tags['throws'] as $offset => $throws_entry) {
                $throws_class = preg_split('/[\\s]+/', $throws_entry)[0];
                if (!$throws_class) {
                    throw new IncorrectDocblockException('Unexpectedly empty @throws');
                }
                $info->throws[] = [$throws_class, $offset, $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset - $comment->getStartFilePos())];
            }
        }
        if (stripos($parsed_docblock->description, '@inheritdoc') !== \false || isset($parsed_docblock->tags['inheritdoc']) || isset($parsed_docblock->tags['inheritDoc'])) {
            $info->inheritdoc = \true;
        }
        $templates = [];
        if (isset($parsed_docblock->combined_tags['template'])) {
            foreach ($parsed_docblock->combined_tags['template'] as $offset => $template_line) {
                $template_type = preg_split('/[\\s]+/', preg_replace('@^[ \\t]*\\*@m', '', $template_line));
                if ($template_type === \false) {
                    throw new AssertionError(preg_last_error_msg());
                }
                $template_name = array_shift($template_type);
                if (!$template_name) {
                    throw new IncorrectDocblockException('Empty @template tag');
                }
                $source_prefix = 'none';
                if (isset($parsed_docblock->tags['psalm-template'][$offset])) {
                    $source_prefix = 'psalm';
                } elseif (isset($parsed_docblock->tags['phpstan-template'][$offset])) {
                    $source_prefix = 'phpstan';
                }
                if (count($template_type) > 1 && in_array(strtolower($template_type[0]), ['as', 'super', 'of'], \true)) {
                    $template_modifier = strtolower(array_shift($template_type));
                    $templates[$template_name][$source_prefix] = [$template_name, $template_modifier, implode(' ', $template_type), \false];
                } else {
                    $templates[$template_name][$source_prefix] = [$template_name, null, null, \false];
                }
            }
        }
        foreach ($templates as $template_entries) {
            foreach (['psalm', 'phpstan', 'none'] as $source_prefix) {
                if (isset($template_entries[$source_prefix])) {
                    $info->templates[] = $template_entries[$source_prefix];
                    break;
                }
            }
        }
        foreach (['psalm-assert', 'phpstan-assert'] as $assert) {
            if (isset($parsed_docblock->tags[$assert])) {
                foreach ($parsed_docblock->tags[$assert] as $assertion) {
                    $line_parts = self::sanitizeAssertionLineParts(CommentAnalyzer::splitDocLine($assertion));
                    $info->assertions[] = ['type' => $line_parts[0], 'param_name' => $line_parts[1][0] === '$' ? substr($line_parts[1], 1) : $line_parts[1]];
                }
                break;
            }
        }
        foreach (['psalm-assert-if-true', 'phpstan-assert-if-true'] as $assert) {
            if (isset($parsed_docblock->tags[$assert])) {
                foreach ($parsed_docblock->tags[$assert] as $assertion) {
                    $line_parts = self::sanitizeAssertionLineParts(CommentAnalyzer::splitDocLine($assertion));
                    $info->if_true_assertions[] = ['type' => $line_parts[0], 'param_name' => $line_parts[1][0] === '$' ? substr($line_parts[1], 1) : $line_parts[1]];
                }
                break;
            }
        }
        foreach (['psalm-assert-if-false', 'phpstan-assert-if-false'] as $assert) {
            if (isset($parsed_docblock->tags[$assert])) {
                foreach ($parsed_docblock->tags[$assert] as $assertion) {
                    $line_parts = self::sanitizeAssertionLineParts(CommentAnalyzer::splitDocLine($assertion));
                    $info->if_false_assertions[] = ['type' => $line_parts[0], 'param_name' => $line_parts[1][0] === '$' ? substr($line_parts[1], 1) : $line_parts[1]];
                }
                break;
            }
        }
        $info->variadic = isset($parsed_docblock->tags['psalm-variadic']);
        $info->pure = isset($parsed_docblock->tags['psalm-pure']) || isset($parsed_docblock->tags['pure']);
        if (isset($parsed_docblock->tags['psalm-mutation-free'])) {
            $info->mutation_free = \true;
        }
        if (isset($parsed_docblock->tags['psalm-external-mutation-free'])) {
            $info->external_mutation_free = \true;
        }
        if (isset($parsed_docblock->tags['no-named-arguments'])) {
            $info->no_named_args = \true;
        }
        $info->ignore_nullable_return = isset($parsed_docblock->tags['psalm-ignore-nullable-return']);
        $info->ignore_falsable_return = isset($parsed_docblock->tags['psalm-ignore-falsable-return']);
        $info->stub_override = isset($parsed_docblock->tags['psalm-stub-override']);
        if (!empty($parsed_docblock->description)) {
            $info->description = $parsed_docblock->description;
        }
        return $info;
    }
    /**
     * @psalm-pure
     * @param list<string> $line_parts
     * @return array{string, string}&array<int<0, max>, string> $line_parts
     */
    private static function sanitizeAssertionLineParts(array $line_parts) : array
    {
        if (count($line_parts) < 2 || strpos($line_parts[1], '$') === \false) {
            throw new IncorrectDocblockException('Misplaced variable');
        }
        $line_parts[0] = CommentAnalyzer::sanitizeDocblockType($line_parts[0]);
        if ($line_parts[1][0] === '$') {
            $param_name_parts = explode('->', $line_parts[1]);
            foreach ($param_name_parts as $i => $param_name_part) {
                if (substr($param_name_part, -2) === '()') {
                    $param_name_parts[$i] = strtolower($param_name_part);
                }
            }
            $line_parts[1] = implode('->', $param_name_parts);
        }
        return $line_parts;
    }
    /**
     * @param array<int, string> $return_specials
     */
    private static function extractReturnType(PhpParser\Comment\Doc $comment, array $return_specials, FunctionDocblockComment $info, CodeLocation $code_location, string $cased_function_id) : void
    {
        foreach ($return_specials as $offset => $return_block) {
            $return_lines = explode("\n", $return_block);
            if (trim($return_lines[0]) === '') {
                return;
            }
            $return_block = trim($return_block);
            if ($return_block === '') {
                return;
            }
            $line_parts = CommentAnalyzer::splitDocLine($return_block);
            if ($line_parts[0][0] !== '{') {
                if ($line_parts[0][0] === '$' && !preg_match('/^\\$this(\\||$)/', $line_parts[0])) {
                    throw new IncorrectDocblockException('Misplaced variable');
                }
                $end = $offset + strlen($line_parts[0]);
                $line_parts[0] = CommentAnalyzer::sanitizeDocblockType($line_parts[0]);
                $info->return_type = array_shift($line_parts);
                $info->return_type_description = $line_parts ? implode(' ', $line_parts) : null;
                $info->return_type_line_number = $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset - $comment->getStartFilePos());
                $info->return_type_start = $offset;
                $info->return_type_end = $end;
            } else {
                IssueBuffer::maybeAdd(new InvalidDocblock('Badly-formatted @param in docblock for ' . $cased_function_id, $code_location));
            }
            break;
        }
    }
    /**
     * @throws DocblockParseException if a duplicate is found
     */
    private static function checkDuplicatedTags(ParsedDocblock $parsed_docblock) : void
    {
        if (count($parsed_docblock->tags['return'] ?? []) > 1 || count($parsed_docblock->tags['psalm-return'] ?? []) > 1 || count($parsed_docblock->tags['phpstan-return'] ?? []) > 1) {
            throw new DocblockParseException('Found duplicated @return or prefixed @return tag');
        }
        self::checkDuplicatedParams($parsed_docblock->tags['param'] ?? []);
        self::checkDuplicatedParams($parsed_docblock->tags['psalm-param'] ?? []);
        self::checkDuplicatedParams($parsed_docblock->tags['phpstan-param'] ?? []);
    }
    /**
     * @param array<int, string> $param
     * @throws DocblockParseException  if a duplicate is found
     */
    private static function checkDuplicatedParams(array $param) : void
    {
        $list_names = self::extractAllParamNames($param);
        if (count($list_names) !== count(array_unique($list_names))) {
            throw new DocblockParseException('Found duplicated @param or prefixed @param tag');
        }
    }
    /**
     * @param array<int, string> $lines
     * @return list<string>
     * @psalm-pure
     */
    private static function extractAllParamNames(array $lines) : array
    {
        $names = [];
        foreach ($lines as $line) {
            $split_by_dollar = explode('$', $line, 2);
            if (count($split_by_dollar) > 1) {
                $split_by_space = explode(' ', $split_by_dollar[1], 2);
                $names[] = $split_by_space[0];
            }
        }
        return $names;
    }
    private static function checkUnexpectedTags(ParsedDocblock $parsed_docblock, FunctionDocblockComment $info, PhpParser\Comment\Doc $comment) : void
    {
        if (isset($parsed_docblock->tags['psalm-import-type'])) {
            $info->unexpected_tags['psalm-import-type']['lines'] = self::tagOffsetsToLines(array_keys($parsed_docblock->tags['psalm-import-type']), $comment);
        }
        if (isset($parsed_docblock->combined_tags['var'])) {
            $info->unexpected_tags['var'] = ['lines' => self::tagOffsetsToLines(array_keys($parsed_docblock->combined_tags['var']), $comment), 'suggested_replacement' => 'param'];
        }
        if (isset($parsed_docblock->tags['psalm-consistent-constructor'])) {
            $info->unexpected_tags['psalm-consistent-constructor'] = ['lines' => self::tagOffsetsToLines(array_keys($parsed_docblock->tags['psalm-consistent-constructor']), $comment), 'suggested_replacement' => 'psalm-consistent-constructor on a class level'];
        }
    }
    /**
     * @param list<int> $offsets
     * @return list<int>
     */
    private static function tagOffsetsToLines(array $offsets, PhpParser\Comment\Doc $comment) : array
    {
        $ret = [];
        foreach ($offsets as $offset) {
            $ret[] = self::docblockLineNumber($comment, $offset);
        }
        return $ret;
    }
    private static function docblockLineNumber(PhpParser\Comment\Doc $comment, int $offset) : int
    {
        return $comment->getStartLine() + substr_count($comment->getText(), "\n", 0, $offset - $comment->getStartFilePos());
    }
}
<?php

namespace Psalm\Internal\PhpVisitor\Reflector;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Aliases;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Exception\FileIncludeException;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\CallAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ConstFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\IncludeAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\SimpleTypeInferer;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Storage\FileStorage;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Type;
use function assert;
use function defined;
use function dirname;
use function explode;
use function implode;
use function in_array;
use function preg_match;
use function strpos;
use function strtolower;
use function substr;
use const DIRECTORY_SEPARATOR;
/**
 * @internal
 */
class ExpressionScanner
{
    public static function scan(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage, Aliases $aliases, PhpParser\Node\Expr $node, ?FunctionLikeStorage $functionlike_storage, ?int $skip_if_descendants) : void
    {
        if ($node instanceof PhpParser\Node\Expr\Include_ && !$skip_if_descendants) {
            self::visitInclude($codebase, $file_storage, $node, $file_scanner->will_analyze);
        } elseif ($node instanceof PhpParser\Node\Expr\Yield_ || $node instanceof PhpParser\Node\Expr\YieldFrom) {
            if ($functionlike_storage) {
                $functionlike_storage->has_yield = \true;
            }
        } elseif ($node instanceof PhpParser\Node\Expr\Cast\Object_) {
            $codebase->scanner->queueClassLikeForScanning('stdClass', \false, \false);
            $file_storage->referenced_classlikes['stdclass'] = 'stdClass';
        } elseif (($node instanceof PhpParser\Node\Expr\New_ || $node instanceof PhpParser\Node\Expr\Instanceof_ || $node instanceof PhpParser\Node\Expr\StaticPropertyFetch || $node instanceof PhpParser\Node\Expr\ClassConstFetch || $node instanceof PhpParser\Node\Expr\StaticCall) && $node->class instanceof PhpParser\Node\Name) {
            $fq_classlike_name = ClassLikeAnalyzer::getFQCLNFromNameObject($node->class, $aliases);
            if (!in_array(strtolower($fq_classlike_name), ['self', 'static', 'parent'], \true)) {
                $codebase->scanner->queueClassLikeForScanning($fq_classlike_name, \false, !$node instanceof PhpParser\Node\Expr\ClassConstFetch || !$node->name instanceof PhpParser\Node\Identifier || strtolower($node->name->name) !== 'class');
                $file_storage->referenced_classlikes[strtolower($fq_classlike_name)] = $fq_classlike_name;
            }
        } elseif ($node instanceof PhpParser\Node\Expr\FuncCall && $node->name instanceof PhpParser\Node\Name) {
            $function_id = implode('\\', $node->name->parts);
            if (InternalCallMapHandler::inCallMap($function_id)) {
                self::registerClassMapFunctionCall($codebase, $file_storage, $file_scanner, $aliases, $function_id, $node, $functionlike_storage, $skip_if_descendants);
            }
        }
    }
    private static function registerClassMapFunctionCall(Codebase $codebase, FileStorage $file_storage, FileScanner $file_scanner, Aliases $aliases, string $function_id, PhpParser\Node\Expr\FuncCall $node, ?FunctionLikeStorage $functionlike_storage, ?int $skip_if_descendants) : void
    {
        $callables = InternalCallMapHandler::getCallablesFromCallMap($function_id);
        if ($callables) {
            foreach ($callables as $callable) {
                assert($callable->params !== null);
                foreach ($callable->params as $function_param) {
                    if ($function_param->type) {
                        /** @psalm-suppress UnusedMethodCall */
                        $function_param->type->queueClassLikesForScanning($codebase, $file_storage);
                    }
                }
                if ($callable->return_type && !$callable->return_type->hasMixed()) {
                    /** @psalm-suppress UnusedMethodCall */
                    $callable->return_type->queueClassLikesForScanning($codebase, $file_storage);
                }
            }
        }
        if ($node->isFirstClassCallable()) {
            return;
        }
        if ($function_id === 'define') {
            $first_arg_value = isset($node->getArgs()[0]) ? $node->getArgs()[0]->value : null;
            $second_arg_value = isset($node->getArgs()[1]) ? $node->getArgs()[1]->value : null;
            if ($first_arg_value && $second_arg_value) {
                $type_provider = new NodeDataProvider();
                $const_name = ConstFetchAnalyzer::getConstName($first_arg_value, $type_provider, $codebase, $aliases);
                if ($const_name !== null) {
                    $const_type = SimpleTypeInferer::infer($codebase, $type_provider, $second_arg_value, $aliases) ?? Type::getMixed();
                    $config = Config::getInstance();
                    if ($functionlike_storage && !$config->hoist_constants) {
                        $functionlike_storage->defined_constants[$const_name] = $const_type;
                    } else {
                        $file_storage->constants[$const_name] = $const_type;
                        $file_storage->declaring_constants[$const_name] = $file_storage->file_path;
                    }
                    if (($codebase->register_stub_files || $codebase->register_autoload_files) && (!defined($const_name) || $const_type->isMixed())) {
                        $codebase->addGlobalConstantType($const_name, $const_type);
                    }
                }
            }
        }
        $mapping_function_ids = [];
        if ($function_id === 'array_map' && isset($node->getArgs()[0]) || $function_id === 'array_filter' && isset($node->getArgs()[1])) {
            $node_arg_value = $function_id === 'array_map' ? $node->getArgs()[0]->value : $node->getArgs()[1]->value;
            if ($node_arg_value instanceof PhpParser\Node\Scalar\String_ || $node_arg_value instanceof PhpParser\Node\Expr\Array_ || $node_arg_value instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
                $mapping_function_ids = CallAnalyzer::getFunctionIdsFromCallableArg($file_scanner, $node_arg_value);
            }
            foreach ($mapping_function_ids as $potential_method_id) {
                if (strpos($potential_method_id, '::') === \false) {
                    continue;
                }
                [$callable_fqcln] = explode('::', $potential_method_id);
                if (!in_array(strtolower($callable_fqcln), ['self', 'parent', 'static'], \true)) {
                    $codebase->scanner->queueClassLikeForScanning($callable_fqcln);
                }
            }
        }
        if ($function_id === 'func_get_arg' || $function_id === 'func_get_args' || $function_id === 'func_num_args') {
            if ($functionlike_storage) {
                $functionlike_storage->variadic = \true;
            }
        }
        if ($function_id === 'is_a' || $function_id === 'is_subclass_of') {
            $second_arg = $node->getArgs()[1]->value ?? null;
            if ($second_arg instanceof PhpParser\Node\Scalar\String_) {
                $codebase->scanner->queueClassLikeForScanning($second_arg->value);
            }
        }
        if ($function_id === 'class_alias' && !$skip_if_descendants) {
            $first_arg = $node->getArgs()[0]->value ?? null;
            $second_arg = $node->getArgs()[1]->value ?? null;
            if ($first_arg instanceof PhpParser\Node\Scalar\String_) {
                $first_arg_value = $first_arg->value;
            } elseif ($first_arg instanceof PhpParser\Node\Expr\ClassConstFetch && $first_arg->class instanceof PhpParser\Node\Name && $first_arg->name instanceof PhpParser\Node\Identifier && strtolower($first_arg->name->name) === 'class') {
                /** @var string */
                $first_arg_value = $first_arg->class->getAttribute('resolvedName');
            } else {
                $first_arg_value = null;
            }
            if ($second_arg instanceof PhpParser\Node\Scalar\String_) {
                $second_arg_value = $second_arg->value;
            } elseif ($second_arg instanceof PhpParser\Node\Expr\ClassConstFetch && $second_arg->class instanceof PhpParser\Node\Name && $second_arg->name instanceof PhpParser\Node\Identifier && strtolower($second_arg->name->name) === 'class') {
                /** @var string */
                $second_arg_value = $second_arg->class->getAttribute('resolvedName');
            } else {
                $second_arg_value = null;
            }
            if ($first_arg_value !== null && $second_arg_value !== null) {
                if ($first_arg_value[0] === '\\') {
                    $first_arg_value = substr($first_arg_value, 1);
                }
                if ($second_arg_value[0] === '\\') {
                    $second_arg_value = substr($second_arg_value, 1);
                }
                $codebase->classlikes->addClassAlias($first_arg_value, $second_arg_value);
                $file_storage->classlike_aliases[$second_arg_value] = $first_arg_value;
            }
        }
    }
    public static function visitInclude(Codebase $codebase, FileStorage $file_storage, PhpParser\Node\Expr\Include_ $stmt, bool $scan_deep) : void
    {
        $config = Config::getInstance();
        if (!$config->allow_includes) {
            throw new FileIncludeException('File includes are not allowed per your Psalm config - check the allowFileIncludes flag.');
        }
        if ($stmt->expr instanceof PhpParser\Node\Scalar\String_) {
            $path_to_file = $stmt->expr->value;
            // attempts to resolve using get_include_path dirs
            $include_path = IncludeAnalyzer::resolveIncludePath($path_to_file, dirname($file_storage->file_path));
            $path_to_file = $include_path ?: $path_to_file;
            if (DIRECTORY_SEPARATOR === '/') {
                $is_path_relative = $path_to_file[0] !== DIRECTORY_SEPARATOR;
            } else {
                $is_path_relative = !preg_match('~^[A-Z]:\\\\~i', $path_to_file);
            }
            if ($is_path_relative) {
                $path_to_file = $config->base_dir . DIRECTORY_SEPARATOR . $path_to_file;
            }
        } else {
            $path_to_file = IncludeAnalyzer::getPathTo($stmt->expr, null, null, $file_storage->file_path, $config);
        }
        if ($path_to_file) {
            $path_to_file = IncludeAnalyzer::normalizeFilePath($path_to_file);
            if ($file_storage->file_path === $path_to_file) {
                return;
            }
            if ($codebase->fileExists($path_to_file)) {
                if ($scan_deep) {
                    $codebase->scanner->addFileToDeepScan($path_to_file);
                } else {
                    $codebase->scanner->addFileToShallowScan($path_to_file);
                }
                $file_storage->required_file_paths[strtolower($path_to_file)] = $path_to_file;
                return;
            }
        }
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
/**
 * Visitor cloning all nodes and linking to the original nodes using an attribute.
 *
 * This visitor is required to perform format-preserving pretty prints.
 *
 * @internal
 */
class CloningVisitor extends NodeVisitorAbstract
{
    public function enterNode(Node $node) : Node
    {
        $node = clone $node;
        if (($cs = $node->getComments()) !== []) {
            $comments = [];
            foreach ($cs as $i => $comment) {
                $comments[$i] = clone $comment;
            }
            $node->setAttribute('comments', $comments);
        }
        return $node;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler\Collecting;
use _HumbugBox1cb33d1f20f1\PhpParser\Parser;
use function count;
use function preg_match_all;
use function preg_replace;
use function reset;
use function str_repeat;
use function strlen;
use function strpos;
use function strrpos;
use function substr;
use function substr_count;
use function substr_replace;
use function token_get_all;
use const PREG_OFFSET_CAPTURE;
use const PREG_SET_ORDER;
/**
 * Given a list of file diffs, this scans an AST to find the sections it can replace, and parses
 * just those methods.
 *
 * @internal
 */
class PartialParserVisitor extends PhpParser\NodeVisitorAbstract
{
    /** @var array<int, array{0: int, 1: int, 2: int, 3: int, 4: int, 5: string}> */
    private array $offset_map;
    private bool $must_rescan = \false;
    private int $non_method_changes;
    private string $a_file_contents;
    private string $b_file_contents;
    private int $a_file_contents_length;
    private Parser $parser;
    private Collecting $error_handler;
    /** @param array<int, array{0: int, 1: int, 2: int, 3: int, 4: int, 5: string}> $offset_map */
    public function __construct(Parser $parser, Collecting $error_handler, array $offset_map, string $a_file_contents, string $b_file_contents)
    {
        $this->parser = $parser;
        $this->error_handler = $error_handler;
        $this->offset_map = $offset_map;
        $this->a_file_contents = $a_file_contents;
        $this->a_file_contents_length = strlen($a_file_contents);
        $this->b_file_contents = $b_file_contents;
        $this->non_method_changes = count($offset_map);
    }
    /**
     * @return null|int|PhpParser\Node
     */
    public function enterNode(PhpParser\Node $node, bool &$traverseChildren = \true)
    {
        /** @var array{startFilePos: int, endFilePos: int, startLine: int} */
        $attrs = $node->getAttributes();
        if ($cs = $node->getComments()) {
            $stmt_start_pos = $cs[0]->getStartFilePos();
        } else {
            $stmt_start_pos = $attrs['startFilePos'];
        }
        $stmt_end_pos = $attrs['endFilePos'];
        $start_offset = 0;
        $end_offset = 0;
        $line_offset = 0;
        foreach ($this->offset_map as [$a_s, $a_e, $b_s, $b_e, $line_diff]) {
            if ($a_s > $stmt_end_pos) {
                break;
            }
            $end_offset = $b_e - $a_e;
            if ($a_s < $stmt_start_pos) {
                $start_offset = $b_s - $a_s;
            }
            if ($a_e < $stmt_start_pos) {
                $start_offset = $end_offset;
                $line_offset = $line_diff;
                continue;
            }
            if ($node instanceof PhpParser\Node\Stmt\ClassMethod || $node instanceof PhpParser\Node\Stmt\Namespace_ || $node instanceof PhpParser\Node\Stmt\ClassLike) {
                if ($node instanceof PhpParser\Node\Stmt\ClassMethod) {
                    if ($a_s >= $stmt_start_pos && $a_e <= $stmt_end_pos) {
                        foreach ($this->offset_map as [$a_s2, $a_e2, $b_s2, $b_e2]) {
                            if ($a_s2 > $stmt_end_pos) {
                                break;
                            }
                            // we have a diff that goes outside the bounds that we care about
                            if ($a_e2 > $stmt_end_pos) {
                                $this->must_rescan = \true;
                                return PhpParser\NodeTraverser::STOP_TRAVERSAL;
                            }
                            $end_offset = $b_e2 - $a_e2;
                            if ($a_s2 < $stmt_start_pos) {
                                $start_offset = $b_s2 - $a_s2;
                            }
                            if ($a_e2 < $stmt_start_pos) {
                                $start_offset = $end_offset;
                                $line_offset = $line_diff;
                                continue;
                            }
                            if ($a_s2 >= $stmt_start_pos && $a_e2 <= $stmt_end_pos) {
                                --$this->non_method_changes;
                            }
                        }
                        $stmt_start_pos += $start_offset;
                        $stmt_end_pos += $end_offset;
                        $current_line = substr_count(substr($this->b_file_contents, 0, $stmt_start_pos), "\n");
                        $method_contents = substr($this->b_file_contents, $stmt_start_pos, $stmt_end_pos - $stmt_start_pos + 1);
                        if (!$method_contents) {
                            $this->must_rescan = \true;
                            return PhpParser\NodeTraverser::STOP_TRAVERSAL;
                        }
                        $error_handler = new Collecting();
                        $fake_class = '<?php class _ {' . $method_contents . '}';
                        $extra_characters = [];
                        // To avoid a parser error during completion we replace
                        //
                        // Foo::
                        // if (...) {}
                        //
                        // with
                        //
                        // Foo::;
                        // if (...) {}
                        //
                        // When we insert the extra semicolon we have to keep track of the places
                        // we inserted it, and then shift the AST node offsets accordingly after parsing
                        // is complete.
                        //
                        // If anyone's unlucky enough to have a static method named "if" with a newline
                        // before the method name e.g.
                        //
                        // Foo::
                        // if(...);
                        //
                        // This transformation will break that.
                        preg_match_all('/(->|::)(\\n\\s*(if|list)\\s*\\()/', $fake_class, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
                        foreach ($matches as $match) {
                            $fake_class = substr_replace($fake_class, $match[1][0] . ';' . $match[2][0], $match[0][1], strlen($match[0][0]));
                            $extra_characters[] = $match[2][1];
                        }
                        $replacement_stmts = $this->parser->parse($fake_class, $error_handler) ?: [];
                        if (!$replacement_stmts || !$replacement_stmts[0] instanceof PhpParser\Node\Stmt\ClassLike || count($replacement_stmts[0]->stmts) !== 1) {
                            $hacky_class_fix = self::balanceBrackets($fake_class);
                            if ($replacement_stmts && $replacement_stmts[0] instanceof PhpParser\Node\Stmt\ClassLike && count($replacement_stmts[0]->stmts) !== 1) {
                                $this->must_rescan = \true;
                                return PhpParser\NodeTraverser::STOP_TRAVERSAL;
                            }
                            // changes "): {" to ") {"
                            $hacky_class_fix = preg_replace('/(\\)[\\s]*):([\\s]*\\{)/', '$1 $2', $hacky_class_fix);
                            if ($hacky_class_fix !== $fake_class) {
                                $replacement_stmts = $this->parser->parse($hacky_class_fix, $error_handler) ?: [];
                            }
                            if (!$replacement_stmts || !$replacement_stmts[0] instanceof PhpParser\Node\Stmt\ClassLike || count($replacement_stmts[0]->stmts) > 1) {
                                $this->must_rescan = \true;
                                return PhpParser\NodeTraverser::STOP_TRAVERSAL;
                            }
                        }
                        $replacement_stmts = $replacement_stmts[0]->stmts;
                        $extra_offsets = [];
                        foreach ($extra_characters as $extra_offset) {
                            $l = strlen($fake_class);
                            for ($i = $extra_offset; $i < $l; $i++) {
                                if (isset($extra_offsets[$i])) {
                                    $extra_offsets[$i]--;
                                } else {
                                    $extra_offsets[$i] = -1;
                                }
                            }
                        }
                        $renumbering_traverser = new PhpParser\NodeTraverser();
                        $position_shifter = new \Psalm\Internal\PhpVisitor\OffsetShifterVisitor($stmt_start_pos - 15, $current_line, $extra_offsets);
                        $renumbering_traverser->addVisitor($position_shifter);
                        $replacement_stmts = $renumbering_traverser->traverse($replacement_stmts);
                        if ($error_handler->hasErrors()) {
                            foreach ($error_handler->getErrors() as $error) {
                                if ($error->hasColumnInfo()) {
                                    /** @var array{startFilePos: int, endFilePos: int} */
                                    $error_attrs = $error->getAttributes();
                                    $error = new PhpParser\Error($error->getRawMessage(), ['startFilePos' => $stmt_start_pos + $error_attrs['startFilePos'] - 15, 'endFilePos' => $stmt_start_pos + $error_attrs['endFilePos'] - 15, 'startLine' => $error->getStartLine() + $current_line + $line_offset]);
                                }
                                $this->error_handler->handleError($error);
                            }
                        }
                        $error_handler->clearErrors();
                        $traverseChildren = \false;
                        return reset($replacement_stmts);
                    }
                    $this->must_rescan = \true;
                    return PhpParser\NodeTraverser::STOP_TRAVERSAL;
                }
                if ($node->stmts) {
                    /** @var int */
                    $stmt_inner_start_pos = $node->stmts[0]->getAttribute('startFilePos');
                    /** @var int */
                    $stmt_inner_end_pos = $node->stmts[count($node->stmts) - 1]->getAttribute('endFilePos');
                    if ($node instanceof PhpParser\Node\Stmt\ClassLike) {
                        /** @psalm-suppress PossiblyFalseOperand */
                        $stmt_inner_start_pos = strrpos($this->a_file_contents, '{', $stmt_inner_start_pos - $this->a_file_contents_length) + 1;
                        if ($stmt_inner_end_pos < $this->a_file_contents_length) {
                            $stmt_inner_end_pos = strpos($this->a_file_contents, '}', $stmt_inner_end_pos + 1);
                        }
                    }
                    if ($a_s > $stmt_inner_start_pos && $a_e < $stmt_inner_end_pos) {
                        continue;
                    }
                }
            }
            $this->must_rescan = \true;
            return PhpParser\NodeTraverser::STOP_TRAVERSAL;
        }
        if ($start_offset !== 0 || $end_offset !== 0 || $line_offset !== 0) {
            if ($start_offset !== 0) {
                if ($cs) {
                    $new_comments = [];
                    foreach ($cs as $c) {
                        if ($c instanceof PhpParser\Comment\Doc) {
                            $new_comments[] = new PhpParser\Comment\Doc($c->getText(), $c->getStartLine() + $line_offset, $c->getStartFilePos() + $start_offset);
                        } else {
                            $new_comments[] = new PhpParser\Comment($c->getText(), $c->getStartLine() + $line_offset, $c->getStartFilePos() + $start_offset);
                        }
                    }
                    $node->setAttribute('comments', $new_comments);
                    $node->setAttribute('startFilePos', $attrs['startFilePos'] + $start_offset);
                } else {
                    $node->setAttribute('startFilePos', $stmt_start_pos + $start_offset);
                }
            }
            if ($end_offset !== 0) {
                $node->setAttribute('endFilePos', $stmt_end_pos + $end_offset);
            }
            if ($line_offset !== 0) {
                $node->setAttribute('startLine', $attrs['startLine'] + $line_offset);
            }
            return $node;
        }
        return null;
    }
    public function mustRescan() : bool
    {
        return $this->must_rescan || $this->non_method_changes;
    }
    /**
     * @psalm-pure
     */
    private static function balanceBrackets(string $fake_class) : string
    {
        $tokens = token_get_all($fake_class);
        $brace_count = 0;
        foreach ($tokens as $token) {
            if ($token === '{') {
                ++$brace_count;
            } elseif ($token === '}') {
                --$brace_count;
            }
        }
        if ($brace_count > 0) {
            $fake_class .= str_repeat('}', $brace_count);
        }
        return $fake_class;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
use Psalm\Internal\Provider\NodeDataProvider;
/**
 * @internal
 */
class TypeMappingVisitor extends NodeVisitorAbstract
{
    private NodeDataProvider $fake_type_provider;
    private NodeDataProvider $real_type_provider;
    public function __construct(NodeDataProvider $fake_type_provider, NodeDataProvider $real_type_provider)
    {
        $this->fake_type_provider = $fake_type_provider;
        $this->real_type_provider = $real_type_provider;
    }
    /**
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingAnyTypeHint
     */
    public function enterNode(Node $node)
    {
        $origNode = $node;
        /** @psalm-suppress ArgumentTypeCoercion */
        $node_type = $this->fake_type_provider->getType($origNode);
        if ($node_type) {
            /** @psalm-suppress ArgumentTypeCoercion */
            $this->real_type_provider->setType($origNode, $node_type);
        }
        return null;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
use Psalm\Internal\Provider\NodeDataProvider;
/**
 * @internal
 */
class ConditionCloningVisitor extends NodeVisitorAbstract
{
    private NodeDataProvider $type_provider;
    public function __construct(NodeDataProvider $old_type_provider)
    {
        $this->type_provider = $old_type_provider;
    }
    /**
     * @return Node\Expr
     */
    public function enterNode(Node $node) : Node
    {
        /** @var Expr $node */
        $origNode = $node;
        $node = clone $node;
        $node_type = $this->type_provider->getType($origNode);
        if ($node_type) {
            $this->type_provider->setType($node, $node_type);
        }
        return $node;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
/**
 * @internal
 */
class CheckTrivialExprVisitor extends PhpParser\NodeVisitorAbstract
{
    /**
     * @var array<int, PhpParser\Node\Expr>
     */
    protected array $non_trivial_expr = [];
    private function checkNonTrivialExpr(PhpParser\Node\Expr $node) : bool
    {
        if ($node instanceof PhpParser\Node\Expr\ArrayDimFetch || $node instanceof PhpParser\Node\Expr\Closure || $node instanceof PhpParser\Node\Expr\ClosureUse || $node instanceof PhpParser\Node\Expr\Eval_ || $node instanceof PhpParser\Node\Expr\Exit_ || $node instanceof PhpParser\Node\Expr\Include_ || $node instanceof PhpParser\Node\Expr\FuncCall || $node instanceof PhpParser\Node\Expr\MethodCall || $node instanceof PhpParser\Node\Expr\ArrowFunction || $node instanceof PhpParser\Node\Expr\ShellExec || $node instanceof PhpParser\Node\Expr\StaticCall || $node instanceof PhpParser\Node\Expr\Yield_ || $node instanceof PhpParser\Node\Expr\YieldFrom || $node instanceof PhpParser\Node\Expr\New_ || $node instanceof PhpParser\Node\Expr\Cast\String_) {
            if (($node instanceof PhpParser\Node\Expr\FuncCall || $node instanceof PhpParser\Node\Expr\MethodCall || $node instanceof PhpParser\Node\Expr\StaticCall) && $node->getAttribute('pure', \false)) {
                return \false;
            }
            if ($node instanceof PhpParser\Node\Expr\New_ && $node->getAttribute('external_mutation_free', \false)) {
                return \false;
            }
            return \true;
        }
        return \false;
    }
    public function enterNode(PhpParser\Node $node) : ?int
    {
        if ($node instanceof PhpParser\Node\Expr) {
            // Check for Non-Trivial Expression first
            if ($this->checkNonTrivialExpr($node)) {
                $this->non_trivial_expr[] = $node;
                return PhpParser\NodeTraverser::STOP_TRAVERSAL;
            }
            if ($node instanceof PhpParser\Node\Expr\ClassConstFetch || $node instanceof PhpParser\Node\Expr\ConstFetch || $node instanceof PhpParser\Node\Expr\Error || $node instanceof PhpParser\Node\Expr\PropertyFetch || $node instanceof PhpParser\Node\Expr\StaticPropertyFetch) {
                return PhpParser\NodeTraverser::STOP_TRAVERSAL;
            }
        }
        return null;
    }
    /**
     * @return array<int, PhpParser\Node\Expr>
     */
    public function getNonTrivialExpr() : array
    {
        return $this->non_trivial_expr;
    }
}
<?php

// based on PhpParser's builtin one
namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\ErrorHandler;
use _HumbugBox1cb33d1f20f1\PhpParser\NameContext;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\NullableType;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
/**
 * @internal
 */
class SimpleNameResolver extends NodeVisitorAbstract
{
    private NameContext $nameContext;
    private ?int $start_change = null;
    private ?int $end_change = null;
    /**
     * @param ErrorHandler $errorHandler Error handler
     * @param null|array<int, array{0: int, 1: int, 2: int, 3: int, 4: int, 5: string}> $offset_map
     */
    public function __construct(ErrorHandler $errorHandler, ?array $offset_map = null)
    {
        if ($offset_map) {
            foreach ($offset_map as [, , $b_s, $b_e]) {
                if ($this->start_change === null) {
                    $this->start_change = $b_s;
                }
                $this->end_change = $b_e;
            }
        }
        $this->nameContext = new NameContext($errorHandler);
    }
    public function beforeTraverse(array $nodes) : ?array
    {
        $this->nameContext->startNamespace();
        return null;
    }
    public function enterNode(Node $node) : ?int
    {
        if ($node instanceof Stmt\Namespace_) {
            $this->nameContext->startNamespace($node->name);
        } elseif ($node instanceof Stmt\Use_) {
            foreach ($node->uses as $use) {
                $this->addAlias($use, $node->type);
            }
        } elseif ($node instanceof Stmt\GroupUse) {
            foreach ($node->uses as $use) {
                $this->addAlias($use, $node->type, $node->prefix);
            }
        } elseif ($node instanceof Stmt\Class_) {
            if (null !== $node->extends) {
                $node->extends = $this->resolveClassName($node->extends);
            }
            foreach ($node->implements as &$interface) {
                $interface = $this->resolveClassName($interface);
            }
            unset($interface);
            $this->resolveAttrGroups($node);
            if (null !== $node->name) {
                $this->addNamespacedName($node);
            }
        }
        if ($node instanceof Stmt\ClassMethod && $this->start_change && $this->end_change) {
            /** @var array{startFilePos: int, endFilePos: int} */
            $attrs = $node->getAttributes();
            if ($cs = $node->getComments()) {
                $attrs['startFilePos'] = $cs[0]->getStartFilePos();
            }
            if ($attrs['endFilePos'] < $this->start_change || $attrs['startFilePos'] > $this->end_change) {
                return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
            }
        }
        if ($node instanceof Stmt\ClassMethod || $node instanceof Expr\Closure) {
            $this->resolveSignature($node);
        } elseif ($node instanceof Expr\StaticCall || $node instanceof Expr\StaticPropertyFetch || $node instanceof Expr\ClassConstFetch || $node instanceof Expr\New_ || $node instanceof Expr\Instanceof_) {
            if ($node->class instanceof Name) {
                $node->class = $this->resolveClassName($node->class);
            }
        } elseif ($node instanceof Stmt\Catch_) {
            foreach ($node->types as &$type) {
                $type = $this->resolveClassName($type);
            }
            unset($type);
        } elseif ($node instanceof Expr\FuncCall) {
            if ($node->name instanceof Name) {
                $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION);
            }
        } elseif ($node instanceof Expr\ConstFetch) {
            $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT);
        } elseif ($node instanceof Stmt\Trait_) {
            $this->resolveTrait($node);
        } elseif ($node instanceof Stmt\TraitUse) {
            foreach ($node->traits as &$trait) {
                $trait = $this->resolveClassName($trait);
            }
            unset($trait);
            foreach ($node->adaptations as $adaptation) {
                if (null !== $adaptation->trait) {
                    $adaptation->trait = $this->resolveClassName($adaptation->trait);
                }
                if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) {
                    foreach ($adaptation->insteadof as &$insteadof) {
                        $insteadof = $this->resolveClassName($insteadof);
                    }
                    unset($insteadof);
                }
            }
        }
        return null;
    }
    private function addAlias(Stmt\UseUse $use, int $type, ?Name $prefix = null) : void
    {
        // Add prefix for group uses
        /** @var Name $name */
        $name = $prefix ? Name::concat($prefix, $use->name) : $use->name;
        // Type is determined either by individual element or whole use declaration
        $type |= $use->type;
        $this->nameContext->addAlias($name, (string) $use->getAlias(), $type, $use->getAttributes());
    }
    /**
     * @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure $node
     */
    private function resolveSignature(PhpParser\NodeAbstract $node) : void
    {
        foreach ($node->params as $param) {
            $param->type = $this->resolveType($param->type);
        }
        $node->returnType = $this->resolveType($node->returnType);
    }
    /**
     * @template T of Node|null
     * @param T $node
     * @return ($node is NullableType ? NullableType : ($node is Name ? Name : T))
     */
    private function resolveType(?Node $node) : ?Node
    {
        if ($node instanceof NullableType) {
            $node->type = $this->resolveType($node->type);
            return $node;
        }
        if ($node instanceof Name) {
            return $this->resolveClassName($node);
        }
        return $node;
    }
    /**
     * Resolve name, according to name resolver options.
     *
     * CAVE: Attribute values are of type `string`, this is
     * different to PhpParser's `NameResolver` using objects.
     *
     * @param Name $name Function or constant name to resolve
     * @param Stmt\Use_::TYPE_*  $type One of Stmt\Use_::TYPE_*
     * @return Name Resolved name, or original name with attribute
     */
    protected function resolveName(Name $name, int $type) : Name
    {
        $resolvedName = $this->nameContext->getResolvedName($name, $type);
        if (null !== $resolvedName) {
            $name->setAttribute('resolvedName', $resolvedName->toString());
        } else {
            $namespaceName = Name\FullyQualified::concat($this->nameContext->getNamespace(), $name, $name->getAttributes());
            if ($namespaceName instanceof Name) {
                $name->setAttribute('namespacedName', $namespaceName->toString());
            }
        }
        return $name;
    }
    protected function resolveClassName(Name $name) : Name
    {
        return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL);
    }
    protected function addNamespacedName(Stmt\Class_ $node) : void
    {
        $node->setAttribute('namespacedName', Name::concat($this->nameContext->getNamespace(), (string) $node->name));
    }
    protected function resolveAttrGroups(Stmt\Class_ $node) : void
    {
        foreach ($node->attrGroups as $attrGroup) {
            foreach ($attrGroup->attrs as $attr) {
                $attr->name = $this->resolveClassName($attr->name);
            }
        }
    }
    protected function resolveTrait(Stmt\Trait_ $node) : void
    {
        $resolvedName = Name::concat($this->nameContext->getNamespace(), (string) $node->name);
        if (null !== $resolvedName) {
            $node->setAttribute('resolvedName', $resolvedName->toString());
        }
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\Provider\NodeDataProvider;
/**
 * @internal
 */
class NodeCleanerVisitor extends PhpParser\NodeVisitorAbstract
{
    private NodeDataProvider $type_provider;
    public function __construct(NodeDataProvider $type_provider)
    {
        $this->type_provider = $type_provider;
    }
    public function enterNode(PhpParser\Node $node) : ?int
    {
        if ($node instanceof PhpParser\Node\Expr) {
            $this->type_provider->clearNodeOfTypeAndAssertions($node);
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Exception\CodeException;
use Psalm\Exception\DocblockParseException;
use Psalm\Exception\TypeParseTreeException;
use Psalm\FileSource;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\SimpleTypeInferer;
use Psalm\Internal\EventDispatcher;
use Psalm\Internal\PhpVisitor\Reflector\ClassLikeNodeScanner;
use Psalm\Internal\PhpVisitor\Reflector\ExpressionResolver;
use Psalm\Internal\PhpVisitor\Reflector\ExpressionScanner;
use Psalm\Internal\PhpVisitor\Reflector\FunctionLikeNodeScanner;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Internal\Scanner\PhpStormMetaScanner;
use Psalm\Internal\Type\TypeAlias;
use Psalm\Internal\Type\TypeParser;
use Psalm\Issue\InvalidDocblock;
use Psalm\Issue\TaintedInput;
use Psalm\Plugin\EventHandler\Event\AfterClassLikeVisitEvent;
use Psalm\Storage\FileStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use UnexpectedValueException;
use function array_merge;
use function array_pop;
use function end;
use function explode;
use function get_class;
use function implode;
use function in_array;
use function is_string;
use function reset;
use function spl_object_id;
use function strpos;
use function strtolower;
use const PHP_VERSION_ID;
/**
 * @internal
 */
class ReflectorVisitor extends PhpParser\NodeVisitorAbstract implements FileSource
{
    private Aliases $aliases;
    private FileScanner $file_scanner;
    private Codebase $codebase;
    private string $file_path;
    private bool $scan_deep;
    private FileStorage $file_storage;
    /**
     * @var array<FunctionLikeNodeScanner>
     */
    private array $functionlike_node_scanners = [];
    /**
     * @var array<ClassLikeNodeScanner>
     */
    private array $classlike_node_scanners = [];
    private ?Name $namespace_name = null;
    private ?Expr $exists_cond_expr = null;
    private ?int $skip_if_descendants = null;
    /**
     * @var array<string, TypeAlias>
     */
    private array $type_aliases = [];
    /**
     * @var array<int, bool>
     */
    private array $bad_classes = [];
    private EventDispatcher $eventDispatcher;
    public function __construct(Codebase $codebase, FileScanner $file_scanner, FileStorage $file_storage)
    {
        $this->codebase = $codebase;
        $this->file_scanner = $file_scanner;
        $this->file_path = $file_scanner->file_path;
        $this->scan_deep = $file_scanner->will_analyze;
        $this->file_storage = $file_storage;
        $this->aliases = $this->file_storage->aliases = new Aliases();
        $this->eventDispatcher = $this->codebase->config->eventDispatcher;
    }
    public function enterNode(PhpParser\Node $node) : ?int
    {
        foreach ($node->getComments() as $comment) {
            if ($comment instanceof PhpParser\Comment\Doc && !$node instanceof PhpParser\Node\Stmt\ClassLike) {
                try {
                    $type_aliases = ClassLikeNodeScanner::getTypeAliasesFromComment($comment, $this->aliases, $this->type_aliases, null);
                    foreach ($type_aliases as $type_alias) {
                        // finds issues, if there are any
                        TypeParser::parseTokens($type_alias->replacement_tokens);
                    }
                    $this->type_aliases += $type_aliases;
                } catch (DocblockParseException|TypeParseTreeException $e) {
                    $this->file_storage->docblock_issues[] = new InvalidDocblock($e->getMessage(), new CodeLocation($this->file_scanner, $node, null, \true));
                }
            }
        }
        if ($node instanceof PhpParser\Node\Stmt\Namespace_) {
            $this->handleNamespace($node);
        } elseif ($node instanceof PhpParser\Node\Stmt\Use_) {
            $this->handleUse($node);
        } elseif ($node instanceof PhpParser\Node\Stmt\GroupUse) {
            $this->handleGroupUse($node);
        } elseif ($node instanceof PhpParser\Node\Stmt\ClassLike) {
            if ($this->skip_if_descendants) {
                return null;
            }
            $classlike_node_scanner = new ClassLikeNodeScanner($this->codebase, $this->file_storage, $this->file_scanner, $this->aliases, $this->namespace_name);
            $this->classlike_node_scanners[] = $classlike_node_scanner;
            if ($classlike_node_scanner->start($node) === \false) {
                $this->bad_classes[spl_object_id($node)] = \true;
                return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
            }
            $this->type_aliases = array_merge($this->type_aliases, $classlike_node_scanner->type_aliases);
        } elseif ($node instanceof PhpParser\Node\Stmt\TryCatch) {
            foreach ($node->catches as $catch) {
                foreach ($catch->types as $catch_type) {
                    $catch_fqcln = ClassLikeAnalyzer::getFQCLNFromNameObject($catch_type, $this->aliases);
                    if (!in_array(strtolower($catch_fqcln), ['self', 'static', 'parent'], \true)) {
                        $this->codebase->scanner->queueClassLikeForScanning($catch_fqcln);
                        $this->file_storage->referenced_classlikes[strtolower($catch_fqcln)] = $catch_fqcln;
                    }
                }
            }
        } elseif ($node instanceof PhpParser\Node\FunctionLike) {
            if ($node instanceof PhpParser\Node\Stmt\Function_ || $node instanceof PhpParser\Node\Stmt\ClassMethod) {
                if ($this->skip_if_descendants) {
                    return null;
                }
            }
            $classlike_storage = null;
            if ($this->classlike_node_scanners) {
                $classlike_node_scanner = end($this->classlike_node_scanners);
                $classlike_storage = $classlike_node_scanner->storage;
            }
            $functionlike_types = [];
            foreach ($this->functionlike_node_scanners as $functionlike_node_scanner) {
                $functionlike_storage = $functionlike_node_scanner->storage;
                $functionlike_types += $functionlike_storage->template_types ?? [];
            }
            $functionlike_node_scanner = new FunctionLikeNodeScanner($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $this->type_aliases, $classlike_storage, $functionlike_types);
            $functionlike_node_scanner->start($node);
            $this->functionlike_node_scanners[] = $functionlike_node_scanner;
            if ($classlike_storage && $this->codebase->analysis_php_version_id >= 80000 && $node instanceof PhpParser\Node\Stmt\ClassMethod && strtolower($node->name->name) === '__tostring') {
                if ($classlike_storage->is_interface) {
                    $classlike_storage->parent_interfaces['stringable'] = 'Stringable';
                } else {
                    $classlike_storage->class_implements['stringable'] = 'Stringable';
                }
                if (PHP_VERSION_ID >= 80000) {
                    $this->codebase->scanner->queueClassLikeForScanning('Stringable');
                }
            }
            if (!$this->scan_deep) {
                return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\Global_) {
            $functionlike_node_scanner = end($this->functionlike_node_scanners);
            if ($functionlike_node_scanner && $functionlike_node_scanner->storage) {
                foreach ($node->vars as $var) {
                    if ($var instanceof PhpParser\Node\Expr\Variable) {
                        if (is_string($var->name) && $var->name !== 'argv' && $var->name !== 'argc') {
                            $var_id = '$' . $var->name;
                            $functionlike_node_scanner->storage->global_variables[$var_id] = \true;
                        }
                    }
                }
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\TraitUse) {
            if ($this->skip_if_descendants) {
                return null;
            }
            if (!$this->classlike_node_scanners) {
                throw new LogicException('$this->classlike_node_scanners should not be empty');
            }
            $classlike_node_scanner = end($this->classlike_node_scanners);
            $classlike_node_scanner->handleTraitUse($node);
        } elseif ($node instanceof PhpParser\Node\Stmt\Const_) {
            foreach ($node->consts as $const) {
                $const_type = SimpleTypeInferer::infer($this->codebase, new NodeDataProvider(), $const->value, $this->aliases) ?? Type::getMixed();
                $fq_const_name = Type::getFQCLNFromString($const->name->name, $this->aliases);
                if ($this->codebase->register_stub_files || $this->codebase->register_autoload_files) {
                    $this->codebase->addGlobalConstantType($fq_const_name, $const_type);
                }
                $this->file_storage->constants[$fq_const_name] = $const_type;
                $this->file_storage->declaring_constants[$fq_const_name] = $this->file_path;
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\If_ && !$this->skip_if_descendants) {
            if (!$this->functionlike_node_scanners) {
                $this->exists_cond_expr = $node->cond;
                if (ExpressionResolver::enterConditional($this->codebase, $this->file_path, $this->exists_cond_expr) === \false) {
                    // the else node should terminate the agreement
                    $this->skip_if_descendants = $node->else ? $node->else->getLine() : $node->getLine();
                }
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\Else_) {
            if ($this->skip_if_descendants === $node->getLine()) {
                $this->skip_if_descendants = null;
                $this->exists_cond_expr = null;
            } elseif (!$this->skip_if_descendants) {
                if ($this->exists_cond_expr && ExpressionResolver::enterConditional($this->codebase, $this->file_path, $this->exists_cond_expr) === \true) {
                    $this->skip_if_descendants = $node->getLine();
                }
            }
        } elseif ($node instanceof Expr) {
            $functionlike_storage = null;
            if ($this->functionlike_node_scanners) {
                $functionlike_node_scanner = end($this->functionlike_node_scanners);
                $functionlike_storage = $functionlike_node_scanner->storage;
            }
            ExpressionScanner::scan($this->codebase, $this->file_scanner, $this->file_storage, $this->aliases, $node, $functionlike_storage, $this->skip_if_descendants);
        }
        if ($doc_comment = $node->getDocComment()) {
            $var_comments = [];
            $template_types = [];
            if ($this->classlike_node_scanners) {
                $classlike_node_scanner = end($this->classlike_node_scanners);
                $classlike_storage = $classlike_node_scanner->storage;
                $template_types = $classlike_storage->template_types ?? [];
            }
            foreach ($this->functionlike_node_scanners as $functionlike_node_scanner) {
                $functionlike_storage = $functionlike_node_scanner->storage;
                $template_types += $functionlike_storage->template_types ?? [];
            }
            try {
                $var_comments = CommentAnalyzer::getTypeFromComment($doc_comment, $this->file_scanner, $this->aliases, $template_types, $this->type_aliases);
            } catch (DocblockParseException $e) {
                // do nothing
            }
            foreach ($var_comments as $var_comment) {
                if (!$var_comment->type) {
                    continue;
                }
                $var_type = $var_comment->type;
                /** @psalm-suppress UnusedMethodCall */
                $var_type->queueClassLikesForScanning($this->codebase, $this->file_storage);
            }
        }
        if ($node instanceof PhpParser\Node\Expr\Assign || $node instanceof PhpParser\Node\Expr\AssignOp || $node instanceof PhpParser\Node\Expr\AssignRef) {
            if ($node->var instanceof PhpParser\Node\Expr\PropertyFetch && $node->var->var instanceof PhpParser\Node\Expr\Variable && $node->var->var->name === 'this' && $node->var->name instanceof PhpParser\Node\Identifier) {
                if ($this->functionlike_node_scanners) {
                    $functionlike_node_scanner = end($this->functionlike_node_scanners);
                    $functionlike_storage = $functionlike_node_scanner->storage;
                    if ($functionlike_storage instanceof MethodStorage) {
                        $functionlike_storage->this_property_mutations[$node->var->name->name] = \true;
                    }
                }
            }
        }
        return null;
    }
    private function handleNamespace(PhpParser\Node\Stmt\Namespace_ $node) : void
    {
        $this->file_storage->aliases = $this->aliases;
        $this->namespace_name = $node->name;
        $this->aliases = new Aliases($node->name ? implode('\\', $node->name->parts) : '', $this->aliases->uses, $this->aliases->functions, $this->aliases->constants, $this->aliases->uses_flipped, $this->aliases->functions_flipped, $this->aliases->constants_flipped);
        $this->file_storage->namespace_aliases[(int) $node->getAttribute('startFilePos')] = $this->aliases;
        if ($node->stmts) {
            $this->aliases->namespace_first_stmt_start = (int) $node->stmts[0]->getAttribute('startFilePos');
        }
    }
    private function handleUse(PhpParser\Node\Stmt\Use_ $node) : void
    {
        foreach ($node->uses as $use) {
            $use_path = implode('\\', $use->name->parts);
            $use_alias = $use->alias->name ?? $use->name->getLast();
            switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $node->type) {
                case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
                    $this->aliases->functions[strtolower($use_alias)] = $use_path;
                    $this->aliases->functions_flipped[strtolower($use_path)] = $use_alias;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_CONSTANT:
                    $this->aliases->constants[$use_alias] = $use_path;
                    $this->aliases->constants_flipped[$use_path] = $use_alias;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_NORMAL:
                    $this->aliases->uses[strtolower($use_alias)] = $use_path;
                    $this->aliases->uses_flipped[strtolower($use_path)] = $use_alias;
                    break;
            }
        }
        if (!$this->aliases->uses_start) {
            $this->aliases->uses_start = (int) $node->getAttribute('startFilePos');
        }
        $this->aliases->uses_end = (int) $node->getAttribute('endFilePos') + 1;
    }
    private function handleGroupUse(PhpParser\Node\Stmt\GroupUse $node) : void
    {
        $use_prefix = implode('\\', $node->prefix->parts);
        foreach ($node->uses as $use) {
            $use_path = $use_prefix . '\\' . implode('\\', $use->name->parts);
            $use_alias = $use->alias->name ?? $use->name->getLast();
            switch ($use->type !== PhpParser\Node\Stmt\Use_::TYPE_UNKNOWN ? $use->type : $node->type) {
                case PhpParser\Node\Stmt\Use_::TYPE_FUNCTION:
                    $this->aliases->functions[strtolower($use_alias)] = $use_path;
                    $this->aliases->functions_flipped[strtolower($use_path)] = $use_alias;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_CONSTANT:
                    $this->aliases->constants[$use_alias] = $use_path;
                    $this->aliases->constants_flipped[$use_path] = $use_alias;
                    break;
                case PhpParser\Node\Stmt\Use_::TYPE_NORMAL:
                    $this->aliases->uses[strtolower($use_alias)] = $use_path;
                    $this->aliases->uses_flipped[strtolower($use_path)] = $use_alias;
                    break;
            }
        }
        if (!$this->aliases->uses_start) {
            $this->aliases->uses_start = (int) $node->getAttribute('startFilePos');
        }
        $this->aliases->uses_end = (int) $node->getAttribute('endFilePos') + 1;
    }
    /**
     * @return null
     */
    public function leaveNode(PhpParser\Node $node)
    {
        if ($node instanceof PhpParser\Node\Stmt\Namespace_) {
            if (!$this->file_storage->aliases) {
                throw new UnexpectedValueException('File storage liases should not be null');
            }
            $this->aliases = $this->file_storage->aliases;
            if ($this->codebase->register_stub_files && $node->name && $node->name->parts === ['PHPSTORM_META']) {
                foreach ($node->stmts as $meta_stmt) {
                    if ($meta_stmt instanceof PhpParser\Node\Stmt\Expression && $meta_stmt->expr instanceof PhpParser\Node\Expr\FuncCall && $meta_stmt->expr->name instanceof Name && $meta_stmt->expr->name->parts === ['override']) {
                        PhpStormMetaScanner::handleOverride($meta_stmt->expr->getArgs(), $this->codebase);
                    }
                }
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\ClassLike) {
            if ($this->skip_if_descendants) {
                return null;
            }
            if (isset($this->bad_classes[spl_object_id($node)])) {
                return null;
            }
            if (!$this->classlike_node_scanners) {
                throw new UnexpectedValueException('$this->classlike_node_scanners cannot be empty');
            }
            $classlike_node_scanner = array_pop($this->classlike_node_scanners);
            $classlike_storage = $classlike_node_scanner->finish($node);
            if ($classlike_storage->has_visitor_issues) {
                $this->file_storage->has_visitor_issues = \true;
            }
            $event = new AfterClassLikeVisitEvent($node, $classlike_storage, $this, $this->codebase, []);
            $this->eventDispatcher->dispatchAfterClassLikeVisit($event);
            if (!$this->file_storage->has_visitor_issues) {
                $this->codebase->cacheClassLikeStorage($classlike_storage, $this->file_path);
            }
        } elseif ($node instanceof PhpParser\Node\FunctionLike) {
            if ($this->skip_if_descendants) {
                return null;
            }
            if (!$this->functionlike_node_scanners) {
                if ($this->file_storage->has_visitor_issues) {
                    return null;
                }
                throw new UnexpectedValueException('There should be function storages for line ' . $this->file_path . ':' . $node->getLine());
            }
            $functionlike_node_scanner = array_pop($this->functionlike_node_scanners);
            if ($functionlike_node_scanner->storage) {
                foreach ($functionlike_node_scanner->storage->docblock_issues as $docblock_issue) {
                    if (strpos($docblock_issue->code_location->file_path, 'CoreGenericFunctions.phpstub') || strpos($docblock_issue->code_location->file_path, 'CoreGenericClasses.phpstub') || strpos($this->file_path, 'CoreGenericIterators.phpstub')) {
                        $e = reset($functionlike_node_scanner->storage->docblock_issues);
                        $fqcn_parts = explode('\\', get_class($e));
                        $issue_type = array_pop($fqcn_parts);
                        $message = $e instanceof TaintedInput ? $e->getJourneyMessage() : $e->message;
                        throw new CodeException('Error with core stub file docblocks: ' . $issue_type . ' - ' . $e->getShortLocationWithPrevious() . ':' . $e->code_location->getColumn() . ' - ' . $message);
                    }
                }
                if ($functionlike_node_scanner->storage->has_visitor_issues) {
                    $this->file_storage->has_visitor_issues = \true;
                }
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\If_ && $node->getLine() === $this->skip_if_descendants) {
            $this->exists_cond_expr = null;
            $this->skip_if_descendants = null;
        } elseif ($node instanceof PhpParser\Node\Stmt\Else_ && $node->getLine() === $this->skip_if_descendants) {
            $this->exists_cond_expr = null;
            $this->skip_if_descendants = null;
        }
        return null;
    }
    /** @psalm-mutation-free */
    public function getFilePath() : string
    {
        return $this->file_path;
    }
    /** @psalm-mutation-free */
    public function getFileName() : string
    {
        return $this->file_scanner->getFileName();
    }
    /** @psalm-mutation-free */
    public function getRootFilePath() : string
    {
        return $this->file_scanner->getRootFilePath();
    }
    /** @psalm-mutation-free */
    public function getRootFileName() : string
    {
        return $this->file_scanner->getRootFileName();
    }
    /** @psalm-mutation-free */
    public function getAliases() : Aliases
    {
        return $this->aliases;
    }
    /**
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingAnyTypeHint
     */
    public function afterTraverse(array $nodes)
    {
        $this->file_storage->type_aliases = $this->type_aliases;
        return null;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\Analyzer\Statements\Expression\ExpressionIdentifier;
/**
 * @internal
 *
 * This produces a graph of probably assignments inside a loop
 *
 * With this map we can calculate how many times the loop analysis must
 * be run before all variables have the correct types
 */
class AssignmentMapVisitor extends PhpParser\NodeVisitorAbstract
{
    /**
     * @var array<string, array<string, bool>>
     */
    protected array $assignment_map = [];
    protected ?string $this_class_name = null;
    public function __construct(?string $this_class_name)
    {
        $this->this_class_name = $this_class_name;
    }
    public function enterNode(PhpParser\Node $node) : ?int
    {
        if ($node instanceof PhpParser\Node\Expr\Assign) {
            $right_var_id = ExpressionIdentifier::getRootVarId($node->expr, $this->this_class_name);
            if ($node->var instanceof PhpParser\Node\Expr\List_ || $node->var instanceof PhpParser\Node\Expr\Array_) {
                foreach ($node->var->items as $assign_item) {
                    if ($assign_item) {
                        $left_var_id = ExpressionIdentifier::getRootVarId($assign_item->value, $this->this_class_name);
                        if ($left_var_id) {
                            $this->assignment_map[$left_var_id][$right_var_id ?: 'isset'] = \true;
                        }
                    }
                }
            } else {
                $left_var_id = ExpressionIdentifier::getRootVarId($node->var, $this->this_class_name);
                if ($left_var_id) {
                    $this->assignment_map[$left_var_id][$right_var_id ?: 'isset'] = \true;
                }
            }
            return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
        }
        if ($node instanceof PhpParser\Node\Expr\PostInc || $node instanceof PhpParser\Node\Expr\PostDec || $node instanceof PhpParser\Node\Expr\PreInc || $node instanceof PhpParser\Node\Expr\PreDec || $node instanceof PhpParser\Node\Expr\AssignOp) {
            $var_id = ExpressionIdentifier::getRootVarId($node->var, $this->this_class_name);
            if ($var_id) {
                $this->assignment_map[$var_id][$var_id] = \true;
            }
            return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
        }
        if ($node instanceof PhpParser\Node\Expr\FuncCall || $node instanceof PhpParser\Node\Expr\MethodCall || $node instanceof PhpParser\Node\Expr\StaticCall) {
            if (!$node->isFirstClassCallable()) {
                foreach ($node->getArgs() as $arg) {
                    $arg_var_id = ExpressionIdentifier::getRootVarId($arg->value, $this->this_class_name);
                    if ($arg_var_id) {
                        $this->assignment_map[$arg_var_id][$arg_var_id] = \true;
                    }
                }
            }
            if ($node instanceof PhpParser\Node\Expr\MethodCall) {
                $var_id = ExpressionIdentifier::getRootVarId($node->var, $this->this_class_name);
                if ($var_id) {
                    $this->assignment_map[$var_id]['isset'] = \true;
                }
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\Unset_) {
            foreach ($node->vars as $arg) {
                $arg_var_id = ExpressionIdentifier::getRootVarId($arg, $this->this_class_name);
                if ($arg_var_id) {
                    $this->assignment_map[$arg_var_id][$arg_var_id] = \true;
                }
            }
        }
        return null;
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getAssignmentMap() : array
    {
        return $this->assignment_map;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
/**
 * @internal
 */
class NodeCounterVisitor extends PhpParser\NodeVisitorAbstract
{
    public int $count = 0;
    public function enterNode(PhpParser\Node $node) : ?int
    {
        $this->count++;
        return null;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\YieldFrom;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Yield_;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\FunctionLike;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeTraverser;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeVisitorAbstract;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Type;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Union;
/**
 * @internal
 */
class YieldTypeCollector extends NodeVisitorAbstract
{
    /** @var list<Union> */
    private array $yield_types = [];
    private NodeDataProvider $nodes;
    public function __construct(NodeDataProvider $nodes)
    {
        $this->nodes = $nodes;
    }
    public function enterNode(Node $node) : ?int
    {
        if ($node instanceof Yield_) {
            $key_type = null;
            if ($node->key && ($node_key_type = $this->nodes->getType($node->key))) {
                $key_type = $node_key_type;
            }
            if ($node->value && ($value_type = $this->nodes->getType($node->value))) {
                $generator_type = new TGenericObject('Generator', [$key_type ? $key_type : Type::getInt(), $value_type, Type::getMixed(), Type::getMixed()]);
                $this->yield_types[] = new Union([$generator_type]);
                return null;
            }
            $this->yield_types[] = Type::getMixed();
        } elseif ($node instanceof YieldFrom) {
            if ($node_expr_type = $this->nodes->getType($node->expr)) {
                $this->yield_types[] = $node_expr_type;
                return null;
            }
            $this->yield_types[] = Type::getMixed();
        } elseif ($node instanceof FunctionLike) {
            return NodeTraverser::DONT_TRAVERSE_CHILDREN;
        }
        return null;
    }
    /**
     * @return list<Union>
     */
    public function getYieldTypes() : array
    {
        return $this->yield_types;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Scanner\DocblockParser;
use function rtrim;
use function str_replace;
use function strlen;
/**
 * @internal
 */
class ParamReplacementVisitor extends PhpParser\NodeVisitorAbstract
{
    private string $old_name;
    private string $new_name;
    /** @var list<FileManipulation> */
    private array $replacements = [];
    private bool $new_name_replaced = \false;
    private bool $new_new_name_used = \false;
    public function __construct(string $old_name, string $new_name)
    {
        $this->old_name = $old_name;
        $this->new_name = $new_name;
    }
    public function enterNode(PhpParser\Node $node) : ?int
    {
        if ($node instanceof PhpParser\Node\Expr\Variable) {
            if ($node->name === $this->old_name) {
                $this->replacements[] = new FileManipulation((int) $node->getAttribute('startFilePos') + 1, (int) $node->getAttribute('endFilePos') + 1, $this->new_name);
            } elseif ($node->name === $this->new_name) {
                if ($this->new_new_name_used) {
                    $this->replacements = [];
                    return PhpParser\NodeTraverser::STOP_TRAVERSAL;
                }
                $this->replacements[] = new FileManipulation((int) $node->getAttribute('startFilePos') + 1, (int) $node->getAttribute('endFilePos') + 1, $this->new_name . '_new');
                $this->new_name_replaced = \true;
            } elseif ($node->name === $this->new_name . '_new') {
                if ($this->new_name_replaced) {
                    $this->replacements = [];
                    return PhpParser\NodeTraverser::STOP_TRAVERSAL;
                }
                $this->new_new_name_used = \true;
            }
        } elseif ($node instanceof PhpParser\Node\Stmt\ClassMethod && ($docblock = $node->getDocComment())) {
            $parsed_docblock = DocblockParser::parse($docblock->getText(), $docblock->getStartFilePos());
            $replaced = \false;
            foreach ($parsed_docblock->tags as $tag_name => $tags) {
                foreach ($tags as $i => $tag) {
                    if ($tag_name === 'param' || $tag_name === 'psalm-param' || $tag_name === 'phpstan-param' || $tag_name === 'phan-param') {
                        $parts = CommentAnalyzer::splitDocLine($tag);
                        if (($parts[1] ?? '') === '$' . $this->old_name) {
                            $parsed_docblock->tags[$tag_name][$i] = str_replace('$' . $this->old_name, '$' . $this->new_name, $tag);
                            $replaced = \true;
                        }
                    }
                }
            }
            if ($replaced) {
                $this->replacements[] = new FileManipulation($docblock->getStartFilePos(), $docblock->getStartFilePos() + strlen($docblock->getText()), rtrim($parsed_docblock->render($parsed_docblock->first_line_padding)), \false, \false);
            }
        }
        return null;
    }
    /**
     * @return list<FileManipulation>
     */
    public function getReplacements() : array
    {
        return $this->replacements;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
use ReflectionClass;
use Throwable;
use function count;
use function end;
use function explode;
use function trait_exists;
/**
 * Given a list of file diffs, this scans an AST to find the sections it can replace, and parses
 * just those methods.
 *
 * @internal
 */
class TraitFinder extends PhpParser\NodeVisitorAbstract
{
    /** @var list<PhpParser\Node\Stmt\Trait_> */
    private array $matching_trait_nodes = [];
    private string $fq_trait_name;
    public function __construct(string $fq_trait_name)
    {
        $this->fq_trait_name = $fq_trait_name;
    }
    public function enterNode(PhpParser\Node $node, bool &$traverseChildren = \true) : ?int
    {
        if ($node instanceof PhpParser\Node\Stmt\Trait_) {
            /** @var ?string */
            $resolved_name = $node->getAttribute('resolvedName');
            if ($resolved_name === null) {
                // compare ends of names, a temporary hack because PHPParser caches
                // may not have that attribute
                $fq_trait_name_parts = explode('\\', $this->fq_trait_name);
                /** @psalm-suppress PossiblyNullPropertyFetch */
                if ($node->name->name === end($fq_trait_name_parts)) {
                    $this->matching_trait_nodes[] = $node;
                }
            } elseif ($resolved_name === $this->fq_trait_name) {
                $this->matching_trait_nodes[] = $node;
            }
        }
        if ($node instanceof PhpParser\Node\Stmt\ClassLike || $node instanceof PhpParser\Node\FunctionLike) {
            return PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN;
        }
        return null;
    }
    public function getNode() : ?PhpParser\Node\Stmt\Trait_
    {
        if (!count($this->matching_trait_nodes)) {
            return null;
        }
        if (count($this->matching_trait_nodes) === 1 || !trait_exists($this->fq_trait_name)) {
            return $this->matching_trait_nodes[0];
        }
        try {
            $reflection_trait = new ReflectionClass($this->fq_trait_name);
        } catch (Throwable $t) {
            return null;
        }
        foreach ($this->matching_trait_nodes as $node) {
            if ($node->getLine() === $reflection_trait->getStartLine()) {
                return $node;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
/**
 * Shifts all nodes in a given AST by a set amount
 *
 * @internal
 */
class OffsetShifterVisitor extends PhpParser\NodeVisitorAbstract
{
    private int $file_offset;
    private int $line_offset;
    /** @var array<int, int> */
    private array $extra_offsets;
    /**
     * @param array<int, int> $extra_offsets
     */
    public function __construct(int $offset, int $line_offset, array $extra_offsets)
    {
        $this->file_offset = $offset;
        $this->line_offset = $line_offset;
        $this->extra_offsets = $extra_offsets;
    }
    public function enterNode(PhpParser\Node $node) : ?int
    {
        /** @var array{startFilePos: int, endFilePos: int, startLine: int} */
        $attrs = $node->getAttributes();
        if ($cs = $node->getComments()) {
            $new_comments = [];
            foreach ($cs as $c) {
                if ($c instanceof PhpParser\Comment\Doc) {
                    $new_comments[] = new PhpParser\Comment\Doc($c->getText(), $c->getStartLine() + $this->line_offset, $c->getStartFilePos() + $this->file_offset + ($this->extra_offsets[$c->getStartFilePos()] ?? 0));
                } else {
                    $new_comments[] = new PhpParser\Comment($c->getText(), $c->getStartLine() + $this->line_offset, $c->getStartFilePos() + $this->file_offset + ($this->extra_offsets[$c->getStartFilePos()] ?? 0));
                }
            }
            $node->setAttribute('comments', $new_comments);
        }
        $node->setAttribute('startFilePos', $attrs['startFilePos'] + $this->file_offset + ($this->extra_offsets[$attrs['startFilePos']] ?? 0));
        $node->setAttribute('endFilePos', $attrs['endFilePos'] + $this->file_offset + ($this->extra_offsets[$attrs['endFilePos']] ?? 0));
        $node->setAttribute('startLine', $attrs['startLine'] + $this->line_offset);
        return null;
    }
}
<?php

namespace Psalm\Internal\PhpVisitor;

use _HumbugBox1cb33d1f20f1\PhpParser;
use function is_string;
/**
 * @internal
 */
class ShortClosureVisitor extends PhpParser\NodeVisitorAbstract
{
    /**
     * @var array<string, bool>
     */
    protected array $used_variables = [];
    public function enterNode(PhpParser\Node $node) : ?int
    {
        if ($node instanceof PhpParser\Node\Expr\Variable && is_string($node->name)) {
            $this->used_variables['$' . $node->name] = \true;
        }
        return null;
    }
    /**
     * @return array<string, bool>
     */
    public function getUsedVariables() : array
    {
        return $this->used_variables;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Codebase;

use Psalm\Codebase;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TMixed;
use function array_merge;
use function array_values;
use function preg_match;
use function sprintf;
use function str_replace;
/**
 * @internal
 */
final class ClassConstantByWildcardResolver
{
    private Codebase $codebase;
    public function __construct(Codebase $codebase)
    {
        $this->codebase = $codebase;
    }
    /**
     * @return list<Atomic>|null
     */
    public function resolve(string $class_name, string $constant_pattern) : ?array
    {
        if (!$this->codebase->classlike_storage_provider->has($class_name)) {
            return null;
        }
        $constant_regex_pattern = sprintf('#^%s$#', str_replace('*', '.*', $constant_pattern));
        $class_like_storage = $this->codebase->classlike_storage_provider->get($class_name);
        $matched_class_constant_types = [];
        foreach ($class_like_storage->constants as $constant => $class_constant_storage) {
            if (preg_match($constant_regex_pattern, $constant) === 0) {
                continue;
            }
            if (!$class_constant_storage->type) {
                $matched_class_constant_types[] = [new TMixed()];
                continue;
            }
            $matched_class_constant_types[] = $class_constant_storage->type->getAtomicTypes();
        }
        return array_values(array_merge([], ...$matched_class_constant_types));
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Psalm\CodeLocation;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\Path;
use function abs;
use function array_merge;
use function count;
/**
 * @internal
 */
class VariableUseGraph extends \Psalm\Internal\Codebase\DataFlowGraph
{
    /** @var array<string, array<string, true>> */
    protected array $backward_edges = [];
    /** @var array<string, DataFlowNode> */
    private array $nodes = [];
    /** @var array<string, list<CodeLocation>> */
    private array $origin_locations_by_id = [];
    public function addNode(DataFlowNode $node) : void
    {
        $this->nodes[$node->id] = $node;
    }
    /**
     * @param array<string> $added_taints
     * @param array<string> $removed_taints
     */
    public function addPath(DataFlowNode $from, DataFlowNode $to, string $path_type, ?array $added_taints = null, ?array $removed_taints = null) : void
    {
        $from_id = $from->id;
        $to_id = $to->id;
        if ($from_id === $to_id) {
            return;
        }
        $length = 0;
        if ($from->code_location && $to->code_location && $from->code_location->file_path === $to->code_location->file_path) {
            $to_line = $to->code_location->raw_line_number;
            $from_line = $from->code_location->raw_line_number;
            $length = abs($to_line - $from_line);
        }
        $this->backward_edges[$to_id][$from_id] = \true;
        $this->forward_edges[$from_id][$to_id] = new Path($path_type, $length);
    }
    public function isVariableUsed(DataFlowNode $assignment_node) : bool
    {
        $visited_source_ids = [];
        $sources = [$assignment_node];
        for ($i = 0; count($sources) && $i < 200; $i++) {
            $new_child_nodes = [];
            foreach ($sources as $source) {
                $visited_source_ids[$source->id] = \true;
                $child_nodes = $this->getChildNodes($source, $visited_source_ids);
                if ($child_nodes === null) {
                    return \true;
                }
                $new_child_nodes = array_merge($new_child_nodes, $child_nodes);
            }
            $sources = $new_child_nodes;
        }
        return \false;
    }
    /**
     * @return list<CodeLocation>
     */
    public function getOriginLocations(DataFlowNode $assignment_node) : array
    {
        if (isset($this->origin_locations_by_id[$assignment_node->id])) {
            return $this->origin_locations_by_id[$assignment_node->id];
        }
        $visited_child_ids = [];
        $origin_locations = [];
        $child_nodes = [$assignment_node];
        for ($i = 0; count($child_nodes) && $i < 200; $i++) {
            $new_parent_nodes = [];
            foreach ($child_nodes as $child_node) {
                $visited_child_ids[$child_node->id] = \true;
                $parent_nodes = $this->getParentNodes($child_node, $visited_child_ids);
                if (!$parent_nodes) {
                    if ($child_node->code_location) {
                        $origin_locations[] = $child_node->code_location;
                    }
                    continue;
                }
                $new_parent_nodes = [...$new_parent_nodes, ...$parent_nodes];
            }
            $child_nodes = $new_parent_nodes;
        }
        $this->origin_locations_by_id[$assignment_node->id] = $origin_locations;
        return $origin_locations;
    }
    /**
     * @param array<string, bool> $visited_source_ids
     * @return array<string, DataFlowNode>|null
     */
    private function getChildNodes(DataFlowNode $generated_source, array $visited_source_ids) : ?array
    {
        $new_child_nodes = [];
        if (!isset($this->forward_edges[$generated_source->id])) {
            return [];
        }
        foreach ($this->forward_edges[$generated_source->id] as $to_id => $path) {
            $path_type = $path->type;
            if ($path->type === 'variable-use' || $path->type === 'closure-use' || $path->type === 'global-use' || $path->type === 'use-inside-instance-property' || $path->type === 'use-inside-static-property' || $path->type === 'use-inside-call' || $path->type === 'use-inside-conditional' || $path->type === 'use-inside-isset' || $path->type === 'arg' || $path->type === 'comparison') {
                return null;
            }
            if (isset($visited_source_ids[$to_id])) {
                continue;
            }
            if (self::shouldIgnoreFetch($path_type, 'arraykey', $generated_source->path_types)) {
                continue;
            }
            if (self::shouldIgnoreFetch($path_type, 'arrayvalue', $generated_source->path_types)) {
                continue;
            }
            if (self::shouldIgnoreFetch($path_type, 'property', $generated_source->path_types)) {
                continue;
            }
            $new_destination = new DataFlowNode($to_id, $to_id, null);
            $new_destination->path_types = [...$generated_source->path_types, ...[$path_type]];
            $new_child_nodes[$to_id] = $new_destination;
        }
        return $new_child_nodes;
    }
    /**
     * @param array<string, bool> $visited_source_ids
     * @return list<DataFlowNode>
     */
    private function getParentNodes(DataFlowNode $destination, array $visited_source_ids) : array
    {
        $new_parent_nodes = [];
        if (!isset($this->backward_edges[$destination->id])) {
            return [];
        }
        foreach ($this->backward_edges[$destination->id] as $from_id => $_) {
            if (isset($visited_source_ids[$from_id])) {
                continue;
            }
            if (isset($this->nodes[$from_id])) {
                $new_parent_nodes[] = $this->nodes[$from_id];
            }
        }
        return $new_parent_nodes;
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Exception;
use LibXMLError;
use LogicException;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Storage\ClassConstantStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Storage\PropertyStorage;
use Psalm\Type;
use Psalm\Type\Union;
use ReflectionClass;
use ReflectionException;
use ReflectionFunction;
use ReflectionMethod;
use ReflectionNamedType;
use ReflectionParameter;
use ReflectionType;
use ReflectionUnionType;
use UnexpectedValueException;
use function array_map;
use function array_merge;
use function get_class;
use function implode;
use function strtolower;
/**
 * @internal
 *
 * Handles information gleaned from class and function reflection
 */
class Reflection
{
    private ClassLikeStorageProvider $storage_provider;
    private Codebase $codebase;
    /**
     * @var array<string, FunctionStorage>
     */
    private static array $builtin_functions = [];
    public function __construct(ClassLikeStorageProvider $storage_provider, Codebase $codebase)
    {
        $this->storage_provider = $storage_provider;
        $this->codebase = $codebase;
        self::$builtin_functions = [];
    }
    public function registerClass(ReflectionClass $reflected_class) : void
    {
        $class_name = $reflected_class->name;
        if ($class_name === LibXMLError::class) {
            $class_name = 'libXMLError';
        }
        $class_name_lower = strtolower($class_name);
        try {
            $this->storage_provider->get($class_name_lower);
            return;
        } catch (Exception $e) {
            // this is fine
        }
        $reflected_parent_class = $reflected_class->getParentClass();
        $storage = $this->storage_provider->create($class_name);
        $storage->abstract = $reflected_class->isAbstract();
        $storage->is_interface = $reflected_class->isInterface();
        $storage->potential_declaring_method_ids['__construct'][$class_name_lower . '::__construct'] = \true;
        if ($reflected_parent_class) {
            $parent_class_name = $reflected_parent_class->getName();
            $this->registerClass($reflected_parent_class);
            $parent_class_name_lc = strtolower($parent_class_name);
            $parent_storage = $this->storage_provider->get($parent_class_name_lc);
            $this->registerInheritedMethods($class_name_lower, $parent_class_name_lc);
            $this->registerInheritedProperties($class_name_lower, $parent_class_name_lc);
            $storage->class_implements = $parent_storage->class_implements;
            $storage->constants = $parent_storage->constants;
            $storage->parent_classes = array_merge([$parent_class_name_lc => $parent_class_name], $parent_storage->parent_classes);
            $storage->used_traits = $parent_storage->used_traits;
        }
        $class_properties = $reflected_class->getProperties();
        $public_mapped_properties = \Psalm\Internal\Codebase\PropertyMap::inPropertyMap($class_name) ? \Psalm\Internal\Codebase\PropertyMap::getPropertyMap()[strtolower($class_name)] : [];
        foreach ($class_properties as $class_property) {
            $property_name = $class_property->getName();
            $storage->properties[$property_name] = new PropertyStorage();
            $storage->properties[$property_name]->type = Type::getMixed();
            if ($class_property->isStatic()) {
                $storage->properties[$property_name]->is_static = \true;
            }
            if ($class_property->isPublic()) {
                $storage->properties[$property_name]->visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
            } elseif ($class_property->isProtected()) {
                $storage->properties[$property_name]->visibility = ClassLikeAnalyzer::VISIBILITY_PROTECTED;
            } elseif ($class_property->isPrivate()) {
                $storage->properties[$property_name]->visibility = ClassLikeAnalyzer::VISIBILITY_PRIVATE;
            }
            $property_id = $class_property->class . '::$' . $property_name;
            $storage->declaring_property_ids[$property_name] = $class_property->class;
            $storage->appearing_property_ids[$property_name] = $property_id;
            if (!$class_property->isPrivate()) {
                $storage->inheritable_property_ids[$property_name] = $property_id;
            }
        }
        // have to do this separately as there can be new properties here
        foreach ($public_mapped_properties as $property_name => $type_string) {
            $property_id = $class_name . '::$' . $property_name;
            if (!isset($storage->properties[$property_name])) {
                $storage->properties[$property_name] = new PropertyStorage();
                $storage->properties[$property_name]->visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
                $storage->declaring_property_ids[$property_name] = $class_name;
                $storage->appearing_property_ids[$property_name] = $property_id;
                $storage->inheritable_property_ids[$property_name] = $property_id;
            }
            $type = Type::parseString($type_string);
            if ($property_id === 'DateInterval::$days') {
                /** @psalm-suppress InaccessibleProperty We just parsed this type */
                $type->ignore_falsable_issues = \true;
            }
            $storage->properties[$property_name]->type = $type;
        }
        /** @var array<string, int|string|float|null|array> */
        $class_constants = $reflected_class->getConstants();
        foreach ($class_constants as $name => $value) {
            $storage->constants[$name] = new ClassConstantStorage(ClassLikeAnalyzer::getTypeFromValue($value), new Union([\Psalm\Internal\Codebase\ConstantTypeResolver::getLiteralTypeFromScalarValue($value)]), ClassLikeAnalyzer::VISIBILITY_PUBLIC, null);
        }
        if ($reflected_class->isInterface()) {
            $this->codebase->classlikes->addFullyQualifiedInterfaceName($class_name);
        } elseif ($reflected_class->isTrait()) {
            $this->codebase->classlikes->addFullyQualifiedTraitName($class_name);
        } else {
            $this->codebase->classlikes->addFullyQualifiedClassName($class_name);
        }
        $reflection_methods = $reflected_class->getMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED);
        if ($class_name_lower === 'generator') {
            $storage->template_types = ['TKey' => ['Generator' => Type::getMixed()], 'TValue' => ['Generator' => Type::getMixed()]];
        }
        $interfaces = $reflected_class->getInterfaces();
        foreach ($interfaces as $interface) {
            $interface_name = $interface->getName();
            $this->registerClass($interface);
            if ($reflected_class->isInterface()) {
                $storage->parent_interfaces[strtolower($interface_name)] = $interface_name;
            } else {
                $storage->class_implements[strtolower($interface_name)] = $interface_name;
            }
        }
        foreach ($reflection_methods as $reflection_method) {
            $method_reflection_class = $reflection_method->getDeclaringClass();
            $this->registerClass($method_reflection_class);
            $this->extractReflectionMethodInfo($reflection_method);
            if ($reflection_method->class !== $class_name && ($class_name !== 'SoapFault' || $reflection_method->name !== '__construct')) {
                $reflection_method_name = strtolower($reflection_method->name);
                $reflection_method_class = $reflection_method->class;
                $this->codebase->methods->setDeclaringMethodId($class_name, $reflection_method_name, $reflection_method_class, $reflection_method_name);
                $this->codebase->methods->setAppearingMethodId($class_name, $reflection_method_name, $reflection_method_class, $reflection_method_name);
            }
        }
    }
    public function extractReflectionMethodInfo(ReflectionMethod $method) : void
    {
        $method_name_lc = strtolower($method->getName());
        $fq_class_name = $method->class;
        $fq_class_name_lc = strtolower($fq_class_name);
        $class_storage = $this->storage_provider->get($fq_class_name_lc);
        if (isset($class_storage->methods[$method_name_lc])) {
            return;
        }
        $method_id = $method->class . '::' . $method_name_lc;
        $storage = $class_storage->methods[$method_name_lc] = new MethodStorage();
        $storage->cased_name = $method->name;
        $storage->defining_fqcln = $method->class;
        if ($method_name_lc === $fq_class_name_lc) {
            $this->codebase->methods->setDeclaringMethodId($fq_class_name, '__construct', $fq_class_name, $method_name_lc);
            $this->codebase->methods->setAppearingMethodId($fq_class_name, '__construct', $fq_class_name, $method_name_lc);
        }
        $declaring_class = $method->getDeclaringClass();
        $storage->is_static = $method->isStatic();
        $storage->abstract = $method->isAbstract();
        $storage->mutation_free = $storage->external_mutation_free = $method_name_lc === '__construct' && $fq_class_name_lc === 'datetimezone';
        $class_storage->declaring_method_ids[$method_name_lc] = new MethodIdentifier($declaring_class->name, $method_name_lc);
        $class_storage->inheritable_method_ids[$method_name_lc] = $class_storage->declaring_method_ids[$method_name_lc];
        $class_storage->appearing_method_ids[$method_name_lc] = $class_storage->declaring_method_ids[$method_name_lc];
        $class_storage->overridden_method_ids[$method_name_lc] = [];
        $storage->visibility = $method->isPrivate() ? ClassLikeAnalyzer::VISIBILITY_PRIVATE : ($method->isProtected() ? ClassLikeAnalyzer::VISIBILITY_PROTECTED : ClassLikeAnalyzer::VISIBILITY_PUBLIC);
        $callables = \Psalm\Internal\Codebase\InternalCallMapHandler::getCallablesFromCallMap($method_id);
        if ($callables && $callables[0]->params !== null && $callables[0]->return_type !== null) {
            $storage->setParams([]);
            foreach ($callables[0]->params as $param) {
                if ($param->type) {
                    /** @psalm-suppress UnusedMethodCall */
                    $param->type->queueClassLikesForScanning($this->codebase);
                }
            }
            $storage->setParams($callables[0]->params);
            $storage->return_type = $callables[0]->return_type;
            /** @psalm-suppress UnusedMethodCall */
            $storage->return_type->queueClassLikesForScanning($this->codebase);
        } else {
            $params = $method->getParameters();
            $storage->setParams([]);
            foreach ($params as $param) {
                $param_array = $this->getReflectionParamData($param);
                $storage->addParam($param_array);
            }
        }
        $storage->required_param_count = 0;
        foreach ($storage->params as $i => $param) {
            if (!$param->is_optional && !$param->is_variadic) {
                $storage->required_param_count = $i + 1;
            }
        }
    }
    private function getReflectionParamData(ReflectionParameter $param) : FunctionLikeParameter
    {
        $param_type = self::getPsalmTypeFromReflectionType($param->getType());
        $param_name = $param->getName();
        $is_optional = $param->isOptional();
        $parameter = new FunctionLikeParameter($param_name, $param->isPassedByReference(), $param_type, $param_type, null, null, $is_optional, $param_type->isNullable(), $param->isVariadic());
        $parameter->signature_type = Type::getMixed();
        return $parameter;
    }
    /**
     * @param  callable-string $function_id
     * @return false|null
     */
    public function registerFunction(string $function_id) : ?bool
    {
        try {
            $reflection_function = new ReflectionFunction($function_id);
            $callmap_callable = null;
            if (isset(self::$builtin_functions[$function_id])) {
                return null;
            }
            $storage = self::$builtin_functions[$function_id] = new FunctionStorage();
            if (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap($function_id)) {
                $callmap_callable = \Psalm\Internal\Codebase\InternalCallMapHandler::getCallableFromCallMapById($this->codebase, $function_id, [], null);
            }
            if ($callmap_callable !== null && $callmap_callable->params !== null && $callmap_callable->return_type !== null) {
                $storage->setParams($callmap_callable->params);
                $storage->return_type = $callmap_callable->return_type;
            } else {
                $reflection_params = $reflection_function->getParameters();
                foreach ($reflection_params as $param) {
                    $param_obj = $this->getReflectionParamData($param);
                    $storage->addParam($param_obj);
                }
                if ($reflection_return_type = $reflection_function->getReturnType()) {
                    $storage->return_type = self::getPsalmTypeFromReflectionType($reflection_return_type);
                }
            }
            $storage->pure = \true;
            $storage->required_param_count = 0;
            foreach ($storage->params as $i => $param) {
                if (!$param->is_optional && !$param->is_variadic) {
                    $storage->required_param_count = $i + 1;
                }
            }
            $storage->cased_name = $reflection_function->getName();
        } catch (ReflectionException $e) {
            return \false;
        }
        return null;
    }
    /** @psalm-suppress UnusedPsalmSuppress,UndefinedClass,TypeDoesNotContainType 7.4 has no ReflectionUnionType */
    public static function getPsalmTypeFromReflectionType(?ReflectionType $reflection_type = null) : Union
    {
        if (!$reflection_type) {
            return Type::getMixed();
        }
        if ($reflection_type instanceof ReflectionNamedType) {
            $type = $reflection_type->getName();
        } elseif ($reflection_type instanceof ReflectionUnionType) {
            /** @psalm-suppress MixedArgument */
            $type = implode('|', array_map(static fn(ReflectionNamedType $reflection): string => $reflection->getName(), $reflection_type->getTypes()));
        } else {
            throw new LogicException('Unexpected reflection class ' . get_class($reflection_type) . ' found.');
        }
        if ($reflection_type->allowsNull()) {
            $type .= '|null';
        }
        return Type::parseString($type);
    }
    private function registerInheritedMethods(string $fq_class_name, string $parent_class) : void
    {
        $parent_storage = $this->storage_provider->get($parent_class);
        $storage = $this->storage_provider->get($fq_class_name);
        // register where they appear (can never be in a trait)
        foreach ($parent_storage->appearing_method_ids as $method_name => $appearing_method_id) {
            $storage->appearing_method_ids[$method_name] = $appearing_method_id;
        }
        // register where they're declared
        foreach ($parent_storage->inheritable_method_ids as $method_name => $declaring_method_id) {
            $storage->declaring_method_ids[$method_name] = $declaring_method_id;
            $storage->inheritable_method_ids[$method_name] = $declaring_method_id;
            $storage->overridden_method_ids[$method_name][$declaring_method_id->fq_class_name] = $declaring_method_id;
        }
    }
    /**
     * @param lowercase-string $fq_class_name
     * @param lowercase-string $parent_class
     */
    private function registerInheritedProperties(string $fq_class_name, string $parent_class) : void
    {
        $parent_storage = $this->storage_provider->get($parent_class);
        $storage = $this->storage_provider->get($fq_class_name);
        // register where they appear (can never be in a trait)
        foreach ($parent_storage->appearing_property_ids as $property_name => $appearing_property_id) {
            if (!$parent_storage->is_trait && isset($parent_storage->properties[$property_name]) && $parent_storage->properties[$property_name]->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                continue;
            }
            $storage->appearing_property_ids[$property_name] = $appearing_property_id;
        }
        // register where they're declared
        foreach ($parent_storage->declaring_property_ids as $property_name => $declaring_property_class) {
            if (!$parent_storage->is_trait && isset($parent_storage->properties[$property_name]) && $parent_storage->properties[$property_name]->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                continue;
            }
            $storage->declaring_property_ids[$property_name] = strtolower($declaring_property_class);
        }
        // register where they're declared
        foreach ($parent_storage->inheritable_property_ids as $property_name => $inheritable_property_id) {
            if (!$parent_storage->is_trait && isset($parent_storage->properties[$property_name]) && $parent_storage->properties[$property_name]->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                continue;
            }
            $storage->inheritable_property_ids[$property_name] = $inheritable_property_id;
        }
    }
    public function hasFunction(string $function_id) : bool
    {
        return isset(self::$builtin_functions[$function_id]);
    }
    public function getFunctionStorage(string $function_id) : FunctionStorage
    {
        if (isset(self::$builtin_functions[$function_id])) {
            return self::$builtin_functions[$function_id];
        }
        throw new UnexpectedValueException('Expecting to have a function for ' . $function_id);
    }
    /**
     * @return array<string, FunctionStorage>
     */
    public function getFunctions() : array
    {
        return self::$builtin_functions;
    }
    public static function clearCache() : void
    {
        self::$builtin_functions = [];
    }
}
<?php

namespace Psalm\Internal\Codebase;

use function dirname;
use function strtolower;
/**
 * @internal
 */
class PropertyMap
{
    /**
     * @var array<lowercase-string, array<string, string>>|null
     */
    private static ?array $property_map = null;
    /**
     * Gets the method/function call map
     *
     * @return array<lowercase-string, array<string, string>>
     */
    public static function getPropertyMap() : array
    {
        if (self::$property_map !== null) {
            return self::$property_map;
        }
        /** @var array<lowercase-string, array<string, string>> */
        $property_map = (require dirname(__DIR__, 4) . '/dictionaries/PropertyMap.php');
        self::$property_map = $property_map;
        return self::$property_map;
    }
    public static function inPropertyMap(string $class_name) : bool
    {
        return isset(self::getPropertyMap()[strtolower($class_name)]);
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\Path;
use function abs;
use function array_keys;
use function array_reverse;
use function array_sum;
use function count;
use function strlen;
use function strpos;
use function substr;
/**
 * @internal
 */
abstract class DataFlowGraph
{
    /** @var array<string, array<string, Path>> */
    protected array $forward_edges = [];
    public abstract function addNode(DataFlowNode $node) : void;
    /**
     * @param array<string> $added_taints
     * @param array<string> $removed_taints
     */
    public function addPath(DataFlowNode $from, DataFlowNode $to, string $path_type, ?array $added_taints = null, ?array $removed_taints = null) : void
    {
        $from_id = $from->id;
        $to_id = $to->id;
        if ($from_id === $to_id) {
            return;
        }
        $length = 0;
        if ($from->code_location && $to->code_location && $from->code_location->file_path === $to->code_location->file_path) {
            $to_line = $to->code_location->raw_line_number;
            $from_line = $from->code_location->raw_line_number;
            $length = abs($to_line - $from_line);
        }
        $this->forward_edges[$from_id][$to_id] = new Path($path_type, $length, $added_taints, $removed_taints);
    }
    /**
     * @param array<string> $previous_path_types
     * @psalm-pure
     */
    protected static function shouldIgnoreFetch(string $path_type, string $expression_type, array $previous_path_types) : bool
    {
        $el = strlen($expression_type);
        // arraykey-fetch requires a matching arraykey-assignment at the same level
        // otherwise the tainting is not valid
        if (strpos($path_type, $expression_type . '-fetch-') === 0 || $path_type === 'arraykey-fetch' && $expression_type === 'arrayvalue') {
            $fetch_nesting = 0;
            $previous_path_types = array_reverse($previous_path_types);
            foreach ($previous_path_types as $previous_path_type) {
                if ($previous_path_type === $expression_type . '-assignment') {
                    if ($fetch_nesting === 0) {
                        return \false;
                    }
                    $fetch_nesting--;
                }
                if (strpos($previous_path_type, $expression_type . '-fetch') === 0) {
                    $fetch_nesting++;
                }
                if (strpos($previous_path_type, $expression_type . '-assignment-') === 0) {
                    if ($fetch_nesting > 0) {
                        $fetch_nesting--;
                        continue;
                    }
                    if (substr($previous_path_type, $el + 12) === substr($path_type, $el + 7)) {
                        return \false;
                    }
                    return \true;
                }
            }
        }
        return \false;
    }
    /**
     * @return array{int, int, int, float}
     */
    public function getEdgeStats() : array
    {
        $lengths = 0;
        $destination_counts = [];
        $origin_counts = [];
        foreach ($this->forward_edges as $from_id => $destinations) {
            foreach ($destinations as $to_id => $path) {
                if ($path->length === 0) {
                    continue;
                }
                $lengths += $path->length;
                if (!isset($destination_counts[$to_id])) {
                    $destination_counts[$to_id] = 0;
                }
                $destination_counts[$to_id]++;
                $origin_counts[$from_id] = \true;
            }
        }
        $count = array_sum($destination_counts);
        if (!$count) {
            return [0, 0, 0, 0.0];
        }
        $mean = $lengths / $count;
        return [$count, count($origin_counts), count($destination_counts), $mean];
    }
    /**
     * @psalm-return list<list<string>>
     */
    public function summarizeEdges() : array
    {
        $edges = [];
        foreach ($this->forward_edges as $source => $destinations) {
            $edges[] = [...[$source], ...array_keys($destinations)];
        }
        return $edges;
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Psalm\Internal\Provider\ClassLikeStorageProvider;
/**
 * @internal
 */
class ReferenceMapGenerator
{
    /**
     * @return array<string, string>
     */
    public static function getReferenceMap(ClassLikeStorageProvider $classlike_storage_provider, array $expected_references) : array
    {
        $reference_dictionary = [];
        foreach ($classlike_storage_provider->getAll() as $storage) {
            if (!$storage->location) {
                continue;
            }
            $fq_classlike_name = $storage->name;
            if (isset($expected_references[$fq_classlike_name])) {
                $reference_dictionary[$fq_classlike_name] = $storage->location->file_name . ':' . $storage->location->getLineNumber() . ':' . $storage->location->getColumn();
            }
            foreach ($storage->methods as $method_name => $method_storage) {
                if (!$method_storage->location) {
                    continue;
                }
                if (isset($expected_references[$fq_classlike_name . '::' . $method_name . '()'])) {
                    $reference_dictionary[$fq_classlike_name . '::' . $method_name . '()'] = $method_storage->location->file_name . ':' . $method_storage->location->getLineNumber() . ':' . $method_storage->location->getColumn();
                }
            }
            foreach ($storage->properties as $property_name => $property_storage) {
                if (!$property_storage->location) {
                    continue;
                }
                if (isset($expected_references[$fq_classlike_name . '::$' . $property_name])) {
                    $reference_dictionary[$fq_classlike_name . '::$' . $property_name] = $property_storage->location->file_name . ':' . $property_storage->location->getLineNumber() . ':' . $property_storage->location->getColumn();
                }
            }
        }
        return $reference_dictionary;
    }
}
<?php

namespace Psalm\Internal\Codebase;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeTraverser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Exception\UnpopulatedClasslikeException;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\FileManipulation\ClassDocblockManipulator;
use Psalm\Internal\FileManipulation\CodeMigration;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\PhpVisitor\TraitFinder;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\StatementsProvider;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\PossiblyUnusedMethod;
use Psalm\Issue\PossiblyUnusedParam;
use Psalm\Issue\PossiblyUnusedProperty;
use Psalm\Issue\PossiblyUnusedReturnValue;
use Psalm\Issue\UnusedClass;
use Psalm\Issue\UnusedConstructor;
use Psalm\Issue\UnusedMethod;
use Psalm\Issue\UnusedParam;
use Psalm\Issue\UnusedProperty;
use Psalm\Issue\UnusedReturnValue;
use Psalm\IssueBuffer;
use Psalm\Node\VirtualNode;
use Psalm\Progress\Progress;
use Psalm\Progress\VoidProgress;
use Psalm\StatementsSource;
use Psalm\Storage\ClassConstantStorage;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Type;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Union;
use ReflectionClass;
use ReflectionProperty;
use UnexpectedValueException;
use function array_filter;
use function array_merge;
use function array_pop;
use function count;
use function end;
use function explode;
use function get_declared_classes;
use function get_declared_interfaces;
use function implode;
use function preg_match;
use function preg_quote;
use function preg_replace;
use function strlen;
use function strrpos;
use function strtolower;
use function substr;
use const PHP_EOL;
/**
 * @internal
 *
 * Handles information about classes, interfaces and traits
 */
class ClassLikes
{
    private ClassLikeStorageProvider $classlike_storage_provider;
    public FileReferenceProvider $file_reference_provider;
    /**
     * @var array<lowercase-string, bool>
     */
    private array $existing_classlikes_lc = [];
    /**
     * @var array<lowercase-string, bool>
     */
    private array $existing_classes_lc = [];
    /**
     * @var array<string, bool>
     */
    private array $existing_classes = [];
    /**
     * @var array<lowercase-string, bool>
     */
    private array $existing_interfaces_lc = [];
    /**
     * @var array<string, bool>
     */
    private array $existing_interfaces = [];
    /**
     * @var array<lowercase-string, bool>
     */
    private array $existing_traits_lc = [];
    /**
     * @var array<string, bool>
     */
    private array $existing_traits = [];
    /**
     * @var array<lowercase-string, bool>
     */
    private array $existing_enums_lc = [];
    /**
     * @var array<string, bool>
     */
    private array $existing_enums = [];
    /**
     * @var array<lowercase-string, string>
     */
    private array $classlike_aliases_map = [];
    /**
     * @var array<string, bool>
     */
    private array $existing_classlike_aliases = [];
    /**
     * @var array<string, PhpParser\Node\Stmt\Trait_>
     */
    private array $trait_nodes = [];
    public bool $collect_references = \false;
    public bool $collect_locations = \false;
    private StatementsProvider $statements_provider;
    private Config $config;
    private \Psalm\Internal\Codebase\Scanner $scanner;
    public function __construct(Config $config, ClassLikeStorageProvider $storage_provider, FileReferenceProvider $file_reference_provider, StatementsProvider $statements_provider, \Psalm\Internal\Codebase\Scanner $scanner)
    {
        $this->config = $config;
        $this->classlike_storage_provider = $storage_provider;
        $this->file_reference_provider = $file_reference_provider;
        $this->statements_provider = $statements_provider;
        $this->scanner = $scanner;
        $this->collectPredefinedClassLikes();
    }
    private function collectPredefinedClassLikes() : void
    {
        /** @var array<int, string> */
        $predefined_classes = get_declared_classes();
        foreach ($predefined_classes as $predefined_class) {
            $predefined_class = preg_replace('/^\\\\/', '', $predefined_class, 1);
            /** @psalm-suppress ArgumentTypeCoercion */
            $reflection_class = new ReflectionClass($predefined_class);
            if (!$reflection_class->isUserDefined() && $reflection_class->name === $predefined_class) {
                $predefined_class_lc = strtolower($predefined_class);
                $this->existing_classlikes_lc[$predefined_class_lc] = \true;
                $this->existing_classes_lc[$predefined_class_lc] = \true;
                $this->existing_classes[$predefined_class] = \true;
            }
        }
        /** @var array<int, string> */
        $predefined_interfaces = get_declared_interfaces();
        foreach ($predefined_interfaces as $predefined_interface) {
            $predefined_interface = preg_replace('/^\\\\/', '', $predefined_interface, 1);
            /** @psalm-suppress ArgumentTypeCoercion */
            $reflection_class = new ReflectionClass($predefined_interface);
            if (!$reflection_class->isUserDefined() && $reflection_class->name === $predefined_interface) {
                $predefined_interface_lc = strtolower($predefined_interface);
                $this->existing_classlikes_lc[$predefined_interface_lc] = \true;
                $this->existing_interfaces_lc[$predefined_interface_lc] = \true;
                $this->existing_interfaces[$predefined_interface] = \true;
            }
        }
    }
    public function addFullyQualifiedClassName(string $fq_class_name, ?string $file_path = null) : void
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        $this->existing_classlikes_lc[$fq_class_name_lc] = \true;
        $this->existing_classes_lc[$fq_class_name_lc] = \true;
        $this->existing_classes[$fq_class_name] = \true;
        $this->existing_traits_lc[$fq_class_name_lc] = \false;
        $this->existing_interfaces_lc[$fq_class_name_lc] = \false;
        $this->existing_enums_lc[$fq_class_name_lc] = \false;
        if ($file_path) {
            $this->scanner->setClassLikeFilePath($fq_class_name_lc, $file_path);
        }
    }
    public function addFullyQualifiedInterfaceName(string $fq_class_name, ?string $file_path = null) : void
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        $this->existing_classlikes_lc[$fq_class_name_lc] = \true;
        $this->existing_interfaces_lc[$fq_class_name_lc] = \true;
        $this->existing_interfaces[$fq_class_name] = \true;
        $this->existing_classes_lc[$fq_class_name_lc] = \false;
        $this->existing_traits_lc[$fq_class_name_lc] = \false;
        $this->existing_enums_lc[$fq_class_name_lc] = \false;
        if ($file_path) {
            $this->scanner->setClassLikeFilePath($fq_class_name_lc, $file_path);
        }
    }
    public function addFullyQualifiedTraitName(string $fq_class_name, ?string $file_path = null) : void
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        $this->existing_classlikes_lc[$fq_class_name_lc] = \true;
        $this->existing_traits_lc[$fq_class_name_lc] = \true;
        $this->existing_traits[$fq_class_name] = \true;
        $this->existing_classes_lc[$fq_class_name_lc] = \false;
        $this->existing_interfaces_lc[$fq_class_name_lc] = \false;
        $this->existing_enums[$fq_class_name] = \false;
        if ($file_path) {
            $this->scanner->setClassLikeFilePath($fq_class_name_lc, $file_path);
        }
    }
    public function addFullyQualifiedEnumName(string $fq_class_name, ?string $file_path = null) : void
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        $this->existing_classlikes_lc[$fq_class_name_lc] = \true;
        $this->existing_enums_lc[$fq_class_name_lc] = \true;
        $this->existing_enums[$fq_class_name] = \true;
        $this->existing_traits_lc[$fq_class_name_lc] = \false;
        $this->existing_classes_lc[$fq_class_name_lc] = \false;
        $this->existing_interfaces_lc[$fq_class_name_lc] = \false;
        if ($file_path) {
            $this->scanner->setClassLikeFilePath($fq_class_name_lc, $file_path);
        }
    }
    public function addFullyQualifiedClassLikeName(string $fq_class_name_lc, ?string $file_path = null) : void
    {
        if ($file_path) {
            $this->scanner->setClassLikeFilePath($fq_class_name_lc, $file_path);
        }
    }
    /**
     * @return list<string>
     */
    public function getMatchingClassLikeNames(string $stub) : array
    {
        $matching_classes = [];
        if ($stub[0] === '*') {
            $stub = substr($stub, 1);
        }
        $fully_qualified = \false;
        if ($stub[0] === '\\') {
            $fully_qualified = \true;
            $stub = substr($stub, 1);
        } else {
            // for any not-fully-qualified class name the bit we care about comes after a dash
            [, $stub] = explode('-', $stub);
        }
        $stub = preg_quote(strtolower($stub));
        if ($fully_qualified) {
            $stub = '^' . $stub;
        } else {
            $stub = '(^|\\\\)' . $stub;
        }
        foreach ($this->existing_classes as $fq_classlike_name => $found) {
            if (!$found) {
                continue;
            }
            if (preg_match('@' . $stub . '.*@i', $fq_classlike_name)) {
                $matching_classes[] = $fq_classlike_name;
            }
        }
        foreach ($this->existing_interfaces as $fq_classlike_name => $found) {
            if (!$found) {
                continue;
            }
            if (preg_match('@' . $stub . '.*@i', $fq_classlike_name)) {
                $matching_classes[] = $fq_classlike_name;
            }
        }
        return $matching_classes;
    }
    public function hasFullyQualifiedClassName(string $fq_class_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        $fq_class_name_lc = strtolower($this->getUnAliasedName($fq_class_name));
        if ($code_location) {
            if ($calling_method_id) {
                $this->file_reference_provider->addMethodReferenceToClass($calling_method_id, $fq_class_name_lc);
            } elseif (!$calling_fq_class_name || strtolower($calling_fq_class_name) !== $fq_class_name_lc) {
                $this->file_reference_provider->addNonMethodReferenceToClass($code_location->file_path, $fq_class_name_lc);
                if ($calling_fq_class_name) {
                    $class_storage = $this->classlike_storage_provider->get($calling_fq_class_name);
                    if ($class_storage->location && $class_storage->location->file_path !== $code_location->file_path) {
                        $this->file_reference_provider->addNonMethodReferenceToClass($class_storage->location->file_path, $fq_class_name_lc);
                    }
                }
            }
        }
        if (!isset($this->existing_classes_lc[$fq_class_name_lc]) || !$this->existing_classes_lc[$fq_class_name_lc] || !$this->classlike_storage_provider->has($fq_class_name_lc)) {
            if ((!isset($this->existing_classes_lc[$fq_class_name_lc]) || $this->existing_classes_lc[$fq_class_name_lc]) && !$this->classlike_storage_provider->has($fq_class_name_lc)) {
                if (!isset($this->existing_classes_lc[$fq_class_name_lc])) {
                    $this->existing_classes_lc[$fq_class_name_lc] = \false;
                    return \false;
                }
                return $this->existing_classes_lc[$fq_class_name_lc];
            }
            return \false;
        }
        if ($this->collect_locations && $code_location) {
            $this->file_reference_provider->addCallingLocationForClass($code_location, strtolower($fq_class_name));
        }
        return \true;
    }
    public function hasFullyQualifiedInterfaceName(string $fq_class_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        $fq_class_name_lc = strtolower($this->getUnAliasedName($fq_class_name));
        if (!isset($this->existing_interfaces_lc[$fq_class_name_lc]) || !$this->existing_interfaces_lc[$fq_class_name_lc] || !$this->classlike_storage_provider->has($fq_class_name_lc)) {
            if ((!isset($this->existing_classes_lc[$fq_class_name_lc]) || $this->existing_classes_lc[$fq_class_name_lc]) && !$this->classlike_storage_provider->has($fq_class_name_lc)) {
                if (!isset($this->existing_interfaces_lc[$fq_class_name_lc])) {
                    $this->existing_interfaces_lc[$fq_class_name_lc] = \false;
                    return \false;
                }
                return $this->existing_interfaces_lc[$fq_class_name_lc];
            }
            return \false;
        }
        if ($this->collect_references && $code_location) {
            if ($calling_method_id) {
                $this->file_reference_provider->addMethodReferenceToClass($calling_method_id, $fq_class_name_lc);
            } else {
                $this->file_reference_provider->addNonMethodReferenceToClass($code_location->file_path, $fq_class_name_lc);
                if ($calling_fq_class_name) {
                    $class_storage = $this->classlike_storage_provider->get($calling_fq_class_name);
                    if ($class_storage->location && $class_storage->location->file_path !== $code_location->file_path) {
                        $this->file_reference_provider->addNonMethodReferenceToClass($class_storage->location->file_path, $fq_class_name_lc);
                    }
                }
            }
        }
        if ($this->collect_locations && $code_location) {
            $this->file_reference_provider->addCallingLocationForClass($code_location, strtolower($fq_class_name));
        }
        return \true;
    }
    public function hasFullyQualifiedEnumName(string $fq_class_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        $fq_class_name_lc = strtolower($this->getUnAliasedName($fq_class_name));
        if (!isset($this->existing_enums_lc[$fq_class_name_lc]) || !$this->existing_enums_lc[$fq_class_name_lc] || !$this->classlike_storage_provider->has($fq_class_name_lc)) {
            if ((!isset($this->existing_classes_lc[$fq_class_name_lc]) || $this->existing_classes_lc[$fq_class_name_lc]) && !$this->classlike_storage_provider->has($fq_class_name_lc)) {
                if (!isset($this->existing_enums_lc[$fq_class_name_lc])) {
                    $this->existing_enums_lc[$fq_class_name_lc] = \false;
                    return \false;
                }
                return $this->existing_enums_lc[$fq_class_name_lc];
            }
            return \false;
        }
        if ($this->collect_references && $code_location) {
            if ($calling_method_id) {
                $this->file_reference_provider->addMethodReferenceToClass($calling_method_id, $fq_class_name_lc);
            } else {
                $this->file_reference_provider->addNonMethodReferenceToClass($code_location->file_path, $fq_class_name_lc);
                if ($calling_fq_class_name) {
                    $class_storage = $this->classlike_storage_provider->get($calling_fq_class_name);
                    if ($class_storage->location && $class_storage->location->file_path !== $code_location->file_path) {
                        $this->file_reference_provider->addNonMethodReferenceToClass($class_storage->location->file_path, $fq_class_name_lc);
                    }
                }
            }
        }
        if ($this->collect_locations && $code_location) {
            $this->file_reference_provider->addCallingLocationForClass($code_location, strtolower($fq_class_name));
        }
        return \true;
    }
    public function hasFullyQualifiedTraitName(string $fq_class_name, ?CodeLocation $code_location = null) : bool
    {
        $fq_class_name_lc = strtolower($this->getUnAliasedName($fq_class_name));
        if (!isset($this->existing_traits_lc[$fq_class_name_lc]) || !$this->existing_traits_lc[$fq_class_name_lc]) {
            return \false;
        }
        if ($this->collect_references && $code_location) {
            $this->file_reference_provider->addNonMethodReferenceToClass($code_location->file_path, $fq_class_name_lc);
        }
        return \true;
    }
    /**
     * Check whether a class/interface exists
     */
    public function classOrInterfaceExists(string $fq_class_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        return $this->classExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id) || $this->interfaceExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    /**
     * Check whether a class/interface exists
     */
    public function classOrInterfaceOrEnumExists(string $fq_class_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        return $this->classExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id) || $this->interfaceExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id) || $this->enumExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    /**
     * Determine whether or not a given class exists
     */
    public function classExists(string $fq_class_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        if (isset(ClassLikeAnalyzer::SPECIAL_TYPES[$fq_class_name])) {
            return \false;
        }
        if ($fq_class_name === 'Generator') {
            return \true;
        }
        return $this->hasFullyQualifiedClassName($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    /**
     * Determine whether or not a class extends a parent
     *
     * @throws UnpopulatedClasslikeException when called on unpopulated class
     * @throws InvalidArgumentException when class does not exist
     */
    public function classExtends(string $fq_class_name, string $possible_parent, bool $from_api = \false) : bool
    {
        $unaliased_fq_class_name = $this->getUnAliasedName($fq_class_name);
        $unaliased_fq_class_name_lc = strtolower($unaliased_fq_class_name);
        if ($unaliased_fq_class_name_lc === 'generator') {
            return \false;
        }
        $class_storage = $this->classlike_storage_provider->get($unaliased_fq_class_name);
        if ($from_api && !$class_storage->populated) {
            throw new UnpopulatedClasslikeException($fq_class_name);
        }
        return isset($class_storage->parent_classes[strtolower($possible_parent)]);
    }
    /**
     * Check whether a class implements an interface
     */
    public function classImplements(string $fq_class_name, string $interface) : bool
    {
        $interface_id = strtolower($interface);
        $fq_class_name = strtolower($fq_class_name);
        if ($interface_id === 'callable' && $fq_class_name === 'closure') {
            return \true;
        }
        if ($interface_id === 'traversable' && $fq_class_name === 'generator') {
            return \true;
        }
        if ($interface_id === 'traversable' && $fq_class_name === 'iterator') {
            return \true;
        }
        if (isset(ClassLikeAnalyzer::SPECIAL_TYPES[$interface_id]) || isset(ClassLikeAnalyzer::SPECIAL_TYPES[$fq_class_name])) {
            return \false;
        }
        $fq_class_name = $this->getUnAliasedName($fq_class_name);
        if (!$this->classlike_storage_provider->has($fq_class_name)) {
            return \false;
        }
        $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        if (isset($class_storage->class_implements[$interface_id])) {
            return \true;
        }
        foreach ($class_storage->class_implements as $implementing_interface_lc => $_) {
            $aliased_interface_lc = strtolower($this->getUnAliasedName($implementing_interface_lc));
            if ($aliased_interface_lc === $interface_id) {
                return \true;
            }
        }
        return \false;
    }
    public function interfaceExists(string $fq_interface_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        if (isset(ClassLikeAnalyzer::SPECIAL_TYPES[strtolower($fq_interface_name)])) {
            return \false;
        }
        return $this->hasFullyQualifiedInterfaceName($fq_interface_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    public function enumExists(string $fq_enum_name, ?CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        if (isset(ClassLikeAnalyzer::SPECIAL_TYPES[strtolower($fq_enum_name)])) {
            return \false;
        }
        return $this->hasFullyQualifiedEnumName($fq_enum_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    public function interfaceExtends(string $interface_name, string $possible_parent) : bool
    {
        return isset($this->getParentInterfaces($interface_name)[strtolower($possible_parent)]);
    }
    /**
     * @return array<lowercase-string, string>   all interfaces extended by $interface_name
     */
    public function getParentInterfaces(string $fq_interface_name) : array
    {
        $fq_interface_name = strtolower($fq_interface_name);
        return $this->classlike_storage_provider->get($fq_interface_name)->parent_interfaces;
    }
    public function traitExists(string $fq_trait_name, ?CodeLocation $code_location = null) : bool
    {
        return $this->hasFullyQualifiedTraitName($fq_trait_name, $code_location);
    }
    /**
     * Determine whether or not a class has the correct casing
     */
    public function classHasCorrectCasing(string $fq_class_name) : bool
    {
        if ($fq_class_name === 'Generator') {
            return \true;
        }
        if (isset($this->existing_classlike_aliases[$fq_class_name])) {
            return \true;
        }
        return isset($this->existing_classes[$fq_class_name]);
    }
    public function interfaceHasCorrectCasing(string $fq_interface_name) : bool
    {
        if (isset($this->existing_classlike_aliases[$fq_interface_name])) {
            return \true;
        }
        return isset($this->existing_interfaces[$fq_interface_name]);
    }
    public function enumHasCorrectCasing(string $fq_enum_name) : bool
    {
        if (isset($this->existing_classlike_aliases[$fq_enum_name])) {
            return \true;
        }
        return isset($this->existing_enums[$fq_enum_name]);
    }
    public function traitHasCorrectCasing(string $fq_trait_name) : bool
    {
        if (isset($this->existing_classlike_aliases[$fq_trait_name])) {
            return \true;
        }
        return isset($this->existing_traits[$fq_trait_name]);
    }
    public function getTraitNode(string $fq_trait_name) : PhpParser\Node\Stmt\Trait_
    {
        $fq_trait_name_lc = strtolower($fq_trait_name);
        if (isset($this->trait_nodes[$fq_trait_name_lc])) {
            return $this->trait_nodes[$fq_trait_name_lc];
        }
        $storage = $this->classlike_storage_provider->get($fq_trait_name);
        if (!$storage->location) {
            throw new UnexpectedValueException('Storage should exist for ' . $fq_trait_name);
        }
        $file_statements = $this->statements_provider->getStatementsForFile($storage->location->file_path, ProjectAnalyzer::getInstance()->getCodebase()->analysis_php_version_id);
        $trait_finder = new TraitFinder($fq_trait_name);
        $traverser = new NodeTraverser();
        $traverser->addVisitor($trait_finder);
        $traverser->traverse($file_statements);
        $trait_node = $trait_finder->getNode();
        if ($trait_node) {
            $this->trait_nodes[$fq_trait_name_lc] = $trait_node;
            return $trait_node;
        }
        throw new UnexpectedValueException('Could not locate trait statement');
    }
    public function addClassAlias(string $fq_class_name, string $alias_name) : void
    {
        $this->classlike_aliases_map[strtolower($alias_name)] = $fq_class_name;
        $this->existing_classlike_aliases[$alias_name] = \true;
    }
    /** @psalm-mutation-free */
    public function getUnAliasedName(string $alias_name) : string
    {
        $alias_name_lc = strtolower($alias_name);
        if ($this->existing_classlikes_lc[$alias_name_lc] ?? \false) {
            return $alias_name;
        }
        $result = $this->classlike_aliases_map[$alias_name_lc] ?? $alias_name;
        if ($result === $alias_name) {
            return $result;
        }
        return $this->getUnAliasedName($result);
    }
    public function consolidateAnalyzedData(\Psalm\Internal\Codebase\Methods $methods, ?Progress $progress, bool $find_unused_code) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $progress->debug('Checking class references' . PHP_EOL);
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        foreach ($this->existing_classlikes_lc as $fq_class_name_lc => $_) {
            try {
                $classlike_storage = $this->classlike_storage_provider->get($fq_class_name_lc);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            if ($classlike_storage->location && $this->config->isInProjectDirs($classlike_storage->location->file_path) && !$classlike_storage->is_trait) {
                if ($find_unused_code) {
                    if ($classlike_storage->public_api || $this->file_reference_provider->isClassReferenced($fq_class_name_lc)) {
                        $this->checkMethodReferences($classlike_storage, $methods);
                        $this->checkPropertyReferences($classlike_storage);
                    } else {
                        IssueBuffer::maybeAdd(new UnusedClass('Class ' . $classlike_storage->name . ' is never used', $classlike_storage->location, $classlike_storage->name), $classlike_storage->suppressed_issues);
                    }
                    $this->checkMethodParamReferences($classlike_storage);
                }
                $this->findPossibleMethodParamTypes($classlike_storage);
                if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MissingImmutableAnnotation']) && !isset($codebase->analyzer->mutable_classes[$fq_class_name_lc]) && !$classlike_storage->external_mutation_free && $classlike_storage->properties && isset($classlike_storage->methods['__construct'])) {
                    $stmts = $codebase->getStatementsForFile($classlike_storage->location->file_path);
                    foreach ($stmts as $stmt) {
                        if ($stmt instanceof PhpParser\Node\Stmt\Namespace_) {
                            foreach ($stmt->stmts as $namespace_stmt) {
                                if ($namespace_stmt instanceof PhpParser\Node\Stmt\Class_ && strtolower((string) $stmt->name . '\\' . (string) $namespace_stmt->name) === $fq_class_name_lc) {
                                    self::makeImmutable($namespace_stmt, $project_analyzer, $classlike_storage->location->file_path);
                                }
                            }
                        } elseif ($stmt instanceof PhpParser\Node\Stmt\Class_ && strtolower((string) $stmt->name) === $fq_class_name_lc) {
                            self::makeImmutable($stmt, $project_analyzer, $classlike_storage->location->file_path);
                        }
                    }
                }
            }
        }
    }
    public static function makeImmutable(PhpParser\Node\Stmt\Class_ $class_stmt, ProjectAnalyzer $project_analyzer, string $file_path) : void
    {
        $manipulator = ClassDocblockManipulator::getForClass($project_analyzer, $file_path, $class_stmt);
        $manipulator->makeImmutable();
    }
    public function moveMethods(\Psalm\Internal\Codebase\Methods $methods, ?Progress $progress = null) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        if (!$codebase->methods_to_move) {
            return;
        }
        $progress->debug('Refactoring methods ' . PHP_EOL);
        $code_migrations = [];
        foreach ($codebase->methods_to_move as $source => $destination) {
            $source_parts = explode('::', $source);
            try {
                $source_method_storage = $methods->getStorage(new MethodIdentifier(...$source_parts));
            } catch (InvalidArgumentException $e) {
                continue;
            }
            [$destination_fq_class_name, $destination_name] = explode('::', $destination);
            try {
                $classlike_storage = $this->classlike_storage_provider->get($destination_fq_class_name);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            if ($classlike_storage->stmt_location && $this->config->isInProjectDirs($classlike_storage->stmt_location->file_path) && $source_method_storage->stmt_location && $source_method_storage->stmt_location->file_path && $source_method_storage->location) {
                $new_class_bounds = $classlike_storage->stmt_location->getSnippetBounds();
                $old_method_bounds = $source_method_storage->stmt_location->getSnippetBounds();
                $old_method_name_bounds = $source_method_storage->location->getSelectionBounds();
                FileManipulationBuffer::add($source_method_storage->stmt_location->file_path, [new FileManipulation($old_method_name_bounds[0], $old_method_name_bounds[1], $destination_name)]);
                $selection = $classlike_storage->stmt_location->getSnippet();
                $insert_pos = strrpos($selection, "\n", -1);
                if (!$insert_pos) {
                    $insert_pos = strlen($selection) - 1;
                } else {
                    ++$insert_pos;
                }
                $code_migrations[] = new CodeMigration($source_method_storage->stmt_location->file_path, $old_method_bounds[0], $old_method_bounds[1], $classlike_storage->stmt_location->file_path, $new_class_bounds[0] + $insert_pos);
            }
        }
        FileManipulationBuffer::addCodeMigrations($code_migrations);
    }
    public function moveProperties(\Psalm\Internal\Codebase\Properties $properties, ?Progress $progress = null) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        if (!$codebase->properties_to_move) {
            return;
        }
        $progress->debug('Refacting properties ' . PHP_EOL);
        $code_migrations = [];
        foreach ($codebase->properties_to_move as $source => $destination) {
            try {
                $source_property_storage = $properties->getStorage($source);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            [$source_fq_class_name] = explode('::$', $source);
            [$destination_fq_class_name, $destination_name] = explode('::$', $destination);
            $source_classlike_storage = $this->classlike_storage_provider->get($source_fq_class_name);
            $destination_classlike_storage = $this->classlike_storage_provider->get($destination_fq_class_name);
            if ($destination_classlike_storage->stmt_location && $this->config->isInProjectDirs($destination_classlike_storage->stmt_location->file_path) && $source_property_storage->stmt_location && $source_property_storage->stmt_location->file_path && $source_property_storage->location) {
                if ($source_property_storage->type && $source_property_storage->type_location && $source_property_storage->type_location !== $source_property_storage->signature_type_location) {
                    $bounds = $source_property_storage->type_location->getSelectionBounds();
                    $replace_type = TypeExpander::expandUnion($codebase, $source_property_storage->type, $source_classlike_storage->name, $source_classlike_storage->name, $source_classlike_storage->parent_class);
                    $this->airliftClassDefinedDocblockType($replace_type, $destination_fq_class_name, $source_property_storage->stmt_location->file_path, $bounds[0], $bounds[1]);
                }
                $new_class_bounds = $destination_classlike_storage->stmt_location->getSnippetBounds();
                $old_property_bounds = $source_property_storage->stmt_location->getSnippetBounds();
                $old_property_name_bounds = $source_property_storage->location->getSelectionBounds();
                FileManipulationBuffer::add($source_property_storage->stmt_location->file_path, [new FileManipulation($old_property_name_bounds[0], $old_property_name_bounds[1], '$' . $destination_name)]);
                $selection = $destination_classlike_storage->stmt_location->getSnippet();
                $insert_pos = strrpos($selection, "\n", -1);
                if (!$insert_pos) {
                    $insert_pos = strlen($selection) - 1;
                } else {
                    ++$insert_pos;
                }
                $code_migrations[] = new CodeMigration($source_property_storage->stmt_location->file_path, $old_property_bounds[0], $old_property_bounds[1], $destination_classlike_storage->stmt_location->file_path, $new_class_bounds[0] + $insert_pos);
            }
        }
        FileManipulationBuffer::addCodeMigrations($code_migrations);
    }
    public function moveClassConstants(?Progress $progress = null) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        if (!$codebase->class_constants_to_move) {
            return;
        }
        $progress->debug('Refacting constants ' . PHP_EOL);
        $code_migrations = [];
        foreach ($codebase->class_constants_to_move as $source => $destination) {
            [$source_fq_class_name, $source_const_name] = explode('::', $source);
            [$destination_fq_class_name, $destination_name] = explode('::', $destination);
            $source_classlike_storage = $this->classlike_storage_provider->get($source_fq_class_name);
            $destination_classlike_storage = $this->classlike_storage_provider->get($destination_fq_class_name);
            $constant_storage = $source_classlike_storage->constants[$source_const_name];
            $source_const_stmt_location = $constant_storage->stmt_location;
            $source_const_location = $constant_storage->location;
            if (!$source_const_location || !$source_const_stmt_location) {
                continue;
            }
            if ($destination_classlike_storage->stmt_location && $this->config->isInProjectDirs($destination_classlike_storage->stmt_location->file_path) && $source_const_stmt_location->file_path) {
                $new_class_bounds = $destination_classlike_storage->stmt_location->getSnippetBounds();
                $old_const_bounds = $source_const_stmt_location->getSnippetBounds();
                $old_const_name_bounds = $source_const_location->getSelectionBounds();
                FileManipulationBuffer::add($source_const_stmt_location->file_path, [new FileManipulation($old_const_name_bounds[0], $old_const_name_bounds[1], $destination_name)]);
                $selection = $destination_classlike_storage->stmt_location->getSnippet();
                $insert_pos = strrpos($selection, "\n", -1);
                if (!$insert_pos) {
                    $insert_pos = strlen($selection) - 1;
                } else {
                    ++$insert_pos;
                }
                $code_migrations[] = new CodeMigration($source_const_stmt_location->file_path, $old_const_bounds[0], $old_const_bounds[1], $destination_classlike_storage->stmt_location->file_path, $new_class_bounds[0] + $insert_pos);
            }
        }
        FileManipulationBuffer::addCodeMigrations($code_migrations);
    }
    /**
     * @param lowercase-string|null $calling_method_id
     */
    public function handleClassLikeReferenceInMigration(Codebase $codebase, StatementsSource $source, PhpParser\Node $class_name_node, string $fq_class_name, ?string $calling_method_id, bool $force_change = \false, bool $was_self = \false) : bool
    {
        if ($class_name_node instanceof VirtualNode) {
            return \false;
        }
        $calling_fq_class_name = $source->getFQCLN();
        // if we're inside a moved class static method
        if ($codebase->methods_to_move && $calling_fq_class_name && $calling_method_id && isset($codebase->methods_to_move[$calling_method_id])) {
            $destination_class = explode('::', $codebase->methods_to_move[$calling_method_id])[0];
            $intended_fq_class_name = strtolower($calling_fq_class_name) === strtolower($fq_class_name) && isset($codebase->classes_to_move[strtolower($calling_fq_class_name)]) ? $destination_class : $fq_class_name;
            $this->airliftClassLikeReference($intended_fq_class_name, $destination_class, $source->getFilePath(), (int) $class_name_node->getAttribute('startFilePos'), (int) $class_name_node->getAttribute('endFilePos') + 1, $class_name_node instanceof PhpParser\Node\Scalar\MagicConst\Class_, $was_self);
            return \true;
        }
        // if we're outside a moved class, but we're changing all references to a class
        if (isset($codebase->class_transforms[strtolower($fq_class_name)])) {
            $new_fq_class_name = $codebase->class_transforms[strtolower($fq_class_name)];
            $file_manipulations = [];
            if ($class_name_node instanceof PhpParser\Node\Identifier) {
                $destination_parts = explode('\\', $new_fq_class_name);
                $destination_class_name = array_pop($destination_parts);
                $file_manipulations[] = new FileManipulation((int) $class_name_node->getAttribute('startFilePos'), (int) $class_name_node->getAttribute('endFilePos') + 1, $destination_class_name);
                FileManipulationBuffer::add($source->getFilePath(), $file_manipulations);
                return \true;
            }
            $uses_flipped = $source->getAliasedClassesFlipped();
            $uses_flipped_replaceable = $source->getAliasedClassesFlippedReplaceable();
            $old_fq_class_name = strtolower($fq_class_name);
            $migrated_source_fqcln = $calling_fq_class_name;
            if ($calling_fq_class_name && isset($codebase->class_transforms[strtolower($calling_fq_class_name)])) {
                $migrated_source_fqcln = $codebase->class_transforms[strtolower($calling_fq_class_name)];
            }
            $source_namespace = $source->getNamespace();
            if ($migrated_source_fqcln && $calling_fq_class_name !== $migrated_source_fqcln) {
                $new_source_parts = explode('\\', $migrated_source_fqcln, -1);
                $source_namespace = implode('\\', $new_source_parts);
            }
            if (isset($uses_flipped_replaceable[$old_fq_class_name])) {
                $alias = $uses_flipped_replaceable[$old_fq_class_name];
                unset($uses_flipped[$old_fq_class_name]);
                $old_class_name_parts = explode('\\', $old_fq_class_name);
                $old_class_name = end($old_class_name_parts);
                if ($old_class_name === strtolower($alias)) {
                    $new_class_name_parts = explode('\\', $new_fq_class_name);
                    $new_class_name = end($new_class_name_parts);
                    $uses_flipped[strtolower($new_fq_class_name)] = $new_class_name;
                } else {
                    $uses_flipped[strtolower($new_fq_class_name)] = $alias;
                }
            }
            $file_manipulations[] = new FileManipulation((int) $class_name_node->getAttribute('startFilePos'), (int) $class_name_node->getAttribute('endFilePos') + 1, Type::getStringFromFQCLN($new_fq_class_name, $source_namespace, $uses_flipped, $migrated_source_fqcln, $was_self) . ($class_name_node instanceof PhpParser\Node\Scalar\MagicConst\Class_ ? '::class' : ''));
            FileManipulationBuffer::add($source->getFilePath(), $file_manipulations);
            return \true;
        }
        // if we're inside a moved class (could be a method, could be a property/class const default)
        if ($codebase->classes_to_move && $calling_fq_class_name && isset($codebase->classes_to_move[strtolower($calling_fq_class_name)])) {
            $destination_class = $codebase->classes_to_move[strtolower($calling_fq_class_name)];
            if ($class_name_node instanceof PhpParser\Node\Identifier) {
                $destination_parts = explode('\\', $destination_class);
                $destination_class_name = array_pop($destination_parts);
                $file_manipulations = [];
                $file_manipulations[] = new FileManipulation((int) $class_name_node->getAttribute('startFilePos'), (int) $class_name_node->getAttribute('endFilePos') + 1, $destination_class_name);
                FileManipulationBuffer::add($source->getFilePath(), $file_manipulations);
            } else {
                $this->airliftClassLikeReference(strtolower($calling_fq_class_name) === strtolower($fq_class_name) ? $destination_class : $fq_class_name, $destination_class, $source->getFilePath(), (int) $class_name_node->getAttribute('startFilePos'), (int) $class_name_node->getAttribute('endFilePos') + 1, $class_name_node instanceof PhpParser\Node\Scalar\MagicConst\Class_);
            }
            return \true;
        }
        if ($force_change) {
            if ($calling_fq_class_name) {
                $this->airliftClassLikeReference($fq_class_name, $calling_fq_class_name, $source->getFilePath(), (int) $class_name_node->getAttribute('startFilePos'), (int) $class_name_node->getAttribute('endFilePos') + 1);
            } else {
                $file_manipulations = [];
                $file_manipulations[] = new FileManipulation((int) $class_name_node->getAttribute('startFilePos'), (int) $class_name_node->getAttribute('endFilePos') + 1, Type::getStringFromFQCLN($fq_class_name, $source->getNamespace(), $source->getAliasedClassesFlipped(), null));
                FileManipulationBuffer::add($source->getFilePath(), $file_manipulations);
            }
            return \true;
        }
        return \false;
    }
    /**
     * @param lowercase-string|null $calling_method_id
     */
    public function handleDocblockTypeInMigration(Codebase $codebase, StatementsSource $source, Union $type, CodeLocation $type_location, ?string $calling_method_id) : void
    {
        $calling_fq_class_name = $source->getFQCLN();
        $fq_class_name_lc = strtolower($calling_fq_class_name ?? '');
        $moved_type = \false;
        // if we're inside a moved class static method
        if ($codebase->methods_to_move && $calling_fq_class_name && $calling_method_id && isset($codebase->methods_to_move[$calling_method_id])) {
            $bounds = $type_location->getSelectionBounds();
            $destination_class = explode('::', $codebase->methods_to_move[$calling_method_id])[0];
            $this->airliftClassDefinedDocblockType($type, $destination_class, $source->getFilePath(), $bounds[0], $bounds[1]);
            $moved_type = \true;
        }
        // if we're outside a moved class, but we're changing all references to a class
        if (!$moved_type && $codebase->class_transforms) {
            $uses_flipped = $source->getAliasedClassesFlipped();
            $uses_flipped_replaceable = $source->getAliasedClassesFlippedReplaceable();
            $migrated_source_fqcln = $calling_fq_class_name;
            if ($calling_fq_class_name && isset($codebase->class_transforms[$fq_class_name_lc])) {
                $migrated_source_fqcln = $codebase->class_transforms[$fq_class_name_lc];
            }
            $source_namespace = $source->getNamespace();
            if ($migrated_source_fqcln && $calling_fq_class_name !== $migrated_source_fqcln) {
                $new_source_parts = explode('\\', $migrated_source_fqcln, -1);
                $source_namespace = implode('\\', $new_source_parts);
            }
            foreach ($codebase->class_transforms as $old_fq_class_name => $new_fq_class_name) {
                if (isset($uses_flipped_replaceable[$old_fq_class_name])) {
                    $alias = $uses_flipped_replaceable[$old_fq_class_name];
                    unset($uses_flipped[$old_fq_class_name]);
                    $old_class_name_parts = explode('\\', $old_fq_class_name);
                    $old_class_name = end($old_class_name_parts);
                    if ($old_class_name === strtolower($alias)) {
                        $new_class_name_parts = explode('\\', $new_fq_class_name);
                        $new_class_name = end($new_class_name_parts);
                        $uses_flipped[strtolower($new_fq_class_name)] = $new_class_name;
                    } else {
                        $uses_flipped[strtolower($new_fq_class_name)] = $alias;
                    }
                }
            }
            foreach ($codebase->class_transforms as $old_fq_class_name => $new_fq_class_name) {
                if ($type->containsClassLike($old_fq_class_name)) {
                    $type = $type->replaceClassLike($old_fq_class_name, $new_fq_class_name);
                    $bounds = $type_location->getSelectionBounds();
                    $file_manipulations = [];
                    $file_manipulations[] = new FileManipulation($bounds[0], $bounds[1], $type->toNamespacedString($source_namespace, $uses_flipped, $migrated_source_fqcln, \false));
                    FileManipulationBuffer::add($source->getFilePath(), $file_manipulations);
                    $moved_type = \true;
                }
            }
        }
        // if we're inside a moved class (could be a method, could be a property/class const default)
        if (!$moved_type && $codebase->classes_to_move && $calling_fq_class_name && isset($codebase->classes_to_move[$fq_class_name_lc])) {
            $bounds = $type_location->getSelectionBounds();
            $destination_class = $codebase->classes_to_move[$fq_class_name_lc];
            if ($type->containsClassLike($fq_class_name_lc)) {
                $type = $type->replaceClassLike($fq_class_name_lc, $destination_class);
            }
            $this->airliftClassDefinedDocblockType($type, $destination_class, $source->getFilePath(), $bounds[0], $bounds[1]);
        }
    }
    public function airliftClassLikeReference(string $fq_class_name, string $destination_fq_class_name, string $source_file_path, int $source_start, int $source_end, bool $add_class_constant = \false, bool $allow_self = \false) : void
    {
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        $destination_class_storage = $codebase->classlike_storage_provider->get($destination_fq_class_name);
        if (!$destination_class_storage->aliases) {
            throw new UnexpectedValueException('Aliases should not be null');
        }
        $file_manipulations = [];
        $file_manipulations[] = new FileManipulation($source_start, $source_end, Type::getStringFromFQCLN($fq_class_name, $destination_class_storage->aliases->namespace, $destination_class_storage->aliases->uses_flipped, $destination_class_storage->name, $allow_self) . ($add_class_constant ? '::class' : ''));
        FileManipulationBuffer::add($source_file_path, $file_manipulations);
    }
    public function airliftClassDefinedDocblockType(Union $type, string $destination_fq_class_name, string $source_file_path, int $source_start, int $source_end) : void
    {
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        $destination_class_storage = $codebase->classlike_storage_provider->get($destination_fq_class_name);
        if (!$destination_class_storage->aliases) {
            throw new UnexpectedValueException('Aliases should not be null');
        }
        $file_manipulations = [];
        $file_manipulations[] = new FileManipulation($source_start, $source_end, $type->toNamespacedString($destination_class_storage->aliases->namespace, $destination_class_storage->aliases->uses_flipped, $destination_class_storage->name, \false));
        FileManipulationBuffer::add($source_file_path, $file_manipulations);
    }
    /**
     * @param ReflectionProperty::IS_PUBLIC|ReflectionProperty::IS_PROTECTED|ReflectionProperty::IS_PRIVATE
     *  $visibility
     * @return array<string, ClassConstantStorage>
     */
    public function getConstantsForClass(string $class_name, int $visibility) : array
    {
        $class_name = strtolower($class_name);
        $storage = $this->classlike_storage_provider->get($class_name);
        if ($visibility === ReflectionProperty::IS_PUBLIC) {
            return array_filter($storage->constants, static fn(ClassConstantStorage $constant): bool => $constant->type && $constant->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC);
        }
        if ($visibility === ReflectionProperty::IS_PROTECTED) {
            return array_filter($storage->constants, static fn(ClassConstantStorage $constant): bool => $constant->type && ($constant->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC || $constant->visibility === ClassLikeAnalyzer::VISIBILITY_PROTECTED));
        }
        return array_filter($storage->constants, static fn(ClassConstantStorage $constant): bool => $constant->type !== null);
    }
    /**
     * @param ReflectionProperty::IS_PUBLIC|ReflectionProperty::IS_PROTECTED|ReflectionProperty::IS_PRIVATE
     *  $visibility
     */
    public function getClassConstantType(string $class_name, string $constant_name, int $visibility, ?StatementsAnalyzer $statements_analyzer = null, array $visited_constant_ids = [], bool $late_static_binding = \false) : ?Union
    {
        $class_name = strtolower($class_name);
        if (!$this->classlike_storage_provider->has($class_name)) {
            return null;
        }
        $storage = $this->classlike_storage_provider->get($class_name);
        if (isset($storage->constants[$constant_name])) {
            $constant_storage = $storage->constants[$constant_name];
            if ($visibility === ReflectionProperty::IS_PUBLIC && $constant_storage->visibility !== ClassLikeAnalyzer::VISIBILITY_PUBLIC) {
                return null;
            }
            if ($visibility === ReflectionProperty::IS_PROTECTED && $constant_storage->visibility !== ClassLikeAnalyzer::VISIBILITY_PUBLIC && $constant_storage->visibility !== ClassLikeAnalyzer::VISIBILITY_PROTECTED) {
                return null;
            }
            if ($constant_storage->unresolved_node) {
                /** @psalm-suppress InaccessibleProperty Lazy resolution */
                $constant_storage->inferred_type = new Union([\Psalm\Internal\Codebase\ConstantTypeResolver::resolve($this, $constant_storage->unresolved_node, $statements_analyzer, $visited_constant_ids)]);
                if ($constant_storage->type === null || !$constant_storage->type->from_docblock) {
                    /** @psalm-suppress InaccessibleProperty Lazy resolution */
                    $constant_storage->type = $constant_storage->inferred_type;
                }
            }
            return $late_static_binding ? $constant_storage->type : $constant_storage->inferred_type ?? null;
        } elseif (isset($storage->enum_cases[$constant_name])) {
            return new Union([new TEnumCase($storage->name, $constant_name)]);
        }
        return null;
    }
    private function checkMethodReferences(ClassLikeStorage $classlike_storage, \Psalm\Internal\Codebase\Methods $methods) : void
    {
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        foreach ($classlike_storage->appearing_method_ids as $method_name => $appearing_method_id) {
            $appearing_fq_classlike_name = $appearing_method_id->fq_class_name;
            if ($appearing_fq_classlike_name !== $classlike_storage->name) {
                continue;
            }
            $method_id = $appearing_method_id;
            $declaring_classlike_storage = $classlike_storage;
            if (isset($classlike_storage->methods[$method_name])) {
                $method_storage = $classlike_storage->methods[$method_name];
            } else {
                $declaring_method_id = $classlike_storage->declaring_method_ids[$method_name];
                $declaring_fq_classlike_name = $declaring_method_id->fq_class_name;
                $declaring_method_name = $declaring_method_id->method_name;
                try {
                    $declaring_classlike_storage = $this->classlike_storage_provider->get($declaring_fq_classlike_name);
                } catch (InvalidArgumentException $e) {
                    continue;
                }
                $method_storage = $declaring_classlike_storage->methods[$declaring_method_name];
                $method_id = $declaring_method_id;
            }
            if ($classlike_storage->public_api && ($method_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC || $method_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PROTECTED && !$classlike_storage->final)) {
                continue;
            }
            if ($method_storage->location && !$project_analyzer->canReportIssues($method_storage->location->file_path) && !$codebase->analyzer->canReportIssues($method_storage->location->file_path)) {
                continue;
            }
            $method_referenced = $this->file_reference_provider->isClassMethodReferenced(strtolower((string) $method_id));
            if (!$method_referenced && $method_storage->location) {
                if ($method_name !== '__destruct' && $method_name !== '__clone' && $method_name !== '__invoke' && $method_name !== '__unset' && $method_name !== '__isset' && $method_name !== '__sleep' && $method_name !== '__wakeup' && $method_name !== '__serialize' && $method_name !== '__unserialize' && $method_name !== '__set_state' && $method_name !== '__debuginfo' && $method_name !== '__tostring') {
                    $method_location = $method_storage->location;
                    $method_id = $classlike_storage->name . '::' . $method_storage->cased_name;
                    if ($method_storage->visibility !== ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                        $has_parent_references = \false;
                        if ($codebase->classImplements($classlike_storage->name, 'Serializable') && ($method_name === 'serialize' || $method_name === 'unserialize')) {
                            continue;
                        }
                        $has_variable_calls = $codebase->analyzer->hasMixedMemberName($method_name) || $codebase->analyzer->hasMixedMemberName(strtolower($classlike_storage->name . '::'));
                        if (isset($classlike_storage->overridden_method_ids[$method_name])) {
                            foreach ($classlike_storage->overridden_method_ids[$method_name] as $parent_method_id) {
                                $parent_method_storage = $methods->getStorage($parent_method_id);
                                if ($parent_method_storage->location && !$project_analyzer->canReportIssues($parent_method_storage->location->file_path)) {
                                    // here we just don’t know
                                    $has_parent_references = \true;
                                    break;
                                }
                                $parent_method_referenced = $this->file_reference_provider->isClassMethodReferenced(strtolower((string) $parent_method_id));
                                if (!$parent_method_storage->abstract || $parent_method_referenced) {
                                    $has_parent_references = \true;
                                    break;
                                }
                            }
                        }
                        foreach ($classlike_storage->parent_classes as $parent_method_fqcln) {
                            if ($codebase->analyzer->hasMixedMemberName(strtolower($parent_method_fqcln) . '::')) {
                                $has_variable_calls = \true;
                                break;
                            }
                        }
                        foreach ($classlike_storage->class_implements as $fq_interface_name_lc => $_) {
                            try {
                                $interface_storage = $this->classlike_storage_provider->get($fq_interface_name_lc);
                            } catch (InvalidArgumentException $e) {
                                continue;
                            }
                            if ($codebase->analyzer->hasMixedMemberName($fq_interface_name_lc . '::')) {
                                $has_variable_calls = \true;
                            }
                            if (isset($interface_storage->methods[$method_name])) {
                                $interface_method_referenced = $this->file_reference_provider->isClassMethodReferenced($fq_interface_name_lc . '::' . $method_name);
                                if ($interface_method_referenced) {
                                    $has_parent_references = \true;
                                }
                            }
                        }
                        if (!$has_parent_references) {
                            $issue = new PossiblyUnusedMethod('Cannot find ' . ($has_variable_calls ? 'explicit' : 'any') . ' calls to method ' . $method_id . ($has_variable_calls ? ' (but did find some potential callers)' : ''), $method_storage->location, $method_id);
                            if ($codebase->alter_code) {
                                if ($method_storage->stmt_location && !$declaring_classlike_storage->is_trait && isset($project_analyzer->getIssuesToFix()['PossiblyUnusedMethod']) && !$has_variable_calls && !IssueBuffer::isSuppressed($issue, $method_storage->suppressed_issues)) {
                                    FileManipulationBuffer::addForCodeLocation($method_storage->stmt_location, '', \true);
                                }
                            } else {
                                IssueBuffer::maybeAdd($issue, $method_storage->suppressed_issues, $method_storage->stmt_location && !$declaring_classlike_storage->is_trait && !$has_variable_calls);
                            }
                        }
                    } elseif (!isset($classlike_storage->declaring_method_ids['__call'])) {
                        $has_variable_calls = $codebase->analyzer->hasMixedMemberName(strtolower($classlike_storage->name . '::')) || $codebase->analyzer->hasMixedMemberName($method_name);
                        if ($method_name === '__construct') {
                            $issue = new UnusedConstructor('Cannot find ' . ($has_variable_calls ? 'explicit' : 'any') . ' calls to private constructor ' . $method_id . ($has_variable_calls ? ' (but did find some potential callers)' : ''), $method_location, $method_id);
                        } else {
                            $issue = new UnusedMethod('Cannot find ' . ($has_variable_calls ? 'explicit' : 'any') . ' calls to private method ' . $method_id . ($has_variable_calls ? ' (but did find some potential callers)' : ''), $method_location, $method_id);
                        }
                        if ($codebase->alter_code) {
                            if ($method_storage->stmt_location && !$declaring_classlike_storage->is_trait && isset($project_analyzer->getIssuesToFix()['UnusedMethod']) && !$has_variable_calls && !IssueBuffer::isSuppressed($issue, $method_storage->suppressed_issues)) {
                                FileManipulationBuffer::addForCodeLocation($method_storage->stmt_location, '', \true);
                            }
                        } else {
                            IssueBuffer::maybeAdd($issue, $method_storage->suppressed_issues, $method_storage->stmt_location && !$declaring_classlike_storage->is_trait && !$has_variable_calls);
                        }
                    }
                }
            } else {
                if ($method_storage->return_type && $method_storage->return_type_location && !$method_storage->return_type->isVoid() && !$method_storage->return_type->isNever() && $method_id->method_name !== '__tostring' && ($method_storage->is_static || !$method_storage->probably_fluent)) {
                    $method_return_referenced = $this->file_reference_provider->isMethodReturnReferenced(strtolower((string) $method_id));
                    if (!$method_return_referenced) {
                        if ($method_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                            IssueBuffer::maybeAdd(new UnusedReturnValue('The return value for this private method is never used', $method_storage->return_type_location), $method_storage->suppressed_issues);
                        } else {
                            IssueBuffer::maybeAdd(new PossiblyUnusedReturnValue('The return value for this method is never used', $method_storage->return_type_location), $method_storage->suppressed_issues);
                        }
                    }
                }
            }
        }
    }
    private function checkMethodParamReferences(ClassLikeStorage $classlike_storage) : void
    {
        foreach ($classlike_storage->appearing_method_ids as $method_name => $appearing_method_id) {
            $appearing_fq_classlike_name = $appearing_method_id->fq_class_name;
            if ($appearing_fq_classlike_name !== $classlike_storage->name) {
                continue;
            }
            $method_id = $appearing_method_id;
            if (isset($classlike_storage->methods[$method_name])) {
                $method_storage = $classlike_storage->methods[$method_name];
            } else {
                $declaring_method_id = $classlike_storage->declaring_method_ids[$method_name];
                $declaring_fq_classlike_name = $declaring_method_id->fq_class_name;
                $declaring_method_name = $declaring_method_id->method_name;
                try {
                    $declaring_classlike_storage = $this->classlike_storage_provider->get($declaring_fq_classlike_name);
                } catch (InvalidArgumentException $e) {
                    continue;
                }
                $method_storage = $declaring_classlike_storage->methods[$declaring_method_name];
                $method_id = $declaring_method_id;
            }
            if ($method_storage->visibility !== ClassLikeAnalyzer::VISIBILITY_PRIVATE && !$classlike_storage->is_interface) {
                foreach ($method_storage->params as $offset => $param_storage) {
                    if (empty($classlike_storage->overridden_method_ids[$method_name]) && $param_storage->location && !$param_storage->promoted_property && !$this->file_reference_provider->isMethodParamUsed(strtolower((string) $method_id), $offset)) {
                        if ($method_storage->final) {
                            IssueBuffer::maybeAdd(new UnusedParam('Param #' . ($offset + 1) . ' is never referenced in this method', $param_storage->location), $method_storage->suppressed_issues);
                        } else {
                            IssueBuffer::maybeAdd(new PossiblyUnusedParam('Param #' . ($offset + 1) . ' is never referenced in this method', $param_storage->location), $method_storage->suppressed_issues);
                        }
                    }
                }
            }
        }
    }
    private function findPossibleMethodParamTypes(ClassLikeStorage $classlike_storage) : void
    {
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        foreach ($classlike_storage->appearing_method_ids as $method_name => $appearing_method_id) {
            $appearing_fq_classlike_name = $appearing_method_id->fq_class_name;
            if ($appearing_fq_classlike_name !== $classlike_storage->name) {
                continue;
            }
            $method_id = $appearing_method_id;
            $declaring_classlike_storage = $classlike_storage;
            if (isset($classlike_storage->methods[$method_name])) {
                $method_storage = $classlike_storage->methods[$method_name];
            } else {
                $declaring_method_id = $classlike_storage->declaring_method_ids[$method_name];
                $declaring_fq_classlike_name = $declaring_method_id->fq_class_name;
                $declaring_method_name = $declaring_method_id->method_name;
                try {
                    $declaring_classlike_storage = $this->classlike_storage_provider->get($declaring_fq_classlike_name);
                } catch (InvalidArgumentException $e) {
                    continue;
                }
                $method_storage = $declaring_classlike_storage->methods[$declaring_method_name];
                $method_id = $declaring_method_id;
            }
            if ($method_storage->location && !$project_analyzer->canReportIssues($method_storage->location->file_path) && !$codebase->analyzer->canReportIssues($method_storage->location->file_path)) {
                continue;
            }
            if ($declaring_classlike_storage->is_trait) {
                continue;
            }
            $method_id_lc = strtolower((string) $method_id);
            if (isset($codebase->analyzer->possible_method_param_types[$method_id_lc])) {
                if ($method_storage->location) {
                    $possible_param_types = $codebase->analyzer->possible_method_param_types[$method_id_lc];
                    if ($possible_param_types) {
                        foreach ($possible_param_types as $offset => $possible_type) {
                            if (!isset($method_storage->params[$offset])) {
                                continue;
                            }
                            $param_name = $method_storage->params[$offset]->name;
                            if ($possible_type->hasMixed() || $possible_type->isNull()) {
                                continue;
                            }
                            if ($method_storage->params[$offset]->default_type) {
                                if ($method_storage->params[$offset]->default_type instanceof Union) {
                                    $default_type = $method_storage->params[$offset]->default_type;
                                } else {
                                    $default_type_atomic = \Psalm\Internal\Codebase\ConstantTypeResolver::resolve($codebase->classlikes, $method_storage->params[$offset]->default_type, null);
                                    $default_type = new Union([$default_type_atomic]);
                                }
                                $possible_type = Type::combineUnionTypes($possible_type, $default_type);
                            }
                            if ($codebase->alter_code && isset($project_analyzer->getIssuesToFix()['MissingParamType'])) {
                                $function_analyzer = $project_analyzer->getFunctionLikeAnalyzer($method_id, $method_storage->location->file_path);
                                $has_variable_calls = $codebase->analyzer->hasMixedMemberName($method_name) || $codebase->analyzer->hasMixedMemberName(strtolower($classlike_storage->name . '::'));
                                if ($has_variable_calls) {
                                    $possible_type = $possible_type->setProperties(['from_docblock' => \true]);
                                }
                                if ($function_analyzer) {
                                    $function_analyzer->addOrUpdateParamType($project_analyzer, $param_name, $possible_type, $possible_type->from_docblock && $project_analyzer->only_replace_php_types_with_non_docblock_types);
                                }
                            } else {
                                IssueBuffer::addFixableIssue('MissingParamType');
                            }
                        }
                    }
                }
            }
        }
    }
    private function checkPropertyReferences(ClassLikeStorage $classlike_storage) : void
    {
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        foreach ($classlike_storage->properties as $property_name => $property_storage) {
            if ($classlike_storage->public_api && ($property_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC || $property_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PROTECTED && !$classlike_storage->final)) {
                continue;
            }
            $referenced_property_name = strtolower($classlike_storage->name) . '::$' . $property_name;
            $property_referenced = $this->file_reference_provider->isClassPropertyReferenced($referenced_property_name);
            $property_constructor_referenced = \false;
            if ($property_referenced && $property_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                $all_method_references = $this->file_reference_provider->getAllMethodReferencesToClassProperties();
                if (isset($all_method_references[$referenced_property_name]) && count($all_method_references[$referenced_property_name]) === 1) {
                    $constructor_name = strtolower($classlike_storage->name) . '::__construct';
                    $property_references = $all_method_references[$referenced_property_name];
                    $property_constructor_referenced = isset($property_references[$constructor_name]) && !$property_storage->is_static;
                }
            }
            if ((!$property_referenced || $property_constructor_referenced) && $property_storage->location) {
                $property_id = $classlike_storage->name . '::$' . $property_name;
                if ($property_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC || $property_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PROTECTED) {
                    $has_parent_references = isset($classlike_storage->overridden_property_ids[$property_name]);
                    $has_variable_calls = $codebase->analyzer->hasMixedMemberName('$' . $property_name) || $codebase->analyzer->hasMixedMemberName(strtolower($classlike_storage->name) . '::$');
                    foreach ($classlike_storage->parent_classes as $parent_method_fqcln) {
                        if ($codebase->analyzer->hasMixedMemberName(strtolower($parent_method_fqcln) . '::$')) {
                            $has_variable_calls = \true;
                            break;
                        }
                    }
                    foreach ($classlike_storage->class_implements as $fq_interface_name) {
                        if ($codebase->analyzer->hasMixedMemberName(strtolower($fq_interface_name) . '::$')) {
                            $has_variable_calls = \true;
                            break;
                        }
                    }
                    if (!$has_parent_references && ($property_storage->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC || !isset($classlike_storage->declaring_method_ids['__get']))) {
                        $issue = new PossiblyUnusedProperty('Cannot find ' . ($has_variable_calls ? 'explicit' : 'any') . ' references to property ' . $property_id . ($has_variable_calls ? ' (but did find some potential references)' : ''), $property_storage->location, $property_id);
                        if ($codebase->alter_code) {
                            if ($property_storage->stmt_location && isset($project_analyzer->getIssuesToFix()['PossiblyUnusedProperty']) && !$has_variable_calls && !IssueBuffer::isSuppressed($issue, $classlike_storage->suppressed_issues)) {
                                FileManipulationBuffer::addForCodeLocation($property_storage->stmt_location, '', \true);
                            }
                        } else {
                            IssueBuffer::maybeAdd($issue, $classlike_storage->suppressed_issues + $property_storage->suppressed_issues);
                        }
                    }
                } elseif (!isset($classlike_storage->declaring_method_ids['__get'])) {
                    $has_variable_calls = $codebase->analyzer->hasMixedMemberName('$' . $property_name);
                    $issue = new UnusedProperty('Cannot find ' . ($has_variable_calls ? 'explicit' : 'any') . ' references to private property ' . $property_id . ($has_variable_calls ? ' (but did find some potential references)' : ''), $property_storage->location, $property_id);
                    if ($codebase->alter_code) {
                        if (!$property_constructor_referenced && $property_storage->stmt_location && isset($project_analyzer->getIssuesToFix()['UnusedProperty']) && !$has_variable_calls && !IssueBuffer::isSuppressed($issue, $classlike_storage->suppressed_issues)) {
                            FileManipulationBuffer::addForCodeLocation($property_storage->stmt_location, '', \true);
                        }
                    } else {
                        IssueBuffer::maybeAdd($issue, $classlike_storage->suppressed_issues + $property_storage->suppressed_issues);
                    }
                }
            }
        }
    }
    /**
     * @param  lowercase-string $fq_classlike_name_lc
     */
    public function registerMissingClassLike(string $fq_classlike_name_lc) : void
    {
        $this->existing_classlikes_lc[$fq_classlike_name_lc] = \false;
    }
    /**
     * @param  lowercase-string $fq_classlike_name_lc
     */
    public function isMissingClassLike(string $fq_classlike_name_lc) : bool
    {
        return isset($this->existing_classlikes_lc[$fq_classlike_name_lc]) && $this->existing_classlikes_lc[$fq_classlike_name_lc] === \false;
    }
    /**
     * @param  lowercase-string $fq_classlike_name_lc
     */
    public function doesClassLikeExist(string $fq_classlike_name_lc) : bool
    {
        return isset($this->existing_classlikes_lc[$fq_classlike_name_lc]) && $this->existing_classlikes_lc[$fq_classlike_name_lc];
    }
    public function forgetMissingClassLikes() : void
    {
        $this->existing_classlikes_lc = array_filter($this->existing_classlikes_lc);
    }
    public function removeClassLike(string $fq_class_name) : void
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        unset($this->existing_classlikes_lc[$fq_class_name_lc], $this->existing_traits_lc[$fq_class_name_lc], $this->existing_traits[$fq_class_name], $this->existing_enums_lc[$fq_class_name_lc], $this->existing_enums[$fq_class_name], $this->existing_interfaces_lc[$fq_class_name_lc], $this->existing_interfaces[$fq_class_name], $this->existing_classes_lc[$fq_class_name_lc], $this->existing_classes[$fq_class_name], $this->trait_nodes[$fq_class_name_lc]);
        $this->scanner->removeClassLike($fq_class_name_lc);
    }
    /**
     * @return array{
     *     array<lowercase-string, bool>,
     *     array<lowercase-string, bool>,
     *     array<lowercase-string, bool>,
     *     array<string, bool>,
     *     array<lowercase-string, bool>,
     *     array<string, bool>,
     *     array<lowercase-string, bool>,
     *     array<string, bool>,
     *     array<string, bool>,
     * }
     */
    public function getThreadData() : array
    {
        return [$this->existing_classlikes_lc, $this->existing_classes_lc, $this->existing_traits_lc, $this->existing_traits, $this->existing_enums_lc, $this->existing_enums, $this->existing_interfaces_lc, $this->existing_interfaces, $this->existing_classes];
    }
    /**
     * @param array{
     *     0: array<lowercase-string, bool>,
     *     1: array<lowercase-string, bool>,
     *     2: array<lowercase-string, bool>,
     *     3: array<string, bool>,
     *     4: array<lowercase-string, bool>,
     *     5: array<string, bool>,
     *     6: array<lowercase-string, bool>,
     *     7: array<string, bool>,
     *     8: array<string, bool>,
     * } $thread_data
     */
    public function addThreadData(array $thread_data) : void
    {
        [$existing_classlikes_lc, $existing_classes_lc, $existing_traits_lc, $existing_traits, $existing_enums_lc, $existing_enums, $existing_interfaces_lc, $existing_interfaces, $existing_classes] = $thread_data;
        $this->existing_classlikes_lc = array_merge($existing_classlikes_lc, $this->existing_classlikes_lc);
        $this->existing_classes_lc = array_merge($existing_classes_lc, $this->existing_classes_lc);
        $this->existing_traits_lc = array_merge($existing_traits_lc, $this->existing_traits_lc);
        $this->existing_traits = array_merge($existing_traits, $this->existing_traits);
        $this->existing_enums_lc = array_merge($existing_enums_lc, $this->existing_enums_lc);
        $this->existing_enums = array_merge($existing_enums, $this->existing_enums);
        $this->existing_interfaces_lc = array_merge($existing_interfaces_lc, $this->existing_interfaces_lc);
        $this->existing_interfaces = array_merge($existing_interfaces, $this->existing_interfaces);
        $this->existing_classes = array_merge($existing_classes, $this->existing_classes);
    }
    public function getStorageFor(string $fq_class_name) : ?ClassLikeStorage
    {
        $fq_class_name = $this->getUnAliasedName($fq_class_name);
        try {
            return $this->classlike_storage_provider->get($fq_class_name);
        } catch (InvalidArgumentException $e) {
            return null;
        }
    }
}
<?php

namespace Psalm\Internal\Codebase;

use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Internal\Analyzer\SourceAnalyzer;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\MethodExistenceProvider;
use Psalm\Internal\Provider\MethodParamsProvider;
use Psalm\Internal\Provider\MethodReturnTypeProvider;
use Psalm\Internal\Provider\MethodVisibilityProvider;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Internal\TypeVisitor\TypeLocalizer;
use Psalm\StatementsSource;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\MethodStorage;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_pop;
use function assert;
use function count;
use function explode;
use function in_array;
use function is_int;
use function reset;
use function strtolower;
/**
 * @internal
 *
 * Handles information about class methods
 */
class Methods
{
    private ClassLikeStorageProvider $classlike_storage_provider;
    public bool $collect_locations = \false;
    public FileReferenceProvider $file_reference_provider;
    private \Psalm\Internal\Codebase\ClassLikes $classlikes;
    public MethodReturnTypeProvider $return_type_provider;
    public MethodParamsProvider $params_provider;
    public MethodExistenceProvider $existence_provider;
    public MethodVisibilityProvider $visibility_provider;
    public function __construct(ClassLikeStorageProvider $storage_provider, FileReferenceProvider $file_reference_provider, \Psalm\Internal\Codebase\ClassLikes $classlikes)
    {
        $this->classlike_storage_provider = $storage_provider;
        $this->file_reference_provider = $file_reference_provider;
        $this->classlikes = $classlikes;
        $this->return_type_provider = new MethodReturnTypeProvider();
        $this->existence_provider = new MethodExistenceProvider();
        $this->visibility_provider = new MethodVisibilityProvider();
        $this->params_provider = new MethodParamsProvider();
    }
    /**
     * Whether or not a given method exists
     *
     * If you pass true in $is_used argument the method return is considered used
     *
     * @param lowercase-string|null $calling_method_id
     */
    public function methodExists(MethodIdentifier $method_id, ?string $calling_method_id = null, ?CodeLocation $code_location = null, ?StatementsSource $source = null, ?string $source_file_path = null, bool $use_method_existence_provider = \true, bool $is_used = \false) : bool
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        if ($use_method_existence_provider && $this->existence_provider->has($fq_class_name)) {
            $method_exists = $this->existence_provider->doesMethodExist($fq_class_name, $method_name, $source, $code_location);
            if ($method_exists !== null) {
                return $method_exists;
            }
        }
        $old_method_id = null;
        $fq_class_name = strtolower($this->classlikes->getUnAliasedName($fq_class_name));
        try {
            $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        } catch (InvalidArgumentException $e) {
            return \false;
        }
        if ($class_storage->is_enum) {
            if ($method_name === 'cases') {
                return \true;
            }
            if ($class_storage->enum_type && in_array($method_name, ['from', 'tryFrom'], \true)) {
                return \true;
            }
        }
        $source_file_path = $source ? $source->getFilePath() : $source_file_path;
        $calling_class_name = $source ? $source->getFQCLN() : null;
        if (!$calling_class_name && $calling_method_id) {
            $calling_class_name = explode('::', $calling_method_id)[0];
        }
        if (isset($class_storage->declaring_method_ids[$method_name])) {
            $declaring_method_id = $class_storage->declaring_method_ids[$method_name];
            if ($calling_method_id === strtolower((string) $declaring_method_id)) {
                return \true;
            }
            $declaring_fq_class_name = strtolower($declaring_method_id->fq_class_name);
            if ($declaring_fq_class_name !== strtolower((string) $calling_class_name)) {
                if ($calling_method_id) {
                    $this->file_reference_provider->addMethodReferenceToClass($calling_method_id, $declaring_fq_class_name);
                } elseif ($source_file_path) {
                    $this->file_reference_provider->addNonMethodReferenceToClass($source_file_path, $declaring_fq_class_name);
                }
            }
            if ((string) $method_id !== (string) $declaring_method_id && $class_storage->user_defined && isset($class_storage->potential_declaring_method_ids[$method_name])) {
                foreach ($class_storage->potential_declaring_method_ids[$method_name] as $potential_id => $_) {
                    if ($calling_method_id) {
                        $this->file_reference_provider->addMethodReferenceToClassMember($calling_method_id, $potential_id, $is_used);
                    } elseif ($source_file_path) {
                        $this->file_reference_provider->addFileReferenceToClassMember($source_file_path, $potential_id, $is_used);
                    }
                }
            } else {
                if ($calling_method_id) {
                    $this->file_reference_provider->addMethodReferenceToClassMember($calling_method_id, strtolower((string) $declaring_method_id), $is_used);
                } elseif ($source_file_path) {
                    $this->file_reference_provider->addFileReferenceToClassMember($source_file_path, strtolower((string) $declaring_method_id), $is_used);
                }
            }
            if ($this->collect_locations && $code_location) {
                $this->file_reference_provider->addCallingLocationForClassMethod($code_location, strtolower((string) $declaring_method_id));
            }
            foreach ($class_storage->class_implements as $fq_interface_name) {
                $interface_method_id_lc = strtolower($fq_interface_name . '::' . $method_name);
                if ($this->collect_locations && $code_location) {
                    $this->file_reference_provider->addCallingLocationForClassMethod($code_location, $interface_method_id_lc);
                }
                if ($calling_method_id) {
                    $this->file_reference_provider->addMethodReferenceToClassMember($calling_method_id, $interface_method_id_lc, $is_used);
                } elseif ($source_file_path) {
                    $this->file_reference_provider->addFileReferenceToClassMember($source_file_path, $interface_method_id_lc, $is_used);
                }
            }
            $declaring_method_class = $declaring_method_id->fq_class_name;
            $declaring_method_name = $declaring_method_id->method_name;
            $declaring_class_storage = $this->classlike_storage_provider->get($declaring_method_class);
            if (isset($declaring_class_storage->overridden_method_ids[$declaring_method_name])) {
                $overridden_method_ids = $declaring_class_storage->overridden_method_ids[$declaring_method_name];
                foreach ($overridden_method_ids as $overridden_method_id) {
                    if ($this->collect_locations && $code_location) {
                        $this->file_reference_provider->addCallingLocationForClassMethod($code_location, strtolower((string) $overridden_method_id));
                    }
                    if ($calling_method_id) {
                        // also store failures in case the method is added later
                        $this->file_reference_provider->addMethodReferenceToClassMember($calling_method_id, strtolower((string) $overridden_method_id), $is_used);
                    } elseif ($source_file_path) {
                        $this->file_reference_provider->addFileReferenceToClassMember($source_file_path, strtolower((string) $overridden_method_id), $is_used);
                    }
                }
            }
            return \true;
        }
        if ($source_file_path && $fq_class_name !== strtolower((string) $calling_class_name)) {
            if ($calling_method_id) {
                $this->file_reference_provider->addMethodReferenceToClass($calling_method_id, $fq_class_name);
            } else {
                $this->file_reference_provider->addNonMethodReferenceToClass($source_file_path, $fq_class_name);
            }
        }
        if ($class_storage->abstract && isset($class_storage->overridden_method_ids[$method_name])) {
            return \true;
        }
        // support checking oldstyle constructors
        if ($method_name === '__construct') {
            $method_name_parts = explode('\\', $fq_class_name);
            $old_constructor_name = array_pop($method_name_parts);
            $old_method_id = $fq_class_name . '::' . $old_constructor_name;
        }
        if (!$class_storage->user_defined && (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $method_id) || $old_method_id && \Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap($old_method_id))) {
            return \true;
        }
        foreach ($class_storage->parent_classes + $class_storage->used_traits as $potential_future_declaring_fqcln) {
            $potential_id = strtolower($potential_future_declaring_fqcln) . '::' . $method_name;
            if ($calling_method_id) {
                // also store failures in case the method is added later
                $this->file_reference_provider->addMethodReferenceToMissingClassMember($calling_method_id, $potential_id);
            } elseif ($source_file_path) {
                $this->file_reference_provider->addFileReferenceToMissingClassMember($source_file_path, $potential_id);
            }
        }
        if ($calling_method_id) {
            // also store failures in case the method is added later
            $this->file_reference_provider->addMethodReferenceToMissingClassMember($calling_method_id, strtolower((string) $method_id));
        } elseif ($source_file_path) {
            $this->file_reference_provider->addFileReferenceToMissingClassMember($source_file_path, strtolower((string) $method_id));
        }
        return \false;
    }
    /**
     * @param  list<PhpParser\Node\Arg> $args
     * @return list<FunctionLikeParameter>
     */
    public function getMethodParams(MethodIdentifier $method_id, ?StatementsSource $source = null, ?array $args = null, ?Context $context = null) : array
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        if ($this->params_provider->has($fq_class_name)) {
            $method_params = $this->params_provider->getMethodParams($fq_class_name, $method_name, $args, $source, $context);
            if ($method_params !== null) {
                return $method_params;
            }
        }
        $declaring_method_id = $this->getDeclaringMethodId($method_id);
        $callmap_id = $declaring_method_id ?? $method_id;
        // functions
        if (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $callmap_id)) {
            $class_storage = $this->classlike_storage_provider->get($callmap_id->fq_class_name);
            $declaring_method_name = $declaring_method_id->method_name ?? $method_name;
            if (!$class_storage->stubbed || empty($class_storage->methods[$declaring_method_name]->stubbed)) {
                $function_callables = \Psalm\Internal\Codebase\InternalCallMapHandler::getCallablesFromCallMap((string) $callmap_id);
                if ($function_callables === null) {
                    throw new UnexpectedValueException('Not expecting $function_callables to be null for ' . $callmap_id);
                }
                if (!$source || $args === null || count($function_callables) === 1) {
                    assert($function_callables[0]->params !== null);
                    return $function_callables[0]->params;
                }
                if ($context && $source instanceof StatementsAnalyzer) {
                    $was_inside_call = $context->inside_call;
                    $context->inside_call = \true;
                    foreach ($args as $arg) {
                        ExpressionAnalyzer::analyze($source, $arg->value, $context);
                    }
                    $context->inside_call = $was_inside_call;
                }
                $matching_callable = \Psalm\Internal\Codebase\InternalCallMapHandler::getMatchingCallableFromCallMapOptions($source->getCodebase(), $function_callables, $args, $source->getNodeTypeProvider(), (string) $callmap_id);
                assert($matching_callable->params !== null);
                return $matching_callable->params;
            }
        }
        if ($declaring_method_id) {
            $storage = $this->getStorage($declaring_method_id);
            $params = $storage->params;
            if ($storage->has_docblock_param_types) {
                return $params;
            }
            $appearing_method_id = $this->getAppearingMethodId($declaring_method_id);
            if (!$appearing_method_id) {
                return $params;
            }
            $appearing_fq_class_name = $appearing_method_id->fq_class_name;
            $appearing_method_name = $appearing_method_id->method_name;
            $class_storage = $this->classlike_storage_provider->get($appearing_fq_class_name);
            if (!isset($class_storage->overridden_method_ids[$appearing_method_name])) {
                return $params;
            }
            if (!isset($class_storage->documenting_method_ids[$appearing_method_name])) {
                return $params;
            }
            $overridden_method_id = $class_storage->documenting_method_ids[$appearing_method_name];
            $overridden_storage = $this->getStorage($overridden_method_id);
            $overriding_fq_class_name = $overridden_method_id->fq_class_name;
            foreach ($params as $i => $param) {
                if (isset($overridden_storage->params[$i]->type) && $overridden_storage->params[$i]->has_docblock_type) {
                    $params[$i] = clone $param;
                    /** @var Union $params[$i]->type */
                    $params[$i]->type = $overridden_storage->params[$i]->type;
                    if ($source) {
                        $overridden_class_storage = $this->classlike_storage_provider->get($overriding_fq_class_name);
                        $params[$i]->type = self::localizeType($source->getCodebase(), $params[$i]->type, $appearing_fq_class_name, $overridden_class_storage->name);
                    }
                    if ($params[$i]->signature_type && $params[$i]->signature_type->isNullable()) {
                        $params[$i]->type = $params[$i]->type->getBuilder()->addType(new TNull())->freeze();
                    }
                    $params[$i]->type_location = $overridden_storage->params[$i]->type_location;
                }
            }
            return $params;
        }
        throw new UnexpectedValueException('Cannot get method params for ' . $method_id);
    }
    public static function localizeType(Codebase $codebase, Union $type, string $appearing_fq_class_name, string $base_fq_class_name) : Union
    {
        $class_storage = $codebase->classlike_storage_provider->get($appearing_fq_class_name);
        $extends = $class_storage->template_extended_params;
        if (!$extends) {
            return $type;
        }
        (new TypeLocalizer($extends, $base_fq_class_name))->traverse($type);
        return $type;
    }
    /**
     * @param array<string, array<string, Union>> $extends
     * @return list<Atomic>
     */
    public static function getExtendedTemplatedTypes(TTemplateParam $atomic_type, array $extends) : array
    {
        $extra_added_types = [];
        if (isset($extends[$atomic_type->defining_class][$atomic_type->param_name])) {
            $extended_param = $extends[$atomic_type->defining_class][$atomic_type->param_name];
            foreach ($extended_param->getAtomicTypes() as $extended_atomic_type) {
                if ($extended_atomic_type instanceof TTemplateParam) {
                    $extra_added_types = [...$extra_added_types, ...self::getExtendedTemplatedTypes($extended_atomic_type, $extends)];
                } else {
                    $extra_added_types[] = $extended_atomic_type;
                }
            }
        } else {
            $extra_added_types[] = $atomic_type;
        }
        return $extra_added_types;
    }
    public function isVariadic(MethodIdentifier $method_id) : bool
    {
        $declaring_method_id = $this->getDeclaringMethodId($method_id);
        if (!$declaring_method_id) {
            return \false;
        }
        return $this->getStorage($declaring_method_id)->variadic;
    }
    /**
     * @param  list<PhpParser\Node\Arg>|null $args
     */
    public function getMethodReturnType(MethodIdentifier $method_id, ?string &$self_class, ?SourceAnalyzer $source_analyzer = null, ?array $args = null) : ?Union
    {
        $original_fq_class_name = $method_id->fq_class_name;
        $original_method_name = $method_id->method_name;
        $adjusted_fq_class_name = $this->classlikes->getUnAliasedName($original_fq_class_name);
        if ($adjusted_fq_class_name !== $original_fq_class_name) {
            $original_fq_class_name = strtolower($adjusted_fq_class_name);
        }
        $original_class_storage = $this->classlike_storage_provider->get($original_fq_class_name);
        if (isset($original_class_storage->pseudo_methods[$original_method_name])) {
            return $original_class_storage->pseudo_methods[$original_method_name]->return_type;
        }
        $declaring_method_id = $this->getDeclaringMethodId($method_id);
        if (!$declaring_method_id) {
            return null;
        }
        $appearing_method_id = $this->getAppearingMethodId($method_id);
        if (!$appearing_method_id) {
            $class_storage = $this->classlike_storage_provider->get($original_fq_class_name);
            if ($class_storage->abstract && isset($class_storage->overridden_method_ids[$original_method_name])) {
                $appearing_method_id = reset($class_storage->overridden_method_ids[$original_method_name]);
            } else {
                return null;
            }
        }
        $appearing_fq_class_name = $appearing_method_id->fq_class_name;
        $appearing_method_name = $appearing_method_id->method_name;
        $appearing_fq_class_storage = $this->classlike_storage_provider->get($appearing_fq_class_name);
        if ($appearing_fq_class_name === 'UnitEnum' && $original_class_storage->is_enum) {
            if ($original_method_name === 'cases') {
                if ($original_class_storage->enum_cases === []) {
                    return Type::getEmptyArray();
                }
                $types = [];
                foreach ($original_class_storage->enum_cases as $case_name => $_) {
                    $types[] = new Union([new TEnumCase($original_fq_class_name, $case_name)]);
                }
                $list = new TKeyedArray($types, null, null, \true);
                return new Union([$list]);
            }
        }
        if ($appearing_fq_class_name === 'BackedEnum' && $original_class_storage->is_enum && $original_class_storage->enum_type) {
            if (($original_method_name === 'from' || $original_method_name === 'tryfrom') && $source_analyzer && isset($args[0]) && ($first_arg_type = $source_analyzer->getNodeTypeProvider()->getType($args[0]->value))) {
                $types = [];
                foreach ($original_class_storage->enum_cases as $case_name => $case_storage) {
                    if (UnionTypeComparator::isContainedBy($source_analyzer->getCodebase(), is_int($case_storage->value) ? Type::getInt(\false, $case_storage->value) : Type::getString($case_storage->value), $first_arg_type)) {
                        $types[] = new TEnumCase($original_fq_class_name, $case_name);
                    }
                }
                if ($types) {
                    if ($original_method_name === 'tryfrom') {
                        $types[] = new TNull();
                    }
                    return new Union($types);
                }
                return $original_method_name === 'tryfrom' ? Type::getNull() : Type::getNever();
            }
        }
        if (!$appearing_fq_class_storage->user_defined && !$appearing_fq_class_storage->stubbed && \Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $appearing_method_id)) {
            if ((string) $appearing_method_id === 'Closure::fromcallable' && isset($args[0]) && $source_analyzer && ($first_arg_type = $source_analyzer->getNodeTypeProvider()->getType($args[0]->value)) && $first_arg_type->isSingle()) {
                foreach ($first_arg_type->getAtomicTypes() as $atomic_type) {
                    if ($atomic_type instanceof TCallable || $atomic_type instanceof TClosure) {
                        $callable_type = $atomic_type;
                        return new Union([new TClosure('Closure', $callable_type->params, $callable_type->return_type)]);
                    }
                    if ($atomic_type instanceof TNamedObject && $this->methodExists(new MethodIdentifier($atomic_type->value, '__invoke'))) {
                        $invokable_storage = $this->getStorage(new MethodIdentifier($atomic_type->value, '__invoke'));
                        return new Union([new TClosure('Closure', $invokable_storage->params, $invokable_storage->return_type)]);
                    }
                }
            }
            $callmap_callables = \Psalm\Internal\Codebase\InternalCallMapHandler::getCallablesFromCallMap((string) $appearing_method_id);
            if (!$callmap_callables || $callmap_callables[0]->return_type === null) {
                throw new UnexpectedValueException('Shouldn’t get here');
            }
            $return_type_candidate = $callmap_callables[0]->return_type;
            if ($return_type_candidate->isFalsable()) {
                return $return_type_candidate->setProperties(['ignore_falsable_issues' => \true]);
            }
            return $return_type_candidate;
        }
        $class_storage = $this->classlike_storage_provider->get($appearing_fq_class_name);
        $storage = $this->getStorage($declaring_method_id);
        $candidate_type = $storage->return_type;
        if ($candidate_type && $candidate_type->isVoid()) {
            return $candidate_type;
        }
        if (isset($class_storage->documenting_method_ids[$appearing_method_name])) {
            $overridden_method_id = $class_storage->documenting_method_ids[$appearing_method_name];
            // special override to allow inference of Iterator types
            if ($overridden_method_id->fq_class_name === 'Iterator' && $storage->return_type && $storage->return_type === $storage->signature_return_type) {
                return $storage->return_type;
            }
            $overridden_storage = $this->getStorage($overridden_method_id);
            if ($overridden_storage->return_type) {
                if ($overridden_storage->return_type->isNull()) {
                    return Type::getVoid();
                }
                if (!$candidate_type || !$source_analyzer) {
                    $self_class = $overridden_method_id->fq_class_name;
                    return $overridden_storage->return_type;
                }
                if ($candidate_type->getId() === $overridden_storage->return_type->getId()) {
                    $self_class = $appearing_fq_class_storage->name;
                    return $candidate_type;
                }
                $overridden_class_storage = $this->classlike_storage_provider->get($overridden_method_id->fq_class_name);
                $overridden_storage_return_type = TypeExpander::expandUnion($source_analyzer->getCodebase(), $overridden_storage->return_type, $overridden_method_id->fq_class_name, $appearing_fq_class_name, $overridden_class_storage->parent_class, \true, \false, $storage->final);
                $old_contained_by_new = UnionTypeComparator::isContainedBy($source_analyzer->getCodebase(), $candidate_type, $overridden_storage_return_type);
                $new_contained_by_old = UnionTypeComparator::isContainedBy($source_analyzer->getCodebase(), $overridden_storage_return_type, $candidate_type);
                if ((!$old_contained_by_new && !$new_contained_by_old || $old_contained_by_new && $new_contained_by_old) && !$candidate_type->hasTemplate() && !$overridden_storage_return_type->hasTemplate()) {
                    $attempted_intersection = null;
                    if ($old_contained_by_new) {
                        //implicitly $new_contained_by_old as well
                        try {
                            $attempted_intersection = Type::intersectUnionTypes($candidate_type, $overridden_storage_return_type, $source_analyzer->getCodebase());
                        } catch (InvalidArgumentException $e) {
                            // TODO: fix
                        }
                    } else {
                        $attempted_intersection = Type::intersectUnionTypes($overridden_storage_return_type, $candidate_type, $source_analyzer->getCodebase());
                    }
                    if ($attempted_intersection) {
                        $self_class = $overridden_method_id->fq_class_name;
                        return $attempted_intersection;
                    }
                    $self_class = $appearing_fq_class_storage->name;
                    return $candidate_type;
                }
                if ($old_contained_by_new) {
                    $self_class = $appearing_fq_class_storage->name;
                    return $candidate_type;
                }
                $self_class = $overridden_method_id->fq_class_name;
                return $overridden_storage_return_type;
            }
        }
        if ($candidate_type) {
            $self_class = $appearing_fq_class_storage->name;
            return $candidate_type;
        }
        if (!isset($class_storage->overridden_method_ids[$appearing_method_name])) {
            return null;
        }
        $candidate_type = null;
        foreach ($class_storage->overridden_method_ids[$appearing_method_name] as $overridden_method_id) {
            $overridden_storage = $this->getStorage($overridden_method_id);
            if ($overridden_storage->return_type) {
                if ($overridden_storage->return_type->isNull()) {
                    if ($candidate_type && !$candidate_type->isVoid()) {
                        return null;
                    }
                    $candidate_type = Type::getVoid();
                    continue;
                }
                $fq_overridden_class = $overridden_method_id->fq_class_name;
                $overridden_class_storage = $this->classlike_storage_provider->get($fq_overridden_class);
                $overridden_return_type = $overridden_storage->return_type;
                $self_class = $overridden_class_storage->name;
                if ($candidate_type && $source_analyzer && !$candidate_type->isMixed()) {
                    $old_contained_by_new = UnionTypeComparator::isContainedBy($source_analyzer->getCodebase(), $candidate_type, $overridden_return_type);
                    $new_contained_by_old = UnionTypeComparator::isContainedBy($source_analyzer->getCodebase(), $overridden_return_type, $candidate_type);
                    if (!$old_contained_by_new && !$new_contained_by_old || $old_contained_by_new && $new_contained_by_old) {
                        $attempted_intersection = Type::intersectUnionTypes($candidate_type, $overridden_return_type, $source_analyzer->getCodebase());
                        if ($attempted_intersection) {
                            $candidate_type = $attempted_intersection;
                            continue;
                        }
                        return null;
                    }
                    if ($old_contained_by_new) {
                        continue;
                    }
                }
                $candidate_type = $overridden_return_type;
            }
        }
        return $candidate_type;
    }
    public function getMethodReturnsByRef(MethodIdentifier $method_id) : bool
    {
        $method_id = $this->getDeclaringMethodId($method_id);
        if (!$method_id) {
            return \false;
        }
        $fq_class_storage = $this->classlike_storage_provider->get($method_id->fq_class_name);
        if (!$fq_class_storage->user_defined && \Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $method_id)) {
            return \false;
        }
        return $this->getStorage($method_id)->returns_by_ref;
    }
    public function getMethodReturnTypeLocation(MethodIdentifier $method_id, CodeLocation &$defined_location = null) : ?CodeLocation
    {
        $method_id = $this->getDeclaringMethodId($method_id);
        if ($method_id === null) {
            return null;
        }
        $storage = $this->getStorage($method_id);
        // if function exists in stubs and in analyzed code
        // use the return type location of the analyzed code instead of the stubbed location
        if ($storage->stubbed) {
            return null;
        }
        if (!$storage->return_type_location) {
            $overridden_method_ids = $this->getOverriddenMethodIds($method_id);
            foreach ($overridden_method_ids as $overridden_method_id) {
                $overridden_storage = $this->getStorage($overridden_method_id);
                if ($overridden_storage->return_type_location && !$overridden_storage->stubbed) {
                    $defined_location = $overridden_storage->return_type_location;
                    break;
                }
            }
        }
        return $storage->return_type_location;
    }
    /**
     * @param lowercase-string $method_name_lc
     * @param lowercase-string $declaring_method_name_lc
     */
    public function setDeclaringMethodId(string $fq_class_name, string $method_name_lc, string $declaring_fq_class_name, string $declaring_method_name_lc) : void
    {
        $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        $class_storage->declaring_method_ids[$method_name_lc] = new MethodIdentifier($declaring_fq_class_name, $declaring_method_name_lc);
    }
    /**
     * @param lowercase-string $method_name_lc
     * @param lowercase-string $appearing_method_name_lc
     */
    public function setAppearingMethodId(string $fq_class_name, string $method_name_lc, string $appearing_fq_class_name, string $appearing_method_name_lc) : void
    {
        $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        $class_storage->appearing_method_ids[$method_name_lc] = new MethodIdentifier($appearing_fq_class_name, $appearing_method_name_lc);
    }
    /** @psalm-mutation-free */
    public function getDeclaringMethodId(MethodIdentifier $method_id) : ?MethodIdentifier
    {
        $fq_class_name = $this->classlikes->getUnAliasedName($method_id->fq_class_name);
        $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        $method_name = $method_id->method_name;
        if (isset($class_storage->declaring_method_ids[$method_name])) {
            return $class_storage->declaring_method_ids[$method_name];
        }
        if ($class_storage->abstract && isset($class_storage->overridden_method_ids[$method_name])) {
            return reset($class_storage->overridden_method_ids[$method_name]);
        }
        return null;
    }
    /**
     * Get the class this method appears in (vs is declared in, which could give a trait
     */
    public function getAppearingMethodId(MethodIdentifier $method_id) : ?MethodIdentifier
    {
        $fq_class_name = $this->classlikes->getUnAliasedName($method_id->fq_class_name);
        $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        $method_name = $method_id->method_name;
        return $class_storage->appearing_method_ids[$method_name] ?? null;
    }
    /**
     * @return array<string, MethodIdentifier>
     */
    public function getOverriddenMethodIds(MethodIdentifier $method_id) : array
    {
        $class_storage = $this->classlike_storage_provider->get($method_id->fq_class_name);
        $method_name = $method_id->method_name;
        return $class_storage->overridden_method_ids[$method_name] ?? [];
    }
    public function getCasedMethodId(MethodIdentifier $original_method_id) : string
    {
        $method_id = $this->getDeclaringMethodId($original_method_id);
        if ($method_id === null) {
            return (string) $original_method_id;
        }
        $fq_class_name = $method_id->fq_class_name;
        $new_method_name = $method_id->method_name;
        $old_fq_class_name = $original_method_id->fq_class_name;
        $old_method_name = $original_method_id->method_name;
        $storage = $this->getStorage($method_id);
        if ($old_method_name === $new_method_name && strtolower($old_fq_class_name) !== $old_fq_class_name) {
            return $old_fq_class_name . '::' . $storage->cased_name;
        }
        return $fq_class_name . '::' . $storage->cased_name;
    }
    public function getUserMethodStorage(MethodIdentifier $method_id) : ?MethodStorage
    {
        $declaring_method_id = $this->getDeclaringMethodId($method_id);
        if (!$declaring_method_id) {
            if (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $method_id)) {
                return null;
            }
            throw new UnexpectedValueException('$storage should not be null for ' . $method_id);
        }
        $storage = $this->getStorage($declaring_method_id);
        if (!$storage->location) {
            return null;
        }
        return $storage;
    }
    public function getClassLikeStorageForMethod(MethodIdentifier $method_id) : ClassLikeStorage
    {
        $fq_class_name = $method_id->fq_class_name;
        $method_name = $method_id->method_name;
        if ($this->existence_provider->has($fq_class_name)) {
            if ($this->existence_provider->doesMethodExist($fq_class_name, $method_name, null, null)) {
                return $this->classlike_storage_provider->get($fq_class_name);
            }
        }
        $declaring_method_id = $this->getDeclaringMethodId($method_id);
        if ($declaring_method_id === null) {
            if (\Psalm\Internal\Codebase\InternalCallMapHandler::inCallMap((string) $method_id)) {
                $declaring_method_id = $method_id;
            } else {
                throw new UnexpectedValueException('$storage should not be null for ' . $method_id);
            }
        }
        $declaring_fq_class_name = $declaring_method_id->fq_class_name;
        return $this->classlike_storage_provider->get($declaring_fq_class_name);
    }
    /** @psalm-mutation-free */
    public function getStorage(MethodIdentifier $method_id) : MethodStorage
    {
        try {
            $class_storage = $this->classlike_storage_provider->get($method_id->fq_class_name);
        } catch (InvalidArgumentException $e) {
            throw new UnexpectedValueException($e->getMessage());
        }
        $method_name = $method_id->method_name;
        if (!isset($class_storage->methods[$method_name])) {
            throw new UnexpectedValueException('$storage should not be null for ' . $method_id);
        }
        return $class_storage->methods[$method_name];
    }
    /** @psalm-mutation-free */
    public function hasStorage(MethodIdentifier $method_id) : bool
    {
        try {
            $class_storage = $this->classlike_storage_provider->get($method_id->fq_class_name);
        } catch (InvalidArgumentException $e) {
            return \false;
        }
        $method_name = $method_id->method_name;
        if (!isset($class_storage->methods[$method_name])) {
            return \false;
        }
        return \true;
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Closure;
use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\FileManipulation;
use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\FileManipulation\ClassDocblockManipulator;
use Psalm\Internal\FileManipulation\FileManipulationBuffer;
use Psalm\Internal\FileManipulation\FunctionDocblockManipulator;
use Psalm\Internal\FileManipulation\PropertyDocblockManipulator;
use Psalm\Internal\Fork\Pool;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\IssueBuffer;
use Psalm\Progress\Progress;
use Psalm\Type;
use Psalm\Type\Union;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Differ;
use _HumbugBox1cb33d1f20f1\SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder;
use UnexpectedValueException;
use function array_filter;
use function array_intersect_key;
use function array_merge;
use function array_values;
use function count;
use function explode;
use function implode;
use function intdiv;
use function ksort;
use function number_format;
use function pathinfo;
use function preg_replace;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
use function usort;
use const PATHINFO_EXTENSION;
use const PHP_INT_MAX;
/**
 * @psalm-type  TaggedCodeType = array<int, array{0: int, 1: non-empty-string}>
 *
 * @psalm-type  FileMapType = array{
 *      0: TaggedCodeType,
 *      1: TaggedCodeType,
 *      2: array<int, array{0: int, 1: non-empty-string, 2: int}>
 * }
 *
 * @psalm-type  WorkerData = array{
 *      issues: array<string, list<IssueData>>,
 *      fixable_issue_counts: array<string, int>,
 *      nonmethod_references_to_classes: array<string, array<string,bool>>,
 *      method_references_to_classes: array<string, array<string,bool>>,
 *      file_references_to_class_members: array<string, array<string,bool>>,
 *      file_references_to_class_properties: array<string, array<string,bool>>,
 *      file_references_to_method_returns: array<string, array<string,bool>>,
 *      file_references_to_missing_class_members: array<string, array<string,bool>>,
 *      mixed_counts: array<string, array{0: int, 1: int}>,
 *      mixed_member_names: array<string, array<string, bool>>,
 *      function_timings: array<string, float>,
 *      file_manipulations: array<string, FileManipulation[]>,
 *      method_references_to_class_members: array<string, array<string,bool>>,
 *      method_dependencies: array<string, array<string,bool>>,
 *      method_references_to_method_returns: array<string, array<string,bool>>,
 *      method_references_to_class_properties: array<string, array<string,bool>>,
 *      method_references_to_missing_class_members: array<string, array<string,bool>>,
 *      method_param_uses: array<string, array<int, array<string, bool>>>,
 *      analyzed_methods: array<string, array<string, int>>,
 *      file_maps: array<string, FileMapType>,
 *      class_locations: array<string, array<int, CodeLocation>>,
 *      class_method_locations: array<string, array<int, CodeLocation>>,
 *      class_property_locations: array<string, array<int, CodeLocation>>,
 *      possible_method_param_types: array<string, array<int, Union>>,
 *      taint_data: ?TaintFlowGraph,
 *      unused_suppressions: array<string, array<int, int>>,
 *      used_suppressions: array<string, array<int, bool>>,
 *      function_docblock_manipulators: array<string, array<int, FunctionDocblockManipulator>>,
 *      mutable_classes: array<string, bool>,
 * }
 */
/**
 * @internal
 *
 * Called in the analysis phase of Psalm's execution
 */
class Analyzer
{
    private Config $config;
    private FileProvider $file_provider;
    private FileStorageProvider $file_storage_provider;
    private Progress $progress;
    /**
     * Used to store counts of mixed vs non-mixed variables
     *
     * @var array<string, list{int, int}>
     */
    private array $mixed_counts = [];
    /**
     * Used to store member names of mixed property/method access
     *
     * @var array<string, array<string, bool>>
     */
    private array $mixed_member_names = [];
    private bool $count_mixed = \true;
    /**
     * Used to store debug performance data
     *
     * @var array<string, float>
     */
    private array $function_timings = [];
    /**
     * We analyze more files than we necessarily report errors in
     *
     * @var array<string, string>
     */
    private array $files_to_analyze = [];
    /**
     * We can show analysis results on more files than we analyze
     * because the results can be cached
     *
     * @var array<string, string>
     */
    private array $files_with_analysis_results = [];
    /**
     * We may update fewer files than we analyse (i.e. for dead code detection)
     *
     * @var array<string>|null
     */
    private ?array $files_to_update = null;
    /**
     * @var array<string, array<string, int>>
     */
    private array $analyzed_methods = [];
    /**
     * @var array<string, array<int, IssueData>>
     */
    private array $existing_issues = [];
    /**
     * @var array<string, array<int, array{0: int, 1: non-empty-string}>>
     */
    private array $reference_map = [];
    /**
     * @var array<string, array<int, array{0: int, 1: non-empty-string}>>
     */
    private array $type_map = [];
    /**
     * @var array<string, array<int, array{0: int, 1: non-empty-string, 2: int}>>
     */
    private array $argument_map = [];
    /**
     * @var array<string, array<int, Union>>
     */
    public array $possible_method_param_types = [];
    /**
     * @var array<string, bool>
     */
    public array $mutable_classes = [];
    public function __construct(Config $config, FileProvider $file_provider, FileStorageProvider $file_storage_provider, Progress $progress)
    {
        $this->config = $config;
        $this->file_provider = $file_provider;
        $this->file_storage_provider = $file_storage_provider;
        $this->progress = $progress;
    }
    /**
     * @param array<string, string> $files_to_analyze
     */
    public function addFilesToAnalyze(array $files_to_analyze) : void
    {
        $this->files_to_analyze += $files_to_analyze;
        $this->files_with_analysis_results += $files_to_analyze;
    }
    /**
     * @param array<string, string> $files_to_analyze
     */
    public function addFilesToShowResults(array $files_to_analyze) : void
    {
        $this->files_with_analysis_results += $files_to_analyze;
    }
    /**
     * @param array<string> $files_to_update
     */
    public function setFilesToUpdate(array $files_to_update) : void
    {
        $this->files_to_update = $files_to_update;
    }
    public function canReportIssues(string $file_path) : bool
    {
        return isset($this->files_with_analysis_results[$file_path]);
    }
    /**
     * @param  array<string, class-string<FileAnalyzer>> $filetype_analyzers
     */
    private function getFileAnalyzer(ProjectAnalyzer $project_analyzer, string $file_path, array $filetype_analyzers) : FileAnalyzer
    {
        $extension = pathinfo($file_path, PATHINFO_EXTENSION);
        $file_name = $this->config->shortenFileName($file_path);
        if (isset($filetype_analyzers[$extension])) {
            $file_analyzer = new $filetype_analyzers[$extension]($project_analyzer, $file_path, $file_name);
        } else {
            $file_analyzer = new FileAnalyzer($project_analyzer, $file_path, $file_name);
        }
        $this->progress->debug('Getting ' . $file_path . "\n");
        return $file_analyzer;
    }
    public function analyzeFiles(ProjectAnalyzer $project_analyzer, int $pool_size, bool $alter_code, bool $consolidate_analyzed_data = \false) : void
    {
        $this->loadCachedResults($project_analyzer);
        $codebase = $project_analyzer->getCodebase();
        if ($alter_code) {
            $project_analyzer->interpretRefactors();
        }
        $this->files_to_analyze = array_filter($this->files_to_analyze, [$this->file_provider, 'fileExists']);
        $this->doAnalysis($project_analyzer, $pool_size);
        $scanned_files = $codebase->scanner->getScannedFiles();
        if ($codebase->taint_flow_graph) {
            $codebase->taint_flow_graph->connectSinksAndSources();
        }
        $this->progress->finish();
        if ($consolidate_analyzed_data) {
            $project_analyzer->consolidateAnalyzedData();
        }
        foreach (IssueBuffer::getIssuesData() as $file_path => $file_issues) {
            $codebase->file_reference_provider->clearExistingIssuesForFile($file_path);
            foreach ($file_issues as $issue_data) {
                $codebase->file_reference_provider->addIssue($file_path, $issue_data);
            }
        }
        $codebase->file_reference_provider->updateReferenceCache($codebase, $scanned_files);
        if ($codebase->track_unused_suppressions) {
            IssueBuffer::processUnusedSuppressions($codebase->file_provider);
        }
        $codebase->file_reference_provider->setAnalyzedMethods($this->analyzed_methods);
        $codebase->file_reference_provider->setFileMaps($this->getFileMaps());
        $codebase->file_reference_provider->setTypeCoverage($this->mixed_counts);
        $codebase->file_reference_provider->updateReferenceCache($codebase, $scanned_files);
        if ($codebase->diff_methods) {
            $codebase->statements_provider->resetDiffs();
        }
        if ($alter_code) {
            $this->progress->startAlteringFiles();
            $project_analyzer->prepareMigration();
            $files_to_update = $this->files_to_update ?? $this->files_to_analyze;
            foreach ($files_to_update as $file_path) {
                $this->updateFile($file_path, $project_analyzer->dry_run);
            }
            $project_analyzer->migrateCode();
        }
    }
    private function doAnalysis(ProjectAnalyzer $project_analyzer, int $pool_size) : void
    {
        $this->progress->start(count($this->files_to_analyze));
        ksort($this->files_to_analyze);
        $codebase = $project_analyzer->getCodebase();
        $analysis_worker = Closure::fromCallable([$this, 'analysisWorker']);
        $task_done_closure = Closure::fromCallable([$this, 'taskDoneClosure']);
        if ($pool_size > 1 && count($this->files_to_analyze) > $pool_size) {
            $shuffle_count = $pool_size + 1;
            $file_paths = array_values($this->files_to_analyze);
            $count = count($file_paths);
            /** @var int<0, max> */
            $middle = intdiv($count, $shuffle_count);
            $remainder = $count % $shuffle_count;
            $new_file_paths = [];
            for ($i = 0; $i < $shuffle_count; $i++) {
                for ($j = 0; $j < $middle; $j++) {
                    if ($j * $shuffle_count + $i < $count) {
                        $new_file_paths[] = $file_paths[$j * $shuffle_count + $i];
                    }
                }
                if ($remainder) {
                    $new_file_paths[] = $file_paths[$middle * $shuffle_count + $remainder - 1];
                    $remainder--;
                }
            }
            $process_file_paths = [];
            $i = 0;
            foreach ($new_file_paths as $file_path) {
                $process_file_paths[$i % $pool_size][] = $file_path;
                ++$i;
            }
            // Run analysis one file at a time, splitting the set of
            // files up among a given number of child processes.
            $pool = new Pool($this->config, $process_file_paths, static function () : void {
                $project_analyzer = ProjectAnalyzer::getInstance();
                $codebase = $project_analyzer->getCodebase();
                $file_reference_provider = $codebase->file_reference_provider;
                if ($codebase->taint_flow_graph) {
                    $codebase->taint_flow_graph = new \Psalm\Internal\Codebase\TaintFlowGraph();
                }
                $file_reference_provider->setNonMethodReferencesToClasses([]);
                $file_reference_provider->setCallingMethodReferencesToClassMembers([]);
                $file_reference_provider->setCallingMethodReferencesToClassProperties([]);
                $file_reference_provider->setFileReferencesToClassMembers([]);
                $file_reference_provider->setFileReferencesToClassProperties([]);
                $file_reference_provider->setCallingMethodReferencesToMissingClassMembers([]);
                $file_reference_provider->setFileReferencesToMissingClassMembers([]);
                $file_reference_provider->setReferencesToMixedMemberNames([]);
                $file_reference_provider->setMethodParamUses([]);
            }, $analysis_worker, Closure::fromCallable([$this, 'getWorkerData']), $task_done_closure);
            $this->progress->debug('Forking analysis' . "\n");
            // Wait for all tasks to complete and collect the results.
            /**
             * @var array<int, WorkerData>
             */
            $forked_pool_data = $pool->wait();
            $this->progress->debug('Collecting forked analysis results' . "\n");
            foreach ($forked_pool_data as $pool_data) {
                IssueBuffer::addIssues($pool_data['issues']);
                IssueBuffer::addFixableIssues($pool_data['fixable_issue_counts']);
                if ($codebase->track_unused_suppressions) {
                    IssueBuffer::addUnusedSuppressions($pool_data['unused_suppressions']);
                    IssueBuffer::addUsedSuppressions($pool_data['used_suppressions']);
                }
                if ($codebase->taint_flow_graph && $pool_data['taint_data']) {
                    $codebase->taint_flow_graph->addGraph($pool_data['taint_data']);
                }
                $codebase->file_reference_provider->addNonMethodReferencesToClasses($pool_data['nonmethod_references_to_classes']);
                $codebase->file_reference_provider->addMethodReferencesToClasses($pool_data['method_references_to_classes']);
                $codebase->file_reference_provider->addFileReferencesToClassMembers($pool_data['file_references_to_class_members']);
                $codebase->file_reference_provider->addFileReferencesToClassProperties($pool_data['file_references_to_class_properties']);
                $codebase->file_reference_provider->addFileReferencesToMethodReturns($pool_data['file_references_to_method_returns']);
                $codebase->file_reference_provider->addMethodReferencesToClassMembers($pool_data['method_references_to_class_members']);
                $codebase->file_reference_provider->addMethodDependencies($pool_data['method_dependencies']);
                $codebase->file_reference_provider->addMethodReferencesToClassProperties($pool_data['method_references_to_class_properties']);
                $codebase->file_reference_provider->addMethodReferencesToMethodReturns($pool_data['method_references_to_method_returns']);
                $codebase->file_reference_provider->addFileReferencesToMissingClassMembers($pool_data['file_references_to_missing_class_members']);
                $codebase->file_reference_provider->addMethodReferencesToMissingClassMembers($pool_data['method_references_to_missing_class_members']);
                $codebase->file_reference_provider->addMethodParamUses($pool_data['method_param_uses']);
                $this->addMixedMemberNames($pool_data['mixed_member_names']);
                $this->function_timings += $pool_data['function_timings'];
                $codebase->file_reference_provider->addClassLocations($pool_data['class_locations']);
                $codebase->file_reference_provider->addClassMethodLocations($pool_data['class_method_locations']);
                $codebase->file_reference_provider->addClassPropertyLocations($pool_data['class_property_locations']);
                $this->mutable_classes = array_merge($this->mutable_classes, $pool_data['mutable_classes']);
                FunctionDocblockManipulator::addManipulators($pool_data['function_docblock_manipulators']);
                $this->analyzed_methods = array_merge($pool_data['analyzed_methods'], $this->analyzed_methods);
                foreach ($pool_data['mixed_counts'] as $file_path => [$mixed_count, $nonmixed_count]) {
                    if (!isset($this->mixed_counts[$file_path])) {
                        $this->mixed_counts[$file_path] = [$mixed_count, $nonmixed_count];
                    } else {
                        $this->mixed_counts[$file_path][0] += $mixed_count;
                        $this->mixed_counts[$file_path][1] += $nonmixed_count;
                    }
                }
                foreach ($pool_data['possible_method_param_types'] as $declaring_method_id => $possible_param_types) {
                    if (!isset($this->possible_method_param_types[$declaring_method_id])) {
                        $this->possible_method_param_types[$declaring_method_id] = $possible_param_types;
                    } else {
                        foreach ($possible_param_types as $offset => $possible_param_type) {
                            $this->possible_method_param_types[$declaring_method_id][$offset] = Type::combineUnionTypes($this->possible_method_param_types[$declaring_method_id][$offset] ?? null, $possible_param_type, $codebase);
                        }
                    }
                }
                foreach ($pool_data['file_manipulations'] as $file_path => $manipulations) {
                    FileManipulationBuffer::add($file_path, $manipulations);
                }
                foreach ($pool_data['file_maps'] as $file_path => $file_maps) {
                    [$reference_map, $type_map, $argument_map] = $file_maps;
                    $this->reference_map[$file_path] = $reference_map;
                    $this->type_map[$file_path] = $type_map;
                    $this->argument_map[$file_path] = $argument_map;
                }
            }
            if ($pool->didHaveError()) {
                exit(1);
            }
        } else {
            $i = 0;
            foreach ($this->files_to_analyze as $file_path => $_) {
                $analysis_worker($i, $file_path);
                ++$i;
                $issues = IssueBuffer::getIssuesDataForFile($file_path);
                $task_done_closure($issues);
            }
        }
    }
    /**
     * @psalm-suppress ComplexMethod
     */
    public function loadCachedResults(ProjectAnalyzer $project_analyzer) : void
    {
        $codebase = $project_analyzer->getCodebase();
        if ($codebase->diff_methods) {
            $this->analyzed_methods = $codebase->file_reference_provider->getAnalyzedMethods();
            $this->existing_issues = $codebase->file_reference_provider->getExistingIssues();
            $file_maps = $codebase->file_reference_provider->getFileMaps();
            foreach ($file_maps as $file_path => [$reference_map, $type_map, $argument_map]) {
                $this->reference_map[$file_path] = $reference_map;
                $this->type_map[$file_path] = $type_map;
                $this->argument_map[$file_path] = $argument_map;
            }
        }
        $statements_provider = $codebase->statements_provider;
        $file_reference_provider = $codebase->file_reference_provider;
        $changed_members = $statements_provider->getChangedMembers();
        $unchanged_signature_members = $statements_provider->getUnchangedSignatureMembers();
        $errored_files = $statements_provider->getErrors();
        $diff_map = $statements_provider->getDiffMap();
        $deletion_ranges = $statements_provider->getDeletionRanges();
        $method_references_to_class_members = $file_reference_provider->getAllMethodReferencesToClassMembers();
        $method_dependencies = $file_reference_provider->getAllMethodDependencies();
        $method_references_to_class_properties = $file_reference_provider->getAllMethodReferencesToClassProperties();
        $method_references_to_method_returns = $file_reference_provider->getAllMethodReferencesToMethodReturns();
        $method_references_to_missing_class_members = $file_reference_provider->getAllMethodReferencesToMissingClassMembers();
        $all_referencing_methods = $method_references_to_class_members + $method_references_to_missing_class_members + $method_dependencies;
        $nonmethod_references_to_classes = $file_reference_provider->getAllNonMethodReferencesToClasses();
        $method_references_to_classes = $file_reference_provider->getAllMethodReferencesToClasses();
        $method_param_uses = $file_reference_provider->getAllMethodParamUses();
        $file_references_to_class_members = $file_reference_provider->getAllFileReferencesToClassMembers();
        $file_references_to_class_properties = $file_reference_provider->getAllFileReferencesToClassProperties();
        $file_references_to_method_returns = $file_reference_provider->getAllFileReferencesToMethodReturns();
        $file_references_to_missing_class_members = $file_reference_provider->getAllFileReferencesToMissingClassMembers();
        $references_to_mixed_member_names = $file_reference_provider->getAllReferencesToMixedMemberNames();
        $this->mixed_counts = $file_reference_provider->getTypeCoverage();
        foreach ($changed_members as $file_path => $members_by_file) {
            foreach ($members_by_file as $changed_member => $_) {
                if (!strpos($changed_member, '&')) {
                    continue;
                }
                [$base_class, $trait] = explode('&', $changed_member);
                foreach ($all_referencing_methods as $member_id => $_) {
                    if (strpos($member_id, $base_class . '::') !== 0) {
                        continue;
                    }
                    $member_bit = substr($member_id, strlen($base_class) + 2);
                    if (isset($all_referencing_methods[$trait . '::' . $member_bit])) {
                        $changed_members[$file_path][$member_id] = \true;
                    }
                }
            }
        }
        $newly_invalidated_methods = [];
        foreach ($unchanged_signature_members as $file_unchanged_signature_members) {
            $newly_invalidated_methods = array_merge($newly_invalidated_methods, $file_unchanged_signature_members);
            foreach ($file_unchanged_signature_members as $unchanged_signature_member_id => $_) {
                // also check for things that might invalidate constructor property initialisation
                if (isset($all_referencing_methods[$unchanged_signature_member_id])) {
                    foreach ($all_referencing_methods[$unchanged_signature_member_id] as $referencing_method_id => $_) {
                        if (substr($referencing_method_id, -13) === '::__construct') {
                            $referencing_base_classlike = explode('::', $referencing_method_id)[0];
                            $unchanged_signature_classlike = explode('::', $unchanged_signature_member_id)[0];
                            if ($referencing_base_classlike === $unchanged_signature_classlike) {
                                $newly_invalidated_methods[$referencing_method_id] = \true;
                            } else {
                                try {
                                    $referencing_storage = $codebase->classlike_storage_provider->get($referencing_base_classlike);
                                } catch (InvalidArgumentException $_) {
                                    // Workaround for #3671
                                    $newly_invalidated_methods[$referencing_method_id] = \true;
                                    $referencing_storage = null;
                                }
                                if (isset($referencing_storage->used_traits[$unchanged_signature_classlike]) || isset($referencing_storage->parent_classes[$unchanged_signature_classlike])) {
                                    $newly_invalidated_methods[$referencing_method_id] = \true;
                                }
                            }
                        }
                    }
                }
            }
        }
        foreach ($changed_members as $file_changed_members) {
            foreach ($file_changed_members as $member_id => $_) {
                $newly_invalidated_methods[$member_id] = \true;
                if (isset($all_referencing_methods[$member_id])) {
                    $newly_invalidated_methods = array_merge($all_referencing_methods[$member_id], $newly_invalidated_methods);
                }
                unset($method_references_to_class_members[$member_id], $method_dependencies[$member_id], $method_references_to_class_properties[$member_id], $method_references_to_method_returns[$member_id], $file_references_to_class_members[$member_id], $file_references_to_class_properties[$member_id], $file_references_to_method_returns[$member_id], $method_references_to_missing_class_members[$member_id], $file_references_to_missing_class_members[$member_id], $references_to_mixed_member_names[$member_id], $method_param_uses[$member_id]);
                $member_stub = preg_replace('/::.*$/', '::*', $member_id, 1);
                if (isset($all_referencing_methods[$member_stub])) {
                    $newly_invalidated_methods = array_merge($all_referencing_methods[$member_stub], $newly_invalidated_methods);
                }
            }
        }
        foreach ($newly_invalidated_methods as $method_id => $_) {
            foreach ($method_references_to_class_members as $i => $_) {
                unset($method_references_to_class_members[$i][$method_id]);
            }
            foreach ($method_dependencies as $i => $_) {
                unset($method_dependencies[$i][$method_id]);
            }
            foreach ($method_references_to_class_properties as $i => $_) {
                unset($method_references_to_class_properties[$i][$method_id]);
            }
            foreach ($method_references_to_method_returns as $i => $_) {
                unset($method_references_to_method_returns[$i][$method_id]);
            }
            foreach ($method_references_to_classes as $i => $_) {
                unset($method_references_to_classes[$i][$method_id]);
            }
            foreach ($method_references_to_missing_class_members as $i => $_) {
                unset($method_references_to_missing_class_members[$i][$method_id]);
            }
            foreach ($references_to_mixed_member_names as $i => $_) {
                unset($references_to_mixed_member_names[$i][$method_id]);
            }
            foreach ($method_param_uses as $i => $_) {
                foreach ($method_param_uses[$i] as $j => $_) {
                    unset($method_param_uses[$i][$j][$method_id]);
                }
            }
        }
        foreach ($errored_files as $file_path => $_) {
            unset($this->analyzed_methods[$file_path]);
            unset($this->existing_issues[$file_path]);
        }
        foreach ($this->analyzed_methods as $file_path => $analyzed_methods) {
            foreach ($analyzed_methods as $correct_method_id => $_) {
                $trait_safe_method_id = $correct_method_id;
                $correct_method_ids = explode('&', $correct_method_id);
                $correct_method_id = $correct_method_ids[0];
                if (isset($newly_invalidated_methods[$correct_method_id]) || isset($correct_method_ids[1]) && isset($newly_invalidated_methods[$correct_method_ids[1]])) {
                    unset($this->analyzed_methods[$file_path][$trait_safe_method_id]);
                }
            }
        }
        $this->shiftFileOffsets($diff_map, $deletion_ranges);
        foreach ($this->files_to_analyze as $file_path) {
            $file_reference_provider->clearExistingIssuesForFile($file_path);
            $file_reference_provider->clearExistingFileMapsForFile($file_path);
            $this->setMixedCountsForFile($file_path, [0, 0]);
            foreach ($file_references_to_class_members as $i => $_) {
                unset($file_references_to_class_members[$i][$file_path]);
            }
            foreach ($file_references_to_class_properties as $i => $_) {
                unset($file_references_to_class_properties[$i][$file_path]);
            }
            foreach ($file_references_to_method_returns as $i => $_) {
                unset($file_references_to_method_returns[$i][$file_path]);
            }
            foreach ($nonmethod_references_to_classes as $i => $_) {
                unset($nonmethod_references_to_classes[$i][$file_path]);
            }
            foreach ($references_to_mixed_member_names as $i => $_) {
                unset($references_to_mixed_member_names[$i][$file_path]);
            }
            foreach ($file_references_to_missing_class_members as $i => $_) {
                unset($file_references_to_missing_class_members[$i][$file_path]);
            }
        }
        foreach ($this->existing_issues as $file_path => $issues) {
            if (!isset($this->files_to_analyze[$file_path])) {
                unset($this->existing_issues[$file_path]);
                if ($this->file_provider->fileExists($file_path)) {
                    IssueBuffer::addIssues([$file_path => array_values($issues)]);
                }
            }
        }
        $method_references_to_class_members = array_filter($method_references_to_class_members);
        $method_dependencies = array_filter($method_dependencies);
        $method_references_to_class_properties = array_filter($method_references_to_class_properties);
        $method_references_to_method_returns = array_filter($method_references_to_method_returns);
        $method_references_to_missing_class_members = array_filter($method_references_to_missing_class_members);
        $file_references_to_class_members = array_filter($file_references_to_class_members);
        $file_references_to_class_properties = array_filter($file_references_to_class_properties);
        $file_references_to_method_returns = array_filter($file_references_to_method_returns);
        $file_references_to_missing_class_members = array_filter($file_references_to_missing_class_members);
        $references_to_mixed_member_names = array_filter($references_to_mixed_member_names);
        $nonmethod_references_to_classes = array_filter($nonmethod_references_to_classes);
        $method_references_to_classes = array_filter($method_references_to_classes);
        $method_param_uses = array_filter($method_param_uses);
        $file_reference_provider->setCallingMethodReferencesToClassMembers($method_references_to_class_members);
        $file_reference_provider->setMethodDependencies($method_dependencies);
        $file_reference_provider->setCallingMethodReferencesToClassProperties($method_references_to_class_properties);
        $file_reference_provider->setCallingMethodReferencesToMethodReturns($method_references_to_method_returns);
        $file_reference_provider->setFileReferencesToClassMembers($file_references_to_class_members);
        $file_reference_provider->setFileReferencesToClassProperties($file_references_to_class_properties);
        $file_reference_provider->setFileReferencesToMethodReturns($file_references_to_method_returns);
        $file_reference_provider->setCallingMethodReferencesToMissingClassMembers($method_references_to_missing_class_members);
        $file_reference_provider->setFileReferencesToMissingClassMembers($file_references_to_missing_class_members);
        $file_reference_provider->setReferencesToMixedMemberNames($references_to_mixed_member_names);
        $file_reference_provider->setCallingMethodReferencesToClasses($method_references_to_classes);
        $file_reference_provider->setNonMethodReferencesToClasses($nonmethod_references_to_classes);
        $file_reference_provider->setMethodParamUses($method_param_uses);
    }
    /**
     * @param array<string, array<int, array{int, int, int, int}>> $diff_map
     * @param array<string, array<int, array{int, int}>> $deletion_ranges
     */
    public function shiftFileOffsets(array $diff_map, array $deletion_ranges) : void
    {
        foreach ($this->existing_issues as $file_path => $file_issues) {
            if (!isset($this->analyzed_methods[$file_path])) {
                continue;
            }
            $file_diff_map = $diff_map[$file_path] ?? [];
            $file_deletion_ranges = $deletion_ranges[$file_path] ?? [];
            if ($file_deletion_ranges) {
                foreach ($file_issues as $i => $issue_data) {
                    foreach ($file_deletion_ranges as [$from, $to]) {
                        if ($issue_data->from >= $from && $issue_data->from <= $to) {
                            unset($this->existing_issues[$file_path][$i]);
                            break;
                        }
                    }
                }
            }
            if ($file_diff_map) {
                foreach ($file_issues as $issue_data) {
                    foreach ($file_diff_map as [$from, $to, $file_offset, $line_offset]) {
                        if ($issue_data->from >= $from && $issue_data->from <= $to) {
                            $issue_data->from += $file_offset;
                            $issue_data->to += $file_offset;
                            $issue_data->snippet_from += $file_offset;
                            $issue_data->snippet_to += $file_offset;
                            $issue_data->line_from += $line_offset;
                            $issue_data->line_to += $line_offset;
                            break;
                        }
                    }
                }
            }
        }
        foreach ($this->reference_map as $file_path => $reference_map) {
            if (!isset($this->analyzed_methods[$file_path])) {
                unset($this->reference_map[$file_path]);
                continue;
            }
            $file_diff_map = $diff_map[$file_path] ?? [];
            $file_deletion_ranges = $deletion_ranges[$file_path] ?? [];
            if ($file_deletion_ranges) {
                foreach ($reference_map as $reference_from => $_) {
                    foreach ($file_deletion_ranges as [$from, $to]) {
                        if ($reference_from >= $from && $reference_from <= $to) {
                            unset($this->reference_map[$file_path][$reference_from]);
                            break;
                        }
                    }
                }
            }
            if ($file_diff_map) {
                foreach ($reference_map as $reference_from => [$reference_to, $tag]) {
                    foreach ($file_diff_map as [$from, $to, $file_offset]) {
                        if ($reference_from >= $from && $reference_from <= $to) {
                            unset($this->reference_map[$file_path][$reference_from]);
                            $this->reference_map[$file_path][$reference_from + $file_offset] = [$reference_to + $file_offset, $tag];
                            break;
                        }
                    }
                }
            }
        }
        foreach ($this->type_map as $file_path => $type_map) {
            if (!isset($this->analyzed_methods[$file_path])) {
                unset($this->type_map[$file_path]);
                continue;
            }
            $file_diff_map = $diff_map[$file_path] ?? [];
            $file_deletion_ranges = $deletion_ranges[$file_path] ?? [];
            if ($file_deletion_ranges) {
                foreach ($type_map as $type_from => $_) {
                    foreach ($file_deletion_ranges as [$from, $to]) {
                        if ($type_from >= $from && $type_from <= $to) {
                            unset($this->type_map[$file_path][$type_from]);
                            break;
                        }
                    }
                }
            }
            if ($file_diff_map) {
                foreach ($type_map as $type_from => [$type_to, $tag]) {
                    foreach ($file_diff_map as [$from, $to, $file_offset]) {
                        if ($type_from >= $from && $type_from <= $to) {
                            unset($this->type_map[$file_path][$type_from]);
                            $this->type_map[$file_path][$type_from + $file_offset] = [$type_to + $file_offset, $tag];
                            break;
                        }
                    }
                }
            }
        }
        foreach ($this->argument_map as $file_path => $argument_map) {
            if (!isset($this->analyzed_methods[$file_path])) {
                unset($this->argument_map[$file_path]);
                continue;
            }
            $file_diff_map = $diff_map[$file_path] ?? [];
            $file_deletion_ranges = $deletion_ranges[$file_path] ?? [];
            if ($file_deletion_ranges) {
                foreach ($argument_map as $argument_from => $_) {
                    foreach ($file_deletion_ranges as [$from, $to]) {
                        if ($argument_from >= $from && $argument_from <= $to) {
                            unset($argument_map[$argument_from]);
                            break;
                        }
                    }
                }
            }
            if ($file_diff_map) {
                foreach ($argument_map as $argument_from => [$argument_to, $method_id, $argument_number]) {
                    foreach ($file_diff_map as [$from, $to, $file_offset]) {
                        if ($argument_from >= $from && $argument_from <= $to) {
                            unset($this->argument_map[$file_path][$argument_from]);
                            $this->argument_map[$file_path][$argument_from + $file_offset] = [$argument_to + $file_offset, $method_id, $argument_number];
                            break;
                        }
                    }
                }
            }
        }
    }
    /**
     * @return array<string, array<string, bool>>
     */
    public function getMixedMemberNames() : array
    {
        return $this->mixed_member_names;
    }
    public function addMixedMemberName(string $member_id, string $reference) : void
    {
        $this->mixed_member_names[$member_id][$reference] = \true;
    }
    public function hasMixedMemberName(string $member_id) : bool
    {
        return isset($this->mixed_member_names[$member_id]);
    }
    /**
     * @param array<string, array<string, bool>> $names
     */
    public function addMixedMemberNames(array $names) : void
    {
        foreach ($names as $key => $name) {
            if (isset($this->mixed_member_names[$key])) {
                $this->mixed_member_names[$key] = array_merge($this->mixed_member_names[$key], $name);
            } else {
                $this->mixed_member_names[$key] = $name;
            }
        }
    }
    /**
     * @return list{int, int}
     */
    public function getMixedCountsForFile(string $file_path) : array
    {
        if (!isset($this->mixed_counts[$file_path])) {
            $this->mixed_counts[$file_path] = [0, 0];
        }
        return $this->mixed_counts[$file_path];
    }
    /**
     * @param  list{int, int} $mixed_counts
     */
    public function setMixedCountsForFile(string $file_path, array $mixed_counts) : void
    {
        $this->mixed_counts[$file_path] = $mixed_counts;
    }
    public function incrementMixedCount(string $file_path) : void
    {
        if (!$this->count_mixed) {
            return;
        }
        if (!isset($this->mixed_counts[$file_path])) {
            $this->mixed_counts[$file_path] = [0, 0];
        }
        ++$this->mixed_counts[$file_path][0];
    }
    public function decrementMixedCount(string $file_path) : void
    {
        if (!$this->count_mixed) {
            return;
        }
        if (!isset($this->mixed_counts[$file_path])) {
            return;
        }
        if ($this->mixed_counts[$file_path][0] === 0) {
            return;
        }
        --$this->mixed_counts[$file_path][0];
    }
    public function incrementNonMixedCount(string $file_path) : void
    {
        if (!$this->count_mixed) {
            return;
        }
        if (!isset($this->mixed_counts[$file_path])) {
            $this->mixed_counts[$file_path] = [0, 0];
        }
        ++$this->mixed_counts[$file_path][1];
    }
    /**
     * @return array<string, array{0: int, 1: int}>
     */
    public function getMixedCounts() : array
    {
        $all_deep_scanned_files = [];
        foreach ($this->files_to_analyze as $file_path => $_) {
            $all_deep_scanned_files[$file_path] = \true;
        }
        return array_intersect_key($this->mixed_counts, $all_deep_scanned_files);
    }
    /**
     * @return array<string, float>
     */
    public function getFunctionTimings() : array
    {
        return $this->function_timings;
    }
    public function addFunctionTiming(string $function_id, float $time_per_node) : void
    {
        $this->function_timings[$function_id] = $time_per_node;
    }
    public function addNodeType(string $file_path, PhpParser\Node $node, string $node_type, PhpParser\Node $parent_node = null) : void
    {
        if ($node_type === '') {
            throw new UnexpectedValueException('non-empty node_type expected');
        }
        $this->type_map[$file_path][(int) $node->getAttribute('startFilePos')] = [($parent_node ? (int) $parent_node->getAttribute('endFilePos') : (int) $node->getAttribute('endFilePos')) + 1, $node_type];
    }
    public function addNodeArgument(string $file_path, int $start_position, int $end_position, string $reference, int $argument_number) : void
    {
        if ($reference === '') {
            throw new UnexpectedValueException('non-empty reference expected');
        }
        $this->argument_map[$file_path][$start_position] = [$end_position, $reference, $argument_number];
    }
    /**
     * @param string $reference The symbol name for the reference.
     *                          Prepend with an asterisk (*) to signify a reference that doesn't exist.
     */
    public function addNodeReference(string $file_path, PhpParser\Node $node, string $reference) : void
    {
        if (!$reference) {
            throw new UnexpectedValueException('non-empty node_type expected');
        }
        $this->reference_map[$file_path][(int) $node->getAttribute('startFilePos')] = [(int) $node->getAttribute('endFilePos') + 1, $reference];
    }
    public function addOffsetReference(string $file_path, int $start, int $end, string $reference) : void
    {
        if (!$reference) {
            throw new UnexpectedValueException('non-empty node_type expected');
        }
        $this->reference_map[$file_path][$start] = [$end, $reference];
    }
    /**
     * @return array{int, int}
     */
    public function getTotalTypeCoverage(Codebase $codebase) : array
    {
        $mixed_count = 0;
        $nonmixed_count = 0;
        foreach ($codebase->file_reference_provider->getTypeCoverage() as $file_path => $counts) {
            if (!$this->config->reportTypeStatsForFile($file_path)) {
                continue;
            }
            [$path_mixed_count, $path_nonmixed_count] = $counts;
            if (isset($this->mixed_counts[$file_path])) {
                $mixed_count += $path_mixed_count;
                $nonmixed_count += $path_nonmixed_count;
            }
        }
        return [$mixed_count, $nonmixed_count];
    }
    public function getTypeInferenceSummary(Codebase $codebase) : string
    {
        $all_deep_scanned_files = [];
        foreach ($this->files_to_analyze as $file_path => $_) {
            $all_deep_scanned_files[$file_path] = \true;
            foreach ($this->file_storage_provider->get($file_path)->required_file_paths as $required_file_path) {
                $all_deep_scanned_files[$required_file_path] = \true;
            }
        }
        [$mixed_count, $nonmixed_count] = $this->getTotalTypeCoverage($codebase);
        $total = $mixed_count + $nonmixed_count;
        $total_files = count($all_deep_scanned_files);
        $lines = [];
        if (!$total_files) {
            $lines[] = 'No files analyzed';
        }
        if (!$total) {
            $lines[] = 'Psalm was unable to infer types in the codebase';
        } else {
            $percentage = $nonmixed_count === $total ? '100' : number_format(100 * $nonmixed_count / $total, 4);
            $lines[] = 'Psalm was able to infer types for ' . $percentage . '%' . ' of the codebase';
        }
        return implode("\n", $lines);
    }
    public function getNonMixedStats() : string
    {
        $stats = '';
        $all_deep_scanned_files = [];
        foreach ($this->files_to_analyze as $file_path => $_) {
            $all_deep_scanned_files[$file_path] = \true;
            if (!$this->config->reportTypeStatsForFile($file_path)) {
                continue;
            }
            foreach ($this->file_storage_provider->get($file_path)->required_file_paths as $required_file_path) {
                $all_deep_scanned_files[$required_file_path] = \true;
            }
        }
        foreach ($all_deep_scanned_files as $file_path => $_) {
            if (isset($this->mixed_counts[$file_path])) {
                [$path_mixed_count, $path_nonmixed_count] = $this->mixed_counts[$file_path];
                if ($path_mixed_count + $path_nonmixed_count) {
                    $stats .= number_format(100 * $path_nonmixed_count / ($path_mixed_count + $path_nonmixed_count), 3) . '% ' . $this->config->shortenFileName($file_path) . ' (' . $path_mixed_count . ' mixed)' . "\n";
                }
            }
        }
        return $stats;
    }
    public function disableMixedCounts() : void
    {
        $this->count_mixed = \false;
    }
    public function enableMixedCounts() : void
    {
        $this->count_mixed = \true;
    }
    public function updateFile(string $file_path, bool $dry_run) : void
    {
        FileManipulationBuffer::add($file_path, FunctionDocblockManipulator::getManipulationsForFile($file_path));
        FileManipulationBuffer::add($file_path, PropertyDocblockManipulator::getManipulationsForFile($file_path));
        FileManipulationBuffer::add($file_path, ClassDocblockManipulator::getManipulationsForFile($file_path));
        $file_manipulations = FileManipulationBuffer::getManipulationsForFile($file_path);
        if (!$file_manipulations) {
            return;
        }
        usort($file_manipulations, static function (FileManipulation $a, FileManipulation $b) : int {
            if ($b->end === $a->end) {
                if ($a->start === $b->start) {
                    return $b->insertion_text > $a->insertion_text ? 1 : -1;
                }
                return $b->start > $a->start ? 1 : -1;
            }
            return $b->end > $a->end ? 1 : -1;
        });
        $last_start = PHP_INT_MAX;
        $existing_contents = $this->file_provider->getContents($file_path);
        foreach ($file_manipulations as $manipulation) {
            if ($manipulation->start <= $last_start) {
                $existing_contents = $manipulation->transform($existing_contents);
                $last_start = $manipulation->start;
            }
        }
        if ($dry_run) {
            echo $file_path . ':' . "\n";
            $differ = new Differ(new StrictUnifiedDiffOutputBuilder(['fromFile' => $file_path, 'toFile' => $file_path]));
            echo $differ->diff($this->file_provider->getContents($file_path), $existing_contents);
            return;
        }
        $this->progress->alterFileDone($file_path);
        $this->file_provider->setContents($file_path, $existing_contents);
    }
    /**
     * @return list<IssueData>
     */
    public function getExistingIssuesForFile(string $file_path, int $start, int $end, ?string $issue_type = null) : array
    {
        if (!isset($this->existing_issues[$file_path])) {
            return [];
        }
        $applicable_issues = [];
        foreach ($this->existing_issues[$file_path] as $issue_data) {
            if ($issue_data->from >= $start && $issue_data->from <= $end) {
                if ($issue_type === null || $issue_type === $issue_data->type) {
                    $applicable_issues[] = $issue_data;
                }
            }
        }
        return $applicable_issues;
    }
    public function removeExistingDataForFile(string $file_path, int $start, int $end, ?string $issue_type = null) : void
    {
        if (isset($this->existing_issues[$file_path])) {
            foreach ($this->existing_issues[$file_path] as $i => $issue_data) {
                if ($issue_data->from >= $start && $issue_data->from <= $end) {
                    if ($issue_type === null || $issue_type === $issue_data->type) {
                        unset($this->existing_issues[$file_path][$i]);
                    }
                }
            }
        }
        if (isset($this->type_map[$file_path])) {
            foreach ($this->type_map[$file_path] as $map_start => $_) {
                if ($map_start >= $start && $map_start <= $end) {
                    unset($this->type_map[$file_path][$map_start]);
                }
            }
        }
        if (isset($this->reference_map[$file_path])) {
            foreach ($this->reference_map[$file_path] as $map_start => $_) {
                if ($map_start >= $start && $map_start <= $end) {
                    unset($this->reference_map[$file_path][$map_start]);
                }
            }
        }
        if (isset($this->argument_map[$file_path])) {
            foreach ($this->argument_map[$file_path] as $map_start => $_) {
                if ($map_start >= $start && $map_start <= $end) {
                    unset($this->argument_map[$file_path][$map_start]);
                }
            }
        }
    }
    /**
     * @return array<string, array<string, int>>
     */
    public function getAnalyzedMethods() : array
    {
        return $this->analyzed_methods;
    }
    /**
     * @return array<string, FileMapType>
     */
    public function getFileMaps() : array
    {
        $file_maps = [];
        foreach ($this->reference_map as $file_path => $reference_map) {
            $file_maps[$file_path] = [$reference_map, [], []];
        }
        foreach ($this->type_map as $file_path => $type_map) {
            if (isset($file_maps[$file_path])) {
                $file_maps[$file_path][1] = $type_map;
            } else {
                $file_maps[$file_path] = [[], $type_map, []];
            }
        }
        foreach ($this->argument_map as $file_path => $argument_map) {
            if (isset($file_maps[$file_path])) {
                $file_maps[$file_path][2] = $argument_map;
            } else {
                $file_maps[$file_path] = [[], [], $argument_map];
            }
        }
        return $file_maps;
    }
    /**
     * @return FileMapType
     */
    public function getMapsForFile(string $file_path) : array
    {
        return [$this->reference_map[$file_path] ?? [], $this->type_map[$file_path] ?? [], $this->argument_map[$file_path] ?? []];
    }
    /**
     * @return array<string, array<int, Union>>
     */
    public function getPossibleMethodParamTypes() : array
    {
        return $this->possible_method_param_types;
    }
    public function addMutableClass(string $fqcln) : void
    {
        $this->mutable_classes[strtolower($fqcln)] = \true;
    }
    public function setAnalyzedMethod(string $file_path, string $method_id, bool $is_constructor = \false) : void
    {
        $this->analyzed_methods[$file_path][$method_id] = $is_constructor ? 2 : 1;
    }
    public function isMethodAlreadyAnalyzed(string $file_path, string $method_id, bool $is_constructor = \false) : bool
    {
        if ($is_constructor) {
            return isset($this->analyzed_methods[$file_path][$method_id]) && $this->analyzed_methods[$file_path][$method_id] === 2;
        }
        return isset($this->analyzed_methods[$file_path][$method_id]);
    }
    /**
     * @param list<IssueData> $issues
     */
    private function taskDoneClosure(array $issues) : void
    {
        $has_error = \false;
        $has_info = \false;
        foreach ($issues as $issue) {
            if ($issue->severity === 'error') {
                $has_error = \true;
                break;
            }
            if ($issue->severity === 'info') {
                $has_info = \true;
            }
        }
        $this->progress->taskDone($has_error ? 2 : ($has_info ? 1 : 0));
    }
    /**
     * @return list<IssueData>
     */
    private function analysisWorker(int $_, string $file_path) : array
    {
        $file_analyzer = $this->getFileAnalyzer(ProjectAnalyzer::getInstance(), $file_path, $this->config->getFiletypeAnalyzers());
        $this->progress->debug('Analyzing ' . $file_analyzer->getFilePath() . "\n");
        $file_analyzer->analyze();
        $file_analyzer->context = null;
        $file_analyzer->clearSourceBeforeDestruction();
        unset($file_analyzer);
        return IssueBuffer::getIssuesDataForFile($file_path);
    }
    /** @return WorkerData */
    private function getWorkerData() : array
    {
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        $analyzer = $codebase->analyzer;
        $file_reference_provider = $codebase->file_reference_provider;
        $this->progress->debug('Gathering data for forked process' . "\n");
        // @codingStandardsIgnoreStart
        return ['issues' => IssueBuffer::getIssuesData(), 'fixable_issue_counts' => IssueBuffer::getFixableIssues(), 'nonmethod_references_to_classes' => $file_reference_provider->getAllNonMethodReferencesToClasses(), 'method_references_to_classes' => $file_reference_provider->getAllMethodReferencesToClasses(), 'file_references_to_class_members' => $file_reference_provider->getAllFileReferencesToClassMembers(), 'method_references_to_class_members' => $file_reference_provider->getAllMethodReferencesToClassMembers(), 'method_dependencies' => $file_reference_provider->getAllMethodDependencies(), 'file_references_to_class_properties' => $file_reference_provider->getAllFileReferencesToClassProperties(), 'file_references_to_method_returns' => $file_reference_provider->getAllFileReferencesToMethodReturns(), 'method_references_to_class_properties' => $file_reference_provider->getAllMethodReferencesToClassProperties(), 'method_references_to_method_returns' => $file_reference_provider->getAllMethodReferencesToMethodReturns(), 'file_references_to_missing_class_members' => $file_reference_provider->getAllFileReferencesToMissingClassMembers(), 'method_references_to_missing_class_members' => $file_reference_provider->getAllMethodReferencesToMissingClassMembers(), 'method_param_uses' => $file_reference_provider->getAllMethodParamUses(), 'mixed_member_names' => $analyzer->getMixedMemberNames(), 'file_manipulations' => FileManipulationBuffer::getAll(), 'mixed_counts' => $analyzer->getMixedCounts(), 'function_timings' => $analyzer->getFunctionTimings(), 'analyzed_methods' => $analyzer->getAnalyzedMethods(), 'file_maps' => $analyzer->getFileMaps(), 'class_locations' => $file_reference_provider->getAllClassLocations(), 'class_method_locations' => $file_reference_provider->getAllClassMethodLocations(), 'class_property_locations' => $file_reference_provider->getAllClassPropertyLocations(), 'possible_method_param_types' => $analyzer->getPossibleMethodParamTypes(), 'taint_data' => $codebase->taint_flow_graph, 'unused_suppressions' => $codebase->track_unused_suppressions ? IssueBuffer::getUnusedSuppressions() : [], 'used_suppressions' => $codebase->track_unused_suppressions ? IssueBuffer::getUsedSuppressions() : [], 'function_docblock_manipulators' => FunctionDocblockManipulator::getManipulators(), 'mutable_classes' => $codebase->analyzer->mutable_classes];
        // @codingStandardsIgnoreEnd
    }
}
<?php

namespace Psalm\Internal\Codebase;

use BackedEnum;
use Exception;
use InvalidArgumentException;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Issue\CircularReference;
use Psalm\IssueBuffer;
use Psalm\Progress\Progress;
use Psalm\Storage\ClassConstantStorage;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Storage\PropertyStorage;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use UnitEnum;
use function array_filter;
use function array_flip;
use function array_intersect_key;
use function array_keys;
use function array_merge;
use function array_splice;
use function count;
use function in_array;
use function key;
use function reset;
use function strpos;
use function strtolower;
/**
 * @internal
 *
 * Populates file and class information so that analysis can work properly
 */
class Populator
{
    private ClassLikeStorageProvider $classlike_storage_provider;
    private FileStorageProvider $file_storage_provider;
    /**
     * @var array<lowercase-string, list<ClassLikeStorage>>
     */
    private array $invalid_class_storages = [];
    private Progress $progress;
    private \Psalm\Internal\Codebase\ClassLikes $classlikes;
    private FileReferenceProvider $file_reference_provider;
    public function __construct(ClassLikeStorageProvider $classlike_storage_provider, FileStorageProvider $file_storage_provider, \Psalm\Internal\Codebase\ClassLikes $classlikes, FileReferenceProvider $file_reference_provider, Progress $progress)
    {
        $this->classlike_storage_provider = $classlike_storage_provider;
        $this->file_storage_provider = $file_storage_provider;
        $this->classlikes = $classlikes;
        $this->progress = $progress;
        $this->file_reference_provider = $file_reference_provider;
    }
    public function populateCodebase() : void
    {
        $this->progress->debug('ClassLikeStorage is populating' . "\n");
        foreach ($this->classlike_storage_provider->getNew() as $class_storage) {
            $this->populateClassLikeStorage($class_storage);
        }
        $this->progress->debug('ClassLikeStorage is populated' . "\n");
        $this->progress->debug('FileStorage is populating' . "\n");
        $all_file_storage = $this->file_storage_provider->getNew();
        foreach ($all_file_storage as $file_storage) {
            $this->populateFileStorage($file_storage);
        }
        foreach ($this->classlike_storage_provider->getNew() as $class_storage) {
            foreach ($class_storage->dependent_classlikes as $dependent_classlike_lc => $_) {
                try {
                    $dependee_storage = $this->classlike_storage_provider->get($dependent_classlike_lc);
                } catch (InvalidArgumentException $exception) {
                    continue;
                }
                $class_storage->dependent_classlikes += $dependee_storage->dependent_classlikes;
            }
        }
        $this->progress->debug('FileStorage is populated' . "\n");
        ClassLikeStorageProvider::populated();
        FileStorageProvider::populated();
    }
    private function populateClassLikeStorage(ClassLikeStorage $storage, array $dependent_classlikes = []) : void
    {
        if ($storage->populated) {
            return;
        }
        $fq_classlike_name_lc = strtolower($storage->name);
        if (isset($dependent_classlikes[$fq_classlike_name_lc])) {
            if ($storage->location) {
                IssueBuffer::maybeAdd(new CircularReference('Circular reference discovered when loading ' . $storage->name, $storage->location));
            }
            return;
        }
        $storage_provider = $this->classlike_storage_provider;
        $dependent_classlikes[$fq_classlike_name_lc] = \true;
        foreach ($storage->used_traits as $used_trait_lc => $_) {
            $this->populateDataFromTrait($storage, $storage_provider, $dependent_classlikes, $used_trait_lc);
        }
        if ($storage->parent_classes) {
            $this->populateDataFromParentClass($storage, $storage_provider, $dependent_classlikes, reset($storage->parent_classes));
        }
        if (!strpos($fq_classlike_name_lc, '\\') && !isset($storage->methods['__construct']) && isset($storage->methods[$fq_classlike_name_lc]) && !$storage->is_interface && !$storage->is_trait) {
            $storage->methods['__construct'] = $storage->methods[$fq_classlike_name_lc];
        }
        foreach ($storage->direct_interface_parents as $parent_interface_lc => $_) {
            $this->populateInterfaceDataFromParentInterface($storage, $storage_provider, $dependent_classlikes, $parent_interface_lc);
        }
        foreach ($storage->direct_class_interfaces as $implemented_interface_lc => $_) {
            $this->populateDataFromImplementedInterface($storage, $storage_provider, $dependent_classlikes, $implemented_interface_lc);
        }
        if ($storage->location) {
            $file_path = $storage->location->file_path;
            foreach ($storage->parent_interfaces as $parent_interface_lc) {
                $this->file_reference_provider->addFileInheritanceToClass($file_path, $parent_interface_lc);
            }
            foreach ($storage->parent_classes as $parent_class_lc => $_) {
                $this->file_reference_provider->addFileInheritanceToClass($file_path, $parent_class_lc);
            }
            foreach ($storage->class_implements as $implemented_interface) {
                $this->file_reference_provider->addFileInheritanceToClass($file_path, strtolower($implemented_interface));
            }
            foreach ($storage->used_traits as $used_trait_lc => $_) {
                $this->file_reference_provider->addFileInheritanceToClass($file_path, $used_trait_lc);
            }
        }
        if ($storage->mutation_free || $storage->external_mutation_free) {
            foreach ($storage->methods as $method) {
                if (!$method->is_static && !$method->external_mutation_free) {
                    $method->mutation_free = $storage->mutation_free;
                    $method->external_mutation_free = $storage->external_mutation_free;
                    $method->immutable = $storage->mutation_free;
                }
            }
            if ($storage->mutation_free) {
                foreach ($storage->properties as $property) {
                    if (!$property->is_static) {
                        $property->readonly = \true;
                    }
                }
            }
        }
        if ($storage->specialize_instance) {
            foreach ($storage->methods as $method) {
                if (!$method->is_static) {
                    $method->specialize_call = \true;
                }
            }
        }
        if (!$storage->is_interface && !$storage->is_trait) {
            foreach ($storage->methods as $method) {
                $method->internal = [...$storage->internal, ...$method->internal];
            }
            foreach ($storage->properties as $property) {
                $property->internal = [...$storage->internal, ...$property->internal];
            }
        }
        $this->populateOverriddenMethods($storage, $storage_provider);
        $this->progress->debug('Have populated ' . $storage->name . "\n");
        $storage->populated = \true;
        if (isset($this->invalid_class_storages[$fq_classlike_name_lc])) {
            foreach ($this->invalid_class_storages[$fq_classlike_name_lc] as $dependency) {
                // Dependencies may not be fully set yet, so we have to loop through dependencies of dependencies
                $dependencies = [strtolower($dependency->name) => \true];
                do {
                    $current_dependency_name = key(array_splice($dependencies, 0, 1));
                    // Key shift
                    $current_dependency = $storage_provider->get($current_dependency_name);
                    $dependencies += $current_dependency->dependent_classlikes;
                    if (isset($current_dependency->dependent_classlikes[$fq_classlike_name_lc])) {
                        if ($dependency->location) {
                            IssueBuffer::maybeAdd(new CircularReference('Circular reference discovered when loading ' . $dependency->name, $dependency->location));
                        }
                        continue 2;
                    }
                } while (!empty($dependencies));
                $dependency->populated = \false;
                unset($dependency->invalid_dependencies[$fq_classlike_name_lc]);
                $this->populateClassLikeStorage($dependency, $dependent_classlikes);
            }
            unset($this->invalid_class_storages[$fq_classlike_name_lc]);
        }
    }
    private function populateOverriddenMethods(ClassLikeStorage $storage, ClassLikeStorageProvider $storage_provider) : void
    {
        $interface_method_implementers = [];
        foreach ($storage->class_implements as $interface) {
            try {
                $implemented_interface = strtolower($this->classlikes->getUnAliasedName($interface));
                $implemented_interface_storage = $storage_provider->get($implemented_interface);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            $implemented_interface_storage->dependent_classlikes[strtolower($storage->name)] = \true;
            foreach ($implemented_interface_storage->methods as $method_name => $method) {
                if ($method->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC) {
                    $interface_method_implementers[$method_name][] = new MethodIdentifier($implemented_interface_storage->name, $method_name);
                }
            }
        }
        foreach ($interface_method_implementers as $method_name => $interface_method_ids) {
            if (count($interface_method_ids) === 1) {
                if (isset($storage->methods[$method_name])) {
                    $method_storage = $storage->methods[$method_name];
                    if ($method_storage->signature_return_type && !$method_storage->signature_return_type->isVoid() && $method_storage->return_type === $method_storage->signature_return_type) {
                        $interface_fqcln = $interface_method_ids[0]->fq_class_name;
                        $interface_storage = $storage_provider->get($interface_fqcln);
                        if (isset($interface_storage->methods[$method_name])) {
                            $interface_method_storage = $interface_storage->methods[$method_name];
                            if ($interface_method_storage->throws && (!$method_storage->throws || $method_storage->inheritdoc)) {
                                $method_storage->throws += $interface_method_storage->throws;
                            }
                        }
                    }
                }
            }
            foreach ($interface_method_ids as $interface_method_id) {
                $storage->overridden_method_ids[$method_name][$interface_method_id->fq_class_name] = $interface_method_id;
            }
        }
        $storage->documenting_method_ids = [];
        foreach ($storage->methods as $method_name => $method_storage) {
            if (isset($storage->overridden_method_ids[$method_name])) {
                $overridden_method_ids = $storage->overridden_method_ids[$method_name];
                $candidate_overridden_ids = null;
                $declaring_class_storages = [];
                foreach ($overridden_method_ids as $declaring_method_id) {
                    $declaring_class = $declaring_method_id->fq_class_name;
                    $declaring_class_storage = $declaring_class_storages[$declaring_class] = $this->classlike_storage_provider->get($declaring_class);
                    if ($candidate_overridden_ids === null) {
                        $candidate_overridden_ids = ($declaring_class_storage->overridden_method_ids[$method_name] ?? []) + [$declaring_method_id->fq_class_name => $declaring_method_id];
                    } else {
                        $candidate_overridden_ids = array_intersect_key($candidate_overridden_ids, ($declaring_class_storage->overridden_method_ids[$method_name] ?? []) + [$declaring_method_id->fq_class_name => $declaring_method_id]);
                    }
                }
                foreach ($overridden_method_ids as $declaring_method_id) {
                    $declaring_class = $declaring_method_id->fq_class_name;
                    $declaring_method_name = $declaring_method_id->method_name;
                    $declaring_class_storage = $declaring_class_storages[$declaring_class];
                    $declaring_method_storage = $declaring_class_storage->methods[$declaring_method_name];
                    if (($declaring_method_storage->has_docblock_param_types || $declaring_method_storage->has_docblock_return_type) && !$method_storage->has_docblock_param_types && !$method_storage->has_docblock_return_type && $method_storage->inherited_return_type !== null) {
                        if (!isset($storage->documenting_method_ids[$method_name]) || (string) $storage->documenting_method_ids[$method_name] === (string) $declaring_method_id) {
                            $storage->documenting_method_ids[$method_name] = $declaring_method_id;
                            $method_storage->inherited_return_type = \true;
                        } else {
                            if (in_array($storage->documenting_method_ids[$method_name]->fq_class_name, $declaring_class_storage->parent_interfaces)) {
                                $storage->documenting_method_ids[$method_name] = $declaring_method_id;
                                $method_storage->inherited_return_type = \true;
                            } else {
                                $documenting_class_storage = $declaring_class_storages[$storage->documenting_method_ids[$method_name]->fq_class_name];
                                if (!in_array($declaring_class, $documenting_class_storage->parent_interfaces) && $documenting_class_storage->is_interface) {
                                    unset($storage->documenting_method_ids[$method_name]);
                                    $method_storage->inherited_return_type = null;
                                }
                            }
                        }
                    }
                    // tell the declaring class it's overridden downstream
                    $declaring_method_storage->overridden_downstream = \true;
                    $declaring_method_storage->overridden_somewhere = \true;
                    if ($declaring_method_storage->mutation_free_inferred) {
                        $declaring_method_storage->mutation_free = \false;
                        $declaring_method_storage->external_mutation_free = \false;
                        $declaring_method_storage->mutation_free_inferred = \false;
                    }
                    if ($declaring_method_storage->throws && (!$method_storage->throws || $method_storage->inheritdoc)) {
                        $method_storage->throws += $declaring_method_storage->throws;
                    }
                }
            }
        }
    }
    private function populateDataFromTrait(ClassLikeStorage $storage, ClassLikeStorageProvider $storage_provider, array $dependent_classlikes, string $used_trait_lc) : void
    {
        try {
            $used_trait_lc = strtolower($this->classlikes->getUnAliasedName($used_trait_lc));
            $trait_storage = $storage_provider->get($used_trait_lc);
        } catch (InvalidArgumentException $e) {
            return;
        }
        $this->populateClassLikeStorage($trait_storage, $dependent_classlikes);
        $this->inheritConstantsFromTrait($storage, $trait_storage);
        $this->inheritMethodsFromParent($storage, $trait_storage);
        $this->inheritPropertiesFromParent($storage, $trait_storage);
        self::extendTemplateParams($storage, $trait_storage, \false);
        $storage->pseudo_property_get_types += $trait_storage->pseudo_property_get_types;
        $storage->pseudo_property_set_types += $trait_storage->pseudo_property_set_types;
        $storage->pseudo_methods += $trait_storage->pseudo_methods;
        $storage->declaring_pseudo_method_ids += $trait_storage->declaring_pseudo_method_ids;
    }
    private static function extendType(Union $type, ClassLikeStorage $storage) : Union
    {
        $extended_types = [];
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TTemplateParam) {
                $referenced_type = $storage->template_extended_params[$atomic_type->defining_class][$atomic_type->param_name] ?? null;
                if ($referenced_type) {
                    foreach ($referenced_type->getAtomicTypes() as $atomic_referenced_type) {
                        if (!$atomic_referenced_type instanceof TTemplateParam) {
                            $extended_types[] = $atomic_referenced_type;
                        } else {
                            $extended_types[] = $atomic_type;
                        }
                    }
                } else {
                    $extended_types[] = $atomic_type;
                }
            } else {
                $extended_types[] = $atomic_type;
            }
        }
        return new Union($extended_types);
    }
    private function populateDataFromParentClass(ClassLikeStorage $storage, ClassLikeStorageProvider $storage_provider, array $dependent_classlikes, string $parent_storage_class) : void
    {
        $parent_storage_class = strtolower($this->classlikes->getUnAliasedName($parent_storage_class));
        try {
            $parent_storage = $storage_provider->get($parent_storage_class);
        } catch (InvalidArgumentException $e) {
            $this->progress->debug('Populator could not find dependency (' . __LINE__ . ")\n");
            $storage->invalid_dependencies[$parent_storage_class] = \true;
            $this->invalid_class_storages[$parent_storage_class][] = $storage;
            return;
        }
        $this->populateClassLikeStorage($parent_storage, $dependent_classlikes);
        $storage->parent_classes = array_merge($storage->parent_classes, $parent_storage->parent_classes);
        self::extendTemplateParams($storage, $parent_storage, \true);
        $this->inheritMethodsFromParent($storage, $parent_storage);
        $this->inheritPropertiesFromParent($storage, $parent_storage);
        $storage->class_implements = array_merge($storage->class_implements, $parent_storage->class_implements);
        $storage->invalid_dependencies = array_merge($storage->invalid_dependencies, $parent_storage->invalid_dependencies);
        if ($parent_storage->has_visitor_issues) {
            $storage->has_visitor_issues = \true;
        }
        $storage->constants = array_merge(array_filter($parent_storage->constants, static fn(ClassConstantStorage $constant): bool => $constant->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC || $constant->visibility === ClassLikeAnalyzer::VISIBILITY_PROTECTED), $storage->constants);
        if ($parent_storage->preserve_constructor_signature) {
            $storage->preserve_constructor_signature = \true;
        }
        if (($parent_storage->namedMixins || $parent_storage->templatedMixins) && (!$storage->namedMixins || !$storage->templatedMixins)) {
            $storage->mixin_declaring_fqcln = $parent_storage->mixin_declaring_fqcln;
            if (!$storage->namedMixins) {
                $storage->namedMixins = $parent_storage->namedMixins;
            }
            if (!$storage->templatedMixins) {
                $storage->templatedMixins = $parent_storage->templatedMixins;
            }
        }
        $storage->pseudo_property_get_types += $parent_storage->pseudo_property_get_types;
        $storage->pseudo_property_set_types += $parent_storage->pseudo_property_set_types;
        $parent_storage->dependent_classlikes[strtolower($storage->name)] = \true;
        $storage->pseudo_methods += $parent_storage->pseudo_methods;
        $storage->declaring_pseudo_method_ids += $parent_storage->declaring_pseudo_method_ids;
    }
    private function populateInterfaceData(ClassLikeStorage $storage, ClassLikeStorage $interface_storage, ClassLikeStorageProvider $storage_provider, array $dependent_classlikes) : void
    {
        $this->populateClassLikeStorage($interface_storage, $dependent_classlikes);
        // copy over any constants
        $storage->constants = array_merge(array_filter($interface_storage->constants, static fn(ClassConstantStorage $constant): bool => $constant->visibility === ClassLikeAnalyzer::VISIBILITY_PUBLIC), $storage->constants);
        $storage->invalid_dependencies = array_merge($storage->invalid_dependencies, $interface_storage->invalid_dependencies);
        self::extendTemplateParams($storage, $interface_storage, \false);
        $new_parents = array_keys($interface_storage->parent_interfaces);
        $new_parents[] = $interface_storage->name;
        foreach ($new_parents as $new_parent) {
            try {
                $new_parent = strtolower($this->classlikes->getUnAliasedName($new_parent));
                $new_parent_interface_storage = $storage_provider->get($new_parent);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            $new_parent_interface_storage->dependent_classlikes[strtolower($storage->name)] = \true;
        }
    }
    private static function extendTemplateParams(ClassLikeStorage $storage, ClassLikeStorage $parent_storage, bool $from_direct_parent) : void
    {
        if ($parent_storage->yield && !$storage->yield) {
            $storage->yield = $parent_storage->yield;
            $storage->declaring_yield_fqcn ??= $parent_storage->name;
        }
        if ($parent_storage->template_types) {
            $storage->template_extended_params[$parent_storage->name] = [];
            if (isset($storage->template_extended_offsets[$parent_storage->name])) {
                foreach ($storage->template_extended_offsets[$parent_storage->name] as $i => $type) {
                    $parent_template_type_names = array_keys($parent_storage->template_types);
                    $mapped_name = $parent_template_type_names[$i] ?? null;
                    if ($mapped_name) {
                        $storage->template_extended_params[$parent_storage->name][$mapped_name] = $type;
                    }
                }
                if ($parent_storage->template_extended_params) {
                    foreach ($parent_storage->template_extended_params as $t_storage_class => $type_map) {
                        foreach ($type_map as $i => $type) {
                            $storage->template_extended_params[$t_storage_class][$i] = self::extendType($type, $storage);
                        }
                    }
                }
            } else {
                foreach ($parent_storage->template_types as $template_name => $template_type_map) {
                    foreach ($template_type_map as $template_type) {
                        $default_param = $template_type->setProperties(['from_docblock' => \false]);
                        $storage->template_extended_params[$parent_storage->name][$template_name] = $default_param;
                    }
                }
                if ($from_direct_parent) {
                    if ($parent_storage->template_extended_params) {
                        $storage->template_extended_params = array_merge($storage->template_extended_params, $parent_storage->template_extended_params);
                    }
                }
            }
        } elseif ($parent_storage->template_extended_params) {
            $storage->template_extended_params = array_merge($storage->template_extended_params ?: [], $parent_storage->template_extended_params);
        }
    }
    private function populateInterfaceDataFromParentInterface(ClassLikeStorage $storage, ClassLikeStorageProvider $storage_provider, array $dependent_classlikes, string $parent_interface_lc) : void
    {
        try {
            $parent_interface_lc = strtolower($this->classlikes->getUnAliasedName($parent_interface_lc));
            $parent_interface_storage = $storage_provider->get($parent_interface_lc);
        } catch (InvalidArgumentException $e) {
            $this->progress->debug('Populator could not find dependency (' . __LINE__ . ")\n");
            $storage->invalid_dependencies[$parent_interface_lc] = \true;
            return;
        }
        $this->populateInterfaceData($storage, $parent_interface_storage, $storage_provider, $dependent_classlikes);
        $this->inheritMethodsFromParent($storage, $parent_interface_storage);
        $storage->pseudo_methods += $parent_interface_storage->pseudo_methods;
        $storage->declaring_pseudo_method_ids += $parent_interface_storage->declaring_pseudo_method_ids;
        $storage->parent_interfaces = array_merge($parent_interface_storage->parent_interfaces, $storage->parent_interfaces);
        if (isset($storage->parent_interfaces[strtolower(UnitEnum::class)])) {
            $storage->declaring_property_ids['name'] = $storage->name;
            $storage->appearing_property_ids['name'] = "{$storage->name}::\$name";
            $storage->properties['name'] = new PropertyStorage();
            $storage->properties['name']->type = new Union([new TNonEmptyString()]);
        }
        if (isset($storage->parent_interfaces[strtolower(BackedEnum::class)])) {
            $storage->declaring_property_ids['value'] = $storage->name;
            $storage->appearing_property_ids['value'] = "{$storage->name}::\$value";
            $storage->properties['value'] = new PropertyStorage();
            $storage->properties['value']->type = new Union([new TInt(), new TString()]);
        }
    }
    private function populateDataFromImplementedInterface(ClassLikeStorage $storage, ClassLikeStorageProvider $storage_provider, array $dependent_classlikes, string $implemented_interface_lc) : void
    {
        try {
            $implemented_interface_lc = strtolower($this->classlikes->getUnAliasedName($implemented_interface_lc));
            $implemented_interface_storage = $storage_provider->get($implemented_interface_lc);
        } catch (InvalidArgumentException $e) {
            $this->progress->debug('Populator could not find dependency (' . __LINE__ . ")\n");
            $storage->invalid_dependencies[$implemented_interface_lc] = \true;
            return;
        }
        $this->populateInterfaceData($storage, $implemented_interface_storage, $storage_provider, $dependent_classlikes);
        $storage->class_implements = array_merge($storage->class_implements, $implemented_interface_storage->parent_interfaces);
    }
    /**
     * @param  array<string, bool> $dependent_file_paths
     */
    private function populateFileStorage(FileStorage $storage, array $dependent_file_paths = []) : void
    {
        if ($storage->populated) {
            return;
        }
        $file_path_lc = strtolower($storage->file_path);
        if (isset($dependent_file_paths[$file_path_lc])) {
            return;
        }
        $dependent_file_paths[$file_path_lc] = \true;
        $all_required_file_paths = $storage->required_file_paths;
        foreach ($storage->required_file_paths as $included_file_path => $_) {
            try {
                $included_file_storage = $this->file_storage_provider->get($included_file_path);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            $this->populateFileStorage($included_file_storage, $dependent_file_paths);
            $all_required_file_paths = $all_required_file_paths + $included_file_storage->required_file_paths;
        }
        foreach ($all_required_file_paths as $included_file_path => $_) {
            try {
                $included_file_storage = $this->file_storage_provider->get($included_file_path);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            $storage->declaring_function_ids = array_merge($included_file_storage->declaring_function_ids, $storage->declaring_function_ids);
            $storage->declaring_constants = array_merge($included_file_storage->declaring_constants, $storage->declaring_constants);
        }
        foreach ($storage->referenced_classlikes as $fq_class_name) {
            try {
                $classlike_storage = $this->classlike_storage_provider->get($fq_class_name);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            if (!$classlike_storage->location) {
                continue;
            }
            try {
                $included_file_storage = $this->file_storage_provider->get($classlike_storage->location->file_path);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            foreach ($classlike_storage->used_traits as $used_trait) {
                try {
                    $trait_storage = $this->classlike_storage_provider->get($used_trait);
                } catch (InvalidArgumentException $e) {
                    continue;
                }
                if (!$trait_storage->location) {
                    continue;
                }
                try {
                    $included_trait_file_storage = $this->file_storage_provider->get($trait_storage->location->file_path);
                } catch (InvalidArgumentException $e) {
                    continue;
                }
                $storage->declaring_function_ids = array_merge($included_trait_file_storage->declaring_function_ids, $storage->declaring_function_ids);
            }
            $storage->declaring_function_ids = array_merge($included_file_storage->declaring_function_ids, $storage->declaring_function_ids);
        }
        $storage->required_file_paths = $all_required_file_paths;
        foreach ($all_required_file_paths as $required_file_path) {
            try {
                $required_file_storage = $this->file_storage_provider->get($required_file_path);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            $required_file_storage->required_by_file_paths += [$file_path_lc => $storage->file_path];
        }
        foreach ($storage->required_classes as $required_classlike) {
            try {
                $classlike_storage = $this->classlike_storage_provider->get($required_classlike);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            if (!$classlike_storage->location) {
                continue;
            }
            try {
                $required_file_storage = $this->file_storage_provider->get($classlike_storage->location->file_path);
            } catch (InvalidArgumentException $e) {
                continue;
            }
            $required_file_storage->required_by_file_paths += [$file_path_lc => $storage->file_path];
        }
        $storage->populated = \true;
    }
    private function inheritConstantsFromTrait(ClassLikeStorage $storage, ClassLikeStorage $trait_storage) : void
    {
        if (!$trait_storage->is_trait) {
            throw new Exception('Class like storage is not for a trait.');
        }
        foreach ($trait_storage->constants as $constant_name => $class_constant_storage) {
            $trait_alias_map_cased = array_flip($storage->trait_alias_map_cased);
            if (isset($trait_alias_map_cased[$constant_name])) {
                $aliased_constant_name_lc = strtolower($trait_alias_map_cased[$constant_name]);
                $aliased_constant_name = $trait_alias_map_cased[$constant_name];
            } else {
                $aliased_constant_name_lc = strtolower($constant_name);
                $aliased_constant_name = $constant_name;
            }
            $visibility = $storage->trait_visibility_map[$aliased_constant_name_lc] ?? $class_constant_storage->visibility;
            $final = $storage->trait_final_map[$aliased_constant_name_lc] ?? $class_constant_storage->final;
            $storage->constants[$aliased_constant_name] = new ClassConstantStorage($class_constant_storage->type, $class_constant_storage->inferred_type, $visibility, $class_constant_storage->location, $class_constant_storage->type_location, $class_constant_storage->stmt_location, $class_constant_storage->deprecated, $final, $class_constant_storage->unresolved_node, $class_constant_storage->attributes, $class_constant_storage->suppressed_issues, $class_constant_storage->description);
        }
    }
    protected function inheritMethodsFromParent(ClassLikeStorage $storage, ClassLikeStorage $parent_storage) : void
    {
        $fq_class_name = $storage->name;
        $fq_class_name_lc = strtolower($fq_class_name);
        if ($parent_storage->sealed_methods) {
            $storage->sealed_methods = \true;
        }
        // register where they appear (can never be in a trait)
        foreach ($parent_storage->appearing_method_ids as $method_name_lc => $appearing_method_id) {
            $aliased_method_names = [$method_name_lc];
            if ($parent_storage->is_trait && $storage->trait_alias_map) {
                $aliased_method_names = array_merge($aliased_method_names, array_keys($storage->trait_alias_map, $method_name_lc, \true));
            }
            foreach ($aliased_method_names as $aliased_method_name) {
                if (isset($storage->appearing_method_ids[$aliased_method_name])) {
                    continue;
                }
                $implemented_method_id = new MethodIdentifier($fq_class_name, $aliased_method_name);
                $storage->appearing_method_ids[$aliased_method_name] = $parent_storage->is_trait ? $implemented_method_id : $appearing_method_id;
                $this_method_id = $fq_class_name_lc . '::' . $method_name_lc;
                if (isset($storage->methods[$aliased_method_name])) {
                    $storage->potential_declaring_method_ids[$aliased_method_name] = [$this_method_id => \true];
                } else {
                    if (isset($parent_storage->potential_declaring_method_ids[$aliased_method_name])) {
                        $storage->potential_declaring_method_ids[$aliased_method_name] = $parent_storage->potential_declaring_method_ids[$aliased_method_name];
                    }
                    $storage->potential_declaring_method_ids[$aliased_method_name][$this_method_id] = \true;
                    $parent_method_id = strtolower($parent_storage->name) . '::' . $method_name_lc;
                    $storage->potential_declaring_method_ids[$aliased_method_name][$parent_method_id] = \true;
                }
            }
        }
        // register where they're declared
        foreach ($parent_storage->inheritable_method_ids as $method_name_lc => $declaring_method_id) {
            if ($method_name_lc !== '__construct' || $parent_storage->preserve_constructor_signature) {
                if ($parent_storage->is_trait) {
                    $declaring_class = $declaring_method_id->fq_class_name;
                    $declaring_class_storage = $this->classlike_storage_provider->get($declaring_class);
                    if (isset($declaring_class_storage->methods[$method_name_lc]) && $declaring_class_storage->methods[$method_name_lc]->abstract) {
                        $storage->overridden_method_ids[$method_name_lc][$declaring_method_id->fq_class_name] = $declaring_method_id;
                    }
                } else {
                    $storage->overridden_method_ids[$method_name_lc][$declaring_method_id->fq_class_name] = $declaring_method_id;
                }
                if (isset($parent_storage->overridden_method_ids[$method_name_lc]) && isset($storage->overridden_method_ids[$method_name_lc])) {
                    $storage->overridden_method_ids[$method_name_lc] += $parent_storage->overridden_method_ids[$method_name_lc];
                }
            }
            $aliased_method_names = [$method_name_lc];
            if ($parent_storage->is_trait && $storage->trait_alias_map) {
                $aliased_method_names = array_merge($aliased_method_names, array_keys($storage->trait_alias_map, $method_name_lc, \true));
            }
            foreach ($aliased_method_names as $aliased_method_name) {
                if (isset($storage->declaring_method_ids[$aliased_method_name])) {
                    $implementing_method_id = $storage->declaring_method_ids[$aliased_method_name];
                    $implementing_class_storage = $this->classlike_storage_provider->get($implementing_method_id->fq_class_name);
                    if (!$implementing_class_storage->methods[$implementing_method_id->method_name]->abstract || !empty($storage->methods[$implementing_method_id->method_name]->abstract)) {
                        continue;
                    }
                }
                $storage->declaring_method_ids[$aliased_method_name] = $declaring_method_id;
                $storage->inheritable_method_ids[$aliased_method_name] = $declaring_method_id;
            }
        }
    }
    private function inheritPropertiesFromParent(ClassLikeStorage $storage, ClassLikeStorage $parent_storage) : void
    {
        if ($parent_storage->sealed_properties) {
            $storage->sealed_properties = \true;
        }
        // register where they appear (can never be in a trait)
        foreach ($parent_storage->appearing_property_ids as $property_name => $appearing_property_id) {
            if (isset($storage->appearing_property_ids[$property_name])) {
                continue;
            }
            if (!$parent_storage->is_trait && isset($parent_storage->properties[$property_name]) && $parent_storage->properties[$property_name]->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                continue;
            }
            $implemented_property_id = $storage->name . '::$' . $property_name;
            $storage->appearing_property_ids[$property_name] = $parent_storage->is_trait ? $implemented_property_id : $appearing_property_id;
        }
        // register where they're declared
        foreach ($parent_storage->declaring_property_ids as $property_name => $declaring_property_class) {
            if (isset($storage->declaring_property_ids[$property_name])) {
                continue;
            }
            if (!$parent_storage->is_trait && isset($parent_storage->properties[$property_name]) && $parent_storage->properties[$property_name]->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                continue;
            }
            $storage->declaring_property_ids[$property_name] = $declaring_property_class;
        }
        // register where they're declared
        foreach ($parent_storage->inheritable_property_ids as $property_name => $inheritable_property_id) {
            if (!$parent_storage->is_trait && isset($parent_storage->properties[$property_name]) && $parent_storage->properties[$property_name]->visibility === ClassLikeAnalyzer::VISIBILITY_PRIVATE) {
                continue;
            }
            if (!$parent_storage->is_trait) {
                $storage->overridden_property_ids[$property_name][] = $inheritable_property_id;
            }
            $storage->inheritable_property_ids[$property_name] = $inheritable_property_id;
        }
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Psalm\CodeLocation;
use Psalm\Config;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Internal\DataFlow\TaintSource;
use Psalm\Issue\TaintedCallable;
use Psalm\Issue\TaintedCookie;
use Psalm\Issue\TaintedCustom;
use Psalm\Issue\TaintedEval;
use Psalm\Issue\TaintedFile;
use Psalm\Issue\TaintedHeader;
use Psalm\Issue\TaintedHtml;
use Psalm\Issue\TaintedInclude;
use Psalm\Issue\TaintedLdap;
use Psalm\Issue\TaintedSSRF;
use Psalm\Issue\TaintedShell;
use Psalm\Issue\TaintedSql;
use Psalm\Issue\TaintedSystemSecret;
use Psalm\Issue\TaintedTextWithQuotes;
use Psalm\Issue\TaintedUnserialize;
use Psalm\Issue\TaintedUserSecret;
use Psalm\IssueBuffer;
use Psalm\Type\TaintKind;
use function array_diff;
use function array_filter;
use function array_intersect;
use function array_merge;
use function array_unique;
use function count;
use function end;
use function implode;
use function json_encode;
use function ksort;
use function sort;
use function strlen;
use function substr;
use const JSON_THROW_ON_ERROR;
/**
 * @internal
 */
class TaintFlowGraph extends \Psalm\Internal\Codebase\DataFlowGraph
{
    /** @var array<string, TaintSource> */
    private array $sources = [];
    /** @var array<string, DataFlowNode> */
    private array $nodes = [];
    /** @var array<string, TaintSink> */
    private array $sinks = [];
    /** @var array<string, array<string, true>> */
    private array $specialized_calls = [];
    /** @var array<string, array<string, true>> */
    private array $specializations = [];
    public function addNode(DataFlowNode $node) : void
    {
        $this->nodes[$node->id] = $node;
        if ($node->unspecialized_id && $node->specialization_key) {
            $this->specialized_calls[$node->specialization_key][$node->unspecialized_id] = \true;
            $this->specializations[$node->unspecialized_id][$node->specialization_key] = \true;
        }
    }
    public function addSource(TaintSource $node) : void
    {
        $this->sources[$node->id] = $node;
    }
    public function addSink(TaintSink $node) : void
    {
        $this->sinks[$node->id] = $node;
        // in the rare case the sink is the _next_ node, this is necessary
        $this->nodes[$node->id] = $node;
    }
    public function addGraph(self $taint) : void
    {
        $this->sources += $taint->sources;
        $this->sinks += $taint->sinks;
        $this->nodes += $taint->nodes;
        $this->specialized_calls += $taint->specialized_calls;
        foreach ($taint->forward_edges as $key => $map) {
            if (!isset($this->forward_edges[$key])) {
                $this->forward_edges[$key] = $map;
            } else {
                $this->forward_edges[$key] += $map;
            }
        }
        foreach ($taint->specializations as $key => $map) {
            if (!isset($this->specializations[$key])) {
                $this->specializations[$key] = $map;
            } else {
                $this->specializations[$key] += $map;
            }
        }
    }
    public function getPredecessorPath(DataFlowNode $source) : string
    {
        $location_summary = '';
        if ($source->code_location) {
            $location_summary = $source->code_location->getShortSummary();
        }
        $source_descriptor = $source->label . ($location_summary ? ' (' . $location_summary . ')' : '');
        $previous_source = $source->previous;
        if ($previous_source) {
            if ($previous_source === $source) {
                return '';
            }
            if ($source->code_location && $previous_source->code_location && $previous_source->code_location->getHash() === $source->code_location->getHash() && $previous_source->previous) {
                return $this->getPredecessorPath($previous_source->previous) . ' -> ' . $source_descriptor;
            }
            return $this->getPredecessorPath($previous_source) . ' -> ' . $source_descriptor;
        }
        return $source_descriptor;
    }
    public function getSuccessorPath(DataFlowNode $sink) : string
    {
        $location_summary = '';
        if ($sink->code_location) {
            $location_summary = $sink->code_location->getShortSummary();
        }
        $sink_descriptor = $sink->label . ($location_summary ? ' (' . $location_summary . ')' : '');
        $next_sink = $sink->previous;
        if ($next_sink) {
            if ($next_sink === $sink) {
                return '';
            }
            if ($sink->code_location && $next_sink->code_location && $next_sink->code_location->getHash() === $sink->code_location->getHash() && $next_sink->previous) {
                return $sink_descriptor . ' -> ' . $this->getSuccessorPath($next_sink->previous);
            }
            return $sink_descriptor . ' -> ' . $this->getSuccessorPath($next_sink);
        }
        return $sink_descriptor;
    }
    /**
     * @return list<array{location: ?CodeLocation, label: string, entry_path_type: string}>
     */
    public function getIssueTrace(DataFlowNode $source) : array
    {
        $previous_source = $source->previous;
        $node = ['location' => $source->code_location, 'label' => $source->label, 'entry_path_type' => end($source->path_types) ?: ''];
        if ($previous_source) {
            if ($previous_source === $source) {
                return [];
            }
            return [...$this->getIssueTrace($previous_source), ...[$node]];
        }
        return [$node];
    }
    public function connectSinksAndSources() : void
    {
        $visited_source_ids = [];
        $sources = $this->sources;
        $sinks = $this->sinks;
        ksort($this->specializations);
        ksort($this->forward_edges);
        // reprocess resolved descendants up to a maximum nesting level of 40
        for ($i = 0; count($sinks) && count($sources) && $i < 40; $i++) {
            $new_sources = [];
            ksort($sources);
            foreach ($sources as $source) {
                $source_taints = $source->taints;
                sort($source_taints);
                $visited_source_ids[$source->id][implode(',', $source_taints)] = \true;
                $generated_sources = $this->getSpecializedSources($source);
                foreach ($generated_sources as $generated_source) {
                    $new_sources = array_merge($new_sources, $this->getChildNodes($generated_source, $source_taints, $sinks, $visited_source_ids));
                }
            }
            $sources = $new_sources;
        }
    }
    /**
     * @param array<string> $source_taints
     * @param array<DataFlowNode> $sinks
     * @return array<string, DataFlowNode>
     */
    private function getChildNodes(DataFlowNode $generated_source, array $source_taints, array $sinks, array $visited_source_ids) : array
    {
        $new_sources = [];
        $config = Config::getInstance();
        $project_analyzer = ProjectAnalyzer::getInstance();
        foreach ($this->forward_edges[$generated_source->id] as $to_id => $path) {
            $path_type = $path->type;
            $added_taints = $path->unescaped_taints ?: [];
            $removed_taints = $path->escaped_taints ?: [];
            if (!isset($this->nodes[$to_id])) {
                continue;
            }
            $destination_node = $this->nodes[$to_id];
            $new_taints = array_unique(array_diff(array_merge($source_taints, $added_taints), $removed_taints));
            sort($new_taints);
            if (isset($visited_source_ids[$to_id][implode(',', $new_taints)])) {
                continue;
            }
            if (self::shouldIgnoreFetch($path_type, 'arraykey', $generated_source->path_types)) {
                continue;
            }
            if (self::shouldIgnoreFetch($path_type, 'arrayvalue', $generated_source->path_types)) {
                continue;
            }
            if (self::shouldIgnoreFetch($path_type, 'property', $generated_source->path_types)) {
                continue;
            }
            if ($generated_source->code_location && $project_analyzer->canReportIssues($generated_source->code_location->file_path) && !$config->reportIssueInFile('TaintedInput', $generated_source->code_location->file_path)) {
                continue;
            }
            if (isset($sinks[$to_id])) {
                $matching_taints = array_intersect($sinks[$to_id]->taints, $new_taints);
                if ($matching_taints && $generated_source->code_location) {
                    if ($sinks[$to_id]->code_location && $config->reportIssueInFile('TaintedInput', $sinks[$to_id]->code_location->file_path)) {
                        $issue_location = $sinks[$to_id]->code_location;
                    } else {
                        $issue_location = $generated_source->code_location;
                    }
                    $issue_trace = $this->getIssueTrace($generated_source);
                    $path = $this->getPredecessorPath($generated_source) . ' -> ' . $this->getSuccessorPath($sinks[$to_id]);
                    foreach ($matching_taints as $matching_taint) {
                        switch ($matching_taint) {
                            case TaintKind::INPUT_CALLABLE:
                                $issue = new TaintedCallable('Detected tainted text', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_UNSERIALIZE:
                                $issue = new TaintedUnserialize('Detected tainted code passed to unserialize or similar', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_INCLUDE:
                                $issue = new TaintedInclude('Detected tainted code passed to include or similar', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_EVAL:
                                $issue = new TaintedEval('Detected tainted code passed to eval or similar', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_SQL:
                                $issue = new TaintedSql('Detected tainted SQL', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_HTML:
                                $issue = new TaintedHtml('Detected tainted HTML', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_HAS_QUOTES:
                                $issue = new TaintedTextWithQuotes('Detected tainted text with possible quotes', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_SHELL:
                                $issue = new TaintedShell('Detected tainted shell code', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::USER_SECRET:
                                $issue = new TaintedUserSecret('Detected tainted user secret leaking', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::SYSTEM_SECRET:
                                $issue = new TaintedSystemSecret('Detected tainted system secret leaking', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_SSRF:
                                $issue = new TaintedSSRF('Detected tainted network request', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_LDAP:
                                $issue = new TaintedLdap('Detected tainted LDAP request', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_COOKIE:
                                $issue = new TaintedCookie('Detected tainted cookie', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_FILE:
                                $issue = new TaintedFile('Detected tainted file handling', $issue_location, $issue_trace, $path);
                                break;
                            case TaintKind::INPUT_HEADER:
                                $issue = new TaintedHeader('Detected tainted header', $issue_location, $issue_trace, $path);
                                break;
                            default:
                                $issue = new TaintedCustom('Detected tainted ' . $matching_taint, $issue_location, $issue_trace, $path);
                        }
                        IssueBuffer::maybeAdd($issue);
                    }
                }
            }
            $new_destination = clone $destination_node;
            $new_destination->previous = $generated_source;
            $new_destination->taints = $new_taints;
            $new_destination->specialized_calls = $generated_source->specialized_calls;
            $new_destination->path_types = [...$generated_source->path_types, ...[$path_type]];
            $key = $to_id . ' ' . json_encode($new_destination->specialized_calls, JSON_THROW_ON_ERROR) . ' ' . json_encode($new_destination->taints, JSON_THROW_ON_ERROR);
            $new_sources[$key] = $new_destination;
        }
        return $new_sources;
    }
    /** @return array<int, DataFlowNode> */
    private function getSpecializedSources(DataFlowNode $source) : array
    {
        $generated_sources = [];
        if (isset($this->forward_edges[$source->id])) {
            return [$source];
        }
        if ($source->specialization_key && isset($this->specialized_calls[$source->specialization_key])) {
            $generated_source = clone $source;
            $generated_source->id = substr($source->id, 0, -strlen($source->specialization_key) - 1);
            $generated_source->specialized_calls[$source->specialization_key][$generated_source->id] = \true;
            $generated_sources[] = $generated_source;
        } elseif (isset($this->specializations[$source->id])) {
            foreach ($this->specializations[$source->id] as $specialization => $_) {
                if (!$source->specialized_calls || isset($source->specialized_calls[$specialization])) {
                    $new_source = clone $source;
                    $new_source->id = $source->id . '-' . $specialization;
                    unset($new_source->specialized_calls[$specialization]);
                    $generated_sources[] = $new_source;
                }
            }
        } else {
            foreach ($source->specialized_calls as $key => $map) {
                if (isset($map[$source->id]) && isset($this->forward_edges[$source->id . '-' . $key])) {
                    $new_source = clone $source;
                    $new_source->id = $source->id . '-' . $key;
                    $generated_sources[] = $new_source;
                }
            }
        }
        return array_filter($generated_sources, [$this, 'doesForwardEdgeExist']);
    }
    private function doesForwardEdgeExist(DataFlowNode $new_source) : bool
    {
        return isset($this->forward_edges[$new_source->id]);
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Exception;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Closure as ClosureNode;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\DynamicFunctionStorageProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Provider\FunctionExistenceProvider;
use Psalm\Internal\Provider\FunctionParamsProvider;
use Psalm\Internal\Provider\FunctionReturnTypeProvider;
use Psalm\Internal\Type\Comparator\CallableTypeComparator;
use Psalm\NodeTypeProvider;
use Psalm\StatementsSource;
use Psalm\Storage\FunctionStorage;
use Psalm\Type\Atomic\TNamedObject;
use UnexpectedValueException;
use function array_shift;
use function count;
use function end;
use function explode;
use function implode;
use function in_array;
use function is_bool;
use function rtrim;
use function strpos;
use function strtolower;
use function substr;
/**
 * @internal
 */
class Functions
{
    private FileStorageProvider $file_storage_provider;
    /**
     * @var array<lowercase-string, FunctionStorage>
     */
    private static array $stubbed_functions;
    public FunctionReturnTypeProvider $return_type_provider;
    public FunctionExistenceProvider $existence_provider;
    public FunctionParamsProvider $params_provider;
    public DynamicFunctionStorageProvider $dynamic_storage_provider;
    private \Psalm\Internal\Codebase\Reflection $reflection;
    public function __construct(FileStorageProvider $storage_provider, \Psalm\Internal\Codebase\Reflection $reflection)
    {
        $this->file_storage_provider = $storage_provider;
        $this->reflection = $reflection;
        $this->return_type_provider = new FunctionReturnTypeProvider();
        $this->existence_provider = new FunctionExistenceProvider();
        $this->params_provider = new FunctionParamsProvider();
        $this->dynamic_storage_provider = new DynamicFunctionStorageProvider();
        self::$stubbed_functions = [];
    }
    /**
     * @param non-empty-lowercase-string $function_id
     */
    public function getStorage(?StatementsAnalyzer $statements_analyzer, string $function_id, ?string $root_file_path = null, ?string $checked_file_path = null) : FunctionStorage
    {
        if ($function_id[0] === '\\') {
            $function_id = substr($function_id, 1);
        }
        $from_stubs = \false;
        if (isset(self::$stubbed_functions[$function_id])) {
            $from_stubs = self::$stubbed_functions[$function_id];
        }
        $file_storage = null;
        if ($statements_analyzer) {
            $root_file_path = $statements_analyzer->getRootFilePath();
            $checked_file_path = $statements_analyzer->getFilePath();
            $file_storage = $this->file_storage_provider->get($root_file_path);
            $function_analyzers = $statements_analyzer->getFunctionAnalyzers();
            if (isset($function_analyzers[$function_id])) {
                $function_id = $function_analyzers[$function_id]->getFunctionId();
                if (isset($file_storage->functions[$function_id])) {
                    return $file_storage->functions[$function_id];
                }
            }
            // closures can be returned here
            if (isset($file_storage->functions[$function_id])) {
                return $file_storage->functions[$function_id];
            }
        }
        if (!$root_file_path || !$checked_file_path) {
            if ($this->reflection->hasFunction($function_id)) {
                return $this->reflection->getFunctionStorage($function_id);
            }
            if ($from_stubs) {
                return $from_stubs;
            }
            throw new UnexpectedValueException('Expecting non-empty $root_file_path and $checked_file_path');
        }
        if ($this->reflection->hasFunction($function_id)) {
            return $this->reflection->getFunctionStorage($function_id);
        }
        if (!isset($file_storage->declaring_function_ids[$function_id])) {
            if ($checked_file_path !== $root_file_path) {
                $file_storage = $this->file_storage_provider->get($checked_file_path);
                if (isset($file_storage->functions[$function_id])) {
                    return $file_storage->functions[$function_id];
                }
            }
            if ($from_stubs) {
                return $from_stubs;
            }
            throw new UnexpectedValueException('Expecting ' . $function_id . ' to have storage in ' . $checked_file_path);
        }
        $declaring_file_path = $file_storage->declaring_function_ids[$function_id];
        $declaring_file_storage = $this->file_storage_provider->get($declaring_file_path);
        if (!isset($declaring_file_storage->functions[$function_id])) {
            if ($from_stubs) {
                return $from_stubs;
            }
            throw new UnexpectedValueException('Not expecting ' . $function_id . ' to not have storage in ' . $declaring_file_path);
        }
        return $declaring_file_storage->functions[$function_id];
    }
    public function addGlobalFunction(string $function_id, FunctionStorage $storage) : void
    {
        self::$stubbed_functions[strtolower($function_id)] = $storage;
    }
    public function hasStubbedFunction(string $function_id) : bool
    {
        return isset(self::$stubbed_functions[strtolower($function_id)]);
    }
    /**
     * @return array<string, FunctionStorage>
     */
    public function getAllStubbedFunctions() : array
    {
        return self::$stubbed_functions;
    }
    /**
     * @param lowercase-string $function_id
     */
    public function functionExists(StatementsAnalyzer $statements_analyzer, string $function_id) : bool
    {
        if ($this->existence_provider->has($function_id)) {
            $function_exists = $this->existence_provider->doesFunctionExist($statements_analyzer, $function_id);
            if ($function_exists !== null) {
                return $function_exists;
            }
        }
        $file_storage = $this->file_storage_provider->get($statements_analyzer->getRootFilePath());
        if (isset($file_storage->declaring_function_ids[$function_id])) {
            return \true;
        }
        if ($this->reflection->hasFunction($function_id)) {
            return \true;
        }
        if (isset(self::$stubbed_functions[$function_id])) {
            return \true;
        }
        if (isset($statements_analyzer->getFunctionAnalyzers()[$function_id])) {
            return \true;
        }
        $predefined_functions = $statements_analyzer->getCodebase()->config->getPredefinedFunctions();
        if (isset($predefined_functions[$function_id])) {
            /** @psalm-suppress ArgumentTypeCoercion */
            if ($this->reflection->registerFunction($function_id) === \false) {
                return \false;
            }
            return \true;
        }
        return \false;
    }
    /**
     * @param  non-empty-string         $function_name
     * @return non-empty-string
     */
    public function getFullyQualifiedFunctionNameFromString(string $function_name, StatementsSource $source) : string
    {
        if ($function_name[0] === '\\') {
            $function_name = substr($function_name, 1);
            if ($function_name === '') {
                throw new UnexpectedValueException('Malformed function name');
            }
            return $function_name;
        }
        $function_name_lcase = strtolower($function_name);
        $aliases = $source->getAliases();
        $imported_function_namespaces = $aliases->functions;
        $imported_namespaces = $aliases->uses;
        if (strpos($function_name, '\\') !== \false) {
            $function_name_parts = explode('\\', $function_name);
            $first_namespace = array_shift($function_name_parts);
            $first_namespace_lcase = strtolower($first_namespace);
            if (isset($imported_namespaces[$first_namespace_lcase])) {
                return $imported_namespaces[$first_namespace_lcase] . '\\' . implode('\\', $function_name_parts);
            }
            if (isset($imported_function_namespaces[$first_namespace_lcase])) {
                return $imported_function_namespaces[$first_namespace_lcase] . '\\' . implode('\\', $function_name_parts);
            }
        } elseif (isset($imported_function_namespaces[$function_name_lcase])) {
            return $imported_function_namespaces[$function_name_lcase];
        }
        $namespace = $source->getNamespace();
        return ($namespace ? $namespace . '\\' : '') . $function_name;
    }
    /**
     * @return array<lowercase-string,FunctionStorage>
     */
    public function getMatchingFunctionNames(string $stub, int $offset, string $file_path, Codebase $codebase) : array
    {
        if ($stub[0] === '*') {
            $stub = substr($stub, 1);
        }
        $fully_qualified = \false;
        if ($stub[0] === '\\') {
            $fully_qualified = \true;
            $stub = substr($stub, 1);
            $stub_namespace = '';
        } else {
            // functions can reference either the current namespace or root-namespaced
            // equivalents. We therefore want to make both candidates.
            [$stub_namespace, $stub] = explode('-', $stub);
        }
        /** @var array<lowercase-string, FunctionStorage> */
        $matching_functions = [];
        $file_storage = $this->file_storage_provider->get($file_path);
        $current_namespace_aliases = null;
        foreach ($file_storage->namespace_aliases as $namespace_start => $namespace_aliases) {
            if ($namespace_start < $offset) {
                $current_namespace_aliases = $namespace_aliases;
                break;
            }
        }
        // We will search all functions for several patterns. This will
        // be for all used namespaces, the global namespace and matched
        // used functions.
        $match_function_patterns = [$stub . '*'];
        if ($stub_namespace) {
            $match_function_patterns[] = $stub_namespace . '\\' . $stub . '*';
        }
        if ($current_namespace_aliases) {
            foreach ($current_namespace_aliases->functions as $alias_name => $function_name) {
                if (strpos($alias_name, $stub) === 0) {
                    try {
                        $match_function_patterns[] = $function_name;
                    } catch (Exception $e) {
                    }
                }
            }
            if (!$fully_qualified) {
                foreach ($current_namespace_aliases->uses as $namespace_name) {
                    $match_function_patterns[] = $namespace_name . '\\' . $stub . '*';
                }
            }
        }
        $function_map = $file_storage->functions + $this->getAllStubbedFunctions() + $this->reflection->getFunctions() + $codebase->config->getPredefinedFunctions();
        foreach ($function_map as $function_name => $function) {
            foreach ($match_function_patterns as $pattern) {
                $pattern_lc = strtolower($pattern);
                if (substr($pattern, -1, 1) === '*') {
                    if (strpos($function_name, rtrim($pattern_lc, '*')) !== 0) {
                        continue;
                    }
                } elseif ($function_name !== $pattern) {
                    continue;
                }
                if (is_bool($function)) {
                    /** @var callable-string $function_name */
                    if ($this->reflection->registerFunction($function_name) === \false) {
                        continue;
                    }
                    $function = $this->reflection->getFunctionStorage($function_name);
                }
                if ($function->cased_name) {
                    $cased_name_parts = explode('\\', $function->cased_name);
                    $pattern_parts = explode('\\', $pattern);
                    if (end($cased_name_parts)[0] !== end($pattern_parts)[0]) {
                        continue;
                    }
                }
                /** @var lowercase-string $function_name */
                $matching_functions[$function_name] = $function;
            }
        }
        return $matching_functions;
    }
    public static function isVariadic(Codebase $codebase, string $function_id, string $file_path) : bool
    {
        $file_storage = $codebase->file_storage_provider->get($file_path);
        if (!isset($file_storage->declaring_function_ids[$function_id])) {
            return \false;
        }
        $declaring_file_path = $file_storage->declaring_function_ids[$function_id];
        $file_storage = $declaring_file_path === $file_path ? $file_storage : $codebase->file_storage_provider->get($declaring_file_path);
        return isset($file_storage->functions[$function_id]) && $file_storage->functions[$function_id]->variadic;
    }
    /**
     * @param ?list<Arg> $args
     */
    public function isCallMapFunctionPure(Codebase $codebase, ?NodeTypeProvider $type_provider, string $function_id, ?array $args, bool &$must_use = \true) : bool
    {
        $impure_functions = [
            // file io
            'chdir',
            'chgrp',
            'chmod',
            'chown',
            'chroot',
            'copy',
            'file_get_contents',
            'file_put_contents',
            'opendir',
            'readdir',
            'closedir',
            'rewinddir',
            'scandir',
            'fopen',
            'fread',
            'fwrite',
            'fclose',
            'touch',
            'fpassthru',
            'fputs',
            'fscanf',
            'fseek',
            'flock',
            'ftruncate',
            'fprintf',
            'symlink',
            'mkdir',
            'unlink',
            'rename',
            'rmdir',
            'popen',
            'pclose',
            'fgetcsv',
            'fputcsv',
            'umask',
            'finfo_open',
            'finfo_close',
            'finfo_file',
            'stream_set_timeout',
            'fgets',
            'fflush',
            'move_uploaded_file',
            'file_exists',
            'realpath',
            'glob',
            'is_readable',
            'is_dir',
            'is_file',
            // stream/socket io
            'stream_context_set_option',
            'socket_write',
            'stream_set_blocking',
            'socket_close',
            'socket_set_option',
            'stream_set_write_buffer',
            'stream_socket_enable_crypto',
            'stream_copy_to_stream',
            'stream_wrapper_register',
            'socket_connect',
            'socket_bind',
            'socket_set_block',
            'socket_set_nonblock',
            'socket_listen',
            // meta calls
            'call_user_func',
            'call_user_func_array',
            'define',
            'create_function',
            // http
            'header',
            'header_remove',
            'http_response_code',
            'setcookie',
            // output buffer
            'ob_start',
            'ob_end_clean',
            'ob_get_clean',
            'readfile',
            'printf',
            'var_dump',
            'phpinfo',
            'ob_implicit_flush',
            'vprintf',
            // mcrypt
            'mcrypt_generic_init',
            'mcrypt_generic_deinit',
            'mcrypt_module_close',
            // internal optimisation
            'opcache_compile_file',
            'clearstatcache',
            // process-related
            'pcntl_signal',
            'pcntl_alarm',
            'posix_kill',
            'cli_set_process_title',
            'pcntl_async_signals',
            'proc_close',
            'proc_nice',
            'proc_open',
            'proc_terminate',
            // curl
            'curl_setopt',
            'curl_close',
            'curl_multi_add_handle',
            'curl_multi_remove_handle',
            'curl_multi_select',
            'curl_multi_close',
            'curl_setopt_array',
            // apc, apcu
            'apc_store',
            'apc_delete',
            'apc_clear_cache',
            'apc_add',
            'apc_inc',
            'apc_dec',
            'apc_cas',
            'apcu_store',
            'apcu_delete',
            'apcu_clear_cache',
            'apcu_add',
            'apcu_inc',
            'apcu_dec',
            'apcu_cas',
            // gz
            'gzwrite',
            'gzrewind',
            'gzseek',
            'gzclose',
            // newrelic
            'newrelic_start_transaction',
            'newrelic_name_transaction',
            'newrelic_add_custom_parameter',
            'newrelic_add_custom_tracer',
            'newrelic_background_job',
            'newrelic_end_transaction',
            'newrelic_set_appname',
            // execution
            'shell_exec',
            'exec',
            'system',
            'passthru',
            'pcntl_exec',
            // well-known functions
            'libxml_use_internal_errors',
            'libxml_disable_entity_loader',
            'curl_exec',
            'mt_srand',
            'openssl_pkcs7_sign',
            'openssl_sign',
            'mt_rand',
            'rand',
            'random_int',
            'random_bytes',
            'wincache_ucache_delete',
            'wincache_ucache_set',
            'wincache_ucache_inc',
            'class_alias',
            'class_exists',
            // impure by virtue of triggering autoloader
            'enum_exists',
            // impure by virtue of triggering autoloader
            // php environment
            'ini_set',
            'sleep',
            'usleep',
            'register_shutdown_function',
            'error_reporting',
            'register_tick_function',
            'unregister_tick_function',
            'set_error_handler',
            'user_error',
            'trigger_error',
            'restore_error_handler',
            'date_default_timezone_set',
            'assert_options',
            'setlocale',
            'set_exception_handler',
            'set_time_limit',
            'putenv',
            'spl_autoload_register',
            'spl_autoload_unregister',
            'microtime',
            'array_rand',
            'set_include_path',
            // logging
            'openlog',
            'syslog',
            'error_log',
            'define_syslog_variables',
            // session
            'session_id',
            'session_decode',
            'session_name',
            'session_set_cookie_params',
            'session_set_save_handler',
            'session_regenerate_id',
            'mb_internal_encoding',
            'session_start',
            'session_cache_limiter',
            // ldap
            'ldap_set_option',
            // iterators
            'rewind',
            'iterator_apply',
            'iterator_to_array',
            // mysqli
            'mysqli_select_db',
            'mysqli_dump_debug_info',
            'mysqli_kill',
            'mysqli_multi_query',
            'mysqli_next_result',
            'mysqli_options',
            'mysqli_ping',
            'mysqli_query',
            'mysqli_report',
            'mysqli_rollback',
            'mysqli_savepoint',
            'mysqli_set_charset',
            'mysqli_ssl_set',
            'mysqli_close',
            // script execution
            'ignore_user_abort',
            // ftp
            'ftp_close',
            'ftp_pasv',
            // bcmath
            'bcscale',
            // json
            'json_last_error',
            // opcache
            'opcache_compile_file',
            'opcache_get_configuration',
            'opcache_get_status',
            'opcache_invalidate',
            'opcache_is_script_cached',
            'opcache_reset',
            //gettext
            'bindtextdomain',
            // hash
            'hash_update',
            'hash_update_file',
            'hash_update_stream',
            // unserialize
            'unserialize',
        ];
        if (in_array(strtolower($function_id), $impure_functions, \true)) {
            return \false;
        }
        if ($function_id === 'serialize' && isset($args[0]) && $type_provider) {
            $serialize_type = $type_provider->getType($args[0]->value);
            if ($serialize_type && $serialize_type->canContainObjectType($codebase)) {
                return \false;
            }
        }
        if (strpos($function_id, 'image') === 0) {
            return \false;
        }
        if (strpos($function_id, 'readline') === 0) {
            return \false;
        }
        if (($function_id === 'var_export' || $function_id === 'print_r') && !isset($args[1])) {
            return \false;
        }
        if ($function_id === 'assert') {
            $must_use = \false;
            return \true;
        }
        if ($function_id === 'func_num_args' || $function_id === 'func_get_args') {
            return \true;
        }
        if ($function_id === 'count' && isset($args[0]) && $type_provider) {
            $count_type = $type_provider->getType($args[0]->value);
            if ($count_type) {
                foreach ($count_type->getAtomicTypes() as $atomic_count_type) {
                    if ($atomic_count_type instanceof TNamedObject) {
                        $count_method_id = new MethodIdentifier($atomic_count_type->value, 'count');
                        try {
                            return $codebase->methods->getStorage($count_method_id)->mutation_free;
                        } catch (Exception $e) {
                            // do nothing
                        }
                    }
                }
            }
        }
        $function_callable = \Psalm\Internal\Codebase\InternalCallMapHandler::getCallableFromCallMapById($codebase, $function_id, $args ?: [], null);
        if (!$function_callable->params || $args !== null && count($args) === 0 || $function_callable->return_type && $function_callable->return_type->isVoid()) {
            return \false;
        }
        $must_use = $function_id !== 'array_map' || isset($args[0]) && !$args[0]->value instanceof ClosureNode;
        foreach ($function_callable->params as $i => $param) {
            if ($type_provider && $param->type && $param->type->hasCallableType() && isset($args[$i])) {
                $arg_type = $type_provider->getType($args[$i]->value);
                if ($arg_type) {
                    foreach ($arg_type->getAtomicTypes() as $possible_callable) {
                        $possible_callable = CallableTypeComparator::getCallableFromAtomic($codebase, $possible_callable);
                        if ($possible_callable && !$possible_callable->is_pure) {
                            return \false;
                        }
                    }
                }
            }
            if ($param->by_ref && isset($args[$i])) {
                $must_use = \false;
            }
        }
        return \true;
    }
    public static function clearCache() : void
    {
        self::$stubbed_functions = [];
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Closure;
use Psalm\Codebase;
use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\ErrorHandler;
use Psalm\Internal\Fork\Pool;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\IssueBuffer;
use Psalm\Progress\Progress;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Type;
use ReflectionClass;
use Throwable;
use UnexpectedValueException;
use function array_filter;
use function array_merge;
use function array_pop;
use function ceil;
use function count;
use function error_reporting;
use function explode;
use function file_exists;
use function min;
use function realpath;
use function strtolower;
use function substr;
use const DIRECTORY_SEPARATOR;
use const PHP_EOL;
/**
 * @psalm-type  ThreadData = array{
 *     array<string, string>,
 *     array<string, string>,
 *     array<string, string>,
 *     array<string, bool>,
 *     array<string, bool>,
 *     array<string, string>,
 *     array<string, bool>,
 *     array<string, bool>,
 *     array<string, bool>
 * }
 *
 * @psalm-type  PoolData = array{
 *     classlikes_data:array{
 *         array<lowercase-string, bool>,
 *         array<lowercase-string, bool>,
 *         array<lowercase-string, bool>,
 *         array<string, bool>,
 *         array<lowercase-string, bool>,
 *         array<string, bool>,
 *         array<lowercase-string, bool>,
 *         array<string, bool>,
 *         array<string, bool>
 *     },
 *     scanner_data: ThreadData,
 *     issues:array<string, list<IssueData>>,
 *     changed_members:array<string, array<string, bool>>,
 *     unchanged_signature_members:array<string, array<string, bool>>,
 *     diff_map:array<string, array<int, array{int, int, int, int}>>,
 *     deletion_ranges:array<string, array<int, array{int, int}>>,
 *     errors:array<string, bool>,
 *     classlike_storage:array<string, ClassLikeStorage>,
 *     file_storage:array<lowercase-string, FileStorage>,
 *     new_file_content_hashes: array<string, string>,
 *     taint_data: ?TaintFlowGraph
 * }
 */
/**
 * @internal
 *
 * Contains methods that aid in the scanning of Psalm's codebase
 */
class Scanner
{
    private Codebase $codebase;
    /**
     * @var array<string, string>
     */
    private array $classlike_files = [];
    /**
     * @var array<string, bool>
     */
    private array $deep_scanned_classlike_files = [];
    /**
     * @var array<string, string>
     */
    private array $files_to_scan = [];
    /**
     * @var array<string, string>
     */
    private array $classes_to_scan = [];
    /**
     * @var array<string, bool>
     */
    private array $classes_to_deep_scan = [];
    /**
     * @var array<string, string>
     */
    private array $files_to_deep_scan = [];
    /**
     * @var array<string, bool>
     */
    private array $scanned_files = [];
    /**
     * @var array<string, bool>
     */
    private array $store_scan_failure = [];
    /**
     * @var array<string, bool>
     */
    private array $reflected_classlikes_lc = [];
    private \Psalm\Internal\Codebase\Reflection $reflection;
    private Config $config;
    private Progress $progress;
    private FileStorageProvider $file_storage_provider;
    private FileProvider $file_provider;
    private FileReferenceProvider $file_reference_provider;
    private bool $is_forked = \false;
    public function __construct(Codebase $codebase, Config $config, FileStorageProvider $file_storage_provider, FileProvider $file_provider, \Psalm\Internal\Codebase\Reflection $reflection, FileReferenceProvider $file_reference_provider, Progress $progress)
    {
        $this->codebase = $codebase;
        $this->reflection = $reflection;
        $this->file_provider = $file_provider;
        $this->progress = $progress;
        $this->file_storage_provider = $file_storage_provider;
        $this->config = $config;
        $this->file_reference_provider = $file_reference_provider;
    }
    /**
     * @param array<string, string> $files_to_scan
     */
    public function addFilesToShallowScan(array $files_to_scan) : void
    {
        $this->files_to_scan += $files_to_scan;
    }
    /**
     * @param array<string, string> $files_to_scan
     */
    public function addFilesToDeepScan(array $files_to_scan) : void
    {
        $this->files_to_scan += $files_to_scan;
        $this->files_to_deep_scan += $files_to_scan;
    }
    public function addFileToShallowScan(string $file_path) : void
    {
        $this->files_to_scan[$file_path] = $file_path;
    }
    public function addFileToDeepScan(string $file_path) : void
    {
        $this->files_to_scan[$file_path] = $file_path;
        $this->files_to_deep_scan[$file_path] = $file_path;
    }
    public function removeFile(string $file_path) : void
    {
        unset($this->scanned_files[$file_path]);
    }
    public function removeClassLike(string $fq_classlike_name_lc) : void
    {
        unset($this->classlike_files[$fq_classlike_name_lc], $this->deep_scanned_classlike_files[$fq_classlike_name_lc]);
    }
    public function setClassLikeFilePath(string $fq_classlike_name_lc, string $file_path) : void
    {
        $this->classlike_files[$fq_classlike_name_lc] = $file_path;
    }
    public function getClassLikeFilePath(string $fq_classlike_name_lc) : string
    {
        if (!isset($this->classlike_files[$fq_classlike_name_lc])) {
            throw new UnexpectedValueException('Could not find file for ' . $fq_classlike_name_lc);
        }
        return $this->classlike_files[$fq_classlike_name_lc];
    }
    /**
     * @param  array<string, mixed> $phantom_classes
     */
    public function queueClassLikeForScanning(string $fq_classlike_name, bool $analyze_too = \false, bool $store_failure = \true, array $phantom_classes = []) : void
    {
        if ($fq_classlike_name[0] === '\\') {
            $fq_classlike_name = substr($fq_classlike_name, 1);
        }
        $fq_classlike_name_lc = strtolower($fq_classlike_name);
        if ($fq_classlike_name_lc === 'static') {
            return;
        }
        // avoid checking classes that we know will just end in failure
        if ($fq_classlike_name_lc === 'null' || substr($fq_classlike_name_lc, -5) === '\\null') {
            return;
        }
        if (!isset($this->classlike_files[$fq_classlike_name_lc]) || $analyze_too && !isset($this->deep_scanned_classlike_files[$fq_classlike_name_lc])) {
            if (!isset($this->classes_to_scan[$fq_classlike_name_lc]) || $store_failure) {
                $this->classes_to_scan[$fq_classlike_name_lc] = $fq_classlike_name;
            }
            if ($analyze_too) {
                $this->classes_to_deep_scan[$fq_classlike_name_lc] = \true;
            }
            $this->store_scan_failure[$fq_classlike_name] = $store_failure;
            if (\Psalm\Internal\Codebase\PropertyMap::inPropertyMap($fq_classlike_name_lc)) {
                $public_mapped_properties = \Psalm\Internal\Codebase\PropertyMap::getPropertyMap()[$fq_classlike_name_lc];
                foreach ($public_mapped_properties as $public_mapped_property) {
                    $property_type = Type::parseString($public_mapped_property);
                    /** @psalm-suppress UnusedMethodCall */
                    $property_type->queueClassLikesForScanning($this->codebase, null, $phantom_classes + [$fq_classlike_name_lc => \true]);
                }
            }
        }
    }
    public function scanFiles(\Psalm\Internal\Codebase\ClassLikes $classlikes, int $pool_size = 1) : bool
    {
        $has_changes = \false;
        while ($this->files_to_scan || $this->classes_to_scan) {
            if ($this->files_to_scan) {
                if ($this->scanFilePaths($pool_size)) {
                    $has_changes = \true;
                }
            } else {
                $this->convertClassesToFilePaths($classlikes);
            }
        }
        return $has_changes;
    }
    private function shouldScan(string $file_path) : bool
    {
        return $this->file_provider->fileExists($file_path) && (!isset($this->scanned_files[$file_path]) || isset($this->files_to_deep_scan[$file_path]) && !$this->scanned_files[$file_path]);
    }
    private function scanFilePaths(int $pool_size) : bool
    {
        $files_to_scan = array_filter($this->files_to_scan, [$this, 'shouldScan']);
        $this->files_to_scan = [];
        if (!$files_to_scan) {
            return \false;
        }
        if (!$this->is_forked && $pool_size > 1 && count($files_to_scan) > 512) {
            $pool_size = ceil(min($pool_size, count($files_to_scan) / 256));
        } else {
            $pool_size = 1;
        }
        if ($pool_size > 1) {
            $process_file_paths = [];
            $i = 0;
            foreach ($files_to_scan as $file_path) {
                $process_file_paths[$i % $pool_size][] = $file_path;
                ++$i;
            }
            $this->progress->debug('Forking process for scanning' . PHP_EOL);
            // Run scanning one file at a time, splitting the set of
            // files up among a given number of child processes.
            $pool = new Pool(
                $this->config,
                $process_file_paths,
                function () : void {
                    $this->progress->debug('Initialising forked process for scanning' . PHP_EOL);
                    $project_analyzer = ProjectAnalyzer::getInstance();
                    $codebase = $project_analyzer->getCodebase();
                    $statements_provider = $codebase->statements_provider;
                    $codebase->scanner->isForked();
                    FileStorageProvider::deleteAll();
                    ClassLikeStorageProvider::deleteAll();
                    $statements_provider->resetDiffs();
                    $this->progress->debug('Have initialised forked process for scanning' . PHP_EOL);
                },
                Closure::fromCallable([$this, 'scanAPath']),
                /**
                 * @return PoolData
                 */
                function () {
                    $this->progress->debug('Collecting data from forked scanner process' . PHP_EOL);
                    $project_analyzer = ProjectAnalyzer::getInstance();
                    $codebase = $project_analyzer->getCodebase();
                    $statements_provider = $codebase->statements_provider;
                    return ['classlikes_data' => $codebase->classlikes->getThreadData(), 'scanner_data' => $codebase->scanner->getThreadData(), 'issues' => IssueBuffer::getIssuesData(), 'changed_members' => $statements_provider->getChangedMembers(), 'unchanged_signature_members' => $statements_provider->getUnchangedSignatureMembers(), 'diff_map' => $statements_provider->getDiffMap(), 'deletion_ranges' => $statements_provider->getDeletionRanges(), 'errors' => $statements_provider->getErrors(), 'classlike_storage' => $codebase->classlike_storage_provider->getAll(), 'file_storage' => $codebase->file_storage_provider->getAll(), 'new_file_content_hashes' => $statements_provider->parser_cache_provider ? $statements_provider->parser_cache_provider->getNewFileContentHashes() : [], 'taint_data' => $codebase->taint_flow_graph];
                }
            );
            // Wait for all tasks to complete and collect the results.
            /**
             * @var array<int, PoolData>
             */
            $forked_pool_data = $pool->wait();
            foreach ($forked_pool_data as $pool_data) {
                IssueBuffer::addIssues($pool_data['issues']);
                $this->codebase->statements_provider->addChangedMembers($pool_data['changed_members']);
                $this->codebase->statements_provider->addUnchangedSignatureMembers($pool_data['unchanged_signature_members']);
                $this->codebase->statements_provider->addDiffMap($pool_data['diff_map']);
                $this->codebase->statements_provider->addDeletionRanges($pool_data['deletion_ranges']);
                $this->codebase->statements_provider->addErrors($pool_data['errors']);
                if ($this->codebase->taint_flow_graph && $pool_data['taint_data']) {
                    $this->codebase->taint_flow_graph->addGraph($pool_data['taint_data']);
                }
                $this->codebase->file_storage_provider->addMore($pool_data['file_storage']);
                $this->codebase->classlike_storage_provider->addMore($pool_data['classlike_storage']);
                $this->codebase->classlikes->addThreadData($pool_data['classlikes_data']);
                $this->addThreadData($pool_data['scanner_data']);
                if ($this->codebase->statements_provider->parser_cache_provider) {
                    $this->codebase->statements_provider->parser_cache_provider->addNewFileContentHashes($pool_data['new_file_content_hashes']);
                }
            }
            if ($pool->didHaveError()) {
                exit(1);
            }
        } else {
            $i = 0;
            foreach ($files_to_scan as $file_path => $_) {
                $this->scanAPath($i, $file_path);
                ++$i;
            }
        }
        if ($this->codebase->statements_provider->parser_cache_provider) {
            $this->codebase->statements_provider->parser_cache_provider->saveFileContentHashes();
        }
        foreach ($files_to_scan as $scanned_file) {
            if ($this->config->hasStubFile($scanned_file)) {
                $file_storage = $this->file_storage_provider->get($scanned_file);
                foreach ($file_storage->functions as $function_storage) {
                    if ($function_storage->cased_name && !$this->codebase->functions->hasStubbedFunction($function_storage->cased_name)) {
                        $this->codebase->functions->addGlobalFunction($function_storage->cased_name, $function_storage);
                    }
                }
                foreach ($file_storage->constants as $name => $type) {
                    $this->codebase->addGlobalConstantType($name, $type);
                }
            }
        }
        $this->file_reference_provider->addClassLikeFiles($this->classlike_files);
        return \true;
    }
    private function convertClassesToFilePaths(\Psalm\Internal\Codebase\ClassLikes $classlikes) : void
    {
        $classes_to_scan = $this->classes_to_scan;
        $this->classes_to_scan = [];
        foreach ($classes_to_scan as $fq_classlike_name) {
            $fq_classlike_name_lc = strtolower($fq_classlike_name);
            if (isset($this->reflected_classlikes_lc[$fq_classlike_name_lc])) {
                continue;
            }
            if ($classlikes->isMissingClassLike($fq_classlike_name_lc)) {
                continue;
            }
            if (!isset($this->classlike_files[$fq_classlike_name_lc])) {
                if ($classlikes->doesClassLikeExist($fq_classlike_name_lc)) {
                    if ($fq_classlike_name_lc === 'self') {
                        continue;
                    }
                    $this->progress->debug('Using reflection to get metadata for ' . $fq_classlike_name . "\n");
                    /** @psalm-suppress ArgumentTypeCoercion */
                    $reflected_class = new ReflectionClass($fq_classlike_name);
                    $this->reflection->registerClass($reflected_class);
                    $this->reflected_classlikes_lc[$fq_classlike_name_lc] = \true;
                } elseif ($this->fileExistsForClassLike($classlikes, $fq_classlike_name)) {
                    $fq_classlike_name_lc = strtolower($classlikes->getUnAliasedName($fq_classlike_name_lc));
                    // even though we've checked this above, calling the method invalidates it
                    if (isset($this->classlike_files[$fq_classlike_name_lc])) {
                        $file_path = $this->classlike_files[$fq_classlike_name_lc];
                        $this->files_to_scan[$file_path] = $file_path;
                        if (isset($this->classes_to_deep_scan[$fq_classlike_name_lc])) {
                            unset($this->classes_to_deep_scan[$fq_classlike_name_lc]);
                            $this->files_to_deep_scan[$file_path] = $file_path;
                        }
                    }
                } elseif ($this->store_scan_failure[$fq_classlike_name]) {
                    $classlikes->registerMissingClassLike($fq_classlike_name_lc);
                }
            } elseif (isset($this->classes_to_deep_scan[$fq_classlike_name_lc]) && !isset($this->deep_scanned_classlike_files[$fq_classlike_name_lc])) {
                $file_path = $this->classlike_files[$fq_classlike_name_lc];
                $this->files_to_scan[$file_path] = $file_path;
                unset($this->classes_to_deep_scan[$fq_classlike_name_lc]);
                $this->files_to_deep_scan[$file_path] = $file_path;
                $this->deep_scanned_classlike_files[$fq_classlike_name_lc] = \true;
            }
        }
    }
    /**
     * @param  array<string, class-string<FileScanner>>  $filetype_scanners
     */
    private function scanFile(string $file_path, array $filetype_scanners, bool $will_analyze = \false) : void
    {
        $file_scanner = $this->getScannerForPath($file_path, $filetype_scanners, $will_analyze);
        if (isset($this->scanned_files[$file_path]) && (!$will_analyze || $this->scanned_files[$file_path])) {
            throw new UnexpectedValueException('Should not be rescanning ' . $file_path);
        }
        if (!$this->file_provider->fileExists($file_path) && $this->config->mustBeIgnored($file_path)) {
            // this should not happen, but might if the file was temporary
            return;
        }
        $file_contents = $this->file_provider->getContents($file_path);
        $from_cache = $this->file_storage_provider->has($file_path, $file_contents);
        if (!$from_cache) {
            $this->file_storage_provider->create($file_path);
        }
        $this->scanned_files[$file_path] = $will_analyze;
        $file_storage = $this->file_storage_provider->get($file_path);
        $file_scanner->scan($this->codebase, $file_storage, $from_cache, $this->progress);
        if (!$from_cache) {
            if (!$file_storage->has_visitor_issues && $this->file_storage_provider->cache) {
                $this->file_storage_provider->cache->writeToCache($file_storage, $file_contents);
            }
        } else {
            $this->codebase->statements_provider->setUnchangedFile($file_path);
            foreach ($file_storage->required_file_paths as $required_file_path) {
                if ($will_analyze) {
                    $this->addFileToDeepScan($required_file_path);
                } else {
                    $this->addFileToShallowScan($required_file_path);
                }
            }
            foreach ($file_storage->classlikes_in_file as $fq_classlike_name) {
                $this->codebase->exhumeClassLikeStorage($fq_classlike_name, $file_path);
            }
            foreach ($file_storage->required_classes as $fq_classlike_name) {
                $this->queueClassLikeForScanning($fq_classlike_name, $will_analyze, \false);
            }
            foreach ($file_storage->required_interfaces as $fq_classlike_name) {
                $this->queueClassLikeForScanning($fq_classlike_name, \false, \false);
            }
            foreach ($file_storage->referenced_classlikes as $fq_classlike_name) {
                $this->queueClassLikeForScanning($fq_classlike_name, \false, \false);
            }
            if ($this->codebase->register_autoload_files) {
                foreach ($file_storage->functions as $function_storage) {
                    if ($function_storage->cased_name && !$this->codebase->functions->hasStubbedFunction($function_storage->cased_name)) {
                        $this->codebase->functions->addGlobalFunction($function_storage->cased_name, $function_storage);
                    }
                }
                foreach ($file_storage->constants as $name => $type) {
                    $this->codebase->addGlobalConstantType($name, $type);
                }
            }
            foreach ($file_storage->classlike_aliases as $aliased_name => $unaliased_name) {
                $this->codebase->classlikes->addClassAlias($unaliased_name, $aliased_name);
            }
        }
    }
    /**
     * @param  array<string, class-string<FileScanner>>  $filetype_scanners
     */
    private function getScannerForPath(string $file_path, array $filetype_scanners, bool $will_analyze = \false) : FileScanner
    {
        $path_parts = explode(DIRECTORY_SEPARATOR, $file_path);
        $file_name_parts = explode('.', array_pop($path_parts));
        $extension = count($file_name_parts) > 1 ? array_pop($file_name_parts) : null;
        $file_name = $this->config->shortenFileName($file_path);
        if (isset($filetype_scanners[$extension])) {
            return new $filetype_scanners[$extension]($file_path, $file_name, $will_analyze);
        }
        return new FileScanner($file_path, $file_name, $will_analyze);
    }
    /**
     * @return array<string, bool>
     */
    public function getScannedFiles() : array
    {
        return $this->scanned_files;
    }
    /**
     * Checks whether a class exists, and if it does then records what file it's in
     * for later checking
     */
    private function fileExistsForClassLike(\Psalm\Internal\Codebase\ClassLikes $classlikes, string $fq_class_name) : bool
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        if (isset($this->classlike_files[$fq_class_name_lc])) {
            return \true;
        }
        if ($fq_class_name === 'self') {
            return \false;
        }
        $composer_file_path = $this->config->getComposerFilePathForClassLike($fq_class_name);
        if ($composer_file_path && file_exists($composer_file_path)) {
            $this->progress->debug('Using composer to locate file for ' . $fq_class_name . "\n");
            $classlikes->addFullyQualifiedClassLikeName($fq_class_name_lc, realpath($composer_file_path));
            return \true;
        }
        $reflected_class = ErrorHandler::runWithExceptionsSuppressed(function () use($fq_class_name) : ?ReflectionClass {
            $old_level = error_reporting();
            $this->progress->setErrorReporting();
            try {
                $this->progress->debug('Using reflection to locate file for ' . $fq_class_name . "\n");
                /** @psalm-suppress ArgumentTypeCoercion */
                return new ReflectionClass($fq_class_name);
            } catch (Throwable $e) {
                // do not cache any results here (as case-sensitive filenames can screw things up)
                return null;
            } finally {
                error_reporting($old_level);
            }
        });
        if (null === $reflected_class) {
            return \false;
        }
        $file_path = (string) $reflected_class->getFileName();
        // if the file was autoloaded but exists in evaled code only, return false
        if (!file_exists($file_path)) {
            return \false;
        }
        $new_fq_class_name = $reflected_class->getName();
        $new_fq_class_name_lc = strtolower($new_fq_class_name);
        if ($new_fq_class_name_lc !== $fq_class_name_lc) {
            $classlikes->addClassAlias($new_fq_class_name, $fq_class_name);
            $fq_class_name_lc = $new_fq_class_name_lc;
        }
        $fq_class_name = $new_fq_class_name;
        $classlikes->addFullyQualifiedClassLikeName($fq_class_name_lc);
        if ($reflected_class->isInterface()) {
            $classlikes->addFullyQualifiedInterfaceName($fq_class_name, $file_path);
        } elseif ($reflected_class->isTrait()) {
            $classlikes->addFullyQualifiedTraitName($fq_class_name, $file_path);
        } else {
            $classlikes->addFullyQualifiedClassName($fq_class_name, $file_path);
        }
        return \true;
    }
    /**
     * @return ThreadData
     */
    public function getThreadData() : array
    {
        return [$this->files_to_scan, $this->files_to_deep_scan, $this->classes_to_scan, $this->classes_to_deep_scan, $this->store_scan_failure, $this->classlike_files, $this->deep_scanned_classlike_files, $this->scanned_files, $this->reflected_classlikes_lc];
    }
    /**
     * @param ThreadData $thread_data
     */
    public function addThreadData(array $thread_data) : void
    {
        [$files_to_scan, $files_to_deep_scan, $classes_to_scan, $classes_to_deep_scan, $store_scan_failure, $classlike_files, $deep_scanned_classlike_files, $scanned_files, $reflected_classlikes_lc] = $thread_data;
        $this->files_to_scan = array_merge($files_to_scan, $this->files_to_scan);
        $this->files_to_deep_scan = array_merge($files_to_deep_scan, $this->files_to_deep_scan);
        $this->classes_to_scan = array_merge($classes_to_scan, $this->classes_to_scan);
        $this->classes_to_deep_scan = array_merge($classes_to_deep_scan, $this->classes_to_deep_scan);
        $this->store_scan_failure = array_merge($store_scan_failure, $this->store_scan_failure);
        $this->classlike_files = array_merge($classlike_files, $this->classlike_files);
        $this->deep_scanned_classlike_files = array_merge($deep_scanned_classlike_files, $this->deep_scanned_classlike_files);
        $this->scanned_files = array_merge($scanned_files, $this->scanned_files);
        $this->reflected_classlikes_lc = array_merge($reflected_classlikes_lc, $this->reflected_classlikes_lc);
    }
    public function isForked() : void
    {
        $this->is_forked = \true;
    }
    private function scanAPath(int $_, string $file_path) : void
    {
        $this->scanFile($file_path, $this->config->getFiletypeScanners(), isset($this->files_to_deep_scan[$file_path]));
    }
}
<?php

namespace Psalm\Internal\Codebase;

use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\PropertyExistenceProvider;
use Psalm\Internal\Provider\PropertyTypeProvider;
use Psalm\Internal\Provider\PropertyVisibilityProvider;
use Psalm\StatementsSource;
use Psalm\Storage\PropertyStorage;
use Psalm\Type\Union;
use UnexpectedValueException;
use function explode;
use function ltrim;
use function strtolower;
/**
 * @internal
 *
 * Handles information about class properties
 */
class Properties
{
    private ClassLikeStorageProvider $classlike_storage_provider;
    private \Psalm\Internal\Codebase\ClassLikes $classlikes;
    public bool $collect_locations = \false;
    public FileReferenceProvider $file_reference_provider;
    public PropertyExistenceProvider $property_existence_provider;
    public PropertyTypeProvider $property_type_provider;
    public PropertyVisibilityProvider $property_visibility_provider;
    public function __construct(ClassLikeStorageProvider $storage_provider, FileReferenceProvider $file_reference_provider, \Psalm\Internal\Codebase\ClassLikes $classlikes)
    {
        $this->classlike_storage_provider = $storage_provider;
        $this->file_reference_provider = $file_reference_provider;
        $this->property_existence_provider = new PropertyExistenceProvider();
        $this->property_visibility_provider = new PropertyVisibilityProvider();
        $this->property_type_provider = new PropertyTypeProvider();
        $this->classlikes = $classlikes;
    }
    /**
     * Whether or not a given property exists
     */
    public function propertyExists(string $property_id, bool $read_mode, ?StatementsSource $source = null, ?Context $context = null, ?CodeLocation $code_location = null) : bool
    {
        // remove leading backslash if it exists
        $property_id = ltrim($property_id, '\\');
        [$fq_class_name, $property_name] = explode('::$', $property_id);
        $fq_class_name_lc = strtolower($fq_class_name);
        if ($this->property_existence_provider->has($fq_class_name)) {
            $property_exists = $this->property_existence_provider->doesPropertyExist($fq_class_name, $property_name, $read_mode, $source, $context, $code_location);
            if ($property_exists !== null) {
                return $property_exists;
            }
        }
        $class_storage = $this->classlikes->getStorageFor($fq_class_name);
        if (!$class_storage) {
            return \false;
        }
        if ($source && $context && $context->self !== $fq_class_name && !$context->collect_initializations && !$context->collect_mutations) {
            if ($context->calling_method_id) {
                $this->file_reference_provider->addMethodReferenceToClass($context->calling_method_id, $fq_class_name_lc);
            } else {
                $this->file_reference_provider->addNonMethodReferenceToClass($source->getFilePath(), $fq_class_name_lc);
            }
        }
        if (isset($class_storage->declaring_property_ids[$property_name])) {
            $declaring_property_class = strtolower($class_storage->declaring_property_ids[$property_name]);
            if ($context && $context->calling_method_id) {
                $this->file_reference_provider->addMethodReferenceToClassMember($context->calling_method_id, $declaring_property_class . '::$' . $property_name, \false);
                if ($read_mode) {
                    $this->file_reference_provider->addMethodReferenceToClassProperty($context->calling_method_id, $declaring_property_class . '::$' . $property_name);
                }
            } elseif ($source) {
                $this->file_reference_provider->addFileReferenceToClassMember($source->getFilePath(), $declaring_property_class . '::$' . $property_name, \false);
                if ($read_mode) {
                    $this->file_reference_provider->addFileReferenceToClassProperty($source->getFilePath(), $declaring_property_class . '::$' . $property_name);
                }
            }
            if ($this->collect_locations && $code_location) {
                $this->file_reference_provider->addCallingLocationForClassProperty($code_location, $declaring_property_class . '::$' . $property_name);
            }
            return \true;
        }
        if ($context && $context->calling_method_id) {
            $this->file_reference_provider->addMethodReferenceToMissingClassMember($context->calling_method_id, $fq_class_name_lc . '::$' . $property_name);
        } elseif ($source) {
            $this->file_reference_provider->addFileReferenceToMissingClassMember($source->getFilePath(), $fq_class_name_lc . '::$' . $property_name);
        }
        return \false;
    }
    public function getDeclaringClassForProperty(string $property_id, bool $read_mode, ?StatementsSource $source = null) : ?string
    {
        [$fq_class_name, $property_name] = explode('::$', $property_id);
        if ($this->property_existence_provider->has($fq_class_name)) {
            if ($this->property_existence_provider->doesPropertyExist($fq_class_name, $property_name, $read_mode, $source, null)) {
                return $fq_class_name;
            }
        }
        $class_storage = $this->classlikes->getStorageFor($fq_class_name);
        if ($class_storage && isset($class_storage->declaring_property_ids[$property_name])) {
            return $class_storage->declaring_property_ids[$property_name];
        }
        return null;
    }
    /**
     * Get the class this property appears in (vs is declared in, which could give a trait)
     */
    public function getAppearingClassForProperty(string $property_id, bool $read_mode, ?StatementsSource $source = null) : ?string
    {
        [$fq_class_name, $property_name] = explode('::$', $property_id);
        if ($this->property_existence_provider->has($fq_class_name)) {
            if ($this->property_existence_provider->doesPropertyExist($fq_class_name, $property_name, $read_mode, $source, null)) {
                return $fq_class_name;
            }
        }
        $class_storage = $this->classlikes->getStorageFor($fq_class_name);
        if ($class_storage && isset($class_storage->appearing_property_ids[$property_name])) {
            $appearing_property_id = $class_storage->appearing_property_ids[$property_name];
            return explode('::$', $appearing_property_id)[0];
        }
        return null;
    }
    public function getStorage(string $property_id) : PropertyStorage
    {
        // remove leading backslash if it exists
        $property_id = ltrim($property_id, '\\');
        [$fq_class_name, $property_name] = explode('::$', $property_id);
        $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        if (isset($class_storage->declaring_property_ids[$property_name])) {
            $declaring_property_class = $class_storage->declaring_property_ids[$property_name];
            $declaring_class_storage = $this->classlike_storage_provider->get($declaring_property_class);
            if (isset($declaring_class_storage->properties[$property_name])) {
                return $declaring_class_storage->properties[$property_name];
            }
        }
        throw new UnexpectedValueException('Property ' . $property_id . ' should exist');
    }
    public function hasStorage(string $property_id) : bool
    {
        // remove leading backslash if it exists
        $property_id = ltrim($property_id, '\\');
        [$fq_class_name, $property_name] = explode('::$', $property_id);
        $class_storage = $this->classlike_storage_provider->get($fq_class_name);
        if (isset($class_storage->declaring_property_ids[$property_name])) {
            $declaring_property_class = $class_storage->declaring_property_ids[$property_name];
            $declaring_class_storage = $this->classlike_storage_provider->get($declaring_property_class);
            return isset($declaring_class_storage->properties[$property_name]);
        }
        return \false;
    }
    public function getPropertyType(string $property_id, bool $property_set, ?StatementsSource $source = null, ?Context $context = null) : ?Union
    {
        // remove leading backslash if it exists
        $property_id = ltrim($property_id, '\\');
        [$fq_class_name, $property_name] = explode('::$', $property_id);
        if ($this->property_type_provider->has($fq_class_name)) {
            $property_type = $this->property_type_provider->getPropertyType($fq_class_name, $property_name, !$property_set, $source, $context);
            if ($property_type !== null) {
                return $property_type;
            }
        }
        $class_storage = $this->classlikes->getStorageFor($fq_class_name);
        if ($class_storage && isset($class_storage->declaring_property_ids[$property_name])) {
            $declaring_property_class = $class_storage->declaring_property_ids[$property_name];
            $declaring_class_storage = $this->classlike_storage_provider->get($declaring_property_class);
            if (isset($declaring_class_storage->properties[$property_name])) {
                $storage = $declaring_class_storage->properties[$property_name];
            } else {
                throw new UnexpectedValueException('Property ' . $property_id . ' should exist');
            }
        } else {
            throw new UnexpectedValueException('Property ' . $property_id . ' should exist');
        }
        if ($storage->type) {
            if ($property_set) {
                if (isset($class_storage->pseudo_property_set_types['$' . $property_name])) {
                    return $class_storage->pseudo_property_set_types['$' . $property_name];
                }
            } else {
                if (isset($class_storage->pseudo_property_get_types['$' . $property_name])) {
                    return $class_storage->pseudo_property_get_types['$' . $property_name];
                }
            }
            return $storage->type;
        }
        if (!isset($class_storage->overridden_property_ids[$property_name])) {
            return null;
        }
        foreach ($class_storage->overridden_property_ids[$property_name] as $overridden_property_id) {
            $overridden_storage = $this->getStorage($overridden_property_id);
            if ($overridden_storage->type) {
                return $overridden_storage->type;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\Codebase;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Provider\NodeDataProvider;
use Psalm\Internal\Type\Comparator\TypeComparisonResult;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\NodeTypeProvider;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\TaintKind;
use UnexpectedValueException;
use function array_shift;
use function assert;
use function count;
use function dirname;
use function file_exists;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
use function version_compare;
/**
 * @internal
 *
 * Gets values from the call map array, which stores data about native functions and methods
 */
class InternalCallMapHandler
{
    private const PHP_MAJOR_VERSION = 8;
    private const PHP_MINOR_VERSION = 2;
    private const LOWEST_AVAILABLE_DELTA = 71;
    private static ?int $loaded_php_major_version = null;
    private static ?int $loaded_php_minor_version = null;
    /**
     * @var array<lowercase-string, array<int|string,string>>|null
     */
    private static ?array $call_map = null;
    /**
     * @var array<list<TCallable>>|null
     */
    private static ?array $call_map_callables = [];
    /**
     * @var array<string, list<list<TaintKind::*>>>
     */
    private static array $taint_sink_map = [];
    /**
     * @param  list<PhpParser\Node\Arg>   $args
     */
    public static function getCallableFromCallMapById(Codebase $codebase, string $method_id, array $args, ?NodeDataProvider $nodes) : TCallable
    {
        $possible_callables = self::getCallablesFromCallMap($method_id);
        if ($possible_callables === null) {
            throw new UnexpectedValueException('Not expecting $function_param_options to be null for ' . $method_id);
        }
        return self::getMatchingCallableFromCallMapOptions($codebase, $possible_callables, $args, $nodes, $method_id);
    }
    /**
     * @param  array<int, TCallable>  $callables
     * @param  list<PhpParser\Node\Arg>                 $args
     */
    public static function getMatchingCallableFromCallMapOptions(Codebase $codebase, array $callables, array $args, ?NodeTypeProvider $nodes, string $method_id) : TCallable
    {
        if (count($callables) === 1) {
            return $callables[0];
        }
        $matching_param_count_callable = null;
        $matching_coerced_param_count_callable = null;
        foreach ($callables as $possible_callable) {
            $possible_function_params = $possible_callable->params;
            assert($possible_function_params !== null);
            $all_args_match = \true;
            $type_coerced = \false;
            $last_param = count($possible_function_params) ? $possible_function_params[count($possible_function_params) - 1] : null;
            $mandatory_param_count = count($possible_function_params);
            foreach ($possible_function_params as $i => $possible_function_param) {
                if ($possible_function_param->is_optional) {
                    $mandatory_param_count = $i;
                    break;
                }
            }
            if ($mandatory_param_count > count($args) && !($last_param && $last_param->is_variadic)) {
                continue;
            }
            foreach ($args as $argument_offset => $arg) {
                if ($argument_offset >= count($possible_function_params)) {
                    if (!$last_param || !$last_param->is_variadic) {
                        $all_args_match = \false;
                        break;
                    }
                    $function_param = $last_param;
                } else {
                    $function_param = $possible_function_params[$argument_offset];
                }
                $param_type = $function_param->type;
                if (!$param_type) {
                    continue;
                }
                if (!$nodes || !($arg_type = $nodes->getType($arg->value))) {
                    continue;
                }
                if ($arg_type->hasMixed()) {
                    continue;
                }
                if ($arg->unpack && !$function_param->is_variadic) {
                    if ($arg_type->hasArray()) {
                        /**
                         * @var TArray|TKeyedArray
                         */
                        $array_atomic_type = $arg_type->getArray();
                        if ($array_atomic_type instanceof TKeyedArray) {
                            $arg_type = $array_atomic_type->getGenericValueType();
                        } else {
                            $arg_type = $array_atomic_type->type_params[1];
                        }
                    }
                }
                $arg_result = new TypeComparisonResult();
                if (UnionTypeComparator::isContainedBy($codebase, $arg_type, $param_type, \true, \true, $arg_result) || $arg_result->type_coerced) {
                    if ($arg_result->type_coerced) {
                        $type_coerced = \true;
                    }
                    continue;
                }
                $all_args_match = \false;
                break;
            }
            if (count($args) === count($possible_function_params)) {
                $matching_param_count_callable = $possible_callable;
            }
            if ($all_args_match && (!$type_coerced || $method_id === 'max' || $method_id === 'min')) {
                return $possible_callable;
            }
            if ($all_args_match) {
                $matching_coerced_param_count_callable = $possible_callable;
            }
        }
        if ($matching_coerced_param_count_callable) {
            return $matching_coerced_param_count_callable;
        }
        if ($matching_param_count_callable) {
            return $matching_param_count_callable;
        }
        // if we don't succeed in finding a match, set to the first possible and wait for issues below
        return $callables[0];
    }
    /**
     * @return list<TCallable>|null
     */
    public static function getCallablesFromCallMap(string $function_id) : ?array
    {
        $call_map_key = strtolower($function_id);
        if (isset(self::$call_map_callables[$call_map_key])) {
            return self::$call_map_callables[$call_map_key];
        }
        $call_map = self::getCallMap();
        if (!isset($call_map[$call_map_key])) {
            return null;
        }
        $call_map_functions = [];
        $call_map_functions[] = $call_map[$call_map_key];
        for ($i = 1; $i < 10; ++$i) {
            if (!isset($call_map[$call_map_key . '\'' . $i])) {
                break;
            }
            $call_map_functions[] = $call_map[$call_map_key . '\'' . $i];
        }
        $possible_callables = [];
        foreach ($call_map_functions as $call_map_function_args) {
            $return_type_string = array_shift($call_map_function_args);
            if (!$return_type_string) {
                $return_type = Type::getMixed();
            } else {
                $return_type = Type::parseString($return_type_string);
            }
            $function_params = [];
            $arg_offset = 0;
            /** @var string $arg_name - key type changed with above array_shift */
            foreach ($call_map_function_args as $arg_name => $arg_type) {
                $by_reference = \false;
                $optional = \false;
                $variadic = \false;
                if ($arg_name[0] === '&') {
                    $arg_name = substr($arg_name, 1);
                    $by_reference = \true;
                }
                if (substr($arg_name, -1) === '=') {
                    $arg_name = substr($arg_name, 0, -1);
                    $optional = \true;
                }
                if (strpos($arg_name, '...') === 0) {
                    $arg_name = substr($arg_name, 3);
                    $variadic = \true;
                }
                $param_type = $arg_type ? Type::parseString($arg_type) : Type::getMixed();
                $out_type = null;
                if (strlen($arg_name) > 2 && $arg_name[0] === 'w' && $arg_name[1] === '_') {
                    $out_type = $param_type;
                    $param_type = Type::getMixed();
                }
                $function_param = new FunctionLikeParameter($arg_name, $by_reference, $param_type, $param_type, null, null, $optional, \false, $variadic);
                if ($out_type) {
                    $function_param->out_type = $out_type;
                }
                if ($arg_name === 'haystack') {
                    $function_param->expect_variable = \true;
                }
                if (isset(self::$taint_sink_map[$call_map_key][$arg_offset])) {
                    $function_param->sinks = self::$taint_sink_map[$call_map_key][$arg_offset];
                }
                $function_param->signature_type = null;
                $function_params[] = $function_param;
                $arg_offset++;
            }
            $possible_callables[] = new TCallable('callable', $function_params, $return_type);
        }
        self::$call_map_callables[$call_map_key] = $possible_callables;
        return $possible_callables;
    }
    /**
     * Gets the method/function call map
     *
     * @return array<string, array<int|string, string>>
     */
    public static function getCallMap() : array
    {
        $codebase = ProjectAnalyzer::getInstance()->getCodebase();
        $analyzer_major_version = $codebase->getMajorAnalysisPhpVersion();
        $analyzer_minor_version = $codebase->getMinorAnalysisPhpVersion();
        $analyzer_version = $analyzer_major_version . '.' . $analyzer_minor_version;
        $current_version = self::PHP_MAJOR_VERSION . '.' . self::PHP_MINOR_VERSION;
        $analyzer_version_int = (int) ($analyzer_major_version . $analyzer_minor_version);
        $current_version_int = (int) (self::PHP_MAJOR_VERSION . self::PHP_MINOR_VERSION);
        if (self::$call_map !== null && $analyzer_major_version === self::$loaded_php_major_version && $analyzer_minor_version === self::$loaded_php_minor_version) {
            return self::$call_map;
        }
        /** @var array<string, array<int|string, string>> */
        $call_map = (require dirname(__DIR__, 4) . '/dictionaries/CallMap.php');
        self::$call_map = [];
        foreach ($call_map as $key => $value) {
            $cased_key = strtolower($key);
            self::$call_map[$cased_key] = $value;
        }
        /**
         * @var array<string, list<list<TaintKind::*>>>
         */
        $taint_map = (require dirname(__DIR__, 4) . '/dictionaries/InternalTaintSinkMap.php');
        foreach ($taint_map as $key => $value) {
            $cased_key = strtolower($key);
            self::$taint_sink_map[$cased_key] = $value;
        }
        if (version_compare($analyzer_version, $current_version, '<')) {
            // the following assumes both minor and major versions a single digits
            for ($i = $current_version_int; $i > $analyzer_version_int && $i >= self::LOWEST_AVAILABLE_DELTA; --$i) {
                $delta_file = dirname(__DIR__, 4) . '/dictionaries/CallMap_' . $i . '_delta.php';
                if (!file_exists($delta_file)) {
                    continue;
                }
                /**
                 * @var array{
                 *     added: array<string, array<int|string, string>>,
                 *     changed: array<string, array{
                 *         old: array<int|string, string>,
                 *         new: array<int|string, string>
                 *     }>,
                 *     removed: array<string, array<int|string, string>>
                 * }
                 */
                $diff_call_map = (require $delta_file);
                foreach ($diff_call_map['added'] as $key => $_) {
                    $cased_key = strtolower($key);
                    unset(self::$call_map[$cased_key]);
                }
                foreach ($diff_call_map['removed'] as $key => $value) {
                    $cased_key = strtolower($key);
                    self::$call_map[$cased_key] = $value;
                }
                foreach ($diff_call_map['changed'] as $key => ['old' => $value]) {
                    $cased_key = strtolower($key);
                    self::$call_map[$cased_key] = $value;
                }
            }
        }
        self::$loaded_php_major_version = $analyzer_major_version;
        self::$loaded_php_minor_version = $analyzer_minor_version;
        return self::$call_map;
    }
    public static function inCallMap(string $key) : bool
    {
        return isset(self::getCallMap()[strtolower($key)]);
    }
    public static function clearCache() : void
    {
        self::$call_map_callables = [];
    }
}
<?php

namespace Psalm\Internal\Codebase;

use InvalidArgumentException;
use Psalm\Exception\CircularReferenceException;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ConstFetchAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Scanner\UnresolvedConstant\ArrayOffsetFetch;
use Psalm\Internal\Scanner\UnresolvedConstant\ArraySpread;
use Psalm\Internal\Scanner\UnresolvedConstant\ArrayValue;
use Psalm\Internal\Scanner\UnresolvedConstant\ClassConstant;
use Psalm\Internal\Scanner\UnresolvedConstant\Constant;
use Psalm\Internal\Scanner\UnresolvedConstant\ScalarValue;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedAdditionOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBinaryOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBitwiseAnd;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBitwiseOr;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedBitwiseXor;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedConcatOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedDivisionOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedMultiplicationOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedSubtractionOp;
use Psalm\Internal\Scanner\UnresolvedConstant\UnresolvedTernary;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
use ReflectionProperty;
use function ctype_digit;
use function is_array;
use function is_float;
use function is_int;
use function is_string;
use function spl_object_id;
/**
 * @internal
 */
class ConstantTypeResolver
{
    public static function resolve(\Psalm\Internal\Codebase\ClassLikes $classlikes, UnresolvedConstantComponent $c, StatementsAnalyzer $statements_analyzer = null, array $visited_constant_ids = []) : Atomic
    {
        $c_id = spl_object_id($c);
        if (isset($visited_constant_ids[$c_id])) {
            throw new CircularReferenceException('Found a circular reference');
        }
        if ($c instanceof ScalarValue) {
            return self::getLiteralTypeFromScalarValue($c->value);
        }
        if ($c instanceof UnresolvedBinaryOp) {
            $left = self::resolve($classlikes, $c->left, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
            $right = self::resolve($classlikes, $c->right, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
            if ($left instanceof TMixed || $right instanceof TMixed) {
                return new TMixed();
            }
            if ($c instanceof UnresolvedConcatOp) {
                if (($left instanceof TLiteralString || $left instanceof TLiteralFloat || $left instanceof TLiteralInt) && ($right instanceof TLiteralString || $right instanceof TLiteralFloat || $right instanceof TLiteralInt)) {
                    return new TLiteralString($left->value . $right->value);
                }
                return new TString();
            }
            if ($c instanceof UnresolvedAdditionOp || $c instanceof UnresolvedSubtractionOp || $c instanceof UnresolvedDivisionOp || $c instanceof UnresolvedMultiplicationOp || $c instanceof UnresolvedBitwiseOr || $c instanceof UnresolvedBitwiseXor || $c instanceof UnresolvedBitwiseAnd) {
                if (($left instanceof TLiteralFloat || $left instanceof TLiteralInt) && ($right instanceof TLiteralFloat || $right instanceof TLiteralInt)) {
                    if ($c instanceof UnresolvedAdditionOp) {
                        return self::getLiteralTypeFromScalarValue($left->value + $right->value);
                    }
                    if ($c instanceof UnresolvedSubtractionOp) {
                        return self::getLiteralTypeFromScalarValue($left->value - $right->value);
                    }
                    if ($c instanceof UnresolvedDivisionOp) {
                        return self::getLiteralTypeFromScalarValue($left->value / $right->value);
                    }
                    if ($c instanceof UnresolvedBitwiseOr) {
                        return self::getLiteralTypeFromScalarValue($left->value | $right->value);
                    }
                    if ($c instanceof UnresolvedBitwiseXor) {
                        return self::getLiteralTypeFromScalarValue($left->value ^ $right->value);
                    }
                    if ($c instanceof UnresolvedBitwiseAnd) {
                        return self::getLiteralTypeFromScalarValue($left->value & $right->value);
                    }
                    return self::getLiteralTypeFromScalarValue($left->value * $right->value);
                }
                if ($left instanceof TKeyedArray && $right instanceof TKeyedArray) {
                    $type = new TKeyedArray($left->properties + $right->properties, null);
                    return $type;
                }
                return new TMixed();
            }
            return new TMixed();
        }
        if ($c instanceof UnresolvedTernary) {
            $cond = self::resolve($classlikes, $c->cond, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
            $if = $c->if ? self::resolve($classlikes, $c->if, $statements_analyzer, $visited_constant_ids + [$c_id => \true]) : null;
            $else = self::resolve($classlikes, $c->else, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
            if ($cond instanceof TLiteralFloat || $cond instanceof TLiteralInt || $cond instanceof TLiteralString) {
                if ($cond->value) {
                    return $if ?? $cond;
                }
            } elseif ($cond instanceof TFalse || $cond instanceof TNull) {
                return $else;
            } elseif ($cond instanceof TTrue) {
                return $if ?? $cond;
            }
        }
        if ($c instanceof ArrayValue) {
            $properties = [];
            $auto_key = 0;
            if (!$c->entries) {
                return new TArray([Type::getNever(), Type::getNever()]);
            }
            $is_list = \true;
            foreach ($c->entries as $entry) {
                if ($entry instanceof ArraySpread) {
                    $spread_array = self::resolve($classlikes, $entry->array, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
                    if ($spread_array instanceof TArray && $spread_array->isEmptyArray()) {
                        continue;
                    }
                    if (!$spread_array instanceof TKeyedArray) {
                        return new TArray([Type::getArrayKey(), Type::getMixed()]);
                    }
                    foreach ($spread_array->properties as $spread_array_type) {
                        $properties[$auto_key++] = $spread_array_type;
                    }
                    continue;
                }
                if ($entry->key) {
                    $key_type = self::resolve($classlikes, $entry->key, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
                    if (!$key_type instanceof TLiteralInt || $key_type->value !== $auto_key) {
                        $is_list = \false;
                    }
                } else {
                    $key_type = new TLiteralInt($auto_key);
                }
                if ($key_type instanceof TLiteralInt || $key_type instanceof TLiteralString) {
                    $key_value = $key_type->value;
                    if ($key_type instanceof TLiteralInt) {
                        $auto_key = $key_type->value + 1;
                    } elseif (ctype_digit($key_type->value)) {
                        $auto_key = (int) $key_type->value + 1;
                    }
                } else {
                    return new TArray([Type::getArrayKey(), Type::getMixed()]);
                }
                $value_type = new Union([self::resolve($classlikes, $entry->value, $statements_analyzer, $visited_constant_ids + [$c_id => \true])]);
                $properties[$key_value] = $value_type;
            }
            if (empty($properties)) {
                $resolved_type = new TArray([new Union([new TNever()]), new Union([new TNever()])]);
            } else {
                $resolved_type = new TKeyedArray($properties, null, null, $is_list);
            }
            return $resolved_type;
        }
        if ($c instanceof ClassConstant) {
            if ($c->name === 'class') {
                return new TLiteralClassString($c->fqcln);
            }
            $found_type = $classlikes->getClassConstantType($c->fqcln, $c->name, ReflectionProperty::IS_PRIVATE, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
            if ($found_type) {
                return $found_type->getSingleAtomic();
            }
        }
        if ($c instanceof ArrayOffsetFetch) {
            $var_type = self::resolve($classlikes, $c->array, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
            $offset_type = self::resolve($classlikes, $c->offset, $statements_analyzer, $visited_constant_ids + [$c_id => \true]);
            if ($var_type instanceof TKeyedArray && ($offset_type instanceof TLiteralInt || $offset_type instanceof TLiteralString)) {
                $union = $var_type->properties[$offset_type->value] ?? null;
                if ($union && $union->isSingle()) {
                    return $union->getSingleAtomic();
                }
            }
        }
        if ($c instanceof Constant) {
            if ($statements_analyzer) {
                $found_type = ConstFetchAnalyzer::getConstType($statements_analyzer, $c->name, $c->is_fully_qualified, null);
                if ($found_type) {
                    return $found_type->getSingleAtomic();
                }
            }
        }
        return new TMixed();
    }
    /**
     * Note: This takes an array, but any array should only contain other arrays and scalars.
     *
     * @param  array|string|int|float|bool|null $value
     */
    public static function getLiteralTypeFromScalarValue($value) : Atomic
    {
        if (is_array($value)) {
            if (empty($value)) {
                return Type::getEmptyArray()->getSingleAtomic();
            }
            $types = [];
            /** @var array|scalar|null $val */
            foreach ($value as $key => $val) {
                $types[$key] = new Union([self::getLiteralTypeFromScalarValue($val)]);
            }
            return new TKeyedArray($types, null);
        }
        if (is_string($value)) {
            return new TLiteralString($value);
        }
        if (is_int($value)) {
            return new TLiteralInt($value);
        }
        if (is_float($value)) {
            return new TLiteralFloat($value);
        }
        if ($value === \false) {
            return new TFalse();
        }
        if ($value === \true) {
            return new TTrue();
        }
        if ($value === null) {
            return new TNull();
        }
        throw new InvalidArgumentException('$value must be a scalar.');
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Internal\Codebase\Scanner;
use Psalm\Storage\FileStorage;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
use function strtolower;
/**
 * @internal
 */
class TypeScanner extends TypeVisitor
{
    private Scanner $scanner;
    private ?FileStorage $file_storage = null;
    /**
     * @var array<string, mixed>
     */
    private array $phantom_classes;
    /**
     * @param  array<string, mixed> $phantom_classes
     */
    public function __construct(Scanner $scanner, ?FileStorage $file_storage, array $phantom_classes)
    {
        $this->scanner = $scanner;
        $this->file_storage = $file_storage;
        $this->phantom_classes = $phantom_classes;
    }
    protected function enterNode(TypeNode $type) : ?int
    {
        if ($type instanceof TNamedObject) {
            $fq_classlike_name_lc = strtolower($type->value);
            if (!isset($this->phantom_classes[$type->value]) && !isset($this->phantom_classes[$fq_classlike_name_lc])) {
                $this->scanner->queueClassLikeForScanning($type->value, \false, !$type->from_docblock, $this->phantom_classes);
                if ($this->file_storage) {
                    $this->file_storage->referenced_classlikes[$fq_classlike_name_lc] = $type->value;
                }
            }
        }
        if ($type instanceof TClassConstant) {
            $this->scanner->queueClassLikeForScanning($type->fq_classlike_name, \false, !$type->from_docblock, $this->phantom_classes);
            if ($this->file_storage) {
                $fq_classlike_name_lc = strtolower($type->fq_classlike_name);
                $this->file_storage->referenced_classlikes[$fq_classlike_name_lc] = $type->fq_classlike_name;
            }
        }
        if ($type instanceof TLiteralClassString) {
            $this->scanner->queueClassLikeForScanning($type->value, \false, !$type->from_docblock, $this->phantom_classes);
            if ($this->file_storage) {
                $fq_classlike_name_lc = strtolower($type->value);
                $this->file_storage->referenced_classlikes[$fq_classlike_name_lc] = $type->value;
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use InvalidArgumentException;
use Psalm\CodeLocation;
use Psalm\CodeLocation\DocblockTypeLocation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\ClassLikeNameOptions;
use Psalm\Internal\Analyzer\MethodAnalyzer;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DeprecatedClass;
use Psalm\Issue\DeprecatedInterface;
use Psalm\Issue\InvalidTemplateParam;
use Psalm\Issue\MissingTemplateParam;
use Psalm\Issue\ReservedWord;
use Psalm\Issue\TooManyTemplateParams;
use Psalm\Issue\UndefinedConstant;
use Psalm\IssueBuffer;
use Psalm\StatementsSource;
use Psalm\Storage\MethodStorage;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TResource;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\MutableUnion;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
use Psalm\Type\Union;
use ReflectionProperty;
use function array_keys;
use function array_search;
use function count;
use function md5;
use function strpos;
use function strtolower;
/**
 * @internal
 */
class TypeChecker extends TypeVisitor
{
    private StatementsSource $source;
    private CodeLocation $code_location;
    /**
     * @var array<string>
     */
    private array $suppressed_issues;
    /**
     * @var array<string, bool>
     */
    private array $phantom_classes;
    private bool $inferred;
    private bool $inherited;
    private bool $prevent_template_covariance;
    private bool $has_errors = \false;
    private ?string $calling_method_id = null;
    /**
     * @param  array<string>    $suppressed_issues
     * @param  array<string, bool> $phantom_classes
     */
    public function __construct(StatementsSource $source, CodeLocation $code_location, array $suppressed_issues, array $phantom_classes = [], bool $inferred = \true, bool $inherited = \false, bool $prevent_template_covariance = \false, ?string $calling_method_id = null)
    {
        $this->source = $source;
        $this->code_location = $code_location;
        $this->suppressed_issues = $suppressed_issues;
        $this->phantom_classes = $phantom_classes;
        $this->inferred = $inferred;
        $this->inherited = $inherited;
        $this->prevent_template_covariance = $prevent_template_covariance;
        $this->calling_method_id = $calling_method_id;
    }
    /**
     * @return self::STOP_TRAVERSAL|self::DONT_TRAVERSE_CHILDREN|null
     */
    protected function enterNode(TypeNode $type) : ?int
    {
        if (!$type instanceof Atomic && !$type instanceof Union && !$type instanceof MutableUnion) {
            return null;
        }
        if ($type->checked) {
            return self::DONT_TRAVERSE_CHILDREN;
        }
        if ($type instanceof TNamedObject) {
            $this->checkNamedObject($type);
        } elseif ($type instanceof TClassConstant) {
            $this->checkScalarClassConstant($type);
        } elseif ($type instanceof TTemplateParam) {
            $this->checkTemplateParam($type);
        } elseif ($type instanceof TResource) {
            $this->checkResource($type);
        }
        /** @psalm-suppress InaccessibleProperty Doesn't affect anything else */
        $type->checked = \true;
        return null;
    }
    public function hasErrors() : bool
    {
        return $this->has_errors;
    }
    private function checkNamedObject(TNamedObject $atomic) : void
    {
        $codebase = $this->source->getCodebase();
        if ($this->code_location instanceof DocblockTypeLocation && $codebase->store_node_types && $atomic->offset_start !== null && $atomic->offset_end !== null) {
            $codebase->analyzer->addOffsetReference($this->source->getFilePath(), $this->code_location->raw_file_start + $atomic->offset_start, $this->code_location->raw_file_start + $atomic->offset_end, $atomic->value);
        }
        if ($this->calling_method_id && $atomic->text !== null) {
            $codebase->file_reference_provider->addMethodReferenceToClassMember($this->calling_method_id, 'use:' . $atomic->text . ':' . md5($this->source->getFilePath()), \false);
        }
        if (!isset($this->phantom_classes[strtolower($atomic->value)]) && ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($this->source, $atomic->value, $this->code_location, $this->source->getFQCLN(), $this->calling_method_id, $this->suppressed_issues, new ClassLikeNameOptions($this->inferred, \false, \true, \true, $atomic->from_docblock)) === \false) {
            $this->has_errors = \true;
            return;
        }
        $fq_class_name_lc = strtolower($atomic->value);
        if (!$this->inherited && $codebase->classlike_storage_provider->has($fq_class_name_lc) && $this->source->getFQCLN() !== $atomic->value) {
            $class_storage = $codebase->classlike_storage_provider->get($fq_class_name_lc);
            if ($class_storage->deprecated) {
                if ($class_storage->is_interface) {
                    IssueBuffer::maybeAdd(new DeprecatedInterface('Interface ' . $atomic->value . ' is marked as deprecated', $this->code_location, $atomic->value), $this->source->getSuppressedIssues() + $this->suppressed_issues);
                } else {
                    IssueBuffer::maybeAdd(new DeprecatedClass('Class ' . $atomic->value . ' is marked as deprecated', $this->code_location, $atomic->value), $this->source->getSuppressedIssues() + $this->suppressed_issues);
                }
            }
        }
        if ($atomic instanceof TGenericObject) {
            $this->checkGenericParams($atomic);
        }
    }
    private function checkGenericParams(TGenericObject $atomic) : void
    {
        $codebase = $this->source->getCodebase();
        try {
            $class_storage = $codebase->classlike_storage_provider->get(strtolower($atomic->value));
        } catch (InvalidArgumentException $e) {
            return;
        }
        $expected_type_params = $class_storage->template_types ?: [];
        $expected_param_covariants = $class_storage->template_covariants;
        $template_type_count = count($expected_type_params);
        $template_param_count = count($atomic->type_params);
        if ($template_type_count > $template_param_count) {
            IssueBuffer::maybeAdd(new MissingTemplateParam($atomic->value . ' has missing template params, expecting ' . $template_type_count, $this->code_location), $this->suppressed_issues);
        } elseif ($template_type_count < $template_param_count) {
            IssueBuffer::maybeAdd(new TooManyTemplateParams($atomic->getId() . ' has too many template params, expecting ' . $template_type_count, $this->code_location), $this->suppressed_issues);
        }
        $expected_type_param_keys = array_keys($expected_type_params);
        foreach ($atomic->type_params as $i => $type_param) {
            $this->prevent_template_covariance = $this->source instanceof MethodAnalyzer && $this->source->getMethodName() !== '__construct' && empty($expected_param_covariants[$i]);
            if (isset($expected_type_param_keys[$i])) {
                $expected_template_name = $expected_type_param_keys[$i];
                foreach ($expected_type_params[$expected_template_name] as $defining_class => $expected_type_param) {
                    $expected_type_param = TypeExpander::expandUnion($codebase, $expected_type_param, $defining_class, null, null);
                    $type_param = TypeExpander::expandUnion($codebase, $type_param, $defining_class, null, null);
                    if (!UnionTypeComparator::isContainedBy($codebase, $type_param, $expected_type_param)) {
                        IssueBuffer::maybeAdd(new InvalidTemplateParam('Extended template param ' . $expected_template_name . ' of ' . $atomic->getId() . ' expects type ' . $expected_type_param->getId() . ', type ' . $type_param->getId() . ' given', $this->code_location), $this->suppressed_issues);
                    }
                }
            }
        }
    }
    public function checkScalarClassConstant(TClassConstant $atomic) : void
    {
        $fq_classlike_name = $atomic->fq_classlike_name === 'self' ? $this->source->getClassName() : $atomic->fq_classlike_name;
        if (!$fq_classlike_name) {
            return;
        }
        if (ClassLikeAnalyzer::checkFullyQualifiedClassLikeName($this->source, $fq_classlike_name, $this->code_location, null, null, $this->suppressed_issues, new ClassLikeNameOptions($this->inferred, \false, \true, \true, $atomic->from_docblock)) === \false) {
            $this->has_errors = \true;
            return;
        }
        $const_name = $atomic->const_name;
        if (strpos($const_name, '*') !== \false) {
            TypeExpander::expandAtomic($this->source->getCodebase(), $atomic, $fq_classlike_name, $fq_classlike_name, null, \true, \true);
            $is_defined = \true;
        } else {
            $class_constant_type = $this->source->getCodebase()->classlikes->getClassConstantType($fq_classlike_name, $atomic->const_name, ReflectionProperty::IS_PRIVATE, null);
            $is_defined = null !== $class_constant_type;
        }
        if (!$is_defined) {
            IssueBuffer::maybeAdd(new UndefinedConstant('Constant ' . $fq_classlike_name . '::' . $const_name . ' is not defined', $this->code_location), $this->source->getSuppressedIssues());
        }
    }
    public function checkTemplateParam(TTemplateParam $atomic) : void
    {
        if ($this->prevent_template_covariance && strpos($atomic->defining_class, 'fn-') !== 0) {
            $codebase = $this->source->getCodebase();
            $class_storage = $codebase->classlike_storage_provider->get($atomic->defining_class);
            $template_offset = $class_storage->template_types ? array_search($atomic->param_name, array_keys($class_storage->template_types), \true) : \false;
            if ($template_offset !== \false && isset($class_storage->template_covariants[$template_offset]) && $class_storage->template_covariants[$template_offset]) {
                $method_storage = $this->source instanceof MethodAnalyzer ? $this->source->getFunctionLikeStorage() : null;
                if ($method_storage instanceof MethodStorage && $method_storage->mutation_free && !$method_storage->mutation_free_inferred) {
                    // do nothing
                } else {
                    IssueBuffer::maybeAdd(new InvalidTemplateParam('Template param ' . $atomic->param_name . ' of ' . $atomic->defining_class . ' is marked covariant and cannot be used here', $this->code_location), $this->source->getSuppressedIssues());
                }
            }
        }
    }
    public function checkResource(TResource $atomic) : void
    {
        if (!$atomic->from_docblock) {
            IssueBuffer::maybeAdd(new ReservedWord('\'resource\' is a reserved word', $this->code_location, 'resource'), $this->source->getSuppressedIssues());
        }
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
use function strtolower;
/**
 * @internal
 */
class ContainsClassLikeVisitor extends TypeVisitor
{
    /**
     * @var lowercase-string
     */
    private string $fq_classlike_name;
    private bool $contains_classlike = \false;
    /**
     * @psalm-external-mutation-free
     * @param lowercase-string $fq_classlike_name
     */
    public function __construct(string $fq_classlike_name)
    {
        $this->fq_classlike_name = $fq_classlike_name;
    }
    /**
     * @psalm-external-mutation-free
     */
    protected function enterNode(TypeNode $type) : ?int
    {
        if ($type instanceof TNamedObject) {
            if (strtolower($type->value) === $this->fq_classlike_name) {
                $this->contains_classlike = \true;
                return self::STOP_TRAVERSAL;
            }
        }
        if ($type instanceof TClassConstant) {
            if (strtolower($type->fq_classlike_name) === $this->fq_classlike_name) {
                $this->contains_classlike = \true;
                return self::STOP_TRAVERSAL;
            }
        }
        if ($type instanceof TLiteralClassString) {
            if (strtolower($type->value) === $this->fq_classlike_name) {
                $this->contains_classlike = \true;
                return self::STOP_TRAVERSAL;
            }
        }
        return null;
    }
    /**
     * @psalm-mutation-free
     */
    public function matches() : bool
    {
        return $this->contains_classlike;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
/**
 * @internal
 */
class ContainsLiteralVisitor extends TypeVisitor
{
    private bool $contains_literal = \false;
    protected function enterNode(TypeNode $type) : ?int
    {
        if ($type instanceof TLiteralString || $type instanceof TLiteralInt || $type instanceof TLiteralFloat || $type instanceof TTrue || $type instanceof TFalse) {
            $this->contains_literal = \true;
            return self::STOP_TRAVERSAL;
        }
        if ($type instanceof TArray && $type->isEmptyArray()) {
            $this->contains_literal = \true;
            return self::STOP_TRAVERSAL;
        }
        return null;
    }
    public function matches() : bool
    {
        return $this->contains_literal;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Type;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
use Psalm\Type\Union;
/**
 * @internal
 */
class TemplateTypeCollector extends TypeVisitor
{
    /**
     * @var list<TTemplateParam>
     */
    private array $template_types = [];
    protected function enterNode(TypeNode $type) : ?int
    {
        if ($type instanceof TTemplateParam) {
            $this->template_types[] = $type;
        } elseif ($type instanceof TTemplateParamClass) {
            $extends = $type->as_type;
            $this->template_types[] = new TTemplateParam($type->param_name, $extends ? new Union([$extends]) : Type::getMixed(), $type->defining_class);
        } elseif ($type instanceof TConditional) {
            $this->template_types[] = new TTemplateParam($type->param_name, Type::getMixed(), $type->defining_class);
        }
        return null;
    }
    /**
     * @return list<TTemplateParam>
     */
    public function getTemplateTypes() : array
    {
        return $this->template_types;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Codebase;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
use Psalm\Type\Union;
/** @internal */
class CanContainObjectTypeVisitor extends TypeVisitor
{
    private bool $contains_object_type = \false;
    private Codebase $codebase;
    public function __construct(Codebase $codebase)
    {
        $this->codebase = $codebase;
    }
    protected function enterNode(TypeNode $type) : ?int
    {
        if ($type instanceof Union && ($type->hasObjectType() || $type->hasIterable() || $type->hasMixed()) || $type instanceof Atomic && ($type->isObjectType() || $type->isIterable($this->codebase) || $type instanceof TMixed)) {
            $this->contains_object_type = \true;
            return self::STOP_TRAVERSAL;
        }
        return null;
    }
    public function matches() : bool
    {
        return $this->contains_object_type;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
/**
 * @internal
 */
class ContainsStaticVisitor extends TypeVisitor
{
    private bool $contains_static = \false;
    protected function enterNode(TypeNode $type) : ?int
    {
        if ($type instanceof TNamedObject && ($type->value === 'static' || $type->is_static)) {
            $this->contains_static = \true;
            return self::STOP_TRAVERSAL;
        }
        return null;
    }
    public function matches() : bool
    {
        return $this->contains_static;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\MutableTypeVisitor;
use Psalm\Type\TypeNode;
use function strtolower;
/**
 * @internal
 */
class ClasslikeReplacer extends MutableTypeVisitor
{
    private string $old;
    private string $new;
    public function __construct(string $old, string $new)
    {
        $this->old = strtolower($old);
        $this->new = $new;
    }
    protected function enterNode(TypeNode &$type) : ?int
    {
        if ($type instanceof TClassConstant) {
            if (strtolower($type->fq_classlike_name) === $this->old) {
                $type = new TClassConstant($this->new, $type->const_name, $type->from_docblock);
            }
        } elseif ($type instanceof TClassString) {
            if ($type->as !== 'object' && strtolower($type->as) === $this->old) {
                $type = new TClassString($this->new, $type->as_type, $type->is_loaded, $type->is_interface, $type->is_enum, $type->from_docblock);
            }
        } elseif ($type instanceof TNamedObject || $type instanceof TLiteralClassString) {
            if (strtolower($type->value) === $this->old) {
                $type = $type->setValue($this->new);
            }
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\MutableTypeVisitor;
use Psalm\Type\MutableUnion;
use Psalm\Type\TypeNode;
use Psalm\Type\Union;
/**
 * @internal
 */
class FromDocblockSetter extends MutableTypeVisitor
{
    private bool $from_docblock;
    public function __construct(bool $from_docblock)
    {
        $this->from_docblock = $from_docblock;
    }
    /**
     * @return self::STOP_TRAVERSAL|self::DONT_TRAVERSE_CHILDREN|null
     */
    protected function enterNode(TypeNode &$type) : ?int
    {
        if (!$type instanceof Atomic && !$type instanceof Union && !$type instanceof MutableUnion) {
            return null;
        }
        if ($type->from_docblock === $this->from_docblock) {
            return null;
        }
        if ($type instanceof MutableUnion) {
            $type->from_docblock = \true;
        } elseif ($type instanceof Union) {
            $type = $type->setProperties(['from_docblock' => $this->from_docblock]);
        } else {
            $type = $type->setFromDocblock($this->from_docblock);
        }
        if ($type instanceof TTemplateParam && $type->as->isMixed()) {
            return self::DONT_TRAVERSE_CHILDREN;
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\TypeVisitor;

use Psalm\Internal\Codebase\Methods;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\MutableTypeVisitor;
use Psalm\Type\MutableUnion;
use Psalm\Type\TypeNode;
use Psalm\Type\Union;
use function array_values;
use function count;
/**
 * @internal
 */
class TypeLocalizer extends MutableTypeVisitor
{
    /**
     * @var array<string, array<string, Union>>
     */
    private array $extends;
    private string $base_fq_class_name;
    /**
     * @param array<string, array<string, Union>> $extends
     */
    public function __construct(array $extends, string $base_fq_class_name)
    {
        $this->extends = $extends;
        $this->base_fq_class_name = $base_fq_class_name;
    }
    protected function enterNode(TypeNode &$type) : ?int
    {
        if ($type instanceof TTemplateParamClass) {
            if ($type->defining_class === $this->base_fq_class_name) {
                if (isset($this->extends[$this->base_fq_class_name][$type->param_name])) {
                    $extended_param = $this->extends[$this->base_fq_class_name][$type->param_name];
                    $types = array_values($extended_param->getAtomicTypes());
                    if (count($types) === 1 && $types[0] instanceof TNamedObject) {
                        $type = $type->setAs($type->as, $types[0]);
                    } elseif ($type->as_type !== null) {
                        $type = $type->setAs($type->as, null);
                    }
                }
            }
        }
        if ($type instanceof Union) {
            $union = $type->getBuilder();
        } elseif ($type instanceof MutableUnion) {
            $union = $type;
        } else {
            return null;
        }
        foreach ($union->getAtomicTypes() as $key => $atomic_type) {
            if ($atomic_type instanceof TTemplateParam && ($atomic_type->defining_class === $this->base_fq_class_name || isset($this->extends[$atomic_type->defining_class]))) {
                $types_to_add = Methods::getExtendedTemplatedTypes($atomic_type, $this->extends);
                if ($types_to_add) {
                    $union->removeType($key);
                    foreach ($types_to_add as $extra_added_type) {
                        $union->addType($extra_added_type);
                    }
                }
            }
        }
        if ($type instanceof Union) {
            $type = $union->freeze();
        } else {
            $type = $union;
        }
        return null;
    }
}
<?php

namespace Psalm\Internal\DataFlow;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @psalm-immutable
 * @internal
 */
class Path
{
    use ImmutableNonCloneableTrait;
    public string $type;
    /** @var ?array<string> */
    public ?array $unescaped_taints = null;
    /** @var ?array<string> */
    public ?array $escaped_taints = null;
    public int $length;
    /**
     * @param ?array<string> $unescaped_taints
     * @param ?array<string> $escaped_taints
     */
    public function __construct(string $type, int $length, ?array $unescaped_taints = null, ?array $escaped_taints = null)
    {
        $this->type = $type;
        $this->length = $length;
        $this->unescaped_taints = $unescaped_taints;
        $this->escaped_taints = $escaped_taints;
    }
}
<?php

namespace Psalm\Internal\DataFlow;

use Psalm\CodeLocation;
use function strtolower;
/**
 * @psalm-consistent-constructor
 * @internal
 */
class DataFlowNode
{
    public string $id;
    public ?string $unspecialized_id = null;
    public string $label;
    public ?CodeLocation $code_location = null;
    public ?string $specialization_key = null;
    /** @var array<string> */
    public array $taints;
    /** @var ?self */
    public ?\Psalm\Internal\DataFlow\DataFlowNode $previous = null;
    /** @var list<string> */
    public array $path_types = [];
    /**
     * @var array<string, array<string, true>>
     */
    public array $specialized_calls = [];
    /**
     * @param array<string> $taints
     */
    public function __construct(string $id, string $label, ?CodeLocation $code_location, ?string $specialization_key = null, array $taints = [])
    {
        $this->id = $id;
        if ($specialization_key) {
            $this->unspecialized_id = $id;
            $this->id .= '-' . $specialization_key;
        }
        $this->label = $label;
        $this->code_location = $code_location;
        $this->specialization_key = $specialization_key;
        $this->taints = $taints;
    }
    /**
     * @return static
     */
    public static final function getForMethodArgument(string $method_id, string $cased_method_id, int $argument_offset, ?CodeLocation $arg_location, ?CodeLocation $code_location = null) : self
    {
        $arg_id = strtolower($method_id) . '#' . ($argument_offset + 1);
        $label = $cased_method_id . '#' . ($argument_offset + 1);
        $specialization_key = null;
        if ($code_location) {
            $specialization_key = strtolower($code_location->file_name) . ':' . $code_location->raw_file_start;
        }
        return new static($arg_id, $label, $arg_location, $specialization_key);
    }
    /**
     * @return static
     */
    public static final function getForAssignment(string $var_id, CodeLocation $assignment_location, ?string $specialization_key = null) : self
    {
        $id = $var_id . '-' . $assignment_location->file_name . ':' . $assignment_location->raw_file_start . '-' . $assignment_location->raw_file_end;
        return new static($id, $var_id, $assignment_location, $specialization_key);
    }
    /**
     * @return static
     */
    public static final function getForMethodReturn(string $method_id, string $cased_method_id, ?CodeLocation $code_location, ?CodeLocation $function_location = null) : self
    {
        $specialization_key = null;
        if ($function_location) {
            $specialization_key = strtolower($function_location->file_name) . ':' . $function_location->raw_file_start;
        }
        return new static(strtolower($method_id), $cased_method_id, $code_location, $specialization_key);
    }
    public function __toString() : string
    {
        return $this->id;
    }
}
<?php

namespace Psalm\Internal\DataFlow;

/**
 * @internal
 */
class TaintSource extends \Psalm\Internal\DataFlow\DataFlowNode
{
}
<?php

namespace Psalm\Internal\DataFlow;

/**
 * @internal
 */
class TaintSink extends \Psalm\Internal\DataFlow\DataFlowNode
{
}
<?php

namespace Psalm\Internal;

use Psalm\Storage\Assertion;
use Psalm\Storage\ImmutableNonCloneableTrait;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TEnumCase;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use function array_diff;
use function array_keys;
use function count;
use function hash;
use function implode;
use function ksort;
use function reset;
use function serialize;
use function substr;
use const PHP_VERSION_ID;
/**
 * @internal
 * @psalm-immutable
 */
class Clause
{
    use ImmutableNonCloneableTrait;
    public int $creating_conditional_id;
    public int $creating_object_id;
    /**
     * An array of strings of the form
     * [
     *     '$a' => ['falsy'],
     *     '$b' => ['!falsy'],
     *     '$c' => ['!null'],
     *     '$d' => ['string', 'int']
     * ]
     *
     * representing the formula
     *
     * !$a || $b || $c !== null || is_string($d) || is_int($d)
     *
     * @var array<string, non-empty-array<string, Assertion>>
     */
    public array $possibilities;
    /**
     * An array of things that are not true
     * [
     *     '$a' => ['!falsy'],
     *     '$b' => ['falsy'],
     *     '$c' => ['null'],
     *     '$d' => ['!string', '!int']
     * ]
     * represents the formula
     *
     * $a && !$b && $c === null && !is_string($d) && !is_int($d)
     *
     * @var array<string, non-empty-list<Assertion>>|null
     */
    public ?array $impossibilities = null;
    public bool $wedge;
    public bool $reconcilable;
    public bool $generated = \false;
    /** @var array<string, bool> */
    public array $redefined_vars = [];
    public string $hash;
    /**
     * @param array<string, non-empty-array<string, Assertion>>  $possibilities
     * @param array<string, bool> $redefined_vars
     */
    public function __construct(array $possibilities, int $creating_conditional_id, int $creating_object_id, bool $wedge = \false, bool $reconcilable = \true, bool $generated = \false, array $redefined_vars = [])
    {
        if ($wedge || !$reconcilable) {
            $this->hash = ($wedge ? 'w' : '') . $creating_object_id;
        } else {
            ksort($possibilities);
            $possibility_strings = [];
            foreach ($possibilities as $i => $v) {
                if (count($v) > 1) {
                    ksort($v);
                }
                $possibility_strings[$i] = array_keys($v);
            }
            /** @psalm-suppress ImpureFunctionCall */
            $data = serialize($possibility_strings);
            $this->hash = PHP_VERSION_ID >= 80100 ? hash('xxh128', $data) : hash('md4', $data);
        }
        $this->possibilities = $possibilities;
        $this->wedge = $wedge;
        $this->reconcilable = $reconcilable;
        $this->generated = $generated;
        $this->redefined_vars = $redefined_vars;
        $this->creating_conditional_id = $creating_conditional_id;
        $this->creating_object_id = $creating_object_id;
    }
    public function contains(\Psalm\Internal\Clause $other_clause) : bool
    {
        if (count($other_clause->possibilities) > count($this->possibilities)) {
            return \false;
        }
        foreach ($other_clause->possibilities as $var => $_) {
            if (!isset($this->possibilities[$var])) {
                return \false;
            }
        }
        foreach ($other_clause->possibilities as $var => $possible_types) {
            if (count(array_diff($possible_types, $this->possibilities[$var]))) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function __toString() : string
    {
        $clause_strings = [];
        foreach ($this->possibilities as $var_id => $values) {
            if ($var_id[0] === '*') {
                $var_id = '<expr>';
            }
            $var_id_clauses = [];
            foreach ($values as $value) {
                $value = (string) $value;
                if ($value === 'falsy') {
                    $var_id_clauses[] = '!' . $var_id;
                    continue;
                }
                if ($value === '!falsy') {
                    $var_id_clauses[] = $var_id;
                    continue;
                }
                $negate = \false;
                if ($value[0] === '!') {
                    $negate = \true;
                    $value = substr($value, 1);
                }
                if ($value[0] === '=') {
                    $value = substr($value, 1);
                }
                if ($negate) {
                    $var_id_clauses[] = $var_id . ' is not ' . $value;
                    continue;
                }
                $var_id_clauses[] = $var_id . ' is ' . $value;
            }
            if (count($var_id_clauses) > 1) {
                $clause_strings[] = '(' . implode(') || (', $var_id_clauses) . ')';
            } else {
                $clause_strings[] = reset($var_id_clauses);
            }
        }
        if (count($clause_strings) > 1) {
            return '(' . implode(') || (', $clause_strings) . ')';
        }
        return reset($clause_strings);
    }
    public function removePossibilities(string $var_id) : ?self
    {
        $possibilities = $this->possibilities;
        unset($possibilities[$var_id]);
        if (!$possibilities) {
            return null;
        }
        return new self($possibilities, $this->creating_conditional_id, $this->creating_object_id, $this->wedge, $this->reconcilable, $this->generated, $this->redefined_vars);
    }
    /**
     * @param non-empty-array<string, Assertion> $clause_var_possibilities
     */
    public function addPossibilities(string $var_id, array $clause_var_possibilities) : self
    {
        $possibilities = $this->possibilities;
        $possibilities[$var_id] = $clause_var_possibilities;
        return new self($possibilities, $this->creating_conditional_id, $this->creating_object_id, $this->wedge, $this->reconcilable, $this->generated, $this->redefined_vars);
    }
    public function calculateNegation() : self
    {
        if ($this->impossibilities !== null) {
            return $this;
        }
        $impossibilities = [];
        foreach ($this->possibilities as $var_id => $possibility) {
            $impossibility = [];
            foreach ($possibility as $type) {
                if (!$type->hasEquality() || ($inner_type = $type->getAtomicType()) && ($inner_type instanceof TLiteralInt || $inner_type instanceof TLiteralFloat || $inner_type instanceof TLiteralString || $inner_type instanceof TClassConstant || $inner_type instanceof TEnumCase)) {
                    $impossibility[] = $type->getNegation();
                }
            }
            if ($impossibility) {
                $impossibilities[$var_id] = $impossibility;
            }
        }
        $clause = clone $this;
        $clause->impossibilities = $impossibilities;
        return $clause;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Diff;

use Exception;
use function array_reverse;
use function count;
use function explode;
use function min;
use function strlen;
use function substr;
/**
 * Borrows from https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Internal/Differ.php
 *
 * Implements the Myers diff algorithm.
 *
 * Myers, Eugene W. "An O (ND) difference algorithm and its variations."
 * Algorithmica 1.1 (1986): 251-266.
 *
 * @internal
 */
class FileDiffer
{
    /**
     * @param list<string>    $a
     * @param list<string>    $b
     * @return array{0:non-empty-list<array<int, int>>, 1: int, 2: int}
     * @psalm-pure
     */
    private static function calculateTrace(array $a, array $b) : array
    {
        $n = count($a);
        $m = count($b);
        $max = $n + $m;
        /** @var array<int, int> $v */
        $v = [1 => 0];
        $trace = [];
        for ($d = 0; $d <= $max; ++$d) {
            $trace[] = $v;
            for ($k = -$d; $k <= $d; $k += 2) {
                if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
                    $x = $v[$k + 1];
                } else {
                    $x = $v[$k - 1] + 1;
                }
                $y = $x - $k;
                while ($x < $n && $y < $m && $a[$x] === $b[$y]) {
                    ++$x;
                    ++$y;
                }
                $v[$k] = $x;
                if ($x >= $n && $y >= $m) {
                    return [$trace, $x, $y];
                }
            }
        }
        throw new Exception('Should not happen');
    }
    /**
     * @param list<array<int, int>> $trace
     * @param list<string> $a
     * @param list<string> $b
     * @return list<DiffElem>
     * @psalm-pure
     */
    private static function extractDiff(array $trace, int $x, int $y, array $a, array $b) : array
    {
        $result = [];
        for ($d = count($trace) - 1; $d >= 0; --$d) {
            $v = $trace[$d];
            $k = $x - $y;
            if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
                $prevK = $k + 1;
            } else {
                $prevK = $k - 1;
            }
            $prevX = $v[$prevK];
            $prevY = $prevX - $prevK;
            while ($x > $prevX && $y > $prevY) {
                $result[] = new \Psalm\Internal\Diff\DiffElem(\Psalm\Internal\Diff\DiffElem::TYPE_KEEP, $a[$x - 1], $b[$y - 1]);
                --$x;
                --$y;
            }
            if ($d === 0) {
                break;
            }
            while ($x > $prevX) {
                $result[] = new \Psalm\Internal\Diff\DiffElem(\Psalm\Internal\Diff\DiffElem::TYPE_REMOVE, $a[$x - 1], null);
                --$x;
            }
            while ($y > $prevY) {
                $result[] = new \Psalm\Internal\Diff\DiffElem(\Psalm\Internal\Diff\DiffElem::TYPE_ADD, null, $b[$y - 1]);
                --$y;
            }
        }
        return array_reverse($result);
    }
    /**
     * @return array<int, array{0: int, 1: int, 2: int, 3: int, 4: int, 5: string}>
     * @psalm-pure
     */
    public static function getDiff(string $a_code, string $b_code) : array
    {
        $a = explode("\n", $a_code);
        $b = explode("\n", $b_code);
        [$trace, $x, $y] = self::calculateTrace($a, $b);
        $diff = self::coalesceReplacements(self::extractDiff($trace, $x, $y, $a, $b));
        $a_offset = 0;
        $b_offset = 0;
        $last_diff_type = null;
        /** @var array{0:int, 1:int, 2:int, 3:int, 4:int, 5:string}|null */
        $last_change = null;
        $changes = [];
        $i = 0;
        $line_diff = 0;
        foreach ($diff as $diff_elem) {
            $diff_type = $diff_elem->type;
            if ($diff_type !== $last_diff_type) {
                $last_change = null;
            }
            if ($diff_type === \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE) {
                /** @var string $diff_elem->old */
                $diff_text = $diff_elem->old . "\n";
                $text_length = strlen($diff_text);
                --$line_diff;
                if ($last_change === null) {
                    ++$i;
                    $last_change = [$a_offset, $a_offset + $text_length, $b_offset, $b_offset, $line_diff, ''];
                    $changes[$i - 1] = $last_change;
                } else {
                    $last_change[1] += $text_length;
                    $last_change[4] = $line_diff;
                    $changes[$i - 1] = $last_change;
                }
                $a_offset += $text_length;
            } elseif ($diff_type === \Psalm\Internal\Diff\DiffElem::TYPE_ADD) {
                /** @var string $diff_elem->new */
                $diff_text = $diff_elem->new . "\n";
                $text_length = strlen($diff_text);
                ++$line_diff;
                if ($last_change === null) {
                    ++$i;
                    $last_change = [$a_offset, $a_offset, $b_offset, $b_offset + $text_length, $line_diff, $diff_text];
                    $changes[$i - 1] = $last_change;
                } else {
                    $last_change[3] += $text_length;
                    $last_change[4] = $line_diff;
                    $last_change[5] .= $diff_text;
                    $changes[$i - 1] = $last_change;
                }
                $b_offset += $text_length;
            } elseif ($diff_type === \Psalm\Internal\Diff\DiffElem::TYPE_REPLACE) {
                /** @var string $diff_elem->old */
                $old_diff_text = $diff_elem->old . "\n";
                /** @var string $diff_elem->new */
                $new_diff_text = $diff_elem->new . "\n";
                $old_text_length = strlen($old_diff_text);
                $new_text_length = strlen($new_diff_text);
                $max_same_count = min($old_text_length, $new_text_length);
                for ($j = 0; $j < $max_same_count; ++$j) {
                    if ($old_diff_text[$j] !== $new_diff_text[$j]) {
                        break;
                    }
                    ++$a_offset;
                    ++$b_offset;
                    --$old_text_length;
                    --$new_text_length;
                }
                $new_diff_text = substr($new_diff_text, $j);
                if ($last_change === null || $j) {
                    ++$i;
                    $last_change = [$a_offset, $a_offset + $old_text_length, $b_offset, $b_offset + $new_text_length, $line_diff, $new_diff_text];
                    $changes[$i - 1] = $last_change;
                } else {
                    $last_change[1] += $old_text_length;
                    $last_change[3] += $new_text_length;
                    $last_change[5] .= $new_diff_text;
                    $changes[$i - 1] = $last_change;
                }
                $a_offset += $old_text_length;
                $b_offset += $new_text_length;
            } else {
                /** @psalm-suppress MixedArgument */
                $same_text_length = strlen($diff_elem->new) + 1;
                $a_offset += $same_text_length;
                $b_offset += $same_text_length;
            }
            $last_diff_type = $diff_elem->type;
        }
        return $changes;
    }
    /**
     * Coalesce equal-length sequences of remove+add into a replace operation.
     *
     * @param DiffElem[] $diff
     * @return list<DiffElem>
     * @psalm-pure
     */
    private static function coalesceReplacements(array $diff) : array
    {
        $newDiff = [];
        $c = count($diff);
        for ($i = 0; $i < $c; ++$i) {
            $diffType = $diff[$i]->type;
            if ($diffType !== \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE) {
                $newDiff[] = $diff[$i];
                continue;
            }
            $j = $i;
            while ($j < $c && $diff[$j]->type === \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE) {
                ++$j;
            }
            $k = $j;
            while ($k < $c && $diff[$k]->type === \Psalm\Internal\Diff\DiffElem::TYPE_ADD) {
                ++$k;
            }
            if ($j - $i === $k - $j) {
                $len = $j - $i;
                for ($n = 0; $n < $len; ++$n) {
                    $newDiff[] = new \Psalm\Internal\Diff\DiffElem(\Psalm\Internal\Diff\DiffElem::TYPE_REPLACE, $diff[$i + $n]->old, $diff[$j + $n]->new);
                }
            } else {
                for (; $i < $k; ++$i) {
                    $newDiff[] = $diff[$i];
                }
            }
            $i = $k - 1;
        }
        return $newDiff;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Diff;

use Psalm\Storage\ImmutableNonCloneableTrait;
/**
 * @internal
 * @psalm-immutable
 */
class DiffElem
{
    use ImmutableNonCloneableTrait;
    public const TYPE_KEEP = 0;
    public const TYPE_REMOVE = 1;
    public const TYPE_ADD = 2;
    public const TYPE_REPLACE = 3;
    public const TYPE_KEEP_SIGNATURE = 4;
    /** @var int One of the TYPE_* constants */
    public int $type;
    /** @var mixed Is null for add operations */
    public $old;
    /** @var mixed Is null for remove operations */
    public $new;
    /**
     * @param mixed  $old
     * @param mixed  $new
     */
    public function __construct(int $type, $old, $new)
    {
        $this->type = $type;
        $this->old = $old;
        $this->new = $new;
    }
}
<?php

namespace Psalm\Internal\Diff;

use _HumbugBox1cb33d1f20f1\PhpParser;
use function end;
use function get_class;
use function substr;
/**
 * @internal
 */
class FileStatementsDiffer extends \Psalm\Internal\Diff\AstDiffer
{
    /**
     * Calculate diff (edit script) from $a to $b.
     *
     * @param list<PhpParser\Node\Stmt> $a
     * @param list<PhpParser\Node\Stmt> $b
     * @return array{
     *      0: list<string>,
     *      1: list<string>,
     *      2: list<string>,
     *      3: list<array{int, int, int, int}>,
     *      4: list<array{int, int}>
     * }
     */
    public static function diff(array $a, array $b, string $a_code, string $b_code) : array
    {
        [$trace, $x, $y, $bc] = self::calculateTrace(static function (PhpParser\Node\Stmt $a, PhpParser\Node\Stmt $b, string $a_code, string $b_code) : bool {
            if (get_class($a) !== get_class($b)) {
                return \false;
            }
            if ($a instanceof PhpParser\Node\Stmt\Namespace_ && $b instanceof PhpParser\Node\Stmt\Namespace_ || $a instanceof PhpParser\Node\Stmt\Class_ && $b instanceof PhpParser\Node\Stmt\Class_ || $a instanceof PhpParser\Node\Stmt\Interface_ && $b instanceof PhpParser\Node\Stmt\Interface_ || $a instanceof PhpParser\Node\Stmt\Trait_ && $b instanceof PhpParser\Node\Stmt\Trait_) {
                return (string) $a->name === (string) $b->name;
            }
            if ($a instanceof PhpParser\Node\Stmt\Use_ && $b instanceof PhpParser\Node\Stmt\Use_ || $a instanceof PhpParser\Node\Stmt\GroupUse && $b instanceof PhpParser\Node\Stmt\GroupUse) {
                $a_start = (int) $a->getAttribute('startFilePos');
                $a_end = (int) $a->getAttribute('endFilePos');
                $b_start = (int) $b->getAttribute('startFilePos');
                $b_end = (int) $b->getAttribute('endFilePos');
                $a_size = $a_end - $a_start;
                $b_size = $b_end - $b_start;
                if (substr($a_code, $a_start, $a_size) === substr($b_code, $b_start, $b_size)) {
                    return \true;
                }
            }
            return \false;
        }, $a, $b, $a_code, $b_code);
        $diff = self::extractDiff($trace, $x, $y, $a, $b, $bc);
        $keep = [];
        $keep_signature = [];
        $add_or_delete = [];
        $diff_map = [];
        $deletion_ranges = [];
        foreach ($diff as $diff_elem) {
            if ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_KEEP) {
                if ($diff_elem->old instanceof PhpParser\Node\Stmt\Namespace_ && $diff_elem->new instanceof PhpParser\Node\Stmt\Namespace_) {
                    $namespace_keep = \Psalm\Internal\Diff\NamespaceStatementsDiffer::diff((string) $diff_elem->old->name, $diff_elem->old->stmts, $diff_elem->new->stmts, $a_code, $b_code);
                    $keep = [...$keep, ...$namespace_keep[0]];
                    $keep_signature = [...$keep_signature, ...$namespace_keep[1]];
                    $add_or_delete = [...$add_or_delete, ...$namespace_keep[2]];
                    $diff_map = [...$diff_map, ...$namespace_keep[3]];
                    $deletion_ranges = [...$deletion_ranges, ...$namespace_keep[4]];
                } elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\Class_ && $diff_elem->new instanceof PhpParser\Node\Stmt\Class_ || $diff_elem->old instanceof PhpParser\Node\Stmt\Interface_ && $diff_elem->new instanceof PhpParser\Node\Stmt\Interface_ || $diff_elem->old instanceof PhpParser\Node\Stmt\Trait_ && $diff_elem->new instanceof PhpParser\Node\Stmt\Trait_) {
                    $class_keep = \Psalm\Internal\Diff\ClassStatementsDiffer::diff((string) $diff_elem->old->name, $diff_elem->old->stmts, $diff_elem->new->stmts, $a_code, $b_code);
                    $keep = [...$keep, ...$class_keep[0]];
                    $keep_signature = [...$keep_signature, ...$class_keep[1]];
                    $add_or_delete = [...$add_or_delete, ...$class_keep[2]];
                    $diff_map = [...$diff_map, ...$class_keep[3]];
                    $deletion_ranges = [...$deletion_ranges, ...$class_keep[4]];
                }
            } elseif ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE) {
                if ($diff_elem->old instanceof PhpParser\Node\Stmt\Use_ || $diff_elem->old instanceof PhpParser\Node\Stmt\GroupUse) {
                    foreach ($diff_elem->old->uses as $use) {
                        if ($use->alias) {
                            $add_or_delete[] = 'use:' . (string) $use->alias;
                        } else {
                            $name_parts = $use->name->parts;
                            $add_or_delete[] = 'use:' . end($name_parts);
                        }
                    }
                } elseif ($diff_elem->old instanceof PhpParser\Node && !$diff_elem->old instanceof PhpParser\Node\Stmt\Namespace_) {
                    if ($doc = $diff_elem->old->getDocComment()) {
                        $start = $doc->getStartFilePos();
                    } else {
                        $start = (int) $diff_elem->old->getAttribute('startFilePos');
                    }
                    $deletion_ranges[] = [$start, (int) $diff_elem->old->getAttribute('endFilePos')];
                }
            } elseif ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_ADD) {
                if ($diff_elem->new instanceof PhpParser\Node\Stmt\Use_ || $diff_elem->new instanceof PhpParser\Node\Stmt\GroupUse) {
                    foreach ($diff_elem->new->uses as $use) {
                        if ($use->alias) {
                            $add_or_delete[] = 'use:' . (string) $use->alias;
                        } else {
                            $name_parts = $use->name->parts;
                            $add_or_delete[] = 'use:' . end($name_parts);
                        }
                    }
                }
            }
        }
        return [$keep, $keep_signature, $add_or_delete, $diff_map, $deletion_ranges];
    }
}
<?php

namespace Psalm\Internal\Diff;

use _HumbugBox1cb33d1f20f1\PhpParser;
use function end;
use function get_class;
use function substr;
/**
 * @internal
 */
class NamespaceStatementsDiffer extends \Psalm\Internal\Diff\AstDiffer
{
    /**
     * Calculate diff (edit script) from $a to $b.
     *
     * @param array<int, PhpParser\Node\Stmt> $a
     * @param array<int, PhpParser\Node\Stmt> $b
     * @return array{
     *      0: list<string>,
     *      1: list<string>,
     *      2: list<string>,
     *      3: list<array{int, int, int, int}>,
     *      4: list<array{int, int}>
     * }
     */
    public static function diff(string $name, array $a, array $b, string $a_code, string $b_code) : array
    {
        [$trace, $x, $y, $bc] = self::calculateTrace(static function (PhpParser\Node\Stmt $a, PhpParser\Node\Stmt $b, string $a_code, string $b_code) : bool {
            if (get_class($a) !== get_class($b)) {
                return \false;
            }
            if ($a instanceof PhpParser\Node\Stmt\Class_ && $b instanceof PhpParser\Node\Stmt\Class_ || $a instanceof PhpParser\Node\Stmt\Interface_ && $b instanceof PhpParser\Node\Stmt\Interface_ || $a instanceof PhpParser\Node\Stmt\Trait_ && $b instanceof PhpParser\Node\Stmt\Trait_) {
                // @todo add check for comments comparison
                return (string) $a->name === (string) $b->name;
            }
            if ($a instanceof PhpParser\Node\Stmt\Use_ && $b instanceof PhpParser\Node\Stmt\Use_ || $a instanceof PhpParser\Node\Stmt\GroupUse && $b instanceof PhpParser\Node\Stmt\GroupUse) {
                $a_start = (int) $a->getAttribute('startFilePos');
                $a_end = (int) $a->getAttribute('endFilePos');
                $b_start = (int) $b->getAttribute('startFilePos');
                $b_end = (int) $b->getAttribute('endFilePos');
                $a_size = $a_end - $a_start;
                $b_size = $b_end - $b_start;
                if (substr($a_code, $a_start, $a_size) === substr($b_code, $b_start, $b_size)) {
                    return \true;
                }
            }
            return \false;
        }, $a, $b, $a_code, $b_code);
        $diff = self::extractDiff($trace, $x, $y, $a, $b, $bc);
        $keep = [];
        $keep_signature = [];
        $add_or_delete = [];
        $diff_map = [];
        $deletion_ranges = [];
        foreach ($diff as $diff_elem) {
            if ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_KEEP) {
                if ($diff_elem->old instanceof PhpParser\Node\Stmt\Class_ && $diff_elem->new instanceof PhpParser\Node\Stmt\Class_ || $diff_elem->old instanceof PhpParser\Node\Stmt\Interface_ && $diff_elem->new instanceof PhpParser\Node\Stmt\Interface_ || $diff_elem->old instanceof PhpParser\Node\Stmt\Trait_ && $diff_elem->new instanceof PhpParser\Node\Stmt\Trait_) {
                    $class_keep = \Psalm\Internal\Diff\ClassStatementsDiffer::diff(($name ? $name . '\\' : '') . $diff_elem->old->name, $diff_elem->old->stmts, $diff_elem->new->stmts, $a_code, $b_code);
                    $keep = [...$keep, ...$class_keep[0]];
                    $keep_signature = [...$keep_signature, ...$class_keep[1]];
                    $add_or_delete = [...$add_or_delete, ...$class_keep[2]];
                    $diff_map = [...$diff_map, ...$class_keep[3]];
                    $deletion_ranges = [...$deletion_ranges, ...$class_keep[4]];
                }
            } elseif ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE) {
                if ($diff_elem->old instanceof PhpParser\Node\Stmt\Use_ || $diff_elem->old instanceof PhpParser\Node\Stmt\GroupUse) {
                    foreach ($diff_elem->old->uses as $use) {
                        if ($use->alias) {
                            $add_or_delete[] = 'use:' . (string) $use->alias;
                        } else {
                            $name_parts = $use->name->parts;
                            $add_or_delete[] = 'use:' . end($name_parts);
                        }
                    }
                }
            } elseif ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_ADD) {
                if ($diff_elem->new instanceof PhpParser\Node\Stmt\Use_ || $diff_elem->new instanceof PhpParser\Node\Stmt\GroupUse) {
                    foreach ($diff_elem->new->uses as $use) {
                        if ($use->alias) {
                            $add_or_delete[] = 'use:' . (string) $use->alias;
                        } else {
                            $name_parts = $use->name->parts;
                            $add_or_delete[] = 'use:' . end($name_parts);
                        }
                    }
                }
            }
        }
        return [$keep, $keep_signature, $add_or_delete, $diff_map, $deletion_ranges];
    }
}
<?php

namespace Psalm\Internal\Diff;

use _HumbugBox1cb33d1f20f1\PhpParser;
use function count;
use function get_class;
use function strpos;
use function strtolower;
use function substr;
use function trim;
/**
 * @internal
 */
class ClassStatementsDiffer extends \Psalm\Internal\Diff\AstDiffer
{
    /**
     * Calculate diff (edit script) from $a to $b.
     *
     * @param array<int, PhpParser\Node\Stmt> $a
     * @param array<int, PhpParser\Node\Stmt> $b
     * @return array{
     *      0: list<string>,
     *      1: list<string>,
     *      2: list<string>,
     *      3: array<int, array{int, int, int, int}>,
     *      4: list<array{int, int}>
     * }
     */
    public static function diff(string $name, array $a, array $b, string $a_code, string $b_code) : array
    {
        $diff_map = [];
        [$trace, $x, $y, $bc] = self::calculateTrace(static function (PhpParser\Node\Stmt $a, PhpParser\Node\Stmt $b, string $a_code, string $b_code, bool &$body_change = \false) use(&$diff_map) : bool {
            if (get_class($a) !== get_class($b)) {
                return \false;
            }
            $a_start = (int) $a->getAttribute('startFilePos');
            $a_end = (int) $a->getAttribute('endFilePos');
            $b_start = (int) $b->getAttribute('startFilePos');
            $b_end = (int) $b->getAttribute('endFilePos');
            $a_comments_end = $a_start;
            $b_comments_end = $b_start;
            /** @var list<PhpParser\Comment> */
            $a_comments = $a->getComments();
            /** @var list<PhpParser\Comment> */
            $b_comments = $b->getComments();
            $signature_change = \false;
            $body_change = \false;
            if ($a_comments) {
                if (!$b_comments) {
                    $signature_change = \true;
                }
                $a_start = $a_comments[0]->getStartFilePos();
            }
            if ($b_comments) {
                if (!$a_comments) {
                    $signature_change = \true;
                }
                $b_start = $b_comments[0]->getStartFilePos();
            }
            $a_size = $a_end - $a_start;
            $b_size = $b_end - $b_start;
            if ($a_size === $b_size && substr($a_code, $a_start, $a_size) === substr($b_code, $b_start, $b_size)) {
                $start_diff = $b_start - $a_start;
                $line_diff = $b->getLine() - $a->getLine();
                /** @psalm-suppress MixedArrayAssignment */
                $diff_map[] = [$a_start, $a_end, $start_diff, $line_diff];
                return \true;
            }
            if (!$signature_change && substr($a_code, $a_start, $a_comments_end - $a_start) !== substr($b_code, $b_start, $b_comments_end - $b_start)) {
                $signature_change = \true;
            }
            if ($a instanceof PhpParser\Node\Stmt\ClassMethod && $b instanceof PhpParser\Node\Stmt\ClassMethod) {
                if ((string) $a->name !== (string) $b->name) {
                    return \false;
                }
                if ($a->stmts) {
                    $first_stmt = $a->stmts[0];
                    $a_stmts_start = (int) $first_stmt->getAttribute('startFilePos');
                    if ($a_stmt_comments = $first_stmt->getComments()) {
                        $a_stmts_start = $a_stmt_comments[0]->getStartFilePos();
                    }
                } else {
                    $a_stmts_start = $a_end;
                }
                if ($b->stmts) {
                    $first_stmt = $b->stmts[0];
                    $b_stmts_start = (int) $first_stmt->getAttribute('startFilePos');
                    if ($b_stmt_comments = $first_stmt->getComments()) {
                        $b_stmts_start = $b_stmt_comments[0]->getStartFilePos();
                    }
                } else {
                    $b_stmts_start = $b_end;
                }
                $a_body_size = $a_end - $a_stmts_start;
                $b_body_size = $b_end - $b_stmts_start;
                $body_change = $a_body_size !== $b_body_size || substr($a_code, $a_stmts_start, $a_end - $a_stmts_start) !== substr($b_code, $b_stmts_start, $b_end - $b_stmts_start);
                if (!$signature_change) {
                    $a_signature = substr($a_code, $a_start, $a_stmts_start - $a_start);
                    $b_signature = substr($b_code, $b_start, $b_stmts_start - $b_start);
                    if ($a_signature !== $b_signature) {
                        $a_signature = trim($a_signature);
                        $b_signature = trim($b_signature);
                        if (strpos($a_signature, $b_signature) === \false && strpos($b_signature, $a_signature) === \false) {
                            $signature_change = \true;
                        }
                    }
                }
            } elseif ($a instanceof PhpParser\Node\Stmt\Property && $b instanceof PhpParser\Node\Stmt\Property) {
                if (count($a->props) !== 1 || count($b->props) !== 1) {
                    return \false;
                }
                if ((string) $a->props[0]->name !== (string) $b->props[0]->name || $a->flags !== $b->flags) {
                    return \false;
                }
                $body_change = substr($a_code, $a_comments_end, $a_end - $a_comments_end) !== substr($b_code, $b_comments_end, $b_end - $b_comments_end);
            } else {
                $signature_change = \true;
            }
            if (!$signature_change && !$body_change) {
                /** @psalm-suppress MixedArrayAssignment */
                $diff_map[] = [$a_start, $a_end, $b_start - $a_start, $b->getLine() - $a->getLine()];
            }
            return !$signature_change;
        }, $a, $b, $a_code, $b_code);
        $diff = self::extractDiff($trace, $x, $y, $a, $b, $bc);
        $keep = [];
        $keep_signature = [];
        $add_or_delete = [];
        $deletion_ranges = [];
        $name_lc = strtolower($name);
        foreach ($diff as $diff_elem) {
            if ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_KEEP) {
                if ($diff_elem->old instanceof PhpParser\Node\Stmt\ClassMethod) {
                    $keep[] = $name_lc . '::' . strtolower((string) $diff_elem->old->name);
                } elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\Property) {
                    foreach ($diff_elem->old->props as $prop) {
                        $keep[] = $name_lc . '::$' . $prop->name;
                    }
                } elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\ClassConst) {
                    foreach ($diff_elem->old->consts as $const) {
                        $keep[] = $name_lc . '::' . $const->name;
                    }
                } elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\TraitUse) {
                    foreach ($diff_elem->old->traits as $trait) {
                        $keep[] = $name_lc . '&' . strtolower((string) $trait->getAttribute('resolvedName'));
                    }
                }
            } elseif ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_KEEP_SIGNATURE) {
                if ($diff_elem->old instanceof PhpParser\Node\Stmt\ClassMethod) {
                    $keep_signature[] = $name_lc . '::' . strtolower((string) $diff_elem->old->name);
                } elseif ($diff_elem->old instanceof PhpParser\Node\Stmt\Property) {
                    foreach ($diff_elem->old->props as $prop) {
                        $keep_signature[] = $name_lc . '::$' . $prop->name;
                    }
                }
            } elseif ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE || $diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_ADD) {
                /** @var PhpParser\Node */
                $affected_elem = $diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE ? $diff_elem->old : $diff_elem->new;
                if ($affected_elem instanceof PhpParser\Node\Stmt\ClassMethod) {
                    $add_or_delete[] = $name_lc . '::' . strtolower((string) $affected_elem->name);
                } elseif ($affected_elem instanceof PhpParser\Node\Stmt\Property) {
                    foreach ($affected_elem->props as $prop) {
                        $add_or_delete[] = $name_lc . '::$' . $prop->name;
                    }
                } elseif ($affected_elem instanceof PhpParser\Node\Stmt\ClassConst) {
                    foreach ($affected_elem->consts as $const) {
                        $add_or_delete[] = $name_lc . '::' . $const->name;
                    }
                } elseif ($affected_elem instanceof PhpParser\Node\Stmt\TraitUse) {
                    foreach ($affected_elem->traits as $trait) {
                        $add_or_delete[] = $name_lc . '&' . strtolower((string) $trait->getAttribute('resolvedName'));
                    }
                }
                if ($diff_elem->type === \Psalm\Internal\Diff\DiffElem::TYPE_REMOVE) {
                    if ($doc = $affected_elem->getDocComment()) {
                        $start = $doc->getStartFilePos();
                    } else {
                        $start = (int) $affected_elem->getAttribute('startFilePos');
                    }
                    $deletion_ranges[] = [$start, (int) $affected_elem->getAttribute('endFilePos')];
                }
            }
        }
        /** @var array<int, array{int, int, int, int}> $diff_map */
        return [$keep, $keep_signature, $add_or_delete, $diff_map, $deletion_ranges];
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\Diff;

use Closure;
use Exception;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use function array_reverse;
use function count;
/**
 * Borrows from https://github.com/nikic/PHP-Parser/blob/master/lib/PhpParser/Internal/Differ.php
 *
 * Implements the Myers diff algorithm.
 *
 * Myers, Eugene W. "An O (ND) difference algorithm and its variations."
 * Algorithmica 1.1 (1986): 251-266.
 *
 * @internal
 */
class AstDiffer
{
    /**
     * @param Closure(Stmt, Stmt, string, string, bool=): bool $is_equal
     * @param array<int, Stmt> $a
     * @param array<int, Stmt> $b
     * @return array{0:non-empty-list<array<int, int>>, 1: int, 2: int, 3: array<int, bool>}
     */
    protected static function calculateTrace(Closure $is_equal, array $a, array $b, string $a_code, string $b_code) : array
    {
        $n = count($a);
        $m = count($b);
        $max = $n + $m;
        /** @var array<int, int> $v */
        $v = [1 => 0];
        $bc = [];
        $trace = [];
        for ($d = 0; $d <= $max; ++$d) {
            $trace[] = $v;
            for ($k = -$d; $k <= $d; $k += 2) {
                if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
                    $x = $v[$k + 1];
                } else {
                    $x = $v[$k - 1] + 1;
                }
                $y = $x - $k;
                $body_change = \false;
                while ($x < $n && $y < $m && $is_equal($a[$x], $b[$y], $a_code, $b_code, $body_change)) {
                    $bc[$x] = $body_change;
                    ++$x;
                    ++$y;
                    $body_change = \false;
                }
                $v[$k] = $x;
                if ($x >= $n && $y >= $m) {
                    return [$trace, $x, $y, $bc];
                }
            }
        }
        throw new Exception('Should not happen');
    }
    /**
     * @param array<int, array<int, int>> $trace
     * @param array<int, Stmt> $a
     * @param array<int, Stmt> $b
     * @param array<int, bool> $bc
     * @return list<DiffElem>
     * @psalm-pure
     */
    protected static function extractDiff(array $trace, int $x, int $y, array $a, array $b, array $bc) : array
    {
        $result = [];
        for ($d = count($trace) - 1; $d >= 0; --$d) {
            $v = $trace[$d];
            $k = $x - $y;
            if ($k === -$d || $k !== $d && $v[$k - 1] < $v[$k + 1]) {
                $prevK = $k + 1;
            } else {
                $prevK = $k - 1;
            }
            $prevX = $v[$prevK];
            $prevY = $prevX - $prevK;
            while ($x > $prevX && $y > $prevY) {
                $result[] = new \Psalm\Internal\Diff\DiffElem($bc[$x - 1] ? \Psalm\Internal\Diff\DiffElem::TYPE_KEEP_SIGNATURE : \Psalm\Internal\Diff\DiffElem::TYPE_KEEP, $a[$x - 1], $b[$y - 1]);
                --$x;
                --$y;
            }
            if ($d === 0) {
                break;
            }
            while ($x > $prevX) {
                $result[] = new \Psalm\Internal\Diff\DiffElem(\Psalm\Internal\Diff\DiffElem::TYPE_REMOVE, $a[$x - 1], null);
                --$x;
            }
            while ($y > $prevY) {
                $result[] = new \Psalm\Internal\Diff\DiffElem(\Psalm\Internal\Diff\DiffElem::TYPE_ADD, null, $b[$y - 1]);
                --$y;
            }
        }
        return array_reverse($result);
    }
}
<?php

namespace Psalm\Internal;

use OutOfBoundsException;
use _HumbugBox1cb33d1f20f1\PackageVersions\Versions;
use Phar;
use function class_exists;
use function dirname;
use function file_put_contents;
use function var_export;
/**
 * @internal
 * @psalm-type _VersionData=array{"vimeo/psalm": string, "nikic/php-parser": string}
 */
final class VersionUtils
{
    private const PSALM_PACKAGE = 'vimeo/psalm';
    private const PHP_PARSER_PACKAGE = 'nikic/php-parser';
    /** @var null|_VersionData */
    private static ?array $versions = null;
    /** @psalm-suppress UnusedConstructor it's here to prevent instantiations */
    private function __construct()
    {
    }
    public static function getPsalmVersion() : string
    {
        return self::getVersions()[self::PSALM_PACKAGE];
    }
    public static function getPhpParserVersion() : string
    {
        return self::getVersions()[self::PHP_PARSER_PACKAGE];
    }
    /** @psalm-suppress UnusedMethod called from bin/build-phar.sh */
    public static function dump() : void
    {
        $versions = self::loadComposerVersions();
        $exported = '<?php return ' . var_export($versions, \true) . ';';
        file_put_contents(dirname(__DIR__, 3) . '/build/phar-versions.php', $exported);
    }
    /** @return _VersionData */
    private static function getVersions() : array
    {
        if (self::$versions !== null) {
            return self::$versions;
        }
        if ($versions = self::loadPharVersions()) {
            return self::$versions = $versions;
        }
        if ($versions = self::loadComposerVersions()) {
            return self::$versions = $versions;
        }
        return self::$versions = [self::PSALM_PACKAGE => 'unknown', self::PHP_PARSER_PACKAGE => 'unknown'];
    }
    /** @return _VersionData|null */
    private static function loadPharVersions() : ?array
    {
        if (!class_exists(Phar::class)) {
            return null;
        }
        $phar_filename = Phar::running(\true);
        if (!$phar_filename) {
            return null;
        }
        /**
         * @psalm-suppress UnresolvableInclude
         * @var _VersionData
         */
        return require $phar_filename . '/phar-versions.php';
    }
    /** @return _VersionData|null */
    private static function loadComposerVersions() : ?array
    {
        try {
            return [self::PSALM_PACKAGE => Versions::getVersion(self::PSALM_PACKAGE), self::PHP_PARSER_PACKAGE => Versions::getVersion(self::PHP_PARSER_PACKAGE)];
        } catch (OutOfBoundsException $ex) {
        }
        return null;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Internal\PhpTraverser;

use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use _HumbugBox1cb33d1f20f1\PhpParser\NodeTraverser;
use function array_pop;
use function array_splice;
use function gettype;
use function is_array;
/**
 * @internal
 */
class CustomTraverser extends NodeTraverser
{
    public function __construct()
    {
        $this->stopTraversal = \false;
    }
    /**
     * Recursively traverse a node.
     *
     * @param Node $node node to traverse
     * @return Node Result of traversal (may be original node or new one)
     */
    protected function traverseNode(Node $node) : Node
    {
        foreach ($node->getSubNodeNames() as $name) {
            $subNode =& $node->{$name};
            if (is_array($subNode)) {
                $subNode = $this->traverseArray($subNode);
                if ($this->stopTraversal) {
                    break;
                }
            } elseif ($subNode instanceof Node) {
                $traverseChildren = \true;
                foreach ($this->visitors as $visitor) {
                    $return = $visitor->enterNode($subNode, $traverseChildren);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $subNode = $return;
                        } elseif (self::DONT_TRAVERSE_CHILDREN === $return) {
                            $traverseChildren = \false;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } else {
                            throw new LogicException('enterNode() returned invalid value of type ' . gettype($return));
                        }
                    }
                }
                if ($traverseChildren) {
                    $subNode = $this->traverseNode($subNode);
                    if ($this->stopTraversal) {
                        break;
                    }
                }
                foreach ($this->visitors as $visitor) {
                    $return = $visitor->leaveNode($subNode);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $subNode = $return;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } elseif (is_array($return)) {
                            throw new LogicException('leaveNode() may only return an array ' . 'if the parent structure is an array');
                        } else {
                            throw new LogicException('leaveNode() returned invalid value of type ' . gettype($return));
                        }
                    }
                }
            }
        }
        return $node;
    }
    /**
     * Recursively traverse array (usually of nodes).
     *
     * @param array $nodes Array to traverse
     * @return array Result of traversal (may be original array or changed one)
     */
    protected function traverseArray(array $nodes) : array
    {
        $doNodes = [];
        foreach ($nodes as $i => &$node) {
            if ($node instanceof Node) {
                $traverseChildren = \true;
                foreach ($this->visitors as $visitor) {
                    $return = $visitor->enterNode($node, $traverseChildren);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $node = $return;
                        } elseif (self::DONT_TRAVERSE_CHILDREN === $return) {
                            $traverseChildren = \false;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } else {
                            throw new LogicException('enterNode() returned invalid value of type ' . gettype($return));
                        }
                    }
                }
                if ($traverseChildren) {
                    $node = $this->traverseNode($node);
                    if ($this->stopTraversal) {
                        break;
                    }
                }
                foreach ($this->visitors as $visitor) {
                    $return = $visitor->leaveNode($node);
                    if (null !== $return) {
                        if ($return instanceof Node) {
                            $node = $return;
                        } elseif (is_array($return)) {
                            $doNodes[] = [$i, $return];
                            break;
                        } elseif (self::REMOVE_NODE === $return) {
                            $doNodes[] = [$i, []];
                            break;
                        } elseif (self::STOP_TRAVERSAL === $return) {
                            $this->stopTraversal = \true;
                            break 2;
                        } elseif (\false === $return) {
                            throw new LogicException('bool(false) return from leaveNode() no longer supported. ' . 'Return NodeTraverser::REMOVE_NODE instead');
                        } else {
                            throw new LogicException('leaveNode() returned invalid value of type ' . gettype($return));
                        }
                    }
                }
            } elseif (is_array($node)) {
                throw new LogicException('Invalid node structure: Contains nested arrays');
            }
        }
        if (!empty($doNodes)) {
            while ([$i, $replace] = array_pop($doNodes)) {
                array_splice($nodes, $i, 1, $replace);
            }
        }
        return $nodes;
    }
}
<?php

namespace Psalm;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Type\Union;
interface NodeTypeProvider
{
    /**
     * @param PhpParser\Node\Expr|PhpParser\Node\Name|PhpParser\Node\Stmt\Return_ $node
     */
    public function setType(PhpParser\NodeAbstract $node, Union $type) : void;
    /**
     * @param PhpParser\Node\Expr|PhpParser\Node\Name|PhpParser\Node\Stmt\Return_ $node
     */
    public function getType(PhpParser\NodeAbstract $node) : ?Union;
}
<?php

namespace Psalm\Storage;

/**
 * @psalm-immutable
 */
trait ImmutableNonCloneableTrait
{
    private function __clone()
    {
    }
}
<?php

namespace Psalm\Storage;

use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
abstract class Assertion
{
    use \Psalm\Storage\ImmutableNonCloneableTrait;
    public abstract function getNegation() : \Psalm\Storage\Assertion;
    public abstract function isNegationOf(self $assertion) : bool;
    public abstract function __toString() : string;
    public function isNegation() : bool
    {
        return \false;
    }
    public function hasEquality() : bool
    {
        return \false;
    }
    public function getAtomicType() : ?Atomic
    {
        return null;
    }
    /**
     * @return static
     */
    public function setAtomicType(Atomic $type) : self
    {
        return $this;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsNotIsset extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsIsset();
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!isset';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsNotIsset;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsIdentical extends Assertion
{
    public Atomic $type;
    public function __construct(Atomic $type)
    {
        $this->type = $type;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsNotIdentical($this->type);
    }
    public function __toString() : string
    {
        return '=' . $this->type->getAssertionString();
    }
    public function hasEquality() : bool
    {
        return \true;
    }
    public function getAtomicType() : ?Atomic
    {
        return $this->type;
    }
    /**
     * @return static
     */
    public function setAtomicType(Atomic $type) : self
    {
        return new static($type);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsNotIdentical && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class HasExactCount extends Assertion
{
    /** @var positive-int */
    public $count;
    /** @param positive-int $count */
    public function __construct(int $count)
    {
        $this->count = $count;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\DoesNotHaveExactCount($this->count);
    }
    public function hasEquality() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '=has-exact-count-' . $this->count;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\DoesNotHaveExactCount && $this->count === $assertion->count;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsLessThanOrEqualTo extends Assertion
{
    public int $value;
    public function __construct(int $value)
    {
        $this->value = $value;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsGreaterThan($this->value);
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!>' . $this->value;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsGreaterThan && $this->value === $assertion->value;
    }
    public function doesFilterNullOrFalse() : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class DoesNotHaveMethod extends Assertion
{
    public string $method;
    public function __construct(string $method)
    {
        $this->method = $method;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\HasMethod($this->method);
    }
    public function __toString() : string
    {
        return '!method-exists-' . $this->method;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\HasMethod && $assertion->method === $this->method;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use UnexpectedValueException;
/**
 * @psalm-immutable
 */
final class HasIntOrStringArrayAccess extends Assertion
{
    public function getNegation() : Assertion
    {
        throw new UnexpectedValueException('This should never be called');
    }
    public function __toString() : string
    {
        return 'has-string-or-int-array-access';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class Any extends Assertion
{
    public function getNegation() : Assertion
    {
        return $this;
    }
    public function __toString() : string
    {
        return 'mixed';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsIsset extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsNotIsset();
    }
    public function __toString() : string
    {
        return 'isset';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsNotIsset;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsNotAClass extends Assertion
{
    /** @var Atomic\TTemplateParamClass|Atomic\TNamedObject */
    public Atomic $type;
    public bool $allow_string;
    /** @param Atomic\TTemplateParamClass|Atomic\TNamedObject $type */
    public function __construct(Atomic $type, bool $allow_string)
    {
        $this->type = $type;
        $this->allow_string = $allow_string;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsAClass($this->type, $this->allow_string);
    }
    public function getAtomicType() : Atomic
    {
        return $this->type;
    }
    public function __toString() : string
    {
        return 'isa-' . ($this->allow_string ? 'string-' : '') . $this->type;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsAClass && $this->type === $assertion->type && $this->allow_string === $assertion->allow_string;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsNotType extends Assertion
{
    public Atomic $type;
    public function __construct(Atomic $type)
    {
        $this->type = $type;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsType($this->type);
    }
    public function __toString() : string
    {
        return '!' . $this->type->getId();
    }
    public function getAtomicType() : ?Atomic
    {
        return $this->type;
    }
    /**
     * @return static
     */
    public function setAtomicType(Atomic $type) : self
    {
        return new static($type);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsType && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class Truthy extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\Falsy();
    }
    public function __toString() : string
    {
        return '!falsy';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\Falsy;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsType extends Assertion
{
    public Atomic $type;
    public function __construct(Atomic $type)
    {
        $this->type = $type;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsNotType($this->type);
    }
    public function __toString() : string
    {
        return $this->type->getId();
    }
    public function getAtomicType() : ?Atomic
    {
        return $this->type;
    }
    /**
     * @return static
     */
    public function setAtomicType(Atomic $type) : self
    {
        return new static($type);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsNotType && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsClassEqual extends Assertion
{
    public string $type;
    public function __construct(string $type)
    {
        $this->type = $type;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsClassNotEqual($this->type);
    }
    public function hasEquality() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '=get-class-' . $this->type;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsClassNotEqual && $this->type === $assertion->type;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class NotNonEmptyCountable extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\NonEmptyCountable(\true);
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!non-empty-countable';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\NonEmptyCountable && $assertion->is_negatable;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsLooselyEqual extends Assertion
{
    public Atomic $type;
    public function __construct(Atomic $type)
    {
        $this->type = $type;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsNotLooselyEqual($this->type);
    }
    public function __toString() : string
    {
        return '~' . $this->type->getAssertionString();
    }
    public function getAtomicType() : ?Atomic
    {
        return $this->type;
    }
    public function hasEquality() : bool
    {
        return \true;
    }
    /**
     * @return static
     */
    public function setAtomicType(Atomic $type) : self
    {
        return new static($type);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsNotLooselyEqual && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsNotCountable extends Assertion
{
    public $is_negatable;
    public function __construct(bool $is_negatable)
    {
        $this->is_negatable = $is_negatable;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsCountable();
    }
    public function __toString() : string
    {
        return '!countable';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsCountable;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsLessThan extends Assertion
{
    public int $value;
    public function __construct(int $value)
    {
        $this->value = $value;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsGreaterThanOrEqualTo($this->value);
    }
    public function __toString() : string
    {
        return '<' . $this->value;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsGreaterThanOrEqualTo && $this->value === $assertion->value;
    }
    public function doesFilterNullOrFalse() : bool
    {
        return $this->value === 0;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class NonEmpty extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\Empty_();
    }
    public function __toString() : string
    {
        return 'non-empty';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\Empty_;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Union;
/**
 * @psalm-immutable
 */
final class NotInArray extends Assertion
{
    /**
     * @readonly
     */
    public Union $type;
    public function __construct(Union $type)
    {
        $this->type = $type;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\InArray($this->type);
    }
    public function __toString() : string
    {
        return '!in-array-' . $this->type;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\InArray && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsClassNotEqual extends Assertion
{
    public string $type;
    public function __construct(string $type)
    {
        $this->type = $type;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsClassEqual($this->type);
    }
    public function __toString() : string
    {
        return '!=get-class-' . $this->type;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsClassEqual && $this->type === $assertion->type;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class Empty_ extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\NonEmpty();
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!non-empty';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\NonEmpty;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class ArrayKeyExists extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\ArrayKeyDoesNotExist();
    }
    public function __toString() : string
    {
        return 'array-key-exists';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\ArrayKeyDoesNotExist;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class DoesNotHaveAtLeastCount extends Assertion
{
    /** @var positive-int */
    public $count;
    /** @param positive-int $count */
    public function __construct(int $count)
    {
        $this->count = $count;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\HasAtLeastCount($this->count);
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!has-at-least-' . $this->count;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\HasAtLeastCount && $this->count === $assertion->count;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class HasMethod extends Assertion
{
    public string $method;
    public function __construct(string $method)
    {
        $this->method = $method;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\DoesNotHaveMethod($this->method);
    }
    public function __toString() : string
    {
        return 'method-exists-' . $this->method;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\DoesNotHaveMethod && $this->method === $assertion->method;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use UnexpectedValueException;
/**
 * @psalm-immutable
 */
final class HasArrayKey extends Assertion
{
    public $key;
    public function __construct(string $key)
    {
        $this->key = $key;
    }
    public function getNegation() : Assertion
    {
        throw new UnexpectedValueException('This should never be called');
    }
    public function __toString() : string
    {
        return 'has-array-key-' . $this->key;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsGreaterThan extends Assertion
{
    public int $value;
    public function __construct(int $value)
    {
        $this->value = $value;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsLessThanOrEqualTo($this->value);
    }
    public function __toString() : string
    {
        return '>' . $this->value;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsLessThanOrEqualTo && $this->value === $assertion->value;
    }
    public function doesFilterNullOrFalse() : bool
    {
        return \true;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsNotLooselyEqual extends Assertion
{
    public Atomic $type;
    public function __construct(Atomic $type)
    {
        $this->type = $type;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsLooselyEqual($this->type);
    }
    public function hasEquality() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!~' . $this->type->getAssertionString();
    }
    public function getAtomicType() : ?Atomic
    {
        return $this->type;
    }
    /**
     * @return static
     */
    public function setAtomicType(Atomic $type) : self
    {
        return new static($type);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsLooselyEqual && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class NonEmptyCountable extends Assertion
{
    public $is_negatable;
    public function __construct(bool $is_negatable)
    {
        $this->is_negatable = $is_negatable;
    }
    public function getNegation() : Assertion
    {
        return $this->is_negatable ? new \Psalm\Storage\Assertion\NotNonEmptyCountable() : new \Psalm\Storage\Assertion\Any();
    }
    public function hasEquality() : bool
    {
        return !$this->is_negatable;
    }
    public function __toString() : string
    {
        return ($this->is_negatable ? '' : '=') . 'non-empty-countable';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $this->is_negatable && $assertion instanceof \Psalm\Storage\Assertion\NotNonEmptyCountable;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsNotIdentical extends Assertion
{
    public Atomic $type;
    public function __construct(Atomic $type)
    {
        $this->type = $type;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsIdentical($this->type);
    }
    public function hasEquality() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!=' . $this->type->getAssertionString();
    }
    public function getAtomicType() : ?Atomic
    {
        return $this->type;
    }
    /**
     * @return static
     */
    public function setAtomicType(Atomic $type) : self
    {
        return new static($type);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsIdentical && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use UnexpectedValueException;
/**
 * @psalm-immutable
 */
final class HasStringArrayAccess extends Assertion
{
    public function getNegation() : Assertion
    {
        throw new UnexpectedValueException('This should never be called');
    }
    public function __toString() : string
    {
        return 'has-string-array-access';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use function json_encode;
use const JSON_THROW_ON_ERROR;
/**
 * @psalm-immutable
 */
final class NestedAssertions extends Assertion
{
    /** @var array<string, list<list<Assertion>>> */
    public array $assertions;
    /** @param array<string, list<list<Assertion>>> $assertions */
    public function __construct(array $assertions)
    {
        $this->assertions = $assertions;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\NotNestedAssertions($this->assertions);
    }
    public function __toString() : string
    {
        return '@' . json_encode($this->assertions, JSON_THROW_ON_ERROR);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsEqualIsset extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\Any();
    }
    public function __toString() : string
    {
        return '=isset';
    }
    public function hasEquality() : bool
    {
        return \true;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsGreaterThanOrEqualTo extends Assertion
{
    public int $value;
    public function __construct(int $value)
    {
        $this->value = $value;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsLessThan($this->value);
    }
    public function __toString() : string
    {
        return '!<' . $this->value;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsLessThan && $this->value === $assertion->value;
    }
    public function doesFilterNullOrFalse() : bool
    {
        return $this->value !== 0;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Union;
/**
 * @psalm-immutable
 */
final class InArray extends Assertion
{
    public Union $type;
    public function __construct(Union $type)
    {
        $this->type = $type;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\NotInArray($this->type);
    }
    public function __toString() : string
    {
        return 'in-array-' . $this->type->getId();
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\NotInArray && $this->type->getId() === $assertion->type->getId();
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use function json_encode;
use const JSON_THROW_ON_ERROR;
/**
 * @psalm-immutable
 */
final class NotNestedAssertions extends Assertion
{
    /** @var array<string, list<list<Assertion>>> */
    public array $assertions;
    /** @param array<string, list<list<Assertion>>> $assertions */
    public function __construct(array $assertions)
    {
        $this->assertions = $assertions;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\NestedAssertions($this->assertions);
    }
    public function __toString() : string
    {
        return '!@' . json_encode($this->assertions, JSON_THROW_ON_ERROR);
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class ArrayKeyDoesNotExist extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\ArrayKeyExists();
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return '!array-key-exists';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\ArrayKeyExists;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class Falsy extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\Truthy();
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function __toString() : string
    {
        return 'falsy';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\Truthy;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class HasAtLeastCount extends Assertion
{
    /** @var positive-int */
    public $count;
    /** @param positive-int $count */
    public function __construct(int $count)
    {
        $this->count = $count;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\DoesNotHaveAtLeastCount($this->count);
    }
    public function __toString() : string
    {
        return 'has-at-least-' . $this->count;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\DoesNotHaveAtLeastCount && $this->count === $assertion->count;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class DoesNotHaveExactCount extends Assertion
{
    /** @var positive-int */
    public $count;
    /** @param positive-int $count */
    public function __construct(int $count)
    {
        $this->count = $count;
    }
    public function isNegation() : bool
    {
        return \true;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\HasExactCount($this->count);
    }
    public function __toString() : string
    {
        return '!has-exact-count-' . $this->count;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\HasExactCount && $assertion->count === $this->count;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
/**
 * @psalm-immutable
 */
final class IsCountable extends Assertion
{
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsNotCountable(\true);
    }
    public function __toString() : string
    {
        return 'countable';
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsNotCountable && $assertion->is_negatable;
    }
}
<?php

namespace Psalm\Storage\Assertion;

use Psalm\Storage\Assertion;
use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class IsAClass extends Assertion
{
    /** @var Atomic\TTemplateParamClass|Atomic\TNamedObject */
    public Atomic $type;
    public bool $allow_string;
    /** @param Atomic\TTemplateParamClass|Atomic\TNamedObject $type */
    public function __construct(Atomic $type, bool $allow_string)
    {
        $this->type = $type;
        $this->allow_string = $allow_string;
    }
    public function getNegation() : Assertion
    {
        return new \Psalm\Storage\Assertion\IsNotAClass($this->type, $this->allow_string);
    }
    public function getAtomicType() : Atomic
    {
        return $this->type;
    }
    public function __toString() : string
    {
        return 'isa-' . ($this->allow_string ? 'string-' : '') . $this->type;
    }
    public function isNegationOf(Assertion $assertion) : bool
    {
        return $assertion instanceof \Psalm\Storage\Assertion\IsNotAClass && $this->type === $assertion->type && $this->allow_string === $assertion->allow_string;
    }
}
<?php

namespace Psalm\Storage;

use Psalm\CodeLocation;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use Psalm\Type\MutableTypeVisitor;
use Psalm\Type\TypeNode;
use Psalm\Type\TypeVisitor;
use Psalm\Type\Union;
final class FunctionLikeParameter implements \Psalm\Storage\HasAttributesInterface, TypeNode
{
    use \Psalm\Storage\CustomMetadataTrait;
    /**
     * @var string
     */
    public $name;
    /**
     * @var bool
     */
    public $by_ref;
    /**
     * @var Union|null
     */
    public $type;
    /**
     * @var Union|null
     */
    public $out_type;
    /**
     * @var Union|null
     */
    public $signature_type;
    /**
     * @var bool
     */
    public $has_docblock_type = \false;
    /**
     * @var bool
     */
    public $is_optional;
    /**
     * @var bool
     */
    public $is_nullable;
    /**
     * @var Union|UnresolvedConstantComponent|null
     */
    public $default_type;
    /**
     * @var CodeLocation|null
     */
    public $location;
    /**
     * @var CodeLocation|null
     */
    public $type_location;
    /**
     * @var CodeLocation|null
     */
    public $signature_type_location;
    /**
     * @var bool
     */
    public $is_variadic;
    /**
     * @var array<string>|null
     */
    public $sinks;
    /**
     * @var bool
     */
    public $assert_untainted = \false;
    /**
     * @var bool
     */
    public $type_inferred = \false;
    /**
     * @var bool
     */
    public $expect_variable = \false;
    /**
     * @var bool
     */
    public $promoted_property = \false;
    /**
     * @var list<AttributeStorage>
     */
    public $attributes = [];
    /**
     * @var ?string
     */
    public $description;
    /**
     * @psalm-external-mutation-free
     * @param Union|UnresolvedConstantComponent|null $default_type
     */
    public function __construct(string $name, bool $by_ref, ?Union $type = null, ?Union $signature_type = null, ?CodeLocation $location = null, ?CodeLocation $type_location = null, bool $is_optional = \true, bool $is_nullable = \false, bool $is_variadic = \false, $default_type = null, ?Union $out_type = null)
    {
        $this->name = $name;
        $this->by_ref = $by_ref;
        $this->type = $type;
        $this->signature_type = $signature_type;
        $this->is_optional = $is_optional;
        $this->is_nullable = $is_nullable;
        $this->is_variadic = $is_variadic;
        $this->location = $location;
        $this->type_location = $type_location;
        $this->signature_type_location = $type_location;
        $this->default_type = $default_type;
        $this->out_type = $out_type;
    }
    /** @psalm-mutation-free */
    public function getId() : string
    {
        return ($this->type ? $this->type->getId() : 'mixed') . ($this->is_variadic ? '...' : '') . ($this->is_optional ? '=' : '');
    }
    /** @psalm-mutation-free */
    public function setType(Union $type) : self
    {
        if ($this->type === $type) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->type = $type;
        return $cloned;
    }
    /**
     * @internal Should only be used by the MutableTypeVisitor.
     * @psalm-mutation-free
     */
    public function visit(TypeVisitor $visitor) : bool
    {
        if ($this->type && !$visitor->traverse($this->type)) {
            return \false;
        }
        if ($this->signature_type && !$visitor->traverse($this->signature_type)) {
            return \false;
        }
        if ($this->out_type && !$visitor->traverse($this->out_type)) {
            return \false;
        }
        if ($this->default_type instanceof Union && !$visitor->traverse($this->default_type)) {
            return \false;
        }
        return \true;
    }
    /**
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingAnyTypeHint
     */
    public static function visitMutable(MutableTypeVisitor $visitor, &$node, bool $cloned) : bool
    {
        foreach (['type', 'signature_type', 'out_type', 'default_type'] as $key) {
            if (!$node->{$key} instanceof TypeNode) {
                continue;
            }
            /** @var TypeNode */
            $value = $node->{$key};
            $value_orig = $value;
            $result = $visitor->traverse($value);
            if ($value !== $value_orig) {
                if (!$cloned) {
                    $node = clone $node;
                    $cloned = \true;
                }
                $node->{$key} = $value;
            }
            if (!$result) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     * @return list<AttributeStorage>
     */
    public function getAttributeStorages() : array
    {
        return $this->attributes;
    }
}
<?php

namespace Psalm\Storage;

/**
 * @psalm-type _MetadataEntry scalar|scalar[]|scalar[][]|scalar[][][]|scalar[][][][]|scalar[][][][][]
 */
trait CustomMetadataTrait
{
    /** @var array<string,_MetadataEntry> */
    public $custom_metadata = [];
}
<?php

namespace Psalm\Storage;

use Psalm\Aliases;
use Psalm\Internal\Type\TypeAlias;
use Psalm\Issue\CodeIssue;
use Psalm\Type\Union;
final class FileStorage
{
    use \Psalm\Storage\CustomMetadataTrait;
    /**
     * @var array<lowercase-string, string>
     */
    public $classlikes_in_file = [];
    /**
     * @var array<lowercase-string, string>
     */
    public $referenced_classlikes = [];
    /**
     * @var array<lowercase-string, string>
     */
    public $required_classes = [];
    /**
     * @var array<lowercase-string, string>
     */
    public $required_interfaces = [];
    /** @var string */
    public $file_path;
    /**
     * @var array<string, FunctionStorage>
     */
    public $functions = [];
    /** @var array<string, string> */
    public $declaring_function_ids = [];
    /**
     * @var array<string, Union>
     */
    public $constants = [];
    /** @var array<string, string> */
    public $declaring_constants = [];
    /** @var array<lowercase-string, string> */
    public $required_file_paths = [];
    /** @var array<lowercase-string, string> */
    public $required_by_file_paths = [];
    /** @var bool */
    public $populated = \false;
    /** @var bool */
    public $deep_scan = \false;
    /** @var bool */
    public $has_extra_statements = \false;
    /**
     * @var string
     */
    public $hash = '';
    /**
     * @var bool
     */
    public $has_visitor_issues = \false;
    /**
     * @var list<CodeIssue>
     */
    public $docblock_issues = [];
    /**
     * @var array<string, TypeAlias>
     */
    public $type_aliases = [];
    /**
     * @var array<string, string>
     */
    public $classlike_aliases = [];
    /** @var ?Aliases */
    public $aliases;
    /** @var Aliases[] */
    public $namespace_aliases = [];
    public function __construct(string $file_path)
    {
        $this->file_path = $file_path;
    }
}
<?php

namespace Psalm\Storage;

use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Type\Union;
final class PropertyStorage implements \Psalm\Storage\HasAttributesInterface
{
    use \Psalm\Storage\CustomMetadataTrait;
    /**
     * @var ?bool
     */
    public $is_static;
    /**
     * @var ClassLikeAnalyzer::VISIBILITY_*
     */
    public $visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
    /**
     * @var CodeLocation|null
     */
    public $location;
    /**
     * @var CodeLocation|null
     */
    public $stmt_location;
    /**
     * @var CodeLocation|null
     */
    public $type_location;
    /**
     * @var CodeLocation|null
     */
    public $signature_type_location;
    /**
     * @var Union|null
     */
    public $type;
    /**
     * @var Union|null
     */
    public $signature_type;
    /**
     * @var Union|null
     */
    public $suggested_type;
    /**
     * @var bool
     */
    public $has_default = \false;
    /**
     * @var bool
     */
    public $deprecated = \false;
    /**
     * @var bool
     */
    public $readonly = \false;
    /**
     * Whether or not to allow mutation by internal methods
     *
     * @var bool
     */
    public $allow_private_mutation = \false;
    /**
     * @var list<non-empty-string>
     */
    public $internal = [];
    /**
     * @var ?string
     */
    public $getter_method;
    /**
     * @var bool
     */
    public $is_promoted = \false;
    /**
     * @var list<AttributeStorage>
     */
    public $attributes = [];
    /**
     * @var array<int, string>
     */
    public $suppressed_issues = [];
    /**
     * @var ?string
     */
    public $description;
    public function getInfo() : string
    {
        switch ($this->visibility) {
            case ClassLikeAnalyzer::VISIBILITY_PRIVATE:
                $visibility_text = 'private';
                break;
            case ClassLikeAnalyzer::VISIBILITY_PROTECTED:
                $visibility_text = 'protected';
                break;
            default:
                $visibility_text = 'public';
        }
        return $visibility_text . ' ' . ($this->type ? $this->type->getId() : 'mixed');
    }
    /**
     * @return list<AttributeStorage>
     */
    public function getAttributeStorages() : array
    {
        return $this->attributes;
    }
}
<?php

namespace Psalm\Storage;

use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Issue\CodeIssue;
use Psalm\Type\Union;
use function array_column;
use function array_fill_keys;
use function array_map;
use function implode;
abstract class FunctionLikeStorage implements \Psalm\Storage\HasAttributesInterface
{
    use \Psalm\Storage\CustomMetadataTrait;
    /**
     * @var CodeLocation|null
     */
    public $location;
    /**
     * @var CodeLocation|null
     */
    public $stmt_location;
    /**
     * @psalm-readonly-allow-private-mutation
     * @var list<FunctionLikeParameter>
     */
    public $params = [];
    /**
     * @psalm-readonly-allow-private-mutation
     * @var array<string, bool>
     */
    public $param_lookup = [];
    /**
     * @var Union|null
     */
    public $return_type;
    /**
     * @var CodeLocation|null
     */
    public $return_type_location;
    /**
     * @var Union|null
     */
    public $signature_return_type;
    /**
     * @var CodeLocation|null
     */
    public $signature_return_type_location;
    /**
     * @var ?string
     */
    public $cased_name;
    /**
     * @var array<int, string>
     */
    public $suppressed_issues = [];
    /**
     * @var ?bool
     */
    public $deprecated;
    /**
     * @var list<non-empty-string>
     */
    public $internal = [];
    /**
     * @var bool
     */
    public $variadic = \false;
    /**
     * @var bool
     */
    public $returns_by_ref = \false;
    /**
     * @var ?int
     */
    public $required_param_count;
    /**
     * @var array<string, Union>
     */
    public $defined_constants = [];
    /**
     * @var array<string, bool>
     */
    public $global_variables = [];
    /**
     * @var array<string, Union>
     */
    public $global_types = [];
    /**
     * An array holding the class template "as" types.
     *
     * It's the de-facto list of all templates on a given class.
     *
     * The name of the template is the first key. The nested array is keyed by a unique
     * function identifier. This allows operations with the same-named template defined
     * across multiple classes and/or functions to not run into trouble.
     *
     * @var array<string, non-empty-array<string, Union>>|null
     */
    public $template_types;
    /**
     * @var array<int, Possibilities>
     */
    public $assertions = [];
    /**
     * @var array<int, Possibilities>
     */
    public $if_true_assertions = [];
    /**
     * @var array<int, Possibilities>
     */
    public $if_false_assertions = [];
    /**
     * @var bool
     */
    public $has_visitor_issues = \false;
    /**
     * @var list<CodeIssue>
     */
    public $docblock_issues = [];
    /**
     * @var array<string, bool>
     */
    public $throws = [];
    /**
     * @var array<string, CodeLocation>
     */
    public $throw_locations = [];
    /**
     * @var bool
     */
    public $has_yield = \false;
    /**
     * @var bool
     */
    public $mutation_free = \false;
    /**
     * @var string|null
     */
    public $return_type_description;
    /**
     * @var array<string, CodeLocation>|null
     */
    public $unused_docblock_params;
    /**
     * @var bool
     */
    public $pure = \false;
    /**
     * Whether or not the function output is dependent solely on input - a function can be
     * impure but still have this property (e.g. var_export). Useful for taint analysis.
     *
     * @var bool
     */
    public $specialize_call = \false;
    /**
     * @var array<string>
     */
    public $taint_source_types = [];
    /**
     * @var array<string>
     */
    public $added_taints = [];
    /**
     * @var array<string>
     */
    public $removed_taints = [];
    /**
     * @var array<Union>
     */
    public $conditionally_removed_taints = [];
    /**
     * @var array<int, string>
     */
    public $return_source_params = [];
    /**
     * @var bool
     */
    public $allow_named_arg_calls = \true;
    /**
     * @var list<AttributeStorage>
     */
    public $attributes = [];
    /**
     * @var list<array{fqn: string, params: array<int>, return: bool}>|null
     */
    public $proxy_calls = [];
    /**
     * @var ?string
     */
    public $description;
    public function __toString() : string
    {
        return $this->getSignature(\false);
    }
    public function getSignature(bool $allow_newlines) : string
    {
        $newlines = $allow_newlines && !empty($this->params);
        $symbol_text = 'function ' . $this->cased_name . '(' . ($newlines ? "\n" : '') . implode(',' . ($newlines ? "\n" : ' '), array_map(static fn(\Psalm\Storage\FunctionLikeParameter $param): string => ($newlines ? '    ' : '') . ($param->type ? $param->type->getId(\false) : 'mixed') . ' $' . $param->name, $this->params)) . ($newlines ? "\n" : '') . ') : ' . ($this->return_type ?: 'mixed');
        if (!$this instanceof \Psalm\Storage\MethodStorage) {
            return $symbol_text;
        }
        switch ($this->visibility) {
            case ClassLikeAnalyzer::VISIBILITY_PRIVATE:
                $visibility_text = 'private';
                break;
            case ClassLikeAnalyzer::VISIBILITY_PROTECTED:
                $visibility_text = 'protected';
                break;
            default:
                $visibility_text = 'public';
        }
        return $visibility_text . ' ' . $symbol_text;
    }
    /**
     * @internal
     * @param list<FunctionLikeParameter> $params
     */
    public function setParams(array $params) : void
    {
        $this->params = $params;
        $param_names = array_column($params, 'name');
        $this->param_lookup = array_fill_keys($param_names, \true);
    }
    /**
     * @internal
     */
    public function addParam(\Psalm\Storage\FunctionLikeParameter $param, bool $lookup_value = null) : void
    {
        $this->params[] = $param;
        $this->param_lookup[$param->name] = $lookup_value ?? \true;
    }
    /**
     * @return list<AttributeStorage>
     */
    public function getAttributeStorages() : array
    {
        return $this->attributes;
    }
}
<?php

namespace Psalm\Storage;

use Psalm\CodeLocation;
/**
 * @psalm-immutable
 */
final class AttributeStorage
{
    use \Psalm\Storage\ImmutableNonCloneableTrait;
    /**
     * @var string
     */
    public $fq_class_name;
    /**
     * @var list<AttributeArg>
     */
    public $args;
    /**
     * @var CodeLocation
     * @psalm-suppress PossiblyUnusedProperty part of public API
     */
    public $location;
    /**
     * @var CodeLocation
     * @psalm-suppress PossiblyUnusedProperty part of public API
     */
    public $name_location;
    /**
     * @param list<AttributeArg> $args
     */
    public function __construct(string $fq_class_name, array $args, CodeLocation $location, CodeLocation $name_location)
    {
        $this->fq_class_name = $fq_class_name;
        $this->args = $args;
        $this->location = $location;
        $this->name_location = $name_location;
    }
}
<?php

namespace Psalm\Storage;

use Psalm\Aliases;
use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\TypeAlias\ClassTypeAlias;
use Psalm\Issue\CodeIssue;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
use function array_values;
final class ClassLikeStorage implements \Psalm\Storage\HasAttributesInterface
{
    use \Psalm\Storage\CustomMetadataTrait;
    /**
     * @var array<string, ClassConstantStorage>
     */
    public $constants = [];
    /**
     * Aliases to help Psalm understand constant refs
     *
     * @var ?Aliases
     */
    public $aliases;
    /**
     * @var bool
     */
    public $populated = \false;
    /**
     * @var bool
     */
    public $stubbed = \false;
    /**
     * @var bool
     */
    public $deprecated = \false;
    /**
     * @var list<non-empty-string>
     */
    public $internal = [];
    /**
     * @var TTemplateParam[]
     */
    public $templatedMixins = [];
    /**
     * @var list<TNamedObject>
     */
    public $namedMixins = [];
    /**
     * @var ?string
     */
    public $mixin_declaring_fqcln;
    /**
     * @var bool
     */
    public $sealed_properties = \false;
    /**
     * @var bool
     */
    public $sealed_methods = \false;
    /**
     * @var bool
     */
    public $override_property_visibility = \false;
    /**
     * @var bool
     */
    public $override_method_visibility = \false;
    /**
     * @var array<int, string>
     */
    public $suppressed_issues = [];
    /**
     * @var string
     */
    public $name;
    /**
     * Is this class user-defined
     *
     * @var bool
     */
    public $user_defined = \false;
    /**
     * Interfaces this class implements directly
     *
     * @var array<lowercase-string, string>
     */
    public $direct_class_interfaces = [];
    /**
     * Interfaces this class implements explicitly and implicitly
     *
     * @var array<lowercase-string, string>
     */
    public $class_implements = [];
    /**
     * Parent interfaces listed explicitly
     *
     * @var array<lowercase-string, string>
     */
    public $direct_interface_parents = [];
    /**
     * Parent interfaces
     *
     * @var  array<lowercase-string, string>
     */
    public $parent_interfaces = [];
    /**
     * There can only be one direct parent class
     *
     * @var ?string
     */
    public $parent_class;
    /**
     * Parent classes
     *
     * @var array<lowercase-string, string>
     */
    public $parent_classes = [];
    /**
     * @var CodeLocation|null
     */
    public $location;
    /**
     * @var CodeLocation|null
     */
    public $stmt_location;
    /**
     * @var CodeLocation|null
     */
    public $namespace_name_location;
    /**
     * @var bool
     */
    public $abstract = \false;
    /**
     * @var bool
     */
    public $final = \false;
    /**
     * @var bool
     */
    public $final_from_docblock = \false;
    /**
     * @var array<lowercase-string, string>
     */
    public $used_traits = [];
    /**
     * @var array<lowercase-string, lowercase-string>
     */
    public $trait_alias_map = [];
    /**
     * @var array<string, string>
     */
    public array $trait_alias_map_cased = [];
    /**
     * @var array<lowercase-string, bool>
     */
    public $trait_final_map = [];
    /**
     * @var array<string, ClassLikeAnalyzer::VISIBILITY_*>
     */
    public $trait_visibility_map = [];
    /**
     * @var bool
     */
    public $is_trait = \false;
    /**
     * @var bool
     */
    public $is_interface = \false;
    /**
     * @var bool
     */
    public $is_enum = \false;
    /**
     * @var bool
     */
    public $external_mutation_free = \false;
    /**
     * @var bool
     */
    public $mutation_free = \false;
    /**
     * @var bool
     */
    public $specialize_instance = \false;
    /**
     * @var array<lowercase-string, MethodStorage>
     */
    public $methods = [];
    /**
     * @var array<lowercase-string, MethodStorage>
     */
    public $pseudo_methods = [];
    /**
     * @var array<lowercase-string, MethodStorage>
     */
    public $pseudo_static_methods = [];
    /**
     * Maps pseudo method names to the original declaring method identifier
     * The key is the method name in lowercase, and the value is the original `MethodIdentifier` instance
     *
     * This property contains all pseudo methods declared on ancestors.
     *
     * @var array<lowercase-string, MethodIdentifier>
     */
    public $declaring_pseudo_method_ids = [];
    /**
     * @var array<lowercase-string, MethodIdentifier>
     */
    public $declaring_method_ids = [];
    /**
     * @var array<lowercase-string, MethodIdentifier>
     */
    public $appearing_method_ids = [];
    /**
     * Map from lowercase method name to list of declarations in order from parent, to grandparent, to
     * great-grandparent, etc **including traits and interfaces**. Ancestors that don't have their own declaration are
     * skipped.
     *
     * @var array<lowercase-string, array<string, MethodIdentifier>>
     */
    public $overridden_method_ids = [];
    /**
     * @var array<lowercase-string, MethodIdentifier>
     */
    public $documenting_method_ids = [];
    /**
     * @var array<lowercase-string, MethodIdentifier>
     */
    public $inheritable_method_ids = [];
    /**
     * @var array<lowercase-string, array<string, bool>>
     */
    public $potential_declaring_method_ids = [];
    /**
     * @var array<string, PropertyStorage>
     */
    public $properties = [];
    /**
     * @var array<string, Union>
     */
    public $pseudo_property_set_types = [];
    /**
     * @var array<string, Union>
     */
    public $pseudo_property_get_types = [];
    /**
     * @var array<string, string>
     */
    public $declaring_property_ids = [];
    /**
     * @var array<string, string>
     */
    public $appearing_property_ids = [];
    /**
     * @var array<string, string>
     */
    public $inheritable_property_ids = [];
    /**
     * @var array<string, array<string>>
     */
    public $overridden_property_ids = [];
    /**
     * An array holding the class template "as" types.
     *
     * It's the de-facto list of all templates on a given class.
     *
     * The name of the template is the first key. The nested array is keyed by the defining class
     * (i.e. the same as the class name). This allows operations with the same-named template defined
     * across multiple classes to not run into trouble.
     *
     * @var array<string, non-empty-array<string, Union>>|null
     */
    public $template_types;
    /**
     * @var array<int, bool>|null
     */
    public $template_covariants;
    /**
     * A map of which generic classlikes are extended or implemented by this class or interface.
     *
     * This is only used in the populator, which poulates the $template_extended_params property below.
     *
     * @internal
     * @var array<string, non-empty-array<int, Union>>|null
     */
    public $template_extended_offsets;
    /**
     * A map of which generic classlikes are extended or implemented by this class or interface.
     *
     * The annotation "@extends Traversable<SomeClass, SomeOtherClass>" would generate an entry of
     *
     * [
     *     "Traversable" => [
     *         "TKey" => new Union([new TNamedObject("SomeClass")]),
     *         "TValue" => new Union([new TNamedObject("SomeOtherClass")])
     *     ]
     * ]
     *
     * @var array<string, array<string, Union>>|null
     */
    public $template_extended_params;
    /**
     * @var array<string, int>|null
     */
    public $template_type_extends_count;
    /**
     * @var array<string, int>|null
     */
    public $template_type_implements_count;
    /**
     * @var ?Union
     */
    public $yield;
    /** @var ?string */
    public $declaring_yield_fqcn;
    /**
     * @var array<string, int>|null
     */
    public $template_type_uses_count;
    /**
     * @var array<string, bool>
     */
    public $initialized_properties = [];
    /**
     * @var array<string, true>
     */
    public $invalid_dependencies = [];
    /**
     * @var array<lowercase-string, bool>
     */
    public $dependent_classlikes = [];
    /**
     * A hash of the source file's name, contents, and this file's modified on date
     *
     * @var string
     */
    public $hash = '';
    /**
     * @var bool
     */
    public $has_visitor_issues = \false;
    /**
     * @var list<CodeIssue>
     */
    public $docblock_issues = [];
    /**
     * @var array<string, ClassTypeAlias>
     */
    public $type_aliases = [];
    /**
     * @var bool
     */
    public $preserve_constructor_signature = \false;
    /**
     * @var bool
     */
    public $enforce_template_inheritance = \false;
    /**
     * @var null|string
     */
    public $extension_requirement;
    /**
     * @var array<int, string>
     */
    public $implementation_requirements = [];
    /**
     * @var list<AttributeStorage>
     */
    public $attributes = [];
    /**
     * @var array<string, EnumCaseStorage>
     */
    public $enum_cases = [];
    /**
     * @var 'int'|'string'|null
     */
    public $enum_type;
    /**
     * @var ?string
     */
    public $description;
    public bool $public_api = \false;
    public function __construct(string $name)
    {
        $this->name = $name;
    }
    /**
     * @return list<AttributeStorage>
     */
    public function getAttributeStorages() : array
    {
        return $this->attributes;
    }
    /**
     * Get the template constraint types for the class.
     *
     * @return list<Union>
     */
    public function getClassTemplateTypes() : array
    {
        $type_params = [];
        foreach ($this->template_types ?? [] as $type_map) {
            $type_params[] = array_values($type_map)[0];
        }
        return $type_params;
    }
}
<?php

namespace Psalm\Storage;

final class FunctionStorage extends \Psalm\Storage\FunctionLikeStorage
{
    /** @var array<string, bool> */
    public $byref_uses = [];
    /**
     * @var bool
     * @todo lift this property to FunctionLikeStorage in Psalm 6
     */
    public $is_static = \false;
}
<?php

declare (strict_types=1);
namespace Psalm\Storage;

interface HasAttributesInterface
{
    /**
     * Returns a list of AttributeStorages with the same order they appear in the AttributeGroups they come from.
     *
     * @return list<AttributeStorage>
     * @psalm-suppress PossiblyUnusedMethod part of public API
     */
    public function getAttributeStorages() : array;
}
<?php

namespace Psalm\Storage;

use Psalm\Type\Union;
final class MethodStorage extends \Psalm\Storage\FunctionLikeStorage
{
    /**
     * @var bool
     */
    public $is_static = \false;
    /**
     * @var int
     */
    public $visibility = 0;
    /**
     * @var bool
     */
    public $final = \false;
    /**
     * @var bool
     */
    public $final_from_docblock = \false;
    /**
     * @var bool
     */
    public $abstract = \false;
    /**
     * @var bool
     */
    public $overridden_downstream = \false;
    /**
     * @var bool
     */
    public $overridden_somewhere = \false;
    /**
     * @var bool
     */
    public $inheritdoc = \false;
    /**
     * @var ?bool
     */
    public $inherited_return_type = \false;
    /**
     * @var ?string
     */
    public $defining_fqcln;
    /**
     * @var bool
     */
    public $has_docblock_param_types = \false;
    /**
     * @var bool
     */
    public $has_docblock_return_type = \false;
    /**
     * @var bool
     */
    public $external_mutation_free = \false;
    /**
     * @var bool
     */
    public $immutable = \false;
    /**
     * @var bool
     */
    public $mutation_free_inferred = \false;
    /**
     * @var ?array<string, bool>
     */
    public $this_property_mutations;
    /**
     * @var Union|null
     */
    public $self_out_type;
    /**
     * @var Union|null
     */
    public $if_this_is_type = null;
    /**
     * @var bool
     */
    public $stubbed = \false;
    /**
     * @var bool
     */
    public $probably_fluent = \false;
}
<?php

namespace Psalm\Storage;

use Psalm\CodeLocation;
final class EnumCaseStorage
{
    /**
     * @var int|string|null
     */
    public $value;
    /** @var CodeLocation */
    public $stmt_location;
    /**
     * @var bool
     */
    public $deprecated = \false;
    /**
     * @param int|string|null  $value
     */
    public function __construct($value, CodeLocation $location)
    {
        $this->value = $value;
        $this->stmt_location = $location;
    }
}
<?php

namespace Psalm\Storage;

use Psalm\Codebase;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Union;
use function is_string;
use function str_replace;
final class Possibilities
{
    /**
     * @var list<Assertion> the rule being asserted
     */
    public $rule;
    /**
     * @var int|string the id of the property/variable, or
     *  the parameter offset of the affected arg
     */
    public $var_id;
    /**
     * @param string|int $var_id
     * @param list<Assertion> $rule
     */
    public function __construct($var_id, array $rule)
    {
        $this->rule = $rule;
        $this->var_id = $var_id;
    }
    public function getUntemplatedCopy(TemplateResult $template_result, ?string $this_var_id, ?Codebase $codebase) : self
    {
        $assertion_rules = [];
        foreach ($this->rule as $assertion) {
            $assertion_type = $assertion->getAtomicType();
            if ($assertion_type) {
                $union = new Union([$assertion_type]);
                $union = TemplateInferredTypeReplacer::replace($union, $template_result, $codebase);
                foreach ($union->getAtomicTypes() as $atomic_type) {
                    $assertion = $assertion->setAtomicType($atomic_type);
                    $assertion_rules[] = $assertion;
                }
            } else {
                $assertion_rules[] = $assertion;
            }
        }
        return new \Psalm\Storage\Possibilities(is_string($this->var_id) && $this_var_id ? str_replace('$this->', $this_var_id . '->', $this->var_id) : $this->var_id, $assertion_rules);
    }
}
<?php

namespace Psalm\Storage;

use Psalm\CodeLocation;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use Psalm\Type\Union;
/**
 * @psalm-suppress PossiblyUnusedProperty
 * @psalm-immutable
 */
final class ClassConstantStorage
{
    /** @psalm-suppress MutableDependency Mutable by design */
    use \Psalm\Storage\CustomMetadataTrait;
    use \Psalm\Storage\ImmutableNonCloneableTrait;
    public ?CodeLocation $type_location;
    /**
     * The type from an annotation, or the inferred type if no annotation exists.
     */
    public ?Union $type;
    /**
     * The type inferred from the value.
     */
    public ?Union $inferred_type;
    /**
     * @var ClassLikeAnalyzer::VISIBILITY_*
     */
    public int $visibility = ClassLikeAnalyzer::VISIBILITY_PUBLIC;
    public ?CodeLocation $location;
    public ?CodeLocation $stmt_location;
    public ?UnresolvedConstantComponent $unresolved_node;
    public bool $deprecated = \false;
    public bool $final = \false;
    /**
     * @var list<AttributeStorage>
     */
    public array $attributes = [];
    /**
     * @var array<int, string>
     */
    public array $suppressed_issues = [];
    public ?string $description;
    /**
     * @param ClassLikeAnalyzer::VISIBILITY_* $visibility
     * @param list<AttributeStorage> $attributes
     * @param array<int, string> $suppressed_issues
     */
    public function __construct(?Union $type, ?Union $inferred_type, int $visibility, ?CodeLocation $location, ?CodeLocation $type_location = null, ?CodeLocation $stmt_location = null, bool $deprecated = \false, bool $final = \false, ?UnresolvedConstantComponent $unresolved_node = null, array $attributes = [], array $suppressed_issues = [], ?string $description = null)
    {
        $this->visibility = $visibility;
        $this->location = $location;
        $this->type = $type;
        $this->inferred_type = $inferred_type;
        $this->type_location = $type_location;
        $this->stmt_location = $stmt_location;
        $this->deprecated = $deprecated;
        $this->final = $final;
        $this->unresolved_node = $unresolved_node;
        $this->attributes = $attributes;
        $this->suppressed_issues = $suppressed_issues;
        $this->description = $description;
    }
}
<?php

namespace Psalm\Storage;

use Psalm\CodeLocation;
use Psalm\Internal\Scanner\UnresolvedConstantComponent;
use Psalm\Type\Union;
/**
 * @psalm-immutable
 */
final class AttributeArg
{
    use \Psalm\Storage\ImmutableNonCloneableTrait;
    /**
     * @var ?string
     * @psalm-suppress PossiblyUnusedProperty It's part of the public API for now
     */
    public $name;
    /**
     * @var Union|UnresolvedConstantComponent
     */
    public $type;
    /**
     * @var CodeLocation
     * @psalm-suppress PossiblyUnusedProperty It's part of the public API for now
     */
    public $location;
    /**
     * @param Union|UnresolvedConstantComponent $type
     */
    public function __construct(?string $name, $type, CodeLocation $location)
    {
        $this->name = $name;
        $this->type = $type;
        $this->location = $location;
    }
}
<?php

namespace Psalm;

use LogicException;
use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Plugin\FileExtensionsInterface;
use function class_exists;
use function in_array;
use function is_a;
use function sprintf;
final class PluginFileExtensionsSocket implements FileExtensionsInterface
{
    private \Psalm\Config $config;
    /**
     * @var array<string, class-string<FileScanner>>
     */
    private array $additionalFileTypeScanners = [];
    /**
     * @var array<string, class-string<FileAnalyzer>>
     */
    private array $additionalFileTypeAnalyzers = [];
    /**
     * @var list<string>
     */
    private array $additionalFileExtensions = [];
    /**
     * @internal
     */
    public function __construct(\Psalm\Config $config)
    {
        $this->config = $config;
    }
    /**
     * @param string $fileExtension e.g. `'html'`
     * @param class-string<FileScanner> $className
     */
    public function addFileTypeScanner(string $fileExtension, string $className) : void
    {
        if (!class_exists($className) || !is_a($className, FileScanner::class, \true)) {
            throw new LogicException(sprintf('Class %s must be of type %s', $className, FileScanner::class), 1622727271);
        }
        if (!empty($this->config->getFiletypeScanners()[$fileExtension]) || !empty($this->additionalFileTypeScanners[$fileExtension])) {
            throw new LogicException(sprintf('Cannot redeclare scanner for file-type %s', $fileExtension), 1622727272);
        }
        $this->additionalFileTypeScanners[$fileExtension] = $className;
        $this->addFileExtension($fileExtension);
    }
    /**
     * @return array<string, class-string<FileScanner>>
     */
    public function getAdditionalFileTypeScanners() : array
    {
        return $this->additionalFileTypeScanners;
    }
    /**
     * @param string $fileExtension e.g. `'html'`
     * @param class-string<FileAnalyzer> $className
     */
    public function addFileTypeAnalyzer(string $fileExtension, string $className) : void
    {
        if (!class_exists($className) || !is_a($className, FileAnalyzer::class, \true)) {
            throw new LogicException(sprintf('Class %s must be of type %s', $className, FileAnalyzer::class), 1622727281);
        }
        if (!empty($this->config->getFiletypeAnalyzers()[$fileExtension]) || !empty($this->additionalFileTypeAnalyzers[$fileExtension])) {
            throw new LogicException(sprintf('Cannot redeclare analyzer for file-type %s', $fileExtension), 1622727282);
        }
        $this->additionalFileTypeAnalyzers[$fileExtension] = $className;
        $this->addFileExtension($fileExtension);
    }
    /**
     * @return array<string, class-string<FileAnalyzer>>
     */
    public function getAdditionalFileTypeAnalyzers() : array
    {
        return $this->additionalFileTypeAnalyzers;
    }
    /**
     * @return list<string> e.g. `['html', 'perl']`
     */
    public function getAdditionalFileExtensions() : array
    {
        return $this->additionalFileExtensions;
    }
    /**
     * @param string $fileExtension e.g. `'html'`
     */
    private function addFileExtension(string $fileExtension) : void
    {
        /** @psalm-suppress RedundantCondition */
        if (!in_array($fileExtension, $this->additionalFileExtensions, \true) && !in_array($fileExtension, $this->config->getFileExtensions(), \true)) {
            $this->additionalFileExtensions[] = $fileExtension;
        }
    }
}
<?php

namespace Psalm;

use Exception;
use InvalidArgumentException;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Command;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\CompletionItem;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\CompletionItemKind;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\InsertTextFormat;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\ParameterInformation;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Position;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\Range;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\SignatureInformation;
use _HumbugBox1cb33d1f20f1\LanguageServerProtocol\TextEdit;
use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
use Psalm\CodeLocation\Raw;
use Psalm\Exception\UnanalyzedFileException;
use Psalm\Exception\UnpopulatedClasslikeException;
use Psalm\Internal\Analyzer\FunctionLikeAnalyzer;
use Psalm\Internal\Analyzer\NamespaceAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Analyzer\Statements\Block\ForeachAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\ConstFetchAnalyzer;
use Psalm\Internal\Analyzer\Statements\Expression\Fetch\VariableFetchAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\Analyzer;
use Psalm\Internal\Codebase\ClassLikes;
use Psalm\Internal\Codebase\Functions;
use Psalm\Internal\Codebase\InternalCallMapHandler;
use Psalm\Internal\Codebase\Methods;
use Psalm\Internal\Codebase\Populator;
use Psalm\Internal\Codebase\Properties;
use Psalm\Internal\Codebase\Reflection;
use Psalm\Internal\Codebase\Scanner;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\DataFlow\TaintSink;
use Psalm\Internal\DataFlow\TaintSource;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Provider\ClassLikeStorageProvider;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Internal\Provider\FileReferenceProvider;
use Psalm\Internal\Provider\FileStorageProvider;
use Psalm\Internal\Provider\Providers;
use Psalm\Internal\Provider\StatementsProvider;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Progress\Progress;
use Psalm\Progress\VoidProgress;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\FileStorage;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Storage\FunctionStorage;
use Psalm\Storage\MethodStorage;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TClassConstant;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\TaintKindGroup;
use Psalm\Type\Union;
use ReflectionProperty;
use ReflectionType;
use UnexpectedValueException;
use function array_combine;
use function array_pop;
use function array_reverse;
use function count;
use function dirname;
use function error_log;
use function explode;
use function implode;
use function in_array;
use function intdiv;
use function is_numeric;
use function is_string;
use function krsort;
use function ksort;
use function preg_match;
use function preg_replace;
use function strlen;
use function strpos;
use function strrpos;
use function strtolower;
use function substr;
use function substr_count;
use const PHP_VERSION_ID;
final class Codebase
{
    /**
     * @var Config
     */
    public $config;
    /**
     * A map of fully-qualified use declarations to the files
     * that reference them (keyed by filename)
     *
     * @var array<lowercase-string, array<int, CodeLocation>>
     */
    public $use_referencing_locations = [];
    /**
     * @var FileStorageProvider
     */
    public $file_storage_provider;
    /**
     * @var ClassLikeStorageProvider
     */
    public $classlike_storage_provider;
    /**
     * @var bool
     */
    public $collect_references = \false;
    /**
     * @var bool
     */
    public $collect_locations = \false;
    /**
     * @var null|'always'|'auto'
     */
    public $find_unused_code;
    /**
     * @var FileProvider
     */
    public $file_provider;
    /**
     * @var FileReferenceProvider
     */
    public $file_reference_provider;
    /**
     * @var StatementsProvider
     */
    public $statements_provider;
    private Progress $progress;
    /**
     * @var array<string, Union>
     */
    private static $stubbed_constants = [];
    /**
     * Whether to register autoloaded information
     *
     * @var bool
     */
    public $register_autoload_files = \false;
    /**
     * Whether to log functions just at the file level or globally (for stubs)
     *
     * @var bool
     */
    public $register_stub_files = \false;
    /**
     * @var bool
     */
    public $find_unused_variables = \false;
    /**
     * @var Scanner
     */
    public $scanner;
    /**
     * @var Analyzer
     */
    public $analyzer;
    /**
     * @var Functions
     */
    public $functions;
    /**
     * @var ClassLikes
     */
    public $classlikes;
    /**
     * @var Methods
     */
    public $methods;
    /**
     * @var Properties
     */
    public $properties;
    /**
     * @var Populator
     */
    public $populator;
    /**
     * @var ?TaintFlowGraph
     */
    public $taint_flow_graph;
    /**
     * @var bool
     */
    public $server_mode = \false;
    /**
     * @var bool
     */
    public $store_node_types = \false;
    /**
     * Whether or not to infer types from usage. Computationally expensive, so turned off by default
     *
     * @var bool
     */
    public $infer_types_from_usage = \false;
    /**
     * @var bool
     */
    public $alter_code = \false;
    /**
     * @var bool
     */
    public $diff_methods = \false;
    /**
     * @var array<lowercase-string, string>
     */
    public $methods_to_move = [];
    /**
     * @var array<lowercase-string, string>
     */
    public $methods_to_rename = [];
    /**
     * @var array<string, string>
     */
    public $properties_to_move = [];
    /**
     * @var array<string, string>
     */
    public $properties_to_rename = [];
    /**
     * @var array<string, string>
     */
    public $class_constants_to_move = [];
    /**
     * @var array<string, string>
     */
    public $class_constants_to_rename = [];
    /**
     * @var array<lowercase-string, string>
     */
    public $classes_to_move = [];
    /**
     * @var array<lowercase-string, string>
     */
    public $call_transforms = [];
    /**
     * @var array<string, string>
     */
    public $property_transforms = [];
    /**
     * @var array<string, string>
     */
    public $class_constant_transforms = [];
    /**
     * @var array<lowercase-string, string>
     */
    public $class_transforms = [];
    /**
     * @var bool
     */
    public $allow_backwards_incompatible_changes = \true;
    /** @var int */
    public $analysis_php_version_id = PHP_VERSION_ID;
    /** @var 'cli'|'config'|'composer'|'tests'|'runtime' */
    public $php_version_source = 'runtime';
    /**
     * @var bool
     */
    public $track_unused_suppressions = \false;
    /** @internal */
    public function __construct(\Psalm\Config $config, Providers $providers, ?Progress $progress = null)
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $this->config = $config;
        $this->file_storage_provider = $providers->file_storage_provider;
        $this->classlike_storage_provider = $providers->classlike_storage_provider;
        $this->progress = $progress;
        $this->file_provider = $providers->file_provider;
        $this->file_reference_provider = $providers->file_reference_provider;
        $this->statements_provider = $providers->statements_provider;
        self::$stubbed_constants = [];
        $reflection = new Reflection($providers->classlike_storage_provider, $this);
        $this->scanner = new Scanner($this, $config, $providers->file_storage_provider, $providers->file_provider, $reflection, $providers->file_reference_provider, $progress);
        $this->loadAnalyzer();
        $this->functions = new Functions($providers->file_storage_provider, $reflection);
        $this->classlikes = new ClassLikes($this->config, $providers->classlike_storage_provider, $providers->file_reference_provider, $providers->statements_provider, $this->scanner);
        $this->properties = new Properties($providers->classlike_storage_provider, $providers->file_reference_provider, $this->classlikes);
        $this->methods = new Methods($providers->classlike_storage_provider, $providers->file_reference_provider, $this->classlikes);
        $this->populator = new Populator($providers->classlike_storage_provider, $providers->file_storage_provider, $this->classlikes, $providers->file_reference_provider, $progress);
        $this->loadAnalyzer();
    }
    private function loadAnalyzer() : void
    {
        $this->analyzer = new Analyzer($this->config, $this->file_provider, $this->file_storage_provider, $this->progress);
    }
    /**
     * @param array<string> $candidate_files
     */
    public function reloadFiles(ProjectAnalyzer $project_analyzer, array $candidate_files) : void
    {
        $this->loadAnalyzer();
        $this->file_reference_provider->loadReferenceCache(\false);
        FunctionLikeAnalyzer::clearCache();
        if (!$this->statements_provider->parser_cache_provider) {
            $diff_files = $candidate_files;
        } else {
            $diff_files = [];
            $parser_cache_provider = $this->statements_provider->parser_cache_provider;
            foreach ($candidate_files as $candidate_file_path) {
                if ($parser_cache_provider->loadExistingFileContentsFromCache($candidate_file_path) !== $this->file_provider->getContents($candidate_file_path)) {
                    $diff_files[] = $candidate_file_path;
                }
            }
        }
        $referenced_files = $project_analyzer->getReferencedFilesFromDiff($diff_files, \false);
        foreach ($diff_files as $diff_file_path) {
            $this->invalidateInformationForFile($diff_file_path);
        }
        foreach ($referenced_files as $referenced_file_path) {
            if (in_array($referenced_file_path, $diff_files, \true)) {
                continue;
            }
            $file_storage = $this->file_storage_provider->get($referenced_file_path);
            foreach ($file_storage->classlikes_in_file as $fq_classlike_name) {
                $this->classlike_storage_provider->remove($fq_classlike_name);
                $this->classlikes->removeClassLike($fq_classlike_name);
            }
            $this->file_storage_provider->remove($referenced_file_path);
            $this->scanner->removeFile($referenced_file_path);
        }
        $referenced_files = array_combine($referenced_files, $referenced_files);
        $this->scanner->addFilesToDeepScan($referenced_files);
        $this->addFilesToAnalyze(array_combine($candidate_files, $candidate_files));
        $this->scanner->scanFiles($this->classlikes);
        $this->file_reference_provider->updateReferenceCache($this, $referenced_files);
        $this->populator->populateCodebase();
    }
    public function enterServerMode() : void
    {
        $this->server_mode = \true;
        $this->store_node_types = \true;
    }
    public function collectLocations() : void
    {
        $this->collect_locations = \true;
        $this->classlikes->collect_locations = \true;
        $this->methods->collect_locations = \true;
        $this->properties->collect_locations = \true;
    }
    /**
     * @param 'always'|'auto' $find_unused_code
     */
    public function reportUnusedCode(string $find_unused_code = 'auto') : void
    {
        $this->collect_references = \true;
        $this->classlikes->collect_references = \true;
        $this->find_unused_code = $find_unused_code;
        $this->find_unused_variables = \true;
    }
    public function reportUnusedVariables() : void
    {
        $this->collect_references = \true;
        $this->find_unused_variables = \true;
    }
    /**
     * @param array<string, string> $files_to_analyze
     */
    public function addFilesToAnalyze(array $files_to_analyze) : void
    {
        $this->scanner->addFilesToDeepScan($files_to_analyze);
        $this->analyzer->addFilesToAnalyze($files_to_analyze);
    }
    /**
     * Scans all files their related files
     */
    public function scanFiles(int $threads = 1) : void
    {
        $has_changes = $this->scanner->scanFiles($this->classlikes, $threads);
        if ($has_changes) {
            $this->populator->populateCodebase();
        }
    }
    /** @psalm-mutation-free */
    public function getFileContents(string $file_path) : string
    {
        return $this->file_provider->getContents($file_path);
    }
    /**
     * @return list<PhpParser\Node\Stmt>
     */
    public function getStatementsForFile(string $file_path) : array
    {
        return $this->statements_provider->getStatementsForFile($file_path, $this->analysis_php_version_id, $this->progress);
    }
    public function createClassLikeStorage(string $fq_classlike_name) : ClassLikeStorage
    {
        return $this->classlike_storage_provider->create($fq_classlike_name);
    }
    public function cacheClassLikeStorage(ClassLikeStorage $classlike_storage, string $file_path) : void
    {
        $file_contents = $this->file_provider->getContents($file_path);
        if ($this->classlike_storage_provider->cache) {
            $this->classlike_storage_provider->cache->writeToCache($classlike_storage, $file_path, $file_contents);
        }
    }
    public function exhumeClassLikeStorage(string $fq_classlike_name, string $file_path) : void
    {
        $file_contents = $this->file_provider->getContents($file_path);
        $storage = $this->classlike_storage_provider->exhume($fq_classlike_name, $file_path, $file_contents);
        if ($storage->is_trait) {
            $this->classlikes->addFullyQualifiedTraitName($storage->name, $file_path);
        } elseif ($storage->is_interface) {
            $this->classlikes->addFullyQualifiedInterfaceName($storage->name, $file_path);
        } else {
            $this->classlikes->addFullyQualifiedClassName($storage->name, $file_path);
        }
    }
    public static function getPsalmTypeFromReflection(?ReflectionType $type) : Union
    {
        return Reflection::getPsalmTypeFromReflectionType($type);
    }
    public function createFileStorageForPath(string $file_path) : FileStorage
    {
        return $this->file_storage_provider->create($file_path);
    }
    /**
     * @return array<int, CodeLocation>
     */
    public function findReferencesToSymbol(string $symbol) : array
    {
        if (!$this->collect_locations) {
            throw new UnexpectedValueException('Should not be checking references');
        }
        if (strpos($symbol, '::$') !== \false) {
            return $this->findReferencesToProperty($symbol);
        }
        if (strpos($symbol, '::') !== \false) {
            return $this->findReferencesToMethod($symbol);
        }
        return $this->findReferencesToClassLike($symbol);
    }
    /**
     * @return array<int, CodeLocation>
     */
    public function findReferencesToMethod(string $method_id) : array
    {
        return $this->file_reference_provider->getClassMethodLocations(strtolower($method_id));
    }
    /**
     * @return array<int, CodeLocation>
     */
    public function findReferencesToProperty(string $property_id) : array
    {
        [$fq_class_name, $property_name] = explode('::', $property_id);
        return $this->file_reference_provider->getClassPropertyLocations(strtolower($fq_class_name) . '::' . $property_name);
    }
    /**
     * @return CodeLocation[]
     * @psalm-return array<int, CodeLocation>
     */
    public function findReferencesToClassLike(string $fq_class_name) : array
    {
        $fq_class_name_lc = strtolower($fq_class_name);
        $locations = $this->file_reference_provider->getClassLocations($fq_class_name_lc);
        if (isset($this->use_referencing_locations[$fq_class_name_lc])) {
            $locations = [...$locations, ...$this->use_referencing_locations[$fq_class_name_lc]];
        }
        return $locations;
    }
    public function getClosureStorage(string $file_path, string $closure_id) : FunctionStorage
    {
        $file_storage = $this->file_storage_provider->get($file_path);
        // closures can be returned here
        if (isset($file_storage->functions[$closure_id])) {
            return $file_storage->functions[$closure_id];
        }
        throw new UnexpectedValueException('Expecting ' . $closure_id . ' to have storage in ' . $file_path);
    }
    public function addGlobalConstantType(string $const_id, Union $type) : void
    {
        self::$stubbed_constants[$const_id] = $type;
    }
    public function getStubbedConstantType(string $const_id) : ?Union
    {
        return self::$stubbed_constants[$const_id] ?? null;
    }
    /**
     * @return array<string, Union>
     */
    public function getAllStubbedConstants() : array
    {
        return self::$stubbed_constants;
    }
    public function fileExists(string $file_path) : bool
    {
        return $this->file_provider->fileExists($file_path);
    }
    /**
     * Check whether a class/interface exists
     */
    public function classOrInterfaceExists(string $fq_class_name, ?\Psalm\CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        return $this->classlikes->classOrInterfaceExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    /**
     * Check whether a class/interface exists
     */
    public function classOrInterfaceOrEnumExists(string $fq_class_name, ?\Psalm\CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        return $this->classlikes->classOrInterfaceOrEnumExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    public function classExtendsOrImplements(string $fq_class_name, string $possible_parent) : bool
    {
        return $this->classlikes->classExtends($fq_class_name, $possible_parent) || $this->classlikes->classImplements($fq_class_name, $possible_parent);
    }
    /**
     * Determine whether or not a given class exists
     */
    public function classExists(string $fq_class_name, ?\Psalm\CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        return $this->classlikes->classExists($fq_class_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    /**
     * Determine whether or not a class extends a parent
     *
     * @throws UnpopulatedClasslikeException when called on unpopulated class
     * @throws InvalidArgumentException when class does not exist
     */
    public function classExtends(string $fq_class_name, string $possible_parent) : bool
    {
        return $this->classlikes->classExtends($fq_class_name, $possible_parent, \true);
    }
    /**
     * Check whether a class implements an interface
     */
    public function classImplements(string $fq_class_name, string $interface) : bool
    {
        return $this->classlikes->classImplements($fq_class_name, $interface);
    }
    public function interfaceExists(string $fq_interface_name, ?\Psalm\CodeLocation $code_location = null, ?string $calling_fq_class_name = null, ?string $calling_method_id = null) : bool
    {
        return $this->classlikes->interfaceExists($fq_interface_name, $code_location, $calling_fq_class_name, $calling_method_id);
    }
    public function interfaceExtends(string $interface_name, string $possible_parent) : bool
    {
        return $this->classlikes->interfaceExtends($interface_name, $possible_parent);
    }
    /**
     * @return array<string, string> all interfaces extended by $interface_name
     */
    public function getParentInterfaces(string $fq_interface_name) : array
    {
        return $this->classlikes->getParentInterfaces($this->classlikes->getUnAliasedName($fq_interface_name));
    }
    /**
     * Determine whether or not a class has the correct casing
     */
    public function classHasCorrectCasing(string $fq_class_name) : bool
    {
        return $this->classlikes->classHasCorrectCasing($fq_class_name);
    }
    public function interfaceHasCorrectCasing(string $fq_interface_name) : bool
    {
        return $this->classlikes->interfaceHasCorrectCasing($fq_interface_name);
    }
    public function traitHasCorrectCasing(string $fq_trait_name) : bool
    {
        return $this->classlikes->traitHasCorrectCasing($fq_trait_name);
    }
    /**
     * Given a function id, return the function like storage for
     * a method, closure, or function.
     *
     * @param non-empty-string $function_id
     * @return FunctionStorage|MethodStorage
     */
    public function getFunctionLikeStorage(StatementsAnalyzer $statements_analyzer, string $function_id) : FunctionLikeStorage
    {
        $doesMethodExist = MethodIdentifier::isValidMethodIdReference($function_id) && $this->methodExists($function_id);
        if ($doesMethodExist) {
            $method_id = MethodIdentifier::wrap($function_id);
            $declaring_method_id = $this->methods->getDeclaringMethodId($method_id);
            if (!$declaring_method_id) {
                throw new UnexpectedValueException('Declaring method for ' . $method_id . ' cannot be found');
            }
            return $this->methods->getStorage($declaring_method_id);
        }
        return $this->functions->getStorage($statements_analyzer, strtolower($function_id));
    }
    /**
     * Whether or not a given method exists
     *
     * @param  string|MethodIdentifier      $method_id
     * @param  string|MethodIdentifier|null $calling_method_id
     */
    public function methodExists($method_id, ?\Psalm\CodeLocation $code_location = null, $calling_method_id = null, ?string $file_path = null, bool $is_used = \true) : bool
    {
        return $this->methods->methodExists(MethodIdentifier::wrap($method_id), is_string($calling_method_id) ? strtolower($calling_method_id) : strtolower((string) $calling_method_id), $code_location, null, $file_path, \true, $is_used);
    }
    /**
     * @param  string|MethodIdentifier $method_id
     * @return array<int, FunctionLikeParameter>
     */
    public function getMethodParams($method_id) : array
    {
        return $this->methods->getMethodParams(MethodIdentifier::wrap($method_id));
    }
    /**
     * @param  string|MethodIdentifier $method_id
     */
    public function isVariadic($method_id) : bool
    {
        return $this->methods->isVariadic(MethodIdentifier::wrap($method_id));
    }
    /**
     * @param  string|MethodIdentifier $method_id
     * @param  list<Arg> $call_args
     */
    public function getMethodReturnType($method_id, ?string &$self_class, array $call_args = []) : ?Union
    {
        return $this->methods->getMethodReturnType(MethodIdentifier::wrap($method_id), $self_class, null, $call_args);
    }
    /**
     * @param  string|MethodIdentifier $method_id
     */
    public function getMethodReturnsByRef($method_id) : bool
    {
        return $this->methods->getMethodReturnsByRef(MethodIdentifier::wrap($method_id));
    }
    /**
     * @param  string|MethodIdentifier $method_id
     */
    public function getMethodReturnTypeLocation($method_id, \Psalm\CodeLocation &$defined_location = null) : ?\Psalm\CodeLocation
    {
        return $this->methods->getMethodReturnTypeLocation(MethodIdentifier::wrap($method_id), $defined_location);
    }
    /**
     * @param  string|MethodIdentifier $method_id
     */
    public function getDeclaringMethodId($method_id) : ?string
    {
        $new_method_id = $this->methods->getDeclaringMethodId(MethodIdentifier::wrap($method_id));
        return $new_method_id ? (string) $new_method_id : null;
    }
    /**
     * Get the class this method appears in (vs is declared in, which could give a trait)
     *
     * @param  string|MethodIdentifier $method_id
     */
    public function getAppearingMethodId($method_id) : ?string
    {
        $new_method_id = $this->methods->getAppearingMethodId(MethodIdentifier::wrap($method_id));
        return $new_method_id ? (string) $new_method_id : null;
    }
    /**
     * @param  string|MethodIdentifier $method_id
     * @return array<string, MethodIdentifier>
     */
    public function getOverriddenMethodIds($method_id) : array
    {
        return $this->methods->getOverriddenMethodIds(MethodIdentifier::wrap($method_id));
    }
    /**
     * @param  string|MethodIdentifier $method_id
     */
    public function getCasedMethodId($method_id) : string
    {
        return $this->methods->getCasedMethodId(MethodIdentifier::wrap($method_id));
    }
    public function invalidateInformationForFile(string $file_path) : void
    {
        $this->scanner->removeFile($file_path);
        try {
            $file_storage = $this->file_storage_provider->get($file_path);
        } catch (InvalidArgumentException $e) {
            return;
        }
        foreach ($file_storage->classlikes_in_file as $fq_classlike_name) {
            $this->classlike_storage_provider->remove($fq_classlike_name);
            $this->classlikes->removeClassLike($fq_classlike_name);
        }
        $this->file_storage_provider->remove($file_path);
    }
    public function getFunctionStorageForSymbol(string $file_path, string $symbol) : ?FunctionLikeStorage
    {
        if (strpos($symbol, '::')) {
            $symbol = substr($symbol, 0, -2);
            /** @psalm-suppress ArgumentTypeCoercion */
            $method_id = new MethodIdentifier(...explode('::', $symbol));
            $declaring_method_id = $this->methods->getDeclaringMethodId($method_id);
            if (!$declaring_method_id) {
                return null;
            }
            return $this->methods->getStorage($declaring_method_id);
        }
        $function_id = strtolower(substr($symbol, 0, -2));
        $file_storage = $this->file_storage_provider->get($file_path);
        if (isset($file_storage->functions[$function_id])) {
            return $file_storage->functions[$function_id];
        }
        if (!$function_id) {
            return null;
        }
        return $this->functions->getStorage(null, $function_id);
    }
    /**
     * @return array{ type: string, description?: string|null}|null
     */
    public function getSymbolInformation(string $file_path, string $symbol) : ?array
    {
        if (is_numeric($symbol[0])) {
            return ['type' => preg_replace('/^[^:]*:/', '', $symbol)];
        }
        try {
            if (strpos($symbol, '::')) {
                if (strpos($symbol, '()')) {
                    $symbol = substr($symbol, 0, -2);
                    /** @psalm-suppress ArgumentTypeCoercion */
                    $method_id = new MethodIdentifier(...explode('::', $symbol));
                    $declaring_method_id = $this->methods->getDeclaringMethodId($method_id);
                    if (!$declaring_method_id) {
                        return null;
                    }
                    $storage = $this->methods->getStorage($declaring_method_id);
                    return ['type' => '<?php ' . $storage->getSignature(\true), 'description' => $storage->description];
                }
                [, $symbol_name] = explode('::', $symbol);
                if (strpos($symbol, '$') !== \false) {
                    $storage = $this->properties->getStorage($symbol);
                    return ['type' => '<?php ' . $storage->getInfo() . ' ' . $symbol_name, 'description' => $storage->description];
                }
                [$fq_classlike_name, $const_name] = explode('::', $symbol);
                $class_constants = $this->classlikes->getConstantsForClass($fq_classlike_name, ReflectionProperty::IS_PRIVATE);
                if (!isset($class_constants[$const_name])) {
                    return null;
                }
                return ['type' => '<?php ' . $const_name, 'description' => $class_constants[$const_name]->description];
            }
            if (strpos($symbol, '()')) {
                $function_id = strtolower(substr($symbol, 0, -2));
                $file_storage = $this->file_storage_provider->get($file_path);
                if (isset($file_storage->functions[$function_id])) {
                    $function_storage = $file_storage->functions[$function_id];
                    return ['type' => '<?php ' . $function_storage->getSignature(\true), 'description' => $function_storage->description];
                }
                if (!$function_id) {
                    return null;
                }
                $function = $this->functions->getStorage(null, $function_id);
                return ['type' => '<?php ' . $function->getSignature(\true), 'description' => $function->description];
            }
            if (strpos($symbol, '$') === 0) {
                $type = VariableFetchAnalyzer::getGlobalType($symbol, $this->analysis_php_version_id);
                if (!$type->isMixed()) {
                    return ['type' => '<?php ' . $type];
                }
            }
            try {
                $storage = $this->classlike_storage_provider->get($symbol);
                return ['type' => '<?php ' . ($storage->abstract ? 'abstract ' : '') . 'class ' . $storage->name, 'description' => $storage->description];
            } catch (InvalidArgumentException $e) {
            }
            if (strpos($symbol, '\\')) {
                $const_name_parts = explode('\\', $symbol);
                $const_name = array_pop($const_name_parts);
                $namespace_name = implode('\\', $const_name_parts);
                $namespace_constants = NamespaceAnalyzer::getConstantsForNamespace($namespace_name, ReflectionProperty::IS_PUBLIC);
                if (isset($namespace_constants[$const_name])) {
                    $type = $namespace_constants[$const_name];
                    return ['type' => '<?php const ' . $symbol . ' ' . $type];
                }
            } else {
                $file_storage = $this->file_storage_provider->get($file_path);
                if (isset($file_storage->constants[$symbol])) {
                    return ['type' => '<?php const ' . $symbol . ' ' . $file_storage->constants[$symbol]];
                }
                $constant = ConstFetchAnalyzer::getGlobalConstType($this, $symbol, $symbol);
                if ($constant) {
                    return ['type' => '<?php const ' . $symbol . ' ' . $constant];
                }
            }
            return null;
        } catch (Exception $e) {
            error_log($e->getMessage());
            return null;
        }
    }
    public function getSymbolLocation(string $file_path, string $symbol) : ?\Psalm\CodeLocation
    {
        if (is_numeric($symbol[0])) {
            $symbol = preg_replace('/:.*/', '', $symbol);
            $symbol_parts = explode('-', $symbol);
            $file_contents = $this->getFileContents($file_path);
            return new Raw($file_contents, $file_path, $this->config->shortenFileName($file_path), (int) $symbol_parts[0], (int) $symbol_parts[1]);
        }
        try {
            if (strpos($symbol, '::')) {
                if (strpos($symbol, '()')) {
                    $symbol = substr($symbol, 0, -2);
                    /** @psalm-suppress ArgumentTypeCoercion */
                    $method_id = new MethodIdentifier(...explode('::', $symbol));
                    $declaring_method_id = $this->methods->getDeclaringMethodId($method_id);
                    if (!$declaring_method_id) {
                        return null;
                    }
                    $storage = $this->methods->getStorage($declaring_method_id);
                    return $storage->location;
                }
                if (strpos($symbol, '$') !== \false) {
                    $storage = $this->properties->getStorage($symbol);
                    return $storage->location;
                }
                [$fq_classlike_name, $const_name] = explode('::', $symbol);
                $class_constants = $this->classlikes->getConstantsForClass($fq_classlike_name, ReflectionProperty::IS_PRIVATE);
                if (!isset($class_constants[$const_name])) {
                    return null;
                }
                return $class_constants[$const_name]->location;
            }
            if (strpos($symbol, '()')) {
                $file_storage = $this->file_storage_provider->get($file_path);
                $function_id = strtolower(substr($symbol, 0, -2));
                if (isset($file_storage->functions[$function_id])) {
                    return $file_storage->functions[$function_id]->location;
                }
                if (!$function_id) {
                    return null;
                }
                return $this->functions->getStorage(null, $function_id)->location;
            }
            return $this->classlike_storage_provider->get($symbol)->location;
        } catch (UnexpectedValueException $e) {
            error_log($e->getMessage());
            return null;
        } catch (InvalidArgumentException $e) {
            return null;
        }
    }
    /**
     * @return array{0: string, 1: Range}|null
     */
    public function getReferenceAtPosition(string $file_path, Position $position) : ?array
    {
        $is_open = $this->file_provider->isOpen($file_path);
        if (!$is_open) {
            throw new UnanalyzedFileException($file_path . ' is not open');
        }
        $file_contents = $this->getFileContents($file_path);
        $offset = $position->toOffset($file_contents);
        [$reference_map, $type_map] = $this->analyzer->getMapsForFile($file_path);
        $reference = null;
        if (!$reference_map && !$type_map) {
            return null;
        }
        $reference_start_pos = null;
        $reference_end_pos = null;
        ksort($reference_map);
        foreach ($reference_map as $start_pos => [$end_pos, $possible_reference]) {
            if ($offset < $start_pos) {
                break;
            }
            if ($offset > $end_pos) {
                continue;
            }
            $reference_start_pos = $start_pos;
            $reference_end_pos = $end_pos;
            $reference = $possible_reference;
        }
        if ($reference === null || $reference_start_pos === null || $reference_end_pos === null) {
            return null;
        }
        $range = new Range(self::getPositionFromOffset($reference_start_pos, $file_contents), self::getPositionFromOffset($reference_end_pos, $file_contents));
        return [$reference, $range];
    }
    /**
     * @return array{0: non-empty-string, 1: int, 2: Range}|null
     */
    public function getFunctionArgumentAtPosition(string $file_path, Position $position) : ?array
    {
        $is_open = $this->file_provider->isOpen($file_path);
        if (!$is_open) {
            throw new UnanalyzedFileException($file_path . ' is not open');
        }
        $file_contents = $this->getFileContents($file_path);
        $offset = $position->toOffset($file_contents);
        [, , $argument_map] = $this->analyzer->getMapsForFile($file_path);
        $reference = null;
        $argument_number = null;
        if (!$argument_map) {
            return null;
        }
        $start_pos = null;
        $end_pos = null;
        ksort($argument_map);
        foreach ($argument_map as $start_pos => [$end_pos, $possible_reference, $possible_argument_number]) {
            if ($offset < $start_pos) {
                break;
            }
            if ($offset > $end_pos) {
                continue;
            }
            $reference = $possible_reference;
            $argument_number = $possible_argument_number;
        }
        if ($reference === null || $start_pos === null || $end_pos === null || $argument_number === null) {
            return null;
        }
        $range = new Range(self::getPositionFromOffset($start_pos, $file_contents), self::getPositionFromOffset($end_pos, $file_contents));
        return [$reference, $argument_number, $range];
    }
    /**
     * @param  non-empty-string $function_symbol
     */
    public function getSignatureInformation(string $function_symbol, string $file_path = null) : ?SignatureInformation
    {
        $signature_label = '';
        $signature_documentation = null;
        if (strpos($function_symbol, '::') !== \false) {
            /** @psalm-suppress ArgumentTypeCoercion */
            $method_id = new MethodIdentifier(...explode('::', $function_symbol));
            $declaring_method_id = $this->methods->getDeclaringMethodId($method_id);
            if ($declaring_method_id === null) {
                return null;
            }
            $method_storage = $this->methods->getStorage($declaring_method_id);
            $params = $method_storage->params;
            $signature_label = $method_storage->cased_name;
            $signature_documentation = $method_storage->description;
        } else {
            try {
                if ($file_path) {
                    $function_storage = $this->functions->getStorage(null, strtolower($function_symbol), dirname($file_path), $file_path);
                } else {
                    $function_storage = $this->functions->getStorage(null, strtolower($function_symbol));
                }
                $params = $function_storage->params;
                $signature_label = $function_storage->cased_name;
                $signature_documentation = $function_storage->description;
            } catch (Exception $exception) {
                if (InternalCallMapHandler::inCallMap($function_symbol)) {
                    $callables = InternalCallMapHandler::getCallablesFromCallMap($function_symbol);
                    if (!$callables || !$callables[0]->params) {
                        return null;
                    }
                    $params = $callables[0]->params;
                } else {
                    return null;
                }
            }
        }
        $signature_label .= '(';
        $parameters = [];
        foreach ($params as $i => $param) {
            $parameter_label = ($param->type ?: 'mixed') . ' $' . $param->name;
            $parameters[] = new ParameterInformation([strlen($signature_label), strlen($signature_label) + strlen($parameter_label)], $param->description ?? null);
            $signature_label .= $parameter_label;
            if ($i < count($params) - 1) {
                $signature_label .= ', ';
            }
        }
        $signature_label .= ')';
        return new SignatureInformation($signature_label, $parameters, $signature_documentation);
    }
    /**
     * @return array{0: string, 1: '->'|'::'|'['|'symbol', 2: int}|null
     */
    public function getCompletionDataAtPosition(string $file_path, Position $position) : ?array
    {
        $is_open = $this->file_provider->isOpen($file_path);
        if (!$is_open) {
            throw new UnanalyzedFileException($file_path . ' is not open');
        }
        $file_contents = $this->getFileContents($file_path);
        $offset = $position->toOffset($file_contents);
        [$reference_map, $type_map] = $this->analyzer->getMapsForFile($file_path);
        if (!$reference_map && !$type_map) {
            return null;
        }
        krsort($type_map);
        foreach ($type_map as $start_pos => [$end_pos_excluding_whitespace, $possible_type]) {
            if ($offset < $start_pos) {
                continue;
            }
            $num_whitespace_bytes = preg_match('/\\G\\s+/', $file_contents, $matches, 0, $end_pos_excluding_whitespace) ? strlen($matches[0]) : 0;
            $end_pos = $end_pos_excluding_whitespace + $num_whitespace_bytes;
            if ($offset - $end_pos === 1) {
                $candidate_gap = substr($file_contents, $end_pos, 1);
                if ($candidate_gap === '[') {
                    $gap = $candidate_gap;
                    $recent_type = $possible_type;
                    if ($recent_type === 'mixed') {
                        return null;
                    }
                    return [$recent_type, $gap, $offset];
                }
            }
            if ($offset - $end_pos === 2 || $offset - $end_pos === 3) {
                $candidate_gap = substr($file_contents, $end_pos, 2);
                if ($candidate_gap === '->' || $candidate_gap === '::') {
                    $gap = $candidate_gap;
                    $recent_type = $possible_type;
                    if ($recent_type === 'mixed') {
                        return null;
                    }
                    return [$recent_type, $gap, $offset];
                }
            }
        }
        foreach ($reference_map as $start_pos => [$end_pos, $possible_reference]) {
            if ($offset < $start_pos) {
                continue;
            }
            // If the reference precedes a "::" then treat it as a class reference.
            if ($offset - $end_pos === 2 && substr($file_contents, $end_pos, 2) === '::') {
                return [$possible_reference, '::', $offset];
            }
            // Only continue for references that are partial / don't exist.
            if ($possible_reference[0] !== '*') {
                continue;
            }
            if ($offset - $end_pos === 0) {
                $recent_type = $possible_reference;
                return [$recent_type, 'symbol', $offset];
            }
        }
        return null;
    }
    public function getTypeContextAtPosition(string $file_path, Position $position) : ?Union
    {
        $file_contents = $this->getFileContents($file_path);
        $offset = $position->toOffset($file_contents);
        [$reference_map, $type_map, $argument_map] = $this->analyzer->getMapsForFile($file_path);
        if (!$reference_map && !$type_map && !$argument_map) {
            return null;
        }
        foreach ($argument_map as $start_pos => [$end_pos, $function, $argument_num]) {
            if ($offset < $start_pos || $offset > $end_pos) {
                continue;
            }
            // First parameter to a function-like
            $function_storage = $this->getFunctionStorageForSymbol($file_path, $function . '()');
            if (!$function_storage || !$function_storage->params || !isset($function_storage->params[$argument_num])) {
                return null;
            }
            return $function_storage->params[$argument_num]->type;
        }
        return null;
    }
    /**
     * @return list<CompletionItem>
     */
    public function getCompletionItemsForClassishThing(string $type_string, string $gap) : array
    {
        $completion_items = [];
        $type = \Psalm\Type::parseString($type_string);
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TNamedObject) {
                try {
                    $class_storage = $this->classlike_storage_provider->get($atomic_type->value);
                    foreach ($class_storage->appearing_method_ids as $declaring_method_id) {
                        $method_storage = $this->methods->getStorage($declaring_method_id);
                        if ($method_storage->is_static || $gap === '->') {
                            $completion_item = new CompletionItem($method_storage->cased_name, CompletionItemKind::METHOD, (string) $method_storage, $method_storage->description, (string) $method_storage->visibility, $method_storage->cased_name, $method_storage->cased_name . (count($method_storage->params) !== 0 ? '($0)' : '()'), null, null, new Command('Trigger parameter hints', 'editor.action.triggerParameterHints'), null, 2);
                            $completion_item->insertTextFormat = InsertTextFormat::SNIPPET;
                            $completion_items[] = $completion_item;
                        }
                    }
                    foreach ($class_storage->declaring_property_ids as $property_name => $declaring_class) {
                        $property_storage = $this->properties->getStorage($declaring_class . '::$' . $property_name);
                        if ($property_storage->is_static || $gap === '->') {
                            $completion_items[] = new CompletionItem('$' . $property_name, CompletionItemKind::PROPERTY, $property_storage->getInfo(), $property_storage->description, (string) $property_storage->visibility, $property_name, ($gap === '::' ? '$' : '') . $property_name);
                        }
                    }
                    foreach ($class_storage->constants as $const_name => $const) {
                        $completion_items[] = new CompletionItem($const_name, CompletionItemKind::VARIABLE, 'const ' . $const_name, $const->description, null, $const_name, $const_name);
                    }
                } catch (Exception $e) {
                    error_log($e->getMessage());
                    continue;
                }
            }
        }
        return $completion_items;
    }
    /**
     * @return list<CompletionItem>
     */
    public function getCompletionItemsForPartialSymbol(string $type_string, int $offset, string $file_path) : array
    {
        $fq_suggestion = \false;
        if (($type_string[1] ?? '') === '\\') {
            $fq_suggestion = \true;
        }
        $matching_classlike_names = $this->classlikes->getMatchingClassLikeNames($type_string);
        $completion_items = [];
        $file_storage = $this->file_storage_provider->get($file_path);
        $aliases = null;
        foreach ($file_storage->classlikes_in_file as $fq_class_name => $_) {
            try {
                $class_storage = $this->classlike_storage_provider->get($fq_class_name);
            } catch (Exception $e) {
                continue;
            }
            if (!$class_storage->stmt_location) {
                continue;
            }
            if ($offset > $class_storage->stmt_location->raw_file_start && $offset < $class_storage->stmt_location->raw_file_end) {
                $aliases = $class_storage->aliases;
                break;
            }
        }
        if (!$aliases) {
            foreach ($file_storage->namespace_aliases as $namespace_start => $namespace_aliases) {
                if ($namespace_start < $offset) {
                    $aliases = $namespace_aliases;
                    break;
                }
            }
            if (!$aliases) {
                $aliases = $file_storage->aliases;
            }
        }
        foreach ($matching_classlike_names as $fq_class_name) {
            $extra_edits = [];
            $insertion_text = \Psalm\Type::getStringFromFQCLN($fq_class_name, $aliases && $aliases->namespace ? $aliases->namespace : null, $aliases->uses_flipped ?? [], null);
            if ($aliases && !$fq_suggestion && $aliases->namespace && $insertion_text === '\\' . $fq_class_name && $aliases->namespace_first_stmt_start) {
                $file_contents = $this->getFileContents($file_path);
                $class_name = preg_replace('/^.*\\\\/', '', $fq_class_name, 1);
                if ($aliases->uses_end) {
                    $position = self::getPositionFromOffset($aliases->uses_end, $file_contents);
                    $extra_edits[] = new TextEdit(new Range($position, $position), "\n" . 'use ' . $fq_class_name . ';');
                } else {
                    $position = self::getPositionFromOffset($aliases->namespace_first_stmt_start, $file_contents);
                    $extra_edits[] = new TextEdit(new Range($position, $position), 'use ' . $fq_class_name . ';' . "\n" . "\n");
                }
                $insertion_text = $class_name;
            }
            try {
                $class_storage = $this->classlike_storage_provider->get($fq_class_name);
                $description = $class_storage->description;
            } catch (Exception $e) {
                $description = null;
            }
            $completion_items[] = new CompletionItem($fq_class_name, CompletionItemKind::CLASS_, null, $description, null, $fq_class_name, $insertion_text, null, $extra_edits);
        }
        $functions = $this->functions->getMatchingFunctionNames($type_string, $offset, $file_path, $this);
        $namespace_map = [];
        if ($aliases) {
            $namespace_map += $aliases->uses_flipped;
            if ($aliases->namespace) {
                $namespace_map[$aliases->namespace] = '';
            }
        }
        // Sort the map by longest first, so we replace most specific
        // used namespaces first.
        ksort($namespace_map);
        $namespace_map = array_reverse($namespace_map);
        foreach ($functions as $function_lowercase => $function) {
            // Transform FQFN relative to all uses namespaces
            $function_name = $function->cased_name;
            if (!$function_name) {
                continue;
            }
            $in_namespace_map = \false;
            foreach ($namespace_map as $namespace_name => $namespace_alias) {
                if (strpos($function_lowercase, $namespace_name . '\\') === 0) {
                    $function_name = $namespace_alias . '\\' . substr($function_name, strlen($namespace_name) + 1);
                    $in_namespace_map = \true;
                }
            }
            // If the function is not use'd, and it's not a global function
            // prepend it with a backslash.
            if (!$in_namespace_map && strpos($function_name, '\\') !== \false) {
                $function_name = '\\' . $function_name;
            }
            $completion_items[] = new CompletionItem($function_name, CompletionItemKind::FUNCTION, $function->getSignature(\false), $function->description, null, $function_name, $function_name . (count($function->params) !== 0 ? '($0)' : '()'), null, null, new Command('Trigger parameter hints', 'editor.action.triggerParameterHints'), null, 2);
        }
        return $completion_items;
    }
    /**
     * @return list<CompletionItem>
     */
    public function getCompletionItemsForType(Union $type) : array
    {
        $completion_items = [];
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TBool) {
                $bools = (string) $atomic_type === 'bool' ? ['true', 'false'] : [(string) $atomic_type];
                foreach ($bools as $property_name) {
                    $completion_items[] = new CompletionItem($property_name, CompletionItemKind::VALUE, 'bool', null, null, null, $property_name);
                }
            } elseif ($atomic_type instanceof TLiteralString) {
                $completion_items[] = new CompletionItem($atomic_type->value, CompletionItemKind::VALUE, $atomic_type->getId(), null, null, null, "'{$atomic_type->value}'");
            } elseif ($atomic_type instanceof TLiteralInt) {
                $completion_items[] = new CompletionItem((string) $atomic_type->value, CompletionItemKind::VALUE, $atomic_type->getId(), null, null, null, (string) $atomic_type->value);
            } elseif ($atomic_type instanceof TClassConstant) {
                $const = $atomic_type->fq_classlike_name . '::' . $atomic_type->const_name;
                $completion_items[] = new CompletionItem($const, CompletionItemKind::VALUE, $atomic_type->getId(), null, null, null, $const);
            }
        }
        return $completion_items;
    }
    /**
     * @return list<CompletionItem>
     */
    public function getCompletionItemsForArrayKeys(string $type_string) : array
    {
        $completion_items = [];
        $type = \Psalm\Type::parseString($type_string);
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TKeyedArray) {
                foreach ($atomic_type->properties as $property_name => $property) {
                    $completion_items[] = new CompletionItem((string) $property_name, CompletionItemKind::PROPERTY, (string) $property, null, null, null, "'{$property_name}'");
                }
            }
        }
        return $completion_items;
    }
    private static function getPositionFromOffset(int $offset, string $file_contents) : Position
    {
        $file_contents = substr($file_contents, 0, $offset);
        $offsetLength = $offset - strlen($file_contents);
        //PHP 8.0: Argument #3 ($offset) must be contained in argument #1 ($haystack)
        if (($textlen = strlen($file_contents)) < $offsetLength) {
            $offsetLength = $textlen;
        }
        $before_newline_count = strrpos($file_contents, "\n", $offsetLength);
        return new Position(substr_count($file_contents, "\n"), $offset - (int) $before_newline_count - 1);
    }
    public function addTemporaryFileChanges(string $file_path, string $new_content) : void
    {
        $this->file_provider->addTemporaryFileChanges($file_path, $new_content);
    }
    public function removeTemporaryFileChanges(string $file_path) : void
    {
        $this->file_provider->removeTemporaryFileChanges($file_path);
    }
    /**
     * Checks if type is a subtype of other
     *
     * Given two types, checks if `$input_type` is a subtype of `$container_type`.
     * If you consider `Union` as a set of types, this will tell you
     * if `$input_type` is fully contained in `$container_type`,
     *
     * $input_type ⊆ $container_type
     *
     * Useful for emitting issues like InvalidArgument, where argument at the call site
     * should be a subset of the function parameter type.
     */
    public function isTypeContainedByType(Union $input_type, Union $container_type) : bool
    {
        return UnionTypeComparator::isContainedBy($this, $input_type, $container_type);
    }
    /**
     * Checks if type has any part that is a subtype of other
     *
     * Given two types, checks if *any part* of `$input_type` is a subtype of `$container_type`.
     * If you consider `Union` as a set of types, this will tell you if intersection
     * of `$input_type` with `$container_type` is not empty.
     *
     * $input_type ∩ $container_type ≠ ∅ , e.g. they are not disjoint.
     *
     * Useful for emitting issues like PossiblyInvalidArgument, where argument at the call
     * site should be a subtype of the function parameter type, but it's has some types that are
     * not a subtype of the required type.
     */
    public function canTypeBeContainedByType(Union $input_type, Union $container_type) : bool
    {
        return UnionTypeComparator::canBeContainedBy($this, $input_type, $container_type);
    }
    /**
     * Extracts key and value types from a traversable object (or iterable)
     *
     * Given an iterable type (*but not TArray*) returns a tuple of it's key/value types.
     * First element of the tuple holds key type, second has the value type.
     *
     * Example:
     * ```php
     * $codebase->getKeyValueParamsForTraversableObject(Type::parseString('iterable<int,string>'))
     * //  returns [Union(TInt), Union(TString)]
     * ```
     *
     * @return array{Union, Union}
     */
    public function getKeyValueParamsForTraversableObject(Atomic $type) : array
    {
        $key_type = null;
        $value_type = null;
        ForeachAnalyzer::getKeyValueParamsForTraversableObject($type, $this, $key_type, $value_type);
        return [$key_type ?? \Psalm\Type::getMixed(), $value_type ?? \Psalm\Type::getMixed()];
    }
    /**
     * @param array<string, mixed> $phantom_classes
     * @psalm-suppress PossiblyUnusedMethod part of the public API
     */
    public function queueClassLikeForScanning(string $fq_classlike_name, bool $analyze_too = \false, bool $store_failure = \true, array $phantom_classes = []) : void
    {
        $this->scanner->queueClassLikeForScanning($fq_classlike_name, $analyze_too, $store_failure, $phantom_classes);
    }
    /**
     * @param array<string> $taints
     * @psalm-suppress PossiblyUnusedMethod
     */
    public function addTaintSource(Union $expr_type, string $taint_id, array $taints = TaintKindGroup::ALL_INPUT, ?\Psalm\CodeLocation $code_location = null) : Union
    {
        if (!$this->taint_flow_graph) {
            return $expr_type;
        }
        $source = new TaintSource($taint_id, $taint_id, $code_location, null, $taints);
        $this->taint_flow_graph->addSource($source);
        return $expr_type->addParentNodes([$source->id => $source]);
    }
    /**
     * @param array<string> $taints
     * @psalm-suppress PossiblyUnusedMethod
     */
    public function addTaintSink(string $taint_id, array $taints = TaintKindGroup::ALL_INPUT, ?\Psalm\CodeLocation $code_location = null) : void
    {
        if (!$this->taint_flow_graph) {
            return;
        }
        $sink = new TaintSink($taint_id, $taint_id, $code_location, null, $taints);
        $this->taint_flow_graph->addSink($sink);
    }
    public function getMinorAnalysisPhpVersion() : int
    {
        return self::transformPhpVersionId($this->analysis_php_version_id % 10000, 100);
    }
    public function getMajorAnalysisPhpVersion() : int
    {
        return self::transformPhpVersionId($this->analysis_php_version_id, 10000);
    }
    public static function transformPhpVersionId(int $php_version_id, int $div) : int
    {
        return intdiv($php_version_id, $div);
    }
}
<?php

namespace Psalm\Exception;

use Exception;
final class TypeParseTreeException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class UnsupportedIssueToFixException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class UnpreparedAnalysisException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
class ConfigException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class UnanalyzedFileException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class FileIncludeException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class CircularReferenceException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class InvalidClasslikeOverrideException extends Exception
{
}
<?php

namespace Psalm\Exception;

use LogicException;
final class UnpopulatedClasslikeException extends LogicException
{
    public function __construct(string $fq_classlike_name)
    {
        parent::__construct('Cannot check inheritance - \'' . $fq_classlike_name . '\' has not been populated yet.' . ' You may need to defer this check to a later phase.');
    }
}
<?php

namespace Psalm\Exception;

use Exception;
final class CodeException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class UnresolvableConstantException extends Exception
{
    /**
     * @var string
     */
    public $class_name;
    /**
     * @var string
     */
    public $const_name;
    public function __construct(string $class_name, string $const_name)
    {
        $this->class_name = $class_name;
        $this->const_name = $const_name;
    }
}
<?php

namespace Psalm\Exception;

use Exception;
final class ConfigCreationException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class RefactorException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
class DocblockParseException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class ComplicatedExpressionException extends Exception
{
}
<?php

namespace Psalm\Exception;

final class ConfigNotFoundException extends \Psalm\Exception\ConfigException
{
}
<?php

namespace Psalm\Exception;

final class IncorrectDocblockException extends \Psalm\Exception\DocblockParseException
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class InvalidMethodOverrideException extends Exception
{
}
<?php

namespace Psalm\Exception;

use Exception;
final class ScopeAnalysisException extends Exception
{
}
<?php

namespace Psalm;

use InvalidArgumentException;
use Psalm\Plugin\EventHandler\DynamicFunctionStorageProviderInterface;
use Psalm\Plugin\EventHandler\FunctionExistenceProviderInterface;
use Psalm\Plugin\EventHandler\FunctionParamsProviderInterface;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Plugin\EventHandler\MethodExistenceProviderInterface;
use Psalm\Plugin\EventHandler\MethodParamsProviderInterface;
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface;
use Psalm\Plugin\EventHandler\MethodVisibilityProviderInterface;
use Psalm\Plugin\EventHandler\PropertyExistenceProviderInterface;
use Psalm\Plugin\EventHandler\PropertyTypeProviderInterface;
use Psalm\Plugin\EventHandler\PropertyVisibilityProviderInterface;
use Psalm\Plugin\RegistrationInterface;
use function class_exists;
use function is_subclass_of;
final class PluginRegistrationSocket implements RegistrationInterface
{
    private \Psalm\Config $config;
    private \Psalm\Codebase $codebase;
    /**
     * @internal
     */
    public function __construct(\Psalm\Config $config, \Psalm\Codebase $codebase)
    {
        $this->config = $config;
        $this->codebase = $codebase;
    }
    public function addStubFile(string $file_name) : void
    {
        $this->config->addStubFile($file_name);
    }
    public function registerHooksFromClass(string $handler) : void
    {
        if (!class_exists($handler, \false)) {
            throw new InvalidArgumentException('Plugins must be loaded before registration');
        }
        $this->config->eventDispatcher->registerClass($handler);
        if (is_subclass_of($handler, PropertyExistenceProviderInterface::class)) {
            $this->codebase->properties->property_existence_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, PropertyVisibilityProviderInterface::class)) {
            $this->codebase->properties->property_visibility_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, PropertyTypeProviderInterface::class)) {
            $this->codebase->properties->property_type_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, MethodExistenceProviderInterface::class)) {
            $this->codebase->methods->existence_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, MethodVisibilityProviderInterface::class)) {
            $this->codebase->methods->visibility_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, MethodReturnTypeProviderInterface::class)) {
            $this->codebase->methods->return_type_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, MethodParamsProviderInterface::class)) {
            $this->codebase->methods->params_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, FunctionExistenceProviderInterface::class)) {
            $this->codebase->functions->existence_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, FunctionParamsProviderInterface::class)) {
            $this->codebase->functions->params_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, FunctionReturnTypeProviderInterface::class)) {
            $this->codebase->functions->return_type_provider->registerClass($handler);
        }
        if (is_subclass_of($handler, DynamicFunctionStorageProviderInterface::class)) {
            $this->codebase->functions->dynamic_storage_provider->registerClass($handler);
        }
    }
}
<?php

namespace Psalm;

use Psalm\Internal\Analyzer\IssueData;
use Psalm\Report\ReportOptions;
use function array_filter;
use function htmlspecialchars;
use const ENT_QUOTES;
use const ENT_XML1;
abstract class Report
{
    public const TYPE_COMPACT = 'compact';
    public const TYPE_CONSOLE = 'console';
    public const TYPE_PYLINT = 'pylint';
    public const TYPE_JSON = 'json';
    public const TYPE_JSON_SUMMARY = 'json-summary';
    public const TYPE_SONARQUBE = 'sonarqube';
    public const TYPE_EMACS = 'emacs';
    public const TYPE_XML = 'xml';
    public const TYPE_JUNIT = 'junit';
    public const TYPE_CHECKSTYLE = 'checkstyle';
    public const TYPE_TEXT = 'text';
    public const TYPE_GITHUB_ACTIONS = 'github';
    public const TYPE_PHP_STORM = 'phpstorm';
    public const TYPE_SARIF = 'sarif';
    public const TYPE_CODECLIMATE = 'codeclimate';
    public const TYPE_COUNT = 'count';
    public const TYPE_BY_ISSUE_LEVEL = 'by-issue-level';
    /**
     * @var array<int, IssueData>
     */
    protected $issues_data;
    /** @var array<string, int> */
    protected $fixable_issue_counts;
    /** @var bool */
    protected $use_color;
    /** @var bool */
    protected $show_snippet;
    /** @var bool */
    protected $show_info;
    /** @var bool */
    protected $pretty;
    /** @var bool */
    protected $in_ci;
    /** @var int */
    protected $mixed_expression_count;
    /** @var int */
    protected $total_expression_count;
    /**
     * @param array<int, IssueData> $issues_data
     * @param array<string, int> $fixable_issue_counts
     */
    public function __construct(array $issues_data, array $fixable_issue_counts, ReportOptions $report_options, int $mixed_expression_count = 1, int $total_expression_count = 1)
    {
        if (!$report_options->show_info) {
            $this->issues_data = array_filter($issues_data, static fn(IssueData $issue_data): bool => $issue_data->severity !== \Psalm\Config::REPORT_INFO);
        } else {
            $this->issues_data = $issues_data;
        }
        $this->fixable_issue_counts = $fixable_issue_counts;
        $this->use_color = $report_options->use_color;
        $this->show_snippet = $report_options->show_snippet;
        $this->show_info = $report_options->show_info;
        $this->pretty = $report_options->pretty;
        $this->in_ci = $report_options->in_ci;
        $this->mixed_expression_count = $mixed_expression_count;
        $this->total_expression_count = $total_expression_count;
    }
    protected function xmlEncode(string $data) : string
    {
        return htmlspecialchars($data, ENT_XML1 | ENT_QUOTES);
    }
    public abstract function create() : string;
}
<?php

namespace Psalm;

use Psalm\CodeLocation\Raw;
use Psalm\Exception\CodeException;
use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\ExecutionEnvironment\BuildInfoCollector;
use Psalm\Internal\ExecutionEnvironment\GitInfoCollector;
use Psalm\Internal\Provider\FileProvider;
use Psalm\Issue\CodeIssue;
use Psalm\Issue\ConfigIssue;
use Psalm\Issue\MixedIssue;
use Psalm\Issue\TaintedInput;
use Psalm\Issue\UnusedBaselineEntry;
use Psalm\Issue\UnusedPsalmSuppress;
use Psalm\Plugin\EventHandler\Event\AfterAnalysisEvent;
use Psalm\Plugin\EventHandler\Event\BeforeAddIssueEvent;
use Psalm\Report\ByIssueLevelAndTypeReport;
use Psalm\Report\CheckstyleReport;
use Psalm\Report\CodeClimateReport;
use Psalm\Report\CompactReport;
use Psalm\Report\ConsoleReport;
use Psalm\Report\CountReport;
use Psalm\Report\EmacsReport;
use Psalm\Report\GithubActionsReport;
use Psalm\Report\JsonReport;
use Psalm\Report\JsonSummaryReport;
use Psalm\Report\JunitReport;
use Psalm\Report\PhpStormReport;
use Psalm\Report\PylintReport;
use Psalm\Report\ReportOptions;
use Psalm\Report\SarifReport;
use Psalm\Report\SonarqubeReport;
use Psalm\Report\TextReport;
use Psalm\Report\XmlReport;
use RuntimeException;
use UnexpectedValueException;
use function array_keys;
use function array_merge;
use function array_pop;
use function array_search;
use function array_splice;
use function array_sum;
use function array_values;
use function arsort;
use function count;
use function debug_print_backtrace;
use function dirname;
use function explode;
use function file_put_contents;
use function fwrite;
use function get_class;
use function implode;
use function in_array;
use function is_dir;
use function is_int;
use function ksort;
use function memory_get_peak_usage;
use function microtime;
use function mkdir;
use function number_format;
use function ob_get_clean;
use function ob_start;
use function preg_match;
use function round;
use function sha1;
use function sprintf;
use function str_repeat;
use function str_replace;
use function strlen;
use function strpos;
use function trim;
use function usort;
use const DEBUG_BACKTRACE_IGNORE_ARGS;
use const PSALM_VERSION;
use const STDERR;
final class IssueBuffer
{
    /**
     * @var array<string, list<IssueData>>
     */
    protected static $issues_data = [];
    /**
     * @var array<int, array>
     */
    protected static $console_issues = [];
    /**
     * @var array<string, int>
     */
    protected static $fixable_issue_counts = [];
    /**
     * @var int
     */
    protected static $error_count = 0;
    /**
     * @var array<string, bool>
     */
    protected static $emitted = [];
    /** @var int */
    protected static $recording_level = 0;
    /** @var array<int, array<int, CodeIssue>> */
    protected static $recorded_issues = [];
    /**
     * @var array<string, array<int, int>>
     */
    protected static $unused_suppressions = [];
    /**
     * @var array<string, array<int, bool>>
     */
    protected static $used_suppressions = [];
    /** @var array<array-key,mixed> */
    private static array $server = [];
    /**
     * This will add an issue to be emitted if it's not suppressed and return if it has been added
     *
     * @param string[]  $suppressed_issues
     */
    public static function accepts(CodeIssue $e, array $suppressed_issues = [], bool $is_fixable = \false) : bool
    {
        if (self::isSuppressed($e, $suppressed_issues)) {
            return \false;
        }
        return self::add($e, $is_fixable);
    }
    /**
     * This will add an issue to be emitted if it's not suppressed
     *
     * @param string[]  $suppressed_issues
     */
    public static function maybeAdd(CodeIssue $e, array $suppressed_issues = [], bool $is_fixable = \false) : void
    {
        self::accepts($e, $suppressed_issues, $is_fixable);
    }
    /**
     * This is part of the findUnusedPsalmSuppress feature
     */
    public static function addUnusedSuppression(string $file_path, int $offset, string $issue_type) : void
    {
        if (strpos($issue_type, 'Tainted') === 0) {
            return;
        }
        if (isset(self::$used_suppressions[$file_path][$offset])) {
            return;
        }
        if (!isset(self::$unused_suppressions[$file_path])) {
            self::$unused_suppressions[$file_path] = [];
        }
        self::$unused_suppressions[$file_path][$offset] = $offset + strlen($issue_type) - 1;
    }
    /**
     * This will return false if an issue is ready to be added for emission. Reasons for not returning false include:
     * - The issue is suppressed in config
     * - We're in a recording state
     * - The issue is included in the list of issues to be suppressed in param
     *
     * @param string[] $suppressed_issues
     */
    public static function isSuppressed(CodeIssue $e, array $suppressed_issues = []) : bool
    {
        $config = \Psalm\Config::getInstance();
        $fqcn_parts = explode('\\', get_class($e));
        $issue_type = array_pop($fqcn_parts);
        $file_path = $e->getFilePath();
        if (!$e instanceof ConfigIssue && !$config->reportIssueInFile($issue_type, $file_path)) {
            return \true;
        }
        $suppressed_issue_position = array_search($issue_type, $suppressed_issues);
        if ($suppressed_issue_position !== \false) {
            if (is_int($suppressed_issue_position)) {
                self::$used_suppressions[$file_path][$suppressed_issue_position] = \true;
            }
            return \true;
        }
        $parent_issue_type = \Psalm\Config::getParentIssueType($issue_type);
        if ($parent_issue_type) {
            $suppressed_issue_position = array_search($parent_issue_type, $suppressed_issues);
            if ($suppressed_issue_position !== \false) {
                if (is_int($suppressed_issue_position)) {
                    self::$used_suppressions[$file_path][$suppressed_issue_position] = \true;
                }
                return \true;
            }
        }
        $suppress_all_position = $config->disable_suppress_all ? \false : array_search('all', $suppressed_issues);
        if ($suppress_all_position !== \false) {
            if (is_int($suppress_all_position)) {
                self::$used_suppressions[$file_path][$suppress_all_position] = \true;
            }
            return \true;
        }
        $reporting_level = $config->getReportingLevelForIssue($e);
        if ($reporting_level === \Psalm\Config::REPORT_SUPPRESS) {
            return \true;
        }
        if ($e->code_location->getLineNumber() === -1) {
            return \true;
        }
        if (self::$recording_level > 0) {
            self::$recorded_issues[self::$recording_level][] = $e;
            return \true;
        }
        return \false;
    }
    /**
     * Add an issue to be emitted. This method should normally not be used! Use IssueBuffer::maybeAdd instead.
     *
     * @psalm-internal Psalm\IssueBuffer
     * @psalm-internal Psalm\Type\Reconciler::getValueForKey
     * @throws  CodeException
     */
    public static function add(CodeIssue $e, bool $is_fixable = \false) : bool
    {
        $config = \Psalm\Config::getInstance();
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        $event = new BeforeAddIssueEvent($e, $is_fixable, $codebase);
        if ($config->eventDispatcher->dispatchBeforeAddIssue($event) === \false) {
            return \false;
        }
        $fqcn_parts = explode('\\', get_class($e));
        $issue_type = array_pop($fqcn_parts);
        if (!$project_analyzer->show_issues) {
            return \false;
        }
        $is_tainted = strpos($issue_type, 'Tainted') === 0;
        if ($codebase->taint_flow_graph && !$is_tainted) {
            return \false;
        }
        $reporting_level = $config->getReportingLevelForIssue($e);
        if ($reporting_level === \Psalm\Config::REPORT_SUPPRESS) {
            return \false;
        }
        if ($config->debug_emitted_issues) {
            ob_start();
            debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
            $trace = ob_get_clean();
            fwrite(STDERR, "\nEmitting {$e->getShortLocation()} {$issue_type} {$e->message}\n{$trace}\n");
        }
        // Make issue type for trace variable specific ("Trace" => "Trace~$var").
        $trace_var = $issue_type === 'Trace' && preg_match('/^(\\$.+?):/', $e->message, $m) === 1 && isset($m[1]) ? '~' . $m[1] : '';
        $emitted_key = $issue_type . $trace_var . '-' . $e->getShortLocation() . ':' . $e->code_location->getColumn() . ' ' . ($e->dupe_key ?? $e->message);
        if ($reporting_level === \Psalm\Config::REPORT_INFO) {
            if ($is_tainted || !self::alreadyEmitted($emitted_key)) {
                self::$issues_data[$e->getFilePath()][] = $e->toIssueData(\Psalm\Config::REPORT_INFO);
                if ($is_fixable) {
                    self::addFixableIssue($issue_type);
                }
            }
            return \false;
        }
        if ($config->throw_exception) {
            FileAnalyzer::clearCache();
            $message = $e instanceof TaintedInput ? $e->getJourneyMessage() : ($e instanceof MixedIssue ? $e->getMixedOriginMessage() : $e->message);
            throw new CodeException($issue_type . ' - ' . $e->getShortLocationWithPrevious() . ':' . $e->code_location->getColumn() . ' - ' . $message);
        }
        if ($is_tainted || !self::alreadyEmitted($emitted_key)) {
            ++self::$error_count;
            self::$issues_data[$e->getFilePath()][] = $e->toIssueData(\Psalm\Config::REPORT_ERROR);
            if ($is_fixable) {
                self::addFixableIssue($issue_type);
            }
        }
        return \true;
    }
    private static function removeRecordedIssue(string $issue_type, int $file_offset) : void
    {
        $recorded_issues = self::$recorded_issues[self::$recording_level];
        $filtered_issues = [];
        foreach ($recorded_issues as $issue) {
            [$from] = $issue->code_location->getSelectionBounds();
            if ($issue::getIssueType() !== $issue_type || $from !== $file_offset) {
                $filtered_issues[] = $issue;
            }
        }
        self::$recorded_issues[self::$recording_level] = $filtered_issues;
    }
    /**
     * This will try to remove an issue that has been added for emission
     */
    public static function remove(string $file_path, string $issue_type, int $file_offset) : void
    {
        if (self::$recording_level > 0) {
            self::removeRecordedIssue($issue_type, $file_offset);
        }
        if (!isset(self::$issues_data[$file_path])) {
            return;
        }
        $filtered_issues = [];
        foreach (self::$issues_data[$file_path] as $issue) {
            if ($issue->type !== $issue_type || $issue->from !== $file_offset) {
                $filtered_issues[] = $issue;
            }
        }
        if (empty($filtered_issues)) {
            unset(self::$issues_data[$file_path]);
        } else {
            self::$issues_data[$file_path] = $filtered_issues;
        }
    }
    public static function addFixableIssue(string $issue_type) : void
    {
        if (isset(self::$fixable_issue_counts[$issue_type])) {
            self::$fixable_issue_counts[$issue_type]++;
        } else {
            self::$fixable_issue_counts[$issue_type] = 1;
        }
    }
    /**
     * @return array<string, list<IssueData>>
     */
    public static function getIssuesData() : array
    {
        return self::$issues_data;
    }
    /**
     * @return list<IssueData>
     */
    public static function getIssuesDataForFile(string $file_path) : array
    {
        return self::$issues_data[$file_path] ?? [];
    }
    /**
     * @return array<string, int>
     */
    public static function getFixableIssues() : array
    {
        return self::$fixable_issue_counts;
    }
    /**
     * @param array<string, int> $fixable_issue_counts
     */
    public static function addFixableIssues(array $fixable_issue_counts) : void
    {
        foreach ($fixable_issue_counts as $issue_type => $count) {
            if (isset(self::$fixable_issue_counts[$issue_type])) {
                self::$fixable_issue_counts[$issue_type] += $count;
            } else {
                self::$fixable_issue_counts[$issue_type] = $count;
            }
        }
    }
    /**
     * @return array<string, array<int, int>>
     */
    public static function getUnusedSuppressions() : array
    {
        return self::$unused_suppressions;
    }
    /**
     * @return array<string, array<int, bool>>
     */
    public static function getUsedSuppressions() : array
    {
        return self::$used_suppressions;
    }
    /**
     * @param array<string, array<int, int>> $unused_suppressions
     */
    public static function addUnusedSuppressions(array $unused_suppressions) : void
    {
        self::$unused_suppressions += $unused_suppressions;
    }
    /**
     * @param array<string, array<int, bool>> $used_suppressions
     */
    public static function addUsedSuppressions(array $used_suppressions) : void
    {
        foreach ($used_suppressions as $file => $offsets) {
            if (!isset(self::$used_suppressions[$file])) {
                self::$used_suppressions[$file] = $offsets;
            } else {
                self::$used_suppressions[$file] += $offsets;
            }
        }
    }
    public static function processUnusedSuppressions(FileProvider $file_provider) : void
    {
        $config = \Psalm\Config::getInstance();
        foreach (self::$unused_suppressions as $file_path => $offsets) {
            if (!$offsets) {
                continue;
            }
            if (!$config->isInProjectDirs($file_path)) {
                continue;
            }
            $file_contents = $file_provider->getContents($file_path);
            foreach ($offsets as $start => $end) {
                if (isset(self::$used_suppressions[$file_path][$start])) {
                    continue;
                }
                self::add(new UnusedPsalmSuppress('This suppression is never used', new Raw($file_contents, $file_path, $config->shortenFileName($file_path), $start, $end)));
            }
        }
    }
    public static function getErrorCount() : int
    {
        return self::$error_count;
    }
    /**
     * @param array<string, list<IssueData>> $issues_data
     */
    public static function addIssues(array $issues_data) : void
    {
        foreach ($issues_data as $file_path => $file_issues) {
            foreach ($file_issues as $issue) {
                $emitted_key = $issue->type . '-' . $issue->file_name . ':' . $issue->line_from . ':' . $issue->column_from . ' ' . ($issue->dupe_key ?? $issue->message);
                if (!self::alreadyEmitted($emitted_key)) {
                    self::$issues_data[$file_path][] = $issue;
                }
            }
        }
    }
    /**
     * @param  array<string,array<string,array{o:int, s:array<int, string>}>>  $issue_baseline
     */
    public static function finish(ProjectAnalyzer $project_analyzer, bool $is_full, float $start_time, bool $add_stats = \false, array $issue_baseline = []) : void
    {
        if (!$project_analyzer->stdout_report_options) {
            throw new UnexpectedValueException('Cannot finish without stdout report options');
        }
        $codebase = $project_analyzer->getCodebase();
        foreach ($codebase->config->config_issues as $issue) {
            self::maybeAdd($issue);
        }
        $error_count = 0;
        $info_count = 0;
        $issues_data = [];
        if (self::$issues_data) {
            if (in_array($project_analyzer->stdout_report_options->format, [\Psalm\Report::TYPE_CONSOLE, \Psalm\Report::TYPE_PHP_STORM])) {
                echo "\n";
            }
            ksort(self::$issues_data);
            foreach (self::$issues_data as $file_path => $file_issues) {
                usort($file_issues, static fn(IssueData $d1, IssueData $d2): int => [$d1->file_path, $d1->line_from, $d1->column_from] <=> [$d2->file_path, $d2->line_from, $d2->column_from]);
                self::$issues_data[$file_path] = $file_issues;
            }
            // make a copy so what gets saved in cache is unaffected by baseline
            $issues_data = self::$issues_data;
            if (!empty($issue_baseline)) {
                // Set severity for issues in baseline to INFO
                foreach ($issues_data as $file_path => $file_issues) {
                    foreach ($file_issues as $key => $issue_data) {
                        $file = $issue_data->file_name;
                        $file = str_replace('\\', '/', $file);
                        $type = $issue_data->type;
                        if (isset($issue_baseline[$file][$type]) && $issue_baseline[$file][$type]['o'] > 0) {
                            if ($issue_baseline[$file][$type]['o'] === count($issue_baseline[$file][$type]['s'])) {
                                $position = array_search(trim($issue_data->selected_text), $issue_baseline[$file][$type]['s'], \true);
                                if ($position !== \false) {
                                    $issue_data->severity = \Psalm\Config::REPORT_INFO;
                                    array_splice($issue_baseline[$file][$type]['s'], $position, 1);
                                    $issue_baseline[$file][$type]['o']--;
                                }
                            } else {
                                $issue_baseline[$file][$type]['s'] = [];
                                $issue_data->severity = \Psalm\Config::REPORT_INFO;
                                $issue_baseline[$file][$type]['o']--;
                            }
                        }
                        $issues_data[$file_path][$key] = $issue_data;
                    }
                }
                if ($codebase->config->find_unused_baseline_entry) {
                    foreach ($issue_baseline as $file_path => $issues) {
                        foreach ($issues as $issue_name => $issue) {
                            if ($issue['o'] !== 0) {
                                $issues_data[$file_path][] = new IssueData(\Psalm\Config::REPORT_ERROR, 0, 0, UnusedBaselineEntry::getIssueType(), sprintf('Baseline for issue "%s" has %d extra %s.', $issue_name, $issue['o'], $issue['o'] === 1 ? 'entry' : 'entries'), $file_path, '', '', '', 0, 0, 0, 0, 0, 0, UnusedBaselineEntry::SHORTCODE, UnusedBaselineEntry::ERROR_LEVEL);
                            }
                        }
                    }
                }
            }
        }
        echo self::getOutput($issues_data, $project_analyzer->stdout_report_options, $codebase->analyzer->getTotalTypeCoverage($codebase));
        foreach ($issues_data as $file_issues) {
            foreach ($file_issues as $issue_data) {
                if ($issue_data->severity === \Psalm\Config::REPORT_ERROR) {
                    ++$error_count;
                } else {
                    ++$info_count;
                }
            }
        }
        if ($codebase->config->eventDispatcher->after_analysis) {
            $source_control_info = null;
            $build_info = (new BuildInfoCollector(self::$server))->collect();
            try {
                $source_control_info = (new GitInfoCollector())->collect();
            } catch (RuntimeException $e) {
                // do nothing
            }
            /** @psalm-suppress ArgumentTypeCoercion due to Psalm bug */
            $event = new AfterAnalysisEvent($codebase, $issues_data, $build_info, $source_control_info);
            $codebase->config->eventDispatcher->dispatchAfterAnalysis($event);
        }
        foreach ($project_analyzer->generated_report_options as $report_options) {
            if (!$report_options->output_path) {
                throw new UnexpectedValueException('Output path should not be null here');
            }
            $folder = dirname($report_options->output_path);
            if (!is_dir($folder) && !mkdir($folder, 0777, \true) && !is_dir($folder)) {
                throw new RuntimeException(sprintf('Directory "%s" was not created', $folder));
            }
            file_put_contents($report_options->output_path, self::getOutput($issues_data, $report_options, $codebase->analyzer->getTotalTypeCoverage($codebase)));
        }
        if (in_array($project_analyzer->stdout_report_options->format, [\Psalm\Report::TYPE_CONSOLE, \Psalm\Report::TYPE_PHP_STORM])) {
            echo str_repeat('-', 30) . "\n";
            if ($error_count) {
                echo ($project_analyzer->stdout_report_options->use_color ? "\x1b[0;31m" . $error_count . " errors\x1b[0m" : $error_count . ' errors') . ' found' . "\n";
            } else {
                self::printSuccessMessage($project_analyzer);
            }
            $show_info = $project_analyzer->stdout_report_options->show_info;
            $show_suggestions = $project_analyzer->stdout_report_options->show_suggestions;
            if ($info_count && ($show_info || $show_suggestions)) {
                echo str_repeat('-', 30) . "\n";
                echo $info_count . ' other issues found.' . "\n";
                if (!$show_info) {
                    echo 'You can display them with ' . ($project_analyzer->stdout_report_options->use_color ? "\x1b[30;48;5;195m--show-info=true\x1b[0m" : '--show-info=true') . "\n";
                }
            }
            if (self::$fixable_issue_counts && $show_suggestions && !$codebase->taint_flow_graph) {
                echo str_repeat('-', 30) . "\n";
                $total_count = array_sum(self::$fixable_issue_counts);
                $command = '--alter --issues=' . implode(',', array_keys(self::$fixable_issue_counts));
                $command .= ' --dry-run';
                echo 'Psalm can automatically fix ' . $total_count . ($show_info ? ' issues' : ' of these issues') . ".\n" . 'Run Psalm again with ' . "\n" . ($project_analyzer->stdout_report_options->use_color ? "\x1b[30;48;5;195m" . $command . "\x1b[0m" : $command) . "\n" . 'to see what it can fix.' . "\n";
            }
            echo str_repeat('-', 30) . "\n" . "\n";
            if ($start_time) {
                echo 'Checks took ' . number_format(microtime(\true) - $start_time, 2) . ' seconds';
                echo ' and used ' . number_format(memory_get_peak_usage() / (1024 * 1024), 3) . 'MB of memory' . "\n";
                $analysis_summary = $codebase->analyzer->getTypeInferenceSummary($codebase);
                echo $analysis_summary . "\n";
                if ($add_stats) {
                    echo '-----------------' . "\n";
                    echo $codebase->analyzer->getNonMixedStats();
                    echo "\n";
                }
                if ($project_analyzer->debug_performance) {
                    echo '-----------------' . "\n";
                    echo 'Slow-to-analyze functions' . "\n";
                    echo '-----------------' . "\n\n";
                    $function_timings = $codebase->analyzer->getFunctionTimings();
                    arsort($function_timings);
                    $i = 0;
                    foreach ($function_timings as $function_id => $time) {
                        if (++$i > 10) {
                            break;
                        }
                        echo $function_id . ': ' . round(1000 * $time, 2) . 'ms per node' . "\n";
                    }
                    echo "\n";
                }
            }
        }
        if ($is_full && $start_time) {
            $codebase->file_reference_provider->removeDeletedFilesFromReferences();
            if ($project_analyzer->project_cache_provider) {
                $project_analyzer->project_cache_provider->processSuccessfulRun($start_time, PSALM_VERSION);
            }
        }
        if ($error_count && !($codebase->taint_flow_graph && $project_analyzer->generated_report_options && isset($_SERVER['GITHUB_WORKFLOW']))) {
            exit(2);
        }
    }
    public static function printSuccessMessage(ProjectAnalyzer $project_analyzer) : void
    {
        if (!$project_analyzer->stdout_report_options) {
            throw new UnexpectedValueException('Cannot print success message without stdout report options');
        }
        // this message will be printed
        $message = "No errors found!";
        // color block will contain this amount of characters
        $blockSize = 30;
        // message with prepended and appended whitespace to be same as $blockSize
        $messageWithPadding = str_repeat(' ', 7) . $message . str_repeat(' ', 7);
        // top side of the color block
        $paddingTop = str_repeat(' ', $blockSize);
        // bottom side of the color block
        $paddingBottom = str_repeat(' ', $blockSize);
        // background color, 42 = green
        $background = "42";
        // foreground/text color, 30 = black
        $foreground = "30";
        // text style, 1 = bold
        $style = "1";
        if ($project_analyzer->stdout_report_options->use_color) {
            echo "\x1b[{$background};{$style}m{$paddingTop}\x1b[0m" . "\n";
            echo "\x1b[{$background};{$foreground};{$style}m{$messageWithPadding}\x1b[0m" . "\n";
            echo "\x1b[{$background};{$style}m{$paddingBottom}\x1b[0m" . "\n";
        } else {
            echo "\n";
            echo "{$messageWithPadding}\n";
            echo "\n";
        }
    }
    /**
     * @param array<string, array<int, IssueData>> $issues_data
     * @param array{int, int} $mixed_counts
     */
    public static function getOutput(array $issues_data, ReportOptions $report_options, array $mixed_counts = [0, 0]) : string
    {
        $total_expression_count = $mixed_counts[0] + $mixed_counts[1];
        $mixed_expression_count = $mixed_counts[0];
        $normalized_data = $issues_data === [] ? [] : array_merge(...array_values($issues_data));
        $format = $report_options->format;
        switch ($format) {
            case \Psalm\Report::TYPE_COMPACT:
                $output = new CompactReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_EMACS:
                $output = new EmacsReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_TEXT:
                $output = new TextReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_JSON:
                $output = new JsonReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_BY_ISSUE_LEVEL:
                $output = new ByIssueLevelAndTypeReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_JSON_SUMMARY:
                $output = new JsonSummaryReport($normalized_data, self::$fixable_issue_counts, $report_options, $mixed_expression_count, $total_expression_count);
                break;
            case \Psalm\Report::TYPE_SONARQUBE:
                $output = new SonarqubeReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_PYLINT:
                $output = new PylintReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_CHECKSTYLE:
                $output = new CheckstyleReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_XML:
                $output = new XmlReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_JUNIT:
                $output = new JunitReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_CONSOLE:
                $output = new ConsoleReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_GITHUB_ACTIONS:
                $output = new GithubActionsReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_PHP_STORM:
                $output = new PhpStormReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_SARIF:
                $output = new SarifReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_CODECLIMATE:
                $output = new CodeClimateReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            case \Psalm\Report::TYPE_COUNT:
                $output = new CountReport($normalized_data, self::$fixable_issue_counts, $report_options);
                break;
            default:
                throw new RuntimeException('Unexpected report format: ' . $report_options->format);
        }
        return $output->create();
    }
    protected static function alreadyEmitted(string $message) : bool
    {
        $sham = sha1($message);
        if (isset(self::$emitted[$sham])) {
            return \true;
        }
        self::$emitted[$sham] = \true;
        return \false;
    }
    public static function clearCache() : void
    {
        self::$issues_data = [];
        self::$emitted = [];
        self::$error_count = 0;
        self::$recording_level = 0;
        self::$recorded_issues = [];
        self::$console_issues = [];
        self::$unused_suppressions = [];
        self::$used_suppressions = [];
    }
    /**
     * @return array<string, list<IssueData>>
     */
    public static function clear() : array
    {
        $current_data = self::$issues_data;
        self::$issues_data = [];
        self::$emitted = [];
        return $current_data;
    }
    /**
     * Return whether or not we're in a recording state regarding startRecording/stopRecording status
     */
    public static function isRecording() : bool
    {
        return self::$recording_level > 0;
    }
    /**
     * Increase the recording level in order to start recording issues instead of adding them while in a loop
     */
    public static function startRecording() : void
    {
        ++self::$recording_level;
        self::$recorded_issues[self::$recording_level] = [];
    }
    /**
     * Decrease the recording level after leaving a loop
     *
     * @see startRecording
     */
    public static function stopRecording() : void
    {
        if (self::$recording_level === 0) {
            throw new UnexpectedValueException('Cannot stop recording - already at base level');
        }
        --self::$recording_level;
    }
    /**
     * This will return the recorded issues for the current recording level
     *
     * @return array<int, CodeIssue>
     */
    public static function clearRecordingLevel() : array
    {
        if (self::$recording_level === 0) {
            throw new UnexpectedValueException('Not currently recording');
        }
        $recorded_issues = self::$recorded_issues[self::$recording_level];
        self::$recorded_issues[self::$recording_level] = [];
        return $recorded_issues;
    }
    /**
     * This will try to add issues that has been retrieved through clearRecordingLevel or record them at a lower level
     */
    public static function bubbleUp(CodeIssue $e) : void
    {
        if (self::$recording_level === 0) {
            self::add($e);
            return;
        }
        self::$recorded_issues[self::$recording_level][] = $e;
    }
    /**
     * @internal
     * @param array<array-key,mixed> $server
     */
    public static final function captureServer(array $server) : void
    {
        self::$server = $server;
    }
}
<?php

namespace Psalm\SourceControl\Git;

/**
 * Remote info.
 *
 * @author Kitamura Satoshi <with.no.parachute@gmail.com>
 */
final class RemoteInfo
{
    /**
     * Remote name.
     *
     * @var null|string
     */
    protected $name;
    /**
     * Remote URL.
     *
     * @var null|string
     */
    protected $url;
    public function toArray() : array
    {
        return ['name' => $this->name, 'url' => $this->url];
    }
    // accessor
    /**
     * Set remote name.
     *
     * @param string $name remote name
     * @return $this
     */
    public function setName(string $name) : \Psalm\SourceControl\Git\RemoteInfo
    {
        $this->name = $name;
        return $this;
    }
    /**
     * Return remote name.
     */
    public function getName() : ?string
    {
        return $this->name;
    }
    /**
     * Set remote URL.
     *
     * @param string $url remote URL
     * @return $this
     */
    public function setUrl(string $url) : \Psalm\SourceControl\Git\RemoteInfo
    {
        $this->url = $url;
        return $this;
    }
    /**
     * Return remote URL.
     */
    public function getUrl() : ?string
    {
        return $this->url;
    }
}
<?php

namespace Psalm\SourceControl\Git;

/**
 * Commit info.
 *
 * @author Kitamura Satoshi <with.no.parachute@gmail.com>
 */
final class CommitInfo
{
    /**
     * Commit ID.
     *
     * @var null|string
     */
    protected $id;
    /**
     * Author name.
     *
     * @var null|string
     */
    protected $author_name;
    /**
     * Author email.
     *
     * @var null|string
     */
    protected $author_email;
    /**
     * Committer name.
     *
     * @var null|string
     */
    protected $committer_name;
    /**
     * Committer email.
     *
     * @var null|string
     */
    protected $committer_email;
    /**
     * Commit message.
     *
     * @var null|string
     */
    protected $message;
    /**
     * Commit message.
     *
     * @var null|int
     */
    protected $date;
    public function toArray() : array
    {
        return ['id' => $this->id, 'author_name' => $this->author_name, 'author_email' => $this->author_email, 'committer_name' => $this->committer_name, 'committer_email' => $this->committer_email, 'message' => $this->message, 'date' => $this->date];
    }
    // accessor
    /**
     * Set commit ID.
     */
    public function setId(string $id) : self
    {
        $this->id = $id;
        return $this;
    }
    /**
     * Return commit ID.
     */
    public function getId() : ?string
    {
        return $this->id;
    }
    /**
     * Set author name.
     */
    public function setAuthorName(string $author_name) : self
    {
        $this->author_name = $author_name;
        return $this;
    }
    /**
     * Return author name.
     */
    public function getAuthorName() : ?string
    {
        return $this->author_name;
    }
    /**
     * Set author email.
     */
    public function setAuthorEmail(string $author_email) : self
    {
        $this->author_email = $author_email;
        return $this;
    }
    /**
     * Return author email.
     */
    public function getAuthorEmail() : ?string
    {
        return $this->author_email;
    }
    /**
     * Set committer name.
     */
    public function setCommitterName(string $committer_name) : self
    {
        $this->committer_name = $committer_name;
        return $this;
    }
    /**
     * Return committer name.
     */
    public function getCommitterName() : ?string
    {
        return $this->committer_name;
    }
    /**
     * Set committer email.
     */
    public function setCommitterEmail(string $committer_email) : self
    {
        $this->committer_email = $committer_email;
        return $this;
    }
    /**
     * Return committer email.
     */
    public function getCommitterEmail() : ?string
    {
        return $this->committer_email;
    }
    /**
     * Set commit message.
     */
    public function setMessage(string $message) : self
    {
        $this->message = $message;
        return $this;
    }
    /**
     * Return commit message.
     */
    public function getMessage() : ?string
    {
        return $this->message;
    }
    /**
     * Set commit date
     */
    public function setDate(int $date) : self
    {
        $this->date = $date;
        return $this;
    }
    /**
     * Return commit date.
     */
    public function getDate() : ?int
    {
        return $this->date;
    }
}
<?php

namespace Psalm\SourceControl\Git;

use Psalm\SourceControl\SourceControlInfo;
/**
 * Data represents "git" of Coveralls API.
 *
 * "git": {
 *   "head": {
 *     "id": "b31f08d07ae564b08237e5a336e478b24ccc4a65",
 *     "author_name": "Nick Merwin",
 *     "author_email": "...",
 *     "committer_name": "Nick Merwin",
 *     "committer_email": "...",
 *     "message": "version bump"
 *   },
 *   "branch": "master",
 *   "remotes": [
 *     {
 *       "name": "origin",
 *       "url": "git@github.com:lemurheavy/coveralls-ruby.git"
 *     }
 *   ]
 * }
 *
 * @author Kitamura Satoshi <with.no.parachute@gmail.com>
 */
final class GitInfo extends SourceControlInfo
{
    /**
     * Branch name.
     *
     * @var string
     */
    protected $branch;
    /**
     * Head.
     *
     * @var CommitInfo
     */
    protected $head;
    /**
     * Remote.
     *
     * @var RemoteInfo[]
     */
    protected $remotes;
    /**
     * Constructor.
     *
     * @param string $branch  branch name
     * @param CommitInfo $head    HEAD commit
     * @param RemoteInfo[]  $remotes remote repositories
     */
    public function __construct(string $branch, \Psalm\SourceControl\Git\CommitInfo $head, array $remotes)
    {
        $this->branch = $branch;
        $this->head = $head;
        $this->remotes = $remotes;
    }
    public function toArray() : array
    {
        $remotes = [];
        foreach ($this->remotes as $remote) {
            $remotes[] = $remote->toArray();
        }
        return ['branch' => $this->branch, 'head' => $this->head->toArray(), 'remotes' => $remotes];
    }
    // accessor
    /**
     * Return branch name.
     */
    public function getBranch() : string
    {
        return $this->branch;
    }
    /**
     * Return HEAD commit.
     */
    public function getHead() : \Psalm\SourceControl\Git\CommitInfo
    {
        return $this->head;
    }
    /**
     * Return remote repositories.
     *
     * @return RemoteInfo[]
     */
    public function getRemotes() : array
    {
        return $this->remotes;
    }
}
<?php

namespace Psalm\SourceControl;

abstract class SourceControlInfo
{
    public abstract function toArray() : array;
}
<?php

namespace Psalm\Plugin;

use SimpleXMLElement;
interface PluginEntryPointInterface extends \Psalm\Plugin\PluginInterface
{
    public function __invoke(\Psalm\Plugin\RegistrationInterface $registration, ?SimpleXMLElement $config = null) : void;
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin;

use Psalm\Type;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
final class DynamicTemplateProvider
{
    private string $defining_class;
    /**
     * @internal
     */
    public function __construct(string $defining_class)
    {
        $this->defining_class = $defining_class;
    }
    /**
     * If {@see DynamicFunctionStorage} requires template params this method can create it.
     */
    public function createTemplate(string $param_name, Union $as = null) : TTemplateParam
    {
        return new TTemplateParam($param_name, $as ?? Type::getMixed(), $this->defining_class);
    }
}
<?php

namespace Psalm\Plugin;

use SimpleXMLElement;
interface PluginFileExtensionsInterface extends \Psalm\Plugin\PluginInterface
{
    public function processFileExtensions(\Psalm\Plugin\FileExtensionsInterface $fileExtensions, ?SimpleXMLElement $config = null) : void;
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin;

use Psalm\Storage\FunctionLikeParameter;
use Psalm\Storage\FunctionStorage;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Union;
final class DynamicFunctionStorage
{
    /**
     * Required param list for a function.
     *
     * @var list<FunctionLikeParameter>
     */
    public array $params = [];
    /**
     * A function return type. Maybe null.
     * That means we can infer it in {@see FunctionReturnTypeProviderInterface} hook.
     */
    public ?Union $return_type = null;
    /**
     * A function can have template args or return type.
     * Plugin hook must fill all used templates here.
     *
     * @var list<TTemplateParam>
     */
    public array $templates = [];
    /**
     * Determines if a function can be called with named arguments.
     */
    public bool $allow_named_arg_calls = \true;
    /**
     * Function purity.
     * If function is pure then plugin hook should set it to true.
     */
    public bool $pure = \false;
    /**
     * Determines if a function can be called with a various number of arguments.
     */
    public bool $variadic = \false;
    /**
     * @internal
     */
    public function toFunctionStorage(string $function_cased_name) : FunctionStorage
    {
        $storage = new FunctionStorage();
        $storage->cased_name = $function_cased_name;
        $storage->setParams($this->params);
        $storage->return_type = $this->return_type;
        $storage->allow_named_arg_calls = $this->allow_named_arg_calls;
        $storage->pure = $this->pure;
        $storage->variadic = $this->variadic;
        if (!empty($this->templates)) {
            $storage->template_types = [];
            foreach ($this->templates as $template) {
                $storage->template_types[$template->param_name] = [$template->defining_class => $template->as];
            }
        }
        return $storage;
    }
}
<?php

namespace Psalm\Plugin;

use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Scanner\FileScanner;
interface FileExtensionsInterface
{
    /**
     * @param string $fileExtension e.g. `'html'`
     * @param class-string<FileScanner> $className
     */
    public function addFileTypeScanner(string $fileExtension, string $className) : void;
    /**
     * @param string $fileExtension e.g. `'html'`
     * @param class-string<FileAnalyzer> $className
     */
    public function addFileTypeAnalyzer(string $fileExtension, string $className) : void;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterClassLikeVisitEvent;
interface AfterClassLikeVisitInterface
{
    /**
     * @return void
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint
     */
    public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event);
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterFileAnalysisEvent;
interface AfterFileAnalysisInterface
{
    /**
     * Called after a file has been checked
     */
    public static function afterAnalyzeFile(AfterFileAnalysisEvent $event) : void;
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\BeforeAddIssueEvent;
interface BeforeAddIssueInterface
{
    /**
     * Called before adding a code issue.
     *
     * Note that event handlers are called in the order they were registered, and thus
     * the handler registered earlier may prevent subsequent handlers from running by
     * returning a boolean value.
     *
     * @return null|bool $event How and whether to continue:
     *  + `null` continues with next event handler
     *  + `true` stops event handling & keeps issue
     *  + `false` stops event handling & ignores issue
     */
    public static function beforeAddIssue(BeforeAddIssueEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\PropertyTypeProviderEvent;
use Psalm\Type\Union;
interface PropertyTypeProviderInterface
{
    /**
     * @return array<string>
     */
    public static function getClassLikeNames() : array;
    public static function getPropertyType(PropertyTypeProviderEvent $event) : ?Union;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterClassLikeAnalysisEvent;
interface AfterClassLikeAnalysisInterface
{
    /**
     * Called after a statement has been checked
     *
     * @return null|false
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint
     */
    public static function afterStatementAnalysis(AfterClassLikeAnalysisEvent $event);
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterAnalysisEvent;
interface AfterAnalysisInterface
{
    /**
     * Called after analysis is complete
     */
    public static function afterAnalysis(AfterAnalysisEvent $event) : void;
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\SourceControl\SourceControlInfo;
final class AfterAnalysisEvent
{
    private Codebase $codebase;
    /**
     * @var IssueData[][]
     */
    private array $issues;
    private array $build_info;
    private ?SourceControlInfo $source_control_info;
    /**
     * Called after analysis is complete
     *
     * @param array<string, list<IssueData>> $issues
     * @internal
     */
    public function __construct(Codebase $codebase, array $issues, array $build_info, ?SourceControlInfo $source_control_info = null)
    {
        $this->codebase = $codebase;
        $this->issues = $issues;
        $this->build_info = $build_info;
        $this->source_control_info = $source_control_info;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return IssueData[][]
     */
    public function getIssues() : array
    {
        return $this->issues;
    }
    public function getBuildInfo() : array
    {
        return $this->build_info;
    }
    public function getSourceControlInfo() : ?SourceControlInfo
    {
        return $this->source_control_info;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\CodeLocation;
use Psalm\StatementsSource;
final class MethodExistenceProviderEvent
{
    private string $fq_classlike_name;
    private string $method_name_lowercase;
    private ?StatementsSource $source;
    private ?CodeLocation $code_location;
    /**
     * Use this hook for informing whether or not a method exists on a given object. If you know the method does
     * not exist, return false. If you aren't sure if it exists or not, return null and the default analysis will
     * continue to determine if the method actually exists.
     *
     * @internal
     */
    public function __construct(string $fq_classlike_name, string $method_name_lowercase, ?StatementsSource $source = null, ?CodeLocation $code_location = null)
    {
        $this->fq_classlike_name = $fq_classlike_name;
        $this->method_name_lowercase = $method_name_lowercase;
        $this->source = $source;
        $this->code_location = $code_location;
    }
    public function getFqClasslikeName() : string
    {
        return $this->fq_classlike_name;
    }
    public function getMethodNameLowercase() : string
    {
        return $this->method_name_lowercase;
    }
    public function getSource() : ?StatementsSource
    {
        return $this->source;
    }
    public function getCodeLocation() : ?CodeLocation
    {
        return $this->code_location;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use Psalm\Codebase;
use Psalm\FileManipulation;
use Psalm\StatementsSource;
use Psalm\Storage\ClassLikeStorage;
final class AfterClassLikeAnalysisEvent
{
    private Node\Stmt\ClassLike $stmt;
    private ClassLikeStorage $classlike_storage;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    /**
     * Called after a statement has been checked
     *
     * @param  FileManipulation[]   $file_replacements
     * @internal
     */
    public function __construct(Node\Stmt\ClassLike $stmt, ClassLikeStorage $classlike_storage, StatementsSource $statements_source, Codebase $codebase, array $file_replacements = [])
    {
        $this->stmt = $stmt;
        $this->classlike_storage = $classlike_storage;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
    }
    public function getStmt() : Node\Stmt\ClassLike
    {
        return $this->stmt;
    }
    public function getClasslikeStorage() : ClassLikeStorage
    {
        return $this->classlike_storage;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\StatementsSource;
final class FunctionExistenceProviderEvent
{
    private StatementsSource $statements_source;
    private string $function_id;
    /**
     * Use this hook for informing whether or not a global function exists. If you know the function does
     * not exist, return false. If you aren't sure if it exists or not, return null and the default analysis
     * will continue to determine if the function actually exists.
     *
     * @internal
     */
    public function __construct(StatementsSource $statements_source, string $function_id)
    {
        $this->statements_source = $statements_source;
        $this->function_id = $function_id;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getFunctionId() : string
    {
        return $this->function_id;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\Plugin\ArgTypeInferer;
use Psalm\Plugin\DynamicTemplateProvider;
use Psalm\StatementsSource;
final class DynamicFunctionStorageProviderEvent
{
    private ArgTypeInferer $arg_type_inferer;
    private DynamicTemplateProvider $template_provider;
    private StatementsSource $statement_source;
    private string $function_id;
    private PhpParser\Node\Expr\FuncCall $func_call;
    private Context $context;
    private CodeLocation $code_location;
    /**
     * @internal
     */
    public function __construct(ArgTypeInferer $arg_type_inferer, DynamicTemplateProvider $template_provider, StatementsSource $statements_source, string $function_id, PhpParser\Node\Expr\FuncCall $func_call, Context $context, CodeLocation $code_location)
    {
        $this->statement_source = $statements_source;
        $this->function_id = $function_id;
        $this->func_call = $func_call;
        $this->context = $context;
        $this->code_location = $code_location;
        $this->arg_type_inferer = $arg_type_inferer;
        $this->template_provider = $template_provider;
    }
    public function getArgTypeInferer() : ArgTypeInferer
    {
        return $this->arg_type_inferer;
    }
    public function getTemplateProvider() : DynamicTemplateProvider
    {
        return $this->template_provider;
    }
    public function getCodebase() : Codebase
    {
        return $this->statement_source->getCodebase();
    }
    public function getStatementSource() : StatementsSource
    {
        return $this->statement_source;
    }
    public function getFunctionId() : string
    {
        return $this->function_id;
    }
    /**
     * @return list<PhpParser\Node\Arg>
     */
    public function getArgs() : array
    {
        return $this->func_call->getArgs();
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getCodeLocation() : CodeLocation
    {
        return $this->code_location;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\StatementsSource;
use Psalm\Storage\FileStorage;
final class AfterFileAnalysisEvent
{
    private StatementsSource $statements_source;
    private Context $file_context;
    private FileStorage $file_storage;
    private Codebase $codebase;
    /**
     * @var Stmt[]
     */
    private array $stmts;
    /**
     * Called after a file has been checked
     *
     * @param array<Stmt> $stmts
     * @internal
     */
    public function __construct(StatementsSource $statements_source, Context $file_context, FileStorage $file_storage, Codebase $codebase, array $stmts)
    {
        $this->statements_source = $statements_source;
        $this->file_context = $file_context;
        $this->file_storage = $file_storage;
        $this->codebase = $codebase;
        $this->stmts = $stmts;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getFileContext() : Context
    {
        return $this->file_context;
    }
    public function getFileStorage() : FileStorage
    {
        return $this->file_storage;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return Stmt[]
     */
    public function getStmts() : array
    {
        return $this->stmts;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\FileManipulation;
use Psalm\StatementsSource;
final class AfterClassLikeExistenceCheckEvent
{
    private string $fq_class_name;
    private CodeLocation $code_location;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    /**
     * @param FileManipulation[] $file_replacements
     * @internal
     */
    public function __construct(string $fq_class_name, CodeLocation $code_location, StatementsSource $statements_source, Codebase $codebase, array $file_replacements = [])
    {
        $this->fq_class_name = $fq_class_name;
        $this->code_location = $code_location;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
    }
    public function getFqClassName() : string
    {
        return $this->fq_class_name;
    }
    public function getCodeLocation() : CodeLocation
    {
        return $this->code_location;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\FuncCall;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\StatementsSource;
final class AfterEveryFunctionCallAnalysisEvent
{
    private FuncCall $expr;
    private string $function_id;
    private Context $context;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /** @internal */
    public function __construct(FuncCall $expr, string $function_id, Context $context, StatementsSource $statements_source, Codebase $codebase)
    {
        $this->expr = $expr;
        $this->function_id = $function_id;
        $this->context = $context;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
    }
    public function getExpr() : FuncCall
    {
        return $this->expr;
    }
    public function getFunctionId() : string
    {
        return $this->function_id;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\StatementsSource;
final class AfterExpressionAnalysisEvent
{
    private Expr $expr;
    private Context $context;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    /**
     * Called after an expression has been checked
     *
     * @param  FileManipulation[]   $file_replacements
     * @internal
     */
    public function __construct(Expr $expr, Context $context, StatementsSource $statements_source, Codebase $codebase, array $file_replacements = [])
    {
        $this->expr = $expr;
        $this->context = $context;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
    }
    public function getExpr() : Expr
    {
        return $this->expr;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\FuncCall;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
final class FunctionReturnTypeProviderEvent
{
    private StatementsSource $statements_source;
    /**
     * @var non-empty-string
     */
    private string $function_id;
    private FuncCall $stmt;
    private Context $context;
    private CodeLocation $code_location;
    /**
     * Use this hook for providing custom return type logic. If this plugin does not know what a function should
     * return but another plugin may be able to determine the type, return null. Otherwise return a mixed union type
     * if something should be returned, but can't be more specific.
     *
     * @param non-empty-string $function_id
     * @internal
     */
    public function __construct(StatementsSource $statements_source, string $function_id, FuncCall $stmt, Context $context, CodeLocation $code_location)
    {
        $this->statements_source = $statements_source;
        $this->function_id = $function_id;
        $this->stmt = $stmt;
        $this->context = $context;
        $this->code_location = $code_location;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    /**
     * @return non-empty-string
     */
    public function getFunctionId() : string
    {
        return $this->function_id;
    }
    /**
     * @return list<PhpParser\Node\Arg>
     */
    public function getCallArgs() : array
    {
        return $this->stmt->getArgs();
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getCodeLocation() : CodeLocation
    {
        return $this->code_location;
    }
    public function getStmt() : FuncCall
    {
        return $this->stmt;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
final class FunctionParamsProviderEvent
{
    private StatementsSource $statements_source;
    private string $function_id;
    /**
     * @var PhpParser\Node\Arg[]
     */
    private array $call_args;
    private ?Context $context;
    private ?CodeLocation $code_location;
    /**
     * @param  list<PhpParser\Node\Arg>    $call_args
     * @internal
     */
    public function __construct(StatementsSource $statements_source, string $function_id, array $call_args, ?Context $context = null, ?CodeLocation $code_location = null)
    {
        $this->statements_source = $statements_source;
        $this->function_id = $function_id;
        $this->call_args = $call_args;
        $this->context = $context;
        $this->code_location = $code_location;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getFunctionId() : string
    {
        return $this->function_id;
    }
    /**
     * @return PhpParser\Node\Arg[]
     */
    public function getCallArgs() : array
    {
        return $this->call_args;
    }
    public function getContext() : ?Context
    {
        return $this->context;
    }
    public function getCodeLocation() : ?CodeLocation
    {
        return $this->code_location;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\Codebase;
final class AfterCodebasePopulatedEvent
{
    private Codebase $codebase;
    /**
     * Called after codebase has been populated
     *
     * @internal
     */
    public function __construct(Codebase $codebase)
    {
        $this->codebase = $codebase;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin\EventHandler\Event;

use Psalm\Codebase;
use Psalm\Issue\CodeIssue;
final class BeforeAddIssueEvent
{
    private CodeIssue $issue;
    private bool $fixable;
    private Codebase $codebase;
    /** @internal */
    public function __construct(CodeIssue $issue, bool $fixable, Codebase $codebase)
    {
        $this->issue = $issue;
        $this->fixable = $fixable;
        $this->codebase = $codebase;
    }
    public function getIssue() : CodeIssue
    {
        return $this->issue;
    }
    public function isFixable() : bool
    {
        return $this->fixable;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\Context;
use Psalm\StatementsSource;
final class PropertyTypeProviderEvent
{
    private string $fq_classlike_name;
    private string $property_name;
    private bool $read_mode;
    private ?StatementsSource $source;
    private ?Context $context;
    /** @internal */
    public function __construct(string $fq_classlike_name, string $property_name, bool $read_mode, ?StatementsSource $source = null, ?Context $context = null)
    {
        $this->fq_classlike_name = $fq_classlike_name;
        $this->property_name = $property_name;
        $this->read_mode = $read_mode;
        $this->source = $source;
        $this->context = $context;
    }
    public function getFqClasslikeName() : string
    {
        return $this->fq_classlike_name;
    }
    public function getPropertyName() : string
    {
        return $this->property_name;
    }
    public function isReadMode() : bool
    {
        return $this->read_mode;
    }
    public function getSource() : ?StatementsSource
    {
        return $this->source;
    }
    public function getContext() : ?Context
    {
        return $this->context;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassLike;
use Psalm\Codebase;
use Psalm\FileManipulation;
use Psalm\FileSource;
use Psalm\Storage\ClassLikeStorage;
final class AfterClassLikeVisitEvent
{
    private ClassLike $stmt;
    private ClassLikeStorage $storage;
    private FileSource $statements_source;
    private Codebase $codebase;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    /**
     * @param  FileManipulation[] $file_replacements
     * @internal
     */
    public function __construct(ClassLike $stmt, ClassLikeStorage $storage, FileSource $statements_source, Codebase $codebase, array $file_replacements = [])
    {
        $this->stmt = $stmt;
        $this->storage = $storage;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
    }
    public function getStmt() : ClassLike
    {
        return $this->stmt;
    }
    public function getStorage() : ClassLikeStorage
    {
        return $this->storage;
    }
    public function getStatementsSource() : FileSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\StatementsSource;
final class BeforeStatementAnalysisEvent
{
    private Stmt $stmt;
    private Context $context;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * @var list<FileManipulation>
     */
    private array $file_replacements;
    /**
     * Called after a statement has been checked
     *
     * @param list<FileManipulation> $file_replacements
     * @internal
     */
    public function __construct(Stmt $stmt, Context $context, StatementsSource $statements_source, Codebase $codebase, array $file_replacements = [])
    {
        $this->stmt = $stmt;
        $this->context = $context;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
    }
    public function getStmt() : Stmt
    {
        return $this->stmt;
    }
    public function setStmt(Stmt $stmt) : void
    {
        $this->stmt = $stmt;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return list<FileManipulation>
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param list<FileManipulation> $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\Codebase;
final class StringInterpreterEvent
{
    private string $value;
    private Codebase $codebase;
    /**
     * Called after a statement has been checked
     *
     * @psalm-external-mutation-free
     * @internal
     */
    public function __construct(string $value, Codebase $codebase)
    {
        $this->value = $value;
        $this->codebase = $codebase;
    }
    public function getValue() : string
    {
        return $this->value;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
final class PropertyVisibilityProviderEvent
{
    private StatementsSource $source;
    private string $fq_classlike_name;
    private string $property_name;
    private bool $read_mode;
    private Context $context;
    private CodeLocation $code_location;
    /** @internal */
    public function __construct(StatementsSource $source, string $fq_classlike_name, string $property_name, bool $read_mode, Context $context, CodeLocation $code_location)
    {
        $this->source = $source;
        $this->fq_classlike_name = $fq_classlike_name;
        $this->property_name = $property_name;
        $this->read_mode = $read_mode;
        $this->context = $context;
        $this->code_location = $code_location;
    }
    public function getSource() : StatementsSource
    {
        return $this->source;
    }
    public function getFqClasslikeName() : string
    {
        return $this->fq_classlike_name;
    }
    public function getPropertyName() : string
    {
        return $this->property_name;
    }
    public function isReadMode() : bool
    {
        return $this->read_mode;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getCodeLocation() : CodeLocation
    {
        return $this->code_location;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\NodeTypeProvider;
use Psalm\StatementsSource;
use Psalm\Storage\FunctionLikeStorage;
final class AfterFunctionLikeAnalysisEvent
{
    private Node\FunctionLike $stmt;
    private FunctionLikeStorage $functionlike_storage;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    private NodeTypeProvider $node_type_provider;
    private Context $context;
    /**
     * Called after a statement has been checked
     *
     * @param  FileManipulation[]   $file_replacements
     * @internal
     */
    public function __construct(Node\FunctionLike $stmt, FunctionLikeStorage $functionlike_storage, StatementsSource $statements_source, Codebase $codebase, array $file_replacements, NodeTypeProvider $node_type_provider, Context $context)
    {
        $this->stmt = $stmt;
        $this->functionlike_storage = $functionlike_storage;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
        $this->node_type_provider = $node_type_provider;
        $this->context = $context;
    }
    public function getStmt() : Node\FunctionLike
    {
        return $this->stmt;
    }
    public function getFunctionlikeStorage() : FunctionLikeStorage
    {
        return $this->functionlike_storage;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
    public function getNodeTypeProvider() : NodeTypeProvider
    {
        return $this->node_type_provider;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
final class MethodVisibilityProviderEvent
{
    private StatementsSource $source;
    private string $fq_classlike_name;
    private string $method_name_lowercase;
    private Context $context;
    private ?CodeLocation $code_location;
    /** @internal */
    public function __construct(StatementsSource $source, string $fq_classlike_name, string $method_name_lowercase, Context $context, ?CodeLocation $code_location = null)
    {
        $this->source = $source;
        $this->fq_classlike_name = $fq_classlike_name;
        $this->method_name_lowercase = $method_name_lowercase;
        $this->context = $context;
        $this->code_location = $code_location;
    }
    public function getSource() : StatementsSource
    {
        return $this->source;
    }
    public function getFqClasslikeName() : string
    {
        return $this->fq_classlike_name;
    }
    public function getMethodNameLowercase() : string
    {
        return $this->method_name_lowercase;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getCodeLocation() : ?CodeLocation
    {
        return $this->code_location;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\StatementsSource;
final class AfterStatementAnalysisEvent
{
    private Stmt $stmt;
    private Context $context;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    /**
     * Called after a statement has been checked
     *
     * @param  FileManipulation[]   $file_replacements
     * @internal
     */
    public function __construct(Stmt $stmt, Context $context, StatementsSource $statements_source, Codebase $codebase, array $file_replacements = [])
    {
        $this->stmt = $stmt;
        $this->context = $context;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
    }
    public function getStmt() : Stmt
    {
        return $this->stmt;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
final class PropertyExistenceProviderEvent
{
    private string $fq_classlike_name;
    private string $property_name;
    private bool $read_mode;
    private ?StatementsSource $source;
    private ?Context $context;
    private ?CodeLocation $code_location;
    /**
     * Use this hook for informing whether or not a property exists on a given object. If you know the property does
     * not exist, return false. If you aren't sure if it exists or not, return null and the default analysis will
     * continue to determine if the property actually exists.
     *
     * @internal
     */
    public function __construct(string $fq_classlike_name, string $property_name, bool $read_mode, ?StatementsSource $source = null, ?Context $context = null, ?CodeLocation $code_location = null)
    {
        $this->fq_classlike_name = $fq_classlike_name;
        $this->property_name = $property_name;
        $this->read_mode = $read_mode;
        $this->source = $source;
        $this->context = $context;
        $this->code_location = $code_location;
    }
    public function getFqClasslikeName() : string
    {
        return $this->fq_classlike_name;
    }
    public function getPropertyName() : string
    {
        return $this->property_name;
    }
    public function isReadMode() : bool
    {
        return $this->read_mode;
    }
    public function getSource() : ?StatementsSource
    {
        return $this->source;
    }
    public function getContext() : ?Context
    {
        return $this->context;
    }
    public function getCodeLocation() : ?CodeLocation
    {
        return $this->code_location;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\FuncCall;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\StatementsSource;
use Psalm\Type\Union;
final class AfterFunctionCallAnalysisEvent
{
    private FuncCall $expr;
    /**
     * @var non-empty-string
     */
    private string $function_id;
    private Context $context;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    private Union $return_type_candidate;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    /**
     * @param non-empty-string $function_id
     * @param FileManipulation[] $file_replacements
     * @internal
     */
    public function __construct(FuncCall $expr, string $function_id, Context $context, StatementsSource $statements_source, Codebase $codebase, Union $return_type_candidate, array $file_replacements)
    {
        $this->expr = $expr;
        $this->function_id = $function_id;
        $this->context = $context;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->return_type_candidate = $return_type_candidate;
        $this->file_replacements = $file_replacements;
    }
    public function getExpr() : FuncCall
    {
        return $this->expr;
    }
    /**
     * @return non-empty-string
     */
    public function getFunctionId() : string
    {
        return $this->function_id;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    public function getReturnTypeCandidate() : Union
    {
        return $this->return_type_candidate;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
final class MethodParamsProviderEvent
{
    private string $fq_classlike_name;
    private string $method_name_lowercase;
    /**
     * @var list<PhpParser\Node\Arg>|null
     */
    private ?array $call_args;
    private ?StatementsSource $statements_source;
    private ?Context $context;
    private ?CodeLocation $code_location;
    /**
     * @param  list<PhpParser\Node\Arg>    $call_args
     * @internal
     */
    public function __construct(string $fq_classlike_name, string $method_name_lowercase, ?array $call_args = null, ?StatementsSource $statements_source = null, ?Context $context = null, ?CodeLocation $code_location = null)
    {
        $this->fq_classlike_name = $fq_classlike_name;
        $this->method_name_lowercase = $method_name_lowercase;
        $this->call_args = $call_args;
        $this->statements_source = $statements_source;
        $this->context = $context;
        $this->code_location = $code_location;
    }
    public function getFqClasslikeName() : string
    {
        return $this->fq_classlike_name;
    }
    public function getMethodNameLowercase() : string
    {
        return $this->method_name_lowercase;
    }
    /**
     * @return list<PhpParser\Node\Arg>|null
     */
    public function getCallArgs() : ?array
    {
        return $this->call_args;
    }
    public function getStatementsSource() : ?StatementsSource
    {
        return $this->statements_source;
    }
    public function getContext() : ?Context
    {
        return $this->context;
    }
    public function getCodeLocation() : ?CodeLocation
    {
        return $this->code_location;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\MethodCall;
use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\StaticCall;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\FileManipulation;
use Psalm\StatementsSource;
use Psalm\Type\Union;
final class AfterMethodCallAnalysisEvent
{
    /**
     * @var MethodCall|StaticCall
     */
    private $expr;
    private string $method_id;
    private string $appearing_method_id;
    private string $declaring_method_id;
    private Context $context;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * @var FileManipulation[]
     */
    private array $file_replacements;
    private ?Union $return_type_candidate;
    /**
     * @param  MethodCall|StaticCall $expr
     * @param  FileManipulation[] $file_replacements
     * @internal
     */
    public function __construct(Expr $expr, string $method_id, string $appearing_method_id, string $declaring_method_id, Context $context, StatementsSource $statements_source, Codebase $codebase, array $file_replacements = [], Union $return_type_candidate = null)
    {
        $this->expr = $expr;
        $this->method_id = $method_id;
        $this->appearing_method_id = $appearing_method_id;
        $this->declaring_method_id = $declaring_method_id;
        $this->context = $context;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
        $this->file_replacements = $file_replacements;
        $this->return_type_candidate = $return_type_candidate;
    }
    /**
     * @return MethodCall|StaticCall
     */
    public function getExpr() : Expr
    {
        return $this->expr;
    }
    public function getMethodId() : string
    {
        return $this->method_id;
    }
    public function getAppearingMethodId() : string
    {
        return $this->appearing_method_id;
    }
    public function getDeclaringMethodId() : string
    {
        return $this->declaring_method_id;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
    /**
     * @return FileManipulation[]
     */
    public function getFileReplacements() : array
    {
        return $this->file_replacements;
    }
    public function getReturnTypeCandidate() : ?Union
    {
        return $this->return_type_candidate;
    }
    /**
     * @param FileManipulation[] $file_replacements
     */
    public function setFileReplacements(array $file_replacements) : void
    {
        $this->file_replacements = $file_replacements;
    }
    public function setReturnTypeCandidate(?Union $return_type_candidate) : void
    {
        $this->return_type_candidate = $return_type_candidate;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use Psalm\Codebase;
use Psalm\Context;
use Psalm\StatementsSource;
use Psalm\Storage\FileStorage;
final class BeforeFileAnalysisEvent
{
    private StatementsSource $statements_source;
    private Context $file_context;
    private FileStorage $file_storage;
    private Codebase $codebase;
    /**
     * Called before a file has been checked
     *
     * @internal
     */
    public function __construct(StatementsSource $statements_source, Context $file_context, FileStorage $file_storage, Codebase $codebase)
    {
        $this->statements_source = $statements_source;
        $this->file_context = $file_context;
        $this->file_storage = $file_storage;
        $this->codebase = $codebase;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getFileContext() : Context
    {
        return $this->file_context;
    }
    public function getFileStorage() : FileStorage
    {
        return $this->file_storage;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
use Psalm\Type\Union;
final class MethodReturnTypeProviderEvent
{
    private StatementsSource $source;
    private string $fq_classlike_name;
    /**
     * @var lowercase-string
     */
    private string $method_name_lowercase;
    private Context $context;
    private CodeLocation $code_location;
    /**
     * @var PhpParser\Node\Expr\MethodCall|PhpParser\Node\Expr\StaticCall
     */
    private $stmt;
    /** @var non-empty-list<Union>|null */
    private ?array $template_type_parameters;
    private ?string $called_fq_classlike_name;
    /**
     * @var lowercase-string|null
     */
    private ?string $called_method_name_lowercase;
    /**
     * Use this hook for providing custom return type logic. If this plugin does not know what a method should return
     * but another plugin may be able to determine the type, return null. Otherwise return a mixed union type if
     * something should be returned, but can't be more specific.
     *
     * @param PhpParser\Node\Expr\MethodCall|PhpParser\Node\Expr\StaticCall $stmt
     * @param non-empty-list<Union>|null $template_type_parameters
     * @param lowercase-string $method_name_lowercase
     * @param lowercase-string $called_method_name_lowercase
     * @internal
     */
    public function __construct(StatementsSource $source, string $fq_classlike_name, string $method_name_lowercase, $stmt, Context $context, CodeLocation $code_location, ?array $template_type_parameters = null, ?string $called_fq_classlike_name = null, ?string $called_method_name_lowercase = null)
    {
        $this->source = $source;
        $this->fq_classlike_name = $fq_classlike_name;
        $this->method_name_lowercase = $method_name_lowercase;
        $this->context = $context;
        $this->code_location = $code_location;
        $this->stmt = $stmt;
        $this->template_type_parameters = $template_type_parameters;
        $this->called_fq_classlike_name = $called_fq_classlike_name;
        $this->called_method_name_lowercase = $called_method_name_lowercase;
    }
    public function getSource() : StatementsSource
    {
        return $this->source;
    }
    public function getFqClasslikeName() : string
    {
        return $this->fq_classlike_name;
    }
    /**
     * @return lowercase-string
     */
    public function getMethodNameLowercase() : string
    {
        return $this->method_name_lowercase;
    }
    /**
     * @return list<PhpParser\Node\Arg>
     */
    public function getCallArgs() : array
    {
        return $this->stmt->getArgs();
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getCodeLocation() : CodeLocation
    {
        return $this->code_location;
    }
    /**
     * @return non-empty-list<Union>|null
     */
    public function getTemplateTypeParameters() : ?array
    {
        return $this->template_type_parameters;
    }
    public function getCalledFqClasslikeName() : ?string
    {
        return $this->called_fq_classlike_name;
    }
    /**
     * @return lowercase-string|null
     */
    public function getCalledMethodNameLowercase() : ?string
    {
        return $this->called_method_name_lowercase;
    }
    /**
     * @return PhpParser\Node\Expr\MethodCall|PhpParser\Node\Expr\StaticCall
     */
    public function getStmt()
    {
        return $this->stmt;
    }
}
<?php

namespace Psalm\Plugin\EventHandler\Event;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr;
use Psalm\Codebase;
use Psalm\Context;
use Psalm\StatementsSource;
final class AddRemoveTaintsEvent
{
    private Expr $expr;
    private Context $context;
    private StatementsSource $statements_source;
    private Codebase $codebase;
    /**
     * Called after an expression has been checked
     *
     * @internal
     */
    public function __construct(Expr $expr, Context $context, StatementsSource $statements_source, Codebase $codebase)
    {
        $this->expr = $expr;
        $this->context = $context;
        $this->statements_source = $statements_source;
        $this->codebase = $codebase;
    }
    public function getExpr() : Expr
    {
        return $this->expr;
    }
    public function getContext() : Context
    {
        return $this->context;
    }
    public function getStatementsSource() : StatementsSource
    {
        return $this->statements_source;
    }
    public function getCodebase() : Codebase
    {
        return $this->codebase;
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\DynamicFunctionStorage;
use Psalm\Plugin\EventHandler\Event\DynamicFunctionStorageProviderEvent;
interface DynamicFunctionStorageProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array;
    public static function getFunctionStorage(DynamicFunctionStorageProviderEvent $event) : ?DynamicFunctionStorage;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterExpressionAnalysisEvent;
interface AfterExpressionAnalysisInterface
{
    /**
     * Called after an expression has been checked
     *
     * @return null|false
     */
    public static function afterExpressionAnalysis(AfterExpressionAnalysisEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\MethodExistenceProviderEvent;
interface MethodExistenceProviderInterface
{
    /**
     * @return array<string>
     */
    public static function getClassLikeNames() : array;
    /**
     * Use this hook for informing whether or not a method exists on a given object. If you know the method does
     * not exist, return false. If you aren't sure if it exists or not, return null and the default analysis will
     * continue to determine if the method actually exists.
     */
    public static function doesMethodExist(MethodExistenceProviderEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterFunctionLikeAnalysisEvent;
interface AfterFunctionLikeAnalysisInterface
{
    /**
     * Called after a statement has been checked
     *
     * @return null|false
     */
    public static function afterStatementAnalysis(AfterFunctionLikeAnalysisEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterClassLikeExistenceCheckEvent;
interface AfterClassLikeExistenceCheckInterface
{
    public static function afterClassLikeExistenceCheck(AfterClassLikeExistenceCheckEvent $event) : void;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterMethodCallAnalysisEvent;
interface AfterMethodCallAnalysisInterface
{
    public static function afterMethodCallAnalysis(AfterMethodCallAnalysisEvent $event) : void;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\BeforeFileAnalysisEvent;
interface BeforeFileAnalysisInterface
{
    /**
     * Called before a file has been checked
     */
    public static function beforeAnalyzeFile(BeforeFileAnalysisEvent $event) : void;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
interface AddTaintsInterface
{
    /**
     * Called to see what taints should be added
     *
     * @return list<string>
     */
    public static function addTaints(AddRemoveTaintsEvent $event) : array;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Type\Union;
interface FunctionReturnTypeProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array;
    /**
     * Use this hook for providing custom return type logic. If this plugin does not know what a function should
     * return but another plugin may be able to determine the type, return null. Otherwise return a mixed union type
     * if something should be returned, but can't be more specific.
     */
    public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event) : ?Union;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\MethodParamsProviderEvent;
use Psalm\Storage\FunctionLikeParameter;
interface MethodParamsProviderInterface
{
    /**
     * @return array<string>
     */
    public static function getClassLikeNames() : array;
    /**
     * @return ?array<int, FunctionLikeParameter>
     */
    public static function getMethodParams(MethodParamsProviderEvent $event) : ?array;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterEveryFunctionCallAnalysisEvent;
interface AfterEveryFunctionCallAnalysisInterface
{
    public static function afterEveryFunctionCallAnalysis(AfterEveryFunctionCallAnalysisEvent $event) : void;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\MethodVisibilityProviderEvent;
interface MethodVisibilityProviderInterface
{
    /**
     * @return array<string>
     */
    public static function getClassLikeNames() : array;
    public static function isMethodVisible(MethodVisibilityProviderEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\PropertyVisibilityProviderEvent;
interface PropertyVisibilityProviderInterface
{
    /**
     * @return array<string>
     */
    public static function getClassLikeNames() : array;
    public static function isPropertyVisible(PropertyVisibilityProviderEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\PropertyExistenceProviderEvent;
interface PropertyExistenceProviderInterface
{
    /**
     * @return array<string>
     */
    public static function getClassLikeNames() : array;
    /**
     * Use this hook for informing whether or not a property exists on a given object. If you know the property does
     * not exist, return false. If you aren't sure if it exists or not, return null and the default analysis will
     * continue to determine if the property actually exists.
     */
    public static function doesPropertyExist(PropertyExistenceProviderEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\StringInterpreterEvent;
use Psalm\Type\Atomic\TLiteralString;
interface StringInterpreterInterface
{
    /**
     * Called after a statement has been checked
     */
    public static function getTypeFromValue(StringInterpreterEvent $event) : ?TLiteralString;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\FunctionExistenceProviderEvent;
interface FunctionExistenceProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array;
    /**
     * Use this hook for informing whether or not a global function exists. If you know the function does
     * not exist, return false. If you aren't sure if it exists or not, return null and the default analysis
     * will continue to determine if the function actually exists.
     */
    public static function doesFunctionExist(FunctionExistenceProviderEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent;
use Psalm\Type\Union;
interface MethodReturnTypeProviderInterface
{
    /**
     * @return array<string>
     */
    public static function getClassLikeNames() : array;
    /**
     * Use this hook for providing custom return type logic. If this plugin does not know what a method should return
     * but another plugin may be able to determine the type, return null. Otherwise return a mixed union type if
     * something should be returned, but can't be more specific.
     */
    public static function getMethodReturnType(MethodReturnTypeProviderEvent $event) : ?Union;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\FunctionParamsProviderEvent;
use Psalm\Storage\FunctionLikeParameter;
interface FunctionParamsProviderInterface
{
    /**
     * @return array<lowercase-string>
     */
    public static function getFunctionIds() : array;
    /**
     * @return ?array<int, FunctionLikeParameter>
     */
    public static function getFunctionParams(FunctionParamsProviderEvent $event) : ?array;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterFunctionCallAnalysisEvent;
interface AfterFunctionCallAnalysisInterface
{
    public static function afterFunctionCallAnalysis(AfterFunctionCallAnalysisEvent $event) : void;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
interface RemoveTaintsInterface
{
    /**
     * Called to see what taints should be removed
     *
     * @return list<string>
     */
    public static function removeTaints(AddRemoveTaintsEvent $event) : array;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterCodebasePopulatedEvent;
interface AfterCodebasePopulatedInterface
{
    /**
     * Called after codebase has been populated
     *
     * @return void
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ReturnTypeHint
     */
    public static function afterCodebasePopulated(AfterCodebasePopulatedEvent $event);
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\BeforeStatementAnalysisEvent;
interface BeforeStatementAnalysisInterface
{
    /**
     * Called before a statement has been checked
     *
     * @return null|false Whether to continue
     *  + `null` continues with next event handler
     *  + `false` stops analyzing current statement in StatementsAnalyzer
     */
    public static function beforeStatementAnalysis(BeforeStatementAnalysisEvent $event) : ?bool;
}
<?php

namespace Psalm\Plugin\EventHandler;

use Psalm\Plugin\EventHandler\Event\AfterStatementAnalysisEvent;
interface AfterStatementAnalysisInterface
{
    /**
     * Called after a statement has been checked
     *
     * @return null|false
     */
    public static function afterStatementAnalysis(AfterStatementAnalysisEvent $event) : ?bool;
}
<?php

declare (strict_types=1);
namespace Psalm\Plugin;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Context;
use Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Type;
use Psalm\Type\Union;
final class ArgTypeInferer
{
    private Context $context;
    private StatementsAnalyzer $statements_analyzer;
    /**
     * @internal
     */
    public function __construct(Context $context, StatementsAnalyzer $statements_analyzer)
    {
        $this->context = $context;
        $this->statements_analyzer = $statements_analyzer;
    }
    /**
     * @return false|Union
     */
    public function infer(PhpParser\Node\Arg $arg)
    {
        $already_inferred_type = $this->statements_analyzer->node_data->getType($arg->value);
        if ($already_inferred_type) {
            return $already_inferred_type;
        }
        if (ExpressionAnalyzer::analyze($this->statements_analyzer, $arg->value, $this->context) === \false) {
            return \false;
        }
        return $this->statements_analyzer->node_data->getType($arg->value) ?? Type::getMixed();
    }
}
<?php

namespace Psalm\Plugin;

interface PluginInterface
{
}
<?php

namespace Psalm\Plugin;

interface RegistrationInterface
{
    public function addStubFile(string $file_name) : void;
    /**
     * @param class-string $handler
     */
    public function registerHooksFromClass(string $handler) : void;
}
<?php

namespace Psalm\Plugin;

use BadMethodCallException;
use Psalm\Config;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Plugin\EventHandler\AfterAnalysisInterface;
use Psalm\Plugin\EventHandler\Event\AfterAnalysisEvent;
use function array_filter;
use function array_merge;
use function array_values;
use function curl_close;
use function curl_exec;
use function curl_getinfo;
use function curl_init;
use function curl_setopt;
use function function_exists;
use function fwrite;
use function is_array;
use function is_int;
use function is_string;
use function json_encode;
use function parse_url;
use function strip_tags;
use function strlen;
use const CURLINFO_HEADER_OUT;
use const CURLOPT_FOLLOWLOCATION;
use const CURLOPT_HTTPHEADER;
use const CURLOPT_POST;
use const CURLOPT_POSTFIELDS;
use const CURLOPT_RETURNTRANSFER;
use const JSON_THROW_ON_ERROR;
use const PHP_EOL;
use const PHP_URL_HOST;
use const PHP_URL_SCHEME;
use const STDERR;
final class Shepherd implements AfterAnalysisInterface
{
    /**
     * Called after analysis is complete
     */
    public static function afterAnalysis(AfterAnalysisEvent $event) : void
    {
        $codebase = $event->getCodebase();
        $issues = $event->getIssues();
        $build_info = $event->getBuildInfo();
        $source_control_info = $event->getSourceControlInfo();
        if (!function_exists('curl_init')) {
            fwrite(STDERR, 'No curl found, cannot send data to ' . $codebase->config->shepherd_host . PHP_EOL);
            return;
        }
        $source_control_data = $source_control_info ? $source_control_info->toArray() : [];
        if (!$source_control_data && isset($build_info['git']) && is_array($build_info['git'])) {
            $source_control_data = $build_info['git'];
        }
        unset($build_info['git']);
        if ($build_info) {
            $normalized_data = $issues === [] ? [] : array_filter(array_merge(...array_values($issues)), static fn(IssueData $i): bool => $i->severity === 'error');
            $data = ['build' => $build_info, 'git' => $source_control_data, 'issues' => $normalized_data, 'coverage' => $codebase->analyzer->getTotalTypeCoverage($codebase), 'level' => Config::getInstance()->level];
            $payload = json_encode($data, JSON_THROW_ON_ERROR);
            /** @psalm-suppress DeprecatedProperty */
            $base_address = $codebase->config->shepherd_host;
            if (parse_url($base_address, PHP_URL_SCHEME) === null) {
                $base_address = 'https://' . $base_address;
            }
            // Prepare new cURL resource
            $ch = curl_init($base_address . '/hooks/psalm');
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, \true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, \true);
            curl_setopt($ch, CURLINFO_HEADER_OUT, \true);
            curl_setopt($ch, CURLOPT_POST, \true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            // Set HTTP Header for POST request
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Content-Length: ' . strlen($payload)]);
            // Submit the POST request
            $curl_result = curl_exec($ch);
            /** @var array{http_code: int, ssl_verify_result: int} $curl_info */
            $curl_info = curl_getinfo($ch);
            // Close cURL session handle
            curl_close($ch);
            $response_status_code = $curl_info['http_code'];
            if ($response_status_code >= 200 && $response_status_code < 300) {
                $shepherd_host = parse_url($codebase->config->shepherd_endpoint, PHP_URL_HOST);
                fwrite(STDERR, "🐑 results sent to {$shepherd_host} 🐑" . PHP_EOL);
                return;
            }
            $is_ssl_error = $curl_info['ssl_verify_result'] > 1;
            if ($is_ssl_error) {
                fwrite(STDERR, self::getCurlSslErrorMessage($curl_info['ssl_verify_result']) . PHP_EOL);
                return;
            }
            fwrite(STDERR, "Shepherd error: server responded with {$response_status_code} HTTP status code.\n");
            $response_content = is_string($curl_result) ? strip_tags($curl_result) : 'n/a';
            fwrite(STDERR, "Shepherd response: {$response_content}\n");
        }
    }
    /**
     * @param mixed $ch
     * @psalm-pure
     * @deprecated Will be removed in Psalm 6
     */
    public static function getCurlErrorMessage($ch) : string
    {
        /**
         * @psalm-suppress MixedArgument
         * @var array
         */
        $curl_info = curl_getinfo($ch);
        /** @psalm-suppress MixedAssignment */
        $ssl_verify_result = $curl_info['ssl_verify_result'] ?? null;
        if (is_int($ssl_verify_result) && $ssl_verify_result > 1) {
            return self::getCurlSslErrorMessage($ssl_verify_result);
        }
        return '';
    }
    /**
     * @psalm-pure
     */
    private static function getCurlSslErrorMessage(int $ssl_verify_result) : string
    {
        switch ($ssl_verify_result) {
            case 1:
                throw new BadMethodCallException('code 1 means a successful SSL response, there is no error to parse');
            case 2:
                return 'unable to get issuer certificate';
            case 3:
                return 'unable to get certificate CRL';
            case 4:
                return 'unable to decrypt certificate’s signature';
            case 5:
                return 'unable to decrypt CRL’s signature';
            case 6:
                return 'unable to decode issuer public key';
            case 7:
                return 'certificate signature failure';
            case 8:
                return 'CRL signature failure';
            case 9:
                return 'certificate is not yet valid';
            case 10:
                return 'certificate has expired';
            case 11:
                return 'CRL is not yet valid';
            case 12:
                return 'CRL has expired';
            case 13:
                return 'format error in certificate’s notBefore field';
            case 14:
                return 'format error in certificate’s notAfter field';
            case 15:
                return 'format error in CRL’s lastUpdate field';
            case 16:
                return 'format error in CRL’s nextUpdate field';
            case 17:
                return 'out of memory';
            case 18:
                return 'self signed certificate';
            case 19:
                return 'self signed certificate in certificate chain';
            case 20:
                return 'unable to get local issuer certificate';
            case 21:
                return 'unable to verify the first certificate';
            case 22:
                return 'certificate chain too long';
            case 23:
                return 'certificate revoked';
            case 24:
                return 'invalid CA certificate';
            case 25:
                return 'path length constraint exceeded';
            case 26:
                return 'unsupported certificate purpose';
            case 27:
                return 'certificate not trusted';
            case 28:
                return 'certificate rejected';
            case 29:
                return 'subject issuer mismatch';
            case 30:
                return 'authority and subject key identifier mismatch';
            case 31:
                return 'authority and issuer serial number mismatch';
            case 32:
                return 'key usage does not include certificate signing';
            case 50:
                return 'application verification failure';
            default:
                return "unknown cURL SSL error {$ssl_verify_result}";
        }
    }
}
<?php

namespace Psalm;

use DOMDocument;
use DOMElement;
use Psalm\Exception\ConfigException;
use Psalm\Internal\Analyzer\IssueData;
use Psalm\Internal\Provider\FileProvider;
use RuntimeException;
use function array_filter;
use function array_intersect;
use function array_map;
use function array_merge;
use function array_reduce;
use function array_values;
use function get_loaded_extensions;
use function implode;
use function ksort;
use function min;
use function phpversion;
use function preg_replace_callback;
use function sort;
use function sprintf;
use function str_replace;
use function trim;
use function usort;
use const LIBXML_NOBLANKS;
use const PHP_VERSION;
final class ErrorBaseline
{
    /**
     * @param array<string,array<string,array{o:int, s:array<int, string>}>> $existingIssues
     * @psalm-pure
     */
    public static function countTotalIssues(array $existingIssues) : int
    {
        $totalIssues = 0;
        foreach ($existingIssues as $existingIssue) {
            $totalIssues += array_reduce(
                $existingIssue,
                /**
                 * @param array{o:int, s:array<int, string>} $existingIssue
                 */
                static fn(int $carry, array $existingIssue): int => $carry + $existingIssue['o'],
                0
            );
        }
        return $totalIssues;
    }
    /**
     * @param array<string, list<IssueData>> $issues
     */
    public static function create(FileProvider $fileProvider, string $baselineFile, array $issues, bool $include_php_versions) : void
    {
        $groupedIssues = self::countIssueTypesByFile($issues);
        self::writeToFile($fileProvider, $baselineFile, $groupedIssues, $include_php_versions);
    }
    /**
     * @return array<string,array<string,array{o:int, s: list<string>}>>
     * @throws ConfigException
     */
    public static function read(FileProvider $fileProvider, string $baselineFile) : array
    {
        if (!$fileProvider->fileExists($baselineFile)) {
            throw new ConfigException("{$baselineFile} does not exist or is not readable");
        }
        $xmlSource = $fileProvider->getContents($baselineFile);
        if ($xmlSource === '') {
            throw new ConfigException('Baseline file is empty');
        }
        $baselineDoc = new DOMDocument();
        $baselineDoc->loadXML($xmlSource, LIBXML_NOBLANKS);
        $filesElement = $baselineDoc->getElementsByTagName('files');
        if ($filesElement->length === 0) {
            throw new ConfigException('Baseline file does not contain <files>');
        }
        $files = [];
        /** @var DOMElement $filesElement */
        $filesElement = $filesElement[0];
        foreach ($filesElement->getElementsByTagName('file') as $file) {
            $fileName = $file->getAttribute('src');
            $fileName = str_replace('\\', '/', $fileName);
            $files[$fileName] = [];
            foreach ($file->childNodes as $issue) {
                if (!$issue instanceof DOMElement) {
                    continue;
                }
                $issueType = $issue->tagName;
                $files[$fileName][$issueType] = ['o' => 0, 's' => []];
                $codeSamples = $issue->getElementsByTagName('code');
                foreach ($codeSamples as $codeSample) {
                    $files[$fileName][$issueType]['o'] += 1;
                    $files[$fileName][$issueType]['s'][] = trim($codeSample->textContent);
                }
                // TODO: Remove in Psalm 6
                $occurrencesAttr = $issue->getAttribute('occurrences');
                if ($occurrencesAttr !== '') {
                    $files[$fileName][$issueType]['o'] = (int) $occurrencesAttr;
                }
            }
        }
        return $files;
    }
    /**
     * @param array<string, list<IssueData>> $issues
     * @return array<string, array<string, array{o: int, s: list<string>}>>
     * @throws ConfigException
     */
    public static function update(FileProvider $fileProvider, string $baselineFile, array $issues, bool $include_php_versions) : array
    {
        $existingIssues = self::read($fileProvider, $baselineFile);
        $newIssues = self::countIssueTypesByFile($issues);
        foreach ($existingIssues as $file => &$existingIssuesCount) {
            if (!isset($newIssues[$file])) {
                unset($existingIssues[$file]);
                continue;
            }
            foreach ($existingIssuesCount as $issueType => $existingIssueType) {
                if (!isset($newIssues[$file][$issueType])) {
                    unset($existingIssuesCount[$issueType]);
                    continue;
                }
                $existingIssuesCount[$issueType]['o'] = min($existingIssueType['o'], $newIssues[$file][$issueType]['o']);
                $existingIssuesCount[$issueType]['s'] = array_intersect($existingIssueType['s'], $newIssues[$file][$issueType]['s']);
            }
        }
        $groupedIssues = array_filter($existingIssues);
        self::writeToFile($fileProvider, $baselineFile, $groupedIssues, $include_php_versions);
        return $groupedIssues;
    }
    /**
     * @param array<string, list<IssueData>> $issues
     * @return array<string,array<string,array{o:int, s:array<int, string>}>>
     */
    private static function countIssueTypesByFile(array $issues) : array
    {
        if ($issues === []) {
            return [];
        }
        $groupedIssues = array_reduce(
            array_merge(...array_values($issues)),
            /**
             * @param array<string,array<string,array{o:int, s:array<int, string>}>> $carry
             * @return array<string,array<string,array{o:int, s:array<int, string>}>>
             */
            static function (array $carry, IssueData $issue) : array {
                if ($issue->severity !== \Psalm\Config::REPORT_ERROR) {
                    return $carry;
                }
                $fileName = $issue->file_name;
                $fileName = str_replace('\\', '/', $fileName);
                $issueType = $issue->type;
                if (!isset($carry[$fileName])) {
                    $carry[$fileName] = [];
                }
                if (!isset($carry[$fileName][$issueType])) {
                    $carry[$fileName][$issueType] = ['o' => 0, 's' => []];
                }
                ++$carry[$fileName][$issueType]['o'];
                $carry[$fileName][$issueType]['s'][] = $issue->selected_text;
                return $carry;
            },
            []
        );
        // Sort files first
        ksort($groupedIssues);
        foreach ($groupedIssues as &$issues) {
            ksort($issues);
        }
        unset($issues);
        return $groupedIssues;
    }
    /**
     * @param array<string,array<string,array{o:int, s:array<int, string>}>> $groupedIssues
     */
    private static function writeToFile(FileProvider $fileProvider, string $baselineFile, array $groupedIssues, bool $include_php_versions) : void
    {
        $baselineDoc = new DOMDocument('1.0', 'UTF-8');
        $filesNode = $baselineDoc->createElement('files');
        $filesNode->setAttribute('psalm-version', \PSALM_VERSION);
        if ($include_php_versions) {
            $extensions = [...get_loaded_extensions(), ...get_loaded_extensions(\true)];
            usort($extensions, 'strnatcasecmp');
            $filesNode->setAttribute('php-version', implode(';' . "\n\t", [...['php:' . PHP_VERSION], ...array_map(static fn(string $extension): string => $extension . ':' . phpversion($extension), $extensions)]));
        }
        foreach ($groupedIssues as $file => $issueTypes) {
            $fileNode = $baselineDoc->createElement('file');
            $fileNode->setAttribute('src', $file);
            foreach ($issueTypes as $issueType => $existingIssueType) {
                $issueNode = $baselineDoc->createElement($issueType);
                sort($existingIssueType['s']);
                foreach ($existingIssueType['s'] as $selection) {
                    $codeNode = $baselineDoc->createElement('code');
                    $codeNode->textContent = trim($selection);
                    $issueNode->appendChild($codeNode);
                }
                $fileNode->appendChild($issueNode);
            }
            $filesNode->appendChild($fileNode);
        }
        $baselineDoc->appendChild($filesNode);
        $baselineDoc->formatOutput = \true;
        $xml = preg_replace_callback(
            '/<files (psalm-version="[^"]+") php-version="(.+)"(\\/?>)\\n/',
            /**
             * @param string[] $matches
             */
            static fn(array $matches): string => sprintf("<files\n  %s\n  php-version=\"\n    %s\n  \"\n%s\n", $matches[1], str_replace('&#10;&#9;', "\n    ", $matches[2]), $matches[3]),
            $baselineDoc->saveXML()
        );
        if ($xml === null) {
            throw new RuntimeException('Failed to reformat opening attributes!');
        }
        $fileProvider->setContents($baselineFile, $xml);
    }
}
<?php

namespace Psalm\CodeLocation;

use Psalm\CodeLocation;
use function substr;
use function substr_count;
/** @psalm-immutable */
class Raw extends CodeLocation
{
    public function __construct(string $file_contents, string $file_path, string $file_name, int $file_start, int $file_end)
    {
        $this->file_start = $file_start;
        $this->file_end = $file_end;
        $this->raw_file_start = $this->file_start;
        $this->raw_file_end = $this->file_end;
        $this->file_path = $file_path;
        $this->file_name = $file_name;
        $this->single_line = \false;
        $this->preview_start = $this->file_start;
        $this->raw_line_number = substr_count(substr($file_contents, 0, $this->file_start), "\n") + 1;
    }
}
<?php

namespace Psalm\CodeLocation;

use Psalm\CodeLocation;
use Psalm\FileSource;
/** @psalm-immutable */
class DocblockTypeLocation extends CodeLocation
{
    public function __construct(FileSource $file_source, int $file_start, int $file_end, int $line_number)
    {
        $this->file_start = $file_start;
        // matches how CodeLocation works
        $this->file_end = $file_end - 1;
        $this->raw_file_start = $file_start;
        $this->raw_file_end = $file_end;
        $this->raw_line_number = $line_number;
        $this->file_path = $file_source->getFilePath();
        $this->file_name = $file_source->getFileName();
        $this->single_line = \false;
        $this->preview_start = $this->file_start;
        $this->docblock_line_number = $line_number;
    }
}
<?php

namespace Psalm\CodeLocation;

use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\CodeLocation;
use function substr;
use function substr_count;
/** @psalm-immutable */
class ParseErrorLocation extends CodeLocation
{
    public function __construct(PhpParser\Error $error, string $file_contents, string $file_path, string $file_name)
    {
        /** @psalm-suppress PossiblyUndefinedStringArrayOffset, ImpureMethodCall */
        $this->file_start = (int) $error->getAttributes()['startFilePos'];
        /** @psalm-suppress PossiblyUndefinedStringArrayOffset, ImpureMethodCall */
        $this->file_end = (int) $error->getAttributes()['endFilePos'];
        $this->raw_file_start = $this->file_start;
        $this->raw_file_end = $this->file_end;
        $this->file_path = $file_path;
        $this->file_name = $file_name;
        $this->single_line = \false;
        $this->preview_start = $this->file_start;
        $this->raw_line_number = substr_count(substr($file_contents, 0, $this->file_start), "\n") + 1;
    }
}
<?php

namespace Psalm;

interface FileSource
{
    /**
     * @psalm-mutation-free
     */
    public function getFileName() : string;
    /**
     * @psalm-mutation-free
     */
    public function getFilePath() : string;
    /**
     * @psalm-mutation-free
     */
    public function getRootFileName() : string;
    /**
     * @psalm-mutation-free
     */
    public function getRootFilePath() : string;
    /**
     * @psalm-mutation-free
     */
    public function getAliases() : \Psalm\Aliases;
}
<?php

namespace Psalm;

use InvalidArgumentException;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Clause;
use Psalm\Internal\ReferenceConstraint;
use Psalm\Internal\Scope\CaseScope;
use Psalm\Internal\Scope\FinallyScope;
use Psalm\Internal\Scope\LoopScope;
use Psalm\Internal\Type\AssertionReconciler;
use Psalm\Storage\FunctionLikeStorage;
use Psalm\Type\Atomic\DependentType;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Union;
use RuntimeException;
use function array_keys;
use function array_search;
use function array_shift;
use function assert;
use function count;
use function in_array;
use function is_int;
use function json_encode;
use function preg_match;
use function preg_quote;
use function preg_replace;
use function strpos;
use function strtolower;
use const JSON_THROW_ON_ERROR;
final class Context
{
    /**
     * @var array<string, Union>
     */
    public $vars_in_scope = [];
    /**
     * @var array<string, bool>
     */
    public $vars_possibly_in_scope = [];
    /**
     * Keeps track of how many times a var_in_scope has been referenced. May not be set for all $vars_in_scope.
     *
     * @var array<string, int<0, max>>
     */
    public $referenced_counts = [];
    /**
     * Maps references to referenced variables for the current scope.
     * With `$b = &$a`, this will contain `['$b' => '$a']`.
     *
     * All keys and values in this array are guaranteed to be set in $vars_in_scope.
     *
     * To check if a variable was passed or returned by reference, or
     * references an object property or array item, see Union::$by_ref.
     *
     * @var array<string, string>
     */
    public $references_in_scope = [];
    /**
     * Set of references to variables in another scope. These references will be marked as used if they are assigned to.
     *
     * @var array<string, true>
     */
    public $references_to_external_scope = [];
    /**
     * A set of globals that are referenced somewhere.
     *
     * @var array<string, true>
     */
    public $referenced_globals = [];
    /**
     * A set of references that might still be in scope from a scope likely to cause confusion. This applies
     * to references set inside a loop or if statement, since it's easy to forget about PHP's weird scope
     * rules, and assinging to a reference will change the referenced variable rather than shadowing it.
     *
     * @var array<string, CodeLocation>
     */
    public $references_possibly_from_confusing_scope = [];
    /**
     * Whether or not we're inside the conditional of an if/where etc.
     *
     * This changes whether or not the context is cloned
     *
     * @var bool
     */
    public $inside_conditional = \false;
    /**
     * Whether or not we're inside an isset call
     *
     * Inside issets Psalm is more lenient about certain things
     *
     * @var bool
     */
    public $inside_isset = \false;
    /**
     * Whether or not we're inside an unset call, where
     * we don't care about possibly undefined variables
     *
     * @var bool
     */
    public $inside_unset = \false;
    /**
     * Whether or not we're inside an class_exists call, where
     * we don't care about possibly undefined classes
     *
     * @var bool
     */
    public $inside_class_exists = \false;
    /**
     * Whether or not we're inside a function/method call
     *
     * @var bool
     */
    public $inside_call = \false;
    /**
     * Whether or not we're inside any other situation that treats a variable as used
     *
     * @var bool
     */
    public $inside_general_use = \false;
    /**
     * Whether or not we're inside a return expression
     *
     * @var bool
     */
    public $inside_return = \false;
    /**
     * Whether or not we're inside a throw
     *
     * @var bool
     */
    public $inside_throw = \false;
    /**
     * Whether or not we're inside an assignment
     *
     * @var bool
     */
    public $inside_assignment = \false;
    /**
     * Whether or not we're inside a try block.
     *
     * @var bool
     */
    public $inside_try = \false;
    /**
     * @var null|CodeLocation
     */
    public $include_location;
    /**
     * @var string|null
     * The name of the current class. Null if outside a class.
     */
    public $self;
    /**
     * @var string|null
     */
    public $parent;
    /**
     * @var bool
     */
    public $check_classes = \true;
    /**
     * @var bool
     */
    public $check_variables = \true;
    /**
     * @var bool
     */
    public $check_methods = \true;
    /**
     * @var bool
     */
    public $check_consts = \true;
    /**
     * @var bool
     */
    public $check_functions = \true;
    /**
     * A list of classes checked with class_exists
     *
     * @var array<lowercase-string,true>
     */
    public $phantom_classes = [];
    /**
     * A list of files checked with file_exists
     *
     * @var array<string,bool>
     */
    public $phantom_files = [];
    /**
     * A list of clauses in Conjunctive Normal Form
     *
     * @var list<Clause>
     */
    public $clauses = [];
    /**
     * A list of hashed clauses that have already been factored in
     *
     * @var list<string|int>
     */
    public $reconciled_expression_clauses = [];
    /**
     * Whether or not to do a deep analysis and collect mutations to this context
     *
     * @var bool
     */
    public $collect_mutations = \false;
    /**
     * Whether or not to do a deep analysis and collect initializations from private or final methods
     *
     * @var bool
     */
    public $collect_initializations = \false;
    /**
     * Whether or not to do a deep analysis and collect initializations from public non-final methods
     *
     * @var bool
     */
    public $collect_nonprivate_initializations = \false;
    /**
     * Stored to prevent re-analysing methods when checking for initialised properties
     *
     * @var array<string, bool>|null
     */
    public $initialized_methods;
    /**
     * @var array<string, Union>
     */
    public $constants = [];
    /**
     * Whether or not to track exceptions
     *
     * @var bool
     */
    public $collect_exceptions = \false;
    /**
     * A list of variables that have been referenced in conditionals
     *
     * @var array<string, bool>
     */
    public $cond_referenced_var_ids = [];
    /**
     * A list of variables that have been passed by reference (where we know their type)
     *
     * @var array<string, ReferenceConstraint>
     */
    public $byref_constraints = [];
    /**
     * A list of vars that have been assigned to
     *
     * @var array<string, int>
     */
    public $assigned_var_ids = [];
    /**
     * A list of vars that have been may have been assigned to
     *
     * @var array<string, bool>
     */
    public $possibly_assigned_var_ids = [];
    /**
     * A list of classes or interfaces that may have been thrown
     *
     * @var array<string, array<array-key, CodeLocation>>
     */
    public $possibly_thrown_exceptions = [];
    /**
     * @var bool
     */
    public $is_global = \false;
    /**
     * @var array<string, bool>
     */
    public $protected_var_ids = [];
    /**
     * If we've branched from the main scope, a byte offset for where that branch happened
     *
     * @var int|null
     */
    public $branch_point;
    /**
     * What does break mean in this context?
     *
     * 'loop' means we're breaking out of a loop,
     * 'switch' means we're breaking out of a switch
     *
     * @var list<'loop'|'switch'>
     */
    public $break_types = [];
    /**
     * @var bool
     */
    public $inside_loop = \false;
    /**
     * @var LoopScope|null
     */
    public $loop_scope;
    /**
     * @var CaseScope|null
     */
    public $case_scope;
    /**
     * @var FinallyScope|null
     */
    public $finally_scope;
    /**
     * @var Context|null
     */
    public $if_body_context;
    /**
     * @var bool
     */
    public $strict_types = \false;
    /**
     * @var string|null
     */
    public $calling_function_id;
    /**
     * @var lowercase-string|null
     */
    public $calling_method_id;
    /**
     * @var bool
     */
    public $inside_negation = \false;
    /**
     * @var bool
     */
    public $ignore_variable_property = \false;
    /**
     * @var bool
     */
    public $ignore_variable_method = \false;
    /**
     * @var bool
     */
    public $pure = \false;
    /**
     * @var bool
     * Set by @psalm-immutable
     */
    public $mutation_free = \false;
    /**
     * @var bool
     * Set by @psalm-external-mutation-free
     */
    public $external_mutation_free = \false;
    /**
     * @var bool
     */
    public $error_suppressing = \false;
    /**
     * @var bool
     */
    public $has_returned = \false;
    /**
     * @var array<string, true>
     */
    public $parent_remove_vars = [];
    /** @internal */
    public function __construct(?string $self = null)
    {
        $this->self = $self;
    }
    public function __destruct()
    {
        $this->case_scope = null;
    }
    /**
     * Updates the parent context, looking at the changes within a block and then applying those changes, where
     * necessary, to the parent context
     *
     * @param  bool        $has_leaving_statements   whether or not the parent scope is abandoned between
     *                                               $start_context and $end_context
     * @param  array<string, bool>  $updated_vars
     */
    public function update(\Psalm\Context $start_context, \Psalm\Context $end_context, bool $has_leaving_statements, array $vars_to_update, array &$updated_vars) : void
    {
        foreach ($start_context->vars_in_scope as $var_id => $old_type) {
            // this is only true if there was some sort of type negation
            if (in_array($var_id, $vars_to_update, \true)) {
                // if we're leaving, we're effectively deleting the possibility of the if types
                $new_type = !$has_leaving_statements && $end_context->hasVariable($var_id) ? $end_context->vars_in_scope[$var_id] : null;
                $existing_type = $this->vars_in_scope[$var_id] ?? null;
                if (!$existing_type) {
                    if ($new_type) {
                        $this->vars_in_scope[$var_id] = $new_type;
                        $updated_vars[$var_id] = \true;
                    }
                    continue;
                }
                // if the type changed within the block of statements, process the replacement
                // also never allow ourselves to remove all types from a union
                if ((!$new_type || !$old_type->equals($new_type)) && ($new_type || count($existing_type->getAtomicTypes()) > 1)) {
                    $existing_type = $existing_type->getBuilder()->substitute($old_type, $new_type);
                    if ($new_type && $new_type->from_docblock) {
                        $existing_type = $existing_type->setFromDocblock();
                    }
                    $existing_type = $existing_type->freeze();
                    $updated_vars[$var_id] = \true;
                }
                $this->vars_in_scope[$var_id] = $existing_type;
            }
        }
    }
    /**
     * Updates the list of possible references from a confusing scope,
     * such as a reference created in an if that might later be reused.
     */
    public function updateReferencesPossiblyFromConfusingScope(\Psalm\Context $confusing_scope_context, StatementsAnalyzer $statements_analyzer) : void
    {
        $references = $confusing_scope_context->references_in_scope + $confusing_scope_context->references_to_external_scope;
        foreach ($references as $reference_id => $_) {
            if (!isset($this->references_in_scope[$reference_id]) && !isset($this->references_to_external_scope[$reference_id]) && ($reference_location = $statements_analyzer->getFirstAppearance($reference_id))) {
                $this->references_possibly_from_confusing_scope[$reference_id] = $reference_location;
            }
        }
        $this->references_possibly_from_confusing_scope += $confusing_scope_context->references_possibly_from_confusing_scope;
    }
    /**
     * @param  array<string, Union> $new_vars_in_scope
     * @return array<string, Union>
     */
    public function getRedefinedVars(array $new_vars_in_scope, bool $include_new_vars = \false) : array
    {
        $redefined_vars = [];
        foreach ($this->vars_in_scope as $var_id => $this_type) {
            if (!isset($new_vars_in_scope[$var_id])) {
                if ($include_new_vars) {
                    $redefined_vars[$var_id] = $this_type;
                }
                continue;
            }
            $new_type = $new_vars_in_scope[$var_id];
            if (!$this_type->equals($new_type, \true, !($this_type->propagate_parent_nodes || $new_type->propagate_parent_nodes))) {
                $redefined_vars[$var_id] = $this_type;
            }
        }
        return $redefined_vars;
    }
    /**
     * @return list<string>
     */
    public static function getNewOrUpdatedVarIds(\Psalm\Context $original_context, \Psalm\Context $new_context) : array
    {
        $redefined_var_ids = [];
        foreach ($new_context->vars_in_scope as $var_id => $context_type) {
            if (!isset($original_context->vars_in_scope[$var_id]) || ($original_context->assigned_var_ids[$var_id] ?? 0) !== ($new_context->assigned_var_ids[$var_id] ?? 0) || !$original_context->vars_in_scope[$var_id]->equals($context_type)) {
                $redefined_var_ids[] = $var_id;
            }
        }
        return $redefined_var_ids;
    }
    public function remove(string $remove_var_id, bool $removeDescendents = \true) : void
    {
        if (isset($this->vars_in_scope[$remove_var_id])) {
            $existing_type = $this->vars_in_scope[$remove_var_id];
            unset($this->vars_in_scope[$remove_var_id]);
            if ($removeDescendents) {
                $this->removeDescendents($remove_var_id, $existing_type);
            }
        }
        $this->removePossibleReference($remove_var_id);
        unset($this->vars_possibly_in_scope[$remove_var_id]);
    }
    /**
     * Remove a variable from the context which might be a reference to another variable, or
     * referenced by another variable. Leaves the variable as possibly-in-scope, unlike remove().
     */
    public function removePossibleReference(string $remove_var_id) : void
    {
        if (isset($this->referenced_counts[$remove_var_id]) && $this->referenced_counts[$remove_var_id] > 0) {
            // If a referenced variable goes out of scope, we need to update the references.
            // All of the references to this variable are still references to the same value,
            // so we pick the first one and make the rest of the references point to it.
            $references = [];
            foreach ($this->references_in_scope as $reference => $referenced) {
                if ($referenced === $remove_var_id) {
                    $references[] = $reference;
                    unset($this->references_in_scope[$reference]);
                }
            }
            assert(!empty($references));
            $first_reference = array_shift($references);
            if (!empty($references)) {
                $this->referenced_counts[$first_reference] = count($references);
                foreach ($references as $reference) {
                    $this->references_in_scope[$reference] = $first_reference;
                }
            }
        }
        if (isset($this->references_in_scope[$remove_var_id])) {
            $this->decrementReferenceCount($remove_var_id);
        }
        unset($this->vars_in_scope[$remove_var_id], $this->cond_referenced_var_ids[$remove_var_id], $this->referenced_counts[$remove_var_id], $this->references_in_scope[$remove_var_id], $this->references_to_external_scope[$remove_var_id]);
    }
    /**
     * Decrement the reference count of the variable that $ref_id is referring to. This needs to
     * be done before $ref_id is changed to no longer reference its currently referenced variable,
     * for example by unsetting, reassigning to another reference, or being shadowed by a global.
     */
    public function decrementReferenceCount(string $ref_id) : void
    {
        if (!isset($this->referenced_counts[$this->references_in_scope[$ref_id]])) {
            throw new InvalidArgumentException("{$ref_id} is not a reference");
        }
        $reference_count = $this->referenced_counts[$this->references_in_scope[$ref_id]];
        if ($reference_count < 1) {
            throw new RuntimeException("Incorrect referenced count found");
        }
        --$reference_count;
        $this->referenced_counts[$this->references_in_scope[$ref_id]] = $reference_count;
    }
    /**
     * @param Clause[]             $clauses
     * @param array<string, bool>  $changed_var_ids
     * @return array{list<Clause>, list<Clause>}
     * @psalm-pure
     */
    public static function removeReconciledClauses(array $clauses, array $changed_var_ids) : array
    {
        $included_clauses = [];
        $rejected_clauses = [];
        foreach ($clauses as $c) {
            if ($c->wedge) {
                $included_clauses[] = $c;
                continue;
            }
            foreach ($c->possibilities as $key => $_) {
                if (isset($changed_var_ids[$key])) {
                    $rejected_clauses[] = $c;
                    continue 2;
                }
            }
            $included_clauses[] = $c;
        }
        return [$included_clauses, $rejected_clauses];
    }
    /**
     * @param  Clause[]               $clauses
     * @return list<Clause>
     */
    public static function filterClauses(string $remove_var_id, array $clauses, ?Union $new_type = null, ?StatementsAnalyzer $statements_analyzer = null) : array
    {
        $new_type_string = $new_type ? $new_type->getId() : '';
        $clauses_to_keep = [];
        foreach ($clauses as $clause) {
            $clause = $clause->calculateNegation();
            $quoted_remove_var_id = preg_quote($remove_var_id, '/');
            foreach ($clause->possibilities as $var_id => $_) {
                if (preg_match('/' . $quoted_remove_var_id . '[\\]\\[\\-]/', $var_id)) {
                    break 2;
                }
            }
            if (!isset($clause->possibilities[$remove_var_id]) || count($clause->possibilities[$remove_var_id]) === 1 && array_keys($clause->possibilities[$remove_var_id])[0] === $new_type_string) {
                $clauses_to_keep[] = $clause;
            } elseif ($statements_analyzer && $new_type && !$new_type->hasMixed()) {
                $type_changed = \false;
                // if the clause contains any possibilities that would be altered
                // by the new type
                foreach ($clause->possibilities[$remove_var_id] as $assertion) {
                    // if we're negating a type, we generally don't need the clause anymore
                    if ($assertion->isNegation()) {
                        $type_changed = \true;
                        break;
                    }
                    $result_type = AssertionReconciler::reconcile($assertion, $new_type, null, $statements_analyzer, \false, [], null, [], $failed_reconciliation);
                    if ($result_type->getId() !== $new_type_string) {
                        $type_changed = \true;
                        break;
                    }
                }
                if (!$type_changed) {
                    $clauses_to_keep[] = $clause;
                }
            }
        }
        return $clauses_to_keep;
    }
    public function removeVarFromConflictingClauses(string $remove_var_id, ?Union $new_type = null, ?StatementsAnalyzer $statements_analyzer = null) : void
    {
        $this->clauses = self::filterClauses($remove_var_id, $this->clauses, $new_type, $statements_analyzer);
        $this->parent_remove_vars[$remove_var_id] = \true;
    }
    /**
     * This method is used after assignments to variables to remove any existing
     * items in $vars_in_scope that are now made redundant by an update to some data
     */
    public function removeDescendents(string $remove_var_id, Union $existing_type, ?Union $new_type = null, ?StatementsAnalyzer $statements_analyzer = null) : void
    {
        $this->removeVarFromConflictingClauses($remove_var_id, $existing_type->hasMixed() || $new_type && $existing_type->from_docblock !== $new_type->from_docblock ? null : $new_type, $statements_analyzer);
        foreach ($this->vars_in_scope as $var_id => &$type) {
            if (preg_match('/' . preg_quote($remove_var_id, '/') . '[\\]\\[\\-]/', $var_id)) {
                $this->remove($var_id, \false);
            }
            $builder = null;
            foreach ($type->getAtomicTypes() as $atomic_type) {
                if ($atomic_type instanceof DependentType && $atomic_type->getVarId() === $remove_var_id) {
                    $builder ??= $type->getBuilder();
                    $builder->addType($atomic_type->getReplacement());
                }
            }
            if ($builder) {
                $type = $builder->freeze();
            }
        }
    }
    public function removeMutableObjectVars(bool $methods_only = \false) : void
    {
        $vars_to_remove = [];
        foreach ($this->vars_in_scope as $var_id => $type) {
            if ($type->has_mutations && (strpos($var_id, '->') !== \false || strpos($var_id, '::') !== \false) && (!$methods_only || strpos($var_id, '()'))) {
                $vars_to_remove[] = $var_id;
            }
        }
        if (!$vars_to_remove) {
            return;
        }
        foreach ($vars_to_remove as $var_id) {
            $this->remove($var_id, \false);
        }
        $clauses_to_keep = [];
        foreach ($this->clauses as $clause) {
            $abandon_clause = \false;
            foreach (array_keys($clause->possibilities) as $key) {
                if ((strpos($key, '->') !== \false || strpos($key, '::') !== \false) && (!$methods_only || strpos($key, '()'))) {
                    $abandon_clause = \true;
                    break;
                }
            }
            if (!$abandon_clause) {
                $clauses_to_keep[] = $clause;
            }
        }
        $this->clauses = $clauses_to_keep;
    }
    public function updateChecks(\Psalm\Context $op_context) : void
    {
        $this->check_classes = $this->check_classes && $op_context->check_classes;
        $this->check_variables = $this->check_variables && $op_context->check_variables;
        $this->check_methods = $this->check_methods && $op_context->check_methods;
        $this->check_functions = $this->check_functions && $op_context->check_functions;
        $this->check_consts = $this->check_consts && $op_context->check_consts;
    }
    public function isPhantomClass(string $class_name) : bool
    {
        return isset($this->phantom_classes[strtolower($class_name)]);
    }
    public function hasVariable(string $var_name) : bool
    {
        if (!$var_name) {
            return \false;
        }
        $stripped_var = preg_replace('/(->|\\[).*$/', '', $var_name, 1);
        if ($stripped_var !== '$this' || $var_name !== $stripped_var) {
            $this->cond_referenced_var_ids[$var_name] = \true;
        }
        return isset($this->vars_in_scope[$var_name]);
    }
    public function getScopeSummary() : string
    {
        $summary = [];
        foreach ($this->vars_possibly_in_scope as $k => $_) {
            $summary[$k] = \true;
        }
        foreach ($this->vars_in_scope as $k => $v) {
            $summary[$k] = $v->getId();
        }
        return json_encode($summary, JSON_THROW_ON_ERROR);
    }
    public function defineGlobals() : void
    {
        $globals = ['$argv' => new Union([new TArray([\Psalm\Type::getInt(), \Psalm\Type::getString()])]), '$argc' => \Psalm\Type::getInt()];
        $config = \Psalm\Config::getInstance();
        foreach ($config->globals as $global_id => $type_string) {
            $globals[$global_id] = \Psalm\Type::parseString($type_string);
        }
        foreach ($globals as $global_id => $type) {
            $this->vars_in_scope[$global_id] = $type;
            $this->vars_possibly_in_scope[$global_id] = \true;
        }
    }
    public function mergeExceptions(\Psalm\Context $other_context) : void
    {
        foreach ($other_context->possibly_thrown_exceptions as $possibly_thrown_exception => $codelocations) {
            foreach ($codelocations as $hash => $codelocation) {
                $this->possibly_thrown_exceptions[$possibly_thrown_exception][$hash] = $codelocation;
            }
        }
    }
    public function isSuppressingExceptions(StatementsAnalyzer $statements_analyzer) : bool
    {
        if (!$this->collect_exceptions) {
            return \true;
        }
        $issue_type = $this->is_global ? 'UncaughtThrowInGlobalScope' : 'MissingThrowsDocblock';
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        $suppressed_issue_position = array_search($issue_type, $suppressed_issues, \true);
        if ($suppressed_issue_position !== \false) {
            if (is_int($suppressed_issue_position)) {
                $file = $statements_analyzer->getFileAnalyzer()->getFilePath();
                \Psalm\IssueBuffer::addUsedSuppressions([$file => [$suppressed_issue_position => \true]]);
            }
            return \true;
        }
        return \false;
    }
    public function mergeFunctionExceptions(FunctionLikeStorage $function_storage, \Psalm\CodeLocation $codelocation) : void
    {
        $hash = $codelocation->getHash();
        foreach ($function_storage->throws as $possibly_thrown_exception => $_) {
            $this->possibly_thrown_exceptions[$possibly_thrown_exception][$hash] = $codelocation;
        }
    }
    public function insideUse() : bool
    {
        return $this->inside_assignment || $this->inside_return || $this->inside_call || $this->inside_general_use || $this->inside_conditional || $this->inside_throw || $this->inside_isset;
    }
}
<?php

namespace Psalm;

use Exception;
use LogicException;
use _HumbugBox1cb33d1f20f1\PhpParser;
use Psalm\Internal\Analyzer\CommentAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Storage\ImmutableNonCloneableTrait;
use UnexpectedValueException;
use function explode;
use function max;
use function mb_strcut;
use function min;
use function preg_match;
use function preg_quote;
use function preg_replace;
use function str_replace;
use function strlen;
use function strpos;
use function strrpos;
use function substr_count;
use function trim;
use const PREG_OFFSET_CAPTURE;
/**
 * @psalm-immutable
 */
class CodeLocation
{
    use ImmutableNonCloneableTrait;
    /** @var string */
    public $file_path;
    /** @var string */
    public $file_name;
    /** @var int */
    public $raw_line_number;
    private int $end_line_number = -1;
    /** @var int */
    public $raw_file_start;
    /** @var int */
    public $raw_file_end;
    /** @var int */
    protected $file_start;
    /** @var int */
    protected $file_end;
    /** @var bool */
    protected $single_line;
    /** @var int */
    protected $preview_start;
    private int $preview_end = -1;
    private int $selection_start = -1;
    private int $selection_end = -1;
    private int $column_from = -1;
    private int $column_to = -1;
    private string $snippet = '';
    private ?string $text = null;
    /** @var int|null */
    public $docblock_start;
    private ?int $docblock_start_line_number = null;
    /** @var int|null */
    protected $docblock_line_number;
    private ?int $regex_type = null;
    private bool $have_recalculated = \false;
    /** @var null|CodeLocation */
    public $previous_location;
    public const VAR_TYPE = 0;
    public const FUNCTION_RETURN_TYPE = 1;
    public const FUNCTION_PARAM_TYPE = 2;
    public const FUNCTION_PHPDOC_RETURN_TYPE = 3;
    public const FUNCTION_PHPDOC_PARAM_TYPE = 4;
    public const FUNCTION_PARAM_VAR = 5;
    public const CATCH_VAR = 6;
    public const FUNCTION_PHPDOC_METHOD = 7;
    public function __construct(\Psalm\FileSource $file_source, PhpParser\Node $stmt, ?\Psalm\CodeLocation $previous_location = null, bool $single_line = \false, ?int $regex_type = null, ?string $selected_text = null, ?int $comment_line = null)
    {
        /** @psalm-suppress ImpureMethodCall Actually mutation-free just not marked */
        $this->file_start = (int) $stmt->getAttribute('startFilePos');
        /** @psalm-suppress ImpureMethodCall Actually mutation-free just not marked */
        $this->file_end = (int) $stmt->getAttribute('endFilePos');
        $this->raw_file_start = $this->file_start;
        $this->raw_file_end = $this->file_end;
        $this->file_path = $file_source->getFilePath();
        $this->file_name = $file_source->getFileName();
        $this->single_line = $single_line;
        $this->regex_type = $regex_type;
        $this->previous_location = $previous_location;
        $this->text = $selected_text;
        /** @psalm-suppress ImpureMethodCall Actually mutation-free just not marked */
        $doc_comment = $stmt->getDocComment();
        $this->docblock_start = $doc_comment ? $doc_comment->getStartFilePos() : null;
        $this->docblock_start_line_number = $doc_comment ? $doc_comment->getStartLine() : null;
        $this->preview_start = $this->docblock_start ?: $this->file_start;
        /** @psalm-suppress ImpureMethodCall Actually mutation-free just not marked */
        $this->raw_line_number = $stmt->getLine();
        $this->docblock_line_number = $comment_line;
    }
    /**
     * @psalm-suppress PossiblyUnusedMethod Part of public API
     * @return static
     */
    public function setCommentLine(?int $line) : self
    {
        if ($line === $this->docblock_line_number) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->docblock_line_number = $line;
        return $cloned;
    }
    /**
     * @psalm-external-mutation-free
     * @psalm-suppress InaccessibleProperty Mainly used for caching
     */
    private function calculateRealLocation() : void
    {
        if ($this->have_recalculated) {
            return;
        }
        $this->have_recalculated = \true;
        $this->selection_start = $this->file_start;
        $this->selection_end = $this->file_end + 1;
        $project_analyzer = ProjectAnalyzer::getInstance();
        $codebase = $project_analyzer->getCodebase();
        $file_contents = $codebase->getFileContents($this->file_path);
        $file_length = strlen($file_contents);
        $search_limit = $this->single_line ? $this->selection_start : $this->selection_end;
        if ($search_limit <= $file_length) {
            $preview_end = strpos($file_contents, "\n", $search_limit);
        } else {
            $preview_end = \false;
        }
        // if the string didn't contain a newline
        if ($preview_end === \false) {
            $preview_end = $this->selection_end;
        }
        $this->preview_end = $preview_end;
        if ($this->docblock_line_number && $this->docblock_start_line_number && $this->preview_start < $this->selection_start) {
            $preview_lines = explode("\n", mb_strcut($file_contents, $this->preview_start, $this->selection_start - $this->preview_start - 1));
            $preview_offset = 0;
            $comment_line_offset = $this->docblock_line_number - $this->docblock_start_line_number;
            for ($i = 0; $i < $comment_line_offset; ++$i) {
                $preview_offset += strlen($preview_lines[$i]) + 1;
            }
            if (!isset($preview_lines[$i])) {
                throw new Exception('Should have offset');
            }
            $key_line = $preview_lines[$i];
            $indentation = (int) strpos($key_line, '@');
            $key_line = trim(preg_replace('@\\**/\\s*@', '', mb_strcut($key_line, $indentation)));
            $this->selection_start = $preview_offset + $indentation + $this->preview_start;
            $this->selection_end = $this->selection_start + strlen($key_line);
        }
        if ($this->regex_type !== null) {
            switch ($this->regex_type) {
                case self::VAR_TYPE:
                    $regex = '/@(?:psalm-)?var[ \\t]+' . CommentAnalyzer::TYPE_REGEX . '/';
                    break;
                case self::FUNCTION_RETURN_TYPE:
                    $regex = '/\\:\\s+(\\??\\s*[A-Za-z0-9_\\\\\\[\\]]+)/';
                    break;
                case self::FUNCTION_PARAM_TYPE:
                    $regex = '/^(\\??\\s*[A-Za-z0-9_\\\\\\[\\]]+)\\s/';
                    break;
                case self::FUNCTION_PHPDOC_RETURN_TYPE:
                    $regex = '/@(?:psalm-)?return[ \\t]+' . CommentAnalyzer::TYPE_REGEX . '/';
                    break;
                case self::FUNCTION_PHPDOC_METHOD:
                    $regex = '/@(?:psalm-)?method[ \\t]+(.*)/';
                    break;
                case self::FUNCTION_PHPDOC_PARAM_TYPE:
                    $regex = '/@(?:psalm-)?param[ \\t]+' . CommentAnalyzer::TYPE_REGEX . '/';
                    break;
                case self::FUNCTION_PARAM_VAR:
                    $regex = '/(\\$[^ ]*)/';
                    break;
                case self::CATCH_VAR:
                    $regex = '/(\\$[^ ^\\)]*)/';
                    break;
                default:
                    throw new UnexpectedValueException('Unrecognised regex type ' . $this->regex_type);
            }
            $preview_snippet = mb_strcut($file_contents, $this->selection_start, $this->selection_end - $this->selection_start);
            if ($this->text) {
                $regex = '/(' . str_replace(',', ',[ ]*', preg_quote($this->text, '/')) . ')/';
            }
            if (preg_match($regex, $preview_snippet, $matches, PREG_OFFSET_CAPTURE)) {
                if (!isset($matches[1]) || $matches[1][1] === -1) {
                    throw new LogicException("Failed to match anything to 1st capturing group, " . "or regex doesn't contain 1st capturing group, regex type " . $this->regex_type);
                }
                $this->selection_start = $this->selection_start + $matches[1][1];
                $this->selection_end = $this->selection_start + strlen($matches[1][0]);
            }
        }
        // reset preview start to beginning of line
        $this->preview_start = (int) strrpos($file_contents, "\n", min($this->preview_start, $this->selection_start) - strlen($file_contents)) + 1;
        $this->selection_start = max($this->preview_start, $this->selection_start);
        $this->selection_end = min($this->preview_end, $this->selection_end);
        if ($this->preview_end - $this->selection_end > 200) {
            $this->preview_end = (int) strrpos($file_contents, "\n", $this->selection_end + 200 - strlen($file_contents));
            // if the line is over 200 characters long
            if ($this->preview_end < $this->selection_end) {
                $this->preview_end = $this->selection_end + 50;
            }
        }
        $this->snippet = mb_strcut($file_contents, $this->preview_start, $this->preview_end - $this->preview_start);
        // text is within snippet. It's 50% faster to cut it from the snippet than from the full text
        $selection_length = $this->selection_end - $this->selection_start;
        $this->text = mb_strcut($this->snippet, $this->selection_start - $this->preview_start, $selection_length);
        // reset preview start to beginning of line
        if ($file_contents !== '') {
            $this->column_from = $this->selection_start - (int) strrpos($file_contents, "\n", $this->selection_start - strlen($file_contents));
        } else {
            $this->column_from = $this->selection_start;
        }
        $newlines = substr_count($this->text, "\n");
        if ($newlines) {
            $last_newline_pos = strrpos($file_contents, "\n", $this->selection_end - strlen($file_contents) - 1);
            $this->column_to = $this->selection_end - (int) $last_newline_pos;
        } else {
            $this->column_to = $this->column_from + strlen($this->text);
        }
        $this->end_line_number = $this->getLineNumber() + $newlines;
    }
    public function getLineNumber() : int
    {
        return $this->docblock_line_number ?: $this->raw_line_number;
    }
    public function getEndLineNumber() : int
    {
        $this->calculateRealLocation();
        return $this->end_line_number;
    }
    public function getSnippet() : string
    {
        $this->calculateRealLocation();
        return $this->snippet;
    }
    public function getSelectedText() : string
    {
        $this->calculateRealLocation();
        return (string) $this->text;
    }
    public function getColumn() : int
    {
        $this->calculateRealLocation();
        return $this->column_from;
    }
    public function getEndColumn() : int
    {
        $this->calculateRealLocation();
        return $this->column_to;
    }
    /**
     * @return array{0: int, 1: int}
     */
    public function getSelectionBounds() : array
    {
        $this->calculateRealLocation();
        return [$this->selection_start, $this->selection_end];
    }
    /**
     * @return array{0: int, 1: int}
     */
    public function getSnippetBounds() : array
    {
        $this->calculateRealLocation();
        return [$this->preview_start, $this->preview_end];
    }
    public function getHash() : string
    {
        return $this->file_name . ' ' . $this->raw_file_start . $this->raw_file_end;
    }
    public function getShortSummary() : string
    {
        return $this->file_name . ':' . $this->getLineNumber() . ':' . $this->getColumn();
    }
}
<?php

namespace Psalm;

final class Aliases
{
    /**
     * @var array<lowercase-string, string>
     */
    public $uses;
    /**
     * @var array<lowercase-string, string>
     */
    public $uses_flipped;
    /**
     * @var array<lowercase-string, non-empty-string>
     */
    public $functions;
    /**
     * @var array<lowercase-string, string>
     */
    public $functions_flipped;
    /**
     * @var array<string, string>
     */
    public $constants;
    /**
     * @var array<string, string>
     */
    public $constants_flipped;
    /** @var string|null */
    public $namespace;
    /** @var ?int */
    public $namespace_first_stmt_start;
    /** @var ?int */
    public $uses_start;
    /** @var ?int */
    public $uses_end;
    /**
     * @param array<lowercase-string, string> $uses
     * @param array<lowercase-string, non-empty-string> $functions
     * @param array<string, string> $constants
     * @param array<lowercase-string, string> $uses_flipped
     * @param array<lowercase-string, string> $functions_flipped
     * @param array<string, string> $constants_flipped
     * @internal
     * @psalm-mutation-free
     */
    public function __construct(?string $namespace = null, array $uses = [], array $functions = [], array $constants = [], array $uses_flipped = [], array $functions_flipped = [], array $constants_flipped = [])
    {
        $this->namespace = $namespace;
        $this->uses = $uses;
        $this->functions = $functions;
        $this->constants = $constants;
        $this->uses_flipped = $uses_flipped;
        $this->functions_flipped = $functions_flipped;
        $this->constants_flipped = $constants_flipped;
    }
}
<?php

namespace Psalm\Type;

abstract class TypeVisitor
{
    public const STOP_TRAVERSAL = 1;
    public const DONT_TRAVERSE_CHILDREN = 2;
    /**
     * @return self::STOP_TRAVERSAL|self::DONT_TRAVERSE_CHILDREN|null
     */
    protected abstract function enterNode(\Psalm\Type\TypeNode $type) : ?int;
    /** @psalm-external-mutation-free */
    public function traverse(\Psalm\Type\TypeNode $node) : bool
    {
        $result = $this->enterNode($node);
        if ($result === self::DONT_TRAVERSE_CHILDREN) {
            return \true;
        }
        if ($result === self::STOP_TRAVERSAL) {
            return \false;
        }
        return $node->visit($this);
    }
    /**
     * @psalm-external-mutation-free
     * @param non-empty-array<TypeNode> $nodes
     */
    public function traverseArray(array $nodes) : void
    {
        foreach ($nodes as $node) {
            if ($this->traverse($node) === \false) {
                return;
            }
        }
    }
}
<?php

namespace Psalm\Type;

interface TypeNode
{
    /** @internal Should only be used by the TypeVisitor */
    public function visit(\Psalm\Type\TypeVisitor $visitor) : bool;
    /**
     * @param static $node
     * @param-out static $node
     * @internal Should only be used by the MutableTypeVisitor
     */
    public static function visitMutable(\Psalm\Type\MutableTypeVisitor $visitor, &$node, bool $cloned) : bool;
}
<?php

namespace Psalm\Type;

use InvalidArgumentException;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Codebase\TaintFlowGraph;
use Psalm\Internal\Codebase\VariableUseGraph;
use Psalm\Internal\MethodIdentifier;
use Psalm\Internal\Type\AssertionReconciler;
use Psalm\Internal\Type\TypeExpander;
use Psalm\Issue\DocblockTypeContradiction;
use Psalm\Issue\PsalmInternalError;
use Psalm\Issue\RedundantCondition;
use Psalm\Issue\RedundantConditionGivenDocblockType;
use Psalm\Issue\RedundantPropertyInitializationCheck;
use Psalm\Issue\TypeDoesNotContainNull;
use Psalm\Issue\TypeDoesNotContainType;
use Psalm\IssueBuffer;
use Psalm\Storage\Assertion;
use Psalm\Storage\Assertion\ArrayKeyExists;
use Psalm\Storage\Assertion\Empty_;
use Psalm\Storage\Assertion\Falsy;
use Psalm\Storage\Assertion\HasArrayKey;
use Psalm\Storage\Assertion\HasIntOrStringArrayAccess;
use Psalm\Storage\Assertion\HasStringArrayAccess;
use Psalm\Storage\Assertion\IsEqualIsset;
use Psalm\Storage\Assertion\IsIdentical;
use Psalm\Storage\Assertion\IsIsset;
use Psalm\Storage\Assertion\IsNotIsset;
use Psalm\Storage\Assertion\IsNotLooselyEqual;
use Psalm\Storage\Assertion\NestedAssertions;
use Psalm\Storage\Assertion\NonEmpty;
use Psalm\Storage\Assertion\NonEmptyCountable;
use Psalm\Storage\Assertion\NotNestedAssertions;
use Psalm\Storage\Assertion\Truthy;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use ReflectionProperty;
use UnexpectedValueException;
use function array_keys;
use function array_merge;
use function array_pop;
use function array_shift;
use function array_values;
use function count;
use function explode;
use function implode;
use function is_numeric;
use function key;
use function ksort;
use function preg_match;
use function preg_quote;
use function str_replace;
use function str_split;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
class Reconciler
{
    public const RECONCILIATION_OK = 0;
    public const RECONCILIATION_REDUNDANT = 1;
    public const RECONCILIATION_EMPTY = 2;
    /** @var array<string, non-empty-list<string>> */
    private static array $broken_paths = [];
    /**
     * Takes two arrays and consolidates them, removing null values from existing types where applicable.
     * Returns a tuple of [new_types, new_references].
     *
     * @param  array<string, array<array<int, Assertion>>> $new_types
     * @param  array<string, array<array<int, Assertion>>> $active_new_types - types we can complain about
     * @param  array<string, Union> $existing_types
     * @param  array<string, string> $existing_references Maps keys of $existing_types that are references to other
     *                                                    keys of $existing_types that they are references to.
     * @param  array<string, bool>       $changed_var_ids
     * @param  array<string, bool>       $referenced_var_ids
     * @param  array<string, array<string, Union>> $template_type_map
     * @return array{array<string, Union>, array<string, string>}
     * @psalm-suppress ComplexMethod
     */
    public static function reconcileKeyedTypes(array $new_types, array $active_new_types, array $existing_types, array $existing_references, array &$changed_var_ids, array $referenced_var_ids, StatementsAnalyzer $statements_analyzer, array $template_type_map = [], bool $inside_loop = \false, ?CodeLocation $code_location = null, bool $negated = \false) : array
    {
        if (!$new_types) {
            return [$existing_types, $existing_references];
        }
        $reference_graph = [];
        if (!empty($existing_references)) {
            // PHP behaves oddly when passing an array containing references: https://bugs.php.net/bug.php?id=20993
            // To work around the issue, if there are any references, we have to recreate the array and fix the
            // references so they're properly scoped and won't affect the caller. Starting with a new array is
            // required for some unclear reason, just cloning elements of the existing array doesn't work properly.
            $old_existing_types = $existing_types;
            $existing_types = [];
            $cloned_referenceds = [];
            foreach ($existing_references as $reference => $referenced) {
                if (!isset($cloned_referenceds[$referenced])) {
                    $existing_types[$referenced] = $old_existing_types[$referenced];
                    $cloned_referenceds[$referenced] = \true;
                }
                $existing_types[$reference] =& $existing_types[$referenced];
            }
            $existing_types += $old_existing_types;
            // Build a map from reference/referenced variables to other variables with the same reference
            foreach ($existing_references as $reference => $referenced) {
                $reference_graph[$reference][$referenced] = \true;
                foreach ($reference_graph[$referenced] ?? [] as $existing_referenced => $_) {
                    $reference_graph[$existing_referenced][$reference] = \true;
                    $reference_graph[$reference][$existing_referenced] = \true;
                }
                $reference_graph[$referenced][$reference] = \true;
            }
        }
        $suppressed_issues = $statements_analyzer->getSuppressedIssues();
        $old_new_types = $new_types;
        $new_types = self::addNestedAssertions($new_types, $existing_types);
        // make sure array keys come after base keys
        ksort($new_types);
        $codebase = $statements_analyzer->getCodebase();
        foreach ($new_types as $key => $new_type_parts) {
            if (strpos($key, '::') && !strpos($key, '$') && !strpos($key, '[')) {
                continue;
            }
            $has_negation = \false;
            $has_isset = \false;
            $has_inverted_isset = \false;
            $has_truthy_or_falsy_or_empty = \false;
            $has_empty = \false;
            $has_count_check = \false;
            $is_real = ($old_new_types[$key] ?? null) === $new_type_parts;
            $is_equality = $is_real;
            foreach ($new_type_parts as $new_type_part_parts) {
                foreach ($new_type_part_parts as $new_type_part_part) {
                    if ($new_type_part_part->isNegation()) {
                        $has_negation = \true;
                    }
                    $has_isset = $has_isset || $new_type_part_part instanceof IsIsset || $new_type_part_part instanceof IsEqualIsset || $new_type_part_part instanceof ArrayKeyExists || $new_type_part_part instanceof HasStringArrayAccess;
                    $has_empty = $has_empty || $new_type_part_part instanceof Empty_;
                    $has_truthy_or_falsy_or_empty = $has_truthy_or_falsy_or_empty || $new_type_part_part instanceof NonEmpty || $new_type_part_part instanceof Truthy || $new_type_part_part instanceof Empty_ || $new_type_part_part instanceof Falsy;
                    $is_equality = $is_equality && $new_type_part_part instanceof IsIdentical;
                    $has_inverted_isset = $has_inverted_isset || $new_type_part_part instanceof IsNotIsset;
                    $has_count_check = $has_count_check || $new_type_part_part instanceof NonEmptyCountable;
                }
            }
            $did_type_exist = isset($existing_types[$key]);
            $has_object_array_access = \false;
            $result_type = $existing_types[$key] ?? self::getValueForKey($codebase, $key, $existing_types, $new_types, $code_location, $has_isset, $has_inverted_isset, $has_empty, $inside_loop, $has_object_array_access);
            if ($result_type && $result_type->isUnionEmpty()) {
                throw new InvalidArgumentException('Union::$types cannot be empty after get value for ' . $key);
            }
            $before_adjustment = $result_type;
            $failed_reconciliation = self::RECONCILIATION_OK;
            foreach ($new_type_parts as $offset => $new_type_part_parts) {
                $orred_type = null;
                foreach ($new_type_part_parts as $new_type_part_part) {
                    if ($new_type_part_part instanceof NestedAssertions || $new_type_part_part instanceof NotNestedAssertions) {
                        $data = $new_type_part_part->assertions;
                        if ($new_type_part_part instanceof NotNestedAssertions) {
                            $nested_negated = !$negated;
                        } else {
                            $nested_negated = $negated;
                        }
                        [$existing_types, $_] = self::reconcileKeyedTypes($data, $data, $existing_types, $existing_references, $changed_var_ids, $referenced_var_ids, $statements_analyzer, $template_type_map, $inside_loop, $code_location, $nested_negated);
                        $new_type_part_part = $nested_negated ? new Falsy() : new Truthy();
                    }
                    $result_type_candidate = AssertionReconciler::reconcile($new_type_part_part, $result_type, $key, $statements_analyzer, $inside_loop, $template_type_map, $code_location && isset($referenced_var_ids[$key]) && isset($active_new_types[$key][$offset]) ? $code_location : null, $suppressed_issues, $failed_reconciliation, $negated);
                    if ($result_type_candidate->isUnionEmpty()) {
                        $result_type_candidate = $result_type_candidate->getBuilder()->addType(new TNever())->freeze();
                    }
                    $orred_type = Type::combineUnionTypes($result_type_candidate, $orred_type, $codebase);
                }
                $result_type = $orred_type;
            }
            if (!$result_type) {
                throw new UnexpectedValueException('$result_type should not be null');
            }
            if (!$did_type_exist && $result_type->isNever()) {
                continue;
            }
            if ($statements_analyzer->data_flow_graph instanceof TaintFlowGraph && (!$result_type->hasScalarType() || $result_type->hasString() && !$result_type->hasLiteralString()) || $statements_analyzer->data_flow_graph instanceof VariableUseGraph) {
                if ($before_adjustment && $before_adjustment->parent_nodes) {
                    $result_type = $result_type->setParentNodes($before_adjustment->parent_nodes);
                } elseif (!$did_type_exist && $code_location) {
                    $result_type = $result_type->setParentNodes($statements_analyzer->getParentNodesForPossiblyUndefinedVariable($key));
                }
            }
            if ($before_adjustment && $before_adjustment->by_ref) {
                $result_type = $result_type->setByRef(\true);
            }
            $type_changed = !$before_adjustment || !$result_type->equals($before_adjustment) || $result_type->different || $before_adjustment->different;
            $key_parts = self::breakUpPathIntoParts($key);
            if ($type_changed || $failed_reconciliation) {
                $changed_var_ids[$key] = \true;
                if (substr($key, -1) === ']' && !$has_inverted_isset && !$has_empty && !$is_equality) {
                    self::adjustTKeyedArrayType($key_parts, $existing_types, $changed_var_ids, $result_type);
                } elseif ($key !== '$this') {
                    foreach ($existing_types as $new_key => $_) {
                        if ($new_key === $key) {
                            continue;
                        }
                        if (!isset($new_types[$new_key]) && preg_match('/' . preg_quote($key, '/') . '[\\]\\[\\-]/', $new_key) && $is_real) {
                            // Fix any references to the type before removing it.
                            $references_to_fix = array_keys($reference_graph[$new_key] ?? []);
                            if (count($references_to_fix) > 1) {
                                // Still multiple references, just remove $new_key
                                foreach ($references_to_fix as $reference_to_fix) {
                                    unset($reference_graph[$reference_to_fix][$new_key]);
                                }
                                // Set references pointing to $new_key to point
                                // to the first other reference from the same group
                                $new_primary_reference = key($reference_graph[$references_to_fix[0]]);
                                unset($existing_references[$new_primary_reference]);
                                foreach ($existing_references as $existing_reference => $existing_referenced) {
                                    if ($existing_referenced === $new_key) {
                                        $existing_references[$existing_reference] = $new_primary_reference;
                                    }
                                }
                            } elseif (count($references_to_fix) === 1) {
                                // Since reference target is going to be removed,
                                // pretend the reference is just a normal variable
                                $reference_to_fix = $references_to_fix[0];
                                unset($reference_graph[$reference_to_fix], $existing_references[$reference_to_fix]);
                            }
                            unset($existing_types[$new_key], $reference_graph[$new_key], $existing_references[$new_key]);
                        }
                    }
                }
            } elseif (!$has_negation && !$has_truthy_or_falsy_or_empty && !$has_isset) {
                $changed_var_ids[$key] = \true;
            }
            if ($failed_reconciliation === self::RECONCILIATION_EMPTY) {
                $result_type = $result_type->setProperties(['failed_reconciliation' => \true]);
            }
            if (!$has_object_array_access) {
                $existing_types[$key] = $result_type;
            }
            if (!$did_type_exist && isset($existing_types[$key]) && isset($reference_graph[$key_parts[0]])) {
                // If key is new, create references for other variables that reference the root variable.
                $reference_key_parts = $key_parts;
                foreach ($reference_graph[$key_parts[0]] as $reference => $_) {
                    $reference_key_parts[0] = $reference;
                    $reference_key = implode("", $reference_key_parts);
                    $existing_types[$reference_key] =& $existing_types[$key];
                }
            }
        }
        return [$existing_types, $existing_references];
    }
    /**
     * This generates a list of extra assertions for an assertion on a nested key.
     *
     * For example  ['$a[0]->foo->bar' => 'isset']
     *
     * generates the assertions
     *
     * [
     *     '$a' => '=int-or-string-array-access',
     *     '$a[0]' => '=isset',
     *     '$a[0]->foo' => '=isset',
     *     '$a[0]->foo->bar' => 'isset' // original assertion
     * ]
     *
     * @param array<string, array<array<int, Assertion>>> $new_types
     * @param array<string, Union> $existing_types
     * @return array<string, array<array<int, Assertion>>>
     */
    private static function addNestedAssertions(array $new_types, array $existing_types) : array
    {
        foreach ($new_types as $nk => $type) {
            if (strpos($nk, '[') || strpos($nk, '->')) {
                if ($type[0][0] instanceof IsEqualIsset || $type[0][0] instanceof IsIsset || $type[0][0] instanceof NonEmpty) {
                    $key_parts = self::breakUpPathIntoParts($nk);
                    $base_key = array_shift($key_parts);
                    if ($base_key[0] !== '$' && count($key_parts) > 2 && $key_parts[0] === '::$') {
                        $base_key .= array_shift($key_parts);
                        $base_key .= array_shift($key_parts);
                    }
                    if (!isset($existing_types[$base_key]) || $existing_types[$base_key]->isNullable()) {
                        if (!isset($new_types[$base_key])) {
                            $new_types[$base_key] = [[new IsEqualIsset()]];
                        } else {
                            $new_types[$base_key][] = [new IsEqualIsset()];
                        }
                    }
                    while ($key_parts) {
                        $divider = array_shift($key_parts);
                        if ($divider === '[') {
                            $array_key = array_shift($key_parts);
                            array_shift($key_parts);
                            $new_base_key = $base_key . '[' . $array_key . ']';
                            if (strpos($array_key, '\'') !== \false) {
                                $new_types[$base_key][] = [new HasStringArrayAccess()];
                            } else {
                                $new_types[$base_key][] = [new HasIntOrStringArrayAccess()];
                            }
                            $base_key = $new_base_key;
                            continue;
                        }
                        if ($divider === '->') {
                            $property_name = array_shift($key_parts);
                            $new_base_key = $base_key . '->' . $property_name;
                            if (!isset($new_types[$base_key])) {
                                $new_types[$base_key] = [[new IsEqualIsset()]];
                            }
                            $base_key = $new_base_key;
                        } else {
                            break;
                        }
                        if (!$key_parts) {
                            break;
                        }
                        if (!isset($new_types[$base_key])) {
                            $new_types[$base_key] = [[new IsNotLooselyEqual(new TBool())], [new IsNotLooselyEqual(new TInt())], [new IsEqualIsset()]];
                        } else {
                            $new_types[$base_key][] = [new IsNotLooselyEqual(new TBool())];
                            $new_types[$base_key][] = [new IsNotLooselyEqual(new TInt())];
                            $new_types[$base_key][] = [new IsEqualIsset()];
                        }
                    }
                }
                if ($type[0][0] instanceof ArrayKeyExists) {
                    $key_parts = self::breakUpPathIntoParts($nk);
                    if (count($key_parts) === 4 && $key_parts[1] === '[' && $key_parts[2][0] !== '\'' && !is_numeric($key_parts[2]) && strpos($key_parts[2], '::class') === strlen($key_parts[2]) - 7) {
                        if ($key_parts[0][0] === '$') {
                            if (isset($new_types[$key_parts[0]])) {
                                $new_types[$key_parts[0]][] = [new HasArrayKey($key_parts[2])];
                            } else {
                                $new_types[$key_parts[0]] = [[new HasArrayKey($key_parts[2])]];
                            }
                        }
                    }
                }
            }
        }
        return $new_types;
    }
    /**
     * @return non-empty-list<string>
     */
    public static function breakUpPathIntoParts(string $path) : array
    {
        if (isset(self::$broken_paths[$path])) {
            return self::$broken_paths[$path];
        }
        $chars = str_split($path);
        $string_char = null;
        $escape_char = \false;
        $brackets = 0;
        $parts = [''];
        $parts_offset = 0;
        for ($i = 0, $char_count = count($chars); $i < $char_count; ++$i) {
            $char = $chars[$i];
            if ($string_char) {
                if ($char === $string_char && !$escape_char) {
                    $string_char = null;
                }
                if ($char === '\\') {
                    $escape_char = !$escape_char;
                }
                $parts[$parts_offset] .= $char;
                continue;
            }
            switch ($char) {
                case '[':
                case ']':
                    $parts_offset++;
                    $parts[$parts_offset] = $char;
                    ++$parts_offset;
                    if ($char === '[') {
                        $brackets++;
                    } else {
                        $brackets--;
                    }
                    continue 2;
                case '\'':
                case '"':
                    if (!isset($parts[$parts_offset])) {
                        $parts[$parts_offset] = '';
                    }
                    $parts[$parts_offset] .= $char;
                    $string_char = $char;
                    continue 2;
                case ':':
                    if (!$brackets && $i < $char_count - 2 && $chars[$i + 1] === ':' && $chars[$i + 2] === '$') {
                        ++$i;
                        ++$i;
                        ++$parts_offset;
                        $parts[$parts_offset] = '::$';
                        ++$parts_offset;
                        continue 2;
                    }
                // fall through
                case '-':
                    if (!$brackets && $i < $char_count - 1 && $chars[$i + 1] === '>') {
                        ++$i;
                        ++$parts_offset;
                        $parts[$parts_offset] = '->';
                        ++$parts_offset;
                        continue 2;
                    }
                // fall through
                // no break
                default:
                    if (!isset($parts[$parts_offset])) {
                        $parts[$parts_offset] = '';
                    }
                    $parts[$parts_offset] .= $char;
            }
        }
        $parts = array_values($parts);
        self::$broken_paths[$path] = $parts;
        return $parts;
    }
    /**
     * Gets the type for a given (non-existent key) based on the passed keys
     *
     * @param array<string, Union>  $existing_keys
     * @param array<string,mixed>       $new_assertions
     */
    private static function getValueForKey(Codebase $codebase, string $key, array &$existing_keys, array $new_assertions, ?CodeLocation $code_location, bool $has_isset, bool $has_inverted_isset, bool $has_empty, bool $inside_loop, bool &$has_object_array_access) : ?\Psalm\Type\Union
    {
        $key_parts = self::breakUpPathIntoParts($key);
        if (count($key_parts) === 1) {
            return $existing_keys[$key_parts[0]] ?? null;
        }
        $base_key = array_shift($key_parts);
        if ($base_key[0] !== '$' && count($key_parts) > 2 && $key_parts[0] === '::$') {
            $base_key .= array_shift($key_parts);
            $base_key .= array_shift($key_parts);
        }
        if (!isset($existing_keys[$base_key])) {
            if (strpos($base_key, '::')) {
                [$fq_class_name, $const_name] = explode('::', $base_key);
                if (!$codebase->classlikes->classOrInterfaceExists($fq_class_name)) {
                    return null;
                }
                $class_constant = $codebase->classlikes->getClassConstantType($fq_class_name, $const_name, ReflectionProperty::IS_PRIVATE, null);
                if ($class_constant) {
                    $existing_keys[$base_key] = $class_constant;
                } else {
                    return null;
                }
            } else {
                return null;
            }
        }
        while ($key_parts) {
            $divider = array_shift($key_parts);
            if ($divider === '[') {
                $array_key = array_shift($key_parts);
                array_shift($key_parts);
                $new_base_key = $base_key . '[' . $array_key . ']';
                if (!isset($existing_keys[$new_base_key])) {
                    $new_base_type = null;
                    $atomic_types = $existing_keys[$base_key]->getAtomicTypes();
                    while ($atomic_types) {
                        $existing_key_type_part = array_shift($atomic_types);
                        if ($existing_key_type_part instanceof TList) {
                            $existing_key_type_part = $existing_key_type_part->getKeyedArray();
                        }
                        if ($existing_key_type_part instanceof TTemplateParam) {
                            $atomic_types = array_merge($atomic_types, $existing_key_type_part->as->getAtomicTypes());
                            continue;
                        }
                        if ($existing_key_type_part instanceof TArray) {
                            if ($has_empty) {
                                return null;
                            }
                            $new_base_type_candidate = $existing_key_type_part->type_params[1];
                            if ($new_base_type_candidate->isMixed() && !$has_isset && !$has_inverted_isset) {
                                return $new_base_type_candidate;
                            }
                            if (($has_isset || $has_inverted_isset) && isset($new_assertions[$new_base_key])) {
                                if ($has_inverted_isset && $new_base_key === $key) {
                                    $new_base_type_candidate = $new_base_type_candidate->getBuilder();
                                    $new_base_type_candidate->addType(new TNull());
                                    $new_base_type_candidate->possibly_undefined = \true;
                                    $new_base_type_candidate = $new_base_type_candidate->freeze();
                                } else {
                                    $new_base_type_candidate = $new_base_type_candidate->setPossiblyUndefined(\true);
                                }
                            }
                        } elseif ($existing_key_type_part instanceof TNull || $existing_key_type_part instanceof TFalse) {
                            $new_base_type_candidate = Type::getNull();
                            if ($existing_keys[$base_key]->ignore_nullable_issues) {
                                /** @psalm-suppress InaccessibleProperty We just created this type */
                                $new_base_type_candidate->ignore_nullable_issues = \true;
                            }
                        } elseif ($existing_key_type_part instanceof TClassStringMap) {
                            return Type::getMixed();
                        } elseif ($existing_key_type_part instanceof TNever || $existing_key_type_part instanceof TMixed && $existing_key_type_part->from_loop_isset) {
                            return Type::getMixed($inside_loop);
                        } elseif ($existing_key_type_part instanceof TString) {
                            $new_base_type_candidate = Type::getString();
                        } elseif ($existing_key_type_part instanceof TNamedObject && ($has_isset || $has_inverted_isset)) {
                            $has_object_array_access = \true;
                            unset($existing_keys[$new_base_key]);
                            return null;
                        } elseif (!$existing_key_type_part instanceof TKeyedArray) {
                            return Type::getMixed();
                        } elseif ($array_key[0] === '$' || $array_key[0] !== '\'' && !is_numeric($array_key[0])) {
                            if ($has_empty) {
                                return null;
                            }
                            $new_base_type_candidate = $existing_key_type_part->getGenericValueType();
                        } else {
                            $array_properties = $existing_key_type_part->properties;
                            $key_parts_key = str_replace('\'', '', $array_key);
                            if (!isset($array_properties[$key_parts_key])) {
                                if ($existing_key_type_part->fallback_params !== null) {
                                    $new_base_type_candidate = $existing_key_type_part->fallback_params[1]->setDifferent(\true);
                                } else {
                                    return null;
                                }
                            } else {
                                $new_base_type_candidate = $array_properties[$key_parts_key];
                            }
                        }
                        $new_base_type = Type::combineUnionTypes($new_base_type, $new_base_type_candidate, $codebase);
                        $existing_keys[$new_base_key] = $new_base_type;
                    }
                }
                $base_key = $new_base_key;
            } elseif ($divider === '->' || $divider === '::$') {
                $property_name = array_shift($key_parts);
                $new_base_key = $base_key . $divider . $property_name;
                if (!isset($existing_keys[$new_base_key])) {
                    $new_base_type = null;
                    $atomic_types = $existing_keys[$base_key]->getAtomicTypes();
                    while ($atomic_types) {
                        $existing_key_type_part = array_shift($atomic_types);
                        if ($existing_key_type_part instanceof TTemplateParam) {
                            $atomic_types = array_merge($atomic_types, $existing_key_type_part->as->getAtomicTypes());
                            continue;
                        }
                        if ($existing_key_type_part instanceof TNull) {
                            $class_property_type = Type::getNull();
                        } elseif ($existing_key_type_part instanceof TMixed || $existing_key_type_part instanceof TObject || $existing_key_type_part instanceof TNamedObject && strtolower($existing_key_type_part->value) === 'stdclass') {
                            $class_property_type = Type::getMixed();
                        } elseif ($existing_key_type_part instanceof TNamedObject) {
                            if (!$codebase->classOrInterfaceExists($existing_key_type_part->value)) {
                                $class_property_type = Type::getMixed();
                            } else {
                                if (substr($property_name, -2) === '()') {
                                    $method_id = new MethodIdentifier($existing_key_type_part->value, strtolower(substr($property_name, 0, -2)));
                                    if (!$codebase->methods->methodExists($method_id)) {
                                        return null;
                                    }
                                    $declaring_method_id = $codebase->methods->getDeclaringMethodId($method_id);
                                    if ($declaring_method_id === null) {
                                        return null;
                                    }
                                    $declaring_class = $declaring_method_id->fq_class_name;
                                    $method_return_type = $codebase->methods->getMethodReturnType($method_id, $declaring_class, null, null);
                                    if ($method_return_type) {
                                        $class_property_type = TypeExpander::expandUnion($codebase, $method_return_type, $declaring_class, $declaring_class, null);
                                    } else {
                                        $class_property_type = Type::getMixed();
                                    }
                                } else {
                                    $class_property_type = self::getPropertyType($codebase, $existing_key_type_part->value, $property_name);
                                    if (!$class_property_type) {
                                        return null;
                                    }
                                }
                            }
                        } else {
                            $class_property_type = Type::getMixed();
                        }
                        $new_base_type = Type::combineUnionTypes($new_base_type, $class_property_type, $codebase);
                        $existing_keys[$new_base_key] = $new_base_type;
                    }
                }
                $base_key = $new_base_key;
            } else {
                return null;
            }
        }
        if (!isset($existing_keys[$base_key])) {
            if ($code_location) {
                IssueBuffer::add(new PsalmInternalError('Unknown key ' . $base_key, $code_location));
            }
            return null;
        }
        return $existing_keys[$base_key];
    }
    private static function getPropertyType(Codebase $codebase, string $fq_class_name, string $property_name) : ?\Psalm\Type\Union
    {
        $property_id = $fq_class_name . '::$' . $property_name;
        if (!$codebase->properties->propertyExists($property_id, \true)) {
            $declaring_class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
            if (isset($declaring_class_storage->pseudo_property_get_types['$' . $property_name])) {
                return $declaring_class_storage->pseudo_property_get_types['$' . $property_name];
            }
            return null;
        }
        $declaring_property_class = $codebase->properties->getDeclaringClassForProperty($property_id, \true);
        if ($declaring_property_class === null) {
            return null;
        }
        $class_property_type = $codebase->properties->getPropertyType($property_id, \false, null, null);
        $declaring_class_storage = $codebase->classlike_storage_provider->get($declaring_property_class);
        if ($class_property_type) {
            return TypeExpander::expandUnion($codebase, $class_property_type, $declaring_class_storage->name, $declaring_class_storage->name, null);
        }
        return Type::getMixed();
    }
    /**
     * @param Union|MutableUnion $existing_var_type
     * @param  string[]     $suppressed_issues
     */
    protected static function triggerIssueForImpossible($existing_var_type, string $old_var_type_string, string $key, Assertion $assertion, bool $redundant, bool $negated, CodeLocation $code_location, array $suppressed_issues) : void
    {
        $assertion_string = (string) $assertion;
        $not = $assertion_string[0] === '!';
        if ($not) {
            $assertion_string = substr($assertion_string, 1);
        }
        $operator = substr($assertion_string, 0, 1);
        if ($operator === '>') {
            $assertion_string = '>= ' . substr($assertion_string, 1);
        } elseif ($operator === '<') {
            $assertion_string = '<= ' . substr($assertion_string, 1);
        }
        if ($negated) {
            $redundant = !$redundant;
            $not = !$not;
        }
        $existing_var_atomic_types = $existing_var_type->getAtomicTypes();
        $from_docblock = $existing_var_type->from_docblock || isset($existing_var_atomic_types[$assertion_string]) && $existing_var_atomic_types[$assertion_string]->from_docblock;
        if ($redundant) {
            if ($existing_var_type->from_property && ($assertion instanceof IsIsset || $assertion instanceof IsNotIsset)) {
                if ($existing_var_type->from_static_property) {
                    IssueBuffer::maybeAdd(new RedundantPropertyInitializationCheck('Static property ' . $key . ' with type ' . $old_var_type_string . ' has unexpected isset check — should it be nullable?', $code_location), $suppressed_issues);
                } else {
                    IssueBuffer::maybeAdd(new RedundantPropertyInitializationCheck('Property ' . $key . ' with type ' . $old_var_type_string . ' should already be set in the constructor', $code_location), $suppressed_issues);
                }
            } elseif ($from_docblock) {
                IssueBuffer::maybeAdd(new RedundantConditionGivenDocblockType('Docblock-defined type ' . $old_var_type_string . ' for ' . $key . ' is ' . ($not ? 'never ' : 'always ') . $assertion_string, $code_location, $old_var_type_string . ' ' . $assertion_string), $suppressed_issues);
            } else {
                IssueBuffer::maybeAdd(new RedundantCondition('Type ' . $old_var_type_string . ' for ' . $key . ' is ' . ($not ? 'never ' : 'always ') . $assertion_string, $code_location, $old_var_type_string . ' ' . $assertion_string), $suppressed_issues);
            }
        } else {
            if ($from_docblock) {
                IssueBuffer::maybeAdd(new DocblockTypeContradiction('Docblock-defined type ' . $old_var_type_string . ' for ' . $key . ' is ' . ($not ? 'always ' : 'never ') . $assertion_string, $code_location, $old_var_type_string . ' ' . $assertion_string), $suppressed_issues);
            } else {
                if ($assertion_string === 'null' && !$not) {
                    $issue = new TypeDoesNotContainNull('Type ' . $old_var_type_string . ' for ' . $key . ' is never ' . $assertion_string, $code_location, $old_var_type_string . ' ' . $assertion_string);
                } else {
                    $issue = new TypeDoesNotContainType('Type ' . $old_var_type_string . ' for ' . $key . ' is ' . ($not ? 'always ' : 'never ') . $assertion, $code_location, $old_var_type_string . ' ' . $assertion);
                }
                IssueBuffer::maybeAdd($issue, $suppressed_issues);
            }
        }
    }
    /**
     * @param  string[]                  $key_parts
     * @param  array<string, Union>  $existing_types
     * @param  array<string, bool>       $changed_var_ids
     */
    private static function adjustTKeyedArrayType(array $key_parts, array &$existing_types, array &$changed_var_ids, \Psalm\Type\Union $result_type) : void
    {
        array_pop($key_parts);
        $array_key = array_pop($key_parts);
        array_pop($key_parts);
        if ($array_key === null) {
            throw new UnexpectedValueException('Not expecting null array key');
        }
        if ($array_key[0] === '$') {
            return;
        }
        $array_key_offset = $array_key[0] === '\'' || $array_key[0] === '"' ? substr($array_key, 1, -1) : $array_key;
        $base_key = implode($key_parts);
        if (isset($existing_types[$base_key]) && $array_key_offset !== \false) {
            foreach ($existing_types[$base_key]->getAtomicTypes() as $base_atomic_type) {
                if ($base_atomic_type instanceof TList) {
                    $base_atomic_type = $base_atomic_type->getKeyedArray();
                }
                if ($base_atomic_type instanceof TKeyedArray || $base_atomic_type instanceof TArray && !$base_atomic_type->isEmptyArray() || $base_atomic_type instanceof TClassStringMap) {
                    $new_base_type = $existing_types[$base_key];
                    if ($base_atomic_type instanceof TArray) {
                        $fallback_key_type = $base_atomic_type->type_params[0];
                        $fallback_value_type = $base_atomic_type->type_params[1];
                        $base_atomic_type = new TKeyedArray([$array_key_offset => $result_type], null, $fallback_key_type->isNever() ? null : [$fallback_key_type, $fallback_value_type]);
                    } elseif ($base_atomic_type instanceof TClassStringMap) {
                        // do nothing
                    } else {
                        $properties = $base_atomic_type->properties;
                        $properties[$array_key_offset] = $result_type;
                        if ($base_atomic_type->is_list && (!is_numeric($array_key_offset) || $array_key_offset && !isset($properties[$array_key_offset - 1]))) {
                            if ($base_atomic_type->fallback_params && is_numeric($array_key_offset)) {
                                $fallback = $base_atomic_type->fallback_params[1]->setPossiblyUndefined($result_type->isNever());
                                for ($x = 0; $x < $array_key_offset; $x++) {
                                    $properties[$x] ??= $fallback;
                                }
                                ksort($properties);
                                $base_atomic_type = $base_atomic_type->setProperties($properties);
                            } else {
                                // This should actually be a paradox
                                $base_atomic_type = new TKeyedArray($properties, null, $base_atomic_type->fallback_params, \false, $base_atomic_type->from_docblock);
                            }
                        } else {
                            $base_atomic_type = $base_atomic_type->setProperties($properties);
                        }
                    }
                    $new_base_type = $new_base_type->getBuilder()->addType($base_atomic_type)->freeze();
                    $changed_var_ids[$base_key . '[' . $array_key . ']'] = \true;
                    if ($key_parts[count($key_parts) - 1] === ']') {
                        self::adjustTKeyedArrayType($key_parts, $existing_types, $changed_var_ids, $new_base_type);
                    }
                    $existing_types[$base_key] = $new_base_type;
                    break;
                }
            }
        }
    }
    protected static function refineArrayKey(\Psalm\Type\Union $key_type) : \Psalm\Type\Union
    {
        return self::refineArrayKeyInner($key_type) ?? $key_type;
    }
    private static function refineArrayKeyInner(\Psalm\Type\Union $key_type) : ?\Psalm\Type\Union
    {
        $refined = \false;
        $types = [];
        foreach ($key_type->getAtomicTypes() as $cat) {
            if ($cat instanceof TTemplateParam) {
                $as = self::refineArrayKeyInner($cat->as);
                if ($as) {
                    $refined = \true;
                    $types[] = $cat->replaceAs($as);
                } else {
                    $types[] = $cat;
                }
            } elseif ($cat instanceof TArrayKey || $cat instanceof TString || $cat instanceof TInt) {
                $types[] = $cat;
            } else {
                $refined = \true;
                $types[] = new TArrayKey();
            }
        }
        if ($refined) {
            return $key_type->getBuilder()->setTypes($types)->freeze();
        }
        return null;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a string, that is also non-empty (every string except '')
 *
 * @psalm-immutable
 */
class TNonEmptyString extends \Psalm\Type\Atomic\TString
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'string';
        }
        return 'non-empty-string';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `false` value type
 *
 * @psalm-immutable
 */
final class TFalse extends \Psalm\Type\Atomic\TBool
{
    /** @var false */
    public $value = \false;
    public function getKey(bool $include_extra = \true) : string
    {
        return 'false';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
abstract class Scalar extends Atomic
{
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \true;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Union;
/**
 * Represents a string whose value is a fully-qualified class found by get_class($var)
 *
 * @psalm-immutable
 */
final class TDependentGetClass extends \Psalm\Type\Atomic\TString implements \Psalm\Type\Atomic\DependentType
{
    /**
     * Used to hold information as to what this refers to
     *
     * @var string
     */
    public $typeof;
    /**
     * @var Union
     */
    public $as_type;
    /**
     * @param string $typeof the variable id
     */
    public function __construct(string $typeof, Union $as_type)
    {
        $this->typeof = $typeof;
        $this->as_type = $as_type;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return $this->as_type->isMixed() || $this->as_type->hasObject() ? 'class-string' : 'class-string<' . $this->as_type->getId($exact) . '>';
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'get-class-of<' . $this->typeof . (!$this->as_type->isMixed() && !$this->as_type->hasObject() ? ', ' . $this->as_type->getId() : '') . '>';
    }
    public function getVarId() : string
    {
        return $this->typeof;
    }
    public function getReplacement() : \Psalm\Type\Atomic\TClassString
    {
        return new \Psalm\Type\Atomic\TClassString();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * @psalm-immutable
 */
final class TLowercaseString extends \Psalm\Type\Atomic\TString
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'lowercase-string';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a floating point value where the exact numeric value is known.
 *
 * @psalm-immutable
 */
final class TLiteralFloat extends \Psalm\Type\Atomic\TFloat
{
    /** @var float */
    public $value;
    public function __construct(float $value, bool $from_docblock = \false)
    {
        $this->value = $value;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'float(' . $this->value . ')';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'float';
        }
        return 'float(' . $this->value . ')';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return 'float';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `trait-string` type, used to describe a string representing a valid PHP trait.
 *
 * @psalm-immutable
 */
final class TTraitString extends \Psalm\Type\Atomic\TString
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'trait-string';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return 'string';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return 'trait-string';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function array_merge;
/**
 * Represents a closure where we know the return type and params
 *
 * @psalm-immutable
 */
final class TClosure extends \Psalm\Type\Atomic\TNamedObject
{
    use \Psalm\Type\Atomic\CallableTrait;
    /** @var array<string, bool> */
    public $byref_uses = [];
    /**
     * @param list<FunctionLikeParameter> $params
     * @param array<string, bool> $byref_uses
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public function __construct(string $value = 'callable', ?array $params = null, ?Union $return_type = null, ?bool $is_pure = null, array $byref_uses = [], array $extra_types = [], bool $from_docblock = \false)
    {
        $this->value = $value;
        $this->params = $params;
        $this->return_type = $return_type;
        $this->is_pure = $is_pure;
        $this->byref_uses = $byref_uses;
        $this->extra_types = $extra_types;
        $this->from_docblock = $from_docblock;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $replaced = $this->replaceCallableTemplateTypesWithArgTypes($template_result, $codebase);
        $intersection = $this->replaceIntersectionTemplateTypesWithArgTypes($template_result, $codebase);
        if (!$replaced && !$intersection) {
            return $this;
        }
        return new static($this->value, $replaced[0] ?? $this->params, $replaced[1] ?? $this->return_type, $this->is_pure, $this->byref_uses, $intersection ?? $this->extra_types);
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $replaced = $this->replaceCallableTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        $intersection = $this->replaceIntersectionTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        if (!$replaced && !$intersection) {
            return $this;
        }
        return new static($this->value, $replaced[0] ?? $this->params, $replaced[1] ?? $this->return_type, $this->is_pure, $this->byref_uses, $intersection ?? $this->extra_types);
    }
    protected function getChildNodeKeys() : array
    {
        return array_merge(parent::getChildNodeKeys(), $this->getCallableChildNodeKeys());
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a string that has a length of 1
 *
 * @psalm-immutable
 */
final class TSingleLetter extends \Psalm\Type\Atomic\TString
{
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
interface DependentType
{
    public function getVarId() : string;
    /**
     * This returns a replacement type for when the dependent data is invalidated
     */
    public function getReplacement() : Atomic;
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `mixed` type, but empty.
 * Generated for `$x` inside the `if` statement `if (!$x) {...}` when `$x` is `mixed` outside.
 *
 * @psalm-immutable
 */
final class TEmptyMixed extends \Psalm\Type\Atomic\TMixed
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'empty-mixed';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `numeric` type that's also empty (which can also result from an `is_numeric` and `empty` check).
 *
 * @psalm-immutable
 */
final class TEmptyNumeric extends \Psalm\Type\Atomic\TNumeric
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'empty-numeric';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a `scalar` type that is also empty.
 *
 * @psalm-immutable
 */
final class TEmptyScalar extends \Psalm\Type\Atomic\TScalar
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'empty-scalar';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a `class-string` corresponding to a template parameter previously specified in a `@template` tag.
 *
 * @psalm-immutable
 */
final class TTemplateParamClass extends \Psalm\Type\Atomic\TClassString
{
    /**
     * @var string
     */
    public $param_name;
    /**
     * @var string
     */
    public $defining_class;
    public function __construct(string $param_name, string $as, ?\Psalm\Type\Atomic\TNamedObject $as_type, string $defining_class, bool $from_docblock = \false)
    {
        $this->param_name = $param_name;
        $this->as = $as;
        $this->as_type = $as_type;
        $this->defining_class = $defining_class;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'class-string<' . $this->param_name . '>';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'class-string<' . $this->param_name . ':' . $this->defining_class . ' as ' . ($this->as_type ? $this->as_type->getId($exact) : $this->as) . '>';
    }
    public function getAssertionString() : string
    {
        return 'class-string<' . $this->param_name . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $this->param_name . '::class';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function array_map;
use function implode;
/**
 * denotes a template parameter that has been previously specified in a `@template` tag.
 *
 * @psalm-immutable
 */
final class TTemplateParam extends Atomic
{
    use \Psalm\Type\Atomic\HasIntersectionTrait;
    /**
     * @var string
     */
    public $param_name;
    /**
     * @var Union
     */
    public $as;
    /**
     * @var string
     */
    public $defining_class;
    /**
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public function __construct(string $param_name, Union $extends, string $defining_class, array $extra_types = [], bool $from_docblock = \false)
    {
        $this->param_name = $param_name;
        $this->as = $extends;
        $this->defining_class = $defining_class;
        $this->extra_types = $extra_types;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @return static
     */
    public function replaceAs(Union $as) : self
    {
        if ($as === $this->as) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->as = $as;
        return $cloned;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        if ($include_extra && $this->extra_types) {
            return $this->param_name . ':' . $this->defining_class . '&' . implode('&', $this->extra_types);
        }
        return $this->param_name . ':' . $this->defining_class;
    }
    public function getAssertionString() : string
    {
        return $this->as->getId();
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return $this->param_name;
        }
        if ($this->extra_types) {
            return '(' . $this->param_name . ':' . $this->defining_class . ' as ' . $this->as->getId($exact) . ')&' . implode('&', array_map(static fn(Atomic $type): string => $type->getId($exact, \true), $this->extra_types));
        }
        return ($nested ? '(' : '') . $this->param_name . ':' . $this->defining_class . ' as ' . $this->as->getId($exact) . ($nested ? ')' : '');
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     * @return null
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return $this->as->toNamespacedString($namespace, $aliased_classes, $this_class, \true);
        }
        $intersection_types = $this->getNamespacedIntersectionTypes($namespace, $aliased_classes, $this_class, \false);
        return $this->param_name . $intersection_types;
    }
    protected function getChildNodeKeys() : array
    {
        return ['as', 'extra_types'];
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $intersection = $this->replaceIntersectionTemplateTypesWithArgTypes($template_result, $codebase);
        if (!$intersection) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->extra_types = $intersection;
        return $cloned;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `float` type, where the exact value is unknown.
 *
 * @psalm-immutable
 */
class TFloat extends \Psalm\Type\Atomic\Scalar
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'float';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70000 ? 'float' : null;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function array_values;
use function count;
use function preg_quote;
use function preg_replace;
use function stripos;
use function strpos;
use function strtolower;
/**
 * Denotes the `class-string` type, used to describe a string representing a valid PHP class.
 * The parent type from which the classes descend may or may not be specified in the constructor.
 *
 * @psalm-immutable
 */
class TClassString extends \Psalm\Type\Atomic\TString
{
    /**
     * @var string
     */
    public $as;
    public ?\Psalm\Type\Atomic\TNamedObject $as_type;
    /** @var bool */
    public $is_loaded = \false;
    /** @var bool */
    public $is_interface = \false;
    /** @var bool */
    public $is_enum = \false;
    public function __construct(string $as = 'object', ?\Psalm\Type\Atomic\TNamedObject $as_type = null, bool $is_loaded = \false, bool $is_interface = \false, bool $is_enum = \false, bool $from_docblock = \false)
    {
        $this->as = $as;
        $this->as_type = $as_type;
        $this->is_loaded = $is_loaded;
        $this->is_interface = $is_interface;
        $this->is_enum = $is_enum;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @return static
     */
    public function setAs(string $as, ?\Psalm\Type\Atomic\TNamedObject $as_type) : self
    {
        if ($this->as === $as && $this->as_type === $as_type) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->as = $as;
        $cloned->as_type = $as_type;
        return $cloned;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        if ($this->is_interface) {
            $key = 'interface-string';
        } elseif ($this->is_enum) {
            $key = 'enum-string';
        } else {
            $key = 'class-string';
        }
        return $key . ($this->as === 'object' ? '' : '<' . $this->as_type . '>');
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if ($this->is_interface) {
            $key = 'interface-string';
        } elseif ($this->is_enum) {
            $key = 'enum-string';
        } else {
            $key = 'class-string';
        }
        return ($this->is_loaded ? 'loaded-' : '') . $key . ($this->as === 'object' ? '' : '<' . $this->as_type . '>');
    }
    public function getAssertionString() : string
    {
        return 'class-string';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return 'string';
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($this->as === 'object') {
            return 'class-string';
        }
        if ($namespace && stripos($this->as, $namespace . '\\') === 0) {
            return 'class-string<' . preg_replace('/^' . preg_quote($namespace . '\\') . '/i', '', $this->as) . '>';
        }
        if (!$namespace && strpos($this->as, '\\') === \false) {
            return 'class-string<' . $this->as . '>';
        }
        if (isset($aliased_classes[strtolower($this->as)])) {
            return 'class-string<' . $aliased_classes[strtolower($this->as)] . '>';
        }
        return 'class-string<\\' . $this->as . '>';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    protected function getChildNodeKeys() : array
    {
        return $this->as_type ? ['as_type'] : [];
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        if (!$this->as_type) {
            return $this;
        }
        if ($input_type instanceof \Psalm\Type\Atomic\TLiteralClassString) {
            $input_object_type = new \Psalm\Type\Atomic\TNamedObject($input_type->value);
        } elseif ($input_type instanceof \Psalm\Type\Atomic\TClassString && $input_type->as_type) {
            $input_object_type = $input_type->as_type;
        } else {
            $input_object_type = new \Psalm\Type\Atomic\TObject();
        }
        $as_type = TemplateStandinTypeReplacer::replace(new Union([$this->as_type]), $template_result, $codebase, $statements_analyzer, new Union([$input_object_type]), $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, null, $depth);
        $as_type_types = array_values($as_type->getAtomicTypes());
        $as_type = count($as_type_types) === 1 && $as_type_types[0] instanceof \Psalm\Type\Atomic\TNamedObject ? $as_type_types[0] : null;
        if ($this->as_type === $as_type) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->as_type = $as_type;
        if (!$cloned->as_type) {
            $cloned->as = 'object';
        }
        return $cloned;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function array_keys;
use function array_map;
use function count;
use function implode;
/**
 * Denotes an object with specified member variables e.g. `object{foo:int, bar:string}`.
 *
 * @psalm-immutable
 */
final class TObjectWithProperties extends \Psalm\Type\Atomic\TObject
{
    use \Psalm\Type\Atomic\HasIntersectionTrait;
    /**
     * @var array<string|int, Union>
     */
    public $properties;
    /**
     * @var array<lowercase-string, string>
     */
    public $methods;
    /** @var bool */
    public $is_stringable_object_only = \false;
    /**
     * Constructs a new instance of a generic type
     *
     * @param array<string|int, Union> $properties
     * @param array<lowercase-string, string> $methods
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public function __construct(array $properties, array $methods = [], array $extra_types = [], bool $from_docblock = \false)
    {
        $this->properties = $properties;
        $this->methods = $methods;
        $this->extra_types = $extra_types;
        $this->from_docblock = $from_docblock;
        $this->is_stringable_object_only = $this->properties === [] && $this->methods === ['__tostring' => 'string'];
    }
    /**
     * @param array<string|int, Union> $properties
     */
    public function setProperties(array $properties) : self
    {
        if ($properties === $this->properties) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->properties = $properties;
        $cloned->is_stringable_object_only = $cloned->properties === [] && $cloned->methods === ['__tostring' => 'string'];
        return $cloned;
    }
    /**
     * @param array<lowercase-string, string> $methods
     */
    public function setMethods(array $methods) : self
    {
        if ($methods === $this->methods) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->methods = $methods;
        $cloned->is_stringable_object_only = $cloned->properties === [] && $cloned->methods === ['__tostring' => 'string'];
        return $cloned;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        $extra_types = '';
        if ($this->extra_types) {
            $extra_types = '&' . implode('&', $this->extra_types);
        }
        $properties_string = implode(', ', array_map(
            /**
             * @psalm-pure
             * @param  string|int $name
             */
            static fn($name, Union $type): string => $name . ($type->possibly_undefined ? '?' : '') . ':' . $type->getId($exact),
            array_keys($this->properties),
            $this->properties
        ));
        $methods_string = implode(', ', array_map(
            /**
             * @psalm-pure
             */
            static fn(string $name): string => $name . '()',
            array_keys($this->methods)
        ));
        return 'object{' . $properties_string . ($methods_string && $properties_string ? ', ' : '') . $methods_string . '}' . $extra_types;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return 'object';
        }
        return 'object{' . implode(', ', array_map(
            /**
             * @psalm-pure
             * @param  string|int $name
             */
            static fn($name, Union $type): string => $name . ($type->possibly_undefined ? '?' : '') . ':' . $type->toNamespacedString($namespace, $aliased_classes, $this_class, \false),
            array_keys($this->properties),
            $this->properties
        )) . '}';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return $this->getKey();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function equals(Atomic $other_type, bool $ensure_source_equality) : bool
    {
        if (!$other_type instanceof self) {
            return \false;
        }
        if (count($this->properties) !== count($other_type->properties)) {
            return \false;
        }
        if ($this->methods !== $other_type->methods) {
            return \false;
        }
        foreach ($this->properties as $property_name => $property_type) {
            if (!isset($other_type->properties[$property_name])) {
                return \false;
            }
            if (!$property_type->equals($other_type->properties[$property_name], $ensure_source_equality)) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $properties = [];
        foreach ($this->properties as $offset => $property) {
            $input_type_param = null;
            if ($input_type instanceof \Psalm\Type\Atomic\TKeyedArray && isset($input_type->properties[$offset])) {
                $input_type_param = $input_type->properties[$offset];
            }
            $properties[$offset] = TemplateStandinTypeReplacer::replace($property, $template_result, $codebase, $statements_analyzer, $input_type_param, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, null, $depth);
        }
        $intersection = $this->replaceIntersectionTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        if ($properties === $this->properties && !$intersection) {
            return $this;
        }
        return new static($properties, $this->methods, $intersection ?? $this->extra_types);
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $properties = $this->properties;
        foreach ($properties as $offset => $property) {
            $properties[$offset] = TemplateInferredTypeReplacer::replace($property, $template_result, $codebase);
        }
        $intersection = $this->replaceIntersectionTemplateTypesWithArgTypes($template_result, $codebase);
        if ($properties === $this->properties && !$intersection) {
            return $this;
        }
        return new static($properties, $this->methods, $intersection ?? $this->extra_types);
    }
    protected function getChildNodeKeys() : array
    {
        return ['properties', 'extra_types'];
    }
    public function getAssertionString() : string
    {
        return $this->getKey();
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Type that resolves to a keyed-array with properties of a class as keys and
 * their apropriate types as values.
 *
 * @psalm-type TokenName = 'properties-of'|'public-properties-of'|'protected-properties-of'|'private-properties-of'
 * @psalm-immutable
 */
final class TPropertiesOf extends Atomic
{
    // These should match the values of
    // `Psalm\Internal\Analyzer\ClassLikeAnalyzer::VISIBILITY_*`, as they are
    // used to compared against properties visibililty.
    public const VISIBILITY_PUBLIC = 1;
    public const VISIBILITY_PROTECTED = 2;
    public const VISIBILITY_PRIVATE = 3;
    public \Psalm\Type\Atomic\TNamedObject $classlike_type;
    /**
     * @var self::VISIBILITY_*|null
     */
    public $visibility_filter;
    /**
     * @return list<TokenName>
     */
    public static function tokenNames() : array
    {
        return ['properties-of', 'public-properties-of', 'protected-properties-of', 'private-properties-of'];
    }
    /**
     * @param self::VISIBILITY_*|null $visibility_filter
     */
    public function __construct(\Psalm\Type\Atomic\TNamedObject $classlike_type, ?int $visibility_filter, bool $from_docblock = \false)
    {
        $this->classlike_type = $classlike_type;
        $this->visibility_filter = $visibility_filter;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @return self::VISIBILITY_*|null
     */
    public static function filterForTokenName(string $token_name) : ?int
    {
        switch ($token_name) {
            case 'public-properties-of':
                return self::VISIBILITY_PUBLIC;
            case 'protected-properties-of':
                return self::VISIBILITY_PROTECTED;
            case 'private-properties-of':
                return self::VISIBILITY_PRIVATE;
            default:
                return null;
        }
    }
    /**
     * @psalm-pure
     * @return TokenName
     */
    public static function tokenNameForFilter(?int $visibility_filter) : string
    {
        switch ($visibility_filter) {
            case self::VISIBILITY_PUBLIC:
                return 'public-properties-of';
            case self::VISIBILITY_PROTECTED:
                return 'protected-properties-of';
            case self::VISIBILITY_PRIVATE:
                return 'private-properties-of';
            default:
                return 'properties-of';
        }
    }
    protected function getChildNodeKeys() : array
    {
        return ['classlike_type'];
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return self::tokenNameForFilter($this->visibility_filter) . '<' . $this->classlike_type . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return $this->getKey();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
/**
 * Represents the type used when using TPropertiesOf when the type of the array is a template
 *
 * @psalm-immutable
 */
final class TTemplatePropertiesOf extends Atomic
{
    /**
     * @var string
     */
    public $param_name;
    /**
     * @var string
     */
    public $defining_class;
    /**
     * @var TTemplateParam
     */
    public $as;
    /**
     * @var TPropertiesOf::VISIBILITY_*|null
     */
    public $visibility_filter;
    /**
     * @param TPropertiesOf::VISIBILITY_*|null $visibility_filter
     */
    public function __construct(string $param_name, string $defining_class, \Psalm\Type\Atomic\TTemplateParam $as, ?int $visibility_filter, bool $from_docblock = \false)
    {
        $this->param_name = $param_name;
        $this->defining_class = $defining_class;
        $this->as = $as;
        $this->visibility_filter = $visibility_filter;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return \Psalm\Type\Atomic\TPropertiesOf::tokenNameForFilter($this->visibility_filter) . '<' . $this->param_name . '>';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return $this->getKey();
        }
        return \Psalm\Type\Atomic\TPropertiesOf::tokenNameForFilter($this->visibility_filter) . '<' . $this->as->getId($exact) . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return $this->getKey();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $param = new \Psalm\Type\Atomic\TTemplateParam($this->as->param_name, TemplateInferredTypeReplacer::replace(new Union([$this->as]), $template_result, $codebase), $this->as->defining_class);
        if ($param->as === $this->as->as) {
            return $this;
        }
        return new static($this->param_name, $this->defining_class, $param, $this->visibility_filter);
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function count;
use function implode;
use function substr;
/**
 * denotes the `iterable` type(which can also result from an `is_iterable` check).
 *
 * @psalm-immutable
 */
final class TIterable extends Atomic
{
    use \Psalm\Type\Atomic\HasIntersectionTrait;
    /**
     * @use GenericTrait<array{Union, Union}>
     */
    use \Psalm\Type\Atomic\GenericTrait;
    /**
     * @var array{Union, Union}
     */
    public array $type_params;
    /**
     * @var string
     */
    public $value = 'iterable';
    /**
     * @var bool
     */
    public $has_docblock_params = \false;
    /**
     * @param array{Union, Union}|array<never, never> $type_params
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public function __construct(array $type_params = [], array $extra_types = [], bool $from_docblock = \false)
    {
        if (isset($type_params[0], $type_params[1])) {
            $this->has_docblock_params = \true;
            $this->type_params = $type_params;
        } else {
            $this->type_params = [Type::getMixed(), Type::getMixed()];
        }
        $this->extra_types = $extra_types;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        if ($include_extra && $this->extra_types) {
            // do nothing
        }
        return 'iterable';
    }
    public function getAssertionString() : string
    {
        return 'iterable';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        $s = '';
        foreach ($this->type_params as $type_param) {
            $s .= $type_param->getId($exact) . ', ';
        }
        $extra_types = '';
        if ($this->extra_types) {
            $extra_types = '&' . implode('&', $this->extra_types);
        }
        return $this->value . '<' . substr($s, 0, -2) . '>' . $extra_types;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70100 ? 'iterable' : null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return $this->type_params[0]->isMixed() && $this->type_params[1]->isMixed();
    }
    public function equals(Atomic $other_type, bool $ensure_source_equality) : bool
    {
        if (!$other_type instanceof self) {
            return \false;
        }
        if (count($this->type_params) !== count($other_type->type_params)) {
            return \false;
        }
        foreach ($this->type_params as $i => $type_param) {
            if (!$type_param->equals($other_type->type_params[$i], $ensure_source_equality)) {
                return \false;
            }
        }
        return \true;
    }
    protected function getChildNodeKeys() : array
    {
        return ['type_params', 'extra_types'];
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $type_params = $this->replaceTypeParamsTemplateTypesWithArgTypes($template_result, $codebase);
        $intersection = $this->replaceIntersectionTemplateTypesWithArgTypes($template_result, $codebase);
        return new static($type_params ?? $this->type_params, $intersection ?? $this->extra_types);
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $types = $this->replaceTypeParamsTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        $intersection = $this->replaceIntersectionTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        if (!$types && !$intersection) {
            return $this;
        }
        return new static($types ?? $this->type_params, $intersection ?? $this->extra_types);
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `numeric` type (which can also result from an `is_numeric` check).
 *
 * @psalm-immutable
 */
class TNumeric extends \Psalm\Type\Atomic\Scalar
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'numeric';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use function preg_quote;
use function preg_replace;
use function stripos;
use function strpos;
use function strtolower;
/**
 * Denotes a specific class string, generated by expressions like `A::class`.
 *
 * @psalm-immutable
 */
final class TLiteralClassString extends \Psalm\Type\Atomic\TLiteralString
{
    /**
     * Whether or not this type can represent a child of the class named in $value
     *
     * @var bool
     */
    public $definite_class = \false;
    public function __construct(string $value, bool $definite_class = \false, bool $from_docblock = \false)
    {
        parent::__construct($value, $from_docblock);
        $this->definite_class = $definite_class;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'class-string(' . $this->value . ')';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return 'string';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'class-string';
        }
        return $this->value . '::class';
    }
    public function getAssertionString() : string
    {
        return $this->getKey();
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return 'string';
        }
        if ($this->value === 'static') {
            return 'static::class';
        }
        if ($this->value === $this_class) {
            return 'self::class';
        }
        if ($namespace && stripos($this->value, $namespace . '\\') === 0) {
            return preg_replace('/^' . preg_quote($namespace . '\\') . '/i', '', $this->value) . '::class';
        }
        if (!$namespace && strpos($this->value, '\\') === \false) {
            return $this->value . '::class';
        }
        if (isset($aliased_classes[strtolower($this->value)])) {
            return $aliased_classes[strtolower($this->value)] . '::class';
        }
        return '\\' . $this->value . '::class';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
/**
 * Represents the type used when using TValueOf when the type of the array or enum is a template
 *
 * @psalm-immutable
 */
final class TTemplateValueOf extends Atomic
{
    /**
     * @var string
     */
    public $param_name;
    /**
     * @var string
     */
    public $defining_class;
    /**
     * @var Union
     */
    public $as;
    public function __construct(string $param_name, string $defining_class, Union $as, bool $from_docblock = \false)
    {
        $this->param_name = $param_name;
        $this->defining_class = $defining_class;
        $this->as = $as;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'value-of<' . $this->param_name . '>';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'value-of<' . $this->param_name . '>';
        }
        return 'value-of<' . $this->as->getId($exact) . '>';
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return 'value-of<' . $this->param_name . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $as = TemplateInferredTypeReplacer::replace($this->as, $template_result, $codebase);
        if ($as === $this->as) {
            return $this;
        }
        return new static($this->param_name, $this->defining_class, $as);
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * @deprecated Will be removed in Psalm v6, use TIntRange instead
 *
 * Represents a list key created from foreach ($list as $key => $value)
 * @psalm-immutable
 */
final class TDependentListKey extends \Psalm\Type\Atomic\TInt implements \Psalm\Type\Atomic\DependentType
{
    /**
     * Used to hold information as to what list variable this refers to
     *
     * @var string
     */
    public $var_id;
    /**
     * @param string $var_id the variable id
     */
    public function __construct(string $var_id)
    {
        $this->var_id = $var_id;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'list-key<' . $this->var_id . '>';
    }
    public function getVarId() : string
    {
        return $this->var_id;
    }
    public function getAssertionString() : string
    {
        return 'int';
    }
    public function getReplacement() : \Psalm\Type\Atomic\TInt
    {
        return new \Psalm\Type\Atomic\TInt();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function count;
use function get_class;
/**
 * Denotes a simple array of the form `array<TKey, TValue>`. It expects an array with two elements, both union types.
 *
 * @psalm-immutable
 */
class TArray extends Atomic
{
    /**
     * @use GenericTrait<array{Union, Union}>
     */
    use \Psalm\Type\Atomic\GenericTrait;
    /**
     * @var array{Union, Union}
     */
    public array $type_params;
    /**
     * @var string
     */
    public $value = 'array';
    /**
     * Constructs a new instance of a generic type
     *
     * @param array{Union, Union} $type_params
     */
    public function __construct(array $type_params, bool $from_docblock = \false)
    {
        $this->type_params = $type_params;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'array';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return $this->getKey();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return $this->type_params[0]->isArrayKey() && $this->type_params[1]->isMixed();
    }
    public function equals(Atomic $other_type, bool $ensure_source_equality) : bool
    {
        if (get_class($other_type) !== static::class) {
            return \false;
        }
        if ($this instanceof \Psalm\Type\Atomic\TNonEmptyArray && $other_type instanceof \Psalm\Type\Atomic\TNonEmptyArray && $this->count !== $other_type->count) {
            return \false;
        }
        if (count($this->type_params) !== count($other_type->type_params)) {
            return \false;
        }
        foreach ($this->type_params as $i => $type_param) {
            if (!$type_param->equals($other_type->type_params[$i], $ensure_source_equality)) {
                return \false;
            }
        }
        return \true;
    }
    public function getAssertionString() : string
    {
        if ($this->type_params[0]->isMixed() && $this->type_params[1]->isMixed()) {
            return 'array';
        }
        return $this->getId();
    }
    public function isEmptyArray() : bool
    {
        return $this->type_params[1]->isNever();
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $type_params = $this->replaceTypeParamsTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        if ($type_params) {
            $cloned = clone $this;
            $cloned->type_params = $type_params;
            return $cloned;
        }
        return $this;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $type_params = $this->replaceTypeParamsTemplateTypesWithArgTypes($template_result, $codebase);
        if ($type_params) {
            $cloned = clone $this;
            $cloned->type_params = $type_params;
            return $cloned;
        }
        return $this;
    }
    protected function getChildNodeKeys() : array
    {
        return ['type_params'];
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type;
use Psalm\Type\Atomic;
use function array_map;
use function implode;
use function strrpos;
use function substr;
/**
 * Denotes an object type where the type of the object is known e.g. `Exception`, `Throwable`, `Foo\Bar`
 *
 * @psalm-immutable
 */
class TNamedObject extends Atomic
{
    use \Psalm\Type\Atomic\HasIntersectionTrait;
    /**
     * @var string
     */
    public $value;
    /**
     * @var bool
     */
    public $is_static = \false;
    /**
     * @var bool
     */
    public $is_static_resolved = \false;
    /**
     * Whether or not this type can represent a child of the class named in $value
     *
     * @var bool
     */
    public $definite_class = \false;
    /**
     * @param string $value the name of the object
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public function __construct(string $value, bool $is_static = \false, bool $definite_class = \false, array $extra_types = [], bool $from_docblock = \false)
    {
        if ($value[0] === '\\') {
            $value = substr($value, 1);
        }
        $this->value = $value;
        $this->is_static = $is_static;
        $this->definite_class = $definite_class;
        $this->extra_types = $extra_types;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @return static
     */
    public function setIsStatic(bool $is_static, ?bool $is_static_resolved = null) : self
    {
        $is_static_resolved ??= $this->is_static_resolved;
        if ($this->is_static === $is_static && $this->is_static_resolved === $is_static_resolved) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->is_static = $is_static;
        $cloned->is_static_resolved = $is_static_resolved;
        return $cloned;
    }
    /**
     * @return static
     */
    public function setValue(string $value) : self
    {
        if ($value[0] === '\\') {
            $value = substr($value, 1);
        }
        if ($value === $this->value) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->value = $value;
        return $cloned;
    }
    /**
     * @return static
     */
    public function setValueIsStatic(string $value, bool $is_static, ?bool $is_static_resolved = null) : self
    {
        $is_static_resolved ??= $this->is_static_resolved;
        if ($value[0] === '\\') {
            $value = substr($value, 1);
        }
        if ($value === $this->value && $this->is_static === $is_static && $this->is_static_resolved === $is_static_resolved) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->value = $value;
        $cloned->is_static = $is_static;
        $cloned->is_static_resolved = $is_static;
        return $cloned;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        if ($include_extra && $this->extra_types) {
            return $this->value . '&' . implode('&', $this->extra_types);
        }
        return $this->value;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if ($this->extra_types) {
            return $this->value . '&' . implode('&', array_map(static fn(Atomic $type): string => $type->getId($exact, \true), $this->extra_types));
        }
        return $this->is_static && $exact ? $this->value . '&static' : $this->value;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($this->value === 'static') {
            return 'static';
        }
        $intersection_types = $this->getNamespacedIntersectionTypes($namespace, $aliased_classes, $this_class, $use_phpdoc_format);
        return Type::getStringFromFQCLN($this->value, $namespace, $aliased_classes, $this_class, \true, $this->is_static) . $intersection_types;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        if ($this->value === 'static') {
            return $analysis_php_version_id >= 80000 ? 'static' : null;
        }
        if ($this->is_static && $this->value === $this_class) {
            return $analysis_php_version_id >= 80000 ? 'static' : 'self';
        }
        $result = $this->toNamespacedString($namespace, $aliased_classes, $this_class, \false);
        $intersection = strrpos($result, '&');
        if ($intersection === \false || $analysis_php_version_id >= 80100) {
            return $result;
        }
        return substr($result, $intersection + 1);
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return $this->value !== 'static' && $this->is_static === \false || $analysis_php_version_id >= 80000;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $intersection = $this->replaceIntersectionTemplateTypesWithArgTypes($template_result, $codebase);
        if (!$intersection) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->extra_types = $intersection;
        return $cloned;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $intersection = $this->replaceIntersectionTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        if ($intersection) {
            $cloned = clone $this;
            $cloned->extra_types = $intersection;
            return $cloned;
        }
        return $this;
    }
    protected function getChildNodeKeys() : array
    {
        return ['extra_types'];
    }
    /**
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public static function createFromName(string $value, bool $is_static = \false, bool $definite_class = \false, array $extra_types = [], bool $from_docblock = \false) : \Psalm\Type\Atomic\TNamedObject
    {
        if ($value === 'Closure') {
            return new \Psalm\Type\Atomic\TClosure($value, null, null, null, [], $extra_types, $from_docblock);
        }
        return new \Psalm\Type\Atomic\TNamedObject($value, $is_static, $definite_class, $extra_types, $from_docblock);
    }
}
<?php

namespace Psalm\Type\Atomic;

use function max;
use function min;
/**
 * Denotes an interval of integers between two bounds
 *
 * @psalm-immutable
 */
final class TIntRange extends \Psalm\Type\Atomic\TInt
{
    public const BOUND_MIN = 'min';
    public const BOUND_MAX = 'max';
    /**
     * @var int|null
     */
    public $min_bound;
    /**
     * @var int|null
     */
    public $max_bound;
    /** @var string|null */
    public $dependent_list_key;
    public function __construct(?int $min_bound, ?int $max_bound, bool $from_docblock = \false, ?string $dependent_list_key = null)
    {
        $this->min_bound = $min_bound;
        $this->max_bound = $max_bound;
        $this->from_docblock = $from_docblock;
        $this->dependent_list_key = $dependent_list_key;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'int<' . ($this->min_bound ?? 'min') . ', ' . ($this->max_bound ?? 'max') . '>';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $use_phpdoc_format ? 'int' : 'int<' . ($this->min_bound ?? 'min') . ', ' . ($this->max_bound ?? 'max') . '>';
    }
    public function isPositive() : bool
    {
        return $this->min_bound !== null && $this->min_bound > 0;
    }
    public function isNegative() : bool
    {
        return $this->max_bound !== null && $this->max_bound < 0;
    }
    public function isPositiveOrZero() : bool
    {
        return $this->min_bound !== null && $this->min_bound >= 0;
    }
    public function isNegativeOrZero() : bool
    {
        return $this->max_bound !== null && $this->max_bound <= 0;
    }
    public function contains(int $i) : bool
    {
        return $this->min_bound === null && $this->max_bound === null || $this->min_bound === null && $this->max_bound >= $i || $this->max_bound === null && $this->min_bound <= $i || $this->min_bound <= $i && $this->max_bound >= $i;
    }
    /**
     * Returns true if every part of the Range is lesser than the given value
     */
    public function isLesserThan(int $i) : bool
    {
        return $this->max_bound !== null && $this->max_bound < $i;
    }
    /**
     * Returns true if every part of the Range is greater than the given value
     */
    public function isGreaterThan(int $i) : bool
    {
        return $this->min_bound !== null && $this->min_bound > $i;
    }
    public static function getNewLowestBound(?int $bound1, ?int $bound2) : ?int
    {
        if ($bound1 === null || $bound2 === null) {
            return null;
        }
        return min($bound1, $bound2);
    }
    public static function getNewHighestBound(?int $bound1, ?int $bound2) : ?int
    {
        if ($bound1 === null || $bound2 === null) {
            return null;
        }
        return max($bound1, $bound2);
    }
    /**
     * convert any int to its equivalent in int range
     */
    public static function convertToIntRange(\Psalm\Type\Atomic\TInt $int_atomic) : \Psalm\Type\Atomic\TIntRange
    {
        if ($int_atomic instanceof \Psalm\Type\Atomic\TIntRange) {
            return $int_atomic;
        }
        if ($int_atomic instanceof \Psalm\Type\Atomic\TLiteralInt) {
            return new \Psalm\Type\Atomic\TIntRange($int_atomic->value, $int_atomic->value);
        }
        return new \Psalm\Type\Atomic\TIntRange(null, null);
    }
    public static function intersectIntRanges(\Psalm\Type\Atomic\TIntRange $int_range1, \Psalm\Type\Atomic\TIntRange $int_range2) : ?\Psalm\Type\Atomic\TIntRange
    {
        if ($int_range1->min_bound === null || $int_range2->min_bound === null) {
            $new_min_bound = $int_range1->min_bound ?? $int_range2->min_bound;
        } else {
            $new_min_bound = self::getNewHighestBound($int_range1->min_bound, $int_range2->min_bound);
        }
        if ($int_range1->max_bound === null || $int_range2->max_bound === null) {
            $new_max_bound = $int_range1->max_bound ?? $int_range2->max_bound;
        } else {
            $new_max_bound = self::getNewLowestBound($int_range1->max_bound, $int_range2->max_bound);
        }
        if ($new_min_bound !== null && $new_max_bound !== null && $new_min_bound > $new_max_bound) {
            return null;
        }
        return new self($new_min_bound, $new_max_bound);
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * @psalm-immutable
 */
final class TTemplateIndexedAccess extends Atomic
{
    /**
     * @var string
     */
    public $array_param_name;
    /**
     * @var string
     */
    public $offset_param_name;
    /**
     * @var string
     */
    public $defining_class;
    public function __construct(string $array_param_name, string $offset_param_name, string $defining_class, bool $from_docblock = \false)
    {
        $this->array_param_name = $array_param_name;
        $this->offset_param_name = $offset_param_name;
        $this->defining_class = $defining_class;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return $this->array_param_name . '[' . $this->offset_param_name . ']';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes an object that is also `callable` (i.e. it has `__invoke` defined).
 *
 * @psalm-immutable
 */
final class TCallableObject extends \Psalm\Type\Atomic\TObject
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'callable-object';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70200 ? 'object' : null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'object';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes an anonymous class (i.e. `new class{}`) with potential methods
 *
 * @psalm-immutable
 */
final class TAnonymousClassInstance extends \Psalm\Type\Atomic\TNamedObject
{
    /**
     * @var string|null
     */
    public $extends;
    /**
     * @param string $value the name of the object
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public function __construct(string $value, bool $is_static = \false, ?string $extends = null, array $extra_types = [])
    {
        parent::__construct($value, $is_static, \false, $extra_types);
        $this->extends = $extends;
    }
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70200 ? $this->extends ?? 'object' : null;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $this->extends ?? 'object';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes an integer value where the exact numeric value is known.
 *
 * @psalm-immutable
 */
final class TLiteralInt extends \Psalm\Type\Atomic\TInt
{
    /** @var int */
    public $value;
    public function __construct(int $value, bool $from_docblock = \false)
    {
        $this->value = $value;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'int(' . $this->value . ')';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'int';
        }
        return (string) $this->value;
    }
    public function getAssertionString() : string
    {
        return 'int(' . $this->value . ')';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $use_phpdoc_format ? 'int' : (string) $this->value;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type;
use function array_fill;
/**
 * @deprecated Will be removed in Psalm v6, please use TCallableKeyedArrays with is_list=true instead.
 *
 * Denotes a list that is _also_ `callable`.
 * @psalm-immutable
 */
final class TCallableList extends \Psalm\Type\Atomic\TNonEmptyList
{
    public const KEY = 'callable-list';
    public function getKeyedArray() : \Psalm\Type\Atomic\TKeyedArray
    {
        if (!$this->count && !$this->min_count) {
            return new \Psalm\Type\Atomic\TKeyedArray([$this->type_param], null, [Type::getListKey(), $this->type_param], \true, $this->from_docblock);
        }
        if ($this->count) {
            return new \Psalm\Type\Atomic\TCallableKeyedArray(array_fill(0, $this->count, $this->type_param), null, null, \true, $this->from_docblock);
        }
        return new \Psalm\Type\Atomic\TCallableKeyedArray(array_fill(0, $this->min_count, $this->type_param), null, [Type::getListKey(), $this->type_param], \true, $this->from_docblock);
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `callable-string` type, used to represent an unknown string that is also `callable`.
 *
 * @psalm-immutable
 */
final class TCallableString extends \Psalm\Type\Atomic\TNonFalsyString
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'callable-string';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return $this->getKey();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'string';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
/**
 * Internal representation of a conditional return type in phpdoc. For example ($param1 is int ? int : string)
 *
 * @psalm-immutable
 */
final class TConditional extends Atomic
{
    /**
     * @var string
     */
    public $param_name;
    /**
     * @var string
     */
    public $defining_class;
    /**
     * @var Union
     */
    public $as_type;
    /**
     * @var Union
     */
    public $conditional_type;
    /**
     * @var Union
     */
    public $if_type;
    /**
     * @var Union
     */
    public $else_type;
    public function __construct(string $param_name, string $defining_class, Union $as_type, Union $conditional_type, Union $if_type, Union $else_type, bool $from_docblock = \false)
    {
        $this->param_name = $param_name;
        $this->defining_class = $defining_class;
        $this->as_type = $as_type;
        $this->conditional_type = $conditional_type;
        $this->if_type = $if_type;
        $this->else_type = $else_type;
        $this->from_docblock = $from_docblock;
    }
    public function setTypes(?Union $as_type, ?Union $conditional_type = null, ?Union $if_type = null, ?Union $else_type = null) : self
    {
        $as_type ??= $this->as_type;
        $conditional_type ??= $this->conditional_type;
        $if_type ??= $this->if_type;
        $else_type ??= $this->else_type;
        if ($as_type === $this->as_type && $conditional_type === $this->conditional_type && $if_type === $this->if_type && $else_type === $this->else_type) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->as_type = $as_type;
        $cloned->conditional_type = $conditional_type;
        $cloned->if_type = $if_type;
        $cloned->else_type = $else_type;
        return $cloned;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'TConditional<' . $this->param_name . '>';
    }
    public function getAssertionString() : string
    {
        return '';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return '(' . $this->param_name . ' is ' . $this->conditional_type->getId($exact) . ' ? ' . $this->if_type->getId($exact) . ' : ' . $this->else_type->getId($exact) . ')';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     * @return null
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return '';
    }
    protected function getChildNodeKeys() : array
    {
        return ['conditional_type', 'if_type', 'else_type'];
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $conditional = TemplateInferredTypeReplacer::replace($this->conditional_type, $template_result, $codebase);
        if ($conditional === $this->conditional_type) {
            return $this;
        }
        return new static($this->param_name, $this->defining_class, $this->as_type, $conditional, $this->if_type, $this->else_type);
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a `scalar` type that is also non-empty.
 *
 * @psalm-immutable
 */
final class TNonEmptyScalar extends \Psalm\Type\Atomic\TScalar
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'non-empty-scalar';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
use function array_map;
use function implode;
/**
 * @psalm-immutable
 */
final class TTypeAlias extends Atomic
{
    /**
     * @var array<string, TTypeAlias>|null
     */
    public $extra_types;
    /** @var string */
    public $declaring_fq_classlike_name;
    /** @var string */
    public $alias_name;
    /**
     * @param array<string, TTypeAlias>|null $extra_types
     */
    public function __construct(string $declaring_fq_classlike_name, string $alias_name, ?array $extra_types = null)
    {
        $this->declaring_fq_classlike_name = $declaring_fq_classlike_name;
        $this->alias_name = $alias_name;
        $this->extra_types = $extra_types;
    }
    /**
     * @param array<string, TTypeAlias>|null $extra_types
     */
    public function setIntersectionTypes(?array $extra_types) : self
    {
        if ($extra_types === $this->extra_types) {
            return $this;
        }
        return new self($this->declaring_fq_classlike_name, $this->alias_name, $extra_types);
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'type-alias(' . $this->declaring_fq_classlike_name . '::' . $this->alias_name . ')';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if ($this->extra_types) {
            return $this->getKey() . '&' . implode('&', array_map(static fn(Atomic $type): string => $type->getId($exact, \true), $this->extra_types));
        }
        return $this->getKey();
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'mixed';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Storage\FunctionLikeParameter;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function count;
use function implode;
/**
 * @psalm-immutable
 */
trait CallableTrait
{
    /**
     * @var list<FunctionLikeParameter>|null
     */
    public $params = [];
    /**
     * @var Union|null
     */
    public $return_type;
    /**
     * @var ?bool
     */
    public $is_pure;
    /**
     * Constructs a new instance of a generic type
     *
     * @param list<FunctionLikeParameter> $params
     */
    public function __construct(string $value = 'callable', ?array $params = null, ?Union $return_type = null, ?bool $is_pure = null, bool $from_docblock = \false)
    {
        $this->value = $value;
        $this->params = $params;
        $this->return_type = $return_type;
        $this->is_pure = $is_pure;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @param list<FunctionLikeParameter>|null $params
     * @return static
     */
    public function replace(?array $params, ?Union $return_type) : self
    {
        if ($this->params === $params && $this->return_type === $return_type) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->params = $params;
        $cloned->return_type = $return_type;
        return $cloned;
    }
    /** @return static */
    public function setIsPure(bool $is_pure) : self
    {
        if ($this->is_pure === $is_pure) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->is_pure = $is_pure;
        return $cloned;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        $param_string = '';
        $return_type_string = '';
        if ($this->params !== null) {
            $param_string .= '(';
            foreach ($this->params as $i => $param) {
                if ($i) {
                    $param_string .= ', ';
                }
                $param_string .= $param->getId();
            }
            $param_string .= ')';
        }
        if ($this->return_type !== null) {
            $return_type_multiple = count($this->return_type->getAtomicTypes()) > 1;
            $return_type_string = ':' . ($return_type_multiple ? '(' : '') . $this->return_type->getId() . ($return_type_multiple ? ')' : '');
        }
        return ($this->is_pure ? 'pure-' : ($this->is_pure === null ? '' : 'impure-')) . $this->value . $param_string . $return_type_string;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            if ($this instanceof \Psalm\Type\Atomic\TNamedObject) {
                return parent::toNamespacedString($namespace, $aliased_classes, $this_class, \true);
            }
            return $this->value;
        }
        $param_string = '';
        $return_type_string = '';
        if ($this->params !== null) {
            $params_array = [];
            foreach ($this->params as $param) {
                if (!$param->type) {
                    $type_string = 'mixed';
                } else {
                    $type_string = $param->type->toNamespacedString($namespace, $aliased_classes, $this_class, \false);
                }
                $params_array[] = ($param->is_variadic ? '...' : '') . $type_string . ($param->is_optional ? '=' : '');
            }
            $param_string = '(' . implode(', ', $params_array) . ')';
        }
        if ($this->return_type !== null) {
            $return_type_multiple = count($this->return_type->getAtomicTypes()) > 1;
            $return_type_string = ':' . ($return_type_multiple ? '(' : '') . $this->return_type->toNamespacedString($namespace, $aliased_classes, $this_class, \false) . ($return_type_multiple ? ')' : '');
        }
        if ($this instanceof \Psalm\Type\Atomic\TNamedObject) {
            return parent::toNamespacedString($namespace, $aliased_classes, $this_class, \true) . $param_string . $return_type_string;
        }
        return ($this->is_pure ? 'pure-' : '') . 'callable' . $param_string . $return_type_string;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        if ($this instanceof \Psalm\Type\Atomic\TNamedObject) {
            return parent::toNamespacedString($namespace, $aliased_classes, $this_class, \true);
        }
        return $this->value;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        $param_string = '';
        $return_type_string = '';
        if ($this->params !== null) {
            $param_string .= '(';
            foreach ($this->params as $i => $param) {
                if ($i) {
                    $param_string .= ', ';
                }
                $param_string .= $param->getId();
            }
            $param_string .= ')';
        }
        if ($this->return_type !== null) {
            $return_type_multiple = count($this->return_type->getAtomicTypes()) > 1;
            $return_type_string = ':' . ($return_type_multiple ? '(' : '') . $this->return_type->getId($exact) . ($return_type_multiple ? ')' : '');
        }
        return ($this->is_pure ? 'pure-' : ($this->is_pure === null ? '' : 'impure-')) . $this->value . $param_string . $return_type_string;
    }
    /**
     * @return array{list<FunctionLikeParameter>|null, Union|null}|null
     */
    protected function replaceCallableTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : ?array
    {
        $replaced = \false;
        $params = $this->params;
        if ($params) {
            foreach ($params as $offset => $param) {
                if (!$param->type) {
                    continue;
                }
                $input_param_type = null;
                if (($input_type instanceof \Psalm\Type\Atomic\TClosure || $input_type instanceof \Psalm\Type\Atomic\TCallable) && isset($input_type->params[$offset])) {
                    $input_param_type = $input_type->params[$offset]->type;
                }
                $new_param = $param->setType(TemplateStandinTypeReplacer::replace($param->type, $template_result, $codebase, $statements_analyzer, $input_param_type, $input_arg_offset, $calling_class, $calling_function, $replace, !$add_lower_bound, null, $depth));
                $replaced = $replaced || $new_param !== $param;
                $params[$offset] = $new_param;
            }
        }
        $return_type = $this->return_type;
        if ($return_type) {
            $return_type = TemplateStandinTypeReplacer::replace($return_type, $template_result, $codebase, $statements_analyzer, $input_type instanceof \Psalm\Type\Atomic\TCallable || $input_type instanceof \Psalm\Type\Atomic\TClosure ? $input_type->return_type : null, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound);
            $replaced = $replaced || $this->return_type !== $return_type;
        }
        if ($replaced) {
            return [$params, $return_type];
        }
        return null;
    }
    /**
     * @return array{list<FunctionLikeParameter>|null, Union|null}|null
     */
    protected function replaceCallableTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : ?array
    {
        $replaced = \false;
        $params = $this->params;
        if ($params) {
            foreach ($params as $k => $param) {
                if ($param->type) {
                    $new_param = $param->setType(TemplateInferredTypeReplacer::replace($param->type, $template_result, $codebase));
                    $replaced = $replaced || $new_param !== $param;
                    $params[$k] = $new_param;
                }
            }
        }
        $return_type = $this->return_type;
        if ($return_type) {
            $return_type = TemplateInferredTypeReplacer::replace($return_type, $template_result, $codebase);
            $replaced = $replaced || $return_type !== $this->return_type;
        }
        if ($replaced) {
            return [$params, $return_type];
        }
        return null;
    }
    /**
     * @return list<string>
     */
    protected function getCallableChildNodeKeys() : array
    {
        return ['params', 'return_type'];
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Codebase\ConstantTypeResolver;
use Psalm\Storage\EnumCaseStorage;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Union;
use function array_map;
use function array_values;
use function assert;
use function count;
/**
 * Represents a value of an array or enum.
 *
 * @psalm-immutable
 */
final class TValueOf extends Atomic
{
    /** @var Union */
    public $type;
    public function __construct(Union $type, bool $from_docblock = \false)
    {
        $this->type = $type;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'value-of<' . $this->type . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'mixed';
    }
    public static function isViableTemplateType(Union $template_type) : bool
    {
        foreach ($template_type->getAtomicTypes() as $type) {
            if (!$type instanceof \Psalm\Type\Atomic\TArray && !$type instanceof \Psalm\Type\Atomic\TClassConstant && !$type instanceof \Psalm\Type\Atomic\TKeyedArray && !$type instanceof TList && !$type instanceof \Psalm\Type\Atomic\TPropertiesOf && !$type instanceof \Psalm\Type\Atomic\TNamedObject) {
                return \false;
            }
        }
        return \true;
    }
    public static function getValueType(Union $type, Codebase $codebase, bool $keep_template_params = \false) : ?Union
    {
        $value_types = [];
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof \Psalm\Type\Atomic\TArray) {
                $value_atomics = $atomic_type->type_params[1];
            } elseif ($atomic_type instanceof TList) {
                $value_atomics = $atomic_type->type_param;
            } elseif ($atomic_type instanceof \Psalm\Type\Atomic\TKeyedArray) {
                $value_atomics = $atomic_type->getGenericValueType();
            } elseif ($atomic_type instanceof \Psalm\Type\Atomic\TTemplateParam) {
                if ($keep_template_params) {
                    $value_atomics = new Union([$atomic_type]);
                } else {
                    $value_atomics = static::getValueType($atomic_type->as, $codebase, $keep_template_params);
                    if ($value_atomics === null) {
                        continue;
                    }
                }
            } elseif ($atomic_type instanceof \Psalm\Type\Atomic\TNamedObject && $codebase->classlike_storage_provider->has($atomic_type->value)) {
                $class_storage = $codebase->classlike_storage_provider->get($atomic_type->value);
                $cases = $class_storage->enum_cases;
                if (!$class_storage->is_enum || $class_storage->enum_type === null || count($cases) === 0) {
                    // Invalid value-of, skip
                    continue;
                }
                $value_atomics = new Union(array_map(function (EnumCaseStorage $case) : Atomic {
                    assert($case->value !== null);
                    // Backed enum must have a value
                    return ConstantTypeResolver::getLiteralTypeFromScalarValue($case->value);
                }, array_values($cases)));
            } else {
                continue;
            }
            $value_types = [...$value_types, ...array_values($value_atomics->getAtomicTypes())];
        }
        if ($value_types === []) {
            return null;
        }
        return new Union($value_types);
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `literal-string` type, where the exact value is unknown but
 * we know that the string is not from user input
 *
 * @psalm-immutable
 */
final class TNonEmptyNonspecificLiteralString extends \Psalm\Type\Atomic\TNonspecificLiteralString
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'string';
        }
        return 'non-empty-literal-string';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Denotes the `mixed` type, used when you don’t know the type of an expression.
 *
 * @psalm-immutable
 */
class TMixed extends Atomic
{
    /** @var bool */
    public $from_loop_isset = \false;
    public function __construct(bool $from_loop_isset = \false, bool $from_docblock = \false)
    {
        $this->from_loop_isset = $from_loop_isset;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'mixed';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 80000 ? 'mixed' : null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return $analysis_php_version_id >= 80000;
    }
    public function getAssertionString() : string
    {
        return 'mixed';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `bool` type where the exact value is unknown.
 *
 * @psalm-immutable
 */
class TBool extends \Psalm\Type\Atomic\Scalar
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'bool';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70000 ? 'bool' : null;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `int` type, where the exact value is unknown.
 *
 * @psalm-immutable
 */
class TInt extends \Psalm\Type\Atomic\Scalar
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'int';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70000 ? 'int' : null;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `string` type, where the exact value is unknown.
 *
 * @psalm-immutable
 */
class TString extends \Psalm\Type\Atomic\Scalar
{
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70000 ? 'string' : null;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'string';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Denotes the `void` type, normally just used to annotate a function/method that returns nothing
 *
 * @psalm-immutable
 */
final class TVoid extends Atomic
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'void';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70100 ? $this->getKey() : null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \true;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic\TList;
use Psalm\Type\Union;
use function array_merge;
use function array_values;
/**
 * Represents an offset of an array.
 *
 * @psalm-immutable
 */
final class TKeyOf extends \Psalm\Type\Atomic\TArrayKey
{
    /** @var Union */
    public $type;
    public function __construct(Union $type, bool $from_docblock = \false)
    {
        $this->type = $type;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'key-of<' . $this->type . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'mixed';
    }
    public static function isViableTemplateType(Union $template_type) : bool
    {
        foreach ($template_type->getAtomicTypes() as $type) {
            if (!$type instanceof \Psalm\Type\Atomic\TArray && !$type instanceof \Psalm\Type\Atomic\TClassConstant && !$type instanceof \Psalm\Type\Atomic\TKeyedArray && !$type instanceof TList && !$type instanceof \Psalm\Type\Atomic\TPropertiesOf) {
                return \false;
            }
        }
        return \true;
    }
    public static function getArrayKeyType(Union $type, bool $keep_template_params = \false) : ?Union
    {
        $key_types = [];
        foreach ($type->getAtomicTypes() as $atomic_type) {
            if ($atomic_type instanceof TList) {
                $atomic_type = $atomic_type->getKeyedArray();
            }
            if ($atomic_type instanceof \Psalm\Type\Atomic\TArray) {
                $array_key_atomics = $atomic_type->type_params[0];
            } elseif ($atomic_type instanceof \Psalm\Type\Atomic\TKeyedArray) {
                $array_key_atomics = $atomic_type->getGenericKeyType();
            } elseif ($atomic_type instanceof \Psalm\Type\Atomic\TTemplateParam) {
                if ($keep_template_params) {
                    $array_key_atomics = new Union([$atomic_type]);
                } else {
                    $array_key_atomics = static::getArrayKeyType($atomic_type->as, $keep_template_params);
                    if ($array_key_atomics === null) {
                        continue;
                    }
                }
            } else {
                continue;
            }
            $key_types = array_merge($key_types, array_values($array_key_atomics->getAtomicTypes()));
        }
        if ($key_types === []) {
            return null;
        }
        return new Union($key_types);
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Denotes the `null` type
 *
 * @psalm-immutable
 */
final class TNull extends Atomic
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'null';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Represents a string whose value is that of a type found by get_debug_type($var)
 *
 * @psalm-immutable
 */
final class TDependentGetDebugType extends \Psalm\Type\Atomic\TString implements \Psalm\Type\Atomic\DependentType
{
    /**
     * Used to hold information as to what this refers to
     *
     * @var string
     */
    public $typeof;
    /**
     * @param string $typeof the variable id
     */
    public function __construct(string $typeof)
    {
        $this->typeof = $typeof;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'get-debug-type-of<' . $this->typeof . '>';
    }
    public function getVarId() : string
    {
        return $this->typeof;
    }
    public function getReplacement() : \Psalm\Type\Atomic\TString
    {
        return new \Psalm\Type\Atomic\TString();
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a string, that is also non-falsy (every string except '' and '0')
 *
 * @psalm-immutable
 */
class TNonFalsyString extends \Psalm\Type\Atomic\TNonEmptyString
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'string';
        }
        return 'non-falsy-string';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes an object-like array that is _also_ `callable`.
 *
 * @psalm-immutable
 */
final class TCallableKeyedArray extends \Psalm\Type\Atomic\TKeyedArray
{
    protected const NAME_ARRAY = 'callable-array';
    protected const NAME_LIST = 'callable-list';
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Union;
use function get_class;
/**
 * Represents an array where the type of each value
 * is a function of its string key value
 *
 * @psalm-immutable
 */
final class TClassStringMap extends Atomic
{
    /**
     * @var string
     */
    public $param_name;
    public ?\Psalm\Type\Atomic\TNamedObject $as_type;
    /**
     * @var Union
     */
    public $value_param;
    /**
     * Constructs a new instance of a list
     */
    public function __construct(string $param_name, ?\Psalm\Type\Atomic\TNamedObject $as_type, Union $value_param, bool $from_docblock = \false)
    {
        $this->param_name = $param_name;
        $this->as_type = $as_type;
        $this->value_param = $value_param;
        $this->from_docblock = $from_docblock;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'class-string-map' . '<' . $this->param_name . ' as ' . ($this->as_type ? $this->as_type->getId($exact) : 'object') . ', ' . $this->value_param->getId($exact) . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return (new \Psalm\Type\Atomic\TArray([Type::getString(), $this->value_param]))->toNamespacedString($namespace, $aliased_classes, $this_class, \true);
        }
        return 'class-string-map' . '<' . $this->param_name . ($this->as_type ? ' as ' . $this->as_type : '') . ', ' . $this->value_param->toNamespacedString($namespace, $aliased_classes, $this_class, \false) . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return 'array';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'array';
    }
    /**
     * @psalm-suppress InaccessibleProperty We're only acting on cloned instances
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $cloned = null;
        foreach ([Type::getString(), $this->value_param] as $offset => $type_param) {
            $input_type_param = null;
            if ($input_type instanceof TList) {
                $input_type = $input_type->getKeyedArray();
            }
            if (($input_type instanceof \Psalm\Type\Atomic\TGenericObject || $input_type instanceof \Psalm\Type\Atomic\TIterable || $input_type instanceof \Psalm\Type\Atomic\TArray) && isset($input_type->type_params[$offset])) {
                $input_type_param = $input_type->type_params[$offset];
            } elseif ($input_type instanceof \Psalm\Type\Atomic\TKeyedArray) {
                if ($offset === 0) {
                    if ($input_type->is_list) {
                        continue;
                    }
                    $input_type_param = $input_type->getGenericKeyType();
                } else {
                    $input_type_param = $input_type->getGenericValueType();
                }
            }
            $value_param = TemplateStandinTypeReplacer::replace($type_param, $template_result, $codebase, $statements_analyzer, $input_type_param, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, null, $depth + 1);
            if ($offset === 1 && ($cloned || $this->value_param !== $value_param)) {
                $cloned ??= clone $this;
                $cloned->value_param = $value_param;
            }
        }
        return $cloned ?? $this;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $value_param = TemplateInferredTypeReplacer::replace($this->value_param, $template_result, $codebase);
        if ($value_param === $this->value_param) {
            return $this;
        }
        return new static($this->param_name, $this->as_type, $value_param);
    }
    protected function getChildNodeKeys() : array
    {
        return ['value_param'];
    }
    public function equals(Atomic $other_type, bool $ensure_source_equality) : bool
    {
        if (get_class($other_type) !== static::class) {
            return \false;
        }
        if (!$this->value_param->equals($other_type->value_param, $ensure_source_equality)) {
            return \false;
        }
        return \true;
    }
    public function getAssertionString() : string
    {
        return $this->getKey();
    }
    public function getStandinKeyParam() : Union
    {
        return new Union([new \Psalm\Type\Atomic\TTemplateParamClass($this->param_name, $this->as_type->value ?? 'object', $this->as_type, 'class-string-map')]);
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type;
use Psalm\Type\Atomic;
/**
 * Denotes a class constant whose value might not yet be known.
 *
 * @psalm-immutable
 */
final class TClassConstant extends Atomic
{
    /** @var string */
    public $fq_classlike_name;
    /** @var string */
    public $const_name;
    public function __construct(string $fq_classlike_name, string $const_name, bool $from_docblock = \false)
    {
        $this->fq_classlike_name = $fq_classlike_name;
        $this->const_name = $const_name;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'class-constant(' . $this->fq_classlike_name . '::' . $this->const_name . ')';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return $this->fq_classlike_name . '::' . $this->const_name;
    }
    public function getAssertionString() : string
    {
        return 'class-constant(' . $this->fq_classlike_name . '::' . $this->const_name . ')';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($this->fq_classlike_name === 'static') {
            return 'static::' . $this->const_name;
        }
        return Type::getStringFromFQCLN($this->fq_classlike_name, $namespace, $aliased_classes, $this_class) . '::' . $this->const_name;
    }
}
<?php

namespace Psalm\Type\Atomic;

use function addcslashes;
use function mb_strlen;
use function mb_substr;
/**
 * Denotes a string whose value is known.
 *
 * @psalm-immutable
 */
class TLiteralString extends \Psalm\Type\Atomic\TString
{
    /** @var string */
    public $value;
    public function __construct(string $value, bool $from_docblock = \false)
    {
        $this->value = $value;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @psalm-suppress PossiblyUnusedMethod
     * @return static
     */
    public function setValue(string $value) : self
    {
        if ($value === $this->value) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->value = $value;
        return $cloned;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'string(' . $this->value . ')';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'string';
        }
        // quote control characters, backslashes and double quote
        $no_newline_value = addcslashes($this->value, "\x00..\x1f\\\"");
        if (mb_strlen($this->value) > 80) {
            return "'" . mb_substr($no_newline_value, 0, 80) . '...' . "'";
        }
        return "'" . $no_newline_value . "'";
    }
    public function getAssertionString() : string
    {
        return 'string(' . $this->value . ')';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $use_phpdoc_format ? 'string' : "'" . $this->value . "'";
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Union;
use UnexpectedValueException;
use function addslashes;
use function assert;
use function count;
use function get_class;
use function implode;
use function is_int;
use function is_string;
use function ksort;
use function preg_match;
use function sort;
use function str_replace;
/**
 * Represents an 'object-like array' - an array with known keys.
 *
 * @psalm-immutable
 */
class TKeyedArray extends Atomic
{
    /**
     * @var non-empty-array<string|int, Union>
     */
    public $properties;
    /**
     * @var array<string, bool>|null
     */
    public $class_strings;
    /**
     * If the shape has fallback params then they are here
     *
     * @var ?list{Union, Union}
     */
    public $fallback_params;
    /**
     * @var bool - if this is a list of sequential elements
     */
    public $is_list = \false;
    /** @var non-empty-lowercase-string */
    protected const NAME_ARRAY = 'array';
    /** @var non-empty-lowercase-string */
    protected const NAME_LIST = 'list';
    /**
     * Constructs a new instance of a generic type
     *
     * @param non-empty-array<string|int, Union> $properties
     * @param ?list{Union, Union} $fallback_params
     * @param array<string, bool> $class_strings
     */
    public function __construct(array $properties, ?array $class_strings = null, ?array $fallback_params = null, bool $is_list = \false, bool $from_docblock = \false)
    {
        if ($is_list && $fallback_params) {
            $fallback_params[0] = Type::getListKey();
        }
        $this->properties = $properties;
        $this->class_strings = $class_strings;
        $this->fallback_params = $fallback_params;
        $this->is_list = $is_list;
        $this->from_docblock = $from_docblock;
        if ($this->is_list) {
            $last_k = -1;
            $had_possibly_undefined = \false;
            ksort($this->properties);
            foreach ($this->properties as $k => $v) {
                if (is_string($k) || $last_k !== $k - 1 || $had_possibly_undefined && !$v->possibly_undefined) {
                    $this->is_list = \false;
                    break;
                }
                if ($v->possibly_undefined) {
                    $had_possibly_undefined = \true;
                }
                $last_k = $k;
            }
        }
    }
    /**
     * @param non-empty-array<string|int, Union> $properties
     * @return static
     */
    public function setProperties(array $properties) : self
    {
        if ($properties === $this->properties) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->properties = $properties;
        if ($cloned->is_list) {
            $last_k = -1;
            $had_possibly_undefined = \false;
            ksort($cloned->properties);
            foreach ($cloned->properties as $k => $v) {
                if (is_string($k) || $last_k !== $k - 1 || $had_possibly_undefined && !$v->possibly_undefined) {
                    $cloned->is_list = \false;
                    break;
                }
                if ($v->possibly_undefined) {
                    $had_possibly_undefined = \true;
                }
                $last_k = $k;
            }
        }
        return $cloned;
    }
    /**
     * @return static
     */
    public function makeSealed() : self
    {
        if ($this->fallback_params === null) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->fallback_params = null;
        return $cloned;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        $property_strings = [];
        if ($this->is_list) {
            if (count($this->properties) === 1 && $this->fallback_params && $this->properties[0]->equals($this->fallback_params[1], \true, \true, \false)) {
                $t = $this->properties[0]->possibly_undefined ? 'list' : 'non-empty-list';
                return "{$t}<" . $this->fallback_params[1]->getId($exact) . '>';
            }
            $use_list_syntax = \true;
            foreach ($this->properties as $property) {
                if ($property->possibly_undefined) {
                    $use_list_syntax = \false;
                    break;
                }
            }
        } else {
            $use_list_syntax = \false;
        }
        foreach ($this->properties as $name => $type) {
            if ($use_list_syntax) {
                $property_strings[$name] = $type->getId($exact);
                continue;
            }
            $class_string_suffix = '';
            if (isset($this->class_strings[$name])) {
                $class_string_suffix = '::class';
            }
            $name = $this->escapeAndQuote($name);
            $property_strings[$name] = $name . $class_string_suffix . ($type->possibly_undefined ? '?' : '') . ': ' . $type->getId($exact);
        }
        if ($this->is_list) {
            $key = static::NAME_LIST;
        } else {
            $key = static::NAME_ARRAY;
            sort($property_strings);
        }
        $params_part = $this->fallback_params !== null ? ', ...<' . $this->fallback_params[0]->getId($exact) . ', ' . $this->fallback_params[1]->getId($exact) . '>' : '';
        return $key . '{' . implode(', ', $property_strings) . $params_part . '}';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return $this->getGenericArrayType()->toNamespacedString($namespace, $aliased_classes, $this_class, \true);
        }
        $suffixed_properties = [];
        if ($this->is_list) {
            if (count($this->properties) === 1 && $this->fallback_params && $this->properties[0]->equals($this->fallback_params[1], \true, \true, \false)) {
                $t = $this->properties[0]->possibly_undefined ? 'list' : 'non-empty-list';
                return "{$t}<" . $this->fallback_params[1]->getId() . '>';
            }
            $use_list_syntax = \true;
            foreach ($this->properties as $property) {
                if ($property->possibly_undefined) {
                    $use_list_syntax = \false;
                    break;
                }
            }
        } else {
            $use_list_syntax = \false;
        }
        foreach ($this->properties as $name => $type) {
            if ($use_list_syntax) {
                $suffixed_properties[$name] = $type->toNamespacedString($namespace, $aliased_classes, $this_class, \false);
                continue;
            }
            $class_string_suffix = '';
            if (isset($this->class_strings[$name])) {
                $class_string_suffix = '::class';
            }
            $name = $this->escapeAndQuote($name);
            $suffixed_properties[$name] = $name . $class_string_suffix . ($type->possibly_undefined ? '?' : '') . ': ' . $type->toNamespacedString($namespace, $aliased_classes, $this_class, \false);
        }
        $params_part = $this->fallback_params !== null ? ',...' : '';
        return ($this->is_list ? static::NAME_LIST : static::NAME_ARRAY) . '{' . implode(', ', $suffixed_properties) . $params_part . '}';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return 'array';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getGenericKeyType(bool $possibly_undefined = \false) : Union
    {
        if ($this->is_list) {
            if ($this->fallback_params) {
                return Type::getListKey();
            }
            if (count($this->properties) === 1) {
                return new Union([new TLiteralInt(0)]);
            }
            return new Union([new \Psalm\Type\Atomic\TIntRange(0, count($this->properties) - 1)]);
        }
        $key_types = [];
        foreach ($this->properties as $key => $_) {
            if (is_int($key)) {
                $key_types[] = new TLiteralInt($key);
            } elseif (isset($this->class_strings[$key])) {
                $key_types[] = new TLiteralClassString($key);
            } else {
                $key_types[] = new TLiteralString($key);
            }
        }
        $key_type = TypeCombiner::combine($key_types);
        /** @psalm-suppress InaccessibleProperty We just created this type */
        $key_type->possibly_undefined = $possibly_undefined;
        if ($this->fallback_params === null) {
            return $key_type;
        }
        return Type::combineUnionTypes($this->fallback_params[0], $key_type);
    }
    public function getGenericValueType(bool $possibly_undefined = \false) : Union
    {
        $value_type = null;
        foreach ($this->properties as $property) {
            $value_type = Type::combineUnionTypes($property, $value_type);
        }
        return Type::combineUnionTypes($this->fallback_params[1] ?? null, $value_type, null, \false, \true, 500, $possibly_undefined);
    }
    /**
     * @return TArray|TNonEmptyArray
     */
    public function getGenericArrayType(bool $allow_non_empty = \true, ?string $list_var_id = null) : TArray
    {
        $key_types = [];
        $value_type = null;
        $has_defined_keys = \false;
        foreach ($this->properties as $key => $property) {
            if ($this->is_list) {
                // Do nothing
            } elseif (is_int($key)) {
                $key_types[] = new TLiteralInt($key);
            } elseif (isset($this->class_strings[$key])) {
                $key_types[] = new TLiteralClassString($key);
            } else {
                $key_types[] = new TLiteralString($key);
            }
            $value_type = Type::combineUnionTypes($property, $value_type);
            if (!$property->possibly_undefined) {
                $has_defined_keys = \true;
            }
        }
        if ($this->is_list) {
            if ($this->fallback_params !== null) {
                $value_type = Type::combineUnionTypes($this->fallback_params[1], $value_type);
            }
            $value_type = $value_type->setPossiblyUndefined(\false);
            if ($this->fallback_params === null) {
                $key_type = new Union([new \Psalm\Type\Atomic\TIntRange(0, count($this->properties) - 1, \false, $list_var_id)]);
            } else {
                $key_type = new Union([new \Psalm\Type\Atomic\TIntRange(0, null, \false, $list_var_id)]);
            }
            if ($has_defined_keys && $allow_non_empty) {
                return new TNonEmptyArray([$key_type, $value_type]);
            }
            return new TArray([$key_type, $value_type]);
        }
        assert($key_types !== []);
        $key_type = TypeCombiner::combine($key_types);
        if ($this->fallback_params !== null) {
            $key_type = Type::combineUnionTypes($this->fallback_params[0], $key_type);
            $value_type = Type::combineUnionTypes($this->fallback_params[1], $value_type);
        }
        $value_type = $value_type->setPossiblyUndefined(\false);
        if ($allow_non_empty && ($has_defined_keys || $this->fallback_params !== null)) {
            return new TNonEmptyArray([$key_type, $value_type]);
        }
        return new TArray([$key_type, $value_type]);
    }
    public function isNonEmpty() : bool
    {
        if ($this->is_list) {
            return !$this->properties[0]->possibly_undefined;
        }
        foreach ($this->properties as $property) {
            if (!$property->possibly_undefined) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @return int<0, max>
     */
    public function getMinCount() : int
    {
        if ($this->is_list) {
            foreach ($this->properties as $k => $property) {
                if ($property->possibly_undefined || $property->isNever()) {
                    /** @var int<0, max> */
                    return $k;
                }
            }
            return count($this->properties);
        }
        $prop_min_count = 0;
        foreach ($this->properties as $property) {
            if (!($property->possibly_undefined || $property->isNever())) {
                $prop_min_count++;
            }
        }
        return $prop_min_count;
    }
    /**
     * Returns null if there is no upper limit.
     *
     * @return int<1, max>|null
     */
    public function getMaxCount() : ?int
    {
        if ($this->fallback_params) {
            return null;
        }
        $prop_max_count = 0;
        foreach ($this->properties as $property) {
            if (!$property->isNever()) {
                $prop_max_count++;
            }
        }
        assert($prop_max_count !== 0);
        return $prop_max_count;
    }
    /**
     * Whether all keys are always defined (ignores unsealedness).
     */
    public function allShapeKeysAlwaysDefined() : bool
    {
        foreach ($this->properties as $property) {
            if ($property->possibly_undefined) {
                return \false;
            }
        }
        return \true;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'array';
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $properties = $this->properties;
        foreach ($properties as $offset => $property) {
            $input_type_param = null;
            if ($input_type instanceof \Psalm\Type\Atomic\TKeyedArray && isset($input_type->properties[$offset])) {
                $input_type_param = $input_type->properties[$offset];
            }
            $properties[$offset] = TemplateStandinTypeReplacer::replace($property, $template_result, $codebase, $statements_analyzer, $input_type_param, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, null, $depth);
        }
        $fallback_params = $this->fallback_params;
        foreach ($fallback_params ?? [] as $offset => $property) {
            $input_type_param = null;
            if ($input_type instanceof \Psalm\Type\Atomic\TKeyedArray && isset($input_type->fallback_params[$offset])) {
                $input_type_param = $input_type->fallback_params[$offset];
            }
            $fallback_params[$offset] = TemplateStandinTypeReplacer::replace($property, $template_result, $codebase, $statements_analyzer, $input_type_param, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, null, $depth);
        }
        if ($properties === $this->properties && $fallback_params === $this->fallback_params) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->properties = $properties;
        /** @psalm-suppress PropertyTypeCoercion */
        $cloned->fallback_params = $fallback_params;
        return $cloned;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $properties = $this->properties;
        foreach ($properties as $offset => $property) {
            $properties[$offset] = TemplateInferredTypeReplacer::replace($property, $template_result, $codebase);
        }
        $fallback_params = $this->fallback_params;
        foreach ($fallback_params ?? [] as $offset => $property) {
            $fallback_params[$offset] = TemplateInferredTypeReplacer::replace($property, $template_result, $codebase);
        }
        if ($properties !== $this->properties || $fallback_params !== $this->fallback_params) {
            $cloned = clone $this;
            $cloned->properties = $properties;
            /** @psalm-suppress PropertyTypeCoercion */
            $cloned->fallback_params = $fallback_params;
            return $cloned;
        }
        return $this;
    }
    protected function getChildNodeKeys() : array
    {
        return ['properties', 'fallback_params'];
    }
    public function equals(Atomic $other_type, bool $ensure_source_equality) : bool
    {
        if (get_class($other_type) !== static::class) {
            return \false;
        }
        if (count($this->properties) !== count($other_type->properties)) {
            return \false;
        }
        if (($this->fallback_params === null) !== ($other_type->fallback_params === null)) {
            return \false;
        }
        if ($this->fallback_params !== null && $other_type->fallback_params !== null) {
            if (!$this->fallback_params[0]->equals($other_type->fallback_params[0])) {
                return \false;
            }
            if (!$this->fallback_params[1]->equals($other_type->fallback_params[1])) {
                return \false;
            }
        }
        foreach ($this->properties as $property_name => $property_type) {
            if (!isset($other_type->properties[$property_name])) {
                return \false;
            }
            if (!$property_type->equals($other_type->properties[$property_name], $ensure_source_equality)) {
                return \false;
            }
        }
        return \true;
    }
    public function getAssertionString() : string
    {
        return $this->is_list ? 'list' : 'array';
    }
    /**
     * @deprecated Will be removed in Psalm v6 along with the TList type.
     */
    public function getList() : \Psalm\Type\Atomic\TList
    {
        if (!$this->is_list) {
            throw new UnexpectedValueException('Object-like array must be a list for conversion');
        }
        return $this->isNonEmpty() ? new \Psalm\Type\Atomic\TNonEmptyList($this->getGenericValueType()) : new \Psalm\Type\Atomic\TList($this->getGenericValueType());
    }
    /**
     * @param string|int $name
     * @return string|int
     */
    private function escapeAndQuote($name)
    {
        if (is_string($name) && ($name === '' || preg_match('/[^a-zA-Z0-9_]/', $name))) {
            $name = '\'' . str_replace("\n", '\\n', addslashes($name)) . '\'';
        }
        return $name;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes an enum with a specific value
 *
 * @psalm-immutable
 */
final class TEnumCase extends \Psalm\Type\Atomic\TNamedObject
{
    /**
     * @var string
     */
    public $case_name;
    public function __construct(string $fq_enum_name, string $case_name)
    {
        parent::__construct($fq_enum_name);
        $this->case_name = $case_name;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'enum(' . $this->value . '::' . $this->case_name . ')';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'enum(' . $this->value . '::' . $this->case_name . ')';
    }
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $this->value;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $this->value . '::' . $this->case_name;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes an array that is _also_ `callable`.
 *
 * @psalm-immutable
 */
final class TCallableArray extends \Psalm\Type\Atomic\TNonEmptyArray
{
    /**
     * @var string
     */
    public $value = 'callable-array';
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `mixed` type, but not empty.
 * Generated for `$x` inside the `if` statement `if ($x) {...}` when `$x` is `mixed` outside.
 *
 * @psalm-immutable
 */
final class TNonEmptyMixed extends \Psalm\Type\Atomic\TMixed
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return 'non-empty-mixed';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Denotes the `no-return`/`never-return` type for functions that never return, either throwing an exception or
 * terminating (like the builtin `exit()`).
 *
 * @psalm-immutable
 */
final class TNever extends Atomic
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'never';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Union;
use function array_map;
use function array_values;
use function count;
use function implode;
use function strpos;
use function substr;
/**
 * @template TTypeParams as array<Union>
 * @psalm-immutable
 */
trait GenericTrait
{
    /**
     * @param TTypeParams $type_params
     * @return static
     */
    public function setTypeParams(array $type_params) : self
    {
        if ($this->type_params === $type_params) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->type_params = $type_params;
        return $cloned;
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        $s = '';
        foreach ($this->type_params as $type_param) {
            $s .= $type_param->getId($exact) . ', ';
        }
        $extra_types = '';
        if ($this instanceof \Psalm\Type\Atomic\TNamedObject) {
            if ($this->extra_types) {
                $extra_types = '&' . implode('&', array_map(static fn(Atomic $type): string => $type->getId($exact, \true), $this->extra_types));
            }
            if ($this->is_static) {
                $extra_types .= '&static';
            }
        }
        return $this->value . '<' . substr($s, 0, -2) . '>' . $extra_types;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        $base_value = $this instanceof \Psalm\Type\Atomic\TNamedObject ? parent::toNamespacedString($namespace, $aliased_classes, $this_class, $use_phpdoc_format) : $this->value;
        if ($base_value === 'non-empty-array') {
            $base_value = 'array';
        }
        if ($use_phpdoc_format) {
            if ($this instanceof \Psalm\Type\Atomic\TNamedObject || $this instanceof \Psalm\Type\Atomic\TIterable) {
                return $base_value;
            }
            $value_type = $this->type_params[1];
            if ($value_type->isMixed() || $value_type->isNever()) {
                return $base_value;
            }
            $value_type_string = $value_type->toNamespacedString($namespace, $aliased_classes, $this_class, \true);
            if (!$value_type->isSingle()) {
                return '(' . $value_type_string . ')[]';
            }
            return $value_type_string . '[]';
        }
        $intersection_pos = strpos($base_value, '&');
        if ($intersection_pos !== \false) {
            $base_value = substr($base_value, 0, $intersection_pos);
        }
        $type_params = $this->type_params;
        //no need for special format if the key is not determined
        if ($this instanceof \Psalm\Type\Atomic\TArray && count($type_params) === 2 && isset($type_params[0]) && $type_params[0]->isArrayKey()) {
            //we remove the key for display
            unset($type_params[0]);
            $type_params = array_values($type_params);
        }
        if ($this instanceof \Psalm\Type\Atomic\TArray && count($type_params) === 1 && isset($type_params[0]) && $type_params[0]->isMixed()) {
            //when the value of an array is mixed, no need for namespaced phpdoc
            return 'array';
        }
        $extra_types = '';
        if ($this instanceof \Psalm\Type\Atomic\TNamedObject && $this->extra_types) {
            $extra_types = '&' . implode('&', array_map(static fn(Atomic $extra_type): string => $extra_type->toNamespacedString($namespace, $aliased_classes, $this_class, \false), $this->extra_types));
        }
        return $base_value . '<' . implode(', ', array_map(static fn(Union $type_param): string => $type_param->toNamespacedString($namespace, $aliased_classes, $this_class, \false), $type_params)) . '>' . $extra_types;
    }
    /**
     * @return TTypeParams|null
     */
    protected function replaceTypeParamsTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : ?array
    {
        if ($input_type instanceof TList) {
            $input_type = $input_type->getKeyedArray();
        }
        $input_object_type_params = [];
        $container_type_params_covariant = [];
        if ($input_type instanceof \Psalm\Type\Atomic\TGenericObject && ($this instanceof \Psalm\Type\Atomic\TGenericObject || $this instanceof \Psalm\Type\Atomic\TIterable)) {
            $input_object_type_params = TemplateStandinTypeReplacer::getMappedGenericTypeParams($codebase, $input_type, $this, $container_type_params_covariant);
        }
        $type_params = $this->type_params;
        foreach ($type_params as $offset => $type_param) {
            $input_type_param = null;
            if (($input_type instanceof \Psalm\Type\Atomic\TIterable || $input_type instanceof \Psalm\Type\Atomic\TArray) && isset($input_type->type_params[$offset])) {
                $input_type_param = $input_type->type_params[$offset];
            } elseif ($input_type instanceof \Psalm\Type\Atomic\TKeyedArray) {
                if ($offset === 0) {
                    $input_type_param = $input_type->getGenericKeyType();
                } else {
                    $input_type_param = $input_type->getGenericValueType();
                }
            } elseif ($input_type instanceof \Psalm\Type\Atomic\TNamedObject && isset($input_object_type_params[$offset])) {
                $input_type_param = $input_object_type_params[$offset];
            }
            $type_params[$offset] = TemplateStandinTypeReplacer::replace($type_param, $template_result, $codebase, $statements_analyzer, $input_type_param, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, !($container_type_params_covariant[$offset] ?? \true) && $this instanceof \Psalm\Type\Atomic\TGenericObject ? $this->value : null, $depth + 1);
        }
        return $type_params === $this->type_params ? null : $type_params;
    }
    /**
     * @return TTypeParams|null
     */
    protected function replaceTypeParamsTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : ?array
    {
        $type_params = $this->type_params;
        foreach ($type_params as $offset => $type_param) {
            $type_param = TemplateInferredTypeReplacer::replace($type_param, $template_result, $codebase);
            if ($this instanceof \Psalm\Type\Atomic\TArray && $offset === 0 && $type_param->isMixed()) {
                $type_param = Type::getArrayKey();
            }
            $type_params[$offset] = $type_param;
        }
        return $type_params === $this->type_params ? null : $type_params;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a non-empty-string where every character is lowercased. (which can also result from a `strtolower` call).
 *
 * @psalm-immutable
 */
final class TNonEmptyLowercaseString extends \Psalm\Type\Atomic\TNonEmptyString
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'string';
        }
        return 'non-empty-lowercase-string';
    }
    /**
     * @return false
     */
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Denotes the `resource` type (e.g. a file handle).
 *
 * @psalm-immutable
 */
final class TResource extends Atomic
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'resource';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `scalar` super type (which can also result from an `is_scalar` check).
 * This type encompasses `float`, `int`, `bool` and `string`.
 *
 * @psalm-immutable
 */
class TScalar extends \Psalm\Type\Atomic\Scalar
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'scalar';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'scalar';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type;
use Psalm\Type\Union;
use function array_fill;
/**
 * @deprecated Will be removed in Psalm v6, please use TKeyedArrays with is_list=true instead.
 *
 * You may also use the \Psalm\Type::getNonEmptyListAtomic shortcut, which creates unsealed list-like shaped arrays
 * with one non-optional element, semantically equivalent to a TNonEmptyList.
 *
 *
 * Represents a non-empty list
 * @psalm-immutable
 */
class TNonEmptyList extends \Psalm\Type\Atomic\TList
{
    /**
     * @var positive-int|null
     */
    public $count;
    /**
     * @var positive-int|null
     */
    public $min_count;
    /** @var non-empty-lowercase-string */
    public const KEY = 'non-empty-list';
    /**
     * Constructs a new instance of a list
     *
     * @param positive-int|null $count
     * @param positive-int|null $min_count
     */
    public function __construct(Union $type_param, ?int $count = null, ?int $min_count = null, bool $from_docblock = \false)
    {
        $this->type_param = $type_param;
        $this->count = $count;
        $this->min_count = $min_count;
        $this->from_docblock = $from_docblock;
    }
    public function getKeyedArray() : \Psalm\Type\Atomic\TKeyedArray
    {
        if (!$this->count && !$this->min_count) {
            return Type::getNonEmptyListAtomic($this->type_param);
        }
        if ($this->count) {
            return new \Psalm\Type\Atomic\TKeyedArray(array_fill(0, $this->count, $this->type_param), null, null, \true, $this->from_docblock);
        }
        return new \Psalm\Type\Atomic\TKeyedArray(array_fill(0, $this->min_count, $this->type_param), null, [Type::getListKey(), $this->type_param], \true, $this->from_docblock);
    }
    /**
     * @param positive-int|null $count
     * @return static
     */
    public function setCount(?int $count) : self
    {
        if ($count === $this->count) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->count = $count;
        return $cloned;
    }
    public function getAssertionString() : string
    {
        return 'non-empty-list';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Type;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function get_class;
/**
 * @deprecated Will be removed in Psalm v6, please use TKeyedArrays with is_list=true instead.
 *
 * You may also use the \Psalm\Type::getListAtomic shortcut, which creates unsealed list-like shaped arrays
 * with all elements optional, semantically equivalent to a TList.
 *
 *
 * Represents an array that has some particularities:
 * - its keys are integers
 * - they start at 0
 * - they are consecutive and go upwards (no negative int)
 * @psalm-immutable
 */
class TList extends Atomic
{
    /**
     * @var Union
     */
    public $type_param;
    /** @var non-empty-lowercase-string */
    public const KEY = 'list';
    /**
     * Constructs a new instance of a list
     */
    public function __construct(Union $type_param, bool $from_docblock = \false)
    {
        $this->type_param = $type_param;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @return static
     */
    public function setTypeParam(Union $type_param) : self
    {
        if ($type_param === $this->type_param) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->type_param = $type_param;
        return $cloned;
    }
    public function getKeyedArray() : \Psalm\Type\Atomic\TKeyedArray
    {
        return Type::getListAtomic($this->type_param);
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return static::KEY . '<' . $this->type_param->getId($exact) . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return (new \Psalm\Type\Atomic\TArray([Type::getInt(), $this->type_param]))->toNamespacedString($namespace, $aliased_classes, $this_class, \true);
        }
        return static::KEY . '<' . $this->type_param->toNamespacedString($namespace, $aliased_classes, $this_class, \false) . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return 'array';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'array';
    }
    /**
     * @psalm-suppress InaccessibleProperty We're only acting on cloned instances
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $cloned = null;
        foreach ([Type::getInt(), $this->type_param] as $offset => $type_param) {
            $input_type_param = null;
            if (($input_type instanceof \Psalm\Type\Atomic\TGenericObject || $input_type instanceof \Psalm\Type\Atomic\TIterable || $input_type instanceof \Psalm\Type\Atomic\TArray) && isset($input_type->type_params[$offset])) {
                $input_type_param = $input_type->type_params[$offset];
            } elseif ($input_type instanceof \Psalm\Type\Atomic\TKeyedArray) {
                if ($offset === 0) {
                    $input_type_param = $input_type->getGenericKeyType();
                } else {
                    $input_type_param = $input_type->getGenericValueType();
                }
            } elseif ($input_type instanceof \Psalm\Type\Atomic\TList) {
                if ($offset === 0) {
                    continue;
                }
                $input_type_param = $input_type->type_param;
            }
            $type_param = TemplateStandinTypeReplacer::replace($type_param, $template_result, $codebase, $statements_analyzer, $input_type_param, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, null, $depth + 1);
            if ($offset === 1 && ($cloned || $this->type_param !== $type_param)) {
                $cloned ??= clone $this;
                $cloned->type_param = $type_param;
            }
        }
        return $cloned ?? $this;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        return $this->setTypeParam(TemplateInferredTypeReplacer::replace($this->type_param, $template_result, $codebase));
    }
    public function equals(Atomic $other_type, bool $ensure_source_equality) : bool
    {
        if (get_class($other_type) !== static::class) {
            return \false;
        }
        if (!$this->type_param->equals($other_type->type_param, $ensure_source_equality)) {
            return \false;
        }
        return \true;
    }
    public function getAssertionString() : string
    {
        if ($this->type_param->isMixed()) {
            return 'list';
        }
        return $this->getId();
    }
    protected function getChildNodeKeys() : array
    {
        return ['type_param'];
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
use function array_merge;
use function count;
use function implode;
use function strrpos;
use function substr;
/**
 * Denotes an object type that has generic parameters e.g. `ArrayObject<string, Foo\Bar>`
 *
 * @psalm-immutable
 */
final class TGenericObject extends \Psalm\Type\Atomic\TNamedObject
{
    /**
     * @use GenericTrait<non-empty-list<Union>>
     */
    use \Psalm\Type\Atomic\GenericTrait;
    /**
     * @var non-empty-list<Union>
     */
    public array $type_params;
    /** @var bool if the parameters have been remapped to another class */
    public $remapped_params = \false;
    /**
     * @param string                $value the name of the object
     * @param non-empty-list<Union> $type_params
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $extra_types
     */
    public function __construct(string $value, array $type_params, bool $remapped_params = \false, bool $is_static = \false, array $extra_types = [], bool $from_docblock = \false)
    {
        if ($value[0] === '\\') {
            $value = substr($value, 1);
        }
        $this->value = $value;
        $this->type_params = $type_params;
        $this->remapped_params = $remapped_params;
        $this->is_static = $is_static;
        $this->extra_types = $extra_types;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        $s = '';
        foreach ($this->type_params as $type_param) {
            $s .= $type_param->getKey() . ', ';
        }
        $extra_types = '';
        if ($include_extra && $this->extra_types) {
            $extra_types = '&' . implode('&', $this->extra_types);
        }
        return $this->value . '<' . substr($s, 0, -2) . '>' . $extra_types;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        $result = $this->toNamespacedString($namespace, $aliased_classes, $this_class, \true);
        $intersection = strrpos($result, '&');
        if ($intersection === \false || $analysis_php_version_id >= 80100) {
            return $result;
        }
        return substr($result, $intersection + 1);
    }
    public function equals(Atomic $other_type, bool $ensure_source_equality) : bool
    {
        if (!$other_type instanceof self) {
            return \false;
        }
        if (count($this->type_params) !== count($other_type->type_params)) {
            return \false;
        }
        foreach ($this->type_params as $i => $type_param) {
            if (!$type_param->equals($other_type->type_params[$i], $ensure_source_equality)) {
                return \false;
            }
        }
        return \true;
    }
    public function getAssertionString() : string
    {
        return $this->value;
    }
    protected function getChildNodeKeys() : array
    {
        return array_merge(parent::getChildNodeKeys(), ['type_params']);
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $types = $this->replaceTypeParamsTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        $intersection = $this->replaceIntersectionTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        if (!$types && !$intersection) {
            return $this;
        }
        return new static($this->value, $types ?? $this->type_params, $this->remapped_params, $this->is_static, $intersection ?? $this->extra_types);
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $type_params = $this->replaceTypeParamsTemplateTypesWithArgTypes($template_result, $codebase);
        $intersection = $this->replaceIntersectionTemplateTypesWithArgTypes($template_result, $codebase);
        if (!$type_params && !$intersection) {
            return $this;
        }
        return new static($this->value, $type_params ?? $this->type_params, \true, $this->is_static, $intersection ?? $this->extra_types);
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Represents a string whose value is that of a type found by gettype($var)
 *
 * @psalm-immutable
 */
final class TDependentGetType extends \Psalm\Type\Atomic\TString
{
    /**
     * Used to hold information as to what this refers to
     *
     * @var string
     */
    public $typeof;
    /**
     * @param string $typeof the variable id
     */
    public function __construct(string $typeof)
    {
        $this->typeof = $typeof;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Represents the type that is the result of a bitmask combination of its parameters.
 * This is the same concept as TIntMask but TIntMaskOf is used with a reference to constants in code
 * `int-mask-of<MyClass::CLASS_CONSTANT_*>` will corresponds to `0|1|2|3|4|5|6|7` if there are three constant 1, 2 and 4
 *
 * @psalm-immutable
 */
final class TIntMaskOf extends \Psalm\Type\Atomic\TInt
{
    /** @var TClassConstant|TKeyOf|TValueOf */
    public $value;
    /**
     * @param TClassConstant|TKeyOf|TValueOf $value
     */
    public function __construct(Atomic $value, bool $from_docblock = \false)
    {
        $this->value = $value;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'int-mask-of<' . $this->value->getKey() . '>';
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return 'int';
        }
        return 'int-mask-of<' . $this->value->toNamespacedString($namespace, $aliased_classes, $this_class, \false) . '>';
    }
    protected function getChildNodeKeys() : array
    {
        return ['value'];
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `literal-int` type, where the exact value is unknown but
 * we know that the int is not from user input
 *
 * @psalm-immutable
 */
final class TNonspecificLiteralInt extends \Psalm\Type\Atomic\TInt
{
    public function getId(bool $exact = \true, bool $nested = \true) : string
    {
        return 'literal-int';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'int';
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes a string that's also a numeric value e.g. `"5"`. It can result from `is_string($s) && is_numeric($s)`.
 *
 * @psalm-immutable
 */
final class TNumericString extends \Psalm\Type\Atomic\TNonEmptyString
{
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'string';
        }
        return 'numeric-string';
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'numeric-string';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'string';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Union;
/**
 * Denotes array known to be non-empty of the form `non-empty-array<TKey, TValue>`.
 * It expects an array with two elements, both union types.
 *
 * @psalm-immutable
 */
class TNonEmptyArray extends \Psalm\Type\Atomic\TArray
{
    /**
     * @var positive-int|null
     */
    public $count;
    /**
     * @var positive-int|null
     */
    public $min_count;
    /**
     * @var string
     */
    public $value = 'non-empty-array';
    /**
     * @param array{Union, Union} $type_params
     * @param positive-int|null $count
     * @param positive-int|null $min_count
     */
    public function __construct(array $type_params, ?int $count = null, ?int $min_count = null, string $value = 'non-empty-array', bool $from_docblock = \false)
    {
        $this->type_params = $type_params;
        $this->count = $count;
        $this->min_count = $min_count;
        $this->value = $value;
        $this->from_docblock = $from_docblock;
    }
    /**
     * @param positive-int|null $count
     * @return static
     */
    public function setCount(?int $count) : self
    {
        if ($count === $this->count) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->count = $count;
        return $cloned;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Denotes the `resource` type that has been closed (e.g. a file handle through `fclose()`).
 *
 * @psalm-immutable
 */
final class TClosedResource extends Atomic
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'closed-resource';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
/**
 * Denotes the `callable` type. Can result from an `is_callable` check.
 *
 * @psalm-immutable
 */
final class TCallable extends Atomic
{
    use \Psalm\Type\Atomic\CallableTrait;
    /**
     * @var string
     */
    public $value;
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : string
    {
        return 'callable';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return $this->params === null && $this->return_type === null;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $replaced = $this->replaceCallableTemplateTypesWithArgTypes($template_result, $codebase);
        if (!$replaced) {
            return $this;
        }
        return new static($this->value, $replaced[0], $replaced[1], $this->is_pure);
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        $replaced = $this->replaceCallableTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
        if (!$replaced) {
            return $this;
        }
        return new static($this->value, $replaced[0], $replaced[1], $this->is_pure);
    }
    protected function getChildNodeKeys() : array
    {
        return $this->getCallableChildNodeKeys();
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `literal-string` type, where the exact value is unknown but
 * we know that the string is not from user input
 *
 * @psalm-immutable
 */
class TNonspecificLiteralString extends \Psalm\Type\Atomic\TString
{
    public function getId(bool $exact = \true, bool $nested = \true) : string
    {
        if (!$exact) {
            return 'string';
        }
        return 'literal-string';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    public function getAssertionString() : string
    {
        return 'string';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Type\Atomic;
/**
 * Denotes the `object` type
 *
 * @psalm-immutable
 */
class TObject extends Atomic
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'object';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return $analysis_php_version_id >= 70200 ? $this->getKey() : null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \true;
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `array-key` type, used for something that could be the offset of an `array`.
 *
 * @psalm-immutable
 */
class TArrayKey extends \Psalm\Type\Atomic\Scalar
{
    public function getKey(bool $include_extra = \true) : string
    {
        return 'array-key';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $use_phpdoc_format ? '(int|string)' : 'array-key';
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Type\Atomic;
use function array_map;
use function array_merge;
use function implode;
/**
 * @psalm-immutable
 */
trait HasIntersectionTrait
{
    /**
     * @var array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties>
     */
    public array $extra_types = [];
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    private function getNamespacedIntersectionTypes(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if (!$this->extra_types) {
            return '';
        }
        return '&' . implode('&', array_map(
            /**
             * @param TNamedObject|TTemplateParam|TIterable|TObjectWithProperties $extra_type
             */
            static fn(Atomic $extra_type): string => $extra_type->toNamespacedString($namespace, $aliased_classes, $this_class, $use_phpdoc_format),
            $this->extra_types
        ));
    }
    /**
     * @param TNamedObject|TTemplateParam|TIterable|TObjectWithProperties $type
     * @return static
     */
    public function addIntersectionType(Atomic $type) : self
    {
        return $this->setIntersectionTypes(array_merge($this->extra_types, [$type->getKey() => $type]));
    }
    /**
     * @param array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties> $types
     * @return static
     */
    public function setIntersectionTypes(array $types) : self
    {
        if ($types === $this->extra_types) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->extra_types = $types;
        return $cloned;
    }
    /**
     * @return array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties>
     */
    public function getIntersectionTypes() : array
    {
        return $this->extra_types;
    }
    /**
     * @return array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties>|null
     */
    protected function replaceIntersectionTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : ?array
    {
        if (!$this->extra_types) {
            return null;
        }
        $new_types = [];
        foreach ($this->extra_types as $extra_type) {
            if ($extra_type instanceof \Psalm\Type\Atomic\TTemplateParam && isset($template_result->lower_bounds[$extra_type->param_name][$extra_type->defining_class])) {
                $template_type = TemplateStandinTypeReplacer::getMostSpecificTypeFromBounds($template_result->lower_bounds[$extra_type->param_name][$extra_type->defining_class], $codebase);
                foreach ($template_type->getAtomicTypes() as $template_type_part) {
                    if ($template_type_part instanceof \Psalm\Type\Atomic\TNamedObject) {
                        $new_types[$template_type_part->getKey()] = $template_type_part;
                    } elseif ($template_type_part instanceof \Psalm\Type\Atomic\TTemplateParam) {
                        $new_types[$template_type_part->getKey()] = $template_type_part;
                    }
                }
            } else {
                $extra_type = $extra_type->replaceTemplateTypesWithArgTypes($template_result, $codebase);
                $new_types[$extra_type->getKey()] = $extra_type;
            }
        }
        return $new_types === $this->extra_types ? null : $new_types;
    }
    /**
     * @return array<string, TNamedObject|TTemplateParam|TIterable|TObjectWithProperties>|null
     */
    protected function replaceIntersectionTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, ?Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : ?array
    {
        if (!$this->extra_types) {
            return null;
        }
        $new_types = [];
        foreach ($this->extra_types as $type) {
            $type = $type->replaceTemplateTypesWithStandins($template_result, $codebase, $statements_analyzer, $input_type, $input_arg_offset, $calling_class, $calling_function, $replace, $add_lower_bound, $depth);
            $new_types[$type->getKey()] = $type;
        }
        return $new_types === $this->extra_types ? null : $new_types;
    }
}
<?php

namespace Psalm\Type\Atomic;

use Psalm\Codebase;
use Psalm\Internal\Type\TemplateInferredTypeReplacer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Type\Atomic;
use Psalm\Type\Union;
/**
 * Represents the type used when using TKeyOf when the type of the array is a template
 *
 * @psalm-immutable
 */
final class TTemplateKeyOf extends Atomic
{
    /**
     * @var string
     */
    public $param_name;
    /**
     * @var string
     */
    public $defining_class;
    /**
     * @var Union
     */
    public $as;
    public function __construct(string $param_name, string $defining_class, Union $as, bool $from_docblock = \false)
    {
        $this->param_name = $param_name;
        $this->defining_class = $defining_class;
        $this->as = $as;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        return 'key-of<' . $this->param_name . '>';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        if (!$exact) {
            return 'key-of<' . $this->param_name . '>';
        }
        return 'key-of<' . $this->as->getId($exact) . '>';
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return 'key-of<' . $this->param_name . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        return null;
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        $as = TemplateInferredTypeReplacer::replace($this->as, $template_result, $codebase);
        if ($as === $this->as) {
            return $this;
        }
        return new static($this->param_name, $this->defining_class, $as);
    }
}
<?php

namespace Psalm\Type\Atomic;

/**
 * Denotes the `true` value type
 *
 * @psalm-immutable
 */
final class TTrue extends \Psalm\Type\Atomic\TBool
{
    /** @var true */
    public $value = \true;
    public function getKey(bool $include_extra = \true) : string
    {
        return 'true';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type\Atomic;

use function substr;
/**
 * Represents the type that is the result of a bitmask combination of its parameters.
 * `int-mask<1, 2, 4>` corresponds to `0|1|2|3|4|5|6|7`
 *
 * @psalm-immutable
 */
final class TIntMask extends \Psalm\Type\Atomic\TInt
{
    /** @var non-empty-array<TLiteralInt|TClassConstant> */
    public $values;
    /** @param non-empty-array<TLiteralInt|TClassConstant> $values */
    public function __construct(array $values, bool $from_docblock = \false)
    {
        $this->values = $values;
        $this->from_docblock = $from_docblock;
    }
    public function getKey(bool $include_extra = \true) : string
    {
        $s = '';
        foreach ($this->values as $value) {
            $s .= $value->getKey() . ', ';
        }
        return 'int-mask<' . substr($s, 0, -2) . '>';
    }
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        $s = '';
        foreach ($this->values as $value) {
            $s .= $value->getId($exact) . ', ';
        }
        return 'int-mask<' . substr($s, 0, -2) . '>';
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        if ($use_phpdoc_format) {
            return 'int';
        }
        $s = '';
        foreach ($this->values as $value) {
            $s .= $value->toNamespacedString($namespace, $aliased_classes, $this_class, \false) . ', ';
        }
        return 'int-mask<' . substr($s, 0, -2) . '>';
    }
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        return \false;
    }
}
<?php

namespace Psalm\Type;

use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Internal\TypeVisitor\FromDocblockSetter;
use Psalm\Type;
use Psalm\Type\Atomic\Scalar;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTrue;
use function count;
use function get_class;
use function get_object_vars;
use function strpos;
final class MutableUnion implements \Psalm\Type\TypeNode
{
    use \Psalm\Type\UnionTrait;
    /**
     * @var non-empty-array<string, Atomic>
     */
    private array $types;
    /**
     * Whether the type originated in a docblock
     *
     * @var bool
     */
    public $from_docblock = \false;
    /**
     * Whether the type originated from integer calculation
     *
     * @var bool
     */
    public $from_calculation = \false;
    /**
     * Whether the type originated from a property
     *
     * This helps turn isset($foo->bar) into a different sort of issue
     *
     * @var bool
     */
    public $from_property = \false;
    /**
     * Whether the type originated from *static* property
     *
     * Unlike non-static properties, static properties have no prescribed place
     * like __construct() to be initialized in
     *
     * @var bool
     */
    public $from_static_property = \false;
    /**
     * Whether the property that this type has been derived from has been initialized in a constructor
     *
     * @var bool
     */
    public $initialized = \true;
    /**
     * Which class the type was initialised in
     *
     * @var ?string
     */
    public $initialized_class;
    /**
     * Whether or not the type has been checked yet
     *
     * @var bool
     */
    public $checked = \false;
    /**
     * @var bool
     */
    public $failed_reconciliation = \false;
    /**
     * Whether or not to ignore issues with possibly-null values
     *
     * @var bool
     */
    public $ignore_nullable_issues = \false;
    /**
     * Whether or not to ignore issues with possibly-false values
     *
     * @var bool
     */
    public $ignore_falsable_issues = \false;
    /**
     * Whether or not to ignore issues with isset on this type
     *
     * @var bool
     */
    public $ignore_isset = \false;
    /**
     * Whether or not this variable is possibly undefined
     *
     * @var bool
     */
    public $possibly_undefined = \false;
    /**
     * Whether or not this variable is possibly undefined
     *
     * @var bool
     */
    public $possibly_undefined_from_try = \false;
    /**
     * whether this type had never set explicitly
     * since it's the bottom type, it's combined into everything else and lost
     *
     * @psalm-suppress PossiblyUnusedProperty used in setTypes and addType
     * @var bool
     */
    public $explicit_never = \false;
    /**
     * Whether or not this union had a template, since replaced
     *
     * @var bool
     */
    public $had_template = \false;
    /**
     * Whether or not this union comes from a template "as" default
     *
     * @var bool
     */
    public $from_template_default = \false;
    /**
     * @var array<string, TLiteralString>
     */
    private array $literal_string_types = [];
    /**
     * @var array<string, TClassString>
     */
    private array $typed_class_strings = [];
    /**
     * @var array<string, TLiteralInt>
     */
    private array $literal_int_types = [];
    /**
     * @var array<string, TLiteralFloat>
     */
    private array $literal_float_types = [];
    /**
     * True if the type was passed or returned by reference, or if the type refers to an object's
     * property or an item in an array. Note that this is not true for locally created references
     * that don't refer to properties or array items (see Context::$references_in_scope).
     *
     * @var bool
     */
    public $by_ref = \false;
    /**
     * @var bool
     */
    public $reference_free = \false;
    /**
     * @var bool
     */
    public $allow_mutations = \true;
    /**
     * @var bool
     */
    public $has_mutations = \true;
    /**
     * This is a cache of getId on non-exact mode
     */
    private ?string $id = null;
    /**
     * This is a cache of getId on exact mode
     */
    private ?string $exact_id = null;
    /**
     * @var array<string, DataFlowNode>
     */
    public $parent_nodes = [];
    /**
     * @var bool
     */
    public $different = \false;
    /** @psalm-suppress PossiblyUnusedProperty */
    public bool $propagate_parent_nodes = \false;
    /**
     * @psalm-external-mutation-free
     * @param non-empty-array<Atomic>  $types
     */
    public function setTypes(array $types) : self
    {
        $this->literal_float_types = [];
        $this->literal_int_types = [];
        $this->literal_string_types = [];
        $this->typed_class_strings = [];
        $this->checked = \false;
        $from_docblock = \false;
        $keyed_types = [];
        foreach ($types as $type) {
            $key = $type->getKey();
            $keyed_types[$key] = $type;
            if ($type instanceof TLiteralInt) {
                $this->literal_int_types[$key] = $type;
            } elseif ($type instanceof TLiteralString) {
                $this->literal_string_types[$key] = $type;
            } elseif ($type instanceof TLiteralFloat) {
                $this->literal_float_types[$key] = $type;
            } elseif ($type instanceof TClassString && ($type->as_type || $type instanceof TTemplateParamClass)) {
                $this->typed_class_strings[$key] = $type;
            } elseif ($type instanceof TNever) {
                $this->explicit_never = \true;
            }
            $from_docblock = $from_docblock || $type->from_docblock;
        }
        $this->types = $keyed_types;
        $this->from_docblock = $from_docblock;
        return $this;
    }
    /**
     * @psalm-external-mutation-free
     */
    public function addType(\Psalm\Type\Atomic $type) : self
    {
        $this->types[$type->getKey()] = $type;
        if ($type instanceof TLiteralString) {
            $this->literal_string_types[$type->getKey()] = $type;
        } elseif ($type instanceof TLiteralInt) {
            $this->literal_int_types[$type->getKey()] = $type;
        } elseif ($type instanceof TLiteralFloat) {
            $this->literal_float_types[$type->getKey()] = $type;
        } elseif ($type instanceof TString && $this->literal_string_types) {
            foreach ($this->literal_string_types as $key => $_) {
                unset($this->literal_string_types[$key], $this->types[$key]);
            }
            if (!$type instanceof TClassString || !$type->as_type && !$type instanceof TTemplateParamClass) {
                foreach ($this->typed_class_strings as $key => $_) {
                    unset($this->typed_class_strings[$key], $this->types[$key]);
                }
            }
        } elseif ($type instanceof TInt && $this->literal_int_types) {
            //we remove any literal that is already included in a wider type
            $int_type_in_range = TIntRange::convertToIntRange($type);
            foreach ($this->literal_int_types as $key => $literal_int_type) {
                if ($int_type_in_range->contains($literal_int_type->value)) {
                    unset($this->literal_int_types[$key], $this->types[$key]);
                }
            }
        } elseif ($type instanceof TFloat && $this->literal_float_types) {
            foreach ($this->literal_float_types as $key => $_) {
                unset($this->literal_float_types[$key], $this->types[$key]);
            }
        } elseif ($type instanceof TNever) {
            $this->explicit_never = \true;
        }
        $this->bustCache();
        return $this;
    }
    /**
     * @psalm-external-mutation-free
     */
    public function removeType(string $type_string) : bool
    {
        if (isset($this->types[$type_string])) {
            unset($this->types[$type_string]);
            if (strpos($type_string, '(')) {
                unset($this->literal_string_types[$type_string], $this->literal_int_types[$type_string], $this->literal_float_types[$type_string]);
            }
            $this->bustCache();
            return \true;
        }
        if ($type_string === 'string') {
            if ($this->literal_string_types) {
                foreach ($this->literal_string_types as $literal_key => $_) {
                    unset($this->types[$literal_key]);
                }
                $this->literal_string_types = [];
            }
            if ($this->typed_class_strings) {
                foreach ($this->typed_class_strings as $typed_class_key => $_) {
                    unset($this->types[$typed_class_key]);
                }
                $this->typed_class_strings = [];
            }
            unset($this->types['class-string'], $this->types['trait-string']);
        } elseif ($type_string === 'int' && $this->literal_int_types) {
            foreach ($this->literal_int_types as $literal_key => $_) {
                unset($this->types[$literal_key]);
            }
            $this->literal_int_types = [];
        } elseif ($type_string === 'float' && $this->literal_float_types) {
            foreach ($this->literal_float_types as $literal_key => $_) {
                unset($this->types[$literal_key]);
            }
            $this->literal_float_types = [];
        }
        return \false;
    }
    public function setFromDocblock(bool $fromDocblock = \true) : self
    {
        $this->from_docblock = $fromDocblock;
        (new FromDocblockSetter($fromDocblock))->traverseArray($this->types);
        return $this;
    }
    /**
     * @psalm-external-mutation-free
     */
    public function bustCache() : void
    {
        $this->id = null;
        $this->exact_id = null;
    }
    /**
     * @psalm-external-mutation-free
     * @param Union|MutableUnion $old_type
     * @param Union|MutableUnion|null $new_type
     */
    public function substitute($old_type, $new_type = null) : self
    {
        if ($this->hasMixed() && !$this->isEmptyMixed()) {
            return $this;
        }
        $old_type = $old_type->getBuilder();
        if ($new_type) {
            $new_type = $new_type->getBuilder();
        }
        if ($new_type && $new_type->ignore_nullable_issues) {
            $this->ignore_nullable_issues = \true;
        }
        if ($new_type && $new_type->ignore_falsable_issues) {
            $this->ignore_falsable_issues = \true;
        }
        foreach ($old_type->types as $old_type_part) {
            $had = isset($this->types[$old_type_part->getKey()]);
            $this->removeType($old_type_part->getKey());
            if (!$had) {
                if ($old_type_part instanceof TFalse && isset($this->types['bool']) && !isset($this->types['true'])) {
                    $this->removeType('bool');
                    $this->types['true'] = new TTrue();
                } elseif ($old_type_part instanceof TTrue && isset($this->types['bool']) && !isset($this->types['false'])) {
                    $this->removeType('bool');
                    $this->types['false'] = new TFalse();
                } elseif (isset($this->types['iterable'])) {
                    if ($old_type_part instanceof TNamedObject && $old_type_part->value === 'Traversable' && !isset($this->types['array'])) {
                        $this->removeType('iterable');
                        $this->types['array'] = new TArray([Type::getArrayKey(), Type::getMixed()]);
                    }
                    if ($old_type_part instanceof TArray && !isset($this->types['traversable'])) {
                        $this->removeType('iterable');
                        $this->types['traversable'] = new TNamedObject('Traversable');
                    }
                } elseif (isset($this->types['array-key'])) {
                    if ($old_type_part instanceof TString && !isset($this->types['int'])) {
                        $this->removeType('array-key');
                        $this->types['int'] = new TInt();
                    }
                    if ($old_type_part instanceof TInt && !isset($this->types['string'])) {
                        $this->removeType('array-key');
                        $this->types['string'] = new TString();
                    }
                }
            }
        }
        if ($new_type) {
            foreach ($new_type->types as $key => $new_type_part) {
                if (!isset($this->types[$key]) || $new_type_part instanceof Scalar && get_class($new_type_part) === get_class($this->types[$key])) {
                    $this->types[$key] = $new_type_part;
                } else {
                    $this->types[$key] = TypeCombiner::combine([$new_type_part, $this->types[$key]])->getSingleAtomic();
                }
            }
        } elseif (count($this->types) === 0) {
            $this->types['mixed'] = new TMixed();
        }
        $this->bustCache();
        return $this;
    }
    /**
     * @psalm-mutation-free
     */
    public function getBuilder() : self
    {
        return $this;
    }
    /**
     * @psalm-mutation-free
     */
    public function freeze() : \Psalm\Type\Union
    {
        /** @psalm-suppress InvalidArgument It's actually filtered internally */
        return new \Psalm\Type\Union($this->getAtomicTypes(), get_object_vars($this));
    }
    /**
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingAnyTypeHint
     */
    public static function visitMutable(\Psalm\Type\MutableTypeVisitor $visitor, &$node, bool $cloned) : bool
    {
        $result = \true;
        $changed = \false;
        foreach ($node->types as &$type) {
            $type_orig = $type;
            $result = $visitor->traverse($type);
            $changed = $changed || $type_orig !== $type;
            if (!$result) {
                break;
            }
        }
        unset($type);
        if ($changed) {
            $node->setTypes($node->types);
        }
        return $result;
    }
}
<?php

namespace Psalm\Type;

/**
 * An Enum class holding all the taint types that Psalm recognises
 */
final class TaintKindGroup
{
    public const ALL_INPUT = [\Psalm\Type\TaintKind::INPUT_HTML, \Psalm\Type\TaintKind::INPUT_HAS_QUOTES, \Psalm\Type\TaintKind::INPUT_SHELL, \Psalm\Type\TaintKind::INPUT_SQL, \Psalm\Type\TaintKind::INPUT_CALLABLE, \Psalm\Type\TaintKind::INPUT_EVAL, \Psalm\Type\TaintKind::INPUT_UNSERIALIZE, \Psalm\Type\TaintKind::INPUT_INCLUDE, \Psalm\Type\TaintKind::INPUT_SSRF, \Psalm\Type\TaintKind::INPUT_LDAP, \Psalm\Type\TaintKind::INPUT_FILE, \Psalm\Type\TaintKind::INPUT_HEADER, \Psalm\Type\TaintKind::INPUT_COOKIE];
}
<?php

namespace Psalm\Type;

use InvalidArgumentException;
use Psalm\CodeLocation;
use Psalm\Codebase;
use Psalm\Internal\TypeVisitor\CanContainObjectTypeVisitor;
use Psalm\Internal\TypeVisitor\ClasslikeReplacer;
use Psalm\Internal\TypeVisitor\ContainsClassLikeVisitor;
use Psalm\Internal\TypeVisitor\ContainsLiteralVisitor;
use Psalm\Internal\TypeVisitor\TemplateTypeCollector;
use Psalm\Internal\TypeVisitor\TypeChecker;
use Psalm\Internal\TypeVisitor\TypeScanner;
use Psalm\StatementsSource;
use Psalm\Storage\FileStorage;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonspecificLiteralInt;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\Atomic\TTrue;
use function array_filter;
use function array_merge;
use function array_unique;
use function count;
use function get_class;
use function implode;
use function ksort;
use function reset;
use function sort;
use function strpos;
/**
 * @psalm-immutable
 * @psalm-import-type TProperties from Union
 */
trait UnionTrait
{
    /**
     * Constructs an Union instance
     *
     * @psalm-external-mutation-free
     * @param non-empty-array<Atomic>     $types
     * @param TProperties $properties
     */
    public function __construct(array $types, array $properties = [])
    {
        foreach ($properties as $key => $value) {
            $this->{$key} = $value;
        }
        $this->literal_int_types = [];
        $this->literal_string_types = [];
        $this->literal_float_types = [];
        $this->typed_class_strings = [];
        $this->checked = \false;
        $this->id = null;
        $this->exact_id = null;
        $keyed_types = [];
        $from_docblock = $this->from_docblock;
        foreach ($types as $type) {
            $key = $type->getKey();
            $keyed_types[$key] = $type;
            if ($type instanceof TLiteralInt) {
                $this->literal_int_types[$key] = $type;
            } elseif ($type instanceof TLiteralString) {
                $this->literal_string_types[$key] = $type;
            } elseif ($type instanceof TLiteralFloat) {
                $this->literal_float_types[$key] = $type;
            } elseif ($type instanceof TClassString && ($type->as_type || $type instanceof TTemplateParamClass)) {
                $this->typed_class_strings[$key] = $type;
            } elseif ($type instanceof TNever) {
                $this->explicit_never = \true;
            }
            $from_docblock = $from_docblock || $type->from_docblock;
        }
        $this->from_docblock = $from_docblock;
        $this->types = $keyed_types;
    }
    /**
     * @psalm-mutation-free
     * @return non-empty-array<string, Atomic>
     */
    public function getAtomicTypes() : array
    {
        return $this->types;
    }
    /**
     * @psalm-mutation-free
     */
    public function __toString() : string
    {
        $types = [];
        $printed_int = \false;
        $printed_float = \false;
        $printed_string = \false;
        foreach ($this->types as $type) {
            if ($type instanceof TLiteralFloat) {
                if ($printed_float) {
                    continue;
                }
                $printed_float = \true;
            } elseif ($type instanceof TLiteralString) {
                if ($printed_string) {
                    continue;
                }
                $printed_string = \true;
            } elseif ($type instanceof TLiteralInt) {
                if ($printed_int) {
                    continue;
                }
                $printed_int = \true;
            }
            $types[] = $type->getId(\false);
        }
        sort($types);
        return implode('|', $types);
    }
    /**
     * @psalm-mutation-free
     */
    public function getKey() : string
    {
        $types = [];
        $printed_int = \false;
        $printed_float = \false;
        $printed_string = \false;
        foreach ($this->types as $type) {
            if ($type instanceof TLiteralFloat) {
                if ($printed_float) {
                    continue;
                }
                $types[] = 'float';
                $printed_float = \true;
            } elseif ($type instanceof TLiteralString) {
                if ($printed_string) {
                    continue;
                }
                $types[] = 'string';
                $printed_string = \true;
            } elseif ($type instanceof TLiteralInt) {
                if ($printed_int) {
                    continue;
                }
                $types[] = 'int';
                $printed_int = \true;
            } else {
                $types[] = $type->getKey();
            }
        }
        sort($types);
        return implode('|', $types);
    }
    /**
     * @psalm-mutation-free
     */
    public function getId(bool $exact = \true) : string
    {
        if ($exact && $this->exact_id) {
            return $this->exact_id;
        } elseif (!$exact && $this->id) {
            return $this->id;
        }
        $types = [];
        foreach ($this->types as $type) {
            $types[] = $type->getId($exact);
        }
        $types = array_unique($types);
        sort($types);
        if (count($types) > 1) {
            foreach ($types as $i => $type) {
                if (strpos($type, ' as ') && strpos($type, '(') === \false) {
                    $types[$i] = '(' . $type . ')';
                }
            }
        }
        $id = implode('|', $types);
        if ($exact) {
            /** @psalm-suppress ImpurePropertyAssignment, InaccessibleProperty Cache */
            $this->exact_id = $id;
        } else {
            /** @psalm-suppress ImpurePropertyAssignment, InaccessibleProperty Cache */
            $this->id = $id;
        }
        return $id;
    }
    /**
     * @param  array<lowercase-string, string> $aliased_classes
     * @psalm-mutation-free
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        $other_types = [];
        $literal_ints = [];
        $literal_strings = [];
        $has_non_literal_int = \false;
        $has_non_literal_string = \false;
        foreach ($this->types as $type) {
            $type_string = $type->toNamespacedString($namespace, $aliased_classes, $this_class, $use_phpdoc_format);
            if ($type instanceof TLiteralInt) {
                $literal_ints[] = $type_string;
            } elseif ($type instanceof TLiteralString) {
                $literal_strings[] = $type_string;
            } else {
                if (get_class($type) === TString::class) {
                    $has_non_literal_string = \true;
                } elseif (get_class($type) === TInt::class) {
                    $has_non_literal_int = \true;
                }
                $other_types[] = $type_string;
            }
        }
        if (count($literal_ints) <= 3 && !$has_non_literal_int) {
            $other_types = array_merge($other_types, $literal_ints);
        } else {
            $other_types[] = 'int';
        }
        if (count($literal_strings) <= 3 && !$has_non_literal_string) {
            $other_types = array_merge($other_types, $literal_strings);
        } else {
            $other_types[] = 'string';
        }
        sort($other_types);
        return implode('|', array_unique($other_types));
    }
    /**
     * @psalm-mutation-free
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string
    {
        if (!$this->isSingleAndMaybeNullable()) {
            if ($analysis_php_version_id < 80000) {
                return null;
            }
        } elseif ($analysis_php_version_id < 70000 || isset($this->types['null']) && $analysis_php_version_id < 70100) {
            return null;
        }
        $types = $this->types;
        $nullable = \false;
        if (isset($types['null']) && count($types) > 1) {
            unset($types['null']);
            $nullable = \true;
        }
        $falsable = \false;
        if (isset($types['false']) && count($types) > 1) {
            unset($types['false']);
            $falsable = \true;
        }
        $php_types = [];
        foreach ($types as $atomic_type) {
            $php_type = $atomic_type->toPhpString($namespace, $aliased_classes, $this_class, $analysis_php_version_id);
            if (!$php_type) {
                return null;
            }
            $php_types[] = $php_type;
        }
        if ($falsable) {
            if ($nullable) {
                $php_types['null'] = 'null';
            }
            $php_types['false'] = 'false';
            ksort($php_types);
            return implode('|', array_unique($php_types));
        }
        if ($analysis_php_version_id < 80000) {
            return ($nullable ? '?' : '') . implode('|', array_unique($php_types));
        }
        if ($nullable) {
            $php_types['null'] = 'null';
        }
        return implode('|', array_unique($php_types));
    }
    /**
     * @psalm-mutation-free
     */
    public function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool
    {
        if (!$this->isSingleAndMaybeNullable() && $analysis_php_version_id < 80000) {
            return \false;
        }
        $types = $this->types;
        if (isset($types['null'])) {
            if (count($types) > 1) {
                unset($types['null']);
            } else {
                return \false;
            }
        }
        return !array_filter($types, static fn($atomic_type): bool => !$atomic_type->canBeFullyExpressedInPhp($analysis_php_version_id));
    }
    /**
     * @psalm-mutation-free
     */
    public function hasType(string $type_string) : bool
    {
        return isset($this->types[$type_string]);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasArray() : bool
    {
        return isset($this->types['array']);
    }
    /**
     * @return TArray|TKeyedArray|TClassStringMap
     */
    public function getArray() : \Psalm\Type\Atomic
    {
        if ($this->types['array'] instanceof TList) {
            return $this->types['array']->getKeyedArray();
        }
        return $this->types['array'];
    }
    /**
     * @psalm-mutation-free
     */
    public function hasIterable() : bool
    {
        return isset($this->types['iterable']);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasList() : bool
    {
        return isset($this->types['array']) && $this->types['array'] instanceof TKeyedArray && $this->types['array']->is_list;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasClassStringMap() : bool
    {
        return isset($this->types['array']) && $this->types['array'] instanceof TClassStringMap;
    }
    /**
     * @psalm-mutation-free
     */
    public function isTemplatedClassString() : bool
    {
        return $this->isSingle() && count(array_filter($this->types, static fn($type): bool => $type instanceof TTemplateParamClass)) === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasArrayAccessInterface(Codebase $codebase) : bool
    {
        return (bool) array_filter($this->types, static fn($type): bool => $type->hasArrayAccessInterface($codebase));
    }
    /**
     * @psalm-mutation-free
     */
    public function hasCallableType() : bool
    {
        return $this->getCallableTypes() || $this->getClosureTypes();
    }
    /**
     * @psalm-mutation-free
     * @return array<string, TCallable>
     */
    public function getCallableTypes() : array
    {
        return array_filter($this->types, static fn($type): bool => $type instanceof TCallable);
    }
    /**
     * @psalm-mutation-free
     * @return array<string, TClosure>
     */
    public function getClosureTypes() : array
    {
        return array_filter($this->types, static fn($type): bool => $type instanceof TClosure);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasObject() : bool
    {
        return isset($this->types['object']);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasObjectType() : bool
    {
        foreach ($this->types as $type) {
            if ($type->isObjectType()) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @psalm-mutation-free
     */
    public function canContainObjectType(Codebase $codebase) : bool
    {
        $object_type_visitor = new CanContainObjectTypeVisitor($codebase);
        $object_type_visitor->traverseArray($this->types);
        return $object_type_visitor->matches();
    }
    /**
     * @psalm-mutation-free
     */
    public function isObjectType() : bool
    {
        foreach ($this->types as $type) {
            if (!$type->isObjectType()) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasNamedObjectType() : bool
    {
        foreach ($this->types as $type) {
            if ($type->isNamedObjectType()) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @psalm-mutation-free
     */
    public function isStaticObject() : bool
    {
        foreach ($this->types as $type) {
            if (!$type instanceof TNamedObject || !$type->is_static) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasStaticObject() : bool
    {
        foreach ($this->types as $type) {
            if ($type instanceof TNamedObject && $type->is_static) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @psalm-mutation-free
     */
    public function isNullable() : bool
    {
        if (isset($this->types['null'])) {
            return \true;
        }
        foreach ($this->types as $type) {
            if ($type instanceof TTemplateParam && $type->as->isNullable()) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @psalm-mutation-free
     */
    public function isFalsable() : bool
    {
        if (isset($this->types['false'])) {
            return \true;
        }
        foreach ($this->types as $type) {
            if ($type instanceof TTemplateParam && $type->as->isFalsable()) {
                return \true;
            }
        }
        return \false;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasBool() : bool
    {
        return isset($this->types['bool']) || isset($this->types['false']) || isset($this->types['true']);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasNull() : bool
    {
        return isset($this->types['null']);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasString() : bool
    {
        return isset($this->types['string']) || isset($this->types['class-string']) || isset($this->types['trait-string']) || isset($this->types['numeric-string']) || isset($this->types['callable-string']) || isset($this->types['array-key']) || $this->literal_string_types || $this->typed_class_strings;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasLowercaseString() : bool
    {
        return isset($this->types['string']) && ($this->types['string'] instanceof TLowercaseString || $this->types['string'] instanceof TNonEmptyLowercaseString);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasLiteralClassString() : bool
    {
        return count($this->typed_class_strings) > 0;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasInt() : bool
    {
        return isset($this->types['int']) || isset($this->types['array-key']) || $this->literal_int_types || array_filter($this->types, static fn(\Psalm\Type\Atomic $type): bool => $type instanceof TIntRange);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasArrayKey() : bool
    {
        return isset($this->types['array-key']);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasFloat() : bool
    {
        return isset($this->types['float']) || $this->literal_float_types;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasScalar() : bool
    {
        return isset($this->types['scalar']);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasNumeric() : bool
    {
        return isset($this->types['numeric']);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasScalarType() : bool
    {
        return isset($this->types['int']) || isset($this->types['float']) || isset($this->types['string']) || isset($this->types['class-string']) || isset($this->types['trait-string']) || isset($this->types['bool']) || isset($this->types['false']) || isset($this->types['true']) || isset($this->types['numeric']) || isset($this->types['numeric-string']) || $this->literal_int_types || $this->literal_float_types || $this->literal_string_types || $this->typed_class_strings;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasTemplate() : bool
    {
        return (bool) array_filter($this->types, static fn(\Psalm\Type\Atomic $type): bool => $type instanceof TTemplateParam || $type instanceof TNamedObject && $type->extra_types && array_filter($type->extra_types, static fn($t): bool => $t instanceof TTemplateParam));
    }
    /**
     * @psalm-mutation-free
     */
    public function hasConditional() : bool
    {
        return (bool) array_filter($this->types, static fn(\Psalm\Type\Atomic $type): bool => $type instanceof TConditional);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasTemplateOrStatic() : bool
    {
        return (bool) array_filter($this->types, static fn(\Psalm\Type\Atomic $type): bool => $type instanceof TTemplateParam || $type instanceof TNamedObject && ($type->is_static || $type->extra_types && array_filter($type->extra_types, static fn($t): bool => $t instanceof TTemplateParam)));
    }
    /**
     * @psalm-mutation-free
     */
    public function hasMixed() : bool
    {
        return isset($this->types['mixed']);
    }
    /**
     * @psalm-mutation-free
     */
    public function isMixed() : bool
    {
        return isset($this->types['mixed']) && count($this->types) === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function isEmptyMixed() : bool
    {
        return isset($this->types['mixed']) && $this->types['mixed'] instanceof TEmptyMixed && count($this->types) === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function isVanillaMixed() : bool
    {
        return isset($this->types['mixed']) && get_class($this->types['mixed']) === TMixed::class && !$this->types['mixed']->from_loop_isset && count($this->types) === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function isArrayKey() : bool
    {
        return isset($this->types['array-key']) && count($this->types) === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function isNull() : bool
    {
        return count($this->types) === 1 && isset($this->types['null']);
    }
    /**
     * @psalm-mutation-free
     */
    public function isFalse() : bool
    {
        return count($this->types) === 1 && isset($this->types['false']);
    }
    /**
     * @psalm-mutation-free
     */
    public function isAlwaysFalsy() : bool
    {
        foreach ($this->getAtomicTypes() as $atomic_type) {
            if (!$atomic_type->isFalsy()) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function isTrue() : bool
    {
        return count($this->types) === 1 && isset($this->types['true']);
    }
    /**
     * @psalm-mutation-free
     */
    public function isAlwaysTruthy() : bool
    {
        if ($this->possibly_undefined || $this->possibly_undefined_from_try) {
            return \false;
        }
        foreach ($this->getAtomicTypes() as $atomic_type) {
            if (!$atomic_type->isTruthy()) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function isVoid() : bool
    {
        return isset($this->types['void']) && count($this->types) === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function isNever() : bool
    {
        return isset($this->types['never']) && count($this->types) === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function isGenerator() : bool
    {
        return count($this->types) === 1 && ($single_type = reset($this->types)) instanceof TNamedObject && $single_type->value === 'Generator';
    }
    /**
     * @psalm-mutation-free
     */
    public function isSingle() : bool
    {
        $type_count = count($this->types);
        $int_literal_count = count($this->literal_int_types);
        $string_literal_count = count($this->literal_string_types);
        $float_literal_count = count($this->literal_float_types);
        if ($int_literal_count && $string_literal_count || $int_literal_count && $float_literal_count || $string_literal_count && $float_literal_count) {
            return \false;
        }
        if ($int_literal_count || $string_literal_count || $float_literal_count) {
            $type_count -= $int_literal_count + $string_literal_count + $float_literal_count - 1;
        }
        return $type_count === 1;
    }
    /**
     * @psalm-mutation-free
     */
    public function isSingleAndMaybeNullable() : bool
    {
        $is_nullable = isset($this->types['null']);
        $type_count = count($this->types);
        if ($type_count === 1 && $is_nullable) {
            return \false;
        }
        $int_literal_count = count($this->literal_int_types);
        $string_literal_count = count($this->literal_string_types);
        $float_literal_count = count($this->literal_float_types);
        if ($int_literal_count && $string_literal_count || $int_literal_count && $float_literal_count || $string_literal_count && $float_literal_count) {
            return \false;
        }
        if ($int_literal_count || $string_literal_count || $float_literal_count) {
            $type_count -= $int_literal_count + $string_literal_count + $float_literal_count - 1;
        }
        return $type_count - (int) $is_nullable === 1;
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is an int
     */
    public function isInt(bool $check_templates = \false) : bool
    {
        return count(array_filter($this->types, static fn($type): bool => $type instanceof TInt || $check_templates && $type instanceof TTemplateParam && $type->as->isInt())) === count($this->types);
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is a float
     */
    public function isFloat() : bool
    {
        if (!$this->isSingle()) {
            return \false;
        }
        return isset($this->types['float']) || $this->literal_float_types;
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is a string
     */
    public function isString(bool $check_templates = \false) : bool
    {
        return count(array_filter($this->types, static fn($type): bool => $type instanceof TString || $check_templates && $type instanceof TTemplateParam && $type->as->isString())) === count($this->types);
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is a boolean
     */
    public function isBool() : bool
    {
        if (!$this->isSingle()) {
            return \false;
        }
        return isset($this->types['bool']);
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is an array
     */
    public function isArray() : bool
    {
        if (!$this->isSingle()) {
            return \false;
        }
        return isset($this->types['array']);
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is a string literal with only one possible value
     */
    public function isSingleStringLiteral() : bool
    {
        return count($this->types) === 1 && count($this->literal_string_types) === 1;
    }
    /**
     * @throws InvalidArgumentException if isSingleStringLiteral is false
     * @psalm-mutation-free
     * @return TLiteralString the only string literal represented by this union type
     */
    public function getSingleStringLiteral() : TLiteralString
    {
        if (count($this->types) !== 1 || count($this->literal_string_types) !== 1) {
            throw new InvalidArgumentException('Not a string literal');
        }
        return reset($this->literal_string_types);
    }
    /**
     * @psalm-mutation-free
     */
    public function allStringLiterals() : bool
    {
        foreach ($this->types as $atomic_key_type) {
            if (!$atomic_key_type instanceof TLiteralString) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function allIntLiterals() : bool
    {
        foreach ($this->types as $atomic_key_type) {
            if (!$atomic_key_type instanceof TLiteralInt) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function allFloatLiterals() : bool
    {
        foreach ($this->types as $atomic_key_type) {
            if (!$atomic_key_type instanceof TLiteralFloat) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     * @psalm-assert-if-true array<
     *     array-key,
     *     TLiteralString|TLiteralInt|TLiteralFloat|TFalse|TTrue
     * > $this->getAtomicTypes()
     */
    public function allSpecificLiterals() : bool
    {
        foreach ($this->types as $atomic_key_type) {
            if (!$atomic_key_type instanceof TLiteralString && !$atomic_key_type instanceof TLiteralInt && !$atomic_key_type instanceof TLiteralFloat && !$atomic_key_type instanceof TFalse && !$atomic_key_type instanceof TTrue) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     * @psalm-assert-if-true array<
     *     array-key,
     *     TLiteralString|TLiteralInt|TLiteralFloat|TNonspecificLiteralString|TNonSpecificLiteralInt|TFalse|TTrue
     * > $this->getAtomicTypes()
     */
    public function allLiterals() : bool
    {
        foreach ($this->types as $atomic_key_type) {
            if (!$atomic_key_type instanceof TLiteralString && !$atomic_key_type instanceof TLiteralInt && !$atomic_key_type instanceof TLiteralFloat && !$atomic_key_type instanceof TNonspecificLiteralString && !$atomic_key_type instanceof TNonspecificLiteralInt && !$atomic_key_type instanceof TFalse && !$atomic_key_type instanceof TTrue) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasLiteralValue() : bool
    {
        return $this->literal_int_types || $this->literal_string_types || $this->literal_float_types || isset($this->types['false']) || isset($this->types['true']);
    }
    /**
     * @psalm-mutation-free
     */
    public function isSingleLiteral() : bool
    {
        return count($this->types) === 1 && count($this->literal_int_types) + count($this->literal_string_types) + count($this->literal_float_types) === 1;
    }
    /**
     * @psalm-mutation-free
     * @return TLiteralInt|TLiteralString|TLiteralFloat
     */
    public function getSingleLiteral()
    {
        if (!$this->isSingleLiteral()) {
            throw new InvalidArgumentException("Not a single literal");
        }
        return ($literal = reset($this->literal_int_types)) !== \false ? $literal : (($literal = reset($this->literal_string_types)) !== \false ? $literal : reset($this->literal_float_types));
    }
    /**
     * @psalm-mutation-free
     */
    public function hasLiteralString() : bool
    {
        return count($this->literal_string_types) > 0;
    }
    /**
     * @psalm-mutation-free
     */
    public function hasLiteralInt() : bool
    {
        return count($this->literal_int_types) > 0;
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is a int literal with only one possible value
     */
    public function isSingleIntLiteral() : bool
    {
        return count($this->types) === 1 && count($this->literal_int_types) === 1;
    }
    /**
     * @throws InvalidArgumentException if isSingleIntLiteral is false
     * @psalm-mutation-free
     * @return TLiteralInt the only int literal represented by this union type
     */
    public function getSingleIntLiteral() : TLiteralInt
    {
        if (count($this->types) !== 1 || count($this->literal_int_types) !== 1) {
            throw new InvalidArgumentException('Not an int literal');
        }
        return reset($this->literal_int_types);
    }
    /**
     * @param  array<string>    $suppressed_issues
     * @param  array<string, bool> $phantom_classes
     */
    public function check(StatementsSource $source, CodeLocation $code_location, array $suppressed_issues, array $phantom_classes = [], bool $inferred = \true, bool $inherited = \false, bool $prevent_template_covariance = \false, ?string $calling_method_id = null) : bool
    {
        if ($this->checked) {
            return \true;
        }
        $checker = new TypeChecker($source, $code_location, $suppressed_issues, $phantom_classes, $inferred, $inherited, $prevent_template_covariance, $calling_method_id);
        $checker->traverseArray($this->types);
        /** @psalm-suppress InaccessibleProperty, ImpurePropertyAssignment Does not affect anything else */
        $this->checked = \true;
        return !$checker->hasErrors();
    }
    /**
     * @param  array<string, mixed> $phantom_classes
     */
    public function queueClassLikesForScanning(Codebase $codebase, ?FileStorage $file_storage = null, array $phantom_classes = []) : void
    {
        $scanner_visitor = new TypeScanner($codebase->scanner, $file_storage, $phantom_classes);
        /** @psalm-suppress ImpureMethodCall */
        $scanner_visitor->traverseArray($this->types);
    }
    /**
     * @param  lowercase-string $fq_class_like_name
     * @psalm-mutation-free
     */
    public function containsClassLike(string $fq_class_like_name) : bool
    {
        $classlike_visitor = new ContainsClassLikeVisitor($fq_class_like_name);
        /** @psalm-suppress ImpureMethodCall Actually mutation-free */
        $classlike_visitor->traverseArray($this->types);
        return $classlike_visitor->matches();
    }
    /**
     * @return static
     */
    public function replaceClassLike(string $old, string $new) : self
    {
        $type = $this;
        (new ClasslikeReplacer($old, $new))->traverse($type);
        return $type;
    }
    /** @psalm-mutation-free */
    public function containsAnyLiteral() : bool
    {
        $literal_visitor = new ContainsLiteralVisitor();
        /** @psalm-suppress ImpureMethodCall Actually mutation-free */
        $literal_visitor->traverseArray($this->types);
        return $literal_visitor->matches();
    }
    /**
     * @psalm-mutation-free
     * @return list<TTemplateParam>
     */
    public function getTemplateTypes() : array
    {
        $template_type_collector = new TemplateTypeCollector();
        /** @psalm-suppress ImpureMethodCall Actually mutation-free */
        $template_type_collector->traverseArray($this->types);
        return $template_type_collector->getTemplateTypes();
    }
    /**
     * @psalm-mutation-free
     */
    public function equals(self $other_type, bool $ensure_source_equality = \true, bool $ensure_parent_node_equality = \true, bool $ensure_possibly_undefined_equality = \true) : bool
    {
        if ($other_type === $this) {
            return \true;
        }
        if ($other_type->id && $this->id && $other_type->id !== $this->id) {
            return \false;
        }
        if ($other_type->exact_id && $this->exact_id && $other_type->exact_id !== $this->exact_id) {
            return \false;
        }
        if ($this->possibly_undefined !== $other_type->possibly_undefined && $ensure_possibly_undefined_equality) {
            return \false;
        }
        if ($this->had_template !== $other_type->had_template) {
            return \false;
        }
        if ($this->possibly_undefined_from_try !== $other_type->possibly_undefined_from_try) {
            return \false;
        }
        if ($this->from_calculation !== $other_type->from_calculation) {
            return \false;
        }
        if ($this->initialized !== $other_type->initialized) {
            return \false;
        }
        if ($ensure_source_equality && $this->from_docblock !== $other_type->from_docblock) {
            return \false;
        }
        if (count($this->types) !== count($other_type->types)) {
            return \false;
        }
        if ($ensure_parent_node_equality && $this->parent_nodes !== $other_type->parent_nodes) {
            return \false;
        }
        if ($this->different || $other_type->different) {
            return \false;
        }
        $other_atomic_types = $other_type->types;
        foreach ($this->types as $key => $atomic_type) {
            if (!isset($other_atomic_types[$key])) {
                return \false;
            }
            if (!$atomic_type->equals($other_atomic_types[$key], $ensure_source_equality)) {
                return \false;
            }
        }
        return \true;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, TLiteralString>
     */
    public function getLiteralStrings() : array
    {
        return $this->literal_string_types;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, TLiteralInt>
     */
    public function getLiteralInts() : array
    {
        return $this->literal_int_types;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, TIntRange>
     */
    public function getRangeInts() : array
    {
        $ranges = [];
        foreach ($this->getAtomicTypes() as $atomic) {
            if ($atomic instanceof TIntRange) {
                $ranges[$atomic->getKey()] = $atomic;
            }
        }
        return $ranges;
    }
    /**
     * @psalm-mutation-free
     * @return array<string, TLiteralFloat>
     */
    public function getLiteralFloats() : array
    {
        return $this->literal_float_types;
    }
    /**
     * @psalm-mutation-free
     * @return bool true if this is a float literal with only one possible value
     */
    public function isSingleFloatLiteral() : bool
    {
        return count($this->types) === 1 && count($this->literal_float_types) === 1;
    }
    /**
     * @psalm-mutation-free
     * @throws InvalidArgumentException if isSingleFloatLiteral is false
     * @return TLiteralFloat the only float literal represented by this union type
     */
    public function getSingleFloatLiteral() : TLiteralFloat
    {
        if (count($this->types) !== 1 || count($this->literal_float_types) !== 1) {
            throw new InvalidArgumentException('Not a float literal');
        }
        return reset($this->literal_float_types);
    }
    /**
     * @psalm-mutation-free
     */
    public function hasLiteralFloat() : bool
    {
        return count($this->literal_float_types) > 0;
    }
    /**
     * @psalm-mutation-free
     */
    public function getSingleAtomic() : \Psalm\Type\Atomic
    {
        return reset($this->types);
    }
    /**
     * @psalm-mutation-free
     */
    public function isEmptyArray() : bool
    {
        return count($this->types) === 1 && isset($this->types['array']) && $this->types['array'] instanceof TArray && $this->types['array']->isEmptyArray();
    }
    /**
     * @psalm-mutation-free
     */
    public function isUnionEmpty() : bool
    {
        return $this->types === [];
    }
    public function visit(\Psalm\Type\TypeVisitor $visitor) : bool
    {
        foreach ($this->types as $type) {
            if ($visitor->traverse($type) === \false) {
                return \false;
            }
        }
        return \true;
    }
}
<?php

namespace Psalm\Type;

/**
 * An Enum class holding all the taint types that Psalm recognises
 */
final class TaintKind
{
    public const INPUT_CALLABLE = 'callable';
    public const INPUT_UNSERIALIZE = 'unserialize';
    public const INPUT_INCLUDE = 'include';
    public const INPUT_EVAL = 'eval';
    public const INPUT_LDAP = 'ldap';
    public const INPUT_SQL = 'sql';
    public const INPUT_HTML = 'html';
    public const INPUT_HAS_QUOTES = 'has_quotes';
    public const INPUT_SHELL = 'shell';
    public const INPUT_SSRF = 'ssrf';
    public const INPUT_FILE = 'file';
    public const INPUT_COOKIE = 'cookie';
    public const INPUT_HEADER = 'header';
    public const USER_SECRET = 'user_secret';
    public const SYSTEM_SECRET = 'system_secret';
}
<?php

namespace Psalm\Type;

use InvalidArgumentException;
use Psalm\Codebase;
use Psalm\Exception\TypeParseTreeException;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Internal\Type\TemplateResult;
use Psalm\Internal\Type\TemplateStandinTypeReplacer;
use Psalm\Internal\Type\TypeAlias;
use Psalm\Internal\Type\TypeAlias\LinkableTypeAlias;
use Psalm\Internal\TypeVisitor\ClasslikeReplacer;
use Psalm\Type;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TCallable;
use Psalm\Type\Atomic\TCallableArray;
use Psalm\Type\Atomic\TCallableKeyedArray;
use Psalm\Type\Atomic\TCallableList;
use Psalm\Type\Atomic\TCallableObject;
use Psalm\Type\Atomic\TCallableString;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClassStringMap;
use Psalm\Type\Atomic\TClosedResource;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TDependentGetClass;
use Psalm\Type\Atomic\TEmptyMixed;
use Psalm\Type\Atomic\TEmptyNumeric;
use Psalm\Type\Atomic\TEmptyScalar;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TGenericObject;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TList;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyArray;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonEmptyMixed;
use Psalm\Type\Atomic\TNonEmptyNonspecificLiteralString;
use Psalm\Type\Atomic\TNonEmptyScalar;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonFalsyString;
use Psalm\Type\Atomic\TNonspecificLiteralInt;
use Psalm\Type\Atomic\TNonspecificLiteralString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TResource;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTraitString;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Atomic\TTypeAlias;
use Psalm\Type\Atomic\TVoid;
use function array_filter;
use function array_keys;
use function count;
use function get_class;
use function is_array;
use function is_numeric;
use function strpos;
use function strtolower;
/**
 * @psalm-immutable
 */
abstract class Atomic implements \Psalm\Type\TypeNode
{
    public function __construct(bool $from_docblock = \false)
    {
        $this->from_docblock = $from_docblock;
    }
    protected function __clone()
    {
    }
    /**
     * Whether or not the type has been checked yet
     *
     * @var bool
     */
    public $checked = \false;
    /**
     * Whether or not the type comes from a docblock
     *
     * @var bool
     */
    public $from_docblock = \false;
    /**
     * @var ?int
     */
    public $offset_start;
    /**
     * @var ?int
     */
    public $offset_end;
    /**
     * @var ?string
     */
    public $text;
    /**
     * @return static
     */
    public function setFromDocblock(bool $from_docblock) : self
    {
        if ($from_docblock === $this->from_docblock) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->from_docblock = $from_docblock;
        return $cloned;
    }
    /**
     * @return static
     */
    public function replaceClassLike(string $old, string $new) : self
    {
        $type = $this;
        /** @psalm-suppress ImpureMethodCall ClasslikeReplacer will always clone */
        (new ClasslikeReplacer($old, $new))->traverse($type);
        return $type;
    }
    /**
     * @psalm-suppress InaccessibleProperty Allowed during construction
     * @param int $analysis_php_version_id contains php version when the type comes from signature
     * @param array<string, array<string, Union>> $template_type_map
     * @param array<string, TypeAlias> $type_aliases
     */
    public static function create(string $value, ?int $analysis_php_version_id = null, array $template_type_map = [], array $type_aliases = [], ?int $offset_start = null, ?int $offset_end = null, ?string $text = null, bool $from_docblock = \false) : \Psalm\Type\Atomic
    {
        $result = self::createInner($value, $analysis_php_version_id, $template_type_map, $type_aliases, $from_docblock);
        $result->offset_start = $offset_start;
        $result->offset_end = $offset_end;
        $result->text = $text;
        $result->from_docblock = $from_docblock;
        return $result;
    }
    /**
     * @psalm-suppress InaccessibleProperty Allowed during construction
     * @param int $analysis_php_version_id contains php version when the type comes from signature
     * @param array<string, array<string, Union>> $template_type_map
     * @param array<string, TypeAlias> $type_aliases
     */
    private static function createInner(string $value, ?int $analysis_php_version_id = null, array $template_type_map = [], array $type_aliases = [], bool $from_docblock = \false) : \Psalm\Type\Atomic
    {
        switch ($value) {
            case 'int':
                return new TInt();
            case 'float':
                return new TFloat();
            case 'string':
                return new TString();
            case 'bool':
                return new TBool();
            case 'void':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 70100) {
                    return new TVoid();
                }
                break;
            case 'array-key':
                return new TArrayKey();
            case 'iterable':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 70100) {
                    return new TIterable();
                }
                break;
            case 'never':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 80100) {
                    return new TNever();
                }
                break;
            case 'never-return':
            case 'never-returns':
            case 'no-return':
            case 'empty':
                return new TNever();
            case 'object':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 70200) {
                    return new TObject();
                }
                break;
            case 'callable':
                return new TCallable();
            case 'pure-callable':
                $type = new TCallable();
                $type->is_pure = \true;
                return $type;
            case 'array':
            case 'associative-array':
                return new TArray([new \Psalm\Type\Union([new TArrayKey($from_docblock)]), new \Psalm\Type\Union([new TMixed(\false, $from_docblock)])]);
            case 'non-empty-array':
                return new TNonEmptyArray([new \Psalm\Type\Union([new TArrayKey($from_docblock)]), new \Psalm\Type\Union([new TMixed(\false, $from_docblock)])]);
            case 'callable-array':
                return new TCallableArray([new \Psalm\Type\Union([new TArrayKey($from_docblock)]), new \Psalm\Type\Union([new TMixed(\false, $from_docblock)])]);
            case 'list':
                return Type::getListAtomic(Type::getMixed(\false, $from_docblock));
            case 'non-empty-list':
                return Type::getNonEmptyListAtomic(Type::getMixed(\false, $from_docblock));
            case 'non-empty-string':
                return new TNonEmptyString();
            case 'truthy-string':
            case 'non-falsy-string':
                return new TNonFalsyString();
            case 'lowercase-string':
                return new TLowercaseString();
            case 'non-empty-lowercase-string':
                return new TNonEmptyLowercaseString();
            case 'resource':
                return $analysis_php_version_id !== null ? new TNamedObject($value) : new TResource();
            case 'resource (closed)':
            case 'closed-resource':
                return new TClosedResource();
            case 'positive-int':
                return new TIntRange(1, null);
            case 'non-positive-int':
                return new TIntRange(null, 0);
            case 'negative-int':
                return new TIntRange(null, -1);
            case 'non-negative-int':
                return new TIntRange(0, null);
            case 'numeric':
                return $analysis_php_version_id !== null ? new TNamedObject($value) : new TNumeric();
            case 'true':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 80200) {
                    return new TTrue();
                }
                return new TNamedObject($value);
            case 'false':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 80000) {
                    return new TFalse();
                }
                return new TNamedObject($value);
            case 'scalar':
                return $analysis_php_version_id !== null ? new TNamedObject($value) : new TScalar();
            case 'null':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 80000) {
                    return new TNull();
                }
                return new TNamedObject($value);
            case 'mixed':
                if ($analysis_php_version_id === null || $analysis_php_version_id >= 80000) {
                    return new TMixed();
                }
                return new TNamedObject($value);
            case 'callable-object':
                return new TCallableObject();
            case 'stringable-object':
                return new TObjectWithProperties([], ['__tostring' => 'string']);
            case 'class-string':
                return new TClassString();
            case 'interface-string':
                $type = new TClassString();
                $type->is_interface = \true;
                return $type;
            case 'enum-string':
                $type = new TClassString();
                $type->is_enum = \true;
                return $type;
            case 'trait-string':
                return new TTraitString();
            case 'callable-string':
                return new TCallableString();
            case 'numeric-string':
                return new TNumericString();
            case 'literal-string':
                return new TNonspecificLiteralString();
            case 'non-empty-literal-string':
                return new TNonEmptyNonspecificLiteralString();
            case 'literal-int':
                return new TNonspecificLiteralInt();
            case '$this':
                return new TNamedObject('static');
            case 'non-empty-scalar':
                return new TNonEmptyScalar();
            case 'empty-scalar':
                return new TEmptyScalar();
            case 'non-empty-mixed':
                return new TNonEmptyMixed();
            case 'Closure':
                return new TClosure('Closure');
        }
        if (strpos($value, '-') && strpos($value, 'OCI-') !== 0) {
            throw new TypeParseTreeException('Unrecognized type ' . $value);
        }
        if (is_numeric($value[0])) {
            throw new TypeParseTreeException('First character of type cannot be numeric');
        }
        if (isset($template_type_map[$value])) {
            $first_class = array_keys($template_type_map[$value])[0];
            return new TTemplateParam($value, $template_type_map[$value][$first_class], $first_class);
        }
        if (isset($type_aliases[$value])) {
            $type_alias = $type_aliases[$value];
            if ($type_alias instanceof LinkableTypeAlias) {
                return new TTypeAlias($type_alias->declaring_fq_classlike_name, $type_alias->alias_name);
            }
            throw new TypeParseTreeException('Invalid type alias ' . $value . ' provided');
        }
        return new TNamedObject($value);
    }
    /**
     * This is the string that will be used to represent the type in Union::$types. This means that two types sharing
     * the same getKey value will override themselves in an Union
     */
    public abstract function getKey(bool $include_extra = \true) : string;
    public function isNumericType() : bool
    {
        return $this instanceof TInt || $this instanceof TFloat || $this instanceof TNumericString || $this instanceof TNumeric || $this instanceof TLiteralString && is_numeric($this->value);
    }
    public function isObjectType() : bool
    {
        return $this instanceof TObject || $this instanceof TNamedObject || $this instanceof TTemplateParam && $this->as->hasObjectType();
    }
    public function isNamedObjectType() : bool
    {
        return $this instanceof TNamedObject || $this instanceof TTemplateParam && ($this->as->hasNamedObjectType() || array_filter($this->extra_types, static fn($extra_type): bool => $extra_type->isNamedObjectType()));
    }
    public function isCallableType() : bool
    {
        return $this instanceof TCallable || $this instanceof TCallableObject || $this instanceof TCallableString || $this instanceof TCallableArray || $this instanceof TCallableList || $this instanceof TCallableKeyedArray || $this instanceof TClosure;
    }
    public function isIterable(Codebase $codebase) : bool
    {
        return $this instanceof TIterable || $this->hasTraversableInterface($codebase) || $this instanceof TArray || $this instanceof TList || $this instanceof TKeyedArray;
    }
    /**
     * @throws InvalidArgumentException if $this is not an iterable type.
     */
    public function getIterable(Codebase $codebase) : TIterable
    {
        if ($this instanceof TIterable) {
            return $this;
        }
        if ($this instanceof TArray) {
            return new TIterable($this->type_params);
        }
        if ($this instanceof TKeyedArray) {
            return new TIterable([$this->getGenericKeyType(), $this->getGenericValueType()]);
        }
        if ($this->hasTraversableInterface($codebase)) {
            if (strtolower($this->value) === "traversable") {
                if ($this instanceof TGenericObject) {
                    if (count($this->type_params) > 2) {
                        throw new InvalidArgumentException('Too many templates!');
                    }
                    return new TIterable($this->type_params);
                }
                return new TIterable([Type::getMixed(), Type::getMixed()]);
            }
            $implemented_traversable_templates = TemplateStandinTypeReplacer::getMappedGenericTypeParams($codebase, $this, new TGenericObject("Traversable", [Type::getMixed(), Type::getMixed()]));
            if (count($implemented_traversable_templates) > 2) {
                throw new InvalidArgumentException('Too many templates!');
            }
            return new TIterable($implemented_traversable_templates);
        }
        throw new InvalidArgumentException("{$this->getId()} is not an iterable");
    }
    public function isCountable(Codebase $codebase) : bool
    {
        return $this->hasCountableInterface($codebase) || $this instanceof TArray || $this instanceof TKeyedArray || $this instanceof TList;
    }
    /**
     * @psalm-assert-if-true TNamedObject $this
     */
    public function hasTraversableInterface(Codebase $codebase) : bool
    {
        return $this instanceof TNamedObject && (strtolower($this->value) === 'traversable' || $codebase->classOrInterfaceExists($this->value) && ($codebase->classExtendsOrImplements($this->value, 'Traversable') || $codebase->interfaceExtends($this->value, 'Traversable')) || $this->extra_types && array_filter($this->extra_types, static fn(\Psalm\Type\Atomic $a): bool => $a->hasTraversableInterface($codebase)));
    }
    public function hasCountableInterface(Codebase $codebase) : bool
    {
        return $this instanceof TNamedObject && (strtolower($this->value) === 'countable' || $codebase->classOrInterfaceExists($this->value) && ($codebase->classExtendsOrImplements($this->value, 'Countable') || $codebase->interfaceExtends($this->value, 'Countable')) || $this->extra_types && array_filter($this->extra_types, static fn(\Psalm\Type\Atomic $a): bool => $a->hasCountableInterface($codebase)));
    }
    public function isArrayAccessibleWithStringKey(Codebase $codebase) : bool
    {
        return $this instanceof TArray || $this instanceof TKeyedArray || $this instanceof TClassStringMap || $this->hasArrayAccessInterface($codebase) || $this instanceof TNamedObject && $this->value === 'SimpleXMLElement';
    }
    public function isArrayAccessibleWithIntOrStringKey(Codebase $codebase) : bool
    {
        return $this instanceof TString || $this->isArrayAccessibleWithStringKey($codebase);
    }
    public function hasArrayAccessInterface(Codebase $codebase) : bool
    {
        return $this instanceof TNamedObject && (strtolower($this->value) === 'arrayaccess' || $codebase->classOrInterfaceExists($this->value) && ($codebase->classExtendsOrImplements($this->value, 'ArrayAccess') || $codebase->interfaceExtends($this->value, 'ArrayAccess')) || $this->extra_types && array_filter($this->extra_types, static fn(\Psalm\Type\Atomic $a): bool => $a->hasArrayAccessInterface($codebase)));
    }
    public function visit(\Psalm\Type\TypeVisitor $visitor) : bool
    {
        foreach ($this->getChildNodeKeys() as $key) {
            /** @psalm-suppress MixedAssignment */
            $value = $this->{$key};
            if (is_array($value)) {
                /** @psalm-suppress MixedAssignment */
                foreach ($value as $type) {
                    if (!$type instanceof \Psalm\Type\TypeNode) {
                        continue;
                    }
                    if ($visitor->traverse($type) === \false) {
                        return \false;
                    }
                }
            } elseif ($value instanceof \Psalm\Type\TypeNode) {
                if ($visitor->traverse($value) === \false) {
                    return \false;
                }
            }
        }
        return \true;
    }
    /**
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingAnyTypeHint
     */
    public static function visitMutable(\Psalm\Type\MutableTypeVisitor $visitor, &$node, bool $cloned) : bool
    {
        foreach ($node->getChildNodeKeys() as $key) {
            /** @psalm-suppress MixedAssignment */
            $value = $node->{$key};
            $result = \true;
            if (is_array($value)) {
                $changed = \false;
                /** @psalm-suppress MixedAssignment */
                foreach ($value as &$type) {
                    if (!$type instanceof \Psalm\Type\TypeNode) {
                        continue;
                    }
                    $type_orig = $type;
                    $result = $visitor->traverse($type);
                    $changed = $changed || $type !== $type_orig;
                }
                unset($type);
            } elseif ($value instanceof \Psalm\Type\TypeNode) {
                $value_orig = $value;
                $result = $visitor->traverse($value);
                $changed = $value !== $value_orig;
            } else {
                continue;
            }
            if ($changed) {
                if (!$cloned) {
                    $node = clone $node;
                    $cloned = \true;
                }
                if ($key === 'extra_types') {
                    /** @var array<Atomic> $value */
                    $new = [];
                    foreach ($value as $type) {
                        $new[$type->getKey()] = $type;
                    }
                    $value = $new;
                }
                $node->{$key} = $value;
            }
            if ($result === \false) {
                return \false;
            }
        }
        return \true;
    }
    /** @return list<string> */
    protected function getChildNodeKeys() : array
    {
        return [];
    }
    public final function __toString() : string
    {
        return $this->getId();
    }
    /**
     * This is the true identifier for the type. It defaults to self::getKey() but can be overrided to be more precise
     */
    public function getId(bool $exact = \true, bool $nested = \false) : string
    {
        return $this->getKey();
    }
    /**
     * This string is used in order to transform a type into an string assertion for the assertion module
     * Default to self::getId()
     */
    public function getAssertionString() : string
    {
        return $this->getId();
    }
    /**
     * Returns the detailed description of the type, either in phpdoc standard format or Psalm format depending on flag
     * Default to self::getKey()
     *
     * @param array<lowercase-string, string> $aliased_classes
     */
    public function toNamespacedString(?string $namespace, array $aliased_classes, ?string $this_class, bool $use_phpdoc_format) : string
    {
        return $this->getKey();
    }
    /**
     * Returns a string representation of the type compatible with php signature or null if the type can't be expressed
     *  with the given php version
     *
     * @param  array<lowercase-string, string> $aliased_classes
     */
    public abstract function toPhpString(?string $namespace, array $aliased_classes, ?string $this_class, int $analysis_php_version_id) : ?string;
    public abstract function canBeFullyExpressedInPhp(int $analysis_php_version_id) : bool;
    /**
     * @return static
     */
    public function replaceTemplateTypesWithStandins(TemplateResult $template_result, Codebase $codebase, ?StatementsAnalyzer $statements_analyzer = null, \Psalm\Type\Atomic $input_type = null, ?int $input_arg_offset = null, ?string $calling_class = null, ?string $calling_function = null, bool $replace = \true, bool $add_lower_bound = \false, int $depth = 0) : self
    {
        // do nothing
        return $this;
    }
    /**
     * @return static
     */
    public function replaceTemplateTypesWithArgTypes(TemplateResult $template_result, ?Codebase $codebase) : self
    {
        // do nothing
        return $this;
    }
    public function equals(\Psalm\Type\Atomic $other_type, bool $ensure_source_equality) : bool
    {
        return get_class($other_type) === get_class($this);
    }
    public function isTruthy() : bool
    {
        if ($this instanceof TTrue) {
            return \true;
        }
        if ($this instanceof TLiteralInt && $this->value !== 0) {
            return \true;
        }
        if ($this instanceof TLiteralFloat && $this->value !== 0.0) {
            return \true;
        }
        if ($this instanceof TLiteralString && ($this->value !== '' && $this->value !== '0')) {
            return \true;
        }
        if ($this instanceof TNonFalsyString) {
            return \true;
        }
        if ($this instanceof TNonEmptyArray) {
            return \true;
        }
        if ($this instanceof TNonEmptyScalar) {
            return \true;
        }
        if ($this instanceof TNonEmptyMixed) {
            return \true;
        }
        if ($this instanceof TObject) {
            return \true;
        }
        if ($this instanceof TNamedObject && $this->value !== 'SimpleXMLElement' && $this->value !== 'SimpleXMLIterator') {
            return \true;
        }
        if ($this instanceof TIntRange && !$this->contains(0)) {
            return \true;
        }
        if ($this instanceof TLiteralClassString) {
            return \true;
        }
        if ($this instanceof TClassString) {
            return \true;
        }
        if ($this instanceof TDependentGetClass) {
            return \true;
        }
        if ($this instanceof TTraitString) {
            return \true;
        }
        if ($this instanceof TResource) {
            return \true;
        }
        if ($this instanceof TKeyedArray) {
            return $this->isNonEmpty();
        }
        if ($this instanceof TTemplateParam && $this->as->isAlwaysTruthy()) {
            return \true;
        }
        //we can't be sure the type is always truthy
        return \false;
    }
    public function isFalsy() : bool
    {
        if ($this instanceof TFalse) {
            return \true;
        }
        if ($this instanceof TLiteralInt && $this->value === 0) {
            return \true;
        }
        if ($this instanceof TLiteralFloat && $this->value === 0.0) {
            return \true;
        }
        if ($this instanceof TLiteralString && ($this->value === '' || $this->value === '0')) {
            return \true;
        }
        if ($this instanceof TNull) {
            return \true;
        }
        if ($this instanceof TEmptyMixed) {
            return \true;
        }
        if ($this instanceof TEmptyNumeric) {
            return \true;
        }
        if ($this instanceof TEmptyScalar) {
            return \true;
        }
        if ($this instanceof TTemplateParam && $this->as->isAlwaysFalsy()) {
            return \true;
        }
        if ($this instanceof TIntRange && $this->min_bound === 0 && $this->max_bound === 0) {
            return \true;
        }
        if ($this instanceof TArray && $this->isEmptyArray()) {
            return \true;
        }
        //we can't be sure the type is always falsy
        return \false;
    }
}
<?php

namespace Psalm\Type;

abstract class MutableTypeVisitor
{
    public const STOP_TRAVERSAL = 1;
    public const DONT_TRAVERSE_CHILDREN = 2;
    /**
     * @template T as TypeNode
     * @param T $type
     * @param-out T $type
     * @return self::STOP_TRAVERSAL|self::DONT_TRAVERSE_CHILDREN|null
     */
    protected abstract function enterNode(\Psalm\Type\TypeNode &$type) : ?int;
    /**
     * @template T as TypeNode
     * @param T $node
     * @param-out T $node
     * @psalm-suppress ReferenceConstraintViolation
     */
    public function traverse(\Psalm\Type\TypeNode &$node) : bool
    {
        $nodeOrig = $node;
        $result = $this->enterNode($node);
        if ($result === self::DONT_TRAVERSE_CHILDREN) {
            return \true;
        }
        if ($result === self::STOP_TRAVERSAL) {
            return \false;
        }
        return $node::visitMutable($this, $node, $node !== $nodeOrig);
    }
    /**
     * @template T as array<TypeNode>
     * @param T $nodes
     * @param-out T $nodes
     */
    public function traverseArray(array &$nodes) : void
    {
        foreach ($nodes as &$node) {
            if ($this->traverse($node) === \false) {
                return;
            }
        }
        unset($node);
    }
}
<?php

namespace Psalm\Type;

use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Internal\TypeVisitor\FromDocblockSetter;
use Psalm\Storage\ImmutableNonCloneableTrait;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use function get_object_vars;
/**
 * @psalm-immutable
 * @psalm-type TProperties=array{
 *      from_docblock?: bool,
 *      from_calculation?: bool,
 *      from_property?: bool,
 *      from_static_property?: bool,
 *      initialized?: bool,
 *      initialized_class?: ?string,
 *      checked?: bool,
 *      failed_reconciliation?: bool,
 *      ignore_nullable_issues?: bool,
 *      ignore_falsable_issues?: bool,
 *      ignore_isset?: bool,
 *      possibly_undefined?: bool,
 *      possibly_undefined_from_try?: bool,
 *      explicit_never?: bool,
 *      had_template?: bool,
 *      from_template_default?: bool,
 *      by_ref?: bool,
 *      reference_free?: bool,
 *      allow_mutations?: bool,
 *      has_mutations?: bool,
 *      different?: bool,
 *      parent_nodes?: array<string, DataFlowNode>
 * }
 */
final class Union implements \Psalm\Type\TypeNode
{
    use ImmutableNonCloneableTrait;
    use \Psalm\Type\UnionTrait;
    /**
     * @psalm-readonly
     * @var non-empty-array<string, Atomic>
     */
    private array $types;
    /**
     * Whether the type originated in a docblock
     *
     * @var bool
     */
    public $from_docblock = \false;
    /**
     * Whether the type originated from integer calculation
     *
     * @var bool
     */
    public $from_calculation = \false;
    /**
     * Whether the type originated from a property
     *
     * This helps turn isset($foo->bar) into a different sort of issue
     *
     * @var bool
     */
    public $from_property = \false;
    /**
     * Whether the type originated from *static* property
     *
     * Unlike non-static properties, static properties have no prescribed place
     * like __construct() to be initialized in
     *
     * @var bool
     */
    public $from_static_property = \false;
    /**
     * Whether the property that this type has been derived from has been initialized in a constructor
     *
     * @var bool
     */
    public $initialized = \true;
    /**
     * Which class the type was initialised in
     *
     * @var ?string
     */
    public $initialized_class;
    /**
     * Whether or not the type has been checked yet
     *
     * @var bool
     */
    public $checked = \false;
    /**
     * @var bool
     */
    public $failed_reconciliation = \false;
    /**
     * Whether or not to ignore issues with possibly-null values
     *
     * @var bool
     */
    public $ignore_nullable_issues = \false;
    /**
     * Whether or not to ignore issues with possibly-false values
     *
     * @var bool
     */
    public $ignore_falsable_issues = \false;
    /**
     * Whether or not to ignore issues with isset on this type
     *
     * @var bool
     */
    public $ignore_isset = \false;
    /**
     * Whether or not this variable is possibly undefined
     *
     * @var bool
     */
    public $possibly_undefined = \false;
    /**
     * Whether or not this variable is possibly undefined
     *
     * @var bool
     */
    public $possibly_undefined_from_try = \false;
    /**
     * whether this type had never set explicitly
     * since it's the bottom type, it's combined into everything else and lost
     *
     * @var bool
     */
    public $explicit_never = \false;
    /**
     * Whether or not this union had a template, since replaced
     *
     * @var bool
     */
    public $had_template = \false;
    /**
     * Whether or not this union comes from a template "as" default
     *
     * @var bool
     */
    public $from_template_default = \false;
    /**
     * @var array<string, TLiteralString>
     */
    private array $literal_string_types = [];
    /**
     * @var array<string, TClassString>
     */
    private array $typed_class_strings = [];
    /**
     * @var array<string, TLiteralInt>
     */
    private array $literal_int_types = [];
    /**
     * @var array<string, TLiteralFloat>
     */
    private array $literal_float_types = [];
    /**
     * True if the type was passed or returned by reference, or if the type refers to an object's
     * property or an item in an array. Note that this is not true for locally created references
     * that don't refer to properties or array items (see Context::$references_in_scope).
     *
     * @var bool
     */
    public $by_ref = \false;
    /**
     * @var bool
     */
    public $reference_free = \false;
    /**
     * @var bool
     */
    public $allow_mutations = \true;
    /**
     * @var bool
     */
    public $has_mutations = \true;
    /**
     * This is a cache of getId on non-exact mode
     */
    private ?string $id = null;
    /**
     * This is a cache of getId on exact mode
     */
    private ?string $exact_id;
    /**
     * @var array<string, DataFlowNode>
     */
    public $parent_nodes = [];
    public bool $propagate_parent_nodes = \false;
    /**
     * @var bool
     */
    public $different = \false;
    /**
     * @param TProperties $properties
     * @return static
     */
    public function setProperties(array $properties) : self
    {
        $obj = null;
        foreach ($properties as $key => $value) {
            if ($this->{$key} !== $value) {
                if ($obj === null) {
                    $obj = clone $this;
                }
                /** @psalm-suppress ImpurePropertyAssignment We just cloned this object */
                $obj->{$key} = $value;
            }
        }
        return $obj ?? $this;
    }
    /**
     * @return static
     */
    public function setDifferent(bool $different) : self
    {
        if ($different === $this->different) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->different = $different;
        return $cloned;
    }
    /**
     * @param array<string, DataFlowNode> $parent_nodes
     * @return static
     */
    public function setParentNodes(array $parent_nodes, bool $propagate_changes = \false) : self
    {
        if ($parent_nodes === $this->parent_nodes) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->parent_nodes = $parent_nodes;
        $cloned->propagate_parent_nodes = $propagate_changes;
        return $cloned;
    }
    /**
     * @param array<string, DataFlowNode> $parent_nodes
     * @return static
     */
    public function addParentNodes(array $parent_nodes) : self
    {
        if (!$parent_nodes) {
            return $this;
        }
        $parent_nodes = $this->parent_nodes + $parent_nodes;
        if ($parent_nodes === $this->parent_nodes) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->parent_nodes = $parent_nodes;
        return $cloned;
    }
    /** @return static */
    public function setPossiblyUndefined(bool $possibly_undefined, ?bool $from_try = null) : self
    {
        $from_try ??= $this->possibly_undefined_from_try;
        if ($this->possibly_undefined === $possibly_undefined && $this->possibly_undefined_from_try == $from_try) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->possibly_undefined = $possibly_undefined;
        $cloned->possibly_undefined_from_try = $from_try;
        return $cloned;
    }
    /** @return static */
    public function setByRef(bool $by_ref)
    {
        if ($by_ref === $this->by_ref) {
            return $this;
        }
        $cloned = clone $this;
        $cloned->by_ref = $by_ref;
        return $cloned;
    }
    /**
     * @psalm-mutation-free
     * @param non-empty-array<Atomic>  $types
     */
    public function setTypes(array $types) : self
    {
        if ($types === $this->types) {
            return $this;
        }
        return $this->getBuilder()->setTypes($types)->freeze();
    }
    /**
     * @psalm-mutation-free
     */
    public function getBuilder() : \Psalm\Type\MutableUnion
    {
        /** @psalm-suppress InvalidArgument It's actually filtered internally */
        return new \Psalm\Type\MutableUnion($this->getAtomicTypes(), get_object_vars($this));
    }
    /**
     * @psalm-mutation-free
     */
    public function setFromDocblock(bool $fromDocblock = \true) : self
    {
        $cloned = clone $this;
        /** @psalm-suppress ImpureMethodCall Acting on clone */
        (new FromDocblockSetter($fromDocblock))->traverse($cloned);
        return $cloned;
    }
    /**
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingAnyTypeHint
     */
    public static function visitMutable(\Psalm\Type\MutableTypeVisitor $visitor, &$node, bool $cloned) : bool
    {
        $result = \true;
        $changed = \false;
        $types = $node->types;
        foreach ($types as &$type) {
            $type_orig = $type;
            $result = $visitor->traverse($type);
            $changed = $changed || $type_orig !== $type;
            if (!$result) {
                break;
            }
        }
        unset($type);
        if ($changed) {
            $node = $node->setTypes($types);
        }
        return $result;
    }
}
<?php

namespace Psalm;

use Composer\Autoload\ClassLoader;
use _HumbugBox1cb33d1f20f1\Composer\Semver\Constraint\Constraint;
use _HumbugBox1cb33d1f20f1\Composer\Semver\VersionParser;
use DOMAttr;
use DOMDocument;
use DOMElement;
use InvalidArgumentException;
use JsonException;
use LogicException;
use OutOfBoundsException;
use Psalm\CodeLocation\Raw;
use Psalm\Config\IssueHandler;
use Psalm\Config\ProjectFileFilter;
use Psalm\Config\TaintAnalysisFileFilter;
use Psalm\Exception\ConfigException;
use Psalm\Exception\ConfigNotFoundException;
use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Analyzer\FileAnalyzer;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Composer;
use Psalm\Internal\EventDispatcher;
use Psalm\Internal\IncludeCollector;
use Psalm\Internal\Provider\AddRemoveTaints\HtmlFunctionTainter;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Issue\ArgumentIssue;
use Psalm\Issue\ClassConstantIssue;
use Psalm\Issue\ClassIssue;
use Psalm\Issue\CodeIssue;
use Psalm\Issue\ConfigIssue;
use Psalm\Issue\FunctionIssue;
use Psalm\Issue\MethodIssue;
use Psalm\Issue\PropertyIssue;
use Psalm\Issue\VariableIssue;
use Psalm\Plugin\PluginEntryPointInterface;
use Psalm\Plugin\PluginFileExtensionsInterface;
use Psalm\Plugin\PluginInterface;
use Psalm\Progress\Progress;
use Psalm\Progress\VoidProgress;
use RuntimeException;
use SimpleXMLElement;
use SimpleXMLIterator;
use _HumbugBox1cb33d1f20f1\Symfony\Component\Filesystem\Path;
use Throwable;
use UnexpectedValueException;
use _HumbugBox1cb33d1f20f1\XdgBaseDir\Xdg;
use stdClass;
use function array_key_exists;
use function array_merge;
use function array_pad;
use function array_pop;
use function array_shift;
use function assert;
use function basename;
use function chdir;
use function class_exists;
use function clearstatcache;
use function count;
use function dirname;
use function explode;
use function extension_loaded;
use function fclose;
use function file_exists;
use function file_get_contents;
use function filetype;
use function flock;
use function fopen;
use function get_class;
use function get_defined_constants;
use function get_defined_functions;
use function getcwd;
use function glob;
use function implode;
use function in_array;
use function is_a;
use function is_array;
use function is_dir;
use function is_file;
use function is_resource;
use function is_string;
use function json_decode;
use function libxml_clear_errors;
use function libxml_get_errors;
use function libxml_use_internal_errors;
use function mkdir;
use function phpversion;
use function preg_match;
use function preg_quote;
use function preg_replace;
use function realpath;
use function reset;
use function rmdir;
use function rtrim;
use function scandir;
use function sha1;
use function simplexml_import_dom;
use function str_replace;
use function strlen;
use function strpos;
use function strrpos;
use function strtolower;
use function substr;
use function substr_count;
use function sys_get_temp_dir;
use function unlink;
use function usleep;
use function version_compare;
use const DIRECTORY_SEPARATOR;
use const GLOB_NOSORT;
use const JSON_THROW_ON_ERROR;
use const LIBXML_ERR_ERROR;
use const LIBXML_ERR_FATAL;
use const LIBXML_NONET;
use const LIBXML_NOWARNING;
use const LOCK_EX;
use const PHP_EOL;
use const PHP_VERSION_ID;
use const PSALM_VERSION;
use const SCANDIR_SORT_NONE;
/**
 * @psalm-suppress PropertyNotSetInConstructor
 * @psalm-consistent-constructor
 */
class Config
{
    private const DEFAULT_FILE_NAME = 'psalm.xml';
    public const CONFIG_NAMESPACE = 'https://getpsalm.org/schema/config';
    public const REPORT_INFO = 'info';
    public const REPORT_ERROR = 'error';
    public const REPORT_SUPPRESS = 'suppress';
    /**
     * @var array<string>
     */
    public static $ERROR_LEVELS = [self::REPORT_INFO, self::REPORT_ERROR, self::REPORT_SUPPRESS];
    /**
     * @var array
     */
    private const MIXED_ISSUES = ['MixedArgument', 'MixedArrayAccess', 'MixedArrayAssignment', 'MixedArrayOffset', 'MixedArrayTypeCoercion', 'MixedAssignment', 'MixedFunctionCall', 'MixedInferredReturnType', 'MixedMethodCall', 'MixedOperand', 'MixedPropertyFetch', 'MixedPropertyAssignment', 'MixedReturnStatement', 'MixedStringOffsetAssignment', 'MixedArgumentTypeCoercion', 'MixedPropertyTypeCoercion', 'MixedReturnTypeCoercion'];
    /**
     * These are special object classes that allow any and all properties to be get/set on them
     *
     * @var array<int, lowercase-string>
     */
    protected $universal_object_crates;
    /**
     * @var static|null
     */
    private static $instance;
    /**
     * Whether or not to use types as defined in docblocks
     *
     * @var bool
     */
    public $use_docblock_types = \true;
    /**
     * Whether or not to use types as defined in property docblocks.
     * This is distinct from the above because you may want to use
     * property docblocks, but not function docblocks.
     *
     * @var bool
     */
    public $use_docblock_property_types = \false;
    /**
     * Whether or not to throw an exception on first error
     *
     * @var bool
     */
    public $throw_exception = \false;
    /**
     * The directory to store PHP Parser (and other) caches
     *
     * @internal
     * @var string|null
     */
    public $cache_directory;
    private bool $cache_directory_initialized = \false;
    /**
     * The directory to store all Psalm project caches
     *
     * @var string|null
     */
    public $global_cache_directory;
    /**
     * Path to the autoader
     *
     * @var string|null
     */
    public $autoloader;
    /**
     * @var ProjectFileFilter|null
     */
    protected $project_files;
    /**
     * @var ProjectFileFilter|null
     */
    protected $extra_files;
    /**
     * The base directory of this config file
     *
     * @var string
     */
    public $base_dir;
    /**
     * The PHP version to assume as declared in the config file
     */
    private ?string $configured_php_version = null;
    /**
     * @var array<int, string>
     */
    private array $file_extensions = ['php'];
    /**
     * @var array<string, class-string<FileScanner>>
     */
    private array $filetype_scanners = [];
    /**
     * @var array<string, class-string<FileAnalyzer>>
     */
    private array $filetype_analyzers = [];
    /**
     * @var array<string, string>
     */
    private array $filetype_scanner_paths = [];
    /**
     * @var array<string, string>
     */
    private array $filetype_analyzer_paths = [];
    /**
     * @var array<string, IssueHandler>
     */
    private array $issue_handlers = [];
    /**
     * @var array<int, string>
     */
    private array $mock_classes = [];
    /**
     * @var array<string, string>
     */
    private array $preloaded_stub_files = [];
    /**
     * @var array<string, string>
     */
    private array $stub_files = [];
    /**
     * @var bool
     */
    public $hide_external_errors = \false;
    /**
     * @var bool
     */
    public $hide_all_errors_except_passed_files = \false;
    /** @var bool */
    public $allow_includes = \true;
    /** @var 1|2|3|4|5|6|7|8 */
    public $level = 1;
    /**
     * @var ?bool
     */
    public $show_mixed_issues;
    /** @var bool */
    public $strict_binary_operands = \false;
    /**
     * @var bool
     */
    public $remember_property_assignments_after_call = \true;
    /** @var bool */
    public $use_igbinary = \false;
    /**
     * @var bool
     */
    public $allow_string_standin_for_class = \false;
    /**
     * @var bool
     */
    public $disable_suppress_all = \false;
    /**
     * @var bool
     */
    public $use_phpdoc_method_without_magic_or_parent = \false;
    /**
     * @var bool
     */
    public $use_phpdoc_property_without_magic_or_parent = \false;
    /**
     * @var bool
     */
    public $skip_checks_on_unresolvable_includes = \false;
    /**
     * @var bool
     */
    public $seal_all_methods = \false;
    /**
     * @var bool
     */
    public $seal_all_properties = \false;
    /**
     * @var bool
     */
    public $memoize_method_calls = \false;
    /**
     * @var bool
     */
    public $hoist_constants = \false;
    /**
     * @var bool
     */
    public $add_param_default_to_docblock_type = \false;
    /**
     * @var bool
     */
    public $disable_var_parsing = \false;
    /**
     * @var bool
     */
    public $check_for_throws_docblock = \false;
    /**
     * @var bool
     */
    public $check_for_throws_in_global_scope = \false;
    /**
     * @var bool
     */
    public $ignore_internal_falsable_issues = \true;
    /**
     * @var bool
     */
    public $ignore_internal_nullable_issues = \true;
    /**
     * @var array<string, bool>
     */
    public $ignored_exceptions = [];
    /**
     * @var array<string, bool>
     */
    public $ignored_exceptions_in_global_scope = [];
    /**
     * @var array<string, bool>
     */
    public $ignored_exceptions_and_descendants = [];
    /**
     * @var array<string, bool>
     */
    public $ignored_exceptions_and_descendants_in_global_scope = [];
    /**
     * @var bool
     */
    public $infer_property_types_from_constructor = \true;
    /**
     * @var bool
     */
    public $ensure_array_string_offsets_exist = \false;
    /**
     * @var bool
     */
    public $ensure_array_int_offsets_exist = \false;
    /**
     * @var array<lowercase-string, bool>
     */
    public $forbidden_functions = [];
    /**
     * TODO: Psalm 6: Update default to be true and remove warning.
     *
     * @var bool
     */
    public $find_unused_code = \false;
    /**
     * @var bool
     */
    public $find_unused_variables = \false;
    /**
     * @var bool
     */
    public $find_unused_psalm_suppress = \false;
    /**
     * TODO: Psalm 6: Update default to be true and remove warning.
     */
    public bool $find_unused_baseline_entry = \false;
    /**
     * @var bool
     */
    public $run_taint_analysis = \false;
    /** @var bool */
    public $use_phpstorm_meta_path = \true;
    /**
     * @var bool
     */
    public $resolve_from_config_file = \true;
    /**
     * @var bool
     */
    public $restrict_return_types = \false;
    /**
     * @var bool
     */
    public $limit_method_complexity = \false;
    /**
     * @var int
     */
    public $max_graph_size = 200;
    /**
     * @var int
     */
    public $max_avg_path_length = 70;
    /**
     * @var int
     */
    public $max_shaped_array_size = 100;
    /**
     * @var string[]
     */
    public $plugin_paths = [];
    /**
     * @var array<array{class:string,config:?SimpleXMLElement}>
     */
    private array $plugin_classes = [];
    /**
     * @var bool
     */
    public $allow_internal_named_arg_calls = \true;
    /**
     * @var bool
     */
    public $allow_named_arg_calls = \true;
    /** @var array<string, mixed> */
    private array $predefined_constants = [];
    /** @var array<callable-string, bool> */
    private array $predefined_functions = [];
    private ?ClassLoader $composer_class_loader = null;
    /**
     * @var string
     */
    public $hash = '';
    /** @var string|null */
    public $error_baseline;
    /**
     * @var bool
     */
    public $include_php_versions_in_error_baseline = \false;
    /**
     * @var string
     * @deprecated Please use {@see self::$shepherd_endpoint} instead. Property will be removed in Psalm 6.
     */
    public $shepherd_host = 'shepherd.dev';
    /**
     * @var string
     * @internal
     */
    public $shepherd_endpoint = 'https://shepherd.dev/hooks/psalm/';
    /**
     * @var array<string, string>
     */
    public $globals = [];
    /**
     * @var int
     */
    public $max_string_length = 1000;
    private ?IncludeCollector $include_collector = null;
    /**
     * @var TaintAnalysisFileFilter|null
     */
    protected $taint_analysis_ignored_files;
    /**
     * @var bool whether to emit a backtrace of emitted issues to stderr
     */
    public $debug_emitted_issues = \false;
    private bool $report_info = \true;
    /**
     * @var EventDispatcher
     */
    public $eventDispatcher;
    /** @var list<ConfigIssue> */
    public $config_issues = [];
    /**
     * @var 'default'|'never'|'always'
     */
    public $trigger_error_exits = 'default';
    /**
     * @var string[]
     */
    public $internal_stubs = [];
    /** @var ?int */
    public $threads;
    /**
     * A list of php extensions supported by Psalm.
     * Where key - extension name (without ext- prefix), value - whether to load extension’s stub.
     *
     * @psalm-readonly-allow-private-mutation
     * @var array<string, bool>
     */
    public $php_extensions = ["apcu" => \false, "decimal" => \false, "dom" => \false, "ds" => \false, "ffi" => \false, "geos" => \false, "gmp" => \false, "mongodb" => \false, "mysqli" => \false, "pdo" => \false, "random" => \false, "redis" => \false, "simplexml" => \false, "soap" => \false, "xdebug" => \false];
    /**
     * A list of php extensions described in CallMap Psalm files
     * as opposite to stub files loaded by condition (see stubs/extensions dir).
     *
     * @see https://www.php.net/manual/en/extensions.membership.php
     * @var list<non-empty-string>
     * @readonly
     */
    public $php_extensions_supported_by_psalm_callmaps = ['apache', 'bcmath', 'bzip2', 'calendar', 'ctype', 'curl', 'dom', 'enchant', 'exif', 'filter', 'gd', 'gettext', 'gmp', 'hash', 'iconv', 'imap', 'intl', 'json', 'ldap', 'libxml', 'mbstring', 'mysqli', 'mysqlnd', 'mhash', 'oci8', 'opcache', 'openssl', 'pcntl', 'PDO', 'pdo_mysql', 'pdo-sqlite', 'pdo-pgsql', 'pgsql', 'pspell', 'phar', 'phpdbg', 'posix', 'redis', 'readline', 'session', 'sockets', 'sqlite3', 'snmp', 'soap', 'sodium', 'shmop', 'sysvsem', 'tidy', 'tokenizer', 'uodbc', 'xml', 'xmlreader', 'xmlwriter', 'xsl', 'zip', 'zlib'];
    /**
     * A list of php extensions required by the project that aren't fully supported by Psalm.
     *
     * @var array<string, true>
     */
    public $php_extensions_not_supported = [];
    /**
     * @var array<class-string, PluginInterface>
     */
    private array $plugins = [];
    /** @var list<string> */
    public array $config_warnings = [];
    /** @internal */
    protected function __construct()
    {
        self::$instance = $this;
        $this->eventDispatcher = new EventDispatcher();
        $this->universal_object_crates = [strtolower(stdClass::class), strtolower(SimpleXMLElement::class), strtolower(SimpleXMLIterator::class)];
    }
    /**
     * Gets a Config object from an XML file.
     *
     * Searches up a folder hierarchy for the most immediate config.
     *
     * @throws ConfigException if a config path is not found
     */
    public static function getConfigForPath(string $path, string $current_dir) : \Psalm\Config
    {
        $config_path = self::locateConfigFile($path);
        if (!$config_path) {
            throw new ConfigNotFoundException('Config not found for path ' . $path);
        }
        return self::loadFromXMLFile($config_path, $current_dir);
    }
    /**
     * Searches up a folder hierarchy for the most immediate config.
     *
     * @throws ConfigException
     */
    public static function locateConfigFile(string $path) : ?string
    {
        $dir_path = realpath($path);
        if ($dir_path === \false) {
            throw new ConfigNotFoundException('Config not found for path ' . $path);
        }
        if (!is_dir($dir_path)) {
            $dir_path = dirname($dir_path);
        }
        do {
            $maybe_path = $dir_path . DIRECTORY_SEPARATOR . self::DEFAULT_FILE_NAME;
            if (file_exists($maybe_path) || file_exists($maybe_path .= '.dist')) {
                return $maybe_path;
            }
            $dir_path = dirname($dir_path);
        } while (dirname($dir_path) !== $dir_path);
        return null;
    }
    /**
     * Creates a new config object from the file
     */
    public static function loadFromXMLFile(string $file_path, string $current_dir) : \Psalm\Config
    {
        $file_contents = file_get_contents($file_path);
        $base_dir = dirname($file_path) . DIRECTORY_SEPARATOR;
        if ($file_contents === \false) {
            throw new InvalidArgumentException('Cannot open ' . $file_path);
        }
        if ($file_contents === '') {
            throw new InvalidArgumentException('Invalid empty file ' . $file_path);
        }
        try {
            $config = self::loadFromXML($base_dir, $file_contents, $current_dir, $file_path);
            $config->hash = sha1($file_contents . PSALM_VERSION);
        } catch (ConfigException $e) {
            throw new ConfigException('Problem parsing ' . $file_path . ":\n" . '  ' . $e->getMessage());
        }
        return $config;
    }
    /**
     * Computes the hash to use for a cache folder from CLI flags and from the config file's xml contents
     */
    public function computeHash() : string
    {
        return sha1($this->hash . ':' . $this->level);
    }
    /**
     * Creates a new config object from an XML string
     *
     * @param  string|null      $current_dir Current working directory, if different to $base_dir
     * @param  non-empty-string $file_contents
     * @throws ConfigException
     */
    public static function loadFromXML(string $base_dir, string $file_contents, ?string $current_dir = null, ?string $file_path = null) : \Psalm\Config
    {
        if ($current_dir === null) {
            $current_dir = $base_dir;
        }
        self::validateXmlConfig($base_dir, $file_contents);
        return self::fromXmlAndPaths($base_dir, $file_contents, $current_dir, $file_path);
    }
    /**
     * @param non-empty-string $file_contents
     */
    private static function loadDomDocument(string $base_dir, string $file_contents) : DOMDocument
    {
        $dom_document = new DOMDocument();
        // there's no obvious way to set xml:base for a document when loading it from string
        // so instead we're changing the current directory instead to be able to process XIncludes
        $oldpwd = getcwd();
        chdir($base_dir);
        $dom_document->loadXML($file_contents, LIBXML_NONET);
        $dom_document->xinclude(LIBXML_NOWARNING | LIBXML_NONET);
        chdir($oldpwd);
        return $dom_document;
    }
    /**
     * @param non-empty-string $file_contents
     * @throws ConfigException
     */
    private static function validateXmlConfig(string $base_dir, string $file_contents) : void
    {
        $schema_path = dirname(__DIR__, 2) . '/config.xsd';
        if (!file_exists($schema_path)) {
            throw new ConfigException('Cannot locate config schema');
        }
        // Enable user error handling
        $prev_xml_internal_errors = libxml_use_internal_errors(\true);
        libxml_clear_errors();
        $dom_document = self::loadDomDocument($base_dir, $file_contents);
        $psalm_nodes = $dom_document->getElementsByTagName('psalm');
        $psalm_node = $psalm_nodes->item(0);
        if (!$psalm_node) {
            throw new ConfigException('Missing psalm node');
        }
        if (!$psalm_node->hasAttribute('xmlns')) {
            $psalm_node->setAttribute('xmlns', self::CONFIG_NAMESPACE);
            $old_dom_document = $dom_document;
            $old_file_contents = $old_dom_document->saveXML();
            assert($old_file_contents !== \false && $old_file_contents !== '');
            $dom_document = self::loadDomDocument($base_dir, $old_file_contents);
        }
        $dom_document->schemaValidate($schema_path);
        // If it returns false it will generate errors handled below
        $errors = libxml_get_errors();
        libxml_clear_errors();
        libxml_use_internal_errors($prev_xml_internal_errors);
        foreach ($errors as $error) {
            if ($error->level === LIBXML_ERR_FATAL || $error->level === LIBXML_ERR_ERROR) {
                throw new ConfigException('Error on line ' . $error->line . ":\n" . '    ' . $error->message);
            }
        }
    }
    /**
     * @param positive-int $line_number 1-based line number
     * @return int 0-based byte offset
     * @throws OutOfBoundsException
     */
    private static function lineNumberToByteOffset(string $string, int $line_number) : int
    {
        if ($line_number === 1) {
            return 0;
        }
        $offset = 0;
        for ($i = 0; $i < $line_number - 1; $i++) {
            $newline_offset = strpos($string, "\n", $offset);
            if (\false === $newline_offset) {
                throw new OutOfBoundsException('Line ' . $line_number . ' is not found in a string with ' . ($i + 1) . ' lines');
            }
            $offset = $newline_offset + 1;
        }
        if ($offset > strlen($string)) {
            throw new OutOfBoundsException('Line ' . $line_number . ' is not found');
        }
        return $offset;
    }
    private static function processDeprecatedAttribute(DOMAttr $attribute, string $file_contents, self $config, string $config_path) : void
    {
        $line = $attribute->getLineNo();
        assert($line > 0);
        // getLineNo() always returns non-zero for nodes loaded from file
        $offset = self::lineNumberToByteOffset($file_contents, $line);
        $attribute_start = strrpos($file_contents, $attribute->name, $offset - strlen($file_contents)) ?: 0;
        $attribute_end = $attribute_start + strlen($attribute->name) - 1;
        $config->config_issues[] = new ConfigIssue('Attribute "' . $attribute->name . '" is deprecated ' . 'and is going to be removed in the next major version', new Raw($file_contents, $config_path, basename($config_path), $attribute_start, $attribute_end));
    }
    private static function processDeprecatedElement(DOMElement $deprecated_element_xml, string $file_contents, self $config, string $config_path) : void
    {
        $line = $deprecated_element_xml->getLineNo();
        assert($line > 0);
        $offset = self::lineNumberToByteOffset($file_contents, $line);
        $element_start = strpos($file_contents, $deprecated_element_xml->localName, $offset) ?: 0;
        $element_end = $element_start + strlen($deprecated_element_xml->localName) - 1;
        $config->config_issues[] = new ConfigIssue('Element "' . $deprecated_element_xml->localName . '" is deprecated ' . 'and is going to be removed in the next major version', new Raw($file_contents, $config_path, basename($config_path), $element_start, $element_end));
    }
    private static function processConfigDeprecations(self $config, DOMDocument $dom_document, string $file_contents, string $config_path) : void
    {
        $config->config_issues = [];
        // Attributes to be removed in Psalm 6
        $deprecated_attributes = [];
        /** @var list<string> */
        $deprecated_elements = [];
        $psalm_element_item = $dom_document->getElementsByTagName('psalm')->item(0);
        assert($psalm_element_item !== null);
        $attributes = $psalm_element_item->attributes;
        foreach ($attributes as $attribute) {
            if (in_array($attribute->name, $deprecated_attributes, \true)) {
                self::processDeprecatedAttribute($attribute, $file_contents, $config, $config_path);
            }
        }
        foreach ($deprecated_elements as $deprecated_element) {
            $deprecated_elements_xml = $dom_document->getElementsByTagNameNS(self::CONFIG_NAMESPACE, $deprecated_element);
            if ($deprecated_elements_xml->length) {
                $deprecated_element_xml = $deprecated_elements_xml->item(0);
                self::processDeprecatedElement($deprecated_element_xml, $file_contents, $config, $config_path);
            }
        }
    }
    /**
     * @param non-empty-string $file_contents
     * @psalm-suppress MixedMethodCall
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedArgument
     * @psalm-suppress MixedPropertyFetch
     * @throws ConfigException
     */
    private static function fromXmlAndPaths(string $base_dir, string $file_contents, string $current_dir, ?string $config_path) : self
    {
        $config = new static();
        $dom_document = self::loadDomDocument($base_dir, $file_contents);
        if (null !== $config_path) {
            self::processConfigDeprecations($config, $dom_document, $file_contents, $config_path);
        }
        $config_xml = simplexml_import_dom($dom_document);
        $booleanAttributes = ['useDocblockTypes' => 'use_docblock_types', 'useDocblockPropertyTypes' => 'use_docblock_property_types', 'throwExceptionOnError' => 'throw_exception', 'hideExternalErrors' => 'hide_external_errors', 'hideAllErrorsExceptPassedFiles' => 'hide_all_errors_except_passed_files', 'resolveFromConfigFile' => 'resolve_from_config_file', 'allowFileIncludes' => 'allow_includes', 'strictBinaryOperands' => 'strict_binary_operands', 'rememberPropertyAssignmentsAfterCall' => 'remember_property_assignments_after_call', 'disableVarParsing' => 'disable_var_parsing', 'allowStringToStandInForClass' => 'allow_string_standin_for_class', 'disableSuppressAll' => 'disable_suppress_all', 'usePhpDocMethodsWithoutMagicCall' => 'use_phpdoc_method_without_magic_or_parent', 'usePhpDocPropertiesWithoutMagicCall' => 'use_phpdoc_property_without_magic_or_parent', 'memoizeMethodCallResults' => 'memoize_method_calls', 'hoistConstants' => 'hoist_constants', 'addParamDefaultToDocblockType' => 'add_param_default_to_docblock_type', 'checkForThrowsDocblock' => 'check_for_throws_docblock', 'checkForThrowsInGlobalScope' => 'check_for_throws_in_global_scope', 'ignoreInternalFunctionFalseReturn' => 'ignore_internal_falsable_issues', 'ignoreInternalFunctionNullReturn' => 'ignore_internal_nullable_issues', 'includePhpVersionsInErrorBaseline' => 'include_php_versions_in_error_baseline', 'ensureArrayStringOffsetsExist' => 'ensure_array_string_offsets_exist', 'ensureArrayIntOffsetsExist' => 'ensure_array_int_offsets_exist', 'reportMixedIssues' => 'show_mixed_issues', 'skipChecksOnUnresolvableIncludes' => 'skip_checks_on_unresolvable_includes', 'sealAllMethods' => 'seal_all_methods', 'sealAllProperties' => 'seal_all_properties', 'runTaintAnalysis' => 'run_taint_analysis', 'usePhpStormMetaPath' => 'use_phpstorm_meta_path', 'allowInternalNamedArgumentsCalls' => 'allow_internal_named_arg_calls', 'allowNamedArgumentCalls' => 'allow_named_arg_calls', 'findUnusedPsalmSuppress' => 'find_unused_psalm_suppress', 'findUnusedBaselineEntry' => 'find_unused_baseline_entry', 'reportInfo' => 'report_info', 'restrictReturnTypes' => 'restrict_return_types', 'limitMethodComplexity' => 'limit_method_complexity'];
        foreach ($booleanAttributes as $xmlName => $internalName) {
            if (isset($config_xml[$xmlName])) {
                $attribute_text = (string) $config_xml[$xmlName];
                $config->setBooleanAttribute($internalName, $attribute_text === 'true' || $attribute_text === '1');
            }
        }
        if ($config->resolve_from_config_file) {
            $config->base_dir = $base_dir;
        } else {
            $config->base_dir = $current_dir;
            $base_dir = $current_dir;
        }
        $composer_json_path = Composer::getJsonFilePath($config->base_dir);
        $composer_json = null;
        if (file_exists($composer_json_path)) {
            $composer_json = json_decode(file_get_contents($composer_json_path), \true);
            if (!is_array($composer_json)) {
                throw new UnexpectedValueException('Invalid composer.json at ' . $composer_json_path);
            }
        }
        $required_extensions = [];
        foreach ($composer_json["require"] ?? [] as $required => $_) {
            if (strpos($required, "ext-") === 0) {
                $required_extensions[strtolower(substr($required, 4))] = \true;
            }
        }
        foreach ($required_extensions as $required_ext => $_) {
            if (isset($config->php_extensions[$required_ext])) {
                $config->php_extensions[$required_ext] = \true;
            } else {
                $config->php_extensions_not_supported[$required_ext] = \true;
            }
        }
        if (isset($config_xml->enableExtensions) && isset($config_xml->enableExtensions->extension)) {
            foreach ($config_xml->enableExtensions->extension as $extension) {
                assert(isset($extension["name"]));
                $extensionName = (string) $extension["name"];
                assert(array_key_exists($extensionName, $config->php_extensions));
                $config->php_extensions[$extensionName] = \true;
            }
        }
        if (isset($config_xml->disableExtensions) && isset($config_xml->disableExtensions->extension)) {
            foreach ($config_xml->disableExtensions->extension as $extension) {
                assert(isset($extension["name"]));
                $extensionName = (string) $extension["name"];
                assert(array_key_exists($extensionName, $config->php_extensions));
                $config->php_extensions[$extensionName] = \false;
            }
        }
        if (isset($config_xml['phpVersion'])) {
            $config->configured_php_version = (string) $config_xml['phpVersion'];
        }
        if (isset($config_xml['autoloader'])) {
            $autoloader_path = $config->base_dir . DIRECTORY_SEPARATOR . $config_xml['autoloader'];
            if (!file_exists($autoloader_path)) {
                // in here for legacy reasons where people put absolute paths but psalm resolved it relative
                if ($config_xml['autoloader']->__toString()[0] === '/') {
                    $autoloader_path = $config_xml['autoloader']->__toString();
                }
                if (!file_exists($autoloader_path)) {
                    throw new ConfigException('Cannot locate autoloader');
                }
            }
            $config->autoloader = realpath($autoloader_path);
        }
        if (isset($config_xml['cacheDirectory'])) {
            $config->cache_directory = (string) $config_xml['cacheDirectory'];
        } elseif ($user_cache_dir = (new Xdg())->getHomeCacheDir()) {
            $config->cache_directory = $user_cache_dir . '/psalm';
        } else {
            $config->cache_directory = sys_get_temp_dir() . '/psalm';
        }
        $config->global_cache_directory = $config->cache_directory;
        $config->cache_directory .= DIRECTORY_SEPARATOR . sha1($base_dir);
        if (isset($config_xml['serializer'])) {
            $attribute_text = (string) $config_xml['serializer'];
            $config->use_igbinary = $attribute_text === 'igbinary';
        } elseif ($igbinary_version = phpversion('igbinary')) {
            $config->use_igbinary = version_compare($igbinary_version, '2.0.5') >= 0;
        }
        if (!isset($config_xml['findUnusedBaselineEntry'])) {
            $config->config_warnings[] = '"findUnusedBaselineEntry" will be defaulted to "true" in Psalm 6.' . ' You should explicitly enable or disable this setting.';
        }
        if (isset($config_xml['findUnusedCode'])) {
            $attribute_text = (string) $config_xml['findUnusedCode'];
            $config->find_unused_code = $attribute_text === 'true' || $attribute_text === '1';
            $config->find_unused_variables = $config->find_unused_code;
        } else {
            $config->config_warnings[] = '"findUnusedCode" will be defaulted to "true" in Psalm 6.' . ' You should explicitly enable or disable this setting.';
        }
        if (isset($config_xml['findUnusedVariablesAndParams'])) {
            $attribute_text = (string) $config_xml['findUnusedVariablesAndParams'];
            $config->find_unused_variables = $attribute_text === 'true' || $attribute_text === '1';
        }
        if (isset($config_xml['errorLevel'])) {
            $attribute_text = (int) $config_xml['errorLevel'];
            if (!in_array($attribute_text, [1, 2, 3, 4, 5, 6, 7, 8], \true)) {
                throw new ConfigException('Invalid error level ' . $config_xml['errorLevel']);
            }
            $config->level = $attribute_text;
        } else {
            $config->level = 2;
        }
        // turn on unused variable detection in level 1
        if (!isset($config_xml['findUnusedCode']) && !isset($config_xml['findUnusedVariablesAndParams']) && $config->level === 1 && $config->show_mixed_issues !== \false) {
            $config->find_unused_variables = \true;
        }
        if (isset($config_xml['errorBaseline'])) {
            $attribute_text = (string) $config_xml['errorBaseline'];
            $config->error_baseline = $attribute_text;
        }
        if (isset($config_xml['maxStringLength'])) {
            $attribute_text = (int) $config_xml['maxStringLength'];
            $config->max_string_length = $attribute_text;
        }
        if (isset($config_xml['maxShapedArraySize'])) {
            $attribute_text = (int) $config_xml['maxShapedArraySize'];
            $config->max_shaped_array_size = $attribute_text;
        }
        if (isset($config_xml['inferPropertyTypesFromConstructor'])) {
            $attribute_text = (string) $config_xml['inferPropertyTypesFromConstructor'];
            $config->infer_property_types_from_constructor = $attribute_text === 'true' || $attribute_text === '1';
        }
        if (isset($config_xml['triggerErrorExits'])) {
            $attribute_text = (string) $config_xml['triggerErrorExits'];
            if ($attribute_text === 'always' || $attribute_text === 'never') {
                $config->trigger_error_exits = $attribute_text;
            }
        }
        if (isset($config_xml->projectFiles)) {
            $config->project_files = ProjectFileFilter::loadFromXMLElement($config_xml->projectFiles, $base_dir, \true);
        }
        if (isset($config_xml->extraFiles)) {
            $config->extra_files = ProjectFileFilter::loadFromXMLElement($config_xml->extraFiles, $base_dir, \true);
        }
        if (isset($config_xml->taintAnalysis->ignoreFiles)) {
            $config->taint_analysis_ignored_files = TaintAnalysisFileFilter::loadFromXMLElement($config_xml->taintAnalysis->ignoreFiles, $base_dir, \false);
        }
        if (isset($config_xml->fileExtensions)) {
            $config->file_extensions = [];
            $config->loadFileExtensions($config_xml->fileExtensions->extension);
        }
        if (isset($config_xml->mockClasses) && isset($config_xml->mockClasses->class)) {
            /** @var SimpleXMLElement $mock_class */
            foreach ($config_xml->mockClasses->class as $mock_class) {
                $config->mock_classes[] = strtolower((string) $mock_class['name']);
            }
        }
        if (isset($config_xml->universalObjectCrates) && isset($config_xml->universalObjectCrates->class)) {
            /** @var SimpleXMLElement $universal_object_crate */
            foreach ($config_xml->universalObjectCrates->class as $universal_object_crate) {
                /** @var string $classString */
                $classString = $universal_object_crate['name'];
                $config->addUniversalObjectCrate($classString);
            }
        }
        if (isset($config_xml->ignoreExceptions)) {
            if (isset($config_xml->ignoreExceptions->class)) {
                /** @var SimpleXMLElement $exception_class */
                foreach ($config_xml->ignoreExceptions->class as $exception_class) {
                    $exception_name = (string) $exception_class['name'];
                    $global_attribute_text = (string) $exception_class['onlyGlobalScope'];
                    if ($global_attribute_text !== 'true' && $global_attribute_text !== '1') {
                        $config->ignored_exceptions[$exception_name] = \true;
                    }
                    $config->ignored_exceptions_in_global_scope[$exception_name] = \true;
                }
            }
            if (isset($config_xml->ignoreExceptions->classAndDescendants)) {
                /** @var SimpleXMLElement $exception_class */
                foreach ($config_xml->ignoreExceptions->classAndDescendants as $exception_class) {
                    $exception_name = (string) $exception_class['name'];
                    $global_attribute_text = (string) $exception_class['onlyGlobalScope'];
                    if ($global_attribute_text !== 'true' && $global_attribute_text !== '1') {
                        $config->ignored_exceptions_and_descendants[$exception_name] = \true;
                    }
                    $config->ignored_exceptions_and_descendants_in_global_scope[$exception_name] = \true;
                }
            }
        }
        if (isset($config_xml->forbiddenFunctions) && isset($config_xml->forbiddenFunctions->function)) {
            /** @var SimpleXMLElement $forbidden_function */
            foreach ($config_xml->forbiddenFunctions->function as $forbidden_function) {
                $config->forbidden_functions[strtolower((string) $forbidden_function['name'])] = \true;
            }
        }
        if (isset($config_xml->stubs) && isset($config_xml->stubs->file)) {
            /** @var SimpleXMLElement $stub_file */
            foreach ($config_xml->stubs->file as $stub_file) {
                $stub_file_name = (string) $stub_file['name'];
                if (!Path::isAbsolute($stub_file_name)) {
                    $stub_file_name = $config->base_dir . DIRECTORY_SEPARATOR . $stub_file_name;
                }
                $file_path = realpath($stub_file_name);
                if (!$file_path) {
                    throw new ConfigException('Cannot resolve stubfile path ' . rtrim($config->base_dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $stub_file['name']);
                }
                if (isset($stub_file['preloadClasses'])) {
                    $preload_classes = (string) $stub_file['preloadClasses'];
                    if ($preload_classes === 'true' || $preload_classes === '1') {
                        $config->addPreloadedStubFile($file_path);
                    } else {
                        $config->addStubFile($file_path);
                    }
                } else {
                    $config->addStubFile($file_path);
                }
            }
        }
        // this plugin loading system borrows heavily from etsy/phan
        if (isset($config_xml->plugins)) {
            if (isset($config_xml->plugins->plugin)) {
                /** @var SimpleXMLElement $plugin */
                foreach ($config_xml->plugins->plugin as $plugin) {
                    $plugin_file_name = (string) $plugin['filename'];
                    $path = Path::isAbsolute($plugin_file_name) ? $plugin_file_name : $config->base_dir . $plugin_file_name;
                    $config->addPluginPath($path);
                }
            }
            if (isset($config_xml->plugins->pluginClass)) {
                /** @var SimpleXMLElement $plugin */
                foreach ($config_xml->plugins->pluginClass as $plugin) {
                    $plugin_class_name = $plugin['class'];
                    // any child elements are used as plugin configuration
                    $plugin_config = null;
                    if ($plugin->count()) {
                        $plugin_config = $plugin->children();
                    }
                    $config->addPluginClass((string) $plugin_class_name, $plugin_config);
                }
            }
        }
        if (isset($config_xml->issueHandlers)) {
            foreach ($config_xml->issueHandlers as $issue_handlers) {
                /** @var SimpleXMLElement $issue_handler */
                foreach ($issue_handlers->children() as $key => $issue_handler) {
                    if ($key === 'PluginIssue') {
                        $custom_class_name = (string) $issue_handler['name'];
                        /** @var string $key */
                        $config->issue_handlers[$custom_class_name] = IssueHandler::loadFromXMLElement($issue_handler, $base_dir);
                    } else {
                        /** @var string $key */
                        $config->issue_handlers[$key] = IssueHandler::loadFromXMLElement($issue_handler, $base_dir);
                    }
                }
            }
        }
        if (isset($config_xml->globals) && isset($config_xml->globals->var)) {
            /** @var SimpleXMLElement $var */
            foreach ($config_xml->globals->var as $var) {
                $config->globals['$' . (string) $var['name']] = (string) $var['type'];
            }
        }
        if (isset($config_xml['threads'])) {
            $config->threads = (int) $config_xml['threads'];
        }
        return $config;
    }
    public static function getInstance() : \Psalm\Config
    {
        if (self::$instance) {
            return self::$instance;
        }
        throw new UnexpectedValueException('No config initialized');
    }
    public function setComposerClassLoader(?ClassLoader $loader = null) : void
    {
        $this->composer_class_loader = $loader;
    }
    public function setAdvancedErrorLevel(string $issue_key, array $config, ?string $default_error_level = null) : void
    {
        $this->issue_handlers[$issue_key] = new IssueHandler();
        if ($default_error_level !== null) {
            $this->issue_handlers[$issue_key]->setErrorLevel($default_error_level);
        }
        $this->issue_handlers[$issue_key]->setCustomLevels($config, $this->base_dir);
    }
    public function setCustomErrorLevel(string $issue_key, string $error_level) : void
    {
        $this->issue_handlers[$issue_key] = new IssueHandler();
        $this->issue_handlers[$issue_key]->setErrorLevel($error_level);
    }
    /**
     * @throws ConfigException if a Config file could not be found
     */
    private function loadFileExtensions(SimpleXMLElement $extensions) : void
    {
        foreach ($extensions as $extension) {
            $extension_name = preg_replace('/^\\.?/', '', (string) $extension['name'], 1);
            $this->file_extensions[] = $extension_name;
            if (isset($extension['scanner'])) {
                $path = $this->base_dir . (string) $extension['scanner'];
                if (!file_exists($path)) {
                    throw new ConfigException('Error parsing config: cannot find file ' . $path);
                }
                $this->filetype_scanner_paths[$extension_name] = $path;
            }
            if (isset($extension['checker'])) {
                $path = $this->base_dir . (string) $extension['checker'];
                if (!file_exists($path)) {
                    throw new ConfigException('Error parsing config: cannot find file ' . $path);
                }
                $this->filetype_analyzer_paths[$extension_name] = $path;
            }
        }
    }
    public function addPluginPath(string $path) : void
    {
        if (!file_exists($path)) {
            throw new InvalidArgumentException('Cannot find plugin file ' . $path);
        }
        $this->plugin_paths[] = $path;
    }
    public function addPluginClass(string $class_name, ?SimpleXMLElement $plugin_config = null) : void
    {
        $this->plugin_classes[] = ['class' => $class_name, 'config' => $plugin_config];
    }
    /** @return array<array{class:string, config:?SimpleXMLElement}> */
    public function getPluginClasses() : array
    {
        return $this->plugin_classes;
    }
    public function processPluginFileExtensions(ProjectAnalyzer $projectAnalyzer) : void
    {
        $projectAnalyzer->progress->debug('Process plugin adjustments...' . PHP_EOL);
        $socket = new \Psalm\PluginFileExtensionsSocket($this);
        foreach ($this->plugin_classes as $pluginClassEntry) {
            $pluginClassName = $pluginClassEntry['class'];
            $pluginConfig = $pluginClassEntry['config'];
            $plugin = $this->loadPlugin($projectAnalyzer, $pluginClassName);
            if (!$plugin instanceof PluginFileExtensionsInterface) {
                continue;
            }
            try {
                $plugin->processFileExtensions($socket, $pluginConfig);
            } catch (Throwable $t) {
                throw new ConfigException('Failed to process plugin file extensions ' . $pluginClassName, 1635800581, $t);
            }
            $projectAnalyzer->progress->debug('Initialized plugin ' . $pluginClassName . ' successfully' . PHP_EOL);
        }
        // populate additional aspects after plugins have been initialized
        foreach ($socket->getAdditionalFileExtensions() as $fileExtension) {
            $this->file_extensions[] = $fileExtension;
        }
        foreach ($socket->getAdditionalFileTypeScanners() as $extension => $className) {
            $this->filetype_scanners[$extension] = $className;
        }
        foreach ($socket->getAdditionalFileTypeAnalyzers() as $extension => $className) {
            $this->filetype_analyzers[$extension] = $className;
        }
    }
    /**
     * Initialises all the plugins (done once the config is fully loaded)
     */
    public function initializePlugins(ProjectAnalyzer $project_analyzer) : void
    {
        $codebase = $project_analyzer->getCodebase();
        $project_analyzer->progress->debug('Initializing plugins...' . PHP_EOL);
        $socket = new \Psalm\PluginRegistrationSocket($this, $codebase);
        // initialize plugin classes earlier to let them hook into subsequent load process
        foreach ($this->plugin_classes as $plugin_class_entry) {
            $plugin_class_name = $plugin_class_entry['class'];
            $plugin_config = $plugin_class_entry['config'];
            $plugin = $this->loadPlugin($project_analyzer, $plugin_class_name);
            if (!$plugin instanceof PluginEntryPointInterface) {
                continue;
            }
            try {
                $plugin($socket, $plugin_config);
            } catch (Throwable $t) {
                throw new ConfigException('Failed to invoke plugin ' . $plugin_class_name, 1635800582, $t);
            }
            $project_analyzer->progress->debug('Initialized plugin ' . $plugin_class_name . ' successfully' . PHP_EOL);
        }
        foreach ($this->filetype_scanner_paths as $extension => $path) {
            $fq_class_name = $this->getPluginClassForPath($codebase, $path, FileScanner::class);
            self::requirePath($path);
            $this->filetype_scanners[$extension] = $fq_class_name;
        }
        foreach ($this->filetype_analyzer_paths as $extension => $path) {
            $fq_class_name = $this->getPluginClassForPath($codebase, $path, FileAnalyzer::class);
            self::requirePath($path);
            $this->filetype_analyzers[$extension] = $fq_class_name;
        }
        foreach ($this->plugin_paths as $path) {
            try {
                $plugin = new \Psalm\FileBasedPluginAdapter($path, $this, $codebase);
                $plugin($socket);
            } catch (Throwable $e) {
                throw new ConfigException('Failed to load plugin ' . $path, 0, $e);
            }
        }
        new HtmlFunctionTainter();
        $socket->registerHooksFromClass(HtmlFunctionTainter::class);
    }
    private function loadPlugin(ProjectAnalyzer $projectAnalyzer, string $pluginClassName) : PluginInterface
    {
        if (isset($this->plugins[$pluginClassName])) {
            return $this->plugins[$pluginClassName];
        }
        try {
            // Below will attempt to load plugins from the project directory first.
            // Failing that, it will use registered autoload chain, which will load
            // plugins from Psalm directory or phar file. If that fails as well, it
            // will fall back to project autoloader. It may seem that the last step
            // will always fail, but it's only true if project uses Composer autoloader
            if ($this->composer_class_loader && ($pluginclas_class_path = $this->composer_class_loader->findFile($pluginClassName))) {
                $projectAnalyzer->progress->debug('Loading plugin ' . $pluginClassName . ' via require' . PHP_EOL);
                self::requirePath($pluginclas_class_path);
            } else {
                if (!class_exists($pluginClassName)) {
                    throw new UnexpectedValueException($pluginClassName . ' is not a known class');
                }
            }
            if (!is_a($pluginClassName, PluginInterface::class, \true)) {
                throw new UnexpectedValueException($pluginClassName . ' is not a PluginInterface implementation');
            }
            $this->plugins[$pluginClassName] = new $pluginClassName();
            $projectAnalyzer->progress->debug('Loaded plugin ' . $pluginClassName . PHP_EOL);
            return $this->plugins[$pluginClassName];
        } catch (Throwable $e) {
            throw new ConfigException('Failed to load plugin ' . $pluginClassName, 0, $e);
        }
    }
    private static function requirePath(string $path) : void
    {
        /** @psalm-suppress UnresolvableInclude */
        require_once $path;
    }
    /**
     * @template T
     * @param  T::class $must_extend
     * @return class-string<T>
     */
    private function getPluginClassForPath(\Psalm\Codebase $codebase, string $path, string $must_extend) : string
    {
        $file_storage = $codebase->createFileStorageForPath($path);
        $file_to_scan = new FileScanner($path, $this->shortenFileName($path), \true);
        $file_to_scan->scan($codebase, $file_storage);
        $declared_classes = ClassLikeAnalyzer::getClassesForFile($codebase, $path);
        if (!count($declared_classes)) {
            throw new InvalidArgumentException('Plugins must have at least one class in the file - ' . $path . ' has ' . count($declared_classes));
        }
        $fq_class_name = reset($declared_classes);
        if (!$codebase->classlikes->classExtends($fq_class_name, $must_extend)) {
            throw new InvalidArgumentException('This plugin must extend ' . $must_extend . ' - ' . $path . ' does not');
        }
        /**
         * @var class-string<T>
         */
        return $fq_class_name;
    }
    public function shortenFileName(string $to) : string
    {
        if (!is_file($to)) {
            return preg_replace('/^' . preg_quote($this->base_dir, '/') . '/', '', $to, 1);
        }
        $from = $this->base_dir;
        // some compatibility fixes for Windows paths
        $from = is_dir($from) ? rtrim($from, '\\/') . '/' : $from;
        $to = is_dir($to) ? rtrim($to, '\\/') . '/' : $to;
        $from = str_replace('\\', '/', $from);
        $to = str_replace('\\', '/', $to);
        $from = explode('/', $from);
        $to = explode('/', $to);
        $relPath = $to;
        foreach ($from as $depth => $dir) {
            // find first non-matching dir
            if ($dir === $to[$depth]) {
                // ignore this directory
                array_shift($relPath);
            } else {
                // get number of remaining dirs to $from
                $remaining = count($from) - $depth;
                if ($remaining > 1) {
                    // add traversals up to first matching dir
                    $padLength = (count($relPath) + $remaining - 1) * -1;
                    $relPath = array_pad($relPath, $padLength, '..');
                    break;
                }
            }
        }
        return implode('/', $relPath);
    }
    public function reportIssueInFile(string $issue_type, string $file_path) : bool
    {
        if (($this->show_mixed_issues === \false || $this->level > 2) && in_array($issue_type, self::MIXED_ISSUES, \true)) {
            return \false;
        }
        if ($this->mustBeIgnored($file_path)) {
            return \false;
        }
        $dependent_files = [strtolower($file_path) => $file_path];
        $project_analyzer = ProjectAnalyzer::getInstance();
        // if the option is set and at least one file is passed via CLI
        if ($this->hide_all_errors_except_passed_files && $project_analyzer->check_paths_files && !in_array($file_path, $project_analyzer->check_paths_files, \true)) {
            return \false;
        }
        $codebase = $project_analyzer->getCodebase();
        if (!$this->hide_external_errors) {
            try {
                $file_storage = $codebase->file_storage_provider->get($file_path);
                $dependent_files += $file_storage->required_by_file_paths;
            } catch (InvalidArgumentException $e) {
                // do nothing
            }
        }
        $any_file_path_matched = \false;
        foreach ($dependent_files as $dependent_file_path) {
            if ((!$project_analyzer->full_run && $codebase->analyzer->canReportIssues($dependent_file_path) || $project_analyzer->canReportIssues($dependent_file_path)) && ($file_path === $dependent_file_path || !$this->mustBeIgnored($dependent_file_path))) {
                $any_file_path_matched = \true;
                break;
            }
        }
        if (!$any_file_path_matched) {
            return \false;
        }
        if ($this->getReportingLevelForFile($issue_type, $file_path) === self::REPORT_SUPPRESS) {
            return \false;
        }
        return \true;
    }
    public function isInProjectDirs(string $file_path) : bool
    {
        return $this->project_files && $this->project_files->allows($file_path);
    }
    public function isInExtraDirs(string $file_path) : bool
    {
        return $this->extra_files && $this->extra_files->allows($file_path);
    }
    public function mustBeIgnored(string $file_path) : bool
    {
        return $this->project_files && $this->project_files->forbids($file_path);
    }
    public function trackTaintsInPath(string $file_path) : bool
    {
        return !$this->taint_analysis_ignored_files || $this->taint_analysis_ignored_files->allows($file_path);
    }
    public function getReportingLevelForIssue(CodeIssue $e) : string
    {
        $fqcn_parts = explode('\\', get_class($e));
        $issue_type = array_pop($fqcn_parts);
        $reporting_level = null;
        if ($e instanceof ClassIssue) {
            $reporting_level = $this->getReportingLevelForClass($issue_type, $e->fq_classlike_name);
        } elseif ($e instanceof MethodIssue) {
            $reporting_level = $this->getReportingLevelForMethod($issue_type, $e->method_id);
        } elseif ($e instanceof FunctionIssue) {
            $reporting_level = $this->getReportingLevelForFunction($issue_type, $e->function_id);
        } elseif ($e instanceof PropertyIssue) {
            $reporting_level = $this->getReportingLevelForProperty($issue_type, $e->property_id);
        } elseif ($e instanceof ClassConstantIssue) {
            $reporting_level = $this->getReportingLevelForClassConstant($issue_type, $e->const_id);
        } elseif ($e instanceof ArgumentIssue && $e->function_id) {
            $reporting_level = $this->getReportingLevelForArgument($issue_type, $e->function_id);
        } elseif ($e instanceof VariableIssue) {
            $reporting_level = $this->getReportingLevelForVariable($issue_type, $e->var_name);
        }
        if ($reporting_level === null) {
            $reporting_level = $this->getReportingLevelForFile($issue_type, $e->getFilePath());
        }
        if (!$this->report_info && $reporting_level === self::REPORT_INFO) {
            $reporting_level = self::REPORT_SUPPRESS;
        }
        $parent_issue_type = self::getParentIssueType($issue_type);
        if ($parent_issue_type && $reporting_level === self::REPORT_ERROR) {
            $parent_reporting_level = $this->getReportingLevelForFile($parent_issue_type, $e->getFilePath());
            if ($parent_reporting_level !== $reporting_level) {
                return $parent_reporting_level;
            }
        }
        return $reporting_level;
    }
    /**
     * @psalm-pure
     */
    public static function getParentIssueType(string $issue_type) : ?string
    {
        if ($issue_type === 'PossiblyUndefinedIntArrayOffset' || $issue_type === 'PossiblyUndefinedStringArrayOffset') {
            return 'PossiblyUndefinedArrayOffset';
        }
        if ($issue_type === 'PossiblyNullReference') {
            return 'NullReference';
        }
        if ($issue_type === 'PossiblyFalseReference') {
            return null;
        }
        if ($issue_type === 'PossiblyUndefinedArrayOffset') {
            return null;
        }
        if (strpos($issue_type, 'Possibly') === 0) {
            $stripped_issue_type = preg_replace('/^Possibly(False|Null)?/', '', $issue_type, 1);
            if (strpos($stripped_issue_type, 'Invalid') === \false && strpos($stripped_issue_type, 'Un') !== 0) {
                $stripped_issue_type = 'Invalid' . $stripped_issue_type;
            }
            return $stripped_issue_type;
        }
        if (strpos($issue_type, 'Tainted') === 0) {
            return 'TaintedInput';
        }
        if (preg_match('/^(False|Null)[A-Z]/', $issue_type) && !strpos($issue_type, 'Reference')) {
            return preg_replace('/^(False|Null)/', 'Invalid', $issue_type, 1);
        }
        if ($issue_type === 'UndefinedInterfaceMethod') {
            return 'UndefinedMethod';
        }
        if ($issue_type === 'UndefinedMagicPropertyFetch') {
            return 'UndefinedPropertyFetch';
        }
        if ($issue_type === 'UndefinedMagicPropertyAssignment') {
            return 'UndefinedPropertyAssignment';
        }
        if ($issue_type === 'UndefinedMagicMethod') {
            return 'UndefinedMethod';
        }
        if ($issue_type === 'PossibleRawObjectIteration') {
            return 'RawObjectIteration';
        }
        if ($issue_type === 'UninitializedProperty') {
            return 'PropertyNotSetInConstructor';
        }
        if ($issue_type === 'InvalidDocblockParamName') {
            return 'InvalidDocblock';
        }
        if ($issue_type === 'UnusedClosureParam') {
            return 'UnusedParam';
        }
        if ($issue_type === 'UnusedConstructor') {
            return 'UnusedMethod';
        }
        if ($issue_type === 'StringIncrement') {
            return 'InvalidOperand';
        }
        if ($issue_type === 'InvalidLiteralArgument') {
            return 'InvalidArgument';
        }
        if ($issue_type === 'RedundantConditionGivenDocblockType') {
            return 'RedundantCondition';
        }
        if ($issue_type === 'RedundantFunctionCallGivenDocblockType') {
            return 'RedundantFunctionCall';
        }
        if ($issue_type === 'RedundantCastGivenDocblockType') {
            return 'RedundantCast';
        }
        if ($issue_type === 'TraitMethodSignatureMismatch') {
            return 'MethodSignatureMismatch';
        }
        if ($issue_type === 'ImplementedParamTypeMismatch') {
            return 'MoreSpecificImplementedParamType';
        }
        if ($issue_type === 'UndefinedDocblockClass') {
            return 'UndefinedClass';
        }
        if ($issue_type === 'UnusedForeachValue') {
            return 'UnusedVariable';
        }
        return null;
    }
    public function getReportingLevelForFile(string $issue_type, string $file_path) : string
    {
        if (isset($this->issue_handlers[$issue_type])) {
            return $this->issue_handlers[$issue_type]->getReportingLevelForFile($file_path);
        }
        // this string is replaced by scoper for Phars, so be careful
        $issue_class = 'Psalm\\Issue\\' . $issue_type;
        if (!class_exists($issue_class) || !is_a($issue_class, CodeIssue::class, \true)) {
            return self::REPORT_ERROR;
        }
        /** @var int */
        $issue_level = $issue_class::ERROR_LEVEL;
        if ($issue_level > 0 && $issue_level < $this->level) {
            return self::REPORT_INFO;
        }
        return self::REPORT_ERROR;
    }
    public function getReportingLevelForClass(string $issue_type, string $fq_classlike_name) : ?string
    {
        if (isset($this->issue_handlers[$issue_type])) {
            return $this->issue_handlers[$issue_type]->getReportingLevelForClass($fq_classlike_name);
        }
        return null;
    }
    public function getReportingLevelForMethod(string $issue_type, string $method_id) : ?string
    {
        if (isset($this->issue_handlers[$issue_type])) {
            return $this->issue_handlers[$issue_type]->getReportingLevelForMethod($method_id);
        }
        return null;
    }
    public function getReportingLevelForFunction(string $issue_type, string $function_id) : ?string
    {
        $level = null;
        if (isset($this->issue_handlers[$issue_type])) {
            $level = $this->issue_handlers[$issue_type]->getReportingLevelForFunction($function_id);
            if ($level === null && $issue_type === 'UndefinedFunction') {
                // undefined functions trigger global namespace fallback
                // so we should also check reporting levels for the symbol in global scope
                $root_function_id = preg_replace('/.*\\\\/', '', $function_id);
                if ($root_function_id !== $function_id) {
                    /** @psalm-suppress PossiblyUndefinedStringArrayOffset https://github.com/vimeo/psalm/issues/7656 */
                    $level = $this->issue_handlers[$issue_type]->getReportingLevelForFunction($root_function_id);
                }
            }
        }
        return $level;
    }
    public function getReportingLevelForArgument(string $issue_type, string $function_id) : ?string
    {
        if (isset($this->issue_handlers[$issue_type])) {
            return $this->issue_handlers[$issue_type]->getReportingLevelForArgument($function_id);
        }
        return null;
    }
    public function getReportingLevelForProperty(string $issue_type, string $property_id) : ?string
    {
        if (isset($this->issue_handlers[$issue_type])) {
            return $this->issue_handlers[$issue_type]->getReportingLevelForProperty($property_id);
        }
        return null;
    }
    public function getReportingLevelForClassConstant(string $issue_type, string $constant_id) : ?string
    {
        if (isset($this->issue_handlers[$issue_type])) {
            return $this->issue_handlers[$issue_type]->getReportingLevelForClassConstant($constant_id);
        }
        return null;
    }
    public function getReportingLevelForVariable(string $issue_type, string $var_name) : ?string
    {
        if (isset($this->issue_handlers[$issue_type])) {
            return $this->issue_handlers[$issue_type]->getReportingLevelForVariable($var_name);
        }
        return null;
    }
    /**
     * @return array<string>
     */
    public function getProjectDirectories() : array
    {
        if (!$this->project_files) {
            return [];
        }
        return $this->project_files->getDirectories();
    }
    /**
     * @return array<string>
     */
    public function getProjectFiles() : array
    {
        if (!$this->project_files) {
            return [];
        }
        return $this->project_files->getFiles();
    }
    /**
     * @return array<string>
     */
    public function getExtraDirectories() : array
    {
        if (!$this->extra_files) {
            return [];
        }
        return $this->extra_files->getDirectories();
    }
    public function reportTypeStatsForFile(string $file_path) : bool
    {
        return $this->project_files && $this->project_files->allows($file_path) && $this->project_files->reportTypeStats($file_path);
    }
    public function useStrictTypesForFile(string $file_path) : bool
    {
        return $this->project_files && $this->project_files->useStrictTypes($file_path);
    }
    /**
     * @return array<int, string>
     */
    public function getFileExtensions() : array
    {
        return $this->file_extensions;
    }
    /**
     * @return array<string, class-string<FileScanner>>
     */
    public function getFiletypeScanners() : array
    {
        return $this->filetype_scanners;
    }
    /**
     * @return array<string, class-string<FileAnalyzer>>
     */
    public function getFiletypeAnalyzers() : array
    {
        return $this->filetype_analyzers;
    }
    /**
     * @return array<int, string>
     */
    public function getMockClasses() : array
    {
        return $this->mock_classes;
    }
    public function visitPreloadedStubFiles(\Psalm\Codebase $codebase, ?Progress $progress = null) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $core_generic_files = [];
        if (PHP_VERSION_ID < 80000 && $codebase->analysis_php_version_id >= 80000) {
            $stringable_path = dirname(__DIR__, 2) . '/stubs/Php80.phpstub';
            if (!file_exists($stringable_path)) {
                throw new UnexpectedValueException('Cannot locate PHP 8.0 classes');
            }
            $core_generic_files[] = $stringable_path;
        }
        if (PHP_VERSION_ID < 80100 && $codebase->analysis_php_version_id >= 80100) {
            $stringable_path = dirname(__DIR__, 2) . '/stubs/Php81.phpstub';
            if (!file_exists($stringable_path)) {
                throw new UnexpectedValueException('Cannot locate PHP 8.1 classes');
            }
            $core_generic_files[] = $stringable_path;
        }
        if (PHP_VERSION_ID < 80200 && $codebase->analysis_php_version_id >= 80200) {
            $stringable_path = dirname(__DIR__, 2) . '/stubs/Php82.phpstub';
            if (!file_exists($stringable_path)) {
                throw new UnexpectedValueException('Cannot locate PHP 8.2 classes');
            }
            $core_generic_files[] = $stringable_path;
        }
        $stub_files = array_merge($core_generic_files, $this->preloaded_stub_files);
        if (!$stub_files) {
            return;
        }
        foreach ($stub_files as $file_path) {
            $file_path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $file_path);
            $codebase->scanner->addFileToDeepScan($file_path);
        }
        $progress->debug('Registering preloaded stub files' . "\n");
        $codebase->register_stub_files = \true;
        $codebase->scanFiles();
        $codebase->register_stub_files = \false;
        $progress->debug('Finished registering preloaded stub files' . "\n");
    }
    public function visitStubFiles(\Psalm\Codebase $codebase, ?Progress $progress = null) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        $codebase->register_stub_files = \true;
        $dir_lvl_2 = dirname(__DIR__, 2);
        $this->internal_stubs = [$dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'CoreGenericFunctions.phpstub', $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'CoreGenericClasses.phpstub', $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'CoreGenericIterators.phpstub', $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'CoreImmutableClasses.phpstub', $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'Reflection.phpstub', $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'SPL.phpstub'];
        if ($codebase->analysis_php_version_id >= 80000) {
            $stringable_path = $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'Php80.phpstub';
            $this->internal_stubs[] = $stringable_path;
        }
        if ($codebase->analysis_php_version_id >= 80100) {
            $stringable_path = $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'Php81.phpstub';
            $this->internal_stubs[] = $stringable_path;
        }
        if ($codebase->analysis_php_version_id >= 80200) {
            $stringable_path = $dir_lvl_2 . DIRECTORY_SEPARATOR . 'stubs' . DIRECTORY_SEPARATOR . 'Php82.phpstub';
            $this->internal_stubs[] = $stringable_path;
            $this->php_extensions['random'] = \true;
            // random is a part of the PHP core starting from PHP 8.2
        }
        $ext_stubs_dir = $dir_lvl_2 . DIRECTORY_SEPARATOR . "stubs" . DIRECTORY_SEPARATOR . "extensions";
        foreach ($this->php_extensions as $ext => $enabled) {
            if ($enabled) {
                $this->internal_stubs[] = $ext_stubs_dir . DIRECTORY_SEPARATOR . "{$ext}.phpstub";
            }
        }
        /** @deprecated Will be removed in Psalm 6 */
        $extensions_to_load_stubs_using_deprecated_way = ['apcu', 'random', 'redis'];
        foreach ($extensions_to_load_stubs_using_deprecated_way as $ext_name) {
            $ext_stub_path = $ext_stubs_dir . DIRECTORY_SEPARATOR . "{$ext_name}.phpstub";
            $is_stub_already_loaded = in_array($ext_stub_path, $this->internal_stubs, \true);
            if (!$is_stub_already_loaded && extension_loaded($ext_name)) {
                $this->internal_stubs[] = $ext_stub_path;
                $progress->write("Deprecation: Psalm stubs for ext-{$ext_name} loaded using legacy way." . " Instead, please declare ext-{$ext_name} as dependency in composer.json" . " or use <enableExtensions> and/or <disableExtensions> directives in Psalm config.\n");
            }
        }
        foreach ($this->internal_stubs as $stub_path) {
            if (!file_exists($stub_path)) {
                throw new UnexpectedValueException('Cannot locate ' . $stub_path);
            }
        }
        $stub_files = array_merge($this->internal_stubs, $this->stub_files);
        $phpstorm_meta_path = $this->base_dir . DIRECTORY_SEPARATOR . '.phpstorm.meta.php';
        if ($this->use_phpstorm_meta_path) {
            if (is_file($phpstorm_meta_path)) {
                $stub_files[] = $phpstorm_meta_path;
            } elseif (is_dir($phpstorm_meta_path)) {
                $phpstorm_meta_path = realpath($phpstorm_meta_path);
                foreach (glob($phpstorm_meta_path . '/*.meta.php', GLOB_NOSORT) as $glob) {
                    if (is_file($glob) && realpath(dirname($glob)) === $phpstorm_meta_path) {
                        $stub_files[] = $glob;
                    }
                }
            }
        }
        foreach ($stub_files as $file_path) {
            $file_path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $file_path);
            $codebase->scanner->addFileToDeepScan($file_path);
        }
        $progress->debug('Registering stub files' . "\n");
        $codebase->scanFiles();
        $progress->debug('Finished registering stub files' . "\n");
        $codebase->register_stub_files = \false;
    }
    public function getCacheDirectory() : ?string
    {
        if ($this->cache_directory === null) {
            return null;
        }
        if ($this->cache_directory_initialized) {
            return $this->cache_directory;
        }
        $cwd = null;
        if ($this->resolve_from_config_file) {
            $cwd = getcwd();
            chdir($this->base_dir);
        }
        try {
            if (!is_dir($this->cache_directory)) {
                try {
                    if (mkdir($this->cache_directory, 0777, \true) === \false) {
                        // any other error than directory already exists/permissions issue
                        throw new RuntimeException('Failed to create Psalm cache directory for unknown reasons');
                    }
                } catch (RuntimeException $e) {
                    if (!is_dir($this->cache_directory)) {
                        // rethrow the error with default message
                        // it contains the reason why creation failed
                        throw $e;
                    }
                }
            }
        } finally {
            if ($cwd) {
                chdir($cwd);
            }
        }
        $this->cache_directory_initialized = \true;
        return $this->cache_directory;
    }
    public function getGlobalCacheDirectory() : ?string
    {
        return $this->global_cache_directory;
    }
    /**
     * @return array<string, mixed>
     */
    public function getPredefinedConstants() : array
    {
        return $this->predefined_constants;
    }
    public function collectPredefinedConstants() : void
    {
        $this->predefined_constants = get_defined_constants();
    }
    /**
     * @return array<callable-string, bool>
     */
    public function getPredefinedFunctions() : array
    {
        return $this->predefined_functions;
    }
    public function collectPredefinedFunctions() : void
    {
        $defined_functions = get_defined_functions();
        foreach ($defined_functions['user'] as $function_name) {
            $this->predefined_functions[$function_name] = \true;
        }
        foreach ($defined_functions['internal'] as $function_name) {
            $this->predefined_functions[$function_name] = \true;
        }
    }
    public function setIncludeCollector(IncludeCollector $include_collector) : void
    {
        $this->include_collector = $include_collector;
    }
    public function visitComposerAutoloadFiles(ProjectAnalyzer $project_analyzer, ?Progress $progress = null) : void
    {
        if ($progress === null) {
            $progress = new VoidProgress();
        }
        if (!$this->include_collector) {
            throw new LogicException("IncludeCollector should be set at this point");
        }
        $vendor_autoload_files_path = $this->base_dir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'composer' . DIRECTORY_SEPARATOR . 'autoload_files.php';
        if (file_exists($vendor_autoload_files_path)) {
            $this->include_collector->runAndCollect(static fn(): array => require $vendor_autoload_files_path);
        }
        $codebase = $project_analyzer->getCodebase();
        $this->collectPredefinedFunctions();
        if ($this->autoloader) {
            // somee classes that we think are missing may not actually be missing
            // as they might be autoloadable once we require the autoloader below
            $codebase->classlikes->forgetMissingClassLikes();
            $this->include_collector->runAndCollect([$this, 'requireAutoloader']);
        }
        $this->collectPredefinedConstants();
        $autoload_included_files = $this->include_collector->getFilteredIncludedFiles();
        if ($autoload_included_files) {
            $codebase->register_autoload_files = \true;
            $progress->debug('Registering autoloaded files' . "\n");
            foreach ($autoload_included_files as $file_path) {
                $file_path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $file_path);
                $progress->debug('   ' . $file_path . "\n");
                $codebase->scanner->addFileToDeepScan($file_path);
            }
            $codebase->scanner->scanFiles($codebase->classlikes);
            $progress->debug('Finished registering autoloaded files' . "\n");
            $codebase->register_autoload_files = \false;
        }
    }
    /**
     * @return string|false
     */
    public function getComposerFilePathForClassLike(string $fq_classlike_name)
    {
        if (!$this->composer_class_loader) {
            return \false;
        }
        return $this->composer_class_loader->findFile($fq_classlike_name);
    }
    public function getPotentialComposerFilePathForClassLike(string $class) : ?string
    {
        if (!$this->composer_class_loader) {
            return null;
        }
        $psr4_prefixes = $this->composer_class_loader->getPrefixesPsr4();
        // PSR-4 lookup
        $logicalPathPsr4 = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
        $candidate_path = null;
        $maxDepth = 0;
        $subPath = $class;
        while (\false !== ($lastPos = strrpos($subPath, '\\'))) {
            $subPath = substr($subPath, 0, $lastPos);
            $search = $subPath . '\\';
            if (isset($psr4_prefixes[$search])) {
                $depth = substr_count($search, '\\');
                $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
                foreach ($psr4_prefixes[$search] as $dir) {
                    $dir = realpath($dir);
                    if ($dir && $depth > $maxDepth && $this->isInProjectDirs($dir . DIRECTORY_SEPARATOR . 'testdummy.php')) {
                        $maxDepth = $depth;
                        $candidate_path = realpath($dir) . $pathEnd;
                    }
                }
            }
        }
        return $candidate_path;
    }
    public static function removeCacheDirectory(string $dir) : void
    {
        clearstatcache(\true, $dir);
        if (is_dir($dir)) {
            $objects = scandir($dir, SCANDIR_SORT_NONE);
            if ($objects === \false) {
                throw new UnexpectedValueException('Not expecting false here');
            }
            foreach ($objects as $object) {
                if ($object === '.' || $object === '..') {
                    continue;
                }
                $full_path = $dir . '/' . $object;
                // if it was deleted in the meantime/race condition with other psalm process
                if (!file_exists($full_path)) {
                    continue;
                }
                if (filetype($full_path) === 'dir') {
                    self::removeCacheDirectory($full_path);
                } else {
                    $fp = fopen($full_path, 'c');
                    if ($fp === \false) {
                        continue;
                    }
                    $max_wait_cycles = 5;
                    $has_lock = \false;
                    while ($max_wait_cycles > 0) {
                        if (flock($fp, LOCK_EX)) {
                            $has_lock = \true;
                            break;
                        }
                        $max_wait_cycles--;
                        usleep(50000);
                    }
                    try {
                        if (!$has_lock) {
                            throw new RuntimeException('Could not acquire lock for deletion of ' . $full_path);
                        }
                        unlink($full_path);
                        fclose($fp);
                    } catch (RuntimeException $e) {
                        if (is_resource($fp)) {
                            fclose($fp);
                        }
                        clearstatcache(\true, $full_path);
                        if (file_exists($full_path)) {
                            // rethrow the error with default message
                            // it contains the reason why deletion failed
                            throw $e;
                        }
                    }
                }
            }
            // may have been removed in the meantime
            clearstatcache(\true, $dir);
            if (is_dir($dir)) {
                rmdir($dir);
            }
        }
    }
    public function setServerMode() : void
    {
        if ($this->cache_directory !== null) {
            $this->cache_directory .= '-s';
        }
    }
    public function addStubFile(string $stub_file) : void
    {
        $this->stub_files[$stub_file] = $stub_file;
    }
    public function hasStubFile(string $stub_file) : bool
    {
        return isset($this->stub_files[$stub_file]);
    }
    /**
     * @return array<string, string>
     */
    public function getStubFiles() : array
    {
        return $this->stub_files;
    }
    public function addPreloadedStubFile(string $stub_file) : void
    {
        $this->preloaded_stub_files[$stub_file] = $stub_file;
    }
    public function getPhpVersion() : ?string
    {
        return $this->getPhpVersionFromConfig() ?? $this->getPHPVersionFromComposerJson();
    }
    public function getPhpVersionFromConfig() : ?string
    {
        return $this->configured_php_version;
    }
    private function setBooleanAttribute(string $name, bool $value) : void
    {
        $this->{$name} = $value;
    }
    /**
     * @psalm-suppress MixedAssignment
     * @psalm-suppress MixedArrayAccess
     */
    public function getPHPVersionFromComposerJson() : ?string
    {
        $composer_json_path = Composer::getJsonFilePath($this->base_dir);
        if (file_exists($composer_json_path)) {
            try {
                $composer_json = json_decode(file_get_contents($composer_json_path), \true, 512, JSON_THROW_ON_ERROR);
            } catch (JsonException $e) {
                $composer_json = null;
            }
            if (!$composer_json) {
                throw new UnexpectedValueException('Invalid composer.json at ' . $composer_json_path);
            }
            $php_version = $composer_json['require']['php'] ?? null;
            if (is_string($php_version)) {
                $version_parser = new VersionParser();
                $constraint = $version_parser->parseConstraints($php_version);
                foreach (['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] as $candidate) {
                    if ($constraint->matches(new Constraint('<=', "{$candidate}.0.0-dev")) || $constraint->matches(new Constraint('<=', "{$candidate}.999"))) {
                        return $candidate;
                    }
                }
            }
        }
        return null;
    }
    public function addUniversalObjectCrate(string $class) : void
    {
        if (!class_exists($class)) {
            throw new UnexpectedValueException($class . ' is not a known class');
        }
        $this->universal_object_crates[] = strtolower($class);
    }
    /**
     * @return array<int, lowercase-string>
     */
    public function getUniversalObjectCrates() : array
    {
        return $this->universal_object_crates;
    }
    /** @internal */
    public function requireAutoloader() : void
    {
        /** @psalm-suppress UnresolvableInclude */
        require $this->autoloader;
    }
}
<?php

namespace Psalm;

use function sha1;
use function strlen;
use function strrpos;
use function substr;
use function trim;
final class FileManipulation
{
    /** @var int */
    public $start;
    /** @var int */
    public $end;
    /** @var string */
    public $insertion_text;
    /** @var bool */
    public $preserve_indentation;
    /** @var bool */
    public $remove_trailing_newline;
    public function __construct(int $start, int $end, string $insertion_text, bool $preserve_indentation = \false, bool $remove_trailing_newline = \false)
    {
        $this->start = $start;
        $this->end = $end;
        $this->insertion_text = $insertion_text;
        $this->preserve_indentation = $preserve_indentation;
        $this->remove_trailing_newline = $remove_trailing_newline;
    }
    public function getKey() : string
    {
        return $this->start === $this->end ? $this->start . ':' . sha1($this->insertion_text) : $this->start . ':' . $this->end;
    }
    public function transform(string $existing_contents) : string
    {
        if ($this->preserve_indentation) {
            $newline_pos = strrpos($existing_contents, "\n", $this->start - strlen($existing_contents));
            $newline_pos = $newline_pos !== \false ? $newline_pos + 1 : 0;
            $indentation = substr($existing_contents, $newline_pos, $this->start - $newline_pos);
            if (trim($indentation) === '') {
                $this->insertion_text .= $indentation;
            }
        }
        if ($this->remove_trailing_newline && strlen($existing_contents) > $this->end && $existing_contents[$this->end] === "\n") {
            $newline_pos = strrpos($existing_contents, "\n", $this->start - strlen($existing_contents));
            $newline_pos = $newline_pos !== \false ? $newline_pos + 1 : 0;
            $indentation = substr($existing_contents, $newline_pos, $this->start - $newline_pos);
            if (trim($indentation) === '') {
                $this->start -= strlen($indentation);
                $this->end++;
            }
        }
        return substr($existing_contents, 0, $this->start) . $this->insertion_text . substr($existing_contents, $this->end);
    }
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\NullableType;
final class VirtualNullableType extends NullableType implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name;
final class VirtualName extends Name implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\MatchArm;
final class VirtualMatchArm extends MatchArm implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\LNumber;
use Psalm\Node\VirtualNode;
final class VirtualLNumber extends LNumber implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\Encapsed;
use Psalm\Node\VirtualNode;
final class VirtualEncapsed extends Encapsed implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\EncapsedStringPart;
use Psalm\Node\VirtualNode;
final class VirtualEncapsedStringPart extends EncapsedStringPart implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\String_;
use Psalm\Node\VirtualNode;
final class VirtualString extends String_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\DNumber;
use Psalm\Node\VirtualNode;
final class VirtualDNumber extends DNumber implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\File;
use Psalm\Node\VirtualNode;
final class VirtualFile extends File implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\Class_;
use Psalm\Node\VirtualNode;
final class VirtualClass extends Class_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\Line;
use Psalm\Node\VirtualNode;
final class VirtualLine extends Line implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\Method;
use Psalm\Node\VirtualNode;
final class VirtualMethod extends Method implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\Namespace_;
use Psalm\Node\VirtualNode;
final class VirtualNamespace extends Namespace_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\Function_;
use Psalm\Node\VirtualNode;
final class VirtualFunction extends Function_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\Dir;
use Psalm\Node\VirtualNode;
final class VirtualDir extends Dir implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Scalar\MagicConst;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Scalar\MagicConst\Trait_;
use Psalm\Node\VirtualNode;
final class VirtualTrait extends Trait_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Arg;
final class VirtualArg extends Arg implements \Psalm\Node\VirtualNode
{
}
<?php

namespace Psalm\Node;

/**
 * Describe a Node that is not part of the original AST and was created by Psalm for analysis
 */
interface VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\VarLikeIdentifier;
/**
 * Represents a name that is written in source code with a leading dollar,
 * but is not a proper variable. The leading dollar is not stored as part of the name.
 *
 * Examples: Names in property declarations are formatted as variables. Names in static property
 * lookups are also formatted as variables.
 */
final class VirtualVarLikeIdentifier extends VarLikeIdentifier implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\AttributeGroup;
final class VirtualAttributeGroup extends AttributeGroup implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\FuncCall;
use Psalm\Node\VirtualNode;
final class VirtualFuncCall extends FuncCall implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\StaticPropertyFetch;
use Psalm\Node\VirtualNode;
final class VirtualStaticPropertyFetch extends StaticPropertyFetch implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Array_;
use Psalm\Node\VirtualNode;
final class VirtualArray extends Array_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\UnaryMinus;
use Psalm\Node\VirtualNode;
final class VirtualUnaryMinus extends UnaryMinus implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PostDec;
use Psalm\Node\VirtualNode;
final class VirtualPostDec extends PostDec implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Eval_;
use Psalm\Node\VirtualNode;
final class VirtualEval extends Eval_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BitwiseNot;
use Psalm\Node\VirtualNode;
final class VirtualBitwiseNot extends BitwiseNot implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\BitwiseXor;
use Psalm\Node\VirtualNode;
final class VirtualBitwiseXor extends BitwiseXor implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Mul;
use Psalm\Node\VirtualNode;
final class VirtualMul extends Mul implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Spaceship;
use Psalm\Node\VirtualNode;
final class VirtualSpaceship extends Spaceship implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Mod;
use Psalm\Node\VirtualNode;
final class VirtualMod extends Mod implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Coalesce;
use Psalm\Node\VirtualNode;
final class VirtualCoalesce extends Coalesce implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Minus;
use Psalm\Node\VirtualNode;
final class VirtualMinus extends Minus implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use Psalm\Node\VirtualNode;
final class VirtualBooleanAnd extends BooleanAnd implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\LogicalOr;
use Psalm\Node\VirtualNode;
final class VirtualLogicalOr extends LogicalOr implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\GreaterOrEqual;
use Psalm\Node\VirtualNode;
final class VirtualGreaterOrEqual extends GreaterOrEqual implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Identical;
use Psalm\Node\VirtualNode;
final class VirtualIdentical extends Identical implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\BitwiseAnd;
use Psalm\Node\VirtualNode;
final class VirtualBitwiseAnd extends BitwiseAnd implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\ShiftLeft;
use Psalm\Node\VirtualNode;
final class VirtualShiftLeft extends ShiftLeft implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Smaller;
use Psalm\Node\VirtualNode;
final class VirtualSmaller extends Smaller implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\BooleanOr;
use Psalm\Node\VirtualNode;
final class VirtualBooleanOr extends BooleanOr implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Equal;
use Psalm\Node\VirtualNode;
final class VirtualEqual extends Equal implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Plus;
use Psalm\Node\VirtualNode;
final class VirtualPlus extends Plus implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\NotEqual;
use Psalm\Node\VirtualNode;
final class VirtualNotEqual extends NotEqual implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\SmallerOrEqual;
use Psalm\Node\VirtualNode;
final class VirtualSmallerOrEqual extends SmallerOrEqual implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\BitwiseOr;
use Psalm\Node\VirtualNode;
final class VirtualBitwiseOr extends BitwiseOr implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Pow;
use Psalm\Node\VirtualNode;
final class VirtualPow extends Pow implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Concat;
use Psalm\Node\VirtualNode;
final class VirtualConcat extends Concat implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Div;
use Psalm\Node\VirtualNode;
final class VirtualDiv extends Div implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\NotIdentical;
use Psalm\Node\VirtualNode;
final class VirtualNotIdentical extends NotIdentical implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\LogicalAnd;
use Psalm\Node\VirtualNode;
final class VirtualLogicalAnd extends LogicalAnd implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\Greater;
use Psalm\Node\VirtualNode;
final class VirtualGreater extends Greater implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\ShiftRight;
use Psalm\Node\VirtualNode;
final class VirtualShiftRight extends ShiftRight implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\BinaryOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BinaryOp\LogicalXor;
use Psalm\Node\VirtualNode;
final class VirtualLogicalXor extends LogicalXor implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\NullsafeMethodCall;
use Psalm\Node\VirtualNode;
final class VirtualNullsafeMethodCall extends NullsafeMethodCall implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Error;
use Psalm\Node\VirtualNode;
/**
 * Error node used during parsing with error recovery.
 *
 * An error node may be placed at a position where an expression is required, but an error occurred.
 * Error nodes will not be present if the parser is run in throwOnError mode (the default).
 */
final class VirtualError extends Error implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ClosureUse;
use Psalm\Node\VirtualNode;
final class VirtualClosureUse extends ClosureUse implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Empty_;
use Psalm\Node\VirtualNode;
final class VirtualEmpty extends Empty_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ArrayDimFetch;
use Psalm\Node\VirtualNode;
final class VirtualArrayDimFetch extends ArrayDimFetch implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignRef;
use Psalm\Node\VirtualNode;
final class VirtualAssignRef extends AssignRef implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ErrorSuppress;
use Psalm\Node\VirtualNode;
final class VirtualErrorSuppress extends ErrorSuppress implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PreInc;
use Psalm\Node\VirtualNode;
final class VirtualPreInc extends PreInc implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\YieldFrom;
use Psalm\Node\VirtualNode;
final class VirtualYieldFrom extends YieldFrom implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Match_;
use Psalm\Node\VirtualNode;
final class VirtualMatch extends Match_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PreDec;
use Psalm\Node\VirtualNode;
final class VirtualPreDec extends PreDec implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Instanceof_;
use Psalm\Node\VirtualNode;
final class VirtualInstanceof extends Instanceof_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\UnaryPlus;
use Psalm\Node\VirtualNode;
final class VirtualUnaryPlus extends UnaryPlus implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\New_;
use Psalm\Node\VirtualNode;
final class VirtualNew extends New_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Throw_;
use Psalm\Node\VirtualNode;
final class VirtualThrow extends Throw_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\List_;
use Psalm\Node\VirtualNode;
final class VirtualList extends List_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Yield_;
use Psalm\Node\VirtualNode;
final class VirtualYield extends Yield_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Assign;
use Psalm\Node\VirtualNode;
final class VirtualAssign extends Assign implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Isset_;
use Psalm\Node\VirtualNode;
final class VirtualIsset extends Isset_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ConstFetch;
use Psalm\Node\VirtualNode;
final class VirtualConstFetch extends ConstFetch implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ArrayItem;
use Psalm\Node\VirtualNode;
final class VirtualArrayItem extends ArrayItem implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\StaticCall;
use Psalm\Node\VirtualNode;
final class VirtualStaticCall extends StaticCall implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\MethodCall;
use Psalm\Node\VirtualNode;
final class VirtualMethodCall extends MethodCall implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Variable;
use Psalm\Node\VirtualNode;
final class VirtualVariable extends Variable implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\NullsafePropertyFetch;
use Psalm\Node\VirtualNode;
final class VirtualNullsafePropertyFetch extends NullsafePropertyFetch implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\BooleanNot;
use Psalm\Node\VirtualNode;
final class VirtualBooleanNot extends BooleanNot implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Ternary;
use Psalm\Node\VirtualNode;
final class VirtualTernary extends Ternary implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PostInc;
use Psalm\Node\VirtualNode;
final class VirtualPostInc extends PostInc implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ShellExec;
use Psalm\Node\VirtualNode;
final class VirtualShellExec extends ShellExec implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\BitwiseXor;
use Psalm\Node\VirtualNode;
final class VirtualBitwiseXor extends BitwiseXor implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Mul;
use Psalm\Node\VirtualNode;
final class VirtualMul extends Mul implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Mod;
use Psalm\Node\VirtualNode;
final class VirtualMod extends Mod implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Coalesce;
use Psalm\Node\VirtualNode;
final class VirtualCoalesce extends Coalesce implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Minus;
use Psalm\Node\VirtualNode;
final class VirtualMinus extends Minus implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\BitwiseAnd;
use Psalm\Node\VirtualNode;
final class VirtualBitwiseAnd extends BitwiseAnd implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\ShiftLeft;
use Psalm\Node\VirtualNode;
final class VirtualShiftLeft extends ShiftLeft implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Plus;
use Psalm\Node\VirtualNode;
final class VirtualPlus extends Plus implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\BitwiseOr;
use Psalm\Node\VirtualNode;
final class VirtualBitwiseOr extends BitwiseOr implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Pow;
use Psalm\Node\VirtualNode;
final class VirtualPow extends Pow implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Concat;
use Psalm\Node\VirtualNode;
final class VirtualConcat extends Concat implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\Div;
use Psalm\Node\VirtualNode;
final class VirtualDiv extends Div implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\AssignOp;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\AssignOp\ShiftRight;
use Psalm\Node\VirtualNode;
final class VirtualShiftRight extends ShiftRight implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Include_;
use Psalm\Node\VirtualNode;
final class VirtualInclude extends Include_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\Array_;
use Psalm\Node\VirtualNode;
final class VirtualArray extends Array_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\Unset_;
use Psalm\Node\VirtualNode;
final class VirtualUnset extends Unset_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\Int_;
use Psalm\Node\VirtualNode;
final class VirtualInt extends Int_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\Bool_;
use Psalm\Node\VirtualNode;
final class VirtualBool extends Bool_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\Object_;
use Psalm\Node\VirtualNode;
final class VirtualObject extends Object_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\Double;
use Psalm\Node\VirtualNode;
final class VirtualDouble extends Double implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr\Cast;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Cast\String_;
use Psalm\Node\VirtualNode;
final class VirtualString extends String_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Print_;
use Psalm\Node\VirtualNode;
final class VirtualPrint extends Print_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Clone_;
use Psalm\Node\VirtualNode;
final class VirtualClone extends Clone_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ClassConstFetch;
use Psalm\Node\VirtualNode;
final class VirtualClassConstFetch extends ClassConstFetch implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Exit_;
use Psalm\Node\VirtualNode;
final class VirtualExit extends Exit_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\ArrowFunction;
use Psalm\Node\VirtualNode;
final class VirtualArrowFunction extends ArrowFunction implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\Closure;
use Psalm\Node\VirtualNode;
final class VirtualClosure extends Closure implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Expr;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Expr\PropertyFetch;
use Psalm\Node\VirtualNode;
final class VirtualPropertyFetch extends PropertyFetch implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Name;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name\Relative;
use Psalm\Node\VirtualNode;
final class VirtualRelative extends Relative implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Name;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Name\FullyQualified;
use Psalm\Node\VirtualNode;
final class VirtualFullyQualified extends FullyQualified implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Const_;
final class VirtualConst extends Const_ implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\PropertyProperty;
use Psalm\Node\VirtualNode;
final class VirtualPropertyProperty extends PropertyProperty implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\For_;
use Psalm\Node\VirtualNode;
final class VirtualFor extends For_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Class_;
use Psalm\Node\VirtualNode;
final class VirtualClass extends Class_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Foreach_;
use Psalm\Node\VirtualNode;
final class VirtualForeach extends Foreach_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Unset_;
use Psalm\Node\VirtualNode;
final class VirtualUnset extends Unset_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Echo_;
use Psalm\Node\VirtualNode;
final class VirtualEcho extends Echo_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt\TraitUseAdaptation;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\TraitUseAdaptation\Precedence;
use Psalm\Node\VirtualNode;
final class VirtualPrecedence extends Precedence implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt\TraitUseAdaptation;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\TraitUseAdaptation\Alias;
use Psalm\Node\VirtualNode;
final class VirtualAlias extends Alias implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Interface_;
use Psalm\Node\VirtualNode;
final class VirtualInterface extends Interface_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Continue_;
use Psalm\Node\VirtualNode;
final class VirtualContinue extends Continue_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Case_;
use Psalm\Node\VirtualNode;
final class VirtualCase extends Case_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Catch_;
use Psalm\Node\VirtualNode;
final class VirtualCatch extends Catch_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\UseUse;
use Psalm\Node\VirtualNode;
final class VirtualUseUse extends UseUse implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Finally_;
use Psalm\Node\VirtualNode;
final class VirtualFinally extends Finally_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\GroupUse;
use Psalm\Node\VirtualNode;
final class VirtualGroupUse extends GroupUse implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Switch_;
use Psalm\Node\VirtualNode;
final class VirtualSwitch extends Switch_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Expression;
use Psalm\Node\VirtualNode;
/**
 * Represents statements of type "expr;"
 */
final class VirtualExpression extends Expression implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Break_;
use Psalm\Node\VirtualNode;
final class VirtualBreak extends Break_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Namespace_;
use Psalm\Node\VirtualNode;
final class VirtualNamespace extends Namespace_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\While_;
use Psalm\Node\VirtualNode;
final class VirtualWhile extends While_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Throw_;
use Psalm\Node\VirtualNode;
final class VirtualThrow extends Throw_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Label;
use Psalm\Node\VirtualNode;
final class VirtualLabel extends Label implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\HaltCompiler;
use Psalm\Node\VirtualNode;
final class VirtualHaltCompiler extends HaltCompiler implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Function_;
use Psalm\Node\VirtualNode;
final class VirtualFunction extends Function_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\TraitUse;
use Psalm\Node\VirtualNode;
final class VirtualTraitUse extends TraitUse implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\DeclareDeclare;
use Psalm\Node\VirtualNode;
final class VirtualDeclareDeclare extends DeclareDeclare implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Declare_;
use Psalm\Node\VirtualNode;
final class VirtualDeclare extends Declare_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Property;
use Psalm\Node\VirtualNode;
final class VirtualProperty extends Property implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ElseIf_;
use Psalm\Node\VirtualNode;
final class VirtualElseIf extends ElseIf_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Static_;
use Psalm\Node\VirtualNode;
final class VirtualStatic extends Static_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Goto_;
use Psalm\Node\VirtualNode;
final class VirtualGoto extends Goto_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Do_;
use Psalm\Node\VirtualNode;
final class VirtualDo extends Do_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\StaticVar;
use Psalm\Node\VirtualNode;
final class VirtualStaticVar extends StaticVar implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Return_;
use Psalm\Node\VirtualNode;
final class VirtualReturn extends Return_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\If_;
use Psalm\Node\VirtualNode;
final class VirtualIf extends If_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Nop;
use Psalm\Node\VirtualNode;
/** Nop/empty statement (;). */
final class VirtualNop extends Nop implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassConst;
use Psalm\Node\VirtualNode;
final class VirtualClassConst extends ClassConst implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\InlineHTML;
use Psalm\Node\VirtualNode;
final class VirtualInlineHTML extends InlineHTML implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\TryCatch;
use Psalm\Node\VirtualNode;
final class VirtualTryCatch extends TryCatch implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Else_;
use Psalm\Node\VirtualNode;
final class VirtualElse extends Else_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Const_;
use Psalm\Node\VirtualNode;
final class VirtualConst extends Const_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Global_;
use Psalm\Node\VirtualNode;
final class VirtualGlobal extends Global_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\ClassMethod;
use Psalm\Node\VirtualNode;
final class VirtualClassMethod extends ClassMethod implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Trait_;
use Psalm\Node\VirtualNode;
final class VirtualTrait extends Trait_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node\Stmt;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Stmt\Use_;
use Psalm\Node\VirtualNode;
final class VirtualUse extends Use_ implements VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Param;
final class VirtualParam extends Param implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Identifier;
/**
 * Represents a non-namespaced name. Namespaced names are represented using Name nodes.
 */
final class VirtualIdentifier extends Identifier implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\Attribute;
final class VirtualAttribute extends Attribute implements \Psalm\Node\VirtualNode
{
}
<?php

declare (strict_types=1);
namespace Psalm\Node;

use _HumbugBox1cb33d1f20f1\PhpParser\Node\UnionType;
final class VirtualUnionType extends UnionType implements \Psalm\Node\VirtualNode
{
}
<?php

namespace Psalm;

use _HumbugBox1cb33d1f20f1\PhpParser\Comment\Doc;
use Psalm\Exception\DocblockParseException;
use Psalm\Internal\Scanner\DocblockParser;
use Psalm\Internal\Scanner\ParsedDocblock;
use function explode;
use function in_array;
use function preg_match;
use function strlen;
use function strpos;
use function strspn;
use function substr;
use function trim;
final class DocComment
{
    public const PSALM_ANNOTATIONS = ['return', 'param', 'template', 'var', 'type', 'template-covariant', 'property', 'property-read', 'property-write', 'method', 'assert', 'assert-if-true', 'assert-if-false', 'suppress', 'ignore-nullable-return', 'override-property-visibility', 'override-method-visibility', 'seal-properties', 'seal-methods', 'ignore-falsable-return', 'variadic', 'pure', 'ignore-variable-method', 'ignore-variable-property', 'internal', 'taint-sink', 'taint-source', 'assert-untainted', 'scope-this', 'mutation-free', 'external-mutation-free', 'immutable', 'readonly', 'allow-private-mutation', 'readonly-allow-private-mutation', 'yield', 'trace', 'import-type', 'flow', 'taint-specialize', 'taint-escape', 'taint-unescape', 'self-out', 'consistent-constructor', 'stub-override', 'require-extends', 'require-implements', 'param-out', 'ignore-var', 'consistent-templates', 'if-this-is', 'this-out', 'check-type', 'check-type-exact', 'api'];
    /**
     * Parse a docblock comment into its parts.
     */
    public static function parsePreservingLength(Doc $docblock) : ParsedDocblock
    {
        $parsed_docblock = DocblockParser::parse($docblock->getText(), $docblock->getStartFilePos());
        foreach ($parsed_docblock->tags as $special_key => $_) {
            if (strpos($special_key, 'psalm-') === 0) {
                $special_key = substr($special_key, 6);
                if (!in_array($special_key, self::PSALM_ANNOTATIONS, \true)) {
                    throw new DocblockParseException('Unrecognised annotation @psalm-' . $special_key);
                }
            }
        }
        return $parsed_docblock;
    }
    /**
     * @psalm-pure
     * @return array<int,string>
     */
    public static function parseSuppressList(string $suppress_entry) : array
    {
        preg_match('/
                (?(DEFINE)
                    # either a single issue or comma separated list of issues
                    (?<issue_list> (?&issue) \\s* , \\s* (?&issue_list) | (?&issue) )

                    # definition of a single issue
                    (?<issue> [A-Za-z0-9_-]+ )
                )
                ^ (?P<issues> (?&issue_list) ) (?P<description> .* ) $
            /xm', $suppress_entry, $matches);
        if (!isset($matches['issues'])) {
            return [];
        }
        $issue_offset = 0;
        $ret = [];
        foreach (explode(',', $matches['issues']) as $suppressed_issue) {
            $issue_offset += strspn($suppressed_issue, "\t\n\f\r ");
            $ret[$issue_offset] = trim($suppressed_issue);
            $issue_offset += strlen($suppressed_issue) + 1;
        }
        return $ret;
    }
}
<?php

namespace Psalm;

use Psalm\Internal\Analyzer\ClassLikeAnalyzer;
use Psalm\Internal\Scanner\FileScanner;
use Psalm\Plugin\PluginEntryPointInterface;
use Psalm\Plugin\RegistrationInterface;
use SimpleXMLElement;
use UnexpectedValueException;
use function assert;
use function class_exists;
use function reset;
use function str_replace;
use const DIRECTORY_SEPARATOR;
/** @internal */
final class FileBasedPluginAdapter implements PluginEntryPointInterface
{
    private string $path;
    private \Psalm\Codebase $codebase;
    private \Psalm\Config $config;
    public function __construct(string $path, \Psalm\Config $config, \Psalm\Codebase $codebase)
    {
        if (!$path) {
            throw new UnexpectedValueException('$path cannot be empty');
        }
        $this->path = $path;
        $this->config = $config;
        $this->codebase = $codebase;
    }
    public function __invoke(RegistrationInterface $registration, ?SimpleXMLElement $config = null) : void
    {
        $fq_class_name = $this->getPluginClassForPath($this->path);
        /** @psalm-suppress UnresolvableInclude */
        require_once $this->path;
        assert(class_exists($fq_class_name));
        $registration->registerHooksFromClass($fq_class_name);
    }
    private function getPluginClassForPath(string $path) : string
    {
        $codebase = $this->codebase;
        $path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
        $file_storage = $codebase->createFileStorageForPath($path);
        $file_to_scan = new FileScanner($path, $this->config->shortenFileName($path), \true);
        $file_to_scan->scan($codebase, $file_storage);
        $declared_classes = ClassLikeAnalyzer::getClassesForFile($codebase, $path);
        return reset($declared_classes);
    }
}
<?php

namespace Psalm;

use InvalidArgumentException;
use LogicException;
use Psalm\Internal\Analyzer\ProjectAnalyzer;
use Psalm\Internal\Type\Comparator\AtomicTypeComparator;
use Psalm\Internal\Type\Comparator\UnionTypeComparator;
use Psalm\Internal\Type\TypeCombiner;
use Psalm\Internal\Type\TypeParser;
use Psalm\Internal\Type\TypeTokenizer;
use Psalm\Plugin\EventHandler\Event\StringInterpreterEvent;
use Psalm\Type\Atomic;
use Psalm\Type\Atomic\TArray;
use Psalm\Type\Atomic\TArrayKey;
use Psalm\Type\Atomic\TBool;
use Psalm\Type\Atomic\TClassString;
use Psalm\Type\Atomic\TClosure;
use Psalm\Type\Atomic\TFalse;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TIterable;
use Psalm\Type\Atomic\TKeyedArray;
use Psalm\Type\Atomic\TLiteralClassString;
use Psalm\Type\Atomic\TLiteralFloat;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TLiteralString;
use Psalm\Type\Atomic\TLowercaseString;
use Psalm\Type\Atomic\TMixed;
use Psalm\Type\Atomic\TNamedObject;
use Psalm\Type\Atomic\TNever;
use Psalm\Type\Atomic\TNonEmptyLowercaseString;
use Psalm\Type\Atomic\TNonEmptyString;
use Psalm\Type\Atomic\TNonFalsyString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TObject;
use Psalm\Type\Atomic\TObjectWithProperties;
use Psalm\Type\Atomic\TResource;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TSingleLetter;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Atomic\TVoid;
use Psalm\Type\MutableUnion;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_merge;
use function array_pop;
use function array_shift;
use function array_values;
use function explode;
use function get_class;
use function implode;
use function preg_quote;
use function preg_replace;
use function stripos;
use function strlen;
use function strpos;
use function strtolower;
use function substr;
abstract class Type
{
    /**
     * Parses a string type representation
     *
     * @param  array{int,int}|null   $php_version
     * @param  array<string, array<string, Union>> $template_type_map
     */
    public static function parseString(string $type_string, ?int $analysis_php_version_id = null, array $template_type_map = []) : Union
    {
        return TypeParser::parseTokens(TypeTokenizer::tokenize($type_string), $analysis_php_version_id, $template_type_map);
    }
    public static function getFQCLNFromString(string $class, \Psalm\Aliases $aliases) : string
    {
        if ($class === '') {
            throw new InvalidArgumentException('$class cannot be empty');
        }
        if ($class[0] === '\\') {
            return substr($class, 1);
        }
        $imported_namespaces = $aliases->uses;
        if (strpos($class, '\\') !== \false) {
            $class_parts = explode('\\', $class);
            $first_namespace = array_shift($class_parts);
            if (isset($imported_namespaces[strtolower($first_namespace)])) {
                return $imported_namespaces[strtolower($first_namespace)] . '\\' . implode('\\', $class_parts);
            }
        } elseif (isset($imported_namespaces[strtolower($class)])) {
            return $imported_namespaces[strtolower($class)];
        }
        $namespace = $aliases->namespace;
        return ($namespace ? $namespace . '\\' : '') . $class;
    }
    /**
     * @param array<lowercase-string, string> $aliased_classes
     * @psalm-pure
     */
    public static function getStringFromFQCLN(string $value, ?string $namespace, array $aliased_classes, ?string $this_class, bool $allow_self = \false, bool $is_static = \false) : string
    {
        if ($allow_self && $value === $this_class) {
            if ($is_static) {
                return 'static';
            }
            return 'self';
        }
        if (isset($aliased_classes[strtolower($value)])) {
            return $aliased_classes[strtolower($value)];
        }
        if ($namespace && stripos($value, $namespace . '\\') === 0) {
            $candidate = preg_replace('/^' . preg_quote($namespace . '\\') . '/i', '', $value);
            $candidate_parts = explode('\\', $candidate);
            if (!isset($aliased_classes[strtolower($candidate_parts[0])])) {
                return $candidate;
            }
        } elseif (!$namespace && strpos($value, '\\') === \false) {
            return $value;
        }
        if (strpos($value, '\\')) {
            $parts = explode('\\', $value);
            $suffix = array_pop($parts);
            while ($parts) {
                $left = implode('\\', $parts);
                if (isset($aliased_classes[strtolower($left)])) {
                    return $aliased_classes[strtolower($left)] . '\\' . $suffix;
                }
                $suffix = array_pop($parts) . '\\' . $suffix;
            }
        }
        return '\\' . $value;
    }
    /**
     * @psalm-pure
     */
    public static function getInt(bool $from_calculation = \false, ?int $value = null) : Union
    {
        if ($value !== null) {
            return new Union([new TLiteralInt($value)], ['from_calculation' => $from_calculation]);
        }
        return new Union([new TInt()], ['from_calculation' => $from_calculation]);
    }
    /**
     * @psalm-pure
     */
    public static function getLowercaseString() : Union
    {
        $type = new TLowercaseString();
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getNonEmptyLowercaseString() : Union
    {
        $type = new TNonEmptyLowercaseString();
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getNonEmptyString() : Union
    {
        $type = new TNonEmptyString();
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getNonFalsyString() : Union
    {
        $type = new TNonFalsyString();
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getNumeric() : Union
    {
        $type = new TNumeric();
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getNumericString() : Union
    {
        $type = new TNumericString();
        return new Union([$type]);
    }
    public static function getString(?string $value = null) : Union
    {
        $type = null;
        if ($value !== null) {
            $config = \Psalm\Config::getInstance();
            $event = new StringInterpreterEvent($value, ProjectAnalyzer::getInstance()->getCodebase());
            $type = $config->eventDispatcher->dispatchStringInterpreter($event);
            if (!$type) {
                if (strlen($value) < $config->max_string_length) {
                    $type = new TLiteralString($value);
                } else {
                    $type = new TNonEmptyString();
                }
            }
        }
        if (!$type) {
            $type = new TString();
        }
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getSingleLetter() : Union
    {
        $type = new TSingleLetter();
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getClassString(string $extends = 'object') : Union
    {
        return new Union([new TClassString($extends, $extends === 'object' ? null : new TNamedObject($extends))]);
    }
    /**
     * @psalm-pure
     */
    public static function getLiteralClassString(string $class_type, bool $definite_class = \false) : Union
    {
        $type = new TLiteralClassString($class_type, $definite_class);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getNull(bool $from_docblock = \false) : Union
    {
        $type = new TNull($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getMixed(bool $from_loop_isset = \false, bool $from_docblock = \false) : Union
    {
        $type = new TMixed($from_loop_isset, $from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getScalar(bool $from_docblock = \false) : Union
    {
        $type = new TScalar($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getNever(bool $from_docblock = \false) : Union
    {
        $type = new TNever($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getBool(bool $from_docblock = \false) : Union
    {
        $type = new TBool($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getFloat(?float $value = null, bool $from_docblock = \false) : Union
    {
        if ($value !== null) {
            $type = new TLiteralFloat($value, $from_docblock);
        } else {
            $type = new TFloat($from_docblock);
        }
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getObject() : Union
    {
        $type = new TObject();
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getClosure() : Union
    {
        $type = new TClosure('Closure');
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getArrayKey(bool $from_docblock = \false) : Union
    {
        $type = new TArrayKey($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getArray() : Union
    {
        $type = new TArray([new Union([new TArrayKey()]), new Union([new TMixed()])]);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getEmptyArray() : Union
    {
        return new Union([self::getEmptyArrayAtomic()]);
    }
    /**
     * @psalm-pure
     */
    public static function getEmptyArrayAtomic() : TArray
    {
        return new TArray([new Union([new TNever()]), new Union([new TNever()])]);
    }
    /**
     * @psalm-pure
     */
    public static function getList(?Union $of = null, bool $from_docblock = \false) : Union
    {
        return new Union([self::getListAtomic($of ?? self::getMixed($from_docblock), $from_docblock)]);
    }
    /**
     * @psalm-pure
     */
    public static function getNonEmptyList(?Union $of = null, bool $from_docblock = \false) : Union
    {
        return new Union([self::getNonEmptyListAtomic($of ?? self::getMixed($from_docblock), $from_docblock)]);
    }
    /**
     * @psalm-pure
     */
    public static function getListAtomic(Union $of, bool $from_docblock = \false) : TKeyedArray
    {
        return new TKeyedArray([$of->setPossiblyUndefined(\true)], null, [self::getListKey(), $of], \true, $from_docblock);
    }
    /**
     * @psalm-pure
     */
    public static function getNonEmptyListAtomic(Union $of, bool $from_docblock = \false) : TKeyedArray
    {
        return new TKeyedArray([$of->setPossiblyUndefined(\false)], null, [self::getListKey(), $of], \true, $from_docblock);
    }
    private static ?Union $listKey = null;
    /**
     * @psalm-pure
     */
    public static function getListKey() : Union
    {
        return self::$listKey ??= new Union([new TIntRange(0, null)]);
    }
    /**
     * @psalm-pure
     */
    public static function getVoid(bool $from_docblock = \false) : Union
    {
        $type = new TVoid($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getFalse(bool $from_docblock = \false) : Union
    {
        $type = new TFalse($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getTrue(bool $from_docblock = \false) : Union
    {
        $type = new TTrue($from_docblock);
        return new Union([$type]);
    }
    /**
     * @psalm-pure
     */
    public static function getResource(bool $from_docblock = \false) : Union
    {
        return new Union([new TResource($from_docblock)]);
    }
    /**
     * @psalm-external-mutation-free
     * @param non-empty-list<Union> $union_types
     */
    public static function combineUnionTypeArray(array $union_types, ?\Psalm\Codebase $codebase) : Union
    {
        $first_type = array_pop($union_types);
        foreach ($union_types as $type) {
            $first_type = self::combineUnionTypes($first_type, $type, $codebase);
        }
        return $first_type;
    }
    /**
     * Combines two union types into one
     *
     * @param  int    $literal_limit any greater number of literal types than this
     *                               will be merged to a scalar
     * @psalm-external-mutation-free
     * @psalm-suppress ImpurePropertyAssignment We're not mutating external instances
     * @psalm-suppress InaccessibleProperty We're not mutating external instances
     */
    public static function combineUnionTypes(?Union $type_1, ?Union $type_2, ?\Psalm\Codebase $codebase = null, bool $overwrite_empty_array = \false, bool $allow_mixed_union = \true, int $literal_limit = 500, ?bool $possibly_undefined = null) : Union
    {
        if ($type_2 === null && $type_1 === null) {
            throw new UnexpectedValueException('At least one type must be provided to combine');
        }
        if ($type_1 === null) {
            if ($possibly_undefined !== null) {
                return $type_2->setPossiblyUndefined($possibly_undefined);
            }
            return $type_2;
        }
        if ($type_2 === null) {
            if ($possibly_undefined !== null) {
                return $type_1->setPossiblyUndefined($possibly_undefined);
            }
            return $type_1;
        }
        if ($type_1 === $type_2) {
            if ($possibly_undefined !== null) {
                return $type_1->setPossiblyUndefined($possibly_undefined);
            }
            return $type_1;
        }
        if ($type_1->isVanillaMixed() && $type_2->isVanillaMixed()) {
            $combined_type = self::getMixed();
        } else {
            $both_failed_reconciliation = \false;
            if ($type_1->failed_reconciliation) {
                if ($type_2->failed_reconciliation) {
                    $both_failed_reconciliation = \true;
                } else {
                    return $type_2->setProperties(['parent_nodes' => array_merge($type_2->parent_nodes, $type_1->parent_nodes), 'possibly_undefined' => $possibly_undefined ?? $type_2->possibly_undefined]);
                }
            } elseif ($type_2->failed_reconciliation) {
                return $type_1->setProperties(['parent_nodes' => array_merge($type_1->parent_nodes, $type_2->parent_nodes), 'possibly_undefined' => $possibly_undefined ?? $type_1->possibly_undefined]);
            }
            $combined_type = TypeCombiner::combine(array_merge(array_values($type_1->getAtomicTypes()), array_values($type_2->getAtomicTypes())), $codebase, $overwrite_empty_array, $allow_mixed_union, $literal_limit);
            if (!$type_1->initialized || !$type_2->initialized) {
                $combined_type->initialized = \false;
            }
            if ($type_1->from_docblock || $type_2->from_docblock) {
                $combined_type->from_docblock = \true;
            }
            if ($type_1->from_calculation || $type_2->from_calculation) {
                $combined_type->from_calculation = \true;
            }
            if ($type_1->ignore_nullable_issues || $type_2->ignore_nullable_issues) {
                $combined_type->ignore_nullable_issues = \true;
            }
            if ($type_1->ignore_falsable_issues || $type_2->ignore_falsable_issues) {
                $combined_type->ignore_falsable_issues = \true;
            }
            if ($type_1->explicit_never || $type_2->explicit_never) {
                $combined_type->explicit_never = \true;
            }
            if ($type_1->had_template && $type_2->had_template) {
                $combined_type->had_template = \true;
            }
            if ($type_1->reference_free && $type_2->reference_free) {
                $combined_type->reference_free = \true;
            }
            if ($both_failed_reconciliation) {
                $combined_type->failed_reconciliation = \true;
            }
        }
        if ($possibly_undefined !== null) {
            $combined_type->possibly_undefined = $possibly_undefined;
        } elseif ($type_1->possibly_undefined || $type_2->possibly_undefined) {
            $combined_type->possibly_undefined = \true;
        }
        if ($type_1->possibly_undefined_from_try || $type_2->possibly_undefined_from_try) {
            $combined_type->possibly_undefined_from_try = \true;
        }
        if ($type_1->parent_nodes || $type_2->parent_nodes) {
            $combined_type->parent_nodes = $type_1->parent_nodes + $type_2->parent_nodes;
        }
        if ($type_1->by_ref || $type_2->by_ref) {
            $combined_type->by_ref = \true;
        }
        return $combined_type;
    }
    /**
     * Combines two union types into one via an intersection
     */
    public static function intersectUnionTypes(?Union $type_1, ?Union $type_2, \Psalm\Codebase $codebase) : ?Union
    {
        if ($type_2 === null && $type_1 === null) {
            throw new UnexpectedValueException('At least one type must be provided to combine');
        }
        if ($type_1 === null) {
            return $type_2;
        }
        if ($type_2 === null) {
            return $type_1;
        }
        if ($type_1 === $type_2) {
            return $type_1;
        }
        $intersection_performed = \false;
        $type_1_mixed = $type_1->isMixed();
        $type_2_mixed = $type_2->isMixed();
        $possibly_undefined = $type_1->possibly_undefined && $type_2->possibly_undefined;
        if ($type_1_mixed && $type_2_mixed) {
            $combined_type = new Union([new TMixed()], ['possibly_undefined' => $possibly_undefined]);
        } else {
            $both_failed_reconciliation = \false;
            if ($type_1->failed_reconciliation) {
                if ($type_2->failed_reconciliation) {
                    $both_failed_reconciliation = \true;
                } else {
                    return $type_2;
                }
            } elseif ($type_2->failed_reconciliation) {
                return $type_1;
            }
            if ($type_1_mixed) {
                $combined_type = $type_2->getBuilder();
                $intersection_performed = \true;
            } elseif ($type_2_mixed) {
                $combined_type = $type_1->getBuilder();
                $intersection_performed = \true;
            } else {
                $combined_type = null;
                foreach ($type_1->getAtomicTypes() as $type_1_atomic) {
                    foreach ($type_2->getAtomicTypes() as $type_2_atomic) {
                        $intersection_atomic = self::intersectAtomicTypes($type_1_atomic, $type_2_atomic, $codebase, $intersection_performed);
                        if (null !== $intersection_atomic) {
                            if (null === $combined_type) {
                                $combined_type = new MutableUnion([$intersection_atomic]);
                            } else {
                                $combined_type->addType($intersection_atomic);
                            }
                        }
                    }
                }
            }
            //if a type is contained by the other, the intersection is the narrowest type
            if (!$intersection_performed) {
                $type_1_in_2 = UnionTypeComparator::isContainedBy($codebase, $type_1, $type_2);
                $type_2_in_1 = UnionTypeComparator::isContainedBy($codebase, $type_2, $type_1);
                if ($type_1_in_2) {
                    $intersection_performed = \true;
                    $combined_type = $type_1->getBuilder();
                } elseif ($type_2_in_1) {
                    $intersection_performed = \true;
                    $combined_type = $type_2->getBuilder();
                }
            }
            if ($combined_type !== null) {
                if (!$type_1->initialized && !$type_2->initialized) {
                    $combined_type->initialized = \false;
                }
                if ($type_1->possibly_undefined_from_try && $type_2->possibly_undefined_from_try) {
                    $combined_type->possibly_undefined_from_try = \true;
                }
                if ($type_1->from_docblock && $type_2->from_docblock) {
                    $combined_type->from_docblock = \true;
                }
                if ($type_1->from_calculation && $type_2->from_calculation) {
                    $combined_type->from_calculation = \true;
                }
                if ($type_1->ignore_nullable_issues && $type_2->ignore_nullable_issues) {
                    $combined_type->ignore_nullable_issues = \true;
                }
                if ($type_1->ignore_falsable_issues && $type_2->ignore_falsable_issues) {
                    $combined_type->ignore_falsable_issues = \true;
                }
                if ($both_failed_reconciliation) {
                    $combined_type->failed_reconciliation = \true;
                }
                $combined_type->possibly_undefined = $possibly_undefined;
                $combined_type = $combined_type->freeze();
            }
        }
        if (!$intersection_performed && $type_1->getId() !== $type_2->getId()) {
            return null;
        }
        return $combined_type;
    }
    private static function intersectAtomicTypes(Atomic $type_1_atomic, Atomic $type_2_atomic, \Psalm\Codebase $codebase, bool &$intersection_performed) : ?Atomic
    {
        $intersection_atomic = null;
        $wider_type = null;
        if ($type_1_atomic instanceof TNamedObject && $type_2_atomic instanceof TNamedObject) {
            if ($type_1_atomic->value === $type_2_atomic->value && get_class($type_1_atomic) === TNamedObject::class && get_class($type_2_atomic) !== TNamedObject::class) {
                $intersection_atomic = $type_2_atomic;
                $wider_type = $type_1_atomic;
                $intersection_performed = \true;
            } elseif ($type_1_atomic->value === $type_2_atomic->value && get_class($type_2_atomic) === TNamedObject::class && get_class($type_1_atomic) !== TNamedObject::class) {
                $intersection_atomic = $type_1_atomic;
                $wider_type = $type_2_atomic;
                $intersection_performed = \true;
            }
        }
        if ($type_1_atomic instanceof TInt && $type_2_atomic instanceof TInt) {
            $int_intersection = TIntRange::intersectIntRanges(TIntRange::convertToIntRange($type_1_atomic), TIntRange::convertToIntRange($type_2_atomic));
            if ($int_intersection && ($int_intersection->min_bound !== null || $int_intersection->max_bound !== null)) {
                $intersection_performed = \true;
                if ($int_intersection->min_bound !== null && $int_intersection->min_bound === $int_intersection->max_bound) {
                    return new TLiteralInt($int_intersection->min_bound);
                }
                return $int_intersection;
            }
        }
        if (null === $intersection_atomic) {
            if (AtomicTypeComparator::isContainedBy($codebase, $type_2_atomic, $type_1_atomic)) {
                $intersection_atomic = $type_2_atomic;
                $wider_type = $type_1_atomic;
                $intersection_performed = \true;
            } elseif (AtomicTypeComparator::isContainedBy($codebase, $type_1_atomic, $type_2_atomic)) {
                $intersection_atomic = $type_1_atomic;
                $wider_type = $type_2_atomic;
                $intersection_performed = \true;
            }
            if ($intersection_atomic && !self::hasIntersection($type_1_atomic) && !self::hasIntersection($type_2_atomic)) {
                return $intersection_atomic;
            }
        }
        if (self::mayHaveIntersection($type_1_atomic, $codebase) && self::mayHaveIntersection($type_2_atomic, $codebase)) {
            /** @psalm-suppress TypeDoesNotContainType */
            if ($type_1_atomic instanceof TNamedObject && $type_2_atomic instanceof TNamedObject) {
                try {
                    $first = $codebase->classlike_storage_provider->get($type_1_atomic->value);
                    $second = $codebase->classlike_storage_provider->get($type_2_atomic->value);
                    $first_is_class = !$first->is_interface && !$first->is_trait;
                    $second_is_class = !$second->is_interface && !$second->is_trait;
                    if ($first_is_class && $second_is_class) {
                        return $intersection_atomic;
                    }
                } catch (InvalidArgumentException $e) {
                    // Ignore non-existing classes during initial scan
                }
            }
            if ($intersection_atomic === null && $wider_type === null) {
                $intersection_atomic = $type_1_atomic;
                $wider_type = $type_2_atomic;
            }
            if ($intersection_atomic === null || $wider_type === null) {
                throw new LogicException('$intersection_atomic and $wider_type should be both set or null.' . ' Check the preceding code for errors.' . ' Did you forget to assign one of the variables?');
            }
            if (!self::mayHaveIntersection($intersection_atomic, $codebase) || !self::mayHaveIntersection($wider_type, $codebase)) {
                throw new LogicException('$intersection_atomic and $wider_type should be both support intersection.' . ' Check the preceding code for errors.');
            }
            $intersection_performed = \true;
            $wider_type_clone = $wider_type->setIntersectionTypes([]);
            $final_intersection = array_merge([$wider_type_clone->getKey() => $wider_type_clone], $intersection_atomic->getIntersectionTypes());
            $wider_type_intersection_types = $wider_type->getIntersectionTypes();
            foreach ($wider_type_intersection_types as $wider_type_intersection_type) {
                $final_intersection[$wider_type_intersection_type->getKey()] = $wider_type_intersection_type;
            }
            return $intersection_atomic->setIntersectionTypes($final_intersection);
        }
        return $intersection_atomic;
    }
    /**
     * @psalm-assert-if-true TIterable|TNamedObject|TTemplateParam|TObjectWithProperties $type
     */
    private static function mayHaveIntersection(Atomic $type, \Psalm\Codebase $codebase) : bool
    {
        if ($type instanceof TIterable || $type instanceof TTemplateParam || $type instanceof TObjectWithProperties) {
            return \true;
        }
        if (!$type instanceof TNamedObject) {
            return \false;
        }
        try {
            $storage = $codebase->classlike_storage_provider->get($type->value);
        } catch (InvalidArgumentException $e) {
            // Ignore non-existing classes during initial scan
            return \true;
        }
        return !$storage->final;
    }
    private static function hasIntersection(Atomic $type) : bool
    {
        return ($type instanceof TIterable || $type instanceof TNamedObject || $type instanceof TTemplateParam || $type instanceof TObjectWithProperties) && $type->extra_types;
    }
}
<?php

namespace Psalm;

use Psalm\Internal\Cli\Psalm;
require_once __DIR__ . '/src/Psalm/Internal/Cli/Psalm.php';
Psalm::run($argv);
<?php
namespace Psalm\Internal;

/**
 * Automatically created by bin/update-property-map.php
 *
 * Please do not modify - adapt the override constants in above file instead.
 */

return [
    'commonmark\\node' => [
        'endColumn' => 'int',
        'endLine' => 'int',
        'firstChild' => 'Node|null',
        'lastChild' => 'Node|null',
        'next' => 'Node|null',
        'parent' => 'Node|null',
        'previous' => 'Node|null',
        'startColumn' => 'int',
        'startLine' => 'int',
    ],
    'commonmark\\node\\bulletlist' => [
        'delimiter' => 'int',
        'tight' => 'bool',
    ],
    'commonmark\\node\\codeblock' => [
        'fence' => 'string|null',
    ],
    'commonmark\\node\\customblock' => [
        'onEnter' => 'string|null',
        'onLeave' => 'string|null',
    ],
    'commonmark\\node\\custominline' => [
        'onEnter' => 'string|null',
        'onLeave' => 'string|null',
    ],
    'commonmark\\node\\heading' => [
        'level' => 'int',
    ],
    'commonmark\\node\\image' => [
        'title' => 'string|null',
        'url' => 'string|null',
    ],
    'commonmark\\node\\link' => [
        'title' => 'string|null',
        'url' => 'string|null',
    ],
    'commonmark\\node\\orderedlist' => [
        'delimiter' => 'int',
        'start' => 'int',
        'tight' => 'bool',
    ],
    'commonmark\\node\\text' => [
        'literal' => 'string|null',
    ],
    'curlfile' => [
        'mime' => 'string',
        'name' => 'string',
        'postname' => 'string',
    ],
    'curlstringfile' => [
        'data' => 'string',
        'mime' => 'string',
        'postname' => 'string',
    ],
    'dateinterval' => [
        'd' => 'int',
        'date_string' => 'string',
        'days' => 'false|int',
        'f' => 'float',
        'from_string' => 'bool',
        'h' => 'int',
        'i' => 'int',
        'invert' => 'int',
        'm' => 'int',
        's' => 'int',
        'y' => 'int',
    ],
    'dateperiod' => [
        'current' => 'DateTimeInterface',
        'end' => 'DateTimeInterface',
        'include_start_date' => 'bool',
        'interval' => 'DateInterval',
        'recurrences' => 'int',
        'start' => 'DateTimeInterface',
    ],
    'directory' => [
        'handle' => 'resource',
        'path' => 'string',
    ],
    'domattr' => [
        'name' => 'string',
        'ownerElement' => 'DOMElement|null',
        'schemaTypeInfo' => 'mixed',
        'specified' => 'bool',
        'value' => 'string',
    ],
    'domcharacterdata' => [
        'data' => 'string',
        'length' => 'int',
        'nextElementSibling' => 'DOMElement|null',
        'previousElementSibling' => 'DOMElement|null',
    ],
    'domdocument' => [
        'actualEncoding' => 'string|null',
        'childElementCount' => 'int',
        'config' => 'mixed',
        'doctype' => 'DOMDocumentType|null',
        'documentElement' => 'DOMElement|null',
        'documentURI' => 'string|null',
        'encoding' => 'string|null',
        'firstElementChild' => 'DOMElement|null',
        'formatOutput' => 'bool',
        'implementation' => 'DOMImplementation',
        'lastElementChild' => 'DOMElement|null',
        'preserveWhiteSpace' => 'bool',
        'recover' => 'bool',
        'resolveExternals' => 'bool',
        'standalone' => 'bool',
        'strictErrorChecking' => 'bool',
        'substituteEntities' => 'bool',
        'validateOnParse' => 'bool',
        'version' => 'string|null',
        'xmlEncoding' => 'string|null',
        'xmlStandalone' => 'bool',
        'xmlVersion' => 'string|null',
    ],
    'domdocumentfragment' => [
        'childElementCount' => 'int',
        'firstelementChild' => 'DOMElement|null',
        'lastelementChild' => 'DOMElement|null',
    ],
    'domdocumenttype' => [
        'entities' => 'DOMNamedNodeMap',
        'internalsubset' => 'string|null',
        'name' => 'string',
        'notations' => 'DOMNamedNodeMap',
        'publicid' => 'string',
        'systemid' => 'string',
    ],
    'domelement' => [
        'childElementCount' => 'int',
        'firstElementChild' => 'DOMElement|null',
        'lastElementChild' => 'DOMElement|null',
        'nextElementSibling' => 'DOMElement|null',
        'previousElementSibling' => 'DOMElement|null',
        'schemaTypeInfo' => 'mixed',
        'tagName' => 'string',
    ],
    'domentity' => [
        'actualEncoding' => 'string|null',
        'encoding' => 'string|null',
        'notationName' => 'string|null',
        'publicid' => 'string|null',
        'systemid' => 'string|null',
        'version' => 'string|null',
    ],
    'domexception' => [
        'code' => 'int',
    ],
    'domnamednodemap' => [
        'length' => 'int',
    ],
    'domnode' => [
        'attributes' => 'DOMNamedNodeMap|null',
        'baseURI' => 'string|null',
        'childNodes' => 'DOMNodeList<DOMNode>',
        'firstChild' => 'DOMNode|null',
        'lastChild' => 'DOMNode|null',
        'localName' => 'string|null',
        'namespaceURI' => 'string|null',
        'nextSibling' => 'DOMNode|null',
        'nodeName' => 'string',
        'nodeType' => 'int',
        'nodeValue' => 'string|null',
        'ownerDocument' => 'DOMDocument|null',
        'parentNode' => 'DOMNode|null',
        'prefix' => 'string',
        'previousSibling' => 'DOMNode|null',
        'textContent' => 'string',
    ],
    'domnodelist' => [
        'length' => 'int',
    ],
    'domnotation' => [
        'publicId' => 'string',
        'systemId' => 'string',
    ],
    'domprocessinginstruction' => [
        'data' => 'string',
        'target' => 'string',
    ],
    'domtext' => [
        'wholeText' => 'string',
    ],
    'domxpath' => [
        'document' => 'DOMDocument',
        'registerNodeNamespaces' => 'bool',
    ],
    'errorexception' => [
        'severity' => 'int',
    ],
    'event' => [
        'pending' => 'bool',
    ],
    'eventbuffer' => [
        'contiguous_space' => 'int',
        'length' => 'int',
    ],
    'eventbufferevent' => [
        'fd' => 'int',
        'input' => 'EventBuffer',
        'output' => 'EventBuffer',
        'priority' => 'int',
    ],
    'eventlistener' => [
        'fd' => 'int',
    ],
    'eventsslcontext' => [
        'local_cert' => 'string',
        'local_pk' => 'string',
    ],
    'libxmlerror' => [
        'code' => 'int',
        'column' => 'int',
        'file' => 'string',
        'level' => 'int',
        'line' => 'int',
        'message' => 'string',
    ],
    'mongoclient' => [
        'connected' => 'boolean',
        'status' => 'string',
    ],
    'mongocollection' => [
        'db' => 'MongoDB',
        'w' => 'integer',
        'wtimeout' => 'integer',
    ],
    'mongocursor' => [
        'slaveokay' => 'boolean',
        'timeout' => 'integer',
    ],
    'mongodb' => [
        'w' => 'integer',
        'wtimeout' => 'integer',
    ],
    'mongodb\\driver\\exception\\commandexception' => [
        'resultdocument' => 'object',
    ],
    'mongodb\\driver\\exception\\runtimeexception' => [
        'errorlabels' => 'array|null',
    ],
    'mongodb\\driver\\exception\\writeexception' => [
        'writeresult' => 'MongoDB\\Driver\\WriteResult',
    ],
    'mongoid' => [
        'id' => 'string',
    ],
    'mongoint32' => [
        'value' => 'string',
    ],
    'mongoint64' => [
        'value' => 'string',
    ],
    'mysqli' => [
        'affected_rows' => 'int|string',
        'client_info' => 'string',
        'client_version' => 'int',
        'connect_errno' => 'int',
        'connect_error' => 'string|null',
        'errno' => 'int',
        'error' => 'string',
        'error_list' => 'array',
        'field_count' => 'int',
        'host_info' => 'string',
        'info' => 'string|null',
        'insert_id' => 'int|string',
        'protocol_version' => 'int',
        'server_info' => 'string',
        'server_version' => 'int',
        'sqlstate' => 'string',
        'thread_id' => 'int',
        'warning_count' => 'int',
    ],
    'mysqli_driver' => [
        'client_info' => 'string',
        'client_version' => 'int',
        'driver_version' => 'int',
        'embedded' => 'bool',
        'reconnect' => 'bool',
        'report_mode' => 'int',
    ],
    'mysqli_result' => [
        'current_field' => 'int',
        'field_count' => 'int',
        'lengths' => 'array|null',
        'num_rows' => 'int|string',
        'type' => 'int',
    ],
    'mysqli_sql_exception' => [
        'sqlstate' => 'string',
    ],
    'mysqli_stmt' => [
        'affected_rows' => 'int|string',
        'errno' => 'int',
        'error' => 'string',
        'error_list' => 'array',
        'field_count' => 'int',
        'id' => 'int',
        'insert_id' => 'int|string',
        'num_rows' => 'int|string',
        'param_count' => 'int',
        'sqlstate' => 'string',
    ],
    'mysqli_warning' => [
        'errno' => 'int',
        'message' => 'string',
        'sqlstate' => 'string',
    ],
    'parallel\\events\\event' => [
        'object' => 'object',
        'source' => 'string',
        'type' => 'int',
    ],
    'parle\\errorinfo' => [
        'id' => 'int',
        'position' => 'int',
        'token' => 'mixed',
    ],
    'parle\\lexer' => [
        'bol' => 'bool',
        'cursor' => 'int',
        'flags' => 'int',
        'marker' => 'int',
        'state' => 'int',
    ],
    'parle\\parser' => [
        'action' => 'int',
        'reduceid' => 'int',
    ],
    'parle\\rlexer' => [
        'bol' => 'bool',
        'cursor' => 'int',
        'flags' => 'int',
        'marker' => 'int',
        'state' => 'int',
    ],
    'parle\\rparser' => [
        'action' => 'int',
        'reduceid' => 'int',
    ],
    'parle\\stack' => [
        'empty' => 'bool',
        'size' => 'int',
        'top' => 'mixed',
    ],
    'parle\\token' => [
        'id' => 'int',
        'value' => 'string',
    ],
    'pdoexception' => [
        'code' => 'int|string',
        'errorInfo' => 'array|null',
    ],
    'pdostatement' => [
        'queryString' => 'string',
    ],
    'php_user_filter' => [
        'filtername' => 'string',
        'params' => 'mixed',
        'stream' => 'resource|null',
    ],
    'phpparser\\node\\expr\\array_' => [
        'items' => 'array<int, PhpParser\\Node\\Expr\\ArrayItem|null>',
    ],
    'phpparser\\node\\expr\\arrowfunction' => [
        'params' => 'list<PhpParser\\Node\\Param>',
    ],
    'phpparser\\node\\expr\\closure' => [
        'params' => 'list<PhpParser\\Node\\Param>',
    ],
    'phpparser\\node\\expr\\list_' => [
        'items' => 'array<int, PhpParser\\Node\\Expr\\ArrayItem|null>',
    ],
    'phpparser\\node\\expr\\shellexec' => [
        'parts' => 'list<PhpParser\\Node>',
    ],
    'phpparser\\node\\matcharm' => [
        'conds' => 'null|non-empty-list<PhpParser\\Node\\Expr>',
    ],
    'phpparser\\node\\name' => [
        'parts' => 'non-empty-list<non-empty-string>',
    ],
    'phpparser\\node\\stmt\\case_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\catch_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\class_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\do_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\else_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\elseif_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\finally_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\for_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\foreach_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\if_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\interface_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\namespace_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\trait_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\trycatch' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\while_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phptoken' => [
        'id' => 'int',
        'line' => 'int',
        'pos' => 'int',
        'text' => 'string',
    ],
    'rdkafka\\message' => [
        'err' => 'int',
        'headers' => 'array<string, string>|null',
        'key' => 'string|null',
        'offset' => 'int',
        'partition' => 'int',
        'payload' => 'string',
        'timestamp' => 'int',
        'topic_name' => 'string',
    ],
    'reflectionextension' => [
        'name' => 'string',
    ],
    'reflectionfunctionabstract' => [
        'name' => 'string',
    ],
    'reflectionzendextension' => [
        'name' => 'string',
    ],
    'snmp' => [
        'enum_print' => 'bool',
        'exceptions_enabled' => 'int',
        'info' => 'array',
        'max_oids' => 'int|null',
        'oid_increasing_check' => 'bool',
        'oid_output_format' => 'int',
        'quick_print' => 'bool',
        'valueretrieval' => 'int',
    ],
    'snmpexception' => [
        'code' => 'string',
    ],
    'soapclient' => [
        '__default_headers' => 'array|null',
        '__last_request' => 'string|null',
        '__last_request_headers' => 'string|null',
        '__last_response' => 'string|null',
        '__last_response_headers' => 'string|null',
        '__soap_fault' => 'SoapFault|null',
        '_classmap' => 'array|null',
        '_connection_timeout' => 'int',
        '_cookies' => 'array',
        '_digest' => 'string|null',
        '_encoding' => 'string|null',
        '_exceptions' => 'bool',
        '_features' => 'int|null',
        '_keep_alive' => 'bool',
        '_login' => 'string|null',
        '_password' => 'string|null',
        '_proxy_host' => 'string|null',
        '_proxy_login' => 'string|null',
        '_proxy_password' => 'string|null',
        '_proxy_port' => 'int|null',
        '_soap_version' => 'int',
        '_ssl_method' => 'int|null',
        '_stream_context' => 'resource|null',
        '_use_digest' => 'bool',
        '_use_proxy' => 'int|null',
        '_user_agent' => 'string|null',
        'compression' => 'int|null',
        'httpsocket' => 'resource|null',
        'httpurl' => 'resource|null',
        'location' => 'string|null',
        'sdl' => 'resource|null',
        'style' => 'int|null',
        'trace' => 'bool',
        'typemap' => 'resource|null',
        'uri' => 'string|null',
        'use' => 'int|null',
    ],
    'soapfault' => [
        '_name' => 'string|null',
        'detail' => 'mixed',
        'faultactor' => 'string|null',
        'faultcode' => 'string|null',
        'faultcodens' => 'string|null',
        'faultstring' => 'string',
        'headerfault' => 'mixed',
    ],
    'soapheader' => [
        'actor' => 'string|int|null',
        'data' => 'mixed',
        'mustUnderstand' => 'bool',
        'name' => 'string',
        'namespace' => 'string',
    ],
    'soapparam' => [
        'param_data' => 'mixed',
        'param_name' => 'string',
    ],
    'soapserver' => [
        '__soap_fault' => 'SoapFault|null',
        'service' => 'resource',
    ],
    'soapvar' => [
        'enc_name' => 'string|null',
        'enc_namens' => 'string|null',
        'enc_ns' => 'string|null',
        'enc_stype' => 'string|null',
        'enc_type' => 'int',
        'enc_value' => 'mixed',
    ],
    'solrdocumentfield' => [
        'boost' => 'float',
        'name' => 'string',
        'values' => 'array',
    ],
    'solrexception' => [
        'sourcefile' => 'string',
        'sourceline' => 'int',
        'zif_name' => 'string',
    ],
    'solrresponse' => [
        'http_digested_response' => 'string',
        'http_raw_request' => 'string',
        'http_raw_request_headers' => 'string',
        'http_raw_response' => 'string',
        'http_raw_response_headers' => 'string',
        'http_request_url' => 'string',
        'http_status' => 'int',
        'http_status_message' => 'string',
        'parser_mode' => 'int',
        'success' => 'bool',
    ],
    'streamwrapper' => [
        'context' => 'resource',
    ],
    'tidy' => [
        'errorBuffer' => 'string',
        'value' => 'string|null',
    ],
    'tidynode' => [
        'attribute' => 'array|null',
        'child' => 'array|null',
        'column' => 'int',
        'id' => 'int|null',
        'line' => 'int',
        'name' => 'string',
        'proprietary' => 'bool',
        'type' => 'int',
        'value' => 'string',
    ],
    'tokyotyrantexception' => [
        'code' => 'int',
    ],
    'transliterator' => [
        'id' => 'string',
    ],
    'xmlreader' => [
        'attributeCount' => 'int',
        'baseURI' => 'string',
        'depth' => 'int',
        'hasAttributes' => 'bool',
        'hasValue' => 'bool',
        'isDefault' => 'bool',
        'isEmptyElement' => 'bool',
        'localName' => 'string',
        'name' => 'string',
        'namespaceURI' => 'string',
        'nodeType' => 'int',
        'prefix' => 'string',
        'value' => 'string',
        'xmlLang' => 'string',
    ],
    'ziparchive' => [
        'comment' => 'string',
        'filename' => 'string',
        'lastId' => 'int',
        'numFiles' => 'int',
        'status' => 'int',
        'statusSys' => 'int',
    ],
];
<?php // phpcs:ignoreFile

/**
 * This file contains the historic state of PHP functions before version 7.1
 *
 * It is _NOT_ used by the Psalm application itself, but serves as a baseline
 * for testing the validity of the CallMap.php and CallMap_xx_delta.php files
 *
 * Updates to this file are only needed if an old function in the main callmap turns out to be incorrect
 *
 * @see tests\Internal\CallMapTest.php
 *
 * @see FunctionSignatureMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
    'AMQPBasicProperties::__construct' => ['void', 'content_type='=>'string', 'content_encoding='=>'string', 'headers='=>'array', 'delivery_mode='=>'int', 'priority='=>'int', 'correlation_id='=>'string', 'reply_to='=>'string', 'expiration='=>'string', 'message_id='=>'string', 'timestamp='=>'int', 'type='=>'string', 'user_id='=>'string', 'app_id='=>'string', 'cluster_id='=>'string'],
    'AMQPBasicProperties::getAppId' => ['string'],
    'AMQPBasicProperties::getClusterId' => ['string'],
    'AMQPBasicProperties::getContentEncoding' => ['string'],
    'AMQPBasicProperties::getContentType' => ['string'],
    'AMQPBasicProperties::getCorrelationId' => ['string'],
    'AMQPBasicProperties::getDeliveryMode' => ['int'],
    'AMQPBasicProperties::getExpiration' => ['string'],
    'AMQPBasicProperties::getHeaders' => ['array'],
    'AMQPBasicProperties::getMessageId' => ['string'],
    'AMQPBasicProperties::getPriority' => ['int'],
    'AMQPBasicProperties::getReplyTo' => ['string'],
    'AMQPBasicProperties::getTimestamp' => ['string'],
    'AMQPBasicProperties::getType' => ['string'],
    'AMQPBasicProperties::getUserId' => ['string'],
    'AMQPChannel::__construct' => ['void', 'amqp_connection'=>'AMQPConnection'],
    'AMQPChannel::basicRecover' => ['', 'requeue='=>'bool'],
    'AMQPChannel::close' => [''],
    'AMQPChannel::commitTransaction' => ['bool'],
    'AMQPChannel::confirmSelect' => [''],
    'AMQPChannel::getChannelId' => ['int'],
    'AMQPChannel::getConnection' => ['AMQPConnection'],
    'AMQPChannel::getConsumers' => ['AMQPQueue[]'],
    'AMQPChannel::getPrefetchCount' => ['int'],
    'AMQPChannel::getPrefetchSize' => ['int'],
    'AMQPChannel::isConnected' => ['bool'],
    'AMQPChannel::qos' => ['bool', 'size'=>'int', 'count'=>'int'],
    'AMQPChannel::rollbackTransaction' => ['bool'],
    'AMQPChannel::setConfirmCallback' => ['', 'ack_callback='=>'?callable', 'nack_callback='=>'?callable'],
    'AMQPChannel::setPrefetchCount' => ['bool', 'count'=>'int'],
    'AMQPChannel::setPrefetchSize' => ['bool', 'size'=>'int'],
    'AMQPChannel::setReturnCallback' => ['', 'return_callback='=>'?callable'],
    'AMQPChannel::startTransaction' => ['bool'],
    'AMQPChannel::waitForBasicReturn' => ['', 'timeout='=>'float'],
    'AMQPChannel::waitForConfirm' => ['', 'timeout='=>'float'],
    'AMQPConnection::__construct' => ['void', 'credentials='=>'array'],
    'AMQPConnection::connect' => ['bool'],
    'AMQPConnection::disconnect' => ['bool'],
    'AMQPConnection::getCACert' => ['string'],
    'AMQPConnection::getCert' => ['string'],
    'AMQPConnection::getHeartbeatInterval' => ['int'],
    'AMQPConnection::getHost' => ['string'],
    'AMQPConnection::getKey' => ['string'],
    'AMQPConnection::getLogin' => ['string'],
    'AMQPConnection::getMaxChannels' => ['?int'],
    'AMQPConnection::getMaxFrameSize' => ['int'],
    'AMQPConnection::getPassword' => ['string'],
    'AMQPConnection::getPort' => ['int'],
    'AMQPConnection::getReadTimeout' => ['float'],
    'AMQPConnection::getTimeout' => ['float'],
    'AMQPConnection::getUsedChannels' => ['int'],
    'AMQPConnection::getVerify' => ['bool'],
    'AMQPConnection::getVhost' => ['string'],
    'AMQPConnection::getWriteTimeout' => ['float'],
    'AMQPConnection::isConnected' => ['bool'],
    'AMQPConnection::isPersistent' => ['?bool'],
    'AMQPConnection::pconnect' => ['bool'],
    'AMQPConnection::pdisconnect' => ['bool'],
    'AMQPConnection::preconnect' => ['bool'],
    'AMQPConnection::reconnect' => ['bool'],
    'AMQPConnection::setCACert' => ['', 'cacert'=>'string'],
    'AMQPConnection::setCert' => ['', 'cert'=>'string'],
    'AMQPConnection::setHost' => ['bool', 'host'=>'string'],
    'AMQPConnection::setKey' => ['', 'key'=>'string'],
    'AMQPConnection::setLogin' => ['bool', 'login'=>'string'],
    'AMQPConnection::setPassword' => ['bool', 'password'=>'string'],
    'AMQPConnection::setPort' => ['bool', 'port'=>'int'],
    'AMQPConnection::setReadTimeout' => ['bool', 'timeout'=>'int'],
    'AMQPConnection::setTimeout' => ['bool', 'timeout'=>'int'],
    'AMQPConnection::setVerify' => ['', 'verify'=>'bool'],
    'AMQPConnection::setVhost' => ['bool', 'vhost'=>'string'],
    'AMQPConnection::setWriteTimeout' => ['bool', 'timeout'=>'int'],
    'AMQPDecimal::__construct' => ['void', 'exponent'=>'', 'significand'=>''],
    'AMQPDecimal::getExponent' => ['int'],
    'AMQPDecimal::getSignificand' => ['int'],
    'AMQPEnvelope::__construct' => ['void'],
    'AMQPEnvelope::getAppId' => ['string'],
    'AMQPEnvelope::getBody' => ['string'],
    'AMQPEnvelope::getClusterId' => ['string'],
    'AMQPEnvelope::getConsumerTag' => ['string'],
    'AMQPEnvelope::getContentEncoding' => ['string'],
    'AMQPEnvelope::getContentType' => ['string'],
    'AMQPEnvelope::getCorrelationId' => ['string'],
    'AMQPEnvelope::getDeliveryMode' => ['int'],
    'AMQPEnvelope::getDeliveryTag' => ['string'],
    'AMQPEnvelope::getExchangeName' => ['string'],
    'AMQPEnvelope::getExpiration' => ['string'],
    'AMQPEnvelope::getHeader' => ['string|false', 'header_key'=>'string'],
    'AMQPEnvelope::getHeaders' => ['array'],
    'AMQPEnvelope::getMessageId' => ['string'],
    'AMQPEnvelope::getPriority' => ['int'],
    'AMQPEnvelope::getReplyTo' => ['string'],
    'AMQPEnvelope::getRoutingKey' => ['string'],
    'AMQPEnvelope::getTimeStamp' => ['string'],
    'AMQPEnvelope::getType' => ['string'],
    'AMQPEnvelope::getUserId' => ['string'],
    'AMQPEnvelope::hasHeader' => ['bool', 'header_key'=>'string'],
    'AMQPEnvelope::isRedelivery' => ['bool'],
    'AMQPExchange::__construct' => ['void', 'amqp_channel'=>'AMQPChannel'],
    'AMQPExchange::bind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
    'AMQPExchange::declareExchange' => ['bool'],
    'AMQPExchange::delete' => ['bool', 'exchangeName='=>'string', 'flags='=>'int'],
    'AMQPExchange::getArgument' => ['int|string|false', 'key'=>'string'],
    'AMQPExchange::getArguments' => ['array'],
    'AMQPExchange::getChannel' => ['AMQPChannel'],
    'AMQPExchange::getConnection' => ['AMQPConnection'],
    'AMQPExchange::getFlags' => ['int'],
    'AMQPExchange::getName' => ['string'],
    'AMQPExchange::getType' => ['string'],
    'AMQPExchange::hasArgument' => ['bool', 'key'=>'string'],
    'AMQPExchange::publish' => ['bool', 'message'=>'string', 'routing_key='=>'string', 'flags='=>'int', 'attributes='=>'array'],
    'AMQPExchange::setArgument' => ['bool', 'key'=>'string', 'value'=>'int|string'],
    'AMQPExchange::setArguments' => ['bool', 'arguments'=>'array'],
    'AMQPExchange::setFlags' => ['bool', 'flags'=>'int'],
    'AMQPExchange::setName' => ['bool', 'exchange_name'=>'string'],
    'AMQPExchange::setType' => ['bool', 'exchange_type'=>'string'],
    'AMQPExchange::unbind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
    'AMQPQueue::__construct' => ['void', 'amqp_channel'=>'AMQPChannel'],
    'AMQPQueue::ack' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'],
    'AMQPQueue::bind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
    'AMQPQueue::cancel' => ['bool', 'consumer_tag='=>'string'],
    'AMQPQueue::consume' => ['void', 'callback='=>'?callable', 'flags='=>'int', 'consumerTag='=>'string'],
    'AMQPQueue::declareQueue' => ['int'],
    'AMQPQueue::delete' => ['int', 'flags='=>'int'],
    'AMQPQueue::get' => ['AMQPEnvelope|false', 'flags='=>'int'],
    'AMQPQueue::getArgument' => ['int|string|false', 'key'=>'string'],
    'AMQPQueue::getArguments' => ['array'],
    'AMQPQueue::getChannel' => ['AMQPChannel'],
    'AMQPQueue::getConnection' => ['AMQPConnection'],
    'AMQPQueue::getConsumerTag' => ['?string'],
    'AMQPQueue::getFlags' => ['int'],
    'AMQPQueue::getName' => ['string'],
    'AMQPQueue::hasArgument' => ['bool', 'key'=>'string'],
    'AMQPQueue::nack' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'],
    'AMQPQueue::purge' => ['bool'],
    'AMQPQueue::reject' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'],
    'AMQPQueue::setArgument' => ['bool', 'key'=>'string', 'value'=>'mixed'],
    'AMQPQueue::setArguments' => ['bool', 'arguments'=>'array'],
    'AMQPQueue::setFlags' => ['bool', 'flags'=>'int'],
    'AMQPQueue::setName' => ['bool', 'queue_name'=>'string'],
    'AMQPQueue::unbind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
    'AMQPTimestamp::__construct' => ['void', 'timestamp'=>'string'],
    'AMQPTimestamp::__toString' => ['string'],
    'AMQPTimestamp::getTimestamp' => ['string'],
    'APCIterator::__construct' => ['void', 'cache'=>'string', 'search='=>'null|string|string[]', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'],
    'APCIterator::current' => ['mixed|false'],
    'APCIterator::getTotalCount' => ['int|false'],
    'APCIterator::getTotalHits' => ['int|false'],
    'APCIterator::getTotalSize' => ['int|false'],
    'APCIterator::key' => ['string'],
    'APCIterator::next' => ['void'],
    'APCIterator::rewind' => ['void'],
    'APCIterator::valid' => ['bool'],
    'APCuIterator::__construct' => ['void', 'search='=>'string|string[]|null', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'],
    'APCuIterator::current' => ['mixed'],
    'APCuIterator::getTotalCount' => ['int'],
    'APCuIterator::getTotalHits' => ['int'],
    'APCuIterator::getTotalSize' => ['int'],
    'APCuIterator::key' => ['string'],
    'APCuIterator::next' => ['void'],
    'APCuIterator::rewind' => ['void'],
    'APCuIterator::valid' => ['bool'],
    'AppendIterator::__construct' => ['void'],
    'AppendIterator::append' => ['void', 'iterator'=>'Iterator'],
    'AppendIterator::current' => ['mixed'],
    'AppendIterator::getArrayIterator' => ['ArrayIterator'],
    'AppendIterator::getInnerIterator' => ['Iterator'],
    'AppendIterator::getIteratorIndex' => ['int'],
    'AppendIterator::key' => ['int|string|float|bool'],
    'AppendIterator::next' => ['void'],
    'AppendIterator::rewind' => ['void'],
    'AppendIterator::valid' => ['bool'],
    'ArgumentCountError::__clone' => ['void'],
    'ArgumentCountError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'ArgumentCountError::__toString' => ['string'],
    'ArgumentCountError::__wakeup' => ['void'],
    'ArgumentCountError::getCode' => ['int'],
    'ArgumentCountError::getFile' => ['string'],
    'ArgumentCountError::getLine' => ['int'],
    'ArgumentCountError::getMessage' => ['string'],
    'ArgumentCountError::getPrevious' => ['?Throwable'],
    'ArgumentCountError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'ArgumentCountError::getTraceAsString' => ['string'],
    'ArithmeticError::__clone' => ['void'],
    'ArithmeticError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'ArithmeticError::__toString' => ['string'],
    'ArithmeticError::__wakeup' => ['void'],
    'ArithmeticError::getCode' => ['int'],
    'ArithmeticError::getFile' => ['string'],
    'ArithmeticError::getLine' => ['int'],
    'ArithmeticError::getMessage' => ['string'],
    'ArithmeticError::getPrevious' => ['?Throwable'],
    'ArithmeticError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'ArithmeticError::getTraceAsString' => ['string'],
    'ArrayAccess::offsetExists' => ['bool', 'offset'=>'mixed'],
    'ArrayAccess::offsetGet' => ['mixed', 'offset'=>'mixed'],
    'ArrayAccess::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
    'ArrayAccess::offsetUnset' => ['void', 'offset'=>'mixed'],
    'ArrayIterator::__construct' => ['void', 'array='=>'array|object', 'flags='=>'int'],
    'ArrayIterator::append' => ['void', 'value'=>'mixed'],
    'ArrayIterator::asort' => ['void'],
    'ArrayIterator::count' => ['int'],
    'ArrayIterator::current' => ['mixed'],
    'ArrayIterator::getArrayCopy' => ['array'],
    'ArrayIterator::getFlags' => ['int'],
    'ArrayIterator::key' => ['int|string|null'],
    'ArrayIterator::ksort' => ['void'],
    'ArrayIterator::natcasesort' => ['true'],
    'ArrayIterator::natsort' => ['true'],
    'ArrayIterator::next' => ['void'],
    'ArrayIterator::offsetExists' => ['bool', 'index'=>'string|int'],
    'ArrayIterator::offsetGet' => ['mixed', 'index'=>'string|int'],
    'ArrayIterator::offsetSet' => ['void', 'index'=>'string|int', 'newval'=>'mixed'],
    'ArrayIterator::offsetUnset' => ['void', 'index'=>'string|int'],
    'ArrayIterator::rewind' => ['void'],
    'ArrayIterator::seek' => ['void', 'position'=>'int'],
    'ArrayIterator::serialize' => ['string'],
    'ArrayIterator::setFlags' => ['void', 'flags'=>'string'],
    'ArrayIterator::uasort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
    'ArrayIterator::uksort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
    'ArrayIterator::unserialize' => ['void', 'serialized'=>'string'],
    'ArrayIterator::valid' => ['bool'],
    'ArrayObject::__construct' => ['void', 'input='=>'array|object', 'flags='=>'int', 'iterator_class='=>'string'],
    'ArrayObject::append' => ['void', 'value'=>'mixed'],
    'ArrayObject::asort' => ['void'],
    'ArrayObject::count' => ['int'],
    'ArrayObject::exchangeArray' => ['array', 'ar'=>'mixed'],
    'ArrayObject::getArrayCopy' => ['array'],
    'ArrayObject::getFlags' => ['int'],
    'ArrayObject::getIterator' => ['ArrayIterator'],
    'ArrayObject::getIteratorClass' => ['string'],
    'ArrayObject::ksort' => ['void'],
    'ArrayObject::natcasesort' => ['true'],
    'ArrayObject::natsort' => ['true'],
    'ArrayObject::offsetExists' => ['bool', 'index'=>'int|string'],
    'ArrayObject::offsetGet' => ['mixed|null', 'index'=>'int|string'],
    'ArrayObject::offsetSet' => ['void', 'index'=>'int|string', 'newval'=>'mixed'],
    'ArrayObject::offsetUnset' => ['void', 'index'=>'int|string'],
    'ArrayObject::serialize' => ['string'],
    'ArrayObject::setFlags' => ['void', 'flags'=>'int'],
    'ArrayObject::setIteratorClass' => ['void', 'iterator_class'=>'string'],
    'ArrayObject::uasort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
    'ArrayObject::uksort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
    'ArrayObject::unserialize' => ['void', 'serialized'=>'string'],
    'BadFunctionCallException::__clone' => ['void'],
    'BadFunctionCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'BadFunctionCallException::__toString' => ['string'],
    'BadFunctionCallException::getCode' => ['int'],
    'BadFunctionCallException::getFile' => ['string'],
    'BadFunctionCallException::getLine' => ['int'],
    'BadFunctionCallException::getMessage' => ['string'],
    'BadFunctionCallException::getPrevious' => ['?Throwable'],
    'BadFunctionCallException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'BadFunctionCallException::getTraceAsString' => ['string'],
    'BadMethodCallException::__clone' => ['void'],
    'BadMethodCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'BadMethodCallException::__toString' => ['string'],
    'BadMethodCallException::getCode' => ['int'],
    'BadMethodCallException::getFile' => ['string'],
    'BadMethodCallException::getLine' => ['int'],
    'BadMethodCallException::getMessage' => ['string'],
    'BadMethodCallException::getPrevious' => ['?Throwable'],
    'BadMethodCallException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'BadMethodCallException::getTraceAsString' => ['string'],
    'COM::__call' => ['', 'name'=>'', 'args'=>''],
    'COM::__construct' => ['void', 'module_name'=>'string', 'server_name='=>'mixed', 'codepage='=>'int', 'typelib='=>'string'],
    'COM::__get' => ['', 'name'=>''],
    'COM::__set' => ['void', 'name'=>'', 'value'=>''],
    'COMPersistHelper::GetCurFile' => ['string'],
    'COMPersistHelper::GetCurFileName' => ['string'],
    'COMPersistHelper::GetMaxStreamSize' => ['int'],
    'COMPersistHelper::InitNew' => ['int'],
    'COMPersistHelper::LoadFromFile' => ['bool', 'filename'=>'string', 'flags'=>'int'],
    'COMPersistHelper::LoadFromStream' => ['', 'stream'=>''],
    'COMPersistHelper::SaveToFile' => ['bool', 'filename'=>'string', 'remember'=>'bool'],
    'COMPersistHelper::SaveToStream' => ['int', 'stream'=>''],
    'COMPersistHelper::__construct' => ['void', 'variant'=>'object'],
    'CURLFile::__construct' => ['void', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'],
    'CURLFile::__wakeup' => ['void'],
    'CURLFile::getFilename' => ['string'],
    'CURLFile::getMimeType' => ['string'],
    'CURLFile::getPostFilename' => ['string'],
    'CURLFile::setMimeType' => ['void', 'mime'=>'string'],
    'CURLFile::setPostFilename' => ['void', 'name'=>'string'],
    'CachingIterator::__construct' => ['void', 'iterator'=>'Iterator', 'flags='=>''],
    'CachingIterator::__toString' => ['string'],
    'CachingIterator::count' => ['int'],
    'CachingIterator::current' => ['mixed'],
    'CachingIterator::getCache' => ['array'],
    'CachingIterator::getFlags' => ['int'],
    'CachingIterator::getInnerIterator' => ['Iterator'],
    'CachingIterator::hasNext' => ['bool'],
    'CachingIterator::key' => ['int|string|float|bool'],
    'CachingIterator::next' => ['void'],
    'CachingIterator::offsetExists' => ['bool', 'index'=>'string'],
    'CachingIterator::offsetGet' => ['mixed', 'index'=>'string'],
    'CachingIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'mixed'],
    'CachingIterator::offsetUnset' => ['void', 'index'=>'string'],
    'CachingIterator::rewind' => ['void'],
    'CachingIterator::setFlags' => ['void', 'flags'=>'int'],
    'CachingIterator::valid' => ['bool'],
    'Cairo::availableFonts' => ['array'],
    'Cairo::availableSurfaces' => ['array'],
    'Cairo::statusToString' => ['string', 'status'=>'int'],
    'Cairo::version' => ['int'],
    'Cairo::versionString' => ['string'],
    'CairoContext::__construct' => ['void', 'surface'=>'CairoSurface'],
    'CairoContext::appendPath' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'],
    'CairoContext::arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
    'CairoContext::arcNegative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
    'CairoContext::clip' => ['', 'context'=>'cairocontext'],
    'CairoContext::clipExtents' => ['array', 'context'=>'cairocontext'],
    'CairoContext::clipPreserve' => ['', 'context'=>'cairocontext'],
    'CairoContext::clipRectangleList' => ['array', 'context'=>'cairocontext'],
    'CairoContext::closePath' => ['', 'context'=>'cairocontext'],
    'CairoContext::copyPage' => ['', 'context'=>'cairocontext'],
    'CairoContext::copyPath' => ['CairoPath', 'context'=>'cairocontext'],
    'CairoContext::copyPathFlat' => ['CairoPath', 'context'=>'cairocontext'],
    'CairoContext::curveTo' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'],
    'CairoContext::deviceToUser' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
    'CairoContext::deviceToUserDistance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
    'CairoContext::fill' => ['', 'context'=>'cairocontext'],
    'CairoContext::fillExtents' => ['array', 'context'=>'cairocontext'],
    'CairoContext::fillPreserve' => ['', 'context'=>'cairocontext'],
    'CairoContext::fontExtents' => ['array', 'context'=>'cairocontext'],
    'CairoContext::getAntialias' => ['int', 'context'=>'cairocontext'],
    'CairoContext::getCurrentPoint' => ['array', 'context'=>'cairocontext'],
    'CairoContext::getDash' => ['array', 'context'=>'cairocontext'],
    'CairoContext::getDashCount' => ['int', 'context'=>'cairocontext'],
    'CairoContext::getFillRule' => ['int', 'context'=>'cairocontext'],
    'CairoContext::getFontFace' => ['', 'context'=>'cairocontext'],
    'CairoContext::getFontMatrix' => ['', 'context'=>'cairocontext'],
    'CairoContext::getFontOptions' => ['', 'context'=>'cairocontext'],
    'CairoContext::getGroupTarget' => ['', 'context'=>'cairocontext'],
    'CairoContext::getLineCap' => ['int', 'context'=>'cairocontext'],
    'CairoContext::getLineJoin' => ['int', 'context'=>'cairocontext'],
    'CairoContext::getLineWidth' => ['float', 'context'=>'cairocontext'],
    'CairoContext::getMatrix' => ['', 'context'=>'cairocontext'],
    'CairoContext::getMiterLimit' => ['float', 'context'=>'cairocontext'],
    'CairoContext::getOperator' => ['int', 'context'=>'cairocontext'],
    'CairoContext::getScaledFont' => ['', 'context'=>'cairocontext'],
    'CairoContext::getSource' => ['', 'context'=>'cairocontext'],
    'CairoContext::getTarget' => ['', 'context'=>'cairocontext'],
    'CairoContext::getTolerance' => ['float', 'context'=>'cairocontext'],
    'CairoContext::glyphPath' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'],
    'CairoContext::hasCurrentPoint' => ['bool', 'context'=>'cairocontext'],
    'CairoContext::identityMatrix' => ['', 'context'=>'cairocontext'],
    'CairoContext::inFill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::inStroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::lineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'],
    'CairoContext::maskSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
    'CairoContext::moveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::newPath' => ['', 'context'=>'cairocontext'],
    'CairoContext::newSubPath' => ['', 'context'=>'cairocontext'],
    'CairoContext::paint' => ['', 'context'=>'cairocontext'],
    'CairoContext::paintWithAlpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'],
    'CairoContext::pathExtents' => ['array', 'context'=>'cairocontext'],
    'CairoContext::popGroup' => ['', 'context'=>'cairocontext'],
    'CairoContext::popGroupToSource' => ['', 'context'=>'cairocontext'],
    'CairoContext::pushGroup' => ['', 'context'=>'cairocontext'],
    'CairoContext::pushGroupWithContent' => ['', 'content'=>'string', 'context'=>'cairocontext'],
    'CairoContext::rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'],
    'CairoContext::relCurveTo' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'],
    'CairoContext::relLineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::relMoveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::resetClip' => ['', 'context'=>'cairocontext'],
    'CairoContext::restore' => ['', 'context'=>'cairocontext'],
    'CairoContext::rotate' => ['', 'angle'=>'string', 'context'=>'cairocontext'],
    'CairoContext::save' => ['', 'context'=>'cairocontext'],
    'CairoContext::scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::selectFontFace' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'],
    'CairoContext::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'],
    'CairoContext::setDash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'],
    'CairoContext::setFillRule' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'CairoContext::setFontFace' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'],
    'CairoContext::setFontMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
    'CairoContext::setFontOptions' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'],
    'CairoContext::setFontSize' => ['', 'size'=>'string', 'context'=>'cairocontext'],
    'CairoContext::setLineCap' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'CairoContext::setLineJoin' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'CairoContext::setLineWidth' => ['', 'width'=>'string', 'context'=>'cairocontext'],
    'CairoContext::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
    'CairoContext::setMiterLimit' => ['', 'limit'=>'string', 'context'=>'cairocontext'],
    'CairoContext::setOperator' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'CairoContext::setScaledFont' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'],
    'CairoContext::setSource' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'],
    'CairoContext::setSourceRGB' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'],
    'CairoContext::setSourceRGBA' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'],
    'CairoContext::setSourceSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
    'CairoContext::setTolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'],
    'CairoContext::showPage' => ['', 'context'=>'cairocontext'],
    'CairoContext::showText' => ['', 'text'=>'string', 'context'=>'cairocontext'],
    'CairoContext::status' => ['int', 'context'=>'cairocontext'],
    'CairoContext::stroke' => ['', 'context'=>'cairocontext'],
    'CairoContext::strokeExtents' => ['array', 'context'=>'cairocontext'],
    'CairoContext::strokePreserve' => ['', 'context'=>'cairocontext'],
    'CairoContext::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'],
    'CairoContext::textPath' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'],
    'CairoContext::transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
    'CairoContext::translate' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::userToDevice' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoContext::userToDeviceDistance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'CairoFontFace::__construct' => ['void'],
    'CairoFontFace::getType' => ['int'],
    'CairoFontFace::status' => ['int', 'fontface'=>'cairofontface'],
    'CairoFontOptions::__construct' => ['void'],
    'CairoFontOptions::equal' => ['bool', 'other'=>'string'],
    'CairoFontOptions::getAntialias' => ['int', 'context'=>'cairocontext'],
    'CairoFontOptions::getHintMetrics' => ['int'],
    'CairoFontOptions::getHintStyle' => ['int'],
    'CairoFontOptions::getSubpixelOrder' => ['int'],
    'CairoFontOptions::hash' => ['int'],
    'CairoFontOptions::merge' => ['void', 'other'=>'string'],
    'CairoFontOptions::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'],
    'CairoFontOptions::setHintMetrics' => ['void', 'hint_metrics'=>'string'],
    'CairoFontOptions::setHintStyle' => ['void', 'hint_style'=>'string'],
    'CairoFontOptions::setSubpixelOrder' => ['void', 'subpixel_order'=>'string'],
    'CairoFontOptions::status' => ['int', 'context'=>'cairocontext'],
    'CairoFormat::strideForWidth' => ['int', 'format'=>'int', 'width'=>'int'],
    'CairoGradientPattern::addColorStopRgb' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string'],
    'CairoGradientPattern::addColorStopRgba' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string'],
    'CairoGradientPattern::getColorStopCount' => ['int'],
    'CairoGradientPattern::getColorStopRgba' => ['array', 'index'=>'string'],
    'CairoGradientPattern::getExtend' => ['int'],
    'CairoGradientPattern::setExtend' => ['void', 'extend'=>'int'],
    'CairoImageSurface::__construct' => ['void', 'format'=>'int', 'width'=>'int', 'height'=>'int'],
    'CairoImageSurface::createForData' => ['void', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'],
    'CairoImageSurface::createFromPng' => ['CairoImageSurface', 'file'=>'string'],
    'CairoImageSurface::getData' => ['string'],
    'CairoImageSurface::getFormat' => ['int'],
    'CairoImageSurface::getHeight' => ['int'],
    'CairoImageSurface::getStride' => ['int'],
    'CairoImageSurface::getWidth' => ['int'],
    'CairoLinearGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'],
    'CairoLinearGradient::getPoints' => ['array'],
    'CairoMatrix::__construct' => ['void', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'],
    'CairoMatrix::initIdentity' => ['object'],
    'CairoMatrix::initRotate' => ['object', 'radians'=>'float'],
    'CairoMatrix::initScale' => ['object', 'sx'=>'float', 'sy'=>'float'],
    'CairoMatrix::initTranslate' => ['object', 'tx'=>'float', 'ty'=>'float'],
    'CairoMatrix::invert' => ['void'],
    'CairoMatrix::multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'],
    'CairoMatrix::rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'],
    'CairoMatrix::scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'],
    'CairoMatrix::transformDistance' => ['array', 'dx'=>'string', 'dy'=>'string'],
    'CairoMatrix::transformPoint' => ['array', 'dx'=>'string', 'dy'=>'string'],
    'CairoMatrix::translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'],
    'CairoPattern::__construct' => ['void'],
    'CairoPattern::getMatrix' => ['', 'context'=>'cairocontext'],
    'CairoPattern::getType' => ['int'],
    'CairoPattern::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
    'CairoPattern::status' => ['int', 'context'=>'cairocontext'],
    'CairoPdfSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
    'CairoPdfSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'],
    'CairoPsSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
    'CairoPsSurface::dscBeginPageSetup' => ['void'],
    'CairoPsSurface::dscBeginSetup' => ['void'],
    'CairoPsSurface::dscComment' => ['void', 'comment'=>'string'],
    'CairoPsSurface::getEps' => ['bool'],
    'CairoPsSurface::getLevels' => ['array'],
    'CairoPsSurface::levelToString' => ['string', 'level'=>'int'],
    'CairoPsSurface::restrictToLevel' => ['void', 'level'=>'string'],
    'CairoPsSurface::setEps' => ['void', 'level'=>'string'],
    'CairoPsSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'],
    'CairoRadialGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'],
    'CairoRadialGradient::getCircles' => ['array'],
    'CairoScaledFont::__construct' => ['void', 'font_face'=>'CairoFontFace', 'matrix'=>'CairoMatrix', 'ctm'=>'CairoMatrix', 'options'=>'CairoFontOptions'],
    'CairoScaledFont::extents' => ['array'],
    'CairoScaledFont::getCtm' => ['CairoMatrix'],
    'CairoScaledFont::getFontFace' => ['', 'context'=>'cairocontext'],
    'CairoScaledFont::getFontMatrix' => ['', 'context'=>'cairocontext'],
    'CairoScaledFont::getFontOptions' => ['', 'context'=>'cairocontext'],
    'CairoScaledFont::getScaleMatrix' => ['void'],
    'CairoScaledFont::getType' => ['int'],
    'CairoScaledFont::glyphExtents' => ['array', 'glyphs'=>'string'],
    'CairoScaledFont::status' => ['int', 'context'=>'cairocontext'],
    'CairoScaledFont::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'],
    'CairoSolidPattern::__construct' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha='=>'float'],
    'CairoSolidPattern::getRgba' => ['array'],
    'CairoSurface::__construct' => ['void'],
    'CairoSurface::copyPage' => ['', 'context'=>'cairocontext'],
    'CairoSurface::createSimilar' => ['void', 'other'=>'cairosurface', 'content'=>'int', 'width'=>'string', 'height'=>'string'],
    'CairoSurface::finish' => ['void'],
    'CairoSurface::flush' => ['void'],
    'CairoSurface::getContent' => ['int'],
    'CairoSurface::getDeviceOffset' => ['array'],
    'CairoSurface::getFontOptions' => ['', 'context'=>'cairocontext'],
    'CairoSurface::getType' => ['int'],
    'CairoSurface::markDirty' => ['void'],
    'CairoSurface::markDirtyRectangle' => ['void', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string'],
    'CairoSurface::setDeviceOffset' => ['void', 'x'=>'string', 'y'=>'string'],
    'CairoSurface::setFallbackResolution' => ['void', 'x'=>'string', 'y'=>'string'],
    'CairoSurface::showPage' => ['', 'context'=>'cairocontext'],
    'CairoSurface::status' => ['int', 'context'=>'cairocontext'],
    'CairoSurface::writeToPng' => ['void', 'file'=>'string'],
    'CairoSurfacePattern::__construct' => ['void', 'surface'=>'CairoSurface'],
    'CairoSurfacePattern::getExtend' => ['int'],
    'CairoSurfacePattern::getFilter' => ['int'],
    'CairoSurfacePattern::getSurface' => ['void'],
    'CairoSurfacePattern::setExtend' => ['void', 'extend'=>'int'],
    'CairoSurfacePattern::setFilter' => ['void', 'filter'=>'string'],
    'CairoSvgSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
    'CairoSvgSurface::getVersions' => ['array'],
    'CairoSvgSurface::restrictToVersion' => ['void', 'version'=>'string'],
    'CairoSvgSurface::versionToString' => ['string', 'version'=>'int'],
    'CallbackFilterIterator::__construct' => ['void', 'iterator'=>'Iterator', 'func'=>'callable(mixed):bool|callable(mixed,mixed):bool|callable(mixed,mixed,mixed):bool'],
    'CallbackFilterIterator::accept' => ['bool'],
    'CallbackFilterIterator::current' => ['mixed'],
    'CallbackFilterIterator::getInnerIterator' => ['Iterator'],
    'CallbackFilterIterator::key' => ['mixed'],
    'CallbackFilterIterator::next' => ['void'],
    'CallbackFilterIterator::rewind' => ['void'],
    'CallbackFilterIterator::valid' => ['bool'],
    'ClosedGeneratorException::__clone' => ['void'],
    'ClosedGeneratorException::__toString' => ['string'],
    'ClosedGeneratorException::getCode' => ['int'],
    'ClosedGeneratorException::getFile' => ['string'],
    'ClosedGeneratorException::getLine' => ['int'],
    'ClosedGeneratorException::getMessage' => ['string'],
    'ClosedGeneratorException::getPrevious' => ['?Throwable'],
    'ClosedGeneratorException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'ClosedGeneratorException::getTraceAsString' => ['string'],
    'Closure::__construct' => ['void'],
    'Closure::__invoke' => ['', '...args='=>''],
    'Closure::bind' => ['Closure|false', 'old'=>'Closure', 'to'=>'?object', 'scope='=>'object|string'],
    'Closure::bindTo' => ['Closure|false', 'new'=>'?object', 'newscope='=>'object|string'],
    'Closure::call' => ['', 'to'=>'object', '...parameters='=>''],
    'Collator::__construct' => ['void', 'locale'=>'string'],
    'Collator::asort' => ['bool', '&rw_arr'=>'array', 'sort_flag='=>'int'],
    'Collator::compare' => ['int|false', 'string1'=>'string', 'string2'=>'string'],
    'Collator::create' => ['?Collator', 'locale'=>'string'],
    'Collator::getAttribute' => ['int|false', 'attr'=>'int'],
    'Collator::getErrorCode' => ['int'],
    'Collator::getErrorMessage' => ['string'],
    'Collator::getLocale' => ['string', 'type'=>'int'],
    'Collator::getSortKey' => ['string|false', 'string'=>'string'],
    'Collator::getStrength' => ['int|false'],
    'Collator::setAttribute' => ['bool', 'attr'=>'int', 'value'=>'int'],
    'Collator::setStrength' => ['bool', 'strength'=>'int'],
    'Collator::sort' => ['bool', '&rw_arr'=>'array', 'sort_flags='=>'int'],
    'Collator::sortWithSortKeys' => ['bool', '&rw_arr'=>'array'],
    'Collectable::isGarbage' => ['bool'],
    'Collectable::setGarbage' => ['void'],
    'Cond::broadcast' => ['bool', 'condition'=>'long'],
    'Cond::create' => ['long'],
    'Cond::destroy' => ['bool', 'condition'=>'long'],
    'Cond::signal' => ['bool', 'condition'=>'long'],
    'Cond::wait' => ['bool', 'condition'=>'long', 'mutex'=>'long', 'timeout='=>'long'],
    'Couchbase\AnalyticsQuery::__construct' => ['void'],
    'Couchbase\AnalyticsQuery::fromString' => ['Couchbase\AnalyticsQuery', 'statement'=>'string'],
    'Couchbase\BooleanFieldSearchQuery::__construct' => ['void'],
    'Couchbase\BooleanFieldSearchQuery::boost' => ['Couchbase\BooleanFieldSearchQuery', 'boost'=>'float'],
    'Couchbase\BooleanFieldSearchQuery::field' => ['Couchbase\BooleanFieldSearchQuery', 'field'=>'string'],
    'Couchbase\BooleanFieldSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\BooleanSearchQuery::__construct' => ['void'],
    'Couchbase\BooleanSearchQuery::boost' => ['Couchbase\BooleanSearchQuery', 'boost'=>'float'],
    'Couchbase\BooleanSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\BooleanSearchQuery::must' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
    'Couchbase\BooleanSearchQuery::mustNot' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
    'Couchbase\BooleanSearchQuery::should' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
    'Couchbase\Bucket::__construct' => ['void'],
    'Couchbase\Bucket::__get' => ['int', 'name'=>'string'],
    'Couchbase\Bucket::__set' => ['int', 'name'=>'string', 'value'=>'int'],
    'Couchbase\Bucket::append' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
    'Couchbase\Bucket::counter' => ['Couchbase\Document|array', 'ids'=>'array|string', 'delta='=>'int', 'options='=>'array'],
    'Couchbase\Bucket::decryptFields' => ['array', 'document'=>'array', 'fieldOptions'=>'', 'prefix='=>'string'],
    'Couchbase\Bucket::diag' => ['array', 'reportId='=>'string'],
    'Couchbase\Bucket::encryptFields' => ['array', 'document'=>'array', 'fieldOptions'=>'', 'prefix='=>'string'],
    'Couchbase\Bucket::get' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
    'Couchbase\Bucket::getAndLock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'lockTime'=>'int', 'options='=>'array'],
    'Couchbase\Bucket::getAndTouch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'],
    'Couchbase\Bucket::getFromReplica' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
    'Couchbase\Bucket::getName' => ['string'],
    'Couchbase\Bucket::insert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
    'Couchbase\Bucket::listExists' => ['bool', 'id'=>'string', 'value'=>'mixed'],
    'Couchbase\Bucket::listGet' => ['mixed', 'id'=>'string', 'index'=>'int'],
    'Couchbase\Bucket::listPush' => ['', 'id'=>'string', 'value'=>'mixed'],
    'Couchbase\Bucket::listRemove' => ['', 'id'=>'string', 'index'=>'int'],
    'Couchbase\Bucket::listSet' => ['', 'id'=>'string', 'index'=>'int', 'value'=>'mixed'],
    'Couchbase\Bucket::listShift' => ['', 'id'=>'string', 'value'=>'mixed'],
    'Couchbase\Bucket::listSize' => ['int', 'id'=>'string'],
    'Couchbase\Bucket::lookupIn' => ['Couchbase\LookupInBuilder', 'id'=>'string'],
    'Couchbase\Bucket::manager' => ['Couchbase\BucketManager'],
    'Couchbase\Bucket::mapAdd' => ['', 'id'=>'string', 'key'=>'string', 'value'=>'mixed'],
    'Couchbase\Bucket::mapGet' => ['mixed', 'id'=>'string', 'key'=>'string'],
    'Couchbase\Bucket::mapRemove' => ['', 'id'=>'string', 'key'=>'string'],
    'Couchbase\Bucket::mapSize' => ['int', 'id'=>'string'],
    'Couchbase\Bucket::mutateIn' => ['Couchbase\MutateInBuilder', 'id'=>'string', 'cas'=>'string'],
    'Couchbase\Bucket::ping' => ['array', 'services='=>'int', 'reportId='=>'string'],
    'Couchbase\Bucket::prepend' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
    'Couchbase\Bucket::query' => ['object', 'query'=>'Couchbase\AnalyticsQuery|Couchbase\N1qlQuery|Couchbase\SearchQuery|Couchbase\SpatialViewQuery|Couchbase\ViewQuery', 'jsonAsArray='=>'bool'],
    'Couchbase\Bucket::queueAdd' => ['', 'id'=>'string', 'value'=>'mixed'],
    'Couchbase\Bucket::queueExists' => ['bool', 'id'=>'string', 'value'=>'mixed'],
    'Couchbase\Bucket::queueRemove' => ['mixed', 'id'=>'string'],
    'Couchbase\Bucket::queueSize' => ['int', 'id'=>'string'],
    'Couchbase\Bucket::remove' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
    'Couchbase\Bucket::replace' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
    'Couchbase\Bucket::retrieveIn' => ['Couchbase\DocumentFragment', 'id'=>'string', '...paths='=>'array<int,string>'],
    'Couchbase\Bucket::setAdd' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'],
    'Couchbase\Bucket::setExists' => ['bool', 'id'=>'string', 'value'=>'bool|float|int|string'],
    'Couchbase\Bucket::setRemove' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'],
    'Couchbase\Bucket::setSize' => ['int', 'id'=>'string'],
    'Couchbase\Bucket::setTranscoder' => ['', 'encoder'=>'callable', 'decoder'=>'callable'],
    'Couchbase\Bucket::touch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'],
    'Couchbase\Bucket::unlock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
    'Couchbase\Bucket::upsert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
    'Couchbase\BucketManager::__construct' => ['void'],
    'Couchbase\BucketManager::createN1qlIndex' => ['', 'name'=>'string', 'fields'=>'array', 'whereClause='=>'string', 'ignoreIfExist='=>'bool', 'defer='=>'bool'],
    'Couchbase\BucketManager::createN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfExist='=>'bool', 'defer='=>'bool'],
    'Couchbase\BucketManager::dropN1qlIndex' => ['', 'name'=>'string', 'ignoreIfNotExist='=>'bool'],
    'Couchbase\BucketManager::dropN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfNotExist='=>'bool'],
    'Couchbase\BucketManager::flush' => [''],
    'Couchbase\BucketManager::getDesignDocument' => ['array', 'name'=>'string'],
    'Couchbase\BucketManager::info' => ['array'],
    'Couchbase\BucketManager::insertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'],
    'Couchbase\BucketManager::listDesignDocuments' => ['array'],
    'Couchbase\BucketManager::listN1qlIndexes' => ['array'],
    'Couchbase\BucketManager::removeDesignDocument' => ['', 'name'=>'string'],
    'Couchbase\BucketManager::upsertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'],
    'Couchbase\ClassicAuthenticator::bucket' => ['', 'name'=>'string', 'password'=>'string'],
    'Couchbase\ClassicAuthenticator::cluster' => ['', 'username'=>'string', 'password'=>'string'],
    'Couchbase\Cluster::__construct' => ['void', 'connstr'=>'string'],
    'Couchbase\Cluster::authenticate' => ['null', 'authenticator'=>'Couchbase\Authenticator'],
    'Couchbase\Cluster::authenticateAs' => ['null', 'username'=>'string', 'password'=>'string'],
    'Couchbase\Cluster::manager' => ['Couchbase\ClusterManager', 'username='=>'string', 'password='=>'string'],
    'Couchbase\Cluster::openBucket' => ['Couchbase\Bucket', 'name='=>'string', 'password='=>'string'],
    'Couchbase\ClusterManager::__construct' => ['void'],
    'Couchbase\ClusterManager::createBucket' => ['', 'name'=>'string', 'options='=>'array'],
    'Couchbase\ClusterManager::getUser' => ['array', 'username'=>'string', 'domain='=>'int'],
    'Couchbase\ClusterManager::info' => ['array'],
    'Couchbase\ClusterManager::listBuckets' => ['array'],
    'Couchbase\ClusterManager::listUsers' => ['array', 'domain='=>'int'],
    'Couchbase\ClusterManager::removeBucket' => ['', 'name'=>'string'],
    'Couchbase\ClusterManager::removeUser' => ['', 'name'=>'string', 'domain='=>'int'],
    'Couchbase\ClusterManager::upsertUser' => ['', 'name'=>'string', 'settings'=>'Couchbase\UserSettings', 'domain='=>'int'],
    'Couchbase\ConjunctionSearchQuery::__construct' => ['void'],
    'Couchbase\ConjunctionSearchQuery::boost' => ['Couchbase\ConjunctionSearchQuery', 'boost'=>'float'],
    'Couchbase\ConjunctionSearchQuery::every' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
    'Couchbase\ConjunctionSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\DateRangeSearchFacet::__construct' => ['void'],
    'Couchbase\DateRangeSearchFacet::addRange' => ['Couchbase\DateRangeSearchFacet', 'name'=>'string', 'start'=>'int|string', 'end'=>'int|string'],
    'Couchbase\DateRangeSearchFacet::jsonSerialize' => ['array'],
    'Couchbase\DateRangeSearchQuery::__construct' => ['void'],
    'Couchbase\DateRangeSearchQuery::boost' => ['Couchbase\DateRangeSearchQuery', 'boost'=>'float'],
    'Couchbase\DateRangeSearchQuery::dateTimeParser' => ['Couchbase\DateRangeSearchQuery', 'dateTimeParser'=>'string'],
    'Couchbase\DateRangeSearchQuery::end' => ['Couchbase\DateRangeSearchQuery', 'end'=>'int|string', 'inclusive='=>'bool'],
    'Couchbase\DateRangeSearchQuery::field' => ['Couchbase\DateRangeSearchQuery', 'field'=>'string'],
    'Couchbase\DateRangeSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\DateRangeSearchQuery::start' => ['Couchbase\DateRangeSearchQuery', 'start'=>'int|string', 'inclusive='=>'bool'],
    'Couchbase\DisjunctionSearchQuery::__construct' => ['void'],
    'Couchbase\DisjunctionSearchQuery::boost' => ['Couchbase\DisjunctionSearchQuery', 'boost'=>'float'],
    'Couchbase\DisjunctionSearchQuery::either' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
    'Couchbase\DisjunctionSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\DisjunctionSearchQuery::min' => ['Couchbase\DisjunctionSearchQuery', 'min'=>'int'],
    'Couchbase\DocIdSearchQuery::__construct' => ['void'],
    'Couchbase\DocIdSearchQuery::boost' => ['Couchbase\DocIdSearchQuery', 'boost'=>'float'],
    'Couchbase\DocIdSearchQuery::docIds' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array<int,string>'],
    'Couchbase\DocIdSearchQuery::field' => ['Couchbase\DocIdSearchQuery', 'field'=>'string'],
    'Couchbase\DocIdSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\GeoBoundingBoxSearchQuery::__construct' => ['void'],
    'Couchbase\GeoBoundingBoxSearchQuery::boost' => ['Couchbase\GeoBoundingBoxSearchQuery', 'boost'=>'float'],
    'Couchbase\GeoBoundingBoxSearchQuery::field' => ['Couchbase\GeoBoundingBoxSearchQuery', 'field'=>'string'],
    'Couchbase\GeoBoundingBoxSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\GeoDistanceSearchQuery::__construct' => ['void'],
    'Couchbase\GeoDistanceSearchQuery::boost' => ['Couchbase\GeoDistanceSearchQuery', 'boost'=>'float'],
    'Couchbase\GeoDistanceSearchQuery::field' => ['Couchbase\GeoDistanceSearchQuery', 'field'=>'string'],
    'Couchbase\GeoDistanceSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\LookupInBuilder::__construct' => ['void'],
    'Couchbase\LookupInBuilder::execute' => ['Couchbase\DocumentFragment'],
    'Couchbase\LookupInBuilder::exists' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'],
    'Couchbase\LookupInBuilder::get' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'],
    'Couchbase\LookupInBuilder::getCount' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'],
    'Couchbase\MatchAllSearchQuery::__construct' => ['void'],
    'Couchbase\MatchAllSearchQuery::boost' => ['Couchbase\MatchAllSearchQuery', 'boost'=>'float'],
    'Couchbase\MatchAllSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\MatchNoneSearchQuery::__construct' => ['void'],
    'Couchbase\MatchNoneSearchQuery::boost' => ['Couchbase\MatchNoneSearchQuery', 'boost'=>'float'],
    'Couchbase\MatchNoneSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\MatchPhraseSearchQuery::__construct' => ['void'],
    'Couchbase\MatchPhraseSearchQuery::analyzer' => ['Couchbase\MatchPhraseSearchQuery', 'analyzer'=>'string'],
    'Couchbase\MatchPhraseSearchQuery::boost' => ['Couchbase\MatchPhraseSearchQuery', 'boost'=>'float'],
    'Couchbase\MatchPhraseSearchQuery::field' => ['Couchbase\MatchPhraseSearchQuery', 'field'=>'string'],
    'Couchbase\MatchPhraseSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\MatchSearchQuery::__construct' => ['void'],
    'Couchbase\MatchSearchQuery::analyzer' => ['Couchbase\MatchSearchQuery', 'analyzer'=>'string'],
    'Couchbase\MatchSearchQuery::boost' => ['Couchbase\MatchSearchQuery', 'boost'=>'float'],
    'Couchbase\MatchSearchQuery::field' => ['Couchbase\MatchSearchQuery', 'field'=>'string'],
    'Couchbase\MatchSearchQuery::fuzziness' => ['Couchbase\MatchSearchQuery', 'fuzziness'=>'int'],
    'Couchbase\MatchSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\MatchSearchQuery::prefixLength' => ['Couchbase\MatchSearchQuery', 'prefixLength'=>'int'],
    'Couchbase\MutateInBuilder::__construct' => ['void'],
    'Couchbase\MutateInBuilder::arrayAddUnique' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::arrayAppend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::arrayAppendAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::arrayInsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'],
    'Couchbase\MutateInBuilder::arrayInsertAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array'],
    'Couchbase\MutateInBuilder::arrayPrepend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::arrayPrependAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::counter' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'delta'=>'int', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::execute' => ['Couchbase\DocumentFragment'],
    'Couchbase\MutateInBuilder::insert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::modeDocument' => ['', 'mode'=>'int'],
    'Couchbase\MutateInBuilder::remove' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'options='=>'array'],
    'Couchbase\MutateInBuilder::replace' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'],
    'Couchbase\MutateInBuilder::upsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
    'Couchbase\MutateInBuilder::withExpiry' => ['Couchbase\MutateInBuilder', 'expiry'=>'Couchbase\expiry'],
    'Couchbase\MutationState::__construct' => ['void'],
    'Couchbase\MutationState::add' => ['', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'],
    'Couchbase\MutationState::from' => ['Couchbase\MutationState', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'],
    'Couchbase\MutationToken::__construct' => ['void'],
    'Couchbase\MutationToken::bucketName' => ['string'],
    'Couchbase\MutationToken::from' => ['', 'bucketName'=>'string', 'vbucketId'=>'int', 'vbucketUuid'=>'string', 'sequenceNumber'=>'string'],
    'Couchbase\MutationToken::sequenceNumber' => ['string'],
    'Couchbase\MutationToken::vbucketId' => ['int'],
    'Couchbase\MutationToken::vbucketUuid' => ['string'],
    'Couchbase\N1qlIndex::__construct' => ['void'],
    'Couchbase\N1qlQuery::__construct' => ['void'],
    'Couchbase\N1qlQuery::adhoc' => ['Couchbase\N1qlQuery', 'adhoc'=>'bool'],
    'Couchbase\N1qlQuery::consistency' => ['Couchbase\N1qlQuery', 'consistency'=>'int'],
    'Couchbase\N1qlQuery::consistentWith' => ['Couchbase\N1qlQuery', 'state'=>'Couchbase\MutationState'],
    'Couchbase\N1qlQuery::crossBucket' => ['Couchbase\N1qlQuery', 'crossBucket'=>'bool'],
    'Couchbase\N1qlQuery::fromString' => ['Couchbase\N1qlQuery', 'statement'=>'string'],
    'Couchbase\N1qlQuery::maxParallelism' => ['Couchbase\N1qlQuery', 'maxParallelism'=>'int'],
    'Couchbase\N1qlQuery::namedParams' => ['Couchbase\N1qlQuery', 'params'=>'array'],
    'Couchbase\N1qlQuery::pipelineBatch' => ['Couchbase\N1qlQuery', 'pipelineBatch'=>'int'],
    'Couchbase\N1qlQuery::pipelineCap' => ['Couchbase\N1qlQuery', 'pipelineCap'=>'int'],
    'Couchbase\N1qlQuery::positionalParams' => ['Couchbase\N1qlQuery', 'params'=>'array'],
    'Couchbase\N1qlQuery::profile' => ['', 'profileType'=>'string'],
    'Couchbase\N1qlQuery::readonly' => ['Couchbase\N1qlQuery', 'readonly'=>'bool'],
    'Couchbase\N1qlQuery::scanCap' => ['Couchbase\N1qlQuery', 'scanCap'=>'int'],
    'Couchbase\NumericRangeSearchFacet::__construct' => ['void'],
    'Couchbase\NumericRangeSearchFacet::addRange' => ['Couchbase\NumericRangeSearchFacet', 'name'=>'string', 'min'=>'float', 'max'=>'float'],
    'Couchbase\NumericRangeSearchFacet::jsonSerialize' => ['array'],
    'Couchbase\NumericRangeSearchQuery::__construct' => ['void'],
    'Couchbase\NumericRangeSearchQuery::boost' => ['Couchbase\NumericRangeSearchQuery', 'boost'=>'float'],
    'Couchbase\NumericRangeSearchQuery::field' => ['Couchbase\NumericRangeSearchQuery', 'field'=>'string'],
    'Couchbase\NumericRangeSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\NumericRangeSearchQuery::max' => ['Couchbase\NumericRangeSearchQuery', 'max'=>'float', 'inclusive='=>'bool'],
    'Couchbase\NumericRangeSearchQuery::min' => ['Couchbase\NumericRangeSearchQuery', 'min'=>'float', 'inclusive='=>'bool'],
    'Couchbase\PasswordAuthenticator::password' => ['Couchbase\PasswordAuthenticator', 'password'=>'string'],
    'Couchbase\PasswordAuthenticator::username' => ['Couchbase\PasswordAuthenticator', 'username'=>'string'],
    'Couchbase\PhraseSearchQuery::__construct' => ['void'],
    'Couchbase\PhraseSearchQuery::boost' => ['Couchbase\PhraseSearchQuery', 'boost'=>'float'],
    'Couchbase\PhraseSearchQuery::field' => ['Couchbase\PhraseSearchQuery', 'field'=>'string'],
    'Couchbase\PhraseSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\PrefixSearchQuery::__construct' => ['void'],
    'Couchbase\PrefixSearchQuery::boost' => ['Couchbase\PrefixSearchQuery', 'boost'=>'float'],
    'Couchbase\PrefixSearchQuery::field' => ['Couchbase\PrefixSearchQuery', 'field'=>'string'],
    'Couchbase\PrefixSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\QueryStringSearchQuery::__construct' => ['void'],
    'Couchbase\QueryStringSearchQuery::boost' => ['Couchbase\QueryStringSearchQuery', 'boost'=>'float'],
    'Couchbase\QueryStringSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\RegexpSearchQuery::__construct' => ['void'],
    'Couchbase\RegexpSearchQuery::boost' => ['Couchbase\RegexpSearchQuery', 'boost'=>'float'],
    'Couchbase\RegexpSearchQuery::field' => ['Couchbase\RegexpSearchQuery', 'field'=>'string'],
    'Couchbase\RegexpSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\SearchQuery::__construct' => ['void', 'indexName'=>'string', 'queryPart'=>'Couchbase\SearchQueryPart'],
    'Couchbase\SearchQuery::addFacet' => ['Couchbase\SearchQuery', 'name'=>'string', 'facet'=>'Couchbase\SearchFacet'],
    'Couchbase\SearchQuery::boolean' => ['Couchbase\BooleanSearchQuery'],
    'Couchbase\SearchQuery::booleanField' => ['Couchbase\BooleanFieldSearchQuery', 'value'=>'bool'],
    'Couchbase\SearchQuery::conjuncts' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
    'Couchbase\SearchQuery::consistentWith' => ['Couchbase\SearchQuery', 'state'=>'Couchbase\MutationState'],
    'Couchbase\SearchQuery::dateRange' => ['Couchbase\DateRangeSearchQuery'],
    'Couchbase\SearchQuery::dateRangeFacet' => ['Couchbase\DateRangeSearchFacet', 'field'=>'string', 'limit'=>'int'],
    'Couchbase\SearchQuery::disjuncts' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
    'Couchbase\SearchQuery::docId' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array<int,string>'],
    'Couchbase\SearchQuery::explain' => ['Couchbase\SearchQuery', 'explain'=>'bool'],
    'Couchbase\SearchQuery::fields' => ['Couchbase\SearchQuery', '...fields='=>'array<int,string>'],
    'Couchbase\SearchQuery::geoBoundingBox' => ['Couchbase\GeoBoundingBoxSearchQuery', 'topLeftLongitude'=>'float', 'topLeftLatitude'=>'float', 'bottomRightLongitude'=>'float', 'bottomRightLatitude'=>'float'],
    'Couchbase\SearchQuery::geoDistance' => ['Couchbase\GeoDistanceSearchQuery', 'longitude'=>'float', 'latitude'=>'float', 'distance'=>'string'],
    'Couchbase\SearchQuery::highlight' => ['Couchbase\SearchQuery', 'style'=>'string', '...fields='=>'array<int,string>'],
    'Couchbase\SearchQuery::jsonSerialize' => ['array'],
    'Couchbase\SearchQuery::limit' => ['Couchbase\SearchQuery', 'limit'=>'int'],
    'Couchbase\SearchQuery::match' => ['Couchbase\MatchSearchQuery', 'match'=>'string'],
    'Couchbase\SearchQuery::matchAll' => ['Couchbase\MatchAllSearchQuery'],
    'Couchbase\SearchQuery::matchNone' => ['Couchbase\MatchNoneSearchQuery'],
    'Couchbase\SearchQuery::matchPhrase' => ['Couchbase\MatchPhraseSearchQuery', '...terms='=>'array<int,string>'],
    'Couchbase\SearchQuery::numericRange' => ['Couchbase\NumericRangeSearchQuery'],
    'Couchbase\SearchQuery::numericRangeFacet' => ['Couchbase\NumericRangeSearchFacet', 'field'=>'string', 'limit'=>'int'],
    'Couchbase\SearchQuery::prefix' => ['Couchbase\PrefixSearchQuery', 'prefix'=>'string'],
    'Couchbase\SearchQuery::queryString' => ['Couchbase\QueryStringSearchQuery', 'queryString'=>'string'],
    'Couchbase\SearchQuery::regexp' => ['Couchbase\RegexpSearchQuery', 'regexp'=>'string'],
    'Couchbase\SearchQuery::serverSideTimeout' => ['Couchbase\SearchQuery', 'serverSideTimeout'=>'int'],
    'Couchbase\SearchQuery::skip' => ['Couchbase\SearchQuery', 'skip'=>'int'],
    'Couchbase\SearchQuery::sort' => ['Couchbase\SearchQuery', '...sort='=>'array<int,Couchbase\sort>'],
    'Couchbase\SearchQuery::term' => ['Couchbase\TermSearchQuery', 'term'=>'string'],
    'Couchbase\SearchQuery::termFacet' => ['Couchbase\TermSearchFacet', 'field'=>'string', 'limit'=>'int'],
    'Couchbase\SearchQuery::termRange' => ['Couchbase\TermRangeSearchQuery'],
    'Couchbase\SearchQuery::wildcard' => ['Couchbase\WildcardSearchQuery', 'wildcard'=>'string'],
    'Couchbase\SearchSort::__construct' => ['void'],
    'Couchbase\SearchSort::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
    'Couchbase\SearchSort::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
    'Couchbase\SearchSort::id' => ['Couchbase\SearchSortId'],
    'Couchbase\SearchSort::score' => ['Couchbase\SearchSortScore'],
    'Couchbase\SearchSortField::__construct' => ['void'],
    'Couchbase\SearchSortField::descending' => ['Couchbase\SearchSortField', 'descending'=>'bool'],
    'Couchbase\SearchSortField::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
    'Couchbase\SearchSortField::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
    'Couchbase\SearchSortField::id' => ['Couchbase\SearchSortId'],
    'Couchbase\SearchSortField::jsonSerialize' => ['mixed'],
    'Couchbase\SearchSortField::missing' => ['', 'missing'=>'string'],
    'Couchbase\SearchSortField::mode' => ['', 'mode'=>'string'],
    'Couchbase\SearchSortField::score' => ['Couchbase\SearchSortScore'],
    'Couchbase\SearchSortField::type' => ['', 'type'=>'string'],
    'Couchbase\SearchSortGeoDistance::__construct' => ['void'],
    'Couchbase\SearchSortGeoDistance::descending' => ['Couchbase\SearchSortGeoDistance', 'descending'=>'bool'],
    'Couchbase\SearchSortGeoDistance::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
    'Couchbase\SearchSortGeoDistance::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
    'Couchbase\SearchSortGeoDistance::id' => ['Couchbase\SearchSortId'],
    'Couchbase\SearchSortGeoDistance::jsonSerialize' => ['mixed'],
    'Couchbase\SearchSortGeoDistance::score' => ['Couchbase\SearchSortScore'],
    'Couchbase\SearchSortGeoDistance::unit' => ['Couchbase\SearchSortGeoDistance', 'unit'=>'string'],
    'Couchbase\SearchSortId::__construct' => ['void'],
    'Couchbase\SearchSortId::descending' => ['Couchbase\SearchSortId', 'descending'=>'bool'],
    'Couchbase\SearchSortId::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
    'Couchbase\SearchSortId::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
    'Couchbase\SearchSortId::id' => ['Couchbase\SearchSortId'],
    'Couchbase\SearchSortId::jsonSerialize' => ['mixed'],
    'Couchbase\SearchSortId::score' => ['Couchbase\SearchSortScore'],
    'Couchbase\SearchSortScore::__construct' => ['void'],
    'Couchbase\SearchSortScore::descending' => ['Couchbase\SearchSortScore', 'descending'=>'bool'],
    'Couchbase\SearchSortScore::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
    'Couchbase\SearchSortScore::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
    'Couchbase\SearchSortScore::id' => ['Couchbase\SearchSortId'],
    'Couchbase\SearchSortScore::jsonSerialize' => ['mixed'],
    'Couchbase\SearchSortScore::score' => ['Couchbase\SearchSortScore'],
    'Couchbase\SpatialViewQuery::__construct' => ['void'],
    'Couchbase\SpatialViewQuery::bbox' => ['Couchbase\SpatialViewQuery', 'bbox'=>'array'],
    'Couchbase\SpatialViewQuery::consistency' => ['Couchbase\SpatialViewQuery', 'consistency'=>'int'],
    'Couchbase\SpatialViewQuery::custom' => ['', 'customParameters'=>'array'],
    'Couchbase\SpatialViewQuery::encode' => ['array'],
    'Couchbase\SpatialViewQuery::endRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'],
    'Couchbase\SpatialViewQuery::limit' => ['Couchbase\SpatialViewQuery', 'limit'=>'int'],
    'Couchbase\SpatialViewQuery::order' => ['Couchbase\SpatialViewQuery', 'order'=>'int'],
    'Couchbase\SpatialViewQuery::skip' => ['Couchbase\SpatialViewQuery', 'skip'=>'int'],
    'Couchbase\SpatialViewQuery::startRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'],
    'Couchbase\TermRangeSearchQuery::__construct' => ['void'],
    'Couchbase\TermRangeSearchQuery::boost' => ['Couchbase\TermRangeSearchQuery', 'boost'=>'float'],
    'Couchbase\TermRangeSearchQuery::field' => ['Couchbase\TermRangeSearchQuery', 'field'=>'string'],
    'Couchbase\TermRangeSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\TermRangeSearchQuery::max' => ['Couchbase\TermRangeSearchQuery', 'max'=>'string', 'inclusive='=>'bool'],
    'Couchbase\TermRangeSearchQuery::min' => ['Couchbase\TermRangeSearchQuery', 'min'=>'string', 'inclusive='=>'bool'],
    'Couchbase\TermSearchFacet::__construct' => ['void'],
    'Couchbase\TermSearchFacet::jsonSerialize' => ['array'],
    'Couchbase\TermSearchQuery::__construct' => ['void'],
    'Couchbase\TermSearchQuery::boost' => ['Couchbase\TermSearchQuery', 'boost'=>'float'],
    'Couchbase\TermSearchQuery::field' => ['Couchbase\TermSearchQuery', 'field'=>'string'],
    'Couchbase\TermSearchQuery::fuzziness' => ['Couchbase\TermSearchQuery', 'fuzziness'=>'int'],
    'Couchbase\TermSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\TermSearchQuery::prefixLength' => ['Couchbase\TermSearchQuery', 'prefixLength'=>'int'],
    'Couchbase\UserSettings::fullName' => ['Couchbase\UserSettings', 'fullName'=>'string'],
    'Couchbase\UserSettings::password' => ['Couchbase\UserSettings', 'password'=>'string'],
    'Couchbase\UserSettings::role' => ['Couchbase\UserSettings', 'role'=>'string', 'bucket='=>'string'],
    'Couchbase\ViewQuery::__construct' => ['void'],
    'Couchbase\ViewQuery::consistency' => ['Couchbase\ViewQuery', 'consistency'=>'int'],
    'Couchbase\ViewQuery::custom' => ['Couchbase\ViewQuery', 'customParameters'=>'array'],
    'Couchbase\ViewQuery::encode' => ['array'],
    'Couchbase\ViewQuery::from' => ['Couchbase\ViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'],
    'Couchbase\ViewQuery::fromSpatial' => ['Couchbase\SpatialViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'],
    'Couchbase\ViewQuery::group' => ['Couchbase\ViewQuery', 'group'=>'bool'],
    'Couchbase\ViewQuery::groupLevel' => ['Couchbase\ViewQuery', 'groupLevel'=>'int'],
    'Couchbase\ViewQuery::idRange' => ['Couchbase\ViewQuery', 'startKeyDocumentId'=>'string', 'endKeyDocumentId'=>'string'],
    'Couchbase\ViewQuery::key' => ['Couchbase\ViewQuery', 'key'=>'mixed'],
    'Couchbase\ViewQuery::keys' => ['Couchbase\ViewQuery', 'keys'=>'array'],
    'Couchbase\ViewQuery::limit' => ['Couchbase\ViewQuery', 'limit'=>'int'],
    'Couchbase\ViewQuery::order' => ['Couchbase\ViewQuery', 'order'=>'int'],
    'Couchbase\ViewQuery::range' => ['Couchbase\ViewQuery', 'startKey'=>'mixed', 'endKey'=>'mixed', 'inclusiveEnd='=>'bool'],
    'Couchbase\ViewQuery::reduce' => ['Couchbase\ViewQuery', 'reduce'=>'bool'],
    'Couchbase\ViewQuery::skip' => ['Couchbase\ViewQuery', 'skip'=>'int'],
    'Couchbase\ViewQueryEncodable::encode' => ['array'],
    'Couchbase\WildcardSearchQuery::__construct' => ['void'],
    'Couchbase\WildcardSearchQuery::boost' => ['Couchbase\WildcardSearchQuery', 'boost'=>'float'],
    'Couchbase\WildcardSearchQuery::field' => ['Couchbase\WildcardSearchQuery', 'field'=>'string'],
    'Couchbase\WildcardSearchQuery::jsonSerialize' => ['array'],
    'Couchbase\basicDecoderV1' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int', 'options'=>'array'],
    'Couchbase\basicEncoderV1' => ['array', 'value'=>'mixed', 'options'=>'array'],
    'Couchbase\defaultDecoder' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'],
    'Couchbase\defaultEncoder' => ['array', 'value'=>'mixed'],
    'Couchbase\fastlzCompress' => ['string', 'data'=>'string'],
    'Couchbase\fastlzDecompress' => ['string', 'data'=>'string'],
    'Couchbase\passthruDecoder' => ['string', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'],
    'Couchbase\passthruEncoder' => ['array', 'value'=>'string'],
    'Couchbase\zlibCompress' => ['string', 'data'=>'string'],
    'Couchbase\zlibDecompress' => ['string', 'data'=>'string'],
    'Countable::count' => ['int'],
    'DOMAttr::__construct' => ['void', 'name'=>'string', 'value='=>'string'],
    'DOMAttr::getLineNo' => ['int'],
    'DOMAttr::getNodePath' => ['?string'],
    'DOMAttr::hasAttributes' => ['bool'],
    'DOMAttr::hasChildNodes' => ['bool'],
    'DOMAttr::insertBefore' => ['DOMNode', 'newnode'=>'DOMNode', 'refnode='=>'DOMNode'],
    'DOMAttr::isDefaultNamespace' => ['bool', 'namespaceuri'=>'string'],
    'DOMAttr::isId' => ['bool'],
    'DOMAttr::isSameNode' => ['bool', 'node'=>'DOMNode'],
    'DOMAttr::isSupported' => ['bool', 'feature'=>'string', 'version'=>'string'],
    'DOMAttr::lookupNamespaceUri' => ['string|null', 'prefix'=>'string|null'],
    'DOMAttr::lookupPrefix' => ['string|null', 'namespaceuri'=>'string'],
    'DOMAttr::normalize' => ['void'],
    'DOMAttr::removeChild' => ['DOMNode', 'oldnode'=>'DOMNode'],
    'DOMAttr::replaceChild' => ['DOMNode', 'newnode'=>'DOMNode', 'oldnode'=>'DOMNode'],
    'DOMCdataSection::__construct' => ['void', 'value'=>'string'],
    'DOMCharacterData::appendData' => ['true', 'data'=>'string'],
    'DOMCharacterData::deleteData' => ['bool', 'offset'=>'int', 'count'=>'int'],
    'DOMCharacterData::insertData' => ['bool', 'offset'=>'int', 'data'=>'string'],
    'DOMCharacterData::replaceData' => ['bool', 'offset'=>'int', 'count'=>'int', 'data'=>'string'],
    'DOMCharacterData::substringData' => ['string', 'offset'=>'int', 'count'=>'int'],
    'DOMComment::__construct' => ['void', 'value='=>'string'],
    'DOMDocument::__construct' => ['void', 'version='=>'string', 'encoding='=>'string'],
    'DOMDocument::createAttribute' => ['DOMAttr|false', 'name'=>'string'],
    'DOMDocument::createAttributeNS' => ['DOMAttr|false', 'namespaceuri'=>'string|null', 'qualifiedname'=>'string'],
    'DOMDocument::createCDATASection' => ['DOMCDATASection|false', 'data'=>'string'],
    'DOMDocument::createComment' => ['DOMComment|false', 'data'=>'string'],
    'DOMDocument::createDocumentFragment' => ['DOMDocumentFragment|false'],
    'DOMDocument::createElement' => ['DOMElement|false', 'name'=>'string', 'value='=>'string'],
    'DOMDocument::createElementNS' => ['DOMElement|false', 'namespaceuri'=>'string|null', 'qualifiedname'=>'string', 'value='=>'string'],
    'DOMDocument::createEntityReference' => ['DOMEntityReference|false', 'name'=>'string'],
    'DOMDocument::createProcessingInstruction' => ['DOMProcessingInstruction|false', 'target'=>'string', 'data='=>'string'],
    'DOMDocument::createTextNode' => ['DOMText|false', 'content'=>'string'],
    'DOMDocument::getElementById' => ['?DOMElement', 'elementid'=>'string'],
    'DOMDocument::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'],
    'DOMDocument::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string|null', 'localname'=>'string'],
    'DOMDocument::importNode' => ['DOMNode|false', 'importednode'=>'DOMNode', 'deep='=>'bool'],
    'DOMDocument::load' => ['DOMDocument|bool', 'filename'=>'string', 'options='=>'int'],
    'DOMDocument::loadHTML' => ['bool', 'source'=>'non-empty-string', 'options='=>'int'],
    'DOMDocument::loadHTMLFile' => ['bool', 'filename'=>'string', 'options='=>'int'],
    'DOMDocument::loadXML' => ['DOMDocument|bool', 'source'=>'non-empty-string', 'options='=>'int'],
    'DOMDocument::normalizeDocument' => ['void'],
    'DOMDocument::registerNodeClass' => ['bool', 'baseclass'=>'string', 'extendedclass'=>'string'],
    'DOMDocument::relaxNGValidate' => ['bool', 'filename'=>'string'],
    'DOMDocument::relaxNGValidateSource' => ['bool', 'source'=>'string'],
    'DOMDocument::save' => ['int|false', 'filename'=>'string', 'options='=>'int'],
    'DOMDocument::saveHTML' => ['string|false', 'node='=>'?DOMNode'],
    'DOMDocument::saveHTMLFile' => ['int|false', 'filename'=>'string'],
    'DOMDocument::saveXML' => ['string|false', 'node='=>'?DOMNode', 'options='=>'int'],
    'DOMDocument::schemaValidate' => ['bool', 'filename'=>'string', 'flags='=>'int'],
    'DOMDocument::schemaValidateSource' => ['bool', 'source'=>'string', 'flags='=>'int'],
    'DOMDocument::validate' => ['bool'],
    'DOMDocument::xinclude' => ['int', 'options='=>'int'],
    'DOMDocumentFragment::__construct' => ['void'],
    'DOMDocumentFragment::appendXML' => ['bool', 'data'=>'string'],
    'DOMElement::__construct' => ['void', 'name'=>'string', 'value='=>'string', 'uri='=>'string'],
    'DOMElement::getAttribute' => ['string', 'name'=>'string'],
    'DOMElement::getAttributeNS' => ['string', 'namespaceuri'=>'string|null', 'localname'=>'string'],
    'DOMElement::getAttributeNode' => ['DOMAttr', 'name'=>'string'],
    'DOMElement::getAttributeNodeNS' => ['DOMAttr', 'namespaceuri'=>'string|null', 'localname'=>'string'],
    'DOMElement::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'],
    'DOMElement::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string|null', 'localname'=>'string'],
    'DOMElement::hasAttribute' => ['bool', 'name'=>'string'],
    'DOMElement::hasAttributeNS' => ['bool', 'namespaceuri'=>'string|null', 'localname'=>'string'],
    'DOMElement::removeAttribute' => ['bool', 'name'=>'string'],
    'DOMElement::removeAttributeNS' => ['bool', 'namespaceuri'=>'string|null', 'localname'=>'string'],
    'DOMElement::removeAttributeNode' => ['bool', 'oldnode'=>'DOMAttr'],
    'DOMElement::setAttribute' => ['DOMAttr|false', 'name'=>'string', 'value'=>'string'],
    'DOMElement::setAttributeNS' => ['void', 'namespaceuri'=>'string|null', 'qualifiedname'=>'string', 'value'=>'string'],
    'DOMElement::setAttributeNode' => ['?DOMAttr', 'attr'=>'DOMAttr'],
    'DOMElement::setAttributeNodeNS' => ['DOMAttr', 'attr'=>'DOMAttr'],
    'DOMElement::setIdAttribute' => ['void', 'name'=>'string', 'isid'=>'bool'],
    'DOMElement::setIdAttributeNS' => ['void', 'namespaceuri'=>'string', 'localname'=>'string', 'isid'=>'bool'],
    'DOMElement::setIdAttributeNode' => ['void', 'attr'=>'DOMAttr', 'isid'=>'bool'],
    'DOMEntityReference::__construct' => ['void', 'name'=>'string'],
    'DOMImplementation::__construct' => ['void'],
    'DOMImplementation::createDocument' => ['DOMDocument', 'namespaceuri='=>'string', 'qualifiedname='=>'string', 'doctype='=>'DOMDocumentType'],
    'DOMImplementation::createDocumentType' => ['DOMDocumentType', 'qualifiedname='=>'string', 'publicid='=>'string', 'systemid='=>'string'],
    'DOMImplementation::hasFeature' => ['bool', 'feature'=>'string', 'version'=>'string'],
    'DOMNamedNodeMap::count' => ['int'],
    'DOMNamedNodeMap::getNamedItem' => ['?DOMNode', 'name'=>'string'],
    'DOMNamedNodeMap::getNamedItemNS' => ['?DOMNode', 'namespaceuri'=>'string', 'localname'=>'string'],
    'DOMNamedNodeMap::item' => ['?DOMNode', 'index'=>'int'],
    'DOMNode::C14N' => ['string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'],
    'DOMNode::C14NFile' => ['int|false', 'uri='=>'string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'],
    'DOMNode::appendChild' => ['DOMNode', 'newnode'=>'DOMNode'],
    'DOMNode::cloneNode' => ['DOMNode', 'deep='=>'bool'],
    'DOMNode::getLineNo' => ['int'],
    'DOMNode::getNodePath' => ['?string'],
    'DOMNode::hasAttributes' => ['bool'],
    'DOMNode::hasChildNodes' => ['bool'],
    'DOMNode::insertBefore' => ['DOMNode', 'newnode'=>'DOMNode', 'refnode='=>'DOMNode|null'],
    'DOMNode::isDefaultNamespace' => ['bool', 'namespaceuri'=>'string'],
    'DOMNode::isSameNode' => ['bool', 'node'=>'DOMNode'],
    'DOMNode::isSupported' => ['bool', 'feature'=>'string', 'version'=>'string'],
    'DOMNode::lookupNamespaceURI' => ['string|null', 'prefix'=>'string|null'],
    'DOMNode::lookupPrefix' => ['string|null', 'namespaceuri'=>'string'],
    'DOMNode::normalize' => ['void'],
    'DOMNode::removeChild' => ['DOMNode', 'oldnode'=>'DOMNode'],
    'DOMNode::replaceChild' => ['DOMNode|false', 'newnode'=>'DOMNode', 'oldnode'=>'DOMNode'],
    'DOMNodeList::item' => ['?DOMNode', 'index'=>'int'],
    'DOMProcessingInstruction::__construct' => ['void', 'name'=>'string', 'value'=>'string'],
    'DOMText::__construct' => ['void', 'value='=>'string'],
    'DOMText::isElementContentWhitespace' => ['bool'],
    'DOMText::isWhitespaceInElementContent' => ['bool'],
    'DOMText::splitText' => ['DOMText', 'offset'=>'int'],
    'DOMXPath::__construct' => ['void', 'doc'=>'DOMDocument'],
    'DOMXPath::evaluate' => ['mixed', 'expression'=>'string', 'contextnode='=>'?DOMNode', 'registernodens='=>'bool'],
    'DOMXPath::query' => ['DOMNodeList|false', 'expression'=>'string', 'contextnode='=>'DOMNode|null', 'registernodens='=>'bool'],
    'DOMXPath::registerNamespace' => ['bool', 'prefix'=>'string', 'namespaceuri'=>'string'],
    'DOMXPath::registerPhpFunctions' => ['void', 'restrict='=>'mixed'],
    'DOTNET::__call' => ['mixed', 'name'=>'string', 'args'=>''],
    'DOTNET::__construct' => ['void', 'assembly_name'=>'string', 'datatype_name'=>'string', 'codepage='=>'int'],
    'DOTNET::__get' => ['mixed', 'name'=>'string'],
    'DOTNET::__set' => ['void', 'name'=>'string', 'value'=>''],
    'DateInterval::__construct' => ['void', 'spec'=>'string'],
    'DateInterval::__set_state' => ['DateInterval', 'array'=>'array'],
    'DateInterval::__wakeup' => ['void'],
    'DateInterval::createFromDateString' => ['DateInterval|false', 'time'=>'string'],
    'DateInterval::format' => ['string', 'format'=>'string'],
    'DatePeriod::__construct' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'recur'=>'int', 'options='=>'int'],
    'DatePeriod::__construct\'1' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'end'=>'DateTimeInterface', 'options='=>'int'],
    'DatePeriod::__construct\'2' => ['void', 'iso'=>'string', 'options='=>'int'],
    'DatePeriod::__wakeup' => ['void'],
    'DatePeriod::getDateInterval' => ['DateInterval'],
    'DatePeriod::getEndDate' => ['?DateTimeInterface'],
    'DatePeriod::getStartDate' => ['DateTimeInterface'],
    'DateTime::__construct' => ['void', 'time='=>'string'],
    'DateTime::__construct\'1' => ['void', 'time'=>'?string', 'timezone'=>'?DateTimeZone'],
    'DateTime::__wakeup' => ['void'],
    'DateTime::add' => ['static', 'interval'=>'DateInterval'],
    'DateTime::createFromFormat' => ['static|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'?DateTimeZone'],
    'DateTime::diff' => ['DateInterval|false', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'],
    'DateTime::format' => ['string|false', 'format'=>'string'],
    'DateTime::getLastErrors' => ['array{warning_count:int,warnings:array<int,string>,error_count:int,errors:array<int,string>}|false'],
    'DateTime::getOffset' => ['int'],
    'DateTime::getTimestamp' => ['int|false'],
    'DateTime::getTimezone' => ['DateTimeZone|false'],
    'DateTime::modify' => ['static|false', 'modify'=>'string'],
    'DateTime::setDate' => ['static', 'year'=>'int', 'month'=>'int', 'day'=>'int'],
    'DateTime::setISODate' => ['static', 'year'=>'int', 'week'=>'int', 'day='=>'int'],
    'DateTime::setTime' => ['static|false', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'],
    'DateTime::setTimestamp' => ['static', 'unixtimestamp'=>'int'],
    'DateTime::setTimezone' => ['static', 'timezone'=>'DateTimeZone'],
    'DateTime::sub' => ['static', 'interval'=>'DateInterval'],
    'DateTimeImmutable::__wakeup' => ['void'],
    'DateTimeImmutable::getLastErrors' => ['array{warning_count:int,warnings:array<int,string>,error_count:int,errors:array<int,string>}|false'],
    'DateTimeInterface::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'],
    'DateTimeInterface::format' => ['string', 'format'=>'string'],
    'DateTimeInterface::getOffset' => ['int'],
    'DateTimeInterface::getTimestamp' => ['int|false'],
    'DateTimeInterface::getTimezone' => ['DateTimeZone|false'],
    'DateTimeZone::__construct' => ['void', 'timezone'=>'string'],
    'DateTimeZone::__set_state' => ['DateTimeZone', 'array'=>'array'],
    'DateTimeZone::__wakeup' => ['void'],
    'DateTimeZone::getLocation' => ['array|false'],
    'DateTimeZone::getName' => ['string'],
    'DateTimeZone::getOffset' => ['int|false', 'datetime'=>'DateTimeInterface'],
    'DateTimeZone::getTransitions' => ['list<array{ts: int, time: string, offset: int, isdst: bool, abbr: string}>|false', 'timestamp_begin='=>'int', 'timestamp_end='=>'int'],
    'DateTimeZone::listAbbreviations' => ['array<string, list<array{dst: bool, offset: int, timezone_id: string|null}>>'],
    'DateTimeZone::listIdentifiers' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'string'],
    'Directory::close' => ['void', 'dir_handle='=>'resource'],
    'Directory::read' => ['string|false', 'dir_handle='=>'resource'],
    'Directory::rewind' => ['void', 'dir_handle='=>'resource'],
    'DirectoryIterator::__construct' => ['void', 'path'=>'string'],
    'DirectoryIterator::__toString' => ['string'],
    'DirectoryIterator::current' => ['DirectoryIterator'],
    'DirectoryIterator::getATime' => ['int'],
    'DirectoryIterator::getBasename' => ['string', 'suffix='=>'string'],
    'DirectoryIterator::getCTime' => ['int'],
    'DirectoryIterator::getExtension' => ['string'],
    'DirectoryIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'DirectoryIterator::getFilename' => ['string'],
    'DirectoryIterator::getGroup' => ['int'],
    'DirectoryIterator::getInode' => ['int'],
    'DirectoryIterator::getLinkTarget' => ['string'],
    'DirectoryIterator::getMTime' => ['int'],
    'DirectoryIterator::getOwner' => ['int'],
    'DirectoryIterator::getPath' => ['string'],
    'DirectoryIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'DirectoryIterator::getPathname' => ['string'],
    'DirectoryIterator::getPerms' => ['int'],
    'DirectoryIterator::getRealPath' => ['string'],
    'DirectoryIterator::getSize' => ['int'],
    'DirectoryIterator::getType' => ['string'],
    'DirectoryIterator::isDir' => ['bool'],
    'DirectoryIterator::isDot' => ['bool'],
    'DirectoryIterator::isExecutable' => ['bool'],
    'DirectoryIterator::isFile' => ['bool'],
    'DirectoryIterator::isLink' => ['bool'],
    'DirectoryIterator::isReadable' => ['bool'],
    'DirectoryIterator::isWritable' => ['bool'],
    'DirectoryIterator::key' => ['string'],
    'DirectoryIterator::next' => ['void'],
    'DirectoryIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
    'DirectoryIterator::rewind' => ['void'],
    'DirectoryIterator::seek' => ['void', 'position'=>'int'],
    'DirectoryIterator::setFileClass' => ['void', 'class_name='=>'string'],
    'DirectoryIterator::setInfoClass' => ['void', 'class_name='=>'string'],
    'DirectoryIterator::valid' => ['bool'],
    'DomAttribute::name' => ['string'],
    'DomAttribute::set_value' => ['bool', 'content'=>'string'],
    'DomAttribute::specified' => ['bool'],
    'DomAttribute::value' => ['string'],
    'DomXsltStylesheet::process' => ['DomDocument', 'xml_doc'=>'DOMDocument', 'xslt_params='=>'array', 'is_xpath_param='=>'bool', 'profile_filename='=>'string'],
    'DomXsltStylesheet::result_dump_file' => ['string', 'xmldoc'=>'DOMDocument', 'filename'=>'string'],
    'DomXsltStylesheet::result_dump_mem' => ['string', 'xmldoc'=>'DOMDocument'],
    'DomainException::__clone' => ['void'],
    'DomainException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'DomainException::__toString' => ['string'],
    'DomainException::__wakeup' => ['void'],
    'DomainException::getCode' => ['int'],
    'DomainException::getFile' => ['string'],
    'DomainException::getLine' => ['int'],
    'DomainException::getMessage' => ['string'],
    'DomainException::getPrevious' => ['?Throwable'],
    'DomainException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'DomainException::getTraceAsString' => ['string'],
    'Ds\Collection::clear' => ['void'],
    'Ds\Collection::copy' => ['Ds\Collection'],
    'Ds\Collection::isEmpty' => ['bool'],
    'Ds\Collection::toArray' => ['array'],
    'Ds\Deque::__construct' => ['void', 'values='=>'mixed'],
    'Ds\Deque::allocate' => ['void', 'capacity'=>'int'],
    'Ds\Deque::apply' => ['void', 'callback'=>'callable'],
    'Ds\Deque::capacity' => ['int'],
    'Ds\Deque::clear' => ['void'],
    'Ds\Deque::contains' => ['bool', '...values='=>'mixed'],
    'Ds\Deque::copy' => ['Ds\Deque'],
    'Ds\Deque::count' => ['int'],
    'Ds\Deque::filter' => ['Ds\Deque', 'callback='=>'callable'],
    'Ds\Deque::find' => ['mixed', 'value'=>'mixed'],
    'Ds\Deque::first' => ['mixed'],
    'Ds\Deque::get' => ['void', 'index'=>'int'],
    'Ds\Deque::insert' => ['void', 'index'=>'int', '...values='=>'mixed'],
    'Ds\Deque::isEmpty' => ['bool'],
    'Ds\Deque::join' => ['string', 'glue='=>'string'],
    'Ds\Deque::jsonSerialize' => ['array'],
    'Ds\Deque::last' => ['mixed'],
    'Ds\Deque::map' => ['Ds\Deque', 'callback'=>'callable'],
    'Ds\Deque::merge' => ['Ds\Deque', 'values'=>'mixed'],
    'Ds\Deque::pop' => ['mixed'],
    'Ds\Deque::push' => ['void', '...values='=>'mixed'],
    'Ds\Deque::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
    'Ds\Deque::remove' => ['mixed', 'index'=>'int'],
    'Ds\Deque::reverse' => ['void'],
    'Ds\Deque::reversed' => ['Ds\Deque'],
    'Ds\Deque::rotate' => ['void', 'rotations'=>'int'],
    'Ds\Deque::set' => ['void', 'index'=>'int', 'value'=>'mixed'],
    'Ds\Deque::shift' => ['mixed'],
    'Ds\Deque::slice' => ['Ds\Deque', 'index'=>'int', 'length='=>'?int'],
    'Ds\Deque::sort' => ['void', 'comparator='=>'callable'],
    'Ds\Deque::sorted' => ['Ds\Deque', 'comparator='=>'callable'],
    'Ds\Deque::sum' => ['int|float'],
    'Ds\Deque::toArray' => ['array'],
    'Ds\Deque::unshift' => ['void', '...values='=>'mixed'],
    'Ds\Hashable::equals' => ['bool', 'object'=>'mixed'],
    'Ds\Hashable::hash' => ['mixed'],
    'Ds\Map::__construct' => ['void', 'values='=>'mixed'],
    'Ds\Map::allocate' => ['void', 'capacity'=>'int'],
    'Ds\Map::apply' => ['void', 'callback'=>'callable'],
    'Ds\Map::capacity' => ['int'],
    'Ds\Map::clear' => ['void'],
    'Ds\Map::copy' => ['Ds\Map'],
    'Ds\Map::count' => ['int'],
    'Ds\Map::diff' => ['Ds\Map', 'map'=>'Ds\Map'],
    'Ds\Map::filter' => ['Ds\Map', 'callback='=>'callable'],
    'Ds\Map::first' => ['Ds\Pair'],
    'Ds\Map::get' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'],
    'Ds\Map::hasKey' => ['bool', 'key'=>'mixed'],
    'Ds\Map::hasValue' => ['bool', 'value'=>'mixed'],
    'Ds\Map::intersect' => ['Ds\Map', 'map'=>'Ds\Map'],
    'Ds\Map::isEmpty' => ['bool'],
    'Ds\Map::jsonSerialize' => ['array'],
    'Ds\Map::keys' => ['Ds\Set'],
    'Ds\Map::ksort' => ['void', 'comparator='=>'callable'],
    'Ds\Map::ksorted' => ['Ds\Map', 'comparator='=>'callable'],
    'Ds\Map::last' => ['Ds\Pair'],
    'Ds\Map::map' => ['Ds\Map', 'callback'=>'callable'],
    'Ds\Map::merge' => ['Ds\Map', 'values'=>'mixed'],
    'Ds\Map::pairs' => ['Ds\Sequence'],
    'Ds\Map::put' => ['void', 'key'=>'mixed', 'value'=>'mixed'],
    'Ds\Map::putAll' => ['void', 'values'=>'mixed'],
    'Ds\Map::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
    'Ds\Map::remove' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'],
    'Ds\Map::reverse' => ['void'],
    'Ds\Map::reversed' => ['Ds\Map'],
    'Ds\Map::skip' => ['Ds\Pair', 'position'=>'int'],
    'Ds\Map::slice' => ['Ds\Map', 'index'=>'int', 'length='=>'?int'],
    'Ds\Map::sort' => ['void', 'comparator='=>'callable'],
    'Ds\Map::sorted' => ['Ds\Map', 'comparator='=>'callable'],
    'Ds\Map::sum' => ['int|float'],
    'Ds\Map::toArray' => ['array'],
    'Ds\Map::union' => ['Ds\Map', 'map'=>'Ds\Map'],
    'Ds\Map::values' => ['Ds\Sequence'],
    'Ds\Map::xor' => ['Ds\Map', 'map'=>'Ds\Map'],
    'Ds\Pair::__construct' => ['void', 'key='=>'mixed', 'value='=>'mixed'],
    'Ds\Pair::clear' => ['void'],
    'Ds\Pair::copy' => ['Ds\Pair'],
    'Ds\Pair::isEmpty' => ['bool'],
    'Ds\Pair::jsonSerialize' => ['array'],
    'Ds\Pair::toArray' => ['array'],
    'Ds\PriorityQueue::__construct' => ['void'],
    'Ds\PriorityQueue::allocate' => ['void', 'capacity'=>'int'],
    'Ds\PriorityQueue::capacity' => ['int'],
    'Ds\PriorityQueue::clear' => ['void'],
    'Ds\PriorityQueue::copy' => ['Ds\PriorityQueue'],
    'Ds\PriorityQueue::count' => ['int'],
    'Ds\PriorityQueue::isEmpty' => ['bool'],
    'Ds\PriorityQueue::jsonSerialize' => ['array'],
    'Ds\PriorityQueue::peek' => ['mixed'],
    'Ds\PriorityQueue::pop' => ['mixed'],
    'Ds\PriorityQueue::push' => ['void', 'value'=>'mixed', 'priority'=>'int'],
    'Ds\PriorityQueue::toArray' => ['array'],
    'Ds\Queue::__construct' => ['void', 'values='=>'mixed'],
    'Ds\Queue::allocate' => ['void', 'capacity'=>'int'],
    'Ds\Queue::capacity' => ['int'],
    'Ds\Queue::clear' => ['void'],
    'Ds\Queue::copy' => ['Ds\Queue'],
    'Ds\Queue::count' => ['int'],
    'Ds\Queue::isEmpty' => ['bool'],
    'Ds\Queue::jsonSerialize' => ['array'],
    'Ds\Queue::peek' => ['mixed'],
    'Ds\Queue::pop' => ['mixed'],
    'Ds\Queue::push' => ['void', '...values='=>'mixed'],
    'Ds\Queue::toArray' => ['array'],
    'Ds\Sequence::allocate' => ['void', 'capacity'=>'int'],
    'Ds\Sequence::apply' => ['void', 'callback'=>'callable'],
    'Ds\Sequence::capacity' => ['int'],
    'Ds\Sequence::contains' => ['bool', '...values='=>'mixed'],
    'Ds\Sequence::filter' => ['Ds\Sequence', 'callback='=>'callable'],
    'Ds\Sequence::find' => ['mixed', 'value'=>'mixed'],
    'Ds\Sequence::first' => ['mixed'],
    'Ds\Sequence::get' => ['mixed', 'index'=>'int'],
    'Ds\Sequence::insert' => ['void', 'index'=>'int', '...values='=>'mixed'],
    'Ds\Sequence::join' => ['string', 'glue='=>'string'],
    'Ds\Sequence::last' => ['void'],
    'Ds\Sequence::map' => ['Ds\Sequence', 'callback'=>'callable'],
    'Ds\Sequence::merge' => ['Ds\Sequence', 'values'=>'mixed'],
    'Ds\Sequence::pop' => ['mixed'],
    'Ds\Sequence::push' => ['void', '...values='=>'mixed'],
    'Ds\Sequence::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
    'Ds\Sequence::remove' => ['mixed', 'index'=>'int'],
    'Ds\Sequence::reverse' => ['void'],
    'Ds\Sequence::reversed' => ['Ds\Sequence'],
    'Ds\Sequence::rotate' => ['void', 'rotations'=>'int'],
    'Ds\Sequence::set' => ['void', 'index'=>'int', 'value'=>'mixed'],
    'Ds\Sequence::shift' => ['mixed'],
    'Ds\Sequence::slice' => ['Ds\Sequence', 'index'=>'int', 'length='=>'?int'],
    'Ds\Sequence::sort' => ['void', 'comparator='=>'callable'],
    'Ds\Sequence::sorted' => ['Ds\Sequence', 'comparator='=>'callable'],
    'Ds\Sequence::sum' => ['int|float'],
    'Ds\Sequence::unshift' => ['void', '...values='=>'mixed'],
    'Ds\Set::__construct' => ['void', 'values='=>'mixed'],
    'Ds\Set::add' => ['void', '...values='=>'mixed'],
    'Ds\Set::allocate' => ['void', 'capacity'=>'int'],
    'Ds\Set::capacity' => ['int'],
    'Ds\Set::clear' => ['void'],
    'Ds\Set::contains' => ['bool', '...values='=>'mixed'],
    'Ds\Set::copy' => ['Ds\Set'],
    'Ds\Set::count' => ['int'],
    'Ds\Set::diff' => ['Ds\Set', 'set'=>'Ds\Set'],
    'Ds\Set::filter' => ['Ds\Set', 'callback='=>'callable'],
    'Ds\Set::first' => ['mixed'],
    'Ds\Set::get' => ['mixed', 'index'=>'int'],
    'Ds\Set::intersect' => ['Ds\Set', 'set'=>'Ds\Set'],
    'Ds\Set::isEmpty' => ['bool'],
    'Ds\Set::join' => ['string', 'glue='=>'string'],
    'Ds\Set::jsonSerialize' => ['array'],
    'Ds\Set::last' => ['mixed'],
    'Ds\Set::merge' => ['Ds\Set', 'values'=>'mixed'],
    'Ds\Set::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
    'Ds\Set::remove' => ['void', '...values='=>'mixed'],
    'Ds\Set::reverse' => ['void'],
    'Ds\Set::reversed' => ['Ds\Set'],
    'Ds\Set::slice' => ['Ds\Set', 'index'=>'int', 'length='=>'?int'],
    'Ds\Set::sort' => ['void', 'comparator='=>'callable'],
    'Ds\Set::sorted' => ['Ds\Set', 'comparator='=>'callable'],
    'Ds\Set::sum' => ['int|float'],
    'Ds\Set::toArray' => ['array'],
    'Ds\Set::union' => ['Ds\Set', 'set'=>'Ds\Set'],
    'Ds\Set::xor' => ['Ds\Set', 'set'=>'Ds\Set'],
    'Ds\Stack::__construct' => ['void', 'values='=>'mixed'],
    'Ds\Stack::allocate' => ['void', 'capacity'=>'int'],
    'Ds\Stack::capacity' => ['int'],
    'Ds\Stack::clear' => ['void'],
    'Ds\Stack::copy' => ['Ds\Stack'],
    'Ds\Stack::count' => ['int'],
    'Ds\Stack::isEmpty' => ['bool'],
    'Ds\Stack::jsonSerialize' => ['array'],
    'Ds\Stack::peek' => ['mixed'],
    'Ds\Stack::pop' => ['mixed'],
    'Ds\Stack::push' => ['void', '...values='=>'mixed'],
    'Ds\Stack::toArray' => ['array'],
    'Ds\Vector::__construct' => ['void', 'values='=>'mixed'],
    'Ds\Vector::allocate' => ['void', 'capacity'=>'int'],
    'Ds\Vector::apply' => ['void', 'callback'=>'callable'],
    'Ds\Vector::capacity' => ['int'],
    'Ds\Vector::clear' => ['void'],
    'Ds\Vector::contains' => ['bool', '...values='=>'mixed'],
    'Ds\Vector::copy' => ['Ds\Vector'],
    'Ds\Vector::count' => ['int'],
    'Ds\Vector::filter' => ['Ds\Vector', 'callback='=>'callable'],
    'Ds\Vector::find' => ['mixed', 'value'=>'mixed'],
    'Ds\Vector::first' => ['mixed'],
    'Ds\Vector::get' => ['mixed', 'index'=>'int'],
    'Ds\Vector::insert' => ['void', 'index'=>'int', '...values='=>'mixed'],
    'Ds\Vector::isEmpty' => ['bool'],
    'Ds\Vector::join' => ['string', 'glue='=>'string'],
    'Ds\Vector::jsonSerialize' => ['array'],
    'Ds\Vector::last' => ['mixed'],
    'Ds\Vector::map' => ['Ds\Vector', 'callback'=>'callable'],
    'Ds\Vector::merge' => ['Ds\Vector', 'values'=>'mixed'],
    'Ds\Vector::pop' => ['mixed'],
    'Ds\Vector::push' => ['void', '...values='=>'mixed'],
    'Ds\Vector::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
    'Ds\Vector::remove' => ['mixed', 'index'=>'int'],
    'Ds\Vector::reverse' => ['void'],
    'Ds\Vector::reversed' => ['Ds\Vector'],
    'Ds\Vector::rotate' => ['void', 'rotations'=>'int'],
    'Ds\Vector::set' => ['void', 'index'=>'int', 'value'=>'mixed'],
    'Ds\Vector::shift' => ['mixed'],
    'Ds\Vector::slice' => ['Ds\Vector', 'index'=>'int', 'length='=>'?int'],
    'Ds\Vector::sort' => ['void', 'comparator='=>'callable'],
    'Ds\Vector::sorted' => ['Ds\Vector', 'comparator='=>'callable'],
    'Ds\Vector::sum' => ['int|float'],
    'Ds\Vector::toArray' => ['array'],
    'Ds\Vector::unshift' => ['void', '...values='=>'mixed'],
    'EmptyIterator::current' => ['never'],
    'EmptyIterator::key' => ['never'],
    'EmptyIterator::next' => ['void'],
    'EmptyIterator::rewind' => ['void'],
    'EmptyIterator::valid' => ['bool'],
    'Error::__clone' => ['void'],
    'Error::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'Error::__toString' => ['string'],
    'Error::getCode' => ['int'],
    'Error::getFile' => ['string'],
    'Error::getLine' => ['int'],
    'Error::getMessage' => ['string'],
    'Error::getPrevious' => ['?Throwable'],
    'Error::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'Error::getTraceAsString' => ['string'],
    'ErrorException::__clone' => ['void'],
    'ErrorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'severity='=>'int', 'filename='=>'string', 'line='=>'int', 'previous='=>'?Throwable'],
    'ErrorException::__toString' => ['string'],
    'ErrorException::getCode' => ['int'],
    'ErrorException::getFile' => ['string'],
    'ErrorException::getLine' => ['int'],
    'ErrorException::getMessage' => ['string'],
    'ErrorException::getPrevious' => ['?Throwable'],
    'ErrorException::getSeverity' => ['int'],
    'ErrorException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'ErrorException::getTraceAsString' => ['string'],
    'Ev::backend' => ['int'],
    'Ev::depth' => ['int'],
    'Ev::embeddableBackends' => ['int'],
    'Ev::feedSignal' => ['void', 'signum'=>'int'],
    'Ev::feedSignalEvent' => ['void', 'signum'=>'int'],
    'Ev::iteration' => ['int'],
    'Ev::now' => ['float'],
    'Ev::nowUpdate' => ['void'],
    'Ev::recommendedBackends' => ['int'],
    'Ev::resume' => ['void'],
    'Ev::run' => ['void', 'flags='=>'int'],
    'Ev::sleep' => ['void', 'seconds'=>'float'],
    'Ev::stop' => ['void', 'how='=>'int'],
    'Ev::supportedBackends' => ['int'],
    'Ev::suspend' => ['void'],
    'Ev::time' => ['float'],
    'Ev::verify' => ['void'],
    'EvCheck::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvCheck::clear' => ['int'],
    'EvCheck::createStopped' => ['EvCheck', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvCheck::feed' => ['void', 'events'=>'int'],
    'EvCheck::getLoop' => ['EvLoop'],
    'EvCheck::invoke' => ['void', 'events'=>'int'],
    'EvCheck::keepAlive' => ['void', 'value'=>'bool'],
    'EvCheck::setCallback' => ['void', 'callback'=>'callable'],
    'EvCheck::start' => ['void'],
    'EvCheck::stop' => ['void'],
    'EvChild::__construct' => ['void', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvChild::clear' => ['int'],
    'EvChild::createStopped' => ['EvChild', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvChild::feed' => ['void', 'events'=>'int'],
    'EvChild::getLoop' => ['EvLoop'],
    'EvChild::invoke' => ['void', 'events'=>'int'],
    'EvChild::keepAlive' => ['void', 'value'=>'bool'],
    'EvChild::set' => ['void', 'pid'=>'int', 'trace'=>'bool'],
    'EvChild::setCallback' => ['void', 'callback'=>'callable'],
    'EvChild::start' => ['void'],
    'EvChild::stop' => ['void'],
    'EvEmbed::__construct' => ['void', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvEmbed::clear' => ['int'],
    'EvEmbed::createStopped' => ['EvEmbed', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvEmbed::feed' => ['void', 'events'=>'int'],
    'EvEmbed::getLoop' => ['EvLoop'],
    'EvEmbed::invoke' => ['void', 'events'=>'int'],
    'EvEmbed::keepAlive' => ['void', 'value'=>'bool'],
    'EvEmbed::set' => ['void', 'other'=>'object'],
    'EvEmbed::setCallback' => ['void', 'callback'=>'callable'],
    'EvEmbed::start' => ['void'],
    'EvEmbed::stop' => ['void'],
    'EvEmbed::sweep' => ['void'],
    'EvFork::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvFork::clear' => ['int'],
    'EvFork::createStopped' => ['EvFork', 'callback'=>'callable', 'data='=>'string', 'priority='=>'string'],
    'EvFork::feed' => ['void', 'events'=>'int'],
    'EvFork::getLoop' => ['EvLoop'],
    'EvFork::invoke' => ['void', 'events'=>'int'],
    'EvFork::keepAlive' => ['void', 'value'=>'bool'],
    'EvFork::setCallback' => ['void', 'callback'=>'callable'],
    'EvFork::start' => ['void'],
    'EvFork::stop' => ['void'],
    'EvIdle::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvIdle::clear' => ['int'],
    'EvIdle::createStopped' => ['EvIdle', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvIdle::feed' => ['void', 'events'=>'int'],
    'EvIdle::getLoop' => ['EvLoop'],
    'EvIdle::invoke' => ['void', 'events'=>'int'],
    'EvIdle::keepAlive' => ['void', 'value'=>'bool'],
    'EvIdle::setCallback' => ['void', 'callback'=>'callable'],
    'EvIdle::start' => ['void'],
    'EvIdle::stop' => ['void'],
    'EvIo::__construct' => ['void', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvIo::clear' => ['int'],
    'EvIo::createStopped' => ['EvIo', 'fd'=>'resource', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvIo::feed' => ['void', 'events'=>'int'],
    'EvIo::getLoop' => ['EvLoop'],
    'EvIo::invoke' => ['void', 'events'=>'int'],
    'EvIo::keepAlive' => ['void', 'value'=>'bool'],
    'EvIo::set' => ['void', 'fd'=>'resource', 'events'=>'int'],
    'EvIo::setCallback' => ['void', 'callback'=>'callable'],
    'EvIo::start' => ['void'],
    'EvIo::stop' => ['void'],
    'EvLoop::__construct' => ['void', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'],
    'EvLoop::backend' => ['int'],
    'EvLoop::check' => ['EvCheck', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::child' => ['EvChild', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::defaultLoop' => ['EvLoop', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'],
    'EvLoop::embed' => ['EvEmbed', 'other'=>'EvLoop', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::fork' => ['EvFork', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::idle' => ['EvIdle', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::invokePending' => ['void'],
    'EvLoop::io' => ['EvIo', 'fd'=>'resource', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::loopFork' => ['void'],
    'EvLoop::now' => ['float'],
    'EvLoop::nowUpdate' => ['void'],
    'EvLoop::periodic' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::prepare' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::resume' => ['void'],
    'EvLoop::run' => ['void', 'flags='=>'int'],
    'EvLoop::signal' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::stat' => ['EvStat', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::stop' => ['void', 'how='=>'int'],
    'EvLoop::suspend' => ['void'],
    'EvLoop::timer' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvLoop::verify' => ['void'],
    'EvPeriodic::__construct' => ['void', 'offset'=>'float', 'interval'=>'string', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvPeriodic::again' => ['void'],
    'EvPeriodic::at' => ['float'],
    'EvPeriodic::clear' => ['int'],
    'EvPeriodic::createStopped' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvPeriodic::feed' => ['void', 'events'=>'int'],
    'EvPeriodic::getLoop' => ['EvLoop'],
    'EvPeriodic::invoke' => ['void', 'events'=>'int'],
    'EvPeriodic::keepAlive' => ['void', 'value'=>'bool'],
    'EvPeriodic::set' => ['void', 'offset'=>'float', 'interval'=>'float'],
    'EvPeriodic::setCallback' => ['void', 'callback'=>'callable'],
    'EvPeriodic::start' => ['void'],
    'EvPeriodic::stop' => ['void'],
    'EvPrepare::__construct' => ['void', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'],
    'EvPrepare::clear' => ['int'],
    'EvPrepare::createStopped' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvPrepare::feed' => ['void', 'events'=>'int'],
    'EvPrepare::getLoop' => ['EvLoop'],
    'EvPrepare::invoke' => ['void', 'events'=>'int'],
    'EvPrepare::keepAlive' => ['void', 'value'=>'bool'],
    'EvPrepare::setCallback' => ['void', 'callback'=>'callable'],
    'EvPrepare::start' => ['void'],
    'EvPrepare::stop' => ['void'],
    'EvSignal::__construct' => ['void', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvSignal::clear' => ['int'],
    'EvSignal::createStopped' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvSignal::feed' => ['void', 'events'=>'int'],
    'EvSignal::getLoop' => ['EvLoop'],
    'EvSignal::invoke' => ['void', 'events'=>'int'],
    'EvSignal::keepAlive' => ['void', 'value'=>'bool'],
    'EvSignal::set' => ['void', 'signum'=>'int'],
    'EvSignal::setCallback' => ['void', 'callback'=>'callable'],
    'EvSignal::start' => ['void'],
    'EvSignal::stop' => ['void'],
    'EvStat::__construct' => ['void', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvStat::attr' => ['array'],
    'EvStat::clear' => ['int'],
    'EvStat::createStopped' => ['EvStat', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvStat::feed' => ['void', 'events'=>'int'],
    'EvStat::getLoop' => ['EvLoop'],
    'EvStat::invoke' => ['void', 'events'=>'int'],
    'EvStat::keepAlive' => ['void', 'value'=>'bool'],
    'EvStat::prev' => ['array'],
    'EvStat::set' => ['void', 'path'=>'string', 'interval'=>'float'],
    'EvStat::setCallback' => ['void', 'callback'=>'callable'],
    'EvStat::start' => ['void'],
    'EvStat::stat' => ['bool'],
    'EvStat::stop' => ['void'],
    'EvTimer::__construct' => ['void', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvTimer::again' => ['void'],
    'EvTimer::clear' => ['int'],
    'EvTimer::createStopped' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
    'EvTimer::feed' => ['void', 'events'=>'int'],
    'EvTimer::getLoop' => ['EvLoop'],
    'EvTimer::invoke' => ['void', 'events'=>'int'],
    'EvTimer::keepAlive' => ['void', 'value'=>'bool'],
    'EvTimer::set' => ['void', 'after'=>'float', 'repeat'=>'float'],
    'EvTimer::setCallback' => ['void', 'callback'=>'callable'],
    'EvTimer::start' => ['void'],
    'EvTimer::stop' => ['void'],
    'EvWatcher::__construct' => ['void'],
    'EvWatcher::clear' => ['int'],
    'EvWatcher::feed' => ['void', 'revents'=>'int'],
    'EvWatcher::getLoop' => ['EvLoop'],
    'EvWatcher::invoke' => ['void', 'revents'=>'int'],
    'EvWatcher::keepalive' => ['bool', 'value='=>'bool'],
    'EvWatcher::setCallback' => ['void', 'callback'=>'callable'],
    'EvWatcher::start' => ['void'],
    'EvWatcher::stop' => ['void'],
    'Event::__construct' => ['void', 'base'=>'EventBase', 'fd'=>'mixed', 'what'=>'int', 'cb'=>'callable', 'arg='=>'mixed'],
    'Event::add' => ['bool', 'timeout='=>'float'],
    'Event::addSignal' => ['bool', 'timeout='=>'float'],
    'Event::addTimer' => ['bool', 'timeout='=>'float'],
    'Event::del' => ['bool'],
    'Event::delSignal' => ['bool'],
    'Event::delTimer' => ['bool'],
    'Event::free' => ['void'],
    'Event::getSupportedMethods' => ['array'],
    'Event::pending' => ['bool', 'flags'=>'int'],
    'Event::set' => ['bool', 'base'=>'EventBase', 'fd'=>'mixed', 'what='=>'int', 'cb='=>'callable', 'arg='=>'mixed'],
    'Event::setPriority' => ['bool', 'priority'=>'int'],
    'Event::setTimer' => ['bool', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'],
    'Event::signal' => ['Event', 'base'=>'EventBase', 'signum'=>'int', 'cb'=>'callable', 'arg='=>'mixed'],
    'Event::timer' => ['Event', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'],
    'EventBase::__construct' => ['void', 'cfg='=>'EventConfig'],
    'EventBase::dispatch' => ['void'],
    'EventBase::exit' => ['bool', 'timeout='=>'float'],
    'EventBase::free' => ['void'],
    'EventBase::getFeatures' => ['int'],
    'EventBase::getMethod' => ['string', 'cfg='=>'EventConfig'],
    'EventBase::getTimeOfDayCached' => ['float'],
    'EventBase::gotExit' => ['bool'],
    'EventBase::gotStop' => ['bool'],
    'EventBase::loop' => ['bool', 'flags='=>'int'],
    'EventBase::priorityInit' => ['bool', 'n_priorities'=>'int'],
    'EventBase::reInit' => ['bool'],
    'EventBase::stop' => ['bool'],
    'EventBuffer::__construct' => ['void'],
    'EventBuffer::add' => ['bool', 'data'=>'string'],
    'EventBuffer::addBuffer' => ['bool', 'buf'=>'EventBuffer'],
    'EventBuffer::appendFrom' => ['int', 'buf'=>'EventBuffer', 'length'=>'int'],
    'EventBuffer::copyout' => ['int', '&w_data'=>'string', 'max_bytes'=>'int'],
    'EventBuffer::drain' => ['bool', 'length'=>'int'],
    'EventBuffer::enableLocking' => ['void'],
    'EventBuffer::expand' => ['bool', 'length'=>'int'],
    'EventBuffer::freeze' => ['bool', 'at_front'=>'bool'],
    'EventBuffer::lock' => ['void'],
    'EventBuffer::prepend' => ['bool', 'data'=>'string'],
    'EventBuffer::prependBuffer' => ['bool', 'buf'=>'EventBuffer'],
    'EventBuffer::pullup' => ['string', 'size'=>'int'],
    'EventBuffer::read' => ['string', 'max_bytes'=>'int'],
    'EventBuffer::readFrom' => ['int', 'fd'=>'mixed', 'howmuch'=>'int'],
    'EventBuffer::readLine' => ['string', 'eol_style'=>'int'],
    'EventBuffer::search' => ['mixed', 'what'=>'string', 'start='=>'int', 'end='=>'int'],
    'EventBuffer::searchEol' => ['mixed', 'start='=>'int', 'eol_style='=>'int'],
    'EventBuffer::substr' => ['string', 'start'=>'int', 'length='=>'int'],
    'EventBuffer::unfreeze' => ['bool', 'at_front'=>'bool'],
    'EventBuffer::unlock' => ['bool'],
    'EventBuffer::write' => ['int', 'fd'=>'mixed', 'howmuch='=>'int'],
    'EventBufferEvent::__construct' => ['void', 'base'=>'EventBase', 'socket='=>'mixed', 'options='=>'int', 'readcb='=>'callable', 'writecb='=>'callable', 'eventcb='=>'callable'],
    'EventBufferEvent::close' => ['void'],
    'EventBufferEvent::connect' => ['bool', 'addr'=>'string'],
    'EventBufferEvent::connectHost' => ['bool', 'dns_base'=>'EventDnsBase', 'hostname'=>'string', 'port'=>'int', 'family='=>'int'],
    'EventBufferEvent::createPair' => ['array', 'base'=>'EventBase', 'options='=>'int'],
    'EventBufferEvent::disable' => ['bool', 'events'=>'int'],
    'EventBufferEvent::enable' => ['bool', 'events'=>'int'],
    'EventBufferEvent::free' => ['void'],
    'EventBufferEvent::getDnsErrorString' => ['string'],
    'EventBufferEvent::getEnabled' => ['int'],
    'EventBufferEvent::getInput' => ['EventBuffer'],
    'EventBufferEvent::getOutput' => ['EventBuffer'],
    'EventBufferEvent::read' => ['string', 'size'=>'int'],
    'EventBufferEvent::readBuffer' => ['bool', 'buf'=>'EventBuffer'],
    'EventBufferEvent::setCallbacks' => ['void', 'readcb'=>'callable', 'writecb'=>'callable', 'eventcb'=>'callable', 'arg='=>'string'],
    'EventBufferEvent::setPriority' => ['bool', 'priority'=>'int'],
    'EventBufferEvent::setTimeouts' => ['bool', 'timeout_read'=>'float', 'timeout_write'=>'float'],
    'EventBufferEvent::setWatermark' => ['void', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'],
    'EventBufferEvent::sslError' => ['string'],
    'EventBufferEvent::sslFilter' => ['EventBufferEvent', 'base'=>'EventBase', 'underlying'=>'EventBufferEvent', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'],
    'EventBufferEvent::sslGetCipherInfo' => ['string'],
    'EventBufferEvent::sslGetCipherName' => ['string'],
    'EventBufferEvent::sslGetCipherVersion' => ['string'],
    'EventBufferEvent::sslGetProtocol' => ['string'],
    'EventBufferEvent::sslRenegotiate' => ['void'],
    'EventBufferEvent::sslSocket' => ['EventBufferEvent', 'base'=>'EventBase', 'socket'=>'mixed', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'],
    'EventBufferEvent::write' => ['bool', 'data'=>'string'],
    'EventBufferEvent::writeBuffer' => ['bool', 'buf'=>'EventBuffer'],
    'EventConfig::__construct' => ['void'],
    'EventConfig::avoidMethod' => ['bool', 'method'=>'string'],
    'EventConfig::requireFeatures' => ['bool', 'feature'=>'int'],
    'EventConfig::setMaxDispatchInterval' => ['void', 'max_interval'=>'int', 'max_callbacks'=>'int', 'min_priority'=>'int'],
    'EventDnsBase::__construct' => ['void', 'base'=>'EventBase', 'initialize'=>'bool'],
    'EventDnsBase::addNameserverIp' => ['bool', 'ip'=>'string'],
    'EventDnsBase::addSearch' => ['void', 'domain'=>'string'],
    'EventDnsBase::clearSearch' => ['void'],
    'EventDnsBase::countNameservers' => ['int'],
    'EventDnsBase::loadHosts' => ['bool', 'hosts'=>'string'],
    'EventDnsBase::parseResolvConf' => ['bool', 'flags'=>'int', 'filename'=>'string'],
    'EventDnsBase::setOption' => ['bool', 'option'=>'string', 'value'=>'string'],
    'EventDnsBase::setSearchNdots' => ['bool', 'ndots'=>'int'],
    'EventHttp::__construct' => ['void', 'base'=>'EventBase', 'ctx='=>'EventSslContext'],
    'EventHttp::accept' => ['bool', 'socket'=>'mixed'],
    'EventHttp::addServerAlias' => ['bool', 'alias'=>'string'],
    'EventHttp::bind' => ['void', 'address'=>'string', 'port'=>'int'],
    'EventHttp::removeServerAlias' => ['bool', 'alias'=>'string'],
    'EventHttp::setAllowedMethods' => ['void', 'methods'=>'int'],
    'EventHttp::setCallback' => ['void', 'path'=>'string', 'cb'=>'string', 'arg='=>'string'],
    'EventHttp::setDefaultCallback' => ['void', 'cb'=>'string', 'arg='=>'string'],
    'EventHttp::setMaxBodySize' => ['void', 'value'=>'int'],
    'EventHttp::setMaxHeadersSize' => ['void', 'value'=>'int'],
    'EventHttp::setTimeout' => ['void', 'value'=>'int'],
    'EventHttpConnection::__construct' => ['void', 'base'=>'EventBase', 'dns_base'=>'EventDnsBase', 'address'=>'string', 'port'=>'int', 'ctx='=>'EventSslContext'],
    'EventHttpConnection::getBase' => ['EventBase'],
    'EventHttpConnection::getPeer' => ['void', '&w_address'=>'string', '&w_port'=>'int'],
    'EventHttpConnection::makeRequest' => ['bool', 'req'=>'EventHttpRequest', 'type'=>'int', 'uri'=>'string'],
    'EventHttpConnection::setCloseCallback' => ['void', 'callback'=>'callable', 'data='=>'mixed'],
    'EventHttpConnection::setLocalAddress' => ['void', 'address'=>'string'],
    'EventHttpConnection::setLocalPort' => ['void', 'port'=>'int'],
    'EventHttpConnection::setMaxBodySize' => ['void', 'max_size'=>'string'],
    'EventHttpConnection::setMaxHeadersSize' => ['void', 'max_size'=>'string'],
    'EventHttpConnection::setRetries' => ['void', 'retries'=>'int'],
    'EventHttpConnection::setTimeout' => ['void', 'timeout'=>'int'],
    'EventHttpRequest::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed'],
    'EventHttpRequest::addHeader' => ['bool', 'key'=>'string', 'value'=>'string', 'type'=>'int'],
    'EventHttpRequest::cancel' => ['void'],
    'EventHttpRequest::clearHeaders' => ['void'],
    'EventHttpRequest::closeConnection' => ['void'],
    'EventHttpRequest::findHeader' => ['void', 'key'=>'string', 'type'=>'string'],
    'EventHttpRequest::free' => ['void'],
    'EventHttpRequest::getBufferEvent' => ['EventBufferEvent'],
    'EventHttpRequest::getCommand' => ['void'],
    'EventHttpRequest::getConnection' => ['EventHttpConnection'],
    'EventHttpRequest::getHost' => ['string'],
    'EventHttpRequest::getInputBuffer' => ['EventBuffer'],
    'EventHttpRequest::getInputHeaders' => ['array'],
    'EventHttpRequest::getOutputBuffer' => ['EventBuffer'],
    'EventHttpRequest::getOutputHeaders' => ['void'],
    'EventHttpRequest::getResponseCode' => ['int'],
    'EventHttpRequest::getUri' => ['string'],
    'EventHttpRequest::removeHeader' => ['void', 'key'=>'string', 'type'=>'string'],
    'EventHttpRequest::sendError' => ['void', 'error'=>'int', 'reason='=>'string'],
    'EventHttpRequest::sendReply' => ['void', 'code'=>'int', 'reason'=>'string', 'buf='=>'EventBuffer'],
    'EventHttpRequest::sendReplyChunk' => ['void', 'buf'=>'EventBuffer'],
    'EventHttpRequest::sendReplyEnd' => ['void'],
    'EventHttpRequest::sendReplyStart' => ['void', 'code'=>'int', 'reason'=>'string'],
    'EventListener::__construct' => ['void', 'base'=>'EventBase', 'cb'=>'callable', 'data'=>'mixed', 'flags'=>'int', 'backlog'=>'int', 'target'=>'mixed'],
    'EventListener::disable' => ['bool'],
    'EventListener::enable' => ['bool'],
    'EventListener::getBase' => ['void'],
    'EventListener::getSocketName' => ['bool', '&w_address'=>'string', '&w_port='=>'mixed'],
    'EventListener::setCallback' => ['void', 'cb'=>'callable', 'arg='=>'mixed'],
    'EventListener::setErrorCallback' => ['void', 'cb'=>'string'],
    'EventSslContext::__construct' => ['void', 'method'=>'string', 'options'=>'string'],
    'EventUtil::__construct' => ['void'],
    'EventUtil::getLastSocketErrno' => ['int', 'socket='=>'mixed'],
    'EventUtil::getLastSocketError' => ['string', 'socket='=>'mixed'],
    'EventUtil::getSocketFd' => ['int', 'socket'=>'mixed'],
    'EventUtil::getSocketName' => ['bool', 'socket'=>'mixed', '&w_address'=>'string', '&w_port='=>'mixed'],
    'EventUtil::setSocketOption' => ['bool', 'socket'=>'mixed', 'level'=>'int', 'optname'=>'int', 'optval'=>'mixed'],
    'EventUtil::sslRandPoll' => ['void'],
    'Exception::__clone' => ['void'],
    'Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'Exception::__toString' => ['string'],
    'Exception::getCode' => ['int|string'],
    'Exception::getFile' => ['string'],
    'Exception::getLine' => ['int'],
    'Exception::getMessage' => ['string'],
    'Exception::getPrevious' => ['?Throwable'],
    'Exception::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'Exception::getTraceAsString' => ['string'],
    'FANNConnection::__construct' => ['void', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'],
    'FANNConnection::getFromNeuron' => ['int'],
    'FANNConnection::getToNeuron' => ['int'],
    'FANNConnection::getWeight' => ['void'],
    'FANNConnection::setWeight' => ['bool', 'weight'=>'float'],
    'FilesystemIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'],
    'FilesystemIterator::__toString' => ['string'],
    'FilesystemIterator::current' => ['SplFileInfo|FilesystemIterator|string'],
    'FilesystemIterator::getATime' => ['int'],
    'FilesystemIterator::getBasename' => ['string', 'suffix='=>'string'],
    'FilesystemIterator::getCTime' => ['int'],
    'FilesystemIterator::getExtension' => ['string'],
    'FilesystemIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'FilesystemIterator::getFilename' => ['string'],
    'FilesystemIterator::getFlags' => ['int'],
    'FilesystemIterator::getGroup' => ['int'],
    'FilesystemIterator::getInode' => ['int'],
    'FilesystemIterator::getLinkTarget' => ['string'],
    'FilesystemIterator::getMTime' => ['int'],
    'FilesystemIterator::getOwner' => ['int'],
    'FilesystemIterator::getPath' => ['string'],
    'FilesystemIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'FilesystemIterator::getPathname' => ['string'],
    'FilesystemIterator::getPerms' => ['int'],
    'FilesystemIterator::getRealPath' => ['string'],
    'FilesystemIterator::getSize' => ['int'],
    'FilesystemIterator::getType' => ['string'],
    'FilesystemIterator::isDir' => ['bool'],
    'FilesystemIterator::isDot' => ['bool'],
    'FilesystemIterator::isExecutable' => ['bool'],
    'FilesystemIterator::isFile' => ['bool'],
    'FilesystemIterator::isLink' => ['bool'],
    'FilesystemIterator::isReadable' => ['bool'],
    'FilesystemIterator::isWritable' => ['bool'],
    'FilesystemIterator::key' => ['string'],
    'FilesystemIterator::next' => ['void'],
    'FilesystemIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
    'FilesystemIterator::rewind' => ['void'],
    'FilesystemIterator::seek' => ['void', 'position'=>'int'],
    'FilesystemIterator::setFileClass' => ['void', 'class_name='=>'string'],
    'FilesystemIterator::setFlags' => ['void', 'flags='=>'int'],
    'FilesystemIterator::setInfoClass' => ['void', 'class_name='=>'string'],
    'FilesystemIterator::valid' => ['bool'],
    'FilterIterator::__construct' => ['void', 'iterator'=>'Iterator'],
    'FilterIterator::accept' => ['bool'],
    'FilterIterator::current' => ['mixed'],
    'FilterIterator::getInnerIterator' => ['Iterator'],
    'FilterIterator::key' => ['mixed'],
    'FilterIterator::next' => ['void'],
    'FilterIterator::rewind' => ['void'],
    'FilterIterator::valid' => ['bool'],
    'GEOSGeometry::__toString' => ['string'],
    'GEOSGeometry::area' => ['float'],
    'GEOSGeometry::boundary' => ['GEOSGeometry'],
    'GEOSGeometry::buffer' => ['GEOSGeometry', 'dist'=>'float', 'styleArray='=>'array'],
    'GEOSGeometry::centroid' => ['GEOSGeometry'],
    'GEOSGeometry::checkValidity' => ['array{valid: bool, reason?: string, location?: GEOSGeometry}'],
    'GEOSGeometry::contains' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::convexHull' => ['GEOSGeometry'],
    'GEOSGeometry::coordinateDimension' => ['int'],
    'GEOSGeometry::coveredBy' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::covers' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::crosses' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::delaunayTriangulation' => ['GEOSGeometry', 'tolerance'=>'float', 'onlyEdges'=>'bool'],
    'GEOSGeometry::difference' => ['GEOSGeometry', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::dimension' => ['int'],
    'GEOSGeometry::disjoint' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::distance' => ['float', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::endPoint' => ['GEOSGeometry'],
    'GEOSGeometry::envelope' => ['GEOSGeometry'],
    'GEOSGeometry::equals' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::equalsExact' => ['bool', 'geom'=>'GEOSGeometry', 'tolerance'=>'float'],
    'GEOSGeometry::exteriorRing' => ['GEOSGeometry'],
    'GEOSGeometry::extractUniquePoints' => ['GEOSGeometry'],
    'GEOSGeometry::geometryN' => ['GEOSGeometry', 'num'=>'int'],
    'GEOSGeometry::getSRID' => ['int'],
    'GEOSGeometry::getX' => ['float'],
    'GEOSGeometry::getY' => ['float'],
    'GEOSGeometry::hasZ' => ['bool'],
    'GEOSGeometry::hausdorffDistance' => ['float', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::interiorRingN' => ['GEOSGeometry', 'num'=>'int'],
    'GEOSGeometry::interpolate' => ['GEOSGeometry', 'dist'=>'float', 'normalized'=>'bool'],
    'GEOSGeometry::intersection' => ['GEOSGeometry', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::intersects' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::isClosed' => ['bool'],
    'GEOSGeometry::isEmpty' => ['bool'],
    'GEOSGeometry::isRing' => ['bool'],
    'GEOSGeometry::isSimple' => ['bool'],
    'GEOSGeometry::length' => ['float'],
    'GEOSGeometry::node' => ['GEOSGeometry'],
    'GEOSGeometry::normalize' => ['GEOSGeometry'],
    'GEOSGeometry::numCoordinates' => ['int'],
    'GEOSGeometry::numGeometries' => ['int'],
    'GEOSGeometry::numInteriorRings' => ['int'],
    'GEOSGeometry::numPoints' => ['int'],
    'GEOSGeometry::offsetCurve' => ['GEOSGeometry', 'dist'=>'float', 'styleArray'=>'array'],
    'GEOSGeometry::overlaps' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::pointN' => ['GEOSGeometry', 'num'=>'int'],
    'GEOSGeometry::pointOnSurface' => ['GEOSGeometry'],
    'GEOSGeometry::project' => ['float', 'other'=>'GEOSGeometry', 'normalized'=>'bool'],
    'GEOSGeometry::relate' => ['string|bool', 'otherGeom'=>'GEOSGeometry', 'pattern'=>'string'],
    'GEOSGeometry::relateBoundaryNodeRule' => ['string', 'otherGeom'=>'GEOSGeometry', 'rule'=>'int'],
    'GEOSGeometry::setSRID' => ['void', 'srid'=>'int'],
    'GEOSGeometry::simplify' => ['GEOSGeometry', 'tolerance'=>'float', 'preserveTopology='=>'bool'],
    'GEOSGeometry::snapTo' => ['GEOSGeometry', 'geom'=>'GEOSGeometry', 'tolerance'=>'float'],
    'GEOSGeometry::startPoint' => ['GEOSGeometry'],
    'GEOSGeometry::symDifference' => ['GEOSGeometry', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::touches' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSGeometry::typeId' => ['int'],
    'GEOSGeometry::typeName' => ['string'],
    'GEOSGeometry::union' => ['GEOSGeometry', 'otherGeom='=>'GEOSGeometry'],
    'GEOSGeometry::voronoiDiagram' => ['GEOSGeometry', 'tolerance'=>'float', 'onlyEdges'=>'bool', 'extent'=>'GEOSGeometry|null'],
    'GEOSGeometry::within' => ['bool', 'geom'=>'GEOSGeometry'],
    'GEOSLineMerge' => ['array', 'geom'=>'GEOSGeometry'],
    'GEOSPolygonize' => ['array{rings: GEOSGeometry[], cut_edges?: GEOSGeometry[], dangles: GEOSGeometry[], invalid_rings: GEOSGeometry[]}', 'geom'=>'GEOSGeometry'],
    'GEOSRelateMatch' => ['bool', 'matrix'=>'string', 'pattern'=>'string'],
    'GEOSSharedPaths' => ['GEOSGeometry', 'geom1'=>'GEOSGeometry', 'geom2'=>'GEOSGeometry'],
    'GEOSVersion' => ['string'],
    'GEOSWKBReader::__construct' => ['void'],
    'GEOSWKBReader::read' => ['GEOSGeometry', 'wkb'=>'string'],
    'GEOSWKBReader::readHEX' => ['GEOSGeometry', 'wkb'=>'string'],
    'GEOSWKBWriter::__construct' => ['void'],
    'GEOSWKBWriter::getByteOrder' => ['int'],
    'GEOSWKBWriter::getIncludeSRID' => ['bool'],
    'GEOSWKBWriter::getOutputDimension' => ['int'],
    'GEOSWKBWriter::setByteOrder' => ['void', 'byteOrder'=>'int'],
    'GEOSWKBWriter::setIncludeSRID' => ['void', 'inc'=>'bool'],
    'GEOSWKBWriter::setOutputDimension' => ['void', 'dim'=>'int'],
    'GEOSWKBWriter::write' => ['string', 'geom'=>'GEOSGeometry'],
    'GEOSWKBWriter::writeHEX' => ['string', 'geom'=>'GEOSGeometry'],
    'GEOSWKTReader::__construct' => ['void'],
    'GEOSWKTReader::read' => ['GEOSGeometry', 'wkt'=>'string'],
    'GEOSWKTWriter::__construct' => ['void'],
    'GEOSWKTWriter::getOutputDimension' => ['int'],
    'GEOSWKTWriter::setOld3D' => ['void', 'val'=>'bool'],
    'GEOSWKTWriter::setOutputDimension' => ['void', 'dim'=>'int'],
    'GEOSWKTWriter::setRoundingPrecision' => ['void', 'prec'=>'int'],
    'GEOSWKTWriter::setTrim' => ['void', 'trim'=>'bool'],
    'GEOSWKTWriter::write' => ['string', 'geom'=>'GEOSGeometry'],
    'GMP::__construct' => ['void'],
    'GMP::__toString' => ['numeric-string'],
    'GearmanClient::__construct' => ['void'],
    'GearmanClient::addOptions' => ['bool', 'options'=>'int'],
    'GearmanClient::addServer' => ['bool', 'host='=>'string', 'port='=>'int'],
    'GearmanClient::addServers' => ['bool', 'servers='=>'string'],
    'GearmanClient::addTask' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
    'GearmanClient::addTaskBackground' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
    'GearmanClient::addTaskHigh' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
    'GearmanClient::addTaskHighBackground' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
    'GearmanClient::addTaskLow' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
    'GearmanClient::addTaskLowBackground' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
    'GearmanClient::addTaskStatus' => ['GearmanTask', 'job_handle'=>'string', 'context='=>'string'],
    'GearmanClient::clearCallbacks' => ['bool'],
    'GearmanClient::clone' => ['GearmanClient'],
    'GearmanClient::context' => ['string'],
    'GearmanClient::data' => ['string'],
    'GearmanClient::do' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
    'GearmanClient::doBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
    'GearmanClient::doHigh' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
    'GearmanClient::doHighBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
    'GearmanClient::doJobHandle' => ['string'],
    'GearmanClient::doLow' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
    'GearmanClient::doLowBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
    'GearmanClient::doNormal' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
    'GearmanClient::doStatus' => ['array'],
    'GearmanClient::echo' => ['bool', 'workload'=>'string'],
    'GearmanClient::error' => ['string'],
    'GearmanClient::getErrno' => ['int'],
    'GearmanClient::jobStatus' => ['array', 'job_handle'=>'string'],
    'GearmanClient::options' => [''],
    'GearmanClient::ping' => ['bool', 'workload'=>'string'],
    'GearmanClient::removeOptions' => ['bool', 'options'=>'int'],
    'GearmanClient::returnCode' => ['int'],
    'GearmanClient::runTasks' => ['bool'],
    'GearmanClient::setClientCallback' => ['void', 'callback'=>'callable'],
    'GearmanClient::setCompleteCallback' => ['bool', 'callback'=>'callable'],
    'GearmanClient::setContext' => ['bool', 'context'=>'string'],
    'GearmanClient::setCreatedCallback' => ['bool', 'callback'=>'string'],
    'GearmanClient::setData' => ['bool', 'data'=>'string'],
    'GearmanClient::setDataCallback' => ['bool', 'callback'=>'callable'],
    'GearmanClient::setExceptionCallback' => ['bool', 'callback'=>'callable'],
    'GearmanClient::setFailCallback' => ['bool', 'callback'=>'callable'],
    'GearmanClient::setOptions' => ['bool', 'options'=>'int'],
    'GearmanClient::setStatusCallback' => ['bool', 'callback'=>'callable'],
    'GearmanClient::setTimeout' => ['bool', 'timeout'=>'int'],
    'GearmanClient::setWarningCallback' => ['bool', 'callback'=>'callable'],
    'GearmanClient::setWorkloadCallback' => ['bool', 'callback'=>'callable'],
    'GearmanClient::timeout' => ['int'],
    'GearmanClient::wait' => [''],
    'GearmanJob::__construct' => ['void'],
    'GearmanJob::complete' => ['bool', 'result'=>'string'],
    'GearmanJob::data' => ['bool', 'data'=>'string'],
    'GearmanJob::exception' => ['bool', 'exception'=>'string'],
    'GearmanJob::fail' => ['bool'],
    'GearmanJob::functionName' => ['string'],
    'GearmanJob::handle' => ['string'],
    'GearmanJob::returnCode' => ['int'],
    'GearmanJob::sendComplete' => ['bool', 'result'=>'string'],
    'GearmanJob::sendData' => ['bool', 'data'=>'string'],
    'GearmanJob::sendException' => ['bool', 'exception'=>'string'],
    'GearmanJob::sendFail' => ['bool'],
    'GearmanJob::sendStatus' => ['bool', 'numerator'=>'int', 'denominator'=>'int'],
    'GearmanJob::sendWarning' => ['bool', 'warning'=>'string'],
    'GearmanJob::setReturn' => ['bool', 'gearman_return_t'=>'string'],
    'GearmanJob::status' => ['bool', 'numerator'=>'int', 'denominator'=>'int'],
    'GearmanJob::unique' => ['string'],
    'GearmanJob::warning' => ['bool', 'warning'=>'string'],
    'GearmanJob::workload' => ['string'],
    'GearmanJob::workloadSize' => ['int'],
    'GearmanTask::__construct' => ['void'],
    'GearmanTask::create' => ['GearmanTask'],
    'GearmanTask::data' => ['string|false'],
    'GearmanTask::dataSize' => ['int|false'],
    'GearmanTask::function' => ['string'],
    'GearmanTask::functionName' => ['string'],
    'GearmanTask::isKnown' => ['bool'],
    'GearmanTask::isRunning' => ['bool'],
    'GearmanTask::jobHandle' => ['string'],
    'GearmanTask::recvData' => ['array|false', 'data_len'=>'int'],
    'GearmanTask::returnCode' => ['int'],
    'GearmanTask::sendData' => ['int', 'data'=>'string'],
    'GearmanTask::sendWorkload' => ['int|false', 'data'=>'string'],
    'GearmanTask::taskDenominator' => ['int|false'],
    'GearmanTask::taskNumerator' => ['int|false'],
    'GearmanTask::unique' => ['string|false'],
    'GearmanTask::uuid' => ['string'],
    'GearmanWorker::__construct' => ['void'],
    'GearmanWorker::addFunction' => ['bool', 'function_name'=>'string', 'function'=>'callable', 'context='=>'mixed', 'timeout='=>'int'],
    'GearmanWorker::addOptions' => ['bool', 'option'=>'int'],
    'GearmanWorker::addServer' => ['bool', 'host='=>'string', 'port='=>'int'],
    'GearmanWorker::addServers' => ['bool', 'servers'=>'string'],
    'GearmanWorker::clone' => ['void'],
    'GearmanWorker::echo' => ['bool', 'workload'=>'string'],
    'GearmanWorker::error' => ['string'],
    'GearmanWorker::getErrno' => ['int'],
    'GearmanWorker::grabJob' => [''],
    'GearmanWorker::options' => ['int'],
    'GearmanWorker::register' => ['bool', 'function_name'=>'string', 'timeout='=>'int'],
    'GearmanWorker::removeOptions' => ['bool', 'option'=>'int'],
    'GearmanWorker::returnCode' => ['int'],
    'GearmanWorker::setId' => ['bool', 'id'=>'string'],
    'GearmanWorker::setOptions' => ['bool', 'option'=>'int'],
    'GearmanWorker::setTimeout' => ['bool', 'timeout'=>'int'],
    'GearmanWorker::timeout' => ['int'],
    'GearmanWorker::unregister' => ['bool', 'function_name'=>'string'],
    'GearmanWorker::unregisterAll' => ['bool'],
    'GearmanWorker::wait' => ['bool'],
    'GearmanWorker::work' => ['bool'],
    'Gender\Gender::__construct' => ['void', 'dsn='=>'string'],
    'Gender\Gender::connect' => ['bool', 'dsn'=>'string'],
    'Gender\Gender::country' => ['array', 'country'=>'int'],
    'Gender\Gender::get' => ['int', 'name'=>'string', 'country='=>'int'],
    'Gender\Gender::isNick' => ['array', 'name0'=>'string', 'name1'=>'string', 'country='=>'int'],
    'Gender\Gender::similarNames' => ['array', 'name'=>'string', 'country='=>'int'],
    'Generator::__wakeup' => ['void'],
    'Generator::current' => ['mixed'],
    'Generator::getReturn' => ['mixed'],
    'Generator::key' => ['mixed'],
    'Generator::next' => ['void'],
    'Generator::rewind' => ['void'],
    'Generator::send' => ['mixed', 'value'=>'mixed'],
    'Generator::throw' => ['mixed', 'exception'=>'Exception|Throwable'],
    'Generator::valid' => ['bool'],
    'GlobIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'],
    'GlobIterator::count' => ['int'],
    'GlobIterator::current' => ['FilesystemIterator|SplFileInfo|string'],
    'GlobIterator::getATime' => ['int'],
    'GlobIterator::getBasename' => ['string', 'suffix='=>'string'],
    'GlobIterator::getCTime' => ['int'],
    'GlobIterator::getExtension' => ['string'],
    'GlobIterator::getFileInfo' => ['SplFileInfo'],
    'GlobIterator::getFilename' => ['string'],
    'GlobIterator::getFlags' => ['int'],
    'GlobIterator::getGroup' => ['int'],
    'GlobIterator::getInode' => ['int'],
    'GlobIterator::getLinkTarget' => ['string|false'],
    'GlobIterator::getMTime' => ['int'],
    'GlobIterator::getOwner' => ['int'],
    'GlobIterator::getPath' => ['string'],
    'GlobIterator::getPathInfo' => ['?SplFileInfo'],
    'GlobIterator::getPathname' => ['string'],
    'GlobIterator::getPerms' => ['int'],
    'GlobIterator::getRealPath' => ['string|false'],
    'GlobIterator::getSize' => ['int'],
    'GlobIterator::getType' => ['string|false'],
    'GlobIterator::isDir' => ['bool'],
    'GlobIterator::isDot' => ['bool'],
    'GlobIterator::isExecutable' => ['bool'],
    'GlobIterator::isFile' => ['bool'],
    'GlobIterator::isLink' => ['bool'],
    'GlobIterator::isReadable' => ['bool'],
    'GlobIterator::isWritable' => ['bool'],
    'GlobIterator::key' => ['string'],
    'GlobIterator::next' => ['void'],
    'GlobIterator::openFile' => ['SplFileObject'],
    'GlobIterator::rewind' => ['void'],
    'GlobIterator::seek' => ['void', 'position'=>'int'],
    'GlobIterator::setFileClass' => ['void'],
    'GlobIterator::setFlags' => ['void', 'flags='=>'int'],
    'GlobIterator::setInfoClass' => ['void'],
    'GlobIterator::valid' => ['bool'],
    'Gmagick::__construct' => ['void', 'filename='=>'string'],
    'Gmagick::addimage' => ['Gmagick', 'gmagick'=>'gmagick'],
    'Gmagick::addnoiseimage' => ['Gmagick', 'noise'=>'int'],
    'Gmagick::annotateimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'],
    'Gmagick::blurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
    'Gmagick::borderimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int'],
    'Gmagick::charcoalimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'],
    'Gmagick::chopimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Gmagick::clear' => ['Gmagick'],
    'Gmagick::commentimage' => ['Gmagick', 'comment'=>'string'],
    'Gmagick::compositeimage' => ['Gmagick', 'source'=>'gmagick', 'compose'=>'int', 'x'=>'int', 'y'=>'int'],
    'Gmagick::cropimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Gmagick::cropthumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int'],
    'Gmagick::current' => ['Gmagick'],
    'Gmagick::cyclecolormapimage' => ['Gmagick', 'displace'=>'int'],
    'Gmagick::deconstructimages' => ['Gmagick'],
    'Gmagick::despeckleimage' => ['Gmagick'],
    'Gmagick::destroy' => ['bool'],
    'Gmagick::drawimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw'],
    'Gmagick::edgeimage' => ['Gmagick', 'radius'=>'float'],
    'Gmagick::embossimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'],
    'Gmagick::enhanceimage' => ['Gmagick'],
    'Gmagick::equalizeimage' => ['Gmagick'],
    'Gmagick::flipimage' => ['Gmagick'],
    'Gmagick::flopimage' => ['Gmagick'],
    'Gmagick::frameimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'],
    'Gmagick::gammaimage' => ['Gmagick', 'gamma'=>'float'],
    'Gmagick::getcopyright' => ['string'],
    'Gmagick::getfilename' => ['string'],
    'Gmagick::getimagebackgroundcolor' => ['GmagickPixel'],
    'Gmagick::getimageblueprimary' => ['array'],
    'Gmagick::getimagebordercolor' => ['GmagickPixel'],
    'Gmagick::getimagechanneldepth' => ['int', 'channel_type'=>'int'],
    'Gmagick::getimagecolors' => ['int'],
    'Gmagick::getimagecolorspace' => ['int'],
    'Gmagick::getimagecompose' => ['int'],
    'Gmagick::getimagedelay' => ['int'],
    'Gmagick::getimagedepth' => ['int'],
    'Gmagick::getimagedispose' => ['int'],
    'Gmagick::getimageextrema' => ['array'],
    'Gmagick::getimagefilename' => ['string'],
    'Gmagick::getimageformat' => ['string'],
    'Gmagick::getimagegamma' => ['float'],
    'Gmagick::getimagegreenprimary' => ['array'],
    'Gmagick::getimageheight' => ['int'],
    'Gmagick::getimagehistogram' => ['array'],
    'Gmagick::getimageindex' => ['int'],
    'Gmagick::getimageinterlacescheme' => ['int'],
    'Gmagick::getimageiterations' => ['int'],
    'Gmagick::getimagematte' => ['int'],
    'Gmagick::getimagemattecolor' => ['GmagickPixel'],
    'Gmagick::getimageprofile' => ['string', 'name'=>'string'],
    'Gmagick::getimageredprimary' => ['array'],
    'Gmagick::getimagerenderingintent' => ['int'],
    'Gmagick::getimageresolution' => ['array'],
    'Gmagick::getimagescene' => ['int'],
    'Gmagick::getimagesignature' => ['string'],
    'Gmagick::getimagetype' => ['int'],
    'Gmagick::getimageunits' => ['int'],
    'Gmagick::getimagewhitepoint' => ['array'],
    'Gmagick::getimagewidth' => ['int'],
    'Gmagick::getpackagename' => ['string'],
    'Gmagick::getquantumdepth' => ['array'],
    'Gmagick::getreleasedate' => ['string'],
    'Gmagick::getsamplingfactors' => ['array'],
    'Gmagick::getsize' => ['array'],
    'Gmagick::getversion' => ['array'],
    'Gmagick::hasnextimage' => ['bool'],
    'Gmagick::haspreviousimage' => ['bool'],
    'Gmagick::implodeimage' => ['mixed', 'radius'=>'float'],
    'Gmagick::labelimage' => ['mixed', 'label'=>'string'],
    'Gmagick::levelimage' => ['mixed', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'],
    'Gmagick::magnifyimage' => ['mixed'],
    'Gmagick::mapimage' => ['Gmagick', 'gmagick'=>'gmagick', 'dither'=>'bool'],
    'Gmagick::medianfilterimage' => ['void', 'radius'=>'float'],
    'Gmagick::minifyimage' => ['Gmagick'],
    'Gmagick::modulateimage' => ['Gmagick', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'],
    'Gmagick::motionblurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'],
    'Gmagick::newimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'background'=>'string', 'format='=>'string'],
    'Gmagick::nextimage' => ['bool'],
    'Gmagick::normalizeimage' => ['Gmagick', 'channel='=>'int'],
    'Gmagick::oilpaintimage' => ['Gmagick', 'radius'=>'float'],
    'Gmagick::previousimage' => ['bool'],
    'Gmagick::profileimage' => ['Gmagick', 'name'=>'string', 'profile'=>'string'],
    'Gmagick::quantizeimage' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
    'Gmagick::quantizeimages' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
    'Gmagick::queryfontmetrics' => ['array', 'draw'=>'gmagickdraw', 'text'=>'string'],
    'Gmagick::queryfonts' => ['array', 'pattern='=>'string'],
    'Gmagick::queryformats' => ['array', 'pattern='=>'string'],
    'Gmagick::radialblurimage' => ['Gmagick', 'angle'=>'float', 'channel='=>'int'],
    'Gmagick::raiseimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'],
    'Gmagick::read' => ['Gmagick', 'filename'=>'string'],
    'Gmagick::readimage' => ['Gmagick', 'filename'=>'string'],
    'Gmagick::readimageblob' => ['Gmagick', 'imagecontents'=>'string', 'filename='=>'string'],
    'Gmagick::readimagefile' => ['Gmagick', 'fp'=>'resource', 'filename='=>'string'],
    'Gmagick::reducenoiseimage' => ['Gmagick', 'radius'=>'float'],
    'Gmagick::removeimage' => ['Gmagick'],
    'Gmagick::removeimageprofile' => ['string', 'name'=>'string'],
    'Gmagick::resampleimage' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float', 'filter'=>'int', 'blur'=>'float'],
    'Gmagick::resizeimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'filter'=>'int', 'blur'=>'float', 'fit='=>'bool'],
    'Gmagick::rollimage' => ['Gmagick', 'x'=>'int', 'y'=>'int'],
    'Gmagick::rotateimage' => ['Gmagick', 'color'=>'mixed', 'degrees'=>'float'],
    'Gmagick::scaleimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'],
    'Gmagick::separateimagechannel' => ['Gmagick', 'channel'=>'int'],
    'Gmagick::setCompressionQuality' => ['Gmagick', 'quality'=>'int'],
    'Gmagick::setfilename' => ['Gmagick', 'filename'=>'string'],
    'Gmagick::setimagebackgroundcolor' => ['Gmagick', 'color'=>'gmagickpixel'],
    'Gmagick::setimageblueprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
    'Gmagick::setimagebordercolor' => ['Gmagick', 'color'=>'gmagickpixel'],
    'Gmagick::setimagechanneldepth' => ['Gmagick', 'channel'=>'int', 'depth'=>'int'],
    'Gmagick::setimagecolorspace' => ['Gmagick', 'colorspace'=>'int'],
    'Gmagick::setimagecompose' => ['Gmagick', 'composite'=>'int'],
    'Gmagick::setimagedelay' => ['Gmagick', 'delay'=>'int'],
    'Gmagick::setimagedepth' => ['Gmagick', 'depth'=>'int'],
    'Gmagick::setimagedispose' => ['Gmagick', 'disposetype'=>'int'],
    'Gmagick::setimagefilename' => ['Gmagick', 'filename'=>'string'],
    'Gmagick::setimageformat' => ['Gmagick', 'imageformat'=>'string'],
    'Gmagick::setimagegamma' => ['Gmagick', 'gamma'=>'float'],
    'Gmagick::setimagegreenprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
    'Gmagick::setimageindex' => ['Gmagick', 'index'=>'int'],
    'Gmagick::setimageinterlacescheme' => ['Gmagick', 'interlace'=>'int'],
    'Gmagick::setimageiterations' => ['Gmagick', 'iterations'=>'int'],
    'Gmagick::setimageprofile' => ['Gmagick', 'name'=>'string', 'profile'=>'string'],
    'Gmagick::setimageredprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
    'Gmagick::setimagerenderingintent' => ['Gmagick', 'rendering_intent'=>'int'],
    'Gmagick::setimageresolution' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float'],
    'Gmagick::setimagescene' => ['Gmagick', 'scene'=>'int'],
    'Gmagick::setimagetype' => ['Gmagick', 'imgtype'=>'int'],
    'Gmagick::setimageunits' => ['Gmagick', 'resolution'=>'int'],
    'Gmagick::setimagewhitepoint' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
    'Gmagick::setsamplingfactors' => ['Gmagick', 'factors'=>'array'],
    'Gmagick::setsize' => ['Gmagick', 'columns'=>'int', 'rows'=>'int'],
    'Gmagick::shearimage' => ['Gmagick', 'color'=>'mixed', 'xshear'=>'float', 'yshear'=>'float'],
    'Gmagick::solarizeimage' => ['Gmagick', 'threshold'=>'int'],
    'Gmagick::spreadimage' => ['Gmagick', 'radius'=>'float'],
    'Gmagick::stripimage' => ['Gmagick'],
    'Gmagick::swirlimage' => ['Gmagick', 'degrees'=>'float'],
    'Gmagick::thumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'],
    'Gmagick::trimimage' => ['Gmagick', 'fuzz'=>'float'],
    'Gmagick::write' => ['Gmagick', 'filename'=>'string'],
    'Gmagick::writeimage' => ['Gmagick', 'filename'=>'string', 'all_frames='=>'bool'],
    'GmagickDraw::annotate' => ['GmagickDraw', 'x'=>'float', 'y'=>'float', 'text'=>'string'],
    'GmagickDraw::arc' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'],
    'GmagickDraw::bezier' => ['GmagickDraw', 'coordinate_array'=>'array'],
    'GmagickDraw::ellipse' => ['GmagickDraw', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'],
    'GmagickDraw::getfillcolor' => ['GmagickPixel'],
    'GmagickDraw::getfillopacity' => ['float'],
    'GmagickDraw::getfont' => ['string|false'],
    'GmagickDraw::getfontsize' => ['float'],
    'GmagickDraw::getfontstyle' => ['int'],
    'GmagickDraw::getfontweight' => ['int'],
    'GmagickDraw::getstrokecolor' => ['GmagickPixel'],
    'GmagickDraw::getstrokeopacity' => ['float'],
    'GmagickDraw::getstrokewidth' => ['float'],
    'GmagickDraw::gettextdecoration' => ['int'],
    'GmagickDraw::gettextencoding' => ['string|false'],
    'GmagickDraw::line' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'],
    'GmagickDraw::point' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'],
    'GmagickDraw::polygon' => ['GmagickDraw', 'coordinates'=>'array'],
    'GmagickDraw::polyline' => ['GmagickDraw', 'coordinate_array'=>'array'],
    'GmagickDraw::rectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'],
    'GmagickDraw::rotate' => ['GmagickDraw', 'degrees'=>'float'],
    'GmagickDraw::roundrectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'],
    'GmagickDraw::scale' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'],
    'GmagickDraw::setfillcolor' => ['GmagickDraw', 'color'=>'string'],
    'GmagickDraw::setfillopacity' => ['GmagickDraw', 'fill_opacity'=>'float'],
    'GmagickDraw::setfont' => ['GmagickDraw', 'font'=>'string'],
    'GmagickDraw::setfontsize' => ['GmagickDraw', 'pointsize'=>'float'],
    'GmagickDraw::setfontstyle' => ['GmagickDraw', 'style'=>'int'],
    'GmagickDraw::setfontweight' => ['GmagickDraw', 'weight'=>'int'],
    'GmagickDraw::setstrokecolor' => ['GmagickDraw', 'color'=>'gmagickpixel'],
    'GmagickDraw::setstrokeopacity' => ['GmagickDraw', 'stroke_opacity'=>'float'],
    'GmagickDraw::setstrokewidth' => ['GmagickDraw', 'width'=>'float'],
    'GmagickDraw::settextdecoration' => ['GmagickDraw', 'decoration'=>'int'],
    'GmagickDraw::settextencoding' => ['GmagickDraw', 'encoding'=>'string'],
    'GmagickPixel::__construct' => ['void', 'color='=>'string'],
    'GmagickPixel::getcolor' => ['mixed', 'as_array='=>'bool', 'normalize_array='=>'bool'],
    'GmagickPixel::getcolorcount' => ['int'],
    'GmagickPixel::getcolorvalue' => ['float', 'color'=>'int'],
    'GmagickPixel::setcolor' => ['GmagickPixel', 'color'=>'string'],
    'GmagickPixel::setcolorvalue' => ['GmagickPixel', 'color'=>'int', 'value'=>'float'],
    'Grpc\Call::__construct' => ['void', 'channel'=>'Grpc\Channel', 'method'=>'string', 'absolute_deadline'=>'Grpc\Timeval', 'host_override='=>'mixed'],
    'Grpc\Call::cancel' => [''],
    'Grpc\Call::getPeer' => ['string'],
    'Grpc\Call::setCredentials' => ['int', 'creds_obj'=>'Grpc\CallCredentials'],
    'Grpc\Call::startBatch' => ['object', 'batch'=>'array'],
    'Grpc\CallCredentials::createComposite' => ['Grpc\CallCredentials', 'cred1'=>'Grpc\CallCredentials', 'cred2'=>'Grpc\CallCredentials'],
    'Grpc\CallCredentials::createFromPlugin' => ['Grpc\CallCredentials', 'callback'=>'Closure'],
    'Grpc\Channel::__construct' => ['void', 'target'=>'string', 'args='=>'array'],
    'Grpc\Channel::close' => [''],
    'Grpc\Channel::getConnectivityState' => ['int', 'try_to_connect='=>'bool'],
    'Grpc\Channel::getTarget' => ['string'],
    'Grpc\Channel::watchConnectivityState' => ['bool', 'last_state'=>'int', 'deadline_obj'=>'Grpc\Timeval'],
    'Grpc\ChannelCredentials::createComposite' => ['Grpc\ChannelCredentials', 'cred1'=>'Grpc\ChannelCredentials', 'cred2'=>'Grpc\CallCredentials'],
    'Grpc\ChannelCredentials::createDefault' => ['Grpc\ChannelCredentials'],
    'Grpc\ChannelCredentials::createInsecure' => ['null'],
    'Grpc\ChannelCredentials::createSsl' => ['Grpc\ChannelCredentials', 'pem_root_certs'=>'string', 'pem_private_key='=>'string', 'pem_cert_chain='=>'string'],
    'Grpc\ChannelCredentials::setDefaultRootsPem' => ['', 'pem_roots'=>'string'],
    'Grpc\Server::__construct' => ['void', 'args'=>'array'],
    'Grpc\Server::addHttp2Port' => ['bool', 'addr'=>'string'],
    'Grpc\Server::addSecureHttp2Port' => ['bool', 'addr'=>'string', 'creds_obj'=>'Grpc\ServerCredentials'],
    'Grpc\Server::requestCall' => ['', 'tag_new'=>'int', 'tag_cancel'=>'int'],
    'Grpc\Server::start' => [''],
    'Grpc\ServerCredentials::createSsl' => ['object', 'pem_root_certs'=>'string', 'pem_private_key'=>'string', 'pem_cert_chain'=>'string'],
    'Grpc\Timeval::__construct' => ['void', 'usec'=>'int'],
    'Grpc\Timeval::add' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'],
    'Grpc\Timeval::compare' => ['int', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval'],
    'Grpc\Timeval::infFuture' => ['Grpc\Timeval'],
    'Grpc\Timeval::infPast' => ['Grpc\Timeval'],
    'Grpc\Timeval::now' => ['Grpc\Timeval'],
    'Grpc\Timeval::similar' => ['bool', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval', 'threshold'=>'Grpc\Timeval'],
    'Grpc\Timeval::sleepUntil' => [''],
    'Grpc\Timeval::subtract' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'],
    'Grpc\Timeval::zero' => ['Grpc\Timeval'],
    'HRTime\PerformanceCounter::getElapsedTicks' => ['int'],
    'HRTime\PerformanceCounter::getFrequency' => ['int'],
    'HRTime\PerformanceCounter::getLastElapsedTicks' => ['int'],
    'HRTime\PerformanceCounter::getTicks' => ['int'],
    'HRTime\PerformanceCounter::getTicksSince' => ['int', 'start'=>'int'],
    'HRTime\PerformanceCounter::isRunning' => ['bool'],
    'HRTime\PerformanceCounter::start' => ['void'],
    'HRTime\PerformanceCounter::stop' => ['void'],
    'HRTime\StopWatch::getElapsedTicks' => ['int'],
    'HRTime\StopWatch::getElapsedTime' => ['float', 'unit='=>'int'],
    'HRTime\StopWatch::getLastElapsedTicks' => ['int'],
    'HRTime\StopWatch::getLastElapsedTime' => ['float', 'unit='=>'int'],
    'HRTime\StopWatch::isRunning' => ['bool'],
    'HRTime\StopWatch::start' => ['void'],
    'HRTime\StopWatch::stop' => ['void'],
    'HaruAnnotation::setBorderStyle' => ['bool', 'width'=>'float', 'dash_on'=>'int', 'dash_off'=>'int'],
    'HaruAnnotation::setHighlightMode' => ['bool', 'mode'=>'int'],
    'HaruAnnotation::setIcon' => ['bool', 'icon'=>'int'],
    'HaruAnnotation::setOpened' => ['bool', 'opened'=>'bool'],
    'HaruDestination::setFit' => ['bool'],
    'HaruDestination::setFitB' => ['bool'],
    'HaruDestination::setFitBH' => ['bool', 'top'=>'float'],
    'HaruDestination::setFitBV' => ['bool', 'left'=>'float'],
    'HaruDestination::setFitH' => ['bool', 'top'=>'float'],
    'HaruDestination::setFitR' => ['bool', 'left'=>'float', 'bottom'=>'float', 'right'=>'float', 'top'=>'float'],
    'HaruDestination::setFitV' => ['bool', 'left'=>'float'],
    'HaruDestination::setXYZ' => ['bool', 'left'=>'float', 'top'=>'float', 'zoom'=>'float'],
    'HaruDoc::__construct' => ['void'],
    'HaruDoc::addPage' => ['object'],
    'HaruDoc::addPageLabel' => ['bool', 'first_page'=>'int', 'style'=>'int', 'first_num'=>'int', 'prefix='=>'string'],
    'HaruDoc::createOutline' => ['object', 'title'=>'string', 'parent_outline='=>'object', 'encoder='=>'object'],
    'HaruDoc::getCurrentEncoder' => ['object'],
    'HaruDoc::getCurrentPage' => ['object'],
    'HaruDoc::getEncoder' => ['object', 'encoding'=>'string'],
    'HaruDoc::getFont' => ['object', 'fontname'=>'string', 'encoding='=>'string'],
    'HaruDoc::getInfoAttr' => ['string', 'type'=>'int'],
    'HaruDoc::getPageLayout' => ['int'],
    'HaruDoc::getPageMode' => ['int'],
    'HaruDoc::getStreamSize' => ['int'],
    'HaruDoc::insertPage' => ['object', 'page'=>'object'],
    'HaruDoc::loadJPEG' => ['object', 'filename'=>'string'],
    'HaruDoc::loadPNG' => ['object', 'filename'=>'string', 'deferred='=>'bool'],
    'HaruDoc::loadRaw' => ['object', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'color_space'=>'int'],
    'HaruDoc::loadTTC' => ['string', 'fontfile'=>'string', 'index'=>'int', 'embed='=>'bool'],
    'HaruDoc::loadTTF' => ['string', 'fontfile'=>'string', 'embed='=>'bool'],
    'HaruDoc::loadType1' => ['string', 'afmfile'=>'string', 'pfmfile='=>'string'],
    'HaruDoc::output' => ['bool'],
    'HaruDoc::readFromStream' => ['string', 'bytes'=>'int'],
    'HaruDoc::resetError' => ['bool'],
    'HaruDoc::resetStream' => ['bool'],
    'HaruDoc::save' => ['bool', 'file'=>'string'],
    'HaruDoc::saveToStream' => ['bool'],
    'HaruDoc::setCompressionMode' => ['bool', 'mode'=>'int'],
    'HaruDoc::setCurrentEncoder' => ['bool', 'encoding'=>'string'],
    'HaruDoc::setEncryptionMode' => ['bool', 'mode'=>'int', 'key_len='=>'int'],
    'HaruDoc::setInfoAttr' => ['bool', 'type'=>'int', 'info'=>'string'],
    'HaruDoc::setInfoDateAttr' => ['bool', 'type'=>'int', 'year'=>'int', 'month'=>'int', 'day'=>'int', 'hour'=>'int', 'min'=>'int', 'sec'=>'int', 'ind'=>'string', 'off_hour'=>'int', 'off_min'=>'int'],
    'HaruDoc::setOpenAction' => ['bool', 'destination'=>'object'],
    'HaruDoc::setPageLayout' => ['bool', 'layout'=>'int'],
    'HaruDoc::setPageMode' => ['bool', 'mode'=>'int'],
    'HaruDoc::setPagesConfiguration' => ['bool', 'page_per_pages'=>'int'],
    'HaruDoc::setPassword' => ['bool', 'owner_password'=>'string', 'user_password'=>'string'],
    'HaruDoc::setPermission' => ['bool', 'permission'=>'int'],
    'HaruDoc::useCNSEncodings' => ['bool'],
    'HaruDoc::useCNSFonts' => ['bool'],
    'HaruDoc::useCNTEncodings' => ['bool'],
    'HaruDoc::useCNTFonts' => ['bool'],
    'HaruDoc::useJPEncodings' => ['bool'],
    'HaruDoc::useJPFonts' => ['bool'],
    'HaruDoc::useKREncodings' => ['bool'],
    'HaruDoc::useKRFonts' => ['bool'],
    'HaruEncoder::getByteType' => ['int', 'text'=>'string', 'index'=>'int'],
    'HaruEncoder::getType' => ['int'],
    'HaruEncoder::getUnicode' => ['int', 'character'=>'int'],
    'HaruEncoder::getWritingMode' => ['int'],
    'HaruFont::getAscent' => ['int'],
    'HaruFont::getCapHeight' => ['int'],
    'HaruFont::getDescent' => ['int'],
    'HaruFont::getEncodingName' => ['string'],
    'HaruFont::getFontName' => ['string'],
    'HaruFont::getTextWidth' => ['array', 'text'=>'string'],
    'HaruFont::getUnicodeWidth' => ['int', 'character'=>'int'],
    'HaruFont::getXHeight' => ['int'],
    'HaruFont::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'font_size'=>'float', 'char_space'=>'float', 'word_space'=>'float', 'word_wrap='=>'bool'],
    'HaruImage::getBitsPerComponent' => ['int'],
    'HaruImage::getColorSpace' => ['string'],
    'HaruImage::getHeight' => ['int'],
    'HaruImage::getSize' => ['array'],
    'HaruImage::getWidth' => ['int'],
    'HaruImage::setColorMask' => ['bool', 'rmin'=>'int', 'rmax'=>'int', 'gmin'=>'int', 'gmax'=>'int', 'bmin'=>'int', 'bmax'=>'int'],
    'HaruImage::setMaskImage' => ['bool', 'mask_image'=>'object'],
    'HaruOutline::setDestination' => ['bool', 'destination'=>'object'],
    'HaruOutline::setOpened' => ['bool', 'opened'=>'bool'],
    'HaruPage::arc' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float', 'ang1'=>'float', 'ang2'=>'float'],
    'HaruPage::beginText' => ['bool'],
    'HaruPage::circle' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float'],
    'HaruPage::closePath' => ['bool'],
    'HaruPage::concat' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'],
    'HaruPage::createDestination' => ['object'],
    'HaruPage::createLinkAnnotation' => ['object', 'rectangle'=>'array', 'destination'=>'object'],
    'HaruPage::createTextAnnotation' => ['object', 'rectangle'=>'array', 'text'=>'string', 'encoder='=>'object'],
    'HaruPage::createURLAnnotation' => ['object', 'rectangle'=>'array', 'url'=>'string'],
    'HaruPage::curveTo' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
    'HaruPage::curveTo2' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
    'HaruPage::curveTo3' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x3'=>'float', 'y3'=>'float'],
    'HaruPage::drawImage' => ['bool', 'image'=>'object', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
    'HaruPage::ellipse' => ['bool', 'x'=>'float', 'y'=>'float', 'xray'=>'float', 'yray'=>'float'],
    'HaruPage::endPath' => ['bool'],
    'HaruPage::endText' => ['bool'],
    'HaruPage::eoFillStroke' => ['bool', 'close_path='=>'bool'],
    'HaruPage::eofill' => ['bool'],
    'HaruPage::fill' => ['bool'],
    'HaruPage::fillStroke' => ['bool', 'close_path='=>'bool'],
    'HaruPage::getCMYKFill' => ['array'],
    'HaruPage::getCMYKStroke' => ['array'],
    'HaruPage::getCharSpace' => ['float'],
    'HaruPage::getCurrentFont' => ['object'],
    'HaruPage::getCurrentFontSize' => ['float'],
    'HaruPage::getCurrentPos' => ['array'],
    'HaruPage::getCurrentTextPos' => ['array'],
    'HaruPage::getDash' => ['array'],
    'HaruPage::getFillingColorSpace' => ['int'],
    'HaruPage::getFlatness' => ['float'],
    'HaruPage::getGMode' => ['int'],
    'HaruPage::getGrayFill' => ['float'],
    'HaruPage::getGrayStroke' => ['float'],
    'HaruPage::getHeight' => ['float'],
    'HaruPage::getHorizontalScaling' => ['float'],
    'HaruPage::getLineCap' => ['int'],
    'HaruPage::getLineJoin' => ['int'],
    'HaruPage::getLineWidth' => ['float'],
    'HaruPage::getMiterLimit' => ['float'],
    'HaruPage::getRGBFill' => ['array'],
    'HaruPage::getRGBStroke' => ['array'],
    'HaruPage::getStrokingColorSpace' => ['int'],
    'HaruPage::getTextLeading' => ['float'],
    'HaruPage::getTextMatrix' => ['array'],
    'HaruPage::getTextRenderingMode' => ['int'],
    'HaruPage::getTextRise' => ['float'],
    'HaruPage::getTextWidth' => ['float', 'text'=>'string'],
    'HaruPage::getTransMatrix' => ['array'],
    'HaruPage::getWidth' => ['float'],
    'HaruPage::getWordSpace' => ['float'],
    'HaruPage::lineTo' => ['bool', 'x'=>'float', 'y'=>'float'],
    'HaruPage::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'wordwrap='=>'bool'],
    'HaruPage::moveTextPos' => ['bool', 'x'=>'float', 'y'=>'float', 'set_leading='=>'bool'],
    'HaruPage::moveTo' => ['bool', 'x'=>'float', 'y'=>'float'],
    'HaruPage::moveToNextLine' => ['bool'],
    'HaruPage::rectangle' => ['bool', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
    'HaruPage::setCMYKFill' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'],
    'HaruPage::setCMYKStroke' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'],
    'HaruPage::setCharSpace' => ['bool', 'char_space'=>'float'],
    'HaruPage::setDash' => ['bool', 'pattern'=>'array', 'phase'=>'int'],
    'HaruPage::setFlatness' => ['bool', 'flatness'=>'float'],
    'HaruPage::setFontAndSize' => ['bool', 'font'=>'object', 'size'=>'float'],
    'HaruPage::setGrayFill' => ['bool', 'value'=>'float'],
    'HaruPage::setGrayStroke' => ['bool', 'value'=>'float'],
    'HaruPage::setHeight' => ['bool', 'height'=>'float'],
    'HaruPage::setHorizontalScaling' => ['bool', 'scaling'=>'float'],
    'HaruPage::setLineCap' => ['bool', 'cap'=>'int'],
    'HaruPage::setLineJoin' => ['bool', 'join'=>'int'],
    'HaruPage::setLineWidth' => ['bool', 'width'=>'float'],
    'HaruPage::setMiterLimit' => ['bool', 'limit'=>'float'],
    'HaruPage::setRGBFill' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'],
    'HaruPage::setRGBStroke' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'],
    'HaruPage::setRotate' => ['bool', 'angle'=>'int'],
    'HaruPage::setSize' => ['bool', 'size'=>'int', 'direction'=>'int'],
    'HaruPage::setSlideShow' => ['bool', 'type'=>'int', 'disp_time'=>'float', 'trans_time'=>'float'],
    'HaruPage::setTextLeading' => ['bool', 'text_leading'=>'float'],
    'HaruPage::setTextMatrix' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'],
    'HaruPage::setTextRenderingMode' => ['bool', 'mode'=>'int'],
    'HaruPage::setTextRise' => ['bool', 'rise'=>'float'],
    'HaruPage::setWidth' => ['bool', 'width'=>'float'],
    'HaruPage::setWordSpace' => ['bool', 'word_space'=>'float'],
    'HaruPage::showText' => ['bool', 'text'=>'string'],
    'HaruPage::showTextNextLine' => ['bool', 'text'=>'string', 'word_space='=>'float', 'char_space='=>'float'],
    'HaruPage::stroke' => ['bool', 'close_path='=>'bool'],
    'HaruPage::textOut' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'],
    'HaruPage::textRect' => ['bool', 'left'=>'float', 'top'=>'float', 'right'=>'float', 'bottom'=>'float', 'text'=>'string', 'align='=>'int'],
    'HttpDeflateStream::__construct' => ['void', 'flags='=>'int'],
    'HttpDeflateStream::factory' => ['HttpDeflateStream', 'flags='=>'int', 'class_name='=>'string'],
    'HttpDeflateStream::finish' => ['string', 'data='=>'string'],
    'HttpDeflateStream::flush' => ['string|false', 'data='=>'string'],
    'HttpDeflateStream::update' => ['string|false', 'data'=>'string'],
    'HttpInflateStream::__construct' => ['void', 'flags='=>'int'],
    'HttpInflateStream::factory' => ['HttpInflateStream', 'flags='=>'int', 'class_name='=>'string'],
    'HttpInflateStream::finish' => ['string', 'data='=>'string'],
    'HttpInflateStream::flush' => ['string|false', 'data='=>'string'],
    'HttpInflateStream::update' => ['string|false', 'data'=>'string'],
    'HttpMessage::__construct' => ['void', 'message='=>'string'],
    'HttpMessage::__toString' => ['string'],
    'HttpMessage::addHeaders' => ['void', 'headers'=>'array', 'append='=>'bool'],
    'HttpMessage::count' => ['int'],
    'HttpMessage::current' => ['mixed'],
    'HttpMessage::detach' => ['HttpMessage'],
    'HttpMessage::factory' => ['?HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'],
    'HttpMessage::fromEnv' => ['?HttpMessage', 'message_type'=>'int', 'class_name='=>'string'],
    'HttpMessage::fromString' => ['?HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'],
    'HttpMessage::getBody' => ['string'],
    'HttpMessage::getHeader' => ['?string', 'header'=>'string'],
    'HttpMessage::getHeaders' => ['array'],
    'HttpMessage::getHttpVersion' => ['string'],
    'HttpMessage::getInfo' => [''],
    'HttpMessage::getParentMessage' => ['HttpMessage'],
    'HttpMessage::getRequestMethod' => ['string|false'],
    'HttpMessage::getRequestUrl' => ['string|false'],
    'HttpMessage::getResponseCode' => ['int'],
    'HttpMessage::getResponseStatus' => ['string'],
    'HttpMessage::getType' => ['int'],
    'HttpMessage::guessContentType' => ['string|false', 'magic_file'=>'string', 'magic_mode='=>'int'],
    'HttpMessage::key' => ['int|string'],
    'HttpMessage::next' => ['void'],
    'HttpMessage::prepend' => ['void', 'message'=>'HttpMessage', 'top='=>'bool'],
    'HttpMessage::reverse' => ['HttpMessage'],
    'HttpMessage::rewind' => ['void'],
    'HttpMessage::send' => ['bool'],
    'HttpMessage::serialize' => ['string'],
    'HttpMessage::setBody' => ['void', 'body'=>'string'],
    'HttpMessage::setHeaders' => ['void', 'headers'=>'array'],
    'HttpMessage::setHttpVersion' => ['bool', 'version'=>'string'],
    'HttpMessage::setInfo' => ['', 'http_info'=>''],
    'HttpMessage::setRequestMethod' => ['bool', 'method'=>'string'],
    'HttpMessage::setRequestUrl' => ['bool', 'url'=>'string'],
    'HttpMessage::setResponseCode' => ['bool', 'code'=>'int'],
    'HttpMessage::setResponseStatus' => ['bool', 'status'=>'string'],
    'HttpMessage::setType' => ['void', 'type'=>'int'],
    'HttpMessage::toMessageTypeObject' => ['HttpRequest|HttpResponse|null'],
    'HttpMessage::toString' => ['string', 'include_parent='=>'bool'],
    'HttpMessage::unserialize' => ['void', 'serialized'=>'string'],
    'HttpMessage::valid' => ['bool'],
    'HttpQueryString::__construct' => ['void', 'global='=>'bool', 'add='=>'mixed'],
    'HttpQueryString::__toString' => ['string'],
    'HttpQueryString::factory' => ['', 'global'=>'', 'params'=>'', 'class_name'=>''],
    'HttpQueryString::get' => ['mixed', 'key='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
    'HttpQueryString::getArray' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
    'HttpQueryString::getBool' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
    'HttpQueryString::getFloat' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
    'HttpQueryString::getInt' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
    'HttpQueryString::getObject' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
    'HttpQueryString::getString' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
    'HttpQueryString::mod' => ['HttpQueryString', 'params'=>'mixed'],
    'HttpQueryString::offsetExists' => ['bool', 'offset'=>'mixed'],
    'HttpQueryString::offsetGet' => ['mixed', 'offset'=>'mixed'],
    'HttpQueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
    'HttpQueryString::offsetUnset' => ['void', 'offset'=>'mixed'],
    'HttpQueryString::serialize' => ['string'],
    'HttpQueryString::set' => ['string', 'params'=>'mixed'],
    'HttpQueryString::singleton' => ['HttpQueryString', 'global='=>'bool'],
    'HttpQueryString::toArray' => ['array'],
    'HttpQueryString::toString' => ['string'],
    'HttpQueryString::unserialize' => ['void', 'serialized'=>'string'],
    'HttpQueryString::xlate' => ['bool', 'ie'=>'string', 'oe'=>'string'],
    'HttpRequest::__construct' => ['void', 'url='=>'string', 'request_method='=>'int', 'options='=>'array'],
    'HttpRequest::addBody' => ['', 'request_body_data'=>''],
    'HttpRequest::addCookies' => ['bool', 'cookies'=>'array'],
    'HttpRequest::addHeaders' => ['bool', 'headers'=>'array'],
    'HttpRequest::addPostFields' => ['bool', 'post_data'=>'array'],
    'HttpRequest::addPostFile' => ['bool', 'name'=>'string', 'file'=>'string', 'content_type='=>'string'],
    'HttpRequest::addPutData' => ['bool', 'put_data'=>'string'],
    'HttpRequest::addQueryData' => ['bool', 'query_params'=>'array'],
    'HttpRequest::addRawPostData' => ['bool', 'raw_post_data'=>'string'],
    'HttpRequest::addSslOptions' => ['bool', 'options'=>'array'],
    'HttpRequest::clearHistory' => ['void'],
    'HttpRequest::enableCookies' => ['bool'],
    'HttpRequest::encodeBody' => ['', 'fields'=>'', 'files'=>''],
    'HttpRequest::factory' => ['', 'url'=>'', 'method'=>'', 'options'=>'', 'class_name'=>''],
    'HttpRequest::flushCookies' => [''],
    'HttpRequest::get' => ['', 'url'=>'', 'options'=>'', '&info'=>''],
    'HttpRequest::getBody' => [''],
    'HttpRequest::getContentType' => ['string'],
    'HttpRequest::getCookies' => ['array'],
    'HttpRequest::getHeaders' => ['array'],
    'HttpRequest::getHistory' => ['HttpMessage'],
    'HttpRequest::getMethod' => ['int'],
    'HttpRequest::getOptions' => ['array'],
    'HttpRequest::getPostFields' => ['array'],
    'HttpRequest::getPostFiles' => ['array'],
    'HttpRequest::getPutData' => ['string'],
    'HttpRequest::getPutFile' => ['string'],
    'HttpRequest::getQueryData' => ['string'],
    'HttpRequest::getRawPostData' => ['string'],
    'HttpRequest::getRawRequestMessage' => ['string'],
    'HttpRequest::getRawResponseMessage' => ['string'],
    'HttpRequest::getRequestMessage' => ['HttpMessage'],
    'HttpRequest::getResponseBody' => ['string'],
    'HttpRequest::getResponseCode' => ['int'],
    'HttpRequest::getResponseCookies' => ['stdClass[]', 'flags='=>'int', 'allowed_extras='=>'array'],
    'HttpRequest::getResponseData' => ['array'],
    'HttpRequest::getResponseHeader' => ['mixed', 'name='=>'string'],
    'HttpRequest::getResponseInfo' => ['mixed', 'name='=>'string'],
    'HttpRequest::getResponseMessage' => ['HttpMessage'],
    'HttpRequest::getResponseStatus' => ['string'],
    'HttpRequest::getSslOptions' => ['array'],
    'HttpRequest::getUrl' => ['string'],
    'HttpRequest::head' => ['', 'url'=>'', 'options'=>'', '&info'=>''],
    'HttpRequest::methodExists' => ['', 'method'=>''],
    'HttpRequest::methodName' => ['', 'method_id'=>''],
    'HttpRequest::methodRegister' => ['', 'method_name'=>''],
    'HttpRequest::methodUnregister' => ['', 'method'=>''],
    'HttpRequest::postData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''],
    'HttpRequest::postFields' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''],
    'HttpRequest::putData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''],
    'HttpRequest::putFile' => ['', 'url'=>'', 'file'=>'', 'options'=>'', '&info'=>''],
    'HttpRequest::putStream' => ['', 'url'=>'', 'stream'=>'', 'options'=>'', '&info'=>''],
    'HttpRequest::resetCookies' => ['bool', 'session_only='=>'bool'],
    'HttpRequest::send' => ['HttpMessage'],
    'HttpRequest::setBody' => ['bool', 'request_body_data='=>'string'],
    'HttpRequest::setContentType' => ['bool', 'content_type'=>'string'],
    'HttpRequest::setCookies' => ['bool', 'cookies='=>'array'],
    'HttpRequest::setHeaders' => ['bool', 'headers='=>'array'],
    'HttpRequest::setMethod' => ['bool', 'request_method'=>'int'],
    'HttpRequest::setOptions' => ['bool', 'options='=>'array'],
    'HttpRequest::setPostFields' => ['bool', 'post_data'=>'array'],
    'HttpRequest::setPostFiles' => ['bool', 'post_files'=>'array'],
    'HttpRequest::setPutData' => ['bool', 'put_data='=>'string'],
    'HttpRequest::setPutFile' => ['bool', 'file='=>'string'],
    'HttpRequest::setQueryData' => ['bool', 'query_data'=>'mixed'],
    'HttpRequest::setRawPostData' => ['bool', 'raw_post_data='=>'string'],
    'HttpRequest::setSslOptions' => ['bool', 'options='=>'array'],
    'HttpRequest::setUrl' => ['bool', 'url'=>'string'],
    'HttpRequestDataShare::__construct' => ['void'],
    'HttpRequestDataShare::__destruct' => ['void'],
    'HttpRequestDataShare::attach' => ['', 'request'=>'HttpRequest'],
    'HttpRequestDataShare::count' => ['int'],
    'HttpRequestDataShare::detach' => ['', 'request'=>'HttpRequest'],
    'HttpRequestDataShare::factory' => ['', 'global'=>'', 'class_name'=>''],
    'HttpRequestDataShare::reset' => [''],
    'HttpRequestDataShare::singleton' => ['', 'global'=>''],
    'HttpRequestPool::__construct' => ['void', 'request='=>'HttpRequest'],
    'HttpRequestPool::__destruct' => ['void'],
    'HttpRequestPool::attach' => ['bool', 'request'=>'HttpRequest'],
    'HttpRequestPool::count' => ['int'],
    'HttpRequestPool::current' => ['mixed'],
    'HttpRequestPool::detach' => ['bool', 'request'=>'HttpRequest'],
    'HttpRequestPool::enableEvents' => ['', 'enable'=>''],
    'HttpRequestPool::enablePipelining' => ['', 'enable'=>''],
    'HttpRequestPool::getAttachedRequests' => ['array'],
    'HttpRequestPool::getFinishedRequests' => ['array'],
    'HttpRequestPool::key' => ['int|string'],
    'HttpRequestPool::next' => ['void'],
    'HttpRequestPool::reset' => ['void'],
    'HttpRequestPool::rewind' => ['void'],
    'HttpRequestPool::send' => ['bool'],
    'HttpRequestPool::socketPerform' => ['bool'],
    'HttpRequestPool::socketSelect' => ['bool', 'timeout='=>'float'],
    'HttpRequestPool::valid' => ['bool'],
    'HttpResponse::capture' => ['void'],
    'HttpResponse::getBufferSize' => ['int'],
    'HttpResponse::getCache' => ['bool'],
    'HttpResponse::getCacheControl' => ['string'],
    'HttpResponse::getContentDisposition' => ['string'],
    'HttpResponse::getContentType' => ['string'],
    'HttpResponse::getData' => ['string'],
    'HttpResponse::getETag' => ['string'],
    'HttpResponse::getFile' => ['string'],
    'HttpResponse::getGzip' => ['bool'],
    'HttpResponse::getHeader' => ['mixed', 'name='=>'string'],
    'HttpResponse::getLastModified' => ['int'],
    'HttpResponse::getRequestBody' => ['string'],
    'HttpResponse::getRequestBodyStream' => ['resource'],
    'HttpResponse::getRequestHeaders' => ['array'],
    'HttpResponse::getStream' => ['resource'],
    'HttpResponse::getThrottleDelay' => ['float'],
    'HttpResponse::guessContentType' => ['string|false', 'magic_file'=>'string', 'magic_mode='=>'int'],
    'HttpResponse::redirect' => ['void', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'],
    'HttpResponse::send' => ['bool', 'clean_ob='=>'bool'],
    'HttpResponse::setBufferSize' => ['bool', 'bytes'=>'int'],
    'HttpResponse::setCache' => ['bool', 'cache'=>'bool'],
    'HttpResponse::setCacheControl' => ['bool', 'control'=>'string', 'max_age='=>'int', 'must_revalidate='=>'bool'],
    'HttpResponse::setContentDisposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'],
    'HttpResponse::setContentType' => ['bool', 'content_type'=>'string'],
    'HttpResponse::setData' => ['bool', 'data'=>'mixed'],
    'HttpResponse::setETag' => ['bool', 'etag'=>'string'],
    'HttpResponse::setFile' => ['bool', 'file'=>'string'],
    'HttpResponse::setGzip' => ['bool', 'gzip'=>'bool'],
    'HttpResponse::setHeader' => ['bool', 'name'=>'string', 'value='=>'mixed', 'replace='=>'bool'],
    'HttpResponse::setLastModified' => ['bool', 'timestamp'=>'int'],
    'HttpResponse::setStream' => ['bool', 'stream'=>'resource'],
    'HttpResponse::setThrottleDelay' => ['bool', 'seconds'=>'float'],
    'HttpResponse::status' => ['bool', 'status'=>'int'],
    'HttpUtil::buildCookie' => ['', 'cookie_array'=>''],
    'HttpUtil::buildStr' => ['', 'query'=>'', 'prefix'=>'', 'arg_sep'=>''],
    'HttpUtil::buildUrl' => ['', 'url'=>'', 'parts'=>'', 'flags'=>'', '&composed'=>''],
    'HttpUtil::chunkedDecode' => ['', 'encoded_string'=>''],
    'HttpUtil::date' => ['', 'timestamp'=>''],
    'HttpUtil::deflate' => ['', 'plain'=>'', 'flags'=>''],
    'HttpUtil::inflate' => ['', 'encoded'=>''],
    'HttpUtil::matchEtag' => ['', 'plain_etag'=>'', 'for_range'=>''],
    'HttpUtil::matchModified' => ['', 'last_modified'=>'', 'for_range'=>''],
    'HttpUtil::matchRequestHeader' => ['', 'header_name'=>'', 'header_value'=>'', 'case_sensitive'=>''],
    'HttpUtil::negotiateCharset' => ['', 'supported'=>'', '&result'=>''],
    'HttpUtil::negotiateContentType' => ['', 'supported'=>'', '&result'=>''],
    'HttpUtil::negotiateLanguage' => ['', 'supported'=>'', '&result'=>''],
    'HttpUtil::parseCookie' => ['', 'cookie_string'=>''],
    'HttpUtil::parseHeaders' => ['', 'headers_string'=>''],
    'HttpUtil::parseMessage' => ['', 'message_string'=>''],
    'HttpUtil::parseParams' => ['', 'param_string'=>'', 'flags'=>''],
    'HttpUtil::support' => ['', 'feature'=>''],
    'Imagick::__construct' => ['void', 'files='=>'string|string[]'],
    'Imagick::__toString' => ['string'],
    'Imagick::adaptiveBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
    'Imagick::adaptiveResizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool'],
    'Imagick::adaptiveSharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
    'Imagick::adaptiveThresholdImage' => ['bool', 'width'=>'int', 'height'=>'int', 'offset'=>'int'],
    'Imagick::addImage' => ['bool', 'source'=>'Imagick'],
    'Imagick::addNoiseImage' => ['bool', 'noise_type'=>'int', 'channel='=>'int'],
    'Imagick::affineTransformImage' => ['bool', 'matrix'=>'ImagickDraw'],
    'Imagick::animateImages' => ['bool', 'x_server'=>'string'],
    'Imagick::annotateImage' => ['bool', 'draw_settings'=>'ImagickDraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'],
    'Imagick::appendImages' => ['Imagick', 'stack'=>'bool'],
    'Imagick::autoGammaImage' => ['bool', 'channel='=>'int'],
    'Imagick::autoLevelImage' => ['void', 'CHANNEL='=>'string'],
    'Imagick::autoOrient' => ['bool'],
    'Imagick::averageImages' => ['Imagick'],
    'Imagick::blackThresholdImage' => ['bool', 'threshold'=>'mixed'],
    'Imagick::blueShiftImage' => ['void', 'factor='=>'float'],
    'Imagick::blurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
    'Imagick::borderImage' => ['bool', 'bordercolor'=>'mixed', 'width'=>'int', 'height'=>'int'],
    'Imagick::brightnessContrastImage' => ['void', 'brightness'=>'string', 'contrast'=>'string', 'CHANNEL='=>'string'],
    'Imagick::charcoalImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'],
    'Imagick::chopImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Imagick::clampImage' => ['void', 'CHANNEL='=>'string'],
    'Imagick::clear' => ['bool'],
    'Imagick::clipImage' => ['bool'],
    'Imagick::clipImagePath' => ['void', 'pathname'=>'string', 'inside'=>'string'],
    'Imagick::clipPathImage' => ['bool', 'pathname'=>'string', 'inside'=>'bool'],
    'Imagick::clone' => ['Imagick'],
    'Imagick::clutImage' => ['bool', 'lookup_table'=>'Imagick', 'channel='=>'float'],
    'Imagick::coalesceImages' => ['Imagick'],
    'Imagick::colorFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'],
    'Imagick::colorMatrixImage' => ['void', 'color_matrix'=>'string'],
    'Imagick::colorizeImage' => ['bool', 'colorize'=>'mixed', 'opacity'=>'mixed'],
    'Imagick::combineImages' => ['Imagick', 'channeltype'=>'int'],
    'Imagick::commentImage' => ['bool', 'comment'=>'string'],
    'Imagick::compareImageChannels' => ['array{Imagick, float}', 'image'=>'Imagick', 'channeltype'=>'int', 'metrictype'=>'int'],
    'Imagick::compareImageLayers' => ['Imagick', 'method'=>'int'],
    'Imagick::compareImages' => ['array{Imagick, float}', 'compare'=>'Imagick', 'metric'=>'int'],
    'Imagick::compositeImage' => ['bool', 'composite_object'=>'Imagick', 'composite'=>'int', 'x'=>'int', 'y'=>'int', 'channel='=>'int'],
    'Imagick::compositeImageGravity' => ['bool', 'Imagick'=>'Imagick', 'COMPOSITE_CONSTANT'=>'int', 'GRAVITY_CONSTANT'=>'int'],
    'Imagick::contrastImage' => ['bool', 'sharpen'=>'bool'],
    'Imagick::contrastStretchImage' => ['bool', 'black_point'=>'float', 'white_point'=>'float', 'channel='=>'int'],
    'Imagick::convolveImage' => ['bool', 'kernel'=>'array', 'channel='=>'int'],
    'Imagick::count' => ['void', 'mode='=>'string'],
    'Imagick::cropImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Imagick::cropThumbnailImage' => ['bool', 'width'=>'int', 'height'=>'int', 'legacy='=>'bool'],
    'Imagick::current' => ['Imagick'],
    'Imagick::cycleColormapImage' => ['bool', 'displace'=>'int'],
    'Imagick::decipherImage' => ['bool', 'passphrase'=>'string'],
    'Imagick::deconstructImages' => ['Imagick'],
    'Imagick::deleteImageArtifact' => ['bool', 'artifact'=>'string'],
    'Imagick::deleteImageProperty' => ['void', 'name'=>'string'],
    'Imagick::deskewImage' => ['bool', 'threshold'=>'float'],
    'Imagick::despeckleImage' => ['bool'],
    'Imagick::destroy' => ['bool'],
    'Imagick::displayImage' => ['bool', 'servername'=>'string'],
    'Imagick::displayImages' => ['bool', 'servername'=>'string'],
    'Imagick::distortImage' => ['bool', 'method'=>'int', 'arguments'=>'array', 'bestfit'=>'bool'],
    'Imagick::drawImage' => ['bool', 'draw'=>'ImagickDraw'],
    'Imagick::edgeImage' => ['bool', 'radius'=>'float'],
    'Imagick::embossImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'],
    'Imagick::encipherImage' => ['bool', 'passphrase'=>'string'],
    'Imagick::enhanceImage' => ['bool'],
    'Imagick::equalizeImage' => ['bool'],
    'Imagick::evaluateImage' => ['bool', 'op'=>'int', 'constant'=>'float', 'channel='=>'int'],
    'Imagick::evaluateImages' => ['bool', 'EVALUATE_CONSTANT'=>'int'],
    'Imagick::exportImagePixels' => ['list<int>', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int'],
    'Imagick::extentImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Imagick::filter' => ['void', 'ImagickKernel'=>'ImagickKernel', 'CHANNEL='=>'int'],
    'Imagick::flattenImages' => ['Imagick'],
    'Imagick::flipImage' => ['bool'],
    'Imagick::floodFillPaintImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'target'=>'mixed', 'x'=>'int', 'y'=>'int', 'invert'=>'bool', 'channel='=>'int'],
    'Imagick::flopImage' => ['bool'],
    'Imagick::forwardFourierTransformimage' => ['void', 'magnitude'=>'bool'],
    'Imagick::frameImage' => ['bool', 'matte_color'=>'mixed', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'],
    'Imagick::functionImage' => ['bool', 'function'=>'int', 'arguments'=>'array', 'channel='=>'int'],
    'Imagick::fxImage' => ['Imagick', 'expression'=>'string', 'channel='=>'int'],
    'Imagick::gammaImage' => ['bool', 'gamma'=>'float', 'channel='=>'int'],
    'Imagick::gaussianBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
    'Imagick::getColorspace' => ['int'],
    'Imagick::getCompression' => ['int'],
    'Imagick::getCompressionQuality' => ['int'],
    'Imagick::getConfigureOptions' => ['string'],
    'Imagick::getCopyright' => ['string'],
    'Imagick::getFeatures' => ['string'],
    'Imagick::getFilename' => ['string'],
    'Imagick::getFont' => ['string|false'],
    'Imagick::getFormat' => ['string'],
    'Imagick::getGravity' => ['int'],
    'Imagick::getHDRIEnabled' => ['int'],
    'Imagick::getHomeURL' => ['string'],
    'Imagick::getImage' => ['Imagick'],
    'Imagick::getImageAlphaChannel' => ['int'],
    'Imagick::getImageArtifact' => ['string', 'artifact'=>'string'],
    'Imagick::getImageAttribute' => ['string', 'key'=>'string'],
    'Imagick::getImageBackgroundColor' => ['ImagickPixel'],
    'Imagick::getImageBlob' => ['string'],
    'Imagick::getImageBluePrimary' => ['array{x:float, y:float}'],
    'Imagick::getImageBorderColor' => ['ImagickPixel'],
    'Imagick::getImageChannelDepth' => ['int', 'channel'=>'int'],
    'Imagick::getImageChannelDistortion' => ['float', 'reference'=>'Imagick', 'channel'=>'int', 'metric'=>'int'],
    'Imagick::getImageChannelDistortions' => ['float', 'reference'=>'Imagick', 'metric'=>'int', 'channel='=>'int'],
    'Imagick::getImageChannelExtrema' => ['array{minima:int, maxima:int}', 'channel'=>'int'],
    'Imagick::getImageChannelKurtosis' => ['array{kurtosis:float, skewness:float}', 'channel='=>'int'],
    'Imagick::getImageChannelMean' => ['array{mean:float, standardDeviation:float}', 'channel'=>'int'],
    'Imagick::getImageChannelRange' => ['array{minima:float, maxima:float}', 'channel'=>'int'],
    'Imagick::getImageChannelStatistics' => ['array<int, array{mean:float, minima:float, maxima:float, standardDeviation:float, depth:int}>'],
    'Imagick::getImageClipMask' => ['Imagick'],
    'Imagick::getImageColormapColor' => ['ImagickPixel', 'index'=>'int'],
    'Imagick::getImageColors' => ['int'],
    'Imagick::getImageColorspace' => ['int'],
    'Imagick::getImageCompose' => ['int'],
    'Imagick::getImageCompression' => ['int'],
    'Imagick::getImageCompressionQuality' => ['int'],
    'Imagick::getImageDelay' => ['int'],
    'Imagick::getImageDepth' => ['int'],
    'Imagick::getImageDispose' => ['int'],
    'Imagick::getImageDistortion' => ['float', 'reference'=>'magickwand', 'metric'=>'int'],
    'Imagick::getImageExtrema' => ['array{min:int, max:int}'],
    'Imagick::getImageFilename' => ['string'],
    'Imagick::getImageFormat' => ['string'],
    'Imagick::getImageGamma' => ['float'],
    'Imagick::getImageGeometry' => ['array{width:int, height:int}'],
    'Imagick::getImageGravity' => ['int'],
    'Imagick::getImageGreenPrimary' => ['array{x:float, y:float}'],
    'Imagick::getImageHeight' => ['int'],
    'Imagick::getImageHistogram' => ['list<ImagickPixel>'],
    'Imagick::getImageIndex' => ['int'],
    'Imagick::getImageInterlaceScheme' => ['int'],
    'Imagick::getImageInterpolateMethod' => ['int'],
    'Imagick::getImageIterations' => ['int'],
    'Imagick::getImageLength' => ['int'],
    'Imagick::getImageMagickLicense' => ['string'],
    'Imagick::getImageMatte' => ['bool'],
    'Imagick::getImageMatteColor' => ['ImagickPixel'],
    'Imagick::getImageMimeType' => ['string'],
    'Imagick::getImageOrientation' => ['int'],
    'Imagick::getImagePage' => ['array{width:int, height:int, x:int, y:int}'],
    'Imagick::getImagePixelColor' => ['ImagickPixel', 'x'=>'int', 'y'=>'int'],
    'Imagick::getImageProfile' => ['string', 'name'=>'string'],
    'Imagick::getImageProfiles' => ['array', 'pattern='=>'string', 'only_names='=>'bool'],
    'Imagick::getImageProperties' => ['array<int|string, string>', 'pattern='=>'string', 'only_names='=>'bool'],
    'Imagick::getImageProperty' => ['string|false', 'name'=>'string'],
    'Imagick::getImageRedPrimary' => ['array{x:float, y:float}'],
    'Imagick::getImageRegion' => ['Imagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Imagick::getImageRenderingIntent' => ['int'],
    'Imagick::getImageResolution' => ['array{x:float, y:float}'],
    'Imagick::getImageScene' => ['int'],
    'Imagick::getImageSignature' => ['string'],
    'Imagick::getImageSize' => ['int'],
    'Imagick::getImageTicksPerSecond' => ['int'],
    'Imagick::getImageTotalInkDensity' => ['float'],
    'Imagick::getImageType' => ['int'],
    'Imagick::getImageUnits' => ['int'],
    'Imagick::getImageVirtualPixelMethod' => ['int'],
    'Imagick::getImageWhitePoint' => ['array{x:float, y:float}'],
    'Imagick::getImageWidth' => ['int'],
    'Imagick::getImagesBlob' => ['string'],
    'Imagick::getInterlaceScheme' => ['int'],
    'Imagick::getIteratorIndex' => ['int'],
    'Imagick::getNumberImages' => ['int'],
    'Imagick::getOption' => ['string', 'key'=>'string'],
    'Imagick::getPackageName' => ['string'],
    'Imagick::getPage' => ['array{width:int, height:int, x:int, y:int}'],
    'Imagick::getPixelIterator' => ['ImagickPixelIterator'],
    'Imagick::getPixelRegionIterator' => ['ImagickPixelIterator', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'],
    'Imagick::getPointSize' => ['float'],
    'Imagick::getQuantum' => ['int'],
    'Imagick::getQuantumDepth' => ['array{quantumDepthLong:int, quantumDepthString:string}'],
    'Imagick::getQuantumRange' => ['array{quantumRangeLong:int, quantumRangeString:string}'],
    'Imagick::getRegistry' => ['string|false', 'key'=>'string'],
    'Imagick::getReleaseDate' => ['string'],
    'Imagick::getResource' => ['int', 'type'=>'int'],
    'Imagick::getResourceLimit' => ['int', 'type'=>'int'],
    'Imagick::getSamplingFactors' => ['array'],
    'Imagick::getSize' => ['array{columns:int, rows: int}'],
    'Imagick::getSizeOffset' => ['int'],
    'Imagick::getVersion' => ['array{versionNumber: int, versionString:string}'],
    'Imagick::haldClutImage' => ['bool', 'clut'=>'Imagick', 'channel='=>'int'],
    'Imagick::hasNextImage' => ['bool'],
    'Imagick::hasPreviousImage' => ['bool'],
    'Imagick::identifyFormat' => ['string|false', 'embedText'=>'string'],
    'Imagick::identifyImage' => ['array<string, mixed>', 'appendrawoutput='=>'bool'],
    'Imagick::identifyImageType' => ['int'],
    'Imagick::implodeImage' => ['bool', 'radius'=>'float'],
    'Imagick::importImagePixels' => ['bool', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int', 'pixels'=>'list<int>'],
    'Imagick::inverseFourierTransformImage' => ['void', 'complement'=>'string', 'magnitude'=>'string'],
    'Imagick::key' => ['int|string'],
    'Imagick::labelImage' => ['bool', 'label'=>'string'],
    'Imagick::levelImage' => ['bool', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'],
    'Imagick::linearStretchImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float'],
    'Imagick::liquidRescaleImage' => ['bool', 'width'=>'int', 'height'=>'int', 'delta_x'=>'float', 'rigidity'=>'float'],
    'Imagick::listRegistry' => ['array'],
    'Imagick::localContrastImage' => ['bool', 'radius'=>'float', 'strength'=>'float'],
    'Imagick::magnifyImage' => ['bool'],
    'Imagick::mapImage' => ['bool', 'map'=>'Imagick', 'dither'=>'bool'],
    'Imagick::matteFloodfillImage' => ['bool', 'alpha'=>'float', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'],
    'Imagick::medianFilterImage' => ['bool', 'radius'=>'float'],
    'Imagick::mergeImageLayers' => ['Imagick', 'layer_method'=>'int'],
    'Imagick::minifyImage' => ['bool'],
    'Imagick::modulateImage' => ['bool', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'],
    'Imagick::montageImage' => ['Imagick', 'draw'=>'ImagickDraw', 'tile_geometry'=>'string', 'thumbnail_geometry'=>'string', 'mode'=>'int', 'frame'=>'string'],
    'Imagick::morphImages' => ['Imagick', 'number_frames'=>'int'],
    'Imagick::morphology' => ['void', 'morphologyMethod'=>'int', 'iterations'=>'int', 'ImagickKernel'=>'ImagickKernel', 'CHANNEL='=>'string'],
    'Imagick::mosaicImages' => ['Imagick'],
    'Imagick::motionBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float', 'channel='=>'int'],
    'Imagick::negateImage' => ['bool', 'gray'=>'bool', 'channel='=>'int'],
    'Imagick::newImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'background'=>'mixed', 'format='=>'string'],
    'Imagick::newPseudoImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'pseudostring'=>'string'],
    'Imagick::next' => ['void'],
    'Imagick::nextImage' => ['bool'],
    'Imagick::normalizeImage' => ['bool', 'channel='=>'int'],
    'Imagick::oilPaintImage' => ['bool', 'radius'=>'float'],
    'Imagick::opaquePaintImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'invert'=>'bool', 'channel='=>'int'],
    'Imagick::optimizeImageLayers' => ['bool'],
    'Imagick::orderedPosterizeImage' => ['bool', 'threshold_map'=>'string', 'channel='=>'int'],
    'Imagick::paintFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int', 'channel='=>'int'],
    'Imagick::paintOpaqueImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'channel='=>'int'],
    'Imagick::paintTransparentImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float'],
    'Imagick::pingImage' => ['bool', 'filename'=>'string'],
    'Imagick::pingImageBlob' => ['bool', 'image'=>'string'],
    'Imagick::pingImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'],
    'Imagick::polaroidImage' => ['bool', 'properties'=>'ImagickDraw', 'angle'=>'float'],
    'Imagick::posterizeImage' => ['bool', 'levels'=>'int', 'dither'=>'bool'],
    'Imagick::previewImages' => ['bool', 'preview'=>'int'],
    'Imagick::previousImage' => ['bool'],
    'Imagick::profileImage' => ['bool', 'name'=>'string', 'profile'=>'string'],
    'Imagick::quantizeImage' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
    'Imagick::quantizeImages' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
    'Imagick::queryFontMetrics' => ['array', 'properties'=>'ImagickDraw', 'text'=>'string', 'multiline='=>'bool'],
    'Imagick::queryFonts' => ['array', 'pattern='=>'string'],
    'Imagick::queryFormats' => ['list<string>', 'pattern='=>'string'],
    'Imagick::radialBlurImage' => ['bool', 'angle'=>'float', 'channel='=>'int'],
    'Imagick::raiseImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'],
    'Imagick::randomThresholdImage' => ['bool', 'low'=>'float', 'high'=>'float', 'channel='=>'int'],
    'Imagick::readImage' => ['bool', 'filename'=>'string'],
    'Imagick::readImageBlob' => ['bool', 'image'=>'string', 'filename='=>'string'],
    'Imagick::readImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'],
    'Imagick::readImages' => ['Imagick', 'filenames'=>'string'],
    'Imagick::recolorImage' => ['bool', 'matrix'=>'list<float>'],
    'Imagick::reduceNoiseImage' => ['bool', 'radius'=>'float'],
    'Imagick::remapImage' => ['bool', 'replacement'=>'Imagick', 'dither'=>'int'],
    'Imagick::removeImage' => ['bool'],
    'Imagick::removeImageProfile' => ['string', 'name'=>'string'],
    'Imagick::render' => ['bool'],
    'Imagick::resampleImage' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float', 'filter'=>'int', 'blur'=>'float'],
    'Imagick::resetImagePage' => ['bool', 'page'=>'string'],
    'Imagick::resetIterator' => [''],
    'Imagick::resizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'filter'=>'int', 'blur'=>'float', 'bestfit='=>'bool'],
    'Imagick::rewind' => ['void'],
    'Imagick::rollImage' => ['bool', 'x'=>'int', 'y'=>'int'],
    'Imagick::rotateImage' => ['bool', 'background'=>'mixed', 'degrees'=>'float'],
    'Imagick::rotationalBlurImage' => ['void', 'angle'=>'string', 'CHANNEL='=>'string'],
    'Imagick::roundCorners' => ['bool', 'x_rounding'=>'float', 'y_rounding'=>'float', 'stroke_width='=>'float', 'displace='=>'float', 'size_correction='=>'float'],
    'Imagick::roundCornersImage' => ['', 'xRounding'=>'', 'yRounding'=>'', 'strokeWidth'=>'', 'displace'=>'', 'sizeCorrection'=>''],
    'Imagick::sampleImage' => ['bool', 'columns'=>'int', 'rows'=>'int'],
    'Imagick::scaleImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'bestfit='=>'bool'],
    'Imagick::segmentImage' => ['bool', 'colorspace'=>'int', 'cluster_threshold'=>'float', 'smooth_threshold'=>'float', 'verbose='=>'bool'],
    'Imagick::selectiveBlurImage' => ['void', 'radius'=>'float', 'sigma'=>'float', 'threshold'=>'float', 'CHANNEL'=>'int'],
    'Imagick::separateImageChannel' => ['bool', 'channel'=>'int'],
    'Imagick::sepiaToneImage' => ['bool', 'threshold'=>'float'],
    'Imagick::setAntiAlias' => ['int', 'antialias'=>'bool'],
    'Imagick::setBackgroundColor' => ['bool', 'background'=>'mixed'],
    'Imagick::setColorspace' => ['bool', 'colorspace'=>'int'],
    'Imagick::setCompression' => ['bool', 'compression'=>'int'],
    'Imagick::setCompressionQuality' => ['bool', 'quality'=>'int'],
    'Imagick::setFilename' => ['bool', 'filename'=>'string'],
    'Imagick::setFirstIterator' => ['bool'],
    'Imagick::setFont' => ['bool', 'font'=>'string'],
    'Imagick::setFormat' => ['bool', 'format'=>'string'],
    'Imagick::setGravity' => ['bool', 'gravity'=>'int'],
    'Imagick::setImage' => ['bool', 'replace'=>'Imagick'],
    'Imagick::setImageAlpha' => ['bool', 'alpha'=>'float'],
    'Imagick::setImageAlphaChannel' => ['bool', 'mode'=>'int'],
    'Imagick::setImageArtifact' => ['bool', 'artifact'=>'string', 'value'=>'string'],
    'Imagick::setImageAttribute' => ['void', 'key'=>'string', 'value'=>'string'],
    'Imagick::setImageBackgroundColor' => ['bool', 'background'=>'mixed'],
    'Imagick::setImageBias' => ['bool', 'bias'=>'float'],
    'Imagick::setImageBiasQuantum' => ['void', 'bias'=>'string'],
    'Imagick::setImageBluePrimary' => ['bool', 'x'=>'float', 'y'=>'float'],
    'Imagick::setImageBorderColor' => ['bool', 'border'=>'mixed'],
    'Imagick::setImageChannelDepth' => ['bool', 'channel'=>'int', 'depth'=>'int'],
    'Imagick::setImageChannelMask' => ['', 'channel'=>'int'],
    'Imagick::setImageClipMask' => ['bool', 'clip_mask'=>'Imagick'],
    'Imagick::setImageColormapColor' => ['bool', 'index'=>'int', 'color'=>'ImagickPixel'],
    'Imagick::setImageColorspace' => ['bool', 'colorspace'=>'int'],
    'Imagick::setImageCompose' => ['bool', 'compose'=>'int'],
    'Imagick::setImageCompression' => ['bool', 'compression'=>'int'],
    'Imagick::setImageCompressionQuality' => ['bool', 'quality'=>'int'],
    'Imagick::setImageDelay' => ['bool', 'delay'=>'int'],
    'Imagick::setImageDepth' => ['bool', 'depth'=>'int'],
    'Imagick::setImageDispose' => ['bool', 'dispose'=>'int'],
    'Imagick::setImageExtent' => ['bool', 'columns'=>'int', 'rows'=>'int'],
    'Imagick::setImageFilename' => ['bool', 'filename'=>'string'],
    'Imagick::setImageFormat' => ['bool', 'format'=>'string'],
    'Imagick::setImageGamma' => ['bool', 'gamma'=>'float'],
    'Imagick::setImageGravity' => ['bool', 'gravity'=>'int'],
    'Imagick::setImageGreenPrimary' => ['bool', 'x'=>'float', 'y'=>'float'],
    'Imagick::setImageIndex' => ['bool', 'index'=>'int'],
    'Imagick::setImageInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'],
    'Imagick::setImageInterpolateMethod' => ['bool', 'method'=>'int'],
    'Imagick::setImageIterations' => ['bool', 'iterations'=>'int'],
    'Imagick::setImageMatte' => ['bool', 'matte'=>'bool'],
    'Imagick::setImageMatteColor' => ['bool', 'matte'=>'mixed'],
    'Imagick::setImageOpacity' => ['bool', 'opacity'=>'float'],
    'Imagick::setImageOrientation' => ['bool', 'orientation'=>'int'],
    'Imagick::setImagePage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Imagick::setImageProfile' => ['bool', 'name'=>'string', 'profile'=>'string'],
    'Imagick::setImageProgressMonitor' => ['', 'filename'=>''],
    'Imagick::setImageProperty' => ['bool', 'name'=>'string', 'value'=>'string'],
    'Imagick::setImageRedPrimary' => ['bool', 'x'=>'float', 'y'=>'float'],
    'Imagick::setImageRenderingIntent' => ['bool', 'rendering_intent'=>'int'],
    'Imagick::setImageResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'],
    'Imagick::setImageScene' => ['bool', 'scene'=>'int'],
    'Imagick::setImageTicksPerSecond' => ['bool', 'ticks_per_second'=>'int'],
    'Imagick::setImageType' => ['bool', 'image_type'=>'int'],
    'Imagick::setImageUnits' => ['bool', 'units'=>'int'],
    'Imagick::setImageVirtualPixelMethod' => ['bool', 'method'=>'int'],
    'Imagick::setImageWhitePoint' => ['bool', 'x'=>'float', 'y'=>'float'],
    'Imagick::setInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'],
    'Imagick::setIteratorIndex' => ['bool', 'index'=>'int'],
    'Imagick::setLastIterator' => ['bool'],
    'Imagick::setOption' => ['bool', 'key'=>'string', 'value'=>'string'],
    'Imagick::setPage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Imagick::setPointSize' => ['bool', 'point_size'=>'float'],
    'Imagick::setProgressMonitor' => ['void', 'callback'=>'callable'],
    'Imagick::setRegistry' => ['void', 'key'=>'string', 'value'=>'string'],
    'Imagick::setResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'],
    'Imagick::setResourceLimit' => ['bool', 'type'=>'int', 'limit'=>'int'],
    'Imagick::setSamplingFactors' => ['bool', 'factors'=>'list<string>'],
    'Imagick::setSize' => ['bool', 'columns'=>'int', 'rows'=>'int'],
    'Imagick::setSizeOffset' => ['bool', 'columns'=>'int', 'rows'=>'int', 'offset'=>'int'],
    'Imagick::setType' => ['bool', 'image_type'=>'int'],
    'Imagick::shadeImage' => ['bool', 'gray'=>'bool', 'azimuth'=>'float', 'elevation'=>'float'],
    'Imagick::shadowImage' => ['bool', 'opacity'=>'float', 'sigma'=>'float', 'x'=>'int', 'y'=>'int'],
    'Imagick::sharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
    'Imagick::shaveImage' => ['bool', 'columns'=>'int', 'rows'=>'int'],
    'Imagick::shearImage' => ['bool', 'background'=>'mixed', 'x_shear'=>'float', 'y_shear'=>'float'],
    'Imagick::sigmoidalContrastImage' => ['bool', 'sharpen'=>'bool', 'alpha'=>'float', 'beta'=>'float', 'channel='=>'int'],
    'Imagick::similarityImage' => ['Imagick', 'Imagick'=>'Imagick', '&bestMatch'=>'array', '&similarity'=>'float', 'similarity_threshold'=>'float', 'metric'=>'int'],
    'Imagick::sketchImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'],
    'Imagick::smushImages' => ['Imagick', 'stack'=>'string', 'offset'=>'string'],
    'Imagick::solarizeImage' => ['bool', 'threshold'=>'int'],
    'Imagick::sparseColorImage' => ['bool', 'sparse_method'=>'int', 'arguments'=>'array', 'channel='=>'int'],
    'Imagick::spliceImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
    'Imagick::spreadImage' => ['bool', 'radius'=>'float'],
    'Imagick::statisticImage' => ['void', 'type'=>'int', 'width'=>'int', 'height'=>'int', 'CHANNEL='=>'string'],
    'Imagick::steganoImage' => ['Imagick', 'watermark_wand'=>'Imagick', 'offset'=>'int'],
    'Imagick::stereoImage' => ['bool', 'offset_wand'=>'Imagick'],
    'Imagick::stripImage' => ['bool'],
    'Imagick::subImageMatch' => ['Imagick', 'Imagick'=>'Imagick', '&w_offset='=>'array', '&w_similarity='=>'float'],
    'Imagick::swirlImage' => ['bool', 'degrees'=>'float'],
    'Imagick::textureImage' => ['bool', 'texture_wand'=>'Imagick'],
    'Imagick::thresholdImage' => ['bool', 'threshold'=>'float', 'channel='=>'int'],
    'Imagick::thumbnailImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool', 'fill='=>'bool', 'legacy='=>'bool'],
    'Imagick::tintImage' => ['bool', 'tint'=>'mixed', 'opacity'=>'mixed'],
    'Imagick::transformImage' => ['Imagick', 'crop'=>'string', 'geometry'=>'string'],
    'Imagick::transformImageColorspace' => ['bool', 'colorspace'=>'int'],
    'Imagick::transparentPaintImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float', 'invert'=>'bool'],
    'Imagick::transposeImage' => ['bool'],
    'Imagick::transverseImage' => ['bool'],
    'Imagick::trimImage' => ['bool', 'fuzz'=>'float'],
    'Imagick::uniqueImageColors' => ['bool'],
    'Imagick::unsharpMaskImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'amount'=>'float', 'threshold'=>'float', 'channel='=>'int'],
    'Imagick::valid' => ['bool'],
    'Imagick::vignetteImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float', 'x'=>'int', 'y'=>'int'],
    'Imagick::waveImage' => ['bool', 'amplitude'=>'float', 'length'=>'float'],
    'Imagick::whiteThresholdImage' => ['bool', 'threshold'=>'mixed'],
    'Imagick::writeImage' => ['bool', 'filename='=>'string'],
    'Imagick::writeImageFile' => ['bool', 'filehandle'=>'resource'],
    'Imagick::writeImages' => ['bool', 'filename'=>'string', 'adjoin'=>'bool'],
    'Imagick::writeImagesFile' => ['bool', 'filehandle'=>'resource'],
    'ImagickDraw::__construct' => ['void'],
    'ImagickDraw::affine' => ['bool', 'affine'=>'array<string, float>'],
    'ImagickDraw::annotation' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'],
    'ImagickDraw::arc' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'],
    'ImagickDraw::bezier' => ['bool', 'coordinates'=>'list<array{x:float, y:float}>'],
    'ImagickDraw::circle' => ['bool', 'ox'=>'float', 'oy'=>'float', 'px'=>'float', 'py'=>'float'],
    'ImagickDraw::clear' => ['bool'],
    'ImagickDraw::clone' => ['ImagickDraw'],
    'ImagickDraw::color' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'],
    'ImagickDraw::comment' => ['bool', 'comment'=>'string'],
    'ImagickDraw::composite' => ['bool', 'compose'=>'int', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float', 'compositewand'=>'Imagick'],
    'ImagickDraw::destroy' => ['bool'],
    'ImagickDraw::ellipse' => ['bool', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'],
    'ImagickDraw::getBorderColor' => ['ImagickPixel'],
    'ImagickDraw::getClipPath' => ['string|false'],
    'ImagickDraw::getClipRule' => ['int'],
    'ImagickDraw::getClipUnits' => ['int'],
    'ImagickDraw::getDensity' => ['?string'],
    'ImagickDraw::getFillColor' => ['ImagickPixel'],
    'ImagickDraw::getFillOpacity' => ['float'],
    'ImagickDraw::getFillRule' => ['int'],
    'ImagickDraw::getFont' => ['string|false'],
    'ImagickDraw::getFontFamily' => ['string|false'],
    'ImagickDraw::getFontResolution' => ['array'],
    'ImagickDraw::getFontSize' => ['float'],
    'ImagickDraw::getFontStretch' => ['int'],
    'ImagickDraw::getFontStyle' => ['int'],
    'ImagickDraw::getFontWeight' => ['int'],
    'ImagickDraw::getGravity' => ['int'],
    'ImagickDraw::getOpacity' => ['float'],
    'ImagickDraw::getStrokeAntialias' => ['bool'],
    'ImagickDraw::getStrokeColor' => ['ImagickPixel'],
    'ImagickDraw::getStrokeDashArray' => ['array'],
    'ImagickDraw::getStrokeDashOffset' => ['float'],
    'ImagickDraw::getStrokeLineCap' => ['int'],
    'ImagickDraw::getStrokeLineJoin' => ['int'],
    'ImagickDraw::getStrokeMiterLimit' => ['int'],
    'ImagickDraw::getStrokeOpacity' => ['float'],
    'ImagickDraw::getStrokeWidth' => ['float'],
    'ImagickDraw::getTextAlignment' => ['int'],
    'ImagickDraw::getTextAntialias' => ['bool'],
    'ImagickDraw::getTextDecoration' => ['int'],
    'ImagickDraw::getTextDirection' => ['bool'],
    'ImagickDraw::getTextEncoding' => ['string'],
    'ImagickDraw::getTextInterlineSpacing' => ['float'],
    'ImagickDraw::getTextInterwordSpacing' => ['float'],
    'ImagickDraw::getTextKerning' => ['float'],
    'ImagickDraw::getTextUnderColor' => ['ImagickPixel'],
    'ImagickDraw::getVectorGraphics' => ['string'],
    'ImagickDraw::line' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'],
    'ImagickDraw::matte' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'],
    'ImagickDraw::pathClose' => ['bool'],
    'ImagickDraw::pathCurveToAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathCurveToQuadraticBezierAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathCurveToQuadraticBezierRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathCurveToQuadraticBezierSmoothAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathCurveToQuadraticBezierSmoothRelative' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathCurveToRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathCurveToSmoothAbsolute' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathCurveToSmoothRelative' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathEllipticArcAbsolute' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathEllipticArcRelative' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathFinish' => ['bool'],
    'ImagickDraw::pathLineToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathLineToHorizontalAbsolute' => ['bool', 'x'=>'float'],
    'ImagickDraw::pathLineToHorizontalRelative' => ['bool', 'x'=>'float'],
    'ImagickDraw::pathLineToRelative' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathLineToVerticalAbsolute' => ['bool', 'y'=>'float'],
    'ImagickDraw::pathLineToVerticalRelative' => ['bool', 'y'=>'float'],
    'ImagickDraw::pathMoveToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathMoveToRelative' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::pathStart' => ['bool'],
    'ImagickDraw::point' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::polygon' => ['bool', 'coordinates'=>'list<array{x:float, y:float}>'],
    'ImagickDraw::polyline' => ['bool', 'coordinates'=>'list<array{x:float, y:float}>'],
    'ImagickDraw::pop' => ['bool'],
    'ImagickDraw::popClipPath' => ['bool'],
    'ImagickDraw::popDefs' => ['bool'],
    'ImagickDraw::popPattern' => ['bool'],
    'ImagickDraw::push' => ['bool'],
    'ImagickDraw::pushClipPath' => ['bool', 'clip_mask_id'=>'string'],
    'ImagickDraw::pushDefs' => ['bool'],
    'ImagickDraw::pushPattern' => ['bool', 'pattern_id'=>'string', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
    'ImagickDraw::rectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'],
    'ImagickDraw::render' => ['bool'],
    'ImagickDraw::resetVectorGraphics' => ['void'],
    'ImagickDraw::rotate' => ['bool', 'degrees'=>'float'],
    'ImagickDraw::roundRectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'],
    'ImagickDraw::scale' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::setBorderColor' => ['bool', 'color'=>'ImagickPixel|string'],
    'ImagickDraw::setClipPath' => ['bool', 'clip_mask'=>'string'],
    'ImagickDraw::setClipRule' => ['bool', 'fill_rule'=>'int'],
    'ImagickDraw::setClipUnits' => ['bool', 'clip_units'=>'int'],
    'ImagickDraw::setDensity' => ['bool', 'density_string'=>'string'],
    'ImagickDraw::setFillAlpha' => ['bool', 'opacity'=>'float'],
    'ImagickDraw::setFillColor' => ['bool', 'fill_pixel'=>'ImagickPixel|string'],
    'ImagickDraw::setFillOpacity' => ['bool', 'fillopacity'=>'float'],
    'ImagickDraw::setFillPatternURL' => ['bool', 'fill_url'=>'string'],
    'ImagickDraw::setFillRule' => ['bool', 'fill_rule'=>'int'],
    'ImagickDraw::setFont' => ['bool', 'font_name'=>'string'],
    'ImagickDraw::setFontFamily' => ['bool', 'font_family'=>'string'],
    'ImagickDraw::setFontResolution' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickDraw::setFontSize' => ['bool', 'pointsize'=>'float'],
    'ImagickDraw::setFontStretch' => ['bool', 'fontstretch'=>'int'],
    'ImagickDraw::setFontStyle' => ['bool', 'style'=>'int'],
    'ImagickDraw::setFontWeight' => ['bool', 'font_weight'=>'int'],
    'ImagickDraw::setGravity' => ['bool', 'gravity'=>'int'],
    'ImagickDraw::setOpacity' => ['void', 'opacity'=>'float'],
    'ImagickDraw::setResolution' => ['void', 'x_resolution'=>'float', 'y_resolution'=>'float'],
    'ImagickDraw::setStrokeAlpha' => ['bool', 'opacity'=>'float'],
    'ImagickDraw::setStrokeAntialias' => ['bool', 'stroke_antialias'=>'bool'],
    'ImagickDraw::setStrokeColor' => ['bool', 'stroke_pixel'=>'ImagickPixel|string'],
    'ImagickDraw::setStrokeDashArray' => ['bool', 'dasharray'=>'list<int|float>'],
    'ImagickDraw::setStrokeDashOffset' => ['bool', 'dash_offset'=>'float'],
    'ImagickDraw::setStrokeLineCap' => ['bool', 'linecap'=>'int'],
    'ImagickDraw::setStrokeLineJoin' => ['bool', 'linejoin'=>'int'],
    'ImagickDraw::setStrokeMiterLimit' => ['bool', 'miterlimit'=>'int'],
    'ImagickDraw::setStrokeOpacity' => ['bool', 'stroke_opacity'=>'float'],
    'ImagickDraw::setStrokePatternURL' => ['bool', 'stroke_url'=>'string'],
    'ImagickDraw::setStrokeWidth' => ['bool', 'stroke_width'=>'float'],
    'ImagickDraw::setTextAlignment' => ['bool', 'alignment'=>'int'],
    'ImagickDraw::setTextAntialias' => ['bool', 'antialias'=>'bool'],
    'ImagickDraw::setTextDecoration' => ['bool', 'decoration'=>'int'],
    'ImagickDraw::setTextDirection' => ['bool', 'direction'=>'int'],
    'ImagickDraw::setTextEncoding' => ['bool', 'encoding'=>'string'],
    'ImagickDraw::setTextInterlineSpacing' => ['void', 'spacing'=>'float'],
    'ImagickDraw::setTextInterwordSpacing' => ['void', 'spacing'=>'float'],
    'ImagickDraw::setTextKerning' => ['void', 'kerning'=>'float'],
    'ImagickDraw::setTextUnderColor' => ['bool', 'under_color'=>'ImagickPixel|string'],
    'ImagickDraw::setVectorGraphics' => ['bool', 'xml'=>'string'],
    'ImagickDraw::setViewbox' => ['bool', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int'],
    'ImagickDraw::skewX' => ['bool', 'degrees'=>'float'],
    'ImagickDraw::skewY' => ['bool', 'degrees'=>'float'],
    'ImagickDraw::translate' => ['bool', 'x'=>'float', 'y'=>'float'],
    'ImagickKernel::addKernel' => ['void', 'ImagickKernel'=>'ImagickKernel'],
    'ImagickKernel::addUnityKernel' => ['void'],
    'ImagickKernel::fromBuiltin' => ['ImagickKernel', 'kernelType'=>'string', 'kernelString'=>'string'],
    'ImagickKernel::fromMatrix' => ['ImagickKernel', 'matrix'=>'list<list<float>>', 'origin='=>'array'],
    'ImagickKernel::getMatrix' => ['list<list<float|false>>'],
    'ImagickKernel::scale' => ['void'],
    'ImagickKernel::separate' => ['ImagickKernel[]'],
    'ImagickKernel::seperate' => ['void'],
    'ImagickPixel::__construct' => ['void', 'color='=>'string'],
    'ImagickPixel::clear' => ['bool'],
    'ImagickPixel::clone' => ['void'],
    'ImagickPixel::destroy' => ['bool'],
    'ImagickPixel::getColor' => ['array{r: int|float, g: int|float, b: int|float, a: int|float}', 'normalized='=>'0|1|2'],
    'ImagickPixel::getColorAsString' => ['string'],
    'ImagickPixel::getColorCount' => ['int'],
    'ImagickPixel::getColorQuantum' => ['mixed'],
    'ImagickPixel::getColorValue' => ['float', 'color'=>'int'],
    'ImagickPixel::getColorValueQuantum' => ['mixed'],
    'ImagickPixel::getHSL' => ['array{hue: float, saturation: float, luminosity: float}'],
    'ImagickPixel::getIndex' => ['int'],
    'ImagickPixel::isPixelSimilar' => ['bool', 'color'=>'ImagickPixel', 'fuzz'=>'float'],
    'ImagickPixel::isPixelSimilarQuantum' => ['bool', 'color'=>'string', 'fuzz='=>'string'],
    'ImagickPixel::isSimilar' => ['bool', 'color'=>'ImagickPixel', 'fuzz'=>'float'],
    'ImagickPixel::setColor' => ['bool', 'color'=>'string'],
    'ImagickPixel::setColorFromPixel' => ['bool', 'srcPixel'=>'ImagickPixel'],
    'ImagickPixel::setColorValue' => ['bool', 'color'=>'int', 'value'=>'float'],
    'ImagickPixel::setColorValueQuantum' => ['void', 'color'=>'int', 'value'=>'mixed'],
    'ImagickPixel::setHSL' => ['bool', 'hue'=>'float', 'saturation'=>'float', 'luminosity'=>'float'],
    'ImagickPixel::setIndex' => ['void', 'index'=>'int'],
    'ImagickPixel::setcolorcount' => ['void', 'colorCount'=>'string'],
    'ImagickPixelIterator::__construct' => ['void', 'wand'=>'Imagick'],
    'ImagickPixelIterator::clear' => ['bool'],
    'ImagickPixelIterator::current' => ['mixed'],
    'ImagickPixelIterator::destroy' => ['bool'],
    'ImagickPixelIterator::getCurrentIteratorRow' => ['array'],
    'ImagickPixelIterator::getIteratorRow' => ['int'],
    'ImagickPixelIterator::getNextIteratorRow' => ['array'],
    'ImagickPixelIterator::getPreviousIteratorRow' => ['array'],
    'ImagickPixelIterator::getpixeliterator' => ['', 'Imagick'=>'Imagick'],
    'ImagickPixelIterator::getpixelregioniterator' => ['', 'Imagick'=>'Imagick', 'x'=>'', 'y'=>'', 'columns'=>'', 'rows'=>''],
    'ImagickPixelIterator::key' => ['int|string'],
    'ImagickPixelIterator::newPixelIterator' => ['bool', 'wand'=>'Imagick'],
    'ImagickPixelIterator::newPixelRegionIterator' => ['bool', 'wand'=>'Imagick', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'],
    'ImagickPixelIterator::next' => ['void'],
    'ImagickPixelIterator::resetIterator' => ['bool'],
    'ImagickPixelIterator::rewind' => ['void'],
    'ImagickPixelIterator::setIteratorFirstRow' => ['bool'],
    'ImagickPixelIterator::setIteratorLastRow' => ['bool'],
    'ImagickPixelIterator::setIteratorRow' => ['bool', 'row'=>'int'],
    'ImagickPixelIterator::syncIterator' => ['bool'],
    'ImagickPixelIterator::valid' => ['bool'],
    'InfiniteIterator::__construct' => ['void', 'iterator'=>'Iterator'],
    'InfiniteIterator::current' => ['mixed'],
    'InfiniteIterator::getInnerIterator' => ['Iterator'],
    'InfiniteIterator::key' => ['bool|float|int|string'],
    'InfiniteIterator::next' => ['void'],
    'InfiniteIterator::rewind' => ['void'],
    'InfiniteIterator::valid' => ['bool'],
    'IntlBreakIterator::__construct' => ['void'],
    'IntlBreakIterator::createCharacterInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'],
    'IntlBreakIterator::createLineInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlBreakIterator::createSentenceInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlBreakIterator::createTitleInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlBreakIterator::createWordInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlBreakIterator::current' => ['int'],
    'IntlBreakIterator::first' => ['int'],
    'IntlBreakIterator::following' => ['int', 'offset'=>'int'],
    'IntlBreakIterator::getErrorCode' => ['int'],
    'IntlBreakIterator::getErrorMessage' => ['string'],
    'IntlBreakIterator::getLocale' => ['string', 'locale_type'=>'string'],
    'IntlBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'int'],
    'IntlBreakIterator::getText' => ['?string'],
    'IntlBreakIterator::isBoundary' => ['bool', 'offset'=>'int'],
    'IntlBreakIterator::last' => ['int'],
    'IntlBreakIterator::next' => ['int', 'offset='=>'?int'],
    'IntlBreakIterator::preceding' => ['int', 'offset'=>'int'],
    'IntlBreakIterator::previous' => ['int'],
    'IntlBreakIterator::setText' => ['?bool', 'text'=>'string'],
    'IntlCalendar::__construct' => ['void'],
    'IntlCalendar::add' => ['bool', 'field'=>'int', 'amount'=>'int'],
    'IntlCalendar::after' => ['bool', 'other'=>'IntlCalendar'],
    'IntlCalendar::before' => ['bool', 'other'=>'IntlCalendar'],
    'IntlCalendar::clear' => ['bool', 'field='=>'?int'],
    'IntlCalendar::createInstance' => ['IntlCalendar', 'timeZone='=>'mixed', 'locale='=>'string'],
    'IntlCalendar::equals' => ['bool', 'other'=>'IntlCalendar'],
    'IntlCalendar::fieldDifference' => ['int', 'when'=>'float', 'field'=>'int'],
    'IntlCalendar::fromDateTime' => ['IntlCalendar', 'dateTime'=>'DateTime|string'],
    'IntlCalendar::get' => ['int', 'field'=>'int'],
    'IntlCalendar::getActualMaximum' => ['int', 'field'=>'int'],
    'IntlCalendar::getActualMinimum' => ['int', 'field'=>'int'],
    'IntlCalendar::getAvailableLocales' => ['array'],
    'IntlCalendar::getDayOfWeekType' => ['int', 'dayOfWeek'=>'int'],
    'IntlCalendar::getErrorCode' => ['int'],
    'IntlCalendar::getErrorMessage' => ['string'],
    'IntlCalendar::getFirstDayOfWeek' => ['int'],
    'IntlCalendar::getGreatestMinimum' => ['int', 'field'=>'int'],
    'IntlCalendar::getKeywordValuesForLocale' => ['Iterator|false', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'],
    'IntlCalendar::getLeastMaximum' => ['int', 'field'=>'int'],
    'IntlCalendar::getLocale' => ['string', 'localeType'=>'int'],
    'IntlCalendar::getMaximum' => ['int|false', 'field'=>'int'],
    'IntlCalendar::getMinimalDaysInFirstWeek' => ['int'],
    'IntlCalendar::getMinimum' => ['int', 'field'=>'int'],
    'IntlCalendar::getNow' => ['float'],
    'IntlCalendar::getRepeatedWallTimeOption' => ['int'],
    'IntlCalendar::getSkippedWallTimeOption' => ['int'],
    'IntlCalendar::getTime' => ['float'],
    'IntlCalendar::getTimeZone' => ['IntlTimeZone'],
    'IntlCalendar::getType' => ['string'],
    'IntlCalendar::getWeekendTransition' => ['int', 'dayOfWeek'=>'string'],
    'IntlCalendar::inDaylightTime' => ['bool'],
    'IntlCalendar::isEquivalentTo' => ['bool', 'other'=>'IntlCalendar'],
    'IntlCalendar::isLenient' => ['bool'],
    'IntlCalendar::isSet' => ['bool', 'field'=>'int'],
    'IntlCalendar::isWeekend' => ['bool', 'date='=>'?float'],
    'IntlCalendar::roll' => ['bool', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'],
    'IntlCalendar::set' => ['bool', 'field'=>'int', 'value'=>'int'],
    'IntlCalendar::set\'1' => ['bool', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'],
    'IntlCalendar::setFirstDayOfWeek' => ['bool', 'dayOfWeek'=>'int'],
    'IntlCalendar::setLenient' => ['bool', 'isLenient'=>'string'],
    'IntlCalendar::setMinimalDaysInFirstWeek' => ['bool', 'minimalDays'=>'int'],
    'IntlCalendar::setRepeatedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
    'IntlCalendar::setSkippedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
    'IntlCalendar::setTime' => ['bool', 'date'=>'float'],
    'IntlCalendar::setTimeZone' => ['bool', 'timeZone'=>'mixed'],
    'IntlCalendar::toDateTime' => ['DateTime|false'],
    'IntlChar::charAge' => ['array', 'char'=>'int|string'],
    'IntlChar::charDigitValue' => ['int', 'codepoint'=>'mixed'],
    'IntlChar::charDirection' => ['int', 'codepoint'=>'mixed'],
    'IntlChar::charFromName' => ['?int', 'name'=>'string', 'namechoice='=>'int'],
    'IntlChar::charMirror' => ['mixed', 'codepoint'=>'mixed'],
    'IntlChar::charName' => ['string', 'char'=>'int|string', 'namechoice='=>'int'],
    'IntlChar::charType' => ['int', 'codepoint'=>'mixed'],
    'IntlChar::chr' => ['string', 'codepoint'=>'mixed'],
    'IntlChar::digit' => ['int|false', 'char'=>'int|string', 'radix='=>'int'],
    'IntlChar::enumCharNames' => ['void', 'start'=>'mixed', 'limit'=>'mixed', 'callback'=>'callable', 'nameChoice='=>'int'],
    'IntlChar::enumCharTypes' => ['void', 'cb='=>'callable'],
    'IntlChar::foldCase' => ['int|string', 'char'=>'int|string', 'options='=>'int'],
    'IntlChar::forDigit' => ['int', 'digit'=>'int', 'radix'=>'int'],
    'IntlChar::getBidiPairedBracket' => ['mixed', 'codepoint'=>'mixed'],
    'IntlChar::getBlockCode' => ['int', 'char'=>'int|string'],
    'IntlChar::getCombiningClass' => ['int', 'codepoint'=>'mixed'],
    'IntlChar::getFC_NFKC_Closure' => ['string', 'char'=>'int|string'],
    'IntlChar::getIntPropertyMaxValue' => ['int', 'property'=>'int'],
    'IntlChar::getIntPropertyMinValue' => ['int', 'property'=>'int'],
    'IntlChar::getIntPropertyValue' => ['int', 'char'=>'int|string', 'property'=>'int'],
    'IntlChar::getNumericValue' => ['float', 'char'=>'int|string'],
    'IntlChar::getPropertyEnum' => ['int', 'alias'=>'string'],
    'IntlChar::getPropertyName' => ['string|false', 'property'=>'int', 'namechoice='=>'int'],
    'IntlChar::getPropertyValueEnum' => ['int', 'property'=>'int', 'name'=>'string'],
    'IntlChar::getPropertyValueName' => ['string|false', 'prop'=>'int', 'value'=>'int', 'namechoice='=>'int'],
    'IntlChar::getUnicodeVersion' => ['array'],
    'IntlChar::hasBinaryProperty' => ['bool', 'char'=>'int|string', 'property'=>'int'],
    'IntlChar::isIDIgnorable' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isIDPart' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isIDStart' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isISOControl' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isJavaIDPart' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isJavaIDStart' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isJavaSpaceChar' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isMirrored' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isUAlphabetic' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isULowercase' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isUUppercase' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isUWhiteSpace' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isWhitespace' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isalnum' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isalpha' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isbase' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isblank' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::iscntrl' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isdefined' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isdigit' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isgraph' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::islower' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isprint' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::ispunct' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isspace' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::istitle' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isupper' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::isxdigit' => ['bool', 'codepoint'=>'mixed'],
    'IntlChar::ord' => ['int', 'character'=>'mixed'],
    'IntlChar::tolower' => ['mixed', 'codepoint'=>'mixed'],
    'IntlChar::totitle' => ['mixed', 'codepoint'=>'mixed'],
    'IntlChar::toupper' => ['mixed', 'codepoint'=>'mixed'],
    'IntlCodePointBreakIterator::__construct' => ['void'],
    'IntlCodePointBreakIterator::createCharacterInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlCodePointBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'],
    'IntlCodePointBreakIterator::createLineInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlCodePointBreakIterator::createSentenceInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlCodePointBreakIterator::createTitleInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlCodePointBreakIterator::createWordInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlCodePointBreakIterator::current' => ['int'],
    'IntlCodePointBreakIterator::first' => ['int'],
    'IntlCodePointBreakIterator::following' => ['int', 'offset'=>'string'],
    'IntlCodePointBreakIterator::getErrorCode' => ['int'],
    'IntlCodePointBreakIterator::getErrorMessage' => ['string'],
    'IntlCodePointBreakIterator::getLastCodePoint' => ['int'],
    'IntlCodePointBreakIterator::getLocale' => ['string', 'locale_type'=>'string'],
    'IntlCodePointBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'string'],
    'IntlCodePointBreakIterator::getText' => ['?string'],
    'IntlCodePointBreakIterator::isBoundary' => ['bool', 'offset'=>'string'],
    'IntlCodePointBreakIterator::last' => ['int'],
    'IntlCodePointBreakIterator::next' => ['int', 'offset='=>'string'],
    'IntlCodePointBreakIterator::preceding' => ['int', 'offset'=>'string'],
    'IntlCodePointBreakIterator::previous' => ['int'],
    'IntlCodePointBreakIterator::setText' => ['?bool', 'text'=>'string'],
    'IntlDateFormatter::__construct' => ['void', 'locale'=>'?string', 'datetype'=>'null|int', 'timetype'=>'null|int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
    'IntlDateFormatter::create' => ['?IntlDateFormatter', 'locale'=>'?string', 'datetype'=>'null|int', 'timetype'=>'null|int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
    'IntlDateFormatter::format' => ['string|false', 'value'=>'IntlCalendar|DateTime|array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int}|array{tm_sec: int, tm_min: int, tm_hour: int, tm_mday: int, tm_mon: int, tm_year: int, tm_wday: int, tm_yday: int, tm_isdst: int}|string|int|float'],
    'IntlDateFormatter::formatObject' => ['string|false', 'object'=>'IntlCalendar|DateTime', 'format='=>'array{0: int, 1: int}|int|string|null', 'locale='=>'?string'],
    'IntlDateFormatter::getCalendar' => ['int'],
    'IntlDateFormatter::getCalendarObject' => ['IntlCalendar'],
    'IntlDateFormatter::getDateType' => ['int'],
    'IntlDateFormatter::getErrorCode' => ['int'],
    'IntlDateFormatter::getErrorMessage' => ['string'],
    'IntlDateFormatter::getLocale' => ['string', 'which='=>'int'],
    'IntlDateFormatter::getPattern' => ['string'],
    'IntlDateFormatter::getTimeType' => ['int'],
    'IntlDateFormatter::getTimeZone' => ['IntlTimeZone|false'],
    'IntlDateFormatter::getTimeZoneId' => ['string'],
    'IntlDateFormatter::isLenient' => ['bool'],
    'IntlDateFormatter::localtime' => ['array', 'value'=>'string', '&rw_position='=>'int'],
    'IntlDateFormatter::parse' => ['int|float', 'value'=>'string', '&rw_position='=>'int'],
    'IntlDateFormatter::setCalendar' => ['bool', 'which'=>'IntlCalendar|int|null'],
    'IntlDateFormatter::setLenient' => ['bool', 'lenient'=>'bool'],
    'IntlDateFormatter::setPattern' => ['bool', 'pattern'=>'string'],
    'IntlDateFormatter::setTimeZone' => ['null|false', 'zone'=>'IntlTimeZone|DateTimeZone|string|null'],
    'IntlException::__clone' => ['void'],
    'IntlException::__construct' => ['void'],
    'IntlException::__toString' => ['string'],
    'IntlException::__wakeup' => ['void'],
    'IntlException::getCode' => ['int'],
    'IntlException::getFile' => ['string'],
    'IntlException::getLine' => ['int'],
    'IntlException::getMessage' => ['string'],
    'IntlException::getPrevious' => ['?Throwable'],
    'IntlException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'IntlException::getTraceAsString' => ['string'],
    'IntlGregorianCalendar::__construct' => ['void'],
    'IntlGregorianCalendar::add' => ['bool', 'field'=>'int', 'amount'=>'int'],
    'IntlGregorianCalendar::after' => ['bool', 'other'=>'IntlCalendar'],
    'IntlGregorianCalendar::before' => ['bool', 'other'=>'IntlCalendar'],
    'IntlGregorianCalendar::clear' => ['bool', 'field='=>'?int'],
    'IntlGregorianCalendar::createInstance' => ['IntlGregorianCalendar', 'timeZone='=>'mixed', 'locale='=>'string'],
    'IntlGregorianCalendar::equals' => ['bool', 'other'=>'IntlCalendar'],
    'IntlGregorianCalendar::fieldDifference' => ['int', 'when'=>'float', 'field'=>'int'],
    'IntlGregorianCalendar::fromDateTime' => ['IntlCalendar', 'dateTime'=>'DateTime|string'],
    'IntlGregorianCalendar::get' => ['int', 'field'=>'int'],
    'IntlGregorianCalendar::getActualMaximum' => ['int', 'field'=>'int'],
    'IntlGregorianCalendar::getActualMinimum' => ['int', 'field'=>'int'],
    'IntlGregorianCalendar::getAvailableLocales' => ['array'],
    'IntlGregorianCalendar::getDayOfWeekType' => ['int', 'dayOfWeek'=>'int'],
    'IntlGregorianCalendar::getErrorCode' => ['int'],
    'IntlGregorianCalendar::getErrorMessage' => ['string'],
    'IntlGregorianCalendar::getFirstDayOfWeek' => ['int'],
    'IntlGregorianCalendar::getGreatestMinimum' => ['int', 'field'=>'int'],
    'IntlGregorianCalendar::getGregorianChange' => ['float'],
    'IntlGregorianCalendar::getKeywordValuesForLocale' => ['Iterator', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'],
    'IntlGregorianCalendar::getLeastMaximum' => ['int', 'field'=>'int'],
    'IntlGregorianCalendar::getLocale' => ['string', 'localeType'=>'int'],
    'IntlGregorianCalendar::getMaximum' => ['int', 'field'=>'int'],
    'IntlGregorianCalendar::getMinimalDaysInFirstWeek' => ['int'],
    'IntlGregorianCalendar::getMinimum' => ['int', 'field'=>'int'],
    'IntlGregorianCalendar::getNow' => ['float'],
    'IntlGregorianCalendar::getRepeatedWallTimeOption' => ['int'],
    'IntlGregorianCalendar::getSkippedWallTimeOption' => ['int'],
    'IntlGregorianCalendar::getTime' => ['float'],
    'IntlGregorianCalendar::getTimeZone' => ['IntlTimeZone'],
    'IntlGregorianCalendar::getType' => ['string'],
    'IntlGregorianCalendar::getWeekendTransition' => ['int', 'dayOfWeek'=>'string'],
    'IntlGregorianCalendar::inDaylightTime' => ['bool'],
    'IntlGregorianCalendar::isEquivalentTo' => ['bool', 'other'=>'IntlCalendar'],
    'IntlGregorianCalendar::isLeapYear' => ['bool', 'year'=>'int'],
    'IntlGregorianCalendar::isLenient' => ['bool'],
    'IntlGregorianCalendar::isSet' => ['bool', 'field'=>'int'],
    'IntlGregorianCalendar::isWeekend' => ['bool', 'date='=>'float'],
    'IntlGregorianCalendar::roll' => ['bool', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'],
    'IntlGregorianCalendar::set' => ['bool', 'field'=>'int', 'value'=>'int'],
    'IntlGregorianCalendar::set\'1' => ['bool', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'],
    'IntlGregorianCalendar::setFirstDayOfWeek' => ['bool', 'dayOfWeek'=>'int'],
    'IntlGregorianCalendar::setGregorianChange' => ['bool', 'date'=>'float'],
    'IntlGregorianCalendar::setLenient' => ['bool', 'isLenient'=>'string'],
    'IntlGregorianCalendar::setMinimalDaysInFirstWeek' => ['bool', 'minimalDays'=>'int'],
    'IntlGregorianCalendar::setRepeatedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
    'IntlGregorianCalendar::setSkippedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
    'IntlGregorianCalendar::setTime' => ['bool', 'date'=>'float'],
    'IntlGregorianCalendar::setTimeZone' => ['bool', 'timeZone'=>'mixed'],
    'IntlGregorianCalendar::toDateTime' => ['DateTime'],
    'IntlIterator::__construct' => ['void'],
    'IntlIterator::current' => ['mixed'],
    'IntlIterator::key' => ['string'],
    'IntlIterator::next' => ['void'],
    'IntlIterator::rewind' => ['void'],
    'IntlIterator::valid' => ['bool'],
    'IntlPartsIterator::getBreakIterator' => ['IntlBreakIterator'],
    'IntlRuleBasedBreakIterator::__construct' => ['void', 'rules'=>'string', 'areCompiled='=>'string'],
    'IntlRuleBasedBreakIterator::createCharacterInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlRuleBasedBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'],
    'IntlRuleBasedBreakIterator::createLineInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlRuleBasedBreakIterator::createSentenceInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlRuleBasedBreakIterator::createTitleInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlRuleBasedBreakIterator::createWordInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
    'IntlRuleBasedBreakIterator::current' => ['int'],
    'IntlRuleBasedBreakIterator::first' => ['int'],
    'IntlRuleBasedBreakIterator::following' => ['int', 'offset'=>'int'],
    'IntlRuleBasedBreakIterator::getBinaryRules' => ['string'],
    'IntlRuleBasedBreakIterator::getErrorCode' => ['int'],
    'IntlRuleBasedBreakIterator::getErrorMessage' => ['string'],
    'IntlRuleBasedBreakIterator::getLocale' => ['string', 'locale_type'=>'string'],
    'IntlRuleBasedBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'int'],
    'IntlRuleBasedBreakIterator::getRuleStatus' => ['int'],
    'IntlRuleBasedBreakIterator::getRuleStatusVec' => ['array'],
    'IntlRuleBasedBreakIterator::getRules' => ['string'],
    'IntlRuleBasedBreakIterator::getText' => ['?string'],
    'IntlRuleBasedBreakIterator::isBoundary' => ['bool', 'offset'=>'int'],
    'IntlRuleBasedBreakIterator::last' => ['int'],
    'IntlRuleBasedBreakIterator::next' => ['int', 'offset='=>'?int'],
    'IntlRuleBasedBreakIterator::preceding' => ['int', 'offset'=>'int'],
    'IntlRuleBasedBreakIterator::previous' => ['int'],
    'IntlRuleBasedBreakIterator::setText' => ['?bool', 'text'=>'string'],
    'IntlTimeZone::countEquivalentIDs' => ['int|false', 'zoneId'=>'string'],
    'IntlTimeZone::createDefault' => ['IntlTimeZone'],
    'IntlTimeZone::createEnumeration' => ['IntlIterator|false', 'countryOrRawOffset='=>'mixed'],
    'IntlTimeZone::createTimeZone' => ['IntlTimeZone|false', 'zoneId'=>'string'],
    'IntlTimeZone::createTimeZoneIDEnumeration' => ['IntlIterator|false', 'zoneType'=>'int', 'region='=>'string', 'rawOffset='=>'int'],
    'IntlTimeZone::fromDateTimeZone' => ['?IntlTimeZone', 'zoneId'=>'DateTimeZone'],
    'IntlTimeZone::getCanonicalID' => ['string|false', 'zoneId'=>'string', '&w_isSystemID='=>'bool'],
    'IntlTimeZone::getDSTSavings' => ['int'],
    'IntlTimeZone::getDisplayName' => ['string|false', 'isDaylight='=>'bool', 'style='=>'int', 'locale='=>'string'],
    'IntlTimeZone::getEquivalentID' => ['string|false', 'zoneId'=>'string', 'index'=>'int'],
    'IntlTimeZone::getErrorCode' => ['int'],
    'IntlTimeZone::getErrorMessage' => ['string'],
    'IntlTimeZone::getGMT' => ['IntlTimeZone'],
    'IntlTimeZone::getID' => ['string'],
    'IntlTimeZone::getIDForWindowsID' => ['string', 'timezone'=>'string', 'region='=>'string'],
    'IntlTimeZone::getOffset' => ['int', 'date'=>'float', 'local'=>'bool', '&w_rawOffset'=>'int', '&w_dstOffset'=>'int'],
    'IntlTimeZone::getRawOffset' => ['int'],
    'IntlTimeZone::getRegion' => ['string|false', 'zoneId'=>'string'],
    'IntlTimeZone::getTZDataVersion' => ['string'],
    'IntlTimeZone::getUnknown' => ['IntlTimeZone'],
    'IntlTimeZone::getWindowsID' => ['string|false', 'timezone'=>'string'],
    'IntlTimeZone::hasSameRules' => ['bool', 'otherTimeZone'=>'IntlTimeZone'],
    'IntlTimeZone::toDateTimeZone' => ['DateTimeZone|false'],
    'IntlTimeZone::useDaylightTime' => ['bool'],
    'InvalidArgumentException::__clone' => ['void'],
    'InvalidArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'InvalidArgumentException::__toString' => ['string'],
    'InvalidArgumentException::getCode' => ['int'],
    'InvalidArgumentException::getFile' => ['string'],
    'InvalidArgumentException::getLine' => ['int'],
    'InvalidArgumentException::getMessage' => ['string'],
    'InvalidArgumentException::getPrevious' => ['?Throwable'],
    'InvalidArgumentException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'InvalidArgumentException::getTraceAsString' => ['string'],
    'Iterator::current' => ['mixed'],
    'Iterator::key' => ['mixed'],
    'Iterator::next' => ['void'],
    'Iterator::rewind' => ['void'],
    'Iterator::valid' => ['bool'],
    'IteratorAggregate::getIterator' => ['Traversable'],
    'IteratorIterator::__construct' => ['void', 'it'=>'Traversable'],
    'IteratorIterator::current' => ['mixed'],
    'IteratorIterator::getInnerIterator' => ['Iterator'],
    'IteratorIterator::key' => ['mixed'],
    'IteratorIterator::next' => ['void'],
    'IteratorIterator::rewind' => ['void'],
    'IteratorIterator::valid' => ['bool'],
    'JavaException::getCause' => ['object'],
    'JsonIncrementalParser::__construct' => ['void', 'depth'=>'', 'options'=>''],
    'JsonIncrementalParser::get' => ['', 'options'=>''],
    'JsonIncrementalParser::getError' => [''],
    'JsonIncrementalParser::parse' => ['', 'json'=>''],
    'JsonIncrementalParser::parseFile' => ['', 'filename'=>''],
    'JsonIncrementalParser::reset' => [''],
    'JsonSerializable::jsonSerialize' => ['mixed'],
    'Judy::__construct' => ['void', 'judy_type'=>'int'],
    'Judy::__destruct' => ['void'],
    'Judy::byCount' => ['int', 'nth_index'=>'int'],
    'Judy::count' => ['int', 'index_start='=>'int', 'index_end='=>'int'],
    'Judy::first' => ['mixed', 'index='=>'mixed'],
    'Judy::firstEmpty' => ['mixed', 'index='=>'mixed'],
    'Judy::free' => ['int'],
    'Judy::getType' => ['int'],
    'Judy::last' => ['mixed', 'index='=>'string'],
    'Judy::lastEmpty' => ['mixed', 'index='=>'int'],
    'Judy::memoryUsage' => ['int'],
    'Judy::next' => ['mixed', 'index'=>'mixed'],
    'Judy::nextEmpty' => ['mixed', 'index'=>'mixed'],
    'Judy::offsetExists' => ['bool', 'offset'=>'mixed'],
    'Judy::offsetGet' => ['mixed', 'offset'=>'mixed'],
    'Judy::offsetSet' => ['bool', 'offset'=>'mixed', 'value'=>'mixed'],
    'Judy::offsetUnset' => ['bool', 'offset'=>'mixed'],
    'Judy::prev' => ['mixed', 'index'=>'mixed'],
    'Judy::prevEmpty' => ['mixed', 'index'=>'mixed'],
    'Judy::size' => ['int'],
    'KTaglib_ID3v2_AttachedPictureFrame::getDescription' => ['string'],
    'KTaglib_ID3v2_AttachedPictureFrame::getMimeType' => ['string'],
    'KTaglib_ID3v2_AttachedPictureFrame::getType' => ['int'],
    'KTaglib_ID3v2_AttachedPictureFrame::savePicture' => ['bool', 'filename'=>'string'],
    'KTaglib_ID3v2_AttachedPictureFrame::setMimeType' => ['string', 'type'=>'string'],
    'KTaglib_ID3v2_AttachedPictureFrame::setPicture' => ['', 'filename'=>'string'],
    'KTaglib_ID3v2_AttachedPictureFrame::setType' => ['', 'type'=>'int'],
    'KTaglib_ID3v2_Frame::__toString' => ['string'],
    'KTaglib_ID3v2_Frame::getDescription' => ['string'],
    'KTaglib_ID3v2_Frame::getMimeType' => ['string'],
    'KTaglib_ID3v2_Frame::getSize' => ['int'],
    'KTaglib_ID3v2_Frame::getType' => ['int'],
    'KTaglib_ID3v2_Frame::savePicture' => ['bool', 'filename'=>'string'],
    'KTaglib_ID3v2_Frame::setMimeType' => ['string', 'type'=>'string'],
    'KTaglib_ID3v2_Frame::setPicture' => ['void', 'filename'=>'string'],
    'KTaglib_ID3v2_Frame::setType' => ['void', 'type'=>'int'],
    'KTaglib_ID3v2_Tag::addFrame' => ['bool', 'frame'=>'KTaglib_ID3v2_Frame'],
    'KTaglib_ID3v2_Tag::getFrameList' => ['array'],
    'KTaglib_MPEG_AudioProperties::getBitrate' => ['int'],
    'KTaglib_MPEG_AudioProperties::getChannels' => ['int'],
    'KTaglib_MPEG_AudioProperties::getLayer' => ['int'],
    'KTaglib_MPEG_AudioProperties::getLength' => ['int'],
    'KTaglib_MPEG_AudioProperties::getSampleBitrate' => ['int'],
    'KTaglib_MPEG_AudioProperties::getVersion' => ['int'],
    'KTaglib_MPEG_AudioProperties::isCopyrighted' => ['bool'],
    'KTaglib_MPEG_AudioProperties::isOriginal' => ['bool'],
    'KTaglib_MPEG_AudioProperties::isProtectionEnabled' => ['bool'],
    'KTaglib_MPEG_File::getAudioProperties' => ['KTaglib_MPEG_File'],
    'KTaglib_MPEG_File::getID3v1Tag' => ['KTaglib_ID3v1_Tag', 'create='=>'bool'],
    'KTaglib_MPEG_File::getID3v2Tag' => ['KTaglib_ID3v2_Tag', 'create='=>'bool'],
    'KTaglib_Tag::getAlbum' => ['string'],
    'KTaglib_Tag::getArtist' => ['string'],
    'KTaglib_Tag::getComment' => ['string'],
    'KTaglib_Tag::getGenre' => ['string'],
    'KTaglib_Tag::getTitle' => ['string'],
    'KTaglib_Tag::getTrack' => ['int'],
    'KTaglib_Tag::getYear' => ['int'],
    'KTaglib_Tag::isEmpty' => ['bool'],
    'Lapack::eigenValues' => ['array', 'a'=>'array', 'left='=>'array', 'right='=>'array'],
    'Lapack::identity' => ['array', 'n'=>'int'],
    'Lapack::leastSquaresByFactorisation' => ['array', 'a'=>'array', 'b'=>'array'],
    'Lapack::leastSquaresBySVD' => ['array', 'a'=>'array', 'b'=>'array'],
    'Lapack::pseudoInverse' => ['array', 'a'=>'array'],
    'Lapack::singularValues' => ['array', 'a'=>'array'],
    'Lapack::solveLinearEquation' => ['array', 'a'=>'array', 'b'=>'array'],
    'LengthException::__clone' => ['void'],
    'LengthException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'LengthException::__toString' => ['string'],
    'LengthException::getCode' => ['int'],
    'LengthException::getFile' => ['string'],
    'LengthException::getLine' => ['int'],
    'LengthException::getMessage' => ['string'],
    'LengthException::getPrevious' => ['?Throwable'],
    'LengthException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'LengthException::getTraceAsString' => ['string'],
    'LevelDB::__construct' => ['void', 'name'=>'string', 'options='=>'array', 'read_options='=>'array', 'write_options='=>'array'],
    'LevelDB::close' => [''],
    'LevelDB::compactRange' => ['', 'start'=>'', 'limit'=>''],
    'LevelDB::delete' => ['bool', 'key'=>'string', 'write_options='=>'array'],
    'LevelDB::destroy' => ['', 'name'=>'', 'options='=>'array'],
    'LevelDB::get' => ['bool|string', 'key'=>'string', 'read_options='=>'array'],
    'LevelDB::getApproximateSizes' => ['', 'start'=>'', 'limit'=>''],
    'LevelDB::getIterator' => ['LevelDBIterator', 'options='=>'array'],
    'LevelDB::getProperty' => ['mixed', 'name'=>'string'],
    'LevelDB::getSnapshot' => ['LevelDBSnapshot'],
    'LevelDB::put' => ['', 'key'=>'string', 'value'=>'string', 'write_options='=>'array'],
    'LevelDB::repair' => ['', 'name'=>'', 'options='=>'array'],
    'LevelDB::set' => ['', 'key'=>'string', 'value'=>'string', 'write_options='=>'array'],
    'LevelDB::write' => ['', 'batch'=>'LevelDBWriteBatch', 'write_options='=>'array'],
    'LevelDBIterator::__construct' => ['void', 'db'=>'LevelDB', 'read_options='=>'array'],
    'LevelDBIterator::current' => ['mixed'],
    'LevelDBIterator::destroy' => [''],
    'LevelDBIterator::getError' => [''],
    'LevelDBIterator::key' => ['int|string'],
    'LevelDBIterator::last' => [''],
    'LevelDBIterator::next' => ['void'],
    'LevelDBIterator::prev' => [''],
    'LevelDBIterator::rewind' => ['void'],
    'LevelDBIterator::seek' => ['', 'key'=>''],
    'LevelDBIterator::valid' => ['bool'],
    'LevelDBSnapshot::__construct' => ['void', 'db'=>'LevelDB'],
    'LevelDBSnapshot::release' => [''],
    'LevelDBWriteBatch::__construct' => ['void', 'name'=>'', 'options='=>'array', 'read_options='=>'array', 'write_options='=>'array'],
    'LevelDBWriteBatch::clear' => [''],
    'LevelDBWriteBatch::delete' => ['', 'key'=>'', 'write_options='=>'array'],
    'LevelDBWriteBatch::put' => ['', 'key'=>'', 'value'=>'', 'write_options='=>'array'],
    'LevelDBWriteBatch::set' => ['', 'key'=>'', 'value'=>'', 'write_options='=>'array'],
    'LimitIterator::__construct' => ['void', 'iterator'=>'Iterator', 'offset='=>'int', 'count='=>'int'],
    'LimitIterator::current' => ['mixed'],
    'LimitIterator::getInnerIterator' => ['Iterator'],
    'LimitIterator::getPosition' => ['int'],
    'LimitIterator::key' => ['mixed'],
    'LimitIterator::next' => ['void'],
    'LimitIterator::rewind' => ['void'],
    'LimitIterator::seek' => ['int', 'position'=>'int'],
    'LimitIterator::valid' => ['bool'],
    'Locale::acceptFromHttp' => ['string|false', 'header'=>'string'],
    'Locale::canonicalize' => ['string', 'locale'=>'string'],
    'Locale::composeLocale' => ['string', 'subtags'=>'array'],
    'Locale::filterMatches' => ['bool', 'langtag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'],
    'Locale::getAllVariants' => ['array', 'locale'=>'string'],
    'Locale::getDefault' => ['string'],
    'Locale::getDisplayLanguage' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
    'Locale::getDisplayName' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
    'Locale::getDisplayRegion' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
    'Locale::getDisplayScript' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
    'Locale::getDisplayVariant' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
    'Locale::getKeywords' => ['array|false', 'locale'=>'string'],
    'Locale::getPrimaryLanguage' => ['string', 'locale'=>'string'],
    'Locale::getRegion' => ['string', 'locale'=>'string'],
    'Locale::getScript' => ['string', 'locale'=>'string'],
    'Locale::lookup' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'string'],
    'Locale::parseLocale' => ['array', 'locale'=>'string'],
    'Locale::setDefault' => ['bool', 'locale'=>'string'],
    'LogicException::__clone' => ['void'],
    'LogicException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'LogicException::__toString' => ['string'],
    'LogicException::getCode' => ['int'],
    'LogicException::getFile' => ['string'],
    'LogicException::getLine' => ['int'],
    'LogicException::getMessage' => ['string'],
    'LogicException::getPrevious' => ['?Throwable'],
    'LogicException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'LogicException::getTraceAsString' => ['string'],
    'Lua::__call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'],
    'Lua::__construct' => ['void', 'lua_script_file'=>'string'],
    'Lua::assign' => ['?Lua', 'name'=>'string', 'value'=>'mixed'],
    'Lua::call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'],
    'Lua::eval' => ['mixed', 'statements'=>'string'],
    'Lua::getVersion' => ['string'],
    'Lua::include' => ['mixed', 'file'=>'string'],
    'Lua::registerCallback' => ['Lua|null|false', 'name'=>'string', 'function'=>'callable'],
    'LuaClosure::__invoke' => ['void', 'arg'=>'mixed', '...args='=>'mixed'],
    'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'],
    'Memcache::append' => [''],
    'Memcache::cas' => [''],
    'Memcache::close' => ['bool'],
    'Memcache::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
    'Memcache::decrement' => ['int', 'key'=>'string', 'value='=>'int'],
    'Memcache::delete' => ['bool', 'key'=>'string', 'timeout='=>'int'],
    'Memcache::findServer' => [''],
    'Memcache::flush' => ['bool'],
    'Memcache::get' => ['string|array|false', 'key'=>'string', 'flags='=>'array', 'keys='=>'array'],
    'Memcache::get\'1' => ['array', 'key'=>'string[]', 'flags='=>'int[]'],
    'Memcache::getExtendedStats' => ['false|array<string, false|array<string, int|string>>', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
    'Memcache::getServerStatus' => ['int', 'host'=>'string', 'port='=>'int'],
    'Memcache::getStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
    'Memcache::getVersion' => ['string'],
    'Memcache::increment' => ['int', 'key'=>'string', 'value='=>'int'],
    'Memcache::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
    'Memcache::prepend' => ['string'],
    'Memcache::replace' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'Memcache::set' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'Memcache::setCompressThreshold' => ['bool', 'threshold'=>'int', 'min_savings='=>'float'],
    'Memcache::setFailureCallback' => [''],
    'Memcache::setServerParams' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable'],
    'MemcachePool::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'MemcachePool::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'?callable', 'timeoutms='=>'int'],
    'MemcachePool::append' => [''],
    'MemcachePool::cas' => [''],
    'MemcachePool::close' => ['bool'],
    'MemcachePool::connect' => ['bool', 'host'=>'string', 'port'=>'int', 'timeout='=>'int'],
    'MemcachePool::decrement' => ['int|false', 'key'=>'', 'value='=>'int|mixed'],
    'MemcachePool::delete' => ['bool', 'key'=>'', 'timeout='=>'int|mixed'],
    'MemcachePool::findServer' => [''],
    'MemcachePool::flush' => ['bool'],
    'MemcachePool::get' => ['array|string|false', 'key'=>'array|string', '&flags='=>'array|int'],
    'MemcachePool::getExtendedStats' => ['false|array<string, false|array<string, int|string>>', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
    'MemcachePool::getServerStatus' => ['int', 'host'=>'string', 'port='=>'int'],
    'MemcachePool::getStats' => ['array|false', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
    'MemcachePool::getVersion' => ['string|false'],
    'MemcachePool::increment' => ['int|false', 'key'=>'', 'value='=>'int|mixed'],
    'MemcachePool::prepend' => ['string'],
    'MemcachePool::replace' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'MemcachePool::set' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'MemcachePool::setCompressThreshold' => ['bool', 'thresold'=>'int', 'min_saving='=>'float'],
    'MemcachePool::setFailureCallback' => [''],
    'MemcachePool::setServerParams' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'?callable'],
    'Memcached::__construct' => ['void', 'persistent_id='=>'mixed|string', 'on_new_object_cb='=>'mixed'],
    'Memcached::add' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::addByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::addServer' => ['bool', 'host'=>'string', 'port'=>'int', 'weight='=>'int'],
    'Memcached::addServers' => ['bool', 'servers'=>'array'],
    'Memcached::append' => ['bool', 'key'=>'string', 'value'=>'string'],
    'Memcached::appendByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'],
    'Memcached::cas' => ['bool', 'cas_token'=>'float', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::casByKey' => ['bool', 'cas_token'=>'float', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::decrement' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
    'Memcached::decrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
    'Memcached::delete' => ['bool', 'key'=>'string', 'time='=>'int'],
    'Memcached::deleteByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'time='=>'int'],
    'Memcached::deleteMulti' => ['array', 'keys'=>'array', 'time='=>'int'],
    'Memcached::deleteMultiByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'time='=>'int'],
    'Memcached::fetch' => ['array|false'],
    'Memcached::fetchAll' => ['array|false'],
    'Memcached::flush' => ['bool', 'delay='=>'int'],
    'Memcached::flushBuffers' => [''],
    'Memcached::get' => ['mixed|false', 'key'=>'string', 'cache_cb='=>'?callable', 'flags='=>'int'],
    'Memcached::getAllKeys' => ['array|false'],
    'Memcached::getByKey' => ['mixed|false', 'server_key'=>'string', 'key'=>'string', 'value_cb='=>'?callable', 'flags='=>'int'],
    'Memcached::getDelayed' => ['bool', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'callable'],
    'Memcached::getDelayedByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'?callable'],
    'Memcached::getLastDisconnectedServer' => [''],
    'Memcached::getLastErrorCode' => [''],
    'Memcached::getLastErrorErrno' => [''],
    'Memcached::getLastErrorMessage' => [''],
    'Memcached::getMulti' => ['array|false', 'keys'=>'array', 'flags='=>'int'],
    'Memcached::getMultiByKey' => ['array|false', 'server_key'=>'string', 'keys'=>'array', 'flags='=>'int'],
    'Memcached::getOption' => ['mixed|false', 'option'=>'int'],
    'Memcached::getResultCode' => ['int'],
    'Memcached::getResultMessage' => ['string'],
    'Memcached::getServerByKey' => ['array', 'server_key'=>'string'],
    'Memcached::getServerList' => ['array'],
    'Memcached::getStats' => ['false|array<string, false|array<string, int|string>>', 'type='=>'?string'],
    'Memcached::getVersion' => ['array'],
    'Memcached::increment' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
    'Memcached::incrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
    'Memcached::isPersistent' => ['bool'],
    'Memcached::isPristine' => ['bool'],
    'Memcached::prepend' => ['bool', 'key'=>'string', 'value'=>'string'],
    'Memcached::prependByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'],
    'Memcached::quit' => ['bool'],
    'Memcached::replace' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::replaceByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::resetServerList' => ['bool'],
    'Memcached::set' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::setBucket' => ['', 'host_map'=>'array', 'forward_map'=>'array', 'replicas'=>''],
    'Memcached::setByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
    'Memcached::setEncodingKey' => ['', 'key'=>''],
    'Memcached::setMulti' => ['bool', 'items'=>'array', 'expiration='=>'int'],
    'Memcached::setMultiByKey' => ['bool', 'server_key'=>'string', 'items'=>'array', 'expiration='=>'int'],
    'Memcached::setOption' => ['bool', 'option'=>'int', 'value'=>'mixed'],
    'Memcached::setOptions' => ['bool', 'options'=>'array'],
    'Memcached::setSaslAuthData' => ['void', 'username'=>'string', 'password'=>'string'],
    'Memcached::touch' => ['bool', 'key'=>'string', 'expiration'=>'int'],
    'Memcached::touchByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'expiration'=>'int'],
    'MessageFormatter::__construct' => ['void', 'locale'=>'string', 'pattern'=>'string'],
    'MessageFormatter::create' => ['MessageFormatter', 'locale'=>'string', 'pattern'=>'string'],
    'MessageFormatter::format' => ['false|string', 'args'=>'array'],
    'MessageFormatter::formatMessage' => ['false|string', 'locale'=>'string', 'pattern'=>'string', 'args'=>'array'],
    'MessageFormatter::getErrorCode' => ['int'],
    'MessageFormatter::getErrorMessage' => ['string'],
    'MessageFormatter::getLocale' => ['string'],
    'MessageFormatter::getPattern' => ['string'],
    'MessageFormatter::parse' => ['array|false', 'value'=>'string'],
    'MessageFormatter::parseMessage' => ['array|false', 'locale'=>'string', 'pattern'=>'string', 'source'=>'string'],
    'MessageFormatter::setPattern' => ['bool', 'pattern'=>'string'],
    'Mongo::__construct' => ['void', 'server='=>'string', 'options='=>'array', 'driver_options='=>'array'],
    'Mongo::__get' => ['MongoDB', 'dbname'=>'string'],
    'Mongo::__toString' => ['string'],
    'Mongo::close' => ['bool'],
    'Mongo::connect' => ['bool'],
    'Mongo::connectUtil' => ['bool'],
    'Mongo::dropDB' => ['array', 'db'=>'mixed'],
    'Mongo::forceError' => ['bool'],
    'Mongo::getConnections' => ['array'],
    'Mongo::getHosts' => ['array'],
    'Mongo::getPoolSize' => ['int'],
    'Mongo::getReadPreference' => ['array'],
    'Mongo::getSlave' => ['?string'],
    'Mongo::getSlaveOkay' => ['bool'],
    'Mongo::getWriteConcern' => ['array'],
    'Mongo::killCursor' => ['', 'server_hash'=>'string', 'id'=>'MongoInt64|int'],
    'Mongo::lastError' => ['?array'],
    'Mongo::listDBs' => ['array'],
    'Mongo::pairConnect' => ['bool'],
    'Mongo::pairPersistConnect' => ['bool', 'username='=>'string', 'password='=>'string'],
    'Mongo::persistConnect' => ['bool', 'username='=>'string', 'password='=>'string'],
    'Mongo::poolDebug' => ['array'],
    'Mongo::prevError' => ['array'],
    'Mongo::resetError' => ['array'],
    'Mongo::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'],
    'Mongo::selectDB' => ['MongoDB', 'name'=>'string'],
    'Mongo::setPoolSize' => ['bool', 'size'=>'int'],
    'Mongo::setReadPreference' => ['bool', 'readPreference'=>'string', 'tags='=>'array'],
    'Mongo::setSlaveOkay' => ['bool', 'ok='=>'bool'],
    'Mongo::switchSlave' => ['string'],
    'MongoBinData::__construct' => ['void', 'data'=>'string', 'type='=>'int'],
    'MongoBinData::__toString' => ['string'],
    'MongoClient::__construct' => ['void', 'server='=>'string', 'options='=>'array', 'driver_options='=>'array'],
    'MongoClient::__get' => ['MongoDB', 'dbname'=>'string'],
    'MongoClient::__toString' => ['string'],
    'MongoClient::close' => ['bool', 'connection='=>'bool|string'],
    'MongoClient::connect' => ['bool'],
    'MongoClient::dropDB' => ['array', 'db'=>'mixed'],
    'MongoClient::getConnections' => ['array'],
    'MongoClient::getHosts' => ['array'],
    'MongoClient::getReadPreference' => ['array'],
    'MongoClient::getWriteConcern' => ['array'],
    'MongoClient::killCursor' => ['bool', 'server_hash'=>'string', 'id'=>'int|MongoInt64'],
    'MongoClient::listDBs' => ['array'],
    'MongoClient::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'],
    'MongoClient::selectDB' => ['MongoDB', 'name'=>'string'],
    'MongoClient::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'],
    'MongoClient::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'],
    'MongoClient::switchSlave' => ['string'],
    'MongoCode::__construct' => ['void', 'code'=>'string', 'scope='=>'array'],
    'MongoCode::__toString' => ['string'],
    'MongoCollection::__construct' => ['void', 'db'=>'MongoDB', 'name'=>'string'],
    'MongoCollection::__get' => ['MongoCollection', 'name'=>'string'],
    'MongoCollection::__toString' => ['string'],
    'MongoCollection::aggregate' => ['array', 'op'=>'array', 'op='=>'array', '...args='=>'array'],
    'MongoCollection::aggregate\'1' => ['array', 'pipeline'=>'array', 'options='=>'array'],
    'MongoCollection::aggregateCursor' => ['MongoCommandCursor', 'command'=>'array', 'options='=>'array'],
    'MongoCollection::batchInsert' => ['array|bool', 'a'=>'array', 'options='=>'array'],
    'MongoCollection::count' => ['int', 'query='=>'array', 'limit='=>'int', 'skip='=>'int'],
    'MongoCollection::createDBRef' => ['array', 'a'=>'array'],
    'MongoCollection::createIndex' => ['array', 'keys'=>'array', 'options='=>'array'],
    'MongoCollection::deleteIndex' => ['array', 'keys'=>'string|array'],
    'MongoCollection::deleteIndexes' => ['array'],
    'MongoCollection::distinct' => ['array|false', 'key'=>'string', 'query='=>'array'],
    'MongoCollection::drop' => ['array'],
    'MongoCollection::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'],
    'MongoCollection::find' => ['MongoCursor', 'query='=>'array', 'fields='=>'array'],
    'MongoCollection::findAndModify' => ['array', 'query'=>'array', 'update='=>'array', 'fields='=>'array', 'options='=>'array'],
    'MongoCollection::findOne' => ['?array', 'query='=>'array', 'fields='=>'array'],
    'MongoCollection::getDBRef' => ['array', 'ref'=>'array'],
    'MongoCollection::getIndexInfo' => ['array'],
    'MongoCollection::getName' => ['string'],
    'MongoCollection::getReadPreference' => ['array'],
    'MongoCollection::getSlaveOkay' => ['bool'],
    'MongoCollection::getWriteConcern' => ['array'],
    'MongoCollection::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'MongoCode', 'options='=>'array'],
    'MongoCollection::insert' => ['bool|array', 'a'=>'array|object', 'options='=>'array'],
    'MongoCollection::parallelCollectionScan' => ['MongoCommandCursor[]', 'num_cursors'=>'int'],
    'MongoCollection::remove' => ['bool|array', 'criteria='=>'array', 'options='=>'array'],
    'MongoCollection::save' => ['bool|array', 'a'=>'array|object', 'options='=>'array'],
    'MongoCollection::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'],
    'MongoCollection::setSlaveOkay' => ['bool', 'ok='=>'bool'],
    'MongoCollection::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'],
    'MongoCollection::toIndexString' => ['string', 'keys'=>'mixed'],
    'MongoCollection::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'],
    'MongoCollection::validate' => ['array', 'scan_data='=>'bool'],
    'MongoCommandCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'command'=>'array'],
    'MongoCommandCursor::batchSize' => ['MongoCommandCursor', 'batchSize'=>'int'],
    'MongoCommandCursor::createFromDocument' => ['MongoCommandCursor', 'connection'=>'MongoClient', 'hash'=>'string', 'document'=>'array'],
    'MongoCommandCursor::current' => ['array'],
    'MongoCommandCursor::dead' => ['bool'],
    'MongoCommandCursor::getReadPreference' => ['array'],
    'MongoCommandCursor::info' => ['array'],
    'MongoCommandCursor::key' => ['int'],
    'MongoCommandCursor::next' => ['void'],
    'MongoCommandCursor::rewind' => ['array'],
    'MongoCommandCursor::setReadPreference' => ['MongoCommandCursor', 'read_preference'=>'string', 'tags='=>'array'],
    'MongoCommandCursor::timeout' => ['MongoCommandCursor', 'ms'=>'int'],
    'MongoCommandCursor::valid' => ['bool'],
    'MongoCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'query='=>'array', 'fields='=>'array'],
    'MongoCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'],
    'MongoCursor::awaitData' => ['MongoCursor', 'wait='=>'bool'],
    'MongoCursor::batchSize' => ['MongoCursor', 'num'=>'int'],
    'MongoCursor::count' => ['int', 'foundonly='=>'bool'],
    'MongoCursor::current' => ['array'],
    'MongoCursor::dead' => ['bool'],
    'MongoCursor::doQuery' => ['void'],
    'MongoCursor::explain' => ['array'],
    'MongoCursor::fields' => ['MongoCursor', 'f'=>'array'],
    'MongoCursor::getNext' => ['array'],
    'MongoCursor::getReadPreference' => ['array'],
    'MongoCursor::hasNext' => ['bool'],
    'MongoCursor::hint' => ['MongoCursor', 'key_pattern'=>'string|array|object'],
    'MongoCursor::immortal' => ['MongoCursor', 'liveforever='=>'bool'],
    'MongoCursor::info' => ['array'],
    'MongoCursor::key' => ['string'],
    'MongoCursor::limit' => ['MongoCursor', 'num'=>'int'],
    'MongoCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'],
    'MongoCursor::next' => ['array'],
    'MongoCursor::partial' => ['MongoCursor', 'okay='=>'bool'],
    'MongoCursor::reset' => ['void'],
    'MongoCursor::rewind' => ['void'],
    'MongoCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool'],
    'MongoCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags='=>'array'],
    'MongoCursor::skip' => ['MongoCursor', 'num'=>'int'],
    'MongoCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool'],
    'MongoCursor::snapshot' => ['MongoCursor'],
    'MongoCursor::sort' => ['MongoCursor', 'fields'=>'array'],
    'MongoCursor::tailable' => ['MongoCursor', 'tail='=>'bool'],
    'MongoCursor::timeout' => ['MongoCursor', 'ms'=>'int'],
    'MongoCursor::valid' => ['bool'],
    'MongoCursorException::__clone' => ['void'],
    'MongoCursorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'MongoCursorException::__toString' => ['string'],
    'MongoCursorException::__wakeup' => ['void'],
    'MongoCursorException::getCode' => ['int'],
    'MongoCursorException::getFile' => ['string'],
    'MongoCursorException::getHost' => ['string'],
    'MongoCursorException::getLine' => ['int'],
    'MongoCursorException::getMessage' => ['string'],
    'MongoCursorException::getPrevious' => ['Exception|Throwable'],
    'MongoCursorException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'MongoCursorException::getTraceAsString' => ['string'],
    'MongoCursorInterface::__construct' => ['void'],
    'MongoCursorInterface::batchSize' => ['MongoCursorInterface', 'batchSize'=>'int'],
    'MongoCursorInterface::current' => ['mixed'],
    'MongoCursorInterface::dead' => ['bool'],
    'MongoCursorInterface::getReadPreference' => ['array'],
    'MongoCursorInterface::info' => ['array'],
    'MongoCursorInterface::key' => ['int|string'],
    'MongoCursorInterface::next' => ['void'],
    'MongoCursorInterface::rewind' => ['void'],
    'MongoCursorInterface::setReadPreference' => ['MongoCursorInterface', 'read_preference'=>'string', 'tags='=>'array'],
    'MongoCursorInterface::timeout' => ['MongoCursorInterface', 'ms'=>'int'],
    'MongoCursorInterface::valid' => ['bool'],
    'MongoDB::__construct' => ['void', 'conn'=>'MongoClient', 'name'=>'string'],
    'MongoDB::__get' => ['MongoCollection', 'name'=>'string'],
    'MongoDB::__toString' => ['string'],
    'MongoDB::authenticate' => ['array', 'username'=>'string', 'password'=>'string'],
    'MongoDB::command' => ['array', 'command'=>'array'],
    'MongoDB::createCollection' => ['MongoCollection', 'name'=>'string', 'capped='=>'bool', 'size='=>'int', 'max='=>'int'],
    'MongoDB::createDBRef' => ['array', 'collection'=>'string', 'a'=>'mixed'],
    'MongoDB::drop' => ['array'],
    'MongoDB::dropCollection' => ['array', 'coll'=>'MongoCollection|string'],
    'MongoDB::execute' => ['array', 'code'=>'MongoCode|string', 'args='=>'array'],
    'MongoDB::forceError' => ['bool'],
    'MongoDB::getCollectionInfo' => ['array', 'options='=>'array'],
    'MongoDB::getCollectionNames' => ['array', 'options='=>'array'],
    'MongoDB::getDBRef' => ['array', 'ref'=>'array'],
    'MongoDB::getGridFS' => ['MongoGridFS', 'prefix='=>'string'],
    'MongoDB::getProfilingLevel' => ['int'],
    'MongoDB::getReadPreference' => ['array'],
    'MongoDB::getSlaveOkay' => ['bool'],
    'MongoDB::getWriteConcern' => ['array'],
    'MongoDB::lastError' => ['array'],
    'MongoDB::listCollections' => ['array'],
    'MongoDB::prevError' => ['array'],
    'MongoDB::repair' => ['array', 'preserve_cloned_files='=>'bool', 'backup_original_files='=>'bool'],
    'MongoDB::resetError' => ['array'],
    'MongoDB::selectCollection' => ['MongoCollection', 'name'=>'string'],
    'MongoDB::setProfilingLevel' => ['int', 'level'=>'int'],
    'MongoDB::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'],
    'MongoDB::setSlaveOkay' => ['bool', 'ok='=>'bool'],
    'MongoDB::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'],
    'MongoDBRef::create' => ['array', 'collection'=>'string', 'id'=>'mixed', 'database='=>'string'],
    'MongoDBRef::get' => ['?array', 'db'=>'MongoDB', 'ref'=>'array'],
    'MongoDBRef::isRef' => ['bool', 'ref'=>'mixed'],
    'MongoDB\BSON\Binary::__construct' => ['void', 'data' => 'string', 'type' => 'int'],
    'MongoDB\BSON\Binary::getData' => ['string'],
    'MongoDB\BSON\Binary::getType' => ['int'],
    'MongoDB\BSON\Binary::__toString' => ['string'],
    'MongoDB\BSON\Binary::serialize' => ['string'],
    'MongoDB\BSON\Binary::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Binary::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\BinaryInterface::getData' => ['string'],
    'MongoDB\BSON\BinaryInterface::getType' => ['int'],
    'MongoDB\BSON\BinaryInterface::__toString' => ['string'],
    'MongoDB\BSON\DBPointer::__toString' => ['string'],
    'MongoDB\BSON\DBPointer::serialize' => ['string'],
    'MongoDB\BSON\DBPointer::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\DBPointer::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\Decimal128::__construct' => ['void', 'value' => 'string'],
    'MongoDB\BSON\Decimal128::__toString' => ['string'],
    'MongoDB\BSON\Decimal128::serialize' => ['string'],
    'MongoDB\BSON\Decimal128::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Decimal128::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\Decimal128Interface::__toString' => ['string'],
    'MongoDB\BSON\Int64::__toString' => ['string'],
    'MongoDB\BSON\Int64::serialize' => ['string'],
    'MongoDB\BSON\Int64::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Int64::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\Javascript::__construct' => ['void', 'code' => 'string', 'scope=' => 'object|array|null'],
    'MongoDB\BSON\Javascript::getCode' => ['string'],
    'MongoDB\BSON\Javascript::getScope' => ['?object'],
    'MongoDB\BSON\Javascript::__toString' => ['string'],
    'MongoDB\BSON\Javascript::serialize' => ['string'],
    'MongoDB\BSON\Javascript::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Javascript::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\JavascriptInterface::getCode' => ['string'],
    'MongoDB\BSON\JavascriptInterface::getScope' => ['?object'],
    'MongoDB\BSON\JavascriptInterface::__toString' => ['string'],
    'MongoDB\BSON\MaxKey::serialize' => ['string'],
    'MongoDB\BSON\MaxKey::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\MaxKey::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\MinKey::serialize' => ['string'],
    'MongoDB\BSON\MinKey::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\MinKey::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\ObjectId::__construct' => ['void', 'id=' => '?string'],
    'MongoDB\BSON\ObjectId::getTimestamp' => ['int'],
    'MongoDB\BSON\ObjectId::__toString' => ['string'],
    'MongoDB\BSON\ObjectId::serialize' => ['string'],
    'MongoDB\BSON\ObjectId::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\ObjectId::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\ObjectIdInterface::getTimestamp' => ['int'],
    'MongoDB\BSON\ObjectIdInterface::__toString' => ['string'],
    'MongoDB\BSON\Regex::__construct' => ['void', 'pattern' => 'string', 'flags=' => 'string'],
    'MongoDB\BSON\Regex::getPattern' => ['string'],
    'MongoDB\BSON\Regex::getFlags' => ['string'],
    'MongoDB\BSON\Regex::__toString' => ['string'],
    'MongoDB\BSON\Regex::serialize' => ['string'],
    'MongoDB\BSON\Regex::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Regex::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\RegexInterface::getPattern' => ['string'],
    'MongoDB\BSON\RegexInterface::getFlags' => ['string'],
    'MongoDB\BSON\RegexInterface::__toString' => ['string'],
    'MongoDB\BSON\Serializable::bsonSerialize' => ['object|array'],
    'MongoDB\BSON\Symbol::__toString' => ['string'],
    'MongoDB\BSON\Symbol::serialize' => ['string'],
    'MongoDB\BSON\Symbol::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Symbol::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\Timestamp::__construct' => ['void', 'increment' => 'string|int', 'timestamp' => 'string|int'],
    'MongoDB\BSON\Timestamp::getTimestamp' => ['int'],
    'MongoDB\BSON\Timestamp::getIncrement' => ['int'],
    'MongoDB\BSON\Timestamp::__toString' => ['string'],
    'MongoDB\BSON\Timestamp::serialize' => ['string'],
    'MongoDB\BSON\Timestamp::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Timestamp::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\TimestampInterface::getTimestamp' => ['int'],
    'MongoDB\BSON\TimestampInterface::getIncrement' => ['int'],
    'MongoDB\BSON\TimestampInterface::__toString' => ['string'],
    'MongoDB\BSON\UTCDateTime::__construct' => ['void', 'milliseconds=' => 'DateTimeInterface|string|int|float|null'],
    'MongoDB\BSON\UTCDateTime::toDateTime' => ['DateTime'],
    'MongoDB\BSON\UTCDateTime::__toString' => ['string'],
    'MongoDB\BSON\UTCDateTime::serialize' => ['string'],
    'MongoDB\BSON\UTCDateTime::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\UTCDateTime::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\UTCDateTimeInterface::toDateTime' => ['DateTime'],
    'MongoDB\BSON\UTCDateTimeInterface::__toString' => ['string'],
    'MongoDB\BSON\Undefined::__toString' => ['string'],
    'MongoDB\BSON\Undefined::serialize' => ['string'],
    'MongoDB\BSON\Undefined::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\BSON\Undefined::jsonSerialize' => ['mixed'],
    'MongoDB\BSON\Unserializable::bsonUnserialize' => ['void', 'data' => 'array'],
    'MongoDB\Driver\BulkWrite::__construct' => ['void', 'options=' => '?array'],
    'MongoDB\Driver\BulkWrite::count' => ['int'],
    'MongoDB\Driver\BulkWrite::delete' => ['void', 'filter' => 'object|array', 'deleteOptions=' => '?array'],
    'MongoDB\Driver\BulkWrite::insert' => ['mixed', 'document' => 'object|array'],
    'MongoDB\Driver\BulkWrite::update' => ['void', 'filter' => 'object|array', 'newObj' => 'object|array', 'updateOptions=' => '?array'],
    'MongoDB\Driver\ClientEncryption::__construct' => ['void', 'options' => 'array'],
    'MongoDB\Driver\ClientEncryption::addKeyAltName' => ['?object', 'keyId' => 'MongoDB\BSON\Binary', 'keyAltName' => 'string'],
    'MongoDB\Driver\ClientEncryption::createDataKey' => ['MongoDB\BSON\Binary', 'kmsProvider' => 'string', 'options=' => '?array'],
    'MongoDB\Driver\ClientEncryption::decrypt' => ['mixed', 'value' => 'MongoDB\BSON\Binary'],
    'MongoDB\Driver\ClientEncryption::deleteKey' => ['object', 'keyId' => 'MongoDB\BSON\Binary'],
    'MongoDB\Driver\ClientEncryption::encrypt' => ['MongoDB\BSON\Binary', 'value' => 'mixed', 'options=' => '?array'],
    'MongoDB\Driver\ClientEncryption::getKey' => ['?object', 'keyId' => 'MongoDB\BSON\Binary'],
    'MongoDB\Driver\ClientEncryption::getKeyByAltName' => ['?object', 'keyAltName' => 'string'],
    'MongoDB\Driver\ClientEncryption::getKeys' => ['MongoDB\Driver\Cursor'],
    'MongoDB\Driver\ClientEncryption::removeKeyAltName' => ['?object', 'keyId' => 'MongoDB\BSON\Binary', 'keyAltName' => 'string'],
    'MongoDB\Driver\ClientEncryption::rewrapManyDataKey' => ['object', 'filter' => 'object|array', 'options=' => '?array'],
    'MongoDB\Driver\Command::__construct' => ['void', 'document' => 'object|array', 'commandOptions=' => '?array'],
    'MongoDB\Driver\Cursor::current' => ['object|array|null'],
    'MongoDB\Driver\Cursor::getId' => ['MongoDB\Driver\CursorId'],
    'MongoDB\Driver\Cursor::getServer' => ['MongoDB\Driver\Server'],
    'MongoDB\Driver\Cursor::isDead' => ['bool'],
    'MongoDB\Driver\Cursor::key' => ['?int'],
    'MongoDB\Driver\Cursor::next' => ['void'],
    'MongoDB\Driver\Cursor::rewind' => ['void'],
    'MongoDB\Driver\Cursor::setTypeMap' => ['void', 'typemap' => 'array'],
    'MongoDB\Driver\Cursor::toArray' => ['array'],
    'MongoDB\Driver\Cursor::valid' => ['bool'],
    'MongoDB\Driver\CursorId::__toString' => ['string'],
    'MongoDB\Driver\CursorId::serialize' => ['string'],
    'MongoDB\Driver\CursorId::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\Driver\CursorInterface::getId' => ['MongoDB\Driver\CursorId'],
    'MongoDB\Driver\CursorInterface::getServer' => ['MongoDB\Driver\Server'],
    'MongoDB\Driver\CursorInterface::isDead' => ['bool'],
    'MongoDB\Driver\CursorInterface::setTypeMap' => ['void', 'typemap' => 'array'],
    'MongoDB\Driver\CursorInterface::toArray' => ['array'],
    'MongoDB\Driver\Exception\AuthenticationException::__toString' => ['string'],
    'MongoDB\Driver\Exception\BulkWriteException::__toString' => ['string'],
    'MongoDB\Driver\Exception\CommandException::getResultDocument' => ['object'],
    'MongoDB\Driver\Exception\CommandException::__toString' => ['string'],
    'MongoDB\Driver\Exception\ConnectionException::__toString' => ['string'],
    'MongoDB\Driver\Exception\ConnectionTimeoutException::__toString' => ['string'],
    'MongoDB\Driver\Exception\EncryptionException::__toString' => ['string'],
    'MongoDB\Driver\Exception\Exception::__toString' => ['string'],
    'MongoDB\Driver\Exception\ExecutionTimeoutException::__toString' => ['string'],
    'MongoDB\Driver\Exception\InvalidArgumentException::__toString' => ['string'],
    'MongoDB\Driver\Exception\LogicException::__toString' => ['string'],
    'MongoDB\Driver\Exception\RuntimeException::hasErrorLabel' => ['bool', 'errorLabel' => 'string'],
    'MongoDB\Driver\Exception\RuntimeException::__toString' => ['string'],
    'MongoDB\Driver\Exception\SSLConnectionException::__toString' => ['string'],
    'MongoDB\Driver\Exception\ServerException::__toString' => ['string'],
    'MongoDB\Driver\Exception\UnexpectedValueException::__toString' => ['string'],
    'MongoDB\Driver\Exception\WriteException::getWriteResult' => ['MongoDB\Driver\WriteResult'],
    'MongoDB\Driver\Exception\WriteException::__toString' => ['string'],
    'MongoDB\Driver\Manager::__construct' => ['void', 'uri=' => '?string', 'uriOptions=' => '?array', 'driverOptions=' => '?array'],
    'MongoDB\Driver\Manager::addSubscriber' => ['void', 'subscriber' => 'MongoDB\Driver\Monitoring\Subscriber'],
    'MongoDB\Driver\Manager::createClientEncryption' => ['MongoDB\Driver\ClientEncryption', 'options' => 'array'],
    'MongoDB\Driver\Manager::executeBulkWrite' => ['MongoDB\Driver\WriteResult', 'namespace' => 'string', 'bulk' => 'MongoDB\Driver\BulkWrite', 'options=' => 'MongoDB\Driver\WriteConcern|array|null'],
    'MongoDB\Driver\Manager::executeCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
    'MongoDB\Driver\Manager::executeQuery' => ['MongoDB\Driver\Cursor', 'namespace' => 'string', 'query' => 'MongoDB\Driver\Query', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
    'MongoDB\Driver\Manager::executeReadCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
    'MongoDB\Driver\Manager::executeReadWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
    'MongoDB\Driver\Manager::executeWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
    'MongoDB\Driver\Manager::getEncryptedFieldsMap' => ['object|array|null'],
    'MongoDB\Driver\Manager::getReadConcern' => ['MongoDB\Driver\ReadConcern'],
    'MongoDB\Driver\Manager::getReadPreference' => ['MongoDB\Driver\ReadPreference'],
    'MongoDB\Driver\Manager::getServers' => ['array'],
    'MongoDB\Driver\Manager::getWriteConcern' => ['MongoDB\Driver\WriteConcern'],
    'MongoDB\Driver\Manager::removeSubscriber' => ['void', 'subscriber' => 'MongoDB\Driver\Monitoring\Subscriber'],
    'MongoDB\Driver\Manager::selectServer' => ['MongoDB\Driver\Server', 'readPreference=' => '?MongoDB\Driver\ReadPreference'],
    'MongoDB\Driver\Manager::startSession' => ['MongoDB\Driver\Session', 'options=' => '?array'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getCommandName' => ['string'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getDurationMicros' => ['int'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getError' => ['Exception'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getOperationId' => ['string'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getReply' => ['object'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getRequestId' => ['string'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getServer' => ['MongoDB\Driver\Server'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\CommandFailedEvent::getServerConnectionId' => ['?int'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getCommand' => ['object'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getCommandName' => ['string'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getDatabaseName' => ['string'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getOperationId' => ['string'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getRequestId' => ['string'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getServer' => ['MongoDB\Driver\Server'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\CommandStartedEvent::getServerConnectionId' => ['?int'],
    'MongoDB\Driver\Monitoring\CommandSubscriber::commandStarted' => ['void', 'event' => 'MongoDB\Driver\Monitoring\CommandStartedEvent'],
    'MongoDB\Driver\Monitoring\CommandSubscriber::commandSucceeded' => ['void', 'event' => 'MongoDB\Driver\Monitoring\CommandSucceededEvent'],
    'MongoDB\Driver\Monitoring\CommandSubscriber::commandFailed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\CommandFailedEvent'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getCommandName' => ['string'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getDurationMicros' => ['int'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getOperationId' => ['string'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getReply' => ['object'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getRequestId' => ['string'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServer' => ['MongoDB\Driver\Server'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServerConnectionId' => ['?int'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::serverChanged' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerChangedEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::serverClosed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerClosedEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::serverOpening' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerOpeningEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatFailed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatStarted' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatSucceeded' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyChanged' => ['void', 'event' => 'MongoDB\Driver\Monitoring\TopologyChangedEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyClosed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\TopologyClosedEvent'],
    'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyOpening' => ['void', 'event' => 'MongoDB\Driver\Monitoring\TopologyOpeningEvent'],
    'MongoDB\Driver\Monitoring\ServerChangedEvent::getPort' => ['int'],
    'MongoDB\Driver\Monitoring\ServerChangedEvent::getHost' => ['string'],
    'MongoDB\Driver\Monitoring\ServerChangedEvent::getNewDescription' => ['MongoDB\Driver\ServerDescription'],
    'MongoDB\Driver\Monitoring\ServerChangedEvent::getPreviousDescription' => ['MongoDB\Driver\ServerDescription'],
    'MongoDB\Driver\Monitoring\ServerChangedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\ServerClosedEvent::getPort' => ['int'],
    'MongoDB\Driver\Monitoring\ServerClosedEvent::getHost' => ['string'],
    'MongoDB\Driver\Monitoring\ServerClosedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getDurationMicros' => ['int'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getError' => ['Exception'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getPort' => ['int'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getHost' => ['string'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::isAwaited' => ['bool'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::getPort' => ['int'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::getHost' => ['string'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::isAwaited' => ['bool'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getDurationMicros' => ['int'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getReply' => ['object'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getPort' => ['int'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getHost' => ['string'],
    'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::isAwaited' => ['bool'],
    'MongoDB\Driver\Monitoring\ServerOpeningEvent::getPort' => ['int'],
    'MongoDB\Driver\Monitoring\ServerOpeningEvent::getHost' => ['string'],
    'MongoDB\Driver\Monitoring\ServerOpeningEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\TopologyChangedEvent::getNewDescription' => ['MongoDB\Driver\TopologyDescription'],
    'MongoDB\Driver\Monitoring\TopologyChangedEvent::getPreviousDescription' => ['MongoDB\Driver\TopologyDescription'],
    'MongoDB\Driver\Monitoring\TopologyChangedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\TopologyClosedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Monitoring\TopologyOpeningEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
    'MongoDB\Driver\Query::__construct' => ['void', 'filter' => 'object|array', 'queryOptions=' => '?array'],
    'MongoDB\Driver\ReadConcern::__construct' => ['void', 'level=' => '?string'],
    'MongoDB\Driver\ReadConcern::getLevel' => ['?string'],
    'MongoDB\Driver\ReadConcern::isDefault' => ['bool'],
    'MongoDB\Driver\ReadConcern::bsonSerialize' => ['object|array'],
    'MongoDB\Driver\ReadConcern::serialize' => ['string'],
    'MongoDB\Driver\ReadConcern::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\Driver\ReadPreference::__construct' => ['void', 'mode' => 'string|int', 'tagSets=' => '?array', 'options=' => '?array'],
    'MongoDB\Driver\ReadPreference::getHedge' => ['?object'],
    'MongoDB\Driver\ReadPreference::getMaxStalenessSeconds' => ['int'],
    'MongoDB\Driver\ReadPreference::getMode' => ['int'],
    'MongoDB\Driver\ReadPreference::getModeString' => ['string'],
    'MongoDB\Driver\ReadPreference::getTagSets' => ['array'],
    'MongoDB\Driver\ReadPreference::bsonSerialize' => ['object|array'],
    'MongoDB\Driver\ReadPreference::serialize' => ['string'],
    'MongoDB\Driver\ReadPreference::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\Driver\Server::executeBulkWrite' => ['MongoDB\Driver\WriteResult', 'namespace' => 'string', 'bulkWrite' => 'MongoDB\Driver\BulkWrite', 'options=' => 'MongoDB\Driver\WriteConcern|array|null'],
    'MongoDB\Driver\Server::executeCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
    'MongoDB\Driver\Server::executeQuery' => ['MongoDB\Driver\Cursor', 'namespace' => 'string', 'query' => 'MongoDB\Driver\Query', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
    'MongoDB\Driver\Server::executeReadCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
    'MongoDB\Driver\Server::executeReadWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
    'MongoDB\Driver\Server::executeWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
    'MongoDB\Driver\Server::getHost' => ['string'],
    'MongoDB\Driver\Server::getInfo' => ['array'],
    'MongoDB\Driver\Server::getLatency' => ['?int'],
    'MongoDB\Driver\Server::getPort' => ['int'],
    'MongoDB\Driver\Server::getServerDescription' => ['MongoDB\Driver\ServerDescription'],
    'MongoDB\Driver\Server::getTags' => ['array'],
    'MongoDB\Driver\Server::getType' => ['int'],
    'MongoDB\Driver\Server::isArbiter' => ['bool'],
    'MongoDB\Driver\Server::isHidden' => ['bool'],
    'MongoDB\Driver\Server::isPassive' => ['bool'],
    'MongoDB\Driver\Server::isPrimary' => ['bool'],
    'MongoDB\Driver\Server::isSecondary' => ['bool'],
    'MongoDB\Driver\ServerApi::__construct' => ['void', 'version' => 'string', 'strict=' => '?bool', 'deprecationErrors=' => '?bool'],
    'MongoDB\Driver\ServerApi::bsonSerialize' => ['object|array'],
    'MongoDB\Driver\ServerApi::serialize' => ['string'],
    'MongoDB\Driver\ServerApi::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\Driver\ServerDescription::getHelloResponse' => ['array'],
    'MongoDB\Driver\ServerDescription::getHost' => ['string'],
    'MongoDB\Driver\ServerDescription::getLastUpdateTime' => ['int'],
    'MongoDB\Driver\ServerDescription::getPort' => ['int'],
    'MongoDB\Driver\ServerDescription::getRoundTripTime' => ['?int'],
    'MongoDB\Driver\ServerDescription::getType' => ['string'],
    'MongoDB\Driver\Session::abortTransaction' => ['void'],
    'MongoDB\Driver\Session::advanceClusterTime' => ['void', 'clusterTime' => 'object|array'],
    'MongoDB\Driver\Session::advanceOperationTime' => ['void', 'operationTime' => 'MongoDB\BSON\TimestampInterface'],
    'MongoDB\Driver\Session::commitTransaction' => ['void'],
    'MongoDB\Driver\Session::endSession' => ['void'],
    'MongoDB\Driver\Session::getClusterTime' => ['?object'],
    'MongoDB\Driver\Session::getLogicalSessionId' => ['object'],
    'MongoDB\Driver\Session::getOperationTime' => ['?MongoDB\BSON\Timestamp'],
    'MongoDB\Driver\Session::getServer' => ['?MongoDB\Driver\Server'],
    'MongoDB\Driver\Session::getTransactionOptions' => ['?array'],
    'MongoDB\Driver\Session::getTransactionState' => ['string'],
    'MongoDB\Driver\Session::isDirty' => ['bool'],
    'MongoDB\Driver\Session::isInTransaction' => ['bool'],
    'MongoDB\Driver\Session::startTransaction' => ['void', 'options=' => '?array'],
    'MongoDB\Driver\TopologyDescription::getServers' => ['array'],
    'MongoDB\Driver\TopologyDescription::getType' => ['string'],
    'MongoDB\Driver\TopologyDescription::hasReadableServer' => ['bool', 'readPreference=' => '?MongoDB\Driver\ReadPreference'],
    'MongoDB\Driver\TopologyDescription::hasWritableServer' => ['bool'],
    'MongoDB\Driver\WriteConcern::__construct' => ['void', 'w' => 'string|int', 'wtimeout=' => '?int', 'journal=' => '?bool'],
    'MongoDB\Driver\WriteConcern::getJournal' => ['?bool'],
    'MongoDB\Driver\WriteConcern::getW' => ['string|int|null'],
    'MongoDB\Driver\WriteConcern::getWtimeout' => ['int'],
    'MongoDB\Driver\WriteConcern::isDefault' => ['bool'],
    'MongoDB\Driver\WriteConcern::bsonSerialize' => ['object|array'],
    'MongoDB\Driver\WriteConcern::serialize' => ['string'],
    'MongoDB\Driver\WriteConcern::unserialize' => ['void', 'serialized' => 'string'],
    'MongoDB\Driver\WriteConcernError::getCode' => ['int'],
    'MongoDB\Driver\WriteConcernError::getInfo' => ['?object'],
    'MongoDB\Driver\WriteConcernError::getMessage' => ['string'],
    'MongoDB\Driver\WriteError::getCode' => ['int'],
    'MongoDB\Driver\WriteError::getIndex' => ['int'],
    'MongoDB\Driver\WriteError::getInfo' => ['?object'],
    'MongoDB\Driver\WriteError::getMessage' => ['string'],
    'MongoDB\Driver\WriteResult::getInsertedCount' => ['?int'],
    'MongoDB\Driver\WriteResult::getMatchedCount' => ['?int'],
    'MongoDB\Driver\WriteResult::getModifiedCount' => ['?int'],
    'MongoDB\Driver\WriteResult::getDeletedCount' => ['?int'],
    'MongoDB\Driver\WriteResult::getUpsertedCount' => ['?int'],
    'MongoDB\Driver\WriteResult::getServer' => ['MongoDB\Driver\Server'],
    'MongoDB\Driver\WriteResult::getUpsertedIds' => ['array'],
    'MongoDB\Driver\WriteResult::getWriteConcernError' => ['?MongoDB\Driver\WriteConcernError'],
    'MongoDB\Driver\WriteResult::getWriteErrors' => ['array'],
    'MongoDB\Driver\WriteResult::isAcknowledged' => ['bool'],
    'MongoDate::__construct' => ['void', 'second='=>'int', 'usecond='=>'int'],
    'MongoDate::__toString' => ['string'],
    'MongoDate::toDateTime' => ['DateTime'],
    'MongoDeleteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'],
    'MongoException::__clone' => ['void'],
    'MongoException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'MongoException::__toString' => ['string'],
    'MongoException::__wakeup' => ['void'],
    'MongoException::getCode' => ['int'],
    'MongoException::getFile' => ['string'],
    'MongoException::getLine' => ['int'],
    'MongoException::getMessage' => ['string'],
    'MongoException::getPrevious' => ['Exception|Throwable'],
    'MongoException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'MongoException::getTraceAsString' => ['string'],
    'MongoGridFS::__construct' => ['void', 'db'=>'MongoDB', 'prefix='=>'string', 'chunks='=>'mixed'],
    'MongoGridFS::__get' => ['MongoCollection', 'name'=>'string'],
    'MongoGridFS::__toString' => ['string'],
    'MongoGridFS::aggregate' => ['array', 'pipeline'=>'array', 'op'=>'array', 'pipelineOperators'=>'array'],
    'MongoGridFS::aggregateCursor' => ['MongoCommandCursor', 'pipeline'=>'array', 'options'=>'array'],
    'MongoGridFS::batchInsert' => ['mixed', 'a'=>'array', 'options='=>'array'],
    'MongoGridFS::count' => ['int', 'query='=>'stdClass|array'],
    'MongoGridFS::createDBRef' => ['array', 'a'=>'array'],
    'MongoGridFS::createIndex' => ['array', 'keys'=>'array', 'options='=>'array'],
    'MongoGridFS::delete' => ['bool', 'id'=>'mixed'],
    'MongoGridFS::deleteIndex' => ['array', 'keys'=>'array|string'],
    'MongoGridFS::deleteIndexes' => ['array'],
    'MongoGridFS::distinct' => ['array|bool', 'key'=>'string', 'query='=>'?array'],
    'MongoGridFS::drop' => ['array'],
    'MongoGridFS::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'],
    'MongoGridFS::find' => ['MongoGridFSCursor', 'query='=>'array', 'fields='=>'array'],
    'MongoGridFS::findAndModify' => ['array', 'query'=>'array', 'update='=>'?array', 'fields='=>'?array', 'options='=>'?array'],
    'MongoGridFS::findOne' => ['?MongoGridFSFile', 'query='=>'mixed', 'fields='=>'mixed'],
    'MongoGridFS::get' => ['?MongoGridFSFile', 'id'=>'mixed'],
    'MongoGridFS::getDBRef' => ['array', 'ref'=>'array'],
    'MongoGridFS::getIndexInfo' => ['array'],
    'MongoGridFS::getName' => ['string'],
    'MongoGridFS::getReadPreference' => ['array'],
    'MongoGridFS::getSlaveOkay' => ['bool'],
    'MongoGridFS::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'MongoCode', 'condition='=>'array'],
    'MongoGridFS::insert' => ['array|bool', 'a'=>'array|object', 'options='=>'array'],
    'MongoGridFS::put' => ['mixed', 'filename'=>'string', 'extra='=>'array'],
    'MongoGridFS::remove' => ['bool', 'criteria='=>'array', 'options='=>'array'],
    'MongoGridFS::save' => ['array|bool', 'a'=>'array|object', 'options='=>'array'],
    'MongoGridFS::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags'=>'array'],
    'MongoGridFS::setSlaveOkay' => ['bool', 'ok='=>'bool'],
    'MongoGridFS::storeBytes' => ['mixed', 'bytes'=>'string', 'extra='=>'array', 'options='=>'array'],
    'MongoGridFS::storeFile' => ['mixed', 'filename'=>'string', 'extra='=>'array', 'options='=>'array'],
    'MongoGridFS::storeUpload' => ['mixed', 'name'=>'string', 'filename='=>'string'],
    'MongoGridFS::toIndexString' => ['string', 'keys'=>'mixed'],
    'MongoGridFS::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'],
    'MongoGridFS::validate' => ['array', 'scan_data='=>'bool'],
    'MongoGridFSCursor::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'connection'=>'resource', 'ns'=>'string', 'query'=>'array', 'fields'=>'array'],
    'MongoGridFSCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'],
    'MongoGridFSCursor::awaitData' => ['MongoCursor', 'wait='=>'bool'],
    'MongoGridFSCursor::batchSize' => ['MongoCursor', 'batchSize'=>'int'],
    'MongoGridFSCursor::count' => ['int', 'all='=>'bool'],
    'MongoGridFSCursor::current' => ['MongoGridFSFile'],
    'MongoGridFSCursor::dead' => ['bool'],
    'MongoGridFSCursor::doQuery' => ['void'],
    'MongoGridFSCursor::explain' => ['array'],
    'MongoGridFSCursor::fields' => ['MongoCursor', 'f'=>'array'],
    'MongoGridFSCursor::getNext' => ['MongoGridFSFile'],
    'MongoGridFSCursor::getReadPreference' => ['array'],
    'MongoGridFSCursor::hasNext' => ['bool'],
    'MongoGridFSCursor::hint' => ['MongoCursor', 'key_pattern'=>'mixed'],
    'MongoGridFSCursor::immortal' => ['MongoCursor', 'liveForever='=>'bool'],
    'MongoGridFSCursor::info' => ['array'],
    'MongoGridFSCursor::key' => ['string'],
    'MongoGridFSCursor::limit' => ['MongoCursor', 'num'=>'int'],
    'MongoGridFSCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'],
    'MongoGridFSCursor::next' => ['void'],
    'MongoGridFSCursor::partial' => ['MongoCursor', 'okay='=>'bool'],
    'MongoGridFSCursor::reset' => ['void'],
    'MongoGridFSCursor::rewind' => ['void'],
    'MongoGridFSCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool'],
    'MongoGridFSCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags'=>'array'],
    'MongoGridFSCursor::skip' => ['MongoCursor', 'num'=>'int'],
    'MongoGridFSCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool'],
    'MongoGridFSCursor::snapshot' => ['MongoCursor'],
    'MongoGridFSCursor::sort' => ['MongoCursor', 'fields'=>'array'],
    'MongoGridFSCursor::tailable' => ['MongoCursor', 'tail='=>'bool'],
    'MongoGridFSCursor::timeout' => ['MongoCursor', 'ms'=>'int'],
    'MongoGridFSCursor::valid' => ['bool'],
    'MongoGridFSFile::getBytes' => ['string'],
    'MongoGridFSFile::getFilename' => ['string'],
    'MongoGridFSFile::getResource' => ['resource'],
    'MongoGridFSFile::getSize' => ['int'],
    'MongoGridFSFile::write' => ['int', 'filename='=>'string'],
    'MongoGridfsFile::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'file'=>'array'],
    'MongoId::__construct' => ['void', 'id='=>'string|MongoId'],
    'MongoId::__set_state' => ['MongoId', 'props'=>'array'],
    'MongoId::__toString' => ['string'],
    'MongoId::getHostname' => ['string'],
    'MongoId::getInc' => ['int'],
    'MongoId::getPID' => ['int'],
    'MongoId::getTimestamp' => ['int'],
    'MongoId::isValid' => ['bool', 'value'=>'mixed'],
    'MongoInsertBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'],
    'MongoInt32::__construct' => ['void', 'value'=>'string'],
    'MongoInt32::__toString' => ['string'],
    'MongoInt64::__construct' => ['void', 'value'=>'string'],
    'MongoInt64::__toString' => ['string'],
    'MongoLog::getCallback' => ['callable'],
    'MongoLog::getLevel' => ['int'],
    'MongoLog::getModule' => ['int'],
    'MongoLog::setCallback' => ['void', 'log_function'=>'callable'],
    'MongoLog::setLevel' => ['void', 'level'=>'int'],
    'MongoLog::setModule' => ['void', 'module'=>'int'],
    'MongoPool::getSize' => ['int'],
    'MongoPool::info' => ['array'],
    'MongoPool::setSize' => ['bool', 'size'=>'int'],
    'MongoRegex::__construct' => ['void', 'regex'=>'string'],
    'MongoRegex::__toString' => ['string'],
    'MongoResultException::__clone' => ['void'],
    'MongoResultException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'MongoResultException::__toString' => ['string'],
    'MongoResultException::__wakeup' => ['void'],
    'MongoResultException::getCode' => ['int'],
    'MongoResultException::getDocument' => ['array'],
    'MongoResultException::getFile' => ['string'],
    'MongoResultException::getLine' => ['int'],
    'MongoResultException::getMessage' => ['string'],
    'MongoResultException::getPrevious' => ['Exception|Throwable'],
    'MongoResultException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'MongoResultException::getTraceAsString' => ['string'],
    'MongoTimestamp::__construct' => ['void', 'second='=>'int', 'inc='=>'int'],
    'MongoTimestamp::__toString' => ['string'],
    'MongoUpdateBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'],
    'MongoUpdateBatch::add' => ['bool', 'item'=>'array'],
    'MongoUpdateBatch::execute' => ['array', 'write_options'=>'array'],
    'MongoWriteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'batch_type'=>'string', 'write_options'=>'array'],
    'MongoWriteBatch::add' => ['bool', 'item'=>'array'],
    'MongoWriteBatch::execute' => ['array', 'write_options'=>'array'],
    'MongoWriteConcernException::__clone' => ['void'],
    'MongoWriteConcernException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'MongoWriteConcernException::__toString' => ['string'],
    'MongoWriteConcernException::__wakeup' => ['void'],
    'MongoWriteConcernException::getCode' => ['int'],
    'MongoWriteConcernException::getDocument' => ['array'],
    'MongoWriteConcernException::getFile' => ['string'],
    'MongoWriteConcernException::getLine' => ['int'],
    'MongoWriteConcernException::getMessage' => ['string'],
    'MongoWriteConcernException::getPrevious' => ['Exception|Throwable'],
    'MongoWriteConcernException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'MongoWriteConcernException::getTraceAsString' => ['string'],
    'MultipleIterator::__construct' => ['void', 'flags='=>'int'],
    'MultipleIterator::attachIterator' => ['void', 'iterator'=>'Iterator', 'infos='=>'string'],
    'MultipleIterator::containsIterator' => ['bool', 'iterator'=>'Iterator'],
    'MultipleIterator::countIterators' => ['int'],
    'MultipleIterator::current' => ['array|false'],
    'MultipleIterator::detachIterator' => ['void', 'iterator'=>'Iterator'],
    'MultipleIterator::getFlags' => ['int'],
    'MultipleIterator::key' => ['array'],
    'MultipleIterator::next' => ['void'],
    'MultipleIterator::rewind' => ['void'],
    'MultipleIterator::setFlags' => ['void', 'flags'=>'int'],
    'MultipleIterator::valid' => ['bool'],
    'Mutex::create' => ['long', 'lock='=>'bool'],
    'Mutex::destroy' => ['bool', 'mutex'=>'long'],
    'Mutex::lock' => ['bool', 'mutex'=>'long'],
    'Mutex::trylock' => ['bool', 'mutex'=>'long'],
    'Mutex::unlock' => ['bool', 'mutex'=>'long', 'destroy='=>'bool'],
    'MysqlndUhConnection::__construct' => ['void'],
    'MysqlndUhConnection::changeUser' => ['bool', 'connection'=>'mysqlnd_connection', 'user'=>'string', 'password'=>'string', 'database'=>'string', 'silent'=>'bool', 'passwd_len'=>'int'],
    'MysqlndUhConnection::charsetName' => ['string', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::close' => ['bool', 'connection'=>'mysqlnd_connection', 'close_type'=>'int'],
    'MysqlndUhConnection::connect' => ['bool', 'connection'=>'mysqlnd_connection', 'host'=>'string', 'use'=>'string', 'password'=>'string', 'database'=>'string', 'port'=>'int', 'socket'=>'string', 'mysql_flags'=>'int'],
    'MysqlndUhConnection::endPSession' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::escapeString' => ['string', 'connection'=>'mysqlnd_connection', 'escape_string'=>'string'],
    'MysqlndUhConnection::getAffectedRows' => ['int', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getErrorNumber' => ['int', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getErrorString' => ['string', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getFieldCount' => ['int', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getHostInformation' => ['string', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getLastInsertId' => ['int', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getLastMessage' => ['void', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getProtocolInformation' => ['string', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getServerInformation' => ['string', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getServerStatistics' => ['string', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getServerVersion' => ['int', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getSqlstate' => ['string', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getStatistics' => ['array', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getThreadId' => ['int', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::getWarningCount' => ['int', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::init' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::killConnection' => ['bool', 'connection'=>'mysqlnd_connection', 'pid'=>'int'],
    'MysqlndUhConnection::listFields' => ['array', 'connection'=>'mysqlnd_connection', 'table'=>'string', 'achtung_wild'=>'string'],
    'MysqlndUhConnection::listMethod' => ['void', 'connection'=>'mysqlnd_connection', 'query'=>'string', 'achtung_wild'=>'string', 'par1'=>'string'],
    'MysqlndUhConnection::moreResults' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::nextResult' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::ping' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::query' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'],
    'MysqlndUhConnection::queryReadResultsetHeader' => ['bool', 'connection'=>'mysqlnd_connection', 'mysqlnd_stmt'=>'mysqlnd_statement'],
    'MysqlndUhConnection::reapQuery' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::refreshServer' => ['bool', 'connection'=>'mysqlnd_connection', 'options'=>'int'],
    'MysqlndUhConnection::restartPSession' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::selectDb' => ['bool', 'connection'=>'mysqlnd_connection', 'database'=>'string'],
    'MysqlndUhConnection::sendClose' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::sendQuery' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'],
    'MysqlndUhConnection::serverDumpDebugInformation' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::setAutocommit' => ['bool', 'connection'=>'mysqlnd_connection', 'mode'=>'int'],
    'MysqlndUhConnection::setCharset' => ['bool', 'connection'=>'mysqlnd_connection', 'charset'=>'string'],
    'MysqlndUhConnection::setClientOption' => ['bool', 'connection'=>'mysqlnd_connection', 'option'=>'int', 'value'=>'int'],
    'MysqlndUhConnection::setServerOption' => ['void', 'connection'=>'mysqlnd_connection', 'option'=>'int'],
    'MysqlndUhConnection::shutdownServer' => ['void', 'MYSQLND_UH_RES_MYSQLND_NAME'=>'string', 'level'=>'string'],
    'MysqlndUhConnection::simpleCommand' => ['bool', 'connection'=>'mysqlnd_connection', 'command'=>'int', 'arg'=>'string', 'ok_packet'=>'int', 'silent'=>'bool', 'ignore_upsert_status'=>'bool'],
    'MysqlndUhConnection::simpleCommandHandleResponse' => ['bool', 'connection'=>'mysqlnd_connection', 'ok_packet'=>'int', 'silent'=>'bool', 'command'=>'int', 'ignore_upsert_status'=>'bool'],
    'MysqlndUhConnection::sslSet' => ['bool', 'connection'=>'mysqlnd_connection', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'],
    'MysqlndUhConnection::stmtInit' => ['resource', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::storeResult' => ['resource', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::txCommit' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::txRollback' => ['bool', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhConnection::useResult' => ['resource', 'connection'=>'mysqlnd_connection'],
    'MysqlndUhPreparedStatement::__construct' => ['void'],
    'MysqlndUhPreparedStatement::execute' => ['bool', 'statement'=>'mysqlnd_prepared_statement'],
    'MysqlndUhPreparedStatement::prepare' => ['bool', 'statement'=>'mysqlnd_prepared_statement', 'query'=>'string'],
    'NoRewindIterator::__construct' => ['void', 'iterator'=>'Iterator'],
    'NoRewindIterator::current' => ['mixed'],
    'NoRewindIterator::getInnerIterator' => ['Iterator'],
    'NoRewindIterator::key' => ['mixed'],
    'NoRewindIterator::next' => ['void'],
    'NoRewindIterator::rewind' => ['void'],
    'NoRewindIterator::valid' => ['bool'],
    'Normalizer::getRawDecomposition' => ['string|null', 'input'=>'string'],
    'Normalizer::isNormalized' => ['bool', 'input'=>'string', 'form='=>'int'],
    'Normalizer::normalize' => ['string', 'input'=>'string', 'form='=>'int'],
    'NumberFormatter::__construct' => ['void', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'],
    'NumberFormatter::create' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'],
    'NumberFormatter::format' => ['string|false', 'num'=>'', 'type='=>'int'],
    'NumberFormatter::formatCurrency' => ['string|false', 'num'=>'float', 'currency'=>'string'],
    'NumberFormatter::getAttribute' => ['int|false', 'attr'=>'int'],
    'NumberFormatter::getErrorCode' => ['int'],
    'NumberFormatter::getErrorMessage' => ['string'],
    'NumberFormatter::getLocale' => ['string', 'type='=>'int'],
    'NumberFormatter::getPattern' => ['string|false'],
    'NumberFormatter::getSymbol' => ['string|false', 'attr'=>'int'],
    'NumberFormatter::getTextAttribute' => ['string|false', 'attr'=>'int'],
    'NumberFormatter::parse' => ['float|false', 'string'=>'string', 'type='=>'int', '&rw_position='=>'int'],
    'NumberFormatter::parseCurrency' => ['float|false', 'string'=>'string', '&w_currency'=>'string', '&rw_position='=>'int'],
    'NumberFormatter::setAttribute' => ['bool', 'attr'=>'int', 'value'=>''],
    'NumberFormatter::setPattern' => ['bool', 'pattern'=>'string'],
    'NumberFormatter::setSymbol' => ['bool', 'attr'=>'int', 'symbol'=>'string'],
    'NumberFormatter::setTextAttribute' => ['bool', 'attr'=>'int', 'value'=>'string'],
    'OAuth::__construct' => ['void', 'consumer_key'=>'string', 'consumer_secret'=>'string', 'signature_method='=>'string', 'auth_type='=>'int'],
    'OAuth::disableDebug' => ['bool'],
    'OAuth::disableRedirects' => ['bool'],
    'OAuth::disableSSLChecks' => ['bool'],
    'OAuth::enableDebug' => ['bool'],
    'OAuth::enableRedirects' => ['bool'],
    'OAuth::enableSSLChecks' => ['bool'],
    'OAuth::fetch' => ['mixed', 'protected_resource_url'=>'string', 'extra_parameters='=>'array', 'http_method='=>'string', 'http_headers='=>'array'],
    'OAuth::generateSignature' => ['string', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'],
    'OAuth::getAccessToken' => ['array|false', 'access_token_url'=>'string', 'auth_session_handle='=>'string', 'verifier_token='=>'string', 'http_method='=>'string'],
    'OAuth::getCAPath' => ['array'],
    'OAuth::getLastResponse' => ['string'],
    'OAuth::getLastResponseHeaders' => ['string|false'],
    'OAuth::getLastResponseInfo' => ['array'],
    'OAuth::getRequestHeader' => ['string|false', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'],
    'OAuth::getRequestToken' => ['array|false', 'request_token_url'=>'string', 'callback_url='=>'string', 'http_method='=>'string'],
    'OAuth::setAuthType' => ['bool', 'auth_type'=>'int'],
    'OAuth::setCAPath' => ['mixed', 'ca_path='=>'string', 'ca_info='=>'string'],
    'OAuth::setNonce' => ['mixed', 'nonce'=>'string'],
    'OAuth::setRSACertificate' => ['mixed', 'cert'=>'string'],
    'OAuth::setRequestEngine' => ['void', 'reqengine'=>'int'],
    'OAuth::setSSLChecks' => ['bool', 'sslcheck'=>'int'],
    'OAuth::setTimeout' => ['void', 'timeout'=>'int'],
    'OAuth::setTimestamp' => ['mixed', 'timestamp'=>'string'],
    'OAuth::setToken' => ['bool', 'token'=>'string', 'token_secret'=>'string'],
    'OAuth::setVersion' => ['bool', 'version'=>'string'],
    'OAuthProvider::__construct' => ['void', 'params_array='=>'array'],
    'OAuthProvider::addRequiredParameter' => ['bool', 'req_params'=>'string'],
    'OAuthProvider::callTimestampNonceHandler' => ['void'],
    'OAuthProvider::callconsumerHandler' => ['void'],
    'OAuthProvider::calltokenHandler' => ['void'],
    'OAuthProvider::checkOAuthRequest' => ['void', 'uri='=>'string', 'method='=>'string'],
    'OAuthProvider::consumerHandler' => ['void', 'callback_function'=>'callable'],
    'OAuthProvider::generateToken' => ['string', 'size'=>'int', 'strong='=>'bool'],
    'OAuthProvider::is2LeggedEndpoint' => ['void', 'params_array'=>'mixed'],
    'OAuthProvider::isRequestTokenEndpoint' => ['void', 'will_issue_request_token'=>'bool'],
    'OAuthProvider::removeRequiredParameter' => ['bool', 'req_params'=>'string'],
    'OAuthProvider::reportProblem' => ['string', 'oauthexception'=>'string', 'send_headers='=>'bool'],
    'OAuthProvider::setParam' => ['bool', 'param_key'=>'string', 'param_val='=>'mixed'],
    'OAuthProvider::setRequestTokenPath' => ['bool', 'path'=>'string'],
    'OAuthProvider::timestampNonceHandler' => ['void', 'callback_function'=>'callable'],
    'OAuthProvider::tokenHandler' => ['void', 'callback_function'=>'callable'],
    'OCICollection::append' => ['bool', 'value'=>'mixed'],
    'OCICollection::assign' => ['bool', 'from'=>'OCI_Collection'],
    'OCICollection::assignElem' => ['bool', 'index'=>'int', 'value'=>'mixed'],
    'OCICollection::free' => ['bool'],
    'OCICollection::getElem' => ['mixed', 'index'=>'int'],
    'OCICollection::max' => ['int|false'],
    'OCICollection::size' => ['int|false'],
    'OCICollection::trim' => ['bool', 'num'=>'int'],
    'OCILob::append' => ['bool', 'lob_from'=>'OCILob'],
    'OCILob::close' => ['bool'],
    'OCILob::eof' => ['bool'],
    'OCILob::erase' => ['int|false', 'offset='=>'int', 'length='=>'int'],
    'OCILob::export' => ['bool', 'filename'=>'string', 'start='=>'int', 'length='=>'int'],
    'OCILob::flush' => ['bool', 'flag='=>'int'],
    'OCILob::free' => ['bool'],
    'OCILob::getbuffering' => ['bool'],
    'OCILob::import' => ['bool', 'filename'=>'string'],
    'OCILob::load' => ['string|false'],
    'OCILob::read' => ['string|false', 'length'=>'int'],
    'OCILob::rewind' => ['bool'],
    'OCILob::save' => ['bool', 'data'=>'string', 'offset='=>'int'],
    'OCILob::savefile' => ['bool', 'filename'=>''],
    'OCILob::seek' => ['bool', 'offset'=>'int', 'whence='=>'int'],
    'OCILob::setbuffering' => ['bool', 'on_off'=>'bool'],
    'OCILob::size' => ['int|false'],
    'OCILob::tell' => ['int|false'],
    'OCILob::truncate' => ['bool', 'length='=>'int'],
    'OCILob::write' => ['int|false', 'data'=>'string', 'length='=>'int'],
    'OCILob::writeTemporary' => ['bool', 'data'=>'string', 'lob_type='=>'int'],
    'OCILob::writetofile' => ['bool', 'filename'=>'', 'start'=>'', 'length'=>''],
    'OutOfBoundsException::__clone' => ['void'],
    'OutOfBoundsException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'OutOfBoundsException::__toString' => ['string'],
    'OutOfBoundsException::getCode' => ['int'],
    'OutOfBoundsException::getFile' => ['string'],
    'OutOfBoundsException::getLine' => ['int'],
    'OutOfBoundsException::getMessage' => ['string'],
    'OutOfBoundsException::getPrevious' => ['?Throwable'],
    'OutOfBoundsException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'OutOfBoundsException::getTraceAsString' => ['string'],
    'OutOfRangeException::__clone' => ['void'],
    'OutOfRangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'OutOfRangeException::__toString' => ['string'],
    'OutOfRangeException::getCode' => ['int'],
    'OutOfRangeException::getFile' => ['string'],
    'OutOfRangeException::getLine' => ['int'],
    'OutOfRangeException::getMessage' => ['string'],
    'OutOfRangeException::getPrevious' => ['?Throwable'],
    'OutOfRangeException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'OutOfRangeException::getTraceAsString' => ['string'],
    'OuterIterator::current' => ['mixed'],
    'OuterIterator::getInnerIterator' => ['Iterator'],
    'OuterIterator::key' => ['int|string'],
    'OuterIterator::next' => ['void'],
    'OuterIterator::rewind' => ['void'],
    'OuterIterator::valid' => ['bool'],
    'OverflowException::__clone' => ['void'],
    'OverflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'OverflowException::__toString' => ['string'],
    'OverflowException::getCode' => ['int'],
    'OverflowException::getFile' => ['string'],
    'OverflowException::getLine' => ['int'],
    'OverflowException::getMessage' => ['string'],
    'OverflowException::getPrevious' => ['?Throwable'],
    'OverflowException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'OverflowException::getTraceAsString' => ['string'],
    'OwsrequestObj::__construct' => ['void'],
    'OwsrequestObj::addParameter' => ['int', 'name'=>'string', 'value'=>'string'],
    'OwsrequestObj::getName' => ['string', 'index'=>'int'],
    'OwsrequestObj::getValue' => ['string', 'index'=>'int'],
    'OwsrequestObj::getValueByName' => ['string', 'name'=>'string'],
    'OwsrequestObj::loadParams' => ['int'],
    'OwsrequestObj::setParameter' => ['int', 'name'=>'string', 'value'=>'string'],
    'PDF_activate_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'],
    'PDF_add_launchlink' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'],
    'PDF_add_locallink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'page'=>'int', 'dest'=>'string'],
    'PDF_add_nameddest' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'],
    'PDF_add_note' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'],
    'PDF_add_pdflink' => ['bool', 'pdfdoc'=>'resource', 'bottom_left_x'=>'float', 'bottom_left_y'=>'float', 'up_right_x'=>'float', 'up_right_y'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'],
    'PDF_add_table_cell' => ['int', 'pdfdoc'=>'resource', 'table'=>'int', 'column'=>'int', 'row'=>'int', 'text'=>'string', 'optlist'=>'string'],
    'PDF_add_textflow' => ['int', 'pdfdoc'=>'resource', 'textflow'=>'int', 'text'=>'string', 'optlist'=>'string'],
    'PDF_add_thumbnail' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int'],
    'PDF_add_weblink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'url'=>'string'],
    'PDF_arc' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
    'PDF_arcn' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
    'PDF_attach_file' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'description'=>'string', 'author'=>'string', 'mimetype'=>'string', 'icon'=>'string'],
    'PDF_begin_document' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'],
    'PDF_begin_font' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float', 'optlist'=>'string'],
    'PDF_begin_glyph' => ['bool', 'pdfdoc'=>'resource', 'glyphname'=>'string', 'wx'=>'float', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float'],
    'PDF_begin_item' => ['int', 'pdfdoc'=>'resource', 'tag'=>'string', 'optlist'=>'string'],
    'PDF_begin_layer' => ['bool', 'pdfdoc'=>'resource', 'layer'=>'int'],
    'PDF_begin_page' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
    'PDF_begin_page_ext' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
    'PDF_begin_pattern' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'],
    'PDF_begin_template' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
    'PDF_begin_template_ext' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
    'PDF_circle' => ['bool', 'pdfdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float'],
    'PDF_clip' => ['bool', 'p'=>'resource'],
    'PDF_close' => ['bool', 'p'=>'resource'],
    'PDF_close_image' => ['bool', 'p'=>'resource', 'image'=>'int'],
    'PDF_close_pdi' => ['bool', 'p'=>'resource', 'doc'=>'int'],
    'PDF_close_pdi_page' => ['bool', 'p'=>'resource', 'page'=>'int'],
    'PDF_closepath' => ['bool', 'p'=>'resource'],
    'PDF_closepath_fill_stroke' => ['bool', 'p'=>'resource'],
    'PDF_closepath_stroke' => ['bool', 'p'=>'resource'],
    'PDF_concat' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
    'PDF_continue_text' => ['bool', 'p'=>'resource', 'text'=>'string'],
    'PDF_create_3dview' => ['int', 'pdfdoc'=>'resource', 'username'=>'string', 'optlist'=>'string'],
    'PDF_create_action' => ['int', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'],
    'PDF_create_annotation' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'type'=>'string', 'optlist'=>'string'],
    'PDF_create_bookmark' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'],
    'PDF_create_field' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'name'=>'string', 'type'=>'string', 'optlist'=>'string'],
    'PDF_create_fieldgroup' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'],
    'PDF_create_gstate' => ['int', 'pdfdoc'=>'resource', 'optlist'=>'string'],
    'PDF_create_pvf' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'data'=>'string', 'optlist'=>'string'],
    'PDF_create_textflow' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'],
    'PDF_curveto' => ['bool', 'p'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
    'PDF_define_layer' => ['int', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'],
    'PDF_delete' => ['bool', 'pdfdoc'=>'resource'],
    'PDF_delete_pvf' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string'],
    'PDF_delete_table' => ['bool', 'pdfdoc'=>'resource', 'table'=>'int', 'optlist'=>'string'],
    'PDF_delete_textflow' => ['bool', 'pdfdoc'=>'resource', 'textflow'=>'int'],
    'PDF_encoding_set_char' => ['bool', 'pdfdoc'=>'resource', 'encoding'=>'string', 'slot'=>'int', 'glyphname'=>'string', 'uv'=>'int'],
    'PDF_end_document' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
    'PDF_end_font' => ['bool', 'pdfdoc'=>'resource'],
    'PDF_end_glyph' => ['bool', 'pdfdoc'=>'resource'],
    'PDF_end_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'],
    'PDF_end_layer' => ['bool', 'pdfdoc'=>'resource'],
    'PDF_end_page' => ['bool', 'p'=>'resource'],
    'PDF_end_page_ext' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
    'PDF_end_pattern' => ['bool', 'p'=>'resource'],
    'PDF_end_template' => ['bool', 'p'=>'resource'],
    'PDF_endpath' => ['bool', 'p'=>'resource'],
    'PDF_fill' => ['bool', 'p'=>'resource'],
    'PDF_fill_imageblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'image'=>'int', 'optlist'=>'string'],
    'PDF_fill_pdfblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'contents'=>'int', 'optlist'=>'string'],
    'PDF_fill_stroke' => ['bool', 'p'=>'resource'],
    'PDF_fill_textblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'text'=>'string', 'optlist'=>'string'],
    'PDF_findfont' => ['int', 'p'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed'=>'int'],
    'PDF_fit_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
    'PDF_fit_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
    'PDF_fit_table' => ['string', 'pdfdoc'=>'resource', 'table'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
    'PDF_fit_textflow' => ['string', 'pdfdoc'=>'resource', 'textflow'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
    'PDF_fit_textline' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
    'PDF_get_apiname' => ['string', 'pdfdoc'=>'resource'],
    'PDF_get_buffer' => ['string', 'p'=>'resource'],
    'PDF_get_errmsg' => ['string', 'pdfdoc'=>'resource'],
    'PDF_get_errnum' => ['int', 'pdfdoc'=>'resource'],
    'PDF_get_majorversion' => ['int'],
    'PDF_get_minorversion' => ['int'],
    'PDF_get_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'],
    'PDF_get_pdi_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
    'PDF_get_pdi_value' => ['float', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
    'PDF_get_value' => ['float', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'],
    'PDF_info_font' => ['float', 'pdfdoc'=>'resource', 'font'=>'int', 'keyword'=>'string', 'optlist'=>'string'],
    'PDF_info_matchbox' => ['float', 'pdfdoc'=>'resource', 'boxname'=>'string', 'num'=>'int', 'keyword'=>'string'],
    'PDF_info_table' => ['float', 'pdfdoc'=>'resource', 'table'=>'int', 'keyword'=>'string'],
    'PDF_info_textflow' => ['float', 'pdfdoc'=>'resource', 'textflow'=>'int', 'keyword'=>'string'],
    'PDF_info_textline' => ['float', 'pdfdoc'=>'resource', 'text'=>'string', 'keyword'=>'string', 'optlist'=>'string'],
    'PDF_initgraphics' => ['bool', 'p'=>'resource'],
    'PDF_lineto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'],
    'PDF_load_3ddata' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'],
    'PDF_load_font' => ['int', 'pdfdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'optlist'=>'string'],
    'PDF_load_iccprofile' => ['int', 'pdfdoc'=>'resource', 'profilename'=>'string', 'optlist'=>'string'],
    'PDF_load_image' => ['int', 'pdfdoc'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'optlist'=>'string'],
    'PDF_makespotcolor' => ['int', 'p'=>'resource', 'spotname'=>'string'],
    'PDF_moveto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'],
    'PDF_new' => ['resource'],
    'PDF_open_ccitt' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'bitreverse'=>'int', 'k'=>'int', 'blackls1'=>'int'],
    'PDF_open_file' => ['bool', 'p'=>'resource', 'filename'=>'string'],
    'PDF_open_image' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'],
    'PDF_open_image_file' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'stringparam'=>'string', 'intparam'=>'int'],
    'PDF_open_memory_image' => ['int', 'p'=>'resource', 'image'=>'resource'],
    'PDF_open_pdi' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string', 'length'=>'int'],
    'PDF_open_pdi_document' => ['int', 'p'=>'resource', 'filename'=>'string', 'optlist'=>'string'],
    'PDF_open_pdi_page' => ['int', 'p'=>'resource', 'doc'=>'int', 'pagenumber'=>'int', 'optlist'=>'string'],
    'PDF_pcos_get_number' => ['float', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'],
    'PDF_pcos_get_stream' => ['string', 'p'=>'resource', 'doc'=>'int', 'optlist'=>'string', 'path'=>'string'],
    'PDF_pcos_get_string' => ['string', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'],
    'PDF_place_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'],
    'PDF_place_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'sx'=>'float', 'sy'=>'float'],
    'PDF_process_pdi' => ['int', 'pdfdoc'=>'resource', 'doc'=>'int', 'page'=>'int', 'optlist'=>'string'],
    'PDF_rect' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
    'PDF_restore' => ['bool', 'p'=>'resource'],
    'PDF_resume_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
    'PDF_rotate' => ['bool', 'p'=>'resource', 'phi'=>'float'],
    'PDF_save' => ['bool', 'p'=>'resource'],
    'PDF_scale' => ['bool', 'p'=>'resource', 'sx'=>'float', 'sy'=>'float'],
    'PDF_set_border_color' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDF_set_border_dash' => ['bool', 'pdfdoc'=>'resource', 'black'=>'float', 'white'=>'float'],
    'PDF_set_border_style' => ['bool', 'pdfdoc'=>'resource', 'style'=>'string', 'width'=>'float'],
    'PDF_set_gstate' => ['bool', 'pdfdoc'=>'resource', 'gstate'=>'int'],
    'PDF_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'],
    'PDF_set_layer_dependency' => ['bool', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'],
    'PDF_set_parameter' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'],
    'PDF_set_text_pos' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'],
    'PDF_set_value' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'float'],
    'PDF_setcolor' => ['bool', 'p'=>'resource', 'fstype'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'],
    'PDF_setdash' => ['bool', 'pdfdoc'=>'resource', 'b'=>'float', 'w'=>'float'],
    'PDF_setdashpattern' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
    'PDF_setflat' => ['bool', 'pdfdoc'=>'resource', 'flatness'=>'float'],
    'PDF_setfont' => ['bool', 'pdfdoc'=>'resource', 'font'=>'int', 'fontsize'=>'float'],
    'PDF_setgray' => ['bool', 'p'=>'resource', 'g'=>'float'],
    'PDF_setgray_fill' => ['bool', 'p'=>'resource', 'g'=>'float'],
    'PDF_setgray_stroke' => ['bool', 'p'=>'resource', 'g'=>'float'],
    'PDF_setlinecap' => ['bool', 'p'=>'resource', 'linecap'=>'int'],
    'PDF_setlinejoin' => ['bool', 'p'=>'resource', 'value'=>'int'],
    'PDF_setlinewidth' => ['bool', 'p'=>'resource', 'width'=>'float'],
    'PDF_setmatrix' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
    'PDF_setmiterlimit' => ['bool', 'pdfdoc'=>'resource', 'miter'=>'float'],
    'PDF_setrgbcolor' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDF_setrgbcolor_fill' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDF_setrgbcolor_stroke' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDF_shading' => ['int', 'pdfdoc'=>'resource', 'shtype'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'],
    'PDF_shading_pattern' => ['int', 'pdfdoc'=>'resource', 'shading'=>'int', 'optlist'=>'string'],
    'PDF_shfill' => ['bool', 'pdfdoc'=>'resource', 'shading'=>'int'],
    'PDF_show' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string'],
    'PDF_show_boxed' => ['int', 'p'=>'resource', 'text'=>'string', 'left'=>'float', 'top'=>'float', 'width'=>'float', 'height'=>'float', 'mode'=>'string', 'feature'=>'string'],
    'PDF_show_xy' => ['bool', 'p'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'],
    'PDF_skew' => ['bool', 'p'=>'resource', 'alpha'=>'float', 'beta'=>'float'],
    'PDF_stringwidth' => ['float', 'p'=>'resource', 'text'=>'string', 'font'=>'int', 'fontsize'=>'float'],
    'PDF_stroke' => ['bool', 'p'=>'resource'],
    'PDF_suspend_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
    'PDF_translate' => ['bool', 'p'=>'resource', 'tx'=>'float', 'ty'=>'float'],
    'PDF_utf16_to_utf8' => ['string', 'pdfdoc'=>'resource', 'utf16string'=>'string'],
    'PDF_utf32_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf32string'=>'string', 'ordering'=>'string'],
    'PDF_utf8_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf8string'=>'string', 'ordering'=>'string'],
    'PDFlib::activate_item' => ['bool', 'id'=>''],
    'PDFlib::add_launchlink' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'],
    'PDFlib::add_locallink' => ['bool', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'page'=>'int', 'dest'=>'string'],
    'PDFlib::add_nameddest' => ['bool', 'name'=>'string', 'optlist'=>'string'],
    'PDFlib::add_note' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'],
    'PDFlib::add_pdflink' => ['bool', 'bottom_left_x'=>'float', 'bottom_left_y'=>'float', 'up_right_x'=>'float', 'up_right_y'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'],
    'PDFlib::add_table_cell' => ['int', 'table'=>'int', 'column'=>'int', 'row'=>'int', 'text'=>'string', 'optlist'=>'string'],
    'PDFlib::add_textflow' => ['int', 'textflow'=>'int', 'text'=>'string', 'optlist'=>'string'],
    'PDFlib::add_thumbnail' => ['bool', 'image'=>'int'],
    'PDFlib::add_weblink' => ['bool', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'url'=>'string'],
    'PDFlib::arc' => ['bool', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
    'PDFlib::arcn' => ['bool', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
    'PDFlib::attach_file' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'description'=>'string', 'author'=>'string', 'mimetype'=>'string', 'icon'=>'string'],
    'PDFlib::begin_document' => ['int', 'filename'=>'string', 'optlist'=>'string'],
    'PDFlib::begin_font' => ['bool', 'filename'=>'string', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float', 'optlist'=>'string'],
    'PDFlib::begin_glyph' => ['bool', 'glyphname'=>'string', 'wx'=>'float', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float'],
    'PDFlib::begin_item' => ['int', 'tag'=>'string', 'optlist'=>'string'],
    'PDFlib::begin_layer' => ['bool', 'layer'=>'int'],
    'PDFlib::begin_page' => ['bool', 'width'=>'float', 'height'=>'float'],
    'PDFlib::begin_page_ext' => ['bool', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
    'PDFlib::begin_pattern' => ['int', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'],
    'PDFlib::begin_template' => ['int', 'width'=>'float', 'height'=>'float'],
    'PDFlib::begin_template_ext' => ['int', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
    'PDFlib::circle' => ['bool', 'x'=>'float', 'y'=>'float', 'r'=>'float'],
    'PDFlib::clip' => ['bool'],
    'PDFlib::close' => ['bool'],
    'PDFlib::close_image' => ['bool', 'image'=>'int'],
    'PDFlib::close_pdi' => ['bool', 'doc'=>'int'],
    'PDFlib::close_pdi_page' => ['bool', 'page'=>'int'],
    'PDFlib::closepath' => ['bool'],
    'PDFlib::closepath_fill_stroke' => ['bool'],
    'PDFlib::closepath_stroke' => ['bool'],
    'PDFlib::concat' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
    'PDFlib::continue_text' => ['bool', 'text'=>'string'],
    'PDFlib::create_3dview' => ['int', 'username'=>'string', 'optlist'=>'string'],
    'PDFlib::create_action' => ['int', 'type'=>'string', 'optlist'=>'string'],
    'PDFlib::create_annotation' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'type'=>'string', 'optlist'=>'string'],
    'PDFlib::create_bookmark' => ['int', 'text'=>'string', 'optlist'=>'string'],
    'PDFlib::create_field' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'name'=>'string', 'type'=>'string', 'optlist'=>'string'],
    'PDFlib::create_fieldgroup' => ['bool', 'name'=>'string', 'optlist'=>'string'],
    'PDFlib::create_gstate' => ['int', 'optlist'=>'string'],
    'PDFlib::create_pvf' => ['bool', 'filename'=>'string', 'data'=>'string', 'optlist'=>'string'],
    'PDFlib::create_textflow' => ['int', 'text'=>'string', 'optlist'=>'string'],
    'PDFlib::curveto' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
    'PDFlib::define_layer' => ['int', 'name'=>'string', 'optlist'=>'string'],
    'PDFlib::delete' => ['bool'],
    'PDFlib::delete_pvf' => ['int', 'filename'=>'string'],
    'PDFlib::delete_table' => ['bool', 'table'=>'int', 'optlist'=>'string'],
    'PDFlib::delete_textflow' => ['bool', 'textflow'=>'int'],
    'PDFlib::encoding_set_char' => ['bool', 'encoding'=>'string', 'slot'=>'int', 'glyphname'=>'string', 'uv'=>'int'],
    'PDFlib::end_document' => ['bool', 'optlist'=>'string'],
    'PDFlib::end_font' => ['bool'],
    'PDFlib::end_glyph' => ['bool'],
    'PDFlib::end_item' => ['bool', 'id'=>'int'],
    'PDFlib::end_layer' => ['bool'],
    'PDFlib::end_page' => ['bool', 'p'=>''],
    'PDFlib::end_page_ext' => ['bool', 'optlist'=>'string'],
    'PDFlib::end_pattern' => ['bool', 'p'=>''],
    'PDFlib::end_template' => ['bool', 'p'=>''],
    'PDFlib::endpath' => ['bool', 'p'=>''],
    'PDFlib::fill' => ['bool'],
    'PDFlib::fill_imageblock' => ['int', 'page'=>'int', 'blockname'=>'string', 'image'=>'int', 'optlist'=>'string'],
    'PDFlib::fill_pdfblock' => ['int', 'page'=>'int', 'blockname'=>'string', 'contents'=>'int', 'optlist'=>'string'],
    'PDFlib::fill_stroke' => ['bool'],
    'PDFlib::fill_textblock' => ['int', 'page'=>'int', 'blockname'=>'string', 'text'=>'string', 'optlist'=>'string'],
    'PDFlib::findfont' => ['int', 'fontname'=>'string', 'encoding'=>'string', 'embed'=>'int'],
    'PDFlib::fit_image' => ['bool', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
    'PDFlib::fit_pdi_page' => ['bool', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
    'PDFlib::fit_table' => ['string', 'table'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
    'PDFlib::fit_textflow' => ['string', 'textflow'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
    'PDFlib::fit_textline' => ['bool', 'text'=>'string', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
    'PDFlib::get_apiname' => ['string'],
    'PDFlib::get_buffer' => ['string'],
    'PDFlib::get_errmsg' => ['string'],
    'PDFlib::get_errnum' => ['int'],
    'PDFlib::get_majorversion' => ['int'],
    'PDFlib::get_minorversion' => ['int'],
    'PDFlib::get_parameter' => ['string', 'key'=>'string', 'modifier'=>'float'],
    'PDFlib::get_pdi_parameter' => ['string', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
    'PDFlib::get_pdi_value' => ['float', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
    'PDFlib::get_value' => ['float', 'key'=>'string', 'modifier'=>'float'],
    'PDFlib::info_font' => ['float', 'font'=>'int', 'keyword'=>'string', 'optlist'=>'string'],
    'PDFlib::info_matchbox' => ['float', 'boxname'=>'string', 'num'=>'int', 'keyword'=>'string'],
    'PDFlib::info_table' => ['float', 'table'=>'int', 'keyword'=>'string'],
    'PDFlib::info_textflow' => ['float', 'textflow'=>'int', 'keyword'=>'string'],
    'PDFlib::info_textline' => ['float', 'text'=>'string', 'keyword'=>'string', 'optlist'=>'string'],
    'PDFlib::initgraphics' => ['bool'],
    'PDFlib::lineto' => ['bool', 'x'=>'float', 'y'=>'float'],
    'PDFlib::load_3ddata' => ['int', 'filename'=>'string', 'optlist'=>'string'],
    'PDFlib::load_font' => ['int', 'fontname'=>'string', 'encoding'=>'string', 'optlist'=>'string'],
    'PDFlib::load_iccprofile' => ['int', 'profilename'=>'string', 'optlist'=>'string'],
    'PDFlib::load_image' => ['int', 'imagetype'=>'string', 'filename'=>'string', 'optlist'=>'string'],
    'PDFlib::makespotcolor' => ['int', 'spotname'=>'string'],
    'PDFlib::moveto' => ['bool', 'x'=>'float', 'y'=>'float'],
    'PDFlib::open_ccitt' => ['int', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'BitReverse'=>'int', 'k'=>'int', 'Blackls1'=>'int'],
    'PDFlib::open_file' => ['bool', 'filename'=>'string'],
    'PDFlib::open_image' => ['int', 'imagetype'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'],
    'PDFlib::open_image_file' => ['int', 'imagetype'=>'string', 'filename'=>'string', 'stringparam'=>'string', 'intparam'=>'int'],
    'PDFlib::open_memory_image' => ['int', 'image'=>'resource'],
    'PDFlib::open_pdi' => ['int', 'filename'=>'string', 'optlist'=>'string', 'length'=>'int'],
    'PDFlib::open_pdi_document' => ['int', 'filename'=>'string', 'optlist'=>'string'],
    'PDFlib::open_pdi_page' => ['int', 'doc'=>'int', 'pagenumber'=>'int', 'optlist'=>'string'],
    'PDFlib::pcos_get_number' => ['float', 'doc'=>'int', 'path'=>'string'],
    'PDFlib::pcos_get_stream' => ['string', 'doc'=>'int', 'optlist'=>'string', 'path'=>'string'],
    'PDFlib::pcos_get_string' => ['string', 'doc'=>'int', 'path'=>'string'],
    'PDFlib::place_image' => ['bool', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'],
    'PDFlib::place_pdi_page' => ['bool', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'sx'=>'float', 'sy'=>'float'],
    'PDFlib::process_pdi' => ['int', 'doc'=>'int', 'page'=>'int', 'optlist'=>'string'],
    'PDFlib::rect' => ['bool', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
    'PDFlib::restore' => ['bool', 'p'=>''],
    'PDFlib::resume_page' => ['bool', 'optlist'=>'string'],
    'PDFlib::rotate' => ['bool', 'phi'=>'float'],
    'PDFlib::save' => ['bool', 'p'=>''],
    'PDFlib::scale' => ['bool', 'sx'=>'float', 'sy'=>'float'],
    'PDFlib::set_border_color' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDFlib::set_border_dash' => ['bool', 'black'=>'float', 'white'=>'float'],
    'PDFlib::set_border_style' => ['bool', 'style'=>'string', 'width'=>'float'],
    'PDFlib::set_gstate' => ['bool', 'gstate'=>'int'],
    'PDFlib::set_info' => ['bool', 'key'=>'string', 'value'=>'string'],
    'PDFlib::set_layer_dependency' => ['bool', 'type'=>'string', 'optlist'=>'string'],
    'PDFlib::set_parameter' => ['bool', 'key'=>'string', 'value'=>'string'],
    'PDFlib::set_text_pos' => ['bool', 'x'=>'float', 'y'=>'float'],
    'PDFlib::set_value' => ['bool', 'key'=>'string', 'value'=>'float'],
    'PDFlib::setcolor' => ['bool', 'fstype'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'],
    'PDFlib::setdash' => ['bool', 'b'=>'float', 'w'=>'float'],
    'PDFlib::setdashpattern' => ['bool', 'optlist'=>'string'],
    'PDFlib::setflat' => ['bool', 'flatness'=>'float'],
    'PDFlib::setfont' => ['bool', 'font'=>'int', 'fontsize'=>'float'],
    'PDFlib::setgray' => ['bool', 'g'=>'float'],
    'PDFlib::setgray_fill' => ['bool', 'g'=>'float'],
    'PDFlib::setgray_stroke' => ['bool', 'g'=>'float'],
    'PDFlib::setlinecap' => ['bool', 'linecap'=>'int'],
    'PDFlib::setlinejoin' => ['bool', 'value'=>'int'],
    'PDFlib::setlinewidth' => ['bool', 'width'=>'float'],
    'PDFlib::setmatrix' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
    'PDFlib::setmiterlimit' => ['bool', 'miter'=>'float'],
    'PDFlib::setrgbcolor' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDFlib::setrgbcolor_fill' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDFlib::setrgbcolor_stroke' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'PDFlib::shading' => ['int', 'shtype'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'],
    'PDFlib::shading_pattern' => ['int', 'shading'=>'int', 'optlist'=>'string'],
    'PDFlib::shfill' => ['bool', 'shading'=>'int'],
    'PDFlib::show' => ['bool', 'text'=>'string'],
    'PDFlib::show_boxed' => ['int', 'text'=>'string', 'left'=>'float', 'top'=>'float', 'width'=>'float', 'height'=>'float', 'mode'=>'string', 'feature'=>'string'],
    'PDFlib::show_xy' => ['bool', 'text'=>'string', 'x'=>'float', 'y'=>'float'],
    'PDFlib::skew' => ['bool', 'alpha'=>'float', 'beta'=>'float'],
    'PDFlib::stringwidth' => ['float', 'text'=>'string', 'font'=>'int', 'fontsize'=>'float'],
    'PDFlib::stroke' => ['bool', 'p'=>''],
    'PDFlib::suspend_page' => ['bool', 'optlist'=>'string'],
    'PDFlib::translate' => ['bool', 'tx'=>'float', 'ty'=>'float'],
    'PDFlib::utf16_to_utf8' => ['string', 'utf16string'=>'string'],
    'PDFlib::utf32_to_utf16' => ['string', 'utf32string'=>'string', 'ordering'=>'string'],
    'PDFlib::utf8_to_utf16' => ['string', 'utf8string'=>'string', 'ordering'=>'string'],
    'PDO::__construct' => ['void', 'dsn'=>'string', 'username='=>'?string', 'passwd='=>'?string', 'options='=>'?array'],
    'PDO::__sleep' => ['list<string>'],
    'PDO::__wakeup' => ['void'],
    'PDO::beginTransaction' => ['bool'],
    'PDO::commit' => ['bool'],
    'PDO::cubrid_schema' => ['array', 'schema_type'=>'int', 'table_name='=>'string', 'col_name='=>'string'],
    'PDO::errorCode' => ['?string'],
    'PDO::errorInfo' => ['array{0: ?string, 1: ?int, 2: ?string, 3?: mixed, 4?: mixed}'],
    'PDO::exec' => ['int|false', 'query'=>'string'],
    'PDO::getAttribute' => ['mixed', 'attribute'=>'int'],
    'PDO::getAvailableDrivers' => ['array'],
    'PDO::inTransaction' => ['bool'],
    'PDO::lastInsertId' => ['string', 'name='=>'string|null'],
    'PDO::pgsqlCopyFromArray' => ['bool', 'table_name'=>'string', 'rows'=>'array', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
    'PDO::pgsqlCopyFromFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
    'PDO::pgsqlCopyToArray' => ['array', 'table_name'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
    'PDO::pgsqlCopyToFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
    'PDO::pgsqlGetNotify' => ['array{message:string,pid:int,payload?:string}|false', 'result_type='=>'PDO::FETCH_*', 'ms_timeout='=>'int'],
    'PDO::pgsqlGetPid' => ['int'],
    'PDO::pgsqlLOBCreate' => ['string'],
    'PDO::pgsqlLOBOpen' => ['resource', 'oid'=>'string', 'mode='=>'string'],
    'PDO::pgsqlLOBUnlink' => ['bool', 'oid'=>'string'],
    'PDO::prepare' => ['PDOStatement|false', 'statement'=>'string', 'options='=>'array'],
    'PDO::query' => ['PDOStatement|false', 'sql'=>'string'],
    'PDO::query\'1' => ['PDOStatement|false', 'sql'=>'string', 'fetch_column'=>'int', 'colno='=>'int'],
    'PDO::query\'2' => ['PDOStatement|false', 'sql'=>'string', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs'=>'array'],
    'PDO::query\'3' => ['PDOStatement|false', 'sql'=>'string', 'fetch_into'=>'int', 'object'=>'object'],
    'PDO::quote' => ['string|false', 'string'=>'string', 'paramtype='=>'int'],
    'PDO::rollBack' => ['bool'],
    'PDO::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>''],
    'PDO::sqliteCreateAggregate' => ['bool', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'],
    'PDO::sqliteCreateCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'],
    'PDO::sqliteCreateFunction' => ['bool', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'],
    'PDOException::getCode' => ['int|string'],
    'PDOException::getFile' => ['string'],
    'PDOException::getLine' => ['int'],
    'PDOException::getMessage' => ['string'],
    'PDOException::getPrevious' => ['?Throwable'],
    'PDOException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'PDOException::getTraceAsString' => ['string'],
    'PDOStatement::__sleep' => ['list<string>'],
    'PDOStatement::__wakeup' => ['void'],
    'PDOStatement::bindColumn' => ['bool', 'column'=>'mixed', '&rw_param'=>'mixed', 'type='=>'int', 'maxlen='=>'int', 'driverdata='=>'mixed'],
    'PDOStatement::bindParam' => ['bool', 'paramno'=>'mixed', '&rw_param'=>'mixed', 'type='=>'int', 'maxlen='=>'int', 'driverdata='=>'mixed'],
    'PDOStatement::bindValue' => ['bool', 'paramno'=>'mixed', 'param'=>'mixed', 'type='=>'int'],
    'PDOStatement::closeCursor' => ['bool'],
    'PDOStatement::columnCount' => ['int'],
    'PDOStatement::debugDumpParams' => ['void'],
    'PDOStatement::errorCode' => ['string'],
    'PDOStatement::errorInfo' => ['array{0: ?string, 1: ?int, 2: ?string, 3?: mixed, 4?: mixed}'],
    'PDOStatement::execute' => ['bool', 'bound_input_params='=>'?array'],
    'PDOStatement::fetch' => ['mixed', 'how='=>'int', 'orientation='=>'int', 'offset='=>'int'],
    'PDOStatement::fetchAll' => ['array|false', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'],
    'PDOStatement::fetchColumn' => ['string|int|float|bool|null', 'column_number='=>'int'],
    'PDOStatement::fetchObject' => ['object|false', 'class_name='=>'string', 'ctor_args='=>'array'],
    'PDOStatement::getAttribute' => ['mixed', 'attribute'=>'int'],
    'PDOStatement::getColumnMeta' => ['array|false', 'column'=>'int'],
    'PDOStatement::nextRowset' => ['bool'],
    'PDOStatement::rowCount' => ['int'],
    'PDOStatement::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>'mixed'],
    'PDOStatement::setFetchMode' => ['bool', 'mode'=>'int'],
    'PDOStatement::setFetchMode\'1' => ['bool', 'fetch_column'=>'int', 'colno'=>'int'],
    'PDOStatement::setFetchMode\'2' => ['bool', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs'=>'array'],
    'PDOStatement::setFetchMode\'3' => ['bool', 'fetch_into'=>'int', 'object'=>'object'],
    'ParentIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator'],
    'ParentIterator::accept' => ['bool'],
    'ParentIterator::getChildren' => ['?ParentIterator'],
    'ParentIterator::hasChildren' => ['bool'],
    'ParentIterator::next' => ['void'],
    'ParentIterator::rewind' => ['void'],
    'ParentIterator::valid' => ['bool'],
    'Parle\Lexer::advance' => ['void'],
    'Parle\Lexer::build' => ['void'],
    'Parle\Lexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'],
    'Parle\Lexer::consume' => ['void', 'data'=>'string'],
    'Parle\Lexer::dump' => ['void'],
    'Parle\Lexer::getToken' => ['Parle\Token'],
    'Parle\Lexer::insertMacro' => ['void', 'name'=>'string', 'regex'=>'string'],
    'Parle\Lexer::push' => ['void', 'regex'=>'string', 'id'=>'int'],
    'Parle\Lexer::reset' => ['void', 'pos'=>'int'],
    'Parle\Parser::advance' => ['void'],
    'Parle\Parser::build' => ['void'],
    'Parle\Parser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
    'Parle\Parser::dump' => ['void'],
    'Parle\Parser::errorInfo' => ['Parle\ErrorInfo'],
    'Parle\Parser::left' => ['void', 'token'=>'string'],
    'Parle\Parser::nonassoc' => ['void', 'token'=>'string'],
    'Parle\Parser::precedence' => ['void', 'token'=>'string'],
    'Parle\Parser::push' => ['int', 'name'=>'string', 'rule'=>'string'],
    'Parle\Parser::reset' => ['void', 'tokenId'=>'int'],
    'Parle\Parser::right' => ['void', 'token'=>'string'],
    'Parle\Parser::sigil' => ['string', 'idx'=>'array'],
    'Parle\Parser::token' => ['void', 'token'=>'string'],
    'Parle\Parser::tokenId' => ['int', 'token'=>'string'],
    'Parle\Parser::trace' => ['string'],
    'Parle\Parser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
    'Parle\RLexer::advance' => ['void'],
    'Parle\RLexer::build' => ['void'],
    'Parle\RLexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'],
    'Parle\RLexer::consume' => ['void', 'data'=>'string'],
    'Parle\RLexer::dump' => ['void'],
    'Parle\RLexer::getToken' => ['Parle\Token'],
    'Parle\RLexer::push' => ['void', 'state'=>'string', 'regex'=>'string', 'newState'=>'string'],
    'Parle\RLexer::pushState' => ['int', 'state'=>'string'],
    'Parle\RLexer::reset' => ['void', 'pos'=>'int'],
    'Parle\RParser::advance' => ['void'],
    'Parle\RParser::build' => ['void'],
    'Parle\RParser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
    'Parle\RParser::dump' => ['void'],
    'Parle\RParser::errorInfo' => ['Parle\ErrorInfo'],
    'Parle\RParser::left' => ['void', 'token'=>'string'],
    'Parle\RParser::nonassoc' => ['void', 'token'=>'string'],
    'Parle\RParser::precedence' => ['void', 'token'=>'string'],
    'Parle\RParser::push' => ['int', 'name'=>'string', 'rule'=>'string'],
    'Parle\RParser::reset' => ['void', 'tokenId'=>'int'],
    'Parle\RParser::right' => ['void', 'token'=>'string'],
    'Parle\RParser::sigil' => ['string', 'idx'=>'array'],
    'Parle\RParser::token' => ['void', 'token'=>'string'],
    'Parle\RParser::tokenId' => ['int', 'token'=>'string'],
    'Parle\RParser::trace' => ['string'],
    'Parle\RParser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
    'Parle\Stack::pop' => ['void'],
    'Parle\Stack::push' => ['void', 'item'=>'mixed'],
    'ParseError::__clone' => ['void'],
    'ParseError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'ParseError::__toString' => ['string'],
    'ParseError::getCode' => ['int'],
    'ParseError::getFile' => ['string'],
    'ParseError::getLine' => ['int'],
    'ParseError::getMessage' => ['string'],
    'ParseError::getPrevious' => ['?Throwable'],
    'ParseError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'ParseError::getTraceAsString' => ['string'],
    'Phar::__construct' => ['void', 'fname'=>'string', 'flags='=>'int', 'alias='=>'string'],
    'Phar::addEmptyDir' => ['void', 'dirname'=>'string'],
    'Phar::addFile' => ['void', 'file'=>'string', 'localname='=>'string'],
    'Phar::addFromString' => ['void', 'localname'=>'string', 'contents'=>'string'],
    'Phar::apiVersion' => ['string'],
    'Phar::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'],
    'Phar::buildFromIterator' => ['array', 'iter'=>'Iterator', 'base_directory='=>'string'],
    'Phar::canCompress' => ['bool', 'method='=>'int'],
    'Phar::canWrite' => ['bool'],
    'Phar::compress' => ['?Phar', 'compression'=>'int', 'extension='=>'string'],
    'Phar::compressAllFilesBZIP2' => ['bool'],
    'Phar::compressAllFilesGZ' => ['bool'],
    'Phar::compressFiles' => ['void', 'compression'=>'int'],
    'Phar::convertToData' => ['?PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
    'Phar::convertToExecutable' => ['?Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
    'Phar::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'],
    'Phar::count' => ['int'],
    'Phar::createDefaultStub' => ['string', 'indexfile='=>'string', 'webindexfile='=>'string'],
    'Phar::decompress' => ['?Phar', 'extension='=>'string'],
    'Phar::decompressFiles' => ['bool'],
    'Phar::delMetadata' => ['bool'],
    'Phar::delete' => ['bool', 'entry'=>'string'],
    'Phar::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'],
    'Phar::getAlias' => ['?string'],
    'Phar::getMetadata' => ['mixed'],
    'Phar::getModified' => ['bool'],
    'Phar::getPath' => ['string'],
    'Phar::getSignature' => ['array{hash:string, hash_type:string}'],
    'Phar::getStub' => ['string'],
    'Phar::getSupportedCompression' => ['array'],
    'Phar::getSupportedSignatures' => ['array'],
    'Phar::getVersion' => ['string'],
    'Phar::hasMetadata' => ['bool'],
    'Phar::interceptFileFuncs' => ['void'],
    'Phar::isBuffering' => ['bool'],
    'Phar::isCompressed' => ['int|false'],
    'Phar::isFileFormat' => ['bool', 'format'=>'int'],
    'Phar::isValidPharFilename' => ['bool', 'filename'=>'string', 'executable='=>'bool'],
    'Phar::isWritable' => ['bool'],
    'Phar::loadPhar' => ['bool', 'filename'=>'string', 'alias='=>'?string'],
    'Phar::mapPhar' => ['bool', 'alias='=>'string', 'dataoffset='=>'int'],
    'Phar::mount' => ['void', 'pharpath'=>'string', 'externalpath'=>'string'],
    'Phar::mungServer' => ['void', 'munglist'=>'array'],
    'Phar::offsetExists' => ['bool', 'offset'=>'string'],
    'Phar::offsetGet' => ['PharFileInfo', 'offset'=>'string'],
    'Phar::offsetSet' => ['void', 'offset'=>'string', 'value'=>'string'],
    'Phar::offsetUnset' => ['bool', 'offset'=>'string'],
    'Phar::running' => ['string', 'retphar='=>'bool'],
    'Phar::setAlias' => ['bool', 'alias'=>'string'],
    'Phar::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'],
    'Phar::setMetadata' => ['void', 'metadata'=>''],
    'Phar::setSignatureAlgorithm' => ['void', 'sigtype'=>'int', 'privatekey='=>'string'],
    'Phar::setStub' => ['bool', 'stub'=>'string', 'length='=>'int'],
    'Phar::startBuffering' => ['void'],
    'Phar::stopBuffering' => ['void'],
    'Phar::uncompressAllFiles' => ['bool'],
    'Phar::unlinkArchive' => ['bool', 'archive'=>'string'],
    'Phar::webPhar' => ['', 'alias='=>'string', 'index='=>'string', 'f404='=>'string', 'mimetypes='=>'array', 'rewrites='=>'array'],
    'PharData::__construct' => ['void', 'fname'=>'string', 'flags='=>'?int', 'alias='=>'?string', 'format='=>'int'],
    'PharData::addEmptyDir' => ['bool', 'dirname'=>'string'],
    'PharData::addFile' => ['void', 'file'=>'string', 'localname='=>'string'],
    'PharData::addFromString' => ['bool', 'localname'=>'string', 'contents'=>'string'],
    'PharData::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'],
    'PharData::buildFromIterator' => ['array', 'iter'=>'Iterator', 'base_directory='=>'string'],
    'PharData::compress' => ['?PharData', 'compression'=>'int', 'extension='=>'string'],
    'PharData::compressFiles' => ['void', 'compression'=>'int'],
    'PharData::convertToData' => ['?PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
    'PharData::convertToExecutable' => ['?Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
    'PharData::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'],
    'PharData::decompress' => ['?PharData', 'extension='=>'string'],
    'PharData::decompressFiles' => ['bool'],
    'PharData::delMetadata' => ['bool'],
    'PharData::delete' => ['bool', 'entry'=>'string'],
    'PharData::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'],
    'PharData::isWritable' => ['bool'],
    'PharData::offsetExists' => ['bool', 'offset'=>'string'],
    'PharData::offsetGet' => ['PharFileInfo', 'offset'=>'string'],
    'PharData::offsetSet' => ['void', 'offset'=>'string', 'value'=>'string'],
    'PharData::offsetUnset' => ['bool', 'offset'=>'string'],
    'PharData::setAlias' => ['bool', 'alias'=>'string'],
    'PharData::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'],
    'PharData::setStub' => ['bool', 'stub'=>'string', 'length='=>'int'],
    'PharFileInfo::__construct' => ['void', 'entry'=>'string'],
    'PharFileInfo::chmod' => ['void', 'permissions'=>'int'],
    'PharFileInfo::compress' => ['bool', 'compression'=>'int'],
    'PharFileInfo::decompress' => ['bool'],
    'PharFileInfo::delMetadata' => ['bool'],
    'PharFileInfo::getCRC32' => ['int'],
    'PharFileInfo::getCompressedSize' => ['int'],
    'PharFileInfo::getContent' => ['string'],
    'PharFileInfo::getMetadata' => ['mixed'],
    'PharFileInfo::getPharFlags' => ['int'],
    'PharFileInfo::hasMetadata' => ['bool'],
    'PharFileInfo::isCRCChecked' => ['bool'],
    'PharFileInfo::isCompressed' => ['bool', 'compression_type='=>'int'],
    'PharFileInfo::isCompressedBZIP2' => ['bool'],
    'PharFileInfo::isCompressedGZ' => ['bool'],
    'PharFileInfo::setCompressedBZIP2' => ['bool'],
    'PharFileInfo::setCompressedGZ' => ['bool'],
    'PharFileInfo::setMetadata' => ['void', 'metadata'=>'mixed'],
    'PharFileInfo::setUncompressed' => ['bool'],
    'Pool::__construct' => ['void', 'size'=>'int', 'class'=>'string', 'ctor='=>'array'],
    'Pool::collect' => ['int', 'collector='=>'Callable'],
    'Pool::resize' => ['void', 'size'=>'int'],
    'Pool::shutdown' => ['void'],
    'Pool::submit' => ['int', 'task'=>'Threaded'],
    'Pool::submitTo' => ['int', 'worker'=>'int', 'task'=>'Threaded'],
    'Postal\Expand::expand_address' => ['string[]', 'address'=>'string', 'options='=>'array<string, mixed>'],
    'Postal\Parser::parse_address' => ['array<string,string>', 'address'=>'string', 'options='=>'array<string, string>'],
    'QuickHashIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
    'QuickHashIntHash::add' => ['bool', 'key'=>'int', 'value='=>'int'],
    'QuickHashIntHash::delete' => ['bool', 'key'=>'int'],
    'QuickHashIntHash::exists' => ['bool', 'key'=>'int'],
    'QuickHashIntHash::get' => ['int', 'key'=>'int'],
    'QuickHashIntHash::getSize' => ['int'],
    'QuickHashIntHash::loadFromFile' => ['QuickHashIntHash', 'filename'=>'string', 'options='=>'int'],
    'QuickHashIntHash::loadFromString' => ['QuickHashIntHash', 'contents'=>'string', 'options='=>'int'],
    'QuickHashIntHash::saveToFile' => ['void', 'filename'=>'string'],
    'QuickHashIntHash::saveToString' => ['string'],
    'QuickHashIntHash::set' => ['bool', 'key'=>'int', 'value'=>'int'],
    'QuickHashIntHash::update' => ['bool', 'key'=>'int', 'value'=>'int'],
    'QuickHashIntSet::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
    'QuickHashIntSet::add' => ['bool', 'key'=>'int'],
    'QuickHashIntSet::delete' => ['bool', 'key'=>'int'],
    'QuickHashIntSet::exists' => ['bool', 'key'=>'int'],
    'QuickHashIntSet::getSize' => ['int'],
    'QuickHashIntSet::loadFromFile' => ['QuickHashIntSet', 'filename'=>'string', 'size='=>'int', 'options='=>'int'],
    'QuickHashIntSet::loadFromString' => ['QuickHashIntSet', 'contents'=>'string', 'size='=>'int', 'options='=>'int'],
    'QuickHashIntSet::saveToFile' => ['void', 'filename'=>'string'],
    'QuickHashIntSet::saveToString' => ['string'],
    'QuickHashIntStringHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
    'QuickHashIntStringHash::add' => ['bool', 'key'=>'int', 'value'=>'string'],
    'QuickHashIntStringHash::delete' => ['bool', 'key'=>'int'],
    'QuickHashIntStringHash::exists' => ['bool', 'key'=>'int'],
    'QuickHashIntStringHash::get' => ['mixed', 'key'=>'int'],
    'QuickHashIntStringHash::getSize' => ['int'],
    'QuickHashIntStringHash::loadFromFile' => ['QuickHashIntStringHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'],
    'QuickHashIntStringHash::loadFromString' => ['QuickHashIntStringHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'],
    'QuickHashIntStringHash::saveToFile' => ['void', 'filename'=>'string'],
    'QuickHashIntStringHash::saveToString' => ['string'],
    'QuickHashIntStringHash::set' => ['int', 'key'=>'int', 'value'=>'string'],
    'QuickHashIntStringHash::update' => ['bool', 'key'=>'int', 'value'=>'string'],
    'QuickHashStringIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
    'QuickHashStringIntHash::add' => ['bool', 'key'=>'string', 'value'=>'int'],
    'QuickHashStringIntHash::delete' => ['bool', 'key'=>'string'],
    'QuickHashStringIntHash::exists' => ['bool', 'key'=>'string'],
    'QuickHashStringIntHash::get' => ['mixed', 'key'=>'string'],
    'QuickHashStringIntHash::getSize' => ['int'],
    'QuickHashStringIntHash::loadFromFile' => ['QuickHashStringIntHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'],
    'QuickHashStringIntHash::loadFromString' => ['QuickHashStringIntHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'],
    'QuickHashStringIntHash::saveToFile' => ['void', 'filename'=>'string'],
    'QuickHashStringIntHash::saveToString' => ['string'],
    'QuickHashStringIntHash::set' => ['int', 'key'=>'string', 'value'=>'int'],
    'QuickHashStringIntHash::update' => ['bool', 'key'=>'string', 'value'=>'int'],
    'RRDCreator::__construct' => ['void', 'path'=>'string', 'starttime='=>'string', 'step='=>'int'],
    'RRDCreator::addArchive' => ['void', 'description'=>'string'],
    'RRDCreator::addDataSource' => ['void', 'description'=>'string'],
    'RRDCreator::save' => ['bool'],
    'RRDGraph::__construct' => ['void', 'path'=>'string'],
    'RRDGraph::save' => ['array|false'],
    'RRDGraph::saveVerbose' => ['array|false'],
    'RRDGraph::setOptions' => ['void', 'options'=>'array'],
    'RRDUpdater::__construct' => ['void', 'path'=>'string'],
    'RRDUpdater::update' => ['bool', 'values'=>'array', 'time='=>'string'],
    'RangeException::__clone' => ['void'],
    'RangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'RangeException::__toString' => ['string'],
    'RangeException::getCode' => ['int'],
    'RangeException::getFile' => ['string'],
    'RangeException::getLine' => ['int'],
    'RangeException::getMessage' => ['string'],
    'RangeException::getPrevious' => ['?Throwable'],
    'RangeException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'RangeException::getTraceAsString' => ['string'],
    'RarArchive::__toString' => ['string'],
    'RarArchive::close' => ['bool'],
    'RarArchive::getComment' => ['string|null'],
    'RarArchive::getEntries' => ['RarEntry[]|false'],
    'RarArchive::getEntry' => ['RarEntry|false', 'entryname'=>'string'],
    'RarArchive::isBroken' => ['bool'],
    'RarArchive::isSolid' => ['bool'],
    'RarArchive::open' => ['RarArchive|false', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'],
    'RarArchive::setAllowBroken' => ['bool', 'allow_broken'=>'bool'],
    'RarEntry::__toString' => ['string'],
    'RarEntry::extract' => ['bool', 'dir'=>'string', 'filepath='=>'string', 'password='=>'string', 'extended_data='=>'bool'],
    'RarEntry::getAttr' => ['int|false'],
    'RarEntry::getCrc' => ['string|false'],
    'RarEntry::getFileTime' => ['string|false'],
    'RarEntry::getHostOs' => ['int|false'],
    'RarEntry::getMethod' => ['int|false'],
    'RarEntry::getName' => ['string|false'],
    'RarEntry::getPackedSize' => ['int|false'],
    'RarEntry::getStream' => ['resource|false', 'password='=>'string'],
    'RarEntry::getUnpackedSize' => ['int|false'],
    'RarEntry::getVersion' => ['int|false'],
    'RarEntry::isDirectory' => ['bool'],
    'RarEntry::isEncrypted' => ['bool'],
    'RarException::getCode' => ['int'],
    'RarException::getFile' => ['string'],
    'RarException::getLine' => ['int'],
    'RarException::getMessage' => ['string'],
    'RarException::getPrevious' => ['Exception|Throwable'],
    'RarException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'RarException::getTraceAsString' => ['string'],
    'RarException::isUsingExceptions' => ['bool'],
    'RarException::setUsingExceptions' => ['RarEntry', 'using_exceptions'=>'bool'],
    'RdKafka::addBrokers' => ['int', 'broker_list'=>'string'],
    'RdKafka::flush' => ['int', 'timeout_ms'=>'int'],
    'RdKafka::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\Topic', 'timeout_ms'=>'int'],
    'RdKafka::getOutQLen' => ['int'],
    'RdKafka::newQueue' => ['RdKafka\Queue'],
    'RdKafka::newTopic' => ['RdKafka\Topic', 'topic_name'=>'string', 'topic_conf='=>'?RdKafka\TopicConf'],
    'RdKafka::poll' => ['void', 'timeout_ms'=>'int'],
    'RdKafka::setLogLevel' => ['void', 'level'=>'int'],
    'RdKafka\Conf::dump' => ['array<string, string>'],
    'RdKafka\Conf::set' => ['void', 'name'=>'string', 'value'=>'string'],
    'RdKafka\Conf::setDefaultTopicConf' => ['void', 'topic_conf'=>'RdKafka\TopicConf'],
    'RdKafka\Conf::setDrMsgCb' => ['void', 'callback'=>'callable'],
    'RdKafka\Conf::setErrorCb' => ['void', 'callback'=>'callable'],
    'RdKafka\Conf::setRebalanceCb' => ['void', 'callback'=>'callable'],
    'RdKafka\Conf::setStatsCb' => ['void', 'callback'=>'callable'],
    'RdKafka\Consumer::__construct' => ['void', 'conf='=>'?RdKafka\Conf'],
    'RdKafka\Consumer::addBrokers' => ['int', 'broker_list'=>'string'],
    'RdKafka\Consumer::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\Topic', 'timeout_ms'=>'int'],
    'RdKafka\Consumer::getOutQLen' => ['int'],
    'RdKafka\Consumer::newQueue' => ['RdKafka\Queue'],
    'RdKafka\Consumer::newTopic' => ['RdKafka\ConsumerTopic', 'topic_name'=>'string', 'topic_conf='=>'?RdKafka\TopicConf'],
    'RdKafka\Consumer::poll' => ['void', 'timeout_ms'=>'int'],
    'RdKafka\Consumer::setLogLevel' => ['void', 'level'=>'int'],
    'RdKafka\ConsumerTopic::__construct' => ['void'],
    'RdKafka\ConsumerTopic::consume' => ['RdKafka\Message', 'partition'=>'int', 'timeout_ms'=>'int'],
    'RdKafka\ConsumerTopic::consumeQueueStart' => ['void', 'partition'=>'int', 'offset'=>'int', 'queue'=>'RdKafka\Queue'],
    'RdKafka\ConsumerTopic::consumeStart' => ['void', 'partition'=>'int', 'offset'=>'int'],
    'RdKafka\ConsumerTopic::consumeStop' => ['void', 'partition'=>'int'],
    'RdKafka\ConsumerTopic::getName' => ['string'],
    'RdKafka\ConsumerTopic::offsetStore' => ['void', 'partition'=>'int', 'offset'=>'int'],
    'RdKafka\KafkaConsumer::__construct' => ['void', 'conf'=>'RdKafka\Conf'],
    'RdKafka\KafkaConsumer::assign' => ['void', 'topic_partitions='=>'RdKafka\TopicPartition[]|null'],
    'RdKafka\KafkaConsumer::commit' => ['void', 'message_or_offsets='=>'RdKafka\Message|RdKafka\TopicPartition[]|null'],
    'RdKafka\KafkaConsumer::commitAsync' => ['void', 'message_or_offsets='=>'RdKafka\Message|RdKafka\TopicPartition[]|null'],
    'RdKafka\KafkaConsumer::consume' => ['RdKafka\Message', 'timeout_ms'=>'int'],
    'RdKafka\KafkaConsumer::getAssignment' => ['RdKafka\TopicPartition[]'],
    'RdKafka\KafkaConsumer::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\KafkaConsumerTopic', 'timeout_ms'=>'int'],
    'RdKafka\KafkaConsumer::getSubscription' => ['array'],
    'RdKafka\KafkaConsumer::subscribe' => ['void', 'topics'=>'array'],
    'RdKafka\KafkaConsumer::unsubscribe' => ['void'],
    'RdKafka\KafkaConsumerTopic::getName' => ['string'],
    'RdKafka\KafkaConsumerTopic::offsetStore' => ['void', 'partition'=>'int', 'offset'=>'int'],
    'RdKafka\Message::errstr' => ['string'],
    'RdKafka\Metadata::getBrokers' => ['RdKafka\Metadata\Collection'],
    'RdKafka\Metadata::getOrigBrokerId' => ['int'],
    'RdKafka\Metadata::getOrigBrokerName' => ['string'],
    'RdKafka\Metadata::getTopics' => ['RdKafka\Metadata\Collection|RdKafka\Metadata\Topic[]'],
    'RdKafka\Metadata\Collection::__construct' => ['void'],
    'RdKafka\Metadata\Collection::count' => ['int'],
    'RdKafka\Metadata\Collection::current' => ['mixed'],
    'RdKafka\Metadata\Collection::key' => ['mixed'],
    'RdKafka\Metadata\Collection::next' => ['void'],
    'RdKafka\Metadata\Collection::rewind' => ['void'],
    'RdKafka\Metadata\Collection::valid' => ['bool'],
    'RdKafka\Metadata\Partition::getErr' => ['mixed'],
    'RdKafka\Metadata\Partition::getId' => ['int'],
    'RdKafka\Metadata\Partition::getIsrs' => ['mixed'],
    'RdKafka\Metadata\Partition::getLeader' => ['mixed'],
    'RdKafka\Metadata\Partition::getReplicas' => ['mixed'],
    'RdKafka\Metadata\Topic::getErr' => ['mixed'],
    'RdKafka\Metadata\Topic::getPartitions' => ['RdKafka\Metadata\Partition[]'],
    'RdKafka\Metadata\Topic::getTopic' => ['string'],
    'RdKafka\Producer::__construct' => ['void', 'conf='=>'?RdKafka\Conf'],
    'RdKafka\Producer::addBrokers' => ['int', 'broker_list'=>'string'],
    'RdKafka\Producer::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\Topic', 'timeout_ms'=>'int'],
    'RdKafka\Producer::getOutQLen' => ['int'],
    'RdKafka\Producer::newQueue' => ['RdKafka\Queue'],
    'RdKafka\Producer::newTopic' => ['RdKafka\ProducerTopic', 'topic_name'=>'string', 'topic_conf='=>'?RdKafka\TopicConf'],
    'RdKafka\Producer::poll' => ['void', 'timeout_ms'=>'int'],
    'RdKafka\Producer::setLogLevel' => ['void', 'level'=>'int'],
    'RdKafka\ProducerTopic::__construct' => ['void'],
    'RdKafka\ProducerTopic::getName' => ['string'],
    'RdKafka\ProducerTopic::produce' => ['void', 'partition'=>'int', 'msgflags'=>'int', 'payload'=>'string', 'key='=>'?string'],
    'RdKafka\ProducerTopic::producev' => ['void', 'partition'=>'int', 'msgflags'=>'int', 'payload'=>'string', 'key='=>'?string', 'headers='=>'?array<string, string>', 'timestamp_ms='=>'?int', 'opaque='=>'?string'],
    'RdKafka\Queue::__construct' => ['void'],
    'RdKafka\Queue::consume' => ['?RdKafka\Message', 'timeout_ms'=>'string'],
    'RdKafka\Topic::getName' => ['string'],
    'RdKafka\TopicConf::dump' => ['array<string, string>'],
    'RdKafka\TopicConf::set' => ['void', 'name'=>'string', 'value'=>'string'],
    'RdKafka\TopicConf::setPartitioner' => ['void', 'partitioner'=>'int'],
    'RdKafka\TopicPartition::__construct' => ['void', 'topic'=>'string', 'partition'=>'int', 'offset='=>'int'],
    'RdKafka\TopicPartition::getOffset' => ['int'],
    'RdKafka\TopicPartition::getPartition' => ['int'],
    'RdKafka\TopicPartition::getTopic' => ['string'],
    'RdKafka\TopicPartition::setOffset' => ['void', 'offset'=>'string'],
    'RdKafka\TopicPartition::setPartition' => ['void', 'partition'=>'string'],
    'RdKafka\TopicPartition::setTopic' => ['void', 'topic_name'=>'string'],
    'RecursiveArrayIterator::__construct' => ['void', 'array='=>'array|object', 'flags='=>'int'],
    'RecursiveArrayIterator::append' => ['void', 'value'=>'mixed'],
    'RecursiveArrayIterator::asort' => ['void'],
    'RecursiveArrayIterator::count' => ['int'],
    'RecursiveArrayIterator::current' => ['mixed'],
    'RecursiveArrayIterator::getArrayCopy' => ['array'],
    'RecursiveArrayIterator::getChildren' => ['?RecursiveArrayIterator'],
    'RecursiveArrayIterator::getFlags' => ['int'],
    'RecursiveArrayIterator::hasChildren' => ['bool'],
    'RecursiveArrayIterator::key' => ['string|int|null'],
    'RecursiveArrayIterator::ksort' => ['void'],
    'RecursiveArrayIterator::natcasesort' => ['true'],
    'RecursiveArrayIterator::natsort' => ['true'],
    'RecursiveArrayIterator::next' => ['void'],
    'RecursiveArrayIterator::offsetExists' => ['void', 'index'=>'string'],
    'RecursiveArrayIterator::offsetGet' => ['mixed', 'index'=>'string'],
    'RecursiveArrayIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'string'],
    'RecursiveArrayIterator::offsetUnset' => ['void', 'index'=>'string'],
    'RecursiveArrayIterator::rewind' => ['void'],
    'RecursiveArrayIterator::seek' => ['void', 'position'=>'int'],
    'RecursiveArrayIterator::serialize' => ['string'],
    'RecursiveArrayIterator::setFlags' => ['void', 'flags'=>'string'],
    'RecursiveArrayIterator::uasort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
    'RecursiveArrayIterator::uksort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
    'RecursiveArrayIterator::unserialize' => ['string', 'serialized'=>'string'],
    'RecursiveArrayIterator::valid' => ['bool'],
    'RecursiveCachingIterator::__construct' => ['void', 'it'=>'Iterator', 'flags='=>'int'],
    'RecursiveCachingIterator::__toString' => ['string'],
    'RecursiveCachingIterator::count' => ['int'],
    'RecursiveCachingIterator::current' => ['void'],
    'RecursiveCachingIterator::getCache' => ['array'],
    'RecursiveCachingIterator::getChildren' => ['?RecursiveCachingIterator'],
    'RecursiveCachingIterator::getFlags' => ['int'],
    'RecursiveCachingIterator::getInnerIterator' => ['Iterator'],
    'RecursiveCachingIterator::hasChildren' => ['bool'],
    'RecursiveCachingIterator::hasNext' => ['bool'],
    'RecursiveCachingIterator::key' => ['bool|float|int|string'],
    'RecursiveCachingIterator::next' => ['void'],
    'RecursiveCachingIterator::offsetExists' => ['bool', 'index'=>'string'],
    'RecursiveCachingIterator::offsetGet' => ['string', 'index'=>'string'],
    'RecursiveCachingIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'string'],
    'RecursiveCachingIterator::offsetUnset' => ['void', 'index'=>'string'],
    'RecursiveCachingIterator::rewind' => ['void'],
    'RecursiveCachingIterator::setFlags' => ['void', 'flags'=>'int'],
    'RecursiveCachingIterator::valid' => ['bool'],
    'RecursiveCallbackFilterIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator', 'func'=>'callable'],
    'RecursiveCallbackFilterIterator::accept' => ['bool'],
    'RecursiveCallbackFilterIterator::current' => ['mixed'],
    'RecursiveCallbackFilterIterator::getChildren' => ['RecursiveCallbackFilterIterator'],
    'RecursiveCallbackFilterIterator::getInnerIterator' => ['Iterator'],
    'RecursiveCallbackFilterIterator::hasChildren' => ['bool'],
    'RecursiveCallbackFilterIterator::key' => ['bool|float|int|string'],
    'RecursiveCallbackFilterIterator::next' => ['void'],
    'RecursiveCallbackFilterIterator::rewind' => ['void'],
    'RecursiveCallbackFilterIterator::valid' => ['bool'],
    'RecursiveDirectoryIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'],
    'RecursiveDirectoryIterator::__toString' => ['string'],
    'RecursiveDirectoryIterator::current' => ['string|SplFileInfo|FilesystemIterator'],
    'RecursiveDirectoryIterator::getATime' => ['int'],
    'RecursiveDirectoryIterator::getBasename' => ['string', 'suffix='=>'string'],
    'RecursiveDirectoryIterator::getCTime' => ['int'],
    'RecursiveDirectoryIterator::getChildren' => ['RecursiveDirectoryIterator'],
    'RecursiveDirectoryIterator::getExtension' => ['string'],
    'RecursiveDirectoryIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'RecursiveDirectoryIterator::getFilename' => ['string'],
    'RecursiveDirectoryIterator::getFlags' => ['int'],
    'RecursiveDirectoryIterator::getGroup' => ['int'],
    'RecursiveDirectoryIterator::getInode' => ['int'],
    'RecursiveDirectoryIterator::getLinkTarget' => ['string'],
    'RecursiveDirectoryIterator::getMTime' => ['int'],
    'RecursiveDirectoryIterator::getOwner' => ['int'],
    'RecursiveDirectoryIterator::getPath' => ['string'],
    'RecursiveDirectoryIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'RecursiveDirectoryIterator::getPathname' => ['string'],
    'RecursiveDirectoryIterator::getPerms' => ['int'],
    'RecursiveDirectoryIterator::getRealPath' => ['string'],
    'RecursiveDirectoryIterator::getSize' => ['int'],
    'RecursiveDirectoryIterator::getSubPath' => ['string'],
    'RecursiveDirectoryIterator::getSubPathname' => ['string'],
    'RecursiveDirectoryIterator::getType' => ['string'],
    'RecursiveDirectoryIterator::hasChildren' => ['bool', 'allow_links='=>'bool'],
    'RecursiveDirectoryIterator::isDir' => ['bool'],
    'RecursiveDirectoryIterator::isDot' => ['bool'],
    'RecursiveDirectoryIterator::isExecutable' => ['bool'],
    'RecursiveDirectoryIterator::isFile' => ['bool'],
    'RecursiveDirectoryIterator::isLink' => ['bool'],
    'RecursiveDirectoryIterator::isReadable' => ['bool'],
    'RecursiveDirectoryIterator::isWritable' => ['bool'],
    'RecursiveDirectoryIterator::key' => ['string'],
    'RecursiveDirectoryIterator::next' => ['void'],
    'RecursiveDirectoryIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
    'RecursiveDirectoryIterator::rewind' => ['void'],
    'RecursiveDirectoryIterator::seek' => ['void', 'position'=>'int'],
    'RecursiveDirectoryIterator::setFileClass' => ['void', 'class_name='=>'string'],
    'RecursiveDirectoryIterator::setFlags' => ['void', 'flags='=>'int'],
    'RecursiveDirectoryIterator::setInfoClass' => ['void', 'class_name='=>'string'],
    'RecursiveDirectoryIterator::valid' => ['bool'],
    'RecursiveFilterIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator'],
    'RecursiveFilterIterator::accept' => ['bool'],
    'RecursiveFilterIterator::current' => ['mixed'],
    'RecursiveFilterIterator::getChildren' => ['?RecursiveFilterIterator'],
    'RecursiveFilterIterator::getInnerIterator' => ['Iterator'],
    'RecursiveFilterIterator::hasChildren' => ['bool'],
    'RecursiveFilterIterator::key' => ['mixed'],
    'RecursiveFilterIterator::next' => ['void'],
    'RecursiveFilterIterator::rewind' => ['void'],
    'RecursiveFilterIterator::valid' => ['bool'],
    'RecursiveIterator::__construct' => ['void'],
    'RecursiveIterator::current' => ['mixed'],
    'RecursiveIterator::getChildren' => ['?RecursiveIterator'],
    'RecursiveIterator::hasChildren' => ['bool'],
    'RecursiveIterator::key' => ['int|string'],
    'RecursiveIterator::next' => ['void'],
    'RecursiveIterator::rewind' => ['void'],
    'RecursiveIterator::valid' => ['bool'],
    'RecursiveIteratorIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator|IteratorAggregate', 'mode='=>'int', 'flags='=>'int'],
    'RecursiveIteratorIterator::beginChildren' => ['void'],
    'RecursiveIteratorIterator::beginIteration' => ['void'],
    'RecursiveIteratorIterator::callGetChildren' => ['?RecursiveIterator'],
    'RecursiveIteratorIterator::callHasChildren' => ['bool'],
    'RecursiveIteratorIterator::current' => ['mixed'],
    'RecursiveIteratorIterator::endChildren' => ['void'],
    'RecursiveIteratorIterator::endIteration' => ['void'],
    'RecursiveIteratorIterator::getDepth' => ['int'],
    'RecursiveIteratorIterator::getInnerIterator' => ['RecursiveIterator'],
    'RecursiveIteratorIterator::getMaxDepth' => ['int|false'],
    'RecursiveIteratorIterator::getSubIterator' => ['?RecursiveIterator', 'level='=>'int'],
    'RecursiveIteratorIterator::key' => ['mixed'],
    'RecursiveIteratorIterator::next' => ['void'],
    'RecursiveIteratorIterator::nextElement' => ['void'],
    'RecursiveIteratorIterator::rewind' => ['void'],
    'RecursiveIteratorIterator::setMaxDepth' => ['void', 'max_depth='=>'int'],
    'RecursiveIteratorIterator::valid' => ['bool'],
    'RecursiveRegexIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator', 'regex'=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'],
    'RecursiveRegexIterator::accept' => ['bool'],
    'RecursiveRegexIterator::current' => ['mixed'],
    'RecursiveRegexIterator::getChildren' => ['RecursiveRegexIterator'],
    'RecursiveRegexIterator::getFlags' => ['int'],
    'RecursiveRegexIterator::getInnerIterator' => ['Iterator'],
    'RecursiveRegexIterator::getMode' => ['int'],
    'RecursiveRegexIterator::getPregFlags' => ['int'],
    'RecursiveRegexIterator::getRegex' => ['string'],
    'RecursiveRegexIterator::hasChildren' => ['bool'],
    'RecursiveRegexIterator::key' => ['mixed'],
    'RecursiveRegexIterator::next' => ['void'],
    'RecursiveRegexIterator::rewind' => ['void'],
    'RecursiveRegexIterator::setFlags' => ['void', 'new_flags'=>'int'],
    'RecursiveRegexIterator::setMode' => ['void', 'new_mode'=>'int'],
    'RecursiveRegexIterator::setPregFlags' => ['void', 'new_flags'=>'int'],
    'RecursiveRegexIterator::valid' => ['bool'],
    'RecursiveTreeIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator|IteratorAggregate', 'flags='=>'int', 'cit_flags='=>'int', 'mode'=>'int'],
    'RecursiveTreeIterator::beginChildren' => ['void'],
    'RecursiveTreeIterator::beginIteration' => ['void'],
    'RecursiveTreeIterator::callGetChildren' => ['?RecursiveIterator'],
    'RecursiveTreeIterator::callHasChildren' => ['bool'],
    'RecursiveTreeIterator::current' => ['string'],
    'RecursiveTreeIterator::endChildren' => ['void'],
    'RecursiveTreeIterator::endIteration' => ['void'],
    'RecursiveTreeIterator::getDepth' => ['int'],
    'RecursiveTreeIterator::getEntry' => ['string'],
    'RecursiveTreeIterator::getInnerIterator' => ['RecursiveIterator'],
    'RecursiveTreeIterator::getMaxDepth' => ['false|int'],
    'RecursiveTreeIterator::getPostfix' => ['string'],
    'RecursiveTreeIterator::getPrefix' => ['string'],
    'RecursiveTreeIterator::getSubIterator' => ['?RecursiveIterator', 'level='=>'int'],
    'RecursiveTreeIterator::key' => ['string'],
    'RecursiveTreeIterator::next' => ['void'],
    'RecursiveTreeIterator::nextElement' => ['void'],
    'RecursiveTreeIterator::rewind' => ['void'],
    'RecursiveTreeIterator::setMaxDepth' => ['void', 'max_depth='=>'int'],
    'RecursiveTreeIterator::setPostfix' => ['void', 'prefix'=>'string'],
    'RecursiveTreeIterator::setPrefixPart' => ['void', 'part'=>'int', 'prefix'=>'string'],
    'RecursiveTreeIterator::valid' => ['bool'],
    'Redis::__construct' => ['void'],
    'Redis::__destruct' => ['void'],
    'Redis::_prefix' => ['string', 'value'=>'mixed'],
    'Redis::_serialize' => ['mixed', 'value'=>'mixed'],
    'Redis::_unserialize' => ['mixed', 'value'=>'string'],
    'Redis::append' => ['int', 'key'=>'string', 'value'=>'string'],
    'Redis::auth' => ['bool', 'password'=>'string'],
    'Redis::bgRewriteAOF' => ['bool'],
    'Redis::bgSave' => ['bool'],
    'Redis::bitCount' => ['int', 'key'=>'string'],
    'Redis::bitOp' => ['int', 'operation'=>'string', 'ret_key'=>'string', 'key'=>'string', '...other_keys='=>'string'],
    'Redis::bitpos' => ['int', 'key'=>'string', 'bit'=>'int', 'start='=>'int', 'end='=>'int'],
    'Redis::blPop' => ['array', 'keys'=>'string[]', 'timeout'=>'int'],
    'Redis::blPop\'1' => ['array', 'key'=>'string', 'timeout_or_key'=>'int|string', '...extra_args'=>'int|string'],
    'Redis::brPop' => ['array', 'keys'=>'string[]', 'timeout'=>'int'],
    'Redis::brPop\'1' => ['array', 'key'=>'string', 'timeout_or_key'=>'int|string', '...extra_args'=>'int|string'],
    'Redis::brpoplpush' => ['string|false', 'srcKey'=>'string', 'dstKey'=>'string', 'timeout'=>'int'],
    'Redis::clearLastError' => ['bool'],
    'Redis::client' => ['mixed', 'command'=>'string', 'arg='=>'string'],
    'Redis::close' => ['bool'],
    'Redis::command' => ['', '...args'=>''],
    'Redis::config' => ['string', 'operation'=>'string', 'key'=>'string', 'value='=>'string'],
    'Redis::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'reserved='=>'null', 'retry_interval='=>'?int', 'read_timeout='=>'float'],
    'Redis::dbSize' => ['int'],
    'Redis::debug' => ['', 'key'=>''],
    'Redis::decr' => ['int', 'key'=>'string'],
    'Redis::decrBy' => ['int', 'key'=>'string', 'value'=>'int'],
    'Redis::decrByFloat' => ['float', 'key'=>'string', 'value'=>'float'],
    'Redis::del' => ['int', 'key'=>'string', '...args'=>'string'],
    'Redis::del\'1' => ['int', 'key'=>'string[]'],
    'Redis::delete' => ['int', 'key'=>'string', '...args'=>'string'],
    'Redis::delete\'1' => ['int', 'key'=>'string[]'],
    'Redis::discard' => [''],
    'Redis::dump' => ['string|false', 'key'=>'string'],
    'Redis::echo' => ['string', 'message'=>'string'],
    'Redis::eval' => ['mixed', 'script'=>'', 'args='=>'', 'numKeys='=>''],
    'Redis::evalSha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'],
    'Redis::evaluate' => ['mixed', 'script'=>'string', 'args='=>'array', 'numKeys='=>'int'],
    'Redis::evaluateSha' => ['', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'],
    'Redis::exec' => ['array'],
    'Redis::exists' => ['int', 'keys'=>'string|string[]'],
    'Redis::exists\'1' => ['int', '...keys'=>'string'],
    'Redis::expire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
    'Redis::expireAt' => ['bool', 'key'=>'string', 'expiry'=>'int'],
    'Redis::flushAll' => ['bool', 'async='=>'bool'],
    'Redis::flushDb' => ['bool', 'async='=>'bool'],
    'Redis::geoAdd' => ['int', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'member'=>'string', '...other_triples='=>'string|int|float'],
    'Redis::geoDist' => ['float', 'key'=>'string', 'member1'=>'string', 'member2'=>'string', 'unit='=>'string'],
    'Redis::geoHash' => ['array<int,string>', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
    'Redis::geoPos' => ['array<int,array{0:string,1:string}>', 'key'=>'string', 'member'=>'string', '...members='=>'string'],
    'Redis::geoRadius' => ['array<int,mixed>|int', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'radius'=>'float', 'unit'=>'float', 'options='=>'array<string,mixed>'],
    'Redis::geoRadiusByMember' => ['array<int,mixed>|int', 'key'=>'string', 'member'=>'string', 'radius'=>'float', 'units'=>'string', 'options='=>'array<string,mixed>'],
    'Redis::get' => ['string|false', 'key'=>'string'],
    'Redis::getAuth' => ['string|false|null'],
    'Redis::getBit' => ['int', 'key'=>'string', 'offset'=>'int'],
    'Redis::getDBNum' => ['int|false'],
    'Redis::getHost' => ['string|false'],
    'Redis::getKeys' => ['array<int,string>', 'pattern'=>'string'],
    'Redis::getLastError' => ['?string'],
    'Redis::getMode' => ['int'],
    'Redis::getMultiple' => ['array', 'keys'=>'string[]'],
    'Redis::getOption' => ['int', 'name'=>'int'],
    'Redis::getPersistentID' => ['string|false|null'],
    'Redis::getPort' => ['int|false'],
    'Redis::getRange' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'Redis::getReadTimeout' => ['float|false'],
    'Redis::getSet' => ['string', 'key'=>'string', 'string'=>'string'],
    'Redis::getTimeout' => ['float|false'],
    'Redis::hDel' => ['int|false', 'key'=>'string', 'hashKey1'=>'string', '...otherHashKeys='=>'string'],
    'Redis::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'],
    'Redis::hGet' => ['string|false', 'key'=>'string', 'hashKey'=>'string'],
    'Redis::hGetAll' => ['array', 'key'=>'string'],
    'Redis::hIncrBy' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'int'],
    'Redis::hIncrByFloat' => ['float', 'key'=>'string', 'field'=>'string', 'increment'=>'float'],
    'Redis::hKeys' => ['array', 'key'=>'string'],
    'Redis::hLen' => ['int|false', 'key'=>'string'],
    'Redis::hMGet' => ['array', 'key'=>'string', 'hashKeys'=>'array'],
    'Redis::hMSet' => ['bool', 'key'=>'string', 'hashKeys'=>'array'],
    'Redis::hScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
    'Redis::hSet' => ['int|false', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
    'Redis::hSetNx' => ['bool', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
    'Redis::hStrLen' => ['', 'key'=>'', 'member'=>''],
    'Redis::hVals' => ['array', 'key'=>'string'],
    'Redis::incr' => ['int', 'key'=>'string'],
    'Redis::incrBy' => ['int', 'key'=>'string', 'value'=>'int'],
    'Redis::incrByFloat' => ['float', 'key'=>'string', 'value'=>'float'],
    'Redis::info' => ['array', 'option='=>'string'],
    'Redis::isConnected' => ['bool'],
    'Redis::keys' => ['array<int,string>', 'pattern'=>'string'],
    'Redis::lGet' => ['string', 'key'=>'string', 'index'=>'int'],
    'Redis::lGetRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'Redis::lIndex' => ['string|false', 'key'=>'string', 'index'=>'int'],
    'Redis::lInsert' => ['int', 'key'=>'string', 'position'=>'int', 'pivot'=>'string', 'value'=>'string'],
    'Redis::lLen' => ['int|false', 'key'=>'string'],
    'Redis::lPop' => ['string|false', 'key'=>'string'],
    'Redis::lPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
    'Redis::lPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
    'Redis::lRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'Redis::lRem' => ['int|false', 'key'=>'string', 'value'=>'string', 'count'=>'int'],
    'Redis::lRemove' => ['int', 'key'=>'string', 'value'=>'string', 'count'=>'int'],
    'Redis::lSet' => ['bool', 'key'=>'string', 'index'=>'int', 'value'=>'string'],
    'Redis::lSize' => ['int', 'key'=>'string'],
    'Redis::lTrim' => ['array|false', 'key'=>'string', 'start'=>'int', 'stop'=>'int'],
    'Redis::lastSave' => ['int'],
    'Redis::listTrim' => ['', 'key'=>'string', 'start'=>'int', 'stop'=>'int'],
    'Redis::mGet' => ['array', 'keys'=>'string[]'],
    'Redis::mSet' => ['bool', 'pairs'=>'array'],
    'Redis::mSetNx' => ['bool', 'pairs'=>'array'],
    'Redis::migrate' => ['bool', 'host'=>'string', 'port'=>'int', 'key'=>'string|string[]', 'db'=>'int', 'timeout'=>'int', 'copy='=>'bool', 'replace='=>'bool'],
    'Redis::move' => ['bool', 'key'=>'string', 'dbindex'=>'int'],
    'Redis::multi' => ['Redis', 'mode='=>'int'],
    'Redis::object' => ['string|long|false', 'info'=>'string', 'key'=>'string'],
    'Redis::open' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'reserved='=>'null', 'retry_interval='=>'?int', 'read_timeout='=>'float'],
    'Redis::pExpire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
    'Redis::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'string', 'retry_interval='=>'?int'],
    'Redis::persist' => ['bool', 'key'=>'string'],
    'Redis::pexpireAt' => ['bool', 'key'=>'string', 'expiry'=>'int'],
    'Redis::pfAdd' => ['bool', 'key'=>'string', 'elements'=>'array'],
    'Redis::pfCount' => ['int', 'key'=>'array|string'],
    'Redis::pfMerge' => ['bool', 'destkey'=>'string', 'sourcekeys'=>'array'],
    'Redis::ping' => ['string'],
    'Redis::pipeline' => ['Redis'],
    'Redis::popen' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'string', 'retry_interval='=>'?int'],
    'Redis::psetex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
    'Redis::psubscribe' => ['', 'patterns'=>'array', 'callback'=>'array|string'],
    'Redis::pttl' => ['int|false', 'key'=>'string'],
    'Redis::publish' => ['int', 'channel'=>'string', 'message'=>'string'],
    'Redis::pubsub' => ['array|int', 'keyword'=>'string', 'argument='=>'array|string'],
    'Redis::punsubscribe' => ['', 'pattern'=>'string', '...other_patterns='=>'string'],
    'Redis::rPop' => ['string|false', 'key'=>'string'],
    'Redis::rPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
    'Redis::rPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
    'Redis::randomKey' => ['string'],
    'Redis::rawCommand' => ['mixed', 'command'=>'string', '...arguments='=>'mixed'],
    'Redis::rename' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'],
    'Redis::renameKey' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'],
    'Redis::renameNx' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'],
    'Redis::resetStat' => ['bool'],
    'Redis::restore' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
    'Redis::role' => ['array', 'nodeParams'=>'string|array{0:string,1:int}'],
    'Redis::rpoplpush' => ['string', 'srcKey'=>'string', 'dstKey'=>'string'],
    'Redis::sAdd' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
    'Redis::sAddArray' => ['bool', 'key'=>'string', 'values'=>'array'],
    'Redis::sCard' => ['int', 'key'=>'string'],
    'Redis::sContains' => ['', 'key'=>'string', 'value'=>'string'],
    'Redis::sDiff' => ['array', 'key1'=>'string', '...other_keys='=>'string'],
    'Redis::sDiffStore' => ['int|false', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
    'Redis::sGetMembers' => ['', 'key'=>'string'],
    'Redis::sInter' => ['array|false', 'key'=>'string', '...other_keys='=>'string'],
    'Redis::sInterStore' => ['int|false', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
    'Redis::sIsMember' => ['bool', 'key'=>'string', 'value'=>'string'],
    'Redis::sMembers' => ['array', 'key'=>'string'],
    'Redis::sMove' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string', 'member'=>'string'],
    'Redis::sPop' => ['string|false', 'key'=>'string'],
    'Redis::sRandMember' => ['array|string|false', 'key'=>'string', 'count='=>'int'],
    'Redis::sRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
    'Redis::sRemove' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
    'Redis::sScan' => ['array|bool', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
    'Redis::sSize' => ['int', 'key'=>'string'],
    'Redis::sUnion' => ['array', 'key'=>'string', '...other_keys='=>'string'],
    'Redis::sUnionStore' => ['int', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
    'Redis::save' => ['bool'],
    'Redis::scan' => ['array<int,string>|false', '&rw_iterator'=>'?int', 'pattern='=>'?string', 'count='=>'?int'],
    'Redis::script' => ['mixed', 'command'=>'string', '...args='=>'mixed'],
    'Redis::select' => ['bool', 'dbindex'=>'int'],
    'Redis::sendEcho' => ['string', 'msg'=>'string'],
    'Redis::set' => ['bool', 'key'=>'string', 'value'=>'mixed', 'options='=>'array'],
    'Redis::set\'1' => ['bool', 'key'=>'string', 'value'=>'mixed', 'timeout='=>'int'],
    'Redis::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'int'],
    'Redis::setEx' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
    'Redis::setNx' => ['bool', 'key'=>'string', 'value'=>'string'],
    'Redis::setOption' => ['bool', 'name'=>'int', 'value'=>'mixed'],
    'Redis::setRange' => ['int', 'key'=>'string', 'offset'=>'int', 'end'=>'int'],
    'Redis::setTimeout' => ['', 'key'=>'string', 'ttl'=>'int'],
    'Redis::slave' => ['bool', 'host'=>'string', 'port'=>'int'],
    'Redis::slave\'1' => ['bool', 'host'=>'string', 'port'=>'int'],
    'Redis::slaveof' => ['bool', 'host='=>'string', 'port='=>'int'],
    'Redis::slowLog' => ['mixed', 'operation'=>'string', 'length='=>'int'],
    'Redis::sort' => ['array|int', 'key'=>'string', 'options='=>'array'],
    'Redis::sortAsc' => ['array', 'key'=>'string', 'pattern='=>'string', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
    'Redis::sortAscAlpha' => ['array', 'key'=>'string', 'pattern='=>'', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
    'Redis::sortDesc' => ['array', 'key'=>'string', 'pattern='=>'', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
    'Redis::sortDescAlpha' => ['array', 'key'=>'string', 'pattern='=>'', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
    'Redis::strLen' => ['int', 'key'=>'string'],
    'Redis::subscribe' => ['mixed|null', 'channels'=>'array', 'callback'=>'string|array'],
    'Redis::substr' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'Redis::swapdb' => ['bool', 'srcdb'=>'int', 'dstdb'=>'int'],
    'Redis::time' => ['array'],
    'Redis::ttl' => ['int|false', 'key'=>'string'],
    'Redis::type' => ['int', 'key'=>'string'],
    'Redis::unlink' => ['int', 'key'=>'string', '...args'=>'string'],
    'Redis::unlink\'1' => ['int', 'key'=>'string[]'],
    'Redis::unsubscribe' => ['', 'channel'=>'string', '...other_channels='=>'string'],
    'Redis::unwatch' => [''],
    'Redis::wait' => ['int', 'numSlaves'=>'int', 'timeout'=>'int'],
    'Redis::watch' => ['void', 'key'=>'string', '...other_keys='=>'string'],
    'Redis::xack' => ['', 'str_key'=>'string', 'str_group'=>'string', 'arr_ids'=>'array'],
    'Redis::xadd' => ['', 'str_key'=>'string', 'str_id'=>'string', 'arr_fields'=>'array', 'i_maxlen='=>'', 'boo_approximate='=>''],
    'Redis::xclaim' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_consumer'=>'string', 'i_min_idle'=>'', 'arr_ids'=>'array', 'arr_opts='=>'array'],
    'Redis::xdel' => ['', 'str_key'=>'string', 'arr_ids'=>'array'],
    'Redis::xgroup' => ['', 'str_operation'=>'string', 'str_key='=>'string', 'str_arg1='=>'', 'str_arg2='=>'', 'str_arg3='=>''],
    'Redis::xinfo' => ['', 'str_cmd'=>'string', 'str_key='=>'string', 'str_group='=>'string'],
    'Redis::xlen' => ['', 'key'=>''],
    'Redis::xpending' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_start='=>'', 'str_end='=>'', 'i_count='=>'', 'str_consumer='=>'string'],
    'Redis::xrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
    'Redis::xread' => ['', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
    'Redis::xreadgroup' => ['', 'str_group'=>'string', 'str_consumer'=>'string', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
    'Redis::xrevrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
    'Redis::xtrim' => ['', 'str_key'=>'string', 'i_maxlen'=>'', 'boo_approximate='=>''],
    'Redis::zAdd' => ['int', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'],
    'Redis::zAdd\'1' => ['int', 'options'=>'array', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'],
    'Redis::zCard' => ['int', 'key'=>'string'],
    'Redis::zCount' => ['int', 'key'=>'string', 'start'=>'string', 'end'=>'string'],
    'Redis::zDelete' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
    'Redis::zDeleteRangeByRank' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'Redis::zDeleteRangeByScore' => ['', 'key'=>'string', 'start'=>'float', 'end'=>'float'],
    'Redis::zIncrBy' => ['float', 'key'=>'string', 'value'=>'float', 'member'=>'string'],
    'Redis::zInter' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
    'Redis::zInterStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
    'Redis::zLexCount' => ['int', 'key'=>'string', 'min'=>'string', 'max'=>'string'],
    'Redis::zRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscores='=>'bool'],
    'Redis::zRangeByLex' => ['array|false', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'],
    'Redis::zRangeByScore' => ['array', 'key'=>'string', 'start'=>'int|string', 'end'=>'int|string', 'options='=>'array'],
    'Redis::zRank' => ['int', 'key'=>'string', 'member'=>'string'],
    'Redis::zRem' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
    'Redis::zRemRangeByLex' => ['int', 'key'=>'string', 'min'=>'string', 'max'=>'string'],
    'Redis::zRemRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'Redis::zRemRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'],
    'Redis::zRemove' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
    'Redis::zRemoveRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'Redis::zRemoveRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'],
    'Redis::zRevRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'],
    'Redis::zRevRangeByLex' => ['array', 'key'=>'string', 'min'=>'string', 'max'=>'string', 'offset='=>'int', 'limit='=>'int'],
    'Redis::zRevRangeByScore' => ['array', 'key'=>'string', 'start'=>'string', 'end'=>'string', 'options='=>'array'],
    'Redis::zRevRank' => ['int', 'key'=>'string', 'member'=>'string'],
    'Redis::zReverseRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'],
    'Redis::zScan' => ['array|bool', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
    'Redis::zScore' => ['float|false', 'key'=>'string', 'member'=>'string'],
    'Redis::zSize' => ['', 'key'=>'string'],
    'Redis::zUnion' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
    'Redis::zUnionStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
    'RedisArray::__call' => ['mixed', 'function_name'=>'string', 'arguments'=>'array'],
    'RedisArray::__construct' => ['void', 'name='=>'string', 'hosts='=>'?array', 'opts='=>'?array'],
    'RedisArray::_continuum' => [''],
    'RedisArray::_distributor' => [''],
    'RedisArray::_function' => ['string'],
    'RedisArray::_hosts' => ['array'],
    'RedisArray::_instance' => ['', 'host'=>''],
    'RedisArray::_rehash' => ['', 'callable='=>'callable'],
    'RedisArray::_target' => ['string', 'key'=>'string'],
    'RedisArray::bgsave' => [''],
    'RedisArray::del' => ['bool', 'key'=>'string', '...args'=>'string'],
    'RedisArray::delete' => ['bool', 'key'=>'string', '...args'=>'string'],
    'RedisArray::delete\'1' => ['bool', 'key'=>'string[]'],
    'RedisArray::discard' => [''],
    'RedisArray::exec' => ['array'],
    'RedisArray::flushAll' => ['bool', 'async='=>'bool'],
    'RedisArray::flushDb' => ['bool', 'async='=>'bool'],
    'RedisArray::getMultiple' => ['', 'keys'=>''],
    'RedisArray::getOption' => ['', 'opt'=>''],
    'RedisArray::info' => ['array'],
    'RedisArray::keys' => ['array<int,string>', 'pattern'=>''],
    'RedisArray::mGet' => ['array', 'keys'=>'string[]'],
    'RedisArray::mSet' => ['bool', 'pairs'=>'array'],
    'RedisArray::multi' => ['RedisArray', 'host'=>'string', 'mode='=>'int'],
    'RedisArray::ping' => ['string'],
    'RedisArray::save' => ['bool'],
    'RedisArray::select' => ['', 'index'=>''],
    'RedisArray::setOption' => ['', 'opt'=>'', 'value'=>''],
    'RedisArray::unlink' => ['int', 'key'=>'string', '...other_keys='=>'string'],
    'RedisArray::unlink\'1' => ['int', 'key'=>'string[]'],
    'RedisArray::unwatch' => [''],
    'RedisCluster::__construct' => ['void', 'name'=>'?string', 'seeds='=>'string[]', 'timeout='=>'float', 'readTimeout='=>'float', 'persistent='=>'bool', 'auth='=>'?string'],
    'RedisCluster::_masters' => ['array'],
    'RedisCluster::_prefix' => ['string', 'value'=>'mixed'],
    'RedisCluster::_redir' => [''],
    'RedisCluster::_serialize' => ['mixed', 'value'=>'mixed'],
    'RedisCluster::_unserialize' => ['mixed', 'value'=>'string'],
    'RedisCluster::append' => ['int', 'key'=>'string', 'value'=>'string'],
    'RedisCluster::bgrewriteaof' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}'],
    'RedisCluster::bgsave' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}'],
    'RedisCluster::bitCount' => ['int', 'key'=>'string'],
    'RedisCluster::bitOp' => ['int', 'operation'=>'string', 'retKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'],
    'RedisCluster::bitpos' => ['int', 'key'=>'string', 'bit'=>'int', 'start='=>'int', 'end='=>'int'],
    'RedisCluster::blPop' => ['array', 'keys'=>'array', 'timeout'=>'int'],
    'RedisCluster::brPop' => ['array', 'keys'=>'array', 'timeout'=>'int'],
    'RedisCluster::brpoplpush' => ['string|false', 'srcKey'=>'string', 'dstKey'=>'string', 'timeout'=>'int'],
    'RedisCluster::clearLastError' => ['bool'],
    'RedisCluster::client' => ['', 'nodeParams'=>'string|array{0:string,1:int}', 'subCmd='=>'string', '...args='=>''],
    'RedisCluster::close' => [''],
    'RedisCluster::cluster' => ['mixed', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'arguments='=>'mixed'],
    'RedisCluster::command' => ['array|bool'],
    'RedisCluster::config' => ['array|bool', 'nodeParams'=>'string|array{0:string,1:int}', 'operation'=>'string', 'key'=>'string', 'value='=>'string'],
    'RedisCluster::dbSize' => ['int', 'nodeParams'=>'string|array{0:string,1:int}'],
    'RedisCluster::decr' => ['int', 'key'=>'string'],
    'RedisCluster::decrBy' => ['int', 'key'=>'string', 'value'=>'int'],
    'RedisCluster::del' => ['int', 'key'=>'string', '...other_keys='=>'string'],
    'RedisCluster::del\'1' => ['int', 'key'=>'string[]'],
    'RedisCluster::discard' => [''],
    'RedisCluster::dump' => ['string|false', 'key'=>'string'],
    'RedisCluster::echo' => ['string', 'nodeParams'=>'string|array{0:string,1:int}', 'msg'=>'string'],
    'RedisCluster::eval' => ['mixed', 'script'=>'', 'args='=>'', 'numKeys='=>''],
    'RedisCluster::evalSha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'],
    'RedisCluster::exec' => ['array|void'],
    'RedisCluster::exists' => ['bool', 'key'=>'string'],
    'RedisCluster::expire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
    'RedisCluster::expireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'],
    'RedisCluster::flushAll' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}', 'async='=>'bool'],
    'RedisCluster::flushDB' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}', 'async='=>'bool'],
    'RedisCluster::geoAdd' => ['int', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'member'=>'string', '...other_members='=>'float|string'],
    'RedisCluster::geoDist' => ['', 'key'=>'string', 'member1'=>'string', 'member2'=>'string', 'unit='=>'string'],
    'RedisCluster::geoRadius' => ['', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'radius'=>'float', 'radiusUnit'=>'string', 'options='=>'array'],
    'RedisCluster::geoRadiusByMember' => ['string[]', 'key'=>'string', 'member'=>'string', 'radius'=>'float', 'radiusUnit'=>'string', 'options='=>'array'],
    'RedisCluster::geohash' => ['array<int,string>', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
    'RedisCluster::geopos' => ['array<int,array{0:string,1:string}>', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
    'RedisCluster::get' => ['string|false', 'key'=>'string'],
    'RedisCluster::getBit' => ['int', 'key'=>'string', 'offset'=>'int'],
    'RedisCluster::getLastError' => ['?string'],
    'RedisCluster::getMode' => ['int'],
    'RedisCluster::getOption' => ['int', 'option'=>'int'],
    'RedisCluster::getRange' => ['string', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'RedisCluster::getSet' => ['string', 'key'=>'string', 'value'=>'string'],
    'RedisCluster::hDel' => ['int|false', 'key'=>'string', 'hashKey'=>'string', '...other_hashKeys='=>'string[]'],
    'RedisCluster::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'],
    'RedisCluster::hGet' => ['string|false', 'key'=>'string', 'hashKey'=>'string'],
    'RedisCluster::hGetAll' => ['array', 'key'=>'string'],
    'RedisCluster::hIncrBy' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'int'],
    'RedisCluster::hIncrByFloat' => ['float', 'key'=>'string', 'field'=>'string', 'increment'=>'float'],
    'RedisCluster::hKeys' => ['array', 'key'=>'string'],
    'RedisCluster::hLen' => ['int|false', 'key'=>'string'],
    'RedisCluster::hMGet' => ['array', 'key'=>'string', 'hashKeys'=>'array'],
    'RedisCluster::hMSet' => ['bool', 'key'=>'string', 'hashKeys'=>'array'],
    'RedisCluster::hScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
    'RedisCluster::hSet' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
    'RedisCluster::hSetNx' => ['bool', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
    'RedisCluster::hStrlen' => ['int', 'key'=>'string', 'member'=>'string'],
    'RedisCluster::hVals' => ['array', 'key'=>'string'],
    'RedisCluster::incr' => ['int', 'key'=>'string'],
    'RedisCluster::incrBy' => ['int', 'key'=>'string', 'value'=>'int'],
    'RedisCluster::incrByFloat' => ['float', 'key'=>'string', 'increment'=>'float'],
    'RedisCluster::info' => ['array', 'nodeParams'=>'string|array{0:string,1:int}', 'option='=>'string'],
    'RedisCluster::keys' => ['array', 'pattern'=>'string'],
    'RedisCluster::lGet' => ['', 'key'=>'string', 'index'=>'int'],
    'RedisCluster::lIndex' => ['string|false', 'key'=>'string', 'index'=>'int'],
    'RedisCluster::lInsert' => ['int', 'key'=>'string', 'position'=>'int', 'pivot'=>'string', 'value'=>'string'],
    'RedisCluster::lLen' => ['int', 'key'=>'string'],
    'RedisCluster::lPop' => ['string|false', 'key'=>'string'],
    'RedisCluster::lPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
    'RedisCluster::lPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
    'RedisCluster::lRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'RedisCluster::lRem' => ['int|false', 'key'=>'string', 'value'=>'string', 'count'=>'int'],
    'RedisCluster::lSet' => ['bool', 'key'=>'string', 'index'=>'int', 'value'=>'string'],
    'RedisCluster::lTrim' => ['array|false', 'key'=>'string', 'start'=>'int', 'stop'=>'int'],
    'RedisCluster::lastSave' => ['int', 'nodeParams'=>'string|array{0:string,1:int}'],
    'RedisCluster::mget' => ['array', 'array'=>'array'],
    'RedisCluster::mset' => ['bool', 'array'=>'array'],
    'RedisCluster::msetnx' => ['int', 'array'=>'array'],
    'RedisCluster::multi' => ['Redis', 'mode='=>'int'],
    'RedisCluster::object' => ['string|int|false', 'string'=>'string', 'key'=>'string'],
    'RedisCluster::pExpire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
    'RedisCluster::pExpireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'],
    'RedisCluster::persist' => ['bool', 'key'=>'string'],
    'RedisCluster::pfAdd' => ['bool', 'key'=>'string', 'elements'=>'array'],
    'RedisCluster::pfCount' => ['int', 'key'=>'string'],
    'RedisCluster::pfMerge' => ['bool', 'destKey'=>'string', 'sourceKeys'=>'array'],
    'RedisCluster::ping' => ['string', 'nodeParams'=>'string|array{0:string,1:int}'],
    'RedisCluster::psetex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
    'RedisCluster::psubscribe' => ['mixed', 'patterns'=>'array', 'callback'=>'string'],
    'RedisCluster::pttl' => ['int', 'key'=>'string'],
    'RedisCluster::publish' => ['int', 'channel'=>'string', 'message'=>'string'],
    'RedisCluster::pubsub' => ['array', 'nodeParams'=>'string', 'keyword'=>'string', '...argument='=>'string'],
    'RedisCluster::punSubscribe' => ['', 'channels'=>'', 'callback'=>''],
    'RedisCluster::rPop' => ['string|false', 'key'=>'string'],
    'RedisCluster::rPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
    'RedisCluster::rPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
    'RedisCluster::randomKey' => ['string', 'nodeParams'=>'string|array{0:string,1:int}'],
    'RedisCluster::rawCommand' => ['mixed', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'arguments='=>'mixed'],
    'RedisCluster::rename' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'],
    'RedisCluster::renameNx' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'],
    'RedisCluster::restore' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
    'RedisCluster::role' => ['array'],
    'RedisCluster::rpoplpush' => ['string|false', 'srcKey'=>'string', 'dstKey'=>'string'],
    'RedisCluster::sAdd' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
    'RedisCluster::sAddArray' => ['int|false', 'key'=>'string', 'valueArray'=>'array'],
    'RedisCluster::sCard' => ['int', 'key'=>'string'],
    'RedisCluster::sDiff' => ['list<string>', 'key1'=>'string', 'key2'=>'string', '...other_keys='=>'string'],
    'RedisCluster::sDiffStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'],
    'RedisCluster::sInter' => ['list<string>', 'key'=>'string', '...other_keys='=>'string'],
    'RedisCluster::sInterStore' => ['int', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
    'RedisCluster::sIsMember' => ['bool', 'key'=>'string', 'value'=>'string'],
    'RedisCluster::sMembers' => ['list<string>', 'key'=>'string'],
    'RedisCluster::sMove' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string', 'member'=>'string'],
    'RedisCluster::sPop' => ['string', 'key'=>'string'],
    'RedisCluster::sRandMember' => ['array|string', 'key'=>'string', 'count='=>'int'],
    'RedisCluster::sRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
    'RedisCluster::sScan' => ['array|false', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'null', 'count='=>'int'],
    'RedisCluster::sUnion' => ['list<string>', 'key1'=>'string', '...other_keys='=>'string'],
    'RedisCluster::sUnion\'1' => ['list<string>', 'keys'=>'string[]'],
    'RedisCluster::sUnionStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'],
    'RedisCluster::save' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}'],
    'RedisCluster::scan' => ['array|false', '&iterator'=>'int', 'nodeParams'=>'string|array{0:string,1:int}', 'pattern='=>'string', 'count='=>'int'],
    'RedisCluster::script' => ['string|bool|array', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'script='=>'string', '...other_scripts='=>'string[]'],
    'RedisCluster::set' => ['bool', 'key'=>'string', 'value'=>'string', 'timeout='=>'array|int'],
    'RedisCluster::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'bool|int'],
    'RedisCluster::setOption' => ['bool', 'option'=>'int', 'value'=>'string|int'],
    'RedisCluster::setRange' => ['string', 'key'=>'string', 'offset'=>'int', 'value'=>'string'],
    'RedisCluster::setex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
    'RedisCluster::setnx' => ['bool', 'key'=>'string', 'value'=>'string'],
    'RedisCluster::slowLog' => ['array|int|bool', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'length='=>'int'],
    'RedisCluster::sort' => ['array', 'key'=>'string', 'option='=>'array'],
    'RedisCluster::strlen' => ['int', 'key'=>'string'],
    'RedisCluster::subscribe' => ['mixed', 'channels'=>'array', 'callback'=>'string'],
    'RedisCluster::time' => ['array'],
    'RedisCluster::ttl' => ['int', 'key'=>'string'],
    'RedisCluster::type' => ['int', 'key'=>'string'],
    'RedisCluster::unSubscribe' => ['', 'channels'=>'', '...other_channels='=>''],
    'RedisCluster::unlink' => ['int', 'key'=>'string', '...other_keys='=>'string'],
    'RedisCluster::unwatch' => [''],
    'RedisCluster::watch' => ['void', 'key'=>'string', '...other_keys='=>'string'],
    'RedisCluster::xack' => ['', 'str_key'=>'string', 'str_group'=>'string', 'arr_ids'=>'array'],
    'RedisCluster::xadd' => ['', 'str_key'=>'string', 'str_id'=>'string', 'arr_fields'=>'array', 'i_maxlen='=>'', 'boo_approximate='=>''],
    'RedisCluster::xclaim' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_consumer'=>'string', 'i_min_idle'=>'', 'arr_ids'=>'array', 'arr_opts='=>'array'],
    'RedisCluster::xdel' => ['', 'str_key'=>'string', 'arr_ids'=>'array'],
    'RedisCluster::xgroup' => ['', 'str_operation'=>'string', 'str_key='=>'string', 'str_arg1='=>'', 'str_arg2='=>'', 'str_arg3='=>''],
    'RedisCluster::xinfo' => ['', 'str_cmd'=>'string', 'str_key='=>'string', 'str_group='=>'string'],
    'RedisCluster::xlen' => ['', 'key'=>''],
    'RedisCluster::xpending' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_start='=>'', 'str_end='=>'', 'i_count='=>'', 'str_consumer='=>'string'],
    'RedisCluster::xrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
    'RedisCluster::xread' => ['', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
    'RedisCluster::xreadgroup' => ['', 'str_group'=>'string', 'str_consumer'=>'string', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
    'RedisCluster::xrevrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
    'RedisCluster::xtrim' => ['', 'str_key'=>'string', 'i_maxlen'=>'', 'boo_approximate='=>''],
    'RedisCluster::zAdd' => ['int', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'],
    'RedisCluster::zCard' => ['int', 'key'=>'string'],
    'RedisCluster::zCount' => ['int', 'key'=>'string', 'start'=>'string', 'end'=>'string'],
    'RedisCluster::zIncrBy' => ['float', 'key'=>'string', 'value'=>'float', 'member'=>'string'],
    'RedisCluster::zInterStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
    'RedisCluster::zLexCount' => ['int', 'key'=>'string', 'min'=>'int', 'max'=>'int'],
    'RedisCluster::zRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscores='=>'bool'],
    'RedisCluster::zRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'],
    'RedisCluster::zRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'],
    'RedisCluster::zRank' => ['int', 'key'=>'string', 'member'=>'string'],
    'RedisCluster::zRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
    'RedisCluster::zRemRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int'],
    'RedisCluster::zRemRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
    'RedisCluster::zRemRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'],
    'RedisCluster::zRevRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'],
    'RedisCluster::zRevRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'],
    'RedisCluster::zRevRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'],
    'RedisCluster::zRevRank' => ['int', 'key'=>'string', 'member'=>'string'],
    'RedisCluster::zScan' => ['array|false', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
    'RedisCluster::zScore' => ['float', 'key'=>'string', 'member'=>'string'],
    'RedisCluster::zUnionStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
    'Reflection::export' => ['?string', 'r'=>'reflector', 'return='=>'bool'],
    'Reflection::getModifierNames' => ['list<string>', 'modifiers'=>'int'],
    'ReflectionClass::__clone' => ['void'],
    'ReflectionClass::__construct' => ['void', 'argument'=>'object|class-string'],
    'ReflectionClass::__toString' => ['string'],
    'ReflectionClass::export' => ['?string', 'argument'=>'string|object', 'return='=>'bool'],
    'ReflectionClass::getConstant' => ['mixed', 'name'=>'string'],
    'ReflectionClass::getConstants' => ['array<string,mixed>'],
    'ReflectionClass::getConstructor' => ['?ReflectionMethod'],
    'ReflectionClass::getDefaultProperties' => ['array'],
    'ReflectionClass::getDocComment' => ['string|false'],
    'ReflectionClass::getEndLine' => ['int|false'],
    'ReflectionClass::getExtension' => ['?ReflectionExtension'],
    'ReflectionClass::getExtensionName' => ['string|false'],
    'ReflectionClass::getFileName' => ['string|false'],
    'ReflectionClass::getInterfaceNames' => ['list<class-string>'],
    'ReflectionClass::getInterfaces' => ['array<class-string, ReflectionClass>'],
    'ReflectionClass::getMethod' => ['ReflectionMethod', 'name'=>'string'],
    'ReflectionClass::getMethods' => ['list<ReflectionMethod>', 'filter='=>'int'],
    'ReflectionClass::getModifiers' => ['int'],
    'ReflectionClass::getName' => ['class-string'],
    'ReflectionClass::getNamespaceName' => ['string'],
    'ReflectionClass::getParentClass' => ['ReflectionClass|false'],
    'ReflectionClass::getProperties' => ['list<ReflectionProperty>', 'filter='=>'int'],
    'ReflectionClass::getProperty' => ['ReflectionProperty', 'name'=>'string'],
    'ReflectionClass::getReflectionConstant' => ['ReflectionClassConstant|false', 'name'=>'string'],
    'ReflectionClass::getReflectionConstants' => ['list<ReflectionClassConstant>'],
    'ReflectionClass::getShortName' => ['string'],
    'ReflectionClass::getStartLine' => ['int|false'],
    'ReflectionClass::getStaticProperties' => ['array<string, ReflectionProperty>'],
    'ReflectionClass::getStaticPropertyValue' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
    'ReflectionClass::getTraitAliases' => ['array<string,string>'],
    'ReflectionClass::getTraitNames' => ['list<trait-string>'],
    'ReflectionClass::getTraits' => ['array<trait-string,ReflectionClass>'],
    'ReflectionClass::hasConstant' => ['bool', 'name'=>'string'],
    'ReflectionClass::hasMethod' => ['bool', 'name'=>'string'],
    'ReflectionClass::hasProperty' => ['bool', 'name'=>'string'],
    'ReflectionClass::implementsInterface' => ['bool', 'interface_name'=>'interface-string|ReflectionClass'],
    'ReflectionClass::inNamespace' => ['bool'],
    'ReflectionClass::isAbstract' => ['bool'],
    'ReflectionClass::isAnonymous' => ['bool'],
    'ReflectionClass::isCloneable' => ['bool'],
    'ReflectionClass::isFinal' => ['bool'],
    'ReflectionClass::isInstance' => ['bool', 'object'=>'object'],
    'ReflectionClass::isInstantiable' => ['bool'],
    'ReflectionClass::isInterface' => ['bool'],
    'ReflectionClass::isInternal' => ['bool'],
    'ReflectionClass::isIterateable' => ['bool'],
    'ReflectionClass::isSubclassOf' => ['bool', 'class'=>'class-string|ReflectionClass'],
    'ReflectionClass::isTrait' => ['bool'],
    'ReflectionClass::isUserDefined' => ['bool'],
    'ReflectionClass::newInstance' => ['object', '...args='=>'mixed'],
    'ReflectionClass::newInstanceArgs' => ['object', 'args='=>'list<mixed>'],
    'ReflectionClass::newInstanceWithoutConstructor' => ['object'],
    'ReflectionClass::setStaticPropertyValue' => ['void', 'name'=>'string', 'value'=>'mixed'],
    'ReflectionClassConstant::__construct' => ['void', 'class'=>'mixed', 'name'=>'string'],
    'ReflectionClassConstant::__toString' => ['string'],
    'ReflectionClassConstant::export' => ['string', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'],
    'ReflectionClassConstant::getDeclaringClass' => ['ReflectionClass'],
    'ReflectionClassConstant::getDocComment' => ['string|false'],
    'ReflectionClassConstant::getModifiers' => ['int'],
    'ReflectionClassConstant::getName' => ['string'],
    'ReflectionClassConstant::getValue' => ['scalar|array<scalar>|null'],
    'ReflectionClassConstant::isPrivate' => ['bool'],
    'ReflectionClassConstant::isProtected' => ['bool'],
    'ReflectionClassConstant::isPublic' => ['bool'],
    'ReflectionExtension::__clone' => ['void'],
    'ReflectionExtension::__construct' => ['void', 'name'=>'string'],
    'ReflectionExtension::__toString' => ['string'],
    'ReflectionExtension::export' => ['?string', 'name'=>'string', 'return='=>'bool'],
    'ReflectionExtension::getClassNames' => ['list<class-string>'],
    'ReflectionExtension::getClasses' => ['array<class-string,ReflectionClass>'],
    'ReflectionExtension::getConstants' => ['array<string,mixed>'],
    'ReflectionExtension::getDependencies' => ['array<string,string>'],
    'ReflectionExtension::getFunctions' => ['array<string,ReflectionFunction>'],
    'ReflectionExtension::getINIEntries' => ['array<string,mixed>'],
    'ReflectionExtension::getName' => ['string'],
    'ReflectionExtension::getVersion' => ['?string'],
    'ReflectionExtension::info' => ['void'],
    'ReflectionExtension::isPersistent' => ['bool'],
    'ReflectionExtension::isTemporary' => ['bool'],
    'ReflectionFunction::__construct' => ['void', 'name'=>'callable-string|Closure'],
    'ReflectionFunction::__toString' => ['string'],
    'ReflectionFunction::export' => ['?string', 'name'=>'string', 'return='=>'bool'],
    'ReflectionFunction::getClosure' => ['Closure'],
    'ReflectionFunction::getClosureScopeClass' => ['ReflectionClass'],
    'ReflectionFunction::getClosureThis' => ['object'],
    'ReflectionFunction::getDocComment' => ['string|false'],
    'ReflectionFunction::getEndLine' => ['int|false'],
    'ReflectionFunction::getExtension' => ['?ReflectionExtension'],
    'ReflectionFunction::getExtensionName' => ['string|false'],
    'ReflectionFunction::getFileName' => ['string|false'],
    'ReflectionFunction::getName' => ['callable-string'],
    'ReflectionFunction::getNamespaceName' => ['string'],
    'ReflectionFunction::getNumberOfParameters' => ['int'],
    'ReflectionFunction::getNumberOfRequiredParameters' => ['int'],
    'ReflectionFunction::getParameters' => ['list<ReflectionParameter>'],
    'ReflectionFunction::getReturnType' => ['?ReflectionType'],
    'ReflectionFunction::getShortName' => ['string'],
    'ReflectionFunction::getStartLine' => ['int|false'],
    'ReflectionFunction::getStaticVariables' => ['array'],
    'ReflectionFunction::hasReturnType' => ['bool'],
    'ReflectionFunction::inNamespace' => ['bool'],
    'ReflectionFunction::invoke' => ['mixed', '...args='=>'mixed'],
    'ReflectionFunction::invokeArgs' => ['mixed', 'args'=>'array'],
    'ReflectionFunction::isClosure' => ['bool'],
    'ReflectionFunction::isDeprecated' => ['bool'],
    'ReflectionFunction::isDisabled' => ['bool'],
    'ReflectionFunction::isGenerator' => ['bool'],
    'ReflectionFunction::isInternal' => ['bool'],
    'ReflectionFunction::isUserDefined' => ['bool'],
    'ReflectionFunction::isVariadic' => ['bool'],
    'ReflectionFunction::returnsReference' => ['bool'],
    'ReflectionFunctionAbstract::__clone' => ['void'],
    'ReflectionFunctionAbstract::__toString' => ['string'],
    'ReflectionFunctionAbstract::export' => ['?string'],
    'ReflectionFunctionAbstract::getClosureScopeClass' => ['ReflectionClass|null'],
    'ReflectionFunctionAbstract::getClosureThis' => ['object|null'],
    'ReflectionFunctionAbstract::getDocComment' => ['string|false'],
    'ReflectionFunctionAbstract::getEndLine' => ['int|false'],
    'ReflectionFunctionAbstract::getExtension' => ['?ReflectionExtension'],
    'ReflectionFunctionAbstract::getExtensionName' => ['string|false'],
    'ReflectionFunctionAbstract::getFileName' => ['string|false'],
    'ReflectionFunctionAbstract::getName' => ['string'],
    'ReflectionFunctionAbstract::getNamespaceName' => ['string'],
    'ReflectionFunctionAbstract::getNumberOfParameters' => ['int'],
    'ReflectionFunctionAbstract::getNumberOfRequiredParameters' => ['int'],
    'ReflectionFunctionAbstract::getParameters' => ['list<ReflectionParameter>'],
    'ReflectionFunctionAbstract::getReturnType' => ['?ReflectionType'],
    'ReflectionFunctionAbstract::getShortName' => ['string'],
    'ReflectionFunctionAbstract::getStartLine' => ['int|false'],
    'ReflectionFunctionAbstract::getStaticVariables' => ['array'],
    'ReflectionFunctionAbstract::hasReturnType' => ['bool'],
    'ReflectionFunctionAbstract::inNamespace' => ['bool'],
    'ReflectionFunctionAbstract::isClosure' => ['bool'],
    'ReflectionFunctionAbstract::isDeprecated' => ['bool'],
    'ReflectionFunctionAbstract::isGenerator' => ['bool'],
    'ReflectionFunctionAbstract::isInternal' => ['bool'],
    'ReflectionFunctionAbstract::isUserDefined' => ['bool'],
    'ReflectionFunctionAbstract::isVariadic' => ['bool'],
    'ReflectionFunctionAbstract::returnsReference' => ['bool'],
    'ReflectionGenerator::__construct' => ['void', 'generator'=>'object'],
    'ReflectionGenerator::getExecutingFile' => ['string'],
    'ReflectionGenerator::getExecutingGenerator' => ['Generator'],
    'ReflectionGenerator::getExecutingLine' => ['int'],
    'ReflectionGenerator::getFunction' => ['ReflectionFunctionAbstract'],
    'ReflectionGenerator::getThis' => ['?object'],
    'ReflectionGenerator::getTrace' => ['array', 'options='=>'int'],
    'ReflectionMethod::__construct' => ['void', 'class'=>'class-string|object', 'name'=>'string'],
    'ReflectionMethod::__construct\'1' => ['void', 'class_method'=>'string'],
    'ReflectionMethod::__toString' => ['string'],
    'ReflectionMethod::export' => ['?string', 'class'=>'string', 'name'=>'string', 'return='=>'bool'],
    'ReflectionMethod::getClosure' => ['?Closure', 'object='=>'object'],
    'ReflectionMethod::getClosureScopeClass' => ['ReflectionClass'],
    'ReflectionMethod::getClosureThis' => ['object'],
    'ReflectionMethod::getDeclaringClass' => ['ReflectionClass'],
    'ReflectionMethod::getDocComment' => ['false|string'],
    'ReflectionMethod::getEndLine' => ['false|int'],
    'ReflectionMethod::getExtension' => ['?ReflectionExtension'],
    'ReflectionMethod::getExtensionName' => ['string|false'],
    'ReflectionMethod::getFileName' => ['false|string'],
    'ReflectionMethod::getModifiers' => ['int'],
    'ReflectionMethod::getName' => ['string'],
    'ReflectionMethod::getNamespaceName' => ['string'],
    'ReflectionMethod::getNumberOfParameters' => ['int'],
    'ReflectionMethod::getNumberOfRequiredParameters' => ['int'],
    'ReflectionMethod::getParameters' => ['list<\ReflectionParameter>'],
    'ReflectionMethod::getPrototype' => ['ReflectionMethod'],
    'ReflectionMethod::getReturnType' => ['?ReflectionType'],
    'ReflectionMethod::getShortName' => ['string'],
    'ReflectionMethod::getStartLine' => ['false|int'],
    'ReflectionMethod::getStaticVariables' => ['array'],
    'ReflectionMethod::hasReturnType' => ['bool'],
    'ReflectionMethod::inNamespace' => ['bool'],
    'ReflectionMethod::invoke' => ['mixed', 'object'=>'?object', '...args='=>'mixed'],
    'ReflectionMethod::invokeArgs' => ['mixed', 'object'=>'?object', 'args'=>'array'],
    'ReflectionMethod::isAbstract' => ['bool'],
    'ReflectionMethod::isClosure' => ['bool'],
    'ReflectionMethod::isConstructor' => ['bool'],
    'ReflectionMethod::isDeprecated' => ['bool'],
    'ReflectionMethod::isDestructor' => ['bool'],
    'ReflectionMethod::isFinal' => ['bool'],
    'ReflectionMethod::isGenerator' => ['bool'],
    'ReflectionMethod::isInternal' => ['bool'],
    'ReflectionMethod::isPrivate' => ['bool'],
    'ReflectionMethod::isProtected' => ['bool'],
    'ReflectionMethod::isPublic' => ['bool'],
    'ReflectionMethod::isStatic' => ['bool'],
    'ReflectionMethod::isUserDefined' => ['bool'],
    'ReflectionMethod::isVariadic' => ['bool'],
    'ReflectionMethod::returnsReference' => ['bool'],
    'ReflectionMethod::setAccessible' => ['void', 'visible'=>'bool'],
    'ReflectionNamedType::__clone' => ['void'],
    'ReflectionNamedType::__toString' => ['string'],
    'ReflectionNamedType::allowsNull' => ['bool'],
    'ReflectionNamedType::getName' => ['string'],
    'ReflectionNamedType::isBuiltin' => ['bool'],
    'ReflectionObject::__clone' => ['void'],
    'ReflectionObject::__construct' => ['void', 'argument'=>'object'],
    'ReflectionObject::__toString' => ['string'],
    'ReflectionObject::export' => ['?string', 'argument'=>'object', 'return='=>'bool'],
    'ReflectionObject::getConstant' => ['mixed', 'name'=>'string'],
    'ReflectionObject::getConstants' => ['array<string,mixed>'],
    'ReflectionObject::getConstructor' => ['?ReflectionMethod'],
    'ReflectionObject::getDefaultProperties' => ['array'],
    'ReflectionObject::getDocComment' => ['false|string'],
    'ReflectionObject::getEndLine' => ['false|int'],
    'ReflectionObject::getExtension' => ['?ReflectionExtension'],
    'ReflectionObject::getExtensionName' => ['false|string'],
    'ReflectionObject::getFileName' => ['false|string'],
    'ReflectionObject::getInterfaceNames' => ['class-string[]'],
    'ReflectionObject::getInterfaces' => ['array<string,\ReflectionClass>'],
    'ReflectionObject::getMethod' => ['ReflectionMethod', 'name'=>'string'],
    'ReflectionObject::getMethods' => ['ReflectionMethod[]', 'filter='=>'int'],
    'ReflectionObject::getModifiers' => ['int'],
    'ReflectionObject::getName' => ['string'],
    'ReflectionObject::getNamespaceName' => ['string'],
    'ReflectionObject::getParentClass' => ['ReflectionClass|false'],
    'ReflectionObject::getProperties' => ['ReflectionProperty[]', 'filter='=>'int'],
    'ReflectionObject::getProperty' => ['ReflectionProperty', 'name'=>'string'],
    'ReflectionObject::getReflectionConstant' => ['ReflectionClassConstant', 'name'=>'string'],
    'ReflectionObject::getReflectionConstants' => ['list<\ReflectionClassConstant>'],
    'ReflectionObject::getShortName' => ['string'],
    'ReflectionObject::getStartLine' => ['false|int'],
    'ReflectionObject::getStaticProperties' => ['ReflectionProperty[]'],
    'ReflectionObject::getStaticPropertyValue' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
    'ReflectionObject::getTraitAliases' => ['array<string,string>'],
    'ReflectionObject::getTraitNames' => ['list<string>'],
    'ReflectionObject::getTraits' => ['array<string,\ReflectionClass>'],
    'ReflectionObject::hasConstant' => ['bool', 'name'=>'string'],
    'ReflectionObject::hasMethod' => ['bool', 'name'=>'string'],
    'ReflectionObject::hasProperty' => ['bool', 'name'=>'string'],
    'ReflectionObject::implementsInterface' => ['bool', 'interface_name'=>'ReflectionClass|string'],
    'ReflectionObject::inNamespace' => ['bool'],
    'ReflectionObject::isAbstract' => ['bool'],
    'ReflectionObject::isAnonymous' => ['bool'],
    'ReflectionObject::isCloneable' => ['bool'],
    'ReflectionObject::isFinal' => ['bool'],
    'ReflectionObject::isInstance' => ['bool', 'object'=>'object'],
    'ReflectionObject::isInstantiable' => ['bool'],
    'ReflectionObject::isInterface' => ['bool'],
    'ReflectionObject::isInternal' => ['bool'],
    'ReflectionObject::isIterable' => ['bool'],
    'ReflectionObject::isIterateable' => ['bool'],
    'ReflectionObject::isSubclassOf' => ['bool', 'class'=>'ReflectionClass|string'],
    'ReflectionObject::isTrait' => ['bool'],
    'ReflectionObject::isUserDefined' => ['bool'],
    'ReflectionObject::newInstance' => ['object', 'args='=>'mixed', '...args='=>'array'],
    'ReflectionObject::newInstanceArgs' => ['object', 'args='=>'list<mixed>'],
    'ReflectionObject::newInstanceWithoutConstructor' => ['object'],
    'ReflectionObject::setStaticPropertyValue' => ['void', 'name'=>'string', 'value'=>'string'],
    'ReflectionParameter::__clone' => ['void'],
    'ReflectionParameter::__construct' => ['void', 'function'=>'', 'parameter'=>''],
    'ReflectionParameter::__toString' => ['string'],
    'ReflectionParameter::allowsNull' => ['bool'],
    'ReflectionParameter::canBePassedByValue' => ['bool'],
    'ReflectionParameter::export' => ['?string', 'function'=>'string', 'parameter'=>'string', 'return='=>'bool'],
    'ReflectionParameter::getClass' => ['?ReflectionClass'],
    'ReflectionParameter::getDeclaringClass' => ['?ReflectionClass'],
    'ReflectionParameter::getDeclaringFunction' => ['ReflectionFunctionAbstract'],
    'ReflectionParameter::getDefaultValue' => ['mixed'],
    'ReflectionParameter::getDefaultValueConstantName' => ['?string'],
    'ReflectionParameter::getName' => ['string'],
    'ReflectionParameter::getPosition' => ['int'],
    'ReflectionParameter::getType' => ['?ReflectionType'],
    'ReflectionParameter::hasType' => ['bool'],
    'ReflectionParameter::isArray' => ['bool'],
    'ReflectionParameter::isCallable' => ['bool'],
    'ReflectionParameter::isDefaultValueAvailable' => ['bool'],
    'ReflectionParameter::isDefaultValueConstant' => ['bool'],
    'ReflectionParameter::isOptional' => ['bool'],
    'ReflectionParameter::isPassedByReference' => ['bool'],
    'ReflectionParameter::isVariadic' => ['bool'],
    'ReflectionProperty::__clone' => ['void'],
    'ReflectionProperty::__construct' => ['void', 'class'=>'', 'name'=>'string'],
    'ReflectionProperty::__toString' => ['string'],
    'ReflectionProperty::export' => ['?string', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'],
    'ReflectionProperty::getDeclaringClass' => ['ReflectionClass'],
    'ReflectionProperty::getDocComment' => ['string|false'],
    'ReflectionProperty::getModifiers' => ['int'],
    'ReflectionProperty::getName' => ['string'],
    'ReflectionProperty::getValue' => ['mixed', 'object='=>'object'],
    'ReflectionProperty::hasType' => ['bool'],
    'ReflectionProperty::isDefault' => ['bool'],
    'ReflectionProperty::isPrivate' => ['bool'],
    'ReflectionProperty::isProtected' => ['bool'],
    'ReflectionProperty::isPublic' => ['bool'],
    'ReflectionProperty::isStatic' => ['bool'],
    'ReflectionProperty::setAccessible' => ['void', 'visible'=>'bool'],
    'ReflectionProperty::setValue' => ['void', 'object'=>'null|object', 'value'=>''],
    'ReflectionProperty::setValue\'1' => ['void', 'value'=>''],
    'ReflectionType::__clone' => ['void'],
    'ReflectionType::__toString' => ['string'],
    'ReflectionType::allowsNull' => ['bool'],
    'ReflectionType::isBuiltin' => ['bool'],
    'ReflectionZendExtension::__clone' => ['void'],
    'ReflectionZendExtension::__construct' => ['void', 'name'=>'string'],
    'ReflectionZendExtension::__toString' => ['string'],
    'ReflectionZendExtension::export' => ['?string', 'name'=>'string', 'return='=>'bool'],
    'ReflectionZendExtension::getAuthor' => ['string'],
    'ReflectionZendExtension::getCopyright' => ['string'],
    'ReflectionZendExtension::getName' => ['string'],
    'ReflectionZendExtension::getURL' => ['string'],
    'ReflectionZendExtension::getVersion' => ['string'],
    'Reflector::__toString' => ['string'],
    'Reflector::export' => ['?string'],
    'RegexIterator::__construct' => ['void', 'iterator'=>'Iterator', 'regex'=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'],
    'RegexIterator::accept' => ['bool'],
    'RegexIterator::current' => ['mixed'],
    'RegexIterator::getFlags' => ['int'],
    'RegexIterator::getInnerIterator' => ['Iterator'],
    'RegexIterator::getMode' => ['int'],
    'RegexIterator::getPregFlags' => ['int'],
    'RegexIterator::getRegex' => ['string'],
    'RegexIterator::key' => ['mixed'],
    'RegexIterator::next' => ['void'],
    'RegexIterator::rewind' => ['void'],
    'RegexIterator::setFlags' => ['void', 'new_flags'=>'int'],
    'RegexIterator::setMode' => ['void', 'new_mode'=>'int'],
    'RegexIterator::setPregFlags' => ['void', 'new_flags'=>'int'],
    'RegexIterator::valid' => ['bool'],
    'ResourceBundle::__construct' => ['void', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'],
    'ResourceBundle::count' => ['int'],
    'ResourceBundle::create' => ['?ResourceBundle', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'],
    'ResourceBundle::get' => ['mixed', 'index'=>'string|int', 'fallback='=>'bool'],
    'ResourceBundle::getErrorCode' => ['int'],
    'ResourceBundle::getErrorMessage' => ['string'],
    'ResourceBundle::getLocales' => ['array', 'bundlename'=>'string'],
    'Runkit_Sandbox::__construct' => ['void', 'options='=>'array'],
    'Runkit_Sandbox_Parent' => [''],
    'Runkit_Sandbox_Parent::__construct' => ['void'],
    'RuntimeException::__clone' => ['void'],
    'RuntimeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'RuntimeException::__toString' => ['string'],
    'RuntimeException::getCode' => ['int'],
    'RuntimeException::getFile' => ['string'],
    'RuntimeException::getLine' => ['int'],
    'RuntimeException::getMessage' => ['string'],
    'RuntimeException::getPrevious' => ['?Throwable'],
    'RuntimeException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'RuntimeException::getTraceAsString' => ['string'],
    'SAMConnection::commit' => ['bool'],
    'SAMConnection::connect' => ['bool', 'protocol'=>'string', 'properties='=>'array'],
    'SAMConnection::disconnect' => ['bool'],
    'SAMConnection::errno' => ['int'],
    'SAMConnection::error' => ['string'],
    'SAMConnection::isConnected' => ['bool'],
    'SAMConnection::peek' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'],
    'SAMConnection::peekAll' => ['array', 'target'=>'string', 'properties='=>'array'],
    'SAMConnection::receive' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'],
    'SAMConnection::remove' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'],
    'SAMConnection::rollback' => ['bool'],
    'SAMConnection::send' => ['string', 'target'=>'string', 'msg'=>'sammessage', 'properties='=>'array'],
    'SAMConnection::setDebug' => ['', 'switch'=>'bool'],
    'SAMConnection::subscribe' => ['string', 'targettopic'=>'string'],
    'SAMConnection::unsubscribe' => ['bool', 'subscriptionid'=>'string', 'targettopic='=>'string'],
    'SAMMessage::body' => ['string'],
    'SAMMessage::header' => ['object'],
    'SCA::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
    'SCA::getService' => ['', 'target'=>'string', 'binding='=>'string', 'config='=>'array'],
    'SCA_LocalProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
    'SCA_SoapProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
    'SDO_DAS_ChangeSummary::beginLogging' => [''],
    'SDO_DAS_ChangeSummary::endLogging' => [''],
    'SDO_DAS_ChangeSummary::getChangeType' => ['int', 'dataobject'=>'sdo_dataobject'],
    'SDO_DAS_ChangeSummary::getChangedDataObjects' => ['SDO_List'],
    'SDO_DAS_ChangeSummary::getOldContainer' => ['SDO_DataObject', 'data_object'=>'sdo_dataobject'],
    'SDO_DAS_ChangeSummary::getOldValues' => ['SDO_List', 'data_object'=>'sdo_dataobject'],
    'SDO_DAS_ChangeSummary::isLogging' => ['bool'],
    'SDO_DAS_DataFactory::addPropertyToType' => ['', 'parent_type_namespace_uri'=>'string', 'parent_type_name'=>'string', 'property_name'=>'string', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'],
    'SDO_DAS_DataFactory::addType' => ['', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'],
    'SDO_DAS_DataFactory::getDataFactory' => ['SDO_DAS_DataFactory'],
    'SDO_DAS_DataObject::getChangeSummary' => ['SDO_DAS_ChangeSummary'],
    'SDO_DAS_Relational::__construct' => ['void', 'database_metadata'=>'array', 'application_root_type='=>'string', 'sdo_containment_references_metadata='=>'array'],
    'SDO_DAS_Relational::applyChanges' => ['', 'database_handle'=>'pdo', 'root_data_object'=>'sdodataobject'],
    'SDO_DAS_Relational::createRootDataObject' => ['SDODataObject'],
    'SDO_DAS_Relational::executePreparedQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'prepared_statement'=>'pdostatement', 'value_list'=>'array', 'column_specifier='=>'array'],
    'SDO_DAS_Relational::executeQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'sql_statement'=>'string', 'column_specifier='=>'array'],
    'SDO_DAS_Setting::getListIndex' => ['int'],
    'SDO_DAS_Setting::getPropertyIndex' => ['int'],
    'SDO_DAS_Setting::getPropertyName' => ['string'],
    'SDO_DAS_Setting::getValue' => [''],
    'SDO_DAS_Setting::isSet' => ['bool'],
    'SDO_DAS_XML::addTypes' => ['', 'xsd_file'=>'string'],
    'SDO_DAS_XML::create' => ['SDO_DAS_XML', 'xsd_file='=>'mixed', 'key='=>'string'],
    'SDO_DAS_XML::createDataObject' => ['SDO_DataObject', 'namespace_uri'=>'string', 'type_name'=>'string'],
    'SDO_DAS_XML::createDocument' => ['SDO_DAS_XML_Document', 'document_element_name'=>'string', 'document_element_namespace_uri'=>'string', 'dataobject='=>'sdo_dataobject'],
    'SDO_DAS_XML::loadFile' => ['SDO_XMLDocument', 'xml_file'=>'string'],
    'SDO_DAS_XML::loadString' => ['SDO_DAS_XML_Document', 'xml_string'=>'string'],
    'SDO_DAS_XML::saveFile' => ['', 'xdoc'=>'sdo_xmldocument', 'xml_file'=>'string', 'indent='=>'int'],
    'SDO_DAS_XML::saveString' => ['string', 'xdoc'=>'sdo_xmldocument', 'indent='=>'int'],
    'SDO_DAS_XML_Document::getRootDataObject' => ['SDO_DataObject'],
    'SDO_DAS_XML_Document::getRootElementName' => ['string'],
    'SDO_DAS_XML_Document::getRootElementURI' => ['string'],
    'SDO_DAS_XML_Document::setEncoding' => ['', 'encoding'=>'string'],
    'SDO_DAS_XML_Document::setXMLDeclaration' => ['', 'xmldeclatation'=>'bool'],
    'SDO_DAS_XML_Document::setXMLVersion' => ['', 'xmlversion'=>'string'],
    'SDO_DataFactory::create' => ['void', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
    'SDO_DataObject::clear' => ['void'],
    'SDO_DataObject::createDataObject' => ['SDO_DataObject', 'identifier'=>''],
    'SDO_DataObject::getContainer' => ['SDO_DataObject'],
    'SDO_DataObject::getSequence' => ['SDO_Sequence'],
    'SDO_DataObject::getTypeName' => ['string'],
    'SDO_DataObject::getTypeNamespaceURI' => ['string'],
    'SDO_Exception::getCause' => [''],
    'SDO_List::insert' => ['void', 'value'=>'mixed', 'index='=>'int'],
    'SDO_Model_Property::getContainingType' => ['SDO_Model_Type'],
    'SDO_Model_Property::getDefault' => [''],
    'SDO_Model_Property::getName' => ['string'],
    'SDO_Model_Property::getType' => ['SDO_Model_Type'],
    'SDO_Model_Property::isContainment' => ['bool'],
    'SDO_Model_Property::isMany' => ['bool'],
    'SDO_Model_ReflectionDataObject::__construct' => ['void', 'data_object'=>'sdo_dataobject'],
    'SDO_Model_ReflectionDataObject::export' => ['mixed', 'rdo'=>'sdo_model_reflectiondataobject', 'return='=>'bool'],
    'SDO_Model_ReflectionDataObject::getContainmentProperty' => ['SDO_Model_Property'],
    'SDO_Model_ReflectionDataObject::getInstanceProperties' => ['array'],
    'SDO_Model_ReflectionDataObject::getType' => ['SDO_Model_Type'],
    'SDO_Model_Type::getBaseType' => ['SDO_Model_Type'],
    'SDO_Model_Type::getName' => ['string'],
    'SDO_Model_Type::getNamespaceURI' => ['string'],
    'SDO_Model_Type::getProperties' => ['array'],
    'SDO_Model_Type::getProperty' => ['SDO_Model_Property', 'identifier'=>''],
    'SDO_Model_Type::isAbstractType' => ['bool'],
    'SDO_Model_Type::isDataType' => ['bool'],
    'SDO_Model_Type::isInstance' => ['bool', 'data_object'=>'sdo_dataobject'],
    'SDO_Model_Type::isOpenType' => ['bool'],
    'SDO_Model_Type::isSequencedType' => ['bool'],
    'SDO_Sequence::getProperty' => ['SDO_Model_Property', 'sequence_index'=>'int'],
    'SDO_Sequence::insert' => ['void', 'value'=>'mixed', 'sequenceindex='=>'int', 'propertyidentifier='=>'mixed'],
    'SDO_Sequence::move' => ['void', 'toindex'=>'int', 'fromindex'=>'int'],
    'SNMP::__construct' => ['void', 'version'=>'int', 'hostname'=>'string', 'community'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'SNMP::close' => ['bool'],
    'SNMP::get' => ['array|string|false', 'objectId'=>'string|array', 'preserveKeys='=>'bool'],
    'SNMP::getErrno' => ['int'],
    'SNMP::getError' => ['string'],
    'SNMP::getnext' => ['string|array|false', 'objectId'=>'string|array'],
    'SNMP::set' => ['bool', 'objectId'=>'string|array', 'type'=>'string|array', 'value'=>'mixed'],
    'SNMP::setSecurity' => ['bool', 'securityLevel'=>'string', 'authProtocol='=>'string', 'authPassphrase='=>'string', 'privacyProtocol='=>'string', 'privacyPassphrase='=>'string', 'contextName='=>'string', 'contextEngineId='=>'string'],
    'SNMP::walk' => ['array|false', 'objectId'=>'string', 'suffixAsKey='=>'bool', 'maxRepetitions='=>'int', 'nonRepeaters='=>'int'],
    'SQLite3::__construct' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryptionKey='=>'?string'],
    'SQLite3::busyTimeout' => ['bool', 'milliseconds'=>'int'],
    'SQLite3::changes' => ['int'],
    'SQLite3::close' => ['bool'],
    'SQLite3::createAggregate' => ['bool', 'name'=>'string', 'stepCallback'=>'callable', 'finalCallback'=>'callable', 'argCount='=>'int'],
    'SQLite3::createCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'],
    'SQLite3::createFunction' => ['bool', 'name'=>'string', 'callback'=>'callable', 'argCount='=>'int'],
    'SQLite3::enableExceptions' => ['bool', 'enable='=>'bool'],
    'SQLite3::escapeString' => ['string', 'string'=>'string'],
    'SQLite3::exec' => ['bool', 'query'=>'string'],
    'SQLite3::lastErrorCode' => ['int'],
    'SQLite3::lastErrorMsg' => ['string'],
    'SQLite3::lastInsertRowID' => ['int'],
    'SQLite3::loadExtension' => ['bool', 'name'=>'string'],
    'SQLite3::open' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryptionKey='=>'?string'],
    'SQLite3::openBlob' => ['resource|false', 'table'=>'string', 'column'=>'string', 'rowid'=>'int', 'dbname='=>'string'],
    'SQLite3::prepare' => ['SQLite3Stmt|false', 'query'=>'string'],
    'SQLite3::query' => ['SQLite3Result|false', 'query'=>'string'],
    'SQLite3::querySingle' => ['array|int|string|bool|float|null|false', 'query'=>'string', 'entireRow='=>'bool'],
    'SQLite3::version' => ['array'],
    'SQLite3Result::__construct' => ['void'],
    'SQLite3Result::columnName' => ['string', 'column'=>'int'],
    'SQLite3Result::columnType' => ['int', 'column'=>'int'],
    'SQLite3Result::fetchArray' => ['array|false', 'mode='=>'int'],
    'SQLite3Result::finalize' => ['bool'],
    'SQLite3Result::numColumns' => ['int'],
    'SQLite3Result::reset' => ['bool'],
    'SQLite3Stmt::__construct' => ['void', 'sqlite3'=>'sqlite3', 'query'=>'string'],
    'SQLite3Stmt::bindParam' => ['bool', 'param'=>'string|int', '&rw_var'=>'mixed', 'type='=>'int'],
    'SQLite3Stmt::bindValue' => ['bool', 'param'=>'string|int', 'value'=>'mixed', 'type='=>'int'],
    'SQLite3Stmt::clear' => ['bool'],
    'SQLite3Stmt::close' => ['bool'],
    'SQLite3Stmt::execute' => ['false|SQLite3Result'],
    'SQLite3Stmt::getSQL' => ['string', 'expand='=>'bool'],
    'SQLite3Stmt::paramCount' => ['int'],
    'SQLite3Stmt::readOnly' => ['bool'],
    'SQLite3Stmt::reset' => ['bool'],
    'SQLiteDatabase::__construct' => ['void', 'filename'=>'', 'mode='=>'int|mixed', '&error_message'=>''],
    'SQLiteDatabase::arrayQuery' => ['array', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'SQLiteDatabase::busyTimeout' => ['int', 'milliseconds'=>'int'],
    'SQLiteDatabase::changes' => ['int'],
    'SQLiteDatabase::createAggregate' => ['', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'],
    'SQLiteDatabase::createFunction' => ['', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'],
    'SQLiteDatabase::exec' => ['bool', 'query'=>'string', 'error_msg='=>'string'],
    'SQLiteDatabase::fetchColumnTypes' => ['array', 'table_name'=>'string', 'result_type='=>'int'],
    'SQLiteDatabase::lastError' => ['int'],
    'SQLiteDatabase::lastInsertRowid' => ['int'],
    'SQLiteDatabase::query' => ['SQLiteResult|false', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'],
    'SQLiteDatabase::queryExec' => ['bool', 'query'=>'string', '&w_error_msg='=>'string'],
    'SQLiteDatabase::singleQuery' => ['array', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'],
    'SQLiteDatabase::unbufferedQuery' => ['SQLiteUnbuffered|false', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'],
    'SQLiteException::__clone' => ['void'],
    'SQLiteException::__construct' => ['void', 'message'=>'', 'code'=>'', 'previous'=>''],
    'SQLiteException::__toString' => ['string'],
    'SQLiteException::__wakeup' => ['void'],
    'SQLiteException::getCode' => ['int'],
    'SQLiteException::getFile' => ['string'],
    'SQLiteException::getLine' => ['int'],
    'SQLiteException::getMessage' => ['string'],
    'SQLiteException::getPrevious' => ['RuntimeException|Throwable|null'],
    'SQLiteException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'SQLiteException::getTraceAsString' => ['string'],
    'SQLiteResult::__construct' => ['void'],
    'SQLiteResult::column' => ['mixed', 'index_or_name'=>'', 'decode_binary='=>'bool'],
    'SQLiteResult::count' => ['int'],
    'SQLiteResult::current' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'SQLiteResult::fetch' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'SQLiteResult::fetchAll' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'SQLiteResult::fetchObject' => ['object', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'],
    'SQLiteResult::fetchSingle' => ['string', 'decode_binary='=>'bool'],
    'SQLiteResult::fieldName' => ['string', 'field_index'=>'int'],
    'SQLiteResult::hasPrev' => ['bool'],
    'SQLiteResult::key' => ['mixed|null'],
    'SQLiteResult::next' => ['bool'],
    'SQLiteResult::numFields' => ['int'],
    'SQLiteResult::numRows' => ['int'],
    'SQLiteResult::prev' => ['bool'],
    'SQLiteResult::rewind' => ['bool'],
    'SQLiteResult::seek' => ['bool', 'rownum'=>'int'],
    'SQLiteResult::valid' => ['bool'],
    'SQLiteUnbuffered::column' => ['void', 'index_or_name'=>'', 'decode_binary='=>'bool'],
    'SQLiteUnbuffered::current' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'SQLiteUnbuffered::fetch' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'SQLiteUnbuffered::fetchAll' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'SQLiteUnbuffered::fetchObject' => ['object', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'],
    'SQLiteUnbuffered::fetchSingle' => ['string', 'decode_binary='=>'bool'],
    'SQLiteUnbuffered::fieldName' => ['string', 'field_index'=>'int'],
    'SQLiteUnbuffered::next' => ['bool'],
    'SQLiteUnbuffered::numFields' => ['int'],
    'SQLiteUnbuffered::valid' => ['bool'],
    'SVM::__construct' => ['void'],
    'SVM::getOptions' => ['array'],
    'SVM::setOptions' => ['bool', 'params'=>'array'],
    'SVMModel::__construct' => ['void', 'filename='=>'string'],
    'SVMModel::checkProbabilityModel' => ['bool'],
    'SVMModel::getLabels' => ['array'],
    'SVMModel::getNrClass' => ['int'],
    'SVMModel::getSvmType' => ['int'],
    'SVMModel::getSvrProbability' => ['float'],
    'SVMModel::load' => ['bool', 'filename'=>'string'],
    'SVMModel::predict' => ['float', 'data'=>'array'],
    'SVMModel::predict_probability' => ['float', 'data'=>'array'],
    'SVMModel::save' => ['bool', 'filename'=>'string'],
    'SWFAction::__construct' => ['void', 'script'=>'string'],
    'SWFBitmap::__construct' => ['void', 'file'=>'', 'alphafile='=>''],
    'SWFBitmap::getHeight' => ['float'],
    'SWFBitmap::getWidth' => ['float'],
    'SWFButton::__construct' => ['void'],
    'SWFButton::addASound' => ['SWFSoundInstance', 'sound'=>'swfsound', 'flags'=>'int'],
    'SWFButton::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'],
    'SWFButton::addShape' => ['void', 'shape'=>'swfshape', 'flags'=>'int'],
    'SWFButton::setAction' => ['void', 'action'=>'swfaction'],
    'SWFButton::setDown' => ['void', 'shape'=>'swfshape'],
    'SWFButton::setHit' => ['void', 'shape'=>'swfshape'],
    'SWFButton::setMenu' => ['void', 'flag'=>'int'],
    'SWFButton::setOver' => ['void', 'shape'=>'swfshape'],
    'SWFButton::setUp' => ['void', 'shape'=>'swfshape'],
    'SWFDisplayItem::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'],
    'SWFDisplayItem::addColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'SWFDisplayItem::endMask' => ['void'],
    'SWFDisplayItem::getRot' => ['float'],
    'SWFDisplayItem::getX' => ['float'],
    'SWFDisplayItem::getXScale' => ['float'],
    'SWFDisplayItem::getXSkew' => ['float'],
    'SWFDisplayItem::getY' => ['float'],
    'SWFDisplayItem::getYScale' => ['float'],
    'SWFDisplayItem::getYSkew' => ['float'],
    'SWFDisplayItem::move' => ['void', 'dx'=>'float', 'dy'=>'float'],
    'SWFDisplayItem::moveTo' => ['void', 'x'=>'float', 'y'=>'float'],
    'SWFDisplayItem::multColor' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'a='=>'float'],
    'SWFDisplayItem::remove' => ['void'],
    'SWFDisplayItem::rotate' => ['void', 'angle'=>'float'],
    'SWFDisplayItem::rotateTo' => ['void', 'angle'=>'float'],
    'SWFDisplayItem::scale' => ['void', 'dx'=>'float', 'dy'=>'float'],
    'SWFDisplayItem::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'],
    'SWFDisplayItem::setDepth' => ['void', 'depth'=>'int'],
    'SWFDisplayItem::setMaskLevel' => ['void', 'level'=>'int'],
    'SWFDisplayItem::setMatrix' => ['void', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'],
    'SWFDisplayItem::setName' => ['void', 'name'=>'string'],
    'SWFDisplayItem::setRatio' => ['void', 'ratio'=>'float'],
    'SWFDisplayItem::skewX' => ['void', 'ddegrees'=>'float'],
    'SWFDisplayItem::skewXTo' => ['void', 'degrees'=>'float'],
    'SWFDisplayItem::skewY' => ['void', 'ddegrees'=>'float'],
    'SWFDisplayItem::skewYTo' => ['void', 'degrees'=>'float'],
    'SWFFill::moveTo' => ['void', 'x'=>'float', 'y'=>'float'],
    'SWFFill::rotateTo' => ['void', 'angle'=>'float'],
    'SWFFill::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'],
    'SWFFill::skewXTo' => ['void', 'x'=>'float'],
    'SWFFill::skewYTo' => ['void', 'y'=>'float'],
    'SWFFont::__construct' => ['void', 'filename'=>'string'],
    'SWFFont::getAscent' => ['float'],
    'SWFFont::getDescent' => ['float'],
    'SWFFont::getLeading' => ['float'],
    'SWFFont::getShape' => ['string', 'code'=>'int'],
    'SWFFont::getUTF8Width' => ['float', 'string'=>'string'],
    'SWFFont::getWidth' => ['float', 'string'=>'string'],
    'SWFFontChar::addChars' => ['void', 'char'=>'string'],
    'SWFFontChar::addUTF8Chars' => ['void', 'char'=>'string'],
    'SWFGradient::__construct' => ['void'],
    'SWFGradient::addEntry' => ['void', 'ratio'=>'float', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'],
    'SWFMorph::__construct' => ['void'],
    'SWFMorph::getShape1' => ['SWFShape'],
    'SWFMorph::getShape2' => ['SWFShape'],
    'SWFMovie::__construct' => ['void', 'version='=>'int'],
    'SWFMovie::add' => ['mixed', 'instance'=>'object'],
    'SWFMovie::addExport' => ['void', 'char'=>'swfcharacter', 'name'=>'string'],
    'SWFMovie::addFont' => ['mixed', 'font'=>'swffont'],
    'SWFMovie::importChar' => ['SWFSprite', 'libswf'=>'string', 'name'=>'string'],
    'SWFMovie::importFont' => ['SWFFontChar', 'libswf'=>'string', 'name'=>'string'],
    'SWFMovie::labelFrame' => ['void', 'label'=>'string'],
    'SWFMovie::namedAnchor' => [''],
    'SWFMovie::nextFrame' => ['void'],
    'SWFMovie::output' => ['int', 'compression='=>'int'],
    'SWFMovie::protect' => [''],
    'SWFMovie::remove' => ['void', 'instance'=>'object'],
    'SWFMovie::save' => ['int', 'filename'=>'string', 'compression='=>'int'],
    'SWFMovie::saveToFile' => ['int', 'x'=>'resource', 'compression='=>'int'],
    'SWFMovie::setDimension' => ['void', 'width'=>'float', 'height'=>'float'],
    'SWFMovie::setFrames' => ['void', 'number'=>'int'],
    'SWFMovie::setRate' => ['void', 'rate'=>'float'],
    'SWFMovie::setbackground' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    'SWFMovie::startSound' => ['SWFSoundInstance', 'sound'=>'swfsound'],
    'SWFMovie::stopSound' => ['void', 'sound'=>'swfsound'],
    'SWFMovie::streamMP3' => ['int', 'mp3file'=>'mixed', 'skip='=>'float'],
    'SWFMovie::writeExports' => ['void'],
    'SWFPrebuiltClip::__construct' => ['void', 'file'=>''],
    'SWFShape::__construct' => ['void'],
    'SWFShape::addFill' => ['SWFFill', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int', 'bitmap='=>'swfbitmap', 'flags='=>'int', 'gradient='=>'swfgradient'],
    'SWFShape::addFill\'1' => ['SWFFill', 'bitmap'=>'SWFBitmap', 'flags='=>'int'],
    'SWFShape::addFill\'2' => ['SWFFill', 'gradient'=>'SWFGradient', 'flags='=>'int'],
    'SWFShape::drawArc' => ['void', 'r'=>'float', 'startangle'=>'float', 'endangle'=>'float'],
    'SWFShape::drawCircle' => ['void', 'r'=>'float'],
    'SWFShape::drawCubic' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'],
    'SWFShape::drawCubicTo' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'],
    'SWFShape::drawCurve' => ['int', 'controldx'=>'float', 'controldy'=>'float', 'anchordx'=>'float', 'anchordy'=>'float', 'targetdx='=>'float', 'targetdy='=>'float'],
    'SWFShape::drawCurveTo' => ['int', 'controlx'=>'float', 'controly'=>'float', 'anchorx'=>'float', 'anchory'=>'float', 'targetx='=>'float', 'targety='=>'float'],
    'SWFShape::drawGlyph' => ['void', 'font'=>'swffont', 'character'=>'string', 'size='=>'int'],
    'SWFShape::drawLine' => ['void', 'dx'=>'float', 'dy'=>'float'],
    'SWFShape::drawLineTo' => ['void', 'x'=>'float', 'y'=>'float'],
    'SWFShape::movePen' => ['void', 'dx'=>'float', 'dy'=>'float'],
    'SWFShape::movePenTo' => ['void', 'x'=>'float', 'y'=>'float'],
    'SWFShape::setLeftFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'SWFShape::setLine' => ['', 'shape'=>'swfshape', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'SWFShape::setRightFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'SWFSound' => ['SWFSound', 'filename'=>'string', 'flags='=>'int'],
    'SWFSound::__construct' => ['void', 'filename'=>'string', 'flags='=>'int'],
    'SWFSoundInstance::loopCount' => ['void', 'point'=>'int'],
    'SWFSoundInstance::loopInPoint' => ['void', 'point'=>'int'],
    'SWFSoundInstance::loopOutPoint' => ['void', 'point'=>'int'],
    'SWFSoundInstance::noMultiple' => ['void'],
    'SWFSprite::__construct' => ['void'],
    'SWFSprite::add' => ['void', 'object'=>'object'],
    'SWFSprite::labelFrame' => ['void', 'label'=>'string'],
    'SWFSprite::nextFrame' => ['void'],
    'SWFSprite::remove' => ['void', 'object'=>'object'],
    'SWFSprite::setFrames' => ['void', 'number'=>'int'],
    'SWFSprite::startSound' => ['SWFSoundInstance', 'sount'=>'swfsound'],
    'SWFSprite::stopSound' => ['void', 'sount'=>'swfsound'],
    'SWFText::__construct' => ['void'],
    'SWFText::addString' => ['void', 'string'=>'string'],
    'SWFText::addUTF8String' => ['void', 'text'=>'string'],
    'SWFText::getAscent' => ['float'],
    'SWFText::getDescent' => ['float'],
    'SWFText::getLeading' => ['float'],
    'SWFText::getUTF8Width' => ['float', 'string'=>'string'],
    'SWFText::getWidth' => ['float', 'string'=>'string'],
    'SWFText::moveTo' => ['void', 'x'=>'float', 'y'=>'float'],
    'SWFText::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'SWFText::setFont' => ['void', 'font'=>'swffont'],
    'SWFText::setHeight' => ['void', 'height'=>'float'],
    'SWFText::setSpacing' => ['void', 'spacing'=>'float'],
    'SWFTextField::__construct' => ['void', 'flags='=>'int'],
    'SWFTextField::addChars' => ['void', 'chars'=>'string'],
    'SWFTextField::addString' => ['void', 'string'=>'string'],
    'SWFTextField::align' => ['void', 'alignement'=>'int'],
    'SWFTextField::setBounds' => ['void', 'width'=>'float', 'height'=>'float'],
    'SWFTextField::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'SWFTextField::setFont' => ['void', 'font'=>'swffont'],
    'SWFTextField::setHeight' => ['void', 'height'=>'float'],
    'SWFTextField::setIndentation' => ['void', 'width'=>'float'],
    'SWFTextField::setLeftMargin' => ['void', 'width'=>'float'],
    'SWFTextField::setLineSpacing' => ['void', 'height'=>'float'],
    'SWFTextField::setMargins' => ['void', 'left'=>'float', 'right'=>'float'],
    'SWFTextField::setName' => ['void', 'name'=>'string'],
    'SWFTextField::setPadding' => ['void', 'padding'=>'float'],
    'SWFTextField::setRightMargin' => ['void', 'width'=>'float'],
    'SWFVideoStream::__construct' => ['void', 'file='=>'string'],
    'SWFVideoStream::getNumFrames' => ['int'],
    'SWFVideoStream::setDimension' => ['void', 'x'=>'int', 'y'=>'int'],
    'Saxon\SaxonProcessor::__construct' => ['void', 'license='=>'bool', 'cwd='=>'string'],
    'Saxon\SaxonProcessor::createAtomicValue' => ['Saxon\XdmValue', 'primitive_type_val'=>'bool|float|int|string'],
    'Saxon\SaxonProcessor::newSchemaValidator' => ['Saxon\SchemaValidator'],
    'Saxon\SaxonProcessor::newXPathProcessor' => ['Saxon\XPathProcessor'],
    'Saxon\SaxonProcessor::newXQueryProcessor' => ['Saxon\XQueryProcessor'],
    'Saxon\SaxonProcessor::newXsltProcessor' => ['Saxon\XsltProcessor'],
    'Saxon\SaxonProcessor::parseXmlFromFile' => ['Saxon\XdmNode', 'fileName'=>'string'],
    'Saxon\SaxonProcessor::parseXmlFromString' => ['Saxon\XdmNode', 'value'=>'string'],
    'Saxon\SaxonProcessor::registerPHPFunctions' => ['void', 'library'=>'string'],
    'Saxon\SaxonProcessor::setConfigurationProperty' => ['void', 'name'=>'string', 'value'=>'string'],
    'Saxon\SaxonProcessor::setResourceDirectory' => ['void', 'dir'=>'string'],
    'Saxon\SaxonProcessor::setcwd' => ['void', 'cwd'=>'string'],
    'Saxon\SaxonProcessor::version' => ['string'],
    'Saxon\SchemaValidator::clearParameters' => ['void'],
    'Saxon\SchemaValidator::clearProperties' => ['void'],
    'Saxon\SchemaValidator::exceptionClear' => ['void'],
    'Saxon\SchemaValidator::getErrorCode' => ['string', 'i'=>'int'],
    'Saxon\SchemaValidator::getErrorMessage' => ['string', 'i'=>'int'],
    'Saxon\SchemaValidator::getExceptionCount' => ['int'],
    'Saxon\SchemaValidator::getValidationReport' => ['Saxon\XdmNode'],
    'Saxon\SchemaValidator::registerSchemaFromFile' => ['void', 'fileName'=>'string'],
    'Saxon\SchemaValidator::registerSchemaFromString' => ['void', 'schemaStr'=>'string'],
    'Saxon\SchemaValidator::setOutputFile' => ['void', 'fileName'=>'string'],
    'Saxon\SchemaValidator::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
    'Saxon\SchemaValidator::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
    'Saxon\SchemaValidator::setSourceNode' => ['void', 'node'=>'Saxon\XdmNode'],
    'Saxon\SchemaValidator::validate' => ['void', 'filename='=>'?string'],
    'Saxon\SchemaValidator::validateToNode' => ['Saxon\XdmNode', 'filename='=>'?string'],
    'Saxon\XPathProcessor::clearParameters' => ['void'],
    'Saxon\XPathProcessor::clearProperties' => ['void'],
    'Saxon\XPathProcessor::declareNamespace' => ['void', 'prefix'=>'', 'namespace'=>''],
    'Saxon\XPathProcessor::effectiveBooleanValue' => ['bool', 'xpathStr'=>'string'],
    'Saxon\XPathProcessor::evaluate' => ['Saxon\XdmValue', 'xpathStr'=>'string'],
    'Saxon\XPathProcessor::evaluateSingle' => ['Saxon\XdmItem', 'xpathStr'=>'string'],
    'Saxon\XPathProcessor::exceptionClear' => ['void'],
    'Saxon\XPathProcessor::getErrorCode' => ['string', 'i'=>'int'],
    'Saxon\XPathProcessor::getErrorMessage' => ['string', 'i'=>'int'],
    'Saxon\XPathProcessor::getExceptionCount' => ['int'],
    'Saxon\XPathProcessor::setBaseURI' => ['void', 'uri'=>'string'],
    'Saxon\XPathProcessor::setContextFile' => ['void', 'fileName'=>'string'],
    'Saxon\XPathProcessor::setContextItem' => ['void', 'item'=>'Saxon\XdmItem'],
    'Saxon\XPathProcessor::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
    'Saxon\XPathProcessor::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
    'Saxon\XQueryProcessor::clearParameters' => ['void'],
    'Saxon\XQueryProcessor::clearProperties' => ['void'],
    'Saxon\XQueryProcessor::declareNamespace' => ['void', 'prefix'=>'string', 'namespace'=>'string'],
    'Saxon\XQueryProcessor::exceptionClear' => ['void'],
    'Saxon\XQueryProcessor::getErrorCode' => ['string', 'i'=>'int'],
    'Saxon\XQueryProcessor::getErrorMessage' => ['string', 'i'=>'int'],
    'Saxon\XQueryProcessor::getExceptionCount' => ['int'],
    'Saxon\XQueryProcessor::runQueryToFile' => ['void', 'outfilename'=>'string'],
    'Saxon\XQueryProcessor::runQueryToString' => ['?string'],
    'Saxon\XQueryProcessor::runQueryToValue' => ['?Saxon\XdmValue'],
    'Saxon\XQueryProcessor::setContextItem' => ['void', 'object'=>'Saxon\XdmAtomicValue|Saxon\XdmItem|Saxon\XdmNode|Saxon\XdmValue'],
    'Saxon\XQueryProcessor::setContextItemFromFile' => ['void', 'fileName'=>'string'],
    'Saxon\XQueryProcessor::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
    'Saxon\XQueryProcessor::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
    'Saxon\XQueryProcessor::setQueryBaseURI' => ['void', 'uri'=>'string'],
    'Saxon\XQueryProcessor::setQueryContent' => ['void', 'string'=>'string'],
    'Saxon\XQueryProcessor::setQueryFile' => ['void', 'filename'=>'string'],
    'Saxon\XQueryProcessor::setQueryItem' => ['void', 'item'=>'Saxon\XdmItem'],
    'Saxon\XdmAtomicValue::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
    'Saxon\XdmAtomicValue::getAtomicValue' => ['?Saxon\XdmAtomicValue'],
    'Saxon\XdmAtomicValue::getBooleanValue' => ['bool'],
    'Saxon\XdmAtomicValue::getDoubleValue' => ['float'],
    'Saxon\XdmAtomicValue::getHead' => ['Saxon\XdmItem'],
    'Saxon\XdmAtomicValue::getLongValue' => ['int'],
    'Saxon\XdmAtomicValue::getNodeValue' => ['?Saxon\XdmNode'],
    'Saxon\XdmAtomicValue::getStringValue' => ['string'],
    'Saxon\XdmAtomicValue::isAtomic' => ['true'],
    'Saxon\XdmAtomicValue::isNode' => ['bool'],
    'Saxon\XdmAtomicValue::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
    'Saxon\XdmAtomicValue::size' => ['int'],
    'Saxon\XdmItem::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
    'Saxon\XdmItem::getAtomicValue' => ['?Saxon\XdmAtomicValue'],
    'Saxon\XdmItem::getHead' => ['Saxon\XdmItem'],
    'Saxon\XdmItem::getNodeValue' => ['?Saxon\XdmNode'],
    'Saxon\XdmItem::getStringValue' => ['string'],
    'Saxon\XdmItem::isAtomic' => ['bool'],
    'Saxon\XdmItem::isNode' => ['bool'],
    'Saxon\XdmItem::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
    'Saxon\XdmItem::size' => ['int'],
    'Saxon\XdmNode::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
    'Saxon\XdmNode::getAtomicValue' => ['?Saxon\XdmAtomicValue'],
    'Saxon\XdmNode::getAttributeCount' => ['int'],
    'Saxon\XdmNode::getAttributeNode' => ['?Saxon\XdmNode', 'index'=>'int'],
    'Saxon\XdmNode::getAttributeValue' => ['?string', 'index'=>'int'],
    'Saxon\XdmNode::getChildCount' => ['int'],
    'Saxon\XdmNode::getChildNode' => ['?Saxon\XdmNode', 'index'=>'int'],
    'Saxon\XdmNode::getHead' => ['Saxon\XdmItem'],
    'Saxon\XdmNode::getNodeKind' => ['int'],
    'Saxon\XdmNode::getNodeName' => ['string'],
    'Saxon\XdmNode::getNodeValue' => ['?Saxon\XdmNode'],
    'Saxon\XdmNode::getParent' => ['?Saxon\XdmNode'],
    'Saxon\XdmNode::getStringValue' => ['string'],
    'Saxon\XdmNode::isAtomic' => ['false'],
    'Saxon\XdmNode::isNode' => ['bool'],
    'Saxon\XdmNode::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
    'Saxon\XdmNode::size' => ['int'],
    'Saxon\XdmValue::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
    'Saxon\XdmValue::getHead' => ['Saxon\XdmItem'],
    'Saxon\XdmValue::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
    'Saxon\XdmValue::size' => ['int'],
    'Saxon\XsltProcessor::clearParameters' => ['void'],
    'Saxon\XsltProcessor::clearProperties' => ['void'],
    'Saxon\XsltProcessor::compileFromFile' => ['void', 'fileName'=>'string'],
    'Saxon\XsltProcessor::compileFromString' => ['void', 'string'=>'string'],
    'Saxon\XsltProcessor::compileFromValue' => ['void', 'node'=>'Saxon\XdmNode'],
    'Saxon\XsltProcessor::exceptionClear' => ['void'],
    'Saxon\XsltProcessor::getErrorCode' => ['string', 'i'=>'int'],
    'Saxon\XsltProcessor::getErrorMessage' => ['string', 'i'=>'int'],
    'Saxon\XsltProcessor::getExceptionCount' => ['int'],
    'Saxon\XsltProcessor::setOutputFile' => ['void', 'fileName'=>'string'],
    'Saxon\XsltProcessor::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
    'Saxon\XsltProcessor::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
    'Saxon\XsltProcessor::setSourceFromFile' => ['void', 'filename'=>'string'],
    'Saxon\XsltProcessor::setSourceFromXdmValue' => ['void', 'value'=>'Saxon\XdmValue'],
    'Saxon\XsltProcessor::transformFileToFile' => ['void', 'sourceFileName'=>'string', 'stylesheetFileName'=>'string', 'outputfileName'=>'string'],
    'Saxon\XsltProcessor::transformFileToString' => ['?string', 'sourceFileName'=>'string', 'stylesheetFileName'=>'string'],
    'Saxon\XsltProcessor::transformFileToValue' => ['Saxon\XdmValue', 'fileName'=>'string'],
    'Saxon\XsltProcessor::transformToFile' => ['void'],
    'Saxon\XsltProcessor::transformToString' => ['string'],
    'Saxon\XsltProcessor::transformToValue' => ['?Saxon\XdmValue'],
    'SeasLog::__destruct' => ['void'],
    'SeasLog::alert' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::analyzerCount' => ['mixed', 'level'=>'string', 'log_path='=>'string', 'key_word='=>'string'],
    'SeasLog::analyzerDetail' => ['mixed', 'level'=>'string', 'log_path='=>'string', 'key_word='=>'string', 'start='=>'int', 'limit='=>'int', 'order='=>'int'],
    'SeasLog::closeLoggerStream' => ['bool', 'model'=>'int', 'logger'=>'string'],
    'SeasLog::critical' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::debug' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::emergency' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::error' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::flushBuffer' => ['bool'],
    'SeasLog::getBasePath' => ['string'],
    'SeasLog::getBuffer' => ['array'],
    'SeasLog::getBufferEnabled' => ['bool'],
    'SeasLog::getDatetimeFormat' => ['string'],
    'SeasLog::getLastLogger' => ['string'],
    'SeasLog::getRequestID' => ['string'],
    'SeasLog::getRequestVariable' => ['bool', 'key'=>'int'],
    'SeasLog::info' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::log' => ['bool', 'level'=>'string', 'message='=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::notice' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeasLog::setBasePath' => ['bool', 'base_path'=>'string'],
    'SeasLog::setDatetimeFormat' => ['bool', 'format'=>'string'],
    'SeasLog::setLogger' => ['bool', 'logger'=>'string'],
    'SeasLog::setRequestID' => ['bool', 'request_id'=>'string'],
    'SeasLog::setRequestVariable' => ['bool', 'key'=>'int', 'value'=>'string'],
    'SeasLog::warning' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
    'SeekableIterator::__construct' => ['void'],
    'SeekableIterator::current' => ['mixed'],
    'SeekableIterator::key' => ['int|string'],
    'SeekableIterator::next' => ['void'],
    'SeekableIterator::rewind' => ['void'],
    'SeekableIterator::seek' => ['void', 'position'=>'int'],
    'SeekableIterator::valid' => ['bool'],
    'Serializable::__construct' => ['void'],
    'Serializable::serialize' => ['?string'],
    'Serializable::unserialize' => ['void', 'serialized'=>'string'],
    'ServerRequest::withInput' => ['ServerRequest', 'input'=>'mixed'],
    'ServerRequest::withParam' => ['ServerRequest', 'key'=>'int|string', 'value'=>'mixed'],
    'ServerRequest::withParams' => ['ServerRequest', 'params'=>'mixed'],
    'ServerRequest::withUrl' => ['ServerRequest', 'url'=>'array'],
    'ServerRequest::withoutParams' => ['ServerRequest', 'params'=>'int|string'],
    'ServerResponse::addHeader' => ['void', 'label'=>'string', 'value'=>'string'],
    'ServerResponse::date' => ['string', 'date'=>'string|DateTimeInterface'],
    'ServerResponse::getHeader' => ['string', 'label'=>'string'],
    'ServerResponse::getHeaders' => ['string[]'],
    'ServerResponse::getStatus' => ['int'],
    'ServerResponse::getVersion' => ['string'],
    'ServerResponse::setHeader' => ['void', 'label'=>'string', 'value'=>'string'],
    'ServerResponse::setStatus' => ['void', 'status'=>'int'],
    'ServerResponse::setVersion' => ['void', 'version'=>'string'],
    'SessionHandler::close' => ['bool'],
    'SessionHandler::create_sid' => ['string'],
    'SessionHandler::destroy' => ['bool', 'id'=>'string'],
    'SessionHandler::gc' => ['bool', 'maxlifetime'=>'int'],
    'SessionHandler::open' => ['bool', 'save_path'=>'string', 'session_name'=>'string'],
    'SessionHandler::read' => ['string', 'id'=>'string'],
    'SessionHandler::write' => ['bool', 'id'=>'string', 'data'=>'string'],
    'SessionHandlerInterface::close' => ['bool'],
    'SessionHandlerInterface::destroy' => ['bool', 'id'=>'string'],
    'SessionHandlerInterface::gc' => ['int|false', 'max_lifetime'=>'int'],
    'SessionHandlerInterface::open' => ['bool', 'path'=>'string', 'name'=>'string'],
    'SessionHandlerInterface::read' => ['string|false', 'id'=>'string'],
    'SessionHandlerInterface::write' => ['bool', 'id'=>'string', 'data'=>'string'],
    'SessionIdInterface::create_sid' => ['string'],
    'SessionUpdateTimestampHandler::updateTimestamp' => ['bool', 'id'=>'string', 'data'=>'string'],
    'SessionUpdateTimestampHandler::validateId' => ['char', 'id'=>'string'],
    'SessionUpdateTimestampHandlerInterface::updateTimestamp' => ['bool', 'key'=>'string', 'value'=>'string'],
    'SessionUpdateTimestampHandlerInterface::validateId' => ['bool', 'key'=>'string'],
    'SimpleXMLElement::__construct' => ['void', 'data'=>'string', 'options='=>'int', 'data_is_url='=>'bool', 'ns='=>'string', 'is_prefix='=>'bool'],
    'SimpleXMLElement::__get' => ['SimpleXMLElement', 'name'=>'string'],
    'SimpleXMLElement::__toString' => ['string'],
    'SimpleXMLElement::addAttribute' => ['void', 'name'=>'string', 'value='=>'string', 'ns='=>'string'],
    'SimpleXMLElement::addChild' => ['SimpleXMLElement', 'name'=>'string', 'value='=>'string', 'ns='=>'string'],
    'SimpleXMLElement::asXML' => ['string|bool', 'filename'=>'string'],
    'SimpleXMLElement::asXML\'1' => ['string|false'],
    'SimpleXMLElement::attributes' => ['?SimpleXMLElement', 'ns='=>'string', 'is_prefix='=>'bool'],
    'SimpleXMLElement::children' => ['SimpleXMLElement', 'ns='=>'string', 'is_prefix='=>'bool'],
    'SimpleXMLElement::count' => ['int'],
    'SimpleXMLElement::getDocNamespaces' => ['string[]', 'recursive='=>'bool', 'from_root='=>'bool'],
    'SimpleXMLElement::getName' => ['string'],
    'SimpleXMLElement::getNamespaces' => ['string[]', 'recursive='=>'bool'],
    'SimpleXMLElement::offsetExists' => ['bool', 'offset'=>'int|string'],
    'SimpleXMLElement::offsetGet' => ['SimpleXMLElement', 'offset'=>'int|string'],
    'SimpleXMLElement::offsetSet' => ['void', 'offset'=>'int|string', 'value'=>'mixed'],
    'SimpleXMLElement::offsetUnset' => ['void', 'offset'=>'int|string'],
    'SimpleXMLElement::registerXPathNamespace' => ['bool', 'prefix'=>'string', 'ns'=>'string'],
    'SimpleXMLElement::saveXML' => ['string|bool', 'filename='=>'string'],
    'SimpleXMLElement::xpath' => ['SimpleXMLElement[]|false', 'path'=>'string'],
    'SimpleXMLIterator::current' => ['?SimpleXMLIterator'],
    'SimpleXMLIterator::getChildren' => ['?SimpleXMLIterator'],
    'SimpleXMLIterator::hasChildren' => ['bool'],
    'SimpleXMLIterator::key' => ['string|false'],
    'SimpleXMLIterator::next' => ['void'],
    'SimpleXMLIterator::rewind' => ['void'],
    'SimpleXMLIterator::valid' => ['bool'],
    'SoapClient::SoapClient' => ['object', 'wsdl'=>'mixed', 'options='=>'array|null'],
    'SoapClient::__call' => ['', 'function_name'=>'string', 'arguments'=>'array'],
    'SoapClient::__construct' => ['void', 'wsdl'=>'mixed', 'options='=>'array|null'],
    'SoapClient::__doRequest' => ['?string', 'request'=>'string', 'location'=>'string', 'action'=>'string', 'version'=>'int', 'one_way='=>'int'],
    'SoapClient::__getCookies' => ['array'],
    'SoapClient::__getFunctions' => ['?array'],
    'SoapClient::__getLastRequest' => ['?string'],
    'SoapClient::__getLastRequestHeaders' => ['?string'],
    'SoapClient::__getLastResponse' => ['?string'],
    'SoapClient::__getLastResponseHeaders' => ['?string'],
    'SoapClient::__getTypes' => ['?array'],
    'SoapClient::__setCookie' => ['', 'name'=>'string', 'value='=>'string'],
    'SoapClient::__setLocation' => ['string', 'new_location='=>'string'],
    'SoapClient::__setSoapHeaders' => ['bool', 'soapheaders='=>''],
    'SoapClient::__soapCall' => ['', 'function_name'=>'string', 'arguments'=>'array', 'options='=>'array', 'input_headers='=>'SoapHeader|array', '&w_output_headers='=>'array'],
    'SoapFault::SoapFault' => ['object', 'faultcode'=>'string', 'faultstring'=>'string', 'faultactor='=>'?string', 'detail='=>'?mixed', 'faultname='=>'?string', 'headerfault='=>'?mixed'],
    'SoapFault::__clone' => ['void'],
    'SoapFault::__construct' => ['void', 'code'=>'array|string|null', 'string'=>'string', 'actor='=>'?string', 'details='=>'?mixed', 'name='=>'?string', 'headerFault='=>'?mixed'],
    'SoapFault::__toString' => ['string'],
    'SoapFault::__wakeup' => ['void'],
    'SoapFault::getCode' => ['int'],
    'SoapFault::getFile' => ['string'],
    'SoapFault::getLine' => ['int'],
    'SoapFault::getMessage' => ['string'],
    'SoapFault::getPrevious' => ['?Exception|?Throwable'],
    'SoapFault::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'SoapFault::getTraceAsString' => ['string'],
    'SoapHeader::SoapHeader' => ['object', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'],
    'SoapHeader::__construct' => ['void', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'],
    'SoapParam::SoapParam' => ['object', 'data'=>'mixed', 'name'=>'string'],
    'SoapParam::__construct' => ['void', 'data'=>'mixed', 'name'=>'string'],
    'SoapServer::SoapServer' => ['object', 'wsdl'=>'?string', 'options='=>'array'],
    'SoapServer::__construct' => ['void', 'wsdl'=>'?string', 'options='=>'array'],
    'SoapServer::addFunction' => ['void', 'functions'=>'mixed'],
    'SoapServer::addSoapHeader' => ['void', 'object'=>'SoapHeader'],
    'SoapServer::fault' => ['void', 'code'=>'string', 'string'=>'string', 'actor='=>'string', 'details='=>'string', 'name='=>'string'],
    'SoapServer::getFunctions' => ['array'],
    'SoapServer::handle' => ['void', 'soap_request='=>'string'],
    'SoapServer::setClass' => ['void', 'class_name'=>'string', '...args='=>'mixed'],
    'SoapServer::setObject' => ['void', 'object'=>'object'],
    'SoapServer::setPersistence' => ['void', 'mode'=>'int'],
    'SoapVar::SoapVar' => ['object', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string|null', 'type_namespace='=>'string|null', 'node_name='=>'string|null', 'node_namespace='=>'string|null'],
    'SoapVar::__construct' => ['void', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string|null', 'type_namespace='=>'string|null', 'node_name='=>'string|null', 'node_namespace='=>'string|null'],
    'Sodium\add' => ['void', '&left'=>'string', 'right'=>'string'],
    'Sodium\bin2hex' => ['string', 'binary'=>'string'],
    'Sodium\compare' => ['int', 'left'=>'string', 'right'=>'string'],
    'Sodium\crypto_aead_aes256gcm_decrypt' => ['string|false', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_aead_aes256gcm_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_aead_aes256gcm_is_available' => ['bool'],
    'Sodium\crypto_aead_chacha20poly1305_decrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_aead_chacha20poly1305_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_auth' => ['string', 'msg'=>'string', 'key'=>'string'],
    'Sodium\crypto_auth_verify' => ['bool', 'mac'=>'string', 'msg'=>'string', 'key'=>'string'],
    'Sodium\crypto_box' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'],
    'Sodium\crypto_box_keypair' => ['string'],
    'Sodium\crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_box_open' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'],
    'Sodium\crypto_box_publickey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_box_publickey_from_secretkey' => ['string', 'secretkey'=>'string'],
    'Sodium\crypto_box_seal' => ['string', 'message'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_box_seal_open' => ['string', 'encrypted'=>'string', 'keypair'=>'string'],
    'Sodium\crypto_box_secretkey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_box_seed_keypair' => ['string', 'seed'=>'string'],
    'Sodium\crypto_generichash' => ['string', 'input'=>'string', 'key='=>'string', 'length='=>'int'],
    'Sodium\crypto_generichash_final' => ['string', 'state'=>'string', 'length='=>'int'],
    'Sodium\crypto_generichash_init' => ['string', 'key='=>'string', 'length='=>'int'],
    'Sodium\crypto_generichash_update' => ['bool', '&hashState'=>'string', 'append'=>'string'],
    'Sodium\crypto_kx' => ['string', 'secretkey'=>'string', 'publickey'=>'string', 'client_publickey'=>'string', 'server_publickey'=>'string'],
    'Sodium\crypto_pwhash' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_scryptsalsa208sha256' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'],
    'Sodium\crypto_pwhash_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'],
    'Sodium\crypto_scalarmult' => ['string', 'ecdhA'=>'string', 'ecdhB'=>'string'],
    'Sodium\crypto_scalarmult_base' => ['string', 'sk'=>'string'],
    'Sodium\crypto_secretbox' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\crypto_secretbox_open' => ['string', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'],
    'Sodium\crypto_sign' => ['string', 'message'=>'string', 'secretkey'=>'string'],
    'Sodium\crypto_sign_detached' => ['string', 'message'=>'string', 'secretkey'=>'string'],
    'Sodium\crypto_sign_ed25519_pk_to_curve25519' => ['string', 'sign_pk'=>'string'],
    'Sodium\crypto_sign_ed25519_sk_to_curve25519' => ['string', 'sign_sk'=>'string'],
    'Sodium\crypto_sign_keypair' => ['string'],
    'Sodium\crypto_sign_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_sign_open' => ['string|false', 'signed_message'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_sign_publickey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_sign_publickey_from_secretkey' => ['string', 'secretkey'=>'string'],
    'Sodium\crypto_sign_secretkey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_sign_seed_keypair' => ['string', 'seed'=>'string'],
    'Sodium\crypto_sign_verify_detached' => ['bool', 'signature'=>'string', 'msg'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\crypto_stream_xor' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\hex2bin' => ['string', 'hex'=>'string'],
    'Sodium\increment' => ['string', '&nonce'=>'string'],
    'Sodium\library_version_major' => ['int'],
    'Sodium\library_version_minor' => ['int'],
    'Sodium\memcmp' => ['int', 'left'=>'string', 'right'=>'string'],
    'Sodium\memzero' => ['void', '&target'=>'string'],
    'Sodium\randombytes_buf' => ['string', 'length'=>'int'],
    'Sodium\randombytes_random16' => ['int|string'],
    'Sodium\randombytes_uniform' => ['int', 'upperBoundNonInclusive'=>'int'],
    'Sodium\version_string' => ['string'],
    'SolrClient::__construct' => ['void', 'clientOptions'=>'array'],
    'SolrClient::__destruct' => ['void'],
    'SolrClient::addDocument' => ['SolrUpdateResponse', 'doc'=>'SolrInputDocument', 'allowdups='=>'bool', 'commitwithin='=>'int'],
    'SolrClient::addDocuments' => ['SolrUpdateResponse', 'docs'=>'array', 'allowdups='=>'bool', 'commitwithin='=>'int'],
    'SolrClient::commit' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'],
    'SolrClient::deleteById' => ['SolrUpdateResponse', 'id'=>'string'],
    'SolrClient::deleteByIds' => ['SolrUpdateResponse', 'ids'=>'array'],
    'SolrClient::deleteByQueries' => ['SolrUpdateResponse', 'queries'=>'array'],
    'SolrClient::deleteByQuery' => ['SolrUpdateResponse', 'query'=>'string'],
    'SolrClient::getById' => ['SolrQueryResponse', 'id'=>'string'],
    'SolrClient::getByIds' => ['SolrQueryResponse', 'ids'=>'array'],
    'SolrClient::getDebug' => ['string'],
    'SolrClient::getOptions' => ['array'],
    'SolrClient::optimize' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'],
    'SolrClient::ping' => ['SolrPingResponse'],
    'SolrClient::query' => ['SolrQueryResponse', 'query'=>'SolrParams'],
    'SolrClient::request' => ['SolrUpdateResponse', 'raw_request'=>'string'],
    'SolrClient::rollback' => ['SolrUpdateResponse'],
    'SolrClient::setResponseWriter' => ['void', 'responsewriter'=>'string'],
    'SolrClient::setServlet' => ['bool', 'type'=>'int', 'value'=>'string'],
    'SolrClient::system' => ['SolrGenericResponse'],
    'SolrClient::threads' => ['SolrGenericResponse'],
    'SolrClientException::__clone' => ['void'],
    'SolrClientException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'SolrClientException::__toString' => ['string'],
    'SolrClientException::__wakeup' => ['void'],
    'SolrClientException::getCode' => ['int'],
    'SolrClientException::getFile' => ['string'],
    'SolrClientException::getInternalInfo' => ['array'],
    'SolrClientException::getLine' => ['int'],
    'SolrClientException::getMessage' => ['string'],
    'SolrClientException::getPrevious' => ['?Exception|?Throwable'],
    'SolrClientException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'SolrClientException::getTraceAsString' => ['string'],
    'SolrCollapseFunction::__construct' => ['void', 'field'=>'string'],
    'SolrCollapseFunction::__toString' => ['string'],
    'SolrCollapseFunction::getField' => ['string'],
    'SolrCollapseFunction::getHint' => ['string'],
    'SolrCollapseFunction::getMax' => ['string'],
    'SolrCollapseFunction::getMin' => ['string'],
    'SolrCollapseFunction::getNullPolicy' => ['string'],
    'SolrCollapseFunction::getSize' => ['int'],
    'SolrCollapseFunction::setField' => ['SolrCollapseFunction', 'fieldName'=>'string'],
    'SolrCollapseFunction::setHint' => ['SolrCollapseFunction', 'hint'=>'string'],
    'SolrCollapseFunction::setMax' => ['SolrCollapseFunction', 'max'=>'string'],
    'SolrCollapseFunction::setMin' => ['SolrCollapseFunction', 'min'=>'string'],
    'SolrCollapseFunction::setNullPolicy' => ['SolrCollapseFunction', 'nullPolicy'=>'string'],
    'SolrCollapseFunction::setSize' => ['SolrCollapseFunction', 'size'=>'int'],
    'SolrDisMaxQuery::__construct' => ['void', 'q='=>'string'],
    'SolrDisMaxQuery::__destruct' => ['void'],
    'SolrDisMaxQuery::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
    'SolrDisMaxQuery::addBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'],
    'SolrDisMaxQuery::addBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string', 'value'=>'string', 'boost='=>'string'],
    'SolrDisMaxQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrDisMaxQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'string'],
    'SolrDisMaxQuery::addFacetDateField' => ['SolrQuery', 'dateField'=>'string'],
    'SolrDisMaxQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::addFacetField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::addFacetQuery' => ['SolrQuery', 'facetQuery'=>'string'],
    'SolrDisMaxQuery::addField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrDisMaxQuery::addGroupField' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'int'],
    'SolrDisMaxQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::addMltField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'],
    'SolrDisMaxQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
    'SolrDisMaxQuery::addPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'],
    'SolrDisMaxQuery::addQueryField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost='=>'string'],
    'SolrDisMaxQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'],
    'SolrDisMaxQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::addStatsField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::addTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'],
    'SolrDisMaxQuery::addUserField' => ['SolrDisMaxQuery', 'field'=>'string'],
    'SolrDisMaxQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'],
    'SolrDisMaxQuery::get' => ['mixed', 'param_name'=>'string'],
    'SolrDisMaxQuery::getExpand' => ['bool'],
    'SolrDisMaxQuery::getExpandFilterQueries' => ['array'],
    'SolrDisMaxQuery::getExpandQuery' => ['array'],
    'SolrDisMaxQuery::getExpandRows' => ['int'],
    'SolrDisMaxQuery::getExpandSortFields' => ['array'],
    'SolrDisMaxQuery::getFacet' => ['bool'],
    'SolrDisMaxQuery::getFacetDateEnd' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetDateFields' => ['array'],
    'SolrDisMaxQuery::getFacetDateGap' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetDateHardEnd' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetDateOther' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetDateStart' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetFields' => ['array'],
    'SolrDisMaxQuery::getFacetLimit' => ['int', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetMethod' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetMinCount' => ['int', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetMissing' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetOffset' => ['int', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetPrefix' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFacetQueries' => ['string'],
    'SolrDisMaxQuery::getFacetSort' => ['int', 'field_override'=>'string'],
    'SolrDisMaxQuery::getFields' => ['string'],
    'SolrDisMaxQuery::getFilterQueries' => ['string'],
    'SolrDisMaxQuery::getGroup' => ['bool'],
    'SolrDisMaxQuery::getGroupCachePercent' => ['int'],
    'SolrDisMaxQuery::getGroupFacet' => ['bool'],
    'SolrDisMaxQuery::getGroupFields' => ['array'],
    'SolrDisMaxQuery::getGroupFormat' => ['string'],
    'SolrDisMaxQuery::getGroupFunctions' => ['array'],
    'SolrDisMaxQuery::getGroupLimit' => ['int'],
    'SolrDisMaxQuery::getGroupMain' => ['bool'],
    'SolrDisMaxQuery::getGroupNGroups' => ['bool'],
    'SolrDisMaxQuery::getGroupOffset' => ['bool'],
    'SolrDisMaxQuery::getGroupQueries' => ['array'],
    'SolrDisMaxQuery::getGroupSortFields' => ['array'],
    'SolrDisMaxQuery::getGroupTruncate' => ['bool'],
    'SolrDisMaxQuery::getHighlight' => ['bool'],
    'SolrDisMaxQuery::getHighlightAlternateField' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightFields' => ['array'],
    'SolrDisMaxQuery::getHighlightFormatter' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightFragmenter' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightFragsize' => ['int', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightHighlightMultiTerm' => ['bool'],
    'SolrDisMaxQuery::getHighlightMaxAlternateFieldLength' => ['int', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightMaxAnalyzedChars' => ['int'],
    'SolrDisMaxQuery::getHighlightMergeContiguous' => ['bool', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightRegexMaxAnalyzedChars' => ['int'],
    'SolrDisMaxQuery::getHighlightRegexPattern' => ['string'],
    'SolrDisMaxQuery::getHighlightRegexSlop' => ['float'],
    'SolrDisMaxQuery::getHighlightRequireFieldMatch' => ['bool'],
    'SolrDisMaxQuery::getHighlightSimplePost' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightSimplePre' => ['string', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightSnippets' => ['int', 'field_override'=>'string'],
    'SolrDisMaxQuery::getHighlightUsePhraseHighlighter' => ['bool'],
    'SolrDisMaxQuery::getMlt' => ['bool'],
    'SolrDisMaxQuery::getMltBoost' => ['bool'],
    'SolrDisMaxQuery::getMltCount' => ['int'],
    'SolrDisMaxQuery::getMltFields' => ['array'],
    'SolrDisMaxQuery::getMltMaxNumQueryTerms' => ['int'],
    'SolrDisMaxQuery::getMltMaxNumTokens' => ['int'],
    'SolrDisMaxQuery::getMltMaxWordLength' => ['int'],
    'SolrDisMaxQuery::getMltMinDocFrequency' => ['int'],
    'SolrDisMaxQuery::getMltMinTermFrequency' => ['int'],
    'SolrDisMaxQuery::getMltMinWordLength' => ['int'],
    'SolrDisMaxQuery::getMltQueryFields' => ['array'],
    'SolrDisMaxQuery::getParam' => ['mixed', 'param_name'=>'string'],
    'SolrDisMaxQuery::getParams' => ['array'],
    'SolrDisMaxQuery::getPreparedParams' => ['array'],
    'SolrDisMaxQuery::getQuery' => ['string'],
    'SolrDisMaxQuery::getRows' => ['int'],
    'SolrDisMaxQuery::getSortFields' => ['array'],
    'SolrDisMaxQuery::getStart' => ['int'],
    'SolrDisMaxQuery::getStats' => ['bool'],
    'SolrDisMaxQuery::getStatsFacets' => ['array'],
    'SolrDisMaxQuery::getStatsFields' => ['array'],
    'SolrDisMaxQuery::getTerms' => ['bool'],
    'SolrDisMaxQuery::getTermsField' => ['string'],
    'SolrDisMaxQuery::getTermsIncludeLowerBound' => ['bool'],
    'SolrDisMaxQuery::getTermsIncludeUpperBound' => ['bool'],
    'SolrDisMaxQuery::getTermsLimit' => ['int'],
    'SolrDisMaxQuery::getTermsLowerBound' => ['string'],
    'SolrDisMaxQuery::getTermsMaxCount' => ['int'],
    'SolrDisMaxQuery::getTermsMinCount' => ['int'],
    'SolrDisMaxQuery::getTermsPrefix' => ['string'],
    'SolrDisMaxQuery::getTermsReturnRaw' => ['bool'],
    'SolrDisMaxQuery::getTermsSort' => ['int'],
    'SolrDisMaxQuery::getTermsUpperBound' => ['string'],
    'SolrDisMaxQuery::getTimeAllowed' => ['int'],
    'SolrDisMaxQuery::removeBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrDisMaxQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::removeField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrDisMaxQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeMltField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeMltQueryField' => ['SolrQuery', 'queryField'=>'string'],
    'SolrDisMaxQuery::removePhraseField' => ['SolrDisMaxQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeQueryField' => ['SolrDisMaxQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeSortField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'],
    'SolrDisMaxQuery::removeUserField' => ['SolrDisMaxQuery', 'field'=>'string'],
    'SolrDisMaxQuery::serialize' => ['string'],
    'SolrDisMaxQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''],
    'SolrDisMaxQuery::setBigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
    'SolrDisMaxQuery::setBigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
    'SolrDisMaxQuery::setBoostFunction' => ['SolrDisMaxQuery', 'function'=>'string'],
    'SolrDisMaxQuery::setBoostQuery' => ['SolrDisMaxQuery', 'q'=>'string'],
    'SolrDisMaxQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'],
    'SolrDisMaxQuery::setExpand' => ['SolrQuery', 'value'=>'bool'],
    'SolrDisMaxQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'],
    'SolrDisMaxQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'],
    'SolrDisMaxQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'],
    'SolrDisMaxQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setFacetSort' => ['SolrQuery', 'facetSort'=>'int', 'field_override'=>'string'],
    'SolrDisMaxQuery::setGroup' => ['SolrQuery', 'value'=>'bool'],
    'SolrDisMaxQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'],
    'SolrDisMaxQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'],
    'SolrDisMaxQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'],
    'SolrDisMaxQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'],
    'SolrDisMaxQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'],
    'SolrDisMaxQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'],
    'SolrDisMaxQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldLength'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'],
    'SolrDisMaxQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxAnalyzedChars'=>'int'],
    'SolrDisMaxQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'],
    'SolrDisMaxQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'],
    'SolrDisMaxQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setHighlightSimplePost' => ['SolrQuery', 'simplePost'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightSimplePre' => ['SolrQuery', 'simplePre'=>'string', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override'=>'string'],
    'SolrDisMaxQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setMinimumMatch' => ['SolrDisMaxQuery', 'value'=>'string'],
    'SolrDisMaxQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setMltCount' => ['SolrQuery', 'count'=>'int'],
    'SolrDisMaxQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'],
    'SolrDisMaxQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'],
    'SolrDisMaxQuery::setMltMaxWordLength' => ['SolrQuery', 'maxWordLength'=>'int'],
    'SolrDisMaxQuery::setMltMinDocFrequency' => ['SolrQuery', 'minDocFrequency'=>'int'],
    'SolrDisMaxQuery::setMltMinTermFrequency' => ['SolrQuery', 'minTermFrequency'=>'int'],
    'SolrDisMaxQuery::setMltMinWordLength' => ['SolrQuery', 'minWordLength'=>'int'],
    'SolrDisMaxQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''],
    'SolrDisMaxQuery::setPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
    'SolrDisMaxQuery::setPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
    'SolrDisMaxQuery::setQuery' => ['SolrQuery', 'query'=>'string'],
    'SolrDisMaxQuery::setQueryAlt' => ['SolrDisMaxQuery', 'q'=>'string'],
    'SolrDisMaxQuery::setQueryPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
    'SolrDisMaxQuery::setRows' => ['SolrQuery', 'rows'=>'int'],
    'SolrDisMaxQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setStart' => ['SolrQuery', 'start'=>'int'],
    'SolrDisMaxQuery::setStats' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'],
    'SolrDisMaxQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'],
    'SolrDisMaxQuery::setTermsLowerBound' => ['SolrQuery', 'lowerBound'=>'string'],
    'SolrDisMaxQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'],
    'SolrDisMaxQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'],
    'SolrDisMaxQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'],
    'SolrDisMaxQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'],
    'SolrDisMaxQuery::setTermsSort' => ['SolrQuery', 'sortType'=>'int'],
    'SolrDisMaxQuery::setTermsUpperBound' => ['SolrQuery', 'upperBound'=>'string'],
    'SolrDisMaxQuery::setTieBreaker' => ['SolrDisMaxQuery', 'tieBreaker'=>'string'],
    'SolrDisMaxQuery::setTimeAllowed' => ['SolrQuery', 'timeAllowed'=>'int'],
    'SolrDisMaxQuery::setTrigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
    'SolrDisMaxQuery::setTrigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
    'SolrDisMaxQuery::setUserFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
    'SolrDisMaxQuery::toString' => ['string', 'url_encode='=>'bool'],
    'SolrDisMaxQuery::unserialize' => ['void', 'serialized'=>'string'],
    'SolrDisMaxQuery::useDisMaxQueryParser' => ['SolrDisMaxQuery'],
    'SolrDisMaxQuery::useEDisMaxQueryParser' => ['SolrDisMaxQuery'],
    'SolrDocument::__clone' => ['void'],
    'SolrDocument::__construct' => ['void'],
    'SolrDocument::__destruct' => ['void'],
    'SolrDocument::__get' => ['SolrDocumentField', 'fieldname'=>'string'],
    'SolrDocument::__isset' => ['bool', 'fieldname'=>'string'],
    'SolrDocument::__set' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'],
    'SolrDocument::__unset' => ['bool', 'fieldname'=>'string'],
    'SolrDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'],
    'SolrDocument::clear' => ['bool'],
    'SolrDocument::current' => ['SolrDocumentField'],
    'SolrDocument::deleteField' => ['bool', 'fieldname'=>'string'],
    'SolrDocument::fieldExists' => ['bool', 'fieldname'=>'string'],
    'SolrDocument::getChildDocuments' => ['SolrInputDocument[]'],
    'SolrDocument::getChildDocumentsCount' => ['int'],
    'SolrDocument::getField' => ['SolrDocumentField|false', 'fieldname'=>'string'],
    'SolrDocument::getFieldCount' => ['int|false'],
    'SolrDocument::getFieldNames' => ['array|false'],
    'SolrDocument::getInputDocument' => ['SolrInputDocument'],
    'SolrDocument::hasChildDocuments' => ['bool'],
    'SolrDocument::key' => ['string'],
    'SolrDocument::merge' => ['bool', 'sourcedoc'=>'solrdocument', 'overwrite='=>'bool'],
    'SolrDocument::next' => ['void'],
    'SolrDocument::offsetExists' => ['bool', 'fieldname'=>'string'],
    'SolrDocument::offsetGet' => ['SolrDocumentField', 'fieldname'=>'string'],
    'SolrDocument::offsetSet' => ['void', 'fieldname'=>'string', 'fieldvalue'=>'string'],
    'SolrDocument::offsetUnset' => ['void', 'fieldname'=>'string'],
    'SolrDocument::reset' => ['bool'],
    'SolrDocument::rewind' => ['void'],
    'SolrDocument::serialize' => ['string'],
    'SolrDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'],
    'SolrDocument::toArray' => ['array'],
    'SolrDocument::unserialize' => ['void', 'serialized'=>'string'],
    'SolrDocument::valid' => ['bool'],
    'SolrDocumentField::__construct' => ['void'],
    'SolrDocumentField::__destruct' => ['void'],
    'SolrException::__clone' => ['void'],
    'SolrException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'SolrException::__toString' => ['string'],
    'SolrException::__wakeup' => ['void'],
    'SolrException::getCode' => ['int'],
    'SolrException::getFile' => ['string'],
    'SolrException::getInternalInfo' => ['array'],
    'SolrException::getLine' => ['int'],
    'SolrException::getMessage' => ['string'],
    'SolrException::getPrevious' => ['Exception|Throwable'],
    'SolrException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'SolrException::getTraceAsString' => ['string'],
    'SolrGenericResponse::__construct' => ['void'],
    'SolrGenericResponse::__destruct' => ['void'],
    'SolrGenericResponse::getDigestedResponse' => ['string'],
    'SolrGenericResponse::getHttpStatus' => ['int'],
    'SolrGenericResponse::getHttpStatusMessage' => ['string'],
    'SolrGenericResponse::getRawRequest' => ['string'],
    'SolrGenericResponse::getRawRequestHeaders' => ['string'],
    'SolrGenericResponse::getRawResponse' => ['string'],
    'SolrGenericResponse::getRawResponseHeaders' => ['string'],
    'SolrGenericResponse::getRequestUrl' => ['string'],
    'SolrGenericResponse::getResponse' => ['SolrObject'],
    'SolrGenericResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
    'SolrGenericResponse::success' => ['bool'],
    'SolrIllegalArgumentException::__clone' => ['void'],
    'SolrIllegalArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'SolrIllegalArgumentException::__toString' => ['string'],
    'SolrIllegalArgumentException::__wakeup' => ['void'],
    'SolrIllegalArgumentException::getCode' => ['int'],
    'SolrIllegalArgumentException::getFile' => ['string'],
    'SolrIllegalArgumentException::getInternalInfo' => ['array'],
    'SolrIllegalArgumentException::getLine' => ['int'],
    'SolrIllegalArgumentException::getMessage' => ['string'],
    'SolrIllegalArgumentException::getPrevious' => ['Exception|Throwable'],
    'SolrIllegalArgumentException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'SolrIllegalArgumentException::getTraceAsString' => ['string'],
    'SolrIllegalOperationException::__clone' => ['void'],
    'SolrIllegalOperationException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'SolrIllegalOperationException::__toString' => ['string'],
    'SolrIllegalOperationException::__wakeup' => ['void'],
    'SolrIllegalOperationException::getCode' => ['int'],
    'SolrIllegalOperationException::getFile' => ['string'],
    'SolrIllegalOperationException::getInternalInfo' => ['array'],
    'SolrIllegalOperationException::getLine' => ['int'],
    'SolrIllegalOperationException::getMessage' => ['string'],
    'SolrIllegalOperationException::getPrevious' => ['Exception|Throwable'],
    'SolrIllegalOperationException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'SolrIllegalOperationException::getTraceAsString' => ['string'],
    'SolrInputDocument::__clone' => ['void'],
    'SolrInputDocument::__construct' => ['void'],
    'SolrInputDocument::__destruct' => ['void'],
    'SolrInputDocument::addChildDocument' => ['void', 'child'=>'SolrInputDocument'],
    'SolrInputDocument::addChildDocuments' => ['void', 'docs'=>'array'],
    'SolrInputDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string', 'fieldboostvalue='=>'float'],
    'SolrInputDocument::clear' => ['bool'],
    'SolrInputDocument::deleteField' => ['bool', 'fieldname'=>'string'],
    'SolrInputDocument::fieldExists' => ['bool', 'fieldname'=>'string'],
    'SolrInputDocument::getBoost' => ['float|false'],
    'SolrInputDocument::getChildDocuments' => ['SolrInputDocument[]'],
    'SolrInputDocument::getChildDocumentsCount' => ['int'],
    'SolrInputDocument::getField' => ['SolrDocumentField|false', 'fieldname'=>'string'],
    'SolrInputDocument::getFieldBoost' => ['float|false', 'fieldname'=>'string'],
    'SolrInputDocument::getFieldCount' => ['int|false'],
    'SolrInputDocument::getFieldNames' => ['array|false'],
    'SolrInputDocument::hasChildDocuments' => ['bool'],
    'SolrInputDocument::merge' => ['bool', 'sourcedoc'=>'SolrInputDocument', 'overwrite='=>'bool'],
    'SolrInputDocument::reset' => ['bool'],
    'SolrInputDocument::setBoost' => ['bool', 'documentboostvalue'=>'float'],
    'SolrInputDocument::setFieldBoost' => ['bool', 'fieldname'=>'string', 'fieldboostvalue'=>'float'],
    'SolrInputDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'],
    'SolrInputDocument::toArray' => ['array|false'],
    'SolrModifiableParams::__construct' => ['void'],
    'SolrModifiableParams::__destruct' => ['void'],
    'SolrModifiableParams::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
    'SolrModifiableParams::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
    'SolrModifiableParams::get' => ['mixed', 'param_name'=>'string'],
    'SolrModifiableParams::getParam' => ['mixed', 'param_name'=>'string'],
    'SolrModifiableParams::getParams' => ['array'],
    'SolrModifiableParams::getPreparedParams' => ['array'],
    'SolrModifiableParams::serialize' => ['string'],
    'SolrModifiableParams::set' => ['SolrParams', 'name'=>'string', 'value'=>''],
    'SolrModifiableParams::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''],
    'SolrModifiableParams::toString' => ['string', 'url_encode='=>'bool'],
    'SolrModifiableParams::unserialize' => ['void', 'serialized'=>'string'],
    'SolrObject::__construct' => ['void'],
    'SolrObject::__destruct' => ['void'],
    'SolrObject::getPropertyNames' => ['array'],
    'SolrObject::offsetExists' => ['bool', 'property_name'=>'string'],
    'SolrObject::offsetGet' => ['SolrDocumentField', 'property_name'=>'string'],
    'SolrObject::offsetSet' => ['void', 'property_name'=>'string', 'property_value'=>'string'],
    'SolrObject::offsetUnset' => ['void', 'property_name'=>'string'],
    'SolrParams::__construct' => ['void'],
    'SolrParams::add' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
    'SolrParams::addParam' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
    'SolrParams::get' => ['mixed', 'param_name'=>'string'],
    'SolrParams::getParam' => ['mixed', 'param_name='=>'string'],
    'SolrParams::getParams' => ['array'],
    'SolrParams::getPreparedParams' => ['array'],
    'SolrParams::serialize' => ['string'],
    'SolrParams::set' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
    'SolrParams::setParam' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
    'SolrParams::toString' => ['string|false', 'url_encode='=>'bool'],
    'SolrParams::unserialize' => ['void', 'serialized'=>'string'],
    'SolrPingResponse::__construct' => ['void'],
    'SolrPingResponse::__destruct' => ['void'],
    'SolrPingResponse::getDigestedResponse' => ['string'],
    'SolrPingResponse::getHttpStatus' => ['int'],
    'SolrPingResponse::getHttpStatusMessage' => ['string'],
    'SolrPingResponse::getRawRequest' => ['string'],
    'SolrPingResponse::getRawRequestHeaders' => ['string'],
    'SolrPingResponse::getRawResponse' => ['string'],
    'SolrPingResponse::getRawResponseHeaders' => ['string'],
    'SolrPingResponse::getRequestUrl' => ['string'],
    'SolrPingResponse::getResponse' => ['string'],
    'SolrPingResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
    'SolrPingResponse::success' => ['bool'],
    'SolrQuery::__construct' => ['void', 'q='=>'string'],
    'SolrQuery::__destruct' => ['void'],
    'SolrQuery::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
    'SolrQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'string'],
    'SolrQuery::addFacetDateField' => ['SolrQuery', 'datefield'=>'string'],
    'SolrQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
    'SolrQuery::addFacetField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::addFacetQuery' => ['SolrQuery', 'facetquery'=>'string'],
    'SolrQuery::addField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrQuery::addGroupField' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'],
    'SolrQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::addMltField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'],
    'SolrQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
    'SolrQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'],
    'SolrQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::addStatsField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'],
    'SolrQuery::get' => ['mixed', 'param_name'=>'string'],
    'SolrQuery::getExpand' => ['bool'],
    'SolrQuery::getExpandFilterQueries' => ['array'],
    'SolrQuery::getExpandQuery' => ['array'],
    'SolrQuery::getExpandRows' => ['int'],
    'SolrQuery::getExpandSortFields' => ['array'],
    'SolrQuery::getFacet' => ['?bool'],
    'SolrQuery::getFacetDateEnd' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getFacetDateFields' => ['array'],
    'SolrQuery::getFacetDateGap' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getFacetDateHardEnd' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getFacetDateOther' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getFacetDateStart' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getFacetFields' => ['array'],
    'SolrQuery::getFacetLimit' => ['?int', 'field_override='=>'string'],
    'SolrQuery::getFacetMethod' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getFacetMinCount' => ['?int', 'field_override='=>'string'],
    'SolrQuery::getFacetMissing' => ['?bool', 'field_override='=>'string'],
    'SolrQuery::getFacetOffset' => ['?int', 'field_override='=>'string'],
    'SolrQuery::getFacetPrefix' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getFacetQueries' => ['?array'],
    'SolrQuery::getFacetSort' => ['int', 'field_override='=>'string'],
    'SolrQuery::getFields' => ['?array'],
    'SolrQuery::getFilterQueries' => ['?array'],
    'SolrQuery::getGroup' => ['bool'],
    'SolrQuery::getGroupCachePercent' => ['int'],
    'SolrQuery::getGroupFacet' => ['bool'],
    'SolrQuery::getGroupFields' => ['array'],
    'SolrQuery::getGroupFormat' => ['string'],
    'SolrQuery::getGroupFunctions' => ['array'],
    'SolrQuery::getGroupLimit' => ['int'],
    'SolrQuery::getGroupMain' => ['bool'],
    'SolrQuery::getGroupNGroups' => ['bool'],
    'SolrQuery::getGroupOffset' => ['int'],
    'SolrQuery::getGroupQueries' => ['array'],
    'SolrQuery::getGroupSortFields' => ['array'],
    'SolrQuery::getGroupTruncate' => ['bool'],
    'SolrQuery::getHighlight' => ['bool'],
    'SolrQuery::getHighlightAlternateField' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getHighlightFields' => ['?array'],
    'SolrQuery::getHighlightFormatter' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getHighlightFragmenter' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getHighlightFragsize' => ['?int', 'field_override='=>'string'],
    'SolrQuery::getHighlightHighlightMultiTerm' => ['?bool'],
    'SolrQuery::getHighlightMaxAlternateFieldLength' => ['?int', 'field_override='=>'string'],
    'SolrQuery::getHighlightMaxAnalyzedChars' => ['?int'],
    'SolrQuery::getHighlightMergeContiguous' => ['?bool', 'field_override='=>'string'],
    'SolrQuery::getHighlightRegexMaxAnalyzedChars' => ['?int'],
    'SolrQuery::getHighlightRegexPattern' => ['?string'],
    'SolrQuery::getHighlightRegexSlop' => ['?float'],
    'SolrQuery::getHighlightRequireFieldMatch' => ['?bool'],
    'SolrQuery::getHighlightSimplePost' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getHighlightSimplePre' => ['?string', 'field_override='=>'string'],
    'SolrQuery::getHighlightSnippets' => ['?int', 'field_override='=>'string'],
    'SolrQuery::getHighlightUsePhraseHighlighter' => ['?bool'],
    'SolrQuery::getMlt' => ['?bool'],
    'SolrQuery::getMltBoost' => ['?bool'],
    'SolrQuery::getMltCount' => ['?int'],
    'SolrQuery::getMltFields' => ['?array'],
    'SolrQuery::getMltMaxNumQueryTerms' => ['?int'],
    'SolrQuery::getMltMaxNumTokens' => ['?int'],
    'SolrQuery::getMltMaxWordLength' => ['?int'],
    'SolrQuery::getMltMinDocFrequency' => ['?int'],
    'SolrQuery::getMltMinTermFrequency' => ['?int'],
    'SolrQuery::getMltMinWordLength' => ['?int'],
    'SolrQuery::getMltQueryFields' => ['?array'],
    'SolrQuery::getParam' => ['?mixed', 'param_name'=>'string'],
    'SolrQuery::getParams' => ['?array'],
    'SolrQuery::getPreparedParams' => ['?array'],
    'SolrQuery::getQuery' => ['?string'],
    'SolrQuery::getRows' => ['?int'],
    'SolrQuery::getSortFields' => ['?array'],
    'SolrQuery::getStart' => ['?int'],
    'SolrQuery::getStats' => ['?bool'],
    'SolrQuery::getStatsFacets' => ['?array'],
    'SolrQuery::getStatsFields' => ['?array'],
    'SolrQuery::getTerms' => ['?bool'],
    'SolrQuery::getTermsField' => ['?string'],
    'SolrQuery::getTermsIncludeLowerBound' => ['?bool'],
    'SolrQuery::getTermsIncludeUpperBound' => ['?bool'],
    'SolrQuery::getTermsLimit' => ['?int'],
    'SolrQuery::getTermsLowerBound' => ['?string'],
    'SolrQuery::getTermsMaxCount' => ['?int'],
    'SolrQuery::getTermsMinCount' => ['?int'],
    'SolrQuery::getTermsPrefix' => ['?string'],
    'SolrQuery::getTermsReturnRaw' => ['?bool'],
    'SolrQuery::getTermsSort' => ['?int'],
    'SolrQuery::getTermsUpperBound' => ['?string'],
    'SolrQuery::getTimeAllowed' => ['?int'],
    'SolrQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
    'SolrQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::removeField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'],
    'SolrQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::removeMltField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::removeMltQueryField' => ['SolrQuery', 'queryfield'=>'string'],
    'SolrQuery::removeSortField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'],
    'SolrQuery::serialize' => ['string'],
    'SolrQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''],
    'SolrQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'],
    'SolrQuery::setExpand' => ['SolrQuery', 'value'=>'bool'],
    'SolrQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'],
    'SolrQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'],
    'SolrQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'],
    'SolrQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
    'SolrQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
    'SolrQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'bool', 'field_override='=>'string'],
    'SolrQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
    'SolrQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override='=>'string'],
    'SolrQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override='=>'string'],
    'SolrQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override='=>'string'],
    'SolrQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override='=>'string'],
    'SolrQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'],
    'SolrQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override='=>'string'],
    'SolrQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override='=>'string'],
    'SolrQuery::setFacetSort' => ['SolrQuery', 'facetsort'=>'int', 'field_override='=>'string'],
    'SolrQuery::setGroup' => ['SolrQuery', 'value'=>'bool'],
    'SolrQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'],
    'SolrQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'],
    'SolrQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'],
    'SolrQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'],
    'SolrQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'],
    'SolrQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'],
    'SolrQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override='=>'string'],
    'SolrQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override='=>'string'],
    'SolrQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override='=>'string'],
    'SolrQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override='=>'string'],
    'SolrQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldlength'=>'int', 'field_override='=>'string'],
    'SolrQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'],
    'SolrQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'],
    'SolrQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxanalyzedchars'=>'int'],
    'SolrQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'],
    'SolrQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'],
    'SolrQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setHighlightSimplePost' => ['SolrQuery', 'simplepost'=>'string', 'field_override='=>'string'],
    'SolrQuery::setHighlightSimplePre' => ['SolrQuery', 'simplepre'=>'string', 'field_override='=>'string'],
    'SolrQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override='=>'string'],
    'SolrQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setMltCount' => ['SolrQuery', 'count'=>'int'],
    'SolrQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'],
    'SolrQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'],
    'SolrQuery::setMltMaxWordLength' => ['SolrQuery', 'maxwordlength'=>'int'],
    'SolrQuery::setMltMinDocFrequency' => ['SolrQuery', 'mindocfrequency'=>'int'],
    'SolrQuery::setMltMinTermFrequency' => ['SolrQuery', 'mintermfrequency'=>'int'],
    'SolrQuery::setMltMinWordLength' => ['SolrQuery', 'minwordlength'=>'int'],
    'SolrQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''],
    'SolrQuery::setQuery' => ['SolrQuery', 'query'=>'string'],
    'SolrQuery::setRows' => ['SolrQuery', 'rows'=>'int'],
    'SolrQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setStart' => ['SolrQuery', 'start'=>'int'],
    'SolrQuery::setStats' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'],
    'SolrQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'],
    'SolrQuery::setTermsLowerBound' => ['SolrQuery', 'lowerbound'=>'string'],
    'SolrQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'],
    'SolrQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'],
    'SolrQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'],
    'SolrQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'],
    'SolrQuery::setTermsSort' => ['SolrQuery', 'sorttype'=>'int'],
    'SolrQuery::setTermsUpperBound' => ['SolrQuery', 'upperbound'=>'string'],
    'SolrQuery::setTimeAllowed' => ['SolrQuery', 'timeallowed'=>'int'],
    'SolrQuery::toString' => ['string', 'url_encode='=>'bool'],
    'SolrQuery::unserialize' => ['void', 'serialized'=>'string'],
    'SolrQueryResponse::__construct' => ['void'],
    'SolrQueryResponse::__destruct' => ['void'],
    'SolrQueryResponse::getDigestedResponse' => ['string'],
    'SolrQueryResponse::getHttpStatus' => ['int'],
    'SolrQueryResponse::getHttpStatusMessage' => ['string'],
    'SolrQueryResponse::getRawRequest' => ['string'],
    'SolrQueryResponse::getRawRequestHeaders' => ['string'],
    'SolrQueryResponse::getRawResponse' => ['string'],
    'SolrQueryResponse::getRawResponseHeaders' => ['string'],
    'SolrQueryResponse::getRequestUrl' => ['string'],
    'SolrQueryResponse::getResponse' => ['SolrObject'],
    'SolrQueryResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
    'SolrQueryResponse::success' => ['bool'],
    'SolrResponse::getDigestedResponse' => ['string'],
    'SolrResponse::getHttpStatus' => ['int'],
    'SolrResponse::getHttpStatusMessage' => ['string'],
    'SolrResponse::getRawRequest' => ['string'],
    'SolrResponse::getRawRequestHeaders' => ['string'],
    'SolrResponse::getRawResponse' => ['string'],
    'SolrResponse::getRawResponseHeaders' => ['string'],
    'SolrResponse::getRequestUrl' => ['string'],
    'SolrResponse::getResponse' => ['SolrObject'],
    'SolrResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
    'SolrResponse::success' => ['bool'],
    'SolrServerException::__clone' => ['void'],
    'SolrServerException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'SolrServerException::__toString' => ['string'],
    'SolrServerException::__wakeup' => ['void'],
    'SolrServerException::getCode' => ['int'],
    'SolrServerException::getFile' => ['string'],
    'SolrServerException::getInternalInfo' => ['array'],
    'SolrServerException::getLine' => ['int'],
    'SolrServerException::getMessage' => ['string'],
    'SolrServerException::getPrevious' => ['Exception|Throwable'],
    'SolrServerException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'SolrServerException::getTraceAsString' => ['string'],
    'SolrUpdateResponse::__construct' => ['void'],
    'SolrUpdateResponse::__destruct' => ['void'],
    'SolrUpdateResponse::getDigestedResponse' => ['string'],
    'SolrUpdateResponse::getHttpStatus' => ['int'],
    'SolrUpdateResponse::getHttpStatusMessage' => ['string'],
    'SolrUpdateResponse::getRawRequest' => ['string'],
    'SolrUpdateResponse::getRawRequestHeaders' => ['string'],
    'SolrUpdateResponse::getRawResponse' => ['string'],
    'SolrUpdateResponse::getRawResponseHeaders' => ['string'],
    'SolrUpdateResponse::getRequestUrl' => ['string'],
    'SolrUpdateResponse::getResponse' => ['SolrObject'],
    'SolrUpdateResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
    'SolrUpdateResponse::success' => ['bool'],
    'SolrUtils::digestXmlResponse' => ['SolrObject', 'xmlresponse'=>'string', 'parse_mode='=>'int'],
    'SolrUtils::escapeQueryChars' => ['string|false', 'string'=>'string'],
    'SolrUtils::getSolrVersion' => ['string'],
    'SolrUtils::queryPhrase' => ['string', 'string'=>'string'],
    'SphinxClient::__construct' => ['void'],
    'SphinxClient::addQuery' => ['int', 'query'=>'string', 'index='=>'string', 'comment='=>'string'],
    'SphinxClient::buildExcerpts' => ['array', 'docs'=>'array', 'index'=>'string', 'words'=>'string', 'opts='=>'array'],
    'SphinxClient::buildKeywords' => ['array', 'query'=>'string', 'index'=>'string', 'hits'=>'bool'],
    'SphinxClient::close' => ['bool'],
    'SphinxClient::escapeString' => ['string', 'string'=>'string'],
    'SphinxClient::getLastError' => ['string'],
    'SphinxClient::getLastWarning' => ['string'],
    'SphinxClient::open' => ['bool'],
    'SphinxClient::query' => ['array', 'query'=>'string', 'index='=>'string', 'comment='=>'string'],
    'SphinxClient::resetFilters' => ['void'],
    'SphinxClient::resetGroupBy' => ['void'],
    'SphinxClient::runQueries' => ['array'],
    'SphinxClient::setArrayResult' => ['bool', 'array_result'=>'bool'],
    'SphinxClient::setConnectTimeout' => ['bool', 'timeout'=>'float'],
    'SphinxClient::setFieldWeights' => ['bool', 'weights'=>'array'],
    'SphinxClient::setFilter' => ['bool', 'attribute'=>'string', 'values'=>'array', 'exclude='=>'bool'],
    'SphinxClient::setFilterFloatRange' => ['bool', 'attribute'=>'string', 'min'=>'float', 'max'=>'float', 'exclude='=>'bool'],
    'SphinxClient::setFilterRange' => ['bool', 'attribute'=>'string', 'min'=>'int', 'max'=>'int', 'exclude='=>'bool'],
    'SphinxClient::setGeoAnchor' => ['bool', 'attrlat'=>'string', 'attrlong'=>'string', 'latitude'=>'float', 'longitude'=>'float'],
    'SphinxClient::setGroupBy' => ['bool', 'attribute'=>'string', 'func'=>'int', 'groupsort='=>'string'],
    'SphinxClient::setGroupDistinct' => ['bool', 'attribute'=>'string'],
    'SphinxClient::setIDRange' => ['bool', 'min'=>'int', 'max'=>'int'],
    'SphinxClient::setIndexWeights' => ['bool', 'weights'=>'array'],
    'SphinxClient::setLimits' => ['bool', 'offset'=>'int', 'limit'=>'int', 'max_matches='=>'int', 'cutoff='=>'int'],
    'SphinxClient::setMatchMode' => ['bool', 'mode'=>'int'],
    'SphinxClient::setMaxQueryTime' => ['bool', 'qtime'=>'int'],
    'SphinxClient::setOverride' => ['bool', 'attribute'=>'string', 'type'=>'int', 'values'=>'array'],
    'SphinxClient::setRankingMode' => ['bool', 'ranker'=>'int'],
    'SphinxClient::setRetries' => ['bool', 'count'=>'int', 'delay='=>'int'],
    'SphinxClient::setSelect' => ['bool', 'clause'=>'string'],
    'SphinxClient::setServer' => ['bool', 'server'=>'string', 'port'=>'int'],
    'SphinxClient::setSortMode' => ['bool', 'mode'=>'int', 'sortby='=>'string'],
    'SphinxClient::status' => ['array'],
    'SphinxClient::updateAttributes' => ['int', 'index'=>'string', 'attributes'=>'array', 'values'=>'array', 'mva='=>'bool'],
    'SplDoublyLinkedList::__construct' => ['void'],
    'SplDoublyLinkedList::add' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
    'SplDoublyLinkedList::bottom' => ['mixed'],
    'SplDoublyLinkedList::count' => ['int'],
    'SplDoublyLinkedList::current' => ['mixed'],
    'SplDoublyLinkedList::getIteratorMode' => ['int'],
    'SplDoublyLinkedList::isEmpty' => ['bool'],
    'SplDoublyLinkedList::key' => ['int'],
    'SplDoublyLinkedList::next' => ['void'],
    'SplDoublyLinkedList::offsetExists' => ['bool', 'index'=>'mixed'],
    'SplDoublyLinkedList::offsetGet' => ['mixed', 'index'=>'mixed'],
    'SplDoublyLinkedList::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
    'SplDoublyLinkedList::offsetUnset' => ['void', 'index'=>'mixed'],
    'SplDoublyLinkedList::pop' => ['mixed'],
    'SplDoublyLinkedList::prev' => ['void'],
    'SplDoublyLinkedList::push' => ['void', 'value'=>'mixed'],
    'SplDoublyLinkedList::rewind' => ['void'],
    'SplDoublyLinkedList::serialize' => ['string'],
    'SplDoublyLinkedList::setIteratorMode' => ['void', 'flags'=>'int'],
    'SplDoublyLinkedList::shift' => ['mixed'],
    'SplDoublyLinkedList::top' => ['mixed'],
    'SplDoublyLinkedList::unserialize' => ['void', 'serialized'=>'string'],
    'SplDoublyLinkedList::unshift' => ['void', 'value'=>'mixed'],
    'SplDoublyLinkedList::valid' => ['bool'],
    'SplEnum::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool'],
    'SplEnum::getConstList' => ['array', 'include_default='=>'bool'],
    'SplFileInfo::__construct' => ['void', 'file_name'=>'string'],
    'SplFileInfo::__toString' => ['string'],
    'SplFileInfo::__wakeup' => ['void'],
    'SplFileInfo::getATime' => ['int|false'],
    'SplFileInfo::getBasename' => ['string', 'suffix='=>'string'],
    'SplFileInfo::getCTime' => ['int|false'],
    'SplFileInfo::getExtension' => ['string'],
    'SplFileInfo::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'SplFileInfo::getFilename' => ['string'],
    'SplFileInfo::getGroup' => ['int|false'],
    'SplFileInfo::getInode' => ['int|false'],
    'SplFileInfo::getLinkTarget' => ['string|false'],
    'SplFileInfo::getMTime' => ['int|false'],
    'SplFileInfo::getOwner' => ['int|false'],
    'SplFileInfo::getPath' => ['string'],
    'SplFileInfo::getPathInfo' => ['SplFileInfo|null', 'class_name='=>'string'],
    'SplFileInfo::getPathname' => ['string'],
    'SplFileInfo::getPerms' => ['int|false'],
    'SplFileInfo::getRealPath' => ['string|false'],
    'SplFileInfo::getSize' => ['int|false'],
    'SplFileInfo::getType' => ['string|false'],
    'SplFileInfo::isDir' => ['bool'],
    'SplFileInfo::isExecutable' => ['bool'],
    'SplFileInfo::isFile' => ['bool'],
    'SplFileInfo::isLink' => ['bool'],
    'SplFileInfo::isReadable' => ['bool'],
    'SplFileInfo::isWritable' => ['bool'],
    'SplFileInfo::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
    'SplFileInfo::setFileClass' => ['void', 'class_name='=>'string'],
    'SplFileInfo::setInfoClass' => ['void', 'class_name='=>'string'],
    'SplFileObject::__construct' => ['void', 'filename'=>'string', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>''],
    'SplFileObject::__toString' => ['string'],
    'SplFileObject::current' => ['string|array|false'],
    'SplFileObject::eof' => ['bool'],
    'SplFileObject::fflush' => ['bool'],
    'SplFileObject::fgetc' => ['string|false'],
    'SplFileObject::fgetcsv' => ['list<string>|array{0: null}|false|null', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'SplFileObject::fgets' => ['string|false'],
    'SplFileObject::fgetss' => ['string|false', 'allowable_tags='=>'string'],
    'SplFileObject::flock' => ['bool', 'operation'=>'int', '&w_wouldblock='=>'int'],
    'SplFileObject::fpassthru' => ['int'],
    'SplFileObject::fputcsv' => ['int|false', 'fields'=>'array<array-key, null|scalar|Stringable>', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'SplFileObject::fread' => ['string|false', 'length'=>'int'],
    'SplFileObject::fscanf' => ['array|int', 'format'=>'string', '&...w_vars='=>'string|int|float'],
    'SplFileObject::fseek' => ['int', 'pos'=>'int', 'whence='=>'int'],
    'SplFileObject::fstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}'],
    'SplFileObject::ftell' => ['int|false'],
    'SplFileObject::ftruncate' => ['bool', 'size'=>'int'],
    'SplFileObject::fwrite' => ['int', 'string'=>'string', 'length='=>'int'],
    'SplFileObject::getATime' => ['int|false'],
    'SplFileObject::getBasename' => ['string', 'suffix='=>'string'],
    'SplFileObject::getCTime' => ['int|false'],
    'SplFileObject::getChildren' => ['null'],
    'SplFileObject::getCsvControl' => ['array'],
    'SplFileObject::getCurrentLine' => ['string|false'],
    'SplFileObject::getExtension' => ['string'],
    'SplFileObject::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'SplFileObject::getFilename' => ['string'],
    'SplFileObject::getFlags' => ['int'],
    'SplFileObject::getGroup' => ['int|false'],
    'SplFileObject::getInode' => ['int|false'],
    'SplFileObject::getLinkTarget' => ['string|false'],
    'SplFileObject::getMaxLineLen' => ['int'],
    'SplFileObject::getMTime' => ['int|false'],
    'SplFileObject::getOwner' => ['int|false'],
    'SplFileObject::getPath' => ['string'],
    'SplFileObject::getPathInfo' => ['SplFileInfo|null', 'class_name='=>'string'],
    'SplFileObject::getPathname' => ['string'],
    'SplFileObject::getPerms' => ['int|false'],
    'SplFileObject::getRealPath' => ['false|string'],
    'SplFileObject::getSize' => ['int|false'],
    'SplFileObject::getType' => ['string|false'],
    'SplFileObject::hasChildren' => ['false'],
    'SplFileObject::isDir' => ['bool'],
    'SplFileObject::isExecutable' => ['bool'],
    'SplFileObject::isFile' => ['bool'],
    'SplFileObject::isLink' => ['bool'],
    'SplFileObject::isReadable' => ['bool'],
    'SplFileObject::isWritable' => ['bool'],
    'SplFileObject::key' => ['int'],
    'SplFileObject::next' => ['void'],
    'SplFileObject::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
    'SplFileObject::rewind' => ['void'],
    'SplFileObject::seek' => ['void', 'line_pos'=>'int'],
    'SplFileObject::setCsvControl' => ['void', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'SplFileObject::setFileClass' => ['void', 'class_name='=>'string'],
    'SplFileObject::setFlags' => ['void', 'flags'=>'int'],
    'SplFileObject::setInfoClass' => ['void', 'class_name='=>'string'],
    'SplFileObject::setMaxLineLen' => ['void', 'max_len'=>'int'],
    'SplFileObject::valid' => ['bool'],
    'SplFixedArray::__construct' => ['void', 'size='=>'int'],
    'SplFixedArray::__wakeup' => ['void'],
    'SplFixedArray::count' => ['int'],
    'SplFixedArray::current' => ['mixed'],
    'SplFixedArray::fromArray' => ['SplFixedArray', 'data'=>'array', 'save_indexes='=>'bool'],
    'SplFixedArray::getSize' => ['int'],
    'SplFixedArray::key' => ['int'],
    'SplFixedArray::next' => ['void'],
    'SplFixedArray::offsetExists' => ['bool', 'index'=>'int'],
    'SplFixedArray::offsetGet' => ['mixed', 'index'=>'int'],
    'SplFixedArray::offsetSet' => ['void', 'index'=>'int', 'newval'=>'mixed'],
    'SplFixedArray::offsetUnset' => ['void', 'index'=>'int'],
    'SplFixedArray::rewind' => ['void'],
    'SplFixedArray::setSize' => ['bool', 'size'=>'int'],
    'SplFixedArray::toArray' => ['array'],
    'SplFixedArray::valid' => ['bool'],
    'SplHeap::__construct' => ['void'],
    'SplHeap::compare' => ['int', 'value1'=>'mixed', 'value2'=>'mixed'],
    'SplHeap::count' => ['int'],
    'SplHeap::current' => ['mixed'],
    'SplHeap::extract' => ['mixed'],
    'SplHeap::insert' => ['bool', 'value'=>'mixed'],
    'SplHeap::isCorrupted' => ['bool'],
    'SplHeap::isEmpty' => ['bool'],
    'SplHeap::key' => ['int'],
    'SplHeap::next' => ['void'],
    'SplHeap::recoverFromCorruption' => ['true'],
    'SplHeap::rewind' => ['void'],
    'SplHeap::top' => ['mixed'],
    'SplHeap::valid' => ['bool'],
    'SplMaxHeap::__construct' => ['void'],
    'SplMaxHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'],
    'SplMinHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'],
    'SplMinHeap::count' => ['int'],
    'SplMinHeap::current' => ['mixed'],
    'SplMinHeap::extract' => ['mixed'],
    'SplMinHeap::insert' => ['true', 'value'=>'mixed'],
    'SplMinHeap::isCorrupted' => ['bool'],
    'SplMinHeap::isEmpty' => ['bool'],
    'SplMinHeap::key' => ['int'],
    'SplMinHeap::next' => ['void'],
    'SplMinHeap::recoverFromCorruption' => ['true'],
    'SplMinHeap::rewind' => ['void'],
    'SplMinHeap::top' => ['mixed'],
    'SplMinHeap::valid' => ['bool'],
    'SplObjectStorage::__construct' => ['void'],
    'SplObjectStorage::addAll' => ['void', 'os'=>'splobjectstorage'],
    'SplObjectStorage::attach' => ['void', 'object'=>'object', 'inf='=>'mixed'],
    'SplObjectStorage::contains' => ['bool', 'object'=>'object'],
    'SplObjectStorage::count' => ['int'],
    'SplObjectStorage::current' => ['object'],
    'SplObjectStorage::detach' => ['void', 'object'=>'object'],
    'SplObjectStorage::getHash' => ['string', 'object'=>'object'],
    'SplObjectStorage::getInfo' => ['mixed'],
    'SplObjectStorage::key' => ['int'],
    'SplObjectStorage::next' => ['void'],
    'SplObjectStorage::offsetExists' => ['bool', 'object'=>'object'],
    'SplObjectStorage::offsetGet' => ['mixed', 'object'=>'object'],
    'SplObjectStorage::offsetSet' => ['object', 'object'=>'object', 'data='=>'mixed'],
    'SplObjectStorage::offsetUnset' => ['void', 'object'=>'object'],
    'SplObjectStorage::removeAll' => ['void', 'os'=>'splobjectstorage'],
    'SplObjectStorage::removeAllExcept' => ['void', 'os'=>'splobjectstorage'],
    'SplObjectStorage::rewind' => ['void'],
    'SplObjectStorage::serialize' => ['string'],
    'SplObjectStorage::setInfo' => ['void', 'inf'=>'mixed'],
    'SplObjectStorage::unserialize' => ['void', 'serialized'=>'string'],
    'SplObjectStorage::valid' => ['bool'],
    'SplObserver::update' => ['void', 'subject'=>'SplSubject'],
    'SplPriorityQueue::__construct' => ['void'],
    'SplPriorityQueue::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'],
    'SplPriorityQueue::count' => ['int'],
    'SplPriorityQueue::current' => ['mixed'],
    'SplPriorityQueue::extract' => ['mixed'],
    'SplPriorityQueue::getExtractFlags' => ['int'],
    'SplPriorityQueue::insert' => ['bool', 'value'=>'mixed', 'priority'=>'mixed'],
    'SplPriorityQueue::isEmpty' => ['bool'],
    'SplPriorityQueue::key' => ['int'],
    'SplPriorityQueue::next' => ['void'],
    'SplPriorityQueue::recoverFromCorruption' => ['void'],
    'SplPriorityQueue::rewind' => ['void'],
    'SplPriorityQueue::setExtractFlags' => ['int', 'flags'=>'int'],
    'SplPriorityQueue::top' => ['mixed'],
    'SplPriorityQueue::valid' => ['bool'],
    'SplQueue::dequeue' => ['mixed'],
    'SplQueue::enqueue' => ['void', 'value'=>'mixed'],
    'SplQueue::getIteratorMode' => ['int'],
    'SplQueue::isEmpty' => ['bool'],
    'SplQueue::key' => ['int'],
    'SplQueue::next' => ['void'],
    'SplQueue::offsetExists' => ['bool', 'index'=>'mixed'],
    'SplQueue::offsetGet' => ['mixed', 'index'=>'mixed'],
    'SplQueue::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
    'SplQueue::offsetUnset' => ['void', 'index'=>'mixed'],
    'SplQueue::pop' => ['mixed'],
    'SplQueue::prev' => ['void'],
    'SplQueue::push' => ['void', 'value'=>'mixed'],
    'SplQueue::rewind' => ['void'],
    'SplQueue::serialize' => ['string'],
    'SplQueue::setIteratorMode' => ['int', 'mode'=>'int'],
    'SplQueue::shift' => ['mixed'],
    'SplQueue::top' => ['mixed'],
    'SplQueue::unserialize' => ['void', 'serialized'=>'string'],
    'SplQueue::unshift' => ['void', 'value'=>'mixed'],
    'SplQueue::valid' => ['bool'],
    'SplStack::__construct' => ['void'],
    'SplStack::add' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
    'SplStack::bottom' => ['mixed'],
    'SplStack::count' => ['int'],
    'SplStack::current' => ['mixed'],
    'SplStack::getIteratorMode' => ['int'],
    'SplStack::isEmpty' => ['bool'],
    'SplStack::key' => ['int'],
    'SplStack::next' => ['void'],
    'SplStack::offsetExists' => ['bool', 'index'=>'mixed'],
    'SplStack::offsetGet' => ['mixed', 'index'=>'mixed'],
    'SplStack::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
    'SplStack::offsetUnset' => ['void', 'index'=>'mixed'],
    'SplStack::pop' => ['mixed'],
    'SplStack::prev' => ['void'],
    'SplStack::push' => ['void', 'value'=>'mixed'],
    'SplStack::rewind' => ['void'],
    'SplStack::serialize' => ['string'],
    'SplStack::setIteratorMode' => ['int', 'mode'=>'int'],
    'SplStack::shift' => ['mixed'],
    'SplStack::top' => ['mixed'],
    'SplStack::unserialize' => ['void', 'serialized'=>'string'],
    'SplStack::unshift' => ['void', 'value'=>'mixed'],
    'SplStack::valid' => ['bool'],
    'SplSubject::attach' => ['void', 'observer'=>'SplObserver'],
    'SplSubject::detach' => ['void', 'observer'=>'SplObserver'],
    'SplSubject::notify' => ['void'],
    'SplTempFileObject::__construct' => ['void', 'max_memory='=>'int'],
    'SplTempFileObject::__toString' => ['string'],
    'SplTempFileObject::current' => ['array|false|string'],
    'SplTempFileObject::eof' => ['bool'],
    'SplTempFileObject::fflush' => ['bool'],
    'SplTempFileObject::fgetc' => ['false|string'],
    'SplTempFileObject::fgetcsv' => ['list<string>|array{0: null}|false|null', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'SplTempFileObject::fgets' => ['string'],
    'SplTempFileObject::fgetss' => ['string', 'allowable_tags='=>'string'],
    'SplTempFileObject::flock' => ['bool', 'operation'=>'int', '&wouldblock='=>'int'],
    'SplTempFileObject::fpassthru' => ['int'],
    'SplTempFileObject::fputcsv' => ['false|int', 'fields'=>'array<array-key, null|scalar|Stringable>', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'SplTempFileObject::fread' => ['false|string', 'length'=>'int'],
    'SplTempFileObject::fscanf' => ['bool', 'format'=>'string', '&...w_vars='=>'array<int,float>|array<int,int>|array<int,string>'],
    'SplTempFileObject::fseek' => ['int', 'pos'=>'int', 'whence='=>'int'],
    'SplTempFileObject::fstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}'],
    'SplTempFileObject::ftell' => ['int'],
    'SplTempFileObject::ftruncate' => ['bool', 'size'=>'int'],
    'SplTempFileObject::fwrite' => ['int', 'string'=>'string', 'length='=>'int'],
    'SplTempFileObject::getATime' => ['int|false'],
    'SplTempFileObject::getBasename' => ['string', 'suffix='=>'string'],
    'SplTempFileObject::getCTime' => ['int|false'],
    'SplTempFileObject::getChildren' => ['null'],
    'SplTempFileObject::getCsvControl' => ['array'],
    'SplTempFileObject::getCurrentLine' => ['string'],
    'SplTempFileObject::getExtension' => ['string'],
    'SplTempFileObject::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'SplTempFileObject::getFilename' => ['string'],
    'SplTempFileObject::getFlags' => ['int'],
    'SplTempFileObject::getGroup' => ['int|false'],
    'SplTempFileObject::getInode' => ['int|false'],
    'SplTempFileObject::getLinkTarget' => ['string|false'],
    'SplTempFileObject::getMaxLineLen' => ['int'],
    'SplTempFileObject::getMTime' => ['int|false'],
    'SplTempFileObject::getOwner' => ['int|false'],
    'SplTempFileObject::getPath' => ['string'],
    'SplTempFileObject::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
    'SplTempFileObject::getPathname' => ['string'],
    'SplTempFileObject::getPerms' => ['int|false'],
    'SplTempFileObject::getRealPath' => ['string|false'],
    'SplTempFileObject::getSize' => ['int|false'],
    'SplTempFileObject::getType' => ['string|false'],
    'SplTempFileObject::hasChildren' => ['bool'],
    'SplTempFileObject::isDir' => ['bool'],
    'SplTempFileObject::isExecutable' => ['bool'],
    'SplTempFileObject::isFile' => ['bool'],
    'SplTempFileObject::isLink' => ['bool'],
    'SplTempFileObject::isReadable' => ['bool'],
    'SplTempFileObject::isWritable' => ['bool'],
    'SplTempFileObject::key' => ['int'],
    'SplTempFileObject::next' => ['void'],
    'SplTempFileObject::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
    'SplTempFileObject::rewind' => ['void'],
    'SplTempFileObject::seek' => ['void', 'line_pos'=>'int'],
    'SplTempFileObject::setCsvControl' => ['void', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'SplTempFileObject::setFileClass' => ['void', 'class_name='=>'string'],
    'SplTempFileObject::setFlags' => ['void', 'flags'=>'int'],
    'SplTempFileObject::setInfoClass' => ['void', 'class_name='=>'string'],
    'SplTempFileObject::setMaxLineLen' => ['void', 'max_len'=>'int'],
    'SplTempFileObject::valid' => ['bool'],
    'SplType::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool'],
    'Spoofchecker::__construct' => ['void'],
    'Spoofchecker::areConfusable' => ['bool', 's1'=>'string', 's2'=>'string', '&w_error='=>'string'],
    'Spoofchecker::isSuspicious' => ['bool', 'text'=>'string', '&w_error='=>'string'],
    'Spoofchecker::setAllowedLocales' => ['void', 'locale_list'=>'string'],
    'Spoofchecker::setChecks' => ['void', 'checks'=>'long'],
    'Spoofchecker::setRestrictionLevel' => ['void', 'restriction_level'=>'int'],
    'Stomp::__construct' => ['void', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'?array'],
    'Stomp::abort' => ['bool', 'transaction_id'=>'string', 'headers='=>'?array'],
    'Stomp::ack' => ['bool', 'msg'=>'', 'headers='=>'?array'],
    'Stomp::begin' => ['bool', 'transaction_id'=>'string', 'headers='=>'?array'],
    'Stomp::commit' => ['bool', 'transaction_id'=>'string', 'headers='=>'?array'],
    'Stomp::error' => ['string'],
    'Stomp::getReadTimeout' => ['array'],
    'Stomp::getSessionId' => ['string'],
    'Stomp::hasFrame' => ['bool'],
    'Stomp::readFrame' => ['array', 'class_name='=>'string'],
    'Stomp::send' => ['bool', 'destination'=>'string', 'msg'=>'', 'headers='=>'?array'],
    'Stomp::setReadTimeout' => ['void', 'seconds'=>'int', 'microseconds='=>'?int'],
    'Stomp::subscribe' => ['bool', 'destination'=>'string', 'headers='=>'?array'],
    'Stomp::unsubscribe' => ['bool', 'destination'=>'string', 'headers='=>'?array'],
    'StompException::getDetails' => ['string'],
    'StompFrame::__construct' => ['void', 'command='=>'string', 'headers='=>'?array', 'body='=>'string'],
    'Swish::__construct' => ['void', 'index_names'=>'string'],
    'Swish::getMetaList' => ['array', 'index_name'=>'string'],
    'Swish::getPropertyList' => ['array', 'index_name'=>'string'],
    'Swish::prepare' => ['object', 'query='=>'string'],
    'Swish::query' => ['object', 'query'=>'string'],
    'SwishResult::getMetaList' => ['array'],
    'SwishResult::stem' => ['array', 'word'=>'string'],
    'SwishResults::getParsedWords' => ['array', 'index_name'=>'string'],
    'SwishResults::getRemovedStopwords' => ['array', 'index_name'=>'string'],
    'SwishResults::nextResult' => ['object'],
    'SwishResults::seekResult' => ['int', 'position'=>'int'],
    'SwishSearch::execute' => ['object', 'query='=>'string'],
    'SwishSearch::resetLimit' => [''],
    'SwishSearch::setLimit' => ['', 'property'=>'string', 'low'=>'string', 'high'=>'string'],
    'SwishSearch::setPhraseDelimiter' => ['', 'delimiter'=>'string'],
    'SwishSearch::setSort' => ['', 'sort'=>'string'],
    'SwishSearch::setStructure' => ['', 'structure'=>'int'],
    'SyncEvent::__construct' => ['void', 'name='=>'string', 'manual='=>'bool'],
    'SyncEvent::fire' => ['bool'],
    'SyncEvent::reset' => ['bool'],
    'SyncEvent::wait' => ['bool', 'wait='=>'int'],
    'SyncMutex::__construct' => ['void', 'name='=>'string'],
    'SyncMutex::lock' => ['bool', 'wait='=>'int'],
    'SyncMutex::unlock' => ['bool', 'all='=>'bool'],
    'SyncReaderWriter::__construct' => ['void', 'name='=>'string', 'autounlock='=>'bool'],
    'SyncReaderWriter::readlock' => ['bool', 'wait='=>'int'],
    'SyncReaderWriter::readunlock' => ['bool'],
    'SyncReaderWriter::writelock' => ['bool', 'wait='=>'int'],
    'SyncReaderWriter::writeunlock' => ['bool'],
    'SyncSemaphore::__construct' => ['void', 'name='=>'string', 'initialval='=>'int', 'autounlock='=>'bool'],
    'SyncSemaphore::lock' => ['bool', 'wait='=>'int'],
    'SyncSemaphore::unlock' => ['bool', '&w_prevcount='=>'int'],
    'SyncSharedMemory::__construct' => ['void', 'name'=>'string', 'size'=>'int'],
    'SyncSharedMemory::first' => ['bool'],
    'SyncSharedMemory::read' => ['string', 'start='=>'int', 'length='=>'int'],
    'SyncSharedMemory::size' => ['int'],
    'SyncSharedMemory::write' => ['int', 'string='=>'string', 'start='=>'int'],
    'Thread::__construct' => ['void'],
    'Thread::addRef' => ['void'],
    'Thread::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'],
    'Thread::count' => ['int'],
    'Thread::delRef' => ['void'],
    'Thread::detach' => ['void'],
    'Thread::extend' => ['bool', 'class'=>'string'],
    'Thread::getCreatorId' => ['int'],
    'Thread::getCurrentThread' => ['Thread'],
    'Thread::getCurrentThreadId' => ['int'],
    'Thread::getRefCount' => ['int'],
    'Thread::getTerminationInfo' => ['array'],
    'Thread::getThreadId' => ['int'],
    'Thread::globally' => ['mixed'],
    'Thread::isGarbage' => ['bool'],
    'Thread::isJoined' => ['bool'],
    'Thread::isRunning' => ['bool'],
    'Thread::isStarted' => ['bool'],
    'Thread::isTerminated' => ['bool'],
    'Thread::isWaiting' => ['bool'],
    'Thread::join' => ['bool'],
    'Thread::kill' => ['void'],
    'Thread::lock' => ['bool'],
    'Thread::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'],
    'Thread::notify' => ['bool'],
    'Thread::notifyOne' => ['bool'],
    'Thread::offsetExists' => ['bool', 'offset'=>'mixed'],
    'Thread::offsetGet' => ['mixed', 'offset'=>'mixed'],
    'Thread::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
    'Thread::offsetUnset' => ['void', 'offset'=>'mixed'],
    'Thread::pop' => ['bool'],
    'Thread::run' => ['void'],
    'Thread::setGarbage' => ['void'],
    'Thread::shift' => ['bool'],
    'Thread::start' => ['bool', 'options='=>'int'],
    'Thread::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'],
    'Thread::unlock' => ['bool'],
    'Thread::wait' => ['bool', 'timeout='=>'int'],
    'Threaded::__construct' => ['void'],
    'Threaded::addRef' => ['void'],
    'Threaded::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'],
    'Threaded::count' => ['int'],
    'Threaded::delRef' => ['void'],
    'Threaded::extend' => ['bool', 'class'=>'string'],
    'Threaded::from' => ['Threaded', 'run'=>'Closure', 'construct='=>'Closure', 'args='=>'array'],
    'Threaded::getRefCount' => ['int'],
    'Threaded::getTerminationInfo' => ['array'],
    'Threaded::isGarbage' => ['bool'],
    'Threaded::isRunning' => ['bool'],
    'Threaded::isTerminated' => ['bool'],
    'Threaded::isWaiting' => ['bool'],
    'Threaded::lock' => ['bool'],
    'Threaded::merge' => ['bool', 'from'=>'mixed', 'overwrite='=>'bool'],
    'Threaded::notify' => ['bool'],
    'Threaded::notifyOne' => ['bool'],
    'Threaded::offsetExists' => ['bool', 'offset'=>'mixed'],
    'Threaded::offsetGet' => ['mixed', 'offset'=>'mixed'],
    'Threaded::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
    'Threaded::offsetUnset' => ['void', 'offset'=>'mixed'],
    'Threaded::pop' => ['bool'],
    'Threaded::run' => ['void'],
    'Threaded::setGarbage' => ['void'],
    'Threaded::shift' => ['mixed'],
    'Threaded::synchronized' => ['mixed', 'block'=>'Closure', '...args='=>'mixed'],
    'Threaded::unlock' => ['bool'],
    'Threaded::wait' => ['bool', 'timeout='=>'int'],
    'Throwable::__toString' => ['string'],
    'Throwable::getCode' => ['int|string'],
    'Throwable::getFile' => ['string'],
    'Throwable::getLine' => ['int'],
    'Throwable::getMessage' => ['string'],
    'Throwable::getPrevious' => ['?Throwable'],
    'Throwable::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'Throwable::getTraceAsString' => ['string'],
    'TokyoTyrant::__construct' => ['void', 'host='=>'string', 'port='=>'int', 'options='=>'array'],
    'TokyoTyrant::add' => ['int|float', 'key'=>'string', 'increment'=>'float', 'type='=>'int'],
    'TokyoTyrant::connect' => ['TokyoTyrant', 'host'=>'string', 'port='=>'int', 'options='=>'array'],
    'TokyoTyrant::connectUri' => ['TokyoTyrant', 'uri'=>'string'],
    'TokyoTyrant::copy' => ['TokyoTyrant', 'path'=>'string'],
    'TokyoTyrant::ext' => ['string', 'name'=>'string', 'options'=>'int', 'key'=>'string', 'value'=>'string'],
    'TokyoTyrant::fwmKeys' => ['array', 'prefix'=>'string', 'max_recs'=>'int'],
    'TokyoTyrant::get' => ['array', 'keys'=>'mixed'],
    'TokyoTyrant::getIterator' => ['TokyoTyrantIterator'],
    'TokyoTyrant::num' => ['int'],
    'TokyoTyrant::out' => ['string', 'keys'=>'mixed'],
    'TokyoTyrant::put' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
    'TokyoTyrant::putCat' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
    'TokyoTyrant::putKeep' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
    'TokyoTyrant::putNr' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
    'TokyoTyrant::putShl' => ['mixed', 'key'=>'string', 'value'=>'string', 'width'=>'int'],
    'TokyoTyrant::restore' => ['mixed', 'log_dir'=>'string', 'timestamp'=>'int', 'check_consistency='=>'bool'],
    'TokyoTyrant::setMaster' => ['mixed', 'host'=>'string', 'port'=>'int', 'timestamp'=>'int', 'check_consistency='=>'bool'],
    'TokyoTyrant::size' => ['int', 'key'=>'string'],
    'TokyoTyrant::stat' => ['array'],
    'TokyoTyrant::sync' => ['mixed'],
    'TokyoTyrant::tune' => ['TokyoTyrant', 'timeout'=>'float', 'options='=>'int'],
    'TokyoTyrant::vanish' => ['mixed'],
    'TokyoTyrantIterator::__construct' => ['void', 'object'=>'mixed'],
    'TokyoTyrantIterator::current' => ['mixed'],
    'TokyoTyrantIterator::key' => ['mixed'],
    'TokyoTyrantIterator::next' => ['mixed'],
    'TokyoTyrantIterator::rewind' => ['void'],
    'TokyoTyrantIterator::valid' => ['bool'],
    'TokyoTyrantQuery::__construct' => ['void', 'table'=>'TokyoTyrantTable'],
    'TokyoTyrantQuery::addCond' => ['mixed', 'name'=>'string', 'op'=>'int', 'expr'=>'string'],
    'TokyoTyrantQuery::count' => ['int'],
    'TokyoTyrantQuery::current' => ['array'],
    'TokyoTyrantQuery::hint' => ['string'],
    'TokyoTyrantQuery::key' => ['string'],
    'TokyoTyrantQuery::metaSearch' => ['array', 'queries'=>'array', 'type'=>'int'],
    'TokyoTyrantQuery::next' => ['array'],
    'TokyoTyrantQuery::out' => ['TokyoTyrantQuery'],
    'TokyoTyrantQuery::rewind' => ['bool'],
    'TokyoTyrantQuery::search' => ['array'],
    'TokyoTyrantQuery::setLimit' => ['mixed', 'max='=>'int', 'skip='=>'int'],
    'TokyoTyrantQuery::setOrder' => ['mixed', 'name'=>'string', 'type'=>'int'],
    'TokyoTyrantQuery::valid' => ['bool'],
    'TokyoTyrantTable::add' => ['void', 'key'=>'string', 'increment'=>'mixed', 'type='=>'string'],
    'TokyoTyrantTable::genUid' => ['int'],
    'TokyoTyrantTable::get' => ['array', 'keys'=>'mixed'],
    'TokyoTyrantTable::getIterator' => ['TokyoTyrantIterator'],
    'TokyoTyrantTable::getQuery' => ['TokyoTyrantQuery'],
    'TokyoTyrantTable::out' => ['void', 'keys'=>'mixed'],
    'TokyoTyrantTable::put' => ['int', 'key'=>'string', 'columns'=>'array'],
    'TokyoTyrantTable::putCat' => ['void', 'key'=>'string', 'columns'=>'array'],
    'TokyoTyrantTable::putKeep' => ['void', 'key'=>'string', 'columns'=>'array'],
    'TokyoTyrantTable::putNr' => ['void', 'keys'=>'mixed', 'value='=>'string'],
    'TokyoTyrantTable::putShl' => ['void', 'key'=>'string', 'value'=>'string', 'width'=>'int'],
    'TokyoTyrantTable::setIndex' => ['mixed', 'column'=>'string', 'type'=>'int'],
    'Transliterator::create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'],
    'Transliterator::createFromRules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'],
    'Transliterator::createInverse' => ['?Transliterator'],
    'Transliterator::getErrorCode' => ['int'],
    'Transliterator::getErrorMessage' => ['string'],
    'Transliterator::listIDs' => ['array'],
    'Transliterator::transliterate' => ['string|false', 'subject'=>'string', 'start='=>'int', 'end='=>'int'],
    'TypeError::__clone' => ['void'],
    'TypeError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'TypeError::__toString' => ['string'],
    'TypeError::getCode' => ['int'],
    'TypeError::getFile' => ['string'],
    'TypeError::getLine' => ['int'],
    'TypeError::getMessage' => ['string'],
    'TypeError::getPrevious' => ['?Throwable'],
    'TypeError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'TypeError::getTraceAsString' => ['string'],
    'UConverter::__construct' => ['void', 'destination_encoding='=>'?string', 'source_encoding='=>'?string'],
    'UConverter::convert' => ['string', 'string'=>'string', 'reverse='=>'bool'],
    'UConverter::fromUCallback' => ['mixed', 'reason'=>'int', 'source'=>'string', 'codePoint'=>'string', '&w_error'=>'int'],
    'UConverter::getAliases' => ['array|false|null', 'name'=>'string'],
    'UConverter::getAvailable' => ['array'],
    'UConverter::getDestinationEncoding' => ['string|false|null'],
    'UConverter::getDestinationType' => ['int|false|null'],
    'UConverter::getErrorCode' => ['int'],
    'UConverter::getErrorMessage' => ['?string'],
    'UConverter::getSourceEncoding' => ['string|false|null'],
    'UConverter::getSourceType' => ['int|false|null'],
    'UConverter::getStandards' => ['?array'],
    'UConverter::getSubstChars' => ['string|false|null'],
    'UConverter::reasonText' => ['string', 'reason='=>'int'],
    'UConverter::setDestinationEncoding' => ['bool', 'encoding'=>'string'],
    'UConverter::setSourceEncoding' => ['bool', 'encoding'=>'string'],
    'UConverter::setSubstChars' => ['bool', 'chars'=>'string'],
    'UConverter::toUCallback' => ['string|int|array|null', 'reason'=>'int', 'source'=>'string', 'codeUnits'=>'string', '&w_error'=>'int'],
    'UConverter::transcode' => ['string', 'string'=>'string', 'toEncoding'=>'string', 'fromEncoding'=>'string', 'options='=>'?array'],
    'UnderflowException::__clone' => ['void'],
    'UnderflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'UnderflowException::__toString' => ['string'],
    'UnderflowException::getCode' => ['int'],
    'UnderflowException::getFile' => ['string'],
    'UnderflowException::getLine' => ['int'],
    'UnderflowException::getMessage' => ['string'],
    'UnderflowException::getPrevious' => ['?Throwable'],
    'UnderflowException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'UnderflowException::getTraceAsString' => ['string'],
    'UnexpectedValueException::__clone' => ['void'],
    'UnexpectedValueException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
    'UnexpectedValueException::__toString' => ['string'],
    'UnexpectedValueException::getCode' => ['int'],
    'UnexpectedValueException::getFile' => ['string'],
    'UnexpectedValueException::getLine' => ['int'],
    'UnexpectedValueException::getMessage' => ['string'],
    'UnexpectedValueException::getPrevious' => ['?Throwable'],
    'UnexpectedValueException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'UnexpectedValueException::getTraceAsString' => ['string'],
    'V8Js::__construct' => ['void', 'object_name='=>'string', 'variables='=>'array', 'extensions='=>'array', 'report_uncaught_exceptions='=>'bool', 'snapshot_blob='=>'string'],
    'V8Js::clearPendingException' => [''],
    'V8Js::compileString' => ['resource', 'script'=>'', 'identifier='=>'string'],
    'V8Js::createSnapshot' => ['false|string', 'embed_source'=>'string'],
    'V8Js::executeScript' => ['', 'script'=>'resource', 'flags='=>'int', 'time_limit='=>'int', 'memory_limit='=>'int'],
    'V8Js::executeString' => ['mixed', 'script'=>'string', 'identifier='=>'string', 'flags='=>'int'],
    'V8Js::getExtensions' => ['string[]'],
    'V8Js::getPendingException' => ['?V8JsException'],
    'V8Js::registerExtension' => ['bool', 'extension_name'=>'string', 'script'=>'string', 'dependencies='=>'array', 'auto_enable='=>'bool'],
    'V8Js::setAverageObjectSize' => ['', 'average_object_size'=>'int'],
    'V8Js::setMemoryLimit' => ['', 'limit'=>'int'],
    'V8Js::setModuleLoader' => ['', 'loader'=>'callable'],
    'V8Js::setModuleNormaliser' => ['', 'normaliser'=>'callable'],
    'V8Js::setTimeLimit' => ['', 'limit'=>'int'],
    'V8JsException::getJsFileName' => ['string'],
    'V8JsException::getJsLineNumber' => ['int'],
    'V8JsException::getJsSourceLine' => ['int'],
    'V8JsException::getJsTrace' => ['string'],
    'V8JsScriptException::__clone' => ['void'],
    'V8JsScriptException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'V8JsScriptException::__toString' => ['string'],
    'V8JsScriptException::__wakeup' => ['void'],
    'V8JsScriptException::getCode' => ['int'],
    'V8JsScriptException::getFile' => ['string'],
    'V8JsScriptException::getJsEndColumn' => ['int'],
    'V8JsScriptException::getJsFileName' => ['string'],
    'V8JsScriptException::getJsLineNumber' => ['int'],
    'V8JsScriptException::getJsSourceLine' => ['string'],
    'V8JsScriptException::getJsStartColumn' => ['int'],
    'V8JsScriptException::getJsTrace' => ['string'],
    'V8JsScriptException::getLine' => ['int'],
    'V8JsScriptException::getMessage' => ['string'],
    'V8JsScriptException::getPrevious' => ['Exception|Throwable'],
    'V8JsScriptException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'V8JsScriptException::getTraceAsString' => ['string'],
    'VARIANT::__construct' => ['void', 'value='=>'mixed', 'type='=>'int', 'codepage='=>'int'],
    'VarnishAdmin::__construct' => ['void', 'args='=>'array'],
    'VarnishAdmin::auth' => ['bool'],
    'VarnishAdmin::ban' => ['int', 'vcl_regex'=>'string'],
    'VarnishAdmin::banUrl' => ['int', 'vcl_regex'=>'string'],
    'VarnishAdmin::clearPanic' => ['int'],
    'VarnishAdmin::connect' => ['bool'],
    'VarnishAdmin::disconnect' => ['bool'],
    'VarnishAdmin::getPanic' => ['string'],
    'VarnishAdmin::getParams' => ['array'],
    'VarnishAdmin::isRunning' => ['bool'],
    'VarnishAdmin::setCompat' => ['void', 'compat'=>'int'],
    'VarnishAdmin::setHost' => ['void', 'host'=>'string'],
    'VarnishAdmin::setIdent' => ['void', 'ident'=>'string'],
    'VarnishAdmin::setParam' => ['int', 'name'=>'string', 'value'=>'string|int'],
    'VarnishAdmin::setPort' => ['void', 'port'=>'int'],
    'VarnishAdmin::setSecret' => ['void', 'secret'=>'string'],
    'VarnishAdmin::setTimeout' => ['void', 'timeout'=>'int'],
    'VarnishAdmin::start' => ['int'],
    'VarnishAdmin::stop' => ['int'],
    'VarnishLog::__construct' => ['void', 'args='=>'array'],
    'VarnishLog::getLine' => ['array'],
    'VarnishLog::getTagName' => ['string', 'index'=>'int'],
    'VarnishStat::__construct' => ['void', 'args='=>'array'],
    'VarnishStat::getSnapshot' => ['array'],
    'Vtiful\Kernel\Chart::__construct' => ['void', 'handle'=>'resource', 'type'=>'int'],
    'Vtiful\Kernel\Chart::axisNameX' => ['Vtiful\Kernel\Chart', 'name'=>'string'],
    'Vtiful\Kernel\Chart::axisNameY' => ['Vtiful\Kernel\Chart', 'name'=>'string'],
    'Vtiful\Kernel\Chart::legendSetPosition' => ['Vtiful\Kernel\Chart', 'type'=>'int'],
    'Vtiful\Kernel\Chart::series' => ['Vtiful\Kernel\Chart', 'value'=>'string', 'categories='=>'string'],
    'Vtiful\Kernel\Chart::seriesName' => ['Vtiful\Kernel\Chart', 'value'=>'string'],
    'Vtiful\Kernel\Chart::style' => ['Vtiful\Kernel\Chart', 'style'=>'int'],
    'Vtiful\Kernel\Chart::title' => ['Vtiful\Kernel\Chart', 'title'=>'string'],
    'Vtiful\Kernel\Chart::toResource' => ['resource'],
    'Vtiful\Kernel\Excel::__construct' => ['void', 'config'=>'array'],
    'Vtiful\Kernel\Excel::activateSheet' => ['bool', 'sheet_name'=>'string'],
    'Vtiful\Kernel\Excel::addSheet' => ['Vtiful\Kernel\Excel', 'sheet_name='=>'?string'],
    'Vtiful\Kernel\Excel::autoFilter' => ['Vtiful\Kernel\Excel', 'range'=>'string'],
    'Vtiful\Kernel\Excel::checkoutSheet' => ['Vtiful\Kernel\Excel', 'sheet_name'=>'string'],
    'Vtiful\Kernel\Excel::close' => ['Vtiful\Kernel\Excel'],
    'Vtiful\Kernel\Excel::columnIndexFromString' => ['int', 'index'=>'string'],
    'Vtiful\Kernel\Excel::constMemory' => ['Vtiful\Kernel\Excel', 'file_name'=>'string', 'sheet_name='=>'?string'],
    'Vtiful\Kernel\Excel::data' => ['Vtiful\Kernel\Excel', 'data'=>'array'],
    'Vtiful\Kernel\Excel::defaultFormat' => ['Vtiful\Kernel\Excel', 'format_handle'=>'resource'],
    'Vtiful\Kernel\Excel::existSheet' => ['bool', 'sheet_name'=>'string'],
    'Vtiful\Kernel\Excel::fileName' => ['Vtiful\Kernel\Excel', 'file_name'=>'string', 'sheet_name='=>'?string'],
    'Vtiful\Kernel\Excel::freezePanes' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int'],
    'Vtiful\Kernel\Excel::getHandle' => ['resource'],
    'Vtiful\Kernel\Excel::getSheetData' => ['array|false'],
    'Vtiful\Kernel\Excel::gridline' => ['Vtiful\Kernel\Excel', 'option='=>'int'],
    'Vtiful\Kernel\Excel::header' => ['Vtiful\Kernel\Excel', 'header'=>'array', 'format_handle='=>'?resource'],
    'Vtiful\Kernel\Excel::insertChart' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'chart_resource'=>'resource'],
    'Vtiful\Kernel\Excel::insertComment' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'comment'=>'string'],
    'Vtiful\Kernel\Excel::insertDate' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'timestamp'=>'int', 'format='=>'?string', 'format_handle='=>'?resource'],
    'Vtiful\Kernel\Excel::insertFormula' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'formula'=>'string', 'format_handle='=>'?resource'],
    'Vtiful\Kernel\Excel::insertImage' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'image'=>'string', 'width='=>'?float', 'height='=>'?float'],
    'Vtiful\Kernel\Excel::insertText' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'data'=>'int|string|double', 'format='=>'?string', 'format_handle='=>'?resource'],
    'Vtiful\Kernel\Excel::insertUrl' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'url'=>'string', 'text='=>'?string', 'tool_tip='=>'?string', 'format='=>'?resource'],
    'Vtiful\Kernel\Excel::mergeCells' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'data'=>'string', 'format_handle='=>'?resource'],
    'Vtiful\Kernel\Excel::nextCellCallback' => ['void', 'fci'=>'callable(int,int,mixed)', 'sheet_name='=>'?string'],
    'Vtiful\Kernel\Excel::nextRow' => ['array|false', 'zv_type_t='=>'?array'],
    'Vtiful\Kernel\Excel::openFile' => ['Vtiful\Kernel\Excel', 'zs_file_name'=>'string'],
    'Vtiful\Kernel\Excel::openSheet' => ['Vtiful\Kernel\Excel', 'zs_sheet_name='=>'?string', 'zl_flag='=>'?int'],
    'Vtiful\Kernel\Excel::output' => ['string'],
    'Vtiful\Kernel\Excel::protection' => ['Vtiful\Kernel\Excel', 'password='=>'?string'],
    'Vtiful\Kernel\Excel::putCSV' => ['bool', 'fp'=>'resource', 'delimiter_str='=>'?string', 'enclosure_str='=>'?string', 'escape_str='=>'?string'],
    'Vtiful\Kernel\Excel::putCSVCallback' => ['bool', 'callback'=>'callable(array):array', 'fp'=>'resource', 'delimiter_str='=>'?string', 'enclosure_str='=>'?string', 'escape_str='=>'?string'],
    'Vtiful\Kernel\Excel::setColumn' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'width'=>'float', 'format_handle='=>'?resource'],
    'Vtiful\Kernel\Excel::setCurrentSheetHide' => ['Vtiful\Kernel\Excel'],
    'Vtiful\Kernel\Excel::setCurrentSheetIsFirst' => ['Vtiful\Kernel\Excel'],
    'Vtiful\Kernel\Excel::setGlobalType' => ['Vtiful\Kernel\Excel', 'zv_type_t'=>'int'],
    'Vtiful\Kernel\Excel::setLandscape' => ['Vtiful\Kernel\Excel'],
    'Vtiful\Kernel\Excel::setMargins' => ['Vtiful\Kernel\Excel', 'left='=>'?float', 'right='=>'?float', 'top='=>'?float', 'bottom='=>'?float'],
    'Vtiful\Kernel\Excel::setPaper' => ['Vtiful\Kernel\Excel', 'paper'=>'int'],
    'Vtiful\Kernel\Excel::setPortrait' => ['Vtiful\Kernel\Excel'],
    'Vtiful\Kernel\Excel::setRow' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'height'=>'float', 'format_handle='=>'?resource'],
    'Vtiful\Kernel\Excel::setSkipRows' => ['Vtiful\Kernel\Excel', 'zv_skip_t'=>'int'],
    'Vtiful\Kernel\Excel::setType' => ['Vtiful\Kernel\Excel', 'zv_type_t'=>'array'],
    'Vtiful\Kernel\Excel::sheetList' => ['array'],
    'Vtiful\Kernel\Excel::showComment' => ['Vtiful\Kernel\Excel'],
    'Vtiful\Kernel\Excel::stringFromColumnIndex' => ['string', 'index'=>'int'],
    'Vtiful\Kernel\Excel::timestampFromDateDouble' => ['int', 'index'=>'?float'],
    'Vtiful\Kernel\Excel::validation' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'validation_resource'=>'resource'],
    'Vtiful\Kernel\Excel::zoom' => ['Vtiful\Kernel\Excel', 'scale'=>'int'],
    'Vtiful\Kernel\Format::__construct' => ['void', 'handle'=>'resource'],
    'Vtiful\Kernel\Format::align' => ['Vtiful\Kernel\Format', '...style'=>'int'],
    'Vtiful\Kernel\Format::background' => ['Vtiful\Kernel\Format', 'color'=>'int', 'pattern='=>'int'],
    'Vtiful\Kernel\Format::bold' => ['Vtiful\Kernel\Format'],
    'Vtiful\Kernel\Format::border' => ['Vtiful\Kernel\Format', 'style'=>'int'],
    'Vtiful\Kernel\Format::font' => ['Vtiful\Kernel\Format', 'font'=>'string'],
    'Vtiful\Kernel\Format::fontColor' => ['Vtiful\Kernel\Format', 'color'=>'int'],
    'Vtiful\Kernel\Format::fontSize' => ['Vtiful\Kernel\Format', 'size'=>'float'],
    'Vtiful\Kernel\Format::italic' => ['Vtiful\Kernel\Format'],
    'Vtiful\Kernel\Format::number' => ['Vtiful\Kernel\Format', 'format'=>'string'],
    'Vtiful\Kernel\Format::strikeout' => ['Vtiful\Kernel\Format'],
    'Vtiful\Kernel\Format::toResource' => ['resource'],
    'Vtiful\Kernel\Format::underline' => ['Vtiful\Kernel\Format', 'style'=>'int'],
    'Vtiful\Kernel\Format::unlocked' => ['Vtiful\Kernel\Format'],
    'Vtiful\Kernel\Format::wrap' => ['Vtiful\Kernel\Format'],
    'Vtiful\Kernel\Validation::__construct' => ['void'],
    'Vtiful\Kernel\Validation::criteriaType' => ['?Vtiful\Kernel\Validation', 'type'=>'int'],
    'Vtiful\Kernel\Validation::maximumFormula' => ['?Vtiful\Kernel\Validation', 'maximum_formula'=>'string'],
    'Vtiful\Kernel\Validation::maximumNumber' => ['?Vtiful\Kernel\Validation', 'maximum_number'=>'float'],
    'Vtiful\Kernel\Validation::minimumFormula' => ['?Vtiful\Kernel\Validation', 'minimum_formula'=>'string'],
    'Vtiful\Kernel\Validation::minimumNumber' => ['?Vtiful\Kernel\Validation', 'minimum_number'=>'float'],
    'Vtiful\Kernel\Validation::toResource' => ['resource'],
    'Vtiful\Kernel\Validation::validationType' => ['?Vtiful\Kernel\Validation', 'type'=>'int'],
    'Vtiful\Kernel\Validation::valueList' => ['?Vtiful\Kernel\Validation', 'value_list'=>'array'],
    'Vtiful\Kernel\Validation::valueNumber' => ['?Vtiful\Kernel\Validation', 'value_number'=>'int'],
    'WeakMap::__construct' => ['void'],
    'WeakMap::count' => ['int'],
    'WeakMap::current' => ['mixed'],
    'WeakMap::key' => ['object'],
    'WeakMap::next' => ['void'],
    'WeakMap::offsetExists' => ['bool', 'object'=>'object'],
    'WeakMap::offsetGet' => ['mixed', 'object'=>'object'],
    'WeakMap::offsetSet' => ['void', 'object'=>'object', 'value'=>'mixed'],
    'WeakMap::offsetUnset' => ['void', 'object'=>'object'],
    'WeakMap::rewind' => ['void'],
    'WeakMap::valid' => ['bool'],
    'Weakref::acquire' => ['bool'],
    'Weakref::get' => ['object'],
    'Weakref::release' => ['bool'],
    'Weakref::valid' => ['bool'],
    'Worker::__construct' => ['void'],
    'Worker::addRef' => ['void'],
    'Worker::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'],
    'Worker::collect' => ['int', 'collector='=>'Callable'],
    'Worker::count' => ['int'],
    'Worker::delRef' => ['void'],
    'Worker::detach' => ['void'],
    'Worker::extend' => ['bool', 'class'=>'string'],
    'Worker::getCreatorId' => ['int'],
    'Worker::getCurrentThread' => ['Thread'],
    'Worker::getCurrentThreadId' => ['int'],
    'Worker::getRefCount' => ['int'],
    'Worker::getStacked' => ['int'],
    'Worker::getTerminationInfo' => ['array'],
    'Worker::getThreadId' => ['int'],
    'Worker::globally' => ['mixed'],
    'Worker::isGarbage' => ['bool'],
    'Worker::isJoined' => ['bool'],
    'Worker::isRunning' => ['bool'],
    'Worker::isShutdown' => ['bool'],
    'Worker::isStarted' => ['bool'],
    'Worker::isTerminated' => ['bool'],
    'Worker::isWaiting' => ['bool'],
    'Worker::isWorking' => ['bool'],
    'Worker::join' => ['bool'],
    'Worker::kill' => ['bool'],
    'Worker::lock' => ['bool'],
    'Worker::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'],
    'Worker::notify' => ['bool'],
    'Worker::notifyOne' => ['bool'],
    'Worker::offsetExists' => ['bool', 'offset'=>'mixed'],
    'Worker::offsetGet' => ['mixed', 'offset'=>'mixed'],
    'Worker::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
    'Worker::offsetUnset' => ['void', 'offset'=>'mixed'],
    'Worker::pop' => ['bool'],
    'Worker::run' => ['void'],
    'Worker::setGarbage' => ['void'],
    'Worker::shift' => ['bool'],
    'Worker::shutdown' => ['bool'],
    'Worker::stack' => ['int', '&rw_work'=>'Threaded'],
    'Worker::start' => ['bool', 'options='=>'int'],
    'Worker::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'],
    'Worker::unlock' => ['bool'],
    'Worker::unstack' => ['int', '&rw_work='=>'Threaded'],
    'Worker::wait' => ['bool', 'timeout='=>'int'],
    'XMLDiff\Base::__construct' => ['void', 'nsname'=>'string'],
    'XMLDiff\Base::diff' => ['mixed', 'from'=>'mixed', 'to'=>'mixed'],
    'XMLDiff\Base::merge' => ['mixed', 'src'=>'mixed', 'diff'=>'mixed'],
    'XMLDiff\DOM::diff' => ['DOMDocument', 'from'=>'DOMDocument', 'to'=>'DOMDocument'],
    'XMLDiff\DOM::merge' => ['DOMDocument', 'src'=>'DOMDocument', 'diff'=>'DOMDocument'],
    'XMLDiff\File::diff' => ['string', 'from'=>'string', 'to'=>'string'],
    'XMLDiff\File::merge' => ['string', 'src'=>'string', 'diff'=>'string'],
    'XMLDiff\Memory::diff' => ['string', 'from'=>'string', 'to'=>'string'],
    'XMLDiff\Memory::merge' => ['string', 'src'=>'string', 'diff'=>'string'],
    'XMLReader::XML' => ['bool', 'source'=>'string', 'encoding='=>'?string', 'options='=>'int'],
    'XMLReader::close' => ['bool'],
    'XMLReader::expand' => ['DOMNode|false', 'baseNode='=>'?DOMNode'],
    'XMLReader::getAttribute' => ['?string', 'name'=>'string'],
    'XMLReader::getAttributeNo' => ['?string', 'index'=>'int'],
    'XMLReader::getAttributeNs' => ['?string', 'name'=>'string', 'namespaceuri'=>'string'],
    'XMLReader::getParserProperty' => ['bool', 'property'=>'int'],
    'XMLReader::isValid' => ['bool'],
    'XMLReader::lookupNamespace' => ['?string', 'prefix'=>'string'],
    'XMLReader::moveToAttribute' => ['bool', 'name'=>'string'],
    'XMLReader::moveToAttributeNo' => ['bool', 'index'=>'int'],
    'XMLReader::moveToAttributeNs' => ['bool', 'localname'=>'string', 'namespaceuri'=>'string'],
    'XMLReader::moveToElement' => ['bool'],
    'XMLReader::moveToFirstAttribute' => ['bool'],
    'XMLReader::moveToNextAttribute' => ['bool'],
    'XMLReader::next' => ['bool', 'localname='=>'string'],
    'XMLReader::open' => ['bool', 'uri'=>'string', 'encoding='=>'?string', 'options='=>'int'],
    'XMLReader::read' => ['bool'],
    'XMLReader::readInnerXML' => ['string'],
    'XMLReader::readOuterXML' => ['string'],
    'XMLReader::readString' => ['string'],
    'XMLReader::setParserProperty' => ['bool', 'property'=>'int', 'value'=>'bool'],
    'XMLReader::setRelaxNGSchema' => ['bool', 'filename'=>'?string'],
    'XMLReader::setRelaxNGSchemaSource' => ['bool', 'source'=>'?string'],
    'XMLReader::setSchema' => ['bool', 'filename'=>'?string'],
    'XMLWriter::endAttribute' => ['bool'],
    'XMLWriter::endCdata' => ['bool'],
    'XMLWriter::endComment' => ['bool'],
    'XMLWriter::endDocument' => ['bool'],
    'XMLWriter::endDtd' => ['bool'],
    'XMLWriter::endDtdAttlist' => ['bool'],
    'XMLWriter::endDtdElement' => ['bool'],
    'XMLWriter::endDtdEntity' => ['bool'],
    'XMLWriter::endElement' => ['bool'],
    'XMLWriter::endPi' => ['bool'],
    'XMLWriter::flush' => ['string|int|false', 'empty='=>'bool'],
    'XMLWriter::fullEndElement' => ['bool'],
    'XMLWriter::openMemory' => ['bool'],
    'XMLWriter::openUri' => ['bool', 'uri'=>'string'],
    'XMLWriter::outputMemory' => ['string', 'flush='=>'bool'],
    'XMLWriter::setIndent' => ['bool', 'enable'=>'bool'],
    'XMLWriter::setIndentString' => ['bool', 'indentation'=>'string'],
    'XMLWriter::startAttribute' => ['bool', 'name'=>'string'],
    'XMLWriter::startAttributeNs' => ['bool', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string'],
    'XMLWriter::startCdata' => ['bool'],
    'XMLWriter::startComment' => ['bool'],
    'XMLWriter::startDocument' => ['bool', 'version='=>'?string', 'encoding='=>'?string', 'standalone='=>'?string'],
    'XMLWriter::startDtd' => ['bool', 'qualifiedName'=>'string', 'publicId='=>'?string', 'systemId='=>'?string'],
    'XMLWriter::startDtdAttlist' => ['bool', 'name'=>'string'],
    'XMLWriter::startDtdElement' => ['bool', 'qualifiedName'=>'string'],
    'XMLWriter::startDtdEntity' => ['bool', 'name'=>'string', 'isParam'=>'bool'],
    'XMLWriter::startElement' => ['bool', 'name'=>'string'],
    'XMLWriter::startElementNs' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
    'XMLWriter::startPi' => ['bool', 'target'=>'string'],
    'XMLWriter::text' => ['bool', 'content'=>'string'],
    'XMLWriter::writeAttribute' => ['bool', 'name'=>'string', 'value'=>'string'],
    'XMLWriter::writeAttributeNs' => ['bool', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
    'XMLWriter::writeCdata' => ['bool', 'content'=>'string'],
    'XMLWriter::writeComment' => ['bool', 'content'=>'string'],
    'XMLWriter::writeDtd' => ['bool', 'name'=>'string', 'publicId='=>'?string', 'systemId='=>'?string', 'content='=>'?string'],
    'XMLWriter::writeDtdAttlist' => ['bool', 'name'=>'string', 'content'=>'string'],
    'XMLWriter::writeDtdElement' => ['bool', 'name'=>'string', 'content'=>'string'],
    'XMLWriter::writeDtdEntity' => ['bool', 'name'=>'string', 'content'=>'string', 'isParam'=>'bool', 'publicId'=>'string', 'systemId'=>'string', 'notationData'=>'string'],
    'XMLWriter::writeElement' => ['bool', 'name'=>'string', 'content='=>'?string'],
    'XMLWriter::writeElementNs' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'content='=>'?string'],
    'XMLWriter::writePi' => ['bool', 'target'=>'string', 'content'=>'string'],
    'XMLWriter::writeRaw' => ['bool', 'content'=>'string'],
    'XSLTProcessor::getParameter' => ['string|false', 'namespace'=>'string', 'name'=>'string'],
    'XSLTProcessor::hasExsltSupport' => ['bool'],
    'XSLTProcessor::importStylesheet' => ['bool', 'stylesheet'=>'object'],
    'XSLTProcessor::registerPHPFunctions' => ['void', 'functions='=>'mixed'],
    'XSLTProcessor::removeParameter' => ['bool', 'namespace'=>'string', 'name'=>'string'],
    'XSLTProcessor::setParameter' => ['bool', 'namespace'=>'string', 'name'=>'string', 'value'=>'string'],
    'XSLTProcessor::setParameter\'1' => ['bool', 'namespace'=>'string', 'options'=>'array'],
    'XSLTProcessor::setProfiling' => ['bool', 'filename'=>'?string'],
    'XSLTProcessor::transformToDoc' => ['DOMDocument|false', 'document'=>'DOMNode'],
    'XSLTProcessor::transformToURI' => ['int', 'document'=>'DOMDocument', 'uri'=>'string'],
    'XSLTProcessor::transformToXML' => ['string|false', 'document'=>'DOMDocument'],
    'Xcom::__construct' => ['void', 'fabric_url='=>'string', 'fabric_token='=>'string', 'capability_token='=>'string'],
    'Xcom::decode' => ['object', 'avro_msg'=>'string', 'json_schema'=>'string'],
    'Xcom::encode' => ['string', 'data'=>'stdClass', 'avro_schema'=>'string'],
    'Xcom::getDebugOutput' => ['string'],
    'Xcom::getLastResponse' => ['string'],
    'Xcom::getLastResponseInfo' => ['array'],
    'Xcom::getOnboardingURL' => ['string', 'capability_name'=>'string', 'agreement_url'=>'string'],
    'Xcom::send' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'],
    'Xcom::sendAsync' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'],
    'XsltProcessor::getSecurityPrefs' => ['int'],
    'XsltProcessor::setSecurityPrefs' => ['int', 'preferences'=>'int'],
    'Yaconf::get' => ['mixed', 'name'=>'string', 'default_value='=>'mixed'],
    'Yaconf::has' => ['bool', 'name'=>'string'],
    'Yaf\Action_Abstract::__clone' => ['void'],
    'Yaf\Action_Abstract::__construct' => ['void', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract', 'view'=>'Yaf\View_Interface', 'invokeArgs='=>'?array'],
    'Yaf\Action_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'],
    'Yaf\Action_Abstract::execute' => ['mixed'],
    'Yaf\Action_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'],
    'Yaf\Action_Abstract::getController' => ['Yaf\Controller_Abstract'],
    'Yaf\Action_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'],
    'Yaf\Action_Abstract::getInvokeArgs' => ['array'],
    'Yaf\Action_Abstract::getModuleName' => ['string'],
    'Yaf\Action_Abstract::getRequest' => ['Yaf\Request_Abstract'],
    'Yaf\Action_Abstract::getResponse' => ['Yaf\Response_Abstract'],
    'Yaf\Action_Abstract::getView' => ['Yaf\View_Interface'],
    'Yaf\Action_Abstract::getViewpath' => ['string'],
    'Yaf\Action_Abstract::init' => [''],
    'Yaf\Action_Abstract::initView' => ['Yaf\Response_Abstract', 'options='=>'?array'],
    'Yaf\Action_Abstract::redirect' => ['bool', 'url'=>'string'],
    'Yaf\Action_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'],
    'Yaf\Action_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'],
    'Yaf\Application::__clone' => ['void'],
    'Yaf\Application::__construct' => ['void', 'config'=>'array|string', 'envrion='=>'string'],
    'Yaf\Application::__destruct' => ['void'],
    'Yaf\Application::__sleep' => ['string[]'],
    'Yaf\Application::__wakeup' => ['void'],
    'Yaf\Application::app' => ['?Yaf\Application'],
    'Yaf\Application::bootstrap' => ['Yaf\Application', 'bootstrap='=>'?Yaf\Bootstrap_Abstract'],
    'Yaf\Application::clearLastError' => ['void'],
    'Yaf\Application::environ' => ['string'],
    'Yaf\Application::execute' => ['void', 'entry'=>'callable', '_='=>'string'],
    'Yaf\Application::getAppDirectory' => ['string'],
    'Yaf\Application::getConfig' => ['Yaf\Config_Abstract'],
    'Yaf\Application::getDispatcher' => ['Yaf\Dispatcher'],
    'Yaf\Application::getLastErrorMsg' => ['string'],
    'Yaf\Application::getLastErrorNo' => ['int'],
    'Yaf\Application::getModules' => ['array'],
    'Yaf\Application::run' => ['void'],
    'Yaf\Application::setAppDirectory' => ['Yaf\Application', 'directory'=>'string'],
    'Yaf\Config\Ini::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'],
    'Yaf\Config\Ini::__get' => ['', 'name='=>'mixed'],
    'Yaf\Config\Ini::__isset' => ['', 'name'=>'string'],
    'Yaf\Config\Ini::__set' => ['void', 'name'=>'', 'value'=>''],
    'Yaf\Config\Ini::count' => ['int'],
    'Yaf\Config\Ini::current' => ['mixed'],
    'Yaf\Config\Ini::get' => ['mixed', 'name='=>'mixed'],
    'Yaf\Config\Ini::key' => ['int|string'],
    'Yaf\Config\Ini::next' => ['void'],
    'Yaf\Config\Ini::offsetExists' => ['bool', 'name'=>'mixed'],
    'Yaf\Config\Ini::offsetGet' => ['mixed', 'name'=>'mixed'],
    'Yaf\Config\Ini::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
    'Yaf\Config\Ini::offsetUnset' => ['void', 'name'=>'mixed'],
    'Yaf\Config\Ini::readonly' => ['bool'],
    'Yaf\Config\Ini::rewind' => ['void'],
    'Yaf\Config\Ini::set' => ['Yaf\Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
    'Yaf\Config\Ini::toArray' => ['array'],
    'Yaf\Config\Ini::valid' => ['bool'],
    'Yaf\Config\Simple::__construct' => ['void', 'array'=>'array', 'readonly='=>'string'],
    'Yaf\Config\Simple::__get' => ['', 'name='=>'mixed'],
    'Yaf\Config\Simple::__isset' => ['', 'name'=>'string'],
    'Yaf\Config\Simple::__set' => ['void', 'name'=>'', 'value'=>''],
    'Yaf\Config\Simple::count' => ['int'],
    'Yaf\Config\Simple::current' => ['mixed'],
    'Yaf\Config\Simple::get' => ['mixed', 'name='=>'mixed'],
    'Yaf\Config\Simple::key' => ['int|string'],
    'Yaf\Config\Simple::next' => ['void'],
    'Yaf\Config\Simple::offsetExists' => ['bool', 'name'=>'mixed'],
    'Yaf\Config\Simple::offsetGet' => ['mixed', 'name'=>'mixed'],
    'Yaf\Config\Simple::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
    'Yaf\Config\Simple::offsetUnset' => ['void', 'name'=>'mixed'],
    'Yaf\Config\Simple::readonly' => ['bool'],
    'Yaf\Config\Simple::rewind' => ['void'],
    'Yaf\Config\Simple::set' => ['Yaf\Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
    'Yaf\Config\Simple::toArray' => ['array'],
    'Yaf\Config\Simple::valid' => ['bool'],
    'Yaf\Config_Abstract::__construct' => ['void'],
    'Yaf\Config_Abstract::get' => ['mixed', 'name='=>'string'],
    'Yaf\Config_Abstract::readonly' => ['bool'],
    'Yaf\Config_Abstract::set' => ['Yaf\Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
    'Yaf\Config_Abstract::toArray' => ['array'],
    'Yaf\Controller_Abstract::__clone' => ['void'],
    'Yaf\Controller_Abstract::__construct' => ['void', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract', 'view'=>'Yaf\View_Interface', 'invokeArgs='=>'?array'],
    'Yaf\Controller_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'],
    'Yaf\Controller_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'],
    'Yaf\Controller_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'],
    'Yaf\Controller_Abstract::getInvokeArgs' => ['array'],
    'Yaf\Controller_Abstract::getModuleName' => ['string'],
    'Yaf\Controller_Abstract::getRequest' => ['Yaf\Request_Abstract'],
    'Yaf\Controller_Abstract::getResponse' => ['Yaf\Response_Abstract'],
    'Yaf\Controller_Abstract::getView' => ['Yaf\View_Interface'],
    'Yaf\Controller_Abstract::getViewpath' => ['string'],
    'Yaf\Controller_Abstract::init' => [''],
    'Yaf\Controller_Abstract::initView' => ['Yaf\Response_Abstract', 'options='=>'?array'],
    'Yaf\Controller_Abstract::redirect' => ['bool', 'url'=>'string'],
    'Yaf\Controller_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'],
    'Yaf\Controller_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'],
    'Yaf\Dispatcher::__clone' => ['void'],
    'Yaf\Dispatcher::__construct' => ['void'],
    'Yaf\Dispatcher::__sleep' => ['list<string>'],
    'Yaf\Dispatcher::__wakeup' => ['void'],
    'Yaf\Dispatcher::autoRender' => ['Yaf\Dispatcher', 'flag='=>'bool'],
    'Yaf\Dispatcher::catchException' => ['Yaf\Dispatcher', 'flag='=>'bool'],
    'Yaf\Dispatcher::disableView' => ['bool'],
    'Yaf\Dispatcher::dispatch' => ['Yaf\Response_Abstract', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Dispatcher::enableView' => ['Yaf\Dispatcher'],
    'Yaf\Dispatcher::flushInstantly' => ['Yaf\Dispatcher', 'flag='=>'bool'],
    'Yaf\Dispatcher::getApplication' => ['Yaf\Application'],
    'Yaf\Dispatcher::getInstance' => ['Yaf\Dispatcher'],
    'Yaf\Dispatcher::getRequest' => ['Yaf\Request_Abstract'],
    'Yaf\Dispatcher::getRouter' => ['Yaf\Router'],
    'Yaf\Dispatcher::initView' => ['Yaf\View_Interface', 'templates_dir'=>'string', 'options='=>'?array'],
    'Yaf\Dispatcher::registerPlugin' => ['Yaf\Dispatcher', 'plugin'=>'Yaf\Plugin_Abstract'],
    'Yaf\Dispatcher::returnResponse' => ['Yaf\Dispatcher', 'flag'=>'bool'],
    'Yaf\Dispatcher::setDefaultAction' => ['Yaf\Dispatcher', 'action'=>'string'],
    'Yaf\Dispatcher::setDefaultController' => ['Yaf\Dispatcher', 'controller'=>'string'],
    'Yaf\Dispatcher::setDefaultModule' => ['Yaf\Dispatcher', 'module'=>'string'],
    'Yaf\Dispatcher::setErrorHandler' => ['Yaf\Dispatcher', 'callback'=>'callable', 'error_types'=>'int'],
    'Yaf\Dispatcher::setRequest' => ['Yaf\Dispatcher', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Dispatcher::setView' => ['Yaf\Dispatcher', 'view'=>'Yaf\View_Interface'],
    'Yaf\Dispatcher::throwException' => ['Yaf\Dispatcher', 'flag='=>'bool'],
    'Yaf\Loader::__clone' => ['void'],
    'Yaf\Loader::__construct' => ['void'],
    'Yaf\Loader::__sleep' => ['list<string>'],
    'Yaf\Loader::__wakeup' => ['void'],
    'Yaf\Loader::autoload' => ['bool', 'class_name'=>'string'],
    'Yaf\Loader::clearLocalNamespace' => [''],
    'Yaf\Loader::getInstance' => ['Yaf\Loader', 'local_library_path='=>'string', 'global_library_path='=>'string'],
    'Yaf\Loader::getLibraryPath' => ['string', 'is_global='=>'bool'],
    'Yaf\Loader::getLocalNamespace' => ['string'],
    'Yaf\Loader::import' => ['bool', 'file'=>'string'],
    'Yaf\Loader::isLocalName' => ['bool', 'class_name'=>'string'],
    'Yaf\Loader::registerLocalNamespace' => ['bool', 'name_prefix'=>'string|string[]'],
    'Yaf\Loader::setLibraryPath' => ['Yaf\Loader', 'directory'=>'string', 'global='=>'bool'],
    'Yaf\Plugin_Abstract::dispatchLoopShutdown' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
    'Yaf\Plugin_Abstract::dispatchLoopStartup' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
    'Yaf\Plugin_Abstract::postDispatch' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
    'Yaf\Plugin_Abstract::preDispatch' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
    'Yaf\Plugin_Abstract::preResponse' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
    'Yaf\Plugin_Abstract::routerShutdown' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
    'Yaf\Plugin_Abstract::routerStartup' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
    'Yaf\Registry::__clone' => ['void'],
    'Yaf\Registry::__construct' => ['void'],
    'Yaf\Registry::del' => ['bool|void', 'name'=>'string'],
    'Yaf\Registry::get' => ['mixed', 'name'=>'string'],
    'Yaf\Registry::has' => ['bool', 'name'=>'string'],
    'Yaf\Registry::set' => ['bool', 'name'=>'string', 'value'=>'mixed'],
    'Yaf\Request\Http::__clone' => ['void'],
    'Yaf\Request\Http::__construct' => ['void', 'request_uri'=>'string', 'base_uri'=>'string'],
    'Yaf\Request\Http::get' => ['mixed', 'name'=>'string', 'default='=>'string'],
    'Yaf\Request\Http::getActionName' => ['string'],
    'Yaf\Request\Http::getBaseUri' => ['string'],
    'Yaf\Request\Http::getControllerName' => ['string'],
    'Yaf\Request\Http::getCookie' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::getException' => ['Yaf\Exception'],
    'Yaf\Request\Http::getFiles' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::getLanguage' => ['string'],
    'Yaf\Request\Http::getMethod' => ['string'],
    'Yaf\Request\Http::getModuleName' => ['string'],
    'Yaf\Request\Http::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::getParams' => ['array'],
    'Yaf\Request\Http::getPost' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::getQuery' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::getRequest' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::getRequestUri' => ['string'],
    'Yaf\Request\Http::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Http::isCli' => ['bool'],
    'Yaf\Request\Http::isDispatched' => ['bool'],
    'Yaf\Request\Http::isGet' => ['bool'],
    'Yaf\Request\Http::isHead' => ['bool'],
    'Yaf\Request\Http::isOptions' => ['bool'],
    'Yaf\Request\Http::isPost' => ['bool'],
    'Yaf\Request\Http::isPut' => ['bool'],
    'Yaf\Request\Http::isRouted' => ['bool'],
    'Yaf\Request\Http::isXmlHttpRequest' => ['bool'],
    'Yaf\Request\Http::setActionName' => ['Yaf\Request_Abstract|bool', 'action'=>'string'],
    'Yaf\Request\Http::setBaseUri' => ['bool', 'uri'=>'string'],
    'Yaf\Request\Http::setControllerName' => ['Yaf\Request_Abstract|bool', 'controller'=>'string'],
    'Yaf\Request\Http::setDispatched' => ['bool'],
    'Yaf\Request\Http::setModuleName' => ['Yaf\Request_Abstract|bool', 'module'=>'string'],
    'Yaf\Request\Http::setParam' => ['Yaf\Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
    'Yaf\Request\Http::setRequestUri' => ['', 'uri'=>'string'],
    'Yaf\Request\Http::setRouted' => ['Yaf\Request_Abstract|bool'],
    'Yaf\Request\Simple::__clone' => ['void'],
    'Yaf\Request\Simple::__construct' => ['void', 'method'=>'string', 'controller'=>'string', 'action'=>'string', 'params='=>'string'],
    'Yaf\Request\Simple::get' => ['mixed', 'name'=>'string', 'default='=>'string'],
    'Yaf\Request\Simple::getActionName' => ['string'],
    'Yaf\Request\Simple::getBaseUri' => ['string'],
    'Yaf\Request\Simple::getControllerName' => ['string'],
    'Yaf\Request\Simple::getCookie' => ['mixed', 'name='=>'string', 'default='=>'string'],
    'Yaf\Request\Simple::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Simple::getException' => ['Yaf\Exception'],
    'Yaf\Request\Simple::getFiles' => ['array', 'name='=>'mixed', 'default='=>'null'],
    'Yaf\Request\Simple::getLanguage' => ['string'],
    'Yaf\Request\Simple::getMethod' => ['string'],
    'Yaf\Request\Simple::getModuleName' => ['string'],
    'Yaf\Request\Simple::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
    'Yaf\Request\Simple::getParams' => ['array'],
    'Yaf\Request\Simple::getPost' => ['mixed', 'name='=>'string', 'default='=>'string'],
    'Yaf\Request\Simple::getQuery' => ['mixed', 'name='=>'string', 'default='=>'string'],
    'Yaf\Request\Simple::getRequest' => ['mixed', 'name='=>'string', 'default='=>'string'],
    'Yaf\Request\Simple::getRequestUri' => ['string'],
    'Yaf\Request\Simple::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request\Simple::isCli' => ['bool'],
    'Yaf\Request\Simple::isDispatched' => ['bool'],
    'Yaf\Request\Simple::isGet' => ['bool'],
    'Yaf\Request\Simple::isHead' => ['bool'],
    'Yaf\Request\Simple::isOptions' => ['bool'],
    'Yaf\Request\Simple::isPost' => ['bool'],
    'Yaf\Request\Simple::isPut' => ['bool'],
    'Yaf\Request\Simple::isRouted' => ['bool'],
    'Yaf\Request\Simple::isXmlHttpRequest' => ['bool'],
    'Yaf\Request\Simple::setActionName' => ['Yaf\Request_Abstract|bool', 'action'=>'string'],
    'Yaf\Request\Simple::setBaseUri' => ['bool', 'uri'=>'string'],
    'Yaf\Request\Simple::setControllerName' => ['Yaf\Request_Abstract|bool', 'controller'=>'string'],
    'Yaf\Request\Simple::setDispatched' => ['bool'],
    'Yaf\Request\Simple::setModuleName' => ['Yaf\Request_Abstract|bool', 'module'=>'string'],
    'Yaf\Request\Simple::setParam' => ['Yaf\Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
    'Yaf\Request\Simple::setRequestUri' => ['', 'uri'=>'string'],
    'Yaf\Request\Simple::setRouted' => ['Yaf\Request_Abstract|bool'],
    'Yaf\Request_Abstract::getActionName' => ['string'],
    'Yaf\Request_Abstract::getBaseUri' => ['string'],
    'Yaf\Request_Abstract::getControllerName' => ['string'],
    'Yaf\Request_Abstract::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request_Abstract::getException' => ['Yaf\Exception'],
    'Yaf\Request_Abstract::getLanguage' => ['string'],
    'Yaf\Request_Abstract::getMethod' => ['string'],
    'Yaf\Request_Abstract::getModuleName' => ['string'],
    'Yaf\Request_Abstract::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
    'Yaf\Request_Abstract::getParams' => ['array'],
    'Yaf\Request_Abstract::getRequestUri' => ['string'],
    'Yaf\Request_Abstract::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf\Request_Abstract::isCli' => ['bool'],
    'Yaf\Request_Abstract::isDispatched' => ['bool'],
    'Yaf\Request_Abstract::isGet' => ['bool'],
    'Yaf\Request_Abstract::isHead' => ['bool'],
    'Yaf\Request_Abstract::isOptions' => ['bool'],
    'Yaf\Request_Abstract::isPost' => ['bool'],
    'Yaf\Request_Abstract::isPut' => ['bool'],
    'Yaf\Request_Abstract::isRouted' => ['bool'],
    'Yaf\Request_Abstract::isXmlHttpRequest' => ['bool'],
    'Yaf\Request_Abstract::setActionName' => ['Yaf\Request_Abstract|bool', 'action'=>'string'],
    'Yaf\Request_Abstract::setBaseUri' => ['bool', 'uri'=>'string'],
    'Yaf\Request_Abstract::setControllerName' => ['Yaf\Request_Abstract|bool', 'controller'=>'string'],
    'Yaf\Request_Abstract::setDispatched' => ['bool'],
    'Yaf\Request_Abstract::setModuleName' => ['Yaf\Request_Abstract|bool', 'module'=>'string'],
    'Yaf\Request_Abstract::setParam' => ['Yaf\Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
    'Yaf\Request_Abstract::setRequestUri' => ['', 'uri'=>'string'],
    'Yaf\Request_Abstract::setRouted' => ['Yaf\Request_Abstract|bool'],
    'Yaf\Response\Cli::__clone' => ['void'],
    'Yaf\Response\Cli::__construct' => ['void'],
    'Yaf\Response\Cli::__destruct' => ['void'],
    'Yaf\Response\Cli::__toString' => ['string'],
    'Yaf\Response\Cli::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response\Cli::clearBody' => ['bool', 'key='=>'string'],
    'Yaf\Response\Cli::getBody' => ['mixed', 'key='=>'?string'],
    'Yaf\Response\Cli::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response\Cli::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response\Http::__clone' => ['void'],
    'Yaf\Response\Http::__construct' => ['void'],
    'Yaf\Response\Http::__destruct' => ['void'],
    'Yaf\Response\Http::__toString' => ['string'],
    'Yaf\Response\Http::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response\Http::clearBody' => ['bool', 'key='=>'string'],
    'Yaf\Response\Http::clearHeaders' => ['Yaf\Response_Abstract|false', 'name='=>'string'],
    'Yaf\Response\Http::getBody' => ['mixed', 'key='=>'?string'],
    'Yaf\Response\Http::getHeader' => ['mixed', 'name='=>'string'],
    'Yaf\Response\Http::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response\Http::response' => ['bool'],
    'Yaf\Response\Http::setAllHeaders' => ['bool', 'headers'=>'array'],
    'Yaf\Response\Http::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response\Http::setHeader' => ['bool', 'name'=>'string', 'value'=>'string', 'replace='=>'bool', 'response_code='=>'int'],
    'Yaf\Response\Http::setRedirect' => ['bool', 'url'=>'string'],
    'Yaf\Response_Abstract::__clone' => ['void'],
    'Yaf\Response_Abstract::__construct' => ['void'],
    'Yaf\Response_Abstract::__destruct' => ['void'],
    'Yaf\Response_Abstract::__toString' => ['void'],
    'Yaf\Response_Abstract::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response_Abstract::clearBody' => ['bool', 'key='=>'string'],
    'Yaf\Response_Abstract::getBody' => ['mixed', 'key='=>'?string'],
    'Yaf\Response_Abstract::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Response_Abstract::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf\Route\Map::__construct' => ['void', 'controller_prefer='=>'bool', 'delimiter='=>'string'],
    'Yaf\Route\Map::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
    'Yaf\Route\Map::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Route\Regex::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'map='=>'?array', 'verify='=>'?array', 'reverse='=>'string'],
    'Yaf\Route\Regex::addConfig' => ['Yaf\Router|bool', 'config'=>'Yaf\Config_Abstract'],
    'Yaf\Route\Regex::addRoute' => ['Yaf\Router|bool', 'name'=>'string', 'route'=>'Yaf\Route_Interface'],
    'Yaf\Route\Regex::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
    'Yaf\Route\Regex::getCurrentRoute' => ['string'],
    'Yaf\Route\Regex::getRoute' => ['Yaf\Route_Interface', 'name'=>'string'],
    'Yaf\Route\Regex::getRoutes' => ['Yaf\Route_Interface[]'],
    'Yaf\Route\Regex::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Route\Rewrite::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'verify='=>'?array', 'reverse='=>'string'],
    'Yaf\Route\Rewrite::addConfig' => ['Yaf\Router|bool', 'config'=>'Yaf\Config_Abstract'],
    'Yaf\Route\Rewrite::addRoute' => ['Yaf\Router|bool', 'name'=>'string', 'route'=>'Yaf\Route_Interface'],
    'Yaf\Route\Rewrite::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
    'Yaf\Route\Rewrite::getCurrentRoute' => ['string'],
    'Yaf\Route\Rewrite::getRoute' => ['Yaf\Route_Interface', 'name'=>'string'],
    'Yaf\Route\Rewrite::getRoutes' => ['Yaf\Route_Interface[]'],
    'Yaf\Route\Rewrite::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Route\Simple::__construct' => ['void', 'module_name'=>'string', 'controller_name'=>'string', 'action_name'=>'string'],
    'Yaf\Route\Simple::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
    'Yaf\Route\Simple::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Route\Supervar::__construct' => ['void', 'supervar_name'=>'string'],
    'Yaf\Route\Supervar::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
    'Yaf\Route\Supervar::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Route_Interface::__construct' => ['Yaf\Route_Interface'],
    'Yaf\Route_Interface::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
    'Yaf\Route_Interface::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Route_Static::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
    'Yaf\Route_Static::match' => ['bool', 'uri'=>'string'],
    'Yaf\Route_Static::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Router::__construct' => ['void'],
    'Yaf\Router::addConfig' => ['Yaf\Router|false', 'config'=>'Yaf\Config_Abstract'],
    'Yaf\Router::addRoute' => ['Yaf\Router|false', 'name'=>'string', 'route'=>'Yaf\Route_Interface'],
    'Yaf\Router::getCurrentRoute' => ['string'],
    'Yaf\Router::getRoute' => ['Yaf\Route_Interface', 'name'=>'string'],
    'Yaf\Router::getRoutes' => ['Yaf\Route_Interface[]'],
    'Yaf\Router::route' => ['Yaf\Router|false', 'request'=>'Yaf\Request_Abstract'],
    'Yaf\Session::__clone' => ['void'],
    'Yaf\Session::__construct' => ['void'],
    'Yaf\Session::__get' => ['void', 'name'=>''],
    'Yaf\Session::__isset' => ['void', 'name'=>''],
    'Yaf\Session::__set' => ['void', 'name'=>'', 'value'=>''],
    'Yaf\Session::__sleep' => ['list<string>'],
    'Yaf\Session::__unset' => ['void', 'name'=>''],
    'Yaf\Session::__wakeup' => ['void'],
    'Yaf\Session::count' => ['int'],
    'Yaf\Session::current' => ['mixed'],
    'Yaf\Session::del' => ['Yaf\Session|false', 'name'=>'string'],
    'Yaf\Session::get' => ['mixed', 'name'=>'string'],
    'Yaf\Session::getInstance' => ['Yaf\Session'],
    'Yaf\Session::has' => ['bool', 'name'=>'string'],
    'Yaf\Session::key' => ['int|string'],
    'Yaf\Session::next' => ['void'],
    'Yaf\Session::offsetExists' => ['bool', 'name'=>'mixed'],
    'Yaf\Session::offsetGet' => ['mixed', 'name'=>'mixed'],
    'Yaf\Session::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
    'Yaf\Session::offsetUnset' => ['void', 'name'=>'mixed'],
    'Yaf\Session::rewind' => ['void'],
    'Yaf\Session::set' => ['Yaf\Session|false', 'name'=>'string', 'value'=>'mixed'],
    'Yaf\Session::start' => ['Yaf\Session'],
    'Yaf\Session::valid' => ['bool'],
    'Yaf\View\Simple::__construct' => ['void', 'template_dir'=>'string', 'options='=>'?array'],
    'Yaf\View\Simple::__get' => ['mixed', 'name='=>'null'],
    'Yaf\View\Simple::__isset' => ['', 'name'=>'string'],
    'Yaf\View\Simple::__set' => ['void', 'name'=>'string', 'value='=>'mixed'],
    'Yaf\View\Simple::assign' => ['Yaf\View\Simple', 'name'=>'array|string', 'value='=>'mixed'],
    'Yaf\View\Simple::assignRef' => ['Yaf\View\Simple', 'name'=>'string', '&value'=>'mixed'],
    'Yaf\View\Simple::clear' => ['Yaf\View\Simple', 'name='=>'string'],
    'Yaf\View\Simple::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'?array'],
    'Yaf\View\Simple::eval' => ['bool|void', 'tpl_str'=>'string', 'vars='=>'?array'],
    'Yaf\View\Simple::getScriptPath' => ['string'],
    'Yaf\View\Simple::render' => ['string|void', 'tpl'=>'string', 'tpl_vars='=>'?array'],
    'Yaf\View\Simple::setScriptPath' => ['Yaf\View\Simple', 'template_dir'=>'string'],
    'Yaf\View_Interface::assign' => ['bool', 'name'=>'array|string', 'value'=>'mixed'],
    'Yaf\View_Interface::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'?array'],
    'Yaf\View_Interface::getScriptPath' => ['string'],
    'Yaf\View_Interface::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'?array'],
    'Yaf\View_Interface::setScriptPath' => ['void', 'template_dir'=>'string'],
    'Yaf_Action_Abstract::__clone' => ['void'],
    'Yaf_Action_Abstract::__construct' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract', 'view'=>'Yaf_View_Interface', 'invokeArgs='=>'?array'],
    'Yaf_Action_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'],
    'Yaf_Action_Abstract::execute' => ['mixed', 'arg='=>'mixed', '...args='=>'mixed'],
    'Yaf_Action_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'],
    'Yaf_Action_Abstract::getController' => ['Yaf_Controller_Abstract'],
    'Yaf_Action_Abstract::getControllerName' => ['string'],
    'Yaf_Action_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'],
    'Yaf_Action_Abstract::getInvokeArgs' => ['array'],
    'Yaf_Action_Abstract::getModuleName' => ['string'],
    'Yaf_Action_Abstract::getRequest' => ['Yaf_Request_Abstract'],
    'Yaf_Action_Abstract::getResponse' => ['Yaf_Response_Abstract'],
    'Yaf_Action_Abstract::getView' => ['Yaf_View_Interface'],
    'Yaf_Action_Abstract::getViewpath' => ['string'],
    'Yaf_Action_Abstract::init' => [''],
    'Yaf_Action_Abstract::initView' => ['Yaf_Response_Abstract', 'options='=>'?array'],
    'Yaf_Action_Abstract::redirect' => ['bool', 'url'=>'string'],
    'Yaf_Action_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'],
    'Yaf_Action_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'],
    'Yaf_Application::__clone' => ['void'],
    'Yaf_Application::__construct' => ['void', 'config'=>'mixed', 'envrion='=>'string'],
    'Yaf_Application::__destruct' => ['void'],
    'Yaf_Application::__sleep' => ['list<string>'],
    'Yaf_Application::__wakeup' => ['void'],
    'Yaf_Application::app' => ['?Yaf_Application'],
    'Yaf_Application::bootstrap' => ['Yaf_Application', 'bootstrap='=>'Yaf_Bootstrap_Abstract'],
    'Yaf_Application::clearLastError' => ['Yaf_Application'],
    'Yaf_Application::environ' => ['string'],
    'Yaf_Application::execute' => ['void', 'entry'=>'callable', '...args'=>'string'],
    'Yaf_Application::getAppDirectory' => ['Yaf_Application'],
    'Yaf_Application::getConfig' => ['Yaf_Config_Abstract'],
    'Yaf_Application::getDispatcher' => ['Yaf_Dispatcher'],
    'Yaf_Application::getLastErrorMsg' => ['string'],
    'Yaf_Application::getLastErrorNo' => ['int'],
    'Yaf_Application::getModules' => ['array'],
    'Yaf_Application::run' => ['void'],
    'Yaf_Application::setAppDirectory' => ['Yaf_Application', 'directory'=>'string'],
    'Yaf_Config_Abstract::__construct' => ['void'],
    'Yaf_Config_Abstract::get' => ['mixed', 'name'=>'string', 'value'=>'mixed'],
    'Yaf_Config_Abstract::readonly' => ['bool'],
    'Yaf_Config_Abstract::set' => ['Yaf_Config_Abstract'],
    'Yaf_Config_Abstract::toArray' => ['array'],
    'Yaf_Config_Ini::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'],
    'Yaf_Config_Ini::__get' => ['void', 'name='=>'string'],
    'Yaf_Config_Ini::__isset' => ['void', 'name'=>'string'],
    'Yaf_Config_Ini::__set' => ['void', 'name'=>'string', 'value'=>'mixed'],
    'Yaf_Config_Ini::count' => ['void'],
    'Yaf_Config_Ini::current' => ['void'],
    'Yaf_Config_Ini::get' => ['mixed', 'name='=>'mixed'],
    'Yaf_Config_Ini::key' => ['void'],
    'Yaf_Config_Ini::next' => ['void'],
    'Yaf_Config_Ini::offsetExists' => ['void', 'name'=>'string'],
    'Yaf_Config_Ini::offsetGet' => ['void', 'name'=>'string'],
    'Yaf_Config_Ini::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'],
    'Yaf_Config_Ini::offsetUnset' => ['void', 'name'=>'string'],
    'Yaf_Config_Ini::readonly' => ['void'],
    'Yaf_Config_Ini::rewind' => ['void'],
    'Yaf_Config_Ini::set' => ['Yaf_Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
    'Yaf_Config_Ini::toArray' => ['array'],
    'Yaf_Config_Ini::valid' => ['void'],
    'Yaf_Config_Simple::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'],
    'Yaf_Config_Simple::__get' => ['void', 'name='=>'string'],
    'Yaf_Config_Simple::__isset' => ['void', 'name'=>'string'],
    'Yaf_Config_Simple::__set' => ['void', 'name'=>'string', 'value'=>'string'],
    'Yaf_Config_Simple::count' => ['void'],
    'Yaf_Config_Simple::current' => ['void'],
    'Yaf_Config_Simple::get' => ['mixed', 'name='=>'mixed'],
    'Yaf_Config_Simple::key' => ['void'],
    'Yaf_Config_Simple::next' => ['void'],
    'Yaf_Config_Simple::offsetExists' => ['void', 'name'=>'string'],
    'Yaf_Config_Simple::offsetGet' => ['void', 'name'=>'string'],
    'Yaf_Config_Simple::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'],
    'Yaf_Config_Simple::offsetUnset' => ['void', 'name'=>'string'],
    'Yaf_Config_Simple::readonly' => ['void'],
    'Yaf_Config_Simple::rewind' => ['void'],
    'Yaf_Config_Simple::set' => ['Yaf_Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
    'Yaf_Config_Simple::toArray' => ['array'],
    'Yaf_Config_Simple::valid' => ['void'],
    'Yaf_Controller_Abstract::__clone' => ['void'],
    'Yaf_Controller_Abstract::__construct' => ['void'],
    'Yaf_Controller_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'array'],
    'Yaf_Controller_Abstract::forward' => ['void', 'action'=>'string', 'parameters='=>'array'],
    'Yaf_Controller_Abstract::forward\'1' => ['void', 'controller'=>'string', 'action'=>'string', 'parameters='=>'array'],
    'Yaf_Controller_Abstract::forward\'2' => ['void', 'module'=>'string', 'controller'=>'string', 'action'=>'string', 'parameters='=>'array'],
    'Yaf_Controller_Abstract::getInvokeArg' => ['void', 'name'=>'string'],
    'Yaf_Controller_Abstract::getInvokeArgs' => ['void'],
    'Yaf_Controller_Abstract::getModuleName' => ['string'],
    'Yaf_Controller_Abstract::getName' => ['string'],
    'Yaf_Controller_Abstract::getRequest' => ['Yaf_Request_Abstract'],
    'Yaf_Controller_Abstract::getResponse' => ['Yaf_Response_Abstract'],
    'Yaf_Controller_Abstract::getView' => ['Yaf_View_Interface'],
    'Yaf_Controller_Abstract::getViewpath' => ['void'],
    'Yaf_Controller_Abstract::init' => ['void'],
    'Yaf_Controller_Abstract::initView' => ['void', 'options='=>'array'],
    'Yaf_Controller_Abstract::redirect' => ['bool', 'url'=>'string'],
    'Yaf_Controller_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'array'],
    'Yaf_Controller_Abstract::setViewpath' => ['void', 'view_directory'=>'string'],
    'Yaf_Dispatcher::__clone' => ['void'],
    'Yaf_Dispatcher::__construct' => ['void'],
    'Yaf_Dispatcher::__sleep' => ['list<string>'],
    'Yaf_Dispatcher::__wakeup' => ['void'],
    'Yaf_Dispatcher::autoRender' => ['Yaf_Dispatcher', 'flag='=>'bool'],
    'Yaf_Dispatcher::catchException' => ['Yaf_Dispatcher', 'flag='=>'bool'],
    'Yaf_Dispatcher::disableView' => ['bool'],
    'Yaf_Dispatcher::dispatch' => ['Yaf_Response_Abstract', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Dispatcher::enableView' => ['Yaf_Dispatcher'],
    'Yaf_Dispatcher::flushInstantly' => ['Yaf_Dispatcher', 'flag='=>'bool'],
    'Yaf_Dispatcher::getApplication' => ['Yaf_Application'],
    'Yaf_Dispatcher::getDefaultAction' => ['string'],
    'Yaf_Dispatcher::getDefaultController' => ['string'],
    'Yaf_Dispatcher::getDefaultModule' => ['string'],
    'Yaf_Dispatcher::getInstance' => ['Yaf_Dispatcher'],
    'Yaf_Dispatcher::getRequest' => ['Yaf_Request_Abstract'],
    'Yaf_Dispatcher::getRouter' => ['Yaf_Router'],
    'Yaf_Dispatcher::initView' => ['Yaf_View_Interface', 'templates_dir'=>'string', 'options='=>'array'],
    'Yaf_Dispatcher::registerPlugin' => ['Yaf_Dispatcher', 'plugin'=>'Yaf_Plugin_Abstract'],
    'Yaf_Dispatcher::returnResponse' => ['Yaf_Dispatcher', 'flag'=>'bool'],
    'Yaf_Dispatcher::setDefaultAction' => ['Yaf_Dispatcher', 'action'=>'string'],
    'Yaf_Dispatcher::setDefaultController' => ['Yaf_Dispatcher', 'controller'=>'string'],
    'Yaf_Dispatcher::setDefaultModule' => ['Yaf_Dispatcher', 'module'=>'string'],
    'Yaf_Dispatcher::setErrorHandler' => ['Yaf_Dispatcher', 'callback'=>'callable', 'error_types'=>'int'],
    'Yaf_Dispatcher::setRequest' => ['Yaf_Dispatcher', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Dispatcher::setView' => ['Yaf_Dispatcher', 'view'=>'Yaf_View_Interface'],
    'Yaf_Dispatcher::throwException' => ['Yaf_Dispatcher', 'flag='=>'bool'],
    'Yaf_Exception::__construct' => ['void'],
    'Yaf_Exception::getPrevious' => ['void'],
    'Yaf_Loader::__clone' => ['void'],
    'Yaf_Loader::__construct' => ['void'],
    'Yaf_Loader::__sleep' => ['list<string>'],
    'Yaf_Loader::__wakeup' => ['void'],
    'Yaf_Loader::autoload' => ['void'],
    'Yaf_Loader::clearLocalNamespace' => ['void'],
    'Yaf_Loader::getInstance' => ['Yaf_Loader'],
    'Yaf_Loader::getLibraryPath' => ['Yaf_Loader', 'is_global='=>'bool'],
    'Yaf_Loader::getLocalNamespace' => ['void'],
    'Yaf_Loader::getNamespacePath' => ['string', 'namespaces'=>'string'],
    'Yaf_Loader::import' => ['bool'],
    'Yaf_Loader::isLocalName' => ['bool'],
    'Yaf_Loader::registerLocalNamespace' => ['void', 'prefix'=>'mixed'],
    'Yaf_Loader::registerNamespace' => ['bool', 'namespaces'=>'string|array', 'path='=>'string'],
    'Yaf_Loader::setLibraryPath' => ['Yaf_Loader', 'directory'=>'string', 'is_global='=>'bool'],
    'Yaf_Plugin_Abstract::dispatchLoopShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
    'Yaf_Plugin_Abstract::dispatchLoopStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
    'Yaf_Plugin_Abstract::postDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
    'Yaf_Plugin_Abstract::preDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
    'Yaf_Plugin_Abstract::preResponse' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
    'Yaf_Plugin_Abstract::routerShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
    'Yaf_Plugin_Abstract::routerStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
    'Yaf_Registry::__clone' => ['void'],
    'Yaf_Registry::__construct' => ['void'],
    'Yaf_Registry::del' => ['void', 'name'=>'string'],
    'Yaf_Registry::get' => ['mixed', 'name'=>'string'],
    'Yaf_Registry::has' => ['bool', 'name'=>'string'],
    'Yaf_Registry::set' => ['bool', 'name'=>'string', 'value'=>'string'],
    'Yaf_Request_Abstract::clearParams' => ['bool'],
    'Yaf_Request_Abstract::getActionName' => ['void'],
    'Yaf_Request_Abstract::getBaseUri' => ['void'],
    'Yaf_Request_Abstract::getControllerName' => ['void'],
    'Yaf_Request_Abstract::getEnv' => ['void', 'name'=>'string', 'default='=>'string'],
    'Yaf_Request_Abstract::getException' => ['void'],
    'Yaf_Request_Abstract::getLanguage' => ['void'],
    'Yaf_Request_Abstract::getMethod' => ['void'],
    'Yaf_Request_Abstract::getModuleName' => ['void'],
    'Yaf_Request_Abstract::getParam' => ['void', 'name'=>'string', 'default='=>'string'],
    'Yaf_Request_Abstract::getParams' => ['void'],
    'Yaf_Request_Abstract::getRequestUri' => ['void'],
    'Yaf_Request_Abstract::getServer' => ['void', 'name'=>'string', 'default='=>'string'],
    'Yaf_Request_Abstract::isCli' => ['void'],
    'Yaf_Request_Abstract::isDispatched' => ['void'],
    'Yaf_Request_Abstract::isGet' => ['void'],
    'Yaf_Request_Abstract::isHead' => ['void'],
    'Yaf_Request_Abstract::isOptions' => ['void'],
    'Yaf_Request_Abstract::isPost' => ['void'],
    'Yaf_Request_Abstract::isPut' => ['void'],
    'Yaf_Request_Abstract::isRouted' => ['void'],
    'Yaf_Request_Abstract::isXmlHttpRequest' => ['void'],
    'Yaf_Request_Abstract::setActionName' => ['void', 'action'=>'string'],
    'Yaf_Request_Abstract::setBaseUri' => ['bool', 'uir'=>'string'],
    'Yaf_Request_Abstract::setControllerName' => ['void', 'controller'=>'string'],
    'Yaf_Request_Abstract::setDispatched' => ['void'],
    'Yaf_Request_Abstract::setModuleName' => ['void', 'module'=>'string'],
    'Yaf_Request_Abstract::setParam' => ['void', 'name'=>'string', 'value='=>'string'],
    'Yaf_Request_Abstract::setRequestUri' => ['void', 'uir'=>'string'],
    'Yaf_Request_Abstract::setRouted' => ['void', 'flag='=>'string'],
    'Yaf_Request_Http::__clone' => ['void'],
    'Yaf_Request_Http::__construct' => ['void'],
    'Yaf_Request_Http::get' => ['mixed', 'name'=>'string', 'default='=>'string'],
    'Yaf_Request_Http::getActionName' => ['string'],
    'Yaf_Request_Http::getBaseUri' => ['string'],
    'Yaf_Request_Http::getControllerName' => ['string'],
    'Yaf_Request_Http::getCookie' => ['mixed', 'name'=>'string', 'default='=>'string'],
    'Yaf_Request_Http::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf_Request_Http::getException' => ['Yaf_Exception'],
    'Yaf_Request_Http::getFiles' => ['void'],
    'Yaf_Request_Http::getLanguage' => ['string'],
    'Yaf_Request_Http::getMethod' => ['string'],
    'Yaf_Request_Http::getModuleName' => ['string'],
    'Yaf_Request_Http::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
    'Yaf_Request_Http::getParams' => ['array'],
    'Yaf_Request_Http::getPost' => ['mixed', 'name'=>'string', 'default='=>'string'],
    'Yaf_Request_Http::getQuery' => ['mixed', 'name'=>'string', 'default='=>'string'],
    'Yaf_Request_Http::getRaw' => ['mixed'],
    'Yaf_Request_Http::getRequest' => ['void'],
    'Yaf_Request_Http::getRequestUri' => ['string'],
    'Yaf_Request_Http::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf_Request_Http::isCli' => ['bool'],
    'Yaf_Request_Http::isDispatched' => ['bool'],
    'Yaf_Request_Http::isGet' => ['bool'],
    'Yaf_Request_Http::isHead' => ['bool'],
    'Yaf_Request_Http::isOptions' => ['bool'],
    'Yaf_Request_Http::isPost' => ['bool'],
    'Yaf_Request_Http::isPut' => ['bool'],
    'Yaf_Request_Http::isRouted' => ['bool'],
    'Yaf_Request_Http::isXmlHttpRequest' => ['bool'],
    'Yaf_Request_Http::setActionName' => ['Yaf_Request_Abstract|bool', 'action'=>'string'],
    'Yaf_Request_Http::setBaseUri' => ['bool', 'uri'=>'string'],
    'Yaf_Request_Http::setControllerName' => ['Yaf_Request_Abstract|bool', 'controller'=>'string'],
    'Yaf_Request_Http::setDispatched' => ['bool'],
    'Yaf_Request_Http::setModuleName' => ['Yaf_Request_Abstract|bool', 'module'=>'string'],
    'Yaf_Request_Http::setParam' => ['Yaf_Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
    'Yaf_Request_Http::setRequestUri' => ['', 'uri'=>'string'],
    'Yaf_Request_Http::setRouted' => ['Yaf_Request_Abstract|bool'],
    'Yaf_Request_Simple::__clone' => ['void'],
    'Yaf_Request_Simple::__construct' => ['void'],
    'Yaf_Request_Simple::get' => ['void'],
    'Yaf_Request_Simple::getActionName' => ['string'],
    'Yaf_Request_Simple::getBaseUri' => ['string'],
    'Yaf_Request_Simple::getControllerName' => ['string'],
    'Yaf_Request_Simple::getCookie' => ['void'],
    'Yaf_Request_Simple::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf_Request_Simple::getException' => ['Yaf_Exception'],
    'Yaf_Request_Simple::getFiles' => ['void'],
    'Yaf_Request_Simple::getLanguage' => ['string'],
    'Yaf_Request_Simple::getMethod' => ['string'],
    'Yaf_Request_Simple::getModuleName' => ['string'],
    'Yaf_Request_Simple::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
    'Yaf_Request_Simple::getParams' => ['array'],
    'Yaf_Request_Simple::getPost' => ['void'],
    'Yaf_Request_Simple::getQuery' => ['void'],
    'Yaf_Request_Simple::getRequest' => ['void'],
    'Yaf_Request_Simple::getRequestUri' => ['string'],
    'Yaf_Request_Simple::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
    'Yaf_Request_Simple::isCli' => ['bool'],
    'Yaf_Request_Simple::isDispatched' => ['bool'],
    'Yaf_Request_Simple::isGet' => ['bool'],
    'Yaf_Request_Simple::isHead' => ['bool'],
    'Yaf_Request_Simple::isOptions' => ['bool'],
    'Yaf_Request_Simple::isPost' => ['bool'],
    'Yaf_Request_Simple::isPut' => ['bool'],
    'Yaf_Request_Simple::isRouted' => ['bool'],
    'Yaf_Request_Simple::isXmlHttpRequest' => ['void'],
    'Yaf_Request_Simple::setActionName' => ['Yaf_Request_Abstract|bool', 'action'=>'string'],
    'Yaf_Request_Simple::setBaseUri' => ['bool', 'uri'=>'string'],
    'Yaf_Request_Simple::setControllerName' => ['Yaf_Request_Abstract|bool', 'controller'=>'string'],
    'Yaf_Request_Simple::setDispatched' => ['bool'],
    'Yaf_Request_Simple::setModuleName' => ['Yaf_Request_Abstract|bool', 'module'=>'string'],
    'Yaf_Request_Simple::setParam' => ['Yaf_Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
    'Yaf_Request_Simple::setRequestUri' => ['', 'uri'=>'string'],
    'Yaf_Request_Simple::setRouted' => ['Yaf_Request_Abstract|bool'],
    'Yaf_Response_Abstract::__clone' => ['void'],
    'Yaf_Response_Abstract::__construct' => ['void'],
    'Yaf_Response_Abstract::__destruct' => ['void'],
    'Yaf_Response_Abstract::__toString' => ['string'],
    'Yaf_Response_Abstract::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Abstract::clearBody' => ['bool', 'key='=>'string'],
    'Yaf_Response_Abstract::clearHeaders' => ['void'],
    'Yaf_Response_Abstract::getBody' => ['mixed', 'key='=>'string'],
    'Yaf_Response_Abstract::getHeader' => ['void'],
    'Yaf_Response_Abstract::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Abstract::response' => ['void'],
    'Yaf_Response_Abstract::setAllHeaders' => ['void'],
    'Yaf_Response_Abstract::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Abstract::setHeader' => ['void'],
    'Yaf_Response_Abstract::setRedirect' => ['void'],
    'Yaf_Response_Cli::__clone' => ['void'],
    'Yaf_Response_Cli::__construct' => ['void'],
    'Yaf_Response_Cli::__destruct' => ['void'],
    'Yaf_Response_Cli::__toString' => ['string'],
    'Yaf_Response_Cli::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Cli::clearBody' => ['bool', 'key='=>'string'],
    'Yaf_Response_Cli::getBody' => ['mixed', 'key='=>'?string'],
    'Yaf_Response_Cli::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Cli::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Http::__clone' => ['void'],
    'Yaf_Response_Http::__construct' => ['void'],
    'Yaf_Response_Http::__destruct' => ['void'],
    'Yaf_Response_Http::__toString' => ['string'],
    'Yaf_Response_Http::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Http::clearBody' => ['bool', 'key='=>'string'],
    'Yaf_Response_Http::clearHeaders' => ['Yaf_Response_Abstract|false', 'name='=>'string'],
    'Yaf_Response_Http::getBody' => ['mixed', 'key='=>'?string'],
    'Yaf_Response_Http::getHeader' => ['mixed', 'name='=>'string'],
    'Yaf_Response_Http::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Http::response' => ['bool'],
    'Yaf_Response_Http::setAllHeaders' => ['bool', 'headers'=>'array'],
    'Yaf_Response_Http::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
    'Yaf_Response_Http::setHeader' => ['bool', 'name'=>'string', 'value'=>'string', 'replace='=>'bool', 'response_code='=>'int'],
    'Yaf_Response_Http::setRedirect' => ['bool', 'url'=>'string'],
    'Yaf_Route_Interface::__construct' => ['void'],
    'Yaf_Route_Interface::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
    'Yaf_Route_Interface::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Route_Map::__construct' => ['void', 'controller_prefer='=>'string', 'delimiter='=>'string'],
    'Yaf_Route_Map::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
    'Yaf_Route_Map::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Route_Regex::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'map='=>'array', 'verify='=>'array', 'reverse='=>'string'],
    'Yaf_Route_Regex::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'],
    'Yaf_Route_Regex::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'],
    'Yaf_Route_Regex::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
    'Yaf_Route_Regex::getCurrentRoute' => ['string'],
    'Yaf_Route_Regex::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'],
    'Yaf_Route_Regex::getRoutes' => ['Yaf_Route_Interface[]'],
    'Yaf_Route_Regex::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Route_Rewrite::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'verify='=>'array'],
    'Yaf_Route_Rewrite::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'],
    'Yaf_Route_Rewrite::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'],
    'Yaf_Route_Rewrite::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
    'Yaf_Route_Rewrite::getCurrentRoute' => ['string'],
    'Yaf_Route_Rewrite::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'],
    'Yaf_Route_Rewrite::getRoutes' => ['Yaf_Route_Interface[]'],
    'Yaf_Route_Rewrite::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Route_Simple::__construct' => ['void', 'module_name'=>'string', 'controller_name'=>'string', 'action_name'=>'string'],
    'Yaf_Route_Simple::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
    'Yaf_Route_Simple::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Route_Static::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
    'Yaf_Route_Static::match' => ['void', 'uri'=>'string'],
    'Yaf_Route_Static::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Route_Supervar::__construct' => ['void', 'supervar_name'=>'string'],
    'Yaf_Route_Supervar::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
    'Yaf_Route_Supervar::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Router::__construct' => ['void'],
    'Yaf_Router::addConfig' => ['bool', 'config'=>'Yaf_Config_Abstract'],
    'Yaf_Router::addRoute' => ['bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'],
    'Yaf_Router::getCurrentRoute' => ['string'],
    'Yaf_Router::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'],
    'Yaf_Router::getRoutes' => ['mixed'],
    'Yaf_Router::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
    'Yaf_Session::__clone' => ['void'],
    'Yaf_Session::__construct' => ['void'],
    'Yaf_Session::__get' => ['void', 'name'=>'string'],
    'Yaf_Session::__isset' => ['void', 'name'=>'string'],
    'Yaf_Session::__set' => ['void', 'name'=>'string', 'value'=>'string'],
    'Yaf_Session::__sleep' => ['list<string>'],
    'Yaf_Session::__unset' => ['void', 'name'=>'string'],
    'Yaf_Session::__wakeup' => ['void'],
    'Yaf_Session::count' => ['void'],
    'Yaf_Session::current' => ['void'],
    'Yaf_Session::del' => ['void', 'name'=>'string'],
    'Yaf_Session::get' => ['mixed', 'name'=>'string'],
    'Yaf_Session::getInstance' => ['void'],
    'Yaf_Session::has' => ['void', 'name'=>'string'],
    'Yaf_Session::key' => ['void'],
    'Yaf_Session::next' => ['void'],
    'Yaf_Session::offsetExists' => ['void', 'name'=>'string'],
    'Yaf_Session::offsetGet' => ['void', 'name'=>'string'],
    'Yaf_Session::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'],
    'Yaf_Session::offsetUnset' => ['void', 'name'=>'string'],
    'Yaf_Session::rewind' => ['void'],
    'Yaf_Session::set' => ['Yaf_Session|bool', 'name'=>'string', 'value'=>'mixed'],
    'Yaf_Session::start' => ['void'],
    'Yaf_Session::valid' => ['void'],
    'Yaf_View_Interface::assign' => ['bool', 'name'=>'string', 'value='=>'string'],
    'Yaf_View_Interface::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'array'],
    'Yaf_View_Interface::getScriptPath' => ['string'],
    'Yaf_View_Interface::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'array'],
    'Yaf_View_Interface::setScriptPath' => ['void', 'template_dir'=>'string'],
    'Yaf_View_Simple::__construct' => ['void', 'tempalte_dir'=>'string', 'options='=>'array'],
    'Yaf_View_Simple::__get' => ['void', 'name='=>'string'],
    'Yaf_View_Simple::__isset' => ['void', 'name'=>'string'],
    'Yaf_View_Simple::__set' => ['void', 'name'=>'string', 'value'=>'mixed'],
    'Yaf_View_Simple::assign' => ['bool', 'name'=>'string', 'value='=>'mixed'],
    'Yaf_View_Simple::assignRef' => ['bool', 'name'=>'string', '&rw_value'=>'mixed'],
    'Yaf_View_Simple::clear' => ['bool', 'name='=>'string'],
    'Yaf_View_Simple::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'array'],
    'Yaf_View_Simple::eval' => ['string', 'tpl_content'=>'string', 'tpl_vars='=>'array'],
    'Yaf_View_Simple::getScriptPath' => ['string'],
    'Yaf_View_Simple::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'array'],
    'Yaf_View_Simple::setScriptPath' => ['bool', 'template_dir'=>'string'],
    'Yar_Client::__call' => ['void', 'method'=>'string', 'parameters'=>'array'],
    'Yar_Client::__construct' => ['void', 'url'=>'string'],
    'Yar_Client::setOpt' => ['Yar_Client|false', 'name'=>'int', 'value'=>'mixed'],
    'Yar_Client_Exception::__clone' => ['void'],
    'Yar_Client_Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'Yar_Client_Exception::__toString' => ['string'],
    'Yar_Client_Exception::__wakeup' => ['void'],
    'Yar_Client_Exception::getCode' => ['int'],
    'Yar_Client_Exception::getFile' => ['string'],
    'Yar_Client_Exception::getLine' => ['int'],
    'Yar_Client_Exception::getMessage' => ['string'],
    'Yar_Client_Exception::getPrevious' => ['?Exception|?Throwable'],
    'Yar_Client_Exception::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'Yar_Client_Exception::getTraceAsString' => ['string'],
    'Yar_Client_Exception::getType' => ['string'],
    'Yar_Concurrent_Client::call' => ['int', 'uri'=>'string', 'method'=>'string', 'parameters'=>'array', 'callback='=>'callable'],
    'Yar_Concurrent_Client::loop' => ['bool', 'callback='=>'callable', 'error_callback='=>'callable'],
    'Yar_Concurrent_Client::reset' => ['bool'],
    'Yar_Server::__construct' => ['void', 'object'=>'Object'],
    'Yar_Server::handle' => ['bool'],
    'Yar_Server_Exception::__clone' => ['void'],
    'Yar_Server_Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
    'Yar_Server_Exception::__toString' => ['string'],
    'Yar_Server_Exception::__wakeup' => ['void'],
    'Yar_Server_Exception::getCode' => ['int'],
    'Yar_Server_Exception::getFile' => ['string'],
    'Yar_Server_Exception::getLine' => ['int'],
    'Yar_Server_Exception::getMessage' => ['string'],
    'Yar_Server_Exception::getPrevious' => ['?Exception|?Throwable'],
    'Yar_Server_Exception::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'Yar_Server_Exception::getTraceAsString' => ['string'],
    'Yar_Server_Exception::getType' => ['string'],
    'ZMQ::__construct' => ['void'],
    'ZMQContext::__construct' => ['void', 'io_threads='=>'int', 'is_persistent='=>'bool'],
    'ZMQContext::getOpt' => ['int|string', 'key'=>'string'],
    'ZMQContext::getSocket' => ['ZMQSocket', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'],
    'ZMQContext::isPersistent' => ['bool'],
    'ZMQContext::setOpt' => ['ZMQContext', 'key'=>'int', 'value'=>'mixed'],
    'ZMQDevice::__construct' => ['void', 'frontend'=>'ZMQSocket', 'backend'=>'ZMQSocket', 'listener='=>'ZMQSocket'],
    'ZMQDevice::getIdleTimeout' => ['ZMQDevice'],
    'ZMQDevice::getTimerTimeout' => ['ZMQDevice'],
    'ZMQDevice::run' => ['void'],
    'ZMQDevice::setIdleCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'],
    'ZMQDevice::setIdleTimeout' => ['ZMQDevice', 'timeout'=>'int'],
    'ZMQDevice::setTimerCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'],
    'ZMQDevice::setTimerTimeout' => ['ZMQDevice', 'timeout'=>'int'],
    'ZMQPoll::add' => ['string', 'entry'=>'mixed', 'type'=>'int'],
    'ZMQPoll::clear' => ['ZMQPoll'],
    'ZMQPoll::count' => ['int'],
    'ZMQPoll::getLastErrors' => ['array'],
    'ZMQPoll::poll' => ['int', '&w_readable'=>'array', '&w_writable'=>'array', 'timeout='=>'int'],
    'ZMQPoll::remove' => ['bool', 'item'=>'mixed'],
    'ZMQSocket::__construct' => ['void', 'context'=>'ZMQContext', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'],
    'ZMQSocket::bind' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'],
    'ZMQSocket::connect' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'],
    'ZMQSocket::disconnect' => ['ZMQSocket', 'dsn'=>'string'],
    'ZMQSocket::getEndpoints' => ['array'],
    'ZMQSocket::getPersistentId' => ['?string'],
    'ZMQSocket::getSockOpt' => ['int|string', 'key'=>'string'],
    'ZMQSocket::getSocketType' => ['int'],
    'ZMQSocket::isPersistent' => ['bool'],
    'ZMQSocket::recv' => ['string', 'mode='=>'int'],
    'ZMQSocket::recvMulti' => ['string[]', 'mode='=>'int'],
    'ZMQSocket::send' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'],
    'ZMQSocket::send\'1' => ['ZMQSocket', 'message'=>'string', 'mode='=>'int'],
    'ZMQSocket::sendmulti' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'],
    'ZMQSocket::setSockOpt' => ['ZMQSocket', 'key'=>'int', 'value'=>'mixed'],
    'ZMQSocket::unbind' => ['ZMQSocket', 'dsn'=>'string'],
    'ZendAPI_Job::ZendAPI_Job' => ['Job', 'script'=>'script'],
    'ZendAPI_Job::addJobToQueue' => ['int', 'jobqueue_url'=>'string', 'password'=>'string'],
    'ZendAPI_Job::getApplicationID' => [''],
    'ZendAPI_Job::getEndTime' => [''],
    'ZendAPI_Job::getGlobalVariables' => [''],
    'ZendAPI_Job::getHost' => [''],
    'ZendAPI_Job::getID' => [''],
    'ZendAPI_Job::getInterval' => [''],
    'ZendAPI_Job::getJobDependency' => [''],
    'ZendAPI_Job::getJobName' => [''],
    'ZendAPI_Job::getJobPriority' => [''],
    'ZendAPI_Job::getJobStatus' => ['int'],
    'ZendAPI_Job::getLastPerformedStatus' => ['int'],
    'ZendAPI_Job::getOutput' => ['An'],
    'ZendAPI_Job::getPreserved' => [''],
    'ZendAPI_Job::getProperties' => ['array'],
    'ZendAPI_Job::getScheduledTime' => [''],
    'ZendAPI_Job::getScript' => [''],
    'ZendAPI_Job::getTimeToNextRepeat' => ['int'],
    'ZendAPI_Job::getUserVariables' => [''],
    'ZendAPI_Job::setApplicationID' => ['', 'app_id'=>''],
    'ZendAPI_Job::setGlobalVariables' => ['', 'vars'=>''],
    'ZendAPI_Job::setJobDependency' => ['', 'job_id'=>''],
    'ZendAPI_Job::setJobName' => ['', 'name'=>''],
    'ZendAPI_Job::setJobPriority' => ['', 'priority'=>'int'],
    'ZendAPI_Job::setPreserved' => ['', 'preserved'=>''],
    'ZendAPI_Job::setRecurrenceData' => ['', 'interval'=>'', 'end_time='=>'mixed'],
    'ZendAPI_Job::setScheduledTime' => ['', 'timestamp'=>''],
    'ZendAPI_Job::setScript' => ['', 'script'=>''],
    'ZendAPI_Job::setUserVariables' => ['', 'vars'=>''],
    'ZendAPI_Queue::addJob' => ['int', '&job'=>'Job'],
    'ZendAPI_Queue::getAllApplicationIDs' => ['array'],
    'ZendAPI_Queue::getAllhosts' => ['array'],
    'ZendAPI_Queue::getHistoricJobs' => ['array', 'status'=>'int', 'start_time'=>'', 'end_time'=>'', 'index'=>'int', 'count'=>'int', '&total'=>'int'],
    'ZendAPI_Queue::getJob' => ['Job', 'job_id'=>'int'],
    'ZendAPI_Queue::getJobsInQueue' => ['array', 'filter_options='=>'array', 'max_jobs='=>'int', 'with_globals_and_output='=>'bool'],
    'ZendAPI_Queue::getLastError' => ['string'],
    'ZendAPI_Queue::getNumOfJobsInQueue' => ['int', 'filter_options='=>'array'],
    'ZendAPI_Queue::getStatistics' => ['array'],
    'ZendAPI_Queue::isScriptExists' => ['bool', 'path'=>'string'],
    'ZendAPI_Queue::isSuspend' => ['bool'],
    'ZendAPI_Queue::login' => ['bool', 'password'=>'string', 'application_id='=>'int'],
    'ZendAPI_Queue::removeJob' => ['bool', 'job_id'=>'array|int'],
    'ZendAPI_Queue::requeueJob' => ['bool', 'job'=>'Job'],
    'ZendAPI_Queue::resumeJob' => ['bool', 'job_id'=>'array|int'],
    'ZendAPI_Queue::resumeQueue' => ['bool'],
    'ZendAPI_Queue::setMaxHistoryTime' => ['bool'],
    'ZendAPI_Queue::suspendJob' => ['bool', 'job_id'=>'array|int'],
    'ZendAPI_Queue::suspendQueue' => ['bool'],
    'ZendAPI_Queue::updateJob' => ['int', '&job'=>'Job'],
    'ZendAPI_Queue::zendapi_queue' => ['ZendAPI_Queue', 'queue_url'=>'string'],
    'ZipArchive::addEmptyDir' => ['bool', 'dirname'=>'string'],
    'ZipArchive::addFile' => ['bool', 'filepath'=>'string', 'entryname='=>'string', 'start='=>'int', 'length='=>'int'],
    'ZipArchive::addFromString' => ['bool', 'name'=>'string', 'content'=>'string'],
    'ZipArchive::addGlob' => ['array|false', 'pattern'=>'string', 'flags='=>'int', 'options='=>'array'],
    'ZipArchive::addPattern' => ['array|false', 'pattern'=>'string', 'path='=>'string', 'options='=>'array'],
    'ZipArchive::close' => ['bool'],
    'ZipArchive::deleteIndex' => ['bool', 'index'=>'int'],
    'ZipArchive::deleteName' => ['bool', 'name'=>'string'],
    'ZipArchive::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string[]|string|null'],
    'ZipArchive::getArchiveComment' => ['string|false', 'flags='=>'int'],
    'ZipArchive::getCommentIndex' => ['string|false', 'index'=>'int', 'flags='=>'int'],
    'ZipArchive::getCommentName' => ['string|false', 'name'=>'string', 'flags='=>'int'],
    'ZipArchive::getExternalAttributesIndex' => ['bool', 'index'=>'int', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'],
    'ZipArchive::getExternalAttributesName' => ['bool', 'name'=>'string', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'],
    'ZipArchive::getFromIndex' => ['string|false', 'index'=>'int', 'len='=>'int', 'flags='=>'int'],
    'ZipArchive::getFromName' => ['string|false', 'name'=>'string', 'len='=>'int', 'flags='=>'int'],
    'ZipArchive::getNameIndex' => ['string|false', 'index'=>'int', 'flags='=>'int'],
    'ZipArchive::getStatusString' => ['string|false'],
    'ZipArchive::getStream' => ['resource|false', 'name'=>'string'],
    'ZipArchive::isCompressionMethodSupported' => ['bool', 'method'=>'int', 'encode='=>'bool'],
    'ZipArchive::isEncryptionMethodSupported' => ['bool', 'method'=>'int', 'encode='=>'bool'],
    'ZipArchive::locateName' => ['int|false', 'name'=>'string', 'flags='=>'int'],
    'ZipArchive::open' => ['int|bool', 'filename'=>'string', 'flags='=>'int'],
    'ZipArchive::registerCancelCallback' => ['bool', 'callback'=>'callable'],
    'ZipArchive::registerProgressCallback' => ['bool', 'rate'=>'float', 'callback'=>'callable'],
    'ZipArchive::renameIndex' => ['bool', 'index'=>'int', 'new_name'=>'string'],
    'ZipArchive::renameName' => ['bool', 'name'=>'string', 'new_name'=>'string'],
    'ZipArchive::replaceFile' => ['bool', 'filepath'=>'string', 'index'=>'int', 'start='=>'int', 'length='=>'int', 'flags='=>'int'],
    'ZipArchive::setArchiveComment' => ['bool', 'comment'=>'string'],
    'ZipArchive::setCommentIndex' => ['bool', 'index'=>'int', 'comment'=>'string'],
    'ZipArchive::setCommentName' => ['bool', 'name'=>'string', 'comment'=>'string'],
    'ZipArchive::setCompressionIndex' => ['bool', 'index'=>'int', 'comp_method'=>'int', 'comp_flags='=>'int'],
    'ZipArchive::setCompressionName' => ['bool', 'name'=>'string', 'comp_method'=>'int', 'comp_flags='=>'int'],
    'ZipArchive::setExternalAttributesIndex' => ['bool', 'index'=>'int', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'],
    'ZipArchive::setExternalAttributesName' => ['bool', 'name'=>'string', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'],
    'ZipArchive::setMtimeIndex' => ['bool', 'index'=>'int', 'timestamp'=>'int', 'flags='=>'int'],
    'ZipArchive::setMtimeName' => ['bool', 'name'=>'string', 'timestamp'=>'int', 'flags='=>'int'],
    'ZipArchive::setPassword' => ['bool', 'password'=>'string'],
    'ZipArchive::statIndex' => ['array|false', 'index'=>'int', 'flags='=>'int'],
    'ZipArchive::statName' => ['array|false', 'name'=>'string', 'flags='=>'int'],
    'ZipArchive::unchangeAll' => ['bool'],
    'ZipArchive::unchangeArchive' => ['bool'],
    'ZipArchive::unchangeIndex' => ['bool', 'index'=>'int'],
    'ZipArchive::unchangeName' => ['bool', 'name'=>'string'],
    'Zookeeper::addAuth' => ['bool', 'scheme'=>'string', 'cert'=>'string', 'completion_cb='=>'callable'],
    'Zookeeper::close' => ['void'],
    'Zookeeper::connect' => ['void', 'host'=>'string', 'watcher_cb='=>'callable', 'recv_timeout='=>'int'],
    'Zookeeper::create' => ['string', 'path'=>'string', 'value'=>'string', 'acls'=>'array', 'flags='=>'int'],
    'Zookeeper::delete' => ['bool', 'path'=>'string', 'version='=>'int'],
    'Zookeeper::exists' => ['bool', 'path'=>'string', 'watcher_cb='=>'callable'],
    'Zookeeper::get' => ['string', 'path'=>'string', 'watcher_cb='=>'callable', 'stat='=>'array', 'max_size='=>'int'],
    'Zookeeper::getAcl' => ['array', 'path'=>'string'],
    'Zookeeper::getChildren' => ['array|false', 'path'=>'string', 'watcher_cb='=>'callable'],
    'Zookeeper::getClientId' => ['int'],
    'Zookeeper::getConfig' => ['ZookeeperConfig'],
    'Zookeeper::getRecvTimeout' => ['int'],
    'Zookeeper::getState' => ['int'],
    'Zookeeper::isRecoverable' => ['bool'],
    'Zookeeper::set' => ['bool', 'path'=>'string', 'value'=>'string', 'version='=>'int', 'stat='=>'array'],
    'Zookeeper::setAcl' => ['bool', 'path'=>'string', 'version'=>'int', 'acl'=>'array'],
    'Zookeeper::setDebugLevel' => ['bool', 'logLevel'=>'int'],
    'Zookeeper::setDeterministicConnOrder' => ['bool', 'yesOrNo'=>'bool'],
    'Zookeeper::setLogStream' => ['bool', 'stream'=>'resource'],
    'Zookeeper::setWatcher' => ['bool', 'watcher_cb'=>'callable'],
    'ZookeeperConfig::add' => ['void', 'members'=>'string', 'version='=>'int', 'stat='=>'array'],
    'ZookeeperConfig::get' => ['string', 'watcher_cb='=>'callable', 'stat='=>'array'],
    'ZookeeperConfig::remove' => ['void', 'id_list'=>'string', 'version='=>'int', 'stat='=>'array'],
    'ZookeeperConfig::set' => ['void', 'members'=>'string', 'version='=>'int', 'stat='=>'array'],
    '_' => ['string', 'message'=>'string'],
    '__halt_compiler' => ['void'],
    'abs' => ['0|positive-int', 'num'=>'int'],
    'abs\'1' => ['float', 'num'=>'float'],
    'abs\'2' => ['numeric', 'num'=>'numeric'],
    'accelerator_get_configuration' => ['array'],
    'accelerator_get_scripts' => ['array'],
    'accelerator_get_status' => ['array', 'fetch_scripts'=>'bool'],
    'accelerator_reset' => [''],
    'accelerator_set_status' => ['void', 'status'=>'bool'],
    'acos' => ['float', 'num'=>'float'],
    'acosh' => ['float', 'num'=>'float'],
    'addcslashes' => ['string', 'string'=>'string', 'characters'=>'string'],
    'addslashes' => ['string', 'string'=>'string'],
    'apache_child_terminate' => ['bool'],
    'apache_get_modules' => ['array'],
    'apache_get_version' => ['string|false'],
    'apache_getenv' => ['string|false', 'variable'=>'string', 'walk_to_top='=>'bool'],
    'apache_lookup_uri' => ['object', 'filename'=>'string'],
    'apache_note' => ['string|false', 'note_name'=>'string', 'note_value='=>'string'],
    'apache_request_headers' => ['array|false'],
    'apache_reset_timeout' => ['bool'],
    'apache_response_headers' => ['array|false'],
    'apache_setenv' => ['bool', 'variable'=>'string', 'value'=>'string', 'walk_to_top='=>'bool'],
    'apc_add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'ttl='=>'int'],
    'apc_add\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
    'apc_bin_dump' => ['string|false|null', 'files='=>'array', 'user_vars='=>'array'],
    'apc_bin_dumpfile' => ['int|false', 'files'=>'array', 'user_vars'=>'array', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
    'apc_bin_load' => ['bool', 'data'=>'string', 'flags='=>'int'],
    'apc_bin_loadfile' => ['bool', 'filename'=>'string', 'context='=>'resource', 'flags='=>'int'],
    'apc_cache_info' => ['array|false', 'cache_type='=>'string', 'limited='=>'bool'],
    'apc_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'],
    'apc_clear_cache' => ['bool', 'cache_type='=>'string'],
    'apc_compile_file' => ['bool', 'filename'=>'string', 'atomic='=>'bool'],
    'apc_dec' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'],
    'apc_define_constants' => ['bool', 'key'=>'string', 'constants'=>'array', 'case_sensitive='=>'bool'],
    'apc_delete' => ['bool', 'key'=>'string|string[]|APCIterator'],
    'apc_delete_file' => ['bool|string[]', 'keys'=>'mixed'],
    'apc_exists' => ['bool', 'keys'=>'string'],
    'apc_exists\'1' => ['array', 'keys'=>'string[]'],
    'apc_fetch' => ['mixed|false', 'key'=>'string', '&w_success='=>'bool'],
    'apc_fetch\'1' => ['array|false', 'key'=>'string[]', '&w_success='=>'bool'],
    'apc_inc' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'],
    'apc_load_constants' => ['bool', 'key'=>'string', 'case_sensitive='=>'bool'],
    'apc_sma_info' => ['array|false', 'limited='=>'bool'],
    'apc_store' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'],
    'apc_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
    'apcu_add' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'],
    'apcu_add\'1' => ['array<string,int>', 'values'=>'array<string,mixed>', 'unused='=>'', 'ttl='=>'int'],
    'apcu_cache_info' => ['array<string,mixed>|false', 'limited='=>'bool'],
    'apcu_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'],
    'apcu_clear_cache' => ['bool'],
    'apcu_dec' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool', 'ttl='=>'int'],
    'apcu_delete' => ['bool', 'key'=>'string|APCuIterator'],
    'apcu_delete\'1' => ['list<string>', 'key'=>'string[]'],
    'apcu_enabled' => ['bool'],
    'apcu_entry' => ['mixed', 'key'=>'string', 'generator'=>'callable', 'ttl='=>'int'],
    'apcu_exists' => ['bool', 'keys'=>'string'],
    'apcu_exists\'1' => ['array', 'keys'=>'string[]'],
    'apcu_fetch' => ['mixed|false', 'key'=>'string', '&w_success='=>'bool'],
    'apcu_fetch\'1' => ['array|false', 'key'=>'string[]', '&w_success='=>'bool'],
    'apcu_inc' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool', 'ttl='=>'int'],
    'apcu_key_info' => ['?array', 'key'=>'string'],
    'apcu_sma_info' => ['array|false', 'limited='=>'bool'],
    'apcu_store' => ['bool', 'key'=>'string', 'var='=>'', 'ttl='=>'int'],
    'apcu_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
    'apd_breakpoint' => ['bool', 'debug_level'=>'int'],
    'apd_callstack' => ['array'],
    'apd_clunk' => ['void', 'warning'=>'string', 'delimiter='=>'string'],
    'apd_continue' => ['bool', 'debug_level'=>'int'],
    'apd_croak' => ['void', 'warning'=>'string', 'delimiter='=>'string'],
    'apd_dump_function_table' => ['void'],
    'apd_dump_persistent_resources' => ['array'],
    'apd_dump_regular_resources' => ['array'],
    'apd_echo' => ['bool', 'output'=>'string'],
    'apd_get_active_symbols' => ['array'],
    'apd_set_pprof_trace' => ['string', 'dump_directory='=>'string', 'fragment='=>'string'],
    'apd_set_session' => ['void', 'debug_level'=>'int'],
    'apd_set_session_trace' => ['void', 'debug_level'=>'int', 'dump_directory='=>'string'],
    'apd_set_session_trace_socket' => ['bool', 'tcp_server'=>'string', 'socket_type'=>'int', 'port'=>'int', 'debug_level'=>'int'],
    'array_change_key_case' => ['associative-array', 'array'=>'array', 'case='=>'int'],
    'array_chunk' => ['list<array[]>', 'array'=>'array', 'length'=>'int', 'preserve_keys='=>'bool'],
    'array_column' => ['array', 'array'=>'array', 'column_key'=>'mixed', 'index_key='=>'mixed'],
    'array_combine' => ['associative-array|false', 'keys'=>'string[]|int[]', 'values'=>'array'],
    'array_count_values' => ['associative-array<mixed,int>', 'array'=>'array'],
    'array_diff' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
    'array_diff_assoc' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
    'array_diff_key' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
    'array_diff_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int'],
    'array_diff_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_diff_ukey' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_comp_func'=>'callable(mixed,mixed):int'],
    'array_diff_ukey\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_fill' => ['array<int,mixed>', 'start_index'=>'int', 'count'=>'int', 'value'=>'mixed'],
    'array_fill_keys' => ['array', 'keys'=>'array', 'value'=>'mixed'],
    'array_filter' => ['associative-array', 'array'=>'array', 'callback='=>'callable(mixed,mixed=):scalar', 'mode='=>'int'],
    'array_flip' => ['associative-array<mixed,int>|associative-array<mixed,string>', 'array'=>'array'],
    'array_intersect' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
    'array_intersect_assoc' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
    'array_intersect_key' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
    'array_intersect_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_compare_func'=>'callable(mixed,mixed):int'],
    'array_intersect_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable(mixed,mixed):int'],
    'array_intersect_ukey' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_compare_func'=>'callable(mixed,mixed):int'],
    'array_intersect_ukey\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable(mixed,mixed):int'],
    'array_key_exists' => ['bool', 'key'=>'string|int', 'array'=>'array|object'],
    'array_keys' => ['list<string|int>', 'array'=>'array', 'filter_value='=>'mixed', 'strict='=>'bool'],
    'array_map' => ['array', 'callback'=>'?callable', 'array'=>'array', '...arrays='=>'array'],
    'array_merge' => ['array', '...arrays'=>'array'],
    'array_merge_recursive' => ['array', '...arrays'=>'array'],
    'array_multisort' => ['bool', '&rw_array'=>'array', 'rest='=>'array|int', 'array1_sort_flags='=>'array|int', '...args='=>'array|int'],
    'array_pad' => ['array', 'array'=>'array', 'length'=>'int', 'value'=>'mixed'],
    'array_pop' => ['mixed', '&rw_array'=>'array'],
    'array_product' => ['int|float', 'array'=>'array'],
    'array_push' => ['int', '&rw_array'=>'array', '...values'=>'mixed'],
    'array_rand' => ['int|string|array<int,int>|array<int,string>', 'array'=>'non-empty-array', 'num'=>'int'],
    'array_rand\'1' => ['int|string', 'array'=>'array'],
    'array_reduce' => ['mixed', 'array'=>'array', 'callback'=>'callable(mixed,mixed):mixed', 'initial='=>'mixed'],
    'array_replace' => ['array', 'array'=>'array', '...replacements='=>'array'],
    'array_replace_recursive' => ['array', 'array'=>'array', '...replacements='=>'array'],
    'array_reverse' => ['array', 'array'=>'array', 'preserve_keys='=>'bool'],
    'array_search' => ['int|string|false', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'],
    'array_shift' => ['mixed|null', '&rw_array'=>'array'],
    'array_slice' => ['array', 'array'=>'array', 'offset'=>'int', 'length='=>'?int', 'preserve_keys='=>'bool'],
    'array_splice' => ['array', '&rw_array'=>'array', 'offset'=>'int', 'length='=>'int', 'replacement='=>'array|string'],
    'array_sum' => ['int|float', 'array'=>'array'],
    'array_udiff' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int'],
    'array_udiff\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_udiff_assoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_comp_func'=>'callable(mixed,mixed):int'],
    'array_udiff_assoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_udiff_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int', 'key_comp_func'=>'callable(mixed,mixed):int'],
    'array_udiff_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', 'arg5'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_uintersect' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int'],
    'array_uintersect\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_uintersect_assoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int'],
    'array_uintersect_assoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_uintersect_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int', 'key_compare_func'=>'callable(mixed,mixed):int'],
    'array_uintersect_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', 'arg5'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
    'array_unique' => ['array', 'array'=>'array', 'flags='=>'0'],
    'array_unique\'1' => ['array<int|float|string|null>', 'array'=>'array<int|float|string|null>', 'flags='=>'1'],
    'array_unique\'2' => ['array<int|float|string|bool|\Stringable|null>', 'array'=>'array<int|float|string|bool|\Stringable|null>', 'flags='=>'2|5'],
    'array_unshift' => ['int', '&rw_array'=>'array', '...values'=>'mixed'],
    'array_values' => ['list<mixed>', 'array'=>'array'],
    'array_walk' => ['bool', '&rw_array'=>'array', 'callback'=>'callable', 'arg='=>'mixed'],
    'array_walk\'1' => ['bool', '&rw_array'=>'object', 'callback'=>'callable', 'arg='=>'mixed'],
    'array_walk_recursive' => ['bool', '&rw_array'=>'array', 'callback'=>'callable', 'arg='=>'mixed'],
    'array_walk_recursive\'1' => ['bool', '&rw_array'=>'object', 'callback'=>'callable', 'arg='=>'mixed'],
    'arsort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
    'asin' => ['float', 'num'=>'float'],
    'asinh' => ['float', 'num'=>'float'],
    'asort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
    'assert' => ['bool', 'assertion'=>'string|bool|int', 'description='=>'string|Throwable|null'],
    'assert_options' => ['mixed|false', 'option'=>'int', 'value='=>'mixed'],
    'ast\Node::__construct' => ['void', 'kind='=>'int', 'flags='=>'int', 'children='=>'ast\Node\Decl[]|ast\Node[]|int[]|string[]|float[]|bool[]|null[]', 'start_line='=>'int'],
    'ast\get_kind_name' => ['string', 'kind'=>'int'],
    'ast\get_metadata' => ['array<int,ast\Metadata>'],
    'ast\get_supported_versions' => ['array<int,int>', 'exclude_deprecated='=>'bool'],
    'ast\kind_uses_flags' => ['bool', 'kind'=>'int'],
    'ast\parse_code' => ['ast\Node', 'code'=>'string', 'version'=>'int', 'filename='=>'string'],
    'ast\parse_file' => ['ast\Node', 'filename'=>'string', 'version'=>'int'],
    'atan' => ['float', 'num'=>'float'],
    'atan2' => ['float', 'y'=>'float', 'x'=>'float'],
    'atanh' => ['float', 'num'=>'float'],
    'base64_decode' => ['string|false', 'string'=>'string', 'strict='=>'bool'],
    'base64_encode' => ['string', 'string'=>'string'],
    'base_convert' => ['string', 'num'=>'string', 'from_base'=>'int', 'to_base'=>'int'],
    'basename' => ['string', 'path'=>'string', 'suffix='=>'string'],
    'bbcode_add_element' => ['bool', 'bbcode_container'=>'resource', 'tag_name'=>'string', 'tag_rules'=>'array'],
    'bbcode_add_smiley' => ['bool', 'bbcode_container'=>'resource', 'smiley'=>'string', 'replace_by'=>'string'],
    'bbcode_create' => ['resource', 'bbcode_initial_tags='=>'array'],
    'bbcode_destroy' => ['bool', 'bbcode_container'=>'resource'],
    'bbcode_parse' => ['string', 'bbcode_container'=>'resource', 'to_parse'=>'string'],
    'bbcode_set_arg_parser' => ['bool', 'bbcode_container'=>'resource', 'bbcode_arg_parser'=>'resource'],
    'bbcode_set_flags' => ['bool', 'bbcode_container'=>'resource', 'flags'=>'int', 'mode='=>'int'],
    'bcadd' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
    'bccomp' => ['int', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
    'bcdiv' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int'],
    'bcmod' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int'],
    'bcmul' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
    'bcompiler_load' => ['bool', 'filename'=>'string'],
    'bcompiler_load_exe' => ['bool', 'filename'=>'string'],
    'bcompiler_parse_class' => ['bool', 'class'=>'string', 'callback'=>'string'],
    'bcompiler_read' => ['bool', 'filehandle'=>'resource'],
    'bcompiler_write_class' => ['bool', 'filehandle'=>'resource', 'classname'=>'string', 'extends='=>'string'],
    'bcompiler_write_constant' => ['bool', 'filehandle'=>'resource', 'constantname'=>'string'],
    'bcompiler_write_exe_footer' => ['bool', 'filehandle'=>'resource', 'startpos'=>'int'],
    'bcompiler_write_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'],
    'bcompiler_write_footer' => ['bool', 'filehandle'=>'resource'],
    'bcompiler_write_function' => ['bool', 'filehandle'=>'resource', 'functionname'=>'string'],
    'bcompiler_write_functions_from_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'],
    'bcompiler_write_header' => ['bool', 'filehandle'=>'resource', 'write_ver='=>'string'],
    'bcompiler_write_included_filename' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'],
    'bcpow' => ['numeric-string', 'num'=>'numeric-string', 'exponent'=>'numeric-string', 'scale='=>'int'],
    'bcpowmod' => ['numeric-string|false', 'base'=>'numeric-string', 'exponent'=>'numeric-string', 'modulus'=>'numeric-string', 'scale='=>'int'],
    'bcscale' => ['int', 'scale'=>'int'],
    'bcsqrt' => ['numeric-string', 'num'=>'numeric-string', 'scale='=>'int'],
    'bcsub' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
    'bin2hex' => ['string', 'string'=>'string'],
    'bind_textdomain_codeset' => ['string', 'domain'=>'string', 'codeset'=>'string'],
    'bindec' => ['float|int', 'binary_string'=>'string'],
    'bindtextdomain' => ['string', 'domain'=>'string', 'directory'=>'string'],
    'birdstep_autocommit' => ['bool', 'index'=>'int'],
    'birdstep_close' => ['bool', 'id'=>'int'],
    'birdstep_commit' => ['bool', 'index'=>'int'],
    'birdstep_connect' => ['int', 'server'=>'string', 'user'=>'string', 'pass'=>'string'],
    'birdstep_exec' => ['int', 'index'=>'int', 'exec_str'=>'string'],
    'birdstep_fetch' => ['bool', 'index'=>'int'],
    'birdstep_fieldname' => ['string', 'index'=>'int', 'col'=>'int'],
    'birdstep_fieldnum' => ['int', 'index'=>'int'],
    'birdstep_freeresult' => ['bool', 'index'=>'int'],
    'birdstep_off_autocommit' => ['bool', 'index'=>'int'],
    'birdstep_result' => ['', 'index'=>'int', 'col'=>''],
    'birdstep_rollback' => ['bool', 'index'=>'int'],
    'blenc_encrypt' => ['string', 'plaintext'=>'string', 'encodedfile'=>'string', 'encryption_key='=>'string'],
    'boolval' => ['bool', 'value'=>'mixed'],
    'bson_decode' => ['array', 'bson'=>'string'],
    'bson_encode' => ['string', 'anything'=>'mixed'],
    'bzclose' => ['bool', 'bz'=>'resource'],
    'bzcompress' => ['string|int', 'data'=>'string', 'block_size='=>'int', 'work_factor='=>'int'],
    'bzdecompress' => ['string|int', 'data'=>'string', 'use_less_memory='=>'int'],
    'bzerrno' => ['int', 'bz'=>'resource'],
    'bzerror' => ['array', 'bz'=>'resource'],
    'bzerrstr' => ['string', 'bz'=>'resource'],
    'bzflush' => ['bool', 'bz'=>'resource'],
    'bzopen' => ['resource|false', 'file'=>'string|resource', 'mode'=>'string'],
    'bzread' => ['string|false', 'bz'=>'resource', 'length='=>'int'],
    'bzwrite' => ['int|false', 'bz'=>'resource', 'data'=>'string', 'length='=>'int'],
    'cairo_append_path' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'],
    'cairo_arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
    'cairo_arc_negative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
    'cairo_available_fonts' => ['array'],
    'cairo_available_surfaces' => ['array'],
    'cairo_clip' => ['', 'context'=>'cairocontext'],
    'cairo_clip_extents' => ['array', 'context'=>'cairocontext'],
    'cairo_clip_preserve' => ['', 'context'=>'cairocontext'],
    'cairo_clip_rectangle_list' => ['array', 'context'=>'cairocontext'],
    'cairo_close_path' => ['', 'context'=>'cairocontext'],
    'cairo_copy_page' => ['', 'context'=>'cairocontext'],
    'cairo_copy_path' => ['CairoPath', 'context'=>'cairocontext'],
    'cairo_copy_path_flat' => ['CairoPath', 'context'=>'cairocontext'],
    'cairo_create' => ['CairoContext', 'surface'=>'cairosurface'],
    'cairo_curve_to' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'],
    'cairo_device_to_user' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
    'cairo_device_to_user_distance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
    'cairo_fill' => ['', 'context'=>'cairocontext'],
    'cairo_fill_extents' => ['array', 'context'=>'cairocontext'],
    'cairo_fill_preserve' => ['', 'context'=>'cairocontext'],
    'cairo_font_extents' => ['array', 'context'=>'cairocontext'],
    'cairo_font_face_get_type' => ['int', 'fontface'=>'cairofontface'],
    'cairo_font_face_status' => ['int', 'fontface'=>'cairofontface'],
    'cairo_font_options_create' => ['CairoFontOptions'],
    'cairo_font_options_equal' => ['bool', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'],
    'cairo_font_options_get_antialias' => ['int', 'options'=>'cairofontoptions'],
    'cairo_font_options_get_hint_metrics' => ['int', 'options'=>'cairofontoptions'],
    'cairo_font_options_get_hint_style' => ['int', 'options'=>'cairofontoptions'],
    'cairo_font_options_get_subpixel_order' => ['int', 'options'=>'cairofontoptions'],
    'cairo_font_options_hash' => ['int', 'options'=>'cairofontoptions'],
    'cairo_font_options_merge' => ['void', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'],
    'cairo_font_options_set_antialias' => ['void', 'options'=>'cairofontoptions', 'antialias'=>'int'],
    'cairo_font_options_set_hint_metrics' => ['void', 'options'=>'cairofontoptions', 'hint_metrics'=>'int'],
    'cairo_font_options_set_hint_style' => ['void', 'options'=>'cairofontoptions', 'hint_style'=>'int'],
    'cairo_font_options_set_subpixel_order' => ['void', 'options'=>'cairofontoptions', 'subpixel_order'=>'int'],
    'cairo_font_options_status' => ['int', 'options'=>'cairofontoptions'],
    'cairo_format_stride_for_width' => ['int', 'format'=>'int', 'width'=>'int'],
    'cairo_get_antialias' => ['int', 'context'=>'cairocontext'],
    'cairo_get_current_point' => ['array', 'context'=>'cairocontext'],
    'cairo_get_dash' => ['array', 'context'=>'cairocontext'],
    'cairo_get_dash_count' => ['int', 'context'=>'cairocontext'],
    'cairo_get_fill_rule' => ['int', 'context'=>'cairocontext'],
    'cairo_get_font_face' => ['', 'context'=>'cairocontext'],
    'cairo_get_font_matrix' => ['', 'context'=>'cairocontext'],
    'cairo_get_font_options' => ['', 'context'=>'cairocontext'],
    'cairo_get_group_target' => ['', 'context'=>'cairocontext'],
    'cairo_get_line_cap' => ['int', 'context'=>'cairocontext'],
    'cairo_get_line_join' => ['int', 'context'=>'cairocontext'],
    'cairo_get_line_width' => ['float', 'context'=>'cairocontext'],
    'cairo_get_matrix' => ['', 'context'=>'cairocontext'],
    'cairo_get_miter_limit' => ['float', 'context'=>'cairocontext'],
    'cairo_get_operator' => ['int', 'context'=>'cairocontext'],
    'cairo_get_scaled_font' => ['', 'context'=>'cairocontext'],
    'cairo_get_source' => ['', 'context'=>'cairocontext'],
    'cairo_get_target' => ['', 'context'=>'cairocontext'],
    'cairo_get_tolerance' => ['float', 'context'=>'cairocontext'],
    'cairo_glyph_path' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'],
    'cairo_has_current_point' => ['bool', 'context'=>'cairocontext'],
    'cairo_identity_matrix' => ['', 'context'=>'cairocontext'],
    'cairo_image_surface_create' => ['CairoImageSurface', 'format'=>'int', 'width'=>'int', 'height'=>'int'],
    'cairo_image_surface_create_for_data' => ['CairoImageSurface', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'],
    'cairo_image_surface_create_from_png' => ['CairoImageSurface', 'file'=>'string'],
    'cairo_image_surface_get_data' => ['string', 'surface'=>'cairoimagesurface'],
    'cairo_image_surface_get_format' => ['int', 'surface'=>'cairoimagesurface'],
    'cairo_image_surface_get_height' => ['int', 'surface'=>'cairoimagesurface'],
    'cairo_image_surface_get_stride' => ['int', 'surface'=>'cairoimagesurface'],
    'cairo_image_surface_get_width' => ['int', 'surface'=>'cairoimagesurface'],
    'cairo_in_fill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_in_stroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'],
    'cairo_mask_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
    'cairo_matrix_create_scale' => ['object', 'sx'=>'float', 'sy'=>'float'],
    'cairo_matrix_init' => ['object', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'],
    'cairo_matrix_init_identity' => ['object'],
    'cairo_matrix_init_rotate' => ['object', 'radians'=>'float'],
    'cairo_matrix_init_scale' => ['object', 'sx'=>'float', 'sy'=>'float'],
    'cairo_matrix_init_translate' => ['object', 'tx'=>'float', 'ty'=>'float'],
    'cairo_matrix_invert' => ['void', 'matrix'=>'cairomatrix'],
    'cairo_matrix_multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'],
    'cairo_matrix_rotate' => ['', 'matrix'=>'cairomatrix', 'radians'=>'float'],
    'cairo_matrix_scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'],
    'cairo_matrix_transform_distance' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'],
    'cairo_matrix_transform_point' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'],
    'cairo_matrix_translate' => ['void', 'matrix'=>'cairomatrix', 'tx'=>'float', 'ty'=>'float'],
    'cairo_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_new_path' => ['', 'context'=>'cairocontext'],
    'cairo_new_sub_path' => ['', 'context'=>'cairocontext'],
    'cairo_paint' => ['', 'context'=>'cairocontext'],
    'cairo_paint_with_alpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'],
    'cairo_path_extents' => ['array', 'context'=>'cairocontext'],
    'cairo_pattern_add_color_stop_rgb' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'cairo_pattern_add_color_stop_rgba' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'],
    'cairo_pattern_create_for_surface' => ['CairoPattern', 'surface'=>'cairosurface'],
    'cairo_pattern_create_linear' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'],
    'cairo_pattern_create_radial' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'],
    'cairo_pattern_create_rgb' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'cairo_pattern_create_rgba' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'],
    'cairo_pattern_get_color_stop_count' => ['int', 'pattern'=>'cairogradientpattern'],
    'cairo_pattern_get_color_stop_rgba' => ['array', 'pattern'=>'cairogradientpattern', 'index'=>'int'],
    'cairo_pattern_get_extend' => ['int', 'pattern'=>'string'],
    'cairo_pattern_get_filter' => ['int', 'pattern'=>'cairosurfacepattern'],
    'cairo_pattern_get_linear_points' => ['array', 'pattern'=>'cairolineargradient'],
    'cairo_pattern_get_matrix' => ['CairoMatrix', 'pattern'=>'cairopattern'],
    'cairo_pattern_get_radial_circles' => ['array', 'pattern'=>'cairoradialgradient'],
    'cairo_pattern_get_rgba' => ['array', 'pattern'=>'cairosolidpattern'],
    'cairo_pattern_get_surface' => ['CairoSurface', 'pattern'=>'cairosurfacepattern'],
    'cairo_pattern_get_type' => ['int', 'pattern'=>'cairopattern'],
    'cairo_pattern_set_extend' => ['void', 'pattern'=>'string', 'extend'=>'string'],
    'cairo_pattern_set_filter' => ['void', 'pattern'=>'cairosurfacepattern', 'filter'=>'int'],
    'cairo_pattern_set_matrix' => ['void', 'pattern'=>'cairopattern', 'matrix'=>'cairomatrix'],
    'cairo_pattern_status' => ['int', 'pattern'=>'cairopattern'],
    'cairo_pdf_surface_create' => ['CairoPdfSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
    'cairo_pdf_surface_set_size' => ['void', 'surface'=>'cairopdfsurface', 'width'=>'float', 'height'=>'float'],
    'cairo_pop_group' => ['', 'context'=>'cairocontext'],
    'cairo_pop_group_to_source' => ['', 'context'=>'cairocontext'],
    'cairo_ps_get_levels' => ['array'],
    'cairo_ps_level_to_string' => ['string', 'level'=>'int'],
    'cairo_ps_surface_create' => ['CairoPsSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
    'cairo_ps_surface_dsc_begin_page_setup' => ['void', 'surface'=>'cairopssurface'],
    'cairo_ps_surface_dsc_begin_setup' => ['void', 'surface'=>'cairopssurface'],
    'cairo_ps_surface_dsc_comment' => ['void', 'surface'=>'cairopssurface', 'comment'=>'string'],
    'cairo_ps_surface_get_eps' => ['bool', 'surface'=>'cairopssurface'],
    'cairo_ps_surface_restrict_to_level' => ['void', 'surface'=>'cairopssurface', 'level'=>'int'],
    'cairo_ps_surface_set_eps' => ['void', 'surface'=>'cairopssurface', 'level'=>'bool'],
    'cairo_ps_surface_set_size' => ['void', 'surface'=>'cairopssurface', 'width'=>'float', 'height'=>'float'],
    'cairo_push_group' => ['', 'context'=>'cairocontext'],
    'cairo_push_group_with_content' => ['', 'content'=>'string', 'context'=>'cairocontext'],
    'cairo_rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'],
    'cairo_rel_curve_to' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'],
    'cairo_rel_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_rel_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_reset_clip' => ['', 'context'=>'cairocontext'],
    'cairo_restore' => ['', 'context'=>'cairocontext'],
    'cairo_rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'],
    'cairo_save' => ['', 'context'=>'cairocontext'],
    'cairo_scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_scaled_font_create' => ['CairoScaledFont', 'fontface'=>'cairofontface', 'matrix'=>'cairomatrix', 'ctm'=>'cairomatrix', 'fontoptions'=>'cairofontoptions'],
    'cairo_scaled_font_extents' => ['array', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_get_ctm' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_get_font_face' => ['CairoFontFace', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_get_font_matrix' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_get_font_options' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_get_scale_matrix' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_get_type' => ['int', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_glyph_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'glyphs'=>'array'],
    'cairo_scaled_font_status' => ['int', 'scaledfont'=>'cairoscaledfont'],
    'cairo_scaled_font_text_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'text'=>'string'],
    'cairo_select_font_face' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'],
    'cairo_set_antialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'],
    'cairo_set_dash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'],
    'cairo_set_fill_rule' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'cairo_set_font_face' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'],
    'cairo_set_font_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
    'cairo_set_font_options' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'],
    'cairo_set_font_size' => ['', 'size'=>'string', 'context'=>'cairocontext'],
    'cairo_set_line_cap' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'cairo_set_line_join' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'cairo_set_line_width' => ['', 'width'=>'string', 'context'=>'cairocontext'],
    'cairo_set_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
    'cairo_set_miter_limit' => ['', 'limit'=>'string', 'context'=>'cairocontext'],
    'cairo_set_operator' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
    'cairo_set_scaled_font' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'],
    'cairo_set_source' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'],
    'cairo_set_source_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
    'cairo_set_tolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'],
    'cairo_show_page' => ['', 'context'=>'cairocontext'],
    'cairo_show_text' => ['', 'text'=>'string', 'context'=>'cairocontext'],
    'cairo_status' => ['int', 'context'=>'cairocontext'],
    'cairo_status_to_string' => ['string', 'status'=>'int'],
    'cairo_stroke' => ['', 'context'=>'cairocontext'],
    'cairo_stroke_extents' => ['array', 'context'=>'cairocontext'],
    'cairo_stroke_preserve' => ['', 'context'=>'cairocontext'],
    'cairo_surface_copy_page' => ['void', 'surface'=>'cairosurface'],
    'cairo_surface_create_similar' => ['CairoSurface', 'surface'=>'cairosurface', 'content'=>'int', 'width'=>'float', 'height'=>'float'],
    'cairo_surface_finish' => ['void', 'surface'=>'cairosurface'],
    'cairo_surface_flush' => ['void', 'surface'=>'cairosurface'],
    'cairo_surface_get_content' => ['int', 'surface'=>'cairosurface'],
    'cairo_surface_get_device_offset' => ['array', 'surface'=>'cairosurface'],
    'cairo_surface_get_font_options' => ['CairoFontOptions', 'surface'=>'cairosurface'],
    'cairo_surface_get_type' => ['int', 'surface'=>'cairosurface'],
    'cairo_surface_mark_dirty' => ['void', 'surface'=>'cairosurface'],
    'cairo_surface_mark_dirty_rectangle' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
    'cairo_surface_set_device_offset' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'],
    'cairo_surface_set_fallback_resolution' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'],
    'cairo_surface_show_page' => ['void', 'surface'=>'cairosurface'],
    'cairo_surface_status' => ['int', 'surface'=>'cairosurface'],
    'cairo_surface_write_to_png' => ['void', 'surface'=>'cairosurface', 'stream'=>'resource'],
    'cairo_svg_get_versions' => ['array'],
    'cairo_svg_surface_create' => ['CairoSvgSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
    'cairo_svg_surface_get_versions' => ['array'],
    'cairo_svg_surface_restrict_to_version' => ['void', 'surface'=>'cairosvgsurface', 'version'=>'int'],
    'cairo_svg_version_to_string' => ['string', 'version'=>'int'],
    'cairo_text_extents' => ['array', 'text'=>'string', 'context'=>'cairocontext'],
    'cairo_text_path' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'],
    'cairo_transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
    'cairo_translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'],
    'cairo_user_to_device' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_user_to_device_distance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
    'cairo_version' => ['int'],
    'cairo_version_string' => ['string'],
    'cal_days_in_month' => ['int', 'calendar'=>'int', 'month'=>'int', 'year'=>'int'],
    'cal_from_jd' => ['array{date:string,month:int,day:int,year:int,dow:int,abbrevdayname:string,dayname:string,abbrevmonth:string,monthname:string}', 'julian_day'=>'int', 'calendar'=>'int'],
    'cal_info' => ['array', 'calendar='=>'int'],
    'cal_to_jd' => ['int', 'calendar'=>'int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
    'calcul_hmac' => ['string', 'clent'=>'string', 'siretcode'=>'string', 'price'=>'string', 'reference'=>'string', 'validity'=>'string', 'taxation'=>'string', 'devise'=>'string', 'language'=>'string'],
    'calculhmac' => ['string', 'clent'=>'string', 'data'=>'string'],
    'call_user_func' => ['mixed|false', 'callback'=>'callable', '...args='=>'mixed'],
    'call_user_func_array' => ['mixed|false', 'callback'=>'callable', 'args'=>'list<mixed>'],
    'call_user_method' => ['mixed', 'method_name'=>'string', 'object'=>'object', 'parameter='=>'mixed', '...args='=>'mixed'],
    'call_user_method_array' => ['mixed', 'method_name'=>'string', 'object'=>'object', 'params'=>'list<mixed>'],
    'ceil' => ['float', 'num'=>'float'],
    'chdb::__construct' => ['void', 'pathname'=>'string'],
    'chdb::get' => ['string', 'key'=>'string'],
    'chdb_create' => ['bool', 'pathname'=>'string', 'data'=>'array'],
    'chdir' => ['bool', 'directory'=>'string'],
    'checkdate' => ['bool', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
    'checkdnsrr' => ['bool', 'hostname'=>'string', 'type='=>'string'],
    'chgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'],
    'chmod' => ['bool', 'filename'=>'string', 'permissions'=>'int'],
    'chop' => ['string', 'string'=>'string', 'characters='=>'string'],
    'chown' => ['bool', 'filename'=>'string', 'user'=>'string|int'],
    'chr' => ['non-empty-string', 'codepoint'=>'int'],
    'chroot' => ['bool', 'directory'=>'string'],
    'chunk_split' => ['string', 'string'=>'string', 'length='=>'int', 'separator='=>'string'],
    'classObj::__construct' => ['void', 'layer'=>'layerObj', 'class'=>'classObj'],
    'classObj::addLabel' => ['int', 'label'=>'labelObj'],
    'classObj::convertToString' => ['string'],
    'classObj::createLegendIcon' => ['imageObj', 'width'=>'int', 'height'=>'int'],
    'classObj::deletestyle' => ['int', 'index'=>'int'],
    'classObj::drawLegendIcon' => ['int', 'width'=>'int', 'height'=>'int', 'im'=>'imageObj', 'dstX'=>'int', 'dstY'=>'int'],
    'classObj::free' => ['void'],
    'classObj::getExpressionString' => ['string'],
    'classObj::getLabel' => ['labelObj', 'index'=>'int'],
    'classObj::getMetaData' => ['int', 'name'=>'string'],
    'classObj::getStyle' => ['styleObj', 'index'=>'int'],
    'classObj::getTextString' => ['string'],
    'classObj::movestyledown' => ['int', 'index'=>'int'],
    'classObj::movestyleup' => ['int', 'index'=>'int'],
    'classObj::ms_newClassObj' => ['classObj', 'layer'=>'layerObj', 'class'=>'classObj'],
    'classObj::removeLabel' => ['labelObj', 'index'=>'int'],
    'classObj::removeMetaData' => ['int', 'name'=>'string'],
    'classObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'classObj::setExpression' => ['int', 'expression'=>'string'],
    'classObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'],
    'classObj::settext' => ['int', 'text'=>'string'],
    'classObj::updateFromString' => ['int', 'snippet'=>'string'],
    'class_alias' => ['bool', 'class'=>'string', 'alias'=>'string', 'autoload='=>'bool'],
    'class_exists' => ['bool', 'class'=>'string', 'autoload='=>'bool'],
    'class_implements' => ['array<string,string>|false', 'object_or_class'=>'object|string', 'autoload='=>'bool'],
    'class_parents' => ['array<string, class-string>|false', 'object_or_class'=>'object|string', 'autoload='=>'bool'],
    'class_uses' => ['array<string,string>|false', 'object_or_class'=>'object|string', 'autoload='=>'bool'],
    'classkit_import' => ['array', 'filename'=>'string'],
    'classkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'],
    'classkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'],
    'classkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'],
    'classkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'],
    'classkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'],
    'clearstatcache' => ['void', 'clear_realpath_cache='=>'bool', 'filename='=>'string'],
    'cli_get_process_title' => ['?string'],
    'cli_set_process_title' => ['bool', 'title'=>'string'],
    'closedir' => ['void', 'dir_handle='=>'resource'],
    'closelog' => ['bool'],
    'clusterObj::convertToString' => ['string'],
    'clusterObj::getFilterString' => ['string'],
    'clusterObj::getGroupString' => ['string'],
    'clusterObj::setFilter' => ['int', 'expression'=>'string'],
    'clusterObj::setGroup' => ['int', 'expression'=>'string'],
    'collator_asort' => ['bool', 'object'=>'collator', '&rw_array'=>'array', 'flags='=>'int'],
    'collator_compare' => ['int', 'object'=>'collator', 'string1'=>'string', 'string2'=>'string'],
    'collator_create' => ['?Collator', 'locale'=>'string'],
    'collator_get_attribute' => ['int|false', 'object'=>'collator', 'attribute'=>'int'],
    'collator_get_error_code' => ['int', 'object'=>'collator'],
    'collator_get_error_message' => ['string', 'object'=>'collator'],
    'collator_get_locale' => ['string', 'object'=>'collator', 'type'=>'int'],
    'collator_get_sort_key' => ['string', 'object'=>'collator', 'string'=>'string'],
    'collator_get_strength' => ['int|false', 'object'=>'collator'],
    'collator_set_attribute' => ['bool', 'object'=>'collator', 'attribute'=>'int', 'value'=>'int'],
    'collator_set_strength' => ['bool', 'object'=>'collator', 'strength'=>'int'],
    'collator_sort' => ['bool', 'object'=>'collator', '&rw_array'=>'array', 'flags='=>'int'],
    'collator_sort_with_sort_keys' => ['bool', 'object'=>'collator', '&rw_array'=>'array'],
    'colorObj::setHex' => ['int', 'hex'=>'string'],
    'colorObj::toHex' => ['string'],
    'com_addref' => [''],
    'com_create_guid' => ['string'],
    'com_event_sink' => ['bool', 'variant'=>'VARIANT', 'sink_object'=>'object', 'sink_interface='=>'mixed'],
    'com_get_active_object' => ['VARIANT', 'prog_id'=>'string', 'codepage='=>'int'],
    'com_isenum' => ['bool', 'com_module'=>'variant'],
    'com_load_typelib' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'bool'],
    'com_message_pump' => ['bool', 'timeout_milliseconds='=>'int'],
    'com_print_typeinfo' => ['bool', 'variant'=>'object', 'dispatch_interface='=>'string', 'display_sink='=>'bool'],
    'commonmark\cql::__invoke' => ['', 'root'=>'CommonMark\Node', 'handler'=>'callable'],
    'commonmark\interfaces\ivisitable::accept' => ['void', 'visitor'=>'CommonMark\Interfaces\IVisitor'],
    'commonmark\interfaces\ivisitor::enter' => ['?int|IVisitable', 'visitable'=>'IVisitable'],
    'commonmark\interfaces\ivisitor::leave' => ['?int|IVisitable', 'visitable'=>'IVisitable'],
    'commonmark\node::accept' => ['void', 'visitor'=>'CommonMark\Interfaces\IVisitor'],
    'commonmark\node::appendChild' => ['CommonMark\Node', 'child'=>'CommonMark\Node'],
    'commonmark\node::insertAfter' => ['CommonMark\Node', 'sibling'=>'CommonMark\Node'],
    'commonmark\node::insertBefore' => ['CommonMark\Node', 'sibling'=>'CommonMark\Node'],
    'commonmark\node::prependChild' => ['CommonMark\Node', 'child'=>'CommonMark\Node'],
    'commonmark\node::replace' => ['CommonMark\Node', 'target'=>'CommonMark\Node'],
    'commonmark\node::unlink' => ['void'],
    'commonmark\parse' => ['CommonMark\Node', 'content'=>'string', 'options='=>'int'],
    'commonmark\parser::finish' => ['CommonMark\Node'],
    'commonmark\parser::parse' => ['void', 'buffer'=>'string'],
    'commonmark\render' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int', 'width='=>'int'],
    'commonmark\render\html' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int'],
    'commonmark\render\latex' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int', 'width='=>'int'],
    'commonmark\render\man' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int', 'width='=>'int'],
    'commonmark\render\xml' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int'],
    'compact' => ['array<string, mixed>', 'var_name'=>'string|array', '...var_names='=>'string|array'],
    'componere\abstract\definition::addInterface' => ['Componere\Abstract\Definition', 'interface'=>'string'],
    'componere\abstract\definition::addMethod' => ['Componere\Abstract\Definition', 'name'=>'string', 'method'=>'Componere\Method'],
    'componere\abstract\definition::addTrait' => ['Componere\Abstract\Definition', 'trait'=>'string'],
    'componere\abstract\definition::getReflector' => ['ReflectionClass'],
    'componere\cast' => ['object', 'arg1'=>'string', 'object'=>'object'],
    'componere\cast_by_ref' => ['object', 'arg1'=>'string', 'object'=>'object'],
    'componere\definition::addConstant' => ['Componere\Definition', 'name'=>'string', 'value'=>'Componere\Value'],
    'componere\definition::addProperty' => ['Componere\Definition', 'name'=>'string', 'value'=>'Componere\Value'],
    'componere\definition::getClosure' => ['Closure', 'name'=>'string'],
    'componere\definition::getClosures' => ['Closure[]'],
    'componere\definition::isRegistered' => ['bool'],
    'componere\definition::register' => ['void'],
    'componere\method::getReflector' => ['ReflectionMethod'],
    'componere\method::setPrivate' => ['Method'],
    'componere\method::setProtected' => ['Method'],
    'componere\method::setStatic' => ['Method'],
    'componere\patch::apply' => ['void'],
    'componere\patch::derive' => ['Componere\Patch', 'instance'=>'object'],
    'componere\patch::getClosure' => ['Closure', 'name'=>'string'],
    'componere\patch::getClosures' => ['Closure[]'],
    'componere\patch::isApplied' => ['bool'],
    'componere\patch::revert' => ['void'],
    'componere\value::hasDefault' => ['bool'],
    'componere\value::isPrivate' => ['bool'],
    'componere\value::isProtected' => ['bool'],
    'componere\value::isStatic' => ['bool'],
    'componere\value::setPrivate' => ['Value'],
    'componere\value::setProtected' => ['Value'],
    'componere\value::setStatic' => ['Value'],
    'confirm_pdo_ibm_compiled' => [''],
    'connection_aborted' => ['int'],
    'connection_status' => ['int'],
    'connection_timeout' => ['int'],
    'constant' => ['mixed', 'name'=>'string'],
    'convert_cyr_string' => ['string', 'string'=>'string', 'from'=>'string', 'to'=>'string'],
    'convert_uudecode' => ['string', 'string'=>'string'],
    'convert_uuencode' => ['string', 'string'=>'string'],
    'copy' => ['bool', 'from'=>'string', 'to'=>'string', 'context='=>'resource'],
    'cos' => ['float', 'num'=>'float'],
    'cosh' => ['float', 'num'=>'float'],
    'count' => ['int<0, max>', 'value'=>'Countable|array|SimpleXMLElement', 'mode='=>'int'],
    'count_chars' => ['array<int,int>|false', 'input'=>'string', 'mode='=>'0|1|2'],
    'count_chars\'1' => ['string|false', 'input'=>'string', 'mode='=>'3|4'],
    'crack_check' => ['bool', 'dictionary'=>'', 'password'=>'string'],
    'crack_closedict' => ['bool', 'dictionary='=>'resource'],
    'crack_getlastmessage' => ['string'],
    'crack_opendict' => ['resource|false', 'dictionary'=>'string'],
    'crash' => [''],
    'crc32' => ['int', 'string'=>'string'],
    'create_function' => ['string', 'args'=>'string', 'code'=>'string'],
    'crypt' => ['string', 'string'=>'string', 'salt='=>'string'],
    'ctype_alnum' => ['bool', 'text'=>'string|int'],
    'ctype_alpha' => ['bool', 'text'=>'string|int'],
    'ctype_cntrl' => ['bool', 'text'=>'string|int'],
    'ctype_digit' => ['bool', 'text'=>'string|int'],
    'ctype_graph' => ['bool', 'text'=>'string|int'],
    'ctype_lower' => ['bool', 'text'=>'string|int'],
    'ctype_print' => ['bool', 'text'=>'string|int'],
    'ctype_punct' => ['bool', 'text'=>'string|int'],
    'ctype_space' => ['bool', 'text'=>'string|int'],
    'ctype_upper' => ['bool', 'text'=>'string|int'],
    'ctype_xdigit' => ['bool', 'text'=>'string|int'],
    'cubrid_affected_rows' => ['int', 'req_identifier='=>''],
    'cubrid_bind' => ['bool', 'req_identifier'=>'resource', 'bind_param'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'],
    'cubrid_client_encoding' => ['string', 'conn_identifier='=>''],
    'cubrid_close' => ['bool', 'conn_identifier='=>''],
    'cubrid_close_prepare' => ['bool', 'req_identifier'=>'resource'],
    'cubrid_close_request' => ['bool', 'req_identifier'=>'resource'],
    'cubrid_col_get' => ['array', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'],
    'cubrid_col_size' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'],
    'cubrid_column_names' => ['array', 'req_identifier'=>'resource'],
    'cubrid_column_types' => ['array', 'req_identifier'=>'resource'],
    'cubrid_commit' => ['bool', 'conn_identifier'=>'resource'],
    'cubrid_connect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'],
    'cubrid_connect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'],
    'cubrid_current_oid' => ['string', 'req_identifier'=>'resource'],
    'cubrid_data_seek' => ['bool', 'req_identifier'=>'', 'row_number'=>'int'],
    'cubrid_db_name' => ['string', 'result'=>'array', 'index'=>'int'],
    'cubrid_db_parameter' => ['array', 'conn_identifier'=>'resource'],
    'cubrid_disconnect' => ['bool', 'conn_identifier'=>'resource'],
    'cubrid_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'],
    'cubrid_errno' => ['int', 'conn_identifier='=>''],
    'cubrid_error' => ['string', 'connection='=>''],
    'cubrid_error_code' => ['int'],
    'cubrid_error_code_facility' => ['int'],
    'cubrid_error_msg' => ['string'],
    'cubrid_execute' => ['bool', 'conn_identifier'=>'', 'sql'=>'string', 'option='=>'int', 'request_identifier='=>''],
    'cubrid_fetch' => ['mixed', 'result'=>'resource', 'type='=>'int'],
    'cubrid_fetch_array' => ['array', 'result'=>'resource', 'type='=>'int'],
    'cubrid_fetch_assoc' => ['array', 'result'=>'resource'],
    'cubrid_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'],
    'cubrid_fetch_lengths' => ['array', 'result'=>'resource'],
    'cubrid_fetch_object' => ['object', 'result'=>'resource', 'class_name='=>'string', 'params='=>'array'],
    'cubrid_fetch_row' => ['array', 'result'=>'resource'],
    'cubrid_field_flags' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
    'cubrid_field_len' => ['int', 'result'=>'resource', 'field_offset'=>'int'],
    'cubrid_field_name' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
    'cubrid_field_seek' => ['bool', 'result'=>'resource', 'field_offset='=>'int'],
    'cubrid_field_table' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
    'cubrid_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
    'cubrid_free_result' => ['bool', 'req_identifier'=>'resource'],
    'cubrid_get' => ['mixed', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'mixed'],
    'cubrid_get_autocommit' => ['bool', 'conn_identifier'=>'resource'],
    'cubrid_get_charset' => ['string', 'conn_identifier'=>'resource'],
    'cubrid_get_class_name' => ['string', 'conn_identifier'=>'resource', 'oid'=>'string'],
    'cubrid_get_client_info' => ['string'],
    'cubrid_get_db_parameter' => ['array', 'conn_identifier'=>'resource'],
    'cubrid_get_query_timeout' => ['int', 'req_identifier'=>'resource'],
    'cubrid_get_server_info' => ['string', 'conn_identifier'=>'resource'],
    'cubrid_insert_id' => ['string', 'conn_identifier='=>'resource'],
    'cubrid_is_instance' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string'],
    'cubrid_list_dbs' => ['array', 'conn_identifier'=>'resource'],
    'cubrid_load_from_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'],
    'cubrid_lob2_bind' => ['bool', 'req_identifier'=>'resource', 'bind_index'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'],
    'cubrid_lob2_close' => ['bool', 'lob_identifier'=>'resource'],
    'cubrid_lob2_export' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'],
    'cubrid_lob2_import' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'],
    'cubrid_lob2_new' => ['resource', 'conn_identifier='=>'resource', 'type='=>'string'],
    'cubrid_lob2_read' => ['string', 'lob_identifier'=>'resource', 'length'=>'int'],
    'cubrid_lob2_seek' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'],
    'cubrid_lob2_seek64' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'string', 'origin='=>'int'],
    'cubrid_lob2_size' => ['int', 'lob_identifier'=>'resource'],
    'cubrid_lob2_size64' => ['string', 'lob_identifier'=>'resource'],
    'cubrid_lob2_tell' => ['int', 'lob_identifier'=>'resource'],
    'cubrid_lob2_tell64' => ['string', 'lob_identifier'=>'resource'],
    'cubrid_lob2_write' => ['bool', 'lob_identifier'=>'resource', 'buf'=>'string'],
    'cubrid_lob_close' => ['bool', 'lob_identifier_array'=>'array'],
    'cubrid_lob_export' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource', 'path_name'=>'string'],
    'cubrid_lob_get' => ['array', 'conn_identifier'=>'resource', 'sql'=>'string'],
    'cubrid_lob_send' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource'],
    'cubrid_lob_size' => ['string', 'lob_identifier'=>'resource'],
    'cubrid_lock_read' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'],
    'cubrid_lock_write' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'],
    'cubrid_move_cursor' => ['int', 'req_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'],
    'cubrid_new_glo' => ['string', 'conn_identifier'=>'', 'class_name'=>'string', 'file_name'=>'string'],
    'cubrid_next_result' => ['bool', 'result'=>'resource'],
    'cubrid_num_cols' => ['int', 'req_identifier'=>'resource'],
    'cubrid_num_fields' => ['int', 'result'=>'resource'],
    'cubrid_num_rows' => ['int', 'req_identifier'=>'resource'],
    'cubrid_pconnect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'],
    'cubrid_pconnect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'],
    'cubrid_ping' => ['bool', 'conn_identifier='=>''],
    'cubrid_prepare' => ['resource', 'conn_identifier'=>'resource', 'prepare_stmt'=>'string', 'option='=>'int'],
    'cubrid_put' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'string', 'value='=>'mixed'],
    'cubrid_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''],
    'cubrid_real_escape_string' => ['string', 'unescaped_string'=>'string', 'conn_identifier='=>''],
    'cubrid_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>''],
    'cubrid_rollback' => ['bool', 'conn_identifier'=>'resource'],
    'cubrid_save_to_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'],
    'cubrid_schema' => ['array', 'conn_identifier'=>'resource', 'schema_type'=>'int', 'class_name='=>'string', 'attr_name='=>'string'],
    'cubrid_send_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string'],
    'cubrid_seq_add' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'seq_element'=>'string'],
    'cubrid_seq_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int'],
    'cubrid_seq_insert' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'],
    'cubrid_seq_put' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'],
    'cubrid_set_add' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'],
    'cubrid_set_autocommit' => ['bool', 'conn_identifier'=>'resource', 'mode'=>'bool'],
    'cubrid_set_db_parameter' => ['bool', 'conn_identifier'=>'resource', 'param_type'=>'int', 'param_value'=>'int'],
    'cubrid_set_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'],
    'cubrid_set_query_timeout' => ['bool', 'req_identifier'=>'resource', 'timeout'=>'int'],
    'cubrid_unbuffered_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''],
    'cubrid_version' => ['string'],
    'curl_close' => ['void', 'ch'=>'resource'],
    'curl_copy_handle' => ['resource', 'ch'=>'resource'],
    'curl_errno' => ['int', 'ch'=>'resource'],
    'curl_error' => ['string', 'ch'=>'resource'],
    'curl_escape' => ['string|false', 'ch'=>'resource', 'string'=>'string'],
    'curl_exec' => ['bool|string', 'ch'=>'resource'],
    'curl_file_create' => ['CURLFile', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'],
    'curl_getinfo' => ['mixed', 'ch'=>'resource', 'option='=>'int'],
    'curl_init' => ['resource|false', 'url='=>'string'],
    'curl_multi_add_handle' => ['int', 'mh'=>'resource', 'ch'=>'resource'],
    'curl_multi_close' => ['void', 'mh'=>'resource'],
    'curl_multi_exec' => ['int', 'mh'=>'resource', '&w_still_running'=>'int'],
    'curl_multi_getcontent' => ['string', 'ch'=>'resource'],
    'curl_multi_info_read' => ['array|false', 'mh'=>'resource', '&w_msgs_in_queue='=>'int'],
    'curl_multi_init' => ['resource'],
    'curl_multi_remove_handle' => ['int', 'mh'=>'resource', 'ch'=>'resource'],
    'curl_multi_select' => ['int', 'mh'=>'resource', 'timeout='=>'float'],
    'curl_multi_setopt' => ['bool', 'mh'=>'resource', 'option'=>'int', 'value'=>'mixed'],
    'curl_multi_strerror' => ['?string', 'error_code'=>'int'],
    'curl_pause' => ['int', 'ch'=>'resource', 'bitmask'=>'int'],
    'curl_reset' => ['void', 'ch'=>'resource'],
    'curl_setopt' => ['bool', 'ch'=>'resource', 'option'=>'int', 'value'=>'callable|mixed'],
    'curl_setopt_array' => ['bool', 'ch'=>'resource', 'options'=>'array'],
    'curl_share_close' => ['void', 'sh'=>'resource'],
    'curl_share_init' => ['resource'],
    'curl_share_setopt' => ['bool', 'sh'=>'resource', 'option'=>'int', 'value'=>'mixed'],
    'curl_strerror' => ['?string', 'error_code'=>'int'],
    'curl_unescape' => ['string|false', 'ch'=>'resource', 'string'=>'string'],
    'curl_version' => ['array', 'version='=>'int'],
    'current' => ['mixed|false', 'array'=>'array|object'],
    'cyrus_authenticate' => ['void', 'connection'=>'resource', 'mechlist='=>'string', 'service='=>'string', 'user='=>'string', 'minssf='=>'int', 'maxssf='=>'int', 'authname='=>'string', 'password='=>'string'],
    'cyrus_bind' => ['bool', 'connection'=>'resource', 'callbacks'=>'array'],
    'cyrus_close' => ['bool', 'connection'=>'resource'],
    'cyrus_connect' => ['resource', 'host='=>'string', 'port='=>'string', 'flags='=>'int'],
    'cyrus_query' => ['array', 'connection'=>'resource', 'query'=>'string'],
    'cyrus_unbind' => ['bool', 'connection'=>'resource', 'trigger_name'=>'string'],
    'date' => ['string', 'format'=>'string', 'timestamp='=>'int'],
    'date_add' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'],
    'date_create' => ['DateTime|false', 'datetime='=>'string', 'timezone='=>'?DateTimeZone'],
    'date_create_from_format' => ['DateTime|false', 'format'=>'string', 'datetime'=>'string', 'timezone='=>'?\DateTimeZone'],
    'date_create_immutable' => ['DateTimeImmutable|false', 'datetime='=>'string', 'timezone='=>'?DateTimeZone'],
    'date_create_immutable_from_format' => ['DateTimeImmutable|false', 'format'=>'string', 'datetime'=>'string', 'timezone='=>'?DateTimeZone'],
    'date_date_set' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'month'=>'int', 'day'=>'int'],
    'date_default_timezone_get' => ['string'],
    'date_default_timezone_set' => ['bool', 'timezoneId'=>'string'],
    'date_diff' => ['DateInterval|false', 'baseObject'=>'DateTimeInterface', 'targetObject'=>'DateTimeInterface', 'absolute='=>'bool'],
    'date_format' => ['string|false', 'object'=>'DateTimeInterface', 'format'=>'string'],
    'date_get_last_errors' => ['array{warning_count:int,warnings:array<int,string>,error_count:int,errors:array<int,string>}|false'],
    'date_interval_create_from_date_string' => ['DateInterval', 'datetime'=>'string'],
    'date_interval_format' => ['string', 'object'=>'DateInterval', 'format'=>'string'],
    'date_isodate_set' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'week'=>'int', 'dayOfWeek='=>'int|mixed'],
    'date_modify' => ['DateTime|false', 'object'=>'DateTime', 'modifier'=>'string'],
    'date_offset_get' => ['int|false', 'object'=>'DateTimeInterface'],
    'date_parse' => ['array|false', 'datetime'=>'string'],
    'date_parse_from_format' => ['array', 'format'=>'string', 'datetime'=>'string'],
    'date_sub' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'],
    'date_sun_info' => ['array|false', 'timestamp'=>'int', 'latitude'=>'float', 'longitude'=>'float'],
    'date_sunrise' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'utcOffset='=>'float'],
    'date_sunset' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'utcOffset='=>'float'],
    'date_time_set' => ['DateTime|false', 'object'=>'', 'hour'=>'', 'minute'=>'', 'second='=>'', 'microsecond='=>''],
    'date_timestamp_get' => ['int', 'object'=>'DateTimeInterface'],
    'date_timestamp_set' => ['DateTime|false', 'object'=>'DateTime', 'timestamp'=>'int'],
    'date_timezone_get' => ['DateTimeZone|false', 'object'=>'DateTimeInterface'],
    'date_timezone_set' => ['DateTime|false', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'],
    'datefmt_create' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType'=>'int', 'timeType'=>'int', 'timezone='=>'DateTimeZone|IntlTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'string'],
    'datefmt_format' => ['string|false', 'formatter'=>'IntlDateFormatter', 'datetime'=>'DateTime|IntlCalendar|array|int'],
    'datefmt_format_object' => ['string|false', 'datetime'=>'object', 'format='=>'mixed', 'locale='=>'?string'],
    'datefmt_get_calendar' => ['int', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_calendar_object' => ['IntlCalendar|false|null', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_datetype' => ['int', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_error_code' => ['int', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_error_message' => ['string', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_locale' => ['string|false', 'formatter'=>'IntlDateFormatter', 'type='=>'int'],
    'datefmt_get_pattern' => ['string', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_timetype' => ['int', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_timezone' => ['IntlTimeZone|false', 'formatter'=>'IntlDateFormatter'],
    'datefmt_get_timezone_id' => ['string|false', 'formatter'=>'IntlDateFormatter'],
    'datefmt_is_lenient' => ['bool', 'formatter'=>'IntlDateFormatter'],
    'datefmt_localtime' => ['array|false', 'formatter'=>'IntlDateFormatter', 'string'=>'string', '&rw_offset='=>'int'],
    'datefmt_parse' => ['int|false', 'formatter'=>'IntlDateFormatter', 'string'=>'string', '&rw_offset='=>'int'],
    'datefmt_set_calendar' => ['bool', 'formatter'=>'IntlDateFormatter', 'calendar'=>'IntlCalendar|int|null'],
    'datefmt_set_lenient' => ['void', 'formatter'=>'IntlDateFormatter', 'lenient'=>'bool'],
    'datefmt_set_pattern' => ['bool', 'formatter'=>'IntlDateFormatter', 'pattern'=>'string'],
    'datefmt_set_timezone' => ['false|null', 'formatter'=>'IntlDateFormatter', 'timezone'=>'IntlTimeZone|DateTimeZone|string|null'],
    'db2_autocommit' => ['mixed', 'connection'=>'resource', 'value='=>'int'],
    'db2_bind_param' => ['bool', 'stmt'=>'resource', 'parameter_number'=>'int', 'variable_name'=>'string', 'parameter_type='=>'int', 'data_type='=>'int', 'precision='=>'int', 'scale='=>'int'],
    'db2_client_info' => ['object|false', 'connection'=>'resource'],
    'db2_close' => ['bool', 'connection'=>'resource'],
    'db2_column_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'],
    'db2_columns' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'],
    'db2_commit' => ['bool', 'connection'=>'resource'],
    'db2_conn_error' => ['string', 'connection='=>'resource'],
    'db2_conn_errormsg' => ['string', 'connection='=>'resource'],
    'db2_connect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'],
    'db2_cursor_type' => ['int', 'stmt'=>'resource'],
    'db2_escape_string' => ['string', 'string_literal'=>'string'],
    'db2_exec' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'],
    'db2_execute' => ['bool', 'stmt'=>'resource', 'parameters='=>'array'],
    'db2_fetch_array' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'],
    'db2_fetch_assoc' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'],
    'db2_fetch_both' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'],
    'db2_fetch_object' => ['object|false', 'stmt'=>'resource', 'row_number='=>'int'],
    'db2_fetch_row' => ['bool', 'stmt'=>'resource', 'row_number='=>'int'],
    'db2_field_display_size' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_field_name' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_field_num' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_field_precision' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_field_scale' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_field_type' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_field_width' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_foreign_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'],
    'db2_free_result' => ['bool', 'stmt'=>'resource'],
    'db2_free_stmt' => ['bool', 'stmt'=>'resource'],
    'db2_get_option' => ['string|false', 'resource'=>'resource', 'option'=>'string'],
    'db2_last_insert_id' => ['string', 'resource'=>'resource'],
    'db2_lob_read' => ['string|false', 'stmt'=>'resource', 'colnum'=>'int', 'length'=>'int'],
    'db2_next_result' => ['resource|false', 'stmt'=>'resource'],
    'db2_num_fields' => ['int|false', 'stmt'=>'resource'],
    'db2_num_rows' => ['int', 'stmt'=>'resource'],
    'db2_pclose' => ['bool', 'resource'=>'resource'],
    'db2_pconnect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'],
    'db2_prepare' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'],
    'db2_primary_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'],
    'db2_primarykeys' => [''],
    'db2_procedure_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string', 'parameter'=>'string'],
    'db2_procedurecolumns' => [''],
    'db2_procedures' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string'],
    'db2_result' => ['mixed', 'stmt'=>'resource', 'column'=>'mixed'],
    'db2_rollback' => ['bool', 'connection'=>'resource'],
    'db2_server_info' => ['object|false', 'connection'=>'resource'],
    'db2_set_option' => ['bool', 'resource'=>'resource', 'options'=>'array', 'type'=>'int'],
    'db2_setoption' => [''],
    'db2_special_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'scope'=>'int'],
    'db2_specialcolumns' => [''],
    'db2_statistics' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'unique'=>'bool'],
    'db2_stmt_error' => ['string', 'stmt='=>'resource'],
    'db2_stmt_errormsg' => ['string', 'stmt='=>'resource'],
    'db2_table_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string'],
    'db2_tableprivileges' => [''],
    'db2_tables' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'table_type='=>'string'],
    'dba_close' => ['void', 'dba'=>'resource'],
    'dba_delete' => ['bool', 'key'=>'string', 'dba'=>'resource'],
    'dba_exists' => ['bool', 'key'=>'string', 'dba'=>'resource'],
    'dba_fetch' => ['string|false', 'key'=>'string', 'skip'=>'int', 'dba'=>'resource'],
    'dba_fetch\'1' => ['string|false', 'key'=>'string', 'skip'=>'resource'],
    'dba_firstkey' => ['string', 'dba'=>'resource'],
    'dba_handlers' => ['array', 'full_info='=>'bool'],
    'dba_insert' => ['bool', 'key'=>'string', 'value'=>'string', 'dba'=>'resource'],
    'dba_key_split' => ['array|false', 'key'=>'string|false|null'],
    'dba_list' => ['array'],
    'dba_nextkey' => ['string', 'dba'=>'resource'],
    'dba_open' => ['resource', 'path'=>'string', 'mode'=>'string', 'handler='=>'string', '...handler_params='=>'string'],
    'dba_optimize' => ['bool', 'dba'=>'resource'],
    'dba_popen' => ['resource', 'path'=>'string', 'mode'=>'string', 'handler='=>'string', '...handler_params='=>'string'],
    'dba_replace' => ['bool', 'key'=>'string', 'value'=>'string', 'dba'=>'resource'],
    'dba_sync' => ['bool', 'dba'=>'resource'],
    'dbase_add_record' => ['bool', 'dbase_identifier'=>'resource', 'record'=>'array'],
    'dbase_close' => ['bool', 'dbase_identifier'=>'resource'],
    'dbase_create' => ['resource|false', 'filename'=>'string', 'fields'=>'array'],
    'dbase_delete_record' => ['bool', 'dbase_identifier'=>'resource', 'record_number'=>'int'],
    'dbase_get_header_info' => ['array', 'dbase_identifier'=>'resource'],
    'dbase_get_record' => ['array', 'dbase_identifier'=>'resource', 'record_number'=>'int'],
    'dbase_get_record_with_names' => ['array', 'dbase_identifier'=>'resource', 'record_number'=>'int'],
    'dbase_numfields' => ['int', 'dbase_identifier'=>'resource'],
    'dbase_numrecords' => ['int', 'dbase_identifier'=>'resource'],
    'dbase_open' => ['resource|false', 'filename'=>'string', 'mode'=>'int'],
    'dbase_pack' => ['bool', 'dbase_identifier'=>'resource'],
    'dbase_replace_record' => ['bool', 'dbase_identifier'=>'resource', 'record'=>'array', 'record_number'=>'int'],
    'dbplus_add' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
    'dbplus_aql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'],
    'dbplus_chdir' => ['string', 'newdir='=>'string'],
    'dbplus_close' => ['mixed', 'relation'=>'resource'],
    'dbplus_curr' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
    'dbplus_errcode' => ['string', 'errno='=>'int'],
    'dbplus_errno' => ['int'],
    'dbplus_find' => ['int', 'relation'=>'resource', 'constraints'=>'array', 'tuple'=>'mixed'],
    'dbplus_first' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
    'dbplus_flush' => ['int', 'relation'=>'resource'],
    'dbplus_freealllocks' => ['int'],
    'dbplus_freelock' => ['int', 'relation'=>'resource', 'tuple'=>'string'],
    'dbplus_freerlocks' => ['int', 'relation'=>'resource'],
    'dbplus_getlock' => ['int', 'relation'=>'resource', 'tuple'=>'string'],
    'dbplus_getunique' => ['int', 'relation'=>'resource', 'uniqueid'=>'int'],
    'dbplus_info' => ['int', 'relation'=>'resource', 'key'=>'string', 'result'=>'array'],
    'dbplus_last' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
    'dbplus_lockrel' => ['int', 'relation'=>'resource'],
    'dbplus_next' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
    'dbplus_open' => ['resource', 'name'=>'string'],
    'dbplus_prev' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
    'dbplus_rchperm' => ['int', 'relation'=>'resource', 'mask'=>'int', 'user'=>'string', 'group'=>'string'],
    'dbplus_rcreate' => ['resource', 'name'=>'string', 'domlist'=>'mixed', 'overwrite='=>'bool'],
    'dbplus_rcrtexact' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'bool'],
    'dbplus_rcrtlike' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'int'],
    'dbplus_resolve' => ['array', 'relation_name'=>'string'],
    'dbplus_restorepos' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
    'dbplus_rkeys' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed'],
    'dbplus_ropen' => ['resource', 'name'=>'string'],
    'dbplus_rquery' => ['resource', 'query'=>'string', 'dbpath='=>'string'],
    'dbplus_rrename' => ['int', 'relation'=>'resource', 'name'=>'string'],
    'dbplus_rsecindex' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed', 'type'=>'int'],
    'dbplus_runlink' => ['int', 'relation'=>'resource'],
    'dbplus_rzap' => ['int', 'relation'=>'resource'],
    'dbplus_savepos' => ['int', 'relation'=>'resource'],
    'dbplus_setindex' => ['int', 'relation'=>'resource', 'idx_name'=>'string'],
    'dbplus_setindexbynumber' => ['int', 'relation'=>'resource', 'idx_number'=>'int'],
    'dbplus_sql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'],
    'dbplus_tcl' => ['string', 'sid'=>'int', 'script'=>'string'],
    'dbplus_tremove' => ['int', 'relation'=>'resource', 'tuple'=>'array', 'current='=>'array'],
    'dbplus_undo' => ['int', 'relation'=>'resource'],
    'dbplus_undoprepare' => ['int', 'relation'=>'resource'],
    'dbplus_unlockrel' => ['int', 'relation'=>'resource'],
    'dbplus_unselect' => ['int', 'relation'=>'resource'],
    'dbplus_update' => ['int', 'relation'=>'resource', 'old'=>'array', 'new'=>'array'],
    'dbplus_xlockrel' => ['int', 'relation'=>'resource'],
    'dbplus_xunlockrel' => ['int', 'relation'=>'resource'],
    'dbx_close' => ['int', 'link_identifier'=>'object'],
    'dbx_compare' => ['int', 'row_a'=>'array', 'row_b'=>'array', 'column_key'=>'string', 'flags='=>'int'],
    'dbx_connect' => ['object', 'module'=>'mixed', 'host'=>'string', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'persistent='=>'int'],
    'dbx_error' => ['string', 'link_identifier'=>'object'],
    'dbx_escape_string' => ['string', 'link_identifier'=>'object', 'text'=>'string'],
    'dbx_fetch_row' => ['mixed', 'result_identifier'=>'object'],
    'dbx_query' => ['mixed', 'link_identifier'=>'object', 'sql_statement'=>'string', 'flags='=>'int'],
    'dbx_sort' => ['bool', 'result'=>'object', 'user_compare_function'=>'string'],
    'dcgettext' => ['string', 'domain'=>'string', 'message'=>'string', 'category'=>'int'],
    'dcngettext' => ['string', 'domain'=>'string', 'singular'=>'string', 'plural'=>'string', 'count'=>'int', 'category'=>'int'],
    'deaggregate' => ['', 'object'=>'object', 'class_name='=>'string'],
    'debug_backtrace' => ['list<array{file:string,line:int,function:string,class?:class-string,object?:object,type?:string,args?:list}>', 'options='=>'int', 'limit='=>'int'],
    'debug_print_backtrace' => ['void', 'options='=>'int', 'limit='=>'int'],
    'debug_zval_dump' => ['void', '...value'=>'mixed'],
    'debugger_connect' => [''],
    'debugger_connector_pid' => [''],
    'debugger_get_server_start_time' => [''],
    'debugger_print' => [''],
    'debugger_start_debug' => [''],
    'decbin' => ['string', 'num'=>'int'],
    'dechex' => ['string', 'num'=>'int'],
    'decoct' => ['string', 'num'=>'int'],
    'define' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'case_insensitive='=>'bool'],
    'define_syslog_variables' => ['void'],
    'defined' => ['bool', 'constant_name'=>'string'],
    'deflate_add' => ['string|false', 'context'=>'resource', 'data'=>'string', 'flush_mode='=>'int'],
    'deflate_init' => ['resource|false', 'encoding'=>'int', 'options='=>'array'],
    'deg2rad' => ['float', 'num'=>'float'],
    'dgettext' => ['string', 'domain'=>'string', 'message'=>'string'],
    'dio_close' => ['void', 'fd'=>'resource'],
    'dio_fcntl' => ['mixed', 'fd'=>'resource', 'cmd'=>'int', 'args='=>'mixed'],
    'dio_open' => ['resource|false', 'filename'=>'string', 'flags'=>'int', 'mode='=>'int'],
    'dio_read' => ['string', 'fd'=>'resource', 'length='=>'int'],
    'dio_seek' => ['int', 'fd'=>'resource', 'pos'=>'int', 'whence='=>'int'],
    'dio_stat' => ['?array', 'fd'=>'resource'],
    'dio_tcsetattr' => ['bool', 'fd'=>'resource', 'options'=>'array'],
    'dio_truncate' => ['bool', 'fd'=>'resource', 'offset'=>'int'],
    'dio_write' => ['int', 'fd'=>'resource', 'data'=>'string', 'length='=>'int'],
    'dir' => ['Directory|false', 'directory'=>'string', 'context='=>'resource'],
    'dirname' => ['string', 'path'=>'string', 'levels='=>'int'],
    'disk_free_space' => ['float|false', 'directory'=>'string'],
    'disk_total_space' => ['float|false', 'directory'=>'string'],
    'diskfreespace' => ['float|false', 'directory'=>'string'],
    'display_disabled_function' => [''],
    'dl' => ['bool', 'extension_filename'=>'string'],
    'dngettext' => ['string', 'domain'=>'string', 'singular'=>'string', 'plural'=>'string', 'count'=>'int'],
    'dns_check_record' => ['bool', 'hostname'=>'string', 'type='=>'string'],
    'dns_get_mx' => ['bool', 'hostname'=>'string', '&w_hosts'=>'array', '&w_weights'=>'array'],
    'dns_get_record' => ['list<array>|false', 'hostname'=>'string', 'type='=>'int', '&w_authoritative_name_servers='=>'array', '&w_additional_records='=>'array', 'raw='=>'bool'],
    'dom_document_relaxNG_validate_file' => ['bool', 'filename'=>'string'],
    'dom_document_relaxNG_validate_xml' => ['bool', 'source'=>'string'],
    'dom_document_schema_validate' => ['bool', 'source'=>'string', 'flags'=>'int'],
    'dom_document_schema_validate_file' => ['bool', 'filename'=>'string', 'flags'=>'int'],
    'dom_document_xinclude' => ['int', 'options'=>'int'],
    'dom_import_simplexml' => ['DOMElement|null', 'node'=>'SimpleXMLElement'],
    'dom_xpath_evaluate' => ['', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'],
    'dom_xpath_query' => ['DOMNodeList', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'],
    'dom_xpath_register_ns' => ['bool', 'prefix'=>'string', 'uri'=>'string'],
    'dom_xpath_register_php_functions' => [''],
    'domxml_new_doc' => ['DomDocument', 'version'=>'string'],
    'domxml_open_file' => ['DomDocument', 'filename'=>'string', 'mode='=>'int', 'error='=>'array'],
    'domxml_open_mem' => ['DomDocument', 'string'=>'string', 'mode='=>'int', 'error='=>'array'],
    'domxml_version' => ['string'],
    'domxml_xmltree' => ['DomDocument', 'string'=>'string'],
    'domxml_xslt_stylesheet' => ['DomXsltStylesheet', 'xsl_buf'=>'string'],
    'domxml_xslt_stylesheet_doc' => ['DomXsltStylesheet', 'xsl_doc'=>'DOMDocument'],
    'domxml_xslt_stylesheet_file' => ['DomXsltStylesheet', 'xsl_file'=>'string'],
    'domxml_xslt_version' => ['int'],
    'dotnet_load' => ['int', 'assembly_name'=>'string', 'datatype_name='=>'string', 'codepage='=>'int'],
    'doubleval' => ['float', 'value'=>'mixed'],
    'each' => ['array{0:int|string,key:int|string,1:mixed,value:mixed}', '&r_arr'=>'array'],
    'easter_date' => ['int', 'year='=>'int'],
    'easter_days' => ['int', 'year='=>'int', 'mode='=>'int'],
    'echo' => ['void', 'arg1'=>'string', '...args='=>'string'],
    'eio_busy' => ['resource', 'delay'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_cancel' => ['void', 'req'=>'resource'],
    'eio_chmod' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_chown' => ['resource', 'path'=>'string', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_close' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_custom' => ['resource', 'execute'=>'callable', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_dup2' => ['resource', 'fd'=>'mixed', 'fd2'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_event_loop' => ['bool'],
    'eio_fallocate' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_fchmod' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_fchown' => ['resource', 'fd'=>'mixed', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_fdatasync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_fstat' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_fstatvfs' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_fsync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_ftruncate' => ['resource', 'fd'=>'mixed', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_futime' => ['resource', 'fd'=>'mixed', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_get_event_stream' => ['mixed'],
    'eio_get_last_error' => ['string', 'req'=>'resource'],
    'eio_grp' => ['resource', 'callback'=>'callable', 'data='=>'string'],
    'eio_grp_add' => ['void', 'grp'=>'resource', 'req'=>'resource'],
    'eio_grp_cancel' => ['void', 'grp'=>'resource'],
    'eio_grp_limit' => ['void', 'grp'=>'resource', 'limit'=>'int'],
    'eio_init' => ['void'],
    'eio_link' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_lstat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_mkdir' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_mknod' => ['resource', 'path'=>'string', 'mode'=>'int', 'dev'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_nop' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_npending' => ['int'],
    'eio_nready' => ['int'],
    'eio_nreqs' => ['int'],
    'eio_nthreads' => ['int'],
    'eio_open' => ['resource', 'path'=>'string', 'flags'=>'int', 'mode'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_poll' => ['int'],
    'eio_read' => ['resource', 'fd'=>'mixed', 'length'=>'int', 'offset'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_readahead' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_readdir' => ['resource', 'path'=>'string', 'flags'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'],
    'eio_readlink' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'],
    'eio_realpath' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'],
    'eio_rename' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_rmdir' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_seek' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'whence'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_sendfile' => ['resource', 'out_fd'=>'mixed', 'in_fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'string'],
    'eio_set_max_idle' => ['void', 'nthreads'=>'int'],
    'eio_set_max_parallel' => ['void', 'nthreads'=>'int'],
    'eio_set_max_poll_reqs' => ['void', 'nreqs'=>'int'],
    'eio_set_max_poll_time' => ['void', 'nseconds'=>'float'],
    'eio_set_min_parallel' => ['void', 'nthreads'=>'string'],
    'eio_stat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_statvfs' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
    'eio_symlink' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_sync' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_sync_file_range' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'nbytes'=>'int', 'flags'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_syncfs' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_truncate' => ['resource', 'path'=>'string', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_unlink' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_utime' => ['resource', 'path'=>'string', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'eio_write' => ['resource', 'fd'=>'mixed', 'string'=>'string', 'length='=>'int', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
    'empty' => ['bool', 'value'=>'mixed'],
    'enchant_broker_describe' => ['array', 'broker'=>'resource'],
    'enchant_broker_dict_exists' => ['bool', 'broker'=>'resource', 'tag'=>'string'],
    'enchant_broker_free' => ['bool', 'broker'=>'resource'],
    'enchant_broker_free_dict' => ['bool', 'dictionary'=>'resource'],
    'enchant_broker_get_dict_path' => ['string', 'broker'=>'resource', 'type'=>'int'],
    'enchant_broker_get_error' => ['string|false', 'broker'=>'resource'],
    'enchant_broker_init' => ['resource|false'],
    'enchant_broker_list_dicts' => ['array<int,array{lang_tag:string,provider_name:string,provider_desc:string,provider_file:string}>|false', 'broker'=>'resource'],
    'enchant_broker_request_dict' => ['resource|false', 'broker'=>'resource', 'tag'=>'string'],
    'enchant_broker_request_pwl_dict' => ['resource|false', 'broker'=>'resource', 'filename'=>'string'],
    'enchant_broker_set_dict_path' => ['bool', 'broker'=>'resource', 'type'=>'int', 'path'=>'string'],
    'enchant_broker_set_ordering' => ['bool', 'broker'=>'resource', 'tag'=>'string', 'ordering'=>'string'],
    'enchant_dict_add_to_personal' => ['void', 'dictionary'=>'resource', 'word'=>'string'],
    'enchant_dict_add_to_session' => ['void', 'dictionary'=>'resource', 'word'=>'string'],
    'enchant_dict_check' => ['bool', 'dictionary'=>'resource', 'word'=>'string'],
    'enchant_dict_describe' => ['array', 'dictionary'=>'resource'],
    'enchant_dict_get_error' => ['string', 'dictionary'=>'resource'],
    'enchant_dict_is_in_session' => ['bool', 'dictionary'=>'resource', 'word'=>'string'],
    'enchant_dict_quick_check' => ['bool', 'dictionary'=>'resource', 'word'=>'string', '&w_suggestions='=>'array<int,string>'],
    'enchant_dict_store_replacement' => ['void', 'dictionary'=>'resource', 'misspelled'=>'string', 'correct'=>'string'],
    'enchant_dict_suggest' => ['array', 'dictionary'=>'resource', 'word'=>'string'],
    'end' => ['mixed|false', '&r_array'=>'array|object'],
    'error_clear_last' => ['void'],
    'error_get_last' => ['?array{type:int,message:string,file:string,line:int}'],
    'error_log' => ['bool', 'message'=>'string', 'message_type='=>'int', 'destination='=>'string', 'additional_headers='=>'string'],
    'error_reporting' => ['int', 'error_level='=>'int'],
    'escapeshellarg' => ['string', 'arg'=>'string'],
    'escapeshellcmd' => ['string', 'command'=>'string'],
    'eval' => ['mixed', 'code_str'=>'string'],
    'event_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'],
    'event_base_free' => ['void', 'event_base'=>'resource'],
    'event_base_loop' => ['int', 'event_base'=>'resource', 'flags='=>'int'],
    'event_base_loopbreak' => ['bool', 'event_base'=>'resource'],
    'event_base_loopexit' => ['bool', 'event_base'=>'resource', 'timeout='=>'int'],
    'event_base_new' => ['resource|false'],
    'event_base_priority_init' => ['bool', 'event_base'=>'resource', 'npriorities'=>'int'],
    'event_base_reinit' => ['bool', 'event_base'=>'resource'],
    'event_base_set' => ['bool', 'event'=>'resource', 'event_base'=>'resource'],
    'event_buffer_base_set' => ['bool', 'bevent'=>'resource', 'event_base'=>'resource'],
    'event_buffer_disable' => ['bool', 'bevent'=>'resource', 'events'=>'int'],
    'event_buffer_enable' => ['bool', 'bevent'=>'resource', 'events'=>'int'],
    'event_buffer_fd_set' => ['void', 'bevent'=>'resource', 'fd'=>'resource'],
    'event_buffer_free' => ['void', 'bevent'=>'resource'],
    'event_buffer_new' => ['resource|false', 'stream'=>'resource', 'readcb'=>'callable|null', 'writecb'=>'callable|null', 'errorcb'=>'callable', 'arg='=>'mixed'],
    'event_buffer_priority_set' => ['bool', 'bevent'=>'resource', 'priority'=>'int'],
    'event_buffer_read' => ['string', 'bevent'=>'resource', 'data_size'=>'int'],
    'event_buffer_set_callback' => ['bool', 'event'=>'resource', 'readcb'=>'mixed', 'writecb'=>'mixed', 'errorcb'=>'mixed', 'arg='=>'mixed'],
    'event_buffer_timeout_set' => ['void', 'bevent'=>'resource', 'read_timeout'=>'int', 'write_timeout'=>'int'],
    'event_buffer_watermark_set' => ['void', 'bevent'=>'resource', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'],
    'event_buffer_write' => ['bool', 'bevent'=>'resource', 'data'=>'string', 'data_size='=>'int'],
    'event_del' => ['bool', 'event'=>'resource'],
    'event_free' => ['void', 'event'=>'resource'],
    'event_new' => ['resource|false'],
    'event_priority_set' => ['bool', 'event'=>'resource', 'priority'=>'int'],
    'event_set' => ['bool', 'event'=>'resource', 'fd'=>'int|resource', 'events'=>'int', 'callback'=>'callable', 'arg='=>'mixed'],
    'event_timer_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'],
    'event_timer_del' => ['bool', 'event'=>'resource'],
    'event_timer_new' => ['resource|false'],
    'event_timer_pending' => ['bool', 'event'=>'resource', 'timeout='=>'int'],
    'event_timer_set' => ['bool', 'event'=>'resource', 'callback'=>'callable', 'arg='=>'mixed'],
    'exec' => ['string|false', 'command'=>'string', '&w_output='=>'array', '&w_result_code='=>'int'],
    'exif_imagetype' => ['int|false', 'filename'=>'string'],
    'exif_read_data' => ['array|false', 'file'=>'string|resource', 'required_sections='=>'string', 'as_arrays='=>'bool', 'read_thumbnail='=>'bool'],
    'exif_tagname' => ['string|false', 'index'=>'int'],
    'exif_thumbnail' => ['string|false', 'file'=>'string', '&w_width='=>'int', '&w_height='=>'int', '&w_image_type='=>'int'],
    'exit' => ['', 'status'=>'string|int'],
    'exp' => ['float', 'num'=>'float'],
    'expect_expectl' => ['int', 'expect'=>'resource', 'cases'=>'array', 'match='=>'array'],
    'expect_popen' => ['resource|false', 'command'=>'string'],
    'explode' => ['list<string>|false', 'separator'=>'string', 'string'=>'string', 'limit='=>'int'],
    'expm1' => ['float', 'num'=>'float'],
    'extension_loaded' => ['bool', 'extension'=>'string'],
    'extract' => ['int', '&rw_array'=>'array', 'flags='=>'int', 'prefix='=>'string'],
    'ezmlm_hash' => ['int', 'addr'=>'string'],
    'fam_cancel_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'],
    'fam_close' => ['void', 'fam'=>'resource'],
    'fam_monitor_collection' => ['resource', 'fam'=>'resource', 'dirname'=>'string', 'depth'=>'int', 'mask'=>'string'],
    'fam_monitor_directory' => ['resource', 'fam'=>'resource', 'dirname'=>'string'],
    'fam_monitor_file' => ['resource', 'fam'=>'resource', 'filename'=>'string'],
    'fam_next_event' => ['array', 'fam'=>'resource'],
    'fam_open' => ['resource|false', 'appname='=>'string'],
    'fam_pending' => ['int', 'fam'=>'resource'],
    'fam_resume_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'],
    'fam_suspend_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'],
    'fann_cascadetrain_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'],
    'fann_cascadetrain_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'],
    'fann_clear_scaling_params' => ['bool', 'ann'=>'resource'],
    'fann_copy' => ['resource|false', 'ann'=>'resource'],
    'fann_create_from_file' => ['resource', 'configuration_file'=>'string'],
    'fann_create_shortcut' => ['resource|false', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'],
    'fann_create_shortcut_array' => ['resource|false', 'num_layers'=>'int', 'layers'=>'array'],
    'fann_create_sparse' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'],
    'fann_create_sparse_array' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'layers'=>'array'],
    'fann_create_standard' => ['resource|false', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'],
    'fann_create_standard_array' => ['resource|false', 'num_layers'=>'int', 'layers'=>'array'],
    'fann_create_train' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int'],
    'fann_create_train_from_callback' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int', 'user_function'=>'callable'],
    'fann_descale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'],
    'fann_descale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'],
    'fann_descale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'],
    'fann_destroy' => ['bool', 'ann'=>'resource'],
    'fann_destroy_train' => ['bool', 'train_data'=>'resource'],
    'fann_duplicate_train_data' => ['resource', 'data'=>'resource'],
    'fann_get_MSE' => ['float|false', 'ann'=>'resource'],
    'fann_get_activation_function' => ['int|false', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'],
    'fann_get_activation_steepness' => ['float|false', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'],
    'fann_get_bias_array' => ['array', 'ann'=>'resource'],
    'fann_get_bit_fail' => ['int|false', 'ann'=>'resource'],
    'fann_get_bit_fail_limit' => ['float|false', 'ann'=>'resource'],
    'fann_get_cascade_activation_functions' => ['array|false', 'ann'=>'resource'],
    'fann_get_cascade_activation_functions_count' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_activation_steepnesses' => ['array|false', 'ann'=>'resource'],
    'fann_get_cascade_activation_steepnesses_count' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_candidate_change_fraction' => ['float|false', 'ann'=>'resource'],
    'fann_get_cascade_candidate_limit' => ['float|false', 'ann'=>'resource'],
    'fann_get_cascade_candidate_stagnation_epochs' => ['float|false', 'ann'=>'resource'],
    'fann_get_cascade_max_cand_epochs' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_max_out_epochs' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_min_cand_epochs' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_min_out_epochs' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_num_candidate_groups' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_num_candidates' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_output_change_fraction' => ['float|false', 'ann'=>'resource'],
    'fann_get_cascade_output_stagnation_epochs' => ['int|false', 'ann'=>'resource'],
    'fann_get_cascade_weight_multiplier' => ['float|false', 'ann'=>'resource'],
    'fann_get_connection_array' => ['array', 'ann'=>'resource'],
    'fann_get_connection_rate' => ['float|false', 'ann'=>'resource'],
    'fann_get_errno' => ['int|false', 'errdat'=>'resource'],
    'fann_get_errstr' => ['string|false', 'errdat'=>'resource'],
    'fann_get_layer_array' => ['array', 'ann'=>'resource'],
    'fann_get_learning_momentum' => ['float|false', 'ann'=>'resource'],
    'fann_get_learning_rate' => ['float|false', 'ann'=>'resource'],
    'fann_get_network_type' => ['int|false', 'ann'=>'resource'],
    'fann_get_num_input' => ['int|false', 'ann'=>'resource'],
    'fann_get_num_layers' => ['int|false', 'ann'=>'resource'],
    'fann_get_num_output' => ['int|false', 'ann'=>'resource'],
    'fann_get_quickprop_decay' => ['float|false', 'ann'=>'resource'],
    'fann_get_quickprop_mu' => ['float|false', 'ann'=>'resource'],
    'fann_get_rprop_decrease_factor' => ['float|false', 'ann'=>'resource'],
    'fann_get_rprop_delta_max' => ['float|false', 'ann'=>'resource'],
    'fann_get_rprop_delta_min' => ['float|false', 'ann'=>'resource'],
    'fann_get_rprop_delta_zero' => ['float|false', 'ann'=>'resource'],
    'fann_get_rprop_increase_factor' => ['float|false', 'ann'=>'resource'],
    'fann_get_sarprop_step_error_shift' => ['float|false', 'ann'=>'resource'],
    'fann_get_sarprop_step_error_threshold_factor' => ['float|false', 'ann'=>'resource'],
    'fann_get_sarprop_temperature' => ['float|false', 'ann'=>'resource'],
    'fann_get_sarprop_weight_decay_shift' => ['float|false', 'ann'=>'resource'],
    'fann_get_total_connections' => ['int|false', 'ann'=>'resource'],
    'fann_get_total_neurons' => ['int|false', 'ann'=>'resource'],
    'fann_get_train_error_function' => ['int|false', 'ann'=>'resource'],
    'fann_get_train_stop_function' => ['int|false', 'ann'=>'resource'],
    'fann_get_training_algorithm' => ['int|false', 'ann'=>'resource'],
    'fann_init_weights' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'],
    'fann_length_train_data' => ['int|false', 'data'=>'resource'],
    'fann_merge_train_data' => ['resource|false', 'data1'=>'resource', 'data2'=>'resource'],
    'fann_num_input_train_data' => ['int|false', 'data'=>'resource'],
    'fann_num_output_train_data' => ['int|false', 'data'=>'resource'],
    'fann_print_error' => ['void', 'errdat'=>'string'],
    'fann_randomize_weights' => ['bool', 'ann'=>'resource', 'min_weight'=>'float', 'max_weight'=>'float'],
    'fann_read_train_from_file' => ['resource', 'filename'=>'string'],
    'fann_reset_MSE' => ['bool', 'ann'=>'string'],
    'fann_reset_errno' => ['void', 'errdat'=>'resource'],
    'fann_reset_errstr' => ['void', 'errdat'=>'resource'],
    'fann_run' => ['array|false', 'ann'=>'resource', 'input'=>'array'],
    'fann_save' => ['bool', 'ann'=>'resource', 'configuration_file'=>'string'],
    'fann_save_train' => ['bool', 'data'=>'resource', 'file_name'=>'string'],
    'fann_scale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'],
    'fann_scale_input_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'],
    'fann_scale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'],
    'fann_scale_output_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'],
    'fann_scale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'],
    'fann_scale_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'],
    'fann_set_activation_function' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int', 'neuron'=>'int'],
    'fann_set_activation_function_hidden' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'],
    'fann_set_activation_function_layer' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int'],
    'fann_set_activation_function_output' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'],
    'fann_set_activation_steepness' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int', 'neuron'=>'int'],
    'fann_set_activation_steepness_hidden' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'],
    'fann_set_activation_steepness_layer' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int'],
    'fann_set_activation_steepness_output' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'],
    'fann_set_bit_fail_limit' => ['bool', 'ann'=>'resource', 'bit_fail_limit'=>'float'],
    'fann_set_callback' => ['bool', 'ann'=>'resource', 'callback'=>'callable'],
    'fann_set_cascade_activation_functions' => ['bool', 'ann'=>'resource', 'cascade_activation_functions'=>'array'],
    'fann_set_cascade_activation_steepnesses' => ['bool', 'ann'=>'resource', 'cascade_activation_steepnesses_count'=>'array'],
    'fann_set_cascade_candidate_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_candidate_change_fraction'=>'float'],
    'fann_set_cascade_candidate_limit' => ['bool', 'ann'=>'resource', 'cascade_candidate_limit'=>'float'],
    'fann_set_cascade_candidate_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_candidate_stagnation_epochs'=>'int'],
    'fann_set_cascade_max_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_cand_epochs'=>'int'],
    'fann_set_cascade_max_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_out_epochs'=>'int'],
    'fann_set_cascade_min_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_cand_epochs'=>'int'],
    'fann_set_cascade_min_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_out_epochs'=>'int'],
    'fann_set_cascade_num_candidate_groups' => ['bool', 'ann'=>'resource', 'cascade_num_candidate_groups'=>'int'],
    'fann_set_cascade_output_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_output_change_fraction'=>'float'],
    'fann_set_cascade_output_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_output_stagnation_epochs'=>'int'],
    'fann_set_cascade_weight_multiplier' => ['bool', 'ann'=>'resource', 'cascade_weight_multiplier'=>'float'],
    'fann_set_error_log' => ['void', 'errdat'=>'resource', 'log_file'=>'string'],
    'fann_set_input_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float'],
    'fann_set_learning_momentum' => ['bool', 'ann'=>'resource', 'learning_momentum'=>'float'],
    'fann_set_learning_rate' => ['bool', 'ann'=>'resource', 'learning_rate'=>'float'],
    'fann_set_output_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_output_min'=>'float', 'new_output_max'=>'float'],
    'fann_set_quickprop_decay' => ['bool', 'ann'=>'resource', 'quickprop_decay'=>'float'],
    'fann_set_quickprop_mu' => ['bool', 'ann'=>'resource', 'quickprop_mu'=>'float'],
    'fann_set_rprop_decrease_factor' => ['bool', 'ann'=>'resource', 'rprop_decrease_factor'=>'float'],
    'fann_set_rprop_delta_max' => ['bool', 'ann'=>'resource', 'rprop_delta_max'=>'float'],
    'fann_set_rprop_delta_min' => ['bool', 'ann'=>'resource', 'rprop_delta_min'=>'float'],
    'fann_set_rprop_delta_zero' => ['bool', 'ann'=>'resource', 'rprop_delta_zero'=>'float'],
    'fann_set_rprop_increase_factor' => ['bool', 'ann'=>'resource', 'rprop_increase_factor'=>'float'],
    'fann_set_sarprop_step_error_shift' => ['bool', 'ann'=>'resource', 'sarprop_step_error_shift'=>'float'],
    'fann_set_sarprop_step_error_threshold_factor' => ['bool', 'ann'=>'resource', 'sarprop_step_error_threshold_factor'=>'float'],
    'fann_set_sarprop_temperature' => ['bool', 'ann'=>'resource', 'sarprop_temperature'=>'float'],
    'fann_set_sarprop_weight_decay_shift' => ['bool', 'ann'=>'resource', 'sarprop_weight_decay_shift'=>'float'],
    'fann_set_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float', 'new_output_min'=>'float', 'new_output_max'=>'float'],
    'fann_set_train_error_function' => ['bool', 'ann'=>'resource', 'error_function'=>'int'],
    'fann_set_train_stop_function' => ['bool', 'ann'=>'resource', 'stop_function'=>'int'],
    'fann_set_training_algorithm' => ['bool', 'ann'=>'resource', 'training_algorithm'=>'int'],
    'fann_set_weight' => ['bool', 'ann'=>'resource', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'],
    'fann_set_weight_array' => ['bool', 'ann'=>'resource', 'connections'=>'array'],
    'fann_shuffle_train_data' => ['bool', 'train_data'=>'resource'],
    'fann_subset_train_data' => ['resource', 'data'=>'resource', 'pos'=>'int', 'length'=>'int'],
    'fann_test' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'],
    'fann_test_data' => ['float|false', 'ann'=>'resource', 'data'=>'resource'],
    'fann_train' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'],
    'fann_train_epoch' => ['float|false', 'ann'=>'resource', 'data'=>'resource'],
    'fann_train_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'],
    'fann_train_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'],
    'fastcgi_finish_request' => ['bool'],
    'fbsql_affected_rows' => ['int', 'link_identifier='=>'?resource'],
    'fbsql_autocommit' => ['bool', 'link_identifier'=>'resource', 'onoff='=>'bool'],
    'fbsql_blob_size' => ['int', 'blob_handle'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_change_user' => ['bool', 'user'=>'string', 'password'=>'string', 'database='=>'string', 'link_identifier='=>'?resource'],
    'fbsql_clob_size' => ['int', 'clob_handle'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_close' => ['bool', 'link_identifier='=>'?resource'],
    'fbsql_commit' => ['bool', 'link_identifier='=>'?resource'],
    'fbsql_connect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'],
    'fbsql_create_blob' => ['string', 'blob_data'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_create_clob' => ['string', 'clob_data'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'],
    'fbsql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'],
    'fbsql_database' => ['string', 'link_identifier'=>'resource', 'database='=>'string'],
    'fbsql_database_password' => ['string', 'link_identifier'=>'resource', 'database_password='=>'string'],
    'fbsql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_db_status' => ['int', 'database_name'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_errno' => ['int', 'link_identifier='=>'?resource'],
    'fbsql_error' => ['string', 'link_identifier='=>'?resource'],
    'fbsql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'],
    'fbsql_fetch_assoc' => ['array', 'result'=>'resource'],
    'fbsql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'],
    'fbsql_fetch_lengths' => ['array', 'result'=>'resource'],
    'fbsql_fetch_object' => ['object', 'result'=>'resource'],
    'fbsql_fetch_row' => ['array', 'result'=>'resource'],
    'fbsql_field_flags' => ['string', 'result'=>'resource', 'field_offset='=>'int'],
    'fbsql_field_len' => ['int', 'result'=>'resource', 'field_offset='=>'int'],
    'fbsql_field_name' => ['string', 'result'=>'resource', 'field_index='=>'int'],
    'fbsql_field_seek' => ['bool', 'result'=>'resource', 'field_offset='=>'int'],
    'fbsql_field_table' => ['string', 'result'=>'resource', 'field_offset='=>'int'],
    'fbsql_field_type' => ['string', 'result'=>'resource', 'field_offset='=>'int'],
    'fbsql_free_result' => ['bool', 'result'=>'resource'],
    'fbsql_get_autostart_info' => ['array', 'link_identifier='=>'?resource'],
    'fbsql_hostname' => ['string', 'link_identifier'=>'resource', 'host_name='=>'string'],
    'fbsql_insert_id' => ['int', 'link_identifier='=>'?resource'],
    'fbsql_list_dbs' => ['resource', 'link_identifier='=>'?resource'],
    'fbsql_list_fields' => ['resource', 'database_name'=>'string', 'table_name'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_next_result' => ['bool', 'result'=>'resource'],
    'fbsql_num_fields' => ['int', 'result'=>'resource'],
    'fbsql_num_rows' => ['int', 'result'=>'resource'],
    'fbsql_password' => ['string', 'link_identifier'=>'resource', 'password='=>'string'],
    'fbsql_pconnect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'],
    'fbsql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource', 'batch_size='=>'int'],
    'fbsql_read_blob' => ['string', 'blob_handle'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_read_clob' => ['string', 'clob_handle'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_result' => ['mixed', 'result'=>'resource', 'row='=>'int', 'field='=>'mixed'],
    'fbsql_rollback' => ['bool', 'link_identifier='=>'?resource'],
    'fbsql_rows_fetched' => ['int', 'result'=>'resource'],
    'fbsql_select_db' => ['bool', 'database_name='=>'string', 'link_identifier='=>'?resource'],
    'fbsql_set_characterset' => ['void', 'link_identifier'=>'resource', 'characterset'=>'int', 'in_out_both='=>'int'],
    'fbsql_set_lob_mode' => ['bool', 'result'=>'resource', 'lob_mode'=>'int'],
    'fbsql_set_password' => ['bool', 'link_identifier'=>'resource', 'user'=>'string', 'password'=>'string', 'old_password'=>'string'],
    'fbsql_set_transaction' => ['void', 'link_identifier'=>'resource', 'locking'=>'int', 'isolation'=>'int'],
    'fbsql_start_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'],
    'fbsql_stop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
    'fbsql_table_name' => ['string', 'result'=>'resource', 'index'=>'int'],
    'fbsql_username' => ['string', 'link_identifier'=>'resource', 'username='=>'string'],
    'fbsql_warnings' => ['bool', 'onoff='=>'bool'],
    'fclose' => ['bool', 'stream'=>'resource'],
    'fdf_add_doc_javascript' => ['bool', 'fdf_document'=>'resource', 'script_name'=>'string', 'script_code'=>'string'],
    'fdf_add_template' => ['bool', 'fdf_document'=>'resource', 'newpage'=>'int', 'filename'=>'string', 'template'=>'string', 'rename'=>'int'],
    'fdf_close' => ['void', 'fdf_document'=>'resource'],
    'fdf_create' => ['resource'],
    'fdf_enum_values' => ['bool', 'fdf_document'=>'resource', 'function'=>'callable', 'userdata='=>'mixed'],
    'fdf_errno' => ['int'],
    'fdf_error' => ['string', 'error_code='=>'int'],
    'fdf_get_ap' => ['bool', 'fdf_document'=>'resource', 'field'=>'string', 'face'=>'int', 'filename'=>'string'],
    'fdf_get_attachment' => ['array', 'fdf_document'=>'resource', 'fieldname'=>'string', 'savepath'=>'string'],
    'fdf_get_encoding' => ['string', 'fdf_document'=>'resource'],
    'fdf_get_file' => ['string', 'fdf_document'=>'resource'],
    'fdf_get_flags' => ['int', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int'],
    'fdf_get_opt' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element='=>'int'],
    'fdf_get_status' => ['string', 'fdf_document'=>'resource'],
    'fdf_get_value' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'which='=>'int'],
    'fdf_get_version' => ['string', 'fdf_document='=>'resource'],
    'fdf_header' => ['void'],
    'fdf_next_field_name' => ['string', 'fdf_document'=>'resource', 'fieldname='=>'string'],
    'fdf_open' => ['resource|false', 'filename'=>'string'],
    'fdf_open_string' => ['resource', 'fdf_data'=>'string'],
    'fdf_remove_item' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'item'=>'int'],
    'fdf_save' => ['bool', 'fdf_document'=>'resource', 'filename='=>'string'],
    'fdf_save_string' => ['string', 'fdf_document'=>'resource'],
    'fdf_set_ap' => ['bool', 'fdf_document'=>'resource', 'field_name'=>'string', 'face'=>'int', 'filename'=>'string', 'page_number'=>'int'],
    'fdf_set_encoding' => ['bool', 'fdf_document'=>'resource', 'encoding'=>'string'],
    'fdf_set_file' => ['bool', 'fdf_document'=>'resource', 'url'=>'string', 'target_frame='=>'string'],
    'fdf_set_flags' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int', 'newflags'=>'int'],
    'fdf_set_javascript_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string'],
    'fdf_set_on_import_javascript' => ['bool', 'fdf_document'=>'resource', 'script'=>'string', 'before_data_import'=>'bool'],
    'fdf_set_opt' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element'=>'int', 'string1'=>'string', 'string2'=>'string'],
    'fdf_set_status' => ['bool', 'fdf_document'=>'resource', 'status'=>'string'],
    'fdf_set_submit_form_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string', 'flags'=>'int'],
    'fdf_set_target_frame' => ['bool', 'fdf_document'=>'resource', 'frame_name'=>'string'],
    'fdf_set_value' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'value'=>'mixed', 'isname='=>'int'],
    'fdf_set_version' => ['bool', 'fdf_document'=>'resource', 'version'=>'string'],
    'feof' => ['bool', 'stream'=>'resource'],
    'fflush' => ['bool', 'stream'=>'resource'],
    'ffmpeg_animated_gif::__construct' => ['void', 'output_file_path'=>'string', 'width'=>'int', 'height'=>'int', 'frame_rate'=>'int', 'loop_count='=>'int'],
    'ffmpeg_animated_gif::addFrame' => ['', 'frame_to_add'=>'ffmpeg_frame'],
    'ffmpeg_frame::__construct' => ['void', 'gd_image'=>'resource'],
    'ffmpeg_frame::crop' => ['', 'crop_top'=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'],
    'ffmpeg_frame::getHeight' => ['int'],
    'ffmpeg_frame::getPTS' => ['int'],
    'ffmpeg_frame::getPresentationTimestamp' => ['int'],
    'ffmpeg_frame::getWidth' => ['int'],
    'ffmpeg_frame::resize' => ['', 'width'=>'int', 'height'=>'int', 'crop_top='=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'],
    'ffmpeg_frame::toGDImage' => ['resource'],
    'ffmpeg_movie::__construct' => ['void', 'path_to_media'=>'string', 'persistent'=>'bool'],
    'ffmpeg_movie::getArtist' => ['string'],
    'ffmpeg_movie::getAudioBitRate' => ['int'],
    'ffmpeg_movie::getAudioChannels' => ['int'],
    'ffmpeg_movie::getAudioCodec' => ['string'],
    'ffmpeg_movie::getAudioSampleRate' => ['int'],
    'ffmpeg_movie::getAuthor' => ['string'],
    'ffmpeg_movie::getBitRate' => ['int'],
    'ffmpeg_movie::getComment' => ['string'],
    'ffmpeg_movie::getCopyright' => ['string'],
    'ffmpeg_movie::getDuration' => ['int'],
    'ffmpeg_movie::getFilename' => ['string'],
    'ffmpeg_movie::getFrame' => ['ffmpeg_frame|false', 'framenumber'=>'int'],
    'ffmpeg_movie::getFrameCount' => ['int'],
    'ffmpeg_movie::getFrameHeight' => ['int'],
    'ffmpeg_movie::getFrameNumber' => ['int'],
    'ffmpeg_movie::getFrameRate' => ['int'],
    'ffmpeg_movie::getFrameWidth' => ['int'],
    'ffmpeg_movie::getGenre' => ['string'],
    'ffmpeg_movie::getNextKeyFrame' => ['ffmpeg_frame|false'],
    'ffmpeg_movie::getPixelFormat' => [''],
    'ffmpeg_movie::getTitle' => ['string'],
    'ffmpeg_movie::getTrackNumber' => ['int|string'],
    'ffmpeg_movie::getVideoBitRate' => ['int'],
    'ffmpeg_movie::getVideoCodec' => ['string'],
    'ffmpeg_movie::getYear' => ['int|string'],
    'ffmpeg_movie::hasAudio' => ['bool'],
    'ffmpeg_movie::hasVideo' => ['bool'],
    'fgetc' => ['string|false', 'stream'=>'resource'],
    'fgetcsv' => ['list<string>|array{0: null}|false', 'stream'=>'resource', 'length='=>'int', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'fgets' => ['string|false', 'stream'=>'resource', 'length='=>'int'],
    'fgetss' => ['string|false', 'fp'=>'resource', 'length='=>'int', 'allowable_tags='=>'string'],
    'file' => ['list<string>|false', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
    'file_exists' => ['bool', 'filename'=>'string'],
    'file_get_contents' => ['string|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'?resource', 'offset='=>'int', 'length='=>'int'],
    'file_put_contents' => ['int|false', 'filename'=>'string', 'data'=>'string|resource|array<string>', 'flags='=>'int', 'context='=>'resource'],
    'fileatime' => ['int|false', 'filename'=>'string'],
    'filectime' => ['int|false', 'filename'=>'string'],
    'filegroup' => ['int|false', 'filename'=>'string'],
    'fileinode' => ['int|false', 'filename'=>'string'],
    'filemtime' => ['int|false', 'filename'=>'string'],
    'fileowner' => ['int|false', 'filename'=>'string'],
    'fileperms' => ['int|false', 'filename'=>'string'],
    'filepro' => ['bool', 'directory'=>'string'],
    'filepro_fieldcount' => ['int'],
    'filepro_fieldname' => ['string', 'field_number'=>'int'],
    'filepro_fieldtype' => ['string', 'field_number'=>'int'],
    'filepro_fieldwidth' => ['int', 'field_number'=>'int'],
    'filepro_retrieve' => ['string', 'row_number'=>'int', 'field_number'=>'int'],
    'filepro_rowcount' => ['int'],
    'filesize' => ['int|false', 'filename'=>'string'],
    'filetype' => ['string|false', 'filename'=>'string'],
    'filter_has_var' => ['bool', 'input_type'=>'int', 'var_name'=>'string'],
    'filter_id' => ['int|false', 'name'=>'string'],
    'filter_input' => ['mixed|false', 'type'=>'int', 'var_name'=>'string', 'filter='=>'int', 'options='=>'array|int'],
    'filter_input_array' => ['array|false|null', 'type'=>'int', 'options='=>'int|array', 'add_empty='=>'bool'],
    'filter_list' => ['array'],
    'filter_var' => ['mixed|false', 'value'=>'mixed', 'filter='=>'int', 'options='=>'array|int'],
    'filter_var_array' => ['array|false|null', 'array'=>'array', 'options='=>'array|int', 'add_empty='=>'bool'],
    'finfo::__construct' => ['void', 'options='=>'int', 'magic_file='=>'string'],
    'finfo::buffer' => ['string|false', 'string'=>'string', 'options='=>'int', 'context='=>'resource'],
    'finfo::file' => ['string|false', 'file_name'=>'string', 'options='=>'int', 'context='=>'resource'],
    'finfo::set_flags' => ['bool', 'options'=>'int'],
    'finfo_buffer' => ['string|false', 'finfo'=>'resource', 'string'=>'string', 'flags='=>'int', 'context='=>'resource'],
    'finfo_close' => ['bool', 'finfo'=>'resource'],
    'finfo_file' => ['string|false', 'finfo'=>'resource', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
    'finfo_open' => ['resource|false', 'flags='=>'int', 'magic_database='=>'string'],
    'finfo_set_flags' => ['bool', 'finfo'=>'resource', 'flags'=>'int'],
    'floatval' => ['float', 'value'=>'mixed'],
    'flock' => ['bool', 'stream'=>'resource', 'operation'=>'int', '&w_would_block='=>'int'],
    'floor' => ['float', 'num'=>'float'],
    'flush' => ['void'],
    'fmod' => ['float', 'num1'=>'float', 'num2'=>'float'],
    'fnmatch' => ['bool', 'pattern'=>'string', 'filename'=>'string', 'flags='=>'int'],
    'fopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'bool', 'context='=>'resource|null'],
    'forward_static_call' => ['mixed|false', 'callback'=>'callable', '...args='=>'mixed'],
    'forward_static_call_array' => ['mixed|false', 'callback'=>'callable', 'args'=>'list<mixed>'],
    'fpassthru' => ['int', 'stream'=>'resource'],
    'fprintf' => ['int', 'stream'=>'resource', 'format'=>'string', '...values='=>'string|int|float'],
    'fputcsv' => ['int|false', 'stream'=>'resource', 'fields'=>'array<array-key, null|scalar|Stringable>', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'fputs' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
    'fread' => ['string|false', 'stream'=>'resource', 'length'=>'int'],
    'frenchtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
    'fribidi_log2vis' => ['string', 'string'=>'string', 'direction'=>'string', 'charset'=>'int'],
    'fscanf' => ['list<mixed>', 'stream'=>'resource', 'format'=>'string'],
    'fscanf\'1' => ['int', 'stream'=>'resource', 'format'=>'string', '&...w_vars='=>'string|int|float'],
    'fseek' => ['int', 'stream'=>'resource', 'offset'=>'int', 'whence='=>'int'],
    'fsockopen' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'float'],
    'fstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'stream'=>'resource'],
    'ftell' => ['int|false', 'stream'=>'resource'],
    'ftok' => ['int', 'filename'=>'string', 'project_id'=>'string'],
    'ftp_alloc' => ['bool', 'ftp'=>'resource', 'size'=>'int', '&w_response='=>'string'],
    'ftp_cdup' => ['bool', 'ftp'=>'resource'],
    'ftp_chdir' => ['bool', 'ftp'=>'resource', 'directory'=>'string'],
    'ftp_chmod' => ['int|false', 'ftp'=>'resource', 'permissions'=>'int', 'filename'=>'string'],
    'ftp_close' => ['bool', 'ftp'=>'resource'],
    'ftp_connect' => ['resource|false', 'hostname'=>'string', 'port='=>'int', 'timeout='=>'int'],
    'ftp_delete' => ['bool', 'ftp'=>'resource', 'filename'=>'string'],
    'ftp_exec' => ['bool', 'ftp'=>'resource', 'command'=>'string'],
    'ftp_fget' => ['bool', 'ftp'=>'resource', 'stream'=>'resource', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
    'ftp_fput' => ['bool', 'ftp'=>'resource', 'remote_filename'=>'string', 'stream'=>'resource', 'mode='=>'int', 'offset='=>'int'],
    'ftp_get' => ['bool', 'ftp'=>'resource', 'local_filename'=>'string', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
    'ftp_get_option' => ['int|false', 'ftp'=>'resource', 'option'=>'int'],
    'ftp_login' => ['bool', 'ftp'=>'resource', 'username'=>'string', 'password'=>'string'],
    'ftp_mdtm' => ['int', 'ftp'=>'resource', 'filename'=>'string'],
    'ftp_mkdir' => ['string|false', 'ftp'=>'resource', 'directory'=>'string'],
    'ftp_mlsd' => ['array|false', 'ftp'=>'resource', 'directory'=>'string'],
    'ftp_nb_continue' => ['int', 'ftp'=>'resource'],
    'ftp_nb_fget' => ['int', 'ftp'=>'resource', 'stream'=>'resource', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
    'ftp_nb_fput' => ['int', 'ftp'=>'resource', 'remote_filename'=>'string', 'stream'=>'resource', 'mode='=>'int', 'offset='=>'int'],
    'ftp_nb_get' => ['int', 'ftp'=>'resource', 'local_filename'=>'string', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
    'ftp_nb_put' => ['int', 'ftp'=>'resource', 'remote_filename'=>'string', 'local_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
    'ftp_nlist' => ['array|false', 'ftp'=>'resource', 'directory'=>'string'],
    'ftp_pasv' => ['bool', 'ftp'=>'resource', 'enable'=>'bool'],
    'ftp_put' => ['bool', 'ftp'=>'resource', 'remote_filename'=>'string', 'local_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
    'ftp_pwd' => ['string|false', 'ftp'=>'resource'],
    'ftp_quit' => ['bool', 'ftp'=>'resource'],
    'ftp_raw' => ['?array', 'ftp'=>'resource', 'command'=>'string'],
    'ftp_rawlist' => ['array|false', 'ftp'=>'resource', 'directory'=>'string', 'recursive='=>'bool'],
    'ftp_rename' => ['bool', 'ftp'=>'resource', 'from'=>'string', 'to'=>'string'],
    'ftp_rmdir' => ['bool', 'ftp'=>'resource', 'directory'=>'string'],
    'ftp_set_option' => ['bool', 'ftp'=>'resource', 'option'=>'int', 'value'=>'mixed'],
    'ftp_site' => ['bool', 'ftp'=>'resource', 'command'=>'string'],
    'ftp_size' => ['int', 'ftp'=>'resource', 'filename'=>'string'],
    'ftp_ssl_connect' => ['resource|false', 'hostname'=>'string', 'port='=>'int', 'timeout='=>'int'],
    'ftp_systype' => ['string|false', 'ftp'=>'resource'],
    'ftruncate' => ['bool', 'stream'=>'resource', 'size'=>'int'],
    'func_get_arg' => ['mixed|false', 'position'=>'int'],
    'func_get_args' => ['list<mixed>'],
    'func_num_args' => ['int'],
    'function_exists' => ['bool', 'function'=>'string'],
    'fwrite' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
    'gc_collect_cycles' => ['int'],
    'gc_disable' => ['void'],
    'gc_enable' => ['void'],
    'gc_enabled' => ['bool'],
    'gc_mem_caches' => ['int'],
    'gd_info' => ['array'],
    'gearman_bugreport' => [''],
    'gearman_client_add_options' => ['', 'client_object'=>'', 'option'=>''],
    'gearman_client_add_server' => ['', 'client_object'=>'', 'host'=>'', 'port'=>''],
    'gearman_client_add_servers' => ['', 'client_object'=>'', 'servers'=>''],
    'gearman_client_add_task' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
    'gearman_client_add_task_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
    'gearman_client_add_task_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
    'gearman_client_add_task_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
    'gearman_client_add_task_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
    'gearman_client_add_task_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
    'gearman_client_add_task_status' => ['', 'client_object'=>'', 'job_handle'=>'', 'context'=>''],
    'gearman_client_clear_fn' => ['', 'client_object'=>''],
    'gearman_client_clone' => ['', 'client_object'=>''],
    'gearman_client_context' => ['', 'client_object'=>''],
    'gearman_client_create' => ['', 'client_object'=>''],
    'gearman_client_do' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
    'gearman_client_do_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
    'gearman_client_do_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
    'gearman_client_do_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
    'gearman_client_do_job_handle' => ['', 'client_object'=>''],
    'gearman_client_do_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
    'gearman_client_do_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
    'gearman_client_do_normal' => ['', 'client_object'=>'', 'function_name'=>'string', 'workload'=>'string', 'unique'=>'string'],
    'gearman_client_do_status' => ['', 'client_object'=>''],
    'gearman_client_echo' => ['', 'client_object'=>'', 'workload'=>''],
    'gearman_client_errno' => ['', 'client_object'=>''],
    'gearman_client_error' => ['', 'client_object'=>''],
    'gearman_client_job_status' => ['', 'client_object'=>'', 'job_handle'=>''],
    'gearman_client_options' => ['', 'client_object'=>''],
    'gearman_client_remove_options' => ['', 'client_object'=>'', 'option'=>''],
    'gearman_client_return_code' => ['', 'client_object'=>''],
    'gearman_client_run_tasks' => ['', 'data'=>''],
    'gearman_client_set_complete_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_set_context' => ['', 'client_object'=>'', 'context'=>''],
    'gearman_client_set_created_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_set_data_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_set_exception_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_set_fail_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_set_options' => ['', 'client_object'=>'', 'option'=>''],
    'gearman_client_set_status_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_set_timeout' => ['', 'client_object'=>'', 'timeout'=>''],
    'gearman_client_set_warning_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_set_workload_fn' => ['', 'client_object'=>'', 'callback'=>''],
    'gearman_client_timeout' => ['', 'client_object'=>''],
    'gearman_client_wait' => ['', 'client_object'=>''],
    'gearman_job_function_name' => ['', 'job_object'=>''],
    'gearman_job_handle' => ['string'],
    'gearman_job_return_code' => ['', 'job_object'=>''],
    'gearman_job_send_complete' => ['', 'job_object'=>'', 'result'=>''],
    'gearman_job_send_data' => ['', 'job_object'=>'', 'data'=>''],
    'gearman_job_send_exception' => ['', 'job_object'=>'', 'exception'=>''],
    'gearman_job_send_fail' => ['', 'job_object'=>''],
    'gearman_job_send_status' => ['', 'job_object'=>'', 'numerator'=>'', 'denominator'=>''],
    'gearman_job_send_warning' => ['', 'job_object'=>'', 'warning'=>''],
    'gearman_job_status' => ['array', 'job_handle'=>'string'],
    'gearman_job_unique' => ['', 'job_object'=>''],
    'gearman_job_workload' => ['', 'job_object'=>''],
    'gearman_job_workload_size' => ['', 'job_object'=>''],
    'gearman_task_data' => ['', 'task_object'=>''],
    'gearman_task_data_size' => ['', 'task_object'=>''],
    'gearman_task_denominator' => ['', 'task_object'=>''],
    'gearman_task_function_name' => ['', 'task_object'=>''],
    'gearman_task_is_known' => ['', 'task_object'=>''],
    'gearman_task_is_running' => ['', 'task_object'=>''],
    'gearman_task_job_handle' => ['', 'task_object'=>''],
    'gearman_task_numerator' => ['', 'task_object'=>''],
    'gearman_task_recv_data' => ['', 'task_object'=>'', 'data_len'=>''],
    'gearman_task_return_code' => ['', 'task_object'=>''],
    'gearman_task_send_workload' => ['', 'task_object'=>'', 'data'=>''],
    'gearman_task_unique' => ['', 'task_object'=>''],
    'gearman_verbose_name' => ['', 'verbose'=>''],
    'gearman_version' => [''],
    'gearman_worker_add_function' => ['', 'worker_object'=>'', 'function_name'=>'', 'function'=>'', 'data'=>'', 'timeout'=>''],
    'gearman_worker_add_options' => ['', 'worker_object'=>'', 'option'=>''],
    'gearman_worker_add_server' => ['', 'worker_object'=>'', 'host'=>'', 'port'=>''],
    'gearman_worker_add_servers' => ['', 'worker_object'=>'', 'servers'=>''],
    'gearman_worker_clone' => ['', 'worker_object'=>''],
    'gearman_worker_create' => [''],
    'gearman_worker_echo' => ['', 'worker_object'=>'', 'workload'=>''],
    'gearman_worker_errno' => ['', 'worker_object'=>''],
    'gearman_worker_error' => ['', 'worker_object'=>''],
    'gearman_worker_grab_job' => ['', 'worker_object'=>''],
    'gearman_worker_options' => ['', 'worker_object'=>''],
    'gearman_worker_register' => ['', 'worker_object'=>'', 'function_name'=>'', 'timeout'=>''],
    'gearman_worker_remove_options' => ['', 'worker_object'=>'', 'option'=>''],
    'gearman_worker_return_code' => ['', 'worker_object'=>''],
    'gearman_worker_set_options' => ['', 'worker_object'=>'', 'option'=>''],
    'gearman_worker_set_timeout' => ['', 'worker_object'=>'', 'timeout'=>''],
    'gearman_worker_timeout' => ['', 'worker_object'=>''],
    'gearman_worker_unregister' => ['', 'worker_object'=>'', 'function_name'=>''],
    'gearman_worker_unregister_all' => ['', 'worker_object'=>''],
    'gearman_worker_wait' => ['', 'worker_object'=>''],
    'gearman_worker_work' => ['', 'worker_object'=>''],
    'geoip_asnum_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_continent_code_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_country_code3_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_country_code_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_country_name_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_database_info' => ['string', 'database='=>'int'],
    'geoip_db_avail' => ['bool', 'database'=>'int'],
    'geoip_db_filename' => ['string', 'database'=>'int'],
    'geoip_db_get_all_info' => ['array'],
    'geoip_domain_by_name' => ['string', 'hostname'=>'string'],
    'geoip_id_by_name' => ['int', 'hostname'=>'string'],
    'geoip_isp_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_netspeedcell_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_org_by_name' => ['string|false', 'hostname'=>'string'],
    'geoip_record_by_name' => ['array|false', 'hostname'=>'string'],
    'geoip_region_by_name' => ['array|false', 'hostname'=>'string'],
    'geoip_region_name_by_code' => ['string|false', 'country_code'=>'string', 'region_code'=>'string'],
    'geoip_setup_custom_directory' => ['void', 'path'=>'string'],
    'geoip_time_zone_by_country_and_region' => ['string|false', 'country_code'=>'string', 'region_code='=>'string'],
    'get_browser' => ['array|object|false', 'user_agent='=>'?string', 'return_array='=>'bool'],
    'get_call_stack' => [''],
    'get_called_class' => ['class-string'],
    'get_cfg_var' => ['string|false', 'option'=>'string'],
    'get_class' => ['class-string', 'object='=>'object'],
    'get_class_methods' => ['list<string>|null', 'object_or_class'=>'mixed'],
    'get_class_vars' => ['array<string,mixed>', 'class'=>'string'],
    'get_current_user' => ['string'],
    'get_declared_classes' => ['list<class-string>'],
    'get_declared_interfaces' => ['list<class-string>'],
    'get_declared_traits' => ['list<class-string>'],
    'get_defined_constants' => ['array<string,int|string|float|bool|null|array|resource>', 'categorize='=>'bool'],
    'get_defined_functions' => ['array{internal: list<callable-string>, user: list<callable-string>}', 'exclude_disabled='=>'bool'],
    'get_defined_vars' => ['array'],
    'get_extension_funcs' => ['list<callable-string>|false', 'extension'=>'string'],
    'get_headers' => ['array|false', 'url'=>'string', 'associative='=>'int'],
    'get_html_translation_table' => ['array', 'table='=>'int', 'flags='=>'int', 'encoding='=>'string'],
    'get_include_path' => ['string'],
    'get_included_files' => ['list<string>'],
    'get_loaded_extensions' => ['list<string>', 'zend_extensions='=>'bool'],
    'get_magic_quotes_gpc' => ['int|false'],
    'get_magic_quotes_runtime' => ['int|false'],
    'get_meta_tags' => ['array', 'filename'=>'string', 'use_include_path='=>'bool'],
    'get_object_vars' => ['array<string,mixed>', 'object'=>'object'],
    'get_parent_class' => ['class-string|false', 'object_or_class='=>'mixed'],
    'get_required_files' => ['list<string>'],
    'get_resource_type' => ['string', 'resource'=>'resource'],
    'get_resources' => ['array<int,resource>', 'type='=>'string'],
    'getallheaders' => ['array|false'],
    'getcwd' => ['string|false'],
    'getdate' => ['array{seconds: int<0, 59>, minutes: int<0, 59>, hours: int<0, 23>, mday: int<1, 31>, wday: int<0, 6>, mon: int<1, 12>, year: int, yday: int<0, 365>, weekday: "Monday"|"Tuesday"|"Wednesday"|"Thursday"|"Friday"|"Saturday"|"Sunday", month: "January"|"February"|"March"|"April"|"May"|"June"|"July"|"August"|"September"|"October"|"November"|"December", 0: int}', 'timestamp='=>'int'],
    'getenv' => ['string|false', 'name'=>'string', 'local_only='=>'bool'],
    'gethostbyaddr' => ['string|false', 'ip'=>'string'],
    'gethostbyname' => ['string', 'hostname'=>'string'],
    'gethostbynamel' => ['list<string>|false', 'hostname'=>'string'],
    'gethostname' => ['string|false'],
    'getimagesize' => ['array|false', 'filename'=>'string', '&w_image_info='=>'array'],
    'getimagesizefromstring' => ['array|false', 'string'=>'string', '&w_image_info='=>'array'],
    'getlastmod' => ['int|false'],
    'getmxrr' => ['bool', 'hostname'=>'string', '&w_hosts'=>'array', '&w_weights='=>'array'],
    'getmygid' => ['int|false'],
    'getmyinode' => ['int|false'],
    'getmypid' => ['int|false'],
    'getmyuid' => ['int|false'],
    'getopt' => ['array<string,string|false|list<string|false>>|false', 'short_options'=>'string', 'long_options='=>'array'],
    'getprotobyname' => ['int|false', 'protocol'=>'string'],
    'getprotobynumber' => ['string', 'protocol'=>'int'],
    'getrandmax' => ['int'],
    'getrusage' => ['array', 'mode='=>'int'],
    'getservbyname' => ['int|false', 'service'=>'string', 'protocol'=>'string'],
    'getservbyport' => ['string|false', 'port'=>'int', 'protocol'=>'string'],
    'gettext' => ['string', 'message'=>'string'],
    'gettimeofday' => ['array<string, int>'],
    'gettimeofday\'1' => ['float', 'as_float='=>'true'],
    'gettype' => ['string', 'value'=>'mixed'],
    'glob' => ['list<string>|false', 'pattern'=>'string', 'flags='=>'int'],
    'gmdate' => ['string', 'format'=>'string', 'timestamp='=>'int'],
    'gmmktime' => ['int|false', 'hour='=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'],
    'gmp_abs' => ['GMP', 'num'=>'GMP|string|int'],
    'gmp_add' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_and' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_clrbit' => ['void', 'num'=>'GMP|string|int', 'index'=>'int'],
    'gmp_cmp' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_com' => ['GMP', 'num'=>'GMP|string|int'],
    'gmp_div' => ['GMP', 'num1'=>'GMP|resource|string', 'num2'=>'GMP|resource|string', 'rounding_mode='=>'int'],
    'gmp_div_q' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int', 'rounding_mode='=>'int'],
    'gmp_div_qr' => ['array{0: GMP, 1: GMP}', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int', 'rounding_mode='=>'int'],
    'gmp_div_r' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int', 'rounding_mode='=>'int'],
    'gmp_divexact' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_export' => ['string|false', 'num'=>'GMP|string|int', 'word_size='=>'int', 'flags='=>'int'],
    'gmp_fact' => ['GMP', 'num'=>'int'],
    'gmp_gcd' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_gcdext' => ['array<string,GMP>', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_hamdist' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_import' => ['GMP|false', 'data'=>'string', 'word_size='=>'int', 'flags='=>'int'],
    'gmp_init' => ['GMP', 'num'=>'int|string', 'base='=>'int'],
    'gmp_intval' => ['int', 'num'=>'GMP|string|int'],
    'gmp_invert' => ['GMP|false', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_jacobi' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_legendre' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_mod' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_mul' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_neg' => ['GMP', 'num'=>'GMP|string|int'],
    'gmp_nextprime' => ['GMP', 'num'=>'GMP|string|int'],
    'gmp_or' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_perfect_square' => ['bool', 'num'=>'GMP|string|int'],
    'gmp_popcount' => ['int', 'num'=>'GMP|string|int'],
    'gmp_pow' => ['GMP', 'num'=>'GMP|string|int', 'exponent'=>'int'],
    'gmp_powm' => ['GMP', 'num'=>'GMP|string|int', 'exponent'=>'GMP|string|int', 'modulus'=>'GMP|string|int'],
    'gmp_prob_prime' => ['int', 'num'=>'GMP|string|int', 'repetitions='=>'int'],
    'gmp_random' => ['GMP', 'limiter='=>'int'],
    'gmp_random_bits' => ['GMP', 'bits'=>'int'],
    'gmp_random_range' => ['GMP', 'min'=>'GMP|string|int', 'max'=>'GMP|string|int'],
    'gmp_random_seed' => ['void', 'seed'=>'GMP|string|int'],
    'gmp_root' => ['GMP', 'num'=>'GMP|string|int', 'nth'=>'int'],
    'gmp_rootrem' => ['array{0: GMP, 1: GMP}', 'num'=>'GMP|string|int', 'nth'=>'int'],
    'gmp_scan0' => ['int', 'num1'=>'GMP|string|int', 'start'=>'int'],
    'gmp_scan1' => ['int', 'num1'=>'GMP|string|int', 'start'=>'int'],
    'gmp_setbit' => ['void', 'num'=>'GMP|string|int', 'index'=>'int', 'value='=>'bool'],
    'gmp_sign' => ['int', 'num'=>'GMP|string|int'],
    'gmp_sqrt' => ['GMP', 'num'=>'GMP|string|int'],
    'gmp_sqrtrem' => ['array{0: GMP, 1: GMP}', 'num'=>'GMP|string|int'],
    'gmp_strval' => ['numeric-string', 'num'=>'GMP|string|int', 'base='=>'int'],
    'gmp_sub' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_testbit' => ['bool', 'num'=>'GMP|string|int', 'index'=>'int'],
    'gmp_xor' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmstrftime' => ['string|false', 'format'=>'string', 'timestamp='=>'int'],
    'gnupg::adddecryptkey' => ['bool', 'fingerprint'=>'string', 'passphrase'=>'string'],
    'gnupg::addencryptkey' => ['bool', 'fingerprint'=>'string'],
    'gnupg::addsignkey' => ['bool', 'fingerprint'=>'string', 'passphrase='=>'string'],
    'gnupg::cleardecryptkeys' => ['bool'],
    'gnupg::clearencryptkeys' => ['bool'],
    'gnupg::clearsignkeys' => ['bool'],
    'gnupg::decrypt' => ['string|false', 'text'=>'string'],
    'gnupg::decryptverify' => ['array|false', 'text'=>'string', '&plaintext'=>'string'],
    'gnupg::encrypt' => ['string|false', 'plaintext'=>'string'],
    'gnupg::encryptsign' => ['string|false', 'plaintext'=>'string'],
    'gnupg::export' => ['string|false', 'fingerprint'=>'string'],
    'gnupg::geterror' => ['string|false'],
    'gnupg::getprotocol' => ['int'],
    'gnupg::import' => ['array|false', 'keydata'=>'string'],
    'gnupg::keyinfo' => ['array', 'pattern'=>'string'],
    'gnupg::setarmor' => ['bool', 'armor'=>'int'],
    'gnupg::seterrormode' => ['void', 'errormode'=>'int'],
    'gnupg::setsignmode' => ['bool', 'signmode'=>'int'],
    'gnupg::sign' => ['string|false', 'plaintext'=>'string'],
    'gnupg::verify' => ['array|false', 'signed_text'=>'string', 'signature'=>'string', '&plaintext='=>'string'],
    'gnupg_adddecryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase'=>'string'],
    'gnupg_addencryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string'],
    'gnupg_addsignkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase='=>'string'],
    'gnupg_cleardecryptkeys' => ['bool', 'identifier'=>'resource'],
    'gnupg_clearencryptkeys' => ['bool', 'identifier'=>'resource'],
    'gnupg_clearsignkeys' => ['bool', 'identifier'=>'resource'],
    'gnupg_decrypt' => ['string', 'identifier'=>'resource', 'text'=>'string'],
    'gnupg_decryptverify' => ['array', 'identifier'=>'resource', 'text'=>'string', 'plaintext'=>'string'],
    'gnupg_encrypt' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'],
    'gnupg_encryptsign' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'],
    'gnupg_export' => ['string', 'identifier'=>'resource', 'fingerprint'=>'string'],
    'gnupg_geterror' => ['string', 'identifier'=>'resource'],
    'gnupg_getprotocol' => ['int', 'identifier'=>'resource'],
    'gnupg_import' => ['array', 'identifier'=>'resource', 'keydata'=>'string'],
    'gnupg_init' => ['resource'],
    'gnupg_keyinfo' => ['array', 'identifier'=>'resource', 'pattern'=>'string'],
    'gnupg_setarmor' => ['bool', 'identifier'=>'resource', 'armor'=>'int'],
    'gnupg_seterrormode' => ['void', 'identifier'=>'resource', 'errormode'=>'int'],
    'gnupg_setsignmode' => ['bool', 'identifier'=>'resource', 'signmode'=>'int'],
    'gnupg_sign' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'],
    'gnupg_verify' => ['array', 'identifier'=>'resource', 'signed_text'=>'string', 'signature'=>'string', 'plaintext='=>'string'],
    'gopher_parsedir' => ['array', 'dirent'=>'string'],
    'grapheme_extract' => ['string|false', 'haystack'=>'string', 'size'=>'int', 'type='=>'int', 'offset='=>'int', '&w_next='=>'int'],
    'grapheme_stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    'grapheme_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'beforeNeedle='=>'bool'],
    'grapheme_strlen' => ['0|positive-int|false|null', 'string'=>'string'],
    'grapheme_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    'grapheme_strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    'grapheme_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    'grapheme_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'beforeNeedle='=>'bool'],
    'grapheme_substr' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'?int'],
    'gregoriantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
    'gridObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'gupnp_context_get_host_ip' => ['string', 'context'=>'resource'],
    'gupnp_context_get_port' => ['int', 'context'=>'resource'],
    'gupnp_context_get_subscription_timeout' => ['int', 'context'=>'resource'],
    'gupnp_context_host_path' => ['bool', 'context'=>'resource', 'local_path'=>'string', 'server_path'=>'string'],
    'gupnp_context_new' => ['resource', 'host_ip='=>'string', 'port='=>'int'],
    'gupnp_context_set_subscription_timeout' => ['void', 'context'=>'resource', 'timeout'=>'int'],
    'gupnp_context_timeout_add' => ['bool', 'context'=>'resource', 'timeout'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
    'gupnp_context_unhost_path' => ['bool', 'context'=>'resource', 'server_path'=>'string'],
    'gupnp_control_point_browse_start' => ['bool', 'cpoint'=>'resource'],
    'gupnp_control_point_browse_stop' => ['bool', 'cpoint'=>'resource'],
    'gupnp_control_point_callback_set' => ['bool', 'cpoint'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
    'gupnp_control_point_new' => ['resource', 'context'=>'resource', 'target'=>'string'],
    'gupnp_device_action_callback_set' => ['bool', 'root_device'=>'resource', 'signal'=>'int', 'action_name'=>'string', 'callback'=>'mixed', 'arg='=>'mixed'],
    'gupnp_device_info_get' => ['array', 'root_device'=>'resource'],
    'gupnp_device_info_get_service' => ['resource', 'root_device'=>'resource', 'type'=>'string'],
    'gupnp_root_device_get_available' => ['bool', 'root_device'=>'resource'],
    'gupnp_root_device_get_relative_location' => ['string', 'root_device'=>'resource'],
    'gupnp_root_device_new' => ['resource', 'context'=>'resource', 'location'=>'string', 'description_dir'=>'string'],
    'gupnp_root_device_set_available' => ['bool', 'root_device'=>'resource', 'available'=>'bool'],
    'gupnp_root_device_start' => ['bool', 'root_device'=>'resource'],
    'gupnp_root_device_stop' => ['bool', 'root_device'=>'resource'],
    'gupnp_service_action_get' => ['mixed', 'action'=>'resource', 'name'=>'string', 'type'=>'int'],
    'gupnp_service_action_return' => ['bool', 'action'=>'resource'],
    'gupnp_service_action_return_error' => ['bool', 'action'=>'resource', 'error_code'=>'int', 'error_description='=>'string'],
    'gupnp_service_action_set' => ['bool', 'action'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'],
    'gupnp_service_freeze_notify' => ['bool', 'service'=>'resource'],
    'gupnp_service_info_get' => ['array', 'proxy'=>'resource'],
    'gupnp_service_info_get_introspection' => ['mixed', 'proxy'=>'resource', 'callback='=>'mixed', 'arg='=>'mixed'],
    'gupnp_service_introspection_get_state_variable' => ['array', 'introspection'=>'resource', 'variable_name'=>'string'],
    'gupnp_service_notify' => ['bool', 'service'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'],
    'gupnp_service_proxy_action_get' => ['mixed', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'type'=>'int'],
    'gupnp_service_proxy_action_set' => ['bool', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'value'=>'mixed', 'type'=>'int'],
    'gupnp_service_proxy_add_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string', 'type'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
    'gupnp_service_proxy_callback_set' => ['bool', 'proxy'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
    'gupnp_service_proxy_get_subscribed' => ['bool', 'proxy'=>'resource'],
    'gupnp_service_proxy_remove_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string'],
    'gupnp_service_proxy_send_action' => ['array', 'proxy'=>'resource', 'action'=>'string', 'in_params'=>'array', 'out_params'=>'array'],
    'gupnp_service_proxy_set_subscribed' => ['bool', 'proxy'=>'resource', 'subscribed'=>'bool'],
    'gupnp_service_thaw_notify' => ['bool', 'service'=>'resource'],
    'gzclose' => ['bool', 'stream'=>'resource'],
    'gzcompress' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'],
    'gzdecode' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
    'gzdeflate' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'],
    'gzencode' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'],
    'gzeof' => ['bool', 'stream'=>'resource'],
    'gzfile' => ['list<string>', 'filename'=>'string', 'use_include_path='=>'int'],
    'gzgetc' => ['string|false', 'stream'=>'resource'],
    'gzgets' => ['string|false', 'stream'=>'resource', 'length='=>'int'],
    'gzgetss' => ['string|false', 'zp'=>'resource', 'length'=>'int', 'allowable_tags='=>'string'],
    'gzinflate' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
    'gzopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'int'],
    'gzpassthru' => ['int', 'stream'=>'resource'],
    'gzputs' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
    'gzread' => ['string|0', 'stream'=>'resource', 'length'=>'int'],
    'gzrewind' => ['bool', 'stream'=>'resource'],
    'gzseek' => ['int', 'stream'=>'resource', 'offset'=>'int', 'whence='=>'int'],
    'gztell' => ['int|false', 'stream'=>'resource'],
    'gzuncompress' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
    'gzwrite' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
    'hash' => ['string|false', 'algo'=>'string', 'data'=>'string', 'binary='=>'bool'],
    'hashTableObj::clear' => ['void'],
    'hashTableObj::get' => ['string', 'key'=>'string'],
    'hashTableObj::nextkey' => ['string', 'previousKey'=>'string'],
    'hashTableObj::remove' => ['int', 'key'=>'string'],
    'hashTableObj::set' => ['int', 'key'=>'string', 'value'=>'string'],
    'hash_algos' => ['list<string>'],
    'hash_copy' => ['resource', 'context'=>'resource'],
    'hash_equals' => ['bool', 'known_string'=>'string', 'user_string'=>'string'],
    'hash_file' => ['non-empty-string|false', 'algo'=>'string', 'filename'=>'string', 'binary='=>'bool'],
    'hash_final' => ['non-empty-string', 'context'=>'resource', 'raw_output='=>'bool'],
    'hash_hmac' => ['non-empty-string|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'binary='=>'bool'],
    'hash_hmac_file' => ['non-empty-string|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'binary='=>'bool'],
    'hash_init' => ['resource', 'algo'=>'string', 'options='=>'int', 'key='=>'string'],
    'hash_pbkdf2' => ['non-empty-string', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'binary='=>'bool'],
    'hash_update' => ['bool', 'context'=>'resource', 'data'=>'string'],
    'hash_update_file' => ['bool', 'hcontext'=>'resource', 'filename'=>'string', 'scontext='=>'resource'],
    'hash_update_stream' => ['int', 'context'=>'resource', 'handle'=>'resource', 'length='=>'int'],
    'header' => ['void', 'header'=>'string', 'replace='=>'bool', 'response_code='=>'int'],
    'header_register_callback' => ['bool', 'callback'=>'callable():void'],
    'header_remove' => ['void', 'name='=>'string'],
    'headers_list' => ['list<string>'],
    'headers_sent' => ['bool', '&w_filename='=>'string', '&w_line='=>'int'],
    'hebrev' => ['string', 'string'=>'string', 'max_chars_per_line='=>'int'],
    'hebrevc' => ['string', 'string'=>'string', 'max_chars_per_line='=>'int'],
    'hex2bin' => ['string|false', 'string'=>'string'],
    'hexdec' => ['int|float', 'hex_string'=>'string'],
    'highlight_file' => ['string|bool', 'filename'=>'string', 'return='=>'bool'],
    'highlight_string' => ['string|bool', 'string'=>'string', 'return='=>'bool'],
    'html_entity_decode' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'string'],
    'htmlentities' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'string', 'double_encode='=>'bool'],
    'htmlspecialchars' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'string|null', 'double_encode='=>'bool'],
    'htmlspecialchars_decode' => ['string', 'string'=>'string', 'flags='=>'int'],
    'http\Client::__construct' => ['void', 'driver='=>'string', 'persistent_handle_id='=>'string'],
    'http\Client::addCookies' => ['http\Client', 'cookies='=>'?array'],
    'http\Client::addSslOptions' => ['http\Client', 'ssl_options='=>'?array'],
    'http\Client::attach' => ['void', 'observer'=>'SplObserver'],
    'http\Client::configure' => ['http\Client', 'settings'=>'array'],
    'http\Client::count' => ['int'],
    'http\Client::dequeue' => ['http\Client', 'request'=>'http\Client\Request'],
    'http\Client::detach' => ['void', 'observer'=>'SplObserver'],
    'http\Client::enableEvents' => ['http\Client', 'enable='=>'mixed'],
    'http\Client::enablePipelining' => ['http\Client', 'enable='=>'mixed'],
    'http\Client::enqueue' => ['http\Client', 'request'=>'http\Client\Request', 'callable='=>'mixed'],
    'http\Client::getAvailableConfiguration' => ['array'],
    'http\Client::getAvailableDrivers' => ['array'],
    'http\Client::getAvailableOptions' => ['array'],
    'http\Client::getCookies' => ['array'],
    'http\Client::getHistory' => ['http\Message'],
    'http\Client::getObservers' => ['SplObjectStorage'],
    'http\Client::getOptions' => ['array'],
    'http\Client::getProgressInfo' => ['null|object', 'request'=>'http\Client\Request'],
    'http\Client::getResponse' => ['http\Client\Response|null', 'request='=>'?http\Client\Request'],
    'http\Client::getSslOptions' => ['array'],
    'http\Client::getTransferInfo' => ['object', 'request'=>'http\Client\Request'],
    'http\Client::notify' => ['void', 'request='=>'?http\Client\Request'],
    'http\Client::once' => ['bool'],
    'http\Client::requeue' => ['http\Client', 'request'=>'http\Client\Request', 'callable='=>'mixed'],
    'http\Client::reset' => ['http\Client'],
    'http\Client::send' => ['http\Client'],
    'http\Client::setCookies' => ['http\Client', 'cookies='=>'?array'],
    'http\Client::setDebug' => ['http\Client', 'callback'=>'callable'],
    'http\Client::setOptions' => ['http\Client', 'options='=>'?array'],
    'http\Client::setSslOptions' => ['http\Client', 'ssl_option='=>'?array'],
    'http\Client::wait' => ['bool', 'timeout='=>'mixed'],
    'http\Client\Curl\User::init' => ['', 'run'=>'callable'],
    'http\Client\Curl\User::once' => [''],
    'http\Client\Curl\User::send' => [''],
    'http\Client\Curl\User::socket' => ['', 'socket'=>'resource', 'action'=>'int'],
    'http\Client\Curl\User::timer' => ['', 'timeout_ms'=>'int'],
    'http\Client\Curl\User::wait' => ['', 'timeout_ms='=>'mixed'],
    'http\Client\Request::__construct' => ['void', 'method='=>'mixed', 'url='=>'mixed', 'headers='=>'?array', 'body='=>'?http\Message\Body'],
    'http\Client\Request::__toString' => ['string'],
    'http\Client\Request::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Client\Request::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
    'http\Client\Request::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
    'http\Client\Request::addQuery' => ['http\Client\Request', 'query_data'=>'mixed'],
    'http\Client\Request::addSslOptions' => ['http\Client\Request', 'ssl_options='=>'?array'],
    'http\Client\Request::count' => ['int'],
    'http\Client\Request::current' => ['mixed'],
    'http\Client\Request::detach' => ['http\Message'],
    'http\Client\Request::getBody' => ['http\Message\Body'],
    'http\Client\Request::getContentType' => ['null|string'],
    'http\Client\Request::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
    'http\Client\Request::getHeaders' => ['array'],
    'http\Client\Request::getHttpVersion' => ['string'],
    'http\Client\Request::getInfo' => ['null|string'],
    'http\Client\Request::getOptions' => ['array'],
    'http\Client\Request::getParentMessage' => ['http\Message'],
    'http\Client\Request::getQuery' => ['null|string'],
    'http\Client\Request::getRequestMethod' => ['false|string'],
    'http\Client\Request::getRequestUrl' => ['false|string'],
    'http\Client\Request::getResponseCode' => ['false|int'],
    'http\Client\Request::getResponseStatus' => ['false|string'],
    'http\Client\Request::getSslOptions' => ['array'],
    'http\Client\Request::getType' => ['int'],
    'http\Client\Request::isMultipart' => ['bool', '&boundary='=>'mixed'],
    'http\Client\Request::key' => ['int|string'],
    'http\Client\Request::next' => ['void'],
    'http\Client\Request::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
    'http\Client\Request::reverse' => ['http\Message'],
    'http\Client\Request::rewind' => ['void'],
    'http\Client\Request::serialize' => ['string'],
    'http\Client\Request::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Client\Request::setContentType' => ['http\Client\Request', 'content_type'=>'string'],
    'http\Client\Request::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
    'http\Client\Request::setHeaders' => ['http\Message', 'headers'=>'array'],
    'http\Client\Request::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
    'http\Client\Request::setInfo' => ['http\Message', 'http_info'=>'string'],
    'http\Client\Request::setOptions' => ['http\Client\Request', 'options='=>'?array'],
    'http\Client\Request::setQuery' => ['http\Client\Request', 'query_data='=>'mixed'],
    'http\Client\Request::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
    'http\Client\Request::setRequestUrl' => ['http\Message', 'url'=>'string'],
    'http\Client\Request::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
    'http\Client\Request::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
    'http\Client\Request::setSslOptions' => ['http\Client\Request', 'ssl_options='=>'?array'],
    'http\Client\Request::setType' => ['http\Message', 'type'=>'int'],
    'http\Client\Request::splitMultipartBody' => ['http\Message'],
    'http\Client\Request::toCallback' => ['http\Message', 'callback'=>'callable'],
    'http\Client\Request::toStream' => ['http\Message', 'stream'=>'resource'],
    'http\Client\Request::toString' => ['string', 'include_parent='=>'mixed'],
    'http\Client\Request::unserialize' => ['void', 'serialized'=>'string'],
    'http\Client\Request::valid' => ['bool'],
    'http\Client\Response::__construct' => ['Iterator'],
    'http\Client\Response::__toString' => ['string'],
    'http\Client\Response::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Client\Response::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
    'http\Client\Response::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
    'http\Client\Response::count' => ['int'],
    'http\Client\Response::current' => ['mixed'],
    'http\Client\Response::detach' => ['http\Message'],
    'http\Client\Response::getBody' => ['http\Message\Body'],
    'http\Client\Response::getCookies' => ['array', 'flags='=>'mixed', 'allowed_extras='=>'mixed'],
    'http\Client\Response::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
    'http\Client\Response::getHeaders' => ['array'],
    'http\Client\Response::getHttpVersion' => ['string'],
    'http\Client\Response::getInfo' => ['null|string'],
    'http\Client\Response::getParentMessage' => ['http\Message'],
    'http\Client\Response::getRequestMethod' => ['false|string'],
    'http\Client\Response::getRequestUrl' => ['false|string'],
    'http\Client\Response::getResponseCode' => ['false|int'],
    'http\Client\Response::getResponseStatus' => ['false|string'],
    'http\Client\Response::getTransferInfo' => ['mixed|object', 'element='=>'mixed'],
    'http\Client\Response::getType' => ['int'],
    'http\Client\Response::isMultipart' => ['bool', '&boundary='=>'mixed'],
    'http\Client\Response::key' => ['int|string'],
    'http\Client\Response::next' => ['void'],
    'http\Client\Response::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
    'http\Client\Response::reverse' => ['http\Message'],
    'http\Client\Response::rewind' => ['void'],
    'http\Client\Response::serialize' => ['string'],
    'http\Client\Response::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Client\Response::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
    'http\Client\Response::setHeaders' => ['http\Message', 'headers'=>'array'],
    'http\Client\Response::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
    'http\Client\Response::setInfo' => ['http\Message', 'http_info'=>'string'],
    'http\Client\Response::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
    'http\Client\Response::setRequestUrl' => ['http\Message', 'url'=>'string'],
    'http\Client\Response::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
    'http\Client\Response::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
    'http\Client\Response::setType' => ['http\Message', 'type'=>'int'],
    'http\Client\Response::splitMultipartBody' => ['http\Message'],
    'http\Client\Response::toCallback' => ['http\Message', 'callback'=>'callable'],
    'http\Client\Response::toStream' => ['http\Message', 'stream'=>'resource'],
    'http\Client\Response::toString' => ['string', 'include_parent='=>'mixed'],
    'http\Client\Response::unserialize' => ['void', 'serialized'=>'string'],
    'http\Client\Response::valid' => ['bool'],
    'http\Cookie::__construct' => ['void', 'cookie_string='=>'mixed', 'parser_flags='=>'int', 'allowed_extras='=>'array'],
    'http\Cookie::__toString' => ['string'],
    'http\Cookie::addCookie' => ['http\Cookie', 'cookie_name'=>'string', 'cookie_value'=>'string'],
    'http\Cookie::addCookies' => ['http\Cookie', 'cookies'=>'array'],
    'http\Cookie::addExtra' => ['http\Cookie', 'extra_name'=>'string', 'extra_value'=>'string'],
    'http\Cookie::addExtras' => ['http\Cookie', 'extras'=>'array'],
    'http\Cookie::getCookie' => ['null|string', 'name'=>'string'],
    'http\Cookie::getCookies' => ['array'],
    'http\Cookie::getDomain' => ['string'],
    'http\Cookie::getExpires' => ['int'],
    'http\Cookie::getExtra' => ['string', 'name'=>'string'],
    'http\Cookie::getExtras' => ['array'],
    'http\Cookie::getFlags' => ['int'],
    'http\Cookie::getMaxAge' => ['int'],
    'http\Cookie::getPath' => ['string'],
    'http\Cookie::setCookie' => ['http\Cookie', 'cookie_name'=>'string', 'cookie_value='=>'mixed'],
    'http\Cookie::setCookies' => ['http\Cookie', 'cookies='=>'mixed'],
    'http\Cookie::setDomain' => ['http\Cookie', 'value='=>'mixed'],
    'http\Cookie::setExpires' => ['http\Cookie', 'value='=>'mixed'],
    'http\Cookie::setExtra' => ['http\Cookie', 'extra_name'=>'string', 'extra_value='=>'mixed'],
    'http\Cookie::setExtras' => ['http\Cookie', 'extras='=>'mixed'],
    'http\Cookie::setFlags' => ['http\Cookie', 'value='=>'mixed'],
    'http\Cookie::setMaxAge' => ['http\Cookie', 'value='=>'mixed'],
    'http\Cookie::setPath' => ['http\Cookie', 'value='=>'mixed'],
    'http\Cookie::toArray' => ['array'],
    'http\Cookie::toString' => ['string'],
    'http\Encoding\Stream::__construct' => ['void', 'flags='=>'mixed'],
    'http\Encoding\Stream::done' => ['bool'],
    'http\Encoding\Stream::finish' => ['string'],
    'http\Encoding\Stream::flush' => ['string'],
    'http\Encoding\Stream::update' => ['string', 'data'=>'string'],
    'http\Encoding\Stream\Debrotli::__construct' => ['void', 'flags='=>'int'],
    'http\Encoding\Stream\Debrotli::decode' => ['string', 'data'=>'string'],
    'http\Encoding\Stream\Debrotli::done' => ['bool'],
    'http\Encoding\Stream\Debrotli::finish' => ['string'],
    'http\Encoding\Stream\Debrotli::flush' => ['string'],
    'http\Encoding\Stream\Debrotli::update' => ['string', 'data'=>'string'],
    'http\Encoding\Stream\Dechunk::__construct' => ['void', 'flags='=>'mixed'],
    'http\Encoding\Stream\Dechunk::decode' => ['false|string', 'data'=>'string', '&decoded_len='=>'mixed'],
    'http\Encoding\Stream\Dechunk::done' => ['bool'],
    'http\Encoding\Stream\Dechunk::finish' => ['string'],
    'http\Encoding\Stream\Dechunk::flush' => ['string'],
    'http\Encoding\Stream\Dechunk::update' => ['string', 'data'=>'string'],
    'http\Encoding\Stream\Deflate::__construct' => ['void', 'flags='=>'mixed'],
    'http\Encoding\Stream\Deflate::done' => ['bool'],
    'http\Encoding\Stream\Deflate::encode' => ['string', 'data'=>'string', 'flags='=>'mixed'],
    'http\Encoding\Stream\Deflate::finish' => ['string'],
    'http\Encoding\Stream\Deflate::flush' => ['string'],
    'http\Encoding\Stream\Deflate::update' => ['string', 'data'=>'string'],
    'http\Encoding\Stream\Enbrotli::__construct' => ['void', 'flags='=>'int'],
    'http\Encoding\Stream\Enbrotli::done' => ['bool'],
    'http\Encoding\Stream\Enbrotli::encode' => ['string', 'data'=>'string', 'flags='=>'int'],
    'http\Encoding\Stream\Enbrotli::finish' => ['string'],
    'http\Encoding\Stream\Enbrotli::flush' => ['string'],
    'http\Encoding\Stream\Enbrotli::update' => ['string', 'data'=>'string'],
    'http\Encoding\Stream\Inflate::__construct' => ['void', 'flags='=>'mixed'],
    'http\Encoding\Stream\Inflate::decode' => ['string', 'data'=>'string'],
    'http\Encoding\Stream\Inflate::done' => ['bool'],
    'http\Encoding\Stream\Inflate::finish' => ['string'],
    'http\Encoding\Stream\Inflate::flush' => ['string'],
    'http\Encoding\Stream\Inflate::update' => ['string', 'data'=>'string'],
    'http\Env::getRequestBody' => ['http\Message\Body', 'body_class_name='=>'mixed'],
    'http\Env::getRequestHeader' => ['array|null|string', 'header_name='=>'mixed'],
    'http\Env::getResponseCode' => ['int'],
    'http\Env::getResponseHeader' => ['array|null|string', 'header_name='=>'mixed'],
    'http\Env::getResponseStatusForAllCodes' => ['array'],
    'http\Env::getResponseStatusForCode' => ['string', 'code'=>'int'],
    'http\Env::negotiate' => ['null|string', 'params'=>'string', 'supported'=>'array', 'primary_type_separator='=>'mixed', '&result_array='=>'mixed'],
    'http\Env::negotiateCharset' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
    'http\Env::negotiateContentType' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
    'http\Env::negotiateEncoding' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
    'http\Env::negotiateLanguage' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
    'http\Env::setResponseCode' => ['bool', 'code'=>'int'],
    'http\Env::setResponseHeader' => ['bool', 'header_name'=>'string', 'header_value='=>'mixed', 'response_code='=>'mixed', 'replace_header='=>'mixed'],
    'http\Env\Request::__construct' => ['void'],
    'http\Env\Request::__toString' => ['string'],
    'http\Env\Request::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Env\Request::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
    'http\Env\Request::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
    'http\Env\Request::count' => ['int'],
    'http\Env\Request::current' => ['mixed'],
    'http\Env\Request::detach' => ['http\Message'],
    'http\Env\Request::getBody' => ['http\Message\Body'],
    'http\Env\Request::getCookie' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
    'http\Env\Request::getFiles' => ['array'],
    'http\Env\Request::getForm' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
    'http\Env\Request::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
    'http\Env\Request::getHeaders' => ['array'],
    'http\Env\Request::getHttpVersion' => ['string'],
    'http\Env\Request::getInfo' => ['null|string'],
    'http\Env\Request::getParentMessage' => ['http\Message'],
    'http\Env\Request::getQuery' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
    'http\Env\Request::getRequestMethod' => ['false|string'],
    'http\Env\Request::getRequestUrl' => ['false|string'],
    'http\Env\Request::getResponseCode' => ['false|int'],
    'http\Env\Request::getResponseStatus' => ['false|string'],
    'http\Env\Request::getType' => ['int'],
    'http\Env\Request::isMultipart' => ['bool', '&boundary='=>'mixed'],
    'http\Env\Request::key' => ['int|string'],
    'http\Env\Request::next' => ['void'],
    'http\Env\Request::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
    'http\Env\Request::reverse' => ['http\Message'],
    'http\Env\Request::rewind' => ['void'],
    'http\Env\Request::serialize' => ['string'],
    'http\Env\Request::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Env\Request::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
    'http\Env\Request::setHeaders' => ['http\Message', 'headers'=>'array'],
    'http\Env\Request::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
    'http\Env\Request::setInfo' => ['http\Message', 'http_info'=>'string'],
    'http\Env\Request::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
    'http\Env\Request::setRequestUrl' => ['http\Message', 'url'=>'string'],
    'http\Env\Request::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
    'http\Env\Request::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
    'http\Env\Request::setType' => ['http\Message', 'type'=>'int'],
    'http\Env\Request::splitMultipartBody' => ['http\Message'],
    'http\Env\Request::toCallback' => ['http\Message', 'callback'=>'callable'],
    'http\Env\Request::toStream' => ['http\Message', 'stream'=>'resource'],
    'http\Env\Request::toString' => ['string', 'include_parent='=>'mixed'],
    'http\Env\Request::unserialize' => ['void', 'serialized'=>'string'],
    'http\Env\Request::valid' => ['bool'],
    'http\Env\Response::__construct' => ['void'],
    'http\Env\Response::__invoke' => ['bool', 'data'=>'string', 'ob_flags='=>'int'],
    'http\Env\Response::__toString' => ['string'],
    'http\Env\Response::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Env\Response::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
    'http\Env\Response::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
    'http\Env\Response::count' => ['int'],
    'http\Env\Response::current' => ['mixed'],
    'http\Env\Response::detach' => ['http\Message'],
    'http\Env\Response::getBody' => ['http\Message\Body'],
    'http\Env\Response::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
    'http\Env\Response::getHeaders' => ['array'],
    'http\Env\Response::getHttpVersion' => ['string'],
    'http\Env\Response::getInfo' => ['?string'],
    'http\Env\Response::getParentMessage' => ['http\Message'],
    'http\Env\Response::getRequestMethod' => ['false|string'],
    'http\Env\Response::getRequestUrl' => ['false|string'],
    'http\Env\Response::getResponseCode' => ['false|int'],
    'http\Env\Response::getResponseStatus' => ['false|string'],
    'http\Env\Response::getType' => ['int'],
    'http\Env\Response::isCachedByETag' => ['int', 'header_name='=>'string'],
    'http\Env\Response::isCachedByLastModified' => ['int', 'header_name='=>'string'],
    'http\Env\Response::isMultipart' => ['bool', '&boundary='=>'mixed'],
    'http\Env\Response::key' => ['int|string'],
    'http\Env\Response::next' => ['void'],
    'http\Env\Response::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
    'http\Env\Response::reverse' => ['http\Message'],
    'http\Env\Response::rewind' => ['void'],
    'http\Env\Response::send' => ['bool', 'stream='=>'resource'],
    'http\Env\Response::serialize' => ['string'],
    'http\Env\Response::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Env\Response::setCacheControl' => ['http\Env\Response', 'cache_control'=>'string'],
    'http\Env\Response::setContentDisposition' => ['http\Env\Response', 'disposition_params'=>'array'],
    'http\Env\Response::setContentEncoding' => ['http\Env\Response', 'content_encoding'=>'int'],
    'http\Env\Response::setContentType' => ['http\Env\Response', 'content_type'=>'string'],
    'http\Env\Response::setCookie' => ['http\Env\Response', 'cookie'=>'mixed'],
    'http\Env\Response::setEnvRequest' => ['http\Env\Response', 'env_request'=>'http\Message'],
    'http\Env\Response::setEtag' => ['http\Env\Response', 'etag'=>'string'],
    'http\Env\Response::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
    'http\Env\Response::setHeaders' => ['http\Message', 'headers'=>'array'],
    'http\Env\Response::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
    'http\Env\Response::setInfo' => ['http\Message', 'http_info'=>'string'],
    'http\Env\Response::setLastModified' => ['http\Env\Response', 'last_modified'=>'int'],
    'http\Env\Response::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
    'http\Env\Response::setRequestUrl' => ['http\Message', 'url'=>'string'],
    'http\Env\Response::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
    'http\Env\Response::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
    'http\Env\Response::setThrottleRate' => ['http\Env\Response', 'chunk_size'=>'int', 'delay='=>'float|int'],
    'http\Env\Response::setType' => ['http\Message', 'type'=>'int'],
    'http\Env\Response::splitMultipartBody' => ['http\Message'],
    'http\Env\Response::toCallback' => ['http\Message', 'callback'=>'callable'],
    'http\Env\Response::toStream' => ['http\Message', 'stream'=>'resource'],
    'http\Env\Response::toString' => ['string', 'include_parent='=>'mixed'],
    'http\Env\Response::unserialize' => ['void', 'serialized'=>'string'],
    'http\Env\Response::valid' => ['bool'],
    'http\Header::__construct' => ['void', 'name='=>'mixed', 'value='=>'mixed'],
    'http\Header::__toString' => ['string'],
    'http\Header::getParams' => ['http\Params', 'param_sep='=>'mixed', 'arg_sep='=>'mixed', 'val_sep='=>'mixed', 'flags='=>'mixed'],
    'http\Header::match' => ['bool', 'value'=>'string', 'flags='=>'mixed'],
    'http\Header::negotiate' => ['null|string', 'supported'=>'array', '&result='=>'mixed'],
    'http\Header::parse' => ['array|false', 'string'=>'string', 'header_class='=>'mixed'],
    'http\Header::serialize' => ['string'],
    'http\Header::toString' => ['string'],
    'http\Header::unserialize' => ['void', 'serialized'=>'string'],
    'http\Header\Parser::getState' => ['int'],
    'http\Header\Parser::parse' => ['int', 'data'=>'string', 'flags'=>'int', '&headers'=>'array'],
    'http\Header\Parser::stream' => ['int', 'stream'=>'resource', 'flags'=>'int', '&headers'=>'array'],
    'http\Message::__construct' => ['void', 'message='=>'mixed', 'greedy='=>'bool'],
    'http\Message::__toString' => ['string'],
    'http\Message::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Message::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
    'http\Message::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
    'http\Message::count' => ['int'],
    'http\Message::current' => ['mixed'],
    'http\Message::detach' => ['http\Message'],
    'http\Message::getBody' => ['http\Message\Body'],
    'http\Message::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
    'http\Message::getHeaders' => ['array'],
    'http\Message::getHttpVersion' => ['string'],
    'http\Message::getInfo' => ['null|string'],
    'http\Message::getParentMessage' => ['http\Message'],
    'http\Message::getRequestMethod' => ['false|string'],
    'http\Message::getRequestUrl' => ['false|string'],
    'http\Message::getResponseCode' => ['false|int'],
    'http\Message::getResponseStatus' => ['false|string'],
    'http\Message::getType' => ['int'],
    'http\Message::isMultipart' => ['bool', '&boundary='=>'mixed'],
    'http\Message::key' => ['int|string'],
    'http\Message::next' => ['void'],
    'http\Message::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
    'http\Message::reverse' => ['http\Message'],
    'http\Message::rewind' => ['void'],
    'http\Message::serialize' => ['string'],
    'http\Message::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
    'http\Message::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
    'http\Message::setHeaders' => ['http\Message', 'headers'=>'array'],
    'http\Message::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
    'http\Message::setInfo' => ['http\Message', 'http_info'=>'string'],
    'http\Message::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
    'http\Message::setRequestUrl' => ['http\Message', 'url'=>'string'],
    'http\Message::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
    'http\Message::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
    'http\Message::setType' => ['http\Message', 'type'=>'int'],
    'http\Message::splitMultipartBody' => ['http\Message'],
    'http\Message::toCallback' => ['http\Message', 'callback'=>'callable'],
    'http\Message::toStream' => ['http\Message', 'stream'=>'resource'],
    'http\Message::toString' => ['string', 'include_parent='=>'mixed'],
    'http\Message::unserialize' => ['void', 'serialized'=>'string'],
    'http\Message::valid' => ['bool'],
    'http\Message\Body::__construct' => ['void', 'stream='=>'resource'],
    'http\Message\Body::__toString' => ['string'],
    'http\Message\Body::addForm' => ['http\Message\Body', 'fields='=>'?array', 'files='=>'?array'],
    'http\Message\Body::addPart' => ['http\Message\Body', 'message'=>'http\Message'],
    'http\Message\Body::append' => ['http\Message\Body', 'string'=>'string'],
    'http\Message\Body::etag' => ['false|string'],
    'http\Message\Body::getBoundary' => ['null|string'],
    'http\Message\Body::getResource' => ['resource'],
    'http\Message\Body::serialize' => ['string'],
    'http\Message\Body::stat' => ['int|object', 'field='=>'mixed'],
    'http\Message\Body::toCallback' => ['http\Message\Body', 'callback'=>'callable', 'offset='=>'mixed', 'maxlen='=>'mixed'],
    'http\Message\Body::toStream' => ['http\Message\Body', 'stream'=>'resource', 'offset='=>'mixed', 'maxlen='=>'mixed'],
    'http\Message\Body::toString' => ['string'],
    'http\Message\Body::unserialize' => ['void', 'serialized'=>'string'],
    'http\Message\Parser::getState' => ['int'],
    'http\Message\Parser::parse' => ['int', 'data'=>'string', 'flags'=>'int', '&message'=>'http\Message'],
    'http\Message\Parser::stream' => ['int', 'stream'=>'resource', 'flags'=>'int', '&message'=>'http\Message'],
    'http\Params::__construct' => ['void', 'params='=>'mixed', 'param_sep='=>'mixed', 'arg_sep='=>'mixed', 'val_sep='=>'mixed', 'flags='=>'mixed'],
    'http\Params::__toString' => ['string'],
    'http\Params::offsetExists' => ['bool', 'name'=>'mixed'],
    'http\Params::offsetGet' => ['mixed', 'name'=>'mixed'],
    'http\Params::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
    'http\Params::offsetUnset' => ['void', 'name'=>'mixed'],
    'http\Params::toArray' => ['array'],
    'http\Params::toString' => ['string'],
    'http\QueryString::__construct' => ['void', 'querystring'=>'string'],
    'http\QueryString::__toString' => ['string'],
    'http\QueryString::get' => ['http\QueryString|string|mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'],
    'http\QueryString::getArray' => ['array|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
    'http\QueryString::getBool' => ['bool|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
    'http\QueryString::getFloat' => ['float|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
    'http\QueryString::getGlobalInstance' => ['http\QueryString'],
    'http\QueryString::getInt' => ['int|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
    'http\QueryString::getIterator' => ['IteratorAggregate'],
    'http\QueryString::getObject' => ['object|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
    'http\QueryString::getString' => ['string|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
    'http\QueryString::mod' => ['http\QueryString', 'params='=>'mixed'],
    'http\QueryString::offsetExists' => ['bool', 'offset'=>'mixed'],
    'http\QueryString::offsetGet' => ['mixed|null', 'offset'=>'mixed'],
    'http\QueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
    'http\QueryString::offsetUnset' => ['void', 'offset'=>'mixed'],
    'http\QueryString::serialize' => ['string'],
    'http\QueryString::set' => ['http\QueryString', 'params'=>'mixed'],
    'http\QueryString::toArray' => ['array'],
    'http\QueryString::toString' => ['string'],
    'http\QueryString::unserialize' => ['void', 'serialized'=>'string'],
    'http\QueryString::xlate' => ['http\QueryString'],
    'http\Url::__construct' => ['void', 'old_url='=>'mixed', 'new_url='=>'mixed', 'flags='=>'int'],
    'http\Url::__toString' => ['string'],
    'http\Url::mod' => ['http\Url', 'parts'=>'mixed', 'flags='=>'float|int|mixed'],
    'http\Url::toArray' => ['string[]'],
    'http\Url::toString' => ['string'],
    'http_build_cookie' => ['string', 'cookie'=>'array'],
    'http_build_query' => ['string', 'data'=>'array|object', 'numeric_prefix='=>'string', 'arg_separator='=>'?string', 'encoding_type='=>'int'],
    'http_build_str' => ['string', 'query'=>'array', 'prefix='=>'?string', 'arg_separator='=>'string'],
    'http_build_url' => ['string', 'url='=>'string|array', 'parts='=>'string|array', 'flags='=>'int', 'new_url='=>'array'],
    'http_cache_etag' => ['bool', 'etag='=>'string'],
    'http_cache_last_modified' => ['bool', 'timestamp_or_expires='=>'int'],
    'http_chunked_decode' => ['string|false', 'encoded'=>'string'],
    'http_date' => ['string', 'timestamp='=>'int'],
    'http_deflate' => ['?string', 'data'=>'string', 'flags='=>'int'],
    'http_get' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'],
    'http_get_request_body' => ['?string'],
    'http_get_request_body_stream' => ['?resource'],
    'http_get_request_headers' => ['array'],
    'http_head' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'],
    'http_inflate' => ['?string', 'data'=>'string'],
    'http_match_etag' => ['bool', 'etag'=>'string', 'for_range='=>'bool'],
    'http_match_modified' => ['bool', 'timestamp='=>'int', 'for_range='=>'bool'],
    'http_match_request_header' => ['bool', 'header'=>'string', 'value'=>'string', 'match_case='=>'bool'],
    'http_negotiate_charset' => ['string', 'supported'=>'array', 'result='=>'array'],
    'http_negotiate_content_type' => ['string', 'supported'=>'array', 'result='=>'array'],
    'http_negotiate_language' => ['string', 'supported'=>'array', 'result='=>'array'],
    'http_parse_cookie' => ['stdClass|false', 'cookie'=>'string', 'flags='=>'int', 'allowed_extras='=>'array'],
    'http_parse_headers' => ['array|false', 'header'=>'string'],
    'http_parse_message' => ['object', 'message'=>'string'],
    'http_parse_params' => ['stdClass', 'param'=>'string', 'flags='=>'int'],
    'http_persistent_handles_clean' => ['string', 'ident='=>'string'],
    'http_persistent_handles_count' => ['stdClass|false'],
    'http_persistent_handles_ident' => ['string|false', 'ident='=>'string'],
    'http_post_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'],
    'http_post_fields' => ['string', 'url'=>'string', 'data'=>'array', 'files='=>'array', 'options='=>'array', 'info='=>'array'],
    'http_put_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'],
    'http_put_file' => ['string', 'url'=>'string', 'file'=>'string', 'options='=>'array', 'info='=>'array'],
    'http_put_stream' => ['string', 'url'=>'string', 'stream'=>'resource', 'options='=>'array', 'info='=>'array'],
    'http_redirect' => ['int|false', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'],
    'http_request' => ['string', 'method'=>'int', 'url'=>'string', 'body='=>'string', 'options='=>'array', 'info='=>'array'],
    'http_request_body_encode' => ['string|false', 'fields'=>'array', 'files'=>'array'],
    'http_request_method_exists' => ['bool', 'method'=>'mixed'],
    'http_request_method_name' => ['string|false', 'method'=>'int'],
    'http_request_method_register' => ['int|false', 'method'=>'string'],
    'http_request_method_unregister' => ['bool', 'method'=>'mixed'],
    'http_response_code' => ['int|bool', 'response_code='=>'int'],
    'http_send_content_disposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'],
    'http_send_content_type' => ['bool', 'content_type='=>'string'],
    'http_send_data' => ['bool', 'data'=>'string'],
    'http_send_file' => ['bool', 'file'=>'string'],
    'http_send_last_modified' => ['bool', 'timestamp='=>'int'],
    'http_send_status' => ['bool', 'status'=>'int'],
    'http_send_stream' => ['bool', 'stream'=>'resource'],
    'http_support' => ['int', 'feature='=>'int'],
    'http_throttle' => ['void', 'sec'=>'float', 'bytes='=>'int'],
    'hw_Array2Objrec' => ['string', 'object_array'=>'array'],
    'hw_Children' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_ChildrenObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_Close' => ['bool', 'connection'=>'int'],
    'hw_Connect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'],
    'hw_Deleteobject' => ['bool', 'connection'=>'int', 'object_to_delete'=>'int'],
    'hw_DocByAnchor' => ['int', 'connection'=>'int', 'anchorid'=>'int'],
    'hw_DocByAnchorObj' => ['string', 'connection'=>'int', 'anchorid'=>'int'],
    'hw_Document_Attributes' => ['string', 'hw_document'=>'int'],
    'hw_Document_BodyTag' => ['string', 'hw_document'=>'int', 'prefix='=>'string'],
    'hw_Document_Content' => ['string', 'hw_document'=>'int'],
    'hw_Document_SetContent' => ['bool', 'hw_document'=>'int', 'content'=>'string'],
    'hw_Document_Size' => ['int', 'hw_document'=>'int'],
    'hw_EditText' => ['bool', 'connection'=>'int', 'hw_document'=>'int'],
    'hw_Error' => ['int', 'connection'=>'int'],
    'hw_ErrorMsg' => ['string', 'connection'=>'int'],
    'hw_Free_Document' => ['bool', 'hw_document'=>'int'],
    'hw_GetAnchors' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetAnchorsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetAndLock' => ['string', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetChildColl' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetChildCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetChildDocColl' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetChildDocCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetObject' => ['', 'connection'=>'int', 'objectid'=>'', 'query='=>'string'],
    'hw_GetObjectByQuery' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'],
    'hw_GetObjectByQueryColl' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'],
    'hw_GetObjectByQueryCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'],
    'hw_GetObjectByQueryObj' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'],
    'hw_GetParents' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetParentsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetRemote' => ['int', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetSrcByDestObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
    'hw_GetText' => ['int', 'connection'=>'int', 'objectid'=>'int', 'prefix='=>''],
    'hw_Identify' => ['string', 'link'=>'int', 'username'=>'string', 'password'=>'string'],
    'hw_InCollections' => ['array', 'connection'=>'int', 'object_id_array'=>'array', 'collection_id_array'=>'array', 'return_collections'=>'int'],
    'hw_Info' => ['string', 'connection'=>'int'],
    'hw_InsColl' => ['int', 'connection'=>'int', 'objectid'=>'int', 'object_array'=>'array'],
    'hw_InsDoc' => ['int', 'connection'=>'', 'parentid'=>'int', 'object_record'=>'string', 'text='=>'string'],
    'hw_InsertDocument' => ['int', 'connection'=>'int', 'parent_id'=>'int', 'hw_document'=>'int'],
    'hw_InsertObject' => ['int', 'connection'=>'int', 'object_rec'=>'string', 'parameter'=>'string'],
    'hw_Modifyobject' => ['bool', 'connection'=>'int', 'object_to_change'=>'int', 'remove'=>'array', 'add'=>'array', 'mode='=>'int'],
    'hw_New_Document' => ['int', 'object_record'=>'string', 'document_data'=>'string', 'document_size'=>'int'],
    'hw_Output_Document' => ['bool', 'hw_document'=>'int'],
    'hw_PipeDocument' => ['int', 'connection'=>'int', 'objectid'=>'int', 'url_prefixes='=>'array'],
    'hw_Root' => ['int'],
    'hw_Unlock' => ['bool', 'connection'=>'int', 'objectid'=>'int'],
    'hw_Who' => ['array', 'connection'=>'int'],
    'hw_api::checkin' => ['bool', 'parameter'=>'array'],
    'hw_api::checkout' => ['bool', 'parameter'=>'array'],
    'hw_api::children' => ['array', 'parameter'=>'array'],
    'hw_api::content' => ['HW_API_Content', 'parameter'=>'array'],
    'hw_api::copy' => ['hw_api_content', 'parameter'=>'array'],
    'hw_api::dbstat' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::dcstat' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::dstanchors' => ['array', 'parameter'=>'array'],
    'hw_api::dstofsrcanchor' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::find' => ['array', 'parameter'=>'array'],
    'hw_api::ftstat' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::hwstat' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::identify' => ['bool', 'parameter'=>'array'],
    'hw_api::info' => ['array', 'parameter'=>'array'],
    'hw_api::insert' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::insertanchor' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::insertcollection' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::insertdocument' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::link' => ['bool', 'parameter'=>'array'],
    'hw_api::lock' => ['bool', 'parameter'=>'array'],
    'hw_api::move' => ['bool', 'parameter'=>'array'],
    'hw_api::object' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::objectbyanchor' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::parents' => ['array', 'parameter'=>'array'],
    'hw_api::remove' => ['bool', 'parameter'=>'array'],
    'hw_api::replace' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::setcommittedversion' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::srcanchors' => ['array', 'parameter'=>'array'],
    'hw_api::srcsofdst' => ['array', 'parameter'=>'array'],
    'hw_api::unlock' => ['bool', 'parameter'=>'array'],
    'hw_api::user' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api::userlist' => ['array', 'parameter'=>'array'],
    'hw_api_attribute' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'],
    'hw_api_attribute::key' => ['string'],
    'hw_api_attribute::langdepvalue' => ['string', 'language'=>'string'],
    'hw_api_attribute::value' => ['string'],
    'hw_api_attribute::values' => ['array'],
    'hw_api_content' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'],
    'hw_api_content::mimetype' => ['string'],
    'hw_api_content::read' => ['string', 'buffer'=>'string', 'length'=>'int'],
    'hw_api_error::count' => ['int'],
    'hw_api_error::reason' => ['HW_API_Reason'],
    'hw_api_object' => ['hw_api_object', 'parameter'=>'array'],
    'hw_api_object::assign' => ['bool', 'parameter'=>'array'],
    'hw_api_object::attreditable' => ['bool', 'parameter'=>'array'],
    'hw_api_object::count' => ['int', 'parameter'=>'array'],
    'hw_api_object::insert' => ['bool', 'attribute'=>'hw_api_attribute'],
    'hw_api_object::remove' => ['bool', 'name'=>'string'],
    'hw_api_object::title' => ['string', 'parameter'=>'array'],
    'hw_api_object::value' => ['string', 'name'=>'string'],
    'hw_api_reason::description' => ['string'],
    'hw_api_reason::type' => ['HW_API_Reason'],
    'hw_changeobject' => ['bool', 'link'=>'int', 'objid'=>'int', 'attributes'=>'array'],
    'hw_connection_info' => ['', 'link'=>'int'],
    'hw_cp' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'destination_id'=>'int'],
    'hw_dummy' => ['string', 'link'=>'int', 'id'=>'int', 'msgid'=>'int'],
    'hw_getrellink' => ['string', 'link'=>'int', 'rootid'=>'int', 'sourceid'=>'int', 'destid'=>'int'],
    'hw_getremotechildren' => ['', 'connection'=>'int', 'object_record'=>'string'],
    'hw_getusername' => ['string', 'connection'=>'int'],
    'hw_insertanchors' => ['bool', 'hwdoc'=>'int', 'anchorecs'=>'array', 'dest'=>'array', 'urlprefixes='=>'array'],
    'hw_mapid' => ['int', 'connection'=>'int', 'server_id'=>'int', 'object_id'=>'int'],
    'hw_mv' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'source_id'=>'int', 'destination_id'=>'int'],
    'hw_objrec2array' => ['array', 'object_record'=>'string', 'format='=>'array'],
    'hw_pConnect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'],
    'hw_setlinkroot' => ['int', 'link'=>'int', 'rootid'=>'int'],
    'hw_stat' => ['string', 'link'=>'int'],
    'hwapi_attribute_new' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'],
    'hwapi_content_new' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'],
    'hwapi_hgcsp' => ['HW_API', 'hostname'=>'string', 'port='=>'int'],
    'hwapi_object_new' => ['hw_api_object', 'parameter'=>'array'],
    'hypot' => ['float', 'x'=>'float', 'y'=>'float'],
    'ibase_add_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'],
    'ibase_affected_rows' => ['int', 'link_identifier='=>'resource'],
    'ibase_backup' => ['mixed', 'service_handle'=>'resource', 'source_db'=>'string', 'dest_file'=>'string', 'options='=>'int', 'verbose='=>'bool'],
    'ibase_blob_add' => ['void', 'blob_handle'=>'resource', 'data'=>'string'],
    'ibase_blob_cancel' => ['bool', 'blob_handle'=>'resource'],
    'ibase_blob_close' => ['string|bool', 'blob_handle'=>'resource'],
    'ibase_blob_create' => ['resource', 'link_identifier='=>'resource'],
    'ibase_blob_echo' => ['bool', 'link_identifier'=>'', 'blob_id'=>'string'],
    'ibase_blob_echo\'1' => ['bool', 'blob_id'=>'string'],
    'ibase_blob_get' => ['string|false', 'blob_handle'=>'resource', 'length'=>'int'],
    'ibase_blob_import' => ['string|false', 'link_identifier'=>'resource', 'file_handle'=>'resource'],
    'ibase_blob_info' => ['array', 'link_identifier'=>'resource', 'blob_id'=>'string'],
    'ibase_blob_info\'1' => ['array', 'blob_id'=>'string'],
    'ibase_blob_open' => ['resource|false', 'link_identifier'=>'', 'blob_id'=>'string'],
    'ibase_blob_open\'1' => ['resource', 'blob_id'=>'string'],
    'ibase_close' => ['bool', 'link_identifier='=>'resource'],
    'ibase_commit' => ['bool', 'link_identifier='=>'resource'],
    'ibase_commit_ret' => ['bool', 'link_identifier='=>'resource'],
    'ibase_connect' => ['resource|false', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'],
    'ibase_db_info' => ['string', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'],
    'ibase_delete_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password='=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'],
    'ibase_drop_db' => ['bool', 'link_identifier='=>'resource'],
    'ibase_errcode' => ['int|false'],
    'ibase_errmsg' => ['string|false'],
    'ibase_execute' => ['resource|false', 'query'=>'resource', 'bind_arg='=>'mixed', '...args='=>'mixed'],
    'ibase_fetch_assoc' => ['array|false', 'result'=>'resource', 'fetch_flags='=>'int'],
    'ibase_fetch_object' => ['object|false', 'result'=>'resource', 'fetch_flags='=>'int'],
    'ibase_fetch_row' => ['array|false', 'result'=>'resource', 'fetch_flags='=>'int'],
    'ibase_field_info' => ['array', 'query_result'=>'resource', 'field_number'=>'int'],
    'ibase_free_event_handler' => ['bool', 'event'=>'resource'],
    'ibase_free_query' => ['bool', 'query'=>'resource'],
    'ibase_free_result' => ['bool', 'result'=>'resource'],
    'ibase_gen_id' => ['int|string', 'generator'=>'string', 'increment='=>'int', 'link_identifier='=>'resource'],
    'ibase_maintain_db' => ['bool', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'],
    'ibase_modify_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'],
    'ibase_name_result' => ['bool', 'result'=>'resource', 'name'=>'string'],
    'ibase_num_fields' => ['int', 'query_result'=>'resource'],
    'ibase_num_params' => ['int', 'query'=>'resource'],
    'ibase_num_rows' => ['int', 'result_identifier'=>''],
    'ibase_param_info' => ['array', 'query'=>'resource', 'field_number'=>'int'],
    'ibase_pconnect' => ['resource|false', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'],
    'ibase_prepare' => ['resource|false', 'link_identifier'=>'', 'query'=>'string', 'trans_identifier'=>''],
    'ibase_query' => ['resource|false', 'link_identifier='=>'resource', 'string='=>'string', 'bind_arg='=>'int', '...args='=>''],
    'ibase_restore' => ['mixed', 'service_handle'=>'resource', 'source_file'=>'string', 'dest_db'=>'string', 'options='=>'int', 'verbose='=>'bool'],
    'ibase_rollback' => ['bool', 'link_identifier='=>'resource'],
    'ibase_rollback_ret' => ['bool', 'link_identifier='=>'resource'],
    'ibase_server_info' => ['string', 'service_handle'=>'resource', 'action'=>'int'],
    'ibase_service_attach' => ['resource', 'host'=>'string', 'dba_username'=>'string', 'dba_password'=>'string'],
    'ibase_service_detach' => ['bool', 'service_handle'=>'resource'],
    'ibase_set_event_handler' => ['resource', 'link_identifier'=>'', 'callback'=>'callable', 'event='=>'string', '...args='=>''],
    'ibase_set_event_handler\'1' => ['resource', 'callback'=>'callable', 'event'=>'string', '...args'=>''],
    'ibase_timefmt' => ['bool', 'format'=>'string', 'columntype='=>'int'],
    'ibase_trans' => ['resource|false', 'trans_args='=>'int', 'link_identifier='=>'', '...args='=>''],
    'ibase_wait_event' => ['string', 'link_identifier'=>'', 'event='=>'string', '...args='=>''],
    'ibase_wait_event\'1' => ['string', 'event'=>'string', '...args'=>''],
    'iconv' => ['string|false', 'from_encoding'=>'string', 'to_encoding'=>'string', 'string'=>'string'],
    'iconv_get_encoding' => ['array|string|false', 'type='=>'string'],
    'iconv_mime_decode' => ['string|false', 'string'=>'string', 'mode='=>'int', 'encoding='=>'string'],
    'iconv_mime_decode_headers' => ['array|false', 'headers'=>'string', 'mode='=>'int', 'encoding='=>'string'],
    'iconv_mime_encode' => ['string|false', 'field_name'=>'string', 'field_value'=>'string', 'options='=>'array'],
    'iconv_set_encoding' => ['bool', 'type'=>'string', 'encoding'=>'string'],
    'iconv_strlen' => ['0|positive-int|false', 'string'=>'string', 'encoding='=>'string'],
    'iconv_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
    'iconv_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string'],
    'iconv_substr' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'int', 'encoding='=>'string'],
    'id3_get_frame_long_name' => ['string', 'frameid'=>'string'],
    'id3_get_frame_short_name' => ['string', 'frameid'=>'string'],
    'id3_get_genre_id' => ['int', 'genre'=>'string'],
    'id3_get_genre_list' => ['array'],
    'id3_get_genre_name' => ['string', 'genre_id'=>'int'],
    'id3_get_tag' => ['array', 'filename'=>'string', 'version='=>'int'],
    'id3_get_version' => ['int', 'filename'=>'string'],
    'id3_remove_tag' => ['bool', 'filename'=>'string', 'version='=>'int'],
    'id3_set_tag' => ['bool', 'filename'=>'string', 'tag'=>'array', 'version='=>'int'],
    'idate' => ['int', 'format'=>'string', 'timestamp='=>'int'],
    'idn_strerror' => ['string', 'errorcode'=>'int'],
    'idn_to_ascii' => ['string|false', 'domain'=>'string', 'flags='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'],
    'idn_to_utf8' => ['string|false', 'domain'=>'string', 'flags='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'],
    'ifx_affected_rows' => ['int', 'result_id'=>'resource'],
    'ifx_blobinfile_mode' => ['bool', 'mode'=>'int'],
    'ifx_byteasvarchar' => ['bool', 'mode'=>'int'],
    'ifx_close' => ['bool', 'link_identifier='=>'resource'],
    'ifx_connect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'],
    'ifx_copy_blob' => ['int', 'bid'=>'int'],
    'ifx_create_blob' => ['int', 'type'=>'int', 'mode'=>'int', 'param'=>'string'],
    'ifx_create_char' => ['int', 'param'=>'string'],
    'ifx_do' => ['bool', 'result_id'=>'resource'],
    'ifx_error' => ['string', 'link_identifier='=>'resource'],
    'ifx_errormsg' => ['string', 'errorcode='=>'int'],
    'ifx_fetch_row' => ['array', 'result_id'=>'resource', 'position='=>'mixed'],
    'ifx_fieldproperties' => ['array', 'result_id'=>'resource'],
    'ifx_fieldtypes' => ['array', 'result_id'=>'resource'],
    'ifx_free_blob' => ['bool', 'bid'=>'int'],
    'ifx_free_char' => ['bool', 'bid'=>'int'],
    'ifx_free_result' => ['bool', 'result_id'=>'resource'],
    'ifx_get_blob' => ['string', 'bid'=>'int'],
    'ifx_get_char' => ['string', 'bid'=>'int'],
    'ifx_getsqlca' => ['array', 'result_id'=>'resource'],
    'ifx_htmltbl_result' => ['int', 'result_id'=>'resource', 'html_table_options='=>'string'],
    'ifx_nullformat' => ['bool', 'mode'=>'int'],
    'ifx_num_fields' => ['int', 'result_id'=>'resource'],
    'ifx_num_rows' => ['int', 'result_id'=>'resource'],
    'ifx_pconnect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'],
    'ifx_prepare' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_def='=>'int', 'blobidarray='=>'mixed'],
    'ifx_query' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_type='=>'int', 'blobidarray='=>'mixed'],
    'ifx_textasvarchar' => ['bool', 'mode'=>'int'],
    'ifx_update_blob' => ['bool', 'bid'=>'int', 'content'=>'string'],
    'ifx_update_char' => ['bool', 'bid'=>'int', 'content'=>'string'],
    'ifxus_close_slob' => ['bool', 'bid'=>'int'],
    'ifxus_create_slob' => ['int', 'mode'=>'int'],
    'ifxus_free_slob' => ['bool', 'bid'=>'int'],
    'ifxus_open_slob' => ['int', 'bid'=>'int', 'mode'=>'int'],
    'ifxus_read_slob' => ['string', 'bid'=>'int', 'nbytes'=>'int'],
    'ifxus_seek_slob' => ['int', 'bid'=>'int', 'mode'=>'int', 'offset'=>'int'],
    'ifxus_tell_slob' => ['int', 'bid'=>'int'],
    'ifxus_write_slob' => ['int', 'bid'=>'int', 'content'=>'string'],
    'igbinary_serialize' => ['string|false', 'value'=>'mixed'],
    'igbinary_unserialize' => ['mixed', 'string'=>'string'],
    'ignore_user_abort' => ['int', 'enable='=>'bool'],
    'iis_add_server' => ['int', 'path'=>'string', 'comment'=>'string', 'server_ip'=>'string', 'port'=>'int', 'host_name'=>'string', 'rights'=>'int', 'start_server'=>'int'],
    'iis_get_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'],
    'iis_get_script_map' => ['string', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string'],
    'iis_get_server_by_comment' => ['int', 'comment'=>'string'],
    'iis_get_server_by_path' => ['int', 'path'=>'string'],
    'iis_get_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'],
    'iis_get_service_state' => ['int', 'service_id'=>'string'],
    'iis_remove_server' => ['int', 'server_instance'=>'int'],
    'iis_set_app_settings' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'application_scope'=>'string'],
    'iis_set_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'],
    'iis_set_script_map' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string', 'engine_path'=>'string', 'allow_scripting'=>'int'],
    'iis_set_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'],
    'iis_start_server' => ['int', 'server_instance'=>'int'],
    'iis_start_service' => ['int', 'service_id'=>'string'],
    'iis_stop_server' => ['int', 'server_instance'=>'int'],
    'iis_stop_service' => ['int', 'service_id'=>'string'],
    'image2wbmp' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'threshold='=>'int'],
    'imageObj::pasteImage' => ['void', 'srcImg'=>'imageObj', 'transparentColorHex'=>'int', 'dstX'=>'int', 'dstY'=>'int', 'angle'=>'int'],
    'imageObj::saveImage' => ['int', 'filename'=>'string', 'oMap'=>'mapObj'],
    'imageObj::saveWebImage' => ['string'],
    'image_type_to_extension' => ['string', 'image_type'=>'int', 'include_dot='=>'bool'],
    'image_type_to_mime_type' => ['string', 'image_type'=>'int'],
    'imageaffine' => ['resource|false', 'src'=>'resource', 'affine'=>'array', 'clip='=>'array'],
    'imageaffinematrixconcat' => ['array{0:float,1:float,2:float,3:float,4:float,5:float}|false', 'matrix1'=>'array', 'matrix2'=>'array'],
    'imageaffinematrixget' => ['array{0:float,1:float,2:float,3:float,4:float,5:float}|false', 'type'=>'int', 'options'=>'array|float'],
    'imagealphablending' => ['bool', 'image'=>'resource', 'enable'=>'bool'],
    'imageantialias' => ['bool', 'image'=>'resource', 'enable'=>'bool'],
    'imagearc' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int'],
    'imagechar' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
    'imagecharup' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
    'imagecolorallocate' => ['int|false', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    'imagecolorallocatealpha' => ['int|false', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    'imagecolorat' => ['int|false', 'image'=>'resource', 'x'=>'int', 'y'=>'int'],
    'imagecolorclosest' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    'imagecolorclosestalpha' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    'imagecolorclosesthwb' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    'imagecolordeallocate' => ['bool', 'image'=>'resource', 'color'=>'int'],
    'imagecolorexact' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    'imagecolorexactalpha' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    'imagecolormatch' => ['bool', 'image1'=>'resource', 'image2'=>'resource'],
    'imagecolorresolve' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    'imagecolorresolvealpha' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    'imagecolorset' => ['false|null', 'image'=>'resource', 'color'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'],
    'imagecolorsforindex' => ['array', 'image'=>'resource', 'color'=>'int'],
    'imagecolorstotal' => ['int', 'image'=>'resource'],
    'imagecolortransparent' => ['int', 'image'=>'resource', 'color='=>'int'],
    'imageconvolution' => ['bool', 'image'=>'resource', 'matrix'=>'array', 'divisor'=>'float', 'offset'=>'float'],
    'imagecopy' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
    'imagecopymerge' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
    'imagecopymergegray' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
    'imagecopyresampled' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
    'imagecopyresized' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
    'imagecreate' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'],
    'imagecreatefromgd' => ['resource|false', 'filename'=>'string'],
    'imagecreatefromgd2' => ['resource|false', 'filename'=>'string'],
    'imagecreatefromgd2part' => ['resource|false', 'filename'=>'string', 'srcx'=>'int', 'srcy'=>'int', 'width'=>'int', 'height'=>'int'],
    'imagecreatefromgif' => ['resource|false', 'filename'=>'string'],
    'imagecreatefromjpeg' => ['resource|false', 'filename'=>'string'],
    'imagecreatefrompng' => ['resource|false', 'filename'=>'string'],
    'imagecreatefromstring' => ['resource|false', 'image'=>'string'],
    'imagecreatefromwbmp' => ['resource|false', 'filename'=>'string'],
    'imagecreatefromwebp' => ['resource|false', 'filename'=>'string'],
    'imagecreatefromxbm' => ['resource|false', 'filename'=>'string'],
    'imagecreatefromxpm' => ['resource|false', 'filename'=>'string'],
    'imagecreatetruecolor' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'],
    'imagecrop' => ['resource|false', 'im'=>'resource', 'rect'=>'array'],
    'imagecropauto' => ['resource|false', 'im'=>'resource', 'mode='=>'int', 'threshold='=>'float', 'color='=>'int'],
    'imagedashedline' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    'imagedestroy' => ['bool', 'image'=>'resource'],
    'imageellipse' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
    'imagefill' => ['bool', 'image'=>'resource', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
    'imagefilledarc' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int', 'style'=>'int'],
    'imagefilledellipse' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
    'imagefilledpolygon' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
    'imagefilledrectangle' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    'imagefilltoborder' => ['bool', 'image'=>'resource', 'x'=>'int', 'y'=>'int', 'border_color'=>'int', 'color'=>'int'],
    'imagefilter' => ['bool', 'image'=>'resource', 'filter'=>'int', 'args='=>'int', 'arg2='=>'int', 'arg3='=>'int', 'arg4='=>'int'],
    'imageflip' => ['bool', 'image'=>'resource', 'mode'=>'int'],
    'imagefontheight' => ['int', 'font'=>'int'],
    'imagefontwidth' => ['int', 'font'=>'int'],
    'imageftbbox' => ['array|false', 'size'=>'float', 'angle'=>'float', 'font_filename'=>'string', 'string'=>'string', 'options='=>'array'],
    'imagefttext' => ['array|false', 'image'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string', 'options='=>'array'],
    'imagegammacorrect' => ['bool', 'image'=>'resource', 'input_gamma'=>'float', 'output_gamma'=>'float'],
    'imagegd' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null'],
    'imagegd2' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'chunk_size='=>'int', 'mode='=>'int'],
    'imagegetclip' => ['array<int,int>|false', 'im'=>'resource'],
    'imagegif' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null'],
    'imagegrabscreen' => ['false|resource'],
    'imagegrabwindow' => ['false|resource', 'window_handle'=>'int', 'client_area='=>'int'],
    'imageinterlace' => ['int|false', 'image'=>'resource', 'enable='=>'int'],
    'imageistruecolor' => ['bool', 'image'=>'resource'],
    'imagejpeg' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'quality='=>'int'],
    'imagelayereffect' => ['bool', 'image'=>'resource', 'effect'=>'int'],
    'imageline' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    'imageloadfont' => ['int|false', 'filename'=>'string'],
    'imagepalettecopy' => ['void', 'dst'=>'resource', 'src'=>'resource'],
    'imagepalettetotruecolor' => ['bool', 'image'=>'resource'],
    'imagepng' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'quality='=>'int', 'filters='=>'int'],
    'imagepolygon' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
    'imagerectangle' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    'imagerotate' => ['resource|false', 'src_im'=>'resource', 'angle'=>'float', 'bgdcolor'=>'int', 'ignoretransparent='=>'int'],
    'imagesavealpha' => ['bool', 'image'=>'resource', 'enable'=>'bool'],
    'imagescale' => ['resource|false', 'im'=>'resource', 'new_width'=>'int', 'new_height='=>'int', 'method='=>'int'],
    'imagesetbrush' => ['bool', 'image'=>'resource', 'brush'=>'resource'],
    'imagesetinterpolation' => ['bool', 'image'=>'resource', 'method'=>'int'],
    'imagesetpixel' => ['bool', 'image'=>'resource', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
    'imagesetstyle' => ['bool', 'image'=>'resource', 'style'=>'non-empty-array'],
    'imagesetthickness' => ['bool', 'image'=>'resource', 'thickness'=>'int'],
    'imagesettile' => ['bool', 'image'=>'resource', 'tile'=>'resource'],
    'imagestring' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
    'imagestringup' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
    'imagesx' => ['int', 'image'=>'resource'],
    'imagesy' => ['int', 'image'=>'resource'],
    'imagetruecolortopalette' => ['bool', 'image'=>'resource', 'dither'=>'bool', 'num_colors'=>'int'],
    'imagettfbbox' => ['false|array', 'size'=>'float', 'angle'=>'float', 'font_filename'=>'string', 'string'=>'string'],
    'imagettftext' => ['false|array', 'image'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string'],
    'imagetypes' => ['int'],
    'imagewbmp' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'foreground_color='=>'int'],
    'imagewebp' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'quality='=>'int'],
    'imagexbm' => ['bool', 'image'=>'resource', 'filename='=>'?string', 'foreground_color='=>'int'],
    'imap_8bit' => ['string|false', 'string'=>'string'],
    'imap_alerts' => ['array|false'],
    'imap_append' => ['bool', 'imap'=>'resource', 'folder'=>'string', 'message'=>'string', 'options='=>'string', 'internal_date='=>'string'],
    'imap_base64' => ['string|false', 'string'=>'string'],
    'imap_binary' => ['string|false', 'string'=>'string'],
    'imap_body' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
    'imap_bodystruct' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'section'=>'string'],
    'imap_check' => ['stdClass|false', 'imap'=>'resource'],
    'imap_clearflag_full' => ['bool', 'imap'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
    'imap_close' => ['bool', 'imap'=>'resource', 'flags='=>'int'],
    'imap_create' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
    'imap_createmailbox' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
    'imap_delete' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'flags='=>'int'],
    'imap_deletemailbox' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
    'imap_errors' => ['array|false'],
    'imap_expunge' => ['bool', 'imap'=>'resource'],
    'imap_fetch_overview' => ['array|false', 'imap'=>'resource', 'sequence'=>'string', 'flags='=>'int'],
    'imap_fetchbody' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
    'imap_fetchheader' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
    'imap_fetchmime' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
    'imap_fetchstructure' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
    'imap_fetchtext' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
    'imap_gc' => ['bool', 'imap'=>'resource', 'flags'=>'int'],
    'imap_get_quota' => ['array|false', 'imap'=>'resource', 'quota_root'=>'string'],
    'imap_get_quotaroot' => ['array|false', 'imap'=>'resource', 'mailbox'=>'string'],
    'imap_getacl' => ['array|false', 'imap'=>'resource', 'mailbox'=>'string'],
    'imap_getmailboxes' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
    'imap_getsubscribed' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
    'imap_header' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string'],
    'imap_headerinfo' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string|null'],
    'imap_headers' => ['array|false', 'imap'=>'resource'],
    'imap_last_error' => ['string|false'],
    'imap_list' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
    'imap_listmailbox' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
    'imap_listscan' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
    'imap_listsubscribed' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
    'imap_lsub' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
    'imap_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string', 'cc='=>'string', 'bcc='=>'string', 'return_path='=>'string'],
    'imap_mail_compose' => ['string|false', 'envelope'=>'array', 'bodies'=>'array'],
    'imap_mail_copy' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
    'imap_mail_move' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
    'imap_mailboxmsginfo' => ['stdClass', 'imap'=>'resource'],
    'imap_mime_header_decode' => ['array|false', 'string'=>'string'],
    'imap_msgno' => ['int', 'imap'=>'resource', 'message_uid'=>'int'],
    'imap_mutf7_to_utf8' => ['string|false', 'string'=>'string'],
    'imap_num_msg' => ['int|false', 'imap'=>'resource'],
    'imap_num_recent' => ['int', 'imap'=>'resource'],
    'imap_open' => ['resource|false', 'mailbox'=>'string', 'user'=>'string', 'password'=>'string', 'flags='=>'int', 'retries='=>'int', 'options='=>'?array'],
    'imap_ping' => ['bool', 'imap'=>'resource'],
    'imap_qprint' => ['string|false', 'string'=>'string'],
    'imap_rename' => ['bool', 'imap'=>'resource', 'from'=>'string', 'to'=>'string'],
    'imap_renamemailbox' => ['bool', 'imap'=>'resource', 'from'=>'string', 'to'=>'string'],
    'imap_reopen' => ['bool', 'imap'=>'resource', 'mailbox'=>'string', 'flags='=>'int', 'retries='=>'int'],
    'imap_rfc822_parse_adrlist' => ['array', 'string'=>'string', 'default_hostname'=>'string'],
    'imap_rfc822_parse_headers' => ['stdClass', 'headers'=>'string', 'default_hostname='=>'string'],
    'imap_rfc822_write_address' => ['string|false', 'mailbox'=>'?string', 'hostname'=>'?string', 'personal'=>'?string'],
    'imap_savebody' => ['bool', 'imap'=>'resource', 'file'=>'string|resource', 'message_num'=>'int', 'section='=>'string', 'flags='=>'int'],
    'imap_scan' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
    'imap_scanmailbox' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
    'imap_search' => ['array|false', 'imap'=>'resource', 'criteria'=>'string', 'flags='=>'int', 'charset='=>'string'],
    'imap_set_quota' => ['bool', 'imap'=>'resource', 'quota_root'=>'string', 'mailbox_size'=>'int'],
    'imap_setacl' => ['bool', 'imap'=>'resource', 'mailbox'=>'string', 'user_id'=>'string', 'rights'=>'string'],
    'imap_setflag_full' => ['bool', 'imap'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
    'imap_sort' => ['array|false', 'imap'=>'resource', 'criteria'=>'int', 'reverse'=>'int', 'flags='=>'int', 'search_criteria='=>'string', 'charset='=>'string'],
    'imap_status' => ['stdClass|false', 'imap'=>'resource', 'mailbox'=>'string', 'flags'=>'int'],
    'imap_subscribe' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
    'imap_thread' => ['array|false', 'imap'=>'resource', 'flags='=>'int'],
    'imap_timeout' => ['int|bool', 'timeout_type'=>'int', 'timeout='=>'int'],
    'imap_uid' => ['int|false', 'imap'=>'resource', 'message_num'=>'int'],
    'imap_undelete' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'flags='=>'int'],
    'imap_unsubscribe' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
    'imap_utf7_decode' => ['string|false', 'string'=>'string'],
    'imap_utf7_encode' => ['string', 'string'=>'string'],
    'imap_utf8' => ['string', 'mime_encoded_text'=>'string'],
    'imap_utf8_to_mutf7' => ['string|false', 'string'=>'string'],
    'implode' => ['string', 'separator'=>'string', 'array'=>'array'],
    'implode\'1' => ['string', 'separator'=>'array'],
    'import_request_variables' => ['bool', 'types'=>'string', 'prefix='=>'string'],
    'in_array' => ['bool', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'],
    'inclued_get_data' => ['array'],
    'inet_ntop' => ['string|false', 'ip'=>'string'],
    'inet_pton' => ['string|false', 'ip'=>'string'],
    'inflate_add' => ['string|false', 'context'=>'resource', 'data'=>'string', 'flush_mode='=>'int'],
    'inflate_get_read_len' => ['int|false', 'context'=>'resource'],
    'inflate_get_status' => ['int|false', 'context'=>'resource'],
    'inflate_init' => ['resource|false', 'encoding'=>'int', 'options='=>'array'],
    'ingres_autocommit' => ['bool', 'link'=>'resource'],
    'ingres_autocommit_state' => ['bool', 'link'=>'resource'],
    'ingres_charset' => ['string', 'link'=>'resource'],
    'ingres_close' => ['bool', 'link'=>'resource'],
    'ingres_commit' => ['bool', 'link'=>'resource'],
    'ingres_connect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'],
    'ingres_cursor' => ['string', 'result'=>'resource'],
    'ingres_errno' => ['int', 'link='=>'resource'],
    'ingres_error' => ['string', 'link='=>'resource'],
    'ingres_errsqlstate' => ['string', 'link='=>'resource'],
    'ingres_escape_string' => ['string', 'link'=>'resource', 'source_string'=>'string'],
    'ingres_execute' => ['bool', 'result'=>'resource', 'params='=>'array', 'types='=>'string'],
    'ingres_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'],
    'ingres_fetch_assoc' => ['array', 'result'=>'resource'],
    'ingres_fetch_object' => ['object', 'result'=>'resource', 'result_type='=>'int'],
    'ingres_fetch_proc_return' => ['int', 'result'=>'resource'],
    'ingres_fetch_row' => ['array', 'result'=>'resource'],
    'ingres_field_length' => ['int', 'result'=>'resource', 'index'=>'int'],
    'ingres_field_name' => ['string', 'result'=>'resource', 'index'=>'int'],
    'ingres_field_nullable' => ['bool', 'result'=>'resource', 'index'=>'int'],
    'ingres_field_precision' => ['int', 'result'=>'resource', 'index'=>'int'],
    'ingres_field_scale' => ['int', 'result'=>'resource', 'index'=>'int'],
    'ingres_field_type' => ['string', 'result'=>'resource', 'index'=>'int'],
    'ingres_free_result' => ['bool', 'result'=>'resource'],
    'ingres_next_error' => ['bool', 'link='=>'resource'],
    'ingres_num_fields' => ['int', 'result'=>'resource'],
    'ingres_num_rows' => ['int', 'result'=>'resource'],
    'ingres_pconnect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'],
    'ingres_prepare' => ['mixed', 'link'=>'resource', 'query'=>'string'],
    'ingres_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'],
    'ingres_result_seek' => ['bool', 'result'=>'resource', 'position'=>'int'],
    'ingres_rollback' => ['bool', 'link'=>'resource'],
    'ingres_set_environment' => ['bool', 'link'=>'resource', 'options'=>'array'],
    'ingres_unbuffered_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'],
    'ini_alter' => ['string|false', 'option'=>'string', 'value'=>'string'],
    'ini_get' => ['string|false', 'option'=>'string'],
    'ini_get_all' => ['array|false', 'extension='=>'?string', 'details='=>'bool'],
    'ini_restore' => ['void', 'option'=>'string'],
    'ini_set' => ['string|false', 'option'=>'string', 'value'=>'string'],
    'inotify_add_watch' => ['int', 'inotify_instance'=>'resource', 'pathname'=>'string', 'mask'=>'int'],
    'inotify_init' => ['resource|false'],
    'inotify_queue_len' => ['int', 'inotify_instance'=>'resource'],
    'inotify_read' => ['array|false', 'inotify_instance'=>'resource'],
    'inotify_rm_watch' => ['bool', 'inotify_instance'=>'resource', 'watch_descriptor'=>'int'],
    'intdiv' => ['int', 'num1'=>'int', 'num2'=>'int'],
    'interface_exists' => ['bool', 'interface'=>'string', 'autoload='=>'bool'],
    'intl_error_name' => ['string', 'errorCode'=>'int'],
    'intl_get_error_code' => ['int'],
    'intl_get_error_message' => ['string'],
    'intl_is_failure' => ['bool', 'errorCode'=>'int'],
    'intlcal_add' => ['bool', 'calendar'=>'IntlCalendar', 'field'=>'int', 'value'=>'int'],
    'intlcal_after' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
    'intlcal_before' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
    'intlcal_clear' => ['bool', 'calendar'=>'IntlCalendar', 'field='=>'?int'],
    'intlcal_create_instance' => ['?IntlCalendar', 'timezone='=>'mixed', 'locale='=>'?string'],
    'intlcal_equals' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
    'intlcal_field_difference' => ['int', 'calendar'=>'IntlCalendar', 'timestamp'=>'float', 'field'=>'int'],
    'intlcal_from_date_time' => ['IntlCalendar', 'datetime'=>'DateTime|string'],
    'intlcal_get' => ['int|false', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_get_actual_maximum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_get_actual_minimum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_get_available_locales' => ['array'],
    'intlcal_get_day_of_week_type' => ['int', 'calendar'=>'IntlCalendar', 'dayOfWeek'=>'int'],
    'intlcal_get_first_day_of_week' => ['int', 'calendar'=>'IntlCalendar'],
    'intlcal_get_greatest_minimum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_get_keyword_values_for_locale' => ['IntlIterator|false', 'keyword'=>'string', 'locale'=>'string', 'onlyCommon'=>'bool'],
    'intlcal_get_least_maximum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_get_locale' => ['string', 'calendar'=>'IntlCalendar', 'type'=>'int'],
    'intlcal_get_maximum' => ['int|false', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_get_minimal_days_in_first_week' => ['int', 'calendar'=>'IntlCalendar'],
    'intlcal_get_minimum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_get_now' => ['float'],
    'intlcal_get_repeated_wall_time_option' => ['int', 'calendar'=>'IntlCalendar'],
    'intlcal_get_skipped_wall_time_option' => ['int', 'calendar'=>'IntlCalendar'],
    'intlcal_get_time' => ['float', 'calendar'=>'IntlCalendar'],
    'intlcal_get_time_zone' => ['IntlTimeZone', 'calendar'=>'IntlCalendar'],
    'intlcal_get_type' => ['string', 'calendar'=>'IntlCalendar'],
    'intlcal_get_weekend_transition' => ['int', 'calendar'=>'IntlCalendar', 'dayOfWeek'=>'string'],
    'intlcal_in_daylight_time' => ['bool', 'calendar'=>'IntlCalendar'],
    'intlcal_is_equivalent_to' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
    'intlcal_is_lenient' => ['bool', 'calendar'=>'IntlCalendar'],
    'intlcal_is_set' => ['bool', 'calendar'=>'IntlCalendar', 'field'=>'int'],
    'intlcal_is_weekend' => ['bool', 'calendar'=>'IntlCalendar', 'timestamp='=>'?float'],
    'intlcal_roll' => ['bool', 'calendar'=>'IntlCalendar', 'field'=>'int', 'value'=>'mixed'],
    'intlcal_set' => ['bool', 'calendar'=>'IntlCalendar', 'year'=>'int', 'month'=>'int'],
    'intlcal_set\'1' => ['bool', 'calendar'=>'IntlCalendar', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'],
    'intlcal_set_first_day_of_week' => ['bool', 'calendar'=>'IntlCalendar', 'dayOfWeek'=>'int'],
    'intlcal_set_lenient' => ['bool', 'calendar'=>'IntlCalendar', 'lenient'=>'bool'],
    'intlcal_set_repeated_wall_time_option' => ['bool', 'calendar'=>'IntlCalendar', 'option'=>'int'],
    'intlcal_set_skipped_wall_time_option' => ['bool', 'calendar'=>'IntlCalendar', 'option'=>'int'],
    'intlcal_set_time' => ['bool', 'calendar'=>'IntlCalendar', 'timestamp'=>'float'],
    'intlcal_set_time_zone' => ['bool', 'calendar'=>'IntlCalendar', 'timezone'=>'mixed'],
    'intlcal_to_date_time' => ['DateTime|false', 'calendar'=>'IntlCalendar'],
    'intlgregcal_create_instance' => ['IntlGregorianCalendar', 'timezoneOrYear='=>'mixed', 'localeOrMonth='=>'string'],
    'intlgregcal_get_gregorian_change' => ['float', 'calendar'=>'IntlGregorianCalendar'],
    'intlgregcal_is_leap_year' => ['bool', 'calendar'=>'int'],
    'intlgregcal_set_gregorian_change' => ['bool', 'calendar'=>'IntlGregorianCalendar', 'timestamp'=>'float'],
    'intltz_count_equivalent_ids' => ['int', 'timezoneId'=>'string'],
    'intltz_create_enumeration' => ['IntlIterator', 'countryOrRawOffset'=>'mixed'],
    'intltz_create_time_zone' => ['?IntlTimeZone', 'timezoneId'=>'string'],
    'intltz_from_date_time_zone' => ['?IntlTimeZone', 'timezone'=>'DateTimeZone'],
    'intltz_getGMT' => ['IntlTimeZone'],
    'intltz_get_canonical_id' => ['string', 'timezoneId'=>'string', '&isSystemId'=>'bool'],
    'intltz_get_display_name' => ['string', 'timezone'=>'IntlTimeZone', 'dst'=>'bool', 'style'=>'int', 'locale'=>'string'],
    'intltz_get_dst_savings' => ['int', 'timezone'=>'IntlTimeZone'],
    'intltz_get_equivalent_id' => ['string', 'timezoneId'=>'string', 'offset'=>'int'],
    'intltz_get_error_code' => ['int', 'timezone'=>'IntlTimeZone'],
    'intltz_get_error_message' => ['string', 'timezone'=>'IntlTimeZone'],
    'intltz_get_id' => ['string', 'timezone'=>'IntlTimeZone'],
    'intltz_get_offset' => ['bool', 'timezone'=>'IntlTimeZone', 'timestamp'=>'float', 'local'=>'bool', '&rawOffset'=>'int', '&dstOffset'=>'int'],
    'intltz_get_raw_offset' => ['int', 'timezone'=>'IntlTimeZone'],
    'intltz_get_tz_data_version' => ['string', 'object'=>'IntlTimeZone'],
    'intltz_has_same_rules' => ['bool', 'timezone'=>'IntlTimeZone', 'other'=>'IntlTimeZone'],
    'intltz_to_date_time_zone' => ['DateTimeZone', 'timezone'=>'IntlTimeZone'],
    'intltz_use_daylight_time' => ['bool', 'timezone'=>'IntlTimeZone'],
    'intlz_create_default' => ['IntlTimeZone'],
    'intval' => ['int', 'value'=>'mixed', 'base='=>'int'],
    'ip2long' => ['int|false', 'ip'=>'string'],
    'iptcembed' => ['string|bool', 'iptc_data'=>'string', 'filename'=>'string', 'spool='=>'int'],
    'iptcparse' => ['array|false', 'iptc_block'=>'string'],
    'is_a' => ['bool', 'object_or_class'=>'mixed', 'class'=>'string', 'allow_string='=>'bool'],
    'is_array' => ['bool', 'value'=>'mixed'],
    'is_bool' => ['bool', 'value'=>'mixed'],
    'is_callable' => ['bool', 'value'=>'callable|mixed', 'syntax_only='=>'bool', '&w_callable_name='=>'string'],
    'is_dir' => ['bool', 'filename'=>'string'],
    'is_double' => ['bool', 'value'=>'mixed'],
    'is_executable' => ['bool', 'filename'=>'string'],
    'is_file' => ['bool', 'filename'=>'string'],
    'is_finite' => ['bool', 'num'=>'float'],
    'is_float' => ['bool', 'value'=>'mixed'],
    'is_infinite' => ['bool', 'num'=>'float'],
    'is_int' => ['bool', 'value'=>'mixed'],
    'is_integer' => ['bool', 'value'=>'mixed'],
    'is_link' => ['bool', 'filename'=>'string'],
    'is_long' => ['bool', 'value'=>'mixed'],
    'is_nan' => ['bool', 'num'=>'float'],
    'is_null' => ['bool', 'value'=>'mixed'],
    'is_numeric' => ['bool', 'value'=>'mixed'],
    'is_object' => ['bool', 'value'=>'mixed'],
    'is_readable' => ['bool', 'filename'=>'string'],
    'is_real' => ['bool', 'value'=>'mixed'],
    'is_resource' => ['bool', 'value'=>'mixed'],
    'is_scalar' => ['bool', 'value'=>'mixed'],
    'is_soap_fault' => ['bool', 'object'=>'mixed'],
    'is_string' => ['bool', 'value'=>'mixed'],
    'is_subclass_of' => ['bool', 'object_or_class'=>'object|string', 'class'=>'class-string', 'allow_string='=>'bool'],
    'is_tainted' => ['bool', 'string'=>'string'],
    'is_uploaded_file' => ['bool', 'filename'=>'string'],
    'is_writable' => ['bool', 'filename'=>'string'],
    'is_writeable' => ['bool', 'filename'=>'string'],
    'isset' => ['bool', 'value'=>'mixed', '...rest='=>'mixed'],
    'iterator_apply' => ['0|positive-int', 'iterator'=>'Traversable', 'callback'=>'callable(mixed):bool', 'args='=>'?array'],
    'iterator_count' => ['0|positive-int', 'iterator'=>'Traversable'],
    'iterator_to_array' => ['array', 'iterator'=>'Traversable', 'preserve_keys='=>'bool'],
    'java_last_exception_clear' => ['void'],
    'java_last_exception_get' => ['object'],
    'java_reload' => ['array', 'new_jarpath'=>'string'],
    'java_require' => ['array', 'new_classpath'=>'string'],
    'java_set_encoding' => ['array', 'encoding'=>'string'],
    'java_set_ignore_case' => ['void', 'ignore'=>'bool'],
    'java_throw_exceptions' => ['void', 'throw'=>'bool'],
    'jddayofweek' => ['string|int', 'julian_day'=>'int', 'mode='=>'int'],
    'jdmonthname' => ['string', 'julian_day'=>'int', 'mode'=>'int'],
    'jdtofrench' => ['string', 'julian_day'=>'int'],
    'jdtogregorian' => ['string', 'julian_day'=>'int'],
    'jdtojewish' => ['string', 'julian_day'=>'int', 'hebrew='=>'bool', 'flags='=>'int'],
    'jdtojulian' => ['string', 'julian_day'=>'int'],
    'jdtounix' => ['int|false', 'julian_day'=>'int'],
    'jewishtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
    'jobqueue_license_info' => ['array'],
    'join' => ['string', 'separator'=>'string', 'array'=>'array'],
    'join\'1' => ['string', 'separator'=>'array'],
    'jpeg2wbmp' => ['bool', 'jpegname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'],
    'json_decode' => ['mixed', 'json'=>'string', 'associative='=>'bool', 'depth='=>'int', 'flags='=>'int'],
    'json_encode' => ['non-empty-string|false', 'value'=>'mixed', 'flags='=>'int', 'depth='=>'int'],
    'json_last_error' => ['int'],
    'json_last_error_msg' => ['string'],
    'judy_type' => ['int', 'array'=>'judy'],
    'judy_version' => ['string'],
    'juliantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
    'kadm5_chpass_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password'=>'string'],
    'kadm5_create_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password='=>'string', 'options='=>'array'],
    'kadm5_delete_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string'],
    'kadm5_destroy' => ['bool', 'handle'=>'resource'],
    'kadm5_flush' => ['bool', 'handle'=>'resource'],
    'kadm5_get_policies' => ['array', 'handle'=>'resource'],
    'kadm5_get_principal' => ['array', 'handle'=>'resource', 'principal'=>'string'],
    'kadm5_get_principals' => ['array', 'handle'=>'resource'],
    'kadm5_init_with_password' => ['resource', 'admin_server'=>'string', 'realm'=>'string', 'principal'=>'string', 'password'=>'string'],
    'kadm5_modify_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'options'=>'array'],
    'key' => ['int|string|null', 'array'=>'array|object'],
    'key_exists' => ['bool', 'key'=>'string|int', 'array'=>'array'],
    'krsort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
    'ksort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
    'labelObj::__construct' => ['void'],
    'labelObj::convertToString' => ['string'],
    'labelObj::deleteStyle' => ['int', 'index'=>'int'],
    'labelObj::free' => ['void'],
    'labelObj::getBinding' => ['string', 'labelbinding'=>'mixed'],
    'labelObj::getExpressionString' => ['string'],
    'labelObj::getStyle' => ['styleObj', 'index'=>'int'],
    'labelObj::getTextString' => ['string'],
    'labelObj::moveStyleDown' => ['int', 'index'=>'int'],
    'labelObj::moveStyleUp' => ['int', 'index'=>'int'],
    'labelObj::removeBinding' => ['int', 'labelbinding'=>'mixed'],
    'labelObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'labelObj::setBinding' => ['int', 'labelbinding'=>'mixed', 'value'=>'string'],
    'labelObj::setExpression' => ['int', 'expression'=>'string'],
    'labelObj::setText' => ['int', 'text'=>'string'],
    'labelObj::updateFromString' => ['int', 'snippet'=>'string'],
    'labelcacheObj::freeCache' => ['bool'],
    'layerObj::addFeature' => ['int', 'shape'=>'shapeObj'],
    'layerObj::applySLD' => ['int', 'sldxml'=>'string', 'namedlayer'=>'string'],
    'layerObj::applySLDURL' => ['int', 'sldurl'=>'string', 'namedlayer'=>'string'],
    'layerObj::clearProcessing' => ['void'],
    'layerObj::close' => ['void'],
    'layerObj::convertToString' => ['string'],
    'layerObj::draw' => ['int', 'image'=>'imageObj'],
    'layerObj::drawQuery' => ['int', 'image'=>'imageObj'],
    'layerObj::free' => ['void'],
    'layerObj::generateSLD' => ['string'],
    'layerObj::getClass' => ['classObj', 'classIndex'=>'int'],
    'layerObj::getClassIndex' => ['int', 'shape'=>'', 'classgroup'=>'', 'numclasses'=>''],
    'layerObj::getExtent' => ['rectObj'],
    'layerObj::getFilterString' => ['?string'],
    'layerObj::getGridIntersectionCoordinates' => ['array'],
    'layerObj::getItems' => ['array'],
    'layerObj::getMetaData' => ['int', 'name'=>'string'],
    'layerObj::getNumResults' => ['int'],
    'layerObj::getProcessing' => ['array'],
    'layerObj::getProjection' => ['string'],
    'layerObj::getResult' => ['resultObj', 'index'=>'int'],
    'layerObj::getResultsBounds' => ['rectObj'],
    'layerObj::getShape' => ['shapeObj', 'result'=>'resultObj'],
    'layerObj::getWMSFeatureInfoURL' => ['string', 'clickX'=>'int', 'clickY'=>'int', 'featureCount'=>'int', 'infoFormat'=>'string'],
    'layerObj::isVisible' => ['bool'],
    'layerObj::moveclassdown' => ['int', 'index'=>'int'],
    'layerObj::moveclassup' => ['int', 'index'=>'int'],
    'layerObj::ms_newLayerObj' => ['layerObj', 'map'=>'mapObj', 'layer'=>'layerObj'],
    'layerObj::nextShape' => ['shapeObj'],
    'layerObj::open' => ['int'],
    'layerObj::queryByAttributes' => ['int', 'qitem'=>'string', 'qstring'=>'string', 'mode'=>'int'],
    'layerObj::queryByFeatures' => ['int', 'slayer'=>'int'],
    'layerObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'],
    'layerObj::queryByRect' => ['int', 'rect'=>'rectObj'],
    'layerObj::queryByShape' => ['int', 'shape'=>'shapeObj'],
    'layerObj::removeClass' => ['?classObj', 'index'=>'int'],
    'layerObj::removeMetaData' => ['int', 'name'=>'string'],
    'layerObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'layerObj::setConnectionType' => ['int', 'connectiontype'=>'int', 'plugin_library'=>'string'],
    'layerObj::setFilter' => ['int', 'expression'=>'string'],
    'layerObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'],
    'layerObj::setProjection' => ['int', 'proj_params'=>'string'],
    'layerObj::setWKTProjection' => ['int', 'proj_params'=>'string'],
    'layerObj::updateFromString' => ['int', 'snippet'=>'string'],
    'lcfirst' => ['string', 'string'=>'string'],
    'lcg_value' => ['float'],
    'lchgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'],
    'lchown' => ['bool', 'filename'=>'string', 'user'=>'string|int'],
    'ldap_8859_to_t61' => ['string', 'value'=>'string'],
    'ldap_add' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
    'ldap_add_ext' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
    'ldap_bind' => ['bool', 'ldap'=>'resource', 'dn='=>'string|null', 'password='=>'string|null'],
    'ldap_bind_ext' => ['resource|false', 'ldap'=>'resource', 'dn='=>'string|null', 'password='=>'string|null', 'controls='=>'array'],
    'ldap_close' => ['bool', 'ldap'=>'resource'],
    'ldap_compare' => ['bool|int', 'ldap'=>'resource', 'dn'=>'string', 'attribute'=>'string', 'value'=>'string'],
    'ldap_connect' => ['resource|false', 'uri='=>'?string', 'port='=>'int', 'wallet='=>'string', 'password='=>'string', 'auth_mode='=>'int'],
    'ldap_control_paged_result' => ['bool', 'link_identifier'=>'resource', 'pagesize'=>'int', 'iscritical='=>'bool', 'cookie='=>'string'],
    'ldap_control_paged_result_response' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', '&w_cookie'=>'string', '&w_estimated'=>'int'],
    'ldap_count_entries' => ['int', 'ldap'=>'resource', 'result'=>'resource'],
    'ldap_delete' => ['bool', 'ldap'=>'resource', 'dn'=>'string'],
    'ldap_delete_ext' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'controls='=>'array'],
    'ldap_dn2ufn' => ['string', 'dn'=>'string'],
    'ldap_err2str' => ['string', 'errno'=>'int'],
    'ldap_errno' => ['int', 'ldap'=>'resource'],
    'ldap_error' => ['string', 'ldap'=>'resource'],
    'ldap_escape' => ['string', 'value'=>'string', 'ignore='=>'string', 'flags='=>'int'],
    'ldap_explode_dn' => ['array|false', 'dn'=>'string', 'with_attrib'=>'int'],
    'ldap_first_attribute' => ['string|false', 'ldap'=>'resource', 'entry'=>'resource'],
    'ldap_first_entry' => ['resource|false', 'ldap'=>'resource', 'result'=>'resource'],
    'ldap_first_reference' => ['resource|false', 'ldap'=>'resource', 'result'=>'resource'],
    'ldap_free_result' => ['bool', 'ldap'=>'resource'],
    'ldap_get_attributes' => ['array', 'ldap'=>'resource', 'entry'=>'resource'],
    'ldap_get_dn' => ['string|false', 'ldap'=>'resource', 'entry'=>'resource'],
    'ldap_get_entries' => ['array|false', 'ldap'=>'resource', 'result'=>'resource'],
    'ldap_get_option' => ['bool', 'ldap'=>'resource', 'option'=>'int', '&w_value'=>'mixed'],
    'ldap_get_values' => ['array|false', 'ldap'=>'resource', 'entry'=>'resource', 'attribute'=>'string'],
    'ldap_get_values_len' => ['array|false', 'ldap'=>'resource', 'entry'=>'resource', 'attribute'=>'string'],
    'ldap_list' => ['resource|false', 'ldap'=>'resource|array', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'],
    'ldap_mod_add' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
    'ldap_mod_add_ext' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
    'ldap_mod_del' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
    'ldap_mod_del_ext' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
    'ldap_mod_replace' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
    'ldap_mod_replace_ext' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
    'ldap_modify' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
    'ldap_modify_batch' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'modifications_info'=>'array'],
    'ldap_next_attribute' => ['string|false', 'ldap'=>'resource', 'entry'=>'resource'],
    'ldap_next_entry' => ['resource|false', 'ldap'=>'resource', 'result'=>'resource'],
    'ldap_next_reference' => ['resource|false', 'ldap'=>'resource', 'entry'=>'resource'],
    'ldap_parse_reference' => ['bool', 'ldap'=>'resource', 'entry'=>'resource', 'referrals'=>'array'],
    'ldap_parse_result' => ['bool', 'ldap'=>'resource', 'result'=>'resource', '&w_error_code'=>'int', '&w_matched_dn='=>'string', '&w_error_message='=>'string', '&w_referrals='=>'array', '&w_controls='=>'array'],
    'ldap_read' => ['resource|false', 'ldap'=>'resource|array', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'],
    'ldap_rename' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool'],
    'ldap_rename_ext' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'array'],
    'ldap_sasl_bind' => ['bool', 'ldap'=>'resource', 'dn='=>'string', 'password='=>'string', 'mech='=>'string', 'realm='=>'string', 'authc_id='=>'string', 'authz_id='=>'string', 'props='=>'string'],
    'ldap_search' => ['resource|false', 'ldap'=>'resource|resource[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'],
    'ldap_set_option' => ['bool', 'ldap'=>'resource|null', 'option'=>'int', 'value'=>'mixed'],
    'ldap_set_rebind_proc' => ['bool', 'ldap'=>'resource', 'callback'=>'callable'],
    'ldap_sort' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', 'sortfilter'=>'string'],
    'ldap_start_tls' => ['bool', 'ldap'=>'resource'],
    'ldap_t61_to_8859' => ['string', 'value'=>'string'],
    'ldap_unbind' => ['bool', 'ldap'=>'resource'],
    'leak' => ['', 'num_bytes'=>'int'],
    'leak_variable' => ['', 'variable'=>'', 'leak_data'=>'bool'],
    'legendObj::convertToString' => ['string'],
    'legendObj::free' => ['void'],
    'legendObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'legendObj::updateFromString' => ['int', 'snippet'=>'string'],
    'levenshtein' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'levenshtein\'1' => ['int', 'string1'=>'string', 'string2'=>'string', 'insertion_cost'=>'int', 'repetition_cost'=>'int', 'deletion_cost'=>'int'],
    'libxml_clear_errors' => ['void'],
    'libxml_disable_entity_loader' => ['bool', 'disable='=>'bool'],
    'libxml_get_errors' => ['list<LibXMLError>'],
    'libxml_get_last_error' => ['LibXMLError|false'],
    'libxml_set_external_entity_loader' => ['bool', 'resolver_function'=>'(callable(string,string,array{directory:?string,intSubName:?string,extSubURI:?string,extSubSystem:?string}):(resource|string|null))|null'],
    'libxml_set_streams_context' => ['void', 'context'=>'resource'],
    'libxml_use_internal_errors' => ['bool', 'use_errors='=>'bool'],
    'lineObj::__construct' => ['void'],
    'lineObj::add' => ['int', 'point'=>'pointObj'],
    'lineObj::addXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'],
    'lineObj::addXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'],
    'lineObj::ms_newLineObj' => ['lineObj'],
    'lineObj::point' => ['pointObj', 'i'=>'int'],
    'lineObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
    'link' => ['bool', 'target'=>'string', 'link'=>'string'],
    'linkinfo' => ['int|false', 'path'=>'string'],
    'litespeed_request_headers' => ['array'],
    'litespeed_response_headers' => ['array'],
    'locale_accept_from_http' => ['string|false', 'header'=>'string'],
    'locale_canonicalize' => ['?string', 'locale'=>'string'],
    'locale_compose' => ['string|false', 'subtags'=>'array'],
    'locale_filter_matches' => ['?bool', 'languageTag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'],
    'locale_get_all_variants' => ['?array', 'locale'=>'string'],
    'locale_get_default' => ['string'],
    'locale_get_display_language' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
    'locale_get_display_name' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
    'locale_get_display_region' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
    'locale_get_display_script' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
    'locale_get_display_variant' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
    'locale_get_keywords' => ['array|false|null', 'locale'=>'string'],
    'locale_get_primary_language' => ['?string', 'locale'=>'string'],
    'locale_get_region' => ['?string', 'locale'=>'string'],
    'locale_get_script' => ['?string', 'locale'=>'string'],
    'locale_lookup' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'string'],
    'locale_parse' => ['?array', 'locale'=>'string'],
    'locale_set_default' => ['bool', 'locale'=>'string'],
    'localeconv' => ['array'],
    'localtime' => ['array', 'timestamp='=>'int', 'associative='=>'bool'],
    'log' => ['float', 'num'=>'float', 'base='=>'float'],
    'log10' => ['float', 'num'=>'float'],
    'log1p' => ['float', 'num'=>'float'],
    'long2ip' => ['string', 'ip'=>'string|int'],
    'lstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'filename'=>'string'],
    'ltrim' => ['string', 'string'=>'string', 'characters='=>'string'],
    'lzf_compress' => ['string', 'data'=>'string'],
    'lzf_decompress' => ['string', 'data'=>'string'],
    'lzf_optimized_for' => ['int'],
    'm_checkstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
    'm_completeauthorizations' => ['int', 'conn'=>'resource', 'array'=>'int'],
    'm_connect' => ['int', 'conn'=>'resource'],
    'm_connectionerror' => ['string', 'conn'=>'resource'],
    'm_deletetrans' => ['bool', 'conn'=>'resource', 'identifier'=>'int'],
    'm_destroyconn' => ['bool', 'conn'=>'resource'],
    'm_destroyengine' => ['void'],
    'm_getcell' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'string', 'row'=>'int'],
    'm_getcellbynum' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'int', 'row'=>'int'],
    'm_getcommadelimited' => ['string', 'conn'=>'resource', 'identifier'=>'int'],
    'm_getheader' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column_num'=>'int'],
    'm_initconn' => ['resource'],
    'm_initengine' => ['int', 'location'=>'string'],
    'm_iscommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
    'm_maxconntimeout' => ['bool', 'conn'=>'resource', 'secs'=>'int'],
    'm_monitor' => ['int', 'conn'=>'resource'],
    'm_numcolumns' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
    'm_numrows' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
    'm_parsecommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
    'm_responsekeys' => ['array', 'conn'=>'resource', 'identifier'=>'int'],
    'm_responseparam' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string'],
    'm_returnstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
    'm_setblocking' => ['int', 'conn'=>'resource', 'tf'=>'int'],
    'm_setdropfile' => ['int', 'conn'=>'resource', 'directory'=>'string'],
    'm_setip' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'],
    'm_setssl' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'],
    'm_setssl_cafile' => ['int', 'conn'=>'resource', 'cafile'=>'string'],
    'm_setssl_files' => ['int', 'conn'=>'resource', 'sslkeyfile'=>'string', 'sslcertfile'=>'string'],
    'm_settimeout' => ['int', 'conn'=>'resource', 'seconds'=>'int'],
    'm_sslcert_gen_hash' => ['string', 'filename'=>'string'],
    'm_transactionssent' => ['int', 'conn'=>'resource'],
    'm_transinqueue' => ['int', 'conn'=>'resource'],
    'm_transkeyval' => ['int', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string', 'value'=>'string'],
    'm_transnew' => ['int', 'conn'=>'resource'],
    'm_transsend' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
    'm_uwait' => ['int', 'microsecs'=>'int'],
    'm_validateidentifier' => ['int', 'conn'=>'resource', 'tf'=>'int'],
    'm_verifyconnection' => ['bool', 'conn'=>'resource', 'tf'=>'int'],
    'm_verifysslcert' => ['bool', 'conn'=>'resource', 'tf'=>'int'],
    'magic_quotes_runtime' => ['bool', 'new_setting'=>'bool'],
    'mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array|null', 'additional_params='=>'string'],
    'mailparse_determine_best_xfer_encoding' => ['string', 'fp'=>'resource'],
    'mailparse_msg_create' => ['resource'],
    'mailparse_msg_extract_part' => ['void', 'mimemail'=>'resource', 'msgbody'=>'string', 'callbackfunc='=>'callable'],
    'mailparse_msg_extract_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'mixed', 'callbackfunc='=>'callable'],
    'mailparse_msg_extract_whole_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'string', 'callbackfunc='=>'callable'],
    'mailparse_msg_free' => ['bool', 'mimemail'=>'resource'],
    'mailparse_msg_get_part' => ['resource', 'mimemail'=>'resource', 'mimesection'=>'string'],
    'mailparse_msg_get_part_data' => ['array', 'mimemail'=>'resource'],
    'mailparse_msg_get_structure' => ['array', 'mimemail'=>'resource'],
    'mailparse_msg_parse' => ['bool', 'mimemail'=>'resource', 'data'=>'string'],
    'mailparse_msg_parse_file' => ['resource|false', 'filename'=>'string'],
    'mailparse_rfc822_parse_addresses' => ['array', 'addresses'=>'string'],
    'mailparse_stream_encode' => ['bool', 'sourcefp'=>'resource', 'destfp'=>'resource', 'encoding'=>'string'],
    'mailparse_uudecode_all' => ['array', 'fp'=>'resource'],
    'mapObj::__construct' => ['void', 'map_file_name'=>'string', 'new_map_path'=>'string'],
    'mapObj::appendOutputFormat' => ['int', 'outputFormat'=>'outputformatObj'],
    'mapObj::applySLD' => ['int', 'sldxml'=>'string'],
    'mapObj::applySLDURL' => ['int', 'sldurl'=>'string'],
    'mapObj::applyconfigoptions' => ['int'],
    'mapObj::convertToString' => ['string'],
    'mapObj::draw' => ['?imageObj'],
    'mapObj::drawLabelCache' => ['int', 'image'=>'imageObj'],
    'mapObj::drawLegend' => ['imageObj'],
    'mapObj::drawQuery' => ['?imageObj'],
    'mapObj::drawReferenceMap' => ['imageObj'],
    'mapObj::drawScaleBar' => ['imageObj'],
    'mapObj::embedLegend' => ['int', 'image'=>'imageObj'],
    'mapObj::embedScalebar' => ['int', 'image'=>'imageObj'],
    'mapObj::free' => ['void'],
    'mapObj::generateSLD' => ['string'],
    'mapObj::getAllGroupNames' => ['array'],
    'mapObj::getAllLayerNames' => ['array'],
    'mapObj::getColorbyIndex' => ['colorObj', 'iCloIndex'=>'int'],
    'mapObj::getConfigOption' => ['string', 'key'=>'string'],
    'mapObj::getLabel' => ['labelcacheMemberObj', 'index'=>'int'],
    'mapObj::getLayer' => ['layerObj', 'index'=>'int'],
    'mapObj::getLayerByName' => ['layerObj', 'layer_name'=>'string'],
    'mapObj::getLayersDrawingOrder' => ['array'],
    'mapObj::getLayersIndexByGroup' => ['array', 'groupname'=>'string'],
    'mapObj::getMetaData' => ['int', 'name'=>'string'],
    'mapObj::getNumSymbols' => ['int'],
    'mapObj::getOutputFormat' => ['?outputformatObj', 'index'=>'int'],
    'mapObj::getProjection' => ['string'],
    'mapObj::getSymbolByName' => ['int', 'symbol_name'=>'string'],
    'mapObj::getSymbolObjectById' => ['symbolObj', 'symbolid'=>'int'],
    'mapObj::loadMapContext' => ['int', 'filename'=>'string', 'unique_layer_name'=>'bool'],
    'mapObj::loadOWSParameters' => ['int', 'request'=>'OwsrequestObj', 'version'=>'string'],
    'mapObj::moveLayerDown' => ['int', 'layerindex'=>'int'],
    'mapObj::moveLayerUp' => ['int', 'layerindex'=>'int'],
    'mapObj::ms_newMapObjFromString' => ['mapObj', 'map_file_string'=>'string', 'new_map_path'=>'string'],
    'mapObj::offsetExtent' => ['int', 'x'=>'float', 'y'=>'float'],
    'mapObj::owsDispatch' => ['int', 'request'=>'OwsrequestObj'],
    'mapObj::prepareImage' => ['imageObj'],
    'mapObj::prepareQuery' => ['void'],
    'mapObj::processLegendTemplate' => ['string', 'params'=>'array'],
    'mapObj::processQueryTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'],
    'mapObj::processTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'],
    'mapObj::queryByFeatures' => ['int', 'slayer'=>'int'],
    'mapObj::queryByIndex' => ['int', 'layerindex'=>'', 'tileindex'=>'', 'shapeindex'=>'', 'addtoquery'=>''],
    'mapObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'],
    'mapObj::queryByRect' => ['int', 'rect'=>'rectObj'],
    'mapObj::queryByShape' => ['int', 'shape'=>'shapeObj'],
    'mapObj::removeLayer' => ['layerObj', 'nIndex'=>'int'],
    'mapObj::removeMetaData' => ['int', 'name'=>'string'],
    'mapObj::removeOutputFormat' => ['int', 'name'=>'string'],
    'mapObj::save' => ['int', 'filename'=>'string'],
    'mapObj::saveMapContext' => ['int', 'filename'=>'string'],
    'mapObj::saveQuery' => ['int', 'filename'=>'string', 'results'=>'int'],
    'mapObj::scaleExtent' => ['int', 'zoomfactor'=>'float', 'minscaledenom'=>'float', 'maxscaledenom'=>'float'],
    'mapObj::selectOutputFormat' => ['int', 'type'=>'string'],
    'mapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'mapObj::setCenter' => ['int', 'center'=>'pointObj'],
    'mapObj::setConfigOption' => ['int', 'key'=>'string', 'value'=>'string'],
    'mapObj::setExtent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'],
    'mapObj::setFontSet' => ['int', 'fileName'=>'string'],
    'mapObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'],
    'mapObj::setProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'],
    'mapObj::setRotation' => ['int', 'rotation_angle'=>'float'],
    'mapObj::setSize' => ['int', 'width'=>'int', 'height'=>'int'],
    'mapObj::setSymbolSet' => ['int', 'fileName'=>'string'],
    'mapObj::setWKTProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'],
    'mapObj::zoomPoint' => ['int', 'nZoomFactor'=>'int', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'],
    'mapObj::zoomRectangle' => ['int', 'oPixelExt'=>'rectObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'],
    'mapObj::zoomScale' => ['int', 'nScaleDenom'=>'float', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj', 'oMaxGeorefExt'=>'rectObj'],
    'max' => ['mixed', 'value'=>'non-empty-array'],
    'max\'1' => ['mixed', 'value'=>'', 'values'=>'', '...args='=>''],
    'maxdb::__construct' => ['void', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
    'maxdb::affected_rows' => ['int', 'link'=>''],
    'maxdb::auto_commit' => ['bool', 'link'=>'', 'mode'=>'bool'],
    'maxdb::change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'],
    'maxdb::character_set_name' => ['string', 'link'=>''],
    'maxdb::close' => ['bool', 'link'=>''],
    'maxdb::commit' => ['bool', 'link'=>''],
    'maxdb::disable_reads_from_master' => ['', 'link'=>''],
    'maxdb::errno' => ['int', 'link'=>''],
    'maxdb::error' => ['string', 'link'=>''],
    'maxdb::field_count' => ['int', 'link'=>''],
    'maxdb::get_host_info' => ['string', 'link'=>''],
    'maxdb::info' => ['string', 'link'=>''],
    'maxdb::insert_id' => ['', 'link'=>''],
    'maxdb::kill' => ['bool', 'link'=>'', 'processid'=>'int'],
    'maxdb::more_results' => ['bool', 'link'=>''],
    'maxdb::multi_query' => ['bool', 'link'=>'', 'query'=>'string'],
    'maxdb::next_result' => ['bool', 'link'=>''],
    'maxdb::num_rows' => ['int', 'result'=>''],
    'maxdb::options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''],
    'maxdb::ping' => ['bool', 'link'=>''],
    'maxdb::prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'],
    'maxdb::protocol_version' => ['string', 'link'=>''],
    'maxdb::query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'],
    'maxdb::real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
    'maxdb::real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'],
    'maxdb::real_query' => ['bool', 'link'=>'', 'query'=>'string'],
    'maxdb::rollback' => ['bool', 'link'=>''],
    'maxdb::rpl_query_type' => ['int', 'link'=>''],
    'maxdb::select_db' => ['bool', 'link'=>'', 'dbname'=>'string'],
    'maxdb::send_query' => ['bool', 'link'=>'', 'query'=>'string'],
    'maxdb::server_info' => ['string', 'link'=>''],
    'maxdb::server_version' => ['int', 'link'=>''],
    'maxdb::sqlstate' => ['string', 'link'=>''],
    'maxdb::ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'],
    'maxdb::stat' => ['string', 'link'=>''],
    'maxdb::stmt_init' => ['object', 'link'=>''],
    'maxdb::store_result' => ['bool', 'link'=>''],
    'maxdb::thread_id' => ['int', 'link'=>''],
    'maxdb::use_result' => ['resource', 'link'=>''],
    'maxdb::warning_count' => ['int', 'link'=>''],
    'maxdb_affected_rows' => ['int', 'link'=>'resource'],
    'maxdb_autocommit' => ['bool', 'link'=>'', 'mode'=>'bool'],
    'maxdb_change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'],
    'maxdb_character_set_name' => ['string', 'link'=>''],
    'maxdb_close' => ['bool', 'link'=>''],
    'maxdb_commit' => ['bool', 'link'=>''],
    'maxdb_connect' => ['resource', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
    'maxdb_connect_errno' => ['int'],
    'maxdb_connect_error' => ['string'],
    'maxdb_data_seek' => ['bool', 'result'=>'', 'offset'=>'int'],
    'maxdb_debug' => ['void', 'debug'=>'string'],
    'maxdb_disable_reads_from_master' => ['', 'link'=>''],
    'maxdb_disable_rpl_parse' => ['bool', 'link'=>'resource'],
    'maxdb_dump_debug_info' => ['bool', 'link'=>'resource'],
    'maxdb_embedded_connect' => ['resource', 'dbname='=>'string'],
    'maxdb_enable_reads_from_master' => ['bool', 'link'=>'resource'],
    'maxdb_enable_rpl_parse' => ['bool', 'link'=>'resource'],
    'maxdb_errno' => ['int', 'link'=>'resource'],
    'maxdb_error' => ['string', 'link'=>'resource'],
    'maxdb_fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'],
    'maxdb_fetch_assoc' => ['array', 'result'=>''],
    'maxdb_fetch_field' => ['', 'result'=>''],
    'maxdb_fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'],
    'maxdb_fetch_fields' => ['', 'result'=>''],
    'maxdb_fetch_lengths' => ['array', 'result'=>'resource'],
    'maxdb_fetch_object' => ['object', 'result'=>'object'],
    'maxdb_fetch_row' => ['', 'result'=>''],
    'maxdb_field_count' => ['int', 'link'=>''],
    'maxdb_field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'],
    'maxdb_field_tell' => ['int', 'result'=>'resource'],
    'maxdb_free_result' => ['', 'result'=>''],
    'maxdb_get_client_info' => ['string'],
    'maxdb_get_client_version' => ['int'],
    'maxdb_get_host_info' => ['string', 'link'=>'resource'],
    'maxdb_get_proto_info' => ['string', 'link'=>'resource'],
    'maxdb_get_server_info' => ['string', 'link'=>'resource'],
    'maxdb_get_server_version' => ['int', 'link'=>'resource'],
    'maxdb_info' => ['string', 'link'=>'resource'],
    'maxdb_init' => ['resource'],
    'maxdb_insert_id' => ['mixed', 'link'=>'resource'],
    'maxdb_kill' => ['bool', 'link'=>'', 'processid'=>'int'],
    'maxdb_master_query' => ['bool', 'link'=>'resource', 'query'=>'string'],
    'maxdb_more_results' => ['bool', 'link'=>'resource'],
    'maxdb_multi_query' => ['bool', 'link'=>'', 'query'=>'string'],
    'maxdb_next_result' => ['bool', 'link'=>'resource'],
    'maxdb_num_fields' => ['int', 'result'=>'resource'],
    'maxdb_num_rows' => ['int', 'result'=>'resource'],
    'maxdb_options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''],
    'maxdb_ping' => ['bool', 'link'=>''],
    'maxdb_prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'],
    'maxdb_query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'],
    'maxdb_real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
    'maxdb_real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'],
    'maxdb_real_query' => ['bool', 'link'=>'', 'query'=>'string'],
    'maxdb_report' => ['bool', 'flags'=>'int'],
    'maxdb_result::current_field' => ['int', 'result'=>''],
    'maxdb_result::data_seek' => ['bool', 'result'=>'', 'offset'=>'int'],
    'maxdb_result::fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'],
    'maxdb_result::fetch_assoc' => ['array', 'result'=>''],
    'maxdb_result::fetch_field' => ['', 'result'=>''],
    'maxdb_result::fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'],
    'maxdb_result::fetch_fields' => ['', 'result'=>''],
    'maxdb_result::fetch_object' => ['object', 'result'=>'object'],
    'maxdb_result::fetch_row' => ['', 'result'=>''],
    'maxdb_result::field_count' => ['int', 'result'=>''],
    'maxdb_result::field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'],
    'maxdb_result::free' => ['', 'result'=>''],
    'maxdb_result::lengths' => ['array', 'result'=>''],
    'maxdb_rollback' => ['bool', 'link'=>''],
    'maxdb_rpl_parse_enabled' => ['int', 'link'=>'resource'],
    'maxdb_rpl_probe' => ['bool', 'link'=>'resource'],
    'maxdb_rpl_query_type' => ['int', 'link'=>''],
    'maxdb_select_db' => ['bool', 'link'=>'resource', 'dbname'=>'string'],
    'maxdb_send_query' => ['bool', 'link'=>'', 'query'=>'string'],
    'maxdb_server_end' => ['void'],
    'maxdb_server_init' => ['bool', 'server='=>'array', 'groups='=>'array'],
    'maxdb_sqlstate' => ['string', 'link'=>'resource'],
    'maxdb_ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'],
    'maxdb_stat' => ['string', 'link'=>''],
    'maxdb_stmt::affected_rows' => ['int', 'stmt'=>''],
    'maxdb_stmt::bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', '&...rw_var'=>''],
    'maxdb_stmt::bind_param\'1' => ['bool', 'stmt'=>'', 'types'=>'string', '&rw_var'=>'array'],
    'maxdb_stmt::bind_result' => ['bool', 'stmt'=>'', '&w_var1'=>'', '&...w_vars='=>''],
    'maxdb_stmt::close' => ['bool', 'stmt'=>''],
    'maxdb_stmt::close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'],
    'maxdb_stmt::data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'],
    'maxdb_stmt::errno' => ['int', 'stmt'=>''],
    'maxdb_stmt::error' => ['string', 'stmt'=>''],
    'maxdb_stmt::execute' => ['bool', 'stmt'=>''],
    'maxdb_stmt::fetch' => ['bool', 'stmt'=>''],
    'maxdb_stmt::free_result' => ['', 'stmt'=>''],
    'maxdb_stmt::num_rows' => ['int', 'stmt'=>''],
    'maxdb_stmt::param_count' => ['int', 'stmt'=>''],
    'maxdb_stmt::prepare' => ['', 'stmt'=>'', 'query'=>'string'],
    'maxdb_stmt::reset' => ['bool', 'stmt'=>''],
    'maxdb_stmt::result_metadata' => ['resource', 'stmt'=>''],
    'maxdb_stmt::send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'],
    'maxdb_stmt::stmt_send_long_data' => ['bool', 'param_nr'=>'int', 'data'=>'string'],
    'maxdb_stmt::store_result' => ['bool'],
    'maxdb_stmt_affected_rows' => ['int', 'stmt'=>'resource'],
    'maxdb_stmt_bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', 'var1'=>'', '...args='=>'', 'var='=>'array'],
    'maxdb_stmt_bind_result' => ['bool', 'stmt'=>'', '&w_var1'=>'', '&...w_vars='=>''],
    'maxdb_stmt_close' => ['bool', 'stmt'=>''],
    'maxdb_stmt_close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'],
    'maxdb_stmt_data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'],
    'maxdb_stmt_errno' => ['int', 'stmt'=>'resource'],
    'maxdb_stmt_error' => ['string', 'stmt'=>'resource'],
    'maxdb_stmt_execute' => ['bool', 'stmt'=>''],
    'maxdb_stmt_fetch' => ['bool', 'stmt'=>''],
    'maxdb_stmt_free_result' => ['', 'stmt'=>''],
    'maxdb_stmt_init' => ['object', 'link'=>''],
    'maxdb_stmt_num_rows' => ['int', 'stmt'=>'resource'],
    'maxdb_stmt_param_count' => ['int', 'stmt'=>'resource'],
    'maxdb_stmt_prepare' => ['', 'stmt'=>'', 'query'=>'string'],
    'maxdb_stmt_reset' => ['bool', 'stmt'=>''],
    'maxdb_stmt_result_metadata' => ['resource', 'stmt'=>''],
    'maxdb_stmt_send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'],
    'maxdb_stmt_sqlstate' => ['string', 'stmt'=>'resource'],
    'maxdb_stmt_store_result' => ['bool', 'stmt'=>''],
    'maxdb_store_result' => ['bool', 'link'=>''],
    'maxdb_thread_id' => ['int', 'link'=>'resource'],
    'maxdb_thread_safe' => ['bool'],
    'maxdb_use_result' => ['resource', 'link'=>''],
    'maxdb_warning_count' => ['int', 'link'=>'resource'],
    'mb_check_encoding' => ['bool', 'value='=>'string', 'encoding='=>'string'],
    'mb_convert_case' => ['string', 'string'=>'string', 'mode'=>'int', 'encoding='=>'string'],
    'mb_convert_encoding' => ['string|false', 'string'=>'string', 'to_encoding'=>'string', 'from_encoding='=>'mixed'],
    'mb_convert_kana' => ['string', 'string'=>'string', 'mode='=>'string', 'encoding='=>'string'],
    'mb_convert_variables' => ['string|false', 'to_encoding'=>'string', 'from_encoding'=>'array|string', '&rw_var'=>'string|array|object', '&...rw_vars='=>'string|array|object'],
    'mb_decode_mimeheader' => ['string', 'string'=>'string'],
    'mb_decode_numericentity' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string'],
    'mb_detect_encoding' => ['string|false', 'string'=>'string', 'encodings='=>'mixed', 'strict='=>'bool'],
    'mb_detect_order' => ['bool|list<string>', 'encoding='=>'mixed'],
    'mb_encode_mimeheader' => ['string', 'string'=>'string', 'charset='=>'string', 'transfer_encoding='=>'string', 'newline='=>'string', 'indent='=>'int'],
    'mb_encode_numericentity' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string', 'hex='=>'bool'],
    'mb_encoding_aliases' => ['list<string>|false', 'encoding'=>'string'],
    'mb_ereg' => ['int|false', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array|null'],
    'mb_ereg_match' => ['bool', 'pattern'=>'string', 'string'=>'string', 'options='=>'string'],
    'mb_ereg_replace' => ['string|false', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string'],
    'mb_ereg_replace_callback' => ['string|false|null', 'pattern'=>'string', 'callback'=>'callable', 'string'=>'string', 'options='=>'string'],
    'mb_ereg_search' => ['bool', 'pattern='=>'string', 'options='=>'string'],
    'mb_ereg_search_getpos' => ['int'],
    'mb_ereg_search_getregs' => ['string[]|false'],
    'mb_ereg_search_init' => ['bool', 'string'=>'string', 'pattern='=>'string', 'options='=>'string'],
    'mb_ereg_search_pos' => ['int[]|false', 'pattern='=>'string', 'options='=>'string'],
    'mb_ereg_search_regs' => ['string[]|false', 'pattern='=>'string', 'options='=>'string'],
    'mb_ereg_search_setpos' => ['bool', 'offset'=>'int'],
    'mb_eregi' => ['int|false', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array'],
    'mb_eregi_replace' => ['string|false', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string'],
    'mb_get_info' => ['array|string|int|false', 'type='=>'string'],
    'mb_http_input' => ['string|false', 'type='=>'string'],
    'mb_http_output' => ['string|bool', 'encoding='=>'string'],
    'mb_internal_encoding' => ['string|bool', 'encoding='=>'string'],
    'mb_language' => ['string|bool', 'language='=>'string'],
    'mb_list_encodings' => ['list<string>'],
    'mb_output_handler' => ['string', 'string'=>'string', 'status'=>'int'],
    'mb_parse_str' => ['bool', 'string'=>'string', '&w_result='=>'array'],
    'mb_preferred_mime_name' => ['string|false', 'encoding'=>'string'],
    'mb_regex_encoding' => ['string|bool', 'encoding='=>'string'],
    'mb_regex_set_options' => ['string', 'options='=>'string'],
    'mb_send_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array', 'additional_params='=>'string'],
    'mb_split' => ['list<string>|false', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'],
    'mb_strcut' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'],
    'mb_strimwidth' => ['string', 'string'=>'string', 'start'=>'int', 'width'=>'int', 'trim_marker='=>'string', 'encoding='=>'string'],
    'mb_stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
    'mb_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
    'mb_strlen' => ['0|positive-int', 'string'=>'string', 'encoding='=>'string'],
    'mb_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
    'mb_strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
    'mb_strrichr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
    'mb_strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
    'mb_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
    'mb_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
    'mb_strtolower' => ['lowercase-string', 'string'=>'string', 'encoding='=>'string'],
    'mb_strtoupper' => ['string', 'string'=>'string', 'encoding='=>'string'],
    'mb_strwidth' => ['int', 'string'=>'string', 'encoding='=>'string'],
    'mb_substitute_character' => ['bool|int|string', 'substitute_character='=>'mixed'],
    'mb_substr' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'],
    'mb_substr_count' => ['int', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string'],
    'mcrypt_cbc' => ['string', 'cipher'=>'string|int', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
    'mcrypt_cfb' => ['string', 'cipher'=>'string|int', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
    'mcrypt_create_iv' => ['string|false', 'size'=>'int', 'source='=>'int'],
    'mcrypt_decrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'],
    'mcrypt_ecb' => ['string', 'cipher'=>'string|int', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
    'mcrypt_enc_get_algorithms_name' => ['string', 'td'=>'resource'],
    'mcrypt_enc_get_block_size' => ['int', 'td'=>'resource'],
    'mcrypt_enc_get_iv_size' => ['int', 'td'=>'resource'],
    'mcrypt_enc_get_key_size' => ['int', 'td'=>'resource'],
    'mcrypt_enc_get_modes_name' => ['string', 'td'=>'resource'],
    'mcrypt_enc_get_supported_key_sizes' => ['array', 'td'=>'resource'],
    'mcrypt_enc_is_block_algorithm' => ['bool', 'td'=>'resource'],
    'mcrypt_enc_is_block_algorithm_mode' => ['bool', 'td'=>'resource'],
    'mcrypt_enc_is_block_mode' => ['bool', 'td'=>'resource'],
    'mcrypt_enc_self_test' => ['int|false', 'td'=>'resource'],
    'mcrypt_encrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'],
    'mcrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'],
    'mcrypt_generic_deinit' => ['bool', 'td'=>'resource'],
    'mcrypt_generic_end' => ['bool', 'td'=>'resource'],
    'mcrypt_generic_init' => ['int|false', 'td'=>'resource', 'key'=>'string', 'iv'=>'string'],
    'mcrypt_get_block_size' => ['int', 'cipher'=>'int|string', 'module'=>'string'],
    'mcrypt_get_cipher_name' => ['string|false', 'cipher'=>'int|string'],
    'mcrypt_get_iv_size' => ['int|false', 'cipher'=>'int|string', 'module'=>'string'],
    'mcrypt_get_key_size' => ['int', 'cipher'=>'int|string', 'module'=>'string'],
    'mcrypt_list_algorithms' => ['array', 'lib_dir='=>'string'],
    'mcrypt_list_modes' => ['array', 'lib_dir='=>'string'],
    'mcrypt_module_close' => ['bool', 'td'=>'resource'],
    'mcrypt_module_get_algo_block_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'],
    'mcrypt_module_get_algo_key_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'],
    'mcrypt_module_get_supported_key_sizes' => ['array', 'algorithm'=>'string', 'lib_dir='=>'string'],
    'mcrypt_module_is_block_algorithm' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'],
    'mcrypt_module_is_block_algorithm_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'],
    'mcrypt_module_is_block_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'],
    'mcrypt_module_open' => ['resource|false', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'],
    'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'],
    'mcrypt_ofb' => ['string', 'cipher'=>'int|string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
    'md5' => ['non-falsy-string', 'string'=>'string', 'binary='=>'bool'],
    'md5_file' => ['non-falsy-string|false', 'filename'=>'string', 'binary='=>'bool'],
    'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'],
    'memcache_add' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'memcache_add_server' => ['bool', 'memcache_obj'=>'Memcache', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'],
    'memcache_append' => ['', 'memcache_obj'=>'Memcache'],
    'memcache_cas' => ['', 'memcache_obj'=>'Memcache'],
    'memcache_close' => ['bool', 'memcache_obj'=>'Memcache'],
    'memcache_connect' => ['Memcache|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
    'memcache_debug' => ['bool', 'on_off'=>'bool'],
    'memcache_decrement' => ['int', 'memcache_obj'=>'Memcache', 'key'=>'string', 'value='=>'int'],
    'memcache_delete' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'timeout='=>'int'],
    'memcache_flush' => ['bool', 'memcache_obj'=>'Memcache'],
    'memcache_get' => ['string', 'memcache_obj'=>'Memcache', 'key'=>'string', 'flags='=>'int'],
    'memcache_get\'1' => ['array', 'memcache_obj'=>'Memcache', 'key'=>'string[]', 'flags='=>'int[]'],
    'memcache_get_extended_stats' => ['array', 'memcache_obj'=>'Memcache', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
    'memcache_get_server_status' => ['int', 'memcache_obj'=>'Memcache', 'host'=>'string', 'port='=>'int'],
    'memcache_get_stats' => ['array', 'memcache_obj'=>'Memcache', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
    'memcache_get_version' => ['string', 'memcache_obj'=>'Memcache'],
    'memcache_increment' => ['int', 'memcache_obj'=>'Memcache', 'key'=>'string', 'value='=>'int'],
    'memcache_pconnect' => ['Memcache|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
    'memcache_prepend' => ['string', 'memcache_obj'=>'Memcache'],
    'memcache_replace' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'memcache_set' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
    'memcache_set_compress_threshold' => ['bool', 'memcache_obj'=>'Memcache', 'threshold'=>'int', 'min_savings='=>'float'],
    'memcache_set_failure_callback' => ['', 'memcache_obj'=>'Memcache'],
    'memcache_set_server_params' => ['bool', 'memcache_obj'=>'Memcache', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable'],
    'memory_get_peak_usage' => ['int', 'real_usage='=>'bool'],
    'memory_get_usage' => ['int', 'real_usage='=>'bool'],
    'metaphone' => ['string|false', 'string'=>'string', 'max_phonemes='=>'int'],
    'method_exists' => ['bool', 'object_or_class'=>'object|class-string|interface-string|enum-string', 'method'=>'string'],
    'mhash' => ['string', 'algo'=>'int', 'data'=>'string', 'key='=>'string'],
    'mhash_count' => ['int'],
    'mhash_get_block_size' => ['int|false', 'algo'=>'int'],
    'mhash_get_hash_name' => ['string|false', 'algo'=>'int'],
    'mhash_keygen_s2k' => ['string|false', 'algo'=>'int', 'password'=>'string', 'salt'=>'string', 'length'=>'int'],
    'microtime' => ['string', 'as_float='=>'false'],
    'microtime\'1' => ['float', 'as_float='=>'true'],
    'mime_content_type' => ['string|false', 'filename'=>'string|resource'],
    'min' => ['mixed', 'value'=>'non-empty-array'],
    'min\'1' => ['mixed', 'value'=>'', 'values'=>'', '...args='=>''],
    'ming_keypress' => ['int', 'char'=>'string'],
    'ming_setcubicthreshold' => ['void', 'threshold'=>'int'],
    'ming_setscale' => ['void', 'scale'=>'float'],
    'ming_setswfcompression' => ['void', 'level'=>'int'],
    'ming_useconstants' => ['void', 'use'=>'int'],
    'ming_useswfversion' => ['void', 'version'=>'int'],
    'mkdir' => ['bool', 'directory'=>'string', 'permissions='=>'int', 'recursive='=>'bool', 'context='=>'resource'],
    'mktime' => ['int|false', 'hour='=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'],
    'money_format' => ['string', 'format'=>'string', 'value'=>'float'],
    'monitor_custom_event' => ['void', 'class'=>'string', 'text'=>'string', 'severe='=>'int', 'user_data='=>'mixed'],
    'monitor_httperror_event' => ['void', 'error_code'=>'int', 'url'=>'string', 'severe='=>'int'],
    'monitor_license_info' => ['array'],
    'monitor_pass_error' => ['void', 'errno'=>'int', 'errstr'=>'string', 'errfile'=>'string', 'errline'=>'int'],
    'monitor_set_aggregation_hint' => ['void', 'hint'=>'string'],
    'move_uploaded_file' => ['bool', 'from'=>'string', 'to'=>'string'],
    'mqseries_back' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_begin' => ['void', 'hconn'=>'resource', 'beginoptions'=>'array', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_close' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'options'=>'int', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_cmit' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_conn' => ['void', 'qmanagername'=>'string', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_connx' => ['void', 'qmanagername'=>'string', 'connoptions'=>'array', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_disc' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_get' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'gmo'=>'array', 'bufferlength'=>'int', 'msg'=>'string', 'data_length'=>'int', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_inq' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattr'=>'resource', 'charattrlength'=>'int', 'charattr'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_open' => ['void', 'hconn'=>'resource', 'objdesc'=>'array', 'option'=>'int', 'hobj'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_put' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'pmo'=>'array', 'message'=>'string', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_put1' => ['void', 'hconn'=>'resource', 'objdesc'=>'resource', 'msgdesc'=>'resource', 'pmo'=>'resource', 'buffer'=>'string', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_set' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattrs'=>'array', 'charattrlength'=>'int', 'charattrs'=>'array', 'compcode'=>'resource', 'reason'=>'resource'],
    'mqseries_strerror' => ['string', 'reason'=>'int'],
    'ms_GetErrorObj' => ['errorObj'],
    'ms_GetVersion' => ['string'],
    'ms_GetVersionInt' => ['int'],
    'ms_ResetErrorList' => ['void'],
    'ms_TokenizeMap' => ['array', 'map_file_name'=>'string'],
    'ms_iogetStdoutBufferBytes' => ['int'],
    'ms_iogetstdoutbufferstring' => ['void'],
    'ms_ioinstallstdinfrombuffer' => ['void'],
    'ms_ioinstallstdouttobuffer' => ['void'],
    'ms_ioresethandlers' => ['void'],
    'ms_iostripstdoutbuffercontentheaders' => ['void'],
    'ms_iostripstdoutbuffercontenttype' => ['string'],
    'msession_connect' => ['bool', 'host'=>'string', 'port'=>'string'],
    'msession_count' => ['int'],
    'msession_create' => ['bool', 'session'=>'string', 'classname='=>'string', 'data='=>'string'],
    'msession_destroy' => ['bool', 'name'=>'string'],
    'msession_disconnect' => ['void'],
    'msession_find' => ['array', 'name'=>'string', 'value'=>'string'],
    'msession_get' => ['string', 'session'=>'string', 'name'=>'string', 'value'=>'string'],
    'msession_get_array' => ['array', 'session'=>'string'],
    'msession_get_data' => ['string', 'session'=>'string'],
    'msession_inc' => ['string', 'session'=>'string', 'name'=>'string'],
    'msession_list' => ['array'],
    'msession_listvar' => ['array', 'name'=>'string'],
    'msession_lock' => ['int', 'name'=>'string'],
    'msession_plugin' => ['string', 'session'=>'string', 'value'=>'string', 'param='=>'string'],
    'msession_randstr' => ['string', 'param'=>'int'],
    'msession_set' => ['bool', 'session'=>'string', 'name'=>'string', 'value'=>'string'],
    'msession_set_array' => ['void', 'session'=>'string', 'tuples'=>'array'],
    'msession_set_data' => ['bool', 'session'=>'string', 'value'=>'string'],
    'msession_timeout' => ['int', 'session'=>'string', 'param='=>'int'],
    'msession_uniq' => ['string', 'param'=>'int', 'classname='=>'string', 'data='=>'string'],
    'msession_unlock' => ['int', 'session'=>'string', 'key'=>'int'],
    'msg_get_queue' => ['resource|false', 'key'=>'int', 'permissions='=>'int'],
    'msg_queue_exists' => ['bool', 'key'=>'int'],
    'msg_receive' => ['bool', 'queue'=>'resource', 'desired_message_type'=>'int', '&w_received_message_type'=>'int', 'max_message_size'=>'int', '&w_message'=>'mixed', 'unserialize='=>'bool', 'flags='=>'int', '&w_error_code='=>'int'],
    'msg_remove_queue' => ['bool', 'queue'=>'resource'],
    'msg_send' => ['bool', 'queue'=>'resource', 'message_type'=>'int', 'message'=>'mixed', 'serialize='=>'bool', 'blocking='=>'bool', '&w_error_code='=>'int'],
    'msg_set_queue' => ['bool', 'queue'=>'resource', 'data'=>'array'],
    'msg_stat_queue' => ['array', 'queue'=>'resource'],
    'msgfmt_create' => ['?MessageFormatter', 'locale'=>'string', 'pattern'=>'string'],
    'msgfmt_format' => ['string|false', 'formatter'=>'MessageFormatter', 'values'=>'array'],
    'msgfmt_format_message' => ['string|false', 'locale'=>'string', 'pattern'=>'string', 'values'=>'array'],
    'msgfmt_get_error_code' => ['int', 'formatter'=>'MessageFormatter'],
    'msgfmt_get_error_message' => ['string', 'formatter'=>'MessageFormatter'],
    'msgfmt_get_locale' => ['string', 'formatter'=>'MessageFormatter'],
    'msgfmt_get_pattern' => ['string', 'formatter'=>'MessageFormatter'],
    'msgfmt_parse' => ['array|false', 'formatter'=>'MessageFormatter', 'string'=>'string'],
    'msgfmt_parse_message' => ['array|false', 'locale'=>'string', 'pattern'=>'string', 'message'=>'string'],
    'msgfmt_set_pattern' => ['bool', 'formatter'=>'MessageFormatter', 'pattern'=>'string'],
    'msql_affected_rows' => ['int', 'result'=>'resource'],
    'msql_close' => ['bool', 'link_identifier='=>'?resource'],
    'msql_connect' => ['resource', 'hostname='=>'string'],
    'msql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
    'msql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'],
    'msql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'],
    'msql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
    'msql_error' => ['string'],
    'msql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'],
    'msql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'],
    'msql_fetch_object' => ['object', 'result'=>'resource'],
    'msql_fetch_row' => ['array', 'result'=>'resource'],
    'msql_field_flags' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
    'msql_field_len' => ['int', 'result'=>'resource', 'field_offset'=>'int'],
    'msql_field_name' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
    'msql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'],
    'msql_field_table' => ['int', 'result'=>'resource', 'field_offset'=>'int'],
    'msql_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
    'msql_free_result' => ['bool', 'result'=>'resource'],
    'msql_list_dbs' => ['resource', 'link_identifier='=>'?resource'],
    'msql_list_fields' => ['resource', 'database'=>'string', 'tablename'=>'string', 'link_identifier='=>'?resource'],
    'msql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'],
    'msql_num_fields' => ['int', 'result'=>'resource'],
    'msql_num_rows' => ['int', 'query_identifier'=>'resource'],
    'msql_pconnect' => ['resource', 'hostname='=>'string'],
    'msql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource'],
    'msql_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'],
    'msql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
    'mt_getrandmax' => ['int'],
    'mt_rand' => ['int', 'min'=>'int', 'max'=>'int'],
    'mt_rand\'1' => ['int'],
    'mt_srand' => ['void', 'seed='=>'int', 'mode='=>'int'],
    'mysql_xdevapi\baseresult::getWarnings' => ['array'],
    'mysql_xdevapi\baseresult::getWarningsCount' => ['integer'],
    'mysql_xdevapi\collection::add' => ['mysql_xdevapi\CollectionAdd', 'document'=>'mixed'],
    'mysql_xdevapi\collection::addOrReplaceOne' => ['mysql_xdevapi\Result', 'id'=>'string', 'doc'=>'string'],
    'mysql_xdevapi\collection::count' => ['integer'],
    'mysql_xdevapi\collection::createIndex' => ['void', 'index_name'=>'string', 'index_desc_json'=>'string'],
    'mysql_xdevapi\collection::dropIndex' => ['bool', 'index_name'=>'string'],
    'mysql_xdevapi\collection::existsInDatabase' => ['bool'],
    'mysql_xdevapi\collection::find' => ['mysql_xdevapi\CollectionFind', 'search_condition='=>'string'],
    'mysql_xdevapi\collection::getName' => ['string'],
    'mysql_xdevapi\collection::getOne' => ['Document', 'id'=>'string'],
    'mysql_xdevapi\collection::getSchema' => ['mysql_xdevapi\schema'],
    'mysql_xdevapi\collection::getSession' => ['Session'],
    'mysql_xdevapi\collection::modify' => ['mysql_xdevapi\CollectionModify', 'search_condition'=>'string'],
    'mysql_xdevapi\collection::remove' => ['mysql_xdevapi\CollectionRemove', 'search_condition'=>'string'],
    'mysql_xdevapi\collection::removeOne' => ['mysql_xdevapi\Result', 'id'=>'string'],
    'mysql_xdevapi\collection::replaceOne' => ['mysql_xdevapi\Result', 'id'=>'string', 'doc'=>'string'],
    'mysql_xdevapi\collectionadd::execute' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\collectionfind::bind' => ['mysql_xdevapi\CollectionFind', 'placeholder_values'=>'array'],
    'mysql_xdevapi\collectionfind::execute' => ['mysql_xdevapi\DocResult'],
    'mysql_xdevapi\collectionfind::fields' => ['mysql_xdevapi\CollectionFind', 'projection'=>'string'],
    'mysql_xdevapi\collectionfind::groupBy' => ['mysql_xdevapi\CollectionFind', 'sort_expr'=>'string'],
    'mysql_xdevapi\collectionfind::having' => ['mysql_xdevapi\CollectionFind', 'sort_expr'=>'string'],
    'mysql_xdevapi\collectionfind::limit' => ['mysql_xdevapi\CollectionFind', 'rows'=>'integer'],
    'mysql_xdevapi\collectionfind::lockExclusive' => ['mysql_xdevapi\CollectionFind', 'lock_waiting_option='=>'integer'],
    'mysql_xdevapi\collectionfind::lockShared' => ['mysql_xdevapi\CollectionFind', 'lock_waiting_option='=>'integer'],
    'mysql_xdevapi\collectionfind::offset' => ['mysql_xdevapi\CollectionFind', 'position'=>'integer'],
    'mysql_xdevapi\collectionfind::sort' => ['mysql_xdevapi\CollectionFind', 'sort_expr'=>'string'],
    'mysql_xdevapi\collectionmodify::arrayAppend' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
    'mysql_xdevapi\collectionmodify::arrayInsert' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
    'mysql_xdevapi\collectionmodify::bind' => ['mysql_xdevapi\CollectionModify', 'placeholder_values'=>'array'],
    'mysql_xdevapi\collectionmodify::execute' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\collectionmodify::limit' => ['mysql_xdevapi\CollectionModify', 'rows'=>'integer'],
    'mysql_xdevapi\collectionmodify::patch' => ['mysql_xdevapi\CollectionModify', 'document'=>'string'],
    'mysql_xdevapi\collectionmodify::replace' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
    'mysql_xdevapi\collectionmodify::set' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
    'mysql_xdevapi\collectionmodify::skip' => ['mysql_xdevapi\CollectionModify', 'position'=>'integer'],
    'mysql_xdevapi\collectionmodify::sort' => ['mysql_xdevapi\CollectionModify', 'sort_expr'=>'string'],
    'mysql_xdevapi\collectionmodify::unset' => ['mysql_xdevapi\CollectionModify', 'fields'=>'array'],
    'mysql_xdevapi\collectionremove::bind' => ['mysql_xdevapi\CollectionRemove', 'placeholder_values'=>'array'],
    'mysql_xdevapi\collectionremove::execute' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\collectionremove::limit' => ['mysql_xdevapi\CollectionRemove', 'rows'=>'integer'],
    'mysql_xdevapi\collectionremove::sort' => ['mysql_xdevapi\CollectionRemove', 'sort_expr'=>'string'],
    'mysql_xdevapi\columnresult::getCharacterSetName' => ['string'],
    'mysql_xdevapi\columnresult::getCollationName' => ['string'],
    'mysql_xdevapi\columnresult::getColumnLabel' => ['string'],
    'mysql_xdevapi\columnresult::getColumnName' => ['string'],
    'mysql_xdevapi\columnresult::getFractionalDigits' => ['integer'],
    'mysql_xdevapi\columnresult::getLength' => ['integer'],
    'mysql_xdevapi\columnresult::getSchemaName' => ['string'],
    'mysql_xdevapi\columnresult::getTableLabel' => ['string'],
    'mysql_xdevapi\columnresult::getTableName' => ['string'],
    'mysql_xdevapi\columnresult::getType' => ['integer'],
    'mysql_xdevapi\columnresult::isNumberSigned' => ['integer'],
    'mysql_xdevapi\columnresult::isPadded' => ['integer'],
    'mysql_xdevapi\crudoperationbindable::bind' => ['mysql_xdevapi\CrudOperationBindable', 'placeholder_values'=>'array'],
    'mysql_xdevapi\crudoperationlimitable::limit' => ['mysql_xdevapi\CrudOperationLimitable', 'rows'=>'integer'],
    'mysql_xdevapi\crudoperationskippable::skip' => ['mysql_xdevapi\CrudOperationSkippable', 'skip'=>'integer'],
    'mysql_xdevapi\crudoperationsortable::sort' => ['mysql_xdevapi\CrudOperationSortable', 'sort_expr'=>'string'],
    'mysql_xdevapi\databaseobject::existsInDatabase' => ['bool'],
    'mysql_xdevapi\databaseobject::getName' => ['string'],
    'mysql_xdevapi\databaseobject::getSession' => ['mysql_xdevapi\Session'],
    'mysql_xdevapi\docresult::fetchAll' => ['Array'],
    'mysql_xdevapi\docresult::fetchOne' => ['Object'],
    'mysql_xdevapi\docresult::getWarnings' => ['Array'],
    'mysql_xdevapi\docresult::getWarningsCount' => ['integer'],
    'mysql_xdevapi\executable::execute' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\getsession' => ['mysql_xdevapi\Session', 'uri'=>'string'],
    'mysql_xdevapi\result::getAutoIncrementValue' => ['int'],
    'mysql_xdevapi\result::getGeneratedIds' => ['ArrayOfInt'],
    'mysql_xdevapi\result::getWarnings' => ['array'],
    'mysql_xdevapi\result::getWarningsCount' => ['integer'],
    'mysql_xdevapi\rowresult::fetchAll' => ['array'],
    'mysql_xdevapi\rowresult::fetchOne' => ['object'],
    'mysql_xdevapi\rowresult::getColumnCount' => ['integer'],
    'mysql_xdevapi\rowresult::getColumnNames' => ['array'],
    'mysql_xdevapi\rowresult::getColumns' => ['array'],
    'mysql_xdevapi\rowresult::getWarnings' => ['array'],
    'mysql_xdevapi\rowresult::getWarningsCount' => ['integer'],
    'mysql_xdevapi\schema::createCollection' => ['mysql_xdevapi\Collection', 'name'=>'string'],
    'mysql_xdevapi\schema::dropCollection' => ['bool', 'collection_name'=>'string'],
    'mysql_xdevapi\schema::existsInDatabase' => ['bool'],
    'mysql_xdevapi\schema::getCollection' => ['mysql_xdevapi\Collection', 'name'=>'string'],
    'mysql_xdevapi\schema::getCollectionAsTable' => ['mysql_xdevapi\Table', 'name'=>'string'],
    'mysql_xdevapi\schema::getCollections' => ['array'],
    'mysql_xdevapi\schema::getName' => ['string'],
    'mysql_xdevapi\schema::getSession' => ['mysql_xdevapi\Session'],
    'mysql_xdevapi\schema::getTable' => ['mysql_xdevapi\Table', 'name'=>'string'],
    'mysql_xdevapi\schema::getTables' => ['array'],
    'mysql_xdevapi\schemaobject::getSchema' => ['mysql_xdevapi\Schema'],
    'mysql_xdevapi\session::close' => ['bool'],
    'mysql_xdevapi\session::commit' => ['Object'],
    'mysql_xdevapi\session::createSchema' => ['mysql_xdevapi\Schema', 'schema_name'=>'string'],
    'mysql_xdevapi\session::dropSchema' => ['bool', 'schema_name'=>'string'],
    'mysql_xdevapi\session::executeSql' => ['Object', 'statement'=>'string'],
    'mysql_xdevapi\session::generateUUID' => ['string'],
    'mysql_xdevapi\session::getClientId' => ['integer'],
    'mysql_xdevapi\session::getSchema' => ['mysql_xdevapi\Schema', 'schema_name'=>'string'],
    'mysql_xdevapi\session::getSchemas' => ['array'],
    'mysql_xdevapi\session::getServerVersion' => ['integer'],
    'mysql_xdevapi\session::killClient' => ['object', 'client_id'=>'integer'],
    'mysql_xdevapi\session::listClients' => ['array'],
    'mysql_xdevapi\session::quoteName' => ['string', 'name'=>'string'],
    'mysql_xdevapi\session::releaseSavepoint' => ['void', 'name'=>'string'],
    'mysql_xdevapi\session::rollback' => ['void'],
    'mysql_xdevapi\session::rollbackTo' => ['void', 'name'=>'string'],
    'mysql_xdevapi\session::setSavepoint' => ['string', 'name='=>'string'],
    'mysql_xdevapi\session::sql' => ['mysql_xdevapi\SqlStatement', 'query'=>'string'],
    'mysql_xdevapi\session::startTransaction' => ['void'],
    'mysql_xdevapi\sqlstatement::bind' => ['mysql_xdevapi\SqlStatement', 'param'=>'string'],
    'mysql_xdevapi\sqlstatement::execute' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\sqlstatement::getNextResult' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\sqlstatement::getResult' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\sqlstatement::hasMoreResults' => ['bool'],
    'mysql_xdevapi\sqlstatementresult::fetchAll' => ['array'],
    'mysql_xdevapi\sqlstatementresult::fetchOne' => ['object'],
    'mysql_xdevapi\sqlstatementresult::getAffectedItemsCount' => ['integer'],
    'mysql_xdevapi\sqlstatementresult::getColumnCount' => ['integer'],
    'mysql_xdevapi\sqlstatementresult::getColumnNames' => ['array'],
    'mysql_xdevapi\sqlstatementresult::getColumns' => ['Array'],
    'mysql_xdevapi\sqlstatementresult::getGeneratedIds' => ['array'],
    'mysql_xdevapi\sqlstatementresult::getLastInsertId' => ['String'],
    'mysql_xdevapi\sqlstatementresult::getWarnings' => ['array'],
    'mysql_xdevapi\sqlstatementresult::getWarningsCount' => ['integer'],
    'mysql_xdevapi\sqlstatementresult::hasData' => ['bool'],
    'mysql_xdevapi\sqlstatementresult::nextResult' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\statement::getNextResult' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\statement::getResult' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\statement::hasMoreResults' => ['bool'],
    'mysql_xdevapi\table::count' => ['integer'],
    'mysql_xdevapi\table::delete' => ['mysql_xdevapi\TableDelete'],
    'mysql_xdevapi\table::existsInDatabase' => ['bool'],
    'mysql_xdevapi\table::getName' => ['string'],
    'mysql_xdevapi\table::getSchema' => ['mysql_xdevapi\Schema'],
    'mysql_xdevapi\table::getSession' => ['mysql_xdevapi\Session'],
    'mysql_xdevapi\table::insert' => ['mysql_xdevapi\TableInsert', 'columns'=>'mixed', '...args='=>'mixed'],
    'mysql_xdevapi\table::isView' => ['bool'],
    'mysql_xdevapi\table::select' => ['mysql_xdevapi\TableSelect', 'columns'=>'mixed', '...args='=>'mixed'],
    'mysql_xdevapi\table::update' => ['mysql_xdevapi\TableUpdate'],
    'mysql_xdevapi\tabledelete::bind' => ['mysql_xdevapi\TableDelete', 'placeholder_values'=>'array'],
    'mysql_xdevapi\tabledelete::execute' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\tabledelete::limit' => ['mysql_xdevapi\TableDelete', 'rows'=>'integer'],
    'mysql_xdevapi\tabledelete::offset' => ['mysql_xdevapi\TableDelete', 'position'=>'integer'],
    'mysql_xdevapi\tabledelete::orderby' => ['mysql_xdevapi\TableDelete', 'orderby_expr'=>'string'],
    'mysql_xdevapi\tabledelete::where' => ['mysql_xdevapi\TableDelete', 'where_expr'=>'string'],
    'mysql_xdevapi\tableinsert::execute' => ['mysql_xdevapi\Result'],
    'mysql_xdevapi\tableinsert::values' => ['mysql_xdevapi\TableInsert', 'row_values'=>'array'],
    'mysql_xdevapi\tableselect::bind' => ['mysql_xdevapi\TableSelect', 'placeholder_values'=>'array'],
    'mysql_xdevapi\tableselect::execute' => ['mysql_xdevapi\RowResult'],
    'mysql_xdevapi\tableselect::groupBy' => ['mysql_xdevapi\TableSelect', 'sort_expr'=>'mixed'],
    'mysql_xdevapi\tableselect::having' => ['mysql_xdevapi\TableSelect', 'sort_expr'=>'string'],
    'mysql_xdevapi\tableselect::limit' => ['mysql_xdevapi\TableSelect', 'rows'=>'integer'],
    'mysql_xdevapi\tableselect::lockExclusive' => ['mysql_xdevapi\TableSelect', 'lock_waiting_option='=>'integer'],
    'mysql_xdevapi\tableselect::lockShared' => ['mysql_xdevapi\TableSelect', 'lock_waiting_option='=>'integer'],
    'mysql_xdevapi\tableselect::offset' => ['mysql_xdevapi\TableSelect', 'position'=>'integer'],
    'mysql_xdevapi\tableselect::orderby' => ['mysql_xdevapi\TableSelect', 'sort_expr'=>'mixed', '...args='=>'mixed'],
    'mysql_xdevapi\tableselect::where' => ['mysql_xdevapi\TableSelect', 'where_expr'=>'string'],
    'mysql_xdevapi\tableupdate::bind' => ['mysql_xdevapi\TableUpdate', 'placeholder_values'=>'array'],
    'mysql_xdevapi\tableupdate::execute' => ['mysql_xdevapi\TableUpdate'],
    'mysql_xdevapi\tableupdate::limit' => ['mysql_xdevapi\TableUpdate', 'rows'=>'integer'],
    'mysql_xdevapi\tableupdate::orderby' => ['mysql_xdevapi\TableUpdate', 'orderby_expr'=>'mixed', '...args='=>'mixed'],
    'mysql_xdevapi\tableupdate::set' => ['mysql_xdevapi\TableUpdate', 'table_field'=>'string', 'expression_or_literal'=>'string'],
    'mysql_xdevapi\tableupdate::where' => ['mysql_xdevapi\TableUpdate', 'where_expr'=>'string'],
    'mysqli::__construct' => ['void', 'hostname='=>'string', 'username='=>'string', 'password='=>'string', 'database='=>'string', 'port='=>'int', 'socket='=>'string'],
    'mysqli::autocommit' => ['bool', 'enable'=>'bool'],
    'mysqli::begin_transaction' => ['bool', 'flags='=>'int', 'name='=>'string'],
    'mysqli::change_user' => ['bool', 'username'=>'string', 'password'=>'string', 'database'=>'?string'],
    'mysqli::character_set_name' => ['string'],
    'mysqli::close' => ['bool'],
    'mysqli::commit' => ['bool', 'flags='=>'int', 'name='=>'string'],
    'mysqli::connect' => ['null|false', 'hostname='=>'string', 'username='=>'string', 'password='=>'string', 'database='=>'string', 'port='=>'int', 'socket='=>'string'],
    'mysqli::debug' => ['bool', 'options'=>'string'],
    'mysqli::disable_reads_from_master' => ['bool'],
    'mysqli::dump_debug_info' => ['bool'],
    'mysqli::escape_string' => ['string', 'string'=>'string'],
    'mysqli::get_charset' => ['object'],
    'mysqli::get_client_info' => ['string'],
    'mysqli::get_connection_stats' => ['array'],
    'mysqli::get_warnings' => ['mysqli_warning'],
    'mysqli::init' => ['false|null'],
    'mysqli::kill' => ['bool', 'process_id'=>'int'],
    'mysqli::more_results' => ['bool'],
    'mysqli::multi_query' => ['bool', 'query'=>'string'],
    'mysqli::next_result' => ['bool'],
    'mysqli::options' => ['bool', 'option'=>'int', 'value'=>'string|int'],
    'mysqli::ping' => ['bool'],
    'mysqli::poll' => ['int|false', '&w_read'=>'array', '&w_write'=>'array', '&w_error'=>'array', 'seconds'=>'int', 'microseconds='=>'int'],
    'mysqli::prepare' => ['mysqli_stmt|false', 'query'=>'string'],
    'mysqli::query' => ['bool|mysqli_result', 'query'=>'string', 'result_mode='=>'int'],
    'mysqli::real_connect' => ['bool', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null', 'flags='=>'int'],
    'mysqli::real_escape_string' => ['string', 'string'=>'string'],
    'mysqli::real_query' => ['bool', 'query'=>'string'],
    'mysqli::reap_async_query' => ['mysqli_result|false'],
    'mysqli::refresh' => ['bool', 'flags'=>'int'],
    'mysqli::release_savepoint' => ['bool', 'name'=>'string'],
    'mysqli::rollback' => ['bool', 'flags='=>'int', 'name='=>'string'],
    'mysqli::rpl_query_type' => ['int', 'query'=>'string'],
    'mysqli::savepoint' => ['bool', 'name'=>'string'],
    'mysqli::select_db' => ['bool', 'database'=>'string'],
    'mysqli::send_query' => ['bool', 'query'=>'string'],
    'mysqli::set_charset' => ['bool', 'charset'=>'string'],
    'mysqli::set_local_infile_default' => ['void'],
    'mysqli::set_local_infile_handler' => ['bool', 'read_func='=>'callable'],
    'mysqli::set_opt' => ['bool', 'option'=>'int', 'value'=>'string|int'],
    'mysqli::ssl_set' => ['bool', 'key'=>'?string', 'certificate'=>'?string', 'ca_certificate'=>'?string', 'ca_path'=>'?string', 'cipher_algos'=>'?string'],
    'mysqli::stat' => ['string|false'],
    'mysqli::stmt_init' => ['mysqli_stmt'],
    'mysqli::store_result' => ['mysqli_result|false', 'mode='=>'int'],
    'mysqli::thread_safe' => ['bool'],
    'mysqli::use_result' => ['mysqli_result|false'],
    'mysqli_affected_rows' => ['int', 'mysql'=>'mysqli'],
    'mysqli_autocommit' => ['bool', 'mysql'=>'mysqli', 'enable'=>'bool'],
    'mysqli_begin_transaction' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'string'],
    'mysqli_change_user' => ['bool', 'mysql'=>'mysqli', 'username'=>'string', 'password'=>'string', 'database'=>'?string'],
    'mysqli_character_set_name' => ['string', 'mysql'=>'mysqli'],
    'mysqli_close' => ['bool', 'mysql'=>'mysqli'],
    'mysqli_commit' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'string'],
    'mysqli_connect' => ['mysqli|false', 'hostname='=>'string', 'username='=>'string', 'password='=>'string', 'database='=>'string', 'port='=>'int', 'socket='=>'string'],
    'mysqli_connect_errno' => ['int'],
    'mysqli_connect_error' => ['?string'],
    'mysqli_data_seek' => ['bool', 'result'=>'mysqli_result', 'offset'=>'int'],
    'mysqli_debug' => ['bool', 'options'=>'string'],
    'mysqli_disable_reads_from_master' => ['bool', 'link'=>'mysqli'],
    'mysqli_disable_rpl_parse' => ['bool', 'link'=>'mysqli'],
    'mysqli_driver::embedded_server_end' => ['void'],
    'mysqli_driver::embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'],
    'mysqli_dump_debug_info' => ['bool', 'mysql'=>'mysqli'],
    'mysqli_embedded_server_end' => ['void'],
    'mysqli_embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'],
    'mysqli_enable_reads_from_master' => ['bool', 'link'=>'mysqli'],
    'mysqli_enable_rpl_parse' => ['bool', 'link'=>'mysqli'],
    'mysqli_errno' => ['int', 'mysql'=>'mysqli'],
    'mysqli_error' => ['string', 'mysql'=>'mysqli'],
    'mysqli_error_list' => ['array', 'mysql'=>'mysqli'],
    'mysqli_escape_string' => ['string', 'mysql'=>'mysqli', 'string'=>'string'],
    'mysqli_execute' => ['bool', 'statement'=>'mysqli_stmt'],
    'mysqli_fetch_all' => ['list<array<array-key,null|int|float|string>>', 'result'=>'mysqli_result', 'mode='=>'3'],
    'mysqli_fetch_all\'1' => ['list<array<string,null|int|float|string>>', 'result'=>'mysqli_result', 'mode='=>'1'],
    'mysqli_fetch_all\'2' => ['list<list<null|int|float|string>>', 'result'=>'mysqli_result', 'mode='=>'2'],
    'mysqli_fetch_array' => ['array<array-key,null|int|float|string>|false|null', 'result'=>'mysqli_result', 'mode='=>'3'],
    'mysqli_fetch_array\'1' => ['array<string,null|int|float|string>|false|null', 'result'=>'mysqli_result', 'mode='=>'1'],
    'mysqli_fetch_array\'2' => ['list<null|int|float|string>|false|null', 'result'=>'mysqli_result', 'mode='=>'2'],
    'mysqli_fetch_assoc' => ['array<string,null|int|float|string>|false|null', 'result'=>'mysqli_result'],
    'mysqli_fetch_field' => ['object|false', 'result'=>'mysqli_result'],
    'mysqli_fetch_field_direct' => ['object|false', 'result'=>'mysqli_result', 'index'=>'int'],
    'mysqli_fetch_fields' => ['stdClass[]', 'result'=>'mysqli_result'],
    'mysqli_fetch_lengths' => ['array|false', 'result'=>'mysqli_result'],
    'mysqli_fetch_object' => ['object|false|null', 'result'=>'mysqli_result', 'class='=>'class-string', 'constructor_args='=>'array'],
    'mysqli_fetch_row' => ['list<null|int|float|string>|false|null', 'result'=>'mysqli_result'],
    'mysqli_field_count' => ['int', 'mysql'=>'mysqli'],
    'mysqli_field_seek' => ['bool', 'result'=>'mysqli_result', 'index'=>'int'],
    'mysqli_field_tell' => ['int', 'result'=>'mysqli_result'],
    'mysqli_free_result' => ['void', 'result'=>'mysqli_result'],
    'mysqli_get_cache_stats' => ['array|false'],
    'mysqli_get_charset' => ['?object', 'mysql'=>'mysqli'],
    'mysqli_get_client_info' => ['string', 'mysql='=>'?mysqli'],
    'mysqli_get_client_stats' => ['array'],
    'mysqli_get_client_version' => ['int', 'link'=>'mysqli'],
    'mysqli_get_connection_stats' => ['array', 'mysql'=>'mysqli'],
    'mysqli_get_host_info' => ['string', 'mysql'=>'mysqli'],
    'mysqli_get_links_stats' => ['array'],
    'mysqli_get_proto_info' => ['int', 'mysql'=>'mysqli'],
    'mysqli_get_server_info' => ['string', 'mysql'=>'mysqli'],
    'mysqli_get_server_version' => ['int', 'mysql'=>'mysqli'],
    'mysqli_get_warnings' => ['mysqli_warning', 'mysql'=>'mysqli'],
    'mysqli_info' => ['?string', 'mysql'=>'mysqli'],
    'mysqli_init' => ['mysqli|false'],
    'mysqli_insert_id' => ['int|string', 'mysql'=>'mysqli'],
    'mysqli_kill' => ['bool', 'mysql'=>'mysqli', 'process_id'=>'int'],
    'mysqli_link_construct' => ['object'],
    'mysqli_master_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'],
    'mysqli_more_results' => ['bool', 'mysql'=>'mysqli'],
    'mysqli_multi_query' => ['bool', 'mysql'=>'mysqli', 'query'=>'string'],
    'mysqli_next_result' => ['bool', 'mysql'=>'mysqli'],
    'mysqli_num_fields' => ['int', 'result'=>'mysqli_result'],
    'mysqli_num_rows' => ['int', 'result'=>'mysqli_result'],
    'mysqli_options' => ['bool', 'mysql'=>'mysqli', 'option'=>'int', 'value'=>'string|int'],
    'mysqli_ping' => ['bool', 'mysql'=>'mysqli'],
    'mysqli_poll' => ['int|false', 'read'=>'array', 'write'=>'array', 'error'=>'array', 'seconds'=>'int', 'microseconds='=>'int'],
    'mysqli_prepare' => ['mysqli_stmt|false', 'mysql'=>'mysqli', 'query'=>'string'],
    'mysqli_query' => ['mysqli_result|bool', 'mysql'=>'mysqli', 'query'=>'string', 'result_mode='=>'int'],
    'mysqli_real_connect' => ['bool', 'mysql='=>'mysqli', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null', 'flags='=>'int'],
    'mysqli_real_escape_string' => ['string', 'mysql'=>'mysqli', 'string'=>'string'],
    'mysqli_real_query' => ['bool', 'mysql'=>'mysqli', 'query'=>'string'],
    'mysqli_reap_async_query' => ['mysqli_result|false', 'mysql'=>'mysqli'],
    'mysqli_refresh' => ['bool', 'mysql'=>'mysqli', 'flags'=>'int'],
    'mysqli_release_savepoint' => ['bool', 'mysql'=>'mysqli', 'name'=>'string'],
    'mysqli_report' => ['bool', 'flags'=>'int'],
    'mysqli_result::__construct' => ['void', 'mysql'=>'mysqli', 'result_mode='=>'int'],
    'mysqli_result::close' => ['void'],
    'mysqli_result::data_seek' => ['bool', 'offset'=>'int'],
    'mysqli_result::fetch_all' => ['list<array<array-key,null|int|float|string>>', 'mode='=>'3'],
    'mysqli_result::fetch_all\'1' => ['list<array<string,null|int|float|string>>', 'mode='=>'1'],
    'mysqli_result::fetch_all\'2' => ['list<list<null|int|float|string>>', 'mode='=>'2'],
    'mysqli_result::fetch_array' => ['array<array-key,null|int|float|string>|false|null', 'mode='=>'3'],
    'mysqli_result::fetch_array\'1' => ['array<string,null|int|float|string>|false|null', 'mode='=>'1'],
    'mysqli_result::fetch_array\'2' => ['list<null|int|float|string>|false|null', 'mode='=>'2'],
    'mysqli_result::fetch_assoc' => ['array<string,null|int|float|string>|false|null'],
    'mysqli_result::fetch_field' => ['object|false'],
    'mysqli_result::fetch_field_direct' => ['object|false', 'index'=>'int'],
    'mysqli_result::fetch_fields' => ['stdClass[]'],
    'mysqli_result::fetch_object' => ['object|false|null', 'class='=>'class-string', 'constructor_args='=>'array'],
    'mysqli_result::fetch_row' => ['list<null|int|float|string>|false|null'],
    'mysqli_result::field_seek' => ['bool', 'index'=>'int'],
    'mysqli_result::free' => ['void'],
    'mysqli_result::free_result' => ['void'],
    'mysqli_rollback' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'string'],
    'mysqli_rpl_parse_enabled' => ['int', 'link'=>'mysqli'],
    'mysqli_rpl_probe' => ['bool', 'link'=>'mysqli'],
    'mysqli_rpl_query_type' => ['int', 'link'=>'mysqli', 'query'=>'string'],
    'mysqli_savepoint' => ['bool', 'mysql'=>'mysqli', 'name'=>'string'],
    'mysqli_savepoint_libmysql' => ['bool'],
    'mysqli_select_db' => ['bool', 'mysql'=>'mysqli', 'database'=>'string'],
    'mysqli_send_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'],
    'mysqli_set_charset' => ['bool', 'mysql'=>'mysqli', 'charset'=>'string'],
    'mysqli_set_local_infile_default' => ['void', 'link'=>'mysqli'],
    'mysqli_set_local_infile_handler' => ['bool', 'link'=>'mysqli', 'read_func'=>'callable'],
    'mysqli_set_opt' => ['bool', 'mysql'=>'mysqli', 'option'=>'int', 'value'=>'string|int'],
    'mysqli_slave_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'],
    'mysqli_sqlstate' => ['string', 'mysql'=>'mysqli'],
    'mysqli_ssl_set' => ['true', 'mysql'=>'mysqli', 'key'=>'?string', 'certificate'=>'?string', 'ca_certificate'=>'?string', 'ca_path'=>'?string', 'cipher_algos'=>'?string'],
    'mysqli_stat' => ['string|false', 'mysql'=>'mysqli'],
    'mysqli_stmt::__construct' => ['void', 'mysql'=>'mysqli', 'query'=>'string'],
    'mysqli_stmt::attr_get' => ['int', 'attribute'=>'int'],
    'mysqli_stmt::attr_set' => ['bool', 'attribute'=>'int', 'value'=>'int'],
    'mysqli_stmt::bind_param' => ['bool', 'types'=>'string', '&vars'=>'mixed', '&...args='=>'mixed'],
    'mysqli_stmt::bind_result' => ['bool', '&w_var1'=>'', '&...w_vars='=>''],
    'mysqli_stmt::close' => ['bool'],
    'mysqli_stmt::data_seek' => ['void', 'offset'=>'int'],
    'mysqli_stmt::execute' => ['bool'],
    'mysqli_stmt::fetch' => ['bool|null'],
    'mysqli_stmt::free_result' => ['void'],
    'mysqli_stmt::get_result' => ['mysqli_result|false'],
    'mysqli_stmt::get_warnings' => ['object'],
    'mysqli_stmt::more_results' => ['bool'],
    'mysqli_stmt::next_result' => ['bool'],
    'mysqli_stmt::num_rows' => ['int'],
    'mysqli_stmt::prepare' => ['bool', 'query'=>'string'],
    'mysqli_stmt::reset' => ['bool'],
    'mysqli_stmt::result_metadata' => ['mysqli_result|false'],
    'mysqli_stmt::send_long_data' => ['bool', 'param_num'=>'int', 'data'=>'string'],
    'mysqli_stmt::store_result' => ['bool'],
    'mysqli_stmt_affected_rows' => ['int|string', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_attr_get' => ['int', 'statement'=>'mysqli_stmt', 'attribute'=>'int'],
    'mysqli_stmt_attr_set' => ['bool', 'statement'=>'mysqli_stmt', 'attribute'=>'int', 'value'=>'int'],
    'mysqli_stmt_bind_param' => ['bool', 'statement'=>'mysqli_stmt', 'types'=>'string', '&vars'=>'mixed', '&...args='=>'mixed'],
    'mysqli_stmt_bind_result' => ['bool', 'statement'=>'mysqli_stmt', '&w_var1'=>'', '&...w_vars='=>''],
    'mysqli_stmt_close' => ['bool', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_data_seek' => ['void', 'statement'=>'mysqli_stmt', 'offset'=>'int'],
    'mysqli_stmt_errno' => ['int', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_error' => ['string', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_error_list' => ['array', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_execute' => ['bool', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_fetch' => ['bool|null', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_field_count' => ['int', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_free_result' => ['void', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_get_result' => ['mysqli_result|false', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_get_warnings' => ['object', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_init' => ['mysqli_stmt', 'mysql'=>'mysqli'],
    'mysqli_stmt_insert_id' => ['mixed', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_more_results' => ['bool', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_next_result' => ['bool', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_num_rows' => ['int', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_param_count' => ['int', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_prepare' => ['bool', 'statement'=>'mysqli_stmt', 'query'=>'string'],
    'mysqli_stmt_reset' => ['bool', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_result_metadata' => ['mysqli_result|false', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_send_long_data' => ['bool', 'statement'=>'mysqli_stmt', 'param_num'=>'int', 'data'=>'string'],
    'mysqli_stmt_sqlstate' => ['string', 'statement'=>'mysqli_stmt'],
    'mysqli_stmt_store_result' => ['bool', 'statement'=>'mysqli_stmt'],
    'mysqli_store_result' => ['mysqli_result|false', 'mysql'=>'mysqli', 'mode='=>'int'],
    'mysqli_thread_id' => ['int', 'mysql'=>'mysqli'],
    'mysqli_thread_safe' => ['bool'],
    'mysqli_use_result' => ['mysqli_result|false', 'mysql'=>'mysqli'],
    'mysqli_warning::__construct' => ['void'],
    'mysqli_warning::next' => ['bool'],
    'mysqli_warning_count' => ['int', 'mysql'=>'mysqli'],
    'mysqlnd_memcache_get_config' => ['array', 'connection'=>'mixed'],
    'mysqlnd_memcache_set' => ['bool', 'mysql_connection'=>'mixed', 'memcache_connection='=>'Memcached', 'pattern='=>'string', 'callback='=>'callable'],
    'mysqlnd_ms_dump_servers' => ['array', 'connection'=>'mixed'],
    'mysqlnd_ms_fabric_select_global' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed'],
    'mysqlnd_ms_fabric_select_shard' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed', 'shard_key'=>'mixed'],
    'mysqlnd_ms_get_last_gtid' => ['string', 'connection'=>'mixed'],
    'mysqlnd_ms_get_last_used_connection' => ['array', 'connection'=>'mixed'],
    'mysqlnd_ms_get_stats' => ['array'],
    'mysqlnd_ms_match_wild' => ['bool', 'table_name'=>'string', 'wildcard'=>'string'],
    'mysqlnd_ms_query_is_select' => ['int', 'query'=>'string'],
    'mysqlnd_ms_set_qos' => ['bool', 'connection'=>'mixed', 'service_level'=>'int', 'service_level_option='=>'int', 'option_value='=>'mixed'],
    'mysqlnd_ms_set_user_pick_server' => ['bool', 'function'=>'string'],
    'mysqlnd_ms_xa_begin' => ['int', 'connection'=>'mixed', 'gtrid'=>'string', 'timeout='=>'int'],
    'mysqlnd_ms_xa_commit' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'],
    'mysqlnd_ms_xa_gc' => ['int', 'connection'=>'mixed', 'gtrid='=>'string', 'ignore_max_retries='=>'bool'],
    'mysqlnd_ms_xa_rollback' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'],
    'mysqlnd_qc_change_handler' => ['bool', 'handler'=>''],
    'mysqlnd_qc_clear_cache' => ['bool'],
    'mysqlnd_qc_get_available_handlers' => ['array'],
    'mysqlnd_qc_get_cache_info' => ['array'],
    'mysqlnd_qc_get_core_stats' => ['array'],
    'mysqlnd_qc_get_handler' => ['array'],
    'mysqlnd_qc_get_normalized_query_trace_log' => ['array'],
    'mysqlnd_qc_get_query_trace_log' => ['array'],
    'mysqlnd_qc_set_cache_condition' => ['bool', 'condition_type'=>'int', 'condition'=>'mixed', 'condition_option'=>'mixed'],
    'mysqlnd_qc_set_is_select' => ['mixed', 'callback'=>'string'],
    'mysqlnd_qc_set_storage_handler' => ['bool', 'handler'=>'string'],
    'mysqlnd_qc_set_user_handlers' => ['bool', 'get_hash'=>'string', 'find_query_in_cache'=>'string', 'return_to_cache'=>'string', 'add_query_to_cache_if_not_exists'=>'string', 'query_is_select'=>'string', 'update_query_run_time_stats'=>'string', 'get_stats'=>'string', 'clear_cache'=>'string'],
    'mysqlnd_uh_convert_to_mysqlnd' => ['resource', '&rw_mysql_connection'=>'mysqli'],
    'mysqlnd_uh_set_connection_proxy' => ['bool', '&rw_connection_proxy'=>'MysqlndUhConnection', '&rw_mysqli_connection='=>'mysqli'],
    'mysqlnd_uh_set_statement_proxy' => ['bool', '&rw_statement_proxy'=>'MysqlndUhStatement'],
    'natcasesort' => ['bool', '&rw_array'=>'array'],
    'natsort' => ['bool', '&rw_array'=>'array'],
    'ncurses_addch' => ['int', 'ch'=>'int'],
    'ncurses_addchnstr' => ['int', 's'=>'string', 'n'=>'int'],
    'ncurses_addchstr' => ['int', 's'=>'string'],
    'ncurses_addnstr' => ['int', 's'=>'string', 'n'=>'int'],
    'ncurses_addstr' => ['int', 'text'=>'string'],
    'ncurses_assume_default_colors' => ['int', 'fg'=>'int', 'bg'=>'int'],
    'ncurses_attroff' => ['int', 'attributes'=>'int'],
    'ncurses_attron' => ['int', 'attributes'=>'int'],
    'ncurses_attrset' => ['int', 'attributes'=>'int'],
    'ncurses_baudrate' => ['int'],
    'ncurses_beep' => ['int'],
    'ncurses_bkgd' => ['int', 'attrchar'=>'int'],
    'ncurses_bkgdset' => ['void', 'attrchar'=>'int'],
    'ncurses_border' => ['int', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'],
    'ncurses_bottom_panel' => ['int', 'panel'=>'resource'],
    'ncurses_can_change_color' => ['bool'],
    'ncurses_cbreak' => ['bool'],
    'ncurses_clear' => ['bool'],
    'ncurses_clrtobot' => ['bool'],
    'ncurses_clrtoeol' => ['bool'],
    'ncurses_color_content' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'],
    'ncurses_color_set' => ['int', 'pair'=>'int'],
    'ncurses_curs_set' => ['int', 'visibility'=>'int'],
    'ncurses_def_prog_mode' => ['bool'],
    'ncurses_def_shell_mode' => ['bool'],
    'ncurses_define_key' => ['int', 'definition'=>'string', 'keycode'=>'int'],
    'ncurses_del_panel' => ['bool', 'panel'=>'resource'],
    'ncurses_delay_output' => ['int', 'milliseconds'=>'int'],
    'ncurses_delch' => ['bool'],
    'ncurses_deleteln' => ['bool'],
    'ncurses_delwin' => ['bool', 'window'=>'resource'],
    'ncurses_doupdate' => ['bool'],
    'ncurses_echo' => ['bool'],
    'ncurses_echochar' => ['int', 'character'=>'int'],
    'ncurses_end' => ['int'],
    'ncurses_erase' => ['bool'],
    'ncurses_erasechar' => ['string'],
    'ncurses_filter' => ['void'],
    'ncurses_flash' => ['bool'],
    'ncurses_flushinp' => ['bool'],
    'ncurses_getch' => ['int'],
    'ncurses_getmaxyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'],
    'ncurses_getmouse' => ['bool', 'mevent'=>'array'],
    'ncurses_getyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'],
    'ncurses_halfdelay' => ['int', 'tenth'=>'int'],
    'ncurses_has_colors' => ['bool'],
    'ncurses_has_ic' => ['bool'],
    'ncurses_has_il' => ['bool'],
    'ncurses_has_key' => ['int', 'keycode'=>'int'],
    'ncurses_hide_panel' => ['int', 'panel'=>'resource'],
    'ncurses_hline' => ['int', 'charattr'=>'int', 'n'=>'int'],
    'ncurses_inch' => ['string'],
    'ncurses_init' => ['void'],
    'ncurses_init_color' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'],
    'ncurses_init_pair' => ['int', 'pair'=>'int', 'fg'=>'int', 'bg'=>'int'],
    'ncurses_insch' => ['int', 'character'=>'int'],
    'ncurses_insdelln' => ['int', 'count'=>'int'],
    'ncurses_insertln' => ['int'],
    'ncurses_insstr' => ['int', 'text'=>'string'],
    'ncurses_instr' => ['int', 'buffer'=>'string'],
    'ncurses_isendwin' => ['bool'],
    'ncurses_keyok' => ['int', 'keycode'=>'int', 'enable'=>'bool'],
    'ncurses_keypad' => ['int', 'window'=>'resource', 'bf'=>'bool'],
    'ncurses_killchar' => ['string'],
    'ncurses_longname' => ['string'],
    'ncurses_meta' => ['int', 'window'=>'resource', '_8bit'=>'bool'],
    'ncurses_mouse_trafo' => ['bool', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'],
    'ncurses_mouseinterval' => ['int', 'milliseconds'=>'int'],
    'ncurses_mousemask' => ['int', 'newmask'=>'int', 'oldmask'=>'int'],
    'ncurses_move' => ['int', 'y'=>'int', 'x'=>'int'],
    'ncurses_move_panel' => ['int', 'panel'=>'resource', 'startx'=>'int', 'starty'=>'int'],
    'ncurses_mvaddch' => ['int', 'y'=>'int', 'x'=>'int', 'c'=>'int'],
    'ncurses_mvaddchnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'],
    'ncurses_mvaddchstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'],
    'ncurses_mvaddnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'],
    'ncurses_mvaddstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'],
    'ncurses_mvcur' => ['int', 'old_y'=>'int', 'old_x'=>'int', 'new_y'=>'int', 'new_x'=>'int'],
    'ncurses_mvdelch' => ['int', 'y'=>'int', 'x'=>'int'],
    'ncurses_mvgetch' => ['int', 'y'=>'int', 'x'=>'int'],
    'ncurses_mvhline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'],
    'ncurses_mvinch' => ['int', 'y'=>'int', 'x'=>'int'],
    'ncurses_mvvline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'],
    'ncurses_mvwaddstr' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'text'=>'string'],
    'ncurses_napms' => ['int', 'milliseconds'=>'int'],
    'ncurses_new_panel' => ['resource', 'window'=>'resource'],
    'ncurses_newpad' => ['resource', 'rows'=>'int', 'cols'=>'int'],
    'ncurses_newwin' => ['resource', 'rows'=>'int', 'cols'=>'int', 'y'=>'int', 'x'=>'int'],
    'ncurses_nl' => ['bool'],
    'ncurses_nocbreak' => ['bool'],
    'ncurses_noecho' => ['bool'],
    'ncurses_nonl' => ['bool'],
    'ncurses_noqiflush' => ['void'],
    'ncurses_noraw' => ['bool'],
    'ncurses_pair_content' => ['int', 'pair'=>'int', 'f'=>'int', 'b'=>'int'],
    'ncurses_panel_above' => ['resource', 'panel'=>'resource'],
    'ncurses_panel_below' => ['resource', 'panel'=>'resource'],
    'ncurses_panel_window' => ['resource', 'panel'=>'resource'],
    'ncurses_pnoutrefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'],
    'ncurses_prefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'],
    'ncurses_putp' => ['int', 'text'=>'string'],
    'ncurses_qiflush' => ['void'],
    'ncurses_raw' => ['bool'],
    'ncurses_refresh' => ['int', 'ch'=>'int'],
    'ncurses_replace_panel' => ['int', 'panel'=>'resource', 'window'=>'resource'],
    'ncurses_reset_prog_mode' => ['int'],
    'ncurses_reset_shell_mode' => ['int'],
    'ncurses_resetty' => ['bool'],
    'ncurses_savetty' => ['bool'],
    'ncurses_scr_dump' => ['int', 'filename'=>'string'],
    'ncurses_scr_init' => ['int', 'filename'=>'string'],
    'ncurses_scr_restore' => ['int', 'filename'=>'string'],
    'ncurses_scr_set' => ['int', 'filename'=>'string'],
    'ncurses_scrl' => ['int', 'count'=>'int'],
    'ncurses_show_panel' => ['int', 'panel'=>'resource'],
    'ncurses_slk_attr' => ['int'],
    'ncurses_slk_attroff' => ['int', 'intarg'=>'int'],
    'ncurses_slk_attron' => ['int', 'intarg'=>'int'],
    'ncurses_slk_attrset' => ['int', 'intarg'=>'int'],
    'ncurses_slk_clear' => ['bool'],
    'ncurses_slk_color' => ['int', 'intarg'=>'int'],
    'ncurses_slk_init' => ['bool', 'format'=>'int'],
    'ncurses_slk_noutrefresh' => ['bool'],
    'ncurses_slk_refresh' => ['int'],
    'ncurses_slk_restore' => ['int'],
    'ncurses_slk_set' => ['bool', 'labelnr'=>'int', 'label'=>'string', 'format'=>'int'],
    'ncurses_slk_touch' => ['int'],
    'ncurses_standend' => ['int'],
    'ncurses_standout' => ['int'],
    'ncurses_start_color' => ['int'],
    'ncurses_termattrs' => ['bool'],
    'ncurses_termname' => ['string'],
    'ncurses_timeout' => ['void', 'millisec'=>'int'],
    'ncurses_top_panel' => ['int', 'panel'=>'resource'],
    'ncurses_typeahead' => ['int', 'fd'=>'int'],
    'ncurses_ungetch' => ['int', 'keycode'=>'int'],
    'ncurses_ungetmouse' => ['bool', 'mevent'=>'array'],
    'ncurses_update_panels' => ['void'],
    'ncurses_use_default_colors' => ['bool'],
    'ncurses_use_env' => ['void', 'flag'=>'bool'],
    'ncurses_use_extended_names' => ['int', 'flag'=>'bool'],
    'ncurses_vidattr' => ['int', 'intarg'=>'int'],
    'ncurses_vline' => ['int', 'charattr'=>'int', 'n'=>'int'],
    'ncurses_waddch' => ['int', 'window'=>'resource', 'ch'=>'int'],
    'ncurses_waddstr' => ['int', 'window'=>'resource', 'string'=>'string', 'n='=>'int'],
    'ncurses_wattroff' => ['int', 'window'=>'resource', 'attrs'=>'int'],
    'ncurses_wattron' => ['int', 'window'=>'resource', 'attrs'=>'int'],
    'ncurses_wattrset' => ['int', 'window'=>'resource', 'attrs'=>'int'],
    'ncurses_wborder' => ['int', 'window'=>'resource', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'],
    'ncurses_wclear' => ['int', 'window'=>'resource'],
    'ncurses_wcolor_set' => ['int', 'window'=>'resource', 'color_pair'=>'int'],
    'ncurses_werase' => ['int', 'window'=>'resource'],
    'ncurses_wgetch' => ['int', 'window'=>'resource'],
    'ncurses_whline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'],
    'ncurses_wmouse_trafo' => ['bool', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'],
    'ncurses_wmove' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int'],
    'ncurses_wnoutrefresh' => ['int', 'window'=>'resource'],
    'ncurses_wrefresh' => ['int', 'window'=>'resource'],
    'ncurses_wstandend' => ['int', 'window'=>'resource'],
    'ncurses_wstandout' => ['int', 'window'=>'resource'],
    'ncurses_wvline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'],
    'newrelic_add_custom_parameter' => ['bool', 'key'=>'string', 'value'=>'bool|float|int|string'],
    'newrelic_add_custom_tracer' => ['bool', 'function_name'=>'string'],
    'newrelic_background_job' => ['void', 'flag='=>'bool'],
    'newrelic_capture_params' => ['void', 'enable='=>'bool'],
    'newrelic_custom_metric' => ['bool', 'metric_name'=>'string', 'value'=>'float'],
    'newrelic_disable_autorum' => ['true'],
    'newrelic_end_of_transaction' => ['void'],
    'newrelic_end_transaction' => ['bool', 'ignore='=>'bool'],
    'newrelic_get_browser_timing_footer' => ['string', 'include_tags='=>'bool'],
    'newrelic_get_browser_timing_header' => ['string', 'include_tags='=>'bool'],
    'newrelic_ignore_apdex' => ['void'],
    'newrelic_ignore_transaction' => ['void'],
    'newrelic_name_transaction' => ['bool', 'name'=>'string'],
    'newrelic_notice_error' => ['void', 'message'=>'string', 'exception='=>'Exception|Throwable'],
    'newrelic_notice_error\'1' => ['void', 'unused_1'=>'string', 'message'=>'string', 'unused_2'=>'string', 'unused_3'=>'int', 'unused_4='=>''],
    'newrelic_record_custom_event' => ['void', 'name'=>'string', 'attributes'=>'array'],
    'newrelic_record_datastore_segment' => ['mixed', 'func'=>'callable', 'parameters'=>'array'],
    'newrelic_set_appname' => ['bool', 'name'=>'string', 'license='=>'string', 'xmit='=>'bool'],
    'newrelic_set_user_attributes' => ['bool', 'user'=>'string', 'account'=>'string', 'product'=>'string'],
    'newrelic_start_transaction' => ['bool', 'appname'=>'string', 'license='=>'string'],
    'newt_bell' => ['void'],
    'newt_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
    'newt_button_bar' => ['resource', 'buttons'=>'array'],
    'newt_centered_window' => ['int', 'width'=>'int', 'height'=>'int', 'title='=>'string'],
    'newt_checkbox' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'def_value'=>'string', 'seq='=>'string'],
    'newt_checkbox_get_value' => ['string', 'checkbox'=>'resource'],
    'newt_checkbox_set_flags' => ['void', 'checkbox'=>'resource', 'flags'=>'int', 'sense'=>'int'],
    'newt_checkbox_set_value' => ['void', 'checkbox'=>'resource', 'value'=>'string'],
    'newt_checkbox_tree' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'],
    'newt_checkbox_tree_add_item' => ['void', 'checkboxtree'=>'resource', 'text'=>'string', 'data'=>'mixed', 'flags'=>'int', 'index'=>'int', '...args='=>'int'],
    'newt_checkbox_tree_find_item' => ['array', 'checkboxtree'=>'resource', 'data'=>'mixed'],
    'newt_checkbox_tree_get_current' => ['mixed', 'checkboxtree'=>'resource'],
    'newt_checkbox_tree_get_entry_value' => ['string', 'checkboxtree'=>'resource', 'data'=>'mixed'],
    'newt_checkbox_tree_get_multi_selection' => ['array', 'checkboxtree'=>'resource', 'seqnum'=>'string'],
    'newt_checkbox_tree_get_selection' => ['array', 'checkboxtree'=>'resource'],
    'newt_checkbox_tree_multi' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'seq'=>'string', 'flags='=>'int'],
    'newt_checkbox_tree_set_current' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed'],
    'newt_checkbox_tree_set_entry' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'text'=>'string'],
    'newt_checkbox_tree_set_entry_value' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'value'=>'string'],
    'newt_checkbox_tree_set_width' => ['void', 'checkbox_tree'=>'resource', 'width'=>'int'],
    'newt_clear_key_buffer' => ['void'],
    'newt_cls' => ['void'],
    'newt_compact_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
    'newt_component_add_callback' => ['void', 'component'=>'resource', 'func_name'=>'mixed', 'data'=>'mixed'],
    'newt_component_takes_focus' => ['void', 'component'=>'resource', 'takes_focus'=>'bool'],
    'newt_create_grid' => ['resource', 'cols'=>'int', 'rows'=>'int'],
    'newt_cursor_off' => ['void'],
    'newt_cursor_on' => ['void'],
    'newt_delay' => ['void', 'microseconds'=>'int'],
    'newt_draw_form' => ['void', 'form'=>'resource'],
    'newt_draw_root_text' => ['void', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
    'newt_entry' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'init_value='=>'string', 'flags='=>'int'],
    'newt_entry_get_value' => ['string', 'entry'=>'resource'],
    'newt_entry_set' => ['void', 'entry'=>'resource', 'value'=>'string', 'cursor_at_end='=>'bool'],
    'newt_entry_set_filter' => ['void', 'entry'=>'resource', 'filter'=>'callable', 'data'=>'mixed'],
    'newt_entry_set_flags' => ['void', 'entry'=>'resource', 'flags'=>'int', 'sense'=>'int'],
    'newt_finished' => ['int'],
    'newt_form' => ['resource', 'vert_bar='=>'resource', 'help='=>'string', 'flags='=>'int'],
    'newt_form_add_component' => ['void', 'form'=>'resource', 'component'=>'resource'],
    'newt_form_add_components' => ['void', 'form'=>'resource', 'components'=>'array'],
    'newt_form_add_hot_key' => ['void', 'form'=>'resource', 'key'=>'int'],
    'newt_form_destroy' => ['void', 'form'=>'resource'],
    'newt_form_get_current' => ['resource', 'form'=>'resource'],
    'newt_form_run' => ['void', 'form'=>'resource', 'exit_struct'=>'array'],
    'newt_form_set_background' => ['void', 'from'=>'resource', 'background'=>'int'],
    'newt_form_set_height' => ['void', 'form'=>'resource', 'height'=>'int'],
    'newt_form_set_size' => ['void', 'form'=>'resource'],
    'newt_form_set_timer' => ['void', 'form'=>'resource', 'milliseconds'=>'int'],
    'newt_form_set_width' => ['void', 'form'=>'resource', 'width'=>'int'],
    'newt_form_watch_fd' => ['void', 'form'=>'resource', 'stream'=>'resource', 'flags='=>'int'],
    'newt_get_screen_size' => ['void', 'cols'=>'int', 'rows'=>'int'],
    'newt_grid_add_components_to_form' => ['void', 'grid'=>'resource', 'form'=>'resource', 'recurse'=>'bool'],
    'newt_grid_basic_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'],
    'newt_grid_free' => ['void', 'grid'=>'resource', 'recurse'=>'bool'],
    'newt_grid_get_size' => ['void', 'grid'=>'resource', 'width'=>'int', 'height'=>'int'],
    'newt_grid_h_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
    'newt_grid_h_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
    'newt_grid_place' => ['void', 'grid'=>'resource', 'left'=>'int', 'top'=>'int'],
    'newt_grid_set_field' => ['void', 'grid'=>'resource', 'col'=>'int', 'row'=>'int', 'type'=>'int', 'value'=>'resource', 'pad_left'=>'int', 'pad_top'=>'int', 'pad_right'=>'int', 'pad_bottom'=>'int', 'anchor'=>'int', 'flags='=>'int'],
    'newt_grid_simple_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'],
    'newt_grid_v_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
    'newt_grid_v_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
    'newt_grid_wrapped_window' => ['void', 'grid'=>'resource', 'title'=>'string'],
    'newt_grid_wrapped_window_at' => ['void', 'grid'=>'resource', 'title'=>'string', 'left'=>'int', 'top'=>'int'],
    'newt_init' => ['int'],
    'newt_label' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
    'newt_label_set_text' => ['void', 'label'=>'resource', 'text'=>'string'],
    'newt_listbox' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'],
    'newt_listbox_append_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed'],
    'newt_listbox_clear' => ['void', 'listobx'=>'resource'],
    'newt_listbox_clear_selection' => ['void', 'listbox'=>'resource'],
    'newt_listbox_delete_entry' => ['void', 'listbox'=>'resource', 'key'=>'mixed'],
    'newt_listbox_get_current' => ['string', 'listbox'=>'resource'],
    'newt_listbox_get_selection' => ['array', 'listbox'=>'resource'],
    'newt_listbox_insert_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed', 'key'=>'mixed'],
    'newt_listbox_item_count' => ['int', 'listbox'=>'resource'],
    'newt_listbox_select_item' => ['void', 'listbox'=>'resource', 'key'=>'mixed', 'sense'=>'int'],
    'newt_listbox_set_current' => ['void', 'listbox'=>'resource', 'num'=>'int'],
    'newt_listbox_set_current_by_key' => ['void', 'listbox'=>'resource', 'key'=>'mixed'],
    'newt_listbox_set_data' => ['void', 'listbox'=>'resource', 'num'=>'int', 'data'=>'mixed'],
    'newt_listbox_set_entry' => ['void', 'listbox'=>'resource', 'num'=>'int', 'text'=>'string'],
    'newt_listbox_set_width' => ['void', 'listbox'=>'resource', 'width'=>'int'],
    'newt_listitem' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_item'=>'resource', 'data'=>'mixed', 'flags='=>'int'],
    'newt_listitem_get_data' => ['mixed', 'item'=>'resource'],
    'newt_listitem_set' => ['void', 'item'=>'resource', 'text'=>'string'],
    'newt_open_window' => ['int', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'title='=>'string'],
    'newt_pop_help_line' => ['void'],
    'newt_pop_window' => ['void'],
    'newt_push_help_line' => ['void', 'text='=>'string'],
    'newt_radio_get_current' => ['resource', 'set_member'=>'resource'],
    'newt_radiobutton' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_button='=>'resource'],
    'newt_redraw_help_line' => ['void'],
    'newt_reflow_text' => ['string', 'text'=>'string', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'actual_width'=>'int', 'actual_height'=>'int'],
    'newt_refresh' => ['void'],
    'newt_resize_screen' => ['void', 'redraw='=>'bool'],
    'newt_resume' => ['void'],
    'newt_run_form' => ['resource', 'form'=>'resource'],
    'newt_scale' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'full_value'=>'int'],
    'newt_scale_set' => ['void', 'scale'=>'resource', 'amount'=>'int'],
    'newt_scrollbar_set' => ['void', 'scrollbar'=>'resource', 'where'=>'int', 'total'=>'int'],
    'newt_set_help_callback' => ['void', 'function'=>'mixed'],
    'newt_set_suspend_callback' => ['void', 'function'=>'callable', 'data'=>'mixed'],
    'newt_suspend' => ['void'],
    'newt_textbox' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'flags='=>'int'],
    'newt_textbox_get_num_lines' => ['int', 'textbox'=>'resource'],
    'newt_textbox_reflowed' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'char', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'flags='=>'int'],
    'newt_textbox_set_height' => ['void', 'textbox'=>'resource', 'height'=>'int'],
    'newt_textbox_set_text' => ['void', 'textbox'=>'resource', 'text'=>'string'],
    'newt_vertical_scrollbar' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'normal_colorset='=>'int', 'thumb_colorset='=>'int'],
    'newt_wait_for_key' => ['void'],
    'newt_win_choice' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'],
    'newt_win_entries' => ['int', 'title'=>'string', 'text'=>'string', 'suggested_width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'data_width'=>'int', 'items'=>'array', 'button1'=>'string', '...args='=>'string'],
    'newt_win_menu' => ['int', 'title'=>'string', 'text'=>'string', 'suggestedwidth'=>'int', 'flexdown'=>'int', 'flexup'=>'int', 'maxlistheight'=>'int', 'items'=>'array', 'listitem'=>'int', 'button1='=>'string', '...args='=>'string'],
    'newt_win_message' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'],
    'newt_win_messagev' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args'=>'array'],
    'newt_win_ternary' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'button3_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'],
    'next' => ['mixed', '&r_array'=>'array|object'],
    'ngettext' => ['string', 'singular'=>'string', 'plural'=>'string', 'count'=>'int'],
    'nl2br' => ['string', 'string'=>'string', 'use_xhtml='=>'bool'],
    'nl_langinfo' => ['string|false', 'item'=>'int'],
    'normalizer_get_raw_decomposition' => ['string|null', 'string'=>'string'],
    'normalizer_is_normalized' => ['bool', 'string'=>'string', 'form='=>'int'],
    'normalizer_normalize' => ['string', 'string'=>'string', 'form='=>'int'],
    'notes_body' => ['array', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'],
    'notes_copy_db' => ['bool', 'from_database_name'=>'string', 'to_database_name'=>'string'],
    'notes_create_db' => ['bool', 'database_name'=>'string'],
    'notes_create_note' => ['bool', 'database_name'=>'string', 'form_name'=>'string'],
    'notes_drop_db' => ['bool', 'database_name'=>'string'],
    'notes_find_note' => ['int', 'database_name'=>'string', 'name'=>'string', 'type='=>'string'],
    'notes_header_info' => ['object', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'],
    'notes_list_msgs' => ['bool', 'db'=>'string'],
    'notes_mark_read' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'],
    'notes_mark_unread' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'],
    'notes_nav_create' => ['bool', 'database_name'=>'string', 'name'=>'string'],
    'notes_search' => ['array', 'database_name'=>'string', 'keywords'=>'string'],
    'notes_unread' => ['array', 'database_name'=>'string', 'user_name'=>'string'],
    'notes_version' => ['float', 'database_name'=>'string'],
    'nsapi_request_headers' => ['array'],
    'nsapi_response_headers' => ['array'],
    'nsapi_virtual' => ['bool', 'uri'=>'string'],
    'nthmac' => ['string', 'clent'=>'string', 'data'=>'string'],
    'number_format' => ['string', 'num'=>'float|int', 'decimals='=>'int'],
    'number_format\'1' => ['string', 'num'=>'float|int', 'decimals'=>'int', 'decimal_separator'=>'?string', 'thousands_separator'=>'?string'],
    'numfmt_create' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'],
    'numfmt_format' => ['string|false', 'formatter'=>'NumberFormatter', 'num'=>'int|float', 'type='=>'int'],
    'numfmt_format_currency' => ['string|false', 'formatter'=>'NumberFormatter', 'amount'=>'float', 'currency'=>'string'],
    'numfmt_get_attribute' => ['int|false', 'formatter'=>'NumberFormatter', 'attribute'=>'int'],
    'numfmt_get_error_code' => ['int', 'formatter'=>'NumberFormatter'],
    'numfmt_get_error_message' => ['string', 'formatter'=>'NumberFormatter'],
    'numfmt_get_locale' => ['string', 'formatter'=>'NumberFormatter', 'type='=>'int'],
    'numfmt_get_pattern' => ['string|false', 'formatter'=>'NumberFormatter'],
    'numfmt_get_symbol' => ['string|false', 'formatter'=>'NumberFormatter', 'symbol'=>'int'],
    'numfmt_get_text_attribute' => ['string|false', 'formatter'=>'NumberFormatter', 'attribute'=>'int'],
    'numfmt_parse' => ['float|int|false', 'formatter'=>'NumberFormatter', 'string'=>'string', 'type='=>'int', '&rw_offset='=>'int'],
    'numfmt_parse_currency' => ['float|false', 'formatter'=>'NumberFormatter', 'string'=>'string', '&w_currency'=>'string', '&rw_offset='=>'int'],
    'numfmt_set_attribute' => ['bool', 'formatter'=>'NumberFormatter', 'attribute'=>'int', 'value'=>'int'],
    'numfmt_set_pattern' => ['bool', 'formatter'=>'NumberFormatter', 'pattern'=>'string'],
    'numfmt_set_symbol' => ['bool', 'formatter'=>'NumberFormatter', 'symbol'=>'int', 'value'=>'string'],
    'numfmt_set_text_attribute' => ['bool', 'formatter'=>'NumberFormatter', 'attribute'=>'int', 'value'=>'string'],
    'oauth_get_sbs' => ['string', 'http_method'=>'string', 'uri'=>'string', 'request_parameters='=>'array'],
    'oauth_urlencode' => ['string', 'uri'=>'string'],
    'ob_clean' => ['bool'],
    'ob_deflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'],
    'ob_end_clean' => ['bool'],
    'ob_end_flush' => ['bool'],
    'ob_etaghandler' => ['string', 'data'=>'string', 'mode'=>'int'],
    'ob_flush' => ['bool'],
    'ob_get_clean' => ['string|false'],
    'ob_get_contents' => ['string|false'],
    'ob_get_flush' => ['string|false'],
    'ob_get_length' => ['int|false'],
    'ob_get_level' => ['int'],
    'ob_get_status' => ['array', 'full_status='=>'bool'],
    'ob_gzhandler' => ['string|false', 'data'=>'string', 'flags'=>'int'],
    'ob_iconv_handler' => ['string', 'contents'=>'string', 'status'=>'int'],
    'ob_implicit_flush' => ['void', 'enable='=>'int'],
    'ob_inflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'],
    'ob_list_handlers' => ['list<string>'],
    'ob_start' => ['bool', 'callback='=>'string|array|?callable', 'chunk_size='=>'int', 'flags='=>'int'],
    'ob_tidyhandler' => ['string', 'input'=>'string', 'mode='=>'int'],
    'oci_bind_array_by_name' => ['bool', 'statement'=>'resource', 'param'=>'string', '&rw_var'=>'array', 'max_array_length'=>'int', 'max_item_length='=>'int', 'type='=>'int'],
    'oci_bind_by_name' => ['bool', 'statement'=>'resource', 'param'=>'string', '&rw_var'=>'mixed', 'max_length='=>'int', 'type='=>'int'],
    'oci_cancel' => ['bool', 'statement'=>'resource'],
    'oci_client_version' => ['string'],
    'oci_close' => ['bool', 'connection'=>'resource'],
    'oci_collection_append' => ['bool', 'collection'=>'string'],
    'oci_collection_assign' => ['bool', 'to'=>'object'],
    'oci_collection_element_assign' => ['bool', 'collection'=>'int', 'index'=>'string'],
    'oci_collection_element_get' => ['string', 'collection'=>'int'],
    'oci_collection_max' => ['int'],
    'oci_collection_size' => ['int'],
    'oci_collection_trim' => ['bool', 'collection'=>'int'],
    'oci_commit' => ['bool', 'connection'=>'resource'],
    'oci_connect' => ['resource|false', 'username'=>'string', 'password'=>'string', 'connection_string='=>'string', 'encoding='=>'string', 'session_mode='=>'int'],
    'oci_define_by_name' => ['bool', 'statement'=>'resource', 'column'=>'string', '&w_var'=>'mixed', 'type='=>'int'],
    'oci_error' => ['array|false', 'connection_or_statement='=>'resource'],
    'oci_execute' => ['bool', 'statement'=>'resource', 'mode='=>'int'],
    'oci_fetch' => ['bool', 'statement'=>'resource'],
    'oci_fetch_all' => ['int|false', 'statement'=>'resource', '&w_output'=>'array', 'offset='=>'int', 'limit='=>'int', 'flags='=>'int'],
    'oci_fetch_array' => ['array|false', 'statement'=>'resource', 'mode='=>'int'],
    'oci_fetch_assoc' => ['array|false', 'statement'=>'resource'],
    'oci_fetch_object' => ['object|false', 'statement'=>'resource'],
    'oci_fetch_row' => ['array|false', 'statement'=>'resource'],
    'oci_field_is_null' => ['bool', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_field_name' => ['string|false', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_field_precision' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_field_scale' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_field_size' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_field_type' => ['mixed|false', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_field_type_raw' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_free_collection' => ['bool'],
    'oci_free_cursor' => ['bool', 'statement'=>'resource'],
    'oci_free_descriptor' => ['bool'],
    'oci_free_statement' => ['bool', 'statement'=>'resource'],
    'oci_get_implicit' => ['bool', 'stmt'=>''],
    'oci_get_implicit_resultset' => ['resource|false', 'statement'=>'resource'],
    'oci_internal_debug' => ['void', 'onoff'=>'bool'],
    'oci_lob_append' => ['bool', 'to'=>'object'],
    'oci_lob_close' => ['bool'],
    'oci_lob_copy' => ['bool', 'to'=>'OCILob', 'from'=>'OCILob', 'length='=>'int'],
    'oci_lob_eof' => ['bool'],
    'oci_lob_erase' => ['int', 'lob'=>'int', 'offset'=>'int'],
    'oci_lob_export' => ['bool', 'lob'=>'string', 'filename'=>'int', 'offset'=>'int'],
    'oci_lob_flush' => ['bool', 'lob'=>'int'],
    'oci_lob_import' => ['bool', 'lob'=>'string'],
    'oci_lob_is_equal' => ['bool', 'lob1'=>'OCILob', 'lob2'=>'OCILob'],
    'oci_lob_load' => ['string'],
    'oci_lob_read' => ['string', 'lob'=>'int'],
    'oci_lob_rewind' => ['bool'],
    'oci_lob_save' => ['bool', 'lob'=>'string', 'data'=>'int'],
    'oci_lob_seek' => ['bool', 'lob'=>'int', 'offset'=>'int'],
    'oci_lob_size' => ['int'],
    'oci_lob_tell' => ['int'],
    'oci_lob_truncate' => ['bool', 'lob'=>'int'],
    'oci_lob_write' => ['int', 'lob'=>'string', 'data'=>'int'],
    'oci_lob_write_temporary' => ['bool', 'value'=>'string', 'lob_type'=>'int'],
    'oci_new_collection' => ['OCICollection|false', 'connection'=>'resource', 'type_name'=>'string', 'schema='=>'string'],
    'oci_new_connect' => ['resource|false', 'username'=>'string', 'password'=>'string', 'connection_string='=>'string', 'encoding='=>'string', 'session_mode='=>'int'],
    'oci_new_cursor' => ['resource|false', 'connection'=>'resource'],
    'oci_new_descriptor' => ['OCILob|false', 'connection'=>'resource', 'type='=>'int'],
    'oci_num_fields' => ['int|false', 'statement'=>'resource'],
    'oci_num_rows' => ['int|false', 'statement'=>'resource'],
    'oci_parse' => ['resource|false', 'connection'=>'resource', 'sql'=>'string'],
    'oci_password_change' => ['bool', 'connection'=>'resource', 'username'=>'string', 'old_password'=>'string', 'new_password'=>'string'],
    'oci_pconnect' => ['resource|false', 'username'=>'string', 'password'=>'string', 'connection_string='=>'string', 'encoding='=>'string', 'session_mode='=>'int'],
    'oci_result' => ['mixed|false', 'statement'=>'resource', 'column'=>'mixed'],
    'oci_rollback' => ['bool', 'connection'=>'resource'],
    'oci_server_version' => ['string|false', 'connection'=>'resource'],
    'oci_set_action' => ['bool', 'connection'=>'resource', 'action'=>'string'],
    'oci_set_call_timeout' => ['bool', 'connection'=>'resource', 'timeout'=>'int'],
    'oci_set_client_identifier' => ['bool', 'connection'=>'resource', 'client_id'=>'string'],
    'oci_set_client_info' => ['bool', 'connection'=>'resource', 'client_info'=>'string'],
    'oci_set_db_operation' => ['bool', 'connection'=>'resource', 'action'=>'string'],
    'oci_set_edition' => ['bool', 'edition'=>'string'],
    'oci_set_module_name' => ['bool', 'connection'=>'resource', 'name'=>'string'],
    'oci_set_prefetch' => ['bool', 'statement'=>'resource', 'rows'=>'int'],
    'oci_statement_type' => ['string|false', 'statement'=>'resource'],
    'ocifetchinto' => ['int|bool', 'statement'=>'resource', '&w_result'=>'array', 'mode='=>'int'],
    'ocigetbufferinglob' => ['bool'],
    'ocisetbufferinglob' => ['bool', 'lob'=>'bool'],
    'octdec' => ['int|float', 'octal_string'=>'string'],
    'odbc_autocommit' => ['int|bool', 'odbc'=>'resource', 'enable='=>'bool'],
    'odbc_binmode' => ['bool', 'statement'=>'resource', 'mode'=>'int'],
    'odbc_close' => ['void', 'odbc'=>'resource'],
    'odbc_close_all' => ['void'],
    'odbc_columnprivileges' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string', 'column'=>'string'],
    'odbc_columns' => ['resource|false', 'odbc'=>'resource', 'catalog='=>'?string', 'schema='=>'?string', 'table='=>'?string', 'column='=>'?string'],
    'odbc_commit' => ['bool', 'odbc'=>'resource'],
    'odbc_connect' => ['resource|false', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'],
    'odbc_cursor' => ['string', 'statement'=>'resource'],
    'odbc_data_source' => ['array|false', 'odbc'=>'resource', 'fetch_type'=>'int'],
    'odbc_do' => ['resource', 'odbc'=>'resource', 'query'=>'string', 'flags='=>'int'],
    'odbc_error' => ['string', 'odbc='=>'resource'],
    'odbc_errormsg' => ['string', 'odbc='=>'resource'],
    'odbc_exec' => ['resource', 'odbc'=>'resource', 'query'=>'string', 'flags='=>'int'],
    'odbc_execute' => ['bool', 'statement'=>'resource', 'params='=>'array'],
    'odbc_fetch_array' => ['array|false', 'statement'=>'resource', 'row='=>'int'],
    'odbc_fetch_into' => ['int', 'statement'=>'resource', '&w_array'=>'array', 'row='=>'int'],
    'odbc_fetch_object' => ['stdClass|false', 'statement'=>'resource', 'row='=>'int'],
    'odbc_fetch_row' => ['bool', 'statement'=>'resource', 'row='=>'int'],
    'odbc_field_len' => ['int|false', 'statement'=>'resource', 'field'=>'int'],
    'odbc_field_name' => ['string|false', 'statement'=>'resource', 'field'=>'int'],
    'odbc_field_num' => ['int|false', 'statement'=>'resource', 'field'=>'string'],
    'odbc_field_precision' => ['int', 'statement'=>'resource', 'field'=>'int'],
    'odbc_field_scale' => ['int|false', 'statement'=>'resource', 'field'=>'int'],
    'odbc_field_type' => ['string|false', 'statement'=>'resource', 'field'=>'int'],
    'odbc_foreignkeys' => ['resource|false', 'odbc'=>'resource', 'pk_catalog'=>'?string', 'pk_schema'=>'string', 'pk_table'=>'string', 'fk_catalog'=>'string', 'fk_schema'=>'string', 'fk_table'=>'string'],
    'odbc_free_result' => ['bool', 'statement'=>'resource'],
    'odbc_gettypeinfo' => ['resource', 'odbc'=>'resource', 'data_type='=>'int'],
    'odbc_longreadlen' => ['bool', 'statement'=>'resource', 'length'=>'int'],
    'odbc_next_result' => ['bool', 'statement'=>'resource'],
    'odbc_num_fields' => ['int', 'statement'=>'resource'],
    'odbc_num_rows' => ['int', 'statement'=>'resource'],
    'odbc_pconnect' => ['resource|false', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'],
    'odbc_prepare' => ['resource|false', 'odbc'=>'resource', 'query'=>'string'],
    'odbc_primarykeys' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string'],
    'odbc_procedurecolumns' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'string', 'schema'=>'string', 'procedure'=>'string', 'column'=>'string'],
    'odbc_procedures' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'string', 'schema'=>'string', 'procedure'=>'string'],
    'odbc_result' => ['mixed|false', 'statement'=>'resource', 'field'=>'mixed'],
    'odbc_result_all' => ['int|false', 'statement'=>'resource', 'format='=>'string'],
    'odbc_rollback' => ['bool', 'odbc'=>'resource'],
    'odbc_setoption' => ['bool', 'odbc'=>'resource', 'which'=>'int', 'option'=>'int', 'value'=>'int'],
    'odbc_specialcolumns' => ['resource|false', 'odbc'=>'resource', 'type'=>'int', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string', 'scope'=>'int', 'nullable'=>'int'],
    'odbc_statistics' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string', 'unique'=>'int', 'accuracy'=>'int'],
    'odbc_tableprivileges' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string'],
    'odbc_tables' => ['resource|false', 'odbc'=>'resource', 'catalog='=>'?string', 'schema='=>'string', 'table='=>'string', 'types='=>'string'],
    'opcache_compile_file' => ['bool', 'filename'=>'string'],
    'opcache_get_configuration' => ['array'],
    'opcache_get_status' => ['array|false', 'include_scripts='=>'bool'],
    'opcache_invalidate' => ['bool', 'filename'=>'string', 'force='=>'bool'],
    'opcache_is_script_cached' => ['bool', 'filename'=>'string'],
    'opcache_reset' => ['bool'],
    'openal_buffer_create' => ['resource'],
    'openal_buffer_data' => ['bool', 'buffer'=>'resource', 'format'=>'int', 'data'=>'string', 'freq'=>'int'],
    'openal_buffer_destroy' => ['bool', 'buffer'=>'resource'],
    'openal_buffer_get' => ['int', 'buffer'=>'resource', 'property'=>'int'],
    'openal_buffer_loadwav' => ['bool', 'buffer'=>'resource', 'wavfile'=>'string'],
    'openal_context_create' => ['resource', 'device'=>'resource'],
    'openal_context_current' => ['bool', 'context'=>'resource'],
    'openal_context_destroy' => ['bool', 'context'=>'resource'],
    'openal_context_process' => ['bool', 'context'=>'resource'],
    'openal_context_suspend' => ['bool', 'context'=>'resource'],
    'openal_device_close' => ['bool', 'device'=>'resource'],
    'openal_device_open' => ['resource|false', 'device_desc='=>'string'],
    'openal_listener_get' => ['mixed', 'property'=>'int'],
    'openal_listener_set' => ['bool', 'property'=>'int', 'setting'=>'mixed'],
    'openal_source_create' => ['resource'],
    'openal_source_destroy' => ['bool', 'source'=>'resource'],
    'openal_source_get' => ['mixed', 'source'=>'resource', 'property'=>'int'],
    'openal_source_pause' => ['bool', 'source'=>'resource'],
    'openal_source_play' => ['bool', 'source'=>'resource'],
    'openal_source_rewind' => ['bool', 'source'=>'resource'],
    'openal_source_set' => ['bool', 'source'=>'resource', 'property'=>'int', 'setting'=>'mixed'],
    'openal_source_stop' => ['bool', 'source'=>'resource'],
    'openal_stream' => ['resource', 'source'=>'resource', 'format'=>'int', 'rate'=>'int'],
    'opendir' => ['resource|false', 'directory'=>'string', 'context='=>'resource'],
    'openlog' => ['bool', 'prefix'=>'string', 'flags'=>'int', 'facility'=>'int'],
    'openssl_cipher_iv_length' => ['int|false', 'cipher_algo'=>'string'],
    'openssl_csr_export' => ['bool', 'csr'=>'string|resource', '&w_output'=>'string', 'no_text='=>'bool'],
    'openssl_csr_export_to_file' => ['bool', 'csr'=>'string|resource', 'output_filename'=>'string', 'no_text='=>'bool'],
    'openssl_csr_get_public_key' => ['resource|false', 'csr'=>'string|resource', 'short_names='=>'bool'],
    'openssl_csr_get_subject' => ['array|false', 'csr'=>'string|resource', 'short_names='=>'bool'],
    'openssl_csr_new' => ['resource|false', 'distinguished_names'=>'array', '&w_private_key'=>'resource', 'options='=>'array', 'extra_attributes='=>'array'],
    'openssl_csr_sign' => ['resource|false', 'csr'=>'string|resource', 'ca_certificate'=>'string|resource|null', 'private_key'=>'string|resource|array', 'days'=>'int', 'options='=>'array', 'serial='=>'int'],
    'openssl_decrypt' => ['string|false', 'data'=>'string', 'cipher_algo'=>'string', 'passphrase'=>'string', 'options='=>'int', 'iv='=>'string', 'tag='=>'string', 'aad='=>'string'],
    'openssl_dh_compute_key' => ['string|false', 'public_key'=>'string', 'private_key'=>'resource'],
    'openssl_digest' => ['string|false', 'data'=>'string', 'digest_algo'=>'string', 'binary='=>'bool'],
    'openssl_encrypt' => ['string|false', 'data'=>'string', 'cipher_algo'=>'string', 'passphrase'=>'string', 'options='=>'int', 'iv='=>'string', '&w_tag='=>'string', 'aad='=>'string', 'tag_length='=>'int'],
    'openssl_error_string' => ['string|false'],
    'openssl_free_key' => ['void', 'key'=>'resource'],
    'openssl_get_cert_locations' => ['array'],
    'openssl_get_cipher_methods' => ['array', 'aliases='=>'bool'],
    'openssl_get_md_methods' => ['array', 'aliases='=>'bool'],
    'openssl_get_privatekey' => ['resource|false', 'private_key'=>'string', 'passphrase='=>'string'],
    'openssl_get_publickey' => ['resource|false', 'public_key'=>'resource|string'],
    'openssl_open' => ['bool', 'data'=>'string', '&w_output'=>'string', 'encrypted_key'=>'string', 'private_key'=>'string|array|resource', 'cipher_algo='=>'string', 'iv='=>'string'],
    'openssl_pbkdf2' => ['string|false', 'password'=>'string', 'salt'=>'string', 'key_length'=>'int', 'iterations'=>'int', 'digest_algo='=>'string'],
    'openssl_pkcs12_export' => ['bool', 'certificate'=>'string|resource', '&w_output'=>'string', 'private_key'=>'string|array|resource', 'passphrase'=>'string', 'options='=>'array'],
    'openssl_pkcs12_export_to_file' => ['bool', 'certificate'=>'string|resource', 'output_filename'=>'string', 'private_key'=>'string|array|resource', 'passphrase'=>'string', 'options='=>'array'],
    'openssl_pkcs12_read' => ['bool', 'pkcs12'=>'string', '&w_certificates'=>'array', 'passphrase'=>'string'],
    'openssl_pkcs7_decrypt' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'string|resource', 'private_key='=>'string|resource|array'],
    'openssl_pkcs7_encrypt' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'cipher_algo='=>'int'],
    'openssl_pkcs7_read' => ['bool', 'input_filename'=>'string', '&w_certificates'=>'array'],
    'openssl_pkcs7_sign' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'string|resource', 'private_key'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'untrusted_certificates_filename='=>'string'],
    'openssl_pkcs7_verify' => ['bool|int', 'input_filename'=>'string', 'flags'=>'int', 'signers_certificates_filename='=>'string', 'ca_info='=>'array', 'untrusted_certificates_filename='=>'string', 'content='=>'string', 'output_filename='=>'string'],
    'openssl_pkey_export' => ['bool', 'key'=>'resource', '&w_output'=>'string', 'passphrase='=>'string|null', 'options='=>'array'],
    'openssl_pkey_export_to_file' => ['bool', 'key'=>'resource|string|array', 'output_filename'=>'string', 'passphrase='=>'string|null', 'options='=>'array'],
    'openssl_pkey_free' => ['void', 'key'=>'resource'],
    'openssl_pkey_get_details' => ['array|false', 'key'=>'resource'],
    'openssl_pkey_get_private' => ['resource|false', 'private_key'=>'string', 'passphrase='=>'string'],
    'openssl_pkey_get_public' => ['resource|false', 'public_key'=>'resource|string'],
    'openssl_pkey_new' => ['resource|false', 'options='=>'array'],
    'openssl_private_decrypt' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'private_key'=>'string|resource|array', 'padding='=>'int'],
    'openssl_private_encrypt' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'private_key'=>'string|resource|array', 'padding='=>'int'],
    'openssl_public_decrypt' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'public_key'=>'string|resource', 'padding='=>'int'],
    'openssl_public_encrypt' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'public_key'=>'string|resource', 'padding='=>'int'],
    'openssl_random_pseudo_bytes' => ['string|false', 'length'=>'int', '&w_strong_result='=>'bool'],
    'openssl_seal' => ['int|false', 'data'=>'string', '&w_sealed_data'=>'string', '&w_encrypted_keys'=>'array', 'public_key'=>'array', 'cipher_algo='=>'string', '&rw_iv='=>'string'],
    'openssl_sign' => ['bool', 'data'=>'string', '&w_signature'=>'string', 'private_key'=>'resource|string', 'algorithm='=>'int|string'],
    'openssl_spki_export' => ['string|false', 'spki'=>'string'],
    'openssl_spki_export_challenge' => ['string|false', 'spki'=>'string'],
    'openssl_spki_new' => ['?string', 'private_key'=>'resource', 'challenge'=>'string', 'digest_algo='=>'int'],
    'openssl_spki_verify' => ['bool', 'spki'=>'string'],
    'openssl_verify' => ['-1|0|1', 'data'=>'string', 'signature'=>'string', 'public_key'=>'resource|string', 'algorithm='=>'int|string'],
    'openssl_x509_check_private_key' => ['bool', 'certificate'=>'string|resource', 'private_key'=>'string|resource|array'],
    'openssl_x509_checkpurpose' => ['bool|int', 'certificate'=>'string|resource', 'purpose'=>'int', 'ca_info='=>'array', 'untrusted_certificates_file='=>'string'],
    'openssl_x509_export' => ['bool', 'certificate'=>'string|resource', '&w_output'=>'string', 'no_text='=>'bool'],
    'openssl_x509_export_to_file' => ['bool', 'certificate'=>'string|resource', 'output_filename'=>'string', 'no_text='=>'bool'],
    'openssl_x509_fingerprint' => ['string|false', 'certificate'=>'string|resource', 'digest_algo='=>'string', 'binary='=>'bool'],
    'openssl_x509_free' => ['void', 'certificate'=>'resource'],
    'openssl_x509_parse' => ['array|false', 'certificate'=>'string|resource', 'short_names='=>'bool'],
    'openssl_x509_read' => ['resource|false', 'certificate'=>'string|resource'],
    'ord' => ['int', 'character'=>'string'],
    'output_add_rewrite_var' => ['bool', 'name'=>'string', 'value'=>'string'],
    'output_cache_disable' => ['void'],
    'output_cache_disable_compression' => ['void'],
    'output_cache_exists' => ['bool', 'key'=>'string', 'lifetime'=>'int'],
    'output_cache_fetch' => ['string', 'key'=>'string', 'function'=>'', 'lifetime'=>'int'],
    'output_cache_get' => ['mixed|false', 'key'=>'string', 'lifetime'=>'int'],
    'output_cache_output' => ['string', 'key'=>'string', 'function'=>'', 'lifetime'=>'int'],
    'output_cache_put' => ['bool', 'key'=>'string', 'data'=>'mixed'],
    'output_cache_remove' => ['bool', 'filename'=>''],
    'output_cache_remove_key' => ['bool', 'key'=>'string'],
    'output_cache_remove_url' => ['bool', 'url'=>'string'],
    'output_cache_stop' => ['void'],
    'output_reset_rewrite_vars' => ['bool'],
    'outputformatObj::getOption' => ['string', 'property_name'=>'string'],
    'outputformatObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'outputformatObj::setOption' => ['void', 'property_name'=>'string', 'new_value'=>'string'],
    'outputformatObj::validate' => ['int'],
    'overload' => ['', 'class_name'=>'string'],
    'override_function' => ['bool', 'function_name'=>'string', 'function_args'=>'string', 'function_code'=>'string'],
    'pack' => ['string|false', 'format'=>'string', '...values='=>'mixed'],
    'parallel\Future::done' => ['bool'],
    'parallel\Future::select' => ['mixed', '&resolving'=>'parallel\Future[]', '&w_resolved'=>'parallel\Future[]', '&w_errored'=>'parallel\Future[]', '&w_timedout='=>'parallel\Future[]', 'timeout='=>'int'],
    'parallel\Future::value' => ['mixed', 'timeout='=>'int'],
    'parallel\Runtime::__construct' => ['void', 'arg'=>'string|array'],
    'parallel\Runtime::__construct\'1' => ['void', 'bootstrap'=>'string', 'configuration'=>'array<string,mixed>'],
    'parallel\Runtime::close' => ['void'],
    'parallel\Runtime::kill' => ['void'],
    'parallel\Runtime::run' => ['?parallel\Future', 'closure'=>'Closure', 'args='=>'array'],
    'parle\rlexer::insertMacro' => ['void', 'name'=>'string', 'regex'=>'string'],
    'parse_ini_file' => ['array|false', 'filename'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'],
    'parse_ini_string' => ['array|false', 'ini_string'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'],
    'parse_str' => ['void', 'string'=>'string', '&w_result='=>'array'],
    'parse_url' => ['int|string|array|null|false', 'url'=>'string', 'component='=>'int'],
    'parsekit_compile_file' => ['array', 'filename'=>'string', 'errors='=>'array', 'options='=>'int'],
    'parsekit_compile_string' => ['array', 'phpcode'=>'string', 'errors='=>'array', 'options='=>'int'],
    'parsekit_func_arginfo' => ['array', 'function'=>'mixed'],
    'passthru' => ['void', 'command'=>'string', '&w_result_code='=>'int'],
    'password_get_info' => ['array', 'hash'=>'string'],
    'password_hash' => ['string|false', 'password'=>'string', 'algo'=>'int', 'options='=>'array'],
    'password_make_salt' => ['bool', 'password'=>'string', 'hash'=>'string'],
    'password_needs_rehash' => ['bool', 'hash'=>'string', 'algo'=>'int', 'options='=>'array'],
    'password_verify' => ['bool', 'password'=>'string', 'hash'=>'string'],
    'pathinfo' => ['array|string', 'path'=>'string', 'flags='=>'int'],
    'pclose' => ['int', 'handle'=>'resource'],
    'pcnlt_sigwaitinfo' => ['int', 'set'=>'array', '&w_siginfo'=>'array'],
    'pcntl_alarm' => ['int', 'seconds'=>'int'],
    'pcntl_errno' => ['int'],
    'pcntl_exec' => ['null|false', 'path'=>'string', 'args='=>'array', 'env_vars='=>'array'],
    'pcntl_fork' => ['int'],
    'pcntl_get_last_error' => ['int'],
    'pcntl_getpriority' => ['int', 'process_id='=>'int', 'mode='=>'int'],
    'pcntl_setpriority' => ['bool', 'priority'=>'int', 'process_id='=>'int', 'mode='=>'int'],
    'pcntl_signal' => ['bool', 'signal'=>'int', 'handler'=>'callable():void|callable(int):void|callable(int,array):void|int', 'restart_syscalls='=>'bool'],
    'pcntl_signal_dispatch' => ['bool'],
    'pcntl_sigprocmask' => ['bool', 'mode'=>'int', 'signals'=>'array', '&w_old_signals='=>'array'],
    'pcntl_sigtimedwait' => ['int', 'signals'=>'array', '&w_info='=>'array', 'seconds='=>'int', 'nanoseconds='=>'int'],
    'pcntl_sigwaitinfo' => ['int', 'signals'=>'array', '&w_info='=>'array'],
    'pcntl_strerror' => ['string', 'error_code'=>'int'],
    'pcntl_wait' => ['int', '&w_status'=>'int', 'flags='=>'int', '&w_resource_usage='=>'array'],
    'pcntl_waitpid' => ['int', 'process_id'=>'int', '&w_status'=>'int', 'flags='=>'int', '&w_resource_usage='=>'array'],
    'pcntl_wexitstatus' => ['int', 'status'=>'int'],
    'pcntl_wifcontinued' => ['bool', 'status'=>'int'],
    'pcntl_wifexited' => ['bool', 'status'=>'int'],
    'pcntl_wifsignaled' => ['bool', 'status'=>'int'],
    'pcntl_wifstopped' => ['bool', 'status'=>'int'],
    'pcntl_wstopsig' => ['int', 'status'=>'int'],
    'pcntl_wtermsig' => ['int', 'status'=>'int'],
    'pdo_drivers' => ['array'],
    'pfsockopen' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'float'],
    'pg_affected_rows' => ['int', 'result'=>'resource'],
    'pg_cancel_query' => ['bool', 'connection'=>'resource'],
    'pg_client_encoding' => ['string', 'connection='=>'resource'],
    'pg_close' => ['bool', 'connection='=>'resource'],
    'pg_connect' => ['resource|false', 'connection_string'=>'string', 'flags='=>'int'],
    'pg_connect_poll' => ['int', 'connection'=>'resource'],
    'pg_connection_busy' => ['bool', 'connection'=>'resource'],
    'pg_connection_reset' => ['bool', 'connection'=>'resource'],
    'pg_connection_status' => ['int', 'connection'=>'resource'],
    'pg_consume_input' => ['bool', 'connection'=>'resource'],
    'pg_convert' => ['array|false', 'connection'=>'resource', 'table_name'=>'string', 'values'=>'array', 'flags='=>'int'],
    'pg_copy_from' => ['bool', 'connection'=>'resource', 'table_name'=>'string', 'rows'=>'array', 'separator='=>'string', 'null_as='=>'string'],
    'pg_copy_to' => ['array|false', 'connection'=>'resource', 'table_name'=>'string', 'separator='=>'string', 'null_as='=>'string'],
    'pg_dbname' => ['string', 'connection='=>'resource'],
    'pg_delete' => ['string|bool', 'connection'=>'resource', 'table_name'=>'string', 'conditions'=>'array', 'flags='=>'int'],
    'pg_end_copy' => ['bool', 'connection='=>'resource'],
    'pg_escape_bytea' => ['string', 'connection'=>'resource', 'string'=>'string'],
    'pg_escape_bytea\'1' => ['string', 'connection'=>'string'],
    'pg_escape_identifier' => ['string|false', 'connection'=>'resource', 'string'=>'string'],
    'pg_escape_identifier\'1' => ['string|false', 'connection'=>'string'],
    'pg_escape_literal' => ['string|false', 'connection'=>'resource', 'string'=>'string'],
    'pg_escape_literal\'1' => ['string|false', 'connection'=>'string'],
    'pg_escape_string' => ['string', 'connection'=>'resource', 'string'=>'string'],
    'pg_escape_string\'1' => ['string', 'connection'=>'string'],
    'pg_exec' => ['resource|false', 'connection'=>'resource', 'query'=>'string'],
    'pg_execute' => ['resource|false', 'connection'=>'resource', 'statement_name'=>'string', 'params'=>'array'],
    'pg_execute\'1' => ['resource|false', 'connection'=>'string', 'statement_name'=>'array'],
    'pg_fetch_all' => ['array<array>', 'result'=>'resource'],
    'pg_fetch_all_columns' => ['array', 'result'=>'resource', 'field='=>'int'],
    'pg_fetch_array' => ['array<string|null>|false', 'result'=>'resource', 'row='=>'?int', 'mode='=>'int'],
    'pg_fetch_assoc' => ['array<string, mixed>|false', 'result'=>'resource', 'row='=>'?int'],
    'pg_fetch_object' => ['object|false', 'result'=>'resource', 'row='=>'?int', 'class='=>'string', 'constructor_args='=>'array'],
    'pg_fetch_result' => ['string|false|null', 'result'=>'resource', 'row'=>'string|int'],
    'pg_fetch_result\'1' => ['string|false|null', 'result'=>'resource', 'row'=>'?int', 'field'=>'string|int'],
    'pg_fetch_row' => ['array|false', 'result'=>'resource', 'row='=>'?int', 'mode='=>'int'],
    'pg_field_is_null' => ['int|false', 'result'=>'resource', 'row'=>'string|int'],
    'pg_field_is_null\'1' => ['int|false', 'result'=>'resource', 'row'=>'int', 'field'=>'string|int'],
    'pg_field_name' => ['string', 'result'=>'resource', 'field'=>'int'],
    'pg_field_num' => ['int', 'result'=>'resource', 'field'=>'string'],
    'pg_field_prtlen' => ['int|false', 'result'=>'resource', 'row'=>'string|int'],
    'pg_field_prtlen\'1' => ['int|false', 'result'=>'resource', 'row'=>'int', 'field'=>'string|int'],
    'pg_field_size' => ['int', 'result'=>'resource', 'field'=>'int'],
    'pg_field_table' => ['string|int|false', 'result'=>'resource', 'field'=>'int', 'oid_only='=>'bool'],
    'pg_field_type' => ['string', 'result'=>'resource', 'field'=>'int'],
    'pg_field_type_oid' => ['int|string', 'result'=>'resource', 'field'=>'int'],
    'pg_flush' => ['int|bool', 'connection'=>'resource'],
    'pg_free_result' => ['bool', 'result'=>'resource'],
    'pg_get_notify' => ['array|false', 'result'=>'resource', 'mode='=>'int'],
    'pg_get_pid' => ['int', 'connection'=>'resource'],
    'pg_get_result' => ['resource|false', 'connection='=>'resource'],
    'pg_host' => ['string', 'connection='=>'resource'],
    'pg_insert' => ['resource|string|false', 'connection'=>'resource', 'table_name'=>'string', 'values'=>'array', 'flags='=>'int'],
    'pg_last_error' => ['string', 'connection='=>'resource'],
    'pg_last_notice' => ['string|array|bool', 'connection'=>'resource', 'mode='=>'int'],
    'pg_last_oid' => ['string|int|false', 'result'=>'resource'],
    'pg_lo_close' => ['bool', 'lob'=>'resource'],
    'pg_lo_create' => ['int|string|false', 'connection='=>'resource', 'oid='=>'int|string'],
    'pg_lo_export' => ['bool', 'connection'=>'resource', 'oid'=>'int|string', 'filename'=>'string'],
    'pg_lo_export\'1' => ['bool', 'connection'=>'int|string', 'oid'=>'string'],
    'pg_lo_import' => ['int|string|false', 'connection'=>'resource', 'filename'=>'string', 'oid'=>'string|int'],
    'pg_lo_import\'1' => ['int|string|false', 'connection'=>'string', 'filename'=>'string|int'],
    'pg_lo_open' => ['resource|false', 'connection'=>'resource', 'oid'=>'int|string', 'mode'=>'string'],
    'pg_lo_open\'1' => ['resource|false', 'connection'=>'int|string', 'oid'=>'string'],
    'pg_lo_read' => ['string|false', 'lob'=>'resource', 'length='=>'int'],
    'pg_lo_read_all' => ['int', 'lob'=>'resource'],
    'pg_lo_seek' => ['bool', 'lob'=>'resource', 'offset'=>'int', 'whence='=>'int'],
    'pg_lo_tell' => ['int', 'lob'=>'resource'],
    'pg_lo_truncate' => ['bool', 'lob'=>'resource', 'size'=>'int'],
    'pg_lo_unlink' => ['bool', 'connection'=>'resource', 'oid'=>'int|string'],
    'pg_lo_unlink\'1' => ['bool', 'connection'=>'int|string'],
    'pg_lo_write' => ['int|false', 'lob'=>'resource', 'data'=>'string', 'length='=>'int'],
    'pg_meta_data' => ['array|false', 'connection'=>'resource', 'table_name'=>'string', 'extended='=>'bool'],
    'pg_num_fields' => ['int', 'result'=>'resource'],
    'pg_num_rows' => ['int', 'result'=>'resource'],
    'pg_options' => ['string', 'connection='=>'resource'],
    'pg_parameter_status' => ['string|false', 'connection'=>'resource', 'name'=>'string'],
    'pg_parameter_status\'1' => ['string|false', 'connection'=>'string'],
    'pg_pconnect' => ['resource|false', 'connection_string'=>'string', 'flags='=>'string', 'port='=>'string|int', 'options='=>'string', 'tty='=>'string', 'database='=>'string'],
    'pg_ping' => ['bool', 'connection='=>'resource'],
    'pg_port' => ['string', 'connection='=>'resource'],
    'pg_prepare' => ['resource|false', 'connection'=>'resource', 'statement_name'=>'string', 'query'=>'string'],
    'pg_prepare\'1' => ['resource|false', 'connection'=>'string', 'statement_name'=>'string'],
    'pg_put_line' => ['bool', 'connection'=>'resource', 'data'=>'string'],
    'pg_put_line\'1' => ['bool', 'connection'=>'string'],
    'pg_query' => ['resource|false', 'connection'=>'resource', 'query'=>'string'],
    'pg_query\'1' => ['resource|false', 'connection'=>'string'],
    'pg_query_params' => ['resource|false', 'connection'=>'resource', 'query'=>'string', 'params'=>'array'],
    'pg_query_params\'1' => ['resource|false', 'connection'=>'string', 'query'=>'array'],
    'pg_result_error' => ['string|false', 'result'=>'resource'],
    'pg_result_error_field' => ['string|false|null', 'result'=>'resource', 'field_code'=>'int'],
    'pg_result_seek' => ['bool', 'result'=>'resource', 'row'=>'int'],
    'pg_result_status' => ['string|int', 'result'=>'resource', 'mode='=>'int'],
    'pg_select' => ['string|array|false', 'connection'=>'resource', 'table_name'=>'string', 'assoc_array'=>'array', 'options='=>'int'],
    'pg_send_execute' => ['bool|int', 'connection'=>'resource', 'query'=>'string', 'params'=>'array'],
    'pg_send_prepare' => ['bool|int', 'connection'=>'resource', 'statement_name'=>'string', 'query'=>'string'],
    'pg_send_query' => ['bool|int', 'connection'=>'resource', 'query'=>'string'],
    'pg_send_query_params' => ['bool|int', 'connection'=>'resource', 'query'=>'string', 'params'=>'array'],
    'pg_set_client_encoding' => ['int', 'connection'=>'resource', 'encoding'=>'string'],
    'pg_set_client_encoding\'1' => ['int', 'connection'=>'string'],
    'pg_set_error_verbosity' => ['int|false', 'connection'=>'resource', 'verbosity'=>'int'],
    'pg_set_error_verbosity\'1' => ['int|false', 'connection'=>'int'],
    'pg_socket' => ['resource|false', 'connection'=>'resource'],
    'pg_trace' => ['bool', 'filename'=>'string', 'mode='=>'string', 'connection='=>'resource'],
    'pg_transaction_status' => ['int', 'connection'=>'resource'],
    'pg_tty' => ['string', 'connection='=>'resource'],
    'pg_unescape_bytea' => ['string', 'string'=>'string'],
    'pg_untrace' => ['bool', 'connection='=>'resource'],
    'pg_update' => ['string|bool', 'connection'=>'resource', 'table_name'=>'string', 'values'=>'array', 'conditions'=>'array', 'flags='=>'int'],
    'pg_version' => ['array', 'connection='=>'resource'],
    'phardata::setMetadata' => ['void', 'metadata'=>'mixed'],
    'phardata::setSignatureAlgorithm' => ['void', 'sigtype'=>'int'],
    'phdfs::__construct' => ['void', 'ip'=>'string', 'port'=>'string'],
    'phdfs::__destruct' => ['void'],
    'phdfs::connect' => ['bool'],
    'phdfs::copy' => ['bool', 'source_file'=>'string', 'destination_file'=>'string'],
    'phdfs::create_directory' => ['bool', 'path'=>'string'],
    'phdfs::delete' => ['bool', 'path'=>'string'],
    'phdfs::disconnect' => ['bool'],
    'phdfs::exists' => ['bool', 'path'=>'string'],
    'phdfs::file_info' => ['array', 'path'=>'string'],
    'phdfs::list_directory' => ['array', 'path'=>'string'],
    'phdfs::read' => ['string', 'path'=>'string', 'length='=>'string'],
    'phdfs::rename' => ['bool', 'old_path'=>'string', 'new_path'=>'string'],
    'phdfs::tell' => ['int', 'path'=>'string'],
    'phdfs::write' => ['bool', 'path'=>'string', 'buffer'=>'string', 'mode='=>'string'],
    'php_check_syntax' => ['bool', 'filename'=>'string', 'error_message='=>'string'],
    'php_ini_loaded_file' => ['string|false'],
    'php_ini_scanned_files' => ['string|false'],
    'php_logo_guid' => ['string'],
    'php_sapi_name' => ['string'],
    'php_strip_whitespace' => ['string', 'filename'=>'string'],
    'php_uname' => ['string', 'mode='=>'string'],
    'php_user_filter::filter' => ['int', 'in'=>'resource', 'out'=>'resource', '&rw_consumed'=>'int', 'closing'=>'bool'],
    'php_user_filter::onClose' => ['void'],
    'php_user_filter::onCreate' => ['bool'],
    'phpcredits' => ['bool', 'flags='=>'int'],
    'phpdbg_break_file' => ['void', 'file'=>'string', 'line'=>'int'],
    'phpdbg_break_function' => ['void', 'function'=>'string'],
    'phpdbg_break_method' => ['void', 'class'=>'string', 'method'=>'string'],
    'phpdbg_break_next' => ['void'],
    'phpdbg_clear' => ['void'],
    'phpdbg_color' => ['void', 'element'=>'int', 'color'=>'string'],
    'phpdbg_end_oplog' => ['array', 'options='=>'array'],
    'phpdbg_exec' => ['mixed', 'context='=>'string'],
    'phpdbg_get_executable' => ['array', 'options='=>'array'],
    'phpdbg_prompt' => ['void', 'string'=>'string'],
    'phpdbg_start_oplog' => ['void'],
    'phpinfo' => ['bool', 'flags='=>'int'],
    'phpversion' => ['string|false', 'extension='=>'string'],
    'pht\AtomicInteger::__construct' => ['void', 'value='=>'int'],
    'pht\AtomicInteger::dec' => ['void'],
    'pht\AtomicInteger::get' => ['int'],
    'pht\AtomicInteger::inc' => ['void'],
    'pht\AtomicInteger::lock' => ['void'],
    'pht\AtomicInteger::set' => ['void', 'value'=>'int'],
    'pht\AtomicInteger::unlock' => ['void'],
    'pht\HashTable::lock' => ['void'],
    'pht\HashTable::size' => ['int'],
    'pht\HashTable::unlock' => ['void'],
    'pht\Queue::front' => ['mixed'],
    'pht\Queue::lock' => ['void'],
    'pht\Queue::pop' => ['mixed'],
    'pht\Queue::push' => ['void', 'value'=>'mixed'],
    'pht\Queue::size' => ['int'],
    'pht\Queue::unlock' => ['void'],
    'pht\Runnable::run' => ['void'],
    'pht\Vector::__construct' => ['void', 'size='=>'int', 'value='=>'mixed'],
    'pht\Vector::deleteAt' => ['void', 'offset'=>'int'],
    'pht\Vector::insertAt' => ['void', 'value'=>'mixed', 'offset'=>'int'],
    'pht\Vector::lock' => ['void'],
    'pht\Vector::pop' => ['mixed'],
    'pht\Vector::push' => ['void', 'value'=>'mixed'],
    'pht\Vector::resize' => ['void', 'size'=>'int', 'value='=>'mixed'],
    'pht\Vector::shift' => ['mixed'],
    'pht\Vector::size' => ['int'],
    'pht\Vector::unlock' => ['void'],
    'pht\Vector::unshift' => ['void', 'value'=>'mixed'],
    'pht\Vector::updateAt' => ['void', 'value'=>'mixed', 'offset'=>'int'],
    'pht\thread::addClassTask' => ['void', 'className'=>'string', '...ctorArgs='=>'mixed'],
    'pht\thread::addFileTask' => ['void', 'fileName'=>'string', '...globals='=>'mixed'],
    'pht\thread::addFunctionTask' => ['void', 'func'=>'callable', '...funcArgs='=>'mixed'],
    'pht\thread::join' => ['void'],
    'pht\thread::start' => ['void'],
    'pht\thread::taskCount' => ['int'],
    'pht\threaded::lock' => ['void'],
    'pht\threaded::unlock' => ['void'],
    'pi' => ['float'],
    'png2wbmp' => ['bool', 'pngname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'],
    'pointObj::__construct' => ['void'],
    'pointObj::distanceToLine' => ['float', 'p1'=>'pointObj', 'p2'=>'pointObj'],
    'pointObj::distanceToPoint' => ['float', 'poPoint'=>'pointObj'],
    'pointObj::distanceToShape' => ['float', 'shape'=>'shapeObj'],
    'pointObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'],
    'pointObj::ms_newPointObj' => ['pointObj'],
    'pointObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
    'pointObj::setXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'],
    'pointObj::setXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'],
    'popen' => ['resource|false', 'command'=>'string', 'mode'=>'string'],
    'pos' => ['mixed', 'array'=>'array'],
    'posix_access' => ['bool', 'filename'=>'string', 'flags='=>'int'],
    'posix_ctermid' => ['string|false'],
    'posix_errno' => ['int'],
    'posix_get_last_error' => ['int'],
    'posix_getcwd' => ['string|false'],
    'posix_getegid' => ['int'],
    'posix_geteuid' => ['int'],
    'posix_getgid' => ['int'],
    'posix_getgrgid' => ['array{name: string, passwd: string, gid: int, members: list<string>}|false', 'group_id'=>'int'],
    'posix_getgrnam' => ['array{name: string, passwd: string, gid: int, members: list<string>}|false', 'name'=>'string'],
    'posix_getgroups' => ['list<int>|false'],
    'posix_getlogin' => ['string|false'],
    'posix_getpgid' => ['int|false', 'process_id'=>'int'],
    'posix_getpgrp' => ['int'],
    'posix_getpid' => ['int'],
    'posix_getppid' => ['int'],
    'posix_getpwnam' => ['array{name: string, passwd: string, uid: int, gid: int, gecos: string, dir: string, shell: string}|false', 'username'=>'string'],
    'posix_getpwuid' => ['array{name: string, passwd: string, uid: int, gid: int, gecos: string, dir: string, shell: string}|false', 'user_id'=>'int'],
    'posix_getrlimit' => ['array{"soft core": string, "hard core": string, "soft data": string, "hard data": string, "soft stack": integer, "hard stack": string, "soft totalmem": string, "hard totalmem": string, "soft rss": string, "hard rss": string, "soft maxproc": integer, "hard maxproc": integer, "soft memlock": integer, "hard memlock": integer, "soft cpu": string, "hard cpu": string, "soft filesize": string, "hard filesize": string, "soft openfiles": integer, "hard openfiles": integer}|false'],
    'posix_getsid' => ['int|false', 'process_id'=>'int'],
    'posix_getuid' => ['int'],
    'posix_initgroups' => ['bool', 'username'=>'string', 'group_id'=>'int'],
    'posix_isatty' => ['bool', 'file_descriptor'=>'resource|int'],
    'posix_kill' => ['bool', 'process_id'=>'int', 'signal'=>'int'],
    'posix_mkfifo' => ['bool', 'filename'=>'string', 'permissions'=>'int'],
    'posix_mknod' => ['bool', 'filename'=>'string', 'flags'=>'int', 'major='=>'int', 'minor='=>'int'],
    'posix_setegid' => ['bool', 'group_id'=>'int'],
    'posix_seteuid' => ['bool', 'user_id'=>'int'],
    'posix_setgid' => ['bool', 'group_id'=>'int'],
    'posix_setpgid' => ['bool', 'process_id'=>'int', 'process_group_id'=>'int'],
    'posix_setrlimit' => ['bool', 'resource'=>'int', 'soft_limit'=>'int', 'hard_limit'=>'int'],
    'posix_setsid' => ['int'],
    'posix_setuid' => ['bool', 'user_id'=>'int'],
    'posix_strerror' => ['string', 'error_code'=>'int'],
    'posix_times' => ['array{ticks: int, utime: int, stime: int, cutime: int, cstime: int}|false'],
    'posix_ttyname' => ['string|false', 'file_descriptor'=>'resource|int'],
    'posix_uname' => ['array{sysname: string, nodename: string, release: string, version: string, machine: string, domainname: string}|false'],
    'pow' => ['float|int', 'num'=>'int|float', 'exponent'=>'int|float'],
    'preg_filter' => ['null|string|string[]', 'pattern'=>'mixed', 'replacement'=>'mixed', 'subject'=>'mixed', 'limit='=>'int', '&w_count='=>'int'],
    'preg_grep' => ['array|false', 'pattern'=>'string', 'array'=>'array', 'flags='=>'int'],
    'preg_last_error' => ['int'],
    'preg_match' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_matches='=>'string[]', 'flags='=>'0', 'offset='=>'int'],
    'preg_match\'1' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_matches='=>'array', 'flags='=>'int', 'offset='=>'int'],
    'preg_match_all' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_matches='=>'array', 'flags='=>'int', 'offset='=>'int'],
    'preg_quote' => ['string', 'str'=>'string', 'delimiter='=>'string'],
    'preg_replace' => ['string|string[]|null', 'pattern'=>'string|array', 'replacement'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
    'preg_replace_callback' => ['string|null', 'pattern'=>'string|array', 'callback'=>'callable(string[]):string', 'subject'=>'string', 'limit='=>'int', '&w_count='=>'int'],
    'preg_replace_callback\'1' => ['string[]|null', 'pattern'=>'string|array', 'callback'=>'callable(string[]):string', 'subject'=>'string[]', 'limit='=>'int', '&w_count='=>'int'],
    'preg_replace_callback_array' => ['string|string[]|null', 'pattern'=>'array<string,callable(array):string>', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
    'preg_split' => ['list<string>|false', 'pattern'=>'string', 'subject'=>'string', 'limit'=>'int', 'flags='=>'null'],
    'preg_split\'1' => ['list<string>|list<list<string|int>>|false', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'int', 'flags='=>'int'],
    'prev' => ['mixed', '&r_array'=>'array|object'],
    'print' => ['int', 'arg'=>'string'],
    'print_r' => ['string', 'value'=>'mixed'],
    'print_r\'1' => ['true', 'value'=>'mixed', 'return='=>'bool'],
    'printf' => ['int', 'format'=>'string', '...values='=>'string|int|float'],
    'proc_close' => ['int', 'process'=>'resource'],
    'proc_get_status' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}|false', 'process'=>'resource'],
    'proc_nice' => ['bool', 'priority'=>'int'],
    'proc_open' => ['resource|false', 'command'=>'string', 'descriptor_spec'=>'array', '&pipes'=>'resource[]', 'cwd='=>'?string', 'env_vars='=>'?array', 'options='=>'?array'],
    'proc_terminate' => ['bool', 'process'=>'resource', 'signal='=>'int'],
    'projectionObj::__construct' => ['void', 'projectionString'=>'string'],
    'projectionObj::getUnits' => ['int'],
    'projectionObj::ms_newProjectionObj' => ['projectionObj', 'projectionString'=>'string'],
    'property_exists' => ['bool', 'object_or_class'=>'object|string', 'property'=>'string'],
    'ps_add_bookmark' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'parent='=>'int', 'open='=>'int'],
    'ps_add_launchlink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'],
    'ps_add_locallink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'page'=>'int', 'dest'=>'string'],
    'ps_add_note' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'],
    'ps_add_pdflink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'],
    'ps_add_weblink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'url'=>'string'],
    'ps_arc' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'],
    'ps_arcn' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'],
    'ps_begin_page' => ['bool', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
    'ps_begin_pattern' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'],
    'ps_begin_template' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
    'ps_circle' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float'],
    'ps_clip' => ['bool', 'psdoc'=>'resource'],
    'ps_close' => ['bool', 'psdoc'=>'resource'],
    'ps_close_image' => ['void', 'psdoc'=>'resource', 'imageid'=>'int'],
    'ps_closepath' => ['bool', 'psdoc'=>'resource'],
    'ps_closepath_stroke' => ['bool', 'psdoc'=>'resource'],
    'ps_continue_text' => ['bool', 'psdoc'=>'resource', 'text'=>'string'],
    'ps_curveto' => ['bool', 'psdoc'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
    'ps_delete' => ['bool', 'psdoc'=>'resource'],
    'ps_end_page' => ['bool', 'psdoc'=>'resource'],
    'ps_end_pattern' => ['bool', 'psdoc'=>'resource'],
    'ps_end_template' => ['bool', 'psdoc'=>'resource'],
    'ps_fill' => ['bool', 'psdoc'=>'resource'],
    'ps_fill_stroke' => ['bool', 'psdoc'=>'resource'],
    'ps_findfont' => ['int', 'psdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed='=>'bool'],
    'ps_get_buffer' => ['string', 'psdoc'=>'resource'],
    'ps_get_parameter' => ['string', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'],
    'ps_get_value' => ['float', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'],
    'ps_hyphenate' => ['array', 'psdoc'=>'resource', 'text'=>'string'],
    'ps_include_file' => ['bool', 'psdoc'=>'resource', 'file'=>'string'],
    'ps_lineto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
    'ps_makespotcolor' => ['int', 'psdoc'=>'resource', 'name'=>'string', 'reserved='=>'int'],
    'ps_moveto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
    'ps_new' => ['resource'],
    'ps_open_file' => ['bool', 'psdoc'=>'resource', 'filename='=>'string'],
    'ps_open_image' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'],
    'ps_open_image_file' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'filename'=>'string', 'stringparam='=>'string', 'intparam='=>'int'],
    'ps_open_memory_image' => ['int', 'psdoc'=>'resource', 'gd'=>'int'],
    'ps_place_image' => ['bool', 'psdoc'=>'resource', 'imageid'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'],
    'ps_rect' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
    'ps_restore' => ['bool', 'psdoc'=>'resource'],
    'ps_rotate' => ['bool', 'psdoc'=>'resource', 'rot'=>'float'],
    'ps_save' => ['bool', 'psdoc'=>'resource'],
    'ps_scale' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
    'ps_set_border_color' => ['bool', 'psdoc'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
    'ps_set_border_dash' => ['bool', 'psdoc'=>'resource', 'black'=>'float', 'white'=>'float'],
    'ps_set_border_style' => ['bool', 'psdoc'=>'resource', 'style'=>'string', 'width'=>'float'],
    'ps_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'],
    'ps_set_parameter' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'string'],
    'ps_set_text_pos' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
    'ps_set_value' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'float'],
    'ps_setcolor' => ['bool', 'psdoc'=>'resource', 'type'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'],
    'ps_setdash' => ['bool', 'psdoc'=>'resource', 'on'=>'float', 'off'=>'float'],
    'ps_setflat' => ['bool', 'psdoc'=>'resource', 'value'=>'float'],
    'ps_setfont' => ['bool', 'psdoc'=>'resource', 'fontid'=>'int', 'size'=>'float'],
    'ps_setgray' => ['bool', 'psdoc'=>'resource', 'gray'=>'float'],
    'ps_setlinecap' => ['bool', 'psdoc'=>'resource', 'type'=>'int'],
    'ps_setlinejoin' => ['bool', 'psdoc'=>'resource', 'type'=>'int'],
    'ps_setlinewidth' => ['bool', 'psdoc'=>'resource', 'width'=>'float'],
    'ps_setmiterlimit' => ['bool', 'psdoc'=>'resource', 'value'=>'float'],
    'ps_setoverprintmode' => ['bool', 'psdoc'=>'resource', 'mode'=>'int'],
    'ps_setpolydash' => ['bool', 'psdoc'=>'resource', 'arr'=>'float'],
    'ps_shading' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'],
    'ps_shading_pattern' => ['int', 'psdoc'=>'resource', 'shadingid'=>'int', 'optlist'=>'string'],
    'ps_shfill' => ['bool', 'psdoc'=>'resource', 'shadingid'=>'int'],
    'ps_show' => ['bool', 'psdoc'=>'resource', 'text'=>'string'],
    'ps_show2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'length'=>'int'],
    'ps_show_boxed' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'left'=>'float', 'bottom'=>'float', 'width'=>'float', 'height'=>'float', 'hmode'=>'string', 'feature='=>'string'],
    'ps_show_xy' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'],
    'ps_show_xy2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'length'=>'int', 'xcoor'=>'float', 'ycoor'=>'float'],
    'ps_string_geometry' => ['array', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'],
    'ps_stringwidth' => ['float', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'],
    'ps_stroke' => ['bool', 'psdoc'=>'resource'],
    'ps_symbol' => ['bool', 'psdoc'=>'resource', 'ord'=>'int'],
    'ps_symbol_name' => ['string', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int'],
    'ps_symbol_width' => ['float', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int', 'size='=>'float'],
    'ps_translate' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
    'pspell_add_to_personal' => ['bool', 'dictionary'=>'int', 'word'=>'string'],
    'pspell_add_to_session' => ['bool', 'dictionary'=>'int', 'word'=>'string'],
    'pspell_check' => ['bool', 'dictionary'=>'int', 'word'=>'string'],
    'pspell_clear_session' => ['bool', 'dictionary'=>'int'],
    'pspell_config_create' => ['int', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string'],
    'pspell_config_data_dir' => ['bool', 'config'=>'int', 'directory'=>'string'],
    'pspell_config_dict_dir' => ['bool', 'config'=>'int', 'directory'=>'string'],
    'pspell_config_ignore' => ['bool', 'config'=>'int', 'min_length'=>'int'],
    'pspell_config_mode' => ['bool', 'config'=>'int', 'mode'=>'int'],
    'pspell_config_personal' => ['bool', 'config'=>'int', 'filename'=>'string'],
    'pspell_config_repl' => ['bool', 'config'=>'int', 'filename'=>'string'],
    'pspell_config_runtogether' => ['bool', 'config'=>'int', 'allow'=>'bool'],
    'pspell_config_save_repl' => ['bool', 'config'=>'int', 'save'=>'bool'],
    'pspell_new' => ['int|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
    'pspell_new_config' => ['int|false', 'config'=>'int'],
    'pspell_new_personal' => ['int|false', 'filename'=>'string', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
    'pspell_save_wordlist' => ['bool', 'dictionary'=>'int'],
    'pspell_store_replacement' => ['bool', 'dictionary'=>'int', 'misspelled'=>'string', 'correct'=>'string'],
    'pspell_suggest' => ['array', 'dictionary'=>'int', 'word'=>'string'],
    'putenv' => ['bool', 'assignment'=>'string'],
    'px_close' => ['bool', 'pxdoc'=>'resource'],
    'px_create_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource', 'fielddesc'=>'array'],
    'px_date2string' => ['string', 'pxdoc'=>'resource', 'value'=>'int', 'format'=>'string'],
    'px_delete' => ['bool', 'pxdoc'=>'resource'],
    'px_delete_record' => ['bool', 'pxdoc'=>'resource', 'num'=>'int'],
    'px_get_field' => ['array', 'pxdoc'=>'resource', 'fieldno'=>'int'],
    'px_get_info' => ['array', 'pxdoc'=>'resource'],
    'px_get_parameter' => ['string', 'pxdoc'=>'resource', 'name'=>'string'],
    'px_get_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'],
    'px_get_schema' => ['array', 'pxdoc'=>'resource', 'mode='=>'int'],
    'px_get_value' => ['float', 'pxdoc'=>'resource', 'name'=>'string'],
    'px_insert_record' => ['int', 'pxdoc'=>'resource', 'data'=>'array'],
    'px_new' => ['resource'],
    'px_numfields' => ['int', 'pxdoc'=>'resource'],
    'px_numrecords' => ['int', 'pxdoc'=>'resource'],
    'px_open_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource'],
    'px_put_record' => ['bool', 'pxdoc'=>'resource', 'record'=>'array', 'recpos='=>'int'],
    'px_retrieve_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'],
    'px_set_blob_file' => ['bool', 'pxdoc'=>'resource', 'filename'=>'string'],
    'px_set_parameter' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'string'],
    'px_set_tablename' => ['void', 'pxdoc'=>'resource', 'name'=>'string'],
    'px_set_targetencoding' => ['bool', 'pxdoc'=>'resource', 'encoding'=>'string'],
    'px_set_value' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'float'],
    'px_timestamp2string' => ['string', 'pxdoc'=>'resource', 'value'=>'float', 'format'=>'string'],
    'px_update_record' => ['bool', 'pxdoc'=>'resource', 'data'=>'array', 'num'=>'int'],
    'qdom_error' => ['string'],
    'qdom_tree' => ['QDomDocument', 'doc'=>'string'],
    'querymapObj::convertToString' => ['string'],
    'querymapObj::free' => ['void'],
    'querymapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'querymapObj::updateFromString' => ['int', 'snippet'=>'string'],
    'quoted_printable_decode' => ['string', 'string'=>'string'],
    'quoted_printable_encode' => ['string', 'string'=>'string'],
    'quotemeta' => ['string', 'string'=>'string'],
    'rad2deg' => ['float', 'num'=>'float'],
    'radius_acct_open' => ['resource|false'],
    'radius_add_server' => ['bool', 'radius_handle'=>'resource', 'hostname'=>'string', 'port'=>'int', 'secret'=>'string', 'timeout'=>'int', 'max_tries'=>'int'],
    'radius_auth_open' => ['resource|false'],
    'radius_close' => ['bool', 'radius_handle'=>'resource'],
    'radius_config' => ['bool', 'radius_handle'=>'resource', 'file'=>'string'],
    'radius_create_request' => ['bool', 'radius_handle'=>'resource', 'type'=>'int'],
    'radius_cvt_addr' => ['string', 'data'=>'string'],
    'radius_cvt_int' => ['int', 'data'=>'string'],
    'radius_cvt_string' => ['string', 'data'=>'string'],
    'radius_demangle' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'],
    'radius_demangle_mppe_key' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'],
    'radius_get_attr' => ['mixed', 'radius_handle'=>'resource'],
    'radius_get_tagged_attr_data' => ['string', 'data'=>'string'],
    'radius_get_tagged_attr_tag' => ['int', 'data'=>'string'],
    'radius_get_vendor_attr' => ['array', 'data'=>'string'],
    'radius_put_addr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'addr'=>'string'],
    'radius_put_attr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'],
    'radius_put_int' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'int'],
    'radius_put_string' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'],
    'radius_put_vendor_addr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'addr'=>'string'],
    'radius_put_vendor_attr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'],
    'radius_put_vendor_int' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'int'],
    'radius_put_vendor_string' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'],
    'radius_request_authenticator' => ['string', 'radius_handle'=>'resource'],
    'radius_salt_encrypt_attr' => ['string', 'radius_handle'=>'resource', 'data'=>'string'],
    'radius_send_request' => ['int|false', 'radius_handle'=>'resource'],
    'radius_server_secret' => ['string', 'radius_handle'=>'resource'],
    'radius_strerror' => ['string', 'radius_handle'=>'resource'],
    'rand' => ['int', 'min'=>'int', 'max'=>'int'],
    'rand\'1' => ['int'],
    'random_bytes' => ['non-empty-string', 'length'=>'positive-int'],
    'random_int' => ['int', 'min'=>'int', 'max'=>'int'],
    'range' => ['array', 'start'=>'mixed', 'end'=>'mixed', 'step='=>'int|float'],
    'rar_allow_broken_set' => ['bool', 'rarfile'=>'RarArchive', 'allow_broken'=>'bool'],
    'rar_broken_is' => ['bool', 'rarfile'=>'rararchive'],
    'rar_close' => ['bool', 'rarfile'=>'rararchive'],
    'rar_comment_get' => ['string', 'rarfile'=>'rararchive'],
    'rar_entry_get' => ['RarEntry', 'rarfile'=>'RarArchive', 'entryname'=>'string'],
    'rar_list' => ['RarArchive', 'rarfile'=>'rararchive'],
    'rar_open' => ['RarArchive', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'],
    'rar_solid_is' => ['bool', 'rarfile'=>'rararchive'],
    'rar_wrapper_cache_stats' => ['string'],
    'rawurldecode' => ['string', 'string'=>'string'],
    'rawurlencode' => ['string', 'string'=>'string'],
    'rd_kafka_err2str' => ['string', 'err'=>'int'],
    'rd_kafka_errno' => ['int'],
    'rd_kafka_errno2err' => ['int', 'errnox'=>'int'],
    'rd_kafka_offset_tail' => ['int', 'cnt'=>'int'],
    'read_exif_data' => ['array', 'filename'=>'string', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'],
    'readdir' => ['string|false', 'dir_handle='=>'resource'],
    'readfile' => ['int|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
    'readgzfile' => ['int|false', 'filename'=>'string', 'use_include_path='=>'int'],
    'readline' => ['string|false', 'prompt='=>'?string'],
    'readline_add_history' => ['bool', 'prompt'=>'string'],
    'readline_callback_handler_install' => ['bool', 'prompt'=>'string', 'callback'=>'callable'],
    'readline_callback_handler_remove' => ['bool'],
    'readline_callback_read_char' => ['void'],
    'readline_clear_history' => ['bool'],
    'readline_completion_function' => ['bool', 'callback'=>'callable'],
    'readline_info' => ['mixed', 'var_name='=>'string', 'value='=>'string|int|bool'],
    'readline_list_history' => ['array'],
    'readline_on_new_line' => ['void'],
    'readline_read_history' => ['bool', 'filename='=>'string'],
    'readline_redisplay' => ['void'],
    'readline_write_history' => ['bool', 'filename='=>'string'],
    'readlink' => ['string|false', 'path'=>'string'],
    'realpath' => ['string|false', 'path'=>'string'],
    'realpath_cache_get' => ['array'],
    'realpath_cache_size' => ['int'],
    'recode' => ['string', 'request'=>'string', 'string'=>'string'],
    'recode_file' => ['bool', 'request'=>'string', 'input'=>'resource', 'output'=>'resource'],
    'recode_string' => ['string|false', 'request'=>'string', 'string'=>'string'],
    'rectObj::__construct' => ['void'],
    'rectObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'],
    'rectObj::fit' => ['float', 'width'=>'int', 'height'=>'int'],
    'rectObj::ms_newRectObj' => ['rectObj'],
    'rectObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
    'rectObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'rectObj::setextent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'],
    'register_event_handler' => ['bool', 'event_handler_func'=>'string', 'handler_register_name'=>'string', 'event_type_mask'=>'int'],
    'register_shutdown_function' => ['void', 'callback'=>'callable', '...args='=>'mixed'],
    'register_tick_function' => ['bool', 'callback'=>'callable():void', '...args='=>'mixed'],
    'rename' => ['bool', 'from'=>'string', 'to'=>'string', 'context='=>'resource'],
    'rename_function' => ['bool', 'original_name'=>'string', 'new_name'=>'string'],
    'reset' => ['mixed|false', '&r_array'=>'array|object'],
    'resourcebundle_count' => ['int', 'bundle'=>'ResourceBundle'],
    'resourcebundle_create' => ['?ResourceBundle', 'locale'=>'?string', 'bundle'=>'?string', 'fallback='=>'bool'],
    'resourcebundle_get' => ['mixed|null', 'bundle'=>'ResourceBundle', 'index'=>'string|int', 'fallback='=>'bool'],
    'resourcebundle_get_error_code' => ['int', 'bundle'=>'ResourceBundle'],
    'resourcebundle_get_error_message' => ['string', 'bundle'=>'ResourceBundle'],
    'resourcebundle_locales' => ['array', 'bundle'=>'string'],
    'restore_error_handler' => ['true'],
    'restore_exception_handler' => ['true'],
    'restore_include_path' => ['void'],
    'rewind' => ['bool', 'stream'=>'resource'],
    'rewinddir' => ['void', 'dir_handle='=>'resource'],
    'rmdir' => ['bool', 'directory'=>'string', 'context='=>'resource'],
    'round' => ['float', 'num'=>'float', 'precision='=>'int', 'mode='=>'0|positive-int'],
    'rpm_close' => ['bool', 'rpmr'=>'resource'],
    'rpm_get_tag' => ['mixed', 'rpmr'=>'resource', 'tagnum'=>'int'],
    'rpm_is_valid' => ['bool', 'filename'=>'string'],
    'rpm_open' => ['resource|false', 'filename'=>'string'],
    'rpm_version' => ['string'],
    'rpmaddtag' => ['bool', 'tag'=>'int'],
    'rpmdbinfo' => ['array', 'nevr'=>'string', 'full='=>'bool'],
    'rpmdbsearch' => ['array', 'pattern'=>'string', 'rpmtag='=>'int', 'rpmmire='=>'int', 'full='=>'bool'],
    'rpminfo' => ['array', 'path'=>'string', 'full='=>'bool', 'error='=>'string'],
    'rpmvercmp' => ['int', 'evr1'=>'string', 'evr2'=>'string'],
    'rrd_create' => ['bool', 'filename'=>'string', 'options'=>'array'],
    'rrd_disconnect' => ['void'],
    'rrd_error' => ['string'],
    'rrd_fetch' => ['array', 'filename'=>'string', 'options'=>'array'],
    'rrd_first' => ['int|false', 'file'=>'string', 'raaindex='=>'int'],
    'rrd_graph' => ['array|false', 'filename'=>'string', 'options'=>'array'],
    'rrd_info' => ['array|false', 'filename'=>'string'],
    'rrd_last' => ['int', 'filename'=>'string'],
    'rrd_lastupdate' => ['array|false', 'filename'=>'string'],
    'rrd_restore' => ['bool', 'xml_file'=>'string', 'rrd_file'=>'string', 'options='=>'array'],
    'rrd_tune' => ['bool', 'filename'=>'string', 'options'=>'array'],
    'rrd_update' => ['bool', 'filename'=>'string', 'options'=>'array'],
    'rrd_version' => ['string'],
    'rrd_xport' => ['array|false', 'options'=>'array'],
    'rrdc_disconnect' => ['void'],
    'rsort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
    'rtrim' => ['string', 'string'=>'string', 'characters='=>'string'],
    'runkit7_constant_add' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'new_visibility='=>'int'],
    'runkit7_constant_redefine' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'new_visibility='=>'?int'],
    'runkit7_constant_remove' => ['bool', 'constant_name'=>'string'],
    'runkit7_function_add' => ['bool', 'function_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_doc_comment='=>'?string', 'return_by_reference='=>'?bool', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
    'runkit7_function_copy' => ['bool', 'source_name'=>'string', 'target_name'=>'string'],
    'runkit7_function_redefine' => ['bool', 'function_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_doc_comment='=>'?string', 'return_by_reference='=>'?bool', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
    'runkit7_function_remove' => ['bool', 'function_name'=>'string'],
    'runkit7_function_rename' => ['bool', 'source_name'=>'string', 'target_name'=>'string'],
    'runkit7_import' => ['bool', 'filename'=>'string', 'flags='=>'?int'],
    'runkit7_method_add' => ['bool', 'class_name'=>'string', 'method_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_flags='=>'int|null|string', 'flags_or_doc_comment='=>'int|null|string', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
    'runkit7_method_copy' => ['bool', 'destination_class'=>'string', 'destination_method'=>'string', 'source_class'=>'string', 'source_method='=>'?string'],
    'runkit7_method_redefine' => ['bool', 'class_name'=>'string', 'method_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_flags='=>'int|null|string', 'flags_or_doc_comment='=>'int|null|string', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
    'runkit7_method_remove' => ['bool', 'class_name'=>'string', 'method_name'=>'string'],
    'runkit7_method_rename' => ['bool', 'class_name'=>'string', 'source_method_name'=>'string', 'source_target_name'=>'string'],
    'runkit7_superglobals' => ['array'],
    'runkit7_zval_inspect' => ['array', 'value'=>'mixed'],
    'runkit_class_adopt' => ['bool', 'classname'=>'string', 'parentname'=>'string'],
    'runkit_class_emancipate' => ['bool', 'classname'=>'string'],
    'runkit_constant_add' => ['bool', 'constname'=>'string', 'value'=>'mixed'],
    'runkit_constant_redefine' => ['bool', 'constname'=>'string', 'newvalue'=>'mixed'],
    'runkit_constant_remove' => ['bool', 'constname'=>'string'],
    'runkit_function_add' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'],
    'runkit_function_add\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'],
    'runkit_function_copy' => ['bool', 'funcname'=>'string', 'targetname'=>'string'],
    'runkit_function_redefine' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'],
    'runkit_function_redefine\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'],
    'runkit_function_remove' => ['bool', 'funcname'=>'string'],
    'runkit_function_rename' => ['bool', 'funcname'=>'string', 'newname'=>'string'],
    'runkit_import' => ['bool', 'filename'=>'string', 'flags='=>'int'],
    'runkit_lint' => ['bool', 'code'=>'string'],
    'runkit_lint_file' => ['bool', 'filename'=>'string'],
    'runkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'],
    'runkit_method_add\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'],
    'runkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'],
    'runkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'],
    'runkit_method_redefine\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'],
    'runkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'],
    'runkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'],
    'runkit_return_value_used' => ['bool'],
    'runkit_sandbox_output_handler' => ['mixed', 'sandbox'=>'object', 'callback='=>'mixed'],
    'runkit_superglobals' => ['array'],
    'runkit_zval_inspect' => ['array', 'value'=>'mixed'],
    'scalebarObj::convertToString' => ['string'],
    'scalebarObj::free' => ['void'],
    'scalebarObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'scalebarObj::setImageColor' => ['int', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    'scalebarObj::updateFromString' => ['int', 'snippet'=>'string'],
    'scandir' => ['list<string>|false', 'directory'=>'string', 'sorting_order='=>'int', 'context='=>'resource'],
    'seaslog_get_author' => ['string'],
    'seaslog_get_version' => ['string'],
    'sem_acquire' => ['bool', 'semaphore'=>'resource', 'non_blocking='=>'bool'],
    'sem_get' => ['resource|false', 'key'=>'int', 'max_acquire='=>'int', 'permissions='=>'int', 'auto_release='=>'int'],
    'sem_release' => ['bool', 'semaphore'=>'resource'],
    'sem_remove' => ['bool', 'semaphore'=>'resource'],
    'serialize' => ['string', 'value'=>'mixed'],
    'session_abort' => ['bool'],
    'session_cache_expire' => ['int', 'value='=>'int'],
    'session_cache_limiter' => ['string', 'value='=>'string'],
    'session_commit' => ['bool'],
    'session_decode' => ['bool', 'data'=>'string'],
    'session_destroy' => ['bool'],
    'session_encode' => ['string'],
    'session_get_cookie_params' => ['array'],
    'session_id' => ['string|false', 'id='=>'string'],
    'session_is_registered' => ['bool', 'name'=>'string'],
    'session_module_name' => ['string', 'module='=>'string'],
    'session_name' => ['string|false', 'name='=>'string'],
    'session_pgsql_add_error' => ['bool', 'error_level'=>'int', 'error_message='=>'string'],
    'session_pgsql_get_error' => ['array', 'with_error_message='=>'bool'],
    'session_pgsql_get_field' => ['string'],
    'session_pgsql_reset' => ['bool'],
    'session_pgsql_set_field' => ['bool', 'value'=>'string'],
    'session_pgsql_status' => ['array'],
    'session_regenerate_id' => ['bool', 'delete_old_session='=>'bool'],
    'session_register' => ['bool', 'name'=>'mixed', '...args='=>'mixed'],
    'session_register_shutdown' => ['void'],
    'session_reset' => ['bool'],
    'session_save_path' => ['string', 'path='=>'string'],
    'session_set_cookie_params' => ['bool', 'lifetime'=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'],
    'session_set_save_handler' => ['bool', 'open'=>'callable(string,string):bool', 'close'=>'callable():bool', 'read'=>'callable(string):string', 'write'=>'callable(string,string):bool', 'destroy'=>'callable(string):bool', 'gc'=>'callable(string):bool', 'create_sid='=>'callable():string', 'validate_sid='=>'callable(string):bool', 'update_timestamp='=>'callable(string):bool'],
    'session_set_save_handler\'1' => ['bool', 'open'=>'SessionHandlerInterface', 'close='=>'bool'],
    'session_start' => ['bool', 'options='=>'array'],
    'session_status' => ['int'],
    'session_unregister' => ['bool', 'name'=>'string'],
    'session_unset' => ['bool'],
    'session_write_close' => ['bool'],
    'setLeftFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'setLine' => ['void', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
    'set_error_handler' => ['null|callable(int,string,string=,int=,array=):bool', 'callback'=>'null|callable(int,string,string=,int=,array=):bool', 'error_levels='=>'int'],
    'set_exception_handler' => ['null|callable(Throwable):void', 'callback'=>'null|callable(Throwable):void'],
    'set_file_buffer' => ['int', 'stream'=>'resource', 'size'=>'int'],
    'set_include_path' => ['string|false', 'include_path'=>'string'],
    'set_magic_quotes_runtime' => ['bool', 'new_setting'=>'bool'],
    'set_time_limit' => ['bool', 'seconds'=>'int'],
    'setcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool', 'samesite='=>'string', 'url_encode='=>'int'],
    'setlocale' => ['string|false', 'category'=>'int', 'locales'=>'string|0|null', '...rest='=>'string'],
    'setlocale\'1' => ['string|false', 'category'=>'int', 'locales'=>'?array'],
    'setproctitle' => ['void', 'title'=>'string'],
    'setrawcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'],
    'setthreadtitle' => ['bool', 'title'=>'string'],
    'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'],
    'sha1' => ['string', 'string'=>'string', 'binary='=>'bool'],
    'sha1_file' => ['string|false', 'filename'=>'string', 'binary='=>'bool'],
    'sha256' => ['string', 'string'=>'string', 'raw_output='=>'bool'],
    'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'],
    'shapeObj::__construct' => ['void', 'type'=>'int'],
    'shapeObj::add' => ['int', 'line'=>'lineObj'],
    'shapeObj::boundary' => ['shapeObj'],
    'shapeObj::contains' => ['bool', 'point'=>'pointObj'],
    'shapeObj::containsShape' => ['int', 'shape2'=>'shapeObj'],
    'shapeObj::convexhull' => ['shapeObj'],
    'shapeObj::crosses' => ['int', 'shape'=>'shapeObj'],
    'shapeObj::difference' => ['shapeObj', 'shape'=>'shapeObj'],
    'shapeObj::disjoint' => ['int', 'shape'=>'shapeObj'],
    'shapeObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj'],
    'shapeObj::equals' => ['int', 'shape'=>'shapeObj'],
    'shapeObj::free' => ['void'],
    'shapeObj::getArea' => ['float'],
    'shapeObj::getCentroid' => ['pointObj'],
    'shapeObj::getLabelPoint' => ['pointObj'],
    'shapeObj::getLength' => ['float'],
    'shapeObj::getPointUsingMeasure' => ['pointObj', 'm'=>'float'],
    'shapeObj::getValue' => ['string', 'layer'=>'layerObj', 'filedname'=>'string'],
    'shapeObj::intersection' => ['shapeObj', 'shape'=>'shapeObj'],
    'shapeObj::intersects' => ['bool', 'shape'=>'shapeObj'],
    'shapeObj::line' => ['lineObj', 'i'=>'int'],
    'shapeObj::ms_shapeObjFromWkt' => ['shapeObj', 'wkt'=>'string'],
    'shapeObj::overlaps' => ['int', 'shape'=>'shapeObj'],
    'shapeObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
    'shapeObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'shapeObj::setBounds' => ['int'],
    'shapeObj::simplify' => ['shapeObj|null', 'tolerance'=>'float'],
    'shapeObj::symdifference' => ['shapeObj', 'shape'=>'shapeObj'],
    'shapeObj::toWkt' => ['string'],
    'shapeObj::topologyPreservingSimplify' => ['shapeObj|null', 'tolerance'=>'float'],
    'shapeObj::touches' => ['int', 'shape'=>'shapeObj'],
    'shapeObj::union' => ['shapeObj', 'shape'=>'shapeObj'],
    'shapeObj::within' => ['int', 'shape2'=>'shapeObj'],
    'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'],
    'shapefileObj::addPoint' => ['int', 'point'=>'pointObj'],
    'shapefileObj::addShape' => ['int', 'shape'=>'shapeObj'],
    'shapefileObj::free' => ['void'],
    'shapefileObj::getExtent' => ['rectObj', 'i'=>'int'],
    'shapefileObj::getPoint' => ['shapeObj', 'i'=>'int'],
    'shapefileObj::getShape' => ['shapeObj', 'i'=>'int'],
    'shapefileObj::getTransformed' => ['shapeObj', 'map'=>'mapObj', 'i'=>'int'],
    'shapefileObj::ms_newShapefileObj' => ['shapefileObj', 'filename'=>'string', 'type'=>'int'],
    'shell_exec' => ['string|false|null', 'command'=>'string'],
    'shm_attach' => ['resource|false', 'key'=>'int', 'size='=>'int', 'permissions='=>'int'],
    'shm_detach' => ['bool', 'shm'=>'resource'],
    'shm_get_var' => ['mixed', 'shm'=>'resource', 'key'=>'int'],
    'shm_has_var' => ['bool', 'shm'=>'resource', 'key'=>'int'],
    'shm_put_var' => ['bool', 'shm'=>'resource', 'key'=>'int', 'value'=>'mixed'],
    'shm_remove' => ['bool', 'shm'=>'resource'],
    'shm_remove_var' => ['bool', 'shm'=>'resource', 'key'=>'int'],
    'shmop_close' => ['void', 'shmop'=>'resource'],
    'shmop_delete' => ['bool', 'shmop'=>'resource'],
    'shmop_open' => ['resource|false', 'key'=>'int', 'mode'=>'string', 'permissions'=>'int', 'size'=>'int'],
    'shmop_read' => ['string|false', 'shmop'=>'resource', 'offset'=>'int', 'size'=>'int'],
    'shmop_size' => ['int', 'shmop'=>'resource'],
    'shmop_write' => ['int|false', 'shmop'=>'resource', 'data'=>'string', 'offset'=>'int'],
    'show_source' => ['string|bool', 'filename'=>'string', 'return='=>'bool'],
    'shuffle' => ['bool', '&rw_array'=>'array'],
    'signeurlpaiement' => ['string', 'clent'=>'string', 'data'=>'string'],
    'similar_text' => ['int', 'string1'=>'string', 'string2'=>'string', '&w_percent='=>'float'],
    'simplexml_import_dom' => ['?SimpleXMLElement', 'node'=>'DOMNode', 'class_name='=>'?string'],
    'simplexml_load_file' => ['SimpleXMLElement|false', 'filename'=>'string', 'class_name='=>'?string', 'options='=>'int', 'namespace_or_prefix='=>'string', 'is_prefix='=>'bool'],
    'simplexml_load_string' => ['SimpleXMLElement|false', 'data'=>'string', 'class_name='=>'?string', 'options='=>'int', 'namespace_or_prefix='=>'string', 'is_prefix='=>'bool'],
    'sin' => ['float', 'num'=>'float'],
    'sinh' => ['float', 'num'=>'float'],
    'sizeof' => ['int', 'value'=>'Countable|array', 'mode='=>'int'],
    'sleep' => ['int|false', 'seconds'=>'0|positive-int'],
    'snmp2_get' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp2_getnext' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp2_real_walk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp2_set' => ['bool', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp2_walk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp3_get' => ['string|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp3_getnext' => ['string|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp3_real_walk' => ['array|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp3_set' => ['bool', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp3_walk' => ['array|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmp_get_quick_print' => ['bool'],
    'snmp_get_valueretrieval' => ['int'],
    'snmp_read_mib' => ['bool', 'filename'=>'string'],
    'snmp_set_enum_print' => ['bool', 'enable'=>'int'],
    'snmp_set_oid_numeric_print' => ['true', 'format'=>'int'],
    'snmp_set_oid_output_format' => ['true', 'format'=>'int'],
    'snmp_set_quick_print' => ['bool', 'enable'=>'bool'],
    'snmp_set_valueretrieval' => ['bool', 'method='=>'int'],
    'snmpget' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmpgetnext' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmprealwalk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmpset' => ['bool', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'mixed', 'timeout='=>'int', 'retries='=>'int'],
    'snmpwalk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'snmpwalkoid' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
    'socket_accept' => ['resource|false', 'socket'=>'resource'],
    'socket_bind' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'],
    'socket_clear_error' => ['void', 'socket='=>'resource'],
    'socket_close' => ['void', 'socket'=>'resource'],
    'socket_cmsg_space' => ['int', 'level'=>'int', 'type'=>'int'],
    'socket_connect' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'],
    'socket_create' => ['resource|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'],
    'socket_create_listen' => ['resource|false', 'port'=>'int', 'backlog='=>'int'],
    'socket_create_pair' => ['bool', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int', '&w_fd'=>'resource[]'],
    'socket_export_stream' => ['resource|false', 'socket'=>'resource'],
    'socket_get_option' => ['mixed|false', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'],
    'socket_get_status' => ['array', 'stream'=>'resource'],
    'socket_getopt' => ['mixed', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'],
    'socket_getpeername' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'],
    'socket_getsockname' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'],
    'socket_import_stream' => ['resource|false', 'stream'=>'resource'],
    'socket_last_error' => ['int', 'socket='=>'resource'],
    'socket_listen' => ['bool', 'socket'=>'resource', 'backlog='=>'int'],
    'socket_read' => ['string|false', 'socket'=>'resource', 'length'=>'int', 'type='=>'int'],
    'socket_recv' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int'],
    'socket_recvfrom' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int', '&w_name'=>'string', '&w_port='=>'int'],
    'socket_recvmsg' => ['int|false', 'socket'=>'resource', '&w_message'=>'string', 'flags='=>'int'],
    'socket_select' => ['int|false', '&rw_read_fds'=>'resource[]|null', '&rw_write_fds'=>'resource[]|null', '&rw_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int'],
    'socket_send' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'length'=>'int', 'flags'=>'int'],
    'socket_sendmsg' => ['int|false', 'socket'=>'resource', 'message'=>'array', 'flags'=>'int'],
    'socket_sendto' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'length'=>'int', 'flags'=>'int', 'addr'=>'string', 'port='=>'int'],
    'socket_set_block' => ['bool', 'socket'=>'resource'],
    'socket_set_blocking' => ['bool', 'socket'=>'resource', 'mode'=>'int'],
    'socket_set_nonblock' => ['bool', 'socket'=>'resource'],
    'socket_set_option' => ['bool', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
    'socket_set_timeout' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'],
    'socket_setopt' => ['void', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
    'socket_shutdown' => ['bool', 'socket'=>'resource', 'how='=>'int'],
    'socket_strerror' => ['string', 'errno'=>'int'],
    'socket_write' => ['int|false', 'socket'=>'resource', 'data'=>'string', 'length='=>'int'],
    'solid_fetch_prev' => ['bool', 'result_id'=>''],
    'solr_get_version' => ['string|false'],
    'sort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
    'soundex' => ['string', 'string'=>'string'],
    'spl_autoload' => ['void', 'class'=>'string', 'file_extensions='=>'string'],
    'spl_autoload_call' => ['void', 'class'=>'string'],
    'spl_autoload_extensions' => ['string', 'file_extensions='=>'string'],
    'spl_autoload_functions' => ['false|list<callable(string):void>'],
    'spl_autoload_register' => ['bool', 'callback='=>'callable(string):void', 'throw='=>'bool', 'prepend='=>'bool'],
    'spl_autoload_unregister' => ['bool', 'callback'=>'callable(string):void'],
    'spl_classes' => ['array'],
    'spl_object_hash' => ['string', 'object'=>'object'],
    'spl_object_id' => ['int', 'object'=>'object'],
    'sprintf' => ['string', 'format'=>'string', '...values='=>'string|int|float'],
    'sqlite_array_query' => ['array|false', 'dbhandle'=>'resource', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'sqlite_busy_timeout' => ['void', 'dbhandle'=>'resource', 'milliseconds'=>'int'],
    'sqlite_changes' => ['int', 'dbhandle'=>'resource'],
    'sqlite_close' => ['void', 'dbhandle'=>'resource'],
    'sqlite_column' => ['mixed', 'result'=>'resource', 'index_or_name'=>'mixed', 'decode_binary='=>'bool'],
    'sqlite_create_aggregate' => ['void', 'dbhandle'=>'resource', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'],
    'sqlite_create_function' => ['void', 'dbhandle'=>'resource', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'],
    'sqlite_current' => ['array|false', 'result'=>'resource', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'sqlite_error_string' => ['string', 'error_code'=>'int'],
    'sqlite_escape_string' => ['string', 'item'=>'string'],
    'sqlite_exec' => ['bool', 'dbhandle'=>'resource', 'query'=>'string', 'error_msg='=>'string'],
    'sqlite_factory' => ['SQLiteDatabase', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'],
    'sqlite_fetch_all' => ['array', 'result'=>'resource', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'sqlite_fetch_array' => ['array|false', 'result'=>'resource', 'result_type='=>'int', 'decode_binary='=>'bool'],
    'sqlite_fetch_column_types' => ['array|false', 'table_name'=>'string', 'dbhandle'=>'resource', 'result_type='=>'int'],
    'sqlite_fetch_object' => ['object', 'result'=>'resource', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'],
    'sqlite_fetch_single' => ['string', 'result'=>'resource', 'decode_binary='=>'bool'],
    'sqlite_fetch_string' => ['string', 'result'=>'resource', 'decode_binary'=>'bool'],
    'sqlite_field_name' => ['string', 'result'=>'resource', 'field_index'=>'int'],
    'sqlite_has_more' => ['bool', 'result'=>'resource'],
    'sqlite_has_prev' => ['bool', 'result'=>'resource'],
    'sqlite_key' => ['int', 'result'=>'resource'],
    'sqlite_last_error' => ['int', 'dbhandle'=>'resource'],
    'sqlite_last_insert_rowid' => ['int', 'dbhandle'=>'resource'],
    'sqlite_libencoding' => ['string'],
    'sqlite_libversion' => ['string'],
    'sqlite_next' => ['bool', 'result'=>'resource'],
    'sqlite_num_fields' => ['int', 'result'=>'resource'],
    'sqlite_num_rows' => ['int', 'result'=>'resource'],
    'sqlite_open' => ['resource|false', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'],
    'sqlite_popen' => ['resource|false', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'],
    'sqlite_prev' => ['bool', 'result'=>'resource'],
    'sqlite_query' => ['resource|false', 'dbhandle'=>'resource', 'query'=>'resource|string', 'result_type='=>'int', 'error_msg='=>'string'],
    'sqlite_rewind' => ['bool', 'result'=>'resource'],
    'sqlite_seek' => ['bool', 'result'=>'resource', 'rownum'=>'int'],
    'sqlite_single_query' => ['array', 'db'=>'resource', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'],
    'sqlite_udf_decode_binary' => ['string', 'data'=>'string'],
    'sqlite_udf_encode_binary' => ['string', 'data'=>'string'],
    'sqlite_unbuffered_query' => ['SQLiteUnbuffered|false', 'dbhandle'=>'resource', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'],
    'sqlite_valid' => ['bool', 'result'=>'resource'],
    'sqlsrv_begin_transaction' => ['bool', 'conn'=>'resource'],
    'sqlsrv_cancel' => ['bool', 'stmt'=>'resource'],
    'sqlsrv_client_info' => ['array|false', 'conn'=>'resource'],
    'sqlsrv_close' => ['bool', 'conn'=>'?resource'],
    'sqlsrv_commit' => ['bool', 'conn'=>'resource'],
    'sqlsrv_configure' => ['bool', 'setting'=>'string', 'value'=>'mixed'],
    'sqlsrv_connect' => ['resource|false', 'serverName'=>'string', 'connectionInfo='=>'array'],
    'sqlsrv_errors' => ['?array', 'errorsOrWarnings='=>'int'],
    'sqlsrv_execute' => ['bool', 'stmt'=>'resource'],
    'sqlsrv_fetch' => ['?bool', 'stmt'=>'resource', 'row='=>'int', 'offset='=>'int'],
    'sqlsrv_fetch_array' => ['array|null|false', 'stmt'=>'resource', 'fetchType='=>'int', 'row='=>'int', 'offset='=>'int'],
    'sqlsrv_fetch_object' => ['object|null|false', 'stmt'=>'resource', 'className='=>'string', 'ctorParams='=>'array', 'row='=>'int', 'offset='=>'int'],
    'sqlsrv_field_metadata' => ['array|false', 'stmt'=>'resource'],
    'sqlsrv_free_stmt' => ['bool', 'stmt'=>'resource'],
    'sqlsrv_get_config' => ['mixed', 'setting'=>'string'],
    'sqlsrv_get_field' => ['mixed', 'stmt'=>'resource', 'fieldIndex'=>'int', 'getAsType='=>'int'],
    'sqlsrv_has_rows' => ['bool', 'stmt'=>'resource'],
    'sqlsrv_next_result' => ['?bool', 'stmt'=>'resource'],
    'sqlsrv_num_fields' => ['int|false', 'stmt'=>'resource'],
    'sqlsrv_num_rows' => ['int|false', 'stmt'=>'resource'],
    'sqlsrv_prepare' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'],
    'sqlsrv_query' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'],
    'sqlsrv_rollback' => ['bool', 'conn'=>'resource'],
    'sqlsrv_rows_affected' => ['int|false', 'stmt'=>'resource'],
    'sqlsrv_send_stream_data' => ['bool', 'stmt'=>'resource'],
    'sqlsrv_server_info' => ['array', 'conn'=>'resource'],
    'sqrt' => ['float', 'num'=>'float'],
    'srand' => ['void', 'seed='=>'int', 'mode='=>'int'],
    'sscanf' => ['list<float|int|string|null>|int|null', 'string'=>'string', 'format'=>'string', '&...w_vars='=>'string|int|float|null'],
    'ssdeep_fuzzy_compare' => ['int', 'signature1'=>'string', 'signature2'=>'string'],
    'ssdeep_fuzzy_hash' => ['string', 'to_hash'=>'string'],
    'ssdeep_fuzzy_hash_filename' => ['string', 'file_name'=>'string'],
    'ssh2_auth_agent' => ['bool', 'session'=>'resource', 'username'=>'string'],
    'ssh2_auth_hostbased_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'hostname'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string', 'local_username='=>'string'],
    'ssh2_auth_none' => ['bool|string[]', 'session'=>'resource', 'username'=>'string'],
    'ssh2_auth_password' => ['bool', 'session'=>'resource', 'username'=>'string', 'password'=>'string'],
    'ssh2_auth_pubkey_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string'],
    'ssh2_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'methods='=>'array', 'callbacks='=>'array'],
    'ssh2_disconnect' => ['bool', 'session'=>'resource'],
    'ssh2_exec' => ['resource|false', 'session'=>'resource', 'command'=>'string', 'pty='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'],
    'ssh2_fetch_stream' => ['resource|false', 'channel'=>'resource', 'streamid'=>'int'],
    'ssh2_fingerprint' => ['string|false', 'session'=>'resource', 'flags='=>'int'],
    'ssh2_forward_accept' => ['resource|false', 'listener'=>'resource'],
    'ssh2_forward_listen' => ['resource|false', 'session'=>'resource', 'port'=>'int', 'host='=>'string', 'max_connections='=>'string'],
    'ssh2_methods_negotiated' => ['array|false', 'session'=>'resource'],
    'ssh2_poll' => ['int', '&polldes'=>'array', 'timeout='=>'int'],
    'ssh2_publickey_add' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string', 'overwrite='=>'bool', 'attributes='=>'array'],
    'ssh2_publickey_init' => ['resource|false', 'session'=>'resource'],
    'ssh2_publickey_list' => ['array|false', 'pkey'=>'resource'],
    'ssh2_publickey_remove' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string'],
    'ssh2_scp_recv' => ['bool', 'session'=>'resource', 'remote_file'=>'string', 'local_file'=>'string'],
    'ssh2_scp_send' => ['bool', 'session'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'create_mode='=>'int'],
    'ssh2_sftp' => ['resource|false', 'session'=>'resource'],
    'ssh2_sftp_chmod' => ['bool', 'sftp'=>'resource', 'filename'=>'string', 'mode'=>'int'],
    'ssh2_sftp_lstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'sftp'=>'resource', 'path'=>'string'],
    'ssh2_sftp_mkdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string', 'mode='=>'int', 'recursive='=>'bool'],
    'ssh2_sftp_readlink' => ['string|false', 'sftp'=>'resource', 'link'=>'string'],
    'ssh2_sftp_realpath' => ['string|false', 'sftp'=>'resource', 'filename'=>'string'],
    'ssh2_sftp_rename' => ['bool', 'sftp'=>'resource', 'from'=>'string', 'to'=>'string'],
    'ssh2_sftp_rmdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string'],
    'ssh2_sftp_stat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'sftp'=>'resource', 'path'=>'string'],
    'ssh2_sftp_symlink' => ['bool', 'sftp'=>'resource', 'target'=>'string', 'link'=>'string'],
    'ssh2_sftp_unlink' => ['bool', 'sftp'=>'resource', 'filename'=>'string'],
    'ssh2_shell' => ['resource|false', 'session'=>'resource', 'termtype='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'],
    'ssh2_tunnel' => ['resource|false', 'session'=>'resource', 'host'=>'string', 'port'=>'int'],
    'stat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'filename'=>'string'],
    'stats_absolute_deviation' => ['float', 'a'=>'array'],
    'stats_cdf_beta' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_cauchy' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
    'stats_cdf_exponential' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
    'stats_cdf_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_gamma' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_laplace' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_logistic' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_negative_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_noncentral_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_noncentral_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'par4'=>'float', 'which'=>'int'],
    'stats_cdf_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_normal' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_poisson' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
    'stats_cdf_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
    'stats_cdf_uniform' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_cdf_weibull' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_covariance' => ['float', 'a'=>'array', 'b'=>'array'],
    'stats_den_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
    'stats_dens_beta' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
    'stats_dens_cauchy' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
    'stats_dens_chisquare' => ['float', 'x'=>'float', 'dfr'=>'float'],
    'stats_dens_exponential' => ['float', 'x'=>'float', 'scale'=>'float'],
    'stats_dens_f' => ['float', 'x'=>'float', 'dfr1'=>'float', 'dfr2'=>'float'],
    'stats_dens_gamma' => ['float', 'x'=>'float', 'shape'=>'float', 'scale'=>'float'],
    'stats_dens_laplace' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
    'stats_dens_logistic' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
    'stats_dens_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'],
    'stats_dens_normal' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
    'stats_dens_pmf_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'],
    'stats_dens_pmf_hypergeometric' => ['float', 'n1'=>'float', 'n2'=>'float', 'N1'=>'float', 'N2'=>'float'],
    'stats_dens_pmf_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'],
    'stats_dens_pmf_poisson' => ['float', 'x'=>'float', 'lb'=>'float'],
    'stats_dens_t' => ['float', 'x'=>'float', 'dfr'=>'float'],
    'stats_dens_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
    'stats_dens_weibull' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
    'stats_harmonic_mean' => ['float', 'a'=>'array'],
    'stats_kurtosis' => ['float', 'a'=>'array'],
    'stats_rand_gen_beta' => ['float', 'a'=>'float', 'b'=>'float'],
    'stats_rand_gen_chisquare' => ['float', 'df'=>'float'],
    'stats_rand_gen_exponential' => ['float', 'av'=>'float'],
    'stats_rand_gen_f' => ['float', 'dfn'=>'float', 'dfd'=>'float'],
    'stats_rand_gen_funiform' => ['float', 'low'=>'float', 'high'=>'float'],
    'stats_rand_gen_gamma' => ['float', 'a'=>'float', 'r'=>'float'],
    'stats_rand_gen_ibinomial' => ['int', 'n'=>'int', 'pp'=>'float'],
    'stats_rand_gen_ibinomial_negative' => ['int', 'n'=>'int', 'p'=>'float'],
    'stats_rand_gen_int' => ['int'],
    'stats_rand_gen_ipoisson' => ['int', 'mu'=>'float'],
    'stats_rand_gen_iuniform' => ['int', 'low'=>'int', 'high'=>'int'],
    'stats_rand_gen_noncenral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'],
    'stats_rand_gen_noncentral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'],
    'stats_rand_gen_noncentral_f' => ['float', 'dfn'=>'float', 'dfd'=>'float', 'xnonc'=>'float'],
    'stats_rand_gen_noncentral_t' => ['float', 'df'=>'float', 'xnonc'=>'float'],
    'stats_rand_gen_normal' => ['float', 'av'=>'float', 'sd'=>'float'],
    'stats_rand_gen_t' => ['float', 'df'=>'float'],
    'stats_rand_get_seeds' => ['array'],
    'stats_rand_phrase_to_seeds' => ['array', 'phrase'=>'string'],
    'stats_rand_ranf' => ['float'],
    'stats_rand_setall' => ['void', 'iseed1'=>'int', 'iseed2'=>'int'],
    'stats_skew' => ['float', 'a'=>'array'],
    'stats_standard_deviation' => ['float', 'a'=>'array', 'sample='=>'bool'],
    'stats_stat_binomial_coef' => ['float', 'x'=>'int', 'n'=>'int'],
    'stats_stat_correlation' => ['float', 'array1'=>'array', 'array2'=>'array'],
    'stats_stat_factorial' => ['float', 'n'=>'int'],
    'stats_stat_gennch' => ['float', 'n'=>'int'],
    'stats_stat_independent_t' => ['float', 'array1'=>'array', 'array2'=>'array'],
    'stats_stat_innerproduct' => ['float', 'array1'=>'array', 'array2'=>'array'],
    'stats_stat_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
    'stats_stat_paired_t' => ['float', 'array1'=>'array', 'array2'=>'array'],
    'stats_stat_percentile' => ['float', 'arr'=>'array', 'perc'=>'float'],
    'stats_stat_powersum' => ['float', 'arr'=>'array', 'power'=>'float'],
    'stats_variance' => ['float', 'a'=>'array', 'sample='=>'bool'],
    'stomp_abort' => ['bool', 'link'=>'resource', 'transaction_id'=>'string', 'headers='=>'?array'],
    'stomp_ack' => ['bool', 'link'=>'resource', 'msg'=>'', 'headers='=>'?array'],
    'stomp_begin' => ['bool', 'link'=>'resource', 'transaction_id'=>'string', 'headers='=>'?array'],
    'stomp_close' => ['bool', 'link'=>'resource'],
    'stomp_commit' => ['bool', 'link'=>'resource', 'transaction_id'=>'string', 'headers='=>'?array'],
    'stomp_connect' => ['resource', 'link'=>'resource', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'?array'],
    'stomp_connect_error' => ['string'],
    'stomp_error' => ['string', 'link'=>'resource'],
    'stomp_get_read_timeout' => ['array', 'link'=>'resource'],
    'stomp_get_session_id' => ['string', 'link'=>'resource'],
    'stomp_has_frame' => ['bool', 'link'=>'resource'],
    'stomp_read_frame' => ['array', 'link'=>'resource', 'class_name='=>'string'],
    'stomp_send' => ['bool', 'link'=>'resource', 'destination'=>'string', 'msg'=>'', 'headers='=>'?array'],
    'stomp_set_read_timeout' => ['void', 'link'=>'resource', 'seconds'=>'int', 'microseconds='=>'?int'],
    'stomp_subscribe' => ['bool', 'link'=>'resource', 'destination'=>'string', 'headers='=>'?array'],
    'stomp_unsubscribe' => ['bool', 'link'=>'resource', 'destination'=>'string', 'headers='=>'?array'],
    'stomp_version' => ['string'],
    'str_getcsv' => ['non-empty-list<?string>', 'string'=>'string', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    'str_ireplace' => ['string|string[]', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_count='=>'int'],
    'str_pad' => ['string', 'string'=>'string', 'length'=>'int', 'pad_string='=>'string', 'pad_type='=>'int'],
    'str_repeat' => ['string', 'string'=>'string', 'times'=>'int'],
    'str_replace' => ['string|string[]', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_count='=>'int'],
    'str_rot13' => ['string', 'string'=>'string'],
    'str_shuffle' => ['string', 'string'=>'string'],
    'str_split' => ['non-empty-list<string>', 'string'=>'string', 'length='=>'positive-int'],
    'str_word_count' => ['array<int, string>|int', 'string'=>'string', 'format='=>'int', 'characters='=>'string'],
    'strcasecmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
    'strcmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'strcoll' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'strcspn' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'int'],
    'streamWrapper::__construct' => ['void'],
    'streamWrapper::__destruct' => ['void'],
    'streamWrapper::dir_closedir' => ['bool'],
    'streamWrapper::dir_opendir' => ['bool', 'path'=>'string', 'options'=>'int'],
    'streamWrapper::dir_readdir' => ['string'],
    'streamWrapper::dir_rewinddir' => ['bool'],
    'streamWrapper::mkdir' => ['bool', 'path'=>'string', 'mode'=>'int', 'options'=>'int'],
    'streamWrapper::rename' => ['bool', 'path_from'=>'string', 'path_to'=>'string'],
    'streamWrapper::rmdir' => ['bool', 'path'=>'string', 'options'=>'int'],
    'streamWrapper::stream_cast' => ['resource', 'cast_as'=>'int'],
    'streamWrapper::stream_close' => ['void'],
    'streamWrapper::stream_eof' => ['bool'],
    'streamWrapper::stream_flush' => ['bool'],
    'streamWrapper::stream_lock' => ['bool', 'operation'=>'mode'],
    'streamWrapper::stream_metadata' => ['bool', 'path'=>'string', 'option'=>'int', 'value'=>'mixed'],
    'streamWrapper::stream_open' => ['bool', 'path'=>'string', 'mode'=>'string', 'options'=>'int', 'opened_path'=>'string'],
    'streamWrapper::stream_read' => ['string', 'count'=>'int'],
    'streamWrapper::stream_seek' => ['bool', 'offset'=>'int', 'whence'=>'int'],
    'streamWrapper::stream_set_option' => ['bool', 'option'=>'int', 'arg1'=>'int', 'arg2'=>'int'],
    'streamWrapper::stream_stat' => ['array'],
    'streamWrapper::stream_tell' => ['int'],
    'streamWrapper::stream_truncate' => ['bool', 'new_size'=>'int'],
    'streamWrapper::stream_write' => ['int', 'data'=>'string'],
    'streamWrapper::unlink' => ['bool', 'path'=>'string'],
    'streamWrapper::url_stat' => ['array', 'path'=>'string', 'flags'=>'int'],
    'stream_bucket_append' => ['void', 'brigade'=>'resource', 'bucket'=>'object'],
    'stream_bucket_make_writeable' => ['?object', 'brigade'=>'resource'],
    'stream_bucket_new' => ['object', 'stream'=>'resource', 'buffer'=>'string'],
    'stream_bucket_prepend' => ['void', 'brigade'=>'resource', 'bucket'=>'object'],
    'stream_context_create' => ['resource', 'options='=>'array', 'params='=>'array'],
    'stream_context_get_default' => ['resource', 'options='=>'array'],
    'stream_context_get_options' => ['array', 'stream_or_context'=>'resource'],
    'stream_context_get_params' => ['array', 'context'=>'resource'],
    'stream_context_set_default' => ['resource', 'options'=>'array'],
    'stream_context_set_option' => ['bool', 'context'=>'', 'wrapper_or_options'=>'string', 'option_name'=>'string', 'value'=>''],
    'stream_context_set_option\'1' => ['bool', 'context'=>'', 'wrapper_or_options'=>'array'],
    'stream_context_set_params' => ['bool', 'context'=>'resource', 'params'=>'array'],
    'stream_copy_to_stream' => ['int|false', 'from'=>'resource', 'to'=>'resource', 'length='=>'int', 'offset='=>'int'],
    'stream_encoding' => ['bool', 'stream'=>'resource', 'encoding='=>'string'],
    'stream_filter_append' => ['resource|false', 'stream'=>'resource', 'filter_name'=>'string', 'mode='=>'int', 'params='=>'mixed'],
    'stream_filter_prepend' => ['resource|false', 'stream'=>'resource', 'filter_name'=>'string', 'mode='=>'int', 'params='=>'mixed'],
    'stream_filter_register' => ['bool', 'filter_name'=>'string', 'class'=>'string'],
    'stream_filter_remove' => ['bool', 'stream_filter'=>'resource'],
    'stream_get_contents' => ['string|false', 'stream'=>'resource', 'length='=>'int', 'offset='=>'int'],
    'stream_get_filters' => ['array'],
    'stream_get_line' => ['string|false', 'stream'=>'resource', 'length'=>'int', 'ending='=>'string'],
    'stream_get_meta_data' => ['array{timed_out:bool,blocked:bool,eof:bool,unread_bytes:int,stream_type:string,wrapper_type:string,wrapper_data:mixed,mode:string,seekable:bool,uri:string,mediatype:string,crypto?:array{protocol:string,cipher_name:string,cipher_bits:int,cipher_version:string}}', 'stream'=>'resource'],
    'stream_get_transports' => ['list<string>'],
    'stream_get_wrappers' => ['list<string>'],
    'stream_is_local' => ['bool', 'stream'=>'resource|string'],
    'stream_notification_callback' => ['callback', 'notification_code'=>'int', 'severity'=>'int', 'message'=>'string', 'message_code'=>'int', 'bytes_transferred'=>'int', 'bytes_max'=>'int'],
    'stream_register_wrapper' => ['bool', 'protocol'=>'string', 'class'=>'string', 'flags='=>'int'],
    'stream_resolve_include_path' => ['string|false', 'filename'=>'string'],
    'stream_select' => ['int|false', '&rw_read'=>'?resource[]', '&rw_write'=>'?resource[]', '&rw_except'=>'?resource[]', 'seconds'=>'?int', 'microseconds='=>'int'],
    'stream_set_blocking' => ['bool', 'stream'=>'resource', 'enable'=>'bool'],
    'stream_set_chunk_size' => ['int|false', 'stream'=>'resource', 'size'=>'int'],
    'stream_set_read_buffer' => ['int', 'stream'=>'resource', 'size'=>'int'],
    'stream_set_timeout' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'],
    'stream_set_write_buffer' => ['int', 'stream'=>'resource', 'size'=>'int'],
    'stream_socket_accept' => ['resource|false', 'socket'=>'resource', 'timeout='=>'float', '&w_peer_name='=>'string'],
    'stream_socket_client' => ['resource|false', 'address'=>'string', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'float', 'flags='=>'int', 'context='=>'resource'],
    'stream_socket_enable_crypto' => ['int|bool', 'stream'=>'resource', 'enable'=>'bool', 'crypto_method='=>'?int', 'session_stream='=>'resource'],
    'stream_socket_get_name' => ['string', 'socket'=>'resource', 'remote'=>'bool'],
    'stream_socket_pair' => ['resource[]|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'],
    'stream_socket_recvfrom' => ['string', 'socket'=>'resource', 'length'=>'int', 'flags='=>'int', '&w_address='=>'string'],
    'stream_socket_sendto' => ['int', 'socket'=>'resource', 'data'=>'string', 'flags='=>'int', 'address='=>'string'],
    'stream_socket_server' => ['resource|false', 'address'=>'string', '&w_error_code='=>'int', '&w_error_message='=>'string', 'flags='=>'int', 'context='=>'resource'],
    'stream_socket_shutdown' => ['bool', 'stream'=>'resource', 'mode'=>'int'],
    'stream_supports_lock' => ['bool', 'stream'=>'resource'],
    'stream_wrapper_register' => ['bool', 'protocol'=>'string', 'class'=>'string', 'flags='=>'int'],
    'stream_wrapper_restore' => ['bool', 'protocol'=>'string'],
    'stream_wrapper_unregister' => ['bool', 'protocol'=>'string'],
    'strftime' => ['string|false', 'format'=>'string', 'timestamp='=>'int'],
    'strip_tags' => ['string', 'string'=>'string', 'allowed_tags='=>'string'],
    'stripcslashes' => ['string', 'string'=>'string'],
    'stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
    'stripslashes' => ['string', 'string'=>'string'],
    'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
    'strlen' => ['0|positive-int', 'string'=>'string'],
    'strnatcasecmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'strnatcmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'strncasecmp' => ['int', 'string1'=>'string', 'string2'=>'string', 'length'=>'int'],
    'strncmp' => ['int', 'string1'=>'string', 'string2'=>'string', 'length'=>'int'],
    'strpbrk' => ['string|false', 'string'=>'string', 'characters'=>'string'],
    'strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
    'strptime' => ['array|false', 'timestamp'=>'string', 'format'=>'string'],
    'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int'],
    'strrev' => ['string', 'string'=>'string'],
    'strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
    'strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
    'strspn' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'int'],
    'strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
    'strtok' => ['string|false', 'string'=>'string', 'token'=>'string'],
    'strtok\'1' => ['string|false', 'string'=>'string'],
    'strtolower' => ['lowercase-string', 'string'=>'string'],
    'strtotime' => ['int|false', 'datetime'=>'string', 'baseTimestamp='=>'int'],
    'strtoupper' => ['string', 'string'=>'string'],
    'strtr' => ['string', 'string'=>'string', 'from'=>'string', 'to'=>'string'],
    'strtr\'1' => ['string', 'string'=>'string', 'from'=>'array'],
    'strval' => ['string', 'value'=>'mixed'],
    'styleObj::__construct' => ['void', 'label'=>'labelObj', 'style'=>'styleObj'],
    'styleObj::convertToString' => ['string'],
    'styleObj::free' => ['void'],
    'styleObj::getBinding' => ['string', 'stylebinding'=>'mixed'],
    'styleObj::getGeomTransform' => ['string'],
    'styleObj::ms_newStyleObj' => ['styleObj', 'class'=>'classObj', 'style'=>'styleObj'],
    'styleObj::removeBinding' => ['int', 'stylebinding'=>'mixed'],
    'styleObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'styleObj::setBinding' => ['int', 'stylebinding'=>'mixed', 'value'=>'string'],
    'styleObj::setGeomTransform' => ['int', 'value'=>'string'],
    'styleObj::updateFromString' => ['int', 'snippet'=>'string'],
    'substr' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'int'],
    'substr_compare' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset'=>'int', 'length='=>'int', 'case_insensitive='=>'bool'],
    'substr_count' => ['int', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'length='=>'int'],
    'substr_replace' => ['string|string[]', 'string'=>'string|string[]', 'replace'=>'mixed', 'offset'=>'mixed', 'length='=>'mixed'],
    'suhosin_encrypt_cookie' => ['string|false', 'name'=>'string', 'value'=>'string'],
    'suhosin_get_raw_cookies' => ['array'],
    'svm::crossvalidate' => ['float', 'problem'=>'array', 'number_of_folds'=>'int'],
    'svm::train' => ['SVMModel', 'problem'=>'array', 'weights='=>'array'],
    'svn_add' => ['bool', 'path'=>'string', 'recursive='=>'bool', 'force='=>'bool'],
    'svn_auth_get_parameter' => ['?string', 'key'=>'string'],
    'svn_auth_set_parameter' => ['void', 'key'=>'string', 'value'=>'string'],
    'svn_blame' => ['array', 'repository_url'=>'string', 'revision_no='=>'int'],
    'svn_cat' => ['string', 'repos_url'=>'string', 'revision_no='=>'int'],
    'svn_checkout' => ['bool', 'repos'=>'string', 'targetpath'=>'string', 'revision='=>'int', 'flags='=>'int'],
    'svn_cleanup' => ['bool', 'workingdir'=>'string'],
    'svn_client_version' => ['string'],
    'svn_commit' => ['array', 'log'=>'string', 'targets'=>'array', 'dontrecurse='=>'bool'],
    'svn_delete' => ['bool', 'path'=>'string', 'force='=>'bool'],
    'svn_diff' => ['array', 'path1'=>'string', 'rev1'=>'int', 'path2'=>'string', 'rev2'=>'int'],
    'svn_export' => ['bool', 'frompath'=>'string', 'topath'=>'string', 'working_copy='=>'bool', 'revision_no='=>'int'],
    'svn_fs_abort_txn' => ['bool', 'txn'=>'resource'],
    'svn_fs_apply_text' => ['resource', 'root'=>'resource', 'path'=>'string'],
    'svn_fs_begin_txn2' => ['resource', 'repos'=>'resource', 'rev'=>'int'],
    'svn_fs_change_node_prop' => ['bool', 'root'=>'resource', 'path'=>'string', 'name'=>'string', 'value'=>'string'],
    'svn_fs_check_path' => ['int', 'fsroot'=>'resource', 'path'=>'string'],
    'svn_fs_contents_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'],
    'svn_fs_copy' => ['bool', 'from_root'=>'resource', 'from_path'=>'string', 'to_root'=>'resource', 'to_path'=>'string'],
    'svn_fs_delete' => ['bool', 'root'=>'resource', 'path'=>'string'],
    'svn_fs_dir_entries' => ['array', 'fsroot'=>'resource', 'path'=>'string'],
    'svn_fs_file_contents' => ['resource', 'fsroot'=>'resource', 'path'=>'string'],
    'svn_fs_file_length' => ['int', 'fsroot'=>'resource', 'path'=>'string'],
    'svn_fs_is_dir' => ['bool', 'root'=>'resource', 'path'=>'string'],
    'svn_fs_is_file' => ['bool', 'root'=>'resource', 'path'=>'string'],
    'svn_fs_make_dir' => ['bool', 'root'=>'resource', 'path'=>'string'],
    'svn_fs_make_file' => ['bool', 'root'=>'resource', 'path'=>'string'],
    'svn_fs_node_created_rev' => ['int', 'fsroot'=>'resource', 'path'=>'string'],
    'svn_fs_node_prop' => ['string', 'fsroot'=>'resource', 'path'=>'string', 'propname'=>'string'],
    'svn_fs_props_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'],
    'svn_fs_revision_prop' => ['string', 'fs'=>'resource', 'revnum'=>'int', 'propname'=>'string'],
    'svn_fs_revision_root' => ['resource', 'fs'=>'resource', 'revnum'=>'int'],
    'svn_fs_txn_root' => ['resource', 'txn'=>'resource'],
    'svn_fs_youngest_rev' => ['int', 'fs'=>'resource'],
    'svn_import' => ['bool', 'path'=>'string', 'url'=>'string', 'nonrecursive'=>'bool'],
    'svn_log' => ['array', 'repos_url'=>'string', 'start_revision='=>'int', 'end_revision='=>'int', 'limit='=>'int', 'flags='=>'int'],
    'svn_ls' => ['array', 'repos_url'=>'string', 'revision_no='=>'int', 'recurse='=>'bool', 'peg='=>'bool'],
    'svn_mkdir' => ['bool', 'path'=>'string', 'log_message='=>'string'],
    'svn_move' => ['mixed', 'src_path'=>'string', 'dst_path'=>'string', 'force='=>'bool'],
    'svn_propget' => ['mixed', 'path'=>'string', 'property_name'=>'string', 'recurse='=>'bool', 'revision'=>'int'],
    'svn_proplist' => ['mixed', 'path'=>'string', 'recurse='=>'bool', 'revision'=>'int'],
    'svn_repos_create' => ['resource', 'path'=>'string', 'config='=>'array', 'fsconfig='=>'array'],
    'svn_repos_fs' => ['resource', 'repos'=>'resource'],
    'svn_repos_fs_begin_txn_for_commit' => ['resource', 'repos'=>'resource', 'rev'=>'int', 'author'=>'string', 'log_msg'=>'string'],
    'svn_repos_fs_commit_txn' => ['int', 'txn'=>'resource'],
    'svn_repos_hotcopy' => ['bool', 'repospath'=>'string', 'destpath'=>'string', 'cleanlogs'=>'bool'],
    'svn_repos_open' => ['resource', 'path'=>'string'],
    'svn_repos_recover' => ['bool', 'path'=>'string'],
    'svn_revert' => ['bool', 'path'=>'string', 'recursive='=>'bool'],
    'svn_status' => ['array', 'path'=>'string', 'flags='=>'int'],
    'svn_update' => ['int|false', 'path'=>'string', 'revno='=>'int', 'recurse='=>'bool'],
    'swf_actiongeturl' => ['', 'url'=>'string', 'target'=>'string'],
    'swf_actiongotoframe' => ['', 'framenumber'=>'int'],
    'swf_actiongotolabel' => ['', 'label'=>'string'],
    'swf_actionnextframe' => [''],
    'swf_actionplay' => [''],
    'swf_actionprevframe' => [''],
    'swf_actionsettarget' => ['', 'target'=>'string'],
    'swf_actionstop' => [''],
    'swf_actiontogglequality' => [''],
    'swf_actionwaitforframe' => ['', 'framenumber'=>'int', 'skipcount'=>'int'],
    'swf_addbuttonrecord' => ['', 'states'=>'int', 'shapeid'=>'int', 'depth'=>'int'],
    'swf_addcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'],
    'swf_closefile' => ['', 'return_file='=>'int'],
    'swf_definebitmap' => ['', 'objid'=>'int', 'image_name'=>'string'],
    'swf_definefont' => ['', 'fontid'=>'int', 'fontname'=>'string'],
    'swf_defineline' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'],
    'swf_definepoly' => ['', 'objid'=>'int', 'coords'=>'array', 'npoints'=>'int', 'width'=>'float'],
    'swf_definerect' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'],
    'swf_definetext' => ['', 'objid'=>'int', 'string'=>'string', 'docenter'=>'int'],
    'swf_endbutton' => [''],
    'swf_enddoaction' => [''],
    'swf_endshape' => [''],
    'swf_endsymbol' => [''],
    'swf_fontsize' => ['', 'size'=>'float'],
    'swf_fontslant' => ['', 'slant'=>'float'],
    'swf_fonttracking' => ['', 'tracking'=>'float'],
    'swf_getbitmapinfo' => ['array', 'bitmapid'=>'int'],
    'swf_getfontinfo' => ['array'],
    'swf_getframe' => ['int'],
    'swf_labelframe' => ['', 'name'=>'string'],
    'swf_lookat' => ['', 'view_x'=>'float', 'view_y'=>'float', 'view_z'=>'float', 'reference_x'=>'float', 'reference_y'=>'float', 'reference_z'=>'float', 'twist'=>'float'],
    'swf_modifyobject' => ['', 'depth'=>'int', 'how'=>'int'],
    'swf_mulcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'],
    'swf_nextid' => ['int'],
    'swf_oncondition' => ['', 'transition'=>'int'],
    'swf_openfile' => ['', 'filename'=>'string', 'width'=>'float', 'height'=>'float', 'framerate'=>'float', 'r'=>'float', 'g'=>'float', 'b'=>'float'],
    'swf_ortho' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float', 'zmin'=>'float', 'zmax'=>'float'],
    'swf_ortho2' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'],
    'swf_perspective' => ['', 'fovy'=>'float', 'aspect'=>'float', 'near'=>'float', 'far'=>'float'],
    'swf_placeobject' => ['', 'objid'=>'int', 'depth'=>'int'],
    'swf_polarview' => ['', 'dist'=>'float', 'azimuth'=>'float', 'incidence'=>'float', 'twist'=>'float'],
    'swf_popmatrix' => [''],
    'swf_posround' => ['', 'round'=>'int'],
    'swf_pushmatrix' => [''],
    'swf_removeobject' => ['', 'depth'=>'int'],
    'swf_rotate' => ['', 'angle'=>'float', 'axis'=>'string'],
    'swf_scale' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'],
    'swf_setfont' => ['', 'fontid'=>'int'],
    'swf_setframe' => ['', 'framenumber'=>'int'],
    'swf_shapearc' => ['', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'ang1'=>'float', 'ang2'=>'float'],
    'swf_shapecurveto' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'],
    'swf_shapecurveto3' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
    'swf_shapefillbitmapclip' => ['', 'bitmapid'=>'int'],
    'swf_shapefillbitmaptile' => ['', 'bitmapid'=>'int'],
    'swf_shapefilloff' => [''],
    'swf_shapefillsolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'],
    'swf_shapelinesolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float', 'width'=>'float'],
    'swf_shapelineto' => ['', 'x'=>'float', 'y'=>'float'],
    'swf_shapemoveto' => ['', 'x'=>'float', 'y'=>'float'],
    'swf_showframe' => [''],
    'swf_startbutton' => ['', 'objid'=>'int', 'type'=>'int'],
    'swf_startdoaction' => [''],
    'swf_startshape' => ['', 'objid'=>'int'],
    'swf_startsymbol' => ['', 'objid'=>'int'],
    'swf_textwidth' => ['float', 'string'=>'string'],
    'swf_translate' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'],
    'swf_viewport' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'],
    'swoole\async::dnsLookup' => ['void', 'hostname'=>'string', 'callback'=>'callable'],
    'swoole\async::read' => ['bool', 'filename'=>'string', 'callback'=>'callable', 'chunk_size='=>'integer', 'offset='=>'integer'],
    'swoole\async::readFile' => ['void', 'filename'=>'string', 'callback'=>'callable'],
    'swoole\async::set' => ['void', 'settings'=>'array'],
    'swoole\async::write' => ['void', 'filename'=>'string', 'content'=>'string', 'offset='=>'integer', 'callback='=>'callable'],
    'swoole\async::writeFile' => ['void', 'filename'=>'string', 'content'=>'string', 'callback='=>'callable', 'flags='=>'string'],
    'swoole\atomic::add' => ['integer', 'add_value='=>'integer'],
    'swoole\atomic::cmpset' => ['integer', 'cmp_value'=>'integer', 'new_value'=>'integer'],
    'swoole\atomic::get' => ['integer'],
    'swoole\atomic::set' => ['integer', 'value'=>'integer'],
    'swoole\atomic::sub' => ['integer', 'sub_value='=>'integer'],
    'swoole\buffer::__destruct' => ['void'],
    'swoole\buffer::__toString' => ['string'],
    'swoole\buffer::append' => ['integer', 'data'=>'string'],
    'swoole\buffer::clear' => ['void'],
    'swoole\buffer::expand' => ['integer', 'size'=>'integer'],
    'swoole\buffer::read' => ['string', 'offset'=>'integer', 'length'=>'integer'],
    'swoole\buffer::recycle' => ['void'],
    'swoole\buffer::substr' => ['string', 'offset'=>'integer', 'length='=>'integer', 'remove='=>'bool'],
    'swoole\buffer::write' => ['void', 'offset'=>'integer', 'data'=>'string'],
    'swoole\channel::__destruct' => ['void'],
    'swoole\channel::pop' => ['mixed'],
    'swoole\channel::push' => ['bool', 'data'=>'string'],
    'swoole\channel::stats' => ['array'],
    'swoole\client::__destruct' => ['void'],
    'swoole\client::close' => ['bool', 'force='=>'bool'],
    'swoole\client::connect' => ['bool', 'host'=>'string', 'port='=>'integer', 'timeout='=>'integer', 'flag='=>'integer'],
    'swoole\client::getpeername' => ['array'],
    'swoole\client::getsockname' => ['array'],
    'swoole\client::isConnected' => ['bool'],
    'swoole\client::on' => ['void', 'event'=>'string', 'callback'=>'callable'],
    'swoole\client::pause' => ['void'],
    'swoole\client::pipe' => ['void', 'socket'=>'string'],
    'swoole\client::recv' => ['void', 'size='=>'string', 'flag='=>'string'],
    'swoole\client::resume' => ['void'],
    'swoole\client::send' => ['integer', 'data'=>'string', 'flag='=>'string'],
    'swoole\client::sendfile' => ['bool', 'filename'=>'string', 'offset='=>'int'],
    'swoole\client::sendto' => ['bool', 'ip'=>'string', 'port'=>'integer', 'data'=>'string'],
    'swoole\client::set' => ['void', 'settings'=>'array'],
    'swoole\client::sleep' => ['void'],
    'swoole\client::wakeup' => ['void'],
    'swoole\connection\iterator::count' => ['int'],
    'swoole\connection\iterator::current' => ['Connection'],
    'swoole\connection\iterator::key' => ['int'],
    'swoole\connection\iterator::next' => ['Connection'],
    'swoole\connection\iterator::offsetExists' => ['bool', 'index'=>'int'],
    'swoole\connection\iterator::offsetGet' => ['Connection', 'index'=>'string'],
    'swoole\connection\iterator::offsetSet' => ['void', 'offset'=>'int', 'connection'=>'mixed'],
    'swoole\connection\iterator::offsetUnset' => ['void', 'offset'=>'int'],
    'swoole\connection\iterator::rewind' => ['void'],
    'swoole\connection\iterator::valid' => ['bool'],
    'swoole\coroutine::call_user_func' => ['mixed', 'callback'=>'callable', 'parameter='=>'mixed', '...args='=>'mixed'],
    'swoole\coroutine::call_user_func_array' => ['mixed', 'callback'=>'callable', 'param_array'=>'array'],
    'swoole\coroutine::cli_wait' => ['ReturnType'],
    'swoole\coroutine::create' => ['ReturnType'],
    'swoole\coroutine::getuid' => ['ReturnType'],
    'swoole\coroutine::resume' => ['ReturnType'],
    'swoole\coroutine::suspend' => ['ReturnType'],
    'swoole\coroutine\client::__destruct' => ['ReturnType'],
    'swoole\coroutine\client::close' => ['ReturnType'],
    'swoole\coroutine\client::connect' => ['ReturnType'],
    'swoole\coroutine\client::getpeername' => ['ReturnType'],
    'swoole\coroutine\client::getsockname' => ['ReturnType'],
    'swoole\coroutine\client::isConnected' => ['ReturnType'],
    'swoole\coroutine\client::recv' => ['ReturnType'],
    'swoole\coroutine\client::send' => ['ReturnType'],
    'swoole\coroutine\client::sendfile' => ['ReturnType'],
    'swoole\coroutine\client::sendto' => ['ReturnType'],
    'swoole\coroutine\client::set' => ['ReturnType'],
    'swoole\coroutine\http\client::__destruct' => ['ReturnType'],
    'swoole\coroutine\http\client::addFile' => ['ReturnType'],
    'swoole\coroutine\http\client::close' => ['ReturnType'],
    'swoole\coroutine\http\client::execute' => ['ReturnType'],
    'swoole\coroutine\http\client::get' => ['ReturnType'],
    'swoole\coroutine\http\client::getDefer' => ['ReturnType'],
    'swoole\coroutine\http\client::isConnected' => ['ReturnType'],
    'swoole\coroutine\http\client::post' => ['ReturnType'],
    'swoole\coroutine\http\client::recv' => ['ReturnType'],
    'swoole\coroutine\http\client::set' => ['ReturnType'],
    'swoole\coroutine\http\client::setCookies' => ['ReturnType'],
    'swoole\coroutine\http\client::setData' => ['ReturnType'],
    'swoole\coroutine\http\client::setDefer' => ['ReturnType'],
    'swoole\coroutine\http\client::setHeaders' => ['ReturnType'],
    'swoole\coroutine\http\client::setMethod' => ['ReturnType'],
    'swoole\coroutine\mysql::__destruct' => ['ReturnType'],
    'swoole\coroutine\mysql::close' => ['ReturnType'],
    'swoole\coroutine\mysql::connect' => ['ReturnType'],
    'swoole\coroutine\mysql::getDefer' => ['ReturnType'],
    'swoole\coroutine\mysql::query' => ['ReturnType'],
    'swoole\coroutine\mysql::recv' => ['ReturnType'],
    'swoole\coroutine\mysql::setDefer' => ['ReturnType'],
    'swoole\event::add' => ['bool', 'fd'=>'int', 'read_callback'=>'callable', 'write_callback='=>'callable', 'events='=>'string'],
    'swoole\event::defer' => ['void', 'callback'=>'mixed'],
    'swoole\event::del' => ['bool', 'fd'=>'string'],
    'swoole\event::exit' => ['void'],
    'swoole\event::set' => ['bool', 'fd'=>'int', 'read_callback='=>'string', 'write_callback='=>'string', 'events='=>'string'],
    'swoole\event::wait' => ['void'],
    'swoole\event::write' => ['void', 'fd'=>'string', 'data'=>'string'],
    'swoole\http\client::__destruct' => ['void'],
    'swoole\http\client::addFile' => ['void', 'path'=>'string', 'name'=>'string', 'type='=>'string', 'filename='=>'string', 'offset='=>'string'],
    'swoole\http\client::close' => ['void'],
    'swoole\http\client::download' => ['void', 'path'=>'string', 'file'=>'string', 'callback'=>'callable', 'offset='=>'integer'],
    'swoole\http\client::execute' => ['void', 'path'=>'string', 'callback'=>'string'],
    'swoole\http\client::get' => ['void', 'path'=>'string', 'callback'=>'callable'],
    'swoole\http\client::isConnected' => ['bool'],
    'swoole\http\client::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
    'swoole\http\client::post' => ['void', 'path'=>'string', 'data'=>'string', 'callback'=>'callable'],
    'swoole\http\client::push' => ['void', 'data'=>'string', 'opcode='=>'string', 'finish='=>'string'],
    'swoole\http\client::set' => ['void', 'settings'=>'array'],
    'swoole\http\client::setCookies' => ['void', 'cookies'=>'array'],
    'swoole\http\client::setData' => ['ReturnType', 'data'=>'string'],
    'swoole\http\client::setHeaders' => ['void', 'headers'=>'array'],
    'swoole\http\client::setMethod' => ['void', 'method'=>'string'],
    'swoole\http\client::upgrade' => ['void', 'path'=>'string', 'callback'=>'string'],
    'swoole\http\request::__destruct' => ['void'],
    'swoole\http\request::rawcontent' => ['string'],
    'swoole\http\response::__destruct' => ['void'],
    'swoole\http\response::cookie' => ['string', 'name'=>'string', 'value='=>'string', 'expires='=>'string', 'path='=>'string', 'domain='=>'string', 'secure='=>'string', 'httponly='=>'string'],
    'swoole\http\response::end' => ['void', 'content='=>'string'],
    'swoole\http\response::gzip' => ['ReturnType', 'compress_level='=>'string'],
    'swoole\http\response::header' => ['void', 'key'=>'string', 'value'=>'string', 'ucwords='=>'string'],
    'swoole\http\response::initHeader' => ['ReturnType'],
    'swoole\http\response::rawcookie' => ['ReturnType', 'name'=>'string', 'value='=>'string', 'expires='=>'string', 'path='=>'string', 'domain='=>'string', 'secure='=>'string', 'httponly='=>'string'],
    'swoole\http\response::sendfile' => ['ReturnType', 'filename'=>'string', 'offset='=>'int'],
    'swoole\http\response::status' => ['ReturnType', 'http_code'=>'string'],
    'swoole\http\response::write' => ['void', 'content'=>'string'],
    'swoole\http\server::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
    'swoole\http\server::start' => ['void'],
    'swoole\lock::__destruct' => ['void'],
    'swoole\lock::lock' => ['void'],
    'swoole\lock::lock_read' => ['void'],
    'swoole\lock::trylock' => ['void'],
    'swoole\lock::trylock_read' => ['void'],
    'swoole\lock::unlock' => ['void'],
    'swoole\mmap::open' => ['ReturnType', 'filename'=>'string', 'size='=>'string', 'offset='=>'string'],
    'swoole\mysql::__destruct' => ['void'],
    'swoole\mysql::close' => ['void'],
    'swoole\mysql::connect' => ['void', 'server_config'=>'array', 'callback'=>'callable'],
    'swoole\mysql::getBuffer' => ['ReturnType'],
    'swoole\mysql::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
    'swoole\mysql::query' => ['ReturnType', 'sql'=>'string', 'callback'=>'callable'],
    'swoole\process::__destruct' => ['void'],
    'swoole\process::alarm' => ['void', 'interval_usec'=>'integer'],
    'swoole\process::close' => ['void'],
    'swoole\process::daemon' => ['void', 'nochdir='=>'bool', 'noclose='=>'bool'],
    'swoole\process::exec' => ['ReturnType', 'exec_file'=>'string', 'args'=>'string'],
    'swoole\process::exit' => ['void', 'exit_code='=>'string'],
    'swoole\process::freeQueue' => ['void'],
    'swoole\process::kill' => ['void', 'pid'=>'integer', 'signal_no='=>'string'],
    'swoole\process::name' => ['void', 'process_name'=>'string'],
    'swoole\process::pop' => ['mixed', 'maxsize='=>'integer'],
    'swoole\process::push' => ['bool', 'data'=>'string'],
    'swoole\process::read' => ['string', 'maxsize='=>'integer'],
    'swoole\process::signal' => ['void', 'signal_no'=>'string', 'callback'=>'callable'],
    'swoole\process::start' => ['void'],
    'swoole\process::statQueue' => ['array'],
    'swoole\process::useQueue' => ['bool', 'key'=>'integer', 'mode='=>'integer'],
    'swoole\process::wait' => ['array', 'blocking='=>'bool'],
    'swoole\process::write' => ['integer', 'data'=>'string'],
    'swoole\redis\server::format' => ['ReturnType', 'type'=>'string', 'value='=>'string'],
    'swoole\redis\server::setHandler' => ['ReturnType', 'command'=>'string', 'callback'=>'string', 'number_of_string_param='=>'string', 'type_of_array_param='=>'string'],
    'swoole\redis\server::start' => ['ReturnType'],
    'swoole\serialize::pack' => ['ReturnType', 'data'=>'string', 'is_fast='=>'int'],
    'swoole\serialize::unpack' => ['ReturnType', 'data'=>'string', 'args='=>'string'],
    'swoole\server::addProcess' => ['bool', 'process'=>'swoole_process'],
    'swoole\server::addlistener' => ['void', 'host'=>'string', 'port'=>'integer', 'socket_type'=>'string'],
    'swoole\server::after' => ['ReturnType', 'after_time_ms'=>'integer', 'callback'=>'callable', 'param='=>'string'],
    'swoole\server::bind' => ['bool', 'fd'=>'integer', 'uid'=>'integer'],
    'swoole\server::close' => ['bool', 'fd'=>'integer', 'reset='=>'bool'],
    'swoole\server::confirm' => ['bool', 'fd'=>'integer'],
    'swoole\server::connection_info' => ['array', 'fd'=>'integer', 'reactor_id='=>'integer'],
    'swoole\server::connection_list' => ['array', 'start_fd'=>'integer', 'pagesize='=>'integer'],
    'swoole\server::defer' => ['void', 'callback'=>'callable'],
    'swoole\server::exist' => ['bool', 'fd'=>'integer'],
    'swoole\server::finish' => ['void', 'data'=>'string'],
    'swoole\server::getClientInfo' => ['ReturnType', 'fd'=>'integer', 'reactor_id='=>'integer'],
    'swoole\server::getClientList' => ['array', 'start_fd'=>'integer', 'pagesize='=>'integer'],
    'swoole\server::getLastError' => ['integer'],
    'swoole\server::heartbeat' => ['mixed', 'if_close_connection'=>'bool'],
    'swoole\server::listen' => ['bool', 'host'=>'string', 'port'=>'integer', 'socket_type'=>'string'],
    'swoole\server::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
    'swoole\server::pause' => ['void', 'fd'=>'integer'],
    'swoole\server::protect' => ['void', 'fd'=>'integer', 'is_protected='=>'bool'],
    'swoole\server::reload' => ['bool'],
    'swoole\server::resume' => ['void', 'fd'=>'integer'],
    'swoole\server::send' => ['bool', 'fd'=>'integer', 'data'=>'string', 'reactor_id='=>'integer'],
    'swoole\server::sendMessage' => ['bool', 'worker_id'=>'integer', 'data'=>'string'],
    'swoole\server::sendfile' => ['bool', 'fd'=>'integer', 'filename'=>'string', 'offset='=>'integer'],
    'swoole\server::sendto' => ['bool', 'ip'=>'string', 'port'=>'integer', 'data'=>'string', 'server_socket='=>'string'],
    'swoole\server::sendwait' => ['bool', 'fd'=>'integer', 'data'=>'string'],
    'swoole\server::set' => ['ReturnType', 'settings'=>'array'],
    'swoole\server::shutdown' => ['void'],
    'swoole\server::start' => ['void'],
    'swoole\server::stats' => ['array'],
    'swoole\server::stop' => ['bool', 'worker_id='=>'integer'],
    'swoole\server::task' => ['mixed', 'data'=>'string', 'dst_worker_id='=>'integer', 'callback='=>'callable'],
    'swoole\server::taskWaitMulti' => ['void', 'tasks'=>'array', 'timeout_ms='=>'double'],
    'swoole\server::taskwait' => ['void', 'data'=>'string', 'timeout='=>'float', 'worker_id='=>'integer'],
    'swoole\server::tick' => ['void', 'interval_ms'=>'integer', 'callback'=>'callable'],
    'swoole\server\port::__destruct' => ['void'],
    'swoole\server\port::on' => ['ReturnType', 'event_name'=>'string', 'callback'=>'callable'],
    'swoole\server\port::set' => ['void', 'settings'=>'array'],
    'swoole\table::column' => ['ReturnType', 'name'=>'string', 'type'=>'string', 'size='=>'integer'],
    'swoole\table::count' => ['integer'],
    'swoole\table::create' => ['void'],
    'swoole\table::current' => ['array'],
    'swoole\table::decr' => ['ReturnType', 'key'=>'string', 'column'=>'string', 'decrby='=>'integer'],
    'swoole\table::del' => ['void', 'key'=>'string'],
    'swoole\table::destroy' => ['void'],
    'swoole\table::exist' => ['bool', 'key'=>'string'],
    'swoole\table::get' => ['integer', 'row_key'=>'string', 'column_key'=>'string'],
    'swoole\table::incr' => ['void', 'key'=>'string', 'column'=>'string', 'incrby='=>'integer'],
    'swoole\table::key' => ['string'],
    'swoole\table::next' => ['ReturnType'],
    'swoole\table::rewind' => ['void'],
    'swoole\table::set' => ['VOID', 'key'=>'string', 'value'=>'array'],
    'swoole\table::valid' => ['bool'],
    'swoole\timer::after' => ['void', 'after_time_ms'=>'int', 'callback'=>'callable'],
    'swoole\timer::clear' => ['void', 'timer_id'=>'integer'],
    'swoole\timer::exists' => ['bool', 'timer_id'=>'integer'],
    'swoole\timer::tick' => ['void', 'interval_ms'=>'integer', 'callback'=>'callable', 'param='=>'string'],
    'swoole\websocket\server::exist' => ['bool', 'fd'=>'integer'],
    'swoole\websocket\server::on' => ['ReturnType', 'event_name'=>'string', 'callback'=>'callable'],
    'swoole\websocket\server::pack' => ['binary', 'data'=>'string', 'opcode='=>'string', 'finish='=>'string', 'mask='=>'string'],
    'swoole\websocket\server::push' => ['void', 'fd'=>'string', 'data'=>'string', 'opcode='=>'string', 'finish='=>'string'],
    'swoole\websocket\server::unpack' => ['string', 'data'=>'binary'],
    'swoole_async_dns_lookup' => ['bool', 'hostname'=>'string', 'callback'=>'callable'],
    'swoole_async_read' => ['bool', 'filename'=>'string', 'callback'=>'callable', 'chunk_size='=>'int', 'offset='=>'int'],
    'swoole_async_readfile' => ['bool', 'filename'=>'string', 'callback'=>'string'],
    'swoole_async_set' => ['void', 'settings'=>'array'],
    'swoole_async_write' => ['bool', 'filename'=>'string', 'content'=>'string', 'offset='=>'int', 'callback='=>'callable'],
    'swoole_async_writefile' => ['bool', 'filename'=>'string', 'content'=>'string', 'callback='=>'callable', 'flags='=>'int'],
    'swoole_client_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'],
    'swoole_cpu_num' => ['int'],
    'swoole_errno' => ['int'],
    'swoole_event_add' => ['int', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'],
    'swoole_event_defer' => ['bool', 'callback'=>'callable'],
    'swoole_event_del' => ['bool', 'fd'=>'int'],
    'swoole_event_exit' => ['void'],
    'swoole_event_set' => ['bool', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'],
    'swoole_event_wait' => ['void'],
    'swoole_event_write' => ['bool', 'fd'=>'int', 'data'=>'string'],
    'swoole_get_local_ip' => ['array'],
    'swoole_last_error' => ['int'],
    'swoole_load_module' => ['mixed', 'filename'=>'string'],
    'swoole_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'],
    'swoole_set_process_name' => ['void', 'process_name'=>'string', 'size='=>'int'],
    'swoole_strerror' => ['string', 'errno'=>'int', 'error_type='=>'int'],
    'swoole_timer_after' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'],
    'swoole_timer_exists' => ['bool', 'timer_id'=>'int'],
    'swoole_timer_tick' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'],
    'swoole_version' => ['string'],
    'symbolObj::__construct' => ['void', 'map'=>'mapObj', 'symbolname'=>'string'],
    'symbolObj::free' => ['void'],
    'symbolObj::getPatternArray' => ['array'],
    'symbolObj::getPointsArray' => ['array'],
    'symbolObj::ms_newSymbolObj' => ['int', 'map'=>'mapObj', 'symbolname'=>'string'],
    'symbolObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'symbolObj::setImagePath' => ['int', 'filename'=>'string'],
    'symbolObj::setPattern' => ['int', 'int'=>'array'],
    'symbolObj::setPoints' => ['int', 'double'=>'array'],
    'symlink' => ['bool', 'target'=>'string', 'link'=>'string'],
    'sys_get_temp_dir' => ['string'],
    'sys_getloadavg' => ['array'],
    'syslog' => ['bool', 'priority'=>'int', 'message'=>'string'],
    'system' => ['string|false', 'command'=>'string', '&w_result_code='=>'int'],
    'taint' => ['bool', '&rw_string'=>'string', '&...w_other_strings='=>'string'],
    'tan' => ['float', 'num'=>'float'],
    'tanh' => ['float', 'num'=>'float'],
    'tcpwrap_check' => ['bool', 'daemon'=>'string', 'address'=>'string', 'user='=>'string', 'nodns='=>'bool'],
    'tempnam' => ['string|false', 'directory'=>'string', 'prefix'=>'string'],
    'textdomain' => ['string', 'domain'=>'?string'],
    'tidy::__construct' => ['void', 'filename='=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
    'tidy::body' => ['?tidyNode'],
    'tidy::cleanRepair' => ['bool'],
    'tidy::diagnose' => ['bool'],
    'tidy::getConfig' => ['array'],
    'tidy::getHtmlVer' => ['int'],
    'tidy::getOpt' => ['string|int|bool', 'option'=>'string'],
    'tidy::getOptDoc' => ['string', 'option'=>'string'],
    'tidy::getRelease' => ['string'],
    'tidy::getStatus' => ['int'],
    'tidy::head' => ['?tidyNode'],
    'tidy::html' => ['?tidyNode'],
    'tidy::isXhtml' => ['bool'],
    'tidy::isXml' => ['bool'],
    'tidy::parseFile' => ['bool', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
    'tidy::parseString' => ['bool', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
    'tidy::repairFile' => ['string', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
    'tidy::repairString' => ['string', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
    'tidy::root' => ['?tidyNode'],
    'tidyNode::__construct' => ['void'],
    'tidyNode::getParent' => ['?tidyNode'],
    'tidyNode::hasChildren' => ['bool'],
    'tidyNode::hasSiblings' => ['bool'],
    'tidyNode::isAsp' => ['bool'],
    'tidyNode::isComment' => ['bool'],
    'tidyNode::isHtml' => ['bool'],
    'tidyNode::isJste' => ['bool'],
    'tidyNode::isPhp' => ['bool'],
    'tidyNode::isText' => ['bool'],
    'tidy_access_count' => ['int', 'tidy'=>'tidy'],
    'tidy_clean_repair' => ['bool', 'tidy'=>'tidy'],
    'tidy_config_count' => ['int', 'tidy'=>'tidy'],
    'tidy_diagnose' => ['bool', 'tidy'=>'tidy'],
    'tidy_error_count' => ['int', 'tidy'=>'tidy'],
    'tidy_get_body' => ['?tidyNode', 'tidy'=>'tidy'],
    'tidy_get_config' => ['array', 'tidy'=>'tidy'],
    'tidy_get_error_buffer' => ['string', 'tidy'=>'tidy'],
    'tidy_get_head' => ['?tidyNode', 'tidy'=>'tidy'],
    'tidy_get_html' => ['?tidyNode', 'tidy'=>'tidy'],
    'tidy_get_html_ver' => ['int', 'tidy'=>'tidy'],
    'tidy_get_opt_doc' => ['string', 'tidy'=>'tidy', 'option'=>'string'],
    'tidy_get_output' => ['string', 'tidy'=>'tidy'],
    'tidy_get_release' => ['string'],
    'tidy_get_root' => ['?tidyNode', 'tidy'=>'tidy'],
    'tidy_get_status' => ['int', 'tidy'=>'tidy'],
    'tidy_getopt' => ['mixed', 'tidy'=>'string', 'option'=>'tidy'],
    'tidy_is_xhtml' => ['bool', 'tidy'=>'tidy'],
    'tidy_is_xml' => ['bool', 'tidy'=>'tidy'],
    'tidy_load_config' => ['void', 'filename'=>'string', 'encoding'=>'string'],
    'tidy_parse_file' => ['tidy', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
    'tidy_parse_string' => ['tidy', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
    'tidy_repair_file' => ['string', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
    'tidy_repair_string' => ['string', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
    'tidy_reset_config' => ['bool'],
    'tidy_save_config' => ['bool', 'filename'=>'string'],
    'tidy_set_encoding' => ['bool', 'encoding'=>'string'],
    'tidy_setopt' => ['bool', 'option'=>'string', 'value'=>'mixed'],
    'tidy_warning_count' => ['int', 'tidy'=>'tidy'],
    'time' => ['positive-int'],
    'time_nanosleep' => ['array{0:0|positive-int,1:0|positive-int}|bool', 'seconds'=>'positive-int', 'nanoseconds'=>'positive-int'],
    'time_sleep_until' => ['bool', 'timestamp'=>'float'],
    'timezone_abbreviations_list' => ['array<string, list<array{dst: bool, offset: int, timezone_id: string|null}>>'],
    'timezone_identifiers_list' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'string'],
    'timezone_location_get' => ['array|false', 'object'=>'DateTimeZone'],
    'timezone_name_from_abbr' => ['string|false', 'abbr'=>'string', 'utcOffset='=>'int', 'isDST='=>'int'],
    'timezone_name_get' => ['string', 'object'=>'DateTimeZone'],
    'timezone_offset_get' => ['int|false', 'object'=>'DateTimeZone', 'datetime'=>'DateTimeInterface'],
    'timezone_open' => ['DateTimeZone|false', 'timezone'=>'string'],
    'timezone_transitions_get' => ['list<array{ts: int, time: string, offset: int, isdst: bool, abbr: string}>|false', 'object'=>'DateTimeZone', 'timestampBegin='=>'int', 'timestampEnd='=>'int'],
    'timezone_version_get' => ['string'],
    'tmpfile' => ['resource|false'],
    'token_get_all' => ['list<string|array{0:int,1:string,2:int}>', 'code'=>'string', 'flags='=>'int'],
    'token_name' => ['string', 'id'=>'int'],
    'touch' => ['bool', 'filename'=>'string', 'mtime='=>'int', 'atime='=>'int'],
    'trader_acos' => ['array', 'real'=>'array'],
    'trader_ad' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array'],
    'trader_add' => ['array', 'real0'=>'array', 'real1'=>'array'],
    'trader_adosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int'],
    'trader_adx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_adxr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_apo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'],
    'trader_aroon' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
    'trader_aroonosc' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
    'trader_asin' => ['array', 'real'=>'array'],
    'trader_atan' => ['array', 'real'=>'array'],
    'trader_atr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_avgprice' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_bbands' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDevUp='=>'float', 'nbDevDn='=>'float', 'mAType='=>'int'],
    'trader_beta' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'],
    'trader_bop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cci' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_cdl2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdl3blackcrows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdl3inside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdl3linestrike' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdl3outside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdl3starsinsouth' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdl3whitesoldiers' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlabandonedbaby' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
    'trader_cdladvanceblock' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlbelthold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlbreakaway' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlclosingmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlconcealbabyswall' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlcounterattack' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdldarkcloudcover' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
    'trader_cdldoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdldojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdldragonflydoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlengulfing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdleveningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
    'trader_cdleveningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
    'trader_cdlgapsidesidewhite' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlgravestonedoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlhangingman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlharami' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlharamicross' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlhighwave' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlhikkake' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlhikkakemod' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlhomingpigeon' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlidentical3crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlinneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlinvertedhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlkicking' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlkickingbylength' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlladderbottom' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdllongleggeddoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdllongline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlmatchinglow' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlmathold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
    'trader_cdlmorningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
    'trader_cdlmorningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
    'trader_cdlonneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlpiercing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlrickshawman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlrisefall3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlseparatinglines' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlshootingstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlshortline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlspinningtop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlstalledpattern' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlsticksandwich' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdltakuri' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdltasukigap' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlthrusting' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdltristar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlunique3river' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlupsidegap2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_cdlxsidegap3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_ceil' => ['array', 'real'=>'array'],
    'trader_cmo' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_correl' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'],
    'trader_cos' => ['array', 'real'=>'array'],
    'trader_cosh' => ['array', 'real'=>'array'],
    'trader_dema' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_div' => ['array', 'real0'=>'array', 'real1'=>'array'],
    'trader_dx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_ema' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_errno' => ['int'],
    'trader_exp' => ['array', 'real'=>'array'],
    'trader_floor' => ['array', 'real'=>'array'],
    'trader_get_compat' => ['int'],
    'trader_get_unstable_period' => ['int', 'functionId'=>'int'],
    'trader_ht_dcperiod' => ['array', 'real'=>'array'],
    'trader_ht_dcphase' => ['array', 'real'=>'array'],
    'trader_ht_phasor' => ['array', 'real'=>'array'],
    'trader_ht_sine' => ['array', 'real'=>'array'],
    'trader_ht_trendline' => ['array', 'real'=>'array'],
    'trader_ht_trendmode' => ['array', 'real'=>'array'],
    'trader_kama' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_linearreg' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_linearreg_angle' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_linearreg_intercept' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_linearreg_slope' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_ln' => ['array', 'real'=>'array'],
    'trader_log10' => ['array', 'real'=>'array'],
    'trader_ma' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'mAType='=>'int'],
    'trader_macd' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'signalPeriod='=>'int'],
    'trader_macdext' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'fastMAType='=>'int', 'slowPeriod='=>'int', 'slowMAType='=>'int', 'signalPeriod='=>'int', 'signalMAType='=>'int'],
    'trader_macdfix' => ['array', 'real'=>'array', 'signalPeriod='=>'int'],
    'trader_mama' => ['array', 'real'=>'array', 'fastLimit='=>'float', 'slowLimit='=>'float'],
    'trader_mavp' => ['array', 'real'=>'array', 'periods'=>'array', 'minPeriod='=>'int', 'maxPeriod='=>'int', 'mAType='=>'int'],
    'trader_max' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_maxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_medprice' => ['array', 'high'=>'array', 'low'=>'array'],
    'trader_mfi' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'timePeriod='=>'int'],
    'trader_midpoint' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_midprice' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
    'trader_min' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_minindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_minmax' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_minmaxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_minus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_minus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
    'trader_mom' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_mult' => ['array', 'real0'=>'array', 'real1'=>'array'],
    'trader_natr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_obv' => ['array', 'real'=>'array', 'volume'=>'array'],
    'trader_plus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_plus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
    'trader_ppo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'],
    'trader_roc' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_rocp' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_rocr' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_rocr100' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_rsi' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_sar' => ['array', 'high'=>'array', 'low'=>'array', 'acceleration='=>'float', 'maximum='=>'float'],
    'trader_sarext' => ['array', 'high'=>'array', 'low'=>'array', 'startValue='=>'float', 'offsetOnReverse='=>'float', 'accelerationInitLong='=>'float', 'accelerationLong='=>'float', 'accelerationMaxLong='=>'float', 'accelerationInitShort='=>'float', 'accelerationShort='=>'float', 'accelerationMaxShort='=>'float'],
    'trader_set_compat' => ['void', 'compatId'=>'int'],
    'trader_set_unstable_period' => ['void', 'functionId'=>'int', 'timePeriod'=>'int'],
    'trader_sin' => ['array', 'real'=>'array'],
    'trader_sinh' => ['array', 'real'=>'array'],
    'trader_sma' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_sqrt' => ['array', 'real'=>'array'],
    'trader_stddev' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'],
    'trader_stoch' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'slowK_Period='=>'int', 'slowK_MAType='=>'int', 'slowD_Period='=>'int', 'slowD_MAType='=>'int'],
    'trader_stochf' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'],
    'trader_stochrsi' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'],
    'trader_sub' => ['array', 'real0'=>'array', 'real1'=>'array'],
    'trader_sum' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_t3' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'vFactor='=>'float'],
    'trader_tan' => ['array', 'real'=>'array'],
    'trader_tanh' => ['array', 'real'=>'array'],
    'trader_tema' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_trange' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_trima' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_trix' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_tsf' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trader_typprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_ultosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod1='=>'int', 'timePeriod2='=>'int', 'timePeriod3='=>'int'],
    'trader_var' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'],
    'trader_wclprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
    'trader_willr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
    'trader_wma' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
    'trait_exists' => ['bool', 'trait'=>'string', 'autoload='=>'bool'],
    'transliterator_create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'],
    'transliterator_create_from_rules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'],
    'transliterator_create_inverse' => ['?Transliterator', 'transliterator'=>'Transliterator'],
    'transliterator_get_error_code' => ['int', 'transliterator'=>'Transliterator'],
    'transliterator_get_error_message' => ['string', 'transliterator'=>'Transliterator'],
    'transliterator_list_ids' => ['array'],
    'transliterator_transliterate' => ['string|false', 'transliterator'=>'Transliterator|string', 'string'=>'string', 'start='=>'int', 'end='=>'int'],
    'trigger_error' => ['bool', 'message'=>'string', 'error_level='=>'256|512|1024|16384'],
    'trim' => ['string', 'string'=>'string', 'characters='=>'string'],
    'uasort' => ['bool', '&rw_array'=>'array', 'callback'=>'callable(mixed,mixed):int'],
    'ucfirst' => ['string', 'string'=>'string'],
    'ucwords' => ['string', 'string'=>'string', 'separators='=>'string'],
    'udm_add_search_limit' => ['bool', 'agent'=>'resource', 'var'=>'int', 'value'=>'string'],
    'udm_alloc_agent' => ['resource', 'dbaddr'=>'string', 'dbmode='=>'string'],
    'udm_alloc_agent_array' => ['resource', 'databases'=>'array'],
    'udm_api_version' => ['int'],
    'udm_cat_list' => ['array', 'agent'=>'resource', 'category'=>'string'],
    'udm_cat_path' => ['array', 'agent'=>'resource', 'category'=>'string'],
    'udm_check_charset' => ['bool', 'agent'=>'resource', 'charset'=>'string'],
    'udm_check_stored' => ['int', 'agent'=>'', 'link'=>'int', 'doc_id'=>'string'],
    'udm_clear_search_limits' => ['bool', 'agent'=>'resource'],
    'udm_close_stored' => ['int', 'agent'=>'', 'link'=>'int'],
    'udm_crc32' => ['int', 'agent'=>'resource', 'string'=>'string'],
    'udm_errno' => ['int', 'agent'=>'resource'],
    'udm_error' => ['string', 'agent'=>'resource'],
    'udm_find' => ['resource', 'agent'=>'resource', 'query'=>'string'],
    'udm_free_agent' => ['int', 'agent'=>'resource'],
    'udm_free_ispell_data' => ['bool', 'agent'=>'int'],
    'udm_free_res' => ['bool', 'res'=>'resource'],
    'udm_get_doc_count' => ['int', 'agent'=>'resource'],
    'udm_get_res_field' => ['string', 'res'=>'resource', 'row'=>'int', 'field'=>'int'],
    'udm_get_res_param' => ['string', 'res'=>'resource', 'param'=>'int'],
    'udm_hash32' => ['int', 'agent'=>'resource', 'string'=>'string'],
    'udm_load_ispell_data' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val1'=>'string', 'val2'=>'string', 'flag'=>'int'],
    'udm_open_stored' => ['int', 'agent'=>'', 'storedaddr'=>'string'],
    'udm_set_agent_param' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val'=>'string'],
    'ui\area::onDraw' => ['', 'pen'=>'UI\Draw\Pen', 'areaSize'=>'UI\Size', 'clipPoint'=>'UI\Point', 'clipSize'=>'UI\Size'],
    'ui\area::onKey' => ['', 'key'=>'string', 'ext'=>'int', 'flags'=>'int'],
    'ui\area::onMouse' => ['', 'areaPoint'=>'UI\Point', 'areaSize'=>'UI\Size', 'flags'=>'int'],
    'ui\area::redraw' => [''],
    'ui\area::scrollTo' => ['', 'point'=>'UI\Point', 'size'=>'UI\Size'],
    'ui\area::setSize' => ['', 'size'=>'UI\Size'],
    'ui\control::destroy' => [''],
    'ui\control::disable' => [''],
    'ui\control::enable' => [''],
    'ui\control::getParent' => ['UI\Control'],
    'ui\control::getTopLevel' => ['int'],
    'ui\control::hide' => [''],
    'ui\control::isEnabled' => ['bool'],
    'ui\control::isVisible' => ['bool'],
    'ui\control::setParent' => ['', 'parent'=>'UI\Control'],
    'ui\control::show' => [''],
    'ui\controls\box::append' => ['int', 'control'=>'Control', 'stretchy='=>'bool'],
    'ui\controls\box::delete' => ['bool', 'index'=>'int'],
    'ui\controls\box::getOrientation' => ['int'],
    'ui\controls\box::isPadded' => ['bool'],
    'ui\controls\box::setPadded' => ['', 'padded'=>'bool'],
    'ui\controls\button::getText' => ['string'],
    'ui\controls\button::onClick' => [''],
    'ui\controls\button::setText' => ['', 'text'=>'string'],
    'ui\controls\check::getText' => ['string'],
    'ui\controls\check::isChecked' => ['bool'],
    'ui\controls\check::onToggle' => [''],
    'ui\controls\check::setChecked' => ['', 'checked'=>'bool'],
    'ui\controls\check::setText' => ['', 'text'=>'string'],
    'ui\controls\colorbutton::getColor' => ['UI\Color'],
    'ui\controls\colorbutton::onChange' => [''],
    'ui\controls\combo::append' => ['', 'text'=>'string'],
    'ui\controls\combo::getSelected' => ['int'],
    'ui\controls\combo::onSelected' => [''],
    'ui\controls\combo::setSelected' => ['', 'index'=>'int'],
    'ui\controls\editablecombo::append' => ['', 'text'=>'string'],
    'ui\controls\editablecombo::getText' => ['string'],
    'ui\controls\editablecombo::onChange' => [''],
    'ui\controls\editablecombo::setText' => ['', 'text'=>'string'],
    'ui\controls\entry::getText' => ['string'],
    'ui\controls\entry::isReadOnly' => ['bool'],
    'ui\controls\entry::onChange' => [''],
    'ui\controls\entry::setReadOnly' => ['', 'readOnly'=>'bool'],
    'ui\controls\entry::setText' => ['', 'text'=>'string'],
    'ui\controls\form::append' => ['int', 'label'=>'string', 'control'=>'UI\Control', 'stretchy='=>'bool'],
    'ui\controls\form::delete' => ['bool', 'index'=>'int'],
    'ui\controls\form::isPadded' => ['bool'],
    'ui\controls\form::setPadded' => ['', 'padded'=>'bool'],
    'ui\controls\grid::append' => ['', 'control'=>'UI\Control', 'left'=>'int', 'top'=>'int', 'xspan'=>'int', 'yspan'=>'int', 'hexpand'=>'bool', 'halign'=>'int', 'vexpand'=>'bool', 'valign'=>'int'],
    'ui\controls\grid::isPadded' => ['bool'],
    'ui\controls\grid::setPadded' => ['', 'padding'=>'bool'],
    'ui\controls\group::append' => ['', 'control'=>'UI\Control'],
    'ui\controls\group::getTitle' => ['string'],
    'ui\controls\group::hasMargin' => ['bool'],
    'ui\controls\group::setMargin' => ['', 'margin'=>'bool'],
    'ui\controls\group::setTitle' => ['', 'title'=>'string'],
    'ui\controls\label::getText' => ['string'],
    'ui\controls\label::setText' => ['', 'text'=>'string'],
    'ui\controls\multilineentry::append' => ['', 'text'=>'string'],
    'ui\controls\multilineentry::getText' => ['string'],
    'ui\controls\multilineentry::isReadOnly' => ['bool'],
    'ui\controls\multilineentry::onChange' => [''],
    'ui\controls\multilineentry::setReadOnly' => ['', 'readOnly'=>'bool'],
    'ui\controls\multilineentry::setText' => ['', 'text'=>'string'],
    'ui\controls\progress::getValue' => ['int'],
    'ui\controls\progress::setValue' => ['', 'value'=>'int'],
    'ui\controls\radio::append' => ['', 'text'=>'string'],
    'ui\controls\radio::getSelected' => ['int'],
    'ui\controls\radio::onSelected' => [''],
    'ui\controls\radio::setSelected' => ['', 'index'=>'int'],
    'ui\controls\slider::getValue' => ['int'],
    'ui\controls\slider::onChange' => [''],
    'ui\controls\slider::setValue' => ['', 'value'=>'int'],
    'ui\controls\spin::getValue' => ['int'],
    'ui\controls\spin::onChange' => [''],
    'ui\controls\spin::setValue' => ['', 'value'=>'int'],
    'ui\controls\tab::append' => ['int', 'name'=>'string', 'control'=>'UI\Control'],
    'ui\controls\tab::delete' => ['bool', 'index'=>'int'],
    'ui\controls\tab::hasMargin' => ['bool', 'page'=>'int'],
    'ui\controls\tab::insertAt' => ['', 'name'=>'string', 'page'=>'int', 'control'=>'UI\Control'],
    'ui\controls\tab::pages' => ['int'],
    'ui\controls\tab::setMargin' => ['', 'page'=>'int', 'margin'=>'bool'],
    'ui\draw\brush::getColor' => ['UI\Draw\Color'],
    'ui\draw\brush\gradient::delStop' => ['int', 'index'=>'int'],
    'ui\draw\color::getChannel' => ['float', 'channel'=>'int'],
    'ui\draw\color::setChannel' => ['void', 'channel'=>'int', 'value'=>'float'],
    'ui\draw\matrix::invert' => [''],
    'ui\draw\matrix::isInvertible' => ['bool'],
    'ui\draw\matrix::multiply' => ['UI\Draw\Matrix', 'matrix'=>'UI\Draw\Matrix'],
    'ui\draw\matrix::rotate' => ['', 'point'=>'UI\Point', 'amount'=>'float'],
    'ui\draw\matrix::scale' => ['', 'center'=>'UI\Point', 'point'=>'UI\Point'],
    'ui\draw\matrix::skew' => ['', 'point'=>'UI\Point', 'amount'=>'UI\Point'],
    'ui\draw\matrix::translate' => ['', 'point'=>'UI\Point'],
    'ui\draw\path::addRectangle' => ['', 'point'=>'UI\Point', 'size'=>'UI\Size'],
    'ui\draw\path::arcTo' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
    'ui\draw\path::bezierTo' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
    'ui\draw\path::closeFigure' => [''],
    'ui\draw\path::end' => [''],
    'ui\draw\path::lineTo' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
    'ui\draw\path::newFigure' => ['', 'point'=>'UI\Point'],
    'ui\draw\path::newFigureWithArc' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
    'ui\draw\pen::clip' => ['', 'path'=>'UI\Draw\Path'],
    'ui\draw\pen::restore' => [''],
    'ui\draw\pen::save' => [''],
    'ui\draw\pen::transform' => ['', 'matrix'=>'UI\Draw\Matrix'],
    'ui\draw\pen::write' => ['', 'point'=>'UI\Point', 'layout'=>'UI\Draw\Text\Layout'],
    'ui\draw\stroke::getCap' => ['int'],
    'ui\draw\stroke::getJoin' => ['int'],
    'ui\draw\stroke::getMiterLimit' => ['float'],
    'ui\draw\stroke::getThickness' => ['float'],
    'ui\draw\stroke::setCap' => ['', 'cap'=>'int'],
    'ui\draw\stroke::setJoin' => ['', 'join'=>'int'],
    'ui\draw\stroke::setMiterLimit' => ['', 'limit'=>'float'],
    'ui\draw\stroke::setThickness' => ['', 'thickness'=>'float'],
    'ui\draw\text\font::getAscent' => ['float'],
    'ui\draw\text\font::getDescent' => ['float'],
    'ui\draw\text\font::getLeading' => ['float'],
    'ui\draw\text\font::getUnderlinePosition' => ['float'],
    'ui\draw\text\font::getUnderlineThickness' => ['float'],
    'ui\draw\text\font\descriptor::getFamily' => ['string'],
    'ui\draw\text\font\descriptor::getItalic' => ['int'],
    'ui\draw\text\font\descriptor::getSize' => ['float'],
    'ui\draw\text\font\descriptor::getStretch' => ['int'],
    'ui\draw\text\font\descriptor::getWeight' => ['int'],
    'ui\draw\text\font\fontfamilies' => ['array'],
    'ui\draw\text\layout::setWidth' => ['', 'width'=>'float'],
    'ui\executor::kill' => ['void'],
    'ui\executor::onExecute' => ['void'],
    'ui\menu::append' => ['UI\MenuItem', 'name'=>'string', 'type='=>'string'],
    'ui\menu::appendAbout' => ['UI\MenuItem', 'type='=>'string'],
    'ui\menu::appendCheck' => ['UI\MenuItem', 'name'=>'string', 'type='=>'string'],
    'ui\menu::appendPreferences' => ['UI\MenuItem', 'type='=>'string'],
    'ui\menu::appendQuit' => ['UI\MenuItem', 'type='=>'string'],
    'ui\menu::appendSeparator' => [''],
    'ui\menuitem::disable' => [''],
    'ui\menuitem::enable' => [''],
    'ui\menuitem::isChecked' => ['bool'],
    'ui\menuitem::onClick' => [''],
    'ui\menuitem::setChecked' => ['', 'checked'=>'bool'],
    'ui\point::getX' => ['float'],
    'ui\point::getY' => ['float'],
    'ui\point::setX' => ['', 'point'=>'float'],
    'ui\point::setY' => ['', 'point'=>'float'],
    'ui\quit' => ['void'],
    'ui\run' => ['void', 'flags='=>'int'],
    'ui\size::getHeight' => ['float'],
    'ui\size::getWidth' => ['float'],
    'ui\size::setHeight' => ['', 'size'=>'float'],
    'ui\size::setWidth' => ['', 'size'=>'float'],
    'ui\window::add' => ['', 'control'=>'UI\Control'],
    'ui\window::error' => ['', 'title'=>'string', 'msg'=>'string'],
    'ui\window::getSize' => ['UI\Size'],
    'ui\window::getTitle' => ['string'],
    'ui\window::hasBorders' => ['bool'],
    'ui\window::hasMargin' => ['bool'],
    'ui\window::isFullScreen' => ['bool'],
    'ui\window::msg' => ['', 'title'=>'string', 'msg'=>'string'],
    'ui\window::onClosing' => ['int'],
    'ui\window::open' => ['string'],
    'ui\window::save' => ['string'],
    'ui\window::setBorders' => ['', 'borders'=>'bool'],
    'ui\window::setFullScreen' => ['', 'full'=>'bool'],
    'ui\window::setMargin' => ['', 'margin'=>'bool'],
    'ui\window::setSize' => ['', 'size'=>'UI\Size'],
    'ui\window::setTitle' => ['', 'title'=>'string'],
    'uksort' => ['bool', '&rw_array'=>'array', 'callback'=>'callable(mixed,mixed):int'],
    'umask' => ['int', 'mask='=>'int'],
    'uniqid' => ['non-empty-string', 'prefix='=>'string', 'more_entropy='=>'bool'],
    'unixtojd' => ['int', 'timestamp='=>'int'],
    'unlink' => ['bool', 'filename'=>'string', 'context='=>'resource'],
    'unpack' => ['array', 'format'=>'string', 'string'=>'string'],
    'unregister_tick_function' => ['void', 'callback'=>'callable'],
    'unserialize' => ['mixed', 'data'=>'string', 'options='=>'array{allowed_classes?:string[]|bool}'],
    'unset' => ['void', 'var='=>'mixed', '...args='=>'mixed'],
    'untaint' => ['bool', '&rw_string'=>'string', '&...rw_strings='=>'string'],
    'uopz_allow_exit' => ['void', 'allow'=>'bool'],
    'uopz_backup' => ['void', 'class'=>'string', 'function'=>'string'],
    'uopz_backup\'1' => ['void', 'function'=>'string'],
    'uopz_compose' => ['void', 'name'=>'string', 'classes'=>'array', 'methods='=>'array', 'properties='=>'array', 'flags='=>'int'],
    'uopz_copy' => ['Closure', 'class'=>'string', 'function'=>'string'],
    'uopz_copy\'1' => ['Closure', 'function'=>'string'],
    'uopz_delete' => ['void', 'class'=>'string', 'function'=>'string'],
    'uopz_delete\'1' => ['void', 'function'=>'string'],
    'uopz_extend' => ['bool', 'class'=>'string', 'parent'=>'string'],
    'uopz_flags' => ['int', 'class'=>'string', 'function'=>'string', 'flags'=>'int'],
    'uopz_flags\'1' => ['int', 'function'=>'string', 'flags'=>'int'],
    'uopz_function' => ['void', 'class'=>'string', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'],
    'uopz_function\'1' => ['void', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'],
    'uopz_get_exit_status' => ['?int'],
    'uopz_get_hook' => ['?Closure', 'class'=>'string', 'function'=>'string'],
    'uopz_get_hook\'1' => ['?Closure', 'function'=>'string'],
    'uopz_get_mock' => ['string|object|null', 'class'=>'string'],
    'uopz_get_property' => ['mixed', 'class'=>'object|string', 'property'=>'string'],
    'uopz_get_return' => ['mixed', 'class='=>'string', 'function='=>'string'],
    'uopz_get_static' => ['?array', 'class'=>'string', 'function'=>'string'],
    'uopz_implement' => ['bool', 'class'=>'string', 'interface'=>'string'],
    'uopz_overload' => ['void', 'opcode'=>'int', 'callable'=>'Callable'],
    'uopz_redefine' => ['bool', 'class'=>'string', 'constant'=>'string', 'value'=>'mixed'],
    'uopz_redefine\'1' => ['bool', 'constant'=>'string', 'value'=>'mixed'],
    'uopz_rename' => ['void', 'class'=>'string', 'function'=>'string', 'rename'=>'string'],
    'uopz_rename\'1' => ['void', 'function'=>'string', 'rename'=>'string'],
    'uopz_restore' => ['void', 'class'=>'string', 'function'=>'string'],
    'uopz_restore\'1' => ['void', 'function'=>'string'],
    'uopz_set_hook' => ['bool', 'class'=>'string', 'function'=>'string', 'hook'=>'Closure'],
    'uopz_set_hook\'1' => ['bool', 'function'=>'string', 'hook'=>'Closure'],
    'uopz_set_mock' => ['void', 'class'=>'string', 'mock'=>'object|string'],
    'uopz_set_property' => ['void', 'class'=>'object|string', 'property'=>'string', 'value'=>'mixed'],
    'uopz_set_return' => ['bool', 'class'=>'string', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'],
    'uopz_set_return\'1' => ['bool', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'],
    'uopz_set_static' => ['void', 'class'=>'string', 'function'=>'string', 'static'=>'array'],
    'uopz_undefine' => ['bool', 'class'=>'string', 'constant'=>'string'],
    'uopz_undefine\'1' => ['bool', 'constant'=>'string'],
    'uopz_unset_hook' => ['bool', 'class'=>'string', 'function'=>'string'],
    'uopz_unset_hook\'1' => ['bool', 'function'=>'string'],
    'uopz_unset_mock' => ['void', 'class'=>'string'],
    'uopz_unset_return' => ['bool', 'class='=>'string', 'function='=>'string'],
    'uopz_unset_return\'1' => ['bool', 'function'=>'string'],
    'urldecode' => ['string', 'string'=>'string'],
    'urlencode' => ['string', 'string'=>'string'],
    'use_soap_error_handler' => ['bool', 'enable='=>'bool'],
    'user_error' => ['bool', 'message'=>'string', 'error_level='=>'int'],
    'usleep' => ['void', 'microseconds'=>'positive-int|0'],
    'usort' => ['bool', '&rw_array'=>'array', 'callback'=>'callable(mixed,mixed):int'],
    'utf8_decode' => ['string', 'string'=>'string'],
    'utf8_encode' => ['string', 'string'=>'string'],
    'var_dump' => ['void', 'value'=>'mixed', '...values='=>'mixed'],
    'var_export' => ['?string', 'value'=>'mixed', 'return='=>'bool'],
    'variant_abs' => ['mixed', 'value'=>'mixed'],
    'variant_add' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_and' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_cast' => ['VARIANT', 'variant'=>'VARIANT', 'type'=>'int'],
    'variant_cat' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_cmp' => ['int', 'left'=>'mixed', 'right'=>'mixed', 'locale_id='=>'int', 'flags='=>'int'],
    'variant_date_from_timestamp' => ['VARIANT', 'timestamp'=>'int'],
    'variant_date_to_timestamp' => ['int', 'variant'=>'VARIANT'],
    'variant_div' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_eqv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_fix' => ['mixed', 'value'=>'mixed'],
    'variant_get_type' => ['int', 'variant'=>'VARIANT'],
    'variant_idiv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_imp' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_int' => ['mixed', 'value'=>'mixed'],
    'variant_mod' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_mul' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_neg' => ['mixed', 'value'=>'mixed'],
    'variant_not' => ['mixed', 'value'=>'mixed'],
    'variant_or' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_pow' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_round' => ['mixed', 'value'=>'mixed', 'decimals'=>'int'],
    'variant_set' => ['void', 'variant'=>'object', 'value'=>'mixed'],
    'variant_set_type' => ['void', 'variant'=>'object', 'type'=>'int'],
    'variant_sub' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'variant_xor' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
    'version_compare' => ['bool', 'version1'=>'string', 'version2'=>'string', 'operator'=>'\'<\'|\'lt\'|\'<=\'|\'le\'|\'>\'|\'gt\'|\'>=\'|\'ge\'|\'==\'|\'=\'|\'eq\'|\'!=\'|\'<>\'|\'ne\''],
    'version_compare\'1' => ['int', 'version1'=>'string', 'version2'=>'string'],
    'vfprintf' => ['int', 'stream'=>'resource', 'format'=>'string', 'values'=>'array'],
    'virtual' => ['bool', 'uri'=>'string'],
    'vpopmail_add_alias_domain' => ['bool', 'domain'=>'string', 'aliasdomain'=>'string'],
    'vpopmail_add_alias_domain_ex' => ['bool', 'olddomain'=>'string', 'newdomain'=>'string'],
    'vpopmail_add_domain' => ['bool', 'domain'=>'string', 'dir'=>'string', 'uid'=>'int', 'gid'=>'int'],
    'vpopmail_add_domain_ex' => ['bool', 'domain'=>'string', 'passwd'=>'string', 'quota='=>'string', 'bounce='=>'string', 'apop='=>'bool'],
    'vpopmail_add_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'gecos='=>'string', 'apop='=>'bool'],
    'vpopmail_alias_add' => ['bool', 'user'=>'string', 'domain'=>'string', 'alias'=>'string'],
    'vpopmail_alias_del' => ['bool', 'user'=>'string', 'domain'=>'string'],
    'vpopmail_alias_del_domain' => ['bool', 'domain'=>'string'],
    'vpopmail_alias_get' => ['array', 'alias'=>'string', 'domain'=>'string'],
    'vpopmail_alias_get_all' => ['array', 'domain'=>'string'],
    'vpopmail_auth_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'string'],
    'vpopmail_del_domain' => ['bool', 'domain'=>'string'],
    'vpopmail_del_domain_ex' => ['bool', 'domain'=>'string'],
    'vpopmail_del_user' => ['bool', 'user'=>'string', 'domain'=>'string'],
    'vpopmail_error' => ['string'],
    'vpopmail_passwd' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'bool'],
    'vpopmail_set_user_quota' => ['bool', 'user'=>'string', 'domain'=>'string', 'quota'=>'string'],
    'vprintf' => ['int', 'format'=>'string', 'values'=>'array'],
    'vsprintf' => ['string', 'format'=>'string', 'values'=>'array'],
    'w32api_deftype' => ['bool', 'typename'=>'string', 'member1_type'=>'string', 'member1_name'=>'string', '...args='=>'string'],
    'w32api_init_dtype' => ['resource', 'typename'=>'string', 'value'=>'', '...args='=>''],
    'w32api_invoke_function' => ['', 'funcname'=>'string', 'argument'=>'', '...args='=>''],
    'w32api_register_function' => ['bool', 'library'=>'string', 'function_name'=>'string', 'return_type'=>'string'],
    'w32api_set_call_method' => ['', 'method'=>'int'],
    'wddx_add_vars' => ['bool', 'packet_id'=>'resource', 'var_names'=>'mixed', '...vars='=>'mixed'],
    'wddx_deserialize' => ['mixed', 'packet'=>'string'],
    'wddx_packet_end' => ['string', 'packet_id'=>'resource'],
    'wddx_packet_start' => ['resource|false', 'comment='=>'string'],
    'wddx_serialize_value' => ['string|false', 'value'=>'mixed', 'comment='=>'string'],
    'wddx_serialize_vars' => ['string|false', 'var_name'=>'mixed', '...vars='=>'mixed'],
    'webObj::convertToString' => ['string'],
    'webObj::free' => ['void'],
    'webObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
    'webObj::updateFromString' => ['int', 'snippet'=>'string'],
    'win32_continue_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
    'win32_create_service' => ['int|false', 'details'=>'array', 'machine='=>'string'],
    'win32_delete_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
    'win32_get_last_control_message' => ['int'],
    'win32_pause_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
    'win32_ps_list_procs' => ['array'],
    'win32_ps_stat_mem' => ['array'],
    'win32_ps_stat_proc' => ['array', 'pid='=>'int'],
    'win32_query_service_status' => ['array|false|int', 'servicename'=>'string', 'machine='=>'string'],
    'win32_send_custom_control' => ['int', 'servicename'=>'string', 'control'=>'int', 'machine='=>'string'],
    'win32_set_service_exit_code' => ['int', 'exitCode='=>'int'],
    'win32_set_service_exit_mode' => ['bool', 'gracefulMode='=>'bool'],
    'win32_set_service_status' => ['bool|int', 'status'=>'int', 'checkpoint='=>'int'],
    'win32_start_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
    'win32_start_service_ctrl_dispatcher' => ['bool|int', 'name'=>'string'],
    'win32_stop_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
    'wincache_fcache_fileinfo' => ['array|false', 'summaryonly='=>'bool'],
    'wincache_fcache_meminfo' => ['array|false'],
    'wincache_lock' => ['bool', 'key'=>'string', 'isglobal='=>'bool'],
    'wincache_ocache_fileinfo' => ['array|false', 'summaryonly='=>'bool'],
    'wincache_ocache_meminfo' => ['array|false'],
    'wincache_refresh_if_changed' => ['bool', 'files='=>'array'],
    'wincache_rplist_fileinfo' => ['array|false', 'summaryonly='=>'bool'],
    'wincache_rplist_meminfo' => ['array|false'],
    'wincache_scache_info' => ['array|false', 'summaryonly='=>'bool'],
    'wincache_scache_meminfo' => ['array|false'],
    'wincache_ucache_add' => ['bool', 'key'=>'string', 'value'=>'mixed', 'ttl='=>'int'],
    'wincache_ucache_add\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
    'wincache_ucache_cas' => ['bool', 'key'=>'string', 'old_value'=>'int', 'new_value'=>'int'],
    'wincache_ucache_clear' => ['bool'],
    'wincache_ucache_dec' => ['int|false', 'key'=>'string', 'dec_by='=>'int', 'success='=>'bool'],
    'wincache_ucache_delete' => ['bool', 'key'=>'mixed'],
    'wincache_ucache_exists' => ['bool', 'key'=>'string'],
    'wincache_ucache_get' => ['mixed', 'key'=>'mixed', '&w_success='=>'bool'],
    'wincache_ucache_inc' => ['int|false', 'key'=>'string', 'inc_by='=>'int', 'success='=>'bool'],
    'wincache_ucache_info' => ['array|false', 'summaryonly='=>'bool', 'key='=>'string'],
    'wincache_ucache_meminfo' => ['array|false'],
    'wincache_ucache_set' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int'],
    'wincache_ucache_set\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
    'wincache_unlock' => ['bool', 'key'=>'string'],
    'wkhtmltox\image\converter::convert' => ['?string'],
    'wkhtmltox\image\converter::getVersion' => ['string'],
    'wkhtmltox\pdf\converter::add' => ['void', 'object'=>'wkhtmltox\PDF\Object'],
    'wkhtmltox\pdf\converter::convert' => ['?string'],
    'wkhtmltox\pdf\converter::getVersion' => ['string'],
    'wordwrap' => ['string', 'string'=>'string', 'width='=>'int', 'break='=>'string', 'cut_long_words='=>'bool'],
    'xattr_get' => ['string', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'],
    'xattr_list' => ['array', 'filename'=>'string', 'flags='=>'int'],
    'xattr_remove' => ['bool', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'],
    'xattr_set' => ['bool', 'filename'=>'string', 'name'=>'string', 'value'=>'string', 'flags='=>'int'],
    'xattr_supported' => ['bool', 'filename'=>'string', 'flags='=>'int'],
    'xcache_asm' => ['string', 'filename'=>'string'],
    'xcache_clear_cache' => ['void', 'type'=>'int', 'id='=>'int'],
    'xcache_coredump' => ['string', 'op_type'=>'int'],
    'xcache_count' => ['int', 'type'=>'int'],
    'xcache_coverager_decode' => ['array', 'data'=>'string'],
    'xcache_coverager_get' => ['array', 'clean='=>'bool'],
    'xcache_coverager_start' => ['void', 'clean='=>'bool'],
    'xcache_coverager_stop' => ['void', 'clean='=>'bool'],
    'xcache_dasm_file' => ['string', 'filename'=>'string'],
    'xcache_dasm_string' => ['string', 'code'=>'string'],
    'xcache_dec' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'],
    'xcache_decode' => ['bool', 'filename'=>'string'],
    'xcache_encode' => ['string', 'filename'=>'string'],
    'xcache_get' => ['mixed', 'name'=>'string'],
    'xcache_get_data_type' => ['string', 'type'=>'int'],
    'xcache_get_op_spec' => ['string', 'op_type'=>'int'],
    'xcache_get_op_type' => ['string', 'op_type'=>'int'],
    'xcache_get_opcode' => ['string', 'opcode'=>'int'],
    'xcache_get_opcode_spec' => ['string', 'opcode'=>'int'],
    'xcache_inc' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'],
    'xcache_info' => ['array', 'type'=>'int', 'id'=>'int'],
    'xcache_is_autoglobal' => ['string', 'name'=>'string'],
    'xcache_isset' => ['bool', 'name'=>'string'],
    'xcache_list' => ['array', 'type'=>'int', 'id'=>'int'],
    'xcache_set' => ['bool', 'name'=>'string', 'value'=>'mixed', 'ttl='=>'int'],
    'xcache_unset' => ['bool', 'name'=>'string'],
    'xcache_unset_by_prefix' => ['bool', 'prefix'=>'string'],
    'xdebug_break' => ['bool'],
    'xdebug_call_class' => ['string', 'depth='=>'int'],
    'xdebug_call_file' => ['string', 'depth='=>'int'],
    'xdebug_call_function' => ['string', 'depth='=>'int'],
    'xdebug_call_line' => ['int', 'depth='=>'int'],
    'xdebug_clear_aggr_profiling_data' => ['bool'],
    'xdebug_code_coverage_started' => ['bool'],
    'xdebug_debug_zval' => ['void', '...varName'=>'string'],
    'xdebug_debug_zval_stdout' => ['void', '...varName'=>'string'],
    'xdebug_disable' => ['void'],
    'xdebug_dump_aggr_profiling_data' => ['bool'],
    'xdebug_dump_superglobals' => ['void'],
    'xdebug_enable' => ['void'],
    'xdebug_get_code_coverage' => ['array'],
    'xdebug_get_collected_errors' => ['string', 'clean='=>'bool'],
    'xdebug_get_declared_vars' => ['array'],
    'xdebug_get_formatted_function_stack' => [''],
    'xdebug_get_function_count' => ['int'],
    'xdebug_get_function_stack' => ['array', 'message='=>'string', 'options='=>'int'],
    'xdebug_get_headers' => ['array'],
    'xdebug_get_monitored_functions' => ['array'],
    'xdebug_get_profiler_filename' => ['string|false'],
    'xdebug_get_stack_depth' => ['int'],
    'xdebug_get_tracefile_name' => ['string'],
    'xdebug_is_debugger_active' => ['bool'],
    'xdebug_is_enabled' => ['bool'],
    'xdebug_memory_usage' => ['int'],
    'xdebug_peak_memory_usage' => ['int'],
    'xdebug_print_function_stack' => ['array', 'message='=>'string', 'options='=>'int'],
    'xdebug_set_filter' => ['void', 'group'=>'int', 'list_type'=>'int', 'configuration'=>'array'],
    'xdebug_start_code_coverage' => ['void', 'options='=>'int'],
    'xdebug_start_error_collection' => ['void'],
    'xdebug_start_function_monitor' => ['void', 'list_of_functions_to_monitor'=>'string[]'],
    'xdebug_start_trace' => ['void', 'trace_file'=>'', 'options='=>'int|mixed'],
    'xdebug_stop_code_coverage' => ['void', 'cleanup='=>'bool'],
    'xdebug_stop_error_collection' => ['void'],
    'xdebug_stop_function_monitor' => ['void'],
    'xdebug_stop_trace' => ['void'],
    'xdebug_time_index' => ['float'],
    'xdebug_var_dump' => ['void', '...var'=>''],
    'xdiff_file_bdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'],
    'xdiff_file_bdiff_size' => ['int', 'file'=>'string'],
    'xdiff_file_bpatch' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'],
    'xdiff_file_diff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string', 'context='=>'int', 'minimal='=>'bool'],
    'xdiff_file_diff_binary' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'],
    'xdiff_file_merge3' => ['mixed', 'old_file'=>'string', 'new_file1'=>'string', 'new_file2'=>'string', 'dest'=>'string'],
    'xdiff_file_patch' => ['mixed', 'file'=>'string', 'patch'=>'string', 'dest'=>'string', 'flags='=>'int'],
    'xdiff_file_patch_binary' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'],
    'xdiff_file_rabdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'],
    'xdiff_string_bdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'],
    'xdiff_string_bdiff_size' => ['int', 'patch'=>'string'],
    'xdiff_string_bpatch' => ['string', 'string'=>'string', 'patch'=>'string'],
    'xdiff_string_diff' => ['string', 'old_data'=>'string', 'new_data'=>'string', 'context='=>'int', 'minimal='=>'bool'],
    'xdiff_string_diff_binary' => ['string', 'old_data'=>'string', 'new_data'=>'string'],
    'xdiff_string_merge3' => ['mixed', 'old_data'=>'string', 'new_data1'=>'string', 'new_data2'=>'string', 'error='=>'string'],
    'xdiff_string_patch' => ['string', 'string'=>'string', 'patch'=>'string', 'flags='=>'int', '&w_error='=>'string'],
    'xdiff_string_patch_binary' => ['string', 'string'=>'string', 'patch'=>'string'],
    'xdiff_string_rabdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'],
    'xhprof_disable' => ['array'],
    'xhprof_enable' => ['void', 'flags='=>'int', 'options='=>'array'],
    'xhprof_sample_disable' => ['array'],
    'xhprof_sample_enable' => ['void'],
    'xlswriter_get_author' => ['string'],
    'xlswriter_get_version' => ['string'],
    'xml_error_string' => ['?string', 'error_code'=>'int'],
    'xml_get_current_byte_index' => ['int|false', 'parser'=>'resource'],
    'xml_get_current_column_number' => ['int|false', 'parser'=>'resource'],
    'xml_get_current_line_number' => ['int|false', 'parser'=>'resource'],
    'xml_get_error_code' => ['int|false', 'parser'=>'resource'],
    'xml_parse' => ['int', 'parser'=>'resource', 'data'=>'string', 'is_final='=>'bool'],
    'xml_parse_into_struct' => ['int', 'parser'=>'resource', 'data'=>'string', '&w_values'=>'array', '&w_index='=>'array'],
    'xml_parser_create' => ['resource', 'encoding='=>'string'],
    'xml_parser_create_ns' => ['resource', 'encoding='=>'string', 'separator='=>'string'],
    'xml_parser_free' => ['bool', 'parser'=>'resource'],
    'xml_parser_get_option' => ['string|false', 'parser'=>'resource', 'option'=>'int'],
    'xml_parser_set_option' => ['bool', 'parser'=>'resource', 'option'=>'int', 'value'=>'mixed'],
    'xml_set_character_data_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xml_set_default_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xml_set_element_handler' => ['bool', 'parser'=>'resource', 'start_handler'=>'callable', 'end_handler'=>'callable'],
    'xml_set_end_namespace_decl_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xml_set_external_entity_ref_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xml_set_notation_decl_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xml_set_object' => ['bool', 'parser'=>'resource', 'object'=>'object'],
    'xml_set_processing_instruction_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xml_set_start_namespace_decl_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xml_set_unparsed_entity_decl_handler' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
    'xmlrpc_decode' => ['mixed', 'xml'=>'string', 'encoding='=>'string'],
    'xmlrpc_decode_request' => ['?array', 'xml'=>'string', '&w_method'=>'string', 'encoding='=>'string'],
    'xmlrpc_encode' => ['string', 'value'=>'mixed'],
    'xmlrpc_encode_request' => ['string', 'method'=>'string', 'params'=>'mixed', 'output_options='=>'array'],
    'xmlrpc_get_type' => ['string', 'value'=>'mixed'],
    'xmlrpc_is_fault' => ['bool', 'arg'=>'array'],
    'xmlrpc_parse_method_descriptions' => ['array', 'xml'=>'string'],
    'xmlrpc_server_add_introspection_data' => ['int', 'server'=>'resource', 'desc'=>'array'],
    'xmlrpc_server_call_method' => ['string', 'server'=>'resource', 'xml'=>'string', 'user_data'=>'mixed', 'output_options='=>'array'],
    'xmlrpc_server_create' => ['resource'],
    'xmlrpc_server_destroy' => ['int', 'server'=>'resource'],
    'xmlrpc_server_register_introspection_callback' => ['bool', 'server'=>'resource', 'function'=>'string'],
    'xmlrpc_server_register_method' => ['bool', 'server'=>'resource', 'method_name'=>'string', 'function'=>'string'],
    'xmlrpc_set_type' => ['bool', '&rw_value'=>'string|DateTime', 'type'=>'string'],
    'xmlwriter_end_attribute' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_cdata' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_comment' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_document' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_dtd' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_dtd_attlist' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_dtd_element' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_dtd_entity' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_element' => ['bool', 'writer'=>'resource'],
    'xmlwriter_end_pi' => ['bool', 'writer'=>'resource'],
    'xmlwriter_flush' => ['string|int|false', 'writer'=>'resource', 'empty='=>'bool'],
    'xmlwriter_full_end_element' => ['bool', 'writer'=>'resource'],
    'xmlwriter_open_memory' => ['resource|false'],
    'xmlwriter_open_uri' => ['resource|false', 'uri'=>'string'],
    'xmlwriter_output_memory' => ['string', 'writer'=>'resource', 'flush='=>'bool'],
    'xmlwriter_set_indent' => ['bool', 'writer'=>'resource', 'enable'=>'bool'],
    'xmlwriter_set_indent_string' => ['bool', 'writer'=>'resource', 'indentation'=>'string'],
    'xmlwriter_start_attribute' => ['bool', 'writer'=>'resource', 'name'=>'string'],
    'xmlwriter_start_attribute_ns' => ['bool', 'writer'=>'resource', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string'],
    'xmlwriter_start_cdata' => ['bool', 'writer'=>'resource'],
    'xmlwriter_start_comment' => ['bool', 'writer'=>'resource'],
    'xmlwriter_start_document' => ['bool', 'writer'=>'resource', 'version='=>'?string', 'encoding='=>'?string', 'standalone='=>'?string'],
    'xmlwriter_start_dtd' => ['bool', 'writer'=>'resource', 'qualifiedName'=>'string', 'publicId='=>'?string', 'systemId='=>'?string'],
    'xmlwriter_start_dtd_attlist' => ['bool', 'writer'=>'resource', 'name'=>'string'],
    'xmlwriter_start_dtd_element' => ['bool', 'writer'=>'resource', 'qualifiedName'=>'string'],
    'xmlwriter_start_dtd_entity' => ['bool', 'writer'=>'resource', 'name'=>'string', 'isParam'=>'bool'],
    'xmlwriter_start_element' => ['bool', 'writer'=>'resource', 'name'=>'string'],
    'xmlwriter_start_element_ns' => ['bool', 'writer'=>'resource', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
    'xmlwriter_start_pi' => ['bool', 'writer'=>'resource', 'target'=>'string'],
    'xmlwriter_text' => ['bool', 'writer'=>'resource', 'content'=>'string'],
    'xmlwriter_write_attribute' => ['bool', 'writer'=>'resource', 'name'=>'string', 'value'=>'string'],
    'xmlwriter_write_attribute_ns' => ['bool', 'writer'=>'resource', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
    'xmlwriter_write_cdata' => ['bool', 'writer'=>'resource', 'content'=>'string'],
    'xmlwriter_write_comment' => ['bool', 'writer'=>'resource', 'content'=>'string'],
    'xmlwriter_write_dtd' => ['bool', 'writer'=>'resource', 'name'=>'string', 'publicId='=>'?string', 'systemId='=>'?string', 'content='=>'?string'],
    'xmlwriter_write_dtd_attlist' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'string'],
    'xmlwriter_write_dtd_element' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'string'],
    'xmlwriter_write_dtd_entity' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'string', 'isParam'=>'bool', 'publicId'=>'string', 'systemId'=>'string', 'notationData'=>'string'],
    'xmlwriter_write_element' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'?string'],
    'xmlwriter_write_element_ns' => ['bool', 'writer'=>'resource', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'string', 'content'=>'?string'],
    'xmlwriter_write_pi' => ['bool', 'writer'=>'resource', 'target'=>'string', 'content'=>'string'],
    'xmlwriter_write_raw' => ['bool', 'writer'=>'resource', 'content'=>'string'],
    'xpath_new_context' => ['XPathContext', 'dom_document'=>'DOMDocument'],
    'xpath_register_ns' => ['bool', 'xpath_context'=>'xpathcontext', 'prefix'=>'string', 'uri'=>'string'],
    'xpath_register_ns_auto' => ['bool', 'xpath_context'=>'xpathcontext', 'context_node='=>'object'],
    'xptr_new_context' => ['XPathContext'],
    'xsl_xsltprocessor_get_parameter' => ['string', 'namespace'=>'string', 'name'=>'string'],
    'xsl_xsltprocessor_get_security_prefs' => ['int'],
    'xsl_xsltprocessor_has_exslt_support' => ['bool'],
    'xsl_xsltprocessor_register_php_functions' => ['', 'restrict'=>''],
    'xsl_xsltprocessor_remove_parameter' => ['bool', 'namespace'=>'string', 'name'=>'string'],
    'xsl_xsltprocessor_set_parameter' => ['bool', 'namespace'=>'string', 'name'=>'', 'value'=>'string'],
    'xsl_xsltprocessor_set_profiling' => ['bool', 'filename'=>'string'],
    'xsl_xsltprocessor_set_security_prefs' => ['int', 'securityprefs'=>'int'],
    'xsl_xsltprocessor_transform_to_uri' => ['int', 'doc'=>'DOMDocument', 'uri'=>'string'],
    'xsl_xsltprocessor_transform_to_xml' => ['string', 'doc'=>'DOMDocument'],
    'xslt_backend_info' => ['string'],
    'xslt_backend_name' => ['string'],
    'xslt_backend_version' => ['string'],
    'xslt_create' => ['resource'],
    'xslt_errno' => ['int', 'xh'=>''],
    'xslt_error' => ['string', 'xh'=>''],
    'xslt_free' => ['', 'xh'=>''],
    'xslt_getopt' => ['int', 'processor'=>''],
    'xslt_process' => ['', 'xh'=>'', 'xmlcontainer'=>'string', 'xslcontainer'=>'string', 'resultcontainer='=>'string', 'arguments='=>'array', 'parameters='=>'array'],
    'xslt_set_base' => ['', 'xh'=>'', 'uri'=>'string'],
    'xslt_set_encoding' => ['', 'xh'=>'', 'encoding'=>'string'],
    'xslt_set_error_handler' => ['', 'xh'=>'', 'handler'=>''],
    'xslt_set_log' => ['', 'xh'=>'', 'log='=>''],
    'xslt_set_object' => ['bool', 'processor'=>'', 'object'=>'object'],
    'xslt_set_sax_handler' => ['', 'xh'=>'', 'handlers'=>'array'],
    'xslt_set_sax_handlers' => ['', 'processor'=>'', 'handlers'=>'array'],
    'xslt_set_scheme_handler' => ['', 'xh'=>'', 'handlers'=>'array'],
    'xslt_set_scheme_handlers' => ['', 'xh'=>'', 'handlers'=>'array'],
    'xslt_setopt' => ['', 'processor'=>'', 'newmask'=>'int'],
    'yac::__construct' => ['void', 'prefix='=>'string'],
    'yac::__get' => ['mixed', 'key'=>'string'],
    'yac::__set' => ['mixed', 'key'=>'string', 'value'=>'mixed'],
    'yac::delete' => ['bool', 'keys'=>'string|array', 'ttl='=>'int'],
    'yac::dump' => ['mixed', 'num'=>'int'],
    'yac::flush' => ['bool'],
    'yac::get' => ['mixed', 'key'=>'string|array', 'cas='=>'int'],
    'yac::info' => ['array'],
    'yaml_emit' => ['string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'],
    'yaml_emit_file' => ['bool', 'filename'=>'string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'],
    'yaml_parse' => ['mixed|false', 'input'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'],
    'yaml_parse_file' => ['mixed|false', 'filename'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'],
    'yaml_parse_url' => ['mixed|false', 'url'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'],
    'yaz_addinfo' => ['string', 'id'=>'resource'],
    'yaz_ccl_conf' => ['void', 'id'=>'resource', 'config'=>'array'],
    'yaz_ccl_parse' => ['bool', 'id'=>'resource', 'query'=>'string', '&w_result'=>'array'],
    'yaz_close' => ['bool', 'id'=>'resource'],
    'yaz_connect' => ['mixed', 'zurl'=>'string', 'options='=>'mixed'],
    'yaz_database' => ['bool', 'id'=>'resource', 'databases'=>'string'],
    'yaz_element' => ['bool', 'id'=>'resource', 'elementset'=>'string'],
    'yaz_errno' => ['int', 'id'=>'resource'],
    'yaz_error' => ['string', 'id'=>'resource'],
    'yaz_es' => ['void', 'id'=>'resource', 'type'=>'string', 'args'=>'array'],
    'yaz_es_result' => ['array', 'id'=>'resource'],
    'yaz_get_option' => ['string', 'id'=>'resource', 'name'=>'string'],
    'yaz_hits' => ['int', 'id'=>'resource', 'searchresult='=>'array'],
    'yaz_itemorder' => ['void', 'id'=>'resource', 'args'=>'array'],
    'yaz_present' => ['bool', 'id'=>'resource'],
    'yaz_range' => ['void', 'id'=>'resource', 'start'=>'int', 'number'=>'int'],
    'yaz_record' => ['string', 'id'=>'resource', 'pos'=>'int', 'type'=>'string'],
    'yaz_scan' => ['void', 'id'=>'resource', 'type'=>'string', 'startterm'=>'string', 'flags='=>'array'],
    'yaz_scan_result' => ['array', 'id'=>'resource', 'result='=>'array'],
    'yaz_schema' => ['void', 'id'=>'resource', 'schema'=>'string'],
    'yaz_search' => ['bool', 'id'=>'resource', 'type'=>'string', 'query'=>'string'],
    'yaz_set_option' => ['', 'id'=>'', 'name'=>'string', 'value'=>'string', 'options'=>'array'],
    'yaz_sort' => ['void', 'id'=>'resource', 'criteria'=>'string'],
    'yaz_syntax' => ['void', 'id'=>'resource', 'syntax'=>'string'],
    'yaz_wait' => ['mixed', '&rw_options='=>'array'],
    'yp_all' => ['void', 'domain'=>'string', 'map'=>'string', 'callback'=>'string'],
    'yp_cat' => ['array', 'domain'=>'string', 'map'=>'string'],
    'yp_err_string' => ['string', 'errorcode'=>'int'],
    'yp_errno' => ['int'],
    'yp_first' => ['array', 'domain'=>'string', 'map'=>'string'],
    'yp_get_default_domain' => ['string'],
    'yp_master' => ['string', 'domain'=>'string', 'map'=>'string'],
    'yp_match' => ['string', 'domain'=>'string', 'map'=>'string', 'key'=>'string'],
    'yp_next' => ['array', 'domain'=>'string', 'map'=>'string', 'key'=>'string'],
    'yp_order' => ['int', 'domain'=>'string', 'map'=>'string'],
    'zem_get_extension_info_by_id' => [''],
    'zem_get_extension_info_by_name' => [''],
    'zem_get_extensions_info' => [''],
    'zem_get_license_info' => [''],
    'zend_current_obfuscation_level' => ['int'],
    'zend_disk_cache_clear' => ['bool', 'namespace='=>'mixed|string'],
    'zend_disk_cache_delete' => ['mixed|null', 'key'=>'string'],
    'zend_disk_cache_fetch' => ['mixed|null', 'key'=>'string'],
    'zend_disk_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'],
    'zend_get_id' => ['array', 'all_ids='=>'all_ids|false'],
    'zend_is_configuration_changed' => [''],
    'zend_loader_current_file' => ['string'],
    'zend_loader_enabled' => ['bool'],
    'zend_loader_file_encoded' => ['bool'],
    'zend_loader_file_licensed' => ['array'],
    'zend_loader_install_license' => ['bool', 'license_file'=>'string', 'override'=>'bool'],
    'zend_logo_guid' => ['string'],
    'zend_obfuscate_class_name' => ['string', 'class_name'=>'string'],
    'zend_obfuscate_function_name' => ['string', 'function_name'=>'string'],
    'zend_optimizer_version' => ['string'],
    'zend_runtime_obfuscate' => ['void'],
    'zend_send_buffer' => ['null|false', 'buffer'=>'string', 'mime_type='=>'string', 'custom_headers='=>'string'],
    'zend_send_file' => ['null|false', 'filename'=>'string', 'mime_type='=>'string', 'custom_headers='=>'string'],
    'zend_set_configuration_changed' => [''],
    'zend_shm_cache_clear' => ['bool', 'namespace='=>'mixed|string'],
    'zend_shm_cache_delete' => ['mixed|null', 'key'=>'string'],
    'zend_shm_cache_fetch' => ['mixed|null', 'key'=>'string'],
    'zend_shm_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'],
    'zend_thread_id' => ['int'],
    'zend_version' => ['string'],
    'zip_close' => ['void', 'zip'=>'resource'],
    'zip_entry_close' => ['bool', 'zip_ent'=>'resource'],
    'zip_entry_compressedsize' => ['int', 'zip_entry'=>'resource'],
    'zip_entry_compressionmethod' => ['string', 'zip_entry'=>'resource'],
    'zip_entry_filesize' => ['int', 'zip_entry'=>'resource'],
    'zip_entry_name' => ['string', 'zip_entry'=>'resource'],
    'zip_entry_open' => ['bool', 'zip_dp'=>'resource', 'zip_entry'=>'resource', 'mode='=>'string'],
    'zip_entry_read' => ['string|false', 'zip_entry'=>'resource', 'len='=>'int'],
    'zip_open' => ['resource|int|false', 'filename'=>'string'],
    'zip_read' => ['resource', 'zip'=>'resource'],
    'zlib_decode' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
    'zlib_encode' => ['string', 'data'=>'string', 'encoding'=>'int', 'level='=>'string|int'],
    'zlib_get_coding_type' => ['string|false'],
    'zookeeper_dispatch' => ['void'],
];
<?php
namespace Psalm\Internal;

/**
 * This file holds manually defined property maps, which are not added to the
 * official PHP docs and therefore can not be automatically updated by
 * bin/update-property-map.php.
 *
 * If you change this file, please run bin/update-property-map.php to keep
 * PropertyMap.php in sync.
 */

return [
    //
    // Incorrectly documented classes from here on.
    // Revise these against the current state of the docs from time to time.
    //
    'dateinterval' => [
        // documented as 'mixed' in doc-en/reference/datetime/dateinterval.xml:90.
        'days' => 'false|int',
    ],
    'domnode' => [
        // documented as 'DomNodeList' in doc-en/reference/dom/domnode.xml:57.
        'childnodes' => 'DomNodeList<DomNode>'
    ],
    'tidy' => [
        // documented via <xi:include> in doc-en/reference/tidy/tidy.xml:33
        'errorbuffer' => 'string',
    ],
    //
    // Undocumented classes from here on.
    //
    'phpparser\\node\\expr\\array_' => [
        'items' => 'array<int, PhpParser\\Node\\Expr\\ArrayItem|null>',
    ],
    'phpparser\\node\\expr\\arrowfunction' => [
        'params' => 'list<PhpParser\\Node\\Param>',
    ],
    'phpparser\\node\\expr\\closure' => [
        'params' => 'list<PhpParser\\Node\\Param>',
    ],
    'phpparser\\node\\expr\\list_' => [
        'items' => 'array<int, PhpParser\\Node\\Expr\\ArrayItem|null>',
    ],
    'phpparser\\node\\expr\\shellexec' => [
        'parts' => 'list<PhpParser\\Node>',
    ],
    'phpparser\\node\\matcharm' => [
        'conds' => 'null|non-empty-list<PhpParser\\Node\\Expr>',
    ],
    'phpparser\\node\\name' => [
        'parts' => 'non-empty-list<non-empty-string>',
    ],
    'phpparser\\node\\stmt\\case_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\catch_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\class_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\do_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\else_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\elseif_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\finally_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\for_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\foreach_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\if_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\interface_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\namespace_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\trait_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\trycatch' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'phpparser\\node\\stmt\\while_' => [
        'stmts' => 'list<PhpParser\\Node\\Stmt>',
    ],
    'rdkafka\\message' => [
        'err' => 'int',
        'headers' => 'array<string, string>|null',
        'key' => 'string|null',
        'offset' => 'int',
        'partition' => 'int',
        'payload' => 'string',
        'timestamp' => 'int',
        'topic_name' => 'string',
    ],

    //
    // Legacy extensions that got removed.
    //
    'mongoclient' => [
        'connected' => 'boolean',
        'status' => 'string',
    ],
    'mongocollection' => [
        'db' => 'MongoDB',
        'w' => 'integer',
        'wtimeout' => 'integer',
    ],
    'mongocursor' => [
        'slaveokay' => 'boolean',
        'timeout' => 'integer',
    ],
    'mongodb' => [
        'w' => 'integer',
        'wtimeout' => 'integer',
    ],
    'mongodb-driver-exception-writeexception' => [
        'writeresult' => 'MongoDBDriverWriteResult',
    ],
    'mongoid' => [
        'id' => 'string',
    ],
    'mongoint32' => [
        'value' => 'string',
    ],
    'mongoint64' => [
        'value' => 'string',
    ],
    'tokyotyrantexception' => [
        'code' => 'int',
    ],
];
<?php // phpcs:ignoreFile

/**
 * This contains the information needed to convert the function signatures for php 8.0 to php 7.4 (and vice versa)
 *
 * This file has three sections.
 * The 'added' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that do not exist in php 7.4
 * The 'removed' section contains the signatures that were removed in php 8.0
 * The 'changed' section contains functions for which the signature has changed for php 8.0.
 *     Each function in the 'changed' section has an 'old' and a 'new' section,
 *     representing the function as it was in PHP 7.4 and in PHP 8.0, respectively
 *
 * @see CallMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
  'added' => [
    'DateTime::createFromInterface' => ['static', 'object'=>'DateTimeInterface'],
    'DateTimeImmutable::createFromInterface' => ['static', 'object'=>'DateTimeInterface'],
    'PhpToken::getTokenName' => ['?string'],
    'PhpToken::is' => ['bool', 'kind'=>'string|int|string[]|int[]'],
    'PhpToken::isIgnorable' => ['bool'],
    'PhpToken::tokenize' => ['list<PhpToken>', 'code'=>'string', 'flags='=>'int'],
    'ReflectionClass::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
    'ReflectionClassConstant::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
    'ReflectionFunctionAbstract::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
    'ReflectionParameter::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
    'ReflectionProperty::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
    'ReflectionUnionType::getTypes' => ['list<ReflectionNamedType>'],
    'fdiv' => ['float', 'num1'=>'float', 'num2'=>'float'],
    'get_debug_type' => ['string', 'value'=>'mixed'],
    'get_resource_id' => ['int', 'resource'=>'resource'],
    'imagegetinterpolation' => ['int', 'image'=>'GdImage'],
    'str_contains' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
    'str_ends_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
    'str_starts_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
  ],
  'changed' => [
    'Collator::getStrength' => [
      'old' => ['int|false'],
      'new' => ['int'],
    ],
    'DateTime::diff' => [
      'old' => ['DateInterval|false', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'],
      'new' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'],
    ],
    'DateTime::format' => [
      'old' => ['string|false', 'format'=>'string'],
      'new' => ['string', 'format'=>'string'],
    ],
    'DateTime::getTimestamp' => [
      'old' => ['int|false'],
      'new' => ['int'],
    ],
    'DateTime::setTime' => [
      'old' => ['static|false', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'],
      'new' => ['static', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'],
    ],
    'DateTimeInterface::getTimestamp' => [
       'old' => ['int|false'],
       'new' => ['int'],
    ],
    'DateTimeZone::getOffset' => [
      'old' => ['int|false', 'datetime'=>'DateTimeInterface'],
      'new' => ['int', 'datetime'=>'DateTimeInterface'],
    ],
    'DateTimeZone::listIdentifiers' => [
      'old' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'string|null'],
      'new' => ['list<string>', 'timezoneGroup='=>'int', 'countryCode='=>'string|null'],
    ],
    'Directory::close' => [
      'old' => ['void', 'dir_handle='=>'resource'],
      'new' => ['void'],
    ],
    'Directory::read' => [
      'old' => ['string|false', 'dir_handle='=>'resource'],
      'new' => ['string|false'],
    ],
    'Directory::rewind' => [
      'old' => ['void', 'dir_handle='=>'resource'],
      'new' => ['void'],
    ],
    'ErrorException::__construct' => [
      'old' => ['void', 'message='=>'string', 'code='=>'int', 'severity='=>'int', 'filename='=>'string', 'line='=>'int', 'previous='=>'?Throwable'],
      'new' => ['void', 'message='=>'string', 'code='=>'int', 'severity='=>'int', 'filename='=>'?string', 'line='=>'?int', 'previous='=>'?Throwable'],
    ],
    'IntlDateFormatter::__construct' => [
      'old' => ['void', 'locale'=>'?string', 'datetype'=>'null|int', 'timetype'=>'null|int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
      'new' => ['void', 'locale'=>'?string', 'dateType'=>'int', 'timeType'=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
    ],
    'IntlDateFormatter::create' => [
      'old' => ['?IntlDateFormatter', 'locale'=>'?string', 'datetype'=>'null|int', 'timetype'=>'null|int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
      'new' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType'=>'int', 'timeType'=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
    ],
    'IntlDateFormatter::format' => [
      'old' => ['string|false', 'value'=>'IntlCalendar|DateTimeInterface|array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int}|array{tm_sec: int, tm_min: int, tm_hour: int, tm_mday: int, tm_mon: int, tm_year: int, tm_wday: int, tm_yday: int, tm_isdst: int}|string|int|float'],
      'new' => ['string|false', 'datetime'=>'IntlCalendar|DateTimeInterface|array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int}|array{tm_sec: int, tm_min: int, tm_hour: int, tm_mday: int, tm_mon: int, tm_year: int, tm_wday: int, tm_yday: int, tm_isdst: int}|string|int|float'],
    ],
    'IntlDateFormatter::formatObject' => [
      'old' => ['string|false', 'object'=>'IntlCalendar|DateTime', 'format='=>'array{0: int, 1: int}|int|string|null', 'locale='=>'?string'],
      'new' => ['string|false', 'datetime'=>'IntlCalendar|DateTimeInterface', 'format='=>'array{0: int, 1: int}|int|string|null', 'locale='=>'?string'],
    ],
    'IntlDateFormatter::getCalendar' => [
      'old' => ['int'],
      'new' => ['int|false'],
    ],
    'IntlDateFormatter::getCalendarObject' => [
      'old' => ['IntlCalendar'],
      'new' => ['IntlCalendar|false|null'],
    ],
    'IntlDateFormatter::getDateType' => [
      'old' => ['int'],
      'new' => ['int|false'],
    ],
    'IntlDateFormatter::getLocale' => [
      'old' => ['string', 'which='=>'int'],
      'new' => ['string|false', 'type='=>'int'],
    ],
    'IntlDateFormatter::getPattern' => [
      'old' => ['string'],
      'new' => ['string|false'],
    ],
    'IntlDateFormatter::getTimeType' => [
      'old' => ['int'],
      'new' => ['int|false'],
    ],
    'IntlDateFormatter::getTimeZoneId' => [
      'old' => ['string'],
      'new' => ['string|false'],
    ],
    'IntlDateFormatter::localtime' => [
      'old' => ['array', 'value'=>'string', '&rw_position='=>'int'],
      'new' => ['array|false', 'string'=>'string', '&rw_offset='=>'int'],
    ],
    'IntlDateFormatter::parse' => [
      'old' => ['int|float', 'value'=>'string', '&rw_position='=>'int'],
      'new' => ['int|float|false', 'string'=>'string', '&rw_offset='=>'int'],
    ],
    'IntlDateFormatter::setCalendar' => [
      'old' => ['bool', 'which'=>'IntlCalendar|int|null'],
      'new' => ['bool', 'calendar'=>'IntlCalendar|int|null'],
    ],
    'IntlDateFormatter::setLenient' => [
      'old' => ['bool', 'lenient'=>'bool'],
      'new' => ['void', 'lenient'=>'bool'],
    ],
    'IntlDateFormatter::setTimeZone' => [
        'old' => ['null|false', 'zone'=>'IntlTimeZone|DateTimeZone|string|null'],
        'new' => ['null|false', 'timezone'=>'IntlTimeZone|DateTimeZone|string|null'],
    ],
    'NumberFormatter::__construct' => [
      'old' => ['void', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'],
      'new' => ['void', 'locale'=>'string', 'style'=>'int', 'pattern='=>'?string'],
    ],
    'NumberFormatter::create' => [
      'old' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'],
      'new' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'?string'],
    ],
    'PDOStatement::bindColumn' => [
      'old' => ['bool', 'column'=>'mixed', '&rw_param'=>'mixed', 'type='=>'int', 'maxlen='=>'int', 'driverdata='=>'mixed'],
      'new' => ['bool', 'column'=>'mixed', '&rw_var'=>'mixed', 'type='=>'int', 'maxLength='=>'int', 'driverOptions='=>'mixed'],
    ],
    'PDOStatement::bindParam' => [
      'old' => ['bool', 'paramno'=>'mixed', '&rw_param'=>'mixed', 'type='=>'int', 'maxlen='=>'int', 'driverdata='=>'mixed'],
      'new' => ['bool', 'param,'=>'string|int', '&rw_var'=>'mixed', 'type='=>'int', 'maxLength='=>'int', 'driverOptions='=>'mixed'],
    ],
    'PDOStatement::bindValue' => [
      'old' => ['bool', 'paramno'=>'mixed', 'param'=>'mixed', 'type='=>'int'],
      'new' => ['bool', 'param'=>'string|int', 'value'=>'mixed', 'type='=>'int'],
    ],
    'PDOStatement::debugDumpParams' => [
      'old' => ['void'],
      'new' => ['bool|null'],
    ],
    'PDOStatement::errorCode' => [
      'old' => ['string'],
      'new' => ['string|null'],
    ],
    'PDOStatement::execute' => [
      'old' => ['bool', 'bound_input_params='=>'?array'],
      'new' => ['bool', 'params='=>'?array'],
    ],
    'PDOStatement::fetch' => [
      'old' => ['mixed', 'how='=>'int', 'orientation='=>'int', 'offset='=>'int'],
      'new' => ['mixed', 'mode='=>'int', 'cursorOrientation='=>'int', 'cursorOffset='=>'int'],
    ],
    'PDOStatement::fetchAll' => [
      'old' => ['array|false', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'],
      'new' => ['array', 'mode='=>'int', '...args='=>'mixed'],
    ],
    'PDOStatement::fetchColumn' => [
      'old' => ['string|int|float|bool|null', 'column_number='=>'int'],
      'new' => ['mixed', 'column='=>'int'],
    ],
    'PDOStatement::fetchObject' => [
      'old' => ['object|false', 'class_name='=>'string', 'ctor_args='=>'array'],
      'new' => ['object|false', 'class='=>'?string', 'ctorArgs='=>'?array'],
    ],
    'PDOStatement::setFetchMode' => [
      'old' => ['bool', 'mode'=>'int'],
      'new' => ['bool', 'mode'=>'int', '...args='=>'mixed'],
    ],
    'PharData::compress' => [
      'old' => ['?PharData', 'compression'=>'int', 'extension='=>'string'],
      'new' => ['?PharData', 'compression'=>'int', 'extension='=>'?string'],
    ],
    'PharData::convertToData' => [
      'old' => ['?PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
      'new' => ['?PharData', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
    ],
    'PharData::convertToExecutable' => [
      'old' => ['?Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
      'new' => ['?Phar', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
    ],
    'PharData::decompress' => [
      'old' => ['?PharData', 'extension='=>'string'],
      'new' => ['?PharData', 'extension='=>'?string'],
    ],
    'Phar::compress' => [
      'old' => ['?Phar', 'compression'=>'int', 'extension='=>'string'],
      'new' => ['?Phar', 'compression'=>'int', 'extension='=>'?string'],
    ],
    'Phar::convertToData' => [
      'old' => ['?PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
      'new' => ['?PharData', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
    ],
    'Phar::convertToExecutable' => [
      'old' => ['?Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'],
      'new' => ['?Phar', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
    ],
    'Phar::decompress' => [
      'old' => ['?Phar', 'extension='=>'string'],
      'new' => ['?Phar', 'extension='=>'?string'],
    ],
    'Phar::getMetadata' => [
      'old' => ['mixed'],
      'new' => ['mixed', 'unserializeOptions='=>'array'],
    ],
    'PharFileInfo::getMetadata' => [
      'old' => ['mixed'],
      'new' => ['mixed', 'unserializeOptions='=>'array'],
    ],
    'RecursiveIteratorIterator::getSubIterator' => [
      'old' => ['?RecursiveIterator', 'level='=>'int'],
      'new' => ['?RecursiveIterator', 'level='=>'?int'],
    ],
    'RecursiveTreeIterator::getSubIterator' => [
      'old' => ['?RecursiveIterator', 'level='=>'int'],
      'new' => ['?RecursiveIterator', 'level='=>'?int'],
    ],
    'ReflectionClass::getConstants' => [
      'old' => ['array<string,mixed>'],
      'new' => ['array<string,mixed>', 'filter='=>'?int'],
    ],
    'ReflectionClass::getReflectionConstants' => [
      'old' => ['list<ReflectionClassConstant>'],
      'new' => ['list<ReflectionClassConstant>', 'filter='=>'?int'],
    ],
    'ReflectionClass::newInstanceArgs' => [
      'old' => ['object', 'args='=>'list<mixed>'],
      'new' => ['object', 'args='=>'list<mixed>|array<string, mixed>'],
    ],
    'ReflectionMethod::getClosure' => [
      'old' => ['?Closure', 'object='=>'object'],
      'new' => ['Closure', 'object='=>'?object'],
    ],
    'ReflectionObject::newInstanceArgs' => [
      'old' => ['object', 'args='=>'list<mixed>'],
      'new' => ['object', 'args='=>'list<mixed>|array<string, mixed>'],
    ],
    'ReflectionProperty::getValue' => [
      'old' => ['mixed', 'object='=>'object'],
      'new' => ['mixed', 'object='=>'null|object'],
    ],
    'tidy::__construct' => [
      'old' => ['void', 'filename='=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
      'new' => ['void', 'filename='=>'?string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
    ],
    'tidy::parseFile' => [
      'old' => ['bool', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
      'new' => ['bool', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
    ],
    'tidy::parseString' => [
      'old' => ['bool', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
      'new' => ['bool', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
    ],
    'tidy::repairFile' => [
      'old' => ['string', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
      'new' => ['string', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
    ],
    'tidy::repairString' => [
      'old' => ['string', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
    ],
    'XMLWriter::flush' => [
      'old' => ['string|int|false', 'empty='=>'bool'],
      'new' => ['string|int', 'empty='=>'bool'],
    ],
    'SimpleXMLElement::asXML' => [
      'old' => ['string|bool', 'filename'=>'string'],
      'new' => ['string|bool', 'filename='=>'?string'],
    ],
    'SimpleXMLElement::saveXML' => [
      'old' => ['string|bool', 'filename='=>'string'],
      'new' => ['string|bool', 'filename='=>'?string'],
    ],
    'SoapClient::__doRequest' => [
      'old' => ['?string', 'request'=>'string', 'location'=>'string', 'action'=>'string', 'version'=>'int', 'one_way='=>'int'],
      'new' => ['?string', 'request'=>'string', 'location'=>'string', 'action'=>'string', 'version'=>'int', 'one_way='=>'bool'],
    ],
    'SplFileObject::fgets' => [
      'old' => ['string|false'],
      'new' => ['string'],
    ],
    'SplFileObject::getCurrentLine' => [
      'old' => ['string|false'],
      'new' => ['string'],
    ],
    'XMLWriter::startAttributeNs' => [
      'old' => ['bool', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string'],
      'new' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
    ],
    'XMLWriter::writeAttributeNs' => [
      'old' => ['bool', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
      'new' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
    ],
    'XMLWriter::writeDtdEntity' => [
      'old' => ['bool', 'name'=>'string', 'content'=>'string', 'isParam'=>'bool', 'publicId'=>'string', 'systemId'=>'string', 'notationData'=>'string'],
      'new' => ['bool', 'name'=>'string', 'content'=>'string', 'isParam='=>'bool', 'publicId='=>'?string', 'systemId='=>'?string', 'notationData='=>'?string'],
    ],
    'ZipArchive::getStatusString' => [
      'old' => ['string|false'],
      'new' => ['string'],
    ],
    'ZipArchive::setEncryptionIndex' => [
      'old' => ['bool', 'index'=>'int', 'method'=>'string', 'password='=>'string'],
      'new' => ['bool', 'index'=>'int', 'method'=>'string', 'password='=>'?string'],
    ],
    'ZipArchive::setEncryptionName' => [
      'old' => ['bool', 'name'=>'string', 'method'=>'int', 'password='=>'string'],
      'new' => ['bool', 'name'=>'string', 'method'=>'int', 'password='=>'?string'],
    ],
    'array_column' => [
      'old' => ['array', 'array'=>'array', 'column_key'=>'mixed', 'index_key='=>'mixed'],
      'new' => ['array', 'array'=>'array', 'column_key'=>'int|string|null', 'index_key='=>'int|string|null'],
    ],
    'array_combine' => [
      'old' => ['associative-array|false', 'keys'=>'string[]|int[]', 'values'=>'array'],
      'new' => ['associative-array', 'keys'=>'string[]|int[]', 'values'=>'array'],
    ],
    'array_diff' => [
      'old' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
      'new' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
    ],
    'array_diff_assoc' => [
      'old' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
      'new' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
    ],
    'array_diff_key' => [
      'old' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
      'new' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
    ],
    'array_filter' => [
      'old' => ['associative-array', 'array'=>'array', 'callback='=>'callable(mixed,mixed=):scalar', 'mode='=>'int'],
      'new' => ['associative-array', 'array'=>'array', 'callback='=>'callable(mixed,mixed=):scalar|null', 'mode='=>'int'],
    ],
    'array_key_exists' => [
      'old' => ['bool', 'key'=>'string|int', 'array'=>'array|object'],
      'new' => ['bool', 'key'=>'string|int', 'array'=>'array'],
    ],
    'array_intersect' => [
      'old' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
      'new' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
    ],
    'array_intersect_assoc' => [
      'old' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
      'new' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
    ],
    'array_intersect_key' => [
      'old' => ['associative-array', 'array'=>'array', '...arrays'=>'array'],
      'new' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
    ],
    'array_splice' => [
      'old' => ['array', '&rw_array'=>'array', 'offset'=>'int', 'length='=>'int', 'replacement='=>'array|string'],
      'new' => ['array', '&rw_array'=>'array', 'offset'=>'int', 'length='=>'?int', 'replacement='=>'array|string'],
    ],
    'bcadd' => [
      'old' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bccomp' => [
      'old' => ['int', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
      'new' => ['int', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bcdiv' => [
      'old' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bcmod' => [
      'old' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bcmul' => [
      'old' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bcpow' => [
      'old' => ['numeric-string', 'num'=>'numeric-string', 'exponent'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string', 'num'=>'numeric-string', 'exponent'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bcpowmod' => [
      'old' => ['numeric-string|false', 'base'=>'numeric-string', 'exponent'=>'numeric-string', 'modulus'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string|false', 'base'=>'numeric-string', 'exponent'=>'numeric-string', 'modulus'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bcscale' => [
      'old' => ['int', 'scale='=>'int'],
      'new' => ['int', 'scale='=>'int|null'],
    ],
    'bcsqrt' => [
      'old' => ['numeric-string', 'num'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string', 'num'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bcsub' => [
      'old' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int'],
      'new' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
    ],
    'bind_textdomain_codeset' => [
      'old' => ['string', 'domain'=>'string', 'codeset'=>'string'],
      'new' => ['string', 'domain'=>'string', 'codeset'=>'?string'],
    ],
    'bindtextdomain' => [
      'old' => ['string', 'domain'=>'string', 'directory'=>'string'],
      'new' => ['string', 'domain'=>'string', 'directory'=>'?string'],
    ],
    'bzwrite' => [
      'old' => ['int|false', 'bz'=>'resource', 'data'=>'string', 'length='=>'int'],
      'new' => ['int|false', 'bz'=>'resource', 'data'=>'string', 'length='=>'?int'],
    ],
    'collator_get_strength' => [
      'old' => ['int|false', 'object'=>'collator'],
      'new' => ['int', 'object'=>'collator'],
    ],
    'com_load_typelib' => [
      'old' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'bool'],
      'new' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'true'],
    ],
    'count' => [
      'old' => ['int<0, max>', 'value'=>'Countable|array|SimpleXMLElement', 'mode='=>'int'],
      'new' => ['int<0, max>', 'value'=>'Countable|array', 'mode='=>'int'],
    ],
    'count_chars' => [
      'old' => ['array<int,int>|false', 'input'=>'string', 'mode='=>'0|1|2'],
      'new' => ['array<int,int>', 'input'=>'string', 'mode='=>'0|1|2'],
    ],
    'count_chars\'1' => [
      'old' => ['string|false', 'input'=>'string', 'mode='=>'3|4'],
      'new' => ['string', 'input'=>'string', 'mode='=>'3|4'],
    ],
    'curl_close' => [
      'old' => ['void', 'ch'=>'resource'],
      'new' => ['void', 'handle'=>'CurlHandle'],
    ],
    'curl_copy_handle' => [
      'old' => ['resource', 'ch'=>'resource'],
      'new' => ['CurlHandle', 'handle'=>'CurlHandle'],
    ],
    'curl_errno' => [
      'old' => ['int', 'ch'=>'resource'],
      'new' => ['int', 'handle'=>'CurlHandle'],
    ],
    'curl_error' => [
      'old' => ['string', 'ch'=>'resource'],
      'new' => ['string', 'handle'=>'CurlHandle'],
    ],
    'curl_escape' => [
      'old' => ['string|false', 'ch'=>'resource', 'string'=>'string'],
      'new' => ['string|false', 'handle'=>'CurlHandle', 'string'=>'string'],
    ],
    'curl_exec' => [
      'old' => ['bool|string', 'ch'=>'resource'],
      'new' => ['bool|string', 'handle'=>'CurlHandle'],
    ],
    'curl_file_create' => [
      'old' => ['CURLFile', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'],
      'new' => ['CURLFile', 'filename'=>'string', 'mime_type='=>'string|null', 'posted_filename='=>'string|null'],
    ],
    'curl_getinfo' => [
      'old' => ['mixed', 'ch'=>'resource', 'option='=>'int'],
      'new' => ['mixed', 'handle'=>'CurlHandle', 'option='=>'?int'],
    ],
    'curl_init' => [
      'old' => ['resource|false', 'url='=>'string'],
      'new' => ['CurlHandle|false', 'url='=>'?string'],
    ],
    'curl_multi_add_handle' => [
      'old' => ['int', 'mh'=>'resource', 'ch'=>'resource'],
      'new' => ['int', 'multi_handle'=>'CurlMultiHandle', 'handle'=>'CurlHandle'],
    ],
    'curl_multi_close' => [
      'old' => ['void', 'mh'=>'resource'],
      'new' => ['void', 'multi_handle'=>'CurlMultiHandle'],
    ],
    'curl_multi_errno' => [
      'old' => ['int|false', 'mh'=>'resource'],
      'new' => ['int', 'multi_handle'=>'CurlMultiHandle'],
    ],
    'curl_multi_exec' => [
      'old' => ['int', 'mh'=>'resource', '&w_still_running'=>'int'],
      'new' => ['int', 'multi_handle'=>'CurlMultiHandle', '&w_still_running'=>'int'],
    ],
    'curl_multi_getcontent' => [
      'old' => ['string', 'ch'=>'resource'],
      'new' => ['string', 'handle'=>'CurlHandle'],
    ],
    'curl_multi_info_read' => [
      'old' => ['array|false', 'mh'=>'resource', '&w_msgs_in_queue='=>'int'],
      'new' => ['array|false', 'multi_handle'=>'CurlMultiHandle', '&w_queued_messages='=>'int'],
    ],
    'curl_multi_init' => [
      'old' => ['resource'],
      'new' => ['CurlMultiHandle'],
    ],
    'curl_multi_remove_handle' => [
      'old' => ['int', 'mh'=>'resource', 'ch'=>'resource'],
      'new' => ['int', 'multi_handle'=>'CurlMultiHandle', 'handle'=>'CurlHandle'],
    ],
    'curl_multi_select' => [
      'old' => ['int', 'mh'=>'resource', 'timeout='=>'float'],
      'new' => ['int', 'multi_handle'=>'CurlMultiHandle', 'timeout='=>'float'],
    ],
    'curl_multi_setopt' => [
      'old' => ['bool', 'mh'=>'resource', 'option'=>'int', 'value'=>'mixed'],
      'new' => ['bool', 'multi_handle'=>'CurlMultiHandle', 'option'=>'int', 'value'=>'mixed'],
    ],
    'curl_pause' => [
      'old' => ['int', 'ch'=>'resource', 'bitmask'=>'int'],
      'new' => ['int', 'handle'=>'CurlHandle', 'flags'=>'int'],
    ],
    'curl_reset' => [
      'old' => ['void', 'ch'=>'resource'],
      'new' => ['void', 'handle'=>'CurlHandle'],
    ],
    'curl_setopt' => [
      'old' => ['bool', 'ch'=>'resource', 'option'=>'int', 'value'=>'callable|mixed'],
      'new' => ['bool', 'handle'=>'CurlHandle', 'option'=>'int', 'value'=>'callable|mixed'],
    ],
    'curl_setopt_array' => [
      'old' => ['bool', 'ch'=>'resource', 'options'=>'array'],
      'new' => ['bool', 'handle'=>'CurlHandle', 'options'=>'array'],
    ],
    'curl_share_close' => [
      'old' => ['void', 'sh'=>'resource'],
      'new' => ['void', 'share_handle'=>'CurlShareHandle'],
    ],
    'curl_share_errno' => [
      'old' => ['int|false', 'sh'=>'resource'],
      'new' => ['int', 'share_handle'=>'CurlShareHandle'],
    ],
    'curl_share_init' => [
      'old' => ['resource'],
      'new' => ['CurlShareHandle'],
    ],
    'curl_share_setopt' => [
      'old' => ['bool', 'sh'=>'resource', 'option'=>'int', 'value'=>'mixed'],
      'new' => ['bool', 'share_handle'=>'CurlShareHandle', 'option'=>'int', 'value'=>'mixed'],
    ],
    'curl_unescape' => [
      'old' => ['string|false', 'ch'=>'resource', 'string'=>'string'],
      'new' => ['string|false', 'handle'=>'CurlHandle', 'string'=>'string'],
    ],
    'date' => [
      'old' => ['string', 'format'=>'string', 'timestamp='=>'int'],
      'new' => ['string', 'format'=>'string', 'timestamp='=>'?int'],
    ],
    'date_add' => [
      'old' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'],
      'new' => ['DateTime', 'object'=>'DateTime', 'interval'=>'DateInterval'],
    ],
    'date_date_set' => [
      'old' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'month'=>'int', 'day'=>'int'],
      'new' => ['DateTime', 'object'=>'DateTime', 'year'=>'int', 'month'=>'int', 'day'=>'int'],
    ],
    'date_diff' => [
      'old' => ['DateInterval|false', 'baseObject'=>'DateTimeInterface', 'targetObject'=>'DateTimeInterface', 'absolute='=>'bool'],
      'new' => ['DateInterval', 'baseObject'=>'DateTimeInterface', 'targetObject'=>'DateTimeInterface', 'absolute='=>'bool'],
    ],
    'date_format' => [
      'old' => ['string|false', 'object'=>'DateTimeInterface', 'format'=>'string'],
      'new' => ['string', 'object'=>'DateTimeInterface', 'format'=>'string'],
    ],
    'date_offset_get' => [
      'old' => ['int|false', 'object'=>'DateTimeInterface'],
      'new' => ['int', 'object'=>'DateTimeInterface'],
    ],
    'date_parse' => [
      'old' => ['array|false', 'datetime'=>'string'],
      'new' => ['array', 'datetime'=>'string'],
    ],
    'date_sub' => [
      'old' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'],
      'new' => ['DateTime', 'object'=>'DateTime', 'interval'=>'DateInterval'],
    ],
    'date_sun_info' => [
      'old' => ['array|false', 'timestamp'=>'int', 'latitude'=>'float', 'longitude'=>'float'],
      'new' => ['array', 'timestamp'=>'int', 'latitude'=>'float', 'longitude'=>'float'],
    ],
    'date_sunrise' => [
      'old' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'utcOffset='=>'float'],
      'new' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'?float', 'longitude='=>'?float', 'zenith='=>'?float', 'utcOffset='=>'?float'],
    ],
    'date_sunset' => [
      'old' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'utcOffset='=>'float'],
      'new' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'?float', 'longitude='=>'?float', 'zenith='=>'?float', 'utcOffset='=>'?float'],
    ],
    'date_time_set' => [
      'old' => ['DateTime|false', 'object'=>'', 'hour'=>'', 'minute'=>'', 'second='=>'', 'microsecond='=>''],
      'new' => ['DateTime', 'object'=>'', 'hour'=>'', 'minute'=>'', 'second='=>'', 'microsecond='=>''],
    ],
    'date_timestamp_set' => [
      'old' => ['DateTime|false', 'object'=>'DateTime', 'timestamp'=>'int'],
      'new' => ['DateTime', 'object'=>'DateTime', 'timestamp'=>'int'],
    ],
    'date_timezone_set' => [
      'old' => ['DateTime|false', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'],
      'new' => ['DateTime', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'],
    ],
    'datefmt_create' => [
      'old' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType'=>'int', 'timeType'=>'int', 'timezone='=>'DateTimeZone|IntlTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'string'],
      'new' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType='=>'int', 'timeType='=>'int', 'timezone='=>'DateTimeZone|IntlTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
    ],
    'deflate_add' => [
      'old' => ['string|false', 'context'=>'resource', 'data'=>'string', 'flush_mode='=>'int'],
      'new' => ['string|false', 'context'=>'DeflateContext', 'data'=>'string', 'flush_mode='=>'int'],
    ],
    'deflate_init' => [
      'old' => ['resource|false', 'encoding'=>'int', 'options='=>'array'],
      'new' => ['DeflateContext|false', 'encoding'=>'int', 'options='=>'array'],
    ],
    'dom_import_simplexml' => [
      'old' => ['DOMElement|null', 'node'=>'SimpleXMLElement'],
      'new' => ['DOMElement', 'node'=>'SimpleXMLElement'],
    ],
    'easter_date' => [
      'old' => ['int', 'year='=>'int'],
      'new' => ['int', 'year='=>'?int'],
    ],
    'easter_days' => [
      'old' => ['int', 'year='=>'int', 'mode='=>'int'],
      'new' => ['int', 'year='=>'?int', 'mode='=>'int'],
    ],
    'enchant_broker_init' => [
      'old' => ['resource|false'],
      'new' => ['EnchantBroker|false'],
    ],
    'error_log' => [
      'old' => ['bool', 'message'=>'string', 'message_type='=>'int', 'destination='=>'string', 'additional_headers='=>'string'],
      'new' => ['bool', 'message'=>'string', 'message_type='=>'int', 'destination='=>'?string', 'additional_headers='=>'?string'],
    ],
    'error_reporting' => [
      'old' => ['int', 'error_level='=>'int'],
      'new' => ['int', 'error_level='=>'?int'],
    ],
    'exif_read_data' => [
      'old' => ['array|false', 'file'=>'string|resource', 'required_sections='=>'string', 'as_arrays='=>'bool', 'read_thumbnail='=>'bool'],
      'new' => ['array|false', 'file'=>'string|resource', 'required_sections='=>'?string', 'as_arrays='=>'bool', 'read_thumbnail='=>'bool'],
    ],
    'explode' => [
      'old' => ['list<string>|false', 'separator'=>'string', 'string'=>'string', 'limit='=>'int'],
      'new' => ['list<string>', 'separator'=>'string', 'string'=>'string', 'limit='=>'int'],
    ],
    'fgetcsv' => [
      'old' => ['list<string>|array{0: null}|false', 'stream'=>'resource', 'length='=>'int', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
      'new' => ['list<string>|array{0: null}|false', 'stream'=>'resource', 'length='=>'?int', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
    ],
    'fgets' => [
      'old' => ['string|false', 'stream'=>'resource', 'length='=>'int'],
      'new' => ['string|false', 'stream'=>'resource', 'length='=>'?int'],
    ],
    'file_get_contents' => [
      'old' => ['string|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'?resource', 'offset='=>'int', 'length='=>'int'],
      'new' => ['string|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'?resource', 'offset='=>'int', 'length='=>'?int'],
    ],
    'finfo_open' => [
      'old' => ['resource|false', 'flags='=>'int', 'magic_database='=>'string'],
      'new' => ['resource|false', 'flags='=>'int', 'magic_database='=>'?string'],
    ],
    'fputs' => [
      'old' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
      'new' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
    ],
    'fsockopen' => [
      'old' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'float'],
      'new' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'?float'],
    ],
    'fwrite' => [
      'old' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
      'new' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
    ],
    'get_class_methods' => [
      'old' => ['list<string>|null', 'object_or_class'=>'mixed'],
      'new' => ['list<string>', 'object_or_class'=>'object|class-string'],
    ],
    'get_headers' => [
      'old' => ['array|false', 'url'=>'string', 'associative='=>'int', 'context='=>'?resource'],
      'new' => ['array|false', 'url'=>'string', 'associative='=>'bool', 'context='=>'?resource'],
    ],
    'get_parent_class' => [
      'old' => ['class-string|false', 'object_or_class='=>'mixed'],
      'new' => ['class-string|false', 'object_or_class='=>'object|class-string'],
    ],
    'get_resources' => [
      'old' => ['array<int,resource>', 'type='=>'string'],
      'new' => ['array<int,resource>', 'type='=>'?string'],
    ],
    'getdate' => [
      'old' => ['array{seconds: int<0, 59>, minutes: int<0, 59>, hours: int<0, 23>, mday: int<1, 31>, wday: int<0, 6>, mon: int<1, 12>, year: int, yday: int<0, 365>, weekday: "Monday"|"Tuesday"|"Wednesday"|"Thursday"|"Friday"|"Saturday"|"Sunday", month: "January"|"February"|"March"|"April"|"May"|"June"|"July"|"August"|"September"|"October"|"November"|"December", 0: int}', 'timestamp='=>'int'],
      'new' => ['array{seconds: int<0, 59>, minutes: int<0, 59>, hours: int<0, 23>, mday: int<1, 31>, wday: int<0, 6>, mon: int<1, 12>, year: int, yday: int<0, 365>, weekday: "Monday"|"Tuesday"|"Wednesday"|"Thursday"|"Friday"|"Saturday"|"Sunday", month: "January"|"February"|"March"|"April"|"May"|"June"|"July"|"August"|"September"|"October"|"November"|"December", 0: int}', 'timestamp='=>'?int'],
    ],
    'gmdate' => [
      'old' => ['string', 'format'=>'string', 'timestamp='=>'int'],
      'new' => ['string', 'format'=>'string', 'timestamp='=>'int|null'],
    ],
    'gmmktime' => [
      'old' => ['int|false', 'hour='=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'],
      'new' => ['int|false', 'hour'=>'int', 'minute='=>'int|null', 'second='=>'int|null', 'month='=>'int|null', 'day='=>'int|null', 'year='=>'int|null'],
    ],
    'gmp_binomial' => [
      'old' => ['GMP|false', 'n'=>'GMP|string|int', 'k'=>'int'],
      'new' => ['GMP', 'n'=>'GMP|string|int', 'k'=>'int'],
    ],
    'gmp_export' => [
      'old' => ['string|false', 'num'=>'GMP|string|int', 'word_size='=>'int', 'flags='=>'int'],
      'new' => ['string', 'num'=>'GMP|string|int', 'word_size='=>'int', 'flags='=>'int'],
    ],
    'gmp_import' => [
      'old' => ['GMP|false', 'data'=>'string', 'word_size='=>'int', 'flags='=>'int'],
      'new' => ['GMP', 'data'=>'string', 'word_size='=>'int', 'flags='=>'int'],
    ],
    'gmstrftime' => [
      'old' => ['string|false', 'format'=>'string', 'timestamp='=>'int'],
      'new' => ['string|false', 'format'=>'string', 'timestamp='=>'?int'],
    ],
    'gzgets' => [
      'old' => ['string|false', 'stream'=>'resource', 'length='=>'int'],
      'new' => ['string|false', 'stream'=>'resource', 'length='=>'?int'],
    ],
    'gzputs' => [
      'old' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
      'new' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
    ],
    'gzwrite' => [
      'old' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'int'],
      'new' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
    ],
    'hash' => [
      'old' => ['string|false', 'algo'=>'string', 'data'=>'string', 'binary='=>'bool'],
      'new' => ['non-empty-string', 'algo'=>'string', 'data'=>'string', 'binary='=>'bool'],
    ],
    'hash_hmac' => [
      'old' => ['non-empty-string|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'binary='=>'bool'],
      'new' => ['non-empty-string', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'binary='=>'bool'],
    ],
    'hash_init' => [
      'old' => ['HashContext|false', 'algo'=>'string', 'flags='=>'int', 'key='=>'string'],
      'new' => ['HashContext', 'algo'=>'string', 'flags='=>'int', 'key='=>'string'],
    ],
    'hash_hkdf' => [
      'old' => ['non-empty-string|false', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'],
      'new' => ['non-empty-string', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'],
    ],
    'hash_update_file' => [
      'old' => ['bool', 'context'=>'HashContext', 'filename'=>'string', 'stream_context='=>'resource'],
      'new' => ['bool', 'context'=>'HashContext', 'filename'=>'string', 'stream_context='=>'?resource'],
    ],
    'header_remove' => [
      'old' => ['void', 'name='=>'string'],
      'new' => ['void', 'name='=>'?string'],
    ],
    'html_entity_decode' => [
      'old' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'?string'],
    ],
    'htmlentities' => [
      'old' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'string', 'double_encode='=>'bool'],
      'new' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'?string', 'double_encode='=>'bool'],
    ],
    'iconv_mime_decode' => [
      'old' => ['string|false', 'string'=>'string', 'mode='=>'int', 'encoding='=>'string'],
      'new' => ['string|false', 'string'=>'string', 'mode='=>'int', 'encoding='=>'?string'],
    ],
    'iconv_mime_decode_headers' => [
      'old' => ['array|false', 'headers'=>'string', 'mode='=>'int', 'encoding='=>'string'],
      'new' => ['array|false', 'headers'=>'string', 'mode='=>'int', 'encoding='=>'?string'],
    ],
    'iconv_strlen' => [
      'old' => ['0|positive-int|false', 'string'=>'string', 'encoding='=>'string'],
      'new' => ['0|positive-int|false', 'string'=>'string', 'encoding='=>'?string'],
    ],
    'iconv_strpos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'?string'],
    ],
    'iconv_strrpos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'?string'],
    ],
    'iconv_substr' => [
      'old' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'int', 'encoding='=>'string'],
      'new' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'?int', 'encoding='=>'?string'],
    ],
    'idate' => [
      'old' => ['int', 'format'=>'string', 'timestamp='=>'int'],
      'new' => ['int', 'format'=>'string', 'timestamp='=>'?int'],
    ],
    'ignore_user_abort' => [
      'old' => ['int', 'enable='=>'bool'],
      'new' => ['int', 'enable='=>'?bool'],
    ],
    'imageaffine' => [
      'old' => ['resource|false', 'src'=>'resource', 'affine'=>'array', 'clip='=>'array'],
      'new' => ['false|GdImage', 'image'=>'GdImage', 'affine'=>'array', 'clip='=>'?array'],
    ],
    'imagealphablending' => [
      'old' => ['bool', 'image'=>'resource', 'enable'=>'bool'],
      'new' => ['bool', 'image'=>'GdImage', 'enable'=>'bool'],
    ],
    'imageantialias' => [
      'old' => ['bool', 'image'=>'resource', 'enable'=>'bool'],
      'new' => ['bool', 'image'=>'GdImage', 'enable'=>'bool'],
    ],
    'imagearc' => [
      'old' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int'],
    ],
    'imagebmp' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'resource|string|null', 'compressed='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'resource|string|null', 'compressed='=>'bool'],
    ],
    'imagechar' => [
      'old' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
    ],
    'imagecharup' => [
      'old' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
    ],
    'imagecolorallocate' => [
      'old' => ['int|false', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
      'new' => ['int|false', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    ],
    'imagecolorallocatealpha' => [
      'old' => ['int|false', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
      'new' => ['int|false', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    ],
    'imagecolorat' => [
      'old' => ['int|false', 'image'=>'resource', 'x'=>'int', 'y'=>'int'],
      'new' => ['int|false', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int'],
    ],
    'imagecolorclosest' => [
      'old' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    ],
    'imagecolorclosestalpha' => [
      'old' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    ],
    'imagecolorclosesthwb' => [
      'old' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    ],
    'imagecolordeallocate' => [
      'old' => ['bool', 'image'=>'resource', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'color'=>'int'],
    ],
    'imagecolorexact' => [
      'old' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    ],
    'imagecolorexactalpha' => [
      'old' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    ],
    'imagecolormatch' => [
      'old' => ['bool', 'image1'=>'resource', 'image2'=>'resource'],
      'new' => ['bool', 'image1'=>'GdImage', 'image2'=>'GdImage'],
    ],
    'imagecolorresolve' => [
      'old' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
    ],
    'imagecolorresolvealpha' => [
      'old' => ['int', 'image'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
    ],
    'imagecolorset' => [
      'old' => ['false|null', 'image'=>'resource', 'color'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'],
      'new' => ['false|null', 'image'=>'GdImage', 'color'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'],
    ],
    'imagecolorsforindex' => [
      'old' => ['array', 'image'=>'resource', 'color'=>'int'],
      'new' => ['array', 'image'=>'GdImage', 'color'=>'int'],
    ],
    'imagecolorstotal' => [
      'old' => ['int', 'image'=>'resource'],
      'new' => ['int', 'image'=>'GdImage'],
    ],
    'imagecolortransparent' => [
      'old' => ['int', 'image'=>'resource', 'color='=>'int'],
      'new' => ['int', 'image'=>'GdImage', 'color='=>'?int'],
    ],
    'imageconvolution' => [
      'old' => ['bool', 'image'=>'resource', 'matrix'=>'array', 'divisor'=>'float', 'offset'=>'float'],
      'new' => ['bool', 'image'=>'GdImage', 'matrix'=>'array', 'divisor'=>'float', 'offset'=>'float'],
    ],
    'imagecopy' => [
      'old' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
      'new' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
    ],
    'imagecopymerge' => [
      'old' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
      'new' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
    ],
    'imagecopymergegray' => [
      'old' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
      'new' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
    ],
    'imagecopyresampled' => [
      'old' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
      'new' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
    ],
    'imagecopyresized' => [
      'old' => ['bool', 'dst_image'=>'resource', 'src_image'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
      'new' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
    ],
    'imagecreate' => [
      'old' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'],
      'new' => ['false|GdImage', 'width'=>'int', 'height'=>'int'],
    ],
    'imagecreatefrombmp' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromgd' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromgd2' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromgd2part' => [
      'old' => ['resource|false', 'filename'=>'string', 'srcx'=>'int', 'srcy'=>'int', 'width'=>'int', 'height'=>'int'],
      'new' => ['false|GdImage', 'filename'=>'string', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int'],
    ],
    'imagecreatefromgif' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromjpeg' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefrompng' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromstring' => [
      'old' => ['resource|false', 'image'=>'string'],
      'new' => ['false|GdImage', 'data'=>'string'],
    ],
    'imagecreatefromwbmp' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromwebp' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromxbm' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatefromxpm' => [
      'old' => ['resource|false', 'filename'=>'string'],
      'new' => ['false|GdImage', 'filename'=>'string'],
    ],
    'imagecreatetruecolor' => [
      'old' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'],
      'new' => ['false|GdImage', 'width'=>'int', 'height'=>'int'],
    ],
    'imagecrop' => [
      'old' => ['resource|false', 'im'=>'resource', 'rect'=>'array'],
      'new' => ['false|GdImage', 'image'=>'GdImage', 'rectangle'=>'array'],
    ],
    'imagecropauto' => [
      'old' => ['resource|false', 'im'=>'resource', 'mode='=>'int', 'threshold='=>'float', 'color='=>'int'],
      'new' => ['false|GdImage', 'image'=>'GdImage', 'mode='=>'int', 'threshold='=>'float', 'color='=>'int'],
    ],
    'imagedashedline' => [
      'old' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    ],
    'imagedestroy' => [
      'old' => ['bool', 'image'=>'resource'],
      'new' => ['bool', 'image'=>'GdImage'],
    ],
    'imageellipse' => [
      'old' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
    ],
    'imagefill' => [
      'old' => ['bool', 'image'=>'resource', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
    ],
    'imagefilledarc' => [
      'old' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int', 'style'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int', 'style'=>'int'],
    ],
    'imagefilledellipse' => [
      'old' => ['bool', 'image'=>'resource', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
    ],
    'imagefilledpolygon' => [
      'old' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
    ],
    'imagefilledrectangle' => [
      'old' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    ],
    'imagefilltoborder' => [
      'old' => ['bool', 'image'=>'resource', 'x'=>'int', 'y'=>'int', 'border_color'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int', 'border_color'=>'int', 'color'=>'int'],
    ],
    'imagefilter' => [
      'old' => ['bool', 'image'=>'resource', 'filter'=>'int', 'args='=>'int', 'arg2='=>'int', 'arg3='=>'int', 'arg4='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'filter'=>'int', 'args='=>'int', 'arg2='=>'int', 'arg3='=>'int', 'arg4='=>'int'],
    ],
    'imageflip' => [
      'old' => ['bool', 'image'=>'resource', 'mode'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'mode'=>'int'],
    ],
    'imagefttext' => [
      'old' => ['array|false', 'image'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string', 'options='=>'array'],
      'new' => ['array|false', 'image'=>'GdImage', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string', 'options='=>'array'],
    ],
    'imagegammacorrect' => [
      'old' => ['bool', 'image'=>'resource', 'input_gamma'=>'float', 'output_gamma'=>'float'],
      'new' => ['bool', 'image'=>'GdImage', 'input_gamma'=>'float', 'output_gamma'=>'float'],
    ],
    'imagegd' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null'],
    ],
    'imagegd2' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'chunk_size='=>'int', 'mode='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'chunk_size='=>'int', 'mode='=>'int'],
    ],
    'imagegetclip' => [
      'old' => ['array<int,int>|false', 'im'=>'resource'],
      'new' => ['array<int,int>', 'image'=>'GdImage'],
    ],
    'imagegif' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null'],
    ],
    'imagegrabscreen' => [
      'old' => ['false|resource'],
      'new' => ['false|GdImage'],
    ],
    'imagegrabwindow' => [
      'old' => ['false|resource', 'window_handle'=>'int', 'client_area='=>'int'],
      'new' => ['false|GdImage', 'handle'=>'int', 'client_area='=>'int'],
    ],
    'imageinterlace' => [
      'old' => ['int|false', 'image'=>'resource', 'enable='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'enable='=>'bool|null'],
    ],
    'imageistruecolor' => [
      'old' => ['bool', 'image'=>'resource'],
      'new' => ['bool', 'image'=>'GdImage'],
    ],
    'imagejpeg' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'quality='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'quality='=>'int'],
    ],
    'imagelayereffect' => [
      'old' => ['bool', 'image'=>'resource', 'effect'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'effect'=>'int'],
    ],
    'imageline' => [
      'old' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    ],
    'imageopenpolygon' => [
      'old' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'points'=>'array', 'num_points'=>'int', 'color'=>'int'],
    ],
    'imagepalettecopy' => [
      'old' => ['void', 'dst'=>'resource', 'src'=>'resource'],
      'new' => ['void', 'dst'=>'GdImage', 'src'=>'GdImage'],
    ],
    'imagepalettetotruecolor' => [
      'old' => ['bool', 'image'=>'resource'],
      'new' => ['bool', 'image'=>'GdImage'],
    ],
    'imagepng' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'quality='=>'int', 'filters='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'quality='=>'int', 'filters='=>'int'],
    ],
    'imagepolygon' => [
      'old' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
    ],
    'imagerectangle' => [
      'old' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
    ],
    'imageresolution' => [
      'old' => ['array|bool', 'image'=>'resource', 'resolution_x='=>'int', 'resolution_y='=>'int'],
      'new' => ['array|bool', 'image'=>'GdImage', 'resolution_x='=>'?int', 'resolution_y='=>'?int'],
    ],
    'imagerotate' => [
      'old' => ['resource|false', 'src_im'=>'resource', 'angle'=>'float', 'bgdcolor'=>'int', 'ignoretransparent='=>'int'],
      'new' => ['false|GdImage', 'image'=>'GdImage', 'angle'=>'float', 'background_color'=>'int', 'ignore_transparent='=>'int'],
    ],
    'imagesavealpha' => [
      'old' => ['bool', 'image'=>'resource', 'enable'=>'bool'],
      'new' => ['bool', 'image'=>'GdImage', 'enable'=>'bool'],
    ],
    'imagescale' => [
      'old' => ['resource|false', 'im'=>'resource', 'new_width'=>'int', 'new_height='=>'int', 'method='=>'int'],
      'new' => ['false|GdImage', 'image'=>'GdImage', 'width'=>'int', 'height='=>'int', 'mode='=>'int'],
    ],
    'imagesetbrush' => [
      'old' => ['bool', 'image'=>'resource', 'brush'=>'resource'],
      'new' => ['bool', 'image'=>'GdImage', 'brush'=>'GdImage'],
    ],
    'imagesetclip' => [
      'old' => ['bool', 'image'=>'resource', 'x1'=>'int', 'x2'=>'int', 'y1'=>'int', 'y2'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'x2'=>'int', 'y1'=>'int', 'y2'=>'int'],
    ],
    'imagesetinterpolation' => [
      'old' => ['bool', 'image'=>'resource', 'method'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'method'=>'int'],
    ],
    'imagesetpixel' => [
      'old' => ['bool', 'image'=>'resource', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
    ],
    'imagesetstyle' => [
      'old' => ['bool', 'image'=>'resource', 'style'=>'non-empty-array'],
      'new' => ['bool', 'image'=>'GdImage', 'style'=>'non-empty-array'],
    ],
    'imagesetthickness' => [
      'old' => ['bool', 'image'=>'resource', 'thickness'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'thickness'=>'int'],
    ],
    'imagesettile' => [
      'old' => ['bool', 'image'=>'resource', 'tile'=>'resource'],
      'new' => ['bool', 'image'=>'GdImage', 'tile'=>'GdImage'],
    ],
    'imagestring' => [
      'old' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
    ],
    'imagestringup' => [
      'old' => ['bool', 'image'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
    ],
    'imagesx' => [
      'old' => ['int', 'image'=>'resource'],
      'new' => ['int', 'image'=>'GdImage'],
    ],
    'imagesy' => [
      'old' => ['int', 'image'=>'resource'],
      'new' => ['int', 'image'=>'GdImage'],
    ],
    'imagetruecolortopalette' => [
      'old' => ['bool', 'image'=>'resource', 'dither'=>'bool', 'num_colors'=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'dither'=>'bool', 'num_colors'=>'int'],
    ],
    'imagettftext' => [
      'old' => ['false|array', 'image'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string'],
      'new' => ['false|array', 'image'=>'GdImage', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string'],
    ],
    'imagewbmp' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'foreground_color='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'foreground_color='=>'?int'],
    ],
    'imagewebp' => [
      'old' => ['bool', 'image'=>'resource', 'file='=>'string|resource|null', 'quality='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'quality='=>'int'],
    ],
    'imagexbm' => [
      'old' => ['bool', 'image'=>'resource', 'filename='=>'?string', 'foreground_color='=>'int'],
      'new' => ['bool', 'image'=>'GdImage', 'filename='=>'?string', 'foreground_color='=>'int'],
    ],
    'imap_append' => [
      'old' => ['bool', 'imap'=>'resource', 'folder'=>'string', 'message'=>'string', 'options='=>'string', 'internal_date='=>'string'],
      'new' => ['bool', 'imap'=>'resource', 'folder'=>'string', 'message'=>'string', 'options='=>'?string', 'internal_date='=>'?string'],
    ],
    'imap_headerinfo' => [
      'old' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string|null'],
      'new' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'from_length='=>'int', 'subject_length='=>'int'],
    ],
    'imap_mail' => [
      'old' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string', 'cc='=>'string', 'bcc='=>'string', 'return_path='=>'string'],
      'new' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'?string', 'cc='=>'?string', 'bcc='=>'?string', 'return_path='=>'?string'],
    ],
    'inflate_init' => [
      'old' => ['resource|false', 'encoding'=>'int', 'options='=>'array'],
      'new' => ['InflateContext|false', 'encoding'=>'int', 'options='=>'array'],
    ],
    'jdtounix' => [
      'old' => ['int|false', 'julian_day'=>'int'],
      'new' => ['int', 'julian_day'=>'int'],
    ],
    'ldap_add' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
      'new' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_add_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
      'new' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_bind_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn='=>'string|null', 'password='=>'string|null', 'controls='=>'array'],
      'new' => ['resource|false', 'ldap'=>'resource', 'dn='=>'string|null', 'password='=>'string|null', 'controls='=>'?array'],
    ],
    'ldap_delete_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'controls='=>'array'],
      'new' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'controls='=>'?array'],
    ],
    'ldap_exop_passwd' => [
      'old' => ['bool|string', 'ldap'=>'resource', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string', '&w_controls='=>'array'],
      'new' => ['bool|string', 'ldap'=>'resource', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string', '&w_controls='=>'array|null'],
    ],
    'ldap_rename_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'array'],
      'new' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'?array'],
    ],
    'ldap_mod_add_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
      'new' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_mod_del_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
      'new' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_mod_replace_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'array'],
      'new' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_set_rebind_proc' => [
      'old' => ['bool', 'ldap'=>'resource', 'callback'=>'callable'],
      'new' => ['bool', 'ldap'=>'resource', 'callback'=>'?callable'],
    ],
    'ldap_sasl_bind' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn='=>'string', 'password='=>'string', 'mech='=>'string', 'realm='=>'string', 'authc_id='=>'string', 'authz_id='=>'string', 'props='=>'string'],
      'new' => ['bool', 'ldap'=>'resource', 'dn='=>'?string', 'password='=>'?string', 'mech='=>'?string', 'realm='=>'?string', 'authc_id='=>'?string', 'authz_id='=>'?string', 'props='=>'?string'],
    ],
    'libxml_use_internal_errors' => [
      'old' => ['bool', 'use_errors='=>'bool'],
      'new' => ['bool', 'use_errors='=>'?bool'],
    ],
    'locale_get_display_language' => [
      'old' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
      'new' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
    ],
    'locale_get_display_name' => [
      'old' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
      'new' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
    ],
    'locale_get_display_region' => [
      'old' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
      'new' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
    ],
    'locale_get_display_script' => [
      'old' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
      'new' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
    ],
    'locale_get_display_variant' => [
      'old' => ['string', 'locale'=>'string', 'displayLocale='=>'string'],
      'new' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
    ],
    'localtime' => [
      'old' => ['array', 'timestamp='=>'int', 'associative='=>'bool'],
      'new' => ['array', 'timestamp='=>'?int', 'associative='=>'bool'],
    ],
    'mb_check_encoding' => [
      'old' => ['bool', 'value='=>'array|string', 'encoding='=>'string'],
      'new' => ['bool', 'value='=>'array|string|null', 'encoding='=>'string|null'],
    ],
    'mb_chr' => [
      'old' => ['non-empty-string|false', 'codepoint'=>'int', 'encoding='=>'string'],
      'new' => ['non-empty-string|false', 'codepoint'=>'int', 'encoding='=>'string|null'],
    ],
    'mb_convert_case' => [
      'old' => ['string', 'string'=>'string', 'mode'=>'int', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'mode'=>'int', 'encoding='=>'string|null'],
    ],
    'mb_convert_encoding' => [
      'old' => ['string|false', 'string'=>'string', 'to_encoding'=>'string', 'from_encoding='=>'mixed'],
      'new' => ['string|false', 'string'=>'string', 'to_encoding'=>'string', 'from_encoding='=>'array|string|null'],
    ],
    'mb_convert_encoding\'1' => [
      'old' => ['array', 'string'=>'array', 'to_encoding'=>'string', 'from_encoding='=>'mixed'],
      'new' => ['array', 'string'=>'array', 'to_encoding'=>'string', 'from_encoding='=>'array|string|null'],
    ],
    'mb_convert_kana' => [
      'old' => ['string', 'string'=>'string', 'mode='=>'string', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'mode='=>'string', 'encoding='=>'string|null'],
    ],
    'mb_decode_numericentity' => [
      'old' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string|null'],
    ],
    'mb_detect_encoding' => [
      'old' => ['string|false', 'string'=>'string', 'encodings='=>'mixed', 'strict='=>'bool'],
      'new' => ['string|false', 'string'=>'string', 'encodings='=>'array|string|null', 'strict='=>'bool'],
    ],
    'mb_detect_order' => [
      'old' => ['bool|list<string>', 'encoding='=>'mixed'],
      'new' => ['bool|list<string>', 'encoding='=>'array|string|null'],
    ],
    'mb_encode_mimeheader' => [
      'old' => ['string', 'string'=>'string', 'charset='=>'string', 'transfer_encoding='=>'string', 'newline='=>'string', 'indent='=>'int'],
      'new' => ['string', 'string'=>'string', 'charset='=>'string|null', 'transfer_encoding='=>'string|null', 'newline='=>'string', 'indent='=>'int'],
    ],
    'mb_encode_numericentity' => [
      'old' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string', 'hex='=>'bool'],
      'new' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string|null', 'hex='=>'bool'],
    ],
    'mb_encoding_aliases' => [
      'old' => ['list<string>|false', 'encoding'=>'string'],
      'new' => ['list<string>', 'encoding'=>'string'],
    ],
    'mb_ereg' => [
      'old' => ['int|false', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array|null'],
      'new' => ['bool', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array|null'],
    ],
    'mb_ereg_match' => [
      'old' => ['bool', 'pattern'=>'string', 'string'=>'string', 'options='=>'string'],
      'new' => ['bool', 'pattern'=>'string', 'string'=>'string', 'options='=>'string|null'],
    ],
    'mb_ereg_replace' => [
      'old' => ['string|false', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string'],
      'new' => ['string|false|null', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string|null'],
    ],
    'mb_ereg_replace_callback' => [
      'old' => ['string|false|null', 'pattern'=>'string', 'callback'=>'callable', 'string'=>'string', 'options='=>'string'],
      'new' => ['string|false|null', 'pattern'=>'string', 'callback'=>'callable', 'string'=>'string', 'options='=>'string|null'],
    ],
    'mb_ereg_search' => [
      'old' => ['bool', 'pattern='=>'string', 'options='=>'string'],
      'new' => ['bool', 'pattern='=>'string|null', 'options='=>'string|null'],
    ],
    'mb_ereg_search_init' => [
      'old' => ['bool', 'string'=>'string', 'pattern='=>'string', 'options='=>'string'],
      'new' => ['bool', 'string'=>'string', 'pattern='=>'string|null', 'options='=>'string|null'],
    ],
    'mb_ereg_search_pos' => [
      'old' => ['int[]|false', 'pattern='=>'string', 'options='=>'string'],
      'new' => ['int[]|false', 'pattern='=>'string|null', 'options='=>'string|null'],
    ],
    'mb_ereg_search_regs' => [
      'old' => ['string[]|false', 'pattern='=>'string', 'options='=>'string'],
      'new' => ['string[]|false', 'pattern='=>'string|null', 'options='=>'string|null'],
    ],
    'mb_eregi' => [
      'old' => ['int|false', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array'],
      'new' => ['bool', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array|null'],
    ],
    'mb_eregi_replace' => [
      'old' => ['string|false', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string'],
      'new' => ['string|false|null', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string|null'],
    ],
    'mb_http_input' => [
      'old' => ['string|false', 'type='=>'string'],
      'new' => ['array|string|false', 'type='=>'string|null'],
    ],
    'mb_http_output' => [
      'old' => ['string|bool', 'encoding='=>'string'],
      'new' => ['string|bool', 'encoding='=>'string|null'],
    ],
    'mb_internal_encoding' => [
      'old' => ['string|bool', 'encoding='=>'string'],
      'new' => ['string|bool', 'encoding='=>'string|null'],
    ],
    'mb_language' => [
      'old' => ['string|bool', 'language='=>'string'],
      'new' => ['string|bool', 'language='=>'string|null'],
    ],
    'mb_ord' => [
      'old' => ['int|false', 'string'=>'string', 'encoding='=>'string'],
      'new' => ['int|false', 'string'=>'string', 'encoding='=>'string|null'],
    ],
    'mb_parse_str' => [
      'old' => ['bool', 'string'=>'string', '&w_result='=>'array'],
      'new' => ['bool', 'string'=>'string', '&w_result'=>'array'],
    ],
    'mb_regex_encoding' => [
      'old' => ['string|bool', 'encoding='=>'string'],
      'new' => ['string|bool', 'encoding='=>'string|null'],
    ],
    'mb_regex_set_options' => [
      'old' => ['string', 'options='=>'string'],
      'new' => ['string', 'options='=>'string|null'],
    ],
    'mb_scrub' => [
      'old' => ['string', 'string'=>'string', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'encoding='=>'string|null'],
    ],
    'mb_send_mail' => [
      'old' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array', 'additional_params='=>'string'],
      'new' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array', 'additional_params='=>'string|null'],
    ],
    'mb_str_split' => [
      'old' => ['list<string>|false', 'string'=>'string', 'length='=>'positive-int', 'encoding='=>'string'],
      'new' => ['list<string>', 'string'=>'string', 'length='=>'positive-int', 'encoding='=>'string|null'],
    ],
    'mb_strcut' => [
      'old' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string|null'],
    ],
    'mb_strimwidth' => [
      'old' => ['string', 'string'=>'string', 'start'=>'int', 'width'=>'int', 'trim_marker='=>'string', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'start'=>'int', 'width'=>'int', 'trim_marker='=>'string', 'encoding='=>'string|null'],
    ],
    'mb_stripos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
    ],
    'mb_stristr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
    ],
    'mb_strlen' => [
      'old' => ['0|positive-int', 'string'=>'string', 'encoding='=>'string'],
      'new' => ['0|positive-int', 'string'=>'string', 'encoding='=>'string|null'],
    ],
    'mb_strpos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
    ],
    'mb_strrchr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
    ],
    'mb_strrichr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
    ],
    'mb_strripos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
    ],
    'mb_strrpos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
    ],
    'mb_strstr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
    ],
    'mb_strtolower' => [
      'old' => ['lowercase-string', 'string'=>'string', 'encoding='=>'string'],
      'new' => ['lowercase-string', 'string'=>'string', 'encoding='=>'string|null'],
    ],
    'mb_strtoupper' => [
      'old' => ['string', 'string'=>'string', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'encoding='=>'string|null'],
    ],
    'mb_strwidth' => [
      'old' => ['int', 'string'=>'string', 'encoding='=>'string'],
      'new' => ['int', 'string'=>'string', 'encoding='=>'string|null'],
    ],
    'mb_substitute_character' => [
      'old' => ['bool|int|string', 'substitute_character='=>'mixed'],
      'new' => ['bool|int|string', 'substitute_character='=>'int|string|null'],
    ],
    'mb_substr' => [
      'old' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string|null'],
    ],
    'mb_substr_count' => [
      'old' => ['int', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string'],
      'new' => ['int', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string|null'],
    ],
    'metaphone' => [
      'old' => ['string|false', 'string'=>'string', 'max_phonemes='=>'int'],
      'new' => ['string', 'string'=>'string', 'max_phonemes='=>'int'],
    ],
    'mhash' => [
      'old' => ['string', 'algo'=>'int', 'data'=>'string', 'key='=>'string'],
      'new' => ['string', 'algo'=>'int', 'data'=>'string', 'key='=>'?string'],
    ],
    'mktime' => [
      'old' => ['int|false', 'hour='=>'int', 'minute='=>'int', 'second='=>'int', 'month='=>'int', 'day='=>'int', 'year='=>'int'],
      'new' => ['int|false', 'hour'=>'int', 'minute='=>'int|null', 'second='=>'int|null', 'month='=>'int|null', 'day='=>'int|null', 'year='=>'int|null'],
    ],
    'msg_get_queue' => [
      'old' => ['resource|false', 'key'=>'int', 'permissions='=>'int'],
      'new' => ['SysvMessageQueue|false', 'key'=>'int', 'permissions='=>'int'],
    ],
    'mysqli::__construct' => [
      'old' => ['void', 'hostname='=>'string', 'username='=>'string', 'password='=>'string', 'database='=>'string', 'port='=>'int', 'socket='=>'string'],
      'new' => ['void', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
    ],
    'mysqli::begin_transaction' => [
      'old' => ['bool', 'flags='=>'int', 'name='=>'string'],
      'new' => ['bool', 'flags='=>'int', 'name='=>'?string'],
    ],
    'mysqli::commit' => [
      'old' => ['bool', 'flags='=>'int', 'name='=>'string'],
      'new' => ['bool', 'flags='=>'int', 'name='=>'?string'],
    ],
    'mysqli::connect' => [
      'old' => ['null|false', 'hostname='=>'string', 'username='=>'string', 'password='=>'string', 'database='=>'string', 'port='=>'int', 'socket='=>'string'],
      'new' => ['null|false', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
    ],
    'mysqli::rollback' => [
      'old' => ['bool', 'flags='=>'int', 'name='=>'string'],
      'new' => ['bool', 'flags='=>'int', 'name='=>'?string'],
    ],
    'mysqli_begin_transaction' => [
      'old' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'string'],
      'new' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'?string'],
    ],
    'mysqli_commit' => [
      'old' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'string'],
      'new' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'?string'],
    ],
    'mysqli_connect' => [
      'old' => ['mysqli|false', 'hostname='=>'string', 'username='=>'string', 'password='=>'string', 'database='=>'string', 'port='=>'int', 'socket='=>'string'],
      'new' => ['mysqli|false', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
    ],
    'mysqli_rollback' => [
      'old' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'string'],
      'new' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'?string'],
    ],
    'number_format' => [
      'old' => ['string', 'num'=>'float|int', 'decimals='=>'int'],
      'new' => ['string', 'num'=>'float|int', 'decimals='=>'int', 'decimal_separator='=>'?string', 'thousands_separator='=>'?string'],
    ],
    'numfmt_create' => [
      'old' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'],
      'new' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'?string'],
    ],
    'ob_implicit_flush' => [
      'old' => ['void', 'enable='=>'int'],
      'new' => ['void', 'enable='=>'bool'],
    ],
    'odbc_exec' => [
      'old' => ['resource', 'odbc'=>'resource', 'query'=>'string', 'flags='=>'int'],
      'new' => ['resource', 'odbc'=>'resource', 'query'=>'string'],
    ],
    'odbc_fetch_row' => [
      'old' => ['bool', 'statement'=>'resource', 'row='=>'int'],
      'new' => ['bool', 'statement'=>'resource', 'row='=>'?int'],
    ],
    'odbc_do' => [
      'old' => ['resource', 'odbc'=>'resource', 'query'=>'string', 'flags='=>'int'],
      'new' => ['resource', 'odbc'=>'resource', 'query'=>'string'],
    ],
    'odbc_tables' => [
      'old' => ['resource|false', 'odbc'=>'resource', 'catalog='=>'?string', 'schema='=>'string', 'table='=>'string', 'types='=>'string'],
      'new' => ['resource|false', 'odbc'=>'resource', 'catalog='=>'?string', 'schema='=>'?string', 'table='=>'?string', 'types='=>'?string'],
    ],
    'openssl_csr_export' => [
      'old' => ['bool', 'csr'=>'string|resource', '&w_output'=>'string', 'no_text='=>'bool'],
      'new' => ['bool', 'csr'=>'OpenSSLCertificateSigningRequest|string', '&w_output'=>'string', 'no_text='=>'bool'],
    ],
    'openssl_csr_export_to_file' => [
      'old' => ['bool', 'csr'=>'string|resource', 'output_filename'=>'string', 'no_text='=>'bool'],
      'new' => ['bool', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'output_filename'=>'string', 'no_text='=>'bool'],
    ],
    'openssl_csr_get_public_key' => [
      'old' => ['resource|false', 'csr'=>'string|resource', 'short_names='=>'bool'],
      'new' => ['OpenSSLAsymmetricKey|false', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'short_names='=>'bool'],
    ],
    'openssl_csr_get_subject' => [
      'old' => ['array|false', 'csr'=>'string|resource', 'short_names='=>'bool'],
      'new' => ['array|false', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'short_names='=>'bool'],
    ],
    'openssl_csr_new' => [
      'old' => ['resource|false', 'distinguished_names'=>'array', '&w_private_key'=>'resource', 'options='=>'array', 'extra_attributes='=>'array'],
      'new' => ['OpenSSLCertificateSigningRequest|false', 'distinguished_names'=>'array', '&w_private_key'=>'OpenSSLAsymmetricKey', 'options='=>'array|null', 'extra_attributes='=>'array|null'],
    ],
    'openssl_csr_sign' => [
        'old' =>  ['resource|false', 'csr'=>'string|resource', 'ca_certificate'=>'string|resource|null', 'private_key'=>'string|resource|array', 'days'=>'int', 'options='=>'array', 'serial='=>'int'],
        'new' => ['OpenSSLCertificate|false', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'ca_certificate'=>'OpenSSLCertificate|string|null', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'days'=>'int', 'options='=>'array|null', 'serial='=>'int'],
    ],
    'openssl_dh_compute_key' => [
      'old' => ['string|false', 'public_key'=>'string', 'private_key'=>'resource'],
      'new' => ['string|false', 'public_key'=>'string', 'private_key'=>'OpenSSLAsymmetricKey'],
    ],
    'openssl_free_key' => [
      'old' => ['void', 'key'=>'resource'],
      'new' => ['void', 'key'=>'OpenSSLAsymmetricKey'],
    ],
    'openssl_get_privatekey' => [
      'old' => ['resource|false', 'private_key'=>'string', 'passphrase='=>'string'],
      'new' => ['OpenSSLAsymmetricKey|false', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'passphrase='=>'?string'],
    ],
    'openssl_get_publickey' => [
      'old' => ['resource|false', 'public_key'=>'resource|string'],
      'new' => ['OpenSSLAsymmetricKey|false', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string'],
    ],
    'openssl_open' => [
      'old' => ['bool', 'data'=>'string', '&w_output'=>'string', 'encrypted_key'=>'string', 'private_key'=>'string|array|resource', 'cipher_algo='=>'string', 'iv='=>'string'],
      'new' => ['bool', 'data'=>'string', '&w_output'=>'string', 'encrypted_key'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'cipher_algo'=>'string', 'iv='=>'string|null'],
    ],
    'openssl_pkcs12_export' => [
      'old' => ['bool', 'certificate'=>'string|resource', '&w_output'=>'string', 'private_key'=>'string|array|resource', 'passphrase'=>'string', 'options='=>'array'],
      'new' => ['bool', 'certificate'=>'OpenSSLCertificate|string', '&w_output'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'passphrase'=>'string', 'options='=>'array'],
    ],
    'openssl_pkcs12_export_to_file' => [
      'old' => ['bool', 'certificate'=>'string|resource', 'output_filename'=>'string', 'private_key'=>'string|array|resource', 'passphrase'=>'string', 'options='=>'array'],
      'new' => ['bool', 'certificate'=>'OpenSSLCertificate|string', 'output_filename'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'passphrase'=>'string', 'options='=>'array'],
    ],
    'openssl_pkcs7_decrypt' => [
      'old' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'string|resource', 'private_key='=>'string|resource|array'],
      'new' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'OpenSSLCertificate|string', 'private_key='=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string|null'],
    ],
    'openssl_pkcs7_encrypt' => [
      'old' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'cipher_algo='=>'int'],
      'new' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'OpenSSLCertificate|list<OpenSSLCertificate|string>|string', 'headers'=>'array|null', 'flags='=>'int', 'cipher_algo='=>'int'],
    ],
    'openssl_pkcs7_sign' => [
      'old' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'string|resource', 'private_key'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'untrusted_certificates_filename='=>'string'],
      'new' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'OpenSSLCertificate|string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'headers'=>'array|null', 'flags='=>'int', 'untrusted_certificates_filename='=>'string|null'],
    ],
    'openssl_pkcs7_verify' => [
      'old' => ['bool|int', 'input_filename'=>'string', 'flags'=>'int', 'signers_certificates_filename='=>'string', 'ca_info='=>'array', 'untrusted_certificates_filename='=>'string', 'content='=>'string', 'output_filename='=>'string'],
      'new' => ['bool|int', 'input_filename'=>'string', 'flags'=>'int', 'signers_certificates_filename='=>'?string', 'ca_info='=>'array', 'untrusted_certificates_filename='=>'?string', 'content='=>'?string', 'output_filename='=>'?string'],
    ],
    'openssl_pkey_derive' => [
      'old' => ['string|false', 'public_key'=>'mixed', 'private_key'=>'mixed', 'key_length='=>'?int'],
      'new' => ['string|false', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'key_length='=>'int'],
    ],
    'openssl_pkey_export' => [
      'old' => ['bool', 'key'=>'resource', '&w_output'=>'string', 'passphrase='=>'string|null', 'options='=>'array'],
      'new' => ['bool', 'key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', '&w_output'=>'string', 'passphrase='=>'string|null', 'options='=>'array|null'],
    ],
    'openssl_pkey_export_to_file' => [
      'old' => ['bool', 'key'=>'resource|string|array', 'output_filename'=>'string', 'passphrase='=>'string|null', 'options='=>'array'],
      'new' => ['bool', 'key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'output_filename'=>'string', 'passphrase='=>'string|null', 'options='=>'array|null'],
    ],
    'openssl_pkey_free' => [
      'old' => ['void', 'key'=>'resource'],
      'new' => ['void', 'key'=>'OpenSSLAsymmetricKey'],
    ],
    'openssl_pkey_get_details' => [
      'old' => ['array|false', 'key'=>'resource'],
      'new' => ['array|false', 'key'=>'OpenSSLAsymmetricKey'],
    ],
    'openssl_pkey_get_private' => [
      'old' => ['resource|false', 'private_key'=>'string', 'passphrase='=>'string'],
      'new' => ['OpenSSLAsymmetricKey|false', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array|string', 'passphrase='=>'?string'],
    ],
    'openssl_pkey_get_public' => [
      'old' => ['resource|false', 'public_key'=>'resource|string'],
      'new' => ['OpenSSLAsymmetricKey|false', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string'],
    ],
    'openssl_pkey_new' => [
      'old' => ['resource|false', 'options='=>'array'],
      'new' => ['OpenSSLAsymmetricKey|false', 'options='=>'array|null'],
    ],
    'openssl_private_decrypt' => [
      'old' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'private_key'=>'string|resource|array', 'padding='=>'int'],
      'new' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
    ],
    'openssl_private_encrypt' => [
      'old' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'private_key'=>'string|resource|array', 'padding='=>'int'],
      'new' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
    ],
    'openssl_public_decrypt' => [
      'old' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'public_key'=>'string|resource', 'padding='=>'int'],
      'new' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
    ],
    'openssl_public_encrypt' => [
      'old' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'public_key'=>'string|resource', 'padding='=>'int'],
      'new' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
    ],
    'openssl_seal' => [
      'old' => ['int|false', 'data'=>'string', '&w_sealed_data'=>'string', '&w_encrypted_keys'=>'array', 'public_key'=>'array', 'cipher_algo='=>'string', '&rw_iv='=>'string'],
      'new' => ['int|false', 'data'=>'string', '&w_sealed_data'=>'string', '&w_encrypted_keys'=>'array', 'public_key'=>'list<OpenSSLAsymmetricKey>', 'cipher_algo'=>'string', '&rw_iv='=>'string'],
    ],
    'openssl_sign' => [
      'old' => ['bool', 'data'=>'string', '&w_signature'=>'string', 'private_key'=>'resource|string', 'algorithm='=>'int|string'],
      'new' => ['bool', 'data'=>'string', '&w_signature'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'algorithm='=>'int|string'],
    ],
    'openssl_spki_new' => [
      'old' => ['?string', 'private_key'=>'resource', 'challenge'=>'string', 'digest_algo='=>'int'],
      'new' => ['string|false', 'private_key'=>'OpenSSLAsymmetricKey', 'challenge'=>'string', 'digest_algo='=>'int'],
    ],
    'openssl_verify' => [
      'old' => ['-1|0|1', 'data'=>'string', 'signature'=>'string', 'public_key'=>'resource|string', 'algorithm='=>'int|string'],
      'new' => ['-1|0|1|false', 'data'=>'string', 'signature'=>'string', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'algorithm='=>'int|string'],
    ],
    'openssl_x509_check_private_key' => [
      'old' => ['bool', 'certificate'=>'string|resource', 'private_key'=>'string|resource|array'],
      'new' => ['bool', 'certificate'=>'OpenSSLCertificate|string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string'],
    ],
    'openssl_x509_checkpurpose' => [
      'old' => ['bool|int', 'certificate'=>'string|resource', 'purpose'=>'int', 'ca_info='=>'array', 'untrusted_certificates_file='=>'string'],
      'new' => ['bool|int', 'certificate'=>'OpenSSLCertificate|string', 'purpose'=>'int', 'ca_info='=>'array', 'untrusted_certificates_file='=>'string|null'],
    ],
    'openssl_x509_export' => [
      'old' => ['bool', 'certificate'=>'string|resource', '&w_output'=>'string', 'no_text='=>'bool'],
      'new' => ['bool', 'certificate'=>'OpenSSLCertificate|string', '&w_output'=>'string', 'no_text='=>'bool'],
    ],
    'openssl_x509_export_to_file' => [
      'old' =>  ['bool', 'certificate'=>'string|resource', 'output_filename'=>'string', 'no_text='=>'bool'],
      'new' => ['bool', 'certificate'=>'OpenSSLCertificate|string', 'output_filename'=>'string', 'no_text='=>'bool'],
    ],
    'openssl_x509_fingerprint' => [
      'old' => ['string|false', 'certificate'=>'string|resource', 'digest_algo='=>'string', 'binary='=>'bool'],
      'new' => ['string|false', 'certificate'=>'OpenSSLCertificate|string', 'digest_algo='=>'string', 'binary='=>'bool'],
    ],
    'openssl_x509_free' => [
      'old' => ['void', 'certificate'=>'resource'],
      'new' => ['void', 'certificate'=>'OpenSSLCertificate'],
    ],
    'openssl_x509_parse' => [
      'old' => ['array|false', 'certificate'=>'string|resource', 'short_names='=>'bool'],
      'new' => ['array|false', 'certificate'=>'OpenSSLCertificate|string', 'short_names='=>'bool'],
    ],
    'openssl_x509_read' => [
      'old' => ['resource|false', 'certificate'=>'string|resource'],
      'new' => ['OpenSSLCertificate|false', 'certificate'=>'OpenSSLCertificate|string'],
    ],
    'openssl_x509_verify' => [
      'old' => ['int', 'certificate'=>'string|resource', 'public_key'=>'string|array|resource'],
      'new' => ['int', 'certificate'=>'string|OpenSSLCertificate', 'public_key'=>'string|OpenSSLCertificate|OpenSSLAsymmetricKey|array'],
    ],
    'pack' => [
      'old' => ['string|false', 'format'=>'string', '...values='=>'mixed'],
      'new' => ['string', 'format'=>'string', '...values='=>'mixed'],
    ],
    'parse_str' => [
      'old' => ['void', 'string'=>'string', '&w_result='=>'array'],
      'new' => ['void', 'string'=>'string', '&w_result'=>'array'],
    ],
    'password_hash' => [
      'old' => ['string|false', 'password'=>'string', 'algo'=>'int|string|null', 'options='=>'array'],
      'new' => ['string', 'password'=>'string', 'algo'=>'int|string|null', 'options='=>'array'],
    ],
    'pcntl_async_signals' => [
      'old' => ['bool', 'enable='=>'bool'],
      'new' => ['bool', 'enable='=>'?bool'],
    ],
    'pcntl_exec' => [
      'old' => ['null|false', 'path'=>'string', 'args='=>'array', 'env_vars='=>'array'],
      'new' => ['false', 'path'=>'string', 'args='=>'array', 'env_vars='=>'array'],
    ],
    'pcntl_getpriority' => [
      'old' => ['int', 'process_id='=>'int', 'mode='=>'int'],
      'new' => ['int', 'process_id='=>'?int', 'mode='=>'int'],
    ],
    'pcntl_setpriority' => [
      'old' => ['bool', 'priority'=>'int', 'process_id='=>'int', 'mode='=>'int'],
      'new' => ['bool', 'priority'=>'int', 'process_id='=>'?int', 'mode='=>'int'],
    ],
    'pfsockopen' => [
      'old' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'float'],
      'new' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'?float'],
    ],
    'pg_client_encoding' => [
      'old' => ['string', 'connection='=>'resource'],
      'new' => ['string', 'connection='=>'?resource'],
    ],
    'pg_close' => [
      'old' => ['bool', 'connection='=>'resource'],
      'new' => ['bool', 'connection='=>'?resource'],
    ],
    'pg_dbname' => [
      'old' => ['string', 'connection='=>'resource'],
      'new' => ['string', 'connection='=>'?resource'],
    ],
    'pg_end_copy' => [
      'old' => ['bool', 'connection='=>'resource'],
      'new' => ['bool', 'connection='=>'?resource'],
    ],
    'pg_last_error' => [
      'old' => ['string', 'connection='=>'resource'],
      'new' => ['string', 'connection='=>'?resource'],
    ],
    'pg_lo_write' => [
      'old' => ['int|false', 'lob'=>'resource', 'data'=>'string', 'length='=>'int'],
      'new' => ['int|false', 'lob'=>'resource', 'data'=>'string', 'length='=>'?int'],
    ],
    'pg_options' => [
      'old' => ['string', 'connection='=>'resource'],
      'new' => ['string', 'connection='=>'?resource'],
    ],
    'pg_ping' => [
      'old' => ['bool', 'connection='=>'resource'],
      'new' => ['bool', 'connection='=>'?resource'],
    ],
    'pg_port' => [
      'old' => ['string', 'connection='=>'resource'],
      'new' => ['string', 'connection='=>'?resource'],
    ],
    'pg_trace' => [
      'old' => ['bool', 'filename'=>'string', 'mode='=>'string', 'connection='=>'resource'],
      'new' => ['bool', 'filename'=>'string', 'mode='=>'string', 'connection='=>'?resource'],
    ],
    'pg_tty' => [
      'old' => ['string', 'connection='=>'resource'],
      'new' => ['string', 'connection='=>'?resource'],
    ],
    'pg_untrace' => [
      'old' => ['bool', 'connection='=>'resource'],
      'new' => ['bool', 'connection='=>'?resource'],
    ],
    'pg_version' => [
      'old' => ['array', 'connection='=>'resource'],
      'new' => ['array', 'connection='=>'?resource'],
    ],
    'phpversion' => [
      'old' => ['string|false', 'extension='=>'string'],
      'new' => ['string|false', 'extension='=>'?string'],
    ],
    'proc_get_status' => [
      'old' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}|false', 'process'=>'resource'],
      'new' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}', 'process'=>'resource'],
    ],
    'readline_info' => [
      'old' => ['mixed', 'var_name='=>'string', 'value='=>'string|int|bool'],
      'new' => ['mixed', 'var_name='=>'?string', 'value='=>'string|int|bool|null'],
    ],
    'readline_read_history' => [
      'old'=> ['bool', 'filename='=>'string'],
      'new'=> ['bool', 'filename='=>'?string'],
    ],
    'readline_write_history' => [
      'old' => ['bool', 'filename='=>'string'],
      'new' => ['bool', 'filename='=>'?string'],
    ],
    'sapi_windows_vt100_support' => [
      'old' => ['bool', 'stream'=>'resource', 'enable='=>'bool'],
      'new' => ['bool', 'stream'=>'resource', 'enable='=>'?bool'],
    ],
    'session_cache_expire' => [
      'old' => ['int', 'value='=>'int'],
      'new' => ['int', 'value='=>'?int'],
    ],
    'session_cache_limiter' => [
      'old' => ['string', 'value='=>'string'],
      'new' => ['string', 'value='=>'?string'],
    ],
    'session_id' => [
      'old' => ['string|false', 'id='=>'string'],
      'new' => ['string|false', 'id='=>'?string'],
    ],
    'session_module_name' => [
      'old' => ['string', 'module='=>'string'],
      'new' => ['string', 'module='=>'?string'],
    ],
    'session_name' => [
      'old' => ['string|false', 'name='=>'string'],
      'new' => ['string|false', 'name='=>'?string'],
    ],
    'session_save_path' => [
      'old' => ['string', 'path='=>'string'],
      'new' => ['string', 'path='=>'?string'],
    ],
    'session_set_cookie_params' => [
      'old' => ['bool', 'lifetime'=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'],
      'new' => ['bool', 'lifetime'=>'int', 'path='=>'?string', 'domain='=>'?string', 'secure='=>'?bool', 'httponly='=>'?bool'],
    ],
    'shm_attach' => [
      'old' => ['resource|false', 'key'=>'int', 'size='=>'int', 'permissions='=>'int'],
      'new' => ['SysvSharedMemory|false', 'key'=>'int', 'size='=>'?int', 'permissions='=>'int'],
    ],
    'shmop_close' => [
      'old' => ['void', 'shmop'=>'resource'],
      'new' => ['void', 'shmop'=>'Shmop'],
    ],
    'shmop_delete' => [
      'old' => ['bool', 'shmop'=>'resource'],
      'new' => ['bool', 'shmop'=>'Shmop'],
    ],
    'shmop_open' => [
      'old' => ['resource|false', 'key'=>'int', 'mode'=>'string', 'permissions'=>'int', 'size'=>'int'],
      'new' => ['Shmop|false', 'key'=>'int', 'mode'=>'string', 'permissions'=>'int', 'size'=>'int'],
    ],
    'shmop_read' => [
      'old' => ['string|false', 'shmop'=>'resource', 'offset'=>'int', 'size'=>'int'],
      'new' => ['string', 'shmop'=>'Shmop', 'offset'=>'int', 'size'=>'int'],
    ],
    'shmop_size' => [
      'old' => ['int', 'shmop'=>'resource'],
      'new' => ['int', 'shmop'=>'Shmop'],
    ],
    'shmop_write' => [
      'old' => ['int|false', 'shmop'=>'resource', 'data'=>'string', 'offset'=>'int'],
      'new' => ['int', 'shmop'=>'Shmop', 'data'=>'string', 'offset'=>'int'],
    ],
    'sleep' => [
      'old' => ['int|false', 'seconds'=>'0|positive-int'],
      'new' => ['int', 'seconds'=>'0|positive-int'],
    ],
    'socket_accept' => [
      'old' => ['resource|false', 'socket'=>'resource'],
      'new' => ['Socket|false', 'socket'=>'Socket'],
    ],
    'socket_addrinfo_bind' => [
      'old' => ['?resource', 'addrinfo'=>'resource'],
      'new' => ['Socket|false', 'address'=>'AddressInfo'],
    ],
    'socket_addrinfo_connect' => [
      'old' => ['resource', 'addrinfo'=>'resource'],
      'new' => ['Socket|false', 'address'=>'AddressInfo'],
    ],
    'socket_addrinfo_explain' => [
      'old' => ['array', 'addrinfo'=>'resource'],
      'new' => ['array', 'address'=>'AddressInfo'],
    ],
    'socket_addrinfo_lookup' => [
      'old' => ['resource[]', 'node'=>'string', 'service='=>'mixed', 'hints='=>'array'],
      'new' => ['false|AddressInfo[]', 'host='=>'string|null', 'service='=>'mixed', 'hints='=>'array'],
    ],
    'socket_bind' => [
      'old' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'],
      'new' => ['bool', 'socket'=>'Socket', 'addr'=>'string', 'port='=>'int'],
    ],
    'socket_clear_error' => [
      'old' => ['void', 'socket='=>'resource'],
      'new' => ['void', 'socket='=>'?Socket'],
    ],
    'socket_close' => [
      'old' => ['void', 'socket'=>'resource'],
      'new' => ['void', 'socket'=>'Socket'],
    ],
    'socket_connect' => [
      'old' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'],
      'new' => ['bool', 'socket'=>'Socket', 'addr'=>'string', 'port='=>'int'],
    ],
    'socket_create' => [
      'old' => ['resource|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'],
      'new' => ['Socket|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'],
    ],
    'socket_create_listen' => [
      'old' => ['resource|false', 'port'=>'int', 'backlog='=>'int'],
      'new' => ['Socket|false', 'port'=>'int', 'backlog='=>'int'],
    ],
    'socket_create_pair' => [
      'old' => ['bool', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int', '&w_fd'=>'resource[]'],
      'new' => ['bool', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int', '&w_fd'=>'Socket[]'],
    ],
    'socket_export_stream' => [
      'old' => ['resource|false', 'socket'=>'resource'],
      'new' => ['resource|false', 'socket'=>'Socket'],
    ],
    'socket_get_option' => [
      'old' => ['mixed|false', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'],
      'new' => ['mixed|false', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int'],
    ],
    'socket_get_status' => [
      'old' => ['array', 'stream'=>'resource'],
      'new' => ['array', 'stream'=>'Socket'],
    ],
    'socket_getopt' => [
      'old' => ['mixed', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'],
      'new' => ['mixed', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int'],
    ],
    'socket_getpeername' => [
      'old' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'],
      'new' => ['bool', 'socket'=>'Socket', '&w_addr'=>'string', '&w_port='=>'int'],
    ],
    'socket_getsockname' => [
      'old' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'],
      'new' => ['bool', 'socket'=>'Socket', '&w_addr'=>'string', '&w_port='=>'int'],
    ],
    'socket_import_stream' => [
      'old' => ['resource|false', 'stream'=>'resource'],
      'new' => ['Socket|false', 'stream'=>'resource'],
    ],
    'socket_last_error' => [
      'old' => ['int', 'socket='=>'resource'],
      'new' => ['int', 'socket='=>'?Socket'],
    ],
    'socket_listen' => [
      'old' => ['bool', 'socket'=>'resource', 'backlog='=>'int'],
      'new' => ['bool', 'socket'=>'Socket', 'backlog='=>'int'],
    ],
    'socket_read' => [
      'old' => ['string|false', 'socket'=>'resource', 'length'=>'int', 'type='=>'int'],
      'new' => ['string|false', 'socket'=>'Socket', 'length'=>'int', 'type='=>'int'],
    ],
    'socket_recv' => [
      'old' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int'],
      'new' => ['int|false', 'socket'=>'Socket', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int'],
    ],
    'socket_recvfrom' => [
      'old' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int', '&w_name'=>'string', '&w_port='=>'int'],
      'new' => ['int|false', 'socket'=>'Socket', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int', '&w_name'=>'string', '&w_port='=>'int'],
    ],
    'socket_recvmsg' => [
      'old' => ['int|false', 'socket'=>'resource', '&w_message'=>'string', 'flags='=>'int'],
      'new' => ['int|false', 'socket'=>'Socket', '&w_message'=>'string', 'flags='=>'int'],
    ],
    'socket_select' => [
      'old' => ['int|false', '&rw_read_fds'=>'resource[]|null', '&rw_write_fds'=>'resource[]|null', '&rw_except_fds'=>'resource[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int'],
      'new' => ['int|false', '&rw_read_fds'=>'Socket[]|null', '&rw_write_fds'=>'Socket[]|null', '&rw_except_fds'=>'Socket[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int'],
    ],
    'socket_send' => [
      'old' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'length'=>'int', 'flags'=>'int'],
      'new' => ['int|false', 'socket'=>'Socket', 'buf'=>'string', 'length'=>'int', 'flags'=>'int'],
    ],
    'socket_sendmsg' => [
      'old' => ['int|false', 'socket'=>'resource', 'message'=>'array', 'flags'=>'int'],
      'new' => ['int|false', 'socket'=>'Socket', 'message'=>'array', 'flags'=>'int'],
    ],
    'socket_sendto' => [
      'old' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'length'=>'int', 'flags'=>'int', 'addr'=>'string', 'port='=>'int'],
      'new' => ['int|false', 'socket'=>'Socket', 'buf'=>'string', 'length'=>'int', 'flags'=>'int', 'addr'=>'string', 'port='=>'int'],
    ],
    'socket_set_block' => [
      'old' => ['bool', 'socket'=>'resource'],
      'new' => ['bool', 'socket'=>'Socket'],
    ],
    'socket_set_blocking' => [
      'old' => ['bool', 'socket'=>'resource', 'mode'=>'int'],
      'new' => ['bool', 'socket'=>'Socket', 'mode'=>'int'],
    ],
    'socket_set_nonblock' => [
      'old' => ['bool', 'socket'=>'resource'],
      'new' => ['bool', 'socket'=>'Socket'],
    ],
    'socket_set_option' => [
      'old' => ['bool', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
      'new' => ['bool', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
    ],
    'socket_set_timeout' => [
      'old' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'],
      'new' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'],
    ],
    'socket_setopt' => [
      'old' => ['void', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
      'new' => ['void', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
    ],
    'socket_shutdown' => [
      'old' => ['bool', 'socket'=>'resource', 'how='=>'int'],
      'new' => ['bool', 'socket'=>'Socket', 'how='=>'int'],
    ],
    'socket_strerror' => [
      'old' => ['string', 'errno'=>'int'],
      'new' => ['string', 'errno'=>'int'],
    ],
    'socket_write' => [
      'old' => ['int|false', 'socket'=>'resource', 'data'=>'string', 'length='=>'int'],
      'new' => ['int|false', 'socket'=>'Socket', 'data'=>'string', 'length='=>'int|null'],
    ],
    'socket_wsaprotocol_info_export' => [
      'old' => ['string|false', 'socket'=>'resource', 'process_id'=>'int'],
      'new' => ['string|false', 'socket'=>'Socket', 'process_id'=>'int'],
    ],
    'socket_wsaprotocol_info_import' => [
      'old' => ['resource|false', 'info_id'=>'string'],
      'new' => ['Socket|false', 'info_id'=>'string'],
    ],
    'spl_autoload' => [
      'old' => ['void', 'class'=>'string', 'file_extensions='=>'string'],
      'new' => ['void', 'class'=>'string', 'file_extensions='=>'?string'],
    ],
    'spl_autoload_extensions' => [
      'old' => ['string', 'file_extensions='=>'string'],
      'new' => ['string', 'file_extensions='=>'?string'],
    ],
    'spl_autoload_functions' => [
      'old' => ['false|list<callable(string):void>'],
      'new' => ['list<callable(string):void>'],
    ],
    'spl_autoload_register' => [
      'old' => ['bool', 'callback='=>'callable(string):void', 'throw='=>'bool', 'prepend='=>'bool'],
      'new' => ['bool', 'callback='=>'callable(string):void|null', 'throw='=>'bool', 'prepend='=>'bool'],
    ],
    'str_word_count' => [
      'old' => ['array<int, string>|int', 'string'=>'string', 'format='=>'int', 'characters='=>'string'],
      'new' => ['array<int, string>|int', 'string'=>'string', 'format='=>'int', 'characters='=>'?string'],
    ],
    'strchr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
    ],
    'strcspn' => [
      'old' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'int'],
      'new' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'?int'],
    ],
    'stream_context_create' => [
      'old' => ['resource', 'options='=>'array', 'params='=>'array'],
      'new' => ['resource', 'options='=>'?array', 'params='=>'?array'],
    ],
    'stream_context_get_default' => [
      'old' => ['resource', 'options='=>'array'],
      'new' => ['resource', 'options='=>'?array'],
    ],
    'stream_copy_to_stream' => [
      'old' => ['int|false', 'from'=>'resource', 'to'=>'resource', 'length='=>'int', 'offset='=>'int'],
      'new' => ['int|false', 'from'=>'resource', 'to'=>'resource', 'length='=>'?int', 'offset='=>'int'],
    ],
    'stream_get_contents' => [
      'old' => ['string|false', 'stream'=>'resource', 'length='=>'int', 'offset='=>'int'],
      'new' => ['string|false', 'stream'=>'resource', 'length='=>'?int', 'offset='=>'int'],
    ],
    'stream_set_chunk_size' => [
      'old' => ['int|false', 'stream'=>'resource', 'size'=>'int'],
      'new' => ['int', 'stream'=>'resource', 'size'=>'int'],
    ],
    'stream_socket_accept' => [
      'old' => ['resource|false', 'socket'=>'resource', 'timeout='=>'float', '&w_peer_name='=>'string'],
      'new' => ['resource|false', 'socket'=>'resource', 'timeout='=>'?float', '&w_peer_name='=>'string'],
    ],
    'stream_socket_client' => [
      'old' => ['resource|false', 'address'=>'string', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'float', 'flags='=>'int', 'context='=>'resource'],
      'new' => ['resource|false', 'address'=>'string', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'?float', 'flags='=>'int', 'context='=>'?resource'],
    ],
    'stream_socket_enable_crypto' => [
      'old' => ['int|bool', 'stream'=>'resource', 'enable'=>'bool', 'crypto_method='=>'?int', 'session_stream='=>'resource'],
      'new' => ['int|bool', 'stream'=>'resource', 'enable'=>'bool', 'crypto_method='=>'?int', 'session_stream='=>'?resource'],
    ],
    'strftime' => [
      'old' => ['string|false', 'format'=>'string', 'timestamp='=>'int'],
      'new' => ['string|false', 'format'=>'string', 'timestamp='=>'?int'],
    ],
    'strip_tags' => [
      'old' => ['string', 'string'=>'string', 'allowed_tags='=>'string|list<non-empty-string>'],
      'new' => ['string', 'string'=>'string', 'allowed_tags='=>'string|list<non-empty-string>|null'],
    ],
    'stripos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    ],
    'stristr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
    ],
    'strpos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    ],
    'strrchr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string'],
    ],
    'strripos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    ],
    'strrpos' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'],
      'new' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
    ],
    'strspn' => [
      'old' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'int'],
      'new' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'?int'],
    ],
    'strstr' => [
      'old' => ['string|false', 'haystack'=>'string', 'needle'=>'string|int', 'before_needle='=>'bool'],
      'new' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
    ],
    'strtotime' => [
      'old' => ['int|false', 'datetime'=>'string', 'baseTimestamp='=>'int'],
      'new' => ['int|false', 'datetime'=>'string', 'baseTimestamp='=>'?int'],
    ],
    'substr_compare' => [
      'old' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset'=>'int', 'length='=>'int', 'case_insensitive='=>'bool'],
      'new' => ['int', 'haystack'=>'string', 'needle'=>'string', 'offset'=>'int', 'length='=>'?int', 'case_insensitive='=>'bool'],
    ],
    'substr_count' => [
      'old' => ['int', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'length='=>'int'],
      'new' => ['int', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'length='=>'?int'],
    ],
    'substr' => [
      'old' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'int'],
      'new' => ['string', 'string'=>'string', 'offset'=>'int', 'length='=>'?int'],
    ],
    'tidy_parse_file' => [
      'old' => ['tidy', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
      'new' => ['tidy', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
    ],
    'tidy_parse_string' => [
      'old' => ['tidy', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
      'new' => ['tidy', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
    ],
    'tidy_repair_file' => [
      'old' => ['string', 'filename'=>'string', 'config='=>'array|string', 'encoding='=>'string', 'useIncludePath='=>'bool'],
      'new' => ['string', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
    ],
    'tidy_repair_string' => [
      'old' => ['string', 'string'=>'string', 'config='=>'array|string', 'encoding='=>'string'],
      'new' => ['string', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
    ],
    'timezone_identifiers_list' => [
      'old' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'?string'],
      'new' => ['list<string>', 'timezoneGroup='=>'int', 'countryCode='=>'?string'],
    ],
    'timezone_offset_get' => [
      'old' => ['int|false', 'object'=>'DateTimeZone', 'datetime'=>'DateTimeInterface'],
      'new' => ['int', 'object'=>'DateTimeZone', 'datetime'=>'DateTimeInterface'],
    ],
    'touch' => [
      'old' => ['bool', 'filename'=>'string', 'mtime='=>'int', 'atime='=>'int'],
      'new' => ['bool', 'filename'=>'string', 'mtime='=>'?int', 'atime='=>'?int'],
    ],
    'umask' => [
      'old' => ['int', 'mask='=>'int'],
      'new' => ['int', 'mask='=>'?int'],
    ],
    'unixtojd' => [
      'old' => ['int', 'timestamp='=>'int'],
      'new' => ['int', 'timestamp='=>'?int'],
    ],
    'xml_get_current_byte_index' => [
      'old' => ['int|false', 'parser'=>'resource'],
      'new' => ['int', 'parser'=>'XMLParser'],
    ],
    'xml_get_current_column_number' => [
      'old' => ['int|false', 'parser'=>'resource'],
      'new' => ['int', 'parser'=>'XMLParser'],
    ],
    'xml_get_current_line_number' => [
      'old' => ['int|false', 'parser'=>'resource'],
      'new' => ['int', 'parser'=>'XMLParser'],
    ],
    'xml_get_error_code' => [
      'old' => ['int|false', 'parser'=>'resource'],
      'new' => ['int', 'parser'=>'XMLParser'],
    ],
    'xml_parse' => [
      'old' => ['int', 'parser'=>'resource', 'data'=>'string', 'is_final='=>'bool'],
      'new' => ['int', 'parser'=>'XMLParser', 'data'=>'string', 'is_final='=>'bool'],
    ],
    'xml_parse_into_struct' => [
      'old' => ['int', 'parser'=>'resource', 'data'=>'string', '&w_values'=>'array', '&w_index='=>'array'],
      'new' => ['int', 'parser'=>'XMLParser', 'data'=>'string', '&w_values'=>'array', '&w_index='=>'array'],
    ],
    'xml_parser_create' => [
      'old' => ['resource', 'encoding='=>'string'],
      'new' => ['XMLParser', 'encoding='=>'?string'],
    ],
    'xml_parser_create_ns' => [
      'old' => ['resource', 'encoding='=>'string', 'separator='=>'string'],
      'new' => ['XMLParser', 'encoding='=>'?string', 'separator='=>'string'],
    ],
    'xml_parser_free' => [
      'old' => ['bool', 'parser'=>'resource'],
      'new' => ['bool', 'parser'=>'XMLParser'],
    ],
    'xml_parser_get_option' => [
      'old' => ['string|false', 'parser'=>'resource', 'option'=>'int'],
      'new' => ['string', 'parser'=>'XMLParser', 'option'=>'int'],
    ],
    'xml_parser_set_option' => [
      'old' => ['bool', 'parser'=>'resource', 'option'=>'int', 'value'=>'mixed'],
      'new' => ['bool', 'parser'=>'XMLParser', 'option'=>'int', 'value'=>'mixed'],
    ],
    'xml_set_character_data_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xml_set_default_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xml_set_element_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'start_handler'=>'callable', 'end_handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'start_handler'=>'callable', 'end_handler'=>'callable'],
    ],
    'xml_set_end_namespace_decl_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xml_set_external_entity_ref_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xml_set_notation_decl_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xml_set_object' => [
      'old' => ['bool', 'parser'=>'resource', 'object'=>'object'],
      'new' => ['bool', 'parser'=>'XMLParser', 'object'=>'object'],
    ],
    'xml_set_processing_instruction_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xml_set_start_namespace_decl_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xml_set_unparsed_entity_decl_handler' => [
      'old' => ['bool', 'parser'=>'resource', 'handler'=>'callable'],
      'new' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
    ],
    'xmlwriter_end_attribute' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_cdata' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_comment' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_document' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_dtd' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_dtd_attlist' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_dtd_element' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_dtd_entity' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_element' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_end_pi' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_flush' => [
      'old' => ['string|int|false', 'writer'=>'resource', 'empty='=>'bool'],
      'new' => ['string|int', 'writer'=>'XMLWriter', 'empty='=>'bool'],
    ],
    'xmlwriter_full_end_element' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_open_memory' => [
      'old' => ['resource|false'],
      'new' => ['XMLWriter|false'],
    ],
    'xmlwriter_open_uri' => [
      'old' => ['resource|false', 'uri'=>'string'],
      'new' => ['XMLWriter|false', 'uri'=>'string'],
    ],
    'xmlwriter_output_memory' => [
      'old' => ['string', 'writer'=>'resource', 'flush='=>'bool'],
      'new' => ['string', 'writer'=>'XMLWriter', 'flush='=>'bool'],
    ],
    'xmlwriter_set_indent' => [
      'old' => ['bool', 'writer'=>'resource', 'enable'=>'bool'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'enable'=>'bool'],
    ],
    'xmlwriter_set_indent_string' => [
      'old' => ['bool', 'writer'=>'resource', 'indentation'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'indentation'=>'string'],
    ],
    'xmlwriter_start_attribute' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string'],
    ],
    'xmlwriter_start_attribute_ns' => [
      'old' => ['bool', 'writer'=>'resource', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
    ],
    'xmlwriter_start_cdata' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_start_comment' => [
      'old' => ['bool', 'writer'=>'resource'],
      'new' => ['bool', 'writer'=>'XMLWriter'],
    ],
    'xmlwriter_start_document' => [
      'old' => ['bool', 'writer'=>'resource', 'version='=>'?string', 'encoding='=>'?string', 'standalone='=>'?string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'version='=>'?string', 'encoding='=>'?string', 'standalone='=>'?string'],
    ],
    'xmlwriter_start_dtd' => [
      'old' => ['bool', 'writer'=>'resource', 'qualifiedName'=>'string', 'publicId='=>'?string', 'systemId='=>'?string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'qualifiedName'=>'string', 'publicId='=>'?string', 'systemId='=>'?string'],
    ],
    'xmlwriter_start_dtd_attlist' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string'],
    ],
    'xmlwriter_start_dtd_element' => [
      'old' => ['bool', 'writer'=>'resource', 'qualifiedName'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'qualifiedName'=>'string'],
    ],
    'xmlwriter_start_dtd_entity' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string', 'isParam'=>'bool'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'isParam'=>'bool'],
    ],
    'xmlwriter_start_element' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string'],
    ],
    'xmlwriter_start_element_ns' => [
      'old' => ['bool', 'writer'=>'resource', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
    ],
    'xmlwriter_start_pi' => [
      'old' => ['bool', 'writer'=>'resource', 'target'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'target'=>'string'],
    ],
    'xmlwriter_text' => [
      'old' => ['bool', 'writer'=>'resource', 'content'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
    ],
    'xmlwriter_write_attribute' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string', 'value'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'value'=>'string'],
    ],
    'xmlwriter_write_attribute_ns' => [
      'old' => ['bool', 'writer'=>'resource', 'prefix'=>'string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
    ],
    'xmlwriter_write_cdata' => [
      'old' => ['bool', 'writer'=>'resource', 'content'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
    ],
    'xmlwriter_write_comment' => [
      'old' => ['bool', 'writer'=>'resource', 'content'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
    ],
    'xmlwriter_write_dtd' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string', 'publicId='=>'?string', 'systemId='=>'?string', 'content='=>'?string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'publicId='=>'?string', 'systemId='=>'?string', 'content='=>'?string'],
    ],
    'xmlwriter_write_dtd_attlist' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content'=>'string'],
    ],
    'xmlwriter_write_dtd_element' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content'=>'string'],
    ],
    'xmlwriter_write_dtd_entity' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'string', 'isParam'=>'bool', 'publicId'=>'string', 'systemId'=>'string', 'notationData'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content'=>'string', 'isParam='=>'bool', 'publicId='=>'?string', 'systemId='=>'?string', 'notationData='=>'?string'],
    ],
    'xmlwriter_write_element' => [
      'old' => ['bool', 'writer'=>'resource', 'name'=>'string', 'content'=>'?string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content='=>'?string'],
    ],
    'xmlwriter_write_element_ns' => [
      'old' => ['bool', 'writer'=>'resource', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'string', 'content'=>'?string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'content='=>'?string'],
    ],
    'xmlwriter_write_pi' => [
      'old' => ['bool', 'writer'=>'resource', 'target'=>'string', 'content'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'target'=>'string', 'content'=>'string'],
    ],
    'xmlwriter_write_raw' => [
      'old' => ['bool', 'writer'=>'resource', 'content'=>'string'],
      'new' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
    ],
    'ZipArchive::addEmptyDir' => [
      'old' => ['bool', 'dirname'=>'string'],
      'new' => ['bool', 'dirname'=>'string', 'flags='=>'int'],
    ],
    'ZipArchive::addFile' => [
      'old' => ['bool', 'filepath'=>'string', 'entryname='=>'string', 'start='=>'int', 'length='=>'int'],
      'new' => ['bool', 'filepath'=>'string', 'entryname='=>'string', 'start='=>'int', 'length='=>'int', 'flags='=>'int'],
    ],
    'ZipArchive::addFromString' => [
      'old' => ['bool', 'name'=>'string', 'content'=>'string'],
      'new' => ['bool', 'name'=>'string', 'content'=>'string', 'flags='=>'int'],
    ],
  ],
  'removed' => [
    'PDOStatement::setFetchMode\'1' => ['bool', 'fetch_column'=>'int', 'colno'=>'int'],
    'PDOStatement::setFetchMode\'2' => ['bool', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs'=>'array'],
    'PDOStatement::setFetchMode\'3' => ['bool', 'fetch_into'=>'int', 'object'=>'object'],
    'ReflectionType::isBuiltin' => ['bool'],
    'SplFileObject::fgetss' => ['string|false', 'allowable_tags='=>'string'],
    'create_function' => ['string', 'args'=>'string', 'code'=>'string'],
    'each' => ['array{0:int|string,key:int|string,1:mixed,value:mixed}', '&r_arr'=>'array'],
    'fgetss' => ['string|false', 'fp'=>'resource', 'length='=>'int', 'allowable_tags='=>'string'],
    'gmp_random' => ['GMP', 'limiter='=>'int'],
    'gzgetss' => ['string|false', 'zp'=>'resource', 'length'=>'int', 'allowable_tags='=>'string'],
    'image2wbmp' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'threshold='=>'int'],
    'jpeg2wbmp' => ['bool', 'jpegname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'],
    'ldap_control_paged_result' => ['bool', 'link_identifier'=>'resource', 'pagesize'=>'int', 'iscritical='=>'bool', 'cookie='=>'string'],
    'ldap_control_paged_result_response' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', '&w_cookie'=>'string', '&w_estimated'=>'int'],
    'ldap_sort' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', 'sortfilter'=>'string'],
    'number_format\'1' => ['string', 'num'=>'float|int', 'decimals'=>'int', 'decimal_separator'=>'?string', 'thousands_separator'=>'?string'],
    'png2wbmp' => ['bool', 'pngname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'],
    'read_exif_data' => ['array', 'filename'=>'string', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'],
    'Reflection::export' => ['?string', 'r'=>'reflector', 'return='=>'bool'],
    'ReflectionClass::export' => ['?string', 'argument'=>'string|object', 'return='=>'bool'],
    'ReflectionClassConstant::export' => ['string', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'],
    'ReflectionExtension::export' => ['?string', 'name'=>'string', 'return='=>'bool'],
    'ReflectionFunction::export' => ['?string', 'name'=>'string', 'return='=>'bool'],
    'ReflectionFunctionAbstract::export' => ['?string'],
    'ReflectionMethod::export' => ['?string', 'class'=>'string', 'name'=>'string', 'return='=>'bool'],
    'ReflectionObject::export' => ['?string', 'argument'=>'object', 'return='=>'bool'],
    'ReflectionParameter::export' => ['?string', 'function'=>'string', 'parameter'=>'string', 'return='=>'bool'],
    'ReflectionProperty::export' => ['?string', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'],
    'ReflectionZendExtension::export' => ['?string', 'name'=>'string', 'return='=>'bool'],
    'SimpleXMLIterator::rewind' => ['void'],
    'SimpleXMLIterator::valid' => ['bool'],
    'SimpleXMLIterator::current' => ['?SimpleXMLIterator'],
    'SimpleXMLIterator::key' => ['string|false'],
    'SimpleXMLIterator::next' => ['void'],
    'SimpleXMLIterator::hasChildren' => ['bool'],
    'SimpleXMLIterator::getChildren' => ['?SimpleXMLIterator'],
    'SplTempFileObject::fgetss' => ['string', 'allowable_tags='=>'string'],
  ],
];
<?php // phpcs:ignoreFile

/**
 * This contains the information needed to convert the function signatures for php 7.1 to php 7.0 (and vice versa)
 *
 * This file has three sections.
 * The 'added' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that did not exist prior to PHP 7.1
 * The 'removed' section contains the signatures that were removed in php 7.1.
 * The 'changed' section contains functions for which the signature has changed for php 7.1.
 *     Each function in the 'changed' section has an 'old' and a 'new' section,
 *     representing the function as it was in PHP before 7.1 and in PHP 7.1, respectively
 *
 * @see CallMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
  'added' => [
    'Closure::fromCallable' => ['Closure', 'callable'=>'callable'],
    'curl_multi_errno' => ['int|false', 'mh'=>'resource'],
    'curl_share_errno' => ['int|false', 'sh'=>'resource'],
    'curl_share_strerror' => ['?string', 'error_code'=>'int'],
    'getenv\'1' => ['array<string,string>'],
    'hash_hkdf' => ['non-empty-string|false', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'],
    'is_iterable' => ['bool', 'value'=>'mixed'],
    'openssl_get_curve_names' => ['list<string>'],
    'pcntl_async_signals' => ['bool', 'enable='=>'bool'],
    'pcntl_signal_get_handler' => ['int|string', 'signal'=>'int'],
    'sapi_windows_cp_conv' => ['?string', 'in_codepage'=>'int|string', 'out_codepage'=>'int|string', 'subject'=>'string'],
    'sapi_windows_cp_get' => ['int'],
    'sapi_windows_cp_is_utf8' => ['bool'],
    'sapi_windows_cp_set' => ['bool', 'codepage'=>'int'],
    'session_create_id' => ['string', 'prefix='=>'string'],
    'session_gc' => ['int|false'],
  ],
  'changed' => [
    'DateTimeZone::listIdentifiers' => [
      'old' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'string'],
      'new' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'string|null'],
    ],
    'IntlDateFormatter::format' => [
        'old' => ['string|false', 'value'=>'IntlCalendar|DateTime|array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int}|array{tm_sec: int, tm_min: int, tm_hour: int, tm_mday: int, tm_mon: int, tm_year: int, tm_wday: int, tm_yday: int, tm_isdst: int}|string|int|float'],
        'new' => ['string|false', 'value'=>'IntlCalendar|DateTimeInterface|array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int}|array{tm_sec: int, tm_min: int, tm_hour: int, tm_mday: int, tm_mon: int, tm_year: int, tm_wday: int, tm_yday: int, tm_isdst: int}|string|int|float'],
    ],
    'SQLite3::createFunction' => [
      'old' => ['bool', 'name'=>'string', 'callback'=>'callable', 'argCount='=>'int'],
      'new' => ['bool', 'name'=>'string', 'callback'=>'callable', 'argCount='=>'int', 'flags='=>'int'],
    ],
    'get_headers' => [
      'old' => ['array|false', 'url'=>'string', 'associative='=>'int'],
      'new' => ['array|false', 'url'=>'string', 'associative='=>'int', 'context='=>'?resource'],
    ],
    'getopt' => [
      'old' => ['array<string,string|false|list<string|false>>|false', 'short_options'=>'string', 'long_options='=>'array'],
      'new' => ['array<string,string|false|list<string|false>>|false', 'short_options'=>'string', 'long_options='=>'array', '&w_rest_index='=>'int'],
    ],
    'pg_fetch_all' => [
      'old' => ['array<array>', 'result'=>'resource'],
      'new' => ['array<array>', 'result'=>'resource', 'result_type='=>'int'],
    ],
    'pg_select' => [
      'old' => ['string|array|false', 'connection'=>'resource', 'table_name'=>'string', 'assoc_array'=>'array', 'options='=>'int'],
      'new' => ['string|array|false', 'connection'=>'resource', 'table_name'=>'string', 'assoc_array'=>'array', 'options='=>'int', 'result_type='=>'int'],
    ],
    'timezone_identifiers_list' => [
      'old' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'string'],
      'new' => ['list<string>|false', 'timezoneGroup='=>'int', 'countryCode='=>'?string'],
    ],
    'unpack' => [
      'old' => ['array', 'format'=>'string', 'string'=>'string'],
      'new' => ['array|false', 'format'=>'string', 'string'=>'string', 'offset='=>'int'],
    ],
  ],
  'removed' => [
  ],
];
<?php // phpcs:ignoreFile

/**
 * This contains the information needed to convert the function signatures for php 8.2 to php 8.1 (and vice versa)
 *
 * This file has three sections.
 * The 'added' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that do not exist in php 8.1
 * The 'removed' section contains the signatures that were removed in php 8.2
 * The 'changed' section contains functions for which the signature has changed for php 8.2.
 *     Each function in the 'changed' section has an 'old' and a 'new' section,
 *     representing the function as it was in PHP 8.1 and in PHP 8.2, respectively
 *
 * @see CallMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
  'added' => [
    'mysqli_execute_query' => ['mysqli_result|bool', 'mysqli'=>'mysqli', 'query'=>'non-empty-string', 'params='=>'list<mixed>|null'],
    'mysqli::execute_query' => ['mysqli_result|bool', 'query'=>'non-empty-string', 'params='=>'list<mixed>|null'],
    'openssl_cipher_key_length' => ['positive-int|false', 'cipher_algo'=>'non-empty-string'],
    'curl_upkeep' => ['bool', 'handle'=>'CurlHandle'],
    'imap_is_open' => ['bool', 'imap'=>'IMAP\Connection'],
    'ini_parse_quantity' => ['int', 'shorthand'=>'non-empty-string'],
    'libxml_get_external_entity_loader' => ['(callable(string,string,array{directory:?string,intSubName:?string,extSubURI:?string,extSubSystem:?string}):(resource|string|null))|null'],
    'memory_reset_peak_usage' => ['void'],
    'sodium_crypto_stream_xchacha20_xor_ic' => ['string', 'message'=>'string', 'nonce'=>'non-empty-string', 'counter'=>'int', 'key'=>'non-empty-string'],
    'ZipArchive::clearError' => ['void'],
    'ZipArchive::getStreamIndex' => ['resource|false', 'index'=>'int', 'flags='=>'int'],
    'ZipArchive::getStreamName' => ['resource|false', 'name'=>'string', 'flags='=>'int'],
    'DateTimeInterface::__serialize' => ['array'],
    'DateTimeInterface::__unserialize' => ['void', 'data'=>'array'],
  ],

  'changed' => [
    'str_split' => [
       'old' => ['non-empty-list<string>', 'string'=>'string', 'length='=>'positive-int'],
       'new' => ['list<string>', 'string'=>'string', 'length='=>'positive-int'],
    ],
  ],

  'removed' => [
  ],
];
<?php // phpcs:ignoreFile
namespace Phan\Language\Internal;

/**
 * CURRENT PHP TARGET VERSION: 8.2
 * The version above has to match Psalm\Internal\Codebase\InternalCallMapHandler::PHP_(MAJOR|MINOR)_VERSION
 *
 * Format
 *
 * '<function_name>' => ['<return_type>, '<arg_name>'=>'<arg_type>']
 * alternative signature for the same function
 * '<function_name\'1>' => ['<return_type>, '<arg_name>'=>'<arg_type>']
 *
 * A '&' in front of the <arg_name> means the arg is always passed by reference.
 * (i.e. ReflectionParameter->isPassedByReference())
 * This was previously only used in cases where the function actually created the
 * variable in the local scope.
 * Some reference arguments will have prefixes in <arg_name> to indicate the way the argument is used.
 * Currently, the only prefixes with meaning are 'rw_' (read-write) and 'w_' (write).
 * Those prefixes don't mean anything for non-references.
 * Code using these signatures should remove those prefixes from messages rendered to the user.
 * 1. '&rw_<arg_name>' indicates that a parameter with a value is expected to be passed in, and may be modified.
 *    Phan will warn if the variable has an incompatible type, or is undefined.
 * 2. '&w_<arg_name>' indicates that a parameter is expected to be passed in, and the value will be ignored, and may be overwritten.
 * 3. The absence of a prefix is treated by Phan the same way as having the prefix 'w_' (Some may be changed to 'rw_name'). These will have prefixes added later.
 *
 * So, for functions like sort() where technically the arg is by-ref,
 * indicate the reference param's signature by-ref and read-write,
 * as `'&rw_array'=>'array'`
 * so that Phan won't create it in the local scope
 *
 * However, for a function like preg_match() where the 3rd arg is an array of sub-pattern matches (and optional),
 * this arg needs to be marked as by-ref and write-only, as `'&w_matches='=>'array'`.
 *
 * A '=' following the <arg_name> indicates this arg is optional.
 *
 * The <arg_name> can begin with '...' to indicate the arg is variadic.
 * '...args=' indicates it is both variadic and optional.
 *
 * Some reference arguments will have prefixes in <arg_name> to indicate the way the argument is used.
 * Currently, the only prefixes with meaning are 'rw_' and 'w_'.
 * Code using these signatures should remove those prefixes from messages rendered to the user.
 * 1. '&rw_name' indicates that a parameter with a value is expected to be passed in, and may be modified.
 * 2. '&w_name' indicates that a parameter is expected to be passed in, and the value will be ignored, and may be overwritten.
 *
 * This file contains the signatures for the most recent minor release of PHP supported by phan (php 7.2)
 *
 * Changes:
 *
 * In Phan 0.12.3,
 *
 * - This started using array shapes for union types (array{...}).
 *
 *   \Phan\Language\UnionType->withFlattenedArrayShapeOrLiteralTypeInstances() may be of help to programmatically convert these to array<string,T1>|array<string,T2>
 *
 * - This started using array shapes with optional fields for union types (array{key?:int}).
 *   A `?` after the array shape field's key indicates that the field is optional.
 *
 * - This started adding param signatures and return signatures to `callable` types.
 *   E.g. 'usort' => ['bool', '&rw_array_arg'=>'array', 'cmp_function'=>'callable(mixed,mixed):int'].
 *   See NEWS.md for 0.12.3 for possible syntax. A suffix of `=` within `callable(...)` means that a parameter is optional.
 *
 *   (Phan assumes that callbacks with optional arguments can be cast to callbacks with/without those args (Similar to inheritance checks)
 *   (e.g. callable(T1,T2=) can be cast to callable(T1) or callable(T1,T2), in the same way that a subclass would check).
 *   For some signatures, e.g. set_error_handler, this results in repetition, because callable(T1=) can't cast to callable(T1).
 *
 * Sources of stub info:
 *
 * 1. Reflection
 * 2. docs.php.net's SVN repo or website, and examples (See internal/internalsignatures.php)
 *
 *    See https://secure.php.net/manual/en/copyright.php
 *
 *    The PHP manual text and comments are covered by the [Creative Commons Attribution 3.0 License](http://creativecommons.org/licenses/by/3.0/legalcode),
 *    copyright (c) the PHP Documentation Group
 * 3. Various websites documenting individual extensions
 * 4. PHPStorm stubs (For anything missing from the above sources)
 *    See internal/internalsignatures.php
 *
 *    Available from https://github.com/JetBrains/phpstorm-stubs under the [Apache 2 license](https://www.apache.org/licenses/LICENSE-2.0)
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 *
 * Note: Some of Phan's inferences about return types are written as plugins for functions/methods where the return type depends on the parameter types.
 * E.g. src/Phan/Plugin/Internal/DependentReturnTypeOverridePlugin.php is one plugin
 */
return [
'_' => ['string', 'message'=>'string'],
'__halt_compiler' => ['void'],
'abs' => ['0|positive-int', 'num'=>'int'],
'abs\'1' => ['float', 'num'=>'float'],
'abs\'2' => ['numeric', 'num'=>'numeric'],
'accelerator_get_configuration' => ['array'],
'accelerator_get_scripts' => ['array'],
'accelerator_get_status' => ['array', 'fetch_scripts'=>'bool'],
'accelerator_reset' => [''],
'accelerator_set_status' => ['void', 'status'=>'bool'],
'acos' => ['float', 'num'=>'float'],
'acosh' => ['float', 'num'=>'float'],
'addcslashes' => ['string', 'string'=>'string', 'characters'=>'string'],
'addslashes' => ['string', 'string'=>'string'],
'AMQPBasicProperties::__construct' => ['void', 'content_type='=>'string', 'content_encoding='=>'string', 'headers='=>'array', 'delivery_mode='=>'int', 'priority='=>'int', 'correlation_id='=>'string', 'reply_to='=>'string', 'expiration='=>'string', 'message_id='=>'string', 'timestamp='=>'int', 'type='=>'string', 'user_id='=>'string', 'app_id='=>'string', 'cluster_id='=>'string'],
'AMQPBasicProperties::getAppId' => ['string'],
'AMQPBasicProperties::getClusterId' => ['string'],
'AMQPBasicProperties::getContentEncoding' => ['string'],
'AMQPBasicProperties::getContentType' => ['string'],
'AMQPBasicProperties::getCorrelationId' => ['string'],
'AMQPBasicProperties::getDeliveryMode' => ['int'],
'AMQPBasicProperties::getExpiration' => ['string'],
'AMQPBasicProperties::getHeaders' => ['array'],
'AMQPBasicProperties::getMessageId' => ['string'],
'AMQPBasicProperties::getPriority' => ['int'],
'AMQPBasicProperties::getReplyTo' => ['string'],
'AMQPBasicProperties::getTimestamp' => ['string'],
'AMQPBasicProperties::getType' => ['string'],
'AMQPBasicProperties::getUserId' => ['string'],
'AMQPChannel::__construct' => ['void', 'amqp_connection'=>'AMQPConnection'],
'AMQPChannel::basicRecover' => ['', 'requeue='=>'bool'],
'AMQPChannel::close' => [''],
'AMQPChannel::commitTransaction' => ['bool'],
'AMQPChannel::confirmSelect' => [''],
'AMQPChannel::getChannelId' => ['int'],
'AMQPChannel::getConnection' => ['AMQPConnection'],
'AMQPChannel::getConsumers' => ['AMQPQueue[]'],
'AMQPChannel::getPrefetchCount' => ['int'],
'AMQPChannel::getPrefetchSize' => ['int'],
'AMQPChannel::isConnected' => ['bool'],
'AMQPChannel::qos' => ['bool', 'size'=>'int', 'count'=>'int'],
'AMQPChannel::rollbackTransaction' => ['bool'],
'AMQPChannel::setConfirmCallback' => ['', 'ack_callback='=>'?callable', 'nack_callback='=>'?callable'],
'AMQPChannel::setPrefetchCount' => ['bool', 'count'=>'int'],
'AMQPChannel::setPrefetchSize' => ['bool', 'size'=>'int'],
'AMQPChannel::setReturnCallback' => ['', 'return_callback='=>'?callable'],
'AMQPChannel::startTransaction' => ['bool'],
'AMQPChannel::waitForBasicReturn' => ['', 'timeout='=>'float'],
'AMQPChannel::waitForConfirm' => ['', 'timeout='=>'float'],
'AMQPConnection::__construct' => ['void', 'credentials='=>'array'],
'AMQPConnection::connect' => ['bool'],
'AMQPConnection::disconnect' => ['bool'],
'AMQPConnection::getCACert' => ['string'],
'AMQPConnection::getCert' => ['string'],
'AMQPConnection::getHeartbeatInterval' => ['int'],
'AMQPConnection::getHost' => ['string'],
'AMQPConnection::getKey' => ['string'],
'AMQPConnection::getLogin' => ['string'],
'AMQPConnection::getMaxChannels' => ['?int'],
'AMQPConnection::getMaxFrameSize' => ['int'],
'AMQPConnection::getPassword' => ['string'],
'AMQPConnection::getPort' => ['int'],
'AMQPConnection::getReadTimeout' => ['float'],
'AMQPConnection::getTimeout' => ['float'],
'AMQPConnection::getUsedChannels' => ['int'],
'AMQPConnection::getVerify' => ['bool'],
'AMQPConnection::getVhost' => ['string'],
'AMQPConnection::getWriteTimeout' => ['float'],
'AMQPConnection::isConnected' => ['bool'],
'AMQPConnection::isPersistent' => ['?bool'],
'AMQPConnection::pconnect' => ['bool'],
'AMQPConnection::pdisconnect' => ['bool'],
'AMQPConnection::preconnect' => ['bool'],
'AMQPConnection::reconnect' => ['bool'],
'AMQPConnection::setCACert' => ['', 'cacert'=>'string'],
'AMQPConnection::setCert' => ['', 'cert'=>'string'],
'AMQPConnection::setHost' => ['bool', 'host'=>'string'],
'AMQPConnection::setKey' => ['', 'key'=>'string'],
'AMQPConnection::setLogin' => ['bool', 'login'=>'string'],
'AMQPConnection::setPassword' => ['bool', 'password'=>'string'],
'AMQPConnection::setPort' => ['bool', 'port'=>'int'],
'AMQPConnection::setReadTimeout' => ['bool', 'timeout'=>'int'],
'AMQPConnection::setTimeout' => ['bool', 'timeout'=>'int'],
'AMQPConnection::setVerify' => ['', 'verify'=>'bool'],
'AMQPConnection::setVhost' => ['bool', 'vhost'=>'string'],
'AMQPConnection::setWriteTimeout' => ['bool', 'timeout'=>'int'],
'AMQPDecimal::__construct' => ['void', 'exponent'=>'', 'significand'=>''],
'AMQPDecimal::getExponent' => ['int'],
'AMQPDecimal::getSignificand' => ['int'],
'AMQPEnvelope::__construct' => ['void'],
'AMQPEnvelope::getAppId' => ['string'],
'AMQPEnvelope::getBody' => ['string'],
'AMQPEnvelope::getClusterId' => ['string'],
'AMQPEnvelope::getConsumerTag' => ['string'],
'AMQPEnvelope::getContentEncoding' => ['string'],
'AMQPEnvelope::getContentType' => ['string'],
'AMQPEnvelope::getCorrelationId' => ['string'],
'AMQPEnvelope::getDeliveryMode' => ['int'],
'AMQPEnvelope::getDeliveryTag' => ['string'],
'AMQPEnvelope::getExchangeName' => ['string'],
'AMQPEnvelope::getExpiration' => ['string'],
'AMQPEnvelope::getHeader' => ['string|false', 'header_key'=>'string'],
'AMQPEnvelope::getHeaders' => ['array'],
'AMQPEnvelope::getMessageId' => ['string'],
'AMQPEnvelope::getPriority' => ['int'],
'AMQPEnvelope::getReplyTo' => ['string'],
'AMQPEnvelope::getRoutingKey' => ['string'],
'AMQPEnvelope::getTimeStamp' => ['string'],
'AMQPEnvelope::getType' => ['string'],
'AMQPEnvelope::getUserId' => ['string'],
'AMQPEnvelope::hasHeader' => ['bool', 'header_key'=>'string'],
'AMQPEnvelope::isRedelivery' => ['bool'],
'AMQPExchange::__construct' => ['void', 'amqp_channel'=>'AMQPChannel'],
'AMQPExchange::bind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
'AMQPExchange::declareExchange' => ['bool'],
'AMQPExchange::delete' => ['bool', 'exchangeName='=>'string', 'flags='=>'int'],
'AMQPExchange::getArgument' => ['int|string|false', 'key'=>'string'],
'AMQPExchange::getArguments' => ['array'],
'AMQPExchange::getChannel' => ['AMQPChannel'],
'AMQPExchange::getConnection' => ['AMQPConnection'],
'AMQPExchange::getFlags' => ['int'],
'AMQPExchange::getName' => ['string'],
'AMQPExchange::getType' => ['string'],
'AMQPExchange::hasArgument' => ['bool', 'key'=>'string'],
'AMQPExchange::publish' => ['bool', 'message'=>'string', 'routing_key='=>'string', 'flags='=>'int', 'attributes='=>'array'],
'AMQPExchange::setArgument' => ['bool', 'key'=>'string', 'value'=>'int|string'],
'AMQPExchange::setArguments' => ['bool', 'arguments'=>'array'],
'AMQPExchange::setFlags' => ['bool', 'flags'=>'int'],
'AMQPExchange::setName' => ['bool', 'exchange_name'=>'string'],
'AMQPExchange::setType' => ['bool', 'exchange_type'=>'string'],
'AMQPExchange::unbind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
'AMQPQueue::__construct' => ['void', 'amqp_channel'=>'AMQPChannel'],
'AMQPQueue::ack' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'],
'AMQPQueue::bind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
'AMQPQueue::cancel' => ['bool', 'consumer_tag='=>'string'],
'AMQPQueue::consume' => ['void', 'callback='=>'?callable', 'flags='=>'int', 'consumerTag='=>'string'],
'AMQPQueue::declareQueue' => ['int'],
'AMQPQueue::delete' => ['int', 'flags='=>'int'],
'AMQPQueue::get' => ['AMQPEnvelope|false', 'flags='=>'int'],
'AMQPQueue::getArgument' => ['int|string|false', 'key'=>'string'],
'AMQPQueue::getArguments' => ['array'],
'AMQPQueue::getChannel' => ['AMQPChannel'],
'AMQPQueue::getConnection' => ['AMQPConnection'],
'AMQPQueue::getConsumerTag' => ['?string'],
'AMQPQueue::getFlags' => ['int'],
'AMQPQueue::getName' => ['string'],
'AMQPQueue::hasArgument' => ['bool', 'key'=>'string'],
'AMQPQueue::nack' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'],
'AMQPQueue::purge' => ['bool'],
'AMQPQueue::reject' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'],
'AMQPQueue::setArgument' => ['bool', 'key'=>'string', 'value'=>'mixed'],
'AMQPQueue::setArguments' => ['bool', 'arguments'=>'array'],
'AMQPQueue::setFlags' => ['bool', 'flags'=>'int'],
'AMQPQueue::setName' => ['bool', 'queue_name'=>'string'],
'AMQPQueue::unbind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'],
'AMQPTimestamp::__construct' => ['void', 'timestamp'=>'string'],
'AMQPTimestamp::__toString' => ['string'],
'AMQPTimestamp::getTimestamp' => ['string'],
'apache_child_terminate' => ['bool'],
'apache_get_modules' => ['array'],
'apache_get_version' => ['string|false'],
'apache_getenv' => ['string|false', 'variable'=>'string', 'walk_to_top='=>'bool'],
'apache_lookup_uri' => ['object', 'filename'=>'string'],
'apache_note' => ['string|false', 'note_name'=>'string', 'note_value='=>'string'],
'apache_request_headers' => ['array|false'],
'apache_reset_timeout' => ['bool'],
'apache_response_headers' => ['array|false'],
'apache_setenv' => ['bool', 'variable'=>'string', 'value'=>'string', 'walk_to_top='=>'bool'],
'apc_add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'ttl='=>'int'],
'apc_add\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
'apc_bin_dump' => ['string|false|null', 'files='=>'array', 'user_vars='=>'array'],
'apc_bin_dumpfile' => ['int|false', 'files'=>'array', 'user_vars'=>'array', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
'apc_bin_load' => ['bool', 'data'=>'string', 'flags='=>'int'],
'apc_bin_loadfile' => ['bool', 'filename'=>'string', 'context='=>'resource', 'flags='=>'int'],
'apc_cache_info' => ['array|false', 'cache_type='=>'string', 'limited='=>'bool'],
'apc_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'],
'apc_clear_cache' => ['bool', 'cache_type='=>'string'],
'apc_compile_file' => ['bool', 'filename'=>'string', 'atomic='=>'bool'],
'apc_dec' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'],
'apc_define_constants' => ['bool', 'key'=>'string', 'constants'=>'array', 'case_sensitive='=>'bool'],
'apc_delete' => ['bool', 'key'=>'string|string[]|APCIterator'],
'apc_delete_file' => ['bool|string[]', 'keys'=>'mixed'],
'apc_exists' => ['bool', 'keys'=>'string'],
'apc_exists\'1' => ['array', 'keys'=>'string[]'],
'apc_fetch' => ['mixed|false', 'key'=>'string', '&w_success='=>'bool'],
'apc_fetch\'1' => ['array|false', 'key'=>'string[]', '&w_success='=>'bool'],
'apc_inc' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'],
'apc_load_constants' => ['bool', 'key'=>'string', 'case_sensitive='=>'bool'],
'apc_sma_info' => ['array|false', 'limited='=>'bool'],
'apc_store' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'],
'apc_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
'APCIterator::__construct' => ['void', 'cache'=>'string', 'search='=>'null|string|string[]', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'],
'APCIterator::current' => ['mixed|false'],
'APCIterator::getTotalCount' => ['int|false'],
'APCIterator::getTotalHits' => ['int|false'],
'APCIterator::getTotalSize' => ['int|false'],
'APCIterator::key' => ['string'],
'APCIterator::next' => ['void'],
'APCIterator::rewind' => ['void'],
'APCIterator::valid' => ['bool'],
'apcu_add' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'],
'apcu_add\'1' => ['array<string,int>', 'values'=>'array<string,mixed>', 'unused='=>'', 'ttl='=>'int'],
'apcu_cache_info' => ['array<string,mixed>|false', 'limited='=>'bool'],
'apcu_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'],
'apcu_clear_cache' => ['bool'],
'apcu_dec' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool', 'ttl='=>'int'],
'apcu_delete' => ['bool', 'key'=>'string|APCuIterator'],
'apcu_delete\'1' => ['list<string>', 'key'=>'string[]'],
'apcu_enabled' => ['bool'],
'apcu_entry' => ['mixed', 'key'=>'string', 'generator'=>'callable', 'ttl='=>'int'],
'apcu_exists' => ['bool', 'keys'=>'string'],
'apcu_exists\'1' => ['array', 'keys'=>'string[]'],
'apcu_fetch' => ['mixed|false', 'key'=>'string', '&w_success='=>'bool'],
'apcu_fetch\'1' => ['array|false', 'key'=>'string[]', '&w_success='=>'bool'],
'apcu_inc' => ['int|false', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool', 'ttl='=>'int'],
'apcu_key_info' => ['?array', 'key'=>'string'],
'apcu_sma_info' => ['array|false', 'limited='=>'bool'],
'apcu_store' => ['bool', 'key'=>'string', 'var='=>'', 'ttl='=>'int'],
'apcu_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
'APCuIterator::__construct' => ['void', 'search='=>'string|string[]|null', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'],
'APCuIterator::current' => ['mixed'],
'APCuIterator::getTotalCount' => ['int'],
'APCuIterator::getTotalHits' => ['int'],
'APCuIterator::getTotalSize' => ['int'],
'APCuIterator::key' => ['string'],
'APCuIterator::next' => ['void'],
'APCuIterator::rewind' => ['void'],
'APCuIterator::valid' => ['bool'],
'apd_breakpoint' => ['bool', 'debug_level'=>'int'],
'apd_callstack' => ['array'],
'apd_clunk' => ['void', 'warning'=>'string', 'delimiter='=>'string'],
'apd_continue' => ['bool', 'debug_level'=>'int'],
'apd_croak' => ['void', 'warning'=>'string', 'delimiter='=>'string'],
'apd_dump_function_table' => ['void'],
'apd_dump_persistent_resources' => ['array'],
'apd_dump_regular_resources' => ['array'],
'apd_echo' => ['bool', 'output'=>'string'],
'apd_get_active_symbols' => ['array'],
'apd_set_pprof_trace' => ['string', 'dump_directory='=>'string', 'fragment='=>'string'],
'apd_set_session' => ['void', 'debug_level'=>'int'],
'apd_set_session_trace' => ['void', 'debug_level'=>'int', 'dump_directory='=>'string'],
'apd_set_session_trace_socket' => ['bool', 'tcp_server'=>'string', 'socket_type'=>'int', 'port'=>'int', 'debug_level'=>'int'],
'AppendIterator::__construct' => ['void'],
'AppendIterator::append' => ['void', 'iterator'=>'Iterator'],
'AppendIterator::current' => ['mixed'],
'AppendIterator::getArrayIterator' => ['ArrayIterator'],
'AppendIterator::getInnerIterator' => ['Iterator'],
'AppendIterator::getIteratorIndex' => ['int'],
'AppendIterator::key' => ['int|string|float|bool'],
'AppendIterator::next' => ['void'],
'AppendIterator::rewind' => ['void'],
'AppendIterator::valid' => ['bool'],
'ArgumentCountError::__clone' => ['void'],
'ArgumentCountError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'ArgumentCountError::__toString' => ['string'],
'ArgumentCountError::__wakeup' => ['void'],
'ArgumentCountError::getCode' => ['int'],
'ArgumentCountError::getFile' => ['string'],
'ArgumentCountError::getLine' => ['int'],
'ArgumentCountError::getMessage' => ['string'],
'ArgumentCountError::getPrevious' => ['?Throwable'],
'ArgumentCountError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'ArgumentCountError::getTraceAsString' => ['string'],
'ArithmeticError::__clone' => ['void'],
'ArithmeticError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'ArithmeticError::__toString' => ['string'],
'ArithmeticError::__wakeup' => ['void'],
'ArithmeticError::getCode' => ['int'],
'ArithmeticError::getFile' => ['string'],
'ArithmeticError::getLine' => ['int'],
'ArithmeticError::getMessage' => ['string'],
'ArithmeticError::getPrevious' => ['?Throwable'],
'ArithmeticError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'ArithmeticError::getTraceAsString' => ['string'],
'array_change_key_case' => ['associative-array', 'array'=>'array', 'case='=>'int'],
'array_chunk' => ['list<array[]>', 'array'=>'array', 'length'=>'int', 'preserve_keys='=>'bool'],
'array_column' => ['array', 'array'=>'array', 'column_key'=>'int|string|null', 'index_key='=>'int|string|null'],
'array_combine' => ['associative-array', 'keys'=>'string[]|int[]', 'values'=>'array'],
'array_count_values' => ['associative-array<mixed,int>', 'array'=>'array'],
'array_diff' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
'array_diff_assoc' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
'array_diff_key' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
'array_diff_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int'],
'array_diff_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
'array_diff_ukey' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_comp_func'=>'callable(mixed,mixed):int'],
'array_diff_ukey\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
'array_fill' => ['array<int,mixed>', 'start_index'=>'int', 'count'=>'int', 'value'=>'mixed'],
'array_fill_keys' => ['array', 'keys'=>'array', 'value'=>'mixed'],
'array_filter' => ['associative-array', 'array'=>'array', 'callback='=>'callable(mixed,mixed=):scalar|null', 'mode='=>'int'],
'array_flip' => ['associative-array<mixed,int>|associative-array<mixed,string>', 'array'=>'array'],
'array_intersect' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
'array_intersect_assoc' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
'array_intersect_key' => ['associative-array', 'array'=>'array', '...arrays='=>'array'],
'array_intersect_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_compare_func'=>'callable(mixed,mixed):int'],
'array_intersect_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable(mixed,mixed):int'],
'array_intersect_ukey' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_compare_func'=>'callable(mixed,mixed):int'],
'array_intersect_ukey\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest'=>'array|callable(mixed,mixed):int'],
'array_is_list' => ['bool', 'array'=>'array'],
'array_key_exists' => ['bool', 'key'=>'string|int', 'array'=>'array'],
'array_key_first' => ['int|string|null', 'array'=>'array'],
'array_key_last' => ['int|string|null', 'array'=>'array'],
'array_keys' => ['list<string|int>', 'array'=>'array', 'filter_value='=>'mixed', 'strict='=>'bool'],
'array_map' => ['array', 'callback'=>'?callable', 'array'=>'array', '...arrays='=>'array'],
'array_merge' => ['array', '...arrays='=>'array'],
'array_merge_recursive' => ['array', '...arrays='=>'array'],
'array_multisort' => ['bool', '&rw_array'=>'array', 'rest='=>'array|int', 'array1_sort_flags='=>'array|int', '...args='=>'array|int'],
'array_pad' => ['array', 'array'=>'array', 'length'=>'int', 'value'=>'mixed'],
'array_pop' => ['mixed', '&rw_array'=>'array'],
'array_product' => ['int|float', 'array'=>'array'],
'array_push' => ['int', '&rw_array'=>'array', '...values='=>'mixed'],
'array_rand' => ['int|string|array<int,int>|array<int,string>', 'array'=>'non-empty-array', 'num'=>'int'],
'array_rand\'1' => ['int|string', 'array'=>'array'],
'array_reduce' => ['mixed', 'array'=>'array', 'callback'=>'callable(mixed,mixed):mixed', 'initial='=>'mixed'],
'array_replace' => ['array', 'array'=>'array', '...replacements='=>'array'],
'array_replace_recursive' => ['array', 'array'=>'array', '...replacements='=>'array'],
'array_reverse' => ['array', 'array'=>'array', 'preserve_keys='=>'bool'],
'array_search' => ['int|string|false', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'],
'array_shift' => ['mixed|null', '&rw_array'=>'array'],
'array_slice' => ['array', 'array'=>'array', 'offset'=>'int', 'length='=>'?int', 'preserve_keys='=>'bool'],
'array_splice' => ['array', '&rw_array'=>'array', 'offset'=>'int', 'length='=>'?int', 'replacement='=>'array|string'],
'array_sum' => ['int|float', 'array'=>'array'],
'array_udiff' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int'],
'array_udiff\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
'array_udiff_assoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'key_comp_func'=>'callable(mixed,mixed):int'],
'array_udiff_assoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
'array_udiff_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_comp_func'=>'callable(mixed,mixed):int', 'key_comp_func'=>'callable(mixed,mixed):int'],
'array_udiff_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', 'arg5'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
'array_uintersect' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int'],
'array_uintersect\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
'array_uintersect_assoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int'],
'array_uintersect_assoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable(mixed,mixed):int'],
'array_uintersect_uassoc' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'data_compare_func'=>'callable(mixed,mixed):int', 'key_compare_func'=>'callable(mixed,mixed):int'],
'array_uintersect_uassoc\'1' => ['associative-array', 'array'=>'array', 'rest'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable(mixed,mixed):int', 'arg5'=>'array|callable(mixed,mixed):int', '...rest='=>'array|callable(mixed,mixed):int'],
'array_unique' => ['array', 'array'=>'array', 'flags='=>'0'],
'array_unique\'1' => ['array<int|float|string|null>', 'array'=>'array<int|float|string|null>', 'flags='=>'1'],
'array_unique\'2' => ['array<int|float|string|bool|\Stringable|null>', 'array'=>'array<int|float|string|bool|\Stringable|null>', 'flags='=>'2|5'],
'array_unshift' => ['int', '&rw_array'=>'array', '...values='=>'mixed'],
'array_values' => ['list<mixed>', 'array'=>'array'],
'array_walk' => ['bool', '&rw_array'=>'array', 'callback'=>'callable', 'arg='=>'mixed'],
'array_walk\'1' => ['bool', '&rw_array'=>'object', 'callback'=>'callable', 'arg='=>'mixed'],
'array_walk_recursive' => ['bool', '&rw_array'=>'array', 'callback'=>'callable', 'arg='=>'mixed'],
'array_walk_recursive\'1' => ['bool', '&rw_array'=>'object', 'callback'=>'callable', 'arg='=>'mixed'],
'ArrayAccess::offsetExists' => ['bool', 'offset'=>'mixed'],
'ArrayAccess::offsetGet' => ['mixed', 'offset'=>'mixed'],
'ArrayAccess::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
'ArrayAccess::offsetUnset' => ['void', 'offset'=>'mixed'],
'ArrayIterator::__construct' => ['void', 'array='=>'array|object', 'flags='=>'int'],
'ArrayIterator::append' => ['void', 'value'=>'mixed'],
'ArrayIterator::asort' => ['void'],
'ArrayIterator::count' => ['int'],
'ArrayIterator::current' => ['mixed'],
'ArrayIterator::getArrayCopy' => ['array'],
'ArrayIterator::getFlags' => ['int'],
'ArrayIterator::key' => ['int|string|null'],
'ArrayIterator::ksort' => ['void'],
'ArrayIterator::natcasesort' => ['true'],
'ArrayIterator::natsort' => ['true'],
'ArrayIterator::next' => ['void'],
'ArrayIterator::offsetExists' => ['bool', 'index'=>'string|int'],
'ArrayIterator::offsetGet' => ['mixed', 'index'=>'string|int'],
'ArrayIterator::offsetSet' => ['void', 'index'=>'string|int', 'newval'=>'mixed'],
'ArrayIterator::offsetUnset' => ['void', 'index'=>'string|int'],
'ArrayIterator::rewind' => ['void'],
'ArrayIterator::seek' => ['void', 'position'=>'int'],
'ArrayIterator::serialize' => ['string'],
'ArrayIterator::setFlags' => ['void', 'flags'=>'string'],
'ArrayIterator::uasort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
'ArrayIterator::uksort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
'ArrayIterator::unserialize' => ['void', 'serialized'=>'string'],
'ArrayIterator::valid' => ['bool'],
'ArrayObject::__construct' => ['void', 'input='=>'array|object', 'flags='=>'int', 'iterator_class='=>'string'],
'ArrayObject::append' => ['void', 'value'=>'mixed'],
'ArrayObject::asort' => ['void'],
'ArrayObject::count' => ['int'],
'ArrayObject::exchangeArray' => ['array', 'ar'=>'mixed'],
'ArrayObject::getArrayCopy' => ['array'],
'ArrayObject::getFlags' => ['int'],
'ArrayObject::getIterator' => ['ArrayIterator'],
'ArrayObject::getIteratorClass' => ['string'],
'ArrayObject::ksort' => ['void'],
'ArrayObject::natcasesort' => ['true'],
'ArrayObject::natsort' => ['true'],
'ArrayObject::offsetExists' => ['bool', 'index'=>'int|string'],
'ArrayObject::offsetGet' => ['mixed|null', 'index'=>'int|string'],
'ArrayObject::offsetSet' => ['void', 'index'=>'int|string', 'newval'=>'mixed'],
'ArrayObject::offsetUnset' => ['void', 'index'=>'int|string'],
'ArrayObject::serialize' => ['string'],
'ArrayObject::setFlags' => ['void', 'flags'=>'int'],
'ArrayObject::setIteratorClass' => ['void', 'iterator_class'=>'string'],
'ArrayObject::uasort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
'ArrayObject::uksort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
'ArrayObject::unserialize' => ['void', 'serialized'=>'string'],
'arsort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
'asin' => ['float', 'num'=>'float'],
'asinh' => ['float', 'num'=>'float'],
'asort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
'assert' => ['bool', 'assertion'=>'string|bool|int', 'description='=>'string|Throwable|null'],
'assert_options' => ['mixed|false', 'option'=>'int', 'value='=>'mixed'],
'ast\get_kind_name' => ['string', 'kind'=>'int'],
'ast\get_metadata' => ['array<int,ast\Metadata>'],
'ast\get_supported_versions' => ['array<int,int>', 'exclude_deprecated='=>'bool'],
'ast\kind_uses_flags' => ['bool', 'kind'=>'int'],
'ast\Node::__construct' => ['void', 'kind='=>'int', 'flags='=>'int', 'children='=>'ast\Node\Decl[]|ast\Node[]|int[]|string[]|float[]|bool[]|null[]', 'start_line='=>'int'],
'ast\parse_code' => ['ast\Node', 'code'=>'string', 'version'=>'int', 'filename='=>'string'],
'ast\parse_file' => ['ast\Node', 'filename'=>'string', 'version'=>'int'],
'atan' => ['float', 'num'=>'float'],
'atan2' => ['float', 'y'=>'float', 'x'=>'float'],
'atanh' => ['float', 'num'=>'float'],
'BadFunctionCallException::__clone' => ['void'],
'BadFunctionCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'BadFunctionCallException::__toString' => ['string'],
'BadFunctionCallException::getCode' => ['int'],
'BadFunctionCallException::getFile' => ['string'],
'BadFunctionCallException::getLine' => ['int'],
'BadFunctionCallException::getMessage' => ['string'],
'BadFunctionCallException::getPrevious' => ['?Throwable'],
'BadFunctionCallException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'BadFunctionCallException::getTraceAsString' => ['string'],
'BadMethodCallException::__clone' => ['void'],
'BadMethodCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'BadMethodCallException::__toString' => ['string'],
'BadMethodCallException::getCode' => ['int'],
'BadMethodCallException::getFile' => ['string'],
'BadMethodCallException::getLine' => ['int'],
'BadMethodCallException::getMessage' => ['string'],
'BadMethodCallException::getPrevious' => ['?Throwable'],
'BadMethodCallException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'BadMethodCallException::getTraceAsString' => ['string'],
'base64_decode' => ['string|false', 'string'=>'string', 'strict='=>'bool'],
'base64_encode' => ['string', 'string'=>'string'],
'base_convert' => ['string', 'num'=>'string', 'from_base'=>'int', 'to_base'=>'int'],
'basename' => ['string', 'path'=>'string', 'suffix='=>'string'],
'bbcode_add_element' => ['bool', 'bbcode_container'=>'resource', 'tag_name'=>'string', 'tag_rules'=>'array'],
'bbcode_add_smiley' => ['bool', 'bbcode_container'=>'resource', 'smiley'=>'string', 'replace_by'=>'string'],
'bbcode_create' => ['resource', 'bbcode_initial_tags='=>'array'],
'bbcode_destroy' => ['bool', 'bbcode_container'=>'resource'],
'bbcode_parse' => ['string', 'bbcode_container'=>'resource', 'to_parse'=>'string'],
'bbcode_set_arg_parser' => ['bool', 'bbcode_container'=>'resource', 'bbcode_arg_parser'=>'resource'],
'bbcode_set_flags' => ['bool', 'bbcode_container'=>'resource', 'flags'=>'int', 'mode='=>'int'],
'bcadd' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
'bccomp' => ['int', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
'bcdiv' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int|null'],
'bcmod' => ['numeric-string', 'dividend'=>'numeric-string', 'divisor'=>'numeric-string', 'scale='=>'int|null'],
'bcmul' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
'bcompiler_load' => ['bool', 'filename'=>'string'],
'bcompiler_load_exe' => ['bool', 'filename'=>'string'],
'bcompiler_parse_class' => ['bool', 'class'=>'string', 'callback'=>'string'],
'bcompiler_read' => ['bool', 'filehandle'=>'resource'],
'bcompiler_write_class' => ['bool', 'filehandle'=>'resource', 'classname'=>'string', 'extends='=>'string'],
'bcompiler_write_constant' => ['bool', 'filehandle'=>'resource', 'constantname'=>'string'],
'bcompiler_write_exe_footer' => ['bool', 'filehandle'=>'resource', 'startpos'=>'int'],
'bcompiler_write_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'],
'bcompiler_write_footer' => ['bool', 'filehandle'=>'resource'],
'bcompiler_write_function' => ['bool', 'filehandle'=>'resource', 'functionname'=>'string'],
'bcompiler_write_functions_from_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'],
'bcompiler_write_header' => ['bool', 'filehandle'=>'resource', 'write_ver='=>'string'],
'bcompiler_write_included_filename' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'],
'bcpow' => ['numeric-string', 'num'=>'numeric-string', 'exponent'=>'numeric-string', 'scale='=>'int|null'],
'bcpowmod' => ['numeric-string|false', 'base'=>'numeric-string', 'exponent'=>'numeric-string', 'modulus'=>'numeric-string', 'scale='=>'int|null'],
'bcscale' => ['int', 'scale='=>'int|null'],
'bcsqrt' => ['numeric-string', 'num'=>'numeric-string', 'scale='=>'int|null'],
'bcsub' => ['numeric-string', 'num1'=>'numeric-string', 'num2'=>'numeric-string', 'scale='=>'int|null'],
'bin2hex' => ['string', 'string'=>'string'],
'bind_textdomain_codeset' => ['string', 'domain'=>'string', 'codeset'=>'?string'],
'bindec' => ['float|int', 'binary_string'=>'string'],
'bindtextdomain' => ['string', 'domain'=>'string', 'directory'=>'?string'],
'birdstep_autocommit' => ['bool', 'index'=>'int'],
'birdstep_close' => ['bool', 'id'=>'int'],
'birdstep_commit' => ['bool', 'index'=>'int'],
'birdstep_connect' => ['int', 'server'=>'string', 'user'=>'string', 'pass'=>'string'],
'birdstep_exec' => ['int', 'index'=>'int', 'exec_str'=>'string'],
'birdstep_fetch' => ['bool', 'index'=>'int'],
'birdstep_fieldname' => ['string', 'index'=>'int', 'col'=>'int'],
'birdstep_fieldnum' => ['int', 'index'=>'int'],
'birdstep_freeresult' => ['bool', 'index'=>'int'],
'birdstep_off_autocommit' => ['bool', 'index'=>'int'],
'birdstep_result' => ['', 'index'=>'int', 'col'=>''],
'birdstep_rollback' => ['bool', 'index'=>'int'],
'blenc_encrypt' => ['string', 'plaintext'=>'string', 'encodedfile'=>'string', 'encryption_key='=>'string'],
'boolval' => ['bool', 'value'=>'mixed'],
'bson_decode' => ['array', 'bson'=>'string'],
'bson_encode' => ['string', 'anything'=>'mixed'],
'bzclose' => ['bool', 'bz'=>'resource'],
'bzcompress' => ['string|int', 'data'=>'string', 'block_size='=>'int', 'work_factor='=>'int'],
'bzdecompress' => ['string|int', 'data'=>'string', 'use_less_memory='=>'int'],
'bzerrno' => ['int', 'bz'=>'resource'],
'bzerror' => ['array', 'bz'=>'resource'],
'bzerrstr' => ['string', 'bz'=>'resource'],
'bzflush' => ['bool', 'bz'=>'resource'],
'bzopen' => ['resource|false', 'file'=>'string|resource', 'mode'=>'string'],
'bzread' => ['string|false', 'bz'=>'resource', 'length='=>'int'],
'bzwrite' => ['int|false', 'bz'=>'resource', 'data'=>'string', 'length='=>'?int'],
'CachingIterator::__construct' => ['void', 'iterator'=>'Iterator', 'flags='=>''],
'CachingIterator::__toString' => ['string'],
'CachingIterator::count' => ['int'],
'CachingIterator::current' => ['mixed'],
'CachingIterator::getCache' => ['array'],
'CachingIterator::getFlags' => ['int'],
'CachingIterator::getInnerIterator' => ['Iterator'],
'CachingIterator::hasNext' => ['bool'],
'CachingIterator::key' => ['int|string|float|bool'],
'CachingIterator::next' => ['void'],
'CachingIterator::offsetExists' => ['bool', 'index'=>'string'],
'CachingIterator::offsetGet' => ['mixed', 'index'=>'string'],
'CachingIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'mixed'],
'CachingIterator::offsetUnset' => ['void', 'index'=>'string'],
'CachingIterator::rewind' => ['void'],
'CachingIterator::setFlags' => ['void', 'flags'=>'int'],
'CachingIterator::valid' => ['bool'],
'Cairo::availableFonts' => ['array'],
'Cairo::availableSurfaces' => ['array'],
'Cairo::statusToString' => ['string', 'status'=>'int'],
'Cairo::version' => ['int'],
'Cairo::versionString' => ['string'],
'cairo_append_path' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'],
'cairo_arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
'cairo_arc_negative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
'cairo_available_fonts' => ['array'],
'cairo_available_surfaces' => ['array'],
'cairo_clip' => ['', 'context'=>'cairocontext'],
'cairo_clip_extents' => ['array', 'context'=>'cairocontext'],
'cairo_clip_preserve' => ['', 'context'=>'cairocontext'],
'cairo_clip_rectangle_list' => ['array', 'context'=>'cairocontext'],
'cairo_close_path' => ['', 'context'=>'cairocontext'],
'cairo_copy_page' => ['', 'context'=>'cairocontext'],
'cairo_copy_path' => ['CairoPath', 'context'=>'cairocontext'],
'cairo_copy_path_flat' => ['CairoPath', 'context'=>'cairocontext'],
'cairo_create' => ['CairoContext', 'surface'=>'cairosurface'],
'cairo_curve_to' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'],
'cairo_device_to_user' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
'cairo_device_to_user_distance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
'cairo_fill' => ['', 'context'=>'cairocontext'],
'cairo_fill_extents' => ['array', 'context'=>'cairocontext'],
'cairo_fill_preserve' => ['', 'context'=>'cairocontext'],
'cairo_font_extents' => ['array', 'context'=>'cairocontext'],
'cairo_font_face_get_type' => ['int', 'fontface'=>'cairofontface'],
'cairo_font_face_status' => ['int', 'fontface'=>'cairofontface'],
'cairo_font_options_create' => ['CairoFontOptions'],
'cairo_font_options_equal' => ['bool', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'],
'cairo_font_options_get_antialias' => ['int', 'options'=>'cairofontoptions'],
'cairo_font_options_get_hint_metrics' => ['int', 'options'=>'cairofontoptions'],
'cairo_font_options_get_hint_style' => ['int', 'options'=>'cairofontoptions'],
'cairo_font_options_get_subpixel_order' => ['int', 'options'=>'cairofontoptions'],
'cairo_font_options_hash' => ['int', 'options'=>'cairofontoptions'],
'cairo_font_options_merge' => ['void', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'],
'cairo_font_options_set_antialias' => ['void', 'options'=>'cairofontoptions', 'antialias'=>'int'],
'cairo_font_options_set_hint_metrics' => ['void', 'options'=>'cairofontoptions', 'hint_metrics'=>'int'],
'cairo_font_options_set_hint_style' => ['void', 'options'=>'cairofontoptions', 'hint_style'=>'int'],
'cairo_font_options_set_subpixel_order' => ['void', 'options'=>'cairofontoptions', 'subpixel_order'=>'int'],
'cairo_font_options_status' => ['int', 'options'=>'cairofontoptions'],
'cairo_format_stride_for_width' => ['int', 'format'=>'int', 'width'=>'int'],
'cairo_get_antialias' => ['int', 'context'=>'cairocontext'],
'cairo_get_current_point' => ['array', 'context'=>'cairocontext'],
'cairo_get_dash' => ['array', 'context'=>'cairocontext'],
'cairo_get_dash_count' => ['int', 'context'=>'cairocontext'],
'cairo_get_fill_rule' => ['int', 'context'=>'cairocontext'],
'cairo_get_font_face' => ['', 'context'=>'cairocontext'],
'cairo_get_font_matrix' => ['', 'context'=>'cairocontext'],
'cairo_get_font_options' => ['', 'context'=>'cairocontext'],
'cairo_get_group_target' => ['', 'context'=>'cairocontext'],
'cairo_get_line_cap' => ['int', 'context'=>'cairocontext'],
'cairo_get_line_join' => ['int', 'context'=>'cairocontext'],
'cairo_get_line_width' => ['float', 'context'=>'cairocontext'],
'cairo_get_matrix' => ['', 'context'=>'cairocontext'],
'cairo_get_miter_limit' => ['float', 'context'=>'cairocontext'],
'cairo_get_operator' => ['int', 'context'=>'cairocontext'],
'cairo_get_scaled_font' => ['', 'context'=>'cairocontext'],
'cairo_get_source' => ['', 'context'=>'cairocontext'],
'cairo_get_target' => ['', 'context'=>'cairocontext'],
'cairo_get_tolerance' => ['float', 'context'=>'cairocontext'],
'cairo_glyph_path' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'],
'cairo_has_current_point' => ['bool', 'context'=>'cairocontext'],
'cairo_identity_matrix' => ['', 'context'=>'cairocontext'],
'cairo_image_surface_create' => ['CairoImageSurface', 'format'=>'int', 'width'=>'int', 'height'=>'int'],
'cairo_image_surface_create_for_data' => ['CairoImageSurface', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'],
'cairo_image_surface_create_from_png' => ['CairoImageSurface', 'file'=>'string'],
'cairo_image_surface_get_data' => ['string', 'surface'=>'cairoimagesurface'],
'cairo_image_surface_get_format' => ['int', 'surface'=>'cairoimagesurface'],
'cairo_image_surface_get_height' => ['int', 'surface'=>'cairoimagesurface'],
'cairo_image_surface_get_stride' => ['int', 'surface'=>'cairoimagesurface'],
'cairo_image_surface_get_width' => ['int', 'surface'=>'cairoimagesurface'],
'cairo_in_fill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_in_stroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'],
'cairo_mask_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
'cairo_matrix_create_scale' => ['object', 'sx'=>'float', 'sy'=>'float'],
'cairo_matrix_init' => ['object', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'],
'cairo_matrix_init_identity' => ['object'],
'cairo_matrix_init_rotate' => ['object', 'radians'=>'float'],
'cairo_matrix_init_scale' => ['object', 'sx'=>'float', 'sy'=>'float'],
'cairo_matrix_init_translate' => ['object', 'tx'=>'float', 'ty'=>'float'],
'cairo_matrix_invert' => ['void', 'matrix'=>'cairomatrix'],
'cairo_matrix_multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'],
'cairo_matrix_rotate' => ['', 'matrix'=>'cairomatrix', 'radians'=>'float'],
'cairo_matrix_scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'],
'cairo_matrix_transform_distance' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'],
'cairo_matrix_transform_point' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'],
'cairo_matrix_translate' => ['void', 'matrix'=>'cairomatrix', 'tx'=>'float', 'ty'=>'float'],
'cairo_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_new_path' => ['', 'context'=>'cairocontext'],
'cairo_new_sub_path' => ['', 'context'=>'cairocontext'],
'cairo_paint' => ['', 'context'=>'cairocontext'],
'cairo_paint_with_alpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'],
'cairo_path_extents' => ['array', 'context'=>'cairocontext'],
'cairo_pattern_add_color_stop_rgb' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'cairo_pattern_add_color_stop_rgba' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'],
'cairo_pattern_create_for_surface' => ['CairoPattern', 'surface'=>'cairosurface'],
'cairo_pattern_create_linear' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'],
'cairo_pattern_create_radial' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'],
'cairo_pattern_create_rgb' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'cairo_pattern_create_rgba' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'],
'cairo_pattern_get_color_stop_count' => ['int', 'pattern'=>'cairogradientpattern'],
'cairo_pattern_get_color_stop_rgba' => ['array', 'pattern'=>'cairogradientpattern', 'index'=>'int'],
'cairo_pattern_get_extend' => ['int', 'pattern'=>'string'],
'cairo_pattern_get_filter' => ['int', 'pattern'=>'cairosurfacepattern'],
'cairo_pattern_get_linear_points' => ['array', 'pattern'=>'cairolineargradient'],
'cairo_pattern_get_matrix' => ['CairoMatrix', 'pattern'=>'cairopattern'],
'cairo_pattern_get_radial_circles' => ['array', 'pattern'=>'cairoradialgradient'],
'cairo_pattern_get_rgba' => ['array', 'pattern'=>'cairosolidpattern'],
'cairo_pattern_get_surface' => ['CairoSurface', 'pattern'=>'cairosurfacepattern'],
'cairo_pattern_get_type' => ['int', 'pattern'=>'cairopattern'],
'cairo_pattern_set_extend' => ['void', 'pattern'=>'string', 'extend'=>'string'],
'cairo_pattern_set_filter' => ['void', 'pattern'=>'cairosurfacepattern', 'filter'=>'int'],
'cairo_pattern_set_matrix' => ['void', 'pattern'=>'cairopattern', 'matrix'=>'cairomatrix'],
'cairo_pattern_status' => ['int', 'pattern'=>'cairopattern'],
'cairo_pdf_surface_create' => ['CairoPdfSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
'cairo_pdf_surface_set_size' => ['void', 'surface'=>'cairopdfsurface', 'width'=>'float', 'height'=>'float'],
'cairo_pop_group' => ['', 'context'=>'cairocontext'],
'cairo_pop_group_to_source' => ['', 'context'=>'cairocontext'],
'cairo_ps_get_levels' => ['array'],
'cairo_ps_level_to_string' => ['string', 'level'=>'int'],
'cairo_ps_surface_create' => ['CairoPsSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
'cairo_ps_surface_dsc_begin_page_setup' => ['void', 'surface'=>'cairopssurface'],
'cairo_ps_surface_dsc_begin_setup' => ['void', 'surface'=>'cairopssurface'],
'cairo_ps_surface_dsc_comment' => ['void', 'surface'=>'cairopssurface', 'comment'=>'string'],
'cairo_ps_surface_get_eps' => ['bool', 'surface'=>'cairopssurface'],
'cairo_ps_surface_restrict_to_level' => ['void', 'surface'=>'cairopssurface', 'level'=>'int'],
'cairo_ps_surface_set_eps' => ['void', 'surface'=>'cairopssurface', 'level'=>'bool'],
'cairo_ps_surface_set_size' => ['void', 'surface'=>'cairopssurface', 'width'=>'float', 'height'=>'float'],
'cairo_push_group' => ['', 'context'=>'cairocontext'],
'cairo_push_group_with_content' => ['', 'content'=>'string', 'context'=>'cairocontext'],
'cairo_rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'],
'cairo_rel_curve_to' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'],
'cairo_rel_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_rel_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_reset_clip' => ['', 'context'=>'cairocontext'],
'cairo_restore' => ['', 'context'=>'cairocontext'],
'cairo_rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'],
'cairo_save' => ['', 'context'=>'cairocontext'],
'cairo_scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_scaled_font_create' => ['CairoScaledFont', 'fontface'=>'cairofontface', 'matrix'=>'cairomatrix', 'ctm'=>'cairomatrix', 'fontoptions'=>'cairofontoptions'],
'cairo_scaled_font_extents' => ['array', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_get_ctm' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_get_font_face' => ['CairoFontFace', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_get_font_matrix' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_get_font_options' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_get_scale_matrix' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_get_type' => ['int', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_glyph_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'glyphs'=>'array'],
'cairo_scaled_font_status' => ['int', 'scaledfont'=>'cairoscaledfont'],
'cairo_scaled_font_text_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'text'=>'string'],
'cairo_select_font_face' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'],
'cairo_set_antialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'],
'cairo_set_dash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'],
'cairo_set_fill_rule' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'cairo_set_font_face' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'],
'cairo_set_font_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
'cairo_set_font_options' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'],
'cairo_set_font_size' => ['', 'size'=>'string', 'context'=>'cairocontext'],
'cairo_set_line_cap' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'cairo_set_line_join' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'cairo_set_line_width' => ['', 'width'=>'string', 'context'=>'cairocontext'],
'cairo_set_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
'cairo_set_miter_limit' => ['', 'limit'=>'string', 'context'=>'cairocontext'],
'cairo_set_operator' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'cairo_set_scaled_font' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'],
'cairo_set_source' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'],
'cairo_set_source_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
'cairo_set_tolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'],
'cairo_show_page' => ['', 'context'=>'cairocontext'],
'cairo_show_text' => ['', 'text'=>'string', 'context'=>'cairocontext'],
'cairo_status' => ['int', 'context'=>'cairocontext'],
'cairo_status_to_string' => ['string', 'status'=>'int'],
'cairo_stroke' => ['', 'context'=>'cairocontext'],
'cairo_stroke_extents' => ['array', 'context'=>'cairocontext'],
'cairo_stroke_preserve' => ['', 'context'=>'cairocontext'],
'cairo_surface_copy_page' => ['void', 'surface'=>'cairosurface'],
'cairo_surface_create_similar' => ['CairoSurface', 'surface'=>'cairosurface', 'content'=>'int', 'width'=>'float', 'height'=>'float'],
'cairo_surface_finish' => ['void', 'surface'=>'cairosurface'],
'cairo_surface_flush' => ['void', 'surface'=>'cairosurface'],
'cairo_surface_get_content' => ['int', 'surface'=>'cairosurface'],
'cairo_surface_get_device_offset' => ['array', 'surface'=>'cairosurface'],
'cairo_surface_get_font_options' => ['CairoFontOptions', 'surface'=>'cairosurface'],
'cairo_surface_get_type' => ['int', 'surface'=>'cairosurface'],
'cairo_surface_mark_dirty' => ['void', 'surface'=>'cairosurface'],
'cairo_surface_mark_dirty_rectangle' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
'cairo_surface_set_device_offset' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'],
'cairo_surface_set_fallback_resolution' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'],
'cairo_surface_show_page' => ['void', 'surface'=>'cairosurface'],
'cairo_surface_status' => ['int', 'surface'=>'cairosurface'],
'cairo_surface_write_to_png' => ['void', 'surface'=>'cairosurface', 'stream'=>'resource'],
'cairo_svg_get_versions' => ['array'],
'cairo_svg_surface_create' => ['CairoSvgSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
'cairo_svg_surface_get_versions' => ['array'],
'cairo_svg_surface_restrict_to_version' => ['void', 'surface'=>'cairosvgsurface', 'version'=>'int'],
'cairo_svg_version_to_string' => ['string', 'version'=>'int'],
'cairo_text_extents' => ['array', 'text'=>'string', 'context'=>'cairocontext'],
'cairo_text_path' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'],
'cairo_transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
'cairo_translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'],
'cairo_user_to_device' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_user_to_device_distance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'cairo_version' => ['int'],
'cairo_version_string' => ['string'],
'CairoContext::__construct' => ['void', 'surface'=>'CairoSurface'],
'CairoContext::appendPath' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'],
'CairoContext::arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
'CairoContext::arcNegative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'],
'CairoContext::clip' => ['', 'context'=>'cairocontext'],
'CairoContext::clipExtents' => ['array', 'context'=>'cairocontext'],
'CairoContext::clipPreserve' => ['', 'context'=>'cairocontext'],
'CairoContext::clipRectangleList' => ['array', 'context'=>'cairocontext'],
'CairoContext::closePath' => ['', 'context'=>'cairocontext'],
'CairoContext::copyPage' => ['', 'context'=>'cairocontext'],
'CairoContext::copyPath' => ['CairoPath', 'context'=>'cairocontext'],
'CairoContext::copyPathFlat' => ['CairoPath', 'context'=>'cairocontext'],
'CairoContext::curveTo' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'],
'CairoContext::deviceToUser' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
'CairoContext::deviceToUserDistance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'],
'CairoContext::fill' => ['', 'context'=>'cairocontext'],
'CairoContext::fillExtents' => ['array', 'context'=>'cairocontext'],
'CairoContext::fillPreserve' => ['', 'context'=>'cairocontext'],
'CairoContext::fontExtents' => ['array', 'context'=>'cairocontext'],
'CairoContext::getAntialias' => ['int', 'context'=>'cairocontext'],
'CairoContext::getCurrentPoint' => ['array', 'context'=>'cairocontext'],
'CairoContext::getDash' => ['array', 'context'=>'cairocontext'],
'CairoContext::getDashCount' => ['int', 'context'=>'cairocontext'],
'CairoContext::getFillRule' => ['int', 'context'=>'cairocontext'],
'CairoContext::getFontFace' => ['', 'context'=>'cairocontext'],
'CairoContext::getFontMatrix' => ['', 'context'=>'cairocontext'],
'CairoContext::getFontOptions' => ['', 'context'=>'cairocontext'],
'CairoContext::getGroupTarget' => ['', 'context'=>'cairocontext'],
'CairoContext::getLineCap' => ['int', 'context'=>'cairocontext'],
'CairoContext::getLineJoin' => ['int', 'context'=>'cairocontext'],
'CairoContext::getLineWidth' => ['float', 'context'=>'cairocontext'],
'CairoContext::getMatrix' => ['', 'context'=>'cairocontext'],
'CairoContext::getMiterLimit' => ['float', 'context'=>'cairocontext'],
'CairoContext::getOperator' => ['int', 'context'=>'cairocontext'],
'CairoContext::getScaledFont' => ['', 'context'=>'cairocontext'],
'CairoContext::getSource' => ['', 'context'=>'cairocontext'],
'CairoContext::getTarget' => ['', 'context'=>'cairocontext'],
'CairoContext::getTolerance' => ['float', 'context'=>'cairocontext'],
'CairoContext::glyphPath' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'],
'CairoContext::hasCurrentPoint' => ['bool', 'context'=>'cairocontext'],
'CairoContext::identityMatrix' => ['', 'context'=>'cairocontext'],
'CairoContext::inFill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::inStroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::lineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'],
'CairoContext::maskSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
'CairoContext::moveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::newPath' => ['', 'context'=>'cairocontext'],
'CairoContext::newSubPath' => ['', 'context'=>'cairocontext'],
'CairoContext::paint' => ['', 'context'=>'cairocontext'],
'CairoContext::paintWithAlpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'],
'CairoContext::pathExtents' => ['array', 'context'=>'cairocontext'],
'CairoContext::popGroup' => ['', 'context'=>'cairocontext'],
'CairoContext::popGroupToSource' => ['', 'context'=>'cairocontext'],
'CairoContext::pushGroup' => ['', 'context'=>'cairocontext'],
'CairoContext::pushGroupWithContent' => ['', 'content'=>'string', 'context'=>'cairocontext'],
'CairoContext::rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'],
'CairoContext::relCurveTo' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'],
'CairoContext::relLineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::relMoveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::resetClip' => ['', 'context'=>'cairocontext'],
'CairoContext::restore' => ['', 'context'=>'cairocontext'],
'CairoContext::rotate' => ['', 'angle'=>'string', 'context'=>'cairocontext'],
'CairoContext::save' => ['', 'context'=>'cairocontext'],
'CairoContext::scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::selectFontFace' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'],
'CairoContext::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'],
'CairoContext::setDash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'],
'CairoContext::setFillRule' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'CairoContext::setFontFace' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'],
'CairoContext::setFontMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
'CairoContext::setFontOptions' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'],
'CairoContext::setFontSize' => ['', 'size'=>'string', 'context'=>'cairocontext'],
'CairoContext::setLineCap' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'CairoContext::setLineJoin' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'CairoContext::setLineWidth' => ['', 'width'=>'string', 'context'=>'cairocontext'],
'CairoContext::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
'CairoContext::setMiterLimit' => ['', 'limit'=>'string', 'context'=>'cairocontext'],
'CairoContext::setOperator' => ['', 'setting'=>'string', 'context'=>'cairocontext'],
'CairoContext::setScaledFont' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'],
'CairoContext::setSource' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'],
'CairoContext::setSourceRGB' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'],
'CairoContext::setSourceRGBA' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'],
'CairoContext::setSourceSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'],
'CairoContext::setTolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'],
'CairoContext::showPage' => ['', 'context'=>'cairocontext'],
'CairoContext::showText' => ['', 'text'=>'string', 'context'=>'cairocontext'],
'CairoContext::status' => ['int', 'context'=>'cairocontext'],
'CairoContext::stroke' => ['', 'context'=>'cairocontext'],
'CairoContext::strokeExtents' => ['array', 'context'=>'cairocontext'],
'CairoContext::strokePreserve' => ['', 'context'=>'cairocontext'],
'CairoContext::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'],
'CairoContext::textPath' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'],
'CairoContext::transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
'CairoContext::translate' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::userToDevice' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoContext::userToDeviceDistance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'],
'CairoFontFace::__construct' => ['void'],
'CairoFontFace::getType' => ['int'],
'CairoFontFace::status' => ['int', 'fontface'=>'cairofontface'],
'CairoFontOptions::__construct' => ['void'],
'CairoFontOptions::equal' => ['bool', 'other'=>'string'],
'CairoFontOptions::getAntialias' => ['int', 'context'=>'cairocontext'],
'CairoFontOptions::getHintMetrics' => ['int'],
'CairoFontOptions::getHintStyle' => ['int'],
'CairoFontOptions::getSubpixelOrder' => ['int'],
'CairoFontOptions::hash' => ['int'],
'CairoFontOptions::merge' => ['void', 'other'=>'string'],
'CairoFontOptions::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'],
'CairoFontOptions::setHintMetrics' => ['void', 'hint_metrics'=>'string'],
'CairoFontOptions::setHintStyle' => ['void', 'hint_style'=>'string'],
'CairoFontOptions::setSubpixelOrder' => ['void', 'subpixel_order'=>'string'],
'CairoFontOptions::status' => ['int', 'context'=>'cairocontext'],
'CairoFormat::strideForWidth' => ['int', 'format'=>'int', 'width'=>'int'],
'CairoGradientPattern::addColorStopRgb' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string'],
'CairoGradientPattern::addColorStopRgba' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string'],
'CairoGradientPattern::getColorStopCount' => ['int'],
'CairoGradientPattern::getColorStopRgba' => ['array', 'index'=>'string'],
'CairoGradientPattern::getExtend' => ['int'],
'CairoGradientPattern::setExtend' => ['void', 'extend'=>'int'],
'CairoImageSurface::__construct' => ['void', 'format'=>'int', 'width'=>'int', 'height'=>'int'],
'CairoImageSurface::createForData' => ['void', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'],
'CairoImageSurface::createFromPng' => ['CairoImageSurface', 'file'=>'string'],
'CairoImageSurface::getData' => ['string'],
'CairoImageSurface::getFormat' => ['int'],
'CairoImageSurface::getHeight' => ['int'],
'CairoImageSurface::getStride' => ['int'],
'CairoImageSurface::getWidth' => ['int'],
'CairoLinearGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'],
'CairoLinearGradient::getPoints' => ['array'],
'CairoMatrix::__construct' => ['void', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'],
'CairoMatrix::initIdentity' => ['object'],
'CairoMatrix::initRotate' => ['object', 'radians'=>'float'],
'CairoMatrix::initScale' => ['object', 'sx'=>'float', 'sy'=>'float'],
'CairoMatrix::initTranslate' => ['object', 'tx'=>'float', 'ty'=>'float'],
'CairoMatrix::invert' => ['void'],
'CairoMatrix::multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'],
'CairoMatrix::rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'],
'CairoMatrix::scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'],
'CairoMatrix::transformDistance' => ['array', 'dx'=>'string', 'dy'=>'string'],
'CairoMatrix::transformPoint' => ['array', 'dx'=>'string', 'dy'=>'string'],
'CairoMatrix::translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'],
'CairoPattern::__construct' => ['void'],
'CairoPattern::getMatrix' => ['', 'context'=>'cairocontext'],
'CairoPattern::getType' => ['int'],
'CairoPattern::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'],
'CairoPattern::status' => ['int', 'context'=>'cairocontext'],
'CairoPdfSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
'CairoPdfSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'],
'CairoPsSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
'CairoPsSurface::dscBeginPageSetup' => ['void'],
'CairoPsSurface::dscBeginSetup' => ['void'],
'CairoPsSurface::dscComment' => ['void', 'comment'=>'string'],
'CairoPsSurface::getEps' => ['bool'],
'CairoPsSurface::getLevels' => ['array'],
'CairoPsSurface::levelToString' => ['string', 'level'=>'int'],
'CairoPsSurface::restrictToLevel' => ['void', 'level'=>'string'],
'CairoPsSurface::setEps' => ['void', 'level'=>'string'],
'CairoPsSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'],
'CairoRadialGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'],
'CairoRadialGradient::getCircles' => ['array'],
'CairoScaledFont::__construct' => ['void', 'font_face'=>'CairoFontFace', 'matrix'=>'CairoMatrix', 'ctm'=>'CairoMatrix', 'options'=>'CairoFontOptions'],
'CairoScaledFont::extents' => ['array'],
'CairoScaledFont::getCtm' => ['CairoMatrix'],
'CairoScaledFont::getFontFace' => ['', 'context'=>'cairocontext'],
'CairoScaledFont::getFontMatrix' => ['', 'context'=>'cairocontext'],
'CairoScaledFont::getFontOptions' => ['', 'context'=>'cairocontext'],
'CairoScaledFont::getScaleMatrix' => ['void'],
'CairoScaledFont::getType' => ['int'],
'CairoScaledFont::glyphExtents' => ['array', 'glyphs'=>'string'],
'CairoScaledFont::status' => ['int', 'context'=>'cairocontext'],
'CairoScaledFont::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'],
'CairoSolidPattern::__construct' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha='=>'float'],
'CairoSolidPattern::getRgba' => ['array'],
'CairoSurface::__construct' => ['void'],
'CairoSurface::copyPage' => ['', 'context'=>'cairocontext'],
'CairoSurface::createSimilar' => ['void', 'other'=>'cairosurface', 'content'=>'int', 'width'=>'string', 'height'=>'string'],
'CairoSurface::finish' => ['void'],
'CairoSurface::flush' => ['void'],
'CairoSurface::getContent' => ['int'],
'CairoSurface::getDeviceOffset' => ['array'],
'CairoSurface::getFontOptions' => ['', 'context'=>'cairocontext'],
'CairoSurface::getType' => ['int'],
'CairoSurface::markDirty' => ['void'],
'CairoSurface::markDirtyRectangle' => ['void', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string'],
'CairoSurface::setDeviceOffset' => ['void', 'x'=>'string', 'y'=>'string'],
'CairoSurface::setFallbackResolution' => ['void', 'x'=>'string', 'y'=>'string'],
'CairoSurface::showPage' => ['', 'context'=>'cairocontext'],
'CairoSurface::status' => ['int', 'context'=>'cairocontext'],
'CairoSurface::writeToPng' => ['void', 'file'=>'string'],
'CairoSurfacePattern::__construct' => ['void', 'surface'=>'CairoSurface'],
'CairoSurfacePattern::getExtend' => ['int'],
'CairoSurfacePattern::getFilter' => ['int'],
'CairoSurfacePattern::getSurface' => ['void'],
'CairoSurfacePattern::setExtend' => ['void', 'extend'=>'int'],
'CairoSurfacePattern::setFilter' => ['void', 'filter'=>'string'],
'CairoSvgSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'],
'CairoSvgSurface::getVersions' => ['array'],
'CairoSvgSurface::restrictToVersion' => ['void', 'version'=>'string'],
'CairoSvgSurface::versionToString' => ['string', 'version'=>'int'],
'cal_days_in_month' => ['int', 'calendar'=>'int', 'month'=>'int', 'year'=>'int'],
'cal_from_jd' => ['array{date:string,month:int,day:int,year:int,dow:int,abbrevdayname:string,dayname:string,abbrevmonth:string,monthname:string}', 'julian_day'=>'int', 'calendar'=>'int'],
'cal_info' => ['array', 'calendar='=>'int'],
'cal_to_jd' => ['int', 'calendar'=>'int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
'calcul_hmac' => ['string', 'clent'=>'string', 'siretcode'=>'string', 'price'=>'string', 'reference'=>'string', 'validity'=>'string', 'taxation'=>'string', 'devise'=>'string', 'language'=>'string'],
'calculhmac' => ['string', 'clent'=>'string', 'data'=>'string'],
'call_user_func' => ['mixed|false', 'callback'=>'callable', '...args='=>'mixed'],
'call_user_func_array' => ['mixed|false', 'callback'=>'callable', 'args'=>'list<mixed>'],
'call_user_method' => ['mixed', 'method_name'=>'string', 'object'=>'object', 'parameter='=>'mixed', '...args='=>'mixed'],
'call_user_method_array' => ['mixed', 'method_name'=>'string', 'object'=>'object', 'params'=>'list<mixed>'],
'CallbackFilterIterator::__construct' => ['void', 'iterator'=>'Iterator', 'func'=>'callable(mixed):bool|callable(mixed,mixed):bool|callable(mixed,mixed,mixed):bool'],
'CallbackFilterIterator::accept' => ['bool'],
'CallbackFilterIterator::current' => ['mixed'],
'CallbackFilterIterator::getInnerIterator' => ['Iterator'],
'CallbackFilterIterator::key' => ['mixed'],
'CallbackFilterIterator::next' => ['void'],
'CallbackFilterIterator::rewind' => ['void'],
'CallbackFilterIterator::valid' => ['bool'],
'ceil' => ['float', 'num'=>'float'],
'chdb::__construct' => ['void', 'pathname'=>'string'],
'chdb::get' => ['string', 'key'=>'string'],
'chdb_create' => ['bool', 'pathname'=>'string', 'data'=>'array'],
'chdir' => ['bool', 'directory'=>'string'],
'checkdate' => ['bool', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
'checkdnsrr' => ['bool', 'hostname'=>'string', 'type='=>'string'],
'chgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'],
'chmod' => ['bool', 'filename'=>'string', 'permissions'=>'int'],
'chop' => ['string', 'string'=>'string', 'characters='=>'string'],
'chown' => ['bool', 'filename'=>'string', 'user'=>'string|int'],
'chr' => ['non-empty-string', 'codepoint'=>'int'],
'chroot' => ['bool', 'directory'=>'string'],
'chunk_split' => ['string', 'string'=>'string', 'length='=>'int', 'separator='=>'string'],
'class_alias' => ['bool', 'class'=>'string', 'alias'=>'string', 'autoload='=>'bool'],
'class_exists' => ['bool', 'class'=>'string', 'autoload='=>'bool'],
'class_implements' => ['array<string,string>|false', 'object_or_class'=>'object|string', 'autoload='=>'bool'],
'class_parents' => ['array<string, class-string>|false', 'object_or_class'=>'object|string', 'autoload='=>'bool'],
'class_uses' => ['array<string,string>|false', 'object_or_class'=>'object|string', 'autoload='=>'bool'],
'classkit_import' => ['array', 'filename'=>'string'],
'classkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'],
'classkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'],
'classkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'],
'classkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'],
'classkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'],
'classObj::__construct' => ['void', 'layer'=>'layerObj', 'class'=>'classObj'],
'classObj::addLabel' => ['int', 'label'=>'labelObj'],
'classObj::convertToString' => ['string'],
'classObj::createLegendIcon' => ['imageObj', 'width'=>'int', 'height'=>'int'],
'classObj::deletestyle' => ['int', 'index'=>'int'],
'classObj::drawLegendIcon' => ['int', 'width'=>'int', 'height'=>'int', 'im'=>'imageObj', 'dstX'=>'int', 'dstY'=>'int'],
'classObj::free' => ['void'],
'classObj::getExpressionString' => ['string'],
'classObj::getLabel' => ['labelObj', 'index'=>'int'],
'classObj::getMetaData' => ['int', 'name'=>'string'],
'classObj::getStyle' => ['styleObj', 'index'=>'int'],
'classObj::getTextString' => ['string'],
'classObj::movestyledown' => ['int', 'index'=>'int'],
'classObj::movestyleup' => ['int', 'index'=>'int'],
'classObj::ms_newClassObj' => ['classObj', 'layer'=>'layerObj', 'class'=>'classObj'],
'classObj::removeLabel' => ['labelObj', 'index'=>'int'],
'classObj::removeMetaData' => ['int', 'name'=>'string'],
'classObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'classObj::setExpression' => ['int', 'expression'=>'string'],
'classObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'],
'classObj::settext' => ['int', 'text'=>'string'],
'classObj::updateFromString' => ['int', 'snippet'=>'string'],
'clearstatcache' => ['void', 'clear_realpath_cache='=>'bool', 'filename='=>'string'],
'cli_get_process_title' => ['?string'],
'cli_set_process_title' => ['bool', 'title'=>'string'],
'ClosedGeneratorException::__clone' => ['void'],
'ClosedGeneratorException::__toString' => ['string'],
'ClosedGeneratorException::getCode' => ['int'],
'ClosedGeneratorException::getFile' => ['string'],
'ClosedGeneratorException::getLine' => ['int'],
'ClosedGeneratorException::getMessage' => ['string'],
'ClosedGeneratorException::getPrevious' => ['?Throwable'],
'ClosedGeneratorException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'ClosedGeneratorException::getTraceAsString' => ['string'],
'closedir' => ['void', 'dir_handle='=>'resource'],
'closelog' => ['bool'],
'Closure::__construct' => ['void'],
'Closure::__invoke' => ['', '...args='=>''],
'Closure::bind' => ['Closure|false', 'old'=>'Closure', 'to'=>'?object', 'scope='=>'object|string'],
'Closure::bindTo' => ['Closure|false', 'new'=>'?object', 'newscope='=>'object|string'],
'Closure::call' => ['', 'to'=>'object', '...parameters='=>''],
'Closure::fromCallable' => ['Closure', 'callable'=>'callable'],
'clusterObj::convertToString' => ['string'],
'clusterObj::getFilterString' => ['string'],
'clusterObj::getGroupString' => ['string'],
'clusterObj::setFilter' => ['int', 'expression'=>'string'],
'clusterObj::setGroup' => ['int', 'expression'=>'string'],
'Collator::__construct' => ['void', 'locale'=>'string'],
'Collator::asort' => ['bool', '&rw_arr'=>'array', 'sort_flag='=>'int'],
'Collator::compare' => ['int|false', 'string1'=>'string', 'string2'=>'string'],
'Collator::create' => ['?Collator', 'locale'=>'string'],
'Collator::getAttribute' => ['int|false', 'attr'=>'int'],
'Collator::getErrorCode' => ['int'],
'Collator::getErrorMessage' => ['string'],
'Collator::getLocale' => ['string', 'type'=>'int'],
'Collator::getSortKey' => ['string|false', 'string'=>'string'],
'Collator::getStrength' => ['int'],
'Collator::setAttribute' => ['bool', 'attr'=>'int', 'value'=>'int'],
'Collator::setStrength' => ['bool', 'strength'=>'int'],
'Collator::sort' => ['bool', '&rw_arr'=>'array', 'sort_flags='=>'int'],
'Collator::sortWithSortKeys' => ['bool', '&rw_arr'=>'array'],
'collator_asort' => ['bool', 'object'=>'collator', '&rw_array'=>'array', 'flags='=>'int'],
'collator_compare' => ['int', 'object'=>'collator', 'string1'=>'string', 'string2'=>'string'],
'collator_create' => ['?Collator', 'locale'=>'string'],
'collator_get_attribute' => ['int|false', 'object'=>'collator', 'attribute'=>'int'],
'collator_get_error_code' => ['int', 'object'=>'collator'],
'collator_get_error_message' => ['string', 'object'=>'collator'],
'collator_get_locale' => ['string', 'object'=>'collator', 'type'=>'int'],
'collator_get_sort_key' => ['string', 'object'=>'collator', 'string'=>'string'],
'collator_get_strength' => ['int', 'object'=>'collator'],
'collator_set_attribute' => ['bool', 'object'=>'collator', 'attribute'=>'int', 'value'=>'int'],
'collator_set_strength' => ['bool', 'object'=>'collator', 'strength'=>'int'],
'collator_sort' => ['bool', 'object'=>'collator', '&rw_array'=>'array', 'flags='=>'int'],
'collator_sort_with_sort_keys' => ['bool', 'object'=>'collator', '&rw_array'=>'array'],
'Collectable::isGarbage' => ['bool'],
'Collectable::setGarbage' => ['void'],
'colorObj::setHex' => ['int', 'hex'=>'string'],
'colorObj::toHex' => ['string'],
'COM::__call' => ['', 'name'=>'', 'args'=>''],
'COM::__construct' => ['void', 'module_name'=>'string', 'server_name='=>'mixed', 'codepage='=>'int', 'typelib='=>'string'],
'COM::__get' => ['', 'name'=>''],
'COM::__set' => ['void', 'name'=>'', 'value'=>''],
'com_addref' => [''],
'com_create_guid' => ['string'],
'com_event_sink' => ['bool', 'variant'=>'VARIANT', 'sink_object'=>'object', 'sink_interface='=>'mixed'],
'com_get_active_object' => ['VARIANT', 'prog_id'=>'string', 'codepage='=>'int'],
'com_isenum' => ['bool', 'com_module'=>'variant'],
'com_load_typelib' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'true'],
'com_message_pump' => ['bool', 'timeout_milliseconds='=>'int'],
'com_print_typeinfo' => ['bool', 'variant'=>'object', 'dispatch_interface='=>'string', 'display_sink='=>'bool'],
'commonmark\cql::__invoke' => ['', 'root'=>'CommonMark\Node', 'handler'=>'callable'],
'commonmark\interfaces\ivisitable::accept' => ['void', 'visitor'=>'CommonMark\Interfaces\IVisitor'],
'commonmark\interfaces\ivisitor::enter' => ['?int|IVisitable', 'visitable'=>'IVisitable'],
'commonmark\interfaces\ivisitor::leave' => ['?int|IVisitable', 'visitable'=>'IVisitable'],
'commonmark\node::accept' => ['void', 'visitor'=>'CommonMark\Interfaces\IVisitor'],
'commonmark\node::appendChild' => ['CommonMark\Node', 'child'=>'CommonMark\Node'],
'commonmark\node::insertAfter' => ['CommonMark\Node', 'sibling'=>'CommonMark\Node'],
'commonmark\node::insertBefore' => ['CommonMark\Node', 'sibling'=>'CommonMark\Node'],
'commonmark\node::prependChild' => ['CommonMark\Node', 'child'=>'CommonMark\Node'],
'commonmark\node::replace' => ['CommonMark\Node', 'target'=>'CommonMark\Node'],
'commonmark\node::unlink' => ['void'],
'commonmark\parse' => ['CommonMark\Node', 'content'=>'string', 'options='=>'int'],
'commonmark\parser::finish' => ['CommonMark\Node'],
'commonmark\parser::parse' => ['void', 'buffer'=>'string'],
'commonmark\render' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int', 'width='=>'int'],
'commonmark\render\html' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int'],
'commonmark\render\latex' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int', 'width='=>'int'],
'commonmark\render\man' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int', 'width='=>'int'],
'commonmark\render\xml' => ['string', 'node'=>'CommonMark\Node', 'options='=>'int'],
'compact' => ['array<string, mixed>', 'var_name'=>'string|array', '...var_names='=>'string|array'],
'COMPersistHelper::__construct' => ['void', 'variant'=>'object'],
'COMPersistHelper::GetCurFile' => ['string'],
'COMPersistHelper::GetCurFileName' => ['string'],
'COMPersistHelper::GetMaxStreamSize' => ['int'],
'COMPersistHelper::InitNew' => ['int'],
'COMPersistHelper::LoadFromFile' => ['bool', 'filename'=>'string', 'flags'=>'int'],
'COMPersistHelper::LoadFromStream' => ['', 'stream'=>''],
'COMPersistHelper::SaveToFile' => ['bool', 'filename'=>'string', 'remember'=>'bool'],
'COMPersistHelper::SaveToStream' => ['int', 'stream'=>''],
'componere\abstract\definition::addInterface' => ['Componere\Abstract\Definition', 'interface'=>'string'],
'componere\abstract\definition::addMethod' => ['Componere\Abstract\Definition', 'name'=>'string', 'method'=>'Componere\Method'],
'componere\abstract\definition::addTrait' => ['Componere\Abstract\Definition', 'trait'=>'string'],
'componere\abstract\definition::getReflector' => ['ReflectionClass'],
'componere\cast' => ['object', 'arg1'=>'string', 'object'=>'object'],
'componere\cast_by_ref' => ['object', 'arg1'=>'string', 'object'=>'object'],
'componere\definition::addConstant' => ['Componere\Definition', 'name'=>'string', 'value'=>'Componere\Value'],
'componere\definition::addProperty' => ['Componere\Definition', 'name'=>'string', 'value'=>'Componere\Value'],
'componere\definition::getClosure' => ['Closure', 'name'=>'string'],
'componere\definition::getClosures' => ['Closure[]'],
'componere\definition::isRegistered' => ['bool'],
'componere\definition::register' => ['void'],
'componere\method::getReflector' => ['ReflectionMethod'],
'componere\method::setPrivate' => ['Method'],
'componere\method::setProtected' => ['Method'],
'componere\method::setStatic' => ['Method'],
'componere\patch::apply' => ['void'],
'componere\patch::derive' => ['Componere\Patch', 'instance'=>'object'],
'componere\patch::getClosure' => ['Closure', 'name'=>'string'],
'componere\patch::getClosures' => ['Closure[]'],
'componere\patch::isApplied' => ['bool'],
'componere\patch::revert' => ['void'],
'componere\value::hasDefault' => ['bool'],
'componere\value::isPrivate' => ['bool'],
'componere\value::isProtected' => ['bool'],
'componere\value::isStatic' => ['bool'],
'componere\value::setPrivate' => ['Value'],
'componere\value::setProtected' => ['Value'],
'componere\value::setStatic' => ['Value'],
'Cond::broadcast' => ['bool', 'condition'=>'long'],
'Cond::create' => ['long'],
'Cond::destroy' => ['bool', 'condition'=>'long'],
'Cond::signal' => ['bool', 'condition'=>'long'],
'Cond::wait' => ['bool', 'condition'=>'long', 'mutex'=>'long', 'timeout='=>'long'],
'confirm_pdo_ibm_compiled' => [''],
'connection_aborted' => ['int'],
'connection_status' => ['int'],
'connection_timeout' => ['int'],
'constant' => ['mixed', 'name'=>'string'],
'convert_cyr_string' => ['string', 'string'=>'string', 'from'=>'string', 'to'=>'string'],
'convert_uudecode' => ['string', 'string'=>'string'],
'convert_uuencode' => ['string', 'string'=>'string'],
'copy' => ['bool', 'from'=>'string', 'to'=>'string', 'context='=>'resource'],
'cos' => ['float', 'num'=>'float'],
'cosh' => ['float', 'num'=>'float'],
'Couchbase\AnalyticsQuery::__construct' => ['void'],
'Couchbase\AnalyticsQuery::fromString' => ['Couchbase\AnalyticsQuery', 'statement'=>'string'],
'Couchbase\basicDecoderV1' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int', 'options'=>'array'],
'Couchbase\basicEncoderV1' => ['array', 'value'=>'mixed', 'options'=>'array'],
'Couchbase\BooleanFieldSearchQuery::__construct' => ['void'],
'Couchbase\BooleanFieldSearchQuery::boost' => ['Couchbase\BooleanFieldSearchQuery', 'boost'=>'float'],
'Couchbase\BooleanFieldSearchQuery::field' => ['Couchbase\BooleanFieldSearchQuery', 'field'=>'string'],
'Couchbase\BooleanFieldSearchQuery::jsonSerialize' => ['array'],
'Couchbase\BooleanSearchQuery::__construct' => ['void'],
'Couchbase\BooleanSearchQuery::boost' => ['Couchbase\BooleanSearchQuery', 'boost'=>'float'],
'Couchbase\BooleanSearchQuery::jsonSerialize' => ['array'],
'Couchbase\BooleanSearchQuery::must' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
'Couchbase\BooleanSearchQuery::mustNot' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
'Couchbase\BooleanSearchQuery::should' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
'Couchbase\Bucket::__construct' => ['void'],
'Couchbase\Bucket::__get' => ['int', 'name'=>'string'],
'Couchbase\Bucket::__set' => ['int', 'name'=>'string', 'value'=>'int'],
'Couchbase\Bucket::append' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
'Couchbase\Bucket::counter' => ['Couchbase\Document|array', 'ids'=>'array|string', 'delta='=>'int', 'options='=>'array'],
'Couchbase\Bucket::decryptFields' => ['array', 'document'=>'array', 'fieldOptions'=>'', 'prefix='=>'string'],
'Couchbase\Bucket::diag' => ['array', 'reportId='=>'string'],
'Couchbase\Bucket::encryptFields' => ['array', 'document'=>'array', 'fieldOptions'=>'', 'prefix='=>'string'],
'Couchbase\Bucket::get' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
'Couchbase\Bucket::getAndLock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'lockTime'=>'int', 'options='=>'array'],
'Couchbase\Bucket::getAndTouch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'],
'Couchbase\Bucket::getFromReplica' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
'Couchbase\Bucket::getName' => ['string'],
'Couchbase\Bucket::insert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
'Couchbase\Bucket::listExists' => ['bool', 'id'=>'string', 'value'=>'mixed'],
'Couchbase\Bucket::listGet' => ['mixed', 'id'=>'string', 'index'=>'int'],
'Couchbase\Bucket::listPush' => ['', 'id'=>'string', 'value'=>'mixed'],
'Couchbase\Bucket::listRemove' => ['', 'id'=>'string', 'index'=>'int'],
'Couchbase\Bucket::listSet' => ['', 'id'=>'string', 'index'=>'int', 'value'=>'mixed'],
'Couchbase\Bucket::listShift' => ['', 'id'=>'string', 'value'=>'mixed'],
'Couchbase\Bucket::listSize' => ['int', 'id'=>'string'],
'Couchbase\Bucket::lookupIn' => ['Couchbase\LookupInBuilder', 'id'=>'string'],
'Couchbase\Bucket::manager' => ['Couchbase\BucketManager'],
'Couchbase\Bucket::mapAdd' => ['', 'id'=>'string', 'key'=>'string', 'value'=>'mixed'],
'Couchbase\Bucket::mapGet' => ['mixed', 'id'=>'string', 'key'=>'string'],
'Couchbase\Bucket::mapRemove' => ['', 'id'=>'string', 'key'=>'string'],
'Couchbase\Bucket::mapSize' => ['int', 'id'=>'string'],
'Couchbase\Bucket::mutateIn' => ['Couchbase\MutateInBuilder', 'id'=>'string', 'cas'=>'string'],
'Couchbase\Bucket::ping' => ['array', 'services='=>'int', 'reportId='=>'string'],
'Couchbase\Bucket::prepend' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
'Couchbase\Bucket::query' => ['object', 'query'=>'Couchbase\AnalyticsQuery|Couchbase\N1qlQuery|Couchbase\SearchQuery|Couchbase\SpatialViewQuery|Couchbase\ViewQuery', 'jsonAsArray='=>'bool'],
'Couchbase\Bucket::queueAdd' => ['', 'id'=>'string', 'value'=>'mixed'],
'Couchbase\Bucket::queueExists' => ['bool', 'id'=>'string', 'value'=>'mixed'],
'Couchbase\Bucket::queueRemove' => ['mixed', 'id'=>'string'],
'Couchbase\Bucket::queueSize' => ['int', 'id'=>'string'],
'Couchbase\Bucket::remove' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
'Couchbase\Bucket::replace' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
'Couchbase\Bucket::retrieveIn' => ['Couchbase\DocumentFragment', 'id'=>'string', '...paths='=>'array<int,string>'],
'Couchbase\Bucket::setAdd' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'],
'Couchbase\Bucket::setExists' => ['bool', 'id'=>'string', 'value'=>'bool|float|int|string'],
'Couchbase\Bucket::setRemove' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'],
'Couchbase\Bucket::setSize' => ['int', 'id'=>'string'],
'Couchbase\Bucket::setTranscoder' => ['', 'encoder'=>'callable', 'decoder'=>'callable'],
'Couchbase\Bucket::touch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'],
'Couchbase\Bucket::unlock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'],
'Couchbase\Bucket::upsert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'],
'Couchbase\BucketManager::__construct' => ['void'],
'Couchbase\BucketManager::createN1qlIndex' => ['', 'name'=>'string', 'fields'=>'array', 'whereClause='=>'string', 'ignoreIfExist='=>'bool', 'defer='=>'bool'],
'Couchbase\BucketManager::createN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfExist='=>'bool', 'defer='=>'bool'],
'Couchbase\BucketManager::dropN1qlIndex' => ['', 'name'=>'string', 'ignoreIfNotExist='=>'bool'],
'Couchbase\BucketManager::dropN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfNotExist='=>'bool'],
'Couchbase\BucketManager::flush' => [''],
'Couchbase\BucketManager::getDesignDocument' => ['array', 'name'=>'string'],
'Couchbase\BucketManager::info' => ['array'],
'Couchbase\BucketManager::insertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'],
'Couchbase\BucketManager::listDesignDocuments' => ['array'],
'Couchbase\BucketManager::listN1qlIndexes' => ['array'],
'Couchbase\BucketManager::removeDesignDocument' => ['', 'name'=>'string'],
'Couchbase\BucketManager::upsertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'],
'Couchbase\ClassicAuthenticator::bucket' => ['', 'name'=>'string', 'password'=>'string'],
'Couchbase\ClassicAuthenticator::cluster' => ['', 'username'=>'string', 'password'=>'string'],
'Couchbase\Cluster::__construct' => ['void', 'connstr'=>'string'],
'Couchbase\Cluster::authenticate' => ['null', 'authenticator'=>'Couchbase\Authenticator'],
'Couchbase\Cluster::authenticateAs' => ['null', 'username'=>'string', 'password'=>'string'],
'Couchbase\Cluster::manager' => ['Couchbase\ClusterManager', 'username='=>'string', 'password='=>'string'],
'Couchbase\Cluster::openBucket' => ['Couchbase\Bucket', 'name='=>'string', 'password='=>'string'],
'Couchbase\ClusterManager::__construct' => ['void'],
'Couchbase\ClusterManager::createBucket' => ['', 'name'=>'string', 'options='=>'array'],
'Couchbase\ClusterManager::getUser' => ['array', 'username'=>'string', 'domain='=>'int'],
'Couchbase\ClusterManager::info' => ['array'],
'Couchbase\ClusterManager::listBuckets' => ['array'],
'Couchbase\ClusterManager::listUsers' => ['array', 'domain='=>'int'],
'Couchbase\ClusterManager::removeBucket' => ['', 'name'=>'string'],
'Couchbase\ClusterManager::removeUser' => ['', 'name'=>'string', 'domain='=>'int'],
'Couchbase\ClusterManager::upsertUser' => ['', 'name'=>'string', 'settings'=>'Couchbase\UserSettings', 'domain='=>'int'],
'Couchbase\ConjunctionSearchQuery::__construct' => ['void'],
'Couchbase\ConjunctionSearchQuery::boost' => ['Couchbase\ConjunctionSearchQuery', 'boost'=>'float'],
'Couchbase\ConjunctionSearchQuery::every' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
'Couchbase\ConjunctionSearchQuery::jsonSerialize' => ['array'],
'Couchbase\DateRangeSearchFacet::__construct' => ['void'],
'Couchbase\DateRangeSearchFacet::addRange' => ['Couchbase\DateRangeSearchFacet', 'name'=>'string', 'start'=>'int|string', 'end'=>'int|string'],
'Couchbase\DateRangeSearchFacet::jsonSerialize' => ['array'],
'Couchbase\DateRangeSearchQuery::__construct' => ['void'],
'Couchbase\DateRangeSearchQuery::boost' => ['Couchbase\DateRangeSearchQuery', 'boost'=>'float'],
'Couchbase\DateRangeSearchQuery::dateTimeParser' => ['Couchbase\DateRangeSearchQuery', 'dateTimeParser'=>'string'],
'Couchbase\DateRangeSearchQuery::end' => ['Couchbase\DateRangeSearchQuery', 'end'=>'int|string', 'inclusive='=>'bool'],
'Couchbase\DateRangeSearchQuery::field' => ['Couchbase\DateRangeSearchQuery', 'field'=>'string'],
'Couchbase\DateRangeSearchQuery::jsonSerialize' => ['array'],
'Couchbase\DateRangeSearchQuery::start' => ['Couchbase\DateRangeSearchQuery', 'start'=>'int|string', 'inclusive='=>'bool'],
'Couchbase\defaultDecoder' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'],
'Couchbase\defaultEncoder' => ['array', 'value'=>'mixed'],
'Couchbase\DisjunctionSearchQuery::__construct' => ['void'],
'Couchbase\DisjunctionSearchQuery::boost' => ['Couchbase\DisjunctionSearchQuery', 'boost'=>'float'],
'Couchbase\DisjunctionSearchQuery::either' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
'Couchbase\DisjunctionSearchQuery::jsonSerialize' => ['array'],
'Couchbase\DisjunctionSearchQuery::min' => ['Couchbase\DisjunctionSearchQuery', 'min'=>'int'],
'Couchbase\DocIdSearchQuery::__construct' => ['void'],
'Couchbase\DocIdSearchQuery::boost' => ['Couchbase\DocIdSearchQuery', 'boost'=>'float'],
'Couchbase\DocIdSearchQuery::docIds' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array<int,string>'],
'Couchbase\DocIdSearchQuery::field' => ['Couchbase\DocIdSearchQuery', 'field'=>'string'],
'Couchbase\DocIdSearchQuery::jsonSerialize' => ['array'],
'Couchbase\fastlzCompress' => ['string', 'data'=>'string'],
'Couchbase\fastlzDecompress' => ['string', 'data'=>'string'],
'Couchbase\GeoBoundingBoxSearchQuery::__construct' => ['void'],
'Couchbase\GeoBoundingBoxSearchQuery::boost' => ['Couchbase\GeoBoundingBoxSearchQuery', 'boost'=>'float'],
'Couchbase\GeoBoundingBoxSearchQuery::field' => ['Couchbase\GeoBoundingBoxSearchQuery', 'field'=>'string'],
'Couchbase\GeoBoundingBoxSearchQuery::jsonSerialize' => ['array'],
'Couchbase\GeoDistanceSearchQuery::__construct' => ['void'],
'Couchbase\GeoDistanceSearchQuery::boost' => ['Couchbase\GeoDistanceSearchQuery', 'boost'=>'float'],
'Couchbase\GeoDistanceSearchQuery::field' => ['Couchbase\GeoDistanceSearchQuery', 'field'=>'string'],
'Couchbase\GeoDistanceSearchQuery::jsonSerialize' => ['array'],
'Couchbase\LookupInBuilder::__construct' => ['void'],
'Couchbase\LookupInBuilder::execute' => ['Couchbase\DocumentFragment'],
'Couchbase\LookupInBuilder::exists' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'],
'Couchbase\LookupInBuilder::get' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'],
'Couchbase\LookupInBuilder::getCount' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'],
'Couchbase\MatchAllSearchQuery::__construct' => ['void'],
'Couchbase\MatchAllSearchQuery::boost' => ['Couchbase\MatchAllSearchQuery', 'boost'=>'float'],
'Couchbase\MatchAllSearchQuery::jsonSerialize' => ['array'],
'Couchbase\MatchNoneSearchQuery::__construct' => ['void'],
'Couchbase\MatchNoneSearchQuery::boost' => ['Couchbase\MatchNoneSearchQuery', 'boost'=>'float'],
'Couchbase\MatchNoneSearchQuery::jsonSerialize' => ['array'],
'Couchbase\MatchPhraseSearchQuery::__construct' => ['void'],
'Couchbase\MatchPhraseSearchQuery::analyzer' => ['Couchbase\MatchPhraseSearchQuery', 'analyzer'=>'string'],
'Couchbase\MatchPhraseSearchQuery::boost' => ['Couchbase\MatchPhraseSearchQuery', 'boost'=>'float'],
'Couchbase\MatchPhraseSearchQuery::field' => ['Couchbase\MatchPhraseSearchQuery', 'field'=>'string'],
'Couchbase\MatchPhraseSearchQuery::jsonSerialize' => ['array'],
'Couchbase\MatchSearchQuery::__construct' => ['void'],
'Couchbase\MatchSearchQuery::analyzer' => ['Couchbase\MatchSearchQuery', 'analyzer'=>'string'],
'Couchbase\MatchSearchQuery::boost' => ['Couchbase\MatchSearchQuery', 'boost'=>'float'],
'Couchbase\MatchSearchQuery::field' => ['Couchbase\MatchSearchQuery', 'field'=>'string'],
'Couchbase\MatchSearchQuery::fuzziness' => ['Couchbase\MatchSearchQuery', 'fuzziness'=>'int'],
'Couchbase\MatchSearchQuery::jsonSerialize' => ['array'],
'Couchbase\MatchSearchQuery::prefixLength' => ['Couchbase\MatchSearchQuery', 'prefixLength'=>'int'],
'Couchbase\MutateInBuilder::__construct' => ['void'],
'Couchbase\MutateInBuilder::arrayAddUnique' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::arrayAppend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::arrayAppendAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::arrayInsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'],
'Couchbase\MutateInBuilder::arrayInsertAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array'],
'Couchbase\MutateInBuilder::arrayPrepend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::arrayPrependAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::counter' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'delta'=>'int', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::execute' => ['Couchbase\DocumentFragment'],
'Couchbase\MutateInBuilder::insert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::modeDocument' => ['', 'mode'=>'int'],
'Couchbase\MutateInBuilder::remove' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'options='=>'array'],
'Couchbase\MutateInBuilder::replace' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'],
'Couchbase\MutateInBuilder::upsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'],
'Couchbase\MutateInBuilder::withExpiry' => ['Couchbase\MutateInBuilder', 'expiry'=>'Couchbase\expiry'],
'Couchbase\MutationState::__construct' => ['void'],
'Couchbase\MutationState::add' => ['', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'],
'Couchbase\MutationState::from' => ['Couchbase\MutationState', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'],
'Couchbase\MutationToken::__construct' => ['void'],
'Couchbase\MutationToken::bucketName' => ['string'],
'Couchbase\MutationToken::from' => ['', 'bucketName'=>'string', 'vbucketId'=>'int', 'vbucketUuid'=>'string', 'sequenceNumber'=>'string'],
'Couchbase\MutationToken::sequenceNumber' => ['string'],
'Couchbase\MutationToken::vbucketId' => ['int'],
'Couchbase\MutationToken::vbucketUuid' => ['string'],
'Couchbase\N1qlIndex::__construct' => ['void'],
'Couchbase\N1qlQuery::__construct' => ['void'],
'Couchbase\N1qlQuery::adhoc' => ['Couchbase\N1qlQuery', 'adhoc'=>'bool'],
'Couchbase\N1qlQuery::consistency' => ['Couchbase\N1qlQuery', 'consistency'=>'int'],
'Couchbase\N1qlQuery::consistentWith' => ['Couchbase\N1qlQuery', 'state'=>'Couchbase\MutationState'],
'Couchbase\N1qlQuery::crossBucket' => ['Couchbase\N1qlQuery', 'crossBucket'=>'bool'],
'Couchbase\N1qlQuery::fromString' => ['Couchbase\N1qlQuery', 'statement'=>'string'],
'Couchbase\N1qlQuery::maxParallelism' => ['Couchbase\N1qlQuery', 'maxParallelism'=>'int'],
'Couchbase\N1qlQuery::namedParams' => ['Couchbase\N1qlQuery', 'params'=>'array'],
'Couchbase\N1qlQuery::pipelineBatch' => ['Couchbase\N1qlQuery', 'pipelineBatch'=>'int'],
'Couchbase\N1qlQuery::pipelineCap' => ['Couchbase\N1qlQuery', 'pipelineCap'=>'int'],
'Couchbase\N1qlQuery::positionalParams' => ['Couchbase\N1qlQuery', 'params'=>'array'],
'Couchbase\N1qlQuery::profile' => ['', 'profileType'=>'string'],
'Couchbase\N1qlQuery::readonly' => ['Couchbase\N1qlQuery', 'readonly'=>'bool'],
'Couchbase\N1qlQuery::scanCap' => ['Couchbase\N1qlQuery', 'scanCap'=>'int'],
'Couchbase\NumericRangeSearchFacet::__construct' => ['void'],
'Couchbase\NumericRangeSearchFacet::addRange' => ['Couchbase\NumericRangeSearchFacet', 'name'=>'string', 'min'=>'float', 'max'=>'float'],
'Couchbase\NumericRangeSearchFacet::jsonSerialize' => ['array'],
'Couchbase\NumericRangeSearchQuery::__construct' => ['void'],
'Couchbase\NumericRangeSearchQuery::boost' => ['Couchbase\NumericRangeSearchQuery', 'boost'=>'float'],
'Couchbase\NumericRangeSearchQuery::field' => ['Couchbase\NumericRangeSearchQuery', 'field'=>'string'],
'Couchbase\NumericRangeSearchQuery::jsonSerialize' => ['array'],
'Couchbase\NumericRangeSearchQuery::max' => ['Couchbase\NumericRangeSearchQuery', 'max'=>'float', 'inclusive='=>'bool'],
'Couchbase\NumericRangeSearchQuery::min' => ['Couchbase\NumericRangeSearchQuery', 'min'=>'float', 'inclusive='=>'bool'],
'Couchbase\passthruDecoder' => ['string', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'],
'Couchbase\passthruEncoder' => ['array', 'value'=>'string'],
'Couchbase\PasswordAuthenticator::password' => ['Couchbase\PasswordAuthenticator', 'password'=>'string'],
'Couchbase\PasswordAuthenticator::username' => ['Couchbase\PasswordAuthenticator', 'username'=>'string'],
'Couchbase\PhraseSearchQuery::__construct' => ['void'],
'Couchbase\PhraseSearchQuery::boost' => ['Couchbase\PhraseSearchQuery', 'boost'=>'float'],
'Couchbase\PhraseSearchQuery::field' => ['Couchbase\PhraseSearchQuery', 'field'=>'string'],
'Couchbase\PhraseSearchQuery::jsonSerialize' => ['array'],
'Couchbase\PrefixSearchQuery::__construct' => ['void'],
'Couchbase\PrefixSearchQuery::boost' => ['Couchbase\PrefixSearchQuery', 'boost'=>'float'],
'Couchbase\PrefixSearchQuery::field' => ['Couchbase\PrefixSearchQuery', 'field'=>'string'],
'Couchbase\PrefixSearchQuery::jsonSerialize' => ['array'],
'Couchbase\QueryStringSearchQuery::__construct' => ['void'],
'Couchbase\QueryStringSearchQuery::boost' => ['Couchbase\QueryStringSearchQuery', 'boost'=>'float'],
'Couchbase\QueryStringSearchQuery::jsonSerialize' => ['array'],
'Couchbase\RegexpSearchQuery::__construct' => ['void'],
'Couchbase\RegexpSearchQuery::boost' => ['Couchbase\RegexpSearchQuery', 'boost'=>'float'],
'Couchbase\RegexpSearchQuery::field' => ['Couchbase\RegexpSearchQuery', 'field'=>'string'],
'Couchbase\RegexpSearchQuery::jsonSerialize' => ['array'],
'Couchbase\SearchQuery::__construct' => ['void', 'indexName'=>'string', 'queryPart'=>'Couchbase\SearchQueryPart'],
'Couchbase\SearchQuery::addFacet' => ['Couchbase\SearchQuery', 'name'=>'string', 'facet'=>'Couchbase\SearchFacet'],
'Couchbase\SearchQuery::boolean' => ['Couchbase\BooleanSearchQuery'],
'Couchbase\SearchQuery::booleanField' => ['Couchbase\BooleanFieldSearchQuery', 'value'=>'bool'],
'Couchbase\SearchQuery::conjuncts' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
'Couchbase\SearchQuery::consistentWith' => ['Couchbase\SearchQuery', 'state'=>'Couchbase\MutationState'],
'Couchbase\SearchQuery::dateRange' => ['Couchbase\DateRangeSearchQuery'],
'Couchbase\SearchQuery::dateRangeFacet' => ['Couchbase\DateRangeSearchFacet', 'field'=>'string', 'limit'=>'int'],
'Couchbase\SearchQuery::disjuncts' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array<int,Couchbase\SearchQueryPart>'],
'Couchbase\SearchQuery::docId' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array<int,string>'],
'Couchbase\SearchQuery::explain' => ['Couchbase\SearchQuery', 'explain'=>'bool'],
'Couchbase\SearchQuery::fields' => ['Couchbase\SearchQuery', '...fields='=>'array<int,string>'],
'Couchbase\SearchQuery::geoBoundingBox' => ['Couchbase\GeoBoundingBoxSearchQuery', 'topLeftLongitude'=>'float', 'topLeftLatitude'=>'float', 'bottomRightLongitude'=>'float', 'bottomRightLatitude'=>'float'],
'Couchbase\SearchQuery::geoDistance' => ['Couchbase\GeoDistanceSearchQuery', 'longitude'=>'float', 'latitude'=>'float', 'distance'=>'string'],
'Couchbase\SearchQuery::highlight' => ['Couchbase\SearchQuery', 'style'=>'string', '...fields='=>'array<int,string>'],
'Couchbase\SearchQuery::jsonSerialize' => ['array'],
'Couchbase\SearchQuery::limit' => ['Couchbase\SearchQuery', 'limit'=>'int'],
'Couchbase\SearchQuery::match' => ['Couchbase\MatchSearchQuery', 'match'=>'string'],
'Couchbase\SearchQuery::matchAll' => ['Couchbase\MatchAllSearchQuery'],
'Couchbase\SearchQuery::matchNone' => ['Couchbase\MatchNoneSearchQuery'],
'Couchbase\SearchQuery::matchPhrase' => ['Couchbase\MatchPhraseSearchQuery', '...terms='=>'array<int,string>'],
'Couchbase\SearchQuery::numericRange' => ['Couchbase\NumericRangeSearchQuery'],
'Couchbase\SearchQuery::numericRangeFacet' => ['Couchbase\NumericRangeSearchFacet', 'field'=>'string', 'limit'=>'int'],
'Couchbase\SearchQuery::prefix' => ['Couchbase\PrefixSearchQuery', 'prefix'=>'string'],
'Couchbase\SearchQuery::queryString' => ['Couchbase\QueryStringSearchQuery', 'queryString'=>'string'],
'Couchbase\SearchQuery::regexp' => ['Couchbase\RegexpSearchQuery', 'regexp'=>'string'],
'Couchbase\SearchQuery::serverSideTimeout' => ['Couchbase\SearchQuery', 'serverSideTimeout'=>'int'],
'Couchbase\SearchQuery::skip' => ['Couchbase\SearchQuery', 'skip'=>'int'],
'Couchbase\SearchQuery::sort' => ['Couchbase\SearchQuery', '...sort='=>'array<int,Couchbase\sort>'],
'Couchbase\SearchQuery::term' => ['Couchbase\TermSearchQuery', 'term'=>'string'],
'Couchbase\SearchQuery::termFacet' => ['Couchbase\TermSearchFacet', 'field'=>'string', 'limit'=>'int'],
'Couchbase\SearchQuery::termRange' => ['Couchbase\TermRangeSearchQuery'],
'Couchbase\SearchQuery::wildcard' => ['Couchbase\WildcardSearchQuery', 'wildcard'=>'string'],
'Couchbase\SearchSort::__construct' => ['void'],
'Couchbase\SearchSort::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
'Couchbase\SearchSort::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
'Couchbase\SearchSort::id' => ['Couchbase\SearchSortId'],
'Couchbase\SearchSort::score' => ['Couchbase\SearchSortScore'],
'Couchbase\SearchSortField::__construct' => ['void'],
'Couchbase\SearchSortField::descending' => ['Couchbase\SearchSortField', 'descending'=>'bool'],
'Couchbase\SearchSortField::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
'Couchbase\SearchSortField::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
'Couchbase\SearchSortField::id' => ['Couchbase\SearchSortId'],
'Couchbase\SearchSortField::jsonSerialize' => ['mixed'],
'Couchbase\SearchSortField::missing' => ['', 'missing'=>'string'],
'Couchbase\SearchSortField::mode' => ['', 'mode'=>'string'],
'Couchbase\SearchSortField::score' => ['Couchbase\SearchSortScore'],
'Couchbase\SearchSortField::type' => ['', 'type'=>'string'],
'Couchbase\SearchSortGeoDistance::__construct' => ['void'],
'Couchbase\SearchSortGeoDistance::descending' => ['Couchbase\SearchSortGeoDistance', 'descending'=>'bool'],
'Couchbase\SearchSortGeoDistance::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
'Couchbase\SearchSortGeoDistance::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
'Couchbase\SearchSortGeoDistance::id' => ['Couchbase\SearchSortId'],
'Couchbase\SearchSortGeoDistance::jsonSerialize' => ['mixed'],
'Couchbase\SearchSortGeoDistance::score' => ['Couchbase\SearchSortScore'],
'Couchbase\SearchSortGeoDistance::unit' => ['Couchbase\SearchSortGeoDistance', 'unit'=>'string'],
'Couchbase\SearchSortId::__construct' => ['void'],
'Couchbase\SearchSortId::descending' => ['Couchbase\SearchSortId', 'descending'=>'bool'],
'Couchbase\SearchSortId::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
'Couchbase\SearchSortId::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
'Couchbase\SearchSortId::id' => ['Couchbase\SearchSortId'],
'Couchbase\SearchSortId::jsonSerialize' => ['mixed'],
'Couchbase\SearchSortId::score' => ['Couchbase\SearchSortScore'],
'Couchbase\SearchSortScore::__construct' => ['void'],
'Couchbase\SearchSortScore::descending' => ['Couchbase\SearchSortScore', 'descending'=>'bool'],
'Couchbase\SearchSortScore::field' => ['Couchbase\SearchSortField', 'field'=>'string'],
'Couchbase\SearchSortScore::geoDistance' => ['Couchbase\SearchSortGeoDistance', 'field'=>'string', 'longitude'=>'float', 'latitude'=>'float'],
'Couchbase\SearchSortScore::id' => ['Couchbase\SearchSortId'],
'Couchbase\SearchSortScore::jsonSerialize' => ['mixed'],
'Couchbase\SearchSortScore::score' => ['Couchbase\SearchSortScore'],
'Couchbase\SpatialViewQuery::__construct' => ['void'],
'Couchbase\SpatialViewQuery::bbox' => ['Couchbase\SpatialViewQuery', 'bbox'=>'array'],
'Couchbase\SpatialViewQuery::consistency' => ['Couchbase\SpatialViewQuery', 'consistency'=>'int'],
'Couchbase\SpatialViewQuery::custom' => ['', 'customParameters'=>'array'],
'Couchbase\SpatialViewQuery::encode' => ['array'],
'Couchbase\SpatialViewQuery::endRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'],
'Couchbase\SpatialViewQuery::limit' => ['Couchbase\SpatialViewQuery', 'limit'=>'int'],
'Couchbase\SpatialViewQuery::order' => ['Couchbase\SpatialViewQuery', 'order'=>'int'],
'Couchbase\SpatialViewQuery::skip' => ['Couchbase\SpatialViewQuery', 'skip'=>'int'],
'Couchbase\SpatialViewQuery::startRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'],
'Couchbase\TermRangeSearchQuery::__construct' => ['void'],
'Couchbase\TermRangeSearchQuery::boost' => ['Couchbase\TermRangeSearchQuery', 'boost'=>'float'],
'Couchbase\TermRangeSearchQuery::field' => ['Couchbase\TermRangeSearchQuery', 'field'=>'string'],
'Couchbase\TermRangeSearchQuery::jsonSerialize' => ['array'],
'Couchbase\TermRangeSearchQuery::max' => ['Couchbase\TermRangeSearchQuery', 'max'=>'string', 'inclusive='=>'bool'],
'Couchbase\TermRangeSearchQuery::min' => ['Couchbase\TermRangeSearchQuery', 'min'=>'string', 'inclusive='=>'bool'],
'Couchbase\TermSearchFacet::__construct' => ['void'],
'Couchbase\TermSearchFacet::jsonSerialize' => ['array'],
'Couchbase\TermSearchQuery::__construct' => ['void'],
'Couchbase\TermSearchQuery::boost' => ['Couchbase\TermSearchQuery', 'boost'=>'float'],
'Couchbase\TermSearchQuery::field' => ['Couchbase\TermSearchQuery', 'field'=>'string'],
'Couchbase\TermSearchQuery::fuzziness' => ['Couchbase\TermSearchQuery', 'fuzziness'=>'int'],
'Couchbase\TermSearchQuery::jsonSerialize' => ['array'],
'Couchbase\TermSearchQuery::prefixLength' => ['Couchbase\TermSearchQuery', 'prefixLength'=>'int'],
'Couchbase\UserSettings::fullName' => ['Couchbase\UserSettings', 'fullName'=>'string'],
'Couchbase\UserSettings::password' => ['Couchbase\UserSettings', 'password'=>'string'],
'Couchbase\UserSettings::role' => ['Couchbase\UserSettings', 'role'=>'string', 'bucket='=>'string'],
'Couchbase\ViewQuery::__construct' => ['void'],
'Couchbase\ViewQuery::consistency' => ['Couchbase\ViewQuery', 'consistency'=>'int'],
'Couchbase\ViewQuery::custom' => ['Couchbase\ViewQuery', 'customParameters'=>'array'],
'Couchbase\ViewQuery::encode' => ['array'],
'Couchbase\ViewQuery::from' => ['Couchbase\ViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'],
'Couchbase\ViewQuery::fromSpatial' => ['Couchbase\SpatialViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'],
'Couchbase\ViewQuery::group' => ['Couchbase\ViewQuery', 'group'=>'bool'],
'Couchbase\ViewQuery::groupLevel' => ['Couchbase\ViewQuery', 'groupLevel'=>'int'],
'Couchbase\ViewQuery::idRange' => ['Couchbase\ViewQuery', 'startKeyDocumentId'=>'string', 'endKeyDocumentId'=>'string'],
'Couchbase\ViewQuery::key' => ['Couchbase\ViewQuery', 'key'=>'mixed'],
'Couchbase\ViewQuery::keys' => ['Couchbase\ViewQuery', 'keys'=>'array'],
'Couchbase\ViewQuery::limit' => ['Couchbase\ViewQuery', 'limit'=>'int'],
'Couchbase\ViewQuery::order' => ['Couchbase\ViewQuery', 'order'=>'int'],
'Couchbase\ViewQuery::range' => ['Couchbase\ViewQuery', 'startKey'=>'mixed', 'endKey'=>'mixed', 'inclusiveEnd='=>'bool'],
'Couchbase\ViewQuery::reduce' => ['Couchbase\ViewQuery', 'reduce'=>'bool'],
'Couchbase\ViewQuery::skip' => ['Couchbase\ViewQuery', 'skip'=>'int'],
'Couchbase\ViewQueryEncodable::encode' => ['array'],
'Couchbase\WildcardSearchQuery::__construct' => ['void'],
'Couchbase\WildcardSearchQuery::boost' => ['Couchbase\WildcardSearchQuery', 'boost'=>'float'],
'Couchbase\WildcardSearchQuery::field' => ['Couchbase\WildcardSearchQuery', 'field'=>'string'],
'Couchbase\WildcardSearchQuery::jsonSerialize' => ['array'],
'Couchbase\zlibCompress' => ['string', 'data'=>'string'],
'Couchbase\zlibDecompress' => ['string', 'data'=>'string'],
'count' => ['int<0, max>', 'value'=>'Countable|array', 'mode='=>'int'],
'count_chars' => ['array<int,int>', 'input'=>'string', 'mode='=>'0|1|2'],
'count_chars\'1' => ['string', 'input'=>'string', 'mode='=>'3|4'],
'Countable::count' => ['int'],
'crack_check' => ['bool', 'dictionary'=>'', 'password'=>'string'],
'crack_closedict' => ['bool', 'dictionary='=>'resource'],
'crack_getlastmessage' => ['string'],
'crack_opendict' => ['resource|false', 'dictionary'=>'string'],
'crash' => [''],
'crc32' => ['int', 'string'=>'string'],
'crypt' => ['string', 'string'=>'string', 'salt='=>'string'],
'ctype_alnum' => ['bool', 'text'=>'string|int'],
'ctype_alpha' => ['bool', 'text'=>'string|int'],
'ctype_cntrl' => ['bool', 'text'=>'string|int'],
'ctype_digit' => ['bool', 'text'=>'string|int'],
'ctype_graph' => ['bool', 'text'=>'string|int'],
'ctype_lower' => ['bool', 'text'=>'string|int'],
'ctype_print' => ['bool', 'text'=>'string|int'],
'ctype_punct' => ['bool', 'text'=>'string|int'],
'ctype_space' => ['bool', 'text'=>'string|int'],
'ctype_upper' => ['bool', 'text'=>'string|int'],
'ctype_xdigit' => ['bool', 'text'=>'string|int'],
'cubrid_affected_rows' => ['int', 'req_identifier='=>''],
'cubrid_bind' => ['bool', 'req_identifier'=>'resource', 'bind_param'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'],
'cubrid_client_encoding' => ['string', 'conn_identifier='=>''],
'cubrid_close' => ['bool', 'conn_identifier='=>''],
'cubrid_close_prepare' => ['bool', 'req_identifier'=>'resource'],
'cubrid_close_request' => ['bool', 'req_identifier'=>'resource'],
'cubrid_col_get' => ['array', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'],
'cubrid_col_size' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'],
'cubrid_column_names' => ['array', 'req_identifier'=>'resource'],
'cubrid_column_types' => ['array', 'req_identifier'=>'resource'],
'cubrid_commit' => ['bool', 'conn_identifier'=>'resource'],
'cubrid_connect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'],
'cubrid_connect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'],
'cubrid_current_oid' => ['string', 'req_identifier'=>'resource'],
'cubrid_data_seek' => ['bool', 'req_identifier'=>'', 'row_number'=>'int'],
'cubrid_db_name' => ['string', 'result'=>'array', 'index'=>'int'],
'cubrid_db_parameter' => ['array', 'conn_identifier'=>'resource'],
'cubrid_disconnect' => ['bool', 'conn_identifier'=>'resource'],
'cubrid_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'],
'cubrid_errno' => ['int', 'conn_identifier='=>''],
'cubrid_error' => ['string', 'connection='=>''],
'cubrid_error_code' => ['int'],
'cubrid_error_code_facility' => ['int'],
'cubrid_error_msg' => ['string'],
'cubrid_execute' => ['bool', 'conn_identifier'=>'', 'sql'=>'string', 'option='=>'int', 'request_identifier='=>''],
'cubrid_fetch' => ['mixed', 'result'=>'resource', 'type='=>'int'],
'cubrid_fetch_array' => ['array', 'result'=>'resource', 'type='=>'int'],
'cubrid_fetch_assoc' => ['array', 'result'=>'resource'],
'cubrid_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'],
'cubrid_fetch_lengths' => ['array', 'result'=>'resource'],
'cubrid_fetch_object' => ['object', 'result'=>'resource', 'class_name='=>'string', 'params='=>'array'],
'cubrid_fetch_row' => ['array', 'result'=>'resource'],
'cubrid_field_flags' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
'cubrid_field_len' => ['int', 'result'=>'resource', 'field_offset'=>'int'],
'cubrid_field_name' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
'cubrid_field_seek' => ['bool', 'result'=>'resource', 'field_offset='=>'int'],
'cubrid_field_table' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
'cubrid_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
'cubrid_free_result' => ['bool', 'req_identifier'=>'resource'],
'cubrid_get' => ['mixed', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'mixed'],
'cubrid_get_autocommit' => ['bool', 'conn_identifier'=>'resource'],
'cubrid_get_charset' => ['string', 'conn_identifier'=>'resource'],
'cubrid_get_class_name' => ['string', 'conn_identifier'=>'resource', 'oid'=>'string'],
'cubrid_get_client_info' => ['string'],
'cubrid_get_db_parameter' => ['array', 'conn_identifier'=>'resource'],
'cubrid_get_query_timeout' => ['int', 'req_identifier'=>'resource'],
'cubrid_get_server_info' => ['string', 'conn_identifier'=>'resource'],
'cubrid_insert_id' => ['string', 'conn_identifier='=>'resource'],
'cubrid_is_instance' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string'],
'cubrid_list_dbs' => ['array', 'conn_identifier'=>'resource'],
'cubrid_load_from_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'],
'cubrid_lob2_bind' => ['bool', 'req_identifier'=>'resource', 'bind_index'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'],
'cubrid_lob2_close' => ['bool', 'lob_identifier'=>'resource'],
'cubrid_lob2_export' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'],
'cubrid_lob2_import' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'],
'cubrid_lob2_new' => ['resource', 'conn_identifier='=>'resource', 'type='=>'string'],
'cubrid_lob2_read' => ['string', 'lob_identifier'=>'resource', 'length'=>'int'],
'cubrid_lob2_seek' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'],
'cubrid_lob2_seek64' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'string', 'origin='=>'int'],
'cubrid_lob2_size' => ['int', 'lob_identifier'=>'resource'],
'cubrid_lob2_size64' => ['string', 'lob_identifier'=>'resource'],
'cubrid_lob2_tell' => ['int', 'lob_identifier'=>'resource'],
'cubrid_lob2_tell64' => ['string', 'lob_identifier'=>'resource'],
'cubrid_lob2_write' => ['bool', 'lob_identifier'=>'resource', 'buf'=>'string'],
'cubrid_lob_close' => ['bool', 'lob_identifier_array'=>'array'],
'cubrid_lob_export' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource', 'path_name'=>'string'],
'cubrid_lob_get' => ['array', 'conn_identifier'=>'resource', 'sql'=>'string'],
'cubrid_lob_send' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource'],
'cubrid_lob_size' => ['string', 'lob_identifier'=>'resource'],
'cubrid_lock_read' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'],
'cubrid_lock_write' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'],
'cubrid_move_cursor' => ['int', 'req_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'],
'cubrid_new_glo' => ['string', 'conn_identifier'=>'', 'class_name'=>'string', 'file_name'=>'string'],
'cubrid_next_result' => ['bool', 'result'=>'resource'],
'cubrid_num_cols' => ['int', 'req_identifier'=>'resource'],
'cubrid_num_fields' => ['int', 'result'=>'resource'],
'cubrid_num_rows' => ['int', 'req_identifier'=>'resource'],
'cubrid_pconnect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'],
'cubrid_pconnect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'],
'cubrid_ping' => ['bool', 'conn_identifier='=>''],
'cubrid_prepare' => ['resource', 'conn_identifier'=>'resource', 'prepare_stmt'=>'string', 'option='=>'int'],
'cubrid_put' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'string', 'value='=>'mixed'],
'cubrid_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''],
'cubrid_real_escape_string' => ['string', 'unescaped_string'=>'string', 'conn_identifier='=>''],
'cubrid_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>''],
'cubrid_rollback' => ['bool', 'conn_identifier'=>'resource'],
'cubrid_save_to_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'],
'cubrid_schema' => ['array', 'conn_identifier'=>'resource', 'schema_type'=>'int', 'class_name='=>'string', 'attr_name='=>'string'],
'cubrid_send_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string'],
'cubrid_seq_add' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'seq_element'=>'string'],
'cubrid_seq_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int'],
'cubrid_seq_insert' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'],
'cubrid_seq_put' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'],
'cubrid_set_add' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'],
'cubrid_set_autocommit' => ['bool', 'conn_identifier'=>'resource', 'mode'=>'bool'],
'cubrid_set_db_parameter' => ['bool', 'conn_identifier'=>'resource', 'param_type'=>'int', 'param_value'=>'int'],
'cubrid_set_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'],
'cubrid_set_query_timeout' => ['bool', 'req_identifier'=>'resource', 'timeout'=>'int'],
'cubrid_unbuffered_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''],
'cubrid_version' => ['string'],
'curl_close' => ['void', 'handle'=>'CurlHandle'],
'curl_copy_handle' => ['CurlHandle', 'handle'=>'CurlHandle'],
'curl_errno' => ['int', 'handle'=>'CurlHandle'],
'curl_error' => ['string', 'handle'=>'CurlHandle'],
'curl_escape' => ['string|false', 'handle'=>'CurlHandle', 'string'=>'string'],
'curl_exec' => ['bool|string', 'handle'=>'CurlHandle'],
'curl_file_create' => ['CURLFile', 'filename'=>'string', 'mime_type='=>'string|null', 'posted_filename='=>'string|null'],
'curl_getinfo' => ['mixed', 'handle'=>'CurlHandle', 'option='=>'?int'],
'curl_init' => ['CurlHandle|false', 'url='=>'?string'],
'curl_multi_add_handle' => ['int', 'multi_handle'=>'CurlMultiHandle', 'handle'=>'CurlHandle'],
'curl_multi_close' => ['void', 'multi_handle'=>'CurlMultiHandle'],
'curl_multi_errno' => ['int', 'multi_handle'=>'CurlMultiHandle'],
'curl_multi_exec' => ['int', 'multi_handle'=>'CurlMultiHandle', '&w_still_running'=>'int'],
'curl_multi_getcontent' => ['string', 'handle'=>'CurlHandle'],
'curl_multi_info_read' => ['array|false', 'multi_handle'=>'CurlMultiHandle', '&w_queued_messages='=>'int'],
'curl_multi_init' => ['CurlMultiHandle'],
'curl_multi_remove_handle' => ['int', 'multi_handle'=>'CurlMultiHandle', 'handle'=>'CurlHandle'],
'curl_multi_select' => ['int', 'multi_handle'=>'CurlMultiHandle', 'timeout='=>'float'],
'curl_multi_setopt' => ['bool', 'multi_handle'=>'CurlMultiHandle', 'option'=>'int', 'value'=>'mixed'],
'curl_multi_strerror' => ['?string', 'error_code'=>'int'],
'curl_pause' => ['int', 'handle'=>'CurlHandle', 'flags'=>'int'],
'curl_reset' => ['void', 'handle'=>'CurlHandle'],
'curl_setopt' => ['bool', 'handle'=>'CurlHandle', 'option'=>'int', 'value'=>'callable|mixed'],
'curl_setopt_array' => ['bool', 'handle'=>'CurlHandle', 'options'=>'array'],
'curl_share_close' => ['void', 'share_handle'=>'CurlShareHandle'],
'curl_share_errno' => ['int', 'share_handle'=>'CurlShareHandle'],
'curl_share_init' => ['CurlShareHandle'],
'curl_share_setopt' => ['bool', 'share_handle'=>'CurlShareHandle', 'option'=>'int', 'value'=>'mixed'],
'curl_share_strerror' => ['?string', 'error_code'=>'int'],
'curl_strerror' => ['?string', 'error_code'=>'int'],
'curl_upkeep' => ['bool', 'handle'=>'CurlHandle'],
'curl_unescape' => ['string|false', 'handle'=>'CurlHandle', 'string'=>'string'],
'curl_version' => ['array', 'version='=>'int'],
'CURLFile::__construct' => ['void', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'],
'CURLFile::__wakeup' => ['void'],
'CURLFile::getFilename' => ['string'],
'CURLFile::getMimeType' => ['string'],
'CURLFile::getPostFilename' => ['string'],
'CURLFile::setMimeType' => ['void', 'mime'=>'string'],
'CURLFile::setPostFilename' => ['void', 'name'=>'string'],
'CURLStringFile::__construct' => ['void', 'data'=>'string', 'postname'=>'string', 'mime='=>'string'],
'current' => ['mixed|false', 'array'=>'array|object'],
'cyrus_authenticate' => ['void', 'connection'=>'resource', 'mechlist='=>'string', 'service='=>'string', 'user='=>'string', 'minssf='=>'int', 'maxssf='=>'int', 'authname='=>'string', 'password='=>'string'],
'cyrus_bind' => ['bool', 'connection'=>'resource', 'callbacks'=>'array'],
'cyrus_close' => ['bool', 'connection'=>'resource'],
'cyrus_connect' => ['resource', 'host='=>'string', 'port='=>'string', 'flags='=>'int'],
'cyrus_query' => ['array', 'connection'=>'resource', 'query'=>'string'],
'cyrus_unbind' => ['bool', 'connection'=>'resource', 'trigger_name'=>'string'],
'date' => ['string', 'format'=>'string', 'timestamp='=>'?int'],
'date_add' => ['DateTime', 'object'=>'DateTime', 'interval'=>'DateInterval'],
'date_create' => ['DateTime|false', 'datetime='=>'string', 'timezone='=>'?DateTimeZone'],
'date_create_from_format' => ['DateTime|false', 'format'=>'string', 'datetime'=>'string', 'timezone='=>'?\DateTimeZone'],
'date_create_immutable' => ['DateTimeImmutable|false', 'datetime='=>'string', 'timezone='=>'?DateTimeZone'],
'date_create_immutable_from_format' => ['DateTimeImmutable|false', 'format'=>'string', 'datetime'=>'string', 'timezone='=>'?DateTimeZone'],
'date_date_set' => ['DateTime', 'object'=>'DateTime', 'year'=>'int', 'month'=>'int', 'day'=>'int'],
'date_default_timezone_get' => ['string'],
'date_default_timezone_set' => ['bool', 'timezoneId'=>'string'],
'date_diff' => ['DateInterval', 'baseObject'=>'DateTimeInterface', 'targetObject'=>'DateTimeInterface', 'absolute='=>'bool'],
'date_format' => ['string', 'object'=>'DateTimeInterface', 'format'=>'string'],
'date_get_last_errors' => ['array{warning_count:int,warnings:array<int,string>,error_count:int,errors:array<int,string>}|false'],
'date_interval_create_from_date_string' => ['DateInterval', 'datetime'=>'string'],
'date_interval_format' => ['string', 'object'=>'DateInterval', 'format'=>'string'],
'date_isodate_set' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'week'=>'int', 'dayOfWeek='=>'int|mixed'],
'date_modify' => ['DateTime|false', 'object'=>'DateTime', 'modifier'=>'string'],
'date_offset_get' => ['int', 'object'=>'DateTimeInterface'],
'date_parse' => ['array', 'datetime'=>'string'],
'date_parse_from_format' => ['array', 'format'=>'string', 'datetime'=>'string'],
'date_sub' => ['DateTime', 'object'=>'DateTime', 'interval'=>'DateInterval'],
'date_sun_info' => ['array', 'timestamp'=>'int', 'latitude'=>'float', 'longitude'=>'float'],
'date_sunrise' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'?float', 'longitude='=>'?float', 'zenith='=>'?float', 'utcOffset='=>'?float'],
'date_sunset' => ['string|int|float|false', 'timestamp'=>'int', 'returnFormat='=>'int', 'latitude='=>'?float', 'longitude='=>'?float', 'zenith='=>'?float', 'utcOffset='=>'?float'],
'date_time_set' => ['DateTime', 'object'=>'', 'hour'=>'', 'minute'=>'', 'second='=>'', 'microsecond='=>''],
'date_timestamp_get' => ['int', 'object'=>'DateTimeInterface'],
'date_timestamp_set' => ['DateTime', 'object'=>'DateTime', 'timestamp'=>'int'],
'date_timezone_get' => ['DateTimeZone|false', 'object'=>'DateTimeInterface'],
'date_timezone_set' => ['DateTime', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'],
'datefmt_create' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType='=>'int', 'timeType='=>'int', 'timezone='=>'DateTimeZone|IntlTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
'datefmt_format' => ['string|false', 'formatter'=>'IntlDateFormatter', 'datetime'=>'DateTime|IntlCalendar|array|int'],
'datefmt_format_object' => ['string|false', 'datetime'=>'object', 'format='=>'mixed', 'locale='=>'?string'],
'datefmt_get_calendar' => ['int', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_calendar_object' => ['IntlCalendar|false|null', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_datetype' => ['int', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_error_code' => ['int', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_error_message' => ['string', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_locale' => ['string|false', 'formatter'=>'IntlDateFormatter', 'type='=>'int'],
'datefmt_get_pattern' => ['string', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_timetype' => ['int', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_timezone' => ['IntlTimeZone|false', 'formatter'=>'IntlDateFormatter'],
'datefmt_get_timezone_id' => ['string|false', 'formatter'=>'IntlDateFormatter'],
'datefmt_is_lenient' => ['bool', 'formatter'=>'IntlDateFormatter'],
'datefmt_localtime' => ['array|false', 'formatter'=>'IntlDateFormatter', 'string'=>'string', '&rw_offset='=>'int'],
'datefmt_parse' => ['int|false', 'formatter'=>'IntlDateFormatter', 'string'=>'string', '&rw_offset='=>'int'],
'datefmt_set_calendar' => ['bool', 'formatter'=>'IntlDateFormatter', 'calendar'=>'IntlCalendar|int|null'],
'datefmt_set_lenient' => ['void', 'formatter'=>'IntlDateFormatter', 'lenient'=>'bool'],
'datefmt_set_pattern' => ['bool', 'formatter'=>'IntlDateFormatter', 'pattern'=>'string'],
'datefmt_set_timezone' => ['false|null', 'formatter'=>'IntlDateFormatter', 'timezone'=>'IntlTimeZone|DateTimeZone|string|null'],
'DateInterval::__construct' => ['void', 'spec'=>'string'],
'DateInterval::__set_state' => ['DateInterval', 'array'=>'array'],
'DateInterval::__wakeup' => ['void'],
'DateInterval::createFromDateString' => ['DateInterval|false', 'time'=>'string'],
'DateInterval::format' => ['string', 'format'=>'string'],
'DatePeriod::__construct' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'recur'=>'int', 'options='=>'int'],
'DatePeriod::__construct\'1' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'end'=>'DateTimeInterface', 'options='=>'int'],
'DatePeriod::__construct\'2' => ['void', 'iso'=>'string', 'options='=>'int'],
'DatePeriod::__wakeup' => ['void'],
'DatePeriod::getDateInterval' => ['DateInterval'],
'DatePeriod::getEndDate' => ['?DateTimeInterface'],
'DatePeriod::getStartDate' => ['DateTimeInterface'],
'DateTime::__construct' => ['void', 'time='=>'string'],
'DateTime::__construct\'1' => ['void', 'time'=>'?string', 'timezone'=>'?DateTimeZone'],
'DateTime::__wakeup' => ['void'],
'DateTime::add' => ['static', 'interval'=>'DateInterval'],
'DateTime::createFromFormat' => ['static|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'?DateTimeZone'],
'DateTime::createFromImmutable' => ['static', 'object'=>'DateTimeImmutable'],
'DateTime::createFromInterface' => ['static', 'object' => 'DateTimeInterface'],
'DateTime::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'],
'DateTime::format' => ['string', 'format'=>'string'],
'DateTime::getLastErrors' => ['array{warning_count:int,warnings:array<int,string>,error_count:int,errors:array<int,string>}|false'],
'DateTime::getOffset' => ['int'],
'DateTime::getTimestamp' => ['int'],
'DateTime::getTimezone' => ['DateTimeZone|false'],
'DateTime::modify' => ['static|false', 'modify'=>'string'],
'DateTime::setDate' => ['static', 'year'=>'int', 'month'=>'int', 'day'=>'int'],
'DateTime::setISODate' => ['static', 'year'=>'int', 'week'=>'int', 'day='=>'int'],
'DateTime::setTime' => ['static', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'],
'DateTime::setTimestamp' => ['static', 'unixtimestamp'=>'int'],
'DateTime::setTimezone' => ['static', 'timezone'=>'DateTimeZone'],
'DateTime::sub' => ['static', 'interval'=>'DateInterval'],
'DateTimeImmutable::__wakeup' => ['void'],
'DateTimeImmutable::createFromInterface' => ['static', 'object' => 'DateTimeInterface'],
'DateTimeImmutable::getLastErrors' => ['array{warning_count:int,warnings:array<int,string>,error_count:int,errors:array<int,string>}|false'],
'DateTimeInterface::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'],
'DateTimeInterface::format' => ['string', 'format'=>'string'],
'DateTimeInterface::getOffset' => ['int'],
'DateTimeInterface::getTimestamp' => ['int'],
'DateTimeInterface::getTimezone' => ['DateTimeZone|false'],
'DateTimeInterface::__serialize' => ['array'],
'DateTimeInterface::__unserialize' => ['void', 'data'=>'array'],
'DateTimeZone::__construct' => ['void', 'timezone'=>'string'],
'DateTimeZone::__set_state' => ['DateTimeZone', 'array'=>'array'],
'DateTimeZone::__wakeup' => ['void'],
'DateTimeZone::getLocation' => ['array|false'],
'DateTimeZone::getName' => ['string'],
'DateTimeZone::getOffset' => ['int', 'datetime'=>'DateTimeInterface'],
'DateTimeZone::getTransitions' => ['list<array{ts: int, time: string, offset: int, isdst: bool, abbr: string}>|false', 'timestamp_begin='=>'int', 'timestamp_end='=>'int'],
'DateTimeZone::listAbbreviations' => ['array<string, list<array{dst: bool, offset: int, timezone_id: string|null}>>'],
'DateTimeZone::listIdentifiers' => ['list<string>', 'timezoneGroup='=>'int', 'countryCode='=>'string|null'],
'db2_autocommit' => ['mixed', 'connection'=>'resource', 'value='=>'int'],
'db2_bind_param' => ['bool', 'stmt'=>'resource', 'parameter_number'=>'int', 'variable_name'=>'string', 'parameter_type='=>'int', 'data_type='=>'int', 'precision='=>'int', 'scale='=>'int'],
'db2_client_info' => ['object|false', 'connection'=>'resource'],
'db2_close' => ['bool', 'connection'=>'resource'],
'db2_column_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'],
'db2_columns' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'],
'db2_commit' => ['bool', 'connection'=>'resource'],
'db2_conn_error' => ['string', 'connection='=>'resource'],
'db2_conn_errormsg' => ['string', 'connection='=>'resource'],
'db2_connect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'],
'db2_cursor_type' => ['int', 'stmt'=>'resource'],
'db2_escape_string' => ['string', 'string_literal'=>'string'],
'db2_exec' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'],
'db2_execute' => ['bool', 'stmt'=>'resource', 'parameters='=>'array'],
'db2_fetch_array' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'],
'db2_fetch_assoc' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'],
'db2_fetch_both' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'],
'db2_fetch_object' => ['object|false', 'stmt'=>'resource', 'row_number='=>'int'],
'db2_fetch_row' => ['bool', 'stmt'=>'resource', 'row_number='=>'int'],
'db2_field_display_size' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_field_name' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_field_num' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_field_precision' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_field_scale' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_field_type' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_field_width' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_foreign_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'],
'db2_free_result' => ['bool', 'stmt'=>'resource'],
'db2_free_stmt' => ['bool', 'stmt'=>'resource'],
'db2_get_option' => ['string|false', 'resource'=>'resource', 'option'=>'string'],
'db2_last_insert_id' => ['string', 'resource'=>'resource'],
'db2_lob_read' => ['string|false', 'stmt'=>'resource', 'colnum'=>'int', 'length'=>'int'],
'db2_next_result' => ['resource|false', 'stmt'=>'resource'],
'db2_num_fields' => ['int|false', 'stmt'=>'resource'],
'db2_num_rows' => ['int', 'stmt'=>'resource'],
'db2_pclose' => ['bool', 'resource'=>'resource'],
'db2_pconnect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'],
'db2_prepare' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'],
'db2_primary_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'],
'db2_primarykeys' => [''],
'db2_procedure_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string', 'parameter'=>'string'],
'db2_procedurecolumns' => [''],
'db2_procedures' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string'],
'db2_result' => ['mixed', 'stmt'=>'resource', 'column'=>'mixed'],
'db2_rollback' => ['bool', 'connection'=>'resource'],
'db2_server_info' => ['object|false', 'connection'=>'resource'],
'db2_set_option' => ['bool', 'resource'=>'resource', 'options'=>'array', 'type'=>'int'],
'db2_setoption' => [''],
'db2_special_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'scope'=>'int'],
'db2_specialcolumns' => [''],
'db2_statistics' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'unique'=>'bool'],
'db2_stmt_error' => ['string', 'stmt='=>'resource'],
'db2_stmt_errormsg' => ['string', 'stmt='=>'resource'],
'db2_table_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string'],
'db2_tableprivileges' => [''],
'db2_tables' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'table_type='=>'string'],
'dba_close' => ['void', 'dba'=>'resource'],
'dba_delete' => ['bool', 'key'=>'string', 'dba'=>'resource'],
'dba_exists' => ['bool', 'key'=>'string', 'dba'=>'resource'],
'dba_fetch' => ['string|false', 'key'=>'string', 'skip'=>'int', 'dba'=>'resource'],
'dba_fetch\'1' => ['string|false', 'key'=>'string', 'skip'=>'resource'],
'dba_firstkey' => ['string', 'dba'=>'resource'],
'dba_handlers' => ['array', 'full_info='=>'bool'],
'dba_insert' => ['bool', 'key'=>'string', 'value'=>'string', 'dba'=>'resource'],
'dba_key_split' => ['array|false', 'key'=>'string|false|null'],
'dba_list' => ['array'],
'dba_nextkey' => ['string', 'dba'=>'resource'],
'dba_open' => ['resource', 'path'=>'string', 'mode'=>'string', 'handler='=>'string', '...handler_params='=>'string'],
'dba_optimize' => ['bool', 'dba'=>'resource'],
'dba_popen' => ['resource', 'path'=>'string', 'mode'=>'string', 'handler='=>'string', '...handler_params='=>'string'],
'dba_replace' => ['bool', 'key'=>'string', 'value'=>'string', 'dba'=>'resource'],
'dba_sync' => ['bool', 'dba'=>'resource'],
'dbase_add_record' => ['bool', 'dbase_identifier'=>'resource', 'record'=>'array'],
'dbase_close' => ['bool', 'dbase_identifier'=>'resource'],
'dbase_create' => ['resource|false', 'filename'=>'string', 'fields'=>'array'],
'dbase_delete_record' => ['bool', 'dbase_identifier'=>'resource', 'record_number'=>'int'],
'dbase_get_header_info' => ['array', 'dbase_identifier'=>'resource'],
'dbase_get_record' => ['array', 'dbase_identifier'=>'resource', 'record_number'=>'int'],
'dbase_get_record_with_names' => ['array', 'dbase_identifier'=>'resource', 'record_number'=>'int'],
'dbase_numfields' => ['int', 'dbase_identifier'=>'resource'],
'dbase_numrecords' => ['int', 'dbase_identifier'=>'resource'],
'dbase_open' => ['resource|false', 'filename'=>'string', 'mode'=>'int'],
'dbase_pack' => ['bool', 'dbase_identifier'=>'resource'],
'dbase_replace_record' => ['bool', 'dbase_identifier'=>'resource', 'record'=>'array', 'record_number'=>'int'],
'dbplus_add' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
'dbplus_aql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'],
'dbplus_chdir' => ['string', 'newdir='=>'string'],
'dbplus_close' => ['mixed', 'relation'=>'resource'],
'dbplus_curr' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
'dbplus_errcode' => ['string', 'errno='=>'int'],
'dbplus_errno' => ['int'],
'dbplus_find' => ['int', 'relation'=>'resource', 'constraints'=>'array', 'tuple'=>'mixed'],
'dbplus_first' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
'dbplus_flush' => ['int', 'relation'=>'resource'],
'dbplus_freealllocks' => ['int'],
'dbplus_freelock' => ['int', 'relation'=>'resource', 'tuple'=>'string'],
'dbplus_freerlocks' => ['int', 'relation'=>'resource'],
'dbplus_getlock' => ['int', 'relation'=>'resource', 'tuple'=>'string'],
'dbplus_getunique' => ['int', 'relation'=>'resource', 'uniqueid'=>'int'],
'dbplus_info' => ['int', 'relation'=>'resource', 'key'=>'string', 'result'=>'array'],
'dbplus_last' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
'dbplus_lockrel' => ['int', 'relation'=>'resource'],
'dbplus_next' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
'dbplus_open' => ['resource', 'name'=>'string'],
'dbplus_prev' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
'dbplus_rchperm' => ['int', 'relation'=>'resource', 'mask'=>'int', 'user'=>'string', 'group'=>'string'],
'dbplus_rcreate' => ['resource', 'name'=>'string', 'domlist'=>'mixed', 'overwrite='=>'bool'],
'dbplus_rcrtexact' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'bool'],
'dbplus_rcrtlike' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'int'],
'dbplus_resolve' => ['array', 'relation_name'=>'string'],
'dbplus_restorepos' => ['int', 'relation'=>'resource', 'tuple'=>'array'],
'dbplus_rkeys' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed'],
'dbplus_ropen' => ['resource', 'name'=>'string'],
'dbplus_rquery' => ['resource', 'query'=>'string', 'dbpath='=>'string'],
'dbplus_rrename' => ['int', 'relation'=>'resource', 'name'=>'string'],
'dbplus_rsecindex' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed', 'type'=>'int'],
'dbplus_runlink' => ['int', 'relation'=>'resource'],
'dbplus_rzap' => ['int', 'relation'=>'resource'],
'dbplus_savepos' => ['int', 'relation'=>'resource'],
'dbplus_setindex' => ['int', 'relation'=>'resource', 'idx_name'=>'string'],
'dbplus_setindexbynumber' => ['int', 'relation'=>'resource', 'idx_number'=>'int'],
'dbplus_sql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'],
'dbplus_tcl' => ['string', 'sid'=>'int', 'script'=>'string'],
'dbplus_tremove' => ['int', 'relation'=>'resource', 'tuple'=>'array', 'current='=>'array'],
'dbplus_undo' => ['int', 'relation'=>'resource'],
'dbplus_undoprepare' => ['int', 'relation'=>'resource'],
'dbplus_unlockrel' => ['int', 'relation'=>'resource'],
'dbplus_unselect' => ['int', 'relation'=>'resource'],
'dbplus_update' => ['int', 'relation'=>'resource', 'old'=>'array', 'new'=>'array'],
'dbplus_xlockrel' => ['int', 'relation'=>'resource'],
'dbplus_xunlockrel' => ['int', 'relation'=>'resource'],
'dbx_close' => ['int', 'link_identifier'=>'object'],
'dbx_compare' => ['int', 'row_a'=>'array', 'row_b'=>'array', 'column_key'=>'string', 'flags='=>'int'],
'dbx_connect' => ['object', 'module'=>'mixed', 'host'=>'string', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'persistent='=>'int'],
'dbx_error' => ['string', 'link_identifier'=>'object'],
'dbx_escape_string' => ['string', 'link_identifier'=>'object', 'text'=>'string'],
'dbx_fetch_row' => ['mixed', 'result_identifier'=>'object'],
'dbx_query' => ['mixed', 'link_identifier'=>'object', 'sql_statement'=>'string', 'flags='=>'int'],
'dbx_sort' => ['bool', 'result'=>'object', 'user_compare_function'=>'string'],
'dcgettext' => ['string', 'domain'=>'string', 'message'=>'string', 'category'=>'int'],
'dcngettext' => ['string', 'domain'=>'string', 'singular'=>'string', 'plural'=>'string', 'count'=>'int', 'category'=>'int'],
'deaggregate' => ['', 'object'=>'object', 'class_name='=>'string'],
'debug_backtrace' => ['list<array{file:string,line:int,function:string,class?:class-string,object?:object,type?:string,args?:list}>', 'options='=>'int', 'limit='=>'int'],
'debug_print_backtrace' => ['void', 'options='=>'int', 'limit='=>'int'],
'debug_zval_dump' => ['void', '...value'=>'mixed'],
'debugger_connect' => [''],
'debugger_connector_pid' => [''],
'debugger_get_server_start_time' => [''],
'debugger_print' => [''],
'debugger_start_debug' => [''],
'decbin' => ['string', 'num'=>'int'],
'dechex' => ['string', 'num'=>'int'],
'decoct' => ['string', 'num'=>'int'],
'define' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'case_insensitive='=>'bool'],
'define_syslog_variables' => ['void'],
'defined' => ['bool', 'constant_name'=>'string'],
'deflate_add' => ['string|false', 'context'=>'DeflateContext', 'data'=>'string', 'flush_mode='=>'int'],
'deflate_init' => ['DeflateContext|false', 'encoding'=>'int', 'options='=>'array'],
'deg2rad' => ['float', 'num'=>'float'],
'dgettext' => ['string', 'domain'=>'string', 'message'=>'string'],
'dio_close' => ['void', 'fd'=>'resource'],
'dio_fcntl' => ['mixed', 'fd'=>'resource', 'cmd'=>'int', 'args='=>'mixed'],
'dio_open' => ['resource|false', 'filename'=>'string', 'flags'=>'int', 'mode='=>'int'],
'dio_read' => ['string', 'fd'=>'resource', 'length='=>'int'],
'dio_seek' => ['int', 'fd'=>'resource', 'pos'=>'int', 'whence='=>'int'],
'dio_stat' => ['?array', 'fd'=>'resource'],
'dio_tcsetattr' => ['bool', 'fd'=>'resource', 'options'=>'array'],
'dio_truncate' => ['bool', 'fd'=>'resource', 'offset'=>'int'],
'dio_write' => ['int', 'fd'=>'resource', 'data'=>'string', 'length='=>'int'],
'dir' => ['Directory|false', 'directory'=>'string', 'context='=>'resource'],
'Directory::close' => ['void'],
'Directory::read' => ['string|false'],
'Directory::rewind' => ['void'],
'DirectoryIterator::__construct' => ['void', 'path'=>'string'],
'DirectoryIterator::__toString' => ['string'],
'DirectoryIterator::current' => ['DirectoryIterator'],
'DirectoryIterator::getATime' => ['int'],
'DirectoryIterator::getBasename' => ['string', 'suffix='=>'string'],
'DirectoryIterator::getCTime' => ['int'],
'DirectoryIterator::getExtension' => ['string'],
'DirectoryIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
'DirectoryIterator::getFilename' => ['string'],
'DirectoryIterator::getGroup' => ['int'],
'DirectoryIterator::getInode' => ['int'],
'DirectoryIterator::getLinkTarget' => ['string'],
'DirectoryIterator::getMTime' => ['int'],
'DirectoryIterator::getOwner' => ['int'],
'DirectoryIterator::getPath' => ['string'],
'DirectoryIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
'DirectoryIterator::getPathname' => ['string'],
'DirectoryIterator::getPerms' => ['int'],
'DirectoryIterator::getRealPath' => ['string'],
'DirectoryIterator::getSize' => ['int'],
'DirectoryIterator::getType' => ['string'],
'DirectoryIterator::isDir' => ['bool'],
'DirectoryIterator::isDot' => ['bool'],
'DirectoryIterator::isExecutable' => ['bool'],
'DirectoryIterator::isFile' => ['bool'],
'DirectoryIterator::isLink' => ['bool'],
'DirectoryIterator::isReadable' => ['bool'],
'DirectoryIterator::isWritable' => ['bool'],
'DirectoryIterator::key' => ['string'],
'DirectoryIterator::next' => ['void'],
'DirectoryIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
'DirectoryIterator::rewind' => ['void'],
'DirectoryIterator::seek' => ['void', 'position'=>'int'],
'DirectoryIterator::setFileClass' => ['void', 'class_name='=>'string'],
'DirectoryIterator::setInfoClass' => ['void', 'class_name='=>'string'],
'DirectoryIterator::valid' => ['bool'],
'dirname' => ['string', 'path'=>'string', 'levels='=>'int'],
'disk_free_space' => ['float|false', 'directory'=>'string'],
'disk_total_space' => ['float|false', 'directory'=>'string'],
'diskfreespace' => ['float|false', 'directory'=>'string'],
'display_disabled_function' => [''],
'dl' => ['bool', 'extension_filename'=>'string'],
'dngettext' => ['string', 'domain'=>'string', 'singular'=>'string', 'plural'=>'string', 'count'=>'int'],
'dns_check_record' => ['bool', 'hostname'=>'string', 'type='=>'string'],
'dns_get_mx' => ['bool', 'hostname'=>'string', '&w_hosts'=>'array', '&w_weights'=>'array'],
'dns_get_record' => ['list<array>|false', 'hostname'=>'string', 'type='=>'int', '&w_authoritative_name_servers='=>'array', '&w_additional_records='=>'array', 'raw='=>'bool'],
'dom_document_relaxNG_validate_file' => ['bool', 'filename'=>'string'],
'dom_document_relaxNG_validate_xml' => ['bool', 'source'=>'string'],
'dom_document_schema_validate' => ['bool', 'source'=>'string', 'flags'=>'int'],
'dom_document_schema_validate_file' => ['bool', 'filename'=>'string', 'flags'=>'int'],
'dom_document_xinclude' => ['int', 'options'=>'int'],
'dom_import_simplexml' => ['DOMElement', 'node'=>'SimpleXMLElement'],
'dom_xpath_evaluate' => ['', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'],
'dom_xpath_query' => ['DOMNodeList', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'],
'dom_xpath_register_ns' => ['bool', 'prefix'=>'string', 'uri'=>'string'],
'dom_xpath_register_php_functions' => [''],
'DomainException::__clone' => ['void'],
'DomainException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'DomainException::__toString' => ['string'],
'DomainException::__wakeup' => ['void'],
'DomainException::getCode' => ['int'],
'DomainException::getFile' => ['string'],
'DomainException::getLine' => ['int'],
'DomainException::getMessage' => ['string'],
'DomainException::getPrevious' => ['?Throwable'],
'DomainException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'DomainException::getTraceAsString' => ['string'],
'DOMAttr::__construct' => ['void', 'name'=>'string', 'value='=>'string'],
'DOMAttr::getLineNo' => ['int'],
'DOMAttr::getNodePath' => ['?string'],
'DOMAttr::hasAttributes' => ['bool'],
'DOMAttr::hasChildNodes' => ['bool'],
'DOMAttr::insertBefore' => ['DOMNode', 'newnode'=>'DOMNode', 'refnode='=>'DOMNode'],
'DOMAttr::isDefaultNamespace' => ['bool', 'namespaceuri'=>'string'],
'DOMAttr::isId' => ['bool'],
'DOMAttr::isSameNode' => ['bool', 'node'=>'DOMNode'],
'DOMAttr::isSupported' => ['bool', 'feature'=>'string', 'version'=>'string'],
'DOMAttr::lookupNamespaceUri' => ['string|null', 'prefix'=>'string|null'],
'DOMAttr::lookupPrefix' => ['string|null', 'namespaceuri'=>'string'],
'DOMAttr::normalize' => ['void'],
'DOMAttr::removeChild' => ['DOMNode', 'oldnode'=>'DOMNode'],
'DOMAttr::replaceChild' => ['DOMNode', 'newnode'=>'DOMNode', 'oldnode'=>'DOMNode'],
'DomAttribute::name' => ['string'],
'DomAttribute::set_value' => ['bool', 'content'=>'string'],
'DomAttribute::specified' => ['bool'],
'DomAttribute::value' => ['string'],
'DOMCdataSection::__construct' => ['void', 'value'=>'string'],
'DOMCharacterData::appendData' => ['true', 'data'=>'string'],
'DOMCharacterData::deleteData' => ['bool', 'offset'=>'int', 'count'=>'int'],
'DOMCharacterData::insertData' => ['bool', 'offset'=>'int', 'data'=>'string'],
'DOMCharacterData::replaceData' => ['bool', 'offset'=>'int', 'count'=>'int', 'data'=>'string'],
'DOMCharacterData::substringData' => ['string', 'offset'=>'int', 'count'=>'int'],
'DOMComment::__construct' => ['void', 'value='=>'string'],
'DOMDocument::__construct' => ['void', 'version='=>'string', 'encoding='=>'string'],
'DOMDocument::createAttribute' => ['DOMAttr|false', 'name'=>'string'],
'DOMDocument::createAttributeNS' => ['DOMAttr|false', 'namespaceuri'=>'string|null', 'qualifiedname'=>'string'],
'DOMDocument::createCDATASection' => ['DOMCDATASection|false', 'data'=>'string'],
'DOMDocument::createComment' => ['DOMComment', 'data'=>'string'],
'DOMDocument::createDocumentFragment' => ['DOMDocumentFragment'],
'DOMDocument::createElement' => ['DOMElement|false', 'name'=>'string', 'value='=>'string'],
'DOMDocument::createElementNS' => ['DOMElement|false', 'namespaceuri'=>'string|null', 'qualifiedname'=>'string', 'value='=>'string'],
'DOMDocument::createEntityReference' => ['DOMEntityReference|false', 'name'=>'string'],
'DOMDocument::createProcessingInstruction' => ['DOMProcessingInstruction|false', 'target'=>'string', 'data='=>'string'],
'DOMDocument::createTextNode' => ['DOMText|false', 'content'=>'string'],
'DOMDocument::getElementById' => ['?DOMElement', 'elementid'=>'string'],
'DOMDocument::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'],
'DOMDocument::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string|null', 'localname'=>'string'],
'DOMDocument::importNode' => ['DOMNode|false', 'importednode'=>'DOMNode', 'deep='=>'bool'],
'DOMDocument::load' => ['DOMDocument|bool', 'filename'=>'string', 'options='=>'int'],
'DOMDocument::loadHTML' => ['bool', 'source'=>'non-empty-string', 'options='=>'int'],
'DOMDocument::loadHTMLFile' => ['bool', 'filename'=>'string', 'options='=>'int'],
'DOMDocument::loadXML' => ['DOMDocument|bool', 'source'=>'non-empty-string', 'options='=>'int'],
'DOMDocument::normalizeDocument' => ['void'],
'DOMDocument::registerNodeClass' => ['bool', 'baseclass'=>'string', 'extendedclass'=>'string'],
'DOMDocument::relaxNGValidate' => ['bool', 'filename'=>'string'],
'DOMDocument::relaxNGValidateSource' => ['bool', 'source'=>'string'],
'DOMDocument::save' => ['int|false', 'filename'=>'string', 'options='=>'int'],
'DOMDocument::saveHTML' => ['string|false', 'node='=>'?DOMNode'],
'DOMDocument::saveHTMLFile' => ['int|false', 'filename'=>'string'],
'DOMDocument::saveXML' => ['string|false', 'node='=>'?DOMNode', 'options='=>'int'],
'DOMDocument::schemaValidate' => ['bool', 'filename'=>'string', 'flags='=>'int'],
'DOMDocument::schemaValidateSource' => ['bool', 'source'=>'string', 'flags='=>'int'],
'DOMDocument::validate' => ['bool'],
'DOMDocument::xinclude' => ['int', 'options='=>'int'],
'DOMDocumentFragment::__construct' => ['void'],
'DOMDocumentFragment::appendXML' => ['bool', 'data'=>'string'],
'DOMElement::__construct' => ['void', 'name'=>'string', 'value='=>'string', 'uri='=>'string'],
'DOMElement::getAttribute' => ['string', 'name'=>'string'],
'DOMElement::getAttributeNode' => ['DOMAttr', 'name'=>'string'],
'DOMElement::getAttributeNodeNS' => ['DOMAttr', 'namespaceuri'=>'string|null', 'localname'=>'string'],
'DOMElement::getAttributeNS' => ['string', 'namespaceuri'=>'string|null', 'localname'=>'string'],
'DOMElement::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'],
'DOMElement::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string|null', 'localname'=>'string'],
'DOMElement::hasAttribute' => ['bool', 'name'=>'string'],
'DOMElement::hasAttributeNS' => ['bool', 'namespaceuri'=>'string|null', 'localname'=>'string'],
'DOMElement::removeAttribute' => ['bool', 'name'=>'string'],
'DOMElement::removeAttributeNode' => ['bool', 'oldnode'=>'DOMAttr'],
'DOMElement::removeAttributeNS' => ['bool', 'namespaceuri'=>'string|null', 'localname'=>'string'],
'DOMElement::setAttribute' => ['DOMAttr|false', 'name'=>'string', 'value'=>'string'],
'DOMElement::setAttributeNode' => ['?DOMAttr', 'attr'=>'DOMAttr'],
'DOMElement::setAttributeNodeNS' => ['DOMAttr', 'attr'=>'DOMAttr'],
'DOMElement::setAttributeNS' => ['void', 'namespaceuri'=>'string|null', 'qualifiedname'=>'string', 'value'=>'string'],
'DOMElement::setIdAttribute' => ['void', 'name'=>'string', 'isid'=>'bool'],
'DOMElement::setIdAttributeNode' => ['void', 'attr'=>'DOMAttr', 'isid'=>'bool'],
'DOMElement::setIdAttributeNS' => ['void', 'namespaceuri'=>'string', 'localname'=>'string', 'isid'=>'bool'],
'DOMEntityReference::__construct' => ['void', 'name'=>'string'],
'DOMImplementation::__construct' => ['void'],
'DOMImplementation::createDocument' => ['DOMDocument', 'namespaceuri='=>'string', 'qualifiedname='=>'string', 'doctype='=>'DOMDocumentType'],
'DOMImplementation::createDocumentType' => ['DOMDocumentType', 'qualifiedname='=>'string', 'publicid='=>'string', 'systemid='=>'string'],
'DOMImplementation::hasFeature' => ['bool', 'feature'=>'string', 'version'=>'string'],
'DOMNamedNodeMap::count' => ['int'],
'DOMNamedNodeMap::getNamedItem' => ['?DOMNode', 'name'=>'string'],
'DOMNamedNodeMap::getNamedItemNS' => ['?DOMNode', 'namespaceuri'=>'string', 'localname'=>'string'],
'DOMNamedNodeMap::item' => ['?DOMNode', 'index'=>'int'],
'DOMNode::appendChild' => ['DOMNode', 'newnode'=>'DOMNode'],
'DOMNode::C14N' => ['string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'],
'DOMNode::C14NFile' => ['int|false', 'uri='=>'string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'],
'DOMNode::cloneNode' => ['DOMNode', 'deep='=>'bool'],
'DOMNode::getLineNo' => ['int'],
'DOMNode::getNodePath' => ['?string'],
'DOMNode::hasAttributes' => ['bool'],
'DOMNode::hasChildNodes' => ['bool'],
'DOMNode::insertBefore' => ['DOMNode', 'newnode'=>'DOMNode', 'refnode='=>'DOMNode|null'],
'DOMNode::isDefaultNamespace' => ['bool', 'namespaceuri'=>'string'],
'DOMNode::isSameNode' => ['bool', 'node'=>'DOMNode'],
'DOMNode::isSupported' => ['bool', 'feature'=>'string', 'version'=>'string'],
'DOMNode::lookupNamespaceURI' => ['string|null', 'prefix'=>'string|null'],
'DOMNode::lookupPrefix' => ['string|null', 'namespaceuri'=>'string'],
'DOMNode::normalize' => ['void'],
'DOMNode::removeChild' => ['DOMNode', 'oldnode'=>'DOMNode'],
'DOMNode::replaceChild' => ['DOMNode|false', 'newnode'=>'DOMNode', 'oldnode'=>'DOMNode'],
'DOMNodeList::count' => ['int'],
'DOMNodeList::item' => ['?DOMNode', 'index'=>'int'],
'DOMProcessingInstruction::__construct' => ['void', 'name'=>'string', 'value'=>'string'],
'DOMText::__construct' => ['void', 'value='=>'string'],
'DOMText::isElementContentWhitespace' => ['bool'],
'DOMText::isWhitespaceInElementContent' => ['bool'],
'DOMText::splitText' => ['DOMText', 'offset'=>'int'],
'domxml_new_doc' => ['DomDocument', 'version'=>'string'],
'domxml_open_file' => ['DomDocument', 'filename'=>'string', 'mode='=>'int', 'error='=>'array'],
'domxml_open_mem' => ['DomDocument', 'string'=>'string', 'mode='=>'int', 'error='=>'array'],
'domxml_version' => ['string'],
'domxml_xmltree' => ['DomDocument', 'string'=>'string'],
'domxml_xslt_stylesheet' => ['DomXsltStylesheet', 'xsl_buf'=>'string'],
'domxml_xslt_stylesheet_doc' => ['DomXsltStylesheet', 'xsl_doc'=>'DOMDocument'],
'domxml_xslt_stylesheet_file' => ['DomXsltStylesheet', 'xsl_file'=>'string'],
'domxml_xslt_version' => ['int'],
'DOMXPath::__construct' => ['void', 'doc'=>'DOMDocument'],
'DOMXPath::evaluate' => ['mixed', 'expression'=>'string', 'contextnode='=>'?DOMNode', 'registernodens='=>'bool'],
'DOMXPath::query' => ['DOMNodeList|false', 'expression'=>'string', 'contextnode='=>'DOMNode|null', 'registernodens='=>'bool'],
'DOMXPath::registerNamespace' => ['bool', 'prefix'=>'string', 'namespaceuri'=>'string'],
'DOMXPath::registerPhpFunctions' => ['void', 'restrict='=>'mixed'],
'DomXsltStylesheet::process' => ['DomDocument', 'xml_doc'=>'DOMDocument', 'xslt_params='=>'array', 'is_xpath_param='=>'bool', 'profile_filename='=>'string'],
'DomXsltStylesheet::result_dump_file' => ['string', 'xmldoc'=>'DOMDocument', 'filename'=>'string'],
'DomXsltStylesheet::result_dump_mem' => ['string', 'xmldoc'=>'DOMDocument'],
'DOTNET::__call' => ['mixed', 'name'=>'string', 'args'=>''],
'DOTNET::__construct' => ['void', 'assembly_name'=>'string', 'datatype_name'=>'string', 'codepage='=>'int'],
'DOTNET::__get' => ['mixed', 'name'=>'string'],
'DOTNET::__set' => ['void', 'name'=>'string', 'value'=>''],
'dotnet_load' => ['int', 'assembly_name'=>'string', 'datatype_name='=>'string', 'codepage='=>'int'],
'doubleval' => ['float', 'value'=>'mixed'],
'Ds\Collection::clear' => ['void'],
'Ds\Collection::copy' => ['Ds\Collection'],
'Ds\Collection::isEmpty' => ['bool'],
'Ds\Collection::toArray' => ['array'],
'Ds\Deque::__construct' => ['void', 'values='=>'mixed'],
'Ds\Deque::allocate' => ['void', 'capacity'=>'int'],
'Ds\Deque::apply' => ['void', 'callback'=>'callable'],
'Ds\Deque::capacity' => ['int'],
'Ds\Deque::clear' => ['void'],
'Ds\Deque::contains' => ['bool', '...values='=>'mixed'],
'Ds\Deque::copy' => ['Ds\Deque'],
'Ds\Deque::count' => ['int'],
'Ds\Deque::filter' => ['Ds\Deque', 'callback='=>'callable'],
'Ds\Deque::find' => ['mixed', 'value'=>'mixed'],
'Ds\Deque::first' => ['mixed'],
'Ds\Deque::get' => ['void', 'index'=>'int'],
'Ds\Deque::insert' => ['void', 'index'=>'int', '...values='=>'mixed'],
'Ds\Deque::isEmpty' => ['bool'],
'Ds\Deque::join' => ['string', 'glue='=>'string'],
'Ds\Deque::jsonSerialize' => ['array'],
'Ds\Deque::last' => ['mixed'],
'Ds\Deque::map' => ['Ds\Deque', 'callback'=>'callable'],
'Ds\Deque::merge' => ['Ds\Deque', 'values'=>'mixed'],
'Ds\Deque::pop' => ['mixed'],
'Ds\Deque::push' => ['void', '...values='=>'mixed'],
'Ds\Deque::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
'Ds\Deque::remove' => ['mixed', 'index'=>'int'],
'Ds\Deque::reverse' => ['void'],
'Ds\Deque::reversed' => ['Ds\Deque'],
'Ds\Deque::rotate' => ['void', 'rotations'=>'int'],
'Ds\Deque::set' => ['void', 'index'=>'int', 'value'=>'mixed'],
'Ds\Deque::shift' => ['mixed'],
'Ds\Deque::slice' => ['Ds\Deque', 'index'=>'int', 'length='=>'?int'],
'Ds\Deque::sort' => ['void', 'comparator='=>'callable'],
'Ds\Deque::sorted' => ['Ds\Deque', 'comparator='=>'callable'],
'Ds\Deque::sum' => ['int|float'],
'Ds\Deque::toArray' => ['array'],
'Ds\Deque::unshift' => ['void', '...values='=>'mixed'],
'Ds\Hashable::equals' => ['bool', 'object'=>'mixed'],
'Ds\Hashable::hash' => ['mixed'],
'Ds\Map::__construct' => ['void', 'values='=>'mixed'],
'Ds\Map::allocate' => ['void', 'capacity'=>'int'],
'Ds\Map::apply' => ['void', 'callback'=>'callable'],
'Ds\Map::capacity' => ['int'],
'Ds\Map::clear' => ['void'],
'Ds\Map::copy' => ['Ds\Map'],
'Ds\Map::count' => ['int'],
'Ds\Map::diff' => ['Ds\Map', 'map'=>'Ds\Map'],
'Ds\Map::filter' => ['Ds\Map', 'callback='=>'callable'],
'Ds\Map::first' => ['Ds\Pair'],
'Ds\Map::get' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'],
'Ds\Map::hasKey' => ['bool', 'key'=>'mixed'],
'Ds\Map::hasValue' => ['bool', 'value'=>'mixed'],
'Ds\Map::intersect' => ['Ds\Map', 'map'=>'Ds\Map'],
'Ds\Map::isEmpty' => ['bool'],
'Ds\Map::jsonSerialize' => ['array'],
'Ds\Map::keys' => ['Ds\Set'],
'Ds\Map::ksort' => ['void', 'comparator='=>'callable'],
'Ds\Map::ksorted' => ['Ds\Map', 'comparator='=>'callable'],
'Ds\Map::last' => ['Ds\Pair'],
'Ds\Map::map' => ['Ds\Map', 'callback'=>'callable'],
'Ds\Map::merge' => ['Ds\Map', 'values'=>'mixed'],
'Ds\Map::pairs' => ['Ds\Sequence'],
'Ds\Map::put' => ['void', 'key'=>'mixed', 'value'=>'mixed'],
'Ds\Map::putAll' => ['void', 'values'=>'mixed'],
'Ds\Map::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
'Ds\Map::remove' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'],
'Ds\Map::reverse' => ['void'],
'Ds\Map::reversed' => ['Ds\Map'],
'Ds\Map::skip' => ['Ds\Pair', 'position'=>'int'],
'Ds\Map::slice' => ['Ds\Map', 'index'=>'int', 'length='=>'?int'],
'Ds\Map::sort' => ['void', 'comparator='=>'callable'],
'Ds\Map::sorted' => ['Ds\Map', 'comparator='=>'callable'],
'Ds\Map::sum' => ['int|float'],
'Ds\Map::toArray' => ['array'],
'Ds\Map::union' => ['Ds\Map', 'map'=>'Ds\Map'],
'Ds\Map::values' => ['Ds\Sequence'],
'Ds\Map::xor' => ['Ds\Map', 'map'=>'Ds\Map'],
'Ds\Pair::__construct' => ['void', 'key='=>'mixed', 'value='=>'mixed'],
'Ds\Pair::clear' => ['void'],
'Ds\Pair::copy' => ['Ds\Pair'],
'Ds\Pair::isEmpty' => ['bool'],
'Ds\Pair::jsonSerialize' => ['array'],
'Ds\Pair::toArray' => ['array'],
'Ds\PriorityQueue::__construct' => ['void'],
'Ds\PriorityQueue::allocate' => ['void', 'capacity'=>'int'],
'Ds\PriorityQueue::capacity' => ['int'],
'Ds\PriorityQueue::clear' => ['void'],
'Ds\PriorityQueue::copy' => ['Ds\PriorityQueue'],
'Ds\PriorityQueue::count' => ['int'],
'Ds\PriorityQueue::isEmpty' => ['bool'],
'Ds\PriorityQueue::jsonSerialize' => ['array'],
'Ds\PriorityQueue::peek' => ['mixed'],
'Ds\PriorityQueue::pop' => ['mixed'],
'Ds\PriorityQueue::push' => ['void', 'value'=>'mixed', 'priority'=>'int'],
'Ds\PriorityQueue::toArray' => ['array'],
'Ds\Queue::__construct' => ['void', 'values='=>'mixed'],
'Ds\Queue::allocate' => ['void', 'capacity'=>'int'],
'Ds\Queue::capacity' => ['int'],
'Ds\Queue::clear' => ['void'],
'Ds\Queue::copy' => ['Ds\Queue'],
'Ds\Queue::count' => ['int'],
'Ds\Queue::isEmpty' => ['bool'],
'Ds\Queue::jsonSerialize' => ['array'],
'Ds\Queue::peek' => ['mixed'],
'Ds\Queue::pop' => ['mixed'],
'Ds\Queue::push' => ['void', '...values='=>'mixed'],
'Ds\Queue::toArray' => ['array'],
'Ds\Sequence::allocate' => ['void', 'capacity'=>'int'],
'Ds\Sequence::apply' => ['void', 'callback'=>'callable'],
'Ds\Sequence::capacity' => ['int'],
'Ds\Sequence::contains' => ['bool', '...values='=>'mixed'],
'Ds\Sequence::filter' => ['Ds\Sequence', 'callback='=>'callable'],
'Ds\Sequence::find' => ['mixed', 'value'=>'mixed'],
'Ds\Sequence::first' => ['mixed'],
'Ds\Sequence::get' => ['mixed', 'index'=>'int'],
'Ds\Sequence::insert' => ['void', 'index'=>'int', '...values='=>'mixed'],
'Ds\Sequence::join' => ['string', 'glue='=>'string'],
'Ds\Sequence::last' => ['void'],
'Ds\Sequence::map' => ['Ds\Sequence', 'callback'=>'callable'],
'Ds\Sequence::merge' => ['Ds\Sequence', 'values'=>'mixed'],
'Ds\Sequence::pop' => ['mixed'],
'Ds\Sequence::push' => ['void', '...values='=>'mixed'],
'Ds\Sequence::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
'Ds\Sequence::remove' => ['mixed', 'index'=>'int'],
'Ds\Sequence::reverse' => ['void'],
'Ds\Sequence::reversed' => ['Ds\Sequence'],
'Ds\Sequence::rotate' => ['void', 'rotations'=>'int'],
'Ds\Sequence::set' => ['void', 'index'=>'int', 'value'=>'mixed'],
'Ds\Sequence::shift' => ['mixed'],
'Ds\Sequence::slice' => ['Ds\Sequence', 'index'=>'int', 'length='=>'?int'],
'Ds\Sequence::sort' => ['void', 'comparator='=>'callable'],
'Ds\Sequence::sorted' => ['Ds\Sequence', 'comparator='=>'callable'],
'Ds\Sequence::sum' => ['int|float'],
'Ds\Sequence::unshift' => ['void', '...values='=>'mixed'],
'Ds\Set::__construct' => ['void', 'values='=>'mixed'],
'Ds\Set::add' => ['void', '...values='=>'mixed'],
'Ds\Set::allocate' => ['void', 'capacity'=>'int'],
'Ds\Set::capacity' => ['int'],
'Ds\Set::clear' => ['void'],
'Ds\Set::contains' => ['bool', '...values='=>'mixed'],
'Ds\Set::copy' => ['Ds\Set'],
'Ds\Set::count' => ['int'],
'Ds\Set::diff' => ['Ds\Set', 'set'=>'Ds\Set'],
'Ds\Set::filter' => ['Ds\Set', 'callback='=>'callable'],
'Ds\Set::first' => ['mixed'],
'Ds\Set::get' => ['mixed', 'index'=>'int'],
'Ds\Set::intersect' => ['Ds\Set', 'set'=>'Ds\Set'],
'Ds\Set::isEmpty' => ['bool'],
'Ds\Set::join' => ['string', 'glue='=>'string'],
'Ds\Set::jsonSerialize' => ['array'],
'Ds\Set::last' => ['mixed'],
'Ds\Set::merge' => ['Ds\Set', 'values'=>'mixed'],
'Ds\Set::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
'Ds\Set::remove' => ['void', '...values='=>'mixed'],
'Ds\Set::reverse' => ['void'],
'Ds\Set::reversed' => ['Ds\Set'],
'Ds\Set::slice' => ['Ds\Set', 'index'=>'int', 'length='=>'?int'],
'Ds\Set::sort' => ['void', 'comparator='=>'callable'],
'Ds\Set::sorted' => ['Ds\Set', 'comparator='=>'callable'],
'Ds\Set::sum' => ['int|float'],
'Ds\Set::toArray' => ['array'],
'Ds\Set::union' => ['Ds\Set', 'set'=>'Ds\Set'],
'Ds\Set::xor' => ['Ds\Set', 'set'=>'Ds\Set'],
'Ds\Stack::__construct' => ['void', 'values='=>'mixed'],
'Ds\Stack::allocate' => ['void', 'capacity'=>'int'],
'Ds\Stack::capacity' => ['int'],
'Ds\Stack::clear' => ['void'],
'Ds\Stack::copy' => ['Ds\Stack'],
'Ds\Stack::count' => ['int'],
'Ds\Stack::isEmpty' => ['bool'],
'Ds\Stack::jsonSerialize' => ['array'],
'Ds\Stack::peek' => ['mixed'],
'Ds\Stack::pop' => ['mixed'],
'Ds\Stack::push' => ['void', '...values='=>'mixed'],
'Ds\Stack::toArray' => ['array'],
'Ds\Vector::__construct' => ['void', 'values='=>'mixed'],
'Ds\Vector::allocate' => ['void', 'capacity'=>'int'],
'Ds\Vector::apply' => ['void', 'callback'=>'callable'],
'Ds\Vector::capacity' => ['int'],
'Ds\Vector::clear' => ['void'],
'Ds\Vector::contains' => ['bool', '...values='=>'mixed'],
'Ds\Vector::copy' => ['Ds\Vector'],
'Ds\Vector::count' => ['int'],
'Ds\Vector::filter' => ['Ds\Vector', 'callback='=>'callable'],
'Ds\Vector::find' => ['mixed', 'value'=>'mixed'],
'Ds\Vector::first' => ['mixed'],
'Ds\Vector::get' => ['mixed', 'index'=>'int'],
'Ds\Vector::insert' => ['void', 'index'=>'int', '...values='=>'mixed'],
'Ds\Vector::isEmpty' => ['bool'],
'Ds\Vector::join' => ['string', 'glue='=>'string'],
'Ds\Vector::jsonSerialize' => ['array'],
'Ds\Vector::last' => ['mixed'],
'Ds\Vector::map' => ['Ds\Vector', 'callback'=>'callable'],
'Ds\Vector::merge' => ['Ds\Vector', 'values'=>'mixed'],
'Ds\Vector::pop' => ['mixed'],
'Ds\Vector::push' => ['void', '...values='=>'mixed'],
'Ds\Vector::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'],
'Ds\Vector::remove' => ['mixed', 'index'=>'int'],
'Ds\Vector::reverse' => ['void'],
'Ds\Vector::reversed' => ['Ds\Vector'],
'Ds\Vector::rotate' => ['void', 'rotations'=>'int'],
'Ds\Vector::set' => ['void', 'index'=>'int', 'value'=>'mixed'],
'Ds\Vector::shift' => ['mixed'],
'Ds\Vector::slice' => ['Ds\Vector', 'index'=>'int', 'length='=>'?int'],
'Ds\Vector::sort' => ['void', 'comparator='=>'callable'],
'Ds\Vector::sorted' => ['Ds\Vector', 'comparator='=>'callable'],
'Ds\Vector::sum' => ['int|float'],
'Ds\Vector::toArray' => ['array'],
'Ds\Vector::unshift' => ['void', '...values='=>'mixed'],
'easter_date' => ['int', 'year='=>'?int'],
'easter_days' => ['int', 'year='=>'?int', 'mode='=>'int'],
'echo' => ['void', 'arg1'=>'string', '...args='=>'string'],
'eio_busy' => ['resource', 'delay'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_cancel' => ['void', 'req'=>'resource'],
'eio_chmod' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_chown' => ['resource', 'path'=>'string', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_close' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_custom' => ['resource', 'execute'=>'callable', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_dup2' => ['resource', 'fd'=>'mixed', 'fd2'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_event_loop' => ['bool'],
'eio_fallocate' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_fchmod' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_fchown' => ['resource', 'fd'=>'mixed', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_fdatasync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_fstat' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_fstatvfs' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_fsync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_ftruncate' => ['resource', 'fd'=>'mixed', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_futime' => ['resource', 'fd'=>'mixed', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_get_event_stream' => ['mixed'],
'eio_get_last_error' => ['string', 'req'=>'resource'],
'eio_grp' => ['resource', 'callback'=>'callable', 'data='=>'string'],
'eio_grp_add' => ['void', 'grp'=>'resource', 'req'=>'resource'],
'eio_grp_cancel' => ['void', 'grp'=>'resource'],
'eio_grp_limit' => ['void', 'grp'=>'resource', 'limit'=>'int'],
'eio_init' => ['void'],
'eio_link' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_lstat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_mkdir' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_mknod' => ['resource', 'path'=>'string', 'mode'=>'int', 'dev'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_nop' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_npending' => ['int'],
'eio_nready' => ['int'],
'eio_nreqs' => ['int'],
'eio_nthreads' => ['int'],
'eio_open' => ['resource', 'path'=>'string', 'flags'=>'int', 'mode'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_poll' => ['int'],
'eio_read' => ['resource', 'fd'=>'mixed', 'length'=>'int', 'offset'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_readahead' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_readdir' => ['resource', 'path'=>'string', 'flags'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'],
'eio_readlink' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'],
'eio_realpath' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'],
'eio_rename' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_rmdir' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_seek' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'whence'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_sendfile' => ['resource', 'out_fd'=>'mixed', 'in_fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'string'],
'eio_set_max_idle' => ['void', 'nthreads'=>'int'],
'eio_set_max_parallel' => ['void', 'nthreads'=>'int'],
'eio_set_max_poll_reqs' => ['void', 'nreqs'=>'int'],
'eio_set_max_poll_time' => ['void', 'nseconds'=>'float'],
'eio_set_min_parallel' => ['void', 'nthreads'=>'string'],
'eio_stat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_statvfs' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'],
'eio_symlink' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_sync' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_sync_file_range' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'nbytes'=>'int', 'flags'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_syncfs' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_truncate' => ['resource', 'path'=>'string', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_unlink' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_utime' => ['resource', 'path'=>'string', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'eio_write' => ['resource', 'fd'=>'mixed', 'string'=>'string', 'length='=>'int', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'],
'empty' => ['bool', 'value'=>'mixed'],
'EmptyIterator::current' => ['never'],
'EmptyIterator::key' => ['never'],
'EmptyIterator::next' => ['void'],
'EmptyIterator::rewind' => ['void'],
'EmptyIterator::valid' => ['bool'],
'enchant_broker_describe' => ['array', 'broker'=>'resource'],
'enchant_broker_dict_exists' => ['bool', 'broker'=>'resource', 'tag'=>'string'],
'enchant_broker_free' => ['bool', 'broker'=>'resource'],
'enchant_broker_free_dict' => ['bool', 'dictionary'=>'resource'],
'enchant_broker_get_dict_path' => ['string', 'broker'=>'resource', 'type'=>'int'],
'enchant_broker_get_error' => ['string|false', 'broker'=>'resource'],
'enchant_broker_init' => ['EnchantBroker|false'],
'enchant_broker_list_dicts' => ['array<int,array{lang_tag:string,provider_name:string,provider_desc:string,provider_file:string}>|false', 'broker'=>'resource'],
'enchant_broker_request_dict' => ['resource|false', 'broker'=>'resource', 'tag'=>'string'],
'enchant_broker_request_pwl_dict' => ['resource|false', 'broker'=>'resource', 'filename'=>'string'],
'enchant_broker_set_dict_path' => ['bool', 'broker'=>'resource', 'type'=>'int', 'path'=>'string'],
'enchant_broker_set_ordering' => ['bool', 'broker'=>'resource', 'tag'=>'string', 'ordering'=>'string'],
'enchant_dict_add_to_personal' => ['void', 'dictionary'=>'resource', 'word'=>'string'],
'enchant_dict_add_to_session' => ['void', 'dictionary'=>'resource', 'word'=>'string'],
'enchant_dict_check' => ['bool', 'dictionary'=>'resource', 'word'=>'string'],
'enchant_dict_describe' => ['array', 'dictionary'=>'resource'],
'enchant_dict_get_error' => ['string', 'dictionary'=>'resource'],
'enchant_dict_is_in_session' => ['bool', 'dictionary'=>'resource', 'word'=>'string'],
'enchant_dict_quick_check' => ['bool', 'dictionary'=>'resource', 'word'=>'string', '&w_suggestions='=>'array<int,string>'],
'enchant_dict_store_replacement' => ['void', 'dictionary'=>'resource', 'misspelled'=>'string', 'correct'=>'string'],
'enchant_dict_suggest' => ['array', 'dictionary'=>'resource', 'word'=>'string'],
'end' => ['mixed|false', '&r_array'=>'array|object'],
'enum_exists' => ['bool', 'enum' => 'string', 'autoload=' => 'bool'],
'Error::__clone' => ['void'],
'Error::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'Error::__toString' => ['string'],
'Error::getCode' => ['int'],
'Error::getFile' => ['string'],
'Error::getLine' => ['int'],
'Error::getMessage' => ['string'],
'Error::getPrevious' => ['?Throwable'],
'Error::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'Error::getTraceAsString' => ['string'],
'error_clear_last' => ['void'],
'error_get_last' => ['?array{type:int,message:string,file:string,line:int}'],
'error_log' => ['bool', 'message'=>'string', 'message_type='=>'int', 'destination='=>'?string', 'additional_headers='=>'?string'],
'error_reporting' => ['int', 'error_level='=>'?int'],
'ErrorException::__clone' => ['void'],
'ErrorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'severity='=>'int', 'filename='=>'?string', 'line='=>'?int', 'previous='=>'?Throwable'],
'ErrorException::__toString' => ['string'],
'ErrorException::getCode' => ['int'],
'ErrorException::getFile' => ['string'],
'ErrorException::getLine' => ['int'],
'ErrorException::getMessage' => ['string'],
'ErrorException::getPrevious' => ['?Throwable'],
'ErrorException::getSeverity' => ['int'],
'ErrorException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'ErrorException::getTraceAsString' => ['string'],
'escapeshellarg' => ['string', 'arg'=>'string'],
'escapeshellcmd' => ['string', 'command'=>'string'],
'Ev::backend' => ['int'],
'Ev::depth' => ['int'],
'Ev::embeddableBackends' => ['int'],
'Ev::feedSignal' => ['void', 'signum'=>'int'],
'Ev::feedSignalEvent' => ['void', 'signum'=>'int'],
'Ev::iteration' => ['int'],
'Ev::now' => ['float'],
'Ev::nowUpdate' => ['void'],
'Ev::recommendedBackends' => ['int'],
'Ev::resume' => ['void'],
'Ev::run' => ['void', 'flags='=>'int'],
'Ev::sleep' => ['void', 'seconds'=>'float'],
'Ev::stop' => ['void', 'how='=>'int'],
'Ev::supportedBackends' => ['int'],
'Ev::suspend' => ['void'],
'Ev::time' => ['float'],
'Ev::verify' => ['void'],
'eval' => ['mixed', 'code_str'=>'string'],
'EvCheck::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvCheck::clear' => ['int'],
'EvCheck::createStopped' => ['EvCheck', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvCheck::feed' => ['void', 'events'=>'int'],
'EvCheck::getLoop' => ['EvLoop'],
'EvCheck::invoke' => ['void', 'events'=>'int'],
'EvCheck::keepAlive' => ['void', 'value'=>'bool'],
'EvCheck::setCallback' => ['void', 'callback'=>'callable'],
'EvCheck::start' => ['void'],
'EvCheck::stop' => ['void'],
'EvChild::__construct' => ['void', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvChild::clear' => ['int'],
'EvChild::createStopped' => ['EvChild', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvChild::feed' => ['void', 'events'=>'int'],
'EvChild::getLoop' => ['EvLoop'],
'EvChild::invoke' => ['void', 'events'=>'int'],
'EvChild::keepAlive' => ['void', 'value'=>'bool'],
'EvChild::set' => ['void', 'pid'=>'int', 'trace'=>'bool'],
'EvChild::setCallback' => ['void', 'callback'=>'callable'],
'EvChild::start' => ['void'],
'EvChild::stop' => ['void'],
'EvEmbed::__construct' => ['void', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvEmbed::clear' => ['int'],
'EvEmbed::createStopped' => ['EvEmbed', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvEmbed::feed' => ['void', 'events'=>'int'],
'EvEmbed::getLoop' => ['EvLoop'],
'EvEmbed::invoke' => ['void', 'events'=>'int'],
'EvEmbed::keepAlive' => ['void', 'value'=>'bool'],
'EvEmbed::set' => ['void', 'other'=>'object'],
'EvEmbed::setCallback' => ['void', 'callback'=>'callable'],
'EvEmbed::start' => ['void'],
'EvEmbed::stop' => ['void'],
'EvEmbed::sweep' => ['void'],
'Event::__construct' => ['void', 'base'=>'EventBase', 'fd'=>'mixed', 'what'=>'int', 'cb'=>'callable', 'arg='=>'mixed'],
'Event::add' => ['bool', 'timeout='=>'float'],
'Event::addSignal' => ['bool', 'timeout='=>'float'],
'Event::addTimer' => ['bool', 'timeout='=>'float'],
'Event::del' => ['bool'],
'Event::delSignal' => ['bool'],
'Event::delTimer' => ['bool'],
'Event::free' => ['void'],
'Event::getSupportedMethods' => ['array'],
'Event::pending' => ['bool', 'flags'=>'int'],
'Event::set' => ['bool', 'base'=>'EventBase', 'fd'=>'mixed', 'what='=>'int', 'cb='=>'callable', 'arg='=>'mixed'],
'Event::setPriority' => ['bool', 'priority'=>'int'],
'Event::setTimer' => ['bool', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'],
'Event::signal' => ['Event', 'base'=>'EventBase', 'signum'=>'int', 'cb'=>'callable', 'arg='=>'mixed'],
'Event::timer' => ['Event', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'],
'event_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'],
'event_base_free' => ['void', 'event_base'=>'resource'],
'event_base_loop' => ['int', 'event_base'=>'resource', 'flags='=>'int'],
'event_base_loopbreak' => ['bool', 'event_base'=>'resource'],
'event_base_loopexit' => ['bool', 'event_base'=>'resource', 'timeout='=>'int'],
'event_base_new' => ['resource|false'],
'event_base_priority_init' => ['bool', 'event_base'=>'resource', 'npriorities'=>'int'],
'event_base_reinit' => ['bool', 'event_base'=>'resource'],
'event_base_set' => ['bool', 'event'=>'resource', 'event_base'=>'resource'],
'event_buffer_base_set' => ['bool', 'bevent'=>'resource', 'event_base'=>'resource'],
'event_buffer_disable' => ['bool', 'bevent'=>'resource', 'events'=>'int'],
'event_buffer_enable' => ['bool', 'bevent'=>'resource', 'events'=>'int'],
'event_buffer_fd_set' => ['void', 'bevent'=>'resource', 'fd'=>'resource'],
'event_buffer_free' => ['void', 'bevent'=>'resource'],
'event_buffer_new' => ['resource|false', 'stream'=>'resource', 'readcb'=>'callable|null', 'writecb'=>'callable|null', 'errorcb'=>'callable', 'arg='=>'mixed'],
'event_buffer_priority_set' => ['bool', 'bevent'=>'resource', 'priority'=>'int'],
'event_buffer_read' => ['string', 'bevent'=>'resource', 'data_size'=>'int'],
'event_buffer_set_callback' => ['bool', 'event'=>'resource', 'readcb'=>'mixed', 'writecb'=>'mixed', 'errorcb'=>'mixed', 'arg='=>'mixed'],
'event_buffer_timeout_set' => ['void', 'bevent'=>'resource', 'read_timeout'=>'int', 'write_timeout'=>'int'],
'event_buffer_watermark_set' => ['void', 'bevent'=>'resource', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'],
'event_buffer_write' => ['bool', 'bevent'=>'resource', 'data'=>'string', 'data_size='=>'int'],
'event_del' => ['bool', 'event'=>'resource'],
'event_free' => ['void', 'event'=>'resource'],
'event_new' => ['resource|false'],
'event_priority_set' => ['bool', 'event'=>'resource', 'priority'=>'int'],
'event_set' => ['bool', 'event'=>'resource', 'fd'=>'int|resource', 'events'=>'int', 'callback'=>'callable', 'arg='=>'mixed'],
'event_timer_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'],
'event_timer_del' => ['bool', 'event'=>'resource'],
'event_timer_new' => ['resource|false'],
'event_timer_pending' => ['bool', 'event'=>'resource', 'timeout='=>'int'],
'event_timer_set' => ['bool', 'event'=>'resource', 'callback'=>'callable', 'arg='=>'mixed'],
'EventBase::__construct' => ['void', 'cfg='=>'EventConfig'],
'EventBase::dispatch' => ['void'],
'EventBase::exit' => ['bool', 'timeout='=>'float'],
'EventBase::free' => ['void'],
'EventBase::getFeatures' => ['int'],
'EventBase::getMethod' => ['string', 'cfg='=>'EventConfig'],
'EventBase::getTimeOfDayCached' => ['float'],
'EventBase::gotExit' => ['bool'],
'EventBase::gotStop' => ['bool'],
'EventBase::loop' => ['bool', 'flags='=>'int'],
'EventBase::priorityInit' => ['bool', 'n_priorities'=>'int'],
'EventBase::reInit' => ['bool'],
'EventBase::stop' => ['bool'],
'EventBuffer::__construct' => ['void'],
'EventBuffer::add' => ['bool', 'data'=>'string'],
'EventBuffer::addBuffer' => ['bool', 'buf'=>'EventBuffer'],
'EventBuffer::appendFrom' => ['int', 'buf'=>'EventBuffer', 'length'=>'int'],
'EventBuffer::copyout' => ['int', '&w_data'=>'string', 'max_bytes'=>'int'],
'EventBuffer::drain' => ['bool', 'length'=>'int'],
'EventBuffer::enableLocking' => ['void'],
'EventBuffer::expand' => ['bool', 'length'=>'int'],
'EventBuffer::freeze' => ['bool', 'at_front'=>'bool'],
'EventBuffer::lock' => ['void'],
'EventBuffer::prepend' => ['bool', 'data'=>'string'],
'EventBuffer::prependBuffer' => ['bool', 'buf'=>'EventBuffer'],
'EventBuffer::pullup' => ['string', 'size'=>'int'],
'EventBuffer::read' => ['string', 'max_bytes'=>'int'],
'EventBuffer::readFrom' => ['int', 'fd'=>'mixed', 'howmuch'=>'int'],
'EventBuffer::readLine' => ['string', 'eol_style'=>'int'],
'EventBuffer::search' => ['mixed', 'what'=>'string', 'start='=>'int', 'end='=>'int'],
'EventBuffer::searchEol' => ['mixed', 'start='=>'int', 'eol_style='=>'int'],
'EventBuffer::substr' => ['string', 'start'=>'int', 'length='=>'int'],
'EventBuffer::unfreeze' => ['bool', 'at_front'=>'bool'],
'EventBuffer::unlock' => ['bool'],
'EventBuffer::write' => ['int', 'fd'=>'mixed', 'howmuch='=>'int'],
'EventBufferEvent::__construct' => ['void', 'base'=>'EventBase', 'socket='=>'mixed', 'options='=>'int', 'readcb='=>'callable', 'writecb='=>'callable', 'eventcb='=>'callable'],
'EventBufferEvent::close' => ['void'],
'EventBufferEvent::connect' => ['bool', 'addr'=>'string'],
'EventBufferEvent::connectHost' => ['bool', 'dns_base'=>'EventDnsBase', 'hostname'=>'string', 'port'=>'int', 'family='=>'int'],
'EventBufferEvent::createPair' => ['array', 'base'=>'EventBase', 'options='=>'int'],
'EventBufferEvent::disable' => ['bool', 'events'=>'int'],
'EventBufferEvent::enable' => ['bool', 'events'=>'int'],
'EventBufferEvent::free' => ['void'],
'EventBufferEvent::getDnsErrorString' => ['string'],
'EventBufferEvent::getEnabled' => ['int'],
'EventBufferEvent::getInput' => ['EventBuffer'],
'EventBufferEvent::getOutput' => ['EventBuffer'],
'EventBufferEvent::read' => ['string', 'size'=>'int'],
'EventBufferEvent::readBuffer' => ['bool', 'buf'=>'EventBuffer'],
'EventBufferEvent::setCallbacks' => ['void', 'readcb'=>'callable', 'writecb'=>'callable', 'eventcb'=>'callable', 'arg='=>'string'],
'EventBufferEvent::setPriority' => ['bool', 'priority'=>'int'],
'EventBufferEvent::setTimeouts' => ['bool', 'timeout_read'=>'float', 'timeout_write'=>'float'],
'EventBufferEvent::setWatermark' => ['void', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'],
'EventBufferEvent::sslError' => ['string'],
'EventBufferEvent::sslFilter' => ['EventBufferEvent', 'base'=>'EventBase', 'underlying'=>'EventBufferEvent', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'],
'EventBufferEvent::sslGetCipherInfo' => ['string'],
'EventBufferEvent::sslGetCipherName' => ['string'],
'EventBufferEvent::sslGetCipherVersion' => ['string'],
'EventBufferEvent::sslGetProtocol' => ['string'],
'EventBufferEvent::sslRenegotiate' => ['void'],
'EventBufferEvent::sslSocket' => ['EventBufferEvent', 'base'=>'EventBase', 'socket'=>'mixed', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'],
'EventBufferEvent::write' => ['bool', 'data'=>'string'],
'EventBufferEvent::writeBuffer' => ['bool', 'buf'=>'EventBuffer'],
'EventConfig::__construct' => ['void'],
'EventConfig::avoidMethod' => ['bool', 'method'=>'string'],
'EventConfig::requireFeatures' => ['bool', 'feature'=>'int'],
'EventConfig::setMaxDispatchInterval' => ['void', 'max_interval'=>'int', 'max_callbacks'=>'int', 'min_priority'=>'int'],
'EventDnsBase::__construct' => ['void', 'base'=>'EventBase', 'initialize'=>'bool'],
'EventDnsBase::addNameserverIp' => ['bool', 'ip'=>'string'],
'EventDnsBase::addSearch' => ['void', 'domain'=>'string'],
'EventDnsBase::clearSearch' => ['void'],
'EventDnsBase::countNameservers' => ['int'],
'EventDnsBase::loadHosts' => ['bool', 'hosts'=>'string'],
'EventDnsBase::parseResolvConf' => ['bool', 'flags'=>'int', 'filename'=>'string'],
'EventDnsBase::setOption' => ['bool', 'option'=>'string', 'value'=>'string'],
'EventDnsBase::setSearchNdots' => ['bool', 'ndots'=>'int'],
'EventHttp::__construct' => ['void', 'base'=>'EventBase', 'ctx='=>'EventSslContext'],
'EventHttp::accept' => ['bool', 'socket'=>'mixed'],
'EventHttp::addServerAlias' => ['bool', 'alias'=>'string'],
'EventHttp::bind' => ['void', 'address'=>'string', 'port'=>'int'],
'EventHttp::removeServerAlias' => ['bool', 'alias'=>'string'],
'EventHttp::setAllowedMethods' => ['void', 'methods'=>'int'],
'EventHttp::setCallback' => ['void', 'path'=>'string', 'cb'=>'string', 'arg='=>'string'],
'EventHttp::setDefaultCallback' => ['void', 'cb'=>'string', 'arg='=>'string'],
'EventHttp::setMaxBodySize' => ['void', 'value'=>'int'],
'EventHttp::setMaxHeadersSize' => ['void', 'value'=>'int'],
'EventHttp::setTimeout' => ['void', 'value'=>'int'],
'EventHttpConnection::__construct' => ['void', 'base'=>'EventBase', 'dns_base'=>'EventDnsBase', 'address'=>'string', 'port'=>'int', 'ctx='=>'EventSslContext'],
'EventHttpConnection::getBase' => ['EventBase'],
'EventHttpConnection::getPeer' => ['void', '&w_address'=>'string', '&w_port'=>'int'],
'EventHttpConnection::makeRequest' => ['bool', 'req'=>'EventHttpRequest', 'type'=>'int', 'uri'=>'string'],
'EventHttpConnection::setCloseCallback' => ['void', 'callback'=>'callable', 'data='=>'mixed'],
'EventHttpConnection::setLocalAddress' => ['void', 'address'=>'string'],
'EventHttpConnection::setLocalPort' => ['void', 'port'=>'int'],
'EventHttpConnection::setMaxBodySize' => ['void', 'max_size'=>'string'],
'EventHttpConnection::setMaxHeadersSize' => ['void', 'max_size'=>'string'],
'EventHttpConnection::setRetries' => ['void', 'retries'=>'int'],
'EventHttpConnection::setTimeout' => ['void', 'timeout'=>'int'],
'EventHttpRequest::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed'],
'EventHttpRequest::addHeader' => ['bool', 'key'=>'string', 'value'=>'string', 'type'=>'int'],
'EventHttpRequest::cancel' => ['void'],
'EventHttpRequest::clearHeaders' => ['void'],
'EventHttpRequest::closeConnection' => ['void'],
'EventHttpRequest::findHeader' => ['void', 'key'=>'string', 'type'=>'string'],
'EventHttpRequest::free' => ['void'],
'EventHttpRequest::getBufferEvent' => ['EventBufferEvent'],
'EventHttpRequest::getCommand' => ['void'],
'EventHttpRequest::getConnection' => ['EventHttpConnection'],
'EventHttpRequest::getHost' => ['string'],
'EventHttpRequest::getInputBuffer' => ['EventBuffer'],
'EventHttpRequest::getInputHeaders' => ['array'],
'EventHttpRequest::getOutputBuffer' => ['EventBuffer'],
'EventHttpRequest::getOutputHeaders' => ['void'],
'EventHttpRequest::getResponseCode' => ['int'],
'EventHttpRequest::getUri' => ['string'],
'EventHttpRequest::removeHeader' => ['void', 'key'=>'string', 'type'=>'string'],
'EventHttpRequest::sendError' => ['void', 'error'=>'int', 'reason='=>'string'],
'EventHttpRequest::sendReply' => ['void', 'code'=>'int', 'reason'=>'string', 'buf='=>'EventBuffer'],
'EventHttpRequest::sendReplyChunk' => ['void', 'buf'=>'EventBuffer'],
'EventHttpRequest::sendReplyEnd' => ['void'],
'EventHttpRequest::sendReplyStart' => ['void', 'code'=>'int', 'reason'=>'string'],
'EventListener::__construct' => ['void', 'base'=>'EventBase', 'cb'=>'callable', 'data'=>'mixed', 'flags'=>'int', 'backlog'=>'int', 'target'=>'mixed'],
'EventListener::disable' => ['bool'],
'EventListener::enable' => ['bool'],
'EventListener::getBase' => ['void'],
'EventListener::getSocketName' => ['bool', '&w_address'=>'string', '&w_port='=>'mixed'],
'EventListener::setCallback' => ['void', 'cb'=>'callable', 'arg='=>'mixed'],
'EventListener::setErrorCallback' => ['void', 'cb'=>'string'],
'EventSslContext::__construct' => ['void', 'method'=>'string', 'options'=>'string'],
'EventUtil::__construct' => ['void'],
'EventUtil::getLastSocketErrno' => ['int', 'socket='=>'mixed'],
'EventUtil::getLastSocketError' => ['string', 'socket='=>'mixed'],
'EventUtil::getSocketFd' => ['int', 'socket'=>'mixed'],
'EventUtil::getSocketName' => ['bool', 'socket'=>'mixed', '&w_address'=>'string', '&w_port='=>'mixed'],
'EventUtil::setSocketOption' => ['bool', 'socket'=>'mixed', 'level'=>'int', 'optname'=>'int', 'optval'=>'mixed'],
'EventUtil::sslRandPoll' => ['void'],
'EvFork::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvFork::clear' => ['int'],
'EvFork::createStopped' => ['EvFork', 'callback'=>'callable', 'data='=>'string', 'priority='=>'string'],
'EvFork::feed' => ['void', 'events'=>'int'],
'EvFork::getLoop' => ['EvLoop'],
'EvFork::invoke' => ['void', 'events'=>'int'],
'EvFork::keepAlive' => ['void', 'value'=>'bool'],
'EvFork::setCallback' => ['void', 'callback'=>'callable'],
'EvFork::start' => ['void'],
'EvFork::stop' => ['void'],
'EvIdle::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvIdle::clear' => ['int'],
'EvIdle::createStopped' => ['EvIdle', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvIdle::feed' => ['void', 'events'=>'int'],
'EvIdle::getLoop' => ['EvLoop'],
'EvIdle::invoke' => ['void', 'events'=>'int'],
'EvIdle::keepAlive' => ['void', 'value'=>'bool'],
'EvIdle::setCallback' => ['void', 'callback'=>'callable'],
'EvIdle::start' => ['void'],
'EvIdle::stop' => ['void'],
'EvIo::__construct' => ['void', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvIo::clear' => ['int'],
'EvIo::createStopped' => ['EvIo', 'fd'=>'resource', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvIo::feed' => ['void', 'events'=>'int'],
'EvIo::getLoop' => ['EvLoop'],
'EvIo::invoke' => ['void', 'events'=>'int'],
'EvIo::keepAlive' => ['void', 'value'=>'bool'],
'EvIo::set' => ['void', 'fd'=>'resource', 'events'=>'int'],
'EvIo::setCallback' => ['void', 'callback'=>'callable'],
'EvIo::start' => ['void'],
'EvIo::stop' => ['void'],
'EvLoop::__construct' => ['void', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'],
'EvLoop::backend' => ['int'],
'EvLoop::check' => ['EvCheck', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::child' => ['EvChild', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::defaultLoop' => ['EvLoop', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'],
'EvLoop::embed' => ['EvEmbed', 'other'=>'EvLoop', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::fork' => ['EvFork', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::idle' => ['EvIdle', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::invokePending' => ['void'],
'EvLoop::io' => ['EvIo', 'fd'=>'resource', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::loopFork' => ['void'],
'EvLoop::now' => ['float'],
'EvLoop::nowUpdate' => ['void'],
'EvLoop::periodic' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::prepare' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::resume' => ['void'],
'EvLoop::run' => ['void', 'flags='=>'int'],
'EvLoop::signal' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::stat' => ['EvStat', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::stop' => ['void', 'how='=>'int'],
'EvLoop::suspend' => ['void'],
'EvLoop::timer' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvLoop::verify' => ['void'],
'EvPeriodic::__construct' => ['void', 'offset'=>'float', 'interval'=>'string', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvPeriodic::again' => ['void'],
'EvPeriodic::at' => ['float'],
'EvPeriodic::clear' => ['int'],
'EvPeriodic::createStopped' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvPeriodic::feed' => ['void', 'events'=>'int'],
'EvPeriodic::getLoop' => ['EvLoop'],
'EvPeriodic::invoke' => ['void', 'events'=>'int'],
'EvPeriodic::keepAlive' => ['void', 'value'=>'bool'],
'EvPeriodic::set' => ['void', 'offset'=>'float', 'interval'=>'float'],
'EvPeriodic::setCallback' => ['void', 'callback'=>'callable'],
'EvPeriodic::start' => ['void'],
'EvPeriodic::stop' => ['void'],
'EvPrepare::__construct' => ['void', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'],
'EvPrepare::clear' => ['int'],
'EvPrepare::createStopped' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvPrepare::feed' => ['void', 'events'=>'int'],
'EvPrepare::getLoop' => ['EvLoop'],
'EvPrepare::invoke' => ['void', 'events'=>'int'],
'EvPrepare::keepAlive' => ['void', 'value'=>'bool'],
'EvPrepare::setCallback' => ['void', 'callback'=>'callable'],
'EvPrepare::start' => ['void'],
'EvPrepare::stop' => ['void'],
'EvSignal::__construct' => ['void', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvSignal::clear' => ['int'],
'EvSignal::createStopped' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvSignal::feed' => ['void', 'events'=>'int'],
'EvSignal::getLoop' => ['EvLoop'],
'EvSignal::invoke' => ['void', 'events'=>'int'],
'EvSignal::keepAlive' => ['void', 'value'=>'bool'],
'EvSignal::set' => ['void', 'signum'=>'int'],
'EvSignal::setCallback' => ['void', 'callback'=>'callable'],
'EvSignal::start' => ['void'],
'EvSignal::stop' => ['void'],
'EvStat::__construct' => ['void', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvStat::attr' => ['array'],
'EvStat::clear' => ['int'],
'EvStat::createStopped' => ['EvStat', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvStat::feed' => ['void', 'events'=>'int'],
'EvStat::getLoop' => ['EvLoop'],
'EvStat::invoke' => ['void', 'events'=>'int'],
'EvStat::keepAlive' => ['void', 'value'=>'bool'],
'EvStat::prev' => ['array'],
'EvStat::set' => ['void', 'path'=>'string', 'interval'=>'float'],
'EvStat::setCallback' => ['void', 'callback'=>'callable'],
'EvStat::start' => ['void'],
'EvStat::stat' => ['bool'],
'EvStat::stop' => ['void'],
'EvTimer::__construct' => ['void', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvTimer::again' => ['void'],
'EvTimer::clear' => ['int'],
'EvTimer::createStopped' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'],
'EvTimer::feed' => ['void', 'events'=>'int'],
'EvTimer::getLoop' => ['EvLoop'],
'EvTimer::invoke' => ['void', 'events'=>'int'],
'EvTimer::keepAlive' => ['void', 'value'=>'bool'],
'EvTimer::set' => ['void', 'after'=>'float', 'repeat'=>'float'],
'EvTimer::setCallback' => ['void', 'callback'=>'callable'],
'EvTimer::start' => ['void'],
'EvTimer::stop' => ['void'],
'EvWatcher::__construct' => ['void'],
'EvWatcher::clear' => ['int'],
'EvWatcher::feed' => ['void', 'revents'=>'int'],
'EvWatcher::getLoop' => ['EvLoop'],
'EvWatcher::invoke' => ['void', 'revents'=>'int'],
'EvWatcher::keepalive' => ['bool', 'value='=>'bool'],
'EvWatcher::setCallback' => ['void', 'callback'=>'callable'],
'EvWatcher::start' => ['void'],
'EvWatcher::stop' => ['void'],
'Exception::__clone' => ['void'],
'Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'Exception::__toString' => ['string'],
'Exception::getCode' => ['int|string'],
'Exception::getFile' => ['string'],
'Exception::getLine' => ['int'],
'Exception::getMessage' => ['string'],
'Exception::getPrevious' => ['?Throwable'],
'Exception::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'Exception::getTraceAsString' => ['string'],
'exec' => ['string|false', 'command'=>'string', '&w_output='=>'array', '&w_result_code='=>'int'],
'exif_imagetype' => ['int|false', 'filename'=>'string'],
'exif_read_data' => ['array|false', 'file'=>'string|resource', 'required_sections='=>'?string', 'as_arrays='=>'bool', 'read_thumbnail='=>'bool'],
'exif_tagname' => ['string|false', 'index'=>'int'],
'exif_thumbnail' => ['string|false', 'file'=>'string', '&w_width='=>'int', '&w_height='=>'int', '&w_image_type='=>'int'],
'exit' => ['', 'status'=>'string|int'],
'exp' => ['float', 'num'=>'float'],
'expect_expectl' => ['int', 'expect'=>'resource', 'cases'=>'array', 'match='=>'array'],
'expect_popen' => ['resource|false', 'command'=>'string'],
'explode' => ['list<string>', 'separator'=>'string', 'string'=>'string', 'limit='=>'int'],
'expm1' => ['float', 'num'=>'float'],
'extension_loaded' => ['bool', 'extension'=>'string'],
'extract' => ['int', '&rw_array'=>'array', 'flags='=>'int', 'prefix='=>'string'],
'ezmlm_hash' => ['int', 'addr'=>'string'],
'fam_cancel_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'],
'fam_close' => ['void', 'fam'=>'resource'],
'fam_monitor_collection' => ['resource', 'fam'=>'resource', 'dirname'=>'string', 'depth'=>'int', 'mask'=>'string'],
'fam_monitor_directory' => ['resource', 'fam'=>'resource', 'dirname'=>'string'],
'fam_monitor_file' => ['resource', 'fam'=>'resource', 'filename'=>'string'],
'fam_next_event' => ['array', 'fam'=>'resource'],
'fam_open' => ['resource|false', 'appname='=>'string'],
'fam_pending' => ['int', 'fam'=>'resource'],
'fam_resume_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'],
'fam_suspend_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'],
'fann_cascadetrain_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'],
'fann_cascadetrain_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'],
'fann_clear_scaling_params' => ['bool', 'ann'=>'resource'],
'fann_copy' => ['resource|false', 'ann'=>'resource'],
'fann_create_from_file' => ['resource', 'configuration_file'=>'string'],
'fann_create_shortcut' => ['resource|false', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'],
'fann_create_shortcut_array' => ['resource|false', 'num_layers'=>'int', 'layers'=>'array'],
'fann_create_sparse' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'],
'fann_create_sparse_array' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'layers'=>'array'],
'fann_create_standard' => ['resource|false', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'],
'fann_create_standard_array' => ['resource|false', 'num_layers'=>'int', 'layers'=>'array'],
'fann_create_train' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int'],
'fann_create_train_from_callback' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int', 'user_function'=>'callable'],
'fann_descale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'],
'fann_descale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'],
'fann_descale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'],
'fann_destroy' => ['bool', 'ann'=>'resource'],
'fann_destroy_train' => ['bool', 'train_data'=>'resource'],
'fann_duplicate_train_data' => ['resource', 'data'=>'resource'],
'fann_get_activation_function' => ['int|false', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'],
'fann_get_activation_steepness' => ['float|false', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'],
'fann_get_bias_array' => ['array', 'ann'=>'resource'],
'fann_get_bit_fail' => ['int|false', 'ann'=>'resource'],
'fann_get_bit_fail_limit' => ['float|false', 'ann'=>'resource'],
'fann_get_cascade_activation_functions' => ['array|false', 'ann'=>'resource'],
'fann_get_cascade_activation_functions_count' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_activation_steepnesses' => ['array|false', 'ann'=>'resource'],
'fann_get_cascade_activation_steepnesses_count' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_candidate_change_fraction' => ['float|false', 'ann'=>'resource'],
'fann_get_cascade_candidate_limit' => ['float|false', 'ann'=>'resource'],
'fann_get_cascade_candidate_stagnation_epochs' => ['float|false', 'ann'=>'resource'],
'fann_get_cascade_max_cand_epochs' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_max_out_epochs' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_min_cand_epochs' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_min_out_epochs' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_num_candidate_groups' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_num_candidates' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_output_change_fraction' => ['float|false', 'ann'=>'resource'],
'fann_get_cascade_output_stagnation_epochs' => ['int|false', 'ann'=>'resource'],
'fann_get_cascade_weight_multiplier' => ['float|false', 'ann'=>'resource'],
'fann_get_connection_array' => ['array', 'ann'=>'resource'],
'fann_get_connection_rate' => ['float|false', 'ann'=>'resource'],
'fann_get_errno' => ['int|false', 'errdat'=>'resource'],
'fann_get_errstr' => ['string|false', 'errdat'=>'resource'],
'fann_get_layer_array' => ['array', 'ann'=>'resource'],
'fann_get_learning_momentum' => ['float|false', 'ann'=>'resource'],
'fann_get_learning_rate' => ['float|false', 'ann'=>'resource'],
'fann_get_MSE' => ['float|false', 'ann'=>'resource'],
'fann_get_network_type' => ['int|false', 'ann'=>'resource'],
'fann_get_num_input' => ['int|false', 'ann'=>'resource'],
'fann_get_num_layers' => ['int|false', 'ann'=>'resource'],
'fann_get_num_output' => ['int|false', 'ann'=>'resource'],
'fann_get_quickprop_decay' => ['float|false', 'ann'=>'resource'],
'fann_get_quickprop_mu' => ['float|false', 'ann'=>'resource'],
'fann_get_rprop_decrease_factor' => ['float|false', 'ann'=>'resource'],
'fann_get_rprop_delta_max' => ['float|false', 'ann'=>'resource'],
'fann_get_rprop_delta_min' => ['float|false', 'ann'=>'resource'],
'fann_get_rprop_delta_zero' => ['float|false', 'ann'=>'resource'],
'fann_get_rprop_increase_factor' => ['float|false', 'ann'=>'resource'],
'fann_get_sarprop_step_error_shift' => ['float|false', 'ann'=>'resource'],
'fann_get_sarprop_step_error_threshold_factor' => ['float|false', 'ann'=>'resource'],
'fann_get_sarprop_temperature' => ['float|false', 'ann'=>'resource'],
'fann_get_sarprop_weight_decay_shift' => ['float|false', 'ann'=>'resource'],
'fann_get_total_connections' => ['int|false', 'ann'=>'resource'],
'fann_get_total_neurons' => ['int|false', 'ann'=>'resource'],
'fann_get_train_error_function' => ['int|false', 'ann'=>'resource'],
'fann_get_train_stop_function' => ['int|false', 'ann'=>'resource'],
'fann_get_training_algorithm' => ['int|false', 'ann'=>'resource'],
'fann_init_weights' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'],
'fann_length_train_data' => ['int|false', 'data'=>'resource'],
'fann_merge_train_data' => ['resource|false', 'data1'=>'resource', 'data2'=>'resource'],
'fann_num_input_train_data' => ['int|false', 'data'=>'resource'],
'fann_num_output_train_data' => ['int|false', 'data'=>'resource'],
'fann_print_error' => ['void', 'errdat'=>'string'],
'fann_randomize_weights' => ['bool', 'ann'=>'resource', 'min_weight'=>'float', 'max_weight'=>'float'],
'fann_read_train_from_file' => ['resource', 'filename'=>'string'],
'fann_reset_errno' => ['void', 'errdat'=>'resource'],
'fann_reset_errstr' => ['void', 'errdat'=>'resource'],
'fann_reset_MSE' => ['bool', 'ann'=>'string'],
'fann_run' => ['array|false', 'ann'=>'resource', 'input'=>'array'],
'fann_save' => ['bool', 'ann'=>'resource', 'configuration_file'=>'string'],
'fann_save_train' => ['bool', 'data'=>'resource', 'file_name'=>'string'],
'fann_scale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'],
'fann_scale_input_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'],
'fann_scale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'],
'fann_scale_output_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'],
'fann_scale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'],
'fann_scale_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'],
'fann_set_activation_function' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int', 'neuron'=>'int'],
'fann_set_activation_function_hidden' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'],
'fann_set_activation_function_layer' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int'],
'fann_set_activation_function_output' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'],
'fann_set_activation_steepness' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int', 'neuron'=>'int'],
'fann_set_activation_steepness_hidden' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'],
'fann_set_activation_steepness_layer' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int'],
'fann_set_activation_steepness_output' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'],
'fann_set_bit_fail_limit' => ['bool', 'ann'=>'resource', 'bit_fail_limit'=>'float'],
'fann_set_callback' => ['bool', 'ann'=>'resource', 'callback'=>'callable'],
'fann_set_cascade_activation_functions' => ['bool', 'ann'=>'resource', 'cascade_activation_functions'=>'array'],
'fann_set_cascade_activation_steepnesses' => ['bool', 'ann'=>'resource', 'cascade_activation_steepnesses_count'=>'array'],
'fann_set_cascade_candidate_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_candidate_change_fraction'=>'float'],
'fann_set_cascade_candidate_limit' => ['bool', 'ann'=>'resource', 'cascade_candidate_limit'=>'float'],
'fann_set_cascade_candidate_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_candidate_stagnation_epochs'=>'int'],
'fann_set_cascade_max_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_cand_epochs'=>'int'],
'fann_set_cascade_max_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_out_epochs'=>'int'],
'fann_set_cascade_min_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_cand_epochs'=>'int'],
'fann_set_cascade_min_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_out_epochs'=>'int'],
'fann_set_cascade_num_candidate_groups' => ['bool', 'ann'=>'resource', 'cascade_num_candidate_groups'=>'int'],
'fann_set_cascade_output_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_output_change_fraction'=>'float'],
'fann_set_cascade_output_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_output_stagnation_epochs'=>'int'],
'fann_set_cascade_weight_multiplier' => ['bool', 'ann'=>'resource', 'cascade_weight_multiplier'=>'float'],
'fann_set_error_log' => ['void', 'errdat'=>'resource', 'log_file'=>'string'],
'fann_set_input_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float'],
'fann_set_learning_momentum' => ['bool', 'ann'=>'resource', 'learning_momentum'=>'float'],
'fann_set_learning_rate' => ['bool', 'ann'=>'resource', 'learning_rate'=>'float'],
'fann_set_output_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_output_min'=>'float', 'new_output_max'=>'float'],
'fann_set_quickprop_decay' => ['bool', 'ann'=>'resource', 'quickprop_decay'=>'float'],
'fann_set_quickprop_mu' => ['bool', 'ann'=>'resource', 'quickprop_mu'=>'float'],
'fann_set_rprop_decrease_factor' => ['bool', 'ann'=>'resource', 'rprop_decrease_factor'=>'float'],
'fann_set_rprop_delta_max' => ['bool', 'ann'=>'resource', 'rprop_delta_max'=>'float'],
'fann_set_rprop_delta_min' => ['bool', 'ann'=>'resource', 'rprop_delta_min'=>'float'],
'fann_set_rprop_delta_zero' => ['bool', 'ann'=>'resource', 'rprop_delta_zero'=>'float'],
'fann_set_rprop_increase_factor' => ['bool', 'ann'=>'resource', 'rprop_increase_factor'=>'float'],
'fann_set_sarprop_step_error_shift' => ['bool', 'ann'=>'resource', 'sarprop_step_error_shift'=>'float'],
'fann_set_sarprop_step_error_threshold_factor' => ['bool', 'ann'=>'resource', 'sarprop_step_error_threshold_factor'=>'float'],
'fann_set_sarprop_temperature' => ['bool', 'ann'=>'resource', 'sarprop_temperature'=>'float'],
'fann_set_sarprop_weight_decay_shift' => ['bool', 'ann'=>'resource', 'sarprop_weight_decay_shift'=>'float'],
'fann_set_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float', 'new_output_min'=>'float', 'new_output_max'=>'float'],
'fann_set_train_error_function' => ['bool', 'ann'=>'resource', 'error_function'=>'int'],
'fann_set_train_stop_function' => ['bool', 'ann'=>'resource', 'stop_function'=>'int'],
'fann_set_training_algorithm' => ['bool', 'ann'=>'resource', 'training_algorithm'=>'int'],
'fann_set_weight' => ['bool', 'ann'=>'resource', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'],
'fann_set_weight_array' => ['bool', 'ann'=>'resource', 'connections'=>'array'],
'fann_shuffle_train_data' => ['bool', 'train_data'=>'resource'],
'fann_subset_train_data' => ['resource', 'data'=>'resource', 'pos'=>'int', 'length'=>'int'],
'fann_test' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'],
'fann_test_data' => ['float|false', 'ann'=>'resource', 'data'=>'resource'],
'fann_train' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'],
'fann_train_epoch' => ['float|false', 'ann'=>'resource', 'data'=>'resource'],
'fann_train_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'],
'fann_train_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'],
'FANNConnection::__construct' => ['void', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'],
'FANNConnection::getFromNeuron' => ['int'],
'FANNConnection::getToNeuron' => ['int'],
'FANNConnection::getWeight' => ['void'],
'FANNConnection::setWeight' => ['bool', 'weight'=>'float'],
'fastcgi_finish_request' => ['bool'],
'fbsql_affected_rows' => ['int', 'link_identifier='=>'?resource'],
'fbsql_autocommit' => ['bool', 'link_identifier'=>'resource', 'onoff='=>'bool'],
'fbsql_blob_size' => ['int', 'blob_handle'=>'string', 'link_identifier='=>'?resource'],
'fbsql_change_user' => ['bool', 'user'=>'string', 'password'=>'string', 'database='=>'string', 'link_identifier='=>'?resource'],
'fbsql_clob_size' => ['int', 'clob_handle'=>'string', 'link_identifier='=>'?resource'],
'fbsql_close' => ['bool', 'link_identifier='=>'?resource'],
'fbsql_commit' => ['bool', 'link_identifier='=>'?resource'],
'fbsql_connect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'],
'fbsql_create_blob' => ['string', 'blob_data'=>'string', 'link_identifier='=>'?resource'],
'fbsql_create_clob' => ['string', 'clob_data'=>'string', 'link_identifier='=>'?resource'],
'fbsql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'],
'fbsql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'],
'fbsql_database' => ['string', 'link_identifier'=>'resource', 'database='=>'string'],
'fbsql_database_password' => ['string', 'link_identifier'=>'resource', 'database_password='=>'string'],
'fbsql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'],
'fbsql_db_status' => ['int', 'database_name'=>'string', 'link_identifier='=>'?resource'],
'fbsql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
'fbsql_errno' => ['int', 'link_identifier='=>'?resource'],
'fbsql_error' => ['string', 'link_identifier='=>'?resource'],
'fbsql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'],
'fbsql_fetch_assoc' => ['array', 'result'=>'resource'],
'fbsql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'],
'fbsql_fetch_lengths' => ['array', 'result'=>'resource'],
'fbsql_fetch_object' => ['object', 'result'=>'resource'],
'fbsql_fetch_row' => ['array', 'result'=>'resource'],
'fbsql_field_flags' => ['string', 'result'=>'resource', 'field_offset='=>'int'],
'fbsql_field_len' => ['int', 'result'=>'resource', 'field_offset='=>'int'],
'fbsql_field_name' => ['string', 'result'=>'resource', 'field_index='=>'int'],
'fbsql_field_seek' => ['bool', 'result'=>'resource', 'field_offset='=>'int'],
'fbsql_field_table' => ['string', 'result'=>'resource', 'field_offset='=>'int'],
'fbsql_field_type' => ['string', 'result'=>'resource', 'field_offset='=>'int'],
'fbsql_free_result' => ['bool', 'result'=>'resource'],
'fbsql_get_autostart_info' => ['array', 'link_identifier='=>'?resource'],
'fbsql_hostname' => ['string', 'link_identifier'=>'resource', 'host_name='=>'string'],
'fbsql_insert_id' => ['int', 'link_identifier='=>'?resource'],
'fbsql_list_dbs' => ['resource', 'link_identifier='=>'?resource'],
'fbsql_list_fields' => ['resource', 'database_name'=>'string', 'table_name'=>'string', 'link_identifier='=>'?resource'],
'fbsql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'],
'fbsql_next_result' => ['bool', 'result'=>'resource'],
'fbsql_num_fields' => ['int', 'result'=>'resource'],
'fbsql_num_rows' => ['int', 'result'=>'resource'],
'fbsql_password' => ['string', 'link_identifier'=>'resource', 'password='=>'string'],
'fbsql_pconnect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'],
'fbsql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource', 'batch_size='=>'int'],
'fbsql_read_blob' => ['string', 'blob_handle'=>'string', 'link_identifier='=>'?resource'],
'fbsql_read_clob' => ['string', 'clob_handle'=>'string', 'link_identifier='=>'?resource'],
'fbsql_result' => ['mixed', 'result'=>'resource', 'row='=>'int', 'field='=>'mixed'],
'fbsql_rollback' => ['bool', 'link_identifier='=>'?resource'],
'fbsql_rows_fetched' => ['int', 'result'=>'resource'],
'fbsql_select_db' => ['bool', 'database_name='=>'string', 'link_identifier='=>'?resource'],
'fbsql_set_characterset' => ['void', 'link_identifier'=>'resource', 'characterset'=>'int', 'in_out_both='=>'int'],
'fbsql_set_lob_mode' => ['bool', 'result'=>'resource', 'lob_mode'=>'int'],
'fbsql_set_password' => ['bool', 'link_identifier'=>'resource', 'user'=>'string', 'password'=>'string', 'old_password'=>'string'],
'fbsql_set_transaction' => ['void', 'link_identifier'=>'resource', 'locking'=>'int', 'isolation'=>'int'],
'fbsql_start_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'],
'fbsql_stop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
'fbsql_table_name' => ['string', 'result'=>'resource', 'index'=>'int'],
'fbsql_username' => ['string', 'link_identifier'=>'resource', 'username='=>'string'],
'fbsql_warnings' => ['bool', 'onoff='=>'bool'],
'fclose' => ['bool', 'stream'=>'resource'],
'fdf_add_doc_javascript' => ['bool', 'fdf_document'=>'resource', 'script_name'=>'string', 'script_code'=>'string'],
'fdf_add_template' => ['bool', 'fdf_document'=>'resource', 'newpage'=>'int', 'filename'=>'string', 'template'=>'string', 'rename'=>'int'],
'fdf_close' => ['void', 'fdf_document'=>'resource'],
'fdf_create' => ['resource'],
'fdf_enum_values' => ['bool', 'fdf_document'=>'resource', 'function'=>'callable', 'userdata='=>'mixed'],
'fdf_errno' => ['int'],
'fdf_error' => ['string', 'error_code='=>'int'],
'fdf_get_ap' => ['bool', 'fdf_document'=>'resource', 'field'=>'string', 'face'=>'int', 'filename'=>'string'],
'fdf_get_attachment' => ['array', 'fdf_document'=>'resource', 'fieldname'=>'string', 'savepath'=>'string'],
'fdf_get_encoding' => ['string', 'fdf_document'=>'resource'],
'fdf_get_file' => ['string', 'fdf_document'=>'resource'],
'fdf_get_flags' => ['int', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int'],
'fdf_get_opt' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element='=>'int'],
'fdf_get_status' => ['string', 'fdf_document'=>'resource'],
'fdf_get_value' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'which='=>'int'],
'fdf_get_version' => ['string', 'fdf_document='=>'resource'],
'fdf_header' => ['void'],
'fdf_next_field_name' => ['string', 'fdf_document'=>'resource', 'fieldname='=>'string'],
'fdf_open' => ['resource|false', 'filename'=>'string'],
'fdf_open_string' => ['resource', 'fdf_data'=>'string'],
'fdf_remove_item' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'item'=>'int'],
'fdf_save' => ['bool', 'fdf_document'=>'resource', 'filename='=>'string'],
'fdf_save_string' => ['string', 'fdf_document'=>'resource'],
'fdf_set_ap' => ['bool', 'fdf_document'=>'resource', 'field_name'=>'string', 'face'=>'int', 'filename'=>'string', 'page_number'=>'int'],
'fdf_set_encoding' => ['bool', 'fdf_document'=>'resource', 'encoding'=>'string'],
'fdf_set_file' => ['bool', 'fdf_document'=>'resource', 'url'=>'string', 'target_frame='=>'string'],
'fdf_set_flags' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int', 'newflags'=>'int'],
'fdf_set_javascript_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string'],
'fdf_set_on_import_javascript' => ['bool', 'fdf_document'=>'resource', 'script'=>'string', 'before_data_import'=>'bool'],
'fdf_set_opt' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element'=>'int', 'string1'=>'string', 'string2'=>'string'],
'fdf_set_status' => ['bool', 'fdf_document'=>'resource', 'status'=>'string'],
'fdf_set_submit_form_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string', 'flags'=>'int'],
'fdf_set_target_frame' => ['bool', 'fdf_document'=>'resource', 'frame_name'=>'string'],
'fdf_set_value' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'value'=>'mixed', 'isname='=>'int'],
'fdf_set_version' => ['bool', 'fdf_document'=>'resource', 'version'=>'string'],
'fdiv' => ['float', 'num1'=>'float', 'num2'=>'float'],
'feof' => ['bool', 'stream'=>'resource'],
'fflush' => ['bool', 'stream'=>'resource'],
'fsync' => ['bool', 'stream'=>'resource'],
'fdatasync' => ['bool', 'stream'=>'resource'],
'ffmpeg_animated_gif::__construct' => ['void', 'output_file_path'=>'string', 'width'=>'int', 'height'=>'int', 'frame_rate'=>'int', 'loop_count='=>'int'],
'ffmpeg_animated_gif::addFrame' => ['', 'frame_to_add'=>'ffmpeg_frame'],
'ffmpeg_frame::__construct' => ['void', 'gd_image'=>'resource'],
'ffmpeg_frame::crop' => ['', 'crop_top'=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'],
'ffmpeg_frame::getHeight' => ['int'],
'ffmpeg_frame::getPresentationTimestamp' => ['int'],
'ffmpeg_frame::getPTS' => ['int'],
'ffmpeg_frame::getWidth' => ['int'],
'ffmpeg_frame::resize' => ['', 'width'=>'int', 'height'=>'int', 'crop_top='=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'],
'ffmpeg_frame::toGDImage' => ['resource'],
'ffmpeg_movie::__construct' => ['void', 'path_to_media'=>'string', 'persistent'=>'bool'],
'ffmpeg_movie::getArtist' => ['string'],
'ffmpeg_movie::getAudioBitRate' => ['int'],
'ffmpeg_movie::getAudioChannels' => ['int'],
'ffmpeg_movie::getAudioCodec' => ['string'],
'ffmpeg_movie::getAudioSampleRate' => ['int'],
'ffmpeg_movie::getAuthor' => ['string'],
'ffmpeg_movie::getBitRate' => ['int'],
'ffmpeg_movie::getComment' => ['string'],
'ffmpeg_movie::getCopyright' => ['string'],
'ffmpeg_movie::getDuration' => ['int'],
'ffmpeg_movie::getFilename' => ['string'],
'ffmpeg_movie::getFrame' => ['ffmpeg_frame|false', 'framenumber'=>'int'],
'ffmpeg_movie::getFrameCount' => ['int'],
'ffmpeg_movie::getFrameHeight' => ['int'],
'ffmpeg_movie::getFrameNumber' => ['int'],
'ffmpeg_movie::getFrameRate' => ['int'],
'ffmpeg_movie::getFrameWidth' => ['int'],
'ffmpeg_movie::getGenre' => ['string'],
'ffmpeg_movie::getNextKeyFrame' => ['ffmpeg_frame|false'],
'ffmpeg_movie::getPixelFormat' => [''],
'ffmpeg_movie::getTitle' => ['string'],
'ffmpeg_movie::getTrackNumber' => ['int|string'],
'ffmpeg_movie::getVideoBitRate' => ['int'],
'ffmpeg_movie::getVideoCodec' => ['string'],
'ffmpeg_movie::getYear' => ['int|string'],
'ffmpeg_movie::hasAudio' => ['bool'],
'ffmpeg_movie::hasVideo' => ['bool'],
'fgetc' => ['string|false', 'stream'=>'resource'],
'fgetcsv' => ['list<string>|array{0: null}|false', 'stream'=>'resource', 'length='=>'?int', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'fgets' => ['string|false', 'stream'=>'resource', 'length='=>'?int'],
'Fiber::__construct' => ['void', 'callback'=>'callable'],
'Fiber::start' => ['mixed', '...args'=>'mixed'],
'Fiber::resume' => ['mixed', 'value='=>'null|mixed'],
'Fiber::throw' => ['mixed', 'exception'=>'Throwable'],
'Fiber::isStarted' => ['bool'],
'Fiber::isSuspended' => ['bool'],
'Fiber::isRunning' => ['bool'],
'Fiber::isTerminated' => ['bool'],
'Fiber::getReturn' => ['mixed'],
'Fiber::getCurrent' => ['?self'],
'Fiber::suspend' => ['mixed', 'value='=>'null|mixed'],
'FiberError::__construct' => ['void'],
'file' => ['list<string>|false', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
'file_exists' => ['bool', 'filename'=>'string'],
'file_get_contents' => ['string|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'?resource', 'offset='=>'int', 'length='=>'?int'],
'file_put_contents' => ['int|false', 'filename'=>'string', 'data'=>'string|resource|array<string>', 'flags='=>'int', 'context='=>'resource'],
'fileatime' => ['int|false', 'filename'=>'string'],
'filectime' => ['int|false', 'filename'=>'string'],
'filegroup' => ['int|false', 'filename'=>'string'],
'fileinode' => ['int|false', 'filename'=>'string'],
'filemtime' => ['int|false', 'filename'=>'string'],
'fileowner' => ['int|false', 'filename'=>'string'],
'fileperms' => ['int|false', 'filename'=>'string'],
'filepro' => ['bool', 'directory'=>'string'],
'filepro_fieldcount' => ['int'],
'filepro_fieldname' => ['string', 'field_number'=>'int'],
'filepro_fieldtype' => ['string', 'field_number'=>'int'],
'filepro_fieldwidth' => ['int', 'field_number'=>'int'],
'filepro_retrieve' => ['string', 'row_number'=>'int', 'field_number'=>'int'],
'filepro_rowcount' => ['int'],
'filesize' => ['int|false', 'filename'=>'string'],
'FilesystemIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'],
'FilesystemIterator::__toString' => ['string'],
'FilesystemIterator::current' => ['SplFileInfo|FilesystemIterator|string'],
'FilesystemIterator::getATime' => ['int'],
'FilesystemIterator::getBasename' => ['string', 'suffix='=>'string'],
'FilesystemIterator::getCTime' => ['int'],
'FilesystemIterator::getExtension' => ['string'],
'FilesystemIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
'FilesystemIterator::getFilename' => ['string'],
'FilesystemIterator::getFlags' => ['int'],
'FilesystemIterator::getGroup' => ['int'],
'FilesystemIterator::getInode' => ['int'],
'FilesystemIterator::getLinkTarget' => ['string'],
'FilesystemIterator::getMTime' => ['int'],
'FilesystemIterator::getOwner' => ['int'],
'FilesystemIterator::getPath' => ['string'],
'FilesystemIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
'FilesystemIterator::getPathname' => ['string'],
'FilesystemIterator::getPerms' => ['int'],
'FilesystemIterator::getRealPath' => ['string'],
'FilesystemIterator::getSize' => ['int'],
'FilesystemIterator::getType' => ['string'],
'FilesystemIterator::isDir' => ['bool'],
'FilesystemIterator::isDot' => ['bool'],
'FilesystemIterator::isExecutable' => ['bool'],
'FilesystemIterator::isFile' => ['bool'],
'FilesystemIterator::isLink' => ['bool'],
'FilesystemIterator::isReadable' => ['bool'],
'FilesystemIterator::isWritable' => ['bool'],
'FilesystemIterator::key' => ['string'],
'FilesystemIterator::next' => ['void'],
'FilesystemIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
'FilesystemIterator::rewind' => ['void'],
'FilesystemIterator::seek' => ['void', 'position'=>'int'],
'FilesystemIterator::setFileClass' => ['void', 'class_name='=>'string'],
'FilesystemIterator::setFlags' => ['void', 'flags='=>'int'],
'FilesystemIterator::setInfoClass' => ['void', 'class_name='=>'string'],
'FilesystemIterator::valid' => ['bool'],
'filetype' => ['string|false', 'filename'=>'string'],
'filter_has_var' => ['bool', 'input_type'=>'int', 'var_name'=>'string'],
'filter_id' => ['int|false', 'name'=>'string'],
'filter_input' => ['mixed|false', 'type'=>'int', 'var_name'=>'string', 'filter='=>'int', 'options='=>'array|int'],
'filter_input_array' => ['array|false|null', 'type'=>'int', 'options='=>'int|array', 'add_empty='=>'bool'],
'filter_list' => ['array'],
'filter_var' => ['mixed|false', 'value'=>'mixed', 'filter='=>'int', 'options='=>'array|int'],
'filter_var_array' => ['array|false|null', 'array'=>'array', 'options='=>'array|int', 'add_empty='=>'bool'],
'FilterIterator::__construct' => ['void', 'iterator'=>'Iterator'],
'FilterIterator::accept' => ['bool'],
'FilterIterator::current' => ['mixed'],
'FilterIterator::getInnerIterator' => ['Iterator'],
'FilterIterator::key' => ['mixed'],
'FilterIterator::next' => ['void'],
'FilterIterator::rewind' => ['void'],
'FilterIterator::valid' => ['bool'],
'finfo::__construct' => ['void', 'options='=>'int', 'magic_file='=>'string'],
'finfo::buffer' => ['string|false', 'string'=>'string', 'options='=>'int', 'context='=>'resource'],
'finfo::file' => ['string|false', 'file_name'=>'string', 'options='=>'int', 'context='=>'resource'],
'finfo::set_flags' => ['bool', 'options'=>'int'],
'finfo_buffer' => ['string|false', 'finfo'=>'finfo', 'string'=>'string', 'flags='=>'int', 'context='=>'resource'],
'finfo_close' => ['bool', 'finfo'=>'finfo'],
'finfo_file' => ['string|false', 'finfo'=>'finfo', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
'finfo_open' => ['finfo|false', 'flags='=>'int', 'magic_database='=>'?string'],
'finfo_set_flags' => ['bool', 'finfo'=>'finfo', 'flags'=>'int'],
'floatval' => ['float', 'value'=>'mixed'],
'flock' => ['bool', 'stream'=>'resource', 'operation'=>'int', '&w_would_block='=>'int'],
'floor' => ['float', 'num'=>'float'],
'flush' => ['void'],
'fmod' => ['float', 'num1'=>'float', 'num2'=>'float'],
'fnmatch' => ['bool', 'pattern'=>'string', 'filename'=>'string', 'flags='=>'int'],
'fopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'bool', 'context='=>'resource|null'],
'forward_static_call' => ['mixed|false', 'callback'=>'callable', '...args='=>'mixed'],
'forward_static_call_array' => ['mixed|false', 'callback'=>'callable', 'args'=>'list<mixed>'],
'fpassthru' => ['int', 'stream'=>'resource'],
'fpm_get_status' => ['array|false'],
'fprintf' => ['int', 'stream'=>'resource', 'format'=>'string', '...values='=>'string|int|float'],
'fputcsv' => ['int|false', 'stream'=>'resource', 'fields'=>'array<array-key, null|scalar|Stringable>', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string', 'eol='=>'string'],
'fputs' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
'fread' => ['string|false', 'stream'=>'resource', 'length'=>'int'],
'frenchtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
'fribidi_log2vis' => ['string', 'string'=>'string', 'direction'=>'string', 'charset'=>'int'],
'fscanf' => ['list<mixed>', 'stream'=>'resource', 'format'=>'string'],
'fscanf\'1' => ['int', 'stream'=>'resource', 'format'=>'string', '&...w_vars='=>'string|int|float'],
'fseek' => ['int', 'stream'=>'resource', 'offset'=>'int', 'whence='=>'int'],
'fsockopen' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'?float'],
'fstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'stream'=>'resource'],
'ftell' => ['int|false', 'stream'=>'resource'],
'ftok' => ['int', 'filename'=>'string', 'project_id'=>'string'],
'ftp_alloc' => ['bool', 'ftp'=>'FTP\Connection', 'size'=>'int', '&w_response='=>'string'],
'ftp_append' => ['bool', 'ftp'=>'FTP\Connection', 'remote_filename'=>'string', 'local_filename'=>'string', 'mode='=>'int'],
'ftp_cdup' => ['bool', 'ftp'=>'FTP\Connection'],
'ftp_chdir' => ['bool', 'ftp'=>'FTP\Connection', 'directory'=>'string'],
'ftp_chmod' => ['int|false', 'ftp'=>'FTP\Connection', 'permissions'=>'int', 'filename'=>'string'],
'ftp_close' => ['bool', 'ftp'=>'FTP\Connection'],
'ftp_connect' => ['FTP\Connection|false', 'hostname'=>'string', 'port='=>'int', 'timeout='=>'int'],
'ftp_delete' => ['bool', 'ftp'=>'FTP\Connection', 'filename'=>'string'],
'ftp_exec' => ['bool', 'ftp'=>'FTP\Connection', 'command'=>'string'],
'ftp_fget' => ['bool', 'ftp'=>'FTP\Connection', 'stream'=>'resource', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
'ftp_fput' => ['bool', 'ftp'=>'FTP\Connection', 'remote_filename'=>'string', 'stream'=>'resource', 'mode='=>'int', 'offset='=>'int'],
'ftp_get' => ['bool', 'ftp'=>'FTP\Connection', 'local_filename'=>'string', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
'ftp_get_option' => ['int|false', 'ftp'=>'FTP\Connection', 'option'=>'int'],
'ftp_login' => ['bool', 'ftp'=>'FTP\Connection', 'username'=>'string', 'password'=>'string'],
'ftp_mdtm' => ['int', 'ftp'=>'FTP\Connection', 'filename'=>'string'],
'ftp_mkdir' => ['string|false', 'ftp'=>'FTP\Connection', 'directory'=>'string'],
'ftp_mlsd' => ['array|false', 'ftp'=>'FTP\Connection', 'directory'=>'string'],
'ftp_nb_continue' => ['int', 'ftp'=>'FTP\Connection'],
'ftp_nb_fget' => ['int', 'ftp'=>'FTP\Connection', 'stream'=>'resource', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
'ftp_nb_fput' => ['int', 'ftp'=>'FTP\Connection', 'remote_filename'=>'string', 'stream'=>'resource', 'mode='=>'int', 'offset='=>'int'],
'ftp_nb_get' => ['int', 'ftp'=>'FTP\Connection', 'local_filename'=>'string', 'remote_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
'ftp_nb_put' => ['int', 'ftp'=>'FTP\Connection', 'remote_filename'=>'string', 'local_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
'ftp_nlist' => ['array|false', 'ftp'=>'FTP\Connection', 'directory'=>'string'],
'ftp_pasv' => ['bool', 'ftp'=>'FTP\Connection', 'enable'=>'bool'],
'ftp_put' => ['bool', 'ftp'=>'FTP\Connection', 'remote_filename'=>'string', 'local_filename'=>'string', 'mode='=>'int', 'offset='=>'int'],
'ftp_pwd' => ['string|false', 'ftp'=>'FTP\Connection'],
'ftp_quit' => ['bool', 'ftp'=>'FTP\Connection'],
'ftp_raw' => ['?array', 'ftp'=>'FTP\Connection', 'command'=>'string'],
'ftp_rawlist' => ['array|false', 'ftp'=>'FTP\Connection', 'directory'=>'string', 'recursive='=>'bool'],
'ftp_rename' => ['bool', 'ftp'=>'FTP\Connection', 'from'=>'string', 'to'=>'string'],
'ftp_rmdir' => ['bool', 'ftp'=>'FTP\Connection', 'directory'=>'string'],
'ftp_set_option' => ['bool', 'ftp'=>'FTP\Connection', 'option'=>'int', 'value'=>'mixed'],
'ftp_site' => ['bool', 'ftp'=>'FTP\Connection', 'command'=>'string'],
'ftp_size' => ['int', 'ftp'=>'FTP\Connection', 'filename'=>'string'],
'ftp_ssl_connect' => ['FTP\Connection|false', 'hostname'=>'string', 'port='=>'int', 'timeout='=>'int'],
'ftp_systype' => ['string|false', 'ftp'=>'FTP\Connection'],
'ftruncate' => ['bool', 'stream'=>'resource', 'size'=>'int'],
'func_get_arg' => ['mixed|false', 'position'=>'int'],
'func_get_args' => ['list<mixed>'],
'func_num_args' => ['int'],
'function_exists' => ['bool', 'function'=>'string'],
'fwrite' => ['int|false', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
'gc_collect_cycles' => ['int'],
'gc_disable' => ['void'],
'gc_enable' => ['void'],
'gc_enabled' => ['bool'],
'gc_mem_caches' => ['int'],
'gc_status' => ['array{runs:int,collected:int,threshold:int,roots:int}'],
'gd_info' => ['array'],
'gearman_bugreport' => [''],
'gearman_client_add_options' => ['', 'client_object'=>'', 'option'=>''],
'gearman_client_add_server' => ['', 'client_object'=>'', 'host'=>'', 'port'=>''],
'gearman_client_add_servers' => ['', 'client_object'=>'', 'servers'=>''],
'gearman_client_add_task' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
'gearman_client_add_task_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
'gearman_client_add_task_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
'gearman_client_add_task_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
'gearman_client_add_task_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
'gearman_client_add_task_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''],
'gearman_client_add_task_status' => ['', 'client_object'=>'', 'job_handle'=>'', 'context'=>''],
'gearman_client_clear_fn' => ['', 'client_object'=>''],
'gearman_client_clone' => ['', 'client_object'=>''],
'gearman_client_context' => ['', 'client_object'=>''],
'gearman_client_create' => ['', 'client_object'=>''],
'gearman_client_do' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
'gearman_client_do_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
'gearman_client_do_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
'gearman_client_do_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
'gearman_client_do_job_handle' => ['', 'client_object'=>''],
'gearman_client_do_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
'gearman_client_do_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''],
'gearman_client_do_normal' => ['', 'client_object'=>'', 'function_name'=>'string', 'workload'=>'string', 'unique'=>'string'],
'gearman_client_do_status' => ['', 'client_object'=>''],
'gearman_client_echo' => ['', 'client_object'=>'', 'workload'=>''],
'gearman_client_errno' => ['', 'client_object'=>''],
'gearman_client_error' => ['', 'client_object'=>''],
'gearman_client_job_status' => ['', 'client_object'=>'', 'job_handle'=>''],
'gearman_client_options' => ['', 'client_object'=>''],
'gearman_client_remove_options' => ['', 'client_object'=>'', 'option'=>''],
'gearman_client_return_code' => ['', 'client_object'=>''],
'gearman_client_run_tasks' => ['', 'data'=>''],
'gearman_client_set_complete_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_set_context' => ['', 'client_object'=>'', 'context'=>''],
'gearman_client_set_created_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_set_data_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_set_exception_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_set_fail_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_set_options' => ['', 'client_object'=>'', 'option'=>''],
'gearman_client_set_status_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_set_timeout' => ['', 'client_object'=>'', 'timeout'=>''],
'gearman_client_set_warning_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_set_workload_fn' => ['', 'client_object'=>'', 'callback'=>''],
'gearman_client_timeout' => ['', 'client_object'=>''],
'gearman_client_wait' => ['', 'client_object'=>''],
'gearman_job_function_name' => ['', 'job_object'=>''],
'gearman_job_handle' => ['string'],
'gearman_job_return_code' => ['', 'job_object'=>''],
'gearman_job_send_complete' => ['', 'job_object'=>'', 'result'=>''],
'gearman_job_send_data' => ['', 'job_object'=>'', 'data'=>''],
'gearman_job_send_exception' => ['', 'job_object'=>'', 'exception'=>''],
'gearman_job_send_fail' => ['', 'job_object'=>''],
'gearman_job_send_status' => ['', 'job_object'=>'', 'numerator'=>'', 'denominator'=>''],
'gearman_job_send_warning' => ['', 'job_object'=>'', 'warning'=>''],
'gearman_job_status' => ['array', 'job_handle'=>'string'],
'gearman_job_unique' => ['', 'job_object'=>''],
'gearman_job_workload' => ['', 'job_object'=>''],
'gearman_job_workload_size' => ['', 'job_object'=>''],
'gearman_task_data' => ['', 'task_object'=>''],
'gearman_task_data_size' => ['', 'task_object'=>''],
'gearman_task_denominator' => ['', 'task_object'=>''],
'gearman_task_function_name' => ['', 'task_object'=>''],
'gearman_task_is_known' => ['', 'task_object'=>''],
'gearman_task_is_running' => ['', 'task_object'=>''],
'gearman_task_job_handle' => ['', 'task_object'=>''],
'gearman_task_numerator' => ['', 'task_object'=>''],
'gearman_task_recv_data' => ['', 'task_object'=>'', 'data_len'=>''],
'gearman_task_return_code' => ['', 'task_object'=>''],
'gearman_task_send_workload' => ['', 'task_object'=>'', 'data'=>''],
'gearman_task_unique' => ['', 'task_object'=>''],
'gearman_verbose_name' => ['', 'verbose'=>''],
'gearman_version' => [''],
'gearman_worker_add_function' => ['', 'worker_object'=>'', 'function_name'=>'', 'function'=>'', 'data'=>'', 'timeout'=>''],
'gearman_worker_add_options' => ['', 'worker_object'=>'', 'option'=>''],
'gearman_worker_add_server' => ['', 'worker_object'=>'', 'host'=>'', 'port'=>''],
'gearman_worker_add_servers' => ['', 'worker_object'=>'', 'servers'=>''],
'gearman_worker_clone' => ['', 'worker_object'=>''],
'gearman_worker_create' => [''],
'gearman_worker_echo' => ['', 'worker_object'=>'', 'workload'=>''],
'gearman_worker_errno' => ['', 'worker_object'=>''],
'gearman_worker_error' => ['', 'worker_object'=>''],
'gearman_worker_grab_job' => ['', 'worker_object'=>''],
'gearman_worker_options' => ['', 'worker_object'=>''],
'gearman_worker_register' => ['', 'worker_object'=>'', 'function_name'=>'', 'timeout'=>''],
'gearman_worker_remove_options' => ['', 'worker_object'=>'', 'option'=>''],
'gearman_worker_return_code' => ['', 'worker_object'=>''],
'gearman_worker_set_options' => ['', 'worker_object'=>'', 'option'=>''],
'gearman_worker_set_timeout' => ['', 'worker_object'=>'', 'timeout'=>''],
'gearman_worker_timeout' => ['', 'worker_object'=>''],
'gearman_worker_unregister' => ['', 'worker_object'=>'', 'function_name'=>''],
'gearman_worker_unregister_all' => ['', 'worker_object'=>''],
'gearman_worker_wait' => ['', 'worker_object'=>''],
'gearman_worker_work' => ['', 'worker_object'=>''],
'GearmanClient::__construct' => ['void'],
'GearmanClient::addOptions' => ['bool', 'options'=>'int'],
'GearmanClient::addServer' => ['bool', 'host='=>'string', 'port='=>'int'],
'GearmanClient::addServers' => ['bool', 'servers='=>'string'],
'GearmanClient::addTask' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
'GearmanClient::addTaskBackground' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
'GearmanClient::addTaskHigh' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
'GearmanClient::addTaskHighBackground' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
'GearmanClient::addTaskLow' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
'GearmanClient::addTaskLowBackground' => ['GearmanTask|false', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'],
'GearmanClient::addTaskStatus' => ['GearmanTask', 'job_handle'=>'string', 'context='=>'string'],
'GearmanClient::clearCallbacks' => ['bool'],
'GearmanClient::clone' => ['GearmanClient'],
'GearmanClient::context' => ['string'],
'GearmanClient::data' => ['string'],
'GearmanClient::do' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
'GearmanClient::doBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
'GearmanClient::doHigh' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
'GearmanClient::doHighBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
'GearmanClient::doJobHandle' => ['string'],
'GearmanClient::doLow' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
'GearmanClient::doLowBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
'GearmanClient::doNormal' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'],
'GearmanClient::doStatus' => ['array'],
'GearmanClient::echo' => ['bool', 'workload'=>'string'],
'GearmanClient::error' => ['string'],
'GearmanClient::getErrno' => ['int'],
'GearmanClient::jobStatus' => ['array', 'job_handle'=>'string'],
'GearmanClient::options' => [''],
'GearmanClient::ping' => ['bool', 'workload'=>'string'],
'GearmanClient::removeOptions' => ['bool', 'options'=>'int'],
'GearmanClient::returnCode' => ['int'],
'GearmanClient::runTasks' => ['bool'],
'GearmanClient::setClientCallback' => ['void', 'callback'=>'callable'],
'GearmanClient::setCompleteCallback' => ['bool', 'callback'=>'callable'],
'GearmanClient::setContext' => ['bool', 'context'=>'string'],
'GearmanClient::setCreatedCallback' => ['bool', 'callback'=>'string'],
'GearmanClient::setData' => ['bool', 'data'=>'string'],
'GearmanClient::setDataCallback' => ['bool', 'callback'=>'callable'],
'GearmanClient::setExceptionCallback' => ['bool', 'callback'=>'callable'],
'GearmanClient::setFailCallback' => ['bool', 'callback'=>'callable'],
'GearmanClient::setOptions' => ['bool', 'options'=>'int'],
'GearmanClient::setStatusCallback' => ['bool', 'callback'=>'callable'],
'GearmanClient::setTimeout' => ['bool', 'timeout'=>'int'],
'GearmanClient::setWarningCallback' => ['bool', 'callback'=>'callable'],
'GearmanClient::setWorkloadCallback' => ['bool', 'callback'=>'callable'],
'GearmanClient::timeout' => ['int'],
'GearmanClient::wait' => [''],
'GearmanJob::__construct' => ['void'],
'GearmanJob::complete' => ['bool', 'result'=>'string'],
'GearmanJob::data' => ['bool', 'data'=>'string'],
'GearmanJob::exception' => ['bool', 'exception'=>'string'],
'GearmanJob::fail' => ['bool'],
'GearmanJob::functionName' => ['string'],
'GearmanJob::handle' => ['string'],
'GearmanJob::returnCode' => ['int'],
'GearmanJob::sendComplete' => ['bool', 'result'=>'string'],
'GearmanJob::sendData' => ['bool', 'data'=>'string'],
'GearmanJob::sendException' => ['bool', 'exception'=>'string'],
'GearmanJob::sendFail' => ['bool'],
'GearmanJob::sendStatus' => ['bool', 'numerator'=>'int', 'denominator'=>'int'],
'GearmanJob::sendWarning' => ['bool', 'warning'=>'string'],
'GearmanJob::setReturn' => ['bool', 'gearman_return_t'=>'string'],
'GearmanJob::status' => ['bool', 'numerator'=>'int', 'denominator'=>'int'],
'GearmanJob::unique' => ['string'],
'GearmanJob::warning' => ['bool', 'warning'=>'string'],
'GearmanJob::workload' => ['string'],
'GearmanJob::workloadSize' => ['int'],
'GearmanTask::__construct' => ['void'],
'GearmanTask::create' => ['GearmanTask'],
'GearmanTask::data' => ['string|false'],
'GearmanTask::dataSize' => ['int|false'],
'GearmanTask::function' => ['string'],
'GearmanTask::functionName' => ['string'],
'GearmanTask::isKnown' => ['bool'],
'GearmanTask::isRunning' => ['bool'],
'GearmanTask::jobHandle' => ['string'],
'GearmanTask::recvData' => ['array|false', 'data_len'=>'int'],
'GearmanTask::returnCode' => ['int'],
'GearmanTask::sendData' => ['int', 'data'=>'string'],
'GearmanTask::sendWorkload' => ['int|false', 'data'=>'string'],
'GearmanTask::taskDenominator' => ['int|false'],
'GearmanTask::taskNumerator' => ['int|false'],
'GearmanTask::unique' => ['string|false'],
'GearmanTask::uuid' => ['string'],
'GearmanWorker::__construct' => ['void'],
'GearmanWorker::addFunction' => ['bool', 'function_name'=>'string', 'function'=>'callable', 'context='=>'mixed', 'timeout='=>'int'],
'GearmanWorker::addOptions' => ['bool', 'option'=>'int'],
'GearmanWorker::addServer' => ['bool', 'host='=>'string', 'port='=>'int'],
'GearmanWorker::addServers' => ['bool', 'servers'=>'string'],
'GearmanWorker::clone' => ['void'],
'GearmanWorker::echo' => ['bool', 'workload'=>'string'],
'GearmanWorker::error' => ['string'],
'GearmanWorker::getErrno' => ['int'],
'GearmanWorker::grabJob' => [''],
'GearmanWorker::options' => ['int'],
'GearmanWorker::register' => ['bool', 'function_name'=>'string', 'timeout='=>'int'],
'GearmanWorker::removeOptions' => ['bool', 'option'=>'int'],
'GearmanWorker::returnCode' => ['int'],
'GearmanWorker::setId' => ['bool', 'id'=>'string'],
'GearmanWorker::setOptions' => ['bool', 'option'=>'int'],
'GearmanWorker::setTimeout' => ['bool', 'timeout'=>'int'],
'GearmanWorker::timeout' => ['int'],
'GearmanWorker::unregister' => ['bool', 'function_name'=>'string'],
'GearmanWorker::unregisterAll' => ['bool'],
'GearmanWorker::wait' => ['bool'],
'GearmanWorker::work' => ['bool'],
'Gender\Gender::__construct' => ['void', 'dsn='=>'string'],
'Gender\Gender::connect' => ['bool', 'dsn'=>'string'],
'Gender\Gender::country' => ['array', 'country'=>'int'],
'Gender\Gender::get' => ['int', 'name'=>'string', 'country='=>'int'],
'Gender\Gender::isNick' => ['array', 'name0'=>'string', 'name1'=>'string', 'country='=>'int'],
'Gender\Gender::similarNames' => ['array', 'name'=>'string', 'country='=>'int'],
'Generator::__wakeup' => ['void'],
'Generator::current' => ['mixed'],
'Generator::getReturn' => ['mixed'],
'Generator::key' => ['mixed'],
'Generator::next' => ['void'],
'Generator::rewind' => ['void'],
'Generator::send' => ['mixed', 'value'=>'mixed'],
'Generator::throw' => ['mixed', 'exception'=>'Exception|Throwable'],
'Generator::valid' => ['bool'],
'geoip_asnum_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_continent_code_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_country_code3_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_country_code_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_country_name_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_database_info' => ['string', 'database='=>'int'],
'geoip_db_avail' => ['bool', 'database'=>'int'],
'geoip_db_filename' => ['string', 'database'=>'int'],
'geoip_db_get_all_info' => ['array'],
'geoip_domain_by_name' => ['string', 'hostname'=>'string'],
'geoip_id_by_name' => ['int', 'hostname'=>'string'],
'geoip_isp_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_netspeedcell_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_org_by_name' => ['string|false', 'hostname'=>'string'],
'geoip_record_by_name' => ['array|false', 'hostname'=>'string'],
'geoip_region_by_name' => ['array|false', 'hostname'=>'string'],
'geoip_region_name_by_code' => ['string|false', 'country_code'=>'string', 'region_code'=>'string'],
'geoip_setup_custom_directory' => ['void', 'path'=>'string'],
'geoip_time_zone_by_country_and_region' => ['string|false', 'country_code'=>'string', 'region_code='=>'string'],
'GEOSGeometry::__toString' => ['string'],
'GEOSGeometry::project' => ['float', 'other'=>'GEOSGeometry', 'normalized'=>'bool'],
'GEOSGeometry::interpolate' => ['GEOSGeometry', 'dist'=>'float', 'normalized'=>'bool'],
'GEOSGeometry::buffer' => ['GEOSGeometry', 'dist'=>'float', 'styleArray='=>'array'],
'GEOSGeometry::offsetCurve' => ['GEOSGeometry', 'dist'=>'float', 'styleArray'=>'array'],
'GEOSGeometry::envelope' => ['GEOSGeometry'],
'GEOSGeometry::intersection' => ['GEOSGeometry', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::convexHull' => ['GEOSGeometry'],
'GEOSGeometry::difference' => ['GEOSGeometry', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::symDifference' => ['GEOSGeometry', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::boundary' => ['GEOSGeometry'],
'GEOSGeometry::union' => ['GEOSGeometry', 'otherGeom='=>'GEOSGeometry'],
'GEOSGeometry::pointOnSurface' => ['GEOSGeometry'],
'GEOSGeometry::centroid' => ['GEOSGeometry'],
'GEOSGeometry::relate' => ['string|bool', 'otherGeom'=>'GEOSGeometry', 'pattern'=>'string'],
'GEOSGeometry::relateBoundaryNodeRule' => ['string', 'otherGeom'=>'GEOSGeometry', 'rule'=>'int'],
'GEOSGeometry::simplify' => ['GEOSGeometry', 'tolerance'=>'float', 'preserveTopology='=>'bool'],
'GEOSGeometry::normalize' => ['GEOSGeometry'],
'GEOSGeometry::extractUniquePoints' => ['GEOSGeometry'],
'GEOSGeometry::disjoint' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::touches' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::intersects' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::crosses' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::within' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::contains' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::overlaps' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::covers' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::coveredBy' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::equals' => ['bool', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::equalsExact' => ['bool', 'geom'=>'GEOSGeometry', 'tolerance'=>'float'],
'GEOSGeometry::isEmpty' => ['bool'],
'GEOSGeometry::checkValidity' => ['array{valid: bool, reason?: string, location?: GEOSGeometry}'],
'GEOSGeometry::isSimple' => ['bool'],
'GEOSGeometry::isRing' => ['bool'],
'GEOSGeometry::hasZ' => ['bool'],
'GEOSGeometry::isClosed' => ['bool'],
'GEOSGeometry::typeName' => ['string'],
'GEOSGeometry::typeId' => ['int'],
'GEOSGeometry::getSRID' => ['int'],
'GEOSGeometry::setSRID' => ['void', 'srid'=>'int'],
'GEOSGeometry::numGeometries' => ['int'],
'GEOSGeometry::geometryN' => ['GEOSGeometry', 'num'=>'int'],
'GEOSGeometry::numInteriorRings' => ['int'],
'GEOSGeometry::numPoints' => ['int'],
'GEOSGeometry::getX' => ['float'],
'GEOSGeometry::getY' => ['float'],
'GEOSGeometry::interiorRingN' => ['GEOSGeometry', 'num'=>'int'],
'GEOSGeometry::exteriorRing' => ['GEOSGeometry'],
'GEOSGeometry::numCoordinates' => ['int'],
'GEOSGeometry::dimension' => ['int'],
'GEOSGeometry::coordinateDimension' => ['int'],
'GEOSGeometry::pointN' => ['GEOSGeometry', 'num'=>'int'],
'GEOSGeometry::startPoint' => ['GEOSGeometry'],
'GEOSGeometry::endPoint' => ['GEOSGeometry'],
'GEOSGeometry::area' => ['float'],
'GEOSGeometry::length' => ['float'],
'GEOSGeometry::distance' => ['float', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::hausdorffDistance' => ['float', 'geom'=>'GEOSGeometry'],
'GEOSGeometry::snapTo' => ['GEOSGeometry', 'geom'=>'GEOSGeometry', 'tolerance'=>'float'],
'GEOSGeometry::node' => ['GEOSGeometry'],
'GEOSGeometry::delaunayTriangulation' => ['GEOSGeometry', 'tolerance'=>'float', 'onlyEdges'=>'bool'],
'GEOSGeometry::voronoiDiagram' => ['GEOSGeometry', 'tolerance'=>'float', 'onlyEdges'=>'bool', 'extent'=>'GEOSGeometry|null'],
'GEOSLineMerge' => ['array', 'geom'=>'GEOSGeometry'],
'GEOSPolygonize' => ['array{rings: GEOSGeometry[], cut_edges?: GEOSGeometry[], dangles: GEOSGeometry[], invalid_rings: GEOSGeometry[]}', 'geom'=>'GEOSGeometry'],
'GEOSRelateMatch' => ['bool', 'matrix'=>'string', 'pattern'=>'string'],
'GEOSSharedPaths' => ['GEOSGeometry', 'geom1'=>'GEOSGeometry', 'geom2'=>'GEOSGeometry'],
'GEOSVersion' => ['string'],
'GEOSWKBReader::__construct' => ['void'],
'GEOSWKBReader::read' => ['GEOSGeometry', 'wkb'=>'string'],
'GEOSWKBReader::readHEX' => ['GEOSGeometry', 'wkb'=>'string'],
'GEOSWKBWriter::__construct' => ['void'],
'GEOSWKBWriter::getOutputDimension' => ['int'],
'GEOSWKBWriter::setOutputDimension' => ['void', 'dim'=>'int'],
'GEOSWKBWriter::getByteOrder' => ['int'],
'GEOSWKBWriter::setByteOrder' => ['void', 'byteOrder'=>'int'],
'GEOSWKBWriter::getIncludeSRID' => ['bool'],
'GEOSWKBWriter::setIncludeSRID' => ['void', 'inc'=>'bool'],
'GEOSWKBWriter::write' => ['string', 'geom'=>'GEOSGeometry'],
'GEOSWKBWriter::writeHEX' => ['string', 'geom'=>'GEOSGeometry'],
'GEOSWKTReader::__construct' => ['void'],
'GEOSWKTReader::read' => ['GEOSGeometry', 'wkt'=>'string'],
'GEOSWKTWriter::__construct' => ['void'],
'GEOSWKTWriter::write' => ['string', 'geom'=>'GEOSGeometry'],
'GEOSWKTWriter::setTrim' => ['void', 'trim'=>'bool'],
'GEOSWKTWriter::setRoundingPrecision' => ['void', 'prec'=>'int'],
'GEOSWKTWriter::setOutputDimension' => ['void', 'dim'=>'int'],
'GEOSWKTWriter::getOutputDimension' => ['int'],
'GEOSWKTWriter::setOld3D' => ['void', 'val'=>'bool'],
'get_browser' => ['array|object|false', 'user_agent='=>'?string', 'return_array='=>'bool'],
'get_call_stack' => [''],
'get_called_class' => ['class-string'],
'get_cfg_var' => ['string|false', 'option'=>'string'],
'get_class' => ['class-string', 'object='=>'object'],
'get_class_methods' => ['list<string>', 'object_or_class'=>'object|class-string'],
'get_class_vars' => ['array<string,mixed>', 'class'=>'string'],
'get_current_user' => ['string'],
'get_debug_type' => ['string', 'value'=>'mixed'],
'get_declared_classes' => ['list<class-string>'],
'get_declared_interfaces' => ['list<class-string>'],
'get_declared_traits' => ['list<class-string>'],
'get_defined_constants' => ['array<string,int|string|float|bool|null|array|resource>', 'categorize='=>'bool'],
'get_defined_functions' => ['array{internal: list<callable-string>, user: list<callable-string>}', 'exclude_disabled='=>'bool'],
'get_defined_vars' => ['array'],
'get_extension_funcs' => ['list<callable-string>|false', 'extension'=>'string'],
'get_headers' => ['array|false', 'url'=>'string', 'associative='=>'bool', 'context='=>'?resource'],
'get_html_translation_table' => ['array', 'table='=>'int', 'flags='=>'int', 'encoding='=>'string'],
'get_include_path' => ['string'],
'get_included_files' => ['list<string>'],
'get_loaded_extensions' => ['list<string>', 'zend_extensions='=>'bool'],
'get_magic_quotes_gpc' => ['int|false'],
'get_magic_quotes_runtime' => ['int|false'],
'get_meta_tags' => ['array', 'filename'=>'string', 'use_include_path='=>'bool'],
'get_object_vars' => ['array<string,mixed>', 'object'=>'object'],
'get_parent_class' => ['class-string|false', 'object_or_class='=>'object|class-string'],
'get_required_files' => ['list<string>'],
'get_resource_id' => ['int', 'resource'=>'resource'],
'get_resource_type' => ['string', 'resource'=>'resource'],
'get_resources' => ['array<int,resource>', 'type='=>'?string'],
'getallheaders' => ['array|false'],
'getcwd' => ['string|false'],
'getdate' => ['array{seconds: int<0, 59>, minutes: int<0, 59>, hours: int<0, 23>, mday: int<1, 31>, wday: int<0, 6>, mon: int<1, 12>, year: int, yday: int<0, 365>, weekday: "Monday"|"Tuesday"|"Wednesday"|"Thursday"|"Friday"|"Saturday"|"Sunday", month: "January"|"February"|"March"|"April"|"May"|"June"|"July"|"August"|"September"|"October"|"November"|"December", 0: int}', 'timestamp='=>'?int'],
'getenv' => ['string|false', 'name'=>'string', 'local_only='=>'bool'],
'getenv\'1' => ['array<string,string>'],
'gethostbyaddr' => ['string|false', 'ip'=>'string'],
'gethostbyname' => ['string', 'hostname'=>'string'],
'gethostbynamel' => ['list<string>|false', 'hostname'=>'string'],
'gethostname' => ['string|false'],
'getimagesize' => ['array|false', 'filename'=>'string', '&w_image_info='=>'array'],
'getimagesizefromstring' => ['array|false', 'string'=>'string', '&w_image_info='=>'array'],
'getlastmod' => ['int|false'],
'getmxrr' => ['bool', 'hostname'=>'string', '&w_hosts'=>'array', '&w_weights='=>'array'],
'getmygid' => ['int|false'],
'getmyinode' => ['int|false'],
'getmypid' => ['int|false'],
'getmyuid' => ['int|false'],
'getopt' => ['array<string,string|false|list<string|false>>|false', 'short_options'=>'string', 'long_options='=>'array', '&w_rest_index='=>'int'],
'getprotobyname' => ['int|false', 'protocol'=>'string'],
'getprotobynumber' => ['string', 'protocol'=>'int'],
'getrandmax' => ['int'],
'getrusage' => ['array', 'mode='=>'int'],
'getservbyname' => ['int|false', 'service'=>'string', 'protocol'=>'string'],
'getservbyport' => ['string|false', 'port'=>'int', 'protocol'=>'string'],
'gettext' => ['string', 'message'=>'string'],
'gettimeofday' => ['array<string, int>'],
'gettimeofday\'1' => ['float', 'as_float='=>'true'],
'gettype' => ['string', 'value'=>'mixed'],
'glob' => ['list<string>|false', 'pattern'=>'string', 'flags='=>'int'],
'GlobIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'],
'GlobIterator::count' => ['int'],
'GlobIterator::current' => ['FilesystemIterator|SplFileInfo|string'],
'GlobIterator::getATime' => ['int'],
'GlobIterator::getBasename' => ['string', 'suffix='=>'string'],
'GlobIterator::getCTime' => ['int'],
'GlobIterator::getExtension' => ['string'],
'GlobIterator::getFileInfo' => ['SplFileInfo'],
'GlobIterator::getFilename' => ['string'],
'GlobIterator::getFlags' => ['int'],
'GlobIterator::getGroup' => ['int'],
'GlobIterator::getInode' => ['int'],
'GlobIterator::getLinkTarget' => ['string|false'],
'GlobIterator::getMTime' => ['int'],
'GlobIterator::getOwner' => ['int'],
'GlobIterator::getPath' => ['string'],
'GlobIterator::getPathInfo' => ['?SplFileInfo'],
'GlobIterator::getPathname' => ['string'],
'GlobIterator::getPerms' => ['int'],
'GlobIterator::getRealPath' => ['string|false'],
'GlobIterator::getSize' => ['int'],
'GlobIterator::getType' => ['string|false'],
'GlobIterator::isDir' => ['bool'],
'GlobIterator::isDot' => ['bool'],
'GlobIterator::isExecutable' => ['bool'],
'GlobIterator::isFile' => ['bool'],
'GlobIterator::isLink' => ['bool'],
'GlobIterator::isReadable' => ['bool'],
'GlobIterator::isWritable' => ['bool'],
'GlobIterator::key' => ['string'],
'GlobIterator::next' => ['void'],
'GlobIterator::openFile' => ['SplFileObject'],
'GlobIterator::rewind' => ['void'],
'GlobIterator::seek' => ['void', 'position'=>'int'],
'GlobIterator::setFileClass' => ['void'],
'GlobIterator::setFlags' => ['void', 'flags='=>'int'],
'GlobIterator::setInfoClass' => ['void'],
'GlobIterator::valid' => ['bool'],
'Gmagick::__construct' => ['void', 'filename='=>'string'],
'Gmagick::addimage' => ['Gmagick', 'gmagick'=>'gmagick'],
'Gmagick::addnoiseimage' => ['Gmagick', 'noise'=>'int'],
'Gmagick::annotateimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'],
'Gmagick::blurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
'Gmagick::borderimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int'],
'Gmagick::charcoalimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'],
'Gmagick::chopimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Gmagick::clear' => ['Gmagick'],
'Gmagick::commentimage' => ['Gmagick', 'comment'=>'string'],
'Gmagick::compositeimage' => ['Gmagick', 'source'=>'gmagick', 'compose'=>'int', 'x'=>'int', 'y'=>'int'],
'Gmagick::cropimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Gmagick::cropthumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int'],
'Gmagick::current' => ['Gmagick'],
'Gmagick::cyclecolormapimage' => ['Gmagick', 'displace'=>'int'],
'Gmagick::deconstructimages' => ['Gmagick'],
'Gmagick::despeckleimage' => ['Gmagick'],
'Gmagick::destroy' => ['bool'],
'Gmagick::drawimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw'],
'Gmagick::edgeimage' => ['Gmagick', 'radius'=>'float'],
'Gmagick::embossimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'],
'Gmagick::enhanceimage' => ['Gmagick'],
'Gmagick::equalizeimage' => ['Gmagick'],
'Gmagick::flipimage' => ['Gmagick'],
'Gmagick::flopimage' => ['Gmagick'],
'Gmagick::frameimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'],
'Gmagick::gammaimage' => ['Gmagick', 'gamma'=>'float'],
'Gmagick::getcopyright' => ['string'],
'Gmagick::getfilename' => ['string'],
'Gmagick::getimagebackgroundcolor' => ['GmagickPixel'],
'Gmagick::getimageblueprimary' => ['array'],
'Gmagick::getimagebordercolor' => ['GmagickPixel'],
'Gmagick::getimagechanneldepth' => ['int', 'channel_type'=>'int'],
'Gmagick::getimagecolors' => ['int'],
'Gmagick::getimagecolorspace' => ['int'],
'Gmagick::getimagecompose' => ['int'],
'Gmagick::getimagedelay' => ['int'],
'Gmagick::getimagedepth' => ['int'],
'Gmagick::getimagedispose' => ['int'],
'Gmagick::getimageextrema' => ['array'],
'Gmagick::getimagefilename' => ['string'],
'Gmagick::getimageformat' => ['string'],
'Gmagick::getimagegamma' => ['float'],
'Gmagick::getimagegreenprimary' => ['array'],
'Gmagick::getimageheight' => ['int'],
'Gmagick::getimagehistogram' => ['array'],
'Gmagick::getimageindex' => ['int'],
'Gmagick::getimageinterlacescheme' => ['int'],
'Gmagick::getimageiterations' => ['int'],
'Gmagick::getimagematte' => ['int'],
'Gmagick::getimagemattecolor' => ['GmagickPixel'],
'Gmagick::getimageprofile' => ['string', 'name'=>'string'],
'Gmagick::getimageredprimary' => ['array'],
'Gmagick::getimagerenderingintent' => ['int'],
'Gmagick::getimageresolution' => ['array'],
'Gmagick::getimagescene' => ['int'],
'Gmagick::getimagesignature' => ['string'],
'Gmagick::getimagetype' => ['int'],
'Gmagick::getimageunits' => ['int'],
'Gmagick::getimagewhitepoint' => ['array'],
'Gmagick::getimagewidth' => ['int'],
'Gmagick::getpackagename' => ['string'],
'Gmagick::getquantumdepth' => ['array'],
'Gmagick::getreleasedate' => ['string'],
'Gmagick::getsamplingfactors' => ['array'],
'Gmagick::getsize' => ['array'],
'Gmagick::getversion' => ['array'],
'Gmagick::hasnextimage' => ['bool'],
'Gmagick::haspreviousimage' => ['bool'],
'Gmagick::implodeimage' => ['mixed', 'radius'=>'float'],
'Gmagick::labelimage' => ['mixed', 'label'=>'string'],
'Gmagick::levelimage' => ['mixed', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'],
'Gmagick::magnifyimage' => ['mixed'],
'Gmagick::mapimage' => ['Gmagick', 'gmagick'=>'gmagick', 'dither'=>'bool'],
'Gmagick::medianfilterimage' => ['void', 'radius'=>'float'],
'Gmagick::minifyimage' => ['Gmagick'],
'Gmagick::modulateimage' => ['Gmagick', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'],
'Gmagick::motionblurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'],
'Gmagick::newimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'background'=>'string', 'format='=>'string'],
'Gmagick::nextimage' => ['bool'],
'Gmagick::normalizeimage' => ['Gmagick', 'channel='=>'int'],
'Gmagick::oilpaintimage' => ['Gmagick', 'radius'=>'float'],
'Gmagick::previousimage' => ['bool'],
'Gmagick::profileimage' => ['Gmagick', 'name'=>'string', 'profile'=>'string'],
'Gmagick::quantizeimage' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
'Gmagick::quantizeimages' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
'Gmagick::queryfontmetrics' => ['array', 'draw'=>'gmagickdraw', 'text'=>'string'],
'Gmagick::queryfonts' => ['array', 'pattern='=>'string'],
'Gmagick::queryformats' => ['array', 'pattern='=>'string'],
'Gmagick::radialblurimage' => ['Gmagick', 'angle'=>'float', 'channel='=>'int'],
'Gmagick::raiseimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'],
'Gmagick::read' => ['Gmagick', 'filename'=>'string'],
'Gmagick::readimage' => ['Gmagick', 'filename'=>'string'],
'Gmagick::readimageblob' => ['Gmagick', 'imagecontents'=>'string', 'filename='=>'string'],
'Gmagick::readimagefile' => ['Gmagick', 'fp'=>'resource', 'filename='=>'string'],
'Gmagick::reducenoiseimage' => ['Gmagick', 'radius'=>'float'],
'Gmagick::removeimage' => ['Gmagick'],
'Gmagick::removeimageprofile' => ['string', 'name'=>'string'],
'Gmagick::resampleimage' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float', 'filter'=>'int', 'blur'=>'float'],
'Gmagick::resizeimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'filter'=>'int', 'blur'=>'float', 'fit='=>'bool'],
'Gmagick::rollimage' => ['Gmagick', 'x'=>'int', 'y'=>'int'],
'Gmagick::rotateimage' => ['Gmagick', 'color'=>'mixed', 'degrees'=>'float'],
'Gmagick::scaleimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'],
'Gmagick::separateimagechannel' => ['Gmagick', 'channel'=>'int'],
'Gmagick::setCompressionQuality' => ['Gmagick', 'quality'=>'int'],
'Gmagick::setfilename' => ['Gmagick', 'filename'=>'string'],
'Gmagick::setimagebackgroundcolor' => ['Gmagick', 'color'=>'gmagickpixel'],
'Gmagick::setimageblueprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
'Gmagick::setimagebordercolor' => ['Gmagick', 'color'=>'gmagickpixel'],
'Gmagick::setimagechanneldepth' => ['Gmagick', 'channel'=>'int', 'depth'=>'int'],
'Gmagick::setimagecolorspace' => ['Gmagick', 'colorspace'=>'int'],
'Gmagick::setimagecompose' => ['Gmagick', 'composite'=>'int'],
'Gmagick::setimagedelay' => ['Gmagick', 'delay'=>'int'],
'Gmagick::setimagedepth' => ['Gmagick', 'depth'=>'int'],
'Gmagick::setimagedispose' => ['Gmagick', 'disposetype'=>'int'],
'Gmagick::setimagefilename' => ['Gmagick', 'filename'=>'string'],
'Gmagick::setimageformat' => ['Gmagick', 'imageformat'=>'string'],
'Gmagick::setimagegamma' => ['Gmagick', 'gamma'=>'float'],
'Gmagick::setimagegreenprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
'Gmagick::setimageindex' => ['Gmagick', 'index'=>'int'],
'Gmagick::setimageinterlacescheme' => ['Gmagick', 'interlace'=>'int'],
'Gmagick::setimageiterations' => ['Gmagick', 'iterations'=>'int'],
'Gmagick::setimageprofile' => ['Gmagick', 'name'=>'string', 'profile'=>'string'],
'Gmagick::setimageredprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
'Gmagick::setimagerenderingintent' => ['Gmagick', 'rendering_intent'=>'int'],
'Gmagick::setimageresolution' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float'],
'Gmagick::setimagescene' => ['Gmagick', 'scene'=>'int'],
'Gmagick::setimagetype' => ['Gmagick', 'imgtype'=>'int'],
'Gmagick::setimageunits' => ['Gmagick', 'resolution'=>'int'],
'Gmagick::setimagewhitepoint' => ['Gmagick', 'x'=>'float', 'y'=>'float'],
'Gmagick::setsamplingfactors' => ['Gmagick', 'factors'=>'array'],
'Gmagick::setsize' => ['Gmagick', 'columns'=>'int', 'rows'=>'int'],
'Gmagick::shearimage' => ['Gmagick', 'color'=>'mixed', 'xshear'=>'float', 'yshear'=>'float'],
'Gmagick::solarizeimage' => ['Gmagick', 'threshold'=>'int'],
'Gmagick::spreadimage' => ['Gmagick', 'radius'=>'float'],
'Gmagick::stripimage' => ['Gmagick'],
'Gmagick::swirlimage' => ['Gmagick', 'degrees'=>'float'],
'Gmagick::thumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'],
'Gmagick::trimimage' => ['Gmagick', 'fuzz'=>'float'],
'Gmagick::write' => ['Gmagick', 'filename'=>'string'],
'Gmagick::writeimage' => ['Gmagick', 'filename'=>'string', 'all_frames='=>'bool'],
'GmagickDraw::annotate' => ['GmagickDraw', 'x'=>'float', 'y'=>'float', 'text'=>'string'],
'GmagickDraw::arc' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'],
'GmagickDraw::bezier' => ['GmagickDraw', 'coordinate_array'=>'array'],
'GmagickDraw::ellipse' => ['GmagickDraw', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'],
'GmagickDraw::getfillcolor' => ['GmagickPixel'],
'GmagickDraw::getfillopacity' => ['float'],
'GmagickDraw::getfont' => ['string|false'],
'GmagickDraw::getfontsize' => ['float'],
'GmagickDraw::getfontstyle' => ['int'],
'GmagickDraw::getfontweight' => ['int'],
'GmagickDraw::getstrokecolor' => ['GmagickPixel'],
'GmagickDraw::getstrokeopacity' => ['float'],
'GmagickDraw::getstrokewidth' => ['float'],
'GmagickDraw::gettextdecoration' => ['int'],
'GmagickDraw::gettextencoding' => ['string|false'],
'GmagickDraw::line' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'],
'GmagickDraw::point' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'],
'GmagickDraw::polygon' => ['GmagickDraw', 'coordinates'=>'array'],
'GmagickDraw::polyline' => ['GmagickDraw', 'coordinate_array'=>'array'],
'GmagickDraw::rectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'],
'GmagickDraw::rotate' => ['GmagickDraw', 'degrees'=>'float'],
'GmagickDraw::roundrectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'],
'GmagickDraw::scale' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'],
'GmagickDraw::setfillcolor' => ['GmagickDraw', 'color'=>'string'],
'GmagickDraw::setfillopacity' => ['GmagickDraw', 'fill_opacity'=>'float'],
'GmagickDraw::setfont' => ['GmagickDraw', 'font'=>'string'],
'GmagickDraw::setfontsize' => ['GmagickDraw', 'pointsize'=>'float'],
'GmagickDraw::setfontstyle' => ['GmagickDraw', 'style'=>'int'],
'GmagickDraw::setfontweight' => ['GmagickDraw', 'weight'=>'int'],
'GmagickDraw::setstrokecolor' => ['GmagickDraw', 'color'=>'gmagickpixel'],
'GmagickDraw::setstrokeopacity' => ['GmagickDraw', 'stroke_opacity'=>'float'],
'GmagickDraw::setstrokewidth' => ['GmagickDraw', 'width'=>'float'],
'GmagickDraw::settextdecoration' => ['GmagickDraw', 'decoration'=>'int'],
'GmagickDraw::settextencoding' => ['GmagickDraw', 'encoding'=>'string'],
'GmagickPixel::__construct' => ['void', 'color='=>'string'],
'GmagickPixel::getcolor' => ['mixed', 'as_array='=>'bool', 'normalize_array='=>'bool'],
'GmagickPixel::getcolorcount' => ['int'],
'GmagickPixel::getcolorvalue' => ['float', 'color'=>'int'],
'GmagickPixel::setcolor' => ['GmagickPixel', 'color'=>'string'],
'GmagickPixel::setcolorvalue' => ['GmagickPixel', 'color'=>'int', 'value'=>'float'],
'gmdate' => ['string', 'format'=>'string', 'timestamp='=>'int|null'],
'gmmktime' => ['int|false', 'hour'=>'int', 'minute='=>'int|null', 'second='=>'int|null', 'month='=>'int|null', 'day='=>'int|null', 'year='=>'int|null'],
'GMP::__construct' => ['void'],
'GMP::__serialize' => ['array'],
'GMP::__toString' => ['numeric-string'],
'GMP::__unserialize' => ['void', 'data'=>'array'],
'gmp_abs' => ['GMP', 'num'=>'GMP|string|int'],
'gmp_add' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_and' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_binomial' => ['GMP', 'n'=>'GMP|string|int', 'k'=>'int'],
'gmp_clrbit' => ['void', 'num'=>'GMP|string|int', 'index'=>'int'],
'gmp_cmp' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_com' => ['GMP', 'num'=>'GMP|string|int'],
'gmp_div' => ['GMP', 'num1'=>'GMP|resource|string', 'num2'=>'GMP|resource|string', 'rounding_mode='=>'int'],
'gmp_div_q' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int', 'rounding_mode='=>'int'],
'gmp_div_qr' => ['array{0: GMP, 1: GMP}', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int', 'rounding_mode='=>'int'],
'gmp_div_r' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int', 'rounding_mode='=>'int'],
'gmp_divexact' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_export' => ['string', 'num'=>'GMP|string|int', 'word_size='=>'int', 'flags='=>'int'],
'gmp_fact' => ['GMP', 'num'=>'int'],
'gmp_gcd' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_gcdext' => ['array<string,GMP>', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_hamdist' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_import' => ['GMP', 'data'=>'string', 'word_size='=>'int', 'flags='=>'int'],
'gmp_init' => ['GMP', 'num'=>'int|string', 'base='=>'int'],
'gmp_intval' => ['int', 'num'=>'GMP|string|int'],
'gmp_invert' => ['GMP|false', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_jacobi' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_kronecker' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_lcm' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_legendre' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_mod' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_mul' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_neg' => ['GMP', 'num'=>'GMP|string|int'],
'gmp_nextprime' => ['GMP', 'num'=>'GMP|string|int'],
'gmp_or' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_perfect_power' => ['bool', 'num'=>'GMP|string|int'],
'gmp_perfect_square' => ['bool', 'num'=>'GMP|string|int'],
'gmp_popcount' => ['int', 'num'=>'GMP|string|int'],
'gmp_pow' => ['GMP', 'num'=>'GMP|string|int', 'exponent'=>'int'],
'gmp_powm' => ['GMP', 'num'=>'GMP|string|int', 'exponent'=>'GMP|string|int', 'modulus'=>'GMP|string|int'],
'gmp_prob_prime' => ['int', 'num'=>'GMP|string|int', 'repetitions='=>'int'],
'gmp_random_bits' => ['GMP', 'bits'=>'int'],
'gmp_random_range' => ['GMP', 'min'=>'GMP|string|int', 'max'=>'GMP|string|int'],
'gmp_random_seed' => ['void', 'seed'=>'GMP|string|int'],
'gmp_root' => ['GMP', 'num'=>'GMP|string|int', 'nth'=>'int'],
'gmp_rootrem' => ['array{0: GMP, 1: GMP}', 'num'=>'GMP|string|int', 'nth'=>'int'],
'gmp_scan0' => ['int', 'num1'=>'GMP|string|int', 'start'=>'int'],
'gmp_scan1' => ['int', 'num1'=>'GMP|string|int', 'start'=>'int'],
'gmp_setbit' => ['void', 'num'=>'GMP|string|int', 'index'=>'int', 'value='=>'bool'],
'gmp_sign' => ['int', 'num'=>'GMP|string|int'],
'gmp_sqrt' => ['GMP', 'num'=>'GMP|string|int'],
'gmp_sqrtrem' => ['array{0: GMP, 1: GMP}', 'num'=>'GMP|string|int'],
'gmp_strval' => ['numeric-string', 'num'=>'GMP|string|int', 'base='=>'int'],
'gmp_sub' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmp_testbit' => ['bool', 'num'=>'GMP|string|int', 'index'=>'int'],
'gmp_xor' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
'gmstrftime' => ['string|false', 'format'=>'string', 'timestamp='=>'?int'],
'gnupg::adddecryptkey' => ['bool', 'fingerprint'=>'string', 'passphrase'=>'string'],
'gnupg::addencryptkey' => ['bool', 'fingerprint'=>'string'],
'gnupg::addsignkey' => ['bool', 'fingerprint'=>'string', 'passphrase='=>'string'],
'gnupg::cleardecryptkeys' => ['bool'],
'gnupg::clearencryptkeys' => ['bool'],
'gnupg::clearsignkeys' => ['bool'],
'gnupg::decrypt' => ['string|false', 'text'=>'string'],
'gnupg::decryptverify' => ['array|false', 'text'=>'string', '&plaintext'=>'string'],
'gnupg::encrypt' => ['string|false', 'plaintext'=>'string'],
'gnupg::encryptsign' => ['string|false', 'plaintext'=>'string'],
'gnupg::export' => ['string|false', 'fingerprint'=>'string'],
'gnupg::geterror' => ['string|false'],
'gnupg::getprotocol' => ['int'],
'gnupg::import' => ['array|false', 'keydata'=>'string'],
'gnupg::keyinfo' => ['array', 'pattern'=>'string'],
'gnupg::setarmor' => ['bool', 'armor'=>'int'],
'gnupg::seterrormode' => ['void', 'errormode'=>'int'],
'gnupg::setsignmode' => ['bool', 'signmode'=>'int'],
'gnupg::sign' => ['string|false', 'plaintext'=>'string'],
'gnupg::verify' => ['array|false', 'signed_text'=>'string', 'signature'=>'string', '&plaintext='=>'string'],
'gnupg_adddecryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase'=>'string'],
'gnupg_addencryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string'],
'gnupg_addsignkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase='=>'string'],
'gnupg_cleardecryptkeys' => ['bool', 'identifier'=>'resource'],
'gnupg_clearencryptkeys' => ['bool', 'identifier'=>'resource'],
'gnupg_clearsignkeys' => ['bool', 'identifier'=>'resource'],
'gnupg_decrypt' => ['string', 'identifier'=>'resource', 'text'=>'string'],
'gnupg_decryptverify' => ['array', 'identifier'=>'resource', 'text'=>'string', 'plaintext'=>'string'],
'gnupg_encrypt' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'],
'gnupg_encryptsign' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'],
'gnupg_export' => ['string', 'identifier'=>'resource', 'fingerprint'=>'string'],
'gnupg_geterror' => ['string', 'identifier'=>'resource'],
'gnupg_getprotocol' => ['int', 'identifier'=>'resource'],
'gnupg_import' => ['array', 'identifier'=>'resource', 'keydata'=>'string'],
'gnupg_init' => ['resource'],
'gnupg_keyinfo' => ['array', 'identifier'=>'resource', 'pattern'=>'string'],
'gnupg_setarmor' => ['bool', 'identifier'=>'resource', 'armor'=>'int'],
'gnupg_seterrormode' => ['void', 'identifier'=>'resource', 'errormode'=>'int'],
'gnupg_setsignmode' => ['bool', 'identifier'=>'resource', 'signmode'=>'int'],
'gnupg_sign' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'],
'gnupg_verify' => ['array', 'identifier'=>'resource', 'signed_text'=>'string', 'signature'=>'string', 'plaintext='=>'string'],
'gopher_parsedir' => ['array', 'dirent'=>'string'],
'grapheme_extract' => ['string|false', 'haystack'=>'string', 'size'=>'int', 'type='=>'int', 'offset='=>'int', '&w_next='=>'int'],
'grapheme_stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'grapheme_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'beforeNeedle='=>'bool'],
'grapheme_strlen' => ['0|positive-int|false|null', 'string'=>'string'],
'grapheme_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'grapheme_strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'grapheme_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'grapheme_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'beforeNeedle='=>'bool'],
'grapheme_substr' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'?int'],
'gregoriantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
'gridObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'Grpc\Call::__construct' => ['void', 'channel'=>'Grpc\Channel', 'method'=>'string', 'absolute_deadline'=>'Grpc\Timeval', 'host_override='=>'mixed'],
'Grpc\Call::cancel' => [''],
'Grpc\Call::getPeer' => ['string'],
'Grpc\Call::setCredentials' => ['int', 'creds_obj'=>'Grpc\CallCredentials'],
'Grpc\Call::startBatch' => ['object', 'batch'=>'array'],
'Grpc\CallCredentials::createComposite' => ['Grpc\CallCredentials', 'cred1'=>'Grpc\CallCredentials', 'cred2'=>'Grpc\CallCredentials'],
'Grpc\CallCredentials::createFromPlugin' => ['Grpc\CallCredentials', 'callback'=>'Closure'],
'Grpc\Channel::__construct' => ['void', 'target'=>'string', 'args='=>'array'],
'Grpc\Channel::close' => [''],
'Grpc\Channel::getConnectivityState' => ['int', 'try_to_connect='=>'bool'],
'Grpc\Channel::getTarget' => ['string'],
'Grpc\Channel::watchConnectivityState' => ['bool', 'last_state'=>'int', 'deadline_obj'=>'Grpc\Timeval'],
'Grpc\ChannelCredentials::createComposite' => ['Grpc\ChannelCredentials', 'cred1'=>'Grpc\ChannelCredentials', 'cred2'=>'Grpc\CallCredentials'],
'Grpc\ChannelCredentials::createDefault' => ['Grpc\ChannelCredentials'],
'Grpc\ChannelCredentials::createInsecure' => ['null'],
'Grpc\ChannelCredentials::createSsl' => ['Grpc\ChannelCredentials', 'pem_root_certs'=>'string', 'pem_private_key='=>'string', 'pem_cert_chain='=>'string'],
'Grpc\ChannelCredentials::setDefaultRootsPem' => ['', 'pem_roots'=>'string'],
'Grpc\Server::__construct' => ['void', 'args'=>'array'],
'Grpc\Server::addHttp2Port' => ['bool', 'addr'=>'string'],
'Grpc\Server::addSecureHttp2Port' => ['bool', 'addr'=>'string', 'creds_obj'=>'Grpc\ServerCredentials'],
'Grpc\Server::requestCall' => ['', 'tag_new'=>'int', 'tag_cancel'=>'int'],
'Grpc\Server::start' => [''],
'Grpc\ServerCredentials::createSsl' => ['object', 'pem_root_certs'=>'string', 'pem_private_key'=>'string', 'pem_cert_chain'=>'string'],
'Grpc\Timeval::__construct' => ['void', 'usec'=>'int'],
'Grpc\Timeval::add' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'],
'Grpc\Timeval::compare' => ['int', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval'],
'Grpc\Timeval::infFuture' => ['Grpc\Timeval'],
'Grpc\Timeval::infPast' => ['Grpc\Timeval'],
'Grpc\Timeval::now' => ['Grpc\Timeval'],
'Grpc\Timeval::similar' => ['bool', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval', 'threshold'=>'Grpc\Timeval'],
'Grpc\Timeval::sleepUntil' => [''],
'Grpc\Timeval::subtract' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'],
'Grpc\Timeval::zero' => ['Grpc\Timeval'],
'gupnp_context_get_host_ip' => ['string', 'context'=>'resource'],
'gupnp_context_get_port' => ['int', 'context'=>'resource'],
'gupnp_context_get_subscription_timeout' => ['int', 'context'=>'resource'],
'gupnp_context_host_path' => ['bool', 'context'=>'resource', 'local_path'=>'string', 'server_path'=>'string'],
'gupnp_context_new' => ['resource', 'host_ip='=>'string', 'port='=>'int'],
'gupnp_context_set_subscription_timeout' => ['void', 'context'=>'resource', 'timeout'=>'int'],
'gupnp_context_timeout_add' => ['bool', 'context'=>'resource', 'timeout'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
'gupnp_context_unhost_path' => ['bool', 'context'=>'resource', 'server_path'=>'string'],
'gupnp_control_point_browse_start' => ['bool', 'cpoint'=>'resource'],
'gupnp_control_point_browse_stop' => ['bool', 'cpoint'=>'resource'],
'gupnp_control_point_callback_set' => ['bool', 'cpoint'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
'gupnp_control_point_new' => ['resource', 'context'=>'resource', 'target'=>'string'],
'gupnp_device_action_callback_set' => ['bool', 'root_device'=>'resource', 'signal'=>'int', 'action_name'=>'string', 'callback'=>'mixed', 'arg='=>'mixed'],
'gupnp_device_info_get' => ['array', 'root_device'=>'resource'],
'gupnp_device_info_get_service' => ['resource', 'root_device'=>'resource', 'type'=>'string'],
'gupnp_root_device_get_available' => ['bool', 'root_device'=>'resource'],
'gupnp_root_device_get_relative_location' => ['string', 'root_device'=>'resource'],
'gupnp_root_device_new' => ['resource', 'context'=>'resource', 'location'=>'string', 'description_dir'=>'string'],
'gupnp_root_device_set_available' => ['bool', 'root_device'=>'resource', 'available'=>'bool'],
'gupnp_root_device_start' => ['bool', 'root_device'=>'resource'],
'gupnp_root_device_stop' => ['bool', 'root_device'=>'resource'],
'gupnp_service_action_get' => ['mixed', 'action'=>'resource', 'name'=>'string', 'type'=>'int'],
'gupnp_service_action_return' => ['bool', 'action'=>'resource'],
'gupnp_service_action_return_error' => ['bool', 'action'=>'resource', 'error_code'=>'int', 'error_description='=>'string'],
'gupnp_service_action_set' => ['bool', 'action'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'],
'gupnp_service_freeze_notify' => ['bool', 'service'=>'resource'],
'gupnp_service_info_get' => ['array', 'proxy'=>'resource'],
'gupnp_service_info_get_introspection' => ['mixed', 'proxy'=>'resource', 'callback='=>'mixed', 'arg='=>'mixed'],
'gupnp_service_introspection_get_state_variable' => ['array', 'introspection'=>'resource', 'variable_name'=>'string'],
'gupnp_service_notify' => ['bool', 'service'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'],
'gupnp_service_proxy_action_get' => ['mixed', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'type'=>'int'],
'gupnp_service_proxy_action_set' => ['bool', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'value'=>'mixed', 'type'=>'int'],
'gupnp_service_proxy_add_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string', 'type'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
'gupnp_service_proxy_callback_set' => ['bool', 'proxy'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'],
'gupnp_service_proxy_get_subscribed' => ['bool', 'proxy'=>'resource'],
'gupnp_service_proxy_remove_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string'],
'gupnp_service_proxy_send_action' => ['array', 'proxy'=>'resource', 'action'=>'string', 'in_params'=>'array', 'out_params'=>'array'],
'gupnp_service_proxy_set_subscribed' => ['bool', 'proxy'=>'resource', 'subscribed'=>'bool'],
'gupnp_service_thaw_notify' => ['bool', 'service'=>'resource'],
'gzclose' => ['bool', 'stream'=>'resource'],
'gzcompress' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'],
'gzdecode' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
'gzdeflate' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'],
'gzencode' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'],
'gzeof' => ['bool', 'stream'=>'resource'],
'gzfile' => ['list<string>', 'filename'=>'string', 'use_include_path='=>'int'],
'gzgetc' => ['string|false', 'stream'=>'resource'],
'gzgets' => ['string|false', 'stream'=>'resource', 'length='=>'?int'],
'gzinflate' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
'gzopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'int'],
'gzpassthru' => ['int', 'stream'=>'resource'],
'gzputs' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
'gzread' => ['string|false', 'stream'=>'resource', 'length'=>'int'],
'gzrewind' => ['bool', 'stream'=>'resource'],
'gzseek' => ['int', 'stream'=>'resource', 'offset'=>'int', 'whence='=>'int'],
'gztell' => ['int|false', 'stream'=>'resource'],
'gzuncompress' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
'gzwrite' => ['int', 'stream'=>'resource', 'data'=>'string', 'length='=>'?int'],
'HaruAnnotation::setBorderStyle' => ['bool', 'width'=>'float', 'dash_on'=>'int', 'dash_off'=>'int'],
'HaruAnnotation::setHighlightMode' => ['bool', 'mode'=>'int'],
'HaruAnnotation::setIcon' => ['bool', 'icon'=>'int'],
'HaruAnnotation::setOpened' => ['bool', 'opened'=>'bool'],
'HaruDestination::setFit' => ['bool'],
'HaruDestination::setFitB' => ['bool'],
'HaruDestination::setFitBH' => ['bool', 'top'=>'float'],
'HaruDestination::setFitBV' => ['bool', 'left'=>'float'],
'HaruDestination::setFitH' => ['bool', 'top'=>'float'],
'HaruDestination::setFitR' => ['bool', 'left'=>'float', 'bottom'=>'float', 'right'=>'float', 'top'=>'float'],
'HaruDestination::setFitV' => ['bool', 'left'=>'float'],
'HaruDestination::setXYZ' => ['bool', 'left'=>'float', 'top'=>'float', 'zoom'=>'float'],
'HaruDoc::__construct' => ['void'],
'HaruDoc::addPage' => ['object'],
'HaruDoc::addPageLabel' => ['bool', 'first_page'=>'int', 'style'=>'int', 'first_num'=>'int', 'prefix='=>'string'],
'HaruDoc::createOutline' => ['object', 'title'=>'string', 'parent_outline='=>'object', 'encoder='=>'object'],
'HaruDoc::getCurrentEncoder' => ['object'],
'HaruDoc::getCurrentPage' => ['object'],
'HaruDoc::getEncoder' => ['object', 'encoding'=>'string'],
'HaruDoc::getFont' => ['object', 'fontname'=>'string', 'encoding='=>'string'],
'HaruDoc::getInfoAttr' => ['string', 'type'=>'int'],
'HaruDoc::getPageLayout' => ['int'],
'HaruDoc::getPageMode' => ['int'],
'HaruDoc::getStreamSize' => ['int'],
'HaruDoc::insertPage' => ['object', 'page'=>'object'],
'HaruDoc::loadJPEG' => ['object', 'filename'=>'string'],
'HaruDoc::loadPNG' => ['object', 'filename'=>'string', 'deferred='=>'bool'],
'HaruDoc::loadRaw' => ['object', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'color_space'=>'int'],
'HaruDoc::loadTTC' => ['string', 'fontfile'=>'string', 'index'=>'int', 'embed='=>'bool'],
'HaruDoc::loadTTF' => ['string', 'fontfile'=>'string', 'embed='=>'bool'],
'HaruDoc::loadType1' => ['string', 'afmfile'=>'string', 'pfmfile='=>'string'],
'HaruDoc::output' => ['bool'],
'HaruDoc::readFromStream' => ['string', 'bytes'=>'int'],
'HaruDoc::resetError' => ['bool'],
'HaruDoc::resetStream' => ['bool'],
'HaruDoc::save' => ['bool', 'file'=>'string'],
'HaruDoc::saveToStream' => ['bool'],
'HaruDoc::setCompressionMode' => ['bool', 'mode'=>'int'],
'HaruDoc::setCurrentEncoder' => ['bool', 'encoding'=>'string'],
'HaruDoc::setEncryptionMode' => ['bool', 'mode'=>'int', 'key_len='=>'int'],
'HaruDoc::setInfoAttr' => ['bool', 'type'=>'int', 'info'=>'string'],
'HaruDoc::setInfoDateAttr' => ['bool', 'type'=>'int', 'year'=>'int', 'month'=>'int', 'day'=>'int', 'hour'=>'int', 'min'=>'int', 'sec'=>'int', 'ind'=>'string', 'off_hour'=>'int', 'off_min'=>'int'],
'HaruDoc::setOpenAction' => ['bool', 'destination'=>'object'],
'HaruDoc::setPageLayout' => ['bool', 'layout'=>'int'],
'HaruDoc::setPageMode' => ['bool', 'mode'=>'int'],
'HaruDoc::setPagesConfiguration' => ['bool', 'page_per_pages'=>'int'],
'HaruDoc::setPassword' => ['bool', 'owner_password'=>'string', 'user_password'=>'string'],
'HaruDoc::setPermission' => ['bool', 'permission'=>'int'],
'HaruDoc::useCNSEncodings' => ['bool'],
'HaruDoc::useCNSFonts' => ['bool'],
'HaruDoc::useCNTEncodings' => ['bool'],
'HaruDoc::useCNTFonts' => ['bool'],
'HaruDoc::useJPEncodings' => ['bool'],
'HaruDoc::useJPFonts' => ['bool'],
'HaruDoc::useKREncodings' => ['bool'],
'HaruDoc::useKRFonts' => ['bool'],
'HaruEncoder::getByteType' => ['int', 'text'=>'string', 'index'=>'int'],
'HaruEncoder::getType' => ['int'],
'HaruEncoder::getUnicode' => ['int', 'character'=>'int'],
'HaruEncoder::getWritingMode' => ['int'],
'HaruFont::getAscent' => ['int'],
'HaruFont::getCapHeight' => ['int'],
'HaruFont::getDescent' => ['int'],
'HaruFont::getEncodingName' => ['string'],
'HaruFont::getFontName' => ['string'],
'HaruFont::getTextWidth' => ['array', 'text'=>'string'],
'HaruFont::getUnicodeWidth' => ['int', 'character'=>'int'],
'HaruFont::getXHeight' => ['int'],
'HaruFont::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'font_size'=>'float', 'char_space'=>'float', 'word_space'=>'float', 'word_wrap='=>'bool'],
'HaruImage::getBitsPerComponent' => ['int'],
'HaruImage::getColorSpace' => ['string'],
'HaruImage::getHeight' => ['int'],
'HaruImage::getSize' => ['array'],
'HaruImage::getWidth' => ['int'],
'HaruImage::setColorMask' => ['bool', 'rmin'=>'int', 'rmax'=>'int', 'gmin'=>'int', 'gmax'=>'int', 'bmin'=>'int', 'bmax'=>'int'],
'HaruImage::setMaskImage' => ['bool', 'mask_image'=>'object'],
'HaruOutline::setDestination' => ['bool', 'destination'=>'object'],
'HaruOutline::setOpened' => ['bool', 'opened'=>'bool'],
'HaruPage::arc' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float', 'ang1'=>'float', 'ang2'=>'float'],
'HaruPage::beginText' => ['bool'],
'HaruPage::circle' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float'],
'HaruPage::closePath' => ['bool'],
'HaruPage::concat' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'],
'HaruPage::createDestination' => ['object'],
'HaruPage::createLinkAnnotation' => ['object', 'rectangle'=>'array', 'destination'=>'object'],
'HaruPage::createTextAnnotation' => ['object', 'rectangle'=>'array', 'text'=>'string', 'encoder='=>'object'],
'HaruPage::createURLAnnotation' => ['object', 'rectangle'=>'array', 'url'=>'string'],
'HaruPage::curveTo' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
'HaruPage::curveTo2' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
'HaruPage::curveTo3' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x3'=>'float', 'y3'=>'float'],
'HaruPage::drawImage' => ['bool', 'image'=>'object', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
'HaruPage::ellipse' => ['bool', 'x'=>'float', 'y'=>'float', 'xray'=>'float', 'yray'=>'float'],
'HaruPage::endPath' => ['bool'],
'HaruPage::endText' => ['bool'],
'HaruPage::eofill' => ['bool'],
'HaruPage::eoFillStroke' => ['bool', 'close_path='=>'bool'],
'HaruPage::fill' => ['bool'],
'HaruPage::fillStroke' => ['bool', 'close_path='=>'bool'],
'HaruPage::getCharSpace' => ['float'],
'HaruPage::getCMYKFill' => ['array'],
'HaruPage::getCMYKStroke' => ['array'],
'HaruPage::getCurrentFont' => ['object'],
'HaruPage::getCurrentFontSize' => ['float'],
'HaruPage::getCurrentPos' => ['array'],
'HaruPage::getCurrentTextPos' => ['array'],
'HaruPage::getDash' => ['array'],
'HaruPage::getFillingColorSpace' => ['int'],
'HaruPage::getFlatness' => ['float'],
'HaruPage::getGMode' => ['int'],
'HaruPage::getGrayFill' => ['float'],
'HaruPage::getGrayStroke' => ['float'],
'HaruPage::getHeight' => ['float'],
'HaruPage::getHorizontalScaling' => ['float'],
'HaruPage::getLineCap' => ['int'],
'HaruPage::getLineJoin' => ['int'],
'HaruPage::getLineWidth' => ['float'],
'HaruPage::getMiterLimit' => ['float'],
'HaruPage::getRGBFill' => ['array'],
'HaruPage::getRGBStroke' => ['array'],
'HaruPage::getStrokingColorSpace' => ['int'],
'HaruPage::getTextLeading' => ['float'],
'HaruPage::getTextMatrix' => ['array'],
'HaruPage::getTextRenderingMode' => ['int'],
'HaruPage::getTextRise' => ['float'],
'HaruPage::getTextWidth' => ['float', 'text'=>'string'],
'HaruPage::getTransMatrix' => ['array'],
'HaruPage::getWidth' => ['float'],
'HaruPage::getWordSpace' => ['float'],
'HaruPage::lineTo' => ['bool', 'x'=>'float', 'y'=>'float'],
'HaruPage::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'wordwrap='=>'bool'],
'HaruPage::moveTextPos' => ['bool', 'x'=>'float', 'y'=>'float', 'set_leading='=>'bool'],
'HaruPage::moveTo' => ['bool', 'x'=>'float', 'y'=>'float'],
'HaruPage::moveToNextLine' => ['bool'],
'HaruPage::rectangle' => ['bool', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
'HaruPage::setCharSpace' => ['bool', 'char_space'=>'float'],
'HaruPage::setCMYKFill' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'],
'HaruPage::setCMYKStroke' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'],
'HaruPage::setDash' => ['bool', 'pattern'=>'array', 'phase'=>'int'],
'HaruPage::setFlatness' => ['bool', 'flatness'=>'float'],
'HaruPage::setFontAndSize' => ['bool', 'font'=>'object', 'size'=>'float'],
'HaruPage::setGrayFill' => ['bool', 'value'=>'float'],
'HaruPage::setGrayStroke' => ['bool', 'value'=>'float'],
'HaruPage::setHeight' => ['bool', 'height'=>'float'],
'HaruPage::setHorizontalScaling' => ['bool', 'scaling'=>'float'],
'HaruPage::setLineCap' => ['bool', 'cap'=>'int'],
'HaruPage::setLineJoin' => ['bool', 'join'=>'int'],
'HaruPage::setLineWidth' => ['bool', 'width'=>'float'],
'HaruPage::setMiterLimit' => ['bool', 'limit'=>'float'],
'HaruPage::setRGBFill' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'],
'HaruPage::setRGBStroke' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'],
'HaruPage::setRotate' => ['bool', 'angle'=>'int'],
'HaruPage::setSize' => ['bool', 'size'=>'int', 'direction'=>'int'],
'HaruPage::setSlideShow' => ['bool', 'type'=>'int', 'disp_time'=>'float', 'trans_time'=>'float'],
'HaruPage::setTextLeading' => ['bool', 'text_leading'=>'float'],
'HaruPage::setTextMatrix' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'],
'HaruPage::setTextRenderingMode' => ['bool', 'mode'=>'int'],
'HaruPage::setTextRise' => ['bool', 'rise'=>'float'],
'HaruPage::setWidth' => ['bool', 'width'=>'float'],
'HaruPage::setWordSpace' => ['bool', 'word_space'=>'float'],
'HaruPage::showText' => ['bool', 'text'=>'string'],
'HaruPage::showTextNextLine' => ['bool', 'text'=>'string', 'word_space='=>'float', 'char_space='=>'float'],
'HaruPage::stroke' => ['bool', 'close_path='=>'bool'],
'HaruPage::textOut' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'],
'HaruPage::textRect' => ['bool', 'left'=>'float', 'top'=>'float', 'right'=>'float', 'bottom'=>'float', 'text'=>'string', 'align='=>'int'],
'hash' => ['non-empty-string', 'algo'=>'string', 'data'=>'string', 'binary='=>'bool', 'options='=>'array{seed:scalar}'],
'hash_algos' => ['list<string>'],
'hash_copy' => ['HashContext', 'context'=>'HashContext'],
'hash_equals' => ['bool', 'known_string'=>'string', 'user_string'=>'string'],
'hash_file' => ['non-empty-string|false', 'algo'=>'string', 'filename'=>'string', 'binary='=>'bool', 'options='=>'array{seed:scalar}'],
'hash_final' => ['non-empty-string', 'context'=>'HashContext', 'binary='=>'bool'],
'hash_hkdf' => ['non-empty-string', 'algo'=>'string', 'key'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'],
'hash_hmac' => ['non-empty-string', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'binary='=>'bool'],
'hash_hmac_algos' => ['list<string>'],
'hash_hmac_file' => ['non-empty-string|false', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'binary='=>'bool'],
'hash_init' => ['HashContext', 'algo'=>'string', 'flags='=>'int', 'key='=>'string', 'options='=>'array{seed:scalar}'],
'hash_pbkdf2' => ['non-empty-string', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'binary='=>'bool'],
'hash_update' => ['bool', 'context'=>'HashContext', 'data'=>'string'],
'hash_update_file' => ['bool', 'context'=>'HashContext', 'filename'=>'string', 'stream_context='=>'?resource'],
'hash_update_stream' => ['int', 'context'=>'HashContext', 'stream'=>'resource', 'length='=>'int'],
'hashTableObj::clear' => ['void'],
'hashTableObj::get' => ['string', 'key'=>'string'],
'hashTableObj::nextkey' => ['string', 'previousKey'=>'string'],
'hashTableObj::remove' => ['int', 'key'=>'string'],
'hashTableObj::set' => ['int', 'key'=>'string', 'value'=>'string'],
'header' => ['void', 'header'=>'string', 'replace='=>'bool', 'response_code='=>'int'],
'header_register_callback' => ['bool', 'callback'=>'callable():void'],
'header_remove' => ['void', 'name='=>'?string'],
'headers_list' => ['list<string>'],
'headers_sent' => ['bool', '&w_filename='=>'string', '&w_line='=>'int'],
'hebrev' => ['string', 'string'=>'string', 'max_chars_per_line='=>'int'],
'hebrevc' => ['string', 'string'=>'string', 'max_chars_per_line='=>'int'],
'hex2bin' => ['string|false', 'string'=>'string'],
'hexdec' => ['int|float', 'hex_string'=>'string'],
'highlight_file' => ['string|bool', 'filename'=>'string', 'return='=>'bool'],
'highlight_string' => ['string|bool', 'string'=>'string', 'return='=>'bool'],
'hrtime' => ['array{0:int,1:int}|false', 'as_number='=>'false'],
'hrtime\'1' => ['int|float|false', 'as_number='=>'true'],
'HRTime\PerformanceCounter::getElapsedTicks' => ['int'],
'HRTime\PerformanceCounter::getFrequency' => ['int'],
'HRTime\PerformanceCounter::getLastElapsedTicks' => ['int'],
'HRTime\PerformanceCounter::getTicks' => ['int'],
'HRTime\PerformanceCounter::getTicksSince' => ['int', 'start'=>'int'],
'HRTime\PerformanceCounter::isRunning' => ['bool'],
'HRTime\PerformanceCounter::start' => ['void'],
'HRTime\PerformanceCounter::stop' => ['void'],
'HRTime\StopWatch::getElapsedTicks' => ['int'],
'HRTime\StopWatch::getElapsedTime' => ['float', 'unit='=>'int'],
'HRTime\StopWatch::getLastElapsedTicks' => ['int'],
'HRTime\StopWatch::getLastElapsedTime' => ['float', 'unit='=>'int'],
'HRTime\StopWatch::isRunning' => ['bool'],
'HRTime\StopWatch::start' => ['void'],
'HRTime\StopWatch::stop' => ['void'],
'html_entity_decode' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'?string'],
'htmlentities' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'?string', 'double_encode='=>'bool'],
'htmlspecialchars' => ['string', 'string'=>'string', 'flags='=>'int', 'encoding='=>'string|null', 'double_encode='=>'bool'],
'htmlspecialchars_decode' => ['string', 'string'=>'string', 'flags='=>'int'],
'http\Client::__construct' => ['void', 'driver='=>'string', 'persistent_handle_id='=>'string'],
'http\Client::addCookies' => ['http\Client', 'cookies='=>'?array'],
'http\Client::addSslOptions' => ['http\Client', 'ssl_options='=>'?array'],
'http\Client::attach' => ['void', 'observer'=>'SplObserver'],
'http\Client::configure' => ['http\Client', 'settings'=>'array'],
'http\Client::count' => ['int'],
'http\Client::dequeue' => ['http\Client', 'request'=>'http\Client\Request'],
'http\Client::detach' => ['void', 'observer'=>'SplObserver'],
'http\Client::enableEvents' => ['http\Client', 'enable='=>'mixed'],
'http\Client::enablePipelining' => ['http\Client', 'enable='=>'mixed'],
'http\Client::enqueue' => ['http\Client', 'request'=>'http\Client\Request', 'callable='=>'mixed'],
'http\Client::getAvailableConfiguration' => ['array'],
'http\Client::getAvailableDrivers' => ['array'],
'http\Client::getAvailableOptions' => ['array'],
'http\Client::getCookies' => ['array'],
'http\Client::getHistory' => ['http\Message'],
'http\Client::getObservers' => ['SplObjectStorage'],
'http\Client::getOptions' => ['array'],
'http\Client::getProgressInfo' => ['null|object', 'request'=>'http\Client\Request'],
'http\Client::getResponse' => ['http\Client\Response|null', 'request='=>'?http\Client\Request'],
'http\Client::getSslOptions' => ['array'],
'http\Client::getTransferInfo' => ['object', 'request'=>'http\Client\Request'],
'http\Client::notify' => ['void', 'request='=>'?http\Client\Request'],
'http\Client::once' => ['bool'],
'http\Client::requeue' => ['http\Client', 'request'=>'http\Client\Request', 'callable='=>'mixed'],
'http\Client::reset' => ['http\Client'],
'http\Client::send' => ['http\Client'],
'http\Client::setCookies' => ['http\Client', 'cookies='=>'?array'],
'http\Client::setDebug' => ['http\Client', 'callback'=>'callable'],
'http\Client::setOptions' => ['http\Client', 'options='=>'?array'],
'http\Client::setSslOptions' => ['http\Client', 'ssl_option='=>'?array'],
'http\Client::wait' => ['bool', 'timeout='=>'mixed'],
'http\Client\Curl\User::init' => ['', 'run'=>'callable'],
'http\Client\Curl\User::once' => [''],
'http\Client\Curl\User::send' => [''],
'http\Client\Curl\User::socket' => ['', 'socket'=>'resource', 'action'=>'int'],
'http\Client\Curl\User::timer' => ['', 'timeout_ms'=>'int'],
'http\Client\Curl\User::wait' => ['', 'timeout_ms='=>'mixed'],
'http\Client\Request::__construct' => ['void', 'method='=>'mixed', 'url='=>'mixed', 'headers='=>'?array', 'body='=>'?http\Message\Body'],
'http\Client\Request::__toString' => ['string'],
'http\Client\Request::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Client\Request::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
'http\Client\Request::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
'http\Client\Request::addQuery' => ['http\Client\Request', 'query_data'=>'mixed'],
'http\Client\Request::addSslOptions' => ['http\Client\Request', 'ssl_options='=>'?array'],
'http\Client\Request::count' => ['int'],
'http\Client\Request::current' => ['mixed'],
'http\Client\Request::detach' => ['http\Message'],
'http\Client\Request::getBody' => ['http\Message\Body'],
'http\Client\Request::getContentType' => ['null|string'],
'http\Client\Request::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
'http\Client\Request::getHeaders' => ['array'],
'http\Client\Request::getHttpVersion' => ['string'],
'http\Client\Request::getInfo' => ['null|string'],
'http\Client\Request::getOptions' => ['array'],
'http\Client\Request::getParentMessage' => ['http\Message'],
'http\Client\Request::getQuery' => ['null|string'],
'http\Client\Request::getRequestMethod' => ['false|string'],
'http\Client\Request::getRequestUrl' => ['false|string'],
'http\Client\Request::getResponseCode' => ['false|int'],
'http\Client\Request::getResponseStatus' => ['false|string'],
'http\Client\Request::getSslOptions' => ['array'],
'http\Client\Request::getType' => ['int'],
'http\Client\Request::isMultipart' => ['bool', '&boundary='=>'mixed'],
'http\Client\Request::key' => ['int|string'],
'http\Client\Request::next' => ['void'],
'http\Client\Request::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
'http\Client\Request::reverse' => ['http\Message'],
'http\Client\Request::rewind' => ['void'],
'http\Client\Request::serialize' => ['string'],
'http\Client\Request::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Client\Request::setContentType' => ['http\Client\Request', 'content_type'=>'string'],
'http\Client\Request::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
'http\Client\Request::setHeaders' => ['http\Message', 'headers'=>'array'],
'http\Client\Request::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
'http\Client\Request::setInfo' => ['http\Message', 'http_info'=>'string'],
'http\Client\Request::setOptions' => ['http\Client\Request', 'options='=>'?array'],
'http\Client\Request::setQuery' => ['http\Client\Request', 'query_data='=>'mixed'],
'http\Client\Request::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
'http\Client\Request::setRequestUrl' => ['http\Message', 'url'=>'string'],
'http\Client\Request::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
'http\Client\Request::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
'http\Client\Request::setSslOptions' => ['http\Client\Request', 'ssl_options='=>'?array'],
'http\Client\Request::setType' => ['http\Message', 'type'=>'int'],
'http\Client\Request::splitMultipartBody' => ['http\Message'],
'http\Client\Request::toCallback' => ['http\Message', 'callback'=>'callable'],
'http\Client\Request::toStream' => ['http\Message', 'stream'=>'resource'],
'http\Client\Request::toString' => ['string', 'include_parent='=>'mixed'],
'http\Client\Request::unserialize' => ['void', 'serialized'=>'string'],
'http\Client\Request::valid' => ['bool'],
'http\Client\Response::__construct' => ['Iterator'],
'http\Client\Response::__toString' => ['string'],
'http\Client\Response::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Client\Response::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
'http\Client\Response::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
'http\Client\Response::count' => ['int'],
'http\Client\Response::current' => ['mixed'],
'http\Client\Response::detach' => ['http\Message'],
'http\Client\Response::getBody' => ['http\Message\Body'],
'http\Client\Response::getCookies' => ['array', 'flags='=>'mixed', 'allowed_extras='=>'mixed'],
'http\Client\Response::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
'http\Client\Response::getHeaders' => ['array'],
'http\Client\Response::getHttpVersion' => ['string'],
'http\Client\Response::getInfo' => ['null|string'],
'http\Client\Response::getParentMessage' => ['http\Message'],
'http\Client\Response::getRequestMethod' => ['false|string'],
'http\Client\Response::getRequestUrl' => ['false|string'],
'http\Client\Response::getResponseCode' => ['false|int'],
'http\Client\Response::getResponseStatus' => ['false|string'],
'http\Client\Response::getTransferInfo' => ['mixed|object', 'element='=>'mixed'],
'http\Client\Response::getType' => ['int'],
'http\Client\Response::isMultipart' => ['bool', '&boundary='=>'mixed'],
'http\Client\Response::key' => ['int|string'],
'http\Client\Response::next' => ['void'],
'http\Client\Response::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
'http\Client\Response::reverse' => ['http\Message'],
'http\Client\Response::rewind' => ['void'],
'http\Client\Response::serialize' => ['string'],
'http\Client\Response::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Client\Response::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
'http\Client\Response::setHeaders' => ['http\Message', 'headers'=>'array'],
'http\Client\Response::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
'http\Client\Response::setInfo' => ['http\Message', 'http_info'=>'string'],
'http\Client\Response::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
'http\Client\Response::setRequestUrl' => ['http\Message', 'url'=>'string'],
'http\Client\Response::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
'http\Client\Response::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
'http\Client\Response::setType' => ['http\Message', 'type'=>'int'],
'http\Client\Response::splitMultipartBody' => ['http\Message'],
'http\Client\Response::toCallback' => ['http\Message', 'callback'=>'callable'],
'http\Client\Response::toStream' => ['http\Message', 'stream'=>'resource'],
'http\Client\Response::toString' => ['string', 'include_parent='=>'mixed'],
'http\Client\Response::unserialize' => ['void', 'serialized'=>'string'],
'http\Client\Response::valid' => ['bool'],
'http\Cookie::__construct' => ['void', 'cookie_string='=>'mixed', 'parser_flags='=>'int', 'allowed_extras='=>'array'],
'http\Cookie::__toString' => ['string'],
'http\Cookie::addCookie' => ['http\Cookie', 'cookie_name'=>'string', 'cookie_value'=>'string'],
'http\Cookie::addCookies' => ['http\Cookie', 'cookies'=>'array'],
'http\Cookie::addExtra' => ['http\Cookie', 'extra_name'=>'string', 'extra_value'=>'string'],
'http\Cookie::addExtras' => ['http\Cookie', 'extras'=>'array'],
'http\Cookie::getCookie' => ['null|string', 'name'=>'string'],
'http\Cookie::getCookies' => ['array'],
'http\Cookie::getDomain' => ['string'],
'http\Cookie::getExpires' => ['int'],
'http\Cookie::getExtra' => ['string', 'name'=>'string'],
'http\Cookie::getExtras' => ['array'],
'http\Cookie::getFlags' => ['int'],
'http\Cookie::getMaxAge' => ['int'],
'http\Cookie::getPath' => ['string'],
'http\Cookie::setCookie' => ['http\Cookie', 'cookie_name'=>'string', 'cookie_value='=>'mixed'],
'http\Cookie::setCookies' => ['http\Cookie', 'cookies='=>'mixed'],
'http\Cookie::setDomain' => ['http\Cookie', 'value='=>'mixed'],
'http\Cookie::setExpires' => ['http\Cookie', 'value='=>'mixed'],
'http\Cookie::setExtra' => ['http\Cookie', 'extra_name'=>'string', 'extra_value='=>'mixed'],
'http\Cookie::setExtras' => ['http\Cookie', 'extras='=>'mixed'],
'http\Cookie::setFlags' => ['http\Cookie', 'value='=>'mixed'],
'http\Cookie::setMaxAge' => ['http\Cookie', 'value='=>'mixed'],
'http\Cookie::setPath' => ['http\Cookie', 'value='=>'mixed'],
'http\Cookie::toArray' => ['array'],
'http\Cookie::toString' => ['string'],
'http\Encoding\Stream::__construct' => ['void', 'flags='=>'mixed'],
'http\Encoding\Stream::done' => ['bool'],
'http\Encoding\Stream::finish' => ['string'],
'http\Encoding\Stream::flush' => ['string'],
'http\Encoding\Stream::update' => ['string', 'data'=>'string'],
'http\Encoding\Stream\Debrotli::__construct' => ['void', 'flags='=>'int'],
'http\Encoding\Stream\Debrotli::decode' => ['string', 'data'=>'string'],
'http\Encoding\Stream\Debrotli::done' => ['bool'],
'http\Encoding\Stream\Debrotli::finish' => ['string'],
'http\Encoding\Stream\Debrotli::flush' => ['string'],
'http\Encoding\Stream\Debrotli::update' => ['string', 'data'=>'string'],
'http\Encoding\Stream\Dechunk::__construct' => ['void', 'flags='=>'mixed'],
'http\Encoding\Stream\Dechunk::decode' => ['false|string', 'data'=>'string', '&decoded_len='=>'mixed'],
'http\Encoding\Stream\Dechunk::done' => ['bool'],
'http\Encoding\Stream\Dechunk::finish' => ['string'],
'http\Encoding\Stream\Dechunk::flush' => ['string'],
'http\Encoding\Stream\Dechunk::update' => ['string', 'data'=>'string'],
'http\Encoding\Stream\Deflate::__construct' => ['void', 'flags='=>'mixed'],
'http\Encoding\Stream\Deflate::done' => ['bool'],
'http\Encoding\Stream\Deflate::encode' => ['string', 'data'=>'string', 'flags='=>'mixed'],
'http\Encoding\Stream\Deflate::finish' => ['string'],
'http\Encoding\Stream\Deflate::flush' => ['string'],
'http\Encoding\Stream\Deflate::update' => ['string', 'data'=>'string'],
'http\Encoding\Stream\Enbrotli::__construct' => ['void', 'flags='=>'int'],
'http\Encoding\Stream\Enbrotli::done' => ['bool'],
'http\Encoding\Stream\Enbrotli::encode' => ['string', 'data'=>'string', 'flags='=>'int'],
'http\Encoding\Stream\Enbrotli::finish' => ['string'],
'http\Encoding\Stream\Enbrotli::flush' => ['string'],
'http\Encoding\Stream\Enbrotli::update' => ['string', 'data'=>'string'],
'http\Encoding\Stream\Inflate::__construct' => ['void', 'flags='=>'mixed'],
'http\Encoding\Stream\Inflate::decode' => ['string', 'data'=>'string'],
'http\Encoding\Stream\Inflate::done' => ['bool'],
'http\Encoding\Stream\Inflate::finish' => ['string'],
'http\Encoding\Stream\Inflate::flush' => ['string'],
'http\Encoding\Stream\Inflate::update' => ['string', 'data'=>'string'],
'http\Env::getRequestBody' => ['http\Message\Body', 'body_class_name='=>'mixed'],
'http\Env::getRequestHeader' => ['array|null|string', 'header_name='=>'mixed'],
'http\Env::getResponseCode' => ['int'],
'http\Env::getResponseHeader' => ['array|null|string', 'header_name='=>'mixed'],
'http\Env::getResponseStatusForAllCodes' => ['array'],
'http\Env::getResponseStatusForCode' => ['string', 'code'=>'int'],
'http\Env::negotiate' => ['null|string', 'params'=>'string', 'supported'=>'array', 'primary_type_separator='=>'mixed', '&result_array='=>'mixed'],
'http\Env::negotiateCharset' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
'http\Env::negotiateContentType' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
'http\Env::negotiateEncoding' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
'http\Env::negotiateLanguage' => ['null|string', 'supported'=>'array', '&result_array='=>'mixed'],
'http\Env::setResponseCode' => ['bool', 'code'=>'int'],
'http\Env::setResponseHeader' => ['bool', 'header_name'=>'string', 'header_value='=>'mixed', 'response_code='=>'mixed', 'replace_header='=>'mixed'],
'http\Env\Request::__construct' => ['void'],
'http\Env\Request::__toString' => ['string'],
'http\Env\Request::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Env\Request::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
'http\Env\Request::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
'http\Env\Request::count' => ['int'],
'http\Env\Request::current' => ['mixed'],
'http\Env\Request::detach' => ['http\Message'],
'http\Env\Request::getBody' => ['http\Message\Body'],
'http\Env\Request::getCookie' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
'http\Env\Request::getFiles' => ['array'],
'http\Env\Request::getForm' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
'http\Env\Request::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
'http\Env\Request::getHeaders' => ['array'],
'http\Env\Request::getHttpVersion' => ['string'],
'http\Env\Request::getInfo' => ['null|string'],
'http\Env\Request::getParentMessage' => ['http\Message'],
'http\Env\Request::getQuery' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
'http\Env\Request::getRequestMethod' => ['false|string'],
'http\Env\Request::getRequestUrl' => ['false|string'],
'http\Env\Request::getResponseCode' => ['false|int'],
'http\Env\Request::getResponseStatus' => ['false|string'],
'http\Env\Request::getType' => ['int'],
'http\Env\Request::isMultipart' => ['bool', '&boundary='=>'mixed'],
'http\Env\Request::key' => ['int|string'],
'http\Env\Request::next' => ['void'],
'http\Env\Request::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
'http\Env\Request::reverse' => ['http\Message'],
'http\Env\Request::rewind' => ['void'],
'http\Env\Request::serialize' => ['string'],
'http\Env\Request::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Env\Request::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
'http\Env\Request::setHeaders' => ['http\Message', 'headers'=>'array'],
'http\Env\Request::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
'http\Env\Request::setInfo' => ['http\Message', 'http_info'=>'string'],
'http\Env\Request::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
'http\Env\Request::setRequestUrl' => ['http\Message', 'url'=>'string'],
'http\Env\Request::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
'http\Env\Request::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
'http\Env\Request::setType' => ['http\Message', 'type'=>'int'],
'http\Env\Request::splitMultipartBody' => ['http\Message'],
'http\Env\Request::toCallback' => ['http\Message', 'callback'=>'callable'],
'http\Env\Request::toStream' => ['http\Message', 'stream'=>'resource'],
'http\Env\Request::toString' => ['string', 'include_parent='=>'mixed'],
'http\Env\Request::unserialize' => ['void', 'serialized'=>'string'],
'http\Env\Request::valid' => ['bool'],
'http\Env\Response::__construct' => ['void'],
'http\Env\Response::__invoke' => ['bool', 'data'=>'string', 'ob_flags='=>'int'],
'http\Env\Response::__toString' => ['string'],
'http\Env\Response::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Env\Response::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
'http\Env\Response::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
'http\Env\Response::count' => ['int'],
'http\Env\Response::current' => ['mixed'],
'http\Env\Response::detach' => ['http\Message'],
'http\Env\Response::getBody' => ['http\Message\Body'],
'http\Env\Response::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
'http\Env\Response::getHeaders' => ['array'],
'http\Env\Response::getHttpVersion' => ['string'],
'http\Env\Response::getInfo' => ['?string'],
'http\Env\Response::getParentMessage' => ['http\Message'],
'http\Env\Response::getRequestMethod' => ['false|string'],
'http\Env\Response::getRequestUrl' => ['false|string'],
'http\Env\Response::getResponseCode' => ['false|int'],
'http\Env\Response::getResponseStatus' => ['false|string'],
'http\Env\Response::getType' => ['int'],
'http\Env\Response::isCachedByETag' => ['int', 'header_name='=>'string'],
'http\Env\Response::isCachedByLastModified' => ['int', 'header_name='=>'string'],
'http\Env\Response::isMultipart' => ['bool', '&boundary='=>'mixed'],
'http\Env\Response::key' => ['int|string'],
'http\Env\Response::next' => ['void'],
'http\Env\Response::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
'http\Env\Response::reverse' => ['http\Message'],
'http\Env\Response::rewind' => ['void'],
'http\Env\Response::send' => ['bool', 'stream='=>'resource'],
'http\Env\Response::serialize' => ['string'],
'http\Env\Response::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Env\Response::setCacheControl' => ['http\Env\Response', 'cache_control'=>'string'],
'http\Env\Response::setContentDisposition' => ['http\Env\Response', 'disposition_params'=>'array'],
'http\Env\Response::setContentEncoding' => ['http\Env\Response', 'content_encoding'=>'int'],
'http\Env\Response::setContentType' => ['http\Env\Response', 'content_type'=>'string'],
'http\Env\Response::setCookie' => ['http\Env\Response', 'cookie'=>'mixed'],
'http\Env\Response::setEnvRequest' => ['http\Env\Response', 'env_request'=>'http\Message'],
'http\Env\Response::setEtag' => ['http\Env\Response', 'etag'=>'string'],
'http\Env\Response::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
'http\Env\Response::setHeaders' => ['http\Message', 'headers'=>'array'],
'http\Env\Response::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
'http\Env\Response::setInfo' => ['http\Message', 'http_info'=>'string'],
'http\Env\Response::setLastModified' => ['http\Env\Response', 'last_modified'=>'int'],
'http\Env\Response::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
'http\Env\Response::setRequestUrl' => ['http\Message', 'url'=>'string'],
'http\Env\Response::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
'http\Env\Response::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
'http\Env\Response::setThrottleRate' => ['http\Env\Response', 'chunk_size'=>'int', 'delay='=>'float|int'],
'http\Env\Response::setType' => ['http\Message', 'type'=>'int'],
'http\Env\Response::splitMultipartBody' => ['http\Message'],
'http\Env\Response::toCallback' => ['http\Message', 'callback'=>'callable'],
'http\Env\Response::toStream' => ['http\Message', 'stream'=>'resource'],
'http\Env\Response::toString' => ['string', 'include_parent='=>'mixed'],
'http\Env\Response::unserialize' => ['void', 'serialized'=>'string'],
'http\Env\Response::valid' => ['bool'],
'http\Header::__construct' => ['void', 'name='=>'mixed', 'value='=>'mixed'],
'http\Header::__toString' => ['string'],
'http\Header::getParams' => ['http\Params', 'param_sep='=>'mixed', 'arg_sep='=>'mixed', 'val_sep='=>'mixed', 'flags='=>'mixed'],
'http\Header::match' => ['bool', 'value'=>'string', 'flags='=>'mixed'],
'http\Header::negotiate' => ['null|string', 'supported'=>'array', '&result='=>'mixed'],
'http\Header::parse' => ['array|false', 'string'=>'string', 'header_class='=>'mixed'],
'http\Header::serialize' => ['string'],
'http\Header::toString' => ['string'],
'http\Header::unserialize' => ['void', 'serialized'=>'string'],
'http\Header\Parser::getState' => ['int'],
'http\Header\Parser::parse' => ['int', 'data'=>'string', 'flags'=>'int', '&headers'=>'array'],
'http\Header\Parser::stream' => ['int', 'stream'=>'resource', 'flags'=>'int', '&headers'=>'array'],
'http\Message::__construct' => ['void', 'message='=>'mixed', 'greedy='=>'bool'],
'http\Message::__toString' => ['string'],
'http\Message::addBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Message::addHeader' => ['http\Message', 'header'=>'string', 'value'=>'mixed'],
'http\Message::addHeaders' => ['http\Message', 'headers'=>'array', 'append='=>'mixed'],
'http\Message::count' => ['int'],
'http\Message::current' => ['mixed'],
'http\Message::detach' => ['http\Message'],
'http\Message::getBody' => ['http\Message\Body'],
'http\Message::getHeader' => ['http\Header|mixed', 'header'=>'string', 'into_class='=>'mixed'],
'http\Message::getHeaders' => ['array'],
'http\Message::getHttpVersion' => ['string'],
'http\Message::getInfo' => ['null|string'],
'http\Message::getParentMessage' => ['http\Message'],
'http\Message::getRequestMethod' => ['false|string'],
'http\Message::getRequestUrl' => ['false|string'],
'http\Message::getResponseCode' => ['false|int'],
'http\Message::getResponseStatus' => ['false|string'],
'http\Message::getType' => ['int'],
'http\Message::isMultipart' => ['bool', '&boundary='=>'mixed'],
'http\Message::key' => ['int|string'],
'http\Message::next' => ['void'],
'http\Message::prepend' => ['http\Message', 'message'=>'http\Message', 'top='=>'mixed'],
'http\Message::reverse' => ['http\Message'],
'http\Message::rewind' => ['void'],
'http\Message::serialize' => ['string'],
'http\Message::setBody' => ['http\Message', 'body'=>'http\Message\Body'],
'http\Message::setHeader' => ['http\Message', 'header'=>'string', 'value='=>'mixed'],
'http\Message::setHeaders' => ['http\Message', 'headers'=>'array'],
'http\Message::setHttpVersion' => ['http\Message', 'http_version'=>'string'],
'http\Message::setInfo' => ['http\Message', 'http_info'=>'string'],
'http\Message::setRequestMethod' => ['http\Message', 'request_method'=>'string'],
'http\Message::setRequestUrl' => ['http\Message', 'url'=>'string'],
'http\Message::setResponseCode' => ['http\Message', 'response_code'=>'int', 'strict='=>'mixed'],
'http\Message::setResponseStatus' => ['http\Message', 'response_status'=>'string'],
'http\Message::setType' => ['http\Message', 'type'=>'int'],
'http\Message::splitMultipartBody' => ['http\Message'],
'http\Message::toCallback' => ['http\Message', 'callback'=>'callable'],
'http\Message::toStream' => ['http\Message', 'stream'=>'resource'],
'http\Message::toString' => ['string', 'include_parent='=>'mixed'],
'http\Message::unserialize' => ['void', 'serialized'=>'string'],
'http\Message::valid' => ['bool'],
'http\Message\Body::__construct' => ['void', 'stream='=>'resource'],
'http\Message\Body::__toString' => ['string'],
'http\Message\Body::addForm' => ['http\Message\Body', 'fields='=>'?array', 'files='=>'?array'],
'http\Message\Body::addPart' => ['http\Message\Body', 'message'=>'http\Message'],
'http\Message\Body::append' => ['http\Message\Body', 'string'=>'string'],
'http\Message\Body::etag' => ['false|string'],
'http\Message\Body::getBoundary' => ['null|string'],
'http\Message\Body::getResource' => ['resource'],
'http\Message\Body::serialize' => ['string'],
'http\Message\Body::stat' => ['int|object', 'field='=>'mixed'],
'http\Message\Body::toCallback' => ['http\Message\Body', 'callback'=>'callable', 'offset='=>'mixed', 'maxlen='=>'mixed'],
'http\Message\Body::toStream' => ['http\Message\Body', 'stream'=>'resource', 'offset='=>'mixed', 'maxlen='=>'mixed'],
'http\Message\Body::toString' => ['string'],
'http\Message\Body::unserialize' => ['void', 'serialized'=>'string'],
'http\Message\Parser::getState' => ['int'],
'http\Message\Parser::parse' => ['int', 'data'=>'string', 'flags'=>'int', '&message'=>'http\Message'],
'http\Message\Parser::stream' => ['int', 'stream'=>'resource', 'flags'=>'int', '&message'=>'http\Message'],
'http\Params::__construct' => ['void', 'params='=>'mixed', 'param_sep='=>'mixed', 'arg_sep='=>'mixed', 'val_sep='=>'mixed', 'flags='=>'mixed'],
'http\Params::__toString' => ['string'],
'http\Params::offsetExists' => ['bool', 'name'=>'mixed'],
'http\Params::offsetGet' => ['mixed', 'name'=>'mixed'],
'http\Params::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
'http\Params::offsetUnset' => ['void', 'name'=>'mixed'],
'http\Params::toArray' => ['array'],
'http\Params::toString' => ['string'],
'http\QueryString::__construct' => ['void', 'querystring'=>'string'],
'http\QueryString::__toString' => ['string'],
'http\QueryString::get' => ['http\QueryString|string|mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'],
'http\QueryString::getArray' => ['array|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
'http\QueryString::getBool' => ['bool|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
'http\QueryString::getFloat' => ['float|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
'http\QueryString::getGlobalInstance' => ['http\QueryString'],
'http\QueryString::getInt' => ['int|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
'http\QueryString::getIterator' => ['IteratorAggregate'],
'http\QueryString::getObject' => ['object|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
'http\QueryString::getString' => ['string|mixed', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'],
'http\QueryString::mod' => ['http\QueryString', 'params='=>'mixed'],
'http\QueryString::offsetExists' => ['bool', 'offset'=>'mixed'],
'http\QueryString::offsetGet' => ['mixed|null', 'offset'=>'mixed'],
'http\QueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
'http\QueryString::offsetUnset' => ['void', 'offset'=>'mixed'],
'http\QueryString::serialize' => ['string'],
'http\QueryString::set' => ['http\QueryString', 'params'=>'mixed'],
'http\QueryString::toArray' => ['array'],
'http\QueryString::toString' => ['string'],
'http\QueryString::unserialize' => ['void', 'serialized'=>'string'],
'http\QueryString::xlate' => ['http\QueryString'],
'http\Url::__construct' => ['void', 'old_url='=>'mixed', 'new_url='=>'mixed', 'flags='=>'int'],
'http\Url::__toString' => ['string'],
'http\Url::mod' => ['http\Url', 'parts'=>'mixed', 'flags='=>'float|int|mixed'],
'http\Url::toArray' => ['string[]'],
'http\Url::toString' => ['string'],
'http_build_cookie' => ['string', 'cookie'=>'array'],
'http_build_query' => ['string', 'data'=>'array|object', 'numeric_prefix='=>'string', 'arg_separator='=>'?string', 'encoding_type='=>'int'],
'http_build_str' => ['string', 'query'=>'array', 'prefix='=>'?string', 'arg_separator='=>'string'],
'http_build_url' => ['string', 'url='=>'string|array', 'parts='=>'string|array', 'flags='=>'int', 'new_url='=>'array'],
'http_cache_etag' => ['bool', 'etag='=>'string'],
'http_cache_last_modified' => ['bool', 'timestamp_or_expires='=>'int'],
'http_chunked_decode' => ['string|false', 'encoded'=>'string'],
'http_date' => ['string', 'timestamp='=>'int'],
'http_deflate' => ['?string', 'data'=>'string', 'flags='=>'int'],
'http_get' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'],
'http_get_request_body' => ['?string'],
'http_get_request_body_stream' => ['?resource'],
'http_get_request_headers' => ['array'],
'http_head' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'],
'http_inflate' => ['?string', 'data'=>'string'],
'http_match_etag' => ['bool', 'etag'=>'string', 'for_range='=>'bool'],
'http_match_modified' => ['bool', 'timestamp='=>'int', 'for_range='=>'bool'],
'http_match_request_header' => ['bool', 'header'=>'string', 'value'=>'string', 'match_case='=>'bool'],
'http_negotiate_charset' => ['string', 'supported'=>'array', 'result='=>'array'],
'http_negotiate_content_type' => ['string', 'supported'=>'array', 'result='=>'array'],
'http_negotiate_language' => ['string', 'supported'=>'array', 'result='=>'array'],
'http_parse_cookie' => ['stdClass|false', 'cookie'=>'string', 'flags='=>'int', 'allowed_extras='=>'array'],
'http_parse_headers' => ['array|false', 'header'=>'string'],
'http_parse_message' => ['object', 'message'=>'string'],
'http_parse_params' => ['stdClass', 'param'=>'string', 'flags='=>'int'],
'http_persistent_handles_clean' => ['string', 'ident='=>'string'],
'http_persistent_handles_count' => ['stdClass|false'],
'http_persistent_handles_ident' => ['string|false', 'ident='=>'string'],
'http_post_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'],
'http_post_fields' => ['string', 'url'=>'string', 'data'=>'array', 'files='=>'array', 'options='=>'array', 'info='=>'array'],
'http_put_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'],
'http_put_file' => ['string', 'url'=>'string', 'file'=>'string', 'options='=>'array', 'info='=>'array'],
'http_put_stream' => ['string', 'url'=>'string', 'stream'=>'resource', 'options='=>'array', 'info='=>'array'],
'http_redirect' => ['int|false', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'],
'http_request' => ['string', 'method'=>'int', 'url'=>'string', 'body='=>'string', 'options='=>'array', 'info='=>'array'],
'http_request_body_encode' => ['string|false', 'fields'=>'array', 'files'=>'array'],
'http_request_method_exists' => ['bool', 'method'=>'mixed'],
'http_request_method_name' => ['string|false', 'method'=>'int'],
'http_request_method_register' => ['int|false', 'method'=>'string'],
'http_request_method_unregister' => ['bool', 'method'=>'mixed'],
'http_response_code' => ['int|bool', 'response_code='=>'int'],
'http_send_content_disposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'],
'http_send_content_type' => ['bool', 'content_type='=>'string'],
'http_send_data' => ['bool', 'data'=>'string'],
'http_send_file' => ['bool', 'file'=>'string'],
'http_send_last_modified' => ['bool', 'timestamp='=>'int'],
'http_send_status' => ['bool', 'status'=>'int'],
'http_send_stream' => ['bool', 'stream'=>'resource'],
'http_support' => ['int', 'feature='=>'int'],
'http_throttle' => ['void', 'sec'=>'float', 'bytes='=>'int'],
'HttpDeflateStream::__construct' => ['void', 'flags='=>'int'],
'HttpDeflateStream::factory' => ['HttpDeflateStream', 'flags='=>'int', 'class_name='=>'string'],
'HttpDeflateStream::finish' => ['string', 'data='=>'string'],
'HttpDeflateStream::flush' => ['string|false', 'data='=>'string'],
'HttpDeflateStream::update' => ['string|false', 'data'=>'string'],
'HttpInflateStream::__construct' => ['void', 'flags='=>'int'],
'HttpInflateStream::factory' => ['HttpInflateStream', 'flags='=>'int', 'class_name='=>'string'],
'HttpInflateStream::finish' => ['string', 'data='=>'string'],
'HttpInflateStream::flush' => ['string|false', 'data='=>'string'],
'HttpInflateStream::update' => ['string|false', 'data'=>'string'],
'HttpMessage::__construct' => ['void', 'message='=>'string'],
'HttpMessage::__toString' => ['string'],
'HttpMessage::addHeaders' => ['void', 'headers'=>'array', 'append='=>'bool'],
'HttpMessage::count' => ['int'],
'HttpMessage::current' => ['mixed'],
'HttpMessage::detach' => ['HttpMessage'],
'HttpMessage::factory' => ['?HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'],
'HttpMessage::fromEnv' => ['?HttpMessage', 'message_type'=>'int', 'class_name='=>'string'],
'HttpMessage::fromString' => ['?HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'],
'HttpMessage::getBody' => ['string'],
'HttpMessage::getHeader' => ['?string', 'header'=>'string'],
'HttpMessage::getHeaders' => ['array'],
'HttpMessage::getHttpVersion' => ['string'],
'HttpMessage::getInfo' => [''],
'HttpMessage::getParentMessage' => ['HttpMessage'],
'HttpMessage::getRequestMethod' => ['string|false'],
'HttpMessage::getRequestUrl' => ['string|false'],
'HttpMessage::getResponseCode' => ['int'],
'HttpMessage::getResponseStatus' => ['string'],
'HttpMessage::getType' => ['int'],
'HttpMessage::guessContentType' => ['string|false', 'magic_file'=>'string', 'magic_mode='=>'int'],
'HttpMessage::key' => ['int|string'],
'HttpMessage::next' => ['void'],
'HttpMessage::prepend' => ['void', 'message'=>'HttpMessage', 'top='=>'bool'],
'HttpMessage::reverse' => ['HttpMessage'],
'HttpMessage::rewind' => ['void'],
'HttpMessage::send' => ['bool'],
'HttpMessage::serialize' => ['string'],
'HttpMessage::setBody' => ['void', 'body'=>'string'],
'HttpMessage::setHeaders' => ['void', 'headers'=>'array'],
'HttpMessage::setHttpVersion' => ['bool', 'version'=>'string'],
'HttpMessage::setInfo' => ['', 'http_info'=>''],
'HttpMessage::setRequestMethod' => ['bool', 'method'=>'string'],
'HttpMessage::setRequestUrl' => ['bool', 'url'=>'string'],
'HttpMessage::setResponseCode' => ['bool', 'code'=>'int'],
'HttpMessage::setResponseStatus' => ['bool', 'status'=>'string'],
'HttpMessage::setType' => ['void', 'type'=>'int'],
'HttpMessage::toMessageTypeObject' => ['HttpRequest|HttpResponse|null'],
'HttpMessage::toString' => ['string', 'include_parent='=>'bool'],
'HttpMessage::unserialize' => ['void', 'serialized'=>'string'],
'HttpMessage::valid' => ['bool'],
'HttpQueryString::__construct' => ['void', 'global='=>'bool', 'add='=>'mixed'],
'HttpQueryString::__toString' => ['string'],
'HttpQueryString::factory' => ['', 'global'=>'', 'params'=>'', 'class_name'=>''],
'HttpQueryString::get' => ['mixed', 'key='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool'],
'HttpQueryString::getArray' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
'HttpQueryString::getBool' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
'HttpQueryString::getFloat' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
'HttpQueryString::getInt' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
'HttpQueryString::getObject' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
'HttpQueryString::getString' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''],
'HttpQueryString::mod' => ['HttpQueryString', 'params'=>'mixed'],
'HttpQueryString::offsetExists' => ['bool', 'offset'=>'mixed'],
'HttpQueryString::offsetGet' => ['mixed', 'offset'=>'mixed'],
'HttpQueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
'HttpQueryString::offsetUnset' => ['void', 'offset'=>'mixed'],
'HttpQueryString::serialize' => ['string'],
'HttpQueryString::set' => ['string', 'params'=>'mixed'],
'HttpQueryString::singleton' => ['HttpQueryString', 'global='=>'bool'],
'HttpQueryString::toArray' => ['array'],
'HttpQueryString::toString' => ['string'],
'HttpQueryString::unserialize' => ['void', 'serialized'=>'string'],
'HttpQueryString::xlate' => ['bool', 'ie'=>'string', 'oe'=>'string'],
'HttpRequest::__construct' => ['void', 'url='=>'string', 'request_method='=>'int', 'options='=>'array'],
'HttpRequest::addBody' => ['', 'request_body_data'=>''],
'HttpRequest::addCookies' => ['bool', 'cookies'=>'array'],
'HttpRequest::addHeaders' => ['bool', 'headers'=>'array'],
'HttpRequest::addPostFields' => ['bool', 'post_data'=>'array'],
'HttpRequest::addPostFile' => ['bool', 'name'=>'string', 'file'=>'string', 'content_type='=>'string'],
'HttpRequest::addPutData' => ['bool', 'put_data'=>'string'],
'HttpRequest::addQueryData' => ['bool', 'query_params'=>'array'],
'HttpRequest::addRawPostData' => ['bool', 'raw_post_data'=>'string'],
'HttpRequest::addSslOptions' => ['bool', 'options'=>'array'],
'HttpRequest::clearHistory' => ['void'],
'HttpRequest::enableCookies' => ['bool'],
'HttpRequest::encodeBody' => ['', 'fields'=>'', 'files'=>''],
'HttpRequest::factory' => ['', 'url'=>'', 'method'=>'', 'options'=>'', 'class_name'=>''],
'HttpRequest::flushCookies' => [''],
'HttpRequest::get' => ['', 'url'=>'', 'options'=>'', '&info'=>''],
'HttpRequest::getBody' => [''],
'HttpRequest::getContentType' => ['string'],
'HttpRequest::getCookies' => ['array'],
'HttpRequest::getHeaders' => ['array'],
'HttpRequest::getHistory' => ['HttpMessage'],
'HttpRequest::getMethod' => ['int'],
'HttpRequest::getOptions' => ['array'],
'HttpRequest::getPostFields' => ['array'],
'HttpRequest::getPostFiles' => ['array'],
'HttpRequest::getPutData' => ['string'],
'HttpRequest::getPutFile' => ['string'],
'HttpRequest::getQueryData' => ['string'],
'HttpRequest::getRawPostData' => ['string'],
'HttpRequest::getRawRequestMessage' => ['string'],
'HttpRequest::getRawResponseMessage' => ['string'],
'HttpRequest::getRequestMessage' => ['HttpMessage'],
'HttpRequest::getResponseBody' => ['string'],
'HttpRequest::getResponseCode' => ['int'],
'HttpRequest::getResponseCookies' => ['stdClass[]', 'flags='=>'int', 'allowed_extras='=>'array'],
'HttpRequest::getResponseData' => ['array'],
'HttpRequest::getResponseHeader' => ['mixed', 'name='=>'string'],
'HttpRequest::getResponseInfo' => ['mixed', 'name='=>'string'],
'HttpRequest::getResponseMessage' => ['HttpMessage'],
'HttpRequest::getResponseStatus' => ['string'],
'HttpRequest::getSslOptions' => ['array'],
'HttpRequest::getUrl' => ['string'],
'HttpRequest::head' => ['', 'url'=>'', 'options'=>'', '&info'=>''],
'HttpRequest::methodExists' => ['', 'method'=>''],
'HttpRequest::methodName' => ['', 'method_id'=>''],
'HttpRequest::methodRegister' => ['', 'method_name'=>''],
'HttpRequest::methodUnregister' => ['', 'method'=>''],
'HttpRequest::postData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''],
'HttpRequest::postFields' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''],
'HttpRequest::putData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''],
'HttpRequest::putFile' => ['', 'url'=>'', 'file'=>'', 'options'=>'', '&info'=>''],
'HttpRequest::putStream' => ['', 'url'=>'', 'stream'=>'', 'options'=>'', '&info'=>''],
'HttpRequest::resetCookies' => ['bool', 'session_only='=>'bool'],
'HttpRequest::send' => ['HttpMessage'],
'HttpRequest::setBody' => ['bool', 'request_body_data='=>'string'],
'HttpRequest::setContentType' => ['bool', 'content_type'=>'string'],
'HttpRequest::setCookies' => ['bool', 'cookies='=>'array'],
'HttpRequest::setHeaders' => ['bool', 'headers='=>'array'],
'HttpRequest::setMethod' => ['bool', 'request_method'=>'int'],
'HttpRequest::setOptions' => ['bool', 'options='=>'array'],
'HttpRequest::setPostFields' => ['bool', 'post_data'=>'array'],
'HttpRequest::setPostFiles' => ['bool', 'post_files'=>'array'],
'HttpRequest::setPutData' => ['bool', 'put_data='=>'string'],
'HttpRequest::setPutFile' => ['bool', 'file='=>'string'],
'HttpRequest::setQueryData' => ['bool', 'query_data'=>'mixed'],
'HttpRequest::setRawPostData' => ['bool', 'raw_post_data='=>'string'],
'HttpRequest::setSslOptions' => ['bool', 'options='=>'array'],
'HttpRequest::setUrl' => ['bool', 'url'=>'string'],
'HttpRequestDataShare::__construct' => ['void'],
'HttpRequestDataShare::__destruct' => ['void'],
'HttpRequestDataShare::attach' => ['', 'request'=>'HttpRequest'],
'HttpRequestDataShare::count' => ['int'],
'HttpRequestDataShare::detach' => ['', 'request'=>'HttpRequest'],
'HttpRequestDataShare::factory' => ['', 'global'=>'', 'class_name'=>''],
'HttpRequestDataShare::reset' => [''],
'HttpRequestDataShare::singleton' => ['', 'global'=>''],
'HttpRequestPool::__construct' => ['void', 'request='=>'HttpRequest'],
'HttpRequestPool::__destruct' => ['void'],
'HttpRequestPool::attach' => ['bool', 'request'=>'HttpRequest'],
'HttpRequestPool::count' => ['int'],
'HttpRequestPool::current' => ['mixed'],
'HttpRequestPool::detach' => ['bool', 'request'=>'HttpRequest'],
'HttpRequestPool::enableEvents' => ['', 'enable'=>''],
'HttpRequestPool::enablePipelining' => ['', 'enable'=>''],
'HttpRequestPool::getAttachedRequests' => ['array'],
'HttpRequestPool::getFinishedRequests' => ['array'],
'HttpRequestPool::key' => ['int|string'],
'HttpRequestPool::next' => ['void'],
'HttpRequestPool::reset' => ['void'],
'HttpRequestPool::rewind' => ['void'],
'HttpRequestPool::send' => ['bool'],
'HttpRequestPool::socketPerform' => ['bool'],
'HttpRequestPool::socketSelect' => ['bool', 'timeout='=>'float'],
'HttpRequestPool::valid' => ['bool'],
'HttpResponse::capture' => ['void'],
'HttpResponse::getBufferSize' => ['int'],
'HttpResponse::getCache' => ['bool'],
'HttpResponse::getCacheControl' => ['string'],
'HttpResponse::getContentDisposition' => ['string'],
'HttpResponse::getContentType' => ['string'],
'HttpResponse::getData' => ['string'],
'HttpResponse::getETag' => ['string'],
'HttpResponse::getFile' => ['string'],
'HttpResponse::getGzip' => ['bool'],
'HttpResponse::getHeader' => ['mixed', 'name='=>'string'],
'HttpResponse::getLastModified' => ['int'],
'HttpResponse::getRequestBody' => ['string'],
'HttpResponse::getRequestBodyStream' => ['resource'],
'HttpResponse::getRequestHeaders' => ['array'],
'HttpResponse::getStream' => ['resource'],
'HttpResponse::getThrottleDelay' => ['float'],
'HttpResponse::guessContentType' => ['string|false', 'magic_file'=>'string', 'magic_mode='=>'int'],
'HttpResponse::redirect' => ['void', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'],
'HttpResponse::send' => ['bool', 'clean_ob='=>'bool'],
'HttpResponse::setBufferSize' => ['bool', 'bytes'=>'int'],
'HttpResponse::setCache' => ['bool', 'cache'=>'bool'],
'HttpResponse::setCacheControl' => ['bool', 'control'=>'string', 'max_age='=>'int', 'must_revalidate='=>'bool'],
'HttpResponse::setContentDisposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'],
'HttpResponse::setContentType' => ['bool', 'content_type'=>'string'],
'HttpResponse::setData' => ['bool', 'data'=>'mixed'],
'HttpResponse::setETag' => ['bool', 'etag'=>'string'],
'HttpResponse::setFile' => ['bool', 'file'=>'string'],
'HttpResponse::setGzip' => ['bool', 'gzip'=>'bool'],
'HttpResponse::setHeader' => ['bool', 'name'=>'string', 'value='=>'mixed', 'replace='=>'bool'],
'HttpResponse::setLastModified' => ['bool', 'timestamp'=>'int'],
'HttpResponse::setStream' => ['bool', 'stream'=>'resource'],
'HttpResponse::setThrottleDelay' => ['bool', 'seconds'=>'float'],
'HttpResponse::status' => ['bool', 'status'=>'int'],
'HttpUtil::buildCookie' => ['', 'cookie_array'=>''],
'HttpUtil::buildStr' => ['', 'query'=>'', 'prefix'=>'', 'arg_sep'=>''],
'HttpUtil::buildUrl' => ['', 'url'=>'', 'parts'=>'', 'flags'=>'', '&composed'=>''],
'HttpUtil::chunkedDecode' => ['', 'encoded_string'=>''],
'HttpUtil::date' => ['', 'timestamp'=>''],
'HttpUtil::deflate' => ['', 'plain'=>'', 'flags'=>''],
'HttpUtil::inflate' => ['', 'encoded'=>''],
'HttpUtil::matchEtag' => ['', 'plain_etag'=>'', 'for_range'=>''],
'HttpUtil::matchModified' => ['', 'last_modified'=>'', 'for_range'=>''],
'HttpUtil::matchRequestHeader' => ['', 'header_name'=>'', 'header_value'=>'', 'case_sensitive'=>''],
'HttpUtil::negotiateCharset' => ['', 'supported'=>'', '&result'=>''],
'HttpUtil::negotiateContentType' => ['', 'supported'=>'', '&result'=>''],
'HttpUtil::negotiateLanguage' => ['', 'supported'=>'', '&result'=>''],
'HttpUtil::parseCookie' => ['', 'cookie_string'=>''],
'HttpUtil::parseHeaders' => ['', 'headers_string'=>''],
'HttpUtil::parseMessage' => ['', 'message_string'=>''],
'HttpUtil::parseParams' => ['', 'param_string'=>'', 'flags'=>''],
'HttpUtil::support' => ['', 'feature'=>''],
'hw_api::checkin' => ['bool', 'parameter'=>'array'],
'hw_api::checkout' => ['bool', 'parameter'=>'array'],
'hw_api::children' => ['array', 'parameter'=>'array'],
'hw_api::content' => ['HW_API_Content', 'parameter'=>'array'],
'hw_api::copy' => ['hw_api_content', 'parameter'=>'array'],
'hw_api::dbstat' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::dcstat' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::dstanchors' => ['array', 'parameter'=>'array'],
'hw_api::dstofsrcanchor' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::find' => ['array', 'parameter'=>'array'],
'hw_api::ftstat' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::hwstat' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::identify' => ['bool', 'parameter'=>'array'],
'hw_api::info' => ['array', 'parameter'=>'array'],
'hw_api::insert' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::insertanchor' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::insertcollection' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::insertdocument' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::link' => ['bool', 'parameter'=>'array'],
'hw_api::lock' => ['bool', 'parameter'=>'array'],
'hw_api::move' => ['bool', 'parameter'=>'array'],
'hw_api::object' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::objectbyanchor' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::parents' => ['array', 'parameter'=>'array'],
'hw_api::remove' => ['bool', 'parameter'=>'array'],
'hw_api::replace' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::setcommittedversion' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::srcanchors' => ['array', 'parameter'=>'array'],
'hw_api::srcsofdst' => ['array', 'parameter'=>'array'],
'hw_api::unlock' => ['bool', 'parameter'=>'array'],
'hw_api::user' => ['hw_api_object', 'parameter'=>'array'],
'hw_api::userlist' => ['array', 'parameter'=>'array'],
'hw_api_attribute' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'],
'hw_api_attribute::key' => ['string'],
'hw_api_attribute::langdepvalue' => ['string', 'language'=>'string'],
'hw_api_attribute::value' => ['string'],
'hw_api_attribute::values' => ['array'],
'hw_api_content' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'],
'hw_api_content::mimetype' => ['string'],
'hw_api_content::read' => ['string', 'buffer'=>'string', 'length'=>'int'],
'hw_api_error::count' => ['int'],
'hw_api_error::reason' => ['HW_API_Reason'],
'hw_api_object' => ['hw_api_object', 'parameter'=>'array'],
'hw_api_object::assign' => ['bool', 'parameter'=>'array'],
'hw_api_object::attreditable' => ['bool', 'parameter'=>'array'],
'hw_api_object::count' => ['int', 'parameter'=>'array'],
'hw_api_object::insert' => ['bool', 'attribute'=>'hw_api_attribute'],
'hw_api_object::remove' => ['bool', 'name'=>'string'],
'hw_api_object::title' => ['string', 'parameter'=>'array'],
'hw_api_object::value' => ['string', 'name'=>'string'],
'hw_api_reason::description' => ['string'],
'hw_api_reason::type' => ['HW_API_Reason'],
'hw_Array2Objrec' => ['string', 'object_array'=>'array'],
'hw_changeobject' => ['bool', 'link'=>'int', 'objid'=>'int', 'attributes'=>'array'],
'hw_Children' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_ChildrenObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_Close' => ['bool', 'connection'=>'int'],
'hw_Connect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'],
'hw_connection_info' => ['', 'link'=>'int'],
'hw_cp' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'destination_id'=>'int'],
'hw_Deleteobject' => ['bool', 'connection'=>'int', 'object_to_delete'=>'int'],
'hw_DocByAnchor' => ['int', 'connection'=>'int', 'anchorid'=>'int'],
'hw_DocByAnchorObj' => ['string', 'connection'=>'int', 'anchorid'=>'int'],
'hw_Document_Attributes' => ['string', 'hw_document'=>'int'],
'hw_Document_BodyTag' => ['string', 'hw_document'=>'int', 'prefix='=>'string'],
'hw_Document_Content' => ['string', 'hw_document'=>'int'],
'hw_Document_SetContent' => ['bool', 'hw_document'=>'int', 'content'=>'string'],
'hw_Document_Size' => ['int', 'hw_document'=>'int'],
'hw_dummy' => ['string', 'link'=>'int', 'id'=>'int', 'msgid'=>'int'],
'hw_EditText' => ['bool', 'connection'=>'int', 'hw_document'=>'int'],
'hw_Error' => ['int', 'connection'=>'int'],
'hw_ErrorMsg' => ['string', 'connection'=>'int'],
'hw_Free_Document' => ['bool', 'hw_document'=>'int'],
'hw_GetAnchors' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetAnchorsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetAndLock' => ['string', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetChildColl' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetChildCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetChildDocColl' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetChildDocCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetObject' => ['', 'connection'=>'int', 'objectid'=>'', 'query='=>'string'],
'hw_GetObjectByQuery' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'],
'hw_GetObjectByQueryColl' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'],
'hw_GetObjectByQueryCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'],
'hw_GetObjectByQueryObj' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'],
'hw_GetParents' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetParentsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_getrellink' => ['string', 'link'=>'int', 'rootid'=>'int', 'sourceid'=>'int', 'destid'=>'int'],
'hw_GetRemote' => ['int', 'connection'=>'int', 'objectid'=>'int'],
'hw_getremotechildren' => ['', 'connection'=>'int', 'object_record'=>'string'],
'hw_GetSrcByDestObj' => ['array', 'connection'=>'int', 'objectid'=>'int'],
'hw_GetText' => ['int', 'connection'=>'int', 'objectid'=>'int', 'prefix='=>''],
'hw_getusername' => ['string', 'connection'=>'int'],
'hw_Identify' => ['string', 'link'=>'int', 'username'=>'string', 'password'=>'string'],
'hw_InCollections' => ['array', 'connection'=>'int', 'object_id_array'=>'array', 'collection_id_array'=>'array', 'return_collections'=>'int'],
'hw_Info' => ['string', 'connection'=>'int'],
'hw_InsColl' => ['int', 'connection'=>'int', 'objectid'=>'int', 'object_array'=>'array'],
'hw_InsDoc' => ['int', 'connection'=>'', 'parentid'=>'int', 'object_record'=>'string', 'text='=>'string'],
'hw_insertanchors' => ['bool', 'hwdoc'=>'int', 'anchorecs'=>'array', 'dest'=>'array', 'urlprefixes='=>'array'],
'hw_InsertDocument' => ['int', 'connection'=>'int', 'parent_id'=>'int', 'hw_document'=>'int'],
'hw_InsertObject' => ['int', 'connection'=>'int', 'object_rec'=>'string', 'parameter'=>'string'],
'hw_mapid' => ['int', 'connection'=>'int', 'server_id'=>'int', 'object_id'=>'int'],
'hw_Modifyobject' => ['bool', 'connection'=>'int', 'object_to_change'=>'int', 'remove'=>'array', 'add'=>'array', 'mode='=>'int'],
'hw_mv' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'source_id'=>'int', 'destination_id'=>'int'],
'hw_New_Document' => ['int', 'object_record'=>'string', 'document_data'=>'string', 'document_size'=>'int'],
'hw_objrec2array' => ['array', 'object_record'=>'string', 'format='=>'array'],
'hw_Output_Document' => ['bool', 'hw_document'=>'int'],
'hw_pConnect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'],
'hw_PipeDocument' => ['int', 'connection'=>'int', 'objectid'=>'int', 'url_prefixes='=>'array'],
'hw_Root' => ['int'],
'hw_setlinkroot' => ['int', 'link'=>'int', 'rootid'=>'int'],
'hw_stat' => ['string', 'link'=>'int'],
'hw_Unlock' => ['bool', 'connection'=>'int', 'objectid'=>'int'],
'hw_Who' => ['array', 'connection'=>'int'],
'hwapi_attribute_new' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'],
'hwapi_content_new' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'],
'hwapi_hgcsp' => ['HW_API', 'hostname'=>'string', 'port='=>'int'],
'hwapi_object_new' => ['hw_api_object', 'parameter'=>'array'],
'hypot' => ['float', 'x'=>'float', 'y'=>'float'],
'ibase_add_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'],
'ibase_affected_rows' => ['int', 'link_identifier='=>'resource'],
'ibase_backup' => ['mixed', 'service_handle'=>'resource', 'source_db'=>'string', 'dest_file'=>'string', 'options='=>'int', 'verbose='=>'bool'],
'ibase_blob_add' => ['void', 'blob_handle'=>'resource', 'data'=>'string'],
'ibase_blob_cancel' => ['bool', 'blob_handle'=>'resource'],
'ibase_blob_close' => ['string|bool', 'blob_handle'=>'resource'],
'ibase_blob_create' => ['resource', 'link_identifier='=>'resource'],
'ibase_blob_echo' => ['bool', 'link_identifier'=>'', 'blob_id'=>'string'],
'ibase_blob_echo\'1' => ['bool', 'blob_id'=>'string'],
'ibase_blob_get' => ['string|false', 'blob_handle'=>'resource', 'length'=>'int'],
'ibase_blob_import' => ['string|false', 'link_identifier'=>'resource', 'file_handle'=>'resource'],
'ibase_blob_info' => ['array', 'link_identifier'=>'resource', 'blob_id'=>'string'],
'ibase_blob_info\'1' => ['array', 'blob_id'=>'string'],
'ibase_blob_open' => ['resource|false', 'link_identifier'=>'', 'blob_id'=>'string'],
'ibase_blob_open\'1' => ['resource', 'blob_id'=>'string'],
'ibase_close' => ['bool', 'link_identifier='=>'resource'],
'ibase_commit' => ['bool', 'link_identifier='=>'resource'],
'ibase_commit_ret' => ['bool', 'link_identifier='=>'resource'],
'ibase_connect' => ['resource|false', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'],
'ibase_db_info' => ['string', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'],
'ibase_delete_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password='=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'],
'ibase_drop_db' => ['bool', 'link_identifier='=>'resource'],
'ibase_errcode' => ['int|false'],
'ibase_errmsg' => ['string|false'],
'ibase_execute' => ['resource|false', 'query'=>'resource', 'bind_arg='=>'mixed', '...args='=>'mixed'],
'ibase_fetch_assoc' => ['array|false', 'result'=>'resource', 'fetch_flags='=>'int'],
'ibase_fetch_object' => ['object|false', 'result'=>'resource', 'fetch_flags='=>'int'],
'ibase_fetch_row' => ['array|false', 'result'=>'resource', 'fetch_flags='=>'int'],
'ibase_field_info' => ['array', 'query_result'=>'resource', 'field_number'=>'int'],
'ibase_free_event_handler' => ['bool', 'event'=>'resource'],
'ibase_free_query' => ['bool', 'query'=>'resource'],
'ibase_free_result' => ['bool', 'result'=>'resource'],
'ibase_gen_id' => ['int|string', 'generator'=>'string', 'increment='=>'int', 'link_identifier='=>'resource'],
'ibase_maintain_db' => ['bool', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'],
'ibase_modify_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'],
'ibase_name_result' => ['bool', 'result'=>'resource', 'name'=>'string'],
'ibase_num_fields' => ['int', 'query_result'=>'resource'],
'ibase_num_params' => ['int', 'query'=>'resource'],
'ibase_num_rows' => ['int', 'result_identifier'=>''],
'ibase_param_info' => ['array', 'query'=>'resource', 'field_number'=>'int'],
'ibase_pconnect' => ['resource|false', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'],
'ibase_prepare' => ['resource|false', 'link_identifier'=>'', 'query'=>'string', 'trans_identifier'=>''],
'ibase_query' => ['resource|false', 'link_identifier='=>'resource', 'string='=>'string', 'bind_arg='=>'int', '...args='=>''],
'ibase_restore' => ['mixed', 'service_handle'=>'resource', 'source_file'=>'string', 'dest_db'=>'string', 'options='=>'int', 'verbose='=>'bool'],
'ibase_rollback' => ['bool', 'link_identifier='=>'resource'],
'ibase_rollback_ret' => ['bool', 'link_identifier='=>'resource'],
'ibase_server_info' => ['string', 'service_handle'=>'resource', 'action'=>'int'],
'ibase_service_attach' => ['resource', 'host'=>'string', 'dba_username'=>'string', 'dba_password'=>'string'],
'ibase_service_detach' => ['bool', 'service_handle'=>'resource'],
'ibase_set_event_handler' => ['resource', 'link_identifier'=>'', 'callback'=>'callable', 'event='=>'string', '...args='=>''],
'ibase_set_event_handler\'1' => ['resource', 'callback'=>'callable', 'event'=>'string', '...args'=>''],
'ibase_timefmt' => ['bool', 'format'=>'string', 'columntype='=>'int'],
'ibase_trans' => ['resource|false', 'trans_args='=>'int', 'link_identifier='=>'', '...args='=>''],
'ibase_wait_event' => ['string', 'link_identifier'=>'', 'event='=>'string', '...args='=>''],
'ibase_wait_event\'1' => ['string', 'event'=>'string', '...args'=>''],
'iconv' => ['string|false', 'from_encoding'=>'string', 'to_encoding'=>'string', 'string'=>'string'],
'iconv_get_encoding' => ['array|string|false', 'type='=>'string'],
'iconv_mime_decode' => ['string|false', 'string'=>'string', 'mode='=>'int', 'encoding='=>'?string'],
'iconv_mime_decode_headers' => ['array|false', 'headers'=>'string', 'mode='=>'int', 'encoding='=>'?string'],
'iconv_mime_encode' => ['string|false', 'field_name'=>'string', 'field_value'=>'string', 'options='=>'array'],
'iconv_set_encoding' => ['bool', 'type'=>'string', 'encoding'=>'string'],
'iconv_strlen' => ['0|positive-int|false', 'string'=>'string', 'encoding='=>'?string'],
'iconv_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'?string'],
'iconv_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'?string'],
'iconv_substr' => ['string|false', 'string'=>'string', 'offset'=>'int', 'length='=>'?int', 'encoding='=>'?string'],
'id3_get_frame_long_name' => ['string', 'frameid'=>'string'],
'id3_get_frame_short_name' => ['string', 'frameid'=>'string'],
'id3_get_genre_id' => ['int', 'genre'=>'string'],
'id3_get_genre_list' => ['array'],
'id3_get_genre_name' => ['string', 'genre_id'=>'int'],
'id3_get_tag' => ['array', 'filename'=>'string', 'version='=>'int'],
'id3_get_version' => ['int', 'filename'=>'string'],
'id3_remove_tag' => ['bool', 'filename'=>'string', 'version='=>'int'],
'id3_set_tag' => ['bool', 'filename'=>'string', 'tag'=>'array', 'version='=>'int'],
'idate' => ['int', 'format'=>'string', 'timestamp='=>'?int'],
'idn_strerror' => ['string', 'errorcode'=>'int'],
'idn_to_ascii' => ['string|false', 'domain'=>'string', 'flags='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'],
'idn_to_utf8' => ['string|false', 'domain'=>'string', 'flags='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'],
'ifx_affected_rows' => ['int', 'result_id'=>'resource'],
'ifx_blobinfile_mode' => ['bool', 'mode'=>'int'],
'ifx_byteasvarchar' => ['bool', 'mode'=>'int'],
'ifx_close' => ['bool', 'link_identifier='=>'resource'],
'ifx_connect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'],
'ifx_copy_blob' => ['int', 'bid'=>'int'],
'ifx_create_blob' => ['int', 'type'=>'int', 'mode'=>'int', 'param'=>'string'],
'ifx_create_char' => ['int', 'param'=>'string'],
'ifx_do' => ['bool', 'result_id'=>'resource'],
'ifx_error' => ['string', 'link_identifier='=>'resource'],
'ifx_errormsg' => ['string', 'errorcode='=>'int'],
'ifx_fetch_row' => ['array', 'result_id'=>'resource', 'position='=>'mixed'],
'ifx_fieldproperties' => ['array', 'result_id'=>'resource'],
'ifx_fieldtypes' => ['array', 'result_id'=>'resource'],
'ifx_free_blob' => ['bool', 'bid'=>'int'],
'ifx_free_char' => ['bool', 'bid'=>'int'],
'ifx_free_result' => ['bool', 'result_id'=>'resource'],
'ifx_get_blob' => ['string', 'bid'=>'int'],
'ifx_get_char' => ['string', 'bid'=>'int'],
'ifx_getsqlca' => ['array', 'result_id'=>'resource'],
'ifx_htmltbl_result' => ['int', 'result_id'=>'resource', 'html_table_options='=>'string'],
'ifx_nullformat' => ['bool', 'mode'=>'int'],
'ifx_num_fields' => ['int', 'result_id'=>'resource'],
'ifx_num_rows' => ['int', 'result_id'=>'resource'],
'ifx_pconnect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'],
'ifx_prepare' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_def='=>'int', 'blobidarray='=>'mixed'],
'ifx_query' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_type='=>'int', 'blobidarray='=>'mixed'],
'ifx_textasvarchar' => ['bool', 'mode'=>'int'],
'ifx_update_blob' => ['bool', 'bid'=>'int', 'content'=>'string'],
'ifx_update_char' => ['bool', 'bid'=>'int', 'content'=>'string'],
'ifxus_close_slob' => ['bool', 'bid'=>'int'],
'ifxus_create_slob' => ['int', 'mode'=>'int'],
'ifxus_free_slob' => ['bool', 'bid'=>'int'],
'ifxus_open_slob' => ['int', 'bid'=>'int', 'mode'=>'int'],
'ifxus_read_slob' => ['string', 'bid'=>'int', 'nbytes'=>'int'],
'ifxus_seek_slob' => ['int', 'bid'=>'int', 'mode'=>'int', 'offset'=>'int'],
'ifxus_tell_slob' => ['int', 'bid'=>'int'],
'ifxus_write_slob' => ['int', 'bid'=>'int', 'content'=>'string'],
'igbinary_serialize' => ['string|false', 'value'=>'mixed'],
'igbinary_unserialize' => ['mixed', 'string'=>'string'],
'ignore_user_abort' => ['int', 'enable='=>'?bool'],
'iis_add_server' => ['int', 'path'=>'string', 'comment'=>'string', 'server_ip'=>'string', 'port'=>'int', 'host_name'=>'string', 'rights'=>'int', 'start_server'=>'int'],
'iis_get_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'],
'iis_get_script_map' => ['string', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string'],
'iis_get_server_by_comment' => ['int', 'comment'=>'string'],
'iis_get_server_by_path' => ['int', 'path'=>'string'],
'iis_get_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'],
'iis_get_service_state' => ['int', 'service_id'=>'string'],
'iis_remove_server' => ['int', 'server_instance'=>'int'],
'iis_set_app_settings' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'application_scope'=>'string'],
'iis_set_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'],
'iis_set_script_map' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string', 'engine_path'=>'string', 'allow_scripting'=>'int'],
'iis_set_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'],
'iis_start_server' => ['int', 'server_instance'=>'int'],
'iis_start_service' => ['int', 'service_id'=>'string'],
'iis_stop_server' => ['int', 'server_instance'=>'int'],
'iis_stop_service' => ['int', 'service_id'=>'string'],
'image_type_to_extension' => ['string', 'image_type'=>'int', 'include_dot='=>'bool'],
'image_type_to_mime_type' => ['string', 'image_type'=>'int'],
'imageaffine' => ['false|GdImage', 'image'=>'GdImage', 'affine'=>'array', 'clip='=>'?array'],
'imageaffinematrixconcat' => ['array{0:float,1:float,2:float,3:float,4:float,5:float}|false', 'matrix1'=>'array', 'matrix2'=>'array'],
'imageaffinematrixget' => ['array{0:float,1:float,2:float,3:float,4:float,5:float}|false', 'type'=>'int', 'options'=>'array|float'],
'imagealphablending' => ['bool', 'image'=>'GdImage', 'enable'=>'bool'],
'imageantialias' => ['bool', 'image'=>'GdImage', 'enable'=>'bool'],
'imagearc' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int'],
'imageavif' => ['bool', 'image'=>'GdImage', 'file='=>'resource|string|null', 'quality='=>'int', 'speed='=>'int'],
'imagebmp' => ['bool', 'image'=>'GdImage', 'file='=>'resource|string|null', 'compressed='=>'bool'],
'imagechar' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
'imagecharup' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'char'=>'string', 'color'=>'int'],
'imagecolorallocate' => ['int|false', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
'imagecolorallocatealpha' => ['int|false', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
'imagecolorat' => ['int|false', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int'],
'imagecolorclosest' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
'imagecolorclosestalpha' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
'imagecolorclosesthwb' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
'imagecolordeallocate' => ['bool', 'image'=>'GdImage', 'color'=>'int'],
'imagecolorexact' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
'imagecolorexactalpha' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
'imagecolormatch' => ['bool', 'image1'=>'GdImage', 'image2'=>'GdImage'],
'imagecolorresolve' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
'imagecolorresolvealpha' => ['int', 'image'=>'GdImage', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'],
'imagecolorset' => ['false|null', 'image'=>'GdImage', 'color'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'],
'imagecolorsforindex' => ['array', 'image'=>'GdImage', 'color'=>'int'],
'imagecolorstotal' => ['int', 'image'=>'GdImage'],
'imagecolortransparent' => ['int', 'image'=>'GdImage', 'color='=>'?int'],
'imageconvolution' => ['bool', 'image'=>'GdImage', 'matrix'=>'array', 'divisor'=>'float', 'offset'=>'float'],
'imagecopy' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
'imagecopymerge' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
'imagecopymergegray' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_width'=>'int', 'src_height'=>'int', 'pct'=>'int'],
'imagecopyresampled' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
'imagecopyresized' => ['bool', 'dst_image'=>'GdImage', 'src_image'=>'GdImage', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_width'=>'int', 'dst_height'=>'int', 'src_width'=>'int', 'src_height'=>'int'],
'imagecreate' => ['false|GdImage', 'width'=>'int', 'height'=>'int'],
'imagecreatefromavif' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefrombmp' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromgd' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromgd2' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromgd2part' => ['false|GdImage', 'filename'=>'string', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int'],
'imagecreatefromgif' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromjpeg' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefrompng' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromstring' => ['false|GdImage', 'data'=>'string'],
'imagecreatefromwbmp' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromwebp' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromxbm' => ['false|GdImage', 'filename'=>'string'],
'imagecreatefromxpm' => ['false|GdImage', 'filename'=>'string'],
'imagecreatetruecolor' => ['false|GdImage', 'width'=>'int', 'height'=>'int'],
'imagecrop' => ['false|GdImage', 'image'=>'GdImage', 'rectangle'=>'array'],
'imagecropauto' => ['false|GdImage', 'image'=>'GdImage', 'mode='=>'int', 'threshold='=>'float', 'color='=>'int'],
'imagedashedline' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
'imagedestroy' => ['bool', 'image'=>'GdImage'],
'imageellipse' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
'imagefill' => ['bool', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
'imagefilledarc' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'start_angle'=>'int', 'end_angle'=>'int', 'color'=>'int', 'style'=>'int'],
'imagefilledellipse' => ['bool', 'image'=>'GdImage', 'center_x'=>'int', 'center_y'=>'int', 'width'=>'int', 'height'=>'int', 'color'=>'int'],
'imagefilledpolygon' => ['bool', 'image'=>'GdImage', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
'imagefilledrectangle' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
'imagefilltoborder' => ['bool', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int', 'border_color'=>'int', 'color'=>'int'],
'imagefilter' => ['bool', 'image'=>'GdImage', 'filter'=>'int', 'args='=>'int', 'arg2='=>'int', 'arg3='=>'int', 'arg4='=>'int'],
'imageflip' => ['bool', 'image'=>'GdImage', 'mode'=>'int'],
'imagefontheight' => ['int', 'font'=>'int'],
'imagefontwidth' => ['int', 'font'=>'int'],
'imageftbbox' => ['array|false', 'size'=>'float', 'angle'=>'float', 'font_filename'=>'string', 'string'=>'string', 'options='=>'array'],
'imagefttext' => ['array|false', 'image'=>'GdImage', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string', 'options='=>'array'],
'imagegammacorrect' => ['bool', 'image'=>'GdImage', 'input_gamma'=>'float', 'output_gamma'=>'float'],
'imagegd' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null'],
'imagegd2' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'chunk_size='=>'int', 'mode='=>'int'],
'imagegetclip' => ['array<int,int>', 'image'=>'GdImage'],
'imagegetinterpolation' => ['int', 'image'=>'GdImage'],
'imagegif' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null'],
'imagegrabscreen' => ['false|GdImage'],
'imagegrabwindow' => ['false|GdImage', 'handle'=>'int', 'client_area='=>'int'],
'imageinterlace' => ['bool', 'image'=>'GdImage', 'enable='=>'bool|null'],
'imageistruecolor' => ['bool', 'image'=>'GdImage'],
'imagejpeg' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'quality='=>'int'],
'imagelayereffect' => ['bool', 'image'=>'GdImage', 'effect'=>'int'],
'imageline' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
'imageloadfont' => ['GdFont|false', 'filename'=>'string'],
'imageObj::pasteImage' => ['void', 'srcImg'=>'imageObj', 'transparentColorHex'=>'int', 'dstX'=>'int', 'dstY'=>'int', 'angle'=>'int'],
'imageObj::saveImage' => ['int', 'filename'=>'string', 'oMap'=>'mapObj'],
'imageObj::saveWebImage' => ['string'],
'imageopenpolygon' => ['bool', 'image'=>'GdImage', 'points'=>'array', 'num_points'=>'int', 'color'=>'int'],
'imagepalettecopy' => ['void', 'dst'=>'GdImage', 'src'=>'GdImage'],
'imagepalettetotruecolor' => ['bool', 'image'=>'GdImage'],
'imagepng' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'quality='=>'int', 'filters='=>'int'],
'imagepolygon' => ['bool', 'image'=>'GdImage', 'points'=>'array', 'num_points_or_color'=>'int', 'color'=>'int'],
'imagerectangle' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'color'=>'int'],
'imageresolution' => ['array|bool', 'image'=>'GdImage', 'resolution_x='=>'?int', 'resolution_y='=>'?int'],
'imagerotate' => ['false|GdImage', 'image'=>'GdImage', 'angle'=>'float', 'background_color'=>'int', 'ignore_transparent='=>'int'],
'imagesavealpha' => ['bool', 'image'=>'GdImage', 'enable'=>'bool'],
'imagescale' => ['false|GdImage', 'image'=>'GdImage', 'width'=>'int', 'height='=>'int', 'mode='=>'int'],
'imagesetbrush' => ['bool', 'image'=>'GdImage', 'brush'=>'GdImage'],
'imagesetclip' => ['bool', 'image'=>'GdImage', 'x1'=>'int', 'x2'=>'int', 'y1'=>'int', 'y2'=>'int'],
'imagesetinterpolation' => ['bool', 'image'=>'GdImage', 'method'=>'int'],
'imagesetpixel' => ['bool', 'image'=>'GdImage', 'x'=>'int', 'y'=>'int', 'color'=>'int'],
'imagesetstyle' => ['bool', 'image'=>'GdImage', 'style'=>'non-empty-array'],
'imagesetthickness' => ['bool', 'image'=>'GdImage', 'thickness'=>'int'],
'imagesettile' => ['bool', 'image'=>'GdImage', 'tile'=>'GdImage'],
'imagestring' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
'imagestringup' => ['bool', 'image'=>'GdImage', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'string'=>'string', 'color'=>'int'],
'imagesx' => ['int', 'image'=>'GdImage'],
'imagesy' => ['int', 'image'=>'GdImage'],
'imagetruecolortopalette' => ['bool', 'image'=>'GdImage', 'dither'=>'bool', 'num_colors'=>'int'],
'imagettfbbox' => ['false|array', 'size'=>'float', 'angle'=>'float', 'font_filename'=>'string', 'string'=>'string'],
'imagettftext' => ['false|array', 'image'=>'GdImage', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'color'=>'int', 'font_filename'=>'string', 'text'=>'string'],
'imagetypes' => ['int'],
'imagewbmp' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'foreground_color='=>'?int'],
'imagewebp' => ['bool', 'image'=>'GdImage', 'file='=>'string|resource|null', 'quality='=>'int'],
'imagexbm' => ['bool', 'image'=>'GdImage', 'filename='=>'?string', 'foreground_color='=>'int'],
'Imagick::__construct' => ['void', 'files='=>'string|string[]'],
'Imagick::__toString' => ['string'],
'Imagick::adaptiveBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
'Imagick::adaptiveResizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool'],
'Imagick::adaptiveSharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
'Imagick::adaptiveThresholdImage' => ['bool', 'width'=>'int', 'height'=>'int', 'offset'=>'int'],
'Imagick::addImage' => ['bool', 'source'=>'Imagick'],
'Imagick::addNoiseImage' => ['bool', 'noise_type'=>'int', 'channel='=>'int'],
'Imagick::affineTransformImage' => ['bool', 'matrix'=>'ImagickDraw'],
'Imagick::animateImages' => ['bool', 'x_server'=>'string'],
'Imagick::annotateImage' => ['bool', 'draw_settings'=>'ImagickDraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'],
'Imagick::appendImages' => ['Imagick', 'stack'=>'bool'],
'Imagick::autoGammaImage' => ['bool', 'channel='=>'int'],
'Imagick::autoLevelImage' => ['void', 'CHANNEL='=>'string'],
'Imagick::autoOrient' => ['bool'],
'Imagick::averageImages' => ['Imagick'],
'Imagick::blackThresholdImage' => ['bool', 'threshold'=>'mixed'],
'Imagick::blueShiftImage' => ['void', 'factor='=>'float'],
'Imagick::blurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
'Imagick::borderImage' => ['bool', 'bordercolor'=>'mixed', 'width'=>'int', 'height'=>'int'],
'Imagick::brightnessContrastImage' => ['void', 'brightness'=>'string', 'contrast'=>'string', 'CHANNEL='=>'string'],
'Imagick::charcoalImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'],
'Imagick::chopImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Imagick::clampImage' => ['void', 'CHANNEL='=>'string'],
'Imagick::clear' => ['bool'],
'Imagick::clipImage' => ['bool'],
'Imagick::clipImagePath' => ['void', 'pathname'=>'string', 'inside'=>'string'],
'Imagick::clipPathImage' => ['bool', 'pathname'=>'string', 'inside'=>'bool'],
'Imagick::clone' => ['Imagick'],
'Imagick::clutImage' => ['bool', 'lookup_table'=>'Imagick', 'channel='=>'float'],
'Imagick::coalesceImages' => ['Imagick'],
'Imagick::colorFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'],
'Imagick::colorizeImage' => ['bool', 'colorize'=>'mixed', 'opacity'=>'mixed'],
'Imagick::colorMatrixImage' => ['void', 'color_matrix'=>'string'],
'Imagick::combineImages' => ['Imagick', 'channeltype'=>'int'],
'Imagick::commentImage' => ['bool', 'comment'=>'string'],
'Imagick::compareImageChannels' => ['array{Imagick, float}', 'image'=>'Imagick', 'channeltype'=>'int', 'metrictype'=>'int'],
'Imagick::compareImageLayers' => ['Imagick', 'method'=>'int'],
'Imagick::compareImages' => ['array{Imagick, float}', 'compare'=>'Imagick', 'metric'=>'int'],
'Imagick::compositeImage' => ['bool', 'composite_object'=>'Imagick', 'composite'=>'int', 'x'=>'int', 'y'=>'int', 'channel='=>'int'],
'Imagick::compositeImageGravity' => ['bool', 'Imagick'=>'Imagick', 'COMPOSITE_CONSTANT'=>'int', 'GRAVITY_CONSTANT'=>'int'],
'Imagick::contrastImage' => ['bool', 'sharpen'=>'bool'],
'Imagick::contrastStretchImage' => ['bool', 'black_point'=>'float', 'white_point'=>'float', 'channel='=>'int'],
'Imagick::convolveImage' => ['bool', 'kernel'=>'array', 'channel='=>'int'],
'Imagick::count' => ['void', 'mode='=>'string'],
'Imagick::cropImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Imagick::cropThumbnailImage' => ['bool', 'width'=>'int', 'height'=>'int', 'legacy='=>'bool'],
'Imagick::current' => ['Imagick'],
'Imagick::cycleColormapImage' => ['bool', 'displace'=>'int'],
'Imagick::decipherImage' => ['bool', 'passphrase'=>'string'],
'Imagick::deconstructImages' => ['Imagick'],
'Imagick::deleteImageArtifact' => ['bool', 'artifact'=>'string'],
'Imagick::deleteImageProperty' => ['void', 'name'=>'string'],
'Imagick::deskewImage' => ['bool', 'threshold'=>'float'],
'Imagick::despeckleImage' => ['bool'],
'Imagick::destroy' => ['bool'],
'Imagick::displayImage' => ['bool', 'servername'=>'string'],
'Imagick::displayImages' => ['bool', 'servername'=>'string'],
'Imagick::distortImage' => ['bool', 'method'=>'int', 'arguments'=>'array', 'bestfit'=>'bool'],
'Imagick::drawImage' => ['bool', 'draw'=>'ImagickDraw'],
'Imagick::edgeImage' => ['bool', 'radius'=>'float'],
'Imagick::embossImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'],
'Imagick::encipherImage' => ['bool', 'passphrase'=>'string'],
'Imagick::enhanceImage' => ['bool'],
'Imagick::equalizeImage' => ['bool'],
'Imagick::evaluateImage' => ['bool', 'op'=>'int', 'constant'=>'float', 'channel='=>'int'],
'Imagick::evaluateImages' => ['bool', 'EVALUATE_CONSTANT'=>'int'],
'Imagick::exportImagePixels' => ['list<int>', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int'],
'Imagick::extentImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Imagick::filter' => ['void', 'ImagickKernel'=>'ImagickKernel', 'CHANNEL='=>'int'],
'Imagick::flattenImages' => ['Imagick'],
'Imagick::flipImage' => ['bool'],
'Imagick::floodFillPaintImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'target'=>'mixed', 'x'=>'int', 'y'=>'int', 'invert'=>'bool', 'channel='=>'int'],
'Imagick::flopImage' => ['bool'],
'Imagick::forwardFourierTransformimage' => ['void', 'magnitude'=>'bool'],
'Imagick::frameImage' => ['bool', 'matte_color'=>'mixed', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'],
'Imagick::functionImage' => ['bool', 'function'=>'int', 'arguments'=>'array', 'channel='=>'int'],
'Imagick::fxImage' => ['Imagick', 'expression'=>'string', 'channel='=>'int'],
'Imagick::gammaImage' => ['bool', 'gamma'=>'float', 'channel='=>'int'],
'Imagick::gaussianBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
'Imagick::getColorspace' => ['int'],
'Imagick::getCompression' => ['int'],
'Imagick::getCompressionQuality' => ['int'],
'Imagick::getConfigureOptions' => ['string'],
'Imagick::getCopyright' => ['string'],
'Imagick::getFeatures' => ['string'],
'Imagick::getFilename' => ['string'],
'Imagick::getFont' => ['string|false'],
'Imagick::getFormat' => ['string'],
'Imagick::getGravity' => ['int'],
'Imagick::getHDRIEnabled' => ['int'],
'Imagick::getHomeURL' => ['string'],
'Imagick::getImage' => ['Imagick'],
'Imagick::getImageAlphaChannel' => ['int'],
'Imagick::getImageArtifact' => ['string', 'artifact'=>'string'],
'Imagick::getImageAttribute' => ['string', 'key'=>'string'],
'Imagick::getImageBackgroundColor' => ['ImagickPixel'],
'Imagick::getImageBlob' => ['string'],
'Imagick::getImageBluePrimary' => ['array{x:float, y:float}'],
'Imagick::getImageBorderColor' => ['ImagickPixel'],
'Imagick::getImageChannelDepth' => ['int', 'channel'=>'int'],
'Imagick::getImageChannelDistortion' => ['float', 'reference'=>'Imagick', 'channel'=>'int', 'metric'=>'int'],
'Imagick::getImageChannelDistortions' => ['float', 'reference'=>'Imagick', 'metric'=>'int', 'channel='=>'int'],
'Imagick::getImageChannelExtrema' => ['array{minima:int, maxima:int}', 'channel'=>'int'],
'Imagick::getImageChannelKurtosis' => ['array{kurtosis:float, skewness:float}', 'channel='=>'int'],
'Imagick::getImageChannelMean' => ['array{mean:float, standardDeviation:float}', 'channel'=>'int'],
'Imagick::getImageChannelRange' => ['array{minima:float, maxima:float}', 'channel'=>'int'],
'Imagick::getImageChannelStatistics' => ['array<int, array{mean:float, minima:float, maxima:float, standardDeviation:float, depth:int}>'],
'Imagick::getImageClipMask' => ['Imagick'],
'Imagick::getImageColormapColor' => ['ImagickPixel', 'index'=>'int'],
'Imagick::getImageColors' => ['int'],
'Imagick::getImageColorspace' => ['int'],
'Imagick::getImageCompose' => ['int'],
'Imagick::getImageCompression' => ['int'],
'Imagick::getImageCompressionQuality' => ['int'],
'Imagick::getImageDelay' => ['int'],
'Imagick::getImageDepth' => ['int'],
'Imagick::getImageDispose' => ['int'],
'Imagick::getImageDistortion' => ['float', 'reference'=>'magickwand', 'metric'=>'int'],
'Imagick::getImageExtrema' => ['array{min:int, max:int}'],
'Imagick::getImageFilename' => ['string'],
'Imagick::getImageFormat' => ['string'],
'Imagick::getImageGamma' => ['float'],
'Imagick::getImageGeometry' => ['array{width:int, height:int}'],
'Imagick::getImageGravity' => ['int'],
'Imagick::getImageGreenPrimary' => ['array{x:float, y:float}'],
'Imagick::getImageHeight' => ['int'],
'Imagick::getImageHistogram' => ['list<ImagickPixel>'],
'Imagick::getImageIndex' => ['int'],
'Imagick::getImageInterlaceScheme' => ['int'],
'Imagick::getImageInterpolateMethod' => ['int'],
'Imagick::getImageIterations' => ['int'],
'Imagick::getImageLength' => ['int'],
'Imagick::getImageMagickLicense' => ['string'],
'Imagick::getImageMatte' => ['bool'],
'Imagick::getImageMatteColor' => ['ImagickPixel'],
'Imagick::getImageMimeType' => ['string'],
'Imagick::getImageOrientation' => ['int'],
'Imagick::getImagePage' => ['array{width:int, height:int, x:int, y:int}'],
'Imagick::getImagePixelColor' => ['ImagickPixel', 'x'=>'int', 'y'=>'int'],
'Imagick::getImageProfile' => ['string', 'name'=>'string'],
'Imagick::getImageProfiles' => ['array', 'pattern='=>'string', 'only_names='=>'bool'],
'Imagick::getImageProperties' => ['array<int|string, string>', 'pattern='=>'string', 'only_names='=>'bool'],
'Imagick::getImageProperty' => ['string|false', 'name'=>'string'],
'Imagick::getImageRedPrimary' => ['array{x:float, y:float}'],
'Imagick::getImageRegion' => ['Imagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Imagick::getImageRenderingIntent' => ['int'],
'Imagick::getImageResolution' => ['array{x:float, y:float}'],
'Imagick::getImagesBlob' => ['string'],
'Imagick::getImageScene' => ['int'],
'Imagick::getImageSignature' => ['string'],
'Imagick::getImageSize' => ['int'],
'Imagick::getImageTicksPerSecond' => ['int'],
'Imagick::getImageTotalInkDensity' => ['float'],
'Imagick::getImageType' => ['int'],
'Imagick::getImageUnits' => ['int'],
'Imagick::getImageVirtualPixelMethod' => ['int'],
'Imagick::getImageWhitePoint' => ['array{x:float, y:float}'],
'Imagick::getImageWidth' => ['int'],
'Imagick::getInterlaceScheme' => ['int'],
'Imagick::getIteratorIndex' => ['int'],
'Imagick::getNumberImages' => ['int'],
'Imagick::getOption' => ['string', 'key'=>'string'],
'Imagick::getPackageName' => ['string'],
'Imagick::getPage' => ['array{width:int, height:int, x:int, y:int}'],
'Imagick::getPixelIterator' => ['ImagickPixelIterator'],
'Imagick::getPixelRegionIterator' => ['ImagickPixelIterator', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'],
'Imagick::getPointSize' => ['float'],
'Imagick::getQuantum' => ['int'],
'Imagick::getQuantumDepth' => ['array{quantumDepthLong:int, quantumDepthString:string}'],
'Imagick::getQuantumRange' => ['array{quantumRangeLong:int, quantumRangeString:string}'],
'Imagick::getRegistry' => ['string|false', 'key'=>'string'],
'Imagick::getReleaseDate' => ['string'],
'Imagick::getResource' => ['int', 'type'=>'int'],
'Imagick::getResourceLimit' => ['int', 'type'=>'int'],
'Imagick::getSamplingFactors' => ['array'],
'Imagick::getSize' => ['array{columns:int, rows: int}'],
'Imagick::getSizeOffset' => ['int'],
'Imagick::getVersion' => ['array{versionNumber: int, versionString:string}'],
'Imagick::haldClutImage' => ['bool', 'clut'=>'Imagick', 'channel='=>'int'],
'Imagick::hasNextImage' => ['bool'],
'Imagick::hasPreviousImage' => ['bool'],
'Imagick::identifyFormat' => ['string|false', 'embedText'=>'string'],
'Imagick::identifyImage' => ['array<string, mixed>', 'appendrawoutput='=>'bool'],
'Imagick::identifyImageType' => ['int'],
'Imagick::implodeImage' => ['bool', 'radius'=>'float'],
'Imagick::importImagePixels' => ['bool', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int', 'pixels'=>'list<int>'],
'Imagick::inverseFourierTransformImage' => ['void', 'complement'=>'string', 'magnitude'=>'string'],
'Imagick::key' => ['int|string'],
'Imagick::labelImage' => ['bool', 'label'=>'string'],
'Imagick::levelImage' => ['bool', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'],
'Imagick::linearStretchImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float'],
'Imagick::liquidRescaleImage' => ['bool', 'width'=>'int', 'height'=>'int', 'delta_x'=>'float', 'rigidity'=>'float'],
'Imagick::listRegistry' => ['array'],
'Imagick::localContrastImage' => ['bool', 'radius'=>'float', 'strength'=>'float'],
'Imagick::magnifyImage' => ['bool'],
'Imagick::mapImage' => ['bool', 'map'=>'Imagick', 'dither'=>'bool'],
'Imagick::matteFloodfillImage' => ['bool', 'alpha'=>'float', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'],
'Imagick::medianFilterImage' => ['bool', 'radius'=>'float'],
'Imagick::mergeImageLayers' => ['Imagick', 'layer_method'=>'int'],
'Imagick::minifyImage' => ['bool'],
'Imagick::modulateImage' => ['bool', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'],
'Imagick::montageImage' => ['Imagick', 'draw'=>'ImagickDraw', 'tile_geometry'=>'string', 'thumbnail_geometry'=>'string', 'mode'=>'int', 'frame'=>'string'],
'Imagick::morphImages' => ['Imagick', 'number_frames'=>'int'],
'Imagick::morphology' => ['void', 'morphologyMethod'=>'int', 'iterations'=>'int', 'ImagickKernel'=>'ImagickKernel', 'CHANNEL='=>'string'],
'Imagick::mosaicImages' => ['Imagick'],
'Imagick::motionBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float', 'channel='=>'int'],
'Imagick::negateImage' => ['bool', 'gray'=>'bool', 'channel='=>'int'],
'Imagick::newImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'background'=>'mixed', 'format='=>'string'],
'Imagick::newPseudoImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'pseudostring'=>'string'],
'Imagick::next' => ['void'],
'Imagick::nextImage' => ['bool'],
'Imagick::normalizeImage' => ['bool', 'channel='=>'int'],
'Imagick::oilPaintImage' => ['bool', 'radius'=>'float'],
'Imagick::opaquePaintImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'invert'=>'bool', 'channel='=>'int'],
'Imagick::optimizeImageLayers' => ['bool'],
'Imagick::orderedPosterizeImage' => ['bool', 'threshold_map'=>'string', 'channel='=>'int'],
'Imagick::paintFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int', 'channel='=>'int'],
'Imagick::paintOpaqueImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'channel='=>'int'],
'Imagick::paintTransparentImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float'],
'Imagick::pingImage' => ['bool', 'filename'=>'string'],
'Imagick::pingImageBlob' => ['bool', 'image'=>'string'],
'Imagick::pingImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'],
'Imagick::polaroidImage' => ['bool', 'properties'=>'ImagickDraw', 'angle'=>'float'],
'Imagick::posterizeImage' => ['bool', 'levels'=>'int', 'dither'=>'bool'],
'Imagick::previewImages' => ['bool', 'preview'=>'int'],
'Imagick::previousImage' => ['bool'],
'Imagick::profileImage' => ['bool', 'name'=>'string', 'profile'=>'string'],
'Imagick::quantizeImage' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
'Imagick::quantizeImages' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'],
'Imagick::queryFontMetrics' => ['array', 'properties'=>'ImagickDraw', 'text'=>'string', 'multiline='=>'bool'],
'Imagick::queryFonts' => ['array', 'pattern='=>'string'],
'Imagick::queryFormats' => ['list<string>', 'pattern='=>'string'],
'Imagick::radialBlurImage' => ['bool', 'angle'=>'float', 'channel='=>'int'],
'Imagick::raiseImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'],
'Imagick::randomThresholdImage' => ['bool', 'low'=>'float', 'high'=>'float', 'channel='=>'int'],
'Imagick::readImage' => ['bool', 'filename'=>'string'],
'Imagick::readImageBlob' => ['bool', 'image'=>'string', 'filename='=>'string'],
'Imagick::readImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'],
'Imagick::readImages' => ['Imagick', 'filenames'=>'string'],
'Imagick::recolorImage' => ['bool', 'matrix'=>'list<float>'],
'Imagick::reduceNoiseImage' => ['bool', 'radius'=>'float'],
'Imagick::remapImage' => ['bool', 'replacement'=>'Imagick', 'dither'=>'int'],
'Imagick::removeImage' => ['bool'],
'Imagick::removeImageProfile' => ['string', 'name'=>'string'],
'Imagick::render' => ['bool'],
'Imagick::resampleImage' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float', 'filter'=>'int', 'blur'=>'float'],
'Imagick::resetImagePage' => ['bool', 'page'=>'string'],
'Imagick::resetIterator' => [''],
'Imagick::resizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'filter'=>'int', 'blur'=>'float', 'bestfit='=>'bool'],
'Imagick::rewind' => ['void'],
'Imagick::rollImage' => ['bool', 'x'=>'int', 'y'=>'int'],
'Imagick::rotateImage' => ['bool', 'background'=>'mixed', 'degrees'=>'float'],
'Imagick::rotationalBlurImage' => ['void', 'angle'=>'string', 'CHANNEL='=>'string'],
'Imagick::roundCorners' => ['bool', 'x_rounding'=>'float', 'y_rounding'=>'float', 'stroke_width='=>'float', 'displace='=>'float', 'size_correction='=>'float'],
'Imagick::roundCornersImage' => ['', 'xRounding'=>'', 'yRounding'=>'', 'strokeWidth'=>'', 'displace'=>'', 'sizeCorrection'=>''],
'Imagick::sampleImage' => ['bool', 'columns'=>'int', 'rows'=>'int'],
'Imagick::scaleImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'bestfit='=>'bool'],
'Imagick::segmentImage' => ['bool', 'colorspace'=>'int', 'cluster_threshold'=>'float', 'smooth_threshold'=>'float', 'verbose='=>'bool'],
'Imagick::selectiveBlurImage' => ['void', 'radius'=>'float', 'sigma'=>'float', 'threshold'=>'float', 'CHANNEL'=>'int'],
'Imagick::separateImageChannel' => ['bool', 'channel'=>'int'],
'Imagick::sepiaToneImage' => ['bool', 'threshold'=>'float'],
'Imagick::setAntiAlias' => ['int', 'antialias'=>'bool'],
'Imagick::setBackgroundColor' => ['bool', 'background'=>'mixed'],
'Imagick::setColorspace' => ['bool', 'colorspace'=>'int'],
'Imagick::setCompression' => ['bool', 'compression'=>'int'],
'Imagick::setCompressionQuality' => ['bool', 'quality'=>'int'],
'Imagick::setFilename' => ['bool', 'filename'=>'string'],
'Imagick::setFirstIterator' => ['bool'],
'Imagick::setFont' => ['bool', 'font'=>'string'],
'Imagick::setFormat' => ['bool', 'format'=>'string'],
'Imagick::setGravity' => ['bool', 'gravity'=>'int'],
'Imagick::setImage' => ['bool', 'replace'=>'Imagick'],
'Imagick::setImageAlpha' => ['bool', 'alpha'=>'float'],
'Imagick::setImageAlphaChannel' => ['bool', 'mode'=>'int'],
'Imagick::setImageArtifact' => ['bool', 'artifact'=>'string', 'value'=>'string'],
'Imagick::setImageAttribute' => ['void', 'key'=>'string', 'value'=>'string'],
'Imagick::setImageBackgroundColor' => ['bool', 'background'=>'mixed'],
'Imagick::setImageBias' => ['bool', 'bias'=>'float'],
'Imagick::setImageBiasQuantum' => ['void', 'bias'=>'string'],
'Imagick::setImageBluePrimary' => ['bool', 'x'=>'float', 'y'=>'float'],
'Imagick::setImageBorderColor' => ['bool', 'border'=>'mixed'],
'Imagick::setImageChannelDepth' => ['bool', 'channel'=>'int', 'depth'=>'int'],
'Imagick::setImageChannelMask' => ['', 'channel'=>'int'],
'Imagick::setImageClipMask' => ['bool', 'clip_mask'=>'Imagick'],
'Imagick::setImageColormapColor' => ['bool', 'index'=>'int', 'color'=>'ImagickPixel'],
'Imagick::setImageColorspace' => ['bool', 'colorspace'=>'int'],
'Imagick::setImageCompose' => ['bool', 'compose'=>'int'],
'Imagick::setImageCompression' => ['bool', 'compression'=>'int'],
'Imagick::setImageCompressionQuality' => ['bool', 'quality'=>'int'],
'Imagick::setImageDelay' => ['bool', 'delay'=>'int'],
'Imagick::setImageDepth' => ['bool', 'depth'=>'int'],
'Imagick::setImageDispose' => ['bool', 'dispose'=>'int'],
'Imagick::setImageExtent' => ['bool', 'columns'=>'int', 'rows'=>'int'],
'Imagick::setImageFilename' => ['bool', 'filename'=>'string'],
'Imagick::setImageFormat' => ['bool', 'format'=>'string'],
'Imagick::setImageGamma' => ['bool', 'gamma'=>'float'],
'Imagick::setImageGravity' => ['bool', 'gravity'=>'int'],
'Imagick::setImageGreenPrimary' => ['bool', 'x'=>'float', 'y'=>'float'],
'Imagick::setImageIndex' => ['bool', 'index'=>'int'],
'Imagick::setImageInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'],
'Imagick::setImageInterpolateMethod' => ['bool', 'method'=>'int'],
'Imagick::setImageIterations' => ['bool', 'iterations'=>'int'],
'Imagick::setImageMatte' => ['bool', 'matte'=>'bool'],
'Imagick::setImageMatteColor' => ['bool', 'matte'=>'mixed'],
'Imagick::setImageOpacity' => ['bool', 'opacity'=>'float'],
'Imagick::setImageOrientation' => ['bool', 'orientation'=>'int'],
'Imagick::setImagePage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Imagick::setImageProfile' => ['bool', 'name'=>'string', 'profile'=>'string'],
'Imagick::setImageProgressMonitor' => ['', 'filename'=>''],
'Imagick::setImageProperty' => ['bool', 'name'=>'string', 'value'=>'string'],
'Imagick::setImageRedPrimary' => ['bool', 'x'=>'float', 'y'=>'float'],
'Imagick::setImageRenderingIntent' => ['bool', 'rendering_intent'=>'int'],
'Imagick::setImageResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'],
'Imagick::setImageScene' => ['bool', 'scene'=>'int'],
'Imagick::setImageTicksPerSecond' => ['bool', 'ticks_per_second'=>'int'],
'Imagick::setImageType' => ['bool', 'image_type'=>'int'],
'Imagick::setImageUnits' => ['bool', 'units'=>'int'],
'Imagick::setImageVirtualPixelMethod' => ['bool', 'method'=>'int'],
'Imagick::setImageWhitePoint' => ['bool', 'x'=>'float', 'y'=>'float'],
'Imagick::setInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'],
'Imagick::setIteratorIndex' => ['bool', 'index'=>'int'],
'Imagick::setLastIterator' => ['bool'],
'Imagick::setOption' => ['bool', 'key'=>'string', 'value'=>'string'],
'Imagick::setPage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Imagick::setPointSize' => ['bool', 'point_size'=>'float'],
'Imagick::setProgressMonitor' => ['void', 'callback'=>'callable'],
'Imagick::setRegistry' => ['void', 'key'=>'string', 'value'=>'string'],
'Imagick::setResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'],
'Imagick::setResourceLimit' => ['bool', 'type'=>'int', 'limit'=>'int'],
'Imagick::setSamplingFactors' => ['bool', 'factors'=>'list<string>'],
'Imagick::setSize' => ['bool', 'columns'=>'int', 'rows'=>'int'],
'Imagick::setSizeOffset' => ['bool', 'columns'=>'int', 'rows'=>'int', 'offset'=>'int'],
'Imagick::setType' => ['bool', 'image_type'=>'int'],
'Imagick::shadeImage' => ['bool', 'gray'=>'bool', 'azimuth'=>'float', 'elevation'=>'float'],
'Imagick::shadowImage' => ['bool', 'opacity'=>'float', 'sigma'=>'float', 'x'=>'int', 'y'=>'int'],
'Imagick::sharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'],
'Imagick::shaveImage' => ['bool', 'columns'=>'int', 'rows'=>'int'],
'Imagick::shearImage' => ['bool', 'background'=>'mixed', 'x_shear'=>'float', 'y_shear'=>'float'],
'Imagick::sigmoidalContrastImage' => ['bool', 'sharpen'=>'bool', 'alpha'=>'float', 'beta'=>'float', 'channel='=>'int'],
'Imagick::similarityImage' => ['Imagick', 'Imagick'=>'Imagick', '&bestMatch'=>'array', '&similarity'=>'float', 'similarity_threshold'=>'float', 'metric'=>'int'],
'Imagick::sketchImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'],
'Imagick::smushImages' => ['Imagick', 'stack'=>'string', 'offset'=>'string'],
'Imagick::solarizeImage' => ['bool', 'threshold'=>'int'],
'Imagick::sparseColorImage' => ['bool', 'sparse_method'=>'int', 'arguments'=>'array', 'channel='=>'int'],
'Imagick::spliceImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'],
'Imagick::spreadImage' => ['bool', 'radius'=>'float'],
'Imagick::statisticImage' => ['void', 'type'=>'int', 'width'=>'int', 'height'=>'int', 'CHANNEL='=>'string'],
'Imagick::steganoImage' => ['Imagick', 'watermark_wand'=>'Imagick', 'offset'=>'int'],
'Imagick::stereoImage' => ['bool', 'offset_wand'=>'Imagick'],
'Imagick::stripImage' => ['bool'],
'Imagick::subImageMatch' => ['Imagick', 'Imagick'=>'Imagick', '&w_offset='=>'array', '&w_similarity='=>'float'],
'Imagick::swirlImage' => ['bool', 'degrees'=>'float'],
'Imagick::textureImage' => ['bool', 'texture_wand'=>'Imagick'],
'Imagick::thresholdImage' => ['bool', 'threshold'=>'float', 'channel='=>'int'],
'Imagick::thumbnailImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool', 'fill='=>'bool', 'legacy='=>'bool'],
'Imagick::tintImage' => ['bool', 'tint'=>'mixed', 'opacity'=>'mixed'],
'Imagick::transformImage' => ['Imagick', 'crop'=>'string', 'geometry'=>'string'],
'Imagick::transformImageColorspace' => ['bool', 'colorspace'=>'int'],
'Imagick::transparentPaintImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float', 'invert'=>'bool'],
'Imagick::transposeImage' => ['bool'],
'Imagick::transverseImage' => ['bool'],
'Imagick::trimImage' => ['bool', 'fuzz'=>'float'],
'Imagick::uniqueImageColors' => ['bool'],
'Imagick::unsharpMaskImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'amount'=>'float', 'threshold'=>'float', 'channel='=>'int'],
'Imagick::valid' => ['bool'],
'Imagick::vignetteImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float', 'x'=>'int', 'y'=>'int'],
'Imagick::waveImage' => ['bool', 'amplitude'=>'float', 'length'=>'float'],
'Imagick::whiteThresholdImage' => ['bool', 'threshold'=>'mixed'],
'Imagick::writeImage' => ['bool', 'filename='=>'string'],
'Imagick::writeImageFile' => ['bool', 'filehandle'=>'resource'],
'Imagick::writeImages' => ['bool', 'filename'=>'string', 'adjoin'=>'bool'],
'Imagick::writeImagesFile' => ['bool', 'filehandle'=>'resource'],
'ImagickDraw::__construct' => ['void'],
'ImagickDraw::affine' => ['bool', 'affine'=>'array<string, float>'],
'ImagickDraw::annotation' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'],
'ImagickDraw::arc' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'],
'ImagickDraw::bezier' => ['bool', 'coordinates'=>'list<array{x:float, y:float}>'],
'ImagickDraw::circle' => ['bool', 'ox'=>'float', 'oy'=>'float', 'px'=>'float', 'py'=>'float'],
'ImagickDraw::clear' => ['bool'],
'ImagickDraw::clone' => ['ImagickDraw'],
'ImagickDraw::color' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'],
'ImagickDraw::comment' => ['bool', 'comment'=>'string'],
'ImagickDraw::composite' => ['bool', 'compose'=>'int', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float', 'compositewand'=>'Imagick'],
'ImagickDraw::destroy' => ['bool'],
'ImagickDraw::ellipse' => ['bool', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'],
'ImagickDraw::getBorderColor' => ['ImagickPixel'],
'ImagickDraw::getClipPath' => ['string|false'],
'ImagickDraw::getClipRule' => ['int'],
'ImagickDraw::getClipUnits' => ['int'],
'ImagickDraw::getDensity' => ['?string'],
'ImagickDraw::getFillColor' => ['ImagickPixel'],
'ImagickDraw::getFillOpacity' => ['float'],
'ImagickDraw::getFillRule' => ['int'],
'ImagickDraw::getFont' => ['string|false'],
'ImagickDraw::getFontFamily' => ['string|false'],
'ImagickDraw::getFontResolution' => ['array'],
'ImagickDraw::getFontSize' => ['float'],
'ImagickDraw::getFontStretch' => ['int'],
'ImagickDraw::getFontStyle' => ['int'],
'ImagickDraw::getFontWeight' => ['int'],
'ImagickDraw::getGravity' => ['int'],
'ImagickDraw::getOpacity' => ['float'],
'ImagickDraw::getStrokeAntialias' => ['bool'],
'ImagickDraw::getStrokeColor' => ['ImagickPixel'],
'ImagickDraw::getStrokeDashArray' => ['array'],
'ImagickDraw::getStrokeDashOffset' => ['float'],
'ImagickDraw::getStrokeLineCap' => ['int'],
'ImagickDraw::getStrokeLineJoin' => ['int'],
'ImagickDraw::getStrokeMiterLimit' => ['int'],
'ImagickDraw::getStrokeOpacity' => ['float'],
'ImagickDraw::getStrokeWidth' => ['float'],
'ImagickDraw::getTextAlignment' => ['int'],
'ImagickDraw::getTextAntialias' => ['bool'],
'ImagickDraw::getTextDecoration' => ['int'],
'ImagickDraw::getTextDirection' => ['bool'],
'ImagickDraw::getTextEncoding' => ['string'],
'ImagickDraw::getTextInterlineSpacing' => ['float'],
'ImagickDraw::getTextInterwordSpacing' => ['float'],
'ImagickDraw::getTextKerning' => ['float'],
'ImagickDraw::getTextUnderColor' => ['ImagickPixel'],
'ImagickDraw::getVectorGraphics' => ['string'],
'ImagickDraw::line' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'],
'ImagickDraw::matte' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'],
'ImagickDraw::pathClose' => ['bool'],
'ImagickDraw::pathCurveToAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathCurveToQuadraticBezierAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathCurveToQuadraticBezierRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathCurveToQuadraticBezierSmoothAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathCurveToQuadraticBezierSmoothRelative' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathCurveToRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathCurveToSmoothAbsolute' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathCurveToSmoothRelative' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathEllipticArcAbsolute' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathEllipticArcRelative' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathFinish' => ['bool'],
'ImagickDraw::pathLineToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathLineToHorizontalAbsolute' => ['bool', 'x'=>'float'],
'ImagickDraw::pathLineToHorizontalRelative' => ['bool', 'x'=>'float'],
'ImagickDraw::pathLineToRelative' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathLineToVerticalAbsolute' => ['bool', 'y'=>'float'],
'ImagickDraw::pathLineToVerticalRelative' => ['bool', 'y'=>'float'],
'ImagickDraw::pathMoveToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathMoveToRelative' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::pathStart' => ['bool'],
'ImagickDraw::point' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::polygon' => ['bool', 'coordinates'=>'list<array{x:float, y:float}>'],
'ImagickDraw::polyline' => ['bool', 'coordinates'=>'list<array{x:float, y:float}>'],
'ImagickDraw::pop' => ['bool'],
'ImagickDraw::popClipPath' => ['bool'],
'ImagickDraw::popDefs' => ['bool'],
'ImagickDraw::popPattern' => ['bool'],
'ImagickDraw::push' => ['bool'],
'ImagickDraw::pushClipPath' => ['bool', 'clip_mask_id'=>'string'],
'ImagickDraw::pushDefs' => ['bool'],
'ImagickDraw::pushPattern' => ['bool', 'pattern_id'=>'string', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
'ImagickDraw::rectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'],
'ImagickDraw::render' => ['bool'],
'ImagickDraw::resetVectorGraphics' => ['void'],
'ImagickDraw::rotate' => ['bool', 'degrees'=>'float'],
'ImagickDraw::roundRectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'],
'ImagickDraw::scale' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::setBorderColor' => ['bool', 'color'=>'ImagickPixel|string'],
'ImagickDraw::setClipPath' => ['bool', 'clip_mask'=>'string'],
'ImagickDraw::setClipRule' => ['bool', 'fill_rule'=>'int'],
'ImagickDraw::setClipUnits' => ['bool', 'clip_units'=>'int'],
'ImagickDraw::setDensity' => ['bool', 'density_string'=>'string'],
'ImagickDraw::setFillAlpha' => ['bool', 'opacity'=>'float'],
'ImagickDraw::setFillColor' => ['bool', 'fill_pixel'=>'ImagickPixel|string'],
'ImagickDraw::setFillOpacity' => ['bool', 'fillopacity'=>'float'],
'ImagickDraw::setFillPatternURL' => ['bool', 'fill_url'=>'string'],
'ImagickDraw::setFillRule' => ['bool', 'fill_rule'=>'int'],
'ImagickDraw::setFont' => ['bool', 'font_name'=>'string'],
'ImagickDraw::setFontFamily' => ['bool', 'font_family'=>'string'],
'ImagickDraw::setFontResolution' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickDraw::setFontSize' => ['bool', 'pointsize'=>'float'],
'ImagickDraw::setFontStretch' => ['bool', 'fontstretch'=>'int'],
'ImagickDraw::setFontStyle' => ['bool', 'style'=>'int'],
'ImagickDraw::setFontWeight' => ['bool', 'font_weight'=>'int'],
'ImagickDraw::setGravity' => ['bool', 'gravity'=>'int'],
'ImagickDraw::setOpacity' => ['void', 'opacity'=>'float'],
'ImagickDraw::setResolution' => ['void', 'x_resolution'=>'float', 'y_resolution'=>'float'],
'ImagickDraw::setStrokeAlpha' => ['bool', 'opacity'=>'float'],
'ImagickDraw::setStrokeAntialias' => ['bool', 'stroke_antialias'=>'bool'],
'ImagickDraw::setStrokeColor' => ['bool', 'stroke_pixel'=>'ImagickPixel|string'],
'ImagickDraw::setStrokeDashArray' => ['bool', 'dasharray'=>'list<int|float>'],
'ImagickDraw::setStrokeDashOffset' => ['bool', 'dash_offset'=>'float'],
'ImagickDraw::setStrokeLineCap' => ['bool', 'linecap'=>'int'],
'ImagickDraw::setStrokeLineJoin' => ['bool', 'linejoin'=>'int'],
'ImagickDraw::setStrokeMiterLimit' => ['bool', 'miterlimit'=>'int'],
'ImagickDraw::setStrokeOpacity' => ['bool', 'stroke_opacity'=>'float'],
'ImagickDraw::setStrokePatternURL' => ['bool', 'stroke_url'=>'string'],
'ImagickDraw::setStrokeWidth' => ['bool', 'stroke_width'=>'float'],
'ImagickDraw::setTextAlignment' => ['bool', 'alignment'=>'int'],
'ImagickDraw::setTextAntialias' => ['bool', 'antialias'=>'bool'],
'ImagickDraw::setTextDecoration' => ['bool', 'decoration'=>'int'],
'ImagickDraw::setTextDirection' => ['bool', 'direction'=>'int'],
'ImagickDraw::setTextEncoding' => ['bool', 'encoding'=>'string'],
'ImagickDraw::setTextInterlineSpacing' => ['void', 'spacing'=>'float'],
'ImagickDraw::setTextInterwordSpacing' => ['void', 'spacing'=>'float'],
'ImagickDraw::setTextKerning' => ['void', 'kerning'=>'float'],
'ImagickDraw::setTextUnderColor' => ['bool', 'under_color'=>'ImagickPixel|string'],
'ImagickDraw::setVectorGraphics' => ['bool', 'xml'=>'string'],
'ImagickDraw::setViewbox' => ['bool', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int'],
'ImagickDraw::skewX' => ['bool', 'degrees'=>'float'],
'ImagickDraw::skewY' => ['bool', 'degrees'=>'float'],
'ImagickDraw::translate' => ['bool', 'x'=>'float', 'y'=>'float'],
'ImagickKernel::addKernel' => ['void', 'ImagickKernel'=>'ImagickKernel'],
'ImagickKernel::addUnityKernel' => ['void'],
'ImagickKernel::fromBuiltin' => ['ImagickKernel', 'kernelType'=>'string', 'kernelString'=>'string'],
'ImagickKernel::fromMatrix' => ['ImagickKernel', 'matrix'=>'list<list<float>>', 'origin='=>'array'],
'ImagickKernel::getMatrix' => ['list<list<float|false>>'],
'ImagickKernel::scale' => ['void'],
'ImagickKernel::separate' => ['ImagickKernel[]'],
'ImagickKernel::seperate' => ['void'],
'ImagickPixel::__construct' => ['void', 'color='=>'string'],
'ImagickPixel::clear' => ['bool'],
'ImagickPixel::clone' => ['void'],
'ImagickPixel::destroy' => ['bool'],
'ImagickPixel::getColor' => ['array{r: int|float, g: int|float, b: int|float, a: int|float}', 'normalized='=>'0|1|2'],
'ImagickPixel::getColorAsString' => ['string'],
'ImagickPixel::getColorCount' => ['int'],
'ImagickPixel::getColorQuantum' => ['mixed'],
'ImagickPixel::getColorValue' => ['float', 'color'=>'int'],
'ImagickPixel::getColorValueQuantum' => ['mixed'],
'ImagickPixel::getHSL' => ['array{hue: float, saturation: float, luminosity: float}'],
'ImagickPixel::getIndex' => ['int'],
'ImagickPixel::isPixelSimilar' => ['bool', 'color'=>'ImagickPixel', 'fuzz'=>'float'],
'ImagickPixel::isPixelSimilarQuantum' => ['bool', 'color'=>'string', 'fuzz='=>'string'],
'ImagickPixel::isSimilar' => ['bool', 'color'=>'ImagickPixel', 'fuzz'=>'float'],
'ImagickPixel::setColor' => ['bool', 'color'=>'string'],
'ImagickPixel::setcolorcount' => ['void', 'colorCount'=>'string'],
'ImagickPixel::setColorFromPixel' => ['bool', 'srcPixel'=>'ImagickPixel'],
'ImagickPixel::setColorValue' => ['bool', 'color'=>'int', 'value'=>'float'],
'ImagickPixel::setColorValueQuantum' => ['void', 'color'=>'int', 'value'=>'mixed'],
'ImagickPixel::setHSL' => ['bool', 'hue'=>'float', 'saturation'=>'float', 'luminosity'=>'float'],
'ImagickPixel::setIndex' => ['void', 'index'=>'int'],
'ImagickPixelIterator::__construct' => ['void', 'wand'=>'Imagick'],
'ImagickPixelIterator::clear' => ['bool'],
'ImagickPixelIterator::current' => ['mixed'],
'ImagickPixelIterator::destroy' => ['bool'],
'ImagickPixelIterator::getCurrentIteratorRow' => ['array'],
'ImagickPixelIterator::getIteratorRow' => ['int'],
'ImagickPixelIterator::getNextIteratorRow' => ['array'],
'ImagickPixelIterator::getpixeliterator' => ['', 'Imagick'=>'Imagick'],
'ImagickPixelIterator::getpixelregioniterator' => ['', 'Imagick'=>'Imagick', 'x'=>'', 'y'=>'', 'columns'=>'', 'rows'=>''],
'ImagickPixelIterator::getPreviousIteratorRow' => ['array'],
'ImagickPixelIterator::key' => ['int|string'],
'ImagickPixelIterator::newPixelIterator' => ['bool', 'wand'=>'Imagick'],
'ImagickPixelIterator::newPixelRegionIterator' => ['bool', 'wand'=>'Imagick', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'],
'ImagickPixelIterator::next' => ['void'],
'ImagickPixelIterator::resetIterator' => ['bool'],
'ImagickPixelIterator::rewind' => ['void'],
'ImagickPixelIterator::setIteratorFirstRow' => ['bool'],
'ImagickPixelIterator::setIteratorLastRow' => ['bool'],
'ImagickPixelIterator::setIteratorRow' => ['bool', 'row'=>'int'],
'ImagickPixelIterator::syncIterator' => ['bool'],
'ImagickPixelIterator::valid' => ['bool'],
'imap_8bit' => ['string|false', 'string'=>'string'],
'imap_alerts' => ['array|false'],
'imap_append' => ['bool', 'imap'=>'IMAP\Connection', 'folder'=>'string', 'message'=>'string', 'options='=>'?string', 'internal_date='=>'?string'],
'imap_base64' => ['string|false', 'string'=>'string'],
'imap_binary' => ['string|false', 'string'=>'string'],
'imap_body' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
'imap_bodystruct' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'section'=>'string'],
'imap_check' => ['stdClass|false', 'imap'=>'IMAP\Connection'],
'imap_clearflag_full' => ['bool', 'imap'=>'IMAP\Connection', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
'imap_close' => ['bool', 'imap'=>'IMAP\Connection', 'flags='=>'int'],
'imap_create' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
'imap_createmailbox' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
'imap_delete' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'flags='=>'int'],
'imap_deletemailbox' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
'imap_errors' => ['array|false'],
'imap_expunge' => ['bool', 'imap'=>'IMAP\Connection'],
'imap_fetch_overview' => ['array|false', 'imap'=>'IMAP\Connection', 'sequence'=>'string', 'flags='=>'int'],
'imap_fetchbody' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
'imap_fetchheader' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
'imap_fetchmime' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
'imap_fetchstructure' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
'imap_fetchtext' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
'imap_gc' => ['bool', 'imap'=>'IMAP\Connection', 'flags'=>'int'],
'imap_get_quota' => ['array|false', 'imap'=>'IMAP\Connection', 'quota_root'=>'string'],
'imap_get_quotaroot' => ['array|false', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
'imap_getacl' => ['array|false', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
'imap_getmailboxes' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
'imap_getsubscribed' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
'imap_header' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string'],
'imap_headerinfo' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'from_length='=>'int', 'subject_length='=>'int'],
'imap_headers' => ['array|false', 'imap'=>'IMAP\Connection'],
'imap_is_open' => ['bool', 'imap'=>'IMAP\Connection'],
'imap_last_error' => ['string|false'],
'imap_list' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
'imap_listmailbox' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
'imap_listscan' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
'imap_listsubscribed' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
'imap_lsub' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
'imap_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'?string', 'cc='=>'?string', 'bcc='=>'?string', 'return_path='=>'?string'],
'imap_mail_compose' => ['string|false', 'envelope'=>'array', 'bodies'=>'array'],
'imap_mail_copy' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
'imap_mail_move' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
'imap_mailboxmsginfo' => ['stdClass', 'imap'=>'IMAP\Connection'],
'imap_mime_header_decode' => ['array|false', 'string'=>'string'],
'imap_msgno' => ['int', 'imap'=>'IMAP\Connection', 'message_uid'=>'int'],
'imap_mutf7_to_utf8' => ['string|false', 'string'=>'string'],
'imap_num_msg' => ['int|false', 'imap'=>'IMAP\Connection'],
'imap_num_recent' => ['int', 'imap'=>'IMAP\Connection'],
'imap_open' => ['IMAP\Connection|false', 'mailbox'=>'string', 'user'=>'string', 'password'=>'string', 'flags='=>'int', 'retries='=>'int', 'options='=>'?array'],
'imap_ping' => ['bool', 'imap'=>'IMAP\Connection'],
'imap_qprint' => ['string|false', 'string'=>'string'],
'imap_rename' => ['bool', 'imap'=>'IMAP\Connection', 'from'=>'string', 'to'=>'string'],
'imap_renamemailbox' => ['bool', 'imap'=>'IMAP\Connection', 'from'=>'string', 'to'=>'string'],
'imap_reopen' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string', 'flags='=>'int', 'retries='=>'int'],
'imap_rfc822_parse_adrlist' => ['array', 'string'=>'string', 'default_hostname'=>'string'],
'imap_rfc822_parse_headers' => ['stdClass', 'headers'=>'string', 'default_hostname='=>'string'],
'imap_rfc822_write_address' => ['string|false', 'mailbox'=>'?string', 'hostname'=>'?string', 'personal'=>'?string'],
'imap_savebody' => ['bool', 'imap'=>'IMAP\Connection', 'file'=>'string|resource', 'message_num'=>'int', 'section='=>'string', 'flags='=>'int'],
'imap_scan' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
'imap_scanmailbox' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
'imap_search' => ['array|false', 'imap'=>'IMAP\Connection', 'criteria'=>'string', 'flags='=>'int', 'charset='=>'string'],
'imap_set_quota' => ['bool', 'imap'=>'IMAP\Connection', 'quota_root'=>'string', 'mailbox_size'=>'int'],
'imap_setacl' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string', 'user_id'=>'string', 'rights'=>'string'],
'imap_setflag_full' => ['bool', 'imap'=>'IMAP\Connection', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
'imap_sort' => ['array|false', 'imap'=>'IMAP\Connection', 'criteria'=>'int', 'reverse'=>'int', 'flags='=>'int', 'search_criteria='=>'string', 'charset='=>'string'],
'imap_status' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'mailbox'=>'string', 'flags'=>'int'],
'imap_subscribe' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
'imap_thread' => ['array|false', 'imap'=>'IMAP\Connection', 'flags='=>'int'],
'imap_timeout' => ['int|bool', 'timeout_type'=>'int', 'timeout='=>'int'],
'imap_uid' => ['int|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int'],
'imap_undelete' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'flags='=>'int'],
'imap_unsubscribe' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
'imap_utf7_decode' => ['string|false', 'string'=>'string'],
'imap_utf7_encode' => ['string', 'string'=>'string'],
'imap_utf8' => ['string', 'mime_encoded_text'=>'string'],
'imap_utf8_to_mutf7' => ['string|false', 'string'=>'string'],
'implode' => ['string', 'separator'=>'string', 'array'=>'array'],
'implode\'1' => ['string', 'separator'=>'array'],
'import_request_variables' => ['bool', 'types'=>'string', 'prefix='=>'string'],
'in_array' => ['bool', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'],
'inclued_get_data' => ['array'],
'inet_ntop' => ['string|false', 'ip'=>'string'],
'inet_pton' => ['string|false', 'ip'=>'string'],
'InfiniteIterator::__construct' => ['void', 'iterator'=>'Iterator'],
'InfiniteIterator::current' => ['mixed'],
'InfiniteIterator::getInnerIterator' => ['Iterator'],
'InfiniteIterator::key' => ['bool|float|int|string'],
'InfiniteIterator::next' => ['void'],
'InfiniteIterator::rewind' => ['void'],
'InfiniteIterator::valid' => ['bool'],
'inflate_add' => ['string|false', 'context'=>'resource', 'data'=>'string', 'flush_mode='=>'int'],
'inflate_get_read_len' => ['int|false', 'context'=>'resource'],
'inflate_get_status' => ['int|false', 'context'=>'resource'],
'inflate_init' => ['InflateContext|false', 'encoding'=>'int', 'options='=>'array'],
'ingres_autocommit' => ['bool', 'link'=>'resource'],
'ingres_autocommit_state' => ['bool', 'link'=>'resource'],
'ingres_charset' => ['string', 'link'=>'resource'],
'ingres_close' => ['bool', 'link'=>'resource'],
'ingres_commit' => ['bool', 'link'=>'resource'],
'ingres_connect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'],
'ingres_cursor' => ['string', 'result'=>'resource'],
'ingres_errno' => ['int', 'link='=>'resource'],
'ingres_error' => ['string', 'link='=>'resource'],
'ingres_errsqlstate' => ['string', 'link='=>'resource'],
'ingres_escape_string' => ['string', 'link'=>'resource', 'source_string'=>'string'],
'ingres_execute' => ['bool', 'result'=>'resource', 'params='=>'array', 'types='=>'string'],
'ingres_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'],
'ingres_fetch_assoc' => ['array', 'result'=>'resource'],
'ingres_fetch_object' => ['object', 'result'=>'resource', 'result_type='=>'int'],
'ingres_fetch_proc_return' => ['int', 'result'=>'resource'],
'ingres_fetch_row' => ['array', 'result'=>'resource'],
'ingres_field_length' => ['int', 'result'=>'resource', 'index'=>'int'],
'ingres_field_name' => ['string', 'result'=>'resource', 'index'=>'int'],
'ingres_field_nullable' => ['bool', 'result'=>'resource', 'index'=>'int'],
'ingres_field_precision' => ['int', 'result'=>'resource', 'index'=>'int'],
'ingres_field_scale' => ['int', 'result'=>'resource', 'index'=>'int'],
'ingres_field_type' => ['string', 'result'=>'resource', 'index'=>'int'],
'ingres_free_result' => ['bool', 'result'=>'resource'],
'ingres_next_error' => ['bool', 'link='=>'resource'],
'ingres_num_fields' => ['int', 'result'=>'resource'],
'ingres_num_rows' => ['int', 'result'=>'resource'],
'ingres_pconnect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'],
'ingres_prepare' => ['mixed', 'link'=>'resource', 'query'=>'string'],
'ingres_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'],
'ingres_result_seek' => ['bool', 'result'=>'resource', 'position'=>'int'],
'ingres_rollback' => ['bool', 'link'=>'resource'],
'ingres_set_environment' => ['bool', 'link'=>'resource', 'options'=>'array'],
'ingres_unbuffered_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'],
'ini_alter' => ['string|false', 'option'=>'string', 'value'=>'string|int|float|bool|null'],
'ini_get' => ['string|false', 'option'=>'string'],
'ini_get_all' => ['array|false', 'extension='=>'?string', 'details='=>'bool'],
'ini_restore' => ['void', 'option'=>'string'],
'ini_parse_quantity' => ['int', 'shorthand'=>'non-empty-string'],
'ini_set' => ['string|false', 'option'=>'string', 'value'=>'string|int|float|bool|null'],
'inotify_add_watch' => ['int', 'inotify_instance'=>'resource', 'pathname'=>'string', 'mask'=>'int'],
'inotify_init' => ['resource|false'],
'inotify_queue_len' => ['int', 'inotify_instance'=>'resource'],
'inotify_read' => ['array|false', 'inotify_instance'=>'resource'],
'inotify_rm_watch' => ['bool', 'inotify_instance'=>'resource', 'watch_descriptor'=>'int'],
'intdiv' => ['int', 'num1'=>'int', 'num2'=>'int'],
'interface_exists' => ['bool', 'interface'=>'string', 'autoload='=>'bool'],
'intl_error_name' => ['string', 'errorCode'=>'int'],
'intl_get_error_code' => ['int'],
'intl_get_error_message' => ['string'],
'intl_is_failure' => ['bool', 'errorCode'=>'int'],
'IntlBreakIterator::__construct' => ['void'],
'IntlBreakIterator::createCharacterInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'],
'IntlBreakIterator::createLineInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlBreakIterator::createSentenceInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlBreakIterator::createTitleInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlBreakIterator::createWordInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlBreakIterator::current' => ['int'],
'IntlBreakIterator::first' => ['int'],
'IntlBreakIterator::following' => ['int', 'offset'=>'int'],
'IntlBreakIterator::getErrorCode' => ['int'],
'IntlBreakIterator::getErrorMessage' => ['string'],
'IntlBreakIterator::getLocale' => ['string', 'locale_type'=>'string'],
'IntlBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'int'],
'IntlBreakIterator::getText' => ['?string'],
'IntlBreakIterator::isBoundary' => ['bool', 'offset'=>'int'],
'IntlBreakIterator::last' => ['int'],
'IntlBreakIterator::next' => ['int', 'offset='=>'?int'],
'IntlBreakIterator::preceding' => ['int', 'offset'=>'int'],
'IntlBreakIterator::previous' => ['int'],
'IntlBreakIterator::setText' => ['?bool', 'text'=>'string'],
'intlcal_add' => ['bool', 'calendar'=>'IntlCalendar', 'field'=>'int', 'value'=>'int'],
'intlcal_after' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
'intlcal_before' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
'intlcal_clear' => ['bool', 'calendar'=>'IntlCalendar', 'field='=>'?int'],
'intlcal_create_instance' => ['?IntlCalendar', 'timezone='=>'mixed', 'locale='=>'?string'],
'intlcal_equals' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
'intlcal_field_difference' => ['int', 'calendar'=>'IntlCalendar', 'timestamp'=>'float', 'field'=>'int'],
'intlcal_from_date_time' => ['IntlCalendar', 'datetime'=>'DateTime|string'],
'intlcal_get' => ['int|false', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_get_actual_maximum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_get_actual_minimum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_get_available_locales' => ['array'],
'intlcal_get_day_of_week_type' => ['int', 'calendar'=>'IntlCalendar', 'dayOfWeek'=>'int'],
'intlcal_get_first_day_of_week' => ['int', 'calendar'=>'IntlCalendar'],
'intlcal_get_greatest_minimum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_get_keyword_values_for_locale' => ['IntlIterator|false', 'keyword'=>'string', 'locale'=>'string', 'onlyCommon'=>'bool'],
'intlcal_get_least_maximum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_get_locale' => ['string', 'calendar'=>'IntlCalendar', 'type'=>'int'],
'intlcal_get_maximum' => ['int|false', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_get_minimal_days_in_first_week' => ['int', 'calendar'=>'IntlCalendar'],
'intlcal_get_minimum' => ['int', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_get_now' => ['float'],
'intlcal_get_repeated_wall_time_option' => ['int', 'calendar'=>'IntlCalendar'],
'intlcal_get_skipped_wall_time_option' => ['int', 'calendar'=>'IntlCalendar'],
'intlcal_get_time' => ['float', 'calendar'=>'IntlCalendar'],
'intlcal_get_time_zone' => ['IntlTimeZone', 'calendar'=>'IntlCalendar'],
'intlcal_get_type' => ['string', 'calendar'=>'IntlCalendar'],
'intlcal_get_weekend_transition' => ['int', 'calendar'=>'IntlCalendar', 'dayOfWeek'=>'string'],
'intlcal_in_daylight_time' => ['bool', 'calendar'=>'IntlCalendar'],
'intlcal_is_equivalent_to' => ['bool', 'calendar'=>'IntlCalendar', 'other'=>'IntlCalendar'],
'intlcal_is_lenient' => ['bool', 'calendar'=>'IntlCalendar'],
'intlcal_is_set' => ['bool', 'calendar'=>'IntlCalendar', 'field'=>'int'],
'intlcal_is_weekend' => ['bool', 'calendar'=>'IntlCalendar', 'timestamp='=>'?float'],
'intlcal_roll' => ['bool', 'calendar'=>'IntlCalendar', 'field'=>'int', 'value'=>'mixed'],
'intlcal_set' => ['bool', 'calendar'=>'IntlCalendar', 'year'=>'int', 'month'=>'int'],
'intlcal_set\'1' => ['bool', 'calendar'=>'IntlCalendar', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'],
'intlcal_set_first_day_of_week' => ['bool', 'calendar'=>'IntlCalendar', 'dayOfWeek'=>'int'],
'intlcal_set_lenient' => ['bool', 'calendar'=>'IntlCalendar', 'lenient'=>'bool'],
'intlcal_set_repeated_wall_time_option' => ['bool', 'calendar'=>'IntlCalendar', 'option'=>'int'],
'intlcal_set_skipped_wall_time_option' => ['bool', 'calendar'=>'IntlCalendar', 'option'=>'int'],
'intlcal_set_time' => ['bool', 'calendar'=>'IntlCalendar', 'timestamp'=>'float'],
'intlcal_set_time_zone' => ['bool', 'calendar'=>'IntlCalendar', 'timezone'=>'mixed'],
'intlcal_to_date_time' => ['DateTime|false', 'calendar'=>'IntlCalendar'],
'IntlCalendar::__construct' => ['void'],
'IntlCalendar::add' => ['bool', 'field'=>'int', 'amount'=>'int'],
'IntlCalendar::after' => ['bool', 'other'=>'IntlCalendar'],
'IntlCalendar::before' => ['bool', 'other'=>'IntlCalendar'],
'IntlCalendar::clear' => ['bool', 'field='=>'?int'],
'IntlCalendar::createInstance' => ['IntlCalendar', 'timeZone='=>'mixed', 'locale='=>'string'],
'IntlCalendar::equals' => ['bool', 'other'=>'IntlCalendar'],
'IntlCalendar::fieldDifference' => ['int', 'when'=>'float', 'field'=>'int'],
'IntlCalendar::fromDateTime' => ['IntlCalendar', 'dateTime'=>'DateTime|string'],
'IntlCalendar::get' => ['int', 'field'=>'int'],
'IntlCalendar::getActualMaximum' => ['int', 'field'=>'int'],
'IntlCalendar::getActualMinimum' => ['int', 'field'=>'int'],
'IntlCalendar::getAvailableLocales' => ['array'],
'IntlCalendar::getDayOfWeekType' => ['int', 'dayOfWeek'=>'int'],
'IntlCalendar::getErrorCode' => ['int'],
'IntlCalendar::getErrorMessage' => ['string'],
'IntlCalendar::getFirstDayOfWeek' => ['int'],
'IntlCalendar::getGreatestMinimum' => ['int', 'field'=>'int'],
'IntlCalendar::getKeywordValuesForLocale' => ['Iterator|false', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'],
'IntlCalendar::getLeastMaximum' => ['int', 'field'=>'int'],
'IntlCalendar::getLocale' => ['string', 'localeType'=>'int'],
'IntlCalendar::getMaximum' => ['int|false', 'field'=>'int'],
'IntlCalendar::getMinimalDaysInFirstWeek' => ['int'],
'IntlCalendar::getMinimum' => ['int', 'field'=>'int'],
'IntlCalendar::getNow' => ['float'],
'IntlCalendar::getRepeatedWallTimeOption' => ['int'],
'IntlCalendar::getSkippedWallTimeOption' => ['int'],
'IntlCalendar::getTime' => ['float'],
'IntlCalendar::getTimeZone' => ['IntlTimeZone'],
'IntlCalendar::getType' => ['string'],
'IntlCalendar::getWeekendTransition' => ['int', 'dayOfWeek'=>'string'],
'IntlCalendar::inDaylightTime' => ['bool'],
'IntlCalendar::isEquivalentTo' => ['bool', 'other'=>'IntlCalendar'],
'IntlCalendar::isLenient' => ['bool'],
'IntlCalendar::isSet' => ['bool', 'field'=>'int'],
'IntlCalendar::isWeekend' => ['bool', 'date='=>'?float'],
'IntlCalendar::roll' => ['bool', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'],
'IntlCalendar::set' => ['bool', 'field'=>'int', 'value'=>'int'],
'IntlCalendar::set\'1' => ['bool', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'],
'IntlCalendar::setFirstDayOfWeek' => ['bool', 'dayOfWeek'=>'int'],
'IntlCalendar::setLenient' => ['bool', 'isLenient'=>'string'],
'IntlCalendar::setMinimalDaysInFirstWeek' => ['bool', 'minimalDays'=>'int'],
'IntlCalendar::setRepeatedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
'IntlCalendar::setSkippedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
'IntlCalendar::setTime' => ['bool', 'date'=>'float'],
'IntlCalendar::setTimeZone' => ['bool', 'timeZone'=>'mixed'],
'IntlCalendar::toDateTime' => ['DateTime|false'],
'IntlChar::charAge' => ['array', 'char'=>'int|string'],
'IntlChar::charDigitValue' => ['int', 'codepoint'=>'mixed'],
'IntlChar::charDirection' => ['int', 'codepoint'=>'mixed'],
'IntlChar::charFromName' => ['?int', 'name'=>'string', 'namechoice='=>'int'],
'IntlChar::charMirror' => ['mixed', 'codepoint'=>'mixed'],
'IntlChar::charName' => ['string', 'char'=>'int|string', 'namechoice='=>'int'],
'IntlChar::charType' => ['int', 'codepoint'=>'mixed'],
'IntlChar::chr' => ['string', 'codepoint'=>'mixed'],
'IntlChar::digit' => ['int|false', 'char'=>'int|string', 'radix='=>'int'],
'IntlChar::enumCharNames' => ['void', 'start'=>'mixed', 'limit'=>'mixed', 'callback'=>'callable', 'nameChoice='=>'int'],
'IntlChar::enumCharTypes' => ['void', 'cb='=>'callable'],
'IntlChar::foldCase' => ['int|string', 'char'=>'int|string', 'options='=>'int'],
'IntlChar::forDigit' => ['int', 'digit'=>'int', 'radix'=>'int'],
'IntlChar::getBidiPairedBracket' => ['mixed', 'codepoint'=>'mixed'],
'IntlChar::getBlockCode' => ['int', 'char'=>'int|string'],
'IntlChar::getCombiningClass' => ['int', 'codepoint'=>'mixed'],
'IntlChar::getFC_NFKC_Closure' => ['string', 'char'=>'int|string'],
'IntlChar::getIntPropertyMaxValue' => ['int', 'property'=>'int'],
'IntlChar::getIntPropertyMinValue' => ['int', 'property'=>'int'],
'IntlChar::getIntPropertyValue' => ['int', 'char'=>'int|string', 'property'=>'int'],
'IntlChar::getNumericValue' => ['float', 'char'=>'int|string'],
'IntlChar::getPropertyEnum' => ['int', 'alias'=>'string'],
'IntlChar::getPropertyName' => ['string|false', 'property'=>'int', 'namechoice='=>'int'],
'IntlChar::getPropertyValueEnum' => ['int', 'property'=>'int', 'name'=>'string'],
'IntlChar::getPropertyValueName' => ['string|false', 'prop'=>'int', 'value'=>'int', 'namechoice='=>'int'],
'IntlChar::getUnicodeVersion' => ['array'],
'IntlChar::hasBinaryProperty' => ['bool', 'char'=>'int|string', 'property'=>'int'],
'IntlChar::isalnum' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isalpha' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isbase' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isblank' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::iscntrl' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isdefined' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isdigit' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isgraph' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isIDIgnorable' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isIDPart' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isIDStart' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isISOControl' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isJavaIDPart' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isJavaIDStart' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isJavaSpaceChar' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::islower' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isMirrored' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isprint' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::ispunct' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isspace' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::istitle' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isUAlphabetic' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isULowercase' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isupper' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isUUppercase' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isUWhiteSpace' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isWhitespace' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::isxdigit' => ['bool', 'codepoint'=>'mixed'],
'IntlChar::ord' => ['int', 'character'=>'mixed'],
'IntlChar::tolower' => ['mixed', 'codepoint'=>'mixed'],
'IntlChar::totitle' => ['mixed', 'codepoint'=>'mixed'],
'IntlChar::toupper' => ['mixed', 'codepoint'=>'mixed'],
'IntlCodePointBreakIterator::__construct' => ['void'],
'IntlCodePointBreakIterator::createCharacterInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlCodePointBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'],
'IntlCodePointBreakIterator::createLineInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlCodePointBreakIterator::createSentenceInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlCodePointBreakIterator::createTitleInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlCodePointBreakIterator::createWordInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlCodePointBreakIterator::current' => ['int'],
'IntlCodePointBreakIterator::first' => ['int'],
'IntlCodePointBreakIterator::following' => ['int', 'offset'=>'string'],
'IntlCodePointBreakIterator::getErrorCode' => ['int'],
'IntlCodePointBreakIterator::getErrorMessage' => ['string'],
'IntlCodePointBreakIterator::getLastCodePoint' => ['int'],
'IntlCodePointBreakIterator::getLocale' => ['string', 'locale_type'=>'string'],
'IntlCodePointBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'string'],
'IntlCodePointBreakIterator::getText' => ['?string'],
'IntlCodePointBreakIterator::isBoundary' => ['bool', 'offset'=>'string'],
'IntlCodePointBreakIterator::last' => ['int'],
'IntlCodePointBreakIterator::next' => ['int', 'offset='=>'string'],
'IntlCodePointBreakIterator::preceding' => ['int', 'offset'=>'string'],
'IntlCodePointBreakIterator::previous' => ['int'],
'IntlCodePointBreakIterator::setText' => ['?bool', 'text'=>'string'],
'IntlDateFormatter::__construct' => ['void', 'locale'=>'?string', 'dateType='=>'int', 'timeType='=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
'IntlDateFormatter::create' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType='=>'int', 'timeType='=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
'IntlDateFormatter::format' => ['string|false', 'datetime'=>'IntlCalendar|DateTimeInterface|array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int}|array{tm_sec: int, tm_min: int, tm_hour: int, tm_mday: int, tm_mon: int, tm_year: int, tm_wday: int, tm_yday: int, tm_isdst: int}|string|int|float'],
'IntlDateFormatter::formatObject' => ['string|false', 'datetime'=>'IntlCalendar|DateTimeInterface', 'format='=>'array{0: int, 1: int}|int|string|null', 'locale='=>'?string'],
'IntlDateFormatter::getCalendar' => ['int|false'],
'IntlDateFormatter::getCalendarObject' => ['IntlCalendar|false|null'],
'IntlDateFormatter::getDateType' => ['int|false'],
'IntlDateFormatter::getErrorCode' => ['int'],
'IntlDateFormatter::getErrorMessage' => ['string'],
'IntlDateFormatter::getLocale' => ['string|false', 'type='=>'int'],
'IntlDateFormatter::getPattern' => ['string|false'],
'IntlDateFormatter::getTimeType' => ['int|false'],
'IntlDateFormatter::getTimeZone' => ['IntlTimeZone|false'],
'IntlDateFormatter::getTimeZoneId' => ['string|false'],
'IntlDateFormatter::isLenient' => ['bool'],
'IntlDateFormatter::localtime' => ['array|false', 'string'=>'string', '&rw_offset='=>'int'],
'IntlDateFormatter::parse' => ['int|float|false', 'string'=>'string', '&rw_offset='=>'int'],
'IntlDateFormatter::setCalendar' => ['bool', 'calendar'=>'IntlCalendar|int|null'],
'IntlDateFormatter::setLenient' => ['void', 'lenient'=>'bool'],
'IntlDateFormatter::setPattern' => ['bool', 'pattern'=>'string'],
'IntlDateFormatter::setTimeZone' => ['null|false', 'timezone'=>'IntlTimeZone|DateTimeZone|string|null'],
'IntlException::__clone' => ['void'],
'IntlException::__construct' => ['void'],
'IntlException::__toString' => ['string'],
'IntlException::__wakeup' => ['void'],
'IntlException::getCode' => ['int'],
'IntlException::getFile' => ['string'],
'IntlException::getLine' => ['int'],
'IntlException::getMessage' => ['string'],
'IntlException::getPrevious' => ['?Throwable'],
'IntlException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'IntlException::getTraceAsString' => ['string'],
'intlgregcal_create_instance' => ['IntlGregorianCalendar', 'timezoneOrYear='=>'mixed', 'localeOrMonth='=>'string'],
'intlgregcal_get_gregorian_change' => ['float', 'calendar'=>'IntlGregorianCalendar'],
'intlgregcal_is_leap_year' => ['bool', 'calendar'=>'int'],
'intlgregcal_set_gregorian_change' => ['bool', 'calendar'=>'IntlGregorianCalendar', 'timestamp'=>'float'],
'IntlGregorianCalendar::__construct' => ['void'],
'IntlGregorianCalendar::add' => ['bool', 'field'=>'int', 'amount'=>'int'],
'IntlGregorianCalendar::after' => ['bool', 'other'=>'IntlCalendar'],
'IntlGregorianCalendar::before' => ['bool', 'other'=>'IntlCalendar'],
'IntlGregorianCalendar::clear' => ['bool', 'field='=>'?int'],
'IntlGregorianCalendar::createInstance' => ['IntlGregorianCalendar', 'timeZone='=>'mixed', 'locale='=>'string'],
'IntlGregorianCalendar::equals' => ['bool', 'other'=>'IntlCalendar'],
'IntlGregorianCalendar::fieldDifference' => ['int', 'when'=>'float', 'field'=>'int'],
'IntlGregorianCalendar::fromDateTime' => ['IntlCalendar', 'dateTime'=>'DateTime|string'],
'IntlGregorianCalendar::get' => ['int', 'field'=>'int'],
'IntlGregorianCalendar::getActualMaximum' => ['int', 'field'=>'int'],
'IntlGregorianCalendar::getActualMinimum' => ['int', 'field'=>'int'],
'IntlGregorianCalendar::getAvailableLocales' => ['array'],
'IntlGregorianCalendar::getDayOfWeekType' => ['int', 'dayOfWeek'=>'int'],
'IntlGregorianCalendar::getErrorCode' => ['int'],
'IntlGregorianCalendar::getErrorMessage' => ['string'],
'IntlGregorianCalendar::getFirstDayOfWeek' => ['int'],
'IntlGregorianCalendar::getGreatestMinimum' => ['int', 'field'=>'int'],
'IntlGregorianCalendar::getGregorianChange' => ['float'],
'IntlGregorianCalendar::getKeywordValuesForLocale' => ['Iterator', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'],
'IntlGregorianCalendar::getLeastMaximum' => ['int', 'field'=>'int'],
'IntlGregorianCalendar::getLocale' => ['string', 'localeType'=>'int'],
'IntlGregorianCalendar::getMaximum' => ['int', 'field'=>'int'],
'IntlGregorianCalendar::getMinimalDaysInFirstWeek' => ['int'],
'IntlGregorianCalendar::getMinimum' => ['int', 'field'=>'int'],
'IntlGregorianCalendar::getNow' => ['float'],
'IntlGregorianCalendar::getRepeatedWallTimeOption' => ['int'],
'IntlGregorianCalendar::getSkippedWallTimeOption' => ['int'],
'IntlGregorianCalendar::getTime' => ['float'],
'IntlGregorianCalendar::getTimeZone' => ['IntlTimeZone'],
'IntlGregorianCalendar::getType' => ['string'],
'IntlGregorianCalendar::getWeekendTransition' => ['int', 'dayOfWeek'=>'string'],
'IntlGregorianCalendar::inDaylightTime' => ['bool'],
'IntlGregorianCalendar::isEquivalentTo' => ['bool', 'other'=>'IntlCalendar'],
'IntlGregorianCalendar::isLeapYear' => ['bool', 'year'=>'int'],
'IntlGregorianCalendar::isLenient' => ['bool'],
'IntlGregorianCalendar::isSet' => ['bool', 'field'=>'int'],
'IntlGregorianCalendar::isWeekend' => ['bool', 'date='=>'float'],
'IntlGregorianCalendar::roll' => ['bool', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'],
'IntlGregorianCalendar::set' => ['bool', 'field'=>'int', 'value'=>'int'],
'IntlGregorianCalendar::set\'1' => ['bool', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'],
'IntlGregorianCalendar::setFirstDayOfWeek' => ['bool', 'dayOfWeek'=>'int'],
'IntlGregorianCalendar::setGregorianChange' => ['bool', 'date'=>'float'],
'IntlGregorianCalendar::setLenient' => ['bool', 'isLenient'=>'string'],
'IntlGregorianCalendar::setMinimalDaysInFirstWeek' => ['bool', 'minimalDays'=>'int'],
'IntlGregorianCalendar::setRepeatedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
'IntlGregorianCalendar::setSkippedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'],
'IntlGregorianCalendar::setTime' => ['bool', 'date'=>'float'],
'IntlGregorianCalendar::setTimeZone' => ['bool', 'timeZone'=>'mixed'],
'IntlGregorianCalendar::toDateTime' => ['DateTime'],
'IntlIterator::__construct' => ['void'],
'IntlIterator::current' => ['mixed'],
'IntlIterator::key' => ['string'],
'IntlIterator::next' => ['void'],
'IntlIterator::rewind' => ['void'],
'IntlIterator::valid' => ['bool'],
'IntlPartsIterator::getBreakIterator' => ['IntlBreakIterator'],
'IntlRuleBasedBreakIterator::__construct' => ['void', 'rules'=>'string', 'areCompiled='=>'string'],
'IntlRuleBasedBreakIterator::createCharacterInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlRuleBasedBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'],
'IntlRuleBasedBreakIterator::createLineInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlRuleBasedBreakIterator::createSentenceInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlRuleBasedBreakIterator::createTitleInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlRuleBasedBreakIterator::createWordInstance' => ['?IntlRuleBasedBreakIterator', 'locale='=>'?string'],
'IntlRuleBasedBreakIterator::current' => ['int'],
'IntlRuleBasedBreakIterator::first' => ['int'],
'IntlRuleBasedBreakIterator::following' => ['int', 'offset'=>'int'],
'IntlRuleBasedBreakIterator::getBinaryRules' => ['string'],
'IntlRuleBasedBreakIterator::getErrorCode' => ['int'],
'IntlRuleBasedBreakIterator::getErrorMessage' => ['string'],
'IntlRuleBasedBreakIterator::getLocale' => ['string', 'locale_type'=>'string'],
'IntlRuleBasedBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'int'],
'IntlRuleBasedBreakIterator::getRules' => ['string'],
'IntlRuleBasedBreakIterator::getRuleStatus' => ['int'],
'IntlRuleBasedBreakIterator::getRuleStatusVec' => ['array'],
'IntlRuleBasedBreakIterator::getText' => ['?string'],
'IntlRuleBasedBreakIterator::isBoundary' => ['bool', 'offset'=>'int'],
'IntlRuleBasedBreakIterator::last' => ['int'],
'IntlRuleBasedBreakIterator::next' => ['int', 'offset='=>'?int'],
'IntlRuleBasedBreakIterator::preceding' => ['int', 'offset'=>'int'],
'IntlRuleBasedBreakIterator::previous' => ['int'],
'IntlRuleBasedBreakIterator::setText' => ['?bool', 'text'=>'string'],
'IntlTimeZone::countEquivalentIDs' => ['int|false', 'zoneId'=>'string'],
'IntlTimeZone::createDefault' => ['IntlTimeZone'],
'IntlTimeZone::createEnumeration' => ['IntlIterator|false', 'countryOrRawOffset='=>'mixed'],
'IntlTimeZone::createTimeZone' => ['IntlTimeZone|false', 'zoneId'=>'string'],
'IntlTimeZone::createTimeZoneIDEnumeration' => ['IntlIterator|false', 'zoneType'=>'int', 'region='=>'string', 'rawOffset='=>'int'],
'IntlTimeZone::fromDateTimeZone' => ['?IntlTimeZone', 'zoneId'=>'DateTimeZone'],
'IntlTimeZone::getCanonicalID' => ['string|false', 'zoneId'=>'string', '&w_isSystemID='=>'bool'],
'IntlTimeZone::getDisplayName' => ['string|false', 'isDaylight='=>'bool', 'style='=>'int', 'locale='=>'string'],
'IntlTimeZone::getDSTSavings' => ['int'],
'IntlTimeZone::getEquivalentID' => ['string|false', 'zoneId'=>'string', 'index'=>'int'],
'IntlTimeZone::getErrorCode' => ['int'],
'IntlTimeZone::getErrorMessage' => ['string'],
'IntlTimeZone::getGMT' => ['IntlTimeZone'],
'IntlTimeZone::getID' => ['string'],
'IntlTimeZone::getIDForWindowsID' => ['string', 'timezone'=>'string', 'region='=>'string'],
'IntlTimeZone::getOffset' => ['int', 'date'=>'float', 'local'=>'bool', '&w_rawOffset'=>'int', '&w_dstOffset'=>'int'],
'IntlTimeZone::getRawOffset' => ['int'],
'IntlTimeZone::getRegion' => ['string|false', 'zoneId'=>'string'],
'IntlTimeZone::getTZDataVersion' => ['string'],
'IntlTimeZone::getUnknown' => ['IntlTimeZone'],
'IntlTimeZone::getWindowsID' => ['string|false', 'timezone'=>'string'],
'IntlTimeZone::hasSameRules' => ['bool', 'otherTimeZone'=>'IntlTimeZone'],
'IntlTimeZone::toDateTimeZone' => ['DateTimeZone|false'],
'IntlTimeZone::useDaylightTime' => ['bool'],
'intltz_count_equivalent_ids' => ['int', 'timezoneId'=>'string'],
'intltz_create_enumeration' => ['IntlIterator', 'countryOrRawOffset'=>'mixed'],
'intltz_create_time_zone' => ['?IntlTimeZone', 'timezoneId'=>'string'],
'intltz_from_date_time_zone' => ['?IntlTimeZone', 'timezone'=>'DateTimeZone'],
'intltz_get_canonical_id' => ['string', 'timezoneId'=>'string', '&isSystemId'=>'bool'],
'intltz_get_display_name' => ['string', 'timezone'=>'IntlTimeZone', 'dst'=>'bool', 'style'=>'int', 'locale'=>'string'],
'intltz_get_dst_savings' => ['int', 'timezone'=>'IntlTimeZone'],
'intltz_get_equivalent_id' => ['string', 'timezoneId'=>'string', 'offset'=>'int'],
'intltz_get_error_code' => ['int', 'timezone'=>'IntlTimeZone'],
'intltz_get_error_message' => ['string', 'timezone'=>'IntlTimeZone'],
'intltz_get_id' => ['string', 'timezone'=>'IntlTimeZone'],
'intltz_get_offset' => ['bool', 'timezone'=>'IntlTimeZone', 'timestamp'=>'float', 'local'=>'bool', '&rawOffset'=>'int', '&dstOffset'=>'int'],
'intltz_get_raw_offset' => ['int', 'timezone'=>'IntlTimeZone'],
'intltz_get_tz_data_version' => ['string', 'object'=>'IntlTimeZone'],
'intltz_getGMT' => ['IntlTimeZone'],
'intltz_has_same_rules' => ['bool', 'timezone'=>'IntlTimeZone', 'other'=>'IntlTimeZone'],
'intltz_to_date_time_zone' => ['DateTimeZone', 'timezone'=>'IntlTimeZone'],
'intltz_use_daylight_time' => ['bool', 'timezone'=>'IntlTimeZone'],
'intlz_create_default' => ['IntlTimeZone'],
'intval' => ['int', 'value'=>'mixed', 'base='=>'int'],
'InvalidArgumentException::__clone' => ['void'],
'InvalidArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'InvalidArgumentException::__toString' => ['string'],
'InvalidArgumentException::getCode' => ['int'],
'InvalidArgumentException::getFile' => ['string'],
'InvalidArgumentException::getLine' => ['int'],
'InvalidArgumentException::getMessage' => ['string'],
'InvalidArgumentException::getPrevious' => ['?Throwable'],
'InvalidArgumentException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'InvalidArgumentException::getTraceAsString' => ['string'],
'ip2long' => ['int|false', 'ip'=>'string'],
'iptcembed' => ['string|bool', 'iptc_data'=>'string', 'filename'=>'string', 'spool='=>'int'],
'iptcparse' => ['array|false', 'iptc_block'=>'string'],
'is_a' => ['bool', 'object_or_class'=>'mixed', 'class'=>'string', 'allow_string='=>'bool'],
'is_array' => ['bool', 'value'=>'mixed'],
'is_bool' => ['bool', 'value'=>'mixed'],
'is_callable' => ['bool', 'value'=>'callable|mixed', 'syntax_only='=>'bool', '&w_callable_name='=>'string'],
'is_countable' => ['bool', 'value'=>'mixed'],
'is_dir' => ['bool', 'filename'=>'string'],
'is_double' => ['bool', 'value'=>'mixed'],
'is_executable' => ['bool', 'filename'=>'string'],
'is_file' => ['bool', 'filename'=>'string'],
'is_finite' => ['bool', 'num'=>'float'],
'is_float' => ['bool', 'value'=>'mixed'],
'is_infinite' => ['bool', 'num'=>'float'],
'is_int' => ['bool', 'value'=>'mixed'],
'is_integer' => ['bool', 'value'=>'mixed'],
'is_iterable' => ['bool', 'value'=>'mixed'],
'is_link' => ['bool', 'filename'=>'string'],
'is_long' => ['bool', 'value'=>'mixed'],
'is_nan' => ['bool', 'num'=>'float'],
'is_null' => ['bool', 'value'=>'mixed'],
'is_numeric' => ['bool', 'value'=>'mixed'],
'is_object' => ['bool', 'value'=>'mixed'],
'is_readable' => ['bool', 'filename'=>'string'],
'is_real' => ['bool', 'value'=>'mixed'],
'is_resource' => ['bool', 'value'=>'mixed'],
'is_scalar' => ['bool', 'value'=>'mixed'],
'is_soap_fault' => ['bool', 'object'=>'mixed'],
'is_string' => ['bool', 'value'=>'mixed'],
'is_subclass_of' => ['bool', 'object_or_class'=>'object|string', 'class'=>'class-string', 'allow_string='=>'bool'],
'is_tainted' => ['bool', 'string'=>'string'],
'is_uploaded_file' => ['bool', 'filename'=>'string'],
'is_writable' => ['bool', 'filename'=>'string'],
'is_writeable' => ['bool', 'filename'=>'string'],
'isset' => ['bool', 'value'=>'mixed', '...rest='=>'mixed'],
'Iterator::current' => ['mixed'],
'Iterator::key' => ['mixed'],
'Iterator::next' => ['void'],
'Iterator::rewind' => ['void'],
'Iterator::valid' => ['bool'],
'iterator_apply' => ['0|positive-int', 'iterator'=>'Traversable', 'callback'=>'callable(mixed):bool', 'args='=>'?array'],
'iterator_count' => ['0|positive-int', 'iterator'=>'Traversable'],
'iterator_to_array' => ['array', 'iterator'=>'Traversable', 'preserve_keys='=>'bool'],
'IteratorAggregate::getIterator' => ['Traversable'],
'IteratorIterator::__construct' => ['void', 'it'=>'Traversable'],
'IteratorIterator::current' => ['mixed'],
'IteratorIterator::getInnerIterator' => ['Iterator'],
'IteratorIterator::key' => ['mixed'],
'IteratorIterator::next' => ['void'],
'IteratorIterator::rewind' => ['void'],
'IteratorIterator::valid' => ['bool'],
'java_last_exception_clear' => ['void'],
'java_last_exception_get' => ['object'],
'java_reload' => ['array', 'new_jarpath'=>'string'],
'java_require' => ['array', 'new_classpath'=>'string'],
'java_set_encoding' => ['array', 'encoding'=>'string'],
'java_set_ignore_case' => ['void', 'ignore'=>'bool'],
'java_throw_exceptions' => ['void', 'throw'=>'bool'],
'JavaException::getCause' => ['object'],
'jddayofweek' => ['string|int', 'julian_day'=>'int', 'mode='=>'int'],
'jdmonthname' => ['string', 'julian_day'=>'int', 'mode'=>'int'],
'jdtofrench' => ['string', 'julian_day'=>'int'],
'jdtogregorian' => ['string', 'julian_day'=>'int'],
'jdtojewish' => ['string', 'julian_day'=>'int', 'hebrew='=>'bool', 'flags='=>'int'],
'jdtojulian' => ['string', 'julian_day'=>'int'],
'jdtounix' => ['int', 'julian_day'=>'int'],
'jewishtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
'jobqueue_license_info' => ['array'],
'join' => ['string', 'separator'=>'string', 'array'=>'array'],
'join\'1' => ['string', 'separator'=>'array'],
'json_decode' => ['mixed', 'json'=>'string', 'associative='=>'?bool', 'depth='=>'int', 'flags='=>'int'],
'json_encode' => ['non-empty-string|false', 'value'=>'mixed', 'flags='=>'int', 'depth='=>'int'],
'json_last_error' => ['int'],
'json_last_error_msg' => ['string'],
'JsonException::__clone' => ['void'],
'JsonException::__construct' => ['void'],
'JsonException::__toString' => ['string'],
'JsonException::__wakeup' => ['void'],
'JsonException::getCode' => ['int'],
'JsonException::getFile' => ['string'],
'JsonException::getLine' => ['int'],
'JsonException::getMessage' => ['string'],
'JsonException::getPrevious' => ['?Throwable'],
'JsonException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'JsonException::getTraceAsString' => ['string'],
'JsonIncrementalParser::__construct' => ['void', 'depth'=>'', 'options'=>''],
'JsonIncrementalParser::get' => ['', 'options'=>''],
'JsonIncrementalParser::getError' => [''],
'JsonIncrementalParser::parse' => ['', 'json'=>''],
'JsonIncrementalParser::parseFile' => ['', 'filename'=>''],
'JsonIncrementalParser::reset' => [''],
'JsonSerializable::jsonSerialize' => ['mixed'],
'Judy::__construct' => ['void', 'judy_type'=>'int'],
'Judy::__destruct' => ['void'],
'Judy::byCount' => ['int', 'nth_index'=>'int'],
'Judy::count' => ['int', 'index_start='=>'int', 'index_end='=>'int'],
'Judy::first' => ['mixed', 'index='=>'mixed'],
'Judy::firstEmpty' => ['mixed', 'index='=>'mixed'],
'Judy::free' => ['int'],
'Judy::getType' => ['int'],
'Judy::last' => ['mixed', 'index='=>'string'],
'Judy::lastEmpty' => ['mixed', 'index='=>'int'],
'Judy::memoryUsage' => ['int'],
'Judy::next' => ['mixed', 'index'=>'mixed'],
'Judy::nextEmpty' => ['mixed', 'index'=>'mixed'],
'Judy::offsetExists' => ['bool', 'offset'=>'mixed'],
'Judy::offsetGet' => ['mixed', 'offset'=>'mixed'],
'Judy::offsetSet' => ['bool', 'offset'=>'mixed', 'value'=>'mixed'],
'Judy::offsetUnset' => ['bool', 'offset'=>'mixed'],
'Judy::prev' => ['mixed', 'index'=>'mixed'],
'Judy::prevEmpty' => ['mixed', 'index'=>'mixed'],
'Judy::size' => ['int'],
'judy_type' => ['int', 'array'=>'judy'],
'judy_version' => ['string'],
'juliantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'],
'kadm5_chpass_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password'=>'string'],
'kadm5_create_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password='=>'string', 'options='=>'array'],
'kadm5_delete_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string'],
'kadm5_destroy' => ['bool', 'handle'=>'resource'],
'kadm5_flush' => ['bool', 'handle'=>'resource'],
'kadm5_get_policies' => ['array', 'handle'=>'resource'],
'kadm5_get_principal' => ['array', 'handle'=>'resource', 'principal'=>'string'],
'kadm5_get_principals' => ['array', 'handle'=>'resource'],
'kadm5_init_with_password' => ['resource', 'admin_server'=>'string', 'realm'=>'string', 'principal'=>'string', 'password'=>'string'],
'kadm5_modify_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'options'=>'array'],
'key' => ['int|string|null', 'array'=>'array|object'],
'key_exists' => ['bool', 'key'=>'string|int', 'array'=>'array'],
'krsort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
'ksort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
'KTaglib_ID3v2_AttachedPictureFrame::getDescription' => ['string'],
'KTaglib_ID3v2_AttachedPictureFrame::getMimeType' => ['string'],
'KTaglib_ID3v2_AttachedPictureFrame::getType' => ['int'],
'KTaglib_ID3v2_AttachedPictureFrame::savePicture' => ['bool', 'filename'=>'string'],
'KTaglib_ID3v2_AttachedPictureFrame::setMimeType' => ['string', 'type'=>'string'],
'KTaglib_ID3v2_AttachedPictureFrame::setPicture' => ['', 'filename'=>'string'],
'KTaglib_ID3v2_AttachedPictureFrame::setType' => ['', 'type'=>'int'],
'KTaglib_ID3v2_Frame::__toString' => ['string'],
'KTaglib_ID3v2_Frame::getDescription' => ['string'],
'KTaglib_ID3v2_Frame::getMimeType' => ['string'],
'KTaglib_ID3v2_Frame::getSize' => ['int'],
'KTaglib_ID3v2_Frame::getType' => ['int'],
'KTaglib_ID3v2_Frame::savePicture' => ['bool', 'filename'=>'string'],
'KTaglib_ID3v2_Frame::setMimeType' => ['string', 'type'=>'string'],
'KTaglib_ID3v2_Frame::setPicture' => ['void', 'filename'=>'string'],
'KTaglib_ID3v2_Frame::setType' => ['void', 'type'=>'int'],
'KTaglib_ID3v2_Tag::addFrame' => ['bool', 'frame'=>'KTaglib_ID3v2_Frame'],
'KTaglib_ID3v2_Tag::getFrameList' => ['array'],
'KTaglib_MPEG_AudioProperties::getBitrate' => ['int'],
'KTaglib_MPEG_AudioProperties::getChannels' => ['int'],
'KTaglib_MPEG_AudioProperties::getLayer' => ['int'],
'KTaglib_MPEG_AudioProperties::getLength' => ['int'],
'KTaglib_MPEG_AudioProperties::getSampleBitrate' => ['int'],
'KTaglib_MPEG_AudioProperties::getVersion' => ['int'],
'KTaglib_MPEG_AudioProperties::isCopyrighted' => ['bool'],
'KTaglib_MPEG_AudioProperties::isOriginal' => ['bool'],
'KTaglib_MPEG_AudioProperties::isProtectionEnabled' => ['bool'],
'KTaglib_MPEG_File::getAudioProperties' => ['KTaglib_MPEG_File'],
'KTaglib_MPEG_File::getID3v1Tag' => ['KTaglib_ID3v1_Tag', 'create='=>'bool'],
'KTaglib_MPEG_File::getID3v2Tag' => ['KTaglib_ID3v2_Tag', 'create='=>'bool'],
'KTaglib_Tag::getAlbum' => ['string'],
'KTaglib_Tag::getArtist' => ['string'],
'KTaglib_Tag::getComment' => ['string'],
'KTaglib_Tag::getGenre' => ['string'],
'KTaglib_Tag::getTitle' => ['string'],
'KTaglib_Tag::getTrack' => ['int'],
'KTaglib_Tag::getYear' => ['int'],
'KTaglib_Tag::isEmpty' => ['bool'],
'labelcacheObj::freeCache' => ['bool'],
'labelObj::__construct' => ['void'],
'labelObj::convertToString' => ['string'],
'labelObj::deleteStyle' => ['int', 'index'=>'int'],
'labelObj::free' => ['void'],
'labelObj::getBinding' => ['string', 'labelbinding'=>'mixed'],
'labelObj::getExpressionString' => ['string'],
'labelObj::getStyle' => ['styleObj', 'index'=>'int'],
'labelObj::getTextString' => ['string'],
'labelObj::moveStyleDown' => ['int', 'index'=>'int'],
'labelObj::moveStyleUp' => ['int', 'index'=>'int'],
'labelObj::removeBinding' => ['int', 'labelbinding'=>'mixed'],
'labelObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'labelObj::setBinding' => ['int', 'labelbinding'=>'mixed', 'value'=>'string'],
'labelObj::setExpression' => ['int', 'expression'=>'string'],
'labelObj::setText' => ['int', 'text'=>'string'],
'labelObj::updateFromString' => ['int', 'snippet'=>'string'],
'Lapack::eigenValues' => ['array', 'a'=>'array', 'left='=>'array', 'right='=>'array'],
'Lapack::identity' => ['array', 'n'=>'int'],
'Lapack::leastSquaresByFactorisation' => ['array', 'a'=>'array', 'b'=>'array'],
'Lapack::leastSquaresBySVD' => ['array', 'a'=>'array', 'b'=>'array'],
'Lapack::pseudoInverse' => ['array', 'a'=>'array'],
'Lapack::singularValues' => ['array', 'a'=>'array'],
'Lapack::solveLinearEquation' => ['array', 'a'=>'array', 'b'=>'array'],
'layerObj::addFeature' => ['int', 'shape'=>'shapeObj'],
'layerObj::applySLD' => ['int', 'sldxml'=>'string', 'namedlayer'=>'string'],
'layerObj::applySLDURL' => ['int', 'sldurl'=>'string', 'namedlayer'=>'string'],
'layerObj::clearProcessing' => ['void'],
'layerObj::close' => ['void'],
'layerObj::convertToString' => ['string'],
'layerObj::draw' => ['int', 'image'=>'imageObj'],
'layerObj::drawQuery' => ['int', 'image'=>'imageObj'],
'layerObj::free' => ['void'],
'layerObj::generateSLD' => ['string'],
'layerObj::getClass' => ['classObj', 'classIndex'=>'int'],
'layerObj::getClassIndex' => ['int', 'shape'=>'', 'classgroup'=>'', 'numclasses'=>''],
'layerObj::getExtent' => ['rectObj'],
'layerObj::getFilterString' => ['?string'],
'layerObj::getGridIntersectionCoordinates' => ['array'],
'layerObj::getItems' => ['array'],
'layerObj::getMetaData' => ['int', 'name'=>'string'],
'layerObj::getNumResults' => ['int'],
'layerObj::getProcessing' => ['array'],
'layerObj::getProjection' => ['string'],
'layerObj::getResult' => ['resultObj', 'index'=>'int'],
'layerObj::getResultsBounds' => ['rectObj'],
'layerObj::getShape' => ['shapeObj', 'result'=>'resultObj'],
'layerObj::getWMSFeatureInfoURL' => ['string', 'clickX'=>'int', 'clickY'=>'int', 'featureCount'=>'int', 'infoFormat'=>'string'],
'layerObj::isVisible' => ['bool'],
'layerObj::moveclassdown' => ['int', 'index'=>'int'],
'layerObj::moveclassup' => ['int', 'index'=>'int'],
'layerObj::ms_newLayerObj' => ['layerObj', 'map'=>'mapObj', 'layer'=>'layerObj'],
'layerObj::nextShape' => ['shapeObj'],
'layerObj::open' => ['int'],
'layerObj::queryByAttributes' => ['int', 'qitem'=>'string', 'qstring'=>'string', 'mode'=>'int'],
'layerObj::queryByFeatures' => ['int', 'slayer'=>'int'],
'layerObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'],
'layerObj::queryByRect' => ['int', 'rect'=>'rectObj'],
'layerObj::queryByShape' => ['int', 'shape'=>'shapeObj'],
'layerObj::removeClass' => ['?classObj', 'index'=>'int'],
'layerObj::removeMetaData' => ['int', 'name'=>'string'],
'layerObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'layerObj::setConnectionType' => ['int', 'connectiontype'=>'int', 'plugin_library'=>'string'],
'layerObj::setFilter' => ['int', 'expression'=>'string'],
'layerObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'],
'layerObj::setProjection' => ['int', 'proj_params'=>'string'],
'layerObj::setWKTProjection' => ['int', 'proj_params'=>'string'],
'layerObj::updateFromString' => ['int', 'snippet'=>'string'],
'lcfirst' => ['string', 'string'=>'string'],
'lcg_value' => ['float'],
'lchgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'],
'lchown' => ['bool', 'filename'=>'string', 'user'=>'string|int'],
'ldap_8859_to_t61' => ['string', 'value'=>'string'],
'ldap_add' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_add_ext' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_bind' => ['bool', 'ldap'=>'LDAP\Connection', 'dn='=>'string|null', 'password='=>'string|null'],
'ldap_bind_ext' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn='=>'string|null', 'password='=>'string|null', 'controls='=>'?array'],
'ldap_close' => ['bool', 'ldap'=>'LDAP\Connection'],
'ldap_compare' => ['bool|int', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'attribute'=>'string', 'value'=>'string', 'controls='=>'?array'],
'ldap_connect' => ['LDAP\Connection|false', 'uri='=>'?string', 'port='=>'int', 'wallet='=>'string', 'password='=>'string', 'auth_mode='=>'int'],
'ldap_count_entries' => ['int', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
'ldap_delete' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'controls='=>'?array'],
'ldap_delete_ext' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'controls='=>'?array'],
'ldap_dn2ufn' => ['string', 'dn'=>'string'],
'ldap_err2str' => ['string', 'errno'=>'int'],
'ldap_errno' => ['int', 'ldap'=>'LDAP\Connection'],
'ldap_error' => ['string', 'ldap'=>'LDAP\Connection'],
'ldap_escape' => ['string', 'value'=>'string', 'ignore='=>'string', 'flags='=>'int'],
'ldap_exop' => ['LDAP\Result|bool', 'ldap'=>'LDAP\Connection', 'request_oid'=>'string', 'request_data='=>'?string', 'controls='=>'?array', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
'ldap_exop_passwd' => ['bool|string', 'ldap'=>'LDAP\Connection', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string', '&w_controls='=>'array|null'],
'ldap_exop_refresh' => ['int|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'ttl'=>'int'],
'ldap_exop_whoami' => ['string|false', 'ldap'=>'LDAP\Connection'],
'ldap_explode_dn' => ['array|false', 'dn'=>'string', 'with_attrib'=>'int'],
'ldap_first_attribute' => ['string|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
'ldap_first_entry' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
'ldap_first_reference' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
'ldap_free_result' => ['bool', 'result'=>'LDAP\Result'],
'ldap_get_attributes' => ['array', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
'ldap_get_dn' => ['string|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
'ldap_get_entries' => ['array|false', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
'ldap_get_option' => ['bool', 'ldap'=>'LDAP\Connection', 'option'=>'int', '&w_value='=>'array|string|int|null'],
'ldap_get_values' => ['array|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry', 'attribute'=>'string'],
'ldap_get_values_len' => ['array|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry', 'attribute'=>'string'],
'ldap_list' => ['LDAP\Result|LDAP\Result[]|false', 'ldap'=>'LDAP\Connection|LDAP\Connection[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'controls='=>'?array'],
'ldap_mod_add' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_mod_add_ext' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_mod_del' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_mod_del_ext' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_mod_replace' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_mod_replace_ext' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_modify' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
'ldap_modify_batch' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'modifications_info'=>'array', 'controls='=>'?array'],
'ldap_next_attribute' => ['string|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
'ldap_next_entry' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
'ldap_next_reference' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
'ldap_parse_exop' => ['bool', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
'ldap_parse_reference' => ['bool', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry', '&w_referrals'=>'array'],
'ldap_parse_result' => ['bool', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result', '&w_error_code'=>'int', '&w_matched_dn='=>'string', '&w_error_message='=>'string', '&w_referrals='=>'array', '&w_controls='=>'array'],
'ldap_read' => ['LDAP\Result|LDAP\Result[]|false', 'ldap'=>'LDAP\Connection|LDAP\Connection[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'controls='=>'?array'],
'ldap_rename' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'?array'],
'ldap_rename_ext' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'?array'],
'ldap_sasl_bind' => ['bool', 'ldap'=>'LDAP\Connection', 'dn='=>'?string', 'password='=>'?string', 'mech='=>'?string', 'realm='=>'?string', 'authc_id='=>'?string', 'authz_id='=>'?string', 'props='=>'?string'],
'ldap_search' => ['LDAP\Result|LDAP\Result[]|false', 'ldap'=>'LDAP\Connection|LDAP\Connection[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'controls='=>'?array'],
'ldap_set_option' => ['bool', 'ldap'=>'LDAP\Connection|null', 'option'=>'int', 'value'=>'mixed'],
'ldap_set_rebind_proc' => ['bool', 'ldap'=>'LDAP\Connection', 'callback'=>'?callable'],
'ldap_start_tls' => ['bool', 'ldap'=>'LDAP\Connection'],
'ldap_t61_to_8859' => ['string', 'value'=>'string'],
'ldap_unbind' => ['bool', 'ldap'=>'LDAP\Connection'],
'leak' => ['', 'num_bytes'=>'int'],
'leak_variable' => ['', 'variable'=>'', 'leak_data'=>'bool'],
'legendObj::convertToString' => ['string'],
'legendObj::free' => ['void'],
'legendObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'legendObj::updateFromString' => ['int', 'snippet'=>'string'],
'LengthException::__clone' => ['void'],
'LengthException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'LengthException::__toString' => ['string'],
'LengthException::getCode' => ['int'],
'LengthException::getFile' => ['string'],
'LengthException::getLine' => ['int'],
'LengthException::getMessage' => ['string'],
'LengthException::getPrevious' => ['?Throwable'],
'LengthException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'LengthException::getTraceAsString' => ['string'],
'LevelDB::__construct' => ['void', 'name'=>'string', 'options='=>'array', 'read_options='=>'array', 'write_options='=>'array'],
'LevelDB::close' => [''],
'LevelDB::compactRange' => ['', 'start'=>'', 'limit'=>''],
'LevelDB::delete' => ['bool', 'key'=>'string', 'write_options='=>'array'],
'LevelDB::destroy' => ['', 'name'=>'', 'options='=>'array'],
'LevelDB::get' => ['bool|string', 'key'=>'string', 'read_options='=>'array'],
'LevelDB::getApproximateSizes' => ['', 'start'=>'', 'limit'=>''],
'LevelDB::getIterator' => ['LevelDBIterator', 'options='=>'array'],
'LevelDB::getProperty' => ['mixed', 'name'=>'string'],
'LevelDB::getSnapshot' => ['LevelDBSnapshot'],
'LevelDB::put' => ['', 'key'=>'string', 'value'=>'string', 'write_options='=>'array'],
'LevelDB::repair' => ['', 'name'=>'', 'options='=>'array'],
'LevelDB::set' => ['', 'key'=>'string', 'value'=>'string', 'write_options='=>'array'],
'LevelDB::write' => ['', 'batch'=>'LevelDBWriteBatch', 'write_options='=>'array'],
'LevelDBIterator::__construct' => ['void', 'db'=>'LevelDB', 'read_options='=>'array'],
'LevelDBIterator::current' => ['mixed'],
'LevelDBIterator::destroy' => [''],
'LevelDBIterator::getError' => [''],
'LevelDBIterator::key' => ['int|string'],
'LevelDBIterator::last' => [''],
'LevelDBIterator::next' => ['void'],
'LevelDBIterator::prev' => [''],
'LevelDBIterator::rewind' => ['void'],
'LevelDBIterator::seek' => ['', 'key'=>''],
'LevelDBIterator::valid' => ['bool'],
'LevelDBSnapshot::__construct' => ['void', 'db'=>'LevelDB'],
'LevelDBSnapshot::release' => [''],
'LevelDBWriteBatch::__construct' => ['void', 'name'=>'', 'options='=>'array', 'read_options='=>'array', 'write_options='=>'array'],
'LevelDBWriteBatch::clear' => [''],
'LevelDBWriteBatch::delete' => ['', 'key'=>'', 'write_options='=>'array'],
'LevelDBWriteBatch::put' => ['', 'key'=>'', 'value'=>'', 'write_options='=>'array'],
'LevelDBWriteBatch::set' => ['', 'key'=>'', 'value'=>'', 'write_options='=>'array'],
'levenshtein' => ['int', 'string1'=>'string', 'string2'=>'string'],
'levenshtein\'1' => ['int', 'string1'=>'string', 'string2'=>'string', 'insertion_cost'=>'int', 'repetition_cost'=>'int', 'deletion_cost'=>'int'],
'libxml_clear_errors' => ['void'],
'libxml_disable_entity_loader' => ['bool', 'disable='=>'bool'],
'libxml_get_errors' => ['list<LibXMLError>'],
'libxml_get_last_error' => ['LibXMLError|false'],
'libxml_get_external_entity_loader' => ['(callable(string,string,array{directory:?string,intSubName:?string,extSubURI:?string,extSubSystem:?string}):(resource|string|null))|null'],
'libxml_set_external_entity_loader' => ['bool', 'resolver_function'=>'(callable(string,string,array{directory:?string,intSubName:?string,extSubURI:?string,extSubSystem:?string}):(resource|string|null))|null'],
'libxml_set_streams_context' => ['void', 'context'=>'resource'],
'libxml_use_internal_errors' => ['bool', 'use_errors='=>'?bool'],
'LimitIterator::__construct' => ['void', 'iterator'=>'Iterator', 'offset='=>'int', 'count='=>'int'],
'LimitIterator::current' => ['mixed'],
'LimitIterator::getInnerIterator' => ['Iterator'],
'LimitIterator::getPosition' => ['int'],
'LimitIterator::key' => ['mixed'],
'LimitIterator::next' => ['void'],
'LimitIterator::rewind' => ['void'],
'LimitIterator::seek' => ['int', 'position'=>'int'],
'LimitIterator::valid' => ['bool'],
'lineObj::__construct' => ['void'],
'lineObj::add' => ['int', 'point'=>'pointObj'],
'lineObj::addXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'],
'lineObj::addXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'],
'lineObj::ms_newLineObj' => ['lineObj'],
'lineObj::point' => ['pointObj', 'i'=>'int'],
'lineObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
'link' => ['bool', 'target'=>'string', 'link'=>'string'],
'linkinfo' => ['int|false', 'path'=>'string'],
'litespeed_request_headers' => ['array'],
'litespeed_response_headers' => ['array'],
'Locale::acceptFromHttp' => ['string|false', 'header'=>'string'],
'Locale::canonicalize' => ['string', 'locale'=>'string'],
'Locale::composeLocale' => ['string', 'subtags'=>'array'],
'Locale::filterMatches' => ['bool', 'langtag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'],
'Locale::getAllVariants' => ['array', 'locale'=>'string'],
'Locale::getDefault' => ['string'],
'Locale::getDisplayLanguage' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
'Locale::getDisplayName' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
'Locale::getDisplayRegion' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
'Locale::getDisplayScript' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
'Locale::getDisplayVariant' => ['string', 'locale'=>'string', 'in_locale='=>'string'],
'Locale::getKeywords' => ['array|false', 'locale'=>'string'],
'Locale::getPrimaryLanguage' => ['string', 'locale'=>'string'],
'Locale::getRegion' => ['string', 'locale'=>'string'],
'Locale::getScript' => ['string', 'locale'=>'string'],
'Locale::lookup' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'?string'],
'Locale::parseLocale' => ['array', 'locale'=>'string'],
'Locale::setDefault' => ['bool', 'locale'=>'string'],
'locale_accept_from_http' => ['string|false', 'header'=>'string'],
'locale_canonicalize' => ['?string', 'locale'=>'string'],
'locale_compose' => ['string|false', 'subtags'=>'array'],
'locale_filter_matches' => ['?bool', 'languageTag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'],
'locale_get_all_variants' => ['?array', 'locale'=>'string'],
'locale_get_default' => ['string'],
'locale_get_display_language' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
'locale_get_display_name' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
'locale_get_display_region' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
'locale_get_display_script' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
'locale_get_display_variant' => ['string', 'locale'=>'string', 'displayLocale='=>'?string'],
'locale_get_keywords' => ['array|false|null', 'locale'=>'string'],
'locale_get_primary_language' => ['?string', 'locale'=>'string'],
'locale_get_region' => ['?string', 'locale'=>'string'],
'locale_get_script' => ['?string', 'locale'=>'string'],
'locale_lookup' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'?string'],
'locale_parse' => ['?array', 'locale'=>'string'],
'locale_set_default' => ['bool', 'locale'=>'string'],
'localeconv' => ['array'],
'localtime' => ['array', 'timestamp='=>'?int', 'associative='=>'bool'],
'log' => ['float', 'num'=>'float', 'base='=>'float'],
'log10' => ['float', 'num'=>'float'],
'log1p' => ['float', 'num'=>'float'],
'LogicException::__clone' => ['void'],
'LogicException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'LogicException::__toString' => ['string'],
'LogicException::getCode' => ['int'],
'LogicException::getFile' => ['string'],
'LogicException::getLine' => ['int'],
'LogicException::getMessage' => ['string'],
'LogicException::getPrevious' => ['?Throwable'],
'LogicException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'LogicException::getTraceAsString' => ['string'],
'long2ip' => ['string', 'ip'=>'string|int'],
'lstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'filename'=>'string'],
'ltrim' => ['string', 'string'=>'string', 'characters='=>'string'],
'Lua::__call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'],
'Lua::__construct' => ['void', 'lua_script_file'=>'string'],
'Lua::assign' => ['?Lua', 'name'=>'string', 'value'=>'mixed'],
'Lua::call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'],
'Lua::eval' => ['mixed', 'statements'=>'string'],
'Lua::getVersion' => ['string'],
'Lua::include' => ['mixed', 'file'=>'string'],
'Lua::registerCallback' => ['Lua|null|false', 'name'=>'string', 'function'=>'callable'],
'LuaClosure::__invoke' => ['void', 'arg'=>'mixed', '...args='=>'mixed'],
'lzf_compress' => ['string', 'data'=>'string'],
'lzf_decompress' => ['string', 'data'=>'string'],
'lzf_optimized_for' => ['int'],
'm_checkstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
'm_completeauthorizations' => ['int', 'conn'=>'resource', 'array'=>'int'],
'm_connect' => ['int', 'conn'=>'resource'],
'm_connectionerror' => ['string', 'conn'=>'resource'],
'm_deletetrans' => ['bool', 'conn'=>'resource', 'identifier'=>'int'],
'm_destroyconn' => ['bool', 'conn'=>'resource'],
'm_destroyengine' => ['void'],
'm_getcell' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'string', 'row'=>'int'],
'm_getcellbynum' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'int', 'row'=>'int'],
'm_getcommadelimited' => ['string', 'conn'=>'resource', 'identifier'=>'int'],
'm_getheader' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column_num'=>'int'],
'm_initconn' => ['resource'],
'm_initengine' => ['int', 'location'=>'string'],
'm_iscommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
'm_maxconntimeout' => ['bool', 'conn'=>'resource', 'secs'=>'int'],
'm_monitor' => ['int', 'conn'=>'resource'],
'm_numcolumns' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
'm_numrows' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
'm_parsecommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
'm_responsekeys' => ['array', 'conn'=>'resource', 'identifier'=>'int'],
'm_responseparam' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string'],
'm_returnstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
'm_setblocking' => ['int', 'conn'=>'resource', 'tf'=>'int'],
'm_setdropfile' => ['int', 'conn'=>'resource', 'directory'=>'string'],
'm_setip' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'],
'm_setssl' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'],
'm_setssl_cafile' => ['int', 'conn'=>'resource', 'cafile'=>'string'],
'm_setssl_files' => ['int', 'conn'=>'resource', 'sslkeyfile'=>'string', 'sslcertfile'=>'string'],
'm_settimeout' => ['int', 'conn'=>'resource', 'seconds'=>'int'],
'm_sslcert_gen_hash' => ['string', 'filename'=>'string'],
'm_transactionssent' => ['int', 'conn'=>'resource'],
'm_transinqueue' => ['int', 'conn'=>'resource'],
'm_transkeyval' => ['int', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string', 'value'=>'string'],
'm_transnew' => ['int', 'conn'=>'resource'],
'm_transsend' => ['int', 'conn'=>'resource', 'identifier'=>'int'],
'm_uwait' => ['int', 'microsecs'=>'int'],
'm_validateidentifier' => ['int', 'conn'=>'resource', 'tf'=>'int'],
'm_verifyconnection' => ['bool', 'conn'=>'resource', 'tf'=>'int'],
'm_verifysslcert' => ['bool', 'conn'=>'resource', 'tf'=>'int'],
'magic_quotes_runtime' => ['bool', 'new_setting'=>'bool'],
'mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array|null', 'additional_params='=>'string'],
'mailparse_determine_best_xfer_encoding' => ['string', 'fp'=>'resource'],
'mailparse_msg_create' => ['resource'],
'mailparse_msg_extract_part' => ['void', 'mimemail'=>'resource', 'msgbody'=>'string', 'callbackfunc='=>'callable'],
'mailparse_msg_extract_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'mixed', 'callbackfunc='=>'callable'],
'mailparse_msg_extract_whole_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'string', 'callbackfunc='=>'callable'],
'mailparse_msg_free' => ['bool', 'mimemail'=>'resource'],
'mailparse_msg_get_part' => ['resource', 'mimemail'=>'resource', 'mimesection'=>'string'],
'mailparse_msg_get_part_data' => ['array', 'mimemail'=>'resource'],
'mailparse_msg_get_structure' => ['array', 'mimemail'=>'resource'],
'mailparse_msg_parse' => ['bool', 'mimemail'=>'resource', 'data'=>'string'],
'mailparse_msg_parse_file' => ['resource|false', 'filename'=>'string'],
'mailparse_rfc822_parse_addresses' => ['array', 'addresses'=>'string'],
'mailparse_stream_encode' => ['bool', 'sourcefp'=>'resource', 'destfp'=>'resource', 'encoding'=>'string'],
'mailparse_uudecode_all' => ['array', 'fp'=>'resource'],
'mapObj::__construct' => ['void', 'map_file_name'=>'string', 'new_map_path'=>'string'],
'mapObj::appendOutputFormat' => ['int', 'outputFormat'=>'outputformatObj'],
'mapObj::applyconfigoptions' => ['int'],
'mapObj::applySLD' => ['int', 'sldxml'=>'string'],
'mapObj::applySLDURL' => ['int', 'sldurl'=>'string'],
'mapObj::convertToString' => ['string'],
'mapObj::draw' => ['?imageObj'],
'mapObj::drawLabelCache' => ['int', 'image'=>'imageObj'],
'mapObj::drawLegend' => ['imageObj'],
'mapObj::drawQuery' => ['?imageObj'],
'mapObj::drawReferenceMap' => ['imageObj'],
'mapObj::drawScaleBar' => ['imageObj'],
'mapObj::embedLegend' => ['int', 'image'=>'imageObj'],
'mapObj::embedScalebar' => ['int', 'image'=>'imageObj'],
'mapObj::free' => ['void'],
'mapObj::generateSLD' => ['string'],
'mapObj::getAllGroupNames' => ['array'],
'mapObj::getAllLayerNames' => ['array'],
'mapObj::getColorbyIndex' => ['colorObj', 'iCloIndex'=>'int'],
'mapObj::getConfigOption' => ['string', 'key'=>'string'],
'mapObj::getLabel' => ['labelcacheMemberObj', 'index'=>'int'],
'mapObj::getLayer' => ['layerObj', 'index'=>'int'],
'mapObj::getLayerByName' => ['layerObj', 'layer_name'=>'string'],
'mapObj::getLayersDrawingOrder' => ['array'],
'mapObj::getLayersIndexByGroup' => ['array', 'groupname'=>'string'],
'mapObj::getMetaData' => ['int', 'name'=>'string'],
'mapObj::getNumSymbols' => ['int'],
'mapObj::getOutputFormat' => ['?outputformatObj', 'index'=>'int'],
'mapObj::getProjection' => ['string'],
'mapObj::getSymbolByName' => ['int', 'symbol_name'=>'string'],
'mapObj::getSymbolObjectById' => ['symbolObj', 'symbolid'=>'int'],
'mapObj::loadMapContext' => ['int', 'filename'=>'string', 'unique_layer_name'=>'bool'],
'mapObj::loadOWSParameters' => ['int', 'request'=>'OwsrequestObj', 'version'=>'string'],
'mapObj::moveLayerDown' => ['int', 'layerindex'=>'int'],
'mapObj::moveLayerUp' => ['int', 'layerindex'=>'int'],
'mapObj::ms_newMapObjFromString' => ['mapObj', 'map_file_string'=>'string', 'new_map_path'=>'string'],
'mapObj::offsetExtent' => ['int', 'x'=>'float', 'y'=>'float'],
'mapObj::owsDispatch' => ['int', 'request'=>'OwsrequestObj'],
'mapObj::prepareImage' => ['imageObj'],
'mapObj::prepareQuery' => ['void'],
'mapObj::processLegendTemplate' => ['string', 'params'=>'array'],
'mapObj::processQueryTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'],
'mapObj::processTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'],
'mapObj::queryByFeatures' => ['int', 'slayer'=>'int'],
'mapObj::queryByIndex' => ['int', 'layerindex'=>'', 'tileindex'=>'', 'shapeindex'=>'', 'addtoquery'=>''],
'mapObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'],
'mapObj::queryByRect' => ['int', 'rect'=>'rectObj'],
'mapObj::queryByShape' => ['int', 'shape'=>'shapeObj'],
'mapObj::removeLayer' => ['layerObj', 'nIndex'=>'int'],
'mapObj::removeMetaData' => ['int', 'name'=>'string'],
'mapObj::removeOutputFormat' => ['int', 'name'=>'string'],
'mapObj::save' => ['int', 'filename'=>'string'],
'mapObj::saveMapContext' => ['int', 'filename'=>'string'],
'mapObj::saveQuery' => ['int', 'filename'=>'string', 'results'=>'int'],
'mapObj::scaleExtent' => ['int', 'zoomfactor'=>'float', 'minscaledenom'=>'float', 'maxscaledenom'=>'float'],
'mapObj::selectOutputFormat' => ['int', 'type'=>'string'],
'mapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'mapObj::setCenter' => ['int', 'center'=>'pointObj'],
'mapObj::setConfigOption' => ['int', 'key'=>'string', 'value'=>'string'],
'mapObj::setExtent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'],
'mapObj::setFontSet' => ['int', 'fileName'=>'string'],
'mapObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'],
'mapObj::setProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'],
'mapObj::setRotation' => ['int', 'rotation_angle'=>'float'],
'mapObj::setSize' => ['int', 'width'=>'int', 'height'=>'int'],
'mapObj::setSymbolSet' => ['int', 'fileName'=>'string'],
'mapObj::setWKTProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'],
'mapObj::zoomPoint' => ['int', 'nZoomFactor'=>'int', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'],
'mapObj::zoomRectangle' => ['int', 'oPixelExt'=>'rectObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'],
'mapObj::zoomScale' => ['int', 'nScaleDenom'=>'float', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj', 'oMaxGeorefExt'=>'rectObj'],
'max' => ['mixed', 'value'=>'non-empty-array'],
'max\'1' => ['mixed', 'value'=>'', 'values'=>'', '...args='=>''],
'maxdb::__construct' => ['void', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
'maxdb::affected_rows' => ['int', 'link'=>''],
'maxdb::auto_commit' => ['bool', 'link'=>'', 'mode'=>'bool'],
'maxdb::change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'],
'maxdb::character_set_name' => ['string', 'link'=>''],
'maxdb::close' => ['bool', 'link'=>''],
'maxdb::commit' => ['bool', 'link'=>''],
'maxdb::disable_reads_from_master' => ['', 'link'=>''],
'maxdb::errno' => ['int', 'link'=>''],
'maxdb::error' => ['string', 'link'=>''],
'maxdb::field_count' => ['int', 'link'=>''],
'maxdb::get_host_info' => ['string', 'link'=>''],
'maxdb::info' => ['string', 'link'=>''],
'maxdb::insert_id' => ['', 'link'=>''],
'maxdb::kill' => ['bool', 'link'=>'', 'processid'=>'int'],
'maxdb::more_results' => ['bool', 'link'=>''],
'maxdb::multi_query' => ['bool', 'link'=>'', 'query'=>'string'],
'maxdb::next_result' => ['bool', 'link'=>''],
'maxdb::num_rows' => ['int', 'result'=>''],
'maxdb::options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''],
'maxdb::ping' => ['bool', 'link'=>''],
'maxdb::prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'],
'maxdb::protocol_version' => ['string', 'link'=>''],
'maxdb::query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'],
'maxdb::real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
'maxdb::real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'],
'maxdb::real_query' => ['bool', 'link'=>'', 'query'=>'string'],
'maxdb::rollback' => ['bool', 'link'=>''],
'maxdb::rpl_query_type' => ['int', 'link'=>''],
'maxdb::select_db' => ['bool', 'link'=>'', 'dbname'=>'string'],
'maxdb::send_query' => ['bool', 'link'=>'', 'query'=>'string'],
'maxdb::server_info' => ['string', 'link'=>''],
'maxdb::server_version' => ['int', 'link'=>''],
'maxdb::sqlstate' => ['string', 'link'=>''],
'maxdb::ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'],
'maxdb::stat' => ['string', 'link'=>''],
'maxdb::stmt_init' => ['object', 'link'=>''],
'maxdb::store_result' => ['bool', 'link'=>''],
'maxdb::thread_id' => ['int', 'link'=>''],
'maxdb::use_result' => ['resource', 'link'=>''],
'maxdb::warning_count' => ['int', 'link'=>''],
'maxdb_affected_rows' => ['int', 'link'=>'resource'],
'maxdb_autocommit' => ['bool', 'link'=>'', 'mode'=>'bool'],
'maxdb_change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'],
'maxdb_character_set_name' => ['string', 'link'=>''],
'maxdb_close' => ['bool', 'link'=>''],
'maxdb_commit' => ['bool', 'link'=>''],
'maxdb_connect' => ['resource', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
'maxdb_connect_errno' => ['int'],
'maxdb_connect_error' => ['string'],
'maxdb_data_seek' => ['bool', 'result'=>'', 'offset'=>'int'],
'maxdb_debug' => ['void', 'debug'=>'string'],
'maxdb_disable_reads_from_master' => ['', 'link'=>''],
'maxdb_disable_rpl_parse' => ['bool', 'link'=>'resource'],
'maxdb_dump_debug_info' => ['bool', 'link'=>'resource'],
'maxdb_embedded_connect' => ['resource', 'dbname='=>'string'],
'maxdb_enable_reads_from_master' => ['bool', 'link'=>'resource'],
'maxdb_enable_rpl_parse' => ['bool', 'link'=>'resource'],
'maxdb_errno' => ['int', 'link'=>'resource'],
'maxdb_error' => ['string', 'link'=>'resource'],
'maxdb_fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'],
'maxdb_fetch_assoc' => ['array', 'result'=>''],
'maxdb_fetch_field' => ['', 'result'=>''],
'maxdb_fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'],
'maxdb_fetch_fields' => ['', 'result'=>''],
'maxdb_fetch_lengths' => ['array', 'result'=>'resource'],
'maxdb_fetch_object' => ['object', 'result'=>'object'],
'maxdb_fetch_row' => ['', 'result'=>''],
'maxdb_field_count' => ['int', 'link'=>''],
'maxdb_field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'],
'maxdb_field_tell' => ['int', 'result'=>'resource'],
'maxdb_free_result' => ['', 'result'=>''],
'maxdb_get_client_info' => ['string'],
'maxdb_get_client_version' => ['int'],
'maxdb_get_host_info' => ['string', 'link'=>'resource'],
'maxdb_get_proto_info' => ['string', 'link'=>'resource'],
'maxdb_get_server_info' => ['string', 'link'=>'resource'],
'maxdb_get_server_version' => ['int', 'link'=>'resource'],
'maxdb_info' => ['string', 'link'=>'resource'],
'maxdb_init' => ['resource'],
'maxdb_insert_id' => ['mixed', 'link'=>'resource'],
'maxdb_kill' => ['bool', 'link'=>'', 'processid'=>'int'],
'maxdb_master_query' => ['bool', 'link'=>'resource', 'query'=>'string'],
'maxdb_more_results' => ['bool', 'link'=>'resource'],
'maxdb_multi_query' => ['bool', 'link'=>'', 'query'=>'string'],
'maxdb_next_result' => ['bool', 'link'=>'resource'],
'maxdb_num_fields' => ['int', 'result'=>'resource'],
'maxdb_num_rows' => ['int', 'result'=>'resource'],
'maxdb_options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''],
'maxdb_ping' => ['bool', 'link'=>''],
'maxdb_prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'],
'maxdb_query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'],
'maxdb_real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'],
'maxdb_real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'],
'maxdb_real_query' => ['bool', 'link'=>'', 'query'=>'string'],
'maxdb_report' => ['bool', 'flags'=>'int'],
'maxdb_result::current_field' => ['int', 'result'=>''],
'maxdb_result::data_seek' => ['bool', 'result'=>'', 'offset'=>'int'],
'maxdb_result::fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'],
'maxdb_result::fetch_assoc' => ['array', 'result'=>''],
'maxdb_result::fetch_field' => ['', 'result'=>''],
'maxdb_result::fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'],
'maxdb_result::fetch_fields' => ['', 'result'=>''],
'maxdb_result::fetch_object' => ['object', 'result'=>'object'],
'maxdb_result::fetch_row' => ['', 'result'=>''],
'maxdb_result::field_count' => ['int', 'result'=>''],
'maxdb_result::field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'],
'maxdb_result::free' => ['', 'result'=>''],
'maxdb_result::lengths' => ['array', 'result'=>''],
'maxdb_rollback' => ['bool', 'link'=>''],
'maxdb_rpl_parse_enabled' => ['int', 'link'=>'resource'],
'maxdb_rpl_probe' => ['bool', 'link'=>'resource'],
'maxdb_rpl_query_type' => ['int', 'link'=>''],
'maxdb_select_db' => ['bool', 'link'=>'resource', 'dbname'=>'string'],
'maxdb_send_query' => ['bool', 'link'=>'', 'query'=>'string'],
'maxdb_server_end' => ['void'],
'maxdb_server_init' => ['bool', 'server='=>'array', 'groups='=>'array'],
'maxdb_sqlstate' => ['string', 'link'=>'resource'],
'maxdb_ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'],
'maxdb_stat' => ['string', 'link'=>''],
'maxdb_stmt::affected_rows' => ['int', 'stmt'=>''],
'maxdb_stmt::bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', '&...rw_var'=>''],
'maxdb_stmt::bind_param\'1' => ['bool', 'stmt'=>'', 'types'=>'string', '&rw_var'=>'array'],
'maxdb_stmt::bind_result' => ['bool', 'stmt'=>'', '&w_var1'=>'', '&...w_vars='=>''],
'maxdb_stmt::close' => ['bool', 'stmt'=>''],
'maxdb_stmt::close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'],
'maxdb_stmt::data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'],
'maxdb_stmt::errno' => ['int', 'stmt'=>''],
'maxdb_stmt::error' => ['string', 'stmt'=>''],
'maxdb_stmt::execute' => ['bool', 'stmt'=>''],
'maxdb_stmt::fetch' => ['bool', 'stmt'=>''],
'maxdb_stmt::free_result' => ['', 'stmt'=>''],
'maxdb_stmt::num_rows' => ['int', 'stmt'=>''],
'maxdb_stmt::param_count' => ['int', 'stmt'=>''],
'maxdb_stmt::prepare' => ['', 'stmt'=>'', 'query'=>'string'],
'maxdb_stmt::reset' => ['bool', 'stmt'=>''],
'maxdb_stmt::result_metadata' => ['resource', 'stmt'=>''],
'maxdb_stmt::send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'],
'maxdb_stmt::stmt_send_long_data' => ['bool', 'param_nr'=>'int', 'data'=>'string'],
'maxdb_stmt::store_result' => ['bool'],
'maxdb_stmt_affected_rows' => ['int', 'stmt'=>'resource'],
'maxdb_stmt_bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', 'var1'=>'', '...args='=>'', 'var='=>'array'],
'maxdb_stmt_bind_result' => ['bool', 'stmt'=>'', '&w_var1'=>'', '&...w_vars='=>''],
'maxdb_stmt_close' => ['bool', 'stmt'=>''],
'maxdb_stmt_close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'],
'maxdb_stmt_data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'],
'maxdb_stmt_errno' => ['int', 'stmt'=>'resource'],
'maxdb_stmt_error' => ['string', 'stmt'=>'resource'],
'maxdb_stmt_execute' => ['bool', 'stmt'=>''],
'maxdb_stmt_fetch' => ['bool', 'stmt'=>''],
'maxdb_stmt_free_result' => ['', 'stmt'=>''],
'maxdb_stmt_init' => ['object', 'link'=>''],
'maxdb_stmt_num_rows' => ['int', 'stmt'=>'resource'],
'maxdb_stmt_param_count' => ['int', 'stmt'=>'resource'],
'maxdb_stmt_prepare' => ['', 'stmt'=>'', 'query'=>'string'],
'maxdb_stmt_reset' => ['bool', 'stmt'=>''],
'maxdb_stmt_result_metadata' => ['resource', 'stmt'=>''],
'maxdb_stmt_send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'],
'maxdb_stmt_sqlstate' => ['string', 'stmt'=>'resource'],
'maxdb_stmt_store_result' => ['bool', 'stmt'=>''],
'maxdb_store_result' => ['bool', 'link'=>''],
'maxdb_thread_id' => ['int', 'link'=>'resource'],
'maxdb_thread_safe' => ['bool'],
'maxdb_use_result' => ['resource', 'link'=>''],
'maxdb_warning_count' => ['int', 'link'=>'resource'],
'mb_check_encoding' => ['bool', 'value='=>'array|string|null', 'encoding='=>'string|null'],
'mb_chr' => ['non-empty-string|false', 'codepoint'=>'int', 'encoding='=>'string|null'],
'mb_convert_case' => ['string', 'string'=>'string', 'mode'=>'int', 'encoding='=>'string|null'],
'mb_convert_encoding' => ['string|false', 'string'=>'string', 'to_encoding'=>'string', 'from_encoding='=>'array|string|null'],
'mb_convert_encoding\'1' => ['array', 'string'=>'array', 'to_encoding'=>'string', 'from_encoding='=>'array|string|null'],
'mb_convert_kana' => ['string', 'string'=>'string', 'mode='=>'string', 'encoding='=>'string|null'],
'mb_convert_variables' => ['string|false', 'to_encoding'=>'string', 'from_encoding'=>'array|string', '&rw_var'=>'string|array|object', '&...rw_vars='=>'string|array|object'],
'mb_decode_mimeheader' => ['string', 'string'=>'string'],
'mb_decode_numericentity' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string|null'],
'mb_detect_encoding' => ['string|false', 'string'=>'string', 'encodings='=>'array|string|null', 'strict='=>'bool'],
'mb_detect_order' => ['bool|list<string>', 'encoding='=>'array|string|null'],
'mb_encode_mimeheader' => ['string', 'string'=>'string', 'charset='=>'string|null', 'transfer_encoding='=>'string|null', 'newline='=>'string', 'indent='=>'int'],
'mb_encode_numericentity' => ['string', 'string'=>'string', 'map'=>'array', 'encoding='=>'string|null', 'hex='=>'bool'],
'mb_encoding_aliases' => ['list<string>', 'encoding'=>'string'],
'mb_ereg' => ['bool', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array|null'],
'mb_ereg_match' => ['bool', 'pattern'=>'string', 'string'=>'string', 'options='=>'string|null'],
'mb_ereg_replace' => ['string|false|null', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string|null'],
'mb_ereg_replace_callback' => ['string|false|null', 'pattern'=>'string', 'callback'=>'callable', 'string'=>'string', 'options='=>'string|null'],
'mb_ereg_search' => ['bool', 'pattern='=>'string|null', 'options='=>'string|null'],
'mb_ereg_search_getpos' => ['int'],
'mb_ereg_search_getregs' => ['string[]|false'],
'mb_ereg_search_init' => ['bool', 'string'=>'string', 'pattern='=>'string|null', 'options='=>'string|null'],
'mb_ereg_search_pos' => ['int[]|false', 'pattern='=>'string|null', 'options='=>'string|null'],
'mb_ereg_search_regs' => ['string[]|false', 'pattern='=>'string|null', 'options='=>'string|null'],
'mb_ereg_search_setpos' => ['bool', 'offset'=>'int'],
'mb_eregi' => ['bool', 'pattern'=>'string', 'string'=>'string', '&w_matches='=>'array|null'],
'mb_eregi_replace' => ['string|false|null', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'options='=>'string|null'],
'mb_get_info' => ['array|string|int|false', 'type='=>'string'],
'mb_http_input' => ['array|string|false', 'type='=>'string|null'],
'mb_http_output' => ['string|bool', 'encoding='=>'string|null'],
'mb_internal_encoding' => ['string|bool', 'encoding='=>'string|null'],
'mb_language' => ['string|bool', 'language='=>'string|null'],
'mb_list_encodings' => ['list<string>'],
'mb_ord' => ['int|false', 'string'=>'string', 'encoding='=>'string|null'],
'mb_output_handler' => ['string', 'string'=>'string', 'status'=>'int'],
'mb_parse_str' => ['bool', 'string'=>'string', '&w_result'=>'array'],
'mb_preferred_mime_name' => ['string|false', 'encoding'=>'string'],
'mb_regex_encoding' => ['string|bool', 'encoding='=>'string|null'],
'mb_regex_set_options' => ['string', 'options='=>'string|null'],
'mb_scrub' => ['string', 'string'=>'string', 'encoding='=>'string|null'],
'mb_send_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string|array', 'additional_params='=>'string|null'],
'mb_split' => ['list<string>|false', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'],
'mb_str_split' => ['list<string>', 'string'=>'string', 'length='=>'positive-int', 'encoding='=>'string|null'],
'mb_strcut' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string|null'],
'mb_strimwidth' => ['string', 'string'=>'string', 'start'=>'int', 'width'=>'int', 'trim_marker='=>'string', 'encoding='=>'string|null'],
'mb_stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
'mb_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
'mb_strlen' => ['0|positive-int', 'string'=>'string', 'encoding='=>'string|null'],
'mb_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
'mb_strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
'mb_strrichr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
'mb_strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
'mb_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string|null'],
'mb_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool', 'encoding='=>'string|null'],
'mb_strtolower' => ['lowercase-string', 'string'=>'string', 'encoding='=>'string|null'],
'mb_strtoupper' => ['string', 'string'=>'string', 'encoding='=>'string|null'],
'mb_strwidth' => ['int', 'string'=>'string', 'encoding='=>'string|null'],
'mb_substitute_character' => ['bool|int|string', 'substitute_character='=>'int|string|null'],
'mb_substr' => ['string', 'string'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string|null'],
'mb_substr_count' => ['int', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string|null'],
'mcrypt_cbc' => ['string', 'cipher'=>'string|int', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
'mcrypt_cfb' => ['string', 'cipher'=>'string|int', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
'mcrypt_create_iv' => ['string|false', 'size'=>'int', 'source='=>'int'],
'mcrypt_decrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'],
'mcrypt_ecb' => ['string', 'cipher'=>'string|int', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
'mcrypt_enc_get_algorithms_name' => ['string', 'td'=>'resource'],
'mcrypt_enc_get_block_size' => ['int', 'td'=>'resource'],
'mcrypt_enc_get_iv_size' => ['int', 'td'=>'resource'],
'mcrypt_enc_get_key_size' => ['int', 'td'=>'resource'],
'mcrypt_enc_get_modes_name' => ['string', 'td'=>'resource'],
'mcrypt_enc_get_supported_key_sizes' => ['array', 'td'=>'resource'],
'mcrypt_enc_is_block_algorithm' => ['bool', 'td'=>'resource'],
'mcrypt_enc_is_block_algorithm_mode' => ['bool', 'td'=>'resource'],
'mcrypt_enc_is_block_mode' => ['bool', 'td'=>'resource'],
'mcrypt_enc_self_test' => ['int|false', 'td'=>'resource'],
'mcrypt_encrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'],
'mcrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'],
'mcrypt_generic_deinit' => ['bool', 'td'=>'resource'],
'mcrypt_generic_end' => ['bool', 'td'=>'resource'],
'mcrypt_generic_init' => ['int|false', 'td'=>'resource', 'key'=>'string', 'iv'=>'string'],
'mcrypt_get_block_size' => ['int', 'cipher'=>'int|string', 'module'=>'string'],
'mcrypt_get_cipher_name' => ['string|false', 'cipher'=>'int|string'],
'mcrypt_get_iv_size' => ['int|false', 'cipher'=>'int|string', 'module'=>'string'],
'mcrypt_get_key_size' => ['int', 'cipher'=>'int|string', 'module'=>'string'],
'mcrypt_list_algorithms' => ['array', 'lib_dir='=>'string'],
'mcrypt_list_modes' => ['array', 'lib_dir='=>'string'],
'mcrypt_module_close' => ['bool', 'td'=>'resource'],
'mcrypt_module_get_algo_block_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'],
'mcrypt_module_get_algo_key_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'],
'mcrypt_module_get_supported_key_sizes' => ['array', 'algorithm'=>'string', 'lib_dir='=>'string'],
'mcrypt_module_is_block_algorithm' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'],
'mcrypt_module_is_block_algorithm_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'],
'mcrypt_module_is_block_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'],
'mcrypt_module_open' => ['resource|false', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'],
'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'],
'mcrypt_ofb' => ['string', 'cipher'=>'int|string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'],
'md5' => ['non-falsy-string', 'string'=>'string', 'binary='=>'bool'],
'md5_file' => ['non-falsy-string|false', 'filename'=>'string', 'binary='=>'bool'],
'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'],
'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'],
'Memcache::append' => [''],
'Memcache::cas' => [''],
'Memcache::close' => ['bool'],
'Memcache::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
'Memcache::decrement' => ['int', 'key'=>'string', 'value='=>'int'],
'Memcache::delete' => ['bool', 'key'=>'string', 'timeout='=>'int'],
'Memcache::findServer' => [''],
'Memcache::flush' => ['bool'],
'Memcache::get' => ['string|array|false', 'key'=>'string', 'flags='=>'array', 'keys='=>'array'],
'Memcache::get\'1' => ['array', 'key'=>'string[]', 'flags='=>'int[]'],
'Memcache::getExtendedStats' => ['false|array<string, false|array<string, int|string>>', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
'Memcache::getServerStatus' => ['int', 'host'=>'string', 'port='=>'int'],
'Memcache::getStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
'Memcache::getVersion' => ['string'],
'Memcache::increment' => ['int', 'key'=>'string', 'value='=>'int'],
'Memcache::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
'Memcache::prepend' => ['string'],
'Memcache::replace' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'Memcache::set' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'Memcache::setCompressThreshold' => ['bool', 'threshold'=>'int', 'min_savings='=>'float'],
'Memcache::setFailureCallback' => [''],
'Memcache::setServerParams' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable'],
'memcache_add' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'memcache_add_server' => ['bool', 'memcache_obj'=>'Memcache', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'],
'memcache_append' => ['', 'memcache_obj'=>'Memcache'],
'memcache_cas' => ['', 'memcache_obj'=>'Memcache'],
'memcache_close' => ['bool', 'memcache_obj'=>'Memcache'],
'memcache_connect' => ['Memcache|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
'memcache_debug' => ['bool', 'on_off'=>'bool'],
'memcache_decrement' => ['int', 'memcache_obj'=>'Memcache', 'key'=>'string', 'value='=>'int'],
'memcache_delete' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'timeout='=>'int'],
'memcache_flush' => ['bool', 'memcache_obj'=>'Memcache'],
'memcache_get' => ['string', 'memcache_obj'=>'Memcache', 'key'=>'string', 'flags='=>'int'],
'memcache_get\'1' => ['array', 'memcache_obj'=>'Memcache', 'key'=>'string[]', 'flags='=>'int[]'],
'memcache_get_extended_stats' => ['array', 'memcache_obj'=>'Memcache', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
'memcache_get_server_status' => ['int', 'memcache_obj'=>'Memcache', 'host'=>'string', 'port='=>'int'],
'memcache_get_stats' => ['array', 'memcache_obj'=>'Memcache', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
'memcache_get_version' => ['string', 'memcache_obj'=>'Memcache'],
'memcache_increment' => ['int', 'memcache_obj'=>'Memcache', 'key'=>'string', 'value='=>'int'],
'memcache_pconnect' => ['Memcache|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'],
'memcache_prepend' => ['string', 'memcache_obj'=>'Memcache'],
'memcache_replace' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'memcache_set' => ['bool', 'memcache_obj'=>'Memcache', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'memcache_set_compress_threshold' => ['bool', 'memcache_obj'=>'Memcache', 'threshold'=>'int', 'min_savings='=>'float'],
'memcache_set_failure_callback' => ['', 'memcache_obj'=>'Memcache'],
'memcache_set_server_params' => ['bool', 'memcache_obj'=>'Memcache', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable'],
'Memcached::__construct' => ['void', 'persistent_id='=>'mixed|string', 'on_new_object_cb='=>'mixed'],
'Memcached::add' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::addByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::addServer' => ['bool', 'host'=>'string', 'port'=>'int', 'weight='=>'int'],
'Memcached::addServers' => ['bool', 'servers'=>'array'],
'Memcached::append' => ['bool', 'key'=>'string', 'value'=>'string'],
'Memcached::appendByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'],
'Memcached::cas' => ['bool', 'cas_token'=>'float', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::casByKey' => ['bool', 'cas_token'=>'float', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::decrement' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
'Memcached::decrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
'Memcached::delete' => ['bool', 'key'=>'string', 'time='=>'int'],
'Memcached::deleteByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'time='=>'int'],
'Memcached::deleteMulti' => ['array', 'keys'=>'array', 'time='=>'int'],
'Memcached::deleteMultiByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'time='=>'int'],
'Memcached::fetch' => ['array|false'],
'Memcached::fetchAll' => ['array|false'],
'Memcached::flush' => ['bool', 'delay='=>'int'],
'Memcached::flushBuffers' => [''],
'Memcached::get' => ['mixed|false', 'key'=>'string', 'cache_cb='=>'?callable', 'flags='=>'int'],
'Memcached::getAllKeys' => ['array|false'],
'Memcached::getByKey' => ['mixed|false', 'server_key'=>'string', 'key'=>'string', 'value_cb='=>'?callable', 'flags='=>'int'],
'Memcached::getDelayed' => ['bool', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'callable'],
'Memcached::getDelayedByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'?callable'],
'Memcached::getLastDisconnectedServer' => [''],
'Memcached::getLastErrorCode' => [''],
'Memcached::getLastErrorErrno' => [''],
'Memcached::getLastErrorMessage' => [''],
'Memcached::getMulti' => ['array|false', 'keys'=>'array', 'flags='=>'int'],
'Memcached::getMultiByKey' => ['array|false', 'server_key'=>'string', 'keys'=>'array', 'flags='=>'int'],
'Memcached::getOption' => ['mixed|false', 'option'=>'int'],
'Memcached::getResultCode' => ['int'],
'Memcached::getResultMessage' => ['string'],
'Memcached::getServerByKey' => ['array', 'server_key'=>'string'],
'Memcached::getServerList' => ['array'],
'Memcached::getStats' => ['false|array<string, false|array<string, int|string>>', 'type='=>'?string'],
'Memcached::getVersion' => ['array'],
'Memcached::increment' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
'Memcached::incrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'],
'Memcached::isPersistent' => ['bool'],
'Memcached::isPristine' => ['bool'],
'Memcached::prepend' => ['bool', 'key'=>'string', 'value'=>'string'],
'Memcached::prependByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'],
'Memcached::quit' => ['bool'],
'Memcached::replace' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::replaceByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::resetServerList' => ['bool'],
'Memcached::set' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::setBucket' => ['', 'host_map'=>'array', 'forward_map'=>'array', 'replicas'=>''],
'Memcached::setByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'],
'Memcached::setEncodingKey' => ['', 'key'=>''],
'Memcached::setMulti' => ['bool', 'items'=>'array', 'expiration='=>'int'],
'Memcached::setMultiByKey' => ['bool', 'server_key'=>'string', 'items'=>'array', 'expiration='=>'int'],
'Memcached::setOption' => ['bool', 'option'=>'int', 'value'=>'mixed'],
'Memcached::setOptions' => ['bool', 'options'=>'array'],
'Memcached::setSaslAuthData' => ['void', 'username'=>'string', 'password'=>'string'],
'Memcached::touch' => ['bool', 'key'=>'string', 'expiration'=>'int'],
'Memcached::touchByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'expiration'=>'int'],
'MemcachePool::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'MemcachePool::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'?callable', 'timeoutms='=>'int'],
'MemcachePool::append' => [''],
'MemcachePool::cas' => [''],
'MemcachePool::close' => ['bool'],
'MemcachePool::connect' => ['bool', 'host'=>'string', 'port'=>'int', 'timeout='=>'int'],
'MemcachePool::decrement' => ['int|false', 'key'=>'', 'value='=>'int|mixed'],
'MemcachePool::delete' => ['bool', 'key'=>'', 'timeout='=>'int|mixed'],
'MemcachePool::findServer' => [''],
'MemcachePool::flush' => ['bool'],
'MemcachePool::get' => ['array|string|false', 'key'=>'array|string', '&flags='=>'array|int'],
'MemcachePool::getExtendedStats' => ['false|array<string, false|array<string, int|string>>', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
'MemcachePool::getServerStatus' => ['int', 'host'=>'string', 'port='=>'int'],
'MemcachePool::getStats' => ['array|false', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'],
'MemcachePool::getVersion' => ['string|false'],
'MemcachePool::increment' => ['int|false', 'key'=>'', 'value='=>'int|mixed'],
'MemcachePool::prepend' => ['string'],
'MemcachePool::replace' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'MemcachePool::set' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'],
'MemcachePool::setCompressThreshold' => ['bool', 'thresold'=>'int', 'min_saving='=>'float'],
'MemcachePool::setFailureCallback' => [''],
'MemcachePool::setServerParams' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'?callable'],
'memory_get_peak_usage' => ['int', 'real_usage='=>'bool'],
'memory_get_usage' => ['int', 'real_usage='=>'bool'],
'memory_reset_peak_usage' => ['void'],
'MessageFormatter::__construct' => ['void', 'locale'=>'string', 'pattern'=>'string'],
'MessageFormatter::create' => ['MessageFormatter', 'locale'=>'string', 'pattern'=>'string'],
'MessageFormatter::format' => ['false|string', 'args'=>'array'],
'MessageFormatter::formatMessage' => ['false|string', 'locale'=>'string', 'pattern'=>'string', 'args'=>'array'],
'MessageFormatter::getErrorCode' => ['int'],
'MessageFormatter::getErrorMessage' => ['string'],
'MessageFormatter::getLocale' => ['string'],
'MessageFormatter::getPattern' => ['string'],
'MessageFormatter::parse' => ['array|false', 'value'=>'string'],
'MessageFormatter::parseMessage' => ['array|false', 'locale'=>'string', 'pattern'=>'string', 'source'=>'string'],
'MessageFormatter::setPattern' => ['bool', 'pattern'=>'string'],
'metaphone' => ['string', 'string'=>'string', 'max_phonemes='=>'int'],
'method_exists' => ['bool', 'object_or_class'=>'object|class-string|interface-string|enum-string', 'method'=>'string'],
'mhash' => ['string', 'algo'=>'int', 'data'=>'string', 'key='=>'?string'],
'mhash_count' => ['int'],
'mhash_get_block_size' => ['int|false', 'algo'=>'int'],
'mhash_get_hash_name' => ['string|false', 'algo'=>'int'],
'mhash_keygen_s2k' => ['string|false', 'algo'=>'int', 'password'=>'string', 'salt'=>'string', 'length'=>'int'],
'microtime' => ['string', 'as_float='=>'false'],
'microtime\'1' => ['float', 'as_float='=>'true'],
'mime_content_type' => ['string|false', 'filename'=>'string|resource'],
'min' => ['mixed', 'value'=>'non-empty-array'],
'min\'1' => ['mixed', 'value'=>'', 'values'=>'', '...args='=>''],
'ming_keypress' => ['int', 'char'=>'string'],
'ming_setcubicthreshold' => ['void', 'threshold'=>'int'],
'ming_setscale' => ['void', 'scale'=>'float'],
'ming_setswfcompression' => ['void', 'level'=>'int'],
'ming_useconstants' => ['void', 'use'=>'int'],
'ming_useswfversion' => ['void', 'version'=>'int'],
'mkdir' => ['bool', 'directory'=>'string', 'permissions='=>'int', 'recursive='=>'bool', 'context='=>'resource'],
'mktime' => ['int|false', 'hour'=>'int', 'minute='=>'int|null', 'second='=>'int|null', 'month='=>'int|null', 'day='=>'int|null', 'year='=>'int|null'],
'money_format' => ['string', 'format'=>'string', 'value'=>'float'],
'Mongo::__construct' => ['void', 'server='=>'string', 'options='=>'array', 'driver_options='=>'array'],
'Mongo::__get' => ['MongoDB', 'dbname'=>'string'],
'Mongo::__toString' => ['string'],
'Mongo::close' => ['bool'],
'Mongo::connect' => ['bool'],
'Mongo::connectUtil' => ['bool'],
'Mongo::dropDB' => ['array', 'db'=>'mixed'],
'Mongo::forceError' => ['bool'],
'Mongo::getConnections' => ['array'],
'Mongo::getHosts' => ['array'],
'Mongo::getPoolSize' => ['int'],
'Mongo::getReadPreference' => ['array'],
'Mongo::getSlave' => ['?string'],
'Mongo::getSlaveOkay' => ['bool'],
'Mongo::getWriteConcern' => ['array'],
'Mongo::killCursor' => ['', 'server_hash'=>'string', 'id'=>'MongoInt64|int'],
'Mongo::lastError' => ['?array'],
'Mongo::listDBs' => ['array'],
'Mongo::pairConnect' => ['bool'],
'Mongo::pairPersistConnect' => ['bool', 'username='=>'string', 'password='=>'string'],
'Mongo::persistConnect' => ['bool', 'username='=>'string', 'password='=>'string'],
'Mongo::poolDebug' => ['array'],
'Mongo::prevError' => ['array'],
'Mongo::resetError' => ['array'],
'Mongo::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'],
'Mongo::selectDB' => ['MongoDB', 'name'=>'string'],
'Mongo::setPoolSize' => ['bool', 'size'=>'int'],
'Mongo::setReadPreference' => ['bool', 'readPreference'=>'string', 'tags='=>'array'],
'Mongo::setSlaveOkay' => ['bool', 'ok='=>'bool'],
'Mongo::switchSlave' => ['string'],
'MongoBinData::__construct' => ['void', 'data'=>'string', 'type='=>'int'],
'MongoBinData::__toString' => ['string'],
'MongoClient::__construct' => ['void', 'server='=>'string', 'options='=>'array', 'driver_options='=>'array'],
'MongoClient::__get' => ['MongoDB', 'dbname'=>'string'],
'MongoClient::__toString' => ['string'],
'MongoClient::close' => ['bool', 'connection='=>'bool|string'],
'MongoClient::connect' => ['bool'],
'MongoClient::dropDB' => ['array', 'db'=>'mixed'],
'MongoClient::getConnections' => ['array'],
'MongoClient::getHosts' => ['array'],
'MongoClient::getReadPreference' => ['array'],
'MongoClient::getWriteConcern' => ['array'],
'MongoClient::killCursor' => ['bool', 'server_hash'=>'string', 'id'=>'int|MongoInt64'],
'MongoClient::listDBs' => ['array'],
'MongoClient::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'],
'MongoClient::selectDB' => ['MongoDB', 'name'=>'string'],
'MongoClient::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'],
'MongoClient::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'],
'MongoClient::switchSlave' => ['string'],
'MongoCode::__construct' => ['void', 'code'=>'string', 'scope='=>'array'],
'MongoCode::__toString' => ['string'],
'MongoCollection::__construct' => ['void', 'db'=>'MongoDB', 'name'=>'string'],
'MongoCollection::__get' => ['MongoCollection', 'name'=>'string'],
'MongoCollection::__toString' => ['string'],
'MongoCollection::aggregate' => ['array', 'op'=>'array', 'op='=>'array', '...args='=>'array'],
'MongoCollection::aggregate\'1' => ['array', 'pipeline'=>'array', 'options='=>'array'],
'MongoCollection::aggregateCursor' => ['MongoCommandCursor', 'command'=>'array', 'options='=>'array'],
'MongoCollection::batchInsert' => ['array|bool', 'a'=>'array', 'options='=>'array'],
'MongoCollection::count' => ['int', 'query='=>'array', 'limit='=>'int', 'skip='=>'int'],
'MongoCollection::createDBRef' => ['array', 'a'=>'array'],
'MongoCollection::createIndex' => ['array', 'keys'=>'array', 'options='=>'array'],
'MongoCollection::deleteIndex' => ['array', 'keys'=>'string|array'],
'MongoCollection::deleteIndexes' => ['array'],
'MongoCollection::distinct' => ['array|false', 'key'=>'string', 'query='=>'array'],
'MongoCollection::drop' => ['array'],
'MongoCollection::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'],
'MongoCollection::find' => ['MongoCursor', 'query='=>'array', 'fields='=>'array'],
'MongoCollection::findAndModify' => ['array', 'query'=>'array', 'update='=>'array', 'fields='=>'array', 'options='=>'array'],
'MongoCollection::findOne' => ['?array', 'query='=>'array', 'fields='=>'array'],
'MongoCollection::getDBRef' => ['array', 'ref'=>'array'],
'MongoCollection::getIndexInfo' => ['array'],
'MongoCollection::getName' => ['string'],
'MongoCollection::getReadPreference' => ['array'],
'MongoCollection::getSlaveOkay' => ['bool'],
'MongoCollection::getWriteConcern' => ['array'],
'MongoCollection::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'MongoCode', 'options='=>'array'],
'MongoCollection::insert' => ['bool|array', 'a'=>'array|object', 'options='=>'array'],
'MongoCollection::parallelCollectionScan' => ['MongoCommandCursor[]', 'num_cursors'=>'int'],
'MongoCollection::remove' => ['bool|array', 'criteria='=>'array', 'options='=>'array'],
'MongoCollection::save' => ['bool|array', 'a'=>'array|object', 'options='=>'array'],
'MongoCollection::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'],
'MongoCollection::setSlaveOkay' => ['bool', 'ok='=>'bool'],
'MongoCollection::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'],
'MongoCollection::toIndexString' => ['string', 'keys'=>'mixed'],
'MongoCollection::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'],
'MongoCollection::validate' => ['array', 'scan_data='=>'bool'],
'MongoCommandCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'command'=>'array'],
'MongoCommandCursor::batchSize' => ['MongoCommandCursor', 'batchSize'=>'int'],
'MongoCommandCursor::createFromDocument' => ['MongoCommandCursor', 'connection'=>'MongoClient', 'hash'=>'string', 'document'=>'array'],
'MongoCommandCursor::current' => ['array'],
'MongoCommandCursor::dead' => ['bool'],
'MongoCommandCursor::getReadPreference' => ['array'],
'MongoCommandCursor::info' => ['array'],
'MongoCommandCursor::key' => ['int'],
'MongoCommandCursor::next' => ['void'],
'MongoCommandCursor::rewind' => ['array'],
'MongoCommandCursor::setReadPreference' => ['MongoCommandCursor', 'read_preference'=>'string', 'tags='=>'array'],
'MongoCommandCursor::timeout' => ['MongoCommandCursor', 'ms'=>'int'],
'MongoCommandCursor::valid' => ['bool'],
'MongoCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'query='=>'array', 'fields='=>'array'],
'MongoCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'],
'MongoCursor::awaitData' => ['MongoCursor', 'wait='=>'bool'],
'MongoCursor::batchSize' => ['MongoCursor', 'num'=>'int'],
'MongoCursor::count' => ['int', 'foundonly='=>'bool'],
'MongoCursor::current' => ['array'],
'MongoCursor::dead' => ['bool'],
'MongoCursor::doQuery' => ['void'],
'MongoCursor::explain' => ['array'],
'MongoCursor::fields' => ['MongoCursor', 'f'=>'array'],
'MongoCursor::getNext' => ['array'],
'MongoCursor::getReadPreference' => ['array'],
'MongoCursor::hasNext' => ['bool'],
'MongoCursor::hint' => ['MongoCursor', 'key_pattern'=>'string|array|object'],
'MongoCursor::immortal' => ['MongoCursor', 'liveforever='=>'bool'],
'MongoCursor::info' => ['array'],
'MongoCursor::key' => ['string'],
'MongoCursor::limit' => ['MongoCursor', 'num'=>'int'],
'MongoCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'],
'MongoCursor::next' => ['array'],
'MongoCursor::partial' => ['MongoCursor', 'okay='=>'bool'],
'MongoCursor::reset' => ['void'],
'MongoCursor::rewind' => ['void'],
'MongoCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool'],
'MongoCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags='=>'array'],
'MongoCursor::skip' => ['MongoCursor', 'num'=>'int'],
'MongoCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool'],
'MongoCursor::snapshot' => ['MongoCursor'],
'MongoCursor::sort' => ['MongoCursor', 'fields'=>'array'],
'MongoCursor::tailable' => ['MongoCursor', 'tail='=>'bool'],
'MongoCursor::timeout' => ['MongoCursor', 'ms'=>'int'],
'MongoCursor::valid' => ['bool'],
'MongoCursorException::__clone' => ['void'],
'MongoCursorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'MongoCursorException::__toString' => ['string'],
'MongoCursorException::__wakeup' => ['void'],
'MongoCursorException::getCode' => ['int'],
'MongoCursorException::getFile' => ['string'],
'MongoCursorException::getHost' => ['string'],
'MongoCursorException::getLine' => ['int'],
'MongoCursorException::getMessage' => ['string'],
'MongoCursorException::getPrevious' => ['Exception|Throwable'],
'MongoCursorException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'MongoCursorException::getTraceAsString' => ['string'],
'MongoCursorInterface::__construct' => ['void'],
'MongoCursorInterface::batchSize' => ['MongoCursorInterface', 'batchSize'=>'int'],
'MongoCursorInterface::current' => ['mixed'],
'MongoCursorInterface::dead' => ['bool'],
'MongoCursorInterface::getReadPreference' => ['array'],
'MongoCursorInterface::info' => ['array'],
'MongoCursorInterface::key' => ['int|string'],
'MongoCursorInterface::next' => ['void'],
'MongoCursorInterface::rewind' => ['void'],
'MongoCursorInterface::setReadPreference' => ['MongoCursorInterface', 'read_preference'=>'string', 'tags='=>'array'],
'MongoCursorInterface::timeout' => ['MongoCursorInterface', 'ms'=>'int'],
'MongoCursorInterface::valid' => ['bool'],
'MongoDate::__construct' => ['void', 'second='=>'int', 'usecond='=>'int'],
'MongoDate::__toString' => ['string'],
'MongoDate::toDateTime' => ['DateTime'],
'MongoDB::__construct' => ['void', 'conn'=>'MongoClient', 'name'=>'string'],
'MongoDB::__get' => ['MongoCollection', 'name'=>'string'],
'MongoDB::__toString' => ['string'],
'MongoDB::authenticate' => ['array', 'username'=>'string', 'password'=>'string'],
'MongoDB::command' => ['array', 'command'=>'array'],
'MongoDB::createCollection' => ['MongoCollection', 'name'=>'string', 'capped='=>'bool', 'size='=>'int', 'max='=>'int'],
'MongoDB::createDBRef' => ['array', 'collection'=>'string', 'a'=>'mixed'],
'MongoDB::drop' => ['array'],
'MongoDB::dropCollection' => ['array', 'coll'=>'MongoCollection|string'],
'MongoDB::execute' => ['array', 'code'=>'MongoCode|string', 'args='=>'array'],
'MongoDB::forceError' => ['bool'],
'MongoDB::getCollectionInfo' => ['array', 'options='=>'array'],
'MongoDB::getCollectionNames' => ['array', 'options='=>'array'],
'MongoDB::getDBRef' => ['array', 'ref'=>'array'],
'MongoDB::getGridFS' => ['MongoGridFS', 'prefix='=>'string'],
'MongoDB::getProfilingLevel' => ['int'],
'MongoDB::getReadPreference' => ['array'],
'MongoDB::getSlaveOkay' => ['bool'],
'MongoDB::getWriteConcern' => ['array'],
'MongoDB::lastError' => ['array'],
'MongoDB::listCollections' => ['array'],
'MongoDB::prevError' => ['array'],
'MongoDB::repair' => ['array', 'preserve_cloned_files='=>'bool', 'backup_original_files='=>'bool'],
'MongoDB::resetError' => ['array'],
'MongoDB::selectCollection' => ['MongoCollection', 'name'=>'string'],
'MongoDB::setProfilingLevel' => ['int', 'level'=>'int'],
'MongoDB::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'],
'MongoDB::setSlaveOkay' => ['bool', 'ok='=>'bool'],
'MongoDB::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'],
'MongoDB\BSON\Binary::__construct' => ['void', 'data' => 'string', 'type' => 'int'],
'MongoDB\BSON\Binary::getData' => ['string'],
'MongoDB\BSON\Binary::getType' => ['int'],
'MongoDB\BSON\Binary::__toString' => ['string'],
'MongoDB\BSON\Binary::serialize' => ['string'],
'MongoDB\BSON\Binary::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Binary::jsonSerialize' => ['mixed'],
'MongoDB\BSON\BinaryInterface::getData' => ['string'],
'MongoDB\BSON\BinaryInterface::getType' => ['int'],
'MongoDB\BSON\BinaryInterface::__toString' => ['string'],
'MongoDB\BSON\DBPointer::__toString' => ['string'],
'MongoDB\BSON\DBPointer::serialize' => ['string'],
'MongoDB\BSON\DBPointer::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\DBPointer::jsonSerialize' => ['mixed'],
'MongoDB\BSON\Decimal128::__construct' => ['void', 'value' => 'string'],
'MongoDB\BSON\Decimal128::__toString' => ['string'],
'MongoDB\BSON\Decimal128::serialize' => ['string'],
'MongoDB\BSON\Decimal128::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Decimal128::jsonSerialize' => ['mixed'],
'MongoDB\BSON\Decimal128Interface::__toString' => ['string'],
'MongoDB\BSON\Int64::__toString' => ['string'],
'MongoDB\BSON\Int64::serialize' => ['string'],
'MongoDB\BSON\Int64::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Int64::jsonSerialize' => ['mixed'],
'MongoDB\BSON\Javascript::__construct' => ['void', 'code' => 'string', 'scope=' => 'object|array|null'],
'MongoDB\BSON\Javascript::getCode' => ['string'],
'MongoDB\BSON\Javascript::getScope' => ['?object'],
'MongoDB\BSON\Javascript::__toString' => ['string'],
'MongoDB\BSON\Javascript::serialize' => ['string'],
'MongoDB\BSON\Javascript::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Javascript::jsonSerialize' => ['mixed'],
'MongoDB\BSON\JavascriptInterface::getCode' => ['string'],
'MongoDB\BSON\JavascriptInterface::getScope' => ['?object'],
'MongoDB\BSON\JavascriptInterface::__toString' => ['string'],
'MongoDB\BSON\MaxKey::serialize' => ['string'],
'MongoDB\BSON\MaxKey::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\MaxKey::jsonSerialize' => ['mixed'],
'MongoDB\BSON\MinKey::serialize' => ['string'],
'MongoDB\BSON\MinKey::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\MinKey::jsonSerialize' => ['mixed'],
'MongoDB\BSON\ObjectId::__construct' => ['void', 'id=' => '?string'],
'MongoDB\BSON\ObjectId::getTimestamp' => ['int'],
'MongoDB\BSON\ObjectId::__toString' => ['string'],
'MongoDB\BSON\ObjectId::serialize' => ['string'],
'MongoDB\BSON\ObjectId::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\ObjectId::jsonSerialize' => ['mixed'],
'MongoDB\BSON\ObjectIdInterface::getTimestamp' => ['int'],
'MongoDB\BSON\ObjectIdInterface::__toString' => ['string'],
'MongoDB\BSON\Regex::__construct' => ['void', 'pattern' => 'string', 'flags=' => 'string'],
'MongoDB\BSON\Regex::getPattern' => ['string'],
'MongoDB\BSON\Regex::getFlags' => ['string'],
'MongoDB\BSON\Regex::__toString' => ['string'],
'MongoDB\BSON\Regex::serialize' => ['string'],
'MongoDB\BSON\Regex::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Regex::jsonSerialize' => ['mixed'],
'MongoDB\BSON\RegexInterface::getPattern' => ['string'],
'MongoDB\BSON\RegexInterface::getFlags' => ['string'],
'MongoDB\BSON\RegexInterface::__toString' => ['string'],
'MongoDB\BSON\Serializable::bsonSerialize' => ['object|array'],
'MongoDB\BSON\Symbol::__toString' => ['string'],
'MongoDB\BSON\Symbol::serialize' => ['string'],
'MongoDB\BSON\Symbol::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Symbol::jsonSerialize' => ['mixed'],
'MongoDB\BSON\Timestamp::__construct' => ['void', 'increment' => 'string|int', 'timestamp' => 'string|int'],
'MongoDB\BSON\Timestamp::getTimestamp' => ['int'],
'MongoDB\BSON\Timestamp::getIncrement' => ['int'],
'MongoDB\BSON\Timestamp::__toString' => ['string'],
'MongoDB\BSON\Timestamp::serialize' => ['string'],
'MongoDB\BSON\Timestamp::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Timestamp::jsonSerialize' => ['mixed'],
'MongoDB\BSON\TimestampInterface::getTimestamp' => ['int'],
'MongoDB\BSON\TimestampInterface::getIncrement' => ['int'],
'MongoDB\BSON\TimestampInterface::__toString' => ['string'],
'MongoDB\BSON\UTCDateTime::__construct' => ['void', 'milliseconds=' => 'DateTimeInterface|string|int|float|null'],
'MongoDB\BSON\UTCDateTime::toDateTime' => ['DateTime'],
'MongoDB\BSON\UTCDateTime::__toString' => ['string'],
'MongoDB\BSON\UTCDateTime::serialize' => ['string'],
'MongoDB\BSON\UTCDateTime::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\UTCDateTime::jsonSerialize' => ['mixed'],
'MongoDB\BSON\UTCDateTimeInterface::toDateTime' => ['DateTime'],
'MongoDB\BSON\UTCDateTimeInterface::__toString' => ['string'],
'MongoDB\BSON\Undefined::__toString' => ['string'],
'MongoDB\BSON\Undefined::serialize' => ['string'],
'MongoDB\BSON\Undefined::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\BSON\Undefined::jsonSerialize' => ['mixed'],
'MongoDB\BSON\Unserializable::bsonUnserialize' => ['void', 'data' => 'array'],
'MongoDB\Driver\BulkWrite::__construct' => ['void', 'options=' => '?array'],
'MongoDB\Driver\BulkWrite::count' => ['int'],
'MongoDB\Driver\BulkWrite::delete' => ['void', 'filter' => 'object|array', 'deleteOptions=' => '?array'],
'MongoDB\Driver\BulkWrite::insert' => ['mixed', 'document' => 'object|array'],
'MongoDB\Driver\BulkWrite::update' => ['void', 'filter' => 'object|array', 'newObj' => 'object|array', 'updateOptions=' => '?array'],
'MongoDB\Driver\ClientEncryption::__construct' => ['void', 'options' => 'array'],
'MongoDB\Driver\ClientEncryption::addKeyAltName' => ['?object', 'keyId' => 'MongoDB\BSON\Binary', 'keyAltName' => 'string'],
'MongoDB\Driver\ClientEncryption::createDataKey' => ['MongoDB\BSON\Binary', 'kmsProvider' => 'string', 'options=' => '?array'],
'MongoDB\Driver\ClientEncryption::decrypt' => ['mixed', 'value' => 'MongoDB\BSON\Binary'],
'MongoDB\Driver\ClientEncryption::deleteKey' => ['object', 'keyId' => 'MongoDB\BSON\Binary'],
'MongoDB\Driver\ClientEncryption::encrypt' => ['MongoDB\BSON\Binary', 'value' => 'mixed', 'options=' => '?array'],
'MongoDB\Driver\ClientEncryption::getKey' => ['?object', 'keyId' => 'MongoDB\BSON\Binary'],
'MongoDB\Driver\ClientEncryption::getKeyByAltName' => ['?object', 'keyAltName' => 'string'],
'MongoDB\Driver\ClientEncryption::getKeys' => ['MongoDB\Driver\Cursor'],
'MongoDB\Driver\ClientEncryption::removeKeyAltName' => ['?object', 'keyId' => 'MongoDB\BSON\Binary', 'keyAltName' => 'string'],
'MongoDB\Driver\ClientEncryption::rewrapManyDataKey' => ['object', 'filter' => 'object|array', 'options=' => '?array'],
'MongoDB\Driver\Command::__construct' => ['void', 'document' => 'object|array', 'commandOptions=' => '?array'],
'MongoDB\Driver\Cursor::current' => ['object|array|null'],
'MongoDB\Driver\Cursor::getId' => ['MongoDB\Driver\CursorId'],
'MongoDB\Driver\Cursor::getServer' => ['MongoDB\Driver\Server'],
'MongoDB\Driver\Cursor::isDead' => ['bool'],
'MongoDB\Driver\Cursor::key' => ['?int'],
'MongoDB\Driver\Cursor::next' => ['void'],
'MongoDB\Driver\Cursor::rewind' => ['void'],
'MongoDB\Driver\Cursor::setTypeMap' => ['void', 'typemap' => 'array'],
'MongoDB\Driver\Cursor::toArray' => ['array'],
'MongoDB\Driver\Cursor::valid' => ['bool'],
'MongoDB\Driver\CursorId::__toString' => ['string'],
'MongoDB\Driver\CursorId::serialize' => ['string'],
'MongoDB\Driver\CursorId::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\Driver\CursorInterface::getId' => ['MongoDB\Driver\CursorId'],
'MongoDB\Driver\CursorInterface::getServer' => ['MongoDB\Driver\Server'],
'MongoDB\Driver\CursorInterface::isDead' => ['bool'],
'MongoDB\Driver\CursorInterface::setTypeMap' => ['void', 'typemap' => 'array'],
'MongoDB\Driver\CursorInterface::toArray' => ['array'],
'MongoDB\Driver\Exception\AuthenticationException::__toString' => ['string'],
'MongoDB\Driver\Exception\BulkWriteException::__toString' => ['string'],
'MongoDB\Driver\Exception\CommandException::getResultDocument' => ['object'],
'MongoDB\Driver\Exception\CommandException::__toString' => ['string'],
'MongoDB\Driver\Exception\ConnectionException::__toString' => ['string'],
'MongoDB\Driver\Exception\ConnectionTimeoutException::__toString' => ['string'],
'MongoDB\Driver\Exception\EncryptionException::__toString' => ['string'],
'MongoDB\Driver\Exception\Exception::__toString' => ['string'],
'MongoDB\Driver\Exception\ExecutionTimeoutException::__toString' => ['string'],
'MongoDB\Driver\Exception\InvalidArgumentException::__toString' => ['string'],
'MongoDB\Driver\Exception\LogicException::__toString' => ['string'],
'MongoDB\Driver\Exception\RuntimeException::hasErrorLabel' => ['bool', 'errorLabel' => 'string'],
'MongoDB\Driver\Exception\RuntimeException::__toString' => ['string'],
'MongoDB\Driver\Exception\SSLConnectionException::__toString' => ['string'],
'MongoDB\Driver\Exception\ServerException::__toString' => ['string'],
'MongoDB\Driver\Exception\UnexpectedValueException::__toString' => ['string'],
'MongoDB\Driver\Exception\WriteException::getWriteResult' => ['MongoDB\Driver\WriteResult'],
'MongoDB\Driver\Exception\WriteException::__toString' => ['string'],
'MongoDB\Driver\Manager::__construct' => ['void', 'uri=' => '?string', 'uriOptions=' => '?array', 'driverOptions=' => '?array'],
'MongoDB\Driver\Manager::addSubscriber' => ['void', 'subscriber' => 'MongoDB\Driver\Monitoring\Subscriber'],
'MongoDB\Driver\Manager::createClientEncryption' => ['MongoDB\Driver\ClientEncryption', 'options' => 'array'],
'MongoDB\Driver\Manager::executeBulkWrite' => ['MongoDB\Driver\WriteResult', 'namespace' => 'string', 'bulk' => 'MongoDB\Driver\BulkWrite', 'options=' => 'MongoDB\Driver\WriteConcern|array|null'],
'MongoDB\Driver\Manager::executeCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
'MongoDB\Driver\Manager::executeQuery' => ['MongoDB\Driver\Cursor', 'namespace' => 'string', 'query' => 'MongoDB\Driver\Query', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
'MongoDB\Driver\Manager::executeReadCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
'MongoDB\Driver\Manager::executeReadWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
'MongoDB\Driver\Manager::executeWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
'MongoDB\Driver\Manager::getEncryptedFieldsMap' => ['object|array|null'],
'MongoDB\Driver\Manager::getReadConcern' => ['MongoDB\Driver\ReadConcern'],
'MongoDB\Driver\Manager::getReadPreference' => ['MongoDB\Driver\ReadPreference'],
'MongoDB\Driver\Manager::getServers' => ['array'],
'MongoDB\Driver\Manager::getWriteConcern' => ['MongoDB\Driver\WriteConcern'],
'MongoDB\Driver\Manager::removeSubscriber' => ['void', 'subscriber' => 'MongoDB\Driver\Monitoring\Subscriber'],
'MongoDB\Driver\Manager::selectServer' => ['MongoDB\Driver\Server', 'readPreference=' => '?MongoDB\Driver\ReadPreference'],
'MongoDB\Driver\Manager::startSession' => ['MongoDB\Driver\Session', 'options=' => '?array'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getCommandName' => ['string'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getDurationMicros' => ['int'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getError' => ['Exception'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getOperationId' => ['string'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getReply' => ['object'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getRequestId' => ['string'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getServer' => ['MongoDB\Driver\Server'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\CommandFailedEvent::getServerConnectionId' => ['?int'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getCommand' => ['object'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getCommandName' => ['string'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getDatabaseName' => ['string'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getOperationId' => ['string'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getRequestId' => ['string'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getServer' => ['MongoDB\Driver\Server'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\CommandStartedEvent::getServerConnectionId' => ['?int'],
'MongoDB\Driver\Monitoring\CommandSubscriber::commandStarted' => ['void', 'event' => 'MongoDB\Driver\Monitoring\CommandStartedEvent'],
'MongoDB\Driver\Monitoring\CommandSubscriber::commandSucceeded' => ['void', 'event' => 'MongoDB\Driver\Monitoring\CommandSucceededEvent'],
'MongoDB\Driver\Monitoring\CommandSubscriber::commandFailed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\CommandFailedEvent'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getCommandName' => ['string'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getDurationMicros' => ['int'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getOperationId' => ['string'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getReply' => ['object'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getRequestId' => ['string'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServer' => ['MongoDB\Driver\Server'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServiceId' => ['?MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\CommandSucceededEvent::getServerConnectionId' => ['?int'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::serverChanged' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerChangedEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::serverClosed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerClosedEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::serverOpening' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerOpeningEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatFailed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatStarted' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::serverHeartbeatSucceeded' => ['void', 'event' => 'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyChanged' => ['void', 'event' => 'MongoDB\Driver\Monitoring\TopologyChangedEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyClosed' => ['void', 'event' => 'MongoDB\Driver\Monitoring\TopologyClosedEvent'],
'MongoDB\Driver\Monitoring\SDAMSubscriber::topologyOpening' => ['void', 'event' => 'MongoDB\Driver\Monitoring\TopologyOpeningEvent'],
'MongoDB\Driver\Monitoring\ServerChangedEvent::getPort' => ['int'],
'MongoDB\Driver\Monitoring\ServerChangedEvent::getHost' => ['string'],
'MongoDB\Driver\Monitoring\ServerChangedEvent::getNewDescription' => ['MongoDB\Driver\ServerDescription'],
'MongoDB\Driver\Monitoring\ServerChangedEvent::getPreviousDescription' => ['MongoDB\Driver\ServerDescription'],
'MongoDB\Driver\Monitoring\ServerChangedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\ServerClosedEvent::getPort' => ['int'],
'MongoDB\Driver\Monitoring\ServerClosedEvent::getHost' => ['string'],
'MongoDB\Driver\Monitoring\ServerClosedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getDurationMicros' => ['int'],
'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getError' => ['Exception'],
'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getPort' => ['int'],
'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::getHost' => ['string'],
'MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent::isAwaited' => ['bool'],
'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::getPort' => ['int'],
'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::getHost' => ['string'],
'MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent::isAwaited' => ['bool'],
'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getDurationMicros' => ['int'],
'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getReply' => ['object'],
'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getPort' => ['int'],
'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::getHost' => ['string'],
'MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent::isAwaited' => ['bool'],
'MongoDB\Driver\Monitoring\ServerOpeningEvent::getPort' => ['int'],
'MongoDB\Driver\Monitoring\ServerOpeningEvent::getHost' => ['string'],
'MongoDB\Driver\Monitoring\ServerOpeningEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\TopologyChangedEvent::getNewDescription' => ['MongoDB\Driver\TopologyDescription'],
'MongoDB\Driver\Monitoring\TopologyChangedEvent::getPreviousDescription' => ['MongoDB\Driver\TopologyDescription'],
'MongoDB\Driver\Monitoring\TopologyChangedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\TopologyClosedEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Monitoring\TopologyOpeningEvent::getTopologyId' => ['MongoDB\BSON\ObjectId'],
'MongoDB\Driver\Query::__construct' => ['void', 'filter' => 'object|array', 'queryOptions=' => '?array'],
'MongoDB\Driver\ReadConcern::__construct' => ['void', 'level=' => '?string'],
'MongoDB\Driver\ReadConcern::getLevel' => ['?string'],
'MongoDB\Driver\ReadConcern::isDefault' => ['bool'],
'MongoDB\Driver\ReadConcern::bsonSerialize' => ['object|array'],
'MongoDB\Driver\ReadConcern::serialize' => ['string'],
'MongoDB\Driver\ReadConcern::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\Driver\ReadPreference::__construct' => ['void', 'mode' => 'string|int', 'tagSets=' => '?array', 'options=' => '?array'],
'MongoDB\Driver\ReadPreference::getHedge' => ['?object'],
'MongoDB\Driver\ReadPreference::getMaxStalenessSeconds' => ['int'],
'MongoDB\Driver\ReadPreference::getMode' => ['int'],
'MongoDB\Driver\ReadPreference::getModeString' => ['string'],
'MongoDB\Driver\ReadPreference::getTagSets' => ['array'],
'MongoDB\Driver\ReadPreference::bsonSerialize' => ['object|array'],
'MongoDB\Driver\ReadPreference::serialize' => ['string'],
'MongoDB\Driver\ReadPreference::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\Driver\Server::executeBulkWrite' => ['MongoDB\Driver\WriteResult', 'namespace' => 'string', 'bulkWrite' => 'MongoDB\Driver\BulkWrite', 'options=' => 'MongoDB\Driver\WriteConcern|array|null'],
'MongoDB\Driver\Server::executeCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
'MongoDB\Driver\Server::executeQuery' => ['MongoDB\Driver\Cursor', 'namespace' => 'string', 'query' => 'MongoDB\Driver\Query', 'options=' => 'MongoDB\Driver\ReadPreference|array|null'],
'MongoDB\Driver\Server::executeReadCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
'MongoDB\Driver\Server::executeReadWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
'MongoDB\Driver\Server::executeWriteCommand' => ['MongoDB\Driver\Cursor', 'db' => 'string', 'command' => 'MongoDB\Driver\Command', 'options=' => '?array'],
'MongoDB\Driver\Server::getHost' => ['string'],
'MongoDB\Driver\Server::getInfo' => ['array'],
'MongoDB\Driver\Server::getLatency' => ['?int'],
'MongoDB\Driver\Server::getPort' => ['int'],
'MongoDB\Driver\Server::getServerDescription' => ['MongoDB\Driver\ServerDescription'],
'MongoDB\Driver\Server::getTags' => ['array'],
'MongoDB\Driver\Server::getType' => ['int'],
'MongoDB\Driver\Server::isArbiter' => ['bool'],
'MongoDB\Driver\Server::isHidden' => ['bool'],
'MongoDB\Driver\Server::isPassive' => ['bool'],
'MongoDB\Driver\Server::isPrimary' => ['bool'],
'MongoDB\Driver\Server::isSecondary' => ['bool'],
'MongoDB\Driver\ServerApi::__construct' => ['void', 'version' => 'string', 'strict=' => '?bool', 'deprecationErrors=' => '?bool'],
'MongoDB\Driver\ServerApi::bsonSerialize' => ['object|array'],
'MongoDB\Driver\ServerApi::serialize' => ['string'],
'MongoDB\Driver\ServerApi::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\Driver\ServerDescription::getHelloResponse' => ['array'],
'MongoDB\Driver\ServerDescription::getHost' => ['string'],
'MongoDB\Driver\ServerDescription::getLastUpdateTime' => ['int'],
'MongoDB\Driver\ServerDescription::getPort' => ['int'],
'MongoDB\Driver\ServerDescription::getRoundTripTime' => ['?int'],
'MongoDB\Driver\ServerDescription::getType' => ['string'],
'MongoDB\Driver\Session::abortTransaction' => ['void'],
'MongoDB\Driver\Session::advanceClusterTime' => ['void', 'clusterTime' => 'object|array'],
'MongoDB\Driver\Session::advanceOperationTime' => ['void', 'operationTime' => 'MongoDB\BSON\TimestampInterface'],
'MongoDB\Driver\Session::commitTransaction' => ['void'],
'MongoDB\Driver\Session::endSession' => ['void'],
'MongoDB\Driver\Session::getClusterTime' => ['?object'],
'MongoDB\Driver\Session::getLogicalSessionId' => ['object'],
'MongoDB\Driver\Session::getOperationTime' => ['?MongoDB\BSON\Timestamp'],
'MongoDB\Driver\Session::getServer' => ['?MongoDB\Driver\Server'],
'MongoDB\Driver\Session::getTransactionOptions' => ['?array'],
'MongoDB\Driver\Session::getTransactionState' => ['string'],
'MongoDB\Driver\Session::isDirty' => ['bool'],
'MongoDB\Driver\Session::isInTransaction' => ['bool'],
'MongoDB\Driver\Session::startTransaction' => ['void', 'options=' => '?array'],
'MongoDB\Driver\TopologyDescription::getServers' => ['array'],
'MongoDB\Driver\TopologyDescription::getType' => ['string'],
'MongoDB\Driver\TopologyDescription::hasReadableServer' => ['bool', 'readPreference=' => '?MongoDB\Driver\ReadPreference'],
'MongoDB\Driver\TopologyDescription::hasWritableServer' => ['bool'],
'MongoDB\Driver\WriteConcern::__construct' => ['void', 'w' => 'string|int', 'wtimeout=' => '?int', 'journal=' => '?bool'],
'MongoDB\Driver\WriteConcern::getJournal' => ['?bool'],
'MongoDB\Driver\WriteConcern::getW' => ['string|int|null'],
'MongoDB\Driver\WriteConcern::getWtimeout' => ['int'],
'MongoDB\Driver\WriteConcern::isDefault' => ['bool'],
'MongoDB\Driver\WriteConcern::bsonSerialize' => ['object|array'],
'MongoDB\Driver\WriteConcern::serialize' => ['string'],
'MongoDB\Driver\WriteConcern::unserialize' => ['void', 'serialized' => 'string'],
'MongoDB\Driver\WriteConcernError::getCode' => ['int'],
'MongoDB\Driver\WriteConcernError::getInfo' => ['?object'],
'MongoDB\Driver\WriteConcernError::getMessage' => ['string'],
'MongoDB\Driver\WriteError::getCode' => ['int'],
'MongoDB\Driver\WriteError::getIndex' => ['int'],
'MongoDB\Driver\WriteError::getInfo' => ['?object'],
'MongoDB\Driver\WriteError::getMessage' => ['string'],
'MongoDB\Driver\WriteResult::getInsertedCount' => ['?int'],
'MongoDB\Driver\WriteResult::getMatchedCount' => ['?int'],
'MongoDB\Driver\WriteResult::getModifiedCount' => ['?int'],
'MongoDB\Driver\WriteResult::getDeletedCount' => ['?int'],
'MongoDB\Driver\WriteResult::getUpsertedCount' => ['?int'],
'MongoDB\Driver\WriteResult::getServer' => ['MongoDB\Driver\Server'],
'MongoDB\Driver\WriteResult::getUpsertedIds' => ['array'],
'MongoDB\Driver\WriteResult::getWriteConcernError' => ['?MongoDB\Driver\WriteConcernError'],
'MongoDB\Driver\WriteResult::getWriteErrors' => ['array'],
'MongoDB\Driver\WriteResult::isAcknowledged' => ['bool'],
'MongoDBRef::create' => ['array', 'collection'=>'string', 'id'=>'mixed', 'database='=>'string'],
'MongoDBRef::get' => ['?array', 'db'=>'MongoDB', 'ref'=>'array'],
'MongoDBRef::isRef' => ['bool', 'ref'=>'mixed'],
'MongoDeleteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'],
'MongoException::__clone' => ['void'],
'MongoException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'MongoException::__toString' => ['string'],
'MongoException::__wakeup' => ['void'],
'MongoException::getCode' => ['int'],
'MongoException::getFile' => ['string'],
'MongoException::getLine' => ['int'],
'MongoException::getMessage' => ['string'],
'MongoException::getPrevious' => ['Exception|Throwable'],
'MongoException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'MongoException::getTraceAsString' => ['string'],
'MongoGridFS::__construct' => ['void', 'db'=>'MongoDB', 'prefix='=>'string', 'chunks='=>'mixed'],
'MongoGridFS::__get' => ['MongoCollection', 'name'=>'string'],
'MongoGridFS::__toString' => ['string'],
'MongoGridFS::aggregate' => ['array', 'pipeline'=>'array', 'op'=>'array', 'pipelineOperators'=>'array'],
'MongoGridFS::aggregateCursor' => ['MongoCommandCursor', 'pipeline'=>'array', 'options'=>'array'],
'MongoGridFS::batchInsert' => ['mixed', 'a'=>'array', 'options='=>'array'],
'MongoGridFS::count' => ['int', 'query='=>'stdClass|array'],
'MongoGridFS::createDBRef' => ['array', 'a'=>'array'],
'MongoGridFS::createIndex' => ['array', 'keys'=>'array', 'options='=>'array'],
'MongoGridFS::delete' => ['bool', 'id'=>'mixed'],
'MongoGridFS::deleteIndex' => ['array', 'keys'=>'array|string'],
'MongoGridFS::deleteIndexes' => ['array'],
'MongoGridFS::distinct' => ['array|bool', 'key'=>'string', 'query='=>'?array'],
'MongoGridFS::drop' => ['array'],
'MongoGridFS::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'],
'MongoGridFS::find' => ['MongoGridFSCursor', 'query='=>'array', 'fields='=>'array'],
'MongoGridFS::findAndModify' => ['array', 'query'=>'array', 'update='=>'?array', 'fields='=>'?array', 'options='=>'?array'],
'MongoGridFS::findOne' => ['?MongoGridFSFile', 'query='=>'mixed', 'fields='=>'mixed'],
'MongoGridFS::get' => ['?MongoGridFSFile', 'id'=>'mixed'],
'MongoGridFS::getDBRef' => ['array', 'ref'=>'array'],
'MongoGridFS::getIndexInfo' => ['array'],
'MongoGridFS::getName' => ['string'],
'MongoGridFS::getReadPreference' => ['array'],
'MongoGridFS::getSlaveOkay' => ['bool'],
'MongoGridFS::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'MongoCode', 'condition='=>'array'],
'MongoGridFS::insert' => ['array|bool', 'a'=>'array|object', 'options='=>'array'],
'MongoGridFS::put' => ['mixed', 'filename'=>'string', 'extra='=>'array'],
'MongoGridFS::remove' => ['bool', 'criteria='=>'array', 'options='=>'array'],
'MongoGridFS::save' => ['array|bool', 'a'=>'array|object', 'options='=>'array'],
'MongoGridFS::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags'=>'array'],
'MongoGridFS::setSlaveOkay' => ['bool', 'ok='=>'bool'],
'MongoGridFS::storeBytes' => ['mixed', 'bytes'=>'string', 'extra='=>'array', 'options='=>'array'],
'MongoGridFS::storeFile' => ['mixed', 'filename'=>'string', 'extra='=>'array', 'options='=>'array'],
'MongoGridFS::storeUpload' => ['mixed', 'name'=>'string', 'filename='=>'string'],
'MongoGridFS::toIndexString' => ['string', 'keys'=>'mixed'],
'MongoGridFS::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'],
'MongoGridFS::validate' => ['array', 'scan_data='=>'bool'],
'MongoGridFSCursor::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'connection'=>'resource', 'ns'=>'string', 'query'=>'array', 'fields'=>'array'],
'MongoGridFSCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'],
'MongoGridFSCursor::awaitData' => ['MongoCursor', 'wait='=>'bool'],
'MongoGridFSCursor::batchSize' => ['MongoCursor', 'batchSize'=>'int'],
'MongoGridFSCursor::count' => ['int', 'all='=>'bool'],
'MongoGridFSCursor::current' => ['MongoGridFSFile'],
'MongoGridFSCursor::dead' => ['bool'],
'MongoGridFSCursor::doQuery' => ['void'],
'MongoGridFSCursor::explain' => ['array'],
'MongoGridFSCursor::fields' => ['MongoCursor', 'f'=>'array'],
'MongoGridFSCursor::getNext' => ['MongoGridFSFile'],
'MongoGridFSCursor::getReadPreference' => ['array'],
'MongoGridFSCursor::hasNext' => ['bool'],
'MongoGridFSCursor::hint' => ['MongoCursor', 'key_pattern'=>'mixed'],
'MongoGridFSCursor::immortal' => ['MongoCursor', 'liveForever='=>'bool'],
'MongoGridFSCursor::info' => ['array'],
'MongoGridFSCursor::key' => ['string'],
'MongoGridFSCursor::limit' => ['MongoCursor', 'num'=>'int'],
'MongoGridFSCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'],
'MongoGridFSCursor::next' => ['void'],
'MongoGridFSCursor::partial' => ['MongoCursor', 'okay='=>'bool'],
'MongoGridFSCursor::reset' => ['void'],
'MongoGridFSCursor::rewind' => ['void'],
'MongoGridFSCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool'],
'MongoGridFSCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags'=>'array'],
'MongoGridFSCursor::skip' => ['MongoCursor', 'num'=>'int'],
'MongoGridFSCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool'],
'MongoGridFSCursor::snapshot' => ['MongoCursor'],
'MongoGridFSCursor::sort' => ['MongoCursor', 'fields'=>'array'],
'MongoGridFSCursor::tailable' => ['MongoCursor', 'tail='=>'bool'],
'MongoGridFSCursor::timeout' => ['MongoCursor', 'ms'=>'int'],
'MongoGridFSCursor::valid' => ['bool'],
'MongoGridfsFile::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'file'=>'array'],
'MongoGridFSFile::getBytes' => ['string'],
'MongoGridFSFile::getFilename' => ['string'],
'MongoGridFSFile::getResource' => ['resource'],
'MongoGridFSFile::getSize' => ['int'],
'MongoGridFSFile::write' => ['int', 'filename='=>'string'],
'MongoId::__construct' => ['void', 'id='=>'string|MongoId'],
'MongoId::__set_state' => ['MongoId', 'props'=>'array'],
'MongoId::__toString' => ['string'],
'MongoId::getHostname' => ['string'],
'MongoId::getInc' => ['int'],
'MongoId::getPID' => ['int'],
'MongoId::getTimestamp' => ['int'],
'MongoId::isValid' => ['bool', 'value'=>'mixed'],
'MongoInsertBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'],
'MongoInt32::__construct' => ['void', 'value'=>'string'],
'MongoInt32::__toString' => ['string'],
'MongoInt64::__construct' => ['void', 'value'=>'string'],
'MongoInt64::__toString' => ['string'],
'MongoLog::getCallback' => ['callable'],
'MongoLog::getLevel' => ['int'],
'MongoLog::getModule' => ['int'],
'MongoLog::setCallback' => ['void', 'log_function'=>'callable'],
'MongoLog::setLevel' => ['void', 'level'=>'int'],
'MongoLog::setModule' => ['void', 'module'=>'int'],
'MongoPool::getSize' => ['int'],
'MongoPool::info' => ['array'],
'MongoPool::setSize' => ['bool', 'size'=>'int'],
'MongoRegex::__construct' => ['void', 'regex'=>'string'],
'MongoRegex::__toString' => ['string'],
'MongoResultException::__clone' => ['void'],
'MongoResultException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'MongoResultException::__toString' => ['string'],
'MongoResultException::__wakeup' => ['void'],
'MongoResultException::getCode' => ['int'],
'MongoResultException::getDocument' => ['array'],
'MongoResultException::getFile' => ['string'],
'MongoResultException::getLine' => ['int'],
'MongoResultException::getMessage' => ['string'],
'MongoResultException::getPrevious' => ['Exception|Throwable'],
'MongoResultException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'MongoResultException::getTraceAsString' => ['string'],
'MongoTimestamp::__construct' => ['void', 'second='=>'int', 'inc='=>'int'],
'MongoTimestamp::__toString' => ['string'],
'MongoUpdateBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'],
'MongoUpdateBatch::add' => ['bool', 'item'=>'array'],
'MongoUpdateBatch::execute' => ['array', 'write_options'=>'array'],
'MongoWriteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'batch_type'=>'string', 'write_options'=>'array'],
'MongoWriteBatch::add' => ['bool', 'item'=>'array'],
'MongoWriteBatch::execute' => ['array', 'write_options'=>'array'],
'MongoWriteConcernException::__clone' => ['void'],
'MongoWriteConcernException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'MongoWriteConcernException::__toString' => ['string'],
'MongoWriteConcernException::__wakeup' => ['void'],
'MongoWriteConcernException::getCode' => ['int'],
'MongoWriteConcernException::getDocument' => ['array'],
'MongoWriteConcernException::getFile' => ['string'],
'MongoWriteConcernException::getLine' => ['int'],
'MongoWriteConcernException::getMessage' => ['string'],
'MongoWriteConcernException::getPrevious' => ['Exception|Throwable'],
'MongoWriteConcernException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'MongoWriteConcernException::getTraceAsString' => ['string'],
'monitor_custom_event' => ['void', 'class'=>'string', 'text'=>'string', 'severe='=>'int', 'user_data='=>'mixed'],
'monitor_httperror_event' => ['void', 'error_code'=>'int', 'url'=>'string', 'severe='=>'int'],
'monitor_license_info' => ['array'],
'monitor_pass_error' => ['void', 'errno'=>'int', 'errstr'=>'string', 'errfile'=>'string', 'errline'=>'int'],
'monitor_set_aggregation_hint' => ['void', 'hint'=>'string'],
'move_uploaded_file' => ['bool', 'from'=>'string', 'to'=>'string'],
'mqseries_back' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_begin' => ['void', 'hconn'=>'resource', 'beginoptions'=>'array', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_close' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'options'=>'int', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_cmit' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_conn' => ['void', 'qmanagername'=>'string', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_connx' => ['void', 'qmanagername'=>'string', 'connoptions'=>'array', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_disc' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_get' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'gmo'=>'array', 'bufferlength'=>'int', 'msg'=>'string', 'data_length'=>'int', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_inq' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattr'=>'resource', 'charattrlength'=>'int', 'charattr'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_open' => ['void', 'hconn'=>'resource', 'objdesc'=>'array', 'option'=>'int', 'hobj'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_put' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'pmo'=>'array', 'message'=>'string', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_put1' => ['void', 'hconn'=>'resource', 'objdesc'=>'resource', 'msgdesc'=>'resource', 'pmo'=>'resource', 'buffer'=>'string', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_set' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattrs'=>'array', 'charattrlength'=>'int', 'charattrs'=>'array', 'compcode'=>'resource', 'reason'=>'resource'],
'mqseries_strerror' => ['string', 'reason'=>'int'],
'ms_GetErrorObj' => ['errorObj'],
'ms_GetVersion' => ['string'],
'ms_GetVersionInt' => ['int'],
'ms_iogetStdoutBufferBytes' => ['int'],
'ms_iogetstdoutbufferstring' => ['void'],
'ms_ioinstallstdinfrombuffer' => ['void'],
'ms_ioinstallstdouttobuffer' => ['void'],
'ms_ioresethandlers' => ['void'],
'ms_iostripstdoutbuffercontentheaders' => ['void'],
'ms_iostripstdoutbuffercontenttype' => ['string'],
'ms_ResetErrorList' => ['void'],
'ms_TokenizeMap' => ['array', 'map_file_name'=>'string'],
'msession_connect' => ['bool', 'host'=>'string', 'port'=>'string'],
'msession_count' => ['int'],
'msession_create' => ['bool', 'session'=>'string', 'classname='=>'string', 'data='=>'string'],
'msession_destroy' => ['bool', 'name'=>'string'],
'msession_disconnect' => ['void'],
'msession_find' => ['array', 'name'=>'string', 'value'=>'string'],
'msession_get' => ['string', 'session'=>'string', 'name'=>'string', 'value'=>'string'],
'msession_get_array' => ['array', 'session'=>'string'],
'msession_get_data' => ['string', 'session'=>'string'],
'msession_inc' => ['string', 'session'=>'string', 'name'=>'string'],
'msession_list' => ['array'],
'msession_listvar' => ['array', 'name'=>'string'],
'msession_lock' => ['int', 'name'=>'string'],
'msession_plugin' => ['string', 'session'=>'string', 'value'=>'string', 'param='=>'string'],
'msession_randstr' => ['string', 'param'=>'int'],
'msession_set' => ['bool', 'session'=>'string', 'name'=>'string', 'value'=>'string'],
'msession_set_array' => ['void', 'session'=>'string', 'tuples'=>'array'],
'msession_set_data' => ['bool', 'session'=>'string', 'value'=>'string'],
'msession_timeout' => ['int', 'session'=>'string', 'param='=>'int'],
'msession_uniq' => ['string', 'param'=>'int', 'classname='=>'string', 'data='=>'string'],
'msession_unlock' => ['int', 'session'=>'string', 'key'=>'int'],
'msg_get_queue' => ['SysvMessageQueue|false', 'key'=>'int', 'permissions='=>'int'],
'msg_queue_exists' => ['bool', 'key'=>'int'],
'msg_receive' => ['bool', 'queue'=>'resource', 'desired_message_type'=>'int', '&w_received_message_type'=>'int', 'max_message_size'=>'int', '&w_message'=>'mixed', 'unserialize='=>'bool', 'flags='=>'int', '&w_error_code='=>'int'],
'msg_remove_queue' => ['bool', 'queue'=>'resource'],
'msg_send' => ['bool', 'queue'=>'resource', 'message_type'=>'int', 'message'=>'mixed', 'serialize='=>'bool', 'blocking='=>'bool', '&w_error_code='=>'int'],
'msg_set_queue' => ['bool', 'queue'=>'resource', 'data'=>'array'],
'msg_stat_queue' => ['array', 'queue'=>'resource'],
'msgfmt_create' => ['?MessageFormatter', 'locale'=>'string', 'pattern'=>'string'],
'msgfmt_format' => ['string|false', 'formatter'=>'MessageFormatter', 'values'=>'array'],
'msgfmt_format_message' => ['string|false', 'locale'=>'string', 'pattern'=>'string', 'values'=>'array'],
'msgfmt_get_error_code' => ['int', 'formatter'=>'MessageFormatter'],
'msgfmt_get_error_message' => ['string', 'formatter'=>'MessageFormatter'],
'msgfmt_get_locale' => ['string', 'formatter'=>'MessageFormatter'],
'msgfmt_get_pattern' => ['string', 'formatter'=>'MessageFormatter'],
'msgfmt_parse' => ['array|false', 'formatter'=>'MessageFormatter', 'string'=>'string'],
'msgfmt_parse_message' => ['array|false', 'locale'=>'string', 'pattern'=>'string', 'message'=>'string'],
'msgfmt_set_pattern' => ['bool', 'formatter'=>'MessageFormatter', 'pattern'=>'string'],
'msql_affected_rows' => ['int', 'result'=>'resource'],
'msql_close' => ['bool', 'link_identifier='=>'?resource'],
'msql_connect' => ['resource', 'hostname='=>'string'],
'msql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
'msql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'],
'msql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'],
'msql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
'msql_error' => ['string'],
'msql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'],
'msql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'],
'msql_fetch_object' => ['object', 'result'=>'resource'],
'msql_fetch_row' => ['array', 'result'=>'resource'],
'msql_field_flags' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
'msql_field_len' => ['int', 'result'=>'resource', 'field_offset'=>'int'],
'msql_field_name' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
'msql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'],
'msql_field_table' => ['int', 'result'=>'resource', 'field_offset'=>'int'],
'msql_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'],
'msql_free_result' => ['bool', 'result'=>'resource'],
'msql_list_dbs' => ['resource', 'link_identifier='=>'?resource'],
'msql_list_fields' => ['resource', 'database'=>'string', 'tablename'=>'string', 'link_identifier='=>'?resource'],
'msql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'],
'msql_num_fields' => ['int', 'result'=>'resource'],
'msql_num_rows' => ['int', 'query_identifier'=>'resource'],
'msql_pconnect' => ['resource', 'hostname='=>'string'],
'msql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource'],
'msql_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'],
'msql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'],
'mt_getrandmax' => ['int'],
'mt_rand' => ['int', 'min'=>'int', 'max'=>'int'],
'mt_rand\'1' => ['int'],
'mt_srand' => ['void', 'seed='=>'int', 'mode='=>'int'],
'MultipleIterator::__construct' => ['void', 'flags='=>'int'],
'MultipleIterator::attachIterator' => ['void', 'iterator'=>'Iterator', 'infos='=>'string'],
'MultipleIterator::containsIterator' => ['bool', 'iterator'=>'Iterator'],
'MultipleIterator::countIterators' => ['int'],
'MultipleIterator::current' => ['array|false'],
'MultipleIterator::detachIterator' => ['void', 'iterator'=>'Iterator'],
'MultipleIterator::getFlags' => ['int'],
'MultipleIterator::key' => ['array'],
'MultipleIterator::next' => ['void'],
'MultipleIterator::rewind' => ['void'],
'MultipleIterator::setFlags' => ['void', 'flags'=>'int'],
'MultipleIterator::valid' => ['bool'],
'Mutex::create' => ['long', 'lock='=>'bool'],
'Mutex::destroy' => ['bool', 'mutex'=>'long'],
'Mutex::lock' => ['bool', 'mutex'=>'long'],
'Mutex::trylock' => ['bool', 'mutex'=>'long'],
'Mutex::unlock' => ['bool', 'mutex'=>'long', 'destroy='=>'bool'],
'mysql_xdevapi\baseresult::getWarnings' => ['array'],
'mysql_xdevapi\baseresult::getWarningsCount' => ['integer'],
'mysql_xdevapi\collection::add' => ['mysql_xdevapi\CollectionAdd', 'document'=>'mixed'],
'mysql_xdevapi\collection::addOrReplaceOne' => ['mysql_xdevapi\Result', 'id'=>'string', 'doc'=>'string'],
'mysql_xdevapi\collection::count' => ['integer'],
'mysql_xdevapi\collection::createIndex' => ['void', 'index_name'=>'string', 'index_desc_json'=>'string'],
'mysql_xdevapi\collection::dropIndex' => ['bool', 'index_name'=>'string'],
'mysql_xdevapi\collection::existsInDatabase' => ['bool'],
'mysql_xdevapi\collection::find' => ['mysql_xdevapi\CollectionFind', 'search_condition='=>'string'],
'mysql_xdevapi\collection::getName' => ['string'],
'mysql_xdevapi\collection::getOne' => ['Document', 'id'=>'string'],
'mysql_xdevapi\collection::getSchema' => ['mysql_xdevapi\schema'],
'mysql_xdevapi\collection::getSession' => ['Session'],
'mysql_xdevapi\collection::modify' => ['mysql_xdevapi\CollectionModify', 'search_condition'=>'string'],
'mysql_xdevapi\collection::remove' => ['mysql_xdevapi\CollectionRemove', 'search_condition'=>'string'],
'mysql_xdevapi\collection::removeOne' => ['mysql_xdevapi\Result', 'id'=>'string'],
'mysql_xdevapi\collection::replaceOne' => ['mysql_xdevapi\Result', 'id'=>'string', 'doc'=>'string'],
'mysql_xdevapi\collectionadd::execute' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\collectionfind::bind' => ['mysql_xdevapi\CollectionFind', 'placeholder_values'=>'array'],
'mysql_xdevapi\collectionfind::execute' => ['mysql_xdevapi\DocResult'],
'mysql_xdevapi\collectionfind::fields' => ['mysql_xdevapi\CollectionFind', 'projection'=>'string'],
'mysql_xdevapi\collectionfind::groupBy' => ['mysql_xdevapi\CollectionFind', 'sort_expr'=>'string'],
'mysql_xdevapi\collectionfind::having' => ['mysql_xdevapi\CollectionFind', 'sort_expr'=>'string'],
'mysql_xdevapi\collectionfind::limit' => ['mysql_xdevapi\CollectionFind', 'rows'=>'integer'],
'mysql_xdevapi\collectionfind::lockExclusive' => ['mysql_xdevapi\CollectionFind', 'lock_waiting_option='=>'integer'],
'mysql_xdevapi\collectionfind::lockShared' => ['mysql_xdevapi\CollectionFind', 'lock_waiting_option='=>'integer'],
'mysql_xdevapi\collectionfind::offset' => ['mysql_xdevapi\CollectionFind', 'position'=>'integer'],
'mysql_xdevapi\collectionfind::sort' => ['mysql_xdevapi\CollectionFind', 'sort_expr'=>'string'],
'mysql_xdevapi\collectionmodify::arrayAppend' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
'mysql_xdevapi\collectionmodify::arrayInsert' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
'mysql_xdevapi\collectionmodify::bind' => ['mysql_xdevapi\CollectionModify', 'placeholder_values'=>'array'],
'mysql_xdevapi\collectionmodify::execute' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\collectionmodify::limit' => ['mysql_xdevapi\CollectionModify', 'rows'=>'integer'],
'mysql_xdevapi\collectionmodify::patch' => ['mysql_xdevapi\CollectionModify', 'document'=>'string'],
'mysql_xdevapi\collectionmodify::replace' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
'mysql_xdevapi\collectionmodify::set' => ['mysql_xdevapi\CollectionModify', 'collection_field'=>'string', 'expression_or_literal'=>'string'],
'mysql_xdevapi\collectionmodify::skip' => ['mysql_xdevapi\CollectionModify', 'position'=>'integer'],
'mysql_xdevapi\collectionmodify::sort' => ['mysql_xdevapi\CollectionModify', 'sort_expr'=>'string'],
'mysql_xdevapi\collectionmodify::unset' => ['mysql_xdevapi\CollectionModify', 'fields'=>'array'],
'mysql_xdevapi\collectionremove::bind' => ['mysql_xdevapi\CollectionRemove', 'placeholder_values'=>'array'],
'mysql_xdevapi\collectionremove::execute' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\collectionremove::limit' => ['mysql_xdevapi\CollectionRemove', 'rows'=>'integer'],
'mysql_xdevapi\collectionremove::sort' => ['mysql_xdevapi\CollectionRemove', 'sort_expr'=>'string'],
'mysql_xdevapi\columnresult::getCharacterSetName' => ['string'],
'mysql_xdevapi\columnresult::getCollationName' => ['string'],
'mysql_xdevapi\columnresult::getColumnLabel' => ['string'],
'mysql_xdevapi\columnresult::getColumnName' => ['string'],
'mysql_xdevapi\columnresult::getFractionalDigits' => ['integer'],
'mysql_xdevapi\columnresult::getLength' => ['integer'],
'mysql_xdevapi\columnresult::getSchemaName' => ['string'],
'mysql_xdevapi\columnresult::getTableLabel' => ['string'],
'mysql_xdevapi\columnresult::getTableName' => ['string'],
'mysql_xdevapi\columnresult::getType' => ['integer'],
'mysql_xdevapi\columnresult::isNumberSigned' => ['integer'],
'mysql_xdevapi\columnresult::isPadded' => ['integer'],
'mysql_xdevapi\crudoperationbindable::bind' => ['mysql_xdevapi\CrudOperationBindable', 'placeholder_values'=>'array'],
'mysql_xdevapi\crudoperationlimitable::limit' => ['mysql_xdevapi\CrudOperationLimitable', 'rows'=>'integer'],
'mysql_xdevapi\crudoperationskippable::skip' => ['mysql_xdevapi\CrudOperationSkippable', 'skip'=>'integer'],
'mysql_xdevapi\crudoperationsortable::sort' => ['mysql_xdevapi\CrudOperationSortable', 'sort_expr'=>'string'],
'mysql_xdevapi\databaseobject::existsInDatabase' => ['bool'],
'mysql_xdevapi\databaseobject::getName' => ['string'],
'mysql_xdevapi\databaseobject::getSession' => ['mysql_xdevapi\Session'],
'mysql_xdevapi\docresult::fetchAll' => ['Array'],
'mysql_xdevapi\docresult::fetchOne' => ['Object'],
'mysql_xdevapi\docresult::getWarnings' => ['Array'],
'mysql_xdevapi\docresult::getWarningsCount' => ['integer'],
'mysql_xdevapi\executable::execute' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\getsession' => ['mysql_xdevapi\Session', 'uri'=>'string'],
'mysql_xdevapi\result::getAutoIncrementValue' => ['int'],
'mysql_xdevapi\result::getGeneratedIds' => ['ArrayOfInt'],
'mysql_xdevapi\result::getWarnings' => ['array'],
'mysql_xdevapi\result::getWarningsCount' => ['integer'],
'mysql_xdevapi\rowresult::fetchAll' => ['array'],
'mysql_xdevapi\rowresult::fetchOne' => ['object'],
'mysql_xdevapi\rowresult::getColumnCount' => ['integer'],
'mysql_xdevapi\rowresult::getColumnNames' => ['array'],
'mysql_xdevapi\rowresult::getColumns' => ['array'],
'mysql_xdevapi\rowresult::getWarnings' => ['array'],
'mysql_xdevapi\rowresult::getWarningsCount' => ['integer'],
'mysql_xdevapi\schema::createCollection' => ['mysql_xdevapi\Collection', 'name'=>'string'],
'mysql_xdevapi\schema::dropCollection' => ['bool', 'collection_name'=>'string'],
'mysql_xdevapi\schema::existsInDatabase' => ['bool'],
'mysql_xdevapi\schema::getCollection' => ['mysql_xdevapi\Collection', 'name'=>'string'],
'mysql_xdevapi\schema::getCollectionAsTable' => ['mysql_xdevapi\Table', 'name'=>'string'],
'mysql_xdevapi\schema::getCollections' => ['array'],
'mysql_xdevapi\schema::getName' => ['string'],
'mysql_xdevapi\schema::getSession' => ['mysql_xdevapi\Session'],
'mysql_xdevapi\schema::getTable' => ['mysql_xdevapi\Table', 'name'=>'string'],
'mysql_xdevapi\schema::getTables' => ['array'],
'mysql_xdevapi\schemaobject::getSchema' => ['mysql_xdevapi\Schema'],
'mysql_xdevapi\session::close' => ['bool'],
'mysql_xdevapi\session::commit' => ['Object'],
'mysql_xdevapi\session::createSchema' => ['mysql_xdevapi\Schema', 'schema_name'=>'string'],
'mysql_xdevapi\session::dropSchema' => ['bool', 'schema_name'=>'string'],
'mysql_xdevapi\session::executeSql' => ['Object', 'statement'=>'string'],
'mysql_xdevapi\session::generateUUID' => ['string'],
'mysql_xdevapi\session::getClientId' => ['integer'],
'mysql_xdevapi\session::getSchema' => ['mysql_xdevapi\Schema', 'schema_name'=>'string'],
'mysql_xdevapi\session::getSchemas' => ['array'],
'mysql_xdevapi\session::getServerVersion' => ['integer'],
'mysql_xdevapi\session::killClient' => ['object', 'client_id'=>'integer'],
'mysql_xdevapi\session::listClients' => ['array'],
'mysql_xdevapi\session::quoteName' => ['string', 'name'=>'string'],
'mysql_xdevapi\session::releaseSavepoint' => ['void', 'name'=>'string'],
'mysql_xdevapi\session::rollback' => ['void'],
'mysql_xdevapi\session::rollbackTo' => ['void', 'name'=>'string'],
'mysql_xdevapi\session::setSavepoint' => ['string', 'name='=>'string'],
'mysql_xdevapi\session::sql' => ['mysql_xdevapi\SqlStatement', 'query'=>'string'],
'mysql_xdevapi\session::startTransaction' => ['void'],
'mysql_xdevapi\sqlstatement::bind' => ['mysql_xdevapi\SqlStatement', 'param'=>'string'],
'mysql_xdevapi\sqlstatement::execute' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\sqlstatement::getNextResult' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\sqlstatement::getResult' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\sqlstatement::hasMoreResults' => ['bool'],
'mysql_xdevapi\sqlstatementresult::fetchAll' => ['array'],
'mysql_xdevapi\sqlstatementresult::fetchOne' => ['object'],
'mysql_xdevapi\sqlstatementresult::getAffectedItemsCount' => ['integer'],
'mysql_xdevapi\sqlstatementresult::getColumnCount' => ['integer'],
'mysql_xdevapi\sqlstatementresult::getColumnNames' => ['array'],
'mysql_xdevapi\sqlstatementresult::getColumns' => ['Array'],
'mysql_xdevapi\sqlstatementresult::getGeneratedIds' => ['array'],
'mysql_xdevapi\sqlstatementresult::getLastInsertId' => ['String'],
'mysql_xdevapi\sqlstatementresult::getWarnings' => ['array'],
'mysql_xdevapi\sqlstatementresult::getWarningsCount' => ['integer'],
'mysql_xdevapi\sqlstatementresult::hasData' => ['bool'],
'mysql_xdevapi\sqlstatementresult::nextResult' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\statement::getNextResult' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\statement::getResult' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\statement::hasMoreResults' => ['bool'],
'mysql_xdevapi\table::count' => ['integer'],
'mysql_xdevapi\table::delete' => ['mysql_xdevapi\TableDelete'],
'mysql_xdevapi\table::existsInDatabase' => ['bool'],
'mysql_xdevapi\table::getName' => ['string'],
'mysql_xdevapi\table::getSchema' => ['mysql_xdevapi\Schema'],
'mysql_xdevapi\table::getSession' => ['mysql_xdevapi\Session'],
'mysql_xdevapi\table::insert' => ['mysql_xdevapi\TableInsert', 'columns'=>'mixed', '...args='=>'mixed'],
'mysql_xdevapi\table::isView' => ['bool'],
'mysql_xdevapi\table::select' => ['mysql_xdevapi\TableSelect', 'columns'=>'mixed', '...args='=>'mixed'],
'mysql_xdevapi\table::update' => ['mysql_xdevapi\TableUpdate'],
'mysql_xdevapi\tabledelete::bind' => ['mysql_xdevapi\TableDelete', 'placeholder_values'=>'array'],
'mysql_xdevapi\tabledelete::execute' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\tabledelete::limit' => ['mysql_xdevapi\TableDelete', 'rows'=>'integer'],
'mysql_xdevapi\tabledelete::offset' => ['mysql_xdevapi\TableDelete', 'position'=>'integer'],
'mysql_xdevapi\tabledelete::orderby' => ['mysql_xdevapi\TableDelete', 'orderby_expr'=>'string'],
'mysql_xdevapi\tabledelete::where' => ['mysql_xdevapi\TableDelete', 'where_expr'=>'string'],
'mysql_xdevapi\tableinsert::execute' => ['mysql_xdevapi\Result'],
'mysql_xdevapi\tableinsert::values' => ['mysql_xdevapi\TableInsert', 'row_values'=>'array'],
'mysql_xdevapi\tableselect::bind' => ['mysql_xdevapi\TableSelect', 'placeholder_values'=>'array'],
'mysql_xdevapi\tableselect::execute' => ['mysql_xdevapi\RowResult'],
'mysql_xdevapi\tableselect::groupBy' => ['mysql_xdevapi\TableSelect', 'sort_expr'=>'mixed'],
'mysql_xdevapi\tableselect::having' => ['mysql_xdevapi\TableSelect', 'sort_expr'=>'string'],
'mysql_xdevapi\tableselect::limit' => ['mysql_xdevapi\TableSelect', 'rows'=>'integer'],
'mysql_xdevapi\tableselect::lockExclusive' => ['mysql_xdevapi\TableSelect', 'lock_waiting_option='=>'integer'],
'mysql_xdevapi\tableselect::lockShared' => ['mysql_xdevapi\TableSelect', 'lock_waiting_option='=>'integer'],
'mysql_xdevapi\tableselect::offset' => ['mysql_xdevapi\TableSelect', 'position'=>'integer'],
'mysql_xdevapi\tableselect::orderby' => ['mysql_xdevapi\TableSelect', 'sort_expr'=>'mixed', '...args='=>'mixed'],
'mysql_xdevapi\tableselect::where' => ['mysql_xdevapi\TableSelect', 'where_expr'=>'string'],
'mysql_xdevapi\tableupdate::bind' => ['mysql_xdevapi\TableUpdate', 'placeholder_values'=>'array'],
'mysql_xdevapi\tableupdate::execute' => ['mysql_xdevapi\TableUpdate'],
'mysql_xdevapi\tableupdate::limit' => ['mysql_xdevapi\TableUpdate', 'rows'=>'integer'],
'mysql_xdevapi\tableupdate::orderby' => ['mysql_xdevapi\TableUpdate', 'orderby_expr'=>'mixed', '...args='=>'mixed'],
'mysql_xdevapi\tableupdate::set' => ['mysql_xdevapi\TableUpdate', 'table_field'=>'string', 'expression_or_literal'=>'string'],
'mysql_xdevapi\tableupdate::where' => ['mysql_xdevapi\TableUpdate', 'where_expr'=>'string'],
'mysqli::__construct' => ['void', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
'mysqli::autocommit' => ['bool', 'enable'=>'bool'],
'mysqli::begin_transaction' => ['bool', 'flags='=>'int', 'name='=>'?string'],
'mysqli::change_user' => ['bool', 'username'=>'string', 'password'=>'string', 'database'=>'?string'],
'mysqli::character_set_name' => ['string'],
'mysqli::close' => ['bool'],
'mysqli::commit' => ['bool', 'flags='=>'int', 'name='=>'?string'],
'mysqli::connect' => ['bool', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
'mysqli::debug' => ['bool', 'options'=>'string'],
'mysqli::disable_reads_from_master' => ['bool'],
'mysqli::dump_debug_info' => ['bool'],
'mysqli::escape_string' => ['string', 'string'=>'string'],
'mysqli::execute_query' => ['mysqli_result|bool', 'query'=>'non-empty-string', 'params='=>'list<mixed>|null'],
'mysqli::get_charset' => ['object'],
'mysqli::get_client_info' => ['string'],
'mysqli::get_connection_stats' => ['array'],
'mysqli::get_warnings' => ['mysqli_warning'],
'mysqli::init' => ['false|null'],
'mysqli::kill' => ['bool', 'process_id'=>'int'],
'mysqli::more_results' => ['bool'],
'mysqli::multi_query' => ['bool', 'query'=>'string'],
'mysqli::next_result' => ['bool'],
'mysqli::options' => ['bool', 'option'=>'int', 'value'=>'string|int'],
'mysqli::ping' => ['bool'],
'mysqli::poll' => ['int|false', '&w_read'=>'array', '&w_write'=>'array', '&w_error'=>'array', 'seconds'=>'int', 'microseconds='=>'int'],
'mysqli::prepare' => ['mysqli_stmt|false', 'query'=>'string'],
'mysqli::query' => ['bool|mysqli_result', 'query'=>'string', 'result_mode='=>'int'],
'mysqli::real_connect' => ['bool', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null', 'flags='=>'int'],
'mysqli::real_escape_string' => ['string', 'string'=>'string'],
'mysqli::real_query' => ['bool', 'query'=>'string'],
'mysqli::reap_async_query' => ['mysqli_result|false'],
'mysqli::refresh' => ['bool', 'flags'=>'int'],
'mysqli::release_savepoint' => ['bool', 'name'=>'string'],
'mysqli::rollback' => ['bool', 'flags='=>'int', 'name='=>'?string'],
'mysqli::rpl_query_type' => ['int', 'query'=>'string'],
'mysqli::savepoint' => ['bool', 'name'=>'string'],
'mysqli::select_db' => ['bool', 'database'=>'string'],
'mysqli::send_query' => ['bool', 'query'=>'string'],
'mysqli::set_charset' => ['bool', 'charset'=>'string'],
'mysqli::set_local_infile_default' => ['void'],
'mysqli::set_local_infile_handler' => ['bool', 'read_func='=>'callable'],
'mysqli::set_opt' => ['bool', 'option'=>'int', 'value'=>'string|int'],
'mysqli::ssl_set' => ['bool', 'key'=>'?string', 'certificate'=>'?string', 'ca_certificate'=>'?string', 'ca_path'=>'?string', 'cipher_algos'=>'?string'],
'mysqli::stat' => ['string|false'],
'mysqli::stmt_init' => ['mysqli_stmt'],
'mysqli::store_result' => ['mysqli_result|false', 'mode='=>'int'],
'mysqli::thread_safe' => ['bool'],
'mysqli::use_result' => ['mysqli_result|false'],
'mysqli_affected_rows' => ['int', 'mysql'=>'mysqli'],
'mysqli_autocommit' => ['bool', 'mysql'=>'mysqli', 'enable'=>'bool'],
'mysqli_begin_transaction' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'?string'],
'mysqli_change_user' => ['bool', 'mysql'=>'mysqli', 'username'=>'string', 'password'=>'string', 'database'=>'?string'],
'mysqli_character_set_name' => ['string', 'mysql'=>'mysqli'],
'mysqli_close' => ['bool', 'mysql'=>'mysqli'],
'mysqli_commit' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'?string'],
'mysqli_connect' => ['mysqli|false', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
'mysqli_connect_errno' => ['int'],
'mysqli_connect_error' => ['?string'],
'mysqli_data_seek' => ['bool', 'result'=>'mysqli_result', 'offset'=>'int'],
'mysqli_debug' => ['bool', 'options'=>'string'],
'mysqli_disable_reads_from_master' => ['bool', 'link'=>'mysqli'],
'mysqli_disable_rpl_parse' => ['bool', 'link'=>'mysqli'],
'mysqli_driver::embedded_server_end' => ['void'],
'mysqli_driver::embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'],
'mysqli_dump_debug_info' => ['bool', 'mysql'=>'mysqli'],
'mysqli_embedded_server_end' => ['void'],
'mysqli_embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'],
'mysqli_enable_reads_from_master' => ['bool', 'link'=>'mysqli'],
'mysqli_enable_rpl_parse' => ['bool', 'link'=>'mysqli'],
'mysqli_errno' => ['int', 'mysql'=>'mysqli'],
'mysqli_error' => ['string', 'mysql'=>'mysqli'],
'mysqli_error_list' => ['array', 'mysql'=>'mysqli'],
'mysqli_escape_string' => ['string', 'mysql'=>'mysqli', 'string'=>'string'],
'mysqli_execute' => ['bool', 'statement'=>'mysqli_stmt', 'params='=>'list<mixed>|null'],
'mysqli_execute_query' => ['mysqli_result|bool', 'mysqli'=>'mysqli', 'query'=>'non-empty-string', 'params='=>'list<mixed>|null'],
'mysqli_fetch_all' => ['list<array<array-key,null|int|float|string>>', 'result'=>'mysqli_result', 'mode='=>'3'],
'mysqli_fetch_all\'1' => ['list<array<string,null|int|float|string>>', 'result'=>'mysqli_result', 'mode='=>'1'],
'mysqli_fetch_all\'2' => ['list<list<null|int|float|string>>', 'result'=>'mysqli_result', 'mode='=>'2'],
'mysqli_fetch_array' => ['array<array-key,null|int|float|string>|false|null', 'result'=>'mysqli_result', 'mode='=>'3'],
'mysqli_fetch_array\'1' => ['array<string,null|int|float|string>|false|null', 'result'=>'mysqli_result', 'mode='=>'1'],
'mysqli_fetch_array\'2' => ['list<null|int|float|string>|false|null', 'result'=>'mysqli_result', 'mode='=>'2'],
'mysqli_fetch_assoc' => ['array<string,null|int|float|string>|false|null', 'result'=>'mysqli_result'],
'mysqli_fetch_column' => ['null|int|float|string|false', 'result'=>'mysqli_result', 'column='=>'int'],
'mysqli_fetch_field' => ['object|false', 'result'=>'mysqli_result'],
'mysqli_fetch_field_direct' => ['object|false', 'result'=>'mysqli_result', 'index'=>'int'],
'mysqli_fetch_fields' => ['stdClass[]', 'result'=>'mysqli_result'],
'mysqli_fetch_lengths' => ['array|false', 'result'=>'mysqli_result'],
'mysqli_fetch_object' => ['object|false|null', 'result'=>'mysqli_result', 'class='=>'class-string', 'constructor_args='=>'array'],
'mysqli_fetch_row' => ['list<null|int|float|string>|false|null', 'result'=>'mysqli_result'],
'mysqli_field_count' => ['int', 'mysql'=>'mysqli'],
'mysqli_field_seek' => ['bool', 'result'=>'mysqli_result', 'index'=>'int'],
'mysqli_field_tell' => ['int', 'result'=>'mysqli_result'],
'mysqli_free_result' => ['void', 'result'=>'mysqli_result'],
'mysqli_get_cache_stats' => ['array|false'],
'mysqli_get_charset' => ['?object', 'mysql'=>'mysqli'],
'mysqli_get_client_info' => ['string', 'mysql='=>'?mysqli'],
'mysqli_get_client_stats' => ['array'],
'mysqli_get_client_version' => ['int', 'link'=>'mysqli'],
'mysqli_get_connection_stats' => ['array', 'mysql'=>'mysqli'],
'mysqli_get_host_info' => ['string', 'mysql'=>'mysqli'],
'mysqli_get_links_stats' => ['array'],
'mysqli_get_proto_info' => ['int', 'mysql'=>'mysqli'],
'mysqli_get_server_info' => ['string', 'mysql'=>'mysqli'],
'mysqli_get_server_version' => ['int', 'mysql'=>'mysqli'],
'mysqli_get_warnings' => ['mysqli_warning', 'mysql'=>'mysqli'],
'mysqli_info' => ['?string', 'mysql'=>'mysqli'],
'mysqli_init' => ['mysqli|false'],
'mysqli_insert_id' => ['int|string', 'mysql'=>'mysqli'],
'mysqli_kill' => ['bool', 'mysql'=>'mysqli', 'process_id'=>'int'],
'mysqli_link_construct' => ['object'],
'mysqli_master_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'],
'mysqli_more_results' => ['bool', 'mysql'=>'mysqli'],
'mysqli_multi_query' => ['bool', 'mysql'=>'mysqli', 'query'=>'string'],
'mysqli_next_result' => ['bool', 'mysql'=>'mysqli'],
'mysqli_num_fields' => ['int', 'result'=>'mysqli_result'],
'mysqli_num_rows' => ['int', 'result'=>'mysqli_result'],
'mysqli_options' => ['bool', 'mysql'=>'mysqli', 'option'=>'int', 'value'=>'string|int'],
'mysqli_ping' => ['bool', 'mysql'=>'mysqli'],
'mysqli_poll' => ['int|false', 'read'=>'array', 'write'=>'array', 'error'=>'array', 'seconds'=>'int', 'microseconds='=>'int'],
'mysqli_prepare' => ['mysqli_stmt|false', 'mysql'=>'mysqli', 'query'=>'string'],
'mysqli_query' => ['mysqli_result|bool', 'mysql'=>'mysqli', 'query'=>'string', 'result_mode='=>'int'],
'mysqli_real_connect' => ['bool', 'mysql='=>'mysqli', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null', 'flags='=>'int'],
'mysqli_real_escape_string' => ['string', 'mysql'=>'mysqli', 'string'=>'string'],
'mysqli_real_query' => ['bool', 'mysql'=>'mysqli', 'query'=>'string'],
'mysqli_reap_async_query' => ['mysqli_result|false', 'mysql'=>'mysqli'],
'mysqli_refresh' => ['bool', 'mysql'=>'mysqli', 'flags'=>'int'],
'mysqli_release_savepoint' => ['bool', 'mysql'=>'mysqli', 'name'=>'string'],
'mysqli_report' => ['bool', 'flags'=>'int'],
'mysqli_result::__construct' => ['void', 'mysql'=>'mysqli', 'result_mode='=>'int'],
'mysqli_result::close' => ['void'],
'mysqli_result::data_seek' => ['bool', 'offset'=>'int'],
'mysqli_result::fetch_all' => ['list<array<array-key,null|int|float|string>>', 'mode='=>'3'],
'mysqli_result::fetch_all\'1' => ['list<array<string,null|int|float|string>>', 'mode='=>'1'],
'mysqli_result::fetch_all\'2' => ['list<list<null|int|float|string>>', 'mode='=>'2'],
'mysqli_result::fetch_array' => ['array<array-key,null|int|float|string>|false|null', 'mode='=>'3'],
'mysqli_result::fetch_array\'1' => ['array<string,null|int|float|string>|false|null', 'mode='=>'1'],
'mysqli_result::fetch_array\'2' => ['list<null|int|float|string>|false|null', 'mode='=>'2'],
'mysqli_result::fetch_assoc' => ['array<string,null|int|float|string>|false|null'],
'mysqli_result::fetch_column' => ['null|int|float|string|false', 'column='=>'int'],
'mysqli_result::fetch_field' => ['object|false'],
'mysqli_result::fetch_field_direct' => ['object|false', 'index'=>'int'],
'mysqli_result::fetch_fields' => ['stdClass[]'],
'mysqli_result::fetch_object' => ['object|false|null', 'class='=>'class-string', 'constructor_args='=>'array'],
'mysqli_result::fetch_row' => ['list<null|int|float|string>|false|null'],
'mysqli_result::field_seek' => ['bool', 'index'=>'int'],
'mysqli_result::free' => ['void'],
'mysqli_result::free_result' => ['void'],
'mysqli_rollback' => ['bool', 'mysql'=>'mysqli', 'flags='=>'int', 'name='=>'?string'],
'mysqli_rpl_parse_enabled' => ['int', 'link'=>'mysqli'],
'mysqli_rpl_probe' => ['bool', 'link'=>'mysqli'],
'mysqli_rpl_query_type' => ['int', 'link'=>'mysqli', 'query'=>'string'],
'mysqli_savepoint' => ['bool', 'mysql'=>'mysqli', 'name'=>'string'],
'mysqli_savepoint_libmysql' => ['bool'],
'mysqli_select_db' => ['bool', 'mysql'=>'mysqli', 'database'=>'string'],
'mysqli_send_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'],
'mysqli_set_charset' => ['bool', 'mysql'=>'mysqli', 'charset'=>'string'],
'mysqli_set_local_infile_default' => ['void', 'link'=>'mysqli'],
'mysqli_set_local_infile_handler' => ['bool', 'link'=>'mysqli', 'read_func'=>'callable'],
'mysqli_set_opt' => ['bool', 'mysql'=>'mysqli', 'option'=>'int', 'value'=>'string|int'],
'mysqli_slave_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'],
'mysqli_sqlstate' => ['string', 'mysql'=>'mysqli'],
'mysqli_ssl_set' => ['true', 'mysql'=>'mysqli', 'key'=>'?string', 'certificate'=>'?string', 'ca_certificate'=>'?string', 'ca_path'=>'?string', 'cipher_algos'=>'?string'],
'mysqli_stat' => ['string|false', 'mysql'=>'mysqli'],
'mysqli_stmt::__construct' => ['void', 'mysql'=>'mysqli', 'query'=>'string'],
'mysqli_stmt::attr_get' => ['int', 'attribute'=>'int'],
'mysqli_stmt::attr_set' => ['bool', 'attribute'=>'int', 'value'=>'int'],
'mysqli_stmt::bind_param' => ['bool', 'types'=>'string', '&vars'=>'mixed', '&...args='=>'mixed'],
'mysqli_stmt::bind_result' => ['bool', '&w_var1'=>'', '&...w_vars='=>''],
'mysqli_stmt::close' => ['bool'],
'mysqli_stmt::data_seek' => ['void', 'offset'=>'int'],
'mysqli_stmt::execute' => ['bool', 'params='=>'list<mixed>|null'],
'mysqli_stmt::fetch' => ['bool|null'],
'mysqli_stmt::free_result' => ['void'],
'mysqli_stmt::get_result' => ['mysqli_result|false'],
'mysqli_stmt::get_warnings' => ['object'],
'mysqli_stmt::more_results' => ['bool'],
'mysqli_stmt::next_result' => ['bool'],
'mysqli_stmt::num_rows' => ['int'],
'mysqli_stmt::prepare' => ['bool', 'query'=>'string'],
'mysqli_stmt::reset' => ['bool'],
'mysqli_stmt::result_metadata' => ['mysqli_result|false'],
'mysqli_stmt::send_long_data' => ['bool', 'param_num'=>'int', 'data'=>'string'],
'mysqli_stmt::store_result' => ['bool'],
'mysqli_stmt_affected_rows' => ['int|string', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_attr_get' => ['int', 'statement'=>'mysqli_stmt', 'attribute'=>'int'],
'mysqli_stmt_attr_set' => ['bool', 'statement'=>'mysqli_stmt', 'attribute'=>'int', 'value'=>'int'],
'mysqli_stmt_bind_param' => ['bool', 'statement'=>'mysqli_stmt', 'types'=>'string', '&vars'=>'mixed', '&...args='=>'mixed'],
'mysqli_stmt_bind_result' => ['bool', 'statement'=>'mysqli_stmt', '&w_var1'=>'', '&...w_vars='=>''],
'mysqli_stmt_close' => ['bool', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_data_seek' => ['void', 'statement'=>'mysqli_stmt', 'offset'=>'int'],
'mysqli_stmt_errno' => ['int', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_error' => ['string', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_error_list' => ['array', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_execute' => ['bool', 'statement'=>'mysqli_stmt', 'params='=>'list<mixed>|null'],
'mysqli_stmt_fetch' => ['bool|null', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_field_count' => ['int', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_free_result' => ['void', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_get_result' => ['mysqli_result|false', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_get_warnings' => ['object', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_init' => ['mysqli_stmt', 'mysql'=>'mysqli'],
'mysqli_stmt_insert_id' => ['mixed', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_more_results' => ['bool', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_next_result' => ['bool', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_num_rows' => ['int', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_param_count' => ['int', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_prepare' => ['bool', 'statement'=>'mysqli_stmt', 'query'=>'string'],
'mysqli_stmt_reset' => ['bool', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_result_metadata' => ['mysqli_result|false', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_send_long_data' => ['bool', 'statement'=>'mysqli_stmt', 'param_num'=>'int', 'data'=>'string'],
'mysqli_stmt_sqlstate' => ['string', 'statement'=>'mysqli_stmt'],
'mysqli_stmt_store_result' => ['bool', 'statement'=>'mysqli_stmt'],
'mysqli_store_result' => ['mysqli_result|false', 'mysql'=>'mysqli', 'mode='=>'int'],
'mysqli_thread_id' => ['int', 'mysql'=>'mysqli'],
'mysqli_thread_safe' => ['bool'],
'mysqli_use_result' => ['mysqli_result|false', 'mysql'=>'mysqli'],
'mysqli_warning::__construct' => ['void'],
'mysqli_warning::next' => ['bool'],
'mysqli_warning_count' => ['int', 'mysql'=>'mysqli'],
'mysqlnd_memcache_get_config' => ['array', 'connection'=>'mixed'],
'mysqlnd_memcache_set' => ['bool', 'mysql_connection'=>'mixed', 'memcache_connection='=>'Memcached', 'pattern='=>'string', 'callback='=>'callable'],
'mysqlnd_ms_dump_servers' => ['array', 'connection'=>'mixed'],
'mysqlnd_ms_fabric_select_global' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed'],
'mysqlnd_ms_fabric_select_shard' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed', 'shard_key'=>'mixed'],
'mysqlnd_ms_get_last_gtid' => ['string', 'connection'=>'mixed'],
'mysqlnd_ms_get_last_used_connection' => ['array', 'connection'=>'mixed'],
'mysqlnd_ms_get_stats' => ['array'],
'mysqlnd_ms_match_wild' => ['bool', 'table_name'=>'string', 'wildcard'=>'string'],
'mysqlnd_ms_query_is_select' => ['int', 'query'=>'string'],
'mysqlnd_ms_set_qos' => ['bool', 'connection'=>'mixed', 'service_level'=>'int', 'service_level_option='=>'int', 'option_value='=>'mixed'],
'mysqlnd_ms_set_user_pick_server' => ['bool', 'function'=>'string'],
'mysqlnd_ms_xa_begin' => ['int', 'connection'=>'mixed', 'gtrid'=>'string', 'timeout='=>'int'],
'mysqlnd_ms_xa_commit' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'],
'mysqlnd_ms_xa_gc' => ['int', 'connection'=>'mixed', 'gtrid='=>'string', 'ignore_max_retries='=>'bool'],
'mysqlnd_ms_xa_rollback' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'],
'mysqlnd_qc_change_handler' => ['bool', 'handler'=>''],
'mysqlnd_qc_clear_cache' => ['bool'],
'mysqlnd_qc_get_available_handlers' => ['array'],
'mysqlnd_qc_get_cache_info' => ['array'],
'mysqlnd_qc_get_core_stats' => ['array'],
'mysqlnd_qc_get_handler' => ['array'],
'mysqlnd_qc_get_normalized_query_trace_log' => ['array'],
'mysqlnd_qc_get_query_trace_log' => ['array'],
'mysqlnd_qc_set_cache_condition' => ['bool', 'condition_type'=>'int', 'condition'=>'mixed', 'condition_option'=>'mixed'],
'mysqlnd_qc_set_is_select' => ['mixed', 'callback'=>'string'],
'mysqlnd_qc_set_storage_handler' => ['bool', 'handler'=>'string'],
'mysqlnd_qc_set_user_handlers' => ['bool', 'get_hash'=>'string', 'find_query_in_cache'=>'string', 'return_to_cache'=>'string', 'add_query_to_cache_if_not_exists'=>'string', 'query_is_select'=>'string', 'update_query_run_time_stats'=>'string', 'get_stats'=>'string', 'clear_cache'=>'string'],
'mysqlnd_uh_convert_to_mysqlnd' => ['resource', '&rw_mysql_connection'=>'mysqli'],
'mysqlnd_uh_set_connection_proxy' => ['bool', '&rw_connection_proxy'=>'MysqlndUhConnection', '&rw_mysqli_connection='=>'mysqli'],
'mysqlnd_uh_set_statement_proxy' => ['bool', '&rw_statement_proxy'=>'MysqlndUhStatement'],
'MysqlndUhConnection::__construct' => ['void'],
'MysqlndUhConnection::changeUser' => ['bool', 'connection'=>'mysqlnd_connection', 'user'=>'string', 'password'=>'string', 'database'=>'string', 'silent'=>'bool', 'passwd_len'=>'int'],
'MysqlndUhConnection::charsetName' => ['string', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::close' => ['bool', 'connection'=>'mysqlnd_connection', 'close_type'=>'int'],
'MysqlndUhConnection::connect' => ['bool', 'connection'=>'mysqlnd_connection', 'host'=>'string', 'use'=>'string', 'password'=>'string', 'database'=>'string', 'port'=>'int', 'socket'=>'string', 'mysql_flags'=>'int'],
'MysqlndUhConnection::endPSession' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::escapeString' => ['string', 'connection'=>'mysqlnd_connection', 'escape_string'=>'string'],
'MysqlndUhConnection::getAffectedRows' => ['int', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getErrorNumber' => ['int', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getErrorString' => ['string', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getFieldCount' => ['int', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getHostInformation' => ['string', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getLastInsertId' => ['int', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getLastMessage' => ['void', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getProtocolInformation' => ['string', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getServerInformation' => ['string', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getServerStatistics' => ['string', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getServerVersion' => ['int', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getSqlstate' => ['string', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getStatistics' => ['array', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getThreadId' => ['int', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::getWarningCount' => ['int', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::init' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::killConnection' => ['bool', 'connection'=>'mysqlnd_connection', 'pid'=>'int'],
'MysqlndUhConnection::listFields' => ['array', 'connection'=>'mysqlnd_connection', 'table'=>'string', 'achtung_wild'=>'string'],
'MysqlndUhConnection::listMethod' => ['void', 'connection'=>'mysqlnd_connection', 'query'=>'string', 'achtung_wild'=>'string', 'par1'=>'string'],
'MysqlndUhConnection::moreResults' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::nextResult' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::ping' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::query' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'],
'MysqlndUhConnection::queryReadResultsetHeader' => ['bool', 'connection'=>'mysqlnd_connection', 'mysqlnd_stmt'=>'mysqlnd_statement'],
'MysqlndUhConnection::reapQuery' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::refreshServer' => ['bool', 'connection'=>'mysqlnd_connection', 'options'=>'int'],
'MysqlndUhConnection::restartPSession' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::selectDb' => ['bool', 'connection'=>'mysqlnd_connection', 'database'=>'string'],
'MysqlndUhConnection::sendClose' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::sendQuery' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'],
'MysqlndUhConnection::serverDumpDebugInformation' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::setAutocommit' => ['bool', 'connection'=>'mysqlnd_connection', 'mode'=>'int'],
'MysqlndUhConnection::setCharset' => ['bool', 'connection'=>'mysqlnd_connection', 'charset'=>'string'],
'MysqlndUhConnection::setClientOption' => ['bool', 'connection'=>'mysqlnd_connection', 'option'=>'int', 'value'=>'int'],
'MysqlndUhConnection::setServerOption' => ['void', 'connection'=>'mysqlnd_connection', 'option'=>'int'],
'MysqlndUhConnection::shutdownServer' => ['void', 'MYSQLND_UH_RES_MYSQLND_NAME'=>'string', 'level'=>'string'],
'MysqlndUhConnection::simpleCommand' => ['bool', 'connection'=>'mysqlnd_connection', 'command'=>'int', 'arg'=>'string', 'ok_packet'=>'int', 'silent'=>'bool', 'ignore_upsert_status'=>'bool'],
'MysqlndUhConnection::simpleCommandHandleResponse' => ['bool', 'connection'=>'mysqlnd_connection', 'ok_packet'=>'int', 'silent'=>'bool', 'command'=>'int', 'ignore_upsert_status'=>'bool'],
'MysqlndUhConnection::sslSet' => ['bool', 'connection'=>'mysqlnd_connection', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'],
'MysqlndUhConnection::stmtInit' => ['resource', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::storeResult' => ['resource', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::txCommit' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::txRollback' => ['bool', 'connection'=>'mysqlnd_connection'],
'MysqlndUhConnection::useResult' => ['resource', 'connection'=>'mysqlnd_connection'],
'MysqlndUhPreparedStatement::__construct' => ['void'],
'MysqlndUhPreparedStatement::execute' => ['bool', 'statement'=>'mysqlnd_prepared_statement'],
'MysqlndUhPreparedStatement::prepare' => ['bool', 'statement'=>'mysqlnd_prepared_statement', 'query'=>'string'],
'natcasesort' => ['bool', '&rw_array'=>'array'],
'natsort' => ['bool', '&rw_array'=>'array'],
'ncurses_addch' => ['int', 'ch'=>'int'],
'ncurses_addchnstr' => ['int', 's'=>'string', 'n'=>'int'],
'ncurses_addchstr' => ['int', 's'=>'string'],
'ncurses_addnstr' => ['int', 's'=>'string', 'n'=>'int'],
'ncurses_addstr' => ['int', 'text'=>'string'],
'ncurses_assume_default_colors' => ['int', 'fg'=>'int', 'bg'=>'int'],
'ncurses_attroff' => ['int', 'attributes'=>'int'],
'ncurses_attron' => ['int', 'attributes'=>'int'],
'ncurses_attrset' => ['int', 'attributes'=>'int'],
'ncurses_baudrate' => ['int'],
'ncurses_beep' => ['int'],
'ncurses_bkgd' => ['int', 'attrchar'=>'int'],
'ncurses_bkgdset' => ['void', 'attrchar'=>'int'],
'ncurses_border' => ['int', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'],
'ncurses_bottom_panel' => ['int', 'panel'=>'resource'],
'ncurses_can_change_color' => ['bool'],
'ncurses_cbreak' => ['bool'],
'ncurses_clear' => ['bool'],
'ncurses_clrtobot' => ['bool'],
'ncurses_clrtoeol' => ['bool'],
'ncurses_color_content' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'],
'ncurses_color_set' => ['int', 'pair'=>'int'],
'ncurses_curs_set' => ['int', 'visibility'=>'int'],
'ncurses_def_prog_mode' => ['bool'],
'ncurses_def_shell_mode' => ['bool'],
'ncurses_define_key' => ['int', 'definition'=>'string', 'keycode'=>'int'],
'ncurses_del_panel' => ['bool', 'panel'=>'resource'],
'ncurses_delay_output' => ['int', 'milliseconds'=>'int'],
'ncurses_delch' => ['bool'],
'ncurses_deleteln' => ['bool'],
'ncurses_delwin' => ['bool', 'window'=>'resource'],
'ncurses_doupdate' => ['bool'],
'ncurses_echo' => ['bool'],
'ncurses_echochar' => ['int', 'character'=>'int'],
'ncurses_end' => ['int'],
'ncurses_erase' => ['bool'],
'ncurses_erasechar' => ['string'],
'ncurses_filter' => ['void'],
'ncurses_flash' => ['bool'],
'ncurses_flushinp' => ['bool'],
'ncurses_getch' => ['int'],
'ncurses_getmaxyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'],
'ncurses_getmouse' => ['bool', 'mevent'=>'array'],
'ncurses_getyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'],
'ncurses_halfdelay' => ['int', 'tenth'=>'int'],
'ncurses_has_colors' => ['bool'],
'ncurses_has_ic' => ['bool'],
'ncurses_has_il' => ['bool'],
'ncurses_has_key' => ['int', 'keycode'=>'int'],
'ncurses_hide_panel' => ['int', 'panel'=>'resource'],
'ncurses_hline' => ['int', 'charattr'=>'int', 'n'=>'int'],
'ncurses_inch' => ['string'],
'ncurses_init' => ['void'],
'ncurses_init_color' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'],
'ncurses_init_pair' => ['int', 'pair'=>'int', 'fg'=>'int', 'bg'=>'int'],
'ncurses_insch' => ['int', 'character'=>'int'],
'ncurses_insdelln' => ['int', 'count'=>'int'],
'ncurses_insertln' => ['int'],
'ncurses_insstr' => ['int', 'text'=>'string'],
'ncurses_instr' => ['int', 'buffer'=>'string'],
'ncurses_isendwin' => ['bool'],
'ncurses_keyok' => ['int', 'keycode'=>'int', 'enable'=>'bool'],
'ncurses_keypad' => ['int', 'window'=>'resource', 'bf'=>'bool'],
'ncurses_killchar' => ['string'],
'ncurses_longname' => ['string'],
'ncurses_meta' => ['int', 'window'=>'resource', '_8bit'=>'bool'],
'ncurses_mouse_trafo' => ['bool', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'],
'ncurses_mouseinterval' => ['int', 'milliseconds'=>'int'],
'ncurses_mousemask' => ['int', 'newmask'=>'int', 'oldmask'=>'int'],
'ncurses_move' => ['int', 'y'=>'int', 'x'=>'int'],
'ncurses_move_panel' => ['int', 'panel'=>'resource', 'startx'=>'int', 'starty'=>'int'],
'ncurses_mvaddch' => ['int', 'y'=>'int', 'x'=>'int', 'c'=>'int'],
'ncurses_mvaddchnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'],
'ncurses_mvaddchstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'],
'ncurses_mvaddnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'],
'ncurses_mvaddstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'],
'ncurses_mvcur' => ['int', 'old_y'=>'int', 'old_x'=>'int', 'new_y'=>'int', 'new_x'=>'int'],
'ncurses_mvdelch' => ['int', 'y'=>'int', 'x'=>'int'],
'ncurses_mvgetch' => ['int', 'y'=>'int', 'x'=>'int'],
'ncurses_mvhline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'],
'ncurses_mvinch' => ['int', 'y'=>'int', 'x'=>'int'],
'ncurses_mvvline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'],
'ncurses_mvwaddstr' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'text'=>'string'],
'ncurses_napms' => ['int', 'milliseconds'=>'int'],
'ncurses_new_panel' => ['resource', 'window'=>'resource'],
'ncurses_newpad' => ['resource', 'rows'=>'int', 'cols'=>'int'],
'ncurses_newwin' => ['resource', 'rows'=>'int', 'cols'=>'int', 'y'=>'int', 'x'=>'int'],
'ncurses_nl' => ['bool'],
'ncurses_nocbreak' => ['bool'],
'ncurses_noecho' => ['bool'],
'ncurses_nonl' => ['bool'],
'ncurses_noqiflush' => ['void'],
'ncurses_noraw' => ['bool'],
'ncurses_pair_content' => ['int', 'pair'=>'int', 'f'=>'int', 'b'=>'int'],
'ncurses_panel_above' => ['resource', 'panel'=>'resource'],
'ncurses_panel_below' => ['resource', 'panel'=>'resource'],
'ncurses_panel_window' => ['resource', 'panel'=>'resource'],
'ncurses_pnoutrefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'],
'ncurses_prefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'],
'ncurses_putp' => ['int', 'text'=>'string'],
'ncurses_qiflush' => ['void'],
'ncurses_raw' => ['bool'],
'ncurses_refresh' => ['int', 'ch'=>'int'],
'ncurses_replace_panel' => ['int', 'panel'=>'resource', 'window'=>'resource'],
'ncurses_reset_prog_mode' => ['int'],
'ncurses_reset_shell_mode' => ['int'],
'ncurses_resetty' => ['bool'],
'ncurses_savetty' => ['bool'],
'ncurses_scr_dump' => ['int', 'filename'=>'string'],
'ncurses_scr_init' => ['int', 'filename'=>'string'],
'ncurses_scr_restore' => ['int', 'filename'=>'string'],
'ncurses_scr_set' => ['int', 'filename'=>'string'],
'ncurses_scrl' => ['int', 'count'=>'int'],
'ncurses_show_panel' => ['int', 'panel'=>'resource'],
'ncurses_slk_attr' => ['int'],
'ncurses_slk_attroff' => ['int', 'intarg'=>'int'],
'ncurses_slk_attron' => ['int', 'intarg'=>'int'],
'ncurses_slk_attrset' => ['int', 'intarg'=>'int'],
'ncurses_slk_clear' => ['bool'],
'ncurses_slk_color' => ['int', 'intarg'=>'int'],
'ncurses_slk_init' => ['bool', 'format'=>'int'],
'ncurses_slk_noutrefresh' => ['bool'],
'ncurses_slk_refresh' => ['int'],
'ncurses_slk_restore' => ['int'],
'ncurses_slk_set' => ['bool', 'labelnr'=>'int', 'label'=>'string', 'format'=>'int'],
'ncurses_slk_touch' => ['int'],
'ncurses_standend' => ['int'],
'ncurses_standout' => ['int'],
'ncurses_start_color' => ['int'],
'ncurses_termattrs' => ['bool'],
'ncurses_termname' => ['string'],
'ncurses_timeout' => ['void', 'millisec'=>'int'],
'ncurses_top_panel' => ['int', 'panel'=>'resource'],
'ncurses_typeahead' => ['int', 'fd'=>'int'],
'ncurses_ungetch' => ['int', 'keycode'=>'int'],
'ncurses_ungetmouse' => ['bool', 'mevent'=>'array'],
'ncurses_update_panels' => ['void'],
'ncurses_use_default_colors' => ['bool'],
'ncurses_use_env' => ['void', 'flag'=>'bool'],
'ncurses_use_extended_names' => ['int', 'flag'=>'bool'],
'ncurses_vidattr' => ['int', 'intarg'=>'int'],
'ncurses_vline' => ['int', 'charattr'=>'int', 'n'=>'int'],
'ncurses_waddch' => ['int', 'window'=>'resource', 'ch'=>'int'],
'ncurses_waddstr' => ['int', 'window'=>'resource', 'string'=>'string', 'n='=>'int'],
'ncurses_wattroff' => ['int', 'window'=>'resource', 'attrs'=>'int'],
'ncurses_wattron' => ['int', 'window'=>'resource', 'attrs'=>'int'],
'ncurses_wattrset' => ['int', 'window'=>'resource', 'attrs'=>'int'],
'ncurses_wborder' => ['int', 'window'=>'resource', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'],
'ncurses_wclear' => ['int', 'window'=>'resource'],
'ncurses_wcolor_set' => ['int', 'window'=>'resource', 'color_pair'=>'int'],
'ncurses_werase' => ['int', 'window'=>'resource'],
'ncurses_wgetch' => ['int', 'window'=>'resource'],
'ncurses_whline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'],
'ncurses_wmouse_trafo' => ['bool', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'],
'ncurses_wmove' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int'],
'ncurses_wnoutrefresh' => ['int', 'window'=>'resource'],
'ncurses_wrefresh' => ['int', 'window'=>'resource'],
'ncurses_wstandend' => ['int', 'window'=>'resource'],
'ncurses_wstandout' => ['int', 'window'=>'resource'],
'ncurses_wvline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'],
'net_get_interfaces' => ['array<string,array<string,mixed>>|false'],
'newrelic_add_custom_parameter' => ['bool', 'key'=>'string', 'value'=>'bool|float|int|string'],
'newrelic_add_custom_tracer' => ['bool', 'function_name'=>'string'],
'newrelic_background_job' => ['void', 'flag='=>'bool'],
'newrelic_capture_params' => ['void', 'enable='=>'bool'],
'newrelic_custom_metric' => ['bool', 'metric_name'=>'string', 'value'=>'float'],
'newrelic_disable_autorum' => ['true'],
'newrelic_end_of_transaction' => ['void'],
'newrelic_end_transaction' => ['bool', 'ignore='=>'bool'],
'newrelic_get_browser_timing_footer' => ['string', 'include_tags='=>'bool'],
'newrelic_get_browser_timing_header' => ['string', 'include_tags='=>'bool'],
'newrelic_ignore_apdex' => ['void'],
'newrelic_ignore_transaction' => ['void'],
'newrelic_name_transaction' => ['bool', 'name'=>'string'],
'newrelic_notice_error' => ['void', 'message'=>'string', 'exception='=>'Exception|Throwable'],
'newrelic_notice_error\'1' => ['void', 'unused_1'=>'string', 'message'=>'string', 'unused_2'=>'string', 'unused_3'=>'int', 'unused_4='=>''],
'newrelic_record_custom_event' => ['void', 'name'=>'string', 'attributes'=>'array'],
'newrelic_record_datastore_segment' => ['mixed', 'func'=>'callable', 'parameters'=>'array'],
'newrelic_set_appname' => ['bool', 'name'=>'string', 'license='=>'string', 'xmit='=>'bool'],
'newrelic_set_user_attributes' => ['bool', 'user'=>'string', 'account'=>'string', 'product'=>'string'],
'newrelic_start_transaction' => ['bool', 'appname'=>'string', 'license='=>'string'],
'newt_bell' => ['void'],
'newt_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
'newt_button_bar' => ['resource', 'buttons'=>'array'],
'newt_centered_window' => ['int', 'width'=>'int', 'height'=>'int', 'title='=>'string'],
'newt_checkbox' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'def_value'=>'string', 'seq='=>'string'],
'newt_checkbox_get_value' => ['string', 'checkbox'=>'resource'],
'newt_checkbox_set_flags' => ['void', 'checkbox'=>'resource', 'flags'=>'int', 'sense'=>'int'],
'newt_checkbox_set_value' => ['void', 'checkbox'=>'resource', 'value'=>'string'],
'newt_checkbox_tree' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'],
'newt_checkbox_tree_add_item' => ['void', 'checkboxtree'=>'resource', 'text'=>'string', 'data'=>'mixed', 'flags'=>'int', 'index'=>'int', '...args='=>'int'],
'newt_checkbox_tree_find_item' => ['array', 'checkboxtree'=>'resource', 'data'=>'mixed'],
'newt_checkbox_tree_get_current' => ['mixed', 'checkboxtree'=>'resource'],
'newt_checkbox_tree_get_entry_value' => ['string', 'checkboxtree'=>'resource', 'data'=>'mixed'],
'newt_checkbox_tree_get_multi_selection' => ['array', 'checkboxtree'=>'resource', 'seqnum'=>'string'],
'newt_checkbox_tree_get_selection' => ['array', 'checkboxtree'=>'resource'],
'newt_checkbox_tree_multi' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'seq'=>'string', 'flags='=>'int'],
'newt_checkbox_tree_set_current' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed'],
'newt_checkbox_tree_set_entry' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'text'=>'string'],
'newt_checkbox_tree_set_entry_value' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'value'=>'string'],
'newt_checkbox_tree_set_width' => ['void', 'checkbox_tree'=>'resource', 'width'=>'int'],
'newt_clear_key_buffer' => ['void'],
'newt_cls' => ['void'],
'newt_compact_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
'newt_component_add_callback' => ['void', 'component'=>'resource', 'func_name'=>'mixed', 'data'=>'mixed'],
'newt_component_takes_focus' => ['void', 'component'=>'resource', 'takes_focus'=>'bool'],
'newt_create_grid' => ['resource', 'cols'=>'int', 'rows'=>'int'],
'newt_cursor_off' => ['void'],
'newt_cursor_on' => ['void'],
'newt_delay' => ['void', 'microseconds'=>'int'],
'newt_draw_form' => ['void', 'form'=>'resource'],
'newt_draw_root_text' => ['void', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
'newt_entry' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'init_value='=>'string', 'flags='=>'int'],
'newt_entry_get_value' => ['string', 'entry'=>'resource'],
'newt_entry_set' => ['void', 'entry'=>'resource', 'value'=>'string', 'cursor_at_end='=>'bool'],
'newt_entry_set_filter' => ['void', 'entry'=>'resource', 'filter'=>'callable', 'data'=>'mixed'],
'newt_entry_set_flags' => ['void', 'entry'=>'resource', 'flags'=>'int', 'sense'=>'int'],
'newt_finished' => ['int'],
'newt_form' => ['resource', 'vert_bar='=>'resource', 'help='=>'string', 'flags='=>'int'],
'newt_form_add_component' => ['void', 'form'=>'resource', 'component'=>'resource'],
'newt_form_add_components' => ['void', 'form'=>'resource', 'components'=>'array'],
'newt_form_add_hot_key' => ['void', 'form'=>'resource', 'key'=>'int'],
'newt_form_destroy' => ['void', 'form'=>'resource'],
'newt_form_get_current' => ['resource', 'form'=>'resource'],
'newt_form_run' => ['void', 'form'=>'resource', 'exit_struct'=>'array'],
'newt_form_set_background' => ['void', 'from'=>'resource', 'background'=>'int'],
'newt_form_set_height' => ['void', 'form'=>'resource', 'height'=>'int'],
'newt_form_set_size' => ['void', 'form'=>'resource'],
'newt_form_set_timer' => ['void', 'form'=>'resource', 'milliseconds'=>'int'],
'newt_form_set_width' => ['void', 'form'=>'resource', 'width'=>'int'],
'newt_form_watch_fd' => ['void', 'form'=>'resource', 'stream'=>'resource', 'flags='=>'int'],
'newt_get_screen_size' => ['void', 'cols'=>'int', 'rows'=>'int'],
'newt_grid_add_components_to_form' => ['void', 'grid'=>'resource', 'form'=>'resource', 'recurse'=>'bool'],
'newt_grid_basic_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'],
'newt_grid_free' => ['void', 'grid'=>'resource', 'recurse'=>'bool'],
'newt_grid_get_size' => ['void', 'grid'=>'resource', 'width'=>'int', 'height'=>'int'],
'newt_grid_h_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
'newt_grid_h_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
'newt_grid_place' => ['void', 'grid'=>'resource', 'left'=>'int', 'top'=>'int'],
'newt_grid_set_field' => ['void', 'grid'=>'resource', 'col'=>'int', 'row'=>'int', 'type'=>'int', 'value'=>'resource', 'pad_left'=>'int', 'pad_top'=>'int', 'pad_right'=>'int', 'pad_bottom'=>'int', 'anchor'=>'int', 'flags='=>'int'],
'newt_grid_simple_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'],
'newt_grid_v_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
'newt_grid_v_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'],
'newt_grid_wrapped_window' => ['void', 'grid'=>'resource', 'title'=>'string'],
'newt_grid_wrapped_window_at' => ['void', 'grid'=>'resource', 'title'=>'string', 'left'=>'int', 'top'=>'int'],
'newt_init' => ['int'],
'newt_label' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'],
'newt_label_set_text' => ['void', 'label'=>'resource', 'text'=>'string'],
'newt_listbox' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'],
'newt_listbox_append_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed'],
'newt_listbox_clear' => ['void', 'listobx'=>'resource'],
'newt_listbox_clear_selection' => ['void', 'listbox'=>'resource'],
'newt_listbox_delete_entry' => ['void', 'listbox'=>'resource', 'key'=>'mixed'],
'newt_listbox_get_current' => ['string', 'listbox'=>'resource'],
'newt_listbox_get_selection' => ['array', 'listbox'=>'resource'],
'newt_listbox_insert_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed', 'key'=>'mixed'],
'newt_listbox_item_count' => ['int', 'listbox'=>'resource'],
'newt_listbox_select_item' => ['void', 'listbox'=>'resource', 'key'=>'mixed', 'sense'=>'int'],
'newt_listbox_set_current' => ['void', 'listbox'=>'resource', 'num'=>'int'],
'newt_listbox_set_current_by_key' => ['void', 'listbox'=>'resource', 'key'=>'mixed'],
'newt_listbox_set_data' => ['void', 'listbox'=>'resource', 'num'=>'int', 'data'=>'mixed'],
'newt_listbox_set_entry' => ['void', 'listbox'=>'resource', 'num'=>'int', 'text'=>'string'],
'newt_listbox_set_width' => ['void', 'listbox'=>'resource', 'width'=>'int'],
'newt_listitem' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_item'=>'resource', 'data'=>'mixed', 'flags='=>'int'],
'newt_listitem_get_data' => ['mixed', 'item'=>'resource'],
'newt_listitem_set' => ['void', 'item'=>'resource', 'text'=>'string'],
'newt_open_window' => ['int', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'title='=>'string'],
'newt_pop_help_line' => ['void'],
'newt_pop_window' => ['void'],
'newt_push_help_line' => ['void', 'text='=>'string'],
'newt_radio_get_current' => ['resource', 'set_member'=>'resource'],
'newt_radiobutton' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_button='=>'resource'],
'newt_redraw_help_line' => ['void'],
'newt_reflow_text' => ['string', 'text'=>'string', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'actual_width'=>'int', 'actual_height'=>'int'],
'newt_refresh' => ['void'],
'newt_resize_screen' => ['void', 'redraw='=>'bool'],
'newt_resume' => ['void'],
'newt_run_form' => ['resource', 'form'=>'resource'],
'newt_scale' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'full_value'=>'int'],
'newt_scale_set' => ['void', 'scale'=>'resource', 'amount'=>'int'],
'newt_scrollbar_set' => ['void', 'scrollbar'=>'resource', 'where'=>'int', 'total'=>'int'],
'newt_set_help_callback' => ['void', 'function'=>'mixed'],
'newt_set_suspend_callback' => ['void', 'function'=>'callable', 'data'=>'mixed'],
'newt_suspend' => ['void'],
'newt_textbox' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'flags='=>'int'],
'newt_textbox_get_num_lines' => ['int', 'textbox'=>'resource'],
'newt_textbox_reflowed' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'char', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'flags='=>'int'],
'newt_textbox_set_height' => ['void', 'textbox'=>'resource', 'height'=>'int'],
'newt_textbox_set_text' => ['void', 'textbox'=>'resource', 'text'=>'string'],
'newt_vertical_scrollbar' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'normal_colorset='=>'int', 'thumb_colorset='=>'int'],
'newt_wait_for_key' => ['void'],
'newt_win_choice' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'],
'newt_win_entries' => ['int', 'title'=>'string', 'text'=>'string', 'suggested_width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'data_width'=>'int', 'items'=>'array', 'button1'=>'string', '...args='=>'string'],
'newt_win_menu' => ['int', 'title'=>'string', 'text'=>'string', 'suggestedwidth'=>'int', 'flexdown'=>'int', 'flexup'=>'int', 'maxlistheight'=>'int', 'items'=>'array', 'listitem'=>'int', 'button1='=>'string', '...args='=>'string'],
'newt_win_message' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'],
'newt_win_messagev' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args'=>'array'],
'newt_win_ternary' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'button3_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'],
'next' => ['mixed', '&r_array'=>'array|object'],
'ngettext' => ['string', 'singular'=>'string', 'plural'=>'string', 'count'=>'int'],
'nl2br' => ['string', 'string'=>'string', 'use_xhtml='=>'bool'],
'nl_langinfo' => ['string|false', 'item'=>'int'],
'NoRewindIterator::__construct' => ['void', 'iterator'=>'Iterator'],
'NoRewindIterator::current' => ['mixed'],
'NoRewindIterator::getInnerIterator' => ['Iterator'],
'NoRewindIterator::key' => ['mixed'],
'NoRewindIterator::next' => ['void'],
'NoRewindIterator::rewind' => ['void'],
'NoRewindIterator::valid' => ['bool'],
'Normalizer::getRawDecomposition' => ['string|null', 'input'=>'string'],
'Normalizer::isNormalized' => ['bool', 'input'=>'string', 'form='=>'int'],
'Normalizer::normalize' => ['string', 'input'=>'string', 'form='=>'int'],
'normalizer_get_raw_decomposition' => ['string|null', 'string'=>'string'],
'normalizer_is_normalized' => ['bool', 'string'=>'string', 'form='=>'int'],
'normalizer_normalize' => ['string', 'string'=>'string', 'form='=>'int'],
'notes_body' => ['array', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'],
'notes_copy_db' => ['bool', 'from_database_name'=>'string', 'to_database_name'=>'string'],
'notes_create_db' => ['bool', 'database_name'=>'string'],
'notes_create_note' => ['bool', 'database_name'=>'string', 'form_name'=>'string'],
'notes_drop_db' => ['bool', 'database_name'=>'string'],
'notes_find_note' => ['int', 'database_name'=>'string', 'name'=>'string', 'type='=>'string'],
'notes_header_info' => ['object', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'],
'notes_list_msgs' => ['bool', 'db'=>'string'],
'notes_mark_read' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'],
'notes_mark_unread' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'],
'notes_nav_create' => ['bool', 'database_name'=>'string', 'name'=>'string'],
'notes_search' => ['array', 'database_name'=>'string', 'keywords'=>'string'],
'notes_unread' => ['array', 'database_name'=>'string', 'user_name'=>'string'],
'notes_version' => ['float', 'database_name'=>'string'],
'nsapi_request_headers' => ['array'],
'nsapi_response_headers' => ['array'],
'nsapi_virtual' => ['bool', 'uri'=>'string'],
'nthmac' => ['string', 'clent'=>'string', 'data'=>'string'],
'number_format' => ['string', 'num'=>'float|int', 'decimals='=>'int', 'decimal_separator='=>'?string', 'thousands_separator='=>'?string'],
'NumberFormatter::__construct' => ['void', 'locale'=>'string', 'style'=>'int', 'pattern='=>'?string'],
'NumberFormatter::create' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'?string'],
'NumberFormatter::format' => ['string|false', 'num'=>'', 'type='=>'int'],
'NumberFormatter::formatCurrency' => ['string|false', 'num'=>'float', 'currency'=>'string'],
'NumberFormatter::getAttribute' => ['int|false', 'attr'=>'int'],
'NumberFormatter::getErrorCode' => ['int'],
'NumberFormatter::getErrorMessage' => ['string'],
'NumberFormatter::getLocale' => ['string', 'type='=>'int'],
'NumberFormatter::getPattern' => ['string|false'],
'NumberFormatter::getSymbol' => ['string|false', 'attr'=>'int'],
'NumberFormatter::getTextAttribute' => ['string|false', 'attr'=>'int'],
'NumberFormatter::parse' => ['float|false', 'string'=>'string', 'type='=>'int', '&rw_position='=>'int'],
'NumberFormatter::parseCurrency' => ['float|false', 'string'=>'string', '&w_currency'=>'string', '&rw_position='=>'int'],
'NumberFormatter::setAttribute' => ['bool', 'attr'=>'int', 'value'=>''],
'NumberFormatter::setPattern' => ['bool', 'pattern'=>'string'],
'NumberFormatter::setSymbol' => ['bool', 'attr'=>'int', 'symbol'=>'string'],
'NumberFormatter::setTextAttribute' => ['bool', 'attr'=>'int', 'value'=>'string'],
'numfmt_create' => ['NumberFormatter|null', 'locale'=>'string', 'style'=>'int', 'pattern='=>'?string'],
'numfmt_format' => ['string|false', 'formatter'=>'NumberFormatter', 'num'=>'int|float', 'type='=>'int'],
'numfmt_format_currency' => ['string|false', 'formatter'=>'NumberFormatter', 'amount'=>'float', 'currency'=>'string'],
'numfmt_get_attribute' => ['int|false', 'formatter'=>'NumberFormatter', 'attribute'=>'int'],
'numfmt_get_error_code' => ['int', 'formatter'=>'NumberFormatter'],
'numfmt_get_error_message' => ['string', 'formatter'=>'NumberFormatter'],
'numfmt_get_locale' => ['string', 'formatter'=>'NumberFormatter', 'type='=>'int'],
'numfmt_get_pattern' => ['string|false', 'formatter'=>'NumberFormatter'],
'numfmt_get_symbol' => ['string|false', 'formatter'=>'NumberFormatter', 'symbol'=>'int'],
'numfmt_get_text_attribute' => ['string|false', 'formatter'=>'NumberFormatter', 'attribute'=>'int'],
'numfmt_parse' => ['float|int|false', 'formatter'=>'NumberFormatter', 'string'=>'string', 'type='=>'int', '&rw_offset='=>'int'],
'numfmt_parse_currency' => ['float|false', 'formatter'=>'NumberFormatter', 'string'=>'string', '&w_currency'=>'string', '&rw_offset='=>'int'],
'numfmt_set_attribute' => ['bool', 'formatter'=>'NumberFormatter', 'attribute'=>'int', 'value'=>'int'],
'numfmt_set_pattern' => ['bool', 'formatter'=>'NumberFormatter', 'pattern'=>'string'],
'numfmt_set_symbol' => ['bool', 'formatter'=>'NumberFormatter', 'symbol'=>'int', 'value'=>'string'],
'numfmt_set_text_attribute' => ['bool', 'formatter'=>'NumberFormatter', 'attribute'=>'int', 'value'=>'string'],
'OAuth::__construct' => ['void', 'consumer_key'=>'string', 'consumer_secret'=>'string', 'signature_method='=>'string', 'auth_type='=>'int'],
'OAuth::disableDebug' => ['bool'],
'OAuth::disableRedirects' => ['bool'],
'OAuth::disableSSLChecks' => ['bool'],
'OAuth::enableDebug' => ['bool'],
'OAuth::enableRedirects' => ['bool'],
'OAuth::enableSSLChecks' => ['bool'],
'OAuth::fetch' => ['mixed', 'protected_resource_url'=>'string', 'extra_parameters='=>'array', 'http_method='=>'string', 'http_headers='=>'array'],
'OAuth::generateSignature' => ['string', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'],
'OAuth::getAccessToken' => ['array|false', 'access_token_url'=>'string', 'auth_session_handle='=>'string', 'verifier_token='=>'string', 'http_method='=>'string'],
'OAuth::getCAPath' => ['array'],
'OAuth::getLastResponse' => ['string'],
'OAuth::getLastResponseHeaders' => ['string|false'],
'OAuth::getLastResponseInfo' => ['array'],
'OAuth::getRequestHeader' => ['string|false', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'],
'OAuth::getRequestToken' => ['array|false', 'request_token_url'=>'string', 'callback_url='=>'string', 'http_method='=>'string'],
'OAuth::setAuthType' => ['bool', 'auth_type'=>'int'],
'OAuth::setCAPath' => ['mixed', 'ca_path='=>'string', 'ca_info='=>'string'],
'OAuth::setNonce' => ['mixed', 'nonce'=>'string'],
'OAuth::setRequestEngine' => ['void', 'reqengine'=>'int'],
'OAuth::setRSACertificate' => ['mixed', 'cert'=>'string'],
'OAuth::setSSLChecks' => ['bool', 'sslcheck'=>'int'],
'OAuth::setTimeout' => ['void', 'timeout'=>'int'],
'OAuth::setTimestamp' => ['mixed', 'timestamp'=>'string'],
'OAuth::setToken' => ['bool', 'token'=>'string', 'token_secret'=>'string'],
'OAuth::setVersion' => ['bool', 'version'=>'string'],
'oauth_get_sbs' => ['string', 'http_method'=>'string', 'uri'=>'string', 'request_parameters='=>'array'],
'oauth_urlencode' => ['string', 'uri'=>'string'],
'OAuthProvider::__construct' => ['void', 'params_array='=>'array'],
'OAuthProvider::addRequiredParameter' => ['bool', 'req_params'=>'string'],
'OAuthProvider::callconsumerHandler' => ['void'],
'OAuthProvider::callTimestampNonceHandler' => ['void'],
'OAuthProvider::calltokenHandler' => ['void'],
'OAuthProvider::checkOAuthRequest' => ['void', 'uri='=>'string', 'method='=>'string'],
'OAuthProvider::consumerHandler' => ['void', 'callback_function'=>'callable'],
'OAuthProvider::generateToken' => ['string', 'size'=>'int', 'strong='=>'bool'],
'OAuthProvider::is2LeggedEndpoint' => ['void', 'params_array'=>'mixed'],
'OAuthProvider::isRequestTokenEndpoint' => ['void', 'will_issue_request_token'=>'bool'],
'OAuthProvider::removeRequiredParameter' => ['bool', 'req_params'=>'string'],
'OAuthProvider::reportProblem' => ['string', 'oauthexception'=>'string', 'send_headers='=>'bool'],
'OAuthProvider::setParam' => ['bool', 'param_key'=>'string', 'param_val='=>'mixed'],
'OAuthProvider::setRequestTokenPath' => ['bool', 'path'=>'string'],
'OAuthProvider::timestampNonceHandler' => ['void', 'callback_function'=>'callable'],
'OAuthProvider::tokenHandler' => ['void', 'callback_function'=>'callable'],
'ob_clean' => ['bool'],
'ob_deflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'],
'ob_end_clean' => ['bool'],
'ob_end_flush' => ['bool'],
'ob_etaghandler' => ['string', 'data'=>'string', 'mode'=>'int'],
'ob_flush' => ['bool'],
'ob_get_clean' => ['string|false'],
'ob_get_contents' => ['string|false'],
'ob_get_flush' => ['string|false'],
'ob_get_length' => ['int|false'],
'ob_get_level' => ['int'],
'ob_get_status' => ['array', 'full_status='=>'bool'],
'ob_gzhandler' => ['string|false', 'data'=>'string', 'flags'=>'int'],
'ob_iconv_handler' => ['string', 'contents'=>'string', 'status'=>'int'],
'ob_implicit_flush' => ['void', 'enable='=>'bool'],
'ob_inflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'],
'ob_list_handlers' => ['list<string>'],
'ob_start' => ['bool', 'callback='=>'string|array|?callable', 'chunk_size='=>'int', 'flags='=>'int'],
'ob_tidyhandler' => ['string', 'input'=>'string', 'mode='=>'int'],
'oci_bind_array_by_name' => ['bool', 'statement'=>'resource', 'param'=>'string', '&rw_var'=>'array', 'max_array_length'=>'int', 'max_item_length='=>'int', 'type='=>'int'],
'oci_bind_by_name' => ['bool', 'statement'=>'resource', 'param'=>'string', '&rw_var'=>'mixed', 'max_length='=>'int', 'type='=>'int'],
'oci_cancel' => ['bool', 'statement'=>'resource'],
'oci_client_version' => ['string'],
'oci_close' => ['bool', 'connection'=>'resource'],
'OCICollection::append' => ['bool', 'value'=>'mixed'],
'OCICollection::assign' => ['bool', 'from'=>'OCI_Collection'],
'OCICollection::assignElem' => ['bool', 'index'=>'int', 'value'=>'mixed'],
'OCICollection::free' => ['bool'],
'OCICollection::getElem' => ['mixed', 'index'=>'int'],
'OCICollection::max' => ['int|false'],
'OCICollection::size' => ['int|false'],
'OCICollection::trim' => ['bool', 'num'=>'int'],
'oci_collection_append' => ['bool', 'collection'=>'string'],
'oci_collection_assign' => ['bool', 'to'=>'object'],
'oci_collection_element_assign' => ['bool', 'collection'=>'int', 'index'=>'string'],
'oci_collection_element_get' => ['string', 'collection'=>'int'],
'oci_collection_max' => ['int'],
'oci_collection_size' => ['int'],
'oci_collection_trim' => ['bool', 'collection'=>'int'],
'oci_commit' => ['bool', 'connection'=>'resource'],
'oci_connect' => ['resource|false', 'username'=>'string', 'password'=>'string', 'connection_string='=>'string', 'encoding='=>'string', 'session_mode='=>'int'],
'oci_define_by_name' => ['bool', 'statement'=>'resource', 'column'=>'string', '&w_var'=>'mixed', 'type='=>'int'],
'oci_error' => ['array|false', 'connection_or_statement='=>'resource'],
'oci_execute' => ['bool', 'statement'=>'resource', 'mode='=>'int'],
'oci_fetch' => ['bool', 'statement'=>'resource'],
'oci_fetch_all' => ['int|false', 'statement'=>'resource', '&w_output'=>'array', 'offset='=>'int', 'limit='=>'int', 'flags='=>'int'],
'oci_fetch_array' => ['array|false', 'statement'=>'resource', 'mode='=>'int'],
'oci_fetch_assoc' => ['array|false', 'statement'=>'resource'],
'oci_fetch_object' => ['object|false', 'statement'=>'resource'],
'oci_fetch_row' => ['array|false', 'statement'=>'resource'],
'oci_field_is_null' => ['bool', 'statement'=>'resource', 'column'=>'mixed'],
'oci_field_name' => ['string|false', 'statement'=>'resource', 'column'=>'mixed'],
'oci_field_precision' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
'oci_field_scale' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
'oci_field_size' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
'oci_field_type' => ['mixed|false', 'statement'=>'resource', 'column'=>'mixed'],
'oci_field_type_raw' => ['int|false', 'statement'=>'resource', 'column'=>'mixed'],
'oci_free_collection' => ['bool'],
'oci_free_cursor' => ['bool', 'statement'=>'resource'],
'oci_free_descriptor' => ['bool'],
'oci_free_statement' => ['bool', 'statement'=>'resource'],
'oci_get_implicit' => ['bool', 'stmt'=>''],
'oci_get_implicit_resultset' => ['resource|false', 'statement'=>'resource'],
'oci_internal_debug' => ['void', 'onoff'=>'bool'],
'OCILob::append' => ['bool', 'lob_from'=>'OCILob'],
'OCILob::close' => ['bool'],
'OCILob::eof' => ['bool'],
'OCILob::erase' => ['int|false', 'offset='=>'int', 'length='=>'int'],
'OCILob::export' => ['bool', 'filename'=>'string', 'start='=>'int', 'length='=>'int'],
'OCILob::flush' => ['bool', 'flag='=>'int'],
'OCILob::free' => ['bool'],
'OCILob::getbuffering' => ['bool'],
'OCILob::import' => ['bool', 'filename'=>'string'],
'OCILob::load' => ['string|false'],
'OCILob::read' => ['string|false', 'length'=>'int'],
'OCILob::rewind' => ['bool'],
'OCILob::save' => ['bool', 'data'=>'string', 'offset='=>'int'],
'OCILob::savefile' => ['bool', 'filename'=>''],
'OCILob::seek' => ['bool', 'offset'=>'int', 'whence='=>'int'],
'OCILob::setbuffering' => ['bool', 'on_off'=>'bool'],
'OCILob::size' => ['int|false'],
'OCILob::tell' => ['int|false'],
'OCILob::truncate' => ['bool', 'length='=>'int'],
'OCILob::write' => ['int|false', 'data'=>'string', 'length='=>'int'],
'OCILob::writeTemporary' => ['bool', 'data'=>'string', 'lob_type='=>'int'],
'OCILob::writetofile' => ['bool', 'filename'=>'', 'start'=>'', 'length'=>''],
'oci_lob_append' => ['bool', 'to'=>'object'],
'oci_lob_close' => ['bool'],
'oci_lob_copy' => ['bool', 'to'=>'OCILob', 'from'=>'OCILob', 'length='=>'int'],
'oci_lob_eof' => ['bool'],
'oci_lob_erase' => ['int', 'lob'=>'int', 'offset'=>'int'],
'oci_lob_export' => ['bool', 'lob'=>'string', 'filename'=>'int', 'offset'=>'int'],
'oci_lob_flush' => ['bool', 'lob'=>'int'],
'oci_lob_import' => ['bool', 'lob'=>'string'],
'oci_lob_is_equal' => ['bool', 'lob1'=>'OCILob', 'lob2'=>'OCILob'],
'oci_lob_load' => ['string'],
'oci_lob_read' => ['string', 'lob'=>'int'],
'oci_lob_rewind' => ['bool'],
'oci_lob_save' => ['bool', 'lob'=>'string', 'data'=>'int'],
'oci_lob_seek' => ['bool', 'lob'=>'int', 'offset'=>'int'],
'oci_lob_size' => ['int'],
'oci_lob_tell' => ['int'],
'oci_lob_truncate' => ['bool', 'lob'=>'int'],
'oci_lob_write' => ['int', 'lob'=>'string', 'data'=>'int'],
'oci_lob_write_temporary' => ['bool', 'value'=>'string', 'lob_type'=>'int'],
'oci_new_collection' => ['OCICollection|false', 'connection'=>'resource', 'type_name'=>'string', 'schema='=>'string'],
'oci_new_connect' => ['resource|false', 'username'=>'string', 'password'=>'string', 'connection_string='=>'string', 'encoding='=>'string', 'session_mode='=>'int'],
'oci_new_cursor' => ['resource|false', 'connection'=>'resource'],
'oci_new_descriptor' => ['OCILob|false', 'connection'=>'resource', 'type='=>'int'],
'oci_num_fields' => ['int|false', 'statement'=>'resource'],
'oci_num_rows' => ['int|false', 'statement'=>'resource'],
'oci_parse' => ['resource|false', 'connection'=>'resource', 'sql'=>'string'],
'oci_password_change' => ['bool', 'connection'=>'resource', 'username'=>'string', 'old_password'=>'string', 'new_password'=>'string'],
'oci_pconnect' => ['resource|false', 'username'=>'string', 'password'=>'string', 'connection_string='=>'string', 'encoding='=>'string', 'session_mode='=>'int'],
'oci_register_taf_callback' => ['bool', 'connection'=>'resource', 'callback='=>'callable'],
'oci_result' => ['mixed|false', 'statement'=>'resource', 'column'=>'mixed'],
'oci_rollback' => ['bool', 'connection'=>'resource'],
'oci_server_version' => ['string|false', 'connection'=>'resource'],
'oci_set_action' => ['bool', 'connection'=>'resource', 'action'=>'string'],
'oci_set_call_timeout' => ['bool', 'connection'=>'resource', 'timeout'=>'int'],
'oci_set_client_identifier' => ['bool', 'connection'=>'resource', 'client_id'=>'string'],
'oci_set_client_info' => ['bool', 'connection'=>'resource', 'client_info'=>'string'],
'oci_set_db_operation' => ['bool', 'connection'=>'resource', 'action'=>'string'],
'oci_set_edition' => ['bool', 'edition'=>'string'],
'oci_set_module_name' => ['bool', 'connection'=>'resource', 'name'=>'string'],
'oci_set_prefetch' => ['bool', 'statement'=>'resource', 'rows'=>'int'],
'oci_statement_type' => ['string|false', 'statement'=>'resource'],
'oci_unregister_taf_callback' => ['bool', 'connection'=>'resource'],
'ocifetchinto' => ['int|bool', 'statement'=>'resource', '&w_result'=>'array', 'mode='=>'int'],
'ocigetbufferinglob' => ['bool'],
'ocisetbufferinglob' => ['bool', 'lob'=>'bool'],
'octdec' => ['int|float', 'octal_string'=>'string'],
'odbc_autocommit' => ['int|bool', 'odbc'=>'resource', 'enable='=>'bool'],
'odbc_binmode' => ['bool', 'statement'=>'resource', 'mode'=>'int'],
'odbc_close' => ['void', 'odbc'=>'resource'],
'odbc_close_all' => ['void'],
'odbc_columnprivileges' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string', 'column'=>'string'],
'odbc_columns' => ['resource|false', 'odbc'=>'resource', 'catalog='=>'?string', 'schema='=>'?string', 'table='=>'?string', 'column='=>'?string'],
'odbc_commit' => ['bool', 'odbc'=>'resource'],
'odbc_connect' => ['resource|false', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'],
'odbc_cursor' => ['string', 'statement'=>'resource'],
'odbc_data_source' => ['array|false', 'odbc'=>'resource', 'fetch_type'=>'int'],
'odbc_do' => ['resource', 'odbc'=>'resource', 'query'=>'string'],
'odbc_error' => ['string', 'odbc='=>'resource'],
'odbc_errormsg' => ['string', 'odbc='=>'resource'],
'odbc_exec' => ['resource', 'odbc'=>'resource', 'query'=>'string'],
'odbc_execute' => ['bool', 'statement'=>'resource', 'params='=>'array'],
'odbc_fetch_array' => ['array|false', 'statement'=>'resource', 'row='=>'int'],
'odbc_fetch_into' => ['int', 'statement'=>'resource', '&w_array'=>'array', 'row='=>'int'],
'odbc_fetch_object' => ['stdClass|false', 'statement'=>'resource', 'row='=>'int'],
'odbc_fetch_row' => ['bool', 'statement'=>'resource', 'row='=>'?int'],
'odbc_field_len' => ['int|false', 'statement'=>'resource', 'field'=>'int'],
'odbc_field_name' => ['string|false', 'statement'=>'resource', 'field'=>'int'],
'odbc_field_num' => ['int|false', 'statement'=>'resource', 'field'=>'string'],
'odbc_field_precision' => ['int', 'statement'=>'resource', 'field'=>'int'],
'odbc_field_scale' => ['int|false', 'statement'=>'resource', 'field'=>'int'],
'odbc_field_type' => ['string|false', 'statement'=>'resource', 'field'=>'int'],
'odbc_foreignkeys' => ['resource|false', 'odbc'=>'resource', 'pk_catalog'=>'?string', 'pk_schema'=>'string', 'pk_table'=>'string', 'fk_catalog'=>'string', 'fk_schema'=>'string', 'fk_table'=>'string'],
'odbc_free_result' => ['bool', 'statement'=>'resource'],
'odbc_gettypeinfo' => ['resource', 'odbc'=>'resource', 'data_type='=>'int'],
'odbc_longreadlen' => ['bool', 'statement'=>'resource', 'length'=>'int'],
'odbc_next_result' => ['bool', 'statement'=>'resource'],
'odbc_num_fields' => ['int', 'statement'=>'resource'],
'odbc_num_rows' => ['int', 'statement'=>'resource'],
'odbc_pconnect' => ['resource|false', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'],
'odbc_prepare' => ['resource|false', 'odbc'=>'resource', 'query'=>'string'],
'odbc_primarykeys' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string'],
'odbc_procedurecolumns' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'string', 'schema'=>'string', 'procedure'=>'string', 'column'=>'string'],
'odbc_procedures' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'string', 'schema'=>'string', 'procedure'=>'string'],
'odbc_result' => ['mixed|false', 'statement'=>'resource', 'field'=>'mixed'],
'odbc_result_all' => ['int|false', 'statement'=>'resource', 'format='=>'string'],
'odbc_rollback' => ['bool', 'odbc'=>'resource'],
'odbc_setoption' => ['bool', 'odbc'=>'resource', 'which'=>'int', 'option'=>'int', 'value'=>'int'],
'odbc_specialcolumns' => ['resource|false', 'odbc'=>'resource', 'type'=>'int', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string', 'scope'=>'int', 'nullable'=>'int'],
'odbc_statistics' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string', 'unique'=>'int', 'accuracy'=>'int'],
'odbc_tableprivileges' => ['resource|false', 'odbc'=>'resource', 'catalog'=>'?string', 'schema'=>'string', 'table'=>'string'],
'odbc_tables' => ['resource|false', 'odbc'=>'resource', 'catalog='=>'?string', 'schema='=>'?string', 'table='=>'?string', 'types='=>'?string'],
'opcache_compile_file' => ['bool', 'filename'=>'string'],
'opcache_get_configuration' => ['array'],
'opcache_get_status' => ['array|false', 'include_scripts='=>'bool'],
'opcache_invalidate' => ['bool', 'filename'=>'string', 'force='=>'bool'],
'opcache_is_script_cached' => ['bool', 'filename'=>'string'],
'opcache_reset' => ['bool'],
'openal_buffer_create' => ['resource'],
'openal_buffer_data' => ['bool', 'buffer'=>'resource', 'format'=>'int', 'data'=>'string', 'freq'=>'int'],
'openal_buffer_destroy' => ['bool', 'buffer'=>'resource'],
'openal_buffer_get' => ['int', 'buffer'=>'resource', 'property'=>'int'],
'openal_buffer_loadwav' => ['bool', 'buffer'=>'resource', 'wavfile'=>'string'],
'openal_context_create' => ['resource', 'device'=>'resource'],
'openal_context_current' => ['bool', 'context'=>'resource'],
'openal_context_destroy' => ['bool', 'context'=>'resource'],
'openal_context_process' => ['bool', 'context'=>'resource'],
'openal_context_suspend' => ['bool', 'context'=>'resource'],
'openal_device_close' => ['bool', 'device'=>'resource'],
'openal_device_open' => ['resource|false', 'device_desc='=>'string'],
'openal_listener_get' => ['mixed', 'property'=>'int'],
'openal_listener_set' => ['bool', 'property'=>'int', 'setting'=>'mixed'],
'openal_source_create' => ['resource'],
'openal_source_destroy' => ['bool', 'source'=>'resource'],
'openal_source_get' => ['mixed', 'source'=>'resource', 'property'=>'int'],
'openal_source_pause' => ['bool', 'source'=>'resource'],
'openal_source_play' => ['bool', 'source'=>'resource'],
'openal_source_rewind' => ['bool', 'source'=>'resource'],
'openal_source_set' => ['bool', 'source'=>'resource', 'property'=>'int', 'setting'=>'mixed'],
'openal_source_stop' => ['bool', 'source'=>'resource'],
'openal_stream' => ['resource', 'source'=>'resource', 'format'=>'int', 'rate'=>'int'],
'opendir' => ['resource|false', 'directory'=>'string', 'context='=>'resource'],
'openlog' => ['bool', 'prefix'=>'string', 'flags'=>'int', 'facility'=>'int'],
'openssl_cipher_iv_length' => ['int|false', 'cipher_algo'=>'string'],
'openssl_cipher_key_length' => ['positive-int|false', 'cipher_algo'=>'non-empty-string'],
'openssl_csr_export' => ['bool', 'csr'=>'OpenSSLCertificateSigningRequest|string', '&w_output'=>'string', 'no_text='=>'bool'],
'openssl_csr_export_to_file' => ['bool', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'output_filename'=>'string', 'no_text='=>'bool'],
'openssl_csr_get_public_key' => ['OpenSSLAsymmetricKey|false', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'short_names='=>'bool'],
'openssl_csr_get_subject' => ['array|false', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'short_names='=>'bool'],
'openssl_csr_new' => ['OpenSSLCertificateSigningRequest|false', 'distinguished_names'=>'array', '&w_private_key'=>'OpenSSLAsymmetricKey', 'options='=>'array|null', 'extra_attributes='=>'array|null'],
'openssl_csr_sign' => ['OpenSSLCertificate|false', 'csr'=>'OpenSSLCertificateSigningRequest|string', 'ca_certificate'=>'OpenSSLCertificate|string|null', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'days'=>'int', 'options='=>'array|null', 'serial='=>'int'],
'openssl_decrypt' => ['string|false', 'data'=>'string', 'cipher_algo'=>'string', 'passphrase'=>'string', 'options='=>'int', 'iv='=>'string', 'tag='=>'?string', 'aad='=>'string'],
'openssl_dh_compute_key' => ['string|false', 'public_key'=>'string', 'private_key'=>'OpenSSLAsymmetricKey'],
'openssl_digest' => ['string|false', 'data'=>'string', 'digest_algo'=>'string', 'binary='=>'bool'],
'openssl_encrypt' => ['string|false', 'data'=>'string', 'cipher_algo'=>'string', 'passphrase'=>'string', 'options='=>'int', 'iv='=>'string', '&w_tag='=>'string', 'aad='=>'string', 'tag_length='=>'int'],
'openssl_error_string' => ['string|false'],
'openssl_free_key' => ['void', 'key'=>'OpenSSLAsymmetricKey'],
'openssl_get_cert_locations' => ['array'],
'openssl_get_cipher_methods' => ['array', 'aliases='=>'bool'],
'openssl_get_curve_names' => ['list<string>'],
'openssl_get_md_methods' => ['array', 'aliases='=>'bool'],
'openssl_get_privatekey' => ['OpenSSLAsymmetricKey|false', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'passphrase='=>'?string'],
'openssl_get_publickey' => ['OpenSSLAsymmetricKey|false', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string'],
'openssl_open' => ['bool', 'data'=>'string', '&w_output'=>'string', 'encrypted_key'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'cipher_algo'=>'string', 'iv='=>'string|null'],
'openssl_pbkdf2' => ['string|false', 'password'=>'string', 'salt'=>'string', 'key_length'=>'int', 'iterations'=>'int', 'digest_algo='=>'string'],
'openssl_pkcs12_export' => ['bool', 'certificate'=>'OpenSSLCertificate|string', '&w_output'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'passphrase'=>'string', 'options='=>'array'],
'openssl_pkcs12_export_to_file' => ['bool', 'certificate'=>'OpenSSLCertificate|string', 'output_filename'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'passphrase'=>'string', 'options='=>'array'],
'openssl_pkcs12_read' => ['bool', 'pkcs12'=>'string', '&w_certificates'=>'array', 'passphrase'=>'string'],
'openssl_pkcs7_decrypt' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'OpenSSLCertificate|string', 'private_key='=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string|null'],
'openssl_pkcs7_encrypt' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'OpenSSLCertificate|list<OpenSSLCertificate|string>|string', 'headers'=>'array|null', 'flags='=>'int', 'cipher_algo='=>'int'],
'openssl_pkcs7_read' => ['bool', 'input_filename'=>'string', '&w_certificates'=>'array'],
'openssl_pkcs7_sign' => ['bool', 'input_filename'=>'string', 'output_filename'=>'string', 'certificate'=>'OpenSSLCertificate|string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'headers'=>'array|null', 'flags='=>'int', 'untrusted_certificates_filename='=>'string|null'],
'openssl_pkcs7_verify' => ['bool|int', 'input_filename'=>'string', 'flags'=>'int', 'signers_certificates_filename='=>'?string', 'ca_info='=>'array', 'untrusted_certificates_filename='=>'?string', 'content='=>'?string', 'output_filename='=>'?string'],
'openssl_pkey_derive' => ['string|false', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'key_length='=>'int'],
'openssl_pkey_export' => ['bool', 'key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', '&w_output'=>'string', 'passphrase='=>'string|null', 'options='=>'array|null'],
'openssl_pkey_export_to_file' => ['bool', 'key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'output_filename'=>'string', 'passphrase='=>'string|null', 'options='=>'array|null'],
'openssl_pkey_free' => ['void', 'key'=>'OpenSSLAsymmetricKey'],
'openssl_pkey_get_details' => ['array|false', 'key'=>'OpenSSLAsymmetricKey'],
'openssl_pkey_get_private' => ['OpenSSLAsymmetricKey|false', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array|string', 'passphrase='=>'?string'],
'openssl_pkey_get_public' => ['OpenSSLAsymmetricKey|false', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string'],
'openssl_pkey_new' => ['OpenSSLAsymmetricKey|false', 'options='=>'array|null'],
'openssl_private_decrypt' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
'openssl_private_encrypt' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
'openssl_public_decrypt' => ['bool', 'data'=>'string', '&w_decrypted_data'=>'string', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
'openssl_public_encrypt' => ['bool', 'data'=>'string', '&w_encrypted_data'=>'string', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'padding='=>'int'],
'openssl_random_pseudo_bytes' => ['string', 'length'=>'int', '&w_strong_result='=>'bool'],
'openssl_seal' => ['int|false', 'data'=>'string', '&w_sealed_data'=>'string', '&w_encrypted_keys'=>'array', 'public_key'=>'list<OpenSSLAsymmetricKey>', 'cipher_algo'=>'string', '&rw_iv='=>'string'],
'openssl_sign' => ['bool', 'data'=>'string', '&w_signature'=>'string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'algorithm='=>'int|string'],
'openssl_spki_export' => ['string|false', 'spki'=>'string'],
'openssl_spki_export_challenge' => ['string|false', 'spki'=>'string'],
'openssl_spki_new' => ['string|false', 'private_key'=>'OpenSSLAsymmetricKey', 'challenge'=>'string', 'digest_algo='=>'int'],
'openssl_spki_verify' => ['bool', 'spki'=>'string'],
'openssl_verify' => ['-1|0|1|false', 'data'=>'string', 'signature'=>'string', 'public_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string', 'algorithm='=>'int|string'],
'openssl_x509_check_private_key' => ['bool', 'certificate'=>'OpenSSLCertificate|string', 'private_key'=>'OpenSSLAsymmetricKey|OpenSSLCertificate|array{OpenSSLAsymmetricKey|OpenSSLCertificate|string, string}|string'],
'openssl_x509_checkpurpose' => ['bool|int', 'certificate'=>'OpenSSLCertificate|string', 'purpose'=>'int', 'ca_info='=>'array', 'untrusted_certificates_file='=>'string|null'],
'openssl_x509_export' => ['bool', 'certificate'=>'OpenSSLCertificate|string', '&w_output'=>'string', 'no_text='=>'bool'],
'openssl_x509_export_to_file' => ['bool', 'certificate'=>'OpenSSLCertificate|string', 'output_filename'=>'string', 'no_text='=>'bool'],
'openssl_x509_fingerprint' => ['string|false', 'certificate'=>'OpenSSLCertificate|string', 'digest_algo='=>'string', 'binary='=>'bool'],
'openssl_x509_free' => ['void', 'certificate'=>'OpenSSLCertificate'],
'openssl_x509_parse' => ['array|false', 'certificate'=>'OpenSSLCertificate|string', 'short_names='=>'bool'],
'openssl_x509_read' => ['OpenSSLCertificate|false', 'certificate'=>'OpenSSLCertificate|string'],
'openssl_x509_verify' => ['int', 'certificate'=>'string|OpenSSLCertificate', 'public_key'=>'string|OpenSSLCertificate|OpenSSLAsymmetricKey|array'],
'ord' => ['int', 'character'=>'string'],
'OuterIterator::current' => ['mixed'],
'OuterIterator::getInnerIterator' => ['Iterator'],
'OuterIterator::key' => ['int|string'],
'OuterIterator::next' => ['void'],
'OuterIterator::rewind' => ['void'],
'OuterIterator::valid' => ['bool'],
'OutOfBoundsException::__clone' => ['void'],
'OutOfBoundsException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'OutOfBoundsException::__toString' => ['string'],
'OutOfBoundsException::getCode' => ['int'],
'OutOfBoundsException::getFile' => ['string'],
'OutOfBoundsException::getLine' => ['int'],
'OutOfBoundsException::getMessage' => ['string'],
'OutOfBoundsException::getPrevious' => ['?Throwable'],
'OutOfBoundsException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'OutOfBoundsException::getTraceAsString' => ['string'],
'OutOfRangeException::__clone' => ['void'],
'OutOfRangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'OutOfRangeException::__toString' => ['string'],
'OutOfRangeException::getCode' => ['int'],
'OutOfRangeException::getFile' => ['string'],
'OutOfRangeException::getLine' => ['int'],
'OutOfRangeException::getMessage' => ['string'],
'OutOfRangeException::getPrevious' => ['?Throwable'],
'OutOfRangeException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'OutOfRangeException::getTraceAsString' => ['string'],
'output_add_rewrite_var' => ['bool', 'name'=>'string', 'value'=>'string'],
'output_cache_disable' => ['void'],
'output_cache_disable_compression' => ['void'],
'output_cache_exists' => ['bool', 'key'=>'string', 'lifetime'=>'int'],
'output_cache_fetch' => ['string', 'key'=>'string', 'function'=>'', 'lifetime'=>'int'],
'output_cache_get' => ['mixed|false', 'key'=>'string', 'lifetime'=>'int'],
'output_cache_output' => ['string', 'key'=>'string', 'function'=>'', 'lifetime'=>'int'],
'output_cache_put' => ['bool', 'key'=>'string', 'data'=>'mixed'],
'output_cache_remove' => ['bool', 'filename'=>''],
'output_cache_remove_key' => ['bool', 'key'=>'string'],
'output_cache_remove_url' => ['bool', 'url'=>'string'],
'output_cache_stop' => ['void'],
'output_reset_rewrite_vars' => ['bool'],
'outputformatObj::getOption' => ['string', 'property_name'=>'string'],
'outputformatObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'outputformatObj::setOption' => ['void', 'property_name'=>'string', 'new_value'=>'string'],
'outputformatObj::validate' => ['int'],
'OverflowException::__clone' => ['void'],
'OverflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'OverflowException::__toString' => ['string'],
'OverflowException::getCode' => ['int'],
'OverflowException::getFile' => ['string'],
'OverflowException::getLine' => ['int'],
'OverflowException::getMessage' => ['string'],
'OverflowException::getPrevious' => ['?Throwable'],
'OverflowException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'OverflowException::getTraceAsString' => ['string'],
'overload' => ['', 'class_name'=>'string'],
'override_function' => ['bool', 'function_name'=>'string', 'function_args'=>'string', 'function_code'=>'string'],
'OwsrequestObj::__construct' => ['void'],
'OwsrequestObj::addParameter' => ['int', 'name'=>'string', 'value'=>'string'],
'OwsrequestObj::getName' => ['string', 'index'=>'int'],
'OwsrequestObj::getValue' => ['string', 'index'=>'int'],
'OwsrequestObj::getValueByName' => ['string', 'name'=>'string'],
'OwsrequestObj::loadParams' => ['int'],
'OwsrequestObj::setParameter' => ['int', 'name'=>'string', 'value'=>'string'],
'pack' => ['string', 'format'=>'string', '...values='=>'mixed'],
'parallel\Future::done' => ['bool'],
'parallel\Future::select' => ['mixed', '&resolving'=>'parallel\Future[]', '&w_resolved'=>'parallel\Future[]', '&w_errored'=>'parallel\Future[]', '&w_timedout='=>'parallel\Future[]', 'timeout='=>'int'],
'parallel\Future::value' => ['mixed', 'timeout='=>'int'],
'parallel\Runtime::__construct' => ['void', 'arg'=>'string|array'],
'parallel\Runtime::__construct\'1' => ['void', 'bootstrap'=>'string', 'configuration'=>'array<string,mixed>'],
'parallel\Runtime::close' => ['void'],
'parallel\Runtime::kill' => ['void'],
'parallel\Runtime::run' => ['?parallel\Future', 'closure'=>'Closure', 'args='=>'array'],
'ParentIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator'],
'ParentIterator::accept' => ['bool'],
'ParentIterator::getChildren' => ['?ParentIterator'],
'ParentIterator::hasChildren' => ['bool'],
'ParentIterator::next' => ['void'],
'ParentIterator::rewind' => ['void'],
'ParentIterator::valid' => ['bool'],
'Parle\Lexer::advance' => ['void'],
'Parle\Lexer::build' => ['void'],
'Parle\Lexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'],
'Parle\Lexer::consume' => ['void', 'data'=>'string'],
'Parle\Lexer::dump' => ['void'],
'Parle\Lexer::getToken' => ['Parle\Token'],
'Parle\Lexer::insertMacro' => ['void', 'name'=>'string', 'regex'=>'string'],
'Parle\Lexer::push' => ['void', 'regex'=>'string', 'id'=>'int'],
'Parle\Lexer::reset' => ['void', 'pos'=>'int'],
'Parle\Parser::advance' => ['void'],
'Parle\Parser::build' => ['void'],
'Parle\Parser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
'Parle\Parser::dump' => ['void'],
'Parle\Parser::errorInfo' => ['Parle\ErrorInfo'],
'Parle\Parser::left' => ['void', 'token'=>'string'],
'Parle\Parser::nonassoc' => ['void', 'token'=>'string'],
'Parle\Parser::precedence' => ['void', 'token'=>'string'],
'Parle\Parser::push' => ['int', 'name'=>'string', 'rule'=>'string'],
'Parle\Parser::reset' => ['void', 'tokenId'=>'int'],
'Parle\Parser::right' => ['void', 'token'=>'string'],
'Parle\Parser::sigil' => ['string', 'idx'=>'array'],
'Parle\Parser::token' => ['void', 'token'=>'string'],
'Parle\Parser::tokenId' => ['int', 'token'=>'string'],
'Parle\Parser::trace' => ['string'],
'Parle\Parser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
'Parle\RLexer::advance' => ['void'],
'Parle\RLexer::build' => ['void'],
'Parle\RLexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'],
'Parle\RLexer::consume' => ['void', 'data'=>'string'],
'Parle\RLexer::dump' => ['void'],
'Parle\RLexer::getToken' => ['Parle\Token'],
'parle\rlexer::insertMacro' => ['void', 'name'=>'string', 'regex'=>'string'],
'Parle\RLexer::push' => ['void', 'state'=>'string', 'regex'=>'string', 'newState'=>'string'],
'Parle\RLexer::pushState' => ['int', 'state'=>'string'],
'Parle\RLexer::reset' => ['void', 'pos'=>'int'],
'Parle\RParser::advance' => ['void'],
'Parle\RParser::build' => ['void'],
'Parle\RParser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
'Parle\RParser::dump' => ['void'],
'Parle\RParser::errorInfo' => ['Parle\ErrorInfo'],
'Parle\RParser::left' => ['void', 'token'=>'string'],
'Parle\RParser::nonassoc' => ['void', 'token'=>'string'],
'Parle\RParser::precedence' => ['void', 'token'=>'string'],
'Parle\RParser::push' => ['int', 'name'=>'string', 'rule'=>'string'],
'Parle\RParser::reset' => ['void', 'tokenId'=>'int'],
'Parle\RParser::right' => ['void', 'token'=>'string'],
'Parle\RParser::sigil' => ['string', 'idx'=>'array'],
'Parle\RParser::token' => ['void', 'token'=>'string'],
'Parle\RParser::tokenId' => ['int', 'token'=>'string'],
'Parle\RParser::trace' => ['string'],
'Parle\RParser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'],
'Parle\Stack::pop' => ['void'],
'Parle\Stack::push' => ['void', 'item'=>'mixed'],
'parse_ini_file' => ['array|false', 'filename'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'],
'parse_ini_string' => ['array|false', 'ini_string'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'],
'parse_str' => ['void', 'string'=>'string', '&w_result'=>'array'],
'parse_url' => ['int|string|array|null|false', 'url'=>'string', 'component='=>'int'],
'ParseError::__clone' => ['void'],
'ParseError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'ParseError::__toString' => ['string'],
'ParseError::getCode' => ['int'],
'ParseError::getFile' => ['string'],
'ParseError::getLine' => ['int'],
'ParseError::getMessage' => ['string'],
'ParseError::getPrevious' => ['?Throwable'],
'ParseError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'ParseError::getTraceAsString' => ['string'],
'parsekit_compile_file' => ['array', 'filename'=>'string', 'errors='=>'array', 'options='=>'int'],
'parsekit_compile_string' => ['array', 'phpcode'=>'string', 'errors='=>'array', 'options='=>'int'],
'parsekit_func_arginfo' => ['array', 'function'=>'mixed'],
'passthru' => ['void', 'command'=>'string', '&w_result_code='=>'int'],
'password_get_info' => ['array', 'hash'=>'string'],
'password_hash' => ['string', 'password'=>'string', 'algo'=>'int|string|null', 'options='=>'array'],
'password_make_salt' => ['bool', 'password'=>'string', 'hash'=>'string'],
'password_needs_rehash' => ['bool', 'hash'=>'string', 'algo'=>'int|string|null', 'options='=>'array'],
'password_verify' => ['bool', 'password'=>'string', 'hash'=>'string'],
'pathinfo' => ['array|string', 'path'=>'string', 'flags='=>'int'],
'pclose' => ['int', 'handle'=>'resource'],
'pcnlt_sigwaitinfo' => ['int', 'set'=>'array', '&w_siginfo'=>'array'],
'pcntl_alarm' => ['int', 'seconds'=>'int'],
'pcntl_async_signals' => ['bool', 'enable='=>'?bool'],
'pcntl_errno' => ['int'],
'pcntl_exec' => ['false', 'path'=>'string', 'args='=>'array', 'env_vars='=>'array'],
'pcntl_fork' => ['int'],
'pcntl_get_last_error' => ['int'],
'pcntl_getpriority' => ['int', 'process_id='=>'?int', 'mode='=>'int'],
'pcntl_setpriority' => ['bool', 'priority'=>'int', 'process_id='=>'?int', 'mode='=>'int'],
'pcntl_signal' => ['bool', 'signal'=>'int', 'handler'=>'callable():void|callable(int):void|callable(int,array):void|int', 'restart_syscalls='=>'bool'],
'pcntl_signal_dispatch' => ['bool'],
'pcntl_signal_get_handler' => ['int|string', 'signal'=>'int'],
'pcntl_sigprocmask' => ['bool', 'mode'=>'int', 'signals'=>'array', '&w_old_signals='=>'array'],
'pcntl_sigtimedwait' => ['int', 'signals'=>'array', '&w_info='=>'array', 'seconds='=>'int', 'nanoseconds='=>'int'],
'pcntl_sigwaitinfo' => ['int', 'signals'=>'array', '&w_info='=>'array'],
'pcntl_strerror' => ['string', 'error_code'=>'int'],
'pcntl_wait' => ['int', '&w_status'=>'int', 'flags='=>'int', '&w_resource_usage='=>'array'],
'pcntl_waitpid' => ['int', 'process_id'=>'int', '&w_status'=>'int', 'flags='=>'int', '&w_resource_usage='=>'array'],
'pcntl_wexitstatus' => ['int', 'status'=>'int'],
'pcntl_wifcontinued' => ['bool', 'status'=>'int'],
'pcntl_wifexited' => ['bool', 'status'=>'int'],
'pcntl_wifsignaled' => ['bool', 'status'=>'int'],
'pcntl_wifstopped' => ['bool', 'status'=>'int'],
'pcntl_wstopsig' => ['int', 'status'=>'int'],
'pcntl_wtermsig' => ['int', 'status'=>'int'],
'PDF_activate_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'],
'PDF_add_launchlink' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'],
'PDF_add_locallink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'page'=>'int', 'dest'=>'string'],
'PDF_add_nameddest' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'],
'PDF_add_note' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'],
'PDF_add_pdflink' => ['bool', 'pdfdoc'=>'resource', 'bottom_left_x'=>'float', 'bottom_left_y'=>'float', 'up_right_x'=>'float', 'up_right_y'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'],
'PDF_add_table_cell' => ['int', 'pdfdoc'=>'resource', 'table'=>'int', 'column'=>'int', 'row'=>'int', 'text'=>'string', 'optlist'=>'string'],
'PDF_add_textflow' => ['int', 'pdfdoc'=>'resource', 'textflow'=>'int', 'text'=>'string', 'optlist'=>'string'],
'PDF_add_thumbnail' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int'],
'PDF_add_weblink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'url'=>'string'],
'PDF_arc' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
'PDF_arcn' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
'PDF_attach_file' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'description'=>'string', 'author'=>'string', 'mimetype'=>'string', 'icon'=>'string'],
'PDF_begin_document' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'],
'PDF_begin_font' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float', 'optlist'=>'string'],
'PDF_begin_glyph' => ['bool', 'pdfdoc'=>'resource', 'glyphname'=>'string', 'wx'=>'float', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float'],
'PDF_begin_item' => ['int', 'pdfdoc'=>'resource', 'tag'=>'string', 'optlist'=>'string'],
'PDF_begin_layer' => ['bool', 'pdfdoc'=>'resource', 'layer'=>'int'],
'PDF_begin_page' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
'PDF_begin_page_ext' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
'PDF_begin_pattern' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'],
'PDF_begin_template' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
'PDF_begin_template_ext' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
'PDF_circle' => ['bool', 'pdfdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float'],
'PDF_clip' => ['bool', 'p'=>'resource'],
'PDF_close' => ['bool', 'p'=>'resource'],
'PDF_close_image' => ['bool', 'p'=>'resource', 'image'=>'int'],
'PDF_close_pdi' => ['bool', 'p'=>'resource', 'doc'=>'int'],
'PDF_close_pdi_page' => ['bool', 'p'=>'resource', 'page'=>'int'],
'PDF_closepath' => ['bool', 'p'=>'resource'],
'PDF_closepath_fill_stroke' => ['bool', 'p'=>'resource'],
'PDF_closepath_stroke' => ['bool', 'p'=>'resource'],
'PDF_concat' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
'PDF_continue_text' => ['bool', 'p'=>'resource', 'text'=>'string'],
'PDF_create_3dview' => ['int', 'pdfdoc'=>'resource', 'username'=>'string', 'optlist'=>'string'],
'PDF_create_action' => ['int', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'],
'PDF_create_annotation' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'type'=>'string', 'optlist'=>'string'],
'PDF_create_bookmark' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'],
'PDF_create_field' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'name'=>'string', 'type'=>'string', 'optlist'=>'string'],
'PDF_create_fieldgroup' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'],
'PDF_create_gstate' => ['int', 'pdfdoc'=>'resource', 'optlist'=>'string'],
'PDF_create_pvf' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'data'=>'string', 'optlist'=>'string'],
'PDF_create_textflow' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'],
'PDF_curveto' => ['bool', 'p'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
'PDF_define_layer' => ['int', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'],
'PDF_delete' => ['bool', 'pdfdoc'=>'resource'],
'PDF_delete_pvf' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string'],
'PDF_delete_table' => ['bool', 'pdfdoc'=>'resource', 'table'=>'int', 'optlist'=>'string'],
'PDF_delete_textflow' => ['bool', 'pdfdoc'=>'resource', 'textflow'=>'int'],
'PDF_encoding_set_char' => ['bool', 'pdfdoc'=>'resource', 'encoding'=>'string', 'slot'=>'int', 'glyphname'=>'string', 'uv'=>'int'],
'PDF_end_document' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
'PDF_end_font' => ['bool', 'pdfdoc'=>'resource'],
'PDF_end_glyph' => ['bool', 'pdfdoc'=>'resource'],
'PDF_end_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'],
'PDF_end_layer' => ['bool', 'pdfdoc'=>'resource'],
'PDF_end_page' => ['bool', 'p'=>'resource'],
'PDF_end_page_ext' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
'PDF_end_pattern' => ['bool', 'p'=>'resource'],
'PDF_end_template' => ['bool', 'p'=>'resource'],
'PDF_endpath' => ['bool', 'p'=>'resource'],
'PDF_fill' => ['bool', 'p'=>'resource'],
'PDF_fill_imageblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'image'=>'int', 'optlist'=>'string'],
'PDF_fill_pdfblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'contents'=>'int', 'optlist'=>'string'],
'PDF_fill_stroke' => ['bool', 'p'=>'resource'],
'PDF_fill_textblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'text'=>'string', 'optlist'=>'string'],
'PDF_findfont' => ['int', 'p'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed'=>'int'],
'PDF_fit_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
'PDF_fit_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
'PDF_fit_table' => ['string', 'pdfdoc'=>'resource', 'table'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
'PDF_fit_textflow' => ['string', 'pdfdoc'=>'resource', 'textflow'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
'PDF_fit_textline' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
'PDF_get_apiname' => ['string', 'pdfdoc'=>'resource'],
'PDF_get_buffer' => ['string', 'p'=>'resource'],
'PDF_get_errmsg' => ['string', 'pdfdoc'=>'resource'],
'PDF_get_errnum' => ['int', 'pdfdoc'=>'resource'],
'PDF_get_majorversion' => ['int'],
'PDF_get_minorversion' => ['int'],
'PDF_get_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'],
'PDF_get_pdi_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
'PDF_get_pdi_value' => ['float', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
'PDF_get_value' => ['float', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'],
'PDF_info_font' => ['float', 'pdfdoc'=>'resource', 'font'=>'int', 'keyword'=>'string', 'optlist'=>'string'],
'PDF_info_matchbox' => ['float', 'pdfdoc'=>'resource', 'boxname'=>'string', 'num'=>'int', 'keyword'=>'string'],
'PDF_info_table' => ['float', 'pdfdoc'=>'resource', 'table'=>'int', 'keyword'=>'string'],
'PDF_info_textflow' => ['float', 'pdfdoc'=>'resource', 'textflow'=>'int', 'keyword'=>'string'],
'PDF_info_textline' => ['float', 'pdfdoc'=>'resource', 'text'=>'string', 'keyword'=>'string', 'optlist'=>'string'],
'PDF_initgraphics' => ['bool', 'p'=>'resource'],
'PDF_lineto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'],
'PDF_load_3ddata' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'],
'PDF_load_font' => ['int', 'pdfdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'optlist'=>'string'],
'PDF_load_iccprofile' => ['int', 'pdfdoc'=>'resource', 'profilename'=>'string', 'optlist'=>'string'],
'PDF_load_image' => ['int', 'pdfdoc'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'optlist'=>'string'],
'PDF_makespotcolor' => ['int', 'p'=>'resource', 'spotname'=>'string'],
'PDF_moveto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'],
'PDF_new' => ['resource'],
'PDF_open_ccitt' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'bitreverse'=>'int', 'k'=>'int', 'blackls1'=>'int'],
'PDF_open_file' => ['bool', 'p'=>'resource', 'filename'=>'string'],
'PDF_open_image' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'],
'PDF_open_image_file' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'stringparam'=>'string', 'intparam'=>'int'],
'PDF_open_memory_image' => ['int', 'p'=>'resource', 'image'=>'resource'],
'PDF_open_pdi' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string', 'length'=>'int'],
'PDF_open_pdi_document' => ['int', 'p'=>'resource', 'filename'=>'string', 'optlist'=>'string'],
'PDF_open_pdi_page' => ['int', 'p'=>'resource', 'doc'=>'int', 'pagenumber'=>'int', 'optlist'=>'string'],
'PDF_pcos_get_number' => ['float', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'],
'PDF_pcos_get_stream' => ['string', 'p'=>'resource', 'doc'=>'int', 'optlist'=>'string', 'path'=>'string'],
'PDF_pcos_get_string' => ['string', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'],
'PDF_place_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'],
'PDF_place_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'sx'=>'float', 'sy'=>'float'],
'PDF_process_pdi' => ['int', 'pdfdoc'=>'resource', 'doc'=>'int', 'page'=>'int', 'optlist'=>'string'],
'PDF_rect' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
'PDF_restore' => ['bool', 'p'=>'resource'],
'PDF_resume_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
'PDF_rotate' => ['bool', 'p'=>'resource', 'phi'=>'float'],
'PDF_save' => ['bool', 'p'=>'resource'],
'PDF_scale' => ['bool', 'p'=>'resource', 'sx'=>'float', 'sy'=>'float'],
'PDF_set_border_color' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDF_set_border_dash' => ['bool', 'pdfdoc'=>'resource', 'black'=>'float', 'white'=>'float'],
'PDF_set_border_style' => ['bool', 'pdfdoc'=>'resource', 'style'=>'string', 'width'=>'float'],
'PDF_set_gstate' => ['bool', 'pdfdoc'=>'resource', 'gstate'=>'int'],
'PDF_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'],
'PDF_set_layer_dependency' => ['bool', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'],
'PDF_set_parameter' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'],
'PDF_set_text_pos' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'],
'PDF_set_value' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'float'],
'PDF_setcolor' => ['bool', 'p'=>'resource', 'fstype'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'],
'PDF_setdash' => ['bool', 'pdfdoc'=>'resource', 'b'=>'float', 'w'=>'float'],
'PDF_setdashpattern' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
'PDF_setflat' => ['bool', 'pdfdoc'=>'resource', 'flatness'=>'float'],
'PDF_setfont' => ['bool', 'pdfdoc'=>'resource', 'font'=>'int', 'fontsize'=>'float'],
'PDF_setgray' => ['bool', 'p'=>'resource', 'g'=>'float'],
'PDF_setgray_fill' => ['bool', 'p'=>'resource', 'g'=>'float'],
'PDF_setgray_stroke' => ['bool', 'p'=>'resource', 'g'=>'float'],
'PDF_setlinecap' => ['bool', 'p'=>'resource', 'linecap'=>'int'],
'PDF_setlinejoin' => ['bool', 'p'=>'resource', 'value'=>'int'],
'PDF_setlinewidth' => ['bool', 'p'=>'resource', 'width'=>'float'],
'PDF_setmatrix' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
'PDF_setmiterlimit' => ['bool', 'pdfdoc'=>'resource', 'miter'=>'float'],
'PDF_setrgbcolor' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDF_setrgbcolor_fill' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDF_setrgbcolor_stroke' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDF_shading' => ['int', 'pdfdoc'=>'resource', 'shtype'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'],
'PDF_shading_pattern' => ['int', 'pdfdoc'=>'resource', 'shading'=>'int', 'optlist'=>'string'],
'PDF_shfill' => ['bool', 'pdfdoc'=>'resource', 'shading'=>'int'],
'PDF_show' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string'],
'PDF_show_boxed' => ['int', 'p'=>'resource', 'text'=>'string', 'left'=>'float', 'top'=>'float', 'width'=>'float', 'height'=>'float', 'mode'=>'string', 'feature'=>'string'],
'PDF_show_xy' => ['bool', 'p'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'],
'PDF_skew' => ['bool', 'p'=>'resource', 'alpha'=>'float', 'beta'=>'float'],
'PDF_stringwidth' => ['float', 'p'=>'resource', 'text'=>'string', 'font'=>'int', 'fontsize'=>'float'],
'PDF_stroke' => ['bool', 'p'=>'resource'],
'PDF_suspend_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'],
'PDF_translate' => ['bool', 'p'=>'resource', 'tx'=>'float', 'ty'=>'float'],
'PDF_utf16_to_utf8' => ['string', 'pdfdoc'=>'resource', 'utf16string'=>'string'],
'PDF_utf32_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf32string'=>'string', 'ordering'=>'string'],
'PDF_utf8_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf8string'=>'string', 'ordering'=>'string'],
'PDFlib::activate_item' => ['bool', 'id'=>''],
'PDFlib::add_launchlink' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'],
'PDFlib::add_locallink' => ['bool', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'page'=>'int', 'dest'=>'string'],
'PDFlib::add_nameddest' => ['bool', 'name'=>'string', 'optlist'=>'string'],
'PDFlib::add_note' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'],
'PDFlib::add_pdflink' => ['bool', 'bottom_left_x'=>'float', 'bottom_left_y'=>'float', 'up_right_x'=>'float', 'up_right_y'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'],
'PDFlib::add_table_cell' => ['int', 'table'=>'int', 'column'=>'int', 'row'=>'int', 'text'=>'string', 'optlist'=>'string'],
'PDFlib::add_textflow' => ['int', 'textflow'=>'int', 'text'=>'string', 'optlist'=>'string'],
'PDFlib::add_thumbnail' => ['bool', 'image'=>'int'],
'PDFlib::add_weblink' => ['bool', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'url'=>'string'],
'PDFlib::arc' => ['bool', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
'PDFlib::arcn' => ['bool', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'],
'PDFlib::attach_file' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'description'=>'string', 'author'=>'string', 'mimetype'=>'string', 'icon'=>'string'],
'PDFlib::begin_document' => ['int', 'filename'=>'string', 'optlist'=>'string'],
'PDFlib::begin_font' => ['bool', 'filename'=>'string', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float', 'optlist'=>'string'],
'PDFlib::begin_glyph' => ['bool', 'glyphname'=>'string', 'wx'=>'float', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float'],
'PDFlib::begin_item' => ['int', 'tag'=>'string', 'optlist'=>'string'],
'PDFlib::begin_layer' => ['bool', 'layer'=>'int'],
'PDFlib::begin_page' => ['bool', 'width'=>'float', 'height'=>'float'],
'PDFlib::begin_page_ext' => ['bool', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
'PDFlib::begin_pattern' => ['int', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'],
'PDFlib::begin_template' => ['int', 'width'=>'float', 'height'=>'float'],
'PDFlib::begin_template_ext' => ['int', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'],
'PDFlib::circle' => ['bool', 'x'=>'float', 'y'=>'float', 'r'=>'float'],
'PDFlib::clip' => ['bool'],
'PDFlib::close' => ['bool'],
'PDFlib::close_image' => ['bool', 'image'=>'int'],
'PDFlib::close_pdi' => ['bool', 'doc'=>'int'],
'PDFlib::close_pdi_page' => ['bool', 'page'=>'int'],
'PDFlib::closepath' => ['bool'],
'PDFlib::closepath_fill_stroke' => ['bool'],
'PDFlib::closepath_stroke' => ['bool'],
'PDFlib::concat' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
'PDFlib::continue_text' => ['bool', 'text'=>'string'],
'PDFlib::create_3dview' => ['int', 'username'=>'string', 'optlist'=>'string'],
'PDFlib::create_action' => ['int', 'type'=>'string', 'optlist'=>'string'],
'PDFlib::create_annotation' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'type'=>'string', 'optlist'=>'string'],
'PDFlib::create_bookmark' => ['int', 'text'=>'string', 'optlist'=>'string'],
'PDFlib::create_field' => ['bool', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'name'=>'string', 'type'=>'string', 'optlist'=>'string'],
'PDFlib::create_fieldgroup' => ['bool', 'name'=>'string', 'optlist'=>'string'],
'PDFlib::create_gstate' => ['int', 'optlist'=>'string'],
'PDFlib::create_pvf' => ['bool', 'filename'=>'string', 'data'=>'string', 'optlist'=>'string'],
'PDFlib::create_textflow' => ['int', 'text'=>'string', 'optlist'=>'string'],
'PDFlib::curveto' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
'PDFlib::define_layer' => ['int', 'name'=>'string', 'optlist'=>'string'],
'PDFlib::delete' => ['bool'],
'PDFlib::delete_pvf' => ['int', 'filename'=>'string'],
'PDFlib::delete_table' => ['bool', 'table'=>'int', 'optlist'=>'string'],
'PDFlib::delete_textflow' => ['bool', 'textflow'=>'int'],
'PDFlib::encoding_set_char' => ['bool', 'encoding'=>'string', 'slot'=>'int', 'glyphname'=>'string', 'uv'=>'int'],
'PDFlib::end_document' => ['bool', 'optlist'=>'string'],
'PDFlib::end_font' => ['bool'],
'PDFlib::end_glyph' => ['bool'],
'PDFlib::end_item' => ['bool', 'id'=>'int'],
'PDFlib::end_layer' => ['bool'],
'PDFlib::end_page' => ['bool', 'p'=>''],
'PDFlib::end_page_ext' => ['bool', 'optlist'=>'string'],
'PDFlib::end_pattern' => ['bool', 'p'=>''],
'PDFlib::end_template' => ['bool', 'p'=>''],
'PDFlib::endpath' => ['bool', 'p'=>''],
'PDFlib::fill' => ['bool'],
'PDFlib::fill_imageblock' => ['int', 'page'=>'int', 'blockname'=>'string', 'image'=>'int', 'optlist'=>'string'],
'PDFlib::fill_pdfblock' => ['int', 'page'=>'int', 'blockname'=>'string', 'contents'=>'int', 'optlist'=>'string'],
'PDFlib::fill_stroke' => ['bool'],
'PDFlib::fill_textblock' => ['int', 'page'=>'int', 'blockname'=>'string', 'text'=>'string', 'optlist'=>'string'],
'PDFlib::findfont' => ['int', 'fontname'=>'string', 'encoding'=>'string', 'embed'=>'int'],
'PDFlib::fit_image' => ['bool', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
'PDFlib::fit_pdi_page' => ['bool', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
'PDFlib::fit_table' => ['string', 'table'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
'PDFlib::fit_textflow' => ['string', 'textflow'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'],
'PDFlib::fit_textline' => ['bool', 'text'=>'string', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'],
'PDFlib::get_apiname' => ['string'],
'PDFlib::get_buffer' => ['string'],
'PDFlib::get_errmsg' => ['string'],
'PDFlib::get_errnum' => ['int'],
'PDFlib::get_majorversion' => ['int'],
'PDFlib::get_minorversion' => ['int'],
'PDFlib::get_parameter' => ['string', 'key'=>'string', 'modifier'=>'float'],
'PDFlib::get_pdi_parameter' => ['string', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
'PDFlib::get_pdi_value' => ['float', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'],
'PDFlib::get_value' => ['float', 'key'=>'string', 'modifier'=>'float'],
'PDFlib::info_font' => ['float', 'font'=>'int', 'keyword'=>'string', 'optlist'=>'string'],
'PDFlib::info_matchbox' => ['float', 'boxname'=>'string', 'num'=>'int', 'keyword'=>'string'],
'PDFlib::info_table' => ['float', 'table'=>'int', 'keyword'=>'string'],
'PDFlib::info_textflow' => ['float', 'textflow'=>'int', 'keyword'=>'string'],
'PDFlib::info_textline' => ['float', 'text'=>'string', 'keyword'=>'string', 'optlist'=>'string'],
'PDFlib::initgraphics' => ['bool'],
'PDFlib::lineto' => ['bool', 'x'=>'float', 'y'=>'float'],
'PDFlib::load_3ddata' => ['int', 'filename'=>'string', 'optlist'=>'string'],
'PDFlib::load_font' => ['int', 'fontname'=>'string', 'encoding'=>'string', 'optlist'=>'string'],
'PDFlib::load_iccprofile' => ['int', 'profilename'=>'string', 'optlist'=>'string'],
'PDFlib::load_image' => ['int', 'imagetype'=>'string', 'filename'=>'string', 'optlist'=>'string'],
'PDFlib::makespotcolor' => ['int', 'spotname'=>'string'],
'PDFlib::moveto' => ['bool', 'x'=>'float', 'y'=>'float'],
'PDFlib::open_ccitt' => ['int', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'BitReverse'=>'int', 'k'=>'int', 'Blackls1'=>'int'],
'PDFlib::open_file' => ['bool', 'filename'=>'string'],
'PDFlib::open_image' => ['int', 'imagetype'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'],
'PDFlib::open_image_file' => ['int', 'imagetype'=>'string', 'filename'=>'string', 'stringparam'=>'string', 'intparam'=>'int'],
'PDFlib::open_memory_image' => ['int', 'image'=>'resource'],
'PDFlib::open_pdi' => ['int', 'filename'=>'string', 'optlist'=>'string', 'length'=>'int'],
'PDFlib::open_pdi_document' => ['int', 'filename'=>'string', 'optlist'=>'string'],
'PDFlib::open_pdi_page' => ['int', 'doc'=>'int', 'pagenumber'=>'int', 'optlist'=>'string'],
'PDFlib::pcos_get_number' => ['float', 'doc'=>'int', 'path'=>'string'],
'PDFlib::pcos_get_stream' => ['string', 'doc'=>'int', 'optlist'=>'string', 'path'=>'string'],
'PDFlib::pcos_get_string' => ['string', 'doc'=>'int', 'path'=>'string'],
'PDFlib::place_image' => ['bool', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'],
'PDFlib::place_pdi_page' => ['bool', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'sx'=>'float', 'sy'=>'float'],
'PDFlib::process_pdi' => ['int', 'doc'=>'int', 'page'=>'int', 'optlist'=>'string'],
'PDFlib::rect' => ['bool', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
'PDFlib::restore' => ['bool', 'p'=>''],
'PDFlib::resume_page' => ['bool', 'optlist'=>'string'],
'PDFlib::rotate' => ['bool', 'phi'=>'float'],
'PDFlib::save' => ['bool', 'p'=>''],
'PDFlib::scale' => ['bool', 'sx'=>'float', 'sy'=>'float'],
'PDFlib::set_border_color' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDFlib::set_border_dash' => ['bool', 'black'=>'float', 'white'=>'float'],
'PDFlib::set_border_style' => ['bool', 'style'=>'string', 'width'=>'float'],
'PDFlib::set_gstate' => ['bool', 'gstate'=>'int'],
'PDFlib::set_info' => ['bool', 'key'=>'string', 'value'=>'string'],
'PDFlib::set_layer_dependency' => ['bool', 'type'=>'string', 'optlist'=>'string'],
'PDFlib::set_parameter' => ['bool', 'key'=>'string', 'value'=>'string'],
'PDFlib::set_text_pos' => ['bool', 'x'=>'float', 'y'=>'float'],
'PDFlib::set_value' => ['bool', 'key'=>'string', 'value'=>'float'],
'PDFlib::setcolor' => ['bool', 'fstype'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'],
'PDFlib::setdash' => ['bool', 'b'=>'float', 'w'=>'float'],
'PDFlib::setdashpattern' => ['bool', 'optlist'=>'string'],
'PDFlib::setflat' => ['bool', 'flatness'=>'float'],
'PDFlib::setfont' => ['bool', 'font'=>'int', 'fontsize'=>'float'],
'PDFlib::setgray' => ['bool', 'g'=>'float'],
'PDFlib::setgray_fill' => ['bool', 'g'=>'float'],
'PDFlib::setgray_stroke' => ['bool', 'g'=>'float'],
'PDFlib::setlinecap' => ['bool', 'linecap'=>'int'],
'PDFlib::setlinejoin' => ['bool', 'value'=>'int'],
'PDFlib::setlinewidth' => ['bool', 'width'=>'float'],
'PDFlib::setmatrix' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'],
'PDFlib::setmiterlimit' => ['bool', 'miter'=>'float'],
'PDFlib::setrgbcolor' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDFlib::setrgbcolor_fill' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDFlib::setrgbcolor_stroke' => ['bool', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'PDFlib::shading' => ['int', 'shtype'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'],
'PDFlib::shading_pattern' => ['int', 'shading'=>'int', 'optlist'=>'string'],
'PDFlib::shfill' => ['bool', 'shading'=>'int'],
'PDFlib::show' => ['bool', 'text'=>'string'],
'PDFlib::show_boxed' => ['int', 'text'=>'string', 'left'=>'float', 'top'=>'float', 'width'=>'float', 'height'=>'float', 'mode'=>'string', 'feature'=>'string'],
'PDFlib::show_xy' => ['bool', 'text'=>'string', 'x'=>'float', 'y'=>'float'],
'PDFlib::skew' => ['bool', 'alpha'=>'float', 'beta'=>'float'],
'PDFlib::stringwidth' => ['float', 'text'=>'string', 'font'=>'int', 'fontsize'=>'float'],
'PDFlib::stroke' => ['bool', 'p'=>''],
'PDFlib::suspend_page' => ['bool', 'optlist'=>'string'],
'PDFlib::translate' => ['bool', 'tx'=>'float', 'ty'=>'float'],
'PDFlib::utf16_to_utf8' => ['string', 'utf16string'=>'string'],
'PDFlib::utf32_to_utf16' => ['string', 'utf32string'=>'string', 'ordering'=>'string'],
'PDFlib::utf8_to_utf16' => ['string', 'utf8string'=>'string', 'ordering'=>'string'],
'PDO::__construct' => ['void', 'dsn'=>'string', 'username='=>'?string', 'passwd='=>'?string', 'options='=>'?array'],
'PDO::__sleep' => ['list<string>'],
'PDO::__wakeup' => ['void'],
'PDO::beginTransaction' => ['bool'],
'PDO::commit' => ['bool'],
'PDO::cubrid_schema' => ['array', 'schema_type'=>'int', 'table_name='=>'string', 'col_name='=>'string'],
'PDO::errorCode' => ['?string'],
'PDO::errorInfo' => ['array{0: ?string, 1: ?int, 2: ?string, 3?: mixed, 4?: mixed}'],
'PDO::exec' => ['int|false', 'query'=>'string'],
'PDO::getAttribute' => ['mixed', 'attribute'=>'int'],
'PDO::getAvailableDrivers' => ['array'],
'PDO::inTransaction' => ['bool'],
'PDO::lastInsertId' => ['string', 'name='=>'string|null'],
'PDO::pgsqlCopyFromArray' => ['bool', 'table_name'=>'string', 'rows'=>'array', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
'PDO::pgsqlCopyFromFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
'PDO::pgsqlCopyToArray' => ['array', 'table_name'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
'PDO::pgsqlCopyToFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'],
'PDO::pgsqlGetNotify' => ['array{message:string,pid:int,payload?:string}|false', 'result_type='=>'PDO::FETCH_*', 'ms_timeout='=>'int'],
'PDO::pgsqlGetPid' => ['int'],
'PDO::pgsqlLOBCreate' => ['string'],
'PDO::pgsqlLOBOpen' => ['resource', 'oid'=>'string', 'mode='=>'string'],
'PDO::pgsqlLOBUnlink' => ['bool', 'oid'=>'string'],
'PDO::prepare' => ['PDOStatement|false', 'statement'=>'string', 'options='=>'array'],
'PDO::query' => ['PDOStatement|false', 'sql'=>'string'],
'PDO::query\'1' => ['PDOStatement|false', 'sql'=>'string', 'fetch_column'=>'int', 'colno='=>'int'],
'PDO::query\'2' => ['PDOStatement|false', 'sql'=>'string', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs'=>'array'],
'PDO::query\'3' => ['PDOStatement|false', 'sql'=>'string', 'fetch_into'=>'int', 'object'=>'object'],
'PDO::quote' => ['string|false', 'string'=>'string', 'paramtype='=>'int'],
'PDO::rollBack' => ['bool'],
'PDO::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>''],
'PDO::sqliteCreateAggregate' => ['bool', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'],
'PDO::sqliteCreateCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'],
'PDO::sqliteCreateFunction' => ['bool', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'],
'pdo_drivers' => ['array'],
'PDOException::getCode' => ['int|string'],
'PDOException::getFile' => ['string'],
'PDOException::getLine' => ['int'],
'PDOException::getMessage' => ['string'],
'PDOException::getPrevious' => ['?Throwable'],
'PDOException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'PDOException::getTraceAsString' => ['string'],
'PDOStatement::__sleep' => ['list<string>'],
'PDOStatement::__wakeup' => ['void'],
'PDOStatement::bindColumn' => ['bool', 'column'=>'mixed', '&rw_var'=>'mixed', 'type='=>'int', 'maxLength='=>'int', 'driverOptions='=>'mixed'],
'PDOStatement::bindParam' => ['bool', 'param,'=>'string|int', '&rw_var'=>'mixed', 'type='=>'int', 'maxLength='=>'int', 'driverOptions='=>'mixed'],
'PDOStatement::bindValue' => ['bool', 'param'=>'string|int', 'value'=>'mixed', 'type='=>'int'],
'PDOStatement::closeCursor' => ['bool'],
'PDOStatement::columnCount' => ['int'],
'PDOStatement::debugDumpParams' => ['bool|null'],
'PDOStatement::errorCode' => ['string|null'],
'PDOStatement::errorInfo' => ['array{0: ?string, 1: ?int, 2: ?string, 3?: mixed, 4?: mixed}'],
'PDOStatement::execute' => ['bool', 'params='=>'?array'],
'PDOStatement::fetch' => ['mixed', 'mode='=>'int', 'cursorOrientation='=>'int', 'cursorOffset='=>'int'],
'PDOStatement::fetchAll' => ['array', 'mode='=>'int', '...args='=>'mixed'],
'PDOStatement::fetchColumn' => ['mixed', 'column='=>'int'],
'PDOStatement::fetchObject' => ['object|false', 'class='=>'?string', 'ctorArgs='=>'?array'],
'PDOStatement::getAttribute' => ['mixed', 'attribute'=>'int'],
'PDOStatement::getColumnMeta' => ['array|false', 'column'=>'int'],
'PDOStatement::nextRowset' => ['bool'],
'PDOStatement::rowCount' => ['int'],
'PDOStatement::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>'mixed'],
'PDOStatement::setFetchMode' => ['bool', 'mode'=>'int', '...args='=> 'mixed'],
'pfsockopen' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'?float'],
'pg_affected_rows' => ['int', 'result'=>'\PgSql\Result'],
'pg_cancel_query' => ['bool', 'connection'=>'\PgSql\Connection'],
'pg_client_encoding' => ['string', 'connection='=>'?\PgSql\Connection'],
'pg_close' => ['bool', 'connection='=>'?\PgSql\Connection'],
'pg_connect' => ['\PgSql\Connection|false', 'connection_string'=>'string', 'flags='=>'int'],
'pg_connect_poll' => ['int', 'connection'=>'\PgSql\Connection'],
'pg_connection_busy' => ['bool', 'connection'=>'\PgSql\Connection'],
'pg_connection_reset' => ['bool', 'connection'=>'\PgSql\Connection'],
'pg_connection_status' => ['int', 'connection'=>'\PgSql\Connection'],
'pg_consume_input' => ['bool', 'connection'=>'\PgSql\Connection'],
'pg_convert' => ['array|false', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'values'=>'array', 'flags='=>'int'],
'pg_copy_from' => ['bool', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'rows'=>'array', 'separator='=>'string', 'null_as='=>'string'],
'pg_copy_to' => ['array|false', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'separator='=>'string', 'null_as='=>'string'],
'pg_dbname' => ['string', 'connection='=>'?\PgSql\Connection'],
'pg_delete' => ['string|bool', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'conditions'=>'array', 'flags='=>'int'],
'pg_end_copy' => ['bool', 'connection='=>'?\PgSql\Connection'],
'pg_escape_bytea' => ['string', 'connection'=>'\PgSql\Connection', 'string'=>'string'],
'pg_escape_bytea\'1' => ['string', 'connection'=>'string'],
'pg_escape_identifier' => ['string|false', 'connection'=>'\PgSql\Connection', 'string'=>'string'],
'pg_escape_identifier\'1' => ['string|false', 'connection'=>'string'],
'pg_escape_literal' => ['string|false', 'connection'=>'\PgSql\Connection', 'string'=>'string'],
'pg_escape_literal\'1' => ['string|false', 'connection'=>'string'],
'pg_escape_string' => ['string', 'connection'=>'\PgSql\Connection', 'string'=>'string'],
'pg_escape_string\'1' => ['string', 'connection'=>'string'],
'pg_exec' => ['\PgSql\Result|false', 'connection'=>'\PgSql\Connection', 'query'=>'string'],
'pg_execute' => ['\PgSql\Result|false', 'connection'=>'\PgSql\Connection', 'statement_name'=>'string', 'params'=>'array'],
'pg_execute\'1' => ['\PgSql\Result|false', 'connection'=>'string', 'statement_name'=>'array'],
'pg_fetch_all' => ['array<array>', 'result'=>'\PgSql\Result', 'result_type='=>'int'],
'pg_fetch_all_columns' => ['array', 'result'=>'\PgSql\Result', 'field='=>'int'],
'pg_fetch_array' => ['array<string|null>|false', 'result'=>'\PgSql\Result', 'row='=>'?int', 'mode='=>'int'],
'pg_fetch_assoc' => ['array<string, mixed>|false', 'result'=>'\PgSql\Result', 'row='=>'?int'],
'pg_fetch_object' => ['object|false', 'result'=>'\PgSql\Result', 'row='=>'?int', 'class='=>'string', 'constructor_args='=>'array'],
'pg_fetch_result' => ['string|false|null', 'result'=>'\PgSql\Result', 'row'=>'string|int'],
'pg_fetch_result\'1' => ['string|false|null', 'result'=>'\PgSql\Result', 'row'=>'?int', 'field'=>'string|int'],
'pg_fetch_row' => ['array|false', 'result'=>'\PgSql\Result', 'row='=>'?int', 'mode='=>'int'],
'pg_field_is_null' => ['int|false', 'result'=>'\PgSql\Result', 'row'=>'string|int'],
'pg_field_is_null\'1' => ['int|false', 'result'=>'\PgSql\Result', 'row'=>'int', 'field'=>'string|int'],
'pg_field_name' => ['string', 'result'=>'\PgSql\Result', 'field'=>'int'],
'pg_field_num' => ['int', 'result'=>'\PgSql\Result', 'field'=>'string'],
'pg_field_prtlen' => ['int|false', 'result'=>'\PgSql\Result', 'row'=>'string|int'],
'pg_field_prtlen\'1' => ['int|false', 'result'=>'\PgSql\Result', 'row'=>'int', 'field'=>'string|int'],
'pg_field_size' => ['int', 'result'=>'\PgSql\Result', 'field'=>'int'],
'pg_field_table' => ['string|int|false', 'result'=>'\PgSql\Result', 'field'=>'int', 'oid_only='=>'bool'],
'pg_field_type' => ['string', 'result'=>'\PgSql\Result', 'field'=>'int'],
'pg_field_type_oid' => ['int|string', 'result'=>'\PgSql\Result', 'field'=>'int'],
'pg_flush' => ['int|bool', 'connection'=>'\PgSql\Connection'],
'pg_free_result' => ['bool', 'result'=>'\PgSql\Result'],
'pg_get_notify' => ['array|false', 'result'=>'\PgSql\Result', 'mode='=>'int'],
'pg_get_pid' => ['int', 'connection'=>'\PgSql\Connection'],
'pg_get_result' => ['\PgSql\Result|false', 'connection='=>'\PgSql\Connection'],
'pg_host' => ['string', 'connection='=>'?\PgSql\Connection'],
'pg_insert' => ['\PgSql\Result|string|false', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'values'=>'array', 'flags='=>'int'],
'pg_last_error' => ['string', 'connection='=>'?\PgSql\Connection'],
'pg_last_notice' => ['string|array|bool', 'connection'=>'\PgSql\Connection', 'mode='=>'int'],
'pg_last_oid' => ['string|int|false', 'result'=>'\PgSql\Result'],
'pg_lo_close' => ['bool', 'lob'=>'\PgSql\Lob'],
'pg_lo_create' => ['int|string|false', 'connection='=>'\PgSql\Connection', 'oid='=>'int|string'],
'pg_lo_export' => ['bool', 'connection'=>'\PgSql\Connection', 'oid'=>'int|string', 'filename'=>'string'],
'pg_lo_export\'1' => ['bool', 'connection'=>'int|string', 'oid'=>'string'],
'pg_lo_import' => ['int|string|false', 'connection'=>'\PgSql\Connection', 'filename'=>'string', 'oid'=>'string|int'],
'pg_lo_import\'1' => ['int|string|false', 'connection'=>'string', 'filename'=>'string|int'],
'pg_lo_open' => ['\PgSql\Lob|false', 'connection'=>'\PgSql\Connection', 'oid'=>'int|string', 'mode'=>'string'],
'pg_lo_open\'1' => ['\PgSql\Lob|false', 'connection'=>'int|string', 'oid'=>'string'],
'pg_lo_read' => ['string|false', 'lob'=>'\PgSql\Lob', 'length='=>'int'],
'pg_lo_read_all' => ['int', 'lob'=>'\PgSql\Lob'],
'pg_lo_seek' => ['bool', 'lob'=>'\PgSql\Lob', 'offset'=>'int', 'whence='=>'int'],
'pg_lo_tell' => ['int', 'lob'=>'\PgSql\Lob'],
'pg_lo_truncate' => ['bool', 'lob'=>'\PgSql\Lob', 'size'=>'int'],
'pg_lo_unlink' => ['bool', 'connection'=>'\PgSql\Connection', 'oid'=>'int|string'],
'pg_lo_unlink\'1' => ['bool', 'connection'=>'int|string'],
'pg_lo_write' => ['int|false', 'lob'=>'\PgSql\Lob', 'data'=>'string', 'length='=>'?int'],
'pg_meta_data' => ['array|false', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'extended='=>'bool'],
'pg_num_fields' => ['int', 'result'=>'\PgSql\Result'],
'pg_num_rows' => ['int', 'result'=>'\PgSql\Result'],
'pg_options' => ['string', 'connection='=>'?\PgSql\Connection'],
'pg_parameter_status' => ['string|false', 'connection'=>'\PgSql\Connection', 'name'=>'string'],
'pg_parameter_status\'1' => ['string|false', 'connection'=>'string'],
'pg_pconnect' => ['\PgSql\Connection|false', 'connection_string'=>'string', 'flags='=>'string', 'port='=>'string|int', 'options='=>'string', 'tty='=>'string', 'database='=>'string'],
'pg_ping' => ['bool', 'connection='=>'?\PgSql\Connection'],
'pg_port' => ['string', 'connection='=>'?\PgSql\Connection'],
'pg_prepare' => ['\PgSql\Result|false', 'connection'=>'\PgSql\Connection', 'statement_name'=>'string', 'query'=>'string'],
'pg_prepare\'1' => ['\PgSql\Result|false', 'connection'=>'string', 'statement_name'=>'string'],
'pg_put_line' => ['bool', 'connection'=>'\PgSql\Connection', 'data'=>'string'],
'pg_put_line\'1' => ['bool', 'connection'=>'string'],
'pg_query' => ['\PgSql\Result|false', 'connection'=>'\PgSql\Connection', 'query'=>'string'],
'pg_query\'1' => ['\PgSql\Result|false', 'connection'=>'string'],
'pg_query_params' => ['\PgSql\Result|false', 'connection'=>'\PgSql\Connection', 'query'=>'string', 'params'=>'array'],
'pg_query_params\'1' => ['\PgSql\Result|false', 'connection'=>'string', 'query'=>'array'],
'pg_result_error' => ['string|false', 'result'=>'\PgSql\Result'],
'pg_result_error_field' => ['string|false|null', 'result'=>'\PgSql\Result', 'field_code'=>'int'],
'pg_result_seek' => ['bool', 'result'=>'\PgSql\Result', 'row'=>'int'],
'pg_result_status' => ['string|int', 'result'=>'\PgSql\Result', 'mode='=>'int'],
'pg_select' => ['string|array|false', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'assoc_array'=>'array', 'options='=>'int', 'result_type='=>'int'],
'pg_send_execute' => ['bool|int', 'connection'=>'\PgSql\Connection', 'query'=>'string', 'params'=>'array'],
'pg_send_prepare' => ['bool|int', 'connection'=>'\PgSql\Connection', 'statement_name'=>'string', 'query'=>'string'],
'pg_send_query' => ['bool|int', 'connection'=>'\PgSql\Connection', 'query'=>'string'],
'pg_send_query_params' => ['bool|int', 'connection'=>'\PgSql\Connection', 'query'=>'string', 'params'=>'array'],
'pg_set_client_encoding' => ['int', 'connection'=>'\PgSql\Connection', 'encoding'=>'string'],
'pg_set_client_encoding\'1' => ['int', 'connection'=>'string'],
'pg_set_error_verbosity' => ['int|false', 'connection'=>'\PgSql\Connection', 'verbosity'=>'int'],
'pg_set_error_verbosity\'1' => ['int|false', 'connection'=>'int'],
'pg_socket' => ['resource|false', 'connection'=>'\PgSql\Connection'],
'pg_trace' => ['bool', 'filename'=>'string', 'mode='=>'string', 'connection='=>'?\PgSql\Connection'],
'pg_transaction_status' => ['int', 'connection'=>'\PgSql\Connection'],
'pg_tty' => ['string', 'connection='=>'?\PgSql\Connection'],
'pg_unescape_bytea' => ['string', 'string'=>'string'],
'pg_untrace' => ['bool', 'connection='=>'?\PgSql\Connection'],
'pg_update' => ['string|bool', 'connection'=>'\PgSql\Connection', 'table_name'=>'string', 'values'=>'array', 'conditions'=>'array', 'flags='=>'int'],
'pg_version' => ['array', 'connection='=>'?\PgSql\Connection'],
'Phar::__construct' => ['void', 'fname'=>'string', 'flags='=>'int', 'alias='=>'string'],
'Phar::addEmptyDir' => ['void', 'dirname'=>'string'],
'Phar::addFile' => ['void', 'file'=>'string', 'localname='=>'string'],
'Phar::addFromString' => ['void', 'localname'=>'string', 'contents'=>'string'],
'Phar::apiVersion' => ['string'],
'Phar::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'],
'Phar::buildFromIterator' => ['array', 'iter'=>'Iterator', 'base_directory='=>'string'],
'Phar::canCompress' => ['bool', 'method='=>'int'],
'Phar::canWrite' => ['bool'],
'Phar::compress' => ['?Phar', 'compression'=>'int', 'extension='=>'?string'],
'Phar::compressAllFilesBZIP2' => ['bool'],
'Phar::compressAllFilesGZ' => ['bool'],
'Phar::compressFiles' => ['void', 'compression'=>'int'],
'Phar::convertToData' => ['?PharData', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
'Phar::convertToExecutable' => ['?Phar', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
'Phar::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'],
'Phar::count' => ['int'],
'Phar::createDefaultStub' => ['string', 'indexfile='=>'string', 'webindexfile='=>'string'],
'Phar::decompress' => ['?Phar', 'extension='=>'?string'],
'Phar::decompressFiles' => ['bool'],
'Phar::delete' => ['bool', 'entry'=>'string'],
'Phar::delMetadata' => ['bool'],
'Phar::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'],
'Phar::getAlias' => ['?string'],
'Phar::getMetadata' => ['mixed', 'unserializeOptions='=>'array'],
'Phar::getModified' => ['bool'],
'Phar::getPath' => ['string'],
'Phar::getSignature' => ['array{hash:string, hash_type:string}'],
'Phar::getStub' => ['string'],
'Phar::getSupportedCompression' => ['array'],
'Phar::getSupportedSignatures' => ['array'],
'Phar::getVersion' => ['string'],
'Phar::hasMetadata' => ['bool'],
'Phar::interceptFileFuncs' => ['void'],
'Phar::isBuffering' => ['bool'],
'Phar::isCompressed' => ['int|false'],
'Phar::isFileFormat' => ['bool', 'format'=>'int'],
'Phar::isValidPharFilename' => ['bool', 'filename'=>'string', 'executable='=>'bool'],
'Phar::isWritable' => ['bool'],
'Phar::loadPhar' => ['bool', 'filename'=>'string', 'alias='=>'?string'],
'Phar::mapPhar' => ['bool', 'alias='=>'string', 'dataoffset='=>'int'],
'Phar::mount' => ['void', 'pharpath'=>'string', 'externalpath'=>'string'],
'Phar::mungServer' => ['void', 'munglist'=>'array'],
'Phar::offsetExists' => ['bool', 'offset'=>'string'],
'Phar::offsetGet' => ['PharFileInfo', 'offset'=>'string'],
'Phar::offsetSet' => ['void', 'offset'=>'string', 'value'=>'string'],
'Phar::offsetUnset' => ['bool', 'offset'=>'string'],
'Phar::running' => ['string', 'retphar='=>'bool'],
'Phar::setAlias' => ['bool', 'alias'=>'string'],
'Phar::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'],
'Phar::setMetadata' => ['void', 'metadata'=>''],
'Phar::setSignatureAlgorithm' => ['void', 'sigtype'=>'int', 'privatekey='=>'string'],
'Phar::setStub' => ['bool', 'stub'=>'string', 'length='=>'int'],
'Phar::startBuffering' => ['void'],
'Phar::stopBuffering' => ['void'],
'Phar::uncompressAllFiles' => ['bool'],
'Phar::unlinkArchive' => ['bool', 'archive'=>'string'],
'Phar::webPhar' => ['', 'alias='=>'string', 'index='=>'string', 'f404='=>'string', 'mimetypes='=>'array', 'rewrites='=>'array'],
'PharData::__construct' => ['void', 'fname'=>'string', 'flags='=>'?int', 'alias='=>'?string', 'format='=>'int'],
'PharData::addEmptyDir' => ['bool', 'dirname'=>'string'],
'PharData::addFile' => ['void', 'file'=>'string', 'localname='=>'string'],
'PharData::addFromString' => ['bool', 'localname'=>'string', 'contents'=>'string'],
'PharData::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'],
'PharData::buildFromIterator' => ['array', 'iter'=>'Iterator', 'base_directory='=>'string'],
'PharData::compress' => ['?PharData', 'compression'=>'int', 'extension='=>'?string'],
'PharData::compressFiles' => ['void', 'compression'=>'int'],
'PharData::convertToData' => ['?PharData', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
'PharData::convertToExecutable' => ['?Phar', 'format='=>'?int', 'compression='=>'?int', 'extension='=>'?string'],
'PharData::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'],
'PharData::decompress' => ['?PharData', 'extension='=>'?string'],
'PharData::decompressFiles' => ['bool'],
'PharData::delete' => ['bool', 'entry'=>'string'],
'PharData::delMetadata' => ['bool'],
'PharData::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array|null', 'overwrite='=>'bool'],
'PharData::isWritable' => ['bool'],
'PharData::offsetExists' => ['bool', 'offset'=>'string'],
'PharData::offsetGet' => ['PharFileInfo', 'offset'=>'string'],
'PharData::offsetSet' => ['void', 'offset'=>'string', 'value'=>'string'],
'PharData::offsetUnset' => ['bool', 'offset'=>'string'],
'PharData::setAlias' => ['bool', 'alias'=>'string'],
'PharData::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'],
'phardata::setMetadata' => ['void', 'metadata'=>'mixed'],
'phardata::setSignatureAlgorithm' => ['void', 'sigtype'=>'int'],
'PharData::setStub' => ['bool', 'stub'=>'string', 'length='=>'int'],
'PharFileInfo::__construct' => ['void', 'entry'=>'string'],
'PharFileInfo::chmod' => ['void', 'permissions'=>'int'],
'PharFileInfo::compress' => ['bool', 'compression'=>'int'],
'PharFileInfo::decompress' => ['bool'],
'PharFileInfo::delMetadata' => ['bool'],
'PharFileInfo::getCompressedSize' => ['int'],
'PharFileInfo::getContent' => ['string'],
'PharFileInfo::getCRC32' => ['int'],
'PharFileInfo::getMetadata' => ['mixed', 'unserializeOptions='=>'array'],
'PharFileInfo::getPharFlags' => ['int'],
'PharFileInfo::hasMetadata' => ['bool'],
'PharFileInfo::isCompressed' => ['bool', 'compression_type='=>'int'],
'PharFileInfo::isCompressedBZIP2' => ['bool'],
'PharFileInfo::isCompressedGZ' => ['bool'],
'PharFileInfo::isCRCChecked' => ['bool'],
'PharFileInfo::setCompressedBZIP2' => ['bool'],
'PharFileInfo::setCompressedGZ' => ['bool'],
'PharFileInfo::setMetadata' => ['void', 'metadata'=>'mixed'],
'PharFileInfo::setUncompressed' => ['bool'],
'phdfs::__construct' => ['void', 'ip'=>'string', 'port'=>'string'],
'phdfs::__destruct' => ['void'],
'phdfs::connect' => ['bool'],
'phdfs::copy' => ['bool', 'source_file'=>'string', 'destination_file'=>'string'],
'phdfs::create_directory' => ['bool', 'path'=>'string'],
'phdfs::delete' => ['bool', 'path'=>'string'],
'phdfs::disconnect' => ['bool'],
'phdfs::exists' => ['bool', 'path'=>'string'],
'phdfs::file_info' => ['array', 'path'=>'string'],
'phdfs::list_directory' => ['array', 'path'=>'string'],
'phdfs::read' => ['string', 'path'=>'string', 'length='=>'string'],
'phdfs::rename' => ['bool', 'old_path'=>'string', 'new_path'=>'string'],
'phdfs::tell' => ['int', 'path'=>'string'],
'phdfs::write' => ['bool', 'path'=>'string', 'buffer'=>'string', 'mode='=>'string'],
'php_check_syntax' => ['bool', 'filename'=>'string', 'error_message='=>'string'],
'php_ini_loaded_file' => ['string|false'],
'php_ini_scanned_files' => ['string|false'],
'php_logo_guid' => ['string'],
'php_sapi_name' => ['string'],
'php_strip_whitespace' => ['string', 'filename'=>'string'],
'php_uname' => ['string', 'mode='=>'string'],
'php_user_filter::filter' => ['int', 'in'=>'resource', 'out'=>'resource', '&rw_consumed'=>'int', 'closing'=>'bool'],
'php_user_filter::onClose' => ['void'],
'php_user_filter::onCreate' => ['bool'],
'phpcredits' => ['bool', 'flags='=>'int'],
'phpdbg_break_file' => ['void', 'file'=>'string', 'line'=>'int'],
'phpdbg_break_function' => ['void', 'function'=>'string'],
'phpdbg_break_method' => ['void', 'class'=>'string', 'method'=>'string'],
'phpdbg_break_next' => ['void'],
'phpdbg_clear' => ['void'],
'phpdbg_color' => ['void', 'element'=>'int', 'color'=>'string'],
'phpdbg_end_oplog' => ['array', 'options='=>'array'],
'phpdbg_exec' => ['mixed', 'context='=>'string'],
'phpdbg_get_executable' => ['array', 'options='=>'array'],
'phpdbg_prompt' => ['void', 'string'=>'string'],
'phpdbg_start_oplog' => ['void'],
'phpinfo' => ['bool', 'flags='=>'int'],
'PhpToken::tokenize' => ['list<PhpToken>', 'code'=>'string', 'flags='=>'int'],
'PhpToken::is' => ['bool', 'kind'=>'string|int|string[]|int[]'],
'PhpToken::isIgnorable' => ['bool'],
'PhpToken::getTokenName' => ['?string'],
'phpversion' => ['string|false', 'extension='=>'?string'],
'pht\AtomicInteger::__construct' => ['void', 'value='=>'int'],
'pht\AtomicInteger::dec' => ['void'],
'pht\AtomicInteger::get' => ['int'],
'pht\AtomicInteger::inc' => ['void'],
'pht\AtomicInteger::lock' => ['void'],
'pht\AtomicInteger::set' => ['void', 'value'=>'int'],
'pht\AtomicInteger::unlock' => ['void'],
'pht\HashTable::lock' => ['void'],
'pht\HashTable::size' => ['int'],
'pht\HashTable::unlock' => ['void'],
'pht\Queue::front' => ['mixed'],
'pht\Queue::lock' => ['void'],
'pht\Queue::pop' => ['mixed'],
'pht\Queue::push' => ['void', 'value'=>'mixed'],
'pht\Queue::size' => ['int'],
'pht\Queue::unlock' => ['void'],
'pht\Runnable::run' => ['void'],
'pht\thread::addClassTask' => ['void', 'className'=>'string', '...ctorArgs='=>'mixed'],
'pht\thread::addFileTask' => ['void', 'fileName'=>'string', '...globals='=>'mixed'],
'pht\thread::addFunctionTask' => ['void', 'func'=>'callable', '...funcArgs='=>'mixed'],
'pht\thread::join' => ['void'],
'pht\thread::start' => ['void'],
'pht\thread::taskCount' => ['int'],
'pht\threaded::lock' => ['void'],
'pht\threaded::unlock' => ['void'],
'pht\Vector::__construct' => ['void', 'size='=>'int', 'value='=>'mixed'],
'pht\Vector::deleteAt' => ['void', 'offset'=>'int'],
'pht\Vector::insertAt' => ['void', 'value'=>'mixed', 'offset'=>'int'],
'pht\Vector::lock' => ['void'],
'pht\Vector::pop' => ['mixed'],
'pht\Vector::push' => ['void', 'value'=>'mixed'],
'pht\Vector::resize' => ['void', 'size'=>'int', 'value='=>'mixed'],
'pht\Vector::shift' => ['mixed'],
'pht\Vector::size' => ['int'],
'pht\Vector::unlock' => ['void'],
'pht\Vector::unshift' => ['void', 'value'=>'mixed'],
'pht\Vector::updateAt' => ['void', 'value'=>'mixed', 'offset'=>'int'],
'pi' => ['float'],
'pointObj::__construct' => ['void'],
'pointObj::distanceToLine' => ['float', 'p1'=>'pointObj', 'p2'=>'pointObj'],
'pointObj::distanceToPoint' => ['float', 'poPoint'=>'pointObj'],
'pointObj::distanceToShape' => ['float', 'shape'=>'shapeObj'],
'pointObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'],
'pointObj::ms_newPointObj' => ['pointObj'],
'pointObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
'pointObj::setXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'],
'pointObj::setXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'],
'Pool::__construct' => ['void', 'size'=>'int', 'class'=>'string', 'ctor='=>'array'],
'Pool::collect' => ['int', 'collector='=>'Callable'],
'Pool::resize' => ['void', 'size'=>'int'],
'Pool::shutdown' => ['void'],
'Pool::submit' => ['int', 'task'=>'Threaded'],
'Pool::submitTo' => ['int', 'worker'=>'int', 'task'=>'Threaded'],
'popen' => ['resource|false', 'command'=>'string', 'mode'=>'string'],
'pos' => ['mixed', 'array'=>'array'],
'posix_access' => ['bool', 'filename'=>'string', 'flags='=>'int'],
'posix_ctermid' => ['string|false'],
'posix_errno' => ['int'],
'posix_get_last_error' => ['int'],
'posix_getcwd' => ['string|false'],
'posix_getegid' => ['int'],
'posix_geteuid' => ['int'],
'posix_getgid' => ['int'],
'posix_getgrgid' => ['array{name: string, passwd: string, gid: int, members: list<string>}|false', 'group_id'=>'int'],
'posix_getgrnam' => ['array{name: string, passwd: string, gid: int, members: list<string>}|false', 'name'=>'string'],
'posix_getgroups' => ['list<int>|false'],
'posix_getlogin' => ['string|false'],
'posix_getpgid' => ['int|false', 'process_id'=>'int'],
'posix_getpgrp' => ['int'],
'posix_getpid' => ['int'],
'posix_getppid' => ['int'],
'posix_getpwnam' => ['array{name: string, passwd: string, uid: int, gid: int, gecos: string, dir: string, shell: string}|false', 'username'=>'string'],
'posix_getpwuid' => ['array{name: string, passwd: string, uid: int, gid: int, gecos: string, dir: string, shell: string}|false', 'user_id'=>'int'],
'posix_getrlimit' => ['array{"soft core": string, "hard core": string, "soft data": string, "hard data": string, "soft stack": integer, "hard stack": string, "soft totalmem": string, "hard totalmem": string, "soft rss": string, "hard rss": string, "soft maxproc": integer, "hard maxproc": integer, "soft memlock": integer, "hard memlock": integer, "soft cpu": string, "hard cpu": string, "soft filesize": string, "hard filesize": string, "soft openfiles": integer, "hard openfiles": integer}|false'],
'posix_getsid' => ['int|false', 'process_id'=>'int'],
'posix_getuid' => ['int'],
'posix_initgroups' => ['bool', 'username'=>'string', 'group_id'=>'int'],
'posix_isatty' => ['bool', 'file_descriptor'=>'resource|int'],
'posix_kill' => ['bool', 'process_id'=>'int', 'signal'=>'int'],
'posix_mkfifo' => ['bool', 'filename'=>'string', 'permissions'=>'int'],
'posix_mknod' => ['bool', 'filename'=>'string', 'flags'=>'int', 'major='=>'int', 'minor='=>'int'],
'posix_setegid' => ['bool', 'group_id'=>'int'],
'posix_seteuid' => ['bool', 'user_id'=>'int'],
'posix_setgid' => ['bool', 'group_id'=>'int'],
'posix_setpgid' => ['bool', 'process_id'=>'int', 'process_group_id'=>'int'],
'posix_setrlimit' => ['bool', 'resource'=>'int', 'soft_limit'=>'int', 'hard_limit'=>'int'],
'posix_setsid' => ['int'],
'posix_setuid' => ['bool', 'user_id'=>'int'],
'posix_strerror' => ['string', 'error_code'=>'int'],
'posix_times' => ['array{ticks: int, utime: int, stime: int, cutime: int, cstime: int}|false'],
'posix_ttyname' => ['string|false', 'file_descriptor'=>'resource|int'],
'posix_uname' => ['array{sysname: string, nodename: string, release: string, version: string, machine: string, domainname: string}|false'],
'Postal\Expand::expand_address' => ['string[]', 'address'=>'string', 'options='=>'array<string, mixed>'],
'Postal\Parser::parse_address' => ['array<string,string>', 'address'=>'string', 'options='=>'array<string, string>'],
'pow' => ['float|int', 'num'=>'int|float', 'exponent'=>'int|float'],
'preg_filter' => ['null|string|string[]', 'pattern'=>'mixed', 'replacement'=>'mixed', 'subject'=>'mixed', 'limit='=>'int', '&w_count='=>'int'],
'preg_grep' => ['array|false', 'pattern'=>'string', 'array'=>'array', 'flags='=>'int'],
'preg_last_error' => ['int'],
'preg_match' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_matches='=>'string[]', 'flags='=>'0', 'offset='=>'int'],
'preg_match\'1' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_matches='=>'array', 'flags='=>'int', 'offset='=>'int'],
'preg_match_all' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_matches='=>'array', 'flags='=>'int', 'offset='=>'int'],
'preg_quote' => ['string', 'str'=>'string', 'delimiter='=>'?string'],
'preg_replace' => ['string|string[]|null', 'pattern'=>'string|array', 'replacement'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_replace_callback' => ['string|null', 'pattern'=>'string|array', 'callback'=>'callable(string[]):string', 'subject'=>'string', 'limit='=>'int', '&w_count='=>'int'],
'preg_replace_callback\'1' => ['string[]|null', 'pattern'=>'string|array', 'callback'=>'callable(string[]):string', 'subject'=>'string[]', 'limit='=>'int', '&w_count='=>'int'],
'preg_replace_callback_array' => ['string|string[]|null', 'pattern'=>'array<string,callable(array):string>', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_split' => ['list<string>|false', 'pattern'=>'string', 'subject'=>'string', 'limit'=>'int', 'flags='=>'null'],
'preg_split\'1' => ['list<string>|list<list<string|int>>|false', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'int', 'flags='=>'int'],
'prev' => ['mixed', '&r_array'=>'array|object'],
'print' => ['int', 'arg'=>'string'],
'print_r' => ['string', 'value'=>'mixed'],
'print_r\'1' => ['true', 'value'=>'mixed', 'return='=>'bool'],
'printf' => ['int', 'format'=>'string', '...values='=>'string|int|float'],
'proc_close' => ['int', 'process'=>'resource'],
'proc_get_status' => ['array{command: string, pid: int, running: bool, signaled: bool, stopped: bool, exitcode: int, termsig: int, stopsig: int}', 'process'=>'resource'],
'proc_nice' => ['bool', 'priority'=>'int'],
'proc_open' => ['resource|false', 'command'=>'string|array', 'descriptor_spec'=>'array', '&pipes'=>'resource[]', 'cwd='=>'?string', 'env_vars='=>'?array', 'options='=>'?array'],
'proc_terminate' => ['bool', 'process'=>'resource', 'signal='=>'int'],
'projectionObj::__construct' => ['void', 'projectionString'=>'string'],
'projectionObj::getUnits' => ['int'],
'projectionObj::ms_newProjectionObj' => ['projectionObj', 'projectionString'=>'string'],
'property_exists' => ['bool', 'object_or_class'=>'object|string', 'property'=>'string'],
'ps_add_bookmark' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'parent='=>'int', 'open='=>'int'],
'ps_add_launchlink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'],
'ps_add_locallink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'page'=>'int', 'dest'=>'string'],
'ps_add_note' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'],
'ps_add_pdflink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'],
'ps_add_weblink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'url'=>'string'],
'ps_arc' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'],
'ps_arcn' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'],
'ps_begin_page' => ['bool', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
'ps_begin_pattern' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'],
'ps_begin_template' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'],
'ps_circle' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float'],
'ps_clip' => ['bool', 'psdoc'=>'resource'],
'ps_close' => ['bool', 'psdoc'=>'resource'],
'ps_close_image' => ['void', 'psdoc'=>'resource', 'imageid'=>'int'],
'ps_closepath' => ['bool', 'psdoc'=>'resource'],
'ps_closepath_stroke' => ['bool', 'psdoc'=>'resource'],
'ps_continue_text' => ['bool', 'psdoc'=>'resource', 'text'=>'string'],
'ps_curveto' => ['bool', 'psdoc'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
'ps_delete' => ['bool', 'psdoc'=>'resource'],
'ps_end_page' => ['bool', 'psdoc'=>'resource'],
'ps_end_pattern' => ['bool', 'psdoc'=>'resource'],
'ps_end_template' => ['bool', 'psdoc'=>'resource'],
'ps_fill' => ['bool', 'psdoc'=>'resource'],
'ps_fill_stroke' => ['bool', 'psdoc'=>'resource'],
'ps_findfont' => ['int', 'psdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed='=>'bool'],
'ps_get_buffer' => ['string', 'psdoc'=>'resource'],
'ps_get_parameter' => ['string', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'],
'ps_get_value' => ['float', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'],
'ps_hyphenate' => ['array', 'psdoc'=>'resource', 'text'=>'string'],
'ps_include_file' => ['bool', 'psdoc'=>'resource', 'file'=>'string'],
'ps_lineto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
'ps_makespotcolor' => ['int', 'psdoc'=>'resource', 'name'=>'string', 'reserved='=>'int'],
'ps_moveto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
'ps_new' => ['resource'],
'ps_open_file' => ['bool', 'psdoc'=>'resource', 'filename='=>'string'],
'ps_open_image' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'],
'ps_open_image_file' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'filename'=>'string', 'stringparam='=>'string', 'intparam='=>'int'],
'ps_open_memory_image' => ['int', 'psdoc'=>'resource', 'gd'=>'int'],
'ps_place_image' => ['bool', 'psdoc'=>'resource', 'imageid'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'],
'ps_rect' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'],
'ps_restore' => ['bool', 'psdoc'=>'resource'],
'ps_rotate' => ['bool', 'psdoc'=>'resource', 'rot'=>'float'],
'ps_save' => ['bool', 'psdoc'=>'resource'],
'ps_scale' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
'ps_set_border_color' => ['bool', 'psdoc'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'],
'ps_set_border_dash' => ['bool', 'psdoc'=>'resource', 'black'=>'float', 'white'=>'float'],
'ps_set_border_style' => ['bool', 'psdoc'=>'resource', 'style'=>'string', 'width'=>'float'],
'ps_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'],
'ps_set_parameter' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'string'],
'ps_set_text_pos' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
'ps_set_value' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'float'],
'ps_setcolor' => ['bool', 'psdoc'=>'resource', 'type'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'],
'ps_setdash' => ['bool', 'psdoc'=>'resource', 'on'=>'float', 'off'=>'float'],
'ps_setflat' => ['bool', 'psdoc'=>'resource', 'value'=>'float'],
'ps_setfont' => ['bool', 'psdoc'=>'resource', 'fontid'=>'int', 'size'=>'float'],
'ps_setgray' => ['bool', 'psdoc'=>'resource', 'gray'=>'float'],
'ps_setlinecap' => ['bool', 'psdoc'=>'resource', 'type'=>'int'],
'ps_setlinejoin' => ['bool', 'psdoc'=>'resource', 'type'=>'int'],
'ps_setlinewidth' => ['bool', 'psdoc'=>'resource', 'width'=>'float'],
'ps_setmiterlimit' => ['bool', 'psdoc'=>'resource', 'value'=>'float'],
'ps_setoverprintmode' => ['bool', 'psdoc'=>'resource', 'mode'=>'int'],
'ps_setpolydash' => ['bool', 'psdoc'=>'resource', 'arr'=>'float'],
'ps_shading' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'],
'ps_shading_pattern' => ['int', 'psdoc'=>'resource', 'shadingid'=>'int', 'optlist'=>'string'],
'ps_shfill' => ['bool', 'psdoc'=>'resource', 'shadingid'=>'int'],
'ps_show' => ['bool', 'psdoc'=>'resource', 'text'=>'string'],
'ps_show2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'length'=>'int'],
'ps_show_boxed' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'left'=>'float', 'bottom'=>'float', 'width'=>'float', 'height'=>'float', 'hmode'=>'string', 'feature='=>'string'],
'ps_show_xy' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'],
'ps_show_xy2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'length'=>'int', 'xcoor'=>'float', 'ycoor'=>'float'],
'ps_string_geometry' => ['array', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'],
'ps_stringwidth' => ['float', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'],
'ps_stroke' => ['bool', 'psdoc'=>'resource'],
'ps_symbol' => ['bool', 'psdoc'=>'resource', 'ord'=>'int'],
'ps_symbol_name' => ['string', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int'],
'ps_symbol_width' => ['float', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int', 'size='=>'float'],
'ps_translate' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'],
'pspell_add_to_personal' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
'pspell_add_to_session' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
'pspell_check' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
'pspell_clear_session' => ['bool', 'dictionary'=>'PSpell\Dictionary'],
'pspell_config_create' => ['PSpell\Config', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string'],
'pspell_config_data_dir' => ['bool', 'config'=>'PSpell\Config', 'directory'=>'string'],
'pspell_config_dict_dir' => ['bool', 'config'=>'PSpell\Config', 'directory'=>'string'],
'pspell_config_ignore' => ['bool', 'config'=>'PSpell\Config', 'min_length'=>'int'],
'pspell_config_mode' => ['bool', 'config'=>'PSpell\Config', 'mode'=>'int'],
'pspell_config_personal' => ['bool', 'config'=>'PSpell\Config', 'filename'=>'string'],
'pspell_config_repl' => ['bool', 'config'=>'PSpell\Config', 'filename'=>'string'],
'pspell_config_runtogether' => ['bool', 'config'=>'PSpell\Config', 'allow'=>'bool'],
'pspell_config_save_repl' => ['bool', 'config'=>'PSpell\Config', 'save'=>'bool'],
'pspell_new' => ['PSpell\Dictionary|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
'pspell_new_config' => ['PSpell\Dictionary|false', 'config'=>'PSpell\Config'],
'pspell_new_personal' => ['PSpell\Dictionary|false', 'filename'=>'string', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
'pspell_save_wordlist' => ['bool', 'dictionary'=>'PSpell\Dictionary'],
'pspell_store_replacement' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'misspelled'=>'string', 'correct'=>'string'],
'pspell_suggest' => ['array', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
'putenv' => ['bool', 'assignment'=>'string'],
'px_close' => ['bool', 'pxdoc'=>'resource'],
'px_create_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource', 'fielddesc'=>'array'],
'px_date2string' => ['string', 'pxdoc'=>'resource', 'value'=>'int', 'format'=>'string'],
'px_delete' => ['bool', 'pxdoc'=>'resource'],
'px_delete_record' => ['bool', 'pxdoc'=>'resource', 'num'=>'int'],
'px_get_field' => ['array', 'pxdoc'=>'resource', 'fieldno'=>'int'],
'px_get_info' => ['array', 'pxdoc'=>'resource'],
'px_get_parameter' => ['string', 'pxdoc'=>'resource', 'name'=>'string'],
'px_get_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'],
'px_get_schema' => ['array', 'pxdoc'=>'resource', 'mode='=>'int'],
'px_get_value' => ['float', 'pxdoc'=>'resource', 'name'=>'string'],
'px_insert_record' => ['int', 'pxdoc'=>'resource', 'data'=>'array'],
'px_new' => ['resource'],
'px_numfields' => ['int', 'pxdoc'=>'resource'],
'px_numrecords' => ['int', 'pxdoc'=>'resource'],
'px_open_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource'],
'px_put_record' => ['bool', 'pxdoc'=>'resource', 'record'=>'array', 'recpos='=>'int'],
'px_retrieve_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'],
'px_set_blob_file' => ['bool', 'pxdoc'=>'resource', 'filename'=>'string'],
'px_set_parameter' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'string'],
'px_set_tablename' => ['void', 'pxdoc'=>'resource', 'name'=>'string'],
'px_set_targetencoding' => ['bool', 'pxdoc'=>'resource', 'encoding'=>'string'],
'px_set_value' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'float'],
'px_timestamp2string' => ['string', 'pxdoc'=>'resource', 'value'=>'float', 'format'=>'string'],
'px_update_record' => ['bool', 'pxdoc'=>'resource', 'data'=>'array', 'num'=>'int'],
'qdom_error' => ['string'],
'qdom_tree' => ['QDomDocument', 'doc'=>'string'],
'querymapObj::convertToString' => ['string'],
'querymapObj::free' => ['void'],
'querymapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'querymapObj::updateFromString' => ['int', 'snippet'=>'string'],
'QuickHashIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
'QuickHashIntHash::add' => ['bool', 'key'=>'int', 'value='=>'int'],
'QuickHashIntHash::delete' => ['bool', 'key'=>'int'],
'QuickHashIntHash::exists' => ['bool', 'key'=>'int'],
'QuickHashIntHash::get' => ['int', 'key'=>'int'],
'QuickHashIntHash::getSize' => ['int'],
'QuickHashIntHash::loadFromFile' => ['QuickHashIntHash', 'filename'=>'string', 'options='=>'int'],
'QuickHashIntHash::loadFromString' => ['QuickHashIntHash', 'contents'=>'string', 'options='=>'int'],
'QuickHashIntHash::saveToFile' => ['void', 'filename'=>'string'],
'QuickHashIntHash::saveToString' => ['string'],
'QuickHashIntHash::set' => ['bool', 'key'=>'int', 'value'=>'int'],
'QuickHashIntHash::update' => ['bool', 'key'=>'int', 'value'=>'int'],
'QuickHashIntSet::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
'QuickHashIntSet::add' => ['bool', 'key'=>'int'],
'QuickHashIntSet::delete' => ['bool', 'key'=>'int'],
'QuickHashIntSet::exists' => ['bool', 'key'=>'int'],
'QuickHashIntSet::getSize' => ['int'],
'QuickHashIntSet::loadFromFile' => ['QuickHashIntSet', 'filename'=>'string', 'size='=>'int', 'options='=>'int'],
'QuickHashIntSet::loadFromString' => ['QuickHashIntSet', 'contents'=>'string', 'size='=>'int', 'options='=>'int'],
'QuickHashIntSet::saveToFile' => ['void', 'filename'=>'string'],
'QuickHashIntSet::saveToString' => ['string'],
'QuickHashIntStringHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
'QuickHashIntStringHash::add' => ['bool', 'key'=>'int', 'value'=>'string'],
'QuickHashIntStringHash::delete' => ['bool', 'key'=>'int'],
'QuickHashIntStringHash::exists' => ['bool', 'key'=>'int'],
'QuickHashIntStringHash::get' => ['mixed', 'key'=>'int'],
'QuickHashIntStringHash::getSize' => ['int'],
'QuickHashIntStringHash::loadFromFile' => ['QuickHashIntStringHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'],
'QuickHashIntStringHash::loadFromString' => ['QuickHashIntStringHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'],
'QuickHashIntStringHash::saveToFile' => ['void', 'filename'=>'string'],
'QuickHashIntStringHash::saveToString' => ['string'],
'QuickHashIntStringHash::set' => ['int', 'key'=>'int', 'value'=>'string'],
'QuickHashIntStringHash::update' => ['bool', 'key'=>'int', 'value'=>'string'],
'QuickHashStringIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'],
'QuickHashStringIntHash::add' => ['bool', 'key'=>'string', 'value'=>'int'],
'QuickHashStringIntHash::delete' => ['bool', 'key'=>'string'],
'QuickHashStringIntHash::exists' => ['bool', 'key'=>'string'],
'QuickHashStringIntHash::get' => ['mixed', 'key'=>'string'],
'QuickHashStringIntHash::getSize' => ['int'],
'QuickHashStringIntHash::loadFromFile' => ['QuickHashStringIntHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'],
'QuickHashStringIntHash::loadFromString' => ['QuickHashStringIntHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'],
'QuickHashStringIntHash::saveToFile' => ['void', 'filename'=>'string'],
'QuickHashStringIntHash::saveToString' => ['string'],
'QuickHashStringIntHash::set' => ['int', 'key'=>'string', 'value'=>'int'],
'QuickHashStringIntHash::update' => ['bool', 'key'=>'string', 'value'=>'int'],
'quoted_printable_decode' => ['string', 'string'=>'string'],
'quoted_printable_encode' => ['string', 'string'=>'string'],
'quotemeta' => ['string', 'string'=>'string'],
'rad2deg' => ['float', 'num'=>'float'],
'radius_acct_open' => ['resource|false'],
'radius_add_server' => ['bool', 'radius_handle'=>'resource', 'hostname'=>'string', 'port'=>'int', 'secret'=>'string', 'timeout'=>'int', 'max_tries'=>'int'],
'radius_auth_open' => ['resource|false'],
'radius_close' => ['bool', 'radius_handle'=>'resource'],
'radius_config' => ['bool', 'radius_handle'=>'resource', 'file'=>'string'],
'radius_create_request' => ['bool', 'radius_handle'=>'resource', 'type'=>'int'],
'radius_cvt_addr' => ['string', 'data'=>'string'],
'radius_cvt_int' => ['int', 'data'=>'string'],
'radius_cvt_string' => ['string', 'data'=>'string'],
'radius_demangle' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'],
'radius_demangle_mppe_key' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'],
'radius_get_attr' => ['mixed', 'radius_handle'=>'resource'],
'radius_get_tagged_attr_data' => ['string', 'data'=>'string'],
'radius_get_tagged_attr_tag' => ['int', 'data'=>'string'],
'radius_get_vendor_attr' => ['array', 'data'=>'string'],
'radius_put_addr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'addr'=>'string'],
'radius_put_attr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'],
'radius_put_int' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'int'],
'radius_put_string' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'],
'radius_put_vendor_addr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'addr'=>'string'],
'radius_put_vendor_attr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'],
'radius_put_vendor_int' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'int'],
'radius_put_vendor_string' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'],
'radius_request_authenticator' => ['string', 'radius_handle'=>'resource'],
'radius_salt_encrypt_attr' => ['string', 'radius_handle'=>'resource', 'data'=>'string'],
'radius_send_request' => ['int|false', 'radius_handle'=>'resource'],
'radius_server_secret' => ['string', 'radius_handle'=>'resource'],
'radius_strerror' => ['string', 'radius_handle'=>'resource'],
'rand' => ['int', 'min'=>'int', 'max'=>'int'],
'rand\'1' => ['int'],
'random_bytes' => ['non-empty-string', 'length'=>'positive-int'],
'random_int' => ['int', 'min'=>'int', 'max'=>'int'],
'range' => ['array', 'start'=>'mixed', 'end'=>'mixed', 'step='=>'int|float'],
'RangeException::__clone' => ['void'],
'RangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'RangeException::__toString' => ['string'],
'RangeException::getCode' => ['int'],
'RangeException::getFile' => ['string'],
'RangeException::getLine' => ['int'],
'RangeException::getMessage' => ['string'],
'RangeException::getPrevious' => ['?Throwable'],
'RangeException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'RangeException::getTraceAsString' => ['string'],
'rar_allow_broken_set' => ['bool', 'rarfile'=>'RarArchive', 'allow_broken'=>'bool'],
'rar_broken_is' => ['bool', 'rarfile'=>'rararchive'],
'rar_close' => ['bool', 'rarfile'=>'rararchive'],
'rar_comment_get' => ['string', 'rarfile'=>'rararchive'],
'rar_entry_get' => ['RarEntry', 'rarfile'=>'RarArchive', 'entryname'=>'string'],
'rar_list' => ['RarArchive', 'rarfile'=>'rararchive'],
'rar_open' => ['RarArchive', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'],
'rar_solid_is' => ['bool', 'rarfile'=>'rararchive'],
'rar_wrapper_cache_stats' => ['string'],
'RarArchive::__toString' => ['string'],
'RarArchive::close' => ['bool'],
'RarArchive::getComment' => ['string|null'],
'RarArchive::getEntries' => ['RarEntry[]|false'],
'RarArchive::getEntry' => ['RarEntry|false', 'entryname'=>'string'],
'RarArchive::isBroken' => ['bool'],
'RarArchive::isSolid' => ['bool'],
'RarArchive::open' => ['RarArchive|false', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'],
'RarArchive::setAllowBroken' => ['bool', 'allow_broken'=>'bool'],
'RarEntry::__toString' => ['string'],
'RarEntry::extract' => ['bool', 'dir'=>'string', 'filepath='=>'string', 'password='=>'string', 'extended_data='=>'bool'],
'RarEntry::getAttr' => ['int|false'],
'RarEntry::getCrc' => ['string|false'],
'RarEntry::getFileTime' => ['string|false'],
'RarEntry::getHostOs' => ['int|false'],
'RarEntry::getMethod' => ['int|false'],
'RarEntry::getName' => ['string|false'],
'RarEntry::getPackedSize' => ['int|false'],
'RarEntry::getStream' => ['resource|false', 'password='=>'string'],
'RarEntry::getUnpackedSize' => ['int|false'],
'RarEntry::getVersion' => ['int|false'],
'RarEntry::isDirectory' => ['bool'],
'RarEntry::isEncrypted' => ['bool'],
'RarException::getCode' => ['int'],
'RarException::getFile' => ['string'],
'RarException::getLine' => ['int'],
'RarException::getMessage' => ['string'],
'RarException::getPrevious' => ['Exception|Throwable'],
'RarException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'RarException::getTraceAsString' => ['string'],
'RarException::isUsingExceptions' => ['bool'],
'RarException::setUsingExceptions' => ['RarEntry', 'using_exceptions'=>'bool'],
'rawurldecode' => ['string', 'string'=>'string'],
'rawurlencode' => ['string', 'string'=>'string'],
'rd_kafka_err2str' => ['string', 'err'=>'int'],
'rd_kafka_errno' => ['int'],
'rd_kafka_errno2err' => ['int', 'errnox'=>'int'],
'rd_kafka_offset_tail' => ['int', 'cnt'=>'int'],
'RdKafka::addBrokers' => ['int', 'broker_list'=>'string'],
'RdKafka::flush' => ['int', 'timeout_ms'=>'int'],
'RdKafka::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\Topic', 'timeout_ms'=>'int'],
'RdKafka::getOutQLen' => ['int'],
'RdKafka::newQueue' => ['RdKafka\Queue'],
'RdKafka::newTopic' => ['RdKafka\Topic', 'topic_name'=>'string', 'topic_conf='=>'?RdKafka\TopicConf'],
'RdKafka::poll' => ['void', 'timeout_ms'=>'int'],
'RdKafka::setLogLevel' => ['void', 'level'=>'int'],
'RdKafka\Conf::dump' => ['array<string, string>'],
'RdKafka\Conf::set' => ['void', 'name'=>'string', 'value'=>'string'],
'RdKafka\Conf::setDefaultTopicConf' => ['void', 'topic_conf'=>'RdKafka\TopicConf'],
'RdKafka\Conf::setDrMsgCb' => ['void', 'callback'=>'callable'],
'RdKafka\Conf::setErrorCb' => ['void', 'callback'=>'callable'],
'RdKafka\Conf::setRebalanceCb' => ['void', 'callback'=>'callable'],
'RdKafka\Conf::setStatsCb' => ['void', 'callback'=>'callable'],
'RdKafka\Consumer::__construct' => ['void', 'conf='=>'?RdKafka\Conf'],
'RdKafka\Consumer::addBrokers' => ['int', 'broker_list'=>'string'],
'RdKafka\Consumer::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\Topic', 'timeout_ms'=>'int'],
'RdKafka\Consumer::getOutQLen' => ['int'],
'RdKafka\Consumer::newQueue' => ['RdKafka\Queue'],
'RdKafka\Consumer::newTopic' => ['RdKafka\ConsumerTopic', 'topic_name'=>'string', 'topic_conf='=>'?RdKafka\TopicConf'],
'RdKafka\Consumer::poll' => ['void', 'timeout_ms'=>'int'],
'RdKafka\Consumer::setLogLevel' => ['void', 'level'=>'int'],
'RdKafka\ConsumerTopic::__construct' => ['void'],
'RdKafka\ConsumerTopic::consume' => ['RdKafka\Message', 'partition'=>'int', 'timeout_ms'=>'int'],
'RdKafka\ConsumerTopic::consumeQueueStart' => ['void', 'partition'=>'int', 'offset'=>'int', 'queue'=>'RdKafka\Queue'],
'RdKafka\ConsumerTopic::consumeStart' => ['void', 'partition'=>'int', 'offset'=>'int'],
'RdKafka\ConsumerTopic::consumeStop' => ['void', 'partition'=>'int'],
'RdKafka\ConsumerTopic::getName' => ['string'],
'RdKafka\ConsumerTopic::offsetStore' => ['void', 'partition'=>'int', 'offset'=>'int'],
'RdKafka\KafkaConsumer::__construct' => ['void', 'conf'=>'RdKafka\Conf'],
'RdKafka\KafkaConsumer::assign' => ['void', 'topic_partitions='=>'RdKafka\TopicPartition[]|null'],
'RdKafka\KafkaConsumer::commit' => ['void', 'message_or_offsets='=>'RdKafka\Message|RdKafka\TopicPartition[]|null'],
'RdKafka\KafkaConsumer::commitAsync' => ['void', 'message_or_offsets='=>'RdKafka\Message|RdKafka\TopicPartition[]|null'],
'RdKafka\KafkaConsumer::consume' => ['RdKafka\Message', 'timeout_ms'=>'int'],
'RdKafka\KafkaConsumer::getAssignment' => ['RdKafka\TopicPartition[]'],
'RdKafka\KafkaConsumer::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\KafkaConsumerTopic', 'timeout_ms'=>'int'],
'RdKafka\KafkaConsumer::getSubscription' => ['array'],
'RdKafka\KafkaConsumer::subscribe' => ['void', 'topics'=>'array'],
'RdKafka\KafkaConsumer::unsubscribe' => ['void'],
'RdKafka\KafkaConsumerTopic::getName' => ['string'],
'RdKafka\KafkaConsumerTopic::offsetStore' => ['void', 'partition'=>'int', 'offset'=>'int'],
'RdKafka\Message::errstr' => ['string'],
'RdKafka\Metadata::getBrokers' => ['RdKafka\Metadata\Collection'],
'RdKafka\Metadata::getOrigBrokerId' => ['int'],
'RdKafka\Metadata::getOrigBrokerName' => ['string'],
'RdKafka\Metadata::getTopics' => ['RdKafka\Metadata\Collection|RdKafka\Metadata\Topic[]'],
'RdKafka\Metadata\Collection::__construct' => ['void'],
'RdKafka\Metadata\Collection::count' => ['int'],
'RdKafka\Metadata\Collection::current' => ['mixed'],
'RdKafka\Metadata\Collection::key' => ['mixed'],
'RdKafka\Metadata\Collection::next' => ['void'],
'RdKafka\Metadata\Collection::rewind' => ['void'],
'RdKafka\Metadata\Collection::valid' => ['bool'],
'RdKafka\Metadata\Partition::getErr' => ['mixed'],
'RdKafka\Metadata\Partition::getId' => ['int'],
'RdKafka\Metadata\Partition::getIsrs' => ['mixed'],
'RdKafka\Metadata\Partition::getLeader' => ['mixed'],
'RdKafka\Metadata\Partition::getReplicas' => ['mixed'],
'RdKafka\Metadata\Topic::getErr' => ['mixed'],
'RdKafka\Metadata\Topic::getPartitions' => ['RdKafka\Metadata\Partition[]'],
'RdKafka\Metadata\Topic::getTopic' => ['string'],
'RdKafka\Producer::__construct' => ['void', 'conf='=>'?RdKafka\Conf'],
'RdKafka\Producer::addBrokers' => ['int', 'broker_list'=>'string'],
'RdKafka\Producer::getMetadata' => ['RdKafka\Metadata', 'all_topics'=>'bool', 'only_topic='=>'?RdKafka\Topic', 'timeout_ms'=>'int'],
'RdKafka\Producer::getOutQLen' => ['int'],
'RdKafka\Producer::newQueue' => ['RdKafka\Queue'],
'RdKafka\Producer::newTopic' => ['RdKafka\ProducerTopic', 'topic_name'=>'string', 'topic_conf='=>'?RdKafka\TopicConf'],
'RdKafka\Producer::poll' => ['void', 'timeout_ms'=>'int'],
'RdKafka\Producer::setLogLevel' => ['void', 'level'=>'int'],
'RdKafka\ProducerTopic::__construct' => ['void'],
'RdKafka\ProducerTopic::getName' => ['string'],
'RdKafka\ProducerTopic::produce' => ['void', 'partition'=>'int', 'msgflags'=>'int', 'payload'=>'string', 'key='=>'?string'],
'RdKafka\ProducerTopic::producev' => ['void', 'partition'=>'int', 'msgflags'=>'int', 'payload'=>'string', 'key='=>'?string', 'headers='=>'?array<string, string>', 'timestamp_ms='=>'?int', 'opaque='=>'?string'],
'RdKafka\Queue::__construct' => ['void'],
'RdKafka\Queue::consume' => ['?RdKafka\Message', 'timeout_ms'=>'string'],
'RdKafka\Topic::getName' => ['string'],
'RdKafka\TopicConf::dump' => ['array<string, string>'],
'RdKafka\TopicConf::set' => ['void', 'name'=>'string', 'value'=>'string'],
'RdKafka\TopicConf::setPartitioner' => ['void', 'partitioner'=>'int'],
'RdKafka\TopicPartition::__construct' => ['void', 'topic'=>'string', 'partition'=>'int', 'offset='=>'int'],
'RdKafka\TopicPartition::getOffset' => ['int'],
'RdKafka\TopicPartition::getPartition' => ['int'],
'RdKafka\TopicPartition::getTopic' => ['string'],
'RdKafka\TopicPartition::setOffset' => ['void', 'offset'=>'string'],
'RdKafka\TopicPartition::setPartition' => ['void', 'partition'=>'string'],
'RdKafka\TopicPartition::setTopic' => ['void', 'topic_name'=>'string'],
'readdir' => ['string|false', 'dir_handle='=>'resource'],
'readfile' => ['int|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
'readgzfile' => ['int|false', 'filename'=>'string', 'use_include_path='=>'int'],
'readline' => ['string|false', 'prompt='=>'?string'],
'readline_add_history' => ['bool', 'prompt'=>'string'],
'readline_callback_handler_install' => ['bool', 'prompt'=>'string', 'callback'=>'callable'],
'readline_callback_handler_remove' => ['bool'],
'readline_callback_read_char' => ['void'],
'readline_clear_history' => ['bool'],
'readline_completion_function' => ['bool', 'callback'=>'callable'],
'readline_info' => ['mixed', 'var_name='=>'?string', 'value='=>'string|int|bool|null'],
'readline_list_history' => ['array'],
'readline_on_new_line' => ['void'],
'readline_read_history' => ['bool', 'filename='=>'?string'],
'readline_redisplay' => ['void'],
'readline_write_history' => ['bool', 'filename='=>'?string'],
'readlink' => ['string|false', 'path'=>'string'],
'realpath' => ['string|false', 'path'=>'string'],
'realpath_cache_get' => ['array'],
'realpath_cache_size' => ['int'],
'recode' => ['string', 'request'=>'string', 'string'=>'string'],
'recode_file' => ['bool', 'request'=>'string', 'input'=>'resource', 'output'=>'resource'],
'recode_string' => ['string|false', 'request'=>'string', 'string'=>'string'],
'rectObj::__construct' => ['void'],
'rectObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'],
'rectObj::fit' => ['float', 'width'=>'int', 'height'=>'int'],
'rectObj::ms_newRectObj' => ['rectObj'],
'rectObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
'rectObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'rectObj::setextent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'],
'RecursiveArrayIterator::__construct' => ['void', 'array='=>'array|object', 'flags='=>'int'],
'RecursiveArrayIterator::append' => ['void', 'value'=>'mixed'],
'RecursiveArrayIterator::asort' => ['void'],
'RecursiveArrayIterator::count' => ['int'],
'RecursiveArrayIterator::current' => ['mixed'],
'RecursiveArrayIterator::getArrayCopy' => ['array'],
'RecursiveArrayIterator::getChildren' => ['?RecursiveArrayIterator'],
'RecursiveArrayIterator::getFlags' => ['int'],
'RecursiveArrayIterator::hasChildren' => ['bool'],
'RecursiveArrayIterator::key' => ['string|int|null'],
'RecursiveArrayIterator::ksort' => ['void'],
'RecursiveArrayIterator::natcasesort' => ['true'],
'RecursiveArrayIterator::natsort' => ['true'],
'RecursiveArrayIterator::next' => ['void'],
'RecursiveArrayIterator::offsetExists' => ['void', 'index'=>'string'],
'RecursiveArrayIterator::offsetGet' => ['mixed', 'index'=>'string'],
'RecursiveArrayIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'string'],
'RecursiveArrayIterator::offsetUnset' => ['void', 'index'=>'string'],
'RecursiveArrayIterator::rewind' => ['void'],
'RecursiveArrayIterator::seek' => ['void', 'position'=>'int'],
'RecursiveArrayIterator::serialize' => ['string'],
'RecursiveArrayIterator::setFlags' => ['void', 'flags'=>'string'],
'RecursiveArrayIterator::uasort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
'RecursiveArrayIterator::uksort' => ['void', 'cmp_function'=>'callable(mixed,mixed):int'],
'RecursiveArrayIterator::unserialize' => ['string', 'serialized'=>'string'],
'RecursiveArrayIterator::valid' => ['bool'],
'RecursiveCachingIterator::__construct' => ['void', 'it'=>'Iterator', 'flags='=>'int'],
'RecursiveCachingIterator::__toString' => ['string'],
'RecursiveCachingIterator::count' => ['int'],
'RecursiveCachingIterator::current' => ['void'],
'RecursiveCachingIterator::getCache' => ['array'],
'RecursiveCachingIterator::getChildren' => ['?RecursiveCachingIterator'],
'RecursiveCachingIterator::getFlags' => ['int'],
'RecursiveCachingIterator::getInnerIterator' => ['Iterator'],
'RecursiveCachingIterator::hasChildren' => ['bool'],
'RecursiveCachingIterator::hasNext' => ['bool'],
'RecursiveCachingIterator::key' => ['bool|float|int|string'],
'RecursiveCachingIterator::next' => ['void'],
'RecursiveCachingIterator::offsetExists' => ['bool', 'index'=>'string'],
'RecursiveCachingIterator::offsetGet' => ['string', 'index'=>'string'],
'RecursiveCachingIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'string'],
'RecursiveCachingIterator::offsetUnset' => ['void', 'index'=>'string'],
'RecursiveCachingIterator::rewind' => ['void'],
'RecursiveCachingIterator::setFlags' => ['void', 'flags'=>'int'],
'RecursiveCachingIterator::valid' => ['bool'],
'RecursiveCallbackFilterIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator', 'func'=>'callable'],
'RecursiveCallbackFilterIterator::accept' => ['bool'],
'RecursiveCallbackFilterIterator::current' => ['mixed'],
'RecursiveCallbackFilterIterator::getChildren' => ['RecursiveCallbackFilterIterator'],
'RecursiveCallbackFilterIterator::getInnerIterator' => ['Iterator'],
'RecursiveCallbackFilterIterator::hasChildren' => ['bool'],
'RecursiveCallbackFilterIterator::key' => ['bool|float|int|string'],
'RecursiveCallbackFilterIterator::next' => ['void'],
'RecursiveCallbackFilterIterator::rewind' => ['void'],
'RecursiveCallbackFilterIterator::valid' => ['bool'],
'RecursiveDirectoryIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'],
'RecursiveDirectoryIterator::__toString' => ['string'],
'RecursiveDirectoryIterator::current' => ['string|SplFileInfo|FilesystemIterator'],
'RecursiveDirectoryIterator::getATime' => ['int'],
'RecursiveDirectoryIterator::getBasename' => ['string', 'suffix='=>'string'],
'RecursiveDirectoryIterator::getChildren' => ['RecursiveDirectoryIterator'],
'RecursiveDirectoryIterator::getCTime' => ['int'],
'RecursiveDirectoryIterator::getExtension' => ['string'],
'RecursiveDirectoryIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
'RecursiveDirectoryIterator::getFilename' => ['string'],
'RecursiveDirectoryIterator::getFlags' => ['int'],
'RecursiveDirectoryIterator::getGroup' => ['int'],
'RecursiveDirectoryIterator::getInode' => ['int'],
'RecursiveDirectoryIterator::getLinkTarget' => ['string'],
'RecursiveDirectoryIterator::getMTime' => ['int'],
'RecursiveDirectoryIterator::getOwner' => ['int'],
'RecursiveDirectoryIterator::getPath' => ['string'],
'RecursiveDirectoryIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
'RecursiveDirectoryIterator::getPathname' => ['string'],
'RecursiveDirectoryIterator::getPerms' => ['int'],
'RecursiveDirectoryIterator::getRealPath' => ['string'],
'RecursiveDirectoryIterator::getSize' => ['int'],
'RecursiveDirectoryIterator::getSubPath' => ['string'],
'RecursiveDirectoryIterator::getSubPathname' => ['string'],
'RecursiveDirectoryIterator::getType' => ['string'],
'RecursiveDirectoryIterator::hasChildren' => ['bool', 'allow_links='=>'bool'],
'RecursiveDirectoryIterator::isDir' => ['bool'],
'RecursiveDirectoryIterator::isDot' => ['bool'],
'RecursiveDirectoryIterator::isExecutable' => ['bool'],
'RecursiveDirectoryIterator::isFile' => ['bool'],
'RecursiveDirectoryIterator::isLink' => ['bool'],
'RecursiveDirectoryIterator::isReadable' => ['bool'],
'RecursiveDirectoryIterator::isWritable' => ['bool'],
'RecursiveDirectoryIterator::key' => ['string'],
'RecursiveDirectoryIterator::next' => ['void'],
'RecursiveDirectoryIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
'RecursiveDirectoryIterator::rewind' => ['void'],
'RecursiveDirectoryIterator::seek' => ['void', 'position'=>'int'],
'RecursiveDirectoryIterator::setFileClass' => ['void', 'class_name='=>'string'],
'RecursiveDirectoryIterator::setFlags' => ['void', 'flags='=>'int'],
'RecursiveDirectoryIterator::setInfoClass' => ['void', 'class_name='=>'string'],
'RecursiveDirectoryIterator::valid' => ['bool'],
'RecursiveFilterIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator'],
'RecursiveFilterIterator::accept' => ['bool'],
'RecursiveFilterIterator::current' => ['mixed'],
'RecursiveFilterIterator::getChildren' => ['?RecursiveFilterIterator'],
'RecursiveFilterIterator::getInnerIterator' => ['Iterator'],
'RecursiveFilterIterator::hasChildren' => ['bool'],
'RecursiveFilterIterator::key' => ['mixed'],
'RecursiveFilterIterator::next' => ['void'],
'RecursiveFilterIterator::rewind' => ['void'],
'RecursiveFilterIterator::valid' => ['bool'],
'RecursiveIterator::__construct' => ['void'],
'RecursiveIterator::current' => ['mixed'],
'RecursiveIterator::getChildren' => ['?RecursiveIterator'],
'RecursiveIterator::hasChildren' => ['bool'],
'RecursiveIterator::key' => ['int|string'],
'RecursiveIterator::next' => ['void'],
'RecursiveIterator::rewind' => ['void'],
'RecursiveIterator::valid' => ['bool'],
'RecursiveIteratorIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator|IteratorAggregate', 'mode='=>'int', 'flags='=>'int'],
'RecursiveIteratorIterator::beginChildren' => ['void'],
'RecursiveIteratorIterator::beginIteration' => ['void'],
'RecursiveIteratorIterator::callGetChildren' => ['?RecursiveIterator'],
'RecursiveIteratorIterator::callHasChildren' => ['bool'],
'RecursiveIteratorIterator::current' => ['mixed'],
'RecursiveIteratorIterator::endChildren' => ['void'],
'RecursiveIteratorIterator::endIteration' => ['void'],
'RecursiveIteratorIterator::getDepth' => ['int'],
'RecursiveIteratorIterator::getInnerIterator' => ['RecursiveIterator'],
'RecursiveIteratorIterator::getMaxDepth' => ['int|false'],
'RecursiveIteratorIterator::getSubIterator' => ['?RecursiveIterator', 'level='=>'?int'],
'RecursiveIteratorIterator::key' => ['mixed'],
'RecursiveIteratorIterator::next' => ['void'],
'RecursiveIteratorIterator::nextElement' => ['void'],
'RecursiveIteratorIterator::rewind' => ['void'],
'RecursiveIteratorIterator::setMaxDepth' => ['void', 'max_depth='=>'int'],
'RecursiveIteratorIterator::valid' => ['bool'],
'RecursiveRegexIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator', 'regex'=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'],
'RecursiveRegexIterator::accept' => ['bool'],
'RecursiveRegexIterator::current' => ['mixed'],
'RecursiveRegexIterator::getChildren' => ['RecursiveRegexIterator'],
'RecursiveRegexIterator::getFlags' => ['int'],
'RecursiveRegexIterator::getInnerIterator' => ['Iterator'],
'RecursiveRegexIterator::getMode' => ['int'],
'RecursiveRegexIterator::getPregFlags' => ['int'],
'RecursiveRegexIterator::getRegex' => ['string'],
'RecursiveRegexIterator::hasChildren' => ['bool'],
'RecursiveRegexIterator::key' => ['mixed'],
'RecursiveRegexIterator::next' => ['void'],
'RecursiveRegexIterator::rewind' => ['void'],
'RecursiveRegexIterator::setFlags' => ['void', 'new_flags'=>'int'],
'RecursiveRegexIterator::setMode' => ['void', 'new_mode'=>'int'],
'RecursiveRegexIterator::setPregFlags' => ['void', 'new_flags'=>'int'],
'RecursiveRegexIterator::valid' => ['bool'],
'RecursiveTreeIterator::__construct' => ['void', 'iterator'=>'RecursiveIterator|IteratorAggregate', 'flags='=>'int', 'cit_flags='=>'int', 'mode'=>'int'],
'RecursiveTreeIterator::beginChildren' => ['void'],
'RecursiveTreeIterator::beginIteration' => ['void'],
'RecursiveTreeIterator::callGetChildren' => ['?RecursiveIterator'],
'RecursiveTreeIterator::callHasChildren' => ['bool'],
'RecursiveTreeIterator::current' => ['string'],
'RecursiveTreeIterator::endChildren' => ['void'],
'RecursiveTreeIterator::endIteration' => ['void'],
'RecursiveTreeIterator::getDepth' => ['int'],
'RecursiveTreeIterator::getEntry' => ['string'],
'RecursiveTreeIterator::getInnerIterator' => ['RecursiveIterator'],
'RecursiveTreeIterator::getMaxDepth' => ['false|int'],
'RecursiveTreeIterator::getPostfix' => ['string'],
'RecursiveTreeIterator::getPrefix' => ['string'],
'RecursiveTreeIterator::getSubIterator' => ['?RecursiveIterator', 'level='=>'?int'],
'RecursiveTreeIterator::key' => ['string'],
'RecursiveTreeIterator::next' => ['void'],
'RecursiveTreeIterator::nextElement' => ['void'],
'RecursiveTreeIterator::rewind' => ['void'],
'RecursiveTreeIterator::setMaxDepth' => ['void', 'max_depth='=>'int'],
'RecursiveTreeIterator::setPostfix' => ['void', 'prefix'=>'string'],
'RecursiveTreeIterator::setPrefixPart' => ['void', 'part'=>'int', 'prefix'=>'string'],
'RecursiveTreeIterator::valid' => ['bool'],
'Redis::__construct' => ['void'],
'Redis::__destruct' => ['void'],
'Redis::_prefix' => ['string', 'value'=>'mixed'],
'Redis::_serialize' => ['mixed', 'value'=>'mixed'],
'Redis::_unserialize' => ['mixed', 'value'=>'string'],
'Redis::append' => ['int', 'key'=>'string', 'value'=>'string'],
'Redis::auth' => ['bool', 'password'=>'string'],
'Redis::bgRewriteAOF' => ['bool'],
'Redis::bgSave' => ['bool'],
'Redis::bitCount' => ['int', 'key'=>'string'],
'Redis::bitOp' => ['int', 'operation'=>'string', 'ret_key'=>'string', 'key'=>'string', '...other_keys='=>'string'],
'Redis::bitpos' => ['int', 'key'=>'string', 'bit'=>'int', 'start='=>'int', 'end='=>'int'],
'Redis::blPop' => ['array', 'keys'=>'string[]', 'timeout'=>'int'],
'Redis::blPop\'1' => ['array', 'key'=>'string', 'timeout_or_key'=>'int|string', '...extra_args'=>'int|string'],
'Redis::brPop' => ['array', 'keys'=>'string[]', 'timeout'=>'int'],
'Redis::brPop\'1' => ['array', 'key'=>'string', 'timeout_or_key'=>'int|string', '...extra_args'=>'int|string'],
'Redis::brpoplpush' => ['string|false', 'srcKey'=>'string', 'dstKey'=>'string', 'timeout'=>'int'],
'Redis::clearLastError' => ['bool'],
'Redis::client' => ['mixed', 'command'=>'string', 'arg='=>'string'],
'Redis::close' => ['bool'],
'Redis::command' => ['', '...args'=>''],
'Redis::config' => ['string', 'operation'=>'string', 'key'=>'string', 'value='=>'string'],
'Redis::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'reserved='=>'null', 'retry_interval='=>'?int', 'read_timeout='=>'float'],
'Redis::dbSize' => ['int'],
'Redis::debug' => ['', 'key'=>''],
'Redis::decr' => ['int', 'key'=>'string'],
'Redis::decrBy' => ['int', 'key'=>'string', 'value'=>'int'],
'Redis::decrByFloat' => ['float', 'key'=>'string', 'value'=>'float'],
'Redis::del' => ['int', 'key'=>'string', '...args'=>'string'],
'Redis::del\'1' => ['int', 'key'=>'string[]'],
'Redis::delete' => ['int', 'key'=>'string', '...args'=>'string'],
'Redis::delete\'1' => ['int', 'key'=>'string[]'],
'Redis::discard' => [''],
'Redis::dump' => ['string|false', 'key'=>'string'],
'Redis::echo' => ['string', 'message'=>'string'],
'Redis::eval' => ['mixed', 'script'=>'', 'args='=>'', 'numKeys='=>''],
'Redis::evalSha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'],
'Redis::evaluate' => ['mixed', 'script'=>'string', 'args='=>'array', 'numKeys='=>'int'],
'Redis::evaluateSha' => ['', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'],
'Redis::exec' => ['array'],
'Redis::exists' => ['int', 'keys'=>'string|string[]'],
'Redis::exists\'1' => ['int', '...keys'=>'string'],
'Redis::expire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
'Redis::expireAt' => ['bool', 'key'=>'string', 'expiry'=>'int'],
'Redis::flushAll' => ['bool', 'async='=>'bool'],
'Redis::flushDb' => ['bool', 'async='=>'bool'],
'Redis::geoAdd' => ['int', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'member'=>'string', '...other_triples='=>'string|int|float'],
'Redis::geoDist' => ['float', 'key'=>'string', 'member1'=>'string', 'member2'=>'string', 'unit='=>'string'],
'Redis::geoHash' => ['array<int,string>', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
'Redis::geoPos' => ['array<int,array{0:string,1:string}>', 'key'=>'string', 'member'=>'string', '...members='=>'string'],
'Redis::geoRadius' => ['array<int,mixed>|int', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'radius'=>'float', 'unit'=>'float', 'options='=>'array<string,mixed>'],
'Redis::geoRadiusByMember' => ['array<int,mixed>|int', 'key'=>'string', 'member'=>'string', 'radius'=>'float', 'units'=>'string', 'options='=>'array<string,mixed>'],
'Redis::get' => ['string|false', 'key'=>'string'],
'Redis::getAuth' => ['string|false|null'],
'Redis::getBit' => ['int', 'key'=>'string', 'offset'=>'int'],
'Redis::getDBNum' => ['int|false'],
'Redis::getHost' => ['string|false'],
'Redis::getKeys' => ['array<int,string>', 'pattern'=>'string'],
'Redis::getLastError' => ['?string'],
'Redis::getMode' => ['int'],
'Redis::getMultiple' => ['array', 'keys'=>'string[]'],
'Redis::getOption' => ['int', 'name'=>'int'],
'Redis::getPersistentID' => ['string|false|null'],
'Redis::getPort' => ['int|false'],
'Redis::getRange' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'Redis::getReadTimeout' => ['float|false'],
'Redis::getSet' => ['string', 'key'=>'string', 'string'=>'string'],
'Redis::getTimeout' => ['float|false'],
'Redis::hDel' => ['int|false', 'key'=>'string', 'hashKey1'=>'string', '...otherHashKeys='=>'string'],
'Redis::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'],
'Redis::hGet' => ['string|false', 'key'=>'string', 'hashKey'=>'string'],
'Redis::hGetAll' => ['array', 'key'=>'string'],
'Redis::hIncrBy' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'int'],
'Redis::hIncrByFloat' => ['float', 'key'=>'string', 'field'=>'string', 'increment'=>'float'],
'Redis::hKeys' => ['array', 'key'=>'string'],
'Redis::hLen' => ['int|false', 'key'=>'string'],
'Redis::hMGet' => ['array', 'key'=>'string', 'hashKeys'=>'array'],
'Redis::hMSet' => ['bool', 'key'=>'string', 'hashKeys'=>'array'],
'Redis::hScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
'Redis::hSet' => ['int|false', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
'Redis::hSetNx' => ['bool', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
'Redis::hStrLen' => ['', 'key'=>'', 'member'=>''],
'Redis::hVals' => ['array', 'key'=>'string'],
'Redis::incr' => ['int', 'key'=>'string'],
'Redis::incrBy' => ['int', 'key'=>'string', 'value'=>'int'],
'Redis::incrByFloat' => ['float', 'key'=>'string', 'value'=>'float'],
'Redis::info' => ['array', 'option='=>'string'],
'Redis::isConnected' => ['bool'],
'Redis::keys' => ['array<int,string>', 'pattern'=>'string'],
'Redis::lastSave' => ['int'],
'Redis::lGet' => ['string', 'key'=>'string', 'index'=>'int'],
'Redis::lGetRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'Redis::lIndex' => ['string|false', 'key'=>'string', 'index'=>'int'],
'Redis::lInsert' => ['int', 'key'=>'string', 'position'=>'int', 'pivot'=>'string', 'value'=>'string'],
'Redis::listTrim' => ['', 'key'=>'string', 'start'=>'int', 'stop'=>'int'],
'Redis::lLen' => ['int|false', 'key'=>'string'],
'Redis::lPop' => ['string|false', 'key'=>'string'],
'Redis::lPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
'Redis::lPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
'Redis::lRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'Redis::lRem' => ['int|false', 'key'=>'string', 'value'=>'string', 'count'=>'int'],
'Redis::lRemove' => ['int', 'key'=>'string', 'value'=>'string', 'count'=>'int'],
'Redis::lSet' => ['bool', 'key'=>'string', 'index'=>'int', 'value'=>'string'],
'Redis::lSize' => ['int', 'key'=>'string'],
'Redis::lTrim' => ['array|false', 'key'=>'string', 'start'=>'int', 'stop'=>'int'],
'Redis::mGet' => ['array', 'keys'=>'string[]'],
'Redis::migrate' => ['bool', 'host'=>'string', 'port'=>'int', 'key'=>'string|string[]', 'db'=>'int', 'timeout'=>'int', 'copy='=>'bool', 'replace='=>'bool'],
'Redis::move' => ['bool', 'key'=>'string', 'dbindex'=>'int'],
'Redis::mSet' => ['bool', 'pairs'=>'array'],
'Redis::mSetNx' => ['bool', 'pairs'=>'array'],
'Redis::multi' => ['Redis', 'mode='=>'int'],
'Redis::object' => ['string|long|false', 'info'=>'string', 'key'=>'string'],
'Redis::open' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'reserved='=>'null', 'retry_interval='=>'?int', 'read_timeout='=>'float'],
'Redis::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'string', 'retry_interval='=>'?int'],
'Redis::persist' => ['bool', 'key'=>'string'],
'Redis::pExpire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
'Redis::pexpireAt' => ['bool', 'key'=>'string', 'expiry'=>'int'],
'Redis::pfAdd' => ['bool', 'key'=>'string', 'elements'=>'array'],
'Redis::pfCount' => ['int', 'key'=>'array|string'],
'Redis::pfMerge' => ['bool', 'destkey'=>'string', 'sourcekeys'=>'array'],
'Redis::ping' => ['string'],
'Redis::pipeline' => ['Redis'],
'Redis::popen' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'string', 'retry_interval='=>'?int'],
'Redis::psetex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
'Redis::psubscribe' => ['', 'patterns'=>'array', 'callback'=>'array|string'],
'Redis::pttl' => ['int|false', 'key'=>'string'],
'Redis::publish' => ['int', 'channel'=>'string', 'message'=>'string'],
'Redis::pubsub' => ['array|int', 'keyword'=>'string', 'argument='=>'array|string'],
'Redis::punsubscribe' => ['', 'pattern'=>'string', '...other_patterns='=>'string'],
'Redis::randomKey' => ['string'],
'Redis::rawCommand' => ['mixed', 'command'=>'string', '...arguments='=>'mixed'],
'Redis::rename' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'],
'Redis::renameKey' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'],
'Redis::renameNx' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'],
'Redis::resetStat' => ['bool'],
'Redis::restore' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
'Redis::role' => ['array', 'nodeParams'=>'string|array{0:string,1:int}'],
'Redis::rPop' => ['string|false', 'key'=>'string'],
'Redis::rpoplpush' => ['string', 'srcKey'=>'string', 'dstKey'=>'string'],
'Redis::rPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
'Redis::rPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
'Redis::sAdd' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
'Redis::sAddArray' => ['bool', 'key'=>'string', 'values'=>'array'],
'Redis::save' => ['bool'],
'Redis::scan' => ['array<int,string>|false', '&rw_iterator'=>'?int', 'pattern='=>'?string', 'count='=>'?int'],
'Redis::sCard' => ['int', 'key'=>'string'],
'Redis::sContains' => ['', 'key'=>'string', 'value'=>'string'],
'Redis::script' => ['mixed', 'command'=>'string', '...args='=>'mixed'],
'Redis::sDiff' => ['array', 'key1'=>'string', '...other_keys='=>'string'],
'Redis::sDiffStore' => ['int|false', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
'Redis::select' => ['bool', 'dbindex'=>'int'],
'Redis::sendEcho' => ['string', 'msg'=>'string'],
'Redis::set' => ['bool', 'key'=>'string', 'value'=>'mixed', 'options='=>'array'],
'Redis::set\'1' => ['bool', 'key'=>'string', 'value'=>'mixed', 'timeout='=>'int'],
'Redis::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'int'],
'Redis::setEx' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
'Redis::setNx' => ['bool', 'key'=>'string', 'value'=>'string'],
'Redis::setOption' => ['bool', 'name'=>'int', 'value'=>'mixed'],
'Redis::setRange' => ['int', 'key'=>'string', 'offset'=>'int', 'end'=>'int'],
'Redis::setTimeout' => ['', 'key'=>'string', 'ttl'=>'int'],
'Redis::sGetMembers' => ['', 'key'=>'string'],
'Redis::sInter' => ['array|false', 'key'=>'string', '...other_keys='=>'string'],
'Redis::sInterStore' => ['int|false', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
'Redis::sIsMember' => ['bool', 'key'=>'string', 'value'=>'string'],
'Redis::slave' => ['bool', 'host'=>'string', 'port'=>'int'],
'Redis::slave\'1' => ['bool', 'host'=>'string', 'port'=>'int'],
'Redis::slaveof' => ['bool', 'host='=>'string', 'port='=>'int'],
'Redis::slowLog' => ['mixed', 'operation'=>'string', 'length='=>'int'],
'Redis::sMembers' => ['array', 'key'=>'string'],
'Redis::sMove' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string', 'member'=>'string'],
'Redis::sort' => ['array|int', 'key'=>'string', 'options='=>'array'],
'Redis::sortAsc' => ['array', 'key'=>'string', 'pattern='=>'string', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
'Redis::sortAscAlpha' => ['array', 'key'=>'string', 'pattern='=>'', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
'Redis::sortDesc' => ['array', 'key'=>'string', 'pattern='=>'', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
'Redis::sortDescAlpha' => ['array', 'key'=>'string', 'pattern='=>'', 'get='=>'string', 'start='=>'int', 'end='=>'int', 'getList='=>'bool'],
'Redis::sPop' => ['string|false', 'key'=>'string'],
'Redis::sRandMember' => ['array|string|false', 'key'=>'string', 'count='=>'int'],
'Redis::sRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
'Redis::sRemove' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
'Redis::sScan' => ['array|bool', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
'Redis::sSize' => ['int', 'key'=>'string'],
'Redis::strLen' => ['int', 'key'=>'string'],
'Redis::subscribe' => ['mixed|null', 'channels'=>'array', 'callback'=>'string|array'],
'Redis::substr' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'Redis::sUnion' => ['array', 'key'=>'string', '...other_keys='=>'string'],
'Redis::sUnionStore' => ['int', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
'Redis::swapdb' => ['bool', 'srcdb'=>'int', 'dstdb'=>'int'],
'Redis::time' => ['array'],
'Redis::ttl' => ['int|false', 'key'=>'string'],
'Redis::type' => ['int', 'key'=>'string'],
'Redis::unlink' => ['int', 'key'=>'string', '...args'=>'string'],
'Redis::unlink\'1' => ['int', 'key'=>'string[]'],
'Redis::unsubscribe' => ['', 'channel'=>'string', '...other_channels='=>'string'],
'Redis::unwatch' => [''],
'Redis::wait' => ['int', 'numSlaves'=>'int', 'timeout'=>'int'],
'Redis::watch' => ['void', 'key'=>'string', '...other_keys='=>'string'],
'Redis::xack' => ['', 'str_key'=>'string', 'str_group'=>'string', 'arr_ids'=>'array'],
'Redis::xadd' => ['', 'str_key'=>'string', 'str_id'=>'string', 'arr_fields'=>'array', 'i_maxlen='=>'', 'boo_approximate='=>''],
'Redis::xclaim' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_consumer'=>'string', 'i_min_idle'=>'', 'arr_ids'=>'array', 'arr_opts='=>'array'],
'Redis::xdel' => ['', 'str_key'=>'string', 'arr_ids'=>'array'],
'Redis::xgroup' => ['', 'str_operation'=>'string', 'str_key='=>'string', 'str_arg1='=>'', 'str_arg2='=>'', 'str_arg3='=>''],
'Redis::xinfo' => ['', 'str_cmd'=>'string', 'str_key='=>'string', 'str_group='=>'string'],
'Redis::xlen' => ['', 'key'=>''],
'Redis::xpending' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_start='=>'', 'str_end='=>'', 'i_count='=>'', 'str_consumer='=>'string'],
'Redis::xrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
'Redis::xread' => ['', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
'Redis::xreadgroup' => ['', 'str_group'=>'string', 'str_consumer'=>'string', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
'Redis::xrevrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
'Redis::xtrim' => ['', 'str_key'=>'string', 'i_maxlen'=>'', 'boo_approximate='=>''],
'Redis::zAdd' => ['int', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'],
'Redis::zAdd\'1' => ['int', 'options'=>'array', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'],
'Redis::zCard' => ['int', 'key'=>'string'],
'Redis::zCount' => ['int', 'key'=>'string', 'start'=>'string', 'end'=>'string'],
'Redis::zDelete' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
'Redis::zDeleteRangeByRank' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'Redis::zDeleteRangeByScore' => ['', 'key'=>'string', 'start'=>'float', 'end'=>'float'],
'Redis::zIncrBy' => ['float', 'key'=>'string', 'value'=>'float', 'member'=>'string'],
'Redis::zInter' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
'Redis::zInterStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
'Redis::zLexCount' => ['int', 'key'=>'string', 'min'=>'string', 'max'=>'string'],
'Redis::zRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscores='=>'bool'],
'Redis::zRangeByLex' => ['array|false', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'],
'Redis::zRangeByScore' => ['array', 'key'=>'string', 'start'=>'int|string', 'end'=>'int|string', 'options='=>'array'],
'Redis::zRank' => ['int', 'key'=>'string', 'member'=>'string'],
'Redis::zRem' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
'Redis::zRemove' => ['int', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
'Redis::zRemoveRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'Redis::zRemoveRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'],
'Redis::zRemRangeByLex' => ['int', 'key'=>'string', 'min'=>'string', 'max'=>'string'],
'Redis::zRemRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'Redis::zRemRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'],
'Redis::zReverseRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'],
'Redis::zRevRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'],
'Redis::zRevRangeByLex' => ['array', 'key'=>'string', 'min'=>'string', 'max'=>'string', 'offset='=>'int', 'limit='=>'int'],
'Redis::zRevRangeByScore' => ['array', 'key'=>'string', 'start'=>'string', 'end'=>'string', 'options='=>'array'],
'Redis::zRevRank' => ['int', 'key'=>'string', 'member'=>'string'],
'Redis::zScan' => ['array|bool', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
'Redis::zScore' => ['float|false', 'key'=>'string', 'member'=>'string'],
'Redis::zSize' => ['', 'key'=>'string'],
'Redis::zUnion' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
'Redis::zUnionStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
'RedisArray::__call' => ['mixed', 'function_name'=>'string', 'arguments'=>'array'],
'RedisArray::__construct' => ['void', 'name='=>'string', 'hosts='=>'?array', 'opts='=>'?array'],
'RedisArray::_continuum' => [''],
'RedisArray::_distributor' => [''],
'RedisArray::_function' => ['string'],
'RedisArray::_hosts' => ['array'],
'RedisArray::_instance' => ['', 'host'=>''],
'RedisArray::_rehash' => ['', 'callable='=>'callable'],
'RedisArray::_target' => ['string', 'key'=>'string'],
'RedisArray::bgsave' => [''],
'RedisArray::del' => ['bool', 'key'=>'string', '...args'=>'string'],
'RedisArray::delete' => ['bool', 'key'=>'string', '...args'=>'string'],
'RedisArray::delete\'1' => ['bool', 'key'=>'string[]'],
'RedisArray::discard' => [''],
'RedisArray::exec' => ['array'],
'RedisArray::flushAll' => ['bool', 'async='=>'bool'],
'RedisArray::flushDb' => ['bool', 'async='=>'bool'],
'RedisArray::getMultiple' => ['', 'keys'=>''],
'RedisArray::getOption' => ['', 'opt'=>''],
'RedisArray::info' => ['array'],
'RedisArray::keys' => ['array<int,string>', 'pattern'=>''],
'RedisArray::mGet' => ['array', 'keys'=>'string[]'],
'RedisArray::mSet' => ['bool', 'pairs'=>'array'],
'RedisArray::multi' => ['RedisArray', 'host'=>'string', 'mode='=>'int'],
'RedisArray::ping' => ['string'],
'RedisArray::save' => ['bool'],
'RedisArray::select' => ['', 'index'=>''],
'RedisArray::setOption' => ['', 'opt'=>'', 'value'=>''],
'RedisArray::unlink' => ['int', 'key'=>'string', '...other_keys='=>'string'],
'RedisArray::unlink\'1' => ['int', 'key'=>'string[]'],
'RedisArray::unwatch' => [''],
'RedisCluster::__construct' => ['void', 'name'=>'?string', 'seeds='=>'string[]', 'timeout='=>'float', 'readTimeout='=>'float', 'persistent='=>'bool', 'auth='=>'?string'],
'RedisCluster::_masters' => ['array'],
'RedisCluster::_prefix' => ['string', 'value'=>'mixed'],
'RedisCluster::_redir' => [''],
'RedisCluster::_serialize' => ['mixed', 'value'=>'mixed'],
'RedisCluster::_unserialize' => ['mixed', 'value'=>'string'],
'RedisCluster::append' => ['int', 'key'=>'string', 'value'=>'string'],
'RedisCluster::bgrewriteaof' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}'],
'RedisCluster::bgsave' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}'],
'RedisCluster::bitCount' => ['int', 'key'=>'string'],
'RedisCluster::bitOp' => ['int', 'operation'=>'string', 'retKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'],
'RedisCluster::bitpos' => ['int', 'key'=>'string', 'bit'=>'int', 'start='=>'int', 'end='=>'int'],
'RedisCluster::blPop' => ['array', 'keys'=>'array', 'timeout'=>'int'],
'RedisCluster::brPop' => ['array', 'keys'=>'array', 'timeout'=>'int'],
'RedisCluster::brpoplpush' => ['string|false', 'srcKey'=>'string', 'dstKey'=>'string', 'timeout'=>'int'],
'RedisCluster::clearLastError' => ['bool'],
'RedisCluster::client' => ['', 'nodeParams'=>'string|array{0:string,1:int}', 'subCmd='=>'string', '...args='=>''],
'RedisCluster::close' => [''],
'RedisCluster::cluster' => ['mixed', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'arguments='=>'mixed'],
'RedisCluster::command' => ['array|bool'],
'RedisCluster::config' => ['array|bool', 'nodeParams'=>'string|array{0:string,1:int}', 'operation'=>'string', 'key'=>'string', 'value='=>'string'],
'RedisCluster::dbSize' => ['int', 'nodeParams'=>'string|array{0:string,1:int}'],
'RedisCluster::decr' => ['int', 'key'=>'string'],
'RedisCluster::decrBy' => ['int', 'key'=>'string', 'value'=>'int'],
'RedisCluster::del' => ['int', 'key'=>'string', '...other_keys='=>'string'],
'RedisCluster::del\'1' => ['int', 'key'=>'string[]'],
'RedisCluster::discard' => [''],
'RedisCluster::dump' => ['string|false', 'key'=>'string'],
'RedisCluster::echo' => ['string', 'nodeParams'=>'string|array{0:string,1:int}', 'msg'=>'string'],
'RedisCluster::eval' => ['mixed', 'script'=>'', 'args='=>'', 'numKeys='=>''],
'RedisCluster::evalSha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'],
'RedisCluster::exec' => ['array|void'],
'RedisCluster::exists' => ['bool', 'key'=>'string'],
'RedisCluster::expire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
'RedisCluster::expireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'],
'RedisCluster::flushAll' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}', 'async='=>'bool'],
'RedisCluster::flushDB' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}', 'async='=>'bool'],
'RedisCluster::geoAdd' => ['int', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'member'=>'string', '...other_members='=>'float|string'],
'RedisCluster::geoDist' => ['', 'key'=>'string', 'member1'=>'string', 'member2'=>'string', 'unit='=>'string'],
'RedisCluster::geohash' => ['array<int,string>', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
'RedisCluster::geopos' => ['array<int,array{0:string,1:string}>', 'key'=>'string', 'member'=>'string', '...other_members='=>'string'],
'RedisCluster::geoRadius' => ['', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'radius'=>'float', 'radiusUnit'=>'string', 'options='=>'array'],
'RedisCluster::geoRadiusByMember' => ['string[]', 'key'=>'string', 'member'=>'string', 'radius'=>'float', 'radiusUnit'=>'string', 'options='=>'array'],
'RedisCluster::get' => ['string|false', 'key'=>'string'],
'RedisCluster::getBit' => ['int', 'key'=>'string', 'offset'=>'int'],
'RedisCluster::getLastError' => ['?string'],
'RedisCluster::getMode' => ['int'],
'RedisCluster::getOption' => ['int', 'option'=>'int'],
'RedisCluster::getRange' => ['string', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'RedisCluster::getSet' => ['string', 'key'=>'string', 'value'=>'string'],
'RedisCluster::hDel' => ['int|false', 'key'=>'string', 'hashKey'=>'string', '...other_hashKeys='=>'string[]'],
'RedisCluster::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'],
'RedisCluster::hGet' => ['string|false', 'key'=>'string', 'hashKey'=>'string'],
'RedisCluster::hGetAll' => ['array', 'key'=>'string'],
'RedisCluster::hIncrBy' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'int'],
'RedisCluster::hIncrByFloat' => ['float', 'key'=>'string', 'field'=>'string', 'increment'=>'float'],
'RedisCluster::hKeys' => ['array', 'key'=>'string'],
'RedisCluster::hLen' => ['int|false', 'key'=>'string'],
'RedisCluster::hMGet' => ['array', 'key'=>'string', 'hashKeys'=>'array'],
'RedisCluster::hMSet' => ['bool', 'key'=>'string', 'hashKeys'=>'array'],
'RedisCluster::hScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
'RedisCluster::hSet' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
'RedisCluster::hSetNx' => ['bool', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'],
'RedisCluster::hStrlen' => ['int', 'key'=>'string', 'member'=>'string'],
'RedisCluster::hVals' => ['array', 'key'=>'string'],
'RedisCluster::incr' => ['int', 'key'=>'string'],
'RedisCluster::incrBy' => ['int', 'key'=>'string', 'value'=>'int'],
'RedisCluster::incrByFloat' => ['float', 'key'=>'string', 'increment'=>'float'],
'RedisCluster::info' => ['array', 'nodeParams'=>'string|array{0:string,1:int}', 'option='=>'string'],
'RedisCluster::keys' => ['array', 'pattern'=>'string'],
'RedisCluster::lastSave' => ['int', 'nodeParams'=>'string|array{0:string,1:int}'],
'RedisCluster::lGet' => ['', 'key'=>'string', 'index'=>'int'],
'RedisCluster::lIndex' => ['string|false', 'key'=>'string', 'index'=>'int'],
'RedisCluster::lInsert' => ['int', 'key'=>'string', 'position'=>'int', 'pivot'=>'string', 'value'=>'string'],
'RedisCluster::lLen' => ['int', 'key'=>'string'],
'RedisCluster::lPop' => ['string|false', 'key'=>'string'],
'RedisCluster::lPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
'RedisCluster::lPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
'RedisCluster::lRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'RedisCluster::lRem' => ['int|false', 'key'=>'string', 'value'=>'string', 'count'=>'int'],
'RedisCluster::lSet' => ['bool', 'key'=>'string', 'index'=>'int', 'value'=>'string'],
'RedisCluster::lTrim' => ['array|false', 'key'=>'string', 'start'=>'int', 'stop'=>'int'],
'RedisCluster::mget' => ['array', 'array'=>'array'],
'RedisCluster::mset' => ['bool', 'array'=>'array'],
'RedisCluster::msetnx' => ['int', 'array'=>'array'],
'RedisCluster::multi' => ['Redis', 'mode='=>'int'],
'RedisCluster::object' => ['string|int|false', 'string'=>'string', 'key'=>'string'],
'RedisCluster::persist' => ['bool', 'key'=>'string'],
'RedisCluster::pExpire' => ['bool', 'key'=>'string', 'ttl'=>'int'],
'RedisCluster::pExpireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'],
'RedisCluster::pfAdd' => ['bool', 'key'=>'string', 'elements'=>'array'],
'RedisCluster::pfCount' => ['int', 'key'=>'string'],
'RedisCluster::pfMerge' => ['bool', 'destKey'=>'string', 'sourceKeys'=>'array'],
'RedisCluster::ping' => ['string', 'nodeParams'=>'string|array{0:string,1:int}'],
'RedisCluster::psetex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
'RedisCluster::psubscribe' => ['mixed', 'patterns'=>'array', 'callback'=>'string'],
'RedisCluster::pttl' => ['int', 'key'=>'string'],
'RedisCluster::publish' => ['int', 'channel'=>'string', 'message'=>'string'],
'RedisCluster::pubsub' => ['array', 'nodeParams'=>'string', 'keyword'=>'string', '...argument='=>'string'],
'RedisCluster::punSubscribe' => ['', 'channels'=>'', 'callback'=>''],
'RedisCluster::randomKey' => ['string', 'nodeParams'=>'string|array{0:string,1:int}'],
'RedisCluster::rawCommand' => ['mixed', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'arguments='=>'mixed'],
'RedisCluster::rename' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'],
'RedisCluster::renameNx' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'],
'RedisCluster::restore' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
'RedisCluster::role' => ['array'],
'RedisCluster::rPop' => ['string|false', 'key'=>'string'],
'RedisCluster::rpoplpush' => ['string|false', 'srcKey'=>'string', 'dstKey'=>'string'],
'RedisCluster::rPush' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
'RedisCluster::rPushx' => ['int|false', 'key'=>'string', 'value'=>'string'],
'RedisCluster::sAdd' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'],
'RedisCluster::sAddArray' => ['int|false', 'key'=>'string', 'valueArray'=>'array'],
'RedisCluster::save' => ['bool', 'nodeParams'=>'string|array{0:string,1:int}'],
'RedisCluster::scan' => ['array|false', '&iterator'=>'int', 'nodeParams'=>'string|array{0:string,1:int}', 'pattern='=>'string', 'count='=>'int'],
'RedisCluster::sCard' => ['int', 'key'=>'string'],
'RedisCluster::script' => ['string|bool|array', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'script='=>'string', '...other_scripts='=>'string[]'],
'RedisCluster::sDiff' => ['list<string>', 'key1'=>'string', 'key2'=>'string', '...other_keys='=>'string'],
'RedisCluster::sDiffStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'],
'RedisCluster::set' => ['bool', 'key'=>'string', 'value'=>'string', 'timeout='=>'array|int'],
'RedisCluster::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'bool|int'],
'RedisCluster::setex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'],
'RedisCluster::setnx' => ['bool', 'key'=>'string', 'value'=>'string'],
'RedisCluster::setOption' => ['bool', 'option'=>'int', 'value'=>'string|int'],
'RedisCluster::setRange' => ['string', 'key'=>'string', 'offset'=>'int', 'value'=>'string'],
'RedisCluster::sInter' => ['list<string>', 'key'=>'string', '...other_keys='=>'string'],
'RedisCluster::sInterStore' => ['int', 'dstKey'=>'string', 'key'=>'string', '...other_keys='=>'string'],
'RedisCluster::sIsMember' => ['bool', 'key'=>'string', 'value'=>'string'],
'RedisCluster::slowLog' => ['array|int|bool', 'nodeParams'=>'string|array{0:string,1:int}', 'command'=>'string', 'length='=>'int'],
'RedisCluster::sMembers' => ['list<string>', 'key'=>'string'],
'RedisCluster::sMove' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string', 'member'=>'string'],
'RedisCluster::sort' => ['array', 'key'=>'string', 'option='=>'array'],
'RedisCluster::sPop' => ['string', 'key'=>'string'],
'RedisCluster::sRandMember' => ['array|string', 'key'=>'string', 'count='=>'int'],
'RedisCluster::sRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
'RedisCluster::sScan' => ['array|false', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'null', 'count='=>'int'],
'RedisCluster::strlen' => ['int', 'key'=>'string'],
'RedisCluster::subscribe' => ['mixed', 'channels'=>'array', 'callback'=>'string'],
'RedisCluster::sUnion' => ['list<string>', 'key1'=>'string', '...other_keys='=>'string'],
'RedisCluster::sUnion\'1' => ['list<string>', 'keys'=>'string[]'],
'RedisCluster::sUnionStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', '...other_keys='=>'string'],
'RedisCluster::time' => ['array'],
'RedisCluster::ttl' => ['int', 'key'=>'string'],
'RedisCluster::type' => ['int', 'key'=>'string'],
'RedisCluster::unlink' => ['int', 'key'=>'string', '...other_keys='=>'string'],
'RedisCluster::unSubscribe' => ['', 'channels'=>'', '...other_channels='=>''],
'RedisCluster::unwatch' => [''],
'RedisCluster::watch' => ['void', 'key'=>'string', '...other_keys='=>'string'],
'RedisCluster::xack' => ['', 'str_key'=>'string', 'str_group'=>'string', 'arr_ids'=>'array'],
'RedisCluster::xadd' => ['', 'str_key'=>'string', 'str_id'=>'string', 'arr_fields'=>'array', 'i_maxlen='=>'', 'boo_approximate='=>''],
'RedisCluster::xclaim' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_consumer'=>'string', 'i_min_idle'=>'', 'arr_ids'=>'array', 'arr_opts='=>'array'],
'RedisCluster::xdel' => ['', 'str_key'=>'string', 'arr_ids'=>'array'],
'RedisCluster::xgroup' => ['', 'str_operation'=>'string', 'str_key='=>'string', 'str_arg1='=>'', 'str_arg2='=>'', 'str_arg3='=>''],
'RedisCluster::xinfo' => ['', 'str_cmd'=>'string', 'str_key='=>'string', 'str_group='=>'string'],
'RedisCluster::xlen' => ['', 'key'=>''],
'RedisCluster::xpending' => ['', 'str_key'=>'string', 'str_group'=>'string', 'str_start='=>'', 'str_end='=>'', 'i_count='=>'', 'str_consumer='=>'string'],
'RedisCluster::xrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
'RedisCluster::xread' => ['', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
'RedisCluster::xreadgroup' => ['', 'str_group'=>'string', 'str_consumer'=>'string', 'arr_streams'=>'array', 'i_count='=>'', 'i_block='=>''],
'RedisCluster::xrevrange' => ['', 'str_key'=>'string', 'str_start'=>'', 'str_end'=>'', 'i_count='=>''],
'RedisCluster::xtrim' => ['', 'str_key'=>'string', 'i_maxlen'=>'', 'boo_approximate='=>''],
'RedisCluster::zAdd' => ['int', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'],
'RedisCluster::zCard' => ['int', 'key'=>'string'],
'RedisCluster::zCount' => ['int', 'key'=>'string', 'start'=>'string', 'end'=>'string'],
'RedisCluster::zIncrBy' => ['float', 'key'=>'string', 'value'=>'float', 'member'=>'string'],
'RedisCluster::zInterStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
'RedisCluster::zLexCount' => ['int', 'key'=>'string', 'min'=>'int', 'max'=>'int'],
'RedisCluster::zRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscores='=>'bool'],
'RedisCluster::zRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'],
'RedisCluster::zRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'],
'RedisCluster::zRank' => ['int', 'key'=>'string', 'member'=>'string'],
'RedisCluster::zRem' => ['int', 'key'=>'string', 'member1'=>'string', '...other_members='=>'string'],
'RedisCluster::zRemRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int'],
'RedisCluster::zRemRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'],
'RedisCluster::zRemRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'],
'RedisCluster::zRevRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'],
'RedisCluster::zRevRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'],
'RedisCluster::zRevRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'],
'RedisCluster::zRevRank' => ['int', 'key'=>'string', 'member'=>'string'],
'RedisCluster::zScan' => ['array|false', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'],
'RedisCluster::zScore' => ['float', 'key'=>'string', 'member'=>'string'],
'RedisCluster::zUnionStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'],
'Reflection::getModifierNames' => ['list<string>', 'modifiers'=>'int'],
'ReflectionClass::__clone' => ['void'],
'ReflectionClass::__construct' => ['void', 'argument'=>'object|class-string'],
'ReflectionClass::__toString' => ['string'],
'ReflectionClass::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
'ReflectionClass::getConstant' => ['mixed', 'name'=>'string'],
'ReflectionClass::getConstants' => ['array<string,mixed>', 'filter=' => '?int'],
'ReflectionClass::getConstructor' => ['?ReflectionMethod'],
'ReflectionClass::getDefaultProperties' => ['array'],
'ReflectionClass::getDocComment' => ['string|false'],
'ReflectionClass::getEndLine' => ['int|false'],
'ReflectionClass::getExtension' => ['?ReflectionExtension'],
'ReflectionClass::getExtensionName' => ['string|false'],
'ReflectionClass::getFileName' => ['string|false'],
'ReflectionClass::getInterfaceNames' => ['list<class-string>'],
'ReflectionClass::getInterfaces' => ['array<class-string, ReflectionClass>'],
'ReflectionClass::getMethod' => ['ReflectionMethod', 'name'=>'string'],
'ReflectionClass::getMethods' => ['list<ReflectionMethod>', 'filter='=>'?int'],
'ReflectionClass::getModifiers' => ['int'],
'ReflectionClass::getName' => ['class-string'],
'ReflectionClass::getNamespaceName' => ['string'],
'ReflectionClass::getParentClass' => ['ReflectionClass|false'],
'ReflectionClass::getProperties' => ['list<ReflectionProperty>', 'filter='=>'?int'],
'ReflectionClass::getProperty' => ['ReflectionProperty', 'name'=>'string'],
'ReflectionClass::getReflectionConstant' => ['ReflectionClassConstant|false', 'name'=>'string'],
'ReflectionClass::getReflectionConstants' => ['list<ReflectionClassConstant>', 'filter='=>'?int'],
'ReflectionClass::getShortName' => ['string'],
'ReflectionClass::getStartLine' => ['int|false'],
'ReflectionClass::getStaticProperties' => ['array<string, ReflectionProperty>'],
'ReflectionClass::getStaticPropertyValue' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
'ReflectionClass::getTraitAliases' => ['array<string,string>'],
'ReflectionClass::getTraitNames' => ['list<trait-string>'],
'ReflectionClass::getTraits' => ['array<trait-string,ReflectionClass>'],
'ReflectionClass::hasConstant' => ['bool', 'name'=>'string'],
'ReflectionClass::hasMethod' => ['bool', 'name'=>'string'],
'ReflectionClass::hasProperty' => ['bool', 'name'=>'string'],
'ReflectionClass::implementsInterface' => ['bool', 'interface_name'=>'interface-string|ReflectionClass'],
'ReflectionClass::inNamespace' => ['bool'],
'ReflectionClass::isAbstract' => ['bool'],
'ReflectionClass::isAnonymous' => ['bool'],
'ReflectionClass::isCloneable' => ['bool'],
'ReflectionClass::isEnum' => ['bool'],
'ReflectionClass::isFinal' => ['bool'],
'ReflectionClass::isInstance' => ['bool', 'object'=>'object'],
'ReflectionClass::isInstantiable' => ['bool'],
'ReflectionClass::isInterface' => ['bool'],
'ReflectionClass::isInternal' => ['bool'],
'ReflectionClass::isIterable' => ['bool'],
'ReflectionClass::isIterateable' => ['bool'],
'ReflectionClass::isSubclassOf' => ['bool', 'class'=>'class-string|ReflectionClass'],
'ReflectionClass::isTrait' => ['bool'],
'ReflectionClass::isUserDefined' => ['bool'],
'ReflectionClass::newInstance' => ['object', '...args='=>'mixed'],
'ReflectionClass::newInstanceArgs' => ['object', 'args='=>'list<mixed>|array<string, mixed>'],
'ReflectionClass::newInstanceWithoutConstructor' => ['object'],
'ReflectionClass::setStaticPropertyValue' => ['void', 'name'=>'string', 'value'=>'mixed'],
'ReflectionClassConstant::__construct' => ['void', 'class'=>'mixed', 'name'=>'string'],
'ReflectionClassConstant::__toString' => ['string'],
'ReflectionClassConstant::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
'ReflectionClassConstant::getDeclaringClass' => ['ReflectionClass'],
'ReflectionClassConstant::getDocComment' => ['string|false'],
'ReflectionClassConstant::getModifiers' => ['int'],
'ReflectionClassConstant::getName' => ['string'],
'ReflectionClassConstant::getValue' => ['scalar|array<scalar>|null'],
'ReflectionClassConstant::isPrivate' => ['bool'],
'ReflectionClassConstant::isProtected' => ['bool'],
'ReflectionClassConstant::isPublic' => ['bool'],
'ReflectionEnum::getBackingType' => ['?ReflectionType'],
'ReflectionEnum::getCase' => ['ReflectionEnumUnitCase', 'name' => 'string'],
'ReflectionEnum::getCases' => ['list<ReflectionEnumUnitCase>'],
'ReflectionEnum::hasCase' => ['bool', 'name' => 'string'],
'ReflectionEnum::isBacked' => ['bool'],
'ReflectionEnumUnitCase::getEnum' => ['ReflectionEnum'],
'ReflectionEnumUnitCase::getValue' => ['UnitEnum'],
'ReflectionEnumBackedCase::getBackingValue' => ['string|int'],
'ReflectionExtension::__clone' => ['void'],
'ReflectionExtension::__construct' => ['void', 'name'=>'string'],
'ReflectionExtension::__toString' => ['string'],
'ReflectionExtension::getClasses' => ['array<class-string,ReflectionClass>'],
'ReflectionExtension::getClassNames' => ['list<class-string>'],
'ReflectionExtension::getConstants' => ['array<string,mixed>'],
'ReflectionExtension::getDependencies' => ['array<string,string>'],
'ReflectionExtension::getFunctions' => ['array<string,ReflectionFunction>'],
'ReflectionExtension::getINIEntries' => ['array<string,mixed>'],
'ReflectionExtension::getName' => ['string'],
'ReflectionExtension::getVersion' => ['?string'],
'ReflectionExtension::info' => ['void'],
'ReflectionExtension::isPersistent' => ['bool'],
'ReflectionExtension::isTemporary' => ['bool'],
'ReflectionFunction::__construct' => ['void', 'name'=>'callable-string|Closure'],
'ReflectionFunction::__toString' => ['string'],
'ReflectionFunction::getClosure' => ['Closure'],
'ReflectionFunction::getClosureScopeClass' => ['ReflectionClass'],
'ReflectionFunction::getClosureThis' => ['object'],
'ReflectionFunction::getDocComment' => ['string|false'],
'ReflectionFunction::getEndLine' => ['int|false'],
'ReflectionFunction::getExtension' => ['?ReflectionExtension'],
'ReflectionFunction::getExtensionName' => ['string|false'],
'ReflectionFunction::getFileName' => ['string|false'],
'ReflectionFunction::getName' => ['callable-string'],
'ReflectionFunction::getNamespaceName' => ['string'],
'ReflectionFunction::getNumberOfParameters' => ['int'],
'ReflectionFunction::getNumberOfRequiredParameters' => ['int'],
'ReflectionFunction::getParameters' => ['list<ReflectionParameter>'],
'ReflectionFunction::getReturnType' => ['?ReflectionType'],
'ReflectionFunction::getShortName' => ['string'],
'ReflectionFunction::getStartLine' => ['int|false'],
'ReflectionFunction::getStaticVariables' => ['array'],
'ReflectionFunction::hasReturnType' => ['bool'],
'ReflectionFunction::inNamespace' => ['bool'],
'ReflectionFunction::invoke' => ['mixed', '...args='=>'mixed'],
'ReflectionFunction::invokeArgs' => ['mixed', 'args'=>'array'],
'ReflectionFunction::isClosure' => ['bool'],
'ReflectionFunction::isDeprecated' => ['bool'],
'ReflectionFunction::isDisabled' => ['bool'],
'ReflectionFunction::isGenerator' => ['bool'],
'ReflectionFunction::isInternal' => ['bool'],
'ReflectionFunction::isUserDefined' => ['bool'],
'ReflectionFunction::isVariadic' => ['bool'],
'ReflectionFunction::returnsReference' => ['bool'],
'ReflectionFunctionAbstract::__clone' => ['void'],
'ReflectionFunctionAbstract::__toString' => ['string'],
'ReflectionFunctionAbstract::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
'ReflectionFunctionAbstract::getClosureScopeClass' => ['ReflectionClass|null'],
'ReflectionFunctionAbstract::getClosureThis' => ['object|null'],
'ReflectionFunctionAbstract::getDocComment' => ['string|false'],
'ReflectionFunctionAbstract::getEndLine' => ['int|false'],
'ReflectionFunctionAbstract::getExtension' => ['?ReflectionExtension'],
'ReflectionFunctionAbstract::getExtensionName' => ['string|false'],
'ReflectionFunctionAbstract::getFileName' => ['string|false'],
'ReflectionFunctionAbstract::getName' => ['string'],
'ReflectionFunctionAbstract::getNamespaceName' => ['string'],
'ReflectionFunctionAbstract::getNumberOfParameters' => ['int'],
'ReflectionFunctionAbstract::getNumberOfRequiredParameters' => ['int'],
'ReflectionFunctionAbstract::getParameters' => ['list<ReflectionParameter>'],
'ReflectionFunctionAbstract::getReturnType' => ['?ReflectionType'],
'ReflectionFunctionAbstract::getShortName' => ['string'],
'ReflectionFunctionAbstract::getStartLine' => ['int|false'],
'ReflectionFunctionAbstract::getStaticVariables' => ['array'],
'ReflectionFunctionAbstract::getTentativeReturnType' => ['?ReflectionType'],
'ReflectionFunctionAbstract::hasReturnType' => ['bool'],
'ReflectionFunctionAbstract::hasTentativeReturnType' => ['bool'],
'ReflectionFunctionAbstract::inNamespace' => ['bool'],
'ReflectionFunctionAbstract::isClosure' => ['bool'],
'ReflectionFunctionAbstract::isDeprecated' => ['bool'],
'ReflectionFunctionAbstract::isGenerator' => ['bool'],
'ReflectionFunctionAbstract::isInternal' => ['bool'],
'ReflectionFunctionAbstract::isStatic' => ['bool'],
'ReflectionFunctionAbstract::isUserDefined' => ['bool'],
'ReflectionFunctionAbstract::isVariadic' => ['bool'],
'ReflectionFunctionAbstract::returnsReference' => ['bool'],
'ReflectionGenerator::__construct' => ['void', 'generator'=>'object'],
'ReflectionGenerator::getExecutingFile' => ['string'],
'ReflectionGenerator::getExecutingGenerator' => ['Generator'],
'ReflectionGenerator::getExecutingLine' => ['int'],
'ReflectionGenerator::getFunction' => ['ReflectionFunctionAbstract'],
'ReflectionGenerator::getThis' => ['?object'],
'ReflectionGenerator::getTrace' => ['array', 'options='=>'int'],
'ReflectionMethod::__construct' => ['void', 'class'=>'class-string|object', 'name'=>'string'],
'ReflectionMethod::__construct\'1' => ['void', 'class_method'=>'string'],
'ReflectionMethod::__toString' => ['string'],
'ReflectionMethod::getClosure' => ['Closure', 'object='=>'?object'],
'ReflectionMethod::getClosureScopeClass' => ['ReflectionClass'],
'ReflectionMethod::getClosureThis' => ['object'],
'ReflectionMethod::getDeclaringClass' => ['ReflectionClass'],
'ReflectionMethod::getDocComment' => ['false|string'],
'ReflectionMethod::getEndLine' => ['false|int'],
'ReflectionMethod::getExtension' => ['?ReflectionExtension'],
'ReflectionMethod::getExtensionName' => ['string|false'],
'ReflectionMethod::getFileName' => ['false|string'],
'ReflectionMethod::getModifiers' => ['int'],
'ReflectionMethod::getName' => ['string'],
'ReflectionMethod::getNamespaceName' => ['string'],
'ReflectionMethod::getNumberOfParameters' => ['int'],
'ReflectionMethod::getNumberOfRequiredParameters' => ['int'],
'ReflectionMethod::getParameters' => ['list<\ReflectionParameter>'],
'ReflectionMethod::getPrototype' => ['ReflectionMethod'],
'ReflectionMethod::getReturnType' => ['?ReflectionType'],
'ReflectionMethod::getShortName' => ['string'],
'ReflectionMethod::getStartLine' => ['false|int'],
'ReflectionMethod::getStaticVariables' => ['array'],
'ReflectionMethod::hasReturnType' => ['bool'],
'ReflectionMethod::inNamespace' => ['bool'],
'ReflectionMethod::invoke' => ['mixed', 'object'=>'?object', '...args='=>'mixed'],
'ReflectionMethod::invokeArgs' => ['mixed', 'object'=>'?object', 'args'=>'array'],
'ReflectionMethod::isAbstract' => ['bool'],
'ReflectionMethod::isClosure' => ['bool'],
'ReflectionMethod::isConstructor' => ['bool'],
'ReflectionMethod::isDeprecated' => ['bool'],
'ReflectionMethod::isDestructor' => ['bool'],
'ReflectionMethod::isFinal' => ['bool'],
'ReflectionMethod::isGenerator' => ['bool'],
'ReflectionMethod::isInternal' => ['bool'],
'ReflectionMethod::isPrivate' => ['bool'],
'ReflectionMethod::isProtected' => ['bool'],
'ReflectionMethod::isPublic' => ['bool'],
'ReflectionMethod::isUserDefined' => ['bool'],
'ReflectionMethod::isVariadic' => ['bool'],
'ReflectionMethod::returnsReference' => ['bool'],
'ReflectionMethod::setAccessible' => ['void', 'visible'=>'bool'],
'ReflectionNamedType::__clone' => ['void'],
'ReflectionNamedType::__toString' => ['string'],
'ReflectionNamedType::allowsNull' => ['bool'],
'ReflectionNamedType::getName' => ['string'],
'ReflectionNamedType::isBuiltin' => ['bool'],
'ReflectionObject::__clone' => ['void'],
'ReflectionObject::__construct' => ['void', 'argument'=>'object'],
'ReflectionObject::__toString' => ['string'],
'ReflectionObject::getConstant' => ['mixed', 'name'=>'string'],
'ReflectionObject::getConstants' => ['array<string,mixed>'],
'ReflectionObject::getConstructor' => ['?ReflectionMethod'],
'ReflectionObject::getDefaultProperties' => ['array'],
'ReflectionObject::getDocComment' => ['false|string'],
'ReflectionObject::getEndLine' => ['false|int'],
'ReflectionObject::getExtension' => ['?ReflectionExtension'],
'ReflectionObject::getExtensionName' => ['false|string'],
'ReflectionObject::getFileName' => ['false|string'],
'ReflectionObject::getInterfaceNames' => ['class-string[]'],
'ReflectionObject::getInterfaces' => ['array<string,\ReflectionClass>'],
'ReflectionObject::getMethod' => ['ReflectionMethod', 'name'=>'string'],
'ReflectionObject::getMethods' => ['ReflectionMethod[]', 'filter='=>'?int'],
'ReflectionObject::getModifiers' => ['int'],
'ReflectionObject::getName' => ['string'],
'ReflectionObject::getNamespaceName' => ['string'],
'ReflectionObject::getParentClass' => ['ReflectionClass|false'],
'ReflectionObject::getProperties' => ['ReflectionProperty[]', 'filter='=>'?int'],
'ReflectionObject::getProperty' => ['ReflectionProperty', 'name'=>'string'],
'ReflectionObject::getReflectionConstant' => ['ReflectionClassConstant', 'name'=>'string'],
'ReflectionObject::getReflectionConstants' => ['list<\ReflectionClassConstant>'],
'ReflectionObject::getShortName' => ['string'],
'ReflectionObject::getStartLine' => ['false|int'],
'ReflectionObject::getStaticProperties' => ['ReflectionProperty[]'],
'ReflectionObject::getStaticPropertyValue' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
'ReflectionObject::getTraitAliases' => ['array<string,string>'],
'ReflectionObject::getTraitNames' => ['list<string>'],
'ReflectionObject::getTraits' => ['array<string,\ReflectionClass>'],
'ReflectionObject::hasConstant' => ['bool', 'name'=>'string'],
'ReflectionObject::hasMethod' => ['bool', 'name'=>'string'],
'ReflectionObject::hasProperty' => ['bool', 'name'=>'string'],
'ReflectionObject::implementsInterface' => ['bool', 'interface_name'=>'ReflectionClass|string'],
'ReflectionObject::inNamespace' => ['bool'],
'ReflectionObject::isAbstract' => ['bool'],
'ReflectionObject::isAnonymous' => ['bool'],
'ReflectionObject::isCloneable' => ['bool'],
'ReflectionObject::isEnum' => ['bool'],
'ReflectionObject::isFinal' => ['bool'],
'ReflectionObject::isInstance' => ['bool', 'object'=>'object'],
'ReflectionObject::isInstantiable' => ['bool'],
'ReflectionObject::isInterface' => ['bool'],
'ReflectionObject::isInternal' => ['bool'],
'ReflectionObject::isIterable' => ['bool'],
'ReflectionObject::isIterateable' => ['bool'],
'ReflectionObject::isSubclassOf' => ['bool', 'class'=>'ReflectionClass|string'],
'ReflectionObject::isTrait' => ['bool'],
'ReflectionObject::isUserDefined' => ['bool'],
'ReflectionObject::newInstance' => ['object', 'args='=>'mixed', '...args='=>'array'],
'ReflectionObject::newInstanceArgs' => ['object', 'args='=>'list<mixed>|array<string, mixed>'],
'ReflectionObject::newInstanceWithoutConstructor' => ['object'],
'ReflectionObject::setStaticPropertyValue' => ['void', 'name'=>'string', 'value'=>'string'],
'ReflectionParameter::__clone' => ['void'],
'ReflectionParameter::__construct' => ['void', 'function'=>'', 'parameter'=>''],
'ReflectionParameter::__toString' => ['string'],
'ReflectionParameter::allowsNull' => ['bool'],
'ReflectionParameter::canBePassedByValue' => ['bool'],
'ReflectionParameter::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
'ReflectionParameter::getClass' => ['?ReflectionClass'],
'ReflectionParameter::getDeclaringClass' => ['?ReflectionClass'],
'ReflectionParameter::getDeclaringFunction' => ['ReflectionFunctionAbstract'],
'ReflectionParameter::getDefaultValue' => ['mixed'],
'ReflectionParameter::getDefaultValueConstantName' => ['?string'],
'ReflectionParameter::getName' => ['string'],
'ReflectionParameter::getPosition' => ['int'],
'ReflectionParameter::getType' => ['?ReflectionType'],
'ReflectionParameter::hasType' => ['bool'],
'ReflectionParameter::isArray' => ['bool'],
'ReflectionParameter::isCallable' => ['bool'],
'ReflectionParameter::isDefaultValueAvailable' => ['bool'],
'ReflectionParameter::isDefaultValueConstant' => ['bool'],
'ReflectionParameter::isOptional' => ['bool'],
'ReflectionParameter::isPassedByReference' => ['bool'],
'ReflectionParameter::isVariadic' => ['bool'],
'ReflectionProperty::__clone' => ['void'],
'ReflectionProperty::__construct' => ['void', 'class'=>'', 'name'=>'string'],
'ReflectionProperty::__toString' => ['string'],
'ReflectionProperty::getAttributes' => ['list<ReflectionAttribute>', 'name='=>'?string', 'flags='=>'int'],
'ReflectionProperty::getDeclaringClass' => ['ReflectionClass'],
'ReflectionProperty::getDocComment' => ['string|false'],
'ReflectionProperty::getModifiers' => ['int'],
'ReflectionProperty::getName' => ['string'],
'ReflectionProperty::getType' => ['?ReflectionType'],
'ReflectionProperty::getValue' => ['mixed', 'object='=>'null|object'],
'ReflectionProperty::hasType' => ['bool'],
'ReflectionProperty::isDefault' => ['bool'],
'ReflectionProperty::isPrivate' => ['bool'],
'ReflectionProperty::isProtected' => ['bool'],
'ReflectionProperty::isPublic' => ['bool'],
'ReflectionProperty::isStatic' => ['bool'],
'ReflectionProperty::setAccessible' => ['void', 'visible'=>'bool'],
'ReflectionProperty::setValue' => ['void', 'object'=>'null|object', 'value'=>''],
'ReflectionProperty::setValue\'1' => ['void', 'value'=>''],
'ReflectionType::__clone' => ['void'],
'ReflectionType::__toString' => ['string'],
'ReflectionType::allowsNull' => ['bool'],
'ReflectionUnionType::getTypes' => ['list<ReflectionNamedType>'],
'ReflectionZendExtension::__clone' => ['void'],
'ReflectionZendExtension::__construct' => ['void', 'name'=>'string'],
'ReflectionZendExtension::__toString' => ['string'],
'ReflectionZendExtension::getAuthor' => ['string'],
'ReflectionZendExtension::getCopyright' => ['string'],
'ReflectionZendExtension::getName' => ['string'],
'ReflectionZendExtension::getURL' => ['string'],
'ReflectionZendExtension::getVersion' => ['string'],
'Reflector::__toString' => ['string'],
'Reflector::export' => ['?string'],
'RegexIterator::__construct' => ['void', 'iterator'=>'Iterator', 'regex'=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'],
'RegexIterator::accept' => ['bool'],
'RegexIterator::current' => ['mixed'],
'RegexIterator::getFlags' => ['int'],
'RegexIterator::getInnerIterator' => ['Iterator'],
'RegexIterator::getMode' => ['int'],
'RegexIterator::getPregFlags' => ['int'],
'RegexIterator::getRegex' => ['string'],
'RegexIterator::key' => ['mixed'],
'RegexIterator::next' => ['void'],
'RegexIterator::rewind' => ['void'],
'RegexIterator::setFlags' => ['void', 'new_flags'=>'int'],
'RegexIterator::setMode' => ['void', 'new_mode'=>'int'],
'RegexIterator::setPregFlags' => ['void', 'new_flags'=>'int'],
'RegexIterator::valid' => ['bool'],
'register_event_handler' => ['bool', 'event_handler_func'=>'string', 'handler_register_name'=>'string', 'event_type_mask'=>'int'],
'register_shutdown_function' => ['void', 'callback'=>'callable', '...args='=>'mixed'],
'register_tick_function' => ['bool', 'callback'=>'callable():void', '...args='=>'mixed'],
'rename' => ['bool', 'from'=>'string', 'to'=>'string', 'context='=>'resource'],
'rename_function' => ['bool', 'original_name'=>'string', 'new_name'=>'string'],
'reset' => ['mixed|false', '&r_array'=>'array|object'],
'ResourceBundle::__construct' => ['void', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'],
'ResourceBundle::count' => ['int'],
'ResourceBundle::create' => ['?ResourceBundle', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'],
'ResourceBundle::get' => ['mixed', 'index'=>'string|int', 'fallback='=>'bool'],
'ResourceBundle::getErrorCode' => ['int'],
'ResourceBundle::getErrorMessage' => ['string'],
'ResourceBundle::getLocales' => ['array', 'bundlename'=>'string'],
'resourcebundle_count' => ['int', 'bundle'=>'ResourceBundle'],
'resourcebundle_create' => ['?ResourceBundle', 'locale'=>'?string', 'bundle'=>'?string', 'fallback='=>'bool'],
'resourcebundle_get' => ['mixed|null', 'bundle'=>'ResourceBundle', 'index'=>'string|int', 'fallback='=>'bool'],
'resourcebundle_get_error_code' => ['int', 'bundle'=>'ResourceBundle'],
'resourcebundle_get_error_message' => ['string', 'bundle'=>'ResourceBundle'],
'resourcebundle_locales' => ['array', 'bundle'=>'string'],
'restore_error_handler' => ['true'],
'restore_exception_handler' => ['true'],
'restore_include_path' => ['void'],
'rewind' => ['bool', 'stream'=>'resource'],
'rewinddir' => ['void', 'dir_handle='=>'resource'],
'rmdir' => ['bool', 'directory'=>'string', 'context='=>'resource'],
'round' => ['float', 'num'=>'float', 'precision='=>'int', 'mode='=>'0|positive-int'],
'rpm_close' => ['bool', 'rpmr'=>'resource'],
'rpm_get_tag' => ['mixed', 'rpmr'=>'resource', 'tagnum'=>'int'],
'rpm_is_valid' => ['bool', 'filename'=>'string'],
'rpm_open' => ['resource|false', 'filename'=>'string'],
'rpm_version' => ['string'],
'rpmaddtag' => ['bool', 'tag'=>'int'],
'rpmdbinfo' => ['array', 'nevr'=>'string', 'full='=>'bool'],
'rpmdbsearch' => ['array', 'pattern'=>'string', 'rpmtag='=>'int', 'rpmmire='=>'int', 'full='=>'bool'],
'rpminfo' => ['array', 'path'=>'string', 'full='=>'bool', 'error='=>'string'],
'rpmvercmp' => ['int', 'evr1'=>'string', 'evr2'=>'string'],
'rrd_create' => ['bool', 'filename'=>'string', 'options'=>'array'],
'rrd_disconnect' => ['void'],
'rrd_error' => ['string'],
'rrd_fetch' => ['array', 'filename'=>'string', 'options'=>'array'],
'rrd_first' => ['int|false', 'file'=>'string', 'raaindex='=>'int'],
'rrd_graph' => ['array|false', 'filename'=>'string', 'options'=>'array'],
'rrd_info' => ['array|false', 'filename'=>'string'],
'rrd_last' => ['int', 'filename'=>'string'],
'rrd_lastupdate' => ['array|false', 'filename'=>'string'],
'rrd_restore' => ['bool', 'xml_file'=>'string', 'rrd_file'=>'string', 'options='=>'array'],
'rrd_tune' => ['bool', 'filename'=>'string', 'options'=>'array'],
'rrd_update' => ['bool', 'filename'=>'string', 'options'=>'array'],
'rrd_version' => ['string'],
'rrd_xport' => ['array|false', 'options'=>'array'],
'rrdc_disconnect' => ['void'],
'RRDCreator::__construct' => ['void', 'path'=>'string', 'starttime='=>'string', 'step='=>'int'],
'RRDCreator::addArchive' => ['void', 'description'=>'string'],
'RRDCreator::addDataSource' => ['void', 'description'=>'string'],
'RRDCreator::save' => ['bool'],
'RRDGraph::__construct' => ['void', 'path'=>'string'],
'RRDGraph::save' => ['array|false'],
'RRDGraph::saveVerbose' => ['array|false'],
'RRDGraph::setOptions' => ['void', 'options'=>'array'],
'RRDUpdater::__construct' => ['void', 'path'=>'string'],
'RRDUpdater::update' => ['bool', 'values'=>'array', 'time='=>'string'],
'rsort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
'rtrim' => ['string', 'string'=>'string', 'characters='=>'string'],
'runkit7_constant_add' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'new_visibility='=>'int'],
'runkit7_constant_redefine' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'new_visibility='=>'?int'],
'runkit7_constant_remove' => ['bool', 'constant_name'=>'string'],
'runkit7_function_add' => ['bool', 'function_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_doc_comment='=>'?string', 'return_by_reference='=>'?bool', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
'runkit7_function_copy' => ['bool', 'source_name'=>'string', 'target_name'=>'string'],
'runkit7_function_redefine' => ['bool', 'function_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_doc_comment='=>'?string', 'return_by_reference='=>'?bool', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
'runkit7_function_remove' => ['bool', 'function_name'=>'string'],
'runkit7_function_rename' => ['bool', 'source_name'=>'string', 'target_name'=>'string'],
'runkit7_import' => ['bool', 'filename'=>'string', 'flags='=>'?int'],
'runkit7_method_add' => ['bool', 'class_name'=>'string', 'method_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_flags='=>'int|null|string', 'flags_or_doc_comment='=>'int|null|string', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
'runkit7_method_copy' => ['bool', 'destination_class'=>'string', 'destination_method'=>'string', 'source_class'=>'string', 'source_method='=>'?string'],
'runkit7_method_redefine' => ['bool', 'class_name'=>'string', 'method_name'=>'string', 'argument_list_or_closure'=>'Closure|string', 'code_or_flags='=>'int|null|string', 'flags_or_doc_comment='=>'int|null|string', 'doc_comment='=>'?string', 'return_type='=>'?string', 'is_strict='=>'?bool'],
'runkit7_method_remove' => ['bool', 'class_name'=>'string', 'method_name'=>'string'],
'runkit7_method_rename' => ['bool', 'class_name'=>'string', 'source_method_name'=>'string', 'source_target_name'=>'string'],
'runkit7_superglobals' => ['array'],
'runkit7_zval_inspect' => ['array', 'value'=>'mixed'],
'runkit_class_adopt' => ['bool', 'classname'=>'string', 'parentname'=>'string'],
'runkit_class_emancipate' => ['bool', 'classname'=>'string'],
'runkit_constant_add' => ['bool', 'constname'=>'string', 'value'=>'mixed'],
'runkit_constant_redefine' => ['bool', 'constname'=>'string', 'newvalue'=>'mixed'],
'runkit_constant_remove' => ['bool', 'constname'=>'string'],
'runkit_function_add' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'],
'runkit_function_add\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'],
'runkit_function_copy' => ['bool', 'funcname'=>'string', 'targetname'=>'string'],
'runkit_function_redefine' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'],
'runkit_function_redefine\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'],
'runkit_function_remove' => ['bool', 'funcname'=>'string'],
'runkit_function_rename' => ['bool', 'funcname'=>'string', 'newname'=>'string'],
'runkit_import' => ['bool', 'filename'=>'string', 'flags='=>'int'],
'runkit_lint' => ['bool', 'code'=>'string'],
'runkit_lint_file' => ['bool', 'filename'=>'string'],
'runkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'],
'runkit_method_add\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'],
'runkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'],
'runkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'],
'runkit_method_redefine\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'],
'runkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'],
'runkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'],
'runkit_return_value_used' => ['bool'],
'Runkit_Sandbox::__construct' => ['void', 'options='=>'array'],
'runkit_sandbox_output_handler' => ['mixed', 'sandbox'=>'object', 'callback='=>'mixed'],
'Runkit_Sandbox_Parent' => [''],
'Runkit_Sandbox_Parent::__construct' => ['void'],
'runkit_superglobals' => ['array'],
'runkit_zval_inspect' => ['array', 'value'=>'mixed'],
'RuntimeException::__clone' => ['void'],
'RuntimeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'RuntimeException::__toString' => ['string'],
'RuntimeException::getCode' => ['int'],
'RuntimeException::getFile' => ['string'],
'RuntimeException::getLine' => ['int'],
'RuntimeException::getMessage' => ['string'],
'RuntimeException::getPrevious' => ['?Throwable'],
'RuntimeException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'RuntimeException::getTraceAsString' => ['string'],
'SAMConnection::commit' => ['bool'],
'SAMConnection::connect' => ['bool', 'protocol'=>'string', 'properties='=>'array'],
'SAMConnection::disconnect' => ['bool'],
'SAMConnection::errno' => ['int'],
'SAMConnection::error' => ['string'],
'SAMConnection::isConnected' => ['bool'],
'SAMConnection::peek' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'],
'SAMConnection::peekAll' => ['array', 'target'=>'string', 'properties='=>'array'],
'SAMConnection::receive' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'],
'SAMConnection::remove' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'],
'SAMConnection::rollback' => ['bool'],
'SAMConnection::send' => ['string', 'target'=>'string', 'msg'=>'sammessage', 'properties='=>'array'],
'SAMConnection::setDebug' => ['', 'switch'=>'bool'],
'SAMConnection::subscribe' => ['string', 'targettopic'=>'string'],
'SAMConnection::unsubscribe' => ['bool', 'subscriptionid'=>'string', 'targettopic='=>'string'],
'SAMMessage::body' => ['string'],
'SAMMessage::header' => ['object'],
'sapi_windows_cp_conv' => ['?string', 'in_codepage'=>'int|string', 'out_codepage'=>'int|string', 'subject'=>'string'],
'sapi_windows_cp_get' => ['int'],
'sapi_windows_cp_is_utf8' => ['bool'],
'sapi_windows_cp_set' => ['bool', 'codepage'=>'int'],
'sapi_windows_vt100_support' => ['bool', 'stream'=>'resource', 'enable='=>'?bool'],
'Saxon\SaxonProcessor::__construct' => ['void', 'license='=>'bool', 'cwd='=>'string'],
'Saxon\SaxonProcessor::createAtomicValue' => ['Saxon\XdmValue', 'primitive_type_val'=>'bool|float|int|string'],
'Saxon\SaxonProcessor::newSchemaValidator' => ['Saxon\SchemaValidator'],
'Saxon\SaxonProcessor::newXPathProcessor' => ['Saxon\XPathProcessor'],
'Saxon\SaxonProcessor::newXQueryProcessor' => ['Saxon\XQueryProcessor'],
'Saxon\SaxonProcessor::newXsltProcessor' => ['Saxon\XsltProcessor'],
'Saxon\SaxonProcessor::parseXmlFromFile' => ['Saxon\XdmNode', 'fileName'=>'string'],
'Saxon\SaxonProcessor::parseXmlFromString' => ['Saxon\XdmNode', 'value'=>'string'],
'Saxon\SaxonProcessor::registerPHPFunctions' => ['void', 'library'=>'string'],
'Saxon\SaxonProcessor::setConfigurationProperty' => ['void', 'name'=>'string', 'value'=>'string'],
'Saxon\SaxonProcessor::setcwd' => ['void', 'cwd'=>'string'],
'Saxon\SaxonProcessor::setResourceDirectory' => ['void', 'dir'=>'string'],
'Saxon\SaxonProcessor::version' => ['string'],
'Saxon\SchemaValidator::clearParameters' => ['void'],
'Saxon\SchemaValidator::clearProperties' => ['void'],
'Saxon\SchemaValidator::exceptionClear' => ['void'],
'Saxon\SchemaValidator::getErrorCode' => ['string', 'i'=>'int'],
'Saxon\SchemaValidator::getErrorMessage' => ['string', 'i'=>'int'],
'Saxon\SchemaValidator::getExceptionCount' => ['int'],
'Saxon\SchemaValidator::getValidationReport' => ['Saxon\XdmNode'],
'Saxon\SchemaValidator::registerSchemaFromFile' => ['void', 'fileName'=>'string'],
'Saxon\SchemaValidator::registerSchemaFromString' => ['void', 'schemaStr'=>'string'],
'Saxon\SchemaValidator::setOutputFile' => ['void', 'fileName'=>'string'],
'Saxon\SchemaValidator::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
'Saxon\SchemaValidator::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
'Saxon\SchemaValidator::setSourceNode' => ['void', 'node'=>'Saxon\XdmNode'],
'Saxon\SchemaValidator::validate' => ['void', 'filename='=>'?string'],
'Saxon\SchemaValidator::validateToNode' => ['Saxon\XdmNode', 'filename='=>'?string'],
'Saxon\XdmAtomicValue::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
'Saxon\XdmAtomicValue::getAtomicValue' => ['?Saxon\XdmAtomicValue'],
'Saxon\XdmAtomicValue::getBooleanValue' => ['bool'],
'Saxon\XdmAtomicValue::getDoubleValue' => ['float'],
'Saxon\XdmAtomicValue::getHead' => ['Saxon\XdmItem'],
'Saxon\XdmAtomicValue::getLongValue' => ['int'],
'Saxon\XdmAtomicValue::getNodeValue' => ['?Saxon\XdmNode'],
'Saxon\XdmAtomicValue::getStringValue' => ['string'],
'Saxon\XdmAtomicValue::isAtomic' => ['true'],
'Saxon\XdmAtomicValue::isNode' => ['bool'],
'Saxon\XdmAtomicValue::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
'Saxon\XdmAtomicValue::size' => ['int'],
'Saxon\XdmItem::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
'Saxon\XdmItem::getAtomicValue' => ['?Saxon\XdmAtomicValue'],
'Saxon\XdmItem::getHead' => ['Saxon\XdmItem'],
'Saxon\XdmItem::getNodeValue' => ['?Saxon\XdmNode'],
'Saxon\XdmItem::getStringValue' => ['string'],
'Saxon\XdmItem::isAtomic' => ['bool'],
'Saxon\XdmItem::isNode' => ['bool'],
'Saxon\XdmItem::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
'Saxon\XdmItem::size' => ['int'],
'Saxon\XdmNode::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
'Saxon\XdmNode::getAtomicValue' => ['?Saxon\XdmAtomicValue'],
'Saxon\XdmNode::getAttributeCount' => ['int'],
'Saxon\XdmNode::getAttributeNode' => ['?Saxon\XdmNode', 'index'=>'int'],
'Saxon\XdmNode::getAttributeValue' => ['?string', 'index'=>'int'],
'Saxon\XdmNode::getChildCount' => ['int'],
'Saxon\XdmNode::getChildNode' => ['?Saxon\XdmNode', 'index'=>'int'],
'Saxon\XdmNode::getHead' => ['Saxon\XdmItem'],
'Saxon\XdmNode::getNodeKind' => ['int'],
'Saxon\XdmNode::getNodeName' => ['string'],
'Saxon\XdmNode::getNodeValue' => ['?Saxon\XdmNode'],
'Saxon\XdmNode::getParent' => ['?Saxon\XdmNode'],
'Saxon\XdmNode::getStringValue' => ['string'],
'Saxon\XdmNode::isAtomic' => ['false'],
'Saxon\XdmNode::isNode' => ['bool'],
'Saxon\XdmNode::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
'Saxon\XdmNode::size' => ['int'],
'Saxon\XdmValue::addXdmItem' => ['', 'item'=>'Saxon\XdmItem'],
'Saxon\XdmValue::getHead' => ['Saxon\XdmItem'],
'Saxon\XdmValue::itemAt' => ['Saxon\XdmItem', 'index'=>'int'],
'Saxon\XdmValue::size' => ['int'],
'Saxon\XPathProcessor::clearParameters' => ['void'],
'Saxon\XPathProcessor::clearProperties' => ['void'],
'Saxon\XPathProcessor::declareNamespace' => ['void', 'prefix'=>'', 'namespace'=>''],
'Saxon\XPathProcessor::effectiveBooleanValue' => ['bool', 'xpathStr'=>'string'],
'Saxon\XPathProcessor::evaluate' => ['Saxon\XdmValue', 'xpathStr'=>'string'],
'Saxon\XPathProcessor::evaluateSingle' => ['Saxon\XdmItem', 'xpathStr'=>'string'],
'Saxon\XPathProcessor::exceptionClear' => ['void'],
'Saxon\XPathProcessor::getErrorCode' => ['string', 'i'=>'int'],
'Saxon\XPathProcessor::getErrorMessage' => ['string', 'i'=>'int'],
'Saxon\XPathProcessor::getExceptionCount' => ['int'],
'Saxon\XPathProcessor::setBaseURI' => ['void', 'uri'=>'string'],
'Saxon\XPathProcessor::setContextFile' => ['void', 'fileName'=>'string'],
'Saxon\XPathProcessor::setContextItem' => ['void', 'item'=>'Saxon\XdmItem'],
'Saxon\XPathProcessor::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
'Saxon\XPathProcessor::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
'Saxon\XQueryProcessor::clearParameters' => ['void'],
'Saxon\XQueryProcessor::clearProperties' => ['void'],
'Saxon\XQueryProcessor::declareNamespace' => ['void', 'prefix'=>'string', 'namespace'=>'string'],
'Saxon\XQueryProcessor::exceptionClear' => ['void'],
'Saxon\XQueryProcessor::getErrorCode' => ['string', 'i'=>'int'],
'Saxon\XQueryProcessor::getErrorMessage' => ['string', 'i'=>'int'],
'Saxon\XQueryProcessor::getExceptionCount' => ['int'],
'Saxon\XQueryProcessor::runQueryToFile' => ['void', 'outfilename'=>'string'],
'Saxon\XQueryProcessor::runQueryToString' => ['?string'],
'Saxon\XQueryProcessor::runQueryToValue' => ['?Saxon\XdmValue'],
'Saxon\XQueryProcessor::setContextItem' => ['void', 'object'=>'Saxon\XdmAtomicValue|Saxon\XdmItem|Saxon\XdmNode|Saxon\XdmValue'],
'Saxon\XQueryProcessor::setContextItemFromFile' => ['void', 'fileName'=>'string'],
'Saxon\XQueryProcessor::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
'Saxon\XQueryProcessor::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
'Saxon\XQueryProcessor::setQueryBaseURI' => ['void', 'uri'=>'string'],
'Saxon\XQueryProcessor::setQueryContent' => ['void', 'string'=>'string'],
'Saxon\XQueryProcessor::setQueryFile' => ['void', 'filename'=>'string'],
'Saxon\XQueryProcessor::setQueryItem' => ['void', 'item'=>'Saxon\XdmItem'],
'Saxon\XsltProcessor::clearParameters' => ['void'],
'Saxon\XsltProcessor::clearProperties' => ['void'],
'Saxon\XsltProcessor::compileFromFile' => ['void', 'fileName'=>'string'],
'Saxon\XsltProcessor::compileFromString' => ['void', 'string'=>'string'],
'Saxon\XsltProcessor::compileFromValue' => ['void', 'node'=>'Saxon\XdmNode'],
'Saxon\XsltProcessor::exceptionClear' => ['void'],
'Saxon\XsltProcessor::getErrorCode' => ['string', 'i'=>'int'],
'Saxon\XsltProcessor::getErrorMessage' => ['string', 'i'=>'int'],
'Saxon\XsltProcessor::getExceptionCount' => ['int'],
'Saxon\XsltProcessor::setOutputFile' => ['void', 'fileName'=>'string'],
'Saxon\XsltProcessor::setParameter' => ['void', 'name'=>'string', 'value'=>'Saxon\XdmValue'],
'Saxon\XsltProcessor::setProperty' => ['void', 'name'=>'string', 'value'=>'string'],
'Saxon\XsltProcessor::setSourceFromFile' => ['void', 'filename'=>'string'],
'Saxon\XsltProcessor::setSourceFromXdmValue' => ['void', 'value'=>'Saxon\XdmValue'],
'Saxon\XsltProcessor::transformFileToFile' => ['void', 'sourceFileName'=>'string', 'stylesheetFileName'=>'string', 'outputfileName'=>'string'],
'Saxon\XsltProcessor::transformFileToString' => ['?string', 'sourceFileName'=>'string', 'stylesheetFileName'=>'string'],
'Saxon\XsltProcessor::transformFileToValue' => ['Saxon\XdmValue', 'fileName'=>'string'],
'Saxon\XsltProcessor::transformToFile' => ['void'],
'Saxon\XsltProcessor::transformToString' => ['string'],
'Saxon\XsltProcessor::transformToValue' => ['?Saxon\XdmValue'],
'SCA::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
'SCA::getService' => ['', 'target'=>'string', 'binding='=>'string', 'config='=>'array'],
'SCA_LocalProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
'SCA_SoapProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
'scalebarObj::convertToString' => ['string'],
'scalebarObj::free' => ['void'],
'scalebarObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'scalebarObj::setImageColor' => ['int', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
'scalebarObj::updateFromString' => ['int', 'snippet'=>'string'],
'scandir' => ['list<string>|false', 'directory'=>'string', 'sorting_order='=>'int', 'context='=>'resource'],
'SDO_DAS_ChangeSummary::beginLogging' => [''],
'SDO_DAS_ChangeSummary::endLogging' => [''],
'SDO_DAS_ChangeSummary::getChangedDataObjects' => ['SDO_List'],
'SDO_DAS_ChangeSummary::getChangeType' => ['int', 'dataobject'=>'sdo_dataobject'],
'SDO_DAS_ChangeSummary::getOldContainer' => ['SDO_DataObject', 'data_object'=>'sdo_dataobject'],
'SDO_DAS_ChangeSummary::getOldValues' => ['SDO_List', 'data_object'=>'sdo_dataobject'],
'SDO_DAS_ChangeSummary::isLogging' => ['bool'],
'SDO_DAS_DataFactory::addPropertyToType' => ['', 'parent_type_namespace_uri'=>'string', 'parent_type_name'=>'string', 'property_name'=>'string', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'],
'SDO_DAS_DataFactory::addType' => ['', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'],
'SDO_DAS_DataFactory::getDataFactory' => ['SDO_DAS_DataFactory'],
'SDO_DAS_DataObject::getChangeSummary' => ['SDO_DAS_ChangeSummary'],
'SDO_DAS_Relational::__construct' => ['void', 'database_metadata'=>'array', 'application_root_type='=>'string', 'sdo_containment_references_metadata='=>'array'],
'SDO_DAS_Relational::applyChanges' => ['', 'database_handle'=>'pdo', 'root_data_object'=>'sdodataobject'],
'SDO_DAS_Relational::createRootDataObject' => ['SDODataObject'],
'SDO_DAS_Relational::executePreparedQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'prepared_statement'=>'pdostatement', 'value_list'=>'array', 'column_specifier='=>'array'],
'SDO_DAS_Relational::executeQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'sql_statement'=>'string', 'column_specifier='=>'array'],
'SDO_DAS_Setting::getListIndex' => ['int'],
'SDO_DAS_Setting::getPropertyIndex' => ['int'],
'SDO_DAS_Setting::getPropertyName' => ['string'],
'SDO_DAS_Setting::getValue' => [''],
'SDO_DAS_Setting::isSet' => ['bool'],
'SDO_DAS_XML::addTypes' => ['', 'xsd_file'=>'string'],
'SDO_DAS_XML::create' => ['SDO_DAS_XML', 'xsd_file='=>'mixed', 'key='=>'string'],
'SDO_DAS_XML::createDataObject' => ['SDO_DataObject', 'namespace_uri'=>'string', 'type_name'=>'string'],
'SDO_DAS_XML::createDocument' => ['SDO_DAS_XML_Document', 'document_element_name'=>'string', 'document_element_namespace_uri'=>'string', 'dataobject='=>'sdo_dataobject'],
'SDO_DAS_XML::loadFile' => ['SDO_XMLDocument', 'xml_file'=>'string'],
'SDO_DAS_XML::loadString' => ['SDO_DAS_XML_Document', 'xml_string'=>'string'],
'SDO_DAS_XML::saveFile' => ['', 'xdoc'=>'sdo_xmldocument', 'xml_file'=>'string', 'indent='=>'int'],
'SDO_DAS_XML::saveString' => ['string', 'xdoc'=>'sdo_xmldocument', 'indent='=>'int'],
'SDO_DAS_XML_Document::getRootDataObject' => ['SDO_DataObject'],
'SDO_DAS_XML_Document::getRootElementName' => ['string'],
'SDO_DAS_XML_Document::getRootElementURI' => ['string'],
'SDO_DAS_XML_Document::setEncoding' => ['', 'encoding'=>'string'],
'SDO_DAS_XML_Document::setXMLDeclaration' => ['', 'xmldeclatation'=>'bool'],
'SDO_DAS_XML_Document::setXMLVersion' => ['', 'xmlversion'=>'string'],
'SDO_DataFactory::create' => ['void', 'type_namespace_uri'=>'string', 'type_name'=>'string'],
'SDO_DataObject::clear' => ['void'],
'SDO_DataObject::createDataObject' => ['SDO_DataObject', 'identifier'=>''],
'SDO_DataObject::getContainer' => ['SDO_DataObject'],
'SDO_DataObject::getSequence' => ['SDO_Sequence'],
'SDO_DataObject::getTypeName' => ['string'],
'SDO_DataObject::getTypeNamespaceURI' => ['string'],
'SDO_Exception::getCause' => [''],
'SDO_List::insert' => ['void', 'value'=>'mixed', 'index='=>'int'],
'SDO_Model_Property::getContainingType' => ['SDO_Model_Type'],
'SDO_Model_Property::getDefault' => [''],
'SDO_Model_Property::getName' => ['string'],
'SDO_Model_Property::getType' => ['SDO_Model_Type'],
'SDO_Model_Property::isContainment' => ['bool'],
'SDO_Model_Property::isMany' => ['bool'],
'SDO_Model_ReflectionDataObject::__construct' => ['void', 'data_object'=>'sdo_dataobject'],
'SDO_Model_ReflectionDataObject::export' => ['mixed', 'rdo'=>'sdo_model_reflectiondataobject', 'return='=>'bool'],
'SDO_Model_ReflectionDataObject::getContainmentProperty' => ['SDO_Model_Property'],
'SDO_Model_ReflectionDataObject::getInstanceProperties' => ['array'],
'SDO_Model_ReflectionDataObject::getType' => ['SDO_Model_Type'],
'SDO_Model_Type::getBaseType' => ['SDO_Model_Type'],
'SDO_Model_Type::getName' => ['string'],
'SDO_Model_Type::getNamespaceURI' => ['string'],
'SDO_Model_Type::getProperties' => ['array'],
'SDO_Model_Type::getProperty' => ['SDO_Model_Property', 'identifier'=>''],
'SDO_Model_Type::isAbstractType' => ['bool'],
'SDO_Model_Type::isDataType' => ['bool'],
'SDO_Model_Type::isInstance' => ['bool', 'data_object'=>'sdo_dataobject'],
'SDO_Model_Type::isOpenType' => ['bool'],
'SDO_Model_Type::isSequencedType' => ['bool'],
'SDO_Sequence::getProperty' => ['SDO_Model_Property', 'sequence_index'=>'int'],
'SDO_Sequence::insert' => ['void', 'value'=>'mixed', 'sequenceindex='=>'int', 'propertyidentifier='=>'mixed'],
'SDO_Sequence::move' => ['void', 'toindex'=>'int', 'fromindex'=>'int'],
'SeasLog::__destruct' => ['void'],
'SeasLog::alert' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::analyzerCount' => ['mixed', 'level'=>'string', 'log_path='=>'string', 'key_word='=>'string'],
'SeasLog::analyzerDetail' => ['mixed', 'level'=>'string', 'log_path='=>'string', 'key_word='=>'string', 'start='=>'int', 'limit='=>'int', 'order='=>'int'],
'SeasLog::closeLoggerStream' => ['bool', 'model'=>'int', 'logger'=>'string'],
'SeasLog::critical' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::debug' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::emergency' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::error' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::flushBuffer' => ['bool'],
'SeasLog::getBasePath' => ['string'],
'SeasLog::getBuffer' => ['array'],
'SeasLog::getBufferEnabled' => ['bool'],
'SeasLog::getDatetimeFormat' => ['string'],
'SeasLog::getLastLogger' => ['string'],
'SeasLog::getRequestID' => ['string'],
'SeasLog::getRequestVariable' => ['bool', 'key'=>'int'],
'SeasLog::info' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::log' => ['bool', 'level'=>'string', 'message='=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::notice' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'SeasLog::setBasePath' => ['bool', 'base_path'=>'string'],
'SeasLog::setDatetimeFormat' => ['bool', 'format'=>'string'],
'SeasLog::setLogger' => ['bool', 'logger'=>'string'],
'SeasLog::setRequestID' => ['bool', 'request_id'=>'string'],
'SeasLog::setRequestVariable' => ['bool', 'key'=>'int', 'value'=>'string'],
'SeasLog::warning' => ['bool', 'message'=>'string', 'content='=>'array', 'logger='=>'string'],
'seaslog_get_author' => ['string'],
'seaslog_get_version' => ['string'],
'SeekableIterator::__construct' => ['void'],
'SeekableIterator::current' => ['mixed'],
'SeekableIterator::key' => ['int|string'],
'SeekableIterator::next' => ['void'],
'SeekableIterator::rewind' => ['void'],
'SeekableIterator::seek' => ['void', 'position'=>'int'],
'SeekableIterator::valid' => ['bool'],
'sem_acquire' => ['bool', 'semaphore'=>'resource', 'non_blocking='=>'bool'],
'sem_get' => ['resource|false', 'key'=>'int', 'max_acquire='=>'int', 'permissions='=>'int', 'auto_release='=>'int'],
'sem_release' => ['bool', 'semaphore'=>'resource'],
'sem_remove' => ['bool', 'semaphore'=>'resource'],
'Serializable::__construct' => ['void'],
'Serializable::serialize' => ['?string'],
'Serializable::unserialize' => ['void', 'serialized'=>'string'],
'serialize' => ['string', 'value'=>'mixed'],
'ServerRequest::withInput' => ['ServerRequest', 'input'=>'mixed'],
'ServerRequest::withoutParams' => ['ServerRequest', 'params'=>'int|string'],
'ServerRequest::withParam' => ['ServerRequest', 'key'=>'int|string', 'value'=>'mixed'],
'ServerRequest::withParams' => ['ServerRequest', 'params'=>'mixed'],
'ServerRequest::withUrl' => ['ServerRequest', 'url'=>'array'],
'ServerResponse::addHeader' => ['void', 'label'=>'string', 'value'=>'string'],
'ServerResponse::date' => ['string', 'date'=>'string|DateTimeInterface'],
'ServerResponse::getHeader' => ['string', 'label'=>'string'],
'ServerResponse::getHeaders' => ['string[]'],
'ServerResponse::getStatus' => ['int'],
'ServerResponse::getVersion' => ['string'],
'ServerResponse::setHeader' => ['void', 'label'=>'string', 'value'=>'string'],
'ServerResponse::setStatus' => ['void', 'status'=>'int'],
'ServerResponse::setVersion' => ['void', 'version'=>'string'],
'session_abort' => ['bool'],
'session_cache_expire' => ['int', 'value='=>'?int'],
'session_cache_limiter' => ['string', 'value='=>'?string'],
'session_commit' => ['bool'],
'session_create_id' => ['string', 'prefix='=>'string'],
'session_decode' => ['bool', 'data'=>'string'],
'session_destroy' => ['bool'],
'session_encode' => ['string'],
'session_gc' => ['int|false'],
'session_get_cookie_params' => ['array'],
'session_id' => ['string|false', 'id='=>'?string'],
'session_is_registered' => ['bool', 'name'=>'string'],
'session_module_name' => ['string', 'module='=>'?string'],
'session_name' => ['string|false', 'name='=>'?string'],
'session_pgsql_add_error' => ['bool', 'error_level'=>'int', 'error_message='=>'string'],
'session_pgsql_get_error' => ['array', 'with_error_message='=>'bool'],
'session_pgsql_get_field' => ['string'],
'session_pgsql_reset' => ['bool'],
'session_pgsql_set_field' => ['bool', 'value'=>'string'],
'session_pgsql_status' => ['array'],
'session_regenerate_id' => ['bool', 'delete_old_session='=>'bool'],
'session_register' => ['bool', 'name'=>'mixed', '...args='=>'mixed'],
'session_register_shutdown' => ['void'],
'session_reset' => ['bool'],
'session_save_path' => ['string', 'path='=>'?string'],
'session_set_cookie_params' => ['bool', 'lifetime'=>'int', 'path='=>'?string', 'domain='=>'?string', 'secure='=>'?bool', 'httponly='=>'?bool'],
'session_set_cookie_params\'1' => ['bool', 'options'=>'array{lifetime?:?int,path?:?string,domain?:?string,secure?:?bool,httponly?:?bool,samesite?:?string}'],
'session_set_save_handler' => ['bool', 'open'=>'callable(string,string):bool', 'close'=>'callable():bool', 'read'=>'callable(string):string', 'write'=>'callable(string,string):bool', 'destroy'=>'callable(string):bool', 'gc'=>'callable(string):bool', 'create_sid='=>'callable():string', 'validate_sid='=>'callable(string):bool', 'update_timestamp='=>'callable(string):bool'],
'session_set_save_handler\'1' => ['bool', 'open'=>'SessionHandlerInterface', 'close='=>'bool'],
'session_start' => ['bool', 'options='=>'array'],
'session_status' => ['int'],
'session_unregister' => ['bool', 'name'=>'string'],
'session_unset' => ['bool'],
'session_write_close' => ['bool'],
'SessionHandler::close' => ['bool'],
'SessionHandler::create_sid' => ['string'],
'SessionHandler::destroy' => ['bool', 'id'=>'string'],
'SessionHandler::gc' => ['bool', 'maxlifetime'=>'int'],
'SessionHandler::open' => ['bool', 'save_path'=>'string', 'session_name'=>'string'],
'SessionHandler::read' => ['string', 'id'=>'string'],
'SessionHandler::write' => ['bool', 'id'=>'string', 'data'=>'string'],
'SessionHandlerInterface::close' => ['bool'],
'SessionHandlerInterface::destroy' => ['bool', 'id'=>'string'],
'SessionHandlerInterface::gc' => ['int|false', 'max_lifetime'=>'int'],
'SessionHandlerInterface::open' => ['bool', 'path'=>'string', 'name'=>'string'],
'SessionHandlerInterface::read' => ['string|false', 'id'=>'string'],
'SessionHandlerInterface::write' => ['bool', 'id'=>'string', 'data'=>'string'],
'SessionIdInterface::create_sid' => ['string'],
'SessionUpdateTimestampHandler::updateTimestamp' => ['bool', 'id'=>'string', 'data'=>'string'],
'SessionUpdateTimestampHandler::validateId' => ['char', 'id'=>'string'],
'SessionUpdateTimestampHandlerInterface::updateTimestamp' => ['bool', 'key'=>'string', 'value'=>'string'],
'SessionUpdateTimestampHandlerInterface::validateId' => ['bool', 'key'=>'string'],
'set_error_handler' => ['null|callable(int,string,string=,int=,array=):bool', 'callback'=>'null|callable(int,string,string=,int=,array=):bool', 'error_levels='=>'int'],
'set_exception_handler' => ['null|callable(Throwable):void', 'callback'=>'null|callable(Throwable):void'],
'set_file_buffer' => ['int', 'stream'=>'resource', 'size'=>'int'],
'set_include_path' => ['string|false', 'include_path'=>'string'],
'set_magic_quotes_runtime' => ['bool', 'new_setting'=>'bool'],
'set_time_limit' => ['bool', 'seconds'=>'int'],
'setcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool', 'samesite='=>'string', 'url_encode='=>'int'],
'setcookie\'1' => ['bool', 'name'=>'string', 'value='=>'string', 'options='=>'array'],
'setLeftFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'setLine' => ['void', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'setlocale' => ['string|false', 'category'=>'int', 'locales'=>'string|0|null', '...rest='=>'string'],
'setlocale\'1' => ['string|false', 'category'=>'int', 'locales'=>'?array'],
'setproctitle' => ['void', 'title'=>'string'],
'setrawcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'],
'setrawcookie\'1' => ['bool', 'name'=>'string', 'value='=>'string', 'options='=>'array'],
'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'setthreadtitle' => ['bool', 'title'=>'string'],
'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'],
'sha1' => ['string', 'string'=>'string', 'binary='=>'bool'],
'sha1_file' => ['string|false', 'filename'=>'string', 'binary='=>'bool'],
'sha256' => ['string', 'string'=>'string', 'raw_output='=>'bool'],
'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'],
'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'],
'shapefileObj::addPoint' => ['int', 'point'=>'pointObj'],
'shapefileObj::addShape' => ['int', 'shape'=>'shapeObj'],
'shapefileObj::free' => ['void'],
'shapefileObj::getExtent' => ['rectObj', 'i'=>'int'],
'shapefileObj::getPoint' => ['shapeObj', 'i'=>'int'],
'shapefileObj::getShape' => ['shapeObj', 'i'=>'int'],
'shapefileObj::getTransformed' => ['shapeObj', 'map'=>'mapObj', 'i'=>'int'],
'shapefileObj::ms_newShapefileObj' => ['shapefileObj', 'filename'=>'string', 'type'=>'int'],
'shapeObj::__construct' => ['void', 'type'=>'int'],
'shapeObj::add' => ['int', 'line'=>'lineObj'],
'shapeObj::boundary' => ['shapeObj'],
'shapeObj::contains' => ['bool', 'point'=>'pointObj'],
'shapeObj::containsShape' => ['int', 'shape2'=>'shapeObj'],
'shapeObj::convexhull' => ['shapeObj'],
'shapeObj::crosses' => ['int', 'shape'=>'shapeObj'],
'shapeObj::difference' => ['shapeObj', 'shape'=>'shapeObj'],
'shapeObj::disjoint' => ['int', 'shape'=>'shapeObj'],
'shapeObj::draw' => ['int', 'map'=>'mapObj', 'layer'=>'layerObj', 'img'=>'imageObj'],
'shapeObj::equals' => ['int', 'shape'=>'shapeObj'],
'shapeObj::free' => ['void'],
'shapeObj::getArea' => ['float'],
'shapeObj::getCentroid' => ['pointObj'],
'shapeObj::getLabelPoint' => ['pointObj'],
'shapeObj::getLength' => ['float'],
'shapeObj::getPointUsingMeasure' => ['pointObj', 'm'=>'float'],
'shapeObj::getValue' => ['string', 'layer'=>'layerObj', 'filedname'=>'string'],
'shapeObj::intersection' => ['shapeObj', 'shape'=>'shapeObj'],
'shapeObj::intersects' => ['bool', 'shape'=>'shapeObj'],
'shapeObj::line' => ['lineObj', 'i'=>'int'],
'shapeObj::ms_shapeObjFromWkt' => ['shapeObj', 'wkt'=>'string'],
'shapeObj::overlaps' => ['int', 'shape'=>'shapeObj'],
'shapeObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'],
'shapeObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'shapeObj::setBounds' => ['int'],
'shapeObj::simplify' => ['shapeObj|null', 'tolerance'=>'float'],
'shapeObj::symdifference' => ['shapeObj', 'shape'=>'shapeObj'],
'shapeObj::topologyPreservingSimplify' => ['shapeObj|null', 'tolerance'=>'float'],
'shapeObj::touches' => ['int', 'shape'=>'shapeObj'],
'shapeObj::toWkt' => ['string'],
'shapeObj::union' => ['shapeObj', 'shape'=>'shapeObj'],
'shapeObj::within' => ['int', 'shape2'=>'shapeObj'],
'shell_exec' => ['string|false|null', 'command'=>'string'],
'shm_attach' => ['SysvSharedMemory|false', 'key'=>'int', 'size='=>'?int', 'permissions='=>'int'],
'shm_detach' => ['bool', 'shm'=>'resource'],
'shm_get_var' => ['mixed', 'shm'=>'resource', 'key'=>'int'],
'shm_has_var' => ['bool', 'shm'=>'resource', 'key'=>'int'],
'shm_put_var' => ['bool', 'shm'=>'resource', 'key'=>'int', 'value'=>'mixed'],
'shm_remove' => ['bool', 'shm'=>'resource'],
'shm_remove_var' => ['bool', 'shm'=>'resource', 'key'=>'int'],
'shmop_close' => ['void', 'shmop'=>'Shmop'],
'shmop_delete' => ['bool', 'shmop'=>'Shmop'],
'shmop_open' => ['Shmop|false', 'key'=>'int', 'mode'=>'string', 'permissions'=>'int', 'size'=>'int'],
'shmop_read' => ['string', 'shmop'=>'Shmop', 'offset'=>'int', 'size'=>'int'],
'shmop_size' => ['int', 'shmop'=>'Shmop'],
'shmop_write' => ['int', 'shmop'=>'Shmop', 'data'=>'string', 'offset'=>'int'],
'show_source' => ['string|bool', 'filename'=>'string', 'return='=>'bool'],
'shuffle' => ['bool', '&rw_array'=>'array'],
'signeurlpaiement' => ['string', 'clent'=>'string', 'data'=>'string'],
'similar_text' => ['int', 'string1'=>'string', 'string2'=>'string', '&w_percent='=>'float'],
'simplexml_import_dom' => ['?SimpleXMLElement', 'node'=>'DOMNode', 'class_name='=>'?string'],
'simplexml_load_file' => ['SimpleXMLElement|false', 'filename'=>'string', 'class_name='=>'?string', 'options='=>'int', 'namespace_or_prefix='=>'string', 'is_prefix='=>'bool'],
'simplexml_load_string' => ['SimpleXMLElement|false', 'data'=>'string', 'class_name='=>'?string', 'options='=>'int', 'namespace_or_prefix='=>'string', 'is_prefix='=>'bool'],
'SimpleXMLElement::__construct' => ['void', 'data'=>'string', 'options='=>'int', 'data_is_url='=>'bool', 'ns='=>'string', 'is_prefix='=>'bool'],
'SimpleXMLElement::__get' => ['SimpleXMLElement', 'name'=>'string'],
'SimpleXMLElement::__toString' => ['string'],
'SimpleXMLElement::addAttribute' => ['void', 'name'=>'string', 'value='=>'string', 'ns='=>'string'],
'SimpleXMLElement::addChild' => ['SimpleXMLElement', 'name'=>'string', 'value='=>'string', 'ns='=>'string'],
'SimpleXMLElement::asXML' => ['string|bool', 'filename='=>'?string'],
'SimpleXMLElement::asXML\'1' => ['string|false'],
'SimpleXMLElement::attributes' => ['?SimpleXMLElement', 'ns='=>'string', 'is_prefix='=>'bool'],
'SimpleXMLElement::children' => ['SimpleXMLElement', 'ns='=>'string', 'is_prefix='=>'bool'],
'SimpleXMLElement::count' => ['int'],
'SimpleXMLElement::getDocNamespaces' => ['string[]', 'recursive='=>'bool', 'from_root='=>'bool'],
'SimpleXMLElement::getName' => ['string'],
'SimpleXMLElement::getNamespaces' => ['string[]', 'recursive='=>'bool'],
'SimpleXMLElement::offsetExists' => ['bool', 'offset'=>'int|string'],
'SimpleXMLElement::offsetGet' => ['SimpleXMLElement', 'offset'=>'int|string'],
'SimpleXMLElement::offsetSet' => ['void', 'offset'=>'int|string', 'value'=>'mixed'],
'SimpleXMLElement::offsetUnset' => ['void', 'offset'=>'int|string'],
'SimpleXMLElement::registerXPathNamespace' => ['bool', 'prefix'=>'string', 'ns'=>'string'],
'SimpleXMLElement::saveXML' => ['string|bool', 'filename='=>'?string'],
'SimpleXMLElement::xpath' => ['SimpleXMLElement[]|false', 'path'=>'string'],
'sin' => ['float', 'num'=>'float'],
'sinh' => ['float', 'num'=>'float'],
'sizeof' => ['int', 'value'=>'Countable|array', 'mode='=>'int'],
'sleep' => ['int', 'seconds'=>'0|positive-int'],
'snmp2_get' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp2_getnext' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp2_real_walk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp2_set' => ['bool', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp2_walk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp3_get' => ['string|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp3_getnext' => ['string|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp3_real_walk' => ['array|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp3_set' => ['bool', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmp3_walk' => ['array|false', 'hostname'=>'string', 'security_name'=>'string', 'security_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'privacy_protocol'=>'string', 'privacy_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'SNMP::__construct' => ['void', 'version'=>'int', 'hostname'=>'string', 'community'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'SNMP::close' => ['bool'],
'SNMP::get' => ['array|string|false', 'objectId'=>'string|array', 'preserveKeys='=>'bool'],
'SNMP::getErrno' => ['int'],
'SNMP::getError' => ['string'],
'SNMP::getnext' => ['string|array|false', 'objectId'=>'string|array'],
'SNMP::set' => ['bool', 'objectId'=>'string|array', 'type'=>'string|array', 'value'=>'mixed'],
'SNMP::setSecurity' => ['bool', 'securityLevel'=>'string', 'authProtocol='=>'string', 'authPassphrase='=>'string', 'privacyProtocol='=>'string', 'privacyPassphrase='=>'string', 'contextName='=>'string', 'contextEngineId='=>'string'],
'SNMP::walk' => ['array|false', 'objectId'=>'string', 'suffixAsKey='=>'bool', 'maxRepetitions='=>'int', 'nonRepeaters='=>'int'],
'snmp_get_quick_print' => ['bool'],
'snmp_get_valueretrieval' => ['int'],
'snmp_read_mib' => ['bool', 'filename'=>'string'],
'snmp_set_enum_print' => ['bool', 'enable'=>'int'],
'snmp_set_oid_numeric_print' => ['true', 'format'=>'int'],
'snmp_set_oid_output_format' => ['true', 'format'=>'int'],
'snmp_set_quick_print' => ['bool', 'enable'=>'bool'],
'snmp_set_valueretrieval' => ['bool', 'method='=>'int'],
'snmpget' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmpgetnext' => ['string|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmprealwalk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmpset' => ['bool', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'mixed', 'timeout='=>'int', 'retries='=>'int'],
'snmpwalk' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'snmpwalkoid' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'],
'SoapClient::__call' => ['', 'function_name'=>'string', 'arguments'=>'array'],
'SoapClient::__construct' => ['void', 'wsdl'=>'mixed', 'options='=>'array|null'],
'SoapClient::__doRequest' => ['?string', 'request'=>'string', 'location'=>'string', 'action'=>'string', 'version'=>'int', 'one_way='=>'bool'],
'SoapClient::__getCookies' => ['array'],
'SoapClient::__getFunctions' => ['?array'],
'SoapClient::__getLastRequest' => ['?string'],
'SoapClient::__getLastRequestHeaders' => ['?string'],
'SoapClient::__getLastResponse' => ['?string'],
'SoapClient::__getLastResponseHeaders' => ['?string'],
'SoapClient::__getTypes' => ['?array'],
'SoapClient::__setCookie' => ['', 'name'=>'string', 'value='=>'string'],
'SoapClient::__setLocation' => ['string', 'new_location='=>'string'],
'SoapClient::__setSoapHeaders' => ['bool', 'soapheaders='=>''],
'SoapClient::__soapCall' => ['', 'function_name'=>'string', 'arguments'=>'array', 'options='=>'array', 'input_headers='=>'SoapHeader|array', '&w_output_headers='=>'array'],
'SoapClient::SoapClient' => ['object', 'wsdl'=>'mixed', 'options='=>'array|null'],
'SoapFault::__clone' => ['void'],
'SoapFault::__construct' => ['void', 'code'=>'array|string|null', 'string'=>'string', 'actor='=>'?string', 'details='=>'?mixed', 'name='=>'?string', 'headerFault='=>'?mixed'],
'SoapFault::__toString' => ['string'],
'SoapFault::__wakeup' => ['void'],
'SoapFault::getCode' => ['int'],
'SoapFault::getFile' => ['string'],
'SoapFault::getLine' => ['int'],
'SoapFault::getMessage' => ['string'],
'SoapFault::getPrevious' => ['?Exception|?Throwable'],
'SoapFault::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'SoapFault::getTraceAsString' => ['string'],
'SoapFault::SoapFault' => ['object', 'faultcode'=>'string', 'faultstring'=>'string', 'faultactor='=>'?string', 'detail='=>'?mixed', 'faultname='=>'?string', 'headerfault='=>'?mixed'],
'SoapHeader::__construct' => ['void', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'],
'SoapHeader::SoapHeader' => ['object', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'],
'SoapParam::__construct' => ['void', 'data'=>'mixed', 'name'=>'string'],
'SoapParam::SoapParam' => ['object', 'data'=>'mixed', 'name'=>'string'],
'SoapServer::__construct' => ['void', 'wsdl'=>'?string', 'options='=>'array'],
'SoapServer::addFunction' => ['void', 'functions'=>'mixed'],
'SoapServer::addSoapHeader' => ['void', 'object'=>'SoapHeader'],
'SoapServer::fault' => ['void', 'code'=>'string', 'string'=>'string', 'actor='=>'string', 'details='=>'string', 'name='=>'string'],
'SoapServer::getFunctions' => ['array'],
'SoapServer::handle' => ['void', 'soap_request='=>'string'],
'SoapServer::setClass' => ['void', 'class_name'=>'string', '...args='=>'mixed'],
'SoapServer::setObject' => ['void', 'object'=>'object'],
'SoapServer::setPersistence' => ['void', 'mode'=>'int'],
'SoapServer::SoapServer' => ['object', 'wsdl'=>'?string', 'options='=>'array'],
'SoapVar::__construct' => ['void', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string|null', 'type_namespace='=>'string|null', 'node_name='=>'string|null', 'node_namespace='=>'string|null'],
'SoapVar::SoapVar' => ['object', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string|null', 'type_namespace='=>'string|null', 'node_name='=>'string|null', 'node_namespace='=>'string|null'],
'socket_accept' => ['Socket|false', 'socket'=>'Socket'],
'socket_addrinfo_bind' => ['Socket|false', 'address'=>'AddressInfo'],
'socket_addrinfo_connect' => ['Socket|false', 'address'=>'AddressInfo'],
'socket_addrinfo_explain' => ['array', 'address'=>'AddressInfo'],
'socket_addrinfo_lookup' => ['false|AddressInfo[]', 'host='=>'string|null', 'service='=>'mixed', 'hints='=>'array'],
'socket_bind' => ['bool', 'socket'=>'Socket', 'addr'=>'string', 'port='=>'int'],
'socket_clear_error' => ['void', 'socket='=>'?Socket'],
'socket_close' => ['void', 'socket'=>'Socket'],
'socket_cmsg_space' => ['int', 'level'=>'int', 'type'=>'int'],
'socket_connect' => ['bool', 'socket'=>'Socket', 'addr'=>'string', 'port='=>'int'],
'socket_create' => ['Socket|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'],
'socket_create_listen' => ['Socket|false', 'port'=>'int', 'backlog='=>'int'],
'socket_create_pair' => ['bool', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int', '&w_fd'=>'Socket[]'],
'socket_export_stream' => ['resource|false', 'socket'=>'Socket'],
'socket_get_option' => ['mixed|false', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int'],
'socket_get_status' => ['array', 'stream'=>'Socket'],
'socket_getopt' => ['mixed', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int'],
'socket_getpeername' => ['bool', 'socket'=>'Socket', '&w_addr'=>'string', '&w_port='=>'int'],
'socket_getsockname' => ['bool', 'socket'=>'Socket', '&w_addr'=>'string', '&w_port='=>'int'],
'socket_import_stream' => ['Socket|false', 'stream'=>'resource'],
'socket_last_error' => ['int', 'socket='=>'?Socket'],
'socket_listen' => ['bool', 'socket'=>'Socket', 'backlog='=>'int'],
'socket_read' => ['string|false', 'socket'=>'Socket', 'length'=>'int', 'type='=>'int'],
'socket_recv' => ['int|false', 'socket'=>'Socket', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int'],
'socket_recvfrom' => ['int|false', 'socket'=>'Socket', '&w_buf'=>'string', 'length'=>'int', 'flags'=>'int', '&w_name'=>'string', '&w_port='=>'int'],
'socket_recvmsg' => ['int|false', 'socket'=>'Socket', '&w_message'=>'string', 'flags='=>'int'],
'socket_select' => ['int|false', '&rw_read_fds'=>'Socket[]|null', '&rw_write_fds'=>'Socket[]|null', '&rw_except_fds'=>'Socket[]|null', 'tv_sec'=>'int|null', 'tv_usec='=>'int'],
'socket_send' => ['int|false', 'socket'=>'Socket', 'buf'=>'string', 'length'=>'int', 'flags'=>'int'],
'socket_sendmsg' => ['int|false', 'socket'=>'Socket', 'message'=>'array', 'flags'=>'int'],
'socket_sendto' => ['int|false', 'socket'=>'Socket', 'buf'=>'string', 'length'=>'int', 'flags'=>'int', 'addr'=>'string', 'port='=>'int'],
'socket_set_block' => ['bool', 'socket'=>'Socket'],
'socket_set_blocking' => ['bool', 'socket'=>'Socket', 'mode'=>'int'],
'socket_set_nonblock' => ['bool', 'socket'=>'Socket'],
'socket_set_option' => ['bool', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
'socket_set_timeout' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'],
'socket_setopt' => ['void', 'socket'=>'Socket', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'],
'socket_shutdown' => ['bool', 'socket'=>'Socket', 'how='=>'int'],
'socket_strerror' => ['string', 'errno'=>'int'],
'socket_write' => ['int|false', 'socket'=>'Socket', 'data'=>'string', 'length='=>'int|null'],
'socket_wsaprotocol_info_export' => ['string|false', 'socket'=>'Socket', 'process_id'=>'int'],
'socket_wsaprotocol_info_import' => ['Socket|false', 'info_id'=>'string'],
'socket_wsaprotocol_info_release' => ['bool', 'info_id'=>'string'],
'sodium_add' => ['void', '&rw_string1'=>'string', 'string2'=>'string'],
'sodium_base642bin' => ['string', 'string'=>'string', 'id'=>'int', 'ignore='=>'string'],
'sodium_bin2base64' => ['string', 'string'=>'string', 'id'=>'int'],
'sodium_bin2hex' => ['string', 'string'=>'string'],
'sodium_compare' => ['int', 'string1'=>'string', 'string2'=>'string'],
'sodium_crypto_aead_aes256gcm_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_aes256gcm_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_aes256gcm_is_available' => ['bool'],
'sodium_crypto_aead_aes256gcm_keygen' => ['non-empty-string'],
'sodium_crypto_aead_chacha20poly1305_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_chacha20poly1305_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_chacha20poly1305_ietf_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_chacha20poly1305_ietf_keygen' => ['non-empty-string'],
'sodium_crypto_aead_chacha20poly1305_keygen' => ['non-empty-string'],
'sodium_crypto_aead_xchacha20poly1305_ietf_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_xchacha20poly1305_ietf_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_aead_xchacha20poly1305_ietf_keygen' => ['non-empty-string'],
'sodium_crypto_auth' => ['string', 'message'=>'string', 'key'=>'string'],
'sodium_crypto_auth_keygen' => ['non-empty-string'],
'sodium_crypto_auth_verify' => ['bool', 'mac'=>'string', 'message'=>'string', 'key'=>'string'],
'sodium_crypto_box' => ['string', 'message'=>'string', 'nonce'=>'string', 'key_pair'=>'string'],
'sodium_crypto_box_keypair' => ['string'],
'sodium_crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secret_key'=>'string', 'public_key'=>'string'],
'sodium_crypto_box_open' => ['string|false', 'ciphertext'=>'string', 'nonce'=>'string', 'key_pair'=>'string'],
'sodium_crypto_box_publickey' => ['string', 'key_pair'=>'string'],
'sodium_crypto_box_publickey_from_secretkey' => ['string', 'secret_key'=>'string'],
'sodium_crypto_box_seal' => ['string', 'message'=>'string', 'public_key'=>'string'],
'sodium_crypto_box_seal_open' => ['string|false', 'ciphertext'=>'string', 'key_pair'=>'string'],
'sodium_crypto_box_secretkey' => ['string', 'key_pair'=>'string'],
'sodium_crypto_box_seed_keypair' => ['string', 'seed'=>'string'],
'sodium_crypto_generichash' => ['string', 'message'=>'string', 'key='=>'?string', 'length='=>'?int'],
'sodium_crypto_generichash_final' => ['string', '&state'=>'string', 'length='=>'?int'],
'sodium_crypto_generichash_init' => ['string', 'key='=>'?string', 'length='=>'?int'],
'sodium_crypto_generichash_keygen' => ['non-empty-string'],
'sodium_crypto_generichash_update' => ['bool', '&rw_state'=>'string', 'string'=>'string'],
'sodium_crypto_kdf_derive_from_key' => ['string', 'subkey_length'=>'int', 'subkey_id'=>'int', 'context'=>'string', 'key'=>'string'],
'sodium_crypto_kdf_keygen' => ['non-empty-string'],
'sodium_crypto_kx_client_session_keys' => ['array<int,string>', 'client_keypair'=>'string', 'server_key'=>'string'],
'sodium_crypto_kx_keypair' => ['string'],
'sodium_crypto_kx_publickey' => ['string', 'key_pair'=>'string'],
'sodium_crypto_kx_secretkey' => ['string', 'key_pair'=>'string'],
'sodium_crypto_kx_seed_keypair' => ['string', 'seed'=>'string'],
'sodium_crypto_kx_server_session_keys' => ['array<int,string>', 'server_key_pair'=>'string', 'client_key'=>'string'],
'sodium_crypto_pwhash' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int', 'algo='=>'int'],
'sodium_crypto_pwhash_scryptsalsa208sha256' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
'sodium_crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
'sodium_crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'],
'sodium_crypto_pwhash_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
'sodium_crypto_pwhash_str_needs_rehash' => ['bool', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
'sodium_crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'],
'sodium_crypto_scalarmult' => ['string', 'n'=>'string', 'p'=>'string'],
'sodium_crypto_scalarmult_base' => ['string', 'secret_key'=>'string'],
'sodium_crypto_secretbox' => ['string', 'message'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_secretbox_keygen' => ['non-empty-string'],
'sodium_crypto_secretbox_open' => ['string|false', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_secretstream_xchacha20poly1305_init_pull' => ['string', 'header'=>'string', 'key'=>'string'],
'sodium_crypto_secretstream_xchacha20poly1305_init_push' => ['array', 'key'=>'string'],
'sodium_crypto_secretstream_xchacha20poly1305_keygen' => ['non-empty-string'],
'sodium_crypto_secretstream_xchacha20poly1305_pull' => ['array', '&r_state'=>'string', 'ciphertext'=>'string', 'additional_data='=>'string'],
'sodium_crypto_secretstream_xchacha20poly1305_push' => ['string', '&w_state'=>'string', 'message'=>'string', 'additional_data='=>'string', 'tag='=>'int'],
'sodium_crypto_secretstream_xchacha20poly1305_rekey' => ['void', 'state'=>'string'],
'sodium_crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'],
'sodium_crypto_shorthash_keygen' => ['non-empty-string'],
'sodium_crypto_sign' => ['string', 'message'=>'string', 'secret_key'=>'string'],
'sodium_crypto_sign_detached' => ['string', 'message'=>'string', 'secret_key'=>'string'],
'sodium_crypto_sign_ed25519_pk_to_curve25519' => ['string', 'public_key'=>'string'],
'sodium_crypto_sign_ed25519_sk_to_curve25519' => ['string', 'secret_key'=>'string'],
'sodium_crypto_sign_keypair' => ['string'],
'sodium_crypto_sign_keypair_from_secretkey_and_publickey' => ['string', 'secret_key'=>'string', 'public_key'=>'string'],
'sodium_crypto_sign_open' => ['string|false', 'signed_message'=>'string', 'public_key'=>'string'],
'sodium_crypto_sign_publickey' => ['string', 'key_pair'=>'string'],
'sodium_crypto_sign_publickey_from_secretkey' => ['string', 'secret_key'=>'string'],
'sodium_crypto_sign_secretkey' => ['string', 'key_pair'=>'string'],
'sodium_crypto_sign_seed_keypair' => ['string', 'seed'=>'string'],
'sodium_crypto_sign_verify_detached' => ['bool', 'signature'=>'string', 'message'=>'string', 'public_key'=>'string'],
'sodium_crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_stream_keygen' => ['non-empty-string'],
'sodium_crypto_stream_xor' => ['string', 'message'=>'string', 'nonce'=>'string', 'key'=>'string'],
'sodium_crypto_stream_xchacha20' => ['non-empty-string', 'length'=>'positive-int', 'nonce'=>'non-empty-string', 'key'=>'non-empty-string'],
'sodium_crypto_stream_xchacha20_keygen' => ['non-empty-string'],
'sodium_crypto_stream_xchacha20_xor' => ['string', 'message'=>'string', 'nonce'=>'non-empty-string', 'key'=>'non-empty-string'],
'sodium_crypto_stream_xchacha20_xor_ic' => ['string', 'message'=>'string', 'nonce'=>'non-empty-string', 'counter'=>'int', 'key'=>'non-empty-string'],
'sodium_hex2bin' => ['string', 'string'=>'string', 'ignore='=>'string'],
'sodium_increment' => ['void', '&rw_string'=>'string'],
'sodium_memcmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
'sodium_memzero' => ['void', '&w_string'=>'string'],
'sodium_pad' => ['string', 'string'=>'string', 'block_size'=>'int'],
'sodium_unpad' => ['string', 'string'=>'string', 'block_size'=>'int'],
'solid_fetch_prev' => ['bool', 'result_id'=>''],
'solr_get_version' => ['string|false'],
'SolrClient::__construct' => ['void', 'clientOptions'=>'array'],
'SolrClient::__destruct' => ['void'],
'SolrClient::addDocument' => ['SolrUpdateResponse', 'doc'=>'SolrInputDocument', 'allowdups='=>'bool', 'commitwithin='=>'int'],
'SolrClient::addDocuments' => ['SolrUpdateResponse', 'docs'=>'array', 'allowdups='=>'bool', 'commitwithin='=>'int'],
'SolrClient::commit' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'],
'SolrClient::deleteById' => ['SolrUpdateResponse', 'id'=>'string'],
'SolrClient::deleteByIds' => ['SolrUpdateResponse', 'ids'=>'array'],
'SolrClient::deleteByQueries' => ['SolrUpdateResponse', 'queries'=>'array'],
'SolrClient::deleteByQuery' => ['SolrUpdateResponse', 'query'=>'string'],
'SolrClient::getById' => ['SolrQueryResponse', 'id'=>'string'],
'SolrClient::getByIds' => ['SolrQueryResponse', 'ids'=>'array'],
'SolrClient::getDebug' => ['string'],
'SolrClient::getOptions' => ['array'],
'SolrClient::optimize' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'],
'SolrClient::ping' => ['SolrPingResponse'],
'SolrClient::query' => ['SolrQueryResponse', 'query'=>'SolrParams'],
'SolrClient::request' => ['SolrUpdateResponse', 'raw_request'=>'string'],
'SolrClient::rollback' => ['SolrUpdateResponse'],
'SolrClient::setResponseWriter' => ['void', 'responsewriter'=>'string'],
'SolrClient::setServlet' => ['bool', 'type'=>'int', 'value'=>'string'],
'SolrClient::system' => ['SolrGenericResponse'],
'SolrClient::threads' => ['SolrGenericResponse'],
'SolrClientException::__clone' => ['void'],
'SolrClientException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'SolrClientException::__toString' => ['string'],
'SolrClientException::__wakeup' => ['void'],
'SolrClientException::getCode' => ['int'],
'SolrClientException::getFile' => ['string'],
'SolrClientException::getInternalInfo' => ['array'],
'SolrClientException::getLine' => ['int'],
'SolrClientException::getMessage' => ['string'],
'SolrClientException::getPrevious' => ['?Exception|?Throwable'],
'SolrClientException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'SolrClientException::getTraceAsString' => ['string'],
'SolrCollapseFunction::__construct' => ['void', 'field'=>'string'],
'SolrCollapseFunction::__toString' => ['string'],
'SolrCollapseFunction::getField' => ['string'],
'SolrCollapseFunction::getHint' => ['string'],
'SolrCollapseFunction::getMax' => ['string'],
'SolrCollapseFunction::getMin' => ['string'],
'SolrCollapseFunction::getNullPolicy' => ['string'],
'SolrCollapseFunction::getSize' => ['int'],
'SolrCollapseFunction::setField' => ['SolrCollapseFunction', 'fieldName'=>'string'],
'SolrCollapseFunction::setHint' => ['SolrCollapseFunction', 'hint'=>'string'],
'SolrCollapseFunction::setMax' => ['SolrCollapseFunction', 'max'=>'string'],
'SolrCollapseFunction::setMin' => ['SolrCollapseFunction', 'min'=>'string'],
'SolrCollapseFunction::setNullPolicy' => ['SolrCollapseFunction', 'nullPolicy'=>'string'],
'SolrCollapseFunction::setSize' => ['SolrCollapseFunction', 'size'=>'int'],
'SolrDisMaxQuery::__construct' => ['void', 'q='=>'string'],
'SolrDisMaxQuery::__destruct' => ['void'],
'SolrDisMaxQuery::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
'SolrDisMaxQuery::addBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'],
'SolrDisMaxQuery::addBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string', 'value'=>'string', 'boost='=>'string'],
'SolrDisMaxQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrDisMaxQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'string'],
'SolrDisMaxQuery::addFacetDateField' => ['SolrQuery', 'dateField'=>'string'],
'SolrDisMaxQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::addFacetField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::addFacetQuery' => ['SolrQuery', 'facetQuery'=>'string'],
'SolrDisMaxQuery::addField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrDisMaxQuery::addGroupField' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'int'],
'SolrDisMaxQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::addMltField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'],
'SolrDisMaxQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
'SolrDisMaxQuery::addPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'],
'SolrDisMaxQuery::addQueryField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost='=>'string'],
'SolrDisMaxQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'],
'SolrDisMaxQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::addStatsField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::addTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'],
'SolrDisMaxQuery::addUserField' => ['SolrDisMaxQuery', 'field'=>'string'],
'SolrDisMaxQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'],
'SolrDisMaxQuery::get' => ['mixed', 'param_name'=>'string'],
'SolrDisMaxQuery::getExpand' => ['bool'],
'SolrDisMaxQuery::getExpandFilterQueries' => ['array'],
'SolrDisMaxQuery::getExpandQuery' => ['array'],
'SolrDisMaxQuery::getExpandRows' => ['int'],
'SolrDisMaxQuery::getExpandSortFields' => ['array'],
'SolrDisMaxQuery::getFacet' => ['bool'],
'SolrDisMaxQuery::getFacetDateEnd' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetDateFields' => ['array'],
'SolrDisMaxQuery::getFacetDateGap' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetDateHardEnd' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetDateOther' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetDateStart' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetFields' => ['array'],
'SolrDisMaxQuery::getFacetLimit' => ['int', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetMethod' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetMinCount' => ['int', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetMissing' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetOffset' => ['int', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetPrefix' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getFacetQueries' => ['string'],
'SolrDisMaxQuery::getFacetSort' => ['int', 'field_override'=>'string'],
'SolrDisMaxQuery::getFields' => ['string'],
'SolrDisMaxQuery::getFilterQueries' => ['string'],
'SolrDisMaxQuery::getGroup' => ['bool'],
'SolrDisMaxQuery::getGroupCachePercent' => ['int'],
'SolrDisMaxQuery::getGroupFacet' => ['bool'],
'SolrDisMaxQuery::getGroupFields' => ['array'],
'SolrDisMaxQuery::getGroupFormat' => ['string'],
'SolrDisMaxQuery::getGroupFunctions' => ['array'],
'SolrDisMaxQuery::getGroupLimit' => ['int'],
'SolrDisMaxQuery::getGroupMain' => ['bool'],
'SolrDisMaxQuery::getGroupNGroups' => ['bool'],
'SolrDisMaxQuery::getGroupOffset' => ['bool'],
'SolrDisMaxQuery::getGroupQueries' => ['array'],
'SolrDisMaxQuery::getGroupSortFields' => ['array'],
'SolrDisMaxQuery::getGroupTruncate' => ['bool'],
'SolrDisMaxQuery::getHighlight' => ['bool'],
'SolrDisMaxQuery::getHighlightAlternateField' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightFields' => ['array'],
'SolrDisMaxQuery::getHighlightFormatter' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightFragmenter' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightFragsize' => ['int', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightHighlightMultiTerm' => ['bool'],
'SolrDisMaxQuery::getHighlightMaxAlternateFieldLength' => ['int', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightMaxAnalyzedChars' => ['int'],
'SolrDisMaxQuery::getHighlightMergeContiguous' => ['bool', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightRegexMaxAnalyzedChars' => ['int'],
'SolrDisMaxQuery::getHighlightRegexPattern' => ['string'],
'SolrDisMaxQuery::getHighlightRegexSlop' => ['float'],
'SolrDisMaxQuery::getHighlightRequireFieldMatch' => ['bool'],
'SolrDisMaxQuery::getHighlightSimplePost' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightSimplePre' => ['string', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightSnippets' => ['int', 'field_override'=>'string'],
'SolrDisMaxQuery::getHighlightUsePhraseHighlighter' => ['bool'],
'SolrDisMaxQuery::getMlt' => ['bool'],
'SolrDisMaxQuery::getMltBoost' => ['bool'],
'SolrDisMaxQuery::getMltCount' => ['int'],
'SolrDisMaxQuery::getMltFields' => ['array'],
'SolrDisMaxQuery::getMltMaxNumQueryTerms' => ['int'],
'SolrDisMaxQuery::getMltMaxNumTokens' => ['int'],
'SolrDisMaxQuery::getMltMaxWordLength' => ['int'],
'SolrDisMaxQuery::getMltMinDocFrequency' => ['int'],
'SolrDisMaxQuery::getMltMinTermFrequency' => ['int'],
'SolrDisMaxQuery::getMltMinWordLength' => ['int'],
'SolrDisMaxQuery::getMltQueryFields' => ['array'],
'SolrDisMaxQuery::getParam' => ['mixed', 'param_name'=>'string'],
'SolrDisMaxQuery::getParams' => ['array'],
'SolrDisMaxQuery::getPreparedParams' => ['array'],
'SolrDisMaxQuery::getQuery' => ['string'],
'SolrDisMaxQuery::getRows' => ['int'],
'SolrDisMaxQuery::getSortFields' => ['array'],
'SolrDisMaxQuery::getStart' => ['int'],
'SolrDisMaxQuery::getStats' => ['bool'],
'SolrDisMaxQuery::getStatsFacets' => ['array'],
'SolrDisMaxQuery::getStatsFields' => ['array'],
'SolrDisMaxQuery::getTerms' => ['bool'],
'SolrDisMaxQuery::getTermsField' => ['string'],
'SolrDisMaxQuery::getTermsIncludeLowerBound' => ['bool'],
'SolrDisMaxQuery::getTermsIncludeUpperBound' => ['bool'],
'SolrDisMaxQuery::getTermsLimit' => ['int'],
'SolrDisMaxQuery::getTermsLowerBound' => ['string'],
'SolrDisMaxQuery::getTermsMaxCount' => ['int'],
'SolrDisMaxQuery::getTermsMinCount' => ['int'],
'SolrDisMaxQuery::getTermsPrefix' => ['string'],
'SolrDisMaxQuery::getTermsReturnRaw' => ['bool'],
'SolrDisMaxQuery::getTermsSort' => ['int'],
'SolrDisMaxQuery::getTermsUpperBound' => ['string'],
'SolrDisMaxQuery::getTimeAllowed' => ['int'],
'SolrDisMaxQuery::removeBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrDisMaxQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::removeField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrDisMaxQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeMltField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeMltQueryField' => ['SolrQuery', 'queryField'=>'string'],
'SolrDisMaxQuery::removePhraseField' => ['SolrDisMaxQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeQueryField' => ['SolrDisMaxQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeSortField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'],
'SolrDisMaxQuery::removeUserField' => ['SolrDisMaxQuery', 'field'=>'string'],
'SolrDisMaxQuery::serialize' => ['string'],
'SolrDisMaxQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''],
'SolrDisMaxQuery::setBigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
'SolrDisMaxQuery::setBigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
'SolrDisMaxQuery::setBoostFunction' => ['SolrDisMaxQuery', 'function'=>'string'],
'SolrDisMaxQuery::setBoostQuery' => ['SolrDisMaxQuery', 'q'=>'string'],
'SolrDisMaxQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'],
'SolrDisMaxQuery::setExpand' => ['SolrQuery', 'value'=>'bool'],
'SolrDisMaxQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'],
'SolrDisMaxQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'],
'SolrDisMaxQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'],
'SolrDisMaxQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setFacetSort' => ['SolrQuery', 'facetSort'=>'int', 'field_override'=>'string'],
'SolrDisMaxQuery::setGroup' => ['SolrQuery', 'value'=>'bool'],
'SolrDisMaxQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'],
'SolrDisMaxQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'],
'SolrDisMaxQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'],
'SolrDisMaxQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'],
'SolrDisMaxQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'],
'SolrDisMaxQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'],
'SolrDisMaxQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldLength'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'],
'SolrDisMaxQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxAnalyzedChars'=>'int'],
'SolrDisMaxQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'],
'SolrDisMaxQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'],
'SolrDisMaxQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setHighlightSimplePost' => ['SolrQuery', 'simplePost'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightSimplePre' => ['SolrQuery', 'simplePre'=>'string', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override'=>'string'],
'SolrDisMaxQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setMinimumMatch' => ['SolrDisMaxQuery', 'value'=>'string'],
'SolrDisMaxQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setMltCount' => ['SolrQuery', 'count'=>'int'],
'SolrDisMaxQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'],
'SolrDisMaxQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'],
'SolrDisMaxQuery::setMltMaxWordLength' => ['SolrQuery', 'maxWordLength'=>'int'],
'SolrDisMaxQuery::setMltMinDocFrequency' => ['SolrQuery', 'minDocFrequency'=>'int'],
'SolrDisMaxQuery::setMltMinTermFrequency' => ['SolrQuery', 'minTermFrequency'=>'int'],
'SolrDisMaxQuery::setMltMinWordLength' => ['SolrQuery', 'minWordLength'=>'int'],
'SolrDisMaxQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''],
'SolrDisMaxQuery::setPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
'SolrDisMaxQuery::setPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
'SolrDisMaxQuery::setQuery' => ['SolrQuery', 'query'=>'string'],
'SolrDisMaxQuery::setQueryAlt' => ['SolrDisMaxQuery', 'q'=>'string'],
'SolrDisMaxQuery::setQueryPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
'SolrDisMaxQuery::setRows' => ['SolrQuery', 'rows'=>'int'],
'SolrDisMaxQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setStart' => ['SolrQuery', 'start'=>'int'],
'SolrDisMaxQuery::setStats' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'],
'SolrDisMaxQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'],
'SolrDisMaxQuery::setTermsLowerBound' => ['SolrQuery', 'lowerBound'=>'string'],
'SolrDisMaxQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'],
'SolrDisMaxQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'],
'SolrDisMaxQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'],
'SolrDisMaxQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'],
'SolrDisMaxQuery::setTermsSort' => ['SolrQuery', 'sortType'=>'int'],
'SolrDisMaxQuery::setTermsUpperBound' => ['SolrQuery', 'upperBound'=>'string'],
'SolrDisMaxQuery::setTieBreaker' => ['SolrDisMaxQuery', 'tieBreaker'=>'string'],
'SolrDisMaxQuery::setTimeAllowed' => ['SolrQuery', 'timeAllowed'=>'int'],
'SolrDisMaxQuery::setTrigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
'SolrDisMaxQuery::setTrigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'],
'SolrDisMaxQuery::setUserFields' => ['SolrDisMaxQuery', 'fields'=>'string'],
'SolrDisMaxQuery::toString' => ['string', 'url_encode='=>'bool'],
'SolrDisMaxQuery::unserialize' => ['void', 'serialized'=>'string'],
'SolrDisMaxQuery::useDisMaxQueryParser' => ['SolrDisMaxQuery'],
'SolrDisMaxQuery::useEDisMaxQueryParser' => ['SolrDisMaxQuery'],
'SolrDocument::__clone' => ['void'],
'SolrDocument::__construct' => ['void'],
'SolrDocument::__destruct' => ['void'],
'SolrDocument::__get' => ['SolrDocumentField', 'fieldname'=>'string'],
'SolrDocument::__isset' => ['bool', 'fieldname'=>'string'],
'SolrDocument::__set' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'],
'SolrDocument::__unset' => ['bool', 'fieldname'=>'string'],
'SolrDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'],
'SolrDocument::clear' => ['bool'],
'SolrDocument::current' => ['SolrDocumentField'],
'SolrDocument::deleteField' => ['bool', 'fieldname'=>'string'],
'SolrDocument::fieldExists' => ['bool', 'fieldname'=>'string'],
'SolrDocument::getChildDocuments' => ['SolrInputDocument[]'],
'SolrDocument::getChildDocumentsCount' => ['int'],
'SolrDocument::getField' => ['SolrDocumentField|false', 'fieldname'=>'string'],
'SolrDocument::getFieldCount' => ['int|false'],
'SolrDocument::getFieldNames' => ['array|false'],
'SolrDocument::getInputDocument' => ['SolrInputDocument'],
'SolrDocument::hasChildDocuments' => ['bool'],
'SolrDocument::key' => ['string'],
'SolrDocument::merge' => ['bool', 'sourcedoc'=>'solrdocument', 'overwrite='=>'bool'],
'SolrDocument::next' => ['void'],
'SolrDocument::offsetExists' => ['bool', 'fieldname'=>'string'],
'SolrDocument::offsetGet' => ['SolrDocumentField', 'fieldname'=>'string'],
'SolrDocument::offsetSet' => ['void', 'fieldname'=>'string', 'fieldvalue'=>'string'],
'SolrDocument::offsetUnset' => ['void', 'fieldname'=>'string'],
'SolrDocument::reset' => ['bool'],
'SolrDocument::rewind' => ['void'],
'SolrDocument::serialize' => ['string'],
'SolrDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'],
'SolrDocument::toArray' => ['array'],
'SolrDocument::unserialize' => ['void', 'serialized'=>'string'],
'SolrDocument::valid' => ['bool'],
'SolrDocumentField::__construct' => ['void'],
'SolrDocumentField::__destruct' => ['void'],
'SolrException::__clone' => ['void'],
'SolrException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'SolrException::__toString' => ['string'],
'SolrException::__wakeup' => ['void'],
'SolrException::getCode' => ['int'],
'SolrException::getFile' => ['string'],
'SolrException::getInternalInfo' => ['array'],
'SolrException::getLine' => ['int'],
'SolrException::getMessage' => ['string'],
'SolrException::getPrevious' => ['Exception|Throwable'],
'SolrException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'SolrException::getTraceAsString' => ['string'],
'SolrGenericResponse::__construct' => ['void'],
'SolrGenericResponse::__destruct' => ['void'],
'SolrGenericResponse::getDigestedResponse' => ['string'],
'SolrGenericResponse::getHttpStatus' => ['int'],
'SolrGenericResponse::getHttpStatusMessage' => ['string'],
'SolrGenericResponse::getRawRequest' => ['string'],
'SolrGenericResponse::getRawRequestHeaders' => ['string'],
'SolrGenericResponse::getRawResponse' => ['string'],
'SolrGenericResponse::getRawResponseHeaders' => ['string'],
'SolrGenericResponse::getRequestUrl' => ['string'],
'SolrGenericResponse::getResponse' => ['SolrObject'],
'SolrGenericResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
'SolrGenericResponse::success' => ['bool'],
'SolrIllegalArgumentException::__clone' => ['void'],
'SolrIllegalArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'SolrIllegalArgumentException::__toString' => ['string'],
'SolrIllegalArgumentException::__wakeup' => ['void'],
'SolrIllegalArgumentException::getCode' => ['int'],
'SolrIllegalArgumentException::getFile' => ['string'],
'SolrIllegalArgumentException::getInternalInfo' => ['array'],
'SolrIllegalArgumentException::getLine' => ['int'],
'SolrIllegalArgumentException::getMessage' => ['string'],
'SolrIllegalArgumentException::getPrevious' => ['Exception|Throwable'],
'SolrIllegalArgumentException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'SolrIllegalArgumentException::getTraceAsString' => ['string'],
'SolrIllegalOperationException::__clone' => ['void'],
'SolrIllegalOperationException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'SolrIllegalOperationException::__toString' => ['string'],
'SolrIllegalOperationException::__wakeup' => ['void'],
'SolrIllegalOperationException::getCode' => ['int'],
'SolrIllegalOperationException::getFile' => ['string'],
'SolrIllegalOperationException::getInternalInfo' => ['array'],
'SolrIllegalOperationException::getLine' => ['int'],
'SolrIllegalOperationException::getMessage' => ['string'],
'SolrIllegalOperationException::getPrevious' => ['Exception|Throwable'],
'SolrIllegalOperationException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'SolrIllegalOperationException::getTraceAsString' => ['string'],
'SolrInputDocument::__clone' => ['void'],
'SolrInputDocument::__construct' => ['void'],
'SolrInputDocument::__destruct' => ['void'],
'SolrInputDocument::addChildDocument' => ['void', 'child'=>'SolrInputDocument'],
'SolrInputDocument::addChildDocuments' => ['void', 'docs'=>'array'],
'SolrInputDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string', 'fieldboostvalue='=>'float'],
'SolrInputDocument::clear' => ['bool'],
'SolrInputDocument::deleteField' => ['bool', 'fieldname'=>'string'],
'SolrInputDocument::fieldExists' => ['bool', 'fieldname'=>'string'],
'SolrInputDocument::getBoost' => ['float|false'],
'SolrInputDocument::getChildDocuments' => ['SolrInputDocument[]'],
'SolrInputDocument::getChildDocumentsCount' => ['int'],
'SolrInputDocument::getField' => ['SolrDocumentField|false', 'fieldname'=>'string'],
'SolrInputDocument::getFieldBoost' => ['float|false', 'fieldname'=>'string'],
'SolrInputDocument::getFieldCount' => ['int|false'],
'SolrInputDocument::getFieldNames' => ['array|false'],
'SolrInputDocument::hasChildDocuments' => ['bool'],
'SolrInputDocument::merge' => ['bool', 'sourcedoc'=>'SolrInputDocument', 'overwrite='=>'bool'],
'SolrInputDocument::reset' => ['bool'],
'SolrInputDocument::setBoost' => ['bool', 'documentboostvalue'=>'float'],
'SolrInputDocument::setFieldBoost' => ['bool', 'fieldname'=>'string', 'fieldboostvalue'=>'float'],
'SolrInputDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'],
'SolrInputDocument::toArray' => ['array|false'],
'SolrModifiableParams::__construct' => ['void'],
'SolrModifiableParams::__destruct' => ['void'],
'SolrModifiableParams::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
'SolrModifiableParams::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
'SolrModifiableParams::get' => ['mixed', 'param_name'=>'string'],
'SolrModifiableParams::getParam' => ['mixed', 'param_name'=>'string'],
'SolrModifiableParams::getParams' => ['array'],
'SolrModifiableParams::getPreparedParams' => ['array'],
'SolrModifiableParams::serialize' => ['string'],
'SolrModifiableParams::set' => ['SolrParams', 'name'=>'string', 'value'=>''],
'SolrModifiableParams::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''],
'SolrModifiableParams::toString' => ['string', 'url_encode='=>'bool'],
'SolrModifiableParams::unserialize' => ['void', 'serialized'=>'string'],
'SolrObject::__construct' => ['void'],
'SolrObject::__destruct' => ['void'],
'SolrObject::getPropertyNames' => ['array'],
'SolrObject::offsetExists' => ['bool', 'property_name'=>'string'],
'SolrObject::offsetGet' => ['SolrDocumentField', 'property_name'=>'string'],
'SolrObject::offsetSet' => ['void', 'property_name'=>'string', 'property_value'=>'string'],
'SolrObject::offsetUnset' => ['void', 'property_name'=>'string'],
'SolrParams::__construct' => ['void'],
'SolrParams::add' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
'SolrParams::addParam' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
'SolrParams::get' => ['mixed', 'param_name'=>'string'],
'SolrParams::getParam' => ['mixed', 'param_name='=>'string'],
'SolrParams::getParams' => ['array'],
'SolrParams::getPreparedParams' => ['array'],
'SolrParams::serialize' => ['string'],
'SolrParams::set' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
'SolrParams::setParam' => ['SolrParams|false', 'name'=>'string', 'value'=>'string'],
'SolrParams::toString' => ['string|false', 'url_encode='=>'bool'],
'SolrParams::unserialize' => ['void', 'serialized'=>'string'],
'SolrPingResponse::__construct' => ['void'],
'SolrPingResponse::__destruct' => ['void'],
'SolrPingResponse::getDigestedResponse' => ['string'],
'SolrPingResponse::getHttpStatus' => ['int'],
'SolrPingResponse::getHttpStatusMessage' => ['string'],
'SolrPingResponse::getRawRequest' => ['string'],
'SolrPingResponse::getRawRequestHeaders' => ['string'],
'SolrPingResponse::getRawResponse' => ['string'],
'SolrPingResponse::getRawResponseHeaders' => ['string'],
'SolrPingResponse::getRequestUrl' => ['string'],
'SolrPingResponse::getResponse' => ['string'],
'SolrPingResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
'SolrPingResponse::success' => ['bool'],
'SolrQuery::__construct' => ['void', 'q='=>'string'],
'SolrQuery::__destruct' => ['void'],
'SolrQuery::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
'SolrQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'string'],
'SolrQuery::addFacetDateField' => ['SolrQuery', 'datefield'=>'string'],
'SolrQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
'SolrQuery::addFacetField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::addFacetQuery' => ['SolrQuery', 'facetquery'=>'string'],
'SolrQuery::addField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrQuery::addGroupField' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'],
'SolrQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::addMltField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'],
'SolrQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'],
'SolrQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'],
'SolrQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::addStatsField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'],
'SolrQuery::get' => ['mixed', 'param_name'=>'string'],
'SolrQuery::getExpand' => ['bool'],
'SolrQuery::getExpandFilterQueries' => ['array'],
'SolrQuery::getExpandQuery' => ['array'],
'SolrQuery::getExpandRows' => ['int'],
'SolrQuery::getExpandSortFields' => ['array'],
'SolrQuery::getFacet' => ['?bool'],
'SolrQuery::getFacetDateEnd' => ['?string', 'field_override='=>'string'],
'SolrQuery::getFacetDateFields' => ['array'],
'SolrQuery::getFacetDateGap' => ['?string', 'field_override='=>'string'],
'SolrQuery::getFacetDateHardEnd' => ['?string', 'field_override='=>'string'],
'SolrQuery::getFacetDateOther' => ['?string', 'field_override='=>'string'],
'SolrQuery::getFacetDateStart' => ['?string', 'field_override='=>'string'],
'SolrQuery::getFacetFields' => ['array'],
'SolrQuery::getFacetLimit' => ['?int', 'field_override='=>'string'],
'SolrQuery::getFacetMethod' => ['?string', 'field_override='=>'string'],
'SolrQuery::getFacetMinCount' => ['?int', 'field_override='=>'string'],
'SolrQuery::getFacetMissing' => ['?bool', 'field_override='=>'string'],
'SolrQuery::getFacetOffset' => ['?int', 'field_override='=>'string'],
'SolrQuery::getFacetPrefix' => ['?string', 'field_override='=>'string'],
'SolrQuery::getFacetQueries' => ['?array'],
'SolrQuery::getFacetSort' => ['int', 'field_override='=>'string'],
'SolrQuery::getFields' => ['?array'],
'SolrQuery::getFilterQueries' => ['?array'],
'SolrQuery::getGroup' => ['bool'],
'SolrQuery::getGroupCachePercent' => ['int'],
'SolrQuery::getGroupFacet' => ['bool'],
'SolrQuery::getGroupFields' => ['array'],
'SolrQuery::getGroupFormat' => ['string'],
'SolrQuery::getGroupFunctions' => ['array'],
'SolrQuery::getGroupLimit' => ['int'],
'SolrQuery::getGroupMain' => ['bool'],
'SolrQuery::getGroupNGroups' => ['bool'],
'SolrQuery::getGroupOffset' => ['int'],
'SolrQuery::getGroupQueries' => ['array'],
'SolrQuery::getGroupSortFields' => ['array'],
'SolrQuery::getGroupTruncate' => ['bool'],
'SolrQuery::getHighlight' => ['bool'],
'SolrQuery::getHighlightAlternateField' => ['?string', 'field_override='=>'string'],
'SolrQuery::getHighlightFields' => ['?array'],
'SolrQuery::getHighlightFormatter' => ['?string', 'field_override='=>'string'],
'SolrQuery::getHighlightFragmenter' => ['?string', 'field_override='=>'string'],
'SolrQuery::getHighlightFragsize' => ['?int', 'field_override='=>'string'],
'SolrQuery::getHighlightHighlightMultiTerm' => ['?bool'],
'SolrQuery::getHighlightMaxAlternateFieldLength' => ['?int', 'field_override='=>'string'],
'SolrQuery::getHighlightMaxAnalyzedChars' => ['?int'],
'SolrQuery::getHighlightMergeContiguous' => ['?bool', 'field_override='=>'string'],
'SolrQuery::getHighlightRegexMaxAnalyzedChars' => ['?int'],
'SolrQuery::getHighlightRegexPattern' => ['?string'],
'SolrQuery::getHighlightRegexSlop' => ['?float'],
'SolrQuery::getHighlightRequireFieldMatch' => ['?bool'],
'SolrQuery::getHighlightSimplePost' => ['?string', 'field_override='=>'string'],
'SolrQuery::getHighlightSimplePre' => ['?string', 'field_override='=>'string'],
'SolrQuery::getHighlightSnippets' => ['?int', 'field_override='=>'string'],
'SolrQuery::getHighlightUsePhraseHighlighter' => ['?bool'],
'SolrQuery::getMlt' => ['?bool'],
'SolrQuery::getMltBoost' => ['?bool'],
'SolrQuery::getMltCount' => ['?int'],
'SolrQuery::getMltFields' => ['?array'],
'SolrQuery::getMltMaxNumQueryTerms' => ['?int'],
'SolrQuery::getMltMaxNumTokens' => ['?int'],
'SolrQuery::getMltMaxWordLength' => ['?int'],
'SolrQuery::getMltMinDocFrequency' => ['?int'],
'SolrQuery::getMltMinTermFrequency' => ['?int'],
'SolrQuery::getMltMinWordLength' => ['?int'],
'SolrQuery::getMltQueryFields' => ['?array'],
'SolrQuery::getParam' => ['?mixed', 'param_name'=>'string'],
'SolrQuery::getParams' => ['?array'],
'SolrQuery::getPreparedParams' => ['?array'],
'SolrQuery::getQuery' => ['?string'],
'SolrQuery::getRows' => ['?int'],
'SolrQuery::getSortFields' => ['?array'],
'SolrQuery::getStart' => ['?int'],
'SolrQuery::getStats' => ['?bool'],
'SolrQuery::getStatsFacets' => ['?array'],
'SolrQuery::getStatsFields' => ['?array'],
'SolrQuery::getTerms' => ['?bool'],
'SolrQuery::getTermsField' => ['?string'],
'SolrQuery::getTermsIncludeLowerBound' => ['?bool'],
'SolrQuery::getTermsIncludeUpperBound' => ['?bool'],
'SolrQuery::getTermsLimit' => ['?int'],
'SolrQuery::getTermsLowerBound' => ['?string'],
'SolrQuery::getTermsMaxCount' => ['?int'],
'SolrQuery::getTermsMinCount' => ['?int'],
'SolrQuery::getTermsPrefix' => ['?string'],
'SolrQuery::getTermsReturnRaw' => ['?bool'],
'SolrQuery::getTermsSort' => ['?int'],
'SolrQuery::getTermsUpperBound' => ['?string'],
'SolrQuery::getTimeAllowed' => ['?int'],
'SolrQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
'SolrQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::removeField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'],
'SolrQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::removeMltField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::removeMltQueryField' => ['SolrQuery', 'queryfield'=>'string'],
'SolrQuery::removeSortField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'],
'SolrQuery::serialize' => ['string'],
'SolrQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''],
'SolrQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'],
'SolrQuery::setExpand' => ['SolrQuery', 'value'=>'bool'],
'SolrQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'],
'SolrQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'],
'SolrQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'],
'SolrQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
'SolrQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
'SolrQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'bool', 'field_override='=>'string'],
'SolrQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'],
'SolrQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override='=>'string'],
'SolrQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override='=>'string'],
'SolrQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override='=>'string'],
'SolrQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override='=>'string'],
'SolrQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'],
'SolrQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override='=>'string'],
'SolrQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override='=>'string'],
'SolrQuery::setFacetSort' => ['SolrQuery', 'facetsort'=>'int', 'field_override='=>'string'],
'SolrQuery::setGroup' => ['SolrQuery', 'value'=>'bool'],
'SolrQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'],
'SolrQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'],
'SolrQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'],
'SolrQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'],
'SolrQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'],
'SolrQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'],
'SolrQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override='=>'string'],
'SolrQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override='=>'string'],
'SolrQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override='=>'string'],
'SolrQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override='=>'string'],
'SolrQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldlength'=>'int', 'field_override='=>'string'],
'SolrQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'],
'SolrQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'],
'SolrQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxanalyzedchars'=>'int'],
'SolrQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'],
'SolrQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'],
'SolrQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setHighlightSimplePost' => ['SolrQuery', 'simplepost'=>'string', 'field_override='=>'string'],
'SolrQuery::setHighlightSimplePre' => ['SolrQuery', 'simplepre'=>'string', 'field_override='=>'string'],
'SolrQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override='=>'string'],
'SolrQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setMltCount' => ['SolrQuery', 'count'=>'int'],
'SolrQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'],
'SolrQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'],
'SolrQuery::setMltMaxWordLength' => ['SolrQuery', 'maxwordlength'=>'int'],
'SolrQuery::setMltMinDocFrequency' => ['SolrQuery', 'mindocfrequency'=>'int'],
'SolrQuery::setMltMinTermFrequency' => ['SolrQuery', 'mintermfrequency'=>'int'],
'SolrQuery::setMltMinWordLength' => ['SolrQuery', 'minwordlength'=>'int'],
'SolrQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''],
'SolrQuery::setQuery' => ['SolrQuery', 'query'=>'string'],
'SolrQuery::setRows' => ['SolrQuery', 'rows'=>'int'],
'SolrQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setStart' => ['SolrQuery', 'start'=>'int'],
'SolrQuery::setStats' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'],
'SolrQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'],
'SolrQuery::setTermsLowerBound' => ['SolrQuery', 'lowerbound'=>'string'],
'SolrQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'],
'SolrQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'],
'SolrQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'],
'SolrQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'],
'SolrQuery::setTermsSort' => ['SolrQuery', 'sorttype'=>'int'],
'SolrQuery::setTermsUpperBound' => ['SolrQuery', 'upperbound'=>'string'],
'SolrQuery::setTimeAllowed' => ['SolrQuery', 'timeallowed'=>'int'],
'SolrQuery::toString' => ['string', 'url_encode='=>'bool'],
'SolrQuery::unserialize' => ['void', 'serialized'=>'string'],
'SolrQueryResponse::__construct' => ['void'],
'SolrQueryResponse::__destruct' => ['void'],
'SolrQueryResponse::getDigestedResponse' => ['string'],
'SolrQueryResponse::getHttpStatus' => ['int'],
'SolrQueryResponse::getHttpStatusMessage' => ['string'],
'SolrQueryResponse::getRawRequest' => ['string'],
'SolrQueryResponse::getRawRequestHeaders' => ['string'],
'SolrQueryResponse::getRawResponse' => ['string'],
'SolrQueryResponse::getRawResponseHeaders' => ['string'],
'SolrQueryResponse::getRequestUrl' => ['string'],
'SolrQueryResponse::getResponse' => ['SolrObject'],
'SolrQueryResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
'SolrQueryResponse::success' => ['bool'],
'SolrResponse::getDigestedResponse' => ['string'],
'SolrResponse::getHttpStatus' => ['int'],
'SolrResponse::getHttpStatusMessage' => ['string'],
'SolrResponse::getRawRequest' => ['string'],
'SolrResponse::getRawRequestHeaders' => ['string'],
'SolrResponse::getRawResponse' => ['string'],
'SolrResponse::getRawResponseHeaders' => ['string'],
'SolrResponse::getRequestUrl' => ['string'],
'SolrResponse::getResponse' => ['SolrObject'],
'SolrResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
'SolrResponse::success' => ['bool'],
'SolrServerException::__clone' => ['void'],
'SolrServerException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'SolrServerException::__toString' => ['string'],
'SolrServerException::__wakeup' => ['void'],
'SolrServerException::getCode' => ['int'],
'SolrServerException::getFile' => ['string'],
'SolrServerException::getInternalInfo' => ['array'],
'SolrServerException::getLine' => ['int'],
'SolrServerException::getMessage' => ['string'],
'SolrServerException::getPrevious' => ['Exception|Throwable'],
'SolrServerException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'SolrServerException::getTraceAsString' => ['string'],
'SolrUpdateResponse::__construct' => ['void'],
'SolrUpdateResponse::__destruct' => ['void'],
'SolrUpdateResponse::getDigestedResponse' => ['string'],
'SolrUpdateResponse::getHttpStatus' => ['int'],
'SolrUpdateResponse::getHttpStatusMessage' => ['string'],
'SolrUpdateResponse::getRawRequest' => ['string'],
'SolrUpdateResponse::getRawRequestHeaders' => ['string'],
'SolrUpdateResponse::getRawResponse' => ['string'],
'SolrUpdateResponse::getRawResponseHeaders' => ['string'],
'SolrUpdateResponse::getRequestUrl' => ['string'],
'SolrUpdateResponse::getResponse' => ['SolrObject'],
'SolrUpdateResponse::setParseMode' => ['bool', 'parser_mode='=>'int'],
'SolrUpdateResponse::success' => ['bool'],
'SolrUtils::digestXmlResponse' => ['SolrObject', 'xmlresponse'=>'string', 'parse_mode='=>'int'],
'SolrUtils::escapeQueryChars' => ['string|false', 'string'=>'string'],
'SolrUtils::getSolrVersion' => ['string'],
'SolrUtils::queryPhrase' => ['string', 'string'=>'string'],
'sort' => ['bool', '&rw_array'=>'array', 'flags='=>'int'],
'soundex' => ['string', 'string'=>'string'],
'SphinxClient::__construct' => ['void'],
'SphinxClient::addQuery' => ['int', 'query'=>'string', 'index='=>'string', 'comment='=>'string'],
'SphinxClient::buildExcerpts' => ['array', 'docs'=>'array', 'index'=>'string', 'words'=>'string', 'opts='=>'array'],
'SphinxClient::buildKeywords' => ['array', 'query'=>'string', 'index'=>'string', 'hits'=>'bool'],
'SphinxClient::close' => ['bool'],
'SphinxClient::escapeString' => ['string', 'string'=>'string'],
'SphinxClient::getLastError' => ['string'],
'SphinxClient::getLastWarning' => ['string'],
'SphinxClient::open' => ['bool'],
'SphinxClient::query' => ['array', 'query'=>'string', 'index='=>'string', 'comment='=>'string'],
'SphinxClient::resetFilters' => ['void'],
'SphinxClient::resetGroupBy' => ['void'],
'SphinxClient::runQueries' => ['array'],
'SphinxClient::setArrayResult' => ['bool', 'array_result'=>'bool'],
'SphinxClient::setConnectTimeout' => ['bool', 'timeout'=>'float'],
'SphinxClient::setFieldWeights' => ['bool', 'weights'=>'array'],
'SphinxClient::setFilter' => ['bool', 'attribute'=>'string', 'values'=>'array', 'exclude='=>'bool'],
'SphinxClient::setFilterFloatRange' => ['bool', 'attribute'=>'string', 'min'=>'float', 'max'=>'float', 'exclude='=>'bool'],
'SphinxClient::setFilterRange' => ['bool', 'attribute'=>'string', 'min'=>'int', 'max'=>'int', 'exclude='=>'bool'],
'SphinxClient::setGeoAnchor' => ['bool', 'attrlat'=>'string', 'attrlong'=>'string', 'latitude'=>'float', 'longitude'=>'float'],
'SphinxClient::setGroupBy' => ['bool', 'attribute'=>'string', 'func'=>'int', 'groupsort='=>'string'],
'SphinxClient::setGroupDistinct' => ['bool', 'attribute'=>'string'],
'SphinxClient::setIDRange' => ['bool', 'min'=>'int', 'max'=>'int'],
'SphinxClient::setIndexWeights' => ['bool', 'weights'=>'array'],
'SphinxClient::setLimits' => ['bool', 'offset'=>'int', 'limit'=>'int', 'max_matches='=>'int', 'cutoff='=>'int'],
'SphinxClient::setMatchMode' => ['bool', 'mode'=>'int'],
'SphinxClient::setMaxQueryTime' => ['bool', 'qtime'=>'int'],
'SphinxClient::setOverride' => ['bool', 'attribute'=>'string', 'type'=>'int', 'values'=>'array'],
'SphinxClient::setRankingMode' => ['bool', 'ranker'=>'int'],
'SphinxClient::setRetries' => ['bool', 'count'=>'int', 'delay='=>'int'],
'SphinxClient::setSelect' => ['bool', 'clause'=>'string'],
'SphinxClient::setServer' => ['bool', 'server'=>'string', 'port'=>'int'],
'SphinxClient::setSortMode' => ['bool', 'mode'=>'int', 'sortby='=>'string'],
'SphinxClient::status' => ['array'],
'SphinxClient::updateAttributes' => ['int', 'index'=>'string', 'attributes'=>'array', 'values'=>'array', 'mva='=>'bool'],
'spl_autoload' => ['void', 'class'=>'string', 'file_extensions='=>'?string'],
'spl_autoload_call' => ['void', 'class'=>'string'],
'spl_autoload_extensions' => ['string', 'file_extensions='=>'?string'],
'spl_autoload_functions' => ['list<callable(string):void>'],
'spl_autoload_register' => ['bool', 'callback='=>'callable(string):void|null', 'throw='=>'bool', 'prepend='=>'bool'],
'spl_autoload_unregister' => ['bool', 'callback'=>'callable(string):void'],
'spl_classes' => ['array'],
'spl_object_hash' => ['string', 'object'=>'object'],
'spl_object_id' => ['int', 'object'=>'object'],
'SplDoublyLinkedList::__construct' => ['void'],
'SplDoublyLinkedList::add' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
'SplDoublyLinkedList::bottom' => ['mixed'],
'SplDoublyLinkedList::count' => ['int'],
'SplDoublyLinkedList::current' => ['mixed'],
'SplDoublyLinkedList::getIteratorMode' => ['int'],
'SplDoublyLinkedList::isEmpty' => ['bool'],
'SplDoublyLinkedList::key' => ['int'],
'SplDoublyLinkedList::next' => ['void'],
'SplDoublyLinkedList::offsetExists' => ['bool', 'index'=>'mixed'],
'SplDoublyLinkedList::offsetGet' => ['mixed', 'index'=>'mixed'],
'SplDoublyLinkedList::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
'SplDoublyLinkedList::offsetUnset' => ['void', 'index'=>'mixed'],
'SplDoublyLinkedList::pop' => ['mixed'],
'SplDoublyLinkedList::prev' => ['void'],
'SplDoublyLinkedList::push' => ['void', 'value'=>'mixed'],
'SplDoublyLinkedList::rewind' => ['void'],
'SplDoublyLinkedList::serialize' => ['string'],
'SplDoublyLinkedList::setIteratorMode' => ['void', 'flags'=>'int'],
'SplDoublyLinkedList::shift' => ['mixed'],
'SplDoublyLinkedList::top' => ['mixed'],
'SplDoublyLinkedList::unserialize' => ['void', 'serialized'=>'string'],
'SplDoublyLinkedList::unshift' => ['void', 'value'=>'mixed'],
'SplDoublyLinkedList::valid' => ['bool'],
'SplEnum::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool'],
'SplEnum::getConstList' => ['array', 'include_default='=>'bool'],
'SplFileInfo::__construct' => ['void', 'file_name'=>'string'],
'SplFileInfo::__toString' => ['string'],
'SplFileInfo::__wakeup' => ['void'],
'SplFileInfo::getATime' => ['int|false'],
'SplFileInfo::getBasename' => ['string', 'suffix='=>'string'],
'SplFileInfo::getCTime' => ['int|false'],
'SplFileInfo::getExtension' => ['string'],
'SplFileInfo::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
'SplFileInfo::getFilename' => ['string'],
'SplFileInfo::getGroup' => ['int|false'],
'SplFileInfo::getInode' => ['int|false'],
'SplFileInfo::getLinkTarget' => ['string|false'],
'SplFileInfo::getMTime' => ['int|false'],
'SplFileInfo::getOwner' => ['int|false'],
'SplFileInfo::getPath' => ['string'],
'SplFileInfo::getPathInfo' => ['SplFileInfo|null', 'class_name='=>'string'],
'SplFileInfo::getPathname' => ['string'],
'SplFileInfo::getPerms' => ['int|false'],
'SplFileInfo::getRealPath' => ['string|false'],
'SplFileInfo::getSize' => ['int|false'],
'SplFileInfo::getType' => ['string|false'],
'SplFileInfo::isDir' => ['bool'],
'SplFileInfo::isExecutable' => ['bool'],
'SplFileInfo::isFile' => ['bool'],
'SplFileInfo::isLink' => ['bool'],
'SplFileInfo::isReadable' => ['bool'],
'SplFileInfo::isWritable' => ['bool'],
'SplFileInfo::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
'SplFileInfo::setFileClass' => ['void', 'class_name='=>'string'],
'SplFileInfo::setInfoClass' => ['void', 'class_name='=>'string'],
'SplFileObject::__construct' => ['void', 'filename'=>'string', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>''],
'SplFileObject::__toString' => ['string'],
'SplFileObject::current' => ['string|array|false'],
'SplFileObject::eof' => ['bool'],
'SplFileObject::fflush' => ['bool'],
'SplFileObject::fgetc' => ['string|false'],
'SplFileObject::fgetcsv' => ['list<string>|array{0: null}|false|null', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'SplFileObject::fgets' => ['string'],
'SplFileObject::flock' => ['bool', 'operation'=>'int', '&w_wouldblock='=>'int'],
'SplFileObject::fpassthru' => ['int'],
'SplFileObject::fputcsv' => ['int|false', 'fields'=>'array<array-key, null|scalar|Stringable>', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'SplFileObject::fread' => ['string|false', 'length'=>'int'],
'SplFileObject::fscanf' => ['array|int', 'format'=>'string', '&...w_vars='=>'string|int|float'],
'SplFileObject::fseek' => ['int', 'pos'=>'int', 'whence='=>'int'],
'SplFileObject::fstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}'],
'SplFileObject::ftell' => ['int|false'],
'SplFileObject::ftruncate' => ['bool', 'size'=>'int'],
'SplFileObject::fwrite' => ['int', 'string'=>'string', 'length='=>'int'],
'SplFileObject::getATime' => ['int|false'],
'SplFileObject::getBasename' => ['string', 'suffix='=>'string'],
'SplFileObject::getChildren' => ['null'],
'SplFileObject::getCsvControl' => ['array'],
'SplFileObject::getCTime' => ['int|false'],
'SplFileObject::getCurrentLine' => ['string'],
'SplFileObject::getExtension' => ['string'],
'SplFileObject::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
'SplFileObject::getFilename' => ['string'],
'SplFileObject::getFlags' => ['int'],
'SplFileObject::getGroup' => ['int|false'],
'SplFileObject::getInode' => ['int|false'],
'SplFileObject::getLinkTarget' => ['string|false'],
'SplFileObject::getMaxLineLen' => ['int'],
'SplFileObject::getMTime' => ['int|false'],
'SplFileObject::getOwner' => ['int|false'],
'SplFileObject::getPath' => ['string'],
'SplFileObject::getPathInfo' => ['SplFileInfo|null', 'class_name='=>'string'],
'SplFileObject::getPathname' => ['string'],
'SplFileObject::getPerms' => ['int|false'],
'SplFileObject::getRealPath' => ['false|string'],
'SplFileObject::getSize' => ['int|false'],
'SplFileObject::getType' => ['string|false'],
'SplFileObject::hasChildren' => ['false'],
'SplFileObject::isDir' => ['bool'],
'SplFileObject::isExecutable' => ['bool'],
'SplFileObject::isFile' => ['bool'],
'SplFileObject::isLink' => ['bool'],
'SplFileObject::isReadable' => ['bool'],
'SplFileObject::isWritable' => ['bool'],
'SplFileObject::key' => ['int'],
'SplFileObject::next' => ['void'],
'SplFileObject::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
'SplFileObject::rewind' => ['void'],
'SplFileObject::seek' => ['void', 'line_pos'=>'int'],
'SplFileObject::setCsvControl' => ['void', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'SplFileObject::setFileClass' => ['void', 'class_name='=>'string'],
'SplFileObject::setFlags' => ['void', 'flags'=>'int'],
'SplFileObject::setInfoClass' => ['void', 'class_name='=>'string'],
'SplFileObject::setMaxLineLen' => ['void', 'max_len'=>'int'],
'SplFileObject::valid' => ['bool'],
'SplFixedArray::__construct' => ['void', 'size='=>'int'],
'SplFixedArray::__wakeup' => ['void'],
'SplFixedArray::count' => ['int'],
'SplFixedArray::current' => ['mixed'],
'SplFixedArray::fromArray' => ['SplFixedArray', 'data'=>'array', 'save_indexes='=>'bool'],
'SplFixedArray::getSize' => ['int'],
'SplFixedArray::key' => ['int'],
'SplFixedArray::next' => ['void'],
'SplFixedArray::offsetExists' => ['bool', 'index'=>'int'],
'SplFixedArray::offsetGet' => ['mixed', 'index'=>'int'],
'SplFixedArray::offsetSet' => ['void', 'index'=>'int', 'newval'=>'mixed'],
'SplFixedArray::offsetUnset' => ['void', 'index'=>'int'],
'SplFixedArray::rewind' => ['void'],
'SplFixedArray::setSize' => ['bool', 'size'=>'int'],
'SplFixedArray::toArray' => ['array'],
'SplFixedArray::valid' => ['bool'],
'SplHeap::__construct' => ['void'],
'SplHeap::compare' => ['int', 'value1'=>'mixed', 'value2'=>'mixed'],
'SplHeap::count' => ['int'],
'SplHeap::current' => ['mixed'],
'SplHeap::extract' => ['mixed'],
'SplHeap::insert' => ['bool', 'value'=>'mixed'],
'SplHeap::isCorrupted' => ['bool'],
'SplHeap::isEmpty' => ['bool'],
'SplHeap::key' => ['int'],
'SplHeap::next' => ['void'],
'SplHeap::recoverFromCorruption' => ['true'],
'SplHeap::rewind' => ['void'],
'SplHeap::top' => ['mixed'],
'SplHeap::valid' => ['bool'],
'SplMaxHeap::__construct' => ['void'],
'SplMaxHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'],
'SplMinHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'],
'SplMinHeap::count' => ['int'],
'SplMinHeap::current' => ['mixed'],
'SplMinHeap::extract' => ['mixed'],
'SplMinHeap::insert' => ['true', 'value'=>'mixed'],
'SplMinHeap::isCorrupted' => ['bool'],
'SplMinHeap::isEmpty' => ['bool'],
'SplMinHeap::key' => ['int'],
'SplMinHeap::next' => ['void'],
'SplMinHeap::recoverFromCorruption' => ['true'],
'SplMinHeap::rewind' => ['void'],
'SplMinHeap::top' => ['mixed'],
'SplMinHeap::valid' => ['bool'],
'SplObjectStorage::__construct' => ['void'],
'SplObjectStorage::addAll' => ['void', 'os'=>'splobjectstorage'],
'SplObjectStorage::attach' => ['void', 'object'=>'object', 'inf='=>'mixed'],
'SplObjectStorage::contains' => ['bool', 'object'=>'object'],
'SplObjectStorage::count' => ['int'],
'SplObjectStorage::current' => ['object'],
'SplObjectStorage::detach' => ['void', 'object'=>'object'],
'SplObjectStorage::getHash' => ['string', 'object'=>'object'],
'SplObjectStorage::getInfo' => ['mixed'],
'SplObjectStorage::key' => ['int'],
'SplObjectStorage::next' => ['void'],
'SplObjectStorage::offsetExists' => ['bool', 'object'=>'object'],
'SplObjectStorage::offsetGet' => ['mixed', 'object'=>'object'],
'SplObjectStorage::offsetSet' => ['object', 'object'=>'object', 'data='=>'mixed'],
'SplObjectStorage::offsetUnset' => ['void', 'object'=>'object'],
'SplObjectStorage::removeAll' => ['void', 'os'=>'splobjectstorage'],
'SplObjectStorage::removeAllExcept' => ['void', 'os'=>'splobjectstorage'],
'SplObjectStorage::rewind' => ['void'],
'SplObjectStorage::serialize' => ['string'],
'SplObjectStorage::setInfo' => ['void', 'inf'=>'mixed'],
'SplObjectStorage::unserialize' => ['void', 'serialized'=>'string'],
'SplObjectStorage::valid' => ['bool'],
'SplObserver::update' => ['void', 'subject'=>'SplSubject'],
'SplPriorityQueue::__construct' => ['void'],
'SplPriorityQueue::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'],
'SplPriorityQueue::count' => ['int'],
'SplPriorityQueue::current' => ['mixed'],
'SplPriorityQueue::extract' => ['mixed'],
'SplPriorityQueue::getExtractFlags' => ['int'],
'SplPriorityQueue::insert' => ['bool', 'value'=>'mixed', 'priority'=>'mixed'],
'SplPriorityQueue::isCorrupted' => ['bool'],
'SplPriorityQueue::isEmpty' => ['bool'],
'SplPriorityQueue::key' => ['int'],
'SplPriorityQueue::next' => ['void'],
'SplPriorityQueue::recoverFromCorruption' => ['void'],
'SplPriorityQueue::rewind' => ['void'],
'SplPriorityQueue::setExtractFlags' => ['int', 'flags'=>'int'],
'SplPriorityQueue::top' => ['mixed'],
'SplPriorityQueue::valid' => ['bool'],
'SplQueue::dequeue' => ['mixed'],
'SplQueue::enqueue' => ['void', 'value'=>'mixed'],
'SplQueue::getIteratorMode' => ['int'],
'SplQueue::isEmpty' => ['bool'],
'SplQueue::key' => ['int'],
'SplQueue::next' => ['void'],
'SplQueue::offsetExists' => ['bool', 'index'=>'mixed'],
'SplQueue::offsetGet' => ['mixed', 'index'=>'mixed'],
'SplQueue::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
'SplQueue::offsetUnset' => ['void', 'index'=>'mixed'],
'SplQueue::pop' => ['mixed'],
'SplQueue::prev' => ['void'],
'SplQueue::push' => ['void', 'value'=>'mixed'],
'SplQueue::rewind' => ['void'],
'SplQueue::serialize' => ['string'],
'SplQueue::setIteratorMode' => ['int', 'mode'=>'int'],
'SplQueue::shift' => ['mixed'],
'SplQueue::top' => ['mixed'],
'SplQueue::unserialize' => ['void', 'serialized'=>'string'],
'SplQueue::unshift' => ['void', 'value'=>'mixed'],
'SplQueue::valid' => ['bool'],
'SplStack::__construct' => ['void'],
'SplStack::add' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
'SplStack::bottom' => ['mixed'],
'SplStack::count' => ['int'],
'SplStack::current' => ['mixed'],
'SplStack::getIteratorMode' => ['int'],
'SplStack::isEmpty' => ['bool'],
'SplStack::key' => ['int'],
'SplStack::next' => ['void'],
'SplStack::offsetExists' => ['bool', 'index'=>'mixed'],
'SplStack::offsetGet' => ['mixed', 'index'=>'mixed'],
'SplStack::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'],
'SplStack::offsetUnset' => ['void', 'index'=>'mixed'],
'SplStack::pop' => ['mixed'],
'SplStack::prev' => ['void'],
'SplStack::push' => ['void', 'value'=>'mixed'],
'SplStack::rewind' => ['void'],
'SplStack::serialize' => ['string'],
'SplStack::setIteratorMode' => ['int', 'mode'=>'int'],
'SplStack::shift' => ['mixed'],
'SplStack::top' => ['mixed'],
'SplStack::unserialize' => ['void', 'serialized'=>'string'],
'SplStack::unshift' => ['void', 'value'=>'mixed'],
'SplStack::valid' => ['bool'],
'SplSubject::attach' => ['void', 'observer'=>'SplObserver'],
'SplSubject::detach' => ['void', 'observer'=>'SplObserver'],
'SplSubject::notify' => ['void'],
'SplTempFileObject::__construct' => ['void', 'max_memory='=>'int'],
'SplTempFileObject::__toString' => ['string'],
'SplTempFileObject::current' => ['array|false|string'],
'SplTempFileObject::eof' => ['bool'],
'SplTempFileObject::fflush' => ['bool'],
'SplTempFileObject::fgetc' => ['false|string'],
'SplTempFileObject::fgetcsv' => ['list<string>|array{0: null}|false|null', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'SplTempFileObject::fgets' => ['string'],
'SplTempFileObject::flock' => ['bool', 'operation'=>'int', '&wouldblock='=>'int'],
'SplTempFileObject::fpassthru' => ['int'],
'SplTempFileObject::fputcsv' => ['false|int', 'fields'=>'array<array-key, null|scalar|Stringable>', 'seperator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'SplTempFileObject::fread' => ['false|string', 'length'=>'int'],
'SplTempFileObject::fscanf' => ['bool', 'format'=>'string', '&...w_vars='=>'array<int,float>|array<int,int>|array<int,string>'],
'SplTempFileObject::fseek' => ['int', 'pos'=>'int', 'whence='=>'int'],
'SplTempFileObject::fstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}'],
'SplTempFileObject::ftell' => ['int'],
'SplTempFileObject::ftruncate' => ['bool', 'size'=>'int'],
'SplTempFileObject::fwrite' => ['int', 'string'=>'string', 'length='=>'int'],
'SplTempFileObject::getATime' => ['int|false'],
'SplTempFileObject::getBasename' => ['string', 'suffix='=>'string'],
'SplTempFileObject::getChildren' => ['null'],
'SplTempFileObject::getCsvControl' => ['array'],
'SplTempFileObject::getCTime' => ['int|false'],
'SplTempFileObject::getCurrentLine' => ['string'],
'SplTempFileObject::getExtension' => ['string'],
'SplTempFileObject::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'],
'SplTempFileObject::getFilename' => ['string'],
'SplTempFileObject::getFlags' => ['int'],
'SplTempFileObject::getGroup' => ['int|false'],
'SplTempFileObject::getInode' => ['int|false'],
'SplTempFileObject::getLinkTarget' => ['string|false'],
'SplTempFileObject::getMaxLineLen' => ['int'],
'SplTempFileObject::getMTime' => ['int|false'],
'SplTempFileObject::getOwner' => ['int|false'],
'SplTempFileObject::getPath' => ['string'],
'SplTempFileObject::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'],
'SplTempFileObject::getPathname' => ['string'],
'SplTempFileObject::getPerms' => ['int|false'],
'SplTempFileObject::getRealPath' => ['string|false'],
'SplTempFileObject::getSize' => ['int|false'],
'SplTempFileObject::getType' => ['string|false'],
'SplTempFileObject::hasChildren' => ['bool'],
'SplTempFileObject::isDir' => ['bool'],
'SplTempFileObject::isExecutable' => ['bool'],
'SplTempFileObject::isFile' => ['bool'],
'SplTempFileObject::isLink' => ['bool'],
'SplTempFileObject::isReadable' => ['bool'],
'SplTempFileObject::isWritable' => ['bool'],
'SplTempFileObject::key' => ['int'],
'SplTempFileObject::next' => ['void'],
'SplTempFileObject::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'],
'SplTempFileObject::rewind' => ['void'],
'SplTempFileObject::seek' => ['void', 'line_pos'=>'int'],
'SplTempFileObject::setCsvControl' => ['void', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'SplTempFileObject::setFileClass' => ['void', 'class_name='=>'string'],
'SplTempFileObject::setFlags' => ['void', 'flags'=>'int'],
'SplTempFileObject::setInfoClass' => ['void', 'class_name='=>'string'],
'SplTempFileObject::setMaxLineLen' => ['void', 'max_len'=>'int'],
'SplTempFileObject::valid' => ['bool'],
'SplType::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool'],
'Spoofchecker::__construct' => ['void'],
'Spoofchecker::areConfusable' => ['bool', 's1'=>'string', 's2'=>'string', '&w_error='=>'string'],
'Spoofchecker::isSuspicious' => ['bool', 'text'=>'string', '&w_error='=>'string'],
'Spoofchecker::setAllowedLocales' => ['void', 'locale_list'=>'string'],
'Spoofchecker::setChecks' => ['void', 'checks'=>'long'],
'Spoofchecker::setRestrictionLevel' => ['void', 'restriction_level'=>'int'],
'sprintf' => ['string', 'format'=>'string', '...values='=>'string|int|float'],
'SQLite3::__construct' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryptionKey='=>'?string'],
'SQLite3::busyTimeout' => ['bool', 'milliseconds'=>'int'],
'SQLite3::changes' => ['int'],
'SQLite3::close' => ['bool'],
'SQLite3::createAggregate' => ['bool', 'name'=>'string', 'stepCallback'=>'callable', 'finalCallback'=>'callable', 'argCount='=>'int'],
'SQLite3::createCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'],
'SQLite3::createFunction' => ['bool', 'name'=>'string', 'callback'=>'callable', 'argCount='=>'int', 'flags='=>'int'],
'SQLite3::enableExceptions' => ['bool', 'enable='=>'bool'],
'SQLite3::escapeString' => ['string', 'string'=>'string'],
'SQLite3::exec' => ['bool', 'query'=>'string'],
'SQLite3::lastErrorCode' => ['int'],
'SQLite3::lastErrorMsg' => ['string'],
'SQLite3::lastInsertRowID' => ['int'],
'SQLite3::loadExtension' => ['bool', 'name'=>'string'],
'SQLite3::open' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryptionKey='=>'?string'],
'SQLite3::openBlob' => ['resource|false', 'table'=>'string', 'column'=>'string', 'rowid'=>'int', 'database='=>'string', 'flags='=>'int'],
'SQLite3::prepare' => ['SQLite3Stmt|false', 'query'=>'string'],
'SQLite3::query' => ['SQLite3Result|false', 'query'=>'string'],
'SQLite3::querySingle' => ['array|int|string|bool|float|null|false', 'query'=>'string', 'entireRow='=>'bool'],
'SQLite3::version' => ['array'],
'SQLite3Result::__construct' => ['void'],
'SQLite3Result::columnName' => ['string', 'column'=>'int'],
'SQLite3Result::columnType' => ['int', 'column'=>'int'],
'SQLite3Result::fetchArray' => ['array|false', 'mode='=>'int'],
'SQLite3Result::finalize' => ['bool'],
'SQLite3Result::numColumns' => ['int'],
'SQLite3Result::reset' => ['bool'],
'SQLite3Stmt::__construct' => ['void', 'sqlite3'=>'sqlite3', 'query'=>'string'],
'SQLite3Stmt::bindParam' => ['bool', 'param'=>'string|int', '&rw_var'=>'mixed', 'type='=>'int'],
'SQLite3Stmt::bindValue' => ['bool', 'param'=>'string|int', 'value'=>'mixed', 'type='=>'int'],
'SQLite3Stmt::clear' => ['bool'],
'SQLite3Stmt::close' => ['bool'],
'SQLite3Stmt::execute' => ['false|SQLite3Result'],
'SQLite3Stmt::getSQL' => ['string', 'expand='=>'bool'],
'SQLite3Stmt::paramCount' => ['int'],
'SQLite3Stmt::readOnly' => ['bool'],
'SQLite3Stmt::reset' => ['bool'],
'sqlite_array_query' => ['array|false', 'dbhandle'=>'resource', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'],
'sqlite_busy_timeout' => ['void', 'dbhandle'=>'resource', 'milliseconds'=>'int'],
'sqlite_changes' => ['int', 'dbhandle'=>'resource'],
'sqlite_close' => ['void', 'dbhandle'=>'resource'],
'sqlite_column' => ['mixed', 'result'=>'resource', 'index_or_name'=>'mixed', 'decode_binary='=>'bool'],
'sqlite_create_aggregate' => ['void', 'dbhandle'=>'resource', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'],
'sqlite_create_function' => ['void', 'dbhandle'=>'resource', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'],
'sqlite_current' => ['array|false', 'result'=>'resource', 'result_type='=>'int', 'decode_binary='=>'bool'],
'sqlite_error_string' => ['string', 'error_code'=>'int'],
'sqlite_escape_string' => ['string', 'item'=>'string'],
'sqlite_exec' => ['bool', 'dbhandle'=>'resource', 'query'=>'string', 'error_msg='=>'string'],
'sqlite_factory' => ['SQLiteDatabase', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'],
'sqlite_fetch_all' => ['array', 'result'=>'resource', 'result_type='=>'int', 'decode_binary='=>'bool'],
'sqlite_fetch_array' => ['array|false', 'result'=>'resource', 'result_type='=>'int', 'decode_binary='=>'bool'],
'sqlite_fetch_column_types' => ['array|false', 'table_name'=>'string', 'dbhandle'=>'resource', 'result_type='=>'int'],
'sqlite_fetch_object' => ['object', 'result'=>'resource', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'],
'sqlite_fetch_single' => ['string', 'result'=>'resource', 'decode_binary='=>'bool'],
'sqlite_fetch_string' => ['string', 'result'=>'resource', 'decode_binary'=>'bool'],
'sqlite_field_name' => ['string', 'result'=>'resource', 'field_index'=>'int'],
'sqlite_has_more' => ['bool', 'result'=>'resource'],
'sqlite_has_prev' => ['bool', 'result'=>'resource'],
'sqlite_key' => ['int', 'result'=>'resource'],
'sqlite_last_error' => ['int', 'dbhandle'=>'resource'],
'sqlite_last_insert_rowid' => ['int', 'dbhandle'=>'resource'],
'sqlite_libencoding' => ['string'],
'sqlite_libversion' => ['string'],
'sqlite_next' => ['bool', 'result'=>'resource'],
'sqlite_num_fields' => ['int', 'result'=>'resource'],
'sqlite_num_rows' => ['int', 'result'=>'resource'],
'sqlite_open' => ['resource|false', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'],
'sqlite_popen' => ['resource|false', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'],
'sqlite_prev' => ['bool', 'result'=>'resource'],
'sqlite_query' => ['resource|false', 'dbhandle'=>'resource', 'query'=>'resource|string', 'result_type='=>'int', 'error_msg='=>'string'],
'sqlite_rewind' => ['bool', 'result'=>'resource'],
'sqlite_seek' => ['bool', 'result'=>'resource', 'rownum'=>'int'],
'sqlite_single_query' => ['array', 'db'=>'resource', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'],
'sqlite_udf_decode_binary' => ['string', 'data'=>'string'],
'sqlite_udf_encode_binary' => ['string', 'data'=>'string'],
'sqlite_unbuffered_query' => ['SQLiteUnbuffered|false', 'dbhandle'=>'resource', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'],
'sqlite_valid' => ['bool', 'result'=>'resource'],
'SQLiteDatabase::__construct' => ['void', 'filename'=>'', 'mode='=>'int|mixed', '&error_message'=>''],
'SQLiteDatabase::arrayQuery' => ['array', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'],
'SQLiteDatabase::busyTimeout' => ['int', 'milliseconds'=>'int'],
'SQLiteDatabase::changes' => ['int'],
'SQLiteDatabase::createAggregate' => ['', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'],
'SQLiteDatabase::createFunction' => ['', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'],
'SQLiteDatabase::exec' => ['bool', 'query'=>'string', 'error_msg='=>'string'],
'SQLiteDatabase::fetchColumnTypes' => ['array', 'table_name'=>'string', 'result_type='=>'int'],
'SQLiteDatabase::lastError' => ['int'],
'SQLiteDatabase::lastInsertRowid' => ['int'],
'SQLiteDatabase::query' => ['SQLiteResult|false', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'],
'SQLiteDatabase::queryExec' => ['bool', 'query'=>'string', '&w_error_msg='=>'string'],
'SQLiteDatabase::singleQuery' => ['array', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'],
'SQLiteDatabase::unbufferedQuery' => ['SQLiteUnbuffered|false', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'],
'SQLiteException::__clone' => ['void'],
'SQLiteException::__construct' => ['void', 'message'=>'', 'code'=>'', 'previous'=>''],
'SQLiteException::__toString' => ['string'],
'SQLiteException::__wakeup' => ['void'],
'SQLiteException::getCode' => ['int'],
'SQLiteException::getFile' => ['string'],
'SQLiteException::getLine' => ['int'],
'SQLiteException::getMessage' => ['string'],
'SQLiteException::getPrevious' => ['RuntimeException|Throwable|null'],
'SQLiteException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'SQLiteException::getTraceAsString' => ['string'],
'SQLiteResult::__construct' => ['void'],
'SQLiteResult::column' => ['mixed', 'index_or_name'=>'', 'decode_binary='=>'bool'],
'SQLiteResult::count' => ['int'],
'SQLiteResult::current' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
'SQLiteResult::fetch' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
'SQLiteResult::fetchAll' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
'SQLiteResult::fetchObject' => ['object', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'],
'SQLiteResult::fetchSingle' => ['string', 'decode_binary='=>'bool'],
'SQLiteResult::fieldName' => ['string', 'field_index'=>'int'],
'SQLiteResult::hasPrev' => ['bool'],
'SQLiteResult::key' => ['mixed|null'],
'SQLiteResult::next' => ['bool'],
'SQLiteResult::numFields' => ['int'],
'SQLiteResult::numRows' => ['int'],
'SQLiteResult::prev' => ['bool'],
'SQLiteResult::rewind' => ['bool'],
'SQLiteResult::seek' => ['bool', 'rownum'=>'int'],
'SQLiteResult::valid' => ['bool'],
'SQLiteUnbuffered::column' => ['void', 'index_or_name'=>'', 'decode_binary='=>'bool'],
'SQLiteUnbuffered::current' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
'SQLiteUnbuffered::fetch' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
'SQLiteUnbuffered::fetchAll' => ['array', 'result_type='=>'int', 'decode_binary='=>'bool'],
'SQLiteUnbuffered::fetchObject' => ['object', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'],
'SQLiteUnbuffered::fetchSingle' => ['string', 'decode_binary='=>'bool'],
'SQLiteUnbuffered::fieldName' => ['string', 'field_index'=>'int'],
'SQLiteUnbuffered::next' => ['bool'],
'SQLiteUnbuffered::numFields' => ['int'],
'SQLiteUnbuffered::valid' => ['bool'],
'sqlsrv_begin_transaction' => ['bool', 'conn'=>'resource'],
'sqlsrv_cancel' => ['bool', 'stmt'=>'resource'],
'sqlsrv_client_info' => ['array|false', 'conn'=>'resource'],
'sqlsrv_close' => ['bool', 'conn'=>'?resource'],
'sqlsrv_commit' => ['bool', 'conn'=>'resource'],
'sqlsrv_configure' => ['bool', 'setting'=>'string', 'value'=>'mixed'],
'sqlsrv_connect' => ['resource|false', 'serverName'=>'string', 'connectionInfo='=>'array'],
'sqlsrv_errors' => ['?array', 'errorsOrWarnings='=>'int'],
'sqlsrv_execute' => ['bool', 'stmt'=>'resource'],
'sqlsrv_fetch' => ['?bool', 'stmt'=>'resource', 'row='=>'int', 'offset='=>'int'],
'sqlsrv_fetch_array' => ['array|null|false', 'stmt'=>'resource', 'fetchType='=>'int', 'row='=>'int', 'offset='=>'int'],
'sqlsrv_fetch_object' => ['object|null|false', 'stmt'=>'resource', 'className='=>'string', 'ctorParams='=>'array', 'row='=>'int', 'offset='=>'int'],
'sqlsrv_field_metadata' => ['array|false', 'stmt'=>'resource'],
'sqlsrv_free_stmt' => ['bool', 'stmt'=>'resource'],
'sqlsrv_get_config' => ['mixed', 'setting'=>'string'],
'sqlsrv_get_field' => ['mixed', 'stmt'=>'resource', 'fieldIndex'=>'int', 'getAsType='=>'int'],
'sqlsrv_has_rows' => ['bool', 'stmt'=>'resource'],
'sqlsrv_next_result' => ['?bool', 'stmt'=>'resource'],
'sqlsrv_num_fields' => ['int|false', 'stmt'=>'resource'],
'sqlsrv_num_rows' => ['int|false', 'stmt'=>'resource'],
'sqlsrv_prepare' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'],
'sqlsrv_query' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'],
'sqlsrv_rollback' => ['bool', 'conn'=>'resource'],
'sqlsrv_rows_affected' => ['int|false', 'stmt'=>'resource'],
'sqlsrv_send_stream_data' => ['bool', 'stmt'=>'resource'],
'sqlsrv_server_info' => ['array', 'conn'=>'resource'],
'sqrt' => ['float', 'num'=>'float'],
'srand' => ['void', 'seed='=>'int', 'mode='=>'int'],
'sscanf' => ['list<float|int|string|null>|int|null', 'string'=>'string', 'format'=>'string', '&...w_vars='=>'string|int|float|null'],
'ssdeep_fuzzy_compare' => ['int', 'signature1'=>'string', 'signature2'=>'string'],
'ssdeep_fuzzy_hash' => ['string', 'to_hash'=>'string'],
'ssdeep_fuzzy_hash_filename' => ['string', 'file_name'=>'string'],
'ssh2_auth_agent' => ['bool', 'session'=>'resource', 'username'=>'string'],
'ssh2_auth_hostbased_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'hostname'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string', 'local_username='=>'string'],
'ssh2_auth_none' => ['bool|string[]', 'session'=>'resource', 'username'=>'string'],
'ssh2_auth_password' => ['bool', 'session'=>'resource', 'username'=>'string', 'password'=>'string'],
'ssh2_auth_pubkey_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string'],
'ssh2_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'methods='=>'array', 'callbacks='=>'array'],
'ssh2_disconnect' => ['bool', 'session'=>'resource'],
'ssh2_exec' => ['resource|false', 'session'=>'resource', 'command'=>'string', 'pty='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'],
'ssh2_fetch_stream' => ['resource|false', 'channel'=>'resource', 'streamid'=>'int'],
'ssh2_fingerprint' => ['string|false', 'session'=>'resource', 'flags='=>'int'],
'ssh2_forward_accept' => ['resource|false', 'listener'=>'resource'],
'ssh2_forward_listen' => ['resource|false', 'session'=>'resource', 'port'=>'int', 'host='=>'string', 'max_connections='=>'string'],
'ssh2_methods_negotiated' => ['array|false', 'session'=>'resource'],
'ssh2_poll' => ['int', '&polldes'=>'array', 'timeout='=>'int'],
'ssh2_publickey_add' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string', 'overwrite='=>'bool', 'attributes='=>'array'],
'ssh2_publickey_init' => ['resource|false', 'session'=>'resource'],
'ssh2_publickey_list' => ['array|false', 'pkey'=>'resource'],
'ssh2_publickey_remove' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string'],
'ssh2_scp_recv' => ['bool', 'session'=>'resource', 'remote_file'=>'string', 'local_file'=>'string'],
'ssh2_scp_send' => ['bool', 'session'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'create_mode='=>'int'],
'ssh2_sftp' => ['resource|false', 'session'=>'resource'],
'ssh2_sftp_chmod' => ['bool', 'sftp'=>'resource', 'filename'=>'string', 'mode'=>'int'],
'ssh2_sftp_lstat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'sftp'=>'resource', 'path'=>'string'],
'ssh2_sftp_mkdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string', 'mode='=>'int', 'recursive='=>'bool'],
'ssh2_sftp_readlink' => ['string|false', 'sftp'=>'resource', 'link'=>'string'],
'ssh2_sftp_realpath' => ['string|false', 'sftp'=>'resource', 'filename'=>'string'],
'ssh2_sftp_rename' => ['bool', 'sftp'=>'resource', 'from'=>'string', 'to'=>'string'],
'ssh2_sftp_rmdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string'],
'ssh2_sftp_stat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'sftp'=>'resource', 'path'=>'string'],
'ssh2_sftp_symlink' => ['bool', 'sftp'=>'resource', 'target'=>'string', 'link'=>'string'],
'ssh2_sftp_unlink' => ['bool', 'sftp'=>'resource', 'filename'=>'string'],
'ssh2_shell' => ['resource|false', 'session'=>'resource', 'termtype='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'],
'ssh2_tunnel' => ['resource|false', 'session'=>'resource', 'host'=>'string', 'port'=>'int'],
'stat' => ['array{0: int, 1: int, 2: int, 3: int, 4: int, 5: int, 6: int, 7: int, 8: int, 9: int, 10: int, 11: int, 12: int, dev: int, ino: int, mode: int, nlink: int, uid: int, gid: int, rdev: int, size: int, atime: int, mtime: int, ctime: int, blksize: int, blocks: int}|false', 'filename'=>'string'],
'stats_absolute_deviation' => ['float', 'a'=>'array'],
'stats_cdf_beta' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_cauchy' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
'stats_cdf_exponential' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
'stats_cdf_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_gamma' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_laplace' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_logistic' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_negative_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_noncentral_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_noncentral_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'par4'=>'float', 'which'=>'int'],
'stats_cdf_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_normal' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_poisson' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
'stats_cdf_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'],
'stats_cdf_uniform' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_cdf_weibull' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_covariance' => ['float', 'a'=>'array', 'b'=>'array'],
'stats_den_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
'stats_dens_beta' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
'stats_dens_cauchy' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
'stats_dens_chisquare' => ['float', 'x'=>'float', 'dfr'=>'float'],
'stats_dens_exponential' => ['float', 'x'=>'float', 'scale'=>'float'],
'stats_dens_f' => ['float', 'x'=>'float', 'dfr1'=>'float', 'dfr2'=>'float'],
'stats_dens_gamma' => ['float', 'x'=>'float', 'shape'=>'float', 'scale'=>'float'],
'stats_dens_laplace' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
'stats_dens_logistic' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
'stats_dens_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'],
'stats_dens_normal' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'],
'stats_dens_pmf_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'],
'stats_dens_pmf_hypergeometric' => ['float', 'n1'=>'float', 'n2'=>'float', 'N1'=>'float', 'N2'=>'float'],
'stats_dens_pmf_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'],
'stats_dens_pmf_poisson' => ['float', 'x'=>'float', 'lb'=>'float'],
'stats_dens_t' => ['float', 'x'=>'float', 'dfr'=>'float'],
'stats_dens_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
'stats_dens_weibull' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'],
'stats_harmonic_mean' => ['float', 'a'=>'array'],
'stats_kurtosis' => ['float', 'a'=>'array'],
'stats_rand_gen_beta' => ['float', 'a'=>'float', 'b'=>'float'],
'stats_rand_gen_chisquare' => ['float', 'df'=>'float'],
'stats_rand_gen_exponential' => ['float', 'av'=>'float'],
'stats_rand_gen_f' => ['float', 'dfn'=>'float', 'dfd'=>'float'],
'stats_rand_gen_funiform' => ['float', 'low'=>'float', 'high'=>'float'],
'stats_rand_gen_gamma' => ['float', 'a'=>'float', 'r'=>'float'],
'stats_rand_gen_ibinomial' => ['int', 'n'=>'int', 'pp'=>'float'],
'stats_rand_gen_ibinomial_negative' => ['int', 'n'=>'int', 'p'=>'float'],
'stats_rand_gen_int' => ['int'],
'stats_rand_gen_ipoisson' => ['int', 'mu'=>'float'],
'stats_rand_gen_iuniform' => ['int', 'low'=>'int', 'high'=>'int'],
'stats_rand_gen_noncenral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'],
'stats_rand_gen_noncentral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'],
'stats_rand_gen_noncentral_f' => ['float', 'dfn'=>'float', 'dfd'=>'float', 'xnonc'=>'float'],
'stats_rand_gen_noncentral_t' => ['float', 'df'=>'float', 'xnonc'=>'float'],
'stats_rand_gen_normal' => ['float', 'av'=>'float', 'sd'=>'float'],
'stats_rand_gen_t' => ['float', 'df'=>'float'],
'stats_rand_get_seeds' => ['array'],
'stats_rand_phrase_to_seeds' => ['array', 'phrase'=>'string'],
'stats_rand_ranf' => ['float'],
'stats_rand_setall' => ['void', 'iseed1'=>'int', 'iseed2'=>'int'],
'stats_skew' => ['float', 'a'=>'array'],
'stats_standard_deviation' => ['float', 'a'=>'array', 'sample='=>'bool'],
'stats_stat_binomial_coef' => ['float', 'x'=>'int', 'n'=>'int'],
'stats_stat_correlation' => ['float', 'array1'=>'array', 'array2'=>'array'],
'stats_stat_factorial' => ['float', 'n'=>'int'],
'stats_stat_gennch' => ['float', 'n'=>'int'],
'stats_stat_independent_t' => ['float', 'array1'=>'array', 'array2'=>'array'],
'stats_stat_innerproduct' => ['float', 'array1'=>'array', 'array2'=>'array'],
'stats_stat_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'],
'stats_stat_paired_t' => ['float', 'array1'=>'array', 'array2'=>'array'],
'stats_stat_percentile' => ['float', 'arr'=>'array', 'perc'=>'float'],
'stats_stat_powersum' => ['float', 'arr'=>'array', 'power'=>'float'],
'stats_variance' => ['float', 'a'=>'array', 'sample='=>'bool'],
'Stomp::__construct' => ['void', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'?array'],
'Stomp::abort' => ['bool', 'transaction_id'=>'string', 'headers='=>'?array'],
'Stomp::ack' => ['bool', 'msg'=>'', 'headers='=>'?array'],
'Stomp::begin' => ['bool', 'transaction_id'=>'string', 'headers='=>'?array'],
'Stomp::commit' => ['bool', 'transaction_id'=>'string', 'headers='=>'?array'],
'Stomp::error' => ['string'],
'Stomp::getReadTimeout' => ['array'],
'Stomp::getSessionId' => ['string'],
'Stomp::hasFrame' => ['bool'],
'Stomp::readFrame' => ['array', 'class_name='=>'string'],
'Stomp::send' => ['bool', 'destination'=>'string', 'msg'=>'', 'headers='=>'?array'],
'Stomp::setReadTimeout' => ['void', 'seconds'=>'int', 'microseconds='=>'?int'],
'Stomp::subscribe' => ['bool', 'destination'=>'string', 'headers='=>'?array'],
'Stomp::unsubscribe' => ['bool', 'destination'=>'string', 'headers='=>'?array'],
'stomp_abort' => ['bool', 'link'=>'resource', 'transaction_id'=>'string', 'headers='=>'?array'],
'stomp_ack' => ['bool', 'link'=>'resource', 'msg'=>'', 'headers='=>'?array'],
'stomp_begin' => ['bool', 'link'=>'resource', 'transaction_id'=>'string', 'headers='=>'?array'],
'stomp_close' => ['bool', 'link'=>'resource'],
'stomp_commit' => ['bool', 'link'=>'resource', 'transaction_id'=>'string', 'headers='=>'?array'],
'stomp_connect' => ['resource', 'link'=>'resource', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'?array'],
'stomp_connect_error' => ['string'],
'stomp_error' => ['string', 'link'=>'resource'],
'stomp_get_read_timeout' => ['array', 'link'=>'resource'],
'stomp_get_session_id' => ['string', 'link'=>'resource'],
'stomp_has_frame' => ['bool', 'link'=>'resource'],
'stomp_read_frame' => ['array', 'link'=>'resource', 'class_name='=>'string'],
'stomp_send' => ['bool', 'link'=>'resource', 'destination'=>'string', 'msg'=>'', 'headers='=>'?array'],
'stomp_set_read_timeout' => ['void', 'link'=>'resource', 'seconds'=>'int', 'microseconds='=>'?int'],
'stomp_subscribe' => ['bool', 'link'=>'resource', 'destination'=>'string', 'headers='=>'?array'],
'stomp_unsubscribe' => ['bool', 'link'=>'resource', 'destination'=>'string', 'headers='=>'?array'],
'stomp_version' => ['string'],
'StompException::getDetails' => ['string'],
'StompFrame::__construct' => ['void', 'command='=>'string', 'headers='=>'?array', 'body='=>'string'],
'str_contains' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
'str_ends_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
'str_getcsv' => ['non-empty-list<?string>', 'string'=>'string', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
'str_ireplace' => ['string|string[]', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_count='=>'int'],
'str_pad' => ['string', 'string'=>'string', 'length'=>'int', 'pad_string='=>'string', 'pad_type='=>'int'],
'str_repeat' => ['string', 'string'=>'string', 'times'=>'int'],
'str_replace' => ['string|string[]', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_count='=>'int'],
'str_rot13' => ['string', 'string'=>'string'],
'str_shuffle' => ['string', 'string'=>'string'],
'str_split' => ['list<string>', 'string'=>'string', 'length='=>'positive-int'],
'str_starts_with' => ['bool', 'haystack'=>'string', 'needle'=>'string'],
'str_word_count' => ['array<int, string>|int', 'string'=>'string', 'format='=>'int', 'characters='=>'?string'],
'strcasecmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
'strcmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
'strcoll' => ['int', 'string1'=>'string', 'string2'=>'string'],
'strcspn' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'?int'],
'stream_bucket_append' => ['void', 'brigade'=>'resource', 'bucket'=>'object'],
'stream_bucket_make_writeable' => ['?object', 'brigade'=>'resource'],
'stream_bucket_new' => ['object', 'stream'=>'resource', 'buffer'=>'string'],
'stream_bucket_prepend' => ['void', 'brigade'=>'resource', 'bucket'=>'object'],
'stream_context_create' => ['resource', 'options='=>'?array', 'params='=>'?array'],
'stream_context_get_default' => ['resource', 'options='=>'?array'],
'stream_context_get_options' => ['array', 'stream_or_context'=>'resource'],
'stream_context_get_params' => ['array', 'context'=>'resource'],
'stream_context_set_default' => ['resource', 'options'=>'array'],
'stream_context_set_option' => ['bool', 'context'=>'', 'wrapper_or_options'=>'string', 'option_name'=>'string', 'value'=>''],
'stream_context_set_option\'1' => ['bool', 'context'=>'', 'wrapper_or_options'=>'array'],
'stream_context_set_params' => ['bool', 'context'=>'resource', 'params'=>'array'],
'stream_copy_to_stream' => ['int|false', 'from'=>'resource', 'to'=>'resource', 'length='=>'?int', 'offset='=>'int'],
'stream_encoding' => ['bool', 'stream'=>'resource', 'encoding='=>'string'],
'stream_filter_append' => ['resource|false', 'stream'=>'resource', 'filter_name'=>'string', 'mode='=>'int', 'params='=>'mixed'],
'stream_filter_prepend' => ['resource|false', 'stream'=>'resource', 'filter_name'=>'string', 'mode='=>'int', 'params='=>'mixed'],
'stream_filter_register' => ['bool', 'filter_name'=>'string', 'class'=>'string'],
'stream_filter_remove' => ['bool', 'stream_filter'=>'resource'],
'stream_get_contents' => ['string|false', 'stream'=>'resource', 'length='=>'?int', 'offset='=>'int'],
'stream_get_filters' => ['array'],
'stream_get_line' => ['string|false', 'stream'=>'resource', 'length'=>'int', 'ending='=>'string'],
'stream_get_meta_data' => ['array{timed_out:bool,blocked:bool,eof:bool,unread_bytes:int,stream_type:string,wrapper_type:string,wrapper_data:mixed,mode:string,seekable:bool,uri:string,mediatype:string,crypto?:array{protocol:string,cipher_name:string,cipher_bits:int,cipher_version:string}}', 'stream'=>'resource'],
'stream_get_transports' => ['list<string>'],
'stream_get_wrappers' => ['list<string>'],
'stream_is_local' => ['bool', 'stream'=>'resource|string'],
'stream_isatty' => ['bool', 'stream'=>'resource'],
'stream_notification_callback' => ['callback', 'notification_code'=>'int', 'severity'=>'int', 'message'=>'string', 'message_code'=>'int', 'bytes_transferred'=>'int', 'bytes_max'=>'int'],
'stream_register_wrapper' => ['bool', 'protocol'=>'string', 'class'=>'string', 'flags='=>'int'],
'stream_resolve_include_path' => ['string|false', 'filename'=>'string'],
'stream_select' => ['int|false', '&rw_read'=>'?resource[]', '&rw_write'=>'?resource[]', '&rw_except'=>'?resource[]', 'seconds'=>'?int', 'microseconds='=>'?int'],
'stream_set_blocking' => ['bool', 'stream'=>'resource', 'enable'=>'bool'],
'stream_set_chunk_size' => ['int', 'stream'=>'resource', 'size'=>'int'],
'stream_set_read_buffer' => ['int', 'stream'=>'resource', 'size'=>'int'],
'stream_set_timeout' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'],
'stream_set_write_buffer' => ['int', 'stream'=>'resource', 'size'=>'int'],
'stream_socket_accept' => ['resource|false', 'socket'=>'resource', 'timeout='=>'?float', '&w_peer_name='=>'string'],
'stream_socket_client' => ['resource|false', 'address'=>'string', '&w_error_code='=>'int', '&w_error_message='=>'string', 'timeout='=>'?float', 'flags='=>'int', 'context='=>'?resource'],
'stream_socket_enable_crypto' => ['int|bool', 'stream'=>'resource', 'enable'=>'bool', 'crypto_method='=>'?int', 'session_stream='=>'?resource'],
'stream_socket_get_name' => ['string', 'socket'=>'resource', 'remote'=>'bool'],
'stream_socket_pair' => ['resource[]|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'],
'stream_socket_recvfrom' => ['string', 'socket'=>'resource', 'length'=>'int', 'flags='=>'int', '&w_address='=>'string'],
'stream_socket_sendto' => ['int', 'socket'=>'resource', 'data'=>'string', 'flags='=>'int', 'address='=>'string'],
'stream_socket_server' => ['resource|false', 'address'=>'string', '&w_error_code='=>'int', '&w_error_message='=>'string', 'flags='=>'int', 'context='=>'resource'],
'stream_socket_shutdown' => ['bool', 'stream'=>'resource', 'mode'=>'int'],
'stream_supports_lock' => ['bool', 'stream'=>'resource'],
'stream_wrapper_register' => ['bool', 'protocol'=>'string', 'class'=>'string', 'flags='=>'int'],
'stream_wrapper_restore' => ['bool', 'protocol'=>'string'],
'stream_wrapper_unregister' => ['bool', 'protocol'=>'string'],
'streamWrapper::__construct' => ['void'],
'streamWrapper::__destruct' => ['void'],
'streamWrapper::dir_closedir' => ['bool'],
'streamWrapper::dir_opendir' => ['bool', 'path'=>'string', 'options'=>'int'],
'streamWrapper::dir_readdir' => ['string'],
'streamWrapper::dir_rewinddir' => ['bool'],
'streamWrapper::mkdir' => ['bool', 'path'=>'string', 'mode'=>'int', 'options'=>'int'],
'streamWrapper::rename' => ['bool', 'path_from'=>'string', 'path_to'=>'string'],
'streamWrapper::rmdir' => ['bool', 'path'=>'string', 'options'=>'int'],
'streamWrapper::stream_cast' => ['resource', 'cast_as'=>'int'],
'streamWrapper::stream_close' => ['void'],
'streamWrapper::stream_eof' => ['bool'],
'streamWrapper::stream_flush' => ['bool'],
'streamWrapper::stream_lock' => ['bool', 'operation'=>'mode'],
'streamWrapper::stream_metadata' => ['bool', 'path'=>'string', 'option'=>'int', 'value'=>'mixed'],
'streamWrapper::stream_open' => ['bool', 'path'=>'string', 'mode'=>'string', 'options'=>'int', 'opened_path'=>'string'],
'streamWrapper::stream_read' => ['string', 'count'=>'int'],
'streamWrapper::stream_seek' => ['bool', 'offset'=>'int', 'whence'=>'int'],
'streamWrapper::stream_set_option' => ['bool', 'option'=>'int', 'arg1'=>'int', 'arg2'=>'int'],
'streamWrapper::stream_stat' => ['array'],
'streamWrapper::stream_tell' => ['int'],
'streamWrapper::stream_truncate' => ['bool', 'new_size'=>'int'],
'streamWrapper::stream_write' => ['int', 'data'=>'string'],
'streamWrapper::unlink' => ['bool', 'path'=>'string'],
'streamWrapper::url_stat' => ['array', 'path'=>'string', 'flags'=>'int'],
'strftime' => ['string|false', 'format'=>'string', 'timestamp='=>'?int'],
'strip_tags' => ['string', 'string'=>'string', 'allowed_tags='=>'string|list<non-empty-string>|null'],
'stripcslashes' => ['string', 'string'=>'string'],
'stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'stripslashes' => ['string', 'string'=>'string'],
'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
'strlen' => ['0|positive-int', 'string'=>'string'],
'strnatcasecmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
'strnatcmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
'strncasecmp' => ['int', 'string1'=>'string', 'string2'=>'string', 'length'=>'int'],
'strncmp' => ['int', 'string1'=>'string', 'string2'=>'string', 'length'=>'int'],
'strpbrk' => ['string|false', 'string'=>'string', 'characters'=>'string'],
'strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'strptime' => ['array|false', 'timestamp'=>'string', 'format'=>'string'],
'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string'],
'strrev' => ['string', 'string'=>'string'],
'strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'],
'strspn' => ['int', 'string'=>'string', 'characters'=>'string', 'offset='=>'int', 'length='=>'?int'],
'strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'],
'strtok' => ['string|false', 'string'=>'string', 'token'=>'string'],
'strtok\'1' => ['string|false', 'string'=>'string'],
'strtolower' => ['lowercase-string', 'string'=>'string'],
'strtotime' => ['int|false', 'datetime'=>'string', 'baseTimestamp='=>'?int'],
'strtoupper' => ['string', 'string'=>'string'],
'strtr' => ['string', 'string'=>'string', 'from'=>'string', 'to'=>'string'],
'strtr\'1' => ['string', 'string'=>'string', 'from'=>'array'],
'strval' => ['string', 'value'=>'mixed'],
'styleObj::__construct' => ['void', 'label'=>'labelObj', 'style'=>'styleObj'],
'styleObj::convertToString' => ['string'],
'styleObj::free' => ['void'],
'styleObj::getBinding' => ['string', 'stylebinding'=>'mixed'],
'styleObj::getGeomTransform' => ['string'],
'styleObj::ms_newStyleObj' => ['styleObj', 'class'=>'classObj', 'style'=>'styleObj'],
'styleObj::removeBinding' => ['int', 'stylebinding'=>'mixed'],
'styleObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'styleObj::setBinding' => ['int', 'stylebinding'=>'mixed', 'value'=>'string'],
'styleObj::setGeomTransform' => ['int', 'value'=>'string'],
'styleObj::updateFromString' => ['int', 'snippet'=>'string'],
'substr' => ['string', 'string'=>'string', 'offset'=>'int', 'length='=>'?int'],
'substr_compare' => ['int', 'haystack'=>'string', 'needle'=>'string', 'offset'=>'int', 'length='=>'?int', 'case_insensitive='=>'bool'],
'substr_count' => ['int', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'length='=>'?int'],
'substr_replace' => ['string|string[]', 'string'=>'string|string[]', 'replace'=>'mixed', 'offset'=>'mixed', 'length='=>'mixed'],
'suhosin_encrypt_cookie' => ['string|false', 'name'=>'string', 'value'=>'string'],
'suhosin_get_raw_cookies' => ['array'],
'SVM::__construct' => ['void'],
'svm::crossvalidate' => ['float', 'problem'=>'array', 'number_of_folds'=>'int'],
'SVM::getOptions' => ['array'],
'SVM::setOptions' => ['bool', 'params'=>'array'],
'svm::train' => ['SVMModel', 'problem'=>'array', 'weights='=>'array'],
'SVMModel::__construct' => ['void', 'filename='=>'string'],
'SVMModel::checkProbabilityModel' => ['bool'],
'SVMModel::getLabels' => ['array'],
'SVMModel::getNrClass' => ['int'],
'SVMModel::getSvmType' => ['int'],
'SVMModel::getSvrProbability' => ['float'],
'SVMModel::load' => ['bool', 'filename'=>'string'],
'SVMModel::predict' => ['float', 'data'=>'array'],
'SVMModel::predict_probability' => ['float', 'data'=>'array'],
'SVMModel::save' => ['bool', 'filename'=>'string'],
'svn_add' => ['bool', 'path'=>'string', 'recursive='=>'bool', 'force='=>'bool'],
'svn_auth_get_parameter' => ['?string', 'key'=>'string'],
'svn_auth_set_parameter' => ['void', 'key'=>'string', 'value'=>'string'],
'svn_blame' => ['array', 'repository_url'=>'string', 'revision_no='=>'int'],
'svn_cat' => ['string', 'repos_url'=>'string', 'revision_no='=>'int'],
'svn_checkout' => ['bool', 'repos'=>'string', 'targetpath'=>'string', 'revision='=>'int', 'flags='=>'int'],
'svn_cleanup' => ['bool', 'workingdir'=>'string'],
'svn_client_version' => ['string'],
'svn_commit' => ['array', 'log'=>'string', 'targets'=>'array', 'dontrecurse='=>'bool'],
'svn_delete' => ['bool', 'path'=>'string', 'force='=>'bool'],
'svn_diff' => ['array', 'path1'=>'string', 'rev1'=>'int', 'path2'=>'string', 'rev2'=>'int'],
'svn_export' => ['bool', 'frompath'=>'string', 'topath'=>'string', 'working_copy='=>'bool', 'revision_no='=>'int'],
'svn_fs_abort_txn' => ['bool', 'txn'=>'resource'],
'svn_fs_apply_text' => ['resource', 'root'=>'resource', 'path'=>'string'],
'svn_fs_begin_txn2' => ['resource', 'repos'=>'resource', 'rev'=>'int'],
'svn_fs_change_node_prop' => ['bool', 'root'=>'resource', 'path'=>'string', 'name'=>'string', 'value'=>'string'],
'svn_fs_check_path' => ['int', 'fsroot'=>'resource', 'path'=>'string'],
'svn_fs_contents_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'],
'svn_fs_copy' => ['bool', 'from_root'=>'resource', 'from_path'=>'string', 'to_root'=>'resource', 'to_path'=>'string'],
'svn_fs_delete' => ['bool', 'root'=>'resource', 'path'=>'string'],
'svn_fs_dir_entries' => ['array', 'fsroot'=>'resource', 'path'=>'string'],
'svn_fs_file_contents' => ['resource', 'fsroot'=>'resource', 'path'=>'string'],
'svn_fs_file_length' => ['int', 'fsroot'=>'resource', 'path'=>'string'],
'svn_fs_is_dir' => ['bool', 'root'=>'resource', 'path'=>'string'],
'svn_fs_is_file' => ['bool', 'root'=>'resource', 'path'=>'string'],
'svn_fs_make_dir' => ['bool', 'root'=>'resource', 'path'=>'string'],
'svn_fs_make_file' => ['bool', 'root'=>'resource', 'path'=>'string'],
'svn_fs_node_created_rev' => ['int', 'fsroot'=>'resource', 'path'=>'string'],
'svn_fs_node_prop' => ['string', 'fsroot'=>'resource', 'path'=>'string', 'propname'=>'string'],
'svn_fs_props_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'],
'svn_fs_revision_prop' => ['string', 'fs'=>'resource', 'revnum'=>'int', 'propname'=>'string'],
'svn_fs_revision_root' => ['resource', 'fs'=>'resource', 'revnum'=>'int'],
'svn_fs_txn_root' => ['resource', 'txn'=>'resource'],
'svn_fs_youngest_rev' => ['int', 'fs'=>'resource'],
'svn_import' => ['bool', 'path'=>'string', 'url'=>'string', 'nonrecursive'=>'bool'],
'svn_log' => ['array', 'repos_url'=>'string', 'start_revision='=>'int', 'end_revision='=>'int', 'limit='=>'int', 'flags='=>'int'],
'svn_ls' => ['array', 'repos_url'=>'string', 'revision_no='=>'int', 'recurse='=>'bool', 'peg='=>'bool'],
'svn_mkdir' => ['bool', 'path'=>'string', 'log_message='=>'string'],
'svn_move' => ['mixed', 'src_path'=>'string', 'dst_path'=>'string', 'force='=>'bool'],
'svn_propget' => ['mixed', 'path'=>'string', 'property_name'=>'string', 'recurse='=>'bool', 'revision'=>'int'],
'svn_proplist' => ['mixed', 'path'=>'string', 'recurse='=>'bool', 'revision'=>'int'],
'svn_repos_create' => ['resource', 'path'=>'string', 'config='=>'array', 'fsconfig='=>'array'],
'svn_repos_fs' => ['resource', 'repos'=>'resource'],
'svn_repos_fs_begin_txn_for_commit' => ['resource', 'repos'=>'resource', 'rev'=>'int', 'author'=>'string', 'log_msg'=>'string'],
'svn_repos_fs_commit_txn' => ['int', 'txn'=>'resource'],
'svn_repos_hotcopy' => ['bool', 'repospath'=>'string', 'destpath'=>'string', 'cleanlogs'=>'bool'],
'svn_repos_open' => ['resource', 'path'=>'string'],
'svn_repos_recover' => ['bool', 'path'=>'string'],
'svn_revert' => ['bool', 'path'=>'string', 'recursive='=>'bool'],
'svn_status' => ['array', 'path'=>'string', 'flags='=>'int'],
'svn_update' => ['int|false', 'path'=>'string', 'revno='=>'int', 'recurse='=>'bool'],
'swf_actiongeturl' => ['', 'url'=>'string', 'target'=>'string'],
'swf_actiongotoframe' => ['', 'framenumber'=>'int'],
'swf_actiongotolabel' => ['', 'label'=>'string'],
'swf_actionnextframe' => [''],
'swf_actionplay' => [''],
'swf_actionprevframe' => [''],
'swf_actionsettarget' => ['', 'target'=>'string'],
'swf_actionstop' => [''],
'swf_actiontogglequality' => [''],
'swf_actionwaitforframe' => ['', 'framenumber'=>'int', 'skipcount'=>'int'],
'swf_addbuttonrecord' => ['', 'states'=>'int', 'shapeid'=>'int', 'depth'=>'int'],
'swf_addcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'],
'swf_closefile' => ['', 'return_file='=>'int'],
'swf_definebitmap' => ['', 'objid'=>'int', 'image_name'=>'string'],
'swf_definefont' => ['', 'fontid'=>'int', 'fontname'=>'string'],
'swf_defineline' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'],
'swf_definepoly' => ['', 'objid'=>'int', 'coords'=>'array', 'npoints'=>'int', 'width'=>'float'],
'swf_definerect' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'],
'swf_definetext' => ['', 'objid'=>'int', 'string'=>'string', 'docenter'=>'int'],
'swf_endbutton' => [''],
'swf_enddoaction' => [''],
'swf_endshape' => [''],
'swf_endsymbol' => [''],
'swf_fontsize' => ['', 'size'=>'float'],
'swf_fontslant' => ['', 'slant'=>'float'],
'swf_fonttracking' => ['', 'tracking'=>'float'],
'swf_getbitmapinfo' => ['array', 'bitmapid'=>'int'],
'swf_getfontinfo' => ['array'],
'swf_getframe' => ['int'],
'swf_labelframe' => ['', 'name'=>'string'],
'swf_lookat' => ['', 'view_x'=>'float', 'view_y'=>'float', 'view_z'=>'float', 'reference_x'=>'float', 'reference_y'=>'float', 'reference_z'=>'float', 'twist'=>'float'],
'swf_modifyobject' => ['', 'depth'=>'int', 'how'=>'int'],
'swf_mulcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'],
'swf_nextid' => ['int'],
'swf_oncondition' => ['', 'transition'=>'int'],
'swf_openfile' => ['', 'filename'=>'string', 'width'=>'float', 'height'=>'float', 'framerate'=>'float', 'r'=>'float', 'g'=>'float', 'b'=>'float'],
'swf_ortho' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float', 'zmin'=>'float', 'zmax'=>'float'],
'swf_ortho2' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'],
'swf_perspective' => ['', 'fovy'=>'float', 'aspect'=>'float', 'near'=>'float', 'far'=>'float'],
'swf_placeobject' => ['', 'objid'=>'int', 'depth'=>'int'],
'swf_polarview' => ['', 'dist'=>'float', 'azimuth'=>'float', 'incidence'=>'float', 'twist'=>'float'],
'swf_popmatrix' => [''],
'swf_posround' => ['', 'round'=>'int'],
'swf_pushmatrix' => [''],
'swf_removeobject' => ['', 'depth'=>'int'],
'swf_rotate' => ['', 'angle'=>'float', 'axis'=>'string'],
'swf_scale' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'],
'swf_setfont' => ['', 'fontid'=>'int'],
'swf_setframe' => ['', 'framenumber'=>'int'],
'swf_shapearc' => ['', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'ang1'=>'float', 'ang2'=>'float'],
'swf_shapecurveto' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'],
'swf_shapecurveto3' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'],
'swf_shapefillbitmapclip' => ['', 'bitmapid'=>'int'],
'swf_shapefillbitmaptile' => ['', 'bitmapid'=>'int'],
'swf_shapefilloff' => [''],
'swf_shapefillsolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'],
'swf_shapelinesolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float', 'width'=>'float'],
'swf_shapelineto' => ['', 'x'=>'float', 'y'=>'float'],
'swf_shapemoveto' => ['', 'x'=>'float', 'y'=>'float'],
'swf_showframe' => [''],
'swf_startbutton' => ['', 'objid'=>'int', 'type'=>'int'],
'swf_startdoaction' => [''],
'swf_startshape' => ['', 'objid'=>'int'],
'swf_startsymbol' => ['', 'objid'=>'int'],
'swf_textwidth' => ['float', 'string'=>'string'],
'swf_translate' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'],
'swf_viewport' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'],
'SWFAction::__construct' => ['void', 'script'=>'string'],
'SWFBitmap::__construct' => ['void', 'file'=>'', 'alphafile='=>''],
'SWFBitmap::getHeight' => ['float'],
'SWFBitmap::getWidth' => ['float'],
'SWFButton::__construct' => ['void'],
'SWFButton::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'],
'SWFButton::addASound' => ['SWFSoundInstance', 'sound'=>'swfsound', 'flags'=>'int'],
'SWFButton::addShape' => ['void', 'shape'=>'swfshape', 'flags'=>'int'],
'SWFButton::setAction' => ['void', 'action'=>'swfaction'],
'SWFButton::setDown' => ['void', 'shape'=>'swfshape'],
'SWFButton::setHit' => ['void', 'shape'=>'swfshape'],
'SWFButton::setMenu' => ['void', 'flag'=>'int'],
'SWFButton::setOver' => ['void', 'shape'=>'swfshape'],
'SWFButton::setUp' => ['void', 'shape'=>'swfshape'],
'SWFDisplayItem::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'],
'SWFDisplayItem::addColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'SWFDisplayItem::endMask' => ['void'],
'SWFDisplayItem::getRot' => ['float'],
'SWFDisplayItem::getX' => ['float'],
'SWFDisplayItem::getXScale' => ['float'],
'SWFDisplayItem::getXSkew' => ['float'],
'SWFDisplayItem::getY' => ['float'],
'SWFDisplayItem::getYScale' => ['float'],
'SWFDisplayItem::getYSkew' => ['float'],
'SWFDisplayItem::move' => ['void', 'dx'=>'float', 'dy'=>'float'],
'SWFDisplayItem::moveTo' => ['void', 'x'=>'float', 'y'=>'float'],
'SWFDisplayItem::multColor' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'a='=>'float'],
'SWFDisplayItem::remove' => ['void'],
'SWFDisplayItem::rotate' => ['void', 'angle'=>'float'],
'SWFDisplayItem::rotateTo' => ['void', 'angle'=>'float'],
'SWFDisplayItem::scale' => ['void', 'dx'=>'float', 'dy'=>'float'],
'SWFDisplayItem::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'],
'SWFDisplayItem::setDepth' => ['void', 'depth'=>'int'],
'SWFDisplayItem::setMaskLevel' => ['void', 'level'=>'int'],
'SWFDisplayItem::setMatrix' => ['void', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'],
'SWFDisplayItem::setName' => ['void', 'name'=>'string'],
'SWFDisplayItem::setRatio' => ['void', 'ratio'=>'float'],
'SWFDisplayItem::skewX' => ['void', 'ddegrees'=>'float'],
'SWFDisplayItem::skewXTo' => ['void', 'degrees'=>'float'],
'SWFDisplayItem::skewY' => ['void', 'ddegrees'=>'float'],
'SWFDisplayItem::skewYTo' => ['void', 'degrees'=>'float'],
'SWFFill::moveTo' => ['void', 'x'=>'float', 'y'=>'float'],
'SWFFill::rotateTo' => ['void', 'angle'=>'float'],
'SWFFill::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'],
'SWFFill::skewXTo' => ['void', 'x'=>'float'],
'SWFFill::skewYTo' => ['void', 'y'=>'float'],
'SWFFont::__construct' => ['void', 'filename'=>'string'],
'SWFFont::getAscent' => ['float'],
'SWFFont::getDescent' => ['float'],
'SWFFont::getLeading' => ['float'],
'SWFFont::getShape' => ['string', 'code'=>'int'],
'SWFFont::getUTF8Width' => ['float', 'string'=>'string'],
'SWFFont::getWidth' => ['float', 'string'=>'string'],
'SWFFontChar::addChars' => ['void', 'char'=>'string'],
'SWFFontChar::addUTF8Chars' => ['void', 'char'=>'string'],
'SWFGradient::__construct' => ['void'],
'SWFGradient::addEntry' => ['void', 'ratio'=>'float', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'],
'SWFMorph::__construct' => ['void'],
'SWFMorph::getShape1' => ['SWFShape'],
'SWFMorph::getShape2' => ['SWFShape'],
'SWFMovie::__construct' => ['void', 'version='=>'int'],
'SWFMovie::add' => ['mixed', 'instance'=>'object'],
'SWFMovie::addExport' => ['void', 'char'=>'swfcharacter', 'name'=>'string'],
'SWFMovie::addFont' => ['mixed', 'font'=>'swffont'],
'SWFMovie::importChar' => ['SWFSprite', 'libswf'=>'string', 'name'=>'string'],
'SWFMovie::importFont' => ['SWFFontChar', 'libswf'=>'string', 'name'=>'string'],
'SWFMovie::labelFrame' => ['void', 'label'=>'string'],
'SWFMovie::namedAnchor' => [''],
'SWFMovie::nextFrame' => ['void'],
'SWFMovie::output' => ['int', 'compression='=>'int'],
'SWFMovie::protect' => [''],
'SWFMovie::remove' => ['void', 'instance'=>'object'],
'SWFMovie::save' => ['int', 'filename'=>'string', 'compression='=>'int'],
'SWFMovie::saveToFile' => ['int', 'x'=>'resource', 'compression='=>'int'],
'SWFMovie::setbackground' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int'],
'SWFMovie::setDimension' => ['void', 'width'=>'float', 'height'=>'float'],
'SWFMovie::setFrames' => ['void', 'number'=>'int'],
'SWFMovie::setRate' => ['void', 'rate'=>'float'],
'SWFMovie::startSound' => ['SWFSoundInstance', 'sound'=>'swfsound'],
'SWFMovie::stopSound' => ['void', 'sound'=>'swfsound'],
'SWFMovie::streamMP3' => ['int', 'mp3file'=>'mixed', 'skip='=>'float'],
'SWFMovie::writeExports' => ['void'],
'SWFPrebuiltClip::__construct' => ['void', 'file'=>''],
'SWFShape::__construct' => ['void'],
'SWFShape::addFill' => ['SWFFill', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int', 'bitmap='=>'swfbitmap', 'flags='=>'int', 'gradient='=>'swfgradient'],
'SWFShape::addFill\'1' => ['SWFFill', 'bitmap'=>'SWFBitmap', 'flags='=>'int'],
'SWFShape::addFill\'2' => ['SWFFill', 'gradient'=>'SWFGradient', 'flags='=>'int'],
'SWFShape::drawArc' => ['void', 'r'=>'float', 'startangle'=>'float', 'endangle'=>'float'],
'SWFShape::drawCircle' => ['void', 'r'=>'float'],
'SWFShape::drawCubic' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'],
'SWFShape::drawCubicTo' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'],
'SWFShape::drawCurve' => ['int', 'controldx'=>'float', 'controldy'=>'float', 'anchordx'=>'float', 'anchordy'=>'float', 'targetdx='=>'float', 'targetdy='=>'float'],
'SWFShape::drawCurveTo' => ['int', 'controlx'=>'float', 'controly'=>'float', 'anchorx'=>'float', 'anchory'=>'float', 'targetx='=>'float', 'targety='=>'float'],
'SWFShape::drawGlyph' => ['void', 'font'=>'swffont', 'character'=>'string', 'size='=>'int'],
'SWFShape::drawLine' => ['void', 'dx'=>'float', 'dy'=>'float'],
'SWFShape::drawLineTo' => ['void', 'x'=>'float', 'y'=>'float'],
'SWFShape::movePen' => ['void', 'dx'=>'float', 'dy'=>'float'],
'SWFShape::movePenTo' => ['void', 'x'=>'float', 'y'=>'float'],
'SWFShape::setLeftFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'SWFShape::setLine' => ['', 'shape'=>'swfshape', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'SWFShape::setRightFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'SWFSound' => ['SWFSound', 'filename'=>'string', 'flags='=>'int'],
'SWFSound::__construct' => ['void', 'filename'=>'string', 'flags='=>'int'],
'SWFSoundInstance::loopCount' => ['void', 'point'=>'int'],
'SWFSoundInstance::loopInPoint' => ['void', 'point'=>'int'],
'SWFSoundInstance::loopOutPoint' => ['void', 'point'=>'int'],
'SWFSoundInstance::noMultiple' => ['void'],
'SWFSprite::__construct' => ['void'],
'SWFSprite::add' => ['void', 'object'=>'object'],
'SWFSprite::labelFrame' => ['void', 'label'=>'string'],
'SWFSprite::nextFrame' => ['void'],
'SWFSprite::remove' => ['void', 'object'=>'object'],
'SWFSprite::setFrames' => ['void', 'number'=>'int'],
'SWFSprite::startSound' => ['SWFSoundInstance', 'sount'=>'swfsound'],
'SWFSprite::stopSound' => ['void', 'sount'=>'swfsound'],
'SWFText::__construct' => ['void'],
'SWFText::addString' => ['void', 'string'=>'string'],
'SWFText::addUTF8String' => ['void', 'text'=>'string'],
'SWFText::getAscent' => ['float'],
'SWFText::getDescent' => ['float'],
'SWFText::getLeading' => ['float'],
'SWFText::getUTF8Width' => ['float', 'string'=>'string'],
'SWFText::getWidth' => ['float', 'string'=>'string'],
'SWFText::moveTo' => ['void', 'x'=>'float', 'y'=>'float'],
'SWFText::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'SWFText::setFont' => ['void', 'font'=>'swffont'],
'SWFText::setHeight' => ['void', 'height'=>'float'],
'SWFText::setSpacing' => ['void', 'spacing'=>'float'],
'SWFTextField::__construct' => ['void', 'flags='=>'int'],
'SWFTextField::addChars' => ['void', 'chars'=>'string'],
'SWFTextField::addString' => ['void', 'string'=>'string'],
'SWFTextField::align' => ['void', 'alignement'=>'int'],
'SWFTextField::setBounds' => ['void', 'width'=>'float', 'height'=>'float'],
'SWFTextField::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'],
'SWFTextField::setFont' => ['void', 'font'=>'swffont'],
'SWFTextField::setHeight' => ['void', 'height'=>'float'],
'SWFTextField::setIndentation' => ['void', 'width'=>'float'],
'SWFTextField::setLeftMargin' => ['void', 'width'=>'float'],
'SWFTextField::setLineSpacing' => ['void', 'height'=>'float'],
'SWFTextField::setMargins' => ['void', 'left'=>'float', 'right'=>'float'],
'SWFTextField::setName' => ['void', 'name'=>'string'],
'SWFTextField::setPadding' => ['void', 'padding'=>'float'],
'SWFTextField::setRightMargin' => ['void', 'width'=>'float'],
'SWFVideoStream::__construct' => ['void', 'file='=>'string'],
'SWFVideoStream::getNumFrames' => ['int'],
'SWFVideoStream::setDimension' => ['void', 'x'=>'int', 'y'=>'int'],
'Swish::__construct' => ['void', 'index_names'=>'string'],
'Swish::getMetaList' => ['array', 'index_name'=>'string'],
'Swish::getPropertyList' => ['array', 'index_name'=>'string'],
'Swish::prepare' => ['object', 'query='=>'string'],
'Swish::query' => ['object', 'query'=>'string'],
'SwishResult::getMetaList' => ['array'],
'SwishResult::stem' => ['array', 'word'=>'string'],
'SwishResults::getParsedWords' => ['array', 'index_name'=>'string'],
'SwishResults::getRemovedStopwords' => ['array', 'index_name'=>'string'],
'SwishResults::nextResult' => ['object'],
'SwishResults::seekResult' => ['int', 'position'=>'int'],
'SwishSearch::execute' => ['object', 'query='=>'string'],
'SwishSearch::resetLimit' => [''],
'SwishSearch::setLimit' => ['', 'property'=>'string', 'low'=>'string', 'high'=>'string'],
'SwishSearch::setPhraseDelimiter' => ['', 'delimiter'=>'string'],
'SwishSearch::setSort' => ['', 'sort'=>'string'],
'SwishSearch::setStructure' => ['', 'structure'=>'int'],
'swoole\async::dnsLookup' => ['void', 'hostname'=>'string', 'callback'=>'callable'],
'swoole\async::read' => ['bool', 'filename'=>'string', 'callback'=>'callable', 'chunk_size='=>'integer', 'offset='=>'integer'],
'swoole\async::readFile' => ['void', 'filename'=>'string', 'callback'=>'callable'],
'swoole\async::set' => ['void', 'settings'=>'array'],
'swoole\async::write' => ['void', 'filename'=>'string', 'content'=>'string', 'offset='=>'integer', 'callback='=>'callable'],
'swoole\async::writeFile' => ['void', 'filename'=>'string', 'content'=>'string', 'callback='=>'callable', 'flags='=>'string'],
'swoole\atomic::add' => ['integer', 'add_value='=>'integer'],
'swoole\atomic::cmpset' => ['integer', 'cmp_value'=>'integer', 'new_value'=>'integer'],
'swoole\atomic::get' => ['integer'],
'swoole\atomic::set' => ['integer', 'value'=>'integer'],
'swoole\atomic::sub' => ['integer', 'sub_value='=>'integer'],
'swoole\buffer::__destruct' => ['void'],
'swoole\buffer::__toString' => ['string'],
'swoole\buffer::append' => ['integer', 'data'=>'string'],
'swoole\buffer::clear' => ['void'],
'swoole\buffer::expand' => ['integer', 'size'=>'integer'],
'swoole\buffer::read' => ['string', 'offset'=>'integer', 'length'=>'integer'],
'swoole\buffer::recycle' => ['void'],
'swoole\buffer::substr' => ['string', 'offset'=>'integer', 'length='=>'integer', 'remove='=>'bool'],
'swoole\buffer::write' => ['void', 'offset'=>'integer', 'data'=>'string'],
'swoole\channel::__destruct' => ['void'],
'swoole\channel::pop' => ['mixed'],
'swoole\channel::push' => ['bool', 'data'=>'string'],
'swoole\channel::stats' => ['array'],
'swoole\client::__destruct' => ['void'],
'swoole\client::close' => ['bool', 'force='=>'bool'],
'swoole\client::connect' => ['bool', 'host'=>'string', 'port='=>'integer', 'timeout='=>'integer', 'flag='=>'integer'],
'swoole\client::getpeername' => ['array'],
'swoole\client::getsockname' => ['array'],
'swoole\client::isConnected' => ['bool'],
'swoole\client::on' => ['void', 'event'=>'string', 'callback'=>'callable'],
'swoole\client::pause' => ['void'],
'swoole\client::pipe' => ['void', 'socket'=>'string'],
'swoole\client::recv' => ['void', 'size='=>'string', 'flag='=>'string'],
'swoole\client::resume' => ['void'],
'swoole\client::send' => ['integer', 'data'=>'string', 'flag='=>'string'],
'swoole\client::sendfile' => ['bool', 'filename'=>'string', 'offset='=>'int'],
'swoole\client::sendto' => ['bool', 'ip'=>'string', 'port'=>'integer', 'data'=>'string'],
'swoole\client::set' => ['void', 'settings'=>'array'],
'swoole\client::sleep' => ['void'],
'swoole\client::wakeup' => ['void'],
'swoole\connection\iterator::count' => ['int'],
'swoole\connection\iterator::current' => ['Connection'],
'swoole\connection\iterator::key' => ['int'],
'swoole\connection\iterator::next' => ['Connection'],
'swoole\connection\iterator::offsetExists' => ['bool', 'index'=>'int'],
'swoole\connection\iterator::offsetGet' => ['Connection', 'index'=>'string'],
'swoole\connection\iterator::offsetSet' => ['void', 'offset'=>'int', 'connection'=>'mixed'],
'swoole\connection\iterator::offsetUnset' => ['void', 'offset'=>'int'],
'swoole\connection\iterator::rewind' => ['void'],
'swoole\connection\iterator::valid' => ['bool'],
'swoole\coroutine::call_user_func' => ['mixed', 'callback'=>'callable', 'parameter='=>'mixed', '...args='=>'mixed'],
'swoole\coroutine::call_user_func_array' => ['mixed', 'callback'=>'callable', 'param_array'=>'array'],
'swoole\coroutine::cli_wait' => ['ReturnType'],
'swoole\coroutine::create' => ['ReturnType'],
'swoole\coroutine::getuid' => ['ReturnType'],
'swoole\coroutine::resume' => ['ReturnType'],
'swoole\coroutine::suspend' => ['ReturnType'],
'swoole\coroutine\client::__destruct' => ['ReturnType'],
'swoole\coroutine\client::close' => ['ReturnType'],
'swoole\coroutine\client::connect' => ['ReturnType'],
'swoole\coroutine\client::getpeername' => ['ReturnType'],
'swoole\coroutine\client::getsockname' => ['ReturnType'],
'swoole\coroutine\client::isConnected' => ['ReturnType'],
'swoole\coroutine\client::recv' => ['ReturnType'],
'swoole\coroutine\client::send' => ['ReturnType'],
'swoole\coroutine\client::sendfile' => ['ReturnType'],
'swoole\coroutine\client::sendto' => ['ReturnType'],
'swoole\coroutine\client::set' => ['ReturnType'],
'swoole\coroutine\http\client::__destruct' => ['ReturnType'],
'swoole\coroutine\http\client::addFile' => ['ReturnType'],
'swoole\coroutine\http\client::close' => ['ReturnType'],
'swoole\coroutine\http\client::execute' => ['ReturnType'],
'swoole\coroutine\http\client::get' => ['ReturnType'],
'swoole\coroutine\http\client::getDefer' => ['ReturnType'],
'swoole\coroutine\http\client::isConnected' => ['ReturnType'],
'swoole\coroutine\http\client::post' => ['ReturnType'],
'swoole\coroutine\http\client::recv' => ['ReturnType'],
'swoole\coroutine\http\client::set' => ['ReturnType'],
'swoole\coroutine\http\client::setCookies' => ['ReturnType'],
'swoole\coroutine\http\client::setData' => ['ReturnType'],
'swoole\coroutine\http\client::setDefer' => ['ReturnType'],
'swoole\coroutine\http\client::setHeaders' => ['ReturnType'],
'swoole\coroutine\http\client::setMethod' => ['ReturnType'],
'swoole\coroutine\mysql::__destruct' => ['ReturnType'],
'swoole\coroutine\mysql::close' => ['ReturnType'],
'swoole\coroutine\mysql::connect' => ['ReturnType'],
'swoole\coroutine\mysql::getDefer' => ['ReturnType'],
'swoole\coroutine\mysql::query' => ['ReturnType'],
'swoole\coroutine\mysql::recv' => ['ReturnType'],
'swoole\coroutine\mysql::setDefer' => ['ReturnType'],
'swoole\event::add' => ['bool', 'fd'=>'int', 'read_callback'=>'callable', 'write_callback='=>'callable', 'events='=>'string'],
'swoole\event::defer' => ['void', 'callback'=>'mixed'],
'swoole\event::del' => ['bool', 'fd'=>'string'],
'swoole\event::exit' => ['void'],
'swoole\event::set' => ['bool', 'fd'=>'int', 'read_callback='=>'string', 'write_callback='=>'string', 'events='=>'string'],
'swoole\event::wait' => ['void'],
'swoole\event::write' => ['void', 'fd'=>'string', 'data'=>'string'],
'swoole\http\client::__destruct' => ['void'],
'swoole\http\client::addFile' => ['void', 'path'=>'string', 'name'=>'string', 'type='=>'string', 'filename='=>'string', 'offset='=>'string'],
'swoole\http\client::close' => ['void'],
'swoole\http\client::download' => ['void', 'path'=>'string', 'file'=>'string', 'callback'=>'callable', 'offset='=>'integer'],
'swoole\http\client::execute' => ['void', 'path'=>'string', 'callback'=>'string'],
'swoole\http\client::get' => ['void', 'path'=>'string', 'callback'=>'callable'],
'swoole\http\client::isConnected' => ['bool'],
'swoole\http\client::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
'swoole\http\client::post' => ['void', 'path'=>'string', 'data'=>'string', 'callback'=>'callable'],
'swoole\http\client::push' => ['void', 'data'=>'string', 'opcode='=>'string', 'finish='=>'string'],
'swoole\http\client::set' => ['void', 'settings'=>'array'],
'swoole\http\client::setCookies' => ['void', 'cookies'=>'array'],
'swoole\http\client::setData' => ['ReturnType', 'data'=>'string'],
'swoole\http\client::setHeaders' => ['void', 'headers'=>'array'],
'swoole\http\client::setMethod' => ['void', 'method'=>'string'],
'swoole\http\client::upgrade' => ['void', 'path'=>'string', 'callback'=>'string'],
'swoole\http\request::__destruct' => ['void'],
'swoole\http\request::rawcontent' => ['string'],
'swoole\http\response::__destruct' => ['void'],
'swoole\http\response::cookie' => ['string', 'name'=>'string', 'value='=>'string', 'expires='=>'string', 'path='=>'string', 'domain='=>'string', 'secure='=>'string', 'httponly='=>'string'],
'swoole\http\response::end' => ['void', 'content='=>'string'],
'swoole\http\response::gzip' => ['ReturnType', 'compress_level='=>'string'],
'swoole\http\response::header' => ['void', 'key'=>'string', 'value'=>'string', 'ucwords='=>'string'],
'swoole\http\response::initHeader' => ['ReturnType'],
'swoole\http\response::rawcookie' => ['ReturnType', 'name'=>'string', 'value='=>'string', 'expires='=>'string', 'path='=>'string', 'domain='=>'string', 'secure='=>'string', 'httponly='=>'string'],
'swoole\http\response::sendfile' => ['ReturnType', 'filename'=>'string', 'offset='=>'int'],
'swoole\http\response::status' => ['ReturnType', 'http_code'=>'string'],
'swoole\http\response::write' => ['void', 'content'=>'string'],
'swoole\http\server::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
'swoole\http\server::start' => ['void'],
'swoole\lock::__destruct' => ['void'],
'swoole\lock::lock' => ['void'],
'swoole\lock::lock_read' => ['void'],
'swoole\lock::trylock' => ['void'],
'swoole\lock::trylock_read' => ['void'],
'swoole\lock::unlock' => ['void'],
'swoole\mmap::open' => ['ReturnType', 'filename'=>'string', 'size='=>'string', 'offset='=>'string'],
'swoole\mysql::__destruct' => ['void'],
'swoole\mysql::close' => ['void'],
'swoole\mysql::connect' => ['void', 'server_config'=>'array', 'callback'=>'callable'],
'swoole\mysql::getBuffer' => ['ReturnType'],
'swoole\mysql::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
'swoole\mysql::query' => ['ReturnType', 'sql'=>'string', 'callback'=>'callable'],
'swoole\process::__destruct' => ['void'],
'swoole\process::alarm' => ['void', 'interval_usec'=>'integer'],
'swoole\process::close' => ['void'],
'swoole\process::daemon' => ['void', 'nochdir='=>'bool', 'noclose='=>'bool'],
'swoole\process::exec' => ['ReturnType', 'exec_file'=>'string', 'args'=>'string'],
'swoole\process::exit' => ['void', 'exit_code='=>'string'],
'swoole\process::freeQueue' => ['void'],
'swoole\process::kill' => ['void', 'pid'=>'integer', 'signal_no='=>'string'],
'swoole\process::name' => ['void', 'process_name'=>'string'],
'swoole\process::pop' => ['mixed', 'maxsize='=>'integer'],
'swoole\process::push' => ['bool', 'data'=>'string'],
'swoole\process::read' => ['string', 'maxsize='=>'integer'],
'swoole\process::signal' => ['void', 'signal_no'=>'string', 'callback'=>'callable'],
'swoole\process::start' => ['void'],
'swoole\process::statQueue' => ['array'],
'swoole\process::useQueue' => ['bool', 'key'=>'integer', 'mode='=>'integer'],
'swoole\process::wait' => ['array', 'blocking='=>'bool'],
'swoole\process::write' => ['integer', 'data'=>'string'],
'swoole\redis\server::format' => ['ReturnType', 'type'=>'string', 'value='=>'string'],
'swoole\redis\server::setHandler' => ['ReturnType', 'command'=>'string', 'callback'=>'string', 'number_of_string_param='=>'string', 'type_of_array_param='=>'string'],
'swoole\redis\server::start' => ['ReturnType'],
'swoole\serialize::pack' => ['ReturnType', 'data'=>'string', 'is_fast='=>'int'],
'swoole\serialize::unpack' => ['ReturnType', 'data'=>'string', 'args='=>'string'],
'swoole\server::addlistener' => ['void', 'host'=>'string', 'port'=>'integer', 'socket_type'=>'string'],
'swoole\server::addProcess' => ['bool', 'process'=>'swoole_process'],
'swoole\server::after' => ['ReturnType', 'after_time_ms'=>'integer', 'callback'=>'callable', 'param='=>'string'],
'swoole\server::bind' => ['bool', 'fd'=>'integer', 'uid'=>'integer'],
'swoole\server::close' => ['bool', 'fd'=>'integer', 'reset='=>'bool'],
'swoole\server::confirm' => ['bool', 'fd'=>'integer'],
'swoole\server::connection_info' => ['array', 'fd'=>'integer', 'reactor_id='=>'integer'],
'swoole\server::connection_list' => ['array', 'start_fd'=>'integer', 'pagesize='=>'integer'],
'swoole\server::defer' => ['void', 'callback'=>'callable'],
'swoole\server::exist' => ['bool', 'fd'=>'integer'],
'swoole\server::finish' => ['void', 'data'=>'string'],
'swoole\server::getClientInfo' => ['ReturnType', 'fd'=>'integer', 'reactor_id='=>'integer'],
'swoole\server::getClientList' => ['array', 'start_fd'=>'integer', 'pagesize='=>'integer'],
'swoole\server::getLastError' => ['integer'],
'swoole\server::heartbeat' => ['mixed', 'if_close_connection'=>'bool'],
'swoole\server::listen' => ['bool', 'host'=>'string', 'port'=>'integer', 'socket_type'=>'string'],
'swoole\server::on' => ['void', 'event_name'=>'string', 'callback'=>'callable'],
'swoole\server::pause' => ['void', 'fd'=>'integer'],
'swoole\server::protect' => ['void', 'fd'=>'integer', 'is_protected='=>'bool'],
'swoole\server::reload' => ['bool'],
'swoole\server::resume' => ['void', 'fd'=>'integer'],
'swoole\server::send' => ['bool', 'fd'=>'integer', 'data'=>'string', 'reactor_id='=>'integer'],
'swoole\server::sendfile' => ['bool', 'fd'=>'integer', 'filename'=>'string', 'offset='=>'integer'],
'swoole\server::sendMessage' => ['bool', 'worker_id'=>'integer', 'data'=>'string'],
'swoole\server::sendto' => ['bool', 'ip'=>'string', 'port'=>'integer', 'data'=>'string', 'server_socket='=>'string'],
'swoole\server::sendwait' => ['bool', 'fd'=>'integer', 'data'=>'string'],
'swoole\server::set' => ['ReturnType', 'settings'=>'array'],
'swoole\server::shutdown' => ['void'],
'swoole\server::start' => ['void'],
'swoole\server::stats' => ['array'],
'swoole\server::stop' => ['bool', 'worker_id='=>'integer'],
'swoole\server::task' => ['mixed', 'data'=>'string', 'dst_worker_id='=>'integer', 'callback='=>'callable'],
'swoole\server::taskwait' => ['void', 'data'=>'string', 'timeout='=>'float', 'worker_id='=>'integer'],
'swoole\server::taskWaitMulti' => ['void', 'tasks'=>'array', 'timeout_ms='=>'double'],
'swoole\server::tick' => ['void', 'interval_ms'=>'integer', 'callback'=>'callable'],
'swoole\server\port::__destruct' => ['void'],
'swoole\server\port::on' => ['ReturnType', 'event_name'=>'string', 'callback'=>'callable'],
'swoole\server\port::set' => ['void', 'settings'=>'array'],
'swoole\table::column' => ['ReturnType', 'name'=>'string', 'type'=>'string', 'size='=>'integer'],
'swoole\table::count' => ['integer'],
'swoole\table::create' => ['void'],
'swoole\table::current' => ['array'],
'swoole\table::decr' => ['ReturnType', 'key'=>'string', 'column'=>'string', 'decrby='=>'integer'],
'swoole\table::del' => ['void', 'key'=>'string'],
'swoole\table::destroy' => ['void'],
'swoole\table::exist' => ['bool', 'key'=>'string'],
'swoole\table::get' => ['integer', 'row_key'=>'string', 'column_key'=>'string'],
'swoole\table::incr' => ['void', 'key'=>'string', 'column'=>'string', 'incrby='=>'integer'],
'swoole\table::key' => ['string'],
'swoole\table::next' => ['ReturnType'],
'swoole\table::rewind' => ['void'],
'swoole\table::set' => ['VOID', 'key'=>'string', 'value'=>'array'],
'swoole\table::valid' => ['bool'],
'swoole\timer::after' => ['void', 'after_time_ms'=>'int', 'callback'=>'callable'],
'swoole\timer::clear' => ['void', 'timer_id'=>'integer'],
'swoole\timer::exists' => ['bool', 'timer_id'=>'integer'],
'swoole\timer::tick' => ['void', 'interval_ms'=>'integer', 'callback'=>'callable', 'param='=>'string'],
'swoole\websocket\server::exist' => ['bool', 'fd'=>'integer'],
'swoole\websocket\server::on' => ['ReturnType', 'event_name'=>'string', 'callback'=>'callable'],
'swoole\websocket\server::pack' => ['binary', 'data'=>'string', 'opcode='=>'string', 'finish='=>'string', 'mask='=>'string'],
'swoole\websocket\server::push' => ['void', 'fd'=>'string', 'data'=>'string', 'opcode='=>'string', 'finish='=>'string'],
'swoole\websocket\server::unpack' => ['string', 'data'=>'binary'],
'swoole_async_dns_lookup' => ['bool', 'hostname'=>'string', 'callback'=>'callable'],
'swoole_async_read' => ['bool', 'filename'=>'string', 'callback'=>'callable', 'chunk_size='=>'int', 'offset='=>'int'],
'swoole_async_readfile' => ['bool', 'filename'=>'string', 'callback'=>'string'],
'swoole_async_set' => ['void', 'settings'=>'array'],
'swoole_async_write' => ['bool', 'filename'=>'string', 'content'=>'string', 'offset='=>'int', 'callback='=>'callable'],
'swoole_async_writefile' => ['bool', 'filename'=>'string', 'content'=>'string', 'callback='=>'callable', 'flags='=>'int'],
'swoole_client_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'],
'swoole_cpu_num' => ['int'],
'swoole_errno' => ['int'],
'swoole_event_add' => ['int', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'],
'swoole_event_defer' => ['bool', 'callback'=>'callable'],
'swoole_event_del' => ['bool', 'fd'=>'int'],
'swoole_event_exit' => ['void'],
'swoole_event_set' => ['bool', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'],
'swoole_event_wait' => ['void'],
'swoole_event_write' => ['bool', 'fd'=>'int', 'data'=>'string'],
'swoole_get_local_ip' => ['array'],
'swoole_last_error' => ['int'],
'swoole_load_module' => ['mixed', 'filename'=>'string'],
'swoole_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'],
'swoole_set_process_name' => ['void', 'process_name'=>'string', 'size='=>'int'],
'swoole_strerror' => ['string', 'errno'=>'int', 'error_type='=>'int'],
'swoole_timer_after' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'],
'swoole_timer_exists' => ['bool', 'timer_id'=>'int'],
'swoole_timer_tick' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'],
'swoole_version' => ['string'],
'symbolObj::__construct' => ['void', 'map'=>'mapObj', 'symbolname'=>'string'],
'symbolObj::free' => ['void'],
'symbolObj::getPatternArray' => ['array'],
'symbolObj::getPointsArray' => ['array'],
'symbolObj::ms_newSymbolObj' => ['int', 'map'=>'mapObj', 'symbolname'=>'string'],
'symbolObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'symbolObj::setImagePath' => ['int', 'filename'=>'string'],
'symbolObj::setPattern' => ['int', 'int'=>'array'],
'symbolObj::setPoints' => ['int', 'double'=>'array'],
'symlink' => ['bool', 'target'=>'string', 'link'=>'string'],
'SyncEvent::__construct' => ['void', 'name='=>'string', 'manual='=>'bool'],
'SyncEvent::fire' => ['bool'],
'SyncEvent::reset' => ['bool'],
'SyncEvent::wait' => ['bool', 'wait='=>'int'],
'SyncMutex::__construct' => ['void', 'name='=>'string'],
'SyncMutex::lock' => ['bool', 'wait='=>'int'],
'SyncMutex::unlock' => ['bool', 'all='=>'bool'],
'SyncReaderWriter::__construct' => ['void', 'name='=>'string', 'autounlock='=>'bool'],
'SyncReaderWriter::readlock' => ['bool', 'wait='=>'int'],
'SyncReaderWriter::readunlock' => ['bool'],
'SyncReaderWriter::writelock' => ['bool', 'wait='=>'int'],
'SyncReaderWriter::writeunlock' => ['bool'],
'SyncSemaphore::__construct' => ['void', 'name='=>'string', 'initialval='=>'int', 'autounlock='=>'bool'],
'SyncSemaphore::lock' => ['bool', 'wait='=>'int'],
'SyncSemaphore::unlock' => ['bool', '&w_prevcount='=>'int'],
'SyncSharedMemory::__construct' => ['void', 'name'=>'string', 'size'=>'int'],
'SyncSharedMemory::first' => ['bool'],
'SyncSharedMemory::read' => ['string', 'start='=>'int', 'length='=>'int'],
'SyncSharedMemory::size' => ['int'],
'SyncSharedMemory::write' => ['int', 'string='=>'string', 'start='=>'int'],
'sys_get_temp_dir' => ['string'],
'sys_getloadavg' => ['array'],
'syslog' => ['bool', 'priority'=>'int', 'message'=>'string'],
'system' => ['string|false', 'command'=>'string', '&w_result_code='=>'int'],
'taint' => ['bool', '&rw_string'=>'string', '&...w_other_strings='=>'string'],
'tan' => ['float', 'num'=>'float'],
'tanh' => ['float', 'num'=>'float'],
'tcpwrap_check' => ['bool', 'daemon'=>'string', 'address'=>'string', 'user='=>'string', 'nodns='=>'bool'],
'tempnam' => ['string|false', 'directory'=>'string', 'prefix'=>'string'],
'textdomain' => ['string', 'domain'=>'?string'],
'Thread::__construct' => ['void'],
'Thread::addRef' => ['void'],
'Thread::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'],
'Thread::count' => ['int'],
'Thread::delRef' => ['void'],
'Thread::detach' => ['void'],
'Thread::extend' => ['bool', 'class'=>'string'],
'Thread::getCreatorId' => ['int'],
'Thread::getCurrentThread' => ['Thread'],
'Thread::getCurrentThreadId' => ['int'],
'Thread::getRefCount' => ['int'],
'Thread::getTerminationInfo' => ['array'],
'Thread::getThreadId' => ['int'],
'Thread::globally' => ['mixed'],
'Thread::isGarbage' => ['bool'],
'Thread::isJoined' => ['bool'],
'Thread::isRunning' => ['bool'],
'Thread::isStarted' => ['bool'],
'Thread::isTerminated' => ['bool'],
'Thread::isWaiting' => ['bool'],
'Thread::join' => ['bool'],
'Thread::kill' => ['void'],
'Thread::lock' => ['bool'],
'Thread::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'],
'Thread::notify' => ['bool'],
'Thread::notifyOne' => ['bool'],
'Thread::offsetExists' => ['bool', 'offset'=>'mixed'],
'Thread::offsetGet' => ['mixed', 'offset'=>'mixed'],
'Thread::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
'Thread::offsetUnset' => ['void', 'offset'=>'mixed'],
'Thread::pop' => ['bool'],
'Thread::run' => ['void'],
'Thread::setGarbage' => ['void'],
'Thread::shift' => ['bool'],
'Thread::start' => ['bool', 'options='=>'int'],
'Thread::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'],
'Thread::unlock' => ['bool'],
'Thread::wait' => ['bool', 'timeout='=>'int'],
'Threaded::__construct' => ['void'],
'Threaded::addRef' => ['void'],
'Threaded::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'],
'Threaded::count' => ['int'],
'Threaded::delRef' => ['void'],
'Threaded::extend' => ['bool', 'class'=>'string'],
'Threaded::from' => ['Threaded', 'run'=>'Closure', 'construct='=>'Closure', 'args='=>'array'],
'Threaded::getRefCount' => ['int'],
'Threaded::getTerminationInfo' => ['array'],
'Threaded::isGarbage' => ['bool'],
'Threaded::isRunning' => ['bool'],
'Threaded::isTerminated' => ['bool'],
'Threaded::isWaiting' => ['bool'],
'Threaded::lock' => ['bool'],
'Threaded::merge' => ['bool', 'from'=>'mixed', 'overwrite='=>'bool'],
'Threaded::notify' => ['bool'],
'Threaded::notifyOne' => ['bool'],
'Threaded::offsetExists' => ['bool', 'offset'=>'mixed'],
'Threaded::offsetGet' => ['mixed', 'offset'=>'mixed'],
'Threaded::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
'Threaded::offsetUnset' => ['void', 'offset'=>'mixed'],
'Threaded::pop' => ['bool'],
'Threaded::run' => ['void'],
'Threaded::setGarbage' => ['void'],
'Threaded::shift' => ['mixed'],
'Threaded::synchronized' => ['mixed', 'block'=>'Closure', '...args='=>'mixed'],
'Threaded::unlock' => ['bool'],
'Threaded::wait' => ['bool', 'timeout='=>'int'],
'Throwable::__toString' => ['string'],
'Throwable::getCode' => ['int|string'],
'Throwable::getFile' => ['string'],
'Throwable::getLine' => ['int'],
'Throwable::getMessage' => ['string'],
'Throwable::getPrevious' => ['?Throwable'],
'Throwable::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'Throwable::getTraceAsString' => ['string'],
'tidy::__construct' => ['void', 'filename='=>'?string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
'tidy::body' => ['?tidyNode'],
'tidy::cleanRepair' => ['bool'],
'tidy::diagnose' => ['bool'],
'tidy::getConfig' => ['array'],
'tidy::getHtmlVer' => ['int'],
'tidy::getOpt' => ['string|int|bool', 'option'=>'string'],
'tidy::getOptDoc' => ['string', 'option'=>'string'],
'tidy::getRelease' => ['string'],
'tidy::getStatus' => ['int'],
'tidy::head' => ['?tidyNode'],
'tidy::html' => ['?tidyNode'],
'tidy::isXhtml' => ['bool'],
'tidy::isXml' => ['bool'],
'tidy::parseFile' => ['bool', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
'tidy::parseString' => ['bool', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
'tidy::repairFile' => ['string', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
'tidy::repairString' => ['string', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
'tidy::root' => ['?tidyNode'],
'tidy_access_count' => ['int', 'tidy'=>'tidy'],
'tidy_clean_repair' => ['bool', 'tidy'=>'tidy'],
'tidy_config_count' => ['int', 'tidy'=>'tidy'],
'tidy_diagnose' => ['bool', 'tidy'=>'tidy'],
'tidy_error_count' => ['int', 'tidy'=>'tidy'],
'tidy_get_body' => ['?tidyNode', 'tidy'=>'tidy'],
'tidy_get_config' => ['array', 'tidy'=>'tidy'],
'tidy_get_error_buffer' => ['string', 'tidy'=>'tidy'],
'tidy_get_head' => ['?tidyNode', 'tidy'=>'tidy'],
'tidy_get_html' => ['?tidyNode', 'tidy'=>'tidy'],
'tidy_get_html_ver' => ['int', 'tidy'=>'tidy'],
'tidy_get_opt_doc' => ['string', 'tidy'=>'tidy', 'option'=>'string'],
'tidy_get_output' => ['string', 'tidy'=>'tidy'],
'tidy_get_release' => ['string'],
'tidy_get_root' => ['?tidyNode', 'tidy'=>'tidy'],
'tidy_get_status' => ['int', 'tidy'=>'tidy'],
'tidy_getopt' => ['mixed', 'tidy'=>'string', 'option'=>'tidy'],
'tidy_is_xhtml' => ['bool', 'tidy'=>'tidy'],
'tidy_is_xml' => ['bool', 'tidy'=>'tidy'],
'tidy_load_config' => ['void', 'filename'=>'string', 'encoding'=>'string'],
'tidy_parse_file' => ['tidy', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
'tidy_parse_string' => ['tidy', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
'tidy_repair_file' => ['string', 'filename'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string', 'useIncludePath='=>'bool'],
'tidy_repair_string' => ['string', 'string'=>'string', 'config='=>'array|string|null', 'encoding='=>'?string'],
'tidy_reset_config' => ['bool'],
'tidy_save_config' => ['bool', 'filename'=>'string'],
'tidy_set_encoding' => ['bool', 'encoding'=>'string'],
'tidy_setopt' => ['bool', 'option'=>'string', 'value'=>'mixed'],
'tidy_warning_count' => ['int', 'tidy'=>'tidy'],
'tidyNode::__construct' => ['void'],
'tidyNode::getParent' => ['?tidyNode'],
'tidyNode::hasChildren' => ['bool'],
'tidyNode::hasSiblings' => ['bool'],
'tidyNode::isAsp' => ['bool'],
'tidyNode::isComment' => ['bool'],
'tidyNode::isHtml' => ['bool'],
'tidyNode::isJste' => ['bool'],
'tidyNode::isPhp' => ['bool'],
'tidyNode::isText' => ['bool'],
'time' => ['positive-int'],
'time_nanosleep' => ['array{0:0|positive-int,1:0|positive-int}|bool', 'seconds'=>'positive-int', 'nanoseconds'=>'positive-int'],
'time_sleep_until' => ['bool', 'timestamp'=>'float'],
'timezone_abbreviations_list' => ['array<string, list<array{dst: bool, offset: int, timezone_id: string|null}>>'],
'timezone_identifiers_list' => ['list<string>', 'timezoneGroup='=>'int', 'countryCode='=>'?string'],
'timezone_location_get' => ['array|false', 'object'=>'DateTimeZone'],
'timezone_name_from_abbr' => ['string|false', 'abbr'=>'string', 'utcOffset='=>'int', 'isDST='=>'int'],
'timezone_name_get' => ['string', 'object'=>'DateTimeZone'],
'timezone_offset_get' => ['int', 'object'=>'DateTimeZone', 'datetime'=>'DateTimeInterface'],
'timezone_open' => ['DateTimeZone|false', 'timezone'=>'string'],
'timezone_transitions_get' => ['list<array{ts: int, time: string, offset: int, isdst: bool, abbr: string}>|false', 'object'=>'DateTimeZone', 'timestampBegin='=>'int', 'timestampEnd='=>'int'],
'timezone_version_get' => ['string'],
'tmpfile' => ['resource|false'],
'token_get_all' => ['list<string|array{0:int,1:string,2:int}>', 'code'=>'string', 'flags='=>'int'],
'token_name' => ['string', 'id'=>'int'],
'TokyoTyrant::__construct' => ['void', 'host='=>'string', 'port='=>'int', 'options='=>'array'],
'TokyoTyrant::add' => ['int|float', 'key'=>'string', 'increment'=>'float', 'type='=>'int'],
'TokyoTyrant::connect' => ['TokyoTyrant', 'host'=>'string', 'port='=>'int', 'options='=>'array'],
'TokyoTyrant::connectUri' => ['TokyoTyrant', 'uri'=>'string'],
'TokyoTyrant::copy' => ['TokyoTyrant', 'path'=>'string'],
'TokyoTyrant::ext' => ['string', 'name'=>'string', 'options'=>'int', 'key'=>'string', 'value'=>'string'],
'TokyoTyrant::fwmKeys' => ['array', 'prefix'=>'string', 'max_recs'=>'int'],
'TokyoTyrant::get' => ['array', 'keys'=>'mixed'],
'TokyoTyrant::getIterator' => ['TokyoTyrantIterator'],
'TokyoTyrant::num' => ['int'],
'TokyoTyrant::out' => ['string', 'keys'=>'mixed'],
'TokyoTyrant::put' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
'TokyoTyrant::putCat' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
'TokyoTyrant::putKeep' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
'TokyoTyrant::putNr' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'],
'TokyoTyrant::putShl' => ['mixed', 'key'=>'string', 'value'=>'string', 'width'=>'int'],
'TokyoTyrant::restore' => ['mixed', 'log_dir'=>'string', 'timestamp'=>'int', 'check_consistency='=>'bool'],
'TokyoTyrant::setMaster' => ['mixed', 'host'=>'string', 'port'=>'int', 'timestamp'=>'int', 'check_consistency='=>'bool'],
'TokyoTyrant::size' => ['int', 'key'=>'string'],
'TokyoTyrant::stat' => ['array'],
'TokyoTyrant::sync' => ['mixed'],
'TokyoTyrant::tune' => ['TokyoTyrant', 'timeout'=>'float', 'options='=>'int'],
'TokyoTyrant::vanish' => ['mixed'],
'TokyoTyrantIterator::__construct' => ['void', 'object'=>'mixed'],
'TokyoTyrantIterator::current' => ['mixed'],
'TokyoTyrantIterator::key' => ['mixed'],
'TokyoTyrantIterator::next' => ['mixed'],
'TokyoTyrantIterator::rewind' => ['void'],
'TokyoTyrantIterator::valid' => ['bool'],
'TokyoTyrantQuery::__construct' => ['void', 'table'=>'TokyoTyrantTable'],
'TokyoTyrantQuery::addCond' => ['mixed', 'name'=>'string', 'op'=>'int', 'expr'=>'string'],
'TokyoTyrantQuery::count' => ['int'],
'TokyoTyrantQuery::current' => ['array'],
'TokyoTyrantQuery::hint' => ['string'],
'TokyoTyrantQuery::key' => ['string'],
'TokyoTyrantQuery::metaSearch' => ['array', 'queries'=>'array', 'type'=>'int'],
'TokyoTyrantQuery::next' => ['array'],
'TokyoTyrantQuery::out' => ['TokyoTyrantQuery'],
'TokyoTyrantQuery::rewind' => ['bool'],
'TokyoTyrantQuery::search' => ['array'],
'TokyoTyrantQuery::setLimit' => ['mixed', 'max='=>'int', 'skip='=>'int'],
'TokyoTyrantQuery::setOrder' => ['mixed', 'name'=>'string', 'type'=>'int'],
'TokyoTyrantQuery::valid' => ['bool'],
'TokyoTyrantTable::add' => ['void', 'key'=>'string', 'increment'=>'mixed', 'type='=>'string'],
'TokyoTyrantTable::genUid' => ['int'],
'TokyoTyrantTable::get' => ['array', 'keys'=>'mixed'],
'TokyoTyrantTable::getIterator' => ['TokyoTyrantIterator'],
'TokyoTyrantTable::getQuery' => ['TokyoTyrantQuery'],
'TokyoTyrantTable::out' => ['void', 'keys'=>'mixed'],
'TokyoTyrantTable::put' => ['int', 'key'=>'string', 'columns'=>'array'],
'TokyoTyrantTable::putCat' => ['void', 'key'=>'string', 'columns'=>'array'],
'TokyoTyrantTable::putKeep' => ['void', 'key'=>'string', 'columns'=>'array'],
'TokyoTyrantTable::putNr' => ['void', 'keys'=>'mixed', 'value='=>'string'],
'TokyoTyrantTable::putShl' => ['void', 'key'=>'string', 'value'=>'string', 'width'=>'int'],
'TokyoTyrantTable::setIndex' => ['mixed', 'column'=>'string', 'type'=>'int'],
'touch' => ['bool', 'filename'=>'string', 'mtime='=>'?int', 'atime='=>'?int'],
'trader_acos' => ['array', 'real'=>'array'],
'trader_ad' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array'],
'trader_add' => ['array', 'real0'=>'array', 'real1'=>'array'],
'trader_adosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int'],
'trader_adx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_adxr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_apo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'],
'trader_aroon' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
'trader_aroonosc' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
'trader_asin' => ['array', 'real'=>'array'],
'trader_atan' => ['array', 'real'=>'array'],
'trader_atr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_avgprice' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_bbands' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDevUp='=>'float', 'nbDevDn='=>'float', 'mAType='=>'int'],
'trader_beta' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'],
'trader_bop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cci' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_cdl2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdl3blackcrows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdl3inside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdl3linestrike' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdl3outside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdl3starsinsouth' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdl3whitesoldiers' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlabandonedbaby' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
'trader_cdladvanceblock' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlbelthold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlbreakaway' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlclosingmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlconcealbabyswall' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlcounterattack' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdldarkcloudcover' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
'trader_cdldoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdldojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdldragonflydoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlengulfing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdleveningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
'trader_cdleveningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
'trader_cdlgapsidesidewhite' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlgravestonedoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlhangingman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlharami' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlharamicross' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlhighwave' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlhikkake' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlhikkakemod' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlhomingpigeon' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlidentical3crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlinneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlinvertedhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlkicking' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlkickingbylength' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlladderbottom' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdllongleggeddoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdllongline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlmatchinglow' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlmathold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
'trader_cdlmorningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
'trader_cdlmorningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'],
'trader_cdlonneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlpiercing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlrickshawman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlrisefall3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlseparatinglines' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlshootingstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlshortline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlspinningtop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlstalledpattern' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlsticksandwich' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdltakuri' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdltasukigap' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlthrusting' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdltristar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlunique3river' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlupsidegap2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_cdlxsidegap3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_ceil' => ['array', 'real'=>'array'],
'trader_cmo' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_correl' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'],
'trader_cos' => ['array', 'real'=>'array'],
'trader_cosh' => ['array', 'real'=>'array'],
'trader_dema' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_div' => ['array', 'real0'=>'array', 'real1'=>'array'],
'trader_dx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_ema' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_errno' => ['int'],
'trader_exp' => ['array', 'real'=>'array'],
'trader_floor' => ['array', 'real'=>'array'],
'trader_get_compat' => ['int'],
'trader_get_unstable_period' => ['int', 'functionId'=>'int'],
'trader_ht_dcperiod' => ['array', 'real'=>'array'],
'trader_ht_dcphase' => ['array', 'real'=>'array'],
'trader_ht_phasor' => ['array', 'real'=>'array'],
'trader_ht_sine' => ['array', 'real'=>'array'],
'trader_ht_trendline' => ['array', 'real'=>'array'],
'trader_ht_trendmode' => ['array', 'real'=>'array'],
'trader_kama' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_linearreg' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_linearreg_angle' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_linearreg_intercept' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_linearreg_slope' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_ln' => ['array', 'real'=>'array'],
'trader_log10' => ['array', 'real'=>'array'],
'trader_ma' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'mAType='=>'int'],
'trader_macd' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'signalPeriod='=>'int'],
'trader_macdext' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'fastMAType='=>'int', 'slowPeriod='=>'int', 'slowMAType='=>'int', 'signalPeriod='=>'int', 'signalMAType='=>'int'],
'trader_macdfix' => ['array', 'real'=>'array', 'signalPeriod='=>'int'],
'trader_mama' => ['array', 'real'=>'array', 'fastLimit='=>'float', 'slowLimit='=>'float'],
'trader_mavp' => ['array', 'real'=>'array', 'periods'=>'array', 'minPeriod='=>'int', 'maxPeriod='=>'int', 'mAType='=>'int'],
'trader_max' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_maxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_medprice' => ['array', 'high'=>'array', 'low'=>'array'],
'trader_mfi' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'timePeriod='=>'int'],
'trader_midpoint' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_midprice' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
'trader_min' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_minindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_minmax' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_minmaxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_minus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_minus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
'trader_mom' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_mult' => ['array', 'real0'=>'array', 'real1'=>'array'],
'trader_natr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_obv' => ['array', 'real'=>'array', 'volume'=>'array'],
'trader_plus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_plus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'],
'trader_ppo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'],
'trader_roc' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_rocp' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_rocr' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_rocr100' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_rsi' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_sar' => ['array', 'high'=>'array', 'low'=>'array', 'acceleration='=>'float', 'maximum='=>'float'],
'trader_sarext' => ['array', 'high'=>'array', 'low'=>'array', 'startValue='=>'float', 'offsetOnReverse='=>'float', 'accelerationInitLong='=>'float', 'accelerationLong='=>'float', 'accelerationMaxLong='=>'float', 'accelerationInitShort='=>'float', 'accelerationShort='=>'float', 'accelerationMaxShort='=>'float'],
'trader_set_compat' => ['void', 'compatId'=>'int'],
'trader_set_unstable_period' => ['void', 'functionId'=>'int', 'timePeriod'=>'int'],
'trader_sin' => ['array', 'real'=>'array'],
'trader_sinh' => ['array', 'real'=>'array'],
'trader_sma' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_sqrt' => ['array', 'real'=>'array'],
'trader_stddev' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'],
'trader_stoch' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'slowK_Period='=>'int', 'slowK_MAType='=>'int', 'slowD_Period='=>'int', 'slowD_MAType='=>'int'],
'trader_stochf' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'],
'trader_stochrsi' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'],
'trader_sub' => ['array', 'real0'=>'array', 'real1'=>'array'],
'trader_sum' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_t3' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'vFactor='=>'float'],
'trader_tan' => ['array', 'real'=>'array'],
'trader_tanh' => ['array', 'real'=>'array'],
'trader_tema' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_trange' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_trima' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_trix' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_tsf' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trader_typprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_ultosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod1='=>'int', 'timePeriod2='=>'int', 'timePeriod3='=>'int'],
'trader_var' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'],
'trader_wclprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'],
'trader_willr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'],
'trader_wma' => ['array', 'real'=>'array', 'timePeriod='=>'int'],
'trait_exists' => ['bool', 'trait'=>'string', 'autoload='=>'bool'],
'Transliterator::create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'],
'Transliterator::createFromRules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'],
'Transliterator::createInverse' => ['?Transliterator'],
'Transliterator::getErrorCode' => ['int'],
'Transliterator::getErrorMessage' => ['string'],
'Transliterator::listIDs' => ['array'],
'Transliterator::transliterate' => ['string|false', 'subject'=>'string', 'start='=>'int', 'end='=>'int'],
'transliterator_create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'],
'transliterator_create_from_rules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'],
'transliterator_create_inverse' => ['?Transliterator', 'transliterator'=>'Transliterator'],
'transliterator_get_error_code' => ['int', 'transliterator'=>'Transliterator'],
'transliterator_get_error_message' => ['string', 'transliterator'=>'Transliterator'],
'transliterator_list_ids' => ['array'],
'transliterator_transliterate' => ['string|false', 'transliterator'=>'Transliterator|string', 'string'=>'string', 'start='=>'int', 'end='=>'int'],
'trigger_error' => ['bool', 'message'=>'string', 'error_level='=>'256|512|1024|16384'],
'trim' => ['string', 'string'=>'string', 'characters='=>'string'],
'TypeError::__clone' => ['void'],
'TypeError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'TypeError::__toString' => ['string'],
'TypeError::getCode' => ['int'],
'TypeError::getFile' => ['string'],
'TypeError::getLine' => ['int'],
'TypeError::getMessage' => ['string'],
'TypeError::getPrevious' => ['?Throwable'],
'TypeError::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'TypeError::getTraceAsString' => ['string'],
'uasort' => ['bool', '&rw_array'=>'array', 'callback'=>'callable(mixed,mixed):int'],
'ucfirst' => ['string', 'string'=>'string'],
'UConverter::__construct' => ['void', 'destination_encoding='=>'?string', 'source_encoding='=>'?string'],
'UConverter::convert' => ['string', 'string'=>'string', 'reverse='=>'bool'],
'UConverter::fromUCallback' => ['mixed', 'reason'=>'int', 'source'=>'string', 'codePoint'=>'string', '&w_error'=>'int'],
'UConverter::getAliases' => ['array|false|null', 'name'=>'string'],
'UConverter::getAvailable' => ['array'],
'UConverter::getDestinationEncoding' => ['string|false|null'],
'UConverter::getDestinationType' => ['int|false|null'],
'UConverter::getErrorCode' => ['int'],
'UConverter::getErrorMessage' => ['?string'],
'UConverter::getSourceEncoding' => ['string|false|null'],
'UConverter::getSourceType' => ['int|false|null'],
'UConverter::getStandards' => ['?array'],
'UConverter::getSubstChars' => ['string|false|null'],
'UConverter::reasonText' => ['string', 'reason='=>'int'],
'UConverter::setDestinationEncoding' => ['bool', 'encoding'=>'string'],
'UConverter::setSourceEncoding' => ['bool', 'encoding'=>'string'],
'UConverter::setSubstChars' => ['bool', 'chars'=>'string'],
'UConverter::toUCallback' => ['string|int|array|null', 'reason'=>'int', 'source'=>'string', 'codeUnits'=>'string', '&w_error'=>'int'],
'UConverter::transcode' => ['string', 'string'=>'string', 'toEncoding'=>'string', 'fromEncoding'=>'string', 'options='=>'?array'],
'ucwords' => ['string', 'string'=>'string', 'separators='=>'string'],
'udm_add_search_limit' => ['bool', 'agent'=>'resource', 'var'=>'int', 'value'=>'string'],
'udm_alloc_agent' => ['resource', 'dbaddr'=>'string', 'dbmode='=>'string'],
'udm_alloc_agent_array' => ['resource', 'databases'=>'array'],
'udm_api_version' => ['int'],
'udm_cat_list' => ['array', 'agent'=>'resource', 'category'=>'string'],
'udm_cat_path' => ['array', 'agent'=>'resource', 'category'=>'string'],
'udm_check_charset' => ['bool', 'agent'=>'resource', 'charset'=>'string'],
'udm_check_stored' => ['int', 'agent'=>'', 'link'=>'int', 'doc_id'=>'string'],
'udm_clear_search_limits' => ['bool', 'agent'=>'resource'],
'udm_close_stored' => ['int', 'agent'=>'', 'link'=>'int'],
'udm_crc32' => ['int', 'agent'=>'resource', 'string'=>'string'],
'udm_errno' => ['int', 'agent'=>'resource'],
'udm_error' => ['string', 'agent'=>'resource'],
'udm_find' => ['resource', 'agent'=>'resource', 'query'=>'string'],
'udm_free_agent' => ['int', 'agent'=>'resource'],
'udm_free_ispell_data' => ['bool', 'agent'=>'int'],
'udm_free_res' => ['bool', 'res'=>'resource'],
'udm_get_doc_count' => ['int', 'agent'=>'resource'],
'udm_get_res_field' => ['string', 'res'=>'resource', 'row'=>'int', 'field'=>'int'],
'udm_get_res_param' => ['string', 'res'=>'resource', 'param'=>'int'],
'udm_hash32' => ['int', 'agent'=>'resource', 'string'=>'string'],
'udm_load_ispell_data' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val1'=>'string', 'val2'=>'string', 'flag'=>'int'],
'udm_open_stored' => ['int', 'agent'=>'', 'storedaddr'=>'string'],
'udm_set_agent_param' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val'=>'string'],
'ui\area::onDraw' => ['', 'pen'=>'UI\Draw\Pen', 'areaSize'=>'UI\Size', 'clipPoint'=>'UI\Point', 'clipSize'=>'UI\Size'],
'ui\area::onKey' => ['', 'key'=>'string', 'ext'=>'int', 'flags'=>'int'],
'ui\area::onMouse' => ['', 'areaPoint'=>'UI\Point', 'areaSize'=>'UI\Size', 'flags'=>'int'],
'ui\area::redraw' => [''],
'ui\area::scrollTo' => ['', 'point'=>'UI\Point', 'size'=>'UI\Size'],
'ui\area::setSize' => ['', 'size'=>'UI\Size'],
'ui\control::destroy' => [''],
'ui\control::disable' => [''],
'ui\control::enable' => [''],
'ui\control::getParent' => ['UI\Control'],
'ui\control::getTopLevel' => ['int'],
'ui\control::hide' => [''],
'ui\control::isEnabled' => ['bool'],
'ui\control::isVisible' => ['bool'],
'ui\control::setParent' => ['', 'parent'=>'UI\Control'],
'ui\control::show' => [''],
'ui\controls\box::append' => ['int', 'control'=>'Control', 'stretchy='=>'bool'],
'ui\controls\box::delete' => ['bool', 'index'=>'int'],
'ui\controls\box::getOrientation' => ['int'],
'ui\controls\box::isPadded' => ['bool'],
'ui\controls\box::setPadded' => ['', 'padded'=>'bool'],
'ui\controls\button::getText' => ['string'],
'ui\controls\button::onClick' => [''],
'ui\controls\button::setText' => ['', 'text'=>'string'],
'ui\controls\check::getText' => ['string'],
'ui\controls\check::isChecked' => ['bool'],
'ui\controls\check::onToggle' => [''],
'ui\controls\check::setChecked' => ['', 'checked'=>'bool'],
'ui\controls\check::setText' => ['', 'text'=>'string'],
'ui\controls\colorbutton::getColor' => ['UI\Color'],
'ui\controls\colorbutton::onChange' => [''],
'ui\controls\combo::append' => ['', 'text'=>'string'],
'ui\controls\combo::getSelected' => ['int'],
'ui\controls\combo::onSelected' => [''],
'ui\controls\combo::setSelected' => ['', 'index'=>'int'],
'ui\controls\editablecombo::append' => ['', 'text'=>'string'],
'ui\controls\editablecombo::getText' => ['string'],
'ui\controls\editablecombo::onChange' => [''],
'ui\controls\editablecombo::setText' => ['', 'text'=>'string'],
'ui\controls\entry::getText' => ['string'],
'ui\controls\entry::isReadOnly' => ['bool'],
'ui\controls\entry::onChange' => [''],
'ui\controls\entry::setReadOnly' => ['', 'readOnly'=>'bool'],
'ui\controls\entry::setText' => ['', 'text'=>'string'],
'ui\controls\form::append' => ['int', 'label'=>'string', 'control'=>'UI\Control', 'stretchy='=>'bool'],
'ui\controls\form::delete' => ['bool', 'index'=>'int'],
'ui\controls\form::isPadded' => ['bool'],
'ui\controls\form::setPadded' => ['', 'padded'=>'bool'],
'ui\controls\grid::append' => ['', 'control'=>'UI\Control', 'left'=>'int', 'top'=>'int', 'xspan'=>'int', 'yspan'=>'int', 'hexpand'=>'bool', 'halign'=>'int', 'vexpand'=>'bool', 'valign'=>'int'],
'ui\controls\grid::isPadded' => ['bool'],
'ui\controls\grid::setPadded' => ['', 'padding'=>'bool'],
'ui\controls\group::append' => ['', 'control'=>'UI\Control'],
'ui\controls\group::getTitle' => ['string'],
'ui\controls\group::hasMargin' => ['bool'],
'ui\controls\group::setMargin' => ['', 'margin'=>'bool'],
'ui\controls\group::setTitle' => ['', 'title'=>'string'],
'ui\controls\label::getText' => ['string'],
'ui\controls\label::setText' => ['', 'text'=>'string'],
'ui\controls\multilineentry::append' => ['', 'text'=>'string'],
'ui\controls\multilineentry::getText' => ['string'],
'ui\controls\multilineentry::isReadOnly' => ['bool'],
'ui\controls\multilineentry::onChange' => [''],
'ui\controls\multilineentry::setReadOnly' => ['', 'readOnly'=>'bool'],
'ui\controls\multilineentry::setText' => ['', 'text'=>'string'],
'ui\controls\progress::getValue' => ['int'],
'ui\controls\progress::setValue' => ['', 'value'=>'int'],
'ui\controls\radio::append' => ['', 'text'=>'string'],
'ui\controls\radio::getSelected' => ['int'],
'ui\controls\radio::onSelected' => [''],
'ui\controls\radio::setSelected' => ['', 'index'=>'int'],
'ui\controls\slider::getValue' => ['int'],
'ui\controls\slider::onChange' => [''],
'ui\controls\slider::setValue' => ['', 'value'=>'int'],
'ui\controls\spin::getValue' => ['int'],
'ui\controls\spin::onChange' => [''],
'ui\controls\spin::setValue' => ['', 'value'=>'int'],
'ui\controls\tab::append' => ['int', 'name'=>'string', 'control'=>'UI\Control'],
'ui\controls\tab::delete' => ['bool', 'index'=>'int'],
'ui\controls\tab::hasMargin' => ['bool', 'page'=>'int'],
'ui\controls\tab::insertAt' => ['', 'name'=>'string', 'page'=>'int', 'control'=>'UI\Control'],
'ui\controls\tab::pages' => ['int'],
'ui\controls\tab::setMargin' => ['', 'page'=>'int', 'margin'=>'bool'],
'ui\draw\brush::getColor' => ['UI\Draw\Color'],
'ui\draw\brush\gradient::delStop' => ['int', 'index'=>'int'],
'ui\draw\color::getChannel' => ['float', 'channel'=>'int'],
'ui\draw\color::setChannel' => ['void', 'channel'=>'int', 'value'=>'float'],
'ui\draw\matrix::invert' => [''],
'ui\draw\matrix::isInvertible' => ['bool'],
'ui\draw\matrix::multiply' => ['UI\Draw\Matrix', 'matrix'=>'UI\Draw\Matrix'],
'ui\draw\matrix::rotate' => ['', 'point'=>'UI\Point', 'amount'=>'float'],
'ui\draw\matrix::scale' => ['', 'center'=>'UI\Point', 'point'=>'UI\Point'],
'ui\draw\matrix::skew' => ['', 'point'=>'UI\Point', 'amount'=>'UI\Point'],
'ui\draw\matrix::translate' => ['', 'point'=>'UI\Point'],
'ui\draw\path::addRectangle' => ['', 'point'=>'UI\Point', 'size'=>'UI\Size'],
'ui\draw\path::arcTo' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
'ui\draw\path::bezierTo' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
'ui\draw\path::closeFigure' => [''],
'ui\draw\path::end' => [''],
'ui\draw\path::lineTo' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
'ui\draw\path::newFigure' => ['', 'point'=>'UI\Point'],
'ui\draw\path::newFigureWithArc' => ['', 'point'=>'UI\Point', 'radius'=>'float', 'angle'=>'float', 'sweep'=>'float', 'negative'=>'float'],
'ui\draw\pen::clip' => ['', 'path'=>'UI\Draw\Path'],
'ui\draw\pen::restore' => [''],
'ui\draw\pen::save' => [''],
'ui\draw\pen::transform' => ['', 'matrix'=>'UI\Draw\Matrix'],
'ui\draw\pen::write' => ['', 'point'=>'UI\Point', 'layout'=>'UI\Draw\Text\Layout'],
'ui\draw\stroke::getCap' => ['int'],
'ui\draw\stroke::getJoin' => ['int'],
'ui\draw\stroke::getMiterLimit' => ['float'],
'ui\draw\stroke::getThickness' => ['float'],
'ui\draw\stroke::setCap' => ['', 'cap'=>'int'],
'ui\draw\stroke::setJoin' => ['', 'join'=>'int'],
'ui\draw\stroke::setMiterLimit' => ['', 'limit'=>'float'],
'ui\draw\stroke::setThickness' => ['', 'thickness'=>'float'],
'ui\draw\text\font::getAscent' => ['float'],
'ui\draw\text\font::getDescent' => ['float'],
'ui\draw\text\font::getLeading' => ['float'],
'ui\draw\text\font::getUnderlinePosition' => ['float'],
'ui\draw\text\font::getUnderlineThickness' => ['float'],
'ui\draw\text\font\descriptor::getFamily' => ['string'],
'ui\draw\text\font\descriptor::getItalic' => ['int'],
'ui\draw\text\font\descriptor::getSize' => ['float'],
'ui\draw\text\font\descriptor::getStretch' => ['int'],
'ui\draw\text\font\descriptor::getWeight' => ['int'],
'ui\draw\text\font\fontfamilies' => ['array'],
'ui\draw\text\layout::setWidth' => ['', 'width'=>'float'],
'ui\executor::kill' => ['void'],
'ui\executor::onExecute' => ['void'],
'ui\menu::append' => ['UI\MenuItem', 'name'=>'string', 'type='=>'string'],
'ui\menu::appendAbout' => ['UI\MenuItem', 'type='=>'string'],
'ui\menu::appendCheck' => ['UI\MenuItem', 'name'=>'string', 'type='=>'string'],
'ui\menu::appendPreferences' => ['UI\MenuItem', 'type='=>'string'],
'ui\menu::appendQuit' => ['UI\MenuItem', 'type='=>'string'],
'ui\menu::appendSeparator' => [''],
'ui\menuitem::disable' => [''],
'ui\menuitem::enable' => [''],
'ui\menuitem::isChecked' => ['bool'],
'ui\menuitem::onClick' => [''],
'ui\menuitem::setChecked' => ['', 'checked'=>'bool'],
'ui\point::getX' => ['float'],
'ui\point::getY' => ['float'],
'ui\point::setX' => ['', 'point'=>'float'],
'ui\point::setY' => ['', 'point'=>'float'],
'ui\quit' => ['void'],
'ui\run' => ['void', 'flags='=>'int'],
'ui\size::getHeight' => ['float'],
'ui\size::getWidth' => ['float'],
'ui\size::setHeight' => ['', 'size'=>'float'],
'ui\size::setWidth' => ['', 'size'=>'float'],
'ui\window::add' => ['', 'control'=>'UI\Control'],
'ui\window::error' => ['', 'title'=>'string', 'msg'=>'string'],
'ui\window::getSize' => ['UI\Size'],
'ui\window::getTitle' => ['string'],
'ui\window::hasBorders' => ['bool'],
'ui\window::hasMargin' => ['bool'],
'ui\window::isFullScreen' => ['bool'],
'ui\window::msg' => ['', 'title'=>'string', 'msg'=>'string'],
'ui\window::onClosing' => ['int'],
'ui\window::open' => ['string'],
'ui\window::save' => ['string'],
'ui\window::setBorders' => ['', 'borders'=>'bool'],
'ui\window::setFullScreen' => ['', 'full'=>'bool'],
'ui\window::setMargin' => ['', 'margin'=>'bool'],
'ui\window::setSize' => ['', 'size'=>'UI\Size'],
'ui\window::setTitle' => ['', 'title'=>'string'],
'uksort' => ['bool', '&rw_array'=>'array', 'callback'=>'callable(mixed,mixed):int'],
'umask' => ['int', 'mask='=>'?int'],
'UnderflowException::__clone' => ['void'],
'UnderflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'UnderflowException::__toString' => ['string'],
'UnderflowException::getCode' => ['int'],
'UnderflowException::getFile' => ['string'],
'UnderflowException::getLine' => ['int'],
'UnderflowException::getMessage' => ['string'],
'UnderflowException::getPrevious' => ['?Throwable'],
'UnderflowException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'UnderflowException::getTraceAsString' => ['string'],
'UnexpectedValueException::__clone' => ['void'],
'UnexpectedValueException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable'],
'UnexpectedValueException::__toString' => ['string'],
'UnexpectedValueException::getCode' => ['int'],
'UnexpectedValueException::getFile' => ['string'],
'UnexpectedValueException::getLine' => ['int'],
'UnexpectedValueException::getMessage' => ['string'],
'UnexpectedValueException::getPrevious' => ['?Throwable'],
'UnexpectedValueException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'UnexpectedValueException::getTraceAsString' => ['string'],
'uniqid' => ['non-empty-string', 'prefix='=>'string', 'more_entropy='=>'bool'],
'unixtojd' => ['int', 'timestamp='=>'?int'],
'unlink' => ['bool', 'filename'=>'string', 'context='=>'resource'],
'unpack' => ['array|false', 'format'=>'string', 'string'=>'string', 'offset='=>'int'],
'unregister_tick_function' => ['void', 'callback'=>'callable'],
'unserialize' => ['mixed', 'data'=>'string', 'options='=>'array{allowed_classes?:string[]|bool}'],
'unset' => ['void', 'var='=>'mixed', '...args='=>'mixed'],
'untaint' => ['bool', '&rw_string'=>'string', '&...rw_strings='=>'string'],
'uopz_allow_exit' => ['void', 'allow'=>'bool'],
'uopz_backup' => ['void', 'class'=>'string', 'function'=>'string'],
'uopz_backup\'1' => ['void', 'function'=>'string'],
'uopz_compose' => ['void', 'name'=>'string', 'classes'=>'array', 'methods='=>'array', 'properties='=>'array', 'flags='=>'int'],
'uopz_copy' => ['Closure', 'class'=>'string', 'function'=>'string'],
'uopz_copy\'1' => ['Closure', 'function'=>'string'],
'uopz_delete' => ['void', 'class'=>'string', 'function'=>'string'],
'uopz_delete\'1' => ['void', 'function'=>'string'],
'uopz_extend' => ['bool', 'class'=>'string', 'parent'=>'string'],
'uopz_flags' => ['int', 'class'=>'string', 'function'=>'string', 'flags'=>'int'],
'uopz_flags\'1' => ['int', 'function'=>'string', 'flags'=>'int'],
'uopz_function' => ['void', 'class'=>'string', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'],
'uopz_function\'1' => ['void', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'],
'uopz_get_exit_status' => ['?int'],
'uopz_get_hook' => ['?Closure', 'class'=>'string', 'function'=>'string'],
'uopz_get_hook\'1' => ['?Closure', 'function'=>'string'],
'uopz_get_mock' => ['string|object|null', 'class'=>'string'],
'uopz_get_property' => ['mixed', 'class'=>'object|string', 'property'=>'string'],
'uopz_get_return' => ['mixed', 'class='=>'string', 'function='=>'string'],
'uopz_get_static' => ['?array', 'class'=>'string', 'function'=>'string'],
'uopz_implement' => ['bool', 'class'=>'string', 'interface'=>'string'],
'uopz_overload' => ['void', 'opcode'=>'int', 'callable'=>'Callable'],
'uopz_redefine' => ['bool', 'class'=>'string', 'constant'=>'string', 'value'=>'mixed'],
'uopz_redefine\'1' => ['bool', 'constant'=>'string', 'value'=>'mixed'],
'uopz_rename' => ['void', 'class'=>'string', 'function'=>'string', 'rename'=>'string'],
'uopz_rename\'1' => ['void', 'function'=>'string', 'rename'=>'string'],
'uopz_restore' => ['void', 'class'=>'string', 'function'=>'string'],
'uopz_restore\'1' => ['void', 'function'=>'string'],
'uopz_set_hook' => ['bool', 'class'=>'string', 'function'=>'string', 'hook'=>'Closure'],
'uopz_set_hook\'1' => ['bool', 'function'=>'string', 'hook'=>'Closure'],
'uopz_set_mock' => ['void', 'class'=>'string', 'mock'=>'object|string'],
'uopz_set_property' => ['void', 'class'=>'object|string', 'property'=>'string', 'value'=>'mixed'],
'uopz_set_return' => ['bool', 'class'=>'string', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'],
'uopz_set_return\'1' => ['bool', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'],
'uopz_set_static' => ['void', 'class'=>'string', 'function'=>'string', 'static'=>'array'],
'uopz_undefine' => ['bool', 'class'=>'string', 'constant'=>'string'],
'uopz_undefine\'1' => ['bool', 'constant'=>'string'],
'uopz_unset_hook' => ['bool', 'class'=>'string', 'function'=>'string'],
'uopz_unset_hook\'1' => ['bool', 'function'=>'string'],
'uopz_unset_mock' => ['void', 'class'=>'string'],
'uopz_unset_return' => ['bool', 'class='=>'string', 'function='=>'string'],
'uopz_unset_return\'1' => ['bool', 'function'=>'string'],
'urldecode' => ['string', 'string'=>'string'],
'urlencode' => ['string', 'string'=>'string'],
'use_soap_error_handler' => ['bool', 'enable='=>'bool'],
'user_error' => ['bool', 'message'=>'string', 'error_level='=>'int'],
'usleep' => ['void', 'microseconds'=>'positive-int|0'],
'usort' => ['bool', '&rw_array'=>'array', 'callback'=>'callable(mixed,mixed):int'],
'utf8_decode' => ['string', 'string'=>'string'],
'utf8_encode' => ['string', 'string'=>'string'],
'V8Js::__construct' => ['void', 'object_name='=>'string', 'variables='=>'array', 'extensions='=>'array', 'report_uncaught_exceptions='=>'bool', 'snapshot_blob='=>'string'],
'V8Js::clearPendingException' => [''],
'V8Js::compileString' => ['resource', 'script'=>'', 'identifier='=>'string'],
'V8Js::createSnapshot' => ['false|string', 'embed_source'=>'string'],
'V8Js::executeScript' => ['', 'script'=>'resource', 'flags='=>'int', 'time_limit='=>'int', 'memory_limit='=>'int'],
'V8Js::executeString' => ['mixed', 'script'=>'string', 'identifier='=>'string', 'flags='=>'int'],
'V8Js::getExtensions' => ['string[]'],
'V8Js::getPendingException' => ['?V8JsException'],
'V8Js::registerExtension' => ['bool', 'extension_name'=>'string', 'script'=>'string', 'dependencies='=>'array', 'auto_enable='=>'bool'],
'V8Js::setAverageObjectSize' => ['', 'average_object_size'=>'int'],
'V8Js::setMemoryLimit' => ['', 'limit'=>'int'],
'V8Js::setModuleLoader' => ['', 'loader'=>'callable'],
'V8Js::setModuleNormaliser' => ['', 'normaliser'=>'callable'],
'V8Js::setTimeLimit' => ['', 'limit'=>'int'],
'V8JsException::getJsFileName' => ['string'],
'V8JsException::getJsLineNumber' => ['int'],
'V8JsException::getJsSourceLine' => ['int'],
'V8JsException::getJsTrace' => ['string'],
'V8JsScriptException::__clone' => ['void'],
'V8JsScriptException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'V8JsScriptException::__toString' => ['string'],
'V8JsScriptException::__wakeup' => ['void'],
'V8JsScriptException::getCode' => ['int'],
'V8JsScriptException::getFile' => ['string'],
'V8JsScriptException::getJsEndColumn' => ['int'],
'V8JsScriptException::getJsFileName' => ['string'],
'V8JsScriptException::getJsLineNumber' => ['int'],
'V8JsScriptException::getJsSourceLine' => ['string'],
'V8JsScriptException::getJsStartColumn' => ['int'],
'V8JsScriptException::getJsTrace' => ['string'],
'V8JsScriptException::getLine' => ['int'],
'V8JsScriptException::getMessage' => ['string'],
'V8JsScriptException::getPrevious' => ['Exception|Throwable'],
'V8JsScriptException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'V8JsScriptException::getTraceAsString' => ['string'],
'var_dump' => ['void', 'value'=>'mixed', '...values='=>'mixed'],
'var_export' => ['?string', 'value'=>'mixed', 'return='=>'bool'],
'VARIANT::__construct' => ['void', 'value='=>'mixed', 'type='=>'int', 'codepage='=>'int'],
'variant_abs' => ['mixed', 'value'=>'mixed'],
'variant_add' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_and' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_cast' => ['VARIANT', 'variant'=>'VARIANT', 'type'=>'int'],
'variant_cat' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_cmp' => ['int', 'left'=>'mixed', 'right'=>'mixed', 'locale_id='=>'int', 'flags='=>'int'],
'variant_date_from_timestamp' => ['VARIANT', 'timestamp'=>'int'],
'variant_date_to_timestamp' => ['int', 'variant'=>'VARIANT'],
'variant_div' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_eqv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_fix' => ['mixed', 'value'=>'mixed'],
'variant_get_type' => ['int', 'variant'=>'VARIANT'],
'variant_idiv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_imp' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_int' => ['mixed', 'value'=>'mixed'],
'variant_mod' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_mul' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_neg' => ['mixed', 'value'=>'mixed'],
'variant_not' => ['mixed', 'value'=>'mixed'],
'variant_or' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_pow' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_round' => ['mixed', 'value'=>'mixed', 'decimals'=>'int'],
'variant_set' => ['void', 'variant'=>'object', 'value'=>'mixed'],
'variant_set_type' => ['void', 'variant'=>'object', 'type'=>'int'],
'variant_sub' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'variant_xor' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'],
'VarnishAdmin::__construct' => ['void', 'args='=>'array'],
'VarnishAdmin::auth' => ['bool'],
'VarnishAdmin::ban' => ['int', 'vcl_regex'=>'string'],
'VarnishAdmin::banUrl' => ['int', 'vcl_regex'=>'string'],
'VarnishAdmin::clearPanic' => ['int'],
'VarnishAdmin::connect' => ['bool'],
'VarnishAdmin::disconnect' => ['bool'],
'VarnishAdmin::getPanic' => ['string'],
'VarnishAdmin::getParams' => ['array'],
'VarnishAdmin::isRunning' => ['bool'],
'VarnishAdmin::setCompat' => ['void', 'compat'=>'int'],
'VarnishAdmin::setHost' => ['void', 'host'=>'string'],
'VarnishAdmin::setIdent' => ['void', 'ident'=>'string'],
'VarnishAdmin::setParam' => ['int', 'name'=>'string', 'value'=>'string|int'],
'VarnishAdmin::setPort' => ['void', 'port'=>'int'],
'VarnishAdmin::setSecret' => ['void', 'secret'=>'string'],
'VarnishAdmin::setTimeout' => ['void', 'timeout'=>'int'],
'VarnishAdmin::start' => ['int'],
'VarnishAdmin::stop' => ['int'],
'VarnishLog::__construct' => ['void', 'args='=>'array'],
'VarnishLog::getLine' => ['array'],
'VarnishLog::getTagName' => ['string', 'index'=>'int'],
'VarnishStat::__construct' => ['void', 'args='=>'array'],
'VarnishStat::getSnapshot' => ['array'],
'version_compare' => ['bool', 'version1'=>'string', 'version2'=>'string', 'operator'=>'\'<\'|\'lt\'|\'<=\'|\'le\'|\'>\'|\'gt\'|\'>=\'|\'ge\'|\'==\'|\'=\'|\'eq\'|\'!=\'|\'<>\'|\'ne\''],
'version_compare\'1' => ['int', 'version1'=>'string', 'version2'=>'string'],
'vfprintf' => ['int', 'stream'=>'resource', 'format'=>'string', 'values'=>'array'],
'virtual' => ['bool', 'uri'=>'string'],
'vpopmail_add_alias_domain' => ['bool', 'domain'=>'string', 'aliasdomain'=>'string'],
'vpopmail_add_alias_domain_ex' => ['bool', 'olddomain'=>'string', 'newdomain'=>'string'],
'vpopmail_add_domain' => ['bool', 'domain'=>'string', 'dir'=>'string', 'uid'=>'int', 'gid'=>'int'],
'vpopmail_add_domain_ex' => ['bool', 'domain'=>'string', 'passwd'=>'string', 'quota='=>'string', 'bounce='=>'string', 'apop='=>'bool'],
'vpopmail_add_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'gecos='=>'string', 'apop='=>'bool'],
'vpopmail_alias_add' => ['bool', 'user'=>'string', 'domain'=>'string', 'alias'=>'string'],
'vpopmail_alias_del' => ['bool', 'user'=>'string', 'domain'=>'string'],
'vpopmail_alias_del_domain' => ['bool', 'domain'=>'string'],
'vpopmail_alias_get' => ['array', 'alias'=>'string', 'domain'=>'string'],
'vpopmail_alias_get_all' => ['array', 'domain'=>'string'],
'vpopmail_auth_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'string'],
'vpopmail_del_domain' => ['bool', 'domain'=>'string'],
'vpopmail_del_domain_ex' => ['bool', 'domain'=>'string'],
'vpopmail_del_user' => ['bool', 'user'=>'string', 'domain'=>'string'],
'vpopmail_error' => ['string'],
'vpopmail_passwd' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'bool'],
'vpopmail_set_user_quota' => ['bool', 'user'=>'string', 'domain'=>'string', 'quota'=>'string'],
'vprintf' => ['int', 'format'=>'string', 'values'=>'array'],
'vsprintf' => ['string', 'format'=>'string', 'values'=>'array'],
'Vtiful\Kernel\Chart::__construct' => ['void', 'handle'=>'resource', 'type'=>'int'],
'Vtiful\Kernel\Chart::axisNameX' => ['Vtiful\Kernel\Chart', 'name'=>'string'],
'Vtiful\Kernel\Chart::axisNameY' => ['Vtiful\Kernel\Chart', 'name'=>'string'],
'Vtiful\Kernel\Chart::legendSetPosition' => ['Vtiful\Kernel\Chart', 'type'=>'int'],
'Vtiful\Kernel\Chart::series' => ['Vtiful\Kernel\Chart', 'value'=>'string', 'categories='=>'string'],
'Vtiful\Kernel\Chart::seriesName' => ['Vtiful\Kernel\Chart', 'value'=>'string'],
'Vtiful\Kernel\Chart::style' => ['Vtiful\Kernel\Chart', 'style'=>'int'],
'Vtiful\Kernel\Chart::title' => ['Vtiful\Kernel\Chart', 'title'=>'string'],
'Vtiful\Kernel\Chart::toResource' => ['resource'],
'Vtiful\Kernel\Excel::__construct' => ['void', 'config'=>'array'],
'Vtiful\Kernel\Excel::activateSheet' => ['bool', 'sheet_name'=>'string'],
'Vtiful\Kernel\Excel::addSheet' => ['Vtiful\Kernel\Excel', 'sheet_name='=>'?string'],
'Vtiful\Kernel\Excel::autoFilter' => ['Vtiful\Kernel\Excel', 'range'=>'string'],
'Vtiful\Kernel\Excel::checkoutSheet' => ['Vtiful\Kernel\Excel', 'sheet_name'=>'string'],
'Vtiful\Kernel\Excel::close' => ['Vtiful\Kernel\Excel'],
'Vtiful\Kernel\Excel::columnIndexFromString' => ['int', 'index'=>'string'],
'Vtiful\Kernel\Excel::constMemory' => ['Vtiful\Kernel\Excel', 'file_name'=>'string', 'sheet_name='=>'?string'],
'Vtiful\Kernel\Excel::data' => ['Vtiful\Kernel\Excel', 'data'=>'array'],
'Vtiful\Kernel\Excel::defaultFormat' => ['Vtiful\Kernel\Excel', 'format_handle'=>'resource'],
'Vtiful\Kernel\Excel::existSheet' => ['bool', 'sheet_name'=>'string'],
'Vtiful\Kernel\Excel::fileName' => ['Vtiful\Kernel\Excel', 'file_name'=>'string', 'sheet_name='=>'?string'],
'Vtiful\Kernel\Excel::freezePanes' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int'],
'Vtiful\Kernel\Excel::getHandle' => ['resource'],
'Vtiful\Kernel\Excel::getSheetData' => ['array|false'],
'Vtiful\Kernel\Excel::gridline' => ['Vtiful\Kernel\Excel', 'option='=>'int'],
'Vtiful\Kernel\Excel::header' => ['Vtiful\Kernel\Excel', 'header'=>'array', 'format_handle='=>'?resource'],
'Vtiful\Kernel\Excel::insertChart' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'chart_resource'=>'resource'],
'Vtiful\Kernel\Excel::insertComment' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'comment'=>'string'],
'Vtiful\Kernel\Excel::insertDate' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'timestamp'=>'int', 'format='=>'?string', 'format_handle='=>'?resource'],
'Vtiful\Kernel\Excel::insertFormula' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'formula'=>'string', 'format_handle='=>'?resource'],
'Vtiful\Kernel\Excel::insertImage' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'image'=>'string', 'width='=>'?float', 'height='=>'?float'],
'Vtiful\Kernel\Excel::insertText' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'data'=>'int|string|double', 'format='=>'?string', 'format_handle='=>'?resource'],
'Vtiful\Kernel\Excel::insertUrl' => ['Vtiful\Kernel\Excel', 'row'=>'int', 'column'=>'int', 'url'=>'string', 'text='=>'?string', 'tool_tip='=>'?string', 'format='=>'?resource'],
'Vtiful\Kernel\Excel::mergeCells' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'data'=>'string', 'format_handle='=>'?resource'],
'Vtiful\Kernel\Excel::nextCellCallback' => ['void', 'fci'=>'callable(int,int,mixed)', 'sheet_name='=>'?string'],
'Vtiful\Kernel\Excel::nextRow' => ['array|false', 'zv_type_t='=>'?array'],
'Vtiful\Kernel\Excel::openFile' => ['Vtiful\Kernel\Excel', 'zs_file_name'=>'string'],
'Vtiful\Kernel\Excel::openSheet' => ['Vtiful\Kernel\Excel', 'zs_sheet_name='=>'?string', 'zl_flag='=>'?int'],
'Vtiful\Kernel\Excel::output' => ['string'],
'Vtiful\Kernel\Excel::protection' => ['Vtiful\Kernel\Excel', 'password='=>'?string'],
'Vtiful\Kernel\Excel::putCSV' => ['bool', 'fp'=>'resource', 'delimiter_str='=>'?string', 'enclosure_str='=>'?string', 'escape_str='=>'?string'],
'Vtiful\Kernel\Excel::putCSVCallback' => ['bool', 'callback'=>'callable(array):array', 'fp'=>'resource', 'delimiter_str='=>'?string', 'enclosure_str='=>'?string', 'escape_str='=>'?string'],
'Vtiful\Kernel\Excel::setColumn' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'width'=>'float', 'format_handle='=>'?resource'],
'Vtiful\Kernel\Excel::setCurrentSheetHide' => ['Vtiful\Kernel\Excel'],
'Vtiful\Kernel\Excel::setCurrentSheetIsFirst' => ['Vtiful\Kernel\Excel'],
'Vtiful\Kernel\Excel::setGlobalType' => ['Vtiful\Kernel\Excel', 'zv_type_t'=>'int'],
'Vtiful\Kernel\Excel::setLandscape' => ['Vtiful\Kernel\Excel'],
'Vtiful\Kernel\Excel::setMargins' => ['Vtiful\Kernel\Excel', 'left='=>'?float', 'right='=>'?float', 'top='=>'?float', 'bottom='=>'?float'],
'Vtiful\Kernel\Excel::setPaper' => ['Vtiful\Kernel\Excel', 'paper'=>'int'],
'Vtiful\Kernel\Excel::setPortrait' => ['Vtiful\Kernel\Excel'],
'Vtiful\Kernel\Excel::setRow' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'height'=>'float', 'format_handle='=>'?resource'],
'Vtiful\Kernel\Excel::setSkipRows' => ['Vtiful\Kernel\Excel', 'zv_skip_t'=>'int'],
'Vtiful\Kernel\Excel::setType' => ['Vtiful\Kernel\Excel', 'zv_type_t'=>'array'],
'Vtiful\Kernel\Excel::sheetList' => ['array'],
'Vtiful\Kernel\Excel::showComment' => ['Vtiful\Kernel\Excel'],
'Vtiful\Kernel\Excel::stringFromColumnIndex' => ['string', 'index'=>'int'],
'Vtiful\Kernel\Excel::timestampFromDateDouble' => ['int', 'index'=>'?float'],
'Vtiful\Kernel\Excel::validation' => ['Vtiful\Kernel\Excel', 'range'=>'string', 'validation_resource'=>'resource'],
'Vtiful\Kernel\Excel::zoom' => ['Vtiful\Kernel\Excel', 'scale'=>'int'],
'Vtiful\Kernel\Format::__construct' => ['void', 'handle'=>'resource'],
'Vtiful\Kernel\Format::align' => ['Vtiful\Kernel\Format', '...style'=>'int'],
'Vtiful\Kernel\Format::background' => ['Vtiful\Kernel\Format', 'color'=>'int', 'pattern='=>'int'],
'Vtiful\Kernel\Format::bold' => ['Vtiful\Kernel\Format'],
'Vtiful\Kernel\Format::border' => ['Vtiful\Kernel\Format', 'style'=>'int'],
'Vtiful\Kernel\Format::font' => ['Vtiful\Kernel\Format', 'font'=>'string'],
'Vtiful\Kernel\Format::fontColor' => ['Vtiful\Kernel\Format', 'color'=>'int'],
'Vtiful\Kernel\Format::fontSize' => ['Vtiful\Kernel\Format', 'size'=>'float'],
'Vtiful\Kernel\Format::italic' => ['Vtiful\Kernel\Format'],
'Vtiful\Kernel\Format::number' => ['Vtiful\Kernel\Format', 'format'=>'string'],
'Vtiful\Kernel\Format::strikeout' => ['Vtiful\Kernel\Format'],
'Vtiful\Kernel\Format::toResource' => ['resource'],
'Vtiful\Kernel\Format::underline' => ['Vtiful\Kernel\Format', 'style'=>'int'],
'Vtiful\Kernel\Format::unlocked' => ['Vtiful\Kernel\Format'],
'Vtiful\Kernel\Format::wrap' => ['Vtiful\Kernel\Format'],
'Vtiful\Kernel\Validation::__construct' => ['void'],
'Vtiful\Kernel\Validation::criteriaType' => ['?Vtiful\Kernel\Validation', 'type'=>'int'],
'Vtiful\Kernel\Validation::maximumFormula' => ['?Vtiful\Kernel\Validation', 'maximum_formula'=>'string'],
'Vtiful\Kernel\Validation::maximumNumber' => ['?Vtiful\Kernel\Validation', 'maximum_number'=>'float'],
'Vtiful\Kernel\Validation::minimumFormula' => ['?Vtiful\Kernel\Validation', 'minimum_formula'=>'string'],
'Vtiful\Kernel\Validation::minimumNumber' => ['?Vtiful\Kernel\Validation', 'minimum_number'=>'float'],
'Vtiful\Kernel\Validation::toResource' => ['resource'],
'Vtiful\Kernel\Validation::validationType' => ['?Vtiful\Kernel\Validation', 'type'=>'int'],
'Vtiful\Kernel\Validation::valueList' => ['?Vtiful\Kernel\Validation', 'value_list'=>'array'],
'Vtiful\Kernel\Validation::valueNumber' => ['?Vtiful\Kernel\Validation', 'value_number'=>'int'],
'w32api_deftype' => ['bool', 'typename'=>'string', 'member1_type'=>'string', 'member1_name'=>'string', '...args='=>'string'],
'w32api_init_dtype' => ['resource', 'typename'=>'string', 'value'=>'', '...args='=>''],
'w32api_invoke_function' => ['', 'funcname'=>'string', 'argument'=>'', '...args='=>''],
'w32api_register_function' => ['bool', 'library'=>'string', 'function_name'=>'string', 'return_type'=>'string'],
'w32api_set_call_method' => ['', 'method'=>'int'],
'wddx_add_vars' => ['bool', 'packet_id'=>'resource', 'var_names'=>'mixed', '...vars='=>'mixed'],
'wddx_deserialize' => ['mixed', 'packet'=>'string'],
'wddx_packet_end' => ['string', 'packet_id'=>'resource'],
'wddx_packet_start' => ['resource|false', 'comment='=>'string'],
'wddx_serialize_value' => ['string|false', 'value'=>'mixed', 'comment='=>'string'],
'wddx_serialize_vars' => ['string|false', 'var_name'=>'mixed', '...vars='=>'mixed'],
'WeakMap::__construct' => ['void'],
'WeakMap::count' => ['int'],
'WeakMap::current' => ['mixed'],
'WeakMap::key' => ['object'],
'WeakMap::next' => ['void'],
'WeakMap::offsetExists' => ['bool', 'object'=>'object'],
'WeakMap::offsetGet' => ['mixed', 'object'=>'object'],
'WeakMap::offsetSet' => ['void', 'object'=>'object', 'value'=>'mixed'],
'WeakMap::offsetUnset' => ['void', 'object'=>'object'],
'WeakMap::rewind' => ['void'],
'WeakMap::valid' => ['bool'],
'Weakref::acquire' => ['bool'],
'Weakref::get' => ['object'],
'Weakref::release' => ['bool'],
'Weakref::valid' => ['bool'],
'webObj::convertToString' => ['string'],
'webObj::free' => ['void'],
'webObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''],
'webObj::updateFromString' => ['int', 'snippet'=>'string'],
'win32_continue_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
'win32_create_service' => ['int|false', 'details'=>'array', 'machine='=>'string'],
'win32_delete_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
'win32_get_last_control_message' => ['int'],
'win32_pause_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
'win32_ps_list_procs' => ['array'],
'win32_ps_stat_mem' => ['array'],
'win32_ps_stat_proc' => ['array', 'pid='=>'int'],
'win32_query_service_status' => ['array|false|int', 'servicename'=>'string', 'machine='=>'string'],
'win32_send_custom_control' => ['int', 'servicename'=>'string', 'control'=>'int', 'machine='=>'string'],
'win32_set_service_exit_code' => ['int', 'exitCode='=>'int'],
'win32_set_service_exit_mode' => ['bool', 'gracefulMode='=>'bool'],
'win32_set_service_status' => ['bool|int', 'status'=>'int', 'checkpoint='=>'int'],
'win32_start_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
'win32_start_service_ctrl_dispatcher' => ['bool|int', 'name'=>'string'],
'win32_stop_service' => ['int|false', 'servicename'=>'string', 'machine='=>'string'],
'wincache_fcache_fileinfo' => ['array|false', 'summaryonly='=>'bool'],
'wincache_fcache_meminfo' => ['array|false'],
'wincache_lock' => ['bool', 'key'=>'string', 'isglobal='=>'bool'],
'wincache_ocache_fileinfo' => ['array|false', 'summaryonly='=>'bool'],
'wincache_ocache_meminfo' => ['array|false'],
'wincache_refresh_if_changed' => ['bool', 'files='=>'array'],
'wincache_rplist_fileinfo' => ['array|false', 'summaryonly='=>'bool'],
'wincache_rplist_meminfo' => ['array|false'],
'wincache_scache_info' => ['array|false', 'summaryonly='=>'bool'],
'wincache_scache_meminfo' => ['array|false'],
'wincache_ucache_add' => ['bool', 'key'=>'string', 'value'=>'mixed', 'ttl='=>'int'],
'wincache_ucache_add\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
'wincache_ucache_cas' => ['bool', 'key'=>'string', 'old_value'=>'int', 'new_value'=>'int'],
'wincache_ucache_clear' => ['bool'],
'wincache_ucache_dec' => ['int|false', 'key'=>'string', 'dec_by='=>'int', 'success='=>'bool'],
'wincache_ucache_delete' => ['bool', 'key'=>'mixed'],
'wincache_ucache_exists' => ['bool', 'key'=>'string'],
'wincache_ucache_get' => ['mixed', 'key'=>'mixed', '&w_success='=>'bool'],
'wincache_ucache_inc' => ['int|false', 'key'=>'string', 'inc_by='=>'int', 'success='=>'bool'],
'wincache_ucache_info' => ['array|false', 'summaryonly='=>'bool', 'key='=>'string'],
'wincache_ucache_meminfo' => ['array|false'],
'wincache_ucache_set' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int'],
'wincache_ucache_set\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'],
'wincache_unlock' => ['bool', 'key'=>'string'],
'wkhtmltox\image\converter::convert' => ['?string'],
'wkhtmltox\image\converter::getVersion' => ['string'],
'wkhtmltox\pdf\converter::add' => ['void', 'object'=>'wkhtmltox\PDF\Object'],
'wkhtmltox\pdf\converter::convert' => ['?string'],
'wkhtmltox\pdf\converter::getVersion' => ['string'],
'wordwrap' => ['string', 'string'=>'string', 'width='=>'int', 'break='=>'string', 'cut_long_words='=>'bool'],
'Worker::__construct' => ['void'],
'Worker::addRef' => ['void'],
'Worker::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'],
'Worker::collect' => ['int', 'collector='=>'Callable'],
'Worker::count' => ['int'],
'Worker::delRef' => ['void'],
'Worker::detach' => ['void'],
'Worker::extend' => ['bool', 'class'=>'string'],
'Worker::getCreatorId' => ['int'],
'Worker::getCurrentThread' => ['Thread'],
'Worker::getCurrentThreadId' => ['int'],
'Worker::getRefCount' => ['int'],
'Worker::getStacked' => ['int'],
'Worker::getTerminationInfo' => ['array'],
'Worker::getThreadId' => ['int'],
'Worker::globally' => ['mixed'],
'Worker::isGarbage' => ['bool'],
'Worker::isJoined' => ['bool'],
'Worker::isRunning' => ['bool'],
'Worker::isShutdown' => ['bool'],
'Worker::isStarted' => ['bool'],
'Worker::isTerminated' => ['bool'],
'Worker::isWaiting' => ['bool'],
'Worker::isWorking' => ['bool'],
'Worker::join' => ['bool'],
'Worker::kill' => ['bool'],
'Worker::lock' => ['bool'],
'Worker::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'],
'Worker::notify' => ['bool'],
'Worker::notifyOne' => ['bool'],
'Worker::offsetExists' => ['bool', 'offset'=>'mixed'],
'Worker::offsetGet' => ['mixed', 'offset'=>'mixed'],
'Worker::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'],
'Worker::offsetUnset' => ['void', 'offset'=>'mixed'],
'Worker::pop' => ['bool'],
'Worker::run' => ['void'],
'Worker::setGarbage' => ['void'],
'Worker::shift' => ['bool'],
'Worker::shutdown' => ['bool'],
'Worker::stack' => ['int', '&rw_work'=>'Threaded'],
'Worker::start' => ['bool', 'options='=>'int'],
'Worker::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'],
'Worker::unlock' => ['bool'],
'Worker::unstack' => ['int', '&rw_work='=>'Threaded'],
'Worker::wait' => ['bool', 'timeout='=>'int'],
'xattr_get' => ['string', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'],
'xattr_list' => ['array', 'filename'=>'string', 'flags='=>'int'],
'xattr_remove' => ['bool', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'],
'xattr_set' => ['bool', 'filename'=>'string', 'name'=>'string', 'value'=>'string', 'flags='=>'int'],
'xattr_supported' => ['bool', 'filename'=>'string', 'flags='=>'int'],
'xcache_asm' => ['string', 'filename'=>'string'],
'xcache_clear_cache' => ['void', 'type'=>'int', 'id='=>'int'],
'xcache_coredump' => ['string', 'op_type'=>'int'],
'xcache_count' => ['int', 'type'=>'int'],
'xcache_coverager_decode' => ['array', 'data'=>'string'],
'xcache_coverager_get' => ['array', 'clean='=>'bool'],
'xcache_coverager_start' => ['void', 'clean='=>'bool'],
'xcache_coverager_stop' => ['void', 'clean='=>'bool'],
'xcache_dasm_file' => ['string', 'filename'=>'string'],
'xcache_dasm_string' => ['string', 'code'=>'string'],
'xcache_dec' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'],
'xcache_decode' => ['bool', 'filename'=>'string'],
'xcache_encode' => ['string', 'filename'=>'string'],
'xcache_get' => ['mixed', 'name'=>'string'],
'xcache_get_data_type' => ['string', 'type'=>'int'],
'xcache_get_op_spec' => ['string', 'op_type'=>'int'],
'xcache_get_op_type' => ['string', 'op_type'=>'int'],
'xcache_get_opcode' => ['string', 'opcode'=>'int'],
'xcache_get_opcode_spec' => ['string', 'opcode'=>'int'],
'xcache_inc' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'],
'xcache_info' => ['array', 'type'=>'int', 'id'=>'int'],
'xcache_is_autoglobal' => ['string', 'name'=>'string'],
'xcache_isset' => ['bool', 'name'=>'string'],
'xcache_list' => ['array', 'type'=>'int', 'id'=>'int'],
'xcache_set' => ['bool', 'name'=>'string', 'value'=>'mixed', 'ttl='=>'int'],
'xcache_unset' => ['bool', 'name'=>'string'],
'xcache_unset_by_prefix' => ['bool', 'prefix'=>'string'],
'Xcom::__construct' => ['void', 'fabric_url='=>'string', 'fabric_token='=>'string', 'capability_token='=>'string'],
'Xcom::decode' => ['object', 'avro_msg'=>'string', 'json_schema'=>'string'],
'Xcom::encode' => ['string', 'data'=>'stdClass', 'avro_schema'=>'string'],
'Xcom::getDebugOutput' => ['string'],
'Xcom::getLastResponse' => ['string'],
'Xcom::getLastResponseInfo' => ['array'],
'Xcom::getOnboardingURL' => ['string', 'capability_name'=>'string', 'agreement_url'=>'string'],
'Xcom::send' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'],
'Xcom::sendAsync' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'],
'xdebug_break' => ['bool'],
'xdebug_call_class' => ['string', 'depth='=>'int'],
'xdebug_call_file' => ['string', 'depth='=>'int'],
'xdebug_call_function' => ['string', 'depth='=>'int'],
'xdebug_call_line' => ['int', 'depth='=>'int'],
'xdebug_clear_aggr_profiling_data' => ['bool'],
'xdebug_code_coverage_started' => ['bool'],
'xdebug_debug_zval' => ['void', '...varName'=>'string'],
'xdebug_debug_zval_stdout' => ['void', '...varName'=>'string'],
'xdebug_disable' => ['void'],
'xdebug_dump_aggr_profiling_data' => ['bool'],
'xdebug_dump_superglobals' => ['void'],
'xdebug_enable' => ['void'],
'xdebug_get_code_coverage' => ['array'],
'xdebug_get_collected_errors' => ['string', 'clean='=>'bool'],
'xdebug_get_declared_vars' => ['array'],
'xdebug_get_formatted_function_stack' => [''],
'xdebug_get_function_count' => ['int'],
'xdebug_get_function_stack' => ['array', 'message='=>'string', 'options='=>'int'],
'xdebug_get_headers' => ['array'],
'xdebug_get_monitored_functions' => ['array'],
'xdebug_get_profiler_filename' => ['string|false'],
'xdebug_get_stack_depth' => ['int'],
'xdebug_get_tracefile_name' => ['string'],
'xdebug_info' => ['mixed', 'category='=>'string'],
'xdebug_is_debugger_active' => ['bool'],
'xdebug_is_enabled' => ['bool'],
'xdebug_memory_usage' => ['int'],
'xdebug_peak_memory_usage' => ['int'],
'xdebug_print_function_stack' => ['array', 'message='=>'string', 'options='=>'int'],
'xdebug_set_filter' => ['void', 'group'=>'int', 'list_type'=>'int', 'configuration'=>'array'],
'xdebug_start_code_coverage' => ['void', 'options='=>'int'],
'xdebug_start_error_collection' => ['void'],
'xdebug_start_function_monitor' => ['void', 'list_of_functions_to_monitor'=>'string[]'],
'xdebug_start_trace' => ['void', 'trace_file'=>'', 'options='=>'int|mixed'],
'xdebug_stop_code_coverage' => ['void', 'cleanup='=>'bool'],
'xdebug_stop_error_collection' => ['void'],
'xdebug_stop_function_monitor' => ['void'],
'xdebug_stop_trace' => ['void'],
'xdebug_time_index' => ['float'],
'xdebug_var_dump' => ['void', '...var'=>''],
'xdiff_file_bdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'],
'xdiff_file_bdiff_size' => ['int', 'file'=>'string'],
'xdiff_file_bpatch' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'],
'xdiff_file_diff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string', 'context='=>'int', 'minimal='=>'bool'],
'xdiff_file_diff_binary' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'],
'xdiff_file_merge3' => ['mixed', 'old_file'=>'string', 'new_file1'=>'string', 'new_file2'=>'string', 'dest'=>'string'],
'xdiff_file_patch' => ['mixed', 'file'=>'string', 'patch'=>'string', 'dest'=>'string', 'flags='=>'int'],
'xdiff_file_patch_binary' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'],
'xdiff_file_rabdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'],
'xdiff_string_bdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'],
'xdiff_string_bdiff_size' => ['int', 'patch'=>'string'],
'xdiff_string_bpatch' => ['string', 'string'=>'string', 'patch'=>'string'],
'xdiff_string_diff' => ['string', 'old_data'=>'string', 'new_data'=>'string', 'context='=>'int', 'minimal='=>'bool'],
'xdiff_string_diff_binary' => ['string', 'old_data'=>'string', 'new_data'=>'string'],
'xdiff_string_merge3' => ['mixed', 'old_data'=>'string', 'new_data1'=>'string', 'new_data2'=>'string', 'error='=>'string'],
'xdiff_string_patch' => ['string', 'string'=>'string', 'patch'=>'string', 'flags='=>'int', '&w_error='=>'string'],
'xdiff_string_patch_binary' => ['string', 'string'=>'string', 'patch'=>'string'],
'xdiff_string_rabdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'],
'xhprof_disable' => ['array'],
'xhprof_enable' => ['void', 'flags='=>'int', 'options='=>'array'],
'xhprof_sample_disable' => ['array'],
'xhprof_sample_enable' => ['void'],
'xlswriter_get_author' => ['string'],
'xlswriter_get_version' => ['string'],
'xml_error_string' => ['?string', 'error_code'=>'int'],
'xml_get_current_byte_index' => ['int', 'parser'=>'XMLParser'],
'xml_get_current_column_number' => ['int', 'parser'=>'XMLParser'],
'xml_get_current_line_number' => ['int', 'parser'=>'XMLParser'],
'xml_get_error_code' => ['int', 'parser'=>'XMLParser'],
'xml_parse' => ['int', 'parser'=>'XMLParser', 'data'=>'string', 'is_final='=>'bool'],
'xml_parse_into_struct' => ['int', 'parser'=>'XMLParser', 'data'=>'string', '&w_values'=>'array', '&w_index='=>'array'],
'xml_parser_create' => ['XMLParser', 'encoding='=>'?string'],
'xml_parser_create_ns' => ['XMLParser', 'encoding='=>'?string', 'separator='=>'string'],
'xml_parser_free' => ['bool', 'parser'=>'XMLParser'],
'xml_parser_get_option' => ['string', 'parser'=>'XMLParser', 'option'=>'int'],
'xml_parser_set_option' => ['bool', 'parser'=>'XMLParser', 'option'=>'int', 'value'=>'mixed'],
'xml_set_character_data_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'xml_set_default_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'xml_set_element_handler' => ['bool', 'parser'=>'XMLParser', 'start_handler'=>'callable', 'end_handler'=>'callable'],
'xml_set_end_namespace_decl_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'xml_set_external_entity_ref_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'xml_set_notation_decl_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'xml_set_object' => ['bool', 'parser'=>'XMLParser', 'object'=>'object'],
'xml_set_processing_instruction_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'xml_set_start_namespace_decl_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'xml_set_unparsed_entity_decl_handler' => ['bool', 'parser'=>'XMLParser', 'handler'=>'callable'],
'XMLDiff\Base::__construct' => ['void', 'nsname'=>'string'],
'XMLDiff\Base::diff' => ['mixed', 'from'=>'mixed', 'to'=>'mixed'],
'XMLDiff\Base::merge' => ['mixed', 'src'=>'mixed', 'diff'=>'mixed'],
'XMLDiff\DOM::diff' => ['DOMDocument', 'from'=>'DOMDocument', 'to'=>'DOMDocument'],
'XMLDiff\DOM::merge' => ['DOMDocument', 'src'=>'DOMDocument', 'diff'=>'DOMDocument'],
'XMLDiff\File::diff' => ['string', 'from'=>'string', 'to'=>'string'],
'XMLDiff\File::merge' => ['string', 'src'=>'string', 'diff'=>'string'],
'XMLDiff\Memory::diff' => ['string', 'from'=>'string', 'to'=>'string'],
'XMLDiff\Memory::merge' => ['string', 'src'=>'string', 'diff'=>'string'],
'XMLReader::close' => ['bool'],
'XMLReader::expand' => ['DOMNode|false', 'baseNode='=>'?DOMNode'],
'XMLReader::getAttribute' => ['?string', 'name'=>'string'],
'XMLReader::getAttributeNo' => ['?string', 'index'=>'int'],
'XMLReader::getAttributeNs' => ['?string', 'name'=>'string', 'namespaceuri'=>'string'],
'XMLReader::getParserProperty' => ['bool', 'property'=>'int'],
'XMLReader::isValid' => ['bool'],
'XMLReader::lookupNamespace' => ['?string', 'prefix'=>'string'],
'XMLReader::moveToAttribute' => ['bool', 'name'=>'string'],
'XMLReader::moveToAttributeNo' => ['bool', 'index'=>'int'],
'XMLReader::moveToAttributeNs' => ['bool', 'localname'=>'string', 'namespaceuri'=>'string'],
'XMLReader::moveToElement' => ['bool'],
'XMLReader::moveToFirstAttribute' => ['bool'],
'XMLReader::moveToNextAttribute' => ['bool'],
'XMLReader::next' => ['bool', 'localname='=>'string'],
'XMLReader::open' => ['bool', 'uri'=>'string', 'encoding='=>'?string', 'options='=>'int'],
'XMLReader::read' => ['bool'],
'XMLReader::readInnerXML' => ['string'],
'XMLReader::readOuterXML' => ['string'],
'XMLReader::readString' => ['string'],
'XMLReader::setParserProperty' => ['bool', 'property'=>'int', 'value'=>'bool'],
'XMLReader::setRelaxNGSchema' => ['bool', 'filename'=>'?string'],
'XMLReader::setRelaxNGSchemaSource' => ['bool', 'source'=>'?string'],
'XMLReader::setSchema' => ['bool', 'filename'=>'?string'],
'XMLReader::XML' => ['bool', 'source'=>'string', 'encoding='=>'?string', 'options='=>'int'],
'xmlrpc_decode' => ['mixed', 'xml'=>'string', 'encoding='=>'string'],
'xmlrpc_decode_request' => ['?array', 'xml'=>'string', '&w_method'=>'string', 'encoding='=>'string'],
'xmlrpc_encode' => ['string', 'value'=>'mixed'],
'xmlrpc_encode_request' => ['string', 'method'=>'string', 'params'=>'mixed', 'output_options='=>'array'],
'xmlrpc_get_type' => ['string', 'value'=>'mixed'],
'xmlrpc_is_fault' => ['bool', 'arg'=>'array'],
'xmlrpc_parse_method_descriptions' => ['array', 'xml'=>'string'],
'xmlrpc_server_add_introspection_data' => ['int', 'server'=>'resource', 'desc'=>'array'],
'xmlrpc_server_call_method' => ['string', 'server'=>'resource', 'xml'=>'string', 'user_data'=>'mixed', 'output_options='=>'array'],
'xmlrpc_server_create' => ['resource'],
'xmlrpc_server_destroy' => ['int', 'server'=>'resource'],
'xmlrpc_server_register_introspection_callback' => ['bool', 'server'=>'resource', 'function'=>'string'],
'xmlrpc_server_register_method' => ['bool', 'server'=>'resource', 'method_name'=>'string', 'function'=>'string'],
'xmlrpc_set_type' => ['bool', '&rw_value'=>'string|DateTime', 'type'=>'string'],
'XMLWriter::endAttribute' => ['bool'],
'XMLWriter::endCdata' => ['bool'],
'XMLWriter::endComment' => ['bool'],
'XMLWriter::endDocument' => ['bool'],
'XMLWriter::endDtd' => ['bool'],
'XMLWriter::endDtdAttlist' => ['bool'],
'XMLWriter::endDtdElement' => ['bool'],
'XMLWriter::endDtdEntity' => ['bool'],
'XMLWriter::endElement' => ['bool'],
'XMLWriter::endPi' => ['bool'],
'XMLWriter::flush' => ['string|int', 'empty='=>'bool'],
'XMLWriter::fullEndElement' => ['bool'],
'XMLWriter::openMemory' => ['bool'],
'XMLWriter::openUri' => ['bool', 'uri'=>'string'],
'XMLWriter::outputMemory' => ['string', 'flush='=>'bool'],
'XMLWriter::setIndent' => ['bool', 'enable'=>'bool'],
'XMLWriter::setIndentString' => ['bool', 'indentation'=>'string'],
'XMLWriter::startAttribute' => ['bool', 'name'=>'string'],
'XMLWriter::startAttributeNs' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
'XMLWriter::startCdata' => ['bool'],
'XMLWriter::startComment' => ['bool'],
'XMLWriter::startDocument' => ['bool', 'version='=>'?string', 'encoding='=>'?string', 'standalone='=>'?string'],
'XMLWriter::startDtd' => ['bool', 'qualifiedName'=>'string', 'publicId='=>'?string', 'systemId='=>'?string'],
'XMLWriter::startDtdAttlist' => ['bool', 'name'=>'string'],
'XMLWriter::startDtdElement' => ['bool', 'qualifiedName'=>'string'],
'XMLWriter::startDtdEntity' => ['bool', 'name'=>'string', 'isParam'=>'bool'],
'XMLWriter::startElement' => ['bool', 'name'=>'string'],
'XMLWriter::startElementNs' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
'XMLWriter::startPi' => ['bool', 'target'=>'string'],
'XMLWriter::text' => ['bool', 'content'=>'string'],
'XMLWriter::writeAttribute' => ['bool', 'name'=>'string', 'value'=>'string'],
'XMLWriter::writeAttributeNs' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
'XMLWriter::writeCdata' => ['bool', 'content'=>'string'],
'XMLWriter::writeComment' => ['bool', 'content'=>'string'],
'XMLWriter::writeDtd' => ['bool', 'name'=>'string', 'publicId='=>'?string', 'systemId='=>'?string', 'content='=>'?string'],
'XMLWriter::writeDtdAttlist' => ['bool', 'name'=>'string', 'content'=>'string'],
'XMLWriter::writeDtdElement' => ['bool', 'name'=>'string', 'content'=>'string'],
'XMLWriter::writeDtdEntity' => ['bool', 'name'=>'string', 'content'=>'string', 'isParam='=>'bool', 'publicId='=>'?string', 'systemId='=>'?string', 'notationData='=>'?string'],
'XMLWriter::writeElement' => ['bool', 'name'=>'string', 'content='=>'?string'],
'XMLWriter::writeElementNs' => ['bool', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'content='=>'?string'],
'XMLWriter::writePi' => ['bool', 'target'=>'string', 'content'=>'string'],
'XMLWriter::writeRaw' => ['bool', 'content'=>'string'],
'xmlwriter_end_attribute' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_cdata' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_comment' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_document' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_dtd' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_dtd_attlist' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_dtd_element' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_dtd_entity' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_element' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_end_pi' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_flush' => ['string|int', 'writer'=>'XMLWriter', 'empty='=>'bool'],
'xmlwriter_full_end_element' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_open_memory' => ['XMLWriter|false'],
'xmlwriter_open_uri' => ['XMLWriter|false', 'uri'=>'string'],
'xmlwriter_output_memory' => ['string', 'writer'=>'XMLWriter', 'flush='=>'bool'],
'xmlwriter_set_indent' => ['bool', 'writer'=>'XMLWriter', 'enable'=>'bool'],
'xmlwriter_set_indent_string' => ['bool', 'writer'=>'XMLWriter', 'indentation'=>'string'],
'xmlwriter_start_attribute' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string'],
'xmlwriter_start_attribute_ns' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
'xmlwriter_start_cdata' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_start_comment' => ['bool', 'writer'=>'XMLWriter'],
'xmlwriter_start_document' => ['bool', 'writer'=>'XMLWriter', 'version='=>'?string', 'encoding='=>'?string', 'standalone='=>'?string'],
'xmlwriter_start_dtd' => ['bool', 'writer'=>'XMLWriter', 'qualifiedName'=>'string', 'publicId='=>'?string', 'systemId='=>'?string'],
'xmlwriter_start_dtd_attlist' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string'],
'xmlwriter_start_dtd_element' => ['bool', 'writer'=>'XMLWriter', 'qualifiedName'=>'string'],
'xmlwriter_start_dtd_entity' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'isParam'=>'bool'],
'xmlwriter_start_element' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string'],
'xmlwriter_start_element_ns' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string'],
'xmlwriter_start_pi' => ['bool', 'writer'=>'XMLWriter', 'target'=>'string'],
'xmlwriter_text' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
'xmlwriter_write_attribute' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'value'=>'string'],
'xmlwriter_write_attribute_ns' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'value'=>'string'],
'xmlwriter_write_cdata' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
'xmlwriter_write_comment' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
'xmlwriter_write_dtd' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'publicId='=>'?string', 'systemId='=>'?string', 'content='=>'?string'],
'xmlwriter_write_dtd_attlist' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content'=>'string'],
'xmlwriter_write_dtd_element' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content'=>'string'],
'xmlwriter_write_dtd_entity' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content'=>'string', 'isParam='=>'bool', 'publicId='=>'?string', 'systemId='=>'?string', 'notationData='=>'?string'],
'xmlwriter_write_element' => ['bool', 'writer'=>'XMLWriter', 'name'=>'string', 'content='=>'?string'],
'xmlwriter_write_element_ns' => ['bool', 'writer'=>'XMLWriter', 'prefix'=>'?string', 'name'=>'string', 'namespace'=>'?string', 'content='=>'?string'],
'xmlwriter_write_pi' => ['bool', 'writer'=>'XMLWriter', 'target'=>'string', 'content'=>'string'],
'xmlwriter_write_raw' => ['bool', 'writer'=>'XMLWriter', 'content'=>'string'],
'xpath_new_context' => ['XPathContext', 'dom_document'=>'DOMDocument'],
'xpath_register_ns' => ['bool', 'xpath_context'=>'xpathcontext', 'prefix'=>'string', 'uri'=>'string'],
'xpath_register_ns_auto' => ['bool', 'xpath_context'=>'xpathcontext', 'context_node='=>'object'],
'xptr_new_context' => ['XPathContext'],
'xsl_xsltprocessor_get_parameter' => ['string', 'namespace'=>'string', 'name'=>'string'],
'xsl_xsltprocessor_get_security_prefs' => ['int'],
'xsl_xsltprocessor_has_exslt_support' => ['bool'],
'xsl_xsltprocessor_register_php_functions' => ['', 'restrict'=>''],
'xsl_xsltprocessor_remove_parameter' => ['bool', 'namespace'=>'string', 'name'=>'string'],
'xsl_xsltprocessor_set_parameter' => ['bool', 'namespace'=>'string', 'name'=>'', 'value'=>'string'],
'xsl_xsltprocessor_set_profiling' => ['bool', 'filename'=>'string'],
'xsl_xsltprocessor_set_security_prefs' => ['int', 'securityprefs'=>'int'],
'xsl_xsltprocessor_transform_to_uri' => ['int', 'doc'=>'DOMDocument', 'uri'=>'string'],
'xsl_xsltprocessor_transform_to_xml' => ['string', 'doc'=>'DOMDocument'],
'xslt_backend_info' => ['string'],
'xslt_backend_name' => ['string'],
'xslt_backend_version' => ['string'],
'xslt_create' => ['resource'],
'xslt_errno' => ['int', 'xh'=>''],
'xslt_error' => ['string', 'xh'=>''],
'xslt_free' => ['', 'xh'=>''],
'xslt_getopt' => ['int', 'processor'=>''],
'xslt_process' => ['', 'xh'=>'', 'xmlcontainer'=>'string', 'xslcontainer'=>'string', 'resultcontainer='=>'string', 'arguments='=>'array', 'parameters='=>'array'],
'xslt_set_base' => ['', 'xh'=>'', 'uri'=>'string'],
'xslt_set_encoding' => ['', 'xh'=>'', 'encoding'=>'string'],
'xslt_set_error_handler' => ['', 'xh'=>'', 'handler'=>''],
'xslt_set_log' => ['', 'xh'=>'', 'log='=>''],
'xslt_set_object' => ['bool', 'processor'=>'', 'object'=>'object'],
'xslt_set_sax_handler' => ['', 'xh'=>'', 'handlers'=>'array'],
'xslt_set_sax_handlers' => ['', 'processor'=>'', 'handlers'=>'array'],
'xslt_set_scheme_handler' => ['', 'xh'=>'', 'handlers'=>'array'],
'xslt_set_scheme_handlers' => ['', 'xh'=>'', 'handlers'=>'array'],
'xslt_setopt' => ['', 'processor'=>'', 'newmask'=>'int'],
'XSLTProcessor::getParameter' => ['string|false', 'namespace'=>'string', 'name'=>'string'],
'XsltProcessor::getSecurityPrefs' => ['int'],
'XSLTProcessor::hasExsltSupport' => ['bool'],
'XSLTProcessor::importStylesheet' => ['bool', 'stylesheet'=>'object'],
'XSLTProcessor::registerPHPFunctions' => ['void', 'functions='=>'mixed'],
'XSLTProcessor::removeParameter' => ['bool', 'namespace'=>'string', 'name'=>'string'],
'XSLTProcessor::setParameter' => ['bool', 'namespace'=>'string', 'name'=>'string', 'value'=>'string'],
'XSLTProcessor::setParameter\'1' => ['bool', 'namespace'=>'string', 'options'=>'array'],
'XSLTProcessor::setProfiling' => ['bool', 'filename'=>'?string'],
'XsltProcessor::setSecurityPrefs' => ['int', 'preferences'=>'int'],
'XSLTProcessor::transformToDoc' => ['DOMDocument|false', 'document'=>'DOMNode'],
'XSLTProcessor::transformToURI' => ['int', 'document'=>'DOMDocument', 'uri'=>'string'],
'XSLTProcessor::transformToXML' => ['string|false', 'document'=>'DOMDocument'],
'yac::__construct' => ['void', 'prefix='=>'string'],
'yac::__get' => ['mixed', 'key'=>'string'],
'yac::__set' => ['mixed', 'key'=>'string', 'value'=>'mixed'],
'yac::delete' => ['bool', 'keys'=>'string|array', 'ttl='=>'int'],
'yac::dump' => ['mixed', 'num'=>'int'],
'yac::flush' => ['bool'],
'yac::get' => ['mixed', 'key'=>'string|array', 'cas='=>'int'],
'yac::info' => ['array'],
'Yaconf::get' => ['mixed', 'name'=>'string', 'default_value='=>'mixed'],
'Yaconf::has' => ['bool', 'name'=>'string'],
'Yaf\Action_Abstract::__clone' => ['void'],
'Yaf\Action_Abstract::__construct' => ['void', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract', 'view'=>'Yaf\View_Interface', 'invokeArgs='=>'?array'],
'Yaf\Action_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'],
'Yaf\Action_Abstract::execute' => ['mixed'],
'Yaf\Action_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'],
'Yaf\Action_Abstract::getController' => ['Yaf\Controller_Abstract'],
'Yaf\Action_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'],
'Yaf\Action_Abstract::getInvokeArgs' => ['array'],
'Yaf\Action_Abstract::getModuleName' => ['string'],
'Yaf\Action_Abstract::getRequest' => ['Yaf\Request_Abstract'],
'Yaf\Action_Abstract::getResponse' => ['Yaf\Response_Abstract'],
'Yaf\Action_Abstract::getView' => ['Yaf\View_Interface'],
'Yaf\Action_Abstract::getViewpath' => ['string'],
'Yaf\Action_Abstract::init' => [''],
'Yaf\Action_Abstract::initView' => ['Yaf\Response_Abstract', 'options='=>'?array'],
'Yaf\Action_Abstract::redirect' => ['bool', 'url'=>'string'],
'Yaf\Action_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'],
'Yaf\Action_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'],
'Yaf\Application::__clone' => ['void'],
'Yaf\Application::__construct' => ['void', 'config'=>'array|string', 'envrion='=>'string'],
'Yaf\Application::__destruct' => ['void'],
'Yaf\Application::__sleep' => ['string[]'],
'Yaf\Application::__wakeup' => ['void'],
'Yaf\Application::app' => ['?Yaf\Application'],
'Yaf\Application::bootstrap' => ['Yaf\Application', 'bootstrap='=>'?Yaf\Bootstrap_Abstract'],
'Yaf\Application::clearLastError' => ['void'],
'Yaf\Application::environ' => ['string'],
'Yaf\Application::execute' => ['void', 'entry'=>'callable', '_='=>'string'],
'Yaf\Application::getAppDirectory' => ['string'],
'Yaf\Application::getConfig' => ['Yaf\Config_Abstract'],
'Yaf\Application::getDispatcher' => ['Yaf\Dispatcher'],
'Yaf\Application::getLastErrorMsg' => ['string'],
'Yaf\Application::getLastErrorNo' => ['int'],
'Yaf\Application::getModules' => ['array'],
'Yaf\Application::run' => ['void'],
'Yaf\Application::setAppDirectory' => ['Yaf\Application', 'directory'=>'string'],
'Yaf\Config\Ini::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'],
'Yaf\Config\Ini::__get' => ['', 'name='=>'mixed'],
'Yaf\Config\Ini::__isset' => ['', 'name'=>'string'],
'Yaf\Config\Ini::__set' => ['void', 'name'=>'', 'value'=>''],
'Yaf\Config\Ini::count' => ['int'],
'Yaf\Config\Ini::current' => ['mixed'],
'Yaf\Config\Ini::get' => ['mixed', 'name='=>'mixed'],
'Yaf\Config\Ini::key' => ['int|string'],
'Yaf\Config\Ini::next' => ['void'],
'Yaf\Config\Ini::offsetExists' => ['bool', 'name'=>'mixed'],
'Yaf\Config\Ini::offsetGet' => ['mixed', 'name'=>'mixed'],
'Yaf\Config\Ini::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
'Yaf\Config\Ini::offsetUnset' => ['void', 'name'=>'mixed'],
'Yaf\Config\Ini::readonly' => ['bool'],
'Yaf\Config\Ini::rewind' => ['void'],
'Yaf\Config\Ini::set' => ['Yaf\Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
'Yaf\Config\Ini::toArray' => ['array'],
'Yaf\Config\Ini::valid' => ['bool'],
'Yaf\Config\Simple::__construct' => ['void', 'array'=>'array', 'readonly='=>'string'],
'Yaf\Config\Simple::__get' => ['', 'name='=>'mixed'],
'Yaf\Config\Simple::__isset' => ['', 'name'=>'string'],
'Yaf\Config\Simple::__set' => ['void', 'name'=>'', 'value'=>''],
'Yaf\Config\Simple::count' => ['int'],
'Yaf\Config\Simple::current' => ['mixed'],
'Yaf\Config\Simple::get' => ['mixed', 'name='=>'mixed'],
'Yaf\Config\Simple::key' => ['int|string'],
'Yaf\Config\Simple::next' => ['void'],
'Yaf\Config\Simple::offsetExists' => ['bool', 'name'=>'mixed'],
'Yaf\Config\Simple::offsetGet' => ['mixed', 'name'=>'mixed'],
'Yaf\Config\Simple::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
'Yaf\Config\Simple::offsetUnset' => ['void', 'name'=>'mixed'],
'Yaf\Config\Simple::readonly' => ['bool'],
'Yaf\Config\Simple::rewind' => ['void'],
'Yaf\Config\Simple::set' => ['Yaf\Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
'Yaf\Config\Simple::toArray' => ['array'],
'Yaf\Config\Simple::valid' => ['bool'],
'Yaf\Config_Abstract::__construct' => ['void'],
'Yaf\Config_Abstract::get' => ['mixed', 'name='=>'string'],
'Yaf\Config_Abstract::readonly' => ['bool'],
'Yaf\Config_Abstract::set' => ['Yaf\Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
'Yaf\Config_Abstract::toArray' => ['array'],
'Yaf\Controller_Abstract::__clone' => ['void'],
'Yaf\Controller_Abstract::__construct' => ['void', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract', 'view'=>'Yaf\View_Interface', 'invokeArgs='=>'?array'],
'Yaf\Controller_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'],
'Yaf\Controller_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'],
'Yaf\Controller_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'],
'Yaf\Controller_Abstract::getInvokeArgs' => ['array'],
'Yaf\Controller_Abstract::getModuleName' => ['string'],
'Yaf\Controller_Abstract::getRequest' => ['Yaf\Request_Abstract'],
'Yaf\Controller_Abstract::getResponse' => ['Yaf\Response_Abstract'],
'Yaf\Controller_Abstract::getView' => ['Yaf\View_Interface'],
'Yaf\Controller_Abstract::getViewpath' => ['string'],
'Yaf\Controller_Abstract::init' => [''],
'Yaf\Controller_Abstract::initView' => ['Yaf\Response_Abstract', 'options='=>'?array'],
'Yaf\Controller_Abstract::redirect' => ['bool', 'url'=>'string'],
'Yaf\Controller_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'],
'Yaf\Controller_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'],
'Yaf\Dispatcher::__clone' => ['void'],
'Yaf\Dispatcher::__construct' => ['void'],
'Yaf\Dispatcher::__sleep' => ['list<string>'],
'Yaf\Dispatcher::__wakeup' => ['void'],
'Yaf\Dispatcher::autoRender' => ['Yaf\Dispatcher', 'flag='=>'bool'],
'Yaf\Dispatcher::catchException' => ['Yaf\Dispatcher', 'flag='=>'bool'],
'Yaf\Dispatcher::disableView' => ['bool'],
'Yaf\Dispatcher::dispatch' => ['Yaf\Response_Abstract', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Dispatcher::enableView' => ['Yaf\Dispatcher'],
'Yaf\Dispatcher::flushInstantly' => ['Yaf\Dispatcher', 'flag='=>'bool'],
'Yaf\Dispatcher::getApplication' => ['Yaf\Application'],
'Yaf\Dispatcher::getInstance' => ['Yaf\Dispatcher'],
'Yaf\Dispatcher::getRequest' => ['Yaf\Request_Abstract'],
'Yaf\Dispatcher::getRouter' => ['Yaf\Router'],
'Yaf\Dispatcher::initView' => ['Yaf\View_Interface', 'templates_dir'=>'string', 'options='=>'?array'],
'Yaf\Dispatcher::registerPlugin' => ['Yaf\Dispatcher', 'plugin'=>'Yaf\Plugin_Abstract'],
'Yaf\Dispatcher::returnResponse' => ['Yaf\Dispatcher', 'flag'=>'bool'],
'Yaf\Dispatcher::setDefaultAction' => ['Yaf\Dispatcher', 'action'=>'string'],
'Yaf\Dispatcher::setDefaultController' => ['Yaf\Dispatcher', 'controller'=>'string'],
'Yaf\Dispatcher::setDefaultModule' => ['Yaf\Dispatcher', 'module'=>'string'],
'Yaf\Dispatcher::setErrorHandler' => ['Yaf\Dispatcher', 'callback'=>'callable', 'error_types'=>'int'],
'Yaf\Dispatcher::setRequest' => ['Yaf\Dispatcher', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Dispatcher::setView' => ['Yaf\Dispatcher', 'view'=>'Yaf\View_Interface'],
'Yaf\Dispatcher::throwException' => ['Yaf\Dispatcher', 'flag='=>'bool'],
'Yaf\Loader::__clone' => ['void'],
'Yaf\Loader::__construct' => ['void'],
'Yaf\Loader::__sleep' => ['list<string>'],
'Yaf\Loader::__wakeup' => ['void'],
'Yaf\Loader::autoload' => ['bool', 'class_name'=>'string'],
'Yaf\Loader::clearLocalNamespace' => [''],
'Yaf\Loader::getInstance' => ['Yaf\Loader', 'local_library_path='=>'string', 'global_library_path='=>'string'],
'Yaf\Loader::getLibraryPath' => ['string', 'is_global='=>'bool'],
'Yaf\Loader::getLocalNamespace' => ['string'],
'Yaf\Loader::import' => ['bool', 'file'=>'string'],
'Yaf\Loader::isLocalName' => ['bool', 'class_name'=>'string'],
'Yaf\Loader::registerLocalNamespace' => ['bool', 'name_prefix'=>'string|string[]'],
'Yaf\Loader::setLibraryPath' => ['Yaf\Loader', 'directory'=>'string', 'global='=>'bool'],
'Yaf\Plugin_Abstract::dispatchLoopShutdown' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
'Yaf\Plugin_Abstract::dispatchLoopStartup' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
'Yaf\Plugin_Abstract::postDispatch' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
'Yaf\Plugin_Abstract::preDispatch' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
'Yaf\Plugin_Abstract::preResponse' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
'Yaf\Plugin_Abstract::routerShutdown' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
'Yaf\Plugin_Abstract::routerStartup' => ['bool', 'request'=>'Yaf\Request_Abstract', 'response'=>'Yaf\Response_Abstract'],
'Yaf\Registry::__clone' => ['void'],
'Yaf\Registry::__construct' => ['void'],
'Yaf\Registry::del' => ['bool|void', 'name'=>'string'],
'Yaf\Registry::get' => ['mixed', 'name'=>'string'],
'Yaf\Registry::has' => ['bool', 'name'=>'string'],
'Yaf\Registry::set' => ['bool', 'name'=>'string', 'value'=>'mixed'],
'Yaf\Request\Http::__clone' => ['void'],
'Yaf\Request\Http::__construct' => ['void', 'request_uri'=>'string', 'base_uri'=>'string'],
'Yaf\Request\Http::get' => ['mixed', 'name'=>'string', 'default='=>'string'],
'Yaf\Request\Http::getActionName' => ['string'],
'Yaf\Request\Http::getBaseUri' => ['string'],
'Yaf\Request\Http::getControllerName' => ['string'],
'Yaf\Request\Http::getCookie' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::getException' => ['Yaf\Exception'],
'Yaf\Request\Http::getFiles' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::getLanguage' => ['string'],
'Yaf\Request\Http::getMethod' => ['string'],
'Yaf\Request\Http::getModuleName' => ['string'],
'Yaf\Request\Http::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::getParams' => ['array'],
'Yaf\Request\Http::getPost' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::getQuery' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::getRequest' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::getRequestUri' => ['string'],
'Yaf\Request\Http::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Http::isCli' => ['bool'],
'Yaf\Request\Http::isDispatched' => ['bool'],
'Yaf\Request\Http::isGet' => ['bool'],
'Yaf\Request\Http::isHead' => ['bool'],
'Yaf\Request\Http::isOptions' => ['bool'],
'Yaf\Request\Http::isPost' => ['bool'],
'Yaf\Request\Http::isPut' => ['bool'],
'Yaf\Request\Http::isRouted' => ['bool'],
'Yaf\Request\Http::isXmlHttpRequest' => ['bool'],
'Yaf\Request\Http::setActionName' => ['Yaf\Request_Abstract|bool', 'action'=>'string'],
'Yaf\Request\Http::setBaseUri' => ['bool', 'uri'=>'string'],
'Yaf\Request\Http::setControllerName' => ['Yaf\Request_Abstract|bool', 'controller'=>'string'],
'Yaf\Request\Http::setDispatched' => ['bool'],
'Yaf\Request\Http::setModuleName' => ['Yaf\Request_Abstract|bool', 'module'=>'string'],
'Yaf\Request\Http::setParam' => ['Yaf\Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
'Yaf\Request\Http::setRequestUri' => ['', 'uri'=>'string'],
'Yaf\Request\Http::setRouted' => ['Yaf\Request_Abstract|bool'],
'Yaf\Request\Simple::__clone' => ['void'],
'Yaf\Request\Simple::__construct' => ['void', 'method'=>'string', 'controller'=>'string', 'action'=>'string', 'params='=>'string'],
'Yaf\Request\Simple::get' => ['mixed', 'name'=>'string', 'default='=>'string'],
'Yaf\Request\Simple::getActionName' => ['string'],
'Yaf\Request\Simple::getBaseUri' => ['string'],
'Yaf\Request\Simple::getControllerName' => ['string'],
'Yaf\Request\Simple::getCookie' => ['mixed', 'name='=>'string', 'default='=>'string'],
'Yaf\Request\Simple::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Simple::getException' => ['Yaf\Exception'],
'Yaf\Request\Simple::getFiles' => ['array', 'name='=>'mixed', 'default='=>'null'],
'Yaf\Request\Simple::getLanguage' => ['string'],
'Yaf\Request\Simple::getMethod' => ['string'],
'Yaf\Request\Simple::getModuleName' => ['string'],
'Yaf\Request\Simple::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
'Yaf\Request\Simple::getParams' => ['array'],
'Yaf\Request\Simple::getPost' => ['mixed', 'name='=>'string', 'default='=>'string'],
'Yaf\Request\Simple::getQuery' => ['mixed', 'name='=>'string', 'default='=>'string'],
'Yaf\Request\Simple::getRequest' => ['mixed', 'name='=>'string', 'default='=>'string'],
'Yaf\Request\Simple::getRequestUri' => ['string'],
'Yaf\Request\Simple::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request\Simple::isCli' => ['bool'],
'Yaf\Request\Simple::isDispatched' => ['bool'],
'Yaf\Request\Simple::isGet' => ['bool'],
'Yaf\Request\Simple::isHead' => ['bool'],
'Yaf\Request\Simple::isOptions' => ['bool'],
'Yaf\Request\Simple::isPost' => ['bool'],
'Yaf\Request\Simple::isPut' => ['bool'],
'Yaf\Request\Simple::isRouted' => ['bool'],
'Yaf\Request\Simple::isXmlHttpRequest' => ['bool'],
'Yaf\Request\Simple::setActionName' => ['Yaf\Request_Abstract|bool', 'action'=>'string'],
'Yaf\Request\Simple::setBaseUri' => ['bool', 'uri'=>'string'],
'Yaf\Request\Simple::setControllerName' => ['Yaf\Request_Abstract|bool', 'controller'=>'string'],
'Yaf\Request\Simple::setDispatched' => ['bool'],
'Yaf\Request\Simple::setModuleName' => ['Yaf\Request_Abstract|bool', 'module'=>'string'],
'Yaf\Request\Simple::setParam' => ['Yaf\Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
'Yaf\Request\Simple::setRequestUri' => ['', 'uri'=>'string'],
'Yaf\Request\Simple::setRouted' => ['Yaf\Request_Abstract|bool'],
'Yaf\Request_Abstract::getActionName' => ['string'],
'Yaf\Request_Abstract::getBaseUri' => ['string'],
'Yaf\Request_Abstract::getControllerName' => ['string'],
'Yaf\Request_Abstract::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request_Abstract::getException' => ['Yaf\Exception'],
'Yaf\Request_Abstract::getLanguage' => ['string'],
'Yaf\Request_Abstract::getMethod' => ['string'],
'Yaf\Request_Abstract::getModuleName' => ['string'],
'Yaf\Request_Abstract::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
'Yaf\Request_Abstract::getParams' => ['array'],
'Yaf\Request_Abstract::getRequestUri' => ['string'],
'Yaf\Request_Abstract::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf\Request_Abstract::isCli' => ['bool'],
'Yaf\Request_Abstract::isDispatched' => ['bool'],
'Yaf\Request_Abstract::isGet' => ['bool'],
'Yaf\Request_Abstract::isHead' => ['bool'],
'Yaf\Request_Abstract::isOptions' => ['bool'],
'Yaf\Request_Abstract::isPost' => ['bool'],
'Yaf\Request_Abstract::isPut' => ['bool'],
'Yaf\Request_Abstract::isRouted' => ['bool'],
'Yaf\Request_Abstract::isXmlHttpRequest' => ['bool'],
'Yaf\Request_Abstract::setActionName' => ['Yaf\Request_Abstract|bool', 'action'=>'string'],
'Yaf\Request_Abstract::setBaseUri' => ['bool', 'uri'=>'string'],
'Yaf\Request_Abstract::setControllerName' => ['Yaf\Request_Abstract|bool', 'controller'=>'string'],
'Yaf\Request_Abstract::setDispatched' => ['bool'],
'Yaf\Request_Abstract::setModuleName' => ['Yaf\Request_Abstract|bool', 'module'=>'string'],
'Yaf\Request_Abstract::setParam' => ['Yaf\Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
'Yaf\Request_Abstract::setRequestUri' => ['', 'uri'=>'string'],
'Yaf\Request_Abstract::setRouted' => ['Yaf\Request_Abstract|bool'],
'Yaf\Response\Cli::__clone' => ['void'],
'Yaf\Response\Cli::__construct' => ['void'],
'Yaf\Response\Cli::__destruct' => ['void'],
'Yaf\Response\Cli::__toString' => ['string'],
'Yaf\Response\Cli::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response\Cli::clearBody' => ['bool', 'key='=>'string'],
'Yaf\Response\Cli::getBody' => ['mixed', 'key='=>'?string'],
'Yaf\Response\Cli::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response\Cli::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response\Http::__clone' => ['void'],
'Yaf\Response\Http::__construct' => ['void'],
'Yaf\Response\Http::__destruct' => ['void'],
'Yaf\Response\Http::__toString' => ['string'],
'Yaf\Response\Http::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response\Http::clearBody' => ['bool', 'key='=>'string'],
'Yaf\Response\Http::clearHeaders' => ['Yaf\Response_Abstract|false', 'name='=>'string'],
'Yaf\Response\Http::getBody' => ['mixed', 'key='=>'?string'],
'Yaf\Response\Http::getHeader' => ['mixed', 'name='=>'string'],
'Yaf\Response\Http::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response\Http::response' => ['bool'],
'Yaf\Response\Http::setAllHeaders' => ['bool', 'headers'=>'array'],
'Yaf\Response\Http::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response\Http::setHeader' => ['bool', 'name'=>'string', 'value'=>'string', 'replace='=>'bool', 'response_code='=>'int'],
'Yaf\Response\Http::setRedirect' => ['bool', 'url'=>'string'],
'Yaf\Response_Abstract::__clone' => ['void'],
'Yaf\Response_Abstract::__construct' => ['void'],
'Yaf\Response_Abstract::__destruct' => ['void'],
'Yaf\Response_Abstract::__toString' => ['void'],
'Yaf\Response_Abstract::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response_Abstract::clearBody' => ['bool', 'key='=>'string'],
'Yaf\Response_Abstract::getBody' => ['mixed', 'key='=>'?string'],
'Yaf\Response_Abstract::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Response_Abstract::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf\Route\Map::__construct' => ['void', 'controller_prefer='=>'bool', 'delimiter='=>'string'],
'Yaf\Route\Map::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
'Yaf\Route\Map::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Route\Regex::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'map='=>'?array', 'verify='=>'?array', 'reverse='=>'string'],
'Yaf\Route\Regex::addConfig' => ['Yaf\Router|bool', 'config'=>'Yaf\Config_Abstract'],
'Yaf\Route\Regex::addRoute' => ['Yaf\Router|bool', 'name'=>'string', 'route'=>'Yaf\Route_Interface'],
'Yaf\Route\Regex::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
'Yaf\Route\Regex::getCurrentRoute' => ['string'],
'Yaf\Route\Regex::getRoute' => ['Yaf\Route_Interface', 'name'=>'string'],
'Yaf\Route\Regex::getRoutes' => ['Yaf\Route_Interface[]'],
'Yaf\Route\Regex::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Route\Rewrite::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'verify='=>'?array', 'reverse='=>'string'],
'Yaf\Route\Rewrite::addConfig' => ['Yaf\Router|bool', 'config'=>'Yaf\Config_Abstract'],
'Yaf\Route\Rewrite::addRoute' => ['Yaf\Router|bool', 'name'=>'string', 'route'=>'Yaf\Route_Interface'],
'Yaf\Route\Rewrite::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
'Yaf\Route\Rewrite::getCurrentRoute' => ['string'],
'Yaf\Route\Rewrite::getRoute' => ['Yaf\Route_Interface', 'name'=>'string'],
'Yaf\Route\Rewrite::getRoutes' => ['Yaf\Route_Interface[]'],
'Yaf\Route\Rewrite::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Route\Simple::__construct' => ['void', 'module_name'=>'string', 'controller_name'=>'string', 'action_name'=>'string'],
'Yaf\Route\Simple::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
'Yaf\Route\Simple::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Route\Supervar::__construct' => ['void', 'supervar_name'=>'string'],
'Yaf\Route\Supervar::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
'Yaf\Route\Supervar::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Route_Interface::__construct' => ['Yaf\Route_Interface'],
'Yaf\Route_Interface::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
'Yaf\Route_Interface::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Route_Static::assemble' => ['bool', 'info'=>'array', 'query='=>'?array'],
'Yaf\Route_Static::match' => ['bool', 'uri'=>'string'],
'Yaf\Route_Static::route' => ['bool', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Router::__construct' => ['void'],
'Yaf\Router::addConfig' => ['Yaf\Router|false', 'config'=>'Yaf\Config_Abstract'],
'Yaf\Router::addRoute' => ['Yaf\Router|false', 'name'=>'string', 'route'=>'Yaf\Route_Interface'],
'Yaf\Router::getCurrentRoute' => ['string'],
'Yaf\Router::getRoute' => ['Yaf\Route_Interface', 'name'=>'string'],
'Yaf\Router::getRoutes' => ['Yaf\Route_Interface[]'],
'Yaf\Router::route' => ['Yaf\Router|false', 'request'=>'Yaf\Request_Abstract'],
'Yaf\Session::__clone' => ['void'],
'Yaf\Session::__construct' => ['void'],
'Yaf\Session::__get' => ['void', 'name'=>''],
'Yaf\Session::__isset' => ['void', 'name'=>''],
'Yaf\Session::__set' => ['void', 'name'=>'', 'value'=>''],
'Yaf\Session::__sleep' => ['list<string>'],
'Yaf\Session::__unset' => ['void', 'name'=>''],
'Yaf\Session::__wakeup' => ['void'],
'Yaf\Session::count' => ['int'],
'Yaf\Session::current' => ['mixed'],
'Yaf\Session::del' => ['Yaf\Session|false', 'name'=>'string'],
'Yaf\Session::get' => ['mixed', 'name'=>'string'],
'Yaf\Session::getInstance' => ['Yaf\Session'],
'Yaf\Session::has' => ['bool', 'name'=>'string'],
'Yaf\Session::key' => ['int|string'],
'Yaf\Session::next' => ['void'],
'Yaf\Session::offsetExists' => ['bool', 'name'=>'mixed'],
'Yaf\Session::offsetGet' => ['mixed', 'name'=>'mixed'],
'Yaf\Session::offsetSet' => ['void', 'name'=>'mixed', 'value'=>'mixed'],
'Yaf\Session::offsetUnset' => ['void', 'name'=>'mixed'],
'Yaf\Session::rewind' => ['void'],
'Yaf\Session::set' => ['Yaf\Session|false', 'name'=>'string', 'value'=>'mixed'],
'Yaf\Session::start' => ['Yaf\Session'],
'Yaf\Session::valid' => ['bool'],
'Yaf\View\Simple::__construct' => ['void', 'template_dir'=>'string', 'options='=>'?array'],
'Yaf\View\Simple::__get' => ['mixed', 'name='=>'null'],
'Yaf\View\Simple::__isset' => ['', 'name'=>'string'],
'Yaf\View\Simple::__set' => ['void', 'name'=>'string', 'value='=>'mixed'],
'Yaf\View\Simple::assign' => ['Yaf\View\Simple', 'name'=>'array|string', 'value='=>'mixed'],
'Yaf\View\Simple::assignRef' => ['Yaf\View\Simple', 'name'=>'string', '&value'=>'mixed'],
'Yaf\View\Simple::clear' => ['Yaf\View\Simple', 'name='=>'string'],
'Yaf\View\Simple::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'?array'],
'Yaf\View\Simple::eval' => ['bool|void', 'tpl_str'=>'string', 'vars='=>'?array'],
'Yaf\View\Simple::getScriptPath' => ['string'],
'Yaf\View\Simple::render' => ['string|void', 'tpl'=>'string', 'tpl_vars='=>'?array'],
'Yaf\View\Simple::setScriptPath' => ['Yaf\View\Simple', 'template_dir'=>'string'],
'Yaf\View_Interface::assign' => ['bool', 'name'=>'array|string', 'value'=>'mixed'],
'Yaf\View_Interface::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'?array'],
'Yaf\View_Interface::getScriptPath' => ['string'],
'Yaf\View_Interface::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'?array'],
'Yaf\View_Interface::setScriptPath' => ['void', 'template_dir'=>'string'],
'Yaf_Action_Abstract::__clone' => ['void'],
'Yaf_Action_Abstract::__construct' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract', 'view'=>'Yaf_View_Interface', 'invokeArgs='=>'?array'],
'Yaf_Action_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'],
'Yaf_Action_Abstract::execute' => ['mixed', 'arg='=>'mixed', '...args='=>'mixed'],
'Yaf_Action_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'],
'Yaf_Action_Abstract::getController' => ['Yaf_Controller_Abstract'],
'Yaf_Action_Abstract::getControllerName' => ['string'],
'Yaf_Action_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'],
'Yaf_Action_Abstract::getInvokeArgs' => ['array'],
'Yaf_Action_Abstract::getModuleName' => ['string'],
'Yaf_Action_Abstract::getRequest' => ['Yaf_Request_Abstract'],
'Yaf_Action_Abstract::getResponse' => ['Yaf_Response_Abstract'],
'Yaf_Action_Abstract::getView' => ['Yaf_View_Interface'],
'Yaf_Action_Abstract::getViewpath' => ['string'],
'Yaf_Action_Abstract::init' => [''],
'Yaf_Action_Abstract::initView' => ['Yaf_Response_Abstract', 'options='=>'?array'],
'Yaf_Action_Abstract::redirect' => ['bool', 'url'=>'string'],
'Yaf_Action_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'],
'Yaf_Action_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'],
'Yaf_Application::__clone' => ['void'],
'Yaf_Application::__construct' => ['void', 'config'=>'mixed', 'envrion='=>'string'],
'Yaf_Application::__destruct' => ['void'],
'Yaf_Application::__sleep' => ['list<string>'],
'Yaf_Application::__wakeup' => ['void'],
'Yaf_Application::app' => ['?Yaf_Application'],
'Yaf_Application::bootstrap' => ['Yaf_Application', 'bootstrap='=>'Yaf_Bootstrap_Abstract'],
'Yaf_Application::clearLastError' => ['Yaf_Application'],
'Yaf_Application::environ' => ['string'],
'Yaf_Application::execute' => ['void', 'entry'=>'callable', '...args'=>'string'],
'Yaf_Application::getAppDirectory' => ['Yaf_Application'],
'Yaf_Application::getConfig' => ['Yaf_Config_Abstract'],
'Yaf_Application::getDispatcher' => ['Yaf_Dispatcher'],
'Yaf_Application::getLastErrorMsg' => ['string'],
'Yaf_Application::getLastErrorNo' => ['int'],
'Yaf_Application::getModules' => ['array'],
'Yaf_Application::run' => ['void'],
'Yaf_Application::setAppDirectory' => ['Yaf_Application', 'directory'=>'string'],
'Yaf_Config_Abstract::__construct' => ['void'],
'Yaf_Config_Abstract::get' => ['mixed', 'name'=>'string', 'value'=>'mixed'],
'Yaf_Config_Abstract::readonly' => ['bool'],
'Yaf_Config_Abstract::set' => ['Yaf_Config_Abstract'],
'Yaf_Config_Abstract::toArray' => ['array'],
'Yaf_Config_Ini::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'],
'Yaf_Config_Ini::__get' => ['void', 'name='=>'string'],
'Yaf_Config_Ini::__isset' => ['void', 'name'=>'string'],
'Yaf_Config_Ini::__set' => ['void', 'name'=>'string', 'value'=>'mixed'],
'Yaf_Config_Ini::count' => ['void'],
'Yaf_Config_Ini::current' => ['void'],
'Yaf_Config_Ini::get' => ['mixed', 'name='=>'mixed'],
'Yaf_Config_Ini::key' => ['void'],
'Yaf_Config_Ini::next' => ['void'],
'Yaf_Config_Ini::offsetExists' => ['void', 'name'=>'string'],
'Yaf_Config_Ini::offsetGet' => ['void', 'name'=>'string'],
'Yaf_Config_Ini::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'],
'Yaf_Config_Ini::offsetUnset' => ['void', 'name'=>'string'],
'Yaf_Config_Ini::readonly' => ['void'],
'Yaf_Config_Ini::rewind' => ['void'],
'Yaf_Config_Ini::set' => ['Yaf_Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
'Yaf_Config_Ini::toArray' => ['array'],
'Yaf_Config_Ini::valid' => ['void'],
'Yaf_Config_Simple::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'],
'Yaf_Config_Simple::__get' => ['void', 'name='=>'string'],
'Yaf_Config_Simple::__isset' => ['void', 'name'=>'string'],
'Yaf_Config_Simple::__set' => ['void', 'name'=>'string', 'value'=>'string'],
'Yaf_Config_Simple::count' => ['void'],
'Yaf_Config_Simple::current' => ['void'],
'Yaf_Config_Simple::get' => ['mixed', 'name='=>'mixed'],
'Yaf_Config_Simple::key' => ['void'],
'Yaf_Config_Simple::next' => ['void'],
'Yaf_Config_Simple::offsetExists' => ['void', 'name'=>'string'],
'Yaf_Config_Simple::offsetGet' => ['void', 'name'=>'string'],
'Yaf_Config_Simple::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'],
'Yaf_Config_Simple::offsetUnset' => ['void', 'name'=>'string'],
'Yaf_Config_Simple::readonly' => ['void'],
'Yaf_Config_Simple::rewind' => ['void'],
'Yaf_Config_Simple::set' => ['Yaf_Config_Abstract', 'name'=>'string', 'value'=>'mixed'],
'Yaf_Config_Simple::toArray' => ['array'],
'Yaf_Config_Simple::valid' => ['void'],
'Yaf_Controller_Abstract::__clone' => ['void'],
'Yaf_Controller_Abstract::__construct' => ['void'],
'Yaf_Controller_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'array'],
'Yaf_Controller_Abstract::forward' => ['void', 'action'=>'string', 'parameters='=>'array'],
'Yaf_Controller_Abstract::forward\'1' => ['void', 'controller'=>'string', 'action'=>'string', 'parameters='=>'array'],
'Yaf_Controller_Abstract::forward\'2' => ['void', 'module'=>'string', 'controller'=>'string', 'action'=>'string', 'parameters='=>'array'],
'Yaf_Controller_Abstract::getInvokeArg' => ['void', 'name'=>'string'],
'Yaf_Controller_Abstract::getInvokeArgs' => ['void'],
'Yaf_Controller_Abstract::getModuleName' => ['string'],
'Yaf_Controller_Abstract::getName' => ['string'],
'Yaf_Controller_Abstract::getRequest' => ['Yaf_Request_Abstract'],
'Yaf_Controller_Abstract::getResponse' => ['Yaf_Response_Abstract'],
'Yaf_Controller_Abstract::getView' => ['Yaf_View_Interface'],
'Yaf_Controller_Abstract::getViewpath' => ['void'],
'Yaf_Controller_Abstract::init' => ['void'],
'Yaf_Controller_Abstract::initView' => ['void', 'options='=>'array'],
'Yaf_Controller_Abstract::redirect' => ['bool', 'url'=>'string'],
'Yaf_Controller_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'array'],
'Yaf_Controller_Abstract::setViewpath' => ['void', 'view_directory'=>'string'],
'Yaf_Dispatcher::__clone' => ['void'],
'Yaf_Dispatcher::__construct' => ['void'],
'Yaf_Dispatcher::__sleep' => ['list<string>'],
'Yaf_Dispatcher::__wakeup' => ['void'],
'Yaf_Dispatcher::autoRender' => ['Yaf_Dispatcher', 'flag='=>'bool'],
'Yaf_Dispatcher::catchException' => ['Yaf_Dispatcher', 'flag='=>'bool'],
'Yaf_Dispatcher::disableView' => ['bool'],
'Yaf_Dispatcher::dispatch' => ['Yaf_Response_Abstract', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Dispatcher::enableView' => ['Yaf_Dispatcher'],
'Yaf_Dispatcher::flushInstantly' => ['Yaf_Dispatcher', 'flag='=>'bool'],
'Yaf_Dispatcher::getApplication' => ['Yaf_Application'],
'Yaf_Dispatcher::getDefaultAction' => ['string'],
'Yaf_Dispatcher::getDefaultController' => ['string'],
'Yaf_Dispatcher::getDefaultModule' => ['string'],
'Yaf_Dispatcher::getInstance' => ['Yaf_Dispatcher'],
'Yaf_Dispatcher::getRequest' => ['Yaf_Request_Abstract'],
'Yaf_Dispatcher::getRouter' => ['Yaf_Router'],
'Yaf_Dispatcher::initView' => ['Yaf_View_Interface', 'templates_dir'=>'string', 'options='=>'array'],
'Yaf_Dispatcher::registerPlugin' => ['Yaf_Dispatcher', 'plugin'=>'Yaf_Plugin_Abstract'],
'Yaf_Dispatcher::returnResponse' => ['Yaf_Dispatcher', 'flag'=>'bool'],
'Yaf_Dispatcher::setDefaultAction' => ['Yaf_Dispatcher', 'action'=>'string'],
'Yaf_Dispatcher::setDefaultController' => ['Yaf_Dispatcher', 'controller'=>'string'],
'Yaf_Dispatcher::setDefaultModule' => ['Yaf_Dispatcher', 'module'=>'string'],
'Yaf_Dispatcher::setErrorHandler' => ['Yaf_Dispatcher', 'callback'=>'callable', 'error_types'=>'int'],
'Yaf_Dispatcher::setRequest' => ['Yaf_Dispatcher', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Dispatcher::setView' => ['Yaf_Dispatcher', 'view'=>'Yaf_View_Interface'],
'Yaf_Dispatcher::throwException' => ['Yaf_Dispatcher', 'flag='=>'bool'],
'Yaf_Exception::__construct' => ['void'],
'Yaf_Exception::getPrevious' => ['void'],
'Yaf_Loader::__clone' => ['void'],
'Yaf_Loader::__construct' => ['void'],
'Yaf_Loader::__sleep' => ['list<string>'],
'Yaf_Loader::__wakeup' => ['void'],
'Yaf_Loader::autoload' => ['void'],
'Yaf_Loader::clearLocalNamespace' => ['void'],
'Yaf_Loader::getInstance' => ['Yaf_Loader'],
'Yaf_Loader::getLibraryPath' => ['Yaf_Loader', 'is_global='=>'bool'],
'Yaf_Loader::getLocalNamespace' => ['void'],
'Yaf_Loader::getNamespacePath' => ['string', 'namespaces'=>'string'],
'Yaf_Loader::import' => ['bool'],
'Yaf_Loader::isLocalName' => ['bool'],
'Yaf_Loader::registerLocalNamespace' => ['void', 'prefix'=>'mixed'],
'Yaf_Loader::registerNamespace' => ['bool', 'namespaces'=>'string|array', 'path='=>'string'],
'Yaf_Loader::setLibraryPath' => ['Yaf_Loader', 'directory'=>'string', 'is_global='=>'bool'],
'Yaf_Plugin_Abstract::dispatchLoopShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
'Yaf_Plugin_Abstract::dispatchLoopStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
'Yaf_Plugin_Abstract::postDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
'Yaf_Plugin_Abstract::preDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
'Yaf_Plugin_Abstract::preResponse' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
'Yaf_Plugin_Abstract::routerShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
'Yaf_Plugin_Abstract::routerStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'],
'Yaf_Registry::__clone' => ['void'],
'Yaf_Registry::__construct' => ['void'],
'Yaf_Registry::del' => ['void', 'name'=>'string'],
'Yaf_Registry::get' => ['mixed', 'name'=>'string'],
'Yaf_Registry::has' => ['bool', 'name'=>'string'],
'Yaf_Registry::set' => ['bool', 'name'=>'string', 'value'=>'string'],
'Yaf_Request_Abstract::clearParams' => ['bool'],
'Yaf_Request_Abstract::getActionName' => ['void'],
'Yaf_Request_Abstract::getBaseUri' => ['void'],
'Yaf_Request_Abstract::getControllerName' => ['void'],
'Yaf_Request_Abstract::getEnv' => ['void', 'name'=>'string', 'default='=>'string'],
'Yaf_Request_Abstract::getException' => ['void'],
'Yaf_Request_Abstract::getLanguage' => ['void'],
'Yaf_Request_Abstract::getMethod' => ['void'],
'Yaf_Request_Abstract::getModuleName' => ['void'],
'Yaf_Request_Abstract::getParam' => ['void', 'name'=>'string', 'default='=>'string'],
'Yaf_Request_Abstract::getParams' => ['void'],
'Yaf_Request_Abstract::getRequestUri' => ['void'],
'Yaf_Request_Abstract::getServer' => ['void', 'name'=>'string', 'default='=>'string'],
'Yaf_Request_Abstract::isCli' => ['void'],
'Yaf_Request_Abstract::isDispatched' => ['void'],
'Yaf_Request_Abstract::isGet' => ['void'],
'Yaf_Request_Abstract::isHead' => ['void'],
'Yaf_Request_Abstract::isOptions' => ['void'],
'Yaf_Request_Abstract::isPost' => ['void'],
'Yaf_Request_Abstract::isPut' => ['void'],
'Yaf_Request_Abstract::isRouted' => ['void'],
'Yaf_Request_Abstract::isXmlHttpRequest' => ['void'],
'Yaf_Request_Abstract::setActionName' => ['void', 'action'=>'string'],
'Yaf_Request_Abstract::setBaseUri' => ['bool', 'uir'=>'string'],
'Yaf_Request_Abstract::setControllerName' => ['void', 'controller'=>'string'],
'Yaf_Request_Abstract::setDispatched' => ['void'],
'Yaf_Request_Abstract::setModuleName' => ['void', 'module'=>'string'],
'Yaf_Request_Abstract::setParam' => ['void', 'name'=>'string', 'value='=>'string'],
'Yaf_Request_Abstract::setRequestUri' => ['void', 'uir'=>'string'],
'Yaf_Request_Abstract::setRouted' => ['void', 'flag='=>'string'],
'Yaf_Request_Http::__clone' => ['void'],
'Yaf_Request_Http::__construct' => ['void'],
'Yaf_Request_Http::get' => ['mixed', 'name'=>'string', 'default='=>'string'],
'Yaf_Request_Http::getActionName' => ['string'],
'Yaf_Request_Http::getBaseUri' => ['string'],
'Yaf_Request_Http::getControllerName' => ['string'],
'Yaf_Request_Http::getCookie' => ['mixed', 'name'=>'string', 'default='=>'string'],
'Yaf_Request_Http::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf_Request_Http::getException' => ['Yaf_Exception'],
'Yaf_Request_Http::getFiles' => ['void'],
'Yaf_Request_Http::getLanguage' => ['string'],
'Yaf_Request_Http::getMethod' => ['string'],
'Yaf_Request_Http::getModuleName' => ['string'],
'Yaf_Request_Http::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
'Yaf_Request_Http::getParams' => ['array'],
'Yaf_Request_Http::getPost' => ['mixed', 'name'=>'string', 'default='=>'string'],
'Yaf_Request_Http::getQuery' => ['mixed', 'name'=>'string', 'default='=>'string'],
'Yaf_Request_Http::getRaw' => ['mixed'],
'Yaf_Request_Http::getRequest' => ['void'],
'Yaf_Request_Http::getRequestUri' => ['string'],
'Yaf_Request_Http::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf_Request_Http::isCli' => ['bool'],
'Yaf_Request_Http::isDispatched' => ['bool'],
'Yaf_Request_Http::isGet' => ['bool'],
'Yaf_Request_Http::isHead' => ['bool'],
'Yaf_Request_Http::isOptions' => ['bool'],
'Yaf_Request_Http::isPost' => ['bool'],
'Yaf_Request_Http::isPut' => ['bool'],
'Yaf_Request_Http::isRouted' => ['bool'],
'Yaf_Request_Http::isXmlHttpRequest' => ['bool'],
'Yaf_Request_Http::setActionName' => ['Yaf_Request_Abstract|bool', 'action'=>'string'],
'Yaf_Request_Http::setBaseUri' => ['bool', 'uri'=>'string'],
'Yaf_Request_Http::setControllerName' => ['Yaf_Request_Abstract|bool', 'controller'=>'string'],
'Yaf_Request_Http::setDispatched' => ['bool'],
'Yaf_Request_Http::setModuleName' => ['Yaf_Request_Abstract|bool', 'module'=>'string'],
'Yaf_Request_Http::setParam' => ['Yaf_Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
'Yaf_Request_Http::setRequestUri' => ['', 'uri'=>'string'],
'Yaf_Request_Http::setRouted' => ['Yaf_Request_Abstract|bool'],
'Yaf_Request_Simple::__clone' => ['void'],
'Yaf_Request_Simple::__construct' => ['void'],
'Yaf_Request_Simple::get' => ['void'],
'Yaf_Request_Simple::getActionName' => ['string'],
'Yaf_Request_Simple::getBaseUri' => ['string'],
'Yaf_Request_Simple::getControllerName' => ['string'],
'Yaf_Request_Simple::getCookie' => ['void'],
'Yaf_Request_Simple::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf_Request_Simple::getException' => ['Yaf_Exception'],
'Yaf_Request_Simple::getFiles' => ['void'],
'Yaf_Request_Simple::getLanguage' => ['string'],
'Yaf_Request_Simple::getMethod' => ['string'],
'Yaf_Request_Simple::getModuleName' => ['string'],
'Yaf_Request_Simple::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'],
'Yaf_Request_Simple::getParams' => ['array'],
'Yaf_Request_Simple::getPost' => ['void'],
'Yaf_Request_Simple::getQuery' => ['void'],
'Yaf_Request_Simple::getRequest' => ['void'],
'Yaf_Request_Simple::getRequestUri' => ['string'],
'Yaf_Request_Simple::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'],
'Yaf_Request_Simple::isCli' => ['bool'],
'Yaf_Request_Simple::isDispatched' => ['bool'],
'Yaf_Request_Simple::isGet' => ['bool'],
'Yaf_Request_Simple::isHead' => ['bool'],
'Yaf_Request_Simple::isOptions' => ['bool'],
'Yaf_Request_Simple::isPost' => ['bool'],
'Yaf_Request_Simple::isPut' => ['bool'],
'Yaf_Request_Simple::isRouted' => ['bool'],
'Yaf_Request_Simple::isXmlHttpRequest' => ['void'],
'Yaf_Request_Simple::setActionName' => ['Yaf_Request_Abstract|bool', 'action'=>'string'],
'Yaf_Request_Simple::setBaseUri' => ['bool', 'uri'=>'string'],
'Yaf_Request_Simple::setControllerName' => ['Yaf_Request_Abstract|bool', 'controller'=>'string'],
'Yaf_Request_Simple::setDispatched' => ['bool'],
'Yaf_Request_Simple::setModuleName' => ['Yaf_Request_Abstract|bool', 'module'=>'string'],
'Yaf_Request_Simple::setParam' => ['Yaf_Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'],
'Yaf_Request_Simple::setRequestUri' => ['', 'uri'=>'string'],
'Yaf_Request_Simple::setRouted' => ['Yaf_Request_Abstract|bool'],
'Yaf_Response_Abstract::__clone' => ['void'],
'Yaf_Response_Abstract::__construct' => ['void'],
'Yaf_Response_Abstract::__destruct' => ['void'],
'Yaf_Response_Abstract::__toString' => ['string'],
'Yaf_Response_Abstract::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Abstract::clearBody' => ['bool', 'key='=>'string'],
'Yaf_Response_Abstract::clearHeaders' => ['void'],
'Yaf_Response_Abstract::getBody' => ['mixed', 'key='=>'string'],
'Yaf_Response_Abstract::getHeader' => ['void'],
'Yaf_Response_Abstract::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Abstract::response' => ['void'],
'Yaf_Response_Abstract::setAllHeaders' => ['void'],
'Yaf_Response_Abstract::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Abstract::setHeader' => ['void'],
'Yaf_Response_Abstract::setRedirect' => ['void'],
'Yaf_Response_Cli::__clone' => ['void'],
'Yaf_Response_Cli::__construct' => ['void'],
'Yaf_Response_Cli::__destruct' => ['void'],
'Yaf_Response_Cli::__toString' => ['string'],
'Yaf_Response_Cli::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Cli::clearBody' => ['bool', 'key='=>'string'],
'Yaf_Response_Cli::getBody' => ['mixed', 'key='=>'?string'],
'Yaf_Response_Cli::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Cli::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Http::__clone' => ['void'],
'Yaf_Response_Http::__construct' => ['void'],
'Yaf_Response_Http::__destruct' => ['void'],
'Yaf_Response_Http::__toString' => ['string'],
'Yaf_Response_Http::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Http::clearBody' => ['bool', 'key='=>'string'],
'Yaf_Response_Http::clearHeaders' => ['Yaf_Response_Abstract|false', 'name='=>'string'],
'Yaf_Response_Http::getBody' => ['mixed', 'key='=>'?string'],
'Yaf_Response_Http::getHeader' => ['mixed', 'name='=>'string'],
'Yaf_Response_Http::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Http::response' => ['bool'],
'Yaf_Response_Http::setAllHeaders' => ['bool', 'headers'=>'array'],
'Yaf_Response_Http::setBody' => ['bool', 'content'=>'string', 'key='=>'string'],
'Yaf_Response_Http::setHeader' => ['bool', 'name'=>'string', 'value'=>'string', 'replace='=>'bool', 'response_code='=>'int'],
'Yaf_Response_Http::setRedirect' => ['bool', 'url'=>'string'],
'Yaf_Route_Interface::__construct' => ['void'],
'Yaf_Route_Interface::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
'Yaf_Route_Interface::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Route_Map::__construct' => ['void', 'controller_prefer='=>'string', 'delimiter='=>'string'],
'Yaf_Route_Map::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
'Yaf_Route_Map::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Route_Regex::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'map='=>'array', 'verify='=>'array', 'reverse='=>'string'],
'Yaf_Route_Regex::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'],
'Yaf_Route_Regex::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'],
'Yaf_Route_Regex::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
'Yaf_Route_Regex::getCurrentRoute' => ['string'],
'Yaf_Route_Regex::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'],
'Yaf_Route_Regex::getRoutes' => ['Yaf_Route_Interface[]'],
'Yaf_Route_Regex::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Route_Rewrite::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'verify='=>'array'],
'Yaf_Route_Rewrite::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'],
'Yaf_Route_Rewrite::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'],
'Yaf_Route_Rewrite::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
'Yaf_Route_Rewrite::getCurrentRoute' => ['string'],
'Yaf_Route_Rewrite::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'],
'Yaf_Route_Rewrite::getRoutes' => ['Yaf_Route_Interface[]'],
'Yaf_Route_Rewrite::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Route_Simple::__construct' => ['void', 'module_name'=>'string', 'controller_name'=>'string', 'action_name'=>'string'],
'Yaf_Route_Simple::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
'Yaf_Route_Simple::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Route_Static::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
'Yaf_Route_Static::match' => ['void', 'uri'=>'string'],
'Yaf_Route_Static::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Route_Supervar::__construct' => ['void', 'supervar_name'=>'string'],
'Yaf_Route_Supervar::assemble' => ['string', 'info'=>'array', 'query='=>'array'],
'Yaf_Route_Supervar::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Router::__construct' => ['void'],
'Yaf_Router::addConfig' => ['bool', 'config'=>'Yaf_Config_Abstract'],
'Yaf_Router::addRoute' => ['bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'],
'Yaf_Router::getCurrentRoute' => ['string'],
'Yaf_Router::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'],
'Yaf_Router::getRoutes' => ['mixed'],
'Yaf_Router::route' => ['bool', 'request'=>'Yaf_Request_Abstract'],
'Yaf_Session::__clone' => ['void'],
'Yaf_Session::__construct' => ['void'],
'Yaf_Session::__get' => ['void', 'name'=>'string'],
'Yaf_Session::__isset' => ['void', 'name'=>'string'],
'Yaf_Session::__set' => ['void', 'name'=>'string', 'value'=>'string'],
'Yaf_Session::__sleep' => ['list<string>'],
'Yaf_Session::__unset' => ['void', 'name'=>'string'],
'Yaf_Session::__wakeup' => ['void'],
'Yaf_Session::count' => ['void'],
'Yaf_Session::current' => ['void'],
'Yaf_Session::del' => ['void', 'name'=>'string'],
'Yaf_Session::get' => ['mixed', 'name'=>'string'],
'Yaf_Session::getInstance' => ['void'],
'Yaf_Session::has' => ['void', 'name'=>'string'],
'Yaf_Session::key' => ['void'],
'Yaf_Session::next' => ['void'],
'Yaf_Session::offsetExists' => ['void', 'name'=>'string'],
'Yaf_Session::offsetGet' => ['void', 'name'=>'string'],
'Yaf_Session::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'],
'Yaf_Session::offsetUnset' => ['void', 'name'=>'string'],
'Yaf_Session::rewind' => ['void'],
'Yaf_Session::set' => ['Yaf_Session|bool', 'name'=>'string', 'value'=>'mixed'],
'Yaf_Session::start' => ['void'],
'Yaf_Session::valid' => ['void'],
'Yaf_View_Interface::assign' => ['bool', 'name'=>'string', 'value='=>'string'],
'Yaf_View_Interface::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'array'],
'Yaf_View_Interface::getScriptPath' => ['string'],
'Yaf_View_Interface::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'array'],
'Yaf_View_Interface::setScriptPath' => ['void', 'template_dir'=>'string'],
'Yaf_View_Simple::__construct' => ['void', 'tempalte_dir'=>'string', 'options='=>'array'],
'Yaf_View_Simple::__get' => ['void', 'name='=>'string'],
'Yaf_View_Simple::__isset' => ['void', 'name'=>'string'],
'Yaf_View_Simple::__set' => ['void', 'name'=>'string', 'value'=>'mixed'],
'Yaf_View_Simple::assign' => ['bool', 'name'=>'string', 'value='=>'mixed'],
'Yaf_View_Simple::assignRef' => ['bool', 'name'=>'string', '&rw_value'=>'mixed'],
'Yaf_View_Simple::clear' => ['bool', 'name='=>'string'],
'Yaf_View_Simple::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'array'],
'Yaf_View_Simple::eval' => ['string', 'tpl_content'=>'string', 'tpl_vars='=>'array'],
'Yaf_View_Simple::getScriptPath' => ['string'],
'Yaf_View_Simple::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'array'],
'Yaf_View_Simple::setScriptPath' => ['bool', 'template_dir'=>'string'],
'yaml_emit' => ['string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'],
'yaml_emit_file' => ['bool', 'filename'=>'string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'],
'yaml_parse' => ['mixed|false', 'input'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'],
'yaml_parse_file' => ['mixed|false', 'filename'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'],
'yaml_parse_url' => ['mixed|false', 'url'=>'string', 'pos='=>'int', '&w_ndocs='=>'int', 'callbacks='=>'array'],
'Yar_Client::__call' => ['void', 'method'=>'string', 'parameters'=>'array'],
'Yar_Client::__construct' => ['void', 'url'=>'string'],
'Yar_Client::setOpt' => ['Yar_Client|false', 'name'=>'int', 'value'=>'mixed'],
'Yar_Client_Exception::__clone' => ['void'],
'Yar_Client_Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'Yar_Client_Exception::__toString' => ['string'],
'Yar_Client_Exception::__wakeup' => ['void'],
'Yar_Client_Exception::getCode' => ['int'],
'Yar_Client_Exception::getFile' => ['string'],
'Yar_Client_Exception::getLine' => ['int'],
'Yar_Client_Exception::getMessage' => ['string'],
'Yar_Client_Exception::getPrevious' => ['?Exception|?Throwable'],
'Yar_Client_Exception::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'Yar_Client_Exception::getTraceAsString' => ['string'],
'Yar_Client_Exception::getType' => ['string'],
'Yar_Concurrent_Client::call' => ['int', 'uri'=>'string', 'method'=>'string', 'parameters'=>'array', 'callback='=>'callable'],
'Yar_Concurrent_Client::loop' => ['bool', 'callback='=>'callable', 'error_callback='=>'callable'],
'Yar_Concurrent_Client::reset' => ['bool'],
'Yar_Server::__construct' => ['void', 'object'=>'Object'],
'Yar_Server::handle' => ['bool'],
'Yar_Server_Exception::__clone' => ['void'],
'Yar_Server_Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Exception|?Throwable'],
'Yar_Server_Exception::__toString' => ['string'],
'Yar_Server_Exception::__wakeup' => ['void'],
'Yar_Server_Exception::getCode' => ['int'],
'Yar_Server_Exception::getFile' => ['string'],
'Yar_Server_Exception::getLine' => ['int'],
'Yar_Server_Exception::getMessage' => ['string'],
'Yar_Server_Exception::getPrevious' => ['?Exception|?Throwable'],
'Yar_Server_Exception::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
'Yar_Server_Exception::getTraceAsString' => ['string'],
'Yar_Server_Exception::getType' => ['string'],
'yaz_addinfo' => ['string', 'id'=>'resource'],
'yaz_ccl_conf' => ['void', 'id'=>'resource', 'config'=>'array'],
'yaz_ccl_parse' => ['bool', 'id'=>'resource', 'query'=>'string', '&w_result'=>'array'],
'yaz_close' => ['bool', 'id'=>'resource'],
'yaz_connect' => ['mixed', 'zurl'=>'string', 'options='=>'mixed'],
'yaz_database' => ['bool', 'id'=>'resource', 'databases'=>'string'],
'yaz_element' => ['bool', 'id'=>'resource', 'elementset'=>'string'],
'yaz_errno' => ['int', 'id'=>'resource'],
'yaz_error' => ['string', 'id'=>'resource'],
'yaz_es' => ['void', 'id'=>'resource', 'type'=>'string', 'args'=>'array'],
'yaz_es_result' => ['array', 'id'=>'resource'],
'yaz_get_option' => ['string', 'id'=>'resource', 'name'=>'string'],
'yaz_hits' => ['int', 'id'=>'resource', 'searchresult='=>'array'],
'yaz_itemorder' => ['void', 'id'=>'resource', 'args'=>'array'],
'yaz_present' => ['bool', 'id'=>'resource'],
'yaz_range' => ['void', 'id'=>'resource', 'start'=>'int', 'number'=>'int'],
'yaz_record' => ['string', 'id'=>'resource', 'pos'=>'int', 'type'=>'string'],
'yaz_scan' => ['void', 'id'=>'resource', 'type'=>'string', 'startterm'=>'string', 'flags='=>'array'],
'yaz_scan_result' => ['array', 'id'=>'resource', 'result='=>'array'],
'yaz_schema' => ['void', 'id'=>'resource', 'schema'=>'string'],
'yaz_search' => ['bool', 'id'=>'resource', 'type'=>'string', 'query'=>'string'],
'yaz_set_option' => ['', 'id'=>'', 'name'=>'string', 'value'=>'string', 'options'=>'array'],
'yaz_sort' => ['void', 'id'=>'resource', 'criteria'=>'string'],
'yaz_syntax' => ['void', 'id'=>'resource', 'syntax'=>'string'],
'yaz_wait' => ['mixed', '&rw_options='=>'array'],
'yp_all' => ['void', 'domain'=>'string', 'map'=>'string', 'callback'=>'string'],
'yp_cat' => ['array', 'domain'=>'string', 'map'=>'string'],
'yp_err_string' => ['string', 'errorcode'=>'int'],
'yp_errno' => ['int'],
'yp_first' => ['array', 'domain'=>'string', 'map'=>'string'],
'yp_get_default_domain' => ['string'],
'yp_master' => ['string', 'domain'=>'string', 'map'=>'string'],
'yp_match' => ['string', 'domain'=>'string', 'map'=>'string', 'key'=>'string'],
'yp_next' => ['array', 'domain'=>'string', 'map'=>'string', 'key'=>'string'],
'yp_order' => ['int', 'domain'=>'string', 'map'=>'string'],
'zem_get_extension_info_by_id' => [''],
'zem_get_extension_info_by_name' => [''],
'zem_get_extensions_info' => [''],
'zem_get_license_info' => [''],
'zend_current_obfuscation_level' => ['int'],
'zend_disk_cache_clear' => ['bool', 'namespace='=>'mixed|string'],
'zend_disk_cache_delete' => ['mixed|null', 'key'=>'string'],
'zend_disk_cache_fetch' => ['mixed|null', 'key'=>'string'],
'zend_disk_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'],
'zend_get_id' => ['array', 'all_ids='=>'all_ids|false'],
'zend_is_configuration_changed' => [''],
'zend_loader_current_file' => ['string'],
'zend_loader_enabled' => ['bool'],
'zend_loader_file_encoded' => ['bool'],
'zend_loader_file_licensed' => ['array'],
'zend_loader_install_license' => ['bool', 'license_file'=>'string', 'override'=>'bool'],
'zend_logo_guid' => ['string'],
'zend_obfuscate_class_name' => ['string', 'class_name'=>'string'],
'zend_obfuscate_function_name' => ['string', 'function_name'=>'string'],
'zend_optimizer_version' => ['string'],
'zend_runtime_obfuscate' => ['void'],
'zend_send_buffer' => ['null|false', 'buffer'=>'string', 'mime_type='=>'string', 'custom_headers='=>'string'],
'zend_send_file' => ['null|false', 'filename'=>'string', 'mime_type='=>'string', 'custom_headers='=>'string'],
'zend_set_configuration_changed' => [''],
'zend_shm_cache_clear' => ['bool', 'namespace='=>'mixed|string'],
'zend_shm_cache_delete' => ['mixed|null', 'key'=>'string'],
'zend_shm_cache_fetch' => ['mixed|null', 'key'=>'string'],
'zend_shm_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'],
'zend_thread_id' => ['int'],
'zend_version' => ['string'],
'ZendAPI_Job::addJobToQueue' => ['int', 'jobqueue_url'=>'string', 'password'=>'string'],
'ZendAPI_Job::getApplicationID' => [''],
'ZendAPI_Job::getEndTime' => [''],
'ZendAPI_Job::getGlobalVariables' => [''],
'ZendAPI_Job::getHost' => [''],
'ZendAPI_Job::getID' => [''],
'ZendAPI_Job::getInterval' => [''],
'ZendAPI_Job::getJobDependency' => [''],
'ZendAPI_Job::getJobName' => [''],
'ZendAPI_Job::getJobPriority' => [''],
'ZendAPI_Job::getJobStatus' => ['int'],
'ZendAPI_Job::getLastPerformedStatus' => ['int'],
'ZendAPI_Job::getOutput' => ['An'],
'ZendAPI_Job::getPreserved' => [''],
'ZendAPI_Job::getProperties' => ['array'],
'ZendAPI_Job::getScheduledTime' => [''],
'ZendAPI_Job::getScript' => [''],
'ZendAPI_Job::getTimeToNextRepeat' => ['int'],
'ZendAPI_Job::getUserVariables' => [''],
'ZendAPI_Job::setApplicationID' => ['', 'app_id'=>''],
'ZendAPI_Job::setGlobalVariables' => ['', 'vars'=>''],
'ZendAPI_Job::setJobDependency' => ['', 'job_id'=>''],
'ZendAPI_Job::setJobName' => ['', 'name'=>''],
'ZendAPI_Job::setJobPriority' => ['', 'priority'=>'int'],
'ZendAPI_Job::setPreserved' => ['', 'preserved'=>''],
'ZendAPI_Job::setRecurrenceData' => ['', 'interval'=>'', 'end_time='=>'mixed'],
'ZendAPI_Job::setScheduledTime' => ['', 'timestamp'=>''],
'ZendAPI_Job::setScript' => ['', 'script'=>''],
'ZendAPI_Job::setUserVariables' => ['', 'vars'=>''],
'ZendAPI_Job::ZendAPI_Job' => ['Job', 'script'=>'script'],
'ZendAPI_Queue::addJob' => ['int', '&job'=>'Job'],
'ZendAPI_Queue::getAllApplicationIDs' => ['array'],
'ZendAPI_Queue::getAllhosts' => ['array'],
'ZendAPI_Queue::getHistoricJobs' => ['array', 'status'=>'int', 'start_time'=>'', 'end_time'=>'', 'index'=>'int', 'count'=>'int', '&total'=>'int'],
'ZendAPI_Queue::getJob' => ['Job', 'job_id'=>'int'],
'ZendAPI_Queue::getJobsInQueue' => ['array', 'filter_options='=>'array', 'max_jobs='=>'int', 'with_globals_and_output='=>'bool'],
'ZendAPI_Queue::getLastError' => ['string'],
'ZendAPI_Queue::getNumOfJobsInQueue' => ['int', 'filter_options='=>'array'],
'ZendAPI_Queue::getStatistics' => ['array'],
'ZendAPI_Queue::isScriptExists' => ['bool', 'path'=>'string'],
'ZendAPI_Queue::isSuspend' => ['bool'],
'ZendAPI_Queue::login' => ['bool', 'password'=>'string', 'application_id='=>'int'],
'ZendAPI_Queue::removeJob' => ['bool', 'job_id'=>'array|int'],
'ZendAPI_Queue::requeueJob' => ['bool', 'job'=>'Job'],
'ZendAPI_Queue::resumeJob' => ['bool', 'job_id'=>'array|int'],
'ZendAPI_Queue::resumeQueue' => ['bool'],
'ZendAPI_Queue::setMaxHistoryTime' => ['bool'],
'ZendAPI_Queue::suspendJob' => ['bool', 'job_id'=>'array|int'],
'ZendAPI_Queue::suspendQueue' => ['bool'],
'ZendAPI_Queue::updateJob' => ['int', '&job'=>'Job'],
'ZendAPI_Queue::zendapi_queue' => ['ZendAPI_Queue', 'queue_url'=>'string'],
'zip_close' => ['void', 'zip'=>'resource'],
'zip_entry_close' => ['bool', 'zip_ent'=>'resource'],
'zip_entry_compressedsize' => ['int', 'zip_entry'=>'resource'],
'zip_entry_compressionmethod' => ['string', 'zip_entry'=>'resource'],
'zip_entry_filesize' => ['int', 'zip_entry'=>'resource'],
'zip_entry_name' => ['string', 'zip_entry'=>'resource'],
'zip_entry_open' => ['bool', 'zip_dp'=>'resource', 'zip_entry'=>'resource', 'mode='=>'string'],
'zip_entry_read' => ['string|false', 'zip_entry'=>'resource', 'len='=>'int'],
'zip_open' => ['resource|int|false', 'filename'=>'string'],
'zip_read' => ['resource', 'zip'=>'resource'],
'ZipArchive::addEmptyDir' => ['bool', 'dirname'=>'string', 'flags='=>'int'],
'ZipArchive::addFile' => ['bool', 'filepath'=>'string', 'entryname='=>'string', 'start='=>'int', 'length='=>'int', 'flags='=>'int'],
'ZipArchive::addFromString' => ['bool', 'name'=>'string', 'content'=>'string', 'flags='=>'int'],
'ZipArchive::addGlob' => ['array|false', 'pattern'=>'string', 'flags='=>'int', 'options='=>'array'],
'ZipArchive::addPattern' => ['array|false', 'pattern'=>'string', 'path='=>'string', 'options='=>'array'],
'ZipArchive::clearError' => ['void'],
'ZipArchive::close' => ['bool'],
'ZipArchive::count' => ['int'],
'ZipArchive::deleteIndex' => ['bool', 'index'=>'int'],
'ZipArchive::deleteName' => ['bool', 'name'=>'string'],
'ZipArchive::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string[]|string|null'],
'ZipArchive::getArchiveComment' => ['string|false', 'flags='=>'int'],
'ZipArchive::getCommentIndex' => ['string|false', 'index'=>'int', 'flags='=>'int'],
'ZipArchive::getCommentName' => ['string|false', 'name'=>'string', 'flags='=>'int'],
'ZipArchive::getExternalAttributesIndex' => ['bool', 'index'=>'int', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'],
'ZipArchive::getExternalAttributesName' => ['bool', 'name'=>'string', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'],
'ZipArchive::getFromIndex' => ['string|false', 'index'=>'int', 'len='=>'int', 'flags='=>'int'],
'ZipArchive::getFromName' => ['string|false', 'name'=>'string', 'len='=>'int', 'flags='=>'int'],
'ZipArchive::getNameIndex' => ['string|false', 'index'=>'int', 'flags='=>'int'],
'ZipArchive::getStatusString' => ['string'],
'ZipArchive::getStream' => ['resource|false', 'name'=>'string'],
'ZipArchive::getStreamIndex' => ['resource|false', 'index'=>'int', 'flags='=>'int'],
'ZipArchive::getStreamName' => ['resource|false', 'name'=>'string', 'flags='=>'int'],
'ZipArchive::isCompressionMethodSupported' => ['bool', 'method'=>'int', 'encode='=>'bool'],
'ZipArchive::isEncryptionMethodSupported' => ['bool', 'method'=>'int', 'encode='=>'bool'],
'ZipArchive::locateName' => ['int|false', 'name'=>'string', 'flags='=>'int'],
'ZipArchive::open' => ['int|bool', 'filename'=>'string', 'flags='=>'int'],
'ZipArchive::registerCancelCallback' => ['bool', 'callback'=>'callable'],
'ZipArchive::registerProgressCallback' => ['bool', 'rate'=>'float', 'callback'=>'callable'],
'ZipArchive::renameIndex' => ['bool', 'index'=>'int', 'new_name'=>'string'],
'ZipArchive::renameName' => ['bool', 'name'=>'string', 'new_name'=>'string'],
'ZipArchive::replaceFile' => ['bool', 'filepath'=>'string', 'index'=>'int', 'start='=>'int', 'length='=>'int', 'flags='=>'int'],
'ZipArchive::setArchiveComment' => ['bool', 'comment'=>'string'],
'ZipArchive::setCommentIndex' => ['bool', 'index'=>'int', 'comment'=>'string'],
'ZipArchive::setCommentName' => ['bool', 'name'=>'string', 'comment'=>'string'],
'ZipArchive::setCompressionIndex' => ['bool', 'index'=>'int', 'comp_method'=>'int', 'comp_flags='=>'int'],
'ZipArchive::setCompressionName' => ['bool', 'name'=>'string', 'comp_method'=>'int', 'comp_flags='=>'int'],
'ZipArchive::setEncryptionIndex' => ['bool', 'index'=>'int', 'method'=>'string', 'password='=>'?string'],
'ZipArchive::setEncryptionName' => ['bool', 'name'=>'string', 'method'=>'int', 'password='=>'?string'],
'ZipArchive::setExternalAttributesIndex' => ['bool', 'index'=>'int', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'],
'ZipArchive::setExternalAttributesName' => ['bool', 'name'=>'string', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'],
'ZipArchive::setMtimeIndex' => ['bool', 'index'=>'int', 'timestamp'=>'int', 'flags='=>'int'],
'ZipArchive::setMtimeName' => ['bool', 'name'=>'string', 'timestamp'=>'int', 'flags='=>'int'],
'ZipArchive::setPassword' => ['bool', 'password'=>'string'],
'ZipArchive::statIndex' => ['array|false', 'index'=>'int', 'flags='=>'int'],
'ZipArchive::statName' => ['array|false', 'name'=>'string', 'flags='=>'int'],
'ZipArchive::unchangeAll' => ['bool'],
'ZipArchive::unchangeArchive' => ['bool'],
'ZipArchive::unchangeIndex' => ['bool', 'index'=>'int'],
'ZipArchive::unchangeName' => ['bool', 'name'=>'string'],
'zlib_decode' => ['string|false', 'data'=>'string', 'max_length='=>'int'],
'zlib_encode' => ['string', 'data'=>'string', 'encoding'=>'int', 'level='=>'string|int'],
'zlib_get_coding_type' => ['string|false'],
'ZMQ::__construct' => ['void'],
'ZMQContext::__construct' => ['void', 'io_threads='=>'int', 'is_persistent='=>'bool'],
'ZMQContext::getOpt' => ['int|string', 'key'=>'string'],
'ZMQContext::getSocket' => ['ZMQSocket', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'],
'ZMQContext::isPersistent' => ['bool'],
'ZMQContext::setOpt' => ['ZMQContext', 'key'=>'int', 'value'=>'mixed'],
'ZMQDevice::__construct' => ['void', 'frontend'=>'ZMQSocket', 'backend'=>'ZMQSocket', 'listener='=>'ZMQSocket'],
'ZMQDevice::getIdleTimeout' => ['ZMQDevice'],
'ZMQDevice::getTimerTimeout' => ['ZMQDevice'],
'ZMQDevice::run' => ['void'],
'ZMQDevice::setIdleCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'],
'ZMQDevice::setIdleTimeout' => ['ZMQDevice', 'timeout'=>'int'],
'ZMQDevice::setTimerCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'],
'ZMQDevice::setTimerTimeout' => ['ZMQDevice', 'timeout'=>'int'],
'ZMQPoll::add' => ['string', 'entry'=>'mixed', 'type'=>'int'],
'ZMQPoll::clear' => ['ZMQPoll'],
'ZMQPoll::count' => ['int'],
'ZMQPoll::getLastErrors' => ['array'],
'ZMQPoll::poll' => ['int', '&w_readable'=>'array', '&w_writable'=>'array', 'timeout='=>'int'],
'ZMQPoll::remove' => ['bool', 'item'=>'mixed'],
'ZMQSocket::__construct' => ['void', 'context'=>'ZMQContext', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'],
'ZMQSocket::bind' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'],
'ZMQSocket::connect' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'],
'ZMQSocket::disconnect' => ['ZMQSocket', 'dsn'=>'string'],
'ZMQSocket::getEndpoints' => ['array'],
'ZMQSocket::getPersistentId' => ['?string'],
'ZMQSocket::getSocketType' => ['int'],
'ZMQSocket::getSockOpt' => ['int|string', 'key'=>'string'],
'ZMQSocket::isPersistent' => ['bool'],
'ZMQSocket::recv' => ['string', 'mode='=>'int'],
'ZMQSocket::recvMulti' => ['string[]', 'mode='=>'int'],
'ZMQSocket::send' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'],
'ZMQSocket::send\'1' => ['ZMQSocket', 'message'=>'string', 'mode='=>'int'],
'ZMQSocket::sendmulti' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'],
'ZMQSocket::setSockOpt' => ['ZMQSocket', 'key'=>'int', 'value'=>'mixed'],
'ZMQSocket::unbind' => ['ZMQSocket', 'dsn'=>'string'],
'Zookeeper::addAuth' => ['bool', 'scheme'=>'string', 'cert'=>'string', 'completion_cb='=>'callable'],
'Zookeeper::close' => ['void'],
'Zookeeper::connect' => ['void', 'host'=>'string', 'watcher_cb='=>'callable', 'recv_timeout='=>'int'],
'Zookeeper::create' => ['string', 'path'=>'string', 'value'=>'string', 'acls'=>'array', 'flags='=>'int'],
'Zookeeper::delete' => ['bool', 'path'=>'string', 'version='=>'int'],
'Zookeeper::exists' => ['bool', 'path'=>'string', 'watcher_cb='=>'callable'],
'Zookeeper::get' => ['string', 'path'=>'string', 'watcher_cb='=>'callable', 'stat='=>'array', 'max_size='=>'int'],
'Zookeeper::getAcl' => ['array', 'path'=>'string'],
'Zookeeper::getChildren' => ['array|false', 'path'=>'string', 'watcher_cb='=>'callable'],
'Zookeeper::getClientId' => ['int'],
'Zookeeper::getConfig' => ['ZookeeperConfig'],
'Zookeeper::getRecvTimeout' => ['int'],
'Zookeeper::getState' => ['int'],
'Zookeeper::isRecoverable' => ['bool'],
'Zookeeper::set' => ['bool', 'path'=>'string', 'value'=>'string', 'version='=>'int', 'stat='=>'array'],
'Zookeeper::setAcl' => ['bool', 'path'=>'string', 'version'=>'int', 'acl'=>'array'],
'Zookeeper::setDebugLevel' => ['bool', 'logLevel'=>'int'],
'Zookeeper::setDeterministicConnOrder' => ['bool', 'yesOrNo'=>'bool'],
'Zookeeper::setLogStream' => ['bool', 'stream'=>'resource'],
'Zookeeper::setWatcher' => ['bool', 'watcher_cb'=>'callable'],
'zookeeper_dispatch' => ['void'],
'ZookeeperConfig::add' => ['void', 'members'=>'string', 'version='=>'int', 'stat='=>'array'],
'ZookeeperConfig::get' => ['string', 'watcher_cb='=>'callable', 'stat='=>'array'],
'ZookeeperConfig::remove' => ['void', 'id_list'=>'string', 'version='=>'int', 'stat='=>'array'],
'ZookeeperConfig::set' => ['void', 'members'=>'string', 'version='=>'int', 'stat='=>'array'],
];
<?php // phpcs:ignoreFile

/**
 * This contains the information needed to convert the function signatures for php 7.4 to php 7.3 (and vice versa)
 *
 * This file has three sections.
 * The 'added' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that do not exist in php 7.3
 * The 'removed' section contains the signatures that were removed in php 7.4.
 * The 'changed' section contains functions for which the signature has changed for php 7.4.
 *     Each function in the 'changed' section has an 'old' and a 'new' section,
 *     representing the function as it was in PHP 7.3 and in PHP 7.4, respectively
 *
 * @see CallMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
  'added' => [
    'ReflectionProperty::getType' => ['?ReflectionType'],
    'mb_str_split' => ['list<string>|false', 'string'=>'string', 'length='=>'positive-int', 'encoding='=>'string'],
    'openssl_x509_verify' => ['int', 'certificate'=>'string|resource', 'public_key'=>'string|array|resource'],
  ],
  'changed' => [
    'Locale::lookup' => [
      'old' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'string'],
      'new' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'?string'],
    ],
    'array_merge' => [
        'old' => ['array', '...arrays'=>'array'],
        'new' => ['array', '...arrays='=>'array'],
    ],
    'array_merge_recursive' => [
        'old' => ['array', '...arrays'=>'array'],
        'new' => ['array', '...arrays='=>'array'],
    ],
    'gzread' => [
      'old' => ['string|0', 'stream'=>'resource', 'length'=>'int'],
      'new' => ['string|false', 'stream'=>'resource', 'length'=>'int'],
    ],
    'locale_lookup' => [
      'old' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'string'],
      'new' => ['?string', 'languageTag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'defaultLocale='=>'?string'],
    ],
    'openssl_random_pseudo_bytes' => [
      'old' => ['string|false', 'length'=>'int', '&w_strong_result='=>'bool'],
      'new' => ['string', 'length'=>'int', '&w_strong_result='=>'bool'],
    ],
    'password_hash' => [
      'old' => ['string|false', 'password'=>'string', 'algo'=>'int', 'options='=>'array'],
      'new' => ['string|false', 'password'=>'string', 'algo'=>'int|string|null', 'options='=>'array'],
    ],
    'password_needs_rehash' => [
      'old' => ['bool', 'hash'=>'string', 'algo'=>'int', 'options='=>'array'],
      'new' => ['bool', 'hash'=>'string', 'algo'=>'int|string|null', 'options='=>'array'],
    ],
    'proc_open' => [
      'old' => ['resource|false', 'command'=>'string', 'descriptor_spec'=>'array', '&pipes'=>'resource[]', 'cwd='=>'?string', 'env_vars='=>'?array', 'options='=>'?array'],
      'new' => ['resource|false', 'command'=>'string|array', 'descriptor_spec'=>'array', '&pipes'=>'resource[]', 'cwd='=>'?string', 'env_vars='=>'?array', 'options='=>'?array'],
    ],
    'strip_tags' => [
      'old' => ['string', 'string'=>'string', 'allowed_tags='=>'string'],
      'new' => ['string', 'string'=>'string', 'allowed_tags='=>'string|list<non-empty-string>'],
    ],
  ],
  'removed' => [
  ],
];
<?php // phpcs:ignoreFile

/**
 * This contains the information needed to convert the function signatures for php 8.1 to php 8.0 (and vice versa)
 *
 * This file has three sections.
 * The 'added' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that do not exist in php 8.0
 * The 'removed' section contains the signatures that were removed in php 8.1
 * The 'changed' section contains functions for which the signature has changed for php 8.1.
 *     Each function in the 'changed' section has an 'old' and a 'new' section,
 *     representing the function as it was in PHP 8.0 and in PHP 8.1, respectively
 *
 * @see CallMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
  'added' => [
    'array_is_list' => ['bool', 'array' => 'array'],
    'enum_exists' => ['bool', 'enum' => 'string', 'autoload=' => 'bool'],
    'fsync' => ['bool', 'stream' => 'resource'],
    'fdatasync' => ['bool', 'stream' => 'resource'],
    'imageavif' => ['bool', 'image'=>'GdImage', 'file='=>'resource|string|null', 'quality='=>'int', 'speed='=>'int'],
    'imagecreatefromavif' => ['false|GdImage', 'filename'=>'string'],
    'mysqli_fetch_column' => ['null|int|float|string|false', 'result'=>'mysqli_result', 'column='=>'int'],
    'mysqli_result::fetch_column' => ['null|int|float|string|false', 'column='=>'int'],
    'CURLStringFile::__construct' => ['void', 'data'=>'string', 'postname'=>'string', 'mime='=>'string'],
    'Fiber::__construct' => ['void', 'callback'=>'callable'],
    'Fiber::start' => ['mixed', '...args'=>'mixed'],
    'Fiber::resume' => ['mixed', 'value='=>'null|mixed'],
    'Fiber::throw' => ['mixed', 'exception'=>'Throwable'],
    'Fiber::isStarted' => ['bool'],
    'Fiber::isSuspended' => ['bool'],
    'Fiber::isRunning' => ['bool'],
    'Fiber::isTerminated' => ['bool'],
    'Fiber::getReturn' => ['mixed'],
    'Fiber::getCurrent' => ['?self'],
    'Fiber::suspend' => ['mixed', 'value='=>'null|mixed'],
    'FiberError::__construct' => ['void'],
    'GMP::__serialize' => ['array'],
    'GMP::__unserialize' => ['void', 'data'=>'array'],
    'ReflectionClass::isEnum' => ['bool'],
    'ReflectionEnum::getBackingType' => ['?ReflectionType'],
    'ReflectionEnum::getCase' => ['ReflectionEnumUnitCase', 'name' => 'string'],
    'ReflectionEnum::getCases' => ['list<ReflectionEnumUnitCase>'],
    'ReflectionEnum::hasCase' => ['bool', 'name' => 'string'],
    'ReflectionEnum::isBacked' => ['bool'],
    'ReflectionEnumUnitCase::getEnum' => ['ReflectionEnum'],
    'ReflectionEnumUnitCase::getValue' => ['UnitEnum'],
    'ReflectionEnumBackedCase::getBackingValue' => ['string|int'],
    'ReflectionFunctionAbstract::getTentativeReturnType' => ['?ReflectionType'],
    'ReflectionFunctionAbstract::hasTentativeReturnType' => ['bool'],
    'ReflectionFunctionAbstract::isStatic' => ['bool'],
    'ReflectionObject::isEnum' => ['bool'],
    'sodium_crypto_stream_xchacha20' => ['non-empty-string', 'length'=>'positive-int', 'nonce'=>'non-empty-string', 'key'=>'non-empty-string'],
    'sodium_crypto_stream_xchacha20_keygen' => ['non-empty-string'],
    'sodium_crypto_stream_xchacha20_xor' => ['string', 'message'=>'string', 'nonce'=>'non-empty-string', 'key'=>'non-empty-string'],
  ],

  'changed' => [
    'DOMDocument::createComment' => [
      'old' => ['DOMComment|false', 'data'=>'string'],
      'new' => ['DOMComment', 'data'=>'string'],
    ],
    'DOMDocument::createDocumentFragment' => [
      'old' => ['DOMDocumentFragment|false'],
      'new' => ['DOMDocumentFragment'],
    ],
    'finfo_buffer' => [
       'old' => ['string|false', 'finfo'=>'resource', 'string'=>'string', 'flags='=>'int', 'context='=>'resource'],
       'new' => ['string|false', 'finfo'=>'finfo', 'string'=>'string', 'flags='=>'int', 'context='=>'resource'],
    ],
    'finfo_close' => [
        'old' => ['bool', 'finfo'=>'resource'],
        'new' => ['bool', 'finfo'=>'finfo'],
    ],
    'finfo_file' => [
        'old' => ['string|false', 'finfo'=>'resource', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
        'new' => ['string|false', 'finfo'=>'finfo', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'],
    ],
    'finfo_open' => [
        'old' => ['resource|false', 'flags='=>'int', 'magic_database='=>'?string'],
        'new' => ['finfo|false', 'flags='=>'int', 'magic_database='=>'?string'],
    ],
    'finfo_set_flags' => [
        'old' => ['bool', 'finfo'=>'resource', 'flags'=>'int'],
        'new' => ['bool', 'finfo'=>'finfo', 'flags'=>'int'],
    ],
    'fputcsv' => [
        'old' => ['int|false', 'stream'=>'resource', 'fields'=>'array<array-key, null|scalar|Stringable>', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string'],
        'new' => ['int|false', 'stream'=>'resource', 'fields'=>'array<array-key, null|scalar|Stringable>', 'separator='=>'string', 'enclosure='=>'string', 'escape='=>'string', 'eol='=>'string'],
    ],
    'ftp_connect' => [
      'old' => ['resource|false', 'hostname' => 'string', 'port=' => 'int', 'timeout=' => 'int'],
      'new' => ['FTP\Connection|false', 'hostname' => 'string', 'port=' => 'int', 'timeout=' => 'int'],
    ],
    'ftp_ssl_connect' => [
      'old' => ['resource|false', 'hostname' => 'string', 'port=' => 'int', 'timeout=' => 'int'],
      'new' => ['FTP\Connection|false', 'hostname' => 'string', 'port=' => 'int', 'timeout=' => 'int'],
    ],
    'ftp_login' => [
      'old' => ['bool', 'ftp' => 'resource', 'username' => 'string', 'password' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'username' => 'string', 'password' => 'string'],
    ],
    'ftp_pwd' => [
      'old' => ['string|false', 'ftp' => 'resource'],
      'new' => ['string|false', 'ftp' => 'FTP\Connection'],
    ],
    'ftp_cdup' => [
      'old' => ['bool', 'ftp' => 'resource'],
      'new' => ['bool', 'ftp' => 'FTP\Connection'],
    ],
    'ftp_chdir' => [
      'old' => ['bool', 'ftp' => 'resource', 'directory' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'directory' => 'string'],
    ],
    'ftp_exec' => [
      'old' => ['bool', 'ftp' => 'resource', 'command' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'command' => 'string'],
    ],
    'ftp_raw' => [
      'old' => ['?array', 'ftp' => 'resource', 'command' => 'string'],
      'new' => ['?array', 'ftp' => 'FTP\Connection', 'command' => 'string'],
    ],
    'ftp_mkdir' => [
      'old' => ['string|false', 'ftp' => 'resource', 'directory' => 'string'],
      'new' => ['string|false', 'ftp' => 'FTP\Connection', 'directory' => 'string'],
    ],
    'ftp_rmdir' => [
      'old' => ['bool', 'ftp' => 'resource', 'directory' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'directory' => 'string'],
    ],
    'ftp_chmod' => [
      'old' => ['int|false', 'ftp' => 'resource', 'permissions' => 'int', 'filename' => 'string'],
      'new' => ['int|false', 'ftp' => 'FTP\Connection', 'permissions' => 'int', 'filename' => 'string'],
    ],
    'ftp_alloc' => [
      'old' => ['bool', 'ftp' => 'resource', 'size' => 'int', '&w_response=' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'size' => 'int', '&w_response=' => 'string'],
    ],
    'ftp_nlist' => [
      'old' => ['array|false', 'ftp' => 'resource', 'directory' => 'string'],
      'new' => ['array|false', 'ftp' => 'FTP\Connection', 'directory' => 'string'],
    ],
    'ftp_rawlist' => [
      'old' => ['array|false', 'ftp' => 'resource', 'directory' => 'string', 'recursive=' => 'bool'],
      'new' => ['array|false', 'ftp' => 'FTP\Connection', 'directory' => 'string', 'recursive=' => 'bool'],
    ],
    'ftp_mlsd' => [
      'old' => ['array|false', 'ftp' => 'resource', 'directory' => 'string'],
      'new' => ['array|false', 'ftp' => 'FTP\Connection', 'directory' => 'string'],
    ],
    'ftp_systype' => [
      'old' => ['string|false', 'ftp' => 'resource'],
      'new' => ['string|false', 'ftp' => 'FTP\Connection'],
    ],
    'ftp_fget' => [
      'old' => ['bool', 'ftp' => 'resource', 'stream' => 'resource', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'stream' => 'resource', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_nb_fget' => [
      'old' => ['int', 'ftp' => 'resource', 'stream' => 'resource', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['int', 'ftp' => 'FTP\Connection', 'stream' => 'resource', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_pasv' => [
      'old' => ['bool', 'ftp' => 'resource', 'enable' => 'bool'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'enable' => 'bool'],
    ],
    'ftp_get' => [
      'old' => ['bool', 'ftp' => 'resource', 'local_filename' => 'string', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'local_filename' => 'string', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_nb_get' => [
      'old' => ['int', 'ftp' => 'resource', 'local_filename' => 'string', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['int', 'ftp' => 'FTP\Connection', 'local_filename' => 'string', 'remote_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_nb_continue' => [
      'old' => ['int', 'ftp' => 'resource'],
      'new' => ['int', 'ftp' => 'FTP\Connection'],
    ],
    'ftp_fput' => [
      'old' => ['bool', 'ftp' => 'resource', 'remote_filename' => 'string', 'stream' => 'resource', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'remote_filename' => 'string', 'stream' => 'resource', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_nb_fput' => [
      'old' => ['int', 'ftp' => 'resource', 'remote_filename' => 'string', 'stream' => 'resource', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['int', 'ftp' => 'FTP\Connection', 'remote_filename' => 'string', 'stream' => 'resource', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_put' => [
      'old' => ['bool', 'ftp' => 'resource', 'remote_filename' => 'string', 'local_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'remote_filename' => 'string', 'local_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_append' => [
      'old' => ['bool', 'ftp' => 'resource', 'remote_filename' => 'string', 'local_filename' => 'string', 'mode=' => 'int'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'remote_filename' => 'string', 'local_filename' => 'string', 'mode=' => 'int'],
    ],
    'ftp_nb_put' => [
      'old' => ['int', 'ftp' => 'resource', 'remote_filename' => 'string', 'local_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
      'new' => ['int', 'ftp' => 'FTP\Connection', 'remote_filename' => 'string', 'local_filename' => 'string', 'mode=' => 'int', 'offset=' => 'int'],
    ],
    'ftp_size' => [
      'old' => ['int', 'ftp' => 'resource', 'filename' => 'string'],
      'new' => ['int', 'ftp' => 'FTP\Connection', 'filename' => 'string'],
    ],
    'ftp_mdtm' => [
      'old' => ['int', 'ftp' => 'resource', 'filename' => 'string'],
      'new' => ['int', 'ftp' => 'FTP\Connection', 'filename' => 'string'],
    ],
    'ftp_rename' => [
      'old' => ['bool', 'ftp' => 'resource', 'from' => 'string', 'to' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'from' => 'string', 'to' => 'string'],
    ],
    'ftp_delete' => [
      'old' => ['bool', 'ftp' => 'resource', 'filename' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'filename' => 'string'],
    ],
    'ftp_site' => [
      'old' => ['bool', 'ftp' => 'resource', 'command' => 'string'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'command' => 'string'],
    ],
    'ftp_close' => [
      'old' => ['bool', 'ftp' => 'resource'],
      'new' => ['bool', 'ftp' => 'FTP\Connection'],
    ],
    'ftp_quit' => [
      'old' => ['bool', 'ftp' => 'resource'],
      'new' => ['bool', 'ftp' => 'FTP\Connection'],
    ],
    'ftp_set_option' => [
      'old' => ['bool', 'ftp' => 'resource', 'option' => 'int', 'value' => 'mixed'],
      'new' => ['bool', 'ftp' => 'FTP\Connection', 'option' => 'int', 'value' => 'mixed'],
    ],
    'ftp_get_option' => [
      'old' => ['int|false', 'ftp' => 'resource', 'option' => 'int'],
      'new' => ['int|false', 'ftp' => 'FTP\Connection', 'option' => 'int'],
    ],
    'hash' => [
      'old' => ['non-empty-string', 'algo'=>'string', 'data'=>'string', 'binary='=>'bool'],
      'new' => ['non-empty-string', 'algo'=>'string', 'data'=>'string', 'binary='=>'bool', 'options='=>'array{seed:scalar}'],
    ],
    'hash_file' => [
      'old' => ['non-empty-string|false', 'algo'=>'string', 'filename'=>'string', 'binary='=>'bool'],
      'new' => ['non-empty-string|false', 'algo'=>'string', 'filename'=>'string', 'binary='=>'bool', 'options='=>'array{seed:scalar}'],
    ],
    'hash_init' => [
      'old' => ['HashContext', 'algo'=>'string', 'flags='=>'int', 'key='=>'string'],
      'new' => ['HashContext', 'algo'=>'string', 'flags='=>'int', 'key='=>'string', 'options='=>'array{seed:scalar}'],
    ],
    'imageloadfont' => [
      'old' => ['int|false', 'filename'=>'string'],
      'new' => ['GdFont|false', 'filename'=>'string'],
    ],
    'imap_append' => [
        'old' => ['bool', 'imap'=>'resource', 'folder'=>'string', 'message'=>'string', 'options='=>'?string', 'internal_date='=>'?string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'folder'=>'string', 'message'=>'string', 'options='=>'?string', 'internal_date='=>'?string'],
    ],
    'imap_body' => [
        'old' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
        'new' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
    ],
    'imap_bodystruct' => [
        'old' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'section'=>'string'],
        'new' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'section'=>'string'],
    ],
    'imap_check' => [
        'old' => ['stdClass|false', 'imap'=>'resource'],
        'new' => ['stdClass|false', 'imap'=>'IMAP\Connection'],
    ],
    'imap_clearflag_full' => [
        'old' => ['bool', 'imap'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
    ],
    'imap_close' => [
        'old' => ['bool', 'imap'=>'resource', 'flags='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'flags='=>'int'],
    ],
    'imap_create' => [
        'old' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
    ],
    'imap_createmailbox' => [
        'old' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
    ],
    'imap_delete' => [
        'old' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'flags='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'flags='=>'int'],
    ],
    'imap_deletemailbox' => [
        'old' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
    ],
    'imap_expunge' => [
        'old' => ['bool', 'imap'=>'resource'],
        'new' => ['bool', 'imap'=>'IMAP\Connection'],
    ],
    'imap_fetch_overview' => [
        'old' => ['array|false', 'imap'=>'resource', 'sequence'=>'string', 'flags='=>'int'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'sequence'=>'string', 'flags='=>'int'],
    ],
    'imap_fetchbody' => [
        'old' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
        'new' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
    ],
    'imap_fetchheader' => [
        'old' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
        'new' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
    ],
    'imap_fetchmime' => [
        'old' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
        'new' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'section'=>'string', 'flags='=>'int'],
    ],
    'imap_fetchstructure' => [
        'old' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
        'new' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
    ],
    'imap_fetchtext' => [
        'old' => ['string|false', 'imap'=>'resource', 'message_num'=>'int', 'flags='=>'int'],
        'new' => ['string|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'flags='=>'int'],
    ],
    'imap_gc' => [
        'old' => ['bool', 'imap'=>'resource', 'flags'=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'flags'=>'int'],
    ],
    'imap_get_quota' => [
        'old' => ['array|false', 'imap'=>'resource', 'quota_root'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'quota_root'=>'string'],
    ],
    'imap_get_quotaroot' => [
        'old' => ['array|false', 'imap'=>'resource', 'mailbox'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
    ],
    'imap_getacl' => [
        'old' => ['array|false', 'imap'=>'resource', 'mailbox'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
    ],
    'imap_getmailboxes' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
    ],
    'imap_getsubscribed' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
    ],
    'imap_headerinfo' => [
        'old' => ['stdClass|false', 'imap'=>'resource', 'message_num'=>'int', 'from_length='=>'int', 'subject_length='=>'int'],
        'new' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int', 'from_length='=>'int', 'subject_length='=>'int'],
    ],
    'imap_headers' => [
        'old' => ['array|false', 'imap'=>'resource'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection'],
    ],
    'imap_list' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
    ],
    'imap_listmailbox' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
    ],
    'imap_listscan' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
    ],
    'imap_listsubscribed' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
    ],
    'imap_lsub' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string'],
    ],
    'imap_mail_copy' => [
        'old' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
    ],
    'imap_mail_move' => [
        'old' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'mailbox'=>'string', 'flags='=>'int'],
    ],
    'imap_mailboxmsginfo' => [
        'old' => ['stdClass', 'imap'=>'resource'],
        'new' => ['stdClass', 'imap'=>'IMAP\Connection'],
    ],
    'imap_msgno' => [
        'old' => ['int', 'imap'=>'resource', 'message_uid'=>'int'],
        'new' => ['int', 'imap'=>'IMAP\Connection', 'message_uid'=>'int'],
    ],
    'imap_num_msg' => [
        'old' => ['int|false', 'imap'=>'resource'],
        'new' => ['int|false', 'imap'=>'IMAP\Connection'],
    ],
    'imap_num_recent' => [
        'old' => ['int', 'imap'=>'resource'],
        'new' => ['int', 'imap'=>'IMAP\Connection'],
    ],
    'imap_open' => [
        'old' => ['resource|false', 'mailbox'=>'string', 'user'=>'string', 'password'=>'string', 'flags='=>'int', 'retries='=>'int', 'options='=>'?array'],
        'new' => ['IMAP\Connection|false', 'mailbox'=>'string', 'user'=>'string', 'password'=>'string', 'flags='=>'int', 'retries='=>'int', 'options='=>'?array'],
    ],
    'imap_ping' => [
        'old' => ['bool', 'imap'=>'resource'],
        'new' => ['bool', 'imap'=>'IMAP\Connection'],
    ],
    'imap_rename' => [
        'old' => ['bool', 'imap'=>'resource', 'from'=>'string', 'to'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'from'=>'string', 'to'=>'string'],
    ],
    'imap_renamemailbox' => [
        'old' => ['bool', 'imap'=>'resource', 'from'=>'string', 'to'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'from'=>'string', 'to'=>'string'],
    ],
    'imap_reopen' => [
        'old' => ['bool', 'imap'=>'resource', 'mailbox'=>'string', 'flags='=>'int', 'retries='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string', 'flags='=>'int', 'retries='=>'int'],
    ],
    'imap_savebody' => [
        'old' => ['bool', 'imap'=>'resource', 'file'=>'string|resource', 'message_num'=>'int', 'section='=>'string', 'flags='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'file'=>'string|resource', 'message_num'=>'int', 'section='=>'string', 'flags='=>'int'],
    ],
    'imap_scan' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
    ],
    'imap_scanmailbox' => [
        'old' => ['array|false', 'imap'=>'resource', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'reference'=>'string', 'pattern'=>'string', 'content'=>'string'],
    ],
    'imap_search' => [
        'old' => ['array|false', 'imap'=>'resource', 'criteria'=>'string', 'flags='=>'int', 'charset='=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'criteria'=>'string', 'flags='=>'int', 'charset='=>'string'],
    ],
    'imap_set_quota' => [
        'old' => ['bool', 'imap'=>'resource', 'quota_root'=>'string', 'mailbox_size'=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'quota_root'=>'string', 'mailbox_size'=>'int'],
    ],
    'imap_setacl' => [
        'old' => ['bool', 'imap'=>'resource', 'mailbox'=>'string', 'user_id'=>'string', 'rights'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string', 'user_id'=>'string', 'rights'=>'string'],
    ],
    'imap_setflag_full' => [
        'old' => ['bool', 'imap'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'],
    ],
    'imap_sort' => [
        'old' => ['array|false', 'imap'=>'resource', 'criteria'=>'int', 'reverse'=>'int', 'flags='=>'int', 'search_criteria='=>'string', 'charset='=>'string'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'criteria'=>'int', 'reverse'=>'int', 'flags='=>'int', 'search_criteria='=>'string', 'charset='=>'string'],
    ],
    'imap_status' => [
        'old' => ['stdClass|false', 'imap'=>'resource', 'mailbox'=>'string', 'flags'=>'int'],
        'new' => ['stdClass|false', 'imap'=>'IMAP\Connection', 'mailbox'=>'string', 'flags'=>'int'],
    ],
    'imap_subscribe' => [
        'old' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
    ],
    'imap_thread' => [
        'old' => ['array|false', 'imap'=>'resource', 'flags='=>'int'],
        'new' => ['array|false', 'imap'=>'IMAP\Connection', 'flags='=>'int'],
    ],
    'imap_uid' => [
        'old' => ['int|false', 'imap'=>'resource', 'message_num'=>'int'],
        'new' => ['int|false', 'imap'=>'IMAP\Connection', 'message_num'=>'int'],
    ],
    'imap_undelete' => [
        'old' => ['bool', 'imap'=>'resource', 'message_nums'=>'string', 'flags='=>'int'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'message_nums'=>'string', 'flags='=>'int'],
    ],
    'imap_unsubscribe' => [
        'old' => ['bool', 'imap'=>'resource', 'mailbox'=>'string'],
        'new' => ['bool', 'imap'=>'IMAP\Connection', 'mailbox'=>'string'],
    ],
    'ini_alter' => [
      'old' => ['string|false', 'option'=>'string', 'value'=>'string'],
      'new' => ['string|false', 'option'=>'string', 'value'=>'string|int|float|bool|null'],
    ],
    'ini_set' => [
        'old' => ['string|false', 'option'=>'string', 'value'=>'string'],
        'new' => ['string|false', 'option'=>'string', 'value'=>'string|int|float|bool|null'],
    ],
    'IntlDateFormatter::__construct' => [
        'old' => ['void', 'locale'=>'?string', 'dateType'=>'int', 'timeType'=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
        'new' => ['void', 'locale'=>'?string', 'dateType='=>'int', 'timeType='=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
    ],
    'IntlDateFormatter::create' => [
      'old' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType'=>'int', 'timeType'=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
      'new' => ['?IntlDateFormatter', 'locale'=>'?string', 'dateType='=>'int', 'timeType='=>'int', 'timezone='=>'IntlTimeZone|DateTimeZone|string|null', 'calendar='=>'IntlCalendar|int|null', 'pattern='=>'?string'],
    ],
    'ldap_add' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_add_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
      'new' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_bind' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn='=>'string|null', 'password='=>'string|null'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn='=>'string|null', 'password='=>'string|null'],
    ],
    'ldap_bind_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn='=>'string|null', 'password='=>'string|null', 'controls='=>'?array'],
      'new' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn='=>'string|null', 'password='=>'string|null', 'controls='=>'?array'],
    ],
    'ldap_close' => [
      'old' => ['bool', 'ldap'=>'resource'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection'],
    ],
    'ldap_compare' => [
      'old' => ['bool|int', 'ldap'=>'resource', 'dn'=>'string', 'attribute'=>'string', 'value'=>'string'],
      'new' => ['bool|int', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'attribute'=>'string', 'value'=>'string', 'controls='=>'?array'],
    ],
    'ldap_connect' => [
      'old' => ['resource|false', 'uri='=>'?string', 'port='=>'int', 'wallet='=>'string', 'password='=>'string', 'auth_mode='=>'int'],
      'new' => ['LDAP\Connection|false', 'uri='=>'?string', 'port='=>'int', 'wallet='=>'string', 'password='=>'string', 'auth_mode='=>'int'],
    ],
    'ldap_count_entries' => [
      'old' => ['int', 'ldap'=>'resource', 'result'=>'resource'],
      'new' => ['int', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
    ],
    'ldap_delete' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'controls='=>'?array'],
    ],
    'ldap_delete_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'controls='=>'?array'],
      'new' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'controls='=>'?array'],
    ],
    'ldap_errno' => [
      'old' => ['int', 'ldap'=>'resource'],
      'new' => ['int', 'ldap'=>'LDAP\Connection'],
    ],
    'ldap_error' => [
      'old' => ['string', 'ldap'=>'resource'],
      'new' => ['string', 'ldap'=>'LDAP\Connection'],
    ],
    'ldap_exop' => [
      'old' => ['resource|bool', 'ldap'=>'resource', 'request_oid'=>'string', 'request_data='=>'?string', 'controls='=>'array|null', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
      'new' => ['LDAP\Result|bool', 'ldap'=>'LDAP\Connection', 'request_oid'=>'string', 'request_data='=>'?string', 'controls='=>'?array', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
    ],
    'ldap_exop_passwd' => [
      'old' => ['bool|string', 'ldap'=>'resource', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string', '&w_controls='=>'array|null'],
      'new' => ['bool|string', 'ldap'=>'LDAP\Connection', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string', '&w_controls='=>'array|null'],
    ],
    'ldap_exop_refresh' => [
      'old' => ['int|false', 'ldap'=>'resource', 'dn'=>'string', 'ttl'=>'int'],
      'new' => ['int|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'ttl'=>'int'],
    ],
    'ldap_exop_whoami' => [
      'old' => ['string|false', 'ldap'=>'resource'],
      'new' => ['string|false', 'ldap'=>'LDAP\Connection'],
    ],
    'ldap_first_attribute' => [
      'old' => ['string|false', 'ldap'=>'resource', 'entry'=>'resource'],
      'new' => ['string|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
    ],
    'ldap_first_entry' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'result'=>'resource'],
      'new' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
    ],
    'ldap_first_reference' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'result'=>'resource'],
      'new' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
    ],
    'ldap_free_result' => [
      'old' => ['bool', 'ldap'=>'resource'],
      'new' => ['bool', 'result'=>'LDAP\Result'],
    ],
    'ldap_get_attributes' => [
      'old' => ['array', 'ldap'=>'resource', 'entry'=>'resource'],
      'new' => ['array', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
    ],
    'ldap_get_dn' => [
      'old' => ['string|false', 'ldap'=>'resource', 'entry'=>'resource'],
      'new' => ['string|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
    ],
    'ldap_get_entries' => [
      'old' => ['array|false', 'ldap'=>'resource', 'result'=>'resource'],
      'new' => ['array|false', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result'],
    ],
    'ldap_get_option' => [
      'old' => ['bool', 'ldap'=>'resource', 'option'=>'int', '&w_value'=>'mixed'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'option'=>'int', '&w_value='=>'array|string|int|null'],
    ],
    'ldap_get_values' => [
      'old' => ['array|false', 'ldap'=>'resource', 'entry'=>'resource', 'attribute'=>'string'],
      'new' => ['array|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry', 'attribute'=>'string'],
    ],
    'ldap_get_values_len' => [
      'old' => ['array|false', 'ldap'=>'resource', 'entry'=>'resource', 'attribute'=>'string'],
      'new' => ['array|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry', 'attribute'=>'string'],
    ],
    'ldap_list' => [
      'old' => ['resource|false', 'ldap'=>'resource|array', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'],
      'new' => ['LDAP\Result|LDAP\Result[]|false', 'ldap'=>'LDAP\Connection|LDAP\Connection[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'controls='=>'?array'],
    ],
    'ldap_mod_add' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_mod_add_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
      'new' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_mod_del' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_mod_del_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
      'new' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_mod_replace' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_mod_replace_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
      'new' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_modify' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'entry'=>'array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'entry'=>'array', 'controls='=>'?array'],
    ],
    'ldap_modify_batch' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'modifications_info'=>'array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'modifications_info'=>'array', 'controls='=>'?array'],
    ],
    'ldap_next_attribute' => [
      'old' => ['string|false', 'ldap'=>'resource', 'entry'=>'resource'],
      'new' => ['string|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
    ],
    'ldap_next_entry' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'result'=>'resource'],
      'new' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
    ],
    'ldap_next_reference' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'entry'=>'resource'],
      'new' => ['LDAP\ResultEntry|false', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry'],
    ],
    'ldap_parse_exop' => [
      'old' => ['bool', 'ldap'=>'resource', 'result'=>'resource', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
    ],
    'ldap_parse_reference' => [
      'old' => ['bool', 'ldap'=>'resource', 'entry'=>'resource', 'referrals'=>'array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'entry'=>'LDAP\ResultEntry', '&w_referrals'=>'array'],
    ],
    'ldap_parse_result' => [
      'old' => ['bool', 'ldap'=>'resource', 'result'=>'resource', '&w_error_code'=>'int', '&w_matched_dn='=>'string', '&w_error_message='=>'string', '&w_referrals='=>'array', '&w_controls='=>'array'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'result'=>'LDAP\Result', '&w_error_code'=>'int', '&w_matched_dn='=>'string', '&w_error_message='=>'string', '&w_referrals='=>'array', '&w_controls='=>'array'],
    ],
    'ldap_read' => [
      'old' => ['resource|false', 'ldap'=>'resource|array', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'],
      'new' => ['LDAP\Result|LDAP\Result[]|false', 'ldap'=>'LDAP\Connection|LDAP\Connection[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'controls='=>'?array'],
    ],
    'ldap_rename' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'?array'],
    ],
    'ldap_rename_ext' => [
      'old' => ['resource|false', 'ldap'=>'resource', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'?array'],
      'new' => ['LDAP\Result|false', 'ldap'=>'LDAP\Connection', 'dn'=>'string', 'new_rdn'=>'string', 'new_parent'=>'string', 'delete_old_rdn'=>'bool', 'controls='=>'?array'],
    ],
    'ldap_sasl_bind' => [
      'old' => ['bool', 'ldap'=>'resource', 'dn='=>'?string', 'password='=>'?string', 'mech='=>'?string', 'realm='=>'?string', 'authc_id='=>'?string', 'authz_id='=>'?string', 'props='=>'?string'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'dn='=>'?string', 'password='=>'?string', 'mech='=>'?string', 'realm='=>'?string', 'authc_id='=>'?string', 'authz_id='=>'?string', 'props='=>'?string'],
    ],
    'ldap_search' => [
      'old' => ['resource|false', 'ldap'=>'resource|resource[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'],
      'new' => ['LDAP\Result|LDAP\Result[]|false', 'ldap'=>'LDAP\Connection|LDAP\Connection[]', 'base'=>'string', 'filter'=>'string', 'attributes='=>'array', 'attributes_only='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int', 'controls='=>'?array'],
    ],
    'ldap_set_option' => [
      'old' => ['bool', 'ldap'=>'resource|null', 'option'=>'int', 'value'=>'mixed'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection|null', 'option'=>'int', 'value'=>'mixed'],
    ],
    'ldap_set_rebind_proc' => [
      'old' => ['bool', 'ldap'=>'resource', 'callback'=>'?callable'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection', 'callback'=>'?callable'],
    ],
    'ldap_start_tls' => [
      'old' => ['bool', 'ldap'=>'resource'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection'],
    ],
    'ldap_unbind' => [
      'old' => ['bool', 'ldap'=>'resource'],
      'new' => ['bool', 'ldap'=>'LDAP\Connection'],
    ],
    'mysqli::connect' => [
      'old' => ['null|false', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
      'new' => ['bool', 'hostname='=>'string|null', 'username='=>'string|null', 'password='=>'string|null', 'database='=>'string|null', 'port='=>'int|null', 'socket='=>'string|null'],
    ],
    'mysqli_execute' => [
      'old' => ['bool', 'statement' => 'mysqli_stmt'],
      'new' => ['bool', 'statement' => 'mysqli_stmt', 'params=' => 'list<mixed>|null'],
    ],
    'mysqli_stmt_execute' => [
      'old' => ['bool', 'statement' => 'mysqli_stmt'],
      'new' => ['bool', 'statement' => 'mysqli_stmt', 'params=' => 'list<mixed>|null'],
    ],
    'mysqli_stmt::execute' => [
      'old' => ['bool'],
      'new' => ['bool', 'params=' => 'list<mixed>|null'],
    ],
    'openssl_decrypt' => [
      'old' => ['string|false', 'data'=>'string', 'cipher_algo'=>'string', 'passphrase'=>'string', 'options='=>'int', 'iv='=>'string', 'tag='=>'string', 'aad='=>'string'],
      'new' => ['string|false', 'data'=>'string', 'cipher_algo'=>'string', 'passphrase'=>'string', 'options='=>'int', 'iv='=>'string', 'tag='=>'?string', 'aad='=>'string'],
    ],
    'pg_affected_rows' => [
      'old' => ['int', 'result' => 'resource'],
      'new' => ['int', 'result' => '\PgSql\Result'],
    ],
    'pg_cancel_query' => [
      'old' => ['bool', 'connection' => 'resource'],
      'new' => ['bool', 'connection' => '\PgSql\Connection'],
    ],
    'pg_client_encoding' => [
      'old' => ['string', 'connection=' => '?resource'],
      'new' => ['string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_close' => [
      'old' => ['bool', 'connection=' => '?resource'],
      'new' => ['bool', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_connect' => [
      'old' => ['resource|false', 'connection_string' => 'string', 'flags=' => 'int'],
      'new' => ['\PgSql\Connection|false', 'connection_string' => 'string', 'flags=' => 'int'],
    ],
    'pg_connect_poll' => [
      'old' => ['int', 'connection' => 'resource'],
      'new' => ['int', 'connection' => '\PgSql\Connection'],
    ],
    'pg_connection_busy' => [
      'old' => ['bool', 'connection' => 'resource'],
      'new' => ['bool', 'connection' => '\PgSql\Connection'],
    ],
    'pg_connection_reset' => [
      'old' => ['bool', 'connection' => 'resource'],
      'new' => ['bool', 'connection' => '\PgSql\Connection'],
    ],
    'pg_connection_status' => [
      'old' => ['int', 'connection' => 'resource'],
      'new' => ['int', 'connection' => '\PgSql\Connection'],
    ],
    'pg_consume_input' => [
      'old' => ['bool', 'connection' => 'resource'],
      'new' => ['bool', 'connection' => '\PgSql\Connection'],
    ],
    'pg_convert' => [
      'old' => ['array|false', 'connection' => 'resource', 'table_name' => 'string', 'values' => 'array', 'flags=' => 'int'],
      'new' => ['array|false', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'values' => 'array', 'flags=' => 'int'],
    ],
    'pg_copy_from' => [
      'old' => ['bool', 'connection' => 'resource', 'table_name' => 'string', 'rows' => 'array', 'separator=' => 'string', 'null_as=' => 'string'],
      'new' => ['bool', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'rows' => 'array', 'separator=' => 'string', 'null_as=' => 'string'],
    ],
    'pg_copy_to' => [
      'old' => ['array|false', 'connection' => 'resource', 'table_name' => 'string', 'separator=' => 'string', 'null_as=' => 'string'],
      'new' => ['array|false', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'separator=' => 'string', 'null_as=' => 'string'],
    ],
    'pg_dbname' => [
      'old' => ['string', 'connection=' => '?resource'],
      'new' => ['string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_delete' => [
      'old' => ['string|bool', 'connection' => 'resource', 'table_name' => 'string', 'conditions' => 'array', 'flags=' => 'int'],
      'new' => ['string|bool', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'conditions' => 'array', 'flags=' => 'int'],
    ],
    'pg_end_copy' => [
      'old' => ['bool', 'connection=' => '?resource'],
      'new' => ['bool', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_escape_bytea' => [
      'old' => ['string', 'connection' => 'resource', 'string' => 'string'],
      'new' => ['string', 'connection' => '\PgSql\Connection', 'string' => 'string'],
    ],
    'pg_escape_identifier' => [
      'old' => ['string|false', 'connection' => 'resource', 'string' => 'string'],
      'new' => ['string|false', 'connection' => '\PgSql\Connection', 'string' => 'string'],
    ],
    'pg_escape_literal' => [
      'old' => ['string|false', 'connection' => 'resource', 'string' => 'string'],
      'new' => ['string|false', 'connection' => '\PgSql\Connection', 'string' => 'string'],
    ],
    'pg_escape_string' => [
      'old' => ['string', 'connection' => 'resource', 'string' => 'string'],
      'new' => ['string', 'connection' => '\PgSql\Connection', 'string' => 'string'],
    ],
    'pg_exec' => [
      'old' => ['resource|false', 'connection' => 'resource', 'query' => 'string'],
      'new' => ['\PgSql\Result|false', 'connection' => '\PgSql\Connection', 'query' => 'string'],
    ],
    'pg_execute' => [
      'old' => ['resource|false', 'connection' => 'resource', 'statement_name' => 'string', 'params' => 'array'],
      'new' => ['\PgSql\Result|false', 'connection' => '\PgSql\Connection', 'statement_name' => 'string', 'params' => 'array'],
    ],
    'pg_execute\'1' => [
      'old' => ['resource|false', 'connection' => 'string', 'statement_name' => 'array'],
      'new' => ['\PgSql\Result|false', 'connection' => 'string', 'statement_name' => 'array'],
    ],
    'pg_fetch_all' => [
      'old' => ['array<array>', 'result' => 'resource', 'result_type=' => 'int'],
      'new' => ['array<array>', 'result' => '\PgSql\Result', 'result_type=' => 'int'],
    ],
    'pg_fetch_all_columns' => [
      'old' => ['array', 'result' => 'resource', 'field=' => 'int'],
      'new' => ['array', 'result' => '\PgSql\Result', 'field=' => 'int'],
    ],
    'pg_fetch_array' => [
      'old' => ['array<string|null>|false', 'result' => 'resource', 'row=' => '?int', 'mode=' => 'int'],
      'new' => ['array<string|null>|false', 'result' => '\PgSql\Result', 'row=' => '?int', 'mode=' => 'int'],
    ],
    'pg_fetch_assoc' => [
      'old' => ['array<string, mixed>|false', 'result' => 'resource', 'row=' => '?int'],
      'new' => ['array<string, mixed>|false', 'result' => '\PgSql\Result', 'row=' => '?int'],
    ],
    'pg_fetch_object' => [
      'old' => ['object|false', 'result' => 'resource', 'row=' => '?int', 'class=' => 'string', 'constructor_args=' => 'array'],
      'new' => ['object|false', 'result' => '\PgSql\Result', 'row=' => '?int', 'class=' => 'string', 'constructor_args=' => 'array'],
    ],
    'pg_fetch_result' => [
      'old' => ['string|false|null', 'result' => 'resource', 'row' => 'string|int'],
      'new' => ['string|false|null', 'result' => '\PgSql\Result', 'row' => 'string|int'],
    ],
    'pg_fetch_result\'1' => [
      'old' => ['string|false|null', 'result' => 'resource', 'row' => '?int', 'field' => 'string|int'],
      'new' => ['string|false|null', 'result' => '\PgSql\Result', 'row' => '?int', 'field' => 'string|int'],
    ],
    'pg_fetch_row' => [
      'old' => ['array|false', 'result' => 'resource', 'row=' => '?int', 'mode=' => 'int'],
      'new' => ['array|false', 'result' => '\PgSql\Result', 'row=' => '?int', 'mode=' => 'int'],
    ],
    'pg_field_is_null' => [
      'old' => ['int|false', 'result' => 'resource', 'row'=>'string|int'],
      'new' => ['int|false', 'result' => '\PgSql\Result', 'row'=>'string|int'],
    ],
    'pg_field_is_null\'1' => [
      'old' => ['int|false', 'result' => 'resource', 'row' => 'int', 'field' => 'string|int'],
      'new' => ['int|false', 'result' => '\PgSql\Result', 'row' => 'int', 'field' => 'string|int'],
    ],
    'pg_field_name' => [
      'old' => ['string', 'result' => 'resource', 'field' => 'int'],
      'new' => ['string', 'result' => '\PgSql\Result', 'field' => 'int'],
    ],
    'pg_field_num' => [
      'old' => ['int', 'result' => 'resource', 'field' => 'string'],
      'new' => ['int', 'result' => '\PgSql\Result', 'field' => 'string'],
    ],
    'pg_field_prtlen' => [
      'old' => ['int|false', 'result' => 'resource', 'row' => 'string|int'],
      'new' => ['int|false', 'result' => '\PgSql\Result', 'row' => 'string|int'],
    ],
    'pg_field_prtlen\'1' => [
      'old' => ['int|false', 'result' => 'resource', 'row' => 'int', 'field' => 'string|int'],
      'new' => ['int|false', 'result' => '\PgSql\Result', 'row' => 'int', 'field' => 'string|int'],
    ],
    'pg_field_size' => [
      'old' => ['int', 'result' => 'resource', 'field' => 'int'],
      'new' => ['int', 'result' => '\PgSql\Result', 'field' => 'int'],
    ],
    'pg_field_table' => [
      'old' => ['string|int|false', 'result' => 'resource', 'field' => 'int', 'oid_only=' => 'bool'],
      'new' => ['string|int|false', 'result' => '\PgSql\Result', 'field' => 'int', 'oid_only=' => 'bool'],
    ],
    'pg_field_type' => [
      'old' => ['string', 'result' => 'resource', 'field' => 'int'],
      'new' => ['string', 'result' => '\PgSql\Result', 'field' => 'int'],
    ],
    'pg_field_type_oid' => [
      'old' => ['int|string', 'result' => 'resource', 'field' => 'int'],
      'new' => ['int|string', 'result' => '\PgSql\Result', 'field' => 'int'],
    ],
    'pg_flush' => [
      'old' => ['int|bool', 'connection' => 'resource'],
      'new' => ['int|bool', 'connection' => '\PgSql\Connection'],
    ],
    'pg_free_result' => [
      'old' => ['bool', 'result' => 'resource'],
      'new' => ['bool', 'result' => '\PgSql\Result'],
    ],
    'pg_get_notify' => [
      'old' => ['array|false', 'result' => 'resource', 'mode=' => 'int'],
      'new' => ['array|false', 'result' => '\PgSql\Result', 'mode=' => 'int'],
    ],
    'pg_get_pid' => [
      'old' => ['int', 'connection' => 'resource'],
      'new' => ['int', 'connection' => '\PgSql\Connection'],
    ],
    'pg_get_result' => [
      'old' => ['resource|false', 'connection=' => 'resource'],
      'new' => ['\PgSql\Result|false', 'connection=' => '\PgSql\Connection'],
    ],
    'pg_host' => [
      'old' => ['string', 'connection=' => 'resource'],
      'new' => ['string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_insert' => [
      'old' => ['resource|string|false', 'connection' => 'resource', 'table_name' => 'string', 'values' => 'array', 'flags=' => 'int'],
      'new' => ['\PgSql\Result|string|false', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'values' => 'array', 'flags=' => 'int'],
    ],
    'pg_last_error' => [
      'old' => ['string', 'connection=' => '?resource'],
      'new' => ['string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_last_notice' => [
      'old' => ['string|array|bool', 'connection' => 'resource', 'mode=' => 'int'],
      'new' => ['string|array|bool', 'connection' => '\PgSql\Connection', 'mode=' => 'int'],
    ],
    'pg_last_oid' => [
      'old' => ['string|int|false', 'result' => 'resource'],
      'new' => ['string|int|false', 'result' => '\PgSql\Result'],
    ],
    'pg_lo_close' => [
      'old' => ['bool', 'lob' => 'resource'],
      'new' => ['bool', 'lob' => '\PgSql\Lob'],
    ],
    'pg_lo_create' => [
      'old' => ['int|string|false', 'connection=' => 'resource', 'oid=' => 'int|string'],
      'new' => ['int|string|false', 'connection=' => '\PgSql\Connection', 'oid=' => 'int|string'],
    ],
    'pg_lo_export' => [
      'old' => ['bool', 'connection' => 'resource', 'oid' => 'int|string', 'filename' => 'string'],
      'new' => ['bool', 'connection' => '\PgSql\Connection', 'oid' => 'int|string', 'filename' => 'string'],
    ],
    'pg_lo_import' => [
      'old' => ['int|string|false', 'connection' => 'resource', 'filename' => 'string', 'oid' => 'string|int'],
      'new' => ['int|string|false', 'connection' => '\PgSql\Connection', 'filename' => 'string', 'oid' => 'string|int'],
    ],
    'pg_lo_open' => [
      'old' => ['resource|false', 'connection' => 'resource', 'oid' => 'int|string', 'mode' => 'string'],
      'new' => ['\PgSql\Lob|false', 'connection' => '\PgSql\Connection', 'oid' => 'int|string', 'mode' => 'string'],
    ],
    'pg_lo_open\'1' => [
      'old' => ['resource|false', 'connection' => 'int|string', 'oid' => 'string'],
      'new' => ['\PgSql\Lob|false', 'connection' => 'int|string', 'oid' => 'string'],
    ],
    'pg_lo_read' => [
      'old' => ['string|false', 'lob' => 'resource', 'length=' => 'int'],
      'new' => ['string|false', 'lob' => '\PgSql\Lob', 'length=' => 'int'],
    ],
    'pg_lo_read_all' => [
      'old' => ['int', 'lob' => 'resource'],
      'new' => ['int', 'lob' => '\PgSql\Lob'],
    ],
    'pg_lo_seek' => [
      'old' => ['bool', 'lob' => 'resource', 'offset' => 'int', 'whence=' => 'int'],
      'new' => ['bool', 'lob' => '\PgSql\Lob', 'offset' => 'int', 'whence=' => 'int'],
    ],
    'pg_lo_tell' => [
      'old' => ['int', 'lob' => 'resource'],
      'new' => ['int', 'lob' => '\PgSql\Lob'],
    ],
    'pg_lo_truncate' => [
      'old' => ['bool', 'lob' => 'resource', 'size' => 'int'],
      'new' => ['bool', 'lob' => '\PgSql\Lob', 'size' => 'int'],
    ],
    'pg_lo_unlink' => [
      'old' => ['bool', 'connection' => 'resource', 'oid' => 'int|string'],
      'new' => ['bool', 'connection' => '\PgSql\Connection', 'oid' => 'int|string'],
    ],
    'pg_lo_write' => [
      'old' => ['int|false', 'lob' => 'resource', 'data' => 'string', 'length=' => '?int'],
      'new' => ['int|false', 'lob' => '\PgSql\Lob', 'data' => 'string', 'length=' => '?int'],
    ],
    'pg_meta_data' => [
      'old' => ['array|false', 'connection' => 'resource', 'table_name' => 'string', 'extended=' => 'bool'],
      'new' => ['array|false', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'extended=' => 'bool'],
    ],
    'pg_num_fields' => [
      'old' => ['int', 'result' => 'resource'],
      'new' => ['int', 'result' => '\PgSql\Result'],
    ],
    'pg_num_rows' => [
      'old' => ['int', 'result' => 'resource'],
      'new' => ['int', 'result' => '\PgSql\Result'],
    ],
    'pg_options' => [
      'old' => ['string', 'connection=' => '?resource'],
      'new' => ['string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_parameter_status' => [
      'old' => ['string|false', 'connection' => 'resource', 'name' => 'string'],
      'new' => ['string|false', 'connection' => '\PgSql\Connection', 'name' => 'string'],
    ],
    'pg_pconnect' => [
      'old' => ['resource|false', 'connection_string' => 'string', 'flags=' => 'string', 'port=' => 'string|int', 'options=' => 'string', 'tty=' => 'string', 'database=' => 'string'],
      'new' => ['\PgSql\Connection|false', 'connection_string' => 'string', 'flags=' => 'string', 'port=' => 'string|int', 'options=' => 'string', 'tty=' => 'string', 'database=' => 'string'],
    ],
    'pg_ping' => [
      'old' => ['bool', 'connection=' => '?resource'],
      'new' => ['bool', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_port' => [
      'old' => ['string', 'connection=' => '?resource'],
      'new' => ['string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_prepare' => [
      'old' => ['resource|false', 'connection' => 'resource', 'statement_name' => 'string', 'query' => 'string'],
      'new' => ['\PgSql\Result|false', 'connection' => '\PgSql\Connection', 'statement_name' => 'string', 'query' => 'string'],
    ],
    'pg_prepare\'1' => [
      'old' => ['resource|false', 'connection' => 'string', 'statement_name' => 'string'],
      'new' => ['\PgSql\Result|false', 'connection' => 'string', 'statement_name' => 'string'],
    ],
    'pg_put_line' => [
      'old' => ['bool', 'connection' => 'resource', 'data' => 'string'],
      'new' => ['bool', 'connection' => '\PgSql\Connection', 'data' => 'string'],
    ],
    'pg_query' => [
      'old' => ['resource|false', 'connection' => 'resource', 'query' => 'string'],
      'new' => ['\PgSql\Result|false', 'connection' => '\PgSql\Connection', 'query' => 'string'],
    ],
    'pg_query\'1' => [
      'old' => ['resource|false', 'connection' => 'string'],
      'new' => ['\PgSql\Result|false', 'connection' => 'string'],
    ],
    'pg_query_params' => [
      'old' => ['resource|false', 'connection' => 'resource', 'query' => 'string', 'params' => 'array'],
      'new' => ['\PgSql\Result|false', 'connection' => '\PgSql\Connection', 'query' => 'string', 'params' => 'array'],
    ],
    'pg_query_params\'1' => [
      'old' => ['resource|false', 'connection' => 'string', 'query' => 'array'],
      'new' => ['\PgSql\Result|false', 'connection' => 'string', 'query' => 'array'],
    ],
    'pg_result_error' => [
      'old' => ['string|false', 'result' => 'resource'],
      'new' => ['string|false', 'result' => '\PgSql\Result'],
    ],
    'pg_result_error_field' => [
      'old' => ['string|false|null', 'result' => 'resource', 'field_code' => 'int'],
      'new' => ['string|false|null', 'result' => '\PgSql\Result', 'field_code' => 'int'],
    ],
    'pg_result_seek' => [
      'old' => ['bool', 'result' => 'resource', 'row' => 'int'],
      'new' => ['bool', 'result' => '\PgSql\Result', 'row' => 'int'],
    ],
    'pg_result_status' => [
      'old' => ['string|int', 'result' => 'resource', 'mode=' => 'int'],
      'new' => ['string|int', 'result' => '\PgSql\Result', 'mode=' => 'int'],
    ],
    'pg_select' => [
      'old' => ['string|array|false', 'connection' => 'resource', 'table_name' => 'string', 'assoc_array' => 'array', 'options=' => 'int', 'result_type=' => 'int'],
      'new' => ['string|array|false', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'assoc_array' => 'array', 'options=' => 'int', 'result_type=' => 'int'],
    ],
    'pg_send_execute' => [
      'old' => ['bool|int', 'connection' => 'resource', 'query' => 'string', 'params' => 'array'],
      'new' => ['bool|int', 'connection' => '\PgSql\Connection', 'query' => 'string', 'params' => 'array'],
    ],
    'pg_send_prepare' => [
      'old' => ['bool|int', 'connection' => 'resource', 'statement_name' => 'string', 'query' => 'string'],
      'new' => ['bool|int', 'connection' => '\PgSql\Connection', 'statement_name' => 'string', 'query' => 'string'],
    ],
    'pg_send_query' => [
      'old' => ['bool|int', 'connection' => 'resource', 'query' => 'string'],
      'new' => ['bool|int', 'connection' => '\PgSql\Connection', 'query' => 'string'],
    ],
    'pg_send_query_params' => [
      'old' => ['bool|int', 'connection' => 'resource', 'query' => 'string', 'params' => 'array'],
      'new' => ['bool|int', 'connection' => '\PgSql\Connection', 'query' => 'string', 'params' => 'array'],
    ],
    'pg_set_client_encoding' => [
      'old' => ['int', 'connection' => 'resource', 'encoding' => 'string'],
      'new' => ['int', 'connection' => '\PgSql\Connection', 'encoding' => 'string'],
    ],
    'pg_set_error_verbosity' => [
      'old' => ['int|false', 'connection' => 'resource', 'verbosity' => 'int'],
      'new' => ['int|false', 'connection' => '\PgSql\Connection', 'verbosity' => 'int'],
    ],
    'pg_socket' => [
      'old' => ['resource|false', 'connection' => 'resource'],
      'new' => ['resource|false', 'connection' => '\PgSql\Connection'],
    ],
    'pg_trace' => [
      'old' => ['bool', 'filename' => 'string', 'mode=' => 'string', 'connection=' => '?resource'],
      'new' => ['bool', 'filename' => 'string', 'mode=' => 'string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_transaction_status' => [
      'old' => ['int', 'connection' => 'resource'],
      'new' => ['int', 'connection' => '\PgSql\Connection'],
    ],
    'pg_tty' => [
      'old' => ['string', 'connection=' => '?resource'],
      'new' => ['string', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_untrace' => [
      'old' => ['bool', 'connection=' => '?resource'],
      'new' => ['bool', 'connection=' => '?\PgSql\Connection'],
    ],
    'pg_update' => [
      'old' => ['string|bool', 'connection' => 'resource', 'table_name' => 'string', 'values' => 'array', 'conditions' => 'array', 'flags=' => 'int'],
      'new' => ['string|bool', 'connection' => '\PgSql\Connection', 'table_name' => 'string', 'values' => 'array', 'conditions' => 'array', 'flags=' => 'int'],
    ],
    'pg_version' => [
      'old' => ['array', 'connection=' => '?resource'],
      'new' => ['array', 'connection=' => '?\PgSql\Connection'],
    ],
    'pspell_add_to_personal' => [
      'old' => ['bool', 'dictionary'=>'int', 'word'=>'string'],
      'new' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
    ],
    'pspell_add_to_session' => [
      'old' => ['bool', 'dictionary'=>'int', 'word'=>'string'],
      'new' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
    ],
    'pspell_check' => [
      'old' => ['bool', 'dictionary'=>'int', 'word'=>'string'],
      'new' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
    ],
    'pspell_clear_session' => [
      'old' => ['bool', 'dictionary'=>'int'],
      'new' => ['bool', 'dictionary'=>'PSpell\Dictionary'],
    ],
    'pspell_config_create' => [
      'old' => ['int', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string'],
      'new' => ['PSpell\Config', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string'],
    ],
    'pspell_config_data_dir' => [
      'old' => ['bool', 'config'=>'int', 'directory'=>'string'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'directory'=>'string'],
    ],
    'pspell_config_dict_dir' => [
      'old' => ['bool', 'config'=>'int', 'directory'=>'string'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'directory'=>'string'],
    ],
    'pspell_config_ignore' => [
      'old' => ['bool', 'config'=>'int', 'min_length'=>'int'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'min_length'=>'int'],
    ],
    'pspell_config_mode' => [
      'old' => ['bool', 'config'=>'int', 'mode'=>'int'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'mode'=>'int'],
    ],
    'pspell_config_personal' => [
      'old' => ['bool', 'config'=>'int', 'filename'=>'string'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'filename'=>'string'],
    ],
    'pspell_config_repl' => [
      'old' => ['bool', 'config'=>'int', 'filename'=>'string'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'filename'=>'string'],
    ],
    'pspell_config_runtogether' => [
      'old' => ['bool', 'config'=>'int', 'allow'=>'bool'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'allow'=>'bool'],
    ],
    'pspell_config_save_repl' => [
      'old' => ['bool', 'config'=>'int', 'save'=>'bool'],
      'new' => ['bool', 'config'=>'PSpell\Config', 'save'=>'bool'],
    ],
    'pspell_new' => [
      'old' => ['int|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
      'new' => ['PSpell\Dictionary|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
    ],
    'pspell_new_config' => [
      'old' => ['int|false', 'config'=>'int'],
      'new' => ['PSpell\Dictionary|false', 'config'=>'PSpell\Config'],
    ],
    'pspell_new_personal' => [
      'old' => ['int|false', 'filename'=>'string', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
      'new' => ['PSpell\Dictionary|false', 'filename'=>'string', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'],
    ],
    'pspell_save_wordlist' => [
      'old' => ['bool', 'dictionary'=>'int'],
      'new' => ['bool', 'dictionary'=>'PSpell\Dictionary'],
    ],
    'pspell_store_replacement' => [
      'old' => ['bool', 'dictionary'=>'int', 'misspelled'=>'string', 'correct'=>'string'],
      'new' => ['bool', 'dictionary'=>'PSpell\Dictionary', 'misspelled'=>'string', 'correct'=>'string'],
    ],
    'pspell_suggest' => [
      'old' => ['array', 'dictionary'=>'int', 'word'=>'string'],
      'new' => ['array', 'dictionary'=>'PSpell\Dictionary', 'word'=>'string'],
    ],
    'stream_select' => [
      'old' => ['int|false', '&rw_read'=>'?resource[]', '&rw_write'=>'?resource[]', '&rw_except'=>'?resource[]', 'seconds'=>'?int', 'microseconds='=>'int'],
      'new' => ['int|false', '&rw_read'=>'?resource[]', '&rw_write'=>'?resource[]', '&rw_except'=>'?resource[]', 'seconds'=>'?int', 'microseconds='=>'?int'],
    ],
  ],

  'removed' => [
    'ReflectionMethod::isStatic' => ['bool'],
  ],
];
<?php // phpcs:ignoreFile

/**
 * This contains the information needed to convert the function signatures for php 7.2 to php 7.1 (and vice versa)
 *
 * This file has three sections.
 * The 'added' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that do not exist in php 7.1
 * The 'removed' section contains the signatures that were removed in php 7.2.
 * The 'changed' section contains functions for which the signature has changed for php 7.2.
 *     Each function in the 'changed' section has an 'old' and a 'new' section,
 *     representing the function as it was in PHP 7.1 and in PHP 7.2, respectively
 *
 * @see CallMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
  'added' => [
    'DOMNodeList::count' => ['int'],
    'ReflectionClass::isIterable' => ['bool'],
    'ZipArchive::count' => ['int'],
    'ZipArchive::setEncryptionIndex' => ['bool', 'index'=>'int', 'method'=>'string', 'password='=>'string'],
    'ZipArchive::setEncryptionName' => ['bool', 'name'=>'string', 'method'=>'int', 'password='=>'string'],
    'ftp_append' => ['bool', 'ftp'=>'resource', 'remote_filename'=>'string', 'local_filename'=>'string', 'mode='=>'int'],
    'hash_hmac_algos' => ['list<string>'],
    'imagebmp' => ['bool', 'image'=>'resource', 'file='=>'resource|string|null', 'compressed='=>'int'],
    'imagecreatefrombmp' => ['resource|false', 'filename'=>'string'],
    'imageopenpolygon' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points'=>'int', 'color'=>'int'],
    'imageresolution' => ['array|bool', 'image'=>'resource', 'resolution_x='=>'int', 'resolution_y='=>'int'],
    'imagesetclip' => ['bool', 'image'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int'],
    'ldap_exop' => ['resource|bool', 'ldap'=>'resource', 'request_oid'=>'string', 'request_data='=>'?string', 'controls='=>'array|null', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
    'ldap_exop_passwd' => ['bool|string', 'ldap'=>'resource', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string'],
    'ldap_exop_refresh' => ['int|false', 'ldap'=>'resource', 'dn'=>'string', 'ttl'=>'int'],
    'ldap_exop_whoami' => ['string|false', 'ldap'=>'resource'],
    'ldap_parse_exop' => ['bool', 'ldap'=>'resource', 'result'=>'resource', '&w_response_data='=>'string', '&w_response_oid='=>'string'],
    'mb_chr' => ['non-empty-string|false', 'codepoint'=>'int', 'encoding='=>'string'],
    'mb_convert_encoding\'1' => ['array', 'string'=>'array', 'to_encoding'=>'string', 'from_encoding='=>'mixed'],
    'mb_ord' => ['int|false', 'string'=>'string', 'encoding='=>'string'],
    'mb_scrub' => ['string', 'string'=>'string', 'encoding='=>'string'],
    'oci_register_taf_callback' => ['bool', 'connection'=>'resource', 'callback='=>'callable'],
    'oci_unregister_taf_callback' => ['bool', 'connection'=>'resource'],
    'sapi_windows_vt100_support' => ['bool', 'stream'=>'resource', 'enable='=>'bool'],
    'socket_addrinfo_bind' => ['?resource', 'addrinfo'=>'resource'],
    'socket_addrinfo_connect' => ['resource', 'addrinfo'=>'resource'],
    'socket_addrinfo_explain' => ['array', 'addrinfo'=>'resource'],
    'socket_addrinfo_lookup' => ['resource[]', 'node'=>'string', 'service='=>'mixed', 'hints='=>'array'],
    'sodium_add' => ['void', '&rw_string1'=>'string', 'string2'=>'string'],
    'sodium_base642bin' => ['string', 'string'=>'string', 'id'=>'int', 'ignore='=>'string'],
    'sodium_bin2base64' => ['string', 'string'=>'string', 'id'=>'int'],
    'sodium_bin2hex' => ['string', 'string'=>'string'],
    'sodium_compare' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'sodium_crypto_aead_aes256gcm_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_aes256gcm_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_aes256gcm_is_available' => ['bool'],
    'sodium_crypto_aead_aes256gcm_keygen' => ['non-empty-string'],
    'sodium_crypto_aead_chacha20poly1305_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_chacha20poly1305_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_chacha20poly1305_ietf_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_chacha20poly1305_ietf_keygen' => ['non-empty-string'],
    'sodium_crypto_aead_chacha20poly1305_keygen' => ['non-empty-string'],
    'sodium_crypto_aead_xchacha20poly1305_ietf_decrypt' => ['string|false', 'ciphertext'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_xchacha20poly1305_ietf_encrypt' => ['string', 'message'=>'string', 'additional_data'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_aead_xchacha20poly1305_ietf_keygen' => ['non-empty-string'],
    'sodium_crypto_auth' => ['string', 'message'=>'string', 'key'=>'string'],
    'sodium_crypto_auth_keygen' => ['non-empty-string'],
    'sodium_crypto_auth_verify' => ['bool', 'mac'=>'string', 'message'=>'string', 'key'=>'string'],
    'sodium_crypto_box' => ['string', 'message'=>'string', 'nonce'=>'string', 'key_pair'=>'string'],
    'sodium_crypto_box_keypair' => ['string'],
    'sodium_crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secret_key'=>'string', 'public_key'=>'string'],
    'sodium_crypto_box_open' => ['string|false', 'ciphertext'=>'string', 'nonce'=>'string', 'key_pair'=>'string'],
    'sodium_crypto_box_publickey' => ['string', 'key_pair'=>'string'],
    'sodium_crypto_box_publickey_from_secretkey' => ['string', 'secret_key'=>'string'],
    'sodium_crypto_box_seal' => ['string', 'message'=>'string', 'public_key'=>'string'],
    'sodium_crypto_box_seal_open' => ['string|false', 'ciphertext'=>'string', 'key_pair'=>'string'],
    'sodium_crypto_box_secretkey' => ['string', 'key_pair'=>'string'],
    'sodium_crypto_box_seed_keypair' => ['string', 'seed'=>'string'],
    'sodium_crypto_generichash' => ['string', 'message'=>'string', 'key='=>'?string', 'length='=>'?int'],
    'sodium_crypto_generichash_final' => ['string', '&state'=>'string', 'length='=>'?int'],
    'sodium_crypto_generichash_init' => ['string', 'key='=>'?string', 'length='=>'?int'],
    'sodium_crypto_generichash_keygen' => ['non-empty-string'],
    'sodium_crypto_generichash_update' => ['bool', '&rw_state'=>'string', 'string'=>'string'],
    'sodium_crypto_kdf_derive_from_key' => ['string', 'subkey_length'=>'int', 'subkey_id'=>'int', 'context'=>'string', 'key'=>'string'],
    'sodium_crypto_kdf_keygen' => ['non-empty-string'],
    'sodium_crypto_kx_client_session_keys' => ['array<int,string>', 'client_keypair'=>'string', 'server_key'=>'string'],
    'sodium_crypto_kx_keypair' => ['string'],
    'sodium_crypto_kx_publickey' => ['string', 'key_pair'=>'string'],
    'sodium_crypto_kx_secretkey' => ['string', 'key_pair'=>'string'],
    'sodium_crypto_kx_seed_keypair' => ['string', 'seed'=>'string'],
    'sodium_crypto_kx_server_session_keys' => ['array<int,string>', 'server_key_pair'=>'string', 'client_key'=>'string'],
    'sodium_crypto_pwhash' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int', 'algo='=>'int'],
    'sodium_crypto_pwhash_scryptsalsa208sha256' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'sodium_crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'sodium_crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'],
    'sodium_crypto_pwhash_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'sodium_crypto_pwhash_str_needs_rehash' => ['bool', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'sodium_crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'],
    'sodium_crypto_scalarmult' => ['string', 'n'=>'string', 'p'=>'string'],
    'sodium_crypto_scalarmult_base' => ['string', 'secret_key'=>'string'],
    'sodium_crypto_secretbox' => ['string', 'message'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_secretbox_keygen' => ['non-empty-string'],
    'sodium_crypto_secretbox_open' => ['string|false', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_secretstream_xchacha20poly1305_init_pull' => ['string', 'header'=>'string', 'key'=>'string'],
    'sodium_crypto_secretstream_xchacha20poly1305_init_push' => ['array', 'key'=>'string'],
    'sodium_crypto_secretstream_xchacha20poly1305_keygen' => ['non-empty-string'],
    'sodium_crypto_secretstream_xchacha20poly1305_pull' => ['array', '&r_state'=>'string', 'ciphertext'=>'string', 'additional_data='=>'string'],
    'sodium_crypto_secretstream_xchacha20poly1305_push' => ['string', '&w_state'=>'string', 'message'=>'string', 'additional_data='=>'string', 'tag='=>'int'],
    'sodium_crypto_secretstream_xchacha20poly1305_rekey' => ['void', 'state'=>'string'],
    'sodium_crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'],
    'sodium_crypto_shorthash_keygen' => ['non-empty-string'],
    'sodium_crypto_sign' => ['string', 'message'=>'string', 'secret_key'=>'string'],
    'sodium_crypto_sign_detached' => ['string', 'message'=>'string', 'secret_key'=>'string'],
    'sodium_crypto_sign_ed25519_pk_to_curve25519' => ['string', 'public_key'=>'string'],
    'sodium_crypto_sign_ed25519_sk_to_curve25519' => ['string', 'secret_key'=>'string'],
    'sodium_crypto_sign_keypair' => ['string'],
    'sodium_crypto_sign_keypair_from_secretkey_and_publickey' => ['string', 'secret_key'=>'string', 'public_key'=>'string'],
    'sodium_crypto_sign_open' => ['string|false', 'signed_message'=>'string', 'public_key'=>'string'],
    'sodium_crypto_sign_publickey' => ['string', 'key_pair'=>'string'],
    'sodium_crypto_sign_publickey_from_secretkey' => ['string', 'secret_key'=>'string'],
    'sodium_crypto_sign_secretkey' => ['string', 'key_pair'=>'string'],
    'sodium_crypto_sign_seed_keypair' => ['string', 'seed'=>'string'],
    'sodium_crypto_sign_verify_detached' => ['bool', 'signature'=>'string', 'message'=>'string', 'public_key'=>'string'],
    'sodium_crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'],
    'sodium_crypto_stream_keygen' => ['non-empty-string'],
    'sodium_crypto_stream_xor' => ['string', 'message'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'sodium_hex2bin' => ['string', 'string'=>'string', 'ignore='=>'string'],
    'sodium_increment' => ['void', '&rw_string'=>'string'],
    'sodium_memcmp' => ['int', 'string1'=>'string', 'string2'=>'string'],
    'sodium_memzero' => ['void', '&w_string'=>'string'],
    'sodium_pad' => ['string', 'string'=>'string', 'block_size'=>'int'],
    'sodium_unpad' => ['string', 'string'=>'string', 'block_size'=>'int'],
    'stream_isatty' => ['bool', 'stream'=>'resource'],
    'xdebug_info' => ['mixed', 'category='=>'string'],
  ],
  'changed' => [
    'ReflectionClass::getMethods' => [
      'old' => ['list<ReflectionMethod>', 'filter='=>'int'],
      'new' => ['list<ReflectionMethod>', 'filter='=>'?int'],
    ],
    'ReflectionClass::getProperties' => [
      'old' => ['list<ReflectionProperty>', 'filter='=>'int'],
      'new' => ['list<ReflectionProperty>', 'filter='=>'?int'],
    ],
    'ReflectionObject::getMethods' => [
      'old' => ['ReflectionMethod[]', 'filter='=>'int'],
      'new' => ['ReflectionMethod[]', 'filter='=>'?int'],
    ],
    'ReflectionObject::getProperties' => [
      'old' => ['ReflectionProperty[]', 'filter='=>'int'],
      'new' => ['ReflectionProperty[]', 'filter='=>'?int'],
    ],
    'SQLite3::openBlob' => [
      'old' => ['resource|false', 'table'=>'string', 'column'=>'string', 'rowid'=>'int', 'dbname='=>'string'],
      'new' => ['resource|false', 'table'=>'string', 'column'=>'string', 'rowid'=>'int', 'database='=>'string', 'flags='=>'int'],
    ],
    'hash_copy' => [
      'old' => ['resource', 'context'=>'resource'],
      'new' => ['HashContext', 'context'=>'HashContext'],
    ],
    'hash_final' => [
      'old' => ['non-empty-string', 'context'=>'resource', 'raw_output='=>'bool'],
      'new' => ['non-empty-string', 'context'=>'HashContext', 'binary='=>'bool'],
    ],
    'hash_init' => [
      'old' => ['resource', 'algo'=>'string', 'options='=>'int', 'key='=>'string'],
      'new' => ['HashContext|false', 'algo'=>'string', 'flags='=>'int', 'key='=>'string'],
    ],
    'hash_update' => [
      'old' => ['bool', 'context'=>'resource', 'data'=>'string'],
      'new' => ['bool', 'context'=>'HashContext', 'data'=>'string'],
    ],
    'hash_update_file' => [
      'old' => ['bool', 'hcontext'=>'resource', 'filename'=>'string', 'scontext='=>'resource'],
      'new' => ['bool', 'context'=>'HashContext', 'filename'=>'string', 'stream_context='=>'resource'],
    ],
    'hash_update_stream' => [
      'old' => ['int', 'context'=>'resource', 'handle'=>'resource', 'length='=>'int'],
      'new' => ['int', 'context'=>'HashContext', 'stream'=>'resource', 'length='=>'int'],
    ],
    'json_decode' => [
      'old' => ['mixed', 'json'=>'string', 'associative='=>'bool', 'depth='=>'int', 'flags='=>'int'],
      'new' => ['mixed', 'json'=>'string', 'associative='=>'?bool', 'depth='=>'int', 'flags='=>'int'],
    ],
    'mb_check_encoding' => [
      'old' => ['bool', 'value='=>'string', 'encoding='=>'string'],
      'new' => ['bool', 'value='=>'array|string', 'encoding='=>'string'],
    ],
    'preg_quote' => [
      'old' => ['string', 'str'=>'string', 'delimiter='=>'string'],
      'new' => ['string', 'str'=>'string', 'delimiter='=>'?string'],
    ],
  ],
  'removed' => [
    'Sodium\add' => ['void', '&left'=>'string', 'right'=>'string'],
    'Sodium\bin2hex' => ['string', 'binary'=>'string'],
    'Sodium\compare' => ['int', 'left'=>'string', 'right'=>'string'],
    'Sodium\crypto_aead_aes256gcm_decrypt' => ['string|false', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_aead_aes256gcm_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_aead_aes256gcm_is_available' => ['bool'],
    'Sodium\crypto_aead_chacha20poly1305_decrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_aead_chacha20poly1305_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'],
    'Sodium\crypto_auth' => ['string', 'msg'=>'string', 'key'=>'string'],
    'Sodium\crypto_auth_verify' => ['bool', 'mac'=>'string', 'msg'=>'string', 'key'=>'string'],
    'Sodium\crypto_box' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'],
    'Sodium\crypto_box_keypair' => ['string'],
    'Sodium\crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_box_open' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'],
    'Sodium\crypto_box_publickey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_box_publickey_from_secretkey' => ['string', 'secretkey'=>'string'],
    'Sodium\crypto_box_seal' => ['string', 'message'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_box_seal_open' => ['string', 'encrypted'=>'string', 'keypair'=>'string'],
    'Sodium\crypto_box_secretkey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_box_seed_keypair' => ['string', 'seed'=>'string'],
    'Sodium\crypto_generichash' => ['string', 'input'=>'string', 'key='=>'string', 'length='=>'int'],
    'Sodium\crypto_generichash_final' => ['string', 'state'=>'string', 'length='=>'int'],
    'Sodium\crypto_generichash_init' => ['string', 'key='=>'string', 'length='=>'int'],
    'Sodium\crypto_generichash_update' => ['bool', '&hashState'=>'string', 'append'=>'string'],
    'Sodium\crypto_kx' => ['string', 'secretkey'=>'string', 'publickey'=>'string', 'client_publickey'=>'string', 'server_publickey'=>'string'],
    'Sodium\crypto_pwhash' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_scryptsalsa208sha256' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'],
    'Sodium\crypto_pwhash_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'],
    'Sodium\crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'],
    'Sodium\crypto_scalarmult' => ['string', 'ecdhA'=>'string', 'ecdhB'=>'string'],
    'Sodium\crypto_scalarmult_base' => ['string', 'sk'=>'string'],
    'Sodium\crypto_secretbox' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\crypto_secretbox_open' => ['string', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'],
    'Sodium\crypto_sign' => ['string', 'message'=>'string', 'secretkey'=>'string'],
    'Sodium\crypto_sign_detached' => ['string', 'message'=>'string', 'secretkey'=>'string'],
    'Sodium\crypto_sign_ed25519_pk_to_curve25519' => ['string', 'sign_pk'=>'string'],
    'Sodium\crypto_sign_ed25519_sk_to_curve25519' => ['string', 'sign_sk'=>'string'],
    'Sodium\crypto_sign_keypair' => ['string'],
    'Sodium\crypto_sign_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_sign_open' => ['string|false', 'signed_message'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_sign_publickey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_sign_publickey_from_secretkey' => ['string', 'secretkey'=>'string'],
    'Sodium\crypto_sign_secretkey' => ['string', 'keypair'=>'string'],
    'Sodium\crypto_sign_seed_keypair' => ['string', 'seed'=>'string'],
    'Sodium\crypto_sign_verify_detached' => ['bool', 'signature'=>'string', 'msg'=>'string', 'publickey'=>'string'],
    'Sodium\crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\crypto_stream_xor' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'],
    'Sodium\hex2bin' => ['string', 'hex'=>'string'],
    'Sodium\increment' => ['string', '&nonce'=>'string'],
    'Sodium\library_version_major' => ['int'],
    'Sodium\library_version_minor' => ['int'],
    'Sodium\memcmp' => ['int', 'left'=>'string', 'right'=>'string'],
    'Sodium\memzero' => ['void', '&target'=>'string'],
    'Sodium\randombytes_buf' => ['string', 'length'=>'int'],
    'Sodium\randombytes_random16' => ['int|string'],
    'Sodium\randombytes_uniform' => ['int', 'upperBoundNonInclusive'=>'int'],
    'Sodium\version_string' => ['string'],
  ],
];
<?php

use Psalm\Type\TaintKind;

// This maps internal function names to sink types that we don’t want to end up there

/**
 * @var array<string, list<list<TaintKind::*>>>
 */
return [
'exec' => [['shell']],
'create_function' => [[], ['eval']],
'file_get_contents' => [['file']],
'file_put_contents' => [['file']],
'fopen' => [['file']],
'unlink' => [['file']],
'copy' => [['file'], ['file']],
'file' => [['file']],
'link' => [['file'], ['file']],
'mkdir' => [['file']],
'move_uploaded_file' => [['file'], ['file']],
'parse_ini_file' => [['file']],
'chown' => [['file']],
'lchown' => [['file']],
'readfile' => [['file']],
'rename' => [['file'], ['file']],
'rmdir' => [['file']],
'header' => [['header']],
'symlink' => [['file']],
'tempnam' => [['file']],
'igbinary_unserialize' => [['unserialize']],
'ldap_search' => [[], ['ldap'], ['ldap']],
'mysqli_query' => [[], ['sql']],
'mysqli::query' => [['sql']],
'mysqli_real_query' => [[], ['sql']],
'mysqli::real_query' => [['sql']],
'mysqli_multi_query' => [[], ['sql']],
'mysqli::multi_query' => [['sql']],
'mysqli_prepare' => [[], ['sql']],
'mysqli::prepare' => [['sql']],
'mysqli_stmt::__construct' => [[], ['sql']],
'mysqli_stmt_prepare' => [[], ['sql']],
'mysqli_stmt::prepare' => [['sql']],
'passthru' => [['shell']],
'pcntl_exec' => [['shell']],
'pg_exec' => [[], ['sql']],
'pg_prepare' => [[], [], ['sql']],
'pg_put_line' => [[], ['sql']],
'pg_query' => [[], ['sql']],
'pg_query_params' => [[], ['sql']],
'pg_send_prepare' => [[], [], ['sql']],
'pg_send_query' => [[], ['sql']],
'pg_send_query_params' => [[], ['sql'], []],
'setcookie' => [['cookie'], ['cookie']],
'shell_exec' => [['shell']],
'system' => [['shell']],
'unserialize' => [['unserialize']],
'popen' => [['shell']],
'proc_open' => [['shell']],
'curl_init' => [['ssrf']],
'curl_setopt' => [[], [], ['ssrf']],
'getimagesize' => [['ssrf']],
];
<?php // phpcs:ignoreFile

/**
 * This contains the information needed to convert the function signatures for php 7.3 to php 7.2 (and vice versa)
 *
 * This file has three sections.
 * The 'added' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that do not exist in php 7.2
 * The 'removed' section contains the signatures that were removed in php 7.3.
 * The 'changed' section contains functions for which the signature has changed for php 7.3.
 *     Each function in the 'changed' section has an 'old' and a 'new' section,
 *     representing the function as it was in PHP 7.2 and in PHP 7.3, respectively
 *
 * @see CallMap.php
 *
 * @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
 */
return [
  'added' => [
    'DateTime::createFromImmutable' => ['static', 'object'=>'DateTimeImmutable'],
    'JsonException::__clone' => ['void'],
    'JsonException::__construct' => ['void'],
    'JsonException::__toString' => ['string'],
    'JsonException::__wakeup' => ['void'],
    'JsonException::getCode' => ['int'],
    'JsonException::getFile' => ['string'],
    'JsonException::getLine' => ['int'],
    'JsonException::getMessage' => ['string'],
    'JsonException::getPrevious' => ['?Throwable'],
    'JsonException::getTrace' => ['list<array{file?:string,line?:int,function:string,class?:class-string,type?:\'::\'|\'->\',args?:array<mixed>}>'],
    'JsonException::getTraceAsString' => ['string'],
    'SplPriorityQueue::isCorrupted' => ['bool'],
    'array_key_first' => ['int|string|null', 'array'=>'array'],
    'array_key_last' => ['int|string|null', 'array'=>'array'],
    'fpm_get_status' => ['array|false'],
    'gc_status' => ['array{runs:int,collected:int,threshold:int,roots:int}'],
    'gmp_binomial' => ['GMP|false', 'n'=>'GMP|string|int', 'k'=>'int'],
    'gmp_kronecker' => ['int', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_lcm' => ['GMP', 'num1'=>'GMP|string|int', 'num2'=>'GMP|string|int'],
    'gmp_perfect_power' => ['bool', 'num'=>'GMP|string|int'],
    'hrtime' => ['array{0:int,1:int}|false', 'as_number='=>'false'],
    'hrtime\'1' => ['int|float|false', 'as_number='=>'true'],
    'is_countable' => ['bool', 'value'=>'mixed'],
    'net_get_interfaces' => ['array<string,array<string,mixed>>|false'],
    'openssl_pkey_derive' => ['string|false', 'public_key'=>'mixed', 'private_key'=>'mixed', 'key_length='=>'?int'],
    'session_set_cookie_params\'1' => ['bool', 'options'=>'array{lifetime?:?int,path?:?string,domain?:?string,secure?:?bool,httponly?:?bool,samesite?:?string}'],
    'setcookie\'1' => ['bool', 'name'=>'string', 'value='=>'string', 'options='=>'array'],
    'setrawcookie\'1' => ['bool', 'name'=>'string', 'value='=>'string', 'options='=>'array'],
    'socket_wsaprotocol_info_export' => ['string|false', 'socket'=>'resource', 'process_id'=>'int'],
    'socket_wsaprotocol_info_import' => ['resource|false', 'info_id'=>'string'],
    'socket_wsaprotocol_info_release' => ['bool', 'info_id'=>'string'],
  ],
  'changed' => [
    'array_push' => [
        'old' => ['int', '&rw_array'=>'array', '...values'=>'mixed'],
        'new' => ['int', '&rw_array'=>'array', '...values='=>'mixed'],
    ],
    'array_unshift' => [
        'old' => ['int', '&rw_array'=>'array', '...values'=>'mixed'],
        'new' => ['int', '&rw_array'=>'array', '...values='=>'mixed'],
    ],
    'bcscale' => [
      'old' => ['int', 'scale'=>'int'],
      'new' => ['int', 'scale='=>'int'],
    ],
    'ldap_exop_passwd' => [
      'old' => ['bool|string', 'ldap'=>'resource', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string'],
      'new' => ['bool|string', 'ldap'=>'resource', 'user='=>'string', 'old_password='=>'string', 'new_password='=>'string', '&w_controls='=>'array'],
    ],
  ],
  'removed' => [
  ],
];
<?php

$long_options = [
    'foreign-map-a:',
    'foreign-map-b:',
    'local-map-a:',
    'local-map-b:',
];

$options = getopt('', $long_options);

$foreign_a = require($options['foreign-map-a']);
$foreign_b = require($options['foreign-map-b']);

$local_a = require($options['local-map-a']);
$local_b = require($options['local-map-b']);

$added_foreign_functions = array_diff_key($foreign_b, $foreign_a);
$removed_foreign_functions = array_diff_key($foreign_a, $foreign_b);

// get all functions changed in the foreign map that haven't been changed
// in the between local maps
$useful_foreign_functions = array_diff_key(
    array_intersect_key(get_changed_functions($foreign_a, $foreign_b), $local_a),
    get_changed_functions($local_a, $local_b)
);

$new_local = array_diff_key(
    array_merge($added_foreign_functions, $local_b, $useful_foreign_functions),
    $removed_foreign_functions
);

uksort($new_local, fn($a, $b) => strtolower($a) <=> strtolower($b));

foreach ($new_local as $name => $data) {
    if (!is_array($data)) {
        throw new UnexpectedValueException('bad data for ' . $name);
    }
    $return_type = array_shift($data);
    echo '\'' . str_replace("'", "\'", $name) . '\' => [\'' . str_replace("'", "\'", $return_type) . '\'';

    if ($data) {
        $signature = [];

        foreach ($data as $param_name => $type) {
            $signature[] = '\'' . str_replace("'", "\'", $param_name) . '\'=>\'' . str_replace("'", "\'", $type) . '\'';
        }

        echo ', ' . implode(', ', $signature);
    }

    echo '],' . "\n";
}


function get_changed_functions(array $a, array $b) {
    $changed_functions = [];

    foreach (array_intersect_key($a, $b) as $function_name => $a_data) {
        if (json_encode($b[$function_name]) !== json_encode($a_data)) {
            $changed_functions[$function_name] = $b[$function_name];
        }
    }

    return $changed_functions;
}
# PossiblyUnusedProperty

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a
particular public/protected property.

If this property is used and part of the public API, annotate the containing
class with `@psalm-api`.

```php
<?php

class A {
    /** @var string|null */
    public $foo;

    /** @var int|null */
    public $bar;
}

$a = new A();
echo $a->foo;
```
# DuplicateFunction

Emitted when a function is defined twice

```php
<?php

function foo() : void {}
function bar() : void {}
function foo() : void {}
```
# DuplicateEnumCase

Emitted when enum has duplicate cases.

```php
<?php

enum Status 
{
    case Open;
    case Open;
}
```

## How to fix

Remove or rename the offending duplicates.

```php
<?php

enum Status 
{
    case Open;
    case Closed;
}
```
# TaintedInput

Emitted when tainted input detection is turned on
# PossiblyNullPropertyAssignment

Emitted when trying to assign a property to a possibly null object

```php
<?php

class A {
    /** @var ?string */
    public $foo;
}
function foo(?A $a) : void {
    $a->foo = "bar";
}
```
# ImpureVariable

Emitted when referencing an impure or possibly-impure variable from a pure context.

```php
<?php

class A {
    public int $a = 5;

    /**
     * @psalm-pure
     */
    public function foo() : self {
        return $this;
    }
}
```
# TooFewArguments

Emitted when calling a function with fewer arguments than the function has parameters

```php
<?php

function foo(string $a) : void {}
foo();
```
# UnusedFunctionCall

Emitted when `--find-dead-code` is turned on and Psalm finds a function call whose return value is not used anywhere

```php
<?php

$a = strlen("hello");
strlen("goodbye"); // unused
echo $a;
```
# InvalidIterator

Emitted when trying to iterate over a value that's not iterable

```php
<?php

$a = 5;
foreach ($a as $b) {}
```
# MissingClosureReturnType

Emitted when a closure lacks a return type

```php
<?php

$a = function() {
    return "foo";
};
```
# ExtensionRequirementViolation

Emitted when a using class of a trait does not extend the class specified using `@psalm-require-extends`.

```php
<?php

class A { }

/**
 * @psalm-require-extends A
 */
trait T { }

class B {
  // ExtensionRequirementViolation is emitted, as T requires
  // the using class B to extend A, which is not the case
  use T; 
}
```
# DeprecatedInterface

Emitted when referring to a deprecated interface

```php
<?php

/** @deprecated */
interface I {}

class A implements I {}
```

## Why this is bad

The `@deprecated` tag is normally indicative of code that will stop working in the near future.

## How to fix

Don’t use the deprecated interface.
# InvalidReturnType

Emitted when a function’s signature return type is incorrect (often emitted with `InvalidReturnStatement`)

```php
<?php

function foo() : int {
    if (rand(0, 1)) {
        return "hello";
    }

    return 5;
}
```
# LessSpecificImplementedReturnType

Emitted when a class implements an interface method but its return type is less specific than the interface method return type

```php
<?php

class A {}
class B extends A {}
interface I {
    /** @return B[] */
    public function foo();
}
class D implements I {
    /** @return A[] */
    public function foo() {
        return [new A, new A];
    }
}
```
# InvalidPropertyAssignmentValue

Emitted when attempting to assign a value to a property that cannot contain that type.

```php
<?php

class A {
    /** @var string|null */
    public $foo;
}
$a = new A();
$a->foo = new stdClass();
```
# NullPropertyFetch

Emitted when trying to fetch a property on a `null` value

```php
<?php

$a = null;
echo $a->foo;
```
# MutableDependency

Emitted when an immutable class inherits from a class or trait not marked @psalm-immutable

```php
<?php

class MutableParent {
    public int $i = 0;

    public function increment() : void {
        $this->i++;
    }
}

/**
 * @psalm-immutable
 */
final class NotReallyImmutableClass extends MutableParent {}
```
# InvalidParamDefault

Emitted when a function parameter default clashes with the type Psalm expects the param to be

```php
<?php

function foo(int $i = false) : void {}
```
# IfThisIsMismatch

Emitted when the type in `@psalm-if-this-is` annotation cannot be contained by the object's actual type.

```php
<?php

/**
 * @template T
 */
class a {
    /**
     * @var T
     */
    private $data;
    /**
     * @param T $data
     */
    public function __construct($data) {
        $this->data = $data;
    }
    /**
     * @psalm-if-this-is a<int>
     */
    public function test(): void {
    }
}

$i = new a(123);
$i->test();

$i = new a("test");
// IfThisIsMismatch - Class is not a<int> as required by psalm-if-this-is
$i->test();
```# InvalidParent

Emitted when a function return type is `parent`, but there's no parent class
```php
<?php

class Foo {
    public function f(): parent {}
}
```
# StringIncrement

Emitted when attempting to increment a string - this works in PHP, but is unexpected behaviour for most people.

```php
<?php

$a = "hello";
$a++;
```
# UndefinedThisPropertyAssignment

Emitted when assigning a property on an object in one of that object’s methods when no such property exists

```php
<?php

class A {
    function foo() {
        $this->foo = "bar";
    }
}
```
# PossiblyNullArgument

Emitted when calling a function with a value that’s possibly null when the function does not expect it

```php
<?php

function foo(string $s): void {}
foo(rand(0, 1) ? "hello" : null);
```

## Common Problem Cases

### Using a Function Call inside `if`

```php
<?php

if (is_string($cat->getName()) {
    foo($cat->getName());
}
```
This fails since it's not guaranteed that subsequent calls to `$cat->getName()` always give the same result.

#### Possible Solutions

Use a variable:
```php
<?php

$catName = $cat->getName();
if (is_string($catName) {
    foo($catName);
}
unset($catName);
```

Or add [`@psalm-mutation-free`](../../annotating_code/supported_annotations.md#psalm-mutation-free) to the declaration of the function

### Calling Another Function After `if`

```php
<?php

if (is_string($cat->getName()) {
    changeCat();
    foo($cat->getName());
}
```
This fails since psalm cannot know if `changeCat()` does actually modify `$cat`.

#### Possible Solutions

* Add [`@psalm-mutation-free`](../../annotating_code/supported_annotations.md#psalm-mutation-free) to the declaration of the other function (here: `changeCat()`) too
* Use a variable: See above
# PossiblyFalseOperand

Emitted when using a possibly `false` value as part of an operation (e.g. `+`, `.`, `^` etc).

```php
<?php

function echoCommaPosition(string $str) : void {
    echo 'The comma is located at ' . strpos($str, ','); 
}
```

## How to fix

You can detect the `false` value with some extra logic:

```php
<?php

function echoCommaPosition(string $str) : void {
    $pos = strpos($str, ',');

    if ($pos === false) {
        echo 'There is no comma in the string';
    }

    echo 'The comma is located at ' . $pos; 
}
```

Alternatively you can just use a ternary to suppress this issue:

```php
<?php

function echoCommaPosition(string $str) : void {
    echo 'The comma is located at ' . (strpos($str, ',') ?: ''); 
}
```
# ImpureStaticProperty

Emitted when attempting to use a static property from a function or method marked as pure

```php
<?php

class ValueHolder {
    public static ?string $value = null;

    /**
     * @psalm-pure
     */
    public static function get(): ?string {
        return self::$value;
    }
}
```
# NullableReturnStatement

Emitted if a return statement contains a null value, but the function return type is not nullable

```php
<?php

function foo() : string {
    if (rand(0, 1)) {
        return "foo";
    }

    return null; // emitted here
}
```
# MixedInferredReturnType

Emitted when Psalm cannot determine a function's return type

```php
<?php

function foo() : int {
    return $GLOBALS['foo'];
}
```
# OverriddenFinalConstant

Emitted when a constant declared as final is overridden in a child class or interface.

```php
<?php

class Foo
{
    /** @var string */
    final public const BAR='baz';
}

class Bar extends Foo
{
    /** @var string */
    public const BAR='foobar';
}
```
# InvalidAttribute

Emitted when using an attribute on an element that doesn't match the attribute's target

```php
<?php
namespace Foo;

#[\Attribute(\Attribute::TARGET_CLASS)]
class Table {
    public function __construct(public string $name) {}
}

#[Table("videos")]
function foo() : void {}
```
# UndefinedPropertyAssignment

Emitted when assigning a property on an object that does not have that property defined

```php
<?php

class A {}
$a = new A();
$a->foo = "bar";
```
# UnusedConstructor

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a given private constructor or function

```php
<?php

class A {
    private function __construct() {}

    public static function createInstance() : void {}
}
A::createInstance();
```
# DocblockTypeContradiction

Emitted when conditional doesn't make sense given the docblock types supplied.

```php
<?php

/**
 * @param string $s
 *
 * @return void
 */
function foo($s) {
    if ($s === null) {
        throw new \Exception('Bad input');
    }

    echo $s;
}
```

## Why this is bad

This can sometimes point to a flaw in either your docblock types, or some unnecessary runtime checks in an environment where all types can be checked by Psalm, without the need for additional runtime checks.

## How to fix

A lot of old PHP code is set up to prevent unexpected errors with checks like the one above.

As you migrate your code to newer versions of PHP you can also use stricter type-hints:

```php
<?php

function foo(string $s) : void {
    echo $s;
}
```

Since it's impossible for `$s` to be anything but a `string` inside the function, the null check can be removed.
# UnresolvableInclude

Emitted when Psalm cannot figure out what specific file is being included/required by PHP.

```php
<?php

function requireFile(string $s) : void {
    require_once $s;
}
```
# InvalidTraversableImplementation

Emitted when class incorrectly implements Traversable. Traversable needs to be
implemented by implementing either `IteratorAggregate` or `Iterator`

```php
<?php

/**
 * @implements Traversable<mixed, mixed>
 */
final class C implements Traversable {} // will cause fatal error
```
# PossiblyNullOperand

Emitted when using a possibly `null` value as part of an operation (e.g. `+`, `.`, `^` etc.)

```php
<?php

function foo(?int $a) : void {
    echo $a + 5;
}
```
# UnusedProperty

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a
private property.

If this property is used and part of the public API, annotate the containing
class with `@psalm-api`.

```php
<?php

class A {
    /** @var string|null */
    private $foo;

    /** @var int|null */
    private $bar;

    public function getFoo(): ?string {
        return $this->foo;
    }
}

$a = new A();
echo $a->getFoo();
```
# ImpureFunctionCall

Emitted when calling an impure function from a function or method marked as pure.

```php
<?php

function impure(array $a) : array {
    /** @var int */
    static $i = 0;

    ++$i;

    $a[$i] = 1;

    return $a;
}

/** @psalm-pure */
function filterOdd(array $a) : void {
    impure($a);
}
```
# AbstractMethodCall

Emitted when an attempt is made to call an abstract static method directly

```php
<?php

abstract class Base {
    abstract static function bar() : void;
}

Base::bar();
```

## Why this is bad

It's not allowed by PHP.
# UnhandledMatchCondition

Emitted when a match expression does not handle one or more options.

```php
<?php

function matchOne(): string {
    $foo = rand(0, 1) ? "foo" : "bar";

    return match ($foo) {
        'foo' => 'foo',
    };
}
```

## Why this is bad

The above code will fail 50% of the time with an `UnhandledMatchError` error.
# PossiblyNullArrayOffset

Emitted when trying to access a value on an array using a possibly null offset

```php
<?php

function foo(?int $a) : void {
    echo [1, 2, 3, 4][$a];
}
```
# RedundantConditionGivenDocblockType

Emitted when conditional is redundant given information supplied in one or more docblocks.

This may be desired (e.g. when checking user input) so is distinct from RedundantCondition, which only applies to non-docblock types.

```php
<?php

/**
 * @param string $s
 *
 * @return void
 */
function foo($s) {
    if (is_string($s)) {};
}
```
# UndefinedClass

Emitted when referencing a class that does not exist

```php
<?php

$a = new A();
```
# MissingConstructor

Unitialized properties are statically hard to analyze. To prevent mistakes, Psalm will enforce that all properties should be initialized.

It does that through [PropertyNotSetInConstructor](./PropertyNotSetInConstructor.md) and this issue.

Psalm will then assume every property in the codebase is initialized.

Doing that allows it to report missing initializations as well as [RedundantPropertyInitializationCheck](./RedundantPropertyInitializationCheck.md)

This issue is emitted when non-null properties without default values are defined in a class without a `__construct` method

If your project relies on having uninitialized properties, it is advised to suppress this issue, as well as [PropertyNotSetInConstructor](./PropertyNotSetInConstructor.md) and [RedundantPropertyInitializationCheck](./RedundantPropertyInitializationCheck.md).

```php
<?php

class A {
    /** @var string */
    public $foo;
}
```
# PossiblyNullArrayAccess

Emitted when trying to access an array offset on a possibly null value

```php
<?php

function foo(?array $a) : void {
    echo $a[0];
}
```
# MissingReturnType

Emitted when a function doesn't have a return type defined

```php
<?php

function foo() {
    return "foo";
}
```

Correct with:

```php
<?php

function foo() : string {
    return "foo";
}
```
# MixedOperand

Emitted when Psalm cannot infer a type for an operand in any calculated expression

```php
<?php

echo $GLOBALS['foo'] + "hello";
```

## Why it’s bad

Mixed operands can have fatal consequences, e.g. here:

```php
<?php

function foo(mixed $m) {
    echo $m . 'bar';
}

class A {}

foo(new A()); // triggers fatal error
```
# DeprecatedTrait

Emitted when referring to a deprecated trait:

```php
<?php

/** @deprecated */
trait T {}
class A {
    use T;
}
```

## Why this is bad

The `@deprecated` tag is normally indicative of code that will stop working in the near future.

## How to fix

Don’t use the deprecated trait.
# LessSpecificReturnType

Emitted when a return type covers more possibilities than the function itself

```php
<?php

function foo() : ?int {
    return 5;
}
```
# OverriddenMethodAccess

Emitted when a method is less accessible than its parent

```php
<?php

class A {
    public function foo() : void {}
}
class B extends A {
    protected function foo() : void {}
}
```
# PossiblyInvalidFunctionCall

Emitted when trying to call a function on a value that may not be callable

```php
<?php

$a = rand(0, 1) ? 5 : function() : int { return 5; };
$b = $a();
```
# RedundantCondition

Emitted when conditional is redundant given previous assertions

```php
<?php

class A {}
function foo(A $a) : ?A {
    if ($a) return $a;
    return null;
}
```
# PossiblyInvalidPropertyAssignmentValue

Emitted when trying to assign a possibly invalid value to a typed property.

```php
<?php

class A {
    /** @var int[] */
    public $bb = [];
}

class B {
    /** @var string[] */
    public $bb;
}

$c = rand(0, 1) ? new A : new B;
$c->bb = ["hello", "world"];
```
# ComplexFunction

Emitted when a function is too complicated. Complicated functions should be split up.
# NullArrayAccess

Emitted when trying to access an array value on `null`

```php
<?php

$arr = null;
echo $arr[0];
```
# MixedReturnTypeCoercion

Emitted when Psalm cannot be sure that part of an array/iterable return type's constraints can be fulfilled

```php
<?php

/**
 * @return string[]
 */
function foo(array $a) : array {
    return $a;
}
```

This can happen with variadic arguments when `@no-named-arguments` is not specified:

```php
<?php

/** @return list<int> */
function foo(int ...$args): array {
    return $args; // $args is array<array-key, int> since it can have named arguments
}
```
# RedundantPropertyInitializationCheck

Unitialized properties are hard to statically analyze. To prevent mistakes, Psalm will enforce that all properties should be initialized.

It does that through [PropertyNotSetInConstructor](./PropertyNotSetInConstructor.md) and [MissingConstructor](./MissingConstructor.md).

Psalm will then assume every property in the codebase is initialized.

Doing that allows it to report missing initializations as well as this issue.

This issue is emitted when checking `isset()` on a non-nullable property. Because every property is assumed to be initialized, this check is redundant

If your project relies on having uninitialized properties, it is advised to suppress this issue, as well as [PropertyNotSetInConstructor](./PropertyNotSetInConstructor.md) and [MissingConstructor](./MissingConstructor.md).

```php
<?php
    class A {
        public string $bar;
        public function getBar() : string {
            if (isset($this->bar)) {
                return $this->bar;
            }
            return "hello";
        }
    }
```
# PossiblyInvalidArrayAccess

Emitted when attempting to access an array offset on a value that may not be an array

```php
<?php

$arr = rand(0, 1) ? 5 : [4, 3, 2, 1];
echo $arr[0];
```
# PossiblyInvalidArrayOffset

Emitted when it’s possible that the array offset is not applicable to the value you’re trying to access.

```php
<?php

$arr = rand(0, 1) ? ["a" => 5] : "hello";
echo $arr[0];
```
# UndefinedTrace

Attempt to trace an undefined variable

```php
<?php

/** @psalm-trace $x */
echo 'Hello World!';
```

## How to fix

Provide existing variable or remove it
# TaintedCallable

Emitted when tainted text is used in an arbitrary function call.

This can lead to dangerous situations, like running arbitrary functions.

```php
<?php

$name = $_GET["name"];

evalCode($name);

function evalCode(string $name) {
    if (is_callable($name)) {
        $name();
    }
}
```
# MissingDocblockType

Emitted when a docblock is present, but the type is missing or badly formatted

```php
<?php

/** @var $a */
$a = [];
```
# UndefinedDocblockClass

Emitted when referencing a class that does not exist from a docblock

```php
<?php

/**
 * @param DoesNotExist $a
 */
function foo($a) : void {}
```
# InvalidPropertyFetch

Emitted when attempting to get a property from a non-object

```php
<?php

$a = "foo";
echo $a->bar;
```
# TaintedLdap

Potential LDAP injection. This rule is emitted when user-controlled input can be passed into an LDAP request.

## Risk

Passing untrusted user input to LDAP requests could be dangerous. 

If LDAP requests like these are used for login purposes, it could result in an authentication bypass. An attacker could write a filter that would evaluate to `true` for any user, and thus bruteforce credentials easily. 


## Example

```php
<?php

$ds = ldap_connect('example.com');
$dn = 'o=Psalm, c=US';
$filter = $_GET['filter'];
ldap_search($ds, $dn, $filter, []);
```

## Mitigations

Use [`ldap_escape`](https://www.php.net/manual/en/function.ldap-escape.php) to escape user input to the LDAP filter and DN.


## Further resources

- [OWASP Wiki for LDAP Injections](https://owasp.org/www-community/attacks/LDAP_Injection)
- [LDAP Injection Prevention Cheatsheet](https://cheatsheetseries.owasp.org/cheatsheets/LDAP_Injection_Prevention_Cheat_Sheet.html)
- [CWE-90](https://cwe.mitre.org/data/definitions/90.html)
# InvalidClass

Emitted when referencing a class with the wrong casing

```php
<?php

class Foo {}
(new foo());
```

Could also be an issue in the namespace even if the class has the correct casing
```php
<?php

namespace OneTwo {
    class Three {}
}

namespace {
    use Onetwo\Three;
    //     ^ ("t" instead of "T")

    $three = new Three();
}
```
# DuplicateParam

Emitted when a function has a param defined twice

```php
<?php

function foo(int $b, string $b) {}
```

## Why this is bad

The above code produces a fatal error in PHP.
# UnevaluatedCode

Emitted when `--find-dead-code` is turned on and Psalm encounters code that will not be evaluated

```php
<?php

function foo() : void {
    return;
    $a = "foo";
}
```
# InvalidFalsableReturnType

Emitted when a function can return a nullable value, but its given return type says otherwise

```php
<?php

function foo() : string {
    if (rand(0, 1)) {
        return "foo";
    }

    return false;
}
```
# MixedArrayOffset

Emitted when attempting to access an array offset where Psalm cannot determine the offset type

```php
<?php

echo [1, 2, 3][$GLOBALS['foo']];
```
# RedundantFunctionCallGivenDocblockType

Emitted when function call is redundant given information supplied in one or more docblocks.

This may be desired (e.g. when checking user input) so is distinct from RedundantFunctionCall, which only applies to non-docblock types.

```php
<?php

/**
 * @param array{0: lowercase-string, 1: non-empty-list<lowercase-string>} $s
 *
 * @return lowercase-string
 */
function foo($s): string {
    $redundantList = array_values($s);
    $redundantSubList = array_values($s[1]);
    $redundantLowercase = strtolower($redundantSubList[0]);
    return $redundantLowercase;
}
```
# InvalidFunctionCall

Emitted when calling a function on a non-callable variable

```php
<?php

$a = 5;
$b = $a();
```
# MixedPropertyFetch

Emitted when retrieving a property on a value for which Psalm cannot infer a type

```php
<?php

/** @param mixed $a */
function foo($a) : void {
    echo $a->foo;
}
```
# UndefinedFunction

Emitted when referencing a function that doesn't exist

```php
<?php

foo();
```
# MixedArgument

Emitted when Psalm cannot determine the type of an argument

```php
<?php

function takesInt(int $i) : void {}
takesInt($GLOBALS['foo']);
```
# UndefinedMethod

Emitted when calling a method that does not exist

```php
<?php

class A {}
A::foo();
```
# DeprecatedConstant

Emitted when referring to a deprecated constant or enum case:

```php
<?php

class A {
    /** @deprecated */
    const FOO = 'foo';
}

echo A::FOO;

enum B {
    /** @deprecated */
    case B;
}

echo B::B;
```

## Why this is bad

The `@deprecated` tag is normally indicative of code that will stop working in the near future.

## How to fix

Don’t use the deprecated constant or enum case
# InvalidDocblockParamName

Emitted when a docblock param name does not match up with a named param in the function, if the param does not have a type or its type is `array`.

```php
<?php

/**
 * @param string[] $bar
 */
function foo(array $barb): void {
    //
}
```
# DeprecatedProperty

Emitted when getting/setting a deprecated property of a given class

```php
<?php

class A {
    /**
     * @deprecated
     * @var ?string
     */
    public $foo;
}
(new A())->foo = 5;
```

## Why this is bad

The `@deprecated` tag is normally indicative of code that will stop working in the near future.

## How to fix

Don’t use the deprecated property.
# PossiblyInvalidDocblockTag

Emitted when Psalm detects a likely mix-up of docblock tags, e.g. `@var`
used on a method (where `@param` is likely expected).

```php
<?php

/** @var int $param */
function foo($param): void {}
```
# PossiblyNullPropertyFetch

Emitted when trying to fetch a property on a possibly null object

```php
<?php

class A {
    /** @var ?string */
    public $foo;
}
function foo(?A $a) : void {
    echo $a->foo;
}
```
# MismatchingDocblockPropertyType

Emitted when an `@var` entry in a property’s docblock does not match the property's type.

```php
<?php
class A {
    /** @var array */
    public string $s = [];
}
```
# UnusedForeachValue

Emitted when `--find-dead-code` is turned on and Psalm cannot find any
references to the foreach value

```php
<?php

/** @param array<string, int> $a */
function foo(array $a) : void {
    foreach ($a as $key => $value) { // $value is unused
        echo $key;
    }
}
```

Can be suppressed by prefixing the variable name with an underscore or naming
it `$_`:

```php
<?php

foreach ([1, 2, 3] as $key => $_val) {}

foreach ([1, 2, 3] as $key => $_) {}
```
# MixedClone

Emitted when trying to clone a value whose type is not known

```php
<?php

$a = clone $GLOBALS["a"];
```
# InvalidArgument

Emitted when a supplied function/method argument is incompatible with the method signature or docblock one.

```php
<?php

class A {}

function foo(A $a) : void {}

/**
 * @param string $s
 */
function callFoo($s) : void {
    foo($s);
}
```

## Why it’s bad

Calling functions with incorrect values will cause a fatal error at runtime.

## How to fix

Sometimes this message can just be the result of an incorrect docblock.

You can fix by correcting the docblock, or converting to a function signature:

```php
<?php

class A {}

function foo(A $a) : void {}

function callFoo(A $a) : void {
    foo($a);
}
```
# InvalidStringClass

Emitted when you have `allowStringToStandInForClass="false"` in your config and you’re passing a string instead of calling a class directly

```php
<?php

class Foo {}
$a = "Foo";
new $a();
```
# ArgumentTypeCoercion

Emitted when calling a function with an argument which has a less specific type than the function expects

```php
<?php

class A {}
class B extends A {}

function takesA(A $a) : void {
    takesB($a);
}
function takesB(B $b) : void {}
```

## How to fix

You could add a typecheck before the call to `takesB`:

```php
<?php

function takesA(A $a) : void {
    if ($a instanceof B) {
        takesB($a);
    }
}
```

Or, if you have control over the function signature of `takesA` you can change it to expect `B`:

```php
<?php

function takesA(B $a) : void {
    takesB($a);
}
```
# PossiblyInvalidMethodCall

Emitted when trying to call a method on a value that may not be an object

```php
<?php

class A {
    public function bar() : void {}
}

/** @return A|int */
function foo() {
    return rand(0, 1) ? new A : 5;
}

foo()->bar();
```
# UnsupportedReferenceUsage

Emitted when Psalm encounters a reference that it is not currently able to track (for instance a reference to an array
offset of an array offset: `$foo = &$bar[$baz[0]]`). When an unsupported reference is encountered, Psalm will issue this
warning and treat the variable as though it wasn't actually a reference.

## How to fix

This can sometimes be fixed by using a temporary variable:

```php
<?php

/** @var non-empty-list<int> */
$bar = [1, 2, 3];
/** @var non-empty-list<int> */
$baz = [1, 2, 3];

$foo = &$bar[$baz[0]];
```

can be turned into

```php
<?php

/** @var non-empty-list<int> */
$bar = [1, 2, 3];
/** @var non-empty-list<int> */
$baz = [1, 2, 3];

$offset = $baz[0];
$foo = &$bar[$offset];
```
# UndefinedMagicMethod

Emitted when calling a magic method that does not exist

```php
<?php

/**
 * @method bar():string
 */
class A {
    public function __call(string $name, array $args) {
        return "cool";
    }
}
(new A)->foo();
```
# NonStaticSelfCall

Emitted when calling a non-static function statically

```php
<?php

class A {
    public function foo(): void {}

    public static function bar(): void {
        self::foo();
    }
}
```
# NullIterator

Emitted when iterating over `null`

```php
<?php

foreach (null as $a) {}
```
# NullFunctionCall

Emitted when trying to use `null` as a `callable`

```php
<?php

$arr = null;
echo $arr();
```
# InvalidStaticInvocation

Emitted when trying to call an instance function statically

```php
<?php

class A {
    /** @var ?string */
    public $foo;

    public function bar() : void {
        echo $this->foo;
    }
}

A::bar();
```
# PossiblyUndefinedIntArrayOffset

Emitted when the config flag `ensureArrayIntOffsetsExist` is set to `true` and an integer-keyed offset is not checked for existence

```php
<?php

/**
 * @param array<int, string> $arr
 */
function foo(array $arr) : void {
    echo $arr[0];
}
```
# NoEnumProperties

Emitted when there a property defined on an enum, as PHP
does not allow user-defined properties on enums.

```php
<?php

enum Status {
    public $prop;
}
```
# InternalMethod

Emitted when attempting to access a method marked as internal an unrelated namespace or class, or attempting
to access a method marked as psalm-internal to a different namespace.

```php
<?php

namespace A {
    class Foo {
        /**
         * @internal
         */
        public static function barBar(): void {
        }
    }
}
namespace B {
    class Bat {
        public function batBat(): void {
            \A\Foo::barBar();
        }
    }
}
```
# UndefinedPropertyFetch

Emitted when getting a property on an object that does not have that property defined

```php
<?php

class A {}
$a = new A();
echo $a->foo;
```
# PossiblyUnusedMethod

Emitted when `--find-dead-code` is turned on and Psalm cannot find any calls to
a public or protected method.

If this method is used and part of the public API, annotate the containing class
with `@psalm-api`.

```php
<?php

class A {
    public function foo() : void {}
    public function bar() : void {}
}
(new A)->foo();
```
# PossiblyInvalidIterator

Emitted when trying to iterate over a value that may be invalid

```php
<?php

$arr = rand(0, 1) ? [1, 2, 3] : "hello";
foreach ($arr as $a) {}
```
# PossiblyInvalidOperand

Emitted when using a possibly invalid value as part of an operation (e.g. `+`, `.`, `^` etc.

```php
<?php

function foo() : void {
    $b = rand(0, 1) ? [] : 4;
    echo $b + 5;
}
```
# EmptyArrayAccess

Emitted when attempting to access a value on an empty array

```php
<?php

$a = [];
$b = $a[0];
```
# PossiblyInvalidArgument

Emitted when

```php
<?php

/** @return int|stdClass */
function foo() {
    return rand(0, 1) ? 5 : new stdClass;
}
function bar(int $i) : void {}
bar(foo());
```
# InaccessibleMethod

Emitted when attempting to access a protected/private method from outside its available scope

```php
<?php

class A {
    protected function foo() : void {}
}
echo (new A)->foo();
```
# DuplicateConstant

Emitted when a constant is defined twice in a single class or when there's a
clash between a constant and an enum case.

```php
<?php
class C {
    public const A = 1;
    public const A = 2;
}
```

## Why this is bad

The above code won’t compile.
# LessSpecificReturnStatement

Emitted when a return statement is more general than the return type given for the function

```php
<?php

class A {}
class B extends A {}

function foo() : B {
    return new A(); // emitted here
}
```
# InaccessibleClassConstant

Emitted when a public/private class constant is not accessible from the calling context

```php
<?php

class A {
    protected const FOO = 'FOO';
}
echo A::FOO;
```
# UndefinedMagicPropertyFetch

Emitted when getting a property on an object that does not have that magic property defined

```php
<?php

/**
 * @property string $bar
 */
class A {
    public function __get(string $name) {
        return "cool";
    }
}
$a = new A();
echo $a->foo;
```
# PluginIssue

Can be emitted by plugins.
# InvalidNamedArgument

Emitted when a supplied function/method argument name is incompatible with the function/method signature.

```php
<?php

function takesArguments(string $name, int $age) : void {}

takesArguments(name: "hello", ag: 5);
```

# ForbiddenCode

Emitted when Psalm encounters a var_dump, exec or similar expression that may make your code more vulnerable

```php
<?php

var_dump("bah");
```

This functions list can be extended by configuring `forbiddenFunctions` in `psalm.xml`

```xml
<?xml version="1.0"?>
<psalm>
    <!-- other configs -->

    <forbiddenFunctions>
        <function name="dd"/>
        <function name="var_dump"/>
    </forbiddenFunctions>
</psalm>
```
# ParadoxicalCondition

Emitted when a paradox is encountered in your programs logic that could not be caught by `RedundantCondition`

```php
<?php

function foo($a, $b) : void {
    if ($a && $b) {
        echo "a";
    } elseif ($a && $b) {
        echo "cannot happen";
    }
}
```
# OverriddenInterfaceConstant

Emitted when a constant declared on an interface is overridden by a child (illegal in PHP < 8.1).

```php
<?php

interface Foo
{
    public const BAR='baz';
}

interface Bar extends Foo
{
    public const BAR='foobar';
}
```
# DuplicateArrayKey

Emitted when an array has a key more than once

```php
<?php

$arr = [
    'a' => 'one',
    'b' => 'two',
    'c' => 'this text will be overwritten by the next line',
    'c' => 'three',
];
```

This can be caused by variadic arguments if `@no-named-arguments` is not specified:

```php
<?php
function foo($bar, ...$baz): array
{
    return [$bar, ...$baz]; // $baz is array<array-key, mixed> since it can have named arguments
}
```

## How to fix

Remove the offending duplicates:

```php
<?php

$arr = [
    'a' => 'one',
    'b' => 'two',
    'c' => 'three',
];
```

The first matching `'c'` key was removed to prevent a change in behaviour (any new duplicate keys overwrite the values of previous ones).
# AbstractInstantiation

Emitted when an attempt is made to instantiate an abstract class:

```php
<?php

abstract class A {}
new A();
```
# UnsafeInstantiation

Emitted when an attempt is made to instantiate a class using `new static` or similar without a constructor that's final:

```php
<?php

class A {
    public function getInstance() : self
    {
        return new static();
    }
}
```

## What’s wrong here?

The problem comes when extending the class:

```php
<?php

class A {
    public function getInstance() : self
    {
        return new static();
    }
}

class AChild extends A {
    public function __construct(string $some_required_param) {}
}

AChild::getInstance(); // fatal error
```

## How to fix

You have two options – you can make the constructor final:

```php
<?php

class A {
    final public function __construct() {}

    public function getInstance() : self
    {
        return new static();
    }
}
```

Or you can add a `@psalm-consistent-constructor` annotation which ensures that any constructor in a child class has the same signature as the parent constructor:

```php
<?php

/**
 * @psalm-consistent-constructor
 */
class A {
    public function getInstance() : self
    {
        return new static();
    }
}

class AChild extends A {
    public function __construct() {
        // this is fine
    }
}

class BadAChild extends A {
    public function __construct(string $s) {
        // this is reported as a violation
    }
}
```
# RedundantCast

Emitted when a cast (string, int, float etc.) is redundant

```php
<?php
function foo(string $s) : string {
    return (string) $s;
}
```
# TaintedTextWithQuotes

Emitted when user-controlled input that can contain quotation marks can be passed into to an `echo` statement.

## Risk

This could lead to a potential Cross Site Scripting (XSS) vulnerability. Using a XSS vulnerability, an attacker could inject malicious JavaScript and execute any action JavaScript could do. Examples include:

- Stealing authentication material (e.g. cookies, JWT tokens)
- Exfiltrate sensitive information by reading the DOM
- Keylog entries on the website (e.g. fake login form)

Whether this is exploitable or not depends on a few conditions:

- Is an executable mimetype set? (e.g. `text/html`)
- Is the content served inline or as attachment? (`Content-Disposition`)
- Is the output properly sanitized? (e.g. stripping all HTML tags or having an allowlist of allowed characters)

## Example

```php
<?php
$param = strip_tags($_GET['param']);
?>

<script>
    console.log('<?=$param?>')
</script>
```

Passing `');alert('injection');//` as a `GET` param here would cause the `alert` to trigger.

## Mitigations

- Sanitize user input by using functions such as `htmlentities` with the `ENT_QUOTES` flag or use an allowlist.
- Set all cookies to `HTTPOnly`.
- Consider using Content Security Policy (CSP), to limit the risk of XSS vulnerabilities.

## Further resources

- [OWASP Wiki for Cross Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/)
- [Content-Security-Policy - Web Fundamentals](https://developers.google.com/web/fundamentals/security/csp)
# UnusedMethodCall

Emitted when `--find-dead-code` is turned on and Psalm finds a method call whose return value is not used anywhere

```php
<?php

final class A {
    private string $foo;

    public function __construct(string $foo) {
        $this->foo = $foo;
    }

    public function getFoo() : string {
        return $this->foo;
    }
}

$a = new A("hello");
$a->getFoo();
```
# InvalidPassByReference

Emitted when passing a non-variable to a function that expects a by-ref variable

```php
<?php

function foo(array &$arr) : void {}
foo([0, 1, 2]);
```
# UnusedPsalmSuppress

Emitted when `--find-unused-psalm-suppress` is turned on and Psalm cannot find any uses of a given `@psalm-suppress` annotation

```php
<?php

/** @psalm-suppress InvalidArgument */
echo strlen("hello");
```
# DeprecatedFunction

Emitted when calling a deprecated function:

```php
<?php

/** @deprecated */
function foo() : void {}
foo();
```

## Why this is bad

The `@deprecated` tag is normally indicative of code that will stop working in the near future.

## How to fix

Don’t use the deprecated function.
# RedundantFunctionCall

Emitted when a function call (`array_values`, `strtolower`, `ksort` etc.) is redundant.

```php
<?php

$a = ['already', 'a', 'list'];

$redundant = array_values($a);
$alreadyLower = strtolower($redundant[0]);
```
# TaintedInclude

Emitted when user-controlled input can be passed into to an `include` or `require` expression.

Passing untrusted user input to `include` calls is dangerous, as it can allow an attacker to execute arbitrary scripts on your server.

```php
<?php

$name = $_GET["name"];

includeCode($name);

function includeCode(string $name) : void {
    include($name . '.php');
}
```
# ImpurePropertyFetch

Emitted when fetching a property value inside a function or method marked as pure.

```php
<?php

class A {
    public int $a = 5;
}

/** @psalm-pure */
function foo(int $i, A $a) : int {
    return $i + $a->a;
}
```
# TypeDoesNotContainNull

Emitted when checking a non-nullable type for `null`

```php
<?php

$a = "hello";
if ($a === null) {}
```
# InvalidPropertyAssignment

Emitted when attempting to assign a property to a non-object

```php
<?php

$a = "foo";
$a->bar = "bar";
```
# PossiblyUnusedReturnValue

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a public/protected method’s return type.

```php
<?php

class A {
    public function foo() : string {
        return "hello";
    }
}
(new A)->foo();
```
# NoValue

Emitted when Psalm invalidated all possible types for a given expression. It is often an indication that Psalm found dead code or that documented types were not exhaustive

```php
<?php

/**
 * @return never
 */
function foo() : void {
    exit();
}

$a = foo(); // Psalm knows $a will never contain any type because foo() won't return
```

```php
<?php

function foo() : void {
    return throw new Exception(''); //Psalm detected the return expression is never used
}
```

```php
<?php
function shutdown(): never {die('Application closed unexpectedly');}
function foo(string $_a): void{}

foo(shutdown()); // foo() will never be called
```

```php
<?php
$a = [];
/** @psalm-suppress TypeDoesNotContainType */
assert(!empty($a));

count($a); // Assert above always fail. There is no possible type that $a can have here
```# InvalidScope

Emitted when referring to `$this` outside a class

```php
<?php

echo $this;
```
# PossiblyNullIterator

Emitted when trying to iterate over a value that may be null

```php
<?php

function foo(?array $arr) : void {
    foreach ($arr as $a) {}
}
```
# MissingThrowsDocblock

Enabled when the `checkForThrowsDocblock` configuration option is enabled.

Emitted when a function throws (or fails to handle) an exception and does not have a `@throws` annotation.

```php
<?php

function foo(int $x, int $y) : int {
    if ($y === 0) {
        throw new \InvalidArgumentException('Cannot divide by zero');
    }

    return intdiv($x, $y);
}
```
# PossiblyInvalidPropertyAssignment

Emitted when trying to assign a property on a value that may not be an object or may be an object that does not have the desired property.

```php
<?php

class A {
    /** @var ?string */
    public $bar;
}

/** @return A|int */
function foo() {
    return rand(0, 1) ? new A : 5;
}

$a = foo();
$a->bar = "5";
```
# TraitMethodSignatureMismatch

Emitted when a method's signature or return type differs from corresponding trait-defined method

```php
<?php

trait T {
    abstract public function foo(int $i);
}

class A {
    use T;

    public function foo(string $s) : void {}
}
```
# MixedAssignment

Emitted when assigning an unannotated variable to a value for which Psalm
cannot infer a type more specific than `mixed`.

```php
<?php

$a = $GLOBALS['foo'];
```

## How to fix

The above example can be fixed in a few ways – by adding an `assert` call:

```php
<?php

$a = $GLOBALS['foo'];
assert(is_string($a));
```

or by adding an explicit cast:

```php
<?php

$a = (string) $GLOBALS['foo'];
```

or by adding a docblock

```php
<?php

/** @var string */
$a = $GLOBALS['foo'];
```
# CheckType

Checks if a variable matches a specific type.
Similar to [Trace](./Trace.md), but only shows if the type does not match the expected type.

```php
<?php

/** @psalm-check-type $x = 1 */
$x = 2; // Checked variable $x = 1 does not match $x = 2
```


```php
<?php

/** @psalm-check-type-exact $x = int */
$x = 2; // Checked variable $x = int does not match $x = 2
```
# UnimplementedAbstractMethod

Emitted when a class extends another, but does not implement all of its abstract methods

```php
<?php

abstract class A {
    abstract public function foo() : void;
}
class B extends A {}
```
# TaintedShell

Emitted when user-controlled input can be passed into to an `exec` call or similar.

```php
<?php

$command = $_GET["command"];

runCode($command);

function runCode(string $command) {
    exec($command);
}
```
# InvalidReturnStatement

Emitted when a function return statement is incorrect

```php
<?php

function foo() : string {
    return 5; // emitted here
}
```
# InvalidNullableReturnType

Emitted when a function can return a nullable value, but its given return type says otherwise

```php
<?php

function foo() : string {
    if (rand(0, 1)) {
        return "foo";
    }

    return null;
}
```
# InvalidToString

Emitted when a `__toString` method does not always return a `string`

```php
<?php

class A {
    public function __toString() {
        /** @psalm-suppress InvalidReturnStatement */
        return true;
    }
}
```
# NullPropertyAssignment

Emitted when trying to set a property on `null`

```php
<?php

$a = null;
$a->foo = "bar";
```
# MismatchingDocblockParamType

Emitted when an `@param` entry in a function’s docblock does not match the param typehint

```php
<?php

/**
 * @param int $b
 */
function foo(string $b) : void {}
```
# MissingFile

Emitted when using `include` or `require` on a file that does not exist

```php
<?php

require("nonexistent.php");
```
# UnusedClass

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a
given class.

If this class is used and part of the public API, annotate it with `@psalm-api`.

```php
<?php

class A {}
class B {}
$a = new A();
```
# UnusedParam

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a particular parameter in a private method or function

```php
<?php

function foo(int $a, int $b) : int {
    return $a + 4;
}
```

Can be suppressed by prefixing the parameter name with an underscore:

```php
function foo(int $_a, int $b) : int {
    return $b + 4;
}
```
# PossiblyUnusedParam

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a particular parameter in a public/protected method

```php
<?php

class A {
    public function foo(int $a, int $b) : int {
        return $a + 4;
    }
}

$a = new A();
echo $a->foo(1, 2);
```

Can be suppressed by prefixing the parameter name with an underscore:

```php
<?php
class A {
    public function foo(int $a, int $_b) : int {
        return $a + 4;
    }
}
```
# InaccessibleProperty

Emitted when attempting to access a protected/private property from outside its available scope

```php
<?php

class A {
    /** @return string */
    protected $foo;
}
echo (new A)->foo;
```
# PossiblyInvalidPropertyFetch

Emitted when trying to fetch a property on a value that may not be an object or may be an object that does not have the desired property.

```php
<?php

class A {
    /** @var ?string */
    public $bar;
}

/** @return A|int */
function foo() {
    return rand(0, 1) ? new A : 5;
}

$a = foo();
echo $a->bar;
```
# MissingTemplateParam

Emitted when using the `@extends`/`@implements` annotation to extend a class without
extending all its template params.

```php
<?php

/**
 * @template-implements ArrayAccess<int>
 */
class SomeIterator implements ArrayAccess
{
    public function offsetSet($offset, $value) {
    }

    public function offsetExists($offset) {
        return false;
    }

    public function offsetUnset($offset) {
    }

    public function offsetGet($offset) {
        return null;
    }
}
```
# FalsableReturnStatement

Emitted if a return statement contains a false value, but the function return type does not allow false

```php
<?php

function getCommaPosition(string $a) : int {
    return strpos($a, ',');
}
```

## How to fix

You can add a specific check for false:

```php
<?php

function getCommaPosition(string $a) : int {
    $pos = strpos($a, ',');

    if ($pos === false) {
        return -1;
    }

    return $pos;
}
```

Alternatively you may choose to throw an exception:

```php
<?php

function getCommaPosition(string $a) : int {
    $pos = strpos($a, ',');

    if ($pos === false) {
        throw new Exception('This is unexpected');
    }

    return $pos;
}
```
# MixedStringOffsetAssignment

Emitted when assigning a value on a string using a value for which Psalm cannot infer a type

```php
<?php

"hello"[0] = $GLOBALS['foo'];
```
# NamedArgumentNotAllowed

Emitted when a named argument is used when calling a function with `@no-named-arguments`.

```php
<?php

/** @no-named-arguments */
function foo(int $a, int $b): int {
	return $a + $b;
}

foo(a: 0, b: 1);

```

## Why this is bad

The `@no-named-arguments` annotation indicates that argument names may be changed in the future, and an update may break backwards compatibility with function calls using named arguments.

## How to fix

Avoid using named arguments for functions annotated with `@no-named-arguments`.

```php
<?php

/** @no-named-arguments */
function foo(int $a, int $b): int {
	return $a + $b;
}

foo(0, 1);

```
# PossiblyUndefinedVariable

Emitted when trying to access a variable in function scope that may not be defined

```php
<?php

function foo() : void {
    if (rand(0, 1)) {
        $a = 5;
    }
    echo $a;
}
```
# UnresolvableConstant

Emitted when Psalm cannot resolve a constant used in `key-of` or `value-of`. Note that `static::CONST` is considered
unresolvable for `key-of` and `value-of`, since the literal keys and values can't be resolved due to the possibility
of being overridden by child classes.

```php
<?php

class Foo
{
    public const BAR = ['bar'];

    /**
     * @return value-of<self::BAT>
     */
    public function bar(): string
    {
        return self::BAR[0];
    }
}
```
# CircularReference

Emitted when a class references itself as one of its parents

```php
<?php

class A extends B {}
class B extends A {}
```

## Why this is bad

The code above will not compile
# ConfigIssue

Emitted for non-fatal configuration issues, e.g. deprecated configuration switches.

## Why this is bad

Your config file may be incompatible with future Psalm versions.
# UndefinedMagicPropertyAssignment

Emitted when assigning a property on an object that does not have that magic property defined

```php
<?php

/**
 * @property string $bar
 */
class A {
    /** @param mixed $value */
    public function __set(string $name, $value) {}
}
$a = new A();
$a->foo = "bar";
```
# MethodSignatureMismatch

Emitted when a method parameter differs from a parent method parameter, or if there are fewer parameters than the parent method

```php
<?php

class A {
    public function foo(int $i) : void {}
}
class B extends A {
    public function foo(string $i) : void {}
}
```
# PossiblyNullFunctionCall

Emitted when trying to call a function on a value that may be null

```php
<?php

function foo(?callable $a) : void {
    $a();
}
```
# PossiblyUndefinedGlobalVariable

Emitted when trying to access a variable in the global scope that may not be defined

```php
<?php

if (rand(0, 1)) {
  $a = 5;
}
echo $a;
```
# InvalidArrayAccess

Emitted when attempting to access an array offset on a value that does not permit it

```php
<?php

$arr = 5;
echo $arr[0];
```
# ImplementedParamTypeMismatch

Emitted when a class that inherits another, or implements an interface, has a docblock param type that's entirely different to the parent.

```php
<?php

class D {
    /** @param string $a */
    public function foo($a): void {}
}

class E extends D {
    /** @param int $a */
    public function foo($a): void {}
}
```

## How to fix

Make sure to respect the [Liskov substitution principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) – any method that overrides a parent method must accept all the same arguments as its parent method.

```php
<?php

class D {
    /** @param string $a */
    public function foo($a): void {}
}

class E extends D {
    /** @param string|int $a */
    public function foo($a): void {}
}
```
# NonInvariantPropertyType

Emitted when a public or protected class property has a different type to the matching property in the parent class.

```php
<?php

class A {
    public string $foo = 'hello';
}

class B extends A {
    public ?string $foo;
}

```

## Why this is bad

For typed properties, this can cause a compile error.
# InternalProperty

Emitted when attempting to access a property marked as internal from an unrelated namespace or class, or attempting
to access a property marked as psalm-internal to a different namespace.

```php
<?php

namespace A {
    class Foo {
        /**
         * @internal
         * @var ?int
         */
        public $foo;
    }
}

namespace B {
    class Bat {
        public function batBat() : void {
            echo (new \A\Foo)->foo;
        }
    }
}
```
# DeprecatedClass

Emitted when referring to a deprecated class:

```php
<?php

/** @deprecated */
class A {}
new A();
```

## Why this is bad

The `@deprecated` tag is normally indicative of code that will stop working in the near future.

## How to fix

Don’t use the deprecated class.
# DuplicateEnumCaseValue

Emitted when a backed enum has duplicate case values.

```php
<?php

enum Status: string 
{
    case Open = "open";
    case Closed = "open";
}
```

## How to fix

Change case values so that there are no duplicates.

```php
<?php

enum Status: string 
{
    case Open = "open";
    case Closed = "closed";
}
```
# InvalidArrayOffset

Emitted when attempting to access an array using a value that's not a valid offset for that array

```php
<?php

$a = [5, 20, 18];
echo $a["hello"];
```
# NullReference

Emitted when attempting to call a method on `null`

```php
<?php

$a = null;
$a->foo();
```
# RedundantCastGivenDocblockType

Emitted when a cast (string, int, float etc.) is redundant given the docblock-provided type

```php
<?php
/**
 * @param  string $s
 */
function foo($s) : string {
    return (string) $s;
}
```
# UnimplementedInterfaceMethod

Emitted when a class `implements` an interface but does not implement all of its methods

```php
<?php

interface I {
    public function foo() : void;
}
class A implements I {}
```
# OverriddenPropertyAccess

Emitted when a property is less accessible than the same-named property in its parent class

```php
<?php

class A {
    /** @var string|null */
    public $foo;
}
class B extends A {
    /** @var string|null */
    protected $foo;
}
```
# PossibleRawObjectIteration

Emitted when possibly iterating over an object’s properties, the comparison to [RawObjectIteration](#rawobjectiteration).

```php
<?php

class A {
    /** @var string|null */
    public $foo;

    /** @var string|null */
    public $bar;
}

function takesA(A $a) {
    if (rand(0, 1)) {
        $a = [1, 2, 3];
    }

    foreach ($a as $property) {}
}
```
# PossiblyFalseReference

Emitted when making a method call on a value that might be `false`

```php
<?php

class A {
    public function bar() : void {}
}

/** @return A|false */
function foo() {
    return rand(0, 1) ? new A : false;
}

foo()->bar();
```
# PossiblyFalseIterator

Emitted when trying to iterate over a value that may be `false`

```php
<?php

$arr = rand(0, 1) ? [1, 2, 3] : false;
foreach ($arr as $a) {}
```
# RawObjectIteration

Emitted when iterating over an object’s properties. This issue exists because it may be undesired behaviour (e.g. you may have meant to iterate over an array)

```php
<?php

class A {
    /** @var string|null */
    public $foo;

    /** @var string|null */
    public $bar;
}

function takesA(A $a) {
    foreach ($a as $property) {}
}
```
# MissingImmutableAnnotation

Emitted when a class inheriting from an immutable interface or class does not also have a `@psalm-immutable` declaration

```php
<?php

/** @psalm-immutable */
interface SomethingImmutable {
    public function someInteger() : int;
}

class MutableImplementation implements SomethingImmutable {
    private int $counter = 0;
    public function someInteger() : int {
        return ++$this->counter;
    }
}
```
# PossiblyNullPropertyAssignmentValue

Emitted when trying to assign a value that may be null to a property that only takes non-null values.

```php
<?php

class A {
    /** @var string */
    public $foo = "bar";
}

function assignToA(?string $s) {
    $a = new A();
    $a->foo = $s;
}
```
# ConstantDeclarationInTrait

Emitted when a trait declares a constant in PHP <8.2.0

```php
<?php

trait A {
    const B = 0;
}
```

## Why this is bad

A fatal error will be thrown.
# MissingPropertyType

Emitted when a property is defined on a class without a type

```php
<?php

class A {
    public $foo = 5;
}
```

This feature is available in PHP since version 7.4

For more information see:
* [Properties](https://www.php.net/manual/en/language.oop5.properties.php) in the PHP manual.
* PHP RFC: [Typed Properties 2.0](https://wiki.php.net/rfc/typed_properties_v2)
# MixedReturnStatement

Emitted when Psalm cannot determine the type of a given return statement

```php
<?php

function foo() : int {
    return $GLOBALS['foo']; // emitted here
}
```
# TaintedCustom

Emitted when tainted input detection is turned on and custom-tainted data is detected.
# ComplexMethod

Emitted when a method is too complicated. Complicated methods should be split up.
# InvalidClassConstantType

Emitted when a constant type in a child does not satisfy the type in the parent.

```php
<?php

class Foo
{
    /** @var int<1,max> */
    public const CONSTANT = 3;

    public static function bar(): array
    {
        return str_split("foobar", static::CONSTANT);
    }
}

class Bar extends Foo
{
    /** @var int<min,-1> */
    public const CONSTANT = -1;
}

Bar::bar(); // Error: str_split argument 2 must be greater than 0
```

This issue will always show up when overriding a constant that doesn't have a docblock type. Psalm will infer the most specific type for the constant that it can, you have to add a type annotation to tell it what type constraint you wish to be applied. Otherwise Psalm has no way of telling if you mean for the constant to be a literal `1`, `int<1, max>`, `int`, `numeric`, etc.
# InvalidCatch

Emitted when trying to catch a class/interface that doesn't extend `Exception` or implement `Throwable`

```php
<?php

class A {}
try {
    $worked = true;
}
catch (A $e) {}
```
# ParamNameMismatch

Emitted when method overrides a parent method but renames a param.

```php
<?php

class A {
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $string, bool $b = false) : void {}
}
```

## Why is this bad?

PHP 8 introduces [named parameters](https://wiki.php.net/rfc/named_params) which allow developers to call methods with explicitly-named parameters;

```php
<?php

function callFoo(A $a) {
    $a->foo(str: "hello");
}
```

In the first example passing `new AChild()` to `callFoo()` results in a fatal error, as AChild's definition of the method `foo()` doesn't have a parameter named `$str`.

## How to fix

You can change the child method param name to match:

```php
<?php

class A {
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $str, bool $b = false) : void {}
}
```

This fix [can be applied automatically by Psalter](https://psalm.dev/docs/manipulating_code/fixing/#paramnamemismatch).

## Workarounds

### @no-named-arguments

Alternatively you can ignore this issue by adding a `@no-named-arguments` annotation to the parent method:

```php
<?php

class A {
    /** @no-named-arguments */
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $string, bool $b = false) : void {}
}
```

Any method with this annotation will be prevented (by Psalm) from being called with named parameters, so the original issue does not matter.

### Config allowNamedArgumentCalls="false"

This prevents any use of named params in your codebase. Ideal for self-contained projects, but less ideal for libraries.

It means the original code above will not emit any errors as long as the class `A` is defined in a directory that Psalm can scan.

### Config allowInternalNamedArgumentCalls="false"

For library authors Psalm supports a more nuanced flag that tells Psalm to prohibit any named parameter calls on `@internal` classes or methods.

With that config value, this is now allowed:

```php
<?php

/**
 * @internal
 */
class A {
    public function foo(string $str, bool $b = false) : void {}
}

class AChild extends A {
    public function foo(string $string, bool $b = false) : void {}
}
```
# NullArgument

Emitted when calling a function with a null value argument when the function does not expect it

```php
<?php

function foo(string $s) : void {}
foo(null);
```
# MixedMethodCall

Emitted when calling a method on a value that Psalm cannot infer a type for

```php
<?php

class A {
    public function foo() : void {}
}

function callFoo(array $arr) : void {
    array_pop($arr)->foo(); // MixedMethodCall emitted here
}

callFoo(
    [new A()]
);
```

## Why this is bad

If Psalm does not know what `array_pop($arr)` is, it can't verify whether `array_pop($arr)->foo()` will work or not.

## How to fix

Make sure that to provide as much type information as possible to Psalm so that it can perform inference. For example, you could add a docblock to the `callFoo` function:

```php
<?php

class A {
    public function foo() : void {}
}

/**
 * @param  array<A> $arr
 */
function callFoo(array $arr) : void {
    array_pop($arr)->foo(); // MixedMethodCall emitted here
}

callFoo(
    [new A()]
);
```

Alternatively you could add a runtime check:

```php
<?php

class A {
    public function foo() : void {}
}

function callFoo(array $arr) : void {
    $a = array_pop($arr);
    assert($a instanceof A);
    $a->foo(); // MixedMethodCall emitted here
}

callFoo(
    [new A()]
);
```
# UndefinedInterface

Emitted when referencing an interface that does not exist but does have an identically-named class.

```php
<?php

class C {}

interface I extends C {}
```
# RiskyCast

Emitted when attempting to cast an array to int or float

```php
<?php

$foo = (int) array( 'hello' );
```

## Why this is bad

The value resulting from the cast depends on if the array is empty or not and can easily lead to off-by-one errors

## How to fix

Don't cast arrays to int or float.
# TaintedCookie

Potential cookie injection. This rule is emitted when user-controlled input can be passed into a cookie.

## Risk

The risk of setting arbitrary cookies depends on further application configuration. 

Examples of potential issues:

- Session Fixation: If the authentication cookie doesn't change after a successful login an attacker could fixate the session cookie. If a victim logs in with a fixated cookie, the attacker can now take over the session of the user.
- Cross-Site-Scripting (XSS): Some application code could read cookies and print it out unsanitized to the user.



## Example

```php
<?php

setcookie('authtoken', $_GET['value'], time() + (86400 * 30), '/');
```

## Mitigations

If this is required functionality, limit the cookie setting to values and not the name. (e.g. `authtoken` in the example)

Make sure to change session tokens after authentication attempts.

## Further resources

- [OWASP Wiki for Session fixation](https://owasp.org/www-community/attacks/Session_fixation)
- [Session Management Cheatsheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html)
- [CWE-384](https://cwe.mitre.org/data/definitions/384.html)
# PossiblyNullArrayAssignment

Emitted when trying to set a value on a possibly null array

```php
<?php

$a = null;
$a[0][] = 1;
```
# ImpureStaticVariable

Emitted when attempting to use a static variable from a function or method marked as pure

```php
<?php

/** @psalm-pure */
function addCumulative(int $left) : int {
    /** @var int */
    static $i = 0;
    $i += $left;
    return $left;
}
```
# InvalidEnumMethod

Enums may not define most of the magic methods like `__get`, `__toString`, etc.

```php
<?php
enum Status: string {
    case Open = 'open';
    case Closed = 'closed';

    public function __toString(): string {
        return "SomeStatus";
    }
}
```
# InternalClass

Emitted when attempting to access a class marked as internal an unrelated namespace or class, or attempting
to access a class marked as psalm-internal to a different namespace.

```php
<?php

namespace A {
    /**
     * @internal
     */
    class Foo { }
}

namespace B {
    class Bat {
        public function batBat(): void {
            $a = new \A\Foo();
        }
    }
}
```
# UndefinedThisPropertyFetch

Emitted when getting a property for an object in one of that object’s methods when no such property exists

```php
<?php

class A {
    function foo() {
        echo $this->foo;
    }
}
```
# PossiblyFalsePropertyAssignmentValue

Emitted when trying to assign a value that may be false to a property that only takes non-false values.

```php
<?php

class A {
    /** @var int */
    public $foo = 0;
}

function assignToA(string $s) {
    $a = new A();
    $a->foo = strpos($s, "haystack");
}
```
# PossiblyUndefinedStringArrayOffset

Emitted when the config flag `ensureArrayStringOffsetsExist` is set to `true` and an integer-keyed offset is not checked for existence

```php
<?php

/**
 * @param array<string, string> $arr
 */
function foo(array $arr) : void {
    echo $arr["hello"];
}
```
# ImpureMethodCall

Emitted when calling an impure method from a function or method marked as pure.

```php
<?php

class A {
    public int $a = 5;

    public function foo() : void {
        $this->a++;
    }
}

/** @psalm-pure */
function filterOdd(int $i, A $a) : ?int {
    $a->foo();

    if ($i % 2 === 0 || $a->a === 2) {
        return $i;
    }

    return null;
}
```
# PossiblyFalseArgument

Emitted when a function argument is possibly `false`, but the function does not expect `false`. This is distinct from a function argument is possibly `bool`, which results in `PossiblyInvalidArgument`.

```php
<?php

function foo(string $s) : void {
    $a_pos = strpos($s, "a");
    echo substr($s, $a_pos);
}
```
# NoInterfaceProperties

Emitted when trying to fetch a property on an interface as interfaces, by definition, do not have definitions for properties.

```php
<?php

interface I {}
class A implements I {
    /** @var ?string */
    public $foo;
}
function bar(I $i) : void {
    if ($i->foo) {}
}
```
# UndefinedGlobalVariable

Emitted when referencing a variable that doesn't exist

```php
<?php

echo $a;
```
# UnsafeGenericInstantiation

Emitted when an attempt is made to instantiate a class using `new static` without a constructor that's final:

```php
<?php

/**
 * @template T
 * @psalm-consistent-constructor
 */
class Container {
    /**
     * @var T
     */
    public $t;

    /**
     * @param T $t
     */
    public function __construct($t) {
        $this->t = $t;
    }

    /**
     * @template U
     * @param U $u
     * @return static<U>
     */
    public function getInstance($u) : static
    {
        return new static($u);
    }
}
```


## What’s wrong here?

The problem comes when extending the class:

```php
<?php

/**
 * @template T
 * @psalm-consistent-constructor
 */
class Container {
    /**
     * @var T
     */
    public $t;

    /**
     * @param T $t
     */
    public function __construct($t) {
        $this->t = $t;
    }

    /**
     * @template U
     * @param U $u
     * @return static<U>
     */
    public function getInstance($u) : static
    {
        return new static($u);
    }
}

/**
 * @extends Container<string>
 */
class StringContainer extends Container {}

$c = StringContainer::getInstance(new stdClass());
// creates StringContainer<stdClass>, clearly invalid
```

## How to fix

Either use `new self` instead of `new static`:

```php
<?php

/**
 * @template T
 * @psalm-consistent-constructor
 */
class Container {
    /**
     * @var T
     */
    public $t;

    /**
     * @param T $t
     */
    public function __construct($t) {
        $this->t = $t;
    }

    /**
     * @template U
     * @param U $u
     * @return self<U>
     */
    public function getInstance($u) : self
    {
        return new self($u);
    }
}
```

Or you can add a `@psalm-consistent-templates` annotation which ensures that any child class has the same generic params:

```php
<?php

/**
 * @template T
 * @psalm-consistent-constructor
 * @psalm-consistent-templates
 */
class Container {
    /**
     * @var T
     */
    public $t;

    /**
     * @param T $t
     */
    public function __construct($t) {
        $this->t = $t;
    }

    /**
     * @template U
     * @param U $u
     * @return static<U>
     */
    public function getInstance($u) : static
    {
        return new static($u);
    }
}

/**
 * @template T
 * @psalm-extends Container<T>
 */
class LazyLoadingContainer extends Container {}
```
# UndefinedAttributeClass

Emitted when referencing an attribute class that does not exist

```php
<?php
use Foo\Bar\Pure;

#[Pure]
class Video {}
```
# TaintedUnserialize

Tainted input detected to an `unserialize` call.

Passing untrusted user input to `unserialize` calls is dangerous – from the [PHP documentation on unserialize](https://www.php.net/manual/en/function.unserialize.php):

> Do not pass untrusted user input to unserialize() regardless of the options value of allowed_classes. Unserialization can result in code being loaded and executed due to object instantiation and autoloading, and a malicious user may be able to exploit this. Use a safe, standard data interchange format such as JSON (via json_decode() and json_encode()) if you need to pass serialized data to the user.

```php
<?php

$command = $_GET["data"];

getObject($command);

function getObject(string $data) : object {
    return unserialize($data);
}
```
# AssignmentToVoid

Emitted when assigning from a function that returns `void`:

```php
<?php

function foo() : void {}
$a = foo();
```

## Why this is bad

Though `void`-returning functions are treated by PHP as returning `null` (so this on its own does not lead to runtime errors), `void` is a concept more broadly in programming languages which is not designed for assignment purposes.

## How to fix

You should just be able to remove the assignment entirely:

```php
<?php

function foo() : void {}
foo();
```
# InvalidMethodCall

Emitted when attempting to call a method on a non-object

```php
<?php

$a = 5;
$a->foo();
```
# TaintedHtml

Emitted when user-controlled input that can contain HTML can be passed into to an `echo` statement.

## Risk

This could lead to a potential Cross Site Scripting (XSS) vulnerability. Using a XSS vulnerability, an attacker could inject malicious JavaScript and execute any action JavaScript could do. Examples include:

- Stealing authentication material (e.g. cookies, JWT tokens)
- Exfiltrate sensitive information by reading the DOM
- Keylog entries on the website (e.g. fake login form)

Whether this is exploitable or not depends on a few conditions:

- Is an executable mimetype set? (e.g. `text/html`)
- Is the content served inline or as attachment? (`Content-Disposition`)
- Is the output properly sanitized? (e.g. stripping all HTML tags or having an allowlist of allowed characters)

## Example

```php
<?php

$name = $_GET["name"];

printName($name);

function printName(string $name) {
    echo $name;
}
```

## Mitigations

- Sanitize user-input by using functions such as `htmlentities` or use an allowlist.
- Set all cookies to `HTTPOnly`.
- Consider using Content Security Policy (CSP), to limit the risk of XSS vulnerabilities.

## Further resources

- [OWASP Wiki for Cross Site Scripting (XSS)](https://owasp.org/www-community/attacks/xss/)
- [Content-Security-Policy - Web Fundamentals](https://developers.google.com/web/fundamentals/security/csp)
# ImplementedReturnTypeMismatch

Emitted when a class that inherits another, or implements an interface, has a docblock return type that's entirely different to the parent. 

```php
<?php

class A {
    /** @return bool */
    public function foo() {
        return true;
    }
}
class B extends A {
    /** @return string */
    public function foo()  {
        return "hello";
    }
}
```

## How to fix

Make sure to respect the [Liskov substitution principle](https://en.wikipedia.org/wiki/Liskov_substitution_principle) – any method that overrides a parent method must return a subtype of the parent method.

In the above case, that means adding the child return type to the parent one.

```php
<?php

class A {
    /** @return bool|string */
    public function foo() {
        return true;
    }
}
class B extends A {
    /** @return string */
    public function foo()  {
        return "hello";
    }
}
```
# InterfaceInstantiation

Emitted when an attempt is made to instantiate an interface:

```php
<?php

interface I {}
new I();
```
# UndefinedVariable

Emitted when referencing a variable that doesn't exist in a given function’s scope

```php
<?php

function foo() {
    echo $a;
}
```
# UndefinedInterfaceMethod

Emitted when calling a method that does not exist on an interface

```php
<?php

interface I {}

function foo(I $i) {
    $i->bar();
}
```
# ReferenceReusedFromConfusingScope

Emitted when a reference assigned in a potentially confusing scope is reused later.
Since PHP doesn't scope loops and ifs the same way most other languages do, a common issue is the reuse of a variable
declared in such a scope. Usually it doesn't matter, because a reassignment to an already-defined variable will just
reassign it, but if the already-defined variable is a reference it will change the value of the referred to variable.

```php
<?php

$arr = [1, 2, 3];
foreach ($arr as &$i) {
    ++$i;
}

// ...more code, after which the usage of $i as a reference has been forgotten by the programmer

for ($i = 0; $i < 10; ++$i) {
    echo $i;
}
// $arr is now [2, 3, 10] instead of the expected [2, 3, 4]
```

To fix the issue, unset the reference after using it in such a scope:

```php
<?php

$arr = [1, 2, 3];
foreach ($arr as &$i) {
    ++$i;
}
unset($i);

for ($i = 0; $i < 10; ++$i) {
    echo $i;
}
// $arr is correctly [2, 3, 4]
```
# InvalidExtendClass

Emitted when attempting to extend a final class or a class annotated with `@final`.

```php
<?php

final class A {}

class B extends A {}

/**
 * @final
 */
class DoctrineA {}

class DoctrineB extends DoctrineA {}
```
# UnnecessaryVarAnnotation

Emitted when `--find-dead-code` is turned on and you're using a `@var` annotation on an assignment that Psalm has already identified a type for.

```php
<?php

function foo() : string {
    return "hello";
}

/** @var string */
$a = foo();
```
# UndefinedTrait

Emitted when referencing a trait that does not exist

```php
<?php

class A {
    use T;
}
```
# ParseError

Emitted when the PHP Parser encounters an error.

```php
<?php

class A {
  public function foo() : void {
    echo "foo"
  }
}
```
# NonInvariantDocblockPropertyType

Emitted when a public or protected class property has a different docblock type to the matching property in the parent class.

```php
<?php

class A {
    /** @var null|string */
    public $foo = 'hello';
}

class AChild extends A {
    /** @var string */
    public $foo;
}
```

## Why this is bad

For non-typed properties, it can cause a type system violation when code written against the parent class reads or writes a value on an object of the child class.

If the child class widens the type then reading the value may return unexpected value that client code cannot deal with. If the child class narrows the type then code setting the value may set it to an invalid value:

```php
<?php

function takesA(A $a) {
    $a->foo = null; // this is valid for A
}

$child = new AChild();
takesA($child);
echo strlen($child->foo); // this is valid for AChild
```

## Workarounds

You can either broaden the type or you could, in certain situations, use templates instead:

```php
<?php

/**
 * @template T of string|null
 */
abstract class A {
    /** @var T */
    public $foo = 'hello';
}

/**
 * @extends A<string>
 */
class AChild extends A {
    /** @var string */
    public $foo;
}
```
# PossiblyUndefinedMethod

Emitted when trying to access a method that may not be defined on the object

```php
<?php

class A {
    public function bar() : void {}
}
class B {}

$a = rand(0, 1) ? new A : new B;
$a->bar();
```
# NullArrayOffset

Emitted when trying to access an array offset with `null`

```php
<?php

$arr = ['' => 5, 'foo' => 1];
echo $arr[null];
```
# InvalidArrayAssignment

Emitted when attempting to assign a value on a non-array

```php
<?php

$arr = 5;
$arr[0] = 3;
```
# PossiblyInvalidClone

Emitted when trying to clone a value that's possibly not cloneable

```php
<?php

class A {}

/**
 * @param A|string $a
 */
function foo($a) {
    return clone $a;
}
```
# TooManyTemplateParams

Emitted when using the `@extends`/`@implements` annotation to extend a class and adds too
many types.

```php
<?php

/**
 * @template-implements IteratorAggregate<int, string, int>
 */
class SomeIterator implements IteratorAggregate
{
    public function getIterator() {
        yield 5;
    }
}
```
# MismatchingDocblockReturnType

Emitted when an `@return` entry in a function’s docblock does not match the function return typehint

```php
<?php

class A {}
class B {}
/**
 * @return B // emitted here
 */
function foo() : A {
    return new A();
}
```

This, however, is fine:

```php
<?php

class A {}
class B extends A {}
/**
 * @return B // emitted here
 */
function foo() : A {
    return new B();
}
```
# DuplicateMethod

Emitted when a method is defined twice

```php
<?php

class A {
    public function foo() {}
    public function foo() {}
}
```
# ImpurePropertyAssignment

Emitted when updating a property value from a function or method marked as pure.

```php
<?php

class A {
    public int $a = 5;
}

/** @psalm-pure */
function foo(int $i, A $a) : int {
    $a->a = $i;

    return $i;
}
```
# ReservedWord

Emitted when using a reserved word as a class name

```php
<?php

function foo(resource $res) : void {}
```
# UnusedMethod

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a
given private method or function.

If this method is used and part of the public API, annotate the containing class
with `@psalm-api`.

```php
<?php

class A {
    public function __construct() {
        $this->foo();
    }
    private function foo() : void {}
    private function bar() : void {}
}
$a = new A();
```
# ReferenceConstraintViolation

Emitted when changing the type of a pass-by-reference variable

```php
<?php

function foo(string &$a) {
    $a = 5;
}
```
# InvalidGlobal

Emitted when there's a reference to the global keyword where it's not expected.

```php
<?php

global $e;
```

If the file is included from a non-global scope this issue will have to be suppressed. See
[Config suppression](../dealing_with_code_issues/#suppressing-issues) for how to suppress this at the file or directory
level.
# InvalidTypeImport

Emitted when a type imported with `@psalm-import-type` is invalid

```php
<?php

namespace A;

class Types {}

namespace B;
use A\Types;
/** @psalm-import-type UnknownType from Types */
class C {}
```
# MethodSignatureMustProvideReturnType

In PHP 8.1+, [most non-final internal methods now require overriding methods to declare a compatible return type, otherwise a deprecated notice is emitted during inheritance validation](https://www.php.net/manual/en/migration81.incompatible.php#migration81.incompatible.core.type-compatibility-internal).  

This issue is emitted when a method overriding a native method is defined without a return type.  

**Only if** the return type cannot be declared to keep support for PHP 7, a `#[ReturnTypeWillChange]` attribute can be added to silence the PHP deprecation notice and Psalm issue.  

```php
<?php
class A implements JsonSerializable {
    public function jsonSerialize() {
        return ['type' => 'A'];
    }
}
```
# FalseOperand

Emitted when using `false` as part of an operation (e.g. `+`, `.`, `^` etc.)

```php
<?php

echo 5 . false; 
```

## Why this is bad

`false` does not make sense in these operations
# MixedPropertyAssignment

Emitted when assigning a property to a value for which Psalm cannot infer a type

```php
<?php

/** @param mixed $a */
function foo($a) : void {
    $a->foo = "bar";
}
```
# UnrecognizedStatement

Emitted when Psalm encounters a code construct that it doesn't know how to handle. This should never happen.
# MissingClosureParamType

Emitted when a closure parameter has no type information associated with it

```php
<?php

$a = function($a): string {
    return "foo";
};
```
# DeprecatedMethod

Emitted when calling a deprecated method on a given class:

```php
<?php

class A {
    /** @deprecated */
    public function foo() : void {}
}
(new A())->foo();
```

## Why this is bad

The `@deprecated` tag is normally indicative of code that will stop working in the near future.

## How to fix

Don’t use the deprecated method.
# InvalidConstantAssignmentValue

Emitted when attempting to assign a value to a class constant that cannot contain that type.

```php
<?php

class Foo {
    /** @var int */
    public const BAR = "bar";
}
```
# UnrecognizedExpression

Emitted when Psalm encounters an expression that it doesn't know how to handle. This should never happen.
# DuplicateClass

Emitted when a class is defined twice

```php
<?php

class A {}
class A {}
```

## Why this is bad

The above code won’t compile.

PHP does allow you to define a class conditionally:

```php
<?php

if (rand(0, 1)) {
    class A {
        public function __construct(string $s) {}
    }
} else {
    class A {
        public function __construct(object $o) {}
    }
}
```

But Psalm _really_ doesn't want you to use this pattern – it's impossible for Psalm to know (without using reflection) which class is getting used.
# UnusedVariable

Emitted when `--find-dead-code` is turned on and Psalm cannot find any references to a variable, once instantiated

```php
<?php

function foo() : void {
    $a = 5;
    $b = 4;
    echo $b;
}
```

Can be suppressed by prefixing the variable name with an underscore:

```php
<?php

$_a = 22;
```
# ImplementationRequirementViolation

Emitted when a using class of a trait does not implement all interfaces specified using `@psalm-require-implements`.

```php
<?php

interface A { }
interface B { }

/**
 * @psalm-require-implements A
 * @psalm-require-implements B
 */
trait T { }

class C {
  // ImplementationRequirementViolation is emitted, as T requires
  // the using class C to implement A and B, which is not the case
  use T; 
}
```
# LessSpecificClassConstantType

Emitted when a constant type in a child is less specific than the type in the parent.

```php
<?php

class Foo
{
    /** @var int<1,max> */
    public const CONSTANT = 3;

    public static function bar(): array
    {
        return str_split("foobar", static::CONSTANT);
    }
}

class Bar extends Foo
{
    /** @var int */
    public const CONSTANT = -1;
}

Bar::bar(); // Error: str_split argument 2 must be greater than 0
```

This issue will always show up when overriding a constant that doesn't have a docblock type. Psalm will infer the most specific type for the constant that it can, you have to add a type annotation to tell it what type constraint you wish to be applied. Otherwise Psalm has no way of telling if you mean for the constant to be a literal `1`, `int<1, max>`, `int`, `numeric`, etc.
# Trace

Not really an issue. Just reports type of the variable.

```php
<?php

/** @psalm-trace $x */
$x = getmypid();
```

## How to fix

Use it for debugging purposes, not for production
# PropertyTypeCoercion

Emitted when setting a property with a value which has a less specific type than the property expects

```php
<?php

class A {}
class B extends A {}

function takesA(C $c, A $a) : void {
    $c->b = $a;
}

class C {
    /** @var ?B */
    public $b;
}
```
# TaintedUserSecret

Emitted when tainted input detection is turned on and data marked as a user secret is detected somewhere it shouldn’t be.

```php
<?php

class User {
    /**
     * @psalm-taint-source user_secret
     */
    public function getPassword() : string {
        return "$omePa$$word";
    }
}

function showUserPassword(User $user) {
    echo $user->getPassword();
}
```
# PossiblyInvalidCast

Emitted when attempting to cast a value that may not be castable

```php
<?php

class A {}
class B {
    public function __toString() {
        return 'hello';
    }
}
$c = (string) (rand(0, 1) ? new A() : new B());
```
# InvalidClone

Emitted when trying to clone a value that's not cloneable

```php
<?php

$a = "hello";
$b = clone $a;
```
# TypeDoesNotContainType

Emitted checking whether one value has a type or value that is impossible given its currently-known type

```php
<?php

$a = "hello";
if ($a === 5) {}
```
# NullOperand

Emitted when using `null` as part of an operation (e.g. `+`, `.`, `^` etc.)

```php
<?php

echo null . 'hello';
```
# UnusedClosureParam

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a particular parameter in a closure.

```php
<?php

$a = function (int $a, int $b) : int {
    return $a + 4;
};

/**
 * @param callable(int,int):int $c
 */
function foo(callable $c) : int {
    return $c(2, 4);
}
```

Can be suppressed by prefixing the parameter name with an underscore:

```php
$f = function (int $_a, int $b) : int {
    return $b + 4;
};
```
# MixedPropertyTypeCoercion

Emitted when Psalm cannot be sure that part of an array/iterable argument's type constraints can be fulfilled

```php
<?php

class A {
    /** @var string[] */
    public $takesStringArray = [];
}

function foo(A $a, array $arr) : void {
    $a->takesStringArray = $arr;
}
```
# InvalidLiteralArgument

Emitted when a literal argument is passed where a variable is expected, such as the first argument of `strpos`, where an explicit `$haystack` is almost always unintended.

```php
<?php

function foo(string $s) : void {
    echo strpos(".", $s);
}
```
# InvalidScalarArgument

Emitted when a scalar value is passed to a method that expected another scalar type.

This is only emitted in situations where Psalm can be sure that PHP tries to coerce one scalar type to another.

In all other cases `InvalidArgument` is emitted.

```php
<?php

function foo(int $i) : void {}
function bar(string $s) : void {
    if (is_numeric($s)) {
        foo($s);
    }
}
```
# InvalidTemplateParam

Emitted when using the `@extends`/`@implements` annotation to extend a class that has a template type constraint, where that extended value does not satisfy the parent class/interface's constraints.

```php
<?php

/**
 * @template T of object
 */
class Base {}

/** @template-extends Base<int> */
class SpecializedByInheritance extends Base {}
```
# InvalidThrow

Emitted when trying to throw a class that doesn't extend `Exception` or implement `Throwable`

```php
<?php

class A {}
throw new A();
```
# ImpureByReferenceAssignment

Emitted when assigning a passed-by-reference variable inside a function or method marked as mutation-free.

```php
<?php

/**
 * @psalm-pure
 */
function foo(string &$a): string {
    $a = "B";
    return $a;
}
```

## How to fix

Just remove the mutating assignment:

```php
<?php

/**
 * @psalm-pure
 */
function foo(string &$a): string {
    return $a;
}
```
# TaintedHeader

Potential header injection. This rule is emitted when user-controlled input can be passed into a HTTP header.

## Risk

The risk of a header injection depends hugely on your environment.

If your webserver supports something like [`XSendFile`](https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile/) / [`X-Accel`](https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/), an attacker could potentially access arbitrary files on the systems.

If your system does not do that, there may be other concerns, such as:

- Cookie Injection
- Open Redirects
- Proxy Cache Poisoning

## Example

```php
<?php

header($_GET['header']);
```

## Mitigations

Make sure only the value and not the key can be set by an attacker. (e.g. `header('Location: ' . $_GET['target']);`)

Verify the set values are sensible. Consider using an allow list. (e.g. for redirections)

## Further resources

- [Unvalidated Redirects and Forwards Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html)
- [OWASP Wiki for Cache Poisoning](https://owasp.org/www-community/attacks/Cache_Poisoning)
- [CWE-601](https://cwe.mitre.org/data/definitions/601.html)
- [CWE-644](https://cwe.mitre.org/data/definitions/644.html)
# ConstructorSignatureMismatch

Emitted when a constructor parameter differs from a parent constructor parameter, or if there are fewer parameters than the parent constructor AND where the parent class has a `@psalm-consistent-constructor` annotation.

```php
<?php

/**
 * @psalm-consistent-constructor
 */
class A {
    public function __construct(int $i) {}
}
class B extends A {
    public function __construct(string $s) {}
}
```
# MoreSpecificImplementedParamType

Emitted when a class implements an interface method but a param type is more specific than the interface method param type

```php
<?php

class A {}
class B extends A {
    public function bar(): void {}
}
class C extends A {
    public function bar(): void {}
}

class D {
    public function foo(A $a): void {}
}

class E extends D {
    /** @param B|C $a */
    public function foo(A $a): void {
        $a->bar();
    }
}
```
# PossiblyUndefinedArrayOffset

Emitted when trying to access a possibly undefined array offset

```php
<?php

if (rand(0, 1)) {
    $arr = ["a" => 1, "b" => 2];
} else {
    $arr = ["a" => 3];
}

echo $arr["b"];
```

## How to fix

You can use the null coalesce operator to provide a default value in the event the array offset does not exist:

```php
<?php

...

echo $arr["b"] ?? 0;
```

Alternatively, you can ensure that the array offset always exists:

```php
<?php

if (rand(0, 1)) {
    $arr = ["a" => 1, "b" => 2];
} else {
    $arr = ["a" => 3, "b" => 0];
}

echo $arr["b"];
```
# ImplicitToStringCast

Emitted when implicitly converting an object with a `__toString` method to a string

```php
<?php

class A {
    public function __toString() {
        return "foo";
    }
}

function takesString(string $s) : void {}

takesString(new A);
```

## How to fix

You can add an explicit string cast:

```php
<?php

...

takesString((string) new A);
```
# PossiblyInvalidArrayAssignment

Emitted when attempting to assign an array offset on a value that may not be an array

```php
<?php

$arr = rand(0, 1) ? 5 : [4, 3, 2, 1];
$arr[0] = "hello";
```
# MixedArrayAccess

Emitted when trying to access an array offset on a value whose type Psalm cannot determine

```php
<?php

echo $GLOBALS['foo'][0];
```
# InvalidDocblock

Emitted when there's an error in a docblock type

```php
<?php

/** @var array() */
$a = [];
```
# TooManyArguments

Emitted when calling a function with more arguments than the function has parameters

```php
<?php

function foo(string $a) : void {}
foo("hello", 4);
```
# MethodSignatureMustOmitReturnType

Emitted when a `__clone`, `__construct`, or `__destruct` method is defined with a return type.

```php
<?php

class A {
    public function __clone() : void {}
}
```
# ContinueOutsideLoop

Emitted when encountering a `continue` statement outside a loop context.

```php
<?php

$a = 5;
continue;
```

## Why this is bad

The code won't compile in PHP 5.6 and above.
# TaintedFile

This rule is emitted when user-controlled input can be passed into a sensitive file operation.

## Risk

The risk here depends on the actual operation that contains user-controlled input, and how it is later on processed.

It could range from:

- Creating files
    - Example: `file_put_contents`
    - Risk: Depending on the server configuration this may result in remote code execution. (e.g. writing a file in the web root)
- Modifying files
    - Example: `file_put_contents`
    - Risk: Depending on the server configuration this may result in remote code execution. (e.g. modifying a PHP file)
- Reading files
    - Example: `file_get_contents`
    - Risk: Sensitive data could be exposed from the filesystem. (e.g. config values, source code, user-submitted files)
- Deleting files
    - Example: `unlink`
    - Risk: Denial of Service or potentially RCE. (e.g. deleting application code, removing a .htaccess file)

## Example

```php
<?php

$content = file_get_contents($_GET['header']);
echo $content;
```

## Mitigations

Use an allowlist approach where possible to verify names on file operations.

Sanitize user-controlled filenames by stripping `..`, `\` and `/`.

## Further resources

- [File Upload Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/File_Upload_Cheat_Sheet.html)
- [OWASP Wiki for Unrestricted FIle Upload](https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload)
- [CWE-73](https://cwe.mitre.org/data/definitions/73.html)
# UndefinedConstant

Emitted when referencing a constant that does not exist

```php
<?php

echo FOO_BAR;
```
# LoopInvalidation

Emitted when logic inside a loop invalidates one of the conditionals of the loop

```php
<?php

for ($i = 0; $i < 10; $i++) {
    $i = 5;
}
```
# MixedFunctionCall

Emitted when calling a function on a value whose type Psalm cannot infer.

```php
<?php

/** @var mixed */
$a = $GLOBALS['foo'];
$a();
```
# TaintedSystemSecret

Emitted when data marked as a system secret is detected somewhere it shouldn’t be.

```php
<?php

/**
 * @psalm-taint-source system_secret
 */
function getConfigValue(string $data) {
    return "$omePa$$word";
}

echo getConfigValue("secret");
```
# InvalidEnumCaseValue

Emitted when case value is invalid (see below).

## Case with a value on a pure enum

```php
<?php

enum Status 
{
    case Open = "open";
}
```

### How to fix

Either remove the value or alter the enum to be backed.

```php
<?php

enum Status: string 
{
    case Open = "open";
}
```

## Case without a value on a backed enum

```php
<?php

enum Status: string 
{
    case Open;    
}
```

### How to fix

Either alter the enum to be pure, or add a value.

```php
<?php

enum Status 
{
    case Open;
}
```

## Case type mismatch

Case type should match the backing type of the enum.

```php
<?php

enum Status: string
{
    case Open = 1;
}
```

### How to fix

Change the types so that they match

```php
<?php

enum Status: string 
{
    case Open = "open";
}
```

## Case with a type that cannot back an enum

Case type should be either `int` or `string`.

```php
<?php

enum Status: int {
    case Open = [];
}
```

### How to fix

Change the case value so that it's one of the allowed types (and matches the backing type)

```php
<?php

enum Status: int
{
    case Open = 1;
}
```
# RedundantIdentityWithTrue

Emitted when comparing a known boolean with true and the `strictBinaryOperands` flag is set to true.

```php
<?php

function returnsABool(): bool {
    return rand(1, 2) === 1;
}

if (returnsABool() === true) {
    echo "hi!";
}

if (returnsABool() !== false) {
    echo "hi!";
}
```
# MixedArrayTypeCoercion

Emitted when trying to access an array with a less specific offset than is expected

```php
<?php

/**
 * @param array<array-key, int> $a
 * @param array<int, string> $b
 */
function foo(array $a, array $b) : void {
    foreach ($a as $j => $k) {
        echo $b[$j];
    }
}
```
# PossiblyNullReference

Emitted when trying to call a method on a possibly null value

```php
<?php

class A {
    public function bar() : void {}
}
function foo(?A $a) : void {
    $a->bar();
}
```
# UncaughtThrowInGlobalScope

Emitted when a possible exception isn't caught in global scope

```php
<?php

/**
 * @throws \Exception
 */
function foo() : int {
    return random_int(0, 1);
}
foo();
```
# UnusedBaselineEntry

Emitted when a baseline entry is not being used to suppress an issue.

Enabled by [findUnusedBaselineEntry](../configuration.md#findunusedbaselineentry) 

```php
<?php
$a = 'Hello, World!';
echo $a;
```
```xml
<?xml version="1.0" encoding="UTF-8"?>
<files>
    <file src="example.php">
        <UnusedVariable>
            <!-- The following entry is unused and should be removed. -->
            <code>$a</code>
        </UnusedVariable>
    </file>
</files>
```
# UninitializedProperty

Emitted when a property is used in a constructor before it is initialized

```php
<?php

class A {
    /** @var string */
    public $foo;

    public function __construct() {
        echo strlen($this->foo);
        $this->foo = "foo";
    }
}
```
# AmbiguousConstantInheritance

Emitted when a constant is inherited from multiple sources.

```php
<?php

interface Foo
{
    /** @var non-empty-string */
    public const CONSTANT='foo';
}

interface Bar
{
    /**
     * @var non-empty-string
     */
    public const CONSTANT='bar';
}

interface Baz extends Foo, Bar {}
```

```php
<?php

interface Foo
{
    /** @var non-empty-string */
    public const CONSTANT='foo';
}

class Bar
{
    /** @var non-empty-string */
    public const CONSTANT='bar';
}

class Baz extends Bar implements Foo {}
```
# TaintedSSRF

Potential Server-Side Request Forgery vulnerability. This rule is emitted when user-controlled input can be passed into a network request.

## Risk

Passing untrusted user input to network requests could be dangerous. 

If an attacker can fully control a HTTP request they could connect to internal services. Depending on the nature of these, this can pose a security risk. (e.g. backend services, admin interfaces, AWS metadata, ...)

## Example

```php
<?php
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $_GET['url']);

curl_exec($ch);

curl_close($ch);
```

## Mitigations

Mitigating SSRF vulnerabilities can be tricky. Disallowing IPs would likely not work as an attacker could create a malicious domain that points to an internal DNS name.

Consider:

1. Having an allow list of domains that can be connected to.
2. Pointing cURL to a proxy that has no access to internal resources.

## Further resources

- [OWASP Wiki for Server Side Request Forgery](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery)
- [CWE-918](https://cwe.mitre.org/data/definitions/918)# MissingDependency

Emitted when referencing a class that does not exist

```php
<?php

/**
 * @psalm-suppress UndefinedClass
 */
class A extends B {}

$a = new A();
```
# ParentNotFound

Emitted when using `parent::` in a class without a parent class.

```php
<?php

class A {
  public function foo() : void {
    parent::foo();
  }
}
```
# TaintedSql

Emitted when user-controlled input can be passed into to a SQL command.

```php
<?php

class A {
    public function deleteUser(PDO $pdo) : void {
        $userId = self::getUserId();
        $pdo->exec("delete from users where user_id = " . $userId);
    }

    public static function getUserId() : string {
        return (string) $_GET["user_id"];
    }
}
```
# TaintedEval

Emitted when user-controlled input can be passed into to an `eval` call.

Passing untrusted user input to `eval` calls is dangerous, as it allows arbitrary data to be executed on your server.

```php
<?php

$name = $_GET["name"];

evalCode($name);

function evalCode(string $name) {
    eval($name);
}
```
# MixedArgumentTypeCoercion

Emitted when Psalm cannot be sure that part of an array/iterable argument's type constraints can be fulfilled

```php
<?php

function foo(array $a) : void {
    takesStringArray($a);
}

/** @param string[] $a */
function takesStringArray(array $a) : void {}
```

This can happen with variadic arguments when `@no-named-arguments` is not specified:

```php
<?php

/** @param list<int> $args */
function foo(int ...$args): array {
    return $args; // $args is array<array-key, int> since it can have named arguments
}
```
# UnusedReturnValue

Emitted when `--find-dead-code` is turned on and Psalm cannot find any uses of a private method’s return value.

```php
<?php

class A {
    public function __construct() {
        $this->foo();
    }
    private function foo() : string {
        return "hello";
    }
}

new A();
```
# InvalidOperand

Emitted when using something as an operand that is unexpected

```php
<?php

class A {}
echo (new A) . ' ';
```
# MixedArrayAssignment

Emitted when trying to assign a value to an array offset on a value whose type Psalm cannot determine

```php
<?php

$GLOBALS['foo'][0] = "5";
```
# InvalidCast

Emitted when attempting to cast a value that's not castable

```php
<?php

class A {}
$a = new A();
$b = (string)$a;
```
# PropertyNotSetInConstructor

Uninitialized properties are hard to statically analyze. To prevent mistakes, Psalm will enforce that all properties should be initialized.

It does that through [MissingConstructor](./MissingConstructor.md) and this issue.

Psalm will then assume every property in the codebase is initialized.

Doing that allows it to report missing initializations as well as [RedundantPropertyInitializationCheck](./RedundantPropertyInitializationCheck.md)

This issue is emitted when a non-null property without a default value is declared but not set in the class’s constructor

If your project relies on having uninitialized properties, it is advised to suppress this issue, as well as [MissingConstructor](./MissingConstructor.md) and [RedundantPropertyInitializationCheck](./RedundantPropertyInitializationCheck.md).

```php
<?php

class A {
    /** @var string */
    public $foo;

    public function __construct() {}
}
```
# MissingParamType

Emitted when a function parameter has no type information associated with it

```php
<?php

function foo($a) : void {}
```
# MoreSpecificReturnType

Emitted when the declared return type for a method is more specific than the inferred one (emitted in the same methods that `LessSpecificReturnStatement` is)

```php
<?php

class A {}
class B extends A {}
function foo() : B {
    /** @psalm-suppress LessSpecificReturnStatement */
    return new A();
}
```
# InvalidEnumBackingType

Enums can only be backed by `int` or `string`. Emitted when an enum is backed
by something else.

```php
<?php

enum Status: array 
{
   case None = [];
}
```
# ConflictingReferenceConstraint

Emitted when a by-ref variable is set in two different branches of an if to different types.

```php
<?php

 class A {
    /** @var int */
    private $foo;

    public function __construct(int &$foo) {
        $this->foo = &$foo;
    }
}

class B {
    /** @var string */
    private $bar;

    public function __construct(string &$bar) {
        $this->bar = &$bar;
    }
}

if (rand(0, 1)) {
    $v = 5;
    $c = (new A($v)); // $v is constrained to an int
} else {
    $v = "hello";
    $c = (new B($v)); // $v is constrained to a string
}

$v = 8;
```

## Why this is bad

Psalm doesn't understand what the type of `$c` should be
<?php

namespace _HumbugBox1cb33d1f20f1;

return array('vimeo/psalm' => '5.6.0@e784128902dfe01d489c4123d69918a9f3c1eac5', 'nikic/php-parser' => 'v4.15.3@570e980a201d8ed0236b0a62ddf2c9cbb2034039');
composer.phar
/vendor/

# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
This allows you to install [Psalm](https://github.com/vimeo/psalm) without worrying about composer conflicts.
{
	"name": "psalm/phar",
	"description": "Composer-based Psalm Phar",
	"license": ["MIT"],
	"require": {
		"php": "^7.1 || ^8.0"
	},
	"conflict": {
		"vimeo/psalm" : "*"
	},
	"bin": ["psalm.phar"],
	"config": {
        "platform-check": false
    }
}
<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893::getLoader();
<?php

/*
 * This file is part of Composer.
 *
 * (c) Nils Adermann <naderman@naderman.de>
 *     Jordi Boggiano <j.boggiano@seld.be>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Composer\Autoload;

/**
 * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
 *
 *     $loader = new \Composer\Autoload\ClassLoader();
 *
 *     // register classes with namespaces
 *     $loader->add('Symfony\Component', __DIR__.'/component');
 *     $loader->add('Symfony',           __DIR__.'/framework');
 *
 *     // activate the autoloader
 *     $loader->register();
 *
 *     // to enable searching the include path (eg. for PEAR packages)
 *     $loader->setUseIncludePath(true);
 *
 * In this example, if you try to use a class in the Symfony\Component
 * namespace or one of its children (Symfony\Component\Console for instance),
 * the autoloader will first look for the class under the component/
 * directory, and it will then fallback to the framework/ directory if not
 * found before giving up.
 *
 * This class is loosely based on the Symfony UniversalClassLoader.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 * @author Jordi Boggiano <j.boggiano@seld.be>
 * @see    https://www.php-fig.org/psr/psr-0/
 * @see    https://www.php-fig.org/psr/psr-4/
 */
class ClassLoader
{
    /** @var ?string */
    private $vendorDir;

    // PSR-4
    /**
     * @var array[]
     * @psalm-var array<string, array<string, int>>
     */
    private $prefixLengthsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, array<int, string>>
     */
    private $prefixDirsPsr4 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr4 = array();

    // PSR-0
    /**
     * @var array[]
     * @psalm-var array<string, array<string, string[]>>
     */
    private $prefixesPsr0 = array();
    /**
     * @var array[]
     * @psalm-var array<string, string>
     */
    private $fallbackDirsPsr0 = array();

    /** @var bool */
    private $useIncludePath = false;

    /**
     * @var string[]
     * @psalm-var array<string, string>
     */
    private $classMap = array();

    /** @var bool */
    private $classMapAuthoritative = false;

    /**
     * @var bool[]
     * @psalm-var array<string, bool>
     */
    private $missingClasses = array();

    /** @var ?string */
    private $apcuPrefix;

    /**
     * @var self[]
     */
    private static $registeredLoaders = array();

    /**
     * @param ?string $vendorDir
     */
    public function __construct($vendorDir = null)
    {
        $this->vendorDir = $vendorDir;
    }

    /**
     * @return string[]
     */
    public function getPrefixes()
    {
        if (!empty($this->prefixesPsr0)) {
            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
        }

        return array();
    }

    /**
     * @return array[]
     * @psalm-return array<string, array<int, string>>
     */
    public function getPrefixesPsr4()
    {
        return $this->prefixDirsPsr4;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirs()
    {
        return $this->fallbackDirsPsr0;
    }

    /**
     * @return array[]
     * @psalm-return array<string, string>
     */
    public function getFallbackDirsPsr4()
    {
        return $this->fallbackDirsPsr4;
    }

    /**
     * @return string[] Array of classname => path
     * @psalm-return array<string, string>
     */
    public function getClassMap()
    {
        return $this->classMap;
    }

    /**
     * @param string[] $classMap Class to filename map
     * @psalm-param array<string, string> $classMap
     *
     * @return void
     */
    public function addClassMap(array $classMap)
    {
        if ($this->classMap) {
            $this->classMap = array_merge($this->classMap, $classMap);
        } else {
            $this->classMap = $classMap;
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix, either
     * appending or prepending to the ones previously set for this prefix.
     *
     * @param string          $prefix  The prefix
     * @param string[]|string $paths   The PSR-0 root directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @return void
     */
    public function add($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            if ($prepend) {
                $this->fallbackDirsPsr0 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr0
                );
            } else {
                $this->fallbackDirsPsr0 = array_merge(
                    $this->fallbackDirsPsr0,
                    (array) $paths
                );
            }

            return;
        }

        $first = $prefix[0];
        if (!isset($this->prefixesPsr0[$first][$prefix])) {
            $this->prefixesPsr0[$first][$prefix] = (array) $paths;

            return;
        }
        if ($prepend) {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                (array) $paths,
                $this->prefixesPsr0[$first][$prefix]
            );
        } else {
            $this->prefixesPsr0[$first][$prefix] = array_merge(
                $this->prefixesPsr0[$first][$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace, either
     * appending or prepending to the ones previously set for this namespace.
     *
     * @param string          $prefix  The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths   The PSR-4 base directories
     * @param bool            $prepend Whether to prepend the directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function addPsr4($prefix, $paths, $prepend = false)
    {
        if (!$prefix) {
            // Register directories for the root namespace.
            if ($prepend) {
                $this->fallbackDirsPsr4 = array_merge(
                    (array) $paths,
                    $this->fallbackDirsPsr4
                );
            } else {
                $this->fallbackDirsPsr4 = array_merge(
                    $this->fallbackDirsPsr4,
                    (array) $paths
                );
            }
        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
            // Register directories for a new namespace.
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        } elseif ($prepend) {
            // Prepend directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                (array) $paths,
                $this->prefixDirsPsr4[$prefix]
            );
        } else {
            // Append directories for an already registered namespace.
            $this->prefixDirsPsr4[$prefix] = array_merge(
                $this->prefixDirsPsr4[$prefix],
                (array) $paths
            );
        }
    }

    /**
     * Registers a set of PSR-0 directories for a given prefix,
     * replacing any others previously set for this prefix.
     *
     * @param string          $prefix The prefix
     * @param string[]|string $paths  The PSR-0 base directories
     *
     * @return void
     */
    public function set($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr0 = (array) $paths;
        } else {
            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
        }
    }

    /**
     * Registers a set of PSR-4 directories for a given namespace,
     * replacing any others previously set for this namespace.
     *
     * @param string          $prefix The prefix/namespace, with trailing '\\'
     * @param string[]|string $paths  The PSR-4 base directories
     *
     * @throws \InvalidArgumentException
     *
     * @return void
     */
    public function setPsr4($prefix, $paths)
    {
        if (!$prefix) {
            $this->fallbackDirsPsr4 = (array) $paths;
        } else {
            $length = strlen($prefix);
            if ('\\' !== $prefix[$length - 1]) {
                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
            }
            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
            $this->prefixDirsPsr4[$prefix] = (array) $paths;
        }
    }

    /**
     * Turns on searching the include path for class files.
     *
     * @param bool $useIncludePath
     *
     * @return void
     */
    public function setUseIncludePath($useIncludePath)
    {
        $this->useIncludePath = $useIncludePath;
    }

    /**
     * Can be used to check if the autoloader uses the include path to check
     * for classes.
     *
     * @return bool
     */
    public function getUseIncludePath()
    {
        return $this->useIncludePath;
    }

    /**
     * Turns off searching the prefix and fallback directories for classes
     * that have not been registered with the class map.
     *
     * @param bool $classMapAuthoritative
     *
     * @return void
     */
    public function setClassMapAuthoritative($classMapAuthoritative)
    {
        $this->classMapAuthoritative = $classMapAuthoritative;
    }

    /**
     * Should class lookup fail if not found in the current class map?
     *
     * @return bool
     */
    public function isClassMapAuthoritative()
    {
        return $this->classMapAuthoritative;
    }

    /**
     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
     *
     * @param string|null $apcuPrefix
     *
     * @return void
     */
    public function setApcuPrefix($apcuPrefix)
    {
        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
    }

    /**
     * The APCu prefix in use, or null if APCu caching is not enabled.
     *
     * @return string|null
     */
    public function getApcuPrefix()
    {
        return $this->apcuPrefix;
    }

    /**
     * Registers this instance as an autoloader.
     *
     * @param bool $prepend Whether to prepend the autoloader or not
     *
     * @return void
     */
    public function register($prepend = false)
    {
        spl_autoload_register(array($this, 'loadClass'), true, $prepend);

        if (null === $this->vendorDir) {
            return;
        }

        if ($prepend) {
            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
        } else {
            unset(self::$registeredLoaders[$this->vendorDir]);
            self::$registeredLoaders[$this->vendorDir] = $this;
        }
    }

    /**
     * Unregisters this instance as an autoloader.
     *
     * @return void
     */
    public function unregister()
    {
        spl_autoload_unregister(array($this, 'loadClass'));

        if (null !== $this->vendorDir) {
            unset(self::$registeredLoaders[$this->vendorDir]);
        }
    }

    /**
     * Loads the given class or interface.
     *
     * @param  string    $class The name of the class
     * @return true|null True if loaded, null otherwise
     */
    public function loadClass($class)
    {
        if ($file = $this->findFile($class)) {
            includeFile($file);

            return true;
        }

        return null;
    }

    /**
     * Finds the path to the file where the class is defined.
     *
     * @param string $class The name of the class
     *
     * @return string|false The path if found, false otherwise
     */
    public function findFile($class)
    {
        // class map lookup
        if (isset($this->classMap[$class])) {
            return $this->classMap[$class];
        }
        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
            return false;
        }
        if (null !== $this->apcuPrefix) {
            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
            if ($hit) {
                return $file;
            }
        }

        $file = $this->findFileWithExtension($class, '.php');

        // Search for Hack files if we are running on HHVM
        if (false === $file && defined('HHVM_VERSION')) {
            $file = $this->findFileWithExtension($class, '.hh');
        }

        if (null !== $this->apcuPrefix) {
            apcu_add($this->apcuPrefix.$class, $file);
        }

        if (false === $file) {
            // Remember that this class does not exist.
            $this->missingClasses[$class] = true;
        }

        return $file;
    }

    /**
     * Returns the currently registered loaders indexed by their corresponding vendor directories.
     *
     * @return self[]
     */
    public static function getRegisteredLoaders()
    {
        return self::$registeredLoaders;
    }

    /**
     * @param  string       $class
     * @param  string       $ext
     * @return string|false
     */
    private function findFileWithExtension($class, $ext)
    {
        // PSR-4 lookup
        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;

        $first = $class[0];
        if (isset($this->prefixLengthsPsr4[$first])) {
            $subPath = $class;
            while (false !== $lastPos = strrpos($subPath, '\\')) {
                $subPath = substr($subPath, 0, $lastPos);
                $search = $subPath . '\\';
                if (isset($this->prefixDirsPsr4[$search])) {
                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
                        if (file_exists($file = $dir . $pathEnd)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-4 fallback dirs
        foreach ($this->fallbackDirsPsr4 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
                return $file;
            }
        }

        // PSR-0 lookup
        if (false !== $pos = strrpos($class, '\\')) {
            // namespaced class name
            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
        } else {
            // PEAR-like class name
            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
        }

        if (isset($this->prefixesPsr0[$first])) {
            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
                if (0 === strpos($class, $prefix)) {
                    foreach ($dirs as $dir) {
                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                            return $file;
                        }
                    }
                }
            }
        }

        // PSR-0 fallback dirs
        foreach ($this->fallbackDirsPsr0 as $dir) {
            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
                return $file;
            }
        }

        // PSR-0 include paths.
        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
            return $file;
        }

        return false;
    }
}

/**
 * Scope isolated include.
 *
 * Prevents access to $this/self from included files.
 *
 * @param  string $file
 * @return void
 * @private
 */
function includeFile($file)
{
    include $file;
}
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    'HumbugBox3150\\Composer\\Semver\\Comparator' => $vendorDir . '/composer/semver/src/Comparator.php',
    'HumbugBox3150\\Composer\\Semver\\CompilingMatcher' => $vendorDir . '/composer/semver/src/CompilingMatcher.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\Bound' => $vendorDir . '/composer/semver/src/Constraint/Bound.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\Constraint' => $vendorDir . '/composer/semver/src/Constraint/Constraint.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\ConstraintInterface' => $vendorDir . '/composer/semver/src/Constraint/ConstraintInterface.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchAllConstraint' => $vendorDir . '/composer/semver/src/Constraint/MatchAllConstraint.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchNoneConstraint' => $vendorDir . '/composer/semver/src/Constraint/MatchNoneConstraint.php',
    'HumbugBox3150\\Composer\\Semver\\Constraint\\MultiConstraint' => $vendorDir . '/composer/semver/src/Constraint/MultiConstraint.php',
    'HumbugBox3150\\Composer\\Semver\\Interval' => $vendorDir . '/composer/semver/src/Interval.php',
    'HumbugBox3150\\Composer\\Semver\\Intervals' => $vendorDir . '/composer/semver/src/Intervals.php',
    'HumbugBox3150\\Composer\\Semver\\Semver' => $vendorDir . '/composer/semver/src/Semver.php',
    'HumbugBox3150\\Composer\\Semver\\VersionParser' => $vendorDir . '/composer/semver/src/VersionParser.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Checker' => $baseDir . '/src/Checker.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IO' => $baseDir . '/src/IO.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IsExtensionFulfilled' => $baseDir . '/src/IsExtensionFulfilled.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IsFulfilled' => $baseDir . '/src/IsFulfilled.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\IsPhpVersionFulfilled' => $baseDir . '/src/IsPhpVersionFulfilled.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Printer' => $baseDir . '/src/Printer.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Requirement' => $baseDir . '/src/Requirement.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\RequirementCollection' => $baseDir . '/src/RequirementCollection.php',
    'HumbugBox3150\\KevinGH\\RequirementChecker\\Terminal' => $baseDir . '/src/Terminal.php',
);
<?php

// autoload_static.php @generated by Composer

namespace Composer\Autoload;

class ComposerStaticInit7b1918d23e69dc64db20ca1f98396893
{
    public static $prefixLengthsPsr4 = array (
        'H' => 
        array (
            'HumbugBox3150\\KevinGH\\RequirementChecker\\' => 41,
            'HumbugBox3150\\Composer\\Semver\\' => 30,
        ),
    );

    public static $prefixDirsPsr4 = array (
        'HumbugBox3150\\KevinGH\\RequirementChecker\\' => 
        array (
            0 => __DIR__ . '/../..' . '/src',
        ),
        'HumbugBox3150\\Composer\\Semver\\' => 
        array (
            0 => __DIR__ . '/..' . '/composer/semver/src',
        ),
    );

    public static $classMap = array (
        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
        'HumbugBox3150\\Composer\\Semver\\Comparator' => __DIR__ . '/..' . '/composer/semver/src/Comparator.php',
        'HumbugBox3150\\Composer\\Semver\\CompilingMatcher' => __DIR__ . '/..' . '/composer/semver/src/CompilingMatcher.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\Bound' => __DIR__ . '/..' . '/composer/semver/src/Constraint/Bound.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\Constraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/Constraint.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\ConstraintInterface' => __DIR__ . '/..' . '/composer/semver/src/Constraint/ConstraintInterface.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchAllConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MatchAllConstraint.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\MatchNoneConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MatchNoneConstraint.php',
        'HumbugBox3150\\Composer\\Semver\\Constraint\\MultiConstraint' => __DIR__ . '/..' . '/composer/semver/src/Constraint/MultiConstraint.php',
        'HumbugBox3150\\Composer\\Semver\\Interval' => __DIR__ . '/..' . '/composer/semver/src/Interval.php',
        'HumbugBox3150\\Composer\\Semver\\Intervals' => __DIR__ . '/..' . '/composer/semver/src/Intervals.php',
        'HumbugBox3150\\Composer\\Semver\\Semver' => __DIR__ . '/..' . '/composer/semver/src/Semver.php',
        'HumbugBox3150\\Composer\\Semver\\VersionParser' => __DIR__ . '/..' . '/composer/semver/src/VersionParser.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Checker' => __DIR__ . '/../..' . '/src/Checker.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IO' => __DIR__ . '/../..' . '/src/IO.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IsExtensionFulfilled' => __DIR__ . '/../..' . '/src/IsExtensionFulfilled.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IsFulfilled' => __DIR__ . '/../..' . '/src/IsFulfilled.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\IsPhpVersionFulfilled' => __DIR__ . '/../..' . '/src/IsPhpVersionFulfilled.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Printer' => __DIR__ . '/../..' . '/src/Printer.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Requirement' => __DIR__ . '/../..' . '/src/Requirement.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\RequirementCollection' => __DIR__ . '/../..' . '/src/RequirementCollection.php',
        'HumbugBox3150\\KevinGH\\RequirementChecker\\Terminal' => __DIR__ . '/../..' . '/src/Terminal.php',
    );

    public static function getInitializer(ClassLoader $loader)
    {
        return \Closure::bind(function () use ($loader) {
            $loader->prefixLengthsPsr4 = ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::$prefixLengthsPsr4;
            $loader->prefixDirsPsr4 = ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::$prefixDirsPsr4;
            $loader->classMap = ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::$classMap;

        }, null, ClassLoader::class);
    }
}
<?php

// autoload_real.php @generated by Composer

class ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893
{
    private static $loader;

    public static function loadClassLoader($class)
    {
        if ('Composer\Autoload\ClassLoader' === $class) {
            require __DIR__ . '/ClassLoader.php';
        }
    }

    /**
     * @return \Composer\Autoload\ClassLoader
     */
    public static function getLoader()
    {
        if (null !== self::$loader) {
            return self::$loader;
        }

        spl_autoload_register(array('ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893', 'loadClassLoader'), true, true);
        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
        spl_autoload_unregister(array('ComposerAutoloaderInit7b1918d23e69dc64db20ca1f98396893', 'loadClassLoader'));

        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
        if ($useStaticLoader) {
            require __DIR__ . '/autoload_static.php';

            call_user_func(\Composer\Autoload\ComposerStaticInit7b1918d23e69dc64db20ca1f98396893::getInitializer($loader));
        } else {
            $classMap = require __DIR__ . '/autoload_classmap.php';
            if ($classMap) {
                $loader->addClassMap($classMap);
            }
        }

        $loader->setClassMapAuthoritative(true);
        $loader->register(true);

        return $loader;
    }
}

Copyright (c) Nils Adermann, Jordi Boggiano

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'HumbugBox3150\\KevinGH\\RequirementChecker\\' => array($baseDir . '/src'),
    'HumbugBox3150\\Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
);
<?php

namespace HumbugBox3150\Composer\Semver;

use HumbugBox3150\Composer\Semver\Constraint\Constraint;
class Semver
{
    const SORT_ASC = 1;
    const SORT_DESC = -1;
    private static $versionParser;
    public static function satisfies($version, $constraints)
    {
        if (null === self::$versionParser) {
            self::$versionParser = new VersionParser();
        }
        $versionParser = self::$versionParser;
        $provider = new Constraint('==', $versionParser->normalize($version));
        $parsedConstraints = $versionParser->parseConstraints($constraints);
        return $parsedConstraints->matches($provider);
    }
    public static function satisfiedBy(array $versions, $constraints)
    {
        $versions = \array_filter($versions, function ($version) use($constraints) {
            return Semver::satisfies($version, $constraints);
        });
        return \array_values($versions);
    }
    public static function sort(array $versions)
    {
        return self::usort($versions, self::SORT_ASC);
    }
    public static function rsort(array $versions)
    {
        return self::usort($versions, self::SORT_DESC);
    }
    private static function usort(array $versions, $direction)
    {
        if (null === self::$versionParser) {
            self::$versionParser = new VersionParser();
        }
        $versionParser = self::$versionParser;
        $normalized = array();
        foreach ($versions as $key => $version) {
            $normalizedVersion = $versionParser->normalize($version);
            $normalizedVersion = $versionParser->normalizeDefaultBranch($normalizedVersion);
            $normalized[] = array($normalizedVersion, $key);
        }
        \usort($normalized, function (array $left, array $right) use($direction) {
            if ($left[0] === $right[0]) {
                return 0;
            }
            if (Comparator::lessThan($left[0], $right[0])) {
                return -$direction;
            }
            return $direction;
        });
        $sorted = array();
        foreach ($normalized as $item) {
            $sorted[] = $versions[$item[1]];
        }
        return $sorted;
    }
}
<?php

namespace HumbugBox3150\Composer\Semver;

use HumbugBox3150\Composer\Semver\Constraint\ConstraintInterface;
use HumbugBox3150\Composer\Semver\Constraint\MatchAllConstraint;
use HumbugBox3150\Composer\Semver\Constraint\MultiConstraint;
use HumbugBox3150\Composer\Semver\Constraint\Constraint;
class VersionParser
{
    private static $modifierRegex = '[._-]?(?:(stable|beta|b|RC|alpha|a|patch|pl|p)((?:[.-]?\\d+)*+)?)?([.-]?dev)?';
    private static $stabilitiesRegex = 'stable|RC|beta|alpha|dev';
    public static function parseStability($version)
    {
        $version = \preg_replace('{#.+$}i', '', $version);
        if (\strpos($version, 'dev-') === 0 || '-dev' === \substr($version, -4)) {
            return 'dev';
        }
        \preg_match('{' . self::$modifierRegex . '(?:\\+.*)?$}i', \strtolower($version), $match);
        if (!empty($match[3])) {
            return 'dev';
        }
        if (!empty($match[1])) {
            if ('beta' === $match[1] || 'b' === $match[1]) {
                return 'beta';
            }
            if ('alpha' === $match[1] || 'a' === $match[1]) {
                return 'alpha';
            }
            if ('rc' === $match[1]) {
                return 'RC';
            }
        }
        return 'stable';
    }
    public static function normalizeStability($stability)
    {
        $stability = \strtolower($stability);
        return $stability === 'rc' ? 'RC' : $stability;
    }
    public function normalize($version, $fullVersion = null)
    {
        $version = \trim($version);
        $origVersion = $version;
        if (null === $fullVersion) {
            $fullVersion = $version;
        }
        if (\preg_match('{^([^,\\s]++) ++as ++([^,\\s]++)$}', $version, $match)) {
            $version = $match[1];
        }
        if (\preg_match('{@(?:' . self::$stabilitiesRegex . ')$}i', $version, $match)) {
            $version = \substr($version, 0, \strlen($version) - \strlen($match[0]));
        }
        if (\in_array($version, array('master', 'trunk', 'default'), \true)) {
            $version = 'dev-' . $version;
        }
        if (\stripos($version, 'dev-') === 0) {
            return 'dev-' . \substr($version, 4);
        }
        if (\preg_match('{^([^,\\s+]++)\\+[^\\s]++$}', $version, $match)) {
            $version = $match[1];
        }
        if (\preg_match('{^v?(\\d{1,5})(\\.\\d++)?(\\.\\d++)?(\\.\\d++)?' . self::$modifierRegex . '$}i', $version, $matches)) {
            $version = $matches[1] . (!empty($matches[2]) ? $matches[2] : '.0') . (!empty($matches[3]) ? $matches[3] : '.0') . (!empty($matches[4]) ? $matches[4] : '.0');
            $index = 5;
        } elseif (\preg_match('{^v?(\\d{4}(?:[.:-]?\\d{2}){1,6}(?:[.:-]?\\d{1,3})?)' . self::$modifierRegex . '$}i', $version, $matches)) {
            $version = \preg_replace('{\\D}', '.', $matches[1]);
            $index = 2;
        }
        if (isset($index)) {
            if (!empty($matches[$index])) {
                if ('stable' === $matches[$index]) {
                    return $version;
                }
                $version .= '-' . $this->expandStability($matches[$index]) . (!empty($matches[$index + 1]) ? \ltrim($matches[$index + 1], '.-') : '');
            }
            if (!empty($matches[$index + 2])) {
                $version .= '-dev';
            }
            return $version;
        }
        if (\preg_match('{(.*?)[.-]?dev$}i', $version, $match)) {
            try {
                $normalized = $this->normalizeBranch($match[1]);
                if (\strpos($normalized, 'dev-') === \false) {
                    return $normalized;
                }
            } catch (\Exception $e) {
            }
        }
        $extraMessage = '';
        if (\preg_match('{ +as +' . \preg_quote($version) . '(?:@(?:' . self::$stabilitiesRegex . '))?$}', $fullVersion)) {
            $extraMessage = ' in "' . $fullVersion . '", the alias must be an exact version';
        } elseif (\preg_match('{^' . \preg_quote($version) . '(?:@(?:' . self::$stabilitiesRegex . '))? +as +}', $fullVersion)) {
            $extraMessage = ' in "' . $fullVersion . '", the alias source must be an exact version, if it is a branch name you should prefix it with dev-';
        }
        throw new \UnexpectedValueException('Invalid version string "' . $origVersion . '"' . $extraMessage);
    }
    public function parseNumericAliasPrefix($branch)
    {
        if (\preg_match('{^(?P<version>(\\d++\\.)*\\d++)(?:\\.x)?-dev$}i', $branch, $matches)) {
            return $matches['version'] . '.';
        }
        return \false;
    }
    public function normalizeBranch($name)
    {
        $name = \trim($name);
        if (\preg_match('{^v?(\\d++)(\\.(?:\\d++|[xX*]))?(\\.(?:\\d++|[xX*]))?(\\.(?:\\d++|[xX*]))?$}i', $name, $matches)) {
            $version = '';
            for ($i = 1; $i < 5; ++$i) {
                $version .= isset($matches[$i]) ? \str_replace(array('*', 'X'), 'x', $matches[$i]) : '.x';
            }
            return \str_replace('x', '9999999', $version) . '-dev';
        }
        return 'dev-' . $name;
    }
    public function normalizeDefaultBranch($name)
    {
        if ($name === 'dev-master' || $name === 'dev-default' || $name === 'dev-trunk') {
            return '9999999-dev';
        }
        return $name;
    }
    public function parseConstraints($constraints)
    {
        $prettyConstraint = $constraints;
        $orConstraints = \preg_split('{\\s*\\|\\|?\\s*}', \trim($constraints));
        $orGroups = array();
        foreach ($orConstraints as $constraints) {
            $andConstraints = \preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
            if (\count($andConstraints) > 1) {
                $constraintObjects = array();
                foreach ($andConstraints as $constraint) {
                    foreach ($this->parseConstraint($constraint) as $parsedConstraint) {
                        $constraintObjects[] = $parsedConstraint;
                    }
                }
            } else {
                $constraintObjects = $this->parseConstraint($andConstraints[0]);
            }
            if (1 === \count($constraintObjects)) {
                $constraint = $constraintObjects[0];
            } else {
                $constraint = new MultiConstraint($constraintObjects);
            }
            $orGroups[] = $constraint;
        }
        $constraint = MultiConstraint::create($orGroups, \false);
        $constraint->setPrettyString($prettyConstraint);
        return $constraint;
    }
    private function parseConstraint($constraint)
    {
        if (\preg_match('{^([^,\\s]++) ++as ++([^,\\s]++)$}', $constraint, $match)) {
            $constraint = $match[1];
        }
        if (\preg_match('{^([^,\\s]*?)@(' . self::$stabilitiesRegex . ')$}i', $constraint, $match)) {
            $constraint = '' !== $match[1] ? $match[1] : '*';
            if ($match[2] !== 'stable') {
                $stabilityModifier = $match[2];
            }
        }
        if (\preg_match('{^(dev-[^,\\s@]+?|[^,\\s@]+?\\.x-dev)#.+$}i', $constraint, $match)) {
            $constraint = $match[1];
        }
        if (\preg_match('{^(v)?[xX*](\\.[xX*])*$}i', $constraint, $match)) {
            if (!empty($match[1]) || !empty($match[2])) {
                return array(new Constraint('>=', '0.0.0.0-dev'));
            }
            return array(new MatchAllConstraint());
        }
        $versionRegex = 'v?(\\d++)(?:\\.(\\d++|[xX*]))?(?:\\.(\\d++|[xX*]))?(?:\\.(\\d++|[xX*]))?' . self::$modifierRegex . '(?:\\+[^\\s]+)?';
        if (\preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
            if (\strpos($constraint, '~>') === 0) {
                throw new \UnexpectedValueException('Could not parse version constraint ' . $constraint . ': ' . 'Invalid operator "~>", you probably meant to use the "~" operator');
            }
            if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
                $position = 4;
            } elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }
            for ($i = $position; $i >= 0; $i--) {
                if ($matches[$i] === 'x' || $matches[$i] === 'X' || $matches[$i] === '*') {
                    $matches[$i] = '9999999';
                }
            }
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7])) {
                $stabilitySuffix .= '-dev';
            }
            $lowVersion = $this->normalize(\substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);
            $highPosition = \max(1, $position - 1);
            $highVersion = $this->manipulateVersionString($matches, $highPosition, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);
            return array($lowerBound, $upperBound);
        }
        if (\preg_match('{^\\^' . $versionRegex . '($)}i', $constraint, $matches)) {
            if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
                $position = 1;
            } elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
                $position = 2;
            } else {
                $position = 3;
            }
            if ($position === 2 && ($matches[2] === 'x' || $matches[2] === 'X' || $matches[2] === '*')) {
                $position = 1;
            }
            $stabilitySuffix = '';
            if (empty($matches[5]) && empty($matches[7])) {
                $stabilitySuffix .= '-dev';
            }
            $lowVersion = $this->normalize(\substr($constraint . $stabilitySuffix, 1));
            $lowerBound = new Constraint('>=', $lowVersion);
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
            $upperBound = new Constraint('<', $highVersion);
            return array($lowerBound, $upperBound);
        }
        if (\preg_match('{^v?(\\d++)(?:\\.(\\d++))?(?:\\.(\\d++))?(?:\\.[xX*])++$}', $constraint, $matches)) {
            if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
                $position = 3;
            } elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
                $position = 2;
            } else {
                $position = 1;
            }
            $lowVersion = $this->manipulateVersionString($matches, $position) . '-dev';
            $highVersion = $this->manipulateVersionString($matches, $position, 1) . '-dev';
            if ($lowVersion === '0.0.0.0-dev') {
                return array(new Constraint('<', $highVersion));
            }
            return array(new Constraint('>=', $lowVersion), new Constraint('<', $highVersion));
        }
        if (\preg_match('{^(?P<from>' . $versionRegex . ') +- +(?P<to>' . $versionRegex . ')($)}i', $constraint, $matches)) {
            $lowStabilitySuffix = '';
            if (empty($matches[6]) && empty($matches[8])) {
                $lowStabilitySuffix = '-dev';
            }
            $lowVersion = $this->normalize($matches['from']);
            $lowerBound = new Constraint('>=', $lowVersion . $lowStabilitySuffix);
            $empty = function ($x) {
                return $x === 0 || $x === '0' ? \false : empty($x);
            };
            if (!$empty($matches[11]) && !$empty($matches[12]) || !empty($matches[14]) || !empty($matches[16])) {
                $highVersion = $this->normalize($matches['to']);
                $upperBound = new Constraint('<=', $highVersion);
            } else {
                $highMatch = array('', $matches[10], $matches[11], $matches[12], $matches[13]);
                $this->normalize($matches['to']);
                $highVersion = $this->manipulateVersionString($highMatch, $empty($matches[11]) ? 1 : 2, 1) . '-dev';
                $upperBound = new Constraint('<', $highVersion);
            }
            return array($lowerBound, $upperBound);
        }
        if (\preg_match('{^(<>|!=|>=?|<=?|==?)?\\s*(.*)}', $constraint, $matches)) {
            try {
                try {
                    $version = $this->normalize($matches[2]);
                } catch (\UnexpectedValueException $e) {
                    if (\substr($matches[2], -4) === '-dev') {
                        $version = $this->normalize('dev-' . \substr($matches[2], 0, -4));
                    } else {
                        throw $e;
                    }
                }
                $op = $matches[1] ?: '=';
                if ($op !== '==' && $op !== '=' && !empty($stabilityModifier) && self::parseStability($version) === 'stable') {
                    $version .= '-' . $stabilityModifier;
                } elseif ('<' === $op || '>=' === $op) {
                    if (!\preg_match('/-' . self::$modifierRegex . '$/', \strtolower($matches[2]))) {
                        if (\strpos($matches[2], 'dev-') !== 0) {
                            $version .= '-dev';
                        }
                    }
                }
                return array(new Constraint($matches[1] ?: '=', $version));
            } catch (\Exception $e) {
            }
        }
        $message = 'Could not parse version constraint ' . $constraint;
        if (isset($e)) {
            $message .= ': ' . $e->getMessage();
        }
        throw new \UnexpectedValueException($message);
    }
    private function manipulateVersionString($matches, $position, $increment = 0, $pad = '0')
    {
        for ($i = 4; $i > 0; --$i) {
            if ($i > $position) {
                $matches[$i] = $pad;
            } elseif ($i === $position && $increment) {
                $matches[$i] += $increment;
                if ($matches[$i] < 0) {
                    $matches[$i] = $pad;
                    --$position;
                    if ($i === 1) {
                        return null;
                    }
                }
            }
        }
        return $matches[1] . '.' . $matches[2] . '.' . $matches[3] . '.' . $matches[4];
    }
    private function expandStability($stability)
    {
        $stability = \strtolower($stability);
        switch ($stability) {
            case 'a':
                return 'alpha';
            case 'b':
                return 'beta';
            case 'p':
            case 'pl':
                return 'patch';
            case 'rc':
                return 'RC';
            default:
                return $stability;
        }
    }
}
<?php

namespace HumbugBox3150\Composer\Semver\Constraint;

class Constraint implements ConstraintInterface
{
    const OP_EQ = 0;
    const OP_LT = 1;
    const OP_LE = 2;
    const OP_GT = 3;
    const OP_GE = 4;
    const OP_NE = 5;
    /**
    @phpstan-var
    */
    private static $transOpStr = array('=' => self::OP_EQ, '==' => self::OP_EQ, '<' => self::OP_LT, '<=' => self::OP_LE, '>' => self::OP_GT, '>=' => self::OP_GE, '<>' => self::OP_NE, '!=' => self::OP_NE);
    /**
    @phpstan-var
    */
    private static $transOpInt = array(self::OP_EQ => '==', self::OP_LT => '<', self::OP_LE => '<=', self::OP_GT => '>', self::OP_GE => '>=', self::OP_NE => '!=');
    /**
    @phpstan-var
    */
    protected $operator;
    protected $version;
    protected $prettyString;
    protected $lowerBound;
    protected $upperBound;
    public function __construct($operator, $version)
    {
        if (!isset(self::$transOpStr[$operator])) {
            throw new \InvalidArgumentException(\sprintf('Invalid operator "%s" given, expected one of: %s', $operator, \implode(', ', self::getSupportedOperators())));
        }
        $this->operator = self::$transOpStr[$operator];
        $this->version = $version;
    }
    public function getVersion()
    {
        return $this->version;
    }
    public function getOperator()
    {
        return self::$transOpInt[$this->operator];
    }
    public function matches(ConstraintInterface $provider)
    {
        if ($provider instanceof self) {
            return $this->matchSpecific($provider);
        }
        return $provider->matches($this);
    }
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return $this->__toString();
    }
    public static function getSupportedOperators()
    {
        return \array_keys(self::$transOpStr);
    }
    /**
    @phpstan-return
    */
    public static function getOperatorConstant($operator)
    {
        return self::$transOpStr[$operator];
    }
    public function versionCompare($a, $b, $operator, $compareBranches = \false)
    {
        if (!isset(self::$transOpStr[$operator])) {
            throw new \InvalidArgumentException(\sprintf('Invalid operator "%s" given, expected one of: %s', $operator, \implode(', ', self::getSupportedOperators())));
        }
        $aIsBranch = 'dev-' === \substr($a, 0, 4);
        $bIsBranch = 'dev-' === \substr($b, 0, 4);
        if ($operator === '!=' && ($aIsBranch || $bIsBranch)) {
            return $a !== $b;
        }
        if ($aIsBranch && $bIsBranch) {
            return $operator === '==' && $a === $b;
        }
        if (!$compareBranches && ($aIsBranch || $bIsBranch)) {
            return \false;
        }
        return \version_compare($a, $b, $operator);
    }
    public function compile($otherOperator)
    {
        if ($this->version[0] === 'd' && 'dev-' === \substr($this->version, 0, 4)) {
            if (self::OP_EQ === $this->operator) {
                if (self::OP_EQ === $otherOperator) {
                    return \sprintf('$b && $v === %s', \var_export($this->version, \true));
                }
                if (self::OP_NE === $otherOperator) {
                    return \sprintf('!$b || $v !== %s', \var_export($this->version, \true));
                }
                return 'false';
            }
            if (self::OP_NE === $this->operator) {
                if (self::OP_EQ === $otherOperator) {
                    return \sprintf('!$b || $v !== %s', \var_export($this->version, \true));
                }
                if (self::OP_NE === $otherOperator) {
                    return 'true';
                }
                return '!$b';
            }
            return 'false';
        }
        if (self::OP_EQ === $this->operator) {
            if (self::OP_EQ === $otherOperator) {
                return \sprintf('\\version_compare($v, %s, \'==\')', \var_export($this->version, \true));
            }
            if (self::OP_NE === $otherOperator) {
                return \sprintf('$b || \\version_compare($v, %s, \'!=\')', \var_export($this->version, \true));
            }
            return \sprintf('!$b && \\version_compare(%s, $v, \'%s\')', \var_export($this->version, \true), self::$transOpInt[$otherOperator]);
        }
        if (self::OP_NE === $this->operator) {
            if (self::OP_EQ === $otherOperator) {
                return \sprintf('$b || (!$b && \\version_compare($v, %s, \'!=\'))', \var_export($this->version, \true));
            }
            if (self::OP_NE === $otherOperator) {
                return 'true';
            }
            return '!$b';
        }
        if (self::OP_LT === $this->operator || self::OP_LE === $this->operator) {
            if (self::OP_LT === $otherOperator || self::OP_LE === $otherOperator) {
                return '!$b';
            }
        } elseif (self::OP_GT === $this->operator || self::OP_GE === $this->operator) {
            if (self::OP_GT === $otherOperator || self::OP_GE === $otherOperator) {
                return '!$b';
            }
        }
        if (self::OP_NE === $otherOperator) {
            return 'true';
        }
        $codeComparison = \sprintf('\\version_compare($v, %s, \'%s\')', \var_export($this->version, \true), self::$transOpInt[$this->operator]);
        if ($this->operator === self::OP_LE) {
            if ($otherOperator === self::OP_GT) {
                return \sprintf('!$b && \\version_compare($v, %s, \'!=\') && ', \var_export($this->version, \true)) . $codeComparison;
            }
        } elseif ($this->operator === self::OP_GE) {
            if ($otherOperator === self::OP_LT) {
                return \sprintf('!$b && \\version_compare($v, %s, \'!=\') && ', \var_export($this->version, \true)) . $codeComparison;
            }
        }
        return \sprintf('!$b && %s', $codeComparison);
    }
    public function matchSpecific(Constraint $provider, $compareBranches = \false)
    {
        $noEqualOp = \str_replace('=', '', self::$transOpInt[$this->operator]);
        $providerNoEqualOp = \str_replace('=', '', self::$transOpInt[$provider->operator]);
        $isEqualOp = self::OP_EQ === $this->operator;
        $isNonEqualOp = self::OP_NE === $this->operator;
        $isProviderEqualOp = self::OP_EQ === $provider->operator;
        $isProviderNonEqualOp = self::OP_NE === $provider->operator;
        if ($isNonEqualOp || $isProviderNonEqualOp) {
            if ($isNonEqualOp && !$isProviderNonEqualOp && !$isProviderEqualOp && 'dev-' === \substr($provider->version, 0, 4)) {
                return \false;
            }
            if ($isProviderNonEqualOp && !$isNonEqualOp && !$isEqualOp && 'dev-' === \substr($this->version, 0, 4)) {
                return \false;
            }
            if (!$isEqualOp && !$isProviderEqualOp) {
                return \true;
            }
            return $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
        }
        if ($this->operator !== self::OP_EQ && $noEqualOp === $providerNoEqualOp) {
            if ('dev-' === \substr($this->version, 0, 4) || 'dev-' === \substr($provider->version, 0, 4)) {
                return \false;
            }
            return \true;
        }
        $version1 = $isEqualOp ? $this->version : $provider->version;
        $version2 = $isEqualOp ? $provider->version : $this->version;
        $operator = $isEqualOp ? $provider->operator : $this->operator;
        if ($this->versionCompare($version1, $version2, self::$transOpInt[$operator], $compareBranches)) {
            return !(self::$transOpInt[$provider->operator] === $providerNoEqualOp && self::$transOpInt[$this->operator] !== $noEqualOp && \version_compare($provider->version, $this->version, '=='));
        }
        return \false;
    }
    public function __toString()
    {
        return self::$transOpInt[$this->operator] . ' ' . $this->version;
    }
    public function getLowerBound()
    {
        $this->extractBounds();
        return $this->lowerBound;
    }
    public function getUpperBound()
    {
        $this->extractBounds();
        return $this->upperBound;
    }
    private function extractBounds()
    {
        if (null !== $this->lowerBound) {
            return;
        }
        if (\strpos($this->version, 'dev-') === 0) {
            $this->lowerBound = Bound::zero();
            $this->upperBound = Bound::positiveInfinity();
            return;
        }
        switch ($this->operator) {
            case self::OP_EQ:
                $this->lowerBound = new Bound($this->version, \true);
                $this->upperBound = new Bound($this->version, \true);
                break;
            case self::OP_LT:
                $this->lowerBound = Bound::zero();
                $this->upperBound = new Bound($this->version, \false);
                break;
            case self::OP_LE:
                $this->lowerBound = Bound::zero();
                $this->upperBound = new Bound($this->version, \true);
                break;
            case self::OP_GT:
                $this->lowerBound = new Bound($this->version, \false);
                $this->upperBound = Bound::positiveInfinity();
                break;
            case self::OP_GE:
                $this->lowerBound = new Bound($this->version, \true);
                $this->upperBound = Bound::positiveInfinity();
                break;
            case self::OP_NE:
                $this->lowerBound = Bound::zero();
                $this->upperBound = Bound::positiveInfinity();
                break;
        }
    }
}
<?php

namespace HumbugBox3150\Composer\Semver\Constraint;

class MultiConstraint implements ConstraintInterface
{
    protected $constraints;
    protected $prettyString;
    protected $string;
    protected $conjunctive;
    protected $lowerBound;
    protected $upperBound;
    public function __construct(array $constraints, $conjunctive = \true)
    {
        if (\count($constraints) < 2) {
            throw new \InvalidArgumentException('Must provide at least two constraints for a MultiConstraint. Use ' . 'the regular Constraint class for one constraint only or MatchAllConstraint for none. You may use ' . 'MultiConstraint::create() which optimizes and handles those cases automatically.');
        }
        $this->constraints = $constraints;
        $this->conjunctive = $conjunctive;
    }
    public function getConstraints()
    {
        return $this->constraints;
    }
    public function isConjunctive()
    {
        return $this->conjunctive;
    }
    public function isDisjunctive()
    {
        return !$this->conjunctive;
    }
    public function compile($otherOperator)
    {
        $parts = array();
        foreach ($this->constraints as $constraint) {
            $code = $constraint->compile($otherOperator);
            if ($code === 'true') {
                if (!$this->conjunctive) {
                    return 'true';
                }
            } elseif ($code === 'false') {
                if ($this->conjunctive) {
                    return 'false';
                }
            } else {
                $parts[] = '(' . $code . ')';
            }
        }
        if (!$parts) {
            return $this->conjunctive ? 'true' : 'false';
        }
        return $this->conjunctive ? \implode('&&', $parts) : \implode('||', $parts);
    }
    public function matches(ConstraintInterface $provider)
    {
        if (\false === $this->conjunctive) {
            foreach ($this->constraints as $constraint) {
                if ($provider->matches($constraint)) {
                    return \true;
                }
            }
            return \false;
        }
        foreach ($this->constraints as $constraint) {
            if (!$provider->matches($constraint)) {
                return \false;
            }
        }
        return \true;
    }
    public function setPrettyString($prettyString)
    {
        $this->prettyString = $prettyString;
    }
    public function getPrettyString()
    {
        if ($this->prettyString) {
            return $this->prettyString;
        }
        return (string) $this;
    }
    public function __toString()
    {
        if ($this->string !== null) {
            return $this->string;
        }
        $constraints = array();
        foreach ($this->constraints as $constraint) {
            $constraints[] = (string) $constraint;
        }
        return $this->string = '[' . \implode($this->conjunctive ? ' ' : ' || ', $constraints) . ']';
    }
    public function getLowerBound()
    {
        $this->extractBounds();
        return $this->lowerBound;
    }
    public function getUpperBound()
    {
        $this->extractBounds();
        return $this->upperBound;
    }
    public static function create(array $constraints, $conjunctive = \true)
    {
        if (0 === \count($constraints)) {
            return new MatchAllConstraint();
        }
        if (1 === \count($constraints)) {
            return $constraints[0];
        }
        $optimized = self::optimizeConstraints($constraints, $conjunctive);
        if ($optimized !== null) {
            list($constraints, $conjunctive) = $optimized;
            if (\count($constraints) === 1) {
                return $constraints[0];
            }
        }
        return new self($constraints, $conjunctive);
    }
    private static function optimizeConstraints(array $constraints, $conjunctive)
    {
        if (!$conjunctive) {
            $left = $constraints[0];
            $mergedConstraints = array();
            $optimized = \false;
            for ($i = 1, $l = \count($constraints); $i < $l; $i++) {
                $right = $constraints[$i];
                if ($left instanceof MultiConstraint && $left->conjunctive && $right instanceof MultiConstraint && $right->conjunctive && ($left0 = (string) $left->constraints[0]) && $left0[0] === '>' && $left0[1] === '=' && ($left1 = (string) $left->constraints[1]) && $left1[0] === '<' && ($right0 = (string) $right->constraints[0]) && $right0[0] === '>' && $right0[1] === '=' && ($right1 = (string) $right->constraints[1]) && $right1[0] === '<' && \substr($left1, 2) === \substr($right0, 3)) {
                    $optimized = \true;
                    $left = new MultiConstraint(\array_merge(array($left->constraints[0], $right->constraints[1]), \array_slice($left->constraints, 2), \array_slice($right->constraints, 2)), \true);
                } else {
                    $mergedConstraints[] = $left;
                    $left = $right;
                }
            }
            if ($optimized) {
                $mergedConstraints[] = $left;
                return array($mergedConstraints, \false);
            }
        }
        return null;
    }
    private function extractBounds()
    {
        if (null !== $this->lowerBound) {
            return;
        }
        foreach ($this->constraints as $constraint) {
            if (null === $this->lowerBound && null === $this->upperBound) {
                $this->lowerBound = $constraint->getLowerBound();
                $this->upperBound = $constraint->getUpperBound();
                continue;
            }
            if ($constraint->getLowerBound()->compareTo($this->lowerBound, $this->isConjunctive() ? '>' : '<')) {
                $this->lowerBound = $constraint->getLowerBound();
            }
            if ($constraint->getUpperBound()->compareTo($this->upperBound, $this->isConjunctive() ? '<' : '>')) {
                $this->upperBound = $constraint->getUpperBound();
            }
        }
    }
}
<?php

namespace HumbugBox3150\Composer\Semver\Constraint;

interface ConstraintInterface
{
    public function matches(ConstraintInterface $provider);
    public function compile($operator);
    public function getUpperBound();
    public function getLowerBound();
    public function getPrettyString();
    public function setPrettyString($prettyString);
    public function __toString();
}
<?php

namespace HumbugBox3150\Composer\Semver;

use HumbugBox3150\Composer\Semver\Constraint\Constraint;
class Comparator
{
    public static function greaterThan($version1, $version2)
    {
        return self::compare($version1, '>', $version2);
    }
    public static function greaterThanOrEqualTo($version1, $version2)
    {
        return self::compare($version1, '>=', $version2);
    }
    public static function lessThan($version1, $version2)
    {
        return self::compare($version1, '<', $version2);
    }
    public static function lessThanOrEqualTo($version1, $version2)
    {
        return self::compare($version1, '<=', $version2);
    }
    public static function equalTo($version1, $version2)
    {
        return self::compare($version1, '==', $version2);
    }
    public static function notEqualTo($version1, $version2)
    {
        return self::compare($version1, '!=', $version2);
    }
    public static function compare($version1, $operator, $version2)
    {
        $constraint = new Constraint($operator, $version2);
        return $constraint->matchSpecific(new Constraint('==', $version1), \true);
    }
}
<?php

// autoload_namespaces.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
);
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

class Terminal
{
    private static $width;
    private static $height;
    private static $stty;
    public function getWidth()
    {
        $width = \getenv('COLUMNS');
        if (\false !== $width) {
            return (int) \trim($width);
        }
        if (null === self::$width) {
            self::initDimensions();
        }
        return self::$width ?: 80;
    }
    public function getHeight()
    {
        $height = \getenv('LINES');
        if (\false !== $height) {
            return (int) \trim($height);
        }
        if (null === self::$height) {
            self::initDimensions();
        }
        return self::$height ?: 50;
    }
    public static function hasSttyAvailable()
    {
        if (null !== self::$stty) {
            return self::$stty;
        }
        if (!\function_exists('exec')) {
            return \false;
        }
        \exec('stty 2>&1', $output, $exitcode);
        return self::$stty = 0 === $exitcode;
    }
    private static function initDimensions()
    {
        if ('\\' === \DIRECTORY_SEPARATOR) {
            if (\preg_match('/^(\\d+)x(\\d+)(?: \\((\\d+)x(\\d+)\\))?$/', \trim(\getenv('ANSICON')), $matches)) {
                self::$width = (int) $matches[1];
                self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2];
            } elseif (!self::hasVt100Support() && self::hasSttyAvailable()) {
                self::initDimensionsUsingStty();
            } elseif (null !== ($dimensions = self::getConsoleMode())) {
                self::$width = (int) $dimensions[0];
                self::$height = (int) $dimensions[1];
            }
        } else {
            self::initDimensionsUsingStty();
        }
    }
    private static function hasVt100Support()
    {
        return \function_exists('sapi_windows_vt100_support') && \sapi_windows_vt100_support(\fopen('php://stdout', 'wb'));
    }
    private static function initDimensionsUsingStty()
    {
        if ($sttyString = self::getSttyColumns()) {
            if (\preg_match('/rows.(\\d+);.columns.(\\d+);/i', $sttyString, $matches)) {
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            } elseif (\preg_match('/;.(\\d+).rows;.(\\d+).columns/i', $sttyString, $matches)) {
                self::$width = (int) $matches[2];
                self::$height = (int) $matches[1];
            }
        }
    }
    private static function getConsoleMode()
    {
        $info = self::readFromProcess('mode CON');
        if (null === $info || !\preg_match('/--------+\\r?\\n.+?(\\d+)\\r?\\n.+?(\\d+)\\r?\\n/', $info, $matches)) {
            return null;
        }
        return array((int) $matches[2], (int) $matches[1]);
    }
    private static function getSttyColumns()
    {
        return self::readFromProcess('stty -a | grep columns');
    }
    private static function readFromProcess($command)
    {
        if (!\function_exists('proc_open')) {
            return null;
        }
        $descriptorspec = array(1 => array('pipe', 'w'), 2 => array('pipe', 'w'));
        $process = \proc_open($command, $descriptorspec, $pipes, null, null, array('suppress_errors' => \true));
        if (!\is_resource($process)) {
            return null;
        }
        $info = \stream_get_contents($pipes[1]);
        \fclose($pipes[1]);
        \fclose($pipes[2]);
        \proc_close($process);
        return $info;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class Printer
{
    private $styles = array('reset' => "\x1b[0m", 'red' => "\x1b[31m", 'green' => "\x1b[32m", 'yellow' => "\x1b[33m", 'title' => "\x1b[33m", 'error' => "\x1b[37;41m", 'success' => "\x1b[30;42m");
    private $verbosity;
    private $supportColors;
    private $width;
    public function __construct($verbosity, $supportColors, $width = null)
    {
        if (null === $width) {
            $terminal = new Terminal();
            $width = $terminal->getWidth();
        }
        $this->verbosity = $verbosity;
        $this->supportColors = $supportColors;
        $this->width = $width ?: 80;
    }
    public function getVerbosity()
    {
        return $this->verbosity;
    }
    public function setVerbosity($verbosity)
    {
        $this->verbosity = $verbosity;
    }
    public function title($title, $verbosity, $style = null)
    {
        if (null === $style) {
            $style = 'title';
        }
        $this->printvln('', $verbosity, $style);
        $this->printvln($title, $verbosity, $style);
        $this->printvln(\str_repeat('=', \min(\strlen($title), $this->width)), $verbosity, $style);
        $this->printvln('', $verbosity, $style);
    }
    public function getRequirementErrorMessage(Requirement $requirement)
    {
        if ($requirement->isFulfilled()) {
            return null;
        }
        $errorMessage = \wordwrap($requirement->getTestMessage(), $this->width - 3, \PHP_EOL . '   ') . \PHP_EOL;
        return $errorMessage;
    }
    public function block($title, $message, $verbosity, $style = null)
    {
        $prefix = ' [' . $title . '] ';
        $lineLength = $this->width - \strlen($prefix) - 1;
        if ($lineLength < 0) {
            $lineLength = 0;
        }
        $message = $prefix . \trim($message);
        $lines = array();
        $remainingMessage = $message;
        $wrapped = \wordwrap($remainingMessage, $lineLength, '¬');
        $wrapped = \explode('¬', $wrapped);
        do {
            $line = \array_shift($wrapped);
            if ($lines && $lineLength > 0) {
                $line = \str_repeat(' ', \strlen($prefix)) . \ltrim($line);
            }
            $lines[] = \str_pad($line, $this->width, ' ', \STR_PAD_RIGHT);
        } while (\count($wrapped));
        $this->printvln('', $verbosity);
        $this->printvln(\str_repeat(' ', $this->width), $verbosity, $style);
        foreach ($lines as $line) {
            $this->printvln($line, $verbosity, $style);
        }
        $this->printv(\str_repeat(' ', $this->width), $verbosity, $style);
        $this->printvln('', $verbosity);
    }
    public function printvln($message, $verbosity, $style = null)
    {
        $this->printv($message, $verbosity, $style);
        $this->printv(\PHP_EOL, $verbosity, null);
    }
    public function printv($message, $verbosity, $style = null)
    {
        if ($verbosity > $this->verbosity) {
            return;
        }
        $message = \wordwrap($message, $this->width);
        $message = \sprintf('%s%s%s', $this->supportColors && isset($this->styles[$style]) ? $this->styles[$style] : '', $message, $this->supportColors ? $this->styles['reset'] : '');
        echo $message;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

use HumbugBox3150\Composer\Semver\Semver;
final class IsPhpVersionFulfilled implements IsFulfilled
{
    private $requiredPhpVersion;
    public function __construct($requiredPhpVersion)
    {
        $this->requiredPhpVersion = $requiredPhpVersion;
    }
    public function __invoke()
    {
        return Semver::satisfies(\sprintf('%d.%d.%d', \PHP_MAJOR_VERSION, \PHP_MINOR_VERSION, \PHP_RELEASE_VERSION), $this->requiredPhpVersion);
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

use ArrayIterator;
use Countable;
use IteratorAggregate;
use ReturnTypeWillChange;
use Traversable;
final class RequirementCollection implements IteratorAggregate, Countable
{
    private $requirements = array();
    #[\ReturnTypeWillChange]
    public function getIterator()
    {
        return new ArrayIterator($this->requirements);
    }
    #[\ReturnTypeWillChange]
    public function count()
    {
        return \count($this->requirements);
    }
    public function add(Requirement $requirement)
    {
        $this->requirements[] = $requirement;
    }
    public function addRequirement($checkIsFulfilled, $testMessage, $helpText)
    {
        $this->add(new Requirement($checkIsFulfilled, $testMessage, $helpText));
    }
    public function getRequirements()
    {
        return $this->requirements;
    }
    public function getPhpIniPath()
    {
        return \get_cfg_var('cfg_file_path');
    }
    public function evaluateRequirements()
    {
        return \array_reduce($this->requirements, function ($checkPassed, Requirement $requirement) {
            return $checkPassed && $requirement->isFulfilled();
        }, \true);
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class Requirement
{
    private $checkIsFulfilled;
    private $fulfilled;
    private $testMessage;
    private $helpText;
    public function __construct($checkIsFulfilled, $testMessage, $helpText)
    {
        $this->checkIsFulfilled = $checkIsFulfilled;
        $this->testMessage = $testMessage;
        $this->helpText = $helpText;
    }
    public function isFulfilled()
    {
        if (null === $this->fulfilled) {
            $this->fulfilled = $this->checkIsFulfilled->__invoke();
        }
        return (bool) $this->fulfilled;
    }
    public function getIsFullfilledChecker()
    {
        return $this->checkIsFulfilled;
    }
    public function getTestMessage()
    {
        return $this->testMessage;
    }
    public function getHelpText()
    {
        return $this->helpText;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

interface IsFulfilled
{
    public function __invoke();
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class Checker
{
    private static $requirementsConfig;
    public static function checkRequirements()
    {
        $requirements = self::retrieveRequirements();
        $checkPassed = $requirements->evaluateRequirements();
        $io = new IO();
        self::printCheck($checkPassed, new Printer($io->getVerbosity(), $io->hasColorSupport()), $requirements);
        return $checkPassed;
    }
    public static function printCheck($checkPassed, Printer $printer, RequirementCollection $requirements)
    {
        if (\false === $checkPassed && IO::VERBOSITY_VERY_VERBOSE > $printer->getVerbosity()) {
            $printer->setVerbosity(IO::VERBOSITY_VERY_VERBOSE);
        }
        $verbosity = IO::VERBOSITY_VERY_VERBOSE;
        $iniPath = $requirements->getPhpIniPath();
        $printer->title('Box Requirements Checker', $verbosity);
        $printer->printv('> Using PHP ', $verbosity);
        $printer->printvln(\PHP_VERSION, $verbosity, 'green');
        $printer->printvln('> PHP is using the following php.ini file:', $verbosity);
        if ($iniPath) {
            $printer->printvln('  ' . $iniPath, $verbosity, 'green');
        } else {
            $printer->printvln('  WARNING: No configuration file (php.ini) used by PHP!', $verbosity, 'yellow');
        }
        $printer->printvln('', $verbosity);
        if (\count($requirements) > 0) {
            $printer->printvln('> Checking Box requirements:', $verbosity);
            $printer->printv('  ', $verbosity);
        } else {
            $printer->printvln('> No requirements found.', $verbosity);
        }
        $errorMessages = array();
        foreach ($requirements->getRequirements() as $requirement) {
            if ($errorMessage = $printer->getRequirementErrorMessage($requirement)) {
                if (IO::VERBOSITY_DEBUG === $printer->getVerbosity()) {
                    $printer->printvln('✘ ' . $requirement->getTestMessage(), IO::VERBOSITY_DEBUG, 'red');
                    $printer->printv('  ', IO::VERBOSITY_DEBUG);
                    $errorMessages[] = $errorMessage;
                } else {
                    $printer->printv('E', $verbosity, 'red');
                    $errorMessages[] = $errorMessage;
                }
                continue;
            }
            if (IO::VERBOSITY_DEBUG === $printer->getVerbosity()) {
                $printer->printvln('✔ ' . $requirement->getHelpText(), IO::VERBOSITY_DEBUG, 'green');
                $printer->printv('  ', IO::VERBOSITY_DEBUG);
            } else {
                $printer->printv('.', $verbosity, 'green');
            }
        }
        if (IO::VERBOSITY_DEBUG !== $printer->getVerbosity() && \count($requirements) > 0) {
            $printer->printvln('', $verbosity);
        }
        if ($requirements->evaluateRequirements()) {
            $printer->block('OK', 'Your system is ready to run the application.', $verbosity, 'success');
        } else {
            $printer->block('ERROR', 'Your system is not ready to run the application.', $verbosity, 'error');
            $printer->title('Fix the following mandatory requirements:', $verbosity, 'red');
            foreach ($errorMessages as $errorMessage) {
                $printer->printv(' * ' . $errorMessage, $verbosity);
            }
        }
        $printer->printvln('', $verbosity);
    }
    private static function retrieveRequirements()
    {
        if (null === self::$requirementsConfig) {
            self::$requirementsConfig = __DIR__ . '/../.requirements.php';
        }
        $config = (require self::$requirementsConfig);
        $requirements = new RequirementCollection();
        foreach ($config as $constraint) {
            $requirements->addRequirement('php' === $constraint['type'] ? new IsPhpVersionFulfilled($constraint['condition']) : new IsExtensionFulfilled($constraint['condition']), $constraint['message'], $constraint['helpMessage']);
        }
        return $requirements;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class IO
{
    const VERBOSITY_QUIET = 16;
    const VERBOSITY_NORMAL = 32;
    const VERBOSITY_VERBOSE = 64;
    const VERBOSITY_VERY_VERBOSE = 128;
    const VERBOSITY_DEBUG = 256;
    private $interactive;
    private $verbosity = self::VERBOSITY_NORMAL;
    private $colorSupport;
    private $options;
    public function __construct()
    {
        $this->options = \implode(' ', $_SERVER['argv']);
        $shellVerbosity = $this->configureVerbosity();
        $this->interactive = $this->checkInteractivity($shellVerbosity);
        $this->colorSupport = $this->checkColorSupport();
    }
    public function isInteractive()
    {
        return $this->interactive;
    }
    public function getVerbosity()
    {
        return $this->verbosity;
    }
    public function hasColorSupport()
    {
        return $this->colorSupport;
    }
    public function hasParameter($values)
    {
        $values = (array) $values;
        foreach ($values as $value) {
            $regexp = \sprintf('/\\s%s\\b/', \str_replace(' ', '\\s+', \preg_quote($value, '/')));
            if (1 === \preg_match($regexp, $this->options)) {
                return \true;
            }
        }
        return \false;
    }
    private function checkInteractivity($shellVerbosity)
    {
        if (-1 === $shellVerbosity) {
            return \false;
        }
        if (\true === $this->hasParameter(array('--no-interaction', '-n'))) {
            return \false;
        }
        if (\function_exists('posix_isatty') && !@\posix_isatty(\STDOUT) && \false === \getenv('SHELL_INTERACTIVE')) {
            return \false;
        }
        return \true;
    }
    private function configureVerbosity()
    {
        switch ($shellVerbosity = (int) \getenv('SHELL_VERBOSITY')) {
            case -1:
                $this->verbosity = self::VERBOSITY_QUIET;
                break;
            case 1:
                $this->verbosity = self::VERBOSITY_VERBOSE;
                break;
            case 2:
                $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
                break;
            case 3:
                $this->verbosity = self::VERBOSITY_DEBUG;
                break;
            default:
                $shellVerbosity = 0;
                break;
        }
        if ($this->hasParameter(array('--quiet', '-q'))) {
            $this->verbosity = self::VERBOSITY_QUIET;
            $shellVerbosity = -1;
        } elseif ($this->hasParameter(array('-vvv', '--verbose=3', '--verbose 3'))) {
            $this->verbosity = self::VERBOSITY_DEBUG;
            $shellVerbosity = 3;
        } elseif ($this->hasParameter(array('-vv', '--verbose=2', '--verbose 2'))) {
            $this->verbosity = self::VERBOSITY_VERY_VERBOSE;
            $shellVerbosity = 2;
        } elseif ($this->hasParameter(array('-v', '--verbose=1', '--verbose 1', '--verbose'))) {
            $this->verbosity = self::VERBOSITY_VERBOSE;
            $shellVerbosity = 1;
        }
        return $shellVerbosity;
    }
    private function checkColorSupport()
    {
        if ($this->hasParameter(array('--ansi'))) {
            return \true;
        }
        if ($this->hasParameter(array('--no-ansi'))) {
            return \false;
        }
        if (\DIRECTORY_SEPARATOR === '\\') {
            return \function_exists('sapi_windows_vt100_support') && \sapi_windows_vt100_support(\STDOUT) || \false !== \getenv('ANSICON') || 'ON' === \getenv('ConEmuANSI') || 'xterm' === \getenv('TERM');
        }
        if (\function_exists('stream_isatty')) {
            return \stream_isatty(\STDOUT);
        }
        if (\function_exists('posix_isatty')) {
            return \posix_isatty(\STDOUT);
        }
        $stat = \fstat(\STDOUT);
        return $stat ? 020000 === ($stat['mode'] & 0170000) : \false;
    }
}
<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

final class IsExtensionFulfilled implements IsFulfilled
{
    private $requiredExtension;
    public function __construct($requiredExtension)
    {
        $this->requiredExtension = $requiredExtension;
    }
    public function __invoke()
    {
        return \extension_loaded($this->requiredExtension);
    }
}
<?php

return array (
  0 => 
  array (
    'type' => 'php',
    'condition' => '^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0',
    'message' => 'The application requires the version "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0" or greater.',
    'helpMessage' => 'The application requires the version "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0" or greater.',
  ),
  1 => 
  array (
    'type' => 'extension',
    'condition' => 'simplexml',
    'message' => 'The application requires the extension "simplexml". Enable it or install a polyfill.',
    'helpMessage' => 'The application requires the extension "simplexml".',
  ),
  2 => 
  array (
    'type' => 'extension',
    'condition' => 'dom',
    'message' => 'The application requires the extension "dom". Enable it or install a polyfill.',
    'helpMessage' => 'The application requires the extension "dom".',
  ),
  3 => 
  array (
    'type' => 'extension',
    'condition' => 'dom',
    'message' => 'The package "spatie/array-to-xml" requires the extension "dom". Enable it or install a polyfill.',
    'helpMessage' => 'The package "spatie/array-to-xml" requires the extension "dom".',
  ),
  4 => 
  array (
    'type' => 'extension',
    'condition' => 'json',
    'message' => 'The application requires the extension "json". Enable it or install a polyfill.',
    'helpMessage' => 'The application requires the extension "json".',
  ),
  5 => 
  array (
    'type' => 'extension',
    'condition' => 'json',
    'message' => 'The package "netresearch/jsonmapper" requires the extension "json". Enable it or install a polyfill.',
    'helpMessage' => 'The package "netresearch/jsonmapper" requires the extension "json".',
  ),
  6 => 
  array (
    'type' => 'extension',
    'condition' => 'libxml',
    'message' => 'The application requires the extension "libxml". Enable it or install a polyfill.',
    'helpMessage' => 'The application requires the extension "libxml".',
  ),
  7 => 
  array (
    'type' => 'extension',
    'condition' => 'tokenizer',
    'message' => 'The application requires the extension "tokenizer". Enable it or install a polyfill.',
    'helpMessage' => 'The application requires the extension "tokenizer".',
  ),
  8 => 
  array (
    'type' => 'extension',
    'condition' => 'tokenizer',
    'message' => 'The package "nikic/php-parser" requires the extension "tokenizer". Enable it or install a polyfill.',
    'helpMessage' => 'The package "nikic/php-parser" requires the extension "tokenizer".',
  ),
  9 => 
  array (
    'type' => 'extension',
    'condition' => 'pcre',
    'message' => 'The package "netresearch/jsonmapper" requires the extension "pcre". Enable it or install a polyfill.',
    'helpMessage' => 'The package "netresearch/jsonmapper" requires the extension "pcre".',
  ),
  10 => 
  array (
    'type' => 'extension',
    'condition' => 'reflection',
    'message' => 'The package "netresearch/jsonmapper" requires the extension "reflection". Enable it or install a polyfill.',
    'helpMessage' => 'The package "netresearch/jsonmapper" requires the extension "reflection".',
  ),
  11 => 
  array (
    'type' => 'extension',
    'condition' => 'spl',
    'message' => 'The package "netresearch/jsonmapper" requires the extension "spl". Enable it or install a polyfill.',
    'helpMessage' => 'The package "netresearch/jsonmapper" requires the extension "spl".',
  ),
  12 => 
  array (
    'type' => 'extension',
    'condition' => 'filter',
    'message' => 'The package "phpdocumentor/reflection-docblock" requires the extension "filter". Enable it or install a polyfill.',
    'helpMessage' => 'The package "phpdocumentor/reflection-docblock" requires the extension "filter".',
  ),
);<?php

namespace HumbugBox3150\KevinGH\RequirementChecker;

require __DIR__ . '/../vendor/autoload.php';
if (\false === \in_array(\PHP_SAPI, array('cli', 'phpdbg', 'embed'), \true)) {
    echo \PHP_EOL . 'The application may only be invoked from a command line, got "' . \PHP_SAPI . '"' . \PHP_EOL;
    exit(1);
}
if ((\false === isset($_SERVER['BOX_REQUIREMENT_CHECKER']) || \true === (bool) $_SERVER['BOX_REQUIREMENT_CHECKER']) && \false === Checker::checkRequirements()) {
    exit(1);
}
�-v!���6��g��3��qiGBMB

Filemanager

Name Type Size Permission Actions
composer File 2.71 MB 0644
php-cs-fixer File 2.57 MB 0644
psalm File 11.46 MB 0644